aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 12:31:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 12:31:14 -0500
commitb399c46ea0070671f3abbe1915d26076101a42f2 (patch)
tree8945606976fc46c3446c09f8a9e0d4f45f6c408e
parentb890eb4ecc718907223a3b7b7b069b59b33f28ef (diff)
parent6c3df5da67f1f53df78c7e20cd53a481dc28eade (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - a new jpeg codec driver for Samsung Exynos (jpeg-hw-exynos4) - a new dvb frontend for ds2103 chipset (m88ds2103) - a new sensor driver for Samsung S5K5BAF UXGA (s5k5baf) - new drivers for R-Car VSP1 - a new radio driver: radio-raremono - a new tuner driver for ts2022 chipset (m88ts2022) - the analog part of em28xx is now a separate module that only load/runs if the device is not a pure digital TV device - added a staging driver for bcm2048 radio devices - the omap 2 video driver (omap24xx) was moved to staging. This driver is for an old hardware and uses a deprecated Kernel internal API. If nobody cares enough to fix it, it would be removed on a couple Kernel releases - the sn9c102 driver was moved to staging. This driver was replaced by gspca, and disabled on some distros, as almost all devices are known to work properly with gspca. It should be removed from kernel on a couple Kernel releases - lots of driver fixes, improvements and cleanups * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (421 commits) [media] media: v4l2-dev: fix video device index assignment [media] rc-core: reuse device numbers [media] em28xx-cards: properly initialize the device bitmap [media] Staging: media: Fix line length exceeding 80 characters in as102_drv.c [media] Staging: media: Fix line length exceeding 80 characters in as102_fe.c [media] Staging: media: Fix quoted string split across line in as102_fe.c [media] media: st-rc: Add reset support [media] m2m-deinterlace: fix allocated struct type [media] radio-usb-si4713: fix sparse non static symbol warnings [media] em28xx-audio: remove needless check before usb_free_coherent() [media] au0828: Fix sparse non static symbol warning Revert "[media] go7007-usb: only use go->dev after allocated" [media] em28xx-audio: provide an error code when URB submit fails [media] em28xx: fix check for audio only usb interfaces when changing the usb alternate setting [media] em28xx: fix usb alternate setting for analog and digital video endpoints > 0 [media] em28xx: make 'em28xx_ctrl_ops' static em28xx-alsa: Fix error patch for init/fini [media] em28xx-audio: flush work at .fini [media] drxk: remove the option to load firmware asynchronously [media] em28xx: adjust period size at runtime ...
-rw-r--r--Documentation/DocBook/media/v4l/compat.xml12
-rw-r--r--Documentation/DocBook/media/v4l/controls.xml41
-rw-r--r--Documentation/DocBook/media/v4l/dev-overlay.xml9
-rw-r--r--Documentation/DocBook/media/v4l/media-ioc-enum-links.xml9
-rw-r--r--Documentation/DocBook/media/v4l/subdev-formats.xml163
-rw-r--r--Documentation/DocBook/media/v4l/v4l2.xml10
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-cropcap.xml10
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-streamon.xml2
-rw-r--r--Documentation/cgroups/resource_counter.txt2
-rw-r--r--Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt11
-rw-r--r--Documentation/devicetree/bindings/media/samsung-s5k5baf.txt58
-rw-r--r--Documentation/video4linux/omap4_camera.txt60
-rw-r--r--Documentation/video4linux/si476x.txt2
-rw-r--r--MAINTAINERS50
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c7
-rw-r--r--arch/blackfin/mach-bf609/boards/ezkit.c4
-rw-r--r--arch/score/lib/checksum.S2
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/media/Kconfig3
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h3
-rw-r--r--drivers/media/dvb-frontends/Kconfig7
-rw-r--r--drivers/media/dvb-frontends/Makefile1
-rw-r--r--drivers/media/dvb-frontends/a8293.c2
-rw-r--r--drivers/media/dvb-frontends/cx24117.c121
-rw-r--r--drivers/media/dvb-frontends/dib8000.c590
-rw-r--r--drivers/media/dvb-frontends/drxk.h2
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c24
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.c1311
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.h114
-rw-r--r--drivers/media/dvb-frontends/m88ds3103_priv.h215
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.c172
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.h2
-rw-r--r--drivers/media/dvb-frontends/nxt200x.c2
-rw-r--r--drivers/media/i2c/Kconfig27
-rw-r--r--drivers/media/i2c/Makefile3
-rw-r--r--drivers/media/i2c/ad9389b.c277
-rw-r--r--drivers/media/i2c/adv7511.c64
-rw-r--r--drivers/media/i2c/adv7604.c645
-rw-r--r--drivers/media/i2c/adv7842.c646
-rw-r--r--drivers/media/i2c/lm3560.c34
-rw-r--r--drivers/media/i2c/mt9m032.c16
-rw-r--r--drivers/media/i2c/mt9p031.c28
-rw-r--r--drivers/media/i2c/mt9t001.c26
-rw-r--r--drivers/media/i2c/mt9v032.c264
-rw-r--r--drivers/media/i2c/s5k5baf.c2045
-rw-r--r--drivers/media/i2c/saa6588.c50
-rw-r--r--drivers/media/i2c/saa6752hs.c (renamed from drivers/media/pci/saa7134/saa6752hs.c)19
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c9
-rw-r--r--drivers/media/i2c/soc_camera/mt9m111.c4
-rw-r--r--drivers/media/i2c/tvp5150.c40
-rw-r--r--drivers/media/i2c/vs6624.c2
-rw-r--r--drivers/media/media-entity.c41
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c10
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c5
-rw-r--r--drivers/media/pci/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/media/pci/cx25821/cx25821-core.c2
-rw-r--r--drivers/media/pci/cx88/cx88-alsa.c4
-rw-r--r--drivers/media/pci/saa7134/Kconfig1
-rw-r--r--drivers/media/pci/saa7134/Makefile2
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c11
-rw-r--r--drivers/media/pci/saa7134/saa7134-empress.c359
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c11
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c781
-rw-r--r--drivers/media/pci/saa7134/saa7134.h66
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c2
-rw-r--r--drivers/media/platform/Kconfig10
-rw-r--r--drivers/media/platform/Makefile3
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c2
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c2
-rw-r--r--drivers/media/platform/davinci/vpif_display.c2
-rw-r--r--drivers/media/platform/exynos4-is/Kconfig2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.c29
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.h2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-regs.c36
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-regs.h1
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.c29
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite-reg.c4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c26
-rw-r--r--drivers/media/platform/exynos4-is/fimc-m2m.c148
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c13
-rw-r--r--drivers/media/platform/m2m-deinterlace.c2
-rw-r--r--drivers/media/platform/mem2mem_testdev.c152
-rw-r--r--drivers/media/platform/omap3isp/isp.c78
-rw-r--r--drivers/media/platform/omap3isp/isp.h5
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c5
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.c3
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.c3
-rw-r--r--drivers/media/platform/omap3isp/isppreview.c3
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.c2
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.c18
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c2
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c106
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.h2
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c124
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.h1
-rw-r--r--drivers/media/platform/s5p-jpeg/Makefile2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c1329
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h69
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c279
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h42
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c (renamed from drivers/media/platform/s5p-jpeg/jpeg-hw.h)82
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h63
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-regs.h209
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c28
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h14
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c57
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c26
-rw-r--r--drivers/media/platform/s5p-tv/mixer_drv.c34
-rw-r--r--drivers/media/platform/s5p-tv/mixer_video.c2
-rw-r--r--drivers/media/platform/s5p-tv/sdo_drv.c39
-rw-r--r--drivers/media/platform/sh_vou.c16
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c179
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c2
-rw-r--r--drivers/media/platform/soc_camera/rcar_vin.c7
-rw-r--r--drivers/media/platform/soc_camera/soc_scale_crop.c4
-rw-r--r--drivers/media/platform/ti-vpe/Makefile2
-rw-r--r--drivers/media/platform/ti-vpe/csc.c196
-rw-r--r--drivers/media/platform/ti-vpe/csc.h68
-rw-r--r--drivers/media/platform/ti-vpe/sc.c311
-rw-r--r--drivers/media/platform/ti-vpe/sc.h208
-rw-r--r--drivers/media/platform/ti-vpe/sc_coeff.h1342
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.c40
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.h12
-rw-r--r--drivers/media/platform/ti-vpe/vpdma_priv.h2
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c327
-rw-r--r--drivers/media/platform/ti-vpe/vpe_regs.h187
-rw-r--r--drivers/media/platform/vsp1/Makefile3
-rw-r--r--drivers/media/platform/vsp1/vsp1.h7
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c39
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c7
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h4
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c222
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.h38
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.c252
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.h38
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h16
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c34
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.c96
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h10
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c356
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.h41
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c13
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c17
-rw-r--r--drivers/media/radio/Kconfig43
-rw-r--r--drivers/media/radio/Makefile4
-rw-r--r--drivers/media/radio/radio-raremono.c387
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c81
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h1
-rw-r--r--drivers/media/radio/si4713/Kconfig40
-rw-r--r--drivers/media/radio/si4713/Makefile7
-rw-r--r--drivers/media/radio/si4713/radio-platform-si4713.c (renamed from drivers/media/radio/radio-si4713.c)0
-rw-r--r--drivers/media/radio/si4713/radio-usb-si4713.c540
-rw-r--r--drivers/media/radio/si4713/si4713.c (renamed from drivers/media/radio/si4713-i2c.c)279
-rw-r--r--drivers/media/radio/si4713/si4713.h (renamed from drivers/media/radio/si4713-i2c.h)4
-rw-r--r--drivers/media/radio/tea575x.c2
-rw-r--r--drivers/media/rc/imon.c8
-rw-r--r--drivers/media/rc/keymaps/Makefile3
-rw-r--r--drivers/media/rc/keymaps/rc-su3000.c75
-rw-r--r--drivers/media/rc/mceusb.c10
-rw-r--r--drivers/media/rc/rc-main.c20
-rw-r--r--drivers/media/rc/st_rc.c13
-rw-r--r--drivers/media/tuners/Kconfig7
-rw-r--r--drivers/media/tuners/Makefile1
-rw-r--r--drivers/media/tuners/e4000.c16
-rw-r--r--drivers/media/tuners/m88ts2022.c674
-rw-r--r--drivers/media/tuners/m88ts2022.h54
-rw-r--r--drivers/media/tuners/m88ts2022_priv.h34
-rw-r--r--drivers/media/tuners/tuner-xc2028.c38
-rw-r--r--drivers/media/usb/Kconfig1
-rw-r--r--drivers/media/usb/Makefile1
-rw-r--r--drivers/media/usb/au0828/au0828-core.c13
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c116
-rw-r--r--drivers/media/usb/au0828/au0828.h6
-rw-r--r--drivers/media/usb/cx231xx/Kconfig2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-i2c.c23
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c3
-rw-r--r--drivers/media/usb/dvb-usb-v2/az6007.c59
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/it913x.c3
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c2
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c21
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c455
-rw-r--r--drivers/media/usb/em28xx/Kconfig8
-rw-r--r--drivers/media/usb/em28xx/Makefile5
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c429
-rw-r--r--drivers/media/usb/em28xx/em28xx-camera.c1
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c553
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c410
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c112
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c199
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c209
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h11
-rw-r--r--drivers/media/usb/em28xx/em28xx-v4l.h20
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c1
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c652
-rw-r--r--drivers/media/usb/em28xx/em28xx.h120
-rw-r--r--drivers/media/usb/pwc/pwc-if.c1
-rw-r--r--drivers/media/v4l2-core/Kconfig11
-rw-r--r--drivers/media/v4l2-core/Makefile1
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c5
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c9
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c126
-rw-r--r--drivers/media/v4l2-core/v4l2-of.c10
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c480
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-sg.c53
-rw-r--r--drivers/staging/media/Kconfig8
-rw-r--r--drivers/staging/media/Makefile5
-rw-r--r--drivers/staging/media/as102/as102_drv.c13
-rw-r--r--drivers/staging/media/as102/as102_drv.h8
-rw-r--r--drivers/staging/media/as102/as102_fe.c37
-rw-r--r--drivers/staging/media/as102/as102_fw.c16
-rw-r--r--drivers/staging/media/as102/as102_usb_drv.c36
-rw-r--r--drivers/staging/media/as102/as10x_cmd.c21
-rw-r--r--drivers/staging/media/as102/as10x_cmd_cfg.c9
-rw-r--r--drivers/staging/media/as102/as10x_cmd_stream.c12
-rw-r--r--drivers/staging/media/bcm2048/Kconfig13
-rw-r--r--drivers/staging/media/bcm2048/Makefile1
-rw-r--r--drivers/staging/media/bcm2048/TODO24
-rw-r--r--drivers/staging/media/bcm2048/radio-bcm2048.c2744
-rw-r--r--drivers/staging/media/bcm2048/radio-bcm2048.h30
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_isif.c3
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.c4
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c4
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c4
-rw-r--r--drivers/staging/media/omap24xx/Kconfig35
-rw-r--r--drivers/staging/media/omap24xx/Makefile5
-rw-r--r--drivers/staging/media/omap24xx/omap24xxcam-dma.c (renamed from drivers/media/platform/omap24xxcam-dma.c)0
-rw-r--r--drivers/staging/media/omap24xx/omap24xxcam.c (renamed from drivers/media/platform/omap24xxcam.c)0
-rw-r--r--drivers/staging/media/omap24xx/omap24xxcam.h (renamed from drivers/media/platform/omap24xxcam.h)2
-rw-r--r--drivers/staging/media/omap24xx/tcm825x.c (renamed from drivers/media/i2c/tcm825x.c)2
-rw-r--r--drivers/staging/media/omap24xx/tcm825x.h (renamed from drivers/media/i2c/tcm825x.h)2
-rw-r--r--drivers/staging/media/omap24xx/v4l2-int-device.c (renamed from drivers/media/v4l2-core/v4l2-int-device.c)2
-rw-r--r--drivers/staging/media/omap24xx/v4l2-int-device.h (renamed from include/media/v4l2-int-device.h)0
-rw-r--r--drivers/staging/media/omap4iss/Kconfig12
-rw-r--r--drivers/staging/media/omap4iss/Makefile6
-rw-r--r--drivers/staging/media/omap4iss/TODO4
-rw-r--r--drivers/staging/media/omap4iss/iss.c1563
-rw-r--r--drivers/staging/media/omap4iss/iss.h236
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c1343
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.h158
-rw-r--r--drivers/staging/media/omap4iss/iss_csiphy.c279
-rw-r--r--drivers/staging/media/omap4iss/iss_csiphy.h51
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipe.c570
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipe.h67
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipeif.c849
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipeif.h92
-rw-r--r--drivers/staging/media/omap4iss/iss_regs.h901
-rw-r--r--drivers/staging/media/omap4iss/iss_resizer.c893
-rw-r--r--drivers/staging/media/omap4iss/iss_resizer.h75
-rw-r--r--drivers/staging/media/omap4iss/iss_video.c1226
-rw-r--r--drivers/staging/media/omap4iss/iss_video.h204
-rw-r--r--drivers/staging/media/sn9c102/Kconfig (renamed from drivers/media/usb/sn9c102/Kconfig)9
-rw-r--r--drivers/staging/media/sn9c102/Makefile (renamed from drivers/media/usb/sn9c102/Makefile)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102.h (renamed from drivers/media/usb/sn9c102/sn9c102.h)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102.txt (renamed from Documentation/video4linux/sn9c102.txt)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_config.h (renamed from drivers/media/usb/sn9c102/sn9c102_config.h)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_core.c (renamed from drivers/media/usb/sn9c102/sn9c102_core.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_devtable.h (renamed from drivers/media/usb/sn9c102/sn9c102_devtable.h)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_hv7131d.c (renamed from drivers/media/usb/sn9c102/sn9c102_hv7131d.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_hv7131r.c (renamed from drivers/media/usb/sn9c102/sn9c102_hv7131r.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mi0343.c (renamed from drivers/media/usb/sn9c102/sn9c102_mi0343.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mi0360.c (renamed from drivers/media/usb/sn9c102/sn9c102_mi0360.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mt9v111.c (renamed from drivers/media/usb/sn9c102/sn9c102_mt9v111.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_ov7630.c (renamed from drivers/media/usb/sn9c102/sn9c102_ov7630.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_ov7660.c (renamed from drivers/media/usb/sn9c102/sn9c102_ov7660.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_pas106b.c (renamed from drivers/media/usb/sn9c102/sn9c102_pas106b.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_pas202bcb.c (renamed from drivers/media/usb/sn9c102/sn9c102_pas202bcb.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_sensor.h (renamed from drivers/media/usb/sn9c102/sn9c102_sensor.h)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c (renamed from drivers/media/usb/sn9c102/sn9c102_tas5110c1b.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5110d.c (renamed from drivers/media/usb/sn9c102/sn9c102_tas5110d.c)0
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c (renamed from drivers/media/usb/sn9c102/sn9c102_tas5130d1b.c)0
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c2
-rw-r--r--drivers/staging/media/solo6x10/solo6x10-v4l2.c7
-rw-r--r--drivers/staging/media/solo6x10/solo6x10.h2
-rw-r--r--include/linux/platform_data/vsp1.h2
-rw-r--r--include/media/adv7604.h38
-rw-r--r--include/media/adv7842.h59
-rw-r--r--include/media/atmel-isi.h2
-rw-r--r--include/media/media-entity.h1
-rw-r--r--include/media/omap4iss.h65
-rw-r--r--include/media/rc-map.h1
-rw-r--r--include/media/saa6588.h2
-rw-r--r--include/media/saa6752hs.h26
-rw-r--r--include/media/si4713.h2
-rw-r--r--include/media/v4l2-fh.h4
-rw-r--r--include/media/v4l2-mem2mem.h24
-rw-r--r--include/media/v4l2-of.h6
-rw-r--r--include/media/videobuf2-core.h18
-rw-r--r--include/trace/events/v4l2.h157
-rw-r--r--include/uapi/linux/media.h1
-rw-r--r--include/uapi/linux/v4l2-controls.h9
-rw-r--r--include/uapi/linux/v4l2-mediabus.h3
-rw-r--r--include/uapi/linux/videodev2.h4
-rw-r--r--include/uapi/linux/vsp1.h34
298 files changed, 29135 insertions, 5098 deletions
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index 0c7195e3e093..c4cac6dbf9af 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2523,6 +2523,18 @@ that used it. It was originally scheduled for removal in 2.6.35.
2523 </orderedlist> 2523 </orderedlist>
2524 </section> 2524 </section>
2525 2525
2526 <section>
2527 <title>V4L2 in Linux 3.14</title>
2528 <orderedlist>
2529 <listitem>
2530 <para> In struct <structname>v4l2_rect</structname>, the type
2531of <structfield>width</structfield> and <structfield>height</structfield>
2532fields changed from _s32 to _u32.
2533 </para>
2534 </listitem>
2535 </orderedlist>
2536 </section>
2537
2526 <section id="other"> 2538 <section id="other">
2527 <title>Relation of V4L2 to other Linux multimedia APIs</title> 2539 <title>Relation of V4L2 to other Linux multimedia APIs</title>
2528 2540
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 7a3b49b3cc3b..a5a3188e5af7 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3161,6 +3161,47 @@ V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD as a golden frame.</entry>
3161 </entrytbl> 3161 </entrytbl>
3162 </row> 3162 </row>
3163 3163
3164 <row><entry></entry></row>
3165 <row>
3166 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_MIN_QP</constant></entry>
3167 <entry>integer</entry>
3168 </row>
3169 <row><entry spanname="descr">Minimum quantization parameter for VP8.</entry>
3170 </row>
3171
3172 <row><entry></entry></row>
3173 <row>
3174 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_MAX_QP</constant></entry>
3175 <entry>integer</entry>
3176 </row>
3177 <row><entry spanname="descr">Maximum quantization parameter for VP8.</entry>
3178 </row>
3179
3180 <row><entry></entry></row>
3181 <row>
3182 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP</constant>&nbsp;</entry>
3183 <entry>integer</entry>
3184 </row>
3185 <row><entry spanname="descr">Quantization parameter for an I frame for VP8.</entry>
3186 </row>
3187
3188 <row><entry></entry></row>
3189 <row>
3190 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP</constant>&nbsp;</entry>
3191 <entry>integer</entry>
3192 </row>
3193 <row><entry spanname="descr">Quantization parameter for a P frame for VP8.</entry>
3194 </row>
3195
3196 <row><entry></entry></row>
3197 <row>
3198 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VPX_PROFILE</constant>&nbsp;</entry>
3199 <entry>integer</entry>
3200 </row>
3201 <row><entry spanname="descr">Select the desired profile for VPx encoder.
3202Acceptable values are 0, 1, 2 and 3 corresponding to encoder profiles 0, 1, 2 and 3.</entry>
3203 </row>
3204
3164 <row><entry></entry></row> 3205 <row><entry></entry></row>
3165 </tbody> 3206 </tbody>
3166 </tgroup> 3207 </tgroup>
diff --git a/Documentation/DocBook/media/v4l/dev-overlay.xml b/Documentation/DocBook/media/v4l/dev-overlay.xml
index 40d1d7681439..cc6e0c5c960c 100644
--- a/Documentation/DocBook/media/v4l/dev-overlay.xml
+++ b/Documentation/DocBook/media/v4l/dev-overlay.xml
@@ -346,17 +346,14 @@ rectangle, in pixels.</entry>
346rectangle, in pixels. Offsets increase to the right and down.</entry> 346rectangle, in pixels. Offsets increase to the right and down.</entry>
347 </row> 347 </row>
348 <row> 348 <row>
349 <entry>__s32</entry> 349 <entry>__u32</entry>
350 <entry><structfield>width</structfield></entry> 350 <entry><structfield>width</structfield></entry>
351 <entry>Width of the rectangle, in pixels.</entry> 351 <entry>Width of the rectangle, in pixels.</entry>
352 </row> 352 </row>
353 <row> 353 <row>
354 <entry>__s32</entry> 354 <entry>__u32</entry>
355 <entry><structfield>height</structfield></entry> 355 <entry><structfield>height</structfield></entry>
356 <entry>Height of the rectangle, in pixels. Width and 356 <entry>Height of the rectangle, in pixels.</entry>
357height cannot be negative, the fields are signed for hysterical
358reasons. <!-- video4linux-list@redhat.com on 22 Oct 2002 subject
359"Re:[V4L][patches!] Re:v4l2/kernel-2.5" --></entry>
360 </row> 357 </row>
361 </tbody> 358 </tbody>
362 </tgroup> 359 </tgroup>
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml
index 355df43badc5..cf8548556c7d 100644
--- a/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml
+++ b/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml
@@ -134,6 +134,15 @@
134 <entry>Output pad, relative to the entity. Output pads source data 134 <entry>Output pad, relative to the entity. Output pads source data
135 and are origins of links.</entry> 135 and are origins of links.</entry>
136 </row> 136 </row>
137 <row>
138 <entry><constant>MEDIA_PAD_FL_MUST_CONNECT</constant></entry>
139 <entry>If this flag is set and the pad is linked to any other
140 pad, then at least one of those links must be enabled for the
141 entity to be able to stream. There could be temporary reasons
142 (e.g. device configuration dependent) for the pad to need
143 enabled links even when this flag isn't set; the absence of the
144 flag doesn't imply there is none.</entry>
145 </row>
137 </tbody> 146 </tbody>
138 </tgroup> 147 </tgroup>
139 </table> 148 </table>
diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml
index f72c1cc93a9b..7331ce116f4c 100644
--- a/Documentation/DocBook/media/v4l/subdev-formats.xml
+++ b/Documentation/DocBook/media/v4l/subdev-formats.xml
@@ -89,7 +89,7 @@
89 <constant>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</constant>. 89 <constant>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</constant>.
90 </para> 90 </para>
91 91
92 <para>The following tables list existing packet RGB formats.</para> 92 <para>The following tables list existing packed RGB formats.</para>
93 93
94 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb"> 94 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb">
95 <title>RGB formats</title> 95 <title>RGB formats</title>
@@ -615,7 +615,7 @@
615 </mediaobject> 615 </mediaobject>
616 </figure> 616 </figure>
617 617
618 <para>The following table lists existing packet Bayer formats. The data 618 <para>The following table lists existing packed Bayer formats. The data
619 organization is given as an example for the first pixel only.</para> 619 organization is given as an example for the first pixel only.</para>
620 620
621 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-bayer"> 621 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-bayer">
@@ -1178,7 +1178,7 @@
1178 U, Y, V, Y order will be named <constant>V4L2_MBUS_FMT_UYVY8_2X8</constant>. 1178 U, Y, V, Y order will be named <constant>V4L2_MBUS_FMT_UYVY8_2X8</constant>.
1179 </para> 1179 </para>
1180 1180
1181 <para><xref linkend="v4l2-mbus-pixelcode-yuv8"/> list existing packet YUV 1181 <para><xref linkend="v4l2-mbus-pixelcode-yuv8"/> lists existing packed YUV
1182 formats and describes the organization of each pixel data in each sample. 1182 formats and describes the organization of each pixel data in each sample.
1183 When a format pattern is split across multiple samples each of the samples 1183 When a format pattern is split across multiple samples each of the samples
1184 in the pattern is described.</para> 1184 in the pattern is described.</para>
@@ -2492,6 +2492,163 @@
2492 </section> 2492 </section>
2493 2493
2494 <section> 2494 <section>
2495 <title>HSV/HSL Formats</title>
2496
2497 <para>Those formats transfer pixel data as RGB values in a cylindrical-coordinate
2498 system using Hue-Saturation-Value or Hue-Saturation-Lightness components. The
2499 format code is made of the following information.
2500 <itemizedlist>
2501 <listitem><para>The hue, saturation, value or lightness and optional alpha
2502 components order code, as encoded in a pixel sample. The only currently
2503 supported value is AHSV.
2504 </para></listitem>
2505 <listitem><para>The number of bits per component, for each component. The values
2506 can be different for all components. The only currently supported value is 8888.
2507 </para></listitem>
2508 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
2509 the bus width must be transferred in multiple samples. The only currently
2510 supported value is 1.</para></listitem>
2511 <listitem><para>The bus width.</para></listitem>
2512 <listitem><para>For formats where the total number of bits per pixel is smaller
2513 than the number of bus samples per pixel times the bus width, a padding
2514 value stating if the bytes are padded in their most high order bits
2515 (PADHI) or low order bits (PADLO).</para></listitem>
2516 <listitem><para>For formats where the number of bus samples per pixel is larger
2517 than 1, an endianness value stating if the pixel is transferred MSB first
2518 (BE) or LSB first (LE).</para></listitem>
2519 </itemizedlist>
2520 </para>
2521
2522 <para>The following table lists existing HSV/HSL formats.</para>
2523
2524 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-hsv">
2525 <title>HSV/HSL formats</title>
2526 <tgroup cols="27">
2527 <colspec colname="id" align="left" />
2528 <colspec colname="code" align="center"/>
2529 <colspec colname="bit" />
2530 <colspec colnum="4" colname="b31" align="center" />
2531 <colspec colnum="5" colname="b20" align="center" />
2532 <colspec colnum="6" colname="b29" align="center" />
2533 <colspec colnum="7" colname="b28" align="center" />
2534 <colspec colnum="8" colname="b27" align="center" />
2535 <colspec colnum="9" colname="b26" align="center" />
2536 <colspec colnum="10" colname="b25" align="center" />
2537 <colspec colnum="11" colname="b24" align="center" />
2538 <colspec colnum="12" colname="b23" align="center" />
2539 <colspec colnum="13" colname="b22" align="center" />
2540 <colspec colnum="14" colname="b21" align="center" />
2541 <colspec colnum="15" colname="b20" align="center" />
2542 <colspec colnum="16" colname="b19" align="center" />
2543 <colspec colnum="17" colname="b18" align="center" />
2544 <colspec colnum="18" colname="b17" align="center" />
2545 <colspec colnum="19" colname="b16" align="center" />
2546 <colspec colnum="20" colname="b15" align="center" />
2547 <colspec colnum="21" colname="b14" align="center" />
2548 <colspec colnum="22" colname="b13" align="center" />
2549 <colspec colnum="23" colname="b12" align="center" />
2550 <colspec colnum="24" colname="b11" align="center" />
2551 <colspec colnum="25" colname="b10" align="center" />
2552 <colspec colnum="26" colname="b09" align="center" />
2553 <colspec colnum="27" colname="b08" align="center" />
2554 <colspec colnum="28" colname="b07" align="center" />
2555 <colspec colnum="29" colname="b06" align="center" />
2556 <colspec colnum="30" colname="b05" align="center" />
2557 <colspec colnum="31" colname="b04" align="center" />
2558 <colspec colnum="32" colname="b03" align="center" />
2559 <colspec colnum="33" colname="b02" align="center" />
2560 <colspec colnum="34" colname="b01" align="center" />
2561 <colspec colnum="35" colname="b00" align="center" />
2562 <spanspec namest="b31" nameend="b00" spanname="b0" />
2563 <thead>
2564 <row>
2565 <entry>Identifier</entry>
2566 <entry>Code</entry>
2567 <entry></entry>
2568 <entry spanname="b0">Data organization</entry>
2569 </row>
2570 <row>
2571 <entry></entry>
2572 <entry></entry>
2573 <entry>Bit</entry>
2574 <entry>31</entry>
2575 <entry>30</entry>
2576 <entry>29</entry>
2577 <entry>28</entry>
2578 <entry>27</entry>
2579 <entry>26</entry>
2580 <entry>25</entry>
2581 <entry>24</entry>
2582 <entry>23</entry>
2583 <entry>22</entry>
2584 <entry>21</entry>
2585 <entry>20</entry>
2586 <entry>19</entry>
2587 <entry>18</entry>
2588 <entry>17</entry>
2589 <entry>16</entry>
2590 <entry>15</entry>
2591 <entry>14</entry>
2592 <entry>13</entry>
2593 <entry>12</entry>
2594 <entry>11</entry>
2595 <entry>10</entry>
2596 <entry>9</entry>
2597 <entry>8</entry>
2598 <entry>7</entry>
2599 <entry>6</entry>
2600 <entry>5</entry>
2601 <entry>4</entry>
2602 <entry>3</entry>
2603 <entry>2</entry>
2604 <entry>1</entry>
2605 <entry>0</entry>
2606 </row>
2607 </thead>
2608 <tbody valign="top">
2609 <row id="V4L2-MBUS-FMT-AHSV8888-1X32">
2610 <entry>V4L2_MBUS_FMT_AHSV8888_1X32</entry>
2611 <entry>0x6001</entry>
2612 <entry></entry>
2613 <entry>a<subscript>7</subscript></entry>
2614 <entry>a<subscript>6</subscript></entry>
2615 <entry>a<subscript>5</subscript></entry>
2616 <entry>a<subscript>4</subscript></entry>
2617 <entry>a<subscript>3</subscript></entry>
2618 <entry>a<subscript>2</subscript></entry>
2619 <entry>a<subscript>1</subscript></entry>
2620 <entry>a<subscript>0</subscript></entry>
2621 <entry>h<subscript>7</subscript></entry>
2622 <entry>h<subscript>6</subscript></entry>
2623 <entry>h<subscript>5</subscript></entry>
2624 <entry>h<subscript>4</subscript></entry>
2625 <entry>h<subscript>3</subscript></entry>
2626 <entry>h<subscript>2</subscript></entry>
2627 <entry>h<subscript>1</subscript></entry>
2628 <entry>h<subscript>0</subscript></entry>
2629 <entry>s<subscript>7</subscript></entry>
2630 <entry>s<subscript>6</subscript></entry>
2631 <entry>s<subscript>5</subscript></entry>
2632 <entry>s<subscript>4</subscript></entry>
2633 <entry>s<subscript>3</subscript></entry>
2634 <entry>s<subscript>2</subscript></entry>
2635 <entry>s<subscript>1</subscript></entry>
2636 <entry>s<subscript>0</subscript></entry>
2637 <entry>v<subscript>7</subscript></entry>
2638 <entry>v<subscript>6</subscript></entry>
2639 <entry>v<subscript>5</subscript></entry>
2640 <entry>v<subscript>4</subscript></entry>
2641 <entry>v<subscript>3</subscript></entry>
2642 <entry>v<subscript>2</subscript></entry>
2643 <entry>v<subscript>1</subscript></entry>
2644 <entry>v<subscript>0</subscript></entry>
2645 </row>
2646 </tbody>
2647 </tgroup>
2648 </table>
2649 </section>
2650
2651 <section>
2495 <title>JPEG Compressed Formats</title> 2652 <title>JPEG Compressed Formats</title>
2496 2653
2497 <para>Those data formats consist of an ordered sequence of 8-bit bytes 2654 <para>Those data formats consist of an ordered sequence of 8-bit bytes
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 8469fe13945c..74b7f27af71a 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -141,6 +141,14 @@ structs, ioctls) must be noted in more detail in the history chapter
141applications. --> 141applications. -->
142 142
143 <revision> 143 <revision>
144 <revnumber>3.14</revnumber>
145 <date>2013-11-25</date>
146 <authorinitials>rr</authorinitials>
147 <revremark>Set width and height as unsigned on v4l2_rect.
148 </revremark>
149 </revision>
150
151 <revision>
144 <revnumber>3.11</revnumber> 152 <revnumber>3.11</revnumber>
145 <date>2013-05-26</date> 153 <date>2013-05-26</date>
146 <authorinitials>hv</authorinitials> 154 <authorinitials>hv</authorinitials>
@@ -501,7 +509,7 @@ and discussions on the V4L mailing list.</revremark>
501</partinfo> 509</partinfo>
502 510
503<title>Video for Linux Two API Specification</title> 511<title>Video for Linux Two API Specification</title>
504 <subtitle>Revision 3.11</subtitle> 512 <subtitle>Revision 3.14</subtitle>
505 513
506 <chapter id="common"> 514 <chapter id="common">
507 &sub-common; 515 &sub-common;
diff --git a/Documentation/DocBook/media/v4l/vidioc-cropcap.xml b/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
index bf7cc979fdfa..1f5ed64cd75a 100644
--- a/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
@@ -133,18 +133,14 @@ rectangle, in pixels.</entry>
133rectangle, in pixels.</entry> 133rectangle, in pixels.</entry>
134 </row> 134 </row>
135 <row> 135 <row>
136 <entry>__s32</entry> 136 <entry>__u32</entry>
137 <entry><structfield>width</structfield></entry> 137 <entry><structfield>width</structfield></entry>
138 <entry>Width of the rectangle, in pixels.</entry> 138 <entry>Width of the rectangle, in pixels.</entry>
139 </row> 139 </row>
140 <row> 140 <row>
141 <entry>__s32</entry> 141 <entry>__u32</entry>
142 <entry><structfield>height</structfield></entry> 142 <entry><structfield>height</structfield></entry>
143 <entry>Height of the rectangle, in pixels. Width 143 <entry>Height of the rectangle, in pixels.</entry>
144and height cannot be negative, the fields are signed for
145hysterical reasons. <!-- video4linux-list@redhat.com
146on 22 Oct 2002 subject "Re:[V4L][patches!] Re:v4l2/kernel-2.5" -->
147</entry>
148 </row> 144 </row>
149 </tbody> 145 </tbody>
150 </tgroup> 146 </tgroup>
diff --git a/Documentation/DocBook/media/v4l/vidioc-streamon.xml b/Documentation/DocBook/media/v4l/vidioc-streamon.xml
index 716ea15e54a1..65dff55079d7 100644
--- a/Documentation/DocBook/media/v4l/vidioc-streamon.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-streamon.xml
@@ -59,7 +59,7 @@ buffers are filled (if there are any empty buffers in the incoming
59queue) until <constant>VIDIOC_STREAMON</constant> has been called. 59queue) until <constant>VIDIOC_STREAMON</constant> has been called.
60Accordingly the output hardware is disabled, no video signal is 60Accordingly the output hardware is disabled, no video signal is
61produced until <constant>VIDIOC_STREAMON</constant> has been called. 61produced until <constant>VIDIOC_STREAMON</constant> has been called.
62The ioctl will succeed only when at least one output buffer is in the 62The ioctl will succeed when at least one output buffer is in the
63incoming queue.</para> 63incoming queue.</para>
64 64
65 <para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of 65 <para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of
diff --git a/Documentation/cgroups/resource_counter.txt b/Documentation/cgroups/resource_counter.txt
index 52e1da16a309..5108afb3645c 100644
--- a/Documentation/cgroups/resource_counter.txt
+++ b/Documentation/cgroups/resource_counter.txt
@@ -95,7 +95,7 @@ to work with it.
95 95
96 f. u64 res_counter_uncharge_until 96 f. u64 res_counter_uncharge_until
97 (struct res_counter *rc, struct res_counter *top, 97 (struct res_counter *rc, struct res_counter *top,
98 unsinged long val) 98 unsigned long val)
99 99
100 Almost same as res_counter_uncharge() but propagation of uncharge 100 Almost same as res_counter_uncharge() but propagation of uncharge
101 stops when rc == top. This is useful when kill a res_counter in 101 stops when rc == top. This is useful when kill a res_counter in
diff --git a/Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt b/Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
new file mode 100644
index 000000000000..937b755baf8f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
@@ -0,0 +1,11 @@
1Samsung S5P/EXYNOS SoC series JPEG codec
2
3Required properties:
4
5- compatible : should be one of:
6 "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg";
7- reg : address and length of the JPEG codec IP register set;
8- interrupts : specifies the JPEG codec IP interrupt;
9- clocks : should contain the JPEG codec IP gate clock specifier, from the
10 common clock bindings;
11- clock-names : should contain "jpeg" entry.
diff --git a/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
new file mode 100644
index 000000000000..1f51e0439c96
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
@@ -0,0 +1,58 @@
1Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP
2--------------------------------------------------------------------
3
4Required properties:
5
6- compatible : "samsung,s5k5baf";
7- reg : I2C slave address of the sensor;
8- vdda-supply : analog power supply 2.8V (2.6V to 3.0V);
9- vddreg-supply : regulator input power supply 1.8V (1.7V to 1.9V)
10 or 2.8V (2.6V to 3.0);
11- vddio-supply : I/O power supply 1.8V (1.65V to 1.95V)
12 or 2.8V (2.5V to 3.1V);
13- stbyn-gpios : GPIO connected to STDBYN pin;
14- rstn-gpios : GPIO connected to RSTN pin;
15- clocks : list of phandle and clock specifier pairs
16 according to common clock bindings for the
17 clocks described in clock-names;
18- clock-names : should include "mclk" for the sensor's master clock;
19
20Optional properties:
21
22- clock-frequency : the frequency at which the "mclk" clock should be
23 configured to operate, in Hz; if this property is not
24 specified default 24 MHz value will be used.
25
26The device node should contain one 'port' child node with one child 'endpoint'
27node, according to the bindings defined in Documentation/devicetree/bindings/
28media/video-interfaces.txt. The following are properties specific to those
29nodes.
30
31endpoint node
32-------------
33
34- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
35 video-interfaces.txt. If present it should be <1> - the device
36 supports only one data lane without re-mapping.
37
38Example:
39
40s5k5bafx@2d {
41 compatible = "samsung,s5k5baf";
42 reg = <0x2d>;
43 vdda-supply = <&cam_io_en_reg>;
44 vddreg-supply = <&vt_core_15v_reg>;
45 vddio-supply = <&vtcam_reg>;
46 stbyn-gpios = <&gpl2 0 1>;
47 rstn-gpios = <&gpl2 1 1>;
48 clock-names = "mclk";
49 clocks = <&clock_cam 0>;
50 clock-frequency = <24000000>;
51
52 port {
53 s5k5bafx_ep: endpoint {
54 remote-endpoint = <&csis1_ep>;
55 data-lanes = <1>;
56 };
57 };
58};
diff --git a/Documentation/video4linux/omap4_camera.txt b/Documentation/video4linux/omap4_camera.txt
new file mode 100644
index 000000000000..25d9b40a4651
--- /dev/null
+++ b/Documentation/video4linux/omap4_camera.txt
@@ -0,0 +1,60 @@
1 OMAP4 ISS Driver
2 ================
3
4Introduction
5------------
6
7The OMAP44XX family of chips contains the Imaging SubSystem (a.k.a. ISS),
8Which contains several components that can be categorized in 3 big groups:
9
10- Interfaces (2 Interfaces: CSI2-A & CSI2-B/CCP2)
11- ISP (Image Signal Processor)
12- SIMCOP (Still Image Coprocessor)
13
14For more information, please look in [1] for latest version of:
15 "OMAP4430 Multimedia Device Silicon Revision 2.x"
16
17As of Revision AB, the ISS is described in detail in section 8.
18
19This driver is supporting _only_ the CSI2-A/B interfaces for now.
20
21It makes use of the Media Controller framework [2], and inherited most of the
22code from OMAP3 ISP driver (found under drivers/media/platform/omap3isp/*),
23except that it doesn't need an IOMMU now for ISS buffers memory mapping.
24
25Supports usage of MMAP buffers only (for now).
26
27Tested platforms
28----------------
29
30- OMAP4430SDP, w/ ES2.1 GP & SEVM4430-CAM-V1-0 (Contains IMX060 & OV5640, in
31 which only the last one is supported, outputting YUV422 frames).
32
33- TI Blaze MDP, w/ OMAP4430 ES2.2 EMU (Contains 1 IMX060 & 2 OV5650 sensors, in
34 which only the OV5650 are supported, outputting RAW10 frames).
35
36- PandaBoard, Rev. A2, w/ OMAP4430 ES2.1 GP & OV adapter board, tested with
37 following sensors:
38 * OV5640
39 * OV5650
40
41- Tested on mainline kernel:
42
43 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=summary
44
45 Tag: v3.3 (commit c16fa4f2ad19908a47c63d8fa436a1178438c7e7)
46
47File list
48---------
49drivers/staging/media/omap4iss/
50include/media/omap4iss.h
51
52References
53----------
54
55[1] http://focus.ti.com/general/docs/wtbu/wtbudocumentcenter.tsp?navigationId=12037&templateId=6123#62
56[2] http://lwn.net/Articles/420485/
57[3] http://www.spinics.net/lists/linux-media/msg44370.html
58--
59Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
60Copyright (C) 2012, Texas Instruments
diff --git a/Documentation/video4linux/si476x.txt b/Documentation/video4linux/si476x.txt
index 2f9b4875ab8a..616607955aaf 100644
--- a/Documentation/video4linux/si476x.txt
+++ b/Documentation/video4linux/si476x.txt
@@ -147,7 +147,7 @@ The drivers exposes following files:
147 -------------------------------------------------------------------- 147 --------------------------------------------------------------------
148 0x12 | readfreq | Current tuned frequency 148 0x12 | readfreq | Current tuned frequency
149 -------------------------------------------------------------------- 149 --------------------------------------------------------------------
150 0x14 | freqoff | Singed frequency offset in units of 150 0x14 | freqoff | Signed frequency offset in units of
151 | | 2ppm 151 | | 2ppm
152 -------------------------------------------------------------------- 152 --------------------------------------------------------------------
153 0x15 | rssi | Signed value of RSSI in dBuV 153 0x15 | rssi | Signed value of RSSI in dBuV
diff --git a/MAINTAINERS b/MAINTAINERS
index 6fb8759f49de..dc2fd2298090 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5425,6 +5425,16 @@ W: http://www.tazenda.demon.co.uk/phil/linux-hp
5425S: Maintained 5425S: Maintained
5426F: arch/m68k/hp300/ 5426F: arch/m68k/hp300/
5427 5427
5428M88DS3103 MEDIA DRIVER
5429M: Antti Palosaari <crope@iki.fi>
5430L: linux-media@vger.kernel.org
5431W: http://linuxtv.org/
5432W: http://palosaari.fi/linux/
5433Q: http://patchwork.linuxtv.org/project/linux-media/list/
5434T: git git://linuxtv.org/anttip/media_tree.git
5435S: Maintained
5436F: drivers/media/dvb-frontends/m88ds3103*
5437
5428M88RS2000 MEDIA DRIVER 5438M88RS2000 MEDIA DRIVER
5429M: Malcolm Priestley <tvboxspy@gmail.com> 5439M: Malcolm Priestley <tvboxspy@gmail.com>
5430L: linux-media@vger.kernel.org 5440L: linux-media@vger.kernel.org
@@ -5433,6 +5443,16 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
5433S: Maintained 5443S: Maintained
5434F: drivers/media/dvb-frontends/m88rs2000* 5444F: drivers/media/dvb-frontends/m88rs2000*
5435 5445
5446M88TS2022 MEDIA DRIVER
5447M: Antti Palosaari <crope@iki.fi>
5448L: linux-media@vger.kernel.org
5449W: http://linuxtv.org/
5450W: http://palosaari.fi/linux/
5451Q: http://patchwork.linuxtv.org/project/linux-media/list/
5452T: git git://linuxtv.org/anttip/media_tree.git
5453S: Maintained
5454F: drivers/media/tuners/m88ts2022*
5455
5436MA901 MASTERKIT USB FM RADIO DRIVER 5456MA901 MASTERKIT USB FM RADIO DRIVER
5437M: Alexey Klimov <klimov.linux@gmail.com> 5457M: Alexey Klimov <klimov.linux@gmail.com>
5438L: linux-media@vger.kernel.org 5458L: linux-media@vger.kernel.org
@@ -7471,6 +7491,13 @@ L: linux-media@vger.kernel.org
7471S: Supported 7491S: Supported
7472F: drivers/media/i2c/s5c73m3/* 7492F: drivers/media/i2c/s5c73m3/*
7473 7493
7494SAMSUNG S5K5BAF CAMERA DRIVER
7495M: Kyungmin Park <kyungmin.park@samsung.com>
7496M: Andrzej Hajda <a.hajda@samsung.com>
7497L: linux-media@vger.kernel.org
7498S: Supported
7499F: drivers/media/i2c/s5k5baf.c
7500
7474SAMSUNG SOC CLOCK DRIVERS 7501SAMSUNG SOC CLOCK DRIVERS
7475M: Tomasz Figa <t.figa@samsung.com> 7502M: Tomasz Figa <t.figa@samsung.com>
7476S: Supported 7503S: Supported
@@ -7774,7 +7801,7 @@ L: linux-media@vger.kernel.org
7774T: git git://linuxtv.org/media_tree.git 7801T: git git://linuxtv.org/media_tree.git
7775W: http://linuxtv.org 7802W: http://linuxtv.org
7776S: Odd Fixes 7803S: Odd Fixes
7777F: drivers/media/radio/si4713-i2c.? 7804F: drivers/media/radio/si4713/si4713.?
7778 7805
7779SI4713 FM RADIO TRANSMITTER PLATFORM DRIVER 7806SI4713 FM RADIO TRANSMITTER PLATFORM DRIVER
7780M: Eduardo Valentin <edubezval@gmail.com> 7807M: Eduardo Valentin <edubezval@gmail.com>
@@ -7782,7 +7809,15 @@ L: linux-media@vger.kernel.org
7782T: git git://linuxtv.org/media_tree.git 7809T: git git://linuxtv.org/media_tree.git
7783W: http://linuxtv.org 7810W: http://linuxtv.org
7784S: Odd Fixes 7811S: Odd Fixes
7785F: drivers/media/radio/radio-si4713.c 7812F: drivers/media/radio/si4713/radio-platform-si4713.c
7813
7814SI4713 FM RADIO TRANSMITTER USB DRIVER
7815M: Hans Verkuil <hverkuil@xs4all.nl>
7816L: linux-media@vger.kernel.org
7817T: git git://linuxtv.org/media_tree.git
7818W: http://linuxtv.org
7819S: Maintained
7820F: drivers/media/radio/si4713/radio-usb-si4713.c
7786 7821
7787SIANO DVB DRIVER 7822SIANO DVB DRIVER
7788M: Mauro Carvalho Chehab <m.chehab@samsung.com> 7823M: Mauro Carvalho Chehab <m.chehab@samsung.com>
@@ -8634,6 +8669,14 @@ L: linux-xtensa@linux-xtensa.org
8634S: Maintained 8669S: Maintained
8635F: arch/xtensa/ 8670F: arch/xtensa/
8636 8671
8672THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
8673M: Hans Verkuil <hverkuil@xs4all.nl>
8674L: linux-media@vger.kernel.org
8675T: git git://linuxtv.org/media_tree.git
8676W: http://linuxtv.org
8677S: Maintained
8678F: drivers/media/radio/radio-raremono.c
8679
8637THERMAL 8680THERMAL
8638M: Zhang Rui <rui.zhang@intel.com> 8681M: Zhang Rui <rui.zhang@intel.com>
8639M: Eduardo Valentin <eduardo.valentin@ti.com> 8682M: Eduardo Valentin <eduardo.valentin@ti.com>
@@ -9166,8 +9209,7 @@ L: linux-media@vger.kernel.org
9166T: git git://linuxtv.org/media_tree.git 9209T: git git://linuxtv.org/media_tree.git
9167W: http://www.linux-projects.org 9210W: http://www.linux-projects.org
9168S: Maintained 9211S: Maintained
9169F: Documentation/video4linux/sn9c102.txt 9212F: drivers/staging/media/sn9c102/
9170F: drivers/media/usb/sn9c102/
9171 9213
9172USB SUBSYSTEM 9214USB SUBSYSTEM
9173M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 9215M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index f093af17f5e6..8760bbe3baab 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -760,7 +760,14 @@ static struct regulator_init_data rx51_vintdig = {
760 }, 760 },
761}; 761};
762 762
763static const char * const si4713_supply_names[] = {
764 "vio",
765 "vdd",
766};
767
763static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = { 768static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
769 .supplies = ARRAY_SIZE(si4713_supply_names),
770 .supply_names = si4713_supply_names,
764 .gpio_reset = RX51_FMTX_RESET_GPIO, 771 .gpio_reset = RX51_FMTX_RESET_GPIO,
765}; 772};
766 773
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index 05194e95981b..8de8bc690b36 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -1025,7 +1025,9 @@ static struct adv7842_platform_data adv7842_data = {
1025 .ain_sel = ADV7842_AIN10_11_12_NC_SYNC_4_1, 1025 .ain_sel = ADV7842_AIN10_11_12_NC_SYNC_4_1,
1026 .prim_mode = ADV7842_PRIM_MODE_SDP, 1026 .prim_mode = ADV7842_PRIM_MODE_SDP,
1027 .vid_std_select = ADV7842_SDP_VID_STD_CVBS_SD_4x1, 1027 .vid_std_select = ADV7842_SDP_VID_STD_CVBS_SD_4x1,
1028 .inp_color_space = ADV7842_INP_COLOR_SPACE_AUTO, 1028 .hdmi_free_run_enable = 1,
1029 .sdp_free_run_auto = 1,
1030 .llc_dll_phase = 0x10,
1029 .i2c_sdp_io = 0x40, 1031 .i2c_sdp_io = 0x40,
1030 .i2c_sdp = 0x41, 1032 .i2c_sdp = 0x41,
1031 .i2c_cp = 0x42, 1033 .i2c_cp = 0x42,
diff --git a/arch/score/lib/checksum.S b/arch/score/lib/checksum.S
index 706157edc7d5..1141f2b4a501 100644
--- a/arch/score/lib/checksum.S
+++ b/arch/score/lib/checksum.S
@@ -137,7 +137,7 @@ ENTRY(csum_partial)
137 ldi r25, 0 137 ldi r25, 0
138 mv r10, r5 138 mv r10, r5
139 cmpi.c r5, 0x8 139 cmpi.c r5, 0x8
140 blt small_csumcpy /* < 8(singed) bytes to copy */ 140 blt small_csumcpy /* < 8(signed) bytes to copy */
141 cmpi.c r5, 0x0 141 cmpi.c r5, 0x0
142 beq out 142 beq out
143 andri.c r25, src, 0x1 /* odd buffer? */ 143 andri.c r25, src, 0x1 /* odd buffer? */
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 026ab0fc06f7..3bfac3accd22 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2118,6 +2118,7 @@ static const struct hid_device_id hid_ignore_list[] = {
2118 { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, 2118 { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) },
2119 { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, 2119 { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) },
2120 { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, 2120 { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) },
2121 { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI4713) },
2121 { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, 2122 { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) },
2122 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, 2123 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) },
2123 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, 2124 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 92b40c09d917..5a5248f2cc07 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -241,6 +241,8 @@
241#define USB_VENDOR_ID_CYGNAL 0x10c4 241#define USB_VENDOR_ID_CYGNAL 0x10c4
242#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a 242#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a
243 243
244#define USB_DEVICE_ID_CYGNAL_RADIO_SI4713 0x8244
245
244#define USB_VENDOR_ID_CYPRESS 0x04b4 246#define USB_VENDOR_ID_CYPRESS 0x04b4
245#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 247#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
246#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 248#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 8270388e2a0d..1d0758aeb8e4 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -172,6 +172,9 @@ comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
172config MEDIA_SUBDRV_AUTOSELECT 172config MEDIA_SUBDRV_AUTOSELECT
173 bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)" 173 bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)"
174 depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT 174 depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT
175 depends on HAS_IOMEM
176 select I2C
177 select I2C_MUX
175 default y 178 default y
176 help 179 help
177 By default, a media driver auto-selects all possible ancillary 180 By default, a media driver auto-selects all possible ancillary
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 419a2d6b4349..f19a2ccd1e4b 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -239,6 +239,7 @@
239#define USB_PID_AVERMEDIA_A835B_4835 0x4835 239#define USB_PID_AVERMEDIA_A835B_4835 0x4835
240#define USB_PID_AVERMEDIA_1867 0x1867 240#define USB_PID_AVERMEDIA_1867 0x1867
241#define USB_PID_AVERMEDIA_A867 0xa867 241#define USB_PID_AVERMEDIA_A867 0xa867
242#define USB_PID_AVERMEDIA_H335 0x0335
242#define USB_PID_AVERMEDIA_TWINSTAR 0x0825 243#define USB_PID_AVERMEDIA_TWINSTAR 0x0825
243#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 244#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
244#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 245#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
@@ -317,6 +318,7 @@
317#define USB_PID_WINFAST_DTV_DONGLE_H 0x60f6 318#define USB_PID_WINFAST_DTV_DONGLE_H 0x60f6
318#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 319#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01
319#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 320#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029
321#define USB_PID_WINFAST_DTV_DONGLE_MINID 0x6f0f
320#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 322#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200
321#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201 323#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201
322#define USB_PID_GENPIX_8PSK_REV_2 0x0202 324#define USB_PID_GENPIX_8PSK_REV_2 0x0202
@@ -365,6 +367,7 @@
365#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac 367#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac
366#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 368#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001
367#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 369#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
370#define USB_PID_TECHNISAT_USB2_CABLESTAR_HDCI 0x0003
368#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004 371#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004
369#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500 372#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
370#define USB_PID_CPYTO_REDI_PC50A 0xa803 373#define USB_PID_CPYTO_REDI_PC50A 0xa803
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index bddbab43a2df..dd12a1ebda82 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -35,6 +35,13 @@ config DVB_STV6110x
35 help 35 help
36 A Silicon tuner that supports DVB-S and DVB-S2 modes 36 A Silicon tuner that supports DVB-S and DVB-S2 modes
37 37
38config DVB_M88DS3103
39 tristate "Montage M88DS3103"
40 depends on DVB_CORE && I2C && I2C_MUX
41 default m if !MEDIA_SUBDRV_AUTOSELECT
42 help
43 Say Y when you want to support this frontend.
44
38comment "Multistandard (cable + terrestrial) frontends" 45comment "Multistandard (cable + terrestrial) frontends"
39 depends on DVB_CORE 46 depends on DVB_CORE
40 47
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index f9cb43d9aed9..0c75a6aafb9d 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_DVB_STV6110) += stv6110.o
85obj-$(CONFIG_DVB_STV0900) += stv0900.o 85obj-$(CONFIG_DVB_STV0900) += stv0900.o
86obj-$(CONFIG_DVB_STV090x) += stv090x.o 86obj-$(CONFIG_DVB_STV090x) += stv090x.o
87obj-$(CONFIG_DVB_STV6110x) += stv6110x.o 87obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
88obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
88obj-$(CONFIG_DVB_ISL6423) += isl6423.o 89obj-$(CONFIG_DVB_ISL6423) += isl6423.o
89obj-$(CONFIG_DVB_EC100) += ec100.o 90obj-$(CONFIG_DVB_EC100) += ec100.o
90obj-$(CONFIG_DVB_HD29L2) += hd29l2.o 91obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c
index 74fbb5d58bed..780da58132f1 100644
--- a/drivers/media/dvb-frontends/a8293.c
+++ b/drivers/media/dvb-frontends/a8293.c
@@ -96,6 +96,8 @@ static int a8293_set_voltage(struct dvb_frontend *fe,
96 if (ret) 96 if (ret)
97 goto err; 97 goto err;
98 98
99 usleep_range(1500, 50000);
100
99 return ret; 101 return ret;
100err: 102err:
101 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 103 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c
index 476b422ccf19..68f768a5422d 100644
--- a/drivers/media/dvb-frontends/cx24117.c
+++ b/drivers/media/dvb-frontends/cx24117.c
@@ -135,15 +135,33 @@
135 135
136 136
137enum cmds { 137enum cmds {
138 CMD_SET_VCO = 0x10, 138 CMD_SET_VCOFREQ = 0x10,
139 CMD_TUNEREQUEST = 0x11, 139 CMD_TUNEREQUEST = 0x11,
140 CMD_MPEGCONFIG = 0x13, 140 CMD_GLOBAL_MPEGCFG = 0x13,
141 CMD_TUNERINIT = 0x14, 141 CMD_MPEGCFG = 0x14,
142 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ 142 CMD_TUNERINIT = 0x15,
143 CMD_LNBDCLEVEL = 0x22, 143 CMD_GET_SRATE = 0x18,
144 CMD_SET_TONE = 0x23, 144 CMD_SET_GOLDCODE = 0x19,
145 CMD_UPDFWVERS = 0x35, 145 CMD_GET_AGCACC = 0x1a,
146 CMD_TUNERSLEEP = 0x36, 146 CMD_DEMODINIT = 0x1b,
147 CMD_GETCTLACC = 0x1c,
148
149 CMD_LNBCONFIG = 0x20,
150 CMD_LNBSEND = 0x21,
151 CMD_LNBDCLEVEL = 0x22,
152 CMD_LNBPCBCONFIG = 0x23,
153 CMD_LNBSENDTONEBST = 0x24,
154 CMD_LNBUPDREPLY = 0x25,
155
156 CMD_SET_GPIOMODE = 0x30,
157 CMD_SET_GPIOEN = 0x31,
158 CMD_SET_GPIODIR = 0x32,
159 CMD_SET_GPIOOUT = 0x33,
160 CMD_ENABLERSCORR = 0x34,
161 CMD_FWVERSION = 0x35,
162 CMD_SET_SLEEPMODE = 0x36,
163 CMD_BERCTRL = 0x3c,
164 CMD_EVENTCTRL = 0x3d,
147}; 165};
148 166
149static LIST_HEAD(hybrid_tuner_instance_list); 167static LIST_HEAD(hybrid_tuner_instance_list);
@@ -619,8 +637,8 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
619 cx24117_writereg(state, 0xf7, 0x0c); 637 cx24117_writereg(state, 0xf7, 0x0c);
620 cx24117_writereg(state, 0xe0, 0x00); 638 cx24117_writereg(state, 0xe0, 0x00);
621 639
622 /* CMD 1B */ 640 /* Init demodulator */
623 cmd.args[0] = 0x1b; 641 cmd.args[0] = CMD_DEMODINIT;
624 cmd.args[1] = 0x00; 642 cmd.args[1] = 0x00;
625 cmd.args[2] = 0x01; 643 cmd.args[2] = 0x01;
626 cmd.args[3] = 0x00; 644 cmd.args[3] = 0x00;
@@ -629,8 +647,8 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
629 if (ret != 0) 647 if (ret != 0)
630 goto error; 648 goto error;
631 649
632 /* CMD 10 */ 650 /* Set VCO frequency */
633 cmd.args[0] = CMD_SET_VCO; 651 cmd.args[0] = CMD_SET_VCOFREQ;
634 cmd.args[1] = 0x06; 652 cmd.args[1] = 0x06;
635 cmd.args[2] = 0x2b; 653 cmd.args[2] = 0x2b;
636 cmd.args[3] = 0xd8; 654 cmd.args[3] = 0xd8;
@@ -648,8 +666,8 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
648 if (ret != 0) 666 if (ret != 0)
649 goto error; 667 goto error;
650 668
651 /* CMD 15 */ 669 /* Tuner init */
652 cmd.args[0] = 0x15; 670 cmd.args[0] = CMD_TUNERINIT;
653 cmd.args[1] = 0x00; 671 cmd.args[1] = 0x00;
654 cmd.args[2] = 0x01; 672 cmd.args[2] = 0x01;
655 cmd.args[3] = 0x00; 673 cmd.args[3] = 0x00;
@@ -667,8 +685,8 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
667 if (ret != 0) 685 if (ret != 0)
668 goto error; 686 goto error;
669 687
670 /* CMD 13 */ 688 /* Global MPEG config */
671 cmd.args[0] = CMD_MPEGCONFIG; 689 cmd.args[0] = CMD_GLOBAL_MPEGCFG;
672 cmd.args[1] = 0x00; 690 cmd.args[1] = 0x00;
673 cmd.args[2] = 0x00; 691 cmd.args[2] = 0x00;
674 cmd.args[3] = 0x00; 692 cmd.args[3] = 0x00;
@@ -679,9 +697,9 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
679 if (ret != 0) 697 if (ret != 0)
680 goto error; 698 goto error;
681 699
682 /* CMD 14 */ 700 /* MPEG config for each demod */
683 for (i = 0; i < 2; i++) { 701 for (i = 0; i < 2; i++) {
684 cmd.args[0] = CMD_TUNERINIT; 702 cmd.args[0] = CMD_MPEGCFG;
685 cmd.args[1] = (u8) i; 703 cmd.args[1] = (u8) i;
686 cmd.args[2] = 0x00; 704 cmd.args[2] = 0x00;
687 cmd.args[3] = 0x05; 705 cmd.args[3] = 0x05;
@@ -699,8 +717,8 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
699 cx24117_writereg(state, 0xcf, 0x00); 717 cx24117_writereg(state, 0xcf, 0x00);
700 cx24117_writereg(state, 0xe5, 0x04); 718 cx24117_writereg(state, 0xe5, 0x04);
701 719
702 /* Firmware CMD 35: Get firmware version */ 720 /* Get firmware version */
703 cmd.args[0] = CMD_UPDFWVERS; 721 cmd.args[0] = CMD_FWVERSION;
704 cmd.len = 2; 722 cmd.len = 2;
705 for (i = 0; i < 4; i++) { 723 for (i = 0; i < 4; i++) {
706 cmd.args[1] = i; 724 cmd.args[1] = i;
@@ -779,8 +797,8 @@ static int cx24117_read_signal_strength(struct dvb_frontend *fe,
779 u8 reg = (state->demod == 0) ? 797 u8 reg = (state->demod == 0) ?
780 CX24117_REG_SSTATUS0 : CX24117_REG_SSTATUS1; 798 CX24117_REG_SSTATUS0 : CX24117_REG_SSTATUS1;
781 799
782 /* Firmware CMD 1A */ 800 /* Read AGC accumulator register */
783 cmd.args[0] = 0x1a; 801 cmd.args[0] = CMD_GET_AGCACC;
784 cmd.args[1] = (u8) state->demod; 802 cmd.args[1] = (u8) state->demod;
785 cmd.len = 2; 803 cmd.len = 2;
786 ret = cx24117_cmd_execute(fe, &cmd); 804 ret = cx24117_cmd_execute(fe, &cmd);
@@ -899,22 +917,15 @@ static int cx24117_set_voltage(struct dvb_frontend *fe,
899 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : 917 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" :
900 "SEC_VOLTAGE_OFF"); 918 "SEC_VOLTAGE_OFF");
901 919
902 /* CMD 32 */ 920 /* Prepare a set GPIO logic level CMD */
903 cmd.args[0] = 0x32; 921 cmd.args[0] = CMD_SET_GPIOOUT;
904 cmd.args[1] = reg; 922 cmd.args[2] = reg; /* mask */
905 cmd.args[2] = reg;
906 cmd.len = 3; 923 cmd.len = 3;
907 ret = cx24117_cmd_execute(fe, &cmd);
908 if (ret)
909 return ret;
910 924
911 if ((voltage == SEC_VOLTAGE_13) || 925 if ((voltage == SEC_VOLTAGE_13) ||
912 (voltage == SEC_VOLTAGE_18)) { 926 (voltage == SEC_VOLTAGE_18)) {
913 /* CMD 33 */ 927 /* power on LNB */
914 cmd.args[0] = 0x33;
915 cmd.args[1] = reg; 928 cmd.args[1] = reg;
916 cmd.args[2] = reg;
917 cmd.len = 3;
918 ret = cx24117_cmd_execute(fe, &cmd); 929 ret = cx24117_cmd_execute(fe, &cmd);
919 if (ret != 0) 930 if (ret != 0)
920 return ret; 931 return ret;
@@ -926,22 +937,22 @@ static int cx24117_set_voltage(struct dvb_frontend *fe,
926 /* Wait for voltage/min repeat delay */ 937 /* Wait for voltage/min repeat delay */
927 msleep(100); 938 msleep(100);
928 939
929 /* CMD 22 - CMD_LNBDCLEVEL */ 940 /* Set 13V/18V select pin */
930 cmd.args[0] = CMD_LNBDCLEVEL; 941 cmd.args[0] = CMD_LNBDCLEVEL;
931 cmd.args[1] = state->demod ? 0 : 1; 942 cmd.args[1] = state->demod ? 0 : 1;
932 cmd.args[2] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00); 943 cmd.args[2] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
933 cmd.len = 3; 944 cmd.len = 3;
945 ret = cx24117_cmd_execute(fe, &cmd);
934 946
935 /* Min delay time before DiSEqC send */ 947 /* Min delay time before DiSEqC send */
936 msleep(20); 948 msleep(20);
937 } else { 949 } else {
938 cmd.args[0] = 0x33; 950 /* power off LNB */
939 cmd.args[1] = 0x00; 951 cmd.args[1] = 0x00;
940 cmd.args[2] = reg; 952 ret = cx24117_cmd_execute(fe, &cmd);
941 cmd.len = 3;
942 } 953 }
943 954
944 return cx24117_cmd_execute(fe, &cmd); 955 return ret;
945} 956}
946 957
947static int cx24117_set_tone(struct dvb_frontend *fe, 958static int cx24117_set_tone(struct dvb_frontend *fe,
@@ -968,8 +979,7 @@ static int cx24117_set_tone(struct dvb_frontend *fe,
968 msleep(20); 979 msleep(20);
969 980
970 /* Set the tone */ 981 /* Set the tone */
971 /* CMD 23 - CMD_SET_TONE */ 982 cmd.args[0] = CMD_LNBPCBCONFIG;
972 cmd.args[0] = CMD_SET_TONE;
973 cmd.args[1] = (state->demod ? 0 : 1); 983 cmd.args[1] = (state->demod ? 0 : 1);
974 cmd.args[2] = 0x00; 984 cmd.args[2] = 0x00;
975 cmd.args[3] = 0x00; 985 cmd.args[3] = 0x00;
@@ -1231,8 +1241,8 @@ static int cx24117_initfe(struct dvb_frontend *fe)
1231 1241
1232 mutex_lock(&state->priv->fe_lock); 1242 mutex_lock(&state->priv->fe_lock);
1233 1243
1234 /* Firmware CMD 36: Power config */ 1244 /* Set sleep mode off */
1235 cmd.args[0] = CMD_TUNERSLEEP; 1245 cmd.args[0] = CMD_SET_SLEEPMODE;
1236 cmd.args[1] = (state->demod ? 1 : 0); 1246 cmd.args[1] = (state->demod ? 1 : 0);
1237 cmd.args[2] = 0; 1247 cmd.args[2] = 0;
1238 cmd.len = 3; 1248 cmd.len = 3;
@@ -1244,8 +1254,8 @@ static int cx24117_initfe(struct dvb_frontend *fe)
1244 if (ret != 0) 1254 if (ret != 0)
1245 goto exit; 1255 goto exit;
1246 1256
1247 /* CMD 3C */ 1257 /* Set BER control */
1248 cmd.args[0] = 0x3c; 1258 cmd.args[0] = CMD_BERCTRL;
1249 cmd.args[1] = (state->demod ? 1 : 0); 1259 cmd.args[1] = (state->demod ? 1 : 0);
1250 cmd.args[2] = 0x10; 1260 cmd.args[2] = 0x10;
1251 cmd.args[3] = 0x10; 1261 cmd.args[3] = 0x10;
@@ -1254,12 +1264,22 @@ static int cx24117_initfe(struct dvb_frontend *fe)
1254 if (ret != 0) 1264 if (ret != 0)
1255 goto exit; 1265 goto exit;
1256 1266
1257 /* CMD 34 */ 1267 /* Set RS correction (enable/disable) */
1258 cmd.args[0] = 0x34; 1268 cmd.args[0] = CMD_ENABLERSCORR;
1259 cmd.args[1] = (state->demod ? 1 : 0); 1269 cmd.args[1] = (state->demod ? 1 : 0);
1260 cmd.args[2] = CX24117_OCC; 1270 cmd.args[2] = CX24117_OCC;
1261 cmd.len = 3; 1271 cmd.len = 3;
1262 ret = cx24117_cmd_execute_nolock(fe, &cmd); 1272 ret = cx24117_cmd_execute_nolock(fe, &cmd);
1273 if (ret != 0)
1274 goto exit;
1275
1276 /* Set GPIO direction */
1277 /* Set as output - controls LNB power on/off */
1278 cmd.args[0] = CMD_SET_GPIODIR;
1279 cmd.args[1] = 0x30;
1280 cmd.args[2] = 0x30;
1281 cmd.len = 3;
1282 ret = cx24117_cmd_execute_nolock(fe, &cmd);
1263 1283
1264exit: 1284exit:
1265 mutex_unlock(&state->priv->fe_lock); 1285 mutex_unlock(&state->priv->fe_lock);
@@ -1278,8 +1298,8 @@ static int cx24117_sleep(struct dvb_frontend *fe)
1278 dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n", 1298 dev_dbg(&state->priv->i2c->dev, "%s() demod%d\n",
1279 __func__, state->demod); 1299 __func__, state->demod);
1280 1300
1281 /* Firmware CMD 36: Power config */ 1301 /* Set sleep mode on */
1282 cmd.args[0] = CMD_TUNERSLEEP; 1302 cmd.args[0] = CMD_SET_SLEEPMODE;
1283 cmd.args[1] = (state->demod ? 1 : 0); 1303 cmd.args[1] = (state->demod ? 1 : 0);
1284 cmd.args[2] = 1; 1304 cmd.args[2] = 1;
1285 cmd.len = 3; 1305 cmd.len = 3;
@@ -1558,7 +1578,8 @@ static int cx24117_get_frontend(struct dvb_frontend *fe)
1558 1578
1559 u8 buf[0x1f-4]; 1579 u8 buf[0x1f-4];
1560 1580
1561 cmd.args[0] = 0x1c; 1581 /* Read current tune parameters */
1582 cmd.args[0] = CMD_GETCTLACC;
1562 cmd.args[1] = (u8) state->demod; 1583 cmd.args[1] = (u8) state->demod;
1563 cmd.len = 2; 1584 cmd.len = 2;
1564 ret = cx24117_cmd_execute(fe, &cmd); 1585 ret = cx24117_cmd_execute(fe, &cmd);
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 6dbbee453ee1..1632d78a5479 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -11,6 +11,7 @@
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/i2c.h> 12#include <linux/i2c.h>
13#include <linux/mutex.h> 13#include <linux/mutex.h>
14#include <asm/div64.h>
14 15
15#include "dvb_math.h" 16#include "dvb_math.h"
16 17
@@ -118,6 +119,12 @@ struct dib8000_state {
118 u8 longest_intlv_layer; 119 u8 longest_intlv_layer;
119 u16 output_mode; 120 u16 output_mode;
120 121
122 /* for DVBv5 stats */
123 s64 init_ucb;
124 unsigned long per_jiffies_stats;
125 unsigned long ber_jiffies_stats;
126 unsigned long ber_jiffies_stats_layer[3];
127
121#ifdef DIB8000_AGC_FREEZE 128#ifdef DIB8000_AGC_FREEZE
122 u16 agc1_max; 129 u16 agc1_max;
123 u16 agc1_min; 130 u16 agc1_min;
@@ -157,15 +164,10 @@ static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
157 return ret; 164 return ret;
158} 165}
159 166
160static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) 167static u16 __dib8000_read_word(struct dib8000_state *state, u16 reg)
161{ 168{
162 u16 ret; 169 u16 ret;
163 170
164 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
165 dprintk("could not acquire lock");
166 return 0;
167 }
168
169 state->i2c_write_buffer[0] = reg >> 8; 171 state->i2c_write_buffer[0] = reg >> 8;
170 state->i2c_write_buffer[1] = reg & 0xff; 172 state->i2c_write_buffer[1] = reg & 0xff;
171 173
@@ -183,6 +185,21 @@ static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
183 dprintk("i2c read error on %d", reg); 185 dprintk("i2c read error on %d", reg);
184 186
185 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; 187 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
188
189 return ret;
190}
191
192static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
193{
194 u16 ret;
195
196 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
197 dprintk("could not acquire lock");
198 return 0;
199 }
200
201 ret = __dib8000_read_word(state, reg);
202
186 mutex_unlock(&state->i2c_buffer_lock); 203 mutex_unlock(&state->i2c_buffer_lock);
187 204
188 return ret; 205 return ret;
@@ -192,8 +209,15 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
192{ 209{
193 u16 rw[2]; 210 u16 rw[2];
194 211
195 rw[0] = dib8000_read_word(state, reg + 0); 212 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
196 rw[1] = dib8000_read_word(state, reg + 1); 213 dprintk("could not acquire lock");
214 return 0;
215 }
216
217 rw[0] = __dib8000_read_word(state, reg + 0);
218 rw[1] = __dib8000_read_word(state, reg + 1);
219
220 mutex_unlock(&state->i2c_buffer_lock);
197 221
198 return ((rw[0] << 16) | (rw[1])); 222 return ((rw[0] << 16) | (rw[1]));
199} 223}
@@ -787,7 +811,7 @@ int dib8000_update_pll(struct dvb_frontend *fe,
787 dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio); 811 dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio);
788 dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */ 812 dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */
789 } 813 }
790} 814 }
791 815
792 return 0; 816 return 0;
793} 817}
@@ -966,6 +990,45 @@ static u16 dib8000_identify(struct i2c_device *client)
966 return value; 990 return value;
967} 991}
968 992
993static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 *unc);
994
995static void dib8000_reset_stats(struct dvb_frontend *fe)
996{
997 struct dib8000_state *state = fe->demodulator_priv;
998 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
999 u32 ucb;
1000
1001 memset(&c->strength, 0, sizeof(c->strength));
1002 memset(&c->cnr, 0, sizeof(c->cnr));
1003 memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
1004 memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
1005 memset(&c->block_error, 0, sizeof(c->block_error));
1006
1007 c->strength.len = 1;
1008 c->cnr.len = 1;
1009 c->block_error.len = 1;
1010 c->block_count.len = 1;
1011 c->post_bit_error.len = 1;
1012 c->post_bit_count.len = 1;
1013
1014 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1015 c->strength.stat[0].uvalue = 0;
1016
1017 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1018 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1019 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1020 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1021 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1022
1023 dib8000_read_unc_blocks(fe, &ucb);
1024
1025 state->init_ucb = -ucb;
1026 state->ber_jiffies_stats = 0;
1027 state->per_jiffies_stats = 0;
1028 memset(&state->ber_jiffies_stats_layer, 0,
1029 sizeof(state->ber_jiffies_stats_layer));
1030}
1031
969static int dib8000_reset(struct dvb_frontend *fe) 1032static int dib8000_reset(struct dvb_frontend *fe)
970{ 1033{
971 struct dib8000_state *state = fe->demodulator_priv; 1034 struct dib8000_state *state = fe->demodulator_priv;
@@ -1071,6 +1134,8 @@ static int dib8000_reset(struct dvb_frontend *fe)
1071 1134
1072 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); 1135 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1073 1136
1137 dib8000_reset_stats(fe);
1138
1074 return 0; 1139 return 0;
1075} 1140}
1076 1141
@@ -2445,7 +2510,8 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe)
2445 if (state->revision == 0x8090) 2510 if (state->revision == 0x8090)
2446 internal = dib8000_read32(state, 23) / 1000; 2511 internal = dib8000_read32(state, 23) / 1000;
2447 2512
2448 if (state->autosearch_state == AS_SEARCHING_FFT) { 2513 if ((state->revision >= 0x8002) &&
2514 (state->autosearch_state == AS_SEARCHING_FFT)) {
2449 dib8000_write_word(state, 37, 0x0065); /* P_ctrl_pha_off_max default values */ 2515 dib8000_write_word(state, 37, 0x0065); /* P_ctrl_pha_off_max default values */
2450 dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */ 2516 dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */
2451 2517
@@ -2481,7 +2547,8 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe)
2481 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */ 2547 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */
2482 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */ 2548 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */
2483 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */ 2549 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */
2484 } else if (state->autosearch_state == AS_SEARCHING_GUARD) { 2550 } else if ((state->revision >= 0x8002) &&
2551 (state->autosearch_state == AS_SEARCHING_GUARD)) {
2485 c->transmission_mode = TRANSMISSION_MODE_8K; 2552 c->transmission_mode = TRANSMISSION_MODE_8K;
2486 c->guard_interval = GUARD_INTERVAL_1_8; 2553 c->guard_interval = GUARD_INTERVAL_1_8;
2487 c->inversion = 0; 2554 c->inversion = 0;
@@ -2583,7 +2650,8 @@ static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2583 struct dib8000_state *state = fe->demodulator_priv; 2650 struct dib8000_state *state = fe->demodulator_priv;
2584 u16 irq_pending = dib8000_read_word(state, 1284); 2651 u16 irq_pending = dib8000_read_word(state, 1284);
2585 2652
2586 if (state->autosearch_state == AS_SEARCHING_FFT) { 2653 if ((state->revision >= 0x8002) &&
2654 (state->autosearch_state == AS_SEARCHING_FFT)) {
2587 if (irq_pending & 0x1) { 2655 if (irq_pending & 0x1) {
2588 dprintk("dib8000_autosearch_irq: max correlation result available"); 2656 dprintk("dib8000_autosearch_irq: max correlation result available");
2589 return 3; 2657 return 3;
@@ -2853,6 +2921,91 @@ static int dib8090p_init_sdram(struct dib8000_state *state)
2853 return 0; 2921 return 0;
2854} 2922}
2855 2923
2924/**
2925 * is_manual_mode - Check if TMCC should be used for parameters settings
2926 * @c: struct dvb_frontend_properties
2927 *
2928 * By default, TMCC table should be used for parameter settings on most
2929 * usercases. However, sometimes it is desirable to lock the demod to
2930 * use the manual parameters.
2931 *
2932 * On manual mode, the current dib8000_tune state machine is very restrict:
2933 * It requires that both per-layer and per-transponder parameters to be
2934 * properly specified, otherwise the device won't lock.
2935 *
2936 * Check if all those conditions are properly satisfied before allowing
2937 * the device to use the manual frequency lock mode.
2938 */
2939static int is_manual_mode(struct dtv_frontend_properties *c)
2940{
2941 int i, n_segs = 0;
2942
2943 /* Use auto mode on DVB-T compat mode */
2944 if (c->delivery_system != SYS_ISDBT)
2945 return 0;
2946
2947 /*
2948 * Transmission mode is only detected on auto mode, currently
2949 */
2950 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2951 dprintk("transmission mode auto");
2952 return 0;
2953 }
2954
2955 /*
2956 * Guard interval is only detected on auto mode, currently
2957 */
2958 if (c->guard_interval == GUARD_INTERVAL_AUTO) {
2959 dprintk("guard interval auto");
2960 return 0;
2961 }
2962
2963 /*
2964 * If no layer is enabled, assume auto mode, as at least one
2965 * layer should be enabled
2966 */
2967 if (!c->isdbt_layer_enabled) {
2968 dprintk("no layer modulation specified");
2969 return 0;
2970 }
2971
2972 /*
2973 * Check if the per-layer parameters aren't auto and
2974 * disable a layer if segment count is 0 or invalid.
2975 */
2976 for (i = 0; i < 3; i++) {
2977 if (!(c->isdbt_layer_enabled & 1 << i))
2978 continue;
2979
2980 if ((c->layer[i].segment_count > 13) ||
2981 (c->layer[i].segment_count == 0)) {
2982 c->isdbt_layer_enabled &= ~(1 << i);
2983 continue;
2984 }
2985
2986 n_segs += c->layer[i].segment_count;
2987
2988 if ((c->layer[i].modulation == QAM_AUTO) ||
2989 (c->layer[i].fec == FEC_AUTO)) {
2990 dprintk("layer %c has either modulation or FEC auto",
2991 'A' + i);
2992 return 0;
2993 }
2994 }
2995
2996 /*
2997 * Userspace specified a wrong number of segments.
2998 * fallback to auto mode.
2999 */
3000 if (n_segs == 0 || n_segs > 13) {
3001 dprintk("number of segments is invalid");
3002 return 0;
3003 }
3004
3005 /* Everything looks ok for manual mode */
3006 return 1;
3007}
3008
2856static int dib8000_tune(struct dvb_frontend *fe) 3009static int dib8000_tune(struct dvb_frontend *fe)
2857{ 3010{
2858 struct dib8000_state *state = fe->demodulator_priv; 3011 struct dib8000_state *state = fe->demodulator_priv;
@@ -2878,40 +3031,19 @@ static int dib8000_tune(struct dvb_frontend *fe)
2878 3031
2879 switch (*tune_state) { 3032 switch (*tune_state) {
2880 case CT_DEMOD_START: /* 30 */ 3033 case CT_DEMOD_START: /* 30 */
3034 dib8000_reset_stats(fe);
3035
2881 if (state->revision == 0x8090) 3036 if (state->revision == 0x8090)
2882 dib8090p_init_sdram(state); 3037 dib8090p_init_sdram(state);
2883 state->status = FE_STATUS_TUNE_PENDING; 3038 state->status = FE_STATUS_TUNE_PENDING;
2884 if ((c->delivery_system != SYS_ISDBT) || 3039 state->channel_parameters_set = is_manual_mode(c);
2885 (c->inversion == INVERSION_AUTO) || 3040
2886 (c->transmission_mode == TRANSMISSION_MODE_AUTO) || 3041 dprintk("Tuning channel on %s search mode",
2887 (c->guard_interval == GUARD_INTERVAL_AUTO) || 3042 state->channel_parameters_set ? "manual" : "auto");
2888 (((c->isdbt_layer_enabled & (1 << 0)) != 0) &&
2889 (c->layer[0].segment_count != 0xff) &&
2890 (c->layer[0].segment_count != 0) &&
2891 ((c->layer[0].modulation == QAM_AUTO) ||
2892 (c->layer[0].fec == FEC_AUTO))) ||
2893 (((c->isdbt_layer_enabled & (1 << 1)) != 0) &&
2894 (c->layer[1].segment_count != 0xff) &&
2895 (c->layer[1].segment_count != 0) &&
2896 ((c->layer[1].modulation == QAM_AUTO) ||
2897 (c->layer[1].fec == FEC_AUTO))) ||
2898 (((c->isdbt_layer_enabled & (1 << 2)) != 0) &&
2899 (c->layer[2].segment_count != 0xff) &&
2900 (c->layer[2].segment_count != 0) &&
2901 ((c->layer[2].modulation == QAM_AUTO) ||
2902 (c->layer[2].fec == FEC_AUTO))) ||
2903 (((c->layer[0].segment_count == 0) ||
2904 ((c->isdbt_layer_enabled & (1 << 0)) == 0)) &&
2905 ((c->layer[1].segment_count == 0) ||
2906 ((c->isdbt_layer_enabled & (2 << 0)) == 0)) &&
2907 ((c->layer[2].segment_count == 0) || ((c->isdbt_layer_enabled & (3 << 0)) == 0))))
2908 state->channel_parameters_set = 0; /* auto search */
2909 else
2910 state->channel_parameters_set = 1; /* channel parameters are known */
2911 3043
2912 dib8000_viterbi_state(state, 0); /* force chan dec in restart */ 3044 dib8000_viterbi_state(state, 0); /* force chan dec in restart */
2913 3045
2914 /* Layer monit */ 3046 /* Layer monitor */
2915 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); 3047 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
2916 3048
2917 dib8000_set_frequency_offset(state); 3049 dib8000_set_frequency_offset(state);
@@ -3256,15 +3388,27 @@ static int dib8000_sleep(struct dvb_frontend *fe)
3256 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); 3388 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
3257} 3389}
3258 3390
3391static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat);
3392
3259static int dib8000_get_frontend(struct dvb_frontend *fe) 3393static int dib8000_get_frontend(struct dvb_frontend *fe)
3260{ 3394{
3261 struct dib8000_state *state = fe->demodulator_priv; 3395 struct dib8000_state *state = fe->demodulator_priv;
3262 u16 i, val = 0; 3396 u16 i, val = 0;
3263 fe_status_t stat; 3397 fe_status_t stat = 0;
3264 u8 index_frontend, sub_index_frontend; 3398 u8 index_frontend, sub_index_frontend;
3265 3399
3266 fe->dtv_property_cache.bandwidth_hz = 6000000; 3400 fe->dtv_property_cache.bandwidth_hz = 6000000;
3267 3401
3402 /*
3403 * If called to early, get_frontend makes dib8000_tune to either
3404 * not lock or not sync. This causes dvbv5-scan/dvbv5-zap to fail.
3405 * So, let's just return if frontend 0 has not locked.
3406 */
3407 dib8000_read_status(fe, &stat);
3408 if (!(stat & FE_HAS_SYNC))
3409 return 0;
3410
3411 dprintk("TMCC lock");
3268 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 3412 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3269 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); 3413 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
3270 if (stat&FE_HAS_SYNC) { 3414 if (stat&FE_HAS_SYNC) {
@@ -3335,9 +3479,13 @@ static int dib8000_get_frontend(struct dvb_frontend *fe)
3335 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F; 3479 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
3336 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count); 3480 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
3337 3481
3338 val = dib8000_read_word(state, 499 + i); 3482 val = dib8000_read_word(state, 499 + i) & 0x3;
3339 fe->dtv_property_cache.layer[i].interleaving = val & 0x3; 3483 /* Interleaving can be 0, 1, 2 or 4 */
3340 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving); 3484 if (val == 3)
3485 val = 4;
3486 fe->dtv_property_cache.layer[i].interleaving = val;
3487 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ",
3488 i, fe->dtv_property_cache.layer[i].interleaving);
3341 3489
3342 val = dib8000_read_word(state, 481 + i); 3490 val = dib8000_read_word(state, 481 + i);
3343 switch (val & 0x7) { 3491 switch (val & 0x7) {
@@ -3556,6 +3704,8 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
3556 return 0; 3704 return 0;
3557} 3705}
3558 3706
3707static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat);
3708
3559static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) 3709static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3560{ 3710{
3561 struct dib8000_state *state = fe->demodulator_priv; 3711 struct dib8000_state *state = fe->demodulator_priv;
@@ -3593,6 +3743,7 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3593 if (lock & 0x01) 3743 if (lock & 0x01)
3594 *stat |= FE_HAS_VITERBI; 3744 *stat |= FE_HAS_VITERBI;
3595 } 3745 }
3746 dib8000_get_stats(fe, *stat);
3596 3747
3597 return 0; 3748 return 0;
3598} 3749}
@@ -3699,6 +3850,357 @@ static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3699 return 0; 3850 return 0;
3700} 3851}
3701 3852
3853struct per_layer_regs {
3854 u16 lock, ber, per;
3855};
3856
3857static const struct per_layer_regs per_layer_regs[] = {
3858 { 554, 560, 562 },
3859 { 555, 576, 578 },
3860 { 556, 581, 583 },
3861};
3862
3863struct linear_segments {
3864 unsigned x;
3865 signed y;
3866};
3867
3868/*
3869 * Table to estimate signal strength in dBm.
3870 * This table was empirically determinated by measuring the signal
3871 * strength generated by a DTA-2111 RF generator directly connected into
3872 * a dib8076 device (a PixelView PV-D231U stick), using a good quality
3873 * 3 meters RC6 cable and good RC6 connectors.
3874 * The real value can actually be different on other devices, depending
3875 * on several factors, like if LNA is enabled or not, if diversity is
3876 * enabled, type of connectors, etc.
3877 * Yet, it is better to use this measure in dB than a random non-linear
3878 * percentage value, especially for antenna adjustments.
3879 * On my tests, the precision of the measure using this table is about
3880 * 0.5 dB, with sounds reasonable enough.
3881 */
3882static struct linear_segments strength_to_db_table[] = {
3883 { 55953, 108500 }, /* -22.5 dBm */
3884 { 55394, 108000 },
3885 { 53834, 107000 },
3886 { 52863, 106000 },
3887 { 52239, 105000 },
3888 { 52012, 104000 },
3889 { 51803, 103000 },
3890 { 51566, 102000 },
3891 { 51356, 101000 },
3892 { 51112, 100000 },
3893 { 50869, 99000 },
3894 { 50600, 98000 },
3895 { 50363, 97000 },
3896 { 50117, 96000 }, /* -35 dBm */
3897 { 49889, 95000 },
3898 { 49680, 94000 },
3899 { 49493, 93000 },
3900 { 49302, 92000 },
3901 { 48929, 91000 },
3902 { 48416, 90000 },
3903 { 48035, 89000 },
3904 { 47593, 88000 },
3905 { 47282, 87000 },
3906 { 46953, 86000 },
3907 { 46698, 85000 },
3908 { 45617, 84000 },
3909 { 44773, 83000 },
3910 { 43845, 82000 },
3911 { 43020, 81000 },
3912 { 42010, 80000 }, /* -51 dBm */
3913 { 0, 0 },
3914};
3915
3916static u32 interpolate_value(u32 value, struct linear_segments *segments,
3917 unsigned len)
3918{
3919 u64 tmp64;
3920 u32 dx;
3921 s32 dy;
3922 int i, ret;
3923
3924 if (value >= segments[0].x)
3925 return segments[0].y;
3926 if (value < segments[len-1].x)
3927 return segments[len-1].y;
3928
3929 for (i = 1; i < len - 1; i++) {
3930 /* If value is identical, no need to interpolate */
3931 if (value == segments[i].x)
3932 return segments[i].y;
3933 if (value > segments[i].x)
3934 break;
3935 }
3936
3937 /* Linear interpolation between the two (x,y) points */
3938 dy = segments[i - 1].y - segments[i].y;
3939 dx = segments[i - 1].x - segments[i].x;
3940
3941 tmp64 = value - segments[i].x;
3942 tmp64 *= dy;
3943 do_div(tmp64, dx);
3944 ret = segments[i].y + tmp64;
3945
3946 return ret;
3947}
3948
3949static u32 dib8000_get_time_us(struct dvb_frontend *fe, int layer)
3950{
3951 struct dib8000_state *state = fe->demodulator_priv;
3952 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
3953 int ini_layer, end_layer, i;
3954 u64 time_us, tmp64;
3955 u32 tmp, denom;
3956 int guard, rate_num, rate_denum = 1, bits_per_symbol, nsegs;
3957 int interleaving = 0, fft_div;
3958
3959 if (layer >= 0) {
3960 ini_layer = layer;
3961 end_layer = layer + 1;
3962 } else {
3963 ini_layer = 0;
3964 end_layer = 3;
3965 }
3966
3967 switch (c->guard_interval) {
3968 case GUARD_INTERVAL_1_4:
3969 guard = 4;
3970 break;
3971 case GUARD_INTERVAL_1_8:
3972 guard = 8;
3973 break;
3974 case GUARD_INTERVAL_1_16:
3975 guard = 16;
3976 break;
3977 default:
3978 case GUARD_INTERVAL_1_32:
3979 guard = 32;
3980 break;
3981 }
3982
3983 switch (c->transmission_mode) {
3984 case TRANSMISSION_MODE_2K:
3985 fft_div = 4;
3986 break;
3987 case TRANSMISSION_MODE_4K:
3988 fft_div = 2;
3989 break;
3990 default:
3991 case TRANSMISSION_MODE_8K:
3992 fft_div = 1;
3993 break;
3994 }
3995
3996 denom = 0;
3997 for (i = ini_layer; i < end_layer; i++) {
3998 nsegs = c->layer[i].segment_count;
3999 if (nsegs == 0 || nsegs > 13)
4000 continue;
4001
4002 switch (c->layer[i].modulation) {
4003 case DQPSK:
4004 case QPSK:
4005 bits_per_symbol = 2;
4006 break;
4007 case QAM_16:
4008 bits_per_symbol = 4;
4009 break;
4010 default:
4011 case QAM_64:
4012 bits_per_symbol = 6;
4013 break;
4014 }
4015
4016 switch (c->layer[i].fec) {
4017 case FEC_1_2:
4018 rate_num = 1;
4019 rate_denum = 2;
4020 break;
4021 case FEC_2_3:
4022 rate_num = 2;
4023 rate_denum = 3;
4024 break;
4025 case FEC_3_4:
4026 rate_num = 3;
4027 rate_denum = 4;
4028 break;
4029 case FEC_5_6:
4030 rate_num = 5;
4031 rate_denum = 6;
4032 break;
4033 default:
4034 case FEC_7_8:
4035 rate_num = 7;
4036 rate_denum = 8;
4037 break;
4038 }
4039
4040 interleaving = c->layer[i].interleaving;
4041
4042 denom += bits_per_symbol * rate_num * fft_div * nsegs * 384;
4043 }
4044
4045 /* If all goes wrong, wait for 1s for the next stats */
4046 if (!denom)
4047 return 0;
4048
4049 /* Estimate the period for the total bit rate */
4050 time_us = rate_denum * (1008 * 1562500L);
4051 tmp64 = time_us;
4052 do_div(tmp64, guard);
4053 time_us = time_us + tmp64;
4054 time_us += denom / 2;
4055 do_div(time_us, denom);
4056
4057 tmp = 1008 * 96 * interleaving;
4058 time_us += tmp + tmp / guard;
4059
4060 return time_us;
4061}
4062
4063static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat)
4064{
4065 struct dib8000_state *state = fe->demodulator_priv;
4066 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
4067 int i;
4068 int show_per_stats = 0;
4069 u32 time_us = 0, snr, val;
4070 u64 blocks;
4071 s32 db;
4072 u16 strength;
4073
4074 /* Get Signal strength */
4075 dib8000_read_signal_strength(fe, &strength);
4076 val = strength;
4077 db = interpolate_value(val,
4078 strength_to_db_table,
4079 ARRAY_SIZE(strength_to_db_table)) - 131000;
4080 c->strength.stat[0].svalue = db;
4081
4082 /* UCB/BER/CNR measures require lock */
4083 if (!(stat & FE_HAS_LOCK)) {
4084 c->cnr.len = 1;
4085 c->block_count.len = 1;
4086 c->block_error.len = 1;
4087 c->post_bit_error.len = 1;
4088 c->post_bit_count.len = 1;
4089 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4090 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4091 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4092 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4093 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4094 return 0;
4095 }
4096
4097 /* Check if time for stats was elapsed */
4098 if (time_after(jiffies, state->per_jiffies_stats)) {
4099 state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
4100
4101 /* Get SNR */
4102 snr = dib8000_get_snr(fe);
4103 for (i = 1; i < MAX_NUMBER_OF_FRONTENDS; i++) {
4104 if (state->fe[i])
4105 snr += dib8000_get_snr(state->fe[i]);
4106 }
4107 snr = snr >> 16;
4108
4109 if (snr) {
4110 snr = 10 * intlog10(snr);
4111 snr = (1000L * snr) >> 24;
4112 } else {
4113 snr = 0;
4114 }
4115 c->cnr.stat[0].svalue = snr;
4116 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
4117
4118 /* Get UCB measures */
4119 dib8000_read_unc_blocks(fe, &val);
4120 if (val < state->init_ucb)
4121 state->init_ucb += 0x100000000LL;
4122
4123 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
4124 c->block_error.stat[0].uvalue = val + state->init_ucb;
4125
4126 /* Estimate the number of packets based on bitrate */
4127 if (!time_us)
4128 time_us = dib8000_get_time_us(fe, -1);
4129
4130 if (time_us) {
4131 blocks = 1250000ULL * 1000000ULL;
4132 do_div(blocks, time_us * 8 * 204);
4133 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
4134 c->block_count.stat[0].uvalue += blocks;
4135 }
4136
4137 show_per_stats = 1;
4138 }
4139
4140 /* Get post-BER measures */
4141 if (time_after(jiffies, state->ber_jiffies_stats)) {
4142 time_us = dib8000_get_time_us(fe, -1);
4143 state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
4144
4145 dprintk("Next all layers stats available in %u us.", time_us);
4146
4147 dib8000_read_ber(fe, &val);
4148 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
4149 c->post_bit_error.stat[0].uvalue += val;
4150
4151 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
4152 c->post_bit_count.stat[0].uvalue += 100000000;
4153 }
4154
4155 if (state->revision < 0x8002)
4156 return 0;
4157
4158 c->block_error.len = 4;
4159 c->post_bit_error.len = 4;
4160 c->post_bit_count.len = 4;
4161
4162 for (i = 0; i < 3; i++) {
4163 unsigned nsegs = c->layer[i].segment_count;
4164
4165 if (nsegs == 0 || nsegs > 13)
4166 continue;
4167
4168 time_us = 0;
4169
4170 if (time_after(jiffies, state->ber_jiffies_stats_layer[i])) {
4171 time_us = dib8000_get_time_us(fe, i);
4172
4173 state->ber_jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
4174 dprintk("Next layer %c stats will be available in %u us\n",
4175 'A' + i, time_us);
4176
4177 val = dib8000_read_word(state, per_layer_regs[i].ber);
4178 c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER;
4179 c->post_bit_error.stat[1 + i].uvalue += val;
4180
4181 c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER;
4182 c->post_bit_count.stat[1 + i].uvalue += 100000000;
4183 }
4184
4185 if (show_per_stats) {
4186 val = dib8000_read_word(state, per_layer_regs[i].per);
4187
4188 c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER;
4189 c->block_error.stat[1 + i].uvalue += val;
4190
4191 if (!time_us)
4192 time_us = dib8000_get_time_us(fe, i);
4193 if (time_us) {
4194 blocks = 1250000ULL * 1000000ULL;
4195 do_div(blocks, time_us * 8 * 204);
4196 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
4197 c->block_count.stat[0].uvalue += blocks;
4198 }
4199 }
4200 }
4201 return 0;
4202}
4203
3702int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) 4204int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
3703{ 4205{
3704 struct dib8000_state *state = fe->demodulator_priv; 4206 struct dib8000_state *state = fe->demodulator_priv;
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index f22eb9f13ad5..f6cb34660327 100644
--- a/drivers/media/dvb-frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -29,7 +29,6 @@
29 * A value of 0 (default) or lower indicates that 29 * A value of 0 (default) or lower indicates that
30 * the correct number of parameters will be 30 * the correct number of parameters will be
31 * automatically detected. 31 * automatically detected.
32 * @load_firmware_sync: Force the firmware load to be synchronous.
33 * 32 *
34 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is 33 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
35 * UIO-3. 34 * UIO-3.
@@ -41,7 +40,6 @@ struct drxk_config {
41 bool parallel_ts; 40 bool parallel_ts;
42 bool dynamic_clk; 41 bool dynamic_clk;
43 bool enable_merr_cfg; 42 bool enable_merr_cfg;
44 bool load_firmware_sync;
45 43
46 bool antenna_dvbt; 44 bool antenna_dvbt;
47 u16 antenna_gpio; 45 u16 antenna_gpio;
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index bf29a3f0e6f0..cce94a75b2e1 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -6830,25 +6830,13 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6830 6830
6831 /* Load firmware and initialize DRX-K */ 6831 /* Load firmware and initialize DRX-K */
6832 if (state->microcode_name) { 6832 if (state->microcode_name) {
6833 if (config->load_firmware_sync) { 6833 const struct firmware *fw = NULL;
6834 const struct firmware *fw = NULL;
6835 6834
6836 status = request_firmware(&fw, state->microcode_name, 6835 status = request_firmware(&fw, state->microcode_name,
6837 state->i2c->dev.parent); 6836 state->i2c->dev.parent);
6838 if (status < 0) 6837 if (status < 0)
6839 fw = NULL; 6838 fw = NULL;
6840 load_firmware_cb(fw, state); 6839 load_firmware_cb(fw, state);
6841 } else {
6842 status = request_firmware_nowait(THIS_MODULE, 1,
6843 state->microcode_name,
6844 state->i2c->dev.parent,
6845 GFP_KERNEL,
6846 state, load_firmware_cb);
6847 if (status < 0) {
6848 pr_err("failed to request a firmware\n");
6849 return NULL;
6850 }
6851 }
6852 } else if (init_drxk(state) < 0) 6840 } else if (init_drxk(state) < 0)
6853 goto error; 6841 goto error;
6854 6842
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
new file mode 100644
index 000000000000..b8a7897e7bd8
--- /dev/null
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -0,0 +1,1311 @@
1/*
2 * Montage M88DS3103 demodulator driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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#include "m88ds3103_priv.h"
18
19static struct dvb_frontend_ops m88ds3103_ops;
20
21/* write multiple registers */
22static int m88ds3103_wr_regs(struct m88ds3103_priv *priv,
23 u8 reg, const u8 *val, int len)
24{
25#define MAX_WR_LEN 32
26#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
27 int ret;
28 u8 buf[MAX_WR_XFER_LEN];
29 struct i2c_msg msg[1] = {
30 {
31 .addr = priv->cfg->i2c_addr,
32 .flags = 0,
33 .len = 1 + len,
34 .buf = buf,
35 }
36 };
37
38 if (WARN_ON(len > MAX_WR_LEN))
39 return -EINVAL;
40
41 buf[0] = reg;
42 memcpy(&buf[1], val, len);
43
44 mutex_lock(&priv->i2c_mutex);
45 ret = i2c_transfer(priv->i2c, msg, 1);
46 mutex_unlock(&priv->i2c_mutex);
47 if (ret == 1) {
48 ret = 0;
49 } else {
50 dev_warn(&priv->i2c->dev,
51 "%s: i2c wr failed=%d reg=%02x len=%d\n",
52 KBUILD_MODNAME, ret, reg, len);
53 ret = -EREMOTEIO;
54 }
55
56 return ret;
57}
58
59/* read multiple registers */
60static int m88ds3103_rd_regs(struct m88ds3103_priv *priv,
61 u8 reg, u8 *val, int len)
62{
63#define MAX_RD_LEN 3
64#define MAX_RD_XFER_LEN (MAX_RD_LEN)
65 int ret;
66 u8 buf[MAX_RD_XFER_LEN];
67 struct i2c_msg msg[2] = {
68 {
69 .addr = priv->cfg->i2c_addr,
70 .flags = 0,
71 .len = 1,
72 .buf = &reg,
73 }, {
74 .addr = priv->cfg->i2c_addr,
75 .flags = I2C_M_RD,
76 .len = len,
77 .buf = buf,
78 }
79 };
80
81 if (WARN_ON(len > MAX_RD_LEN))
82 return -EINVAL;
83
84 mutex_lock(&priv->i2c_mutex);
85 ret = i2c_transfer(priv->i2c, msg, 2);
86 mutex_unlock(&priv->i2c_mutex);
87 if (ret == 2) {
88 memcpy(val, buf, len);
89 ret = 0;
90 } else {
91 dev_warn(&priv->i2c->dev,
92 "%s: i2c rd failed=%d reg=%02x len=%d\n",
93 KBUILD_MODNAME, ret, reg, len);
94 ret = -EREMOTEIO;
95 }
96
97 return ret;
98}
99
100/* write single register */
101static int m88ds3103_wr_reg(struct m88ds3103_priv *priv, u8 reg, u8 val)
102{
103 return m88ds3103_wr_regs(priv, reg, &val, 1);
104}
105
106/* read single register */
107static int m88ds3103_rd_reg(struct m88ds3103_priv *priv, u8 reg, u8 *val)
108{
109 return m88ds3103_rd_regs(priv, reg, val, 1);
110}
111
112/* write single register with mask */
113static int m88ds3103_wr_reg_mask(struct m88ds3103_priv *priv,
114 u8 reg, u8 val, u8 mask)
115{
116 int ret;
117 u8 u8tmp;
118
119 /* no need for read if whole reg is written */
120 if (mask != 0xff) {
121 ret = m88ds3103_rd_regs(priv, reg, &u8tmp, 1);
122 if (ret)
123 return ret;
124
125 val &= mask;
126 u8tmp &= ~mask;
127 val |= u8tmp;
128 }
129
130 return m88ds3103_wr_regs(priv, reg, &val, 1);
131}
132
133/* read single register with mask */
134static int m88ds3103_rd_reg_mask(struct m88ds3103_priv *priv,
135 u8 reg, u8 *val, u8 mask)
136{
137 int ret, i;
138 u8 u8tmp;
139
140 ret = m88ds3103_rd_regs(priv, reg, &u8tmp, 1);
141 if (ret)
142 return ret;
143
144 u8tmp &= mask;
145
146 /* find position of the first bit */
147 for (i = 0; i < 8; i++) {
148 if ((mask >> i) & 0x01)
149 break;
150 }
151 *val = u8tmp >> i;
152
153 return 0;
154}
155
156/* write reg val table using reg addr auto increment */
157static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv,
158 const struct m88ds3103_reg_val *tab, int tab_len)
159{
160 int ret, i, j;
161 u8 buf[83];
162 dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
163
164 if (tab_len > 83) {
165 ret = -EINVAL;
166 goto err;
167 }
168
169 for (i = 0, j = 0; i < tab_len; i++, j++) {
170 buf[j] = tab[i].val;
171
172 if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1 ||
173 !((j + 1) % (priv->cfg->i2c_wr_max - 1))) {
174 ret = m88ds3103_wr_regs(priv, tab[i].reg - j, buf, j + 1);
175 if (ret)
176 goto err;
177
178 j = -1;
179 }
180 }
181
182 return 0;
183err:
184 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
185 return ret;
186}
187
188static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
189{
190 struct m88ds3103_priv *priv = fe->demodulator_priv;
191 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
192 int ret;
193 u8 u8tmp;
194
195 *status = 0;
196
197 if (!priv->warm) {
198 ret = -EAGAIN;
199 goto err;
200 }
201
202 switch (c->delivery_system) {
203 case SYS_DVBS:
204 ret = m88ds3103_rd_reg_mask(priv, 0xd1, &u8tmp, 0x07);
205 if (ret)
206 goto err;
207
208 if (u8tmp == 0x07)
209 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
210 FE_HAS_VITERBI | FE_HAS_SYNC |
211 FE_HAS_LOCK;
212 break;
213 case SYS_DVBS2:
214 ret = m88ds3103_rd_reg_mask(priv, 0x0d, &u8tmp, 0x8f);
215 if (ret)
216 goto err;
217
218 if (u8tmp == 0x8f)
219 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
220 FE_HAS_VITERBI | FE_HAS_SYNC |
221 FE_HAS_LOCK;
222 break;
223 default:
224 dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
225 __func__);
226 ret = -EINVAL;
227 goto err;
228 }
229
230 priv->fe_status = *status;
231
232 dev_dbg(&priv->i2c->dev, "%s: lock=%02x status=%02x\n",
233 __func__, u8tmp, *status);
234
235 return 0;
236err:
237 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
238 return ret;
239}
240
241static int m88ds3103_set_frontend(struct dvb_frontend *fe)
242{
243 struct m88ds3103_priv *priv = fe->demodulator_priv;
244 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
245 int ret, len;
246 const struct m88ds3103_reg_val *init;
247 u8 u8tmp, u8tmp1, u8tmp2;
248 u8 buf[2];
249 u16 u16tmp, divide_ratio;
250 u32 tuner_frequency, target_mclk, ts_clk;
251 s32 s32tmp;
252 dev_dbg(&priv->i2c->dev,
253 "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
254 __func__, c->delivery_system,
255 c->modulation, c->frequency, c->symbol_rate,
256 c->inversion, c->pilot, c->rolloff);
257
258 if (!priv->warm) {
259 ret = -EAGAIN;
260 goto err;
261 }
262
263 /* program tuner */
264 if (fe->ops.tuner_ops.set_params) {
265 ret = fe->ops.tuner_ops.set_params(fe);
266 if (ret)
267 goto err;
268 }
269
270 if (fe->ops.tuner_ops.get_frequency) {
271 ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_frequency);
272 if (ret)
273 goto err;
274 }
275
276 /* reset */
277 ret = m88ds3103_wr_reg(priv, 0x07, 0x80);
278 if (ret)
279 goto err;
280
281 ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
282 if (ret)
283 goto err;
284
285 ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
286 if (ret)
287 goto err;
288
289 ret = m88ds3103_wr_reg(priv, 0x00, 0x01);
290 if (ret)
291 goto err;
292
293 switch (c->delivery_system) {
294 case SYS_DVBS:
295 len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals);
296 init = m88ds3103_dvbs_init_reg_vals;
297 target_mclk = 96000;
298 break;
299 case SYS_DVBS2:
300 len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals);
301 init = m88ds3103_dvbs2_init_reg_vals;
302
303 switch (priv->cfg->ts_mode) {
304 case M88DS3103_TS_SERIAL:
305 case M88DS3103_TS_SERIAL_D7:
306 if (c->symbol_rate < 18000000)
307 target_mclk = 96000;
308 else
309 target_mclk = 144000;
310 break;
311 case M88DS3103_TS_PARALLEL:
312 case M88DS3103_TS_PARALLEL_12:
313 case M88DS3103_TS_PARALLEL_16:
314 case M88DS3103_TS_PARALLEL_19_2:
315 case M88DS3103_TS_CI:
316 if (c->symbol_rate < 18000000)
317 target_mclk = 96000;
318 else if (c->symbol_rate < 28000000)
319 target_mclk = 144000;
320 else
321 target_mclk = 192000;
322 break;
323 default:
324 dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n",
325 __func__);
326 ret = -EINVAL;
327 goto err;
328 }
329 break;
330 default:
331 dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
332 __func__);
333 ret = -EINVAL;
334 goto err;
335 }
336
337 /* program init table */
338 if (c->delivery_system != priv->delivery_system) {
339 ret = m88ds3103_wr_reg_val_tab(priv, init, len);
340 if (ret)
341 goto err;
342 }
343
344 u8tmp1 = 0; /* silence compiler warning */
345 switch (priv->cfg->ts_mode) {
346 case M88DS3103_TS_SERIAL:
347 u8tmp1 = 0x00;
348 ts_clk = 0;
349 u8tmp = 0x46;
350 break;
351 case M88DS3103_TS_SERIAL_D7:
352 u8tmp1 = 0x20;
353 ts_clk = 0;
354 u8tmp = 0x46;
355 break;
356 case M88DS3103_TS_PARALLEL:
357 ts_clk = 24000;
358 u8tmp = 0x42;
359 break;
360 case M88DS3103_TS_PARALLEL_12:
361 ts_clk = 12000;
362 u8tmp = 0x42;
363 break;
364 case M88DS3103_TS_PARALLEL_16:
365 ts_clk = 16000;
366 u8tmp = 0x42;
367 break;
368 case M88DS3103_TS_PARALLEL_19_2:
369 ts_clk = 19200;
370 u8tmp = 0x42;
371 break;
372 case M88DS3103_TS_CI:
373 ts_clk = 6000;
374 u8tmp = 0x43;
375 break;
376 default:
377 dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__);
378 ret = -EINVAL;
379 goto err;
380 }
381
382 /* TS mode */
383 ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp);
384 if (ret)
385 goto err;
386
387 switch (priv->cfg->ts_mode) {
388 case M88DS3103_TS_SERIAL:
389 case M88DS3103_TS_SERIAL_D7:
390 ret = m88ds3103_wr_reg_mask(priv, 0x29, u8tmp1, 0x20);
391 if (ret)
392 goto err;
393 }
394
395 if (ts_clk) {
396 divide_ratio = DIV_ROUND_UP(target_mclk, ts_clk);
397 u8tmp1 = divide_ratio / 2;
398 u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
399 } else {
400 divide_ratio = 0;
401 u8tmp1 = 0;
402 u8tmp2 = 0;
403 }
404
405 dev_dbg(&priv->i2c->dev,
406 "%s: target_mclk=%d ts_clk=%d divide_ratio=%d\n",
407 __func__, target_mclk, ts_clk, divide_ratio);
408
409 u8tmp1--;
410 u8tmp2--;
411 /* u8tmp1[5:2] => fe[3:0], u8tmp1[1:0] => ea[7:6] */
412 u8tmp1 &= 0x3f;
413 /* u8tmp2[5:0] => ea[5:0] */
414 u8tmp2 &= 0x3f;
415
416 ret = m88ds3103_rd_reg(priv, 0xfe, &u8tmp);
417 if (ret)
418 goto err;
419
420 u8tmp = ((u8tmp & 0xf0) << 0) | u8tmp1 >> 2;
421 ret = m88ds3103_wr_reg(priv, 0xfe, u8tmp);
422 if (ret)
423 goto err;
424
425 u8tmp = ((u8tmp1 & 0x03) << 6) | u8tmp2 >> 0;
426 ret = m88ds3103_wr_reg(priv, 0xea, u8tmp);
427 if (ret)
428 goto err;
429
430 switch (target_mclk) {
431 case 72000:
432 u8tmp1 = 0x00; /* 0b00 */
433 u8tmp2 = 0x03; /* 0b11 */
434 break;
435 case 96000:
436 u8tmp1 = 0x02; /* 0b10 */
437 u8tmp2 = 0x01; /* 0b01 */
438 break;
439 case 115200:
440 u8tmp1 = 0x01; /* 0b01 */
441 u8tmp2 = 0x01; /* 0b01 */
442 break;
443 case 144000:
444 u8tmp1 = 0x00; /* 0b00 */
445 u8tmp2 = 0x01; /* 0b01 */
446 break;
447 case 192000:
448 u8tmp1 = 0x03; /* 0b11 */
449 u8tmp2 = 0x00; /* 0b00 */
450 break;
451 default:
452 dev_dbg(&priv->i2c->dev, "%s: invalid target_mclk\n", __func__);
453 ret = -EINVAL;
454 goto err;
455 }
456
457 ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0);
458 if (ret)
459 goto err;
460
461 ret = m88ds3103_wr_reg_mask(priv, 0x24, u8tmp2 << 6, 0xc0);
462 if (ret)
463 goto err;
464
465 if (c->symbol_rate <= 3000000)
466 u8tmp = 0x20;
467 else if (c->symbol_rate <= 10000000)
468 u8tmp = 0x10;
469 else
470 u8tmp = 0x06;
471
472 ret = m88ds3103_wr_reg(priv, 0xc3, 0x08);
473 if (ret)
474 goto err;
475
476 ret = m88ds3103_wr_reg(priv, 0xc8, u8tmp);
477 if (ret)
478 goto err;
479
480 ret = m88ds3103_wr_reg(priv, 0xc4, 0x08);
481 if (ret)
482 goto err;
483
484 ret = m88ds3103_wr_reg(priv, 0xc7, 0x00);
485 if (ret)
486 goto err;
487
488 u16tmp = DIV_ROUND_CLOSEST((c->symbol_rate / 1000) << 15, M88DS3103_MCLK_KHZ / 2);
489 buf[0] = (u16tmp >> 0) & 0xff;
490 buf[1] = (u16tmp >> 8) & 0xff;
491 ret = m88ds3103_wr_regs(priv, 0x61, buf, 2);
492 if (ret)
493 goto err;
494
495 ret = m88ds3103_wr_reg_mask(priv, 0x4d, priv->cfg->spec_inv << 1, 0x02);
496 if (ret)
497 goto err;
498
499 ret = m88ds3103_wr_reg_mask(priv, 0x30, priv->cfg->agc_inv << 4, 0x10);
500 if (ret)
501 goto err;
502
503 ret = m88ds3103_wr_reg(priv, 0x33, priv->cfg->agc);
504 if (ret)
505 goto err;
506
507 dev_dbg(&priv->i2c->dev, "%s: carrier offset=%d\n", __func__,
508 (tuner_frequency - c->frequency));
509
510 s32tmp = 0x10000 * (tuner_frequency - c->frequency);
511 s32tmp = DIV_ROUND_CLOSEST(s32tmp, M88DS3103_MCLK_KHZ);
512 if (s32tmp < 0)
513 s32tmp += 0x10000;
514
515 buf[0] = (s32tmp >> 0) & 0xff;
516 buf[1] = (s32tmp >> 8) & 0xff;
517 ret = m88ds3103_wr_regs(priv, 0x5e, buf, 2);
518 if (ret)
519 goto err;
520
521 ret = m88ds3103_wr_reg(priv, 0x00, 0x00);
522 if (ret)
523 goto err;
524
525 ret = m88ds3103_wr_reg(priv, 0xb2, 0x00);
526 if (ret)
527 goto err;
528
529 priv->delivery_system = c->delivery_system;
530
531 return 0;
532err:
533 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
534 return ret;
535}
536
537static int m88ds3103_init(struct dvb_frontend *fe)
538{
539 struct m88ds3103_priv *priv = fe->demodulator_priv;
540 int ret, len, remaining;
541 const struct firmware *fw = NULL;
542 u8 *fw_file = M88DS3103_FIRMWARE;
543 u8 u8tmp;
544 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
545
546 /* set cold state by default */
547 priv->warm = false;
548
549 /* wake up device from sleep */
550 ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x01, 0x01);
551 if (ret)
552 goto err;
553
554 ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x00, 0x01);
555 if (ret)
556 goto err;
557
558 ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x00, 0x10);
559 if (ret)
560 goto err;
561
562 /* reset */
563 ret = m88ds3103_wr_reg(priv, 0x07, 0x60);
564 if (ret)
565 goto err;
566
567 ret = m88ds3103_wr_reg(priv, 0x07, 0x00);
568 if (ret)
569 goto err;
570
571 /* firmware status */
572 ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp);
573 if (ret)
574 goto err;
575
576 dev_dbg(&priv->i2c->dev, "%s: firmware=%02x\n", __func__, u8tmp);
577
578 if (u8tmp)
579 goto skip_fw_download;
580
581 /* cold state - try to download firmware */
582 dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state\n",
583 KBUILD_MODNAME, m88ds3103_ops.info.name);
584
585 /* request the firmware, this will block and timeout */
586 ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
587 if (ret) {
588 dev_err(&priv->i2c->dev, "%s: firmare file '%s' not found\n",
589 KBUILD_MODNAME, fw_file);
590 goto err;
591 }
592
593 dev_info(&priv->i2c->dev, "%s: downloading firmware from file '%s'\n",
594 KBUILD_MODNAME, fw_file);
595
596 ret = m88ds3103_wr_reg(priv, 0xb2, 0x01);
597 if (ret)
598 goto err;
599
600 for (remaining = fw->size; remaining > 0;
601 remaining -= (priv->cfg->i2c_wr_max - 1)) {
602 len = remaining;
603 if (len > (priv->cfg->i2c_wr_max - 1))
604 len = (priv->cfg->i2c_wr_max - 1);
605
606 ret = m88ds3103_wr_regs(priv, 0xb0,
607 &fw->data[fw->size - remaining], len);
608 if (ret) {
609 dev_err(&priv->i2c->dev,
610 "%s: firmware download failed=%d\n",
611 KBUILD_MODNAME, ret);
612 goto err;
613 }
614 }
615
616 ret = m88ds3103_wr_reg(priv, 0xb2, 0x00);
617 if (ret)
618 goto err;
619
620 release_firmware(fw);
621 fw = NULL;
622
623 ret = m88ds3103_rd_reg(priv, 0xb9, &u8tmp);
624 if (ret)
625 goto err;
626
627 if (!u8tmp) {
628 dev_info(&priv->i2c->dev, "%s: firmware did not run\n",
629 KBUILD_MODNAME);
630 ret = -EFAULT;
631 goto err;
632 }
633
634 dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n",
635 KBUILD_MODNAME, m88ds3103_ops.info.name);
636 dev_info(&priv->i2c->dev, "%s: firmware version %X.%X\n",
637 KBUILD_MODNAME, (u8tmp >> 4) & 0xf, (u8tmp >> 0 & 0xf));
638
639skip_fw_download:
640 /* warm state */
641 priv->warm = true;
642
643 return 0;
644err:
645 if (fw)
646 release_firmware(fw);
647
648 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
649 return ret;
650}
651
652static int m88ds3103_sleep(struct dvb_frontend *fe)
653{
654 struct m88ds3103_priv *priv = fe->demodulator_priv;
655 int ret;
656 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
657
658 priv->delivery_system = SYS_UNDEFINED;
659
660 /* TS Hi-Z */
661 ret = m88ds3103_wr_reg_mask(priv, 0x27, 0x00, 0x01);
662 if (ret)
663 goto err;
664
665 /* sleep */
666 ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01);
667 if (ret)
668 goto err;
669
670 ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01);
671 if (ret)
672 goto err;
673
674 ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10);
675 if (ret)
676 goto err;
677
678 return 0;
679err:
680 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
681 return ret;
682}
683
684static int m88ds3103_get_frontend(struct dvb_frontend *fe)
685{
686 struct m88ds3103_priv *priv = fe->demodulator_priv;
687 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
688 int ret;
689 u8 buf[3];
690 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
691
692 if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
693 ret = -EAGAIN;
694 goto err;
695 }
696
697 switch (c->delivery_system) {
698 case SYS_DVBS:
699 ret = m88ds3103_rd_reg(priv, 0xe0, &buf[0]);
700 if (ret)
701 goto err;
702
703 ret = m88ds3103_rd_reg(priv, 0xe6, &buf[1]);
704 if (ret)
705 goto err;
706
707 switch ((buf[0] >> 2) & 0x01) {
708 case 0:
709 c->inversion = INVERSION_OFF;
710 break;
711 case 1:
712 c->inversion = INVERSION_ON;
713 break;
714 default:
715 dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n",
716 __func__);
717 }
718
719 switch ((buf[1] >> 5) & 0x07) {
720 case 0:
721 c->fec_inner = FEC_7_8;
722 break;
723 case 1:
724 c->fec_inner = FEC_5_6;
725 break;
726 case 2:
727 c->fec_inner = FEC_3_4;
728 break;
729 case 3:
730 c->fec_inner = FEC_2_3;
731 break;
732 case 4:
733 c->fec_inner = FEC_1_2;
734 break;
735 default:
736 dev_dbg(&priv->i2c->dev, "%s: invalid fec_inner\n",
737 __func__);
738 }
739
740 c->modulation = QPSK;
741
742 break;
743 case SYS_DVBS2:
744 ret = m88ds3103_rd_reg(priv, 0x7e, &buf[0]);
745 if (ret)
746 goto err;
747
748 ret = m88ds3103_rd_reg(priv, 0x89, &buf[1]);
749 if (ret)
750 goto err;
751
752 ret = m88ds3103_rd_reg(priv, 0xf2, &buf[2]);
753 if (ret)
754 goto err;
755
756 switch ((buf[0] >> 0) & 0x0f) {
757 case 2:
758 c->fec_inner = FEC_2_5;
759 break;
760 case 3:
761 c->fec_inner = FEC_1_2;
762 break;
763 case 4:
764 c->fec_inner = FEC_3_5;
765 break;
766 case 5:
767 c->fec_inner = FEC_2_3;
768 break;
769 case 6:
770 c->fec_inner = FEC_3_4;
771 break;
772 case 7:
773 c->fec_inner = FEC_4_5;
774 break;
775 case 8:
776 c->fec_inner = FEC_5_6;
777 break;
778 case 9:
779 c->fec_inner = FEC_8_9;
780 break;
781 case 10:
782 c->fec_inner = FEC_9_10;
783 break;
784 default:
785 dev_dbg(&priv->i2c->dev, "%s: invalid fec_inner\n",
786 __func__);
787 }
788
789 switch ((buf[0] >> 5) & 0x01) {
790 case 0:
791 c->pilot = PILOT_OFF;
792 break;
793 case 1:
794 c->pilot = PILOT_ON;
795 break;
796 default:
797 dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n",
798 __func__);
799 }
800
801 switch ((buf[0] >> 6) & 0x07) {
802 case 0:
803 c->modulation = QPSK;
804 break;
805 case 1:
806 c->modulation = PSK_8;
807 break;
808 case 2:
809 c->modulation = APSK_16;
810 break;
811 case 3:
812 c->modulation = APSK_32;
813 break;
814 default:
815 dev_dbg(&priv->i2c->dev, "%s: invalid modulation\n",
816 __func__);
817 }
818
819 switch ((buf[1] >> 7) & 0x01) {
820 case 0:
821 c->inversion = INVERSION_OFF;
822 break;
823 case 1:
824 c->inversion = INVERSION_ON;
825 break;
826 default:
827 dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n",
828 __func__);
829 }
830
831 switch ((buf[2] >> 0) & 0x03) {
832 case 0:
833 c->rolloff = ROLLOFF_35;
834 break;
835 case 1:
836 c->rolloff = ROLLOFF_25;
837 break;
838 case 2:
839 c->rolloff = ROLLOFF_20;
840 break;
841 default:
842 dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n",
843 __func__);
844 }
845 break;
846 default:
847 dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
848 __func__);
849 ret = -EINVAL;
850 goto err;
851 }
852
853 ret = m88ds3103_rd_regs(priv, 0x6d, buf, 2);
854 if (ret)
855 goto err;
856
857 c->symbol_rate = 1ull * ((buf[1] << 8) | (buf[0] << 0)) *
858 M88DS3103_MCLK_KHZ * 1000 / 0x10000;
859
860 return 0;
861err:
862 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
863 return ret;
864}
865
866static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
867{
868 struct m88ds3103_priv *priv = fe->demodulator_priv;
869 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
870 int ret, i, tmp;
871 u8 buf[3];
872 u16 noise, signal;
873 u32 noise_tot, signal_tot;
874 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
875 /* reports SNR in resolution of 0.1 dB */
876
877 /* more iterations for more accurate estimation */
878 #define M88DS3103_SNR_ITERATIONS 3
879
880 switch (c->delivery_system) {
881 case SYS_DVBS:
882 tmp = 0;
883
884 for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
885 ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]);
886 if (ret)
887 goto err;
888
889 tmp += buf[0];
890 }
891
892 /* use of one register limits max value to 15 dB */
893 /* SNR(X) dB = 10 * ln(X) / ln(10) dB */
894 tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS);
895 if (tmp)
896 *snr = 100ul * intlog2(tmp) / intlog2(10);
897 else
898 *snr = 0;
899 break;
900 case SYS_DVBS2:
901 noise_tot = 0;
902 signal_tot = 0;
903
904 for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
905 ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3);
906 if (ret)
907 goto err;
908
909 noise = buf[1] << 6; /* [13:6] */
910 noise |= buf[0] & 0x3f; /* [5:0] */
911 noise >>= 2;
912 signal = buf[2] * buf[2];
913 signal >>= 1;
914
915 noise_tot += noise;
916 signal_tot += signal;
917 }
918
919 noise = noise_tot / M88DS3103_SNR_ITERATIONS;
920 signal = signal_tot / M88DS3103_SNR_ITERATIONS;
921
922 /* SNR(X) dB = 10 * log10(X) dB */
923 if (signal > noise) {
924 tmp = signal / noise;
925 *snr = 100ul * intlog10(tmp) / (1 << 24);
926 } else {
927 *snr = 0;
928 }
929 break;
930 default:
931 dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
932 __func__);
933 ret = -EINVAL;
934 goto err;
935 }
936
937 return 0;
938err:
939 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
940 return ret;
941}
942
943
944static int m88ds3103_set_tone(struct dvb_frontend *fe,
945 fe_sec_tone_mode_t fe_sec_tone_mode)
946{
947 struct m88ds3103_priv *priv = fe->demodulator_priv;
948 int ret;
949 u8 u8tmp, tone, reg_a1_mask;
950 dev_dbg(&priv->i2c->dev, "%s: fe_sec_tone_mode=%d\n", __func__,
951 fe_sec_tone_mode);
952
953 if (!priv->warm) {
954 ret = -EAGAIN;
955 goto err;
956 }
957
958 switch (fe_sec_tone_mode) {
959 case SEC_TONE_ON:
960 tone = 0;
961 reg_a1_mask = 0x87;
962 break;
963 case SEC_TONE_OFF:
964 tone = 1;
965 reg_a1_mask = 0x00;
966 break;
967 default:
968 dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n",
969 __func__);
970 ret = -EINVAL;
971 goto err;
972 }
973
974 u8tmp = tone << 7 | priv->cfg->envelope_mode << 5;
975 ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0);
976 if (ret)
977 goto err;
978
979 u8tmp = 1 << 2;
980 ret = m88ds3103_wr_reg_mask(priv, 0xa1, u8tmp, reg_a1_mask);
981 if (ret)
982 goto err;
983
984 return 0;
985err:
986 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
987 return ret;
988}
989
990static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
991 struct dvb_diseqc_master_cmd *diseqc_cmd)
992{
993 struct m88ds3103_priv *priv = fe->demodulator_priv;
994 int ret, i;
995 u8 u8tmp;
996 dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__,
997 diseqc_cmd->msg_len, diseqc_cmd->msg);
998
999 if (!priv->warm) {
1000 ret = -EAGAIN;
1001 goto err;
1002 }
1003
1004 if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
1005 ret = -EINVAL;
1006 goto err;
1007 }
1008
1009 u8tmp = priv->cfg->envelope_mode << 5;
1010 ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0);
1011 if (ret)
1012 goto err;
1013
1014 ret = m88ds3103_wr_regs(priv, 0xa3, diseqc_cmd->msg,
1015 diseqc_cmd->msg_len);
1016 if (ret)
1017 goto err;
1018
1019 ret = m88ds3103_wr_reg(priv, 0xa1,
1020 (diseqc_cmd->msg_len - 1) << 3 | 0x07);
1021 if (ret)
1022 goto err;
1023
1024 /* DiSEqC message typical period is 54 ms */
1025 usleep_range(40000, 60000);
1026
1027 /* wait DiSEqC TX ready */
1028 for (i = 20, u8tmp = 1; i && u8tmp; i--) {
1029 usleep_range(5000, 10000);
1030
1031 ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40);
1032 if (ret)
1033 goto err;
1034 }
1035
1036 dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
1037
1038 if (i == 0) {
1039 dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);
1040
1041 ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0);
1042 if (ret)
1043 goto err;
1044 }
1045
1046 ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0);
1047 if (ret)
1048 goto err;
1049
1050 if (i == 0) {
1051 ret = -ETIMEDOUT;
1052 goto err;
1053 }
1054
1055 return 0;
1056err:
1057 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
1058 return ret;
1059}
1060
1061static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
1062 fe_sec_mini_cmd_t fe_sec_mini_cmd)
1063{
1064 struct m88ds3103_priv *priv = fe->demodulator_priv;
1065 int ret, i;
1066 u8 u8tmp, burst;
1067 dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
1068 fe_sec_mini_cmd);
1069
1070 if (!priv->warm) {
1071 ret = -EAGAIN;
1072 goto err;
1073 }
1074
1075 u8tmp = priv->cfg->envelope_mode << 5;
1076 ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0xe0);
1077 if (ret)
1078 goto err;
1079
1080 switch (fe_sec_mini_cmd) {
1081 case SEC_MINI_A:
1082 burst = 0x02;
1083 break;
1084 case SEC_MINI_B:
1085 burst = 0x01;
1086 break;
1087 default:
1088 dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n",
1089 __func__);
1090 ret = -EINVAL;
1091 goto err;
1092 }
1093
1094 ret = m88ds3103_wr_reg(priv, 0xa1, burst);
1095 if (ret)
1096 goto err;
1097
1098 /* DiSEqC ToneBurst period is 12.5 ms */
1099 usleep_range(11000, 20000);
1100
1101 /* wait DiSEqC TX ready */
1102 for (i = 5, u8tmp = 1; i && u8tmp; i--) {
1103 usleep_range(800, 2000);
1104
1105 ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40);
1106 if (ret)
1107 goto err;
1108 }
1109
1110 dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
1111
1112 ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0);
1113 if (ret)
1114 goto err;
1115
1116 if (i == 0) {
1117 dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);
1118 ret = -ETIMEDOUT;
1119 goto err;
1120 }
1121
1122 return 0;
1123err:
1124 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
1125 return ret;
1126}
1127
1128static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
1129 struct dvb_frontend_tune_settings *s)
1130{
1131 s->min_delay_ms = 3000;
1132
1133 return 0;
1134}
1135
1136static void m88ds3103_release(struct dvb_frontend *fe)
1137{
1138 struct m88ds3103_priv *priv = fe->demodulator_priv;
1139 i2c_del_mux_adapter(priv->i2c_adapter);
1140 kfree(priv);
1141}
1142
1143static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
1144{
1145 struct m88ds3103_priv *priv = mux_priv;
1146 int ret;
1147 struct i2c_msg gate_open_msg[1] = {
1148 {
1149 .addr = priv->cfg->i2c_addr,
1150 .flags = 0,
1151 .len = 2,
1152 .buf = "\x03\x11",
1153 }
1154 };
1155
1156 mutex_lock(&priv->i2c_mutex);
1157
1158 /* open tuner I2C repeater for 1 xfer, closes automatically */
1159 ret = __i2c_transfer(priv->i2c, gate_open_msg, 1);
1160 if (ret != 1) {
1161 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d\n",
1162 KBUILD_MODNAME, ret);
1163 if (ret >= 0)
1164 ret = -EREMOTEIO;
1165
1166 return ret;
1167 }
1168
1169 return 0;
1170}
1171
1172static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv,
1173 u32 chan)
1174{
1175 struct m88ds3103_priv *priv = mux_priv;
1176
1177 mutex_unlock(&priv->i2c_mutex);
1178
1179 return 0;
1180}
1181
1182struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
1183 struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter)
1184{
1185 int ret;
1186 struct m88ds3103_priv *priv;
1187 u8 chip_id, u8tmp;
1188
1189 /* allocate memory for the internal priv */
1190 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1191 if (!priv) {
1192 ret = -ENOMEM;
1193 dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
1194 goto err;
1195 }
1196
1197 priv->cfg = cfg;
1198 priv->i2c = i2c;
1199 mutex_init(&priv->i2c_mutex);
1200
1201 ret = m88ds3103_rd_reg(priv, 0x01, &chip_id);
1202 if (ret)
1203 goto err;
1204
1205 dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
1206
1207 switch (chip_id) {
1208 case 0xd0:
1209 break;
1210 default:
1211 goto err;
1212 }
1213
1214 switch (priv->cfg->clock_out) {
1215 case M88DS3103_CLOCK_OUT_DISABLED:
1216 u8tmp = 0x80;
1217 break;
1218 case M88DS3103_CLOCK_OUT_ENABLED:
1219 u8tmp = 0x00;
1220 break;
1221 case M88DS3103_CLOCK_OUT_ENABLED_DIV2:
1222 u8tmp = 0x10;
1223 break;
1224 default:
1225 goto err;
1226 }
1227
1228 ret = m88ds3103_wr_reg(priv, 0x29, u8tmp);
1229 if (ret)
1230 goto err;
1231
1232 /* sleep */
1233 ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01);
1234 if (ret)
1235 goto err;
1236
1237 ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01);
1238 if (ret)
1239 goto err;
1240
1241 ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10);
1242 if (ret)
1243 goto err;
1244
1245 /* create mux i2c adapter for tuner */
1246 priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
1247 m88ds3103_select, m88ds3103_deselect);
1248 if (priv->i2c_adapter == NULL)
1249 goto err;
1250
1251 *tuner_i2c_adapter = priv->i2c_adapter;
1252
1253 /* create dvb_frontend */
1254 memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
1255 priv->fe.demodulator_priv = priv;
1256
1257 return &priv->fe;
1258err:
1259 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
1260 kfree(priv);
1261 return NULL;
1262}
1263EXPORT_SYMBOL(m88ds3103_attach);
1264
1265static struct dvb_frontend_ops m88ds3103_ops = {
1266 .delsys = { SYS_DVBS, SYS_DVBS2 },
1267 .info = {
1268 .name = "Montage M88DS3103",
1269 .frequency_min = 950000,
1270 .frequency_max = 2150000,
1271 .frequency_tolerance = 5000,
1272 .symbol_rate_min = 1000000,
1273 .symbol_rate_max = 45000000,
1274 .caps = FE_CAN_INVERSION_AUTO |
1275 FE_CAN_FEC_1_2 |
1276 FE_CAN_FEC_2_3 |
1277 FE_CAN_FEC_3_4 |
1278 FE_CAN_FEC_4_5 |
1279 FE_CAN_FEC_5_6 |
1280 FE_CAN_FEC_6_7 |
1281 FE_CAN_FEC_7_8 |
1282 FE_CAN_FEC_8_9 |
1283 FE_CAN_FEC_AUTO |
1284 FE_CAN_QPSK |
1285 FE_CAN_RECOVER |
1286 FE_CAN_2G_MODULATION
1287 },
1288
1289 .release = m88ds3103_release,
1290
1291 .get_tune_settings = m88ds3103_get_tune_settings,
1292
1293 .init = m88ds3103_init,
1294 .sleep = m88ds3103_sleep,
1295
1296 .set_frontend = m88ds3103_set_frontend,
1297 .get_frontend = m88ds3103_get_frontend,
1298
1299 .read_status = m88ds3103_read_status,
1300 .read_snr = m88ds3103_read_snr,
1301
1302 .diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd,
1303 .diseqc_send_burst = m88ds3103_diseqc_send_burst,
1304
1305 .set_tone = m88ds3103_set_tone,
1306};
1307
1308MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1309MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver");
1310MODULE_LICENSE("GPL");
1311MODULE_FIRMWARE(M88DS3103_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h
new file mode 100644
index 000000000000..bbb7e3aa5675
--- /dev/null
+++ b/drivers/media/dvb-frontends/m88ds3103.h
@@ -0,0 +1,114 @@
1/*
2 * Montage M88DS3103 demodulator driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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#ifndef M88DS3103_H
18#define M88DS3103_H
19
20#include <linux/dvb/frontend.h>
21
22struct m88ds3103_config {
23 /*
24 * I2C address
25 * Default: none, must set
26 * 0x68, ...
27 */
28 u8 i2c_addr;
29
30 /*
31 * clock
32 * Default: none, must set
33 * 27000000
34 */
35 u32 clock;
36
37 /*
38 * max bytes I2C provider is asked to write at once
39 * Default: none, must set
40 * 33, 65, ...
41 */
42 u16 i2c_wr_max;
43
44 /*
45 * TS output mode
46 * Default: M88DS3103_TS_SERIAL
47 */
48#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */
49#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */
50#define M88DS3103_TS_PARALLEL 2 /* 24 MHz, normal */
51#define M88DS3103_TS_PARALLEL_12 3 /* 12 MHz */
52#define M88DS3103_TS_PARALLEL_16 4 /* 16 MHz */
53#define M88DS3103_TS_PARALLEL_19_2 5 /* 19.2 MHz */
54#define M88DS3103_TS_CI 6 /* 6 MHz */
55 u8 ts_mode;
56
57 /*
58 * spectrum inversion
59 * Default: 0
60 */
61 u8 spec_inv:1;
62
63 /*
64 * AGC polarity
65 * Default: 0
66 */
67 u8 agc_inv:1;
68
69 /*
70 * clock output
71 * Default: M88DS3103_CLOCK_OUT_DISABLED
72 */
73#define M88DS3103_CLOCK_OUT_DISABLED 0
74#define M88DS3103_CLOCK_OUT_ENABLED 1
75#define M88DS3103_CLOCK_OUT_ENABLED_DIV2 2
76 u8 clock_out;
77
78 /*
79 * DiSEqC envelope mode
80 * Default: 0
81 */
82 u8 envelope_mode:1;
83
84 /*
85 * AGC configuration
86 * Default: none, must set
87 */
88 u8 agc;
89};
90
91/*
92 * Driver implements own I2C-adapter for tuner I2C access. That's since chip
93 * has I2C-gate control which closes gate automatically after I2C transfer.
94 * Using own I2C adapter we can workaround that.
95 */
96
97#if defined(CONFIG_DVB_M88DS3103) || \
98 (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
99extern struct dvb_frontend *m88ds3103_attach(
100 const struct m88ds3103_config *config,
101 struct i2c_adapter *i2c,
102 struct i2c_adapter **tuner_i2c);
103#else
104static inline struct dvb_frontend *m88ds3103_attach(
105 const struct m88ds3103_config *config,
106 struct i2c_adapter *i2c,
107 struct i2c_adapter **tuner_i2c)
108{
109 pr_warn("%s: driver disabled by Kconfig\n", __func__);
110 return NULL;
111}
112#endif
113
114#endif
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
new file mode 100644
index 000000000000..84c3c06df622
--- /dev/null
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -0,0 +1,215 @@
1/*
2 * Montage M88DS3103 demodulator driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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#ifndef M88DS3103_PRIV_H
18#define M88DS3103_PRIV_H
19
20#include "dvb_frontend.h"
21#include "m88ds3103.h"
22#include "dvb_math.h"
23#include <linux/firmware.h>
24#include <linux/i2c-mux.h>
25
26#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"
27#define M88DS3103_MCLK_KHZ 96000
28
29struct m88ds3103_priv {
30 struct i2c_adapter *i2c;
31 /* mutex needed due to own tuner I2C adapter */
32 struct mutex i2c_mutex;
33 const struct m88ds3103_config *cfg;
34 struct dvb_frontend fe;
35 fe_delivery_system_t delivery_system;
36 fe_status_t fe_status;
37 bool warm; /* FW running */
38 struct i2c_adapter *i2c_adapter;
39};
40
41struct m88ds3103_reg_val {
42 u8 reg;
43 u8 val;
44};
45
46static const struct m88ds3103_reg_val m88ds3103_dvbs_init_reg_vals[] = {
47 {0x23, 0x07},
48 {0x08, 0x03},
49 {0x0c, 0x02},
50 {0x21, 0x54},
51 {0x25, 0x8a},
52 {0x27, 0x31},
53 {0x30, 0x08},
54 {0x31, 0x40},
55 {0x32, 0x32},
56 {0x35, 0xff},
57 {0x3a, 0x00},
58 {0x37, 0x10},
59 {0x38, 0x10},
60 {0x39, 0x02},
61 {0x42, 0x60},
62 {0x4a, 0x80},
63 {0x4b, 0x04},
64 {0x4d, 0x91},
65 {0x5d, 0xc8},
66 {0x50, 0x36},
67 {0x51, 0x36},
68 {0x52, 0x36},
69 {0x53, 0x36},
70 {0x56, 0x01},
71 {0x63, 0x0f},
72 {0x64, 0x30},
73 {0x65, 0x40},
74 {0x68, 0x26},
75 {0x69, 0x4c},
76 {0x70, 0x20},
77 {0x71, 0x70},
78 {0x72, 0x04},
79 {0x73, 0x00},
80 {0x70, 0x40},
81 {0x71, 0x70},
82 {0x72, 0x04},
83 {0x73, 0x00},
84 {0x70, 0x60},
85 {0x71, 0x70},
86 {0x72, 0x04},
87 {0x73, 0x00},
88 {0x70, 0x80},
89 {0x71, 0x70},
90 {0x72, 0x04},
91 {0x73, 0x00},
92 {0x70, 0xa0},
93 {0x71, 0x70},
94 {0x72, 0x04},
95 {0x73, 0x00},
96 {0x70, 0x1f},
97 {0x76, 0x38},
98 {0x77, 0xa6},
99 {0x78, 0x0c},
100 {0x79, 0x80},
101 {0x7f, 0x14},
102 {0x7c, 0x00},
103 {0xae, 0x82},
104 {0x80, 0x64},
105 {0x81, 0x66},
106 {0x82, 0x44},
107 {0x85, 0x04},
108 {0xcd, 0xf4},
109 {0x90, 0x33},
110 {0xa0, 0x44},
111 {0xc0, 0x08},
112 {0xc3, 0x10},
113 {0xc4, 0x08},
114 {0xc5, 0xf0},
115 {0xc6, 0xff},
116 {0xc7, 0x00},
117 {0xc8, 0x1a},
118 {0xc9, 0x80},
119 {0xe0, 0xf8},
120 {0xe6, 0x8b},
121 {0xd0, 0x40},
122 {0xf8, 0x20},
123 {0xfa, 0x0f},
124 {0x00, 0x00},
125 {0xbd, 0x01},
126 {0xb8, 0x00},
127};
128
129static const struct m88ds3103_reg_val m88ds3103_dvbs2_init_reg_vals[] = {
130 {0x23, 0x07},
131 {0x08, 0x07},
132 {0x0c, 0x02},
133 {0x21, 0x54},
134 {0x25, 0x8a},
135 {0x27, 0x31},
136 {0x30, 0x08},
137 {0x32, 0x32},
138 {0x35, 0xff},
139 {0x3a, 0x00},
140 {0x37, 0x10},
141 {0x38, 0x10},
142 {0x39, 0x02},
143 {0x42, 0x60},
144 {0x4a, 0x80},
145 {0x4b, 0x04},
146 {0x4d, 0x91},
147 {0x5d, 0xc8},
148 {0x50, 0x36},
149 {0x51, 0x36},
150 {0x52, 0x36},
151 {0x53, 0x36},
152 {0x56, 0x01},
153 {0x63, 0x0f},
154 {0x64, 0x10},
155 {0x65, 0x20},
156 {0x68, 0x46},
157 {0x69, 0xcd},
158 {0x70, 0x20},
159 {0x71, 0x70},
160 {0x72, 0x04},
161 {0x73, 0x00},
162 {0x70, 0x40},
163 {0x71, 0x70},
164 {0x72, 0x04},
165 {0x73, 0x00},
166 {0x70, 0x60},
167 {0x71, 0x70},
168 {0x72, 0x04},
169 {0x73, 0x00},
170 {0x70, 0x80},
171 {0x71, 0x70},
172 {0x72, 0x04},
173 {0x73, 0x00},
174 {0x70, 0xa0},
175 {0x71, 0x70},
176 {0x72, 0x04},
177 {0x73, 0x00},
178 {0x70, 0x1f},
179 {0x76, 0x38},
180 {0x77, 0xa6},
181 {0x78, 0x0c},
182 {0x79, 0x80},
183 {0x7f, 0x14},
184 {0x85, 0x08},
185 {0xcd, 0xf4},
186 {0x90, 0x33},
187 {0x86, 0x00},
188 {0x87, 0x0f},
189 {0x89, 0x00},
190 {0x8b, 0x44},
191 {0x8c, 0x66},
192 {0x9d, 0xc1},
193 {0x8a, 0x10},
194 {0xad, 0x40},
195 {0xa0, 0x44},
196 {0xc0, 0x08},
197 {0xc1, 0x10},
198 {0xc2, 0x08},
199 {0xc3, 0x10},
200 {0xc4, 0x08},
201 {0xc5, 0xf0},
202 {0xc6, 0xff},
203 {0xc7, 0x00},
204 {0xc8, 0x1a},
205 {0xc9, 0x80},
206 {0xca, 0x23},
207 {0xcb, 0x24},
208 {0xcc, 0xf4},
209 {0xce, 0x74},
210 {0x00, 0x00},
211 {0xbd, 0x01},
212 {0xb8, 0x00},
213};
214
215#endif
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index 4da5272075cb..b2351466b0da 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -110,28 +110,94 @@ static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 reg)
110 return b1[0]; 110 return b1[0];
111} 111}
112 112
113static u32 m88rs2000_get_mclk(struct dvb_frontend *fe)
114{
115 struct m88rs2000_state *state = fe->demodulator_priv;
116 u32 mclk;
117 u8 reg;
118 /* Must not be 0x00 or 0xff */
119 reg = m88rs2000_readreg(state, 0x86);
120 if (!reg || reg == 0xff)
121 return 0;
122
123 reg /= 2;
124 reg += 1;
125
126 mclk = (u32)(reg * RS2000_FE_CRYSTAL_KHZ + 28 / 2) / 28;
127
128 return mclk;
129}
130
131static int m88rs2000_set_carrieroffset(struct dvb_frontend *fe, s16 offset)
132{
133 struct m88rs2000_state *state = fe->demodulator_priv;
134 u32 mclk;
135 s32 tmp;
136 u8 reg;
137 int ret;
138
139 mclk = m88rs2000_get_mclk(fe);
140 if (!mclk)
141 return -EINVAL;
142
143 tmp = (offset * 4096 + (s32)mclk / 2) / (s32)mclk;
144 if (tmp < 0)
145 tmp += 4096;
146
147 /* Carrier Offset */
148 ret = m88rs2000_writereg(state, 0x9c, (u8)(tmp >> 4));
149
150 reg = m88rs2000_readreg(state, 0x9d);
151 reg &= 0xf;
152 reg |= (u8)(tmp & 0xf) << 4;
153
154 ret |= m88rs2000_writereg(state, 0x9d, reg);
155
156 return ret;
157}
158
113static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate) 159static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
114{ 160{
115 struct m88rs2000_state *state = fe->demodulator_priv; 161 struct m88rs2000_state *state = fe->demodulator_priv;
116 int ret; 162 int ret;
117 u32 temp; 163 u64 temp;
164 u32 mclk;
118 u8 b[3]; 165 u8 b[3];
119 166
120 if ((srate < 1000000) || (srate > 45000000)) 167 if ((srate < 1000000) || (srate > 45000000))
121 return -EINVAL; 168 return -EINVAL;
122 169
170 mclk = m88rs2000_get_mclk(fe);
171 if (!mclk)
172 return -EINVAL;
173
123 temp = srate / 1000; 174 temp = srate / 1000;
124 temp *= 11831; 175 temp *= 1 << 24;
125 temp /= 68; 176
126 temp -= 3; 177 do_div(temp, mclk);
127 178
128 b[0] = (u8) (temp >> 16) & 0xff; 179 b[0] = (u8) (temp >> 16) & 0xff;
129 b[1] = (u8) (temp >> 8) & 0xff; 180 b[1] = (u8) (temp >> 8) & 0xff;
130 b[2] = (u8) temp & 0xff; 181 b[2] = (u8) temp & 0xff;
182
131 ret = m88rs2000_writereg(state, 0x93, b[2]); 183 ret = m88rs2000_writereg(state, 0x93, b[2]);
132 ret |= m88rs2000_writereg(state, 0x94, b[1]); 184 ret |= m88rs2000_writereg(state, 0x94, b[1]);
133 ret |= m88rs2000_writereg(state, 0x95, b[0]); 185 ret |= m88rs2000_writereg(state, 0x95, b[0]);
134 186
187 if (srate > 10000000)
188 ret |= m88rs2000_writereg(state, 0xa0, 0x20);
189 else
190 ret |= m88rs2000_writereg(state, 0xa0, 0x60);
191
192 ret |= m88rs2000_writereg(state, 0xa1, 0xe0);
193
194 if (srate > 12000000)
195 ret |= m88rs2000_writereg(state, 0xa3, 0x20);
196 else if (srate > 2800000)
197 ret |= m88rs2000_writereg(state, 0xa3, 0x98);
198 else
199 ret |= m88rs2000_writereg(state, 0xa3, 0x90);
200
135 deb_info("m88rs2000: m88rs2000_set_symbolrate\n"); 201 deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
136 return ret; 202 return ret;
137} 203}
@@ -261,8 +327,6 @@ struct inittab m88rs2000_shutdown[] = {
261 327
262struct inittab fe_reset[] = { 328struct inittab fe_reset[] = {
263 {DEMOD_WRITE, 0x00, 0x01}, 329 {DEMOD_WRITE, 0x00, 0x01},
264 {DEMOD_WRITE, 0xf1, 0xbf},
265 {DEMOD_WRITE, 0x00, 0x01},
266 {DEMOD_WRITE, 0x20, 0x81}, 330 {DEMOD_WRITE, 0x20, 0x81},
267 {DEMOD_WRITE, 0x21, 0x80}, 331 {DEMOD_WRITE, 0x21, 0x80},
268 {DEMOD_WRITE, 0x10, 0x33}, 332 {DEMOD_WRITE, 0x10, 0x33},
@@ -305,9 +369,6 @@ struct inittab fe_trigger[] = {
305 {DEMOD_WRITE, 0x9b, 0x64}, 369 {DEMOD_WRITE, 0x9b, 0x64},
306 {DEMOD_WRITE, 0x9e, 0x00}, 370 {DEMOD_WRITE, 0x9e, 0x00},
307 {DEMOD_WRITE, 0x9f, 0xf8}, 371 {DEMOD_WRITE, 0x9f, 0xf8},
308 {DEMOD_WRITE, 0xa0, 0x20},
309 {DEMOD_WRITE, 0xa1, 0xe0},
310 {DEMOD_WRITE, 0xa3, 0x38},
311 {DEMOD_WRITE, 0x98, 0xff}, 372 {DEMOD_WRITE, 0x98, 0xff},
312 {DEMOD_WRITE, 0xc0, 0x0f}, 373 {DEMOD_WRITE, 0xc0, 0x0f},
313 {DEMOD_WRITE, 0x89, 0x01}, 374 {DEMOD_WRITE, 0x89, 0x01},
@@ -408,7 +469,7 @@ static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
408 469
409 *status = 0; 470 *status = 0;
410 471
411 if ((reg & 0x7) == 0x7) { 472 if ((reg & 0xee) == 0xee) {
412 *status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI 473 *status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI
413 | FE_HAS_SYNC | FE_HAS_LOCK; 474 | FE_HAS_SYNC | FE_HAS_LOCK;
414 if (state->config->set_ts_params) 475 if (state->config->set_ts_params)
@@ -480,33 +541,38 @@ static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
480static int m88rs2000_set_fec(struct m88rs2000_state *state, 541static int m88rs2000_set_fec(struct m88rs2000_state *state,
481 fe_code_rate_t fec) 542 fe_code_rate_t fec)
482{ 543{
483 u16 fec_set; 544 u8 fec_set, reg;
545 int ret;
546
484 switch (fec) { 547 switch (fec) {
485 /* This is not confirmed kept for reference */ 548 case FEC_1_2:
486/* case FEC_1_2: 549 fec_set = 0x8;
487 fec_set = 0x88;
488 break; 550 break;
489 case FEC_2_3: 551 case FEC_2_3:
490 fec_set = 0x68; 552 fec_set = 0x10;
491 break; 553 break;
492 case FEC_3_4: 554 case FEC_3_4:
493 fec_set = 0x48; 555 fec_set = 0x20;
494 break; 556 break;
495 case FEC_5_6: 557 case FEC_5_6:
496 fec_set = 0x28; 558 fec_set = 0x40;
497 break; 559 break;
498 case FEC_7_8: 560 case FEC_7_8:
499 fec_set = 0x18; 561 fec_set = 0x80;
500 break; */ 562 break;
501 case FEC_AUTO: 563 case FEC_AUTO:
502 default: 564 default:
503 fec_set = 0x08; 565 fec_set = 0x0;
504 } 566 }
505 m88rs2000_writereg(state, 0x76, fec_set);
506 567
507 return 0; 568 reg = m88rs2000_readreg(state, 0x70);
508} 569 reg &= 0x7;
570 ret = m88rs2000_writereg(state, 0x70, reg | fec_set);
509 571
572 ret |= m88rs2000_writereg(state, 0x76, 0x8);
573
574 return ret;
575}
510 576
511static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state) 577static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
512{ 578{
@@ -515,18 +581,20 @@ static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
515 reg = m88rs2000_readreg(state, 0x76); 581 reg = m88rs2000_readreg(state, 0x76);
516 m88rs2000_writereg(state, 0x9a, 0xb0); 582 m88rs2000_writereg(state, 0x9a, 0xb0);
517 583
584 reg &= 0xf0;
585 reg >>= 5;
586
518 switch (reg) { 587 switch (reg) {
519 case 0x88: 588 case 0x4:
520 return FEC_1_2; 589 return FEC_1_2;
521 case 0x68: 590 case 0x3:
522 return FEC_2_3; 591 return FEC_2_3;
523 case 0x48: 592 case 0x2:
524 return FEC_3_4; 593 return FEC_3_4;
525 case 0x28: 594 case 0x1:
526 return FEC_5_6; 595 return FEC_5_6;
527 case 0x18: 596 case 0x0:
528 return FEC_7_8; 597 return FEC_7_8;
529 case 0x08:
530 default: 598 default:
531 break; 599 break;
532 } 600 }
@@ -540,9 +608,8 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
540 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 608 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
541 fe_status_t status; 609 fe_status_t status;
542 int i, ret = 0; 610 int i, ret = 0;
543 s32 tmp;
544 u32 tuner_freq; 611 u32 tuner_freq;
545 u16 offset = 0; 612 s16 offset = 0;
546 u8 reg; 613 u8 reg;
547 614
548 state->no_lock_count = 0; 615 state->no_lock_count = 0;
@@ -567,38 +634,31 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
567 if (ret < 0) 634 if (ret < 0)
568 return -ENODEV; 635 return -ENODEV;
569 636
570 offset = tuner_freq - c->frequency; 637 offset = (s16)((s32)tuner_freq - c->frequency);
571
572 /* calculate offset assuming 96000kHz*/
573 tmp = offset;
574 tmp *= 65536;
575
576 tmp = (2 * tmp + 96000) / (2 * 96000);
577 if (tmp < 0)
578 tmp += 65536;
579 638
580 offset = tmp & 0xffff; 639 /* default mclk value 96.4285 * 2 * 1000 = 192857 */
640 if (((c->frequency % 192857) >= (192857 - 3000)) ||
641 (c->frequency % 192857) <= 3000)
642 ret = m88rs2000_writereg(state, 0x86, 0xc2);
643 else
644 ret = m88rs2000_writereg(state, 0x86, 0xc6);
581 645
582 ret = m88rs2000_writereg(state, 0x9a, 0x30); 646 ret |= m88rs2000_set_carrieroffset(fe, offset);
583 /* Unknown usually 0xc6 sometimes 0xc1 */ 647 if (ret < 0)
584 reg = m88rs2000_readreg(state, 0x86); 648 return -ENODEV;
585 ret |= m88rs2000_writereg(state, 0x86, reg);
586 /* Offset lower nibble always 0 */
587 ret |= m88rs2000_writereg(state, 0x9c, (offset >> 8));
588 ret |= m88rs2000_writereg(state, 0x9d, offset & 0xf0);
589 649
650 /* Reset demod by symbol rate */
651 if (c->symbol_rate > 27500000)
652 ret = m88rs2000_writereg(state, 0xf1, 0xa4);
653 else
654 ret = m88rs2000_writereg(state, 0xf1, 0xbf);
590 655
591 /* Reset Demod */ 656 ret |= m88rs2000_tab_set(state, fe_reset);
592 ret = m88rs2000_tab_set(state, fe_reset);
593 if (ret < 0) 657 if (ret < 0)
594 return -ENODEV; 658 return -ENODEV;
595 659
596 /* Unknown */
597 reg = m88rs2000_readreg(state, 0x70);
598 ret = m88rs2000_writereg(state, 0x70, reg);
599
600 /* Set FEC */ 660 /* Set FEC */
601 ret |= m88rs2000_set_fec(state, c->fec_inner); 661 ret = m88rs2000_set_fec(state, c->fec_inner);
602 ret |= m88rs2000_writereg(state, 0x85, 0x1); 662 ret |= m88rs2000_writereg(state, 0x85, 0x1);
603 ret |= m88rs2000_writereg(state, 0x8a, 0xbf); 663 ret |= m88rs2000_writereg(state, 0x8a, 0xbf);
604 ret |= m88rs2000_writereg(state, 0x8d, 0x1e); 664 ret |= m88rs2000_writereg(state, 0x8d, 0x1e);
@@ -620,7 +680,7 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
620 680
621 for (i = 0; i < 25; i++) { 681 for (i = 0; i < 25; i++) {
622 reg = m88rs2000_readreg(state, 0x8c); 682 reg = m88rs2000_readreg(state, 0x8c);
623 if ((reg & 0x7) == 0x7) { 683 if ((reg & 0xee) == 0xee) {
624 status = FE_HAS_LOCK; 684 status = FE_HAS_LOCK;
625 break; 685 break;
626 } 686 }
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
index 14ce31e76ae6..0a50ea90736b 100644
--- a/drivers/media/dvb-frontends/m88rs2000.h
+++ b/drivers/media/dvb-frontends/m88rs2000.h
@@ -53,6 +53,8 @@ static inline struct dvb_frontend *m88rs2000_attach(
53} 53}
54#endif /* CONFIG_DVB_M88RS2000 */ 54#endif /* CONFIG_DVB_M88RS2000 */
55 55
56#define RS2000_FE_CRYSTAL_KHZ 27000
57
56enum { 58enum {
57 DEMOD_WRITE = 0x1, 59 DEMOD_WRITE = 0x1,
58 WRITE_DELAY = 0x10, 60 WRITE_DELAY = 0x10,
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c
index fbca9856313a..4bf057544607 100644
--- a/drivers/media/dvb-frontends/nxt200x.c
+++ b/drivers/media/dvb-frontends/nxt200x.c
@@ -40,7 +40,7 @@
40#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 40#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
41 41
42/* Max transfer size done by I2C transfer functions */ 42/* Max transfer size done by I2C transfer functions */
43#define MAX_XFER_SIZE 64 43#define MAX_XFER_SIZE 256
44 44
45#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" 45#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
46#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw" 46#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 842654d33317..4aa9c5311cc5 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -555,14 +555,6 @@ config VIDEO_MT9V032
555 This is a Video4Linux2 sensor-level driver for the Micron 555 This is a Video4Linux2 sensor-level driver for the Micron
556 MT9V032 752x480 CMOS sensor. 556 MT9V032 752x480 CMOS sensor.
557 557
558config VIDEO_TCM825X
559 tristate "TCM825x camera sensor support"
560 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_INT_DEVICE
561 depends on MEDIA_CAMERA_SUPPORT
562 ---help---
563 This is a driver for the Toshiba TCM825x VGA camera sensor.
564 It is used for example in Nokia N800.
565
566config VIDEO_SR030PC30 558config VIDEO_SR030PC30
567 tristate "Siliconfile SR030PC30 sensor support" 559 tristate "Siliconfile SR030PC30 sensor support"
568 depends on I2C && VIDEO_V4L2 560 depends on I2C && VIDEO_V4L2
@@ -594,6 +586,13 @@ config VIDEO_S5K4ECGX
594 This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M 586 This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
595 camera sensor with an embedded SoC image signal processor. 587 camera sensor with an embedded SoC image signal processor.
596 588
589config VIDEO_S5K5BAF
590 tristate "Samsung S5K5BAF sensor support"
591 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
592 ---help---
593 This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
594 camera sensor with an embedded SoC image signal processor.
595
597source "drivers/media/i2c/smiapp/Kconfig" 596source "drivers/media/i2c/smiapp/Kconfig"
598 597
599config VIDEO_S5C73M3 598config VIDEO_S5C73M3
@@ -655,6 +654,18 @@ config VIDEO_UPD64083
655 To compile this driver as a module, choose M here: the 654 To compile this driver as a module, choose M here: the
656 module will be called upd64083. 655 module will be called upd64083.
657 656
657comment "Audio/Video compression chips"
658
659config VIDEO_SAA6752HS
660 tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder"
661 depends on VIDEO_V4L2 && I2C
662 ---help---
663 Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3
664 audio encoder with multiplexer.
665
666 To compile this driver as a module, choose M here: the
667 module will be called saa6752hs.
668
658comment "Miscellaneous helper chips" 669comment "Miscellaneous helper chips"
659 670
660config VIDEO_THS7303 671config VIDEO_THS7303
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index e03f1776f4f4..48888ae876fb 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
19obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o 19obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
20obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o 20obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
21obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o 21obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
22obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
22obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o 23obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
23obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o 24obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
24obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o 25obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
@@ -57,7 +58,6 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
57obj-$(CONFIG_VIDEO_OV7640) += ov7640.o 58obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
58obj-$(CONFIG_VIDEO_OV7670) += ov7670.o 59obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
59obj-$(CONFIG_VIDEO_OV9650) += ov9650.o 60obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
60obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
61obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o 61obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
62obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o 62obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
63obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o 63obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
67obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 67obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
68obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o 68obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
69obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o 69obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o
70obj-$(CONFIG_VIDEO_S5K5BAF) += s5k5baf.o
70obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ 71obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
71obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o 72obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
72obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o 73obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index b06a7e54ee0d..83225d6a0dd9 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -66,11 +66,6 @@ MODULE_LICENSE("GPL");
66********************************************************************** 66**********************************************************************
67*/ 67*/
68 68
69struct i2c_reg_value {
70 u8 reg;
71 u8 value;
72};
73
74struct ad9389b_state_edid { 69struct ad9389b_state_edid {
75 /* total number of blocks */ 70 /* total number of blocks */
76 u32 blocks; 71 u32 blocks;
@@ -143,14 +138,14 @@ static int ad9389b_wr(struct v4l2_subdev *sd, u8 reg, u8 val)
143 if (ret == 0) 138 if (ret == 0)
144 return 0; 139 return 0;
145 } 140 }
146 v4l2_err(sd, "I2C Write Problem\n"); 141 v4l2_err(sd, "%s: failed reg 0x%x, val 0x%x\n", __func__, reg, val);
147 return ret; 142 return ret;
148} 143}
149 144
150/* To set specific bits in the register, a clear-mask is given (to be AND-ed), 145/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
151 and then the value-mask (to be OR-ed). */ 146 and then the value-mask (to be OR-ed). */
152static inline void ad9389b_wr_and_or(struct v4l2_subdev *sd, u8 reg, 147static inline void ad9389b_wr_and_or(struct v4l2_subdev *sd, u8 reg,
153 u8 clr_mask, u8 val_mask) 148 u8 clr_mask, u8 val_mask)
154{ 149{
155 ad9389b_wr(sd, reg, (ad9389b_rd(sd, reg) & clr_mask) | val_mask); 150 ad9389b_wr(sd, reg, (ad9389b_rd(sd, reg) & clr_mask) | val_mask);
156} 151}
@@ -321,12 +316,12 @@ static int ad9389b_s_ctrl(struct v4l2_ctrl *ctrl)
321 struct ad9389b_state *state = get_ad9389b_state(sd); 316 struct ad9389b_state *state = get_ad9389b_state(sd);
322 317
323 v4l2_dbg(1, debug, sd, 318 v4l2_dbg(1, debug, sd,
324 "%s: ctrl id: %d, ctrl->val %d\n", __func__, ctrl->id, ctrl->val); 319 "%s: ctrl id: %d, ctrl->val %d\n", __func__, ctrl->id, ctrl->val);
325 320
326 if (state->hdmi_mode_ctrl == ctrl) { 321 if (state->hdmi_mode_ctrl == ctrl) {
327 /* Set HDMI or DVI-D */ 322 /* Set HDMI or DVI-D */
328 ad9389b_wr_and_or(sd, 0xaf, 0xfd, 323 ad9389b_wr_and_or(sd, 0xaf, 0xfd,
329 ctrl->val == V4L2_DV_TX_MODE_HDMI ? 0x02 : 0x00); 324 ctrl->val == V4L2_DV_TX_MODE_HDMI ? 0x02 : 0x00);
330 return 0; 325 return 0;
331 } 326 }
332 if (state->rgb_quantization_range_ctrl == ctrl) 327 if (state->rgb_quantization_range_ctrl == ctrl)
@@ -387,61 +382,57 @@ static int ad9389b_log_status(struct v4l2_subdev *sd)
387 v4l2_info(sd, "chip revision %d\n", state->chip_revision); 382 v4l2_info(sd, "chip revision %d\n", state->chip_revision);
388 v4l2_info(sd, "power %s\n", state->power_on ? "on" : "off"); 383 v4l2_info(sd, "power %s\n", state->power_on ? "on" : "off");
389 v4l2_info(sd, "%s hotplug, %s Rx Sense, %s EDID (%d block(s))\n", 384 v4l2_info(sd, "%s hotplug, %s Rx Sense, %s EDID (%d block(s))\n",
390 (ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT) ? 385 (ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT) ?
391 "detected" : "no", 386 "detected" : "no",
392 (ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT) ? 387 (ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT) ?
393 "detected" : "no", 388 "detected" : "no",
394 edid->segments ? "found" : "no", edid->blocks); 389 edid->segments ? "found" : "no", edid->blocks);
395 if (state->have_monitor) { 390 v4l2_info(sd, "%s output %s\n",
396 v4l2_info(sd, "%s output %s\n", 391 (ad9389b_rd(sd, 0xaf) & 0x02) ?
397 (ad9389b_rd(sd, 0xaf) & 0x02) ? 392 "HDMI" : "DVI-D",
398 "HDMI" : "DVI-D", 393 (ad9389b_rd(sd, 0xa1) & 0x3c) ?
399 (ad9389b_rd(sd, 0xa1) & 0x3c) ? 394 "disabled" : "enabled");
400 "disabled" : "enabled");
401 }
402 v4l2_info(sd, "ad9389b: %s\n", (ad9389b_rd(sd, 0xb8) & 0x40) ? 395 v4l2_info(sd, "ad9389b: %s\n", (ad9389b_rd(sd, 0xb8) & 0x40) ?
403 "encrypted" : "no encryption"); 396 "encrypted" : "no encryption");
404 v4l2_info(sd, "state: %s, error: %s, detect count: %u, msk/irq: %02x/%02x\n", 397 v4l2_info(sd, "state: %s, error: %s, detect count: %u, msk/irq: %02x/%02x\n",
405 states[ad9389b_rd(sd, 0xc8) & 0xf], 398 states[ad9389b_rd(sd, 0xc8) & 0xf],
406 errors[ad9389b_rd(sd, 0xc8) >> 4], 399 errors[ad9389b_rd(sd, 0xc8) >> 4],
407 state->edid_detect_counter, 400 state->edid_detect_counter,
408 ad9389b_rd(sd, 0x94), ad9389b_rd(sd, 0x96)); 401 ad9389b_rd(sd, 0x94), ad9389b_rd(sd, 0x96));
409 manual_gear = ad9389b_rd(sd, 0x98) & 0x80; 402 manual_gear = ad9389b_rd(sd, 0x98) & 0x80;
410 v4l2_info(sd, "ad9389b: RGB quantization: %s range\n", 403 v4l2_info(sd, "ad9389b: RGB quantization: %s range\n",
411 ad9389b_rd(sd, 0x3b) & 0x01 ? "limited" : "full"); 404 ad9389b_rd(sd, 0x3b) & 0x01 ? "limited" : "full");
412 v4l2_info(sd, "ad9389b: %s gear %d\n", 405 v4l2_info(sd, "ad9389b: %s gear %d\n",
413 manual_gear ? "manual" : "automatic", 406 manual_gear ? "manual" : "automatic",
414 manual_gear ? ((ad9389b_rd(sd, 0x98) & 0x70) >> 4) : 407 manual_gear ? ((ad9389b_rd(sd, 0x98) & 0x70) >> 4) :
415 ((ad9389b_rd(sd, 0x9e) & 0x0e) >> 1)); 408 ((ad9389b_rd(sd, 0x9e) & 0x0e) >> 1));
416 if (state->have_monitor) { 409 if (ad9389b_rd(sd, 0xaf) & 0x02) {
417 if (ad9389b_rd(sd, 0xaf) & 0x02) { 410 /* HDMI only */
418 /* HDMI only */ 411 u8 manual_cts = ad9389b_rd(sd, 0x0a) & 0x80;
419 u8 manual_cts = ad9389b_rd(sd, 0x0a) & 0x80; 412 u32 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
420 u32 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 | 413 ad9389b_rd(sd, 0x02) << 8 |
421 ad9389b_rd(sd, 0x02) << 8 | 414 ad9389b_rd(sd, 0x03);
422 ad9389b_rd(sd, 0x03); 415 u8 vic_detect = ad9389b_rd(sd, 0x3e) >> 2;
423 u8 vic_detect = ad9389b_rd(sd, 0x3e) >> 2; 416 u8 vic_sent = ad9389b_rd(sd, 0x3d) & 0x3f;
424 u8 vic_sent = ad9389b_rd(sd, 0x3d) & 0x3f; 417 u32 CTS;
425 u32 CTS; 418
426 419 if (manual_cts)
427 if (manual_cts) 420 CTS = (ad9389b_rd(sd, 0x07) & 0xf) << 16 |
428 CTS = (ad9389b_rd(sd, 0x07) & 0xf) << 16 | 421 ad9389b_rd(sd, 0x08) << 8 |
429 ad9389b_rd(sd, 0x08) << 8 | 422 ad9389b_rd(sd, 0x09);
430 ad9389b_rd(sd, 0x09); 423 else
431 else 424 CTS = (ad9389b_rd(sd, 0x04) & 0xf) << 16 |
432 CTS = (ad9389b_rd(sd, 0x04) & 0xf) << 16 | 425 ad9389b_rd(sd, 0x05) << 8 |
433 ad9389b_rd(sd, 0x05) << 8 | 426 ad9389b_rd(sd, 0x06);
434 ad9389b_rd(sd, 0x06); 427 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
435 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 | 428 ad9389b_rd(sd, 0x02) << 8 |
436 ad9389b_rd(sd, 0x02) << 8 | 429 ad9389b_rd(sd, 0x03);
437 ad9389b_rd(sd, 0x03); 430
438 431 v4l2_info(sd, "ad9389b: CTS %s mode: N %d, CTS %d\n",
439 v4l2_info(sd, "ad9389b: CTS %s mode: N %d, CTS %d\n", 432 manual_cts ? "manual" : "automatic", N, CTS);
440 manual_cts ? "manual" : "automatic", N, CTS); 433
441 434 v4l2_info(sd, "ad9389b: VIC: detected %d, sent %d\n",
442 v4l2_info(sd, "ad9389b: VIC: detected %d, sent %d\n", 435 vic_detect, vic_sent);
443 vic_detect, vic_sent);
444 }
445 } 436 }
446 if (state->dv_timings.type == V4L2_DV_BT_656_1120) 437 if (state->dv_timings.type == V4L2_DV_BT_656_1120)
447 v4l2_print_dv_timings(sd->name, "timings: ", 438 v4l2_print_dv_timings(sd->name, "timings: ",
@@ -486,7 +477,7 @@ static int ad9389b_s_power(struct v4l2_subdev *sd, int on)
486 } 477 }
487 if (i > 1) 478 if (i > 1)
488 v4l2_dbg(1, debug, sd, 479 v4l2_dbg(1, debug, sd,
489 "needed %d retries to powerup the ad9389b\n", i); 480 "needed %d retries to powerup the ad9389b\n", i);
490 481
491 /* Select chip: AD9389B */ 482 /* Select chip: AD9389B */
492 ad9389b_wr_and_or(sd, 0xba, 0xef, 0x10); 483 ad9389b_wr_and_or(sd, 0xba, 0xef, 0x10);
@@ -556,14 +547,16 @@ static int ad9389b_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
556 irq_status = ad9389b_rd(sd, 0x96); 547 irq_status = ad9389b_rd(sd, 0x96);
557 /* clear detected interrupts */ 548 /* clear detected interrupts */
558 ad9389b_wr(sd, 0x96, irq_status); 549 ad9389b_wr(sd, 0x96, irq_status);
550 /* enable interrupts */
551 ad9389b_set_isr(sd, true);
552
553 v4l2_dbg(1, debug, sd, "%s: irq_status 0x%x\n", __func__, irq_status);
559 554
560 if (irq_status & (MASK_AD9389B_HPD_INT | MASK_AD9389B_MSEN_INT)) 555 if (irq_status & (MASK_AD9389B_HPD_INT))
561 ad9389b_check_monitor_present_status(sd); 556 ad9389b_check_monitor_present_status(sd);
562 if (irq_status & MASK_AD9389B_EDID_RDY_INT) 557 if (irq_status & MASK_AD9389B_EDID_RDY_INT)
563 ad9389b_check_edid_status(sd); 558 ad9389b_check_edid_status(sd);
564 559
565 /* enable interrupts */
566 ad9389b_set_isr(sd, true);
567 *handled = true; 560 *handled = true;
568 return 0; 561 return 0;
569} 562}
@@ -599,7 +592,7 @@ static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi
599 if (edid->blocks + edid->start_block >= state->edid.segments * 2) 592 if (edid->blocks + edid->start_block >= state->edid.segments * 2)
600 edid->blocks = state->edid.segments * 2 - edid->start_block; 593 edid->blocks = state->edid.segments * 2 - edid->start_block;
601 memcpy(edid->edid, &state->edid.data[edid->start_block * 128], 594 memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
602 128 * edid->blocks); 595 128 * edid->blocks);
603 return 0; 596 return 0;
604} 597}
605 598
@@ -612,8 +605,6 @@ static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
612/* Enable/disable ad9389b output */ 605/* Enable/disable ad9389b output */
613static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable) 606static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable)
614{ 607{
615 struct ad9389b_state *state = get_ad9389b_state(sd);
616
617 v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis")); 608 v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
618 609
619 ad9389b_wr_and_or(sd, 0xa1, ~0x3c, (enable ? 0 : 0x3c)); 610 ad9389b_wr_and_or(sd, 0xa1, ~0x3c, (enable ? 0 : 0x3c));
@@ -621,7 +612,6 @@ static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable)
621 ad9389b_check_monitor_present_status(sd); 612 ad9389b_check_monitor_present_status(sd);
622 } else { 613 } else {
623 ad9389b_s_power(sd, 0); 614 ad9389b_s_power(sd, 0);
624 state->have_monitor = false;
625 } 615 }
626 return 0; 616 return 0;
627} 617}
@@ -686,14 +676,14 @@ static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
686} 676}
687 677
688static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd, 678static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
689 struct v4l2_enum_dv_timings *timings) 679 struct v4l2_enum_dv_timings *timings)
690{ 680{
691 return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap, 681 return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
692 NULL, NULL); 682 NULL, NULL);
693} 683}
694 684
695static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd, 685static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
696 struct v4l2_dv_timings_cap *cap) 686 struct v4l2_dv_timings_cap *cap)
697{ 687{
698 *cap = ad9389b_timings_cap; 688 *cap = ad9389b_timings_cap;
699 return 0; 689 return 0;
@@ -724,15 +714,15 @@ static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
724 u32 N; 714 u32 N;
725 715
726 switch (freq) { 716 switch (freq) {
727 case 32000: N = 4096; break; 717 case 32000: N = 4096; break;
728 case 44100: N = 6272; break; 718 case 44100: N = 6272; break;
729 case 48000: N = 6144; break; 719 case 48000: N = 6144; break;
730 case 88200: N = 12544; break; 720 case 88200: N = 12544; break;
731 case 96000: N = 12288; break; 721 case 96000: N = 12288; break;
732 case 176400: N = 25088; break; 722 case 176400: N = 25088; break;
733 case 192000: N = 24576; break; 723 case 192000: N = 24576; break;
734 default: 724 default:
735 return -EINVAL; 725 return -EINVAL;
736 } 726 }
737 727
738 /* Set N (used with CTS to regenerate the audio clock) */ 728 /* Set N (used with CTS to regenerate the audio clock) */
@@ -748,15 +738,15 @@ static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
748 u32 i2s_sf; 738 u32 i2s_sf;
749 739
750 switch (freq) { 740 switch (freq) {
751 case 32000: i2s_sf = 0x30; break; 741 case 32000: i2s_sf = 0x30; break;
752 case 44100: i2s_sf = 0x00; break; 742 case 44100: i2s_sf = 0x00; break;
753 case 48000: i2s_sf = 0x20; break; 743 case 48000: i2s_sf = 0x20; break;
754 case 88200: i2s_sf = 0x80; break; 744 case 88200: i2s_sf = 0x80; break;
755 case 96000: i2s_sf = 0xa0; break; 745 case 96000: i2s_sf = 0xa0; break;
756 case 176400: i2s_sf = 0xc0; break; 746 case 176400: i2s_sf = 0xc0; break;
757 case 192000: i2s_sf = 0xe0; break; 747 case 192000: i2s_sf = 0xe0; break;
758 default: 748 default:
759 return -EINVAL; 749 return -EINVAL;
760 } 750 }
761 751
762 /* Set sampling frequency for I2S audio to 48 kHz */ 752 /* Set sampling frequency for I2S audio to 48 kHz */
@@ -800,7 +790,7 @@ static const struct v4l2_subdev_ops ad9389b_ops = {
800 790
801/* ----------------------------------------------------------------------- */ 791/* ----------------------------------------------------------------------- */
802static void ad9389b_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd, 792static void ad9389b_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd,
803 int segment, u8 *buf) 793 int segment, u8 *buf)
804{ 794{
805 int i, j; 795 int i, j;
806 796
@@ -826,8 +816,8 @@ static void ad9389b_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd,
826static void ad9389b_edid_handler(struct work_struct *work) 816static void ad9389b_edid_handler(struct work_struct *work)
827{ 817{
828 struct delayed_work *dwork = to_delayed_work(work); 818 struct delayed_work *dwork = to_delayed_work(work);
829 struct ad9389b_state *state = container_of(dwork, 819 struct ad9389b_state *state =
830 struct ad9389b_state, edid_handler); 820 container_of(dwork, struct ad9389b_state, edid_handler);
831 struct v4l2_subdev *sd = &state->sd; 821 struct v4l2_subdev *sd = &state->sd;
832 struct ad9389b_edid_detect ed; 822 struct ad9389b_edid_detect ed;
833 823
@@ -845,11 +835,10 @@ static void ad9389b_edid_handler(struct work_struct *work)
845 if (state->edid.read_retries) { 835 if (state->edid.read_retries) {
846 state->edid.read_retries--; 836 state->edid.read_retries--;
847 v4l2_dbg(1, debug, sd, "%s: edid read failed\n", __func__); 837 v4l2_dbg(1, debug, sd, "%s: edid read failed\n", __func__);
848 state->have_monitor = false;
849 ad9389b_s_power(sd, false); 838 ad9389b_s_power(sd, false);
850 ad9389b_s_power(sd, true); 839 ad9389b_s_power(sd, true);
851 queue_delayed_work(state->work_queue, 840 queue_delayed_work(state->work_queue,
852 &state->edid_handler, EDID_DELAY); 841 &state->edid_handler, EDID_DELAY);
853 return; 842 return;
854 } 843 }
855 } 844 }
@@ -915,49 +904,35 @@ static void ad9389b_notify_monitor_detect(struct v4l2_subdev *sd)
915 v4l2_subdev_notify(sd, AD9389B_MONITOR_DETECT, (void *)&mdt); 904 v4l2_subdev_notify(sd, AD9389B_MONITOR_DETECT, (void *)&mdt);
916} 905}
917 906
918static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd) 907static void ad9389b_update_monitor_present_status(struct v4l2_subdev *sd)
919{ 908{
920 struct ad9389b_state *state = get_ad9389b_state(sd); 909 struct ad9389b_state *state = get_ad9389b_state(sd);
921 /* read hotplug and rx-sense state */ 910 /* read hotplug and rx-sense state */
922 u8 status = ad9389b_rd(sd, 0x42); 911 u8 status = ad9389b_rd(sd, 0x42);
923 912
924 v4l2_dbg(1, debug, sd, "%s: status: 0x%x%s%s\n", 913 v4l2_dbg(1, debug, sd, "%s: status: 0x%x%s%s\n",
925 __func__, 914 __func__,
926 status, 915 status,
927 status & MASK_AD9389B_HPD_DETECT ? ", hotplug" : "", 916 status & MASK_AD9389B_HPD_DETECT ? ", hotplug" : "",
928 status & MASK_AD9389B_MSEN_DETECT ? ", rx-sense" : ""); 917 status & MASK_AD9389B_MSEN_DETECT ? ", rx-sense" : "");
929 918
930 if ((status & MASK_AD9389B_HPD_DETECT) && 919 if (status & MASK_AD9389B_HPD_DETECT) {
931 ((status & MASK_AD9389B_MSEN_DETECT) || state->edid.segments)) {
932 v4l2_dbg(1, debug, sd,
933 "%s: hotplug and (rx-sense or edid)\n", __func__);
934 if (!state->have_monitor) {
935 v4l2_dbg(1, debug, sd, "%s: monitor detected\n", __func__);
936 state->have_monitor = true;
937 ad9389b_set_isr(sd, true);
938 if (!ad9389b_s_power(sd, true)) {
939 v4l2_dbg(1, debug, sd,
940 "%s: monitor detected, powerup failed\n", __func__);
941 return;
942 }
943 ad9389b_setup(sd);
944 ad9389b_notify_monitor_detect(sd);
945 state->edid.read_retries = EDID_MAX_RETRIES;
946 queue_delayed_work(state->work_queue,
947 &state->edid_handler, EDID_DELAY);
948 }
949 } else if (status & MASK_AD9389B_HPD_DETECT) {
950 v4l2_dbg(1, debug, sd, "%s: hotplug detected\n", __func__); 920 v4l2_dbg(1, debug, sd, "%s: hotplug detected\n", __func__);
921 state->have_monitor = true;
922 if (!ad9389b_s_power(sd, true)) {
923 v4l2_dbg(1, debug, sd,
924 "%s: monitor detected, powerup failed\n", __func__);
925 return;
926 }
927 ad9389b_setup(sd);
928 ad9389b_notify_monitor_detect(sd);
951 state->edid.read_retries = EDID_MAX_RETRIES; 929 state->edid.read_retries = EDID_MAX_RETRIES;
952 queue_delayed_work(state->work_queue, 930 queue_delayed_work(state->work_queue,
953 &state->edid_handler, EDID_DELAY); 931 &state->edid_handler, EDID_DELAY);
954 } else if (!(status & MASK_AD9389B_HPD_DETECT)) { 932 } else if (!(status & MASK_AD9389B_HPD_DETECT)) {
955 v4l2_dbg(1, debug, sd, "%s: hotplug not detected\n", __func__); 933 v4l2_dbg(1, debug, sd, "%s: hotplug not detected\n", __func__);
956 if (state->have_monitor) { 934 state->have_monitor = false;
957 v4l2_dbg(1, debug, sd, "%s: monitor not detected\n", __func__); 935 ad9389b_notify_monitor_detect(sd);
958 state->have_monitor = false;
959 ad9389b_notify_monitor_detect(sd);
960 }
961 ad9389b_s_power(sd, false); 936 ad9389b_s_power(sd, false);
962 memset(&state->edid, 0, sizeof(struct ad9389b_state_edid)); 937 memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
963 } 938 }
@@ -966,6 +941,35 @@ static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
966 v4l2_ctrl_s_ctrl(state->hotplug_ctrl, ad9389b_have_hotplug(sd) ? 0x1 : 0x0); 941 v4l2_ctrl_s_ctrl(state->hotplug_ctrl, ad9389b_have_hotplug(sd) ? 0x1 : 0x0);
967 v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, ad9389b_have_rx_sense(sd) ? 0x1 : 0x0); 942 v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, ad9389b_have_rx_sense(sd) ? 0x1 : 0x0);
968 v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0); 943 v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
944
945 /* update with setting from ctrls */
946 ad9389b_s_ctrl(state->rgb_quantization_range_ctrl);
947 ad9389b_s_ctrl(state->hdmi_mode_ctrl);
948}
949
950static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
951{
952 struct ad9389b_state *state = get_ad9389b_state(sd);
953 int retry = 0;
954
955 ad9389b_update_monitor_present_status(sd);
956
957 /*
958 * Rapid toggling of the hotplug may leave the chip powered off,
959 * even if we think it is on. In that case reset and power up again.
960 */
961 while (state->power_on && (ad9389b_rd(sd, 0x41) & 0x40)) {
962 if (++retry > 5) {
963 v4l2_err(sd, "retried %d times, give up\n", retry);
964 return;
965 }
966 v4l2_dbg(1, debug, sd, "%s: reset and re-check status (%d)\n", __func__, retry);
967 ad9389b_notify_monitor_detect(sd);
968 cancel_delayed_work_sync(&state->edid_handler);
969 memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
970 ad9389b_s_power(sd, false);
971 ad9389b_update_monitor_present_status(sd);
972 }
969} 973}
970 974
971static bool edid_block_verify_crc(u8 *edid_block) 975static bool edid_block_verify_crc(u8 *edid_block)
@@ -978,7 +982,7 @@ static bool edid_block_verify_crc(u8 *edid_block)
978 return sum == 0; 982 return sum == 0;
979} 983}
980 984
981static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment) 985static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment)
982{ 986{
983 struct ad9389b_state *state = get_ad9389b_state(sd); 987 struct ad9389b_state *state = get_ad9389b_state(sd);
984 u32 blocks = state->edid.blocks; 988 u32 blocks = state->edid.blocks;
@@ -992,6 +996,25 @@ static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment)
992 return false; 996 return false;
993} 997}
994 998
999static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment)
1000{
1001 static const u8 hdmi_header[] = {
1002 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
1003 };
1004 struct ad9389b_state *state = get_ad9389b_state(sd);
1005 u8 *data = state->edid.data;
1006 int i;
1007
1008 if (segment)
1009 return true;
1010
1011 for (i = 0; i < ARRAY_SIZE(hdmi_header); i++)
1012 if (data[i] != hdmi_header[i])
1013 return false;
1014
1015 return true;
1016}
1017
995static bool ad9389b_check_edid_status(struct v4l2_subdev *sd) 1018static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
996{ 1019{
997 struct ad9389b_state *state = get_ad9389b_state(sd); 1020 struct ad9389b_state *state = get_ad9389b_state(sd);
@@ -1000,7 +1023,7 @@ static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
1000 u8 edidRdy = ad9389b_rd(sd, 0xc5); 1023 u8 edidRdy = ad9389b_rd(sd, 0xc5);
1001 1024
1002 v4l2_dbg(1, debug, sd, "%s: edid ready (retries: %d)\n", 1025 v4l2_dbg(1, debug, sd, "%s: edid ready (retries: %d)\n",
1003 __func__, EDID_MAX_RETRIES - state->edid.read_retries); 1026 __func__, EDID_MAX_RETRIES - state->edid.read_retries);
1004 1027
1005 if (!(edidRdy & MASK_AD9389B_EDID_RDY)) 1028 if (!(edidRdy & MASK_AD9389B_EDID_RDY))
1006 return false; 1029 return false;
@@ -1013,16 +1036,16 @@ static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
1013 v4l2_dbg(1, debug, sd, "%s: got segment %d\n", __func__, segment); 1036 v4l2_dbg(1, debug, sd, "%s: got segment %d\n", __func__, segment);
1014 ad9389b_edid_rd(sd, 256, &state->edid.data[segment * 256]); 1037 ad9389b_edid_rd(sd, 256, &state->edid.data[segment * 256]);
1015 ad9389b_dbg_dump_edid(2, debug, sd, segment, 1038 ad9389b_dbg_dump_edid(2, debug, sd, segment,
1016 &state->edid.data[segment * 256]); 1039 &state->edid.data[segment * 256]);
1017 if (segment == 0) { 1040 if (segment == 0) {
1018 state->edid.blocks = state->edid.data[0x7e] + 1; 1041 state->edid.blocks = state->edid.data[0x7e] + 1;
1019 v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n", 1042 v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n",
1020 __func__, state->edid.blocks); 1043 __func__, state->edid.blocks);
1021 } 1044 }
1022 if (!edid_segment_verify_crc(sd, segment)) { 1045 if (!edid_verify_crc(sd, segment) ||
1046 !edid_verify_header(sd, segment)) {
1023 /* edid crc error, force reread of edid segment */ 1047 /* edid crc error, force reread of edid segment */
1024 v4l2_err(sd, "%s: edid crc error\n", __func__); 1048 v4l2_err(sd, "%s: edid crc or header error\n", __func__);
1025 state->have_monitor = false;
1026 ad9389b_s_power(sd, false); 1049 ad9389b_s_power(sd, false);
1027 ad9389b_s_power(sd, true); 1050 ad9389b_s_power(sd, true);
1028 return false; 1051 return false;
@@ -1032,12 +1055,12 @@ static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
1032 if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) { 1055 if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
1033 /* Request next EDID segment */ 1056 /* Request next EDID segment */
1034 v4l2_dbg(1, debug, sd, "%s: request segment %d\n", 1057 v4l2_dbg(1, debug, sd, "%s: request segment %d\n",
1035 __func__, state->edid.segments); 1058 __func__, state->edid.segments);
1036 ad9389b_wr(sd, 0xc9, 0xf); 1059 ad9389b_wr(sd, 0xc9, 0xf);
1037 ad9389b_wr(sd, 0xc4, state->edid.segments); 1060 ad9389b_wr(sd, 0xc4, state->edid.segments);
1038 state->edid.read_retries = EDID_MAX_RETRIES; 1061 state->edid.read_retries = EDID_MAX_RETRIES;
1039 queue_delayed_work(state->work_queue, 1062 queue_delayed_work(state->work_queue,
1040 &state->edid_handler, EDID_DELAY); 1063 &state->edid_handler, EDID_DELAY);
1041 return false; 1064 return false;
1042 } 1065 }
1043 1066
@@ -1081,7 +1104,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
1081 return -EIO; 1104 return -EIO;
1082 1105
1083 v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n", 1106 v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
1084 client->addr << 1); 1107 client->addr << 1);
1085 1108
1086 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL); 1109 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
1087 if (!state) 1110 if (!state)
@@ -1140,7 +1163,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
1140 goto err_entity; 1163 goto err_entity;
1141 } 1164 }
1142 v4l2_dbg(1, debug, sd, "reg 0x41 0x%x, chip version (reg 0x00) 0x%x\n", 1165 v4l2_dbg(1, debug, sd, "reg 0x41 0x%x, chip version (reg 0x00) 0x%x\n",
1143 ad9389b_rd(sd, 0x41), state->chip_revision); 1166 ad9389b_rd(sd, 0x41), state->chip_revision);
1144 1167
1145 state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1)); 1168 state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1));
1146 if (state->edid_i2c_client == NULL) { 1169 if (state->edid_i2c_client == NULL) {
@@ -1163,7 +1186,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
1163 ad9389b_set_isr(sd, true); 1186 ad9389b_set_isr(sd, true);
1164 1187
1165 v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, 1188 v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
1166 client->addr << 1, client->adapter->name); 1189 client->addr << 1, client->adapter->name);
1167 return 0; 1190 return 0;
1168 1191
1169err_unreg: 1192err_unreg:
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index 7c8d971f1f61..ee618942cb8e 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -452,6 +452,29 @@ static int adv7511_log_status(struct v4l2_subdev *sd)
452 errors[adv7511_rd(sd, 0xc8) >> 4], state->edid_detect_counter, 452 errors[adv7511_rd(sd, 0xc8) >> 4], state->edid_detect_counter,
453 adv7511_rd(sd, 0x94), adv7511_rd(sd, 0x96)); 453 adv7511_rd(sd, 0x94), adv7511_rd(sd, 0x96));
454 v4l2_info(sd, "RGB quantization: %s range\n", adv7511_rd(sd, 0x18) & 0x80 ? "limited" : "full"); 454 v4l2_info(sd, "RGB quantization: %s range\n", adv7511_rd(sd, 0x18) & 0x80 ? "limited" : "full");
455 if (adv7511_rd(sd, 0xaf) & 0x02) {
456 /* HDMI only */
457 u8 manual_cts = adv7511_rd(sd, 0x0a) & 0x80;
458 u32 N = (adv7511_rd(sd, 0x01) & 0xf) << 16 |
459 adv7511_rd(sd, 0x02) << 8 |
460 adv7511_rd(sd, 0x03);
461 u8 vic_detect = adv7511_rd(sd, 0x3e) >> 2;
462 u8 vic_sent = adv7511_rd(sd, 0x3d) & 0x3f;
463 u32 CTS;
464
465 if (manual_cts)
466 CTS = (adv7511_rd(sd, 0x07) & 0xf) << 16 |
467 adv7511_rd(sd, 0x08) << 8 |
468 adv7511_rd(sd, 0x09);
469 else
470 CTS = (adv7511_rd(sd, 0x04) & 0xf) << 16 |
471 adv7511_rd(sd, 0x05) << 8 |
472 adv7511_rd(sd, 0x06);
473 v4l2_info(sd, "CTS %s mode: N %d, CTS %d\n",
474 manual_cts ? "manual" : "automatic", N, CTS);
475 v4l2_info(sd, "VIC: detected %d, sent %d\n",
476 vic_detect, vic_sent);
477 }
455 if (state->dv_timings.type == V4L2_DV_BT_656_1120) 478 if (state->dv_timings.type == V4L2_DV_BT_656_1120)
456 v4l2_print_dv_timings(sd->name, "timings: ", 479 v4l2_print_dv_timings(sd->name, "timings: ",
457 &state->dv_timings, false); 480 &state->dv_timings, false);
@@ -942,26 +965,38 @@ static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd)
942 965
943static bool edid_block_verify_crc(uint8_t *edid_block) 966static bool edid_block_verify_crc(uint8_t *edid_block)
944{ 967{
945 int i;
946 uint8_t sum = 0; 968 uint8_t sum = 0;
969 int i;
947 970
948 for (i = 0; i < 128; i++) 971 for (i = 0; i < 128; i++)
949 sum += *(edid_block + i); 972 sum += edid_block[i];
950 return (sum == 0); 973 return sum == 0;
951} 974}
952 975
953static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment) 976static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment)
954{ 977{
955 struct adv7511_state *state = get_adv7511_state(sd); 978 struct adv7511_state *state = get_adv7511_state(sd);
956 u32 blocks = state->edid.blocks; 979 u32 blocks = state->edid.blocks;
957 uint8_t *data = state->edid.data; 980 uint8_t *data = state->edid.data;
958 981
959 if (edid_block_verify_crc(&data[segment * 256])) { 982 if (!edid_block_verify_crc(&data[segment * 256]))
960 if ((segment + 1) * 2 <= blocks) 983 return false;
961 return edid_block_verify_crc(&data[segment * 256 + 128]); 984 if ((segment + 1) * 2 <= blocks)
985 return edid_block_verify_crc(&data[segment * 256 + 128]);
986 return true;
987}
988
989static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment)
990{
991 static const u8 hdmi_header[] = {
992 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
993 };
994 struct adv7511_state *state = get_adv7511_state(sd);
995 u8 *data = state->edid.data;
996
997 if (segment != 0)
962 return true; 998 return true;
963 } 999 return !memcmp(data, hdmi_header, sizeof(hdmi_header));
964 return false;
965} 1000}
966 1001
967static bool adv7511_check_edid_status(struct v4l2_subdev *sd) 1002static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
@@ -990,9 +1025,10 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
990 state->edid.blocks = state->edid.data[0x7e] + 1; 1025 state->edid.blocks = state->edid.data[0x7e] + 1;
991 v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n", __func__, state->edid.blocks); 1026 v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n", __func__, state->edid.blocks);
992 } 1027 }
993 if (!edid_segment_verify_crc(sd, segment)) { 1028 if (!edid_verify_crc(sd, segment) ||
1029 !edid_verify_header(sd, segment)) {
994 /* edid crc error, force reread of edid segment */ 1030 /* edid crc error, force reread of edid segment */
995 v4l2_dbg(1, debug, sd, "%s: edid crc error\n", __func__); 1031 v4l2_err(sd, "%s: edid crc or header error\n", __func__);
996 state->have_monitor = false; 1032 state->have_monitor = false;
997 adv7511_s_power(sd, false); 1033 adv7511_s_power(sd, false);
998 adv7511_s_power(sd, true); 1034 adv7511_s_power(sd, true);
@@ -1038,6 +1074,12 @@ static void adv7511_init_setup(struct v4l2_subdev *sd)
1038 1074
1039 /* clear all interrupts */ 1075 /* clear all interrupts */
1040 adv7511_wr(sd, 0x96, 0xff); 1076 adv7511_wr(sd, 0x96, 0xff);
1077 /*
1078 * Stop HPD from resetting a lot of registers.
1079 * It might leave the chip in a partly un-initialized state,
1080 * in particular with regards to hotplug bounces.
1081 */
1082 adv7511_wr_and_or(sd, 0xd6, 0x3f, 0xc0);
1041 memset(edid, 0, sizeof(struct adv7511_state_edid)); 1083 memset(edid, 0, sizeof(struct adv7511_state_edid));
1042 state->have_monitor = false; 1084 state->have_monitor = false;
1043 adv7511_set_isr(sd, false); 1085 adv7511_set_isr(sd, false);
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index a324106b9f11..71c8570bd9ea 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -53,8 +53,6 @@ MODULE_LICENSE("GPL");
53/* ADV7604 system clock frequency */ 53/* ADV7604 system clock frequency */
54#define ADV7604_fsc (28636360) 54#define ADV7604_fsc (28636360)
55 55
56#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI)
57
58/* 56/*
59 ********************************************************************** 57 **********************************************************************
60 * 58 *
@@ -67,17 +65,19 @@ struct adv7604_state {
67 struct v4l2_subdev sd; 65 struct v4l2_subdev sd;
68 struct media_pad pad; 66 struct media_pad pad;
69 struct v4l2_ctrl_handler hdl; 67 struct v4l2_ctrl_handler hdl;
70 enum adv7604_mode mode; 68 enum adv7604_input_port selected_input;
71 struct v4l2_dv_timings timings; 69 struct v4l2_dv_timings timings;
72 u8 edid[256]; 70 struct {
73 unsigned edid_blocks; 71 u8 edid[256];
72 u32 present;
73 unsigned blocks;
74 } edid;
75 u16 spa_port_a[2];
74 struct v4l2_fract aspect_ratio; 76 struct v4l2_fract aspect_ratio;
75 u32 rgb_quantization_range; 77 u32 rgb_quantization_range;
76 struct workqueue_struct *work_queues; 78 struct workqueue_struct *work_queues;
77 struct delayed_work delayed_work_enable_hotplug; 79 struct delayed_work delayed_work_enable_hotplug;
78 bool connector_hdmi;
79 bool restart_stdi_once; 80 bool restart_stdi_once;
80 u32 prev_input_status;
81 81
82 /* i2c clients */ 82 /* i2c clients */
83 struct i2c_client *i2c_avlink; 83 struct i2c_client *i2c_avlink;
@@ -160,6 +160,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
160 V4L2_DV_BT_DMT_1792X1344P60, 160 V4L2_DV_BT_DMT_1792X1344P60,
161 V4L2_DV_BT_DMT_1856X1392P60, 161 V4L2_DV_BT_DMT_1856X1392P60,
162 V4L2_DV_BT_DMT_1920X1200P60_RB, 162 V4L2_DV_BT_DMT_1920X1200P60_RB,
163 V4L2_DV_BT_DMT_1366X768P60_RB,
163 V4L2_DV_BT_DMT_1366X768P60, 164 V4L2_DV_BT_DMT_1366X768P60,
164 V4L2_DV_BT_DMT_1920X1080P60, 165 V4L2_DV_BT_DMT_1920X1080P60,
165 { }, 166 { },
@@ -507,57 +508,31 @@ static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val)
507 return 0; 508 return 0;
508} 509}
509 510
510static void adv7604_delayed_work_enable_hotplug(struct work_struct *work)
511{
512 struct delayed_work *dwork = to_delayed_work(work);
513 struct adv7604_state *state = container_of(dwork, struct adv7604_state,
514 delayed_work_enable_hotplug);
515 struct v4l2_subdev *sd = &state->sd;
516
517 v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__);
518
519 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)1);
520}
521
522static inline int edid_write_block(struct v4l2_subdev *sd, 511static inline int edid_write_block(struct v4l2_subdev *sd,
523 unsigned len, const u8 *val) 512 unsigned len, const u8 *val)
524{ 513{
525 struct i2c_client *client = v4l2_get_subdevdata(sd);
526 struct adv7604_state *state = to_state(sd); 514 struct adv7604_state *state = to_state(sd);
527 int err = 0; 515 int err = 0;
528 int i; 516 int i;
529 517
530 v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len); 518 v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len);
531 519
532 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)0);
533
534 /* Disables I2C access to internal EDID ram from DDC port */
535 rep_write_and_or(sd, 0x77, 0xf0, 0x0);
536
537 for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) 520 for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX)
538 err = adv_smbus_write_i2c_block_data(state->i2c_edid, i, 521 err = adv_smbus_write_i2c_block_data(state->i2c_edid, i,
539 I2C_SMBUS_BLOCK_MAX, val + i); 522 I2C_SMBUS_BLOCK_MAX, val + i);
540 if (err) 523 return err;
541 return err; 524}
542 525
543 /* adv7604 calculates the checksums and enables I2C access to internal 526static void adv7604_delayed_work_enable_hotplug(struct work_struct *work)
544 EDID ram from DDC port. */ 527{
545 rep_write_and_or(sd, 0x77, 0xf0, 0x1); 528 struct delayed_work *dwork = to_delayed_work(work);
529 struct adv7604_state *state = container_of(dwork, struct adv7604_state,
530 delayed_work_enable_hotplug);
531 struct v4l2_subdev *sd = &state->sd;
546 532
547 for (i = 0; i < 1000; i++) { 533 v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__);
548 if (rep_read(sd, 0x7d) & 1)
549 break;
550 mdelay(1);
551 }
552 if (i == 1000) {
553 v4l_err(client, "error enabling edid\n");
554 return -EIO;
555 }
556 534
557 /* enable hotplug after 100 ms */ 535 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)&state->edid.present);
558 queue_delayed_work(state->work_queues,
559 &state->delayed_work_enable_hotplug, HZ / 10);
560 return 0;
561} 536}
562 537
563static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg) 538static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg)
@@ -574,6 +549,11 @@ static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
574 return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val); 549 return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val);
575} 550}
576 551
552static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
553{
554 return hdmi_write(sd, reg, (hdmi_read(sd, reg) & mask) | val);
555}
556
577static inline int test_read(struct v4l2_subdev *sd, u8 reg) 557static inline int test_read(struct v4l2_subdev *sd, u8 reg)
578{ 558{
579 struct adv7604_state *state = to_state(sd); 559 struct adv7604_state *state = to_state(sd);
@@ -623,6 +603,26 @@ static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
623 603
624/* ----------------------------------------------------------------------- */ 604/* ----------------------------------------------------------------------- */
625 605
606static inline bool is_analog_input(struct v4l2_subdev *sd)
607{
608 struct adv7604_state *state = to_state(sd);
609
610 return state->selected_input == ADV7604_INPUT_VGA_RGB ||
611 state->selected_input == ADV7604_INPUT_VGA_COMP;
612}
613
614static inline bool is_digital_input(struct v4l2_subdev *sd)
615{
616 struct adv7604_state *state = to_state(sd);
617
618 return state->selected_input == ADV7604_INPUT_HDMI_PORT_A ||
619 state->selected_input == ADV7604_INPUT_HDMI_PORT_B ||
620 state->selected_input == ADV7604_INPUT_HDMI_PORT_C ||
621 state->selected_input == ADV7604_INPUT_HDMI_PORT_D;
622}
623
624/* ----------------------------------------------------------------------- */
625
626#ifdef CONFIG_VIDEO_ADV_DEBUG 626#ifdef CONFIG_VIDEO_ADV_DEBUG
627static void adv7604_inv_register(struct v4l2_subdev *sd) 627static void adv7604_inv_register(struct v4l2_subdev *sd)
628{ 628{
@@ -696,45 +696,47 @@ static int adv7604_g_register(struct v4l2_subdev *sd,
696static int adv7604_s_register(struct v4l2_subdev *sd, 696static int adv7604_s_register(struct v4l2_subdev *sd,
697 const struct v4l2_dbg_register *reg) 697 const struct v4l2_dbg_register *reg)
698{ 698{
699 u8 val = reg->val & 0xff;
700
699 switch (reg->reg >> 8) { 701 switch (reg->reg >> 8) {
700 case 0: 702 case 0:
701 io_write(sd, reg->reg & 0xff, reg->val & 0xff); 703 io_write(sd, reg->reg & 0xff, val);
702 break; 704 break;
703 case 1: 705 case 1:
704 avlink_write(sd, reg->reg & 0xff, reg->val & 0xff); 706 avlink_write(sd, reg->reg & 0xff, val);
705 break; 707 break;
706 case 2: 708 case 2:
707 cec_write(sd, reg->reg & 0xff, reg->val & 0xff); 709 cec_write(sd, reg->reg & 0xff, val);
708 break; 710 break;
709 case 3: 711 case 3:
710 infoframe_write(sd, reg->reg & 0xff, reg->val & 0xff); 712 infoframe_write(sd, reg->reg & 0xff, val);
711 break; 713 break;
712 case 4: 714 case 4:
713 esdp_write(sd, reg->reg & 0xff, reg->val & 0xff); 715 esdp_write(sd, reg->reg & 0xff, val);
714 break; 716 break;
715 case 5: 717 case 5:
716 dpp_write(sd, reg->reg & 0xff, reg->val & 0xff); 718 dpp_write(sd, reg->reg & 0xff, val);
717 break; 719 break;
718 case 6: 720 case 6:
719 afe_write(sd, reg->reg & 0xff, reg->val & 0xff); 721 afe_write(sd, reg->reg & 0xff, val);
720 break; 722 break;
721 case 7: 723 case 7:
722 rep_write(sd, reg->reg & 0xff, reg->val & 0xff); 724 rep_write(sd, reg->reg & 0xff, val);
723 break; 725 break;
724 case 8: 726 case 8:
725 edid_write(sd, reg->reg & 0xff, reg->val & 0xff); 727 edid_write(sd, reg->reg & 0xff, val);
726 break; 728 break;
727 case 9: 729 case 9:
728 hdmi_write(sd, reg->reg & 0xff, reg->val & 0xff); 730 hdmi_write(sd, reg->reg & 0xff, val);
729 break; 731 break;
730 case 0xa: 732 case 0xa:
731 test_write(sd, reg->reg & 0xff, reg->val & 0xff); 733 test_write(sd, reg->reg & 0xff, val);
732 break; 734 break;
733 case 0xb: 735 case 0xb:
734 cp_write(sd, reg->reg & 0xff, reg->val & 0xff); 736 cp_write(sd, reg->reg & 0xff, val);
735 break; 737 break;
736 case 0xc: 738 case 0xc:
737 vdp_write(sd, reg->reg & 0xff, reg->val & 0xff); 739 vdp_write(sd, reg->reg & 0xff, val);
738 break; 740 break;
739 default: 741 default:
740 v4l2_info(sd, "Register %03llx not supported\n", reg->reg); 742 v4l2_info(sd, "Register %03llx not supported\n", reg->reg);
@@ -748,10 +750,13 @@ static int adv7604_s_register(struct v4l2_subdev *sd,
748static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) 750static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
749{ 751{
750 struct adv7604_state *state = to_state(sd); 752 struct adv7604_state *state = to_state(sd);
753 u8 reg_io_6f = io_read(sd, 0x6f);
751 754
752 /* port A only */
753 return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, 755 return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl,
754 ((io_read(sd, 0x6f) & 0x10) >> 4)); 756 ((reg_io_6f & 0x10) >> 4) |
757 ((reg_io_6f & 0x08) >> 2) |
758 (reg_io_6f & 0x04) |
759 ((reg_io_6f & 0x02) << 2));
755} 760}
756 761
757static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, 762static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
@@ -759,12 +764,11 @@ static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
759 const struct adv7604_video_standards *predef_vid_timings, 764 const struct adv7604_video_standards *predef_vid_timings,
760 const struct v4l2_dv_timings *timings) 765 const struct v4l2_dv_timings *timings)
761{ 766{
762 struct adv7604_state *state = to_state(sd);
763 int i; 767 int i;
764 768
765 for (i = 0; predef_vid_timings[i].timings.bt.width; i++) { 769 for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
766 if (!v4l2_match_dv_timings(timings, &predef_vid_timings[i].timings, 770 if (!v4l2_match_dv_timings(timings, &predef_vid_timings[i].timings,
767 DIGITAL_INPUT ? 250000 : 1000000)) 771 is_digital_input(sd) ? 250000 : 1000000))
768 continue; 772 continue;
769 io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */ 773 io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
770 io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) + 774 io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) +
@@ -799,27 +803,22 @@ static int configure_predefined_video_timings(struct v4l2_subdev *sd,
799 cp_write(sd, 0xab, 0x00); 803 cp_write(sd, 0xab, 0x00);
800 cp_write(sd, 0xac, 0x00); 804 cp_write(sd, 0xac, 0x00);
801 805
802 switch (state->mode) { 806 if (is_analog_input(sd)) {
803 case ADV7604_MODE_COMP:
804 case ADV7604_MODE_GR:
805 err = find_and_set_predefined_video_timings(sd, 807 err = find_and_set_predefined_video_timings(sd,
806 0x01, adv7604_prim_mode_comp, timings); 808 0x01, adv7604_prim_mode_comp, timings);
807 if (err) 809 if (err)
808 err = find_and_set_predefined_video_timings(sd, 810 err = find_and_set_predefined_video_timings(sd,
809 0x02, adv7604_prim_mode_gr, timings); 811 0x02, adv7604_prim_mode_gr, timings);
810 break; 812 } else if (is_digital_input(sd)) {
811 case ADV7604_MODE_HDMI:
812 err = find_and_set_predefined_video_timings(sd, 813 err = find_and_set_predefined_video_timings(sd,
813 0x05, adv7604_prim_mode_hdmi_comp, timings); 814 0x05, adv7604_prim_mode_hdmi_comp, timings);
814 if (err) 815 if (err)
815 err = find_and_set_predefined_video_timings(sd, 816 err = find_and_set_predefined_video_timings(sd,
816 0x06, adv7604_prim_mode_hdmi_gr, timings); 817 0x06, adv7604_prim_mode_hdmi_gr, timings);
817 break; 818 } else {
818 default: 819 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n",
819 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", 820 __func__, state->selected_input);
820 __func__, state->mode);
821 err = -1; 821 err = -1;
822 break;
823 } 822 }
824 823
825 824
@@ -846,9 +845,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
846 845
847 v4l2_dbg(2, debug, sd, "%s\n", __func__); 846 v4l2_dbg(2, debug, sd, "%s\n", __func__);
848 847
849 switch (state->mode) { 848 if (is_analog_input(sd)) {
850 case ADV7604_MODE_COMP:
851 case ADV7604_MODE_GR:
852 /* auto graphics */ 849 /* auto graphics */
853 io_write(sd, 0x00, 0x07); /* video std */ 850 io_write(sd, 0x00, 0x07); /* video std */
854 io_write(sd, 0x01, 0x02); /* prim mode */ 851 io_write(sd, 0x01, 0x02); /* prim mode */
@@ -858,33 +855,28 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
858 /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ 855 /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
859 /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ 856 /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
860 /* IO-map reg. 0x16 and 0x17 should be written in sequence */ 857 /* IO-map reg. 0x16 and 0x17 should be written in sequence */
861 if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { 858 if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll))
862 v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); 859 v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
863 break;
864 }
865 860
866 /* active video - horizontal timing */ 861 /* active video - horizontal timing */
867 cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff); 862 cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff);
868 cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | 863 cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) |
869 ((cp_start_eav >> 8) & 0x0f)); 864 ((cp_start_eav >> 8) & 0x0f));
870 cp_write(sd, 0xa4, cp_start_eav & 0xff); 865 cp_write(sd, 0xa4, cp_start_eav & 0xff);
871 866
872 /* active video - vertical timing */ 867 /* active video - vertical timing */
873 cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff); 868 cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
874 cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | 869 cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) |
875 ((cp_end_vbi >> 8) & 0xf)); 870 ((cp_end_vbi >> 8) & 0xf));
876 cp_write(sd, 0xa7, cp_end_vbi & 0xff); 871 cp_write(sd, 0xa7, cp_end_vbi & 0xff);
877 break; 872 } else if (is_digital_input(sd)) {
878 case ADV7604_MODE_HDMI:
879 /* set default prim_mode/vid_std for HDMI 873 /* set default prim_mode/vid_std for HDMI
880 according to [REF_03, c. 4.2] */ 874 according to [REF_03, c. 4.2] */
881 io_write(sd, 0x00, 0x02); /* video std */ 875 io_write(sd, 0x00, 0x02); /* video std */
882 io_write(sd, 0x01, 0x06); /* prim mode */ 876 io_write(sd, 0x01, 0x06); /* prim mode */
883 break; 877 } else {
884 default: 878 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n",
885 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", 879 __func__, state->selected_input);
886 __func__, state->mode);
887 break;
888 } 880 }
889 881
890 cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); 882 cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);
@@ -893,43 +885,149 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
893 cp_write(sd, 0xac, (height & 0x0f) << 4); 885 cp_write(sd, 0xac, (height & 0x0f) << 4);
894} 886}
895 887
888static void adv7604_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 offset_a, u16 offset_b, u16 offset_c)
889{
890 struct adv7604_state *state = to_state(sd);
891 u8 offset_buf[4];
892
893 if (auto_offset) {
894 offset_a = 0x3ff;
895 offset_b = 0x3ff;
896 offset_c = 0x3ff;
897 }
898
899 v4l2_dbg(2, debug, sd, "%s: %s offset: a = 0x%x, b = 0x%x, c = 0x%x\n",
900 __func__, auto_offset ? "Auto" : "Manual",
901 offset_a, offset_b, offset_c);
902
903 offset_buf[0] = (cp_read(sd, 0x77) & 0xc0) | ((offset_a & 0x3f0) >> 4);
904 offset_buf[1] = ((offset_a & 0x00f) << 4) | ((offset_b & 0x3c0) >> 6);
905 offset_buf[2] = ((offset_b & 0x03f) << 2) | ((offset_c & 0x300) >> 8);
906 offset_buf[3] = offset_c & 0x0ff;
907
908 /* Registers must be written in this order with no i2c access in between */
909 if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf))
910 v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__);
911}
912
913static void adv7604_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, u16 gain_b, u16 gain_c)
914{
915 struct adv7604_state *state = to_state(sd);
916 u8 gain_buf[4];
917 u8 gain_man = 1;
918 u8 agc_mode_man = 1;
919
920 if (auto_gain) {
921 gain_man = 0;
922 agc_mode_man = 0;
923 gain_a = 0x100;
924 gain_b = 0x100;
925 gain_c = 0x100;
926 }
927
928 v4l2_dbg(2, debug, sd, "%s: %s gain: a = 0x%x, b = 0x%x, c = 0x%x\n",
929 __func__, auto_gain ? "Auto" : "Manual",
930 gain_a, gain_b, gain_c);
931
932 gain_buf[0] = ((gain_man << 7) | (agc_mode_man << 6) | ((gain_a & 0x3f0) >> 4));
933 gain_buf[1] = (((gain_a & 0x00f) << 4) | ((gain_b & 0x3c0) >> 6));
934 gain_buf[2] = (((gain_b & 0x03f) << 2) | ((gain_c & 0x300) >> 8));
935 gain_buf[3] = ((gain_c & 0x0ff));
936
937 /* Registers must be written in this order with no i2c access in between */
938 if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf))
939 v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__);
940}
941
896static void set_rgb_quantization_range(struct v4l2_subdev *sd) 942static void set_rgb_quantization_range(struct v4l2_subdev *sd)
897{ 943{
898 struct adv7604_state *state = to_state(sd); 944 struct adv7604_state *state = to_state(sd);
945 bool rgb_output = io_read(sd, 0x02) & 0x02;
946 bool hdmi_signal = hdmi_read(sd, 0x05) & 0x80;
947
948 v4l2_dbg(2, debug, sd, "%s: RGB quantization range: %d, RGB out: %d, HDMI: %d\n",
949 __func__, state->rgb_quantization_range,
950 rgb_output, hdmi_signal);
951
952 adv7604_set_gain(sd, true, 0x0, 0x0, 0x0);
953 adv7604_set_offset(sd, true, 0x0, 0x0, 0x0);
899 954
900 switch (state->rgb_quantization_range) { 955 switch (state->rgb_quantization_range) {
901 case V4L2_DV_RGB_RANGE_AUTO: 956 case V4L2_DV_RGB_RANGE_AUTO:
902 /* automatic */ 957 if (state->selected_input == ADV7604_INPUT_VGA_RGB) {
903 if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) { 958 /* Receiving analog RGB signal
904 /* receiving DVI-D signal */ 959 * Set RGB full range (0-255) */
960 io_write_and_or(sd, 0x02, 0x0f, 0x10);
961 break;
962 }
963
964 if (state->selected_input == ADV7604_INPUT_VGA_COMP) {
965 /* Receiving analog YPbPr signal
966 * Set automode */
967 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
968 break;
969 }
970
971 if (hdmi_signal) {
972 /* Receiving HDMI signal
973 * Set automode */
974 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
975 break;
976 }
905 977
906 /* ADV7604 selects RGB limited range regardless of 978 /* Receiving DVI-D signal
907 input format (CE/IT) in automatic mode */ 979 * ADV7604 selects RGB limited range regardless of
908 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { 980 * input format (CE/IT) in automatic mode */
909 /* RGB limited range (16-235) */ 981 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
910 io_write_and_or(sd, 0x02, 0x0f, 0x00); 982 /* RGB limited range (16-235) */
983 io_write_and_or(sd, 0x02, 0x0f, 0x00);
984 } else {
985 /* RGB full range (0-255) */
986 io_write_and_or(sd, 0x02, 0x0f, 0x10);
911 987
988 if (is_digital_input(sd) && rgb_output) {
989 adv7604_set_offset(sd, false, 0x40, 0x40, 0x40);
912 } else { 990 } else {
913 /* RGB full range (0-255) */ 991 adv7604_set_gain(sd, false, 0xe0, 0xe0, 0xe0);
914 io_write_and_or(sd, 0x02, 0x0f, 0x10); 992 adv7604_set_offset(sd, false, 0x70, 0x70, 0x70);
915 } 993 }
916 } else {
917 /* receiving HDMI or analog signal, set automode */
918 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
919 } 994 }
920 break; 995 break;
921 case V4L2_DV_RGB_RANGE_LIMITED: 996 case V4L2_DV_RGB_RANGE_LIMITED:
997 if (state->selected_input == ADV7604_INPUT_VGA_COMP) {
998 /* YCrCb limited range (16-235) */
999 io_write_and_or(sd, 0x02, 0x0f, 0x20);
1000 break;
1001 }
1002
922 /* RGB limited range (16-235) */ 1003 /* RGB limited range (16-235) */
923 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1004 io_write_and_or(sd, 0x02, 0x0f, 0x00);
1005
924 break; 1006 break;
925 case V4L2_DV_RGB_RANGE_FULL: 1007 case V4L2_DV_RGB_RANGE_FULL:
1008 if (state->selected_input == ADV7604_INPUT_VGA_COMP) {
1009 /* YCrCb full range (0-255) */
1010 io_write_and_or(sd, 0x02, 0x0f, 0x60);
1011 break;
1012 }
1013
926 /* RGB full range (0-255) */ 1014 /* RGB full range (0-255) */
927 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1015 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1016
1017 if (is_analog_input(sd) || hdmi_signal)
1018 break;
1019
1020 /* Adjust gain/offset for DVI-D signals only */
1021 if (rgb_output) {
1022 adv7604_set_offset(sd, false, 0x40, 0x40, 0x40);
1023 } else {
1024 adv7604_set_gain(sd, false, 0xe0, 0xe0, 0xe0);
1025 adv7604_set_offset(sd, false, 0x70, 0x70, 0x70);
1026 }
928 break; 1027 break;
929 } 1028 }
930} 1029}
931 1030
932
933static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl) 1031static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl)
934{ 1032{
935 struct v4l2_subdev *sd = to_sd(ctrl); 1033 struct v4l2_subdev *sd = to_sd(ctrl);
@@ -983,8 +1081,9 @@ static inline bool no_power(struct v4l2_subdev *sd)
983 1081
984static inline bool no_signal_tmds(struct v4l2_subdev *sd) 1082static inline bool no_signal_tmds(struct v4l2_subdev *sd)
985{ 1083{
986 /* TODO port B, C and D */ 1084 struct adv7604_state *state = to_state(sd);
987 return !(io_read(sd, 0x6a) & 0x10); 1085
1086 return !(io_read(sd, 0x6a) & (0x10 >> state->selected_input));
988} 1087}
989 1088
990static inline bool no_lock_tmds(struct v4l2_subdev *sd) 1089static inline bool no_lock_tmds(struct v4l2_subdev *sd)
@@ -1011,7 +1110,6 @@ static inline bool no_lock_stdi(struct v4l2_subdev *sd)
1011 1110
1012static inline bool no_signal(struct v4l2_subdev *sd) 1111static inline bool no_signal(struct v4l2_subdev *sd)
1013{ 1112{
1014 struct adv7604_state *state = to_state(sd);
1015 bool ret; 1113 bool ret;
1016 1114
1017 ret = no_power(sd); 1115 ret = no_power(sd);
@@ -1019,7 +1117,7 @@ static inline bool no_signal(struct v4l2_subdev *sd)
1019 ret |= no_lock_stdi(sd); 1117 ret |= no_lock_stdi(sd);
1020 ret |= no_lock_sspd(sd); 1118 ret |= no_lock_sspd(sd);
1021 1119
1022 if (DIGITAL_INPUT) { 1120 if (is_digital_input(sd)) {
1023 ret |= no_lock_tmds(sd); 1121 ret |= no_lock_tmds(sd);
1024 ret |= no_signal_tmds(sd); 1122 ret |= no_signal_tmds(sd);
1025 } 1123 }
@@ -1036,13 +1134,11 @@ static inline bool no_lock_cp(struct v4l2_subdev *sd)
1036 1134
1037static int adv7604_g_input_status(struct v4l2_subdev *sd, u32 *status) 1135static int adv7604_g_input_status(struct v4l2_subdev *sd, u32 *status)
1038{ 1136{
1039 struct adv7604_state *state = to_state(sd);
1040
1041 *status = 0; 1137 *status = 0;
1042 *status |= no_power(sd) ? V4L2_IN_ST_NO_POWER : 0; 1138 *status |= no_power(sd) ? V4L2_IN_ST_NO_POWER : 0;
1043 *status |= no_signal(sd) ? V4L2_IN_ST_NO_SIGNAL : 0; 1139 *status |= no_signal(sd) ? V4L2_IN_ST_NO_SIGNAL : 0;
1044 if (no_lock_cp(sd)) 1140 if (no_lock_cp(sd))
1045 *status |= DIGITAL_INPUT ? V4L2_IN_ST_NO_SYNC : V4L2_IN_ST_NO_H_LOCK; 1141 *status |= is_digital_input(sd) ? V4L2_IN_ST_NO_SYNC : V4L2_IN_ST_NO_H_LOCK;
1046 1142
1047 v4l2_dbg(1, debug, sd, "%s: status = 0x%x\n", __func__, *status); 1143 v4l2_dbg(1, debug, sd, "%s: status = 0x%x\n", __func__, *status);
1048 1144
@@ -1157,13 +1253,11 @@ static int adv7604_enum_dv_timings(struct v4l2_subdev *sd,
1157static int adv7604_dv_timings_cap(struct v4l2_subdev *sd, 1253static int adv7604_dv_timings_cap(struct v4l2_subdev *sd,
1158 struct v4l2_dv_timings_cap *cap) 1254 struct v4l2_dv_timings_cap *cap)
1159{ 1255{
1160 struct adv7604_state *state = to_state(sd);
1161
1162 cap->type = V4L2_DV_BT_656_1120; 1256 cap->type = V4L2_DV_BT_656_1120;
1163 cap->bt.max_width = 1920; 1257 cap->bt.max_width = 1920;
1164 cap->bt.max_height = 1200; 1258 cap->bt.max_height = 1200;
1165 cap->bt.min_pixelclock = 25000000; 1259 cap->bt.min_pixelclock = 25000000;
1166 if (DIGITAL_INPUT) 1260 if (is_digital_input(sd))
1167 cap->bt.max_pixelclock = 225000000; 1261 cap->bt.max_pixelclock = 225000000;
1168 else 1262 else
1169 cap->bt.max_pixelclock = 170000000; 1263 cap->bt.max_pixelclock = 170000000;
@@ -1179,12 +1273,11 @@ static int adv7604_dv_timings_cap(struct v4l2_subdev *sd,
1179static void adv7604_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, 1273static void adv7604_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
1180 struct v4l2_dv_timings *timings) 1274 struct v4l2_dv_timings *timings)
1181{ 1275{
1182 struct adv7604_state *state = to_state(sd);
1183 int i; 1276 int i;
1184 1277
1185 for (i = 0; adv7604_timings[i].bt.width; i++) { 1278 for (i = 0; adv7604_timings[i].bt.width; i++) {
1186 if (v4l2_match_dv_timings(timings, &adv7604_timings[i], 1279 if (v4l2_match_dv_timings(timings, &adv7604_timings[i],
1187 DIGITAL_INPUT ? 250000 : 1000000)) { 1280 is_digital_input(sd) ? 250000 : 1000000)) {
1188 *timings = adv7604_timings[i]; 1281 *timings = adv7604_timings[i];
1189 break; 1282 break;
1190 } 1283 }
@@ -1204,6 +1297,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1204 memset(timings, 0, sizeof(struct v4l2_dv_timings)); 1297 memset(timings, 0, sizeof(struct v4l2_dv_timings));
1205 1298
1206 if (no_signal(sd)) { 1299 if (no_signal(sd)) {
1300 state->restart_stdi_once = true;
1207 v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__); 1301 v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__);
1208 return -ENOLINK; 1302 return -ENOLINK;
1209 } 1303 }
@@ -1216,7 +1310,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1216 bt->interlaced = stdi.interlaced ? 1310 bt->interlaced = stdi.interlaced ?
1217 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; 1311 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
1218 1312
1219 if (DIGITAL_INPUT) { 1313 if (is_digital_input(sd)) {
1220 uint32_t freq; 1314 uint32_t freq;
1221 1315
1222 timings->type = V4L2_DV_BT_656_1120; 1316 timings->type = V4L2_DV_BT_656_1120;
@@ -1305,8 +1399,8 @@ found:
1305 return -ENOLINK; 1399 return -ENOLINK;
1306 } 1400 }
1307 1401
1308 if ((!DIGITAL_INPUT && bt->pixelclock > 170000000) || 1402 if ((is_analog_input(sd) && bt->pixelclock > 170000000) ||
1309 (DIGITAL_INPUT && bt->pixelclock > 225000000)) { 1403 (is_digital_input(sd) && bt->pixelclock > 225000000)) {
1310 v4l2_dbg(1, debug, sd, "%s: pixelclock out of range %d\n", 1404 v4l2_dbg(1, debug, sd, "%s: pixelclock out of range %d\n",
1311 __func__, (u32)bt->pixelclock); 1405 __func__, (u32)bt->pixelclock);
1312 return -ERANGE; 1406 return -ERANGE;
@@ -1329,10 +1423,15 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
1329 if (!timings) 1423 if (!timings)
1330 return -EINVAL; 1424 return -EINVAL;
1331 1425
1426 if (v4l2_match_dv_timings(&state->timings, timings, 0)) {
1427 v4l2_dbg(1, debug, sd, "%s: no change\n", __func__);
1428 return 0;
1429 }
1430
1332 bt = &timings->bt; 1431 bt = &timings->bt;
1333 1432
1334 if ((!DIGITAL_INPUT && bt->pixelclock > 170000000) || 1433 if ((is_analog_input(sd) && bt->pixelclock > 170000000) ||
1335 (DIGITAL_INPUT && bt->pixelclock > 225000000)) { 1434 (is_digital_input(sd) && bt->pixelclock > 225000000)) {
1336 v4l2_dbg(1, debug, sd, "%s: pixelclock out of range %d\n", 1435 v4l2_dbg(1, debug, sd, "%s: pixelclock out of range %d\n",
1337 __func__, (u32)bt->pixelclock); 1436 __func__, (u32)bt->pixelclock);
1338 return -ERANGE; 1437 return -ERANGE;
@@ -1354,7 +1453,6 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
1354 1453
1355 set_rgb_quantization_range(sd); 1454 set_rgb_quantization_range(sd);
1356 1455
1357
1358 if (debug > 1) 1456 if (debug > 1)
1359 v4l2_print_dv_timings(sd->name, "adv7604_s_dv_timings: ", 1457 v4l2_print_dv_timings(sd->name, "adv7604_s_dv_timings: ",
1360 timings, true); 1458 timings, true);
@@ -1374,30 +1472,24 @@ static void enable_input(struct v4l2_subdev *sd)
1374{ 1472{
1375 struct adv7604_state *state = to_state(sd); 1473 struct adv7604_state *state = to_state(sd);
1376 1474
1377 switch (state->mode) { 1475 if (is_analog_input(sd)) {
1378 case ADV7604_MODE_COMP:
1379 case ADV7604_MODE_GR:
1380 /* enable */
1381 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ 1476 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
1382 break; 1477 } else if (is_digital_input(sd)) {
1383 case ADV7604_MODE_HDMI: 1478 hdmi_write_and_or(sd, 0x00, 0xfc, state->selected_input);
1384 /* enable */
1385 hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
1386 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ 1479 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
1387 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ 1480 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
1388 break; 1481 hdmi_write_and_or(sd, 0x1a, 0xef, 0x00); /* Unmute audio */
1389 default: 1482 } else {
1390 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", 1483 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n",
1391 __func__, state->mode); 1484 __func__, state->selected_input);
1392 break;
1393 } 1485 }
1394} 1486}
1395 1487
1396static void disable_input(struct v4l2_subdev *sd) 1488static void disable_input(struct v4l2_subdev *sd)
1397{ 1489{
1398 /* disable */ 1490 hdmi_write_and_or(sd, 0x1a, 0xef, 0x10); /* Mute audio */
1491 msleep(16); /* 512 samples with >= 32 kHz sample rate [REF_03, c. 7.16.10] */
1399 io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */ 1492 io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */
1400 hdmi_write(sd, 0x1a, 0x1a); /* Mute audio */
1401 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ 1493 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
1402} 1494}
1403 1495
@@ -1405,9 +1497,7 @@ static void select_input(struct v4l2_subdev *sd)
1405{ 1497{
1406 struct adv7604_state *state = to_state(sd); 1498 struct adv7604_state *state = to_state(sd);
1407 1499
1408 switch (state->mode) { 1500 if (is_analog_input(sd)) {
1409 case ADV7604_MODE_COMP:
1410 case ADV7604_MODE_GR:
1411 /* reset ADI recommended settings for HDMI: */ 1501 /* reset ADI recommended settings for HDMI: */
1412 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ 1502 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
1413 hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */ 1503 hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
@@ -1433,9 +1523,9 @@ static void select_input(struct v4l2_subdev *sd)
1433 cp_write(sd, 0x3e, 0x04); /* CP core pre-gain control */ 1523 cp_write(sd, 0x3e, 0x04); /* CP core pre-gain control */
1434 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */ 1524 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */
1435 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ 1525 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
1436 break; 1526 } else if (is_digital_input(sd)) {
1527 hdmi_write(sd, 0x00, state->selected_input & 0x03);
1437 1528
1438 case ADV7604_MODE_HDMI:
1439 /* set ADI recommended settings for HDMI: */ 1529 /* set ADI recommended settings for HDMI: */
1440 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ 1530 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
1441 hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ 1531 hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */
@@ -1461,12 +1551,9 @@ static void select_input(struct v4l2_subdev *sd)
1461 cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */ 1551 cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */
1462 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */ 1552 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */
1463 cp_write(sd, 0x40, 0x80); /* CP core pre-gain control. Graphics mode */ 1553 cp_write(sd, 0x40, 0x80); /* CP core pre-gain control. Graphics mode */
1464 1554 } else {
1465 break; 1555 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n",
1466 default: 1556 __func__, state->selected_input);
1467 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
1468 __func__, state->mode);
1469 break;
1470 } 1557 }
1471} 1558}
1472 1559
@@ -1475,9 +1562,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
1475{ 1562{
1476 struct adv7604_state *state = to_state(sd); 1563 struct adv7604_state *state = to_state(sd);
1477 1564
1478 v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); 1565 v4l2_dbg(2, debug, sd, "%s: input %d, selected input %d",
1566 __func__, input, state->selected_input);
1567
1568 if (input == state->selected_input)
1569 return 0;
1479 1570
1480 state->mode = input; 1571 state->selected_input = input;
1481 1572
1482 disable_input(sd); 1573 disable_input(sd);
1483 1574
@@ -1516,36 +1607,47 @@ static int adv7604_g_mbus_fmt(struct v4l2_subdev *sd,
1516 1607
1517static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled) 1608static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1518{ 1609{
1519 struct adv7604_state *state = to_state(sd); 1610 const u8 irq_reg_0x43 = io_read(sd, 0x43);
1520 u8 fmt_change, fmt_change_digital, tx_5v; 1611 const u8 irq_reg_0x6b = io_read(sd, 0x6b);
1521 u32 input_status; 1612 const u8 irq_reg_0x70 = io_read(sd, 0x70);
1613 u8 fmt_change_digital;
1614 u8 fmt_change;
1615 u8 tx_5v;
1616
1617 if (irq_reg_0x43)
1618 io_write(sd, 0x44, irq_reg_0x43);
1619 if (irq_reg_0x70)
1620 io_write(sd, 0x71, irq_reg_0x70);
1621 if (irq_reg_0x6b)
1622 io_write(sd, 0x6c, irq_reg_0x6b);
1623
1624 v4l2_dbg(2, debug, sd, "%s: ", __func__);
1522 1625
1523 /* format change */ 1626 /* format change */
1524 fmt_change = io_read(sd, 0x43) & 0x98; 1627 fmt_change = irq_reg_0x43 & 0x98;
1525 if (fmt_change) 1628 fmt_change_digital = is_digital_input(sd) ? (irq_reg_0x6b & 0xc0) : 0;
1526 io_write(sd, 0x44, fmt_change); 1629
1527 fmt_change_digital = DIGITAL_INPUT ? (io_read(sd, 0x6b) & 0xc0) : 0;
1528 if (fmt_change_digital)
1529 io_write(sd, 0x6c, fmt_change_digital);
1530 if (fmt_change || fmt_change_digital) { 1630 if (fmt_change || fmt_change_digital) {
1531 v4l2_dbg(1, debug, sd, 1631 v4l2_dbg(1, debug, sd,
1532 "%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n", 1632 "%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n",
1533 __func__, fmt_change, fmt_change_digital); 1633 __func__, fmt_change, fmt_change_digital);
1534 1634
1535 adv7604_g_input_status(sd, &input_status); 1635 v4l2_subdev_notify(sd, ADV7604_FMT_CHANGE, NULL);
1536 if (input_status != state->prev_input_status) {
1537 v4l2_dbg(1, debug, sd,
1538 "%s: input_status = 0x%x, prev_input_status = 0x%x\n",
1539 __func__, input_status, state->prev_input_status);
1540 state->prev_input_status = input_status;
1541 v4l2_subdev_notify(sd, ADV7604_FMT_CHANGE, NULL);
1542 }
1543 1636
1544 if (handled) 1637 if (handled)
1545 *handled = true; 1638 *handled = true;
1546 } 1639 }
1640 /* HDMI/DVI mode */
1641 if (irq_reg_0x6b & 0x01) {
1642 v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__,
1643 (io_read(sd, 0x6a) & 0x01) ? "HDMI" : "DVI");
1644 set_rgb_quantization_range(sd);
1645 if (handled)
1646 *handled = true;
1647 }
1648
1547 /* tx 5v detect */ 1649 /* tx 5v detect */
1548 tx_5v = io_read(sd, 0x70) & 0x10; 1650 tx_5v = io_read(sd, 0x70) & 0x1e;
1549 if (tx_5v) { 1651 if (tx_5v) {
1550 v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v); 1652 v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v);
1551 io_write(sd, 0x71, tx_5v); 1653 io_write(sd, 0x71, tx_5v);
@@ -1559,55 +1661,178 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1559static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid) 1661static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
1560{ 1662{
1561 struct adv7604_state *state = to_state(sd); 1663 struct adv7604_state *state = to_state(sd);
1664 u8 *data = NULL;
1562 1665
1563 if (edid->pad != 0) 1666 if (edid->pad > ADV7604_EDID_PORT_D)
1564 return -EINVAL; 1667 return -EINVAL;
1565 if (edid->blocks == 0) 1668 if (edid->blocks == 0)
1566 return -EINVAL; 1669 return -EINVAL;
1567 if (edid->start_block >= state->edid_blocks) 1670 if (edid->blocks > 2)
1671 return -EINVAL;
1672 if (edid->start_block > 1)
1568 return -EINVAL; 1673 return -EINVAL;
1569 if (edid->start_block + edid->blocks > state->edid_blocks) 1674 if (edid->start_block == 1)
1570 edid->blocks = state->edid_blocks - edid->start_block; 1675 edid->blocks = 1;
1571 if (!edid->edid) 1676 if (!edid->edid)
1572 return -EINVAL; 1677 return -EINVAL;
1573 memcpy(edid->edid + edid->start_block * 128, 1678
1574 state->edid + edid->start_block * 128, 1679 if (edid->blocks > state->edid.blocks)
1680 edid->blocks = state->edid.blocks;
1681
1682 switch (edid->pad) {
1683 case ADV7604_EDID_PORT_A:
1684 case ADV7604_EDID_PORT_B:
1685 case ADV7604_EDID_PORT_C:
1686 case ADV7604_EDID_PORT_D:
1687 if (state->edid.present & (1 << edid->pad))
1688 data = state->edid.edid;
1689 break;
1690 default:
1691 return -EINVAL;
1692 break;
1693 }
1694 if (!data)
1695 return -ENODATA;
1696
1697 memcpy(edid->edid,
1698 data + edid->start_block * 128,
1575 edid->blocks * 128); 1699 edid->blocks * 128);
1576 return 0; 1700 return 0;
1577} 1701}
1578 1702
1703static int get_edid_spa_location(const u8 *edid)
1704{
1705 u8 d;
1706
1707 if ((edid[0x7e] != 1) ||
1708 (edid[0x80] != 0x02) ||
1709 (edid[0x81] != 0x03)) {
1710 return -1;
1711 }
1712
1713 /* search Vendor Specific Data Block (tag 3) */
1714 d = edid[0x82] & 0x7f;
1715 if (d > 4) {
1716 int i = 0x84;
1717 int end = 0x80 + d;
1718
1719 do {
1720 u8 tag = edid[i] >> 5;
1721 u8 len = edid[i] & 0x1f;
1722
1723 if ((tag == 3) && (len >= 5))
1724 return i + 4;
1725 i += len + 1;
1726 } while (i < end);
1727 }
1728 return -1;
1729}
1730
1579static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid) 1731static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
1580{ 1732{
1581 struct adv7604_state *state = to_state(sd); 1733 struct adv7604_state *state = to_state(sd);
1734 int spa_loc;
1735 int tmp = 0;
1582 int err; 1736 int err;
1737 int i;
1583 1738
1584 if (edid->pad != 0) 1739 if (edid->pad > ADV7604_EDID_PORT_D)
1585 return -EINVAL; 1740 return -EINVAL;
1586 if (edid->start_block != 0) 1741 if (edid->start_block != 0)
1587 return -EINVAL; 1742 return -EINVAL;
1588 if (edid->blocks == 0) { 1743 if (edid->blocks == 0) {
1589 /* Pull down the hotplug pin */ 1744 /* Disable hotplug and I2C access to EDID RAM from DDC port */
1590 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)0); 1745 state->edid.present &= ~(1 << edid->pad);
1591 /* Disables I2C access to internal EDID ram from DDC port */ 1746 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)&state->edid.present);
1592 rep_write_and_or(sd, 0x77, 0xf0, 0x0); 1747 rep_write_and_or(sd, 0x77, 0xf0, state->edid.present);
1593 state->edid_blocks = 0; 1748
1594 /* Fall back to a 16:9 aspect ratio */ 1749 /* Fall back to a 16:9 aspect ratio */
1595 state->aspect_ratio.numerator = 16; 1750 state->aspect_ratio.numerator = 16;
1596 state->aspect_ratio.denominator = 9; 1751 state->aspect_ratio.denominator = 9;
1752
1753 if (!state->edid.present)
1754 state->edid.blocks = 0;
1755
1756 v4l2_dbg(2, debug, sd, "%s: clear EDID pad %d, edid.present = 0x%x\n",
1757 __func__, edid->pad, state->edid.present);
1597 return 0; 1758 return 0;
1598 } 1759 }
1599 if (edid->blocks > 2) 1760 if (edid->blocks > 2) {
1761 edid->blocks = 2;
1600 return -E2BIG; 1762 return -E2BIG;
1763 }
1601 if (!edid->edid) 1764 if (!edid->edid)
1602 return -EINVAL; 1765 return -EINVAL;
1603 memcpy(state->edid, edid->edid, 128 * edid->blocks); 1766
1604 state->edid_blocks = edid->blocks; 1767 v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n",
1768 __func__, edid->pad, state->edid.present);
1769
1770 /* Disable hotplug and I2C access to EDID RAM from DDC port */
1771 cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
1772 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)&tmp);
1773 rep_write_and_or(sd, 0x77, 0xf0, 0x00);
1774
1775 spa_loc = get_edid_spa_location(edid->edid);
1776 if (spa_loc < 0)
1777 spa_loc = 0xc0; /* Default value [REF_02, p. 116] */
1778
1779 switch (edid->pad) {
1780 case ADV7604_EDID_PORT_A:
1781 state->spa_port_a[0] = edid->edid[spa_loc];
1782 state->spa_port_a[1] = edid->edid[spa_loc + 1];
1783 break;
1784 case ADV7604_EDID_PORT_B:
1785 rep_write(sd, 0x70, edid->edid[spa_loc]);
1786 rep_write(sd, 0x71, edid->edid[spa_loc + 1]);
1787 break;
1788 case ADV7604_EDID_PORT_C:
1789 rep_write(sd, 0x72, edid->edid[spa_loc]);
1790 rep_write(sd, 0x73, edid->edid[spa_loc + 1]);
1791 break;
1792 case ADV7604_EDID_PORT_D:
1793 rep_write(sd, 0x74, edid->edid[spa_loc]);
1794 rep_write(sd, 0x75, edid->edid[spa_loc + 1]);
1795 break;
1796 default:
1797 return -EINVAL;
1798 }
1799 rep_write(sd, 0x76, spa_loc & 0xff);
1800 rep_write_and_or(sd, 0x77, 0xbf, (spa_loc >> 2) & 0x40);
1801
1802 edid->edid[spa_loc] = state->spa_port_a[0];
1803 edid->edid[spa_loc + 1] = state->spa_port_a[1];
1804
1805 memcpy(state->edid.edid, edid->edid, 128 * edid->blocks);
1806 state->edid.blocks = edid->blocks;
1605 state->aspect_ratio = v4l2_calc_aspect_ratio(edid->edid[0x15], 1807 state->aspect_ratio = v4l2_calc_aspect_ratio(edid->edid[0x15],
1606 edid->edid[0x16]); 1808 edid->edid[0x16]);
1607 err = edid_write_block(sd, 128 * edid->blocks, state->edid); 1809 state->edid.present |= 1 << edid->pad;
1608 if (err < 0) 1810
1609 v4l2_err(sd, "error %d writing edid\n", err); 1811 err = edid_write_block(sd, 128 * edid->blocks, state->edid.edid);
1610 return err; 1812 if (err < 0) {
1813 v4l2_err(sd, "error %d writing edid pad %d\n", err, edid->pad);
1814 return err;
1815 }
1816
1817 /* adv7604 calculates the checksums and enables I2C access to internal
1818 EDID RAM from DDC port. */
1819 rep_write_and_or(sd, 0x77, 0xf0, state->edid.present);
1820
1821 for (i = 0; i < 1000; i++) {
1822 if (rep_read(sd, 0x7d) & state->edid.present)
1823 break;
1824 mdelay(1);
1825 }
1826 if (i == 1000) {
1827 v4l2_err(sd, "error enabling edid (0x%x)\n", state->edid.present);
1828 return -EIO;
1829 }
1830
1831
1832 /* enable hotplug after 100 ms */
1833 queue_delayed_work(state->work_queues,
1834 &state->delayed_work_enable_hotplug, HZ / 10);
1835 return 0;
1611} 1836}
1612 1837
1613/*********** avi info frame CEA-861-E **************/ 1838/*********** avi info frame CEA-861-E **************/
@@ -1670,7 +1895,7 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
1670 char *input_color_space_txt[16] = { 1895 char *input_color_space_txt[16] = {
1671 "RGB limited range (16-235)", "RGB full range (0-255)", 1896 "RGB limited range (16-235)", "RGB full range (0-255)",
1672 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)", 1897 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
1673 "XvYCC Bt.601", "XvYCC Bt.709", 1898 "xvYCC Bt.601", "xvYCC Bt.709",
1674 "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)", 1899 "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
1675 "invalid", "invalid", "invalid", "invalid", "invalid", 1900 "invalid", "invalid", "invalid", "invalid", "invalid",
1676 "invalid", "invalid", "automatic" 1901 "invalid", "invalid", "automatic"
@@ -1689,16 +1914,20 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
1689 1914
1690 v4l2_info(sd, "-----Chip status-----\n"); 1915 v4l2_info(sd, "-----Chip status-----\n");
1691 v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on"); 1916 v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on");
1692 v4l2_info(sd, "Connector type: %s\n", state->connector_hdmi ? 1917 v4l2_info(sd, "EDID enabled port A: %s, B: %s, C: %s, D: %s\n",
1693 "HDMI" : (DIGITAL_INPUT ? "DVI-D" : "DVI-A")); 1918 ((rep_read(sd, 0x7d) & 0x01) ? "Yes" : "No"),
1694 v4l2_info(sd, "EDID: %s\n", ((rep_read(sd, 0x7d) & 0x01) && 1919 ((rep_read(sd, 0x7d) & 0x02) ? "Yes" : "No"),
1695 (rep_read(sd, 0x77) & 0x01)) ? "enabled" : "disabled "); 1920 ((rep_read(sd, 0x7d) & 0x04) ? "Yes" : "No"),
1921 ((rep_read(sd, 0x7d) & 0x08) ? "Yes" : "No"));
1696 v4l2_info(sd, "CEC: %s\n", !!(cec_read(sd, 0x2a) & 0x01) ? 1922 v4l2_info(sd, "CEC: %s\n", !!(cec_read(sd, 0x2a) & 0x01) ?
1697 "enabled" : "disabled"); 1923 "enabled" : "disabled");
1698 1924
1699 v4l2_info(sd, "-----Signal status-----\n"); 1925 v4l2_info(sd, "-----Signal status-----\n");
1700 v4l2_info(sd, "Cable detected (+5V power): %s\n", 1926 v4l2_info(sd, "Cable detected (+5V power) port A: %s, B: %s, C: %s, D: %s\n",
1701 (io_read(sd, 0x6f) & 0x10) ? "true" : "false"); 1927 ((io_read(sd, 0x6f) & 0x10) ? "Yes" : "No"),
1928 ((io_read(sd, 0x6f) & 0x08) ? "Yes" : "No"),
1929 ((io_read(sd, 0x6f) & 0x04) ? "Yes" : "No"),
1930 ((io_read(sd, 0x6f) & 0x02) ? "Yes" : "No"));
1702 v4l2_info(sd, "TMDS signal detected: %s\n", 1931 v4l2_info(sd, "TMDS signal detected: %s\n",
1703 no_signal_tmds(sd) ? "false" : "true"); 1932 no_signal_tmds(sd) ? "false" : "true");
1704 v4l2_info(sd, "TMDS signal locked: %s\n", 1933 v4l2_info(sd, "TMDS signal locked: %s\n",
@@ -1744,11 +1973,14 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
1744 v4l2_info(sd, "Color space conversion: %s\n", 1973 v4l2_info(sd, "Color space conversion: %s\n",
1745 csc_coeff_sel_rb[cp_read(sd, 0xfc) >> 4]); 1974 csc_coeff_sel_rb[cp_read(sd, 0xfc) >> 4]);
1746 1975
1747 if (!DIGITAL_INPUT) 1976 if (!is_digital_input(sd))
1748 return 0; 1977 return 0;
1749 1978
1750 v4l2_info(sd, "-----%s status-----\n", is_hdmi(sd) ? "HDMI" : "DVI-D"); 1979 v4l2_info(sd, "-----%s status-----\n", is_hdmi(sd) ? "HDMI" : "DVI-D");
1751 v4l2_info(sd, "HDCP encrypted content: %s\n", (hdmi_read(sd, 0x05) & 0x40) ? "true" : "false"); 1980 v4l2_info(sd, "Digital video port selected: %c\n",
1981 (hdmi_read(sd, 0x00) & 0x03) + 'A');
1982 v4l2_info(sd, "HDCP encrypted content: %s\n",
1983 (hdmi_read(sd, 0x05) & 0x40) ? "true" : "false");
1752 v4l2_info(sd, "HDCP keys read: %s%s\n", 1984 v4l2_info(sd, "HDCP keys read: %s%s\n",
1753 (hdmi_read(sd, 0x04) & 0x20) ? "yes" : "no", 1985 (hdmi_read(sd, 0x04) & 0x20) ? "yes" : "no",
1754 (hdmi_read(sd, 0x04) & 0x10) ? "ERROR" : ""); 1986 (hdmi_read(sd, 0x04) & 0x10) ? "ERROR" : "");
@@ -1894,10 +2126,16 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
1894 pdata->replicate_av_codes << 1 | 2126 pdata->replicate_av_codes << 1 |
1895 pdata->invert_cbcr << 0); 2127 pdata->invert_cbcr << 0);
1896 2128
1897 /* TODO from platform data */
1898 cp_write(sd, 0x69, 0x30); /* Enable CP CSC */ 2129 cp_write(sd, 0x69, 0x30); /* Enable CP CSC */
1899 io_write(sd, 0x06, 0xa6); /* positive VS and HS */ 2130
1900 io_write(sd, 0x14, 0x7f); /* Drive strength adjusted to max */ 2131 /* VS, HS polarities */
2132 io_write(sd, 0x06, 0xa0 | pdata->inv_vs_pol << 2 | pdata->inv_hs_pol << 1);
2133
2134 /* Adjust drive strength */
2135 io_write(sd, 0x14, 0x40 | pdata->dr_str_data << 4 |
2136 pdata->dr_str_clk << 2 |
2137 pdata->dr_str_sync);
2138
1901 cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */ 2139 cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */
1902 cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */ 2140 cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */
1903 cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold - 2141 cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold -
@@ -1907,6 +2145,11 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
1907 cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution 2145 cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution
1908 for digital formats */ 2146 for digital formats */
1909 2147
2148 /* HDMI audio */
2149 hdmi_write_and_or(sd, 0x15, 0xfc, 0x03); /* Mute on FIFO over-/underflow [REF_01, c. 1.2.18] */
2150 hdmi_write_and_or(sd, 0x1a, 0xf1, 0x08); /* Wait 1 s before unmute */
2151 hdmi_write_and_or(sd, 0x68, 0xf9, 0x06); /* FIFO reset on over-/underflow [REF_01, c. 1.2.19] */
2152
1910 /* TODO from platform data */ 2153 /* TODO from platform data */
1911 afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */ 2154 afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */
1912 2155
@@ -1917,8 +2160,8 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
1917 io_write(sd, 0x40, 0xc2); /* Configure INT1 */ 2160 io_write(sd, 0x40, 0xc2); /* Configure INT1 */
1918 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ 2161 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
1919 io_write(sd, 0x46, 0x98); /* Enable SSPD, STDI and CP unlocked interrupts */ 2162 io_write(sd, 0x46, 0x98); /* Enable SSPD, STDI and CP unlocked interrupts */
1920 io_write(sd, 0x6e, 0xc0); /* Enable V_LOCKED and DE_REGEN_LCK interrupts */ 2163 io_write(sd, 0x6e, 0xc1); /* Enable V_LOCKED, DE_REGEN_LCK, HDMI_MODE interrupts */
1921 io_write(sd, 0x73, 0x10); /* Enable CABLE_DET_A_ST (+5v) interrupt */ 2164 io_write(sd, 0x73, 0x1e); /* Enable CABLE_DET_A_ST (+5v) interrupts */
1922 2165
1923 return v4l2_ctrl_handler_setup(sd->ctrl_handler); 2166 return v4l2_ctrl_handler_setup(sd->ctrl_handler);
1924} 2167}
@@ -1964,6 +2207,8 @@ static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd,
1964static int adv7604_probe(struct i2c_client *client, 2207static int adv7604_probe(struct i2c_client *client,
1965 const struct i2c_device_id *id) 2208 const struct i2c_device_id *id)
1966{ 2209{
2210 static const struct v4l2_dv_timings cea640x480 =
2211 V4L2_DV_BT_CEA_640X480P59_94;
1967 struct adv7604_state *state; 2212 struct adv7604_state *state;
1968 struct adv7604_platform_data *pdata = client->dev.platform_data; 2213 struct adv7604_platform_data *pdata = client->dev.platform_data;
1969 struct v4l2_ctrl_handler *hdl; 2214 struct v4l2_ctrl_handler *hdl;
@@ -1984,19 +2229,19 @@ static int adv7604_probe(struct i2c_client *client,
1984 2229
1985 /* initialize variables */ 2230 /* initialize variables */
1986 state->restart_stdi_once = true; 2231 state->restart_stdi_once = true;
1987 state->prev_input_status = ~0; 2232 state->selected_input = ~0;
1988 2233
1989 /* platform data */ 2234 /* platform data */
1990 if (!pdata) { 2235 if (!pdata) {
1991 v4l_err(client, "No platform data!\n"); 2236 v4l_err(client, "No platform data!\n");
1992 return -ENODEV; 2237 return -ENODEV;
1993 } 2238 }
1994 memcpy(&state->pdata, pdata, sizeof(state->pdata)); 2239 state->pdata = *pdata;
2240 state->timings = cea640x480;
1995 2241
1996 sd = &state->sd; 2242 sd = &state->sd;
1997 v4l2_i2c_subdev_init(sd, client, &adv7604_ops); 2243 v4l2_i2c_subdev_init(sd, client, &adv7604_ops);
1998 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 2244 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1999 state->connector_hdmi = pdata->connector_hdmi;
2000 2245
2001 /* i2c access to adv7604? */ 2246 /* i2c access to adv7604? */
2002 if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) { 2247 if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) {
@@ -2020,7 +2265,7 @@ static int adv7604_probe(struct i2c_client *client,
2020 2265
2021 /* private controls */ 2266 /* private controls */
2022 state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL, 2267 state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL,
2023 V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0); 2268 V4L2_CID_DV_RX_POWER_PRESENT, 0, 0x0f, 0, 0);
2024 state->rgb_quantization_range_ctrl = 2269 state->rgb_quantization_range_ctrl =
2025 v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops, 2270 v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops,
2026 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 2271 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index b154f36740b4..1effc21e1cdd 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -20,10 +20,13 @@
20 20
21/* 21/*
22 * References (c = chapter, p = page): 22 * References (c = chapter, p = page):
23 * REF_01 - Analog devices, ADV7842, Register Settings Recommendations, 23 * REF_01 - Analog devices, ADV7842,
24 * Revision 2.5, June 2010 24 * Register Settings Recommendations, Rev. 1.9, April 2011
25 * REF_02 - Analog devices, Register map documentation, Documentation of 25 * REF_02 - Analog devices, Software User Guide, UG-206,
26 * the register maps, Software manual, Rev. F, June 2010 26 * ADV7842 I2C Register Maps, Rev. 0, November 2010
27 * REF_03 - Analog devices, Hardware User Guide, UG-214,
28 * ADV7842 Fast Switching 2:1 HDMI 1.4 Receiver with 3D-Comb
29 * Decoder and Digitizer , Rev. 0, January 2011
27 */ 30 */
28 31
29 32
@@ -61,6 +64,7 @@ MODULE_LICENSE("GPL");
61*/ 64*/
62 65
63struct adv7842_state { 66struct adv7842_state {
67 struct adv7842_platform_data pdata;
64 struct v4l2_subdev sd; 68 struct v4l2_subdev sd;
65 struct media_pad pad; 69 struct media_pad pad;
66 struct v4l2_ctrl_handler hdl; 70 struct v4l2_ctrl_handler hdl;
@@ -81,7 +85,7 @@ struct adv7842_state {
81 bool is_cea_format; 85 bool is_cea_format;
82 struct workqueue_struct *work_queues; 86 struct workqueue_struct *work_queues;
83 struct delayed_work delayed_work_enable_hotplug; 87 struct delayed_work delayed_work_enable_hotplug;
84 bool connector_hdmi; 88 bool restart_stdi_once;
85 bool hdmi_port_a; 89 bool hdmi_port_a;
86 90
87 /* i2c clients */ 91 /* i2c clients */
@@ -491,6 +495,11 @@ static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
491 return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val); 495 return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val);
492} 496}
493 497
498static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
499{
500 return hdmi_write(sd, reg, (hdmi_read(sd, reg) & mask) | val);
501}
502
494static inline int cp_read(struct v4l2_subdev *sd, u8 reg) 503static inline int cp_read(struct v4l2_subdev *sd, u8 reg)
495{ 504{
496 struct adv7842_state *state = to_state(sd); 505 struct adv7842_state *state = to_state(sd);
@@ -532,7 +541,7 @@ static void main_reset(struct v4l2_subdev *sd)
532 541
533 adv_smbus_write_byte_no_check(client, 0xff, 0x80); 542 adv_smbus_write_byte_no_check(client, 0xff, 0x80);
534 543
535 mdelay(2); 544 mdelay(5);
536} 545}
537 546
538/* ----------------------------------------------------------------------- */ 547/* ----------------------------------------------------------------------- */
@@ -587,10 +596,10 @@ static void adv7842_delayed_work_enable_hotplug(struct work_struct *work)
587 v4l2_dbg(2, debug, sd, "%s: enable hotplug on ports: 0x%x\n", 596 v4l2_dbg(2, debug, sd, "%s: enable hotplug on ports: 0x%x\n",
588 __func__, present); 597 __func__, present);
589 598
590 if (present & 0x1) 599 if (present & (0x04 << ADV7842_EDID_PORT_A))
591 mask |= 0x20; /* port A */ 600 mask |= 0x20;
592 if (present & 0x2) 601 if (present & (0x04 << ADV7842_EDID_PORT_B))
593 mask |= 0x10; /* port B */ 602 mask |= 0x10;
594 io_write_and_or(sd, 0x20, 0xcf, mask); 603 io_write_and_or(sd, 0x20, 0xcf, mask);
595} 604}
596 605
@@ -679,14 +688,12 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
679 struct i2c_client *client = v4l2_get_subdevdata(sd); 688 struct i2c_client *client = v4l2_get_subdevdata(sd);
680 struct adv7842_state *state = to_state(sd); 689 struct adv7842_state *state = to_state(sd);
681 const u8 *val = state->hdmi_edid.edid; 690 const u8 *val = state->hdmi_edid.edid;
682 u8 cur_mask = rep_read(sd, 0x77) & 0x0c;
683 u8 mask = port == 0 ? 0x4 : 0x8;
684 int spa_loc = edid_spa_location(val); 691 int spa_loc = edid_spa_location(val);
685 int err = 0; 692 int err = 0;
686 int i; 693 int i;
687 694
688 v4l2_dbg(2, debug, sd, "%s: write EDID on port %d (spa at 0x%x)\n", 695 v4l2_dbg(2, debug, sd, "%s: write EDID on port %c (spa at 0x%x)\n",
689 __func__, port, spa_loc); 696 __func__, (port == ADV7842_EDID_PORT_A) ? 'A' : 'B', spa_loc);
690 697
691 /* HPA disable on port A and B */ 698 /* HPA disable on port A and B */
692 io_write_and_or(sd, 0x20, 0xcf, 0x00); 699 io_write_and_or(sd, 0x20, 0xcf, 0x00);
@@ -694,6 +701,9 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
694 /* Disable I2C access to internal EDID ram from HDMI DDC ports */ 701 /* Disable I2C access to internal EDID ram from HDMI DDC ports */
695 rep_write_and_or(sd, 0x77, 0xf3, 0x00); 702 rep_write_and_or(sd, 0x77, 0xf3, 0x00);
696 703
704 if (!state->hdmi_edid.present)
705 return 0;
706
697 /* edid segment pointer '0' for HDMI ports */ 707 /* edid segment pointer '0' for HDMI ports */
698 rep_write_and_or(sd, 0x77, 0xef, 0x00); 708 rep_write_and_or(sd, 0x77, 0xef, 0x00);
699 709
@@ -703,44 +713,32 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
703 if (err) 713 if (err)
704 return err; 714 return err;
705 715
706 if (spa_loc > 0) { 716 if (spa_loc < 0)
707 if (port == 0) { 717 spa_loc = 0xc0; /* Default value [REF_02, p. 199] */
708 /* port A SPA */ 718
709 rep_write(sd, 0x72, val[spa_loc]); 719 if (port == ADV7842_EDID_PORT_A) {
710 rep_write(sd, 0x73, val[spa_loc + 1]); 720 rep_write(sd, 0x72, val[spa_loc]);
711 } else { 721 rep_write(sd, 0x73, val[spa_loc + 1]);
712 /* port B SPA */
713 rep_write(sd, 0x74, val[spa_loc]);
714 rep_write(sd, 0x75, val[spa_loc + 1]);
715 }
716 rep_write(sd, 0x76, spa_loc);
717 } else { 722 } else {
718 /* default register values for SPA */ 723 rep_write(sd, 0x74, val[spa_loc]);
719 if (port == 0) { 724 rep_write(sd, 0x75, val[spa_loc + 1]);
720 /* port A SPA */
721 rep_write(sd, 0x72, 0);
722 rep_write(sd, 0x73, 0);
723 } else {
724 /* port B SPA */
725 rep_write(sd, 0x74, 0);
726 rep_write(sd, 0x75, 0);
727 }
728 rep_write(sd, 0x76, 0xc0);
729 } 725 }
730 rep_write_and_or(sd, 0x77, 0xbf, 0x00); 726 rep_write(sd, 0x76, spa_loc & 0xff);
727 rep_write_and_or(sd, 0x77, 0xbf, (spa_loc >> 2) & 0x40);
731 728
732 /* Calculates the checksums and enables I2C access to internal 729 /* Calculates the checksums and enables I2C access to internal
733 * EDID ram from HDMI DDC ports 730 * EDID ram from HDMI DDC ports
734 */ 731 */
735 rep_write_and_or(sd, 0x77, 0xf3, mask | cur_mask); 732 rep_write_and_or(sd, 0x77, 0xf3, state->hdmi_edid.present);
736 733
737 for (i = 0; i < 1000; i++) { 734 for (i = 0; i < 1000; i++) {
738 if (rep_read(sd, 0x7d) & mask) 735 if (rep_read(sd, 0x7d) & state->hdmi_edid.present)
739 break; 736 break;
740 mdelay(1); 737 mdelay(1);
741 } 738 }
742 if (i == 1000) { 739 if (i == 1000) {
743 v4l_err(client, "error enabling edid on port %d\n", port); 740 v4l_err(client, "error enabling edid on port %c\n",
741 (port == ADV7842_EDID_PORT_A) ? 'A' : 'B');
744 return -EIO; 742 return -EIO;
745 } 743 }
746 744
@@ -927,7 +925,7 @@ static int configure_predefined_video_timings(struct v4l2_subdev *sd,
927 cp_write(sd, 0x27, 0x00); 925 cp_write(sd, 0x27, 0x00);
928 cp_write(sd, 0x28, 0x00); 926 cp_write(sd, 0x28, 0x00);
929 cp_write(sd, 0x29, 0x00); 927 cp_write(sd, 0x29, 0x00);
930 cp_write(sd, 0x8f, 0x00); 928 cp_write(sd, 0x8f, 0x40);
931 cp_write(sd, 0x90, 0x00); 929 cp_write(sd, 0x90, 0x00);
932 cp_write(sd, 0xa5, 0x00); 930 cp_write(sd, 0xa5, 0x00);
933 cp_write(sd, 0xa6, 0x00); 931 cp_write(sd, 0xa6, 0x00);
@@ -1033,34 +1031,60 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
1033{ 1031{
1034 struct adv7842_state *state = to_state(sd); 1032 struct adv7842_state *state = to_state(sd);
1035 1033
1034 v4l2_dbg(2, debug, sd, "%s: rgb_quantization_range = %d\n",
1035 __func__, state->rgb_quantization_range);
1036
1036 switch (state->rgb_quantization_range) { 1037 switch (state->rgb_quantization_range) {
1037 case V4L2_DV_RGB_RANGE_AUTO: 1038 case V4L2_DV_RGB_RANGE_AUTO:
1038 /* automatic */ 1039 if (state->mode == ADV7842_MODE_RGB) {
1039 if (is_digital_input(sd) && !(hdmi_read(sd, 0x05) & 0x80)) { 1040 /* Receiving analog RGB signal
1040 /* receiving DVI-D signal */ 1041 * Set RGB full range (0-255) */
1041 1042 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1042 /* ADV7842 selects RGB limited range regardless of 1043 break;
1043 input format (CE/IT) in automatic mode */ 1044 }
1044 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { 1045
1045 /* RGB limited range (16-235) */ 1046 if (state->mode == ADV7842_MODE_COMP) {
1046 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1047 /* Receiving analog YPbPr signal
1047 1048 * Set automode */
1048 } else {
1049 /* RGB full range (0-255) */
1050 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1051 }
1052 } else {
1053 /* receiving HDMI or analog signal, set automode */
1054 io_write_and_or(sd, 0x02, 0x0f, 0xf0); 1049 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
1050 break;
1051 }
1052
1053 if (hdmi_read(sd, 0x05) & 0x80) {
1054 /* Receiving HDMI signal
1055 * Set automode */
1056 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
1057 break;
1058 }
1059
1060 /* Receiving DVI-D signal
1061 * ADV7842 selects RGB limited range regardless of
1062 * input format (CE/IT) in automatic mode */
1063 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
1064 /* RGB limited range (16-235) */
1065 io_write_and_or(sd, 0x02, 0x0f, 0x00);
1066 } else {
1067 /* RGB full range (0-255) */
1068 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1055 } 1069 }
1056 break; 1070 break;
1057 case V4L2_DV_RGB_RANGE_LIMITED: 1071 case V4L2_DV_RGB_RANGE_LIMITED:
1058 /* RGB limited range (16-235) */ 1072 if (state->mode == ADV7842_MODE_COMP) {
1059 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1073 /* YCrCb limited range (16-235) */
1074 io_write_and_or(sd, 0x02, 0x0f, 0x20);
1075 } else {
1076 /* RGB limited range (16-235) */
1077 io_write_and_or(sd, 0x02, 0x0f, 0x00);
1078 }
1060 break; 1079 break;
1061 case V4L2_DV_RGB_RANGE_FULL: 1080 case V4L2_DV_RGB_RANGE_FULL:
1062 /* RGB full range (0-255) */ 1081 if (state->mode == ADV7842_MODE_COMP) {
1063 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1082 /* YCrCb full range (0-255) */
1083 io_write_and_or(sd, 0x02, 0x0f, 0x60);
1084 } else {
1085 /* RGB full range (0-255) */
1086 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1087 }
1064 break; 1088 break;
1065 } 1089 }
1066} 1090}
@@ -1298,7 +1322,7 @@ static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
1298} 1322}
1299 1323
1300/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings 1324/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
1301 if the format is listed in adv7604_timings[] */ 1325 if the format is listed in adv7842_timings[] */
1302static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, 1326static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
1303 struct v4l2_dv_timings *timings) 1327 struct v4l2_dv_timings *timings)
1304{ 1328{
@@ -1314,119 +1338,106 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
1314 struct v4l2_bt_timings *bt = &timings->bt; 1338 struct v4l2_bt_timings *bt = &timings->bt;
1315 struct stdi_readback stdi = { 0 }; 1339 struct stdi_readback stdi = { 0 };
1316 1340
1341 v4l2_dbg(1, debug, sd, "%s:\n", __func__);
1342
1317 /* SDP block */ 1343 /* SDP block */
1318 if (state->mode == ADV7842_MODE_SDP) 1344 if (state->mode == ADV7842_MODE_SDP)
1319 return -ENODATA; 1345 return -ENODATA;
1320 1346
1321 /* read STDI */ 1347 /* read STDI */
1322 if (read_stdi(sd, &stdi)) { 1348 if (read_stdi(sd, &stdi)) {
1349 state->restart_stdi_once = true;
1323 v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__); 1350 v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__);
1324 return -ENOLINK; 1351 return -ENOLINK;
1325 } 1352 }
1326 bt->interlaced = stdi.interlaced ? 1353 bt->interlaced = stdi.interlaced ?
1327 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; 1354 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
1328 bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ? V4L2_DV_VSYNC_POS_POL : 0) |
1329 ((hdmi_read(sd, 0x05) & 0x20) ? V4L2_DV_HSYNC_POS_POL : 0);
1330 bt->vsync = stdi.lcvs;
1331 1355
1332 if (is_digital_input(sd)) { 1356 if (is_digital_input(sd)) {
1333 bool lock = hdmi_read(sd, 0x04) & 0x02; 1357 uint32_t freq;
1334 bool interlaced = hdmi_read(sd, 0x0b) & 0x20;
1335 unsigned w = (hdmi_read(sd, 0x07) & 0x1f) * 256 + hdmi_read(sd, 0x08);
1336 unsigned h = (hdmi_read(sd, 0x09) & 0x1f) * 256 + hdmi_read(sd, 0x0a);
1337 unsigned w_total = (hdmi_read(sd, 0x1e) & 0x3f) * 256 +
1338 hdmi_read(sd, 0x1f);
1339 unsigned h_total = ((hdmi_read(sd, 0x26) & 0x3f) * 256 +
1340 hdmi_read(sd, 0x27)) / 2;
1341 unsigned freq = (((hdmi_read(sd, 0x51) << 1) +
1342 (hdmi_read(sd, 0x52) >> 7)) * 1000000) +
1343 ((hdmi_read(sd, 0x52) & 0x7f) * 1000000) / 128;
1344 int i;
1345 1358
1346 if (is_hdmi(sd)) { 1359 timings->type = V4L2_DV_BT_656_1120;
1347 /* adjust for deep color mode */
1348 freq = freq * 8 / (((hdmi_read(sd, 0x0b) & 0xc0)>>6) * 2 + 8);
1349 }
1350
1351 /* No lock? */
1352 if (!lock) {
1353 v4l2_dbg(1, debug, sd, "%s: no lock on TMDS signal\n", __func__);
1354 return -ENOLCK;
1355 }
1356 /* Interlaced? */
1357 if (interlaced) {
1358 v4l2_dbg(1, debug, sd, "%s: interlaced video not supported\n", __func__);
1359 return -ERANGE;
1360 }
1361
1362 for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) {
1363 const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
1364
1365 if (!v4l2_valid_dv_timings(&v4l2_dv_timings_presets[i],
1366 adv7842_get_dv_timings_cap(sd),
1367 adv7842_check_dv_timings, NULL))
1368 continue;
1369 if (w_total != htotal(bt) || h_total != vtotal(bt))
1370 continue;
1371 1360
1372 if (w != bt->width || h != bt->height) 1361 bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08);
1373 continue; 1362 bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a);
1363 freq = (hdmi_read(sd, 0x06) * 1000000) +
1364 ((hdmi_read(sd, 0x3b) & 0x30) >> 4) * 250000;
1374 1365
1375 if (abs(freq - bt->pixelclock) > 1000000) 1366 if (is_hdmi(sd)) {
1376 continue; 1367 /* adjust for deep color mode */
1377 *timings = v4l2_dv_timings_presets[i]; 1368 freq = freq * 8 / (((hdmi_read(sd, 0x0b) & 0xc0) >> 5) + 8);
1378 return 0;
1379 } 1369 }
1380 1370 bt->pixelclock = freq;
1381 timings->type = V4L2_DV_BT_656_1120; 1371 bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x03) * 256 +
1382
1383 bt->width = w;
1384 bt->height = h;
1385 bt->interlaced = (hdmi_read(sd, 0x0b) & 0x20) ?
1386 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
1387 bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ?
1388 V4L2_DV_VSYNC_POS_POL : 0) | ((hdmi_read(sd, 0x05) & 0x20) ?
1389 V4L2_DV_HSYNC_POS_POL : 0);
1390 bt->pixelclock = (((hdmi_read(sd, 0x51) << 1) +
1391 (hdmi_read(sd, 0x52) >> 7)) * 1000000) +
1392 ((hdmi_read(sd, 0x52) & 0x7f) * 1000000) / 128;
1393 bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x1f) * 256 +
1394 hdmi_read(sd, 0x21); 1372 hdmi_read(sd, 0x21);
1395 bt->hsync = (hdmi_read(sd, 0x22) & 0x1f) * 256 + 1373 bt->hsync = (hdmi_read(sd, 0x22) & 0x03) * 256 +
1396 hdmi_read(sd, 0x23); 1374 hdmi_read(sd, 0x23);
1397 bt->hbackporch = (hdmi_read(sd, 0x24) & 0x1f) * 256 + 1375 bt->hbackporch = (hdmi_read(sd, 0x24) & 0x03) * 256 +
1398 hdmi_read(sd, 0x25); 1376 hdmi_read(sd, 0x25);
1399 bt->vfrontporch = ((hdmi_read(sd, 0x2a) & 0x3f) * 256 + 1377 bt->vfrontporch = ((hdmi_read(sd, 0x2a) & 0x1f) * 256 +
1400 hdmi_read(sd, 0x2b)) / 2; 1378 hdmi_read(sd, 0x2b)) / 2;
1401 bt->il_vfrontporch = ((hdmi_read(sd, 0x2c) & 0x3f) * 256 + 1379 bt->vsync = ((hdmi_read(sd, 0x2e) & 0x1f) * 256 +
1402 hdmi_read(sd, 0x2d)) / 2; 1380 hdmi_read(sd, 0x2f)) / 2;
1403 bt->vsync = ((hdmi_read(sd, 0x2e) & 0x3f) * 256 + 1381 bt->vbackporch = ((hdmi_read(sd, 0x32) & 0x1f) * 256 +
1404 hdmi_read(sd, 0x2f)) / 2; 1382 hdmi_read(sd, 0x33)) / 2;
1405 bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x3f) * 256 + 1383 bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ? V4L2_DV_VSYNC_POS_POL : 0) |
1406 hdmi_read(sd, 0x31)) / 2; 1384 ((hdmi_read(sd, 0x05) & 0x20) ? V4L2_DV_HSYNC_POS_POL : 0);
1407 bt->vbackporch = ((hdmi_read(sd, 0x32) & 0x3f) * 256 + 1385 if (bt->interlaced == V4L2_DV_INTERLACED) {
1408 hdmi_read(sd, 0x33)) / 2; 1386 bt->height += (hdmi_read(sd, 0x0b) & 0x0f) * 256 +
1409 bt->il_vbackporch = ((hdmi_read(sd, 0x34) & 0x3f) * 256 + 1387 hdmi_read(sd, 0x0c);
1410 hdmi_read(sd, 0x35)) / 2; 1388 bt->il_vfrontporch = ((hdmi_read(sd, 0x2c) & 0x1f) * 256 +
1411 1389 hdmi_read(sd, 0x2d)) / 2;
1412 bt->standards = 0; 1390 bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x1f) * 256 +
1413 bt->flags = 0; 1391 hdmi_read(sd, 0x31)) / 2;
1414 } else { 1392 bt->vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
1415 /* Interlaced? */ 1393 hdmi_read(sd, 0x35)) / 2;
1416 if (stdi.interlaced) {
1417 v4l2_dbg(1, debug, sd, "%s: interlaced video not supported\n", __func__);
1418 return -ERANGE;
1419 } 1394 }
1420 1395 adv7842_fill_optional_dv_timings_fields(sd, timings);
1396 } else {
1397 /* find format
1398 * Since LCVS values are inaccurate [REF_03, p. 339-340],
1399 * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
1400 */
1401 if (!stdi2dv_timings(sd, &stdi, timings))
1402 goto found;
1403 stdi.lcvs += 1;
1404 v4l2_dbg(1, debug, sd, "%s: lcvs + 1 = %d\n", __func__, stdi.lcvs);
1405 if (!stdi2dv_timings(sd, &stdi, timings))
1406 goto found;
1407 stdi.lcvs -= 2;
1408 v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
1421 if (stdi2dv_timings(sd, &stdi, timings)) { 1409 if (stdi2dv_timings(sd, &stdi, timings)) {
1410 /*
1411 * The STDI block may measure wrong values, especially
1412 * for lcvs and lcf. If the driver can not find any
1413 * valid timing, the STDI block is restarted to measure
1414 * the video timings again. The function will return an
1415 * error, but the restart of STDI will generate a new
1416 * STDI interrupt and the format detection process will
1417 * restart.
1418 */
1419 if (state->restart_stdi_once) {
1420 v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
1421 /* TODO restart STDI for Sync Channel 2 */
1422 /* enter one-shot mode */
1423 cp_write_and_or(sd, 0x86, 0xf9, 0x00);
1424 /* trigger STDI restart */
1425 cp_write_and_or(sd, 0x86, 0xf9, 0x04);
1426 /* reset to continuous mode */
1427 cp_write_and_or(sd, 0x86, 0xf9, 0x02);
1428 state->restart_stdi_once = false;
1429 return -ENOLINK;
1430 }
1422 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); 1431 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
1423 return -ERANGE; 1432 return -ERANGE;
1424 } 1433 }
1434 state->restart_stdi_once = true;
1425 } 1435 }
1436found:
1426 1437
1427 if (debug > 1) 1438 if (debug > 1)
1428 v4l2_print_dv_timings(sd->name, "adv7842_query_dv_timings: ", 1439 v4l2_print_dv_timings(sd->name, "adv7842_query_dv_timings:",
1429 timings, true); 1440 timings, true);
1430 return 0; 1441 return 0;
1431} 1442}
1432 1443
@@ -1437,9 +1448,16 @@ static int adv7842_s_dv_timings(struct v4l2_subdev *sd,
1437 struct v4l2_bt_timings *bt; 1448 struct v4l2_bt_timings *bt;
1438 int err; 1449 int err;
1439 1450
1451 v4l2_dbg(1, debug, sd, "%s:\n", __func__);
1452
1440 if (state->mode == ADV7842_MODE_SDP) 1453 if (state->mode == ADV7842_MODE_SDP)
1441 return -ENODATA; 1454 return -ENODATA;
1442 1455
1456 if (v4l2_match_dv_timings(&state->timings, timings, 0)) {
1457 v4l2_dbg(1, debug, sd, "%s: no change\n", __func__);
1458 return 0;
1459 }
1460
1443 bt = &timings->bt; 1461 bt = &timings->bt;
1444 1462
1445 if (!v4l2_valid_dv_timings(timings, adv7842_get_dv_timings_cap(sd), 1463 if (!v4l2_valid_dv_timings(timings, adv7842_get_dv_timings_cap(sd),
@@ -1450,7 +1468,7 @@ static int adv7842_s_dv_timings(struct v4l2_subdev *sd,
1450 1468
1451 state->timings = *timings; 1469 state->timings = *timings;
1452 1470
1453 cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10); 1471 cp_write(sd, 0x91, bt->interlaced ? 0x40 : 0x00);
1454 1472
1455 /* Use prim_mode and vid_std when available */ 1473 /* Use prim_mode and vid_std when available */
1456 err = configure_predefined_video_timings(sd, timings); 1474 err = configure_predefined_video_timings(sd, timings);
@@ -1483,18 +1501,18 @@ static int adv7842_g_dv_timings(struct v4l2_subdev *sd,
1483static void enable_input(struct v4l2_subdev *sd) 1501static void enable_input(struct v4l2_subdev *sd)
1484{ 1502{
1485 struct adv7842_state *state = to_state(sd); 1503 struct adv7842_state *state = to_state(sd);
1504
1505 set_rgb_quantization_range(sd);
1486 switch (state->mode) { 1506 switch (state->mode) {
1487 case ADV7842_MODE_SDP: 1507 case ADV7842_MODE_SDP:
1488 case ADV7842_MODE_COMP: 1508 case ADV7842_MODE_COMP:
1489 case ADV7842_MODE_RGB: 1509 case ADV7842_MODE_RGB:
1490 /* enable */
1491 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ 1510 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
1492 break; 1511 break;
1493 case ADV7842_MODE_HDMI: 1512 case ADV7842_MODE_HDMI:
1494 /* enable */
1495 hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
1496 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ 1513 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
1497 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ 1514 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
1515 hdmi_write_and_or(sd, 0x1a, 0xef, 0x00); /* Unmute audio */
1498 break; 1516 break;
1499 default: 1517 default:
1500 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", 1518 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
@@ -1505,9 +1523,9 @@ static void enable_input(struct v4l2_subdev *sd)
1505 1523
1506static void disable_input(struct v4l2_subdev *sd) 1524static void disable_input(struct v4l2_subdev *sd)
1507{ 1525{
1508 /* disable */ 1526 hdmi_write_and_or(sd, 0x1a, 0xef, 0x10); /* Mute audio [REF_01, c. 2.2.2] */
1527 msleep(16); /* 512 samples with >= 32 kHz sample rate [REF_03, c. 8.29] */
1509 io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */ 1528 io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */
1510 hdmi_write(sd, 0x1a, 0x1a); /* Mute audio */
1511 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ 1529 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
1512} 1530}
1513 1531
@@ -1575,9 +1593,6 @@ static void select_input(struct v4l2_subdev *sd,
1575 afe_write(sd, 0x00, 0x00); /* power up ADC */ 1593 afe_write(sd, 0x00, 0x00); /* power up ADC */
1576 afe_write(sd, 0xc8, 0x00); /* phase control */ 1594 afe_write(sd, 0xc8, 0x00); /* phase control */
1577 1595
1578 io_write(sd, 0x19, 0x83); /* LLC DLL phase */
1579 io_write(sd, 0x33, 0x40); /* LLC DLL enable */
1580
1581 io_write(sd, 0xdd, 0x90); /* Manual 2x output clock */ 1596 io_write(sd, 0xdd, 0x90); /* Manual 2x output clock */
1582 /* script says register 0xde, which don't exist in manual */ 1597 /* script says register 0xde, which don't exist in manual */
1583 1598
@@ -1611,8 +1626,6 @@ static void select_input(struct v4l2_subdev *sd,
1611 /* deinterlacer enabled and 3D comb */ 1626 /* deinterlacer enabled and 3D comb */
1612 sdp_write_and_or(sd, 0x12, 0xf6, 0x09); 1627 sdp_write_and_or(sd, 0x12, 0xf6, 0x09);
1613 1628
1614 sdp_write(sd, 0xdd, 0x08); /* free run auto */
1615
1616 break; 1629 break;
1617 1630
1618 case ADV7842_MODE_COMP: 1631 case ADV7842_MODE_COMP:
@@ -1627,6 +1640,13 @@ static void select_input(struct v4l2_subdev *sd,
1627 1640
1628 afe_write(sd, 0x00, 0x00); /* power up ADC */ 1641 afe_write(sd, 0x00, 0x00); /* power up ADC */
1629 afe_write(sd, 0xc8, 0x00); /* phase control */ 1642 afe_write(sd, 0xc8, 0x00); /* phase control */
1643 if (state->mode == ADV7842_MODE_COMP) {
1644 /* force to YCrCb */
1645 io_write_and_or(sd, 0x02, 0x0f, 0x60);
1646 } else {
1647 /* force to RGB */
1648 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1649 }
1630 1650
1631 /* set ADI recommended settings for digitizer */ 1651 /* set ADI recommended settings for digitizer */
1632 /* "ADV7842 Register Settings Recommendations 1652 /* "ADV7842 Register Settings Recommendations
@@ -1722,19 +1742,19 @@ static int adv7842_s_routing(struct v4l2_subdev *sd,
1722 1742
1723 switch (input) { 1743 switch (input) {
1724 case ADV7842_SELECT_HDMI_PORT_A: 1744 case ADV7842_SELECT_HDMI_PORT_A:
1725 /* TODO select HDMI_COMP or HDMI_GR */
1726 state->mode = ADV7842_MODE_HDMI; 1745 state->mode = ADV7842_MODE_HDMI;
1727 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P; 1746 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P;
1728 state->hdmi_port_a = true; 1747 state->hdmi_port_a = true;
1729 break; 1748 break;
1730 case ADV7842_SELECT_HDMI_PORT_B: 1749 case ADV7842_SELECT_HDMI_PORT_B:
1731 /* TODO select HDMI_COMP or HDMI_GR */
1732 state->mode = ADV7842_MODE_HDMI; 1750 state->mode = ADV7842_MODE_HDMI;
1733 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P; 1751 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P;
1734 state->hdmi_port_a = false; 1752 state->hdmi_port_a = false;
1735 break; 1753 break;
1736 case ADV7842_SELECT_VGA_COMP: 1754 case ADV7842_SELECT_VGA_COMP:
1737 v4l2_info(sd, "%s: VGA component: todo\n", __func__); 1755 state->mode = ADV7842_MODE_COMP;
1756 state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE;
1757 break;
1738 case ADV7842_SELECT_VGA_RGB: 1758 case ADV7842_SELECT_VGA_RGB:
1739 state->mode = ADV7842_MODE_RGB; 1759 state->mode = ADV7842_MODE_RGB;
1740 state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE; 1760 state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE;
@@ -1814,12 +1834,15 @@ static void adv7842_irq_enable(struct v4l2_subdev *sd, bool enable)
1814 io_write(sd, 0x78, 0x03); 1834 io_write(sd, 0x78, 0x03);
1815 /* Enable SDP Standard Detection Change and SDP Video Detected */ 1835 /* Enable SDP Standard Detection Change and SDP Video Detected */
1816 io_write(sd, 0xa0, 0x09); 1836 io_write(sd, 0xa0, 0x09);
1837 /* Enable HDMI_MODE interrupt */
1838 io_write(sd, 0x69, 0x08);
1817 } else { 1839 } else {
1818 io_write(sd, 0x46, 0x0); 1840 io_write(sd, 0x46, 0x0);
1819 io_write(sd, 0x5a, 0x0); 1841 io_write(sd, 0x5a, 0x0);
1820 io_write(sd, 0x73, 0x0); 1842 io_write(sd, 0x73, 0x0);
1821 io_write(sd, 0x78, 0x0); 1843 io_write(sd, 0x78, 0x0);
1822 io_write(sd, 0xa0, 0x0); 1844 io_write(sd, 0xa0, 0x0);
1845 io_write(sd, 0x69, 0x0);
1823 } 1846 }
1824} 1847}
1825 1848
@@ -1827,11 +1850,9 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1827{ 1850{
1828 struct adv7842_state *state = to_state(sd); 1851 struct adv7842_state *state = to_state(sd);
1829 u8 fmt_change_cp, fmt_change_digital, fmt_change_sdp; 1852 u8 fmt_change_cp, fmt_change_digital, fmt_change_sdp;
1830 u8 irq_status[5]; 1853 u8 irq_status[6];
1831 u8 irq_cfg = io_read(sd, 0x40);
1832 1854
1833 /* disable irq-pin output */ 1855 adv7842_irq_enable(sd, false);
1834 io_write(sd, 0x40, irq_cfg | 0x3);
1835 1856
1836 /* read status */ 1857 /* read status */
1837 irq_status[0] = io_read(sd, 0x43); 1858 irq_status[0] = io_read(sd, 0x43);
@@ -1839,6 +1860,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1839 irq_status[2] = io_read(sd, 0x70); 1860 irq_status[2] = io_read(sd, 0x70);
1840 irq_status[3] = io_read(sd, 0x75); 1861 irq_status[3] = io_read(sd, 0x75);
1841 irq_status[4] = io_read(sd, 0x9d); 1862 irq_status[4] = io_read(sd, 0x9d);
1863 irq_status[5] = io_read(sd, 0x66);
1842 1864
1843 /* and clear */ 1865 /* and clear */
1844 if (irq_status[0]) 1866 if (irq_status[0])
@@ -1851,10 +1873,14 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1851 io_write(sd, 0x76, irq_status[3]); 1873 io_write(sd, 0x76, irq_status[3]);
1852 if (irq_status[4]) 1874 if (irq_status[4])
1853 io_write(sd, 0x9e, irq_status[4]); 1875 io_write(sd, 0x9e, irq_status[4]);
1876 if (irq_status[5])
1877 io_write(sd, 0x67, irq_status[5]);
1854 1878
1855 v4l2_dbg(1, debug, sd, "%s: irq %x, %x, %x, %x, %x\n", __func__, 1879 adv7842_irq_enable(sd, true);
1880
1881 v4l2_dbg(1, debug, sd, "%s: irq %x, %x, %x, %x, %x, %x\n", __func__,
1856 irq_status[0], irq_status[1], irq_status[2], 1882 irq_status[0], irq_status[1], irq_status[2],
1857 irq_status[3], irq_status[4]); 1883 irq_status[3], irq_status[4], irq_status[5]);
1858 1884
1859 /* format change CP */ 1885 /* format change CP */
1860 fmt_change_cp = irq_status[0] & 0x9c; 1886 fmt_change_cp = irq_status[0] & 0x9c;
@@ -1871,25 +1897,72 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1871 else 1897 else
1872 fmt_change_digital = 0; 1898 fmt_change_digital = 0;
1873 1899
1874 /* notify */ 1900 /* format change */
1875 if (fmt_change_cp || fmt_change_digital || fmt_change_sdp) { 1901 if (fmt_change_cp || fmt_change_digital || fmt_change_sdp) {
1876 v4l2_dbg(1, debug, sd, 1902 v4l2_dbg(1, debug, sd,
1877 "%s: fmt_change_cp = 0x%x, fmt_change_digital = 0x%x, fmt_change_sdp = 0x%x\n", 1903 "%s: fmt_change_cp = 0x%x, fmt_change_digital = 0x%x, fmt_change_sdp = 0x%x\n",
1878 __func__, fmt_change_cp, fmt_change_digital, 1904 __func__, fmt_change_cp, fmt_change_digital,
1879 fmt_change_sdp); 1905 fmt_change_sdp);
1880 v4l2_subdev_notify(sd, ADV7842_FMT_CHANGE, NULL); 1906 v4l2_subdev_notify(sd, ADV7842_FMT_CHANGE, NULL);
1907 if (handled)
1908 *handled = true;
1881 } 1909 }
1882 1910
1883 /* 5v cable detect */ 1911 /* HDMI/DVI mode */
1884 if (irq_status[2]) 1912 if (irq_status[5] & 0x08) {
1913 v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__,
1914 (io_read(sd, 0x65) & 0x08) ? "HDMI" : "DVI");
1915 if (handled)
1916 *handled = true;
1917 }
1918
1919 /* tx 5v detect */
1920 if (irq_status[2] & 0x3) {
1921 v4l2_dbg(1, debug, sd, "%s: irq tx_5v\n", __func__);
1885 adv7842_s_detect_tx_5v_ctrl(sd); 1922 adv7842_s_detect_tx_5v_ctrl(sd);
1923 if (handled)
1924 *handled = true;
1925 }
1926 return 0;
1927}
1928
1929static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
1930{
1931 struct adv7842_state *state = to_state(sd);
1932 u8 *data = NULL;
1886 1933
1887 if (handled) 1934 if (edid->pad > ADV7842_EDID_PORT_VGA)
1888 *handled = true; 1935 return -EINVAL;
1936 if (edid->blocks == 0)
1937 return -EINVAL;
1938 if (edid->blocks > 2)
1939 return -EINVAL;
1940 if (edid->start_block > 1)
1941 return -EINVAL;
1942 if (edid->start_block == 1)
1943 edid->blocks = 1;
1944 if (!edid->edid)
1945 return -EINVAL;
1889 1946
1890 /* re-enable irq-pin output */ 1947 switch (edid->pad) {
1891 io_write(sd, 0x40, irq_cfg); 1948 case ADV7842_EDID_PORT_A:
1949 case ADV7842_EDID_PORT_B:
1950 if (state->hdmi_edid.present & (0x04 << edid->pad))
1951 data = state->hdmi_edid.edid;
1952 break;
1953 case ADV7842_EDID_PORT_VGA:
1954 if (state->vga_edid.present)
1955 data = state->vga_edid.edid;
1956 break;
1957 default:
1958 return -EINVAL;
1959 }
1960 if (!data)
1961 return -ENODATA;
1892 1962
1963 memcpy(edid->edid,
1964 data + edid->start_block * 128,
1965 edid->blocks * 128);
1893 return 0; 1966 return 0;
1894} 1967}
1895 1968
@@ -1898,7 +1971,7 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
1898 struct adv7842_state *state = to_state(sd); 1971 struct adv7842_state *state = to_state(sd);
1899 int err = 0; 1972 int err = 0;
1900 1973
1901 if (e->pad > 2) 1974 if (e->pad > ADV7842_EDID_PORT_VGA)
1902 return -EINVAL; 1975 return -EINVAL;
1903 if (e->start_block != 0) 1976 if (e->start_block != 0)
1904 return -EINVAL; 1977 return -EINVAL;
@@ -1911,20 +1984,25 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
1911 state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], 1984 state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
1912 e->edid[0x16]); 1985 e->edid[0x16]);
1913 1986
1914 if (e->pad == 2) { 1987 switch (e->pad) {
1988 case ADV7842_EDID_PORT_VGA:
1915 memset(&state->vga_edid.edid, 0, 256); 1989 memset(&state->vga_edid.edid, 0, 256);
1916 state->vga_edid.present = e->blocks ? 0x1 : 0x0; 1990 state->vga_edid.present = e->blocks ? 0x1 : 0x0;
1917 memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks); 1991 memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks);
1918 err = edid_write_vga_segment(sd); 1992 err = edid_write_vga_segment(sd);
1919 } else { 1993 break;
1920 u32 mask = 0x1<<e->pad; 1994 case ADV7842_EDID_PORT_A:
1995 case ADV7842_EDID_PORT_B:
1921 memset(&state->hdmi_edid.edid, 0, 256); 1996 memset(&state->hdmi_edid.edid, 0, 256);
1922 if (e->blocks) 1997 if (e->blocks)
1923 state->hdmi_edid.present |= mask; 1998 state->hdmi_edid.present |= 0x04 << e->pad;
1924 else 1999 else
1925 state->hdmi_edid.present &= ~mask; 2000 state->hdmi_edid.present &= ~(0x04 << e->pad);
1926 memcpy(&state->hdmi_edid.edid, e->edid, 128*e->blocks); 2001 memcpy(&state->hdmi_edid.edid, e->edid, 128 * e->blocks);
1927 err = edid_write_hdmi_segment(sd, e->pad); 2002 err = edid_write_hdmi_segment(sd, e->pad);
2003 break;
2004 default:
2005 return -EINVAL;
1928 } 2006 }
1929 if (err < 0) 2007 if (err < 0)
1930 v4l2_err(sd, "error %d writing edid on port %d\n", err, e->pad); 2008 v4l2_err(sd, "error %d writing edid on port %d\n", err, e->pad);
@@ -2156,7 +2234,7 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd)
2156 static const char * const input_color_space_txt[16] = { 2234 static const char * const input_color_space_txt[16] = {
2157 "RGB limited range (16-235)", "RGB full range (0-255)", 2235 "RGB limited range (16-235)", "RGB full range (0-255)",
2158 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)", 2236 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
2159 "XvYCC Bt.601", "XvYCC Bt.709", 2237 "xvYCC Bt.601", "xvYCC Bt.709",
2160 "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)", 2238 "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
2161 "invalid", "invalid", "invalid", "invalid", "invalid", 2239 "invalid", "invalid", "invalid", "invalid", "invalid",
2162 "invalid", "invalid", "automatic" 2240 "invalid", "invalid", "automatic"
@@ -2175,8 +2253,6 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd)
2175 2253
2176 v4l2_info(sd, "-----Chip status-----\n"); 2254 v4l2_info(sd, "-----Chip status-----\n");
2177 v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on"); 2255 v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on");
2178 v4l2_info(sd, "Connector type: %s\n", state->connector_hdmi ?
2179 "HDMI" : (is_digital_input(sd) ? "DVI-D" : "DVI-A"));
2180 v4l2_info(sd, "HDMI/DVI-D port selected: %s\n", 2256 v4l2_info(sd, "HDMI/DVI-D port selected: %s\n",
2181 state->hdmi_port_a ? "A" : "B"); 2257 state->hdmi_port_a ? "A" : "B");
2182 v4l2_info(sd, "EDID A %s, B %s\n", 2258 v4l2_info(sd, "EDID A %s, B %s\n",
@@ -2354,15 +2430,63 @@ static int adv7842_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
2354 return 0; 2430 return 0;
2355} 2431}
2356 2432
2433static void adv7842_s_sdp_io(struct v4l2_subdev *sd, struct adv7842_sdp_io_sync_adjustment *s)
2434{
2435 if (s && s->adjust) {
2436 sdp_io_write(sd, 0x94, (s->hs_beg >> 8) & 0xf);
2437 sdp_io_write(sd, 0x95, s->hs_beg & 0xff);
2438 sdp_io_write(sd, 0x96, (s->hs_width >> 8) & 0xf);
2439 sdp_io_write(sd, 0x97, s->hs_width & 0xff);
2440 sdp_io_write(sd, 0x98, (s->de_beg >> 8) & 0xf);
2441 sdp_io_write(sd, 0x99, s->de_beg & 0xff);
2442 sdp_io_write(sd, 0x9a, (s->de_end >> 8) & 0xf);
2443 sdp_io_write(sd, 0x9b, s->de_end & 0xff);
2444 sdp_io_write(sd, 0xa8, s->vs_beg_o);
2445 sdp_io_write(sd, 0xa9, s->vs_beg_e);
2446 sdp_io_write(sd, 0xaa, s->vs_end_o);
2447 sdp_io_write(sd, 0xab, s->vs_end_e);
2448 sdp_io_write(sd, 0xac, s->de_v_beg_o);
2449 sdp_io_write(sd, 0xad, s->de_v_beg_e);
2450 sdp_io_write(sd, 0xae, s->de_v_end_o);
2451 sdp_io_write(sd, 0xaf, s->de_v_end_e);
2452 } else {
2453 /* set to default */
2454 sdp_io_write(sd, 0x94, 0x00);
2455 sdp_io_write(sd, 0x95, 0x00);
2456 sdp_io_write(sd, 0x96, 0x00);
2457 sdp_io_write(sd, 0x97, 0x20);
2458 sdp_io_write(sd, 0x98, 0x00);
2459 sdp_io_write(sd, 0x99, 0x00);
2460 sdp_io_write(sd, 0x9a, 0x00);
2461 sdp_io_write(sd, 0x9b, 0x00);
2462 sdp_io_write(sd, 0xa8, 0x04);
2463 sdp_io_write(sd, 0xa9, 0x04);
2464 sdp_io_write(sd, 0xaa, 0x04);
2465 sdp_io_write(sd, 0xab, 0x04);
2466 sdp_io_write(sd, 0xac, 0x04);
2467 sdp_io_write(sd, 0xad, 0x04);
2468 sdp_io_write(sd, 0xae, 0x04);
2469 sdp_io_write(sd, 0xaf, 0x04);
2470 }
2471}
2472
2357static int adv7842_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) 2473static int adv7842_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
2358{ 2474{
2359 struct adv7842_state *state = to_state(sd); 2475 struct adv7842_state *state = to_state(sd);
2476 struct adv7842_platform_data *pdata = &state->pdata;
2360 2477
2361 v4l2_dbg(1, debug, sd, "%s:\n", __func__); 2478 v4l2_dbg(1, debug, sd, "%s:\n", __func__);
2362 2479
2363 if (state->mode != ADV7842_MODE_SDP) 2480 if (state->mode != ADV7842_MODE_SDP)
2364 return -ENODATA; 2481 return -ENODATA;
2365 2482
2483 if (norm & V4L2_STD_625_50)
2484 adv7842_s_sdp_io(sd, &pdata->sdp_io_sync_625);
2485 else if (norm & V4L2_STD_525_60)
2486 adv7842_s_sdp_io(sd, &pdata->sdp_io_sync_525);
2487 else
2488 adv7842_s_sdp_io(sd, NULL);
2489
2366 if (norm & V4L2_STD_ALL) { 2490 if (norm & V4L2_STD_ALL) {
2367 state->norm = norm; 2491 state->norm = norm;
2368 return 0; 2492 return 0;
@@ -2385,9 +2509,10 @@ static int adv7842_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
2385 2509
2386/* ----------------------------------------------------------------------- */ 2510/* ----------------------------------------------------------------------- */
2387 2511
2388static int adv7842_core_init(struct v4l2_subdev *sd, 2512static int adv7842_core_init(struct v4l2_subdev *sd)
2389 const struct adv7842_platform_data *pdata)
2390{ 2513{
2514 struct adv7842_state *state = to_state(sd);
2515 struct adv7842_platform_data *pdata = &state->pdata;
2391 hdmi_write(sd, 0x48, 2516 hdmi_write(sd, 0x48,
2392 (pdata->disable_pwrdnb ? 0x80 : 0) | 2517 (pdata->disable_pwrdnb ? 0x80 : 0) |
2393 (pdata->disable_cable_det_rst ? 0x40 : 0)); 2518 (pdata->disable_cable_det_rst ? 0x40 : 0));
@@ -2400,7 +2525,7 @@ static int adv7842_core_init(struct v4l2_subdev *sd,
2400 2525
2401 /* video format */ 2526 /* video format */
2402 io_write(sd, 0x02, 2527 io_write(sd, 0x02,
2403 pdata->inp_color_space << 4 | 2528 0xf0 |
2404 pdata->alt_gamma << 3 | 2529 pdata->alt_gamma << 3 |
2405 pdata->op_656_range << 2 | 2530 pdata->op_656_range << 2 |
2406 pdata->rgb_out << 1 | 2531 pdata->rgb_out << 1 |
@@ -2412,13 +2537,24 @@ static int adv7842_core_init(struct v4l2_subdev *sd,
2412 pdata->replicate_av_codes << 1 | 2537 pdata->replicate_av_codes << 1 |
2413 pdata->invert_cbcr << 0); 2538 pdata->invert_cbcr << 0);
2414 2539
2540 /* HDMI audio */
2541 hdmi_write_and_or(sd, 0x1a, 0xf1, 0x08); /* Wait 1 s before unmute */
2542
2415 /* Drive strength */ 2543 /* Drive strength */
2416 io_write_and_or(sd, 0x14, 0xc0, pdata->drive_strength.data<<4 | 2544 io_write_and_or(sd, 0x14, 0xc0,
2417 pdata->drive_strength.clock<<2 | 2545 pdata->dr_str_data << 4 |
2418 pdata->drive_strength.sync); 2546 pdata->dr_str_clk << 2 |
2547 pdata->dr_str_sync);
2419 2548
2420 /* HDMI free run */ 2549 /* HDMI free run */
2421 cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); 2550 cp_write_and_or(sd, 0xba, 0xfc, pdata->hdmi_free_run_enable |
2551 (pdata->hdmi_free_run_mode << 1));
2552
2553 /* SPD free run */
2554 sdp_write_and_or(sd, 0xdd, 0xf0, pdata->sdp_free_run_force |
2555 (pdata->sdp_free_run_cbar_en << 1) |
2556 (pdata->sdp_free_run_man_col_en << 2) |
2557 (pdata->sdp_free_run_force << 3));
2422 2558
2423 /* TODO from platform data */ 2559 /* TODO from platform data */
2424 cp_write(sd, 0x69, 0x14); /* Enable CP CSC */ 2560 cp_write(sd, 0x69, 0x14); /* Enable CP CSC */
@@ -2431,18 +2567,6 @@ static int adv7842_core_init(struct v4l2_subdev *sd,
2431 2567
2432 sdp_csc_coeff(sd, &pdata->sdp_csc_coeff); 2568 sdp_csc_coeff(sd, &pdata->sdp_csc_coeff);
2433 2569
2434 if (pdata->sdp_io_sync.adjust) {
2435 const struct adv7842_sdp_io_sync_adjustment *s = &pdata->sdp_io_sync;
2436 sdp_io_write(sd, 0x94, (s->hs_beg>>8) & 0xf);
2437 sdp_io_write(sd, 0x95, s->hs_beg & 0xff);
2438 sdp_io_write(sd, 0x96, (s->hs_width>>8) & 0xf);
2439 sdp_io_write(sd, 0x97, s->hs_width & 0xff);
2440 sdp_io_write(sd, 0x98, (s->de_beg>>8) & 0xf);
2441 sdp_io_write(sd, 0x99, s->de_beg & 0xff);
2442 sdp_io_write(sd, 0x9a, (s->de_end>>8) & 0xf);
2443 sdp_io_write(sd, 0x9b, s->de_end & 0xff);
2444 }
2445
2446 /* todo, improve settings for sdram */ 2570 /* todo, improve settings for sdram */
2447 if (pdata->sd_ram_size >= 128) { 2571 if (pdata->sd_ram_size >= 128) {
2448 sdp_write(sd, 0x12, 0x0d); /* Frame TBC,3D comb enabled */ 2572 sdp_write(sd, 0x12, 0x0d); /* Frame TBC,3D comb enabled */
@@ -2483,12 +2607,11 @@ static int adv7842_core_init(struct v4l2_subdev *sd,
2483 io_write_and_or(sd, 0x20, 0xcf, 0x00); 2607 io_write_and_or(sd, 0x20, 0xcf, 0x00);
2484 2608
2485 /* LLC */ 2609 /* LLC */
2486 /* Set phase to 16. TODO: get this from platform_data */ 2610 io_write(sd, 0x19, 0x80 | pdata->llc_dll_phase);
2487 io_write(sd, 0x19, 0x90);
2488 io_write(sd, 0x33, 0x40); 2611 io_write(sd, 0x33, 0x40);
2489 2612
2490 /* interrupts */ 2613 /* interrupts */
2491 io_write(sd, 0x40, 0xe2); /* Configure INT1 */ 2614 io_write(sd, 0x40, 0xf2); /* Configure INT1 */
2492 2615
2493 adv7842_irq_enable(sd, true); 2616 adv7842_irq_enable(sd, true);
2494 2617
@@ -2588,6 +2711,7 @@ static int adv7842_command_ram_test(struct v4l2_subdev *sd)
2588 struct i2c_client *client = v4l2_get_subdevdata(sd); 2711 struct i2c_client *client = v4l2_get_subdevdata(sd);
2589 struct adv7842_state *state = to_state(sd); 2712 struct adv7842_state *state = to_state(sd);
2590 struct adv7842_platform_data *pdata = client->dev.platform_data; 2713 struct adv7842_platform_data *pdata = client->dev.platform_data;
2714 struct v4l2_dv_timings timings;
2591 int ret = 0; 2715 int ret = 0;
2592 2716
2593 if (!pdata) 2717 if (!pdata)
@@ -2610,7 +2734,7 @@ static int adv7842_command_ram_test(struct v4l2_subdev *sd)
2610 adv7842_rewrite_i2c_addresses(sd, pdata); 2734 adv7842_rewrite_i2c_addresses(sd, pdata);
2611 2735
2612 /* and re-init chip and state */ 2736 /* and re-init chip and state */
2613 adv7842_core_init(sd, pdata); 2737 adv7842_core_init(sd);
2614 2738
2615 disable_input(sd); 2739 disable_input(sd);
2616 2740
@@ -2618,11 +2742,15 @@ static int adv7842_command_ram_test(struct v4l2_subdev *sd)
2618 2742
2619 enable_input(sd); 2743 enable_input(sd);
2620 2744
2621 adv7842_s_dv_timings(sd, &state->timings);
2622
2623 edid_write_vga_segment(sd); 2745 edid_write_vga_segment(sd);
2624 edid_write_hdmi_segment(sd, 0); 2746 edid_write_hdmi_segment(sd, ADV7842_EDID_PORT_A);
2625 edid_write_hdmi_segment(sd, 1); 2747 edid_write_hdmi_segment(sd, ADV7842_EDID_PORT_B);
2748
2749 timings = state->timings;
2750
2751 memset(&state->timings, 0, sizeof(struct v4l2_dv_timings));
2752
2753 adv7842_s_dv_timings(sd, &timings);
2626 2754
2627 return ret; 2755 return ret;
2628} 2756}
@@ -2670,6 +2798,7 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = {
2670}; 2798};
2671 2799
2672static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { 2800static const struct v4l2_subdev_pad_ops adv7842_pad_ops = {
2801 .get_edid = adv7842_get_edid,
2673 .set_edid = adv7842_set_edid, 2802 .set_edid = adv7842_set_edid,
2674}; 2803};
2675 2804
@@ -2712,8 +2841,9 @@ static const struct v4l2_ctrl_config adv7842_ctrl_free_run_color = {
2712}; 2841};
2713 2842
2714 2843
2715static void adv7842_unregister_clients(struct adv7842_state *state) 2844static void adv7842_unregister_clients(struct v4l2_subdev *sd)
2716{ 2845{
2846 struct adv7842_state *state = to_state(sd);
2717 if (state->i2c_avlink) 2847 if (state->i2c_avlink)
2718 i2c_unregister_device(state->i2c_avlink); 2848 i2c_unregister_device(state->i2c_avlink);
2719 if (state->i2c_cec) 2849 if (state->i2c_cec)
@@ -2736,21 +2866,79 @@ static void adv7842_unregister_clients(struct adv7842_state *state)
2736 i2c_unregister_device(state->i2c_cp); 2866 i2c_unregister_device(state->i2c_cp);
2737 if (state->i2c_vdp) 2867 if (state->i2c_vdp)
2738 i2c_unregister_device(state->i2c_vdp); 2868 i2c_unregister_device(state->i2c_vdp);
2869
2870 state->i2c_avlink = NULL;
2871 state->i2c_cec = NULL;
2872 state->i2c_infoframe = NULL;
2873 state->i2c_sdp_io = NULL;
2874 state->i2c_sdp = NULL;
2875 state->i2c_afe = NULL;
2876 state->i2c_repeater = NULL;
2877 state->i2c_edid = NULL;
2878 state->i2c_hdmi = NULL;
2879 state->i2c_cp = NULL;
2880 state->i2c_vdp = NULL;
2739} 2881}
2740 2882
2741static struct i2c_client *adv7842_dummy_client(struct v4l2_subdev *sd, 2883static struct i2c_client *adv7842_dummy_client(struct v4l2_subdev *sd, const char *desc,
2742 u8 addr, u8 io_reg) 2884 u8 addr, u8 io_reg)
2743{ 2885{
2744 struct i2c_client *client = v4l2_get_subdevdata(sd); 2886 struct i2c_client *client = v4l2_get_subdevdata(sd);
2887 struct i2c_client *cp;
2745 2888
2746 io_write(sd, io_reg, addr << 1); 2889 io_write(sd, io_reg, addr << 1);
2747 return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); 2890
2891 if (addr == 0) {
2892 v4l2_err(sd, "no %s i2c addr configured\n", desc);
2893 return NULL;
2894 }
2895
2896 cp = i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1);
2897 if (!cp)
2898 v4l2_err(sd, "register %s on i2c addr 0x%x failed\n", desc, addr);
2899
2900 return cp;
2901}
2902
2903static int adv7842_register_clients(struct v4l2_subdev *sd)
2904{
2905 struct adv7842_state *state = to_state(sd);
2906 struct adv7842_platform_data *pdata = &state->pdata;
2907
2908 state->i2c_avlink = adv7842_dummy_client(sd, "avlink", pdata->i2c_avlink, 0xf3);
2909 state->i2c_cec = adv7842_dummy_client(sd, "cec", pdata->i2c_cec, 0xf4);
2910 state->i2c_infoframe = adv7842_dummy_client(sd, "infoframe", pdata->i2c_infoframe, 0xf5);
2911 state->i2c_sdp_io = adv7842_dummy_client(sd, "sdp_io", pdata->i2c_sdp_io, 0xf2);
2912 state->i2c_sdp = adv7842_dummy_client(sd, "sdp", pdata->i2c_sdp, 0xf1);
2913 state->i2c_afe = adv7842_dummy_client(sd, "afe", pdata->i2c_afe, 0xf8);
2914 state->i2c_repeater = adv7842_dummy_client(sd, "repeater", pdata->i2c_repeater, 0xf9);
2915 state->i2c_edid = adv7842_dummy_client(sd, "edid", pdata->i2c_edid, 0xfa);
2916 state->i2c_hdmi = adv7842_dummy_client(sd, "hdmi", pdata->i2c_hdmi, 0xfb);
2917 state->i2c_cp = adv7842_dummy_client(sd, "cp", pdata->i2c_cp, 0xfd);
2918 state->i2c_vdp = adv7842_dummy_client(sd, "vdp", pdata->i2c_vdp, 0xfe);
2919
2920 if (!state->i2c_avlink ||
2921 !state->i2c_cec ||
2922 !state->i2c_infoframe ||
2923 !state->i2c_sdp_io ||
2924 !state->i2c_sdp ||
2925 !state->i2c_afe ||
2926 !state->i2c_repeater ||
2927 !state->i2c_edid ||
2928 !state->i2c_hdmi ||
2929 !state->i2c_cp ||
2930 !state->i2c_vdp)
2931 return -1;
2932
2933 return 0;
2748} 2934}
2749 2935
2750static int adv7842_probe(struct i2c_client *client, 2936static int adv7842_probe(struct i2c_client *client,
2751 const struct i2c_device_id *id) 2937 const struct i2c_device_id *id)
2752{ 2938{
2753 struct adv7842_state *state; 2939 struct adv7842_state *state;
2940 static const struct v4l2_dv_timings cea640x480 =
2941 V4L2_DV_BT_CEA_640X480P59_94;
2754 struct adv7842_platform_data *pdata = client->dev.platform_data; 2942 struct adv7842_platform_data *pdata = client->dev.platform_data;
2755 struct v4l2_ctrl_handler *hdl; 2943 struct v4l2_ctrl_handler *hdl;
2756 struct v4l2_subdev *sd; 2944 struct v4l2_subdev *sd;
@@ -2775,13 +2963,17 @@ static int adv7842_probe(struct i2c_client *client,
2775 return -ENOMEM; 2963 return -ENOMEM;
2776 } 2964 }
2777 2965
2966 /* platform data */
2967 state->pdata = *pdata;
2968 state->timings = cea640x480;
2969
2778 sd = &state->sd; 2970 sd = &state->sd;
2779 v4l2_i2c_subdev_init(sd, client, &adv7842_ops); 2971 v4l2_i2c_subdev_init(sd, client, &adv7842_ops);
2780 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 2972 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2781 state->connector_hdmi = pdata->connector_hdmi;
2782 state->mode = pdata->mode; 2973 state->mode = pdata->mode;
2783 2974
2784 state->hdmi_port_a = true; 2975 state->hdmi_port_a = pdata->input == ADV7842_SELECT_HDMI_PORT_A;
2976 state->restart_stdi_once = true;
2785 2977
2786 /* i2c access to adv7842? */ 2978 /* i2c access to adv7842? */
2787 rev = adv_smbus_read_byte_data_check(client, 0xea, false) << 8 | 2979 rev = adv_smbus_read_byte_data_check(client, 0xea, false) << 8 |
@@ -2843,21 +3035,7 @@ static int adv7842_probe(struct i2c_client *client,
2843 goto err_hdl; 3035 goto err_hdl;
2844 } 3036 }
2845 3037
2846 state->i2c_avlink = adv7842_dummy_client(sd, pdata->i2c_avlink, 0xf3); 3038 if (adv7842_register_clients(sd) < 0) {
2847 state->i2c_cec = adv7842_dummy_client(sd, pdata->i2c_cec, 0xf4);
2848 state->i2c_infoframe = adv7842_dummy_client(sd, pdata->i2c_infoframe, 0xf5);
2849 state->i2c_sdp_io = adv7842_dummy_client(sd, pdata->i2c_sdp_io, 0xf2);
2850 state->i2c_sdp = adv7842_dummy_client(sd, pdata->i2c_sdp, 0xf1);
2851 state->i2c_afe = adv7842_dummy_client(sd, pdata->i2c_afe, 0xf8);
2852 state->i2c_repeater = adv7842_dummy_client(sd, pdata->i2c_repeater, 0xf9);
2853 state->i2c_edid = adv7842_dummy_client(sd, pdata->i2c_edid, 0xfa);
2854 state->i2c_hdmi = adv7842_dummy_client(sd, pdata->i2c_hdmi, 0xfb);
2855 state->i2c_cp = adv7842_dummy_client(sd, pdata->i2c_cp, 0xfd);
2856 state->i2c_vdp = adv7842_dummy_client(sd, pdata->i2c_vdp, 0xfe);
2857 if (!state->i2c_avlink || !state->i2c_cec || !state->i2c_infoframe ||
2858 !state->i2c_sdp_io || !state->i2c_sdp || !state->i2c_afe ||
2859 !state->i2c_repeater || !state->i2c_edid || !state->i2c_hdmi ||
2860 !state->i2c_cp || !state->i2c_vdp) {
2861 err = -ENOMEM; 3039 err = -ENOMEM;
2862 v4l2_err(sd, "failed to create all i2c clients\n"); 3040 v4l2_err(sd, "failed to create all i2c clients\n");
2863 goto err_i2c; 3041 goto err_i2c;
@@ -2879,7 +3057,7 @@ static int adv7842_probe(struct i2c_client *client,
2879 if (err) 3057 if (err)
2880 goto err_work_queues; 3058 goto err_work_queues;
2881 3059
2882 err = adv7842_core_init(sd, pdata); 3060 err = adv7842_core_init(sd);
2883 if (err) 3061 if (err)
2884 goto err_entity; 3062 goto err_entity;
2885 3063
@@ -2893,7 +3071,7 @@ err_work_queues:
2893 cancel_delayed_work(&state->delayed_work_enable_hotplug); 3071 cancel_delayed_work(&state->delayed_work_enable_hotplug);
2894 destroy_workqueue(state->work_queues); 3072 destroy_workqueue(state->work_queues);
2895err_i2c: 3073err_i2c:
2896 adv7842_unregister_clients(state); 3074 adv7842_unregister_clients(sd);
2897err_hdl: 3075err_hdl:
2898 v4l2_ctrl_handler_free(hdl); 3076 v4l2_ctrl_handler_free(hdl);
2899 return err; 3077 return err;
@@ -2912,7 +3090,7 @@ static int adv7842_remove(struct i2c_client *client)
2912 destroy_workqueue(state->work_queues); 3090 destroy_workqueue(state->work_queues);
2913 v4l2_device_unregister_subdev(sd); 3091 v4l2_device_unregister_subdev(sd);
2914 media_entity_cleanup(&sd->entity); 3092 media_entity_cleanup(&sd->entity);
2915 adv7842_unregister_clients(to_state(sd)); 3093 adv7842_unregister_clients(sd);
2916 v4l2_ctrl_handler_free(sd->ctrl_handler); 3094 v4l2_ctrl_handler_free(sd->ctrl_handler);
2917 return 0; 3095 return 0;
2918} 3096}
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 3317a9ae3961..d98ca3aebe23 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -172,28 +172,28 @@ static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash,
172static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) 172static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
173{ 173{
174 struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); 174 struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
175 int rval = -EINVAL;
175 176
176 mutex_lock(&flash->lock); 177 mutex_lock(&flash->lock);
177 178
178 if (ctrl->id == V4L2_CID_FLASH_FAULT) { 179 if (ctrl->id == V4L2_CID_FLASH_FAULT) {
179 int rval;
180 s32 fault = 0; 180 s32 fault = 0;
181 unsigned int reg_val; 181 unsigned int reg_val;
182 rval = regmap_read(flash->regmap, REG_FLAG, &reg_val); 182 rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
183 if (rval < 0) 183 if (rval < 0)
184 return rval; 184 goto out;
185 if (rval & FAULT_SHORT_CIRCUIT) 185 if (reg_val & FAULT_SHORT_CIRCUIT)
186 fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; 186 fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
187 if (rval & FAULT_OVERTEMP) 187 if (reg_val & FAULT_OVERTEMP)
188 fault |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; 188 fault |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
189 if (rval & FAULT_TIMEOUT) 189 if (reg_val & FAULT_TIMEOUT)
190 fault |= V4L2_FLASH_FAULT_TIMEOUT; 190 fault |= V4L2_FLASH_FAULT_TIMEOUT;
191 ctrl->cur.val = fault; 191 ctrl->cur.val = fault;
192 return 0;
193 } 192 }
194 193
194out:
195 mutex_unlock(&flash->lock); 195 mutex_unlock(&flash->lock);
196 return -EINVAL; 196 return rval;
197} 197}
198 198
199static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) 199static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
@@ -219,15 +219,19 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
219 break; 219 break;
220 220
221 case V4L2_CID_FLASH_STROBE: 221 case V4L2_CID_FLASH_STROBE:
222 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) 222 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
223 return -EBUSY; 223 rval = -EBUSY;
224 goto err_out;
225 }
224 flash->led_mode = V4L2_FLASH_LED_MODE_FLASH; 226 flash->led_mode = V4L2_FLASH_LED_MODE_FLASH;
225 rval = lm3560_mode_ctrl(flash); 227 rval = lm3560_mode_ctrl(flash);
226 break; 228 break;
227 229
228 case V4L2_CID_FLASH_STROBE_STOP: 230 case V4L2_CID_FLASH_STROBE_STOP:
229 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) 231 if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
230 return -EBUSY; 232 rval = -EBUSY;
233 goto err_out;
234 }
231 flash->led_mode = V4L2_FLASH_LED_MODE_NONE; 235 flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
232 rval = lm3560_mode_ctrl(flash); 236 rval = lm3560_mode_ctrl(flash);
233 break; 237 break;
@@ -247,8 +251,8 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
247 break; 251 break;
248 } 252 }
249 253
250 mutex_unlock(&flash->lock);
251err_out: 254err_out:
255 mutex_unlock(&flash->lock);
252 return rval; 256 return rval;
253} 257}
254 258
@@ -444,14 +448,14 @@ static int lm3560_probe(struct i2c_client *client,
444 if (rval < 0) 448 if (rval < 0)
445 return rval; 449 return rval;
446 450
451 i2c_set_clientdata(client, flash);
452
447 return 0; 453 return 0;
448} 454}
449 455
450static int lm3560_remove(struct i2c_client *client) 456static int lm3560_remove(struct i2c_client *client)
451{ 457{
452 struct v4l2_subdev *subdev = i2c_get_clientdata(client); 458 struct lm3560_flash *flash = i2c_get_clientdata(client);
453 struct lm3560_flash *flash = container_of(subdev, struct lm3560_flash,
454 subdev_led[LM3560_LED_MAX]);
455 unsigned int i; 459 unsigned int i;
456 460
457 for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) { 461 for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) {
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index 846b15f0bf64..85ec3bacdf1c 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -459,13 +459,15 @@ static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev,
459 MT9M032_COLUMN_START_MAX); 459 MT9M032_COLUMN_START_MAX);
460 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN, 460 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN,
461 MT9M032_ROW_START_MAX); 461 MT9M032_ROW_START_MAX);
462 rect.width = clamp(ALIGN(crop->rect.width, 2), MT9M032_COLUMN_SIZE_MIN, 462 rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2),
463 MT9M032_COLUMN_SIZE_MAX); 463 MT9M032_COLUMN_SIZE_MIN, MT9M032_COLUMN_SIZE_MAX);
464 rect.height = clamp(ALIGN(crop->rect.height, 2), MT9M032_ROW_SIZE_MIN, 464 rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2),
465 MT9M032_ROW_SIZE_MAX); 465 MT9M032_ROW_SIZE_MIN, MT9M032_ROW_SIZE_MAX);
466 466
467 rect.width = min(rect.width, MT9M032_PIXEL_ARRAY_WIDTH - rect.left); 467 rect.width = min_t(unsigned int, rect.width,
468 rect.height = min(rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top); 468 MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
469 rect.height = min_t(unsigned int, rect.height,
470 MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);
469 471
470 __crop = __mt9m032_get_pad_crop(sensor, fh, crop->which); 472 __crop = __mt9m032_get_pad_crop(sensor, fh, crop->which);
471 473
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 1c2303d18bf4..e5ddf47030fd 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -519,11 +519,13 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev,
519 519
520 /* Clamp the width and height to avoid dividing by zero. */ 520 /* Clamp the width and height to avoid dividing by zero. */
521 width = clamp_t(unsigned int, ALIGN(format->format.width, 2), 521 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
522 max(__crop->width / 7, MT9P031_WINDOW_WIDTH_MIN), 522 max_t(unsigned int, __crop->width / 7,
523 MT9P031_WINDOW_WIDTH_MIN),
523 __crop->width); 524 __crop->width);
524 height = clamp_t(unsigned int, ALIGN(format->format.height, 2), 525 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
525 max(__crop->height / 8, MT9P031_WINDOW_HEIGHT_MIN), 526 max_t(unsigned int, __crop->height / 8,
526 __crop->height); 527 MT9P031_WINDOW_HEIGHT_MIN),
528 __crop->height);
527 529
528 hratio = DIV_ROUND_CLOSEST(__crop->width, width); 530 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
529 vratio = DIV_ROUND_CLOSEST(__crop->height, height); 531 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
@@ -565,15 +567,17 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev,
565 MT9P031_COLUMN_START_MAX); 567 MT9P031_COLUMN_START_MAX);
566 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9P031_ROW_START_MIN, 568 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9P031_ROW_START_MIN,
567 MT9P031_ROW_START_MAX); 569 MT9P031_ROW_START_MAX);
568 rect.width = clamp(ALIGN(crop->rect.width, 2), 570 rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2),
569 MT9P031_WINDOW_WIDTH_MIN, 571 MT9P031_WINDOW_WIDTH_MIN,
570 MT9P031_WINDOW_WIDTH_MAX); 572 MT9P031_WINDOW_WIDTH_MAX);
571 rect.height = clamp(ALIGN(crop->rect.height, 2), 573 rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2),
572 MT9P031_WINDOW_HEIGHT_MIN, 574 MT9P031_WINDOW_HEIGHT_MIN,
573 MT9P031_WINDOW_HEIGHT_MAX); 575 MT9P031_WINDOW_HEIGHT_MAX);
574 576
575 rect.width = min(rect.width, MT9P031_PIXEL_ARRAY_WIDTH - rect.left); 577 rect.width = min_t(unsigned int, rect.width,
576 rect.height = min(rect.height, MT9P031_PIXEL_ARRAY_HEIGHT - rect.top); 578 MT9P031_PIXEL_ARRAY_WIDTH - rect.left);
579 rect.height = min_t(unsigned int, rect.height,
580 MT9P031_PIXEL_ARRAY_HEIGHT - rect.top);
577 581
578 __crop = __mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which); 582 __crop = __mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which);
579 583
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 796463466ef0..d41c70eaf838 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -291,10 +291,12 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev,
291 291
292 /* Clamp the width and height to avoid dividing by zero. */ 292 /* Clamp the width and height to avoid dividing by zero. */
293 width = clamp_t(unsigned int, ALIGN(format->format.width, 2), 293 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
294 max(__crop->width / 8, MT9T001_WINDOW_HEIGHT_MIN + 1), 294 max_t(unsigned int, __crop->width / 8,
295 MT9T001_WINDOW_HEIGHT_MIN + 1),
295 __crop->width); 296 __crop->width);
296 height = clamp_t(unsigned int, ALIGN(format->format.height, 2), 297 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
297 max(__crop->height / 8, MT9T001_WINDOW_HEIGHT_MIN + 1), 298 max_t(unsigned int, __crop->height / 8,
299 MT9T001_WINDOW_HEIGHT_MIN + 1),
298 __crop->height); 300 __crop->height);
299 301
300 hratio = DIV_ROUND_CLOSEST(__crop->width, width); 302 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
@@ -339,15 +341,17 @@ static int mt9t001_set_crop(struct v4l2_subdev *subdev,
339 rect.top = clamp(ALIGN(crop->rect.top, 2), 341 rect.top = clamp(ALIGN(crop->rect.top, 2),
340 MT9T001_ROW_START_MIN, 342 MT9T001_ROW_START_MIN,
341 MT9T001_ROW_START_MAX); 343 MT9T001_ROW_START_MAX);
342 rect.width = clamp(ALIGN(crop->rect.width, 2), 344 rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2),
343 MT9T001_WINDOW_WIDTH_MIN + 1, 345 MT9T001_WINDOW_WIDTH_MIN + 1,
344 MT9T001_WINDOW_WIDTH_MAX + 1); 346 MT9T001_WINDOW_WIDTH_MAX + 1);
345 rect.height = clamp(ALIGN(crop->rect.height, 2), 347 rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2),
346 MT9T001_WINDOW_HEIGHT_MIN + 1, 348 MT9T001_WINDOW_HEIGHT_MIN + 1,
347 MT9T001_WINDOW_HEIGHT_MAX + 1); 349 MT9T001_WINDOW_HEIGHT_MAX + 1);
348 350
349 rect.width = min(rect.width, MT9T001_PIXEL_ARRAY_WIDTH - rect.left); 351 rect.width = min_t(unsigned int, rect.width,
350 rect.height = min(rect.height, MT9T001_PIXEL_ARRAY_HEIGHT - rect.top); 352 MT9T001_PIXEL_ARRAY_WIDTH - rect.left);
353 rect.height = min_t(unsigned int, rect.height,
354 MT9T001_PIXEL_ARRAY_HEIGHT - rect.top);
351 355
352 __crop = __mt9t001_get_pad_crop(mt9t001, fh, crop->pad, crop->which); 356 __crop = __mt9t001_get_pad_crop(mt9t001, fh, crop->pad, crop->which);
353 357
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 2c50effaa334..36c504b78f2c 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -27,14 +27,16 @@
27#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>
28#include <media/v4l2-subdev.h> 28#include <media/v4l2-subdev.h>
29 29
30#define MT9V032_PIXEL_ARRAY_HEIGHT 492 30/* The first four rows are black rows. The active area spans 753x481 pixels. */
31#define MT9V032_PIXEL_ARRAY_WIDTH 782 31#define MT9V032_PIXEL_ARRAY_HEIGHT 485
32#define MT9V032_PIXEL_ARRAY_WIDTH 753
32 33
33#define MT9V032_SYSCLK_FREQ_DEF 26600000 34#define MT9V032_SYSCLK_FREQ_DEF 26600000
34 35
35#define MT9V032_CHIP_VERSION 0x00 36#define MT9V032_CHIP_VERSION 0x00
36#define MT9V032_CHIP_ID_REV1 0x1311 37#define MT9V032_CHIP_ID_REV1 0x1311
37#define MT9V032_CHIP_ID_REV3 0x1313 38#define MT9V032_CHIP_ID_REV3 0x1313
39#define MT9V034_CHIP_ID_REV1 0X1324
38#define MT9V032_COLUMN_START 0x01 40#define MT9V032_COLUMN_START 0x01
39#define MT9V032_COLUMN_START_MIN 1 41#define MT9V032_COLUMN_START_MIN 1
40#define MT9V032_COLUMN_START_DEF 1 42#define MT9V032_COLUMN_START_DEF 1
@@ -53,12 +55,15 @@
53#define MT9V032_WINDOW_WIDTH_MAX 752 55#define MT9V032_WINDOW_WIDTH_MAX 752
54#define MT9V032_HORIZONTAL_BLANKING 0x05 56#define MT9V032_HORIZONTAL_BLANKING 0x05
55#define MT9V032_HORIZONTAL_BLANKING_MIN 43 57#define MT9V032_HORIZONTAL_BLANKING_MIN 43
58#define MT9V034_HORIZONTAL_BLANKING_MIN 61
56#define MT9V032_HORIZONTAL_BLANKING_DEF 94 59#define MT9V032_HORIZONTAL_BLANKING_DEF 94
57#define MT9V032_HORIZONTAL_BLANKING_MAX 1023 60#define MT9V032_HORIZONTAL_BLANKING_MAX 1023
58#define MT9V032_VERTICAL_BLANKING 0x06 61#define MT9V032_VERTICAL_BLANKING 0x06
59#define MT9V032_VERTICAL_BLANKING_MIN 4 62#define MT9V032_VERTICAL_BLANKING_MIN 4
63#define MT9V034_VERTICAL_BLANKING_MIN 2
60#define MT9V032_VERTICAL_BLANKING_DEF 45 64#define MT9V032_VERTICAL_BLANKING_DEF 45
61#define MT9V032_VERTICAL_BLANKING_MAX 3000 65#define MT9V032_VERTICAL_BLANKING_MAX 3000
66#define MT9V034_VERTICAL_BLANKING_MAX 32288
62#define MT9V032_CHIP_CONTROL 0x07 67#define MT9V032_CHIP_CONTROL 0x07
63#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3) 68#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
64#define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7) 69#define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7)
@@ -68,8 +73,10 @@
68#define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a 73#define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a
69#define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b 74#define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b
70#define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1 75#define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1
76#define MT9V034_TOTAL_SHUTTER_WIDTH_MIN 0
71#define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480 77#define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480
72#define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767 78#define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767
79#define MT9V034_TOTAL_SHUTTER_WIDTH_MAX 32765
73#define MT9V032_RESET 0x0c 80#define MT9V032_RESET 0x0c
74#define MT9V032_READ_MODE 0x0d 81#define MT9V032_READ_MODE 0x0d
75#define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0) 82#define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0)
@@ -81,6 +88,8 @@
81#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6) 88#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
82#define MT9V032_READ_MODE_DARK_ROWS (1 << 7) 89#define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
83#define MT9V032_PIXEL_OPERATION_MODE 0x0f 90#define MT9V032_PIXEL_OPERATION_MODE 0x0f
91#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 0)
92#define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 1)
84#define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2) 93#define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2)
85#define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6) 94#define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6)
86#define MT9V032_ANALOG_GAIN 0x35 95#define MT9V032_ANALOG_GAIN 0x35
@@ -96,9 +105,12 @@
96#define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8) 105#define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8)
97#define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8 106#define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8
98#define MT9V032_ROW_NOISE_CORR_CONTROL 0x70 107#define MT9V032_ROW_NOISE_CORR_CONTROL 0x70
108#define MT9V034_ROW_NOISE_CORR_ENABLE (1 << 0)
109#define MT9V034_ROW_NOISE_CORR_USE_BLK_AVG (1 << 1)
99#define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5) 110#define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5)
100#define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7) 111#define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7)
101#define MT9V032_PIXEL_CLOCK 0x74 112#define MT9V032_PIXEL_CLOCK 0x74
113#define MT9V034_PIXEL_CLOCK 0x72
102#define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0) 114#define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0)
103#define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1) 115#define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1)
104#define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2) 116#define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2)
@@ -120,12 +132,88 @@
120#define MT9V032_AGC_ENABLE (1 << 1) 132#define MT9V032_AGC_ENABLE (1 << 1)
121#define MT9V032_THERMAL_INFO 0xc1 133#define MT9V032_THERMAL_INFO 0xc1
122 134
135enum mt9v032_model {
136 MT9V032_MODEL_V032_COLOR,
137 MT9V032_MODEL_V032_MONO,
138 MT9V032_MODEL_V034_COLOR,
139 MT9V032_MODEL_V034_MONO,
140};
141
142struct mt9v032_model_version {
143 unsigned int version;
144 const char *name;
145};
146
147struct mt9v032_model_data {
148 unsigned int min_row_time;
149 unsigned int min_hblank;
150 unsigned int min_vblank;
151 unsigned int max_vblank;
152 unsigned int min_shutter;
153 unsigned int max_shutter;
154 unsigned int pclk_reg;
155};
156
157struct mt9v032_model_info {
158 const struct mt9v032_model_data *data;
159 bool color;
160};
161
162static const struct mt9v032_model_version mt9v032_versions[] = {
163 { MT9V032_CHIP_ID_REV1, "MT9V032 rev1/2" },
164 { MT9V032_CHIP_ID_REV3, "MT9V032 rev3" },
165 { MT9V034_CHIP_ID_REV1, "MT9V034 rev1" },
166};
167
168static const struct mt9v032_model_data mt9v032_model_data[] = {
169 {
170 /* MT9V032 revisions 1/2/3 */
171 .min_row_time = 660,
172 .min_hblank = MT9V032_HORIZONTAL_BLANKING_MIN,
173 .min_vblank = MT9V032_VERTICAL_BLANKING_MIN,
174 .max_vblank = MT9V032_VERTICAL_BLANKING_MAX,
175 .min_shutter = MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
176 .max_shutter = MT9V032_TOTAL_SHUTTER_WIDTH_MAX,
177 .pclk_reg = MT9V032_PIXEL_CLOCK,
178 }, {
179 /* MT9V034 */
180 .min_row_time = 690,
181 .min_hblank = MT9V034_HORIZONTAL_BLANKING_MIN,
182 .min_vblank = MT9V034_VERTICAL_BLANKING_MIN,
183 .max_vblank = MT9V034_VERTICAL_BLANKING_MAX,
184 .min_shutter = MT9V034_TOTAL_SHUTTER_WIDTH_MIN,
185 .max_shutter = MT9V034_TOTAL_SHUTTER_WIDTH_MAX,
186 .pclk_reg = MT9V034_PIXEL_CLOCK,
187 },
188};
189
190static const struct mt9v032_model_info mt9v032_models[] = {
191 [MT9V032_MODEL_V032_COLOR] = {
192 .data = &mt9v032_model_data[0],
193 .color = true,
194 },
195 [MT9V032_MODEL_V032_MONO] = {
196 .data = &mt9v032_model_data[0],
197 .color = false,
198 },
199 [MT9V032_MODEL_V034_COLOR] = {
200 .data = &mt9v032_model_data[1],
201 .color = true,
202 },
203 [MT9V032_MODEL_V034_MONO] = {
204 .data = &mt9v032_model_data[1],
205 .color = false,
206 },
207};
208
123struct mt9v032 { 209struct mt9v032 {
124 struct v4l2_subdev subdev; 210 struct v4l2_subdev subdev;
125 struct media_pad pad; 211 struct media_pad pad;
126 212
127 struct v4l2_mbus_framefmt format; 213 struct v4l2_mbus_framefmt format;
128 struct v4l2_rect crop; 214 struct v4l2_rect crop;
215 unsigned int hratio;
216 unsigned int vratio;
129 217
130 struct v4l2_ctrl_handler ctrls; 218 struct v4l2_ctrl_handler ctrls;
131 struct { 219 struct {
@@ -139,6 +227,8 @@ struct mt9v032 {
139 struct clk *clk; 227 struct clk *clk;
140 228
141 struct mt9v032_platform_data *pdata; 229 struct mt9v032_platform_data *pdata;
230 const struct mt9v032_model_info *model;
231 const struct mt9v032_model_version *version;
142 232
143 u32 sysclk; 233 u32 sysclk;
144 u16 chip_control; 234 u16 chip_control;
@@ -210,12 +300,17 @@ mt9v032_update_hblank(struct mt9v032 *mt9v032)
210{ 300{
211 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); 301 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
212 struct v4l2_rect *crop = &mt9v032->crop; 302 struct v4l2_rect *crop = &mt9v032->crop;
303 unsigned int min_hblank = mt9v032->model->data->min_hblank;
304 unsigned int hblank;
213 305
214 return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING, 306 if (mt9v032->version->version == MT9V034_CHIP_ID_REV1)
215 max_t(s32, mt9v032->hblank, 660 - crop->width)); 307 min_hblank += (mt9v032->hratio - 1) * 10;
216} 308 min_hblank = max_t(unsigned int, (int)mt9v032->model->data->min_row_time - crop->width,
309 (int)min_hblank);
310 hblank = max_t(unsigned int, mt9v032->hblank, min_hblank);
217 311
218#define EXT_CLK 25000000 312 return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING, hblank);
313}
219 314
220static int mt9v032_power_on(struct mt9v032 *mt9v032) 315static int mt9v032_power_on(struct mt9v032 *mt9v032)
221{ 316{
@@ -259,7 +354,7 @@ static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
259 354
260 /* Configure the pixel clock polarity */ 355 /* Configure the pixel clock polarity */
261 if (mt9v032->pdata && mt9v032->pdata->clk_pol) { 356 if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
262 ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK, 357 ret = mt9v032_write(client, mt9v032->model->data->pclk_reg,
263 MT9V032_PIXEL_CLOCK_INV_PXL_CLK); 358 MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
264 if (ret < 0) 359 if (ret < 0)
265 return ret; 360 return ret;
@@ -312,22 +407,20 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
312 | MT9V032_CHIP_CONTROL_SEQUENTIAL; 407 | MT9V032_CHIP_CONTROL_SEQUENTIAL;
313 struct i2c_client *client = v4l2_get_subdevdata(subdev); 408 struct i2c_client *client = v4l2_get_subdevdata(subdev);
314 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 409 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
315 struct v4l2_mbus_framefmt *format = &mt9v032->format;
316 struct v4l2_rect *crop = &mt9v032->crop; 410 struct v4l2_rect *crop = &mt9v032->crop;
317 unsigned int hratio; 411 unsigned int hbin;
318 unsigned int vratio; 412 unsigned int vbin;
319 int ret; 413 int ret;
320 414
321 if (!enable) 415 if (!enable)
322 return mt9v032_set_chip_control(mt9v032, mode, 0); 416 return mt9v032_set_chip_control(mt9v032, mode, 0);
323 417
324 /* Configure the window size and row/column bin */ 418 /* Configure the window size and row/column bin */
325 hratio = DIV_ROUND_CLOSEST(crop->width, format->width); 419 hbin = fls(mt9v032->hratio) - 1;
326 vratio = DIV_ROUND_CLOSEST(crop->height, format->height); 420 vbin = fls(mt9v032->vratio) - 1;
327
328 ret = mt9v032_write(client, MT9V032_READ_MODE, 421 ret = mt9v032_write(client, MT9V032_READ_MODE,
329 (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT | 422 hbin << MT9V032_READ_MODE_COLUMN_BIN_SHIFT |
330 (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT); 423 vbin << MT9V032_READ_MODE_ROW_BIN_SHIFT);
331 if (ret < 0) 424 if (ret < 0)
332 return ret; 425 return ret;
333 426
@@ -370,12 +463,12 @@ static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
370 struct v4l2_subdev_fh *fh, 463 struct v4l2_subdev_fh *fh,
371 struct v4l2_subdev_frame_size_enum *fse) 464 struct v4l2_subdev_frame_size_enum *fse)
372{ 465{
373 if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) 466 if (fse->index >= 3 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
374 return -EINVAL; 467 return -EINVAL;
375 468
376 fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index; 469 fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index);
377 fse->max_width = fse->min_width; 470 fse->max_width = fse->min_width;
378 fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index; 471 fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / (1 << fse->index);
379 fse->max_height = fse->min_height; 472 fse->max_height = fse->min_height;
380 473
381 return 0; 474 return 0;
@@ -392,18 +485,30 @@ static int mt9v032_get_format(struct v4l2_subdev *subdev,
392 return 0; 485 return 0;
393} 486}
394 487
395static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032, 488static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032)
396 unsigned int hratio)
397{ 489{
398 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); 490 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
399 int ret; 491 int ret;
400 492
401 ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate, 493 ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate,
402 mt9v032->sysclk / hratio); 494 mt9v032->sysclk / mt9v032->hratio);
403 if (ret < 0) 495 if (ret < 0)
404 dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret); 496 dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret);
405} 497}
406 498
499static unsigned int mt9v032_calc_ratio(unsigned int input, unsigned int output)
500{
501 /* Compute the power-of-two binning factor closest to the input size to
502 * output size ratio. Given that the output size is bounded by input/4
503 * and input, a generic implementation would be an ineffective luxury.
504 */
505 if (output * 3 > input * 2)
506 return 1;
507 if (output * 3 > input)
508 return 2;
509 return 4;
510}
511
407static int mt9v032_set_format(struct v4l2_subdev *subdev, 512static int mt9v032_set_format(struct v4l2_subdev *subdev,
408 struct v4l2_subdev_fh *fh, 513 struct v4l2_subdev_fh *fh,
409 struct v4l2_subdev_format *format) 514 struct v4l2_subdev_format *format)
@@ -420,22 +525,28 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev,
420 format->which); 525 format->which);
421 526
422 /* Clamp the width and height to avoid dividing by zero. */ 527 /* Clamp the width and height to avoid dividing by zero. */
423 width = clamp_t(unsigned int, ALIGN(format->format.width, 2), 528 width = clamp(ALIGN(format->format.width, 2),
424 max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN), 529 max_t(unsigned int, __crop->width / 4,
425 __crop->width); 530 MT9V032_WINDOW_WIDTH_MIN),
426 height = clamp_t(unsigned int, ALIGN(format->format.height, 2), 531 __crop->width);
427 max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN), 532 height = clamp(ALIGN(format->format.height, 2),
428 __crop->height); 533 max_t(unsigned int, __crop->height / 4,
429 534 MT9V032_WINDOW_HEIGHT_MIN),
430 hratio = DIV_ROUND_CLOSEST(__crop->width, width); 535 __crop->height);
431 vratio = DIV_ROUND_CLOSEST(__crop->height, height); 536
537 hratio = mt9v032_calc_ratio(__crop->width, width);
538 vratio = mt9v032_calc_ratio(__crop->height, height);
432 539
433 __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad, 540 __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
434 format->which); 541 format->which);
435 __format->width = __crop->width / hratio; 542 __format->width = __crop->width / hratio;
436 __format->height = __crop->height / vratio; 543 __format->height = __crop->height / vratio;
437 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 544
438 mt9v032_configure_pixel_rate(mt9v032, hratio); 545 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
546 mt9v032->hratio = hratio;
547 mt9v032->vratio = vratio;
548 mt9v032_configure_pixel_rate(mt9v032);
549 }
439 550
440 format->format = *__format; 551 format->format = *__format;
441 552
@@ -471,15 +582,17 @@ static int mt9v032_set_crop(struct v4l2_subdev *subdev,
471 rect.top = clamp(ALIGN(crop->rect.top + 1, 2) - 1, 582 rect.top = clamp(ALIGN(crop->rect.top + 1, 2) - 1,
472 MT9V032_ROW_START_MIN, 583 MT9V032_ROW_START_MIN,
473 MT9V032_ROW_START_MAX); 584 MT9V032_ROW_START_MAX);
474 rect.width = clamp(ALIGN(crop->rect.width, 2), 585 rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2),
475 MT9V032_WINDOW_WIDTH_MIN, 586 MT9V032_WINDOW_WIDTH_MIN,
476 MT9V032_WINDOW_WIDTH_MAX); 587 MT9V032_WINDOW_WIDTH_MAX);
477 rect.height = clamp(ALIGN(crop->rect.height, 2), 588 rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2),
478 MT9V032_WINDOW_HEIGHT_MIN, 589 MT9V032_WINDOW_HEIGHT_MIN,
479 MT9V032_WINDOW_HEIGHT_MAX); 590 MT9V032_WINDOW_HEIGHT_MAX);
480 591
481 rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left); 592 rect.width = min_t(unsigned int,
482 rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top); 593 rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
594 rect.height = min_t(unsigned int,
595 rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
483 596
484 __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which); 597 __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
485 598
@@ -491,8 +604,11 @@ static int mt9v032_set_crop(struct v4l2_subdev *subdev,
491 crop->which); 604 crop->which);
492 __format->width = rect.width; 605 __format->width = rect.width;
493 __format->height = rect.height; 606 __format->height = rect.height;
494 if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) 607 if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
495 mt9v032_configure_pixel_rate(mt9v032, 1); 608 mt9v032->hratio = 1;
609 mt9v032->vratio = 1;
610 mt9v032_configure_pixel_rate(mt9v032);
611 }
496 } 612 }
497 613
498 *__crop = rect; 614 *__crop = rect;
@@ -641,7 +757,8 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
641{ 757{
642 struct i2c_client *client = v4l2_get_subdevdata(subdev); 758 struct i2c_client *client = v4l2_get_subdevdata(subdev);
643 struct mt9v032 *mt9v032 = to_mt9v032(subdev); 759 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
644 s32 data; 760 unsigned int i;
761 s32 version;
645 int ret; 762 int ret;
646 763
647 dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n", 764 dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
@@ -654,25 +771,38 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
654 } 771 }
655 772
656 /* Read and check the sensor version */ 773 /* Read and check the sensor version */
657 data = mt9v032_read(client, MT9V032_CHIP_VERSION); 774 version = mt9v032_read(client, MT9V032_CHIP_VERSION);
658 if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) { 775 if (version < 0) {
659 dev_err(&client->dev, "MT9V032 not detected, wrong version " 776 dev_err(&client->dev, "Failed reading chip version\n");
660 "0x%04x\n", data); 777 return version;
778 }
779
780 for (i = 0; i < ARRAY_SIZE(mt9v032_versions); ++i) {
781 if (mt9v032_versions[i].version == version) {
782 mt9v032->version = &mt9v032_versions[i];
783 break;
784 }
785 }
786
787 if (mt9v032->version == NULL) {
788 dev_err(&client->dev, "Unsupported chip version 0x%04x\n",
789 version);
661 return -ENODEV; 790 return -ENODEV;
662 } 791 }
663 792
664 mt9v032_power_off(mt9v032); 793 mt9v032_power_off(mt9v032);
665 794
666 dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n", 795 dev_info(&client->dev, "%s detected at address 0x%02x\n",
667 client->addr); 796 mt9v032->version->name, client->addr);
668 797
669 mt9v032_configure_pixel_rate(mt9v032, 1); 798 mt9v032_configure_pixel_rate(mt9v032);
670 799
671 return ret; 800 return ret;
672} 801}
673 802
674static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 803static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
675{ 804{
805 struct mt9v032 *mt9v032 = to_mt9v032(subdev);
676 struct v4l2_mbus_framefmt *format; 806 struct v4l2_mbus_framefmt *format;
677 struct v4l2_rect *crop; 807 struct v4l2_rect *crop;
678 808
@@ -683,7 +813,12 @@ static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
683 crop->height = MT9V032_WINDOW_HEIGHT_DEF; 813 crop->height = MT9V032_WINDOW_HEIGHT_DEF;
684 814
685 format = v4l2_subdev_get_try_format(fh, 0); 815 format = v4l2_subdev_get_try_format(fh, 0);
686 format->code = V4L2_MBUS_FMT_SGRBG10_1X10; 816
817 if (mt9v032->model->color)
818 format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
819 else
820 format->code = V4L2_MBUS_FMT_Y10_1X10;
821
687 format->width = MT9V032_WINDOW_WIDTH_DEF; 822 format->width = MT9V032_WINDOW_WIDTH_DEF;
688 format->height = MT9V032_WINDOW_HEIGHT_DEF; 823 format->height = MT9V032_WINDOW_HEIGHT_DEF;
689 format->field = V4L2_FIELD_NONE; 824 format->field = V4L2_FIELD_NONE;
@@ -755,6 +890,7 @@ static int mt9v032_probe(struct i2c_client *client,
755 890
756 mutex_init(&mt9v032->power_lock); 891 mutex_init(&mt9v032->power_lock);
757 mt9v032->pdata = pdata; 892 mt9v032->pdata = pdata;
893 mt9v032->model = (const void *)did->driver_data;
758 894
759 v4l2_ctrl_handler_init(&mt9v032->ctrls, 10); 895 v4l2_ctrl_handler_init(&mt9v032->ctrls, 10);
760 896
@@ -767,16 +903,16 @@ static int mt9v032_probe(struct i2c_client *client,
767 V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0, 903 V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
768 V4L2_EXPOSURE_AUTO); 904 V4L2_EXPOSURE_AUTO);
769 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 905 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
770 V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN, 906 V4L2_CID_EXPOSURE, mt9v032->model->data->min_shutter,
771 MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1, 907 mt9v032->model->data->max_shutter, 1,
772 MT9V032_TOTAL_SHUTTER_WIDTH_DEF); 908 MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
773 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 909 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
774 V4L2_CID_HBLANK, MT9V032_HORIZONTAL_BLANKING_MIN, 910 V4L2_CID_HBLANK, mt9v032->model->data->min_hblank,
775 MT9V032_HORIZONTAL_BLANKING_MAX, 1, 911 MT9V032_HORIZONTAL_BLANKING_MAX, 1,
776 MT9V032_HORIZONTAL_BLANKING_DEF); 912 MT9V032_HORIZONTAL_BLANKING_DEF);
777 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 913 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
778 V4L2_CID_VBLANK, MT9V032_VERTICAL_BLANKING_MIN, 914 V4L2_CID_VBLANK, mt9v032->model->data->min_vblank,
779 MT9V032_VERTICAL_BLANKING_MAX, 1, 915 mt9v032->model->data->max_vblank, 1,
780 MT9V032_VERTICAL_BLANKING_DEF); 916 MT9V032_VERTICAL_BLANKING_DEF);
781 mt9v032->test_pattern = v4l2_ctrl_new_std_menu_items(&mt9v032->ctrls, 917 mt9v032->test_pattern = v4l2_ctrl_new_std_menu_items(&mt9v032->ctrls,
782 &mt9v032_ctrl_ops, V4L2_CID_TEST_PATTERN, 918 &mt9v032_ctrl_ops, V4L2_CID_TEST_PATTERN,
@@ -819,12 +955,19 @@ static int mt9v032_probe(struct i2c_client *client,
819 mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF; 955 mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
820 mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF; 956 mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
821 957
822 mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; 958 if (mt9v032->model->color)
959 mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
960 else
961 mt9v032->format.code = V4L2_MBUS_FMT_Y10_1X10;
962
823 mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF; 963 mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
824 mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF; 964 mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
825 mt9v032->format.field = V4L2_FIELD_NONE; 965 mt9v032->format.field = V4L2_FIELD_NONE;
826 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB; 966 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
827 967
968 mt9v032->hratio = 1;
969 mt9v032->vratio = 1;
970
828 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE; 971 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
829 mt9v032->hblank = MT9V032_HORIZONTAL_BLANKING_DEF; 972 mt9v032->hblank = MT9V032_HORIZONTAL_BLANKING_DEF;
830 mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF; 973 mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF;
@@ -855,7 +998,10 @@ static int mt9v032_remove(struct i2c_client *client)
855} 998}
856 999
857static const struct i2c_device_id mt9v032_id[] = { 1000static const struct i2c_device_id mt9v032_id[] = {
858 { "mt9v032", 0 }, 1001 { "mt9v032", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_COLOR] },
1002 { "mt9v032m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_MONO] },
1003 { "mt9v034", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_COLOR] },
1004 { "mt9v034m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_MONO] },
859 { } 1005 { }
860}; 1006};
861MODULE_DEVICE_TABLE(i2c, mt9v032_id); 1007MODULE_DEVICE_TABLE(i2c, mt9v032_id);
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
new file mode 100644
index 000000000000..4b8381111cbd
--- /dev/null
+++ b/drivers/media/i2c/s5k5baf.c
@@ -0,0 +1,2045 @@
1/*
2 * Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
3 * with embedded SoC ISP.
4 *
5 * Copyright (C) 2013, Samsung Electronics Co., Ltd.
6 * Andrzej Hajda <a.hajda@samsung.com>
7 *
8 * Based on S5K6AA driver authored by Sylwester Nawrocki
9 * Copyright (C) 2013, Samsung Electronics Co., Ltd.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/clk.h>
17#include <linux/delay.h>
18#include <linux/firmware.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/media.h>
22#include <linux/module.h>
23#include <linux/of_gpio.h>
24#include <linux/regulator/consumer.h>
25#include <linux/slab.h>
26
27#include <media/media-entity.h>
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-subdev.h>
31#include <media/v4l2-mediabus.h>
32#include <media/v4l2-of.h>
33
34static int debug;
35module_param(debug, int, 0644);
36
37#define S5K5BAF_DRIVER_NAME "s5k5baf"
38#define S5K5BAF_DEFAULT_MCLK_FREQ 24000000U
39#define S5K5BAF_CLK_NAME "mclk"
40
41#define S5K5BAF_FW_FILENAME "s5k5baf-cfg.bin"
42#define S5K5BAF_FW_TAG "SF00"
43#define S5K5BAG_FW_TAG_LEN 2
44#define S5K5BAG_FW_MAX_COUNT 16
45
46#define S5K5BAF_CIS_WIDTH 1600
47#define S5K5BAF_CIS_HEIGHT 1200
48#define S5K5BAF_WIN_WIDTH_MIN 8
49#define S5K5BAF_WIN_HEIGHT_MIN 8
50#define S5K5BAF_GAIN_RED_DEF 127
51#define S5K5BAF_GAIN_GREEN_DEF 95
52#define S5K5BAF_GAIN_BLUE_DEF 180
53/* Default number of MIPI CSI-2 data lanes used */
54#define S5K5BAF_DEF_NUM_LANES 1
55
56#define AHB_MSB_ADDR_PTR 0xfcfc
57
58/*
59 * Register interface pages (the most significant word of the address)
60 */
61#define PAGE_IF_HW 0xd000
62#define PAGE_IF_SW 0x7000
63
64/*
65 * H/W register Interface (PAGE_IF_HW)
66 */
67#define REG_SW_LOAD_COMPLETE 0x0014
68#define REG_CMDWR_PAGE 0x0028
69#define REG_CMDWR_ADDR 0x002a
70#define REG_CMDRD_PAGE 0x002c
71#define REG_CMDRD_ADDR 0x002e
72#define REG_CMD_BUF 0x0f12
73#define REG_SET_HOST_INT 0x1000
74#define REG_CLEAR_HOST_INT 0x1030
75#define REG_PATTERN_SET 0x3100
76#define REG_PATTERN_WIDTH 0x3118
77#define REG_PATTERN_HEIGHT 0x311a
78#define REG_PATTERN_PARAM 0x311c
79
80/*
81 * S/W register interface (PAGE_IF_SW)
82 */
83
84/* Firmware revision information */
85#define REG_FW_APIVER 0x012e
86#define S5K5BAF_FW_APIVER 0x0001
87#define REG_FW_REVISION 0x0130
88#define REG_FW_SENSOR_ID 0x0152
89
90/* Initialization parameters */
91/* Master clock frequency in KHz */
92#define REG_I_INCLK_FREQ_L 0x01b8
93#define REG_I_INCLK_FREQ_H 0x01ba
94#define MIN_MCLK_FREQ_KHZ 6000U
95#define MAX_MCLK_FREQ_KHZ 48000U
96#define REG_I_USE_NPVI_CLOCKS 0x01c6
97#define NPVI_CLOCKS 1
98#define REG_I_USE_NMIPI_CLOCKS 0x01c8
99#define NMIPI_CLOCKS 1
100#define REG_I_BLOCK_INTERNAL_PLL_CALC 0x01ca
101
102/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
103#define REG_I_OPCLK_4KHZ(n) ((n) * 6 + 0x01cc)
104#define REG_I_MIN_OUTRATE_4KHZ(n) ((n) * 6 + 0x01ce)
105#define REG_I_MAX_OUTRATE_4KHZ(n) ((n) * 6 + 0x01d0)
106#define SCLK_PVI_FREQ 24000
107#define SCLK_MIPI_FREQ 48000
108#define PCLK_MIN_FREQ 6000
109#define PCLK_MAX_FREQ 48000
110#define REG_I_USE_REGS_API 0x01de
111#define REG_I_INIT_PARAMS_UPDATED 0x01e0
112#define REG_I_ERROR_INFO 0x01e2
113
114/* General purpose parameters */
115#define REG_USER_BRIGHTNESS 0x01e4
116#define REG_USER_CONTRAST 0x01e6
117#define REG_USER_SATURATION 0x01e8
118#define REG_USER_SHARPBLUR 0x01ea
119
120#define REG_G_SPEC_EFFECTS 0x01ee
121#define REG_G_ENABLE_PREV 0x01f0
122#define REG_G_ENABLE_PREV_CHG 0x01f2
123#define REG_G_NEW_CFG_SYNC 0x01f8
124#define REG_G_PREVREQ_IN_WIDTH 0x01fa
125#define REG_G_PREVREQ_IN_HEIGHT 0x01fc
126#define REG_G_PREVREQ_IN_XOFFS 0x01fe
127#define REG_G_PREVREQ_IN_YOFFS 0x0200
128#define REG_G_PREVZOOM_IN_WIDTH 0x020a
129#define REG_G_PREVZOOM_IN_HEIGHT 0x020c
130#define REG_G_PREVZOOM_IN_XOFFS 0x020e
131#define REG_G_PREVZOOM_IN_YOFFS 0x0210
132#define REG_G_INPUTS_CHANGE_REQ 0x021a
133#define REG_G_ACTIVE_PREV_CFG 0x021c
134#define REG_G_PREV_CFG_CHG 0x021e
135#define REG_G_PREV_OPEN_AFTER_CH 0x0220
136#define REG_G_PREV_CFG_ERROR 0x0222
137#define CFG_ERROR_RANGE 0x0b
138#define REG_G_PREV_CFG_BYPASS_CHANGED 0x022a
139#define REG_G_ACTUAL_P_FR_TIME 0x023a
140#define REG_G_ACTUAL_P_OUT_RATE 0x023c
141#define REG_G_ACTUAL_C_FR_TIME 0x023e
142#define REG_G_ACTUAL_C_OUT_RATE 0x0240
143
144/* Preview control section. n = 0...4. */
145#define PREG(n, x) ((n) * 0x26 + x)
146#define REG_P_OUT_WIDTH(n) PREG(n, 0x0242)
147#define REG_P_OUT_HEIGHT(n) PREG(n, 0x0244)
148#define REG_P_FMT(n) PREG(n, 0x0246)
149#define REG_P_MAX_OUT_RATE(n) PREG(n, 0x0248)
150#define REG_P_MIN_OUT_RATE(n) PREG(n, 0x024a)
151#define REG_P_PVI_MASK(n) PREG(n, 0x024c)
152#define PVI_MASK_MIPI 0x52
153#define REG_P_CLK_INDEX(n) PREG(n, 0x024e)
154#define CLK_PVI_INDEX 0
155#define CLK_MIPI_INDEX NPVI_CLOCKS
156#define REG_P_FR_RATE_TYPE(n) PREG(n, 0x0250)
157#define FR_RATE_DYNAMIC 0
158#define FR_RATE_FIXED 1
159#define FR_RATE_FIXED_ACCURATE 2
160#define REG_P_FR_RATE_Q_TYPE(n) PREG(n, 0x0252)
161#define FR_RATE_Q_DYNAMIC 0
162#define FR_RATE_Q_BEST_FRRATE 1 /* Binning enabled */
163#define FR_RATE_Q_BEST_QUALITY 2 /* Binning disabled */
164/* Frame period in 0.1 ms units */
165#define REG_P_MAX_FR_TIME(n) PREG(n, 0x0254)
166#define REG_P_MIN_FR_TIME(n) PREG(n, 0x0256)
167#define S5K5BAF_MIN_FR_TIME 333 /* x100 us */
168#define S5K5BAF_MAX_FR_TIME 6500 /* x100 us */
169/* The below 5 registers are for "device correction" values */
170#define REG_P_SATURATION(n) PREG(n, 0x0258)
171#define REG_P_SHARP_BLUR(n) PREG(n, 0x025a)
172#define REG_P_GLAMOUR(n) PREG(n, 0x025c)
173#define REG_P_COLORTEMP(n) PREG(n, 0x025e)
174#define REG_P_GAMMA_INDEX(n) PREG(n, 0x0260)
175#define REG_P_PREV_MIRROR(n) PREG(n, 0x0262)
176#define REG_P_CAP_MIRROR(n) PREG(n, 0x0264)
177#define REG_P_CAP_ROTATION(n) PREG(n, 0x0266)
178
179/* Extended image property controls */
180/* Exposure time in 10 us units */
181#define REG_SF_USR_EXPOSURE_L 0x03bc
182#define REG_SF_USR_EXPOSURE_H 0x03be
183#define REG_SF_USR_EXPOSURE_CHG 0x03c0
184#define REG_SF_USR_TOT_GAIN 0x03c2
185#define REG_SF_USR_TOT_GAIN_CHG 0x03c4
186#define REG_SF_RGAIN 0x03c6
187#define REG_SF_RGAIN_CHG 0x03c8
188#define REG_SF_GGAIN 0x03ca
189#define REG_SF_GGAIN_CHG 0x03cc
190#define REG_SF_BGAIN 0x03ce
191#define REG_SF_BGAIN_CHG 0x03d0
192#define REG_SF_WBGAIN_CHG 0x03d2
193#define REG_SF_FLICKER_QUANT 0x03d4
194#define REG_SF_FLICKER_QUANT_CHG 0x03d6
195
196/* Output interface (parallel/MIPI) setup */
197#define REG_OIF_EN_MIPI_LANES 0x03f2
198#define REG_OIF_EN_PACKETS 0x03f4
199#define EN_PACKETS_CSI2 0xc3
200#define REG_OIF_CFG_CHG 0x03f6
201
202/* Auto-algorithms enable mask */
203#define REG_DBG_AUTOALG_EN 0x03f8
204#define AALG_ALL_EN BIT(0)
205#define AALG_AE_EN BIT(1)
206#define AALG_DIVLEI_EN BIT(2)
207#define AALG_WB_EN BIT(3)
208#define AALG_USE_WB_FOR_ISP BIT(4)
209#define AALG_FLICKER_EN BIT(5)
210#define AALG_FIT_EN BIT(6)
211#define AALG_WRHW_EN BIT(7)
212
213/* Pointers to color correction matrices */
214#define REG_PTR_CCM_HORIZON 0x06d0
215#define REG_PTR_CCM_INCANDESCENT 0x06d4
216#define REG_PTR_CCM_WARM_WHITE 0x06d8
217#define REG_PTR_CCM_COOL_WHITE 0x06dc
218#define REG_PTR_CCM_DL50 0x06e0
219#define REG_PTR_CCM_DL65 0x06e4
220#define REG_PTR_CCM_OUTDOOR 0x06ec
221
222#define REG_ARR_CCM(n) (0x2800 + 36 * (n))
223
224static const char * const s5k5baf_supply_names[] = {
225 "vdda", /* Analog power supply 2.8V (2.6V to 3.0V) */
226 "vddreg", /* Regulator input power supply 1.8V (1.7V to 1.9V)
227 or 2.8V (2.6V to 3.0) */
228 "vddio", /* I/O power supply 1.8V (1.65V to 1.95V)
229 or 2.8V (2.5V to 3.1V) */
230};
231#define S5K5BAF_NUM_SUPPLIES ARRAY_SIZE(s5k5baf_supply_names)
232
233struct s5k5baf_gpio {
234 int gpio;
235 int level;
236};
237
238enum s5k5baf_gpio_id {
239 STBY,
240 RST,
241 NUM_GPIOS,
242};
243
244#define PAD_CIS 0
245#define PAD_OUT 1
246#define NUM_CIS_PADS 1
247#define NUM_ISP_PADS 2
248
249struct s5k5baf_pixfmt {
250 enum v4l2_mbus_pixelcode code;
251 u32 colorspace;
252 /* REG_P_FMT(x) register value */
253 u16 reg_p_fmt;
254};
255
256struct s5k5baf_ctrls {
257 struct v4l2_ctrl_handler handler;
258 struct { /* Auto / manual white balance cluster */
259 struct v4l2_ctrl *awb;
260 struct v4l2_ctrl *gain_red;
261 struct v4l2_ctrl *gain_blue;
262 };
263 struct { /* Mirror cluster */
264 struct v4l2_ctrl *hflip;
265 struct v4l2_ctrl *vflip;
266 };
267 struct { /* Auto exposure / manual exposure and gain cluster */
268 struct v4l2_ctrl *auto_exp;
269 struct v4l2_ctrl *exposure;
270 struct v4l2_ctrl *gain;
271 };
272};
273
274enum {
275 S5K5BAF_FW_ID_PATCH,
276 S5K5BAF_FW_ID_CCM,
277 S5K5BAF_FW_ID_CIS,
278};
279
280struct s5k5baf_fw {
281 u16 count;
282 struct {
283 u16 id;
284 u16 offset;
285 } seq[0];
286 u16 data[0];
287};
288
289struct s5k5baf {
290 struct s5k5baf_gpio gpios[NUM_GPIOS];
291 enum v4l2_mbus_type bus_type;
292 u8 nlanes;
293 struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
294
295 struct clk *clock;
296 u32 mclk_frequency;
297
298 struct s5k5baf_fw *fw;
299
300 struct v4l2_subdev cis_sd;
301 struct media_pad cis_pad;
302
303 struct v4l2_subdev sd;
304 struct media_pad pads[NUM_ISP_PADS];
305
306 /* protects the struct members below */
307 struct mutex lock;
308
309 int error;
310
311 struct v4l2_rect crop_sink;
312 struct v4l2_rect compose;
313 struct v4l2_rect crop_source;
314 /* index to s5k5baf_formats array */
315 int pixfmt;
316 /* actual frame interval in 100us */
317 u16 fiv;
318 /* requested frame interval in 100us */
319 u16 req_fiv;
320 /* cache for REG_DBG_AUTOALG_EN register */
321 u16 auto_alg;
322
323 struct s5k5baf_ctrls ctrls;
324
325 unsigned int streaming:1;
326 unsigned int apply_cfg:1;
327 unsigned int apply_crop:1;
328 unsigned int valid_auto_alg:1;
329 unsigned int power;
330};
331
332static const struct s5k5baf_pixfmt s5k5baf_formats[] = {
333 { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 5 },
334 /* range 16-240 */
335 { V4L2_MBUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_REC709, 6 },
336 { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 },
337};
338
339static struct v4l2_rect s5k5baf_cis_rect = {
340 0, 0, S5K5BAF_CIS_WIDTH, S5K5BAF_CIS_HEIGHT
341};
342
343/* Setfile contains set of I2C command sequences. Each sequence has its ID.
344 * setfile format:
345 * u8 magic[4];
346 * u16 count; number of sequences
347 * struct {
348 * u16 id; sequence id
349 * u16 offset; sequence offset in data array
350 * } seq[count];
351 * u16 data[*]; array containing sequences
352 *
353 */
354static int s5k5baf_fw_parse(struct device *dev, struct s5k5baf_fw **fw,
355 size_t count, const u16 *data)
356{
357 struct s5k5baf_fw *f;
358 u16 *d, i, *end;
359 int ret;
360
361 if (count < S5K5BAG_FW_TAG_LEN + 1) {
362 dev_err(dev, "firmware file too short (%zu)\n", count);
363 return -EINVAL;
364 }
365
366 ret = memcmp(data, S5K5BAF_FW_TAG, S5K5BAG_FW_TAG_LEN * sizeof(u16));
367 if (ret != 0) {
368 dev_err(dev, "invalid firmware magic number\n");
369 return -EINVAL;
370 }
371
372 data += S5K5BAG_FW_TAG_LEN;
373 count -= S5K5BAG_FW_TAG_LEN;
374
375 d = devm_kzalloc(dev, count * sizeof(u16), GFP_KERNEL);
376
377 for (i = 0; i < count; ++i)
378 d[i] = le16_to_cpu(data[i]);
379
380 f = (struct s5k5baf_fw *)d;
381 if (count < 1 + 2 * f->count) {
382 dev_err(dev, "invalid firmware header (count=%d size=%zu)\n",
383 f->count, 2 * (count + S5K5BAG_FW_TAG_LEN));
384 return -EINVAL;
385 }
386 end = d + count;
387 d += 1 + 2 * f->count;
388
389 for (i = 0; i < f->count; ++i) {
390 if (f->seq[i].offset + d <= end)
391 continue;
392 dev_err(dev, "invalid firmware header (seq=%d)\n", i);
393 return -EINVAL;
394 }
395
396 *fw = f;
397
398 return 0;
399}
400
401static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
402{
403 return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd;
404}
405
406static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
407{
408 return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
409}
410
411static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
412{
413 if (s5k5baf_is_cis_subdev(sd))
414 return container_of(sd, struct s5k5baf, cis_sd);
415 else
416 return container_of(sd, struct s5k5baf, sd);
417}
418
419static u16 s5k5baf_i2c_read(struct s5k5baf *state, u16 addr)
420{
421 struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
422 __be16 w, r;
423 struct i2c_msg msg[] = {
424 { .addr = c->addr, .flags = 0,
425 .len = 2, .buf = (u8 *)&w },
426 { .addr = c->addr, .flags = I2C_M_RD,
427 .len = 2, .buf = (u8 *)&r },
428 };
429 int ret;
430
431 if (state->error)
432 return 0;
433
434 w = cpu_to_be16(addr);
435 ret = i2c_transfer(c->adapter, msg, 2);
436 r = be16_to_cpu(r);
437
438 v4l2_dbg(3, debug, c, "i2c_read: 0x%04x : 0x%04x\n", addr, r);
439
440 if (ret != 2) {
441 v4l2_err(c, "i2c_read: error during transfer (%d)\n", ret);
442 state->error = ret;
443 }
444 return r;
445}
446
447static void s5k5baf_i2c_write(struct s5k5baf *state, u16 addr, u16 val)
448{
449 u8 buf[4] = { addr >> 8, addr & 0xFF, val >> 8, val & 0xFF };
450 struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
451 int ret;
452
453 if (state->error)
454 return;
455
456 ret = i2c_master_send(c, buf, 4);
457 v4l2_dbg(3, debug, c, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
458
459 if (ret != 4) {
460 v4l2_err(c, "i2c_write: error during transfer (%d)\n", ret);
461 state->error = ret;
462 }
463}
464
465static u16 s5k5baf_read(struct s5k5baf *state, u16 addr)
466{
467 s5k5baf_i2c_write(state, REG_CMDRD_ADDR, addr);
468 return s5k5baf_i2c_read(state, REG_CMD_BUF);
469}
470
471static void s5k5baf_write(struct s5k5baf *state, u16 addr, u16 val)
472{
473 s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
474 s5k5baf_i2c_write(state, REG_CMD_BUF, val);
475}
476
477static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
478 u16 count, const u16 *seq)
479{
480 struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
481 __be16 buf[count + 1];
482 int ret, n;
483
484 s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
485 if (state->error)
486 return;
487
488 buf[0] = __constant_cpu_to_be16(REG_CMD_BUF);
489 for (n = 1; n <= count; ++n)
490 buf[n] = cpu_to_be16(*seq++);
491
492 n *= 2;
493 ret = i2c_master_send(c, (char *)buf, n);
494 v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
495 min(2 * count, 64), seq - count);
496
497 if (ret != n) {
498 v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
499 state->error = ret;
500 }
501}
502
503#define s5k5baf_write_seq(state, addr, seq...) \
504 s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \
505 (const u16 []){ seq });
506
507/* add items count at the beginning of the list */
508#define NSEQ(seq...) sizeof((char[]){ seq }), seq
509
510/*
511 * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
512 * @nseq: sequence of u16 words in format:
513 * (N, address, value[1]...value[N-1])*,0
514 * Ex.:
515 * u16 seq[] = { NSEQ(0x4000, 1, 1), NSEQ(0x4010, 640, 480), 0 };
516 * ret = s5k5baf_write_nseq(c, seq);
517 */
518static void s5k5baf_write_nseq(struct s5k5baf *state, const u16 *nseq)
519{
520 int count;
521
522 while ((count = *nseq++)) {
523 u16 addr = *nseq++;
524 --count;
525
526 s5k5baf_write_arr_seq(state, addr, count, nseq);
527 nseq += count;
528 }
529}
530
531static void s5k5baf_synchronize(struct s5k5baf *state, int timeout, u16 addr)
532{
533 unsigned long end = jiffies + msecs_to_jiffies(timeout);
534 u16 reg;
535
536 s5k5baf_write(state, addr, 1);
537 do {
538 reg = s5k5baf_read(state, addr);
539 if (state->error || !reg)
540 return;
541 usleep_range(5000, 10000);
542 } while (time_is_after_jiffies(end));
543
544 v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr);
545 state->error = -ETIMEDOUT;
546}
547
548static u16 *s5k5baf_fw_get_seq(struct s5k5baf *state, u16 seq_id)
549{
550 struct s5k5baf_fw *fw = state->fw;
551 u16 *data;
552 int i;
553
554 if (fw == NULL)
555 return NULL;
556
557 data = fw->data + 2 * fw->count;
558
559 for (i = 0; i < fw->count; ++i) {
560 if (fw->seq[i].id == seq_id)
561 return data + fw->seq[i].offset;
562 }
563
564 return NULL;
565}
566
567static void s5k5baf_hw_patch(struct s5k5baf *state)
568{
569 u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_PATCH);
570
571 if (seq)
572 s5k5baf_write_nseq(state, seq);
573}
574
575static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
576{
577 unsigned long mclk = state->mclk_frequency / 1000;
578 u16 status;
579 static const u16 nseq_clk_cfg[] = {
580 NSEQ(REG_I_USE_NPVI_CLOCKS,
581 NPVI_CLOCKS, NMIPI_CLOCKS, 0,
582 SCLK_PVI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4,
583 SCLK_MIPI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4),
584 NSEQ(REG_I_USE_REGS_API, 1),
585 0
586 };
587
588 s5k5baf_write_seq(state, REG_I_INCLK_FREQ_L, mclk & 0xffff, mclk >> 16);
589 s5k5baf_write_nseq(state, nseq_clk_cfg);
590
591 s5k5baf_synchronize(state, 250, REG_I_INIT_PARAMS_UPDATED);
592 status = s5k5baf_read(state, REG_I_ERROR_INFO);
593 if (!state->error && status) {
594 v4l2_err(&state->sd, "error configuring PLL (%d)\n", status);
595 state->error = -EINVAL;
596 }
597}
598
599/* set custom color correction matrices for various illuminations */
600static void s5k5baf_hw_set_ccm(struct s5k5baf *state)
601{
602 u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_CCM);
603
604 if (seq)
605 s5k5baf_write_nseq(state, seq);
606}
607
608/* CIS sensor tuning, based on undocumented android driver code */
609static void s5k5baf_hw_set_cis(struct s5k5baf *state)
610{
611 u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_CIS);
612
613 if (!seq)
614 return;
615
616 s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_HW);
617 s5k5baf_write_nseq(state, seq);
618 s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
619}
620
621static void s5k5baf_hw_sync_cfg(struct s5k5baf *state)
622{
623 s5k5baf_write(state, REG_G_PREV_CFG_CHG, 1);
624 if (state->apply_crop) {
625 s5k5baf_write(state, REG_G_INPUTS_CHANGE_REQ, 1);
626 s5k5baf_write(state, REG_G_PREV_CFG_BYPASS_CHANGED, 1);
627 }
628 s5k5baf_synchronize(state, 500, REG_G_NEW_CFG_SYNC);
629}
630/* Set horizontal and vertical image flipping */
631static void s5k5baf_hw_set_mirror(struct s5k5baf *state)
632{
633 u16 flip = state->ctrls.vflip->val | (state->ctrls.vflip->val << 1);
634
635 s5k5baf_write(state, REG_P_PREV_MIRROR(0), flip);
636 if (state->streaming)
637 s5k5baf_hw_sync_cfg(state);
638}
639
640static void s5k5baf_hw_set_alg(struct s5k5baf *state, u16 alg, bool enable)
641{
642 u16 cur_alg, new_alg;
643
644 if (!state->valid_auto_alg)
645 cur_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
646 else
647 cur_alg = state->auto_alg;
648
649 new_alg = enable ? (cur_alg | alg) : (cur_alg & ~alg);
650
651 if (new_alg != cur_alg)
652 s5k5baf_write(state, REG_DBG_AUTOALG_EN, new_alg);
653
654 if (state->error)
655 return;
656
657 state->valid_auto_alg = 1;
658 state->auto_alg = new_alg;
659}
660
661/* Configure auto/manual white balance and R/G/B gains */
662static void s5k5baf_hw_set_awb(struct s5k5baf *state, int awb)
663{
664 struct s5k5baf_ctrls *ctrls = &state->ctrls;
665
666 if (!awb)
667 s5k5baf_write_seq(state, REG_SF_RGAIN,
668 ctrls->gain_red->val, 1,
669 S5K5BAF_GAIN_GREEN_DEF, 1,
670 ctrls->gain_blue->val, 1,
671 1);
672
673 s5k5baf_hw_set_alg(state, AALG_WB_EN, awb);
674}
675
676/* Program FW with exposure time, 'exposure' in us units */
677static void s5k5baf_hw_set_user_exposure(struct s5k5baf *state, int exposure)
678{
679 unsigned int time = exposure / 10;
680
681 s5k5baf_write_seq(state, REG_SF_USR_EXPOSURE_L,
682 time & 0xffff, time >> 16, 1);
683}
684
685static void s5k5baf_hw_set_user_gain(struct s5k5baf *state, int gain)
686{
687 s5k5baf_write_seq(state, REG_SF_USR_TOT_GAIN, gain, 1);
688}
689
690/* Set auto/manual exposure and total gain */
691static void s5k5baf_hw_set_auto_exposure(struct s5k5baf *state, int value)
692{
693 if (value == V4L2_EXPOSURE_AUTO) {
694 s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, true);
695 } else {
696 unsigned int exp_time = state->ctrls.exposure->val;
697
698 s5k5baf_hw_set_user_exposure(state, exp_time);
699 s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val);
700 s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, false);
701 }
702}
703
704static void s5k5baf_hw_set_anti_flicker(struct s5k5baf *state, int v)
705{
706 if (v == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
707 s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, true);
708 } else {
709 /* The V4L2_CID_LINE_FREQUENCY control values match
710 * the register values */
711 s5k5baf_write_seq(state, REG_SF_FLICKER_QUANT, v, 1);
712 s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, false);
713 }
714}
715
716static void s5k5baf_hw_set_colorfx(struct s5k5baf *state, int val)
717{
718 static const u16 colorfx[] = {
719 [V4L2_COLORFX_NONE] = 0,
720 [V4L2_COLORFX_BW] = 1,
721 [V4L2_COLORFX_NEGATIVE] = 2,
722 [V4L2_COLORFX_SEPIA] = 3,
723 [V4L2_COLORFX_SKY_BLUE] = 4,
724 [V4L2_COLORFX_SKETCH] = 5,
725 };
726
727 s5k5baf_write(state, REG_G_SPEC_EFFECTS, colorfx[val]);
728}
729
730static int s5k5baf_find_pixfmt(struct v4l2_mbus_framefmt *mf)
731{
732 int i, c = -1;
733
734 for (i = 0; i < ARRAY_SIZE(s5k5baf_formats); i++) {
735 if (mf->colorspace != s5k5baf_formats[i].colorspace)
736 continue;
737 if (mf->code == s5k5baf_formats[i].code)
738 return i;
739 if (c < 0)
740 c = i;
741 }
742 return (c < 0) ? 0 : c;
743}
744
745static int s5k5baf_clear_error(struct s5k5baf *state)
746{
747 int ret = state->error;
748
749 state->error = 0;
750 return ret;
751}
752
753static int s5k5baf_hw_set_video_bus(struct s5k5baf *state)
754{
755 u16 en_pkts;
756
757 if (state->bus_type == V4L2_MBUS_CSI2)
758 en_pkts = EN_PACKETS_CSI2;
759 else
760 en_pkts = 0;
761
762 s5k5baf_write_seq(state, REG_OIF_EN_MIPI_LANES,
763 state->nlanes, en_pkts, 1);
764
765 return s5k5baf_clear_error(state);
766}
767
768static u16 s5k5baf_get_cfg_error(struct s5k5baf *state)
769{
770 u16 err = s5k5baf_read(state, REG_G_PREV_CFG_ERROR);
771 if (err)
772 s5k5baf_write(state, REG_G_PREV_CFG_ERROR, 0);
773 return err;
774}
775
776static void s5k5baf_hw_set_fiv(struct s5k5baf *state, u16 fiv)
777{
778 s5k5baf_write(state, REG_P_MAX_FR_TIME(0), fiv);
779 s5k5baf_hw_sync_cfg(state);
780}
781
782static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
783{
784 u16 err, fiv;
785 int n;
786
787 fiv = s5k5baf_read(state, REG_G_ACTUAL_P_FR_TIME);
788 if (state->error)
789 return;
790
791 for (n = 5; n > 0; --n) {
792 s5k5baf_hw_set_fiv(state, fiv);
793 err = s5k5baf_get_cfg_error(state);
794 if (state->error)
795 return;
796 switch (err) {
797 case CFG_ERROR_RANGE:
798 ++fiv;
799 break;
800 case 0:
801 state->fiv = fiv;
802 v4l2_info(&state->sd,
803 "found valid frame interval: %d00us\n", fiv);
804 return;
805 default:
806 v4l2_err(&state->sd,
807 "error setting frame interval: %d\n", err);
808 state->error = -EINVAL;
809 }
810 };
811 v4l2_err(&state->sd, "cannot find correct frame interval\n");
812 state->error = -ERANGE;
813}
814
815static void s5k5baf_hw_validate_cfg(struct s5k5baf *state)
816{
817 u16 err;
818
819 err = s5k5baf_get_cfg_error(state);
820 if (state->error)
821 return;
822
823 switch (err) {
824 case 0:
825 state->apply_cfg = 1;
826 return;
827 case CFG_ERROR_RANGE:
828 s5k5baf_hw_find_min_fiv(state);
829 if (!state->error)
830 state->apply_cfg = 1;
831 return;
832 default:
833 v4l2_err(&state->sd,
834 "error setting format: %d\n", err);
835 state->error = -EINVAL;
836 }
837}
838
839static void s5k5baf_rescale(struct v4l2_rect *r, const struct v4l2_rect *v,
840 const struct v4l2_rect *n,
841 const struct v4l2_rect *d)
842{
843 r->left = v->left * n->width / d->width;
844 r->top = v->top * n->height / d->height;
845 r->width = v->width * n->width / d->width;
846 r->height = v->height * n->height / d->height;
847}
848
849static int s5k5baf_hw_set_crop_rects(struct s5k5baf *state)
850{
851 struct v4l2_rect *p, r;
852 u16 err;
853 int ret;
854
855 p = &state->crop_sink;
856 s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height,
857 p->left, p->top);
858
859 s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink,
860 &state->compose);
861 s5k5baf_write_seq(state, REG_G_PREVZOOM_IN_WIDTH, r.width, r.height,
862 r.left, r.top);
863
864 s5k5baf_synchronize(state, 500, REG_G_INPUTS_CHANGE_REQ);
865 s5k5baf_synchronize(state, 500, REG_G_PREV_CFG_BYPASS_CHANGED);
866 err = s5k5baf_get_cfg_error(state);
867 ret = s5k5baf_clear_error(state);
868 if (ret < 0)
869 return ret;
870
871 switch (err) {
872 case 0:
873 break;
874 case CFG_ERROR_RANGE:
875 /* retry crop with frame interval set to max */
876 s5k5baf_hw_set_fiv(state, S5K5BAF_MAX_FR_TIME);
877 err = s5k5baf_get_cfg_error(state);
878 ret = s5k5baf_clear_error(state);
879 if (ret < 0)
880 return ret;
881 if (err) {
882 v4l2_err(&state->sd,
883 "crop error on max frame interval: %d\n", err);
884 state->error = -EINVAL;
885 }
886 s5k5baf_hw_set_fiv(state, state->req_fiv);
887 s5k5baf_hw_validate_cfg(state);
888 break;
889 default:
890 v4l2_err(&state->sd, "crop error: %d\n", err);
891 return -EINVAL;
892 }
893
894 if (!state->apply_cfg)
895 return 0;
896
897 p = &state->crop_source;
898 s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height);
899 s5k5baf_hw_set_fiv(state, state->req_fiv);
900 s5k5baf_hw_validate_cfg(state);
901
902 return s5k5baf_clear_error(state);
903}
904
905static void s5k5baf_hw_set_config(struct s5k5baf *state)
906{
907 u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt;
908 struct v4l2_rect *r = &state->crop_source;
909
910 s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0),
911 r->width, r->height, reg_fmt,
912 PCLK_MAX_FREQ >> 2, PCLK_MIN_FREQ >> 2,
913 PVI_MASK_MIPI, CLK_MIPI_INDEX,
914 FR_RATE_FIXED, FR_RATE_Q_DYNAMIC,
915 state->req_fiv, S5K5BAF_MIN_FR_TIME);
916 s5k5baf_hw_sync_cfg(state);
917 s5k5baf_hw_validate_cfg(state);
918}
919
920
921static void s5k5baf_hw_set_test_pattern(struct s5k5baf *state, int id)
922{
923 s5k5baf_i2c_write(state, REG_PATTERN_WIDTH, 800);
924 s5k5baf_i2c_write(state, REG_PATTERN_HEIGHT, 511);
925 s5k5baf_i2c_write(state, REG_PATTERN_PARAM, 0);
926 s5k5baf_i2c_write(state, REG_PATTERN_SET, id);
927}
928
929static void s5k5baf_gpio_assert(struct s5k5baf *state, int id)
930{
931 struct s5k5baf_gpio *gpio = &state->gpios[id];
932
933 gpio_set_value(gpio->gpio, gpio->level);
934}
935
936static void s5k5baf_gpio_deassert(struct s5k5baf *state, int id)
937{
938 struct s5k5baf_gpio *gpio = &state->gpios[id];
939
940 gpio_set_value(gpio->gpio, !gpio->level);
941}
942
943static int s5k5baf_power_on(struct s5k5baf *state)
944{
945 int ret;
946
947 ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies);
948 if (ret < 0)
949 goto err;
950
951 ret = clk_set_rate(state->clock, state->mclk_frequency);
952 if (ret < 0)
953 goto err_reg_dis;
954
955 ret = clk_prepare_enable(state->clock);
956 if (ret < 0)
957 goto err_reg_dis;
958
959 v4l2_dbg(1, debug, &state->sd, "clock frequency: %ld\n",
960 clk_get_rate(state->clock));
961
962 s5k5baf_gpio_deassert(state, STBY);
963 usleep_range(50, 100);
964 s5k5baf_gpio_deassert(state, RST);
965 return 0;
966
967err_reg_dis:
968 regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies);
969err:
970 v4l2_err(&state->sd, "%s() failed (%d)\n", __func__, ret);
971 return ret;
972}
973
974static int s5k5baf_power_off(struct s5k5baf *state)
975{
976 int ret;
977
978 state->streaming = 0;
979 state->apply_cfg = 0;
980 state->apply_crop = 0;
981
982 s5k5baf_gpio_assert(state, RST);
983 s5k5baf_gpio_assert(state, STBY);
984
985 if (!IS_ERR(state->clock))
986 clk_disable_unprepare(state->clock);
987
988 ret = regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES,
989 state->supplies);
990 if (ret < 0)
991 v4l2_err(&state->sd, "failed to disable regulators\n");
992
993 return 0;
994}
995
996static void s5k5baf_hw_init(struct s5k5baf *state)
997{
998 s5k5baf_i2c_write(state, AHB_MSB_ADDR_PTR, PAGE_IF_HW);
999 s5k5baf_i2c_write(state, REG_CLEAR_HOST_INT, 0);
1000 s5k5baf_i2c_write(state, REG_SW_LOAD_COMPLETE, 1);
1001 s5k5baf_i2c_write(state, REG_CMDRD_PAGE, PAGE_IF_SW);
1002 s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
1003}
1004
1005/*
1006 * V4L2 subdev core and video operations
1007 */
1008
1009static void s5k5baf_initialize_data(struct s5k5baf *state)
1010{
1011 state->pixfmt = 0;
1012 state->req_fiv = 10000 / 15;
1013 state->fiv = state->req_fiv;
1014 state->valid_auto_alg = 0;
1015}
1016
1017static int s5k5baf_load_setfile(struct s5k5baf *state)
1018{
1019 struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
1020 const struct firmware *fw;
1021 int ret;
1022
1023 ret = request_firmware(&fw, S5K5BAF_FW_FILENAME, &c->dev);
1024 if (ret < 0) {
1025 dev_warn(&c->dev, "firmware file (%s) not loaded\n",
1026 S5K5BAF_FW_FILENAME);
1027 return ret;
1028 }
1029
1030 ret = s5k5baf_fw_parse(&c->dev, &state->fw, fw->size / 2,
1031 (u16 *)fw->data);
1032
1033 release_firmware(fw);
1034
1035 return ret;
1036}
1037
1038static int s5k5baf_set_power(struct v4l2_subdev *sd, int on)
1039{
1040 struct s5k5baf *state = to_s5k5baf(sd);
1041 int ret = 0;
1042
1043 mutex_lock(&state->lock);
1044
1045 if (!on != state->power)
1046 goto out;
1047
1048 if (on) {
1049 if (state->fw == NULL)
1050 s5k5baf_load_setfile(state);
1051
1052 s5k5baf_initialize_data(state);
1053 ret = s5k5baf_power_on(state);
1054 if (ret < 0)
1055 goto out;
1056
1057 s5k5baf_hw_init(state);
1058 s5k5baf_hw_patch(state);
1059 s5k5baf_i2c_write(state, REG_SET_HOST_INT, 1);
1060 s5k5baf_hw_set_clocks(state);
1061
1062 ret = s5k5baf_hw_set_video_bus(state);
1063 if (ret < 0)
1064 goto out;
1065
1066 s5k5baf_hw_set_cis(state);
1067 s5k5baf_hw_set_ccm(state);
1068
1069 ret = s5k5baf_clear_error(state);
1070 if (!ret)
1071 state->power++;
1072 } else {
1073 s5k5baf_power_off(state);
1074 state->power--;
1075 }
1076
1077out:
1078 mutex_unlock(&state->lock);
1079
1080 if (!ret && on)
1081 ret = v4l2_ctrl_handler_setup(&state->ctrls.handler);
1082
1083 return ret;
1084}
1085
1086static void s5k5baf_hw_set_stream(struct s5k5baf *state, int enable)
1087{
1088 s5k5baf_write_seq(state, REG_G_ENABLE_PREV, enable, 1);
1089}
1090
1091static int s5k5baf_s_stream(struct v4l2_subdev *sd, int on)
1092{
1093 struct s5k5baf *state = to_s5k5baf(sd);
1094 int ret;
1095
1096 mutex_lock(&state->lock);
1097
1098 if (state->streaming == !!on) {
1099 ret = 0;
1100 goto out;
1101 }
1102
1103 if (on) {
1104 s5k5baf_hw_set_config(state);
1105 ret = s5k5baf_hw_set_crop_rects(state);
1106 if (ret < 0)
1107 goto out;
1108 s5k5baf_hw_set_stream(state, 1);
1109 s5k5baf_i2c_write(state, 0xb0cc, 0x000b);
1110 } else {
1111 s5k5baf_hw_set_stream(state, 0);
1112 }
1113 ret = s5k5baf_clear_error(state);
1114 if (!ret)
1115 state->streaming = !state->streaming;
1116
1117out:
1118 mutex_unlock(&state->lock);
1119
1120 return ret;
1121}
1122
1123static int s5k5baf_g_frame_interval(struct v4l2_subdev *sd,
1124 struct v4l2_subdev_frame_interval *fi)
1125{
1126 struct s5k5baf *state = to_s5k5baf(sd);
1127
1128 mutex_lock(&state->lock);
1129 fi->interval.numerator = state->fiv;
1130 fi->interval.denominator = 10000;
1131 mutex_unlock(&state->lock);
1132
1133 return 0;
1134}
1135
1136static void s5k5baf_set_frame_interval(struct s5k5baf *state,
1137 struct v4l2_subdev_frame_interval *fi)
1138{
1139 struct v4l2_fract *i = &fi->interval;
1140
1141 if (fi->interval.denominator == 0)
1142 state->req_fiv = S5K5BAF_MAX_FR_TIME;
1143 else
1144 state->req_fiv = clamp_t(u32,
1145 i->numerator * 10000 / i->denominator,
1146 S5K5BAF_MIN_FR_TIME,
1147 S5K5BAF_MAX_FR_TIME);
1148
1149 state->fiv = state->req_fiv;
1150 if (state->apply_cfg) {
1151 s5k5baf_hw_set_fiv(state, state->req_fiv);
1152 s5k5baf_hw_validate_cfg(state);
1153 }
1154 *i = (struct v4l2_fract){ state->fiv, 10000 };
1155 if (state->fiv == state->req_fiv)
1156 v4l2_info(&state->sd, "frame interval changed to %d00us\n",
1157 state->fiv);
1158}
1159
1160static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd,
1161 struct v4l2_subdev_frame_interval *fi)
1162{
1163 struct s5k5baf *state = to_s5k5baf(sd);
1164
1165 mutex_lock(&state->lock);
1166 s5k5baf_set_frame_interval(state, fi);
1167 mutex_unlock(&state->lock);
1168 return 0;
1169}
1170
1171/*
1172 * V4L2 subdev pad level and video operations
1173 */
1174static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd,
1175 struct v4l2_subdev_fh *fh,
1176 struct v4l2_subdev_frame_interval_enum *fie)
1177{
1178 if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME ||
1179 fie->pad != PAD_CIS)
1180 return -EINVAL;
1181
1182 v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN,
1183 S5K5BAF_CIS_WIDTH, 1,
1184 &fie->height, S5K5BAF_WIN_HEIGHT_MIN,
1185 S5K5BAF_CIS_HEIGHT, 1, 0);
1186
1187 fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index;
1188 fie->interval.denominator = 10000;
1189
1190 return 0;
1191}
1192
1193static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd,
1194 struct v4l2_subdev_fh *fh,
1195 struct v4l2_subdev_mbus_code_enum *code)
1196{
1197 if (code->pad == PAD_CIS) {
1198 if (code->index > 0)
1199 return -EINVAL;
1200 code->code = V4L2_MBUS_FMT_FIXED;
1201 return 0;
1202 }
1203
1204 if (code->index >= ARRAY_SIZE(s5k5baf_formats))
1205 return -EINVAL;
1206
1207 code->code = s5k5baf_formats[code->index].code;
1208 return 0;
1209}
1210
1211static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd,
1212 struct v4l2_subdev_fh *fh,
1213 struct v4l2_subdev_frame_size_enum *fse)
1214{
1215 int i;
1216
1217 if (fse->index > 0)
1218 return -EINVAL;
1219
1220 if (fse->pad == PAD_CIS) {
1221 fse->code = V4L2_MBUS_FMT_FIXED;
1222 fse->min_width = S5K5BAF_CIS_WIDTH;
1223 fse->max_width = S5K5BAF_CIS_WIDTH;
1224 fse->min_height = S5K5BAF_CIS_HEIGHT;
1225 fse->max_height = S5K5BAF_CIS_HEIGHT;
1226 return 0;
1227 }
1228
1229 i = ARRAY_SIZE(s5k5baf_formats);
1230 while (--i)
1231 if (fse->code == s5k5baf_formats[i].code)
1232 break;
1233 fse->code = s5k5baf_formats[i].code;
1234 fse->min_width = S5K5BAF_WIN_WIDTH_MIN;
1235 fse->max_width = S5K5BAF_CIS_WIDTH;
1236 fse->max_height = S5K5BAF_WIN_HEIGHT_MIN;
1237 fse->min_height = S5K5BAF_CIS_HEIGHT;
1238
1239 return 0;
1240}
1241
1242static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf)
1243{
1244 mf->width = S5K5BAF_CIS_WIDTH;
1245 mf->height = S5K5BAF_CIS_HEIGHT;
1246 mf->code = V4L2_MBUS_FMT_FIXED;
1247 mf->colorspace = V4L2_COLORSPACE_JPEG;
1248 mf->field = V4L2_FIELD_NONE;
1249}
1250
1251static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf)
1252{
1253 int pixfmt;
1254
1255 v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN,
1256 S5K5BAF_CIS_WIDTH, 1,
1257 &mf->height, S5K5BAF_WIN_HEIGHT_MIN,
1258 S5K5BAF_CIS_HEIGHT, 1, 0);
1259
1260 pixfmt = s5k5baf_find_pixfmt(mf);
1261
1262 mf->colorspace = s5k5baf_formats[pixfmt].colorspace;
1263 mf->code = s5k5baf_formats[pixfmt].code;
1264 mf->field = V4L2_FIELD_NONE;
1265
1266 return pixfmt;
1267}
1268
1269static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1270 struct v4l2_subdev_format *fmt)
1271{
1272 struct s5k5baf *state = to_s5k5baf(sd);
1273 const struct s5k5baf_pixfmt *pixfmt;
1274 struct v4l2_mbus_framefmt *mf;
1275
1276 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1277 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1278 fmt->format = *mf;
1279 return 0;
1280 }
1281
1282 mf = &fmt->format;
1283 if (fmt->pad == PAD_CIS) {
1284 s5k5baf_try_cis_format(mf);
1285 return 0;
1286 }
1287 mf->field = V4L2_FIELD_NONE;
1288 mutex_lock(&state->lock);
1289 pixfmt = &s5k5baf_formats[state->pixfmt];
1290 mf->width = state->crop_source.width;
1291 mf->height = state->crop_source.height;
1292 mf->code = pixfmt->code;
1293 mf->colorspace = pixfmt->colorspace;
1294 mutex_unlock(&state->lock);
1295
1296 return 0;
1297}
1298
1299static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1300 struct v4l2_subdev_format *fmt)
1301{
1302 struct v4l2_mbus_framefmt *mf = &fmt->format;
1303 struct s5k5baf *state = to_s5k5baf(sd);
1304 const struct s5k5baf_pixfmt *pixfmt;
1305 int ret = 0;
1306
1307 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1308 *v4l2_subdev_get_try_format(fh, fmt->pad) = *mf;
1309 return 0;
1310 }
1311
1312 if (fmt->pad == PAD_CIS) {
1313 s5k5baf_try_cis_format(mf);
1314 return 0;
1315 }
1316
1317 mutex_lock(&state->lock);
1318
1319 if (state->streaming) {
1320 mutex_unlock(&state->lock);
1321 return -EBUSY;
1322 }
1323
1324 state->pixfmt = s5k5baf_try_isp_format(mf);
1325 pixfmt = &s5k5baf_formats[state->pixfmt];
1326 mf->code = pixfmt->code;
1327 mf->colorspace = pixfmt->colorspace;
1328 mf->width = state->crop_source.width;
1329 mf->height = state->crop_source.height;
1330
1331 mutex_unlock(&state->lock);
1332 return ret;
1333}
1334
1335enum selection_rect { R_CIS, R_CROP_SINK, R_COMPOSE, R_CROP_SOURCE, R_INVALID };
1336
1337static enum selection_rect s5k5baf_get_sel_rect(u32 pad, u32 target)
1338{
1339 switch (target) {
1340 case V4L2_SEL_TGT_CROP_BOUNDS:
1341 return pad ? R_COMPOSE : R_CIS;
1342 case V4L2_SEL_TGT_CROP:
1343 return pad ? R_CROP_SOURCE : R_CROP_SINK;
1344 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1345 return pad ? R_INVALID : R_CROP_SINK;
1346 case V4L2_SEL_TGT_COMPOSE:
1347 return pad ? R_INVALID : R_COMPOSE;
1348 default:
1349 return R_INVALID;
1350 }
1351}
1352
1353static int s5k5baf_is_bound_target(u32 target)
1354{
1355 return target == V4L2_SEL_TGT_CROP_BOUNDS ||
1356 target == V4L2_SEL_TGT_COMPOSE_BOUNDS;
1357}
1358
1359static int s5k5baf_get_selection(struct v4l2_subdev *sd,
1360 struct v4l2_subdev_fh *fh,
1361 struct v4l2_subdev_selection *sel)
1362{
1363 static enum selection_rect rtype;
1364 struct s5k5baf *state = to_s5k5baf(sd);
1365
1366 rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
1367
1368 switch (rtype) {
1369 case R_INVALID:
1370 return -EINVAL;
1371 case R_CIS:
1372 sel->r = s5k5baf_cis_rect;
1373 return 0;
1374 default:
1375 break;
1376 }
1377
1378 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1379 if (rtype == R_COMPOSE)
1380 sel->r = *v4l2_subdev_get_try_compose(fh, sel->pad);
1381 else
1382 sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
1383 return 0;
1384 }
1385
1386 mutex_lock(&state->lock);
1387 switch (rtype) {
1388 case R_CROP_SINK:
1389 sel->r = state->crop_sink;
1390 break;
1391 case R_COMPOSE:
1392 sel->r = state->compose;
1393 break;
1394 case R_CROP_SOURCE:
1395 sel->r = state->crop_source;
1396 break;
1397 default:
1398 break;
1399 }
1400 if (s5k5baf_is_bound_target(sel->target)) {
1401 sel->r.left = 0;
1402 sel->r.top = 0;
1403 }
1404 mutex_unlock(&state->lock);
1405
1406 return 0;
1407}
1408
1409/* bounds range [start, start+len) to [0, max) and aligns to 2 */
1410static void s5k5baf_bound_range(u32 *start, u32 *len, u32 max)
1411{
1412 if (*len > max)
1413 *len = max;
1414 if (*start + *len > max)
1415 *start = max - *len;
1416 *start &= ~1;
1417 *len &= ~1;
1418 if (*len < S5K5BAF_WIN_WIDTH_MIN)
1419 *len = S5K5BAF_WIN_WIDTH_MIN;
1420}
1421
1422static void s5k5baf_bound_rect(struct v4l2_rect *r, u32 width, u32 height)
1423{
1424 s5k5baf_bound_range(&r->left, &r->width, width);
1425 s5k5baf_bound_range(&r->top, &r->height, height);
1426}
1427
1428static void s5k5baf_set_rect_and_adjust(struct v4l2_rect **rects,
1429 enum selection_rect first,
1430 struct v4l2_rect *v)
1431{
1432 struct v4l2_rect *r, *br;
1433 enum selection_rect i = first;
1434
1435 *rects[first] = *v;
1436 do {
1437 r = rects[i];
1438 br = rects[i - 1];
1439 s5k5baf_bound_rect(r, br->width, br->height);
1440 } while (++i != R_INVALID);
1441 *v = *rects[first];
1442}
1443
1444static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1,
1445 const struct v4l2_rect *r2)
1446{
1447 return !memcmp(r1, r2, sizeof(*r1));
1448}
1449
1450static int s5k5baf_set_selection(struct v4l2_subdev *sd,
1451 struct v4l2_subdev_fh *fh,
1452 struct v4l2_subdev_selection *sel)
1453{
1454 static enum selection_rect rtype;
1455 struct s5k5baf *state = to_s5k5baf(sd);
1456 struct v4l2_rect **rects;
1457 int ret = 0;
1458
1459 rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
1460 if (rtype == R_INVALID || s5k5baf_is_bound_target(sel->target))
1461 return -EINVAL;
1462
1463 /* allow only scaling on compose */
1464 if (rtype == R_COMPOSE) {
1465 sel->r.left = 0;
1466 sel->r.top = 0;
1467 }
1468
1469 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1470 rects = (struct v4l2_rect * []) {
1471 &s5k5baf_cis_rect,
1472 v4l2_subdev_get_try_crop(fh, PAD_CIS),
1473 v4l2_subdev_get_try_compose(fh, PAD_CIS),
1474 v4l2_subdev_get_try_crop(fh, PAD_OUT)
1475 };
1476 s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
1477 return 0;
1478 }
1479
1480 rects = (struct v4l2_rect * []) {
1481 &s5k5baf_cis_rect,
1482 &state->crop_sink,
1483 &state->compose,
1484 &state->crop_source
1485 };
1486 mutex_lock(&state->lock);
1487 if (state->streaming) {
1488 /* adjust sel->r to avoid output resolution change */
1489 if (rtype < R_CROP_SOURCE) {
1490 if (sel->r.width < state->crop_source.width)
1491 sel->r.width = state->crop_source.width;
1492 if (sel->r.height < state->crop_source.height)
1493 sel->r.height = state->crop_source.height;
1494 } else {
1495 sel->r.width = state->crop_source.width;
1496 sel->r.height = state->crop_source.height;
1497 }
1498 }
1499 s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
1500 if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) ||
1501 !s5k5baf_cmp_rect(&state->compose, &s5k5baf_cis_rect))
1502 state->apply_crop = 1;
1503 if (state->streaming)
1504 ret = s5k5baf_hw_set_crop_rects(state);
1505 mutex_unlock(&state->lock);
1506
1507 return ret;
1508}
1509
1510static const struct v4l2_subdev_pad_ops s5k5baf_cis_pad_ops = {
1511 .enum_mbus_code = s5k5baf_enum_mbus_code,
1512 .enum_frame_size = s5k5baf_enum_frame_size,
1513 .get_fmt = s5k5baf_get_fmt,
1514 .set_fmt = s5k5baf_set_fmt,
1515};
1516
1517static const struct v4l2_subdev_pad_ops s5k5baf_pad_ops = {
1518 .enum_mbus_code = s5k5baf_enum_mbus_code,
1519 .enum_frame_size = s5k5baf_enum_frame_size,
1520 .enum_frame_interval = s5k5baf_enum_frame_interval,
1521 .get_fmt = s5k5baf_get_fmt,
1522 .set_fmt = s5k5baf_set_fmt,
1523 .get_selection = s5k5baf_get_selection,
1524 .set_selection = s5k5baf_set_selection,
1525};
1526
1527static const struct v4l2_subdev_video_ops s5k5baf_video_ops = {
1528 .g_frame_interval = s5k5baf_g_frame_interval,
1529 .s_frame_interval = s5k5baf_s_frame_interval,
1530 .s_stream = s5k5baf_s_stream,
1531};
1532
1533/*
1534 * V4L2 subdev controls
1535 */
1536
1537static int s5k5baf_s_ctrl(struct v4l2_ctrl *ctrl)
1538{
1539 struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1540 struct s5k5baf *state = to_s5k5baf(sd);
1541 int ret;
1542
1543 v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val);
1544
1545 mutex_lock(&state->lock);
1546
1547 if (state->power == 0)
1548 goto unlock;
1549
1550 switch (ctrl->id) {
1551 case V4L2_CID_AUTO_WHITE_BALANCE:
1552 s5k5baf_hw_set_awb(state, ctrl->val);
1553 break;
1554
1555 case V4L2_CID_BRIGHTNESS:
1556 s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val);
1557 break;
1558
1559 case V4L2_CID_COLORFX:
1560 s5k5baf_hw_set_colorfx(state, ctrl->val);
1561 break;
1562
1563 case V4L2_CID_CONTRAST:
1564 s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val);
1565 break;
1566
1567 case V4L2_CID_EXPOSURE_AUTO:
1568 s5k5baf_hw_set_auto_exposure(state, ctrl->val);
1569 break;
1570
1571 case V4L2_CID_HFLIP:
1572 s5k5baf_hw_set_mirror(state);
1573 break;
1574
1575 case V4L2_CID_POWER_LINE_FREQUENCY:
1576 s5k5baf_hw_set_anti_flicker(state, ctrl->val);
1577 break;
1578
1579 case V4L2_CID_SATURATION:
1580 s5k5baf_write(state, REG_USER_SATURATION, ctrl->val);
1581 break;
1582
1583 case V4L2_CID_SHARPNESS:
1584 s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val);
1585 break;
1586
1587 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
1588 s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val);
1589 if (state->apply_cfg)
1590 s5k5baf_hw_sync_cfg(state);
1591 break;
1592
1593 case V4L2_CID_TEST_PATTERN:
1594 s5k5baf_hw_set_test_pattern(state, ctrl->val);
1595 break;
1596 }
1597unlock:
1598 ret = s5k5baf_clear_error(state);
1599 mutex_unlock(&state->lock);
1600 return ret;
1601}
1602
1603static const struct v4l2_ctrl_ops s5k5baf_ctrl_ops = {
1604 .s_ctrl = s5k5baf_s_ctrl,
1605};
1606
1607static const char * const s5k5baf_test_pattern_menu[] = {
1608 "Disabled",
1609 "Blank",
1610 "Bars",
1611 "Gradients",
1612 "Textile",
1613 "Textile2",
1614 "Squares"
1615};
1616
1617static int s5k5baf_initialize_ctrls(struct s5k5baf *state)
1618{
1619 const struct v4l2_ctrl_ops *ops = &s5k5baf_ctrl_ops;
1620 struct s5k5baf_ctrls *ctrls = &state->ctrls;
1621 struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1622 int ret;
1623
1624 ret = v4l2_ctrl_handler_init(hdl, 16);
1625 if (ret < 0) {
1626 v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret);
1627 return ret;
1628 }
1629
1630 /* Auto white balance cluster */
1631 ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
1632 0, 1, 1, 1);
1633 ctrls->gain_red = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
1634 0, 255, 1, S5K5BAF_GAIN_RED_DEF);
1635 ctrls->gain_blue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
1636 0, 255, 1, S5K5BAF_GAIN_BLUE_DEF);
1637 v4l2_ctrl_auto_cluster(3, &ctrls->awb, 0, false);
1638
1639 ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1640 ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1641 v4l2_ctrl_cluster(2, &ctrls->hflip);
1642
1643 ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
1644 V4L2_CID_EXPOSURE_AUTO,
1645 V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
1646 /* Exposure time: x 1 us */
1647 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
1648 0, 6000000U, 1, 100000U);
1649 /* Total gain: 256 <=> 1x */
1650 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
1651 0, 256, 1, 256);
1652 v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
1653
1654 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
1655 V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
1656 V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
1657
1658 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
1659 V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
1660
1661 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
1662 0, 256, 1, 0);
1663
1664 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
1665 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
1666 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
1667 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
1668
1669 v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
1670 ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1,
1671 0, 0, s5k5baf_test_pattern_menu);
1672
1673 if (hdl->error) {
1674 v4l2_err(&state->sd, "error creating controls (%d)\n",
1675 hdl->error);
1676 ret = hdl->error;
1677 v4l2_ctrl_handler_free(hdl);
1678 return ret;
1679 }
1680
1681 state->sd.ctrl_handler = hdl;
1682 return 0;
1683}
1684
1685/*
1686 * V4L2 subdev internal operations
1687 */
1688static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1689{
1690 struct v4l2_mbus_framefmt *mf;
1691
1692 mf = v4l2_subdev_get_try_format(fh, PAD_CIS);
1693 s5k5baf_try_cis_format(mf);
1694
1695 if (s5k5baf_is_cis_subdev(sd))
1696 return 0;
1697
1698 mf = v4l2_subdev_get_try_format(fh, PAD_OUT);
1699 mf->colorspace = s5k5baf_formats[0].colorspace;
1700 mf->code = s5k5baf_formats[0].code;
1701 mf->width = s5k5baf_cis_rect.width;
1702 mf->height = s5k5baf_cis_rect.height;
1703 mf->field = V4L2_FIELD_NONE;
1704
1705 *v4l2_subdev_get_try_crop(fh, PAD_CIS) = s5k5baf_cis_rect;
1706 *v4l2_subdev_get_try_compose(fh, PAD_CIS) = s5k5baf_cis_rect;
1707 *v4l2_subdev_get_try_crop(fh, PAD_OUT) = s5k5baf_cis_rect;
1708
1709 return 0;
1710}
1711
1712static int s5k5baf_check_fw_revision(struct s5k5baf *state)
1713{
1714 u16 api_ver = 0, fw_rev = 0, s_id = 0;
1715 int ret;
1716
1717 api_ver = s5k5baf_read(state, REG_FW_APIVER);
1718 fw_rev = s5k5baf_read(state, REG_FW_REVISION) & 0xff;
1719 s_id = s5k5baf_read(state, REG_FW_SENSOR_ID);
1720 ret = s5k5baf_clear_error(state);
1721 if (ret < 0)
1722 return ret;
1723
1724 v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n",
1725 api_ver, fw_rev, s_id);
1726
1727 if (api_ver != S5K5BAF_FW_APIVER) {
1728 v4l2_err(&state->sd, "FW API version not supported\n");
1729 return -ENODEV;
1730 }
1731
1732 return 0;
1733}
1734
1735static int s5k5baf_registered(struct v4l2_subdev *sd)
1736{
1737 struct s5k5baf *state = to_s5k5baf(sd);
1738 int ret;
1739
1740 ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd);
1741 if (ret < 0)
1742 v4l2_err(sd, "failed to register subdev %s\n",
1743 state->cis_sd.name);
1744 else
1745 ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
1746 &state->sd.entity, PAD_CIS,
1747 MEDIA_LNK_FL_IMMUTABLE |
1748 MEDIA_LNK_FL_ENABLED);
1749 return ret;
1750}
1751
1752static void s5k5baf_unregistered(struct v4l2_subdev *sd)
1753{
1754 struct s5k5baf *state = to_s5k5baf(sd);
1755 v4l2_device_unregister_subdev(&state->cis_sd);
1756}
1757
1758static const struct v4l2_subdev_ops s5k5baf_cis_subdev_ops = {
1759 .pad = &s5k5baf_cis_pad_ops,
1760};
1761
1762static const struct v4l2_subdev_internal_ops s5k5baf_cis_subdev_internal_ops = {
1763 .open = s5k5baf_open,
1764};
1765
1766static const struct v4l2_subdev_internal_ops s5k5baf_subdev_internal_ops = {
1767 .registered = s5k5baf_registered,
1768 .unregistered = s5k5baf_unregistered,
1769 .open = s5k5baf_open,
1770};
1771
1772static const struct v4l2_subdev_core_ops s5k5baf_core_ops = {
1773 .s_power = s5k5baf_set_power,
1774 .log_status = v4l2_ctrl_subdev_log_status,
1775};
1776
1777static const struct v4l2_subdev_ops s5k5baf_subdev_ops = {
1778 .core = &s5k5baf_core_ops,
1779 .pad = &s5k5baf_pad_ops,
1780 .video = &s5k5baf_video_ops,
1781};
1782
1783static int s5k5baf_configure_gpios(struct s5k5baf *state)
1784{
1785 static const char const *name[] = { "S5K5BAF_STBY", "S5K5BAF_RST" };
1786 struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
1787 struct s5k5baf_gpio *g = state->gpios;
1788 int ret, i;
1789
1790 for (i = 0; i < NUM_GPIOS; ++i) {
1791 int flags = GPIOF_DIR_OUT;
1792 if (g[i].level)
1793 flags |= GPIOF_INIT_HIGH;
1794 ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, name[i]);
1795 if (ret < 0) {
1796 v4l2_err(c, "failed to request gpio %s\n", name[i]);
1797 return ret;
1798 }
1799 }
1800 return 0;
1801}
1802
1803static int s5k5baf_parse_gpios(struct s5k5baf_gpio *gpios, struct device *dev)
1804{
1805 static const char * const names[] = {
1806 "stbyn-gpios",
1807 "rstn-gpios",
1808 };
1809 struct device_node *node = dev->of_node;
1810 enum of_gpio_flags flags;
1811 int ret, i;
1812
1813 for (i = 0; i < NUM_GPIOS; ++i) {
1814 ret = of_get_named_gpio_flags(node, names[i], 0, &flags);
1815 if (ret < 0) {
1816 dev_err(dev, "no %s GPIO pin provided\n", names[i]);
1817 return ret;
1818 }
1819 gpios[i].gpio = ret;
1820 gpios[i].level = !(flags & OF_GPIO_ACTIVE_LOW);
1821 }
1822
1823 return 0;
1824}
1825
1826static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
1827{
1828 struct device_node *node = dev->of_node;
1829 struct device_node *node_ep;
1830 struct v4l2_of_endpoint ep;
1831 int ret;
1832
1833 if (!node) {
1834 dev_err(dev, "no device-tree node provided\n");
1835 return -EINVAL;
1836 }
1837
1838 ret = of_property_read_u32(node, "clock-frequency",
1839 &state->mclk_frequency);
1840 if (ret < 0) {
1841 state->mclk_frequency = S5K5BAF_DEFAULT_MCLK_FREQ;
1842 dev_info(dev, "using default %u Hz clock frequency\n",
1843 state->mclk_frequency);
1844 }
1845
1846 ret = s5k5baf_parse_gpios(state->gpios, dev);
1847 if (ret < 0)
1848 return ret;
1849
1850 node_ep = v4l2_of_get_next_endpoint(node, NULL);
1851 if (!node_ep) {
1852 dev_err(dev, "no endpoint defined at node %s\n",
1853 node->full_name);
1854 return -EINVAL;
1855 }
1856
1857 v4l2_of_parse_endpoint(node_ep, &ep);
1858 of_node_put(node_ep);
1859 state->bus_type = ep.bus_type;
1860
1861 switch (state->bus_type) {
1862 case V4L2_MBUS_CSI2:
1863 state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
1864 break;
1865 case V4L2_MBUS_PARALLEL:
1866 break;
1867 default:
1868 dev_err(dev, "unsupported bus in endpoint defined at node %s\n",
1869 node->full_name);
1870 return -EINVAL;
1871 }
1872
1873 return 0;
1874}
1875
1876static int s5k5baf_configure_subdevs(struct s5k5baf *state,
1877 struct i2c_client *c)
1878{
1879 struct v4l2_subdev *sd;
1880 int ret;
1881
1882 sd = &state->cis_sd;
1883 v4l2_subdev_init(sd, &s5k5baf_cis_subdev_ops);
1884 sd->owner = THIS_MODULE;
1885 v4l2_set_subdevdata(sd, state);
1886 snprintf(sd->name, sizeof(sd->name), "S5K5BAF-CIS %d-%04x",
1887 i2c_adapter_id(c->adapter), c->addr);
1888
1889 sd->internal_ops = &s5k5baf_cis_subdev_internal_ops;
1890 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1891
1892 state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
1893 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
1894 ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad, 0);
1895 if (ret < 0)
1896 goto err;
1897
1898 sd = &state->sd;
1899 v4l2_i2c_subdev_init(sd, c, &s5k5baf_subdev_ops);
1900 snprintf(sd->name, sizeof(sd->name), "S5K5BAF-ISP %d-%04x",
1901 i2c_adapter_id(c->adapter), c->addr);
1902
1903 sd->internal_ops = &s5k5baf_subdev_internal_ops;
1904 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1905
1906 state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
1907 state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
1908 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
1909 ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads, 0);
1910
1911 if (!ret)
1912 return 0;
1913
1914 media_entity_cleanup(&state->cis_sd.entity);
1915err:
1916 dev_err(&c->dev, "cannot init media entity %s\n", sd->name);
1917 return ret;
1918}
1919
1920static int s5k5baf_configure_regulators(struct s5k5baf *state)
1921{
1922 struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
1923 int ret;
1924 int i;
1925
1926 for (i = 0; i < S5K5BAF_NUM_SUPPLIES; i++)
1927 state->supplies[i].supply = s5k5baf_supply_names[i];
1928
1929 ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES,
1930 state->supplies);
1931 if (ret < 0)
1932 v4l2_err(c, "failed to get regulators\n");
1933 return ret;
1934}
1935
1936static int s5k5baf_probe(struct i2c_client *c,
1937 const struct i2c_device_id *id)
1938{
1939 struct s5k5baf *state;
1940 int ret;
1941
1942 state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL);
1943 if (!state)
1944 return -ENOMEM;
1945
1946 mutex_init(&state->lock);
1947 state->crop_sink = s5k5baf_cis_rect;
1948 state->compose = s5k5baf_cis_rect;
1949 state->crop_source = s5k5baf_cis_rect;
1950
1951 ret = s5k5baf_parse_device_node(state, &c->dev);
1952 if (ret < 0)
1953 return ret;
1954
1955 ret = s5k5baf_configure_subdevs(state, c);
1956 if (ret < 0)
1957 return ret;
1958
1959 ret = s5k5baf_configure_gpios(state);
1960 if (ret < 0)
1961 goto err_me;
1962
1963 ret = s5k5baf_configure_regulators(state);
1964 if (ret < 0)
1965 goto err_me;
1966
1967 state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
1968 if (IS_ERR(state->clock)) {
1969 ret = -EPROBE_DEFER;
1970 goto err_me;
1971 }
1972
1973 ret = s5k5baf_power_on(state);
1974 if (ret < 0) {
1975 ret = -EPROBE_DEFER;
1976 goto err_me;
1977 }
1978 s5k5baf_hw_init(state);
1979 ret = s5k5baf_check_fw_revision(state);
1980
1981 s5k5baf_power_off(state);
1982 if (ret < 0)
1983 goto err_me;
1984
1985 ret = s5k5baf_initialize_ctrls(state);
1986 if (ret < 0)
1987 goto err_me;
1988
1989 ret = v4l2_async_register_subdev(&state->sd);
1990 if (ret < 0)
1991 goto err_ctrl;
1992
1993 return 0;
1994
1995err_ctrl:
1996 v4l2_ctrl_handler_free(state->sd.ctrl_handler);
1997err_me:
1998 media_entity_cleanup(&state->sd.entity);
1999 media_entity_cleanup(&state->cis_sd.entity);
2000 return ret;
2001}
2002
2003static int s5k5baf_remove(struct i2c_client *c)
2004{
2005 struct v4l2_subdev *sd = i2c_get_clientdata(c);
2006 struct s5k5baf *state = to_s5k5baf(sd);
2007
2008 v4l2_async_unregister_subdev(sd);
2009 v4l2_ctrl_handler_free(sd->ctrl_handler);
2010 media_entity_cleanup(&sd->entity);
2011
2012 sd = &state->cis_sd;
2013 v4l2_device_unregister_subdev(sd);
2014 media_entity_cleanup(&sd->entity);
2015
2016 return 0;
2017}
2018
2019static const struct i2c_device_id s5k5baf_id[] = {
2020 { S5K5BAF_DRIVER_NAME, 0 },
2021 { },
2022};
2023MODULE_DEVICE_TABLE(i2c, s5k5baf_id);
2024
2025static const struct of_device_id s5k5baf_of_match[] = {
2026 { .compatible = "samsung,s5k5baf" },
2027 { }
2028};
2029MODULE_DEVICE_TABLE(of, s5k5baf_of_match);
2030
2031static struct i2c_driver s5k5baf_i2c_driver = {
2032 .driver = {
2033 .of_match_table = s5k5baf_of_match,
2034 .name = S5K5BAF_DRIVER_NAME
2035 },
2036 .probe = s5k5baf_probe,
2037 .remove = s5k5baf_remove,
2038 .id_table = s5k5baf_id,
2039};
2040
2041module_i2c_driver(s5k5baf_i2c_driver);
2042
2043MODULE_DESCRIPTION("Samsung S5K5BAF(X) UXGA camera driver");
2044MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
2045MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c
index 70bc72e795d0..2960b5a8362a 100644
--- a/drivers/media/i2c/saa6588.c
+++ b/drivers/media/i2c/saa6588.c
@@ -150,14 +150,14 @@ static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
150 150
151/* ---------------------------------------------------------------------- */ 151/* ---------------------------------------------------------------------- */
152 152
153static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf) 153static bool block_from_buf(struct saa6588 *s, unsigned char *buf)
154{ 154{
155 int i; 155 int i;
156 156
157 if (s->rd_index == s->wr_index) { 157 if (s->rd_index == s->wr_index) {
158 if (debug > 2) 158 if (debug > 2)
159 dprintk(PREFIX "Read: buffer empty.\n"); 159 dprintk(PREFIX "Read: buffer empty.\n");
160 return 0; 160 return false;
161 } 161 }
162 162
163 if (debug > 2) { 163 if (debug > 2) {
@@ -166,8 +166,7 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
166 dprintk("0x%02x ", s->buffer[i]); 166 dprintk("0x%02x ", s->buffer[i]);
167 } 167 }
168 168
169 if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3)) 169 memcpy(buf, &s->buffer[s->rd_index], 3);
170 return -EFAULT;
171 170
172 s->rd_index += 3; 171 s->rd_index += 3;
173 if (s->rd_index >= s->buf_size) 172 if (s->rd_index >= s->buf_size)
@@ -177,22 +176,22 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
177 if (debug > 2) 176 if (debug > 2)
178 dprintk("%d blocks total.\n", s->block_count); 177 dprintk("%d blocks total.\n", s->block_count);
179 178
180 return 1; 179 return true;
181} 180}
182 181
183static void read_from_buf(struct saa6588 *s, struct saa6588_command *a) 182static void read_from_buf(struct saa6588 *s, struct saa6588_command *a)
184{ 183{
185 unsigned long flags;
186
187 unsigned char __user *buf_ptr = a->buffer; 184 unsigned char __user *buf_ptr = a->buffer;
188 unsigned int i; 185 unsigned char buf[3];
186 unsigned long flags;
189 unsigned int rd_blocks; 187 unsigned int rd_blocks;
188 unsigned int i;
190 189
191 a->result = 0; 190 a->result = 0;
192 if (!a->buffer) 191 if (!a->buffer)
193 return; 192 return;
194 193
195 while (!s->data_available_for_read) { 194 while (!a->nonblocking && !s->data_available_for_read) {
196 int ret = wait_event_interruptible(s->read_queue, 195 int ret = wait_event_interruptible(s->read_queue,
197 s->data_available_for_read); 196 s->data_available_for_read);
198 if (ret == -ERESTARTSYS) { 197 if (ret == -ERESTARTSYS) {
@@ -201,24 +200,31 @@ static void read_from_buf(struct saa6588 *s, struct saa6588_command *a)
201 } 200 }
202 } 201 }
203 202
204 spin_lock_irqsave(&s->lock, flags);
205 rd_blocks = a->block_count; 203 rd_blocks = a->block_count;
204 spin_lock_irqsave(&s->lock, flags);
206 if (rd_blocks > s->block_count) 205 if (rd_blocks > s->block_count)
207 rd_blocks = s->block_count; 206 rd_blocks = s->block_count;
207 spin_unlock_irqrestore(&s->lock, flags);
208 208
209 if (!rd_blocks) { 209 if (!rd_blocks)
210 spin_unlock_irqrestore(&s->lock, flags);
211 return; 210 return;
212 }
213 211
214 for (i = 0; i < rd_blocks; i++) { 212 for (i = 0; i < rd_blocks; i++) {
215 if (block_to_user_buf(s, buf_ptr)) { 213 bool got_block;
216 buf_ptr += 3; 214
217 a->result++; 215 spin_lock_irqsave(&s->lock, flags);
218 } else 216 got_block = block_from_buf(s, buf);
217 spin_unlock_irqrestore(&s->lock, flags);
218 if (!got_block)
219 break; 219 break;
220 if (copy_to_user(buf_ptr, buf, 3)) {
221 a->result = -EFAULT;
222 return;
223 }
224 buf_ptr += 3;
225 a->result += 3;
220 } 226 }
221 a->result *= 3; 227 spin_lock_irqsave(&s->lock, flags);
222 s->data_available_for_read = (s->block_count > 0); 228 s->data_available_for_read = (s->block_count > 0);
223 spin_unlock_irqrestore(&s->lock, flags); 229 spin_unlock_irqrestore(&s->lock, flags);
224} 230}
@@ -394,14 +400,11 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
394 struct saa6588_command *a = arg; 400 struct saa6588_command *a = arg;
395 401
396 switch (cmd) { 402 switch (cmd) {
397 /* --- open() for /dev/radio --- */
398 case SAA6588_CMD_OPEN:
399 a->result = 0; /* return error if chip doesn't work ??? */
400 break;
401 /* --- close() for /dev/radio --- */ 403 /* --- close() for /dev/radio --- */
402 case SAA6588_CMD_CLOSE: 404 case SAA6588_CMD_CLOSE:
403 s->data_available_for_read = 1; 405 s->data_available_for_read = 1;
404 wake_up_interruptible(&s->read_queue); 406 wake_up_interruptible(&s->read_queue);
407 s->data_available_for_read = 0;
405 a->result = 0; 408 a->result = 0;
406 break; 409 break;
407 /* --- read() for /dev/radio --- */ 410 /* --- read() for /dev/radio --- */
@@ -411,9 +414,8 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
411 /* --- poll() for /dev/radio --- */ 414 /* --- poll() for /dev/radio --- */
412 case SAA6588_CMD_POLL: 415 case SAA6588_CMD_POLL:
413 a->result = 0; 416 a->result = 0;
414 if (s->data_available_for_read) { 417 if (s->data_available_for_read)
415 a->result |= POLLIN | POLLRDNORM; 418 a->result |= POLLIN | POLLRDNORM;
416 }
417 poll_wait(a->instance, &s->read_queue, a->event_list); 419 poll_wait(a->instance, &s->read_queue, a->event_list);
418 break; 420 break;
419 421
diff --git a/drivers/media/pci/saa7134/saa6752hs.c b/drivers/media/i2c/saa6752hs.c
index 8ac4b1f2322d..8272c0b9c5bf 100644
--- a/drivers/media/pci/saa7134/saa6752hs.c
+++ b/drivers/media/i2c/saa6752hs.c
@@ -33,11 +33,11 @@
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/videodev2.h> 35#include <linux/videodev2.h>
36#include <linux/init.h>
37#include <linux/crc32.h>
36#include <media/v4l2-device.h> 38#include <media/v4l2-device.h>
37#include <media/v4l2-ctrls.h> 39#include <media/v4l2-ctrls.h>
38#include <media/v4l2-common.h> 40#include <media/v4l2-common.h>
39#include <linux/init.h>
40#include <linux/crc32.h>
41 41
42#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 42#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
43#define MPEG_VIDEO_MAX_BITRATE_MAX 27000 43#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
@@ -124,7 +124,7 @@ static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
124 124
125/* ---------------------------------------------------------------------- */ 125/* ---------------------------------------------------------------------- */
126 126
127static u8 PAT[] = { 127static const u8 PAT[] = {
128 0xc2, /* i2c register */ 128 0xc2, /* i2c register */
129 0x00, /* table number for encoder */ 129 0x00, /* table number for encoder */
130 130
@@ -150,7 +150,7 @@ static u8 PAT[] = {
150 0x00, 0x00, 0x00, 0x00 /* CRC32 */ 150 0x00, 0x00, 0x00, 0x00 /* CRC32 */
151}; 151};
152 152
153static u8 PMT[] = { 153static const u8 PMT[] = {
154 0xc2, /* i2c register */ 154 0xc2, /* i2c register */
155 0x01, /* table number for encoder */ 155 0x01, /* table number for encoder */
156 156
@@ -179,7 +179,7 @@ static u8 PMT[] = {
179 0x00, 0x00, 0x00, 0x00 /* CRC32 */ 179 0x00, 0x00, 0x00, 0x00 /* CRC32 */
180}; 180};
181 181
182static u8 PMT_AC3[] = { 182static const u8 PMT_AC3[] = {
183 0xc2, /* i2c register */ 183 0xc2, /* i2c register */
184 0x01, /* table number for encoder(1) */ 184 0x01, /* table number for encoder(1) */
185 0x47, /* sync */ 185 0x47, /* sync */
@@ -212,7 +212,7 @@ static u8 PMT_AC3[] = {
212 0xED, 0xDE, 0x2D, 0xF3 /* CRC32 BE */ 212 0xED, 0xDE, 0x2D, 0xF3 /* CRC32 BE */
213}; 213};
214 214
215static struct saa6752hs_mpeg_params param_defaults = 215static const struct saa6752hs_mpeg_params param_defaults =
216{ 216{
217 .ts_pid_pmt = 16, 217 .ts_pid_pmt = 16,
218 .ts_pid_video = 260, 218 .ts_pid_video = 260,
@@ -643,13 +643,6 @@ static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = {
643 643
644static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { 644static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
645 .init = saa6752hs_init, 645 .init = saa6752hs_init,
646 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
647 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
648 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
649 .g_ctrl = v4l2_subdev_g_ctrl,
650 .s_ctrl = v4l2_subdev_s_ctrl,
651 .queryctrl = v4l2_subdev_queryctrl,
652 .querymenu = v4l2_subdev_querymenu,
653 .s_std = saa6752hs_s_std, 646 .s_std = saa6752hs_s_std,
654}; 647};
655 648
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index ae66d91bf713..8741cae9c9f2 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -399,7 +399,6 @@ static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor)
399 399
400 BUG_ON(max(internal_csi_format_idx, csi_format_idx) + pixel_order 400 BUG_ON(max(internal_csi_format_idx, csi_format_idx) + pixel_order
401 >= ARRAY_SIZE(smiapp_csi_data_formats)); 401 >= ARRAY_SIZE(smiapp_csi_data_formats));
402 BUG_ON(min(internal_csi_format_idx, csi_format_idx) < 0);
403 402
404 dev_dbg(&client->dev, "new pixel order %s\n", 403 dev_dbg(&client->dev, "new pixel order %s\n",
405 pixel_order_str[pixel_order]); 404 pixel_order_str[pixel_order]);
@@ -2028,8 +2027,8 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev,
2028 sel->r.width = min(sel->r.width, src_size->width); 2027 sel->r.width = min(sel->r.width, src_size->width);
2029 sel->r.height = min(sel->r.height, src_size->height); 2028 sel->r.height = min(sel->r.height, src_size->height);
2030 2029
2031 sel->r.left = min(sel->r.left, src_size->width - sel->r.width); 2030 sel->r.left = min_t(int, sel->r.left, src_size->width - sel->r.width);
2032 sel->r.top = min(sel->r.top, src_size->height - sel->r.height); 2031 sel->r.top = min_t(int, sel->r.top, src_size->height - sel->r.height);
2033 2032
2034 *crops[sel->pad] = sel->r; 2033 *crops[sel->pad] = sel->r;
2035 2034
@@ -2121,8 +2120,8 @@ static int smiapp_set_selection(struct v4l2_subdev *subdev,
2121 2120
2122 sel->r.left = max(0, sel->r.left & ~1); 2121 sel->r.left = max(0, sel->r.left & ~1);
2123 sel->r.top = max(0, sel->r.top & ~1); 2122 sel->r.top = max(0, sel->r.top & ~1);
2124 sel->r.width = max(0, SMIAPP_ALIGN_DIM(sel->r.width, sel->flags)); 2123 sel->r.width = SMIAPP_ALIGN_DIM(sel->r.width, sel->flags);
2125 sel->r.height = max(0, SMIAPP_ALIGN_DIM(sel->r.height, sel->flags)); 2124 sel->r.height = SMIAPP_ALIGN_DIM(sel->r.height, sel->flags);
2126 2125
2127 sel->r.width = max_t(unsigned int, 2126 sel->r.width = max_t(unsigned int,
2128 sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE], 2127 sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index 6f4056668bbc..ccf59406a172 100644
--- a/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -208,8 +208,8 @@ struct mt9m111 {
208 struct mt9m111_context *ctx; 208 struct mt9m111_context *ctx;
209 struct v4l2_rect rect; /* cropping rectangle */ 209 struct v4l2_rect rect; /* cropping rectangle */
210 struct v4l2_clk *clk; 210 struct v4l2_clk *clk;
211 int width; /* output */ 211 unsigned int width; /* output */
212 int height; /* sizes */ 212 unsigned int height; /* sizes */
213 struct mutex power_lock; /* lock to protect power_count */ 213 struct mutex power_lock; /* lock to protect power_count */
214 int power_count; 214 int power_count;
215 const struct mt9m111_datafmt *fmt; 215 const struct mt9m111_datafmt *fmt;
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 89c0b13463b7..542d2528b3f9 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -58,21 +58,17 @@ static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
58 struct i2c_client *c = v4l2_get_subdevdata(sd); 58 struct i2c_client *c = v4l2_get_subdevdata(sd);
59 unsigned char buffer[1]; 59 unsigned char buffer[1];
60 int rc; 60 int rc;
61 61 struct i2c_msg msg[] = {
62 buffer[0] = addr; 62 { .addr = c->addr, .flags = 0,
63 63 .buf = &addr, .len = 1 },
64 rc = i2c_master_send(c, buffer, 1); 64 { .addr = c->addr, .flags = I2C_M_RD,
65 if (rc < 0) { 65 .buf = buffer, .len = 1 }
66 v4l2_err(sd, "i2c i/o error: rc == %d (should be 1)\n", rc); 66 };
67 return rc; 67
68 } 68 rc = i2c_transfer(c->adapter, msg, 2);
69 69 if (rc < 0 || rc != 2) {
70 msleep(10); 70 v4l2_err(sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
71 71 return rc < 0 ? rc : -EIO;
72 rc = i2c_master_recv(c, buffer, 1);
73 if (rc < 0) {
74 v4l2_err(sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
75 return rc;
76 } 72 }
77 73
78 v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); 74 v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
@@ -867,7 +863,7 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
867 struct v4l2_rect rect = a->c; 863 struct v4l2_rect rect = a->c;
868 struct tvp5150 *decoder = to_tvp5150(sd); 864 struct tvp5150 *decoder = to_tvp5150(sd);
869 v4l2_std_id std; 865 v4l2_std_id std;
870 int hmax; 866 unsigned int hmax;
871 867
872 v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n", 868 v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n",
873 __func__, rect.left, rect.top, rect.width, rect.height); 869 __func__, rect.left, rect.top, rect.width, rect.height);
@@ -877,9 +873,9 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
877 873
878 /* tvp5150 has some special limits */ 874 /* tvp5150 has some special limits */
879 rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT); 875 rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
880 rect.width = clamp(rect.width, 876 rect.width = clamp_t(unsigned int, rect.width,
881 TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left, 877 TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
882 TVP5150_H_MAX - rect.left); 878 TVP5150_H_MAX - rect.left);
883 rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP); 879 rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP);
884 880
885 /* Calculate height based on current standard */ 881 /* Calculate height based on current standard */
@@ -893,9 +889,9 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
893 else 889 else
894 hmax = TVP5150_V_MAX_OTHERS; 890 hmax = TVP5150_V_MAX_OTHERS;
895 891
896 rect.height = clamp(rect.height, 892 rect.height = clamp_t(unsigned int, rect.height,
897 hmax - TVP5150_MAX_CROP_TOP - rect.top, 893 hmax - TVP5150_MAX_CROP_TOP - rect.top,
898 hmax - rect.top); 894 hmax - rect.top);
899 895
900 tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top); 896 tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top);
901 tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 897 tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP,
diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
index 25bdd9312fea..23f4f65fccd7 100644
--- a/drivers/media/i2c/vs6624.c
+++ b/drivers/media/i2c/vs6624.c
@@ -503,6 +503,7 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
503 return &container_of(ctrl->handler, struct vs6624, hdl)->sd; 503 return &container_of(ctrl->handler, struct vs6624, hdl)->sd;
504} 504}
505 505
506#ifdef CONFIG_VIDEO_ADV_DEBUG
506static int vs6624_read(struct v4l2_subdev *sd, u16 index) 507static int vs6624_read(struct v4l2_subdev *sd, u16 index)
507{ 508{
508 struct i2c_client *client = v4l2_get_subdevdata(sd); 509 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -515,6 +516,7 @@ static int vs6624_read(struct v4l2_subdev *sd, u16 index)
515 516
516 return buf[0]; 517 return buf[0];
517} 518}
519#endif
518 520
519static int vs6624_write(struct v4l2_subdev *sd, u16 index, 521static int vs6624_write(struct v4l2_subdev *sd, u16 index,
520 u8 value) 522 u8 value)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 2c286c307145..37c334edc7e8 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -235,6 +235,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
235 media_entity_graph_walk_start(&graph, entity); 235 media_entity_graph_walk_start(&graph, entity);
236 236
237 while ((entity = media_entity_graph_walk_next(&graph))) { 237 while ((entity = media_entity_graph_walk_next(&graph))) {
238 DECLARE_BITMAP(active, entity->num_pads);
239 DECLARE_BITMAP(has_no_links, entity->num_pads);
238 unsigned int i; 240 unsigned int i;
239 241
240 entity->stream_count++; 242 entity->stream_count++;
@@ -248,21 +250,46 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
248 if (!entity->ops || !entity->ops->link_validate) 250 if (!entity->ops || !entity->ops->link_validate)
249 continue; 251 continue;
250 252
253 bitmap_zero(active, entity->num_pads);
254 bitmap_fill(has_no_links, entity->num_pads);
255
251 for (i = 0; i < entity->num_links; i++) { 256 for (i = 0; i < entity->num_links; i++) {
252 struct media_link *link = &entity->links[i]; 257 struct media_link *link = &entity->links[i];
253 258 struct media_pad *pad = link->sink->entity == entity
254 /* Is this pad part of an enabled link? */ 259 ? link->sink : link->source;
255 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) 260
256 continue; 261 /* Mark that a pad is connected by a link. */
257 262 bitmap_clear(has_no_links, pad->index, 1);
258 /* Are we the sink or not? */ 263
259 if (link->sink->entity != entity) 264 /*
265 * Pads that either do not need to connect or
266 * are connected through an enabled link are
267 * fine.
268 */
269 if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) ||
270 link->flags & MEDIA_LNK_FL_ENABLED)
271 bitmap_set(active, pad->index, 1);
272
273 /*
274 * Link validation will only take place for
275 * sink ends of the link that are enabled.
276 */
277 if (link->sink != pad ||
278 !(link->flags & MEDIA_LNK_FL_ENABLED))
260 continue; 279 continue;
261 280
262 ret = entity->ops->link_validate(link); 281 ret = entity->ops->link_validate(link);
263 if (ret < 0 && ret != -ENOIOCTLCMD) 282 if (ret < 0 && ret != -ENOIOCTLCMD)
264 goto error; 283 goto error;
265 } 284 }
285
286 /* Either no links or validated links are fine. */
287 bitmap_or(active, active, has_no_links, entity->num_pads);
288
289 if (!bitmap_full(active, entity->num_pads)) {
290 ret = -EPIPE;
291 goto error;
292 }
266 } 293 }
267 294
268 mutex_unlock(&mdev->graph_mutex); 295 mutex_unlock(&mdev->graph_mutex);
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 92a06fd85865..afcd53bfcf8e 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -1126,9 +1126,9 @@ bttv_crop_calc_limits(struct bttv_crop *c)
1126 c->min_scaled_height = 32; 1126 c->min_scaled_height = 32;
1127 } else { 1127 } else {
1128 c->min_scaled_width = 1128 c->min_scaled_width =
1129 (max(48, c->rect.width >> 4) + 3) & ~3; 1129 (max_t(unsigned int, 48, c->rect.width >> 4) + 3) & ~3;
1130 c->min_scaled_height = 1130 c->min_scaled_height =
1131 max(32, c->rect.height >> 4); 1131 max_t(unsigned int, 32, c->rect.height >> 4);
1132 } 1132 }
1133 1133
1134 c->max_scaled_width = c->rect.width & ~3; 1134 c->max_scaled_width = c->rect.width & ~3;
@@ -2024,7 +2024,7 @@ limit_scaled_size_lock (struct bttv_fh * fh,
2024 /* We cannot scale up. When the scaled image is larger 2024 /* We cannot scale up. When the scaled image is larger
2025 than crop.rect we adjust the crop.rect as required 2025 than crop.rect we adjust the crop.rect as required
2026 by the V4L2 spec, hence cropcap.bounds are our limit. */ 2026 by the V4L2 spec, hence cropcap.bounds are our limit. */
2027 max_width = min(b->width, (__s32) MAX_HACTIVE); 2027 max_width = min_t(unsigned int, b->width, MAX_HACTIVE);
2028 max_height = b->height; 2028 max_height = b->height;
2029 2029
2030 /* We cannot capture the same line as video and VBI data. 2030 /* We cannot capture the same line as video and VBI data.
@@ -3266,7 +3266,9 @@ static ssize_t radio_read(struct file *file, char __user *data,
3266 struct bttv_fh *fh = file->private_data; 3266 struct bttv_fh *fh = file->private_data;
3267 struct bttv *btv = fh->btv; 3267 struct bttv *btv = fh->btv;
3268 struct saa6588_command cmd; 3268 struct saa6588_command cmd;
3269 cmd.block_count = count/3; 3269
3270 cmd.block_count = count / 3;
3271 cmd.nonblocking = file->f_flags & O_NONBLOCK;
3270 cmd.buffer = data; 3272 cmd.buffer = data;
3271 cmd.instance = file; 3273 cmd.instance = file;
3272 cmd.result = -ENODEV; 3274 cmd.result = -ENODEV;
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
index c1f8cc6f14b2..716bdc57fac6 100644
--- a/drivers/media/pci/cx18/cx18-driver.c
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -327,13 +327,16 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
327 struct i2c_client *c; 327 struct i2c_client *c;
328 u8 eedata[256]; 328 u8 eedata[256];
329 329
330 memset(tv, 0, sizeof(*tv));
331
330 c = kzalloc(sizeof(*c), GFP_KERNEL); 332 c = kzalloc(sizeof(*c), GFP_KERNEL);
333 if (!c)
334 return;
331 335
332 strlcpy(c->name, "cx18 tveeprom tmp", sizeof(c->name)); 336 strlcpy(c->name, "cx18 tveeprom tmp", sizeof(c->name));
333 c->adapter = &cx->i2c_adap[0]; 337 c->adapter = &cx->i2c_adap[0];
334 c->addr = 0xa0 >> 1; 338 c->addr = 0xa0 >> 1;
335 339
336 memset(tv, 0, sizeof(*tv));
337 if (tveeprom_read(c, eedata, sizeof(eedata))) 340 if (tveeprom_read(c, eedata, sizeof(eedata)))
338 goto ret; 341 goto ret;
339 342
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index 6e91e84d6bf9..b1e08c3e55cd 100644
--- a/drivers/media/pci/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
@@ -618,7 +618,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
618 * Only boards with eeprom and byte 1 at eeprom=1 have it 618 * Only boards with eeprom and byte 1 at eeprom=1 have it
619 */ 619 */
620 620
621static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = { 621static const struct pci_device_id cx25821_audio_pci_tbl[] = {
622 {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 622 {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
623 {0,} 623 {0,}
624}; 624};
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index b762c5b2ca10..e81173c41e5a 100644
--- a/drivers/media/pci/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
@@ -1361,7 +1361,7 @@ static void cx25821_finidev(struct pci_dev *pci_dev)
1361 kfree(dev); 1361 kfree(dev);
1362} 1362}
1363 1363
1364static DEFINE_PCI_DEVICE_TABLE(cx25821_pci_tbl) = { 1364static const struct pci_device_id cx25821_pci_tbl[] = {
1365 { 1365 {
1366 /* CX25821 Athena */ 1366 /* CX25821 Athena */
1367 .vendor = 0x14f1, 1367 .vendor = 0x14f1,
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c
index 400eb1c42d3f..d014206e7176 100644
--- a/drivers/media/pci/cx88/cx88-alsa.c
+++ b/drivers/media/pci/cx88/cx88-alsa.c
@@ -931,9 +931,9 @@ error:
931 */ 931 */
932static void cx88_audio_finidev(struct pci_dev *pci) 932static void cx88_audio_finidev(struct pci_dev *pci)
933{ 933{
934 struct cx88_audio_dev *card = pci_get_drvdata(pci); 934 struct snd_card *card = pci_get_drvdata(pci);
935 935
936 snd_card_free((void *)card); 936 snd_card_free(card);
937 937
938 devno--; 938 devno--;
939} 939}
diff --git a/drivers/media/pci/saa7134/Kconfig b/drivers/media/pci/saa7134/Kconfig
index 15b90d6e9130..7883393571e5 100644
--- a/drivers/media/pci/saa7134/Kconfig
+++ b/drivers/media/pci/saa7134/Kconfig
@@ -6,6 +6,7 @@ config VIDEO_SAA7134
6 select VIDEO_TVEEPROM 6 select VIDEO_TVEEPROM
7 select CRC32 7 select CRC32
8 select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT 8 select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT
9 select VIDEO_SAA6752HS if MEDIA_SUBDRV_AUTOSELECT
9 ---help--- 10 ---help---
10 This is a video4linux driver for Philips SAA713x based 11 This is a video4linux driver for Philips SAA713x based
11 TV cards. 12 TV cards.
diff --git a/drivers/media/pci/saa7134/Makefile b/drivers/media/pci/saa7134/Makefile
index 35375480ed4d..58de9b085689 100644
--- a/drivers/media/pci/saa7134/Makefile
+++ b/drivers/media/pci/saa7134/Makefile
@@ -4,7 +4,7 @@ saa7134-y += saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o
4saa7134-y += saa7134-video.o 4saa7134-y += saa7134-video.o
5saa7134-$(CONFIG_VIDEO_SAA7134_RC) += saa7134-input.o 5saa7134-$(CONFIG_VIDEO_SAA7134_RC) += saa7134-input.o
6 6
7obj-$(CONFIG_VIDEO_SAA7134) += saa6752hs.o saa7134.o saa7134-empress.o 7obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o
8 8
9obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o 9obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
10 10
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index 27d7ee709c58..1362b4aab473 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -751,6 +751,7 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
751 saa7134_input_fini(dev); 751 saa7134_input_fini(dev);
752 saa7134_vbi_fini(dev); 752 saa7134_vbi_fini(dev);
753 saa7134_tvaudio_fini(dev); 753 saa7134_tvaudio_fini(dev);
754 saa7134_video_fini(dev);
754 return 0; 755 return 0;
755} 756}
756 757
@@ -802,7 +803,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
802 *vfd = *template; 803 *vfd = *template;
803 vfd->v4l2_dev = &dev->v4l2_dev; 804 vfd->v4l2_dev = &dev->v4l2_dev;
804 vfd->release = video_device_release; 805 vfd->release = video_device_release;
805 vfd->debug = video_debug;
806 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", 806 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
807 dev->name, type, saa7134_boards[dev->board].name); 807 dev->name, type, saa7134_boards[dev->board].name);
808 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); 808 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
@@ -1008,13 +1008,13 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
1008 1008
1009 /* load i2c helpers */ 1009 /* load i2c helpers */
1010 if (card_is_empress(dev)) { 1010 if (card_is_empress(dev)) {
1011 struct v4l2_subdev *sd = 1011 dev->empress_sd =
1012 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 1012 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
1013 "saa6752hs", 1013 "saa6752hs",
1014 saa7134_boards[dev->board].empress_addr, NULL); 1014 saa7134_boards[dev->board].empress_addr, NULL);
1015 1015
1016 if (sd) 1016 if (dev->empress_sd)
1017 sd->grp_id = GRP_EMPRESS; 1017 dev->empress_sd->grp_id = GRP_EMPRESS;
1018 } 1018 }
1019 1019
1020 if (saa7134_boards[dev->board].rds_addr) { 1020 if (saa7134_boards[dev->board].rds_addr) {
@@ -1046,6 +1046,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
1046 printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name); 1046 printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
1047 1047
1048 dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); 1048 dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
1049 dev->video_dev->ctrl_handler = &dev->ctrl_handler;
1049 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, 1050 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
1050 video_nr[dev->nr]); 1051 video_nr[dev->nr]);
1051 if (err < 0) { 1052 if (err < 0) {
@@ -1057,6 +1058,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
1057 dev->name, video_device_node_name(dev->video_dev)); 1058 dev->name, video_device_node_name(dev->video_dev));
1058 1059
1059 dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); 1060 dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
1061 dev->vbi_dev->ctrl_handler = &dev->ctrl_handler;
1060 1062
1061 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, 1063 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
1062 vbi_nr[dev->nr]); 1064 vbi_nr[dev->nr]);
@@ -1067,6 +1069,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
1067 1069
1068 if (card_has_radio(dev)) { 1070 if (card_has_radio(dev)) {
1069 dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); 1071 dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
1072 dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler;
1070 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, 1073 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
1071 radio_nr[dev->nr]); 1074 radio_nr[dev->nr]);
1072 if (err < 0) 1075 if (err < 0)
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 3022eb2a7925..0a9047e754b9 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -23,12 +23,12 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25 25
26#include <media/v4l2-common.h>
27#include <media/v4l2-event.h>
28
26#include "saa7134-reg.h" 29#include "saa7134-reg.h"
27#include "saa7134.h" 30#include "saa7134.h"
28 31
29#include <media/saa6752hs.h>
30#include <media/v4l2-common.h>
31
32/* ------------------------------------------------------------------ */ 32/* ------------------------------------------------------------------ */
33 33
34MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 34MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -85,52 +85,54 @@ static int ts_open(struct file *file)
85{ 85{
86 struct video_device *vdev = video_devdata(file); 86 struct video_device *vdev = video_devdata(file);
87 struct saa7134_dev *dev = video_drvdata(file); 87 struct saa7134_dev *dev = video_drvdata(file);
88 int err; 88 struct saa7134_fh *fh;
89 89
90 dprintk("open dev=%s\n", video_device_node_name(vdev)); 90 /* allocate + initialize per filehandle data */
91 err = -EBUSY; 91 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
92 if (!mutex_trylock(&dev->empress_tsq.vb_lock)) 92 if (NULL == fh)
93 return err; 93 return -ENOMEM;
94 if (atomic_read(&dev->empress_users)) 94
95 goto done; 95 v4l2_fh_init(&fh->fh, vdev);
96 file->private_data = fh;
97 fh->is_empress = true;
98 v4l2_fh_add(&fh->fh);
96 99
97 /* Unmute audio */ 100 /* Unmute audio */
98 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, 101 saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
99 saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); 102 saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
100 103
101 atomic_inc(&dev->empress_users); 104 return 0;
102 file->private_data = dev;
103 err = 0;
104
105done:
106 mutex_unlock(&dev->empress_tsq.vb_lock);
107 return err;
108} 105}
109 106
110static int ts_release(struct file *file) 107static int ts_release(struct file *file)
111{ 108{
112 struct saa7134_dev *dev = file->private_data; 109 struct saa7134_dev *dev = video_drvdata(file);
110 struct saa7134_fh *fh = file->private_data;
113 111
114 videobuf_stop(&dev->empress_tsq); 112 if (res_check(fh, RESOURCE_EMPRESS)) {
115 videobuf_mmap_free(&dev->empress_tsq); 113 videobuf_stop(&dev->empress_tsq);
114 videobuf_mmap_free(&dev->empress_tsq);
116 115
117 /* stop the encoder */ 116 /* stop the encoder */
118 ts_reset_encoder(dev); 117 ts_reset_encoder(dev);
119 118
120 /* Mute audio */ 119 /* Mute audio */
121 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, 120 saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
122 saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); 121 saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
123 122 }
124 atomic_dec(&dev->empress_users);
125 123
124 v4l2_fh_del(&fh->fh);
125 v4l2_fh_exit(&fh->fh);
126 return 0; 126 return 0;
127} 127}
128 128
129static ssize_t 129static ssize_t
130ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 130ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
131{ 131{
132 struct saa7134_dev *dev = file->private_data; 132 struct saa7134_dev *dev = video_drvdata(file);
133 133
134 if (res_locked(dev, RESOURCE_EMPRESS))
135 return -EBUSY;
134 if (!dev->empress_started) 136 if (!dev->empress_started)
135 ts_init_encoder(dev); 137 ts_init_encoder(dev);
136 138
@@ -142,68 +144,27 @@ ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
142static unsigned int 144static unsigned int
143ts_poll(struct file *file, struct poll_table_struct *wait) 145ts_poll(struct file *file, struct poll_table_struct *wait)
144{ 146{
145 struct saa7134_dev *dev = file->private_data; 147 unsigned long req_events = poll_requested_events(wait);
148 struct saa7134_dev *dev = video_drvdata(file);
149 struct saa7134_fh *fh = file->private_data;
150 unsigned int rc = 0;
146 151
147 return videobuf_poll_stream(file, &dev->empress_tsq, wait); 152 if (v4l2_event_pending(&fh->fh))
153 rc = POLLPRI;
154 else if (req_events & POLLPRI)
155 poll_wait(file, &fh->fh.wait, wait);
156 return rc | videobuf_poll_stream(file, &dev->empress_tsq, wait);
148} 157}
149 158
150 159
151static int 160static int
152ts_mmap(struct file *file, struct vm_area_struct * vma) 161ts_mmap(struct file *file, struct vm_area_struct * vma)
153{ 162{
154 struct saa7134_dev *dev = file->private_data; 163 struct saa7134_dev *dev = video_drvdata(file);
155 164
156 return videobuf_mmap_mapper(&dev->empress_tsq, vma); 165 return videobuf_mmap_mapper(&dev->empress_tsq, vma);
157} 166}
158 167
159/*
160 * This function is _not_ called directly, but from
161 * video_generic_ioctl (and maybe others). userspace
162 * copying is done already, arg is a kernel pointer.
163 */
164
165static int empress_querycap(struct file *file, void *priv,
166 struct v4l2_capability *cap)
167{
168 struct saa7134_dev *dev = file->private_data;
169
170 strcpy(cap->driver, "saa7134");
171 strlcpy(cap->card, saa7134_boards[dev->board].name,
172 sizeof(cap->card));
173 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
174 cap->capabilities =
175 V4L2_CAP_VIDEO_CAPTURE |
176 V4L2_CAP_READWRITE |
177 V4L2_CAP_STREAMING;
178 return 0;
179}
180
181static int empress_enum_input(struct file *file, void *priv,
182 struct v4l2_input *i)
183{
184 if (i->index != 0)
185 return -EINVAL;
186
187 i->type = V4L2_INPUT_TYPE_CAMERA;
188 strcpy(i->name, "CCIR656");
189
190 return 0;
191}
192
193static int empress_g_input(struct file *file, void *priv, unsigned int *i)
194{
195 *i = 0;
196 return 0;
197}
198
199static int empress_s_input(struct file *file, void *priv, unsigned int i)
200{
201 if (i != 0)
202 return -EINVAL;
203
204 return 0;
205}
206
207static int empress_enum_fmt_vid_cap(struct file *file, void *priv, 168static int empress_enum_fmt_vid_cap(struct file *file, void *priv,
208 struct v4l2_fmtdesc *f) 169 struct v4l2_fmtdesc *f)
209{ 170{
@@ -219,7 +180,7 @@ static int empress_enum_fmt_vid_cap(struct file *file, void *priv,
219static int empress_g_fmt_vid_cap(struct file *file, void *priv, 180static int empress_g_fmt_vid_cap(struct file *file, void *priv,
220 struct v4l2_format *f) 181 struct v4l2_format *f)
221{ 182{
222 struct saa7134_dev *dev = file->private_data; 183 struct saa7134_dev *dev = video_drvdata(file);
223 struct v4l2_mbus_framefmt mbus_fmt; 184 struct v4l2_mbus_framefmt mbus_fmt;
224 185
225 saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt); 186 saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt);
@@ -236,7 +197,7 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
236static int empress_s_fmt_vid_cap(struct file *file, void *priv, 197static int empress_s_fmt_vid_cap(struct file *file, void *priv,
237 struct v4l2_format *f) 198 struct v4l2_format *f)
238{ 199{
239 struct saa7134_dev *dev = file->private_data; 200 struct saa7134_dev *dev = video_drvdata(file);
240 struct v4l2_mbus_framefmt mbus_fmt; 201 struct v4l2_mbus_framefmt mbus_fmt;
241 202
242 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); 203 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
@@ -254,7 +215,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
254static int empress_try_fmt_vid_cap(struct file *file, void *priv, 215static int empress_try_fmt_vid_cap(struct file *file, void *priv,
255 struct v4l2_format *f) 216 struct v4l2_format *f)
256{ 217{
257 struct saa7134_dev *dev = file->private_data; 218 struct saa7134_dev *dev = video_drvdata(file);
258 struct v4l2_mbus_framefmt mbus_fmt; 219 struct v4l2_mbus_framefmt mbus_fmt;
259 220
260 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); 221 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
@@ -269,175 +230,6 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,
269 return 0; 230 return 0;
270} 231}
271 232
272static int empress_reqbufs(struct file *file, void *priv,
273 struct v4l2_requestbuffers *p)
274{
275 struct saa7134_dev *dev = file->private_data;
276
277 return videobuf_reqbufs(&dev->empress_tsq, p);
278}
279
280static int empress_querybuf(struct file *file, void *priv,
281 struct v4l2_buffer *b)
282{
283 struct saa7134_dev *dev = file->private_data;
284
285 return videobuf_querybuf(&dev->empress_tsq, b);
286}
287
288static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
289{
290 struct saa7134_dev *dev = file->private_data;
291
292 return videobuf_qbuf(&dev->empress_tsq, b);
293}
294
295static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
296{
297 struct saa7134_dev *dev = file->private_data;
298
299 return videobuf_dqbuf(&dev->empress_tsq, b,
300 file->f_flags & O_NONBLOCK);
301}
302
303static int empress_streamon(struct file *file, void *priv,
304 enum v4l2_buf_type type)
305{
306 struct saa7134_dev *dev = file->private_data;
307
308 return videobuf_streamon(&dev->empress_tsq);
309}
310
311static int empress_streamoff(struct file *file, void *priv,
312 enum v4l2_buf_type type)
313{
314 struct saa7134_dev *dev = file->private_data;
315
316 return videobuf_streamoff(&dev->empress_tsq);
317}
318
319static int empress_s_ext_ctrls(struct file *file, void *priv,
320 struct v4l2_ext_controls *ctrls)
321{
322 struct saa7134_dev *dev = file->private_data;
323 int err;
324
325 /* count == 0 is abused in saa6752hs.c, so that special
326 case is handled here explicitly. */
327 if (ctrls->count == 0)
328 return 0;
329
330 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
331 return -EINVAL;
332
333 err = saa_call_empress(dev, core, s_ext_ctrls, ctrls);
334 ts_init_encoder(dev);
335
336 return err;
337}
338
339static int empress_g_ext_ctrls(struct file *file, void *priv,
340 struct v4l2_ext_controls *ctrls)
341{
342 struct saa7134_dev *dev = file->private_data;
343
344 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
345 return -EINVAL;
346 return saa_call_empress(dev, core, g_ext_ctrls, ctrls);
347}
348
349static int empress_g_ctrl(struct file *file, void *priv,
350 struct v4l2_control *c)
351{
352 struct saa7134_dev *dev = file->private_data;
353
354 return saa7134_g_ctrl_internal(dev, NULL, c);
355}
356
357static int empress_s_ctrl(struct file *file, void *priv,
358 struct v4l2_control *c)
359{
360 struct saa7134_dev *dev = file->private_data;
361
362 return saa7134_s_ctrl_internal(dev, NULL, c);
363}
364
365static int empress_queryctrl(struct file *file, void *priv,
366 struct v4l2_queryctrl *c)
367{
368 /* Must be sorted from low to high control ID! */
369 static const u32 user_ctrls[] = {
370 V4L2_CID_USER_CLASS,
371 V4L2_CID_BRIGHTNESS,
372 V4L2_CID_CONTRAST,
373 V4L2_CID_SATURATION,
374 V4L2_CID_HUE,
375 V4L2_CID_AUDIO_VOLUME,
376 V4L2_CID_AUDIO_MUTE,
377 V4L2_CID_HFLIP,
378 0
379 };
380
381 /* Must be sorted from low to high control ID! */
382 static const u32 mpeg_ctrls[] = {
383 V4L2_CID_MPEG_CLASS,
384 V4L2_CID_MPEG_STREAM_TYPE,
385 V4L2_CID_MPEG_STREAM_PID_PMT,
386 V4L2_CID_MPEG_STREAM_PID_AUDIO,
387 V4L2_CID_MPEG_STREAM_PID_VIDEO,
388 V4L2_CID_MPEG_STREAM_PID_PCR,
389 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
390 V4L2_CID_MPEG_AUDIO_ENCODING,
391 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
392 V4L2_CID_MPEG_VIDEO_ENCODING,
393 V4L2_CID_MPEG_VIDEO_ASPECT,
394 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
395 V4L2_CID_MPEG_VIDEO_BITRATE,
396 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
397 0
398 };
399 static const u32 *ctrl_classes[] = {
400 user_ctrls,
401 mpeg_ctrls,
402 NULL
403 };
404 struct saa7134_dev *dev = file->private_data;
405
406 c->id = v4l2_ctrl_next(ctrl_classes, c->id);
407 if (c->id == 0)
408 return -EINVAL;
409 if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
410 return v4l2_ctrl_query_fill(c, 0, 0, 0, 0);
411 if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
412 return saa7134_queryctrl(file, priv, c);
413 return saa_call_empress(dev, core, queryctrl, c);
414}
415
416static int empress_querymenu(struct file *file, void *priv,
417 struct v4l2_querymenu *c)
418{
419 struct saa7134_dev *dev = file->private_data;
420
421 if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
422 return -EINVAL;
423 return saa_call_empress(dev, core, querymenu, c);
424}
425
426static int empress_s_std(struct file *file, void *priv, v4l2_std_id id)
427{
428 struct saa7134_dev *dev = file->private_data;
429
430 return saa7134_s_std_internal(dev, NULL, id);
431}
432
433static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id)
434{
435 struct saa7134_dev *dev = file->private_data;
436
437 *id = dev->tvnorm->id;
438 return 0;
439}
440
441static const struct v4l2_file_operations ts_fops = 233static const struct v4l2_file_operations ts_fops =
442{ 234{
443 .owner = THIS_MODULE, 235 .owner = THIS_MODULE,
@@ -450,28 +242,29 @@ static const struct v4l2_file_operations ts_fops =
450}; 242};
451 243
452static const struct v4l2_ioctl_ops ts_ioctl_ops = { 244static const struct v4l2_ioctl_ops ts_ioctl_ops = {
453 .vidioc_querycap = empress_querycap, 245 .vidioc_querycap = saa7134_querycap,
454 .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, 246 .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap,
455 .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, 247 .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap,
456 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, 248 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
457 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, 249 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
458 .vidioc_reqbufs = empress_reqbufs, 250 .vidioc_reqbufs = saa7134_reqbufs,
459 .vidioc_querybuf = empress_querybuf, 251 .vidioc_querybuf = saa7134_querybuf,
460 .vidioc_qbuf = empress_qbuf, 252 .vidioc_qbuf = saa7134_qbuf,
461 .vidioc_dqbuf = empress_dqbuf, 253 .vidioc_dqbuf = saa7134_dqbuf,
462 .vidioc_streamon = empress_streamon, 254 .vidioc_streamon = saa7134_streamon,
463 .vidioc_streamoff = empress_streamoff, 255 .vidioc_streamoff = saa7134_streamoff,
464 .vidioc_s_ext_ctrls = empress_s_ext_ctrls, 256 .vidioc_g_frequency = saa7134_g_frequency,
465 .vidioc_g_ext_ctrls = empress_g_ext_ctrls, 257 .vidioc_s_frequency = saa7134_s_frequency,
466 .vidioc_enum_input = empress_enum_input, 258 .vidioc_g_tuner = saa7134_g_tuner,
467 .vidioc_g_input = empress_g_input, 259 .vidioc_s_tuner = saa7134_s_tuner,
468 .vidioc_s_input = empress_s_input, 260 .vidioc_enum_input = saa7134_enum_input,
469 .vidioc_queryctrl = empress_queryctrl, 261 .vidioc_g_input = saa7134_g_input,
470 .vidioc_querymenu = empress_querymenu, 262 .vidioc_s_input = saa7134_s_input,
471 .vidioc_g_ctrl = empress_g_ctrl, 263 .vidioc_s_std = saa7134_s_std,
472 .vidioc_s_ctrl = empress_s_ctrl, 264 .vidioc_g_std = saa7134_g_std,
473 .vidioc_s_std = empress_s_std, 265 .vidioc_log_status = v4l2_ctrl_log_status,
474 .vidioc_g_std = empress_g_std, 266 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
267 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
475}; 268};
476 269
477/* ----------------------------------------------------------- */ 270/* ----------------------------------------------------------- */
@@ -501,9 +294,26 @@ static void empress_signal_change(struct saa7134_dev *dev)
501 schedule_work(&dev->empress_workqueue); 294 schedule_work(&dev->empress_workqueue);
502} 295}
503 296
297static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl)
298{
299 switch (ctrl->id) {
300 case V4L2_CID_BRIGHTNESS:
301 case V4L2_CID_HUE:
302 case V4L2_CID_CONTRAST:
303 case V4L2_CID_SATURATION:
304 case V4L2_CID_AUDIO_MUTE:
305 case V4L2_CID_AUDIO_VOLUME:
306 case V4L2_CID_PRIVATE_INVERT:
307 case V4L2_CID_PRIVATE_AUTOMUTE:
308 return true;
309 default:
310 return false;
311 }
312}
504 313
505static int empress_init(struct saa7134_dev *dev) 314static int empress_init(struct saa7134_dev *dev)
506{ 315{
316 struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler;
507 int err; 317 int err;
508 318
509 dprintk("%s: %s\n",dev->name,__func__); 319 dprintk("%s: %s\n",dev->name,__func__);
@@ -516,6 +326,16 @@ static int empress_init(struct saa7134_dev *dev)
516 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), 326 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
517 "%s empress (%s)", dev->name, 327 "%s empress (%s)", dev->name,
518 saa7134_boards[dev->board].name); 328 saa7134_boards[dev->board].name);
329 set_bit(V4L2_FL_USE_FH_PRIO, &dev->empress_dev->flags);
330 v4l2_ctrl_handler_init(hdl, 21);
331 v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter);
332 if (dev->empress_sd)
333 v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL);
334 if (hdl->error) {
335 video_device_release(dev->empress_dev);
336 return hdl->error;
337 }
338 dev->empress_dev->ctrl_handler = hdl;
519 339
520 INIT_WORK(&dev->empress_workqueue, empress_signal_update); 340 INIT_WORK(&dev->empress_workqueue, empress_signal_update);
521 341
@@ -551,6 +371,7 @@ static int empress_fini(struct saa7134_dev *dev)
551 return 0; 371 return 0;
552 flush_work(&dev->empress_workqueue); 372 flush_work(&dev->empress_workqueue);
553 video_unregister_device(dev->empress_dev); 373 video_unregister_device(dev->empress_dev);
374 v4l2_ctrl_handler_free(&dev->empress_ctrl_handler);
554 dev->empress_dev = NULL; 375 dev->empress_dev = NULL;
555 return 0; 376 return 0;
556} 377}
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index e9aa94b807f1..d4da18d049f3 100644
--- a/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -117,8 +117,7 @@ static int buffer_prepare(struct videobuf_queue *q,
117 struct videobuf_buffer *vb, 117 struct videobuf_buffer *vb,
118 enum v4l2_field field) 118 enum v4l2_field field)
119{ 119{
120 struct saa7134_fh *fh = q->priv_data; 120 struct saa7134_dev *dev = q->priv_data;
121 struct saa7134_dev *dev = fh->dev;
122 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 121 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
123 struct saa7134_tvnorm *norm = dev->tvnorm; 122 struct saa7134_tvnorm *norm = dev->tvnorm;
124 unsigned int lines, llength, size; 123 unsigned int lines, llength, size;
@@ -141,7 +140,7 @@ static int buffer_prepare(struct videobuf_queue *q,
141 buf->vb.width = llength; 140 buf->vb.width = llength;
142 buf->vb.height = lines; 141 buf->vb.height = lines;
143 buf->vb.size = size; 142 buf->vb.size = size;
144 buf->pt = &fh->pt_vbi; 143 buf->pt = &dev->pt_vbi;
145 144
146 err = videobuf_iolock(q,&buf->vb,NULL); 145 err = videobuf_iolock(q,&buf->vb,NULL);
147 if (err) 146 if (err)
@@ -166,8 +165,7 @@ static int buffer_prepare(struct videobuf_queue *q,
166static int 165static int
167buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 166buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
168{ 167{
169 struct saa7134_fh *fh = q->priv_data; 168 struct saa7134_dev *dev = q->priv_data;
170 struct saa7134_dev *dev = fh->dev;
171 int llength,lines; 169 int llength,lines;
172 170
173 lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1; 171 lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
@@ -181,8 +179,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
181 179
182static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 180static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
183{ 181{
184 struct saa7134_fh *fh = q->priv_data; 182 struct saa7134_dev *dev = q->priv_data;
185 struct saa7134_dev *dev = fh->dev;
186 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 183 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
187 184
188 saa7134_buffer_queue(dev,&dev->vbi_q,buf); 185 saa7134_buffer_queue(dev,&dev->vbi_q,buf);
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index fb60da85bc2c..eb472b5b26a0 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -27,11 +27,13 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/sort.h> 28#include <linux/sort.h>
29 29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-event.h>
33#include <media/saa6588.h> 32#include <media/saa6588.h>
34 33
34#include "saa7134-reg.h"
35#include "saa7134.h"
36
35/* ------------------------------------------------------------------ */ 37/* ------------------------------------------------------------------ */
36 38
37unsigned int video_debug; 39unsigned int video_debug;
@@ -369,117 +371,6 @@ static struct saa7134_tvnorm tvnorms[] = {
369}; 371};
370#define TVNORMS ARRAY_SIZE(tvnorms) 372#define TVNORMS ARRAY_SIZE(tvnorms)
371 373
372#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0)
373#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1)
374#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2)
375#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3)
376#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4)
377
378static const struct v4l2_queryctrl no_ctrl = {
379 .name = "42",
380 .flags = V4L2_CTRL_FLAG_DISABLED,
381};
382static const struct v4l2_queryctrl video_ctrls[] = {
383 /* --- video --- */
384 {
385 .id = V4L2_CID_BRIGHTNESS,
386 .name = "Brightness",
387 .minimum = 0,
388 .maximum = 255,
389 .step = 1,
390 .default_value = 128,
391 .type = V4L2_CTRL_TYPE_INTEGER,
392 },{
393 .id = V4L2_CID_CONTRAST,
394 .name = "Contrast",
395 .minimum = 0,
396 .maximum = 127,
397 .step = 1,
398 .default_value = 68,
399 .type = V4L2_CTRL_TYPE_INTEGER,
400 },{
401 .id = V4L2_CID_SATURATION,
402 .name = "Saturation",
403 .minimum = 0,
404 .maximum = 127,
405 .step = 1,
406 .default_value = 64,
407 .type = V4L2_CTRL_TYPE_INTEGER,
408 },{
409 .id = V4L2_CID_HUE,
410 .name = "Hue",
411 .minimum = -128,
412 .maximum = 127,
413 .step = 1,
414 .default_value = 0,
415 .type = V4L2_CTRL_TYPE_INTEGER,
416 },{
417 .id = V4L2_CID_HFLIP,
418 .name = "Mirror",
419 .minimum = 0,
420 .maximum = 1,
421 .type = V4L2_CTRL_TYPE_BOOLEAN,
422 },
423 /* --- audio --- */
424 {
425 .id = V4L2_CID_AUDIO_MUTE,
426 .name = "Mute",
427 .minimum = 0,
428 .maximum = 1,
429 .type = V4L2_CTRL_TYPE_BOOLEAN,
430 },{
431 .id = V4L2_CID_AUDIO_VOLUME,
432 .name = "Volume",
433 .minimum = -15,
434 .maximum = 15,
435 .step = 1,
436 .default_value = 0,
437 .type = V4L2_CTRL_TYPE_INTEGER,
438 },
439 /* --- private --- */
440 {
441 .id = V4L2_CID_PRIVATE_INVERT,
442 .name = "Invert",
443 .minimum = 0,
444 .maximum = 1,
445 .type = V4L2_CTRL_TYPE_BOOLEAN,
446 },{
447 .id = V4L2_CID_PRIVATE_Y_ODD,
448 .name = "y offset odd field",
449 .minimum = 0,
450 .maximum = 128,
451 .step = 1,
452 .default_value = 0,
453 .type = V4L2_CTRL_TYPE_INTEGER,
454 },{
455 .id = V4L2_CID_PRIVATE_Y_EVEN,
456 .name = "y offset even field",
457 .minimum = 0,
458 .maximum = 128,
459 .step = 1,
460 .default_value = 0,
461 .type = V4L2_CTRL_TYPE_INTEGER,
462 },{
463 .id = V4L2_CID_PRIVATE_AUTOMUTE,
464 .name = "automute",
465 .minimum = 0,
466 .maximum = 1,
467 .default_value = 1,
468 .type = V4L2_CTRL_TYPE_BOOLEAN,
469 }
470};
471static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
472
473static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
474{
475 unsigned int i;
476
477 for (i = 0; i < CTRLS; i++)
478 if (video_ctrls[i].id == id)
479 return video_ctrls+i;
480 return NULL;
481}
482
483static struct saa7134_format* format_by_fourcc(unsigned int fourcc) 374static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
484{ 375{
485 unsigned int i; 376 unsigned int i;
@@ -514,16 +405,6 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int
514 return 1; 405 return 1;
515} 406}
516 407
517static int res_check(struct saa7134_fh *fh, unsigned int bit)
518{
519 return (fh->resources & bit);
520}
521
522static int res_locked(struct saa7134_dev *dev, unsigned int bit)
523{
524 return (dev->resources & bit);
525}
526
527static 408static
528void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) 409void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
529{ 410{
@@ -868,7 +749,7 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win, bool
868 return 0; 749 return 0;
869} 750}
870 751
871static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh) 752static int start_preview(struct saa7134_dev *dev)
872{ 753{
873 unsigned long base,control,bpl; 754 unsigned long base,control,bpl;
874 int err; 755 int err;
@@ -923,7 +804,7 @@ static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
923 return 0; 804 return 0;
924} 805}
925 806
926static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh) 807static int stop_preview(struct saa7134_dev *dev)
927{ 808{
928 dev->ovenable = 0; 809 dev->ovenable = 0;
929 saa7134_set_dmabits(dev); 810 saa7134_set_dmabits(dev);
@@ -1018,8 +899,7 @@ static int buffer_prepare(struct videobuf_queue *q,
1018 struct videobuf_buffer *vb, 899 struct videobuf_buffer *vb,
1019 enum v4l2_field field) 900 enum v4l2_field field)
1020{ 901{
1021 struct saa7134_fh *fh = q->priv_data; 902 struct saa7134_dev *dev = q->priv_data;
1022 struct saa7134_dev *dev = fh->dev;
1023 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 903 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1024 unsigned int size; 904 unsigned int size;
1025 int err; 905 int err;
@@ -1057,7 +937,7 @@ static int buffer_prepare(struct videobuf_queue *q,
1057 buf->vb.size = size; 937 buf->vb.size = size;
1058 buf->vb.field = field; 938 buf->vb.field = field;
1059 buf->fmt = dev->fmt; 939 buf->fmt = dev->fmt;
1060 buf->pt = &fh->pt_cap; 940 buf->pt = &dev->pt_cap;
1061 dev->video_q.curr = NULL; 941 dev->video_q.curr = NULL;
1062 942
1063 err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); 943 err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
@@ -1082,8 +962,7 @@ static int buffer_prepare(struct videobuf_queue *q,
1082static int 962static int
1083buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 963buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1084{ 964{
1085 struct saa7134_fh *fh = q->priv_data; 965 struct saa7134_dev *dev = q->priv_data;
1086 struct saa7134_dev *dev = fh->dev;
1087 966
1088 *size = dev->fmt->depth * dev->width * dev->height >> 3; 967 *size = dev->fmt->depth * dev->width * dev->height >> 3;
1089 if (0 == *count) 968 if (0 == *count)
@@ -1094,10 +973,10 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1094 973
1095static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 974static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1096{ 975{
1097 struct saa7134_fh *fh = q->priv_data; 976 struct saa7134_dev *dev = q->priv_data;
1098 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 977 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1099 978
1100 saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf); 979 saa7134_buffer_queue(dev, &dev->video_q, buf);
1101} 980}
1102 981
1103static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 982static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -1116,133 +995,56 @@ static struct videobuf_queue_ops video_qops = {
1116 995
1117/* ------------------------------------------------------------------ */ 996/* ------------------------------------------------------------------ */
1118 997
1119int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c) 998static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl)
1120{ 999{
1121 const struct v4l2_queryctrl* ctrl; 1000 struct saa7134_dev *dev = container_of(ctrl->handler, struct saa7134_dev, ctrl_handler);
1122
1123 ctrl = ctrl_by_id(c->id);
1124 if (NULL == ctrl)
1125 return -EINVAL;
1126 switch (c->id) {
1127 case V4L2_CID_BRIGHTNESS:
1128 c->value = dev->ctl_bright;
1129 break;
1130 case V4L2_CID_HUE:
1131 c->value = dev->ctl_hue;
1132 break;
1133 case V4L2_CID_CONTRAST:
1134 c->value = dev->ctl_contrast;
1135 break;
1136 case V4L2_CID_SATURATION:
1137 c->value = dev->ctl_saturation;
1138 break;
1139 case V4L2_CID_AUDIO_MUTE:
1140 c->value = dev->ctl_mute;
1141 break;
1142 case V4L2_CID_AUDIO_VOLUME:
1143 c->value = dev->ctl_volume;
1144 break;
1145 case V4L2_CID_PRIVATE_INVERT:
1146 c->value = dev->ctl_invert;
1147 break;
1148 case V4L2_CID_HFLIP:
1149 c->value = dev->ctl_mirror;
1150 break;
1151 case V4L2_CID_PRIVATE_Y_EVEN:
1152 c->value = dev->ctl_y_even;
1153 break;
1154 case V4L2_CID_PRIVATE_Y_ODD:
1155 c->value = dev->ctl_y_odd;
1156 break;
1157 case V4L2_CID_PRIVATE_AUTOMUTE:
1158 c->value = dev->ctl_automute;
1159 break;
1160 default:
1161 return -EINVAL;
1162 }
1163 return 0;
1164}
1165EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal);
1166
1167static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
1168{
1169 struct saa7134_fh *fh = priv;
1170
1171 return saa7134_g_ctrl_internal(fh->dev, fh, c);
1172}
1173
1174int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
1175{
1176 const struct v4l2_queryctrl* ctrl;
1177 unsigned long flags; 1001 unsigned long flags;
1178 int restart_overlay = 0; 1002 int restart_overlay = 0;
1179 int err;
1180 1003
1181 err = -EINVAL; 1004 switch (ctrl->id) {
1182
1183 mutex_lock(&dev->lock);
1184
1185 ctrl = ctrl_by_id(c->id);
1186 if (NULL == ctrl)
1187 goto error;
1188
1189 dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
1190 switch (ctrl->type) {
1191 case V4L2_CTRL_TYPE_BOOLEAN:
1192 case V4L2_CTRL_TYPE_MENU:
1193 case V4L2_CTRL_TYPE_INTEGER:
1194 if (c->value < ctrl->minimum)
1195 c->value = ctrl->minimum;
1196 if (c->value > ctrl->maximum)
1197 c->value = ctrl->maximum;
1198 break;
1199 default:
1200 /* nothing */;
1201 }
1202 switch (c->id) {
1203 case V4L2_CID_BRIGHTNESS: 1005 case V4L2_CID_BRIGHTNESS:
1204 dev->ctl_bright = c->value; 1006 dev->ctl_bright = ctrl->val;
1205 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright); 1007 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, ctrl->val);
1206 break; 1008 break;
1207 case V4L2_CID_HUE: 1009 case V4L2_CID_HUE:
1208 dev->ctl_hue = c->value; 1010 dev->ctl_hue = ctrl->val;
1209 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue); 1011 saa_writeb(SAA7134_DEC_CHROMA_HUE, ctrl->val);
1210 break; 1012 break;
1211 case V4L2_CID_CONTRAST: 1013 case V4L2_CID_CONTRAST:
1212 dev->ctl_contrast = c->value; 1014 dev->ctl_contrast = ctrl->val;
1213 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, 1015 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1214 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast); 1016 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1215 break; 1017 break;
1216 case V4L2_CID_SATURATION: 1018 case V4L2_CID_SATURATION:
1217 dev->ctl_saturation = c->value; 1019 dev->ctl_saturation = ctrl->val;
1218 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, 1020 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1219 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); 1021 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1220 break; 1022 break;
1221 case V4L2_CID_AUDIO_MUTE: 1023 case V4L2_CID_AUDIO_MUTE:
1222 dev->ctl_mute = c->value; 1024 dev->ctl_mute = ctrl->val;
1223 saa7134_tvaudio_setmute(dev); 1025 saa7134_tvaudio_setmute(dev);
1224 break; 1026 break;
1225 case V4L2_CID_AUDIO_VOLUME: 1027 case V4L2_CID_AUDIO_VOLUME:
1226 dev->ctl_volume = c->value; 1028 dev->ctl_volume = ctrl->val;
1227 saa7134_tvaudio_setvolume(dev,dev->ctl_volume); 1029 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
1228 break; 1030 break;
1229 case V4L2_CID_PRIVATE_INVERT: 1031 case V4L2_CID_PRIVATE_INVERT:
1230 dev->ctl_invert = c->value; 1032 dev->ctl_invert = ctrl->val;
1231 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, 1033 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1232 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast); 1034 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1233 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, 1035 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1234 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); 1036 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1235 break; 1037 break;
1236 case V4L2_CID_HFLIP: 1038 case V4L2_CID_HFLIP:
1237 dev->ctl_mirror = c->value; 1039 dev->ctl_mirror = ctrl->val;
1238 restart_overlay = 1; 1040 restart_overlay = 1;
1239 break; 1041 break;
1240 case V4L2_CID_PRIVATE_Y_EVEN: 1042 case V4L2_CID_PRIVATE_Y_EVEN:
1241 dev->ctl_y_even = c->value; 1043 dev->ctl_y_even = ctrl->val;
1242 restart_overlay = 1; 1044 restart_overlay = 1;
1243 break; 1045 break;
1244 case V4L2_CID_PRIVATE_Y_ODD: 1046 case V4L2_CID_PRIVATE_Y_ODD:
1245 dev->ctl_y_odd = c->value; 1047 dev->ctl_y_odd = ctrl->val;
1246 restart_overlay = 1; 1048 restart_overlay = 1;
1247 break; 1049 break;
1248 case V4L2_CID_PRIVATE_AUTOMUTE: 1050 case V4L2_CID_PRIVATE_AUTOMUTE:
@@ -1252,7 +1054,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
1252 tda9887_cfg.tuner = TUNER_TDA9887; 1054 tda9887_cfg.tuner = TUNER_TDA9887;
1253 tda9887_cfg.priv = &dev->tda9887_conf; 1055 tda9887_cfg.priv = &dev->tda9887_conf;
1254 1056
1255 dev->ctl_automute = c->value; 1057 dev->ctl_automute = ctrl->val;
1256 if (dev->tda9887_conf) { 1058 if (dev->tda9887_conf) {
1257 if (dev->ctl_automute) 1059 if (dev->ctl_automute)
1258 dev->tda9887_conf |= TDA9887_AUTOMUTE; 1060 dev->tda9887_conf |= TDA9887_AUTOMUTE;
@@ -1264,27 +1066,15 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
1264 break; 1066 break;
1265 } 1067 }
1266 default: 1068 default:
1267 goto error; 1069 return -EINVAL;
1268 } 1070 }
1269 if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) { 1071 if (restart_overlay && res_locked(dev, RESOURCE_OVERLAY)) {
1270 spin_lock_irqsave(&dev->slock,flags); 1072 spin_lock_irqsave(&dev->slock, flags);
1271 stop_preview(dev,fh); 1073 stop_preview(dev);
1272 start_preview(dev,fh); 1074 start_preview(dev);
1273 spin_unlock_irqrestore(&dev->slock,flags); 1075 spin_unlock_irqrestore(&dev->slock, flags);
1274 } 1076 }
1275 err = 0; 1077 return 0;
1276
1277error:
1278 mutex_unlock(&dev->lock);
1279 return err;
1280}
1281EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal);
1282
1283static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
1284{
1285 struct saa7134_fh *fh = f;
1286
1287 return saa7134_s_ctrl_internal(fh->dev, fh, c);
1288} 1078}
1289 1079
1290/* ------------------------------------------------------------------ */ 1080/* ------------------------------------------------------------------ */
@@ -1292,15 +1082,16 @@ static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
1292static struct videobuf_queue *saa7134_queue(struct file *file) 1082static struct videobuf_queue *saa7134_queue(struct file *file)
1293{ 1083{
1294 struct video_device *vdev = video_devdata(file); 1084 struct video_device *vdev = video_devdata(file);
1085 struct saa7134_dev *dev = video_drvdata(file);
1295 struct saa7134_fh *fh = file->private_data; 1086 struct saa7134_fh *fh = file->private_data;
1296 struct videobuf_queue *q = NULL; 1087 struct videobuf_queue *q = NULL;
1297 1088
1298 switch (vdev->vfl_type) { 1089 switch (vdev->vfl_type) {
1299 case VFL_TYPE_GRABBER: 1090 case VFL_TYPE_GRABBER:
1300 q = &fh->cap; 1091 q = fh->is_empress ? &dev->empress_tsq : &dev->cap;
1301 break; 1092 break;
1302 case VFL_TYPE_VBI: 1093 case VFL_TYPE_VBI:
1303 q = &fh->vbi; 1094 q = &dev->vbi;
1304 break; 1095 break;
1305 default: 1096 default:
1306 BUG(); 1097 BUG();
@@ -1311,9 +1102,10 @@ static struct videobuf_queue *saa7134_queue(struct file *file)
1311static int saa7134_resource(struct file *file) 1102static int saa7134_resource(struct file *file)
1312{ 1103{
1313 struct video_device *vdev = video_devdata(file); 1104 struct video_device *vdev = video_devdata(file);
1105 struct saa7134_fh *fh = file->private_data;
1314 1106
1315 if (vdev->vfl_type == VFL_TYPE_GRABBER) 1107 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1316 return RESOURCE_VIDEO; 1108 return fh->is_empress ? RESOURCE_EMPRESS : RESOURCE_VIDEO;
1317 1109
1318 if (vdev->vfl_type == VFL_TYPE_VBI) 1110 if (vdev->vfl_type == VFL_TYPE_VBI)
1319 return RESOURCE_VBI; 1111 return RESOURCE_VBI;
@@ -1335,22 +1127,6 @@ static int video_open(struct file *file)
1335 1127
1336 v4l2_fh_init(&fh->fh, vdev); 1128 v4l2_fh_init(&fh->fh, vdev);
1337 file->private_data = fh; 1129 file->private_data = fh;
1338 fh->dev = dev;
1339
1340 videobuf_queue_sg_init(&fh->cap, &video_qops,
1341 &dev->pci->dev, &dev->slock,
1342 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1343 V4L2_FIELD_INTERLACED,
1344 sizeof(struct saa7134_buf),
1345 fh, NULL);
1346 videobuf_queue_sg_init(&fh->vbi, &saa7134_vbi_qops,
1347 &dev->pci->dev, &dev->slock,
1348 V4L2_BUF_TYPE_VBI_CAPTURE,
1349 V4L2_FIELD_SEQ_TB,
1350 sizeof(struct saa7134_buf),
1351 fh, NULL);
1352 saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
1353 saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
1354 1130
1355 if (vdev->vfl_type == VFL_TYPE_RADIO) { 1131 if (vdev->vfl_type == VFL_TYPE_RADIO) {
1356 /* switch to radio mode */ 1132 /* switch to radio mode */
@@ -1369,17 +1145,18 @@ static ssize_t
1369video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1145video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1370{ 1146{
1371 struct video_device *vdev = video_devdata(file); 1147 struct video_device *vdev = video_devdata(file);
1148 struct saa7134_dev *dev = video_drvdata(file);
1372 struct saa7134_fh *fh = file->private_data; 1149 struct saa7134_fh *fh = file->private_data;
1373 1150
1374 switch (vdev->vfl_type) { 1151 switch (vdev->vfl_type) {
1375 case VFL_TYPE_GRABBER: 1152 case VFL_TYPE_GRABBER:
1376 if (res_locked(fh->dev,RESOURCE_VIDEO)) 1153 if (res_locked(dev, RESOURCE_VIDEO))
1377 return -EBUSY; 1154 return -EBUSY;
1378 return videobuf_read_one(saa7134_queue(file), 1155 return videobuf_read_one(saa7134_queue(file),
1379 data, count, ppos, 1156 data, count, ppos,
1380 file->f_flags & O_NONBLOCK); 1157 file->f_flags & O_NONBLOCK);
1381 case VFL_TYPE_VBI: 1158 case VFL_TYPE_VBI:
1382 if (!res_get(fh->dev,fh,RESOURCE_VBI)) 1159 if (!res_get(dev, fh, RESOURCE_VBI))
1383 return -EBUSY; 1160 return -EBUSY;
1384 return videobuf_read_stream(saa7134_queue(file), 1161 return videobuf_read_stream(saa7134_queue(file),
1385 data, count, ppos, 1, 1162 data, count, ppos, 1,
@@ -1394,52 +1171,59 @@ video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1394static unsigned int 1171static unsigned int
1395video_poll(struct file *file, struct poll_table_struct *wait) 1172video_poll(struct file *file, struct poll_table_struct *wait)
1396{ 1173{
1174 unsigned long req_events = poll_requested_events(wait);
1397 struct video_device *vdev = video_devdata(file); 1175 struct video_device *vdev = video_devdata(file);
1176 struct saa7134_dev *dev = video_drvdata(file);
1398 struct saa7134_fh *fh = file->private_data; 1177 struct saa7134_fh *fh = file->private_data;
1399 struct videobuf_buffer *buf = NULL; 1178 struct videobuf_buffer *buf = NULL;
1400 unsigned int rc = 0; 1179 unsigned int rc = 0;
1401 1180
1181 if (v4l2_event_pending(&fh->fh))
1182 rc = POLLPRI;
1183 else if (req_events & POLLPRI)
1184 poll_wait(file, &fh->fh.wait, wait);
1185
1402 if (vdev->vfl_type == VFL_TYPE_VBI) 1186 if (vdev->vfl_type == VFL_TYPE_VBI)
1403 return videobuf_poll_stream(file, &fh->vbi, wait); 1187 return rc | videobuf_poll_stream(file, &dev->vbi, wait);
1404 1188
1405 if (res_check(fh,RESOURCE_VIDEO)) { 1189 if (res_check(fh, RESOURCE_VIDEO)) {
1406 mutex_lock(&fh->cap.vb_lock); 1190 mutex_lock(&dev->cap.vb_lock);
1407 if (!list_empty(&fh->cap.stream)) 1191 if (!list_empty(&dev->cap.stream))
1408 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); 1192 buf = list_entry(dev->cap.stream.next, struct videobuf_buffer, stream);
1409 } else { 1193 } else {
1410 mutex_lock(&fh->cap.vb_lock); 1194 mutex_lock(&dev->cap.vb_lock);
1411 if (UNSET == fh->cap.read_off) { 1195 if (UNSET == dev->cap.read_off) {
1412 /* need to capture a new frame */ 1196 /* need to capture a new frame */
1413 if (res_locked(fh->dev,RESOURCE_VIDEO)) 1197 if (res_locked(dev, RESOURCE_VIDEO))
1414 goto err; 1198 goto err;
1415 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) 1199 if (0 != dev->cap.ops->buf_prepare(&dev->cap,
1200 dev->cap.read_buf, dev->cap.field))
1416 goto err; 1201 goto err;
1417 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1202 dev->cap.ops->buf_queue(&dev->cap, dev->cap.read_buf);
1418 fh->cap.read_off = 0; 1203 dev->cap.read_off = 0;
1419 } 1204 }
1420 buf = fh->cap.read_buf; 1205 buf = dev->cap.read_buf;
1421 } 1206 }
1422 1207
1423 if (!buf) 1208 if (!buf)
1424 goto err; 1209 goto err;
1425 1210
1426 poll_wait(file, &buf->done, wait); 1211 poll_wait(file, &buf->done, wait);
1427 if (buf->state == VIDEOBUF_DONE || 1212 if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR)
1428 buf->state == VIDEOBUF_ERROR) 1213 rc |= POLLIN | POLLRDNORM;
1429 rc = POLLIN|POLLRDNORM; 1214 mutex_unlock(&dev->cap.vb_lock);
1430 mutex_unlock(&fh->cap.vb_lock);
1431 return rc; 1215 return rc;
1432 1216
1433err: 1217err:
1434 mutex_unlock(&fh->cap.vb_lock); 1218 mutex_unlock(&dev->cap.vb_lock);
1435 return POLLERR; 1219 return rc | POLLERR;
1436} 1220}
1437 1221
1438static int video_release(struct file *file) 1222static int video_release(struct file *file)
1439{ 1223{
1440 struct video_device *vdev = video_devdata(file); 1224 struct video_device *vdev = video_devdata(file);
1441 struct saa7134_fh *fh = file->private_data; 1225 struct saa7134_dev *dev = video_drvdata(file);
1442 struct saa7134_dev *dev = fh->dev; 1226 struct saa7134_fh *fh = file->private_data;
1443 struct saa6588_command cmd; 1227 struct saa6588_command cmd;
1444 unsigned long flags; 1228 unsigned long flags;
1445 1229
@@ -1448,26 +1232,28 @@ static int video_release(struct file *file)
1448 /* turn off overlay */ 1232 /* turn off overlay */
1449 if (res_check(fh, RESOURCE_OVERLAY)) { 1233 if (res_check(fh, RESOURCE_OVERLAY)) {
1450 spin_lock_irqsave(&dev->slock,flags); 1234 spin_lock_irqsave(&dev->slock,flags);
1451 stop_preview(dev,fh); 1235 stop_preview(dev);
1452 spin_unlock_irqrestore(&dev->slock,flags); 1236 spin_unlock_irqrestore(&dev->slock,flags);
1453 res_free(dev,fh,RESOURCE_OVERLAY); 1237 res_free(dev, fh, RESOURCE_OVERLAY);
1454 } 1238 }
1455 1239
1456 /* stop video capture */ 1240 /* stop video capture */
1457 if (res_check(fh, RESOURCE_VIDEO)) { 1241 if (res_check(fh, RESOURCE_VIDEO)) {
1458 pm_qos_remove_request(&dev->qos_request); 1242 pm_qos_remove_request(&dev->qos_request);
1459 videobuf_streamoff(&fh->cap); 1243 videobuf_streamoff(&dev->cap);
1460 res_free(dev,fh,RESOURCE_VIDEO); 1244 res_free(dev, fh, RESOURCE_VIDEO);
1245 videobuf_mmap_free(&dev->cap);
1461 } 1246 }
1462 if (fh->cap.read_buf) { 1247 if (dev->cap.read_buf) {
1463 buffer_release(&fh->cap,fh->cap.read_buf); 1248 buffer_release(&dev->cap, dev->cap.read_buf);
1464 kfree(fh->cap.read_buf); 1249 kfree(dev->cap.read_buf);
1465 } 1250 }
1466 1251
1467 /* stop vbi capture */ 1252 /* stop vbi capture */
1468 if (res_check(fh, RESOURCE_VBI)) { 1253 if (res_check(fh, RESOURCE_VBI)) {
1469 videobuf_stop(&fh->vbi); 1254 videobuf_stop(&dev->vbi);
1470 res_free(dev,fh,RESOURCE_VBI); 1255 res_free(dev, fh, RESOURCE_VBI);
1256 videobuf_mmap_free(&dev->vbi);
1471 } 1257 }
1472 1258
1473 /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/ 1259 /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
@@ -1480,12 +1266,6 @@ static int video_release(struct file *file)
1480 if (vdev->vfl_type == VFL_TYPE_RADIO) 1266 if (vdev->vfl_type == VFL_TYPE_RADIO)
1481 saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); 1267 saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
1482 1268
1483 /* free stuff */
1484 videobuf_mmap_free(&fh->cap);
1485 videobuf_mmap_free(&fh->vbi);
1486 saa7134_pgtable_free(dev->pci,&fh->pt_cap);
1487 saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
1488
1489 v4l2_fh_del(&fh->fh); 1269 v4l2_fh_del(&fh->fh);
1490 v4l2_fh_exit(&fh->fh); 1270 v4l2_fh_exit(&fh->fh);
1491 file->private_data = NULL; 1271 file->private_data = NULL;
@@ -1501,11 +1281,11 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
1501static ssize_t radio_read(struct file *file, char __user *data, 1281static ssize_t radio_read(struct file *file, char __user *data,
1502 size_t count, loff_t *ppos) 1282 size_t count, loff_t *ppos)
1503{ 1283{
1504 struct saa7134_fh *fh = file->private_data; 1284 struct saa7134_dev *dev = video_drvdata(file);
1505 struct saa7134_dev *dev = fh->dev;
1506 struct saa6588_command cmd; 1285 struct saa6588_command cmd;
1507 1286
1508 cmd.block_count = count/3; 1287 cmd.block_count = count/3;
1288 cmd.nonblocking = file->f_flags & O_NONBLOCK;
1509 cmd.buffer = data; 1289 cmd.buffer = data;
1510 cmd.instance = file; 1290 cmd.instance = file;
1511 cmd.result = -ENODEV; 1291 cmd.result = -ENODEV;
@@ -1517,16 +1297,16 @@ static ssize_t radio_read(struct file *file, char __user *data,
1517 1297
1518static unsigned int radio_poll(struct file *file, poll_table *wait) 1298static unsigned int radio_poll(struct file *file, poll_table *wait)
1519{ 1299{
1520 struct saa7134_fh *fh = file->private_data; 1300 struct saa7134_dev *dev = video_drvdata(file);
1521 struct saa7134_dev *dev = fh->dev;
1522 struct saa6588_command cmd; 1301 struct saa6588_command cmd;
1302 unsigned int rc = v4l2_ctrl_poll(file, wait);
1523 1303
1524 cmd.instance = file; 1304 cmd.instance = file;
1525 cmd.event_list = wait; 1305 cmd.event_list = wait;
1526 cmd.result = -ENODEV; 1306 cmd.result = 0;
1527 saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); 1307 saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
1528 1308
1529 return cmd.result; 1309 return rc | cmd.result;
1530} 1310}
1531 1311
1532/* ------------------------------------------------------------------ */ 1312/* ------------------------------------------------------------------ */
@@ -1534,8 +1314,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
1534static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv, 1314static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
1535 struct v4l2_format *f) 1315 struct v4l2_format *f)
1536{ 1316{
1537 struct saa7134_fh *fh = priv; 1317 struct saa7134_dev *dev = video_drvdata(file);
1538 struct saa7134_dev *dev = fh->dev;
1539 struct saa7134_tvnorm *norm = dev->tvnorm; 1318 struct saa7134_tvnorm *norm = dev->tvnorm;
1540 1319
1541 memset(&f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved)); 1320 memset(&f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved));
@@ -1555,12 +1334,11 @@ static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
1555static int saa7134_g_fmt_vid_cap(struct file *file, void *priv, 1334static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
1556 struct v4l2_format *f) 1335 struct v4l2_format *f)
1557{ 1336{
1558 struct saa7134_fh *fh = priv; 1337 struct saa7134_dev *dev = video_drvdata(file);
1559 struct saa7134_dev *dev = fh->dev;
1560 1338
1561 f->fmt.pix.width = dev->width; 1339 f->fmt.pix.width = dev->width;
1562 f->fmt.pix.height = dev->height; 1340 f->fmt.pix.height = dev->height;
1563 f->fmt.pix.field = fh->cap.field; 1341 f->fmt.pix.field = dev->cap.field;
1564 f->fmt.pix.pixelformat = dev->fmt->fourcc; 1342 f->fmt.pix.pixelformat = dev->fmt->fourcc;
1565 f->fmt.pix.bytesperline = 1343 f->fmt.pix.bytesperline =
1566 (f->fmt.pix.width * dev->fmt->depth) >> 3; 1344 (f->fmt.pix.width * dev->fmt->depth) >> 3;
@@ -1574,8 +1352,7 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
1574static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, 1352static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
1575 struct v4l2_format *f) 1353 struct v4l2_format *f)
1576{ 1354{
1577 struct saa7134_fh *fh = priv; 1355 struct saa7134_dev *dev = video_drvdata(file);
1578 struct saa7134_dev *dev = fh->dev;
1579 struct v4l2_clip __user *clips = f->fmt.win.clips; 1356 struct v4l2_clip __user *clips = f->fmt.win.clips;
1580 u32 clipcount = f->fmt.win.clipcount; 1357 u32 clipcount = f->fmt.win.clipcount;
1581 int err = 0; 1358 int err = 0;
@@ -1607,8 +1384,7 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
1607static int saa7134_try_fmt_vid_cap(struct file *file, void *priv, 1384static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
1608 struct v4l2_format *f) 1385 struct v4l2_format *f)
1609{ 1386{
1610 struct saa7134_fh *fh = priv; 1387 struct saa7134_dev *dev = video_drvdata(file);
1611 struct saa7134_dev *dev = fh->dev;
1612 struct saa7134_format *fmt; 1388 struct saa7134_format *fmt;
1613 enum v4l2_field field; 1389 enum v4l2_field field;
1614 unsigned int maxw, maxh; 1390 unsigned int maxw, maxh;
@@ -1659,8 +1435,7 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
1659static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv, 1435static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,
1660 struct v4l2_format *f) 1436 struct v4l2_format *f)
1661{ 1437{
1662 struct saa7134_fh *fh = priv; 1438 struct saa7134_dev *dev = video_drvdata(file);
1663 struct saa7134_dev *dev = fh->dev;
1664 1439
1665 if (saa7134_no_overlay > 0) { 1440 if (saa7134_no_overlay > 0) {
1666 printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); 1441 printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
@@ -1675,8 +1450,7 @@ static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,
1675static int saa7134_s_fmt_vid_cap(struct file *file, void *priv, 1450static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
1676 struct v4l2_format *f) 1451 struct v4l2_format *f)
1677{ 1452{
1678 struct saa7134_fh *fh = priv; 1453 struct saa7134_dev *dev = video_drvdata(file);
1679 struct saa7134_dev *dev = fh->dev;
1680 int err; 1454 int err;
1681 1455
1682 err = saa7134_try_fmt_vid_cap(file, priv, f); 1456 err = saa7134_try_fmt_vid_cap(file, priv, f);
@@ -1686,15 +1460,14 @@ static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
1686 dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); 1460 dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1687 dev->width = f->fmt.pix.width; 1461 dev->width = f->fmt.pix.width;
1688 dev->height = f->fmt.pix.height; 1462 dev->height = f->fmt.pix.height;
1689 fh->cap.field = f->fmt.pix.field; 1463 dev->cap.field = f->fmt.pix.field;
1690 return 0; 1464 return 0;
1691} 1465}
1692 1466
1693static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv, 1467static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
1694 struct v4l2_format *f) 1468 struct v4l2_format *f)
1695{ 1469{
1696 struct saa7134_fh *fh = priv; 1470 struct saa7134_dev *dev = video_drvdata(file);
1697 struct saa7134_dev *dev = fh->dev;
1698 int err; 1471 int err;
1699 unsigned long flags; 1472 unsigned long flags;
1700 1473
@@ -1719,10 +1492,10 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
1719 return -EFAULT; 1492 return -EFAULT;
1720 } 1493 }
1721 1494
1722 if (res_check(fh, RESOURCE_OVERLAY)) { 1495 if (res_check(priv, RESOURCE_OVERLAY)) {
1723 spin_lock_irqsave(&dev->slock, flags); 1496 spin_lock_irqsave(&dev->slock, flags);
1724 stop_preview(dev, fh); 1497 stop_preview(dev);
1725 start_preview(dev, fh); 1498 start_preview(dev);
1726 spin_unlock_irqrestore(&dev->slock, flags); 1499 spin_unlock_irqrestore(&dev->slock, flags);
1727 } 1500 }
1728 1501
@@ -1730,26 +1503,9 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
1730 return 0; 1503 return 0;
1731} 1504}
1732 1505
1733int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) 1506int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i)
1734{
1735 const struct v4l2_queryctrl *ctrl;
1736
1737 if ((c->id < V4L2_CID_BASE ||
1738 c->id >= V4L2_CID_LASTP1) &&
1739 (c->id < V4L2_CID_PRIVATE_BASE ||
1740 c->id >= V4L2_CID_PRIVATE_LASTP1))
1741 return -EINVAL;
1742 ctrl = ctrl_by_id(c->id);
1743 *c = (NULL != ctrl) ? *ctrl : no_ctrl;
1744 return 0;
1745}
1746EXPORT_SYMBOL_GPL(saa7134_queryctrl);
1747
1748static int saa7134_enum_input(struct file *file, void *priv,
1749 struct v4l2_input *i)
1750{ 1507{
1751 struct saa7134_fh *fh = priv; 1508 struct saa7134_dev *dev = video_drvdata(file);
1752 struct saa7134_dev *dev = fh->dev;
1753 unsigned int n; 1509 unsigned int n;
1754 1510
1755 n = i->index; 1511 n = i->index;
@@ -1769,27 +1525,27 @@ static int saa7134_enum_input(struct file *file, void *priv,
1769 if (0 != (v1 & 0x40)) 1525 if (0 != (v1 & 0x40))
1770 i->status |= V4L2_IN_ST_NO_H_LOCK; 1526 i->status |= V4L2_IN_ST_NO_H_LOCK;
1771 if (0 != (v2 & 0x40)) 1527 if (0 != (v2 & 0x40))
1772 i->status |= V4L2_IN_ST_NO_SYNC; 1528 i->status |= V4L2_IN_ST_NO_SIGNAL;
1773 if (0 != (v2 & 0x0e)) 1529 if (0 != (v2 & 0x0e))
1774 i->status |= V4L2_IN_ST_MACROVISION; 1530 i->status |= V4L2_IN_ST_MACROVISION;
1775 } 1531 }
1776 i->std = SAA7134_NORMS; 1532 i->std = SAA7134_NORMS;
1777 return 0; 1533 return 0;
1778} 1534}
1535EXPORT_SYMBOL_GPL(saa7134_enum_input);
1779 1536
1780static int saa7134_g_input(struct file *file, void *priv, unsigned int *i) 1537int saa7134_g_input(struct file *file, void *priv, unsigned int *i)
1781{ 1538{
1782 struct saa7134_fh *fh = priv; 1539 struct saa7134_dev *dev = video_drvdata(file);
1783 struct saa7134_dev *dev = fh->dev;
1784 1540
1785 *i = dev->ctl_input; 1541 *i = dev->ctl_input;
1786 return 0; 1542 return 0;
1787} 1543}
1544EXPORT_SYMBOL_GPL(saa7134_g_input);
1788 1545
1789static int saa7134_s_input(struct file *file, void *priv, unsigned int i) 1546int saa7134_s_input(struct file *file, void *priv, unsigned int i)
1790{ 1547{
1791 struct saa7134_fh *fh = priv; 1548 struct saa7134_dev *dev = video_drvdata(file);
1792 struct saa7134_dev *dev = fh->dev;
1793 1549
1794 if (i >= SAA7134_INPUT_MAX) 1550 if (i >= SAA7134_INPUT_MAX)
1795 return -EINVAL; 1551 return -EINVAL;
@@ -1800,13 +1556,14 @@ static int saa7134_s_input(struct file *file, void *priv, unsigned int i)
1800 mutex_unlock(&dev->lock); 1556 mutex_unlock(&dev->lock);
1801 return 0; 1557 return 0;
1802} 1558}
1559EXPORT_SYMBOL_GPL(saa7134_s_input);
1803 1560
1804static int saa7134_querycap(struct file *file, void *priv, 1561int saa7134_querycap(struct file *file, void *priv,
1805 struct v4l2_capability *cap) 1562 struct v4l2_capability *cap)
1806{ 1563{
1807 struct saa7134_fh *fh = priv; 1564 struct saa7134_dev *dev = video_drvdata(file);
1808 struct saa7134_dev *dev = fh->dev;
1809 struct video_device *vdev = video_devdata(file); 1565 struct video_device *vdev = video_devdata(file);
1566 struct saa7134_fh *fh = priv;
1810 u32 radio_caps, video_caps, vbi_caps; 1567 u32 radio_caps, video_caps, vbi_caps;
1811 1568
1812 unsigned int tuner_type = dev->tuner_type; 1569 unsigned int tuner_type = dev->tuner_type;
@@ -1825,7 +1582,7 @@ static int saa7134_querycap(struct file *file, void *priv,
1825 radio_caps |= V4L2_CAP_RDS_CAPTURE; 1582 radio_caps |= V4L2_CAP_RDS_CAPTURE;
1826 1583
1827 video_caps = V4L2_CAP_VIDEO_CAPTURE; 1584 video_caps = V4L2_CAP_VIDEO_CAPTURE;
1828 if (saa7134_no_overlay <= 0) 1585 if (saa7134_no_overlay <= 0 && !fh->is_empress)
1829 video_caps |= V4L2_CAP_VIDEO_OVERLAY; 1586 video_caps |= V4L2_CAP_VIDEO_OVERLAY;
1830 1587
1831 vbi_caps = V4L2_CAP_VBI_CAPTURE; 1588 vbi_caps = V4L2_CAP_VBI_CAPTURE;
@@ -1851,14 +1608,17 @@ static int saa7134_querycap(struct file *file, void *priv,
1851 1608
1852 return 0; 1609 return 0;
1853} 1610}
1611EXPORT_SYMBOL_GPL(saa7134_querycap);
1854 1612
1855int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id id) 1613int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)
1856{ 1614{
1615 struct saa7134_dev *dev = video_drvdata(file);
1616 struct saa7134_fh *fh = priv;
1857 unsigned long flags; 1617 unsigned long flags;
1858 unsigned int i; 1618 unsigned int i;
1859 v4l2_std_id fixup; 1619 v4l2_std_id fixup;
1860 1620
1861 if (!fh && res_locked(dev, RESOURCE_OVERLAY)) { 1621 if (fh->is_empress && res_locked(dev, RESOURCE_OVERLAY)) {
1862 /* Don't change the std from the mpeg device 1622 /* Don't change the std from the mpeg device
1863 if overlay is active. */ 1623 if overlay is active. */
1864 return -EBUSY; 1624 return -EBUSY;
@@ -1898,15 +1658,15 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_
1898 id = tvnorms[i].id; 1658 id = tvnorms[i].id;
1899 1659
1900 mutex_lock(&dev->lock); 1660 mutex_lock(&dev->lock);
1901 if (fh && res_check(fh, RESOURCE_OVERLAY)) { 1661 if (!fh->is_empress && res_check(fh, RESOURCE_OVERLAY)) {
1902 spin_lock_irqsave(&dev->slock, flags); 1662 spin_lock_irqsave(&dev->slock, flags);
1903 stop_preview(dev, fh); 1663 stop_preview(dev);
1904 spin_unlock_irqrestore(&dev->slock, flags); 1664 spin_unlock_irqrestore(&dev->slock, flags);
1905 1665
1906 set_tvnorm(dev, &tvnorms[i]); 1666 set_tvnorm(dev, &tvnorms[i]);
1907 1667
1908 spin_lock_irqsave(&dev->slock, flags); 1668 spin_lock_irqsave(&dev->slock, flags);
1909 start_preview(dev, fh); 1669 start_preview(dev);
1910 spin_unlock_irqrestore(&dev->slock, flags); 1670 spin_unlock_irqrestore(&dev->slock, flags);
1911 } else 1671 } else
1912 set_tvnorm(dev, &tvnorms[i]); 1672 set_tvnorm(dev, &tvnorms[i]);
@@ -1915,29 +1675,21 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_
1915 mutex_unlock(&dev->lock); 1675 mutex_unlock(&dev->lock);
1916 return 0; 1676 return 0;
1917} 1677}
1918EXPORT_SYMBOL_GPL(saa7134_s_std_internal); 1678EXPORT_SYMBOL_GPL(saa7134_s_std);
1919 1679
1920static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) 1680int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)
1921{ 1681{
1922 struct saa7134_fh *fh = priv; 1682 struct saa7134_dev *dev = video_drvdata(file);
1923
1924 return saa7134_s_std_internal(fh->dev, fh, id);
1925}
1926
1927static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)
1928{
1929 struct saa7134_fh *fh = priv;
1930 struct saa7134_dev *dev = fh->dev;
1931 1683
1932 *id = dev->tvnorm->id; 1684 *id = dev->tvnorm->id;
1933 return 0; 1685 return 0;
1934} 1686}
1687EXPORT_SYMBOL_GPL(saa7134_g_std);
1935 1688
1936static int saa7134_cropcap(struct file *file, void *priv, 1689static int saa7134_cropcap(struct file *file, void *priv,
1937 struct v4l2_cropcap *cap) 1690 struct v4l2_cropcap *cap)
1938{ 1691{
1939 struct saa7134_fh *fh = priv; 1692 struct saa7134_dev *dev = video_drvdata(file);
1940 struct saa7134_dev *dev = fh->dev;
1941 1693
1942 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1694 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1943 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 1695 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
@@ -1959,8 +1711,7 @@ static int saa7134_cropcap(struct file *file, void *priv,
1959 1711
1960static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop) 1712static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
1961{ 1713{
1962 struct saa7134_fh *fh = f; 1714 struct saa7134_dev *dev = video_drvdata(file);
1963 struct saa7134_dev *dev = fh->dev;
1964 1715
1965 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1716 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1966 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 1717 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
@@ -1971,22 +1722,17 @@ static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
1971 1722
1972static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *crop) 1723static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *crop)
1973{ 1724{
1974 struct saa7134_fh *fh = f; 1725 struct saa7134_dev *dev = video_drvdata(file);
1975 struct saa7134_dev *dev = fh->dev;
1976 struct v4l2_rect *b = &dev->crop_bounds; 1726 struct v4l2_rect *b = &dev->crop_bounds;
1977 struct v4l2_rect *c = &dev->crop_current; 1727 struct v4l2_rect *c = &dev->crop_current;
1978 1728
1979 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 1729 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1980 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 1730 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1981 return -EINVAL; 1731 return -EINVAL;
1982 if (crop->c.height < 0)
1983 return -EINVAL;
1984 if (crop->c.width < 0)
1985 return -EINVAL;
1986 1732
1987 if (res_locked(fh->dev, RESOURCE_OVERLAY)) 1733 if (res_locked(dev, RESOURCE_OVERLAY))
1988 return -EBUSY; 1734 return -EBUSY;
1989 if (res_locked(fh->dev, RESOURCE_VIDEO)) 1735 if (res_locked(dev, RESOURCE_VIDEO))
1990 return -EBUSY; 1736 return -EBUSY;
1991 1737
1992 *c = crop->c; 1738 *c = crop->c;
@@ -2006,11 +1752,10 @@ static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *cr
2006 return 0; 1752 return 0;
2007} 1753}
2008 1754
2009static int saa7134_g_tuner(struct file *file, void *priv, 1755int saa7134_g_tuner(struct file *file, void *priv,
2010 struct v4l2_tuner *t) 1756 struct v4l2_tuner *t)
2011{ 1757{
2012 struct saa7134_fh *fh = priv; 1758 struct saa7134_dev *dev = video_drvdata(file);
2013 struct saa7134_dev *dev = fh->dev;
2014 int n; 1759 int n;
2015 1760
2016 if (0 != t->index) 1761 if (0 != t->index)
@@ -2037,12 +1782,12 @@ static int saa7134_g_tuner(struct file *file, void *priv,
2037 t->signal = 0xffff; 1782 t->signal = 0xffff;
2038 return 0; 1783 return 0;
2039} 1784}
1785EXPORT_SYMBOL_GPL(saa7134_g_tuner);
2040 1786
2041static int saa7134_s_tuner(struct file *file, void *priv, 1787int saa7134_s_tuner(struct file *file, void *priv,
2042 const struct v4l2_tuner *t) 1788 const struct v4l2_tuner *t)
2043{ 1789{
2044 struct saa7134_fh *fh = priv; 1790 struct saa7134_dev *dev = video_drvdata(file);
2045 struct saa7134_dev *dev = fh->dev;
2046 int rx, mode; 1791 int rx, mode;
2047 1792
2048 if (0 != t->index) 1793 if (0 != t->index)
@@ -2058,12 +1803,12 @@ static int saa7134_s_tuner(struct file *file, void *priv,
2058 1803
2059 return 0; 1804 return 0;
2060} 1805}
1806EXPORT_SYMBOL_GPL(saa7134_s_tuner);
2061 1807
2062static int saa7134_g_frequency(struct file *file, void *priv, 1808int saa7134_g_frequency(struct file *file, void *priv,
2063 struct v4l2_frequency *f) 1809 struct v4l2_frequency *f)
2064{ 1810{
2065 struct saa7134_fh *fh = priv; 1811 struct saa7134_dev *dev = video_drvdata(file);
2066 struct saa7134_dev *dev = fh->dev;
2067 1812
2068 if (0 != f->tuner) 1813 if (0 != f->tuner)
2069 return -EINVAL; 1814 return -EINVAL;
@@ -2072,12 +1817,12 @@ static int saa7134_g_frequency(struct file *file, void *priv,
2072 1817
2073 return 0; 1818 return 0;
2074} 1819}
1820EXPORT_SYMBOL_GPL(saa7134_g_frequency);
2075 1821
2076static int saa7134_s_frequency(struct file *file, void *priv, 1822int saa7134_s_frequency(struct file *file, void *priv,
2077 const struct v4l2_frequency *f) 1823 const struct v4l2_frequency *f)
2078{ 1824{
2079 struct saa7134_fh *fh = priv; 1825 struct saa7134_dev *dev = video_drvdata(file);
2080 struct saa7134_dev *dev = fh->dev;
2081 1826
2082 if (0 != f->tuner) 1827 if (0 != f->tuner)
2083 return -EINVAL; 1828 return -EINVAL;
@@ -2089,6 +1834,7 @@ static int saa7134_s_frequency(struct file *file, void *priv,
2089 mutex_unlock(&dev->lock); 1834 mutex_unlock(&dev->lock);
2090 return 0; 1835 return 0;
2091} 1836}
1837EXPORT_SYMBOL_GPL(saa7134_s_frequency);
2092 1838
2093static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv, 1839static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv,
2094 struct v4l2_fmtdesc *f) 1840 struct v4l2_fmtdesc *f)
@@ -2126,8 +1872,7 @@ static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv,
2126static int saa7134_g_fbuf(struct file *file, void *f, 1872static int saa7134_g_fbuf(struct file *file, void *f,
2127 struct v4l2_framebuffer *fb) 1873 struct v4l2_framebuffer *fb)
2128{ 1874{
2129 struct saa7134_fh *fh = f; 1875 struct saa7134_dev *dev = video_drvdata(file);
2130 struct saa7134_dev *dev = fh->dev;
2131 1876
2132 *fb = dev->ovbuf; 1877 *fb = dev->ovbuf;
2133 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; 1878 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
@@ -2138,8 +1883,7 @@ static int saa7134_g_fbuf(struct file *file, void *f,
2138static int saa7134_s_fbuf(struct file *file, void *f, 1883static int saa7134_s_fbuf(struct file *file, void *f,
2139 const struct v4l2_framebuffer *fb) 1884 const struct v4l2_framebuffer *fb)
2140{ 1885{
2141 struct saa7134_fh *fh = f; 1886 struct saa7134_dev *dev = video_drvdata(file);
2142 struct saa7134_dev *dev = fh->dev;
2143 struct saa7134_format *fmt; 1887 struct saa7134_format *fmt;
2144 1888
2145 if (!capable(CAP_SYS_ADMIN) && 1889 if (!capable(CAP_SYS_ADMIN) &&
@@ -2160,10 +1904,9 @@ static int saa7134_s_fbuf(struct file *file, void *f,
2160 return 0; 1904 return 0;
2161} 1905}
2162 1906
2163static int saa7134_overlay(struct file *file, void *f, unsigned int on) 1907static int saa7134_overlay(struct file *file, void *priv, unsigned int on)
2164{ 1908{
2165 struct saa7134_fh *fh = f; 1909 struct saa7134_dev *dev = video_drvdata(file);
2166 struct saa7134_dev *dev = fh->dev;
2167 unsigned long flags; 1910 unsigned long flags;
2168 1911
2169 if (on) { 1912 if (on) {
@@ -2172,54 +1915,57 @@ static int saa7134_overlay(struct file *file, void *f, unsigned int on)
2172 return -EINVAL; 1915 return -EINVAL;
2173 } 1916 }
2174 1917
2175 if (!res_get(dev, fh, RESOURCE_OVERLAY)) 1918 if (!res_get(dev, priv, RESOURCE_OVERLAY))
2176 return -EBUSY; 1919 return -EBUSY;
2177 spin_lock_irqsave(&dev->slock, flags); 1920 spin_lock_irqsave(&dev->slock, flags);
2178 start_preview(dev, fh); 1921 start_preview(dev);
2179 spin_unlock_irqrestore(&dev->slock, flags); 1922 spin_unlock_irqrestore(&dev->slock, flags);
2180 } 1923 }
2181 if (!on) { 1924 if (!on) {
2182 if (!res_check(fh, RESOURCE_OVERLAY)) 1925 if (!res_check(priv, RESOURCE_OVERLAY))
2183 return -EINVAL; 1926 return -EINVAL;
2184 spin_lock_irqsave(&dev->slock, flags); 1927 spin_lock_irqsave(&dev->slock, flags);
2185 stop_preview(dev, fh); 1928 stop_preview(dev);
2186 spin_unlock_irqrestore(&dev->slock, flags); 1929 spin_unlock_irqrestore(&dev->slock, flags);
2187 res_free(dev, fh, RESOURCE_OVERLAY); 1930 res_free(dev, priv, RESOURCE_OVERLAY);
2188 } 1931 }
2189 return 0; 1932 return 0;
2190} 1933}
2191 1934
2192static int saa7134_reqbufs(struct file *file, void *priv, 1935int saa7134_reqbufs(struct file *file, void *priv,
2193 struct v4l2_requestbuffers *p) 1936 struct v4l2_requestbuffers *p)
2194{ 1937{
2195 return videobuf_reqbufs(saa7134_queue(file), p); 1938 return videobuf_reqbufs(saa7134_queue(file), p);
2196} 1939}
1940EXPORT_SYMBOL_GPL(saa7134_reqbufs);
2197 1941
2198static int saa7134_querybuf(struct file *file, void *priv, 1942int saa7134_querybuf(struct file *file, void *priv,
2199 struct v4l2_buffer *b) 1943 struct v4l2_buffer *b)
2200{ 1944{
2201 return videobuf_querybuf(saa7134_queue(file), b); 1945 return videobuf_querybuf(saa7134_queue(file), b);
2202} 1946}
1947EXPORT_SYMBOL_GPL(saa7134_querybuf);
2203 1948
2204static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1949int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
2205{ 1950{
2206 return videobuf_qbuf(saa7134_queue(file), b); 1951 return videobuf_qbuf(saa7134_queue(file), b);
2207} 1952}
1953EXPORT_SYMBOL_GPL(saa7134_qbuf);
2208 1954
2209static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1955int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
2210{ 1956{
2211 return videobuf_dqbuf(saa7134_queue(file), b, 1957 return videobuf_dqbuf(saa7134_queue(file), b,
2212 file->f_flags & O_NONBLOCK); 1958 file->f_flags & O_NONBLOCK);
2213} 1959}
1960EXPORT_SYMBOL_GPL(saa7134_dqbuf);
2214 1961
2215static int saa7134_streamon(struct file *file, void *priv, 1962int saa7134_streamon(struct file *file, void *priv,
2216 enum v4l2_buf_type type) 1963 enum v4l2_buf_type type)
2217{ 1964{
2218 struct saa7134_fh *fh = priv; 1965 struct saa7134_dev *dev = video_drvdata(file);
2219 struct saa7134_dev *dev = fh->dev;
2220 int res = saa7134_resource(file); 1966 int res = saa7134_resource(file);
2221 1967
2222 if (!res_get(dev, fh, res)) 1968 if (!res_get(dev, priv, res))
2223 return -EBUSY; 1969 return -EBUSY;
2224 1970
2225 /* The SAA7134 has a 1K FIFO; the datasheet suggests that when 1971 /* The SAA7134 has a 1K FIFO; the datasheet suggests that when
@@ -2229,36 +1975,37 @@ static int saa7134_streamon(struct file *file, void *priv,
2229 * Unfortunately, I lack register-level documentation to check the 1975 * Unfortunately, I lack register-level documentation to check the
2230 * Linux FIFO setup and confirm the perfect value. 1976 * Linux FIFO setup and confirm the perfect value.
2231 */ 1977 */
2232 pm_qos_add_request(&dev->qos_request, 1978 if (res != RESOURCE_EMPRESS)
2233 PM_QOS_CPU_DMA_LATENCY, 1979 pm_qos_add_request(&dev->qos_request,
2234 20); 1980 PM_QOS_CPU_DMA_LATENCY, 20);
2235 1981
2236 return videobuf_streamon(saa7134_queue(file)); 1982 return videobuf_streamon(saa7134_queue(file));
2237} 1983}
1984EXPORT_SYMBOL_GPL(saa7134_streamon);
2238 1985
2239static int saa7134_streamoff(struct file *file, void *priv, 1986int saa7134_streamoff(struct file *file, void *priv,
2240 enum v4l2_buf_type type) 1987 enum v4l2_buf_type type)
2241{ 1988{
1989 struct saa7134_dev *dev = video_drvdata(file);
2242 int err; 1990 int err;
2243 struct saa7134_fh *fh = priv;
2244 struct saa7134_dev *dev = fh->dev;
2245 int res = saa7134_resource(file); 1991 int res = saa7134_resource(file);
2246 1992
2247 pm_qos_remove_request(&dev->qos_request); 1993 if (res != RESOURCE_EMPRESS)
1994 pm_qos_remove_request(&dev->qos_request);
2248 1995
2249 err = videobuf_streamoff(saa7134_queue(file)); 1996 err = videobuf_streamoff(saa7134_queue(file));
2250 if (err < 0) 1997 if (err < 0)
2251 return err; 1998 return err;
2252 res_free(dev, fh, res); 1999 res_free(dev, priv, res);
2253 return 0; 2000 return 0;
2254} 2001}
2002EXPORT_SYMBOL_GPL(saa7134_streamoff);
2255 2003
2256#ifdef CONFIG_VIDEO_ADV_DEBUG 2004#ifdef CONFIG_VIDEO_ADV_DEBUG
2257static int vidioc_g_register (struct file *file, void *priv, 2005static int vidioc_g_register (struct file *file, void *priv,
2258 struct v4l2_dbg_register *reg) 2006 struct v4l2_dbg_register *reg)
2259{ 2007{
2260 struct saa7134_fh *fh = priv; 2008 struct saa7134_dev *dev = video_drvdata(file);
2261 struct saa7134_dev *dev = fh->dev;
2262 2009
2263 reg->val = saa_readb(reg->reg & 0xffffff); 2010 reg->val = saa_readb(reg->reg & 0xffffff);
2264 reg->size = 1; 2011 reg->size = 1;
@@ -2268,8 +2015,7 @@ static int vidioc_g_register (struct file *file, void *priv,
2268static int vidioc_s_register (struct file *file, void *priv, 2015static int vidioc_s_register (struct file *file, void *priv,
2269 const struct v4l2_dbg_register *reg) 2016 const struct v4l2_dbg_register *reg)
2270{ 2017{
2271 struct saa7134_fh *fh = priv; 2018 struct saa7134_dev *dev = video_drvdata(file);
2272 struct saa7134_dev *dev = fh->dev;
2273 2019
2274 saa_writeb(reg->reg & 0xffffff, reg->val); 2020 saa_writeb(reg->reg & 0xffffff, reg->val);
2275 return 0; 2021 return 0;
@@ -2279,8 +2025,7 @@ static int vidioc_s_register (struct file *file, void *priv,
2279static int radio_g_tuner(struct file *file, void *priv, 2025static int radio_g_tuner(struct file *file, void *priv,
2280 struct v4l2_tuner *t) 2026 struct v4l2_tuner *t)
2281{ 2027{
2282 struct saa7134_fh *fh = file->private_data; 2028 struct saa7134_dev *dev = video_drvdata(file);
2283 struct saa7134_dev *dev = fh->dev;
2284 2029
2285 if (0 != t->index) 2030 if (0 != t->index)
2286 return -EINVAL; 2031 return -EINVAL;
@@ -2299,8 +2044,7 @@ static int radio_g_tuner(struct file *file, void *priv,
2299static int radio_s_tuner(struct file *file, void *priv, 2044static int radio_s_tuner(struct file *file, void *priv,
2300 const struct v4l2_tuner *t) 2045 const struct v4l2_tuner *t)
2301{ 2046{
2302 struct saa7134_fh *fh = file->private_data; 2047 struct saa7134_dev *dev = video_drvdata(file);
2303 struct saa7134_dev *dev = fh->dev;
2304 2048
2305 if (0 != t->index) 2049 if (0 != t->index)
2306 return -EINVAL; 2050 return -EINVAL;
@@ -2309,50 +2053,6 @@ static int radio_s_tuner(struct file *file, void *priv,
2309 return 0; 2053 return 0;
2310} 2054}
2311 2055
2312static int radio_enum_input(struct file *file, void *priv,
2313 struct v4l2_input *i)
2314{
2315 if (i->index != 0)
2316 return -EINVAL;
2317
2318 strcpy(i->name, "Radio");
2319 i->type = V4L2_INPUT_TYPE_TUNER;
2320
2321 return 0;
2322}
2323
2324static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
2325{
2326 *i = 0;
2327 return 0;
2328}
2329
2330static int radio_s_input(struct file *filp, void *priv, unsigned int i)
2331{
2332 return 0;
2333}
2334
2335static int radio_s_std(struct file *file, void *fh, v4l2_std_id norm)
2336{
2337 return 0;
2338}
2339
2340static int radio_queryctrl(struct file *file, void *priv,
2341 struct v4l2_queryctrl *c)
2342{
2343 const struct v4l2_queryctrl *ctrl;
2344
2345 if (c->id < V4L2_CID_BASE ||
2346 c->id >= V4L2_CID_LASTP1)
2347 return -EINVAL;
2348 if (c->id == V4L2_CID_AUDIO_MUTE) {
2349 ctrl = ctrl_by_id(c->id);
2350 *c = *ctrl;
2351 } else
2352 *c = no_ctrl;
2353 return 0;
2354}
2355
2356static const struct v4l2_file_operations video_fops = 2056static const struct v4l2_file_operations video_fops =
2357{ 2057{
2358 .owner = THIS_MODULE, 2058 .owner = THIS_MODULE,
@@ -2387,9 +2087,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
2387 .vidioc_enum_input = saa7134_enum_input, 2087 .vidioc_enum_input = saa7134_enum_input,
2388 .vidioc_g_input = saa7134_g_input, 2088 .vidioc_g_input = saa7134_g_input,
2389 .vidioc_s_input = saa7134_s_input, 2089 .vidioc_s_input = saa7134_s_input,
2390 .vidioc_queryctrl = saa7134_queryctrl,
2391 .vidioc_g_ctrl = saa7134_g_ctrl,
2392 .vidioc_s_ctrl = saa7134_s_ctrl,
2393 .vidioc_streamon = saa7134_streamon, 2090 .vidioc_streamon = saa7134_streamon,
2394 .vidioc_streamoff = saa7134_streamoff, 2091 .vidioc_streamoff = saa7134_streamoff,
2395 .vidioc_g_tuner = saa7134_g_tuner, 2092 .vidioc_g_tuner = saa7134_g_tuner,
@@ -2405,6 +2102,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
2405 .vidioc_g_register = vidioc_g_register, 2102 .vidioc_g_register = vidioc_g_register,
2406 .vidioc_s_register = vidioc_s_register, 2103 .vidioc_s_register = vidioc_s_register,
2407#endif 2104#endif
2105 .vidioc_log_status = v4l2_ctrl_log_status,
2106 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2107 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2408}; 2108};
2409 2109
2410static const struct v4l2_file_operations radio_fops = { 2110static const struct v4l2_file_operations radio_fops = {
@@ -2419,16 +2119,11 @@ static const struct v4l2_file_operations radio_fops = {
2419static const struct v4l2_ioctl_ops radio_ioctl_ops = { 2119static const struct v4l2_ioctl_ops radio_ioctl_ops = {
2420 .vidioc_querycap = saa7134_querycap, 2120 .vidioc_querycap = saa7134_querycap,
2421 .vidioc_g_tuner = radio_g_tuner, 2121 .vidioc_g_tuner = radio_g_tuner,
2422 .vidioc_enum_input = radio_enum_input,
2423 .vidioc_s_tuner = radio_s_tuner, 2122 .vidioc_s_tuner = radio_s_tuner,
2424 .vidioc_s_input = radio_s_input,
2425 .vidioc_s_std = radio_s_std,
2426 .vidioc_queryctrl = radio_queryctrl,
2427 .vidioc_g_input = radio_g_input,
2428 .vidioc_g_ctrl = saa7134_g_ctrl,
2429 .vidioc_s_ctrl = saa7134_s_ctrl,
2430 .vidioc_g_frequency = saa7134_g_frequency, 2123 .vidioc_g_frequency = saa7134_g_frequency,
2431 .vidioc_s_frequency = saa7134_s_frequency, 2124 .vidioc_s_frequency = saa7134_s_frequency,
2125 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2126 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2432}; 2127};
2433 2128
2434/* ----------------------------------------------------------- */ 2129/* ----------------------------------------------------------- */
@@ -2447,8 +2142,55 @@ struct video_device saa7134_radio_template = {
2447 .ioctl_ops = &radio_ioctl_ops, 2142 .ioctl_ops = &radio_ioctl_ops,
2448}; 2143};
2449 2144
2145static const struct v4l2_ctrl_ops saa7134_ctrl_ops = {
2146 .s_ctrl = saa7134_s_ctrl,
2147};
2148
2149static const struct v4l2_ctrl_config saa7134_ctrl_invert = {
2150 .ops = &saa7134_ctrl_ops,
2151 .id = V4L2_CID_PRIVATE_INVERT,
2152 .name = "Invert",
2153 .type = V4L2_CTRL_TYPE_BOOLEAN,
2154 .min = 0,
2155 .max = 1,
2156 .step = 1,
2157};
2158
2159static const struct v4l2_ctrl_config saa7134_ctrl_y_odd = {
2160 .ops = &saa7134_ctrl_ops,
2161 .id = V4L2_CID_PRIVATE_Y_ODD,
2162 .name = "Y Offset Odd Field",
2163 .type = V4L2_CTRL_TYPE_INTEGER,
2164 .min = 0,
2165 .max = 128,
2166 .step = 1,
2167};
2168
2169static const struct v4l2_ctrl_config saa7134_ctrl_y_even = {
2170 .ops = &saa7134_ctrl_ops,
2171 .id = V4L2_CID_PRIVATE_Y_EVEN,
2172 .name = "Y Offset Even Field",
2173 .type = V4L2_CTRL_TYPE_INTEGER,
2174 .min = 0,
2175 .max = 128,
2176 .step = 1,
2177};
2178
2179static const struct v4l2_ctrl_config saa7134_ctrl_automute = {
2180 .ops = &saa7134_ctrl_ops,
2181 .id = V4L2_CID_PRIVATE_AUTOMUTE,
2182 .name = "Automute",
2183 .type = V4L2_CTRL_TYPE_BOOLEAN,
2184 .min = 0,
2185 .max = 1,
2186 .step = 1,
2187 .def = 1,
2188};
2189
2450int saa7134_video_init1(struct saa7134_dev *dev) 2190int saa7134_video_init1(struct saa7134_dev *dev)
2451{ 2191{
2192 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2193
2452 /* sanitycheck insmod options */ 2194 /* sanitycheck insmod options */
2453 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) 2195 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
2454 gbuffers = 2; 2196 gbuffers = 2;
@@ -2456,17 +2198,38 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2456 gbufsize = gbufsize_max; 2198 gbufsize = gbufsize_max;
2457 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; 2199 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
2458 2200
2459 /* put some sensible defaults into the data structures ... */ 2201 v4l2_ctrl_handler_init(hdl, 11);
2460 dev->ctl_bright = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value; 2202 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2461 dev->ctl_contrast = ctrl_by_id(V4L2_CID_CONTRAST)->default_value; 2203 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
2462 dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value; 2204 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2463 dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value; 2205 V4L2_CID_CONTRAST, 0, 127, 1, 68);
2464 dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value; 2206 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2465 dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value; 2207 V4L2_CID_SATURATION, 0, 127, 1, 64);
2466 dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value; 2208 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2467 dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value; 2209 V4L2_CID_HUE, -128, 127, 1, 0);
2468 2210 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2469 if (dev->tda9887_conf && dev->ctl_automute) 2211 V4L2_CID_HFLIP, 0, 1, 1, 0);
2212 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2213 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
2214 v4l2_ctrl_new_std(hdl, &saa7134_ctrl_ops,
2215 V4L2_CID_AUDIO_VOLUME, -15, 15, 1, 0);
2216 v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_invert, NULL);
2217 v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_y_odd, NULL);
2218 v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_y_even, NULL);
2219 v4l2_ctrl_new_custom(hdl, &saa7134_ctrl_automute, NULL);
2220 if (hdl->error)
2221 return hdl->error;
2222 if (card_has_radio(dev)) {
2223 hdl = &dev->radio_ctrl_handler;
2224 v4l2_ctrl_handler_init(hdl, 2);
2225 v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler,
2226 v4l2_ctrl_radio_filter);
2227 if (hdl->error)
2228 return hdl->error;
2229 }
2230 dev->ctl_mute = 1;
2231
2232 if (dev->tda9887_conf && saa7134_ctrl_automute.def)
2470 dev->tda9887_conf |= TDA9887_AUTOMUTE; 2233 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2471 dev->automute = 0; 2234 dev->automute = 0;
2472 2235
@@ -2489,9 +2252,34 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2489 if (saa7134_boards[dev->board].video_out) 2252 if (saa7134_boards[dev->board].video_out)
2490 saa7134_videoport_init(dev); 2253 saa7134_videoport_init(dev);
2491 2254
2255 videobuf_queue_sg_init(&dev->cap, &video_qops,
2256 &dev->pci->dev, &dev->slock,
2257 V4L2_BUF_TYPE_VIDEO_CAPTURE,
2258 V4L2_FIELD_INTERLACED,
2259 sizeof(struct saa7134_buf),
2260 dev, NULL);
2261 videobuf_queue_sg_init(&dev->vbi, &saa7134_vbi_qops,
2262 &dev->pci->dev, &dev->slock,
2263 V4L2_BUF_TYPE_VBI_CAPTURE,
2264 V4L2_FIELD_SEQ_TB,
2265 sizeof(struct saa7134_buf),
2266 dev, NULL);
2267 saa7134_pgtable_alloc(dev->pci, &dev->pt_cap);
2268 saa7134_pgtable_alloc(dev->pci, &dev->pt_vbi);
2269
2492 return 0; 2270 return 0;
2493} 2271}
2494 2272
2273void saa7134_video_fini(struct saa7134_dev *dev)
2274{
2275 /* free stuff */
2276 saa7134_pgtable_free(dev->pci, &dev->pt_cap);
2277 saa7134_pgtable_free(dev->pci, &dev->pt_vbi);
2278 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2279 if (card_has_radio(dev))
2280 v4l2_ctrl_handler_free(&dev->radio_ctrl_handler);
2281}
2282
2495int saa7134_videoport_init(struct saa7134_dev *dev) 2283int saa7134_videoport_init(struct saa7134_dev *dev)
2496{ 2284{
2497 /* enable video output */ 2285 /* enable video output */
@@ -2533,6 +2321,7 @@ int saa7134_video_init2(struct saa7134_dev *dev)
2533 /* init video hw */ 2321 /* init video hw */
2534 set_tvnorm(dev,&tvnorms[0]); 2322 set_tvnorm(dev,&tvnorms[0]);
2535 video_mux(dev,0); 2323 video_mux(dev,0);
2324 v4l2_ctrl_handler_setup(&dev->ctrl_handler);
2536 saa7134_tvaudio_setmute(dev); 2325 saa7134_tvaudio_setmute(dev);
2537 saa7134_tvaudio_setvolume(dev,dev->ctl_volume); 2326 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
2538 return 0; 2327 return 0;
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 8d1453a48014..2474e848f2c0 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -37,6 +37,7 @@
37#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-device.h> 38#include <media/v4l2-device.h>
39#include <media/v4l2-fh.h> 39#include <media/v4l2-fh.h>
40#include <media/v4l2-ctrls.h>
40#include <media/tuner.h> 41#include <media/tuner.h>
41#include <media/rc-core.h> 42#include <media/rc-core.h>
42#include <media/ir-kbd-i2c.h> 43#include <media/ir-kbd-i2c.h>
@@ -410,12 +411,18 @@ struct saa7134_board {
410#define card(dev) (saa7134_boards[dev->board]) 411#define card(dev) (saa7134_boards[dev->board])
411#define card_in(dev,n) (saa7134_boards[dev->board].inputs[n]) 412#define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
412 413
414#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_USER_SAA7134_BASE + 0)
415#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_USER_SAA7134_BASE + 1)
416#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_USER_SAA7134_BASE + 2)
417#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_USER_SAA7134_BASE + 3)
418
413/* ----------------------------------------------------------- */ 419/* ----------------------------------------------------------- */
414/* device / file handle status */ 420/* device / file handle status */
415 421
416#define RESOURCE_OVERLAY 1 422#define RESOURCE_OVERLAY 1
417#define RESOURCE_VIDEO 2 423#define RESOURCE_VIDEO 2
418#define RESOURCE_VBI 4 424#define RESOURCE_VBI 4
425#define RESOURCE_EMPRESS 8
419 426
420#define INTERLACE_AUTO 0 427#define INTERLACE_AUTO 0
421#define INTERLACE_ON 1 428#define INTERLACE_ON 1
@@ -470,16 +477,8 @@ struct saa7134_dmaqueue {
470/* video filehandle status */ 477/* video filehandle status */
471struct saa7134_fh { 478struct saa7134_fh {
472 struct v4l2_fh fh; 479 struct v4l2_fh fh;
473 struct saa7134_dev *dev; 480 bool is_empress;
474 unsigned int resources; 481 unsigned int resources;
475
476 /* video capture */
477 struct videobuf_queue cap;
478 struct saa7134_pgtable pt_cap;
479
480 /* vbi capture */
481 struct videobuf_queue vbi;
482 struct saa7134_pgtable pt_vbi;
483}; 482};
484 483
485/* dmasound dsp status */ 484/* dmasound dsp status */
@@ -589,7 +588,11 @@ struct saa7134_dev {
589 588
590 /* video+ts+vbi capture */ 589 /* video+ts+vbi capture */
591 struct saa7134_dmaqueue video_q; 590 struct saa7134_dmaqueue video_q;
591 struct videobuf_queue cap;
592 struct saa7134_pgtable pt_cap;
592 struct saa7134_dmaqueue vbi_q; 593 struct saa7134_dmaqueue vbi_q;
594 struct videobuf_queue vbi;
595 struct saa7134_pgtable pt_vbi;
593 unsigned int video_fieldcount; 596 unsigned int video_fieldcount;
594 unsigned int vbi_fieldcount; 597 unsigned int vbi_fieldcount;
595 struct saa7134_format *fmt; 598 struct saa7134_format *fmt;
@@ -599,6 +602,7 @@ struct saa7134_dev {
599 /* various v4l controls */ 602 /* various v4l controls */
600 struct saa7134_tvnorm *tvnorm; /* video */ 603 struct saa7134_tvnorm *tvnorm; /* video */
601 struct saa7134_tvaudio *tvaudio; 604 struct saa7134_tvaudio *tvaudio;
605 struct v4l2_ctrl_handler ctrl_handler;
602 unsigned int ctl_input; 606 unsigned int ctl_input;
603 int ctl_bright; 607 int ctl_bright;
604 int ctl_contrast; 608 int ctl_contrast;
@@ -626,6 +630,7 @@ struct saa7134_dev {
626 int last_carrier; 630 int last_carrier;
627 int nosignal; 631 int nosignal;
628 unsigned int insuspend; 632 unsigned int insuspend;
633 struct v4l2_ctrl_handler radio_ctrl_handler;
629 634
630 /* I2C keyboard data */ 635 /* I2C keyboard data */
631 struct IR_i2c_init_data init_data; 636 struct IR_i2c_init_data init_data;
@@ -638,10 +643,11 @@ struct saa7134_dev {
638 643
639 /* SAA7134_MPEG_EMPRESS only */ 644 /* SAA7134_MPEG_EMPRESS only */
640 struct video_device *empress_dev; 645 struct video_device *empress_dev;
646 struct v4l2_subdev *empress_sd;
641 struct videobuf_queue empress_tsq; 647 struct videobuf_queue empress_tsq;
642 atomic_t empress_users;
643 struct work_struct empress_workqueue; 648 struct work_struct empress_workqueue;
644 int empress_started; 649 int empress_started;
650 struct v4l2_ctrl_handler empress_ctrl_handler;
645 651
646#if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB) 652#if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
647 /* SAA7134_MPEG_DVB only */ 653 /* SAA7134_MPEG_DVB only */
@@ -699,6 +705,16 @@ struct saa7134_dev {
699 _rc; \ 705 _rc; \
700}) 706})
701 707
708static inline int res_check(struct saa7134_fh *fh, unsigned int bit)
709{
710 return fh->resources & bit;
711}
712
713static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
714{
715 return dev->resources & bit;
716}
717
702/* ----------------------------------------------------------- */ 718/* ----------------------------------------------------------- */
703/* saa7134-core.c */ 719/* saa7134-core.c */
704 720
@@ -761,10 +777,31 @@ extern unsigned int video_debug;
761extern struct video_device saa7134_video_template; 777extern struct video_device saa7134_video_template;
762extern struct video_device saa7134_radio_template; 778extern struct video_device saa7134_radio_template;
763 779
764int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); 780int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id);
765int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); 781int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id);
766int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c); 782int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i);
767int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id id); 783int saa7134_g_input(struct file *file, void *priv, unsigned int *i);
784int saa7134_s_input(struct file *file, void *priv, unsigned int i);
785int saa7134_querycap(struct file *file, void *priv,
786 struct v4l2_capability *cap);
787int saa7134_g_tuner(struct file *file, void *priv,
788 struct v4l2_tuner *t);
789int saa7134_s_tuner(struct file *file, void *priv,
790 const struct v4l2_tuner *t);
791int saa7134_g_frequency(struct file *file, void *priv,
792 struct v4l2_frequency *f);
793int saa7134_s_frequency(struct file *file, void *priv,
794 const struct v4l2_frequency *f);
795int saa7134_reqbufs(struct file *file, void *priv,
796 struct v4l2_requestbuffers *p);
797int saa7134_querybuf(struct file *file, void *priv,
798 struct v4l2_buffer *b);
799int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
800int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
801int saa7134_streamon(struct file *file, void *priv,
802 enum v4l2_buf_type type);
803int saa7134_streamoff(struct file *file, void *priv,
804 enum v4l2_buf_type type);
768 805
769int saa7134_videoport_init(struct saa7134_dev *dev); 806int saa7134_videoport_init(struct saa7134_dev *dev);
770void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); 807void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
@@ -773,6 +810,7 @@ int saa7134_video_init1(struct saa7134_dev *dev);
773int saa7134_video_init2(struct saa7134_dev *dev); 810int saa7134_video_init2(struct saa7134_dev *dev);
774void saa7134_irq_video_signalchange(struct saa7134_dev *dev); 811void saa7134_irq_video_signalchange(struct saa7134_dev *dev);
775void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status); 812void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
813void saa7134_video_fini(struct saa7134_dev *dev);
776 814
777 815
778/* ----------------------------------------------------------- */ 816/* ----------------------------------------------------------- */
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index 77edc113e485..e5cfb6cfa18d 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -1303,7 +1303,7 @@ static int sta2x11_vip_resume(struct pci_dev *pdev)
1303 1303
1304#endif 1304#endif
1305 1305
1306static DEFINE_PCI_DEVICE_TABLE(sta2x11_vip_pci_tbl) = { 1306static const struct pci_device_id sta2x11_vip_pci_tbl[] = {
1307 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)}, 1307 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},
1308 {0,} 1308 {0,}
1309}; 1309};
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index d7f0249e4050..b2a4403940c5 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -36,7 +36,8 @@ source "drivers/media/platform/blackfin/Kconfig"
36config VIDEO_SH_VOU 36config VIDEO_SH_VOU
37 tristate "SuperH VOU video output driver" 37 tristate "SuperH VOU video output driver"
38 depends on MEDIA_CAMERA_SUPPORT 38 depends on MEDIA_CAMERA_SUPPORT
39 depends on VIDEO_DEV && ARCH_SHMOBILE && I2C 39 depends on VIDEO_DEV && I2C
40 depends on ARCH_SHMOBILE || COMPILE_TEST
40 select VIDEOBUF_DMA_CONTIG 41 select VIDEOBUF_DMA_CONTIG
41 help 42 help
42 Support for the Video Output Unit (VOU) on SuperH SoCs. 43 Support for the Video Output Unit (VOU) on SuperH SoCs.
@@ -90,13 +91,6 @@ config VIDEO_M32R_AR_M64278
90 To compile this driver as a module, choose M here: the 91 To compile this driver as a module, choose M here: the
91 module will be called arv. 92 module will be called arv.
92 93
93config VIDEO_OMAP2
94 tristate "OMAP2 Camera Capture Interface driver"
95 depends on VIDEO_DEV && ARCH_OMAP2 && VIDEO_V4L2_INT_DEVICE
96 select VIDEOBUF_DMA_SG
97 ---help---
98 This is a v4l2 driver for the TI OMAP2 camera capture interface
99
100config VIDEO_OMAP3 94config VIDEO_OMAP3
101 tristate "OMAP 3 Camera support" 95 tristate "OMAP 3 Camera support"
102 depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 96 depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 1348ba1faf92..e5269da91906 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -2,8 +2,6 @@
2# Makefile for the video capture/playback device drivers. 2# Makefile for the video capture/playback device drivers.
3# 3#
4 4
5omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
6
7obj-$(CONFIG_VIDEO_VINO) += indycam.o 5obj-$(CONFIG_VIDEO_VINO) += indycam.o
8obj-$(CONFIG_VIDEO_VINO) += vino.o 6obj-$(CONFIG_VIDEO_VINO) += vino.o
9 7
@@ -14,7 +12,6 @@ obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
14obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/ 12obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/
15obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/ 13obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/
16 14
17obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
18obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/ 15obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
19 16
20obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o 17obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index eac472b5ae83..b02aba488826 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -347,7 +347,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
347 /* If buffer queue is empty, return error */ 347 /* If buffer queue is empty, return error */
348 if (list_empty(&layer->dma_queue)) { 348 if (list_empty(&layer->dma_queue)) {
349 v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n"); 349 v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
350 return -EINVAL; 350 return -ENOBUFS;
351 } 351 }
352 /* Get the next frame from the buffer queue */ 352 /* Get the next frame from the buffer queue */
353 layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next, 353 layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 52ac5e6c8625..735ec47601a9 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -277,7 +277,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
277 if (list_empty(&common->dma_queue)) { 277 if (list_empty(&common->dma_queue)) {
278 spin_unlock_irqrestore(&common->irqlock, flags); 278 spin_unlock_irqrestore(&common->irqlock, flags);
279 vpif_dbg(1, debug, "buffer queue is empty\n"); 279 vpif_dbg(1, debug, "buffer queue is empty\n");
280 return -EIO; 280 return -ENOBUFS;
281 } 281 }
282 282
283 /* Get the next frame from the buffer queue */ 283 /* Get the next frame from the buffer queue */
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index c31bcf129a5d..9d115cdc6bdb 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -239,7 +239,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
239 if (list_empty(&common->dma_queue)) { 239 if (list_empty(&common->dma_queue)) {
240 spin_unlock_irqrestore(&common->irqlock, flags); 240 spin_unlock_irqrestore(&common->irqlock, flags);
241 vpif_err("buffer queue is empty\n"); 241 vpif_err("buffer queue is empty\n");
242 return -EIO; 242 return -ENOBUFS;
243 } 243 }
244 244
245 /* Get the next frame from the buffer queue */ 245 /* Get the next frame from the buffer queue */
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index d2d3b4b61435..01ed1ecdff7e 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -1,7 +1,7 @@
1 1
2config VIDEO_SAMSUNG_EXYNOS4_IS 2config VIDEO_SAMSUNG_EXYNOS4_IS
3 bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" 3 bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver"
4 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PM_RUNTIME 4 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
5 depends on (PLAT_S5P || ARCH_EXYNOS) 5 depends on (PLAT_S5P || ARCH_EXYNOS)
6 help 6 help
7 Say Y here to enable camera host interface devices for 7 Say Y here to enable camera host interface devices for
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index fb27ff7e1e07..8a712ca91d11 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -549,7 +549,7 @@ static int fimc_capture_release(struct file *file)
549 vc->streaming = false; 549 vc->streaming = false;
550 } 550 }
551 551
552 ret = vb2_fop_release(file); 552 ret = _vb2_fop_release(file, NULL);
553 553
554 if (close) { 554 if (close) {
555 clear_bit(ST_CAPT_BUSY, &fimc->state); 555 clear_bit(ST_CAPT_BUSY, &fimc->state);
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index f7915695c907..a7dfd07e8389 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -998,36 +998,39 @@ static int fimc_probe(struct platform_device *pdev)
998 998
999 ret = devm_request_irq(dev, res->start, fimc_irq_handler, 999 ret = devm_request_irq(dev, res->start, fimc_irq_handler,
1000 0, dev_name(dev), fimc); 1000 0, dev_name(dev), fimc);
1001 if (ret) { 1001 if (ret < 0) {
1002 dev_err(dev, "failed to install irq (%d)\n", ret); 1002 dev_err(dev, "failed to install irq (%d)\n", ret);
1003 goto err_clk; 1003 goto err_sclk;
1004 } 1004 }
1005 1005
1006 ret = fimc_initialize_capture_subdev(fimc); 1006 ret = fimc_initialize_capture_subdev(fimc);
1007 if (ret) 1007 if (ret < 0)
1008 goto err_clk; 1008 goto err_sclk;
1009 1009
1010 platform_set_drvdata(pdev, fimc); 1010 platform_set_drvdata(pdev, fimc);
1011 pm_runtime_enable(dev); 1011 pm_runtime_enable(dev);
1012 ret = pm_runtime_get_sync(dev); 1012
1013 if (ret < 0) 1013 if (!pm_runtime_enabled(dev)) {
1014 goto err_sd; 1014 ret = clk_enable(fimc->clock[CLK_GATE]);
1015 if (ret < 0)
1016 goto err_sd;
1017 }
1018
1015 /* Initialize contiguous memory allocator */ 1019 /* Initialize contiguous memory allocator */
1016 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); 1020 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
1017 if (IS_ERR(fimc->alloc_ctx)) { 1021 if (IS_ERR(fimc->alloc_ctx)) {
1018 ret = PTR_ERR(fimc->alloc_ctx); 1022 ret = PTR_ERR(fimc->alloc_ctx);
1019 goto err_pm; 1023 goto err_gclk;
1020 } 1024 }
1021 1025
1022 dev_dbg(dev, "FIMC.%d registered successfully\n", fimc->id); 1026 dev_dbg(dev, "FIMC.%d registered successfully\n", fimc->id);
1023
1024 pm_runtime_put(dev);
1025 return 0; 1027 return 0;
1026err_pm: 1028
1027 pm_runtime_put(dev); 1029err_gclk:
1030 clk_disable(fimc->clock[CLK_GATE]);
1028err_sd: 1031err_sd:
1029 fimc_unregister_capture_subdev(fimc); 1032 fimc_unregister_capture_subdev(fimc);
1030err_clk: 1033err_sclk:
1031 clk_disable(fimc->clock[CLK_BUS]); 1034 clk_disable(fimc->clock[CLK_BUS]);
1032 fimc_clk_put(fimc); 1035 fimc_clk_put(fimc);
1033 return ret; 1036 return ret;
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
index 3d376faec777..1790fb4e32ea 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/exynos4-is/fimc-core.h
@@ -481,7 +481,6 @@ struct fimc_ctrls {
481 * @flags: additional flags for image conversion 481 * @flags: additional flags for image conversion
482 * @state: flags to keep track of user configuration 482 * @state: flags to keep track of user configuration
483 * @fimc_dev: the FIMC device this context applies to 483 * @fimc_dev: the FIMC device this context applies to
484 * @m2m_ctx: memory-to-memory device context
485 * @fh: v4l2 file handle 484 * @fh: v4l2 file handle
486 * @ctrls: v4l2 controls structure 485 * @ctrls: v4l2 controls structure
487 */ 486 */
@@ -502,7 +501,6 @@ struct fimc_ctx {
502 u32 flags; 501 u32 flags;
503 u32 state; 502 u32 state;
504 struct fimc_dev *fimc_dev; 503 struct fimc_dev *fimc_dev;
505 struct v4l2_m2m_ctx *m2m_ctx;
506 struct v4l2_fh fh; 504 struct v4l2_fh fh;
507 struct fimc_ctrls ctrls; 505 struct fimc_ctrls ctrls;
508}; 506};
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
index f758e2694fa3..2628733c4e10 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
@@ -33,47 +33,23 @@ void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is)
33 mcuctl_write(INTGR0_INTGD(0), is, MCUCTL_REG_INTGR0); 33 mcuctl_write(INTGR0_INTGD(0), is, MCUCTL_REG_INTGR0);
34} 34}
35 35
36int fimc_is_hw_wait_intsr0_intsd0(struct fimc_is *is)
37{
38 unsigned int timeout = 2000;
39 u32 cfg, status;
40
41 cfg = mcuctl_read(is, MCUCTL_REG_INTSR0);
42 status = INTSR0_GET_INTSD(0, cfg);
43
44 while (status) {
45 cfg = mcuctl_read(is, MCUCTL_REG_INTSR0);
46 status = INTSR0_GET_INTSD(0, cfg);
47 if (timeout == 0) {
48 dev_warn(&is->pdev->dev, "%s timeout\n",
49 __func__);
50 return -ETIME;
51 }
52 timeout--;
53 udelay(1);
54 }
55 return 0;
56}
57
58int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is) 36int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is)
59{ 37{
60 unsigned int timeout = 2000; 38 unsigned int timeout = 2000;
61 u32 cfg, status; 39 u32 cfg, status;
62 40
63 cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0); 41 do {
64 status = INTMSR0_GET_INTMSD(0, cfg);
65
66 while (status) {
67 cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0); 42 cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0);
68 status = INTMSR0_GET_INTMSD(0, cfg); 43 status = INTMSR0_GET_INTMSD(0, cfg);
69 if (timeout == 0) { 44
45 if (--timeout == 0) {
70 dev_warn(&is->pdev->dev, "%s timeout\n", 46 dev_warn(&is->pdev->dev, "%s timeout\n",
71 __func__); 47 __func__);
72 return -ETIME; 48 return -ETIMEDOUT;
73 } 49 }
74 timeout--;
75 udelay(1); 50 udelay(1);
76 } 51 } while (status != 0);
52
77 return 0; 53 return 0;
78} 54}
79 55
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.h b/drivers/media/platform/exynos4-is/fimc-is-regs.h
index 5fa2fda46742..1d9d4ffc6ad5 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.h
+++ b/drivers/media/platform/exynos4-is/fimc-is-regs.h
@@ -145,7 +145,6 @@ void fimc_is_fw_clear_irq2(struct fimc_is *is);
145int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num); 145int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num);
146 146
147void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is); 147void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is);
148int fimc_is_hw_wait_intsr0_intsd0(struct fimc_is *is);
149int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is); 148int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is);
150void fimc_is_hw_set_sensor_num(struct fimc_is *is); 149void fimc_is_hw_set_sensor_num(struct fimc_is *is);
151void fimc_is_hw_stream_on(struct fimc_is *is); 150void fimc_is_hw_stream_on(struct fimc_is *is);
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 9770fa98d6a1..13a4228952e3 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -781,6 +781,9 @@ static int fimc_is_debugfs_create(struct fimc_is *is)
781 return is->debugfs_entry == NULL ? -EIO : 0; 781 return is->debugfs_entry == NULL ? -EIO : 0;
782} 782}
783 783
784static int fimc_is_runtime_resume(struct device *dev);
785static int fimc_is_runtime_suspend(struct device *dev);
786
784static int fimc_is_probe(struct platform_device *pdev) 787static int fimc_is_probe(struct platform_device *pdev)
785{ 788{
786 struct device *dev = &pdev->dev; 789 struct device *dev = &pdev->dev;
@@ -835,14 +838,20 @@ static int fimc_is_probe(struct platform_device *pdev)
835 } 838 }
836 pm_runtime_enable(dev); 839 pm_runtime_enable(dev);
837 840
841 if (!pm_runtime_enabled(dev)) {
842 ret = fimc_is_runtime_resume(dev);
843 if (ret < 0)
844 goto err_irq;
845 }
846
838 ret = pm_runtime_get_sync(dev); 847 ret = pm_runtime_get_sync(dev);
839 if (ret < 0) 848 if (ret < 0)
840 goto err_irq; 849 goto err_pm;
841 850
842 is->alloc_ctx = vb2_dma_contig_init_ctx(dev); 851 is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
843 if (IS_ERR(is->alloc_ctx)) { 852 if (IS_ERR(is->alloc_ctx)) {
844 ret = PTR_ERR(is->alloc_ctx); 853 ret = PTR_ERR(is->alloc_ctx);
845 goto err_irq; 854 goto err_pm;
846 } 855 }
847 /* 856 /*
848 * Register FIMC-IS V4L2 subdevs to this driver. The video nodes 857 * Register FIMC-IS V4L2 subdevs to this driver. The video nodes
@@ -867,10 +876,13 @@ static int fimc_is_probe(struct platform_device *pdev)
867 876
868err_dfs: 877err_dfs:
869 fimc_is_debugfs_remove(is); 878 fimc_is_debugfs_remove(is);
870err_vb:
871 vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
872err_sd: 879err_sd:
873 fimc_is_unregister_subdevs(is); 880 fimc_is_unregister_subdevs(is);
881err_vb:
882 vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
883err_pm:
884 if (!pm_runtime_enabled(dev))
885 fimc_is_runtime_suspend(dev);
874err_irq: 886err_irq:
875 free_irq(is->irq, is); 887 free_irq(is->irq, is);
876err_clk: 888err_clk:
@@ -919,10 +931,13 @@ static int fimc_is_suspend(struct device *dev)
919 931
920static int fimc_is_remove(struct platform_device *pdev) 932static int fimc_is_remove(struct platform_device *pdev)
921{ 933{
922 struct fimc_is *is = platform_get_drvdata(pdev); 934 struct device *dev = &pdev->dev;
935 struct fimc_is *is = dev_get_drvdata(dev);
923 936
924 pm_runtime_disable(&pdev->dev); 937 pm_runtime_disable(dev);
925 pm_runtime_set_suspended(&pdev->dev); 938 pm_runtime_set_suspended(dev);
939 if (!pm_runtime_status_suspended(dev))
940 fimc_is_runtime_suspend(dev);
926 free_irq(is->irq, is); 941 free_irq(is->irq, is);
927 fimc_is_unregister_subdevs(is); 942 fimc_is_unregister_subdevs(is);
928 vb2_dma_contig_cleanup_ctx(is->alloc_ctx); 943 vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
index 72a343e3b5e8..d0dc7ee04452 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
@@ -133,7 +133,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
133 int i = ARRAY_SIZE(src_pixfmt_map); 133 int i = ARRAY_SIZE(src_pixfmt_map);
134 u32 cfg; 134 u32 cfg;
135 135
136 while (--i >= 0) { 136 while (--i) {
137 if (src_pixfmt_map[i][0] == pixelcode) 137 if (src_pixfmt_map[i][0] == pixelcode)
138 break; 138 break;
139 } 139 }
@@ -240,7 +240,7 @@ static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
240 u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT); 240 u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
241 int i = ARRAY_SIZE(pixcode); 241 int i = ARRAY_SIZE(pixcode);
242 242
243 while (--i >= 0) 243 while (--i)
244 if (pixcode[i][0] == f->fmt->mbus_code) 244 if (pixcode[i][0] == f->fmt->mbus_code)
245 break; 245 break;
246 cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK; 246 cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK;
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index e5798f70d149..1234734bccf4 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -546,7 +546,7 @@ static int fimc_lite_release(struct file *file)
546 mutex_unlock(&entity->parent->graph_mutex); 546 mutex_unlock(&entity->parent->graph_mutex);
547 } 547 }
548 548
549 vb2_fop_release(file); 549 _vb2_fop_release(file, NULL);
550 pm_runtime_put(&fimc->pdev->dev); 550 pm_runtime_put(&fimc->pdev->dev);
551 clear_bit(ST_FLITE_SUSPENDED, &fimc->state); 551 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
552 552
@@ -1549,38 +1549,40 @@ static int fimc_lite_probe(struct platform_device *pdev)
1549 0, dev_name(dev), fimc); 1549 0, dev_name(dev), fimc);
1550 if (ret) { 1550 if (ret) {
1551 dev_err(dev, "Failed to install irq (%d)\n", ret); 1551 dev_err(dev, "Failed to install irq (%d)\n", ret);
1552 goto err_clk; 1552 goto err_clk_put;
1553 } 1553 }
1554 1554
1555 /* The video node will be created within the subdev's registered() op */ 1555 /* The video node will be created within the subdev's registered() op */
1556 ret = fimc_lite_create_capture_subdev(fimc); 1556 ret = fimc_lite_create_capture_subdev(fimc);
1557 if (ret) 1557 if (ret)
1558 goto err_clk; 1558 goto err_clk_put;
1559 1559
1560 platform_set_drvdata(pdev, fimc); 1560 platform_set_drvdata(pdev, fimc);
1561 pm_runtime_enable(dev); 1561 pm_runtime_enable(dev);
1562 ret = pm_runtime_get_sync(dev); 1562
1563 if (ret < 0) 1563 if (!pm_runtime_enabled(dev)) {
1564 goto err_sd; 1564 ret = clk_enable(fimc->clock);
1565 if (ret < 0)
1566 goto err_clk_put;
1567 }
1565 1568
1566 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); 1569 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
1567 if (IS_ERR(fimc->alloc_ctx)) { 1570 if (IS_ERR(fimc->alloc_ctx)) {
1568 ret = PTR_ERR(fimc->alloc_ctx); 1571 ret = PTR_ERR(fimc->alloc_ctx);
1569 goto err_pm; 1572 goto err_clk_dis;
1570 } 1573 }
1571 1574
1572 pm_runtime_put(dev);
1573
1574 fimc_lite_set_default_config(fimc); 1575 fimc_lite_set_default_config(fimc);
1575 1576
1576 dev_dbg(dev, "FIMC-LITE.%d registered successfully\n", 1577 dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
1577 fimc->index); 1578 fimc->index);
1578 return 0; 1579 return 0;
1579err_pm: 1580
1580 pm_runtime_put(dev); 1581err_clk_dis:
1582 clk_disable(fimc->clock);
1581err_sd: 1583err_sd:
1582 fimc_lite_unregister_capture_subdev(fimc); 1584 fimc_lite_unregister_capture_subdev(fimc);
1583err_clk: 1585err_clk_put:
1584 fimc_lite_clk_put(fimc); 1586 fimc_lite_clk_put(fimc);
1585 return ret; 1587 return ret;
1586} 1588}
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 8d33b68c76ba..9da95bd14820 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -44,17 +44,17 @@ void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
44{ 44{
45 struct vb2_buffer *src_vb, *dst_vb; 45 struct vb2_buffer *src_vb, *dst_vb;
46 46
47 if (!ctx || !ctx->m2m_ctx) 47 if (!ctx || !ctx->fh.m2m_ctx)
48 return; 48 return;
49 49
50 src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 50 src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
51 dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 51 dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
52 52
53 if (src_vb && dst_vb) { 53 if (src_vb && dst_vb) {
54 v4l2_m2m_buf_done(src_vb, vb_state); 54 v4l2_m2m_buf_done(src_vb, vb_state);
55 v4l2_m2m_buf_done(dst_vb, vb_state); 55 v4l2_m2m_buf_done(dst_vb, vb_state);
56 v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev, 56 v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
57 ctx->m2m_ctx); 57 ctx->fh.m2m_ctx);
58 } 58 }
59} 59}
60 60
@@ -123,12 +123,12 @@ static void fimc_device_run(void *priv)
123 fimc_prepare_dma_offset(ctx, df); 123 fimc_prepare_dma_offset(ctx, df);
124 } 124 }
125 125
126 src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 126 src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
127 ret = fimc_prepare_addr(ctx, src_vb, sf, &sf->paddr); 127 ret = fimc_prepare_addr(ctx, src_vb, sf, &sf->paddr);
128 if (ret) 128 if (ret)
129 goto dma_unlock; 129 goto dma_unlock;
130 130
131 dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 131 dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
132 ret = fimc_prepare_addr(ctx, dst_vb, df, &df->paddr); 132 ret = fimc_prepare_addr(ctx, dst_vb, df, &df->paddr);
133 if (ret) 133 if (ret)
134 goto dma_unlock; 134 goto dma_unlock;
@@ -219,31 +219,15 @@ static int fimc_buf_prepare(struct vb2_buffer *vb)
219static void fimc_buf_queue(struct vb2_buffer *vb) 219static void fimc_buf_queue(struct vb2_buffer *vb)
220{ 220{
221 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 221 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
222 222 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
223 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
224
225 if (ctx->m2m_ctx)
226 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
227}
228
229static void fimc_lock(struct vb2_queue *vq)
230{
231 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
232 mutex_lock(&ctx->fimc_dev->lock);
233}
234
235static void fimc_unlock(struct vb2_queue *vq)
236{
237 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
238 mutex_unlock(&ctx->fimc_dev->lock);
239} 223}
240 224
241static struct vb2_ops fimc_qops = { 225static struct vb2_ops fimc_qops = {
242 .queue_setup = fimc_queue_setup, 226 .queue_setup = fimc_queue_setup,
243 .buf_prepare = fimc_buf_prepare, 227 .buf_prepare = fimc_buf_prepare,
244 .buf_queue = fimc_buf_queue, 228 .buf_queue = fimc_buf_queue,
245 .wait_prepare = fimc_unlock, 229 .wait_prepare = vb2_ops_wait_prepare,
246 .wait_finish = fimc_lock, 230 .wait_finish = vb2_ops_wait_finish,
247 .stop_streaming = stop_streaming, 231 .stop_streaming = stop_streaming,
248 .start_streaming = start_streaming, 232 .start_streaming = start_streaming,
249}; 233};
@@ -385,7 +369,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
385 if (ret) 369 if (ret)
386 return ret; 370 return ret;
387 371
388 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 372 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
389 373
390 if (vb2_is_busy(vq)) { 374 if (vb2_is_busy(vq)) {
391 v4l2_err(&fimc->m2m.vfd, "queue (%d) busy\n", f->type); 375 v4l2_err(&fimc->m2m.vfd, "queue (%d) busy\n", f->type);
@@ -410,56 +394,6 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
410 return 0; 394 return 0;
411} 395}
412 396
413static int fimc_m2m_reqbufs(struct file *file, void *fh,
414 struct v4l2_requestbuffers *reqbufs)
415{
416 struct fimc_ctx *ctx = fh_to_ctx(fh);
417 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
418}
419
420static int fimc_m2m_querybuf(struct file *file, void *fh,
421 struct v4l2_buffer *buf)
422{
423 struct fimc_ctx *ctx = fh_to_ctx(fh);
424 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
425}
426
427static int fimc_m2m_qbuf(struct file *file, void *fh,
428 struct v4l2_buffer *buf)
429{
430 struct fimc_ctx *ctx = fh_to_ctx(fh);
431 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
432}
433
434static int fimc_m2m_dqbuf(struct file *file, void *fh,
435 struct v4l2_buffer *buf)
436{
437 struct fimc_ctx *ctx = fh_to_ctx(fh);
438 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
439}
440
441static int fimc_m2m_expbuf(struct file *file, void *fh,
442 struct v4l2_exportbuffer *eb)
443{
444 struct fimc_ctx *ctx = fh_to_ctx(fh);
445 return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
446}
447
448
449static int fimc_m2m_streamon(struct file *file, void *fh,
450 enum v4l2_buf_type type)
451{
452 struct fimc_ctx *ctx = fh_to_ctx(fh);
453 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
454}
455
456static int fimc_m2m_streamoff(struct file *file, void *fh,
457 enum v4l2_buf_type type)
458{
459 struct fimc_ctx *ctx = fh_to_ctx(fh);
460 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
461}
462
463static int fimc_m2m_cropcap(struct file *file, void *fh, 397static int fimc_m2m_cropcap(struct file *file, void *fh,
464 struct v4l2_cropcap *cr) 398 struct v4l2_cropcap *cr)
465{ 399{
@@ -598,13 +532,13 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
598 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane, 532 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
599 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane, 533 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
600 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane, 534 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
601 .vidioc_reqbufs = fimc_m2m_reqbufs, 535 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
602 .vidioc_querybuf = fimc_m2m_querybuf, 536 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
603 .vidioc_qbuf = fimc_m2m_qbuf, 537 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
604 .vidioc_dqbuf = fimc_m2m_dqbuf, 538 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
605 .vidioc_expbuf = fimc_m2m_expbuf, 539 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
606 .vidioc_streamon = fimc_m2m_streamon, 540 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
607 .vidioc_streamoff = fimc_m2m_streamoff, 541 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
608 .vidioc_g_crop = fimc_m2m_g_crop, 542 .vidioc_g_crop = fimc_m2m_g_crop,
609 .vidioc_s_crop = fimc_m2m_s_crop, 543 .vidioc_s_crop = fimc_m2m_s_crop,
610 .vidioc_cropcap = fimc_m2m_cropcap 544 .vidioc_cropcap = fimc_m2m_cropcap
@@ -624,6 +558,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
624 src_vq->mem_ops = &vb2_dma_contig_memops; 558 src_vq->mem_ops = &vb2_dma_contig_memops;
625 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 559 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
626 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 560 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
561 src_vq->lock = &ctx->fimc_dev->lock;
627 562
628 ret = vb2_queue_init(src_vq); 563 ret = vb2_queue_init(src_vq);
629 if (ret) 564 if (ret)
@@ -636,6 +571,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
636 dst_vq->mem_ops = &vb2_dma_contig_memops; 571 dst_vq->mem_ops = &vb2_dma_contig_memops;
637 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 572 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
638 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 573 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
574 dst_vq->lock = &ctx->fimc_dev->lock;
639 575
640 return vb2_queue_init(dst_vq); 576 return vb2_queue_init(dst_vq);
641} 577}
@@ -708,9 +644,9 @@ static int fimc_m2m_open(struct file *file)
708 ctx->out_path = FIMC_IO_DMA; 644 ctx->out_path = FIMC_IO_DMA;
709 ctx->scaler.enabled = 1; 645 ctx->scaler.enabled = 1;
710 646
711 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); 647 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
712 if (IS_ERR(ctx->m2m_ctx)) { 648 if (IS_ERR(ctx->fh.m2m_ctx)) {
713 ret = PTR_ERR(ctx->m2m_ctx); 649 ret = PTR_ERR(ctx->fh.m2m_ctx);
714 goto error_c; 650 goto error_c;
715 } 651 }
716 652
@@ -725,7 +661,7 @@ static int fimc_m2m_open(struct file *file)
725 return 0; 661 return 0;
726 662
727error_m2m_ctx: 663error_m2m_ctx:
728 v4l2_m2m_ctx_release(ctx->m2m_ctx); 664 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
729error_c: 665error_c:
730 fimc_ctrls_delete(ctx); 666 fimc_ctrls_delete(ctx);
731error_fh: 667error_fh:
@@ -747,7 +683,7 @@ static int fimc_m2m_release(struct file *file)
747 683
748 mutex_lock(&fimc->lock); 684 mutex_lock(&fimc->lock);
749 685
750 v4l2_m2m_ctx_release(ctx->m2m_ctx); 686 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
751 fimc_ctrls_delete(ctx); 687 fimc_ctrls_delete(ctx);
752 v4l2_fh_del(&ctx->fh); 688 v4l2_fh_del(&ctx->fh);
753 v4l2_fh_exit(&ctx->fh); 689 v4l2_fh_exit(&ctx->fh);
@@ -760,45 +696,13 @@ static int fimc_m2m_release(struct file *file)
760 return 0; 696 return 0;
761} 697}
762 698
763static unsigned int fimc_m2m_poll(struct file *file,
764 struct poll_table_struct *wait)
765{
766 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
767 struct fimc_dev *fimc = ctx->fimc_dev;
768 int ret;
769
770 if (mutex_lock_interruptible(&fimc->lock))
771 return -ERESTARTSYS;
772
773 ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
774 mutex_unlock(&fimc->lock);
775
776 return ret;
777}
778
779
780static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
781{
782 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
783 struct fimc_dev *fimc = ctx->fimc_dev;
784 int ret;
785
786 if (mutex_lock_interruptible(&fimc->lock))
787 return -ERESTARTSYS;
788
789 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
790 mutex_unlock(&fimc->lock);
791
792 return ret;
793}
794
795static const struct v4l2_file_operations fimc_m2m_fops = { 699static const struct v4l2_file_operations fimc_m2m_fops = {
796 .owner = THIS_MODULE, 700 .owner = THIS_MODULE,
797 .open = fimc_m2m_open, 701 .open = fimc_m2m_open,
798 .release = fimc_m2m_release, 702 .release = fimc_m2m_release,
799 .poll = fimc_m2m_poll, 703 .poll = v4l2_m2m_fop_poll,
800 .unlocked_ioctl = video_ioctl2, 704 .unlocked_ioctl = video_ioctl2,
801 .mmap = fimc_m2m_mmap, 705 .mmap = v4l2_m2m_fop_mmap,
802}; 706};
803 707
804static struct v4l2_m2m_ops m2m_ops = { 708static struct v4l2_m2m_ops m2m_ops = {
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 9fc2af6a0446..f3c3591fdc5d 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -91,7 +91,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
91#define S5PCSIS_INTSRC_ODD_BEFORE (1 << 29) 91#define S5PCSIS_INTSRC_ODD_BEFORE (1 << 29)
92#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28) 92#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28)
93#define S5PCSIS_INTSRC_ODD (0x3 << 28) 93#define S5PCSIS_INTSRC_ODD (0x3 << 28)
94#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28) 94#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xf << 28)
95#define S5PCSIS_INTSRC_FRAME_START (1 << 27) 95#define S5PCSIS_INTSRC_FRAME_START (1 << 27)
96#define S5PCSIS_INTSRC_FRAME_END (1 << 26) 96#define S5PCSIS_INTSRC_FRAME_END (1 << 26)
97#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12) 97#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12)
@@ -790,6 +790,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
790#define s5pcsis_parse_dt(pdev, state) (-ENOSYS) 790#define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
791#endif 791#endif
792 792
793static int s5pcsis_pm_resume(struct device *dev, bool runtime);
793static const struct of_device_id s5pcsis_of_match[]; 794static const struct of_device_id s5pcsis_of_match[];
794 795
795static int s5pcsis_probe(struct platform_device *pdev) 796static int s5pcsis_probe(struct platform_device *pdev)
@@ -902,13 +903,21 @@ static int s5pcsis_probe(struct platform_device *pdev)
902 /* .. and a pointer to the subdev. */ 903 /* .. and a pointer to the subdev. */
903 platform_set_drvdata(pdev, &state->sd); 904 platform_set_drvdata(pdev, &state->sd);
904 memcpy(state->events, s5pcsis_events, sizeof(state->events)); 905 memcpy(state->events, s5pcsis_events, sizeof(state->events));
906
905 pm_runtime_enable(dev); 907 pm_runtime_enable(dev);
908 if (!pm_runtime_enabled(dev)) {
909 ret = s5pcsis_pm_resume(dev, true);
910 if (ret < 0)
911 goto e_m_ent;
912 }
906 913
907 dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n", 914 dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n",
908 state->num_lanes, state->hs_settle, state->wclk_ext, 915 state->num_lanes, state->hs_settle, state->wclk_ext,
909 state->clk_frequency); 916 state->clk_frequency);
910 return 0; 917 return 0;
911 918
919e_m_ent:
920 media_entity_cleanup(&state->sd.entity);
912e_clkdis: 921e_clkdis:
913 clk_disable(state->clock[CSIS_CLK_MUX]); 922 clk_disable(state->clock[CSIS_CLK_MUX]);
914e_clkput: 923e_clkput:
@@ -1014,7 +1023,7 @@ static int s5pcsis_remove(struct platform_device *pdev)
1014 struct csis_state *state = sd_to_csis_state(sd); 1023 struct csis_state *state = sd_to_csis_state(sd);
1015 1024
1016 pm_runtime_disable(&pdev->dev); 1025 pm_runtime_disable(&pdev->dev);
1017 s5pcsis_pm_suspend(&pdev->dev, false); 1026 s5pcsis_pm_suspend(&pdev->dev, true);
1018 clk_disable(state->clock[CSIS_CLK_MUX]); 1027 clk_disable(state->clock[CSIS_CLK_MUX]);
1019 pm_runtime_set_suspended(&pdev->dev); 1028 pm_runtime_set_suspended(&pdev->dev);
1020 s5pcsis_clk_put(state); 1029 s5pcsis_clk_put(state);
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 65cab70fefcb..6bb86b581a34 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -918,7 +918,7 @@ static int deinterlace_open(struct file *file)
918 return ret; 918 return ret;
919 } 919 }
920 920
921 ctx->xt = kzalloc(sizeof(struct dma_async_tx_descriptor) + 921 ctx->xt = kzalloc(sizeof(struct dma_interleaved_template) +
922 sizeof(struct data_chunk), GFP_KERNEL); 922 sizeof(struct data_chunk), GFP_KERNEL);
923 if (!ctx->xt) { 923 if (!ctx->xt) {
924 kfree(ctx); 924 kfree(ctx);
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c
index 8df5975b700a..08e24379b794 100644
--- a/drivers/media/platform/mem2mem_testdev.c
+++ b/drivers/media/platform/mem2mem_testdev.c
@@ -177,8 +177,6 @@ struct m2mtest_ctx {
177 177
178 enum v4l2_colorspace colorspace; 178 enum v4l2_colorspace colorspace;
179 179
180 struct v4l2_m2m_ctx *m2m_ctx;
181
182 /* Source and destination queue data */ 180 /* Source and destination queue data */
183 struct m2mtest_q_data q_data[2]; 181 struct m2mtest_q_data q_data[2];
184}; 182};
@@ -342,8 +340,8 @@ static int job_ready(void *priv)
342{ 340{
343 struct m2mtest_ctx *ctx = priv; 341 struct m2mtest_ctx *ctx = priv;
344 342
345 if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) < ctx->translen 343 if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen
346 || v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < ctx->translen) { 344 || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen) {
347 dprintk(ctx->dev, "Not enough buffers available\n"); 345 dprintk(ctx->dev, "Not enough buffers available\n");
348 return 0; 346 return 0;
349 } 347 }
@@ -359,21 +357,6 @@ static void job_abort(void *priv)
359 ctx->aborting = 1; 357 ctx->aborting = 1;
360} 358}
361 359
362static void m2mtest_lock(void *priv)
363{
364 struct m2mtest_ctx *ctx = priv;
365 struct m2mtest_dev *dev = ctx->dev;
366 mutex_lock(&dev->dev_mutex);
367}
368
369static void m2mtest_unlock(void *priv)
370{
371 struct m2mtest_ctx *ctx = priv;
372 struct m2mtest_dev *dev = ctx->dev;
373 mutex_unlock(&dev->dev_mutex);
374}
375
376
377/* device_run() - prepares and starts the device 360/* device_run() - prepares and starts the device
378 * 361 *
379 * This simulates all the immediate preparations required before starting 362 * This simulates all the immediate preparations required before starting
@@ -386,8 +369,8 @@ static void device_run(void *priv)
386 struct m2mtest_dev *dev = ctx->dev; 369 struct m2mtest_dev *dev = ctx->dev;
387 struct vb2_buffer *src_buf, *dst_buf; 370 struct vb2_buffer *src_buf, *dst_buf;
388 371
389 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 372 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
390 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 373 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
391 374
392 device_process(ctx, src_buf, dst_buf); 375 device_process(ctx, src_buf, dst_buf);
393 376
@@ -409,8 +392,8 @@ static void device_isr(unsigned long priv)
409 return; 392 return;
410 } 393 }
411 394
412 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); 395 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
413 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); 396 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
414 397
415 curr_ctx->num_processed++; 398 curr_ctx->num_processed++;
416 399
@@ -423,7 +406,7 @@ static void device_isr(unsigned long priv)
423 || curr_ctx->aborting) { 406 || curr_ctx->aborting) {
424 dprintk(curr_ctx->dev, "Finishing transaction\n"); 407 dprintk(curr_ctx->dev, "Finishing transaction\n");
425 curr_ctx->num_processed = 0; 408 curr_ctx->num_processed = 0;
426 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx); 409 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->fh.m2m_ctx);
427 } else { 410 } else {
428 device_run(curr_ctx); 411 device_run(curr_ctx);
429 } 412 }
@@ -491,7 +474,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
491 struct vb2_queue *vq; 474 struct vb2_queue *vq;
492 struct m2mtest_q_data *q_data; 475 struct m2mtest_q_data *q_data;
493 476
494 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 477 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
495 if (!vq) 478 if (!vq)
496 return -EINVAL; 479 return -EINVAL;
497 480
@@ -594,7 +577,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
594 struct m2mtest_q_data *q_data; 577 struct m2mtest_q_data *q_data;
595 struct vb2_queue *vq; 578 struct vb2_queue *vq;
596 579
597 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 580 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
598 if (!vq) 581 if (!vq)
599 return -EINVAL; 582 return -EINVAL;
600 583
@@ -648,52 +631,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
648 return ret; 631 return ret;
649} 632}
650 633
651static int vidioc_reqbufs(struct file *file, void *priv,
652 struct v4l2_requestbuffers *reqbufs)
653{
654 struct m2mtest_ctx *ctx = file2ctx(file);
655
656 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
657}
658
659static int vidioc_querybuf(struct file *file, void *priv,
660 struct v4l2_buffer *buf)
661{
662 struct m2mtest_ctx *ctx = file2ctx(file);
663
664 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
665}
666
667static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
668{
669 struct m2mtest_ctx *ctx = file2ctx(file);
670
671 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
672}
673
674static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
675{
676 struct m2mtest_ctx *ctx = file2ctx(file);
677
678 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
679}
680
681static int vidioc_streamon(struct file *file, void *priv,
682 enum v4l2_buf_type type)
683{
684 struct m2mtest_ctx *ctx = file2ctx(file);
685
686 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
687}
688
689static int vidioc_streamoff(struct file *file, void *priv,
690 enum v4l2_buf_type type)
691{
692 struct m2mtest_ctx *ctx = file2ctx(file);
693
694 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
695}
696
697static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl) 634static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl)
698{ 635{
699 struct m2mtest_ctx *ctx = 636 struct m2mtest_ctx *ctx =
@@ -748,14 +685,14 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
748 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, 685 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
749 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, 686 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
750 687
751 .vidioc_reqbufs = vidioc_reqbufs, 688 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
752 .vidioc_querybuf = vidioc_querybuf, 689 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
690 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
691 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
753 692
754 .vidioc_qbuf = vidioc_qbuf, 693 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
755 .vidioc_dqbuf = vidioc_dqbuf, 694 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
756 695
757 .vidioc_streamon = vidioc_streamon,
758 .vidioc_streamoff = vidioc_streamoff,
759 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 696 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
760 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 697 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
761}; 698};
@@ -818,27 +755,15 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb)
818static void m2mtest_buf_queue(struct vb2_buffer *vb) 755static void m2mtest_buf_queue(struct vb2_buffer *vb)
819{ 756{
820 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 757 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
821 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); 758 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
822}
823
824static void m2mtest_wait_prepare(struct vb2_queue *q)
825{
826 struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
827 m2mtest_unlock(ctx);
828}
829
830static void m2mtest_wait_finish(struct vb2_queue *q)
831{
832 struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
833 m2mtest_lock(ctx);
834} 759}
835 760
836static struct vb2_ops m2mtest_qops = { 761static struct vb2_ops m2mtest_qops = {
837 .queue_setup = m2mtest_queue_setup, 762 .queue_setup = m2mtest_queue_setup,
838 .buf_prepare = m2mtest_buf_prepare, 763 .buf_prepare = m2mtest_buf_prepare,
839 .buf_queue = m2mtest_buf_queue, 764 .buf_queue = m2mtest_buf_queue,
840 .wait_prepare = m2mtest_wait_prepare, 765 .wait_prepare = vb2_ops_wait_prepare,
841 .wait_finish = m2mtest_wait_finish, 766 .wait_finish = vb2_ops_wait_finish,
842}; 767};
843 768
844static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) 769static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
@@ -853,6 +778,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
853 src_vq->ops = &m2mtest_qops; 778 src_vq->ops = &m2mtest_qops;
854 src_vq->mem_ops = &vb2_vmalloc_memops; 779 src_vq->mem_ops = &vb2_vmalloc_memops;
855 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 780 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
781 src_vq->lock = &ctx->dev->dev_mutex;
856 782
857 ret = vb2_queue_init(src_vq); 783 ret = vb2_queue_init(src_vq);
858 if (ret) 784 if (ret)
@@ -865,6 +791,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
865 dst_vq->ops = &m2mtest_qops; 791 dst_vq->ops = &m2mtest_qops;
866 dst_vq->mem_ops = &vb2_vmalloc_memops; 792 dst_vq->mem_ops = &vb2_vmalloc_memops;
867 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 793 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
794 dst_vq->lock = &ctx->dev->dev_mutex;
868 795
869 return vb2_queue_init(dst_vq); 796 return vb2_queue_init(dst_vq);
870} 797}
@@ -936,10 +863,10 @@ static int m2mtest_open(struct file *file)
936 ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC]; 863 ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
937 ctx->colorspace = V4L2_COLORSPACE_REC709; 864 ctx->colorspace = V4L2_COLORSPACE_REC709;
938 865
939 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); 866 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
940 867
941 if (IS_ERR(ctx->m2m_ctx)) { 868 if (IS_ERR(ctx->fh.m2m_ctx)) {
942 rc = PTR_ERR(ctx->m2m_ctx); 869 rc = PTR_ERR(ctx->fh.m2m_ctx);
943 870
944 v4l2_ctrl_handler_free(hdl); 871 v4l2_ctrl_handler_free(hdl);
945 kfree(ctx); 872 kfree(ctx);
@@ -949,7 +876,8 @@ static int m2mtest_open(struct file *file)
949 v4l2_fh_add(&ctx->fh); 876 v4l2_fh_add(&ctx->fh);
950 atomic_inc(&dev->num_inst); 877 atomic_inc(&dev->num_inst);
951 878
952 dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx); 879 dprintk(dev, "Created instance: %p, m2m_ctx: %p\n",
880 ctx, ctx->fh.m2m_ctx);
953 881
954open_unlock: 882open_unlock:
955 mutex_unlock(&dev->dev_mutex); 883 mutex_unlock(&dev->dev_mutex);
@@ -967,7 +895,7 @@ static int m2mtest_release(struct file *file)
967 v4l2_fh_exit(&ctx->fh); 895 v4l2_fh_exit(&ctx->fh);
968 v4l2_ctrl_handler_free(&ctx->hdl); 896 v4l2_ctrl_handler_free(&ctx->hdl);
969 mutex_lock(&dev->dev_mutex); 897 mutex_lock(&dev->dev_mutex);
970 v4l2_m2m_ctx_release(ctx->m2m_ctx); 898 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
971 mutex_unlock(&dev->dev_mutex); 899 mutex_unlock(&dev->dev_mutex);
972 kfree(ctx); 900 kfree(ctx);
973 901
@@ -976,34 +904,13 @@ static int m2mtest_release(struct file *file)
976 return 0; 904 return 0;
977} 905}
978 906
979static unsigned int m2mtest_poll(struct file *file,
980 struct poll_table_struct *wait)
981{
982 struct m2mtest_ctx *ctx = file2ctx(file);
983
984 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
985}
986
987static int m2mtest_mmap(struct file *file, struct vm_area_struct *vma)
988{
989 struct m2mtest_dev *dev = video_drvdata(file);
990 struct m2mtest_ctx *ctx = file2ctx(file);
991 int res;
992
993 if (mutex_lock_interruptible(&dev->dev_mutex))
994 return -ERESTARTSYS;
995 res = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
996 mutex_unlock(&dev->dev_mutex);
997 return res;
998}
999
1000static const struct v4l2_file_operations m2mtest_fops = { 907static const struct v4l2_file_operations m2mtest_fops = {
1001 .owner = THIS_MODULE, 908 .owner = THIS_MODULE,
1002 .open = m2mtest_open, 909 .open = m2mtest_open,
1003 .release = m2mtest_release, 910 .release = m2mtest_release,
1004 .poll = m2mtest_poll, 911 .poll = v4l2_m2m_fop_poll,
1005 .unlocked_ioctl = video_ioctl2, 912 .unlocked_ioctl = video_ioctl2,
1006 .mmap = m2mtest_mmap, 913 .mmap = v4l2_m2m_fop_mmap,
1007}; 914};
1008 915
1009static struct video_device m2mtest_videodev = { 916static struct video_device m2mtest_videodev = {
@@ -1019,8 +926,6 @@ static struct v4l2_m2m_ops m2m_ops = {
1019 .device_run = device_run, 926 .device_run = device_run,
1020 .job_ready = job_ready, 927 .job_ready = job_ready,
1021 .job_abort = job_abort, 928 .job_abort = job_abort,
1022 .lock = m2mtest_lock,
1023 .unlock = m2mtest_unlock,
1024}; 929};
1025 930
1026static int m2mtest_probe(struct platform_device *pdev) 931static int m2mtest_probe(struct platform_device *pdev)
@@ -1133,4 +1038,3 @@ static int __init m2mtest_init(void)
1133 1038
1134module_init(m2mtest_init); 1039module_init(m2mtest_init);
1135module_exit(m2mtest_exit); 1040module_exit(m2mtest_exit);
1136
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index fdbdeae3900d..5807185262fe 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -873,15 +873,12 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
873 unsigned long flags; 873 unsigned long flags;
874 int ret; 874 int ret;
875 875
876 /* If the preview engine crashed it might not respond to read/write 876 /* Refuse to start streaming if an entity included in the pipeline has
877 * operations on the L4 bus. This would result in a bus fault and a 877 * crashed. This check must be performed before the loop below to avoid
878 * kernel oops. Refuse to start streaming in that case. This check must 878 * starting entities if the pipeline won't start anyway (those entities
879 * be performed before the loop below to avoid starting entities if the 879 * would then likely fail to stop, making the problem worse).
880 * pipeline won't start anyway (those entities would then likely fail to
881 * stop, making the problem worse).
882 */ 880 */
883 if ((pipe->entities & isp->crashed) & 881 if (pipe->entities & isp->crashed)
884 (1U << isp->isp_prev.subdev.entity.id))
885 return -EIO; 882 return -EIO;
886 883
887 spin_lock_irqsave(&pipe->lock, flags); 884 spin_lock_irqsave(&pipe->lock, flags);
@@ -1014,13 +1011,23 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
1014 else 1011 else
1015 ret = 0; 1012 ret = 0;
1016 1013
1014 /* Handle stop failures. An entity that fails to stop can
1015 * usually just be restarted. Flag the stop failure nonetheless
1016 * to trigger an ISP reset the next time the device is released,
1017 * just in case.
1018 *
1019 * The preview engine is a special case. A failure to stop can
1020 * mean a hardware crash. When that happens the preview engine
1021 * won't respond to read/write operations on the L4 bus anymore,
1022 * resulting in a bus fault and a kernel oops next time it gets
1023 * accessed. Mark it as crashed to prevent pipelines including
1024 * it from being started.
1025 */
1017 if (ret) { 1026 if (ret) {
1018 dev_info(isp->dev, "Unable to stop %s\n", subdev->name); 1027 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
1019 /* If the entity failed to stopped, assume it has 1028 isp->stop_failure = true;
1020 * crashed. Mark it as such, the ISP will be reset when 1029 if (subdev == &isp->isp_prev.subdev)
1021 * applications will release it. 1030 isp->crashed |= 1U << subdev->entity.id;
1022 */
1023 isp->crashed |= 1U << subdev->entity.id;
1024 failure = -ETIMEDOUT; 1031 failure = -ETIMEDOUT;
1025 } 1032 }
1026 } 1033 }
@@ -1057,6 +1064,23 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
1057} 1064}
1058 1065
1059/* 1066/*
1067 * omap3isp_pipeline_cancel_stream - Cancel stream on a pipeline
1068 * @pipe: ISP pipeline
1069 *
1070 * Cancelling a stream mark all buffers on all video nodes in the pipeline as
1071 * erroneous and makes sure no new buffer can be queued. This function is called
1072 * when a fatal error that prevents any further operation on the pipeline
1073 * occurs.
1074 */
1075void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe)
1076{
1077 if (pipe->input)
1078 omap3isp_video_cancel_stream(pipe->input);
1079 if (pipe->output)
1080 omap3isp_video_cancel_stream(pipe->output);
1081}
1082
1083/*
1060 * isp_pipeline_resume - Resume streaming on a pipeline 1084 * isp_pipeline_resume - Resume streaming on a pipeline
1061 * @pipe: ISP pipeline 1085 * @pipe: ISP pipeline
1062 * 1086 *
@@ -1208,6 +1232,7 @@ static int isp_reset(struct isp_device *isp)
1208 udelay(1); 1232 udelay(1);
1209 } 1233 }
1210 1234
1235 isp->stop_failure = false;
1211 isp->crashed = 0; 1236 isp->crashed = 0;
1212 return 0; 1237 return 0;
1213} 1238}
@@ -1619,7 +1644,7 @@ void omap3isp_put(struct isp_device *isp)
1619 /* Reset the ISP if an entity has failed to stop. This is the 1644 /* Reset the ISP if an entity has failed to stop. This is the
1620 * only way to recover from such conditions. 1645 * only way to recover from such conditions.
1621 */ 1646 */
1622 if (isp->crashed) 1647 if (isp->crashed || isp->stop_failure)
1623 isp_reset(isp); 1648 isp_reset(isp);
1624 isp_disable_clocks(isp); 1649 isp_disable_clocks(isp);
1625 } 1650 }
@@ -2130,28 +2155,13 @@ static int isp_map_mem_resource(struct platform_device *pdev,
2130 /* request the mem region for the camera registers */ 2155 /* request the mem region for the camera registers */
2131 2156
2132 mem = platform_get_resource(pdev, IORESOURCE_MEM, res); 2157 mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
2133 if (!mem) {
2134 dev_err(isp->dev, "no mem resource?\n");
2135 return -ENODEV;
2136 }
2137
2138 if (!devm_request_mem_region(isp->dev, mem->start, resource_size(mem),
2139 pdev->name)) {
2140 dev_err(isp->dev,
2141 "cannot reserve camera register I/O region\n");
2142 return -ENODEV;
2143 }
2144 isp->mmio_base_phys[res] = mem->start;
2145 isp->mmio_size[res] = resource_size(mem);
2146 2158
2147 /* map the region */ 2159 /* map the region */
2148 isp->mmio_base[res] = devm_ioremap_nocache(isp->dev, 2160 isp->mmio_base[res] = devm_ioremap_resource(isp->dev, mem);
2149 isp->mmio_base_phys[res], 2161 if (IS_ERR(isp->mmio_base[res]))
2150 isp->mmio_size[res]); 2162 return PTR_ERR(isp->mmio_base[res]);
2151 if (!isp->mmio_base[res]) { 2163
2152 dev_err(isp->dev, "cannot map camera register I/O region\n"); 2164 isp->mmio_base_phys[res] = mem->start;
2153 return -ENODEV;
2154 }
2155 2165
2156 return 0; 2166 return 0;
2157} 2167}
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index d1e857e41731..081f5ec5a663 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -152,9 +152,9 @@ struct isp_xclk {
152 * regions. 152 * regions.
153 * @mmio_base_phys: Array with physical L4 bus addresses for ISP register 153 * @mmio_base_phys: Array with physical L4 bus addresses for ISP register
154 * regions. 154 * regions.
155 * @mmio_size: Array with ISP register regions size in bytes.
156 * @stat_lock: Spinlock for handling statistics 155 * @stat_lock: Spinlock for handling statistics
157 * @isp_mutex: Mutex for serializing requests to ISP. 156 * @isp_mutex: Mutex for serializing requests to ISP.
157 * @stop_failure: Indicates that an entity failed to stop.
158 * @crashed: Bitmask of crashed entities (indexed by entity ID) 158 * @crashed: Bitmask of crashed entities (indexed by entity ID)
159 * @has_context: Context has been saved at least once and can be restored. 159 * @has_context: Context has been saved at least once and can be restored.
160 * @ref_count: Reference count for handling multiple ISP requests. 160 * @ref_count: Reference count for handling multiple ISP requests.
@@ -188,11 +188,11 @@ struct isp_device {
188 188
189 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST]; 189 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
190 unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST]; 190 unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
191 resource_size_t mmio_size[OMAP3_ISP_IOMEM_LAST];
192 191
193 /* ISP Obj */ 192 /* ISP Obj */
194 spinlock_t stat_lock; /* common lock for statistic drivers */ 193 spinlock_t stat_lock; /* common lock for statistic drivers */
195 struct mutex isp_mutex; /* For handling ref_count field */ 194 struct mutex isp_mutex; /* For handling ref_count field */
195 bool stop_failure;
196 u32 crashed; 196 u32 crashed;
197 int has_context; 197 int has_context;
198 int ref_count; 198 int ref_count;
@@ -238,6 +238,7 @@ int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
238 238
239int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, 239int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
240 enum isp_pipeline_stream_state state); 240 enum isp_pipeline_stream_state state);
241void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe);
241void omap3isp_configure_bridge(struct isp_device *isp, 242void omap3isp_configure_bridge(struct isp_device *isp,
242 enum ccdc_input_entity input, 243 enum ccdc_input_entity input,
243 const struct isp_parallel_platform_data *pdata, 244 const struct isp_parallel_platform_data *pdata,
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 907a205da5a5..5db2c88b9ad8 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -1516,6 +1516,8 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
1516 1516
1517 if (ccdc_sbl_wait_idle(ccdc, 1000)) { 1517 if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1518 dev_info(isp->dev, "CCDC won't become idle!\n"); 1518 dev_info(isp->dev, "CCDC won't become idle!\n");
1519 isp->crashed |= 1U << ccdc->subdev.entity.id;
1520 omap3isp_pipeline_cancel_stream(pipe);
1519 goto done; 1521 goto done;
1520 } 1522 }
1521 1523
@@ -2484,7 +2486,8 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2484 v4l2_set_subdevdata(sd, ccdc); 2486 v4l2_set_subdevdata(sd, ccdc);
2485 sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; 2487 sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
2486 2488
2487 pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 2489 pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK
2490 | MEDIA_PAD_FL_MUST_CONNECT;
2488 pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; 2491 pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
2489 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE; 2492 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
2490 2493
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e71651429dda..e84fe0543e47 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1076,7 +1076,8 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1076 v4l2_set_subdevdata(sd, ccp2); 1076 v4l2_set_subdevdata(sd, ccp2);
1077 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1077 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1078 1078
1079 pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1079 pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
1080 | MEDIA_PAD_FL_MUST_CONNECT;
1080 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1081 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1081 1082
1082 me->ops = &ccp2_media_ops; 1083 me->ops = &ccp2_media_ops;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6db245d84bbb..620560828a48 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1245,7 +1245,8 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
1245 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1245 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1246 1246
1247 pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1247 pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1248 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1248 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
1249 | MEDIA_PAD_FL_MUST_CONNECT;
1249 1250
1250 me->ops = &csi2_media_ops; 1251 me->ops = &csi2_media_ops;
1251 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0); 1252 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index cd8831aebdeb..1c776c1186f1 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2283,7 +2283,8 @@ static int preview_init_entities(struct isp_prev_device *prev)
2283 v4l2_ctrl_handler_setup(&prev->ctrls); 2283 v4l2_ctrl_handler_setup(&prev->ctrls);
2284 sd->ctrl_handler = &prev->ctrls; 2284 sd->ctrl_handler = &prev->ctrls;
2285 2285
2286 pads[PREV_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 2286 pads[PREV_PAD_SINK].flags = MEDIA_PAD_FL_SINK
2287 | MEDIA_PAD_FL_MUST_CONNECT;
2287 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 2288 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
2288 2289
2289 me->ops = &preview_media_ops; 2290 me->ops = &preview_media_ops;
diff --git a/drivers/media/platform/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index e15f01342058..5f0f8fab1d17 100644
--- a/drivers/media/platform/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -553,8 +553,10 @@ static void isp_video_buffer_query(struct isp_video_buffer *buf,
553 switch (buf->state) { 553 switch (buf->state) {
554 case ISP_BUF_STATE_ERROR: 554 case ISP_BUF_STATE_ERROR:
555 vbuf->flags |= V4L2_BUF_FLAG_ERROR; 555 vbuf->flags |= V4L2_BUF_FLAG_ERROR;
556 /* Fallthrough */
556 case ISP_BUF_STATE_DONE: 557 case ISP_BUF_STATE_DONE:
557 vbuf->flags |= V4L2_BUF_FLAG_DONE; 558 vbuf->flags |= V4L2_BUF_FLAG_DONE;
559 break;
558 case ISP_BUF_STATE_QUEUED: 560 case ISP_BUF_STATE_QUEUED:
559 case ISP_BUF_STATE_ACTIVE: 561 case ISP_BUF_STATE_ACTIVE:
560 vbuf->flags |= V4L2_BUF_FLAG_QUEUED; 562 vbuf->flags |= V4L2_BUF_FLAG_QUEUED;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index d11fb261d530..0d36b8bc9f98 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1532,6 +1532,20 @@ static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1532 return 0; 1532 return 0;
1533} 1533}
1534 1534
1535static int resizer_link_validate(struct v4l2_subdev *sd,
1536 struct media_link *link,
1537 struct v4l2_subdev_format *source_fmt,
1538 struct v4l2_subdev_format *sink_fmt)
1539{
1540 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1541 struct isp_pipeline *pipe = to_isp_pipeline(&sd->entity);
1542
1543 omap3isp_resizer_max_rate(res, &pipe->max_rate);
1544
1545 return v4l2_subdev_link_validate_default(sd, link,
1546 source_fmt, sink_fmt);
1547}
1548
1535/* 1549/*
1536 * resizer_init_formats - Initialize formats on all pads 1550 * resizer_init_formats - Initialize formats on all pads
1537 * @sd: ISP resizer V4L2 subdevice 1551 * @sd: ISP resizer V4L2 subdevice
@@ -1570,6 +1584,7 @@ static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
1570 .set_fmt = resizer_set_format, 1584 .set_fmt = resizer_set_format,
1571 .get_selection = resizer_get_selection, 1585 .get_selection = resizer_get_selection,
1572 .set_selection = resizer_set_selection, 1586 .set_selection = resizer_set_selection,
1587 .link_validate = resizer_link_validate,
1573}; 1588};
1574 1589
1575/* subdev operations */ 1590/* subdev operations */
@@ -1701,7 +1716,8 @@ static int resizer_init_entities(struct isp_res_device *res)
1701 v4l2_set_subdevdata(sd, res); 1716 v4l2_set_subdevdata(sd, res);
1702 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1717 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1703 1718
1704 pads[RESZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1719 pads[RESZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK
1720 | MEDIA_PAD_FL_MUST_CONNECT;
1705 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1721 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1706 1722
1707 me->ops = &resizer_media_ops; 1723 me->ops = &resizer_media_ops;
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 61e17f9bd8b9..a75407c3a726 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1067,7 +1067,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1067 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE; 1067 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1068 v4l2_set_subdevdata(subdev, stat); 1068 v4l2_set_subdevdata(subdev, stat);
1069 1069
1070 stat->pad.flags = MEDIA_PAD_FL_SINK; 1070 stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
1071 me->ops = NULL; 1071 me->ops = NULL;
1072 1072
1073 return media_entity_init(me, 1, &stat->pad, 0); 1073 return media_entity_init(me, 1, &stat->pad, 0);
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index f6304bb074f5..856fdf554035 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -278,55 +278,6 @@ static int isp_video_get_graph_data(struct isp_video *video,
278 return 0; 278 return 0;
279} 279}
280 280
281/*
282 * Validate a pipeline by checking both ends of all links for format
283 * discrepancies.
284 *
285 * Compute the minimum time per frame value as the maximum of time per frame
286 * limits reported by every block in the pipeline.
287 *
288 * Return 0 if all formats match, or -EPIPE if at least one link is found with
289 * different formats on its two ends or if the pipeline doesn't start with a
290 * video source (either a subdev with no input pad, or a non-subdev entity).
291 */
292static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
293{
294 struct isp_device *isp = pipe->output->isp;
295 struct media_pad *pad;
296 struct v4l2_subdev *subdev;
297
298 subdev = isp_video_remote_subdev(pipe->output, NULL);
299 if (subdev == NULL)
300 return -EPIPE;
301
302 while (1) {
303 /* Retrieve the sink format */
304 pad = &subdev->entity.pads[0];
305 if (!(pad->flags & MEDIA_PAD_FL_SINK))
306 break;
307
308 /* Update the maximum frame rate */
309 if (subdev == &isp->isp_res.subdev)
310 omap3isp_resizer_max_rate(&isp->isp_res,
311 &pipe->max_rate);
312
313 /* Retrieve the source format. Return an error if no source
314 * entity can be found, and stop checking the pipeline if the
315 * source entity isn't a subdev.
316 */
317 pad = media_entity_remote_pad(pad);
318 if (pad == NULL)
319 return -EPIPE;
320
321 if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
322 break;
323
324 subdev = media_entity_to_v4l2_subdev(pad->entity);
325 }
326
327 return 0;
328}
329
330static int 281static int
331__isp_video_get_format(struct isp_video *video, struct v4l2_format *format) 282__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
332{ 283{
@@ -460,6 +411,15 @@ static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
460 struct isp_video *video = vfh->video; 411 struct isp_video *video = vfh->video;
461 unsigned long addr; 412 unsigned long addr;
462 413
414 /* Refuse to prepare the buffer is the video node has registered an
415 * error. We don't need to take any lock here as the operation is
416 * inherently racy. The authoritative check will be performed in the
417 * queue handler, which can't return an error, this check is just a best
418 * effort to notify userspace as early as possible.
419 */
420 if (unlikely(video->error))
421 return -EIO;
422
463 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen); 423 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
464 if (IS_ERR_VALUE(addr)) 424 if (IS_ERR_VALUE(addr))
465 return -EIO; 425 return -EIO;
@@ -496,6 +456,12 @@ static void isp_video_buffer_queue(struct isp_video_buffer *buf)
496 unsigned int empty; 456 unsigned int empty;
497 unsigned int start; 457 unsigned int start;
498 458
459 if (unlikely(video->error)) {
460 buf->state = ISP_BUF_STATE_ERROR;
461 wake_up(&buf->wait);
462 return;
463 }
464
499 empty = list_empty(&video->dmaqueue); 465 empty = list_empty(&video->dmaqueue);
500 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue); 466 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
501 467
@@ -618,6 +584,36 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
618} 584}
619 585
620/* 586/*
587 * omap3isp_video_cancel_stream - Cancel stream on a video node
588 * @video: ISP video object
589 *
590 * Cancelling a stream mark all buffers on the video node as erroneous and makes
591 * sure no new buffer can be queued.
592 */
593void omap3isp_video_cancel_stream(struct isp_video *video)
594{
595 struct isp_video_queue *queue = video->queue;
596 unsigned long flags;
597
598 spin_lock_irqsave(&queue->irqlock, flags);
599
600 while (!list_empty(&video->dmaqueue)) {
601 struct isp_video_buffer *buf;
602
603 buf = list_first_entry(&video->dmaqueue,
604 struct isp_video_buffer, irqlist);
605 list_del(&buf->irqlist);
606
607 buf->state = ISP_BUF_STATE_ERROR;
608 wake_up(&buf->wait);
609 }
610
611 video->error = true;
612
613 spin_unlock_irqrestore(&queue->irqlock, flags);
614}
615
616/*
621 * omap3isp_video_resume - Perform resume operation on the buffers 617 * omap3isp_video_resume - Perform resume operation on the buffers
622 * @video: ISP video object 618 * @video: ISP video object
623 * @continuous: Pipeline is in single shot mode if 0 or continuous mode otherwise 619 * @continuous: Pipeline is in single shot mode if 0 or continuous mode otherwise
@@ -1051,11 +1047,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1051 if (ret < 0) 1047 if (ret < 0)
1052 goto err_check_format; 1048 goto err_check_format;
1053 1049
1054 /* Validate the pipeline and update its state. */
1055 ret = isp_video_validate_pipeline(pipe);
1056 if (ret < 0)
1057 goto err_check_format;
1058
1059 pipe->error = false; 1050 pipe->error = false;
1060 1051
1061 spin_lock_irqsave(&pipe->lock, flags); 1052 spin_lock_irqsave(&pipe->lock, flags);
@@ -1159,6 +1150,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1159 omap3isp_video_queue_streamoff(&vfh->queue); 1150 omap3isp_video_queue_streamoff(&vfh->queue);
1160 video->queue = NULL; 1151 video->queue = NULL;
1161 video->streaming = 0; 1152 video->streaming = 0;
1153 video->error = false;
1162 1154
1163 if (video->isp->pdata->set_constraints) 1155 if (video->isp->pdata->set_constraints)
1164 video->isp->pdata->set_constraints(video->isp, false); 1156 video->isp->pdata->set_constraints(video->isp, false);
@@ -1332,11 +1324,13 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
1332 switch (video->type) { 1324 switch (video->type) {
1333 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1325 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1334 direction = "output"; 1326 direction = "output";
1335 video->pad.flags = MEDIA_PAD_FL_SINK; 1327 video->pad.flags = MEDIA_PAD_FL_SINK
1328 | MEDIA_PAD_FL_MUST_CONNECT;
1336 break; 1329 break;
1337 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1330 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1338 direction = "input"; 1331 direction = "input";
1339 video->pad.flags = MEDIA_PAD_FL_SOURCE; 1332 video->pad.flags = MEDIA_PAD_FL_SOURCE
1333 | MEDIA_PAD_FL_MUST_CONNECT;
1340 video->video.vfl_dir = VFL_DIR_TX; 1334 video->video.vfl_dir = VFL_DIR_TX;
1341 break; 1335 break;
1342 1336
diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h
index 1ad470ec2b9d..4e194076cc60 100644
--- a/drivers/media/platform/omap3isp/ispvideo.h
+++ b/drivers/media/platform/omap3isp/ispvideo.h
@@ -178,6 +178,7 @@ struct isp_video {
178 /* Pipeline state */ 178 /* Pipeline state */
179 struct isp_pipeline pipe; 179 struct isp_pipeline pipe;
180 struct mutex stream_lock; /* pipeline and stream states */ 180 struct mutex stream_lock; /* pipeline and stream states */
181 bool error;
181 182
182 /* Video buffers queue */ 183 /* Video buffers queue */
183 struct isp_video_queue *queue; 184 struct isp_video_queue *queue;
@@ -207,6 +208,7 @@ int omap3isp_video_register(struct isp_video *video,
207 struct v4l2_device *vdev); 208 struct v4l2_device *vdev);
208void omap3isp_video_unregister(struct isp_video *video); 209void omap3isp_video_unregister(struct isp_video *video);
209struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video); 210struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video);
211void omap3isp_video_cancel_stream(struct isp_video *video);
210void omap3isp_video_resume(struct isp_video *video, int continuous); 212void omap3isp_video_resume(struct isp_video *video, int continuous);
211struct media_pad *omap3isp_video_remote_pad(struct isp_video *video); 213struct media_pad *omap3isp_video_remote_pad(struct isp_video *video);
212 214
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 0b2948376aee..0fcf7d75e841 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -136,10 +136,9 @@ static int g2d_buf_prepare(struct vb2_buffer *vb)
136static void g2d_buf_queue(struct vb2_buffer *vb) 136static void g2d_buf_queue(struct vb2_buffer *vb)
137{ 137{
138 struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 138 struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
139 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); 139 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
140} 140}
141 141
142
143static struct vb2_ops g2d_qops = { 142static struct vb2_ops g2d_qops = {
144 .queue_setup = g2d_queue_setup, 143 .queue_setup = g2d_queue_setup,
145 .buf_prepare = g2d_buf_prepare, 144 .buf_prepare = g2d_buf_prepare,
@@ -159,6 +158,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
159 src_vq->mem_ops = &vb2_dma_contig_memops; 158 src_vq->mem_ops = &vb2_dma_contig_memops;
160 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 159 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
161 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 160 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
161 src_vq->lock = &ctx->dev->mutex;
162 162
163 ret = vb2_queue_init(src_vq); 163 ret = vb2_queue_init(src_vq);
164 if (ret) 164 if (ret)
@@ -171,6 +171,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
171 dst_vq->mem_ops = &vb2_dma_contig_memops; 171 dst_vq->mem_ops = &vb2_dma_contig_memops;
172 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 172 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
173 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 173 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
174 dst_vq->lock = &ctx->dev->mutex;
174 175
175 return vb2_queue_init(dst_vq); 176 return vb2_queue_init(dst_vq);
176} 177}
@@ -253,9 +254,9 @@ static int g2d_open(struct file *file)
253 kfree(ctx); 254 kfree(ctx);
254 return -ERESTARTSYS; 255 return -ERESTARTSYS;
255 } 256 }
256 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); 257 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
257 if (IS_ERR(ctx->m2m_ctx)) { 258 if (IS_ERR(ctx->fh.m2m_ctx)) {
258 ret = PTR_ERR(ctx->m2m_ctx); 259 ret = PTR_ERR(ctx->fh.m2m_ctx);
259 mutex_unlock(&dev->mutex); 260 mutex_unlock(&dev->mutex);
260 kfree(ctx); 261 kfree(ctx);
261 return ret; 262 return ret;
@@ -324,7 +325,7 @@ static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
324 struct vb2_queue *vq; 325 struct vb2_queue *vq;
325 struct g2d_frame *frm; 326 struct g2d_frame *frm;
326 327
327 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 328 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
328 if (!vq) 329 if (!vq)
329 return -EINVAL; 330 return -EINVAL;
330 frm = get_frame(ctx, f->type); 331 frm = get_frame(ctx, f->type);
@@ -384,7 +385,7 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
384 ret = vidioc_try_fmt(file, prv, f); 385 ret = vidioc_try_fmt(file, prv, f);
385 if (ret) 386 if (ret)
386 return ret; 387 return ret;
387 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 388 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
388 if (vb2_is_busy(vq)) { 389 if (vb2_is_busy(vq)) {
389 v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type); 390 v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type);
390 return -EBUSY; 391 return -EBUSY;
@@ -410,72 +411,6 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
410 return 0; 411 return 0;
411} 412}
412 413
413static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait)
414{
415 struct g2d_ctx *ctx = fh2ctx(file->private_data);
416 struct g2d_dev *dev = ctx->dev;
417 unsigned int res;
418
419 mutex_lock(&dev->mutex);
420 res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
421 mutex_unlock(&dev->mutex);
422 return res;
423}
424
425static int g2d_mmap(struct file *file, struct vm_area_struct *vma)
426{
427 struct g2d_ctx *ctx = fh2ctx(file->private_data);
428 struct g2d_dev *dev = ctx->dev;
429 int ret;
430
431 if (mutex_lock_interruptible(&dev->mutex))
432 return -ERESTARTSYS;
433 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
434 mutex_unlock(&dev->mutex);
435 return ret;
436}
437
438static int vidioc_reqbufs(struct file *file, void *priv,
439 struct v4l2_requestbuffers *reqbufs)
440{
441 struct g2d_ctx *ctx = priv;
442 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
443}
444
445static int vidioc_querybuf(struct file *file, void *priv,
446 struct v4l2_buffer *buf)
447{
448 struct g2d_ctx *ctx = priv;
449 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
450}
451
452static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
453{
454 struct g2d_ctx *ctx = priv;
455 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
456}
457
458static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
459{
460 struct g2d_ctx *ctx = priv;
461 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
462}
463
464
465static int vidioc_streamon(struct file *file, void *priv,
466 enum v4l2_buf_type type)
467{
468 struct g2d_ctx *ctx = priv;
469 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
470}
471
472static int vidioc_streamoff(struct file *file, void *priv,
473 enum v4l2_buf_type type)
474{
475 struct g2d_ctx *ctx = priv;
476 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
477}
478
479static int vidioc_cropcap(struct file *file, void *priv, 414static int vidioc_cropcap(struct file *file, void *priv,
480 struct v4l2_cropcap *cr) 415 struct v4l2_cropcap *cr)
481{ 416{
@@ -551,20 +486,6 @@ static int vidioc_s_crop(struct file *file, void *prv, const struct v4l2_crop *c
551 return 0; 486 return 0;
552} 487}
553 488
554static void g2d_lock(void *prv)
555{
556 struct g2d_ctx *ctx = prv;
557 struct g2d_dev *dev = ctx->dev;
558 mutex_lock(&dev->mutex);
559}
560
561static void g2d_unlock(void *prv)
562{
563 struct g2d_ctx *ctx = prv;
564 struct g2d_dev *dev = ctx->dev;
565 mutex_unlock(&dev->mutex);
566}
567
568static void job_abort(void *prv) 489static void job_abort(void *prv)
569{ 490{
570 struct g2d_ctx *ctx = prv; 491 struct g2d_ctx *ctx = prv;
@@ -589,8 +510,8 @@ static void device_run(void *prv)
589 510
590 dev->curr = ctx; 511 dev->curr = ctx;
591 512
592 src = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 513 src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
593 dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 514 dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
594 515
595 clk_enable(dev->gate); 516 clk_enable(dev->gate);
596 g2d_reset(dev); 517 g2d_reset(dev);
@@ -631,8 +552,8 @@ static irqreturn_t g2d_isr(int irq, void *prv)
631 552
632 BUG_ON(ctx == NULL); 553 BUG_ON(ctx == NULL);
633 554
634 src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 555 src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
635 dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 556 dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
636 557
637 BUG_ON(src == NULL); 558 BUG_ON(src == NULL);
638 BUG_ON(dst == NULL); 559 BUG_ON(dst == NULL);
@@ -642,7 +563,7 @@ static irqreturn_t g2d_isr(int irq, void *prv)
642 563
643 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); 564 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
644 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); 565 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
645 v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx); 566 v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
646 567
647 dev->curr = NULL; 568 dev->curr = NULL;
648 wake_up(&dev->irq_queue); 569 wake_up(&dev->irq_queue);
@@ -653,9 +574,9 @@ static const struct v4l2_file_operations g2d_fops = {
653 .owner = THIS_MODULE, 574 .owner = THIS_MODULE,
654 .open = g2d_open, 575 .open = g2d_open,
655 .release = g2d_release, 576 .release = g2d_release,
656 .poll = g2d_poll, 577 .poll = v4l2_m2m_fop_poll,
657 .unlocked_ioctl = video_ioctl2, 578 .unlocked_ioctl = video_ioctl2,
658 .mmap = g2d_mmap, 579 .mmap = v4l2_m2m_fop_mmap,
659}; 580};
660 581
661static const struct v4l2_ioctl_ops g2d_ioctl_ops = { 582static const struct v4l2_ioctl_ops g2d_ioctl_ops = {
@@ -671,14 +592,13 @@ static const struct v4l2_ioctl_ops g2d_ioctl_ops = {
671 .vidioc_try_fmt_vid_out = vidioc_try_fmt, 592 .vidioc_try_fmt_vid_out = vidioc_try_fmt,
672 .vidioc_s_fmt_vid_out = vidioc_s_fmt, 593 .vidioc_s_fmt_vid_out = vidioc_s_fmt,
673 594
674 .vidioc_reqbufs = vidioc_reqbufs, 595 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
675 .vidioc_querybuf = vidioc_querybuf, 596 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
676 597 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
677 .vidioc_qbuf = vidioc_qbuf, 598 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
678 .vidioc_dqbuf = vidioc_dqbuf,
679 599
680 .vidioc_streamon = vidioc_streamon, 600 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
681 .vidioc_streamoff = vidioc_streamoff, 601 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
682 602
683 .vidioc_g_crop = vidioc_g_crop, 603 .vidioc_g_crop = vidioc_g_crop,
684 .vidioc_s_crop = vidioc_s_crop, 604 .vidioc_s_crop = vidioc_s_crop,
@@ -697,8 +617,6 @@ static struct video_device g2d_videodev = {
697static struct v4l2_m2m_ops g2d_m2m_ops = { 617static struct v4l2_m2m_ops g2d_m2m_ops = {
698 .device_run = device_run, 618 .device_run = device_run,
699 .job_abort = job_abort, 619 .job_abort = job_abort,
700 .lock = g2d_lock,
701 .unlock = g2d_unlock,
702}; 620};
703 621
704static const struct of_device_id exynos_g2d_match[]; 622static const struct of_device_id exynos_g2d_match[];
diff --git a/drivers/media/platform/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h
index 300ca05ba404..b0e52ab7ecdb 100644
--- a/drivers/media/platform/s5p-g2d/g2d.h
+++ b/drivers/media/platform/s5p-g2d/g2d.h
@@ -57,7 +57,6 @@ struct g2d_frame {
57struct g2d_ctx { 57struct g2d_ctx {
58 struct v4l2_fh fh; 58 struct v4l2_fh fh;
59 struct g2d_dev *dev; 59 struct g2d_dev *dev;
60 struct v4l2_m2m_ctx *m2m_ctx;
61 struct g2d_frame in; 60 struct g2d_frame in;
62 struct g2d_frame out; 61 struct g2d_frame out;
63 struct v4l2_ctrl *ctrl_hflip; 62 struct v4l2_ctrl *ctrl_hflip;
diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile
index d18cb5edd2d5..a1a9169254c3 100644
--- a/drivers/media/platform/s5p-jpeg/Makefile
+++ b/drivers/media/platform/s5p-jpeg/Makefile
@@ -1,2 +1,2 @@
1s5p-jpeg-objs := jpeg-core.o 1s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos4.o jpeg-hw-s5p.o
2obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o 2obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 9b88a4601007..a1c78c870b68 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1,9 +1,10 @@
1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c 1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
2 * 2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
5 * 5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * 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 * it under the terms of the GNU General Public License version 2 as
@@ -17,6 +18,7 @@
17#include <linux/io.h> 18#include <linux/io.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
19#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/of.h>
20#include <linux/platform_device.h> 22#include <linux/platform_device.h>
21#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
22#include <linux/slab.h> 24#include <linux/slab.h>
@@ -28,70 +30,234 @@
28#include <media/videobuf2-dma-contig.h> 30#include <media/videobuf2-dma-contig.h>
29 31
30#include "jpeg-core.h" 32#include "jpeg-core.h"
31#include "jpeg-hw.h" 33#include "jpeg-hw-s5p.h"
34#include "jpeg-hw-exynos4.h"
35#include "jpeg-regs.h"
32 36
33static struct s5p_jpeg_fmt formats_enc[] = { 37static struct s5p_jpeg_fmt sjpeg_formats[] = {
34 { 38 {
35 .name = "JPEG JFIF", 39 .name = "JPEG JFIF",
36 .fourcc = V4L2_PIX_FMT_JPEG, 40 .fourcc = V4L2_PIX_FMT_JPEG,
41 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
42 SJPEG_FMT_FLAG_DEC_OUTPUT |
43 SJPEG_FMT_FLAG_S5P |
44 SJPEG_FMT_FLAG_EXYNOS4,
45 },
46 {
47 .name = "YUV 4:2:2 packed, YCbYCr",
48 .fourcc = V4L2_PIX_FMT_YUYV,
49 .depth = 16,
37 .colplanes = 1, 50 .colplanes = 1,
38 .types = MEM2MEM_CAPTURE, 51 .h_align = 4,
52 .v_align = 3,
53 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
54 SJPEG_FMT_FLAG_DEC_CAPTURE |
55 SJPEG_FMT_FLAG_S5P |
56 SJPEG_FMT_NON_RGB,
57 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
39 }, 58 },
40 { 59 {
41 .name = "YUV 4:2:2 packed, YCbYCr", 60 .name = "YUV 4:2:2 packed, YCbYCr",
42 .fourcc = V4L2_PIX_FMT_YUYV, 61 .fourcc = V4L2_PIX_FMT_YUYV,
43 .depth = 16, 62 .depth = 16,
44 .colplanes = 1, 63 .colplanes = 1,
45 .types = MEM2MEM_OUTPUT, 64 .h_align = 1,
65 .v_align = 0,
66 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
67 SJPEG_FMT_FLAG_DEC_CAPTURE |
68 SJPEG_FMT_FLAG_EXYNOS4 |
69 SJPEG_FMT_NON_RGB,
70 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
71 },
72 {
73 .name = "YUV 4:2:2 packed, YCrYCb",
74 .fourcc = V4L2_PIX_FMT_YVYU,
75 .depth = 16,
76 .colplanes = 1,
77 .h_align = 1,
78 .v_align = 0,
79 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
80 SJPEG_FMT_FLAG_DEC_CAPTURE |
81 SJPEG_FMT_FLAG_EXYNOS4 |
82 SJPEG_FMT_NON_RGB,
83 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
46 }, 84 },
47 { 85 {
48 .name = "RGB565", 86 .name = "RGB565",
49 .fourcc = V4L2_PIX_FMT_RGB565, 87 .fourcc = V4L2_PIX_FMT_RGB565,
50 .depth = 16, 88 .depth = 16,
51 .colplanes = 1, 89 .colplanes = 1,
52 .types = MEM2MEM_OUTPUT, 90 .h_align = 0,
91 .v_align = 0,
92 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
93 SJPEG_FMT_FLAG_DEC_CAPTURE |
94 SJPEG_FMT_FLAG_EXYNOS4 |
95 SJPEG_FMT_RGB,
96 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
53 }, 97 },
54};
55#define NUM_FORMATS_ENC ARRAY_SIZE(formats_enc)
56
57static struct s5p_jpeg_fmt formats_dec[] = {
58 { 98 {
59 .name = "YUV 4:2:0 planar, YCbCr", 99 .name = "RGB565",
60 .fourcc = V4L2_PIX_FMT_YUV420, 100 .fourcc = V4L2_PIX_FMT_RGB565,
61 .depth = 12, 101 .depth = 16,
62 .colplanes = 3, 102 .colplanes = 1,
63 .h_align = 4, 103 .h_align = 0,
64 .v_align = 4, 104 .v_align = 0,
65 .types = MEM2MEM_CAPTURE, 105 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
106 SJPEG_FMT_FLAG_S5P |
107 SJPEG_FMT_RGB,
108 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
66 }, 109 },
67 { 110 {
68 .name = "YUV 4:2:2 packed, YCbYCr", 111 .name = "ARGB8888, 32 bpp",
69 .fourcc = V4L2_PIX_FMT_YUYV, 112 .fourcc = V4L2_PIX_FMT_RGB32,
70 .depth = 16, 113 .depth = 32,
71 .colplanes = 1, 114 .colplanes = 1,
115 .h_align = 0,
116 .v_align = 0,
117 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
118 SJPEG_FMT_FLAG_DEC_CAPTURE |
119 SJPEG_FMT_FLAG_EXYNOS4 |
120 SJPEG_FMT_RGB,
121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
122 },
123 {
124 .name = "YUV 4:4:4 planar, Y/CbCr",
125 .fourcc = V4L2_PIX_FMT_NV24,
126 .depth = 24,
127 .colplanes = 2,
128 .h_align = 0,
129 .v_align = 0,
130 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
131 SJPEG_FMT_FLAG_DEC_CAPTURE |
132 SJPEG_FMT_FLAG_EXYNOS4 |
133 SJPEG_FMT_NON_RGB,
134 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
135 },
136 {
137 .name = "YUV 4:4:4 planar, Y/CrCb",
138 .fourcc = V4L2_PIX_FMT_NV42,
139 .depth = 24,
140 .colplanes = 2,
141 .h_align = 0,
142 .v_align = 0,
143 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
144 SJPEG_FMT_FLAG_DEC_CAPTURE |
145 SJPEG_FMT_FLAG_EXYNOS4 |
146 SJPEG_FMT_NON_RGB,
147 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
148 },
149 {
150 .name = "YUV 4:2:2 planar, Y/CrCb",
151 .fourcc = V4L2_PIX_FMT_NV61,
152 .depth = 16,
153 .colplanes = 2,
154 .h_align = 1,
155 .v_align = 0,
156 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
157 SJPEG_FMT_FLAG_DEC_CAPTURE |
158 SJPEG_FMT_FLAG_EXYNOS4 |
159 SJPEG_FMT_NON_RGB,
160 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
161 },
162 {
163 .name = "YUV 4:2:2 planar, Y/CbCr",
164 .fourcc = V4L2_PIX_FMT_NV16,
165 .depth = 16,
166 .colplanes = 2,
167 .h_align = 1,
168 .v_align = 0,
169 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
170 SJPEG_FMT_FLAG_DEC_CAPTURE |
171 SJPEG_FMT_FLAG_EXYNOS4 |
172 SJPEG_FMT_NON_RGB,
173 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
174 },
175 {
176 .name = "YUV 4:2:0 planar, Y/CbCr",
177 .fourcc = V4L2_PIX_FMT_NV12,
178 .depth = 16,
179 .colplanes = 2,
180 .h_align = 1,
181 .v_align = 1,
182 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
183 SJPEG_FMT_FLAG_DEC_CAPTURE |
184 SJPEG_FMT_FLAG_EXYNOS4 |
185 SJPEG_FMT_NON_RGB,
186 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
187 },
188 {
189 .name = "YUV 4:2:0 planar, Y/CbCr",
190 .fourcc = V4L2_PIX_FMT_NV12,
191 .depth = 16,
192 .colplanes = 4,
72 .h_align = 4, 193 .h_align = 4,
73 .v_align = 3, 194 .v_align = 1,
74 .types = MEM2MEM_CAPTURE, 195 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
196 SJPEG_FMT_FLAG_DEC_CAPTURE |
197 SJPEG_FMT_FLAG_S5P |
198 SJPEG_FMT_NON_RGB,
199 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
75 }, 200 },
76 { 201 {
77 .name = "JPEG JFIF", 202 .name = "YUV 4:2:0 planar, Y/CrCb",
78 .fourcc = V4L2_PIX_FMT_JPEG, 203 .fourcc = V4L2_PIX_FMT_NV21,
204 .depth = 12,
205 .colplanes = 2,
206 .h_align = 1,
207 .v_align = 1,
208 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
209 SJPEG_FMT_FLAG_DEC_CAPTURE |
210 SJPEG_FMT_FLAG_EXYNOS4 |
211 SJPEG_FMT_NON_RGB,
212 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
213 },
214 {
215 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
216 .fourcc = V4L2_PIX_FMT_YUV420,
217 .depth = 12,
218 .colplanes = 3,
219 .h_align = 1,
220 .v_align = 1,
221 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
222 SJPEG_FMT_FLAG_DEC_CAPTURE |
223 SJPEG_FMT_FLAG_EXYNOS4 |
224 SJPEG_FMT_NON_RGB,
225 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
226 },
227 {
228 .name = "Gray",
229 .fourcc = V4L2_PIX_FMT_GREY,
230 .depth = 8,
79 .colplanes = 1, 231 .colplanes = 1,
80 .types = MEM2MEM_OUTPUT, 232 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
233 SJPEG_FMT_FLAG_DEC_CAPTURE |
234 SJPEG_FMT_FLAG_EXYNOS4 |
235 SJPEG_FMT_NON_RGB,
236 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
81 }, 237 },
82}; 238};
83#define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec) 239#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
84 240
85static const unsigned char qtbl_luminance[4][64] = { 241static const unsigned char qtbl_luminance[4][64] = {
86 {/* level 1 - high quality */ 242 {/*level 0 - high compression quality */
87 8, 6, 6, 8, 12, 14, 16, 17, 243 20, 16, 25, 39, 50, 46, 62, 68,
88 6, 6, 6, 8, 10, 13, 12, 15, 244 16, 18, 23, 38, 38, 53, 65, 68,
89 6, 6, 7, 8, 13, 14, 18, 24, 245 25, 23, 31, 38, 53, 65, 68, 68,
90 8, 8, 8, 14, 13, 19, 24, 35, 246 39, 38, 38, 53, 65, 68, 68, 68,
91 12, 10, 13, 13, 20, 26, 34, 39, 247 50, 38, 53, 65, 68, 68, 68, 68,
92 14, 13, 14, 19, 26, 34, 39, 39, 248 46, 53, 65, 68, 68, 68, 68, 68,
93 16, 12, 18, 24, 34, 39, 39, 39, 249 62, 65, 68, 68, 68, 68, 68, 68,
94 17, 15, 24, 35, 39, 39, 39, 39 250 68, 68, 68, 68, 68, 68, 68, 68
251 },
252 {/* level 1 */
253 16, 11, 11, 16, 23, 27, 31, 30,
254 11, 12, 12, 15, 20, 23, 23, 30,
255 11, 12, 13, 16, 23, 26, 35, 47,
256 16, 15, 16, 23, 26, 37, 47, 64,
257 23, 20, 23, 26, 39, 51, 64, 64,
258 27, 23, 26, 37, 51, 64, 64, 64,
259 31, 23, 35, 47, 64, 64, 64, 64,
260 30, 30, 47, 64, 64, 64, 64, 64
95 }, 261 },
96 {/* level 2 */ 262 {/* level 2 */
97 12, 8, 8, 12, 17, 21, 24, 23, 263 12, 8, 8, 12, 17, 21, 24, 23,
@@ -103,38 +269,38 @@ static const unsigned char qtbl_luminance[4][64] = {
103 24, 18, 27, 36, 51, 59, 59, 59, 269 24, 18, 27, 36, 51, 59, 59, 59,
104 23, 23, 36, 53, 59, 59, 59, 59 270 23, 23, 36, 53, 59, 59, 59, 59
105 }, 271 },
106 {/* level 3 */ 272 {/* level 3 - low compression quality */
107 16, 11, 11, 16, 23, 27, 31, 30, 273 8, 6, 6, 8, 12, 14, 16, 17,
108 11, 12, 12, 15, 20, 23, 23, 30, 274 6, 6, 6, 8, 10, 13, 12, 15,
109 11, 12, 13, 16, 23, 26, 35, 47, 275 6, 6, 7, 8, 13, 14, 18, 24,
110 16, 15, 16, 23, 26, 37, 47, 64, 276 8, 8, 8, 14, 13, 19, 24, 35,
111 23, 20, 23, 26, 39, 51, 64, 64, 277 12, 10, 13, 13, 20, 26, 34, 39,
112 27, 23, 26, 37, 51, 64, 64, 64, 278 14, 13, 14, 19, 26, 34, 39, 39,
113 31, 23, 35, 47, 64, 64, 64, 64, 279 16, 12, 18, 24, 34, 39, 39, 39,
114 30, 30, 47, 64, 64, 64, 64, 64 280 17, 15, 24, 35, 39, 39, 39, 39
115 },
116 {/*level 4 - low quality */
117 20, 16, 25, 39, 50, 46, 62, 68,
118 16, 18, 23, 38, 38, 53, 65, 68,
119 25, 23, 31, 38, 53, 65, 68, 68,
120 39, 38, 38, 53, 65, 68, 68, 68,
121 50, 38, 53, 65, 68, 68, 68, 68,
122 46, 53, 65, 68, 68, 68, 68, 68,
123 62, 65, 68, 68, 68, 68, 68, 68,
124 68, 68, 68, 68, 68, 68, 68, 68
125 } 281 }
126}; 282};
127 283
128static const unsigned char qtbl_chrominance[4][64] = { 284static const unsigned char qtbl_chrominance[4][64] = {
129 {/* level 1 - high quality */ 285 {/*level 0 - high compression quality */
130 9, 8, 9, 11, 14, 17, 19, 24, 286 21, 25, 32, 38, 54, 68, 68, 68,
131 8, 10, 9, 11, 14, 13, 17, 22, 287 25, 28, 24, 38, 54, 68, 68, 68,
132 9, 9, 13, 14, 13, 15, 23, 26, 288 32, 24, 32, 43, 66, 68, 68, 68,
133 11, 11, 14, 14, 15, 20, 26, 33, 289 38, 38, 43, 53, 68, 68, 68, 68,
134 14, 14, 13, 15, 20, 24, 33, 39, 290 54, 54, 66, 68, 68, 68, 68, 68,
135 17, 13, 15, 20, 24, 32, 39, 39, 291 68, 68, 68, 68, 68, 68, 68, 68,
136 19, 17, 23, 26, 33, 39, 39, 39, 292 68, 68, 68, 68, 68, 68, 68, 68,
137 24, 22, 26, 33, 39, 39, 39, 39 293 68, 68, 68, 68, 68, 68, 68, 68
294 },
295 {/* level 1 */
296 17, 15, 17, 21, 20, 26, 38, 48,
297 15, 19, 18, 17, 20, 26, 35, 43,
298 17, 18, 20, 22, 26, 30, 46, 53,
299 21, 17, 22, 28, 30, 39, 53, 64,
300 20, 20, 26, 30, 39, 48, 64, 64,
301 26, 26, 30, 39, 48, 63, 64, 64,
302 38, 35, 46, 53, 64, 64, 64, 64,
303 48, 43, 53, 64, 64, 64, 64, 64
138 }, 304 },
139 {/* level 2 */ 305 {/* level 2 */
140 13, 11, 13, 16, 20, 20, 29, 37, 306 13, 11, 13, 16, 20, 20, 29, 37,
@@ -146,25 +312,15 @@ static const unsigned char qtbl_chrominance[4][64] = {
146 29, 26, 35, 40, 50, 59, 59, 59, 312 29, 26, 35, 40, 50, 59, 59, 59,
147 37, 32, 40, 50, 59, 59, 59, 59 313 37, 32, 40, 50, 59, 59, 59, 59
148 }, 314 },
149 {/* level 3 */ 315 {/* level 3 - low compression quality */
150 17, 15, 17, 21, 20, 26, 38, 48, 316 9, 8, 9, 11, 14, 17, 19, 24,
151 15, 19, 18, 17, 20, 26, 35, 43, 317 8, 10, 9, 11, 14, 13, 17, 22,
152 17, 18, 20, 22, 26, 30, 46, 53, 318 9, 9, 13, 14, 13, 15, 23, 26,
153 21, 17, 22, 28, 30, 39, 53, 64, 319 11, 11, 14, 14, 15, 20, 26, 33,
154 20, 20, 26, 30, 39, 48, 64, 64, 320 14, 14, 13, 15, 20, 24, 33, 39,
155 26, 26, 30, 39, 48, 63, 64, 64, 321 17, 13, 15, 20, 24, 32, 39, 39,
156 38, 35, 46, 53, 64, 64, 64, 64, 322 19, 17, 23, 26, 33, 39, 39, 39,
157 48, 43, 53, 64, 64, 64, 64, 64 323 24, 22, 26, 33, 39, 39, 39, 39
158 },
159 {/*level 4 - low quality */
160 21, 25, 32, 38, 54, 68, 68, 68,
161 25, 28, 24, 38, 54, 68, 68, 68,
162 32, 24, 32, 43, 66, 68, 68, 68,
163 38, 38, 43, 53, 68, 68, 68, 68,
164 54, 54, 66, 68, 68, 68, 68, 68,
165 68, 68, 68, 68, 68, 68, 68, 68,
166 68, 68, 68, 68, 68, 68, 68, 68,
167 68, 68, 68, 68, 68, 68, 68, 68
168 } 324 }
169}; 325};
170 326
@@ -202,6 +358,106 @@ static const unsigned char hactblg0[162] = {
202 0xf9, 0xfa 358 0xf9, 0xfa
203}; 359};
204 360
361/*
362 * Fourcc downgrade schema lookup tables for 422 and 420
363 * chroma subsampling - fourcc on each position maps on the
364 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
365 * to get the most suitable fourcc counterpart for the given
366 * downgraded subsampling property.
367 */
368static const u32 subs422_fourcc_dwngrd_schema[] = {
369 V4L2_PIX_FMT_NV16,
370 V4L2_PIX_FMT_NV61,
371};
372
373static const u32 subs420_fourcc_dwngrd_schema[] = {
374 V4L2_PIX_FMT_NV12,
375 V4L2_PIX_FMT_NV21,
376 V4L2_PIX_FMT_NV12,
377 V4L2_PIX_FMT_NV21,
378 V4L2_PIX_FMT_NV12,
379 V4L2_PIX_FMT_NV21,
380 V4L2_PIX_FMT_GREY,
381 V4L2_PIX_FMT_GREY,
382 V4L2_PIX_FMT_GREY,
383 V4L2_PIX_FMT_GREY,
384};
385
386/*
387 * Lookup table for translation of a fourcc to the position
388 * of its downgraded counterpart in the *fourcc_dwngrd_schema
389 * tables.
390 */
391static const u32 fourcc_to_dwngrd_schema_id[] = {
392 V4L2_PIX_FMT_NV24,
393 V4L2_PIX_FMT_NV42,
394 V4L2_PIX_FMT_NV16,
395 V4L2_PIX_FMT_NV61,
396 V4L2_PIX_FMT_YUYV,
397 V4L2_PIX_FMT_YVYU,
398 V4L2_PIX_FMT_NV12,
399 V4L2_PIX_FMT_NV21,
400 V4L2_PIX_FMT_YUV420,
401 V4L2_PIX_FMT_GREY,
402};
403
404static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
405{
406 int i;
407 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
408 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
409 return i;
410 }
411
412 return -EINVAL;
413}
414
415static int s5p_jpeg_adjust_fourcc_to_subsampling(
416 enum v4l2_jpeg_chroma_subsampling subs,
417 u32 in_fourcc,
418 u32 *out_fourcc,
419 struct s5p_jpeg_ctx *ctx)
420{
421 int dwngrd_sch_id;
422
423 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
424 dwngrd_sch_id =
425 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
426 if (dwngrd_sch_id < 0)
427 return -EINVAL;
428 }
429
430 switch (ctx->subsampling) {
431 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
432 *out_fourcc = V4L2_PIX_FMT_GREY;
433 break;
434 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
435 if (dwngrd_sch_id >
436 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
437 return -EINVAL;
438 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
439 break;
440 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
441 if (dwngrd_sch_id >
442 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
443 return -EINVAL;
444 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
445 break;
446 default:
447 *out_fourcc = V4L2_PIX_FMT_GREY;
448 break;
449 }
450
451 return 0;
452}
453
454static int exynos4x12_decoded_subsampling[] = {
455 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
456 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
457 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
458 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
459};
460
205static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) 461static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
206{ 462{
207 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler); 463 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
@@ -212,8 +468,24 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
212 return container_of(fh, struct s5p_jpeg_ctx, fh); 468 return container_of(fh, struct s5p_jpeg_ctx, fh);
213} 469}
214 470
215static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl, 471static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
216 unsigned long tab, int len) 472{
473 WARN_ON(ctx->subsampling > 3);
474
475 if (ctx->jpeg->variant->version == SJPEG_S5P) {
476 if (ctx->subsampling > 2)
477 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
478 return ctx->subsampling;
479 } else {
480 if (ctx->subsampling > 2)
481 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
482 return exynos4x12_decoded_subsampling[ctx->subsampling];
483 }
484}
485
486static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
487 const unsigned char *qtbl,
488 unsigned long tab, int len)
217{ 489{
218 int i; 490 int i;
219 491
@@ -221,22 +493,25 @@ static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
221 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04)); 493 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
222} 494}
223 495
224static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality) 496static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
225{ 497{
226 /* this driver fills quantisation table 0 with data for luma */ 498 /* this driver fills quantisation table 0 with data for luma */
227 jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0), 499 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
228 ARRAY_SIZE(qtbl_luminance[quality])); 500 S5P_JPG_QTBL_CONTENT(0),
501 ARRAY_SIZE(qtbl_luminance[quality]));
229} 502}
230 503
231static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality) 504static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
232{ 505{
233 /* this driver fills quantisation table 1 with data for chroma */ 506 /* this driver fills quantisation table 1 with data for chroma */
234 jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1), 507 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
235 ARRAY_SIZE(qtbl_chrominance[quality])); 508 S5P_JPG_QTBL_CONTENT(1),
509 ARRAY_SIZE(qtbl_chrominance[quality]));
236} 510}
237 511
238static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl, 512static inline void s5p_jpeg_set_htbl(void __iomem *regs,
239 unsigned long tab, int len) 513 const unsigned char *htbl,
514 unsigned long tab, int len)
240{ 515{
241 int i; 516 int i;
242 517
@@ -244,28 +519,84 @@ static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
244 writel((unsigned int)htbl[i], regs + tab + (i * 0x04)); 519 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
245} 520}
246 521
247static inline void jpeg_set_hdctbl(void __iomem *regs) 522static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
248{ 523{
249 /* this driver fills table 0 for this component */ 524 /* this driver fills table 0 for this component */
250 jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0)); 525 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
526 ARRAY_SIZE(hdctbl0));
251} 527}
252 528
253static inline void jpeg_set_hdctblg(void __iomem *regs) 529static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
254{ 530{
255 /* this driver fills table 0 for this component */ 531 /* this driver fills table 0 for this component */
256 jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0)); 532 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
533 ARRAY_SIZE(hdctblg0));
257} 534}
258 535
259static inline void jpeg_set_hactbl(void __iomem *regs) 536static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
260{ 537{
261 /* this driver fills table 0 for this component */ 538 /* this driver fills table 0 for this component */
262 jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0)); 539 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
540 ARRAY_SIZE(hactbl0));
263} 541}
264 542
265static inline void jpeg_set_hactblg(void __iomem *regs) 543static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
266{ 544{
267 /* this driver fills table 0 for this component */ 545 /* this driver fills table 0 for this component */
268 jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0)); 546 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
547 ARRAY_SIZE(hactblg0));
548}
549
550static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
551 const unsigned char *tbl,
552 unsigned long tab, int len)
553{
554 int i;
555 unsigned int dword;
556
557 for (i = 0; i < len; i += 4) {
558 dword = tbl[i] |
559 (tbl[i + 1] << 8) |
560 (tbl[i + 2] << 16) |
561 (tbl[i + 3] << 24);
562 writel(dword, regs + tab + i);
563 }
564}
565
566static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
567{
568 /* this driver fills quantisation table 0 with data for luma */
569 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
570 EXYNOS4_QTBL_CONTENT(0),
571 ARRAY_SIZE(qtbl_luminance[quality]));
572}
573
574static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
575{
576 /* this driver fills quantisation table 1 with data for chroma */
577 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
578 EXYNOS4_QTBL_CONTENT(1),
579 ARRAY_SIZE(qtbl_chrominance[quality]));
580}
581
582void exynos4_jpeg_set_huff_tbl(void __iomem *base)
583{
584 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
585 ARRAY_SIZE(hdctbl0));
586 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
587 ARRAY_SIZE(hdctbl0));
588 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
589 ARRAY_SIZE(hdctblg0));
590 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
591 ARRAY_SIZE(hdctblg0));
592 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
593 ARRAY_SIZE(hactbl0));
594 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
595 ARRAY_SIZE(hactbl0));
596 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
597 ARRAY_SIZE(hactblg0));
598 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
599 ARRAY_SIZE(hactblg0));
269} 600}
270 601
271/* 602/*
@@ -276,8 +607,8 @@ static inline void jpeg_set_hactblg(void __iomem *regs)
276 607
277static int queue_init(void *priv, struct vb2_queue *src_vq, 608static int queue_init(void *priv, struct vb2_queue *src_vq,
278 struct vb2_queue *dst_vq); 609 struct vb2_queue *dst_vq);
279static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode, 610static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
280 __u32 pixelformat); 611 __u32 pixelformat, unsigned int fmt_type);
281static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx); 612static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
282 613
283static int s5p_jpeg_open(struct file *file) 614static int s5p_jpeg_open(struct file *file)
@@ -285,7 +616,7 @@ static int s5p_jpeg_open(struct file *file)
285 struct s5p_jpeg *jpeg = video_drvdata(file); 616 struct s5p_jpeg *jpeg = video_drvdata(file);
286 struct video_device *vfd = video_devdata(file); 617 struct video_device *vfd = video_devdata(file);
287 struct s5p_jpeg_ctx *ctx; 618 struct s5p_jpeg_ctx *ctx;
288 struct s5p_jpeg_fmt *out_fmt; 619 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
289 int ret = 0; 620 int ret = 0;
290 621
291 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 622 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -306,24 +637,31 @@ static int s5p_jpeg_open(struct file *file)
306 ctx->jpeg = jpeg; 637 ctx->jpeg = jpeg;
307 if (vfd == jpeg->vfd_encoder) { 638 if (vfd == jpeg->vfd_encoder) {
308 ctx->mode = S5P_JPEG_ENCODE; 639 ctx->mode = S5P_JPEG_ENCODE;
309 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565); 640 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
641 FMT_TYPE_OUTPUT);
642 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
643 FMT_TYPE_CAPTURE);
310 } else { 644 } else {
311 ctx->mode = S5P_JPEG_DECODE; 645 ctx->mode = S5P_JPEG_DECODE;
312 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG); 646 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
647 FMT_TYPE_OUTPUT);
648 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
649 FMT_TYPE_CAPTURE);
313 } 650 }
314 651
315 ret = s5p_jpeg_controls_create(ctx); 652 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
316 if (ret < 0) 653 if (IS_ERR(ctx->fh.m2m_ctx)) {
317 goto error; 654 ret = PTR_ERR(ctx->fh.m2m_ctx);
318
319 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
320 if (IS_ERR(ctx->m2m_ctx)) {
321 ret = PTR_ERR(ctx->m2m_ctx);
322 goto error; 655 goto error;
323 } 656 }
324 657
325 ctx->out_q.fmt = out_fmt; 658 ctx->out_q.fmt = out_fmt;
326 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV); 659 ctx->cap_q.fmt = cap_fmt;
660
661 ret = s5p_jpeg_controls_create(ctx);
662 if (ret < 0)
663 goto error;
664
327 mutex_unlock(&jpeg->lock); 665 mutex_unlock(&jpeg->lock);
328 return 0; 666 return 0;
329 667
@@ -342,49 +680,23 @@ static int s5p_jpeg_release(struct file *file)
342 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); 680 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
343 681
344 mutex_lock(&jpeg->lock); 682 mutex_lock(&jpeg->lock);
345 v4l2_m2m_ctx_release(ctx->m2m_ctx); 683 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
346 mutex_unlock(&jpeg->lock);
347 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 684 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
348 v4l2_fh_del(&ctx->fh); 685 v4l2_fh_del(&ctx->fh);
349 v4l2_fh_exit(&ctx->fh); 686 v4l2_fh_exit(&ctx->fh);
350 kfree(ctx); 687 kfree(ctx);
351
352 return 0;
353}
354
355static unsigned int s5p_jpeg_poll(struct file *file,
356 struct poll_table_struct *wait)
357{
358 struct s5p_jpeg *jpeg = video_drvdata(file);
359 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
360 unsigned int res;
361
362 mutex_lock(&jpeg->lock);
363 res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
364 mutex_unlock(&jpeg->lock); 688 mutex_unlock(&jpeg->lock);
365 return res;
366}
367
368static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
369{
370 struct s5p_jpeg *jpeg = video_drvdata(file);
371 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
372 int ret;
373 689
374 if (mutex_lock_interruptible(&jpeg->lock)) 690 return 0;
375 return -ERESTARTSYS;
376 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
377 mutex_unlock(&jpeg->lock);
378 return ret;
379} 691}
380 692
381static const struct v4l2_file_operations s5p_jpeg_fops = { 693static const struct v4l2_file_operations s5p_jpeg_fops = {
382 .owner = THIS_MODULE, 694 .owner = THIS_MODULE,
383 .open = s5p_jpeg_open, 695 .open = s5p_jpeg_open,
384 .release = s5p_jpeg_release, 696 .release = s5p_jpeg_release,
385 .poll = s5p_jpeg_poll, 697 .poll = v4l2_m2m_fop_poll,
386 .unlocked_ioctl = video_ioctl2, 698 .unlocked_ioctl = video_ioctl2,
387 .mmap = s5p_jpeg_mmap, 699 .mmap = v4l2_m2m_fop_mmap,
388}; 700};
389 701
390/* 702/*
@@ -427,10 +739,11 @@ static void skip(struct s5p_jpeg_buffer *buf, long len)
427} 739}
428 740
429static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, 741static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
430 unsigned long buffer, unsigned long size) 742 unsigned long buffer, unsigned long size,
743 struct s5p_jpeg_ctx *ctx)
431{ 744{
432 int c, components, notfound; 745 int c, components, notfound;
433 unsigned int height, width, word; 746 unsigned int height, width, word, subsampling = 0;
434 long length; 747 long length;
435 struct s5p_jpeg_buffer jpeg_buffer; 748 struct s5p_jpeg_buffer jpeg_buffer;
436 749
@@ -469,7 +782,15 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
469 break; 782 break;
470 notfound = 0; 783 notfound = 0;
471 784
472 skip(&jpeg_buffer, components * 3); 785 if (components == 1) {
786 subsampling = 0x33;
787 } else {
788 skip(&jpeg_buffer, 1);
789 subsampling = get_byte(&jpeg_buffer);
790 skip(&jpeg_buffer, 1);
791 }
792
793 skip(&jpeg_buffer, components * 2);
473 break; 794 break;
474 795
475 /* skip payload-less markers */ 796 /* skip payload-less markers */
@@ -491,6 +812,24 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
491 result->w = width; 812 result->w = width;
492 result->h = height; 813 result->h = height;
493 result->size = components; 814 result->size = components;
815
816 switch (subsampling) {
817 case 0x11:
818 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
819 break;
820 case 0x21:
821 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
822 break;
823 case 0x22:
824 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
825 break;
826 case 0x33:
827 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
828 break;
829 default:
830 return false;
831 }
832
494 return !notfound; 833 return !notfound;
495} 834}
496 835
@@ -521,13 +860,13 @@ static int s5p_jpeg_querycap(struct file *file, void *priv,
521 return 0; 860 return 0;
522} 861}
523 862
524static int enum_fmt(struct s5p_jpeg_fmt *formats, int n, 863static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
525 struct v4l2_fmtdesc *f, u32 type) 864 struct v4l2_fmtdesc *f, u32 type)
526{ 865{
527 int i, num = 0; 866 int i, num = 0;
528 867
529 for (i = 0; i < n; ++i) { 868 for (i = 0; i < n; ++i) {
530 if (formats[i].types & type) { 869 if (sjpeg_formats[i].flags & type) {
531 /* index-th format of type type found ? */ 870 /* index-th format of type type found ? */
532 if (num == f->index) 871 if (num == f->index)
533 break; 872 break;
@@ -541,8 +880,8 @@ static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
541 if (i >= n) 880 if (i >= n)
542 return -EINVAL; 881 return -EINVAL;
543 882
544 strlcpy(f->description, formats[i].name, sizeof(f->description)); 883 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
545 f->pixelformat = formats[i].fourcc; 884 f->pixelformat = sjpeg_formats[i].fourcc;
546 885
547 return 0; 886 return 0;
548} 887}
@@ -553,10 +892,11 @@ static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
553 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 892 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
554 893
555 if (ctx->mode == S5P_JPEG_ENCODE) 894 if (ctx->mode == S5P_JPEG_ENCODE)
556 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f, 895 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
557 MEM2MEM_CAPTURE); 896 SJPEG_FMT_FLAG_ENC_CAPTURE);
558 897
559 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE); 898 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
899 SJPEG_FMT_FLAG_DEC_CAPTURE);
560} 900}
561 901
562static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv, 902static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
@@ -565,10 +905,11 @@ static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
565 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 905 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
566 906
567 if (ctx->mode == S5P_JPEG_ENCODE) 907 if (ctx->mode == S5P_JPEG_ENCODE)
568 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f, 908 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
569 MEM2MEM_OUTPUT); 909 SJPEG_FMT_FLAG_ENC_OUTPUT);
570 910
571 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT); 911 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
912 SJPEG_FMT_FLAG_DEC_OUTPUT);
572} 913}
573 914
574static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx, 915static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
@@ -589,7 +930,7 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
589 struct v4l2_pix_format *pix = &f->fmt.pix; 930 struct v4l2_pix_format *pix = &f->fmt.pix;
590 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv); 931 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
591 932
592 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type); 933 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
593 if (!vq) 934 if (!vq)
594 return -EINVAL; 935 return -EINVAL;
595 936
@@ -615,29 +956,35 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
615 return 0; 956 return 0;
616} 957}
617 958
618static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode, 959static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
619 u32 pixelformat) 960 u32 pixelformat, unsigned int fmt_type)
620{ 961{
621 unsigned int k; 962 unsigned int k, fmt_flag, ver_flag;
622 struct s5p_jpeg_fmt *formats;
623 int n;
624 963
625 if (mode == S5P_JPEG_ENCODE) { 964 if (ctx->mode == S5P_JPEG_ENCODE)
626 formats = formats_enc; 965 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
627 n = NUM_FORMATS_ENC; 966 SJPEG_FMT_FLAG_ENC_OUTPUT :
628 } else { 967 SJPEG_FMT_FLAG_ENC_CAPTURE;
629 formats = formats_dec; 968 else
630 n = NUM_FORMATS_DEC; 969 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
631 } 970 SJPEG_FMT_FLAG_DEC_OUTPUT :
971 SJPEG_FMT_FLAG_DEC_CAPTURE;
972
973 if (ctx->jpeg->variant->version == SJPEG_S5P)
974 ver_flag = SJPEG_FMT_FLAG_S5P;
975 else
976 ver_flag = SJPEG_FMT_FLAG_EXYNOS4;
632 977
633 for (k = 0; k < n; k++) { 978 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
634 struct s5p_jpeg_fmt *fmt = &formats[k]; 979 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
635 if (fmt->fourcc == pixelformat) 980 if (fmt->fourcc == pixelformat &&
981 fmt->flags & fmt_flag &&
982 fmt->flags & ver_flag) {
636 return fmt; 983 return fmt;
984 }
637 } 985 }
638 986
639 return NULL; 987 return NULL;
640
641} 988}
642 989
643static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, 990static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
@@ -673,7 +1020,7 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
673 1020
674 /* V4L2 specification suggests the driver corrects the format struct 1021 /* V4L2 specification suggests the driver corrects the format struct
675 * if any of the dimensions is unsupported */ 1022 * if any of the dimensions is unsupported */
676 if (q_type == MEM2MEM_OUTPUT) 1023 if (q_type == FMT_TYPE_OUTPUT)
677 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH, 1024 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
678 S5P_JPEG_MAX_WIDTH, 0, 1025 S5P_JPEG_MAX_WIDTH, 0,
679 &pix->height, S5P_JPEG_MIN_HEIGHT, 1026 &pix->height, S5P_JPEG_MIN_HEIGHT,
@@ -695,7 +1042,7 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
695 bpl = pix->width; /* planar */ 1042 bpl = pix->width; /* planar */
696 1043
697 if (fmt->colplanes == 1 && /* packed */ 1044 if (fmt->colplanes == 1 && /* packed */
698 (bpl << 3) * fmt->depth < pix->width) 1045 (bpl << 3) / fmt->depth < pix->width)
699 bpl = (pix->width * fmt->depth) >> 3; 1046 bpl = (pix->width * fmt->depth) >> 3;
700 1047
701 pix->bytesperline = bpl; 1048 pix->bytesperline = bpl;
@@ -709,17 +1056,41 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
709 struct v4l2_format *f) 1056 struct v4l2_format *f)
710{ 1057{
711 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 1058 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1059 struct v4l2_pix_format *pix = &f->fmt.pix;
712 struct s5p_jpeg_fmt *fmt; 1060 struct s5p_jpeg_fmt *fmt;
1061 int ret;
713 1062
714 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat); 1063 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
715 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) { 1064 FMT_TYPE_CAPTURE);
1065 if (!fmt) {
716 v4l2_err(&ctx->jpeg->v4l2_dev, 1066 v4l2_err(&ctx->jpeg->v4l2_dev,
717 "Fourcc format (0x%08x) invalid.\n", 1067 "Fourcc format (0x%08x) invalid.\n",
718 f->fmt.pix.pixelformat); 1068 f->fmt.pix.pixelformat);
719 return -EINVAL; 1069 return -EINVAL;
720 } 1070 }
721 1071
722 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE); 1072 /*
1073 * The exynos4x12 device requires resulting YUV image
1074 * subsampling not to be lower than the input jpeg subsampling.
1075 * If this requirement is not met then downgrade the requested
1076 * capture format to the one with subsampling equal to the input jpeg.
1077 */
1078 if ((ctx->jpeg->variant->version != SJPEG_S5P) &&
1079 (ctx->mode == S5P_JPEG_DECODE) &&
1080 (fmt->flags & SJPEG_FMT_NON_RGB) &&
1081 (fmt->subsampling < ctx->subsampling)) {
1082 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1083 fmt->fourcc,
1084 &pix->pixelformat,
1085 ctx);
1086 if (ret < 0)
1087 pix->pixelformat = V4L2_PIX_FMT_GREY;
1088
1089 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1090 FMT_TYPE_CAPTURE);
1091 }
1092
1093 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
723} 1094}
724 1095
725static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv, 1096static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
@@ -728,15 +1099,16 @@ static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
728 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 1099 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
729 struct s5p_jpeg_fmt *fmt; 1100 struct s5p_jpeg_fmt *fmt;
730 1101
731 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat); 1102 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
732 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) { 1103 FMT_TYPE_OUTPUT);
1104 if (!fmt) {
733 v4l2_err(&ctx->jpeg->v4l2_dev, 1105 v4l2_err(&ctx->jpeg->v4l2_dev,
734 "Fourcc format (0x%08x) invalid.\n", 1106 "Fourcc format (0x%08x) invalid.\n",
735 f->fmt.pix.pixelformat); 1107 f->fmt.pix.pixelformat);
736 return -EINVAL; 1108 return -EINVAL;
737 } 1109 }
738 1110
739 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT); 1111 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
740} 1112}
741 1113
742static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) 1114static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
@@ -744,8 +1116,10 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
744 struct vb2_queue *vq; 1116 struct vb2_queue *vq;
745 struct s5p_jpeg_q_data *q_data = NULL; 1117 struct s5p_jpeg_q_data *q_data = NULL;
746 struct v4l2_pix_format *pix = &f->fmt.pix; 1118 struct v4l2_pix_format *pix = &f->fmt.pix;
1119 struct v4l2_ctrl *ctrl_subs;
1120 unsigned int f_type;
747 1121
748 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type); 1122 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
749 if (!vq) 1123 if (!vq)
750 return -EINVAL; 1124 return -EINVAL;
751 1125
@@ -757,7 +1131,10 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
757 return -EBUSY; 1131 return -EBUSY;
758 } 1132 }
759 1133
760 q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat); 1134 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1135 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1136
1137 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
761 q_data->w = pix->width; 1138 q_data->w = pix->width;
762 q_data->h = pix->height; 1139 q_data->h = pix->height;
763 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) 1140 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
@@ -765,6 +1142,13 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
765 else 1142 else
766 q_data->size = pix->sizeimage; 1143 q_data->size = pix->sizeimage;
767 1144
1145 if (f_type == FMT_TYPE_OUTPUT) {
1146 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1147 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1148 if (ctrl_subs)
1149 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1150 }
1151
768 return 0; 1152 return 0;
769} 1153}
770 1154
@@ -792,60 +1176,14 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
792 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); 1176 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
793} 1177}
794 1178
795static int s5p_jpeg_reqbufs(struct file *file, void *priv,
796 struct v4l2_requestbuffers *reqbufs)
797{
798 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
799
800 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
801}
802
803static int s5p_jpeg_querybuf(struct file *file, void *priv,
804 struct v4l2_buffer *buf)
805{
806 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
807
808 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
809}
810
811static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
812{
813 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
814
815 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
816}
817
818static int s5p_jpeg_dqbuf(struct file *file, void *priv,
819 struct v4l2_buffer *buf)
820{
821 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
822
823 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
824}
825
826static int s5p_jpeg_streamon(struct file *file, void *priv,
827 enum v4l2_buf_type type)
828{
829 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
830
831 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
832}
833
834static int s5p_jpeg_streamoff(struct file *file, void *priv,
835 enum v4l2_buf_type type)
836{
837 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
838
839 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
840}
841
842static int s5p_jpeg_g_selection(struct file *file, void *priv, 1179static int s5p_jpeg_g_selection(struct file *file, void *priv,
843 struct v4l2_selection *s) 1180 struct v4l2_selection *s)
844{ 1181{
845 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 1182 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
846 1183
847 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 1184 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
848 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1185 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1186 ctx->jpeg->variant->version != SJPEG_S5P)
849 return -EINVAL; 1187 return -EINVAL;
850 1188
851 /* For JPEG blob active == default == bounds */ 1189 /* For JPEG blob active == default == bounds */
@@ -884,12 +1222,7 @@ static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
884 switch (ctrl->id) { 1222 switch (ctrl->id) {
885 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: 1223 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
886 spin_lock_irqsave(&jpeg->slock, flags); 1224 spin_lock_irqsave(&jpeg->slock, flags);
887 1225 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
888 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
889 if (ctx->subsampling > 2)
890 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
891 else
892 ctrl->val = ctx->subsampling;
893 spin_unlock_irqrestore(&jpeg->slock, flags); 1226 spin_unlock_irqrestore(&jpeg->slock, flags);
894 break; 1227 break;
895 } 1228 }
@@ -897,6 +1230,40 @@ static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
897 return 0; 1230 return 0;
898} 1231}
899 1232
1233static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1234{
1235 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1236 unsigned long flags;
1237 int ret = 0;
1238
1239 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1240
1241 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) {
1242 if (ctx->jpeg->variant->version == SJPEG_S5P)
1243 goto error_free;
1244 /*
1245 * The exynos4x12 device requires input raw image fourcc
1246 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1247 * is to be set.
1248 */
1249 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1250 ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
1251 ret = -EINVAL;
1252 goto error_free;
1253 }
1254 /*
1255 * The exynos4x12 device requires resulting jpeg subsampling
1256 * not to be lower than the input raw image subsampling.
1257 */
1258 if (ctx->out_q.fmt->subsampling > ctrl->val)
1259 ctrl->val = ctx->out_q.fmt->subsampling;
1260 }
1261
1262error_free:
1263 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1264 return ret;
1265}
1266
900static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) 1267static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
901{ 1268{
902 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); 1269 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
@@ -906,7 +1273,7 @@ static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
906 1273
907 switch (ctrl->id) { 1274 switch (ctrl->id) {
908 case V4L2_CID_JPEG_COMPRESSION_QUALITY: 1275 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
909 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val; 1276 ctx->compr_quality = ctrl->val;
910 break; 1277 break;
911 case V4L2_CID_JPEG_RESTART_INTERVAL: 1278 case V4L2_CID_JPEG_RESTART_INTERVAL:
912 ctx->restart_interval = ctrl->val; 1279 ctx->restart_interval = ctrl->val;
@@ -922,6 +1289,7 @@ static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
922 1289
923static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = { 1290static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
924 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl, 1291 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1292 .try_ctrl = s5p_jpeg_try_ctrl,
925 .s_ctrl = s5p_jpeg_s_ctrl, 1293 .s_ctrl = s5p_jpeg_s_ctrl,
926}; 1294};
927 1295
@@ -929,18 +1297,20 @@ static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
929{ 1297{
930 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */ 1298 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
931 struct v4l2_ctrl *ctrl; 1299 struct v4l2_ctrl *ctrl;
1300 int ret;
932 1301
933 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3); 1302 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
934 1303
935 if (ctx->mode == S5P_JPEG_ENCODE) { 1304 if (ctx->mode == S5P_JPEG_ENCODE) {
936 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, 1305 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
937 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1306 V4L2_CID_JPEG_COMPRESSION_QUALITY,
938 0, 3, 1, 3); 1307 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
939 1308
940 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, 1309 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
941 V4L2_CID_JPEG_RESTART_INTERVAL, 1310 V4L2_CID_JPEG_RESTART_INTERVAL,
942 0, 3, 0xffff, 0); 1311 0, 3, 0xffff, 0);
943 mask = ~0x06; /* 422, 420 */ 1312 if (ctx->jpeg->variant->version == SJPEG_S5P)
1313 mask = ~0x06; /* 422, 420 */
944 } 1314 }
945 1315
946 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, 1316 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
@@ -948,13 +1318,24 @@ static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
948 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask, 1318 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
949 V4L2_JPEG_CHROMA_SUBSAMPLING_422); 1319 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
950 1320
951 if (ctx->ctrl_handler.error) 1321 if (ctx->ctrl_handler.error) {
952 return ctx->ctrl_handler.error; 1322 ret = ctx->ctrl_handler.error;
1323 goto error_free;
1324 }
953 1325
954 if (ctx->mode == S5P_JPEG_DECODE) 1326 if (ctx->mode == S5P_JPEG_DECODE)
955 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE | 1327 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
956 V4L2_CTRL_FLAG_READ_ONLY; 1328 V4L2_CTRL_FLAG_READ_ONLY;
957 return 0; 1329
1330 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1331 if (ret < 0)
1332 goto error_free;
1333
1334 return ret;
1335
1336error_free:
1337 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1338 return ret;
958} 1339}
959 1340
960static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = { 1341static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
@@ -972,14 +1353,13 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
972 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap, 1353 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
973 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out, 1354 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
974 1355
975 .vidioc_reqbufs = s5p_jpeg_reqbufs, 1356 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
976 .vidioc_querybuf = s5p_jpeg_querybuf, 1357 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1358 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1359 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
977 1360
978 .vidioc_qbuf = s5p_jpeg_qbuf, 1361 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
979 .vidioc_dqbuf = s5p_jpeg_dqbuf, 1362 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
980
981 .vidioc_streamon = s5p_jpeg_streamon,
982 .vidioc_streamoff = s5p_jpeg_streamoff,
983 1363
984 .vidioc_g_selection = s5p_jpeg_g_selection, 1364 .vidioc_g_selection = s5p_jpeg_g_selection,
985}; 1365};
@@ -995,74 +1375,181 @@ static void s5p_jpeg_device_run(void *priv)
995 struct s5p_jpeg_ctx *ctx = priv; 1375 struct s5p_jpeg_ctx *ctx = priv;
996 struct s5p_jpeg *jpeg = ctx->jpeg; 1376 struct s5p_jpeg *jpeg = ctx->jpeg;
997 struct vb2_buffer *src_buf, *dst_buf; 1377 struct vb2_buffer *src_buf, *dst_buf;
998 unsigned long src_addr, dst_addr; 1378 unsigned long src_addr, dst_addr, flags;
1379
1380 spin_lock_irqsave(&ctx->jpeg->slock, flags);
999 1381
1000 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 1382 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1001 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 1383 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1002 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); 1384 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1003 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); 1385 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1004 1386
1005 jpeg_reset(jpeg->regs); 1387 s5p_jpeg_reset(jpeg->regs);
1006 jpeg_poweron(jpeg->regs); 1388 s5p_jpeg_poweron(jpeg->regs);
1007 jpeg_proc_mode(jpeg->regs, ctx->mode); 1389 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1008 if (ctx->mode == S5P_JPEG_ENCODE) { 1390 if (ctx->mode == S5P_JPEG_ENCODE) {
1009 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565) 1391 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1010 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565); 1392 s5p_jpeg_input_raw_mode(jpeg->regs,
1393 S5P_JPEG_RAW_IN_565);
1011 else 1394 else
1012 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422); 1395 s5p_jpeg_input_raw_mode(jpeg->regs,
1013 jpeg_subsampling_mode(jpeg->regs, ctx->subsampling); 1396 S5P_JPEG_RAW_IN_422);
1014 jpeg_dri(jpeg->regs, ctx->restart_interval); 1397 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1015 jpeg_x(jpeg->regs, ctx->out_q.w); 1398 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1016 jpeg_y(jpeg->regs, ctx->out_q.h); 1399 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1017 jpeg_imgadr(jpeg->regs, src_addr); 1400 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1018 jpeg_jpgadr(jpeg->regs, dst_addr); 1401 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1402 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1019 1403
1020 /* ultimately comes from sizeimage from userspace */ 1404 /* ultimately comes from sizeimage from userspace */
1021 jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size); 1405 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1022 1406
1023 /* JPEG RGB to YCbCr conversion matrix */ 1407 /* JPEG RGB to YCbCr conversion matrix */
1024 jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11); 1408 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1025 jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12); 1409 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1026 jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13); 1410 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1027 jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21); 1411 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1028 jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22); 1412 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1029 jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23); 1413 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1030 jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31); 1414 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1031 jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32); 1415 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1032 jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33); 1416 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1033 1417
1034 /* 1418 /*
1035 * JPEG IP allows storing 4 quantization tables 1419 * JPEG IP allows storing 4 quantization tables
1036 * We fill table 0 for luma and table 1 for chroma 1420 * We fill table 0 for luma and table 1 for chroma
1037 */ 1421 */
1038 jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality); 1422 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1039 jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality); 1423 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1040 /* use table 0 for Y */ 1424 /* use table 0 for Y */
1041 jpeg_qtbl(jpeg->regs, 1, 0); 1425 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1042 /* use table 1 for Cb and Cr*/ 1426 /* use table 1 for Cb and Cr*/
1043 jpeg_qtbl(jpeg->regs, 2, 1); 1427 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1044 jpeg_qtbl(jpeg->regs, 3, 1); 1428 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1045 1429
1046 /* Y, Cb, Cr use Huffman table 0 */ 1430 /* Y, Cb, Cr use Huffman table 0 */
1047 jpeg_htbl_ac(jpeg->regs, 1); 1431 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1048 jpeg_htbl_dc(jpeg->regs, 1); 1432 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1049 jpeg_htbl_ac(jpeg->regs, 2); 1433 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1050 jpeg_htbl_dc(jpeg->regs, 2); 1434 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1051 jpeg_htbl_ac(jpeg->regs, 3); 1435 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1052 jpeg_htbl_dc(jpeg->regs, 3); 1436 s5p_jpeg_htbl_dc(jpeg->regs, 3);
1053 } else { /* S5P_JPEG_DECODE */ 1437 } else { /* S5P_JPEG_DECODE */
1054 jpeg_rst_int_enable(jpeg->regs, true); 1438 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1055 jpeg_data_num_int_enable(jpeg->regs, true); 1439 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1056 jpeg_final_mcu_num_int_enable(jpeg->regs, true); 1440 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1057 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV) 1441 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1058 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422); 1442 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1059 else 1443 else
1060 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420); 1444 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1061 jpeg_jpgadr(jpeg->regs, src_addr); 1445 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1062 jpeg_imgadr(jpeg->regs, dst_addr); 1446 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1063 } 1447 }
1064 1448
1065 jpeg_start(jpeg->regs); 1449 s5p_jpeg_start(jpeg->regs);
1450
1451 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1452}
1453
1454static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1455{
1456 struct s5p_jpeg *jpeg = ctx->jpeg;
1457 struct s5p_jpeg_fmt *fmt;
1458 struct vb2_buffer *vb;
1459 struct s5p_jpeg_addr jpeg_addr;
1460 u32 pix_size, padding_bytes = 0;
1461
1462 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1463
1464 if (ctx->mode == S5P_JPEG_ENCODE) {
1465 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1466 fmt = ctx->out_q.fmt;
1467 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1468 padding_bytes = ctx->out_q.h;
1469 } else {
1470 fmt = ctx->cap_q.fmt;
1471 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1472 }
1473
1474 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1475
1476 if (fmt->colplanes == 2) {
1477 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1478 } else if (fmt->colplanes == 3) {
1479 jpeg_addr.cb = jpeg_addr.y + pix_size;
1480 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1481 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1482 else
1483 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1484 }
1485
1486 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1487}
1488
1489static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1490{
1491 struct s5p_jpeg *jpeg = ctx->jpeg;
1492 struct vb2_buffer *vb;
1493 unsigned int jpeg_addr = 0;
1494
1495 if (ctx->mode == S5P_JPEG_ENCODE)
1496 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1497 else
1498 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1499
1500 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1501 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1502}
1503
1504static void exynos4_jpeg_device_run(void *priv)
1505{
1506 struct s5p_jpeg_ctx *ctx = priv;
1507 struct s5p_jpeg *jpeg = ctx->jpeg;
1508 unsigned int bitstream_size;
1509 unsigned long flags;
1510
1511 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1512
1513 if (ctx->mode == S5P_JPEG_ENCODE) {
1514 exynos4_jpeg_sw_reset(jpeg->regs);
1515 exynos4_jpeg_set_interrupt(jpeg->regs);
1516 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1517
1518 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1519
1520 /*
1521 * JPEG IP allows storing 4 quantization tables
1522 * We fill table 0 for luma and table 1 for chroma
1523 */
1524 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1525 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1526
1527 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1528 ctx->compr_quality);
1529 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1530 ctx->cap_q.h);
1531
1532 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1533 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1534 exynos4_jpeg_set_img_addr(ctx);
1535 exynos4_jpeg_set_jpeg_addr(ctx);
1536 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1537 ctx->out_q.fmt->fourcc);
1538 } else {
1539 exynos4_jpeg_sw_reset(jpeg->regs);
1540 exynos4_jpeg_set_interrupt(jpeg->regs);
1541 exynos4_jpeg_set_img_addr(ctx);
1542 exynos4_jpeg_set_jpeg_addr(ctx);
1543 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1544
1545 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1546
1547 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1548 }
1549
1550 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1551
1552 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1066} 1553}
1067 1554
1068static int s5p_jpeg_job_ready(void *priv) 1555static int s5p_jpeg_job_ready(void *priv)
@@ -1082,6 +1569,12 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1082 .device_run = s5p_jpeg_device_run, 1569 .device_run = s5p_jpeg_device_run,
1083 .job_ready = s5p_jpeg_job_ready, 1570 .job_ready = s5p_jpeg_job_ready,
1084 .job_abort = s5p_jpeg_job_abort, 1571 .job_abort = s5p_jpeg_job_abort,
1572}
1573;
1574static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1575 .device_run = exynos4_jpeg_device_run,
1576 .job_ready = s5p_jpeg_job_ready,
1577 .job_abort = s5p_jpeg_job_abort,
1085}; 1578};
1086 1579
1087/* 1580/*
@@ -1149,7 +1642,7 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1149 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp, 1642 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1150 (unsigned long)vb2_plane_vaddr(vb, 0), 1643 (unsigned long)vb2_plane_vaddr(vb, 0),
1151 min((unsigned long)ctx->out_q.size, 1644 min((unsigned long)ctx->out_q.size,
1152 vb2_get_plane_payload(vb, 0))); 1645 vb2_get_plane_payload(vb, 0)), ctx);
1153 if (!ctx->hdr_parsed) { 1646 if (!ctx->hdr_parsed) {
1154 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); 1647 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1155 return; 1648 return;
@@ -1162,30 +1655,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1162 q_data = &ctx->cap_q; 1655 q_data = &ctx->cap_q;
1163 q_data->w = tmp.w; 1656 q_data->w = tmp.w;
1164 q_data->h = tmp.h; 1657 q_data->h = tmp.h;
1165
1166 jpeg_bound_align_image(&q_data->w, S5P_JPEG_MIN_WIDTH,
1167 S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1168 &q_data->h, S5P_JPEG_MIN_HEIGHT,
1169 S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
1170 );
1171 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1172 } 1658 }
1173 if (ctx->m2m_ctx)
1174 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
1175}
1176
1177static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
1178{
1179 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1180 1659
1181 mutex_unlock(&ctx->jpeg->lock); 1660 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
1182}
1183
1184static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
1185{
1186 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1187
1188 mutex_lock(&ctx->jpeg->lock);
1189} 1661}
1190 1662
1191static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) 1663static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
@@ -1211,8 +1683,8 @@ static struct vb2_ops s5p_jpeg_qops = {
1211 .queue_setup = s5p_jpeg_queue_setup, 1683 .queue_setup = s5p_jpeg_queue_setup,
1212 .buf_prepare = s5p_jpeg_buf_prepare, 1684 .buf_prepare = s5p_jpeg_buf_prepare,
1213 .buf_queue = s5p_jpeg_buf_queue, 1685 .buf_queue = s5p_jpeg_buf_queue,
1214 .wait_prepare = s5p_jpeg_wait_prepare, 1686 .wait_prepare = vb2_ops_wait_prepare,
1215 .wait_finish = s5p_jpeg_wait_finish, 1687 .wait_finish = vb2_ops_wait_finish,
1216 .start_streaming = s5p_jpeg_start_streaming, 1688 .start_streaming = s5p_jpeg_start_streaming,
1217 .stop_streaming = s5p_jpeg_stop_streaming, 1689 .stop_streaming = s5p_jpeg_stop_streaming,
1218}; 1690};
@@ -1230,6 +1702,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
1230 src_vq->ops = &s5p_jpeg_qops; 1702 src_vq->ops = &s5p_jpeg_qops;
1231 src_vq->mem_ops = &vb2_dma_contig_memops; 1703 src_vq->mem_ops = &vb2_dma_contig_memops;
1232 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1704 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1705 src_vq->lock = &ctx->jpeg->lock;
1233 1706
1234 ret = vb2_queue_init(src_vq); 1707 ret = vb2_queue_init(src_vq);
1235 if (ret) 1708 if (ret)
@@ -1242,6 +1715,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
1242 dst_vq->ops = &s5p_jpeg_qops; 1715 dst_vq->ops = &s5p_jpeg_qops;
1243 dst_vq->mem_ops = &vb2_dma_contig_memops; 1716 dst_vq->mem_ops = &vb2_dma_contig_memops;
1244 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1717 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1718 dst_vq->lock = &ctx->jpeg->lock;
1245 1719
1246 return vb2_queue_init(dst_vq); 1720 return vb2_queue_init(dst_vq);
1247} 1721}
@@ -1267,26 +1741,27 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1267 1741
1268 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); 1742 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1269 1743
1270 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); 1744 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1271 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); 1745 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1272 1746
1273 if (curr_ctx->mode == S5P_JPEG_ENCODE) 1747 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1274 enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs); 1748 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1275 timer_elapsed = jpeg_timer_stat(jpeg->regs); 1749 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1276 op_completed = jpeg_result_stat_ok(jpeg->regs); 1750 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
1277 if (curr_ctx->mode == S5P_JPEG_DECODE) 1751 if (curr_ctx->mode == S5P_JPEG_DECODE)
1278 op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs); 1752 op_completed = op_completed &&
1753 s5p_jpeg_stream_stat_ok(jpeg->regs);
1279 1754
1280 if (enc_jpeg_too_large) { 1755 if (enc_jpeg_too_large) {
1281 state = VB2_BUF_STATE_ERROR; 1756 state = VB2_BUF_STATE_ERROR;
1282 jpeg_clear_enc_stream_stat(jpeg->regs); 1757 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
1283 } else if (timer_elapsed) { 1758 } else if (timer_elapsed) {
1284 state = VB2_BUF_STATE_ERROR; 1759 state = VB2_BUF_STATE_ERROR;
1285 jpeg_clear_timer_stat(jpeg->regs); 1760 s5p_jpeg_clear_timer_stat(jpeg->regs);
1286 } else if (!op_completed) { 1761 } else if (!op_completed) {
1287 state = VB2_BUF_STATE_ERROR; 1762 state = VB2_BUF_STATE_ERROR;
1288 } else { 1763 } else {
1289 payload_size = jpeg_compressed_size(jpeg->regs); 1764 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
1290 } 1765 }
1291 1766
1292 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode; 1767 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
@@ -1296,16 +1771,79 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1296 if (curr_ctx->mode == S5P_JPEG_ENCODE) 1771 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1297 vb2_set_plane_payload(dst_buf, 0, payload_size); 1772 vb2_set_plane_payload(dst_buf, 0, payload_size);
1298 v4l2_m2m_buf_done(dst_buf, state); 1773 v4l2_m2m_buf_done(dst_buf, state);
1299 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx); 1774 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1300 1775
1301 curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs); 1776 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
1302 spin_unlock(&jpeg->slock); 1777 spin_unlock(&jpeg->slock);
1303 1778
1304 jpeg_clear_int(jpeg->regs); 1779 s5p_jpeg_clear_int(jpeg->regs);
1305 1780
1306 return IRQ_HANDLED; 1781 return IRQ_HANDLED;
1307} 1782}
1308 1783
1784static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1785{
1786 unsigned int int_status;
1787 struct vb2_buffer *src_vb, *dst_vb;
1788 struct s5p_jpeg *jpeg = priv;
1789 struct s5p_jpeg_ctx *curr_ctx;
1790 unsigned long payload_size = 0;
1791
1792 spin_lock(&jpeg->slock);
1793
1794 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1795
1796 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1797 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1798
1799 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1800
1801 if (int_status) {
1802 switch (int_status & 0x1f) {
1803 case 0x1:
1804 jpeg->irq_ret = ERR_PROT;
1805 break;
1806 case 0x2:
1807 jpeg->irq_ret = OK_ENC_OR_DEC;
1808 break;
1809 case 0x4:
1810 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1811 break;
1812 case 0x8:
1813 jpeg->irq_ret = ERR_MULTI_SCAN;
1814 break;
1815 case 0x10:
1816 jpeg->irq_ret = ERR_FRAME;
1817 break;
1818 default:
1819 jpeg->irq_ret = ERR_UNKNOWN;
1820 break;
1821 }
1822 } else {
1823 jpeg->irq_ret = ERR_UNKNOWN;
1824 }
1825
1826 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1827 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1828 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1829 vb2_set_plane_payload(dst_vb, 0, payload_size);
1830 }
1831 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1832 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1833 } else {
1834 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1835 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1836 }
1837
1838 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1839 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1840
1841 spin_unlock(&jpeg->slock);
1842 return IRQ_HANDLED;
1843}
1844
1845static void *jpeg_get_drv_data(struct platform_device *pdev);
1846
1309/* 1847/*
1310 * ============================================================================ 1848 * ============================================================================
1311 * Driver basic infrastructure 1849 * Driver basic infrastructure
@@ -1316,13 +1854,19 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1316{ 1854{
1317 struct s5p_jpeg *jpeg; 1855 struct s5p_jpeg *jpeg;
1318 struct resource *res; 1856 struct resource *res;
1857 struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
1319 int ret; 1858 int ret;
1320 1859
1860 if (!pdev->dev.of_node)
1861 return -ENODEV;
1862
1321 /* JPEG IP abstraction struct */ 1863 /* JPEG IP abstraction struct */
1322 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL); 1864 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1323 if (!jpeg) 1865 if (!jpeg)
1324 return -ENOMEM; 1866 return -ENOMEM;
1325 1867
1868 jpeg->variant = jpeg_get_drv_data(pdev);
1869
1326 mutex_init(&jpeg->lock); 1870 mutex_init(&jpeg->lock);
1327 spin_lock_init(&jpeg->slock); 1871 spin_lock_init(&jpeg->slock);
1328 jpeg->dev = &pdev->dev; 1872 jpeg->dev = &pdev->dev;
@@ -1341,8 +1885,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1341 return ret; 1885 return ret;
1342 } 1886 }
1343 1887
1344 ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0, 1888 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1345 dev_name(&pdev->dev), jpeg); 1889 0, dev_name(&pdev->dev), jpeg);
1346 if (ret) { 1890 if (ret) {
1347 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq); 1891 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1348 return ret; 1892 return ret;
@@ -1356,7 +1900,6 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1356 return ret; 1900 return ret;
1357 } 1901 }
1358 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk); 1902 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1359 clk_prepare_enable(jpeg->clk);
1360 1903
1361 /* v4l2 device */ 1904 /* v4l2 device */
1362 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev); 1905 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
@@ -1365,8 +1908,13 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1365 goto clk_get_rollback; 1908 goto clk_get_rollback;
1366 } 1909 }
1367 1910
1911 if (jpeg->variant->version == SJPEG_S5P)
1912 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1913 else
1914 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1915
1368 /* mem2mem device */ 1916 /* mem2mem device */
1369 jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops); 1917 jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
1370 if (IS_ERR(jpeg->m2m_dev)) { 1918 if (IS_ERR(jpeg->m2m_dev)) {
1371 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); 1919 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1372 ret = PTR_ERR(jpeg->m2m_dev); 1920 ret = PTR_ERR(jpeg->m2m_dev);
@@ -1387,8 +1935,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1387 ret = -ENOMEM; 1935 ret = -ENOMEM;
1388 goto vb2_allocator_rollback; 1936 goto vb2_allocator_rollback;
1389 } 1937 }
1390 strlcpy(jpeg->vfd_encoder->name, S5P_JPEG_M2M_NAME, 1938 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1391 sizeof(jpeg->vfd_encoder->name)); 1939 "%s-enc", S5P_JPEG_M2M_NAME);
1392 jpeg->vfd_encoder->fops = &s5p_jpeg_fops; 1940 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1393 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops; 1941 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1394 jpeg->vfd_encoder->minor = -1; 1942 jpeg->vfd_encoder->minor = -1;
@@ -1415,8 +1963,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1415 ret = -ENOMEM; 1963 ret = -ENOMEM;
1416 goto enc_vdev_register_rollback; 1964 goto enc_vdev_register_rollback;
1417 } 1965 }
1418 strlcpy(jpeg->vfd_decoder->name, S5P_JPEG_M2M_NAME, 1966 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1419 sizeof(jpeg->vfd_decoder->name)); 1967 "%s-dec", S5P_JPEG_M2M_NAME);
1420 jpeg->vfd_decoder->fops = &s5p_jpeg_fops; 1968 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1421 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops; 1969 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1422 jpeg->vfd_decoder->minor = -1; 1970 jpeg->vfd_decoder->minor = -1;
@@ -1464,7 +2012,6 @@ device_register_rollback:
1464 v4l2_device_unregister(&jpeg->v4l2_dev); 2012 v4l2_device_unregister(&jpeg->v4l2_dev);
1465 2013
1466clk_get_rollback: 2014clk_get_rollback:
1467 clk_disable_unprepare(jpeg->clk);
1468 clk_put(jpeg->clk); 2015 clk_put(jpeg->clk);
1469 2016
1470 return ret; 2017 return ret;
@@ -1484,7 +2031,9 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
1484 v4l2_m2m_release(jpeg->m2m_dev); 2031 v4l2_m2m_release(jpeg->m2m_dev);
1485 v4l2_device_unregister(&jpeg->v4l2_dev); 2032 v4l2_device_unregister(&jpeg->v4l2_dev);
1486 2033
1487 clk_disable_unprepare(jpeg->clk); 2034 if (!pm_runtime_status_suspended(&pdev->dev))
2035 clk_disable_unprepare(jpeg->clk);
2036
1488 clk_put(jpeg->clk); 2037 clk_put(jpeg->clk);
1489 2038
1490 return 0; 2039 return 0;
@@ -1492,41 +2041,119 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
1492 2041
1493static int s5p_jpeg_runtime_suspend(struct device *dev) 2042static int s5p_jpeg_runtime_suspend(struct device *dev)
1494{ 2043{
2044 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2045
2046 clk_disable_unprepare(jpeg->clk);
2047
1495 return 0; 2048 return 0;
1496} 2049}
1497 2050
1498static int s5p_jpeg_runtime_resume(struct device *dev) 2051static int s5p_jpeg_runtime_resume(struct device *dev)
1499{ 2052{
1500 struct s5p_jpeg *jpeg = dev_get_drvdata(dev); 2053 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2054 unsigned long flags;
2055 int ret;
2056
2057 ret = clk_prepare_enable(jpeg->clk);
2058 if (ret < 0)
2059 return ret;
2060
2061 spin_lock_irqsave(&jpeg->slock, flags);
2062
1501 /* 2063 /*
1502 * JPEG IP allows storing two Huffman tables for each component 2064 * JPEG IP allows storing two Huffman tables for each component
1503 * We fill table 0 for each component 2065 * We fill table 0 for each component and do this here only
2066 * for S5PC210 device as Exynos4x12 requires programming its
2067 * Huffman tables each time the encoding process is initialized.
1504 */ 2068 */
1505 jpeg_set_hdctbl(jpeg->regs); 2069 if (jpeg->variant->version == SJPEG_S5P) {
1506 jpeg_set_hdctblg(jpeg->regs); 2070 s5p_jpeg_set_hdctbl(jpeg->regs);
1507 jpeg_set_hactbl(jpeg->regs); 2071 s5p_jpeg_set_hdctblg(jpeg->regs);
1508 jpeg_set_hactblg(jpeg->regs); 2072 s5p_jpeg_set_hactbl(jpeg->regs);
2073 s5p_jpeg_set_hactblg(jpeg->regs);
2074 }
2075
2076 spin_unlock_irqrestore(&jpeg->slock, flags);
2077
1509 return 0; 2078 return 0;
1510} 2079}
1511 2080
2081static int s5p_jpeg_suspend(struct device *dev)
2082{
2083 if (pm_runtime_suspended(dev))
2084 return 0;
2085
2086 return s5p_jpeg_runtime_suspend(dev);
2087}
2088
2089static int s5p_jpeg_resume(struct device *dev)
2090{
2091 if (pm_runtime_suspended(dev))
2092 return 0;
2093
2094 return s5p_jpeg_runtime_resume(dev);
2095}
2096
1512static const struct dev_pm_ops s5p_jpeg_pm_ops = { 2097static const struct dev_pm_ops s5p_jpeg_pm_ops = {
1513 .runtime_suspend = s5p_jpeg_runtime_suspend, 2098 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
1514 .runtime_resume = s5p_jpeg_runtime_resume, 2099 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
2100};
2101
2102#ifdef CONFIG_OF
2103static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2104 .version = SJPEG_S5P,
2105 .jpeg_irq = s5p_jpeg_irq,
2106};
2107
2108static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2109 .version = SJPEG_EXYNOS4,
2110 .jpeg_irq = exynos4_jpeg_irq,
2111};
2112
2113static const struct of_device_id samsung_jpeg_match[] = {
2114 {
2115 .compatible = "samsung,s5pv210-jpeg",
2116 .data = &s5p_jpeg_drvdata,
2117 }, {
2118 .compatible = "samsung,exynos4210-jpeg",
2119 .data = &s5p_jpeg_drvdata,
2120 }, {
2121 .compatible = "samsung,exynos4212-jpeg",
2122 .data = &exynos4_jpeg_drvdata,
2123 },
2124 {},
1515}; 2125};
1516 2126
2127MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2128
2129static void *jpeg_get_drv_data(struct platform_device *pdev)
2130{
2131 struct s5p_jpeg_variant *driver_data = NULL;
2132 const struct of_device_id *match;
2133
2134 match = of_match_node(of_match_ptr(samsung_jpeg_match),
2135 pdev->dev.of_node);
2136 if (match)
2137 driver_data = (struct s5p_jpeg_variant *)match->data;
2138
2139 return driver_data;
2140}
2141#endif
2142
1517static struct platform_driver s5p_jpeg_driver = { 2143static struct platform_driver s5p_jpeg_driver = {
1518 .probe = s5p_jpeg_probe, 2144 .probe = s5p_jpeg_probe,
1519 .remove = s5p_jpeg_remove, 2145 .remove = s5p_jpeg_remove,
1520 .driver = { 2146 .driver = {
1521 .owner = THIS_MODULE, 2147 .of_match_table = of_match_ptr(samsung_jpeg_match),
1522 .name = S5P_JPEG_M2M_NAME, 2148 .owner = THIS_MODULE,
1523 .pm = &s5p_jpeg_pm_ops, 2149 .name = S5P_JPEG_M2M_NAME,
2150 .pm = &s5p_jpeg_pm_ops,
1524 }, 2151 },
1525}; 2152};
1526 2153
1527module_platform_driver(s5p_jpeg_driver); 2154module_platform_driver(s5p_jpeg_driver);
1528 2155
1529MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>"); 2156MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
2157MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
1530MODULE_DESCRIPTION("Samsung JPEG codec driver"); 2158MODULE_DESCRIPTION("Samsung JPEG codec driver");
1531MODULE_LICENSE("GPL"); 2159MODULE_LICENSE("GPL");
1532
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 8a4013e3aee7..f482dbf55d5f 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -13,6 +13,7 @@
13#ifndef JPEG_CORE_H_ 13#ifndef JPEG_CORE_H_
14#define JPEG_CORE_H_ 14#define JPEG_CORE_H_
15 15
16#include <linux/interrupt.h>
16#include <media/v4l2-device.h> 17#include <media/v4l2-device.h>
17#include <media/v4l2-fh.h> 18#include <media/v4l2-fh.h>
18#include <media/v4l2-ctrls.h> 19#include <media/v4l2-ctrls.h>
@@ -43,8 +44,45 @@
43#define DHP 0xde 44#define DHP 0xde
44 45
45/* Flags that indicate a format can be used for capture/output */ 46/* Flags that indicate a format can be used for capture/output */
46#define MEM2MEM_CAPTURE (1 << 0) 47#define SJPEG_FMT_FLAG_ENC_CAPTURE (1 << 0)
47#define MEM2MEM_OUTPUT (1 << 1) 48#define SJPEG_FMT_FLAG_ENC_OUTPUT (1 << 1)
49#define SJPEG_FMT_FLAG_DEC_CAPTURE (1 << 2)
50#define SJPEG_FMT_FLAG_DEC_OUTPUT (1 << 3)
51#define SJPEG_FMT_FLAG_S5P (1 << 4)
52#define SJPEG_FMT_FLAG_EXYNOS4 (1 << 5)
53#define SJPEG_FMT_RGB (1 << 6)
54#define SJPEG_FMT_NON_RGB (1 << 7)
55
56#define S5P_JPEG_ENCODE 0
57#define S5P_JPEG_DECODE 1
58
59#define FMT_TYPE_OUTPUT 0
60#define FMT_TYPE_CAPTURE 1
61
62#define SJPEG_SUBSAMPLING_444 0x11
63#define SJPEG_SUBSAMPLING_422 0x21
64#define SJPEG_SUBSAMPLING_420 0x22
65
66/* Version numbers */
67
68#define SJPEG_S5P 1
69#define SJPEG_EXYNOS4 2
70
71enum exynos4_jpeg_result {
72 OK_ENC_OR_DEC,
73 ERR_PROT,
74 ERR_DEC_INVALID_FORMAT,
75 ERR_MULTI_SCAN,
76 ERR_FRAME,
77 ERR_UNKNOWN,
78};
79
80enum exynos4_jpeg_img_quality_level {
81 QUALITY_LEVEL_1 = 0, /* high */
82 QUALITY_LEVEL_2,
83 QUALITY_LEVEL_3,
84 QUALITY_LEVEL_4, /* low */
85};
48 86
49/** 87/**
50 * struct s5p_jpeg - JPEG IP abstraction 88 * struct s5p_jpeg - JPEG IP abstraction
@@ -71,9 +109,16 @@ struct s5p_jpeg {
71 109
72 void __iomem *regs; 110 void __iomem *regs;
73 unsigned int irq; 111 unsigned int irq;
112 enum exynos4_jpeg_result irq_ret;
74 struct clk *clk; 113 struct clk *clk;
75 struct device *dev; 114 struct device *dev;
76 void *alloc_ctx; 115 void *alloc_ctx;
116 struct s5p_jpeg_variant *variant;
117};
118
119struct s5p_jpeg_variant {
120 unsigned int version;
121 irqreturn_t (*jpeg_irq)(int irq, void *priv);
77}; 122};
78 123
79/** 124/**
@@ -84,16 +129,18 @@ struct s5p_jpeg {
84 * @colplanes: number of color planes (1 for packed formats) 129 * @colplanes: number of color planes (1 for packed formats)
85 * @h_align: horizontal alignment order (align to 2^h_align) 130 * @h_align: horizontal alignment order (align to 2^h_align)
86 * @v_align: vertical alignment order (align to 2^v_align) 131 * @v_align: vertical alignment order (align to 2^v_align)
87 * @types: types of queue this format is applicable to 132 * @flags: flags describing format applicability
88 */ 133 */
89struct s5p_jpeg_fmt { 134struct s5p_jpeg_fmt {
90 char *name; 135 char *name;
91 u32 fourcc; 136 u32 fourcc;
92 int depth; 137 int depth;
93 int colplanes; 138 int colplanes;
139 int memplanes;
94 int h_align; 140 int h_align;
95 int v_align; 141 int v_align;
96 u32 types; 142 int subsampling;
143 u32 flags;
97}; 144};
98 145
99/** 146/**
@@ -115,7 +162,6 @@ struct s5p_jpeg_q_data {
115 * @jpeg: JPEG IP device for this context 162 * @jpeg: JPEG IP device for this context
116 * @mode: compression (encode) operation or decompression (decode) 163 * @mode: compression (encode) operation or decompression (decode)
117 * @compr_quality: destination image quality in compression (encode) mode 164 * @compr_quality: destination image quality in compression (encode) mode
118 * @m2m_ctx: mem2mem device context
119 * @out_q: source (output) queue information 165 * @out_q: source (output) queue information
120 * @cap_fmt: destination (capture) queue queue information 166 * @cap_fmt: destination (capture) queue queue information
121 * @hdr_parsed: set if header has been parsed during decompression 167 * @hdr_parsed: set if header has been parsed during decompression
@@ -127,7 +173,6 @@ struct s5p_jpeg_ctx {
127 unsigned short compr_quality; 173 unsigned short compr_quality;
128 unsigned short restart_interval; 174 unsigned short restart_interval;
129 unsigned short subsampling; 175 unsigned short subsampling;
130 struct v4l2_m2m_ctx *m2m_ctx;
131 struct s5p_jpeg_q_data out_q; 176 struct s5p_jpeg_q_data out_q;
132 struct s5p_jpeg_q_data cap_q; 177 struct s5p_jpeg_q_data cap_q;
133 struct v4l2_fh fh; 178 struct v4l2_fh fh;
@@ -147,4 +192,16 @@ struct s5p_jpeg_buffer {
147 unsigned long data; 192 unsigned long data;
148}; 193};
149 194
195/**
196 * struct s5p_jpeg_addr - JPEG converter physical address set for DMA
197 * @y: luminance plane physical address
198 * @cb: Cb plane physical address
199 * @cr: Cr plane physical address
200 */
201struct s5p_jpeg_addr {
202 u32 y;
203 u32 cb;
204 u32 cr;
205};
206
150#endif /* JPEG_CORE_H */ 207#endif /* JPEG_CORE_H */
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
new file mode 100644
index 000000000000..da8d6a1a984f
--- /dev/null
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
@@ -0,0 +1,279 @@
1/* Copyright (c) 2013 Samsung Electronics Co., Ltd.
2 * http://www.samsung.com/
3 *
4 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
5 *
6 * Register interface file for JPEG driver on Exynos4x12.
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#include <linux/io.h>
13#include <linux/delay.h>
14
15#include "jpeg-core.h"
16#include "jpeg-hw-exynos4.h"
17#include "jpeg-regs.h"
18
19void exynos4_jpeg_sw_reset(void __iomem *base)
20{
21 unsigned int reg;
22
23 reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
24 writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
25
26 ndelay(100000);
27
28 writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
29}
30
31void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode)
32{
33 unsigned int reg;
34
35 reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
36 /* set exynos4_jpeg mod register */
37 if (mode == S5P_JPEG_DECODE) {
38 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
39 EXYNOS4_DEC_MODE,
40 base + EXYNOS4_JPEG_CNTL_REG);
41 } else {/* encode */
42 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
43 EXYNOS4_ENC_MODE,
44 base + EXYNOS4_JPEG_CNTL_REG);
45 }
46}
47
48void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt)
49{
50 unsigned int reg;
51
52 reg = readl(base + EXYNOS4_IMG_FMT_REG) &
53 EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */
54
55 switch (img_fmt) {
56 case V4L2_PIX_FMT_GREY:
57 reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP;
58 break;
59 case V4L2_PIX_FMT_RGB32:
60 reg = reg | EXYNOS4_ENC_RGB_IMG |
61 EXYNOS4_RGB_IP_RGB_32BIT_IMG;
62 break;
63 case V4L2_PIX_FMT_RGB565:
64 reg = reg | EXYNOS4_ENC_RGB_IMG |
65 EXYNOS4_RGB_IP_RGB_16BIT_IMG;
66 break;
67 case V4L2_PIX_FMT_NV24:
68 reg = reg | EXYNOS4_ENC_YUV_444_IMG |
69 EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
70 EXYNOS4_SWAP_CHROMA_CBCR;
71 break;
72 case V4L2_PIX_FMT_NV42:
73 reg = reg | EXYNOS4_ENC_YUV_444_IMG |
74 EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
75 EXYNOS4_SWAP_CHROMA_CRCB;
76 break;
77 case V4L2_PIX_FMT_YUYV:
78 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
79 EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
80 EXYNOS4_SWAP_CHROMA_CBCR;
81 break;
82
83 case V4L2_PIX_FMT_YVYU:
84 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
85 EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
86 EXYNOS4_SWAP_CHROMA_CRCB;
87 break;
88 case V4L2_PIX_FMT_NV16:
89 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
90 EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
91 EXYNOS4_SWAP_CHROMA_CBCR;
92 break;
93 case V4L2_PIX_FMT_NV61:
94 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
95 EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
96 EXYNOS4_SWAP_CHROMA_CRCB;
97 break;
98 case V4L2_PIX_FMT_NV12:
99 reg = reg | EXYNOS4_DEC_YUV_420_IMG |
100 EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
101 EXYNOS4_SWAP_CHROMA_CBCR;
102 break;
103 case V4L2_PIX_FMT_NV21:
104 reg = reg | EXYNOS4_DEC_YUV_420_IMG |
105 EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
106 EXYNOS4_SWAP_CHROMA_CRCB;
107 break;
108 case V4L2_PIX_FMT_YUV420:
109 reg = reg | EXYNOS4_DEC_YUV_420_IMG |
110 EXYNOS4_YUV_420_IP_YUV_420_3P_IMG |
111 EXYNOS4_SWAP_CHROMA_CBCR;
112 break;
113 default:
114 break;
115
116 }
117
118 writel(reg, base + EXYNOS4_IMG_FMT_REG);
119}
120
121void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt)
122{
123 unsigned int reg;
124
125 reg = readl(base + EXYNOS4_IMG_FMT_REG) &
126 ~EXYNOS4_ENC_FMT_MASK; /* clear enc format */
127
128 switch (out_fmt) {
129 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
130 reg = reg | EXYNOS4_ENC_FMT_GRAY;
131 break;
132
133 case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
134 reg = reg | EXYNOS4_ENC_FMT_YUV_444;
135 break;
136
137 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
138 reg = reg | EXYNOS4_ENC_FMT_YUV_422;
139 break;
140
141 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
142 reg = reg | EXYNOS4_ENC_FMT_YUV_420;
143 break;
144
145 default:
146 break;
147 }
148
149 writel(reg, base + EXYNOS4_IMG_FMT_REG);
150}
151
152void exynos4_jpeg_set_interrupt(void __iomem *base)
153{
154 unsigned int reg;
155
156 reg = readl(base + EXYNOS4_INT_EN_REG) & ~EXYNOS4_INT_EN_MASK;
157 writel(EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
158}
159
160unsigned int exynos4_jpeg_get_int_status(void __iomem *base)
161{
162 unsigned int int_status;
163
164 int_status = readl(base + EXYNOS4_INT_STATUS_REG);
165
166 return int_status;
167}
168
169unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base)
170{
171 unsigned int fifo_status;
172
173 fifo_status = readl(base + EXYNOS4_FIFO_STATUS_REG);
174
175 return fifo_status;
176}
177
178void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value)
179{
180 unsigned int reg;
181
182 reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN;
183
184 if (value == 1)
185 writel(reg | EXYNOS4_HUF_TBL_EN,
186 base + EXYNOS4_JPEG_CNTL_REG);
187 else
188 writel(reg | ~EXYNOS4_HUF_TBL_EN,
189 base + EXYNOS4_JPEG_CNTL_REG);
190}
191
192void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value)
193{
194 unsigned int reg;
195
196 reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN);
197
198 if (value == 1)
199 writel(EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
200 else
201 writel(~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
202}
203
204void exynos4_jpeg_set_stream_buf_address(void __iomem *base,
205 unsigned int address)
206{
207 writel(address, base + EXYNOS4_OUT_MEM_BASE_REG);
208}
209
210void exynos4_jpeg_set_stream_size(void __iomem *base,
211 unsigned int x_value, unsigned int y_value)
212{
213 writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */
214 writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value),
215 base + EXYNOS4_JPEG_IMG_SIZE_REG);
216}
217
218void exynos4_jpeg_set_frame_buf_address(void __iomem *base,
219 struct s5p_jpeg_addr *exynos4_jpeg_addr)
220{
221 writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG);
222 writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG);
223 writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG);
224}
225
226void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
227 enum exynos4_jpeg_img_quality_level level)
228{
229 unsigned int reg;
230
231 reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 |
232 EXYNOS4_Q_TBL_COMP3_1 |
233 EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 |
234 EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 |
235 EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1;
236
237 writel(reg, base + EXYNOS4_TBL_SEL_REG);
238}
239
240void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt)
241{
242 if (fmt == V4L2_PIX_FMT_GREY)
243 writel(0xd2, base + EXYNOS4_HUFF_CNT_REG);
244 else
245 writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG);
246}
247
248unsigned int exynos4_jpeg_get_stream_size(void __iomem *base)
249{
250 unsigned int size;
251
252 size = readl(base + EXYNOS4_BITSTREAM_SIZE_REG);
253 return size;
254}
255
256void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size)
257{
258 writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG);
259}
260
261void exynos4_jpeg_get_frame_size(void __iomem *base,
262 unsigned int *width, unsigned int *height)
263{
264 *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) &
265 EXYNOS4_DECODED_SIZE_MASK);
266 *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) &
267 EXYNOS4_DECODED_SIZE_MASK;
268}
269
270unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base)
271{
272 return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) &
273 EXYNOS4_JPEG_DECODED_IMG_FMT_MASK;
274}
275
276void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size)
277{
278 writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG);
279}
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h
new file mode 100644
index 000000000000..c228d28a4bc7
--- /dev/null
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.h
@@ -0,0 +1,42 @@
1/* Copyright (c) 2013 Samsung Electronics Co., Ltd.
2 * http://www.samsung.com/
3 *
4 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
5 *
6 * Header file of the register interface for JPEG driver on Exynos4x12.
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 JPEG_HW_EXYNOS4_H_
14#define JPEG_HW_EXYNOS4_H_
15
16void exynos4_jpeg_sw_reset(void __iomem *base);
17void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode);
18void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt);
19void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt);
20void exynos4_jpeg_set_enc_tbl(void __iomem *base);
21void exynos4_jpeg_set_interrupt(void __iomem *base);
22unsigned int exynos4_jpeg_get_int_status(void __iomem *base);
23void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value);
24void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value);
25void exynos4_jpeg_set_stream_buf_address(void __iomem *base,
26 unsigned int address);
27void exynos4_jpeg_set_stream_size(void __iomem *base,
28 unsigned int x_value, unsigned int y_value);
29void exynos4_jpeg_set_frame_buf_address(void __iomem *base,
30 struct s5p_jpeg_addr *jpeg_addr);
31void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
32 enum exynos4_jpeg_img_quality_level level);
33void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt);
34void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size);
35unsigned int exynos4_jpeg_get_stream_size(void __iomem *base);
36void exynos4_jpeg_get_frame_size(void __iomem *base,
37 unsigned int *width, unsigned int *height);
38unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base);
39unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base);
40void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size);
41
42#endif /* JPEG_HW_EXYNOS4_H_ */
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c
index b47e887b6138..52407d790726 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c
@@ -9,27 +9,15 @@
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12#ifndef JPEG_HW_H_
13#define JPEG_HW_H_
14 12
15#include <linux/io.h> 13#include <linux/io.h>
16#include <linux/videodev2.h> 14#include <linux/videodev2.h>
17 15
18#include "jpeg-hw.h" 16#include "jpeg-core.h"
19#include "jpeg-regs.h" 17#include "jpeg-regs.h"
18#include "jpeg-hw-s5p.h"
20 19
21#define S5P_JPEG_MIN_WIDTH 32 20void s5p_jpeg_reset(void __iomem *regs)
22#define S5P_JPEG_MIN_HEIGHT 32
23#define S5P_JPEG_MAX_WIDTH 8192
24#define S5P_JPEG_MAX_HEIGHT 8192
25#define S5P_JPEG_ENCODE 0
26#define S5P_JPEG_DECODE 1
27#define S5P_JPEG_RAW_IN_565 0
28#define S5P_JPEG_RAW_IN_422 1
29#define S5P_JPEG_RAW_OUT_422 0
30#define S5P_JPEG_RAW_OUT_420 1
31
32static inline void jpeg_reset(void __iomem *regs)
33{ 21{
34 unsigned long reg; 22 unsigned long reg;
35 23
@@ -42,12 +30,12 @@ static inline void jpeg_reset(void __iomem *regs)
42 } 30 }
43} 31}
44 32
45static inline void jpeg_poweron(void __iomem *regs) 33void s5p_jpeg_poweron(void __iomem *regs)
46{ 34{
47 writel(S5P_POWER_ON, regs + S5P_JPGCLKCON); 35 writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
48} 36}
49 37
50static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode) 38void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
51{ 39{
52 unsigned long reg, m; 40 unsigned long reg, m;
53 41
@@ -63,7 +51,7 @@ static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
63 writel(reg, regs + S5P_JPGCMOD); 51 writel(reg, regs + S5P_JPGCMOD);
64} 52}
65 53
66static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16) 54void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16)
67{ 55{
68 unsigned long reg; 56 unsigned long reg;
69 57
@@ -75,7 +63,7 @@ static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16)
75 writel(reg, regs + S5P_JPGCMOD); 63 writel(reg, regs + S5P_JPGCMOD);
76} 64}
77 65
78static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode) 66void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode)
79{ 67{
80 unsigned long reg, m; 68 unsigned long reg, m;
81 69
@@ -90,7 +78,7 @@ static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
90 writel(reg, regs + S5P_JPGMOD); 78 writel(reg, regs + S5P_JPGMOD);
91} 79}
92 80
93static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) 81void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
94{ 82{
95 unsigned long reg, m; 83 unsigned long reg, m;
96 84
@@ -105,12 +93,12 @@ static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
105 writel(reg, regs + S5P_JPGMOD); 93 writel(reg, regs + S5P_JPGMOD);
106} 94}
107 95
108static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs) 96unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs)
109{ 97{
110 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; 98 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
111} 99}
112 100
113static inline void jpeg_dri(void __iomem *regs, unsigned int dri) 101void s5p_jpeg_dri(void __iomem *regs, unsigned int dri)
114{ 102{
115 unsigned long reg; 103 unsigned long reg;
116 104
@@ -125,7 +113,7 @@ static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
125 writel(reg, regs + S5P_JPGDRI_L); 113 writel(reg, regs + S5P_JPGDRI_L);
126} 114}
127 115
128static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) 116void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
129{ 117{
130 unsigned long reg; 118 unsigned long reg;
131 119
@@ -135,7 +123,7 @@ static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
135 writel(reg, regs + S5P_JPG_QTBL); 123 writel(reg, regs + S5P_JPG_QTBL);
136} 124}
137 125
138static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t) 126void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
139{ 127{
140 unsigned long reg; 128 unsigned long reg;
141 129
@@ -146,7 +134,7 @@ static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t)
146 writel(reg, regs + S5P_JPG_HTBL); 134 writel(reg, regs + S5P_JPG_HTBL);
147} 135}
148 136
149static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t) 137void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
150{ 138{
151 unsigned long reg; 139 unsigned long reg;
152 140
@@ -157,7 +145,7 @@ static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t)
157 writel(reg, regs + S5P_JPG_HTBL); 145 writel(reg, regs + S5P_JPG_HTBL);
158} 146}
159 147
160static inline void jpeg_y(void __iomem *regs, unsigned int y) 148void s5p_jpeg_y(void __iomem *regs, unsigned int y)
161{ 149{
162 unsigned long reg; 150 unsigned long reg;
163 151
@@ -172,7 +160,7 @@ static inline void jpeg_y(void __iomem *regs, unsigned int y)
172 writel(reg, regs + S5P_JPGY_L); 160 writel(reg, regs + S5P_JPGY_L);
173} 161}
174 162
175static inline void jpeg_x(void __iomem *regs, unsigned int x) 163void s5p_jpeg_x(void __iomem *regs, unsigned int x)
176{ 164{
177 unsigned long reg; 165 unsigned long reg;
178 166
@@ -187,7 +175,7 @@ static inline void jpeg_x(void __iomem *regs, unsigned int x)
187 writel(reg, regs + S5P_JPGX_L); 175 writel(reg, regs + S5P_JPGX_L);
188} 176}
189 177
190static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable) 178void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable)
191{ 179{
192 unsigned long reg; 180 unsigned long reg;
193 181
@@ -198,7 +186,7 @@ static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable)
198 writel(reg, regs + S5P_JPGINTSE); 186 writel(reg, regs + S5P_JPGINTSE);
199} 187}
200 188
201static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable) 189void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable)
202{ 190{
203 unsigned long reg; 191 unsigned long reg;
204 192
@@ -209,7 +197,7 @@ static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable)
209 writel(reg, regs + S5P_JPGINTSE); 197 writel(reg, regs + S5P_JPGINTSE);
210} 198}
211 199
212static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) 200void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
213{ 201{
214 unsigned long reg; 202 unsigned long reg;
215 203
@@ -220,7 +208,7 @@ static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
220 writel(reg, regs + S5P_JPGINTSE); 208 writel(reg, regs + S5P_JPGINTSE);
221} 209}
222 210
223static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val) 211void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val)
224{ 212{
225 unsigned long reg; 213 unsigned long reg;
226 214
@@ -231,7 +219,7 @@ static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val)
231 writel(reg, regs + S5P_JPG_TIMER_SE); 219 writel(reg, regs + S5P_JPG_TIMER_SE);
232} 220}
233 221
234static inline void jpeg_timer_disable(void __iomem *regs) 222void s5p_jpeg_timer_disable(void __iomem *regs)
235{ 223{
236 unsigned long reg; 224 unsigned long reg;
237 225
@@ -240,13 +228,13 @@ static inline void jpeg_timer_disable(void __iomem *regs)
240 writel(reg, regs + S5P_JPG_TIMER_SE); 228 writel(reg, regs + S5P_JPG_TIMER_SE);
241} 229}
242 230
243static inline int jpeg_timer_stat(void __iomem *regs) 231int s5p_jpeg_timer_stat(void __iomem *regs)
244{ 232{
245 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) 233 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
246 >> S5P_TIMER_INT_STAT_SHIFT); 234 >> S5P_TIMER_INT_STAT_SHIFT);
247} 235}
248 236
249static inline void jpeg_clear_timer_stat(void __iomem *regs) 237void s5p_jpeg_clear_timer_stat(void __iomem *regs)
250{ 238{
251 unsigned long reg; 239 unsigned long reg;
252 240
@@ -255,7 +243,7 @@ static inline void jpeg_clear_timer_stat(void __iomem *regs)
255 writel(reg, regs + S5P_JPG_TIMER_SE); 243 writel(reg, regs + S5P_JPG_TIMER_SE);
256} 244}
257 245
258static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size) 246void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
259{ 247{
260 unsigned long reg; 248 unsigned long reg;
261 249
@@ -266,13 +254,13 @@ static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
266 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 254 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
267} 255}
268 256
269static inline int jpeg_enc_stream_stat(void __iomem *regs) 257int s5p_jpeg_enc_stream_stat(void __iomem *regs)
270{ 258{
271 return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) & 259 return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
272 S5P_ENC_STREAM_INT_STAT_MASK); 260 S5P_ENC_STREAM_INT_STAT_MASK);
273} 261}
274 262
275static inline void jpeg_clear_enc_stream_stat(void __iomem *regs) 263void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs)
276{ 264{
277 unsigned long reg; 265 unsigned long reg;
278 266
@@ -281,7 +269,7 @@ static inline void jpeg_clear_enc_stream_stat(void __iomem *regs)
281 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 269 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
282} 270}
283 271
284static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format) 272void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format)
285{ 273{
286 unsigned long reg, f; 274 unsigned long reg, f;
287 275
@@ -296,17 +284,17 @@ static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
296 writel(reg, regs + S5P_JPG_OUTFORM); 284 writel(reg, regs + S5P_JPG_OUTFORM);
297} 285}
298 286
299static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr) 287void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr)
300{ 288{
301 writel(addr, regs + S5P_JPG_JPGADR); 289 writel(addr, regs + S5P_JPG_JPGADR);
302} 290}
303 291
304static inline void jpeg_imgadr(void __iomem *regs, unsigned long addr) 292void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr)
305{ 293{
306 writel(addr, regs + S5P_JPG_IMGADR); 294 writel(addr, regs + S5P_JPG_IMGADR);
307} 295}
308 296
309static inline void jpeg_coef(void __iomem *regs, unsigned int i, 297void s5p_jpeg_coef(void __iomem *regs, unsigned int i,
310 unsigned int j, unsigned int coef) 298 unsigned int j, unsigned int coef)
311{ 299{
312 unsigned long reg; 300 unsigned long reg;
@@ -317,24 +305,24 @@ static inline void jpeg_coef(void __iomem *regs, unsigned int i,
317 writel(reg, regs + S5P_JPG_COEF(i)); 305 writel(reg, regs + S5P_JPG_COEF(i));
318} 306}
319 307
320static inline void jpeg_start(void __iomem *regs) 308void s5p_jpeg_start(void __iomem *regs)
321{ 309{
322 writel(1, regs + S5P_JSTART); 310 writel(1, regs + S5P_JSTART);
323} 311}
324 312
325static inline int jpeg_result_stat_ok(void __iomem *regs) 313int s5p_jpeg_result_stat_ok(void __iomem *regs)
326{ 314{
327 return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK) 315 return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
328 >> S5P_RESULT_STAT_SHIFT); 316 >> S5P_RESULT_STAT_SHIFT);
329} 317}
330 318
331static inline int jpeg_stream_stat_ok(void __iomem *regs) 319int s5p_jpeg_stream_stat_ok(void __iomem *regs)
332{ 320{
333 return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK) 321 return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
334 >> S5P_STREAM_STAT_SHIFT); 322 >> S5P_STREAM_STAT_SHIFT);
335} 323}
336 324
337static inline void jpeg_clear_int(void __iomem *regs) 325void s5p_jpeg_clear_int(void __iomem *regs)
338{ 326{
339 unsigned long reg; 327 unsigned long reg;
340 328
@@ -343,7 +331,7 @@ static inline void jpeg_clear_int(void __iomem *regs)
343 reg = readl(regs + S5P_JPGOPR); 331 reg = readl(regs + S5P_JPGOPR);
344} 332}
345 333
346static inline unsigned int jpeg_compressed_size(void __iomem *regs) 334unsigned int s5p_jpeg_compressed_size(void __iomem *regs)
347{ 335{
348 unsigned long jpeg_size = 0; 336 unsigned long jpeg_size = 0;
349 337
@@ -353,5 +341,3 @@ static inline unsigned int jpeg_compressed_size(void __iomem *regs)
353 341
354 return (unsigned int)jpeg_size; 342 return (unsigned int)jpeg_size;
355} 343}
356
357#endif /* JPEG_HW_H_ */
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
new file mode 100644
index 000000000000..c11ebe86b9c9
--- /dev/null
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
@@ -0,0 +1,63 @@
1/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef JPEG_HW_S5P_H_
13#define JPEG_HW_S5P_H_
14
15#include <linux/io.h>
16#include <linux/videodev2.h>
17
18#include "jpeg-regs.h"
19
20#define S5P_JPEG_MIN_WIDTH 32
21#define S5P_JPEG_MIN_HEIGHT 32
22#define S5P_JPEG_MAX_WIDTH 8192
23#define S5P_JPEG_MAX_HEIGHT 8192
24#define S5P_JPEG_RAW_IN_565 0
25#define S5P_JPEG_RAW_IN_422 1
26#define S5P_JPEG_RAW_OUT_422 0
27#define S5P_JPEG_RAW_OUT_420 1
28
29void s5p_jpeg_reset(void __iomem *regs);
30void s5p_jpeg_poweron(void __iomem *regs);
31void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode);
32void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16);
33void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode);
34void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode);
35unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs);
36void s5p_jpeg_dri(void __iomem *regs, unsigned int dri);
37void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n);
38void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t);
39void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t);
40void s5p_jpeg_y(void __iomem *regs, unsigned int y);
41void s5p_jpeg_x(void __iomem *regs, unsigned int x);
42void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable);
43void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable);
44void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl);
45void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val);
46void s5p_jpeg_timer_disable(void __iomem *regs);
47int s5p_jpeg_timer_stat(void __iomem *regs);
48void s5p_jpeg_clear_timer_stat(void __iomem *regs);
49void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size);
50int s5p_jpeg_enc_stream_stat(void __iomem *regs);
51void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs);
52void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format);
53void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr);
54void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr);
55void s5p_jpeg_coef(void __iomem *regs, unsigned int i,
56 unsigned int j, unsigned int coef);
57void s5p_jpeg_start(void __iomem *regs);
58int s5p_jpeg_result_stat_ok(void __iomem *regs);
59int s5p_jpeg_stream_stat_ok(void __iomem *regs);
60void s5p_jpeg_clear_int(void __iomem *regs);
61unsigned int s5p_jpeg_compressed_size(void __iomem *regs);
62
63#endif /* JPEG_HW_S5P_H_ */
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
index 38e50815668c..33f2c7374cfd 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
@@ -2,10 +2,11 @@
2 * 2 *
3 * Register definition file for Samsung JPEG codec driver 3 * Register definition file for Samsung JPEG codec driver
4 * 4 *
5 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 5 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
6 * http://www.samsung.com 6 * http://www.samsung.com
7 * 7 *
8 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 8 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
9 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -15,6 +16,8 @@
15#ifndef JPEG_REGS_H_ 16#ifndef JPEG_REGS_H_
16#define JPEG_REGS_H_ 17#define JPEG_REGS_H_
17 18
19/* Register and bit definitions for S5PC210 */
20
18/* JPEG mode register */ 21/* JPEG mode register */
19#define S5P_JPGMOD 0x00 22#define S5P_JPGMOD 0x00
20#define S5P_PROC_MODE_MASK (0x1 << 3) 23#define S5P_PROC_MODE_MASK (0x1 << 3)
@@ -166,5 +169,209 @@
166/* JPEG AC Huffman table register */ 169/* JPEG AC Huffman table register */
167#define S5P_JPG_HACTBLG(n) (0x8c0 + (n) * 0x400) 170#define S5P_JPG_HACTBLG(n) (0x8c0 + (n) * 0x400)
168 171
172
173/* Register and bit definitions for Exynos 4x12 */
174
175/* JPEG Codec Control Registers */
176#define EXYNOS4_JPEG_CNTL_REG 0x00
177#define EXYNOS4_INT_EN_REG 0x04
178#define EXYNOS4_INT_TIMER_COUNT_REG 0x08
179#define EXYNOS4_INT_STATUS_REG 0x0c
180#define EXYNOS4_OUT_MEM_BASE_REG 0x10
181#define EXYNOS4_JPEG_IMG_SIZE_REG 0x14
182#define EXYNOS4_IMG_BA_PLANE_1_REG 0x18
183#define EXYNOS4_IMG_SO_PLANE_1_REG 0x1c
184#define EXYNOS4_IMG_PO_PLANE_1_REG 0x20
185#define EXYNOS4_IMG_BA_PLANE_2_REG 0x24
186#define EXYNOS4_IMG_SO_PLANE_2_REG 0x28
187#define EXYNOS4_IMG_PO_PLANE_2_REG 0x2c
188#define EXYNOS4_IMG_BA_PLANE_3_REG 0x30
189#define EXYNOS4_IMG_SO_PLANE_3_REG 0x34
190#define EXYNOS4_IMG_PO_PLANE_3_REG 0x38
191
192#define EXYNOS4_TBL_SEL_REG 0x3c
193
194#define EXYNOS4_IMG_FMT_REG 0x40
195
196#define EXYNOS4_BITSTREAM_SIZE_REG 0x44
197#define EXYNOS4_PADDING_REG 0x48
198#define EXYNOS4_HUFF_CNT_REG 0x4c
199#define EXYNOS4_FIFO_STATUS_REG 0x50
200#define EXYNOS4_DECODE_XY_SIZE_REG 0x54
201#define EXYNOS4_DECODE_IMG_FMT_REG 0x58
202
203#define EXYNOS4_QUAN_TBL_ENTRY_REG 0x100
204#define EXYNOS4_HUFF_TBL_ENTRY_REG 0x200
205
206
207/****************************************************************/
208/* Bit definition part */
209/****************************************************************/
210
211/* JPEG CNTL Register bit */
212#define EXYNOS4_ENC_DEC_MODE_MASK (0xfffffffc << 0)
213#define EXYNOS4_DEC_MODE (1 << 0)
214#define EXYNOS4_ENC_MODE (1 << 1)
215#define EXYNOS4_AUTO_RST_MARKER (1 << 2)
216#define EXYNOS4_RST_INTERVAL_SHIFT 3
217#define EXYNOS4_RST_INTERVAL(x) (((x) & 0xffff) \
218 << EXYNOS4_RST_INTERVAL_SHIFT)
219#define EXYNOS4_HUF_TBL_EN (1 << 19)
220#define EXYNOS4_HOR_SCALING_SHIFT 20
221#define EXYNOS4_HOR_SCALING_MASK (3 << EXYNOS4_HOR_SCALING_SHIFT)
222#define EXYNOS4_HOR_SCALING(x) (((x) & 0x3) \
223 << EXYNOS4_HOR_SCALING_SHIFT)
224#define EXYNOS4_VER_SCALING_SHIFT 22
225#define EXYNOS4_VER_SCALING_MASK (3 << EXYNOS4_VER_SCALING_SHIFT)
226#define EXYNOS4_VER_SCALING(x) (((x) & 0x3) \
227 << EXYNOS4_VER_SCALING_SHIFT)
228#define EXYNOS4_PADDING (1 << 27)
229#define EXYNOS4_SYS_INT_EN (1 << 28)
230#define EXYNOS4_SOFT_RESET_HI (1 << 29)
231
232/* JPEG INT Register bit */
233#define EXYNOS4_INT_EN_MASK (0x1f << 0)
234#define EXYNOS4_PROT_ERR_INT_EN (1 << 0)
235#define EXYNOS4_IMG_COMPLETION_INT_EN (1 << 1)
236#define EXYNOS4_DEC_INVALID_FORMAT_EN (1 << 2)
237#define EXYNOS4_MULTI_SCAN_ERROR_EN (1 << 3)
238#define EXYNOS4_FRAME_ERR_EN (1 << 4)
239#define EXYNOS4_INT_EN_ALL (0x1f << 0)
240
241#define EXYNOS4_MOD_REG_PROC_ENC (0 << 3)
242#define EXYNOS4_MOD_REG_PROC_DEC (1 << 3)
243
244#define EXYNOS4_MOD_REG_SUBSAMPLE_444 (0 << 0)
245#define EXYNOS4_MOD_REG_SUBSAMPLE_422 (1 << 0)
246#define EXYNOS4_MOD_REG_SUBSAMPLE_420 (2 << 0)
247#define EXYNOS4_MOD_REG_SUBSAMPLE_GRAY (3 << 0)
248
249
250/* JPEG IMAGE SIZE Register bit */
251#define EXYNOS4_X_SIZE_SHIFT 0
252#define EXYNOS4_X_SIZE_MASK (0xffff << EXYNOS4_X_SIZE_SHIFT)
253#define EXYNOS4_X_SIZE(x) (((x) & 0xffff) << EXYNOS4_X_SIZE_SHIFT)
254#define EXYNOS4_Y_SIZE_SHIFT 16
255#define EXYNOS4_Y_SIZE_MASK (0xffff << EXYNOS4_Y_SIZE_SHIFT)
256#define EXYNOS4_Y_SIZE(x) (((x) & 0xffff) << EXYNOS4_Y_SIZE_SHIFT)
257
258/* JPEG IMAGE FORMAT Register bit */
259#define EXYNOS4_ENC_IN_FMT_MASK 0xffff0000
260#define EXYNOS4_ENC_GRAY_IMG (0 << 0)
261#define EXYNOS4_ENC_RGB_IMG (1 << 0)
262#define EXYNOS4_ENC_YUV_444_IMG (2 << 0)
263#define EXYNOS4_ENC_YUV_422_IMG (3 << 0)
264#define EXYNOS4_ENC_YUV_440_IMG (4 << 0)
265
266#define EXYNOS4_DEC_GRAY_IMG (0 << 0)
267#define EXYNOS4_DEC_RGB_IMG (1 << 0)
268#define EXYNOS4_DEC_YUV_444_IMG (2 << 0)
269#define EXYNOS4_DEC_YUV_422_IMG (3 << 0)
270#define EXYNOS4_DEC_YUV_420_IMG (4 << 0)
271
272#define EXYNOS4_GRAY_IMG_IP_SHIFT 3
273#define EXYNOS4_GRAY_IMG_IP_MASK (7 << EXYNOS4_GRAY_IMG_IP_SHIFT)
274#define EXYNOS4_GRAY_IMG_IP (4 << EXYNOS4_GRAY_IMG_IP_SHIFT)
275
276#define EXYNOS4_RGB_IP_SHIFT 6
277#define EXYNOS4_RGB_IP_MASK (7 << EXYNOS4_RGB_IP_SHIFT)
278#define EXYNOS4_RGB_IP_RGB_16BIT_IMG (4 << EXYNOS4_RGB_IP_SHIFT)
279#define EXYNOS4_RGB_IP_RGB_32BIT_IMG (5 << EXYNOS4_RGB_IP_SHIFT)
280
281#define EXYNOS4_YUV_444_IP_SHIFT 9
282#define EXYNOS4_YUV_444_IP_MASK (7 << EXYNOS4_YUV_444_IP_SHIFT)
283#define EXYNOS4_YUV_444_IP_YUV_444_2P_IMG (4 << EXYNOS4_YUV_444_IP_SHIFT)
284#define EXYNOS4_YUV_444_IP_YUV_444_3P_IMG (5 << EXYNOS4_YUV_444_IP_SHIFT)
285
286#define EXYNOS4_YUV_422_IP_SHIFT 12
287#define EXYNOS4_YUV_422_IP_MASK (7 << EXYNOS4_YUV_422_IP_SHIFT)
288#define EXYNOS4_YUV_422_IP_YUV_422_1P_IMG (4 << EXYNOS4_YUV_422_IP_SHIFT)
289#define EXYNOS4_YUV_422_IP_YUV_422_2P_IMG (5 << EXYNOS4_YUV_422_IP_SHIFT)
290#define EXYNOS4_YUV_422_IP_YUV_422_3P_IMG (6 << EXYNOS4_YUV_422_IP_SHIFT)
291
292#define EXYNOS4_YUV_420_IP_SHIFT 15
293#define EXYNOS4_YUV_420_IP_MASK (7 << EXYNOS4_YUV_420_IP_SHIFT)
294#define EXYNOS4_YUV_420_IP_YUV_420_2P_IMG (4 << EXYNOS4_YUV_420_IP_SHIFT)
295#define EXYNOS4_YUV_420_IP_YUV_420_3P_IMG (5 << EXYNOS4_YUV_420_IP_SHIFT)
296
297#define EXYNOS4_ENC_FMT_SHIFT 24
298#define EXYNOS4_ENC_FMT_MASK (3 << EXYNOS4_ENC_FMT_SHIFT)
299#define EXYNOS4_ENC_FMT_GRAY (0 << EXYNOS4_ENC_FMT_SHIFT)
300#define EXYNOS4_ENC_FMT_YUV_444 (1 << EXYNOS4_ENC_FMT_SHIFT)
301#define EXYNOS4_ENC_FMT_YUV_422 (2 << EXYNOS4_ENC_FMT_SHIFT)
302#define EXYNOS4_ENC_FMT_YUV_420 (3 << EXYNOS4_ENC_FMT_SHIFT)
303
304#define EXYNOS4_JPEG_DECODED_IMG_FMT_MASK 0x03
305
306#define EXYNOS4_SWAP_CHROMA_CRCB (1 << 26)
307#define EXYNOS4_SWAP_CHROMA_CBCR (0 << 26)
308
309/* JPEG HUFF count Register bit */
310#define EXYNOS4_HUFF_COUNT_MASK 0xffff
311
312/* JPEG Decoded_img_x_y_size Register bit */
313#define EXYNOS4_DECODED_SIZE_MASK 0x0000ffff
314
315/* JPEG Decoded image format Register bit */
316#define EXYNOS4_DECODED_IMG_FMT_MASK 0x3
317
318/* JPEG TBL SEL Register bit */
319#define EXYNOS4_Q_TBL_COMP1_0 (0 << 0)
320#define EXYNOS4_Q_TBL_COMP1_1 (1 << 0)
321#define EXYNOS4_Q_TBL_COMP1_2 (2 << 0)
322#define EXYNOS4_Q_TBL_COMP1_3 (3 << 0)
323
324#define EXYNOS4_Q_TBL_COMP2_0 (0 << 2)
325#define EXYNOS4_Q_TBL_COMP2_1 (1 << 2)
326#define EXYNOS4_Q_TBL_COMP2_2 (2 << 2)
327#define EXYNOS4_Q_TBL_COMP2_3 (3 << 2)
328
329#define EXYNOS4_Q_TBL_COMP3_0 (0 << 4)
330#define EXYNOS4_Q_TBL_COMP3_1 (1 << 4)
331#define EXYNOS4_Q_TBL_COMP3_2 (2 << 4)
332#define EXYNOS4_Q_TBL_COMP3_3 (3 << 4)
333
334#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_0 (0 << 6)
335#define EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 (1 << 6)
336#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_0 (2 << 6)
337#define EXYNOS4_HUFF_TBL_COMP1_AC_1_DC_1 (3 << 6)
338
339#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 (0 << 8)
340#define EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_1 (1 << 8)
341#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_0 (2 << 8)
342#define EXYNOS4_HUFF_TBL_COMP2_AC_1_DC_1 (3 << 8)
343
344#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_0 (0 << 10)
345#define EXYNOS4_HUFF_TBL_COMP3_AC_0_DC_1 (1 << 10)
346#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_0 (2 << 10)
347#define EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1 (3 << 10)
348
349/* JPEG quantizer table register */
350#define EXYNOS4_QTBL_CONTENT(n) (0x100 + (n) * 0x40)
351
352/* JPEG DC luminance (code length) Huffman table register */
353#define EXYNOS4_HUFF_TBL_HDCLL 0x200
354
355/* JPEG DC luminance (values) Huffman table register */
356#define EXYNOS4_HUFF_TBL_HDCLV 0x210
357
358/* JPEG DC chrominance (code length) Huffman table register */
359#define EXYNOS4_HUFF_TBL_HDCCL 0x220
360
361/* JPEG DC chrominance (values) Huffman table register */
362#define EXYNOS4_HUFF_TBL_HDCCV 0x230
363
364/* JPEG AC luminance (code length) Huffman table register */
365#define EXYNOS4_HUFF_TBL_HACLL 0x240
366
367/* JPEG AC luminance (values) Huffman table register */
368#define EXYNOS4_HUFF_TBL_HACLV 0x250
369
370/* JPEG AC chrominance (code length) Huffman table register */
371#define EXYNOS4_HUFF_TBL_HACCL 0x300
372
373/* JPEG AC chrominance (values) Huffman table register */
374#define EXYNOS4_HUFF_TBL_HACCV 0x310
375
169#endif /* JPEG_REGS_H_ */ 376#endif /* JPEG_REGS_H_ */
170 377
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index e46067a57853..e2aac592d29f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -177,21 +177,6 @@ unlock:
177 mutex_unlock(&dev->mfc_mutex); 177 mutex_unlock(&dev->mfc_mutex);
178} 178}
179 179
180static enum s5p_mfc_node_type s5p_mfc_get_node_type(struct file *file)
181{
182 struct video_device *vdev = video_devdata(file);
183
184 if (!vdev) {
185 mfc_err("failed to get video_device");
186 return MFCNODE_INVALID;
187 }
188 if (vdev->index == 0)
189 return MFCNODE_DECODER;
190 else if (vdev->index == 1)
191 return MFCNODE_ENCODER;
192 return MFCNODE_INVALID;
193}
194
195static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev) 180static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
196{ 181{
197 mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT); 182 mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
@@ -705,6 +690,7 @@ irq_cleanup_hw:
705/* Open an MFC node */ 690/* Open an MFC node */
706static int s5p_mfc_open(struct file *file) 691static int s5p_mfc_open(struct file *file)
707{ 692{
693 struct video_device *vdev = video_devdata(file);
708 struct s5p_mfc_dev *dev = video_drvdata(file); 694 struct s5p_mfc_dev *dev = video_drvdata(file);
709 struct s5p_mfc_ctx *ctx = NULL; 695 struct s5p_mfc_ctx *ctx = NULL;
710 struct vb2_queue *q; 696 struct vb2_queue *q;
@@ -742,7 +728,7 @@ static int s5p_mfc_open(struct file *file)
742 /* Mark context as idle */ 728 /* Mark context as idle */
743 clear_work_bit_irqsave(ctx); 729 clear_work_bit_irqsave(ctx);
744 dev->ctx[ctx->num] = ctx; 730 dev->ctx[ctx->num] = ctx;
745 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { 731 if (vdev == dev->vfd_dec) {
746 ctx->type = MFCINST_DECODER; 732 ctx->type = MFCINST_DECODER;
747 ctx->c_ops = get_dec_codec_ops(); 733 ctx->c_ops = get_dec_codec_ops();
748 s5p_mfc_dec_init(ctx); 734 s5p_mfc_dec_init(ctx);
@@ -752,7 +738,7 @@ static int s5p_mfc_open(struct file *file)
752 mfc_err("Failed to setup mfc controls\n"); 738 mfc_err("Failed to setup mfc controls\n");
753 goto err_ctrls_setup; 739 goto err_ctrls_setup;
754 } 740 }
755 } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) { 741 } else if (vdev == dev->vfd_enc) {
756 ctx->type = MFCINST_ENCODER; 742 ctx->type = MFCINST_ENCODER;
757 ctx->c_ops = get_enc_codec_ops(); 743 ctx->c_ops = get_enc_codec_ops();
758 /* only for encoder */ 744 /* only for encoder */
@@ -797,10 +783,10 @@ static int s5p_mfc_open(struct file *file)
797 q = &ctx->vq_dst; 783 q = &ctx->vq_dst;
798 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 784 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
799 q->drv_priv = &ctx->fh; 785 q->drv_priv = &ctx->fh;
800 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { 786 if (vdev == dev->vfd_dec) {
801 q->io_modes = VB2_MMAP; 787 q->io_modes = VB2_MMAP;
802 q->ops = get_dec_queue_ops(); 788 q->ops = get_dec_queue_ops();
803 } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) { 789 } else if (vdev == dev->vfd_enc) {
804 q->io_modes = VB2_MMAP | VB2_USERPTR; 790 q->io_modes = VB2_MMAP | VB2_USERPTR;
805 q->ops = get_enc_queue_ops(); 791 q->ops = get_enc_queue_ops();
806 } else { 792 } else {
@@ -819,10 +805,10 @@ static int s5p_mfc_open(struct file *file)
819 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 805 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
820 q->io_modes = VB2_MMAP; 806 q->io_modes = VB2_MMAP;
821 q->drv_priv = &ctx->fh; 807 q->drv_priv = &ctx->fh;
822 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { 808 if (vdev == dev->vfd_dec) {
823 q->io_modes = VB2_MMAP; 809 q->io_modes = VB2_MMAP;
824 q->ops = get_dec_queue_ops(); 810 q->ops = get_dec_queue_ops();
825 } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) { 811 } else if (vdev == dev->vfd_enc) {
826 q->io_modes = VB2_MMAP | VB2_USERPTR; 812 q->io_modes = VB2_MMAP | VB2_USERPTR;
827 q->ops = get_enc_queue_ops(); 813 q->ops = get_enc_queue_ops();
828 } else { 814 } else {
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 6920b546181a..f723f1f2f578 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -115,15 +115,6 @@ enum s5p_mfc_fmt_type {
115}; 115};
116 116
117/** 117/**
118 * enum s5p_mfc_node_type - The type of an MFC device node.
119 */
120enum s5p_mfc_node_type {
121 MFCNODE_INVALID = -1,
122 MFCNODE_DECODER = 0,
123 MFCNODE_ENCODER = 1,
124};
125
126/**
127 * enum s5p_mfc_inst_type - The type of an MFC instance. 118 * enum s5p_mfc_inst_type - The type of an MFC instance.
128 */ 119 */
129enum s5p_mfc_inst_type { 120enum s5p_mfc_inst_type {
@@ -422,6 +413,11 @@ struct s5p_mfc_vp8_enc_params {
422 enum v4l2_vp8_golden_frame_sel golden_frame_sel; 413 enum v4l2_vp8_golden_frame_sel golden_frame_sel;
423 u8 hier_layer; 414 u8 hier_layer;
424 u8 hier_layer_qp[3]; 415 u8 hier_layer_qp[3];
416 u8 rc_min_qp;
417 u8 rc_max_qp;
418 u8 rc_frame_qp;
419 u8 rc_p_frame_qp;
420 u8 profile;
425}; 421};
426 422
427/** 423/**
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 4ff3b6cd6842..91b6e020ddf3 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -618,6 +618,46 @@ static struct mfc_control controls[] = {
618 .default_value = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV, 618 .default_value = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV,
619 .menu_skip_mask = 0, 619 .menu_skip_mask = 0,
620 }, 620 },
621 {
622 .id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP,
623 .type = V4L2_CTRL_TYPE_INTEGER,
624 .minimum = 0,
625 .maximum = 127,
626 .step = 1,
627 .default_value = 127,
628 },
629 {
630 .id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP,
631 .type = V4L2_CTRL_TYPE_INTEGER,
632 .minimum = 0,
633 .maximum = 11,
634 .step = 1,
635 .default_value = 0,
636 },
637 {
638 .id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP,
639 .type = V4L2_CTRL_TYPE_INTEGER,
640 .minimum = 0,
641 .maximum = 127,
642 .step = 1,
643 .default_value = 10,
644 },
645 {
646 .id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP,
647 .type = V4L2_CTRL_TYPE_INTEGER,
648 .minimum = 0,
649 .maximum = 127,
650 .step = 1,
651 .default_value = 10,
652 },
653 {
654 .id = V4L2_CID_MPEG_VIDEO_VPX_PROFILE,
655 .type = V4L2_CTRL_TYPE_INTEGER,
656 .minimum = 0,
657 .maximum = 3,
658 .step = 1,
659 .default_value = 0,
660 },
621}; 661};
622 662
623#define NUM_CTRLS ARRAY_SIZE(controls) 663#define NUM_CTRLS ARRAY_SIZE(controls)
@@ -1557,6 +1597,21 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
1557 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: 1597 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:
1558 p->codec.vp8.golden_frame_sel = ctrl->val; 1598 p->codec.vp8.golden_frame_sel = ctrl->val;
1559 break; 1599 break;
1600 case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP:
1601 p->codec.vp8.rc_min_qp = ctrl->val;
1602 break;
1603 case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP:
1604 p->codec.vp8.rc_max_qp = ctrl->val;
1605 break;
1606 case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP:
1607 p->codec.vp8.rc_frame_qp = ctrl->val;
1608 break;
1609 case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP:
1610 p->codec.vp8.rc_p_frame_qp = ctrl->val;
1611 break;
1612 case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:
1613 p->codec.vp8.profile = ctrl->val;
1614 break;
1560 default: 1615 default:
1561 v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", 1616 v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",
1562 ctrl->id, ctrl->val); 1617 ctrl->id, ctrl->val);
@@ -1863,7 +1918,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
1863 if (ctx->src_bufs_cnt < ctx->pb_count) { 1918 if (ctx->src_bufs_cnt < ctx->pb_count) {
1864 mfc_err("Need minimum %d OUTPUT buffers\n", 1919 mfc_err("Need minimum %d OUTPUT buffers\n",
1865 ctx->pb_count); 1920 ctx->pb_count);
1866 return -EINVAL; 1921 return -ENOBUFS;
1867 } 1922 }
1868 } 1923 }
1869 1924
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 461358c4a790..f6ff2dbf3a1d 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -1197,10 +1197,8 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
1197 reg |= ((p->num_b_frame & 0x3) << 16); 1197 reg |= ((p->num_b_frame & 0x3) << 16);
1198 WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6); 1198 WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
1199 1199
1200 /* profile & level */ 1200 /* profile - 0 ~ 3 */
1201 reg = 0; 1201 reg = p_vp8->profile & 0x3;
1202 /** profile */
1203 reg |= (0x1 << 4);
1204 WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6); 1202 WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
1205 1203
1206 /* rate control config. */ 1204 /* rate control config. */
@@ -1218,6 +1216,26 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
1218 WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6); 1216 WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
1219 } 1217 }
1220 1218
1219 /* frame QP */
1220 reg &= ~(0x7F);
1221 reg |= p_vp8->rc_frame_qp & 0x7F;
1222 WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
1223
1224 /* other QPs */
1225 WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
1226 if (!p->rc_frame && !p->rc_mb) {
1227 reg = 0;
1228 reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8);
1229 reg |= p_vp8->rc_frame_qp & 0x7F;
1230 WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
1231 }
1232
1233 /* max QP */
1234 reg = ((p_vp8->rc_max_qp & 0x7F) << 8);
1235 /* min QP */
1236 reg |= p_vp8->rc_min_qp & 0x7F;
1237 WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
1238
1221 /* vbv buffer size */ 1239 /* vbv buffer size */
1222 if (p->frame_skip_mode == 1240 if (p->frame_skip_mode ==
1223 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { 1241 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
diff --git a/drivers/media/platform/s5p-tv/mixer_drv.c b/drivers/media/platform/s5p-tv/mixer_drv.c
index 51805a5e2beb..bc08b5f28e44 100644
--- a/drivers/media/platform/s5p-tv/mixer_drv.c
+++ b/drivers/media/platform/s5p-tv/mixer_drv.c
@@ -347,19 +347,41 @@ static int mxr_runtime_resume(struct device *dev)
347{ 347{
348 struct mxr_device *mdev = to_mdev(dev); 348 struct mxr_device *mdev = to_mdev(dev);
349 struct mxr_resources *res = &mdev->res; 349 struct mxr_resources *res = &mdev->res;
350 int ret;
350 351
351 mxr_dbg(mdev, "resume - start\n"); 352 mxr_dbg(mdev, "resume - start\n");
352 mutex_lock(&mdev->mutex); 353 mutex_lock(&mdev->mutex);
353 /* turn clocks on */ 354 /* turn clocks on */
354 clk_enable(res->mixer); 355 ret = clk_prepare_enable(res->mixer);
355 clk_enable(res->vp); 356 if (ret < 0) {
356 clk_enable(res->sclk_mixer); 357 dev_err(mdev->dev, "clk_prepare_enable(mixer) failed\n");
358 goto fail;
359 }
360 ret = clk_prepare_enable(res->vp);
361 if (ret < 0) {
362 dev_err(mdev->dev, "clk_prepare_enable(vp) failed\n");
363 goto fail_mixer;
364 }
365 ret = clk_prepare_enable(res->sclk_mixer);
366 if (ret < 0) {
367 dev_err(mdev->dev, "clk_prepare_enable(sclk_mixer) failed\n");
368 goto fail_vp;
369 }
357 /* apply default configuration */ 370 /* apply default configuration */
358 mxr_reg_reset(mdev); 371 mxr_reg_reset(mdev);
359 mxr_dbg(mdev, "resume - finished\n"); 372 mxr_dbg(mdev, "resume - finished\n");
360 373
361 mutex_unlock(&mdev->mutex); 374 mutex_unlock(&mdev->mutex);
362 return 0; 375 return 0;
376
377fail_vp:
378 clk_disable_unprepare(res->vp);
379fail_mixer:
380 clk_disable_unprepare(res->mixer);
381fail:
382 mutex_unlock(&mdev->mutex);
383 dev_err(mdev->dev, "resume failed\n");
384 return ret;
363} 385}
364 386
365static int mxr_runtime_suspend(struct device *dev) 387static int mxr_runtime_suspend(struct device *dev)
@@ -369,9 +391,9 @@ static int mxr_runtime_suspend(struct device *dev)
369 mxr_dbg(mdev, "suspend - start\n"); 391 mxr_dbg(mdev, "suspend - start\n");
370 mutex_lock(&mdev->mutex); 392 mutex_lock(&mdev->mutex);
371 /* turn clocks off */ 393 /* turn clocks off */
372 clk_disable(res->sclk_mixer); 394 clk_disable_unprepare(res->sclk_mixer);
373 clk_disable(res->vp); 395 clk_disable_unprepare(res->vp);
374 clk_disable(res->mixer); 396 clk_disable_unprepare(res->mixer);
375 mutex_unlock(&mdev->mutex); 397 mutex_unlock(&mdev->mutex);
376 mxr_dbg(mdev, "suspend - finished\n"); 398 mxr_dbg(mdev, "suspend - finished\n");
377 return 0; 399 return 0;
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index 81b97db111d8..c5059ba0d733 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -948,7 +948,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
948 948
949 if (count == 0) { 949 if (count == 0) {
950 mxr_dbg(mdev, "no output buffers queued\n"); 950 mxr_dbg(mdev, "no output buffers queued\n");
951 return -EINVAL; 951 return -ENOBUFS;
952 } 952 }
953 953
954 /* block any changes in output configuration */ 954 /* block any changes in output configuration */
diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c
index 0afa90f0f6ab..5a7c3796f22e 100644
--- a/drivers/media/platform/s5p-tv/sdo_drv.c
+++ b/drivers/media/platform/s5p-tv/sdo_drv.c
@@ -55,6 +55,8 @@ struct sdo_device {
55 struct clk *dacphy; 55 struct clk *dacphy;
56 /** clock for control of VPLL */ 56 /** clock for control of VPLL */
57 struct clk *fout_vpll; 57 struct clk *fout_vpll;
58 /** vpll rate before sdo stream was on */
59 unsigned long vpll_rate;
58 /** regulator for SDO IP power */ 60 /** regulator for SDO IP power */
59 struct regulator *vdac; 61 struct regulator *vdac;
60 /** regulator for SDO plug detection */ 62 /** regulator for SDO plug detection */
@@ -193,17 +195,33 @@ static int sdo_s_power(struct v4l2_subdev *sd, int on)
193 195
194static int sdo_streamon(struct sdo_device *sdev) 196static int sdo_streamon(struct sdo_device *sdev)
195{ 197{
198 int ret;
199
196 /* set proper clock for Timing Generator */ 200 /* set proper clock for Timing Generator */
197 clk_set_rate(sdev->fout_vpll, 54000000); 201 sdev->vpll_rate = clk_get_rate(sdev->fout_vpll);
202 ret = clk_set_rate(sdev->fout_vpll, 54000000);
203 if (ret < 0) {
204 dev_err(sdev->dev, "Failed to set vpll rate\n");
205 return ret;
206 }
198 dev_info(sdev->dev, "fout_vpll.rate = %lu\n", 207 dev_info(sdev->dev, "fout_vpll.rate = %lu\n",
199 clk_get_rate(sdev->fout_vpll)); 208 clk_get_rate(sdev->fout_vpll));
200 /* enable clock in SDO */ 209 /* enable clock in SDO */
201 sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_CLOCK_ON); 210 sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_CLOCK_ON);
202 clk_enable(sdev->dacphy); 211 ret = clk_prepare_enable(sdev->dacphy);
212 if (ret < 0) {
213 dev_err(sdev->dev, "clk_prepare_enable(dacphy) failed\n");
214 goto fail;
215 }
203 /* enable DAC */ 216 /* enable DAC */
204 sdo_write_mask(sdev, SDO_DAC, ~0, SDO_POWER_ON_DAC); 217 sdo_write_mask(sdev, SDO_DAC, ~0, SDO_POWER_ON_DAC);
205 sdo_reg_debug(sdev); 218 sdo_reg_debug(sdev);
206 return 0; 219 return 0;
220
221fail:
222 sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_CLOCK_ON);
223 clk_set_rate(sdev->fout_vpll, sdev->vpll_rate);
224 return ret;
207} 225}
208 226
209static int sdo_streamoff(struct sdo_device *sdev) 227static int sdo_streamoff(struct sdo_device *sdev)
@@ -211,7 +229,7 @@ static int sdo_streamoff(struct sdo_device *sdev)
211 int tries; 229 int tries;
212 230
213 sdo_write_mask(sdev, SDO_DAC, 0, SDO_POWER_ON_DAC); 231 sdo_write_mask(sdev, SDO_DAC, 0, SDO_POWER_ON_DAC);
214 clk_disable(sdev->dacphy); 232 clk_disable_unprepare(sdev->dacphy);
215 sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_CLOCK_ON); 233 sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_CLOCK_ON);
216 for (tries = 100; tries; --tries) { 234 for (tries = 100; tries; --tries) {
217 if (sdo_read(sdev, SDO_CLKCON) & SDO_TVOUT_CLOCK_READY) 235 if (sdo_read(sdev, SDO_CLKCON) & SDO_TVOUT_CLOCK_READY)
@@ -220,6 +238,7 @@ static int sdo_streamoff(struct sdo_device *sdev)
220 } 238 }
221 if (tries == 0) 239 if (tries == 0)
222 dev_err(sdev->dev, "failed to stop streaming\n"); 240 dev_err(sdev->dev, "failed to stop streaming\n");
241 clk_set_rate(sdev->fout_vpll, sdev->vpll_rate);
223 return tries ? 0 : -EIO; 242 return tries ? 0 : -EIO;
224} 243}
225 244
@@ -254,7 +273,7 @@ static int sdo_runtime_suspend(struct device *dev)
254 dev_info(dev, "suspend\n"); 273 dev_info(dev, "suspend\n");
255 regulator_disable(sdev->vdet); 274 regulator_disable(sdev->vdet);
256 regulator_disable(sdev->vdac); 275 regulator_disable(sdev->vdac);
257 clk_disable(sdev->sclk_dac); 276 clk_disable_unprepare(sdev->sclk_dac);
258 return 0; 277 return 0;
259} 278}
260 279
@@ -266,7 +285,7 @@ static int sdo_runtime_resume(struct device *dev)
266 285
267 dev_info(dev, "resume\n"); 286 dev_info(dev, "resume\n");
268 287
269 ret = clk_enable(sdev->sclk_dac); 288 ret = clk_prepare_enable(sdev->sclk_dac);
270 if (ret < 0) 289 if (ret < 0)
271 return ret; 290 return ret;
272 291
@@ -299,7 +318,7 @@ static int sdo_runtime_resume(struct device *dev)
299vdac_r_dis: 318vdac_r_dis:
300 regulator_disable(sdev->vdac); 319 regulator_disable(sdev->vdac);
301dac_clk_dis: 320dac_clk_dis:
302 clk_disable(sdev->sclk_dac); 321 clk_disable_unprepare(sdev->sclk_dac);
303 return ret; 322 return ret;
304} 323}
305 324
@@ -405,7 +424,11 @@ static int sdo_probe(struct platform_device *pdev)
405 } 424 }
406 425
407 /* enable gate for dac clock, because mixer uses it */ 426 /* enable gate for dac clock, because mixer uses it */
408 clk_enable(sdev->dac); 427 ret = clk_prepare_enable(sdev->dac);
428 if (ret < 0) {
429 dev_err(dev, "clk_prepare_enable(dac) failed\n");
430 goto fail_fout_vpll;
431 }
409 432
410 /* configure power management */ 433 /* configure power management */
411 pm_runtime_enable(dev); 434 pm_runtime_enable(dev);
@@ -444,7 +467,7 @@ static int sdo_remove(struct platform_device *pdev)
444 struct sdo_device *sdev = sd_to_sdev(sd); 467 struct sdo_device *sdev = sd_to_sdev(sd);
445 468
446 pm_runtime_disable(&pdev->dev); 469 pm_runtime_disable(&pdev->dev);
447 clk_disable(sdev->dac); 470 clk_disable_unprepare(sdev->dac);
448 clk_put(sdev->fout_vpll); 471 clk_put(sdev->fout_vpll);
449 clk_put(sdev->dacphy); 472 clk_put(sdev->dacphy);
450 clk_put(sdev->dac); 473 clk_put(sdev->dac);
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 4f30341dc2ab..e5f1d4c14f2c 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -286,7 +286,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq,
286 vb->size = vb->height * bytes_per_line; 286 vb->size = vb->height * bytes_per_line;
287 if (vb->baddr && vb->bsize < vb->size) { 287 if (vb->baddr && vb->bsize < vb->size) {
288 /* User buffer too small */ 288 /* User buffer too small */
289 dev_warn(vq->dev, "User buffer too small: [%u] @ %lx\n", 289 dev_warn(vq->dev, "User buffer too small: [%zu] @ %lx\n",
290 vb->bsize, vb->baddr); 290 vb->bsize, vb->baddr);
291 return -EINVAL; 291 return -EINVAL;
292 } 292 }
@@ -302,9 +302,10 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq,
302 } 302 }
303 303
304 dev_dbg(vou_dev->v4l2_dev.dev, 304 dev_dbg(vou_dev->v4l2_dev.dev,
305 "%s(): fmt #%d, %u bytes per line, phys 0x%x, type %d, state %d\n", 305 "%s(): fmt #%d, %u bytes per line, phys %pad, type %d, state %d\n",
306 __func__, vou_dev->pix_idx, bytes_per_line, 306 __func__, vou_dev->pix_idx, bytes_per_line,
307 videobuf_to_dma_contig(vb), vb->memory, vb->state); 307 ({ dma_addr_t addr = videobuf_to_dma_contig(vb); &addr; }),
308 vb->memory, vb->state);
308 309
309 return 0; 310 return 0;
310} 311}
@@ -442,7 +443,7 @@ static void sh_vou_configure_geometry(struct sh_vou_device *vou_dev,
442 int pix_idx, int w_idx, int h_idx) 443 int pix_idx, int w_idx, int h_idx)
443{ 444{
444 struct sh_vou_fmt *fmt = vou_fmt + pix_idx; 445 struct sh_vou_fmt *fmt = vou_fmt + pix_idx;
445 unsigned int black_left, black_top, width_max, height_max, 446 unsigned int black_left, black_top, width_max,
446 frame_in_height, frame_out_height, frame_out_top; 447 frame_in_height, frame_out_height, frame_out_top;
447 struct v4l2_rect *rect = &vou_dev->rect; 448 struct v4l2_rect *rect = &vou_dev->rect;
448 struct v4l2_pix_format *pix = &vou_dev->pix; 449 struct v4l2_pix_format *pix = &vou_dev->pix;
@@ -450,10 +451,10 @@ static void sh_vou_configure_geometry(struct sh_vou_device *vou_dev,
450 451
451 if (vou_dev->std & V4L2_STD_525_60) { 452 if (vou_dev->std & V4L2_STD_525_60) {
452 width_max = 858; 453 width_max = 858;
453 height_max = 262; 454 /* height_max = 262; */
454 } else { 455 } else {
455 width_max = 864; 456 width_max = 864;
456 height_max = 312; 457 /* height_max = 312; */
457 } 458 }
458 459
459 frame_in_height = pix->height / 2; 460 frame_in_height = pix->height / 2;
@@ -1052,7 +1053,6 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
1052 static unsigned long j; 1053 static unsigned long j;
1053 struct videobuf_buffer *vb; 1054 struct videobuf_buffer *vb;
1054 static int cnt; 1055 static int cnt;
1055 static int side;
1056 u32 irq_status = sh_vou_reg_a_read(vou_dev, VOUIR), masked; 1056 u32 irq_status = sh_vou_reg_a_read(vou_dev, VOUIR), masked;
1057 u32 vou_status = sh_vou_reg_a_read(vou_dev, VOUSTR); 1057 u32 vou_status = sh_vou_reg_a_read(vou_dev, VOUSTR);
1058 1058
@@ -1080,7 +1080,7 @@ static irqreturn_t sh_vou_isr(int irq, void *dev_id)
1080 irq_status, masked, vou_status, cnt); 1080 irq_status, masked, vou_status, cnt);
1081 1081
1082 cnt++; 1082 cnt++;
1083 side = vou_status & 0x10000; 1083 /* side = vou_status & 0x10000; */
1084 1084
1085 /* Clear only set interrupts */ 1085 /* Clear only set interrupts */
1086 sh_vou_reg_a_write(vou_dev, VOUIR, masked); 1086 sh_vou_reg_a_write(vou_dev, VOUIR, masked);
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 104485632501..4835173d7f80 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -34,13 +34,6 @@
34#define MIN_FRAME_RATE 15 34#define MIN_FRAME_RATE 15
35#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) 35#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
36 36
37/* ISI states */
38enum {
39 ISI_STATE_IDLE = 0,
40 ISI_STATE_READY,
41 ISI_STATE_WAIT_SOF,
42};
43
44/* Frame buffer descriptor */ 37/* Frame buffer descriptor */
45struct fbd { 38struct fbd {
46 /* Physical address of the frame buffer */ 39 /* Physical address of the frame buffer */
@@ -75,11 +68,6 @@ struct atmel_isi {
75 void __iomem *regs; 68 void __iomem *regs;
76 69
77 int sequence; 70 int sequence;
78 /* State of the ISI module in capturing mode */
79 int state;
80
81 /* Wait queue for waiting for SOF */
82 wait_queue_head_t vsync_wq;
83 71
84 struct vb2_alloc_ctx *alloc_ctx; 72 struct vb2_alloc_ctx *alloc_ctx;
85 73
@@ -124,16 +112,16 @@ static int configure_geometry(struct atmel_isi *isi, u32 width,
124 case V4L2_MBUS_FMT_Y8_1X8: 112 case V4L2_MBUS_FMT_Y8_1X8:
125 cr = ISI_CFG2_GRAYSCALE; 113 cr = ISI_CFG2_GRAYSCALE;
126 break; 114 break;
127 case V4L2_MBUS_FMT_UYVY8_2X8: 115 case V4L2_MBUS_FMT_VYUY8_2X8:
128 cr = ISI_CFG2_YCC_SWAP_MODE_3; 116 cr = ISI_CFG2_YCC_SWAP_MODE_3;
129 break; 117 break;
130 case V4L2_MBUS_FMT_VYUY8_2X8: 118 case V4L2_MBUS_FMT_UYVY8_2X8:
131 cr = ISI_CFG2_YCC_SWAP_MODE_2; 119 cr = ISI_CFG2_YCC_SWAP_MODE_2;
132 break; 120 break;
133 case V4L2_MBUS_FMT_YUYV8_2X8: 121 case V4L2_MBUS_FMT_YVYU8_2X8:
134 cr = ISI_CFG2_YCC_SWAP_MODE_1; 122 cr = ISI_CFG2_YCC_SWAP_MODE_1;
135 break; 123 break;
136 case V4L2_MBUS_FMT_YVYU8_2X8: 124 case V4L2_MBUS_FMT_YUYV8_2X8:
137 cr = ISI_CFG2_YCC_SWAP_DEFAULT; 125 cr = ISI_CFG2_YCC_SWAP_DEFAULT;
138 break; 126 break;
139 /* RGB, TODO */ 127 /* RGB, TODO */
@@ -144,6 +132,8 @@ static int configure_geometry(struct atmel_isi *isi, u32 width,
144 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 132 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
145 133
146 cfg2 = isi_readl(isi, ISI_CFG2); 134 cfg2 = isi_readl(isi, ISI_CFG2);
135 /* Set YCC swap mode */
136 cfg2 &= ~ISI_CFG2_YCC_SWAP_MODE_MASK;
147 cfg2 |= cr; 137 cfg2 |= cr;
148 /* Set width */ 138 /* Set width */
149 cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK); 139 cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK);
@@ -207,12 +197,6 @@ static irqreturn_t isi_interrupt(int irq, void *dev_id)
207 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS); 197 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
208 ret = IRQ_HANDLED; 198 ret = IRQ_HANDLED;
209 } else { 199 } else {
210 if ((pending & ISI_SR_VSYNC) &&
211 (isi->state == ISI_STATE_IDLE)) {
212 isi->state = ISI_STATE_READY;
213 wake_up_interruptible(&isi->vsync_wq);
214 ret = IRQ_HANDLED;
215 }
216 if (likely(pending & ISI_SR_CXFR_DONE)) 200 if (likely(pending & ISI_SR_CXFR_DONE))
217 ret = atmel_isi_handle_streaming(isi); 201 ret = atmel_isi_handle_streaming(isi);
218 } 202 }
@@ -259,16 +243,6 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
259 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 243 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
260 struct atmel_isi *isi = ici->priv; 244 struct atmel_isi *isi = ici->priv;
261 unsigned long size; 245 unsigned long size;
262 int ret;
263
264 /* Reset ISI */
265 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
266 if (ret < 0) {
267 dev_err(icd->parent, "Reset ISI timed out\n");
268 return ret;
269 }
270 /* Disable all interrupts */
271 isi_writel(isi, ISI_INTDIS, ~0UL);
272 246
273 size = icd->sizeimage; 247 size = icd->sizeimage;
274 248
@@ -374,6 +348,7 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
374 isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); 348 isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
375 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); 349 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
376 350
351 cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
377 /* Enable linked list */ 352 /* Enable linked list */
378 cfg1 |= isi->pdata->frate | ISI_CFG1_DISCR; 353 cfg1 |= isi->pdata->frate | ISI_CFG1_DISCR;
379 354
@@ -407,43 +382,27 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
407 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 382 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
408 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 383 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
409 struct atmel_isi *isi = ici->priv; 384 struct atmel_isi *isi = ici->priv;
410
411 u32 sr = 0; 385 u32 sr = 0;
412 int ret; 386 int ret;
413 387
414 spin_lock_irq(&isi->lock); 388 /* Reset ISI */
415 isi->state = ISI_STATE_IDLE; 389 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
416 /* Clear any pending SOF interrupt */ 390 if (ret < 0) {
417 sr = isi_readl(isi, ISI_STATUS); 391 dev_err(icd->parent, "Reset ISI timed out\n");
418 /* Enable VSYNC interrupt for SOF */ 392 return ret;
419 isi_writel(isi, ISI_INTEN, ISI_SR_VSYNC);
420 isi_writel(isi, ISI_CTRL, ISI_CTRL_EN);
421 spin_unlock_irq(&isi->lock);
422
423 dev_dbg(icd->parent, "Waiting for SOF\n");
424 ret = wait_event_interruptible(isi->vsync_wq,
425 isi->state != ISI_STATE_IDLE);
426 if (ret)
427 goto err;
428
429 if (isi->state != ISI_STATE_READY) {
430 ret = -EIO;
431 goto err;
432 } 393 }
394 /* Disable all interrupts */
395 isi_writel(isi, ISI_INTDIS, ~0UL);
433 396
434 spin_lock_irq(&isi->lock); 397 spin_lock_irq(&isi->lock);
435 isi->state = ISI_STATE_WAIT_SOF; 398 /* Clear any pending interrupt */
436 isi_writel(isi, ISI_INTDIS, ISI_SR_VSYNC); 399 sr = isi_readl(isi, ISI_STATUS);
400
437 if (count) 401 if (count)
438 start_dma(isi, isi->active); 402 start_dma(isi, isi->active);
439 spin_unlock_irq(&isi->lock); 403 spin_unlock_irq(&isi->lock);
440 404
441 return 0; 405 return 0;
442err:
443 isi->active = NULL;
444 isi->sequence = 0;
445 INIT_LIST_HEAD(&isi->video_buffer_list);
446 return ret;
447} 406}
448 407
449/* abort streaming and wait for last buffer */ 408/* abort streaming and wait for last buffer */
@@ -765,14 +724,16 @@ static int isi_camera_clock_start(struct soc_camera_host *ici)
765 struct atmel_isi *isi = ici->priv; 724 struct atmel_isi *isi = ici->priv;
766 int ret; 725 int ret;
767 726
768 ret = clk_enable(isi->pclk); 727 ret = clk_prepare_enable(isi->pclk);
769 if (ret) 728 if (ret)
770 return ret; 729 return ret;
771 730
772 ret = clk_enable(isi->mck); 731 if (!IS_ERR(isi->mck)) {
773 if (ret) { 732 ret = clk_prepare_enable(isi->mck);
774 clk_disable(isi->pclk); 733 if (ret) {
775 return ret; 734 clk_disable_unprepare(isi->pclk);
735 return ret;
736 }
776 } 737 }
777 738
778 return 0; 739 return 0;
@@ -783,8 +744,9 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici)
783{ 744{
784 struct atmel_isi *isi = ici->priv; 745 struct atmel_isi *isi = ici->priv;
785 746
786 clk_disable(isi->mck); 747 if (!IS_ERR(isi->mck))
787 clk_disable(isi->pclk); 748 clk_disable_unprepare(isi->mck);
749 clk_disable_unprepare(isi->pclk);
788} 750}
789 751
790static unsigned int isi_camera_poll(struct file *file, poll_table *pt) 752static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
@@ -906,7 +868,6 @@ static int atmel_isi_remove(struct platform_device *pdev)
906 struct atmel_isi *isi = container_of(soc_host, 868 struct atmel_isi *isi = container_of(soc_host,
907 struct atmel_isi, soc_host); 869 struct atmel_isi, soc_host);
908 870
909 free_irq(isi->irq, isi);
910 soc_camera_host_unregister(soc_host); 871 soc_camera_host_unregister(soc_host);
911 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx); 872 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
912 dma_free_coherent(&pdev->dev, 873 dma_free_coherent(&pdev->dev,
@@ -914,13 +875,6 @@ static int atmel_isi_remove(struct platform_device *pdev)
914 isi->p_fb_descriptors, 875 isi->p_fb_descriptors,
915 isi->fb_descriptors_phys); 876 isi->fb_descriptors_phys);
916 877
917 iounmap(isi->regs);
918 clk_unprepare(isi->mck);
919 clk_put(isi->mck);
920 clk_unprepare(isi->pclk);
921 clk_put(isi->pclk);
922 kfree(isi);
923
924 return 0; 878 return 0;
925} 879}
926 880
@@ -928,7 +882,6 @@ static int atmel_isi_probe(struct platform_device *pdev)
928{ 882{
929 unsigned int irq; 883 unsigned int irq;
930 struct atmel_isi *isi; 884 struct atmel_isi *isi;
931 struct clk *pclk;
932 struct resource *regs; 885 struct resource *regs;
933 int ret, i; 886 int ret, i;
934 struct device *dev = &pdev->dev; 887 struct device *dev = &pdev->dev;
@@ -936,64 +889,50 @@ static int atmel_isi_probe(struct platform_device *pdev)
936 struct isi_platform_data *pdata; 889 struct isi_platform_data *pdata;
937 890
938 pdata = dev->platform_data; 891 pdata = dev->platform_data;
939 if (!pdata || !pdata->data_width_flags || !pdata->mck_hz) { 892 if (!pdata || !pdata->data_width_flags) {
940 dev_err(&pdev->dev, 893 dev_err(&pdev->dev,
941 "No config available for Atmel ISI\n"); 894 "No config available for Atmel ISI\n");
942 return -EINVAL; 895 return -EINVAL;
943 } 896 }
944 897
945 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 898 isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
946 if (!regs)
947 return -ENXIO;
948
949 pclk = clk_get(&pdev->dev, "isi_clk");
950 if (IS_ERR(pclk))
951 return PTR_ERR(pclk);
952
953 ret = clk_prepare(pclk);
954 if (ret)
955 goto err_clk_prepare_pclk;
956
957 isi = kzalloc(sizeof(struct atmel_isi), GFP_KERNEL);
958 if (!isi) { 899 if (!isi) {
959 ret = -ENOMEM;
960 dev_err(&pdev->dev, "Can't allocate interface!\n"); 900 dev_err(&pdev->dev, "Can't allocate interface!\n");
961 goto err_alloc_isi; 901 return -ENOMEM;
962 } 902 }
963 903
964 isi->pclk = pclk; 904 isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
905 if (IS_ERR(isi->pclk))
906 return PTR_ERR(isi->pclk);
907
965 isi->pdata = pdata; 908 isi->pdata = pdata;
966 isi->active = NULL; 909 isi->active = NULL;
967 spin_lock_init(&isi->lock); 910 spin_lock_init(&isi->lock);
968 init_waitqueue_head(&isi->vsync_wq);
969 INIT_LIST_HEAD(&isi->video_buffer_list); 911 INIT_LIST_HEAD(&isi->video_buffer_list);
970 INIT_LIST_HEAD(&isi->dma_desc_head); 912 INIT_LIST_HEAD(&isi->dma_desc_head);
971 913
972 /* Get ISI_MCK, provided by programmable clock or external clock */ 914 /* ISI_MCK is the sensor master clock. It should be handled by the
973 isi->mck = clk_get(dev, "isi_mck"); 915 * sensor driver directly, as the ISI has no use for that clock. Make
974 if (IS_ERR(isi->mck)) { 916 * the clock optional here while platforms transition to the correct
975 dev_err(dev, "Failed to get isi_mck\n"); 917 * model.
976 ret = PTR_ERR(isi->mck); 918 */
977 goto err_clk_get; 919 isi->mck = devm_clk_get(dev, "isi_mck");
920 if (!IS_ERR(isi->mck)) {
921 /* Set ISI_MCK's frequency, it should be faster than pixel
922 * clock.
923 */
924 ret = clk_set_rate(isi->mck, pdata->mck_hz);
925 if (ret < 0)
926 return ret;
978 } 927 }
979 928
980 ret = clk_prepare(isi->mck);
981 if (ret)
982 goto err_clk_prepare_mck;
983
984 /* Set ISI_MCK's frequency, it should be faster than pixel clock */
985 ret = clk_set_rate(isi->mck, pdata->mck_hz);
986 if (ret < 0)
987 goto err_set_mck_rate;
988
989 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev, 929 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
990 sizeof(struct fbd) * MAX_BUFFER_NUM, 930 sizeof(struct fbd) * MAX_BUFFER_NUM,
991 &isi->fb_descriptors_phys, 931 &isi->fb_descriptors_phys,
992 GFP_KERNEL); 932 GFP_KERNEL);
993 if (!isi->p_fb_descriptors) { 933 if (!isi->p_fb_descriptors) {
994 ret = -ENOMEM;
995 dev_err(&pdev->dev, "Can't allocate descriptors!\n"); 934 dev_err(&pdev->dev, "Can't allocate descriptors!\n");
996 goto err_alloc_descriptors; 935 return -ENOMEM;
997 } 936 }
998 937
999 for (i = 0; i < MAX_BUFFER_NUM; i++) { 938 for (i = 0; i < MAX_BUFFER_NUM; i++) {
@@ -1009,9 +948,10 @@ static int atmel_isi_probe(struct platform_device *pdev)
1009 goto err_alloc_ctx; 948 goto err_alloc_ctx;
1010 } 949 }
1011 950
1012 isi->regs = ioremap(regs->start, resource_size(regs)); 951 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1013 if (!isi->regs) { 952 isi->regs = devm_ioremap_resource(&pdev->dev, regs);
1014 ret = -ENOMEM; 953 if (IS_ERR(isi->regs)) {
954 ret = PTR_ERR(isi->regs);
1015 goto err_ioremap; 955 goto err_ioremap;
1016 } 956 }
1017 957
@@ -1028,7 +968,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
1028 goto err_req_irq; 968 goto err_req_irq;
1029 } 969 }
1030 970
1031 ret = request_irq(irq, isi_interrupt, 0, "isi", isi); 971 ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1032 if (ret) { 972 if (ret) {
1033 dev_err(&pdev->dev, "Unable to request irq %d\n", irq); 973 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1034 goto err_req_irq; 974 goto err_req_irq;
@@ -1050,9 +990,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
1050 return 0; 990 return 0;
1051 991
1052err_register_soc_camera_host: 992err_register_soc_camera_host:
1053 free_irq(isi->irq, isi);
1054err_req_irq: 993err_req_irq:
1055 iounmap(isi->regs);
1056err_ioremap: 994err_ioremap:
1057 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx); 995 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
1058err_alloc_ctx: 996err_alloc_ctx:
@@ -1060,17 +998,6 @@ err_alloc_ctx:
1060 sizeof(struct fbd) * MAX_BUFFER_NUM, 998 sizeof(struct fbd) * MAX_BUFFER_NUM,
1061 isi->p_fb_descriptors, 999 isi->p_fb_descriptors,
1062 isi->fb_descriptors_phys); 1000 isi->fb_descriptors_phys);
1063err_alloc_descriptors:
1064err_set_mck_rate:
1065 clk_unprepare(isi->mck);
1066err_clk_prepare_mck:
1067 clk_put(isi->mck);
1068err_clk_get:
1069 kfree(isi);
1070err_alloc_isi:
1071 clk_unprepare(pclk);
1072err_clk_prepare_pclk:
1073 clk_put(pclk);
1074 1001
1075 return ret; 1002 return ret;
1076} 1003}
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 45a0276be4e5..d73abca9c6ee 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -659,7 +659,7 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
659 unsigned long flags; 659 unsigned long flags;
660 660
661 if (count < 2) 661 if (count < 2)
662 return -EINVAL; 662 return -ENOBUFS;
663 663
664 spin_lock_irqsave(&pcdev->lock, flags); 664 spin_lock_irqsave(&pcdev->lock, flags);
665 665
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
index 6866bb4fbebc..3b1c05a72d00 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -106,7 +106,7 @@
106#define VIN_MAX_HEIGHT 2048 106#define VIN_MAX_HEIGHT 2048
107 107
108enum chip_id { 108enum chip_id {
109 RCAR_H2, 109 RCAR_GEN2,
110 RCAR_H1, 110 RCAR_H1,
111 RCAR_M1, 111 RCAR_M1,
112 RCAR_E1, 112 RCAR_E1,
@@ -302,7 +302,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
302 dmr = 0; 302 dmr = 0;
303 break; 303 break;
304 case V4L2_PIX_FMT_RGB32: 304 case V4L2_PIX_FMT_RGB32:
305 if (priv->chip == RCAR_H2 || priv->chip == RCAR_H1 || 305 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
306 priv->chip == RCAR_E1) { 306 priv->chip == RCAR_E1) {
307 dmr = VNDMR_EXRGB; 307 dmr = VNDMR_EXRGB;
308 break; 308 break;
@@ -1384,7 +1384,8 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
1384}; 1384};
1385 1385
1386static struct platform_device_id rcar_vin_id_table[] = { 1386static struct platform_device_id rcar_vin_id_table[] = {
1387 { "r8a7790-vin", RCAR_H2 }, 1387 { "r8a7791-vin", RCAR_GEN2 },
1388 { "r8a7790-vin", RCAR_GEN2 },
1388 { "r8a7779-vin", RCAR_H1 }, 1389 { "r8a7779-vin", RCAR_H1 },
1389 { "r8a7778-vin", RCAR_M1 }, 1390 { "r8a7778-vin", RCAR_M1 },
1390 { "uPD35004-vin", RCAR_E1 }, 1391 { "uPD35004-vin", RCAR_E1 },
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
index cbd3a34f4f3f..8e74fb7f2a07 100644
--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -141,8 +141,8 @@ int soc_camera_client_s_crop(struct v4l2_subdev *sd,
141 * Popular special case - some cameras can only handle fixed sizes like 141 * Popular special case - some cameras can only handle fixed sizes like
142 * QVGA, VGA,... Take care to avoid infinite loop. 142 * QVGA, VGA,... Take care to avoid infinite loop.
143 */ 143 */
144 width = max(cam_rect->width, 2); 144 width = max_t(unsigned int, cam_rect->width, 2);
145 height = max(cam_rect->height, 2); 145 height = max_t(unsigned int, cam_rect->height, 2);
146 146
147 /* 147 /*
148 * Loop as long as sensor is not covering the requested rectangle and 148 * Loop as long as sensor is not covering the requested rectangle and
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile
index cbf0a806ba1d..be680f839e77 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti-vpe/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o 1obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
2 2
3ti-vpe-y := vpe.o vpdma.o 3ti-vpe-y := vpe.o sc.o csc.o vpdma.o
4 4
5ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG 5ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c
new file mode 100644
index 000000000000..acfea500710e
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/csc.c
@@ -0,0 +1,196 @@
1/*
2 * Color space converter library
3 *
4 * Copyright (c) 2013 Texas Instruments Inc.
5 *
6 * David Griego, <dagriego@biglakesoftware.com>
7 * Dale Farnsworth, <dale@farnsworth.org>
8 * Archit Taneja, <archit@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 */
14
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/videodev2.h>
20
21#include "csc.h"
22
23/*
24 * 16 coefficients in the order:
25 * a0, b0, c0, a1, b1, c1, a2, b2, c2, d0, d1, d2
26 * (we may need to pass non-default values from user space later on, we might
27 * need to make the coefficient struct more easy to populate)
28 */
29struct colorspace_coeffs {
30 u16 sd[12];
31 u16 hd[12];
32};
33
34/* VIDEO_RANGE: limited range, GRAPHICS_RANGE: full range */
35#define CSC_COEFFS_VIDEO_RANGE_Y2R 0
36#define CSC_COEFFS_GRAPHICS_RANGE_Y2R 1
37#define CSC_COEFFS_VIDEO_RANGE_R2Y 2
38#define CSC_COEFFS_GRAPHICS_RANGE_R2Y 3
39
40/* default colorspace coefficients */
41static struct colorspace_coeffs colorspace_coeffs[4] = {
42 [CSC_COEFFS_VIDEO_RANGE_Y2R] = {
43 {
44 /* SDTV */
45 0x0400, 0x0000, 0x057D, 0x0400, 0x1EA7, 0x1D35,
46 0x0400, 0x06EF, 0x1FFE, 0x0D40, 0x0210, 0x0C88,
47 },
48 {
49 /* HDTV */
50 0x0400, 0x0000, 0x0629, 0x0400, 0x1F45, 0x1E2B,
51 0x0400, 0x0742, 0x0000, 0x0CEC, 0x0148, 0x0C60,
52 },
53 },
54 [CSC_COEFFS_GRAPHICS_RANGE_Y2R] = {
55 {
56 /* SDTV */
57 0x04A8, 0x1FFE, 0x0662, 0x04A8, 0x1E6F, 0x1CBF,
58 0x04A8, 0x0812, 0x1FFF, 0x0C84, 0x0220, 0x0BAC,
59 },
60 {
61 /* HDTV */
62 0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
63 0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
64 },
65 },
66 [CSC_COEFFS_VIDEO_RANGE_R2Y] = {
67 {
68 /* SDTV */
69 0x0132, 0x0259, 0x0075, 0x1F50, 0x1EA5, 0x020B,
70 0x020B, 0x1E4A, 0x1FAB, 0x0000, 0x0200, 0x0200,
71 },
72 {
73 /* HDTV */
74 0x00DA, 0x02DC, 0x004A, 0x1F88, 0x1E6C, 0x020C,
75 0x020C, 0x1E24, 0x1FD0, 0x0000, 0x0200, 0x0200,
76 },
77 },
78 [CSC_COEFFS_GRAPHICS_RANGE_R2Y] = {
79 {
80 /* SDTV */
81 0x0107, 0x0204, 0x0064, 0x1F68, 0x1ED6, 0x01C2,
82 0x01C2, 0x1E87, 0x1FB7, 0x0040, 0x0200, 0x0200,
83 },
84 {
85 /* HDTV */
86 0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
87 0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
88 },
89 },
90};
91
92void csc_dump_regs(struct csc_data *csc)
93{
94 struct device *dev = &csc->pdev->dev;
95
96 u32 read_reg(struct csc_data *csc, int offset)
97 {
98 return ioread32(csc->base + offset);
99 }
100
101#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(csc, CSC_##r))
102
103 DUMPREG(CSC00);
104 DUMPREG(CSC01);
105 DUMPREG(CSC02);
106 DUMPREG(CSC03);
107 DUMPREG(CSC04);
108 DUMPREG(CSC05);
109
110#undef DUMPREG
111}
112
113void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5)
114{
115 *csc_reg5 |= CSC_BYPASS;
116}
117
118/*
119 * set the color space converter coefficient shadow register values
120 */
121void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
122 enum v4l2_colorspace src_colorspace,
123 enum v4l2_colorspace dst_colorspace)
124{
125 u32 *csc_reg5 = csc_reg0 + 5;
126 u32 *shadow_csc = csc_reg0;
127 struct colorspace_coeffs *sd_hd_coeffs;
128 u16 *coeff, *end_coeff;
129 enum v4l2_colorspace yuv_colorspace;
130 int sel = 0;
131
132 /*
133 * support only graphics data range(full range) for now, a control ioctl
134 * would be nice here
135 */
136 /* Y2R */
137 if (dst_colorspace == V4L2_COLORSPACE_SRGB &&
138 (src_colorspace == V4L2_COLORSPACE_SMPTE170M ||
139 src_colorspace == V4L2_COLORSPACE_REC709)) {
140 /* Y2R */
141 sel = 1;
142 yuv_colorspace = src_colorspace;
143 } else if ((dst_colorspace == V4L2_COLORSPACE_SMPTE170M ||
144 dst_colorspace == V4L2_COLORSPACE_REC709) &&
145 src_colorspace == V4L2_COLORSPACE_SRGB) {
146 /* R2Y */
147 sel = 3;
148 yuv_colorspace = dst_colorspace;
149 } else {
150 *csc_reg5 |= CSC_BYPASS;
151 return;
152 }
153
154 sd_hd_coeffs = &colorspace_coeffs[sel];
155
156 /* select between SD or HD coefficients */
157 if (yuv_colorspace == V4L2_COLORSPACE_SMPTE170M)
158 coeff = sd_hd_coeffs->sd;
159 else
160 coeff = sd_hd_coeffs->hd;
161
162 end_coeff = coeff + 12;
163
164 for (; coeff < end_coeff; coeff += 2)
165 *shadow_csc++ = (*(coeff + 1) << 16) | *coeff;
166}
167
168struct csc_data *csc_create(struct platform_device *pdev)
169{
170 struct csc_data *csc;
171
172 dev_dbg(&pdev->dev, "csc_create\n");
173
174 csc = devm_kzalloc(&pdev->dev, sizeof(*csc), GFP_KERNEL);
175 if (!csc) {
176 dev_err(&pdev->dev, "couldn't alloc csc_data\n");
177 return ERR_PTR(-ENOMEM);
178 }
179
180 csc->pdev = pdev;
181
182 csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
183 "vpe_csc");
184 if (csc->res == NULL) {
185 dev_err(&pdev->dev, "missing platform resources data\n");
186 return ERR_PTR(-ENODEV);
187 }
188
189 csc->base = devm_ioremap_resource(&pdev->dev, csc->res);
190 if (!csc->base) {
191 dev_err(&pdev->dev, "failed to ioremap\n");
192 return ERR_PTR(-ENOMEM);
193 }
194
195 return csc;
196}
diff --git a/drivers/media/platform/ti-vpe/csc.h b/drivers/media/platform/ti-vpe/csc.h
new file mode 100644
index 000000000000..1ad2b6dad561
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/csc.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2013 Texas Instruments Inc.
3 *
4 * David Griego, <dagriego@biglakesoftware.com>
5 * Dale Farnsworth, <dale@farnsworth.org>
6 * Archit Taneja, <archit@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12#ifndef TI_CSC_H
13#define TI_CSC_H
14
15/* VPE color space converter regs */
16#define CSC_CSC00 0x00
17#define CSC_A0_MASK 0x1fff
18#define CSC_A0_SHIFT 0
19#define CSC_B0_MASK 0x1fff
20#define CSC_B0_SHIFT 16
21
22#define CSC_CSC01 0x04
23#define CSC_C0_MASK 0x1fff
24#define CSC_C0_SHIFT 0
25#define CSC_A1_MASK 0x1fff
26#define CSC_A1_SHIFT 16
27
28#define CSC_CSC02 0x08
29#define CSC_B1_MASK 0x1fff
30#define CSC_B1_SHIFT 0
31#define CSC_C1_MASK 0x1fff
32#define CSC_C1_SHIFT 16
33
34#define CSC_CSC03 0x0c
35#define CSC_A2_MASK 0x1fff
36#define CSC_A2_SHIFT 0
37#define CSC_B2_MASK 0x1fff
38#define CSC_B2_SHIFT 16
39
40#define CSC_CSC04 0x10
41#define CSC_C2_MASK 0x1fff
42#define CSC_C2_SHIFT 0
43#define CSC_D0_MASK 0x0fff
44#define CSC_D0_SHIFT 16
45
46#define CSC_CSC05 0x14
47#define CSC_D1_MASK 0x0fff
48#define CSC_D1_SHIFT 0
49#define CSC_D2_MASK 0x0fff
50#define CSC_D2_SHIFT 16
51
52#define CSC_BYPASS (1 << 28)
53
54struct csc_data {
55 void __iomem *base;
56 struct resource *res;
57
58 struct platform_device *pdev;
59};
60
61void csc_dump_regs(struct csc_data *csc);
62void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5);
63void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
64 enum v4l2_colorspace src_colorspace,
65 enum v4l2_colorspace dst_colorspace);
66struct csc_data *csc_create(struct platform_device *pdev);
67
68#endif
diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c
new file mode 100644
index 000000000000..93f0af546b76
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/sc.c
@@ -0,0 +1,311 @@
1/*
2 * Scaler library
3 *
4 * Copyright (c) 2013 Texas Instruments Inc.
5 *
6 * David Griego, <dagriego@biglakesoftware.com>
7 * Dale Farnsworth, <dale@farnsworth.org>
8 * Archit Taneja, <archit@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 */
14
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19
20#include "sc.h"
21#include "sc_coeff.h"
22
23void sc_dump_regs(struct sc_data *sc)
24{
25 struct device *dev = &sc->pdev->dev;
26
27 u32 read_reg(struct sc_data *sc, int offset)
28 {
29 return ioread32(sc->base + offset);
30 }
31
32#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(sc, CFG_##r))
33
34 DUMPREG(SC0);
35 DUMPREG(SC1);
36 DUMPREG(SC2);
37 DUMPREG(SC3);
38 DUMPREG(SC4);
39 DUMPREG(SC5);
40 DUMPREG(SC6);
41 DUMPREG(SC8);
42 DUMPREG(SC9);
43 DUMPREG(SC10);
44 DUMPREG(SC11);
45 DUMPREG(SC12);
46 DUMPREG(SC13);
47 DUMPREG(SC17);
48 DUMPREG(SC18);
49 DUMPREG(SC19);
50 DUMPREG(SC20);
51 DUMPREG(SC21);
52 DUMPREG(SC22);
53 DUMPREG(SC23);
54 DUMPREG(SC24);
55 DUMPREG(SC25);
56
57#undef DUMPREG
58}
59
60/*
61 * set the horizontal scaler coefficients according to the ratio of output to
62 * input widths, after accounting for up to two levels of decimation
63 */
64void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
65 unsigned int dst_w)
66{
67 int sixteenths;
68 int idx;
69 int i, j;
70 u16 *coeff_h = addr;
71 const u16 *cp;
72
73 if (dst_w > src_w) {
74 idx = HS_UP_SCALE;
75 } else {
76 if ((dst_w << 1) < src_w)
77 dst_w <<= 1; /* first level decimation */
78 if ((dst_w << 1) < src_w)
79 dst_w <<= 1; /* second level decimation */
80
81 if (dst_w == src_w) {
82 idx = HS_LE_16_16_SCALE;
83 } else {
84 sixteenths = (dst_w << 4) / src_w;
85 if (sixteenths < 8)
86 sixteenths = 8;
87 idx = HS_LT_9_16_SCALE + sixteenths - 8;
88 }
89 }
90
91 if (idx == sc->hs_index)
92 return;
93
94 cp = scaler_hs_coeffs[idx];
95
96 for (i = 0; i < SC_NUM_PHASES * 2; i++) {
97 for (j = 0; j < SC_H_NUM_TAPS; j++)
98 *coeff_h++ = *cp++;
99 /*
100 * for each phase, the scaler expects space for 8 coefficients
101 * in it's memory. For the horizontal scaler, we copy the first
102 * 7 coefficients and skip the last slot to move to the next
103 * row to hold coefficients for the next phase
104 */
105 coeff_h += SC_NUM_TAPS_MEM_ALIGN - SC_H_NUM_TAPS;
106 }
107
108 sc->hs_index = idx;
109
110 sc->load_coeff_h = true;
111}
112
113/*
114 * set the vertical scaler coefficients according to the ratio of output to
115 * input heights
116 */
117void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
118 unsigned int dst_h)
119{
120 int sixteenths;
121 int idx;
122 int i, j;
123 u16 *coeff_v = addr;
124 const u16 *cp;
125
126 if (dst_h > src_h) {
127 idx = VS_UP_SCALE;
128 } else if (dst_h == src_h) {
129 idx = VS_1_TO_1_SCALE;
130 } else {
131 sixteenths = (dst_h << 4) / src_h;
132 if (sixteenths < 8)
133 sixteenths = 8;
134 idx = VS_LT_9_16_SCALE + sixteenths - 8;
135 }
136
137 if (idx == sc->vs_index)
138 return;
139
140 cp = scaler_vs_coeffs[idx];
141
142 for (i = 0; i < SC_NUM_PHASES * 2; i++) {
143 for (j = 0; j < SC_V_NUM_TAPS; j++)
144 *coeff_v++ = *cp++;
145 /*
146 * for the vertical scaler, we copy the first 5 coefficients and
147 * skip the last 3 slots to move to the next row to hold
148 * coefficients for the next phase
149 */
150 coeff_v += SC_NUM_TAPS_MEM_ALIGN - SC_V_NUM_TAPS;
151 }
152
153 sc->vs_index = idx;
154 sc->load_coeff_v = true;
155}
156
157void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
158 u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
159 unsigned int dst_w, unsigned int dst_h)
160{
161 struct device *dev = &sc->pdev->dev;
162 u32 val;
163 int dcm_x, dcm_shift;
164 bool use_rav;
165 unsigned long lltmp;
166 u32 lin_acc_inc, lin_acc_inc_u;
167 u32 col_acc_offset;
168 u16 factor = 0;
169 int row_acc_init_rav = 0, row_acc_init_rav_b = 0;
170 u32 row_acc_inc = 0, row_acc_offset = 0, row_acc_offset_b = 0;
171 /*
172 * location of SC register in payload memory with respect to the first
173 * register in the mmr address data block
174 */
175 u32 *sc_reg9 = sc_reg8 + 1;
176 u32 *sc_reg12 = sc_reg8 + 4;
177 u32 *sc_reg13 = sc_reg8 + 5;
178 u32 *sc_reg24 = sc_reg17 + 7;
179
180 val = sc_reg0[0];
181
182 /* clear all the features(they may get enabled elsewhere later) */
183 val &= ~(CFG_SELFGEN_FID | CFG_TRIM | CFG_ENABLE_SIN2_VER_INTP |
184 CFG_INTERLACE_I | CFG_DCM_4X | CFG_DCM_2X | CFG_AUTO_HS |
185 CFG_ENABLE_EV | CFG_USE_RAV | CFG_INVT_FID | CFG_SC_BYPASS |
186 CFG_INTERLACE_O | CFG_Y_PK_EN | CFG_HP_BYPASS | CFG_LINEAR);
187
188 if (src_w == dst_w && src_h == dst_h) {
189 val |= CFG_SC_BYPASS;
190 sc_reg0[0] = val;
191 return;
192 }
193
194 /* we only support linear scaling for now */
195 val |= CFG_LINEAR;
196
197 /* configure horizontal scaler */
198
199 /* enable 2X or 4X decimation */
200 dcm_x = src_w / dst_w;
201 if (dcm_x > 4) {
202 val |= CFG_DCM_4X;
203 dcm_shift = 2;
204 } else if (dcm_x > 2) {
205 val |= CFG_DCM_2X;
206 dcm_shift = 1;
207 } else {
208 dcm_shift = 0;
209 }
210
211 lltmp = dst_w - 1;
212 lin_acc_inc = div64_u64(((u64)(src_w >> dcm_shift) - 1) << 24, lltmp);
213 lin_acc_inc_u = 0;
214 col_acc_offset = 0;
215
216 dev_dbg(dev, "hs config: src_w = %d, dst_w = %d, decimation = %s, lin_acc_inc = %08x\n",
217 src_w, dst_w, dcm_shift == 2 ? "4x" :
218 (dcm_shift == 1 ? "2x" : "none"), lin_acc_inc);
219
220 /* configure vertical scaler */
221
222 /* use RAV for vertical scaler if vertical downscaling is > 4x */
223 if (dst_h < (src_h >> 2)) {
224 use_rav = true;
225 val |= CFG_USE_RAV;
226 } else {
227 use_rav = false;
228 }
229
230 if (use_rav) {
231 /* use RAV */
232 factor = (u16) ((dst_h << 10) / src_h);
233
234 row_acc_init_rav = factor + ((1 + factor) >> 1);
235 if (row_acc_init_rav >= 1024)
236 row_acc_init_rav -= 1024;
237
238 row_acc_init_rav_b = row_acc_init_rav +
239 (1 + (row_acc_init_rav >> 1)) -
240 (1024 >> 1);
241
242 if (row_acc_init_rav_b < 0) {
243 row_acc_init_rav_b += row_acc_init_rav;
244 row_acc_init_rav *= 2;
245 }
246
247 dev_dbg(dev, "vs config(RAV): src_h = %d, dst_h = %d, factor = %d, acc_init = %08x, acc_init_b = %08x\n",
248 src_h, dst_h, factor, row_acc_init_rav,
249 row_acc_init_rav_b);
250 } else {
251 /* use polyphase */
252 row_acc_inc = ((src_h - 1) << 16) / (dst_h - 1);
253 row_acc_offset = 0;
254 row_acc_offset_b = 0;
255
256 dev_dbg(dev, "vs config(POLY): src_h = %d, dst_h = %d,row_acc_inc = %08x\n",
257 src_h, dst_h, row_acc_inc);
258 }
259
260
261 sc_reg0[0] = val;
262 sc_reg0[1] = row_acc_inc;
263 sc_reg0[2] = row_acc_offset;
264 sc_reg0[3] = row_acc_offset_b;
265
266 sc_reg0[4] = ((lin_acc_inc_u & CFG_LIN_ACC_INC_U_MASK) <<
267 CFG_LIN_ACC_INC_U_SHIFT) | (dst_w << CFG_TAR_W_SHIFT) |
268 (dst_h << CFG_TAR_H_SHIFT);
269
270 sc_reg0[5] = (src_w << CFG_SRC_W_SHIFT) | (src_h << CFG_SRC_H_SHIFT);
271
272 sc_reg0[6] = (row_acc_init_rav_b << CFG_ROW_ACC_INIT_RAV_B_SHIFT) |
273 (row_acc_init_rav << CFG_ROW_ACC_INIT_RAV_SHIFT);
274
275 *sc_reg9 = lin_acc_inc;
276
277 *sc_reg12 = col_acc_offset << CFG_COL_ACC_OFFSET_SHIFT;
278
279 *sc_reg13 = factor;
280
281 *sc_reg24 = (src_w << CFG_ORG_W_SHIFT) | (src_h << CFG_ORG_H_SHIFT);
282}
283
284struct sc_data *sc_create(struct platform_device *pdev)
285{
286 struct sc_data *sc;
287
288 dev_dbg(&pdev->dev, "sc_create\n");
289
290 sc = devm_kzalloc(&pdev->dev, sizeof(*sc), GFP_KERNEL);
291 if (!sc) {
292 dev_err(&pdev->dev, "couldn't alloc sc_data\n");
293 return ERR_PTR(-ENOMEM);
294 }
295
296 sc->pdev = pdev;
297
298 sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sc");
299 if (!sc->res) {
300 dev_err(&pdev->dev, "missing platform resources data\n");
301 return ERR_PTR(-ENODEV);
302 }
303
304 sc->base = devm_ioremap_resource(&pdev->dev, sc->res);
305 if (!sc->base) {
306 dev_err(&pdev->dev, "failed to ioremap\n");
307 return ERR_PTR(-ENOMEM);
308 }
309
310 return sc;
311}
diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h
new file mode 100644
index 000000000000..60e411e05c30
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/sc.h
@@ -0,0 +1,208 @@
1/*
2 * Copyright (c) 2013 Texas Instruments Inc.
3 *
4 * David Griego, <dagriego@biglakesoftware.com>
5 * Dale Farnsworth, <dale@farnsworth.org>
6 * Archit Taneja, <archit@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 */
12#ifndef TI_SC_H
13#define TI_SC_H
14
15/* Scaler regs */
16#define CFG_SC0 0x0
17#define CFG_INTERLACE_O (1 << 0)
18#define CFG_LINEAR (1 << 1)
19#define CFG_SC_BYPASS (1 << 2)
20#define CFG_INVT_FID (1 << 3)
21#define CFG_USE_RAV (1 << 4)
22#define CFG_ENABLE_EV (1 << 5)
23#define CFG_AUTO_HS (1 << 6)
24#define CFG_DCM_2X (1 << 7)
25#define CFG_DCM_4X (1 << 8)
26#define CFG_HP_BYPASS (1 << 9)
27#define CFG_INTERLACE_I (1 << 10)
28#define CFG_ENABLE_SIN2_VER_INTP (1 << 11)
29#define CFG_Y_PK_EN (1 << 14)
30#define CFG_TRIM (1 << 15)
31#define CFG_SELFGEN_FID (1 << 16)
32
33#define CFG_SC1 0x4
34#define CFG_ROW_ACC_INC_MASK 0x07ffffff
35#define CFG_ROW_ACC_INC_SHIFT 0
36
37#define CFG_SC2 0x08
38#define CFG_ROW_ACC_OFFSET_MASK 0x0fffffff
39#define CFG_ROW_ACC_OFFSET_SHIFT 0
40
41#define CFG_SC3 0x0c
42#define CFG_ROW_ACC_OFFSET_B_MASK 0x0fffffff
43#define CFG_ROW_ACC_OFFSET_B_SHIFT 0
44
45#define CFG_SC4 0x10
46#define CFG_TAR_H_MASK 0x07ff
47#define CFG_TAR_H_SHIFT 0
48#define CFG_TAR_W_MASK 0x07ff
49#define CFG_TAR_W_SHIFT 12
50#define CFG_LIN_ACC_INC_U_MASK 0x07
51#define CFG_LIN_ACC_INC_U_SHIFT 24
52#define CFG_NLIN_ACC_INIT_U_MASK 0x07
53#define CFG_NLIN_ACC_INIT_U_SHIFT 28
54
55#define CFG_SC5 0x14
56#define CFG_SRC_H_MASK 0x07ff
57#define CFG_SRC_H_SHIFT 0
58#define CFG_SRC_W_MASK 0x07ff
59#define CFG_SRC_W_SHIFT 12
60#define CFG_NLIN_ACC_INC_U_MASK 0x07
61#define CFG_NLIN_ACC_INC_U_SHIFT 24
62
63#define CFG_SC6 0x18
64#define CFG_ROW_ACC_INIT_RAV_MASK 0x03ff
65#define CFG_ROW_ACC_INIT_RAV_SHIFT 0
66#define CFG_ROW_ACC_INIT_RAV_B_MASK 0x03ff
67#define CFG_ROW_ACC_INIT_RAV_B_SHIFT 10
68
69#define CFG_SC8 0x20
70#define CFG_NLIN_LEFT_MASK 0x07ff
71#define CFG_NLIN_LEFT_SHIFT 0
72#define CFG_NLIN_RIGHT_MASK 0x07ff
73#define CFG_NLIN_RIGHT_SHIFT 12
74
75#define CFG_SC9 0x24
76#define CFG_LIN_ACC_INC CFG_SC9
77
78#define CFG_SC10 0x28
79#define CFG_NLIN_ACC_INIT CFG_SC10
80
81#define CFG_SC11 0x2c
82#define CFG_NLIN_ACC_INC CFG_SC11
83
84#define CFG_SC12 0x30
85#define CFG_COL_ACC_OFFSET_MASK 0x01ffffff
86#define CFG_COL_ACC_OFFSET_SHIFT 0
87
88#define CFG_SC13 0x34
89#define CFG_SC_FACTOR_RAV_MASK 0xff
90#define CFG_SC_FACTOR_RAV_SHIFT 0
91#define CFG_CHROMA_INTP_THR_MASK 0x03ff
92#define CFG_CHROMA_INTP_THR_SHIFT 12
93#define CFG_DELTA_CHROMA_THR_MASK 0x0f
94#define CFG_DELTA_CHROMA_THR_SHIFT 24
95
96#define CFG_SC17 0x44
97#define CFG_EV_THR_MASK 0x03ff
98#define CFG_EV_THR_SHIFT 12
99#define CFG_DELTA_LUMA_THR_MASK 0x0f
100#define CFG_DELTA_LUMA_THR_SHIFT 24
101#define CFG_DELTA_EV_THR_MASK 0x0f
102#define CFG_DELTA_EV_THR_SHIFT 28
103
104#define CFG_SC18 0x48
105#define CFG_HS_FACTOR_MASK 0x03ff
106#define CFG_HS_FACTOR_SHIFT 0
107#define CFG_CONF_DEFAULT_MASK 0x01ff
108#define CFG_CONF_DEFAULT_SHIFT 16
109
110#define CFG_SC19 0x4c
111#define CFG_HPF_COEFF0_MASK 0xff
112#define CFG_HPF_COEFF0_SHIFT 0
113#define CFG_HPF_COEFF1_MASK 0xff
114#define CFG_HPF_COEFF1_SHIFT 8
115#define CFG_HPF_COEFF2_MASK 0xff
116#define CFG_HPF_COEFF2_SHIFT 16
117#define CFG_HPF_COEFF3_MASK 0xff
118#define CFG_HPF_COEFF3_SHIFT 23
119
120#define CFG_SC20 0x50
121#define CFG_HPF_COEFF4_MASK 0xff
122#define CFG_HPF_COEFF4_SHIFT 0
123#define CFG_HPF_COEFF5_MASK 0xff
124#define CFG_HPF_COEFF5_SHIFT 8
125#define CFG_HPF_NORM_SHIFT_MASK 0x07
126#define CFG_HPF_NORM_SHIFT_SHIFT 16
127#define CFG_NL_LIMIT_MASK 0x1ff
128#define CFG_NL_LIMIT_SHIFT 20
129
130#define CFG_SC21 0x54
131#define CFG_NL_LO_THR_MASK 0x01ff
132#define CFG_NL_LO_THR_SHIFT 0
133#define CFG_NL_LO_SLOPE_MASK 0xff
134#define CFG_NL_LO_SLOPE_SHIFT 16
135
136#define CFG_SC22 0x58
137#define CFG_NL_HI_THR_MASK 0x01ff
138#define CFG_NL_HI_THR_SHIFT 0
139#define CFG_NL_HI_SLOPE_SH_MASK 0x07
140#define CFG_NL_HI_SLOPE_SH_SHIFT 16
141
142#define CFG_SC23 0x5c
143#define CFG_GRADIENT_THR_MASK 0x07ff
144#define CFG_GRADIENT_THR_SHIFT 0
145#define CFG_GRADIENT_THR_RANGE_MASK 0x0f
146#define CFG_GRADIENT_THR_RANGE_SHIFT 12
147#define CFG_MIN_GY_THR_MASK 0xff
148#define CFG_MIN_GY_THR_SHIFT 16
149#define CFG_MIN_GY_THR_RANGE_MASK 0x0f
150#define CFG_MIN_GY_THR_RANGE_SHIFT 28
151
152#define CFG_SC24 0x60
153#define CFG_ORG_H_MASK 0x07ff
154#define CFG_ORG_H_SHIFT 0
155#define CFG_ORG_W_MASK 0x07ff
156#define CFG_ORG_W_SHIFT 16
157
158#define CFG_SC25 0x64
159#define CFG_OFF_H_MASK 0x07ff
160#define CFG_OFF_H_SHIFT 0
161#define CFG_OFF_W_MASK 0x07ff
162#define CFG_OFF_W_SHIFT 16
163
164/* number of phases supported by the polyphase scalers */
165#define SC_NUM_PHASES 32
166
167/* number of taps used by horizontal polyphase scaler */
168#define SC_H_NUM_TAPS 7
169
170/* number of taps used by vertical polyphase scaler */
171#define SC_V_NUM_TAPS 5
172
173/* number of taps expected by the scaler in it's coefficient memory */
174#define SC_NUM_TAPS_MEM_ALIGN 8
175
176/*
177 * coefficient memory size in bytes:
178 * num phases x num sets(luma and chroma) x num taps(aligned) x coeff size
179 */
180#define SC_COEF_SRAM_SIZE (SC_NUM_PHASES * 2 * SC_NUM_TAPS_MEM_ALIGN * 2)
181
182struct sc_data {
183 void __iomem *base;
184 struct resource *res;
185
186 dma_addr_t loaded_coeff_h; /* loaded h coeffs in SC */
187 dma_addr_t loaded_coeff_v; /* loaded v coeffs in SC */
188
189 bool load_coeff_h; /* have new h SC coeffs */
190 bool load_coeff_v; /* have new v SC coeffs */
191
192 unsigned int hs_index; /* h SC coeffs selector */
193 unsigned int vs_index; /* v SC coeffs selector */
194
195 struct platform_device *pdev;
196};
197
198void sc_dump_regs(struct sc_data *sc);
199void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
200 unsigned int dst_w);
201void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
202 unsigned int dst_h);
203void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
204 u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
205 unsigned int dst_w, unsigned int dst_h);
206struct sc_data *sc_create(struct platform_device *pdev);
207
208#endif
diff --git a/drivers/media/platform/ti-vpe/sc_coeff.h b/drivers/media/platform/ti-vpe/sc_coeff.h
new file mode 100644
index 000000000000..5bfa5c03aec6
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/sc_coeff.h
@@ -0,0 +1,1342 @@
1/*
2 * VPE SC coefs
3 *
4 * Copyright (c) 2013 Texas Instruments Inc.
5 *
6 * David Griego, <dagriego@biglakesoftware.com>
7 * Dale Farnsworth, <dale@farnsworth.org>
8 * Archit Taneja, <archit@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 */
14
15#ifndef __TI_SC_COEFF_H
16#define __TI_SC_COEFF_H
17
18/* horizontal scaler coefficients */
19enum {
20 HS_UP_SCALE = 0,
21 HS_LT_9_16_SCALE,
22 HS_LT_10_16_SCALE,
23 HS_LT_11_16_SCALE,
24 HS_LT_12_16_SCALE,
25 HS_LT_13_16_SCALE,
26 HS_LT_14_16_SCALE,
27 HS_LT_15_16_SCALE,
28 HS_LE_16_16_SCALE,
29};
30
31static const u16 scaler_hs_coeffs[13][SC_NUM_PHASES * 2 * SC_H_NUM_TAPS] = {
32 [HS_UP_SCALE] = {
33 /* Luma */
34 0x001F, 0x1F90, 0x00D2, 0x06FE, 0x00D2, 0x1F90, 0x001F,
35 0x001C, 0x1F9E, 0x009F, 0x06FB, 0x0108, 0x1F82, 0x0022,
36 0x0019, 0x1FAC, 0x006F, 0x06F3, 0x0140, 0x1F74, 0x0025,
37 0x0016, 0x1FB9, 0x0041, 0x06E7, 0x017B, 0x1F66, 0x0028,
38 0x0013, 0x1FC6, 0x0017, 0x06D6, 0x01B7, 0x1F58, 0x002B,
39 0x0010, 0x1FD3, 0x1FEF, 0x06C0, 0x01F6, 0x1F4B, 0x002D,
40 0x000E, 0x1FDF, 0x1FCB, 0x06A5, 0x0235, 0x1F3F, 0x002F,
41 0x000B, 0x1FEA, 0x1FAA, 0x0686, 0x0277, 0x1F33, 0x0031,
42 0x0009, 0x1FF5, 0x1F8C, 0x0663, 0x02B8, 0x1F28, 0x0033,
43 0x0007, 0x1FFF, 0x1F72, 0x063A, 0x02FB, 0x1F1F, 0x0034,
44 0x0005, 0x0008, 0x1F5A, 0x060F, 0x033E, 0x1F17, 0x0035,
45 0x0003, 0x0010, 0x1F46, 0x05E0, 0x0382, 0x1F10, 0x0035,
46 0x0002, 0x0017, 0x1F34, 0x05AF, 0x03C5, 0x1F0B, 0x0034,
47 0x0001, 0x001E, 0x1F26, 0x0579, 0x0407, 0x1F08, 0x0033,
48 0x0000, 0x0023, 0x1F1A, 0x0541, 0x0449, 0x1F07, 0x0032,
49 0x1FFF, 0x0028, 0x1F12, 0x0506, 0x048A, 0x1F08, 0x002F,
50 0x002C, 0x1F0C, 0x04C8, 0x04C8, 0x1F0C, 0x002C, 0x0000,
51 0x002F, 0x1F08, 0x048A, 0x0506, 0x1F12, 0x0028, 0x1FFF,
52 0x0032, 0x1F07, 0x0449, 0x0541, 0x1F1A, 0x0023, 0x0000,
53 0x0033, 0x1F08, 0x0407, 0x0579, 0x1F26, 0x001E, 0x0001,
54 0x0034, 0x1F0B, 0x03C5, 0x05AF, 0x1F34, 0x0017, 0x0002,
55 0x0035, 0x1F10, 0x0382, 0x05E0, 0x1F46, 0x0010, 0x0003,
56 0x0035, 0x1F17, 0x033E, 0x060F, 0x1F5A, 0x0008, 0x0005,
57 0x0034, 0x1F1F, 0x02FB, 0x063A, 0x1F72, 0x1FFF, 0x0007,
58 0x0033, 0x1F28, 0x02B8, 0x0663, 0x1F8C, 0x1FF5, 0x0009,
59 0x0031, 0x1F33, 0x0277, 0x0686, 0x1FAA, 0x1FEA, 0x000B,
60 0x002F, 0x1F3F, 0x0235, 0x06A5, 0x1FCB, 0x1FDF, 0x000E,
61 0x002D, 0x1F4B, 0x01F6, 0x06C0, 0x1FEF, 0x1FD3, 0x0010,
62 0x002B, 0x1F58, 0x01B7, 0x06D6, 0x0017, 0x1FC6, 0x0013,
63 0x0028, 0x1F66, 0x017B, 0x06E7, 0x0041, 0x1FB9, 0x0016,
64 0x0025, 0x1F74, 0x0140, 0x06F3, 0x006F, 0x1FAC, 0x0019,
65 0x0022, 0x1F82, 0x0108, 0x06FB, 0x009F, 0x1F9E, 0x001C,
66 /* Chroma */
67 0x001F, 0x1F90, 0x00D2, 0x06FE, 0x00D2, 0x1F90, 0x001F,
68 0x001C, 0x1F9E, 0x009F, 0x06FB, 0x0108, 0x1F82, 0x0022,
69 0x0019, 0x1FAC, 0x006F, 0x06F3, 0x0140, 0x1F74, 0x0025,
70 0x0016, 0x1FB9, 0x0041, 0x06E7, 0x017B, 0x1F66, 0x0028,
71 0x0013, 0x1FC6, 0x0017, 0x06D6, 0x01B7, 0x1F58, 0x002B,
72 0x0010, 0x1FD3, 0x1FEF, 0x06C0, 0x01F6, 0x1F4B, 0x002D,
73 0x000E, 0x1FDF, 0x1FCB, 0x06A5, 0x0235, 0x1F3F, 0x002F,
74 0x000B, 0x1FEA, 0x1FAA, 0x0686, 0x0277, 0x1F33, 0x0031,
75 0x0009, 0x1FF5, 0x1F8C, 0x0663, 0x02B8, 0x1F28, 0x0033,
76 0x0007, 0x1FFF, 0x1F72, 0x063A, 0x02FB, 0x1F1F, 0x0034,
77 0x0005, 0x0008, 0x1F5A, 0x060F, 0x033E, 0x1F17, 0x0035,
78 0x0003, 0x0010, 0x1F46, 0x05E0, 0x0382, 0x1F10, 0x0035,
79 0x0002, 0x0017, 0x1F34, 0x05AF, 0x03C5, 0x1F0B, 0x0034,
80 0x0001, 0x001E, 0x1F26, 0x0579, 0x0407, 0x1F08, 0x0033,
81 0x0000, 0x0023, 0x1F1A, 0x0541, 0x0449, 0x1F07, 0x0032,
82 0x1FFF, 0x0028, 0x1F12, 0x0506, 0x048A, 0x1F08, 0x002F,
83 0x002C, 0x1F0C, 0x04C8, 0x04C8, 0x1F0C, 0x002C, 0x0000,
84 0x002F, 0x1F08, 0x048A, 0x0506, 0x1F12, 0x0028, 0x1FFF,
85 0x0032, 0x1F07, 0x0449, 0x0541, 0x1F1A, 0x0023, 0x0000,
86 0x0033, 0x1F08, 0x0407, 0x0579, 0x1F26, 0x001E, 0x0001,
87 0x0034, 0x1F0B, 0x03C5, 0x05AF, 0x1F34, 0x0017, 0x0002,
88 0x0035, 0x1F10, 0x0382, 0x05E0, 0x1F46, 0x0010, 0x0003,
89 0x0035, 0x1F17, 0x033E, 0x060F, 0x1F5A, 0x0008, 0x0005,
90 0x0034, 0x1F1F, 0x02FB, 0x063A, 0x1F72, 0x1FFF, 0x0007,
91 0x0033, 0x1F28, 0x02B8, 0x0663, 0x1F8C, 0x1FF5, 0x0009,
92 0x0031, 0x1F33, 0x0277, 0x0686, 0x1FAA, 0x1FEA, 0x000B,
93 0x002F, 0x1F3F, 0x0235, 0x06A5, 0x1FCB, 0x1FDF, 0x000E,
94 0x002D, 0x1F4B, 0x01F6, 0x06C0, 0x1FEF, 0x1FD3, 0x0010,
95 0x002B, 0x1F58, 0x01B7, 0x06D6, 0x0017, 0x1FC6, 0x0013,
96 0x0028, 0x1F66, 0x017B, 0x06E7, 0x0041, 0x1FB9, 0x0016,
97 0x0025, 0x1F74, 0x0140, 0x06F3, 0x006F, 0x1FAC, 0x0019,
98 0x0022, 0x1F82, 0x0108, 0x06FB, 0x009F, 0x1F9E, 0x001C,
99 },
100 [HS_LT_9_16_SCALE] = {
101 /* Luma */
102 0x1FA3, 0x005E, 0x024A, 0x036A, 0x024A, 0x005E, 0x1FA3,
103 0x1FA3, 0x0052, 0x023A, 0x036A, 0x0259, 0x006A, 0x1FA4,
104 0x1FA3, 0x0046, 0x022A, 0x036A, 0x0269, 0x0076, 0x1FA4,
105 0x1FA3, 0x003B, 0x021A, 0x0368, 0x0278, 0x0083, 0x1FA5,
106 0x1FA4, 0x0031, 0x020A, 0x0365, 0x0286, 0x0090, 0x1FA6,
107 0x1FA5, 0x0026, 0x01F9, 0x0362, 0x0294, 0x009E, 0x1FA8,
108 0x1FA6, 0x001C, 0x01E8, 0x035E, 0x02A3, 0x00AB, 0x1FAA,
109 0x1FA7, 0x0013, 0x01D7, 0x035A, 0x02B0, 0x00B9, 0x1FAC,
110 0x1FA9, 0x000A, 0x01C6, 0x0354, 0x02BD, 0x00C7, 0x1FAF,
111 0x1FAA, 0x0001, 0x01B6, 0x034E, 0x02C9, 0x00D6, 0x1FB2,
112 0x1FAC, 0x1FF9, 0x01A5, 0x0347, 0x02D5, 0x00E5, 0x1FB5,
113 0x1FAE, 0x1FF1, 0x0194, 0x0340, 0x02E1, 0x00F3, 0x1FB9,
114 0x1FB0, 0x1FEA, 0x0183, 0x0338, 0x02EC, 0x0102, 0x1FBD,
115 0x1FB2, 0x1FE3, 0x0172, 0x0330, 0x02F6, 0x0112, 0x1FC1,
116 0x1FB4, 0x1FDC, 0x0161, 0x0327, 0x0301, 0x0121, 0x1FC6,
117 0x1FB7, 0x1FD6, 0x0151, 0x031D, 0x030A, 0x0130, 0x1FCB,
118 0x1FD2, 0x0136, 0x02F8, 0x02F8, 0x0136, 0x1FD2, 0x0000,
119 0x1FCB, 0x0130, 0x030A, 0x031D, 0x0151, 0x1FD6, 0x1FB7,
120 0x1FC6, 0x0121, 0x0301, 0x0327, 0x0161, 0x1FDC, 0x1FB4,
121 0x1FC1, 0x0112, 0x02F6, 0x0330, 0x0172, 0x1FE3, 0x1FB2,
122 0x1FBD, 0x0102, 0x02EC, 0x0338, 0x0183, 0x1FEA, 0x1FB0,
123 0x1FB9, 0x00F3, 0x02E1, 0x0340, 0x0194, 0x1FF1, 0x1FAE,
124 0x1FB5, 0x00E5, 0x02D5, 0x0347, 0x01A5, 0x1FF9, 0x1FAC,
125 0x1FB2, 0x00D6, 0x02C9, 0x034E, 0x01B6, 0x0001, 0x1FAA,
126 0x1FAF, 0x00C7, 0x02BD, 0x0354, 0x01C6, 0x000A, 0x1FA9,
127 0x1FAC, 0x00B9, 0x02B0, 0x035A, 0x01D7, 0x0013, 0x1FA7,
128 0x1FAA, 0x00AB, 0x02A3, 0x035E, 0x01E8, 0x001C, 0x1FA6,
129 0x1FA8, 0x009E, 0x0294, 0x0362, 0x01F9, 0x0026, 0x1FA5,
130 0x1FA6, 0x0090, 0x0286, 0x0365, 0x020A, 0x0031, 0x1FA4,
131 0x1FA5, 0x0083, 0x0278, 0x0368, 0x021A, 0x003B, 0x1FA3,
132 0x1FA4, 0x0076, 0x0269, 0x036A, 0x022A, 0x0046, 0x1FA3,
133 0x1FA4, 0x006A, 0x0259, 0x036A, 0x023A, 0x0052, 0x1FA3,
134 /* Chroma */
135 0x1FA3, 0x005E, 0x024A, 0x036A, 0x024A, 0x005E, 0x1FA3,
136 0x1FA3, 0x0052, 0x023A, 0x036A, 0x0259, 0x006A, 0x1FA4,
137 0x1FA3, 0x0046, 0x022A, 0x036A, 0x0269, 0x0076, 0x1FA4,
138 0x1FA3, 0x003B, 0x021A, 0x0368, 0x0278, 0x0083, 0x1FA5,
139 0x1FA4, 0x0031, 0x020A, 0x0365, 0x0286, 0x0090, 0x1FA6,
140 0x1FA5, 0x0026, 0x01F9, 0x0362, 0x0294, 0x009E, 0x1FA8,
141 0x1FA6, 0x001C, 0x01E8, 0x035E, 0x02A3, 0x00AB, 0x1FAA,
142 0x1FA7, 0x0013, 0x01D7, 0x035A, 0x02B0, 0x00B9, 0x1FAC,
143 0x1FA9, 0x000A, 0x01C6, 0x0354, 0x02BD, 0x00C7, 0x1FAF,
144 0x1FAA, 0x0001, 0x01B6, 0x034E, 0x02C9, 0x00D6, 0x1FB2,
145 0x1FAC, 0x1FF9, 0x01A5, 0x0347, 0x02D5, 0x00E5, 0x1FB5,
146 0x1FAE, 0x1FF1, 0x0194, 0x0340, 0x02E1, 0x00F3, 0x1FB9,
147 0x1FB0, 0x1FEA, 0x0183, 0x0338, 0x02EC, 0x0102, 0x1FBD,
148 0x1FB2, 0x1FE3, 0x0172, 0x0330, 0x02F6, 0x0112, 0x1FC1,
149 0x1FB4, 0x1FDC, 0x0161, 0x0327, 0x0301, 0x0121, 0x1FC6,
150 0x1FB7, 0x1FD6, 0x0151, 0x031D, 0x030A, 0x0130, 0x1FCB,
151 0x1FD2, 0x0136, 0x02F8, 0x02F8, 0x0136, 0x1FD2, 0x0000,
152 0x1FCB, 0x0130, 0x030A, 0x031D, 0x0151, 0x1FD6, 0x1FB7,
153 0x1FC6, 0x0121, 0x0301, 0x0327, 0x0161, 0x1FDC, 0x1FB4,
154 0x1FC1, 0x0112, 0x02F6, 0x0330, 0x0172, 0x1FE3, 0x1FB2,
155 0x1FBD, 0x0102, 0x02EC, 0x0338, 0x0183, 0x1FEA, 0x1FB0,
156 0x1FB9, 0x00F3, 0x02E1, 0x0340, 0x0194, 0x1FF1, 0x1FAE,
157 0x1FB5, 0x00E5, 0x02D5, 0x0347, 0x01A5, 0x1FF9, 0x1FAC,
158 0x1FB2, 0x00D6, 0x02C9, 0x034E, 0x01B6, 0x0001, 0x1FAA,
159 0x1FAF, 0x00C7, 0x02BD, 0x0354, 0x01C6, 0x000A, 0x1FA9,
160 0x1FAC, 0x00B9, 0x02B0, 0x035A, 0x01D7, 0x0013, 0x1FA7,
161 0x1FAA, 0x00AB, 0x02A3, 0x035E, 0x01E8, 0x001C, 0x1FA6,
162 0x1FA8, 0x009E, 0x0294, 0x0362, 0x01F9, 0x0026, 0x1FA5,
163 0x1FA6, 0x0090, 0x0286, 0x0365, 0x020A, 0x0031, 0x1FA4,
164 0x1FA5, 0x0083, 0x0278, 0x0368, 0x021A, 0x003B, 0x1FA3,
165 0x1FA4, 0x0076, 0x0269, 0x036A, 0x022A, 0x0046, 0x1FA3,
166 0x1FA4, 0x006A, 0x0259, 0x036A, 0x023A, 0x0052, 0x1FA3,
167 },
168 [HS_LT_10_16_SCALE] = {
169 /* Luma */
170 0x1F8D, 0x000C, 0x026A, 0x03FA, 0x026A, 0x000C, 0x1F8D,
171 0x1F8F, 0x0000, 0x0255, 0x03FA, 0x027F, 0x0019, 0x1F8A,
172 0x1F92, 0x1FF5, 0x023F, 0x03F8, 0x0293, 0x0027, 0x1F88,
173 0x1F95, 0x1FEA, 0x022A, 0x03F6, 0x02A7, 0x0034, 0x1F86,
174 0x1F99, 0x1FDF, 0x0213, 0x03F2, 0x02BB, 0x0043, 0x1F85,
175 0x1F9C, 0x1FD5, 0x01FE, 0x03ED, 0x02CF, 0x0052, 0x1F83,
176 0x1FA0, 0x1FCC, 0x01E8, 0x03E7, 0x02E1, 0x0061, 0x1F83,
177 0x1FA4, 0x1FC3, 0x01D2, 0x03E0, 0x02F4, 0x0071, 0x1F82,
178 0x1FA7, 0x1FBB, 0x01BC, 0x03D9, 0x0306, 0x0081, 0x1F82,
179 0x1FAB, 0x1FB4, 0x01A6, 0x03D0, 0x0317, 0x0092, 0x1F82,
180 0x1FAF, 0x1FAD, 0x0190, 0x03C7, 0x0327, 0x00A3, 0x1F83,
181 0x1FB3, 0x1FA7, 0x017A, 0x03BC, 0x0337, 0x00B5, 0x1F84,
182 0x1FB8, 0x1FA1, 0x0165, 0x03B0, 0x0346, 0x00C7, 0x1F85,
183 0x1FBC, 0x1F9C, 0x0150, 0x03A4, 0x0354, 0x00D9, 0x1F87,
184 0x1FC0, 0x1F98, 0x013A, 0x0397, 0x0361, 0x00EC, 0x1F8A,
185 0x1FC4, 0x1F93, 0x0126, 0x0389, 0x036F, 0x00FE, 0x1F8D,
186 0x1F93, 0x010A, 0x0363, 0x0363, 0x010A, 0x1F93, 0x0000,
187 0x1F8D, 0x00FE, 0x036F, 0x0389, 0x0126, 0x1F93, 0x1FC4,
188 0x1F8A, 0x00EC, 0x0361, 0x0397, 0x013A, 0x1F98, 0x1FC0,
189 0x1F87, 0x00D9, 0x0354, 0x03A4, 0x0150, 0x1F9C, 0x1FBC,
190 0x1F85, 0x00C7, 0x0346, 0x03B0, 0x0165, 0x1FA1, 0x1FB8,
191 0x1F84, 0x00B5, 0x0337, 0x03BC, 0x017A, 0x1FA7, 0x1FB3,
192 0x1F83, 0x00A3, 0x0327, 0x03C7, 0x0190, 0x1FAD, 0x1FAF,
193 0x1F82, 0x0092, 0x0317, 0x03D0, 0x01A6, 0x1FB4, 0x1FAB,
194 0x1F82, 0x0081, 0x0306, 0x03D9, 0x01BC, 0x1FBB, 0x1FA7,
195 0x1F82, 0x0071, 0x02F4, 0x03E0, 0x01D2, 0x1FC3, 0x1FA4,
196 0x1F83, 0x0061, 0x02E1, 0x03E7, 0x01E8, 0x1FCC, 0x1FA0,
197 0x1F83, 0x0052, 0x02CF, 0x03ED, 0x01FE, 0x1FD5, 0x1F9C,
198 0x1F85, 0x0043, 0x02BB, 0x03F2, 0x0213, 0x1FDF, 0x1F99,
199 0x1F86, 0x0034, 0x02A7, 0x03F6, 0x022A, 0x1FEA, 0x1F95,
200 0x1F88, 0x0027, 0x0293, 0x03F8, 0x023F, 0x1FF5, 0x1F92,
201 0x1F8A, 0x0019, 0x027F, 0x03FA, 0x0255, 0x0000, 0x1F8F,
202 /* Chroma */
203 0x1F8D, 0x000C, 0x026A, 0x03FA, 0x026A, 0x000C, 0x1F8D,
204 0x1F8F, 0x0000, 0x0255, 0x03FA, 0x027F, 0x0019, 0x1F8A,
205 0x1F92, 0x1FF5, 0x023F, 0x03F8, 0x0293, 0x0027, 0x1F88,
206 0x1F95, 0x1FEA, 0x022A, 0x03F6, 0x02A7, 0x0034, 0x1F86,
207 0x1F99, 0x1FDF, 0x0213, 0x03F2, 0x02BB, 0x0043, 0x1F85,
208 0x1F9C, 0x1FD5, 0x01FE, 0x03ED, 0x02CF, 0x0052, 0x1F83,
209 0x1FA0, 0x1FCC, 0x01E8, 0x03E7, 0x02E1, 0x0061, 0x1F83,
210 0x1FA4, 0x1FC3, 0x01D2, 0x03E0, 0x02F4, 0x0071, 0x1F82,
211 0x1FA7, 0x1FBB, 0x01BC, 0x03D9, 0x0306, 0x0081, 0x1F82,
212 0x1FAB, 0x1FB4, 0x01A6, 0x03D0, 0x0317, 0x0092, 0x1F82,
213 0x1FAF, 0x1FAD, 0x0190, 0x03C7, 0x0327, 0x00A3, 0x1F83,
214 0x1FB3, 0x1FA7, 0x017A, 0x03BC, 0x0337, 0x00B5, 0x1F84,
215 0x1FB8, 0x1FA1, 0x0165, 0x03B0, 0x0346, 0x00C7, 0x1F85,
216 0x1FBC, 0x1F9C, 0x0150, 0x03A4, 0x0354, 0x00D9, 0x1F87,
217 0x1FC0, 0x1F98, 0x013A, 0x0397, 0x0361, 0x00EC, 0x1F8A,
218 0x1FC4, 0x1F93, 0x0126, 0x0389, 0x036F, 0x00FE, 0x1F8D,
219 0x1F93, 0x010A, 0x0363, 0x0363, 0x010A, 0x1F93, 0x0000,
220 0x1F8D, 0x00FE, 0x036F, 0x0389, 0x0126, 0x1F93, 0x1FC4,
221 0x1F8A, 0x00EC, 0x0361, 0x0397, 0x013A, 0x1F98, 0x1FC0,
222 0x1F87, 0x00D9, 0x0354, 0x03A4, 0x0150, 0x1F9C, 0x1FBC,
223 0x1F85, 0x00C7, 0x0346, 0x03B0, 0x0165, 0x1FA1, 0x1FB8,
224 0x1F84, 0x00B5, 0x0337, 0x03BC, 0x017A, 0x1FA7, 0x1FB3,
225 0x1F83, 0x00A3, 0x0327, 0x03C7, 0x0190, 0x1FAD, 0x1FAF,
226 0x1F82, 0x0092, 0x0317, 0x03D0, 0x01A6, 0x1FB4, 0x1FAB,
227 0x1F82, 0x0081, 0x0306, 0x03D9, 0x01BC, 0x1FBB, 0x1FA7,
228 0x1F82, 0x0071, 0x02F4, 0x03E0, 0x01D2, 0x1FC3, 0x1FA4,
229 0x1F83, 0x0061, 0x02E1, 0x03E7, 0x01E8, 0x1FCC, 0x1FA0,
230 0x1F83, 0x0052, 0x02CF, 0x03ED, 0x01FE, 0x1FD5, 0x1F9C,
231 0x1F85, 0x0043, 0x02BB, 0x03F2, 0x0213, 0x1FDF, 0x1F99,
232 0x1F86, 0x0034, 0x02A7, 0x03F6, 0x022A, 0x1FEA, 0x1F95,
233 0x1F88, 0x0027, 0x0293, 0x03F8, 0x023F, 0x1FF5, 0x1F92,
234 0x1F8A, 0x0019, 0x027F, 0x03FA, 0x0255, 0x0000, 0x1F8F,
235 },
236 [HS_LT_11_16_SCALE] = {
237 /* Luma */
238 0x1F95, 0x1FB5, 0x0272, 0x0488, 0x0272, 0x1FB5, 0x1F95,
239 0x1F9B, 0x1FAA, 0x0257, 0x0486, 0x028D, 0x1FC1, 0x1F90,
240 0x1FA0, 0x1FA0, 0x023C, 0x0485, 0x02A8, 0x1FCD, 0x1F8A,
241 0x1FA6, 0x1F96, 0x0221, 0x0481, 0x02C2, 0x1FDB, 0x1F85,
242 0x1FAC, 0x1F8E, 0x0205, 0x047C, 0x02DC, 0x1FE9, 0x1F80,
243 0x1FB1, 0x1F86, 0x01E9, 0x0476, 0x02F6, 0x1FF8, 0x1F7C,
244 0x1FB7, 0x1F7F, 0x01CE, 0x046E, 0x030F, 0x0008, 0x1F77,
245 0x1FBD, 0x1F79, 0x01B3, 0x0465, 0x0326, 0x0019, 0x1F73,
246 0x1FC3, 0x1F73, 0x0197, 0x045B, 0x033E, 0x002A, 0x1F70,
247 0x1FC8, 0x1F6F, 0x017D, 0x044E, 0x0355, 0x003C, 0x1F6D,
248 0x1FCE, 0x1F6B, 0x0162, 0x0441, 0x036B, 0x004F, 0x1F6A,
249 0x1FD3, 0x1F68, 0x0148, 0x0433, 0x0380, 0x0063, 0x1F67,
250 0x1FD8, 0x1F65, 0x012E, 0x0424, 0x0395, 0x0077, 0x1F65,
251 0x1FDE, 0x1F63, 0x0115, 0x0413, 0x03A8, 0x008B, 0x1F64,
252 0x1FE3, 0x1F62, 0x00FC, 0x0403, 0x03BA, 0x00A0, 0x1F62,
253 0x1FE7, 0x1F62, 0x00E4, 0x03EF, 0x03CC, 0x00B6, 0x1F62,
254 0x1F63, 0x00CA, 0x03D3, 0x03D3, 0x00CA, 0x1F63, 0x0000,
255 0x1F62, 0x00B6, 0x03CC, 0x03EF, 0x00E4, 0x1F62, 0x1FE7,
256 0x1F62, 0x00A0, 0x03BA, 0x0403, 0x00FC, 0x1F62, 0x1FE3,
257 0x1F64, 0x008B, 0x03A8, 0x0413, 0x0115, 0x1F63, 0x1FDE,
258 0x1F65, 0x0077, 0x0395, 0x0424, 0x012E, 0x1F65, 0x1FD8,
259 0x1F67, 0x0063, 0x0380, 0x0433, 0x0148, 0x1F68, 0x1FD3,
260 0x1F6A, 0x004F, 0x036B, 0x0441, 0x0162, 0x1F6B, 0x1FCE,
261 0x1F6D, 0x003C, 0x0355, 0x044E, 0x017D, 0x1F6F, 0x1FC8,
262 0x1F70, 0x002A, 0x033E, 0x045B, 0x0197, 0x1F73, 0x1FC3,
263 0x1F73, 0x0019, 0x0326, 0x0465, 0x01B3, 0x1F79, 0x1FBD,
264 0x1F77, 0x0008, 0x030F, 0x046E, 0x01CE, 0x1F7F, 0x1FB7,
265 0x1F7C, 0x1FF8, 0x02F6, 0x0476, 0x01E9, 0x1F86, 0x1FB1,
266 0x1F80, 0x1FE9, 0x02DC, 0x047C, 0x0205, 0x1F8E, 0x1FAC,
267 0x1F85, 0x1FDB, 0x02C2, 0x0481, 0x0221, 0x1F96, 0x1FA6,
268 0x1F8A, 0x1FCD, 0x02A8, 0x0485, 0x023C, 0x1FA0, 0x1FA0,
269 0x1F90, 0x1FC1, 0x028D, 0x0486, 0x0257, 0x1FAA, 0x1F9B,
270 /* Chroma */
271 0x1F95, 0x1FB5, 0x0272, 0x0488, 0x0272, 0x1FB5, 0x1F95,
272 0x1F9B, 0x1FAA, 0x0257, 0x0486, 0x028D, 0x1FC1, 0x1F90,
273 0x1FA0, 0x1FA0, 0x023C, 0x0485, 0x02A8, 0x1FCD, 0x1F8A,
274 0x1FA6, 0x1F96, 0x0221, 0x0481, 0x02C2, 0x1FDB, 0x1F85,
275 0x1FAC, 0x1F8E, 0x0205, 0x047C, 0x02DC, 0x1FE9, 0x1F80,
276 0x1FB1, 0x1F86, 0x01E9, 0x0476, 0x02F6, 0x1FF8, 0x1F7C,
277 0x1FB7, 0x1F7F, 0x01CE, 0x046E, 0x030F, 0x0008, 0x1F77,
278 0x1FBD, 0x1F79, 0x01B3, 0x0465, 0x0326, 0x0019, 0x1F73,
279 0x1FC3, 0x1F73, 0x0197, 0x045B, 0x033E, 0x002A, 0x1F70,
280 0x1FC8, 0x1F6F, 0x017D, 0x044E, 0x0355, 0x003C, 0x1F6D,
281 0x1FCE, 0x1F6B, 0x0162, 0x0441, 0x036B, 0x004F, 0x1F6A,
282 0x1FD3, 0x1F68, 0x0148, 0x0433, 0x0380, 0x0063, 0x1F67,
283 0x1FD8, 0x1F65, 0x012E, 0x0424, 0x0395, 0x0077, 0x1F65,
284 0x1FDE, 0x1F63, 0x0115, 0x0413, 0x03A8, 0x008B, 0x1F64,
285 0x1FE3, 0x1F62, 0x00FC, 0x0403, 0x03BA, 0x00A0, 0x1F62,
286 0x1FE7, 0x1F62, 0x00E4, 0x03EF, 0x03CC, 0x00B6, 0x1F62,
287 0x1F63, 0x00CA, 0x03D3, 0x03D3, 0x00CA, 0x1F63, 0x0000,
288 0x1F62, 0x00B6, 0x03CC, 0x03EF, 0x00E4, 0x1F62, 0x1FE7,
289 0x1F62, 0x00A0, 0x03BA, 0x0403, 0x00FC, 0x1F62, 0x1FE3,
290 0x1F64, 0x008B, 0x03A8, 0x0413, 0x0115, 0x1F63, 0x1FDE,
291 0x1F65, 0x0077, 0x0395, 0x0424, 0x012E, 0x1F65, 0x1FD8,
292 0x1F67, 0x0063, 0x0380, 0x0433, 0x0148, 0x1F68, 0x1FD3,
293 0x1F6A, 0x004F, 0x036B, 0x0441, 0x0162, 0x1F6B, 0x1FCE,
294 0x1F6D, 0x003C, 0x0355, 0x044E, 0x017D, 0x1F6F, 0x1FC8,
295 0x1F70, 0x002A, 0x033E, 0x045B, 0x0197, 0x1F73, 0x1FC3,
296 0x1F73, 0x0019, 0x0326, 0x0465, 0x01B3, 0x1F79, 0x1FBD,
297 0x1F77, 0x0008, 0x030F, 0x046E, 0x01CE, 0x1F7F, 0x1FB7,
298 0x1F7C, 0x1FF8, 0x02F6, 0x0476, 0x01E9, 0x1F86, 0x1FB1,
299 0x1F80, 0x1FE9, 0x02DC, 0x047C, 0x0205, 0x1F8E, 0x1FAC,
300 0x1F85, 0x1FDB, 0x02C2, 0x0481, 0x0221, 0x1F96, 0x1FA6,
301 0x1F8A, 0x1FCD, 0x02A8, 0x0485, 0x023C, 0x1FA0, 0x1FA0,
302 0x1F90, 0x1FC1, 0x028D, 0x0486, 0x0257, 0x1FAA, 0x1F9B,
303 },
304 [HS_LT_12_16_SCALE] = {
305 /* Luma */
306 0x1FBB, 0x1F65, 0x025E, 0x0504, 0x025E, 0x1F65, 0x1FBB,
307 0x1FC3, 0x1F5D, 0x023C, 0x0503, 0x027F, 0x1F6E, 0x1FB4,
308 0x1FCA, 0x1F56, 0x021B, 0x0501, 0x02A0, 0x1F78, 0x1FAC,
309 0x1FD1, 0x1F50, 0x01FA, 0x04FD, 0x02C0, 0x1F83, 0x1FA5,
310 0x1FD8, 0x1F4B, 0x01D9, 0x04F6, 0x02E1, 0x1F90, 0x1F9D,
311 0x1FDF, 0x1F47, 0x01B8, 0x04EF, 0x0301, 0x1F9D, 0x1F95,
312 0x1FE6, 0x1F43, 0x0198, 0x04E5, 0x0321, 0x1FAB, 0x1F8E,
313 0x1FEC, 0x1F41, 0x0178, 0x04DA, 0x0340, 0x1FBB, 0x1F86,
314 0x1FF2, 0x1F40, 0x0159, 0x04CC, 0x035E, 0x1FCC, 0x1F7F,
315 0x1FF8, 0x1F40, 0x013A, 0x04BE, 0x037B, 0x1FDD, 0x1F78,
316 0x1FFE, 0x1F40, 0x011B, 0x04AD, 0x0398, 0x1FF0, 0x1F72,
317 0x0003, 0x1F41, 0x00FD, 0x049C, 0x03B4, 0x0004, 0x1F6B,
318 0x0008, 0x1F43, 0x00E0, 0x0489, 0x03CE, 0x0019, 0x1F65,
319 0x000D, 0x1F46, 0x00C4, 0x0474, 0x03E8, 0x002E, 0x1F5F,
320 0x0011, 0x1F49, 0x00A9, 0x045E, 0x0400, 0x0045, 0x1F5A,
321 0x0015, 0x1F4D, 0x008E, 0x0447, 0x0418, 0x005C, 0x1F55,
322 0x1F4F, 0x0076, 0x043B, 0x043B, 0x0076, 0x1F4F, 0x0000,
323 0x1F55, 0x005C, 0x0418, 0x0447, 0x008E, 0x1F4D, 0x0015,
324 0x1F5A, 0x0045, 0x0400, 0x045E, 0x00A9, 0x1F49, 0x0011,
325 0x1F5F, 0x002E, 0x03E8, 0x0474, 0x00C4, 0x1F46, 0x000D,
326 0x1F65, 0x0019, 0x03CE, 0x0489, 0x00E0, 0x1F43, 0x0008,
327 0x1F6B, 0x0004, 0x03B4, 0x049C, 0x00FD, 0x1F41, 0x0003,
328 0x1F72, 0x1FF0, 0x0398, 0x04AD, 0x011B, 0x1F40, 0x1FFE,
329 0x1F78, 0x1FDD, 0x037B, 0x04BE, 0x013A, 0x1F40, 0x1FF8,
330 0x1F7F, 0x1FCC, 0x035E, 0x04CC, 0x0159, 0x1F40, 0x1FF2,
331 0x1F86, 0x1FBB, 0x0340, 0x04DA, 0x0178, 0x1F41, 0x1FEC,
332 0x1F8E, 0x1FAB, 0x0321, 0x04E5, 0x0198, 0x1F43, 0x1FE6,
333 0x1F95, 0x1F9D, 0x0301, 0x04EF, 0x01B8, 0x1F47, 0x1FDF,
334 0x1F9D, 0x1F90, 0x02E1, 0x04F6, 0x01D9, 0x1F4B, 0x1FD8,
335 0x1FA5, 0x1F83, 0x02C0, 0x04FD, 0x01FA, 0x1F50, 0x1FD1,
336 0x1FAC, 0x1F78, 0x02A0, 0x0501, 0x021B, 0x1F56, 0x1FCA,
337 0x1FB4, 0x1F6E, 0x027F, 0x0503, 0x023C, 0x1F5D, 0x1FC3,
338 /* Chroma */
339 0x1FBB, 0x1F65, 0x025E, 0x0504, 0x025E, 0x1F65, 0x1FBB,
340 0x1FC3, 0x1F5D, 0x023C, 0x0503, 0x027F, 0x1F6E, 0x1FB4,
341 0x1FCA, 0x1F56, 0x021B, 0x0501, 0x02A0, 0x1F78, 0x1FAC,
342 0x1FD1, 0x1F50, 0x01FA, 0x04FD, 0x02C0, 0x1F83, 0x1FA5,
343 0x1FD8, 0x1F4B, 0x01D9, 0x04F6, 0x02E1, 0x1F90, 0x1F9D,
344 0x1FDF, 0x1F47, 0x01B8, 0x04EF, 0x0301, 0x1F9D, 0x1F95,
345 0x1FE6, 0x1F43, 0x0198, 0x04E5, 0x0321, 0x1FAB, 0x1F8E,
346 0x1FEC, 0x1F41, 0x0178, 0x04DA, 0x0340, 0x1FBB, 0x1F86,
347 0x1FF2, 0x1F40, 0x0159, 0x04CC, 0x035E, 0x1FCC, 0x1F7F,
348 0x1FF8, 0x1F40, 0x013A, 0x04BE, 0x037B, 0x1FDD, 0x1F78,
349 0x1FFE, 0x1F40, 0x011B, 0x04AD, 0x0398, 0x1FF0, 0x1F72,
350 0x0003, 0x1F41, 0x00FD, 0x049C, 0x03B4, 0x0004, 0x1F6B,
351 0x0008, 0x1F43, 0x00E0, 0x0489, 0x03CE, 0x0019, 0x1F65,
352 0x000D, 0x1F46, 0x00C4, 0x0474, 0x03E8, 0x002E, 0x1F5F,
353 0x0011, 0x1F49, 0x00A9, 0x045E, 0x0400, 0x0045, 0x1F5A,
354 0x0015, 0x1F4D, 0x008E, 0x0447, 0x0418, 0x005C, 0x1F55,
355 0x1F4F, 0x0076, 0x043B, 0x043B, 0x0076, 0x1F4F, 0x0000,
356 0x1F55, 0x005C, 0x0418, 0x0447, 0x008E, 0x1F4D, 0x0015,
357 0x1F5A, 0x0045, 0x0400, 0x045E, 0x00A9, 0x1F49, 0x0011,
358 0x1F5F, 0x002E, 0x03E8, 0x0474, 0x00C4, 0x1F46, 0x000D,
359 0x1F65, 0x0019, 0x03CE, 0x0489, 0x00E0, 0x1F43, 0x0008,
360 0x1F6B, 0x0004, 0x03B4, 0x049C, 0x00FD, 0x1F41, 0x0003,
361 0x1F72, 0x1FF0, 0x0398, 0x04AD, 0x011B, 0x1F40, 0x1FFE,
362 0x1F78, 0x1FDD, 0x037B, 0x04BE, 0x013A, 0x1F40, 0x1FF8,
363 0x1F7F, 0x1FCC, 0x035E, 0x04CC, 0x0159, 0x1F40, 0x1FF2,
364 0x1F86, 0x1FBB, 0x0340, 0x04DA, 0x0178, 0x1F41, 0x1FEC,
365 0x1F8E, 0x1FAB, 0x0321, 0x04E5, 0x0198, 0x1F43, 0x1FE6,
366 0x1F95, 0x1F9D, 0x0301, 0x04EF, 0x01B8, 0x1F47, 0x1FDF,
367 0x1F9D, 0x1F90, 0x02E1, 0x04F6, 0x01D9, 0x1F4B, 0x1FD8,
368 0x1FA5, 0x1F83, 0x02C0, 0x04FD, 0x01FA, 0x1F50, 0x1FD1,
369 0x1FAC, 0x1F78, 0x02A0, 0x0501, 0x021B, 0x1F56, 0x1FCA,
370 0x1FB4, 0x1F6E, 0x027F, 0x0503, 0x023C, 0x1F5D, 0x1FC3,
371 },
372 [HS_LT_13_16_SCALE] = {
373 /* Luma */
374 0x1FF4, 0x1F29, 0x022D, 0x056C, 0x022D, 0x1F29, 0x1FF4,
375 0x1FFC, 0x1F26, 0x0206, 0x056A, 0x0254, 0x1F2E, 0x1FEC,
376 0x0003, 0x1F24, 0x01E0, 0x0567, 0x027A, 0x1F34, 0x1FE4,
377 0x000A, 0x1F23, 0x01BA, 0x0561, 0x02A2, 0x1F3B, 0x1FDB,
378 0x0011, 0x1F22, 0x0194, 0x055B, 0x02C9, 0x1F43, 0x1FD2,
379 0x0017, 0x1F23, 0x016F, 0x0551, 0x02F0, 0x1F4D, 0x1FC9,
380 0x001D, 0x1F25, 0x014B, 0x0545, 0x0316, 0x1F58, 0x1FC0,
381 0x0022, 0x1F28, 0x0127, 0x0538, 0x033C, 0x1F65, 0x1FB6,
382 0x0027, 0x1F2C, 0x0104, 0x0528, 0x0361, 0x1F73, 0x1FAD,
383 0x002B, 0x1F30, 0x00E2, 0x0518, 0x0386, 0x1F82, 0x1FA3,
384 0x002F, 0x1F36, 0x00C2, 0x0504, 0x03AA, 0x1F92, 0x1F99,
385 0x0032, 0x1F3C, 0x00A2, 0x04EF, 0x03CD, 0x1FA4, 0x1F90,
386 0x0035, 0x1F42, 0x0083, 0x04D9, 0x03EF, 0x1FB8, 0x1F86,
387 0x0038, 0x1F49, 0x0065, 0x04C0, 0x0410, 0x1FCD, 0x1F7D,
388 0x003A, 0x1F51, 0x0048, 0x04A6, 0x0431, 0x1FE3, 0x1F73,
389 0x003C, 0x1F59, 0x002D, 0x048A, 0x0450, 0x1FFA, 0x1F6A,
390 0x1F5D, 0x0014, 0x048F, 0x048F, 0x0014, 0x1F5D, 0x0000,
391 0x1F6A, 0x1FFA, 0x0450, 0x048A, 0x002D, 0x1F59, 0x003C,
392 0x1F73, 0x1FE3, 0x0431, 0x04A6, 0x0048, 0x1F51, 0x003A,
393 0x1F7D, 0x1FCD, 0x0410, 0x04C0, 0x0065, 0x1F49, 0x0038,
394 0x1F86, 0x1FB8, 0x03EF, 0x04D9, 0x0083, 0x1F42, 0x0035,
395 0x1F90, 0x1FA4, 0x03CD, 0x04EF, 0x00A2, 0x1F3C, 0x0032,
396 0x1F99, 0x1F92, 0x03AA, 0x0504, 0x00C2, 0x1F36, 0x002F,
397 0x1FA3, 0x1F82, 0x0386, 0x0518, 0x00E2, 0x1F30, 0x002B,
398 0x1FAD, 0x1F73, 0x0361, 0x0528, 0x0104, 0x1F2C, 0x0027,
399 0x1FB6, 0x1F65, 0x033C, 0x0538, 0x0127, 0x1F28, 0x0022,
400 0x1FC0, 0x1F58, 0x0316, 0x0545, 0x014B, 0x1F25, 0x001D,
401 0x1FC9, 0x1F4D, 0x02F0, 0x0551, 0x016F, 0x1F23, 0x0017,
402 0x1FD2, 0x1F43, 0x02C9, 0x055B, 0x0194, 0x1F22, 0x0011,
403 0x1FDB, 0x1F3B, 0x02A2, 0x0561, 0x01BA, 0x1F23, 0x000A,
404 0x1FE4, 0x1F34, 0x027A, 0x0567, 0x01E0, 0x1F24, 0x0003,
405 0x1FEC, 0x1F2E, 0x0254, 0x056A, 0x0206, 0x1F26, 0x1FFC,
406 /* Chroma */
407 0x1FF4, 0x1F29, 0x022D, 0x056C, 0x022D, 0x1F29, 0x1FF4,
408 0x1FFC, 0x1F26, 0x0206, 0x056A, 0x0254, 0x1F2E, 0x1FEC,
409 0x0003, 0x1F24, 0x01E0, 0x0567, 0x027A, 0x1F34, 0x1FE4,
410 0x000A, 0x1F23, 0x01BA, 0x0561, 0x02A2, 0x1F3B, 0x1FDB,
411 0x0011, 0x1F22, 0x0194, 0x055B, 0x02C9, 0x1F43, 0x1FD2,
412 0x0017, 0x1F23, 0x016F, 0x0551, 0x02F0, 0x1F4D, 0x1FC9,
413 0x001D, 0x1F25, 0x014B, 0x0545, 0x0316, 0x1F58, 0x1FC0,
414 0x0022, 0x1F28, 0x0127, 0x0538, 0x033C, 0x1F65, 0x1FB6,
415 0x0027, 0x1F2C, 0x0104, 0x0528, 0x0361, 0x1F73, 0x1FAD,
416 0x002B, 0x1F30, 0x00E2, 0x0518, 0x0386, 0x1F82, 0x1FA3,
417 0x002F, 0x1F36, 0x00C2, 0x0504, 0x03AA, 0x1F92, 0x1F99,
418 0x0032, 0x1F3C, 0x00A2, 0x04EF, 0x03CD, 0x1FA4, 0x1F90,
419 0x0035, 0x1F42, 0x0083, 0x04D9, 0x03EF, 0x1FB8, 0x1F86,
420 0x0038, 0x1F49, 0x0065, 0x04C0, 0x0410, 0x1FCD, 0x1F7D,
421 0x003A, 0x1F51, 0x0048, 0x04A6, 0x0431, 0x1FE3, 0x1F73,
422 0x003C, 0x1F59, 0x002D, 0x048A, 0x0450, 0x1FFA, 0x1F6A,
423 0x1F5D, 0x0014, 0x048F, 0x048F, 0x0014, 0x1F5D, 0x0000,
424 0x1F6A, 0x1FFA, 0x0450, 0x048A, 0x002D, 0x1F59, 0x003C,
425 0x1F73, 0x1FE3, 0x0431, 0x04A6, 0x0048, 0x1F51, 0x003A,
426 0x1F7D, 0x1FCD, 0x0410, 0x04C0, 0x0065, 0x1F49, 0x0038,
427 0x1F86, 0x1FB8, 0x03EF, 0x04D9, 0x0083, 0x1F42, 0x0035,
428 0x1F90, 0x1FA4, 0x03CD, 0x04EF, 0x00A2, 0x1F3C, 0x0032,
429 0x1F99, 0x1F92, 0x03AA, 0x0504, 0x00C2, 0x1F36, 0x002F,
430 0x1FA3, 0x1F82, 0x0386, 0x0518, 0x00E2, 0x1F30, 0x002B,
431 0x1FAD, 0x1F73, 0x0361, 0x0528, 0x0104, 0x1F2C, 0x0027,
432 0x1FB6, 0x1F65, 0x033C, 0x0538, 0x0127, 0x1F28, 0x0022,
433 0x1FC0, 0x1F58, 0x0316, 0x0545, 0x014B, 0x1F25, 0x001D,
434 0x1FC9, 0x1F4D, 0x02F0, 0x0551, 0x016F, 0x1F23, 0x0017,
435 0x1FD2, 0x1F43, 0x02C9, 0x055B, 0x0194, 0x1F22, 0x0011,
436 0x1FDB, 0x1F3B, 0x02A2, 0x0561, 0x01BA, 0x1F23, 0x000A,
437 0x1FE4, 0x1F34, 0x027A, 0x0567, 0x01E0, 0x1F24, 0x0003,
438 0x1FEC, 0x1F2E, 0x0254, 0x056A, 0x0206, 0x1F26, 0x1FFC,
439 },
440 [HS_LT_14_16_SCALE] = {
441 /* Luma */
442 0x002F, 0x1F0B, 0x01E7, 0x05BE, 0x01E7, 0x1F0B, 0x002F,
443 0x0035, 0x1F0D, 0x01BC, 0x05BD, 0x0213, 0x1F0A, 0x0028,
444 0x003A, 0x1F11, 0x0191, 0x05BA, 0x023F, 0x1F0A, 0x0021,
445 0x003F, 0x1F15, 0x0167, 0x05B3, 0x026C, 0x1F0C, 0x001A,
446 0x0043, 0x1F1B, 0x013E, 0x05AA, 0x0299, 0x1F0F, 0x0012,
447 0x0046, 0x1F21, 0x0116, 0x05A1, 0x02C6, 0x1F13, 0x0009,
448 0x0049, 0x1F28, 0x00EF, 0x0593, 0x02F4, 0x1F19, 0x0000,
449 0x004C, 0x1F30, 0x00C9, 0x0584, 0x0321, 0x1F20, 0x1FF6,
450 0x004E, 0x1F39, 0x00A4, 0x0572, 0x034D, 0x1F2A, 0x1FEC,
451 0x004F, 0x1F43, 0x0080, 0x055E, 0x037A, 0x1F34, 0x1FE2,
452 0x0050, 0x1F4D, 0x005E, 0x0548, 0x03A5, 0x1F41, 0x1FD7,
453 0x0050, 0x1F57, 0x003D, 0x0531, 0x03D1, 0x1F4F, 0x1FCB,
454 0x0050, 0x1F62, 0x001E, 0x0516, 0x03FB, 0x1F5F, 0x1FC0,
455 0x004F, 0x1F6D, 0x0000, 0x04FA, 0x0425, 0x1F71, 0x1FB4,
456 0x004E, 0x1F79, 0x1FE4, 0x04DC, 0x044D, 0x1F84, 0x1FA8,
457 0x004D, 0x1F84, 0x1FCA, 0x04BC, 0x0474, 0x1F99, 0x1F9C,
458 0x1F8C, 0x1FAE, 0x04C6, 0x04C6, 0x1FAE, 0x1F8C, 0x0000,
459 0x1F9C, 0x1F99, 0x0474, 0x04BC, 0x1FCA, 0x1F84, 0x004D,
460 0x1FA8, 0x1F84, 0x044D, 0x04DC, 0x1FE4, 0x1F79, 0x004E,
461 0x1FB4, 0x1F71, 0x0425, 0x04FA, 0x0000, 0x1F6D, 0x004F,
462 0x1FC0, 0x1F5F, 0x03FB, 0x0516, 0x001E, 0x1F62, 0x0050,
463 0x1FCB, 0x1F4F, 0x03D1, 0x0531, 0x003D, 0x1F57, 0x0050,
464 0x1FD7, 0x1F41, 0x03A5, 0x0548, 0x005E, 0x1F4D, 0x0050,
465 0x1FE2, 0x1F34, 0x037A, 0x055E, 0x0080, 0x1F43, 0x004F,
466 0x1FEC, 0x1F2A, 0x034D, 0x0572, 0x00A4, 0x1F39, 0x004E,
467 0x1FF6, 0x1F20, 0x0321, 0x0584, 0x00C9, 0x1F30, 0x004C,
468 0x0000, 0x1F19, 0x02F4, 0x0593, 0x00EF, 0x1F28, 0x0049,
469 0x0009, 0x1F13, 0x02C6, 0x05A1, 0x0116, 0x1F21, 0x0046,
470 0x0012, 0x1F0F, 0x0299, 0x05AA, 0x013E, 0x1F1B, 0x0043,
471 0x001A, 0x1F0C, 0x026C, 0x05B3, 0x0167, 0x1F15, 0x003F,
472 0x0021, 0x1F0A, 0x023F, 0x05BA, 0x0191, 0x1F11, 0x003A,
473 0x0028, 0x1F0A, 0x0213, 0x05BD, 0x01BC, 0x1F0D, 0x0035,
474 /* Chroma */
475 0x002F, 0x1F0B, 0x01E7, 0x05BE, 0x01E7, 0x1F0B, 0x002F,
476 0x0035, 0x1F0D, 0x01BC, 0x05BD, 0x0213, 0x1F0A, 0x0028,
477 0x003A, 0x1F11, 0x0191, 0x05BA, 0x023F, 0x1F0A, 0x0021,
478 0x003F, 0x1F15, 0x0167, 0x05B3, 0x026C, 0x1F0C, 0x001A,
479 0x0043, 0x1F1B, 0x013E, 0x05AA, 0x0299, 0x1F0F, 0x0012,
480 0x0046, 0x1F21, 0x0116, 0x05A1, 0x02C6, 0x1F13, 0x0009,
481 0x0049, 0x1F28, 0x00EF, 0x0593, 0x02F4, 0x1F19, 0x0000,
482 0x004C, 0x1F30, 0x00C9, 0x0584, 0x0321, 0x1F20, 0x1FF6,
483 0x004E, 0x1F39, 0x00A4, 0x0572, 0x034D, 0x1F2A, 0x1FEC,
484 0x004F, 0x1F43, 0x0080, 0x055E, 0x037A, 0x1F34, 0x1FE2,
485 0x0050, 0x1F4D, 0x005E, 0x0548, 0x03A5, 0x1F41, 0x1FD7,
486 0x0050, 0x1F57, 0x003D, 0x0531, 0x03D1, 0x1F4F, 0x1FCB,
487 0x0050, 0x1F62, 0x001E, 0x0516, 0x03FB, 0x1F5F, 0x1FC0,
488 0x004F, 0x1F6D, 0x0000, 0x04FA, 0x0425, 0x1F71, 0x1FB4,
489 0x004E, 0x1F79, 0x1FE4, 0x04DC, 0x044D, 0x1F84, 0x1FA8,
490 0x004D, 0x1F84, 0x1FCA, 0x04BC, 0x0474, 0x1F99, 0x1F9C,
491 0x1F8C, 0x1FAE, 0x04C6, 0x04C6, 0x1FAE, 0x1F8C, 0x0000,
492 0x1F9C, 0x1F99, 0x0474, 0x04BC, 0x1FCA, 0x1F84, 0x004D,
493 0x1FA8, 0x1F84, 0x044D, 0x04DC, 0x1FE4, 0x1F79, 0x004E,
494 0x1FB4, 0x1F71, 0x0425, 0x04FA, 0x0000, 0x1F6D, 0x004F,
495 0x1FC0, 0x1F5F, 0x03FB, 0x0516, 0x001E, 0x1F62, 0x0050,
496 0x1FCB, 0x1F4F, 0x03D1, 0x0531, 0x003D, 0x1F57, 0x0050,
497 0x1FD7, 0x1F41, 0x03A5, 0x0548, 0x005E, 0x1F4D, 0x0050,
498 0x1FE2, 0x1F34, 0x037A, 0x055E, 0x0080, 0x1F43, 0x004F,
499 0x1FEC, 0x1F2A, 0x034D, 0x0572, 0x00A4, 0x1F39, 0x004E,
500 0x1FF6, 0x1F20, 0x0321, 0x0584, 0x00C9, 0x1F30, 0x004C,
501 0x0000, 0x1F19, 0x02F4, 0x0593, 0x00EF, 0x1F28, 0x0049,
502 0x0009, 0x1F13, 0x02C6, 0x05A1, 0x0116, 0x1F21, 0x0046,
503 0x0012, 0x1F0F, 0x0299, 0x05AA, 0x013E, 0x1F1B, 0x0043,
504 0x001A, 0x1F0C, 0x026C, 0x05B3, 0x0167, 0x1F15, 0x003F,
505 0x0021, 0x1F0A, 0x023F, 0x05BA, 0x0191, 0x1F11, 0x003A,
506 0x0028, 0x1F0A, 0x0213, 0x05BD, 0x01BC, 0x1F0D, 0x0035,
507 },
508 [HS_LT_15_16_SCALE] = {
509 /* Luma */
510 0x005B, 0x1F0A, 0x0195, 0x060C, 0x0195, 0x1F0A, 0x005B,
511 0x005D, 0x1F13, 0x0166, 0x0609, 0x01C6, 0x1F03, 0x0058,
512 0x005F, 0x1F1C, 0x0138, 0x0605, 0x01F7, 0x1EFD, 0x0054,
513 0x0060, 0x1F26, 0x010B, 0x05FF, 0x0229, 0x1EF8, 0x004F,
514 0x0060, 0x1F31, 0x00DF, 0x05F5, 0x025C, 0x1EF5, 0x004A,
515 0x0060, 0x1F3D, 0x00B5, 0x05E8, 0x028F, 0x1EF3, 0x0044,
516 0x005F, 0x1F49, 0x008C, 0x05DA, 0x02C3, 0x1EF2, 0x003D,
517 0x005E, 0x1F56, 0x0065, 0x05C7, 0x02F6, 0x1EF4, 0x0036,
518 0x005C, 0x1F63, 0x003F, 0x05B3, 0x032B, 0x1EF7, 0x002D,
519 0x0059, 0x1F71, 0x001B, 0x059D, 0x035F, 0x1EFB, 0x0024,
520 0x0057, 0x1F7F, 0x1FF9, 0x0583, 0x0392, 0x1F02, 0x001A,
521 0x0053, 0x1F8D, 0x1FD9, 0x0567, 0x03C5, 0x1F0B, 0x0010,
522 0x0050, 0x1F9B, 0x1FBB, 0x0548, 0x03F8, 0x1F15, 0x0005,
523 0x004C, 0x1FA9, 0x1F9E, 0x0528, 0x042A, 0x1F22, 0x1FF9,
524 0x0048, 0x1FB7, 0x1F84, 0x0505, 0x045A, 0x1F31, 0x1FED,
525 0x0043, 0x1FC5, 0x1F6C, 0x04E0, 0x048A, 0x1F42, 0x1FE0,
526 0x1FD1, 0x1F50, 0x04DF, 0x04DF, 0x1F50, 0x1FD1, 0x0000,
527 0x1FE0, 0x1F42, 0x048A, 0x04E0, 0x1F6C, 0x1FC5, 0x0043,
528 0x1FED, 0x1F31, 0x045A, 0x0505, 0x1F84, 0x1FB7, 0x0048,
529 0x1FF9, 0x1F22, 0x042A, 0x0528, 0x1F9E, 0x1FA9, 0x004C,
530 0x0005, 0x1F15, 0x03F8, 0x0548, 0x1FBB, 0x1F9B, 0x0050,
531 0x0010, 0x1F0B, 0x03C5, 0x0567, 0x1FD9, 0x1F8D, 0x0053,
532 0x001A, 0x1F02, 0x0392, 0x0583, 0x1FF9, 0x1F7F, 0x0057,
533 0x0024, 0x1EFB, 0x035F, 0x059D, 0x001B, 0x1F71, 0x0059,
534 0x002D, 0x1EF7, 0x032B, 0x05B3, 0x003F, 0x1F63, 0x005C,
535 0x0036, 0x1EF4, 0x02F6, 0x05C7, 0x0065, 0x1F56, 0x005E,
536 0x003D, 0x1EF2, 0x02C3, 0x05DA, 0x008C, 0x1F49, 0x005F,
537 0x0044, 0x1EF3, 0x028F, 0x05E8, 0x00B5, 0x1F3D, 0x0060,
538 0x004A, 0x1EF5, 0x025C, 0x05F5, 0x00DF, 0x1F31, 0x0060,
539 0x004F, 0x1EF8, 0x0229, 0x05FF, 0x010B, 0x1F26, 0x0060,
540 0x0054, 0x1EFD, 0x01F7, 0x0605, 0x0138, 0x1F1C, 0x005F,
541 0x0058, 0x1F03, 0x01C6, 0x0609, 0x0166, 0x1F13, 0x005D,
542 /* Chroma */
543 0x005B, 0x1F0A, 0x0195, 0x060C, 0x0195, 0x1F0A, 0x005B,
544 0x005D, 0x1F13, 0x0166, 0x0609, 0x01C6, 0x1F03, 0x0058,
545 0x005F, 0x1F1C, 0x0138, 0x0605, 0x01F7, 0x1EFD, 0x0054,
546 0x0060, 0x1F26, 0x010B, 0x05FF, 0x0229, 0x1EF8, 0x004F,
547 0x0060, 0x1F31, 0x00DF, 0x05F5, 0x025C, 0x1EF5, 0x004A,
548 0x0060, 0x1F3D, 0x00B5, 0x05E8, 0x028F, 0x1EF3, 0x0044,
549 0x005F, 0x1F49, 0x008C, 0x05DA, 0x02C3, 0x1EF2, 0x003D,
550 0x005E, 0x1F56, 0x0065, 0x05C7, 0x02F6, 0x1EF4, 0x0036,
551 0x005C, 0x1F63, 0x003F, 0x05B3, 0x032B, 0x1EF7, 0x002D,
552 0x0059, 0x1F71, 0x001B, 0x059D, 0x035F, 0x1EFB, 0x0024,
553 0x0057, 0x1F7F, 0x1FF9, 0x0583, 0x0392, 0x1F02, 0x001A,
554 0x0053, 0x1F8D, 0x1FD9, 0x0567, 0x03C5, 0x1F0B, 0x0010,
555 0x0050, 0x1F9B, 0x1FBB, 0x0548, 0x03F8, 0x1F15, 0x0005,
556 0x004C, 0x1FA9, 0x1F9E, 0x0528, 0x042A, 0x1F22, 0x1FF9,
557 0x0048, 0x1FB7, 0x1F84, 0x0505, 0x045A, 0x1F31, 0x1FED,
558 0x0043, 0x1FC5, 0x1F6C, 0x04E0, 0x048A, 0x1F42, 0x1FE0,
559 0x1FD1, 0x1F50, 0x04DF, 0x04DF, 0x1F50, 0x1FD1, 0x0000,
560 0x1FE0, 0x1F42, 0x048A, 0x04E0, 0x1F6C, 0x1FC5, 0x0043,
561 0x1FED, 0x1F31, 0x045A, 0x0505, 0x1F84, 0x1FB7, 0x0048,
562 0x1FF9, 0x1F22, 0x042A, 0x0528, 0x1F9E, 0x1FA9, 0x004C,
563 0x0005, 0x1F15, 0x03F8, 0x0548, 0x1FBB, 0x1F9B, 0x0050,
564 0x0010, 0x1F0B, 0x03C5, 0x0567, 0x1FD9, 0x1F8D, 0x0053,
565 0x001A, 0x1F02, 0x0392, 0x0583, 0x1FF9, 0x1F7F, 0x0057,
566 0x0024, 0x1EFB, 0x035F, 0x059D, 0x001B, 0x1F71, 0x0059,
567 0x002D, 0x1EF7, 0x032B, 0x05B3, 0x003F, 0x1F63, 0x005C,
568 0x0036, 0x1EF4, 0x02F6, 0x05C7, 0x0065, 0x1F56, 0x005E,
569 0x003D, 0x1EF2, 0x02C3, 0x05DA, 0x008C, 0x1F49, 0x005F,
570 0x0044, 0x1EF3, 0x028F, 0x05E8, 0x00B5, 0x1F3D, 0x0060,
571 0x004A, 0x1EF5, 0x025C, 0x05F5, 0x00DF, 0x1F31, 0x0060,
572 0x004F, 0x1EF8, 0x0229, 0x05FF, 0x010B, 0x1F26, 0x0060,
573 0x0054, 0x1EFD, 0x01F7, 0x0605, 0x0138, 0x1F1C, 0x005F,
574 0x0058, 0x1F03, 0x01C6, 0x0609, 0x0166, 0x1F13, 0x005D,
575 },
576 [HS_LE_16_16_SCALE] = {
577 /* Luma */
578 0x006E, 0x1F24, 0x013E, 0x0660, 0x013E, 0x1F24, 0x006E,
579 0x006C, 0x1F33, 0x010B, 0x065D, 0x0172, 0x1F17, 0x0070,
580 0x0069, 0x1F41, 0x00DA, 0x0659, 0x01A8, 0x1F0B, 0x0070,
581 0x0066, 0x1F51, 0x00AA, 0x0650, 0x01DF, 0x1F00, 0x0070,
582 0x0062, 0x1F61, 0x007D, 0x0644, 0x0217, 0x1EF6, 0x006F,
583 0x005E, 0x1F71, 0x0051, 0x0636, 0x0250, 0x1EED, 0x006D,
584 0x0059, 0x1F81, 0x0028, 0x0624, 0x028A, 0x1EE5, 0x006B,
585 0x0054, 0x1F91, 0x0000, 0x060F, 0x02C5, 0x1EE0, 0x0067,
586 0x004E, 0x1FA2, 0x1FDB, 0x05F6, 0x0300, 0x1EDC, 0x0063,
587 0x0049, 0x1FB2, 0x1FB8, 0x05DB, 0x033B, 0x1EDA, 0x005D,
588 0x0043, 0x1FC3, 0x1F98, 0x05BC, 0x0376, 0x1ED9, 0x0057,
589 0x003D, 0x1FD3, 0x1F7A, 0x059B, 0x03B1, 0x1EDB, 0x004F,
590 0x0036, 0x1FE2, 0x1F5E, 0x0578, 0x03EC, 0x1EDF, 0x0047,
591 0x0030, 0x1FF1, 0x1F45, 0x0551, 0x0426, 0x1EE6, 0x003D,
592 0x002A, 0x0000, 0x1F2E, 0x0528, 0x045F, 0x1EEE, 0x0033,
593 0x0023, 0x000E, 0x1F19, 0x04FD, 0x0498, 0x1EFA, 0x0027,
594 0x001B, 0x1F04, 0x04E1, 0x04E1, 0x1F04, 0x001B, 0x0000,
595 0x0027, 0x1EFA, 0x0498, 0x04FD, 0x1F19, 0x000E, 0x0023,
596 0x0033, 0x1EEE, 0x045F, 0x0528, 0x1F2E, 0x0000, 0x002A,
597 0x003D, 0x1EE6, 0x0426, 0x0551, 0x1F45, 0x1FF1, 0x0030,
598 0x0047, 0x1EDF, 0x03EC, 0x0578, 0x1F5E, 0x1FE2, 0x0036,
599 0x004F, 0x1EDB, 0x03B1, 0x059B, 0x1F7A, 0x1FD3, 0x003D,
600 0x0057, 0x1ED9, 0x0376, 0x05BC, 0x1F98, 0x1FC3, 0x0043,
601 0x005D, 0x1EDA, 0x033B, 0x05DB, 0x1FB8, 0x1FB2, 0x0049,
602 0x0063, 0x1EDC, 0x0300, 0x05F6, 0x1FDB, 0x1FA2, 0x004E,
603 0x0067, 0x1EE0, 0x02C5, 0x060F, 0x0000, 0x1F91, 0x0054,
604 0x006B, 0x1EE5, 0x028A, 0x0624, 0x0028, 0x1F81, 0x0059,
605 0x006D, 0x1EED, 0x0250, 0x0636, 0x0051, 0x1F71, 0x005E,
606 0x006F, 0x1EF6, 0x0217, 0x0644, 0x007D, 0x1F61, 0x0062,
607 0x0070, 0x1F00, 0x01DF, 0x0650, 0x00AA, 0x1F51, 0x0066,
608 0x0070, 0x1F0B, 0x01A8, 0x0659, 0x00DA, 0x1F41, 0x0069,
609 0x0070, 0x1F17, 0x0172, 0x065D, 0x010B, 0x1F33, 0x006C,
610 /* Chroma */
611 0x006E, 0x1F24, 0x013E, 0x0660, 0x013E, 0x1F24, 0x006E,
612 0x006C, 0x1F33, 0x010B, 0x065D, 0x0172, 0x1F17, 0x0070,
613 0x0069, 0x1F41, 0x00DA, 0x0659, 0x01A8, 0x1F0B, 0x0070,
614 0x0066, 0x1F51, 0x00AA, 0x0650, 0x01DF, 0x1F00, 0x0070,
615 0x0062, 0x1F61, 0x007D, 0x0644, 0x0217, 0x1EF6, 0x006F,
616 0x005E, 0x1F71, 0x0051, 0x0636, 0x0250, 0x1EED, 0x006D,
617 0x0059, 0x1F81, 0x0028, 0x0624, 0x028A, 0x1EE5, 0x006B,
618 0x0054, 0x1F91, 0x0000, 0x060F, 0x02C5, 0x1EE0, 0x0067,
619 0x004E, 0x1FA2, 0x1FDB, 0x05F6, 0x0300, 0x1EDC, 0x0063,
620 0x0049, 0x1FB2, 0x1FB8, 0x05DB, 0x033B, 0x1EDA, 0x005D,
621 0x0043, 0x1FC3, 0x1F98, 0x05BC, 0x0376, 0x1ED9, 0x0057,
622 0x003D, 0x1FD3, 0x1F7A, 0x059B, 0x03B1, 0x1EDB, 0x004F,
623 0x0036, 0x1FE2, 0x1F5E, 0x0578, 0x03EC, 0x1EDF, 0x0047,
624 0x0030, 0x1FF1, 0x1F45, 0x0551, 0x0426, 0x1EE6, 0x003D,
625 0x002A, 0x0000, 0x1F2E, 0x0528, 0x045F, 0x1EEE, 0x0033,
626 0x0023, 0x000E, 0x1F19, 0x04FD, 0x0498, 0x1EFA, 0x0027,
627 0x001B, 0x1F04, 0x04E1, 0x04E1, 0x1F04, 0x001B, 0x0000,
628 0x0027, 0x1EFA, 0x0498, 0x04FD, 0x1F19, 0x000E, 0x0023,
629 0x0033, 0x1EEE, 0x045F, 0x0528, 0x1F2E, 0x0000, 0x002A,
630 0x003D, 0x1EE6, 0x0426, 0x0551, 0x1F45, 0x1FF1, 0x0030,
631 0x0047, 0x1EDF, 0x03EC, 0x0578, 0x1F5E, 0x1FE2, 0x0036,
632 0x004F, 0x1EDB, 0x03B1, 0x059B, 0x1F7A, 0x1FD3, 0x003D,
633 0x0057, 0x1ED9, 0x0376, 0x05BC, 0x1F98, 0x1FC3, 0x0043,
634 0x005D, 0x1EDA, 0x033B, 0x05DB, 0x1FB8, 0x1FB2, 0x0049,
635 0x0063, 0x1EDC, 0x0300, 0x05F6, 0x1FDB, 0x1FA2, 0x004E,
636 0x0067, 0x1EE0, 0x02C5, 0x060F, 0x0000, 0x1F91, 0x0054,
637 0x006B, 0x1EE5, 0x028A, 0x0624, 0x0028, 0x1F81, 0x0059,
638 0x006D, 0x1EED, 0x0250, 0x0636, 0x0051, 0x1F71, 0x005E,
639 0x006F, 0x1EF6, 0x0217, 0x0644, 0x007D, 0x1F61, 0x0062,
640 0x0070, 0x1F00, 0x01DF, 0x0650, 0x00AA, 0x1F51, 0x0066,
641 0x0070, 0x1F0B, 0x01A8, 0x0659, 0x00DA, 0x1F41, 0x0069,
642 0x0070, 0x1F17, 0x0172, 0x065D, 0x010B, 0x1F33, 0x006C,
643 },
644};
645
646/* vertical scaler coefficients */
647enum {
648 VS_UP_SCALE = 0,
649 VS_LT_9_16_SCALE,
650 VS_LT_10_16_SCALE,
651 VS_LT_11_16_SCALE,
652 VS_LT_12_16_SCALE,
653 VS_LT_13_16_SCALE,
654 VS_LT_14_16_SCALE,
655 VS_LT_15_16_SCALE,
656 VS_LT_16_16_SCALE,
657 VS_1_TO_1_SCALE,
658};
659
660static const u16 scaler_vs_coeffs[15][SC_NUM_PHASES * 2 * SC_V_NUM_TAPS] = {
661 [VS_UP_SCALE] = {
662 /* Luma */
663 0x1FD1, 0x00B1, 0x06FC, 0x00B1, 0x1FD1,
664 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
665 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
666 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
667 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
668 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
669 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
670 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
671 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
672 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
673 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
674 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
675 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
676 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
677 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
678 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
679 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
680 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
681 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
682 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
683 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
684 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
685 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
686 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
687 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
688 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
689 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
690 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
691 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
692 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
693 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
694 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
695 /* Chroma */
696 0x1FD1, 0x00B1, 0x06FC, 0x00B1, 0x1FD1,
697 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
698 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
699 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
700 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
701 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
702 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
703 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
704 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
705 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
706 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
707 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
708 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
709 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
710 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
711 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
712 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
713 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
714 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
715 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
716 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
717 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
718 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
719 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
720 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
721 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
722 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
723 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
724 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
725 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
726 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
727 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
728 },
729 [VS_LT_9_16_SCALE] = {
730 /* Luma */
731 0x001C, 0x01F6, 0x03DC, 0x01F6, 0x001C,
732 0x0018, 0x01DF, 0x03DB, 0x020C, 0x0022,
733 0x0013, 0x01C9, 0x03D9, 0x0223, 0x0028,
734 0x000F, 0x01B3, 0x03D6, 0x023A, 0x002E,
735 0x000C, 0x019D, 0x03D2, 0x0250, 0x0035,
736 0x0009, 0x0188, 0x03CC, 0x0266, 0x003D,
737 0x0006, 0x0173, 0x03C5, 0x027D, 0x0045,
738 0x0004, 0x015E, 0x03BD, 0x0293, 0x004E,
739 0x0002, 0x014A, 0x03B4, 0x02A8, 0x0058,
740 0x0000, 0x0136, 0x03AA, 0x02BE, 0x0062,
741 0x1FFF, 0x0123, 0x039E, 0x02D3, 0x006D,
742 0x1FFE, 0x0110, 0x0392, 0x02E8, 0x0078,
743 0x1FFD, 0x00FE, 0x0384, 0x02FC, 0x0085,
744 0x1FFD, 0x00ED, 0x0376, 0x030F, 0x0091,
745 0x1FFC, 0x00DC, 0x0367, 0x0322, 0x009F,
746 0x1FFC, 0x00CC, 0x0357, 0x0334, 0x00AD,
747 0x00BC, 0x0344, 0x0344, 0x00BC, 0x0000,
748 0x00AD, 0x0334, 0x0357, 0x00CC, 0x1FFC,
749 0x009F, 0x0322, 0x0367, 0x00DC, 0x1FFC,
750 0x0091, 0x030F, 0x0376, 0x00ED, 0x1FFD,
751 0x0085, 0x02FC, 0x0384, 0x00FE, 0x1FFD,
752 0x0078, 0x02E8, 0x0392, 0x0110, 0x1FFE,
753 0x006D, 0x02D3, 0x039E, 0x0123, 0x1FFF,
754 0x0062, 0x02BE, 0x03AA, 0x0136, 0x0000,
755 0x0058, 0x02A8, 0x03B4, 0x014A, 0x0002,
756 0x004E, 0x0293, 0x03BD, 0x015E, 0x0004,
757 0x0045, 0x027D, 0x03C5, 0x0173, 0x0006,
758 0x003D, 0x0266, 0x03CC, 0x0188, 0x0009,
759 0x0035, 0x0250, 0x03D2, 0x019D, 0x000C,
760 0x002E, 0x023A, 0x03D6, 0x01B3, 0x000F,
761 0x0028, 0x0223, 0x03D9, 0x01C9, 0x0013,
762 0x0022, 0x020C, 0x03DB, 0x01DF, 0x0018,
763 /* Chroma */
764 0x001C, 0x01F6, 0x03DC, 0x01F6, 0x001C,
765 0x0018, 0x01DF, 0x03DB, 0x020C, 0x0022,
766 0x0013, 0x01C9, 0x03D9, 0x0223, 0x0028,
767 0x000F, 0x01B3, 0x03D6, 0x023A, 0x002E,
768 0x000C, 0x019D, 0x03D2, 0x0250, 0x0035,
769 0x0009, 0x0188, 0x03CC, 0x0266, 0x003D,
770 0x0006, 0x0173, 0x03C5, 0x027D, 0x0045,
771 0x0004, 0x015E, 0x03BD, 0x0293, 0x004E,
772 0x0002, 0x014A, 0x03B4, 0x02A8, 0x0058,
773 0x0000, 0x0136, 0x03AA, 0x02BE, 0x0062,
774 0x1FFF, 0x0123, 0x039E, 0x02D3, 0x006D,
775 0x1FFE, 0x0110, 0x0392, 0x02E8, 0x0078,
776 0x1FFD, 0x00FE, 0x0384, 0x02FC, 0x0085,
777 0x1FFD, 0x00ED, 0x0376, 0x030F, 0x0091,
778 0x1FFC, 0x00DC, 0x0367, 0x0322, 0x009F,
779 0x1FFC, 0x00CC, 0x0357, 0x0334, 0x00AD,
780 0x00BC, 0x0344, 0x0344, 0x00BC, 0x0000,
781 0x00AD, 0x0334, 0x0357, 0x00CC, 0x1FFC,
782 0x009F, 0x0322, 0x0367, 0x00DC, 0x1FFC,
783 0x0091, 0x030F, 0x0376, 0x00ED, 0x1FFD,
784 0x0085, 0x02FC, 0x0384, 0x00FE, 0x1FFD,
785 0x0078, 0x02E8, 0x0392, 0x0110, 0x1FFE,
786 0x006D, 0x02D3, 0x039E, 0x0123, 0x1FFF,
787 0x0062, 0x02BE, 0x03AA, 0x0136, 0x0000,
788 0x0058, 0x02A8, 0x03B4, 0x014A, 0x0002,
789 0x004E, 0x0293, 0x03BD, 0x015E, 0x0004,
790 0x0045, 0x027D, 0x03C5, 0x0173, 0x0006,
791 0x003D, 0x0266, 0x03CC, 0x0188, 0x0009,
792 0x0035, 0x0250, 0x03D2, 0x019D, 0x000C,
793 0x002E, 0x023A, 0x03D6, 0x01B3, 0x000F,
794 0x0028, 0x0223, 0x03D9, 0x01C9, 0x0013,
795 0x0022, 0x020C, 0x03DB, 0x01DF, 0x0018,
796 },
797 [VS_LT_10_16_SCALE] = {
798 /* Luma */
799 0x0003, 0x01E9, 0x0428, 0x01E9, 0x0003,
800 0x0000, 0x01D0, 0x0426, 0x0203, 0x0007,
801 0x1FFD, 0x01B7, 0x0424, 0x021C, 0x000C,
802 0x1FFB, 0x019E, 0x0420, 0x0236, 0x0011,
803 0x1FF9, 0x0186, 0x041A, 0x0250, 0x0017,
804 0x1FF7, 0x016E, 0x0414, 0x026A, 0x001D,
805 0x1FF6, 0x0157, 0x040B, 0x0284, 0x0024,
806 0x1FF5, 0x0140, 0x0401, 0x029E, 0x002C,
807 0x1FF4, 0x012A, 0x03F6, 0x02B7, 0x0035,
808 0x1FF4, 0x0115, 0x03E9, 0x02D0, 0x003E,
809 0x1FF4, 0x0100, 0x03DB, 0x02E9, 0x0048,
810 0x1FF4, 0x00EC, 0x03CC, 0x0301, 0x0053,
811 0x1FF4, 0x00D9, 0x03BC, 0x0318, 0x005F,
812 0x1FF5, 0x00C7, 0x03AA, 0x032F, 0x006B,
813 0x1FF6, 0x00B5, 0x0398, 0x0345, 0x0078,
814 0x1FF6, 0x00A5, 0x0384, 0x035B, 0x0086,
815 0x0094, 0x036C, 0x036C, 0x0094, 0x0000,
816 0x0086, 0x035B, 0x0384, 0x00A5, 0x1FF6,
817 0x0078, 0x0345, 0x0398, 0x00B5, 0x1FF6,
818 0x006B, 0x032F, 0x03AA, 0x00C7, 0x1FF5,
819 0x005F, 0x0318, 0x03BC, 0x00D9, 0x1FF4,
820 0x0053, 0x0301, 0x03CC, 0x00EC, 0x1FF4,
821 0x0048, 0x02E9, 0x03DB, 0x0100, 0x1FF4,
822 0x003E, 0x02D0, 0x03E9, 0x0115, 0x1FF4,
823 0x0035, 0x02B7, 0x03F6, 0x012A, 0x1FF4,
824 0x002C, 0x029E, 0x0401, 0x0140, 0x1FF5,
825 0x0024, 0x0284, 0x040B, 0x0157, 0x1FF6,
826 0x001D, 0x026A, 0x0414, 0x016E, 0x1FF7,
827 0x0017, 0x0250, 0x041A, 0x0186, 0x1FF9,
828 0x0011, 0x0236, 0x0420, 0x019E, 0x1FFB,
829 0x000C, 0x021C, 0x0424, 0x01B7, 0x1FFD,
830 0x0007, 0x0203, 0x0426, 0x01D0, 0x0000,
831 /* Chroma */
832 0x0003, 0x01E9, 0x0428, 0x01E9, 0x0003,
833 0x0000, 0x01D0, 0x0426, 0x0203, 0x0007,
834 0x1FFD, 0x01B7, 0x0424, 0x021C, 0x000C,
835 0x1FFB, 0x019E, 0x0420, 0x0236, 0x0011,
836 0x1FF9, 0x0186, 0x041A, 0x0250, 0x0017,
837 0x1FF7, 0x016E, 0x0414, 0x026A, 0x001D,
838 0x1FF6, 0x0157, 0x040B, 0x0284, 0x0024,
839 0x1FF5, 0x0140, 0x0401, 0x029E, 0x002C,
840 0x1FF4, 0x012A, 0x03F6, 0x02B7, 0x0035,
841 0x1FF4, 0x0115, 0x03E9, 0x02D0, 0x003E,
842 0x1FF4, 0x0100, 0x03DB, 0x02E9, 0x0048,
843 0x1FF4, 0x00EC, 0x03CC, 0x0301, 0x0053,
844 0x1FF4, 0x00D9, 0x03BC, 0x0318, 0x005F,
845 0x1FF5, 0x00C7, 0x03AA, 0x032F, 0x006B,
846 0x1FF6, 0x00B5, 0x0398, 0x0345, 0x0078,
847 0x1FF6, 0x00A5, 0x0384, 0x035B, 0x0086,
848 0x0094, 0x036C, 0x036C, 0x0094, 0x0000,
849 0x0086, 0x035B, 0x0384, 0x00A5, 0x1FF6,
850 0x0078, 0x0345, 0x0398, 0x00B5, 0x1FF6,
851 0x006B, 0x032F, 0x03AA, 0x00C7, 0x1FF5,
852 0x005F, 0x0318, 0x03BC, 0x00D9, 0x1FF4,
853 0x0053, 0x0301, 0x03CC, 0x00EC, 0x1FF4,
854 0x0048, 0x02E9, 0x03DB, 0x0100, 0x1FF4,
855 0x003E, 0x02D0, 0x03E9, 0x0115, 0x1FF4,
856 0x0035, 0x02B7, 0x03F6, 0x012A, 0x1FF4,
857 0x002C, 0x029E, 0x0401, 0x0140, 0x1FF5,
858 0x0024, 0x0284, 0x040B, 0x0157, 0x1FF6,
859 0x001D, 0x026A, 0x0414, 0x016E, 0x1FF7,
860 0x0017, 0x0250, 0x041A, 0x0186, 0x1FF9,
861 0x0011, 0x0236, 0x0420, 0x019E, 0x1FFB,
862 0x000C, 0x021C, 0x0424, 0x01B7, 0x1FFD,
863 0x0007, 0x0203, 0x0426, 0x01D0, 0x0000,
864 },
865 [VS_LT_11_16_SCALE] = {
866 /* Luma */
867 0x1FEC, 0x01D6, 0x047C, 0x01D6, 0x1FEC,
868 0x1FEA, 0x01BA, 0x047B, 0x01F3, 0x1FEE,
869 0x1FE9, 0x019D, 0x0478, 0x0211, 0x1FF1,
870 0x1FE8, 0x0182, 0x0473, 0x022E, 0x1FF5,
871 0x1FE8, 0x0167, 0x046C, 0x024C, 0x1FF9,
872 0x1FE8, 0x014D, 0x0464, 0x026A, 0x1FFD,
873 0x1FE8, 0x0134, 0x0459, 0x0288, 0x0003,
874 0x1FE9, 0x011B, 0x044D, 0x02A6, 0x0009,
875 0x1FE9, 0x0104, 0x0440, 0x02C3, 0x0010,
876 0x1FEA, 0x00ED, 0x0430, 0x02E1, 0x0018,
877 0x1FEB, 0x00D7, 0x0420, 0x02FD, 0x0021,
878 0x1FED, 0x00C2, 0x040D, 0x0319, 0x002B,
879 0x1FEE, 0x00AE, 0x03F9, 0x0336, 0x0035,
880 0x1FF0, 0x009C, 0x03E3, 0x0350, 0x0041,
881 0x1FF1, 0x008A, 0x03CD, 0x036B, 0x004D,
882 0x1FF3, 0x0079, 0x03B5, 0x0384, 0x005B,
883 0x0069, 0x0397, 0x0397, 0x0069, 0x0000,
884 0x005B, 0x0384, 0x03B5, 0x0079, 0x1FF3,
885 0x004D, 0x036B, 0x03CD, 0x008A, 0x1FF1,
886 0x0041, 0x0350, 0x03E3, 0x009C, 0x1FF0,
887 0x0035, 0x0336, 0x03F9, 0x00AE, 0x1FEE,
888 0x002B, 0x0319, 0x040D, 0x00C2, 0x1FED,
889 0x0021, 0x02FD, 0x0420, 0x00D7, 0x1FEB,
890 0x0018, 0x02E1, 0x0430, 0x00ED, 0x1FEA,
891 0x0010, 0x02C3, 0x0440, 0x0104, 0x1FE9,
892 0x0009, 0x02A6, 0x044D, 0x011B, 0x1FE9,
893 0x0003, 0x0288, 0x0459, 0x0134, 0x1FE8,
894 0x1FFD, 0x026A, 0x0464, 0x014D, 0x1FE8,
895 0x1FF9, 0x024C, 0x046C, 0x0167, 0x1FE8,
896 0x1FF5, 0x022E, 0x0473, 0x0182, 0x1FE8,
897 0x1FF1, 0x0211, 0x0478, 0x019D, 0x1FE9,
898 0x1FEE, 0x01F3, 0x047B, 0x01BA, 0x1FEA,
899 /* Chroma */
900 0x1FEC, 0x01D6, 0x047C, 0x01D6, 0x1FEC,
901 0x1FEA, 0x01BA, 0x047B, 0x01F3, 0x1FEE,
902 0x1FE9, 0x019D, 0x0478, 0x0211, 0x1FF1,
903 0x1FE8, 0x0182, 0x0473, 0x022E, 0x1FF5,
904 0x1FE8, 0x0167, 0x046C, 0x024C, 0x1FF9,
905 0x1FE8, 0x014D, 0x0464, 0x026A, 0x1FFD,
906 0x1FE8, 0x0134, 0x0459, 0x0288, 0x0003,
907 0x1FE9, 0x011B, 0x044D, 0x02A6, 0x0009,
908 0x1FE9, 0x0104, 0x0440, 0x02C3, 0x0010,
909 0x1FEA, 0x00ED, 0x0430, 0x02E1, 0x0018,
910 0x1FEB, 0x00D7, 0x0420, 0x02FD, 0x0021,
911 0x1FED, 0x00C2, 0x040D, 0x0319, 0x002B,
912 0x1FEE, 0x00AE, 0x03F9, 0x0336, 0x0035,
913 0x1FF0, 0x009C, 0x03E3, 0x0350, 0x0041,
914 0x1FF1, 0x008A, 0x03CD, 0x036B, 0x004D,
915 0x1FF3, 0x0079, 0x03B5, 0x0384, 0x005B,
916 0x0069, 0x0397, 0x0397, 0x0069, 0x0000,
917 0x005B, 0x0384, 0x03B5, 0x0079, 0x1FF3,
918 0x004D, 0x036B, 0x03CD, 0x008A, 0x1FF1,
919 0x0041, 0x0350, 0x03E3, 0x009C, 0x1FF0,
920 0x0035, 0x0336, 0x03F9, 0x00AE, 0x1FEE,
921 0x002B, 0x0319, 0x040D, 0x00C2, 0x1FED,
922 0x0021, 0x02FD, 0x0420, 0x00D7, 0x1FEB,
923 0x0018, 0x02E1, 0x0430, 0x00ED, 0x1FEA,
924 0x0010, 0x02C3, 0x0440, 0x0104, 0x1FE9,
925 0x0009, 0x02A6, 0x044D, 0x011B, 0x1FE9,
926 0x0003, 0x0288, 0x0459, 0x0134, 0x1FE8,
927 0x1FFD, 0x026A, 0x0464, 0x014D, 0x1FE8,
928 0x1FF9, 0x024C, 0x046C, 0x0167, 0x1FE8,
929 0x1FF5, 0x022E, 0x0473, 0x0182, 0x1FE8,
930 0x1FF1, 0x0211, 0x0478, 0x019D, 0x1FE9,
931 0x1FEE, 0x01F3, 0x047B, 0x01BA, 0x1FEA,
932 },
933 [VS_LT_12_16_SCALE] = {
934 /* Luma */
935 0x1FD8, 0x01BC, 0x04D8, 0x01BC, 0x1FD8,
936 0x1FD8, 0x019C, 0x04D8, 0x01DC, 0x1FD8,
937 0x1FD8, 0x017D, 0x04D4, 0x01FE, 0x1FD9,
938 0x1FD9, 0x015E, 0x04CF, 0x0220, 0x1FDA,
939 0x1FDB, 0x0141, 0x04C7, 0x0241, 0x1FDC,
940 0x1FDC, 0x0125, 0x04BC, 0x0264, 0x1FDF,
941 0x1FDE, 0x0109, 0x04B0, 0x0286, 0x1FE3,
942 0x1FE0, 0x00EF, 0x04A1, 0x02A9, 0x1FE7,
943 0x1FE2, 0x00D6, 0x0491, 0x02CB, 0x1FEC,
944 0x1FE4, 0x00BE, 0x047E, 0x02EE, 0x1FF2,
945 0x1FE6, 0x00A7, 0x046A, 0x030F, 0x1FFA,
946 0x1FE9, 0x0092, 0x0453, 0x0330, 0x0002,
947 0x1FEB, 0x007E, 0x043B, 0x0351, 0x000B,
948 0x1FED, 0x006B, 0x0421, 0x0372, 0x0015,
949 0x1FEF, 0x005A, 0x0406, 0x0391, 0x0020,
950 0x1FF1, 0x0049, 0x03EA, 0x03AF, 0x002D,
951 0x003A, 0x03C6, 0x03C6, 0x003A, 0x0000,
952 0x002D, 0x03AF, 0x03EA, 0x0049, 0x1FF1,
953 0x0020, 0x0391, 0x0406, 0x005A, 0x1FEF,
954 0x0015, 0x0372, 0x0421, 0x006B, 0x1FED,
955 0x000B, 0x0351, 0x043B, 0x007E, 0x1FEB,
956 0x0002, 0x0330, 0x0453, 0x0092, 0x1FE9,
957 0x1FFA, 0x030F, 0x046A, 0x00A7, 0x1FE6,
958 0x1FF2, 0x02EE, 0x047E, 0x00BE, 0x1FE4,
959 0x1FEC, 0x02CB, 0x0491, 0x00D6, 0x1FE2,
960 0x1FE7, 0x02A9, 0x04A1, 0x00EF, 0x1FE0,
961 0x1FE3, 0x0286, 0x04B0, 0x0109, 0x1FDE,
962 0x1FDF, 0x0264, 0x04BC, 0x0125, 0x1FDC,
963 0x1FDC, 0x0241, 0x04C7, 0x0141, 0x1FDB,
964 0x1FDA, 0x0220, 0x04CF, 0x015E, 0x1FD9,
965 0x1FD9, 0x01FE, 0x04D4, 0x017D, 0x1FD8,
966 0x1FD8, 0x01DC, 0x04D8, 0x019C, 0x1FD8,
967 /* Chroma */
968 0x1FD8, 0x01BC, 0x04D8, 0x01BC, 0x1FD8,
969 0x1FD8, 0x019C, 0x04D8, 0x01DC, 0x1FD8,
970 0x1FD8, 0x017D, 0x04D4, 0x01FE, 0x1FD9,
971 0x1FD9, 0x015E, 0x04CF, 0x0220, 0x1FDA,
972 0x1FDB, 0x0141, 0x04C7, 0x0241, 0x1FDC,
973 0x1FDC, 0x0125, 0x04BC, 0x0264, 0x1FDF,
974 0x1FDE, 0x0109, 0x04B0, 0x0286, 0x1FE3,
975 0x1FE0, 0x00EF, 0x04A1, 0x02A9, 0x1FE7,
976 0x1FE2, 0x00D6, 0x0491, 0x02CB, 0x1FEC,
977 0x1FE4, 0x00BE, 0x047E, 0x02EE, 0x1FF2,
978 0x1FE6, 0x00A7, 0x046A, 0x030F, 0x1FFA,
979 0x1FE9, 0x0092, 0x0453, 0x0330, 0x0002,
980 0x1FEB, 0x007E, 0x043B, 0x0351, 0x000B,
981 0x1FED, 0x006B, 0x0421, 0x0372, 0x0015,
982 0x1FEF, 0x005A, 0x0406, 0x0391, 0x0020,
983 0x1FF1, 0x0049, 0x03EA, 0x03AF, 0x002D,
984 0x003A, 0x03C6, 0x03C6, 0x003A, 0x0000,
985 0x002D, 0x03AF, 0x03EA, 0x0049, 0x1FF1,
986 0x0020, 0x0391, 0x0406, 0x005A, 0x1FEF,
987 0x0015, 0x0372, 0x0421, 0x006B, 0x1FED,
988 0x000B, 0x0351, 0x043B, 0x007E, 0x1FEB,
989 0x0002, 0x0330, 0x0453, 0x0092, 0x1FE9,
990 0x1FFA, 0x030F, 0x046A, 0x00A7, 0x1FE6,
991 0x1FF2, 0x02EE, 0x047E, 0x00BE, 0x1FE4,
992 0x1FEC, 0x02CB, 0x0491, 0x00D6, 0x1FE2,
993 0x1FE7, 0x02A9, 0x04A1, 0x00EF, 0x1FE0,
994 0x1FE3, 0x0286, 0x04B0, 0x0109, 0x1FDE,
995 0x1FDF, 0x0264, 0x04BC, 0x0125, 0x1FDC,
996 0x1FDC, 0x0241, 0x04C7, 0x0141, 0x1FDB,
997 0x1FDA, 0x0220, 0x04CF, 0x015E, 0x1FD9,
998 0x1FD9, 0x01FE, 0x04D4, 0x017D, 0x1FD8,
999 0x1FD8, 0x01DC, 0x04D8, 0x019C, 0x1FD8,
1000 },
1001 [VS_LT_13_16_SCALE] = {
1002 /* Luma */
1003 0x1FC8, 0x0199, 0x053E, 0x0199, 0x1FC8,
1004 0x1FCA, 0x0175, 0x053E, 0x01BD, 0x1FC6,
1005 0x1FCD, 0x0153, 0x0539, 0x01E2, 0x1FC5,
1006 0x1FCF, 0x0132, 0x0532, 0x0209, 0x1FC4,
1007 0x1FD2, 0x0112, 0x0529, 0x022F, 0x1FC4,
1008 0x1FD5, 0x00F4, 0x051C, 0x0256, 0x1FC5,
1009 0x1FD8, 0x00D7, 0x050D, 0x027E, 0x1FC6,
1010 0x1FDC, 0x00BB, 0x04FB, 0x02A6, 0x1FC8,
1011 0x1FDF, 0x00A1, 0x04E7, 0x02CE, 0x1FCB,
1012 0x1FE2, 0x0089, 0x04D1, 0x02F5, 0x1FCF,
1013 0x1FE5, 0x0072, 0x04B8, 0x031D, 0x1FD4,
1014 0x1FE8, 0x005D, 0x049E, 0x0344, 0x1FD9,
1015 0x1FEB, 0x0049, 0x0480, 0x036B, 0x1FE1,
1016 0x1FEE, 0x0037, 0x0462, 0x0390, 0x1FE9,
1017 0x1FF0, 0x0026, 0x0442, 0x03B6, 0x1FF2,
1018 0x1FF2, 0x0017, 0x0420, 0x03DA, 0x1FFD,
1019 0x0009, 0x03F7, 0x03F7, 0x0009, 0x0000,
1020 0x1FFD, 0x03DA, 0x0420, 0x0017, 0x1FF2,
1021 0x1FF2, 0x03B6, 0x0442, 0x0026, 0x1FF0,
1022 0x1FE9, 0x0390, 0x0462, 0x0037, 0x1FEE,
1023 0x1FE1, 0x036B, 0x0480, 0x0049, 0x1FEB,
1024 0x1FD9, 0x0344, 0x049E, 0x005D, 0x1FE8,
1025 0x1FD4, 0x031D, 0x04B8, 0x0072, 0x1FE5,
1026 0x1FCF, 0x02F5, 0x04D1, 0x0089, 0x1FE2,
1027 0x1FCB, 0x02CE, 0x04E7, 0x00A1, 0x1FDF,
1028 0x1FC8, 0x02A6, 0x04FB, 0x00BB, 0x1FDC,
1029 0x1FC6, 0x027E, 0x050D, 0x00D7, 0x1FD8,
1030 0x1FC5, 0x0256, 0x051C, 0x00F4, 0x1FD5,
1031 0x1FC4, 0x022F, 0x0529, 0x0112, 0x1FD2,
1032 0x1FC4, 0x0209, 0x0532, 0x0132, 0x1FCF,
1033 0x1FC5, 0x01E2, 0x0539, 0x0153, 0x1FCD,
1034 0x1FC6, 0x01BD, 0x053E, 0x0175, 0x1FCA,
1035 /* Chroma */
1036 0x1FC8, 0x0199, 0x053E, 0x0199, 0x1FC8,
1037 0x1FCA, 0x0175, 0x053E, 0x01BD, 0x1FC6,
1038 0x1FCD, 0x0153, 0x0539, 0x01E2, 0x1FC5,
1039 0x1FCF, 0x0132, 0x0532, 0x0209, 0x1FC4,
1040 0x1FD2, 0x0112, 0x0529, 0x022F, 0x1FC4,
1041 0x1FD5, 0x00F4, 0x051C, 0x0256, 0x1FC5,
1042 0x1FD8, 0x00D7, 0x050D, 0x027E, 0x1FC6,
1043 0x1FDC, 0x00BB, 0x04FB, 0x02A6, 0x1FC8,
1044 0x1FDF, 0x00A1, 0x04E7, 0x02CE, 0x1FCB,
1045 0x1FE2, 0x0089, 0x04D1, 0x02F5, 0x1FCF,
1046 0x1FE5, 0x0072, 0x04B8, 0x031D, 0x1FD4,
1047 0x1FE8, 0x005D, 0x049E, 0x0344, 0x1FD9,
1048 0x1FEB, 0x0049, 0x0480, 0x036B, 0x1FE1,
1049 0x1FEE, 0x0037, 0x0462, 0x0390, 0x1FE9,
1050 0x1FF0, 0x0026, 0x0442, 0x03B6, 0x1FF2,
1051 0x1FF2, 0x0017, 0x0420, 0x03DA, 0x1FFD,
1052 0x0009, 0x03F7, 0x03F7, 0x0009, 0x0000,
1053 0x1FFD, 0x03DA, 0x0420, 0x0017, 0x1FF2,
1054 0x1FF2, 0x03B6, 0x0442, 0x0026, 0x1FF0,
1055 0x1FE9, 0x0390, 0x0462, 0x0037, 0x1FEE,
1056 0x1FE1, 0x036B, 0x0480, 0x0049, 0x1FEB,
1057 0x1FD9, 0x0344, 0x049E, 0x005D, 0x1FE8,
1058 0x1FD4, 0x031D, 0x04B8, 0x0072, 0x1FE5,
1059 0x1FCF, 0x02F5, 0x04D1, 0x0089, 0x1FE2,
1060 0x1FCB, 0x02CE, 0x04E7, 0x00A1, 0x1FDF,
1061 0x1FC8, 0x02A6, 0x04FB, 0x00BB, 0x1FDC,
1062 0x1FC6, 0x027E, 0x050D, 0x00D7, 0x1FD8,
1063 0x1FC5, 0x0256, 0x051C, 0x00F4, 0x1FD5,
1064 0x1FC4, 0x022F, 0x0529, 0x0112, 0x1FD2,
1065 0x1FC4, 0x0209, 0x0532, 0x0132, 0x1FCF,
1066 0x1FC5, 0x01E2, 0x0539, 0x0153, 0x1FCD,
1067 0x1FC6, 0x01BD, 0x053E, 0x0175, 0x1FCA,
1068 },
1069 [VS_LT_14_16_SCALE] = {
1070 /* Luma */
1071 0x1FBF, 0x016C, 0x05AA, 0x016C, 0x1FBF,
1072 0x1FC3, 0x0146, 0x05A8, 0x0194, 0x1FBB,
1073 0x1FC7, 0x0121, 0x05A3, 0x01BD, 0x1FB8,
1074 0x1FCB, 0x00FD, 0x059B, 0x01E8, 0x1FB5,
1075 0x1FD0, 0x00DC, 0x058F, 0x0213, 0x1FB2,
1076 0x1FD4, 0x00BC, 0x0580, 0x0240, 0x1FB0,
1077 0x1FD8, 0x009E, 0x056E, 0x026D, 0x1FAF,
1078 0x1FDC, 0x0082, 0x055A, 0x029A, 0x1FAE,
1079 0x1FE0, 0x0067, 0x0542, 0x02C9, 0x1FAE,
1080 0x1FE4, 0x004F, 0x0528, 0x02F6, 0x1FAF,
1081 0x1FE8, 0x0038, 0x050A, 0x0325, 0x1FB1,
1082 0x1FEB, 0x0024, 0x04EB, 0x0352, 0x1FB4,
1083 0x1FEE, 0x0011, 0x04C8, 0x0380, 0x1FB9,
1084 0x1FF1, 0x0000, 0x04A4, 0x03AC, 0x1FBF,
1085 0x1FF4, 0x1FF1, 0x047D, 0x03D8, 0x1FC6,
1086 0x1FF6, 0x1FE4, 0x0455, 0x0403, 0x1FCE,
1087 0x1FD8, 0x0428, 0x0428, 0x1FD8, 0x0000,
1088 0x1FCE, 0x0403, 0x0455, 0x1FE4, 0x1FF6,
1089 0x1FC6, 0x03D8, 0x047D, 0x1FF1, 0x1FF4,
1090 0x1FBF, 0x03AC, 0x04A4, 0x0000, 0x1FF1,
1091 0x1FB9, 0x0380, 0x04C8, 0x0011, 0x1FEE,
1092 0x1FB4, 0x0352, 0x04EB, 0x0024, 0x1FEB,
1093 0x1FB1, 0x0325, 0x050A, 0x0038, 0x1FE8,
1094 0x1FAF, 0x02F6, 0x0528, 0x004F, 0x1FE4,
1095 0x1FAE, 0x02C9, 0x0542, 0x0067, 0x1FE0,
1096 0x1FAE, 0x029A, 0x055A, 0x0082, 0x1FDC,
1097 0x1FAF, 0x026D, 0x056E, 0x009E, 0x1FD8,
1098 0x1FB0, 0x0240, 0x0580, 0x00BC, 0x1FD4,
1099 0x1FB2, 0x0213, 0x058F, 0x00DC, 0x1FD0,
1100 0x1FB5, 0x01E8, 0x059B, 0x00FD, 0x1FCB,
1101 0x1FB8, 0x01BD, 0x05A3, 0x0121, 0x1FC7,
1102 0x1FBB, 0x0194, 0x05A8, 0x0146, 0x1FC3,
1103 /* Chroma */
1104 0x1FBF, 0x016C, 0x05AA, 0x016C, 0x1FBF,
1105 0x1FC3, 0x0146, 0x05A8, 0x0194, 0x1FBB,
1106 0x1FC7, 0x0121, 0x05A3, 0x01BD, 0x1FB8,
1107 0x1FCB, 0x00FD, 0x059B, 0x01E8, 0x1FB5,
1108 0x1FD0, 0x00DC, 0x058F, 0x0213, 0x1FB2,
1109 0x1FD4, 0x00BC, 0x0580, 0x0240, 0x1FB0,
1110 0x1FD8, 0x009E, 0x056E, 0x026D, 0x1FAF,
1111 0x1FDC, 0x0082, 0x055A, 0x029A, 0x1FAE,
1112 0x1FE0, 0x0067, 0x0542, 0x02C9, 0x1FAE,
1113 0x1FE4, 0x004F, 0x0528, 0x02F6, 0x1FAF,
1114 0x1FE8, 0x0038, 0x050A, 0x0325, 0x1FB1,
1115 0x1FEB, 0x0024, 0x04EB, 0x0352, 0x1FB4,
1116 0x1FEE, 0x0011, 0x04C8, 0x0380, 0x1FB9,
1117 0x1FF1, 0x0000, 0x04A4, 0x03AC, 0x1FBF,
1118 0x1FF4, 0x1FF1, 0x047D, 0x03D8, 0x1FC6,
1119 0x1FF6, 0x1FE4, 0x0455, 0x0403, 0x1FCE,
1120 0x1FD8, 0x0428, 0x0428, 0x1FD8, 0x0000,
1121 0x1FCE, 0x0403, 0x0455, 0x1FE4, 0x1FF6,
1122 0x1FC6, 0x03D8, 0x047D, 0x1FF1, 0x1FF4,
1123 0x1FBF, 0x03AC, 0x04A4, 0x0000, 0x1FF1,
1124 0x1FB9, 0x0380, 0x04C8, 0x0011, 0x1FEE,
1125 0x1FB4, 0x0352, 0x04EB, 0x0024, 0x1FEB,
1126 0x1FB1, 0x0325, 0x050A, 0x0038, 0x1FE8,
1127 0x1FAF, 0x02F6, 0x0528, 0x004F, 0x1FE4,
1128 0x1FAE, 0x02C9, 0x0542, 0x0067, 0x1FE0,
1129 0x1FAE, 0x029A, 0x055A, 0x0082, 0x1FDC,
1130 0x1FAF, 0x026D, 0x056E, 0x009E, 0x1FD8,
1131 0x1FB0, 0x0240, 0x0580, 0x00BC, 0x1FD4,
1132 0x1FB2, 0x0213, 0x058F, 0x00DC, 0x1FD0,
1133 0x1FB5, 0x01E8, 0x059B, 0x00FD, 0x1FCB,
1134 0x1FB8, 0x01BD, 0x05A3, 0x0121, 0x1FC7,
1135 0x1FBB, 0x0194, 0x05A8, 0x0146, 0x1FC3,
1136 },
1137 [VS_LT_15_16_SCALE] = {
1138 /* Luma */
1139 0x1FBD, 0x0136, 0x061A, 0x0136, 0x1FBD,
1140 0x1FC3, 0x010D, 0x0617, 0x0161, 0x1FB8,
1141 0x1FC9, 0x00E6, 0x0611, 0x018E, 0x1FB2,
1142 0x1FCE, 0x00C1, 0x0607, 0x01BD, 0x1FAD,
1143 0x1FD4, 0x009E, 0x05F9, 0x01ED, 0x1FA8,
1144 0x1FD9, 0x007D, 0x05E8, 0x021F, 0x1FA3,
1145 0x1FDE, 0x005E, 0x05D3, 0x0252, 0x1F9F,
1146 0x1FE2, 0x0042, 0x05BC, 0x0285, 0x1F9B,
1147 0x1FE7, 0x0029, 0x059F, 0x02B9, 0x1F98,
1148 0x1FEA, 0x0011, 0x0580, 0x02EF, 0x1F96,
1149 0x1FEE, 0x1FFC, 0x055D, 0x0324, 0x1F95,
1150 0x1FF1, 0x1FE9, 0x0538, 0x0359, 0x1F95,
1151 0x1FF4, 0x1FD8, 0x0510, 0x038E, 0x1F96,
1152 0x1FF7, 0x1FC9, 0x04E5, 0x03C2, 0x1F99,
1153 0x1FF9, 0x1FBD, 0x04B8, 0x03F5, 0x1F9D,
1154 0x1FFB, 0x1FB2, 0x0489, 0x0428, 0x1FA2,
1155 0x1FAA, 0x0456, 0x0456, 0x1FAA, 0x0000,
1156 0x1FA2, 0x0428, 0x0489, 0x1FB2, 0x1FFB,
1157 0x1F9D, 0x03F5, 0x04B8, 0x1FBD, 0x1FF9,
1158 0x1F99, 0x03C2, 0x04E5, 0x1FC9, 0x1FF7,
1159 0x1F96, 0x038E, 0x0510, 0x1FD8, 0x1FF4,
1160 0x1F95, 0x0359, 0x0538, 0x1FE9, 0x1FF1,
1161 0x1F95, 0x0324, 0x055D, 0x1FFC, 0x1FEE,
1162 0x1F96, 0x02EF, 0x0580, 0x0011, 0x1FEA,
1163 0x1F98, 0x02B9, 0x059F, 0x0029, 0x1FE7,
1164 0x1F9B, 0x0285, 0x05BC, 0x0042, 0x1FE2,
1165 0x1F9F, 0x0252, 0x05D3, 0x005E, 0x1FDE,
1166 0x1FA3, 0x021F, 0x05E8, 0x007D, 0x1FD9,
1167 0x1FA8, 0x01ED, 0x05F9, 0x009E, 0x1FD4,
1168 0x1FAD, 0x01BD, 0x0607, 0x00C1, 0x1FCE,
1169 0x1FB2, 0x018E, 0x0611, 0x00E6, 0x1FC9,
1170 0x1FB8, 0x0161, 0x0617, 0x010D, 0x1FC3,
1171 /* Chroma */
1172 0x1FBD, 0x0136, 0x061A, 0x0136, 0x1FBD,
1173 0x1FC3, 0x010D, 0x0617, 0x0161, 0x1FB8,
1174 0x1FC9, 0x00E6, 0x0611, 0x018E, 0x1FB2,
1175 0x1FCE, 0x00C1, 0x0607, 0x01BD, 0x1FAD,
1176 0x1FD4, 0x009E, 0x05F9, 0x01ED, 0x1FA8,
1177 0x1FD9, 0x007D, 0x05E8, 0x021F, 0x1FA3,
1178 0x1FDE, 0x005E, 0x05D3, 0x0252, 0x1F9F,
1179 0x1FE2, 0x0042, 0x05BC, 0x0285, 0x1F9B,
1180 0x1FE7, 0x0029, 0x059F, 0x02B9, 0x1F98,
1181 0x1FEA, 0x0011, 0x0580, 0x02EF, 0x1F96,
1182 0x1FEE, 0x1FFC, 0x055D, 0x0324, 0x1F95,
1183 0x1FF1, 0x1FE9, 0x0538, 0x0359, 0x1F95,
1184 0x1FF4, 0x1FD8, 0x0510, 0x038E, 0x1F96,
1185 0x1FF7, 0x1FC9, 0x04E5, 0x03C2, 0x1F99,
1186 0x1FF9, 0x1FBD, 0x04B8, 0x03F5, 0x1F9D,
1187 0x1FFB, 0x1FB2, 0x0489, 0x0428, 0x1FA2,
1188 0x1FAA, 0x0456, 0x0456, 0x1FAA, 0x0000,
1189 0x1FA2, 0x0428, 0x0489, 0x1FB2, 0x1FFB,
1190 0x1F9D, 0x03F5, 0x04B8, 0x1FBD, 0x1FF9,
1191 0x1F99, 0x03C2, 0x04E5, 0x1FC9, 0x1FF7,
1192 0x1F96, 0x038E, 0x0510, 0x1FD8, 0x1FF4,
1193 0x1F95, 0x0359, 0x0538, 0x1FE9, 0x1FF1,
1194 0x1F95, 0x0324, 0x055D, 0x1FFC, 0x1FEE,
1195 0x1F96, 0x02EF, 0x0580, 0x0011, 0x1FEA,
1196 0x1F98, 0x02B9, 0x059F, 0x0029, 0x1FE7,
1197 0x1F9B, 0x0285, 0x05BC, 0x0042, 0x1FE2,
1198 0x1F9F, 0x0252, 0x05D3, 0x005E, 0x1FDE,
1199 0x1FA3, 0x021F, 0x05E8, 0x007D, 0x1FD9,
1200 0x1FA8, 0x01ED, 0x05F9, 0x009E, 0x1FD4,
1201 0x1FAD, 0x01BD, 0x0607, 0x00C1, 0x1FCE,
1202 0x1FB2, 0x018E, 0x0611, 0x00E6, 0x1FC9,
1203 0x1FB8, 0x0161, 0x0617, 0x010D, 0x1FC3,
1204 },
1205 [VS_LT_16_16_SCALE] = {
1206 /* Luma */
1207 0x1FC3, 0x00F8, 0x068A, 0x00F8, 0x1FC3,
1208 0x1FCA, 0x00CC, 0x0689, 0x0125, 0x1FBC,
1209 0x1FD1, 0x00A3, 0x0681, 0x0156, 0x1FB5,
1210 0x1FD7, 0x007D, 0x0676, 0x0188, 0x1FAE,
1211 0x1FDD, 0x005A, 0x0666, 0x01BD, 0x1FA6,
1212 0x1FE3, 0x0039, 0x0652, 0x01F3, 0x1F9F,
1213 0x1FE8, 0x001B, 0x0639, 0x022C, 0x1F98,
1214 0x1FEC, 0x0000, 0x061D, 0x0265, 0x1F92,
1215 0x1FF0, 0x1FE8, 0x05FC, 0x02A0, 0x1F8C,
1216 0x1FF4, 0x1FD2, 0x05D7, 0x02DC, 0x1F87,
1217 0x1FF7, 0x1FBF, 0x05AF, 0x0319, 0x1F82,
1218 0x1FFA, 0x1FAF, 0x0583, 0x0356, 0x1F7E,
1219 0x1FFC, 0x1FA1, 0x0554, 0x0393, 0x1F7C,
1220 0x1FFE, 0x1F95, 0x0523, 0x03CF, 0x1F7B,
1221 0x0000, 0x1F8C, 0x04EE, 0x040B, 0x1F7B,
1222 0x0001, 0x1F85, 0x04B8, 0x0446, 0x1F7C,
1223 0x1F80, 0x0480, 0x0480, 0x1F80, 0x0000,
1224 0x1F7C, 0x0446, 0x04B8, 0x1F85, 0x0001,
1225 0x1F7B, 0x040B, 0x04EE, 0x1F8C, 0x0000,
1226 0x1F7B, 0x03CF, 0x0523, 0x1F95, 0x1FFE,
1227 0x1F7C, 0x0393, 0x0554, 0x1FA1, 0x1FFC,
1228 0x1F7E, 0x0356, 0x0583, 0x1FAF, 0x1FFA,
1229 0x1F82, 0x0319, 0x05AF, 0x1FBF, 0x1FF7,
1230 0x1F87, 0x02DC, 0x05D7, 0x1FD2, 0x1FF4,
1231 0x1F8C, 0x02A0, 0x05FC, 0x1FE8, 0x1FF0,
1232 0x1F92, 0x0265, 0x061D, 0x0000, 0x1FEC,
1233 0x1F98, 0x022C, 0x0639, 0x001B, 0x1FE8,
1234 0x1F9F, 0x01F3, 0x0652, 0x0039, 0x1FE3,
1235 0x1FA6, 0x01BD, 0x0666, 0x005A, 0x1FDD,
1236 0x1FAE, 0x0188, 0x0676, 0x007D, 0x1FD7,
1237 0x1FB5, 0x0156, 0x0681, 0x00A3, 0x1FD1,
1238 0x1FBC, 0x0125, 0x0689, 0x00CC, 0x1FCA,
1239 /* Chroma */
1240 0x1FC3, 0x00F8, 0x068A, 0x00F8, 0x1FC3,
1241 0x1FCA, 0x00CC, 0x0689, 0x0125, 0x1FBC,
1242 0x1FD1, 0x00A3, 0x0681, 0x0156, 0x1FB5,
1243 0x1FD7, 0x007D, 0x0676, 0x0188, 0x1FAE,
1244 0x1FDD, 0x005A, 0x0666, 0x01BD, 0x1FA6,
1245 0x1FE3, 0x0039, 0x0652, 0x01F3, 0x1F9F,
1246 0x1FE8, 0x001B, 0x0639, 0x022C, 0x1F98,
1247 0x1FEC, 0x0000, 0x061D, 0x0265, 0x1F92,
1248 0x1FF0, 0x1FE8, 0x05FC, 0x02A0, 0x1F8C,
1249 0x1FF4, 0x1FD2, 0x05D7, 0x02DC, 0x1F87,
1250 0x1FF7, 0x1FBF, 0x05AF, 0x0319, 0x1F82,
1251 0x1FFA, 0x1FAF, 0x0583, 0x0356, 0x1F7E,
1252 0x1FFC, 0x1FA1, 0x0554, 0x0393, 0x1F7C,
1253 0x1FFE, 0x1F95, 0x0523, 0x03CF, 0x1F7B,
1254 0x0000, 0x1F8C, 0x04EE, 0x040B, 0x1F7B,
1255 0x0001, 0x1F85, 0x04B8, 0x0446, 0x1F7C,
1256 0x1F80, 0x0480, 0x0480, 0x1F80, 0x0000,
1257 0x1F7C, 0x0446, 0x04B8, 0x1F85, 0x0001,
1258 0x1F7B, 0x040B, 0x04EE, 0x1F8C, 0x0000,
1259 0x1F7B, 0x03CF, 0x0523, 0x1F95, 0x1FFE,
1260 0x1F7C, 0x0393, 0x0554, 0x1FA1, 0x1FFC,
1261 0x1F7E, 0x0356, 0x0583, 0x1FAF, 0x1FFA,
1262 0x1F82, 0x0319, 0x05AF, 0x1FBF, 0x1FF7,
1263 0x1F87, 0x02DC, 0x05D7, 0x1FD2, 0x1FF4,
1264 0x1F8C, 0x02A0, 0x05FC, 0x1FE8, 0x1FF0,
1265 0x1F92, 0x0265, 0x061D, 0x0000, 0x1FEC,
1266 0x1F98, 0x022C, 0x0639, 0x001B, 0x1FE8,
1267 0x1F9F, 0x01F3, 0x0652, 0x0039, 0x1FE3,
1268 0x1FA6, 0x01BD, 0x0666, 0x005A, 0x1FDD,
1269 0x1FAE, 0x0188, 0x0676, 0x007D, 0x1FD7,
1270 0x1FB5, 0x0156, 0x0681, 0x00A3, 0x1FD1,
1271 0x1FBC, 0x0125, 0x0689, 0x00CC, 0x1FCA,
1272 },
1273 [VS_1_TO_1_SCALE] = {
1274 /* Luma */
1275 0x0000, 0x0000, 0x0800, 0x0000, 0x0000,
1276 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
1277 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
1278 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
1279 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
1280 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
1281 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
1282 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
1283 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
1284 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
1285 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
1286 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
1287 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
1288 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
1289 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
1290 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
1291 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
1292 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
1293 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
1294 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
1295 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
1296 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
1297 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
1298 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
1299 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
1300 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
1301 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
1302 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
1303 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
1304 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
1305 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
1306 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
1307 /* Chroma */
1308 0x0000, 0x0000, 0x0800, 0x0000, 0x0000,
1309 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
1310 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
1311 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
1312 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
1313 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
1314 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
1315 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
1316 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
1317 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
1318 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
1319 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
1320 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
1321 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
1322 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
1323 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
1324 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
1325 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
1326 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
1327 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
1328 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
1329 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
1330 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
1331 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
1332 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
1333 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
1334 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
1335 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
1336 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
1337 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
1338 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
1339 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
1340 },
1341};
1342#endif
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index fcbe48a09cf8..e8175e7938ed 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -30,38 +30,47 @@
30 30
31const struct vpdma_data_format vpdma_yuv_fmts[] = { 31const struct vpdma_data_format vpdma_yuv_fmts[] = {
32 [VPDMA_DATA_FMT_Y444] = { 32 [VPDMA_DATA_FMT_Y444] = {
33 .type = VPDMA_DATA_FMT_TYPE_YUV,
33 .data_type = DATA_TYPE_Y444, 34 .data_type = DATA_TYPE_Y444,
34 .depth = 8, 35 .depth = 8,
35 }, 36 },
36 [VPDMA_DATA_FMT_Y422] = { 37 [VPDMA_DATA_FMT_Y422] = {
38 .type = VPDMA_DATA_FMT_TYPE_YUV,
37 .data_type = DATA_TYPE_Y422, 39 .data_type = DATA_TYPE_Y422,
38 .depth = 8, 40 .depth = 8,
39 }, 41 },
40 [VPDMA_DATA_FMT_Y420] = { 42 [VPDMA_DATA_FMT_Y420] = {
43 .type = VPDMA_DATA_FMT_TYPE_YUV,
41 .data_type = DATA_TYPE_Y420, 44 .data_type = DATA_TYPE_Y420,
42 .depth = 8, 45 .depth = 8,
43 }, 46 },
44 [VPDMA_DATA_FMT_C444] = { 47 [VPDMA_DATA_FMT_C444] = {
48 .type = VPDMA_DATA_FMT_TYPE_YUV,
45 .data_type = DATA_TYPE_C444, 49 .data_type = DATA_TYPE_C444,
46 .depth = 8, 50 .depth = 8,
47 }, 51 },
48 [VPDMA_DATA_FMT_C422] = { 52 [VPDMA_DATA_FMT_C422] = {
53 .type = VPDMA_DATA_FMT_TYPE_YUV,
49 .data_type = DATA_TYPE_C422, 54 .data_type = DATA_TYPE_C422,
50 .depth = 8, 55 .depth = 8,
51 }, 56 },
52 [VPDMA_DATA_FMT_C420] = { 57 [VPDMA_DATA_FMT_C420] = {
58 .type = VPDMA_DATA_FMT_TYPE_YUV,
53 .data_type = DATA_TYPE_C420, 59 .data_type = DATA_TYPE_C420,
54 .depth = 4, 60 .depth = 4,
55 }, 61 },
56 [VPDMA_DATA_FMT_YC422] = { 62 [VPDMA_DATA_FMT_YC422] = {
63 .type = VPDMA_DATA_FMT_TYPE_YUV,
57 .data_type = DATA_TYPE_YC422, 64 .data_type = DATA_TYPE_YC422,
58 .depth = 16, 65 .depth = 16,
59 }, 66 },
60 [VPDMA_DATA_FMT_YC444] = { 67 [VPDMA_DATA_FMT_YC444] = {
68 .type = VPDMA_DATA_FMT_TYPE_YUV,
61 .data_type = DATA_TYPE_YC444, 69 .data_type = DATA_TYPE_YC444,
62 .depth = 24, 70 .depth = 24,
63 }, 71 },
64 [VPDMA_DATA_FMT_CY422] = { 72 [VPDMA_DATA_FMT_CY422] = {
73 .type = VPDMA_DATA_FMT_TYPE_YUV,
65 .data_type = DATA_TYPE_CY422, 74 .data_type = DATA_TYPE_CY422,
66 .depth = 16, 75 .depth = 16,
67 }, 76 },
@@ -69,82 +78,102 @@ const struct vpdma_data_format vpdma_yuv_fmts[] = {
69 78
70const struct vpdma_data_format vpdma_rgb_fmts[] = { 79const struct vpdma_data_format vpdma_rgb_fmts[] = {
71 [VPDMA_DATA_FMT_RGB565] = { 80 [VPDMA_DATA_FMT_RGB565] = {
81 .type = VPDMA_DATA_FMT_TYPE_RGB,
72 .data_type = DATA_TYPE_RGB16_565, 82 .data_type = DATA_TYPE_RGB16_565,
73 .depth = 16, 83 .depth = 16,
74 }, 84 },
75 [VPDMA_DATA_FMT_ARGB16_1555] = { 85 [VPDMA_DATA_FMT_ARGB16_1555] = {
86 .type = VPDMA_DATA_FMT_TYPE_RGB,
76 .data_type = DATA_TYPE_ARGB_1555, 87 .data_type = DATA_TYPE_ARGB_1555,
77 .depth = 16, 88 .depth = 16,
78 }, 89 },
79 [VPDMA_DATA_FMT_ARGB16] = { 90 [VPDMA_DATA_FMT_ARGB16] = {
91 .type = VPDMA_DATA_FMT_TYPE_RGB,
80 .data_type = DATA_TYPE_ARGB_4444, 92 .data_type = DATA_TYPE_ARGB_4444,
81 .depth = 16, 93 .depth = 16,
82 }, 94 },
83 [VPDMA_DATA_FMT_RGBA16_5551] = { 95 [VPDMA_DATA_FMT_RGBA16_5551] = {
96 .type = VPDMA_DATA_FMT_TYPE_RGB,
84 .data_type = DATA_TYPE_RGBA_5551, 97 .data_type = DATA_TYPE_RGBA_5551,
85 .depth = 16, 98 .depth = 16,
86 }, 99 },
87 [VPDMA_DATA_FMT_RGBA16] = { 100 [VPDMA_DATA_FMT_RGBA16] = {
101 .type = VPDMA_DATA_FMT_TYPE_RGB,
88 .data_type = DATA_TYPE_RGBA_4444, 102 .data_type = DATA_TYPE_RGBA_4444,
89 .depth = 16, 103 .depth = 16,
90 }, 104 },
91 [VPDMA_DATA_FMT_ARGB24] = { 105 [VPDMA_DATA_FMT_ARGB24] = {
106 .type = VPDMA_DATA_FMT_TYPE_RGB,
92 .data_type = DATA_TYPE_ARGB24_6666, 107 .data_type = DATA_TYPE_ARGB24_6666,
93 .depth = 24, 108 .depth = 24,
94 }, 109 },
95 [VPDMA_DATA_FMT_RGB24] = { 110 [VPDMA_DATA_FMT_RGB24] = {
111 .type = VPDMA_DATA_FMT_TYPE_RGB,
96 .data_type = DATA_TYPE_RGB24_888, 112 .data_type = DATA_TYPE_RGB24_888,
97 .depth = 24, 113 .depth = 24,
98 }, 114 },
99 [VPDMA_DATA_FMT_ARGB32] = { 115 [VPDMA_DATA_FMT_ARGB32] = {
116 .type = VPDMA_DATA_FMT_TYPE_RGB,
100 .data_type = DATA_TYPE_ARGB32_8888, 117 .data_type = DATA_TYPE_ARGB32_8888,
101 .depth = 32, 118 .depth = 32,
102 }, 119 },
103 [VPDMA_DATA_FMT_RGBA24] = { 120 [VPDMA_DATA_FMT_RGBA24] = {
121 .type = VPDMA_DATA_FMT_TYPE_RGB,
104 .data_type = DATA_TYPE_RGBA24_6666, 122 .data_type = DATA_TYPE_RGBA24_6666,
105 .depth = 24, 123 .depth = 24,
106 }, 124 },
107 [VPDMA_DATA_FMT_RGBA32] = { 125 [VPDMA_DATA_FMT_RGBA32] = {
126 .type = VPDMA_DATA_FMT_TYPE_RGB,
108 .data_type = DATA_TYPE_RGBA32_8888, 127 .data_type = DATA_TYPE_RGBA32_8888,
109 .depth = 32, 128 .depth = 32,
110 }, 129 },
111 [VPDMA_DATA_FMT_BGR565] = { 130 [VPDMA_DATA_FMT_BGR565] = {
131 .type = VPDMA_DATA_FMT_TYPE_RGB,
112 .data_type = DATA_TYPE_BGR16_565, 132 .data_type = DATA_TYPE_BGR16_565,
113 .depth = 16, 133 .depth = 16,
114 }, 134 },
115 [VPDMA_DATA_FMT_ABGR16_1555] = { 135 [VPDMA_DATA_FMT_ABGR16_1555] = {
136 .type = VPDMA_DATA_FMT_TYPE_RGB,
116 .data_type = DATA_TYPE_ABGR_1555, 137 .data_type = DATA_TYPE_ABGR_1555,
117 .depth = 16, 138 .depth = 16,
118 }, 139 },
119 [VPDMA_DATA_FMT_ABGR16] = { 140 [VPDMA_DATA_FMT_ABGR16] = {
141 .type = VPDMA_DATA_FMT_TYPE_RGB,
120 .data_type = DATA_TYPE_ABGR_4444, 142 .data_type = DATA_TYPE_ABGR_4444,
121 .depth = 16, 143 .depth = 16,
122 }, 144 },
123 [VPDMA_DATA_FMT_BGRA16_5551] = { 145 [VPDMA_DATA_FMT_BGRA16_5551] = {
146 .type = VPDMA_DATA_FMT_TYPE_RGB,
124 .data_type = DATA_TYPE_BGRA_5551, 147 .data_type = DATA_TYPE_BGRA_5551,
125 .depth = 16, 148 .depth = 16,
126 }, 149 },
127 [VPDMA_DATA_FMT_BGRA16] = { 150 [VPDMA_DATA_FMT_BGRA16] = {
151 .type = VPDMA_DATA_FMT_TYPE_RGB,
128 .data_type = DATA_TYPE_BGRA_4444, 152 .data_type = DATA_TYPE_BGRA_4444,
129 .depth = 16, 153 .depth = 16,
130 }, 154 },
131 [VPDMA_DATA_FMT_ABGR24] = { 155 [VPDMA_DATA_FMT_ABGR24] = {
156 .type = VPDMA_DATA_FMT_TYPE_RGB,
132 .data_type = DATA_TYPE_ABGR24_6666, 157 .data_type = DATA_TYPE_ABGR24_6666,
133 .depth = 24, 158 .depth = 24,
134 }, 159 },
135 [VPDMA_DATA_FMT_BGR24] = { 160 [VPDMA_DATA_FMT_BGR24] = {
161 .type = VPDMA_DATA_FMT_TYPE_RGB,
136 .data_type = DATA_TYPE_BGR24_888, 162 .data_type = DATA_TYPE_BGR24_888,
137 .depth = 24, 163 .depth = 24,
138 }, 164 },
139 [VPDMA_DATA_FMT_ABGR32] = { 165 [VPDMA_DATA_FMT_ABGR32] = {
166 .type = VPDMA_DATA_FMT_TYPE_RGB,
140 .data_type = DATA_TYPE_ABGR32_8888, 167 .data_type = DATA_TYPE_ABGR32_8888,
141 .depth = 32, 168 .depth = 32,
142 }, 169 },
143 [VPDMA_DATA_FMT_BGRA24] = { 170 [VPDMA_DATA_FMT_BGRA24] = {
171 .type = VPDMA_DATA_FMT_TYPE_RGB,
144 .data_type = DATA_TYPE_BGRA24_6666, 172 .data_type = DATA_TYPE_BGRA24_6666,
145 .depth = 24, 173 .depth = 24,
146 }, 174 },
147 [VPDMA_DATA_FMT_BGRA32] = { 175 [VPDMA_DATA_FMT_BGRA32] = {
176 .type = VPDMA_DATA_FMT_TYPE_RGB,
148 .data_type = DATA_TYPE_BGRA32_8888, 177 .data_type = DATA_TYPE_BGRA32_8888,
149 .depth = 32, 178 .depth = 32,
150 }, 179 },
@@ -152,6 +181,7 @@ const struct vpdma_data_format vpdma_rgb_fmts[] = {
152 181
153const struct vpdma_data_format vpdma_misc_fmts[] = { 182const struct vpdma_data_format vpdma_misc_fmts[] = {
154 [VPDMA_DATA_FMT_MV] = { 183 [VPDMA_DATA_FMT_MV] = {
184 .type = VPDMA_DATA_FMT_TYPE_MISC,
155 .data_type = DATA_TYPE_MV, 185 .data_type = DATA_TYPE_MV,
156 .depth = 4, 186 .depth = 4,
157 }, 187 },
@@ -599,10 +629,11 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
599 629
600 channel = next_chan = chan_info[chan].num; 630 channel = next_chan = chan_info[chan].num;
601 631
602 if (fmt->data_type == DATA_TYPE_C420) 632 if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
633 fmt->data_type == DATA_TYPE_C420)
603 depth = 8; 634 depth = 8;
604 635
605 stride = (depth * c_rect->width) >> 3; 636 stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN);
606 dma_addr += (c_rect->left * depth) >> 3; 637 dma_addr += (c_rect->left * depth) >> 3;
607 638
608 dtd = list->next; 639 dtd = list->next;
@@ -649,13 +680,14 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
649 680
650 channel = next_chan = chan_info[chan].num; 681 channel = next_chan = chan_info[chan].num;
651 682
652 if (fmt->data_type == DATA_TYPE_C420) { 683 if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
684 fmt->data_type == DATA_TYPE_C420) {
653 height >>= 1; 685 height >>= 1;
654 frame_height >>= 1; 686 frame_height >>= 1;
655 depth = 8; 687 depth = 8;
656 } 688 }
657 689
658 stride = (depth * c_rect->width) >> 3; 690 stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN);
659 dma_addr += (c_rect->left * depth) >> 3; 691 dma_addr += (c_rect->left * depth) >> 3;
660 692
661 dtd = list->next; 693 dtd = list->next;
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index eaa2a71a5db9..cf40f11b3c8f 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -39,13 +39,23 @@ struct vpdma_data {
39 bool ready; 39 bool ready;
40}; 40};
41 41
42enum vpdma_data_format_type {
43 VPDMA_DATA_FMT_TYPE_YUV,
44 VPDMA_DATA_FMT_TYPE_RGB,
45 VPDMA_DATA_FMT_TYPE_MISC,
46};
47
42struct vpdma_data_format { 48struct vpdma_data_format {
49 enum vpdma_data_format_type type;
43 int data_type; 50 int data_type;
44 u8 depth; 51 u8 depth;
45}; 52};
46 53
47#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */ 54#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */
48 55#define VPDMA_STRIDE_ALIGN 16 /*
56 * line stride of source and dest
57 * buffers should be 16 byte aligned
58 */
49#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */ 59#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */
50#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */ 60#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */
51 61
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
index f0e9a8038c1b..c1a6ce1884f3 100644
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ b/drivers/media/platform/ti-vpe/vpdma_priv.h
@@ -78,7 +78,7 @@
78#define DATA_TYPE_C420 0x6 78#define DATA_TYPE_C420 0x6
79#define DATA_TYPE_YC422 0x7 79#define DATA_TYPE_YC422 0x7
80#define DATA_TYPE_YC444 0x8 80#define DATA_TYPE_YC444 0x8
81#define DATA_TYPE_CY422 0x23 81#define DATA_TYPE_CY422 0x27
82 82
83#define DATA_TYPE_RGB16_565 0x0 83#define DATA_TYPE_RGB16_565 0x0
84#define DATA_TYPE_ARGB_1555 0x1 84#define DATA_TYPE_ARGB_1555 0x1
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 4e58069e24ff..1296c5386231 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -30,6 +30,7 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/videodev2.h> 32#include <linux/videodev2.h>
33#include <linux/log2.h>
33 34
34#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
35#include <media/v4l2-ctrls.h> 36#include <media/v4l2-ctrls.h>
@@ -42,6 +43,8 @@
42 43
43#include "vpdma.h" 44#include "vpdma.h"
44#include "vpe_regs.h" 45#include "vpe_regs.h"
46#include "sc.h"
47#include "csc.h"
45 48
46#define VPE_MODULE_NAME "vpe" 49#define VPE_MODULE_NAME "vpe"
47 50
@@ -54,10 +57,6 @@
54/* required alignments */ 57/* required alignments */
55#define S_ALIGN 0 /* multiple of 1 */ 58#define S_ALIGN 0 /* multiple of 1 */
56#define H_ALIGN 1 /* multiple of 2 */ 59#define H_ALIGN 1 /* multiple of 2 */
57#define W_ALIGN 1 /* multiple of 2 */
58
59/* multiple of 128 bits, line stride, 16 bytes */
60#define L_ALIGN 4
61 60
62/* flags that indicate a format can be used for capture/output */ 61/* flags that indicate a format can be used for capture/output */
63#define VPE_FMT_TYPE_CAPTURE (1 << 0) 62#define VPE_FMT_TYPE_CAPTURE (1 << 0)
@@ -268,6 +267,38 @@ static struct vpe_fmt vpe_formats[] = {
268 .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422], 267 .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CY422],
269 }, 268 },
270 }, 269 },
270 {
271 .name = "RGB888 packed",
272 .fourcc = V4L2_PIX_FMT_RGB24,
273 .types = VPE_FMT_TYPE_CAPTURE,
274 .coplanar = 0,
275 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB24],
276 },
277 },
278 {
279 .name = "ARGB32",
280 .fourcc = V4L2_PIX_FMT_RGB32,
281 .types = VPE_FMT_TYPE_CAPTURE,
282 .coplanar = 0,
283 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ARGB32],
284 },
285 },
286 {
287 .name = "BGR888 packed",
288 .fourcc = V4L2_PIX_FMT_BGR24,
289 .types = VPE_FMT_TYPE_CAPTURE,
290 .coplanar = 0,
291 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_BGR24],
292 },
293 },
294 {
295 .name = "ABGR32",
296 .fourcc = V4L2_PIX_FMT_BGR32,
297 .types = VPE_FMT_TYPE_CAPTURE,
298 .coplanar = 0,
299 .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32],
300 },
301 },
271}; 302};
272 303
273/* 304/*
@@ -327,9 +358,12 @@ struct vpe_dev {
327 358
328 int irq; 359 int irq;
329 void __iomem *base; 360 void __iomem *base;
361 struct resource *res;
330 362
331 struct vb2_alloc_ctx *alloc_ctx; 363 struct vb2_alloc_ctx *alloc_ctx;
332 struct vpdma_data *vpdma; /* vpdma data handle */ 364 struct vpdma_data *vpdma; /* vpdma data handle */
365 struct sc_data *sc; /* scaler data handle */
366 struct csc_data *csc; /* csc data handle */
333}; 367};
334 368
335/* 369/*
@@ -356,6 +390,8 @@ struct vpe_ctx {
356 void *mv_buf[2]; /* virtual addrs of motion vector bufs */ 390 void *mv_buf[2]; /* virtual addrs of motion vector bufs */
357 size_t mv_buf_size; /* current motion vector buffer size */ 391 size_t mv_buf_size; /* current motion vector buffer size */
358 struct vpdma_buf mmr_adb; /* shadow reg addr/data block */ 392 struct vpdma_buf mmr_adb; /* shadow reg addr/data block */
393 struct vpdma_buf sc_coeff_h; /* h coeff buffer */
394 struct vpdma_buf sc_coeff_v; /* v coeff buffer */
359 struct vpdma_desc_list desc_list; /* DMA descriptor list */ 395 struct vpdma_desc_list desc_list; /* DMA descriptor list */
360 396
361 bool deinterlacing; /* using de-interlacer */ 397 bool deinterlacing; /* using de-interlacer */
@@ -438,14 +474,23 @@ struct vpe_mmr_adb {
438 u32 us3_regs[8]; 474 u32 us3_regs[8];
439 struct vpdma_adb_hdr dei_hdr; 475 struct vpdma_adb_hdr dei_hdr;
440 u32 dei_regs[8]; 476 u32 dei_regs[8];
441 struct vpdma_adb_hdr sc_hdr; 477 struct vpdma_adb_hdr sc_hdr0;
442 u32 sc_regs[1]; 478 u32 sc_regs0[7];
443 u32 sc_pad[3]; 479 u32 sc_pad0[1];
480 struct vpdma_adb_hdr sc_hdr8;
481 u32 sc_regs8[6];
482 u32 sc_pad8[2];
483 struct vpdma_adb_hdr sc_hdr17;
484 u32 sc_regs17[9];
485 u32 sc_pad17[3];
444 struct vpdma_adb_hdr csc_hdr; 486 struct vpdma_adb_hdr csc_hdr;
445 u32 csc_regs[6]; 487 u32 csc_regs[6];
446 u32 csc_pad[2]; 488 u32 csc_pad[2];
447}; 489};
448 490
491#define GET_OFFSET_TOP(ctx, obj, reg) \
492 ((obj)->res->start - ctx->dev->res->start + reg)
493
449#define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a) \ 494#define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a) \
450 VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a) 495 VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a)
451/* 496/*
@@ -458,8 +503,14 @@ static void init_adb_hdrs(struct vpe_ctx *ctx)
458 VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0); 503 VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0);
459 VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0); 504 VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0);
460 VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE); 505 VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE);
461 VPE_SET_MMR_ADB_HDR(ctx, sc_hdr, sc_regs, VPE_SC_MP_SC0); 506 VPE_SET_MMR_ADB_HDR(ctx, sc_hdr0, sc_regs0,
462 VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs, VPE_CSC_CSC00); 507 GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC0));
508 VPE_SET_MMR_ADB_HDR(ctx, sc_hdr8, sc_regs8,
509 GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC8));
510 VPE_SET_MMR_ADB_HDR(ctx, sc_hdr17, sc_regs17,
511 GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC17));
512 VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs,
513 GET_OFFSET_TOP(ctx, ctx->dev->csc, CSC_CSC00));
463}; 514};
464 515
465/* 516/*
@@ -670,17 +721,20 @@ static void set_src_registers(struct vpe_ctx *ctx)
670static void set_dst_registers(struct vpe_ctx *ctx) 721static void set_dst_registers(struct vpe_ctx *ctx)
671{ 722{
672 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; 723 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
724 enum v4l2_colorspace clrspc = ctx->q_data[Q_DATA_DST].colorspace;
673 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt; 725 struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt;
674 u32 val = 0; 726 u32 val = 0;
675 727
676 /* select RGB path when color space conversion is supported in future */ 728 if (clrspc == V4L2_COLORSPACE_SRGB)
677 if (fmt->fourcc == V4L2_PIX_FMT_RGB24) 729 val |= VPE_RGB_OUT_SELECT;
678 val |= VPE_RGB_OUT_SELECT | VPE_CSC_SRC_DEI_SCALER;
679 else if (fmt->fourcc == V4L2_PIX_FMT_NV16) 730 else if (fmt->fourcc == V4L2_PIX_FMT_NV16)
680 val |= VPE_COLOR_SEPARATE_422; 731 val |= VPE_COLOR_SEPARATE_422;
681 732
682 /* The source of CHR_DS is always the scaler, whether it's used or not */ 733 /*
683 val |= VPE_DS_SRC_DEI_SCALER; 734 * the source of CHR_DS and CSC is always the scaler, irrespective of
735 * whether it's used or not
736 */
737 val |= VPE_DS_SRC_DEI_SCALER | VPE_CSC_SRC_DEI_SCALER;
684 738
685 if (fmt->fourcc != V4L2_PIX_FMT_NV12) 739 if (fmt->fourcc != V4L2_PIX_FMT_NV12)
686 val |= VPE_DS_BYPASS; 740 val |= VPE_DS_BYPASS;
@@ -742,28 +796,6 @@ static void set_dei_shadow_registers(struct vpe_ctx *ctx)
742 ctx->load_mmrs = true; 796 ctx->load_mmrs = true;
743} 797}
744 798
745static void set_csc_coeff_bypass(struct vpe_ctx *ctx)
746{
747 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
748 u32 *shadow_csc_reg5 = &mmr_adb->csc_regs[5];
749
750 *shadow_csc_reg5 |= VPE_CSC_BYPASS;
751
752 ctx->load_mmrs = true;
753}
754
755static void set_sc_regs_bypass(struct vpe_ctx *ctx)
756{
757 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
758 u32 *sc_reg0 = &mmr_adb->sc_regs[0];
759 u32 val = 0;
760
761 val |= VPE_SC_BYPASS;
762 *sc_reg0 = val;
763
764 ctx->load_mmrs = true;
765}
766
767/* 799/*
768 * Set the shadow registers whose values are modified when either the 800 * Set the shadow registers whose values are modified when either the
769 * source or destination format is changed. 801 * source or destination format is changed.
@@ -772,6 +804,11 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
772{ 804{
773 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC]; 805 struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
774 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; 806 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
807 struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
808 unsigned int src_w = s_q_data->c_rect.width;
809 unsigned int src_h = s_q_data->c_rect.height;
810 unsigned int dst_w = d_q_data->c_rect.width;
811 unsigned int dst_h = d_q_data->c_rect.height;
775 size_t mv_buf_size; 812 size_t mv_buf_size;
776 int ret; 813 int ret;
777 814
@@ -780,12 +817,23 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
780 817
781 if ((s_q_data->flags & Q_DATA_INTERLACED) && 818 if ((s_q_data->flags & Q_DATA_INTERLACED) &&
782 !(d_q_data->flags & Q_DATA_INTERLACED)) { 819 !(d_q_data->flags & Q_DATA_INTERLACED)) {
820 int bytes_per_line;
783 const struct vpdma_data_format *mv = 821 const struct vpdma_data_format *mv =
784 &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; 822 &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
785 823
824 /*
825 * we make sure that the source image has a 16 byte aligned
826 * stride, we need to do the same for the motion vector buffer
827 * by aligning it's stride to the next 16 byte boundry. this
828 * extra space will not be used by the de-interlacer, but will
829 * ensure that vpdma operates correctly
830 */
831 bytes_per_line = ALIGN((s_q_data->width * mv->depth) >> 3,
832 VPDMA_STRIDE_ALIGN);
833 mv_buf_size = bytes_per_line * s_q_data->height;
834
786 ctx->deinterlacing = 1; 835 ctx->deinterlacing = 1;
787 mv_buf_size = 836 src_h <<= 1;
788 (s_q_data->width * s_q_data->height * mv->depth) >> 3;
789 } else { 837 } else {
790 ctx->deinterlacing = 0; 838 ctx->deinterlacing = 0;
791 mv_buf_size = 0; 839 mv_buf_size = 0;
@@ -799,8 +847,16 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
799 847
800 set_cfg_and_line_modes(ctx); 848 set_cfg_and_line_modes(ctx);
801 set_dei_regs(ctx); 849 set_dei_regs(ctx);
802 set_csc_coeff_bypass(ctx); 850
803 set_sc_regs_bypass(ctx); 851 csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0],
852 s_q_data->colorspace, d_q_data->colorspace);
853
854 sc_set_hs_coeffs(ctx->dev->sc, ctx->sc_coeff_h.addr, src_w, dst_w);
855 sc_set_vs_coeffs(ctx->dev->sc, ctx->sc_coeff_v.addr, src_h, dst_h);
856
857 sc_config_scaler(ctx->dev->sc, &mmr_adb->sc_regs0[0],
858 &mmr_adb->sc_regs8[0], &mmr_adb->sc_regs17[0],
859 src_w, src_h, dst_w, dst_h);
804 860
805 return 0; 861 return 0;
806} 862}
@@ -916,35 +972,10 @@ static void vpe_dump_regs(struct vpe_dev *dev)
916 DUMPREG(DEI_FMD_STATUS_R0); 972 DUMPREG(DEI_FMD_STATUS_R0);
917 DUMPREG(DEI_FMD_STATUS_R1); 973 DUMPREG(DEI_FMD_STATUS_R1);
918 DUMPREG(DEI_FMD_STATUS_R2); 974 DUMPREG(DEI_FMD_STATUS_R2);
919 DUMPREG(SC_MP_SC0);
920 DUMPREG(SC_MP_SC1);
921 DUMPREG(SC_MP_SC2);
922 DUMPREG(SC_MP_SC3);
923 DUMPREG(SC_MP_SC4);
924 DUMPREG(SC_MP_SC5);
925 DUMPREG(SC_MP_SC6);
926 DUMPREG(SC_MP_SC8);
927 DUMPREG(SC_MP_SC9);
928 DUMPREG(SC_MP_SC10);
929 DUMPREG(SC_MP_SC11);
930 DUMPREG(SC_MP_SC12);
931 DUMPREG(SC_MP_SC13);
932 DUMPREG(SC_MP_SC17);
933 DUMPREG(SC_MP_SC18);
934 DUMPREG(SC_MP_SC19);
935 DUMPREG(SC_MP_SC20);
936 DUMPREG(SC_MP_SC21);
937 DUMPREG(SC_MP_SC22);
938 DUMPREG(SC_MP_SC23);
939 DUMPREG(SC_MP_SC24);
940 DUMPREG(SC_MP_SC25);
941 DUMPREG(CSC_CSC00);
942 DUMPREG(CSC_CSC01);
943 DUMPREG(CSC_CSC02);
944 DUMPREG(CSC_CSC03);
945 DUMPREG(CSC_CSC04);
946 DUMPREG(CSC_CSC05);
947#undef DUMPREG 975#undef DUMPREG
976
977 sc_dump_regs(dev->sc);
978 csc_dump_regs(dev->csc);
948} 979}
949 980
950static void add_out_dtd(struct vpe_ctx *ctx, int port) 981static void add_out_dtd(struct vpe_ctx *ctx, int port)
@@ -1053,6 +1084,7 @@ static void disable_irqs(struct vpe_ctx *ctx)
1053static void device_run(void *priv) 1084static void device_run(void *priv)
1054{ 1085{
1055 struct vpe_ctx *ctx = priv; 1086 struct vpe_ctx *ctx = priv;
1087 struct sc_data *sc = ctx->dev->sc;
1056 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST]; 1088 struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
1057 1089
1058 if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) { 1090 if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) {
@@ -1075,13 +1107,37 @@ static void device_run(void *priv)
1075 ctx->load_mmrs = false; 1107 ctx->load_mmrs = false;
1076 } 1108 }
1077 1109
1110 if (sc->loaded_coeff_h != ctx->sc_coeff_h.dma_addr ||
1111 sc->load_coeff_h) {
1112 vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_h);
1113 vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT,
1114 &ctx->sc_coeff_h, 0);
1115
1116 sc->loaded_coeff_h = ctx->sc_coeff_h.dma_addr;
1117 sc->load_coeff_h = false;
1118 }
1119
1120 if (sc->loaded_coeff_v != ctx->sc_coeff_v.dma_addr ||
1121 sc->load_coeff_v) {
1122 vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_v);
1123 vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT,
1124 &ctx->sc_coeff_v, SC_COEF_SRAM_SIZE >> 4);
1125
1126 sc->loaded_coeff_v = ctx->sc_coeff_v.dma_addr;
1127 sc->load_coeff_v = false;
1128 }
1129
1078 /* output data descriptors */ 1130 /* output data descriptors */
1079 if (ctx->deinterlacing) 1131 if (ctx->deinterlacing)
1080 add_out_dtd(ctx, VPE_PORT_MV_OUT); 1132 add_out_dtd(ctx, VPE_PORT_MV_OUT);
1081 1133
1082 add_out_dtd(ctx, VPE_PORT_LUMA_OUT); 1134 if (d_q_data->colorspace == V4L2_COLORSPACE_SRGB) {
1083 if (d_q_data->fmt->coplanar) 1135 add_out_dtd(ctx, VPE_PORT_RGB_OUT);
1084 add_out_dtd(ctx, VPE_PORT_CHROMA_OUT); 1136 } else {
1137 add_out_dtd(ctx, VPE_PORT_LUMA_OUT);
1138 if (d_q_data->fmt->coplanar)
1139 add_out_dtd(ctx, VPE_PORT_CHROMA_OUT);
1140 }
1085 1141
1086 /* input data descriptors */ 1142 /* input data descriptors */
1087 if (ctx->deinterlacing) { 1143 if (ctx->deinterlacing) {
@@ -1117,9 +1173,16 @@ static void device_run(void *priv)
1117 } 1173 }
1118 1174
1119 /* sync on channel control descriptors for output ports */ 1175 /* sync on channel control descriptors for output ports */
1120 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA_OUT); 1176 if (d_q_data->colorspace == V4L2_COLORSPACE_SRGB) {
1121 if (d_q_data->fmt->coplanar) 1177 vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1122 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA_OUT); 1178 VPE_CHAN_RGB_OUT);
1179 } else {
1180 vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1181 VPE_CHAN_LUMA_OUT);
1182 if (d_q_data->fmt->coplanar)
1183 vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1184 VPE_CHAN_CHROMA_OUT);
1185 }
1123 1186
1124 if (ctx->deinterlacing) 1187 if (ctx->deinterlacing)
1125 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT); 1188 vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT);
@@ -1198,6 +1261,8 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
1198 1261
1199 vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); 1262 vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
1200 vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb); 1263 vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb);
1264 vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h);
1265 vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v);
1201 1266
1202 vpdma_reset_desc_list(&ctx->desc_list); 1267 vpdma_reset_desc_list(&ctx->desc_list);
1203 1268
@@ -1352,7 +1417,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1352{ 1417{
1353 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; 1418 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1354 struct v4l2_plane_pix_format *plane_fmt; 1419 struct v4l2_plane_pix_format *plane_fmt;
1355 int i; 1420 unsigned int w_align;
1421 int i, depth, depth_bytes;
1356 1422
1357 if (!fmt || !(fmt->types & type)) { 1423 if (!fmt || !(fmt->types & type)) {
1358 vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", 1424 vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
@@ -1363,35 +1429,57 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1363 if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE) 1429 if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE)
1364 pix->field = V4L2_FIELD_NONE; 1430 pix->field = V4L2_FIELD_NONE;
1365 1431
1366 v4l_bound_align_image(&pix->width, MIN_W, MAX_W, W_ALIGN, 1432 depth = fmt->vpdma_fmt[VPE_LUMA]->depth;
1433
1434 /*
1435 * the line stride should 16 byte aligned for VPDMA to work, based on
1436 * the bytes per pixel, figure out how much the width should be aligned
1437 * to make sure line stride is 16 byte aligned
1438 */
1439 depth_bytes = depth >> 3;
1440
1441 if (depth_bytes == 3)
1442 /*
1443 * if bpp is 3(as in some RGB formats), the pixel width doesn't
1444 * really help in ensuring line stride is 16 byte aligned
1445 */
1446 w_align = 4;
1447 else
1448 /*
1449 * for the remainder bpp(4, 2 and 1), the pixel width alignment
1450 * can ensure a line stride alignment of 16 bytes. For example,
1451 * if bpp is 2, then the line stride can be 16 byte aligned if
1452 * the width is 8 byte aligned
1453 */
1454 w_align = order_base_2(VPDMA_DESC_ALIGN / depth_bytes);
1455
1456 v4l_bound_align_image(&pix->width, MIN_W, MAX_W, w_align,
1367 &pix->height, MIN_H, MAX_H, H_ALIGN, 1457 &pix->height, MIN_H, MAX_H, H_ALIGN,
1368 S_ALIGN); 1458 S_ALIGN);
1369 1459
1370 pix->num_planes = fmt->coplanar ? 2 : 1; 1460 pix->num_planes = fmt->coplanar ? 2 : 1;
1371 pix->pixelformat = fmt->fourcc; 1461 pix->pixelformat = fmt->fourcc;
1372 1462
1373 if (type == VPE_FMT_TYPE_CAPTURE) { 1463 if (!pix->colorspace) {
1374 struct vpe_q_data *s_q_data; 1464 if (fmt->fourcc == V4L2_PIX_FMT_RGB24 ||
1375 1465 fmt->fourcc == V4L2_PIX_FMT_BGR24 ||
1376 /* get colorspace from the source queue */ 1466 fmt->fourcc == V4L2_PIX_FMT_RGB32 ||
1377 s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 1467 fmt->fourcc == V4L2_PIX_FMT_BGR32) {
1378 1468 pix->colorspace = V4L2_COLORSPACE_SRGB;
1379 pix->colorspace = s_q_data->colorspace; 1469 } else {
1380 } else { 1470 if (pix->height > 1280) /* HD */
1381 if (!pix->colorspace) 1471 pix->colorspace = V4L2_COLORSPACE_REC709;
1382 pix->colorspace = V4L2_COLORSPACE_SMPTE240M; 1472 else /* SD */
1473 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1474 }
1383 } 1475 }
1384 1476
1385 for (i = 0; i < pix->num_planes; i++) { 1477 for (i = 0; i < pix->num_planes; i++) {
1386 int depth;
1387
1388 plane_fmt = &pix->plane_fmt[i]; 1478 plane_fmt = &pix->plane_fmt[i];
1389 depth = fmt->vpdma_fmt[i]->depth; 1479 depth = fmt->vpdma_fmt[i]->depth;
1390 1480
1391 if (i == VPE_LUMA) 1481 if (i == VPE_LUMA)
1392 plane_fmt->bytesperline = 1482 plane_fmt->bytesperline = (pix->width * depth) >> 3;
1393 round_up((pix->width * depth) >> 3,
1394 1 << L_ALIGN);
1395 else 1483 else
1396 plane_fmt->bytesperline = pix->width; 1484 plane_fmt->bytesperline = pix->width;
1397 1485
@@ -1749,6 +1837,14 @@ static int vpe_open(struct file *file)
1749 if (ret != 0) 1837 if (ret != 0)
1750 goto free_desc_list; 1838 goto free_desc_list;
1751 1839
1840 ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_h, SC_COEF_SRAM_SIZE);
1841 if (ret != 0)
1842 goto free_mmr_adb;
1843
1844 ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_v, SC_COEF_SRAM_SIZE);
1845 if (ret != 0)
1846 goto free_sc_h;
1847
1752 init_adb_hdrs(ctx); 1848 init_adb_hdrs(ctx);
1753 1849
1754 v4l2_fh_init(&ctx->fh, video_devdata(file)); 1850 v4l2_fh_init(&ctx->fh, video_devdata(file));
@@ -1770,7 +1866,7 @@ static int vpe_open(struct file *file)
1770 s_q_data->height = 1080; 1866 s_q_data->height = 1080;
1771 s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height * 1867 s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height *
1772 s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3; 1868 s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
1773 s_q_data->colorspace = V4L2_COLORSPACE_SMPTE240M; 1869 s_q_data->colorspace = V4L2_COLORSPACE_SMPTE170M;
1774 s_q_data->field = V4L2_FIELD_NONE; 1870 s_q_data->field = V4L2_FIELD_NONE;
1775 s_q_data->c_rect.left = 0; 1871 s_q_data->c_rect.left = 0;
1776 s_q_data->c_rect.top = 0; 1872 s_q_data->c_rect.top = 0;
@@ -1817,6 +1913,10 @@ static int vpe_open(struct file *file)
1817exit_fh: 1913exit_fh:
1818 v4l2_ctrl_handler_free(hdl); 1914 v4l2_ctrl_handler_free(hdl);
1819 v4l2_fh_exit(&ctx->fh); 1915 v4l2_fh_exit(&ctx->fh);
1916 vpdma_free_desc_buf(&ctx->sc_coeff_v);
1917free_sc_h:
1918 vpdma_free_desc_buf(&ctx->sc_coeff_h);
1919free_mmr_adb:
1820 vpdma_free_desc_buf(&ctx->mmr_adb); 1920 vpdma_free_desc_buf(&ctx->mmr_adb);
1821free_desc_list: 1921free_desc_list:
1822 vpdma_free_desc_list(&ctx->desc_list); 1922 vpdma_free_desc_list(&ctx->desc_list);
@@ -1938,12 +2038,11 @@ static int vpe_probe(struct platform_device *pdev)
1938{ 2038{
1939 struct vpe_dev *dev; 2039 struct vpe_dev *dev;
1940 struct video_device *vfd; 2040 struct video_device *vfd;
1941 struct resource *res;
1942 int ret, irq, func; 2041 int ret, irq, func;
1943 2042
1944 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 2043 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
1945 if (IS_ERR(dev)) 2044 if (!dev)
1946 return PTR_ERR(dev); 2045 return -ENOMEM;
1947 2046
1948 spin_lock_init(&dev->lock); 2047 spin_lock_init(&dev->lock);
1949 2048
@@ -1954,16 +2053,17 @@ static int vpe_probe(struct platform_device *pdev)
1954 atomic_set(&dev->num_instances, 0); 2053 atomic_set(&dev->num_instances, 0);
1955 mutex_init(&dev->dev_mutex); 2054 mutex_init(&dev->dev_mutex);
1956 2055
1957 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpe_top"); 2056 dev->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2057 "vpe_top");
1958 /* 2058 /*
1959 * HACK: we get resource info from device tree in the form of a list of 2059 * HACK: we get resource info from device tree in the form of a list of
1960 * VPE sub blocks, the driver currently uses only the base of vpe_top 2060 * VPE sub blocks, the driver currently uses only the base of vpe_top
1961 * for register access, the driver should be changed later to access 2061 * for register access, the driver should be changed later to access
1962 * registers based on the sub block base addresses 2062 * registers based on the sub block base addresses
1963 */ 2063 */
1964 dev->base = devm_ioremap(&pdev->dev, res->start, SZ_32K); 2064 dev->base = devm_ioremap(&pdev->dev, dev->res->start, SZ_32K);
1965 if (IS_ERR(dev->base)) { 2065 if (!dev->base) {
1966 ret = PTR_ERR(dev->base); 2066 ret = -ENOMEM;
1967 goto v4l2_dev_unreg; 2067 goto v4l2_dev_unreg;
1968 } 2068 }
1969 2069
@@ -2006,9 +2106,23 @@ static int vpe_probe(struct platform_device *pdev)
2006 2106
2007 vpe_top_vpdma_reset(dev); 2107 vpe_top_vpdma_reset(dev);
2008 2108
2109 dev->sc = sc_create(pdev);
2110 if (IS_ERR(dev->sc)) {
2111 ret = PTR_ERR(dev->sc);
2112 goto runtime_put;
2113 }
2114
2115 dev->csc = csc_create(pdev);
2116 if (IS_ERR(dev->csc)) {
2117 ret = PTR_ERR(dev->csc);
2118 goto runtime_put;
2119 }
2120
2009 dev->vpdma = vpdma_create(pdev); 2121 dev->vpdma = vpdma_create(pdev);
2010 if (IS_ERR(dev->vpdma)) 2122 if (IS_ERR(dev->vpdma)) {
2123 ret = PTR_ERR(dev->vpdma);
2011 goto runtime_put; 2124 goto runtime_put;
2125 }
2012 2126
2013 vfd = &dev->vfd; 2127 vfd = &dev->vfd;
2014 *vfd = vpe_videodev; 2128 *vfd = vpe_videodev;
@@ -2081,18 +2195,7 @@ static struct platform_driver vpe_pdrv = {
2081 }, 2195 },
2082}; 2196};
2083 2197
2084static void __exit vpe_exit(void) 2198module_platform_driver(vpe_pdrv);
2085{
2086 platform_driver_unregister(&vpe_pdrv);
2087}
2088
2089static int __init vpe_init(void)
2090{
2091 return platform_driver_register(&vpe_pdrv);
2092}
2093
2094module_init(vpe_init);
2095module_exit(vpe_exit);
2096 2199
2097MODULE_DESCRIPTION("TI VPE driver"); 2200MODULE_DESCRIPTION("TI VPE driver");
2098MODULE_AUTHOR("Dale Farnsworth, <dale@farnsworth.org>"); 2201MODULE_AUTHOR("Dale Farnsworth, <dale@farnsworth.org>");
diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti-vpe/vpe_regs.h
index ed214e828398..74283d79eae1 100644
--- a/drivers/media/platform/ti-vpe/vpe_regs.h
+++ b/drivers/media/platform/ti-vpe/vpe_regs.h
@@ -306,191 +306,4 @@
306#define VPE_FMD_FRAME_DIFF_MASK 0x000fffff 306#define VPE_FMD_FRAME_DIFF_MASK 0x000fffff
307#define VPE_FMD_FRAME_DIFF_SHIFT 0 307#define VPE_FMD_FRAME_DIFF_SHIFT 0
308 308
309/* VPE scaler regs */
310#define VPE_SC_MP_SC0 0x0700
311#define VPE_INTERLACE_O (1 << 0)
312#define VPE_LINEAR (1 << 1)
313#define VPE_SC_BYPASS (1 << 2)
314#define VPE_INVT_FID (1 << 3)
315#define VPE_USE_RAV (1 << 4)
316#define VPE_ENABLE_EV (1 << 5)
317#define VPE_AUTO_HS (1 << 6)
318#define VPE_DCM_2X (1 << 7)
319#define VPE_DCM_4X (1 << 8)
320#define VPE_HP_BYPASS (1 << 9)
321#define VPE_INTERLACE_I (1 << 10)
322#define VPE_ENABLE_SIN2_VER_INTP (1 << 11)
323#define VPE_Y_PK_EN (1 << 14)
324#define VPE_TRIM (1 << 15)
325#define VPE_SELFGEN_FID (1 << 16)
326
327#define VPE_SC_MP_SC1 0x0704
328#define VPE_ROW_ACC_INC_MASK 0x07ffffff
329#define VPE_ROW_ACC_INC_SHIFT 0
330
331#define VPE_SC_MP_SC2 0x0708
332#define VPE_ROW_ACC_OFFSET_MASK 0x0fffffff
333#define VPE_ROW_ACC_OFFSET_SHIFT 0
334
335#define VPE_SC_MP_SC3 0x070c
336#define VPE_ROW_ACC_OFFSET_B_MASK 0x0fffffff
337#define VPE_ROW_ACC_OFFSET_B_SHIFT 0
338
339#define VPE_SC_MP_SC4 0x0710
340#define VPE_TAR_H_MASK 0x07ff
341#define VPE_TAR_H_SHIFT 0
342#define VPE_TAR_W_MASK 0x07ff
343#define VPE_TAR_W_SHIFT 12
344#define VPE_LIN_ACC_INC_U_MASK 0x07
345#define VPE_LIN_ACC_INC_U_SHIFT 24
346#define VPE_NLIN_ACC_INIT_U_MASK 0x07
347#define VPE_NLIN_ACC_INIT_U_SHIFT 28
348
349#define VPE_SC_MP_SC5 0x0714
350#define VPE_SRC_H_MASK 0x07ff
351#define VPE_SRC_H_SHIFT 0
352#define VPE_SRC_W_MASK 0x07ff
353#define VPE_SRC_W_SHIFT 12
354#define VPE_NLIN_ACC_INC_U_MASK 0x07
355#define VPE_NLIN_ACC_INC_U_SHIFT 24
356
357#define VPE_SC_MP_SC6 0x0718
358#define VPE_ROW_ACC_INIT_RAV_MASK 0x03ff
359#define VPE_ROW_ACC_INIT_RAV_SHIFT 0
360#define VPE_ROW_ACC_INIT_RAV_B_MASK 0x03ff
361#define VPE_ROW_ACC_INIT_RAV_B_SHIFT 10
362
363#define VPE_SC_MP_SC8 0x0720
364#define VPE_NLIN_LEFT_MASK 0x07ff
365#define VPE_NLIN_LEFT_SHIFT 0
366#define VPE_NLIN_RIGHT_MASK 0x07ff
367#define VPE_NLIN_RIGHT_SHIFT 12
368
369#define VPE_SC_MP_SC9 0x0724
370#define VPE_LIN_ACC_INC VPE_SC_MP_SC9
371
372#define VPE_SC_MP_SC10 0x0728
373#define VPE_NLIN_ACC_INIT VPE_SC_MP_SC10
374
375#define VPE_SC_MP_SC11 0x072c
376#define VPE_NLIN_ACC_INC VPE_SC_MP_SC11
377
378#define VPE_SC_MP_SC12 0x0730
379#define VPE_COL_ACC_OFFSET_MASK 0x01ffffff
380#define VPE_COL_ACC_OFFSET_SHIFT 0
381
382#define VPE_SC_MP_SC13 0x0734
383#define VPE_SC_FACTOR_RAV_MASK 0x03ff
384#define VPE_SC_FACTOR_RAV_SHIFT 0
385#define VPE_CHROMA_INTP_THR_MASK 0x03ff
386#define VPE_CHROMA_INTP_THR_SHIFT 12
387#define VPE_DELTA_CHROMA_THR_MASK 0x0f
388#define VPE_DELTA_CHROMA_THR_SHIFT 24
389
390#define VPE_SC_MP_SC17 0x0744
391#define VPE_EV_THR_MASK 0x03ff
392#define VPE_EV_THR_SHIFT 12
393#define VPE_DELTA_LUMA_THR_MASK 0x0f
394#define VPE_DELTA_LUMA_THR_SHIFT 24
395#define VPE_DELTA_EV_THR_MASK 0x0f
396#define VPE_DELTA_EV_THR_SHIFT 28
397
398#define VPE_SC_MP_SC18 0x0748
399#define VPE_HS_FACTOR_MASK 0x03ff
400#define VPE_HS_FACTOR_SHIFT 0
401#define VPE_CONF_DEFAULT_MASK 0x01ff
402#define VPE_CONF_DEFAULT_SHIFT 16
403
404#define VPE_SC_MP_SC19 0x074c
405#define VPE_HPF_COEFF0_MASK 0xff
406#define VPE_HPF_COEFF0_SHIFT 0
407#define VPE_HPF_COEFF1_MASK 0xff
408#define VPE_HPF_COEFF1_SHIFT 8
409#define VPE_HPF_COEFF2_MASK 0xff
410#define VPE_HPF_COEFF2_SHIFT 16
411#define VPE_HPF_COEFF3_MASK 0xff
412#define VPE_HPF_COEFF3_SHIFT 23
413
414#define VPE_SC_MP_SC20 0x0750
415#define VPE_HPF_COEFF4_MASK 0xff
416#define VPE_HPF_COEFF4_SHIFT 0
417#define VPE_HPF_COEFF5_MASK 0xff
418#define VPE_HPF_COEFF5_SHIFT 8
419#define VPE_HPF_NORM_SHIFT_MASK 0x07
420#define VPE_HPF_NORM_SHIFT_SHIFT 16
421#define VPE_NL_LIMIT_MASK 0x1ff
422#define VPE_NL_LIMIT_SHIFT 20
423
424#define VPE_SC_MP_SC21 0x0754
425#define VPE_NL_LO_THR_MASK 0x01ff
426#define VPE_NL_LO_THR_SHIFT 0
427#define VPE_NL_LO_SLOPE_MASK 0xff
428#define VPE_NL_LO_SLOPE_SHIFT 16
429
430#define VPE_SC_MP_SC22 0x0758
431#define VPE_NL_HI_THR_MASK 0x01ff
432#define VPE_NL_HI_THR_SHIFT 0
433#define VPE_NL_HI_SLOPE_SH_MASK 0x07
434#define VPE_NL_HI_SLOPE_SH_SHIFT 16
435
436#define VPE_SC_MP_SC23 0x075c
437#define VPE_GRADIENT_THR_MASK 0x07ff
438#define VPE_GRADIENT_THR_SHIFT 0
439#define VPE_GRADIENT_THR_RANGE_MASK 0x0f
440#define VPE_GRADIENT_THR_RANGE_SHIFT 12
441#define VPE_MIN_GY_THR_MASK 0xff
442#define VPE_MIN_GY_THR_SHIFT 16
443#define VPE_MIN_GY_THR_RANGE_MASK 0x0f
444#define VPE_MIN_GY_THR_RANGE_SHIFT 28
445
446#define VPE_SC_MP_SC24 0x0760
447#define VPE_ORG_H_MASK 0x07ff
448#define VPE_ORG_H_SHIFT 0
449#define VPE_ORG_W_MASK 0x07ff
450#define VPE_ORG_W_SHIFT 16
451
452#define VPE_SC_MP_SC25 0x0764
453#define VPE_OFF_H_MASK 0x07ff
454#define VPE_OFF_H_SHIFT 0
455#define VPE_OFF_W_MASK 0x07ff
456#define VPE_OFF_W_SHIFT 16
457
458/* VPE color space converter regs */
459#define VPE_CSC_CSC00 0x5700
460#define VPE_CSC_A0_MASK 0x1fff
461#define VPE_CSC_A0_SHIFT 0
462#define VPE_CSC_B0_MASK 0x1fff
463#define VPE_CSC_B0_SHIFT 16
464
465#define VPE_CSC_CSC01 0x5704
466#define VPE_CSC_C0_MASK 0x1fff
467#define VPE_CSC_C0_SHIFT 0
468#define VPE_CSC_A1_MASK 0x1fff
469#define VPE_CSC_A1_SHIFT 16
470
471#define VPE_CSC_CSC02 0x5708
472#define VPE_CSC_B1_MASK 0x1fff
473#define VPE_CSC_B1_SHIFT 0
474#define VPE_CSC_C1_MASK 0x1fff
475#define VPE_CSC_C1_SHIFT 16
476
477#define VPE_CSC_CSC03 0x570c
478#define VPE_CSC_A2_MASK 0x1fff
479#define VPE_CSC_A2_SHIFT 0
480#define VPE_CSC_B2_MASK 0x1fff
481#define VPE_CSC_B2_SHIFT 16
482
483#define VPE_CSC_CSC04 0x5710
484#define VPE_CSC_C2_MASK 0x1fff
485#define VPE_CSC_C2_SHIFT 0
486#define VPE_CSC_D0_MASK 0x0fff
487#define VPE_CSC_D0_SHIFT 16
488
489#define VPE_CSC_CSC05 0x5714
490#define VPE_CSC_D1_MASK 0x0fff
491#define VPE_CSC_D1_SHIFT 0
492#define VPE_CSC_D2_MASK 0x0fff
493#define VPE_CSC_D2_SHIFT 16
494#define VPE_CSC_BYPASS (1 << 28)
495
496#endif 309#endif
diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 4da226169e15..151cecd0ea25 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,5 +1,6 @@
1vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_video.o 1vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_video.o
2vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o 2vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
3vsp1-y += vsp1_lif.o vsp1_uds.o 3vsp1-y += vsp1_hsit.o vsp1_lif.o vsp1_lut.o
4vsp1-y += vsp1_sru.o vsp1_uds.o
4 5
5obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o 6obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index d6c6ecd039ff..94d1b02680c5 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -28,8 +28,11 @@ struct clk;
28struct device; 28struct device;
29 29
30struct vsp1_platform_data; 30struct vsp1_platform_data;
31struct vsp1_hsit;
31struct vsp1_lif; 32struct vsp1_lif;
33struct vsp1_lut;
32struct vsp1_rwpf; 34struct vsp1_rwpf;
35struct vsp1_sru;
33struct vsp1_uds; 36struct vsp1_uds;
34 37
35#define VPS1_MAX_RPF 5 38#define VPS1_MAX_RPF 5
@@ -47,8 +50,12 @@ struct vsp1_device {
47 struct mutex lock; 50 struct mutex lock;
48 int ref_count; 51 int ref_count;
49 52
53 struct vsp1_hsit *hsi;
54 struct vsp1_hsit *hst;
50 struct vsp1_lif *lif; 55 struct vsp1_lif *lif;
56 struct vsp1_lut *lut;
51 struct vsp1_rwpf *rpf[VPS1_MAX_RPF]; 57 struct vsp1_rwpf *rpf[VPS1_MAX_RPF];
58 struct vsp1_sru *sru;
52 struct vsp1_uds *uds[VPS1_MAX_UDS]; 59 struct vsp1_uds *uds[VPS1_MAX_UDS];
53 struct vsp1_rwpf *wpf[VPS1_MAX_WPF]; 60 struct vsp1_rwpf *wpf[VPS1_MAX_WPF];
54 61
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index d16bf0f41e24..0df0a994e575 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -20,8 +20,11 @@
20#include <linux/videodev2.h> 20#include <linux/videodev2.h>
21 21
22#include "vsp1.h" 22#include "vsp1.h"
23#include "vsp1_hsit.h"
23#include "vsp1_lif.h" 24#include "vsp1_lif.h"
25#include "vsp1_lut.h"
24#include "vsp1_rwpf.h" 26#include "vsp1_rwpf.h"
27#include "vsp1_sru.h"
25#include "vsp1_uds.h" 28#include "vsp1_uds.h"
26 29
27/* ----------------------------------------------------------------------------- 30/* -----------------------------------------------------------------------------
@@ -152,6 +155,22 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
152 } 155 }
153 156
154 /* Instantiate all the entities. */ 157 /* Instantiate all the entities. */
158 vsp1->hsi = vsp1_hsit_create(vsp1, true);
159 if (IS_ERR(vsp1->hsi)) {
160 ret = PTR_ERR(vsp1->hsi);
161 goto done;
162 }
163
164 list_add_tail(&vsp1->hsi->entity.list_dev, &vsp1->entities);
165
166 vsp1->hst = vsp1_hsit_create(vsp1, false);
167 if (IS_ERR(vsp1->hst)) {
168 ret = PTR_ERR(vsp1->hst);
169 goto done;
170 }
171
172 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities);
173
155 if (vsp1->pdata->features & VSP1_HAS_LIF) { 174 if (vsp1->pdata->features & VSP1_HAS_LIF) {
156 vsp1->lif = vsp1_lif_create(vsp1); 175 vsp1->lif = vsp1_lif_create(vsp1);
157 if (IS_ERR(vsp1->lif)) { 176 if (IS_ERR(vsp1->lif)) {
@@ -162,6 +181,16 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
162 list_add_tail(&vsp1->lif->entity.list_dev, &vsp1->entities); 181 list_add_tail(&vsp1->lif->entity.list_dev, &vsp1->entities);
163 } 182 }
164 183
184 if (vsp1->pdata->features & VSP1_HAS_LUT) {
185 vsp1->lut = vsp1_lut_create(vsp1);
186 if (IS_ERR(vsp1->lut)) {
187 ret = PTR_ERR(vsp1->lut);
188 goto done;
189 }
190
191 list_add_tail(&vsp1->lut->entity.list_dev, &vsp1->entities);
192 }
193
165 for (i = 0; i < vsp1->pdata->rpf_count; ++i) { 194 for (i = 0; i < vsp1->pdata->rpf_count; ++i) {
166 struct vsp1_rwpf *rpf; 195 struct vsp1_rwpf *rpf;
167 196
@@ -175,6 +204,16 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
175 list_add_tail(&rpf->entity.list_dev, &vsp1->entities); 204 list_add_tail(&rpf->entity.list_dev, &vsp1->entities);
176 } 205 }
177 206
207 if (vsp1->pdata->features & VSP1_HAS_SRU) {
208 vsp1->sru = vsp1_sru_create(vsp1);
209 if (IS_ERR(vsp1->sru)) {
210 ret = PTR_ERR(vsp1->sru);
211 goto done;
212 }
213
214 list_add_tail(&vsp1->sru->entity.list_dev, &vsp1->entities);
215 }
216
178 for (i = 0; i < vsp1->pdata->uds_count; ++i) { 217 for (i = 0; i < vsp1->pdata->uds_count; ++i) {
179 struct vsp1_uds *uds; 218 struct vsp1_uds *uds;
180 219
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 9028f9d524f4..0226e47df6d9 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -15,6 +15,7 @@
15#include <linux/gfp.h> 15#include <linux/gfp.h>
16 16
17#include <media/media-entity.h> 17#include <media/media-entity.h>
18#include <media/v4l2-ctrls.h>
18#include <media/v4l2-subdev.h> 19#include <media/v4l2-subdev.h>
19 20
20#include "vsp1.h" 21#include "vsp1.h"
@@ -122,12 +123,16 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
122 unsigned int id; 123 unsigned int id;
123 unsigned int reg; 124 unsigned int reg;
124 } routes[] = { 125 } routes[] = {
126 { VI6_DPR_NODE_HSI, VI6_DPR_HSI_ROUTE },
127 { VI6_DPR_NODE_HST, VI6_DPR_HST_ROUTE },
125 { VI6_DPR_NODE_LIF, 0 }, 128 { VI6_DPR_NODE_LIF, 0 },
129 { VI6_DPR_NODE_LUT, VI6_DPR_LUT_ROUTE },
126 { VI6_DPR_NODE_RPF(0), VI6_DPR_RPF_ROUTE(0) }, 130 { VI6_DPR_NODE_RPF(0), VI6_DPR_RPF_ROUTE(0) },
127 { VI6_DPR_NODE_RPF(1), VI6_DPR_RPF_ROUTE(1) }, 131 { VI6_DPR_NODE_RPF(1), VI6_DPR_RPF_ROUTE(1) },
128 { VI6_DPR_NODE_RPF(2), VI6_DPR_RPF_ROUTE(2) }, 132 { VI6_DPR_NODE_RPF(2), VI6_DPR_RPF_ROUTE(2) },
129 { VI6_DPR_NODE_RPF(3), VI6_DPR_RPF_ROUTE(3) }, 133 { VI6_DPR_NODE_RPF(3), VI6_DPR_RPF_ROUTE(3) },
130 { VI6_DPR_NODE_RPF(4), VI6_DPR_RPF_ROUTE(4) }, 134 { VI6_DPR_NODE_RPF(4), VI6_DPR_RPF_ROUTE(4) },
135 { VI6_DPR_NODE_SRU, VI6_DPR_SRU_ROUTE },
131 { VI6_DPR_NODE_UDS(0), VI6_DPR_UDS_ROUTE(0) }, 136 { VI6_DPR_NODE_UDS(0), VI6_DPR_UDS_ROUTE(0) },
132 { VI6_DPR_NODE_UDS(1), VI6_DPR_UDS_ROUTE(1) }, 137 { VI6_DPR_NODE_UDS(1), VI6_DPR_UDS_ROUTE(1) },
133 { VI6_DPR_NODE_UDS(2), VI6_DPR_UDS_ROUTE(2) }, 138 { VI6_DPR_NODE_UDS(2), VI6_DPR_UDS_ROUTE(2) },
@@ -177,5 +182,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
177 182
178void vsp1_entity_destroy(struct vsp1_entity *entity) 183void vsp1_entity_destroy(struct vsp1_entity *entity)
179{ 184{
185 if (entity->subdev.ctrl_handler)
186 v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
180 media_entity_cleanup(&entity->subdev.entity); 187 media_entity_cleanup(&entity->subdev.entity);
181} 188}
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index c4feab2cbb81..e152798d7f38 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -20,8 +20,12 @@
20struct vsp1_device; 20struct vsp1_device;
21 21
22enum vsp1_entity_type { 22enum vsp1_entity_type {
23 VSP1_ENTITY_HSI,
24 VSP1_ENTITY_HST,
23 VSP1_ENTITY_LIF, 25 VSP1_ENTITY_LIF,
26 VSP1_ENTITY_LUT,
24 VSP1_ENTITY_RPF, 27 VSP1_ENTITY_RPF,
28 VSP1_ENTITY_SRU,
25 VSP1_ENTITY_UDS, 29 VSP1_ENTITY_UDS,
26 VSP1_ENTITY_WPF, 30 VSP1_ENTITY_WPF,
27}; 31};
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
new file mode 100644
index 000000000000..285485350d82
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -0,0 +1,222 @@
1/*
2 * vsp1_hsit.c -- R-Car VSP1 Hue Saturation value (Inverse) Transform
3 *
4 * Copyright (C) 2013 Renesas 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
19#include "vsp1.h"
20#include "vsp1_hsit.h"
21
22#define HSIT_MIN_SIZE 4U
23#define HSIT_MAX_SIZE 8190U
24
25/* -----------------------------------------------------------------------------
26 * Device Access
27 */
28
29static inline u32 vsp1_hsit_read(struct vsp1_hsit *hsit, u32 reg)
30{
31 return vsp1_read(hsit->entity.vsp1, reg);
32}
33
34static inline void vsp1_hsit_write(struct vsp1_hsit *hsit, u32 reg, u32 data)
35{
36 vsp1_write(hsit->entity.vsp1, reg, data);
37}
38
39/* -----------------------------------------------------------------------------
40 * V4L2 Subdevice Core Operations
41 */
42
43static int hsit_s_stream(struct v4l2_subdev *subdev, int enable)
44{
45 struct vsp1_hsit *hsit = to_hsit(subdev);
46
47 if (!enable)
48 return 0;
49
50 if (hsit->inverse)
51 vsp1_hsit_write(hsit, VI6_HSI_CTRL, VI6_HSI_CTRL_EN);
52 else
53 vsp1_hsit_write(hsit, VI6_HST_CTRL, VI6_HST_CTRL_EN);
54
55 return 0;
56}
57
58/* -----------------------------------------------------------------------------
59 * V4L2 Subdevice Pad Operations
60 */
61
62static int hsit_enum_mbus_code(struct v4l2_subdev *subdev,
63 struct v4l2_subdev_fh *fh,
64 struct v4l2_subdev_mbus_code_enum *code)
65{
66 struct vsp1_hsit *hsit = to_hsit(subdev);
67
68 if (code->index > 0)
69 return -EINVAL;
70
71 if ((code->pad == HSIT_PAD_SINK && !hsit->inverse) |
72 (code->pad == HSIT_PAD_SOURCE && hsit->inverse))
73 code->code = V4L2_MBUS_FMT_ARGB8888_1X32;
74 else
75 code->code = V4L2_MBUS_FMT_AHSV8888_1X32;
76
77 return 0;
78}
79
80static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
81 struct v4l2_subdev_fh *fh,
82 struct v4l2_subdev_frame_size_enum *fse)
83{
84 struct v4l2_mbus_framefmt *format;
85
86 format = v4l2_subdev_get_try_format(fh, fse->pad);
87
88 if (fse->index || fse->code != format->code)
89 return -EINVAL;
90
91 if (fse->pad == HSIT_PAD_SINK) {
92 fse->min_width = HSIT_MIN_SIZE;
93 fse->max_width = HSIT_MAX_SIZE;
94 fse->min_height = HSIT_MIN_SIZE;
95 fse->max_height = HSIT_MAX_SIZE;
96 } else {
97 /* The size on the source pad are fixed and always identical to
98 * the size on the sink pad.
99 */
100 fse->min_width = format->width;
101 fse->max_width = format->width;
102 fse->min_height = format->height;
103 fse->max_height = format->height;
104 }
105
106 return 0;
107}
108
109static int hsit_get_format(struct v4l2_subdev *subdev,
110 struct v4l2_subdev_fh *fh,
111 struct v4l2_subdev_format *fmt)
112{
113 struct vsp1_hsit *hsit = to_hsit(subdev);
114
115 fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad,
116 fmt->which);
117
118 return 0;
119}
120
121static int hsit_set_format(struct v4l2_subdev *subdev,
122 struct v4l2_subdev_fh *fh,
123 struct v4l2_subdev_format *fmt)
124{
125 struct vsp1_hsit *hsit = to_hsit(subdev);
126 struct v4l2_mbus_framefmt *format;
127
128 format = vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad,
129 fmt->which);
130
131 if (fmt->pad == HSIT_PAD_SOURCE) {
132 /* The HST and HSI output format code and resolution can't be
133 * modified.
134 */
135 fmt->format = *format;
136 return 0;
137 }
138
139 format->code = hsit->inverse ? V4L2_MBUS_FMT_AHSV8888_1X32
140 : V4L2_MBUS_FMT_ARGB8888_1X32;
141 format->width = clamp_t(unsigned int, fmt->format.width,
142 HSIT_MIN_SIZE, HSIT_MAX_SIZE);
143 format->height = clamp_t(unsigned int, fmt->format.height,
144 HSIT_MIN_SIZE, HSIT_MAX_SIZE);
145 format->field = V4L2_FIELD_NONE;
146 format->colorspace = V4L2_COLORSPACE_SRGB;
147
148 fmt->format = *format;
149
150 /* Propagate the format to the source pad. */
151 format = vsp1_entity_get_pad_format(&hsit->entity, fh, HSIT_PAD_SOURCE,
152 fmt->which);
153 *format = fmt->format;
154 format->code = hsit->inverse ? V4L2_MBUS_FMT_ARGB8888_1X32
155 : V4L2_MBUS_FMT_AHSV8888_1X32;
156
157 return 0;
158}
159
160/* -----------------------------------------------------------------------------
161 * V4L2 Subdevice Operations
162 */
163
164static struct v4l2_subdev_video_ops hsit_video_ops = {
165 .s_stream = hsit_s_stream,
166};
167
168static struct v4l2_subdev_pad_ops hsit_pad_ops = {
169 .enum_mbus_code = hsit_enum_mbus_code,
170 .enum_frame_size = hsit_enum_frame_size,
171 .get_fmt = hsit_get_format,
172 .set_fmt = hsit_set_format,
173};
174
175static struct v4l2_subdev_ops hsit_ops = {
176 .video = &hsit_video_ops,
177 .pad = &hsit_pad_ops,
178};
179
180/* -----------------------------------------------------------------------------
181 * Initialization and Cleanup
182 */
183
184struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse)
185{
186 struct v4l2_subdev *subdev;
187 struct vsp1_hsit *hsit;
188 int ret;
189
190 hsit = devm_kzalloc(vsp1->dev, sizeof(*hsit), GFP_KERNEL);
191 if (hsit == NULL)
192 return ERR_PTR(-ENOMEM);
193
194 hsit->inverse = inverse;
195
196 if (inverse) {
197 hsit->entity.type = VSP1_ENTITY_HSI;
198 hsit->entity.id = VI6_DPR_NODE_HSI;
199 } else {
200 hsit->entity.type = VSP1_ENTITY_HST;
201 hsit->entity.id = VI6_DPR_NODE_HST;
202 }
203
204 ret = vsp1_entity_init(vsp1, &hsit->entity, 2);
205 if (ret < 0)
206 return ERR_PTR(ret);
207
208 /* Initialize the V4L2 subdev. */
209 subdev = &hsit->entity.subdev;
210 v4l2_subdev_init(subdev, &hsit_ops);
211
212 subdev->entity.ops = &vsp1_media_ops;
213 subdev->internal_ops = &vsp1_subdev_internal_ops;
214 snprintf(subdev->name, sizeof(subdev->name), "%s %s",
215 dev_name(vsp1->dev), inverse ? "hsi" : "hst");
216 v4l2_set_subdevdata(subdev, hsit);
217 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
218
219 vsp1_entity_init_formats(subdev, NULL);
220
221 return hsit;
222}
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.h b/drivers/media/platform/vsp1/vsp1_hsit.h
new file mode 100644
index 000000000000..82f1c8426900
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_hsit.h
@@ -0,0 +1,38 @@
1/*
2 * vsp1_hsit.h -- R-Car VSP1 Hue Saturation value (Inverse) Transform
3 *
4 * Copyright (C) 2013 Renesas 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_HSIT_H__
14#define __VSP1_HSIT_H__
15
16#include <media/media-entity.h>
17#include <media/v4l2-subdev.h>
18
19#include "vsp1_entity.h"
20
21struct vsp1_device;
22
23#define HSIT_PAD_SINK 0
24#define HSIT_PAD_SOURCE 1
25
26struct vsp1_hsit {
27 struct vsp1_entity entity;
28 bool inverse;
29};
30
31static inline struct vsp1_hsit *to_hsit(struct v4l2_subdev *subdev)
32{
33 return container_of(subdev, struct vsp1_hsit, entity.subdev);
34}
35
36struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse);
37
38#endif /* __VSP1_HSIT_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
new file mode 100644
index 000000000000..4e9dc7c86ef8
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -0,0 +1,252 @@
1/*
2 * vsp1_lut.c -- R-Car VSP1 Look-Up Table
3 *
4 * Copyright (C) 2013 Renesas 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#include <linux/vsp1.h>
17
18#include <media/v4l2-subdev.h>
19
20#include "vsp1.h"
21#include "vsp1_lut.h"
22
23#define LUT_MIN_SIZE 4U
24#define LUT_MAX_SIZE 8190U
25
26/* -----------------------------------------------------------------------------
27 * Device Access
28 */
29
30static inline u32 vsp1_lut_read(struct vsp1_lut *lut, u32 reg)
31{
32 return vsp1_read(lut->entity.vsp1, reg);
33}
34
35static inline void vsp1_lut_write(struct vsp1_lut *lut, u32 reg, u32 data)
36{
37 vsp1_write(lut->entity.vsp1, reg, data);
38}
39
40/* -----------------------------------------------------------------------------
41 * V4L2 Subdevice Core Operations
42 */
43
44static void lut_configure(struct vsp1_lut *lut, struct vsp1_lut_config *config)
45{
46 memcpy_toio(lut->entity.vsp1->mmio + VI6_LUT_TABLE, config->lut,
47 sizeof(config->lut));
48}
49
50static long lut_ioctl(struct v4l2_subdev *subdev, unsigned int cmd, void *arg)
51{
52 struct vsp1_lut *lut = to_lut(subdev);
53
54 switch (cmd) {
55 case VIDIOC_VSP1_LUT_CONFIG:
56 lut_configure(lut, arg);
57 return 0;
58
59 default:
60 return -ENOIOCTLCMD;
61 }
62}
63
64/* -----------------------------------------------------------------------------
65 * V4L2 Subdevice Video Operations
66 */
67
68static int lut_s_stream(struct v4l2_subdev *subdev, int enable)
69{
70 struct vsp1_lut *lut = to_lut(subdev);
71
72 if (!enable)
73 return 0;
74
75 vsp1_lut_write(lut, VI6_LUT_CTRL, VI6_LUT_CTRL_EN);
76
77 return 0;
78}
79
80/* -----------------------------------------------------------------------------
81 * V4L2 Subdevice Pad Operations
82 */
83
84static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
85 struct v4l2_subdev_fh *fh,
86 struct v4l2_subdev_mbus_code_enum *code)
87{
88 static const unsigned int codes[] = {
89 V4L2_MBUS_FMT_ARGB8888_1X32,
90 V4L2_MBUS_FMT_AHSV8888_1X32,
91 V4L2_MBUS_FMT_AYUV8_1X32,
92 };
93 struct v4l2_mbus_framefmt *format;
94
95 if (code->pad == LUT_PAD_SINK) {
96 if (code->index >= ARRAY_SIZE(codes))
97 return -EINVAL;
98
99 code->code = codes[code->index];
100 } else {
101 /* The LUT can't perform format conversion, the sink format is
102 * always identical to the source format.
103 */
104 if (code->index)
105 return -EINVAL;
106
107 format = v4l2_subdev_get_try_format(fh, LUT_PAD_SINK);
108 code->code = format->code;
109 }
110
111 return 0;
112}
113
114static int lut_enum_frame_size(struct v4l2_subdev *subdev,
115 struct v4l2_subdev_fh *fh,
116 struct v4l2_subdev_frame_size_enum *fse)
117{
118 struct v4l2_mbus_framefmt *format;
119
120 format = v4l2_subdev_get_try_format(fh, fse->pad);
121
122 if (fse->index || fse->code != format->code)
123 return -EINVAL;
124
125 if (fse->pad == LUT_PAD_SINK) {
126 fse->min_width = LUT_MIN_SIZE;
127 fse->max_width = LUT_MAX_SIZE;
128 fse->min_height = LUT_MIN_SIZE;
129 fse->max_height = LUT_MAX_SIZE;
130 } else {
131 /* The size on the source pad are fixed and always identical to
132 * the size on the sink pad.
133 */
134 fse->min_width = format->width;
135 fse->max_width = format->width;
136 fse->min_height = format->height;
137 fse->max_height = format->height;
138 }
139
140 return 0;
141}
142
143static int lut_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
144 struct v4l2_subdev_format *fmt)
145{
146 struct vsp1_lut *lut = to_lut(subdev);
147
148 fmt->format = *vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad,
149 fmt->which);
150
151 return 0;
152}
153
154static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
155 struct v4l2_subdev_format *fmt)
156{
157 struct vsp1_lut *lut = to_lut(subdev);
158 struct v4l2_mbus_framefmt *format;
159
160 /* Default to YUV if the requested format is not supported. */
161 if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 &&
162 fmt->format.code != V4L2_MBUS_FMT_AHSV8888_1X32 &&
163 fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32)
164 fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32;
165
166 format = vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad,
167 fmt->which);
168
169 if (fmt->pad == LUT_PAD_SOURCE) {
170 /* The LUT output format can't be modified. */
171 fmt->format = *format;
172 return 0;
173 }
174
175 format->width = clamp_t(unsigned int, fmt->format.width,
176 LUT_MIN_SIZE, LUT_MAX_SIZE);
177 format->height = clamp_t(unsigned int, fmt->format.height,
178 LUT_MIN_SIZE, LUT_MAX_SIZE);
179 format->field = V4L2_FIELD_NONE;
180 format->colorspace = V4L2_COLORSPACE_SRGB;
181
182 fmt->format = *format;
183
184 /* Propagate the format to the source pad. */
185 format = vsp1_entity_get_pad_format(&lut->entity, fh, LUT_PAD_SOURCE,
186 fmt->which);
187 *format = fmt->format;
188
189 return 0;
190}
191
192/* -----------------------------------------------------------------------------
193 * V4L2 Subdevice Operations
194 */
195
196static struct v4l2_subdev_core_ops lut_core_ops = {
197 .ioctl = lut_ioctl,
198};
199
200static struct v4l2_subdev_video_ops lut_video_ops = {
201 .s_stream = lut_s_stream,
202};
203
204static struct v4l2_subdev_pad_ops lut_pad_ops = {
205 .enum_mbus_code = lut_enum_mbus_code,
206 .enum_frame_size = lut_enum_frame_size,
207 .get_fmt = lut_get_format,
208 .set_fmt = lut_set_format,
209};
210
211static struct v4l2_subdev_ops lut_ops = {
212 .core = &lut_core_ops,
213 .video = &lut_video_ops,
214 .pad = &lut_pad_ops,
215};
216
217/* -----------------------------------------------------------------------------
218 * Initialization and Cleanup
219 */
220
221struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1)
222{
223 struct v4l2_subdev *subdev;
224 struct vsp1_lut *lut;
225 int ret;
226
227 lut = devm_kzalloc(vsp1->dev, sizeof(*lut), GFP_KERNEL);
228 if (lut == NULL)
229 return ERR_PTR(-ENOMEM);
230
231 lut->entity.type = VSP1_ENTITY_LUT;
232 lut->entity.id = VI6_DPR_NODE_LUT;
233
234 ret = vsp1_entity_init(vsp1, &lut->entity, 2);
235 if (ret < 0)
236 return ERR_PTR(ret);
237
238 /* Initialize the V4L2 subdev. */
239 subdev = &lut->entity.subdev;
240 v4l2_subdev_init(subdev, &lut_ops);
241
242 subdev->entity.ops = &vsp1_media_ops;
243 subdev->internal_ops = &vsp1_subdev_internal_ops;
244 snprintf(subdev->name, sizeof(subdev->name), "%s lut",
245 dev_name(vsp1->dev));
246 v4l2_set_subdevdata(subdev, lut);
247 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
248
249 vsp1_entity_init_formats(subdev, NULL);
250
251 return lut;
252}
diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h
new file mode 100644
index 000000000000..f92ffb867350
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_lut.h
@@ -0,0 +1,38 @@
1/*
2 * vsp1_lut.h -- R-Car VSP1 Look-Up Table
3 *
4 * Copyright (C) 2013 Renesas 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_LUT_H__
14#define __VSP1_LUT_H__
15
16#include <media/media-entity.h>
17#include <media/v4l2-subdev.h>
18
19#include "vsp1_entity.h"
20
21struct vsp1_device;
22
23#define LUT_PAD_SINK 0
24#define LUT_PAD_SOURCE 1
25
26struct vsp1_lut {
27 struct vsp1_entity entity;
28 u32 lut[256];
29};
30
31static inline struct vsp1_lut *to_lut(struct v4l2_subdev *subdev)
32{
33 return container_of(subdev, struct vsp1_lut, entity.subdev);
34}
35
36struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1);
37
38#endif /* __VSP1_LUT_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 1d3304f1365b..28650806c20f 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -336,8 +336,21 @@
336 */ 336 */
337 337
338#define VI6_SRU_CTRL0 0x2200 338#define VI6_SRU_CTRL0 0x2200
339#define VI6_SRU_CTRL0_PARAM0_SHIFT 16
340#define VI6_SRU_CTRL0_PARAM1_SHIFT 8
341#define VI6_SRU_CTRL0_MODE_UPSCALE (4 << 4)
342#define VI6_SRU_CTRL0_PARAM2 (1 << 3)
343#define VI6_SRU_CTRL0_PARAM3 (1 << 2)
344#define VI6_SRU_CTRL0_PARAM4 (1 << 1)
345#define VI6_SRU_CTRL0_EN (1 << 0)
346
339#define VI6_SRU_CTRL1 0x2204 347#define VI6_SRU_CTRL1 0x2204
348#define VI6_SRU_CTRL1_PARAM5 0x7ff
349
340#define VI6_SRU_CTRL2 0x2208 350#define VI6_SRU_CTRL2 0x2208
351#define VI6_SRU_CTRL2_PARAM6_SHIFT 16
352#define VI6_SRU_CTRL2_PARAM7_SHIFT 8
353#define VI6_SRU_CTRL2_PARAM8_SHIFT 0
341 354
342/* ----------------------------------------------------------------------------- 355/* -----------------------------------------------------------------------------
343 * UDS Control Registers 356 * UDS Control Registers
@@ -412,6 +425,7 @@
412 */ 425 */
413 426
414#define VI6_LUT_CTRL 0x2800 427#define VI6_LUT_CTRL 0x2800
428#define VI6_LUT_CTRL_EN (1 << 0)
415 429
416/* ----------------------------------------------------------------------------- 430/* -----------------------------------------------------------------------------
417 * CLU Control Registers 431 * CLU Control Registers
@@ -424,12 +438,14 @@
424 */ 438 */
425 439
426#define VI6_HST_CTRL 0x2a00 440#define VI6_HST_CTRL 0x2a00
441#define VI6_HST_CTRL_EN (1 << 0)
427 442
428/* ----------------------------------------------------------------------------- 443/* -----------------------------------------------------------------------------
429 * HSI Control Registers 444 * HSI Control Registers
430 */ 445 */
431 446
432#define VI6_HSI_CTRL 0x2b00 447#define VI6_HSI_CTRL 0x2b00
448#define VI6_HSI_CTRL_EN (1 << 0)
433 449
434/* ----------------------------------------------------------------------------- 450/* -----------------------------------------------------------------------------
435 * BRU Control Registers 451 * BRU Control Registers
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 254871d3423e..bce2be5466b9 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -47,25 +47,36 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
47 struct vsp1_rwpf *rpf = to_rwpf(subdev); 47 struct vsp1_rwpf *rpf = to_rwpf(subdev);
48 const struct vsp1_format_info *fmtinfo = rpf->video.fmtinfo; 48 const struct vsp1_format_info *fmtinfo = rpf->video.fmtinfo;
49 const struct v4l2_pix_format_mplane *format = &rpf->video.format; 49 const struct v4l2_pix_format_mplane *format = &rpf->video.format;
50 const struct v4l2_rect *crop = &rpf->crop;
50 u32 pstride; 51 u32 pstride;
51 u32 infmt; 52 u32 infmt;
52 53
53 if (!enable) 54 if (!enable)
54 return 0; 55 return 0;
55 56
56 /* Source size and stride. Cropping isn't supported yet. */ 57 /* Source size, stride and crop offsets.
58 *
59 * The crop offsets correspond to the location of the crop rectangle top
60 * left corner in the plane buffer. Only two offsets are needed, as
61 * planes 2 and 3 always have identical strides.
62 */
57 vsp1_rpf_write(rpf, VI6_RPF_SRC_BSIZE, 63 vsp1_rpf_write(rpf, VI6_RPF_SRC_BSIZE,
58 (format->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) | 64 (crop->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) |
59 (format->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT)); 65 (crop->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT));
60 vsp1_rpf_write(rpf, VI6_RPF_SRC_ESIZE, 66 vsp1_rpf_write(rpf, VI6_RPF_SRC_ESIZE,
61 (format->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) | 67 (crop->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) |
62 (format->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT)); 68 (crop->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT));
63 69
70 rpf->offsets[0] = crop->top * format->plane_fmt[0].bytesperline
71 + crop->left * fmtinfo->bpp[0] / 8;
64 pstride = format->plane_fmt[0].bytesperline 72 pstride = format->plane_fmt[0].bytesperline
65 << VI6_RPF_SRCM_PSTRIDE_Y_SHIFT; 73 << VI6_RPF_SRCM_PSTRIDE_Y_SHIFT;
66 if (format->num_planes > 1) 74 if (format->num_planes > 1) {
75 rpf->offsets[1] = crop->top * format->plane_fmt[1].bytesperline
76 + crop->left * fmtinfo->bpp[1] / 8;
67 pstride |= format->plane_fmt[1].bytesperline 77 pstride |= format->plane_fmt[1].bytesperline
68 << VI6_RPF_SRCM_PSTRIDE_C_SHIFT; 78 << VI6_RPF_SRCM_PSTRIDE_C_SHIFT;
79 }
69 80
70 vsp1_rpf_write(rpf, VI6_RPF_SRCM_PSTRIDE, pstride); 81 vsp1_rpf_write(rpf, VI6_RPF_SRCM_PSTRIDE, pstride);
71 82
@@ -113,6 +124,8 @@ static struct v4l2_subdev_pad_ops rpf_pad_ops = {
113 .enum_frame_size = vsp1_rwpf_enum_frame_size, 124 .enum_frame_size = vsp1_rwpf_enum_frame_size,
114 .get_fmt = vsp1_rwpf_get_format, 125 .get_fmt = vsp1_rwpf_get_format,
115 .set_fmt = vsp1_rwpf_set_format, 126 .set_fmt = vsp1_rwpf_set_format,
127 .get_selection = vsp1_rwpf_get_selection,
128 .set_selection = vsp1_rwpf_set_selection,
116}; 129};
117 130
118static struct v4l2_subdev_ops rpf_ops = { 131static struct v4l2_subdev_ops rpf_ops = {
@@ -129,11 +142,14 @@ static void rpf_vdev_queue(struct vsp1_video *video,
129{ 142{
130 struct vsp1_rwpf *rpf = container_of(video, struct vsp1_rwpf, video); 143 struct vsp1_rwpf *rpf = container_of(video, struct vsp1_rwpf, video);
131 144
132 vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y, buf->addr[0]); 145 vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y,
146 buf->addr[0] + rpf->offsets[0]);
133 if (buf->buf.num_planes > 1) 147 if (buf->buf.num_planes > 1)
134 vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0, buf->addr[1]); 148 vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0,
149 buf->addr[1] + rpf->offsets[1]);
135 if (buf->buf.num_planes > 2) 150 if (buf->buf.num_planes > 2)
136 vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1, buf->addr[2]); 151 vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1,
152 buf->addr[2] + rpf->offsets[1]);
137} 153}
138 154
139static const struct vsp1_video_operations rpf_vdev_ops = { 155static const struct vsp1_video_operations rpf_vdev_ops = {
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index 9752d5516ceb..782f770daee5 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -71,6 +71,19 @@ int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
71 return 0; 71 return 0;
72} 72}
73 73
74static struct v4l2_rect *
75vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_fh *fh, u32 which)
76{
77 switch (which) {
78 case V4L2_SUBDEV_FORMAT_TRY:
79 return v4l2_subdev_get_try_crop(fh, RWPF_PAD_SINK);
80 case V4L2_SUBDEV_FORMAT_ACTIVE:
81 return &rwpf->crop;
82 default:
83 return NULL;
84 }
85}
86
74int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 87int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
75 struct v4l2_subdev_format *fmt) 88 struct v4l2_subdev_format *fmt)
76{ 89{
@@ -87,6 +100,7 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
87{ 100{
88 struct vsp1_rwpf *rwpf = to_rwpf(subdev); 101 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
89 struct v4l2_mbus_framefmt *format; 102 struct v4l2_mbus_framefmt *format;
103 struct v4l2_rect *crop;
90 104
91 /* Default to YUV if the requested format is not supported. */ 105 /* Default to YUV if the requested format is not supported. */
92 if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && 106 if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 &&
@@ -115,6 +129,13 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
115 129
116 fmt->format = *format; 130 fmt->format = *format;
117 131
132 /* Update the sink crop rectangle. */
133 crop = vsp1_rwpf_get_crop(rwpf, fh, fmt->which);
134 crop->left = 0;
135 crop->top = 0;
136 crop->width = fmt->format.width;
137 crop->height = fmt->format.height;
138
118 /* Propagate the format to the source pad. */ 139 /* Propagate the format to the source pad. */
119 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE, 140 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE,
120 fmt->which); 141 fmt->which);
@@ -122,3 +143,78 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
122 143
123 return 0; 144 return 0;
124} 145}
146
147int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
148 struct v4l2_subdev_fh *fh,
149 struct v4l2_subdev_selection *sel)
150{
151 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
152 struct v4l2_mbus_framefmt *format;
153
154 /* Cropping is implemented on the sink pad. */
155 if (sel->pad != RWPF_PAD_SINK)
156 return -EINVAL;
157
158 switch (sel->target) {
159 case V4L2_SEL_TGT_CROP:
160 sel->r = *vsp1_rwpf_get_crop(rwpf, fh, sel->which);
161 break;
162
163 case V4L2_SEL_TGT_CROP_BOUNDS:
164 format = vsp1_entity_get_pad_format(&rwpf->entity, fh,
165 RWPF_PAD_SINK, sel->which);
166 sel->r.left = 0;
167 sel->r.top = 0;
168 sel->r.width = format->width;
169 sel->r.height = format->height;
170 break;
171
172 default:
173 return -EINVAL;
174 }
175
176 return 0;
177}
178
179int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
180 struct v4l2_subdev_fh *fh,
181 struct v4l2_subdev_selection *sel)
182{
183 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
184 struct v4l2_mbus_framefmt *format;
185 struct v4l2_rect *crop;
186
187 /* Cropping is implemented on the sink pad. */
188 if (sel->pad != RWPF_PAD_SINK)
189 return -EINVAL;
190
191 if (sel->target != V4L2_SEL_TGT_CROP)
192 return -EINVAL;
193
194 /* Make sure the crop rectangle is entirely contained in the image. The
195 * WPF top and left offsets are limited to 255.
196 */
197 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SINK,
198 sel->which);
199 sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2);
200 sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2);
201 if (rwpf->entity.type == VSP1_ENTITY_WPF) {
202 sel->r.left = min_t(unsigned int, sel->r.left, 255);
203 sel->r.top = min_t(unsigned int, sel->r.top, 255);
204 }
205 sel->r.width = min_t(unsigned int, sel->r.width,
206 format->width - sel->r.left);
207 sel->r.height = min_t(unsigned int, sel->r.height,
208 format->height - sel->r.top);
209
210 crop = vsp1_rwpf_get_crop(rwpf, fh, sel->which);
211 *crop = sel->r;
212
213 /* Propagate the format to the source pad. */
214 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE,
215 sel->which);
216 format->width = crop->width;
217 format->height = crop->height;
218
219 return 0;
220}
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index c182d85f36b3..6cbdb547470b 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -29,6 +29,10 @@ struct vsp1_rwpf {
29 29
30 unsigned int max_width; 30 unsigned int max_width;
31 unsigned int max_height; 31 unsigned int max_height;
32
33 struct v4l2_rect crop;
34
35 unsigned int offsets[2];
32}; 36};
33 37
34static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev) 38static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev)
@@ -49,5 +53,11 @@ int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
49 struct v4l2_subdev_format *fmt); 53 struct v4l2_subdev_format *fmt);
50int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 54int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
51 struct v4l2_subdev_format *fmt); 55 struct v4l2_subdev_format *fmt);
56int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
57 struct v4l2_subdev_fh *fh,
58 struct v4l2_subdev_selection *sel);
59int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
60 struct v4l2_subdev_fh *fh,
61 struct v4l2_subdev_selection *sel);
52 62
53#endif /* __VSP1_RWPF_H__ */ 63#endif /* __VSP1_RWPF_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
new file mode 100644
index 000000000000..7ab1a0b2d656
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -0,0 +1,356 @@
1/*
2 * vsp1_sru.c -- R-Car VSP1 Super Resolution Unit
3 *
4 * Copyright (C) 2013 Renesas 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
19#include "vsp1.h"
20#include "vsp1_sru.h"
21
22#define SRU_MIN_SIZE 4U
23#define SRU_MAX_SIZE 8190U
24
25/* -----------------------------------------------------------------------------
26 * Device Access
27 */
28
29static inline u32 vsp1_sru_read(struct vsp1_sru *sru, u32 reg)
30{
31 return vsp1_read(sru->entity.vsp1, reg);
32}
33
34static inline void vsp1_sru_write(struct vsp1_sru *sru, u32 reg, u32 data)
35{
36 vsp1_write(sru->entity.vsp1, reg, data);
37}
38
39/* -----------------------------------------------------------------------------
40 * Controls
41 */
42
43#define V4L2_CID_VSP1_SRU_INTENSITY (V4L2_CID_USER_BASE + 1)
44
45static int sru_s_ctrl(struct v4l2_ctrl *ctrl)
46{
47 struct vsp1_sru *sru =
48 container_of(ctrl->handler, struct vsp1_sru, ctrls);
49
50 switch (ctrl->id) {
51 case V4L2_CID_VSP1_SRU_INTENSITY:
52 sru->intensity = ctrl->val;
53 break;
54 }
55
56 return 0;
57}
58
59static const struct v4l2_ctrl_ops sru_ctrl_ops = {
60 .s_ctrl = sru_s_ctrl,
61};
62
63static const struct v4l2_ctrl_config sru_intensity_control = {
64 .ops = &sru_ctrl_ops,
65 .id = V4L2_CID_VSP1_SRU_INTENSITY,
66 .name = "Intensity",
67 .type = V4L2_CTRL_TYPE_INTEGER,
68 .min = 1,
69 .max = 6,
70 .step = 1,
71};
72
73/* -----------------------------------------------------------------------------
74 * V4L2 Subdevice Core Operations
75 */
76
77struct vsp1_sru_param {
78 u32 ctrl0;
79 u32 ctrl2;
80};
81
82#define VI6_SRU_CTRL0_PARAMS(p0, p1) \
83 (((p0) << VI6_SRU_CTRL0_PARAM0_SHIFT) | \
84 ((p1) << VI6_SRU_CTRL0_PARAM1_SHIFT))
85
86#define VI6_SRU_CTRL2_PARAMS(p6, p7, p8) \
87 (((p6) << VI6_SRU_CTRL2_PARAM6_SHIFT) | \
88 ((p7) << VI6_SRU_CTRL2_PARAM7_SHIFT) | \
89 ((p8) << VI6_SRU_CTRL2_PARAM8_SHIFT))
90
91static const struct vsp1_sru_param vsp1_sru_params[] = {
92 {
93 .ctrl0 = VI6_SRU_CTRL0_PARAMS(256, 4) | VI6_SRU_CTRL0_EN,
94 .ctrl2 = VI6_SRU_CTRL2_PARAMS(24, 40, 255),
95 }, {
96 .ctrl0 = VI6_SRU_CTRL0_PARAMS(256, 4) | VI6_SRU_CTRL0_EN,
97 .ctrl2 = VI6_SRU_CTRL2_PARAMS(8, 16, 255),
98 }, {
99 .ctrl0 = VI6_SRU_CTRL0_PARAMS(384, 5) | VI6_SRU_CTRL0_EN,
100 .ctrl2 = VI6_SRU_CTRL2_PARAMS(36, 60, 255),
101 }, {
102 .ctrl0 = VI6_SRU_CTRL0_PARAMS(384, 5) | VI6_SRU_CTRL0_EN,
103 .ctrl2 = VI6_SRU_CTRL2_PARAMS(12, 27, 255),
104 }, {
105 .ctrl0 = VI6_SRU_CTRL0_PARAMS(511, 6) | VI6_SRU_CTRL0_EN,
106 .ctrl2 = VI6_SRU_CTRL2_PARAMS(48, 80, 255),
107 }, {
108 .ctrl0 = VI6_SRU_CTRL0_PARAMS(511, 6) | VI6_SRU_CTRL0_EN,
109 .ctrl2 = VI6_SRU_CTRL2_PARAMS(16, 36, 255),
110 },
111};
112
113static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
114{
115 struct vsp1_sru *sru = to_sru(subdev);
116 const struct vsp1_sru_param *param;
117 struct v4l2_mbus_framefmt *input;
118 struct v4l2_mbus_framefmt *output;
119 bool upscale;
120 u32 ctrl0;
121
122 if (!enable)
123 return 0;
124
125 input = &sru->entity.formats[SRU_PAD_SINK];
126 output = &sru->entity.formats[SRU_PAD_SOURCE];
127 upscale = input->width != output->width;
128 param = &vsp1_sru_params[sru->intensity];
129
130 if (input->code == V4L2_MBUS_FMT_ARGB8888_1X32)
131 ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3
132 | VI6_SRU_CTRL0_PARAM4;
133 else
134 ctrl0 = VI6_SRU_CTRL0_PARAM3;
135
136 vsp1_sru_write(sru, VI6_SRU_CTRL0, param->ctrl0 | ctrl0 |
137 (upscale ? VI6_SRU_CTRL0_MODE_UPSCALE : 0));
138 vsp1_sru_write(sru, VI6_SRU_CTRL1, VI6_SRU_CTRL1_PARAM5);
139 vsp1_sru_write(sru, VI6_SRU_CTRL2, param->ctrl2);
140
141 return 0;
142}
143
144/* -----------------------------------------------------------------------------
145 * V4L2 Subdevice Pad Operations
146 */
147
148static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
149 struct v4l2_subdev_fh *fh,
150 struct v4l2_subdev_mbus_code_enum *code)
151{
152 static const unsigned int codes[] = {
153 V4L2_MBUS_FMT_ARGB8888_1X32,
154 V4L2_MBUS_FMT_AYUV8_1X32,
155 };
156 struct v4l2_mbus_framefmt *format;
157
158 if (code->pad == SRU_PAD_SINK) {
159 if (code->index >= ARRAY_SIZE(codes))
160 return -EINVAL;
161
162 code->code = codes[code->index];
163 } else {
164 /* The SRU can't perform format conversion, the sink format is
165 * always identical to the source format.
166 */
167 if (code->index)
168 return -EINVAL;
169
170 format = v4l2_subdev_get_try_format(fh, SRU_PAD_SINK);
171 code->code = format->code;
172 }
173
174 return 0;
175}
176
177static int sru_enum_frame_size(struct v4l2_subdev *subdev,
178 struct v4l2_subdev_fh *fh,
179 struct v4l2_subdev_frame_size_enum *fse)
180{
181 struct v4l2_mbus_framefmt *format;
182
183 format = v4l2_subdev_get_try_format(fh, SRU_PAD_SINK);
184
185 if (fse->index || fse->code != format->code)
186 return -EINVAL;
187
188 if (fse->pad == SRU_PAD_SINK) {
189 fse->min_width = SRU_MIN_SIZE;
190 fse->max_width = SRU_MAX_SIZE;
191 fse->min_height = SRU_MIN_SIZE;
192 fse->max_height = SRU_MAX_SIZE;
193 } else {
194 fse->min_width = format->width;
195 fse->min_height = format->height;
196 if (format->width <= SRU_MAX_SIZE / 2 &&
197 format->height <= SRU_MAX_SIZE / 2) {
198 fse->max_width = format->width * 2;
199 fse->max_height = format->height * 2;
200 } else {
201 fse->max_width = format->width;
202 fse->max_height = format->height;
203 }
204 }
205
206 return 0;
207}
208
209static int sru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
210 struct v4l2_subdev_format *fmt)
211{
212 struct vsp1_sru *sru = to_sru(subdev);
213
214 fmt->format = *vsp1_entity_get_pad_format(&sru->entity, fh, fmt->pad,
215 fmt->which);
216
217 return 0;
218}
219
220static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh,
221 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
222 enum v4l2_subdev_format_whence which)
223{
224 struct v4l2_mbus_framefmt *format;
225 unsigned int input_area;
226 unsigned int output_area;
227
228 switch (pad) {
229 case SRU_PAD_SINK:
230 /* Default to YUV if the requested format is not supported. */
231 if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 &&
232 fmt->code != V4L2_MBUS_FMT_AYUV8_1X32)
233 fmt->code = V4L2_MBUS_FMT_AYUV8_1X32;
234
235 fmt->width = clamp(fmt->width, SRU_MIN_SIZE, SRU_MAX_SIZE);
236 fmt->height = clamp(fmt->height, SRU_MIN_SIZE, SRU_MAX_SIZE);
237 break;
238
239 case SRU_PAD_SOURCE:
240 /* The SRU can't perform format conversion. */
241 format = vsp1_entity_get_pad_format(&sru->entity, fh,
242 SRU_PAD_SINK, which);
243 fmt->code = format->code;
244
245 /* We can upscale by 2 in both direction, but not independently.
246 * Compare the input and output rectangles areas (avoiding
247 * integer overflows on the output): if the requested output
248 * area is larger than 1.5^2 the input area upscale by two,
249 * otherwise don't scale.
250 */
251 input_area = format->width * format->height;
252 output_area = min(fmt->width, SRU_MAX_SIZE)
253 * min(fmt->height, SRU_MAX_SIZE);
254
255 if (fmt->width <= SRU_MAX_SIZE / 2 &&
256 fmt->height <= SRU_MAX_SIZE / 2 &&
257 output_area > input_area * 9 / 4) {
258 fmt->width = format->width * 2;
259 fmt->height = format->height * 2;
260 } else {
261 fmt->width = format->width;
262 fmt->height = format->height;
263 }
264 break;
265 }
266
267 fmt->field = V4L2_FIELD_NONE;
268 fmt->colorspace = V4L2_COLORSPACE_SRGB;
269}
270
271static int sru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
272 struct v4l2_subdev_format *fmt)
273{
274 struct vsp1_sru *sru = to_sru(subdev);
275 struct v4l2_mbus_framefmt *format;
276
277 sru_try_format(sru, fh, fmt->pad, &fmt->format, fmt->which);
278
279 format = vsp1_entity_get_pad_format(&sru->entity, fh, fmt->pad,
280 fmt->which);
281 *format = fmt->format;
282
283 if (fmt->pad == SRU_PAD_SINK) {
284 /* Propagate the format to the source pad. */
285 format = vsp1_entity_get_pad_format(&sru->entity, fh,
286 SRU_PAD_SOURCE, fmt->which);
287 *format = fmt->format;
288
289 sru_try_format(sru, fh, SRU_PAD_SOURCE, format, fmt->which);
290 }
291
292 return 0;
293}
294
295/* -----------------------------------------------------------------------------
296 * V4L2 Subdevice Operations
297 */
298
299static struct v4l2_subdev_video_ops sru_video_ops = {
300 .s_stream = sru_s_stream,
301};
302
303static struct v4l2_subdev_pad_ops sru_pad_ops = {
304 .enum_mbus_code = sru_enum_mbus_code,
305 .enum_frame_size = sru_enum_frame_size,
306 .get_fmt = sru_get_format,
307 .set_fmt = sru_set_format,
308};
309
310static struct v4l2_subdev_ops sru_ops = {
311 .video = &sru_video_ops,
312 .pad = &sru_pad_ops,
313};
314
315/* -----------------------------------------------------------------------------
316 * Initialization and Cleanup
317 */
318
319struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
320{
321 struct v4l2_subdev *subdev;
322 struct vsp1_sru *sru;
323 int ret;
324
325 sru = devm_kzalloc(vsp1->dev, sizeof(*sru), GFP_KERNEL);
326 if (sru == NULL)
327 return ERR_PTR(-ENOMEM);
328
329 sru->entity.type = VSP1_ENTITY_SRU;
330 sru->entity.id = VI6_DPR_NODE_SRU;
331
332 ret = vsp1_entity_init(vsp1, &sru->entity, 2);
333 if (ret < 0)
334 return ERR_PTR(ret);
335
336 /* Initialize the V4L2 subdev. */
337 subdev = &sru->entity.subdev;
338 v4l2_subdev_init(subdev, &sru_ops);
339
340 subdev->entity.ops = &vsp1_media_ops;
341 subdev->internal_ops = &vsp1_subdev_internal_ops;
342 snprintf(subdev->name, sizeof(subdev->name), "%s sru",
343 dev_name(vsp1->dev));
344 v4l2_set_subdevdata(subdev, sru);
345 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
346
347 vsp1_entity_init_formats(subdev, NULL);
348
349 /* Initialize the control handler. */
350 v4l2_ctrl_handler_init(&sru->ctrls, 1);
351 v4l2_ctrl_new_custom(&sru->ctrls, &sru_intensity_control, NULL);
352 v4l2_ctrl_handler_setup(&sru->ctrls);
353 sru->entity.subdev.ctrl_handler = &sru->ctrls;
354
355 return sru;
356}
diff --git a/drivers/media/platform/vsp1/vsp1_sru.h b/drivers/media/platform/vsp1/vsp1_sru.h
new file mode 100644
index 000000000000..381870b74780
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_sru.h
@@ -0,0 +1,41 @@
1/*
2 * vsp1_sru.h -- R-Car VSP1 Super Resolution Unit
3 *
4 * Copyright (C) 2013 Renesas 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_SRU_H__
14#define __VSP1_SRU_H__
15
16#include <media/media-entity.h>
17#include <media/v4l2-ctrls.h>
18#include <media/v4l2-subdev.h>
19
20#include "vsp1_entity.h"
21
22struct vsp1_device;
23
24#define SRU_PAD_SINK 0
25#define SRU_PAD_SOURCE 1
26
27struct vsp1_sru {
28 struct vsp1_entity entity;
29
30 struct v4l2_ctrl_handler ctrls;
31 unsigned int intensity;
32};
33
34static inline struct vsp1_sru *to_sru(struct v4l2_subdev *subdev)
35{
36 return container_of(subdev, struct vsp1_sru, entity.subdev);
37}
38
39struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1);
40
41#endif /* __VSP1_SRU_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 4b0ac07af662..b4687a834f85 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -488,11 +488,17 @@ static bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe)
488 * This function completes the current buffer by filling its sequence number, 488 * This function completes the current buffer by filling its sequence number,
489 * time stamp and payload size, and hands it back to the videobuf core. 489 * time stamp and payload size, and hands it back to the videobuf core.
490 * 490 *
491 * When operating in DU output mode (deep pipeline to the DU through the LIF),
492 * the VSP1 needs to constantly supply frames to the display. In that case, if
493 * no other buffer is queued, reuse the one that has just been processed instead
494 * of handing it back to the videobuf core.
495 *
491 * Return the next queued buffer or NULL if the queue is empty. 496 * Return the next queued buffer or NULL if the queue is empty.
492 */ 497 */
493static struct vsp1_video_buffer * 498static struct vsp1_video_buffer *
494vsp1_video_complete_buffer(struct vsp1_video *video) 499vsp1_video_complete_buffer(struct vsp1_video *video)
495{ 500{
501 struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity);
496 struct vsp1_video_buffer *next = NULL; 502 struct vsp1_video_buffer *next = NULL;
497 struct vsp1_video_buffer *done; 503 struct vsp1_video_buffer *done;
498 unsigned long flags; 504 unsigned long flags;
@@ -507,6 +513,13 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
507 513
508 done = list_first_entry(&video->irqqueue, 514 done = list_first_entry(&video->irqqueue,
509 struct vsp1_video_buffer, queue); 515 struct vsp1_video_buffer, queue);
516
517 /* In DU output mode reuse the buffer if the list is singular. */
518 if (pipe->lif && list_is_singular(&video->irqqueue)) {
519 spin_unlock_irqrestore(&video->irqlock, flags);
520 return done;
521 }
522
510 list_del(&done->queue); 523 list_del(&done->queue);
511 524
512 if (!list_empty(&video->irqqueue)) 525 if (!list_empty(&video->irqqueue))
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index db4b85ee05fc..7baed81ff005 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -48,8 +48,7 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
48 struct vsp1_pipeline *pipe = 48 struct vsp1_pipeline *pipe =
49 to_vsp1_pipeline(&wpf->entity.subdev.entity); 49 to_vsp1_pipeline(&wpf->entity.subdev.entity);
50 struct vsp1_device *vsp1 = wpf->entity.vsp1; 50 struct vsp1_device *vsp1 = wpf->entity.vsp1;
51 const struct v4l2_mbus_framefmt *format = 51 const struct v4l2_rect *crop = &wpf->crop;
52 &wpf->entity.formats[RWPF_PAD_SOURCE];
53 unsigned int i; 52 unsigned int i;
54 u32 srcrpf = 0; 53 u32 srcrpf = 0;
55 u32 outfmt = 0; 54 u32 outfmt = 0;
@@ -68,7 +67,7 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
68 67
69 vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf); 68 vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf);
70 69
71 /* Destination stride. Cropping isn't supported yet. */ 70 /* Destination stride. */
72 if (!pipe->lif) { 71 if (!pipe->lif) {
73 struct v4l2_pix_format_mplane *format = &wpf->video.format; 72 struct v4l2_pix_format_mplane *format = &wpf->video.format;
74 73
@@ -79,10 +78,12 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
79 format->plane_fmt[1].bytesperline); 78 format->plane_fmt[1].bytesperline);
80 } 79 }
81 80
82 vsp1_wpf_write(wpf, VI6_WPF_HSZCLIP, 81 vsp1_wpf_write(wpf, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN |
83 format->width << VI6_WPF_SZCLIP_SIZE_SHIFT); 82 (crop->left << VI6_WPF_SZCLIP_OFST_SHIFT) |
84 vsp1_wpf_write(wpf, VI6_WPF_VSZCLIP, 83 (crop->width << VI6_WPF_SZCLIP_SIZE_SHIFT));
85 format->height << VI6_WPF_SZCLIP_SIZE_SHIFT); 84 vsp1_wpf_write(wpf, VI6_WPF_VSZCLIP, VI6_WPF_SZCLIP_EN |
85 (crop->top << VI6_WPF_SZCLIP_OFST_SHIFT) |
86 (crop->height << VI6_WPF_SZCLIP_SIZE_SHIFT));
86 87
87 /* Format */ 88 /* Format */
88 if (!pipe->lif) { 89 if (!pipe->lif) {
@@ -130,6 +131,8 @@ static struct v4l2_subdev_pad_ops wpf_pad_ops = {
130 .enum_frame_size = vsp1_rwpf_enum_frame_size, 131 .enum_frame_size = vsp1_rwpf_enum_frame_size,
131 .get_fmt = vsp1_rwpf_get_format, 132 .get_fmt = vsp1_rwpf_get_format,
132 .set_fmt = vsp1_rwpf_set_format, 133 .set_fmt = vsp1_rwpf_set_format,
134 .get_selection = vsp1_rwpf_get_selection,
135 .set_selection = vsp1_rwpf_set_selection,
133}; 136};
134 137
135static struct v4l2_subdev_ops wpf_ops = { 138static struct v4l2_subdev_ops wpf_ops = {
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 6ecdc39bb366..192f36f2f4aa 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -21,6 +21,12 @@ config RADIO_SI470X
21 21
22source "drivers/media/radio/si470x/Kconfig" 22source "drivers/media/radio/si470x/Kconfig"
23 23
24config RADIO_SI4713
25 tristate "Silicon Labs Si4713 FM Radio with RDS Transmitter support"
26 depends on VIDEO_V4L2
27
28source "drivers/media/radio/si4713/Kconfig"
29
24config RADIO_SI476X 30config RADIO_SI476X
25 tristate "Silicon Laboratories Si476x I2C FM Radio" 31 tristate "Silicon Laboratories Si476x I2C FM Radio"
26 depends on I2C && VIDEO_V4L2 32 depends on I2C && VIDEO_V4L2
@@ -113,29 +119,6 @@ config RADIO_SHARK2
113 To compile this driver as a module, choose M here: the 119 To compile this driver as a module, choose M here: the
114 module will be called radio-shark2. 120 module will be called radio-shark2.
115 121
116config I2C_SI4713
117 tristate "I2C driver for Silicon Labs Si4713 device"
118 depends on I2C && VIDEO_V4L2
119 ---help---
120 Say Y here if you want support to Si4713 I2C device.
121 This device driver supports only i2c bus.
122
123 To compile this driver as a module, choose M here: the
124 module will be called si4713.
125
126config RADIO_SI4713
127 tristate "Silicon Labs Si4713 FM Radio Transmitter support"
128 depends on I2C && VIDEO_V4L2
129 select I2C_SI4713
130 ---help---
131 Say Y here if you want support to Si4713 FM Radio Transmitter.
132 This device can transmit audio through FM. It can transmit
133 RDS and RBDS signals as well. This module is the v4l2 radio
134 interface for the i2c driver of this device.
135
136 To compile this driver as a module, choose M here: the
137 module will be called radio-si4713.
138
139config USB_KEENE 122config USB_KEENE
140 tristate "Keene FM Transmitter USB support" 123 tristate "Keene FM Transmitter USB support"
141 depends on USB && VIDEO_V4L2 124 depends on USB && VIDEO_V4L2
@@ -146,6 +129,20 @@ config USB_KEENE
146 To compile this driver as a module, choose M here: the 129 To compile this driver as a module, choose M here: the
147 module will be called radio-keene. 130 module will be called radio-keene.
148 131
132config USB_RAREMONO
133 tristate "Thanko's Raremono AM/FM/SW radio support"
134 depends on USB && VIDEO_V4L2
135 ---help---
136 The 'Thanko's Raremono' device contains the Si4734 chip from Silicon Labs Inc.
137 It is one of the very few or perhaps the only consumer USB radio device
138 to receive the AM/FM/SW bands.
139
140 Say Y here if you want to connect this type of AM/FM/SW receiver
141 to your computer's USB port.
142
143 To compile this driver as a module, choose M here: the
144 module will be called radio-raremono.
145
149config USB_MA901 146config USB_MA901
150 tristate "Masterkit MA901 USB FM radio support" 147 tristate "Masterkit MA901 USB FM radio support"
151 depends on USB && VIDEO_V4L2 148 depends on USB && VIDEO_V4L2
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 3b645601800d..120e791199b2 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -17,12 +17,11 @@ obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
17obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o 17obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
18obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o 18obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
19obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 19obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
20obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
21obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
22obj-$(CONFIG_RADIO_SI476X) += radio-si476x.o 20obj-$(CONFIG_RADIO_SI476X) += radio-si476x.o
23obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o 21obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
24obj-$(CONFIG_USB_DSBR) += dsbr100.o 22obj-$(CONFIG_USB_DSBR) += dsbr100.o
25obj-$(CONFIG_RADIO_SI470X) += si470x/ 23obj-$(CONFIG_RADIO_SI470X) += si470x/
24obj-$(CONFIG_RADIO_SI4713) += si4713/
26obj-$(CONFIG_USB_MR800) += radio-mr800.o 25obj-$(CONFIG_USB_MR800) += radio-mr800.o
27obj-$(CONFIG_USB_KEENE) += radio-keene.o 26obj-$(CONFIG_USB_KEENE) += radio-keene.o
28obj-$(CONFIG_USB_MA901) += radio-ma901.o 27obj-$(CONFIG_USB_MA901) += radio-ma901.o
@@ -33,6 +32,7 @@ obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
33obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o 32obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
34obj-$(CONFIG_RADIO_WL128X) += wl128x/ 33obj-$(CONFIG_RADIO_WL128X) += wl128x/
35obj-$(CONFIG_RADIO_TEA575X) += tea575x.o 34obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
35obj-$(CONFIG_USB_RAREMONO) += radio-raremono.o
36 36
37shark2-objs := radio-shark2.o radio-tea5777.o 37shark2-objs := radio-shark2.o radio-tea5777.o
38 38
diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c
new file mode 100644
index 000000000000..7b3bdbb1be73
--- /dev/null
+++ b/drivers/media/radio/radio-raremono.c
@@ -0,0 +1,387 @@
1/*
2 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/slab.h>
22#include <linux/input.h>
23#include <linux/usb.h>
24#include <linux/hid.h>
25#include <linux/mutex.h>
26#include <linux/videodev2.h>
27#include <asm/unaligned.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-ctrls.h>
31#include <media/v4l2-event.h>
32
33/*
34 * 'Thanko's Raremono' is a Japanese si4734-based AM/FM/SW USB receiver:
35 *
36 * http://www.raremono.jp/product/484.html/
37 *
38 * The USB protocol has been reversed engineered using wireshark, initially
39 * by Dinesh Ram <dinesh.ram@cern.ch> and finished by Hans Verkuil
40 * <hverkuil@xs4all.nl>.
41 *
42 * Sadly the firmware used in this product hides lots of goodies since the
43 * si4734 has more features than are supported by the firmware. Oh well...
44 */
45
46/* driver and module definitions */
47MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
48MODULE_DESCRIPTION("Thanko's Raremono AM/FM/SW Receiver USB driver");
49MODULE_LICENSE("GPL v2");
50
51/*
52 * The Device announces itself as Cygnal Integrated Products, Inc.
53 *
54 * The vendor and product IDs (and in fact all other lsusb information as
55 * well) are identical to the si470x Silicon Labs USB FM Radio Reference
56 * Design board, even though this card has a si4734 device. Clearly the
57 * designer of this product never bothered to change the USB IDs.
58 */
59
60/* USB Device ID List */
61static struct usb_device_id usb_raremono_device_table[] = {
62 {USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
63 { } /* Terminating entry */
64};
65
66MODULE_DEVICE_TABLE(usb, usb_raremono_device_table);
67
68#define BUFFER_LENGTH 64
69
70/* Timeout is set to a high value, could probably be reduced. Need more tests */
71#define USB_TIMEOUT 10000
72
73/* Frequency limits in KHz */
74#define FM_FREQ_RANGE_LOW 64000
75#define FM_FREQ_RANGE_HIGH 108000
76
77#define AM_FREQ_RANGE_LOW 520
78#define AM_FREQ_RANGE_HIGH 1710
79
80#define SW_FREQ_RANGE_LOW 2300
81#define SW_FREQ_RANGE_HIGH 26100
82
83enum { BAND_FM, BAND_AM, BAND_SW };
84
85static const struct v4l2_frequency_band bands[] = {
86 /* Band FM */
87 {
88 .type = V4L2_TUNER_RADIO,
89 .index = 0,
90 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
91 V4L2_TUNER_CAP_FREQ_BANDS,
92 .rangelow = FM_FREQ_RANGE_LOW * 16,
93 .rangehigh = FM_FREQ_RANGE_HIGH * 16,
94 .modulation = V4L2_BAND_MODULATION_FM,
95 },
96 /* Band AM */
97 {
98 .type = V4L2_TUNER_RADIO,
99 .index = 1,
100 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
101 .rangelow = AM_FREQ_RANGE_LOW * 16,
102 .rangehigh = AM_FREQ_RANGE_HIGH * 16,
103 .modulation = V4L2_BAND_MODULATION_AM,
104 },
105 /* Band SW */
106 {
107 .type = V4L2_TUNER_RADIO,
108 .index = 2,
109 .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
110 .rangelow = SW_FREQ_RANGE_LOW * 16,
111 .rangehigh = SW_FREQ_RANGE_HIGH * 16,
112 .modulation = V4L2_BAND_MODULATION_AM,
113 },
114};
115
116struct raremono_device {
117 struct usb_device *usbdev;
118 struct usb_interface *intf;
119 struct video_device vdev;
120 struct v4l2_device v4l2_dev;
121 struct mutex lock;
122
123 u8 *buffer;
124 u32 band;
125 unsigned curfreq;
126};
127
128static inline struct raremono_device *to_raremono_dev(struct v4l2_device *v4l2_dev)
129{
130 return container_of(v4l2_dev, struct raremono_device, v4l2_dev);
131}
132
133/* Set frequency. */
134static int raremono_cmd_main(struct raremono_device *radio, unsigned band, unsigned freq)
135{
136 unsigned band_offset;
137 int ret;
138
139 switch (band) {
140 case BAND_FM:
141 band_offset = 1;
142 freq /= 10;
143 break;
144 case BAND_AM:
145 band_offset = 0;
146 break;
147 default:
148 band_offset = 2;
149 break;
150 }
151 radio->buffer[0] = 0x04 + band_offset;
152 radio->buffer[1] = freq >> 8;
153 radio->buffer[2] = freq & 0xff;
154
155 ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
156 HID_REQ_SET_REPORT,
157 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
158 0x0300 + radio->buffer[0], 2,
159 radio->buffer, 3, USB_TIMEOUT);
160
161 if (ret < 0) {
162 dev_warn(radio->v4l2_dev.dev, "%s failed (%d)\n", __func__, ret);
163 return ret;
164 }
165 radio->curfreq = (band == BAND_FM) ? freq * 10 : freq;
166 return 0;
167}
168
169/* Handle unplugging the device.
170 * We call video_unregister_device in any case.
171 * The last function called in this procedure is
172 * usb_raremono_device_release.
173 */
174static void usb_raremono_disconnect(struct usb_interface *intf)
175{
176 struct raremono_device *radio = to_raremono_dev(usb_get_intfdata(intf));
177
178 dev_info(&intf->dev, "Thanko's Raremono disconnected\n");
179
180 mutex_lock(&radio->lock);
181 usb_set_intfdata(intf, NULL);
182 video_unregister_device(&radio->vdev);
183 v4l2_device_disconnect(&radio->v4l2_dev);
184 mutex_unlock(&radio->lock);
185 v4l2_device_put(&radio->v4l2_dev);
186}
187
188/*
189 * Linux Video interface
190 */
191static int vidioc_querycap(struct file *file, void *priv,
192 struct v4l2_capability *v)
193{
194 struct raremono_device *radio = video_drvdata(file);
195
196 strlcpy(v->driver, "radio-raremono", sizeof(v->driver));
197 strlcpy(v->card, "Thanko's Raremono", sizeof(v->card));
198 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
199 v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
200 v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
201 return 0;
202}
203
204static int vidioc_enum_freq_bands(struct file *file, void *priv,
205 struct v4l2_frequency_band *band)
206{
207 if (band->tuner != 0)
208 return -EINVAL;
209
210 if (band->index >= ARRAY_SIZE(bands))
211 return -EINVAL;
212
213 *band = bands[band->index];
214
215 return 0;
216}
217
218static int vidioc_g_tuner(struct file *file, void *priv,
219 struct v4l2_tuner *v)
220{
221 struct raremono_device *radio = video_drvdata(file);
222 int ret;
223
224 if (v->index > 0)
225 return -EINVAL;
226
227 strlcpy(v->name, "AM/FM/SW", sizeof(v->name));
228 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
229 V4L2_TUNER_CAP_FREQ_BANDS;
230 v->rangelow = AM_FREQ_RANGE_LOW * 16;
231 v->rangehigh = FM_FREQ_RANGE_HIGH * 16;
232 v->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
233 v->audmode = (radio->curfreq < FM_FREQ_RANGE_LOW) ?
234 V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
235 memset(radio->buffer, 1, BUFFER_LENGTH);
236 ret = usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
237 1, 0xa1, 0x030d, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
238
239 if (ret < 0) {
240 dev_warn(radio->v4l2_dev.dev, "%s failed (%d)\n", __func__, ret);
241 return ret;
242 }
243 v->signal = ((radio->buffer[1] & 0xf) << 8 | radio->buffer[2]) << 4;
244 return 0;
245}
246
247static int vidioc_s_tuner(struct file *file, void *priv,
248 const struct v4l2_tuner *v)
249{
250 return v->index ? -EINVAL : 0;
251}
252
253static int vidioc_s_frequency(struct file *file, void *priv,
254 const struct v4l2_frequency *f)
255{
256 struct raremono_device *radio = video_drvdata(file);
257 u32 freq = f->frequency;
258 unsigned band;
259
260 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
261 return -EINVAL;
262
263 if (f->frequency >= (FM_FREQ_RANGE_LOW + SW_FREQ_RANGE_HIGH) * 8)
264 band = BAND_FM;
265 else if (f->frequency <= (AM_FREQ_RANGE_HIGH + SW_FREQ_RANGE_LOW) * 8)
266 band = BAND_AM;
267 else
268 band = BAND_SW;
269
270 freq = clamp_t(u32, f->frequency, bands[band].rangelow, bands[band].rangehigh);
271 return raremono_cmd_main(radio, band, freq / 16);
272}
273
274static int vidioc_g_frequency(struct file *file, void *priv,
275 struct v4l2_frequency *f)
276{
277 struct raremono_device *radio = video_drvdata(file);
278
279 if (f->tuner != 0)
280 return -EINVAL;
281 f->type = V4L2_TUNER_RADIO;
282 f->frequency = radio->curfreq * 16;
283 return 0;
284}
285
286/* File system interface */
287static const struct v4l2_file_operations usb_raremono_fops = {
288 .owner = THIS_MODULE,
289 .open = v4l2_fh_open,
290 .release = v4l2_fh_release,
291 .unlocked_ioctl = video_ioctl2,
292};
293
294static const struct v4l2_ioctl_ops usb_raremono_ioctl_ops = {
295 .vidioc_querycap = vidioc_querycap,
296 .vidioc_g_tuner = vidioc_g_tuner,
297 .vidioc_s_tuner = vidioc_s_tuner,
298 .vidioc_g_frequency = vidioc_g_frequency,
299 .vidioc_s_frequency = vidioc_s_frequency,
300 .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
301};
302
303/* check if the device is present and register with v4l and usb if it is */
304static int usb_raremono_probe(struct usb_interface *intf,
305 const struct usb_device_id *id)
306{
307 struct raremono_device *radio;
308 int retval = 0;
309
310 radio = devm_kzalloc(&intf->dev, sizeof(struct raremono_device), GFP_KERNEL);
311 if (radio)
312 radio->buffer = devm_kmalloc(&intf->dev, BUFFER_LENGTH, GFP_KERNEL);
313
314 if (!radio || !radio->buffer)
315 return -ENOMEM;
316
317 radio->usbdev = interface_to_usbdev(intf);
318 radio->intf = intf;
319
320 /*
321 * This device uses the same USB IDs as the si470x SiLabs reference
322 * design. So do an additional check: attempt to read the device ID
323 * from the si470x: the lower 12 bits are 0x0242 for the si470x. The
324 * Raremono always returns 0x0800 (the meaning of that is unknown, but
325 * at least it works).
326 *
327 * We use this check to determine which device we are dealing with.
328 */
329 msleep(20);
330 retval = usb_control_msg(radio->usbdev,
331 usb_rcvctrlpipe(radio->usbdev, 0),
332 HID_REQ_GET_REPORT,
333 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
334 1, 2,
335 radio->buffer, 3, 500);
336 if (retval != 3 ||
337 (get_unaligned_be16(&radio->buffer[1]) & 0xfff) == 0x0242) {
338 dev_info(&intf->dev, "this is not Thanko's Raremono.\n");
339 return -ENODEV;
340 }
341
342 dev_info(&intf->dev, "Thanko's Raremono connected: (%04X:%04X)\n",
343 id->idVendor, id->idProduct);
344
345 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
346 if (retval < 0) {
347 dev_err(&intf->dev, "couldn't register v4l2_device\n");
348 return retval;
349 }
350
351 mutex_init(&radio->lock);
352
353 strlcpy(radio->vdev.name, radio->v4l2_dev.name,
354 sizeof(radio->vdev.name));
355 radio->vdev.v4l2_dev = &radio->v4l2_dev;
356 radio->vdev.fops = &usb_raremono_fops;
357 radio->vdev.ioctl_ops = &usb_raremono_ioctl_ops;
358 radio->vdev.lock = &radio->lock;
359 radio->vdev.release = video_device_release_empty;
360
361 usb_set_intfdata(intf, &radio->v4l2_dev);
362
363 video_set_drvdata(&radio->vdev, radio);
364 set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
365
366 raremono_cmd_main(radio, BAND_FM, 95160);
367
368 retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
369 if (retval == 0) {
370 dev_info(&intf->dev, "V4L2 device registered as %s\n",
371 video_device_node_name(&radio->vdev));
372 return 0;
373 }
374 dev_err(&intf->dev, "could not register video device\n");
375 v4l2_device_unregister(&radio->v4l2_dev);
376 return retval;
377}
378
379/* USB subsystem interface */
380static struct usb_driver usb_raremono_driver = {
381 .name = "radio-raremono",
382 .probe = usb_raremono_probe,
383 .disconnect = usb_raremono_disconnect,
384 .id_table = usb_raremono_device_table,
385};
386
387module_usb_driver(usb_raremono_driver);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index d6d4d60261d5..07ef40595efd 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -137,6 +137,8 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
137/* interrupt out endpoint 2 every 1 millisecond */ 137/* interrupt out endpoint 2 every 1 millisecond */
138#define UNUSED_REPORT 23 138#define UNUSED_REPORT 23
139 139
140#define MAX_REPORT_SIZE 64
141
140 142
141 143
142/************************************************************************** 144/**************************************************************************
@@ -208,7 +210,7 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
208 */ 210 */
209static int si470x_get_report(struct si470x_device *radio, void *buf, int size) 211static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
210{ 212{
211 unsigned char *report = (unsigned char *) buf; 213 unsigned char *report = buf;
212 int retval; 214 int retval;
213 215
214 retval = usb_control_msg(radio->usbdev, 216 retval = usb_control_msg(radio->usbdev,
@@ -231,7 +233,7 @@ static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
231 */ 233 */
232static int si470x_set_report(struct si470x_device *radio, void *buf, int size) 234static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
233{ 235{
234 unsigned char *report = (unsigned char *) buf; 236 unsigned char *report = buf;
235 int retval; 237 int retval;
236 238
237 retval = usb_control_msg(radio->usbdev, 239 retval = usb_control_msg(radio->usbdev,
@@ -254,15 +256,14 @@ static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
254 */ 256 */
255int si470x_get_register(struct si470x_device *radio, int regnr) 257int si470x_get_register(struct si470x_device *radio, int regnr)
256{ 258{
257 unsigned char buf[REGISTER_REPORT_SIZE];
258 int retval; 259 int retval;
259 260
260 buf[0] = REGISTER_REPORT(regnr); 261 radio->usb_buf[0] = REGISTER_REPORT(regnr);
261 262
262 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); 263 retval = si470x_get_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE);
263 264
264 if (retval >= 0) 265 if (retval >= 0)
265 radio->registers[regnr] = get_unaligned_be16(&buf[1]); 266 radio->registers[regnr] = get_unaligned_be16(&radio->usb_buf[1]);
266 267
267 return (retval < 0) ? -EINVAL : 0; 268 return (retval < 0) ? -EINVAL : 0;
268} 269}
@@ -273,13 +274,12 @@ int si470x_get_register(struct si470x_device *radio, int regnr)
273 */ 274 */
274int si470x_set_register(struct si470x_device *radio, int regnr) 275int si470x_set_register(struct si470x_device *radio, int regnr)
275{ 276{
276 unsigned char buf[REGISTER_REPORT_SIZE];
277 int retval; 277 int retval;
278 278
279 buf[0] = REGISTER_REPORT(regnr); 279 radio->usb_buf[0] = REGISTER_REPORT(regnr);
280 put_unaligned_be16(radio->registers[regnr], &buf[1]); 280 put_unaligned_be16(radio->registers[regnr], &radio->usb_buf[1]);
281 281
282 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); 282 retval = si470x_set_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE);
283 283
284 return (retval < 0) ? -EINVAL : 0; 284 return (retval < 0) ? -EINVAL : 0;
285} 285}
@@ -295,18 +295,17 @@ int si470x_set_register(struct si470x_device *radio, int regnr)
295 */ 295 */
296static int si470x_get_all_registers(struct si470x_device *radio) 296static int si470x_get_all_registers(struct si470x_device *radio)
297{ 297{
298 unsigned char buf[ENTIRE_REPORT_SIZE];
299 int retval; 298 int retval;
300 unsigned char regnr; 299 unsigned char regnr;
301 300
302 buf[0] = ENTIRE_REPORT; 301 radio->usb_buf[0] = ENTIRE_REPORT;
303 302
304 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); 303 retval = si470x_get_report(radio, radio->usb_buf, ENTIRE_REPORT_SIZE);
305 304
306 if (retval >= 0) 305 if (retval >= 0)
307 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) 306 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
308 radio->registers[regnr] = get_unaligned_be16( 307 radio->registers[regnr] = get_unaligned_be16(
309 &buf[regnr * RADIO_REGISTER_SIZE + 1]); 308 &radio->usb_buf[regnr * RADIO_REGISTER_SIZE + 1]);
310 309
311 return (retval < 0) ? -EINVAL : 0; 310 return (retval < 0) ? -EINVAL : 0;
312} 311}
@@ -323,14 +322,13 @@ static int si470x_get_all_registers(struct si470x_device *radio)
323static int si470x_set_led_state(struct si470x_device *radio, 322static int si470x_set_led_state(struct si470x_device *radio,
324 unsigned char led_state) 323 unsigned char led_state)
325{ 324{
326 unsigned char buf[LED_REPORT_SIZE];
327 int retval; 325 int retval;
328 326
329 buf[0] = LED_REPORT; 327 radio->usb_buf[0] = LED_REPORT;
330 buf[1] = LED_COMMAND; 328 radio->usb_buf[1] = LED_COMMAND;
331 buf[2] = led_state; 329 radio->usb_buf[2] = led_state;
332 330
333 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); 331 retval = si470x_set_report(radio, radio->usb_buf, LED_REPORT_SIZE);
334 332
335 return (retval < 0) ? -EINVAL : 0; 333 return (retval < 0) ? -EINVAL : 0;
336} 334}
@@ -346,19 +344,18 @@ static int si470x_set_led_state(struct si470x_device *radio,
346 */ 344 */
347static int si470x_get_scratch_page_versions(struct si470x_device *radio) 345static int si470x_get_scratch_page_versions(struct si470x_device *radio)
348{ 346{
349 unsigned char buf[SCRATCH_REPORT_SIZE];
350 int retval; 347 int retval;
351 348
352 buf[0] = SCRATCH_REPORT; 349 radio->usb_buf[0] = SCRATCH_REPORT;
353 350
354 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); 351 retval = si470x_get_report(radio, radio->usb_buf, SCRATCH_REPORT_SIZE);
355 352
356 if (retval < 0) 353 if (retval < 0)
357 dev_warn(&radio->intf->dev, "si470x_get_scratch: " 354 dev_warn(&radio->intf->dev, "si470x_get_scratch: "
358 "si470x_get_report returned %d\n", retval); 355 "si470x_get_report returned %d\n", retval);
359 else { 356 else {
360 radio->software_version = buf[1]; 357 radio->software_version = radio->usb_buf[1];
361 radio->hardware_version = buf[2]; 358 radio->hardware_version = radio->usb_buf[2];
362 } 359 }
363 360
364 return (retval < 0) ? -EINVAL : 0; 361 return (retval < 0) ? -EINVAL : 0;
@@ -509,6 +506,7 @@ static void si470x_usb_release(struct v4l2_device *v4l2_dev)
509 v4l2_device_unregister(&radio->v4l2_dev); 506 v4l2_device_unregister(&radio->v4l2_dev);
510 kfree(radio->int_in_buffer); 507 kfree(radio->int_in_buffer);
511 kfree(radio->buffer); 508 kfree(radio->buffer);
509 kfree(radio->usb_buf);
512 kfree(radio); 510 kfree(radio);
513} 511}
514 512
@@ -593,6 +591,11 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
593 retval = -ENOMEM; 591 retval = -ENOMEM;
594 goto err_initial; 592 goto err_initial;
595 } 593 }
594 radio->usb_buf = kmalloc(MAX_REPORT_SIZE, GFP_KERNEL);
595 if (radio->usb_buf == NULL) {
596 retval = -ENOMEM;
597 goto err_radio;
598 }
596 radio->usbdev = interface_to_usbdev(intf); 599 radio->usbdev = interface_to_usbdev(intf);
597 radio->intf = intf; 600 radio->intf = intf;
598 radio->band = 1; /* Default to 76 - 108 MHz */ 601 radio->band = 1; /* Default to 76 - 108 MHz */
@@ -612,7 +615,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
612 if (!radio->int_in_endpoint) { 615 if (!radio->int_in_endpoint) {
613 dev_info(&intf->dev, "could not find interrupt in endpoint\n"); 616 dev_info(&intf->dev, "could not find interrupt in endpoint\n");
614 retval = -EIO; 617 retval = -EIO;
615 goto err_radio; 618 goto err_usbbuf;
616 } 619 }
617 620
618 int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize); 621 int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
@@ -621,7 +624,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
621 if (!radio->int_in_buffer) { 624 if (!radio->int_in_buffer) {
622 dev_info(&intf->dev, "could not allocate int_in_buffer"); 625 dev_info(&intf->dev, "could not allocate int_in_buffer");
623 retval = -ENOMEM; 626 retval = -ENOMEM;
624 goto err_radio; 627 goto err_usbbuf;
625 } 628 }
626 629
627 radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); 630 radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -632,6 +635,30 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
632 } 635 }
633 636
634 radio->v4l2_dev.release = si470x_usb_release; 637 radio->v4l2_dev.release = si470x_usb_release;
638
639 /*
640 * The si470x SiLabs reference design uses the same USB IDs as
641 * 'Thanko's Raremono' si4734 based receiver. So check here which we
642 * have: attempt to read the device ID from the si470x: the lower 12
643 * bits should be 0x0242 for the si470x.
644 *
645 * We use this check to determine which device we are dealing with.
646 */
647 if (id->idVendor == 0x10c4 && id->idProduct == 0x818a) {
648 retval = usb_control_msg(radio->usbdev,
649 usb_rcvctrlpipe(radio->usbdev, 0),
650 HID_REQ_GET_REPORT,
651 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
652 1, 2,
653 radio->usb_buf, 3, 500);
654 if (retval != 3 ||
655 (get_unaligned_be16(&radio->usb_buf[1]) & 0xfff) != 0x0242) {
656 dev_info(&intf->dev, "this is not a si470x device.\n");
657 retval = -ENODEV;
658 goto err_urb;
659 }
660 }
661
635 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev); 662 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
636 if (retval < 0) { 663 if (retval < 0) {
637 dev_err(&intf->dev, "couldn't register v4l2_device\n"); 664 dev_err(&intf->dev, "couldn't register v4l2_device\n");
@@ -743,6 +770,8 @@ err_urb:
743 usb_free_urb(radio->int_in_urb); 770 usb_free_urb(radio->int_in_urb);
744err_intbuffer: 771err_intbuffer:
745 kfree(radio->int_in_buffer); 772 kfree(radio->int_in_buffer);
773err_usbbuf:
774 kfree(radio->usb_buf);
746err_radio: 775err_radio:
747 kfree(radio); 776 kfree(radio);
748err_initial: 777err_initial:
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index 467e95575488..4b7660470e2f 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -167,6 +167,7 @@ struct si470x_device {
167 /* reference to USB and video device */ 167 /* reference to USB and video device */
168 struct usb_device *usbdev; 168 struct usb_device *usbdev;
169 struct usb_interface *intf; 169 struct usb_interface *intf;
170 char *usb_buf;
170 171
171 /* Interrupt endpoint handling */ 172 /* Interrupt endpoint handling */
172 char *int_in_buffer; 173 char *int_in_buffer;
diff --git a/drivers/media/radio/si4713/Kconfig b/drivers/media/radio/si4713/Kconfig
new file mode 100644
index 000000000000..a7c3ba85d12b
--- /dev/null
+++ b/drivers/media/radio/si4713/Kconfig
@@ -0,0 +1,40 @@
1config USB_SI4713
2 tristate "Silicon Labs Si4713 FM Radio Transmitter support with USB"
3 depends on USB && RADIO_SI4713
4 select SI4713
5 ---help---
6 This is a driver for USB devices with the Silicon Labs SI4713
7 chip. Currently these devices are known to work.
8 - 10c4:8244: Silicon Labs FM Transmitter USB device.
9
10 Say Y here if you want to connect this type of radio to your
11 computer's USB port.
12
13 To compile this driver as a module, choose M here: the
14 module will be called radio-usb-si4713.
15
16config PLATFORM_SI4713
17 tristate "Silicon Labs Si4713 FM Radio Transmitter support with I2C"
18 depends on I2C && RADIO_SI4713
19 select SI4713
20 ---help---
21 This is a driver for I2C devices with the Silicon Labs SI4713
22 chip.
23
24 Say Y here if you want to connect this type of radio to your
25 computer's I2C port.
26
27 To compile this driver as a module, choose M here: the
28 module will be called radio-platform-si4713.
29
30config I2C_SI4713
31 tristate "Silicon Labs Si4713 FM Radio Transmitter support"
32 depends on I2C && RADIO_SI4713
33 ---help---
34 Say Y here if you want support to Si4713 FM Radio Transmitter.
35 This device can transmit audio through FM. It can transmit
36 RDS and RBDS signals as well. This module is the v4l2 radio
37 interface for the i2c driver of this device.
38
39 To compile this driver as a module, choose M here: the
40 module will be called si4713.
diff --git a/drivers/media/radio/si4713/Makefile b/drivers/media/radio/si4713/Makefile
new file mode 100644
index 000000000000..ddaaf925e883
--- /dev/null
+++ b/drivers/media/radio/si4713/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for radios with Silicon Labs Si4713 FM Radio Transmitters
3#
4
5obj-$(CONFIG_I2C_SI4713) += si4713.o
6obj-$(CONFIG_USB_SI4713) += radio-usb-si4713.o
7obj-$(CONFIG_PLATFORM_SI4713) += radio-platform-si4713.o
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c
index ba4cfc946868..ba4cfc946868 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/si4713/radio-platform-si4713.c
diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c
new file mode 100644
index 000000000000..779855b74bcd
--- /dev/null
+++ b/drivers/media/radio/si4713/radio-usb-si4713.c
@@ -0,0 +1,540 @@
1/*
2 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
3 * All rights reserved.
4 *
5 * This program is free software; you may redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 * SOFTWARE.
17 */
18
19/* kernel includes */
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/usb.h>
23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/input.h>
26#include <linux/mutex.h>
27#include <linux/i2c.h>
28/* V4l includes */
29#include <linux/videodev2.h>
30#include <media/v4l2-common.h>
31#include <media/v4l2-device.h>
32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-event.h>
34#include <media/si4713.h>
35
36#include "si4713.h"
37
38/* driver and module definitions */
39MODULE_AUTHOR("Dinesh Ram <dinesh.ram@cern.ch>");
40MODULE_DESCRIPTION("Si4713 FM Transmitter USB driver");
41MODULE_LICENSE("GPL v2");
42
43/* The Device announces itself as Cygnal Integrated Products, Inc. */
44#define USB_SI4713_VENDOR 0x10c4
45#define USB_SI4713_PRODUCT 0x8244
46
47#define BUFFER_LENGTH 64
48#define USB_TIMEOUT 1000
49#define USB_RESP_TIMEOUT 50000
50
51/* USB Device ID List */
52static struct usb_device_id usb_si4713_usb_device_table[] = {
53 {USB_DEVICE_AND_INTERFACE_INFO(USB_SI4713_VENDOR, USB_SI4713_PRODUCT,
54 USB_CLASS_HID, 0, 0) },
55 { } /* Terminating entry */
56};
57
58MODULE_DEVICE_TABLE(usb, usb_si4713_usb_device_table);
59
60struct si4713_usb_device {
61 struct usb_device *usbdev;
62 struct usb_interface *intf;
63 struct video_device vdev;
64 struct v4l2_device v4l2_dev;
65 struct v4l2_subdev *v4l2_subdev;
66 struct mutex lock;
67 struct i2c_adapter i2c_adapter;
68
69 u8 *buffer;
70};
71
72static inline struct si4713_usb_device *to_si4713_dev(struct v4l2_device *v4l2_dev)
73{
74 return container_of(v4l2_dev, struct si4713_usb_device, v4l2_dev);
75}
76
77static int vidioc_querycap(struct file *file, void *priv,
78 struct v4l2_capability *v)
79{
80 struct si4713_usb_device *radio = video_drvdata(file);
81
82 strlcpy(v->driver, "radio-usb-si4713", sizeof(v->driver));
83 strlcpy(v->card, "Si4713 FM Transmitter", sizeof(v->card));
84 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
85 v->device_caps = V4L2_CAP_MODULATOR | V4L2_CAP_RDS_OUTPUT;
86 v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
87
88 return 0;
89}
90
91static int vidioc_g_modulator(struct file *file, void *priv,
92 struct v4l2_modulator *vm)
93{
94 struct si4713_usb_device *radio = video_drvdata(file);
95
96 return v4l2_subdev_call(radio->v4l2_subdev, tuner, g_modulator, vm);
97}
98
99static int vidioc_s_modulator(struct file *file, void *priv,
100 const struct v4l2_modulator *vm)
101{
102 struct si4713_usb_device *radio = video_drvdata(file);
103
104 return v4l2_subdev_call(radio->v4l2_subdev, tuner, s_modulator, vm);
105}
106
107static int vidioc_s_frequency(struct file *file, void *priv,
108 const struct v4l2_frequency *vf)
109{
110 struct si4713_usb_device *radio = video_drvdata(file);
111
112 return v4l2_subdev_call(radio->v4l2_subdev, tuner, s_frequency, vf);
113}
114
115static int vidioc_g_frequency(struct file *file, void *priv,
116 struct v4l2_frequency *vf)
117{
118 struct si4713_usb_device *radio = video_drvdata(file);
119
120 return v4l2_subdev_call(radio->v4l2_subdev, tuner, g_frequency, vf);
121}
122
123static const struct v4l2_ioctl_ops usb_si4713_ioctl_ops = {
124 .vidioc_querycap = vidioc_querycap,
125 .vidioc_g_modulator = vidioc_g_modulator,
126 .vidioc_s_modulator = vidioc_s_modulator,
127 .vidioc_g_frequency = vidioc_g_frequency,
128 .vidioc_s_frequency = vidioc_s_frequency,
129 .vidioc_log_status = v4l2_ctrl_log_status,
130 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
131 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
132};
133
134/* File system interface */
135static const struct v4l2_file_operations usb_si4713_fops = {
136 .owner = THIS_MODULE,
137 .open = v4l2_fh_open,
138 .release = v4l2_fh_release,
139 .poll = v4l2_ctrl_poll,
140 .unlocked_ioctl = video_ioctl2,
141};
142
143static void usb_si4713_video_device_release(struct v4l2_device *v4l2_dev)
144{
145 struct si4713_usb_device *radio = to_si4713_dev(v4l2_dev);
146 struct i2c_adapter *adapter = &radio->i2c_adapter;
147
148 i2c_del_adapter(adapter);
149 v4l2_device_unregister(&radio->v4l2_dev);
150 kfree(radio->buffer);
151 kfree(radio);
152}
153
154/*
155 * This command sequence emulates the behaviour of the Windows driver.
156 * The structure of these commands was determined by sniffing the
157 * usb traffic of the device during startup.
158 * Most likely, these commands make some queries to the device.
159 * Commands are sent to enquire parameters like the bus mode,
160 * component revision, boot mode, the device serial number etc.
161 *
162 * These commands are necessary to be sent in this order during startup.
163 * The device fails to powerup if these commands are not sent.
164 *
165 * The complete list of startup commands is given in the start_seq table below.
166 */
167static int si4713_send_startup_command(struct si4713_usb_device *radio)
168{
169 unsigned long until_jiffies = jiffies + usecs_to_jiffies(USB_RESP_TIMEOUT) + 1;
170 u8 *buffer = radio->buffer;
171 int retval;
172
173 /* send the command */
174 retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
175 0x09, 0x21, 0x033f, 0, radio->buffer,
176 BUFFER_LENGTH, USB_TIMEOUT);
177 if (retval < 0)
178 return retval;
179
180 for (;;) {
181 /* receive the response */
182 retval = usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
183 0x01, 0xa1, 0x033f, 0, radio->buffer,
184 BUFFER_LENGTH, USB_TIMEOUT);
185 if (retval < 0)
186 return retval;
187 if (!radio->buffer[1]) {
188 /* USB traffic sniffing showed that some commands require
189 * additional checks. */
190 switch (buffer[1]) {
191 case 0x32:
192 if (radio->buffer[2] == 0)
193 return 0;
194 break;
195 case 0x14:
196 case 0x12:
197 if (radio->buffer[2] & SI4713_CTS)
198 return 0;
199 break;
200 case 0x06:
201 if ((radio->buffer[2] & SI4713_CTS) && radio->buffer[9] == 0x08)
202 return 0;
203 break;
204 default:
205 return 0;
206 }
207 }
208 if (time_is_before_jiffies(until_jiffies))
209 return -EIO;
210 msleep(3);
211 }
212
213 return retval;
214}
215
216struct si4713_start_seq_table {
217 int len;
218 u8 payload[8];
219};
220
221/*
222 * Some of the startup commands that could be recognized are :
223 * (0x03): Get serial number of the board (Response : CB000-00-00)
224 * (0x06, 0x03, 0x03, 0x08, 0x01, 0x0f) : Get Component revision
225 */
226static struct si4713_start_seq_table start_seq[] = {
227
228 { 1, { 0x03 } },
229 { 2, { 0x32, 0x7f } },
230 { 6, { 0x06, 0x03, 0x03, 0x08, 0x01, 0x0f } },
231 { 2, { 0x14, 0x02 } },
232 { 2, { 0x09, 0x90 } },
233 { 3, { 0x08, 0x90, 0xfa } },
234 { 2, { 0x36, 0x01 } },
235 { 2, { 0x05, 0x03 } },
236 { 7, { 0x06, 0x00, 0x06, 0x0e, 0x01, 0x0f, 0x05 } },
237 { 1, { 0x12 } },
238 /* Commands that are sent after pressing the 'Initialize'
239 button in the windows application */
240 { 1, { 0x03 } },
241 { 1, { 0x01 } },
242 { 2, { 0x09, 0x90 } },
243 { 3, { 0x08, 0x90, 0xfa } },
244 { 1, { 0x34 } },
245 { 2, { 0x35, 0x01 } },
246 { 2, { 0x36, 0x01 } },
247 { 2, { 0x30, 0x09 } },
248 { 4, { 0x30, 0x06, 0x00, 0xe2 } },
249 { 3, { 0x31, 0x01, 0x30 } },
250 { 3, { 0x31, 0x04, 0x09 } },
251 { 2, { 0x05, 0x02 } },
252 { 6, { 0x06, 0x03, 0x03, 0x08, 0x01, 0x0f } },
253};
254
255static int si4713_start_seq(struct si4713_usb_device *radio)
256{
257 int retval = 0;
258 int i;
259
260 radio->buffer[0] = 0x3f;
261
262 for (i = 0; i < ARRAY_SIZE(start_seq); i++) {
263 int len = start_seq[i].len;
264 u8 *payload = start_seq[i].payload;
265
266 memcpy(radio->buffer + 1, payload, len);
267 memset(radio->buffer + len + 1, 0, BUFFER_LENGTH - 1 - len);
268 retval = si4713_send_startup_command(radio);
269 }
270
271 return retval;
272}
273
274static struct i2c_board_info si4713_board_info = {
275 I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
276};
277
278struct si4713_command_table {
279 int command_id;
280 u8 payload[8];
281};
282
283/*
284 * Structure of a command :
285 * Byte 1 : 0x3f (always)
286 * Byte 2 : 0x06 (send a command)
287 * Byte 3 : Unknown
288 * Byte 4 : Number of arguments + 1 (for the command byte)
289 * Byte 5 : Number of response bytes
290 */
291static struct si4713_command_table command_table[] = {
292
293 { SI4713_CMD_POWER_UP, { 0x00, SI4713_PWUP_NARGS + 1, SI4713_PWUP_NRESP} },
294 { SI4713_CMD_GET_REV, { 0x03, 0x01, SI4713_GETREV_NRESP } },
295 { SI4713_CMD_POWER_DOWN, { 0x00, 0x01, SI4713_PWDN_NRESP} },
296 { SI4713_CMD_SET_PROPERTY, { 0x00, SI4713_SET_PROP_NARGS + 1, SI4713_SET_PROP_NRESP } },
297 { SI4713_CMD_GET_PROPERTY, { 0x00, SI4713_GET_PROP_NARGS + 1, SI4713_GET_PROP_NRESP } },
298 { SI4713_CMD_TX_TUNE_FREQ, { 0x03, SI4713_TXFREQ_NARGS + 1, SI4713_TXFREQ_NRESP } },
299 { SI4713_CMD_TX_TUNE_POWER, { 0x03, SI4713_TXPWR_NARGS + 1, SI4713_TXPWR_NRESP } },
300 { SI4713_CMD_TX_TUNE_MEASURE, { 0x03, SI4713_TXMEA_NARGS + 1, SI4713_TXMEA_NRESP } },
301 { SI4713_CMD_TX_TUNE_STATUS, { 0x00, SI4713_TXSTATUS_NARGS + 1, SI4713_TXSTATUS_NRESP } },
302 { SI4713_CMD_TX_ASQ_STATUS, { 0x03, SI4713_ASQSTATUS_NARGS + 1, SI4713_ASQSTATUS_NRESP } },
303 { SI4713_CMD_GET_INT_STATUS, { 0x03, 0x01, SI4713_GET_STATUS_NRESP } },
304 { SI4713_CMD_TX_RDS_BUFF, { 0x03, SI4713_RDSBUFF_NARGS + 1, SI4713_RDSBUFF_NRESP } },
305 { SI4713_CMD_TX_RDS_PS, { 0x00, SI4713_RDSPS_NARGS + 1, SI4713_RDSPS_NRESP } },
306};
307
308static int send_command(struct si4713_usb_device *radio, u8 *payload, char *data, int len)
309{
310 int retval;
311
312 radio->buffer[0] = 0x3f;
313 radio->buffer[1] = 0x06;
314
315 memcpy(radio->buffer + 2, payload, 3);
316 memcpy(radio->buffer + 5, data, len);
317 memset(radio->buffer + 5 + len, 0, BUFFER_LENGTH - 5 - len);
318
319 /* send the command */
320 retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
321 0x09, 0x21, 0x033f, 0, radio->buffer,
322 BUFFER_LENGTH, USB_TIMEOUT);
323
324 return retval < 0 ? retval : 0;
325}
326
327static int si4713_i2c_read(struct si4713_usb_device *radio, char *data, int len)
328{
329 unsigned long until_jiffies = jiffies + usecs_to_jiffies(USB_RESP_TIMEOUT) + 1;
330 int retval;
331
332 /* receive the response */
333 for (;;) {
334 retval = usb_control_msg(radio->usbdev,
335 usb_rcvctrlpipe(radio->usbdev, 0),
336 0x01, 0xa1, 0x033f, 0, radio->buffer,
337 BUFFER_LENGTH, USB_TIMEOUT);
338 if (retval < 0)
339 return retval;
340
341 /*
342 * Check that we get a valid reply back (buffer[1] == 0) and
343 * that CTS is set before returning, otherwise we wait and try
344 * again. The i2c driver also does the CTS check, but the timeouts
345 * used there are much too small for this USB driver, so we wait
346 * for it here.
347 */
348 if (radio->buffer[1] == 0 && (radio->buffer[2] & SI4713_CTS)) {
349 memcpy(data, radio->buffer + 2, len);
350 return 0;
351 }
352 if (time_is_before_jiffies(until_jiffies)) {
353 /* Zero the status value, ensuring CTS isn't set */
354 data[0] = 0;
355 return 0;
356 }
357 msleep(3);
358 }
359}
360
361static int si4713_i2c_write(struct si4713_usb_device *radio, char *data, int len)
362{
363 int retval = -EINVAL;
364 int i;
365
366 if (len > BUFFER_LENGTH - 5)
367 return -EINVAL;
368
369 for (i = 0; i < ARRAY_SIZE(command_table); i++) {
370 if (data[0] == command_table[i].command_id)
371 retval = send_command(radio, command_table[i].payload,
372 data, len);
373 }
374
375 return retval < 0 ? retval : 0;
376}
377
378static int si4713_transfer(struct i2c_adapter *i2c_adapter,
379 struct i2c_msg *msgs, int num)
380{
381 struct si4713_usb_device *radio = i2c_get_adapdata(i2c_adapter);
382 int retval = -EINVAL;
383 int i;
384
385 if (num <= 0)
386 return 0;
387
388 for (i = 0; i < num; i++) {
389 if (msgs[i].flags & I2C_M_RD)
390 retval = si4713_i2c_read(radio, msgs[i].buf, msgs[i].len);
391 else
392 retval = si4713_i2c_write(radio, msgs[i].buf, msgs[i].len);
393 if (retval)
394 break;
395 }
396
397 return retval ? retval : num;
398}
399
400static u32 si4713_functionality(struct i2c_adapter *adapter)
401{
402 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
403}
404
405static struct i2c_algorithm si4713_algo = {
406 .master_xfer = si4713_transfer,
407 .functionality = si4713_functionality,
408};
409
410/* This name value shows up in the sysfs filename associated
411 with this I2C adapter */
412static struct i2c_adapter si4713_i2c_adapter_template = {
413 .name = "si4713-i2c",
414 .owner = THIS_MODULE,
415 .algo = &si4713_algo,
416};
417
418static int si4713_register_i2c_adapter(struct si4713_usb_device *radio)
419{
420 radio->i2c_adapter = si4713_i2c_adapter_template;
421 /* set up sysfs linkage to our parent device */
422 radio->i2c_adapter.dev.parent = &radio->usbdev->dev;
423 i2c_set_adapdata(&radio->i2c_adapter, radio);
424
425 return i2c_add_adapter(&radio->i2c_adapter);
426}
427
428/* check if the device is present and register with v4l and usb if it is */
429static int usb_si4713_probe(struct usb_interface *intf,
430 const struct usb_device_id *id)
431{
432 struct si4713_usb_device *radio;
433 struct i2c_adapter *adapter;
434 struct v4l2_subdev *sd;
435 int retval = -ENOMEM;
436
437 dev_info(&intf->dev, "Si4713 development board discovered: (%04X:%04X)\n",
438 id->idVendor, id->idProduct);
439
440 /* Initialize local device structure */
441 radio = kzalloc(sizeof(struct si4713_usb_device), GFP_KERNEL);
442 if (radio)
443 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
444
445 if (!radio || !radio->buffer) {
446 dev_err(&intf->dev, "kmalloc for si4713_usb_device failed\n");
447 kfree(radio);
448 return -ENOMEM;
449 }
450
451 mutex_init(&radio->lock);
452
453 radio->usbdev = interface_to_usbdev(intf);
454 radio->intf = intf;
455 usb_set_intfdata(intf, &radio->v4l2_dev);
456
457 retval = si4713_start_seq(radio);
458 if (retval < 0)
459 goto err_v4l2;
460
461 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
462 if (retval < 0) {
463 dev_err(&intf->dev, "couldn't register v4l2_device\n");
464 goto err_v4l2;
465 }
466
467 retval = si4713_register_i2c_adapter(radio);
468 if (retval < 0) {
469 dev_err(&intf->dev, "could not register i2c device\n");
470 goto err_i2cdev;
471 }
472
473 adapter = &radio->i2c_adapter;
474 sd = v4l2_i2c_new_subdev_board(&radio->v4l2_dev, adapter,
475 &si4713_board_info, NULL);
476 radio->v4l2_subdev = sd;
477 if (!sd) {
478 dev_err(&intf->dev, "cannot get v4l2 subdevice\n");
479 retval = -ENODEV;
480 goto del_adapter;
481 }
482
483 radio->vdev.ctrl_handler = sd->ctrl_handler;
484 radio->v4l2_dev.release = usb_si4713_video_device_release;
485 strlcpy(radio->vdev.name, radio->v4l2_dev.name,
486 sizeof(radio->vdev.name));
487 radio->vdev.v4l2_dev = &radio->v4l2_dev;
488 radio->vdev.fops = &usb_si4713_fops;
489 radio->vdev.ioctl_ops = &usb_si4713_ioctl_ops;
490 radio->vdev.lock = &radio->lock;
491 radio->vdev.release = video_device_release_empty;
492 radio->vdev.vfl_dir = VFL_DIR_TX;
493
494 video_set_drvdata(&radio->vdev, radio);
495 set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
496
497 retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
498 if (retval < 0) {
499 dev_err(&intf->dev, "could not register video device\n");
500 goto del_adapter;
501 }
502
503 dev_info(&intf->dev, "V4L2 device registered as %s\n",
504 video_device_node_name(&radio->vdev));
505
506 return 0;
507
508del_adapter:
509 i2c_del_adapter(adapter);
510err_i2cdev:
511 v4l2_device_unregister(&radio->v4l2_dev);
512err_v4l2:
513 kfree(radio->buffer);
514 kfree(radio);
515 return retval;
516}
517
518static void usb_si4713_disconnect(struct usb_interface *intf)
519{
520 struct si4713_usb_device *radio = to_si4713_dev(usb_get_intfdata(intf));
521
522 dev_info(&intf->dev, "Si4713 development board now disconnected\n");
523
524 mutex_lock(&radio->lock);
525 usb_set_intfdata(intf, NULL);
526 video_unregister_device(&radio->vdev);
527 v4l2_device_disconnect(&radio->v4l2_dev);
528 mutex_unlock(&radio->lock);
529 v4l2_device_put(&radio->v4l2_dev);
530}
531
532/* USB subsystem interface */
533static struct usb_driver usb_si4713_driver = {
534 .name = "radio-usb-si4713",
535 .probe = usb_si4713_probe,
536 .disconnect = usb_si4713_disconnect,
537 .id_table = usb_si4713_usb_device_table,
538};
539
540module_usb_driver(usb_si4713_driver);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713/si4713.c
index 9ec48ccbcf0b..07d5153811e8 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713/si4713.c
@@ -27,13 +27,12 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/gpio.h> 29#include <linux/gpio.h>
30#include <linux/regulator/consumer.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <media/v4l2-device.h> 31#include <media/v4l2-device.h>
33#include <media/v4l2-ioctl.h> 32#include <media/v4l2-ioctl.h>
34#include <media/v4l2-common.h> 33#include <media/v4l2-common.h>
35 34
36#include "si4713-i2c.h" 35#include "si4713.h"
37 36
38/* module parameters */ 37/* module parameters */
39static int debug; 38static int debug;
@@ -45,23 +44,18 @@ MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
45MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter"); 44MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
46MODULE_VERSION("0.0.1"); 45MODULE_VERSION("0.0.1");
47 46
48static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = {
49 "vio",
50 "vdd",
51};
52
53#define DEFAULT_RDS_PI 0x00 47#define DEFAULT_RDS_PI 0x00
54#define DEFAULT_RDS_PTY 0x00 48#define DEFAULT_RDS_PTY 0x00
55#define DEFAULT_RDS_DEVIATION 0x00C8 49#define DEFAULT_RDS_DEVIATION 0x00C8
56#define DEFAULT_RDS_PS_REPEAT_COUNT 0x0003 50#define DEFAULT_RDS_PS_REPEAT_COUNT 0x0003
57#define DEFAULT_LIMITER_RTIME 0x1392 51#define DEFAULT_LIMITER_RTIME 0x1392
58#define DEFAULT_LIMITER_DEV 0x102CA 52#define DEFAULT_LIMITER_DEV 0x102CA
59#define DEFAULT_PILOT_FREQUENCY 0x4A38 53#define DEFAULT_PILOT_FREQUENCY 0x4A38
60#define DEFAULT_PILOT_DEVIATION 0x1A5E 54#define DEFAULT_PILOT_DEVIATION 0x1A5E
61#define DEFAULT_ACOMP_ATIME 0x0000 55#define DEFAULT_ACOMP_ATIME 0x0000
62#define DEFAULT_ACOMP_RTIME 0xF4240L 56#define DEFAULT_ACOMP_RTIME 0xF4240L
63#define DEFAULT_ACOMP_GAIN 0x0F 57#define DEFAULT_ACOMP_GAIN 0x0F
64#define DEFAULT_ACOMP_THRESHOLD (-0x28) 58#define DEFAULT_ACOMP_THRESHOLD (-0x28)
65#define DEFAULT_MUTE 0x01 59#define DEFAULT_MUTE 0x01
66#define DEFAULT_POWER_LEVEL 88 60#define DEFAULT_POWER_LEVEL 88
67#define DEFAULT_FREQUENCY 8800 61#define DEFAULT_FREQUENCY 8800
@@ -213,6 +207,7 @@ static int si4713_send_command(struct si4713_device *sdev, const u8 command,
213 u8 response[], const int respn, const int usecs) 207 u8 response[], const int respn, const int usecs)
214{ 208{
215 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd); 209 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
210 unsigned long until_jiffies;
216 u8 data1[MAX_ARGS + 1]; 211 u8 data1[MAX_ARGS + 1];
217 int err; 212 int err;
218 213
@@ -228,30 +223,42 @@ static int si4713_send_command(struct si4713_device *sdev, const u8 command,
228 if (err != argn + 1) { 223 if (err != argn + 1) {
229 v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n", 224 v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
230 command); 225 command);
231 return (err > 0) ? -EIO : err; 226 return err < 0 ? err : -EIO;
232 } 227 }
233 228
229 until_jiffies = jiffies + usecs_to_jiffies(usecs) + 1;
230
234 /* Wait response from interrupt */ 231 /* Wait response from interrupt */
235 if (!wait_for_completion_timeout(&sdev->work, 232 if (client->irq) {
233 if (!wait_for_completion_timeout(&sdev->work,
236 usecs_to_jiffies(usecs) + 1)) 234 usecs_to_jiffies(usecs) + 1))
237 v4l2_warn(&sdev->sd, 235 v4l2_warn(&sdev->sd,
238 "(%s) Device took too much time to answer.\n", 236 "(%s) Device took too much time to answer.\n",
239 __func__); 237 __func__);
240
241 /* Then get the response */
242 err = i2c_master_recv(client, response, respn);
243 if (err != respn) {
244 v4l2_err(&sdev->sd,
245 "Error while reading response for command 0x%02x\n",
246 command);
247 return (err > 0) ? -EIO : err;
248 } 238 }
249 239
250 DBG_BUFFER(&sdev->sd, "Response", response, respn); 240 do {
251 if (check_command_failed(response[0])) 241 err = i2c_master_recv(client, response, respn);
252 return -EBUSY; 242 if (err != respn) {
243 v4l2_err(&sdev->sd,
244 "Error %d while reading response for command 0x%02x\n",
245 err, command);
246 return err < 0 ? err : -EIO;
247 }
253 248
254 return 0; 249 DBG_BUFFER(&sdev->sd, "Response", response, respn);
250 if (!check_command_failed(response[0]))
251 return 0;
252
253 if (client->irq)
254 return -EBUSY;
255 if (usecs <= 1000)
256 usleep_range(usecs, 1000);
257 else
258 usleep_range(1000, 2000);
259 } while (time_is_after_jiffies(until_jiffies));
260
261 return -EBUSY;
255} 262}
256 263
257/* 264/*
@@ -265,9 +272,9 @@ static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv)
265 int err; 272 int err;
266 u8 val[SI4713_GET_PROP_NRESP]; 273 u8 val[SI4713_GET_PROP_NRESP];
267 /* 274 /*
268 * .First byte = 0 275 * .First byte = 0
269 * .Second byte = property's MSB 276 * .Second byte = property's MSB
270 * .Third byte = property's LSB 277 * .Third byte = property's LSB
271 */ 278 */
272 const u8 args[SI4713_GET_PROP_NARGS] = { 279 const u8 args[SI4713_GET_PROP_NARGS] = {
273 0x00, 280 0x00,
@@ -302,11 +309,11 @@ static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val)
302 int rval; 309 int rval;
303 u8 resp[SI4713_SET_PROP_NRESP]; 310 u8 resp[SI4713_SET_PROP_NRESP];
304 /* 311 /*
305 * .First byte = 0 312 * .First byte = 0
306 * .Second byte = property's MSB 313 * .Second byte = property's MSB
307 * .Third byte = property's LSB 314 * .Third byte = property's LSB
308 * .Fourth byte = value's MSB 315 * .Fourth byte = value's MSB
309 * .Fifth byte = value's LSB 316 * .Fifth byte = value's LSB
310 */ 317 */
311 const u8 args[SI4713_SET_PROP_NARGS] = { 318 const u8 args[SI4713_SET_PROP_NARGS] = {
312 0x00, 319 0x00,
@@ -344,31 +351,36 @@ static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val)
344 */ 351 */
345static int si4713_powerup(struct si4713_device *sdev) 352static int si4713_powerup(struct si4713_device *sdev)
346{ 353{
354 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
347 int err; 355 int err;
348 u8 resp[SI4713_PWUP_NRESP]; 356 u8 resp[SI4713_PWUP_NRESP];
349 /* 357 /*
350 * .First byte = Enabled interrupts and boot function 358 * .First byte = Enabled interrupts and boot function
351 * .Second byte = Input operation mode 359 * .Second byte = Input operation mode
352 */ 360 */
353 const u8 args[SI4713_PWUP_NARGS] = { 361 u8 args[SI4713_PWUP_NARGS] = {
354 SI4713_PWUP_CTSIEN | SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX, 362 SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX,
355 SI4713_PWUP_OPMOD_ANALOG, 363 SI4713_PWUP_OPMOD_ANALOG,
356 }; 364 };
357 365
358 if (sdev->power_state) 366 if (sdev->power_state)
359 return 0; 367 return 0;
360 368
361 err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies), 369 if (sdev->supplies) {
362 sdev->supplies); 370 err = regulator_bulk_enable(sdev->supplies, sdev->supply_data);
363 if (err) { 371 if (err) {
364 v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err); 372 v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err);
365 return err; 373 return err;
374 }
366 } 375 }
367 if (gpio_is_valid(sdev->gpio_reset)) { 376 if (gpio_is_valid(sdev->gpio_reset)) {
368 udelay(50); 377 udelay(50);
369 gpio_set_value(sdev->gpio_reset, 1); 378 gpio_set_value(sdev->gpio_reset, 1);
370 } 379 }
371 380
381 if (client->irq)
382 args[0] |= SI4713_PWUP_CTSIEN;
383
372 err = si4713_send_command(sdev, SI4713_CMD_POWER_UP, 384 err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
373 args, ARRAY_SIZE(args), 385 args, ARRAY_SIZE(args),
374 resp, ARRAY_SIZE(resp), 386 resp, ARRAY_SIZE(resp),
@@ -380,13 +392,15 @@ static int si4713_powerup(struct si4713_device *sdev)
380 v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n"); 392 v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n");
381 sdev->power_state = POWER_ON; 393 sdev->power_state = POWER_ON;
382 394
383 err = si4713_write_property(sdev, SI4713_GPO_IEN, 395 if (client->irq)
396 err = si4713_write_property(sdev, SI4713_GPO_IEN,
384 SI4713_STC_INT | SI4713_CTS); 397 SI4713_STC_INT | SI4713_CTS);
385 } else { 398 return err;
386 if (gpio_is_valid(sdev->gpio_reset)) 399 }
387 gpio_set_value(sdev->gpio_reset, 0); 400 if (gpio_is_valid(sdev->gpio_reset))
388 err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies), 401 gpio_set_value(sdev->gpio_reset, 0);
389 sdev->supplies); 402 if (sdev->supplies) {
403 err = regulator_bulk_disable(sdev->supplies, sdev->supply_data);
390 if (err) 404 if (err)
391 v4l2_err(&sdev->sd, 405 v4l2_err(&sdev->sd,
392 "Failed to disable supplies: %d\n", err); 406 "Failed to disable supplies: %d\n", err);
@@ -418,11 +432,13 @@ static int si4713_powerdown(struct si4713_device *sdev)
418 v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); 432 v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
419 if (gpio_is_valid(sdev->gpio_reset)) 433 if (gpio_is_valid(sdev->gpio_reset))
420 gpio_set_value(sdev->gpio_reset, 0); 434 gpio_set_value(sdev->gpio_reset, 0);
421 err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies), 435 if (sdev->supplies) {
422 sdev->supplies); 436 err = regulator_bulk_disable(sdev->supplies,
423 if (err) 437 sdev->supply_data);
424 v4l2_err(&sdev->sd, 438 if (err)
425 "Failed to disable supplies: %d\n", err); 439 v4l2_err(&sdev->sd,
440 "Failed to disable supplies: %d\n", err);
441 }
426 sdev->power_state = POWER_OFF; 442 sdev->power_state = POWER_OFF;
427 } 443 }
428 444
@@ -451,7 +467,7 @@ static int si4713_checkrev(struct si4713_device *sdev)
451 v4l2_info(&sdev->sd, "chip found @ 0x%02x (%s)\n", 467 v4l2_info(&sdev->sd, "chip found @ 0x%02x (%s)\n",
452 client->addr << 1, client->adapter->name); 468 client->addr << 1, client->adapter->name);
453 } else { 469 } else {
454 v4l2_err(&sdev->sd, "Invalid product number\n"); 470 v4l2_err(&sdev->sd, "Invalid product number 0x%X\n", resp[1]);
455 rval = -EINVAL; 471 rval = -EINVAL;
456 } 472 }
457 return rval; 473 return rval;
@@ -465,39 +481,45 @@ static int si4713_checkrev(struct si4713_device *sdev)
465 */ 481 */
466static int si4713_wait_stc(struct si4713_device *sdev, const int usecs) 482static int si4713_wait_stc(struct si4713_device *sdev, const int usecs)
467{ 483{
468 int err; 484 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
469 u8 resp[SI4713_GET_STATUS_NRESP]; 485 u8 resp[SI4713_GET_STATUS_NRESP];
486 unsigned long start_jiffies = jiffies;
487 int err;
470 488
471 /* Wait response from STC interrupt */ 489 if (client->irq &&
472 if (!wait_for_completion_timeout(&sdev->work, 490 !wait_for_completion_timeout(&sdev->work, usecs_to_jiffies(usecs) + 1))
473 usecs_to_jiffies(usecs) + 1))
474 v4l2_warn(&sdev->sd, 491 v4l2_warn(&sdev->sd,
475 "%s: device took too much time to answer (%d usec).\n", 492 "(%s) Device took too much time to answer.\n", __func__);
476 __func__, usecs); 493
477 494 for (;;) {
478 /* Clear status bits */ 495 /* Clear status bits */
479 err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS, 496 err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS,
480 NULL, 0, 497 NULL, 0,
481 resp, ARRAY_SIZE(resp), 498 resp, ARRAY_SIZE(resp),
482 DEFAULT_TIMEOUT); 499 DEFAULT_TIMEOUT);
483 500 /* The USB device returns errors when it waits for the
484 if (err < 0) 501 * STC bit to be set. Hence polling */
485 goto exit; 502 if (err >= 0) {
486 503 v4l2_dbg(1, debug, &sdev->sd,
487 v4l2_dbg(1, debug, &sdev->sd, 504 "%s: status bits: 0x%02x\n", __func__, resp[0]);
488 "%s: status bits: 0x%02x\n", __func__, resp[0]); 505
489 506 if (resp[0] & SI4713_STC_INT)
490 if (!(resp[0] & SI4713_STC_INT)) 507 return 0;
491 err = -EIO; 508 }
492 509 if (jiffies_to_usecs(jiffies - start_jiffies) > usecs)
493exit: 510 return err < 0 ? err : -EIO;
494 return err; 511 /* We sleep here for 3-4 ms in order to avoid flooding the device
512 * with USB requests. The si4713 USB driver was developed
513 * by reverse engineering the Windows USB driver. The windows
514 * driver also has a ~2.5 ms delay between responses. */
515 usleep_range(3000, 4000);
516 }
495} 517}
496 518
497/* 519/*
498 * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning 520 * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning
499 * frequency between 76 and 108 MHz in 10 kHz units and 521 * frequency between 76 and 108 MHz in 10 kHz units and
500 * steps of 50 kHz. 522 * steps of 50 kHz.
501 * @sdev: si4713_device structure for the device we are communicating 523 * @sdev: si4713_device structure for the device we are communicating
502 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz) 524 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
503 */ 525 */
@@ -506,9 +528,9 @@ static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
506 int err; 528 int err;
507 u8 val[SI4713_TXFREQ_NRESP]; 529 u8 val[SI4713_TXFREQ_NRESP];
508 /* 530 /*
509 * .First byte = 0 531 * .First byte = 0
510 * .Second byte = frequency's MSB 532 * .Second byte = frequency's MSB
511 * .Third byte = frequency's LSB 533 * .Third byte = frequency's LSB
512 */ 534 */
513 const u8 args[SI4713_TXFREQ_NARGS] = { 535 const u8 args[SI4713_TXFREQ_NARGS] = {
514 0x00, 536 0x00,
@@ -535,14 +557,14 @@ static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
535} 557}
536 558
537/* 559/*
538 * si4713_tx_tune_power - Sets the RF voltage level between 88 and 115 dBuV in 560 * si4713_tx_tune_power - Sets the RF voltage level between 88 and 120 dBuV in
539 * 1 dB units. A value of 0x00 indicates off. The command 561 * 1 dB units. A value of 0x00 indicates off. The command
540 * also sets the antenna tuning capacitance. A value of 0 562 * also sets the antenna tuning capacitance. A value of 0
541 * indicates autotuning, and a value of 1 - 191 indicates 563 * indicates autotuning, and a value of 1 - 191 indicates
542 * a manual override, which results in a tuning 564 * a manual override, which results in a tuning
543 * capacitance of 0.25 pF x @antcap. 565 * capacitance of 0.25 pF x @antcap.
544 * @sdev: si4713_device structure for the device we are communicating 566 * @sdev: si4713_device structure for the device we are communicating
545 * @power: tuning power (88 - 115 dBuV, unit/step 1 dB) 567 * @power: tuning power (88 - 120 dBuV, unit/step 1 dB)
546 * @antcap: value of antenna tuning capacitor (0 - 191) 568 * @antcap: value of antenna tuning capacitor (0 - 191)
547 */ 569 */
548static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power, 570static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
@@ -551,21 +573,21 @@ static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
551 int err; 573 int err;
552 u8 val[SI4713_TXPWR_NRESP]; 574 u8 val[SI4713_TXPWR_NRESP];
553 /* 575 /*
554 * .First byte = 0 576 * .First byte = 0
555 * .Second byte = 0 577 * .Second byte = 0
556 * .Third byte = power 578 * .Third byte = power
557 * .Fourth byte = antcap 579 * .Fourth byte = antcap
558 */ 580 */
559 const u8 args[SI4713_TXPWR_NARGS] = { 581 u8 args[SI4713_TXPWR_NARGS] = {
560 0x00, 582 0x00,
561 0x00, 583 0x00,
562 power, 584 power,
563 antcap, 585 antcap,
564 }; 586 };
565 587
566 if (((power > 0) && (power < SI4713_MIN_POWER)) || 588 /* Map power values 1-87 to MIN_POWER (88) */
567 power > SI4713_MAX_POWER || antcap > SI4713_MAX_ANTCAP) 589 if (power > 0 && power < SI4713_MIN_POWER)
568 return -EDOM; 590 args[2] = power = SI4713_MIN_POWER;
569 591
570 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER, 592 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
571 args, ARRAY_SIZE(args), val, 593 args, ARRAY_SIZE(args), val,
@@ -583,12 +605,12 @@ static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
583 605
584/* 606/*
585 * si4713_tx_tune_measure - Enters receive mode and measures the received noise 607 * si4713_tx_tune_measure - Enters receive mode and measures the received noise
586 * level in units of dBuV on the selected frequency. 608 * level in units of dBuV on the selected frequency.
587 * The Frequency must be between 76 and 108 MHz in 10 kHz 609 * The Frequency must be between 76 and 108 MHz in 10 kHz
588 * units and steps of 50 kHz. The command also sets the 610 * units and steps of 50 kHz. The command also sets the
589 * antenna tuning capacitance. A value of 0 means 611 * antenna tuning capacitance. A value of 0 means
590 * autotuning, and a value of 1 to 191 indicates manual 612 * autotuning, and a value of 1 to 191 indicates manual
591 * override. 613 * override.
592 * @sdev: si4713_device structure for the device we are communicating 614 * @sdev: si4713_device structure for the device we are communicating
593 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz) 615 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
594 * @antcap: value of antenna tuning capacitor (0 - 191) 616 * @antcap: value of antenna tuning capacitor (0 - 191)
@@ -599,10 +621,10 @@ static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency,
599 int err; 621 int err;
600 u8 val[SI4713_TXMEA_NRESP]; 622 u8 val[SI4713_TXMEA_NRESP];
601 /* 623 /*
602 * .First byte = 0 624 * .First byte = 0
603 * .Second byte = frequency's MSB 625 * .Second byte = frequency's MSB
604 * .Third byte = frequency's LSB 626 * .Third byte = frequency's LSB
605 * .Fourth byte = antcap 627 * .Fourth byte = antcap
606 */ 628 */
607 const u8 args[SI4713_TXMEA_NARGS] = { 629 const u8 args[SI4713_TXMEA_NARGS] = {
608 0x00, 630 0x00,
@@ -632,11 +654,11 @@ static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency,
632 654
633/* 655/*
634 * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or 656 * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or
635 * tx_tune_power commands. This command return the current 657 * tx_tune_power commands. This command return the current
636 * frequency, output voltage in dBuV, the antenna tunning 658 * frequency, output voltage in dBuV, the antenna tunning
637 * capacitance value and the received noise level. The 659 * capacitance value and the received noise level. The
638 * command also clears the stcint interrupt bit when the 660 * command also clears the stcint interrupt bit when the
639 * first bit of its arguments is high. 661 * first bit of its arguments is high.
640 * @sdev: si4713_device structure for the device we are communicating 662 * @sdev: si4713_device structure for the device we are communicating
641 * @intack: 0x01 to clear the seek/tune complete interrupt status indicator. 663 * @intack: 0x01 to clear the seek/tune complete interrupt status indicator.
642 * @frequency: returned frequency 664 * @frequency: returned frequency
@@ -651,7 +673,7 @@ static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack,
651 int err; 673 int err;
652 u8 val[SI4713_TXSTATUS_NRESP]; 674 u8 val[SI4713_TXSTATUS_NRESP];
653 /* 675 /*
654 * .First byte = intack bit 676 * .First byte = intack bit
655 */ 677 */
656 const u8 args[SI4713_TXSTATUS_NARGS] = { 678 const u8 args[SI4713_TXSTATUS_NARGS] = {
657 intack & SI4713_INTACK_MASK, 679 intack & SI4713_INTACK_MASK,
@@ -812,8 +834,9 @@ static int si4713_set_rds_ps_name(struct si4713_device *sdev, char *ps_name)
812 return rval; 834 return rval;
813} 835}
814 836
815static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt) 837static int si4713_set_rds_radio_text(struct si4713_device *sdev, const char *rt)
816{ 838{
839 static const char cr[RDS_RADIOTEXT_BLK_SIZE] = { RDS_CARRIAGE_RETURN, 0 };
817 int rval = 0, i; 840 int rval = 0, i;
818 u16 t_index = 0; 841 u16 t_index = 0;
819 u8 b_index = 0, cr_inserted = 0; 842 u8 b_index = 0, cr_inserted = 0;
@@ -837,7 +860,7 @@ static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt)
837 for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) { 860 for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) {
838 if (!rt[t_index + i] || 861 if (!rt[t_index + i] ||
839 rt[t_index + i] == RDS_CARRIAGE_RETURN) { 862 rt[t_index + i] == RDS_CARRIAGE_RETURN) {
840 rt[t_index + i] = RDS_CARRIAGE_RETURN; 863 rt = cr;
841 cr_inserted = 1; 864 cr_inserted = 1;
842 break; 865 break;
843 } 866 }
@@ -1024,7 +1047,6 @@ static int si4713_initialize(struct si4713_device *sdev)
1024 if (rval < 0) 1047 if (rval < 0)
1025 return rval; 1048 return rval;
1026 1049
1027
1028 sdev->frequency = DEFAULT_FREQUENCY; 1050 sdev->frequency = DEFAULT_FREQUENCY;
1029 sdev->stereo = 1; 1051 sdev->stereo = 1;
1030 sdev->tune_rnl = DEFAULT_TUNE_RNL; 1052 sdev->tune_rnl = DEFAULT_TUNE_RNL;
@@ -1345,7 +1367,7 @@ static int si4713_probe(struct i2c_client *client,
1345 struct v4l2_ctrl_handler *hdl; 1367 struct v4l2_ctrl_handler *hdl;
1346 int rval, i; 1368 int rval, i;
1347 1369
1348 sdev = kzalloc(sizeof *sdev, GFP_KERNEL); 1370 sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
1349 if (!sdev) { 1371 if (!sdev) {
1350 dev_err(&client->dev, "Failed to alloc video device.\n"); 1372 dev_err(&client->dev, "Failed to alloc video device.\n");
1351 rval = -ENOMEM; 1373 rval = -ENOMEM;
@@ -1362,13 +1384,14 @@ static int si4713_probe(struct i2c_client *client,
1362 } 1384 }
1363 sdev->gpio_reset = pdata->gpio_reset; 1385 sdev->gpio_reset = pdata->gpio_reset;
1364 gpio_direction_output(sdev->gpio_reset, 0); 1386 gpio_direction_output(sdev->gpio_reset, 0);
1387 sdev->supplies = pdata->supplies;
1365 } 1388 }
1366 1389
1367 for (i = 0; i < ARRAY_SIZE(sdev->supplies); i++) 1390 for (i = 0; i < sdev->supplies; i++)
1368 sdev->supplies[i].supply = si4713_supply_names[i]; 1391 sdev->supply_data[i].supply = pdata->supply_names[i];
1369 1392
1370 rval = regulator_bulk_get(&client->dev, ARRAY_SIZE(sdev->supplies), 1393 rval = regulator_bulk_get(&client->dev, sdev->supplies,
1371 sdev->supplies); 1394 sdev->supply_data);
1372 if (rval) { 1395 if (rval) {
1373 dev_err(&client->dev, "Cannot get regulators: %d\n", rval); 1396 dev_err(&client->dev, "Cannot get regulators: %d\n", rval);
1374 goto free_gpio; 1397 goto free_gpio;
@@ -1420,8 +1443,8 @@ static int si4713_probe(struct i2c_client *client,
1420 V4L2_CID_AUDIO_COMPRESSION_GAIN, 0, MAX_ACOMP_GAIN, 1, 1443 V4L2_CID_AUDIO_COMPRESSION_GAIN, 0, MAX_ACOMP_GAIN, 1,
1421 DEFAULT_ACOMP_GAIN); 1444 DEFAULT_ACOMP_GAIN);
1422 sdev->compression_threshold = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops, 1445 sdev->compression_threshold = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1423 V4L2_CID_AUDIO_COMPRESSION_THRESHOLD, MIN_ACOMP_THRESHOLD, 1446 V4L2_CID_AUDIO_COMPRESSION_THRESHOLD,
1424 MAX_ACOMP_THRESHOLD, 1, 1447 MIN_ACOMP_THRESHOLD, MAX_ACOMP_THRESHOLD, 1,
1425 DEFAULT_ACOMP_THRESHOLD); 1448 DEFAULT_ACOMP_THRESHOLD);
1426 sdev->compression_attack_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops, 1449 sdev->compression_attack_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1427 V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME, 0, 1450 V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME, 0,
@@ -1443,9 +1466,11 @@ static int si4713_probe(struct i2c_client *client,
1443 V4L2_CID_TUNE_PREEMPHASIS, 1466 V4L2_CID_TUNE_PREEMPHASIS,
1444 V4L2_PREEMPHASIS_75_uS, 0, V4L2_PREEMPHASIS_50_uS); 1467 V4L2_PREEMPHASIS_75_uS, 0, V4L2_PREEMPHASIS_50_uS);
1445 sdev->tune_pwr_level = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops, 1468 sdev->tune_pwr_level = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1446 V4L2_CID_TUNE_POWER_LEVEL, 0, 120, 1, DEFAULT_POWER_LEVEL); 1469 V4L2_CID_TUNE_POWER_LEVEL, 0, SI4713_MAX_POWER,
1470 1, DEFAULT_POWER_LEVEL);
1447 sdev->tune_ant_cap = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops, 1471 sdev->tune_ant_cap = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1448 V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0, 191, 1, 0); 1472 V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0, SI4713_MAX_ANTCAP,
1473 1, 0);
1449 1474
1450 if (hdl->error) { 1475 if (hdl->error) {
1451 rval = hdl->error; 1476 rval = hdl->error;
@@ -1481,7 +1506,7 @@ free_irq:
1481free_ctrls: 1506free_ctrls:
1482 v4l2_ctrl_handler_free(hdl); 1507 v4l2_ctrl_handler_free(hdl);
1483put_reg: 1508put_reg:
1484 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); 1509 regulator_bulk_free(sdev->supplies, sdev->supply_data);
1485free_gpio: 1510free_gpio:
1486 if (gpio_is_valid(sdev->gpio_reset)) 1511 if (gpio_is_valid(sdev->gpio_reset))
1487 gpio_free(sdev->gpio_reset); 1512 gpio_free(sdev->gpio_reset);
@@ -1505,7 +1530,7 @@ static int si4713_remove(struct i2c_client *client)
1505 1530
1506 v4l2_device_unregister_subdev(sd); 1531 v4l2_device_unregister_subdev(sd);
1507 v4l2_ctrl_handler_free(sd->ctrl_handler); 1532 v4l2_ctrl_handler_free(sd->ctrl_handler);
1508 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); 1533 regulator_bulk_free(sdev->supplies, sdev->supply_data);
1509 if (gpio_is_valid(sdev->gpio_reset)) 1534 if (gpio_is_valid(sdev->gpio_reset))
1510 gpio_free(sdev->gpio_reset); 1535 gpio_free(sdev->gpio_reset);
1511 kfree(sdev); 1536 kfree(sdev);
diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713/si4713.h
index 25cdea26343b..4837cf6e0e1b 100644
--- a/drivers/media/radio/si4713-i2c.h
+++ b/drivers/media/radio/si4713/si4713.h
@@ -15,6 +15,7 @@
15#ifndef SI4713_I2C_H 15#ifndef SI4713_I2C_H
16#define SI4713_I2C_H 16#define SI4713_I2C_H
17 17
18#include <linux/regulator/consumer.h>
18#include <media/v4l2-subdev.h> 19#include <media/v4l2-subdev.h>
19#include <media/v4l2-ctrls.h> 20#include <media/v4l2-ctrls.h>
20#include <media/si4713.h> 21#include <media/si4713.h>
@@ -226,7 +227,8 @@ struct si4713_device {
226 struct v4l2_ctrl *tune_ant_cap; 227 struct v4l2_ctrl *tune_ant_cap;
227 }; 228 };
228 struct completion work; 229 struct completion work;
229 struct regulator_bulk_data supplies[SI4713_NUM_SUPPLIES]; 230 unsigned supplies;
231 struct regulator_bulk_data supply_data[SI4713_NUM_SUPPLIES];
230 int gpio_reset; 232 int gpio_reset;
231 u32 power_state; 233 u32 power_state;
232 u32 rds_enabled; 234 u32 rds_enabled;
diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c
index cef06981b7c9..7c14060a40b8 100644
--- a/drivers/media/radio/tea575x.c
+++ b/drivers/media/radio/tea575x.c
@@ -20,12 +20,12 @@
20 * 20 *
21 */ 21 */
22 22
23#include <asm/io.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/module.h> 24#include <linux/module.h>
26#include <linux/init.h> 25#include <linux/init.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28#include <linux/sched.h> 27#include <linux/sched.h>
28#include <asm/io.h>
29#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-dev.h> 30#include <media/v4l2-dev.h>
31#include <media/v4l2-fh.h> 31#include <media/v4l2-fh.h>
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index f329485c6629..822b9f47ca72 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1909,10 +1909,8 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx)
1909 int ret, i; 1909 int ret, i;
1910 1910
1911 idev = input_allocate_device(); 1911 idev = input_allocate_device();
1912 if (!idev) { 1912 if (!idev)
1913 dev_err(ictx->dev, "input dev allocation failed\n");
1914 goto out; 1913 goto out;
1915 }
1916 1914
1917 snprintf(ictx->name_idev, sizeof(ictx->name_idev), 1915 snprintf(ictx->name_idev, sizeof(ictx->name_idev),
1918 "iMON Panel, Knob and Mouse(%04x:%04x)", 1916 "iMON Panel, Knob and Mouse(%04x:%04x)",
@@ -1960,10 +1958,8 @@ static struct input_dev *imon_init_touch(struct imon_context *ictx)
1960 int ret; 1958 int ret;
1961 1959
1962 touch = input_allocate_device(); 1960 touch = input_allocate_device();
1963 if (!touch) { 1961 if (!touch)
1964 dev_err(ictx->dev, "touchscreen input dev allocation failed\n");
1965 goto touch_alloc_failed; 1962 goto touch_alloc_failed;
1966 }
1967 1963
1968 snprintf(ictx->name_touch, sizeof(ictx->name_touch), 1964 snprintf(ictx->name_touch, sizeof(ictx->name_touch),
1969 "iMON USB Touchscreen (%04x:%04x)", 1965 "iMON USB Touchscreen (%04x:%04x)",
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index b1cde8c0422b..0b8c54919010 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -98,4 +98,5 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
98 rc-videomate-s350.o \ 98 rc-videomate-s350.o \
99 rc-videomate-tv-pvr.o \ 99 rc-videomate-tv-pvr.o \
100 rc-winfast.o \ 100 rc-winfast.o \
101 rc-winfast-usbii-deluxe.o 101 rc-winfast-usbii-deluxe.o \
102 rc-su3000.o
diff --git a/drivers/media/rc/keymaps/rc-su3000.c b/drivers/media/rc/keymaps/rc-su3000.c
new file mode 100644
index 000000000000..8dbd3e9bc951
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-su3000.c
@@ -0,0 +1,75 @@
1/* rc-su3000.h - Keytable for Geniatech HDStar Remote Controller
2 *
3 * Copyright (c) 2013 by Evgeny Plehov <Evgeny Plehov@ukr.net>
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
11#include <media/rc-map.h>
12#include <linux/module.h>
13
14static struct rc_map_table su3000[] = {
15 { 0x25, KEY_POWER }, /* right-bottom Red */
16 { 0x0a, KEY_MUTE }, /* -/-- */
17 { 0x01, KEY_1 },
18 { 0x02, KEY_2 },
19 { 0x03, KEY_3 },
20 { 0x04, KEY_4 },
21 { 0x05, KEY_5 },
22 { 0x06, KEY_6 },
23 { 0x07, KEY_7 },
24 { 0x08, KEY_8 },
25 { 0x09, KEY_9 },
26 { 0x00, KEY_0 },
27 { 0x20, KEY_UP }, /* CH+ */
28 { 0x21, KEY_DOWN }, /* CH+ */
29 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
30 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
31 { 0x1f, KEY_RECORD },
32 { 0x17, KEY_PLAY },
33 { 0x16, KEY_PAUSE },
34 { 0x0b, KEY_STOP },
35 { 0x27, KEY_FASTFORWARD },/* >> */
36 { 0x26, KEY_REWIND }, /* << */
37 { 0x0d, KEY_OK }, /* Mute */
38 { 0x11, KEY_LEFT }, /* VOL- */
39 { 0x10, KEY_RIGHT }, /* VOL+ */
40 { 0x29, KEY_BACK }, /* button under 9 */
41 { 0x2c, KEY_MENU }, /* TTX */
42 { 0x2b, KEY_EPG }, /* EPG */
43 { 0x1e, KEY_RED }, /* OSD */
44 { 0x0e, KEY_GREEN }, /* Window */
45 { 0x2d, KEY_YELLOW }, /* button under << */
46 { 0x0f, KEY_BLUE }, /* bottom yellow button */
47 { 0x14, KEY_AUDIO }, /* Snapshot */
48 { 0x38, KEY_TV }, /* TV/Radio */
49 { 0x0c, KEY_ESC } /* upper Red button */
50};
51
52static struct rc_map_list su3000_map = {
53 .map = {
54 .scan = su3000,
55 .size = ARRAY_SIZE(su3000),
56 .rc_type = RC_TYPE_RC5,
57 .name = RC_MAP_SU3000,
58 }
59};
60
61static int __init init_rc_map_su3000(void)
62{
63 return rc_map_register(&su3000_map);
64}
65
66static void __exit exit_rc_map_su3000(void)
67{
68 rc_map_unregister(&su3000_map);
69}
70
71module_init(init_rc_map_su3000)
72module_exit(exit_rc_map_su3000)
73
74MODULE_LICENSE("GPL");
75MODULE_AUTHOR("Evgeny Plehov <Evgeny Plehov@ukr.net>");
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 3c761014d3ce..a25bb1581e46 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -199,6 +199,7 @@ static bool debug;
199#define VENDOR_TIVO 0x105a 199#define VENDOR_TIVO 0x105a
200#define VENDOR_CONEXANT 0x0572 200#define VENDOR_CONEXANT 0x0572
201#define VENDOR_TWISTEDMELON 0x2596 201#define VENDOR_TWISTEDMELON 0x2596
202#define VENDOR_HAUPPAUGE 0x2040
202 203
203enum mceusb_model_type { 204enum mceusb_model_type {
204 MCE_GEN2 = 0, /* Most boards */ 205 MCE_GEN2 = 0, /* Most boards */
@@ -210,6 +211,7 @@ enum mceusb_model_type {
210 MULTIFUNCTION, 211 MULTIFUNCTION,
211 TIVO_KIT, 212 TIVO_KIT,
212 MCE_GEN2_NO_TX, 213 MCE_GEN2_NO_TX,
214 HAUPPAUGE_CX_HYBRID_TV,
213}; 215};
214 216
215struct mceusb_model { 217struct mceusb_model {
@@ -258,6 +260,11 @@ static const struct mceusb_model mceusb_model[] = {
258 .no_tx = 1, /* tx isn't wired up at all */ 260 .no_tx = 1, /* tx isn't wired up at all */
259 .name = "Conexant Hybrid TV (cx231xx) MCE IR", 261 .name = "Conexant Hybrid TV (cx231xx) MCE IR",
260 }, 262 },
263 [HAUPPAUGE_CX_HYBRID_TV] = {
264 .rc_map = RC_MAP_HAUPPAUGE,
265 .no_tx = 1, /* eeprom says it has no tx */
266 .name = "Conexant Hybrid TV (cx231xx) MCE IR no TX",
267 },
261 [MULTIFUNCTION] = { 268 [MULTIFUNCTION] = {
262 .mce_gen2 = 1, 269 .mce_gen2 = 1,
263 .ir_intfnum = 2, 270 .ir_intfnum = 2,
@@ -399,6 +406,9 @@ static struct usb_device_id mceusb_dev_table[] = {
399 { USB_DEVICE(VENDOR_TWISTEDMELON, 0x8016) }, 406 { USB_DEVICE(VENDOR_TWISTEDMELON, 0x8016) },
400 /* Twisted Melon Inc. - Manta Transceiver */ 407 /* Twisted Melon Inc. - Manta Transceiver */
401 { USB_DEVICE(VENDOR_TWISTEDMELON, 0x8042) }, 408 { USB_DEVICE(VENDOR_TWISTEDMELON, 0x8042) },
409 /* Hauppauge WINTV-HVR-HVR 930C-HD - based on cx231xx */
410 { USB_DEVICE(VENDOR_HAUPPAUGE, 0xb130),
411 .driver_info = HAUPPAUGE_CX_HYBRID_TV },
402 /* Terminating entry */ 412 /* Terminating entry */
403 { } 413 { }
404}; 414};
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 46da365c9c84..02e2f38c9c85 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -22,6 +22,10 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include "rc-core-priv.h" 23#include "rc-core-priv.h"
24 24
25/* Bitmap to store allocated device numbers from 0 to IRRCV_NUM_DEVICES - 1 */
26#define IRRCV_NUM_DEVICES 256
27DECLARE_BITMAP(ir_core_dev_number, IRRCV_NUM_DEVICES);
28
25/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ 29/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
26#define IR_TAB_MIN_SIZE 256 30#define IR_TAB_MIN_SIZE 256
27#define IR_TAB_MAX_SIZE 8192 31#define IR_TAB_MAX_SIZE 8192
@@ -1065,10 +1069,9 @@ EXPORT_SYMBOL_GPL(rc_free_device);
1065int rc_register_device(struct rc_dev *dev) 1069int rc_register_device(struct rc_dev *dev)
1066{ 1070{
1067 static bool raw_init = false; /* raw decoders loaded? */ 1071 static bool raw_init = false; /* raw decoders loaded? */
1068 static atomic_t devno = ATOMIC_INIT(0);
1069 struct rc_map *rc_map; 1072 struct rc_map *rc_map;
1070 const char *path; 1073 const char *path;
1071 int rc; 1074 int rc, devno;
1072 1075
1073 if (!dev || !dev->map_name) 1076 if (!dev || !dev->map_name)
1074 return -EINVAL; 1077 return -EINVAL;
@@ -1096,7 +1099,15 @@ int rc_register_device(struct rc_dev *dev)
1096 */ 1099 */
1097 mutex_lock(&dev->lock); 1100 mutex_lock(&dev->lock);
1098 1101
1099 dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1); 1102 do {
1103 devno = find_first_zero_bit(ir_core_dev_number,
1104 IRRCV_NUM_DEVICES);
1105 /* No free device slots */
1106 if (devno >= IRRCV_NUM_DEVICES)
1107 return -ENOMEM;
1108 } while (test_and_set_bit(devno, ir_core_dev_number));
1109
1110 dev->devno = devno;
1100 dev_set_name(&dev->dev, "rc%ld", dev->devno); 1111 dev_set_name(&dev->dev, "rc%ld", dev->devno);
1101 dev_set_drvdata(&dev->dev, dev); 1112 dev_set_drvdata(&dev->dev, dev);
1102 rc = device_add(&dev->dev); 1113 rc = device_add(&dev->dev);
@@ -1186,6 +1197,7 @@ out_dev:
1186 device_del(&dev->dev); 1197 device_del(&dev->dev);
1187out_unlock: 1198out_unlock:
1188 mutex_unlock(&dev->lock); 1199 mutex_unlock(&dev->lock);
1200 clear_bit(dev->devno, ir_core_dev_number);
1189 return rc; 1201 return rc;
1190} 1202}
1191EXPORT_SYMBOL_GPL(rc_register_device); 1203EXPORT_SYMBOL_GPL(rc_register_device);
@@ -1197,6 +1209,8 @@ void rc_unregister_device(struct rc_dev *dev)
1197 1209
1198 del_timer_sync(&dev->timer_keyup); 1210 del_timer_sync(&dev->timer_keyup);
1199 1211
1212 clear_bit(dev->devno, ir_core_dev_number);
1213
1200 if (dev->driver_type == RC_DRIVER_IR_RAW) 1214 if (dev->driver_type == RC_DRIVER_IR_RAW)
1201 ir_raw_event_unregister(dev); 1215 ir_raw_event_unregister(dev);
1202 1216
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index 65120c2d47ad..8f0cddb9e8f2 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/reset.h>
16#include <media/rc-core.h> 17#include <media/rc-core.h>
17#include <linux/pinctrl/consumer.h> 18#include <linux/pinctrl/consumer.h>
18 19
@@ -28,6 +29,7 @@ struct st_rc_device {
28 int sample_mult; 29 int sample_mult;
29 int sample_div; 30 int sample_div;
30 bool rxuhfmode; 31 bool rxuhfmode;
32 struct reset_control *rstc;
31}; 33};
32 34
33/* Registers */ 35/* Registers */
@@ -161,6 +163,10 @@ static void st_rc_hardware_init(struct st_rc_device *dev)
161 unsigned int rx_max_symbol_per = MAX_SYMB_TIME; 163 unsigned int rx_max_symbol_per = MAX_SYMB_TIME;
162 unsigned int rx_sampling_freq_div; 164 unsigned int rx_sampling_freq_div;
163 165
166 /* Enable the IP */
167 if (dev->rstc)
168 reset_control_deassert(dev->rstc);
169
164 clk_prepare_enable(dev->sys_clock); 170 clk_prepare_enable(dev->sys_clock);
165 baseclock = clk_get_rate(dev->sys_clock); 171 baseclock = clk_get_rate(dev->sys_clock);
166 172
@@ -271,6 +277,11 @@ static int st_rc_probe(struct platform_device *pdev)
271 else 277 else
272 rc_dev->rx_base = rc_dev->base; 278 rc_dev->rx_base = rc_dev->base;
273 279
280
281 rc_dev->rstc = reset_control_get(dev, NULL);
282 if (IS_ERR(rc_dev->rstc))
283 rc_dev->rstc = NULL;
284
274 rc_dev->dev = dev; 285 rc_dev->dev = dev;
275 platform_set_drvdata(pdev, rc_dev); 286 platform_set_drvdata(pdev, rc_dev);
276 st_rc_hardware_init(rc_dev); 287 st_rc_hardware_init(rc_dev);
@@ -338,6 +349,8 @@ static int st_rc_suspend(struct device *dev)
338 writel(0x00, rc_dev->rx_base + IRB_RX_EN); 349 writel(0x00, rc_dev->rx_base + IRB_RX_EN);
339 writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN); 350 writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN);
340 clk_disable_unprepare(rc_dev->sys_clock); 351 clk_disable_unprepare(rc_dev->sys_clock);
352 if (rc_dev->rstc)
353 reset_control_assert(rc_dev->rstc);
341 } 354 }
342 355
343 return 0; 356 return 0;
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 15665debc572..ba2e365296cf 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -215,6 +215,13 @@ config MEDIA_TUNER_FC2580
215 help 215 help
216 FCI FC2580 silicon tuner driver. 216 FCI FC2580 silicon tuner driver.
217 217
218config MEDIA_TUNER_M88TS2022
219 tristate "Montage M88TS2022 silicon tuner"
220 depends on MEDIA_SUPPORT && I2C
221 default m if !MEDIA_SUBDRV_AUTOSELECT
222 help
223 Montage M88TS2022 silicon tuner driver.
224
218config MEDIA_TUNER_TUA9001 225config MEDIA_TUNER_TUA9001
219 tristate "Infineon TUA 9001 silicon tuner" 226 tristate "Infineon TUA 9001 silicon tuner"
220 depends on MEDIA_SUPPORT && I2C 227 depends on MEDIA_SUPPORT && I2C
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
index 308f108eadba..efe82a904b12 100644
--- a/drivers/media/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
31obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o 31obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o
32obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o 32obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o
33obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o 33obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
34obj-$(CONFIG_MEDIA_TUNER_M88TS2022) += m88ts2022.o
34obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o 35obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
35obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o 36obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
36obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o 37obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c
index 72971a8d3c37..40c1da707d15 100644
--- a/drivers/media/tuners/e4000.c
+++ b/drivers/media/tuners/e4000.c
@@ -243,8 +243,10 @@ static int e4000_set_params(struct dvb_frontend *fe)
243 break; 243 break;
244 } 244 }
245 245
246 if (i == ARRAY_SIZE(e4000_pll_lut)) 246 if (i == ARRAY_SIZE(e4000_pll_lut)) {
247 ret = -EINVAL;
247 goto err; 248 goto err;
249 }
248 250
249 /* 251 /*
250 * Note: Currently f_vco overflows when c->frequency is 1 073 741 824 Hz 252 * Note: Currently f_vco overflows when c->frequency is 1 073 741 824 Hz
@@ -271,8 +273,10 @@ static int e4000_set_params(struct dvb_frontend *fe)
271 break; 273 break;
272 } 274 }
273 275
274 if (i == ARRAY_SIZE(e400_lna_filter_lut)) 276 if (i == ARRAY_SIZE(e400_lna_filter_lut)) {
277 ret = -EINVAL;
275 goto err; 278 goto err;
279 }
276 280
277 ret = e4000_wr_reg(priv, 0x10, e400_lna_filter_lut[i].val); 281 ret = e4000_wr_reg(priv, 0x10, e400_lna_filter_lut[i].val);
278 if (ret < 0) 282 if (ret < 0)
@@ -284,8 +288,10 @@ static int e4000_set_params(struct dvb_frontend *fe)
284 break; 288 break;
285 } 289 }
286 290
287 if (i == ARRAY_SIZE(e4000_if_filter_lut)) 291 if (i == ARRAY_SIZE(e4000_if_filter_lut)) {
292 ret = -EINVAL;
288 goto err; 293 goto err;
294 }
289 295
290 buf[0] = e4000_if_filter_lut[i].reg11_val; 296 buf[0] = e4000_if_filter_lut[i].reg11_val;
291 buf[1] = e4000_if_filter_lut[i].reg12_val; 297 buf[1] = e4000_if_filter_lut[i].reg12_val;
@@ -300,8 +306,10 @@ static int e4000_set_params(struct dvb_frontend *fe)
300 break; 306 break;
301 } 307 }
302 308
303 if (i == ARRAY_SIZE(e4000_band_lut)) 309 if (i == ARRAY_SIZE(e4000_band_lut)) {
310 ret = -EINVAL;
304 goto err; 311 goto err;
312 }
305 313
306 ret = e4000_wr_reg(priv, 0x07, e4000_band_lut[i].reg07_val); 314 ret = e4000_wr_reg(priv, 0x07, e4000_band_lut[i].reg07_val);
307 if (ret < 0) 315 if (ret < 0)
diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c
new file mode 100644
index 000000000000..40c42dec721b
--- /dev/null
+++ b/drivers/media/tuners/m88ts2022.c
@@ -0,0 +1,674 @@
1/*
2 * Montage M88TS2022 silicon tuner driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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 * Some calculations are taken from existing TS2020 driver.
17 */
18
19#include "m88ts2022_priv.h"
20
21/* write multiple registers */
22static int m88ts2022_wr_regs(struct m88ts2022_priv *priv,
23 u8 reg, const u8 *val, int len)
24{
25#define MAX_WR_LEN 3
26#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
27 int ret;
28 u8 buf[MAX_WR_XFER_LEN];
29 struct i2c_msg msg[1] = {
30 {
31 .addr = priv->client->addr,
32 .flags = 0,
33 .len = 1 + len,
34 .buf = buf,
35 }
36 };
37
38 if (WARN_ON(len > MAX_WR_LEN))
39 return -EINVAL;
40
41 buf[0] = reg;
42 memcpy(&buf[1], val, len);
43
44 ret = i2c_transfer(priv->client->adapter, msg, 1);
45 if (ret == 1) {
46 ret = 0;
47 } else {
48 dev_warn(&priv->client->dev,
49 "%s: i2c wr failed=%d reg=%02x len=%d\n",
50 KBUILD_MODNAME, ret, reg, len);
51 ret = -EREMOTEIO;
52 }
53
54 return ret;
55}
56
57/* read multiple registers */
58static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg,
59 u8 *val, int len)
60{
61#define MAX_RD_LEN 1
62#define MAX_RD_XFER_LEN (MAX_RD_LEN)
63 int ret;
64 u8 buf[MAX_RD_XFER_LEN];
65 struct i2c_msg msg[2] = {
66 {
67 .addr = priv->client->addr,
68 .flags = 0,
69 .len = 1,
70 .buf = &reg,
71 }, {
72 .addr = priv->client->addr,
73 .flags = I2C_M_RD,
74 .len = len,
75 .buf = buf,
76 }
77 };
78
79 if (WARN_ON(len > MAX_RD_LEN))
80 return -EINVAL;
81
82 ret = i2c_transfer(priv->client->adapter, msg, 2);
83 if (ret == 2) {
84 memcpy(val, buf, len);
85 ret = 0;
86 } else {
87 dev_warn(&priv->client->dev,
88 "%s: i2c rd failed=%d reg=%02x len=%d\n",
89 KBUILD_MODNAME, ret, reg, len);
90 ret = -EREMOTEIO;
91 }
92
93 return ret;
94}
95
96/* write single register */
97static int m88ts2022_wr_reg(struct m88ts2022_priv *priv, u8 reg, u8 val)
98{
99 return m88ts2022_wr_regs(priv, reg, &val, 1);
100}
101
102/* read single register */
103static int m88ts2022_rd_reg(struct m88ts2022_priv *priv, u8 reg, u8 *val)
104{
105 return m88ts2022_rd_regs(priv, reg, val, 1);
106}
107
108/* write single register with mask */
109static int m88ts2022_wr_reg_mask(struct m88ts2022_priv *priv,
110 u8 reg, u8 val, u8 mask)
111{
112 int ret;
113 u8 u8tmp;
114
115 /* no need for read if whole reg is written */
116 if (mask != 0xff) {
117 ret = m88ts2022_rd_regs(priv, reg, &u8tmp, 1);
118 if (ret)
119 return ret;
120
121 val &= mask;
122 u8tmp &= ~mask;
123 val |= u8tmp;
124 }
125
126 return m88ts2022_wr_regs(priv, reg, &val, 1);
127}
128
129static int m88ts2022_cmd(struct dvb_frontend *fe,
130 int op, int sleep, u8 reg, u8 mask, u8 val, u8 *reg_val)
131{
132 struct m88ts2022_priv *priv = fe->tuner_priv;
133 int ret, i;
134 u8 u8tmp;
135 struct m88ts2022_reg_val reg_vals[] = {
136 {0x51, 0x1f - op},
137 {0x51, 0x1f},
138 {0x50, 0x00 + op},
139 {0x50, 0x00},
140 };
141
142 for (i = 0; i < 2; i++) {
143 dev_dbg(&priv->client->dev,
144 "%s: i=%d op=%02x reg=%02x mask=%02x val=%02x\n",
145 __func__, i, op, reg, mask, val);
146
147 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
148 ret = m88ts2022_wr_reg(priv, reg_vals[i].reg,
149 reg_vals[i].val);
150 if (ret)
151 goto err;
152 }
153
154 usleep_range(sleep * 1000, sleep * 10000);
155
156 ret = m88ts2022_rd_reg(priv, reg, &u8tmp);
157 if (ret)
158 goto err;
159
160 if ((u8tmp & mask) != val)
161 break;
162 }
163
164 if (reg_val)
165 *reg_val = u8tmp;
166err:
167 return ret;
168}
169
170static int m88ts2022_set_params(struct dvb_frontend *fe)
171{
172 struct m88ts2022_priv *priv = fe->tuner_priv;
173 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
174 int ret;
175 unsigned int frequency_khz, frequency_offset_khz, f_3db_hz;
176 unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28;
177 u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min;
178 u16 u16tmp;
179 dev_dbg(&priv->client->dev,
180 "%s: frequency=%d symbol_rate=%d rolloff=%d\n",
181 __func__, c->frequency, c->symbol_rate, c->rolloff);
182 /*
183 * Integer-N PLL synthesizer
184 * kHz is used for all calculations to keep calculations within 32-bit
185 */
186 f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg.clock, 1000);
187 div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000);
188
189 if (c->symbol_rate < 5000000)
190 frequency_offset_khz = 3000; /* 3 MHz */
191 else
192 frequency_offset_khz = 0;
193
194 frequency_khz = c->frequency + frequency_offset_khz;
195
196 if (frequency_khz < 1103000) {
197 div_out = 4;
198 u8tmp = 0x1b;
199 } else {
200 div_out = 2;
201 u8tmp = 0x0b;
202 }
203
204 buf[0] = u8tmp;
205 buf[1] = 0x40;
206 ret = m88ts2022_wr_regs(priv, 0x10, buf, 2);
207 if (ret)
208 goto err;
209
210 f_vco_khz = frequency_khz * div_out;
211 pll_n = f_vco_khz * div_ref / f_ref_khz;
212 pll_n += pll_n % 2;
213 priv->frequency_khz = pll_n * f_ref_khz / div_ref / div_out;
214
215 if (pll_n < 4095)
216 u16tmp = pll_n - 1024;
217 else if (pll_n < 6143)
218 u16tmp = pll_n + 1024;
219 else
220 u16tmp = pll_n + 3072;
221
222 buf[0] = (u16tmp >> 8) & 0x3f;
223 buf[1] = (u16tmp >> 0) & 0xff;
224 buf[2] = div_ref - 8;
225 ret = m88ts2022_wr_regs(priv, 0x01, buf, 3);
226 if (ret)
227 goto err;
228
229 dev_dbg(&priv->client->dev,
230 "%s: frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n",
231 __func__, priv->frequency_khz,
232 priv->frequency_khz - c->frequency, f_vco_khz, pll_n,
233 div_ref, div_out);
234
235 ret = m88ts2022_cmd(fe, 0x10, 5, 0x15, 0x40, 0x00, NULL);
236 if (ret)
237 goto err;
238
239 ret = m88ts2022_rd_reg(priv, 0x14, &u8tmp);
240 if (ret)
241 goto err;
242
243 u8tmp &= 0x7f;
244 if (u8tmp < 64) {
245 ret = m88ts2022_wr_reg_mask(priv, 0x10, 0x80, 0x80);
246 if (ret)
247 goto err;
248
249 ret = m88ts2022_wr_reg(priv, 0x11, 0x6f);
250 if (ret)
251 goto err;
252
253 ret = m88ts2022_cmd(fe, 0x10, 5, 0x15, 0x40, 0x00, NULL);
254 if (ret)
255 goto err;
256 }
257
258 ret = m88ts2022_rd_reg(priv, 0x14, &u8tmp);
259 if (ret)
260 goto err;
261
262 u8tmp &= 0x1f;
263 if (u8tmp > 19) {
264 ret = m88ts2022_wr_reg_mask(priv, 0x10, 0x00, 0x02);
265 if (ret)
266 goto err;
267 }
268
269 ret = m88ts2022_cmd(fe, 0x08, 5, 0x3c, 0xff, 0x00, NULL);
270 if (ret)
271 goto err;
272
273 ret = m88ts2022_wr_reg(priv, 0x25, 0x00);
274 if (ret)
275 goto err;
276
277 ret = m88ts2022_wr_reg(priv, 0x27, 0x70);
278 if (ret)
279 goto err;
280
281 ret = m88ts2022_wr_reg(priv, 0x41, 0x09);
282 if (ret)
283 goto err;
284
285 ret = m88ts2022_wr_reg(priv, 0x08, 0x0b);
286 if (ret)
287 goto err;
288
289 /* filters */
290 gdiv28 = DIV_ROUND_CLOSEST(f_ref_khz * 1694U, 1000000U);
291
292 ret = m88ts2022_wr_reg(priv, 0x04, gdiv28);
293 if (ret)
294 goto err;
295
296 ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp);
297 if (ret)
298 goto err;
299
300 cap_code = u8tmp & 0x3f;
301
302 ret = m88ts2022_wr_reg(priv, 0x41, 0x0d);
303 if (ret)
304 goto err;
305
306 ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp);
307 if (ret)
308 goto err;
309
310 u8tmp &= 0x3f;
311 cap_code = (cap_code + u8tmp) / 2;
312 gdiv28 = gdiv28 * 207 / (cap_code * 2 + 151);
313 div_max = gdiv28 * 135 / 100;
314 div_min = gdiv28 * 78 / 100;
315 div_max = clamp_val(div_max, 0U, 63U);
316
317 f_3db_hz = c->symbol_rate * 135UL / 200UL;
318 f_3db_hz += 2000000U + (frequency_offset_khz * 1000U);
319 f_3db_hz = clamp(f_3db_hz, 7000000U, 40000000U);
320
321#define LPF_COEFF 3200U
322 lpf_gm = DIV_ROUND_CLOSEST(f_3db_hz * gdiv28, LPF_COEFF * f_ref_khz);
323 lpf_gm = clamp_val(lpf_gm, 1U, 23U);
324
325 lpf_mxdiv = DIV_ROUND_CLOSEST(lpf_gm * LPF_COEFF * f_ref_khz, f_3db_hz);
326 if (lpf_mxdiv < div_min)
327 lpf_mxdiv = DIV_ROUND_CLOSEST(++lpf_gm * LPF_COEFF * f_ref_khz, f_3db_hz);
328 lpf_mxdiv = clamp_val(lpf_mxdiv, 0U, div_max);
329
330 ret = m88ts2022_wr_reg(priv, 0x04, lpf_mxdiv);
331 if (ret)
332 goto err;
333
334 ret = m88ts2022_wr_reg(priv, 0x06, lpf_gm);
335 if (ret)
336 goto err;
337
338 ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp);
339 if (ret)
340 goto err;
341
342 cap_code = u8tmp & 0x3f;
343
344 ret = m88ts2022_wr_reg(priv, 0x41, 0x09);
345 if (ret)
346 goto err;
347
348 ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp);
349 if (ret)
350 goto err;
351
352 u8tmp &= 0x3f;
353 cap_code = (cap_code + u8tmp) / 2;
354
355 u8tmp = cap_code | 0x80;
356 ret = m88ts2022_wr_reg(priv, 0x25, u8tmp);
357 if (ret)
358 goto err;
359
360 ret = m88ts2022_wr_reg(priv, 0x27, 0x30);
361 if (ret)
362 goto err;
363
364 ret = m88ts2022_wr_reg(priv, 0x08, 0x09);
365 if (ret)
366 goto err;
367
368 ret = m88ts2022_cmd(fe, 0x01, 20, 0x21, 0xff, 0x00, NULL);
369 if (ret)
370 goto err;
371err:
372 if (ret)
373 dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
374
375 return ret;
376}
377
378static int m88ts2022_init(struct dvb_frontend *fe)
379{
380 struct m88ts2022_priv *priv = fe->tuner_priv;
381 int ret, i;
382 u8 u8tmp;
383 static const struct m88ts2022_reg_val reg_vals[] = {
384 {0x7d, 0x9d},
385 {0x7c, 0x9a},
386 {0x7a, 0x76},
387 {0x3b, 0x01},
388 {0x63, 0x88},
389 {0x61, 0x85},
390 {0x22, 0x30},
391 {0x30, 0x40},
392 {0x20, 0x23},
393 {0x24, 0x02},
394 {0x12, 0xa0},
395 };
396 dev_dbg(&priv->client->dev, "%s:\n", __func__);
397
398 ret = m88ts2022_wr_reg(priv, 0x00, 0x01);
399 if (ret)
400 goto err;
401
402 ret = m88ts2022_wr_reg(priv, 0x00, 0x03);
403 if (ret)
404 goto err;
405
406 switch (priv->cfg.clock_out) {
407 case M88TS2022_CLOCK_OUT_DISABLED:
408 u8tmp = 0x60;
409 break;
410 case M88TS2022_CLOCK_OUT_ENABLED:
411 u8tmp = 0x70;
412 ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg.clock_out_div);
413 if (ret)
414 goto err;
415 break;
416 case M88TS2022_CLOCK_OUT_ENABLED_XTALOUT:
417 u8tmp = 0x6c;
418 break;
419 default:
420 goto err;
421 }
422
423 ret = m88ts2022_wr_reg(priv, 0x42, u8tmp);
424 if (ret)
425 goto err;
426
427 if (priv->cfg.loop_through)
428 u8tmp = 0xec;
429 else
430 u8tmp = 0x6c;
431
432 ret = m88ts2022_wr_reg(priv, 0x62, u8tmp);
433 if (ret)
434 goto err;
435
436 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
437 ret = m88ts2022_wr_reg(priv, reg_vals[i].reg, reg_vals[i].val);
438 if (ret)
439 goto err;
440 }
441err:
442 if (ret)
443 dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
444 return ret;
445}
446
447static int m88ts2022_sleep(struct dvb_frontend *fe)
448{
449 struct m88ts2022_priv *priv = fe->tuner_priv;
450 int ret;
451 dev_dbg(&priv->client->dev, "%s:\n", __func__);
452
453 ret = m88ts2022_wr_reg(priv, 0x00, 0x00);
454 if (ret)
455 goto err;
456err:
457 if (ret)
458 dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
459 return ret;
460}
461
462static int m88ts2022_get_frequency(struct dvb_frontend *fe, u32 *frequency)
463{
464 struct m88ts2022_priv *priv = fe->tuner_priv;
465 dev_dbg(&priv->client->dev, "%s:\n", __func__);
466
467 *frequency = priv->frequency_khz;
468 return 0;
469}
470
471static int m88ts2022_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
472{
473 struct m88ts2022_priv *priv = fe->tuner_priv;
474 dev_dbg(&priv->client->dev, "%s:\n", __func__);
475
476 *frequency = 0; /* Zero-IF */
477 return 0;
478}
479
480static int m88ts2022_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
481{
482 struct m88ts2022_priv *priv = fe->tuner_priv;
483 int ret;
484 u8 u8tmp;
485 u16 gain, u16tmp;
486 unsigned int gain1, gain2, gain3;
487
488 ret = m88ts2022_rd_reg(priv, 0x3d, &u8tmp);
489 if (ret)
490 goto err;
491
492 gain1 = (u8tmp >> 0) & 0x1f;
493 gain1 = clamp(gain1, 0U, 15U);
494
495 ret = m88ts2022_rd_reg(priv, 0x21, &u8tmp);
496 if (ret)
497 goto err;
498
499 gain2 = (u8tmp >> 0) & 0x1f;
500 gain2 = clamp(gain2, 2U, 16U);
501
502 ret = m88ts2022_rd_reg(priv, 0x66, &u8tmp);
503 if (ret)
504 goto err;
505
506 gain3 = (u8tmp >> 3) & 0x07;
507 gain3 = clamp(gain3, 0U, 6U);
508
509 gain = gain1 * 265 + gain2 * 338 + gain3 * 285;
510
511 /* scale value to 0x0000-0xffff */
512 u16tmp = (0xffff - gain);
513 u16tmp = clamp_val(u16tmp, 59000U, 61500U);
514
515 *strength = (u16tmp - 59000) * 0xffff / (61500 - 59000);
516err:
517 if (ret)
518 dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
519 return ret;
520}
521
522static const struct dvb_tuner_ops m88ts2022_tuner_ops = {
523 .info = {
524 .name = "Montage M88TS2022",
525 .frequency_min = 950000,
526 .frequency_max = 2150000,
527 },
528
529 .init = m88ts2022_init,
530 .sleep = m88ts2022_sleep,
531 .set_params = m88ts2022_set_params,
532
533 .get_frequency = m88ts2022_get_frequency,
534 .get_if_frequency = m88ts2022_get_if_frequency,
535 .get_rf_strength = m88ts2022_get_rf_strength,
536};
537
538static int m88ts2022_probe(struct i2c_client *client,
539 const struct i2c_device_id *id)
540{
541 struct m88ts2022_config *cfg = client->dev.platform_data;
542 struct dvb_frontend *fe = cfg->fe;
543 struct m88ts2022_priv *priv;
544 int ret;
545 u8 chip_id, u8tmp;
546
547 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
548 if (!priv) {
549 ret = -ENOMEM;
550 dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
551 goto err;
552 }
553
554 memcpy(&priv->cfg, cfg, sizeof(struct m88ts2022_config));
555 priv->client = client;
556
557 /* check if the tuner is there */
558 ret = m88ts2022_rd_reg(priv, 0x00, &u8tmp);
559 if (ret)
560 goto err;
561
562 if ((u8tmp & 0x03) == 0x00) {
563 ret = m88ts2022_wr_reg(priv, 0x00, 0x01);
564 if (ret < 0)
565 goto err;
566
567 usleep_range(2000, 50000);
568 }
569
570 ret = m88ts2022_wr_reg(priv, 0x00, 0x03);
571 if (ret)
572 goto err;
573
574 usleep_range(2000, 50000);
575
576 ret = m88ts2022_rd_reg(priv, 0x00, &chip_id);
577 if (ret)
578 goto err;
579
580 dev_dbg(&priv->client->dev, "%s: chip_id=%02x\n", __func__, chip_id);
581
582 switch (chip_id) {
583 case 0xc3:
584 case 0x83:
585 break;
586 default:
587 goto err;
588 }
589
590 switch (priv->cfg.clock_out) {
591 case M88TS2022_CLOCK_OUT_DISABLED:
592 u8tmp = 0x60;
593 break;
594 case M88TS2022_CLOCK_OUT_ENABLED:
595 u8tmp = 0x70;
596 ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg.clock_out_div);
597 if (ret)
598 goto err;
599 break;
600 case M88TS2022_CLOCK_OUT_ENABLED_XTALOUT:
601 u8tmp = 0x6c;
602 break;
603 default:
604 goto err;
605 }
606
607 ret = m88ts2022_wr_reg(priv, 0x42, u8tmp);
608 if (ret)
609 goto err;
610
611 if (priv->cfg.loop_through)
612 u8tmp = 0xec;
613 else
614 u8tmp = 0x6c;
615
616 ret = m88ts2022_wr_reg(priv, 0x62, u8tmp);
617 if (ret)
618 goto err;
619
620 /* sleep */
621 ret = m88ts2022_wr_reg(priv, 0x00, 0x00);
622 if (ret)
623 goto err;
624
625 dev_info(&priv->client->dev,
626 "%s: Montage M88TS2022 successfully identified\n",
627 KBUILD_MODNAME);
628
629 fe->tuner_priv = priv;
630 memcpy(&fe->ops.tuner_ops, &m88ts2022_tuner_ops,
631 sizeof(struct dvb_tuner_ops));
632
633 i2c_set_clientdata(client, priv);
634 return 0;
635err:
636 dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
637 kfree(priv);
638 return ret;
639}
640
641static int m88ts2022_remove(struct i2c_client *client)
642{
643 struct m88ts2022_priv *priv = i2c_get_clientdata(client);
644 struct dvb_frontend *fe = priv->cfg.fe;
645 dev_dbg(&client->dev, "%s:\n", __func__);
646
647 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
648 fe->tuner_priv = NULL;
649 kfree(priv);
650
651 return 0;
652}
653
654static const struct i2c_device_id m88ts2022_id[] = {
655 {"m88ts2022", 0},
656 {}
657};
658MODULE_DEVICE_TABLE(i2c, m88ts2022_id);
659
660static struct i2c_driver m88ts2022_driver = {
661 .driver = {
662 .owner = THIS_MODULE,
663 .name = "m88ts2022",
664 },
665 .probe = m88ts2022_probe,
666 .remove = m88ts2022_remove,
667 .id_table = m88ts2022_id,
668};
669
670module_i2c_driver(m88ts2022_driver);
671
672MODULE_DESCRIPTION("Montage M88TS2022 silicon tuner driver");
673MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
674MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/m88ts2022.h b/drivers/media/tuners/m88ts2022.h
new file mode 100644
index 000000000000..659fa1b1633a
--- /dev/null
+++ b/drivers/media/tuners/m88ts2022.h
@@ -0,0 +1,54 @@
1/*
2 * Montage M88TS2022 silicon tuner driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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#ifndef M88TS2022_H
18#define M88TS2022_H
19
20#include "dvb_frontend.h"
21
22struct m88ts2022_config {
23 /*
24 * clock
25 * 16000000 - 32000000
26 */
27 u32 clock;
28
29 /*
30 * RF loop-through
31 */
32 u8 loop_through:1;
33
34 /*
35 * clock output
36 */
37#define M88TS2022_CLOCK_OUT_DISABLED 0
38#define M88TS2022_CLOCK_OUT_ENABLED 1
39#define M88TS2022_CLOCK_OUT_ENABLED_XTALOUT 2
40 u8 clock_out:2;
41
42 /*
43 * clock output divider
44 * 1 - 31
45 */
46 u8 clock_out_div:5;
47
48 /*
49 * pointer to DVB frontend
50 */
51 struct dvb_frontend *fe;
52};
53
54#endif
diff --git a/drivers/media/tuners/m88ts2022_priv.h b/drivers/media/tuners/m88ts2022_priv.h
new file mode 100644
index 000000000000..0363dd866a2d
--- /dev/null
+++ b/drivers/media/tuners/m88ts2022_priv.h
@@ -0,0 +1,34 @@
1/*
2 * Montage M88TS2022 silicon tuner driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
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#ifndef M88TS2022_PRIV_H
18#define M88TS2022_PRIV_H
19
20#include "m88ts2022.h"
21
22struct m88ts2022_priv {
23 struct m88ts2022_config cfg;
24 struct i2c_client *client;
25 struct dvb_frontend *fe;
26 u32 frequency_khz;
27};
28
29struct m88ts2022_reg_val {
30 u8 reg;
31 u8 val;
32};
33
34#endif
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index 4be5cf808a40..cca508d4aafb 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -134,15 +134,6 @@ struct xc2028_data {
134 _rc; \ 134 _rc; \
135}) 135})
136 136
137#define i2c_rcv(priv, buf, size) ({ \
138 int _rc; \
139 _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \
140 if (size != _rc) \
141 tuner_err("i2c input error: rc = %d (should be %d)\n", \
142 _rc, (int)size); \
143 _rc; \
144})
145
146#define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({ \ 137#define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({ \
147 int _rc; \ 138 int _rc; \
148 _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize, \ 139 _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize, \
@@ -276,6 +267,7 @@ static int check_device_status(struct xc2028_data *priv)
276 case XC2028_WAITING_FIRMWARE: 267 case XC2028_WAITING_FIRMWARE:
277 return -EAGAIN; 268 return -EAGAIN;
278 case XC2028_ACTIVE: 269 case XC2028_ACTIVE:
270 return 1;
279 case XC2028_SLEEP: 271 case XC2028_SLEEP:
280 return 0; 272 return 0;
281 case XC2028_NODEV: 273 case XC2028_NODEV:
@@ -718,6 +710,8 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type,
718 return 0; 710 return 0;
719} 711}
720 712
713static int xc2028_sleep(struct dvb_frontend *fe);
714
721static int check_firmware(struct dvb_frontend *fe, unsigned int type, 715static int check_firmware(struct dvb_frontend *fe, unsigned int type,
722 v4l2_std_id std, __u16 int_freq) 716 v4l2_std_id std, __u16 int_freq)
723{ 717{
@@ -890,7 +884,7 @@ read_not_reliable:
890 return 0; 884 return 0;
891 885
892fail: 886fail:
893 priv->state = XC2028_SLEEP; 887 priv->state = XC2028_NO_FIRMWARE;
894 888
895 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 889 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
896 if (retry_count < 8) { 890 if (retry_count < 8) {
@@ -900,6 +894,9 @@ fail:
900 goto retry; 894 goto retry;
901 } 895 }
902 896
897 /* Firmware didn't load. Put the device to sleep */
898 xc2028_sleep(fe);
899
903 if (rc == -ENOENT) 900 if (rc == -ENOENT)
904 rc = -EINVAL; 901 rc = -EINVAL;
905 return rc; 902 return rc;
@@ -917,6 +914,12 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
917 if (rc < 0) 914 if (rc < 0)
918 return rc; 915 return rc;
919 916
917 /* If the device is sleeping, no channel is tuned */
918 if (!rc) {
919 *strength = 0;
920 return 0;
921 }
922
920 mutex_lock(&priv->lock); 923 mutex_lock(&priv->lock);
921 924
922 /* Sync Lock Indicator */ 925 /* Sync Lock Indicator */
@@ -964,6 +967,12 @@ static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc)
964 if (rc < 0) 967 if (rc < 0)
965 return rc; 968 return rc;
966 969
970 /* If the device is sleeping, no channel is tuned */
971 if (!rc) {
972 *afc = 0;
973 return 0;
974 }
975
967 mutex_lock(&priv->lock); 976 mutex_lock(&priv->lock);
968 977
969 /* Sync Lock Indicator */ 978 /* Sync Lock Indicator */
@@ -1281,6 +1290,10 @@ static int xc2028_sleep(struct dvb_frontend *fe)
1281 if (rc < 0) 1290 if (rc < 0)
1282 return rc; 1291 return rc;
1283 1292
1293 /* Device is already in sleep mode */
1294 if (!rc)
1295 return 0;
1296
1284 /* Avoid firmware reload on slow devices or if PM disabled */ 1297 /* Avoid firmware reload on slow devices or if PM disabled */
1285 if (no_poweroff || priv->ctrl.disable_power_mgmt) 1298 if (no_poweroff || priv->ctrl.disable_power_mgmt)
1286 return 0; 1299 return 0;
@@ -1298,7 +1311,8 @@ static int xc2028_sleep(struct dvb_frontend *fe)
1298 else 1311 else
1299 rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); 1312 rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
1300 1313
1301 priv->state = XC2028_SLEEP; 1314 if (rc >= 0)
1315 priv->state = XC2028_SLEEP;
1302 1316
1303 mutex_unlock(&priv->lock); 1317 mutex_unlock(&priv->lock);
1304 1318
@@ -1366,7 +1380,7 @@ static void load_firmware_cb(const struct firmware *fw,
1366 1380
1367 if (rc < 0) 1381 if (rc < 0)
1368 return; 1382 return;
1369 priv->state = XC2028_SLEEP; 1383 priv->state = XC2028_ACTIVE;
1370} 1384}
1371 1385
1372static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) 1386static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index cfe8056b91aa..39d824e2bb69 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -17,7 +17,6 @@ source "drivers/media/usb/cpia2/Kconfig"
17source "drivers/media/usb/zr364xx/Kconfig" 17source "drivers/media/usb/zr364xx/Kconfig"
18source "drivers/media/usb/stkwebcam/Kconfig" 18source "drivers/media/usb/stkwebcam/Kconfig"
19source "drivers/media/usb/s2255/Kconfig" 19source "drivers/media/usb/s2255/Kconfig"
20source "drivers/media/usb/sn9c102/Kconfig"
21source "drivers/media/usb/usbtv/Kconfig" 20source "drivers/media/usb/usbtv/Kconfig"
22endif 21endif
23 22
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 0935f47497a6..7ac4b143dce8 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
10obj-$(CONFIG_USB_GSPCA) += gspca/ 10obj-$(CONFIG_USB_GSPCA) += gspca/
11obj-$(CONFIG_USB_PWC) += pwc/ 11obj-$(CONFIG_USB_PWC) += pwc/
12obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ 12obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
13obj-$(CONFIG_USB_SN9C102) += sn9c102/
14obj-$(CONFIG_VIDEO_AU0828) += au0828/ 13obj-$(CONFIG_VIDEO_AU0828) += au0828/
15obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/ 14obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
16obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 15obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index bd9d19a73efd..ab45a6f9dcc9 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -173,9 +173,8 @@ static int au0828_usb_probe(struct usb_interface *interface,
173 const struct usb_device_id *id) 173 const struct usb_device_id *id)
174{ 174{
175 int ifnum; 175 int ifnum;
176#ifdef CONFIG_VIDEO_AU0828_V4L2 176 int retval = 0;
177 int retval; 177
178#endif
179 struct au0828_dev *dev; 178 struct au0828_dev *dev;
180 struct usb_device *usbdev = interface_to_usbdev(interface); 179 struct usb_device *usbdev = interface_to_usbdev(interface);
181 180
@@ -257,7 +256,11 @@ static int au0828_usb_probe(struct usb_interface *interface,
257#endif 256#endif
258 257
259 /* Digital TV */ 258 /* Digital TV */
260 au0828_dvb_register(dev); 259 retval = au0828_dvb_register(dev);
260 if (retval)
261 pr_err("%s() au0282_dev_register failed\n",
262 __func__);
263
261 264
262 /* Store the pointer to the au0828_dev so it can be accessed in 265 /* Store the pointer to the au0828_dev so it can be accessed in
263 au0828_usb_disconnect */ 266 au0828_usb_disconnect */
@@ -268,7 +271,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
268 271
269 mutex_unlock(&dev->lock); 272 mutex_unlock(&dev->lock);
270 273
271 return 0; 274 return retval;
272} 275}
273 276
274static struct usb_driver au0828_usb_driver = { 277static struct usb_driver au0828_usb_driver = {
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 9a6f15613a38..4ae8b1074649 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -33,6 +33,10 @@
33#include "mxl5007t.h" 33#include "mxl5007t.h"
34#include "tda18271.h" 34#include "tda18271.h"
35 35
36static int preallocate_big_buffers;
37module_param_named(preallocate_big_buffers, preallocate_big_buffers, int, 0644);
38MODULE_PARM_DESC(preallocate_big_buffers, "Preallocate the larger transfer buffers at module load time");
39
36DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
37 41
38#define _AU0828_BULKPIPE 0x83 42#define _AU0828_BULKPIPE 0x83
@@ -153,9 +157,13 @@ static int stop_urb_transfer(struct au0828_dev *dev)
153 157
154 dev->urb_streaming = 0; 158 dev->urb_streaming = 0;
155 for (i = 0; i < URB_COUNT; i++) { 159 for (i = 0; i < URB_COUNT; i++) {
156 usb_kill_urb(dev->urbs[i]); 160 if (dev->urbs[i]) {
157 kfree(dev->urbs[i]->transfer_buffer); 161 usb_kill_urb(dev->urbs[i]);
158 usb_free_urb(dev->urbs[i]); 162 if (!preallocate_big_buffers)
163 kfree(dev->urbs[i]->transfer_buffer);
164
165 usb_free_urb(dev->urbs[i]);
166 }
159 } 167 }
160 168
161 return 0; 169 return 0;
@@ -181,10 +189,18 @@ static int start_urb_transfer(struct au0828_dev *dev)
181 189
182 purb = dev->urbs[i]; 190 purb = dev->urbs[i];
183 191
184 purb->transfer_buffer = kzalloc(URB_BUFSIZE, GFP_KERNEL); 192 if (preallocate_big_buffers)
193 purb->transfer_buffer = dev->dig_transfer_buffer[i];
194 else
195 purb->transfer_buffer = kzalloc(URB_BUFSIZE,
196 GFP_KERNEL);
197
185 if (!purb->transfer_buffer) { 198 if (!purb->transfer_buffer) {
186 usb_free_urb(purb); 199 usb_free_urb(purb);
187 dev->urbs[i] = NULL; 200 dev->urbs[i] = NULL;
201 printk(KERN_ERR
202 "%s: failed big buffer allocation, err = %d\n",
203 __func__, ret);
188 goto err; 204 goto err;
189 } 205 }
190 206
@@ -217,6 +233,27 @@ err:
217 return ret; 233 return ret;
218} 234}
219 235
236static void au0828_start_transport(struct au0828_dev *dev)
237{
238 au0828_write(dev, 0x608, 0x90);
239 au0828_write(dev, 0x609, 0x72);
240 au0828_write(dev, 0x60a, 0x71);
241 au0828_write(dev, 0x60b, 0x01);
242
243}
244
245static void au0828_stop_transport(struct au0828_dev *dev, int full_stop)
246{
247 if (full_stop) {
248 au0828_write(dev, 0x608, 0x00);
249 au0828_write(dev, 0x609, 0x00);
250 au0828_write(dev, 0x60a, 0x00);
251 }
252 au0828_write(dev, 0x60b, 0x00);
253}
254
255
256
220static int au0828_dvb_start_feed(struct dvb_demux_feed *feed) 257static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
221{ 258{
222 struct dvb_demux *demux = feed->demux; 259 struct dvb_demux *demux = feed->demux;
@@ -231,13 +268,17 @@ static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
231 268
232 if (dvb) { 269 if (dvb) {
233 mutex_lock(&dvb->lock); 270 mutex_lock(&dvb->lock);
271 dvb->start_count++;
272 dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
273 dvb->start_count, dvb->stop_count);
234 if (dvb->feeding++ == 0) { 274 if (dvb->feeding++ == 0) {
235 /* Start transport */ 275 /* Start transport */
236 au0828_write(dev, 0x608, 0x90); 276 au0828_start_transport(dev);
237 au0828_write(dev, 0x609, 0x72);
238 au0828_write(dev, 0x60a, 0x71);
239 au0828_write(dev, 0x60b, 0x01);
240 ret = start_urb_transfer(dev); 277 ret = start_urb_transfer(dev);
278 if (ret < 0) {
279 au0828_stop_transport(dev, 0);
280 dvb->feeding--; /* We ran out of memory... */
281 }
241 } 282 }
242 mutex_unlock(&dvb->lock); 283 mutex_unlock(&dvb->lock);
243 } 284 }
@@ -256,10 +297,16 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
256 297
257 if (dvb) { 298 if (dvb) {
258 mutex_lock(&dvb->lock); 299 mutex_lock(&dvb->lock);
259 if (--dvb->feeding == 0) { 300 dvb->stop_count++;
260 /* Stop transport */ 301 dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
261 ret = stop_urb_transfer(dev); 302 dvb->start_count, dvb->stop_count);
262 au0828_write(dev, 0x60b, 0x00); 303 if (dvb->feeding > 0) {
304 dvb->feeding--;
305 if (dvb->feeding == 0) {
306 /* Stop transport */
307 ret = stop_urb_transfer(dev);
308 au0828_stop_transport(dev, 0);
309 }
263 } 310 }
264 mutex_unlock(&dvb->lock); 311 mutex_unlock(&dvb->lock);
265 } 312 }
@@ -282,16 +329,10 @@ static void au0828_restart_dvb_streaming(struct work_struct *work)
282 329
283 /* Stop transport */ 330 /* Stop transport */
284 stop_urb_transfer(dev); 331 stop_urb_transfer(dev);
285 au0828_write(dev, 0x608, 0x00); 332 au0828_stop_transport(dev, 1);
286 au0828_write(dev, 0x609, 0x00);
287 au0828_write(dev, 0x60a, 0x00);
288 au0828_write(dev, 0x60b, 0x00);
289 333
290 /* Start transport */ 334 /* Start transport */
291 au0828_write(dev, 0x608, 0x90); 335 au0828_start_transport(dev);
292 au0828_write(dev, 0x609, 0x72);
293 au0828_write(dev, 0x60a, 0x71);
294 au0828_write(dev, 0x60b, 0x01);
295 start_urb_transfer(dev); 336 start_urb_transfer(dev);
296 337
297 mutex_unlock(&dvb->lock); 338 mutex_unlock(&dvb->lock);
@@ -304,6 +345,23 @@ static int dvb_register(struct au0828_dev *dev)
304 345
305 dprintk(1, "%s()\n", __func__); 346 dprintk(1, "%s()\n", __func__);
306 347
348 if (preallocate_big_buffers) {
349 int i;
350 for (i = 0; i < URB_COUNT; i++) {
351 dev->dig_transfer_buffer[i] = kzalloc(URB_BUFSIZE,
352 GFP_KERNEL);
353
354 if (!dev->dig_transfer_buffer[i]) {
355 result = -ENOMEM;
356
357 printk(KERN_ERR
358 "%s: failed buffer allocation (errno = %d)\n",
359 DRIVER_NAME, result);
360 goto fail_adapter;
361 }
362 }
363 }
364
307 INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming); 365 INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);
308 366
309 /* register adapter */ 367 /* register adapter */
@@ -375,6 +433,9 @@ static int dvb_register(struct au0828_dev *dev)
375 433
376 /* register network adapter */ 434 /* register network adapter */
377 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 435 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
436
437 dvb->start_count = 0;
438 dvb->stop_count = 0;
378 return 0; 439 return 0;
379 440
380fail_fe_conn: 441fail_fe_conn:
@@ -391,6 +452,13 @@ fail_frontend:
391 dvb_frontend_detach(dvb->frontend); 452 dvb_frontend_detach(dvb->frontend);
392 dvb_unregister_adapter(&dvb->adapter); 453 dvb_unregister_adapter(&dvb->adapter);
393fail_adapter: 454fail_adapter:
455
456 if (preallocate_big_buffers) {
457 int i;
458 for (i = 0; i < URB_COUNT; i++)
459 kfree(dev->dig_transfer_buffer[i]);
460 }
461
394 return result; 462 return result;
395} 463}
396 464
@@ -411,6 +479,14 @@ void au0828_dvb_unregister(struct au0828_dev *dev)
411 dvb_unregister_frontend(dvb->frontend); 479 dvb_unregister_frontend(dvb->frontend);
412 dvb_frontend_detach(dvb->frontend); 480 dvb_frontend_detach(dvb->frontend);
413 dvb_unregister_adapter(&dvb->adapter); 481 dvb_unregister_adapter(&dvb->adapter);
482
483 if (preallocate_big_buffers) {
484 int i;
485 for (i = 0; i < URB_COUNT; i++)
486 kfree(dev->dig_transfer_buffer[i]);
487 }
488
489
414} 490}
415 491
416/* All the DVB attach calls go here, this function get's modified 492/* All the DVB attach calls go here, this function get's modified
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index ef1f57f22be7..5439772c1551 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -102,6 +102,8 @@ struct au0828_dvb {
102 struct dmx_frontend fe_mem; 102 struct dmx_frontend fe_mem;
103 struct dvb_net net; 103 struct dvb_net net;
104 int feeding; 104 int feeding;
105 int start_count;
106 int stop_count;
105}; 107};
106 108
107enum au0828_stream_state { 109enum au0828_stream_state {
@@ -260,6 +262,10 @@ struct au0828_dev {
260 /* USB / URB Related */ 262 /* USB / URB Related */
261 int urb_streaming; 263 int urb_streaming;
262 struct urb *urbs[URB_COUNT]; 264 struct urb *urbs[URB_COUNT];
265
266 /* Preallocated transfer digital transfer buffers */
267
268 char *dig_transfer_buffer[URB_COUNT];
263}; 269};
264 270
265/* ----------------------------------------------------------- */ 271/* ----------------------------------------------------------- */
diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig
index 86feeeaf61c2..f14c5e89a567 100644
--- a/drivers/media/usb/cx231xx/Kconfig
+++ b/drivers/media/usb/cx231xx/Kconfig
@@ -45,6 +45,8 @@ config VIDEO_CX231XX_DVB
45 select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT 45 select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
46 select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT 46 select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
47 select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT 47 select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
48 select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
49 select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
48 50
49 ---help--- 51 ---help---
50 This adds support for DVB cards based on the 52 This adds support for DVB cards based on the
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 528cce958a82..2ee03e4ddd86 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -709,6 +709,8 @@ const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
709 709
710/* table of devices that work with this driver */ 710/* table of devices that work with this driver */
711struct usb_device_id cx231xx_id_table[] = { 711struct usb_device_id cx231xx_id_table[] = {
712 {USB_DEVICE(0x1D19, 0x6109),
713 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
712 {USB_DEVICE(0x0572, 0x5A3C), 714 {USB_DEVICE(0x0572, 0x5A3C),
713 .driver_info = CX231XX_BOARD_UNKNOWN}, 715 .driver_info = CX231XX_BOARD_UNKNOWN},
714 {USB_DEVICE(0x0572, 0x58A2), 716 {USB_DEVICE(0x0572, 0x58A2),
diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c
index 96a5a0965399..7c0f797f1057 100644
--- a/drivers/media/usb/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c
@@ -371,9 +371,9 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
371 mutex_lock(&dev->i2c_lock); 371 mutex_lock(&dev->i2c_lock);
372 for (i = 0; i < num; i++) { 372 for (i = 0; i < num; i++) {
373 373
374 addr = msgs[i].addr >> 1; 374 addr = msgs[i].addr;
375 375
376 dprintk2(2, "%s %s addr=%x len=%d:", 376 dprintk2(2, "%s %s addr=0x%x len=%d:",
377 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 377 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
378 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); 378 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
379 if (!msgs[i].len) { 379 if (!msgs[i].len) {
@@ -390,32 +390,41 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
390 rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]); 390 rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]);
391 if (i2c_debug >= 2) { 391 if (i2c_debug >= 2) {
392 for (byte = 0; byte < msgs[i].len; byte++) 392 for (byte = 0; byte < msgs[i].len; byte++)
393 printk(" %02x", msgs[i].buf[byte]); 393 printk(KERN_CONT " %02x", msgs[i].buf[byte]);
394 } 394 }
395 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && 395 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
396 msgs[i].addr == msgs[i + 1].addr 396 msgs[i].addr == msgs[i + 1].addr
397 && (msgs[i].len <= 2) && (bus->nr < 3)) { 397 && (msgs[i].len <= 2) && (bus->nr < 3)) {
398 /* write bytes */
399 if (i2c_debug >= 2) {
400 for (byte = 0; byte < msgs[i].len; byte++)
401 printk(KERN_CONT " %02x", msgs[i].buf[byte]);
402 printk(KERN_CONT "\n");
403 }
398 /* read bytes */ 404 /* read bytes */
405 dprintk2(2, "plus %s %s addr=0x%x len=%d:",
406 (msgs[i+1].flags & I2C_M_RD) ? "read" : "write",
407 i+1 == num - 1 ? "stop" : "nonstop", addr, msgs[i+1].len);
399 rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap, 408 rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap,
400 &msgs[i], 409 &msgs[i],
401 &msgs[i + 1]); 410 &msgs[i + 1]);
402 if (i2c_debug >= 2) { 411 if (i2c_debug >= 2) {
403 for (byte = 0; byte < msgs[i].len; byte++) 412 for (byte = 0; byte < msgs[i+1].len; byte++)
404 printk(" %02x", msgs[i].buf[byte]); 413 printk(KERN_CONT " %02x", msgs[i+1].buf[byte]);
405 } 414 }
406 i++; 415 i++;
407 } else { 416 } else {
408 /* write bytes */ 417 /* write bytes */
409 if (i2c_debug >= 2) { 418 if (i2c_debug >= 2) {
410 for (byte = 0; byte < msgs[i].len; byte++) 419 for (byte = 0; byte < msgs[i].len; byte++)
411 printk(" %02x", msgs[i].buf[byte]); 420 printk(KERN_CONT " %02x", msgs[i].buf[byte]);
412 } 421 }
413 rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]); 422 rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]);
414 } 423 }
415 if (rc < 0) 424 if (rc < 0)
416 goto err; 425 goto err;
417 if (i2c_debug >= 2) 426 if (i2c_debug >= 2)
418 printk("\n"); 427 printk(KERN_CONT "\n");
419 } 428 }
420 mutex_unlock(&dev->i2c_lock); 429 mutex_unlock(&dev->i2c_lock);
421 return num; 430 return num;
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
index 90cfa35ef6e6..eeab79bdd2aa 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.c
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -442,6 +442,7 @@ static struct cxd2820r_config anysee_cxd2820r_config = {
442 * IOD[0] ZL10353 1=enabled 442 * IOD[0] ZL10353 1=enabled
443 * IOE[0] tuner 0=enabled 443 * IOE[0] tuner 0=enabled
444 * tuner is behind ZL10353 I2C-gate 444 * tuner is behind ZL10353 I2C-gate
445 * tuner is behind TDA10023 I2C-gate
445 * 446 *
446 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)" 447 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
447 * PCB: 508TC (rev0.6) 448 * PCB: 508TC (rev0.6)
@@ -956,7 +957,7 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
956 957
957 if (fe && adap->fe[1]) { 958 if (fe && adap->fe[1]) {
958 /* attach tuner for 2nd FE */ 959 /* attach tuner for 2nd FE */
959 fe = dvb_attach(dvb_pll_attach, adap->fe[0], 960 fe = dvb_attach(dvb_pll_attach, adap->fe[1],
960 (0xc0 >> 1), &d->i2c_adap, 961 (0xc0 >> 1), &d->i2c_adap,
961 DVB_PLL_SAMSUNG_DTOS403IH102A); 962 DVB_PLL_SAMSUNG_DTOS403IH102A);
962 } 963 }
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 44c64ef361bf..c1051c347744 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -68,6 +68,19 @@ static struct drxk_config terratec_h7_drxk = {
68 .microcode_name = "dvb-usb-terratec-h7-drxk.fw", 68 .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
69}; 69};
70 70
71static struct drxk_config cablestar_hdci_drxk = {
72 .adr = 0x29,
73 .parallel_ts = true,
74 .dynamic_clk = true,
75 .single_master = true,
76 .enable_merr_cfg = true,
77 .no_i2c_bridge = false,
78 .chunk_size = 64,
79 .mpeg_out_clk_strength = 0x02,
80 .qam_demod_parameter_count = 2,
81 .microcode_name = "dvb-usb-technisat-cablestar-hdci-drxk.fw",
82};
83
71static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 84static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
72{ 85{
73 struct az6007_device_state *st = fe_to_priv(fe); 86 struct az6007_device_state *st = fe_to_priv(fe);
@@ -630,6 +643,27 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
630 return 0; 643 return 0;
631} 644}
632 645
646static int az6007_cablestar_hdci_frontend_attach(struct dvb_usb_adapter *adap)
647{
648 struct az6007_device_state *st = adap_to_priv(adap);
649 struct dvb_usb_device *d = adap_to_d(adap);
650
651 pr_debug("attaching demod drxk\n");
652
653 adap->fe[0] = dvb_attach(drxk_attach, &cablestar_hdci_drxk,
654 &d->i2c_adap);
655 if (!adap->fe[0])
656 return -EINVAL;
657
658 adap->fe[0]->sec_priv = adap;
659 st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
660 adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
661
662 az6007_ci_init(adap);
663
664 return 0;
665}
666
633static int az6007_tuner_attach(struct dvb_usb_adapter *adap) 667static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
634{ 668{
635 struct dvb_usb_device *d = adap_to_d(adap); 669 struct dvb_usb_device *d = adap_to_d(adap);
@@ -868,6 +902,29 @@ static struct dvb_usb_device_properties az6007_props = {
868 } 902 }
869}; 903};
870 904
905static struct dvb_usb_device_properties az6007_cablestar_hdci_props = {
906 .driver_name = KBUILD_MODNAME,
907 .owner = THIS_MODULE,
908 .firmware = AZ6007_FIRMWARE,
909
910 .adapter_nr = adapter_nr,
911 .size_of_priv = sizeof(struct az6007_device_state),
912 .i2c_algo = &az6007_i2c_algo,
913 .tuner_attach = az6007_tuner_attach,
914 .frontend_attach = az6007_cablestar_hdci_frontend_attach,
915 .streaming_ctrl = az6007_streaming_ctrl,
916/* ditch get_rc_config as it can't work (TS35 remote, I believe it's rc5) */
917 .get_rc_config = NULL,
918 .read_mac_address = az6007_read_mac_addr,
919 .download_firmware = az6007_download_firmware,
920 .identify_state = az6007_identify_state,
921 .power_ctrl = az6007_power_ctrl,
922 .num_adapters = 1,
923 .adapter = {
924 { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
925 }
926};
927
871static struct usb_device_id az6007_usb_table[] = { 928static struct usb_device_id az6007_usb_table[] = {
872 {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007, 929 {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007,
873 &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)}, 930 &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)},
@@ -875,6 +932,8 @@ static struct usb_device_id az6007_usb_table[] = {
875 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)}, 932 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
876 {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2, 933 {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2,
877 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)}, 934 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
935 {DVB_USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_CABLESTAR_HDCI,
936 &az6007_cablestar_hdci_props, "Technisat CableStar Combo HD CI", RC_MAP_EMPTY)},
878 {0}, 937 {0},
879}; 938};
880 939
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
index 5c68f3918bc8..0c2b377704ff 100644
--- a/drivers/media/usb/dvb-usb-v2/ec168.c
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -170,7 +170,7 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
170 170
171error: 171error:
172 mutex_unlock(&d->i2c_mutex); 172 mutex_unlock(&d->i2c_mutex);
173 return i; 173 return ret;
174} 174}
175 175
176static u32 ec168_i2c_func(struct i2c_adapter *adapter) 176static u32 ec168_i2c_func(struct i2c_adapter *adapter)
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
index 1cb6899cf797..fe95a586dd5d 100644
--- a/drivers/media/usb/dvb-usb-v2/it913x.c
+++ b/drivers/media/usb/dvb-usb-v2/it913x.c
@@ -799,6 +799,9 @@ static const struct usb_device_id it913x_id_table[] = {
799 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2, 799 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
800 &it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2", 800 &it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2",
801 RC_MAP_IT913X_V1) }, 801 RC_MAP_IT913X_V1) },
802 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
803 &it913x_properties, "Avermedia H335",
804 RC_MAP_IT913X_V2) },
802 {} /* Terminating entry */ 805 {} /* Terminating entry */
803}; 806};
804 807
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index ecca03667f98..fda5c64ba0e8 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1407,6 +1407,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
1407 &rtl2832u_props, "Dexatek DK DVB-T Dongle", NULL) }, 1407 &rtl2832u_props, "Dexatek DK DVB-T Dongle", NULL) },
1408 { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6680, 1408 { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6680,
1409 &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) }, 1409 &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) },
1410 { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_MINID,
1411 &rtl2832u_props, "Leadtek Winfast DTV Dongle Mini D", NULL) },
1410 { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3, 1412 { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3,
1411 &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) }, 1413 &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) },
1412 { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102, 1414 { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102,
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 20e345d9fe8f..a1c641e18362 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -149,6 +149,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
149 int num) 149 int num)
150{ 150{
151 struct dvb_usb_device *d = i2c_get_adapdata(adap); 151 struct dvb_usb_device *d = i2c_get_adapdata(adap);
152 int ret;
152 int i; 153 int i;
153 154
154 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 155 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
@@ -173,7 +174,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
173 if (1 + msg[i].len > sizeof(ibuf)) { 174 if (1 + msg[i].len > sizeof(ibuf)) {
174 warn("i2c rd: len=%d is too big!\n", 175 warn("i2c rd: len=%d is too big!\n",
175 msg[i].len); 176 msg[i].len);
176 return -EOPNOTSUPP; 177 ret = -EOPNOTSUPP;
178 goto unlock;
177 } 179 }
178 obuf[0] = 0; 180 obuf[0] = 0;
179 obuf[1] = msg[i].len; 181 obuf[1] = msg[i].len;
@@ -193,12 +195,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
193 if (3 + msg[i].len > sizeof(obuf)) { 195 if (3 + msg[i].len > sizeof(obuf)) {
194 warn("i2c wr: len=%d is too big!\n", 196 warn("i2c wr: len=%d is too big!\n",
195 msg[i].len); 197 msg[i].len);
196 return -EOPNOTSUPP; 198 ret = -EOPNOTSUPP;
199 goto unlock;
197 } 200 }
198 if (1 + msg[i + 1].len > sizeof(ibuf)) { 201 if (1 + msg[i + 1].len > sizeof(ibuf)) {
199 warn("i2c rd: len=%d is too big!\n", 202 warn("i2c rd: len=%d is too big!\n",
200 msg[i + 1].len); 203 msg[i + 1].len);
201 return -EOPNOTSUPP; 204 ret = -EOPNOTSUPP;
205 goto unlock;
202 } 206 }
203 obuf[0] = msg[i].len; 207 obuf[0] = msg[i].len;
204 obuf[1] = msg[i+1].len; 208 obuf[1] = msg[i+1].len;
@@ -223,7 +227,8 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
223 if (2 + msg[i].len > sizeof(obuf)) { 227 if (2 + msg[i].len > sizeof(obuf)) {
224 warn("i2c wr: len=%d is too big!\n", 228 warn("i2c wr: len=%d is too big!\n",
225 msg[i].len); 229 msg[i].len);
226 return -EOPNOTSUPP; 230 ret = -EOPNOTSUPP;
231 goto unlock;
227 } 232 }
228 obuf[0] = msg[i].addr; 233 obuf[0] = msg[i].addr;
229 obuf[1] = msg[i].len; 234 obuf[1] = msg[i].len;
@@ -237,8 +242,14 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
237 } 242 }
238 } 243 }
239 244
245 if (i == num)
246 ret = num;
247 else
248 ret = -EREMOTEIO;
249
250unlock:
240 mutex_unlock(&d->i2c_mutex); 251 mutex_unlock(&d->i2c_mutex);
241 return i == num ? num : -EREMOTEIO; 252 return ret;
242} 253}
243 254
244static u32 cxusb_i2c_func(struct i2c_adapter *adapter) 255static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index c1a63b2a6baa..ae0f56a32e4d 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -2,7 +2,7 @@
2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3 * TeVii S600, S630, S650, S660, S480, S421, S632 3 * TeVii S600, S630, S650, S660, S480, S421, S632
4 * Prof 1100, 7500, 4 * Prof 1100, 7500,
5 * Geniatech SU3000 Cards 5 * Geniatech SU3000, T220 Cards
6 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by) 6 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
@@ -29,6 +29,8 @@
29#include "stb6100.h" 29#include "stb6100.h"
30#include "stb6100_proc.h" 30#include "stb6100_proc.h"
31#include "m88rs2000.h" 31#include "m88rs2000.h"
32#include "tda18271.h"
33#include "cxd2820r.h"
32 34
33/* Max transfer size done by I2C transfer functions */ 35/* Max transfer size done by I2C transfer functions */
34#define MAX_XFER_SIZE 64 36#define MAX_XFER_SIZE 64
@@ -110,11 +112,6 @@
110 "Please see linux/Documentation/dvb/ for more details " \ 112 "Please see linux/Documentation/dvb/ for more details " \
111 "on firmware-problems." 113 "on firmware-problems."
112 114
113struct rc_map_dvb_usb_table_table {
114 struct rc_map_table *rc_keys;
115 int rc_keys_size;
116};
117
118struct su3000_state { 115struct su3000_state {
119 u8 initialized; 116 u8 initialized;
120}; 117};
@@ -129,12 +126,6 @@ module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
129MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." 126MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
130 DVB_USB_DEBUG_STATUS); 127 DVB_USB_DEBUG_STATUS);
131 128
132/* keymaps */
133static int ir_keymap;
134module_param_named(keymap, ir_keymap, int, 0644);
135MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
136 " 256=none");
137
138/* demod probe */ 129/* demod probe */
139static int demod_probe = 1; 130static int demod_probe = 1;
140module_param_named(demod, demod_probe, int, 0644); 131module_param_named(demod, demod_probe, int, 0644);
@@ -301,6 +292,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
301static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 292static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
302{ 293{
303 struct dvb_usb_device *d = i2c_get_adapdata(adap); 294 struct dvb_usb_device *d = i2c_get_adapdata(adap);
295 int ret;
304 296
305 if (!d) 297 if (!d)
306 return -ENODEV; 298 return -ENODEV;
@@ -316,7 +308,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
316 if (2 + msg[1].len > sizeof(ibuf)) { 308 if (2 + msg[1].len > sizeof(ibuf)) {
317 warn("i2c rd: len=%d is too big!\n", 309 warn("i2c rd: len=%d is too big!\n",
318 msg[1].len); 310 msg[1].len);
319 return -EOPNOTSUPP; 311 ret = -EOPNOTSUPP;
312 goto unlock;
320 } 313 }
321 314
322 obuf[0] = msg[0].addr << 1; 315 obuf[0] = msg[0].addr << 1;
@@ -340,7 +333,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
340 if (2 + msg[0].len > sizeof(obuf)) { 333 if (2 + msg[0].len > sizeof(obuf)) {
341 warn("i2c wr: len=%d is too big!\n", 334 warn("i2c wr: len=%d is too big!\n",
342 msg[1].len); 335 msg[1].len);
343 return -EOPNOTSUPP; 336 ret = -EOPNOTSUPP;
337 goto unlock;
344 } 338 }
345 339
346 obuf[0] = msg[0].addr << 1; 340 obuf[0] = msg[0].addr << 1;
@@ -357,7 +351,8 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
357 if (2 + msg[0].len > sizeof(obuf)) { 351 if (2 + msg[0].len > sizeof(obuf)) {
358 warn("i2c wr: len=%d is too big!\n", 352 warn("i2c wr: len=%d is too big!\n",
359 msg[1].len); 353 msg[1].len);
360 return -EOPNOTSUPP; 354 ret = -EOPNOTSUPP;
355 goto unlock;
361 } 356 }
362 357
363 obuf[0] = msg[0].addr << 1; 358 obuf[0] = msg[0].addr << 1;
@@ -386,15 +381,17 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
386 381
387 break; 382 break;
388 } 383 }
384 ret = num;
389 385
386unlock:
390 mutex_unlock(&d->i2c_mutex); 387 mutex_unlock(&d->i2c_mutex);
391 return num; 388 return ret;
392} 389}
393 390
394static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 391static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
395{ 392{
396 struct dvb_usb_device *d = i2c_get_adapdata(adap); 393 struct dvb_usb_device *d = i2c_get_adapdata(adap);
397 int len, i, j; 394 int len, i, j, ret;
398 395
399 if (!d) 396 if (!d)
400 return -ENODEV; 397 return -ENODEV;
@@ -430,7 +427,8 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
430 if (2 + msg[j].len > sizeof(ibuf)) { 427 if (2 + msg[j].len > sizeof(ibuf)) {
431 warn("i2c rd: len=%d is too big!\n", 428 warn("i2c rd: len=%d is too big!\n",
432 msg[j].len); 429 msg[j].len);
433 return -EOPNOTSUPP; 430 ret = -EOPNOTSUPP;
431 goto unlock;
434 } 432 }
435 433
436 dw210x_op_rw(d->udev, 0xc3, 434 dw210x_op_rw(d->udev, 0xc3,
@@ -466,7 +464,8 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
466 if (2 + msg[j].len > sizeof(obuf)) { 464 if (2 + msg[j].len > sizeof(obuf)) {
467 warn("i2c wr: len=%d is too big!\n", 465 warn("i2c wr: len=%d is too big!\n",
468 msg[j].len); 466 msg[j].len);
469 return -EOPNOTSUPP; 467 ret = -EOPNOTSUPP;
468 goto unlock;
470 } 469 }
471 470
472 obuf[0] = msg[j].addr << 1; 471 obuf[0] = msg[j].addr << 1;
@@ -481,15 +480,18 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
481 } 480 }
482 481
483 } 482 }
483 ret = num;
484 484
485unlock:
485 mutex_unlock(&d->i2c_mutex); 486 mutex_unlock(&d->i2c_mutex);
486 return num; 487 return ret;
487} 488}
488 489
489static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 490static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
490 int num) 491 int num)
491{ 492{
492 struct dvb_usb_device *d = i2c_get_adapdata(adap); 493 struct dvb_usb_device *d = i2c_get_adapdata(adap);
494 int ret;
493 int i; 495 int i;
494 496
495 if (!d) 497 if (!d)
@@ -506,7 +508,8 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
506 if (2 + msg[1].len > sizeof(ibuf)) { 508 if (2 + msg[1].len > sizeof(ibuf)) {
507 warn("i2c rd: len=%d is too big!\n", 509 warn("i2c rd: len=%d is too big!\n",
508 msg[1].len); 510 msg[1].len);
509 return -EOPNOTSUPP; 511 ret = -EOPNOTSUPP;
512 goto unlock;
510 } 513 }
511 obuf[0] = msg[0].addr << 1; 514 obuf[0] = msg[0].addr << 1;
512 obuf[1] = msg[0].len; 515 obuf[1] = msg[0].len;
@@ -530,7 +533,8 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
530 if (2 + msg[0].len > sizeof(obuf)) { 533 if (2 + msg[0].len > sizeof(obuf)) {
531 warn("i2c wr: len=%d is too big!\n", 534 warn("i2c wr: len=%d is too big!\n",
532 msg[0].len); 535 msg[0].len);
533 return -EOPNOTSUPP; 536 ret = -EOPNOTSUPP;
537 goto unlock;
534 } 538 }
535 obuf[0] = msg[0].addr << 1; 539 obuf[0] = msg[0].addr << 1;
536 obuf[1] = msg[0].len; 540 obuf[1] = msg[0].len;
@@ -556,9 +560,11 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
556 msg[i].flags == 0 ? ">>>" : "<<<"); 560 msg[i].flags == 0 ? ">>>" : "<<<");
557 debug_dump(msg[i].buf, msg[i].len, deb_xfer); 561 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
558 } 562 }
563 ret = num;
559 564
565unlock:
560 mutex_unlock(&d->i2c_mutex); 566 mutex_unlock(&d->i2c_mutex);
561 return num; 567 return ret;
562} 568}
563 569
564static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 570static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -566,7 +572,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
566{ 572{
567 struct dvb_usb_device *d = i2c_get_adapdata(adap); 573 struct dvb_usb_device *d = i2c_get_adapdata(adap);
568 struct usb_device *udev; 574 struct usb_device *udev;
569 int len, i, j; 575 int len, i, j, ret;
570 576
571 if (!d) 577 if (!d)
572 return -ENODEV; 578 return -ENODEV;
@@ -618,7 +624,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
618 if (msg[j].len > sizeof(ibuf)) { 624 if (msg[j].len > sizeof(ibuf)) {
619 warn("i2c rd: len=%d is too big!\n", 625 warn("i2c rd: len=%d is too big!\n",
620 msg[j].len); 626 msg[j].len);
621 return -EOPNOTSUPP; 627 ret = -EOPNOTSUPP;
628 goto unlock;
622 } 629 }
623 630
624 dw210x_op_rw(d->udev, 0x91, 0, 0, 631 dw210x_op_rw(d->udev, 0x91, 0, 0,
@@ -652,7 +659,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
652 if (2 + msg[j].len > sizeof(obuf)) { 659 if (2 + msg[j].len > sizeof(obuf)) {
653 warn("i2c wr: len=%d is too big!\n", 660 warn("i2c wr: len=%d is too big!\n",
654 msg[j].len); 661 msg[j].len);
655 return -EOPNOTSUPP; 662 ret = -EOPNOTSUPP;
663 goto unlock;
656 } 664 }
657 665
658 obuf[0] = msg[j + 1].len; 666 obuf[0] = msg[j + 1].len;
@@ -671,7 +679,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
671 if (2 + msg[j].len > sizeof(obuf)) { 679 if (2 + msg[j].len > sizeof(obuf)) {
672 warn("i2c wr: len=%d is too big!\n", 680 warn("i2c wr: len=%d is too big!\n",
673 msg[j].len); 681 msg[j].len);
674 return -EOPNOTSUPP; 682 ret = -EOPNOTSUPP;
683 goto unlock;
675 } 684 }
676 obuf[0] = msg[j].len + 1; 685 obuf[0] = msg[j].len + 1;
677 obuf[1] = (msg[j].addr << 1); 686 obuf[1] = (msg[j].addr << 1);
@@ -685,9 +694,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
685 } 694 }
686 } 695 }
687 } 696 }
697 ret = num;
688 698
699unlock:
689 mutex_unlock(&d->i2c_mutex); 700 mutex_unlock(&d->i2c_mutex);
690 return num; 701 return ret;
691} 702}
692 703
693static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 704static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -1095,6 +1106,16 @@ static struct ds3000_config su3000_ds3000_config = {
1095 .set_lock_led = dw210x_led_ctrl, 1106 .set_lock_led = dw210x_led_ctrl,
1096}; 1107};
1097 1108
1109static struct cxd2820r_config cxd2820r_config = {
1110 .i2c_address = 0x6c, /* (0xd8 >> 1) */
1111 .ts_mode = 0x38,
1112};
1113
1114static struct tda18271_config tda18271_config = {
1115 .output_opt = TDA18271_OUTPUT_LT_OFF,
1116 .gate = TDA18271_GATE_DIGITAL,
1117};
1118
1098static u8 m88rs2000_inittab[] = { 1119static u8 m88rs2000_inittab[] = {
1099 DEMOD_WRITE, 0x9a, 0x30, 1120 DEMOD_WRITE, 0x9a, 0x30,
1100 DEMOD_WRITE, 0x00, 0x01, 1121 DEMOD_WRITE, 0x00, 0x01,
@@ -1364,6 +1385,49 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1364 return -EIO; 1385 return -EIO;
1365} 1386}
1366 1387
1388static int t220_frontend_attach(struct dvb_usb_adapter *d)
1389{
1390 u8 obuf[3] = { 0xe, 0x80, 0 };
1391 u8 ibuf[] = { 0 };
1392
1393 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1394 err("command 0x0e transfer failed.");
1395
1396 obuf[0] = 0xe;
1397 obuf[1] = 0x83;
1398 obuf[2] = 0;
1399
1400 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1401 err("command 0x0e transfer failed.");
1402
1403 msleep(100);
1404
1405 obuf[0] = 0xe;
1406 obuf[1] = 0x80;
1407 obuf[2] = 1;
1408
1409 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1410 err("command 0x0e transfer failed.");
1411
1412 obuf[0] = 0x51;
1413
1414 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1415 err("command 0x51 transfer failed.");
1416
1417 d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
1418 &d->dev->i2c_adap, NULL);
1419 if (d->fe_adap[0].fe != NULL) {
1420 if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
1421 &d->dev->i2c_adap, &tda18271_config)) {
1422 info("Attached TDA18271HD/CXD2820R!\n");
1423 return 0;
1424 }
1425 }
1426
1427 info("Failed to attach TDA18271HD/CXD2820R!\n");
1428 return -EIO;
1429}
1430
1367static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d) 1431static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
1368{ 1432{
1369 u8 obuf[] = { 0x51 }; 1433 u8 obuf[] = { 0x51 };
@@ -1404,174 +1468,29 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
1404 return 0; 1468 return 0;
1405} 1469}
1406 1470
1407static struct rc_map_table rc_map_dw210x_table[] = { 1471static int dw2102_rc_query(struct dvb_usb_device *d)
1408 { 0xf80a, KEY_POWER2 }, /*power*/ 1472{
1409 { 0xf80c, KEY_MUTE }, /*mute*/ 1473 u8 key[2];
1410 { 0xf811, KEY_1 }, 1474 struct i2c_msg msg = {
1411 { 0xf812, KEY_2 }, 1475 .addr = DW2102_RC_QUERY,
1412 { 0xf813, KEY_3 }, 1476 .flags = I2C_M_RD,
1413 { 0xf814, KEY_4 }, 1477 .buf = key,
1414 { 0xf815, KEY_5 }, 1478 .len = 2
1415 { 0xf816, KEY_6 }, 1479 };
1416 { 0xf817, KEY_7 },
1417 { 0xf818, KEY_8 },
1418 { 0xf819, KEY_9 },
1419 { 0xf810, KEY_0 },
1420 { 0xf81c, KEY_CHANNELUP }, /*ch+*/
1421 { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
1422 { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
1423 { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
1424 { 0xf804, KEY_RECORD }, /*rec*/
1425 { 0xf809, KEY_FAVORITES }, /*fav*/
1426 { 0xf808, KEY_REWIND }, /*rewind*/
1427 { 0xf807, KEY_FASTFORWARD }, /*fast*/
1428 { 0xf80b, KEY_PAUSE }, /*pause*/
1429 { 0xf802, KEY_ESC }, /*cancel*/
1430 { 0xf803, KEY_TAB }, /*tab*/
1431 { 0xf800, KEY_UP }, /*up*/
1432 { 0xf81f, KEY_OK }, /*ok*/
1433 { 0xf801, KEY_DOWN }, /*down*/
1434 { 0xf805, KEY_CAMERA }, /*cap*/
1435 { 0xf806, KEY_STOP }, /*stop*/
1436 { 0xf840, KEY_ZOOM }, /*full*/
1437 { 0xf81e, KEY_TV }, /*tvmode*/
1438 { 0xf81b, KEY_LAST }, /*recall*/
1439};
1440
1441static struct rc_map_table rc_map_tevii_table[] = {
1442 { 0xf80a, KEY_POWER },
1443 { 0xf80c, KEY_MUTE },
1444 { 0xf811, KEY_1 },
1445 { 0xf812, KEY_2 },
1446 { 0xf813, KEY_3 },
1447 { 0xf814, KEY_4 },
1448 { 0xf815, KEY_5 },
1449 { 0xf816, KEY_6 },
1450 { 0xf817, KEY_7 },
1451 { 0xf818, KEY_8 },
1452 { 0xf819, KEY_9 },
1453 { 0xf810, KEY_0 },
1454 { 0xf81c, KEY_MENU },
1455 { 0xf80f, KEY_VOLUMEDOWN },
1456 { 0xf81a, KEY_LAST },
1457 { 0xf80e, KEY_OPEN },
1458 { 0xf804, KEY_RECORD },
1459 { 0xf809, KEY_VOLUMEUP },
1460 { 0xf808, KEY_CHANNELUP },
1461 { 0xf807, KEY_PVR },
1462 { 0xf80b, KEY_TIME },
1463 { 0xf802, KEY_RIGHT },
1464 { 0xf803, KEY_LEFT },
1465 { 0xf800, KEY_UP },
1466 { 0xf81f, KEY_OK },
1467 { 0xf801, KEY_DOWN },
1468 { 0xf805, KEY_TUNER },
1469 { 0xf806, KEY_CHANNELDOWN },
1470 { 0xf840, KEY_PLAYPAUSE },
1471 { 0xf81e, KEY_REWIND },
1472 { 0xf81b, KEY_FAVORITES },
1473 { 0xf81d, KEY_BACK },
1474 { 0xf84d, KEY_FASTFORWARD },
1475 { 0xf844, KEY_EPG },
1476 { 0xf84c, KEY_INFO },
1477 { 0xf841, KEY_AB },
1478 { 0xf843, KEY_AUDIO },
1479 { 0xf845, KEY_SUBTITLE },
1480 { 0xf84a, KEY_LIST },
1481 { 0xf846, KEY_F1 },
1482 { 0xf847, KEY_F2 },
1483 { 0xf85e, KEY_F3 },
1484 { 0xf85c, KEY_F4 },
1485 { 0xf852, KEY_F5 },
1486 { 0xf85a, KEY_F6 },
1487 { 0xf856, KEY_MODE },
1488 { 0xf858, KEY_SWITCHVIDEOMODE },
1489};
1490
1491static struct rc_map_table rc_map_tbs_table[] = {
1492 { 0xf884, KEY_POWER },
1493 { 0xf894, KEY_MUTE },
1494 { 0xf887, KEY_1 },
1495 { 0xf886, KEY_2 },
1496 { 0xf885, KEY_3 },
1497 { 0xf88b, KEY_4 },
1498 { 0xf88a, KEY_5 },
1499 { 0xf889, KEY_6 },
1500 { 0xf88f, KEY_7 },
1501 { 0xf88e, KEY_8 },
1502 { 0xf88d, KEY_9 },
1503 { 0xf892, KEY_0 },
1504 { 0xf896, KEY_CHANNELUP },
1505 { 0xf891, KEY_CHANNELDOWN },
1506 { 0xf893, KEY_VOLUMEUP },
1507 { 0xf88c, KEY_VOLUMEDOWN },
1508 { 0xf883, KEY_RECORD },
1509 { 0xf898, KEY_PAUSE },
1510 { 0xf899, KEY_OK },
1511 { 0xf89a, KEY_SHUFFLE },
1512 { 0xf881, KEY_UP },
1513 { 0xf890, KEY_LEFT },
1514 { 0xf882, KEY_RIGHT },
1515 { 0xf888, KEY_DOWN },
1516 { 0xf895, KEY_FAVORITES },
1517 { 0xf897, KEY_SUBTITLE },
1518 { 0xf89d, KEY_ZOOM },
1519 { 0xf89f, KEY_EXIT },
1520 { 0xf89e, KEY_MENU },
1521 { 0xf89c, KEY_EPG },
1522 { 0xf880, KEY_PREVIOUS },
1523 { 0xf89b, KEY_MODE }
1524};
1525 1480
1526static struct rc_map_table rc_map_su3000_table[] = { 1481 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1527 { 0x25, KEY_POWER }, /* right-bottom Red */ 1482 if (msg.buf[0] != 0xff) {
1528 { 0x0a, KEY_MUTE }, /* -/-- */ 1483 deb_rc("%s: rc code: %x, %x\n",
1529 { 0x01, KEY_1 }, 1484 __func__, key[0], key[1]);
1530 { 0x02, KEY_2 }, 1485 rc_keydown(d->rc_dev, key[0], 1);
1531 { 0x03, KEY_3 }, 1486 }
1532 { 0x04, KEY_4 }, 1487 }
1533 { 0x05, KEY_5 },
1534 { 0x06, KEY_6 },
1535 { 0x07, KEY_7 },
1536 { 0x08, KEY_8 },
1537 { 0x09, KEY_9 },
1538 { 0x00, KEY_0 },
1539 { 0x20, KEY_UP }, /* CH+ */
1540 { 0x21, KEY_DOWN }, /* CH+ */
1541 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
1542 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
1543 { 0x1f, KEY_RECORD },
1544 { 0x17, KEY_PLAY },
1545 { 0x16, KEY_PAUSE },
1546 { 0x0b, KEY_STOP },
1547 { 0x27, KEY_FASTFORWARD },/* >> */
1548 { 0x26, KEY_REWIND }, /* << */
1549 { 0x0d, KEY_OK }, /* Mute */
1550 { 0x11, KEY_LEFT }, /* VOL- */
1551 { 0x10, KEY_RIGHT }, /* VOL+ */
1552 { 0x29, KEY_BACK }, /* button under 9 */
1553 { 0x2c, KEY_MENU }, /* TTX */
1554 { 0x2b, KEY_EPG }, /* EPG */
1555 { 0x1e, KEY_RED }, /* OSD */
1556 { 0x0e, KEY_GREEN }, /* Window */
1557 { 0x2d, KEY_YELLOW }, /* button under << */
1558 { 0x0f, KEY_BLUE }, /* bottom yellow button */
1559 { 0x14, KEY_AUDIO }, /* Snapshot */
1560 { 0x38, KEY_TV }, /* TV/Radio */
1561 { 0x0c, KEY_ESC } /* upper Red button */
1562};
1563 1488
1564static struct rc_map_dvb_usb_table_table keys_tables[] = { 1489 return 0;
1565 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, 1490}
1566 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
1567 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
1568 { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
1569};
1570 1491
1571static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 1492static int prof_rc_query(struct dvb_usb_device *d)
1572{ 1493{
1573 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
1574 int keymap_size = d->props.rc.legacy.rc_map_size;
1575 u8 key[2]; 1494 u8 key[2];
1576 struct i2c_msg msg = { 1495 struct i2c_msg msg = {
1577 .addr = DW2102_RC_QUERY, 1496 .addr = DW2102_RC_QUERY,
@@ -1579,32 +1498,34 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1579 .buf = key, 1498 .buf = key,
1580 .len = 2 1499 .len = 2
1581 }; 1500 };
1582 int i;
1583 /* override keymap */
1584 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1585 keymap = keys_tables[ir_keymap - 1].rc_keys ;
1586 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1587 } else if (ir_keymap > ARRAY_SIZE(keys_tables))
1588 return 0; /* none */
1589
1590 *state = REMOTE_NO_KEY_PRESSED;
1591 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1592 for (i = 0; i < keymap_size ; i++) {
1593 if (rc5_data(&keymap[i]) == msg.buf[0]) {
1594 *state = REMOTE_KEY_PRESSED;
1595 *event = keymap[i].keycode;
1596 break;
1597 }
1598 1501
1502 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1503 if (msg.buf[0] != 0xff) {
1504 deb_rc("%s: rc code: %x, %x\n",
1505 __func__, key[0], key[1]);
1506 rc_keydown(d->rc_dev, key[0]^0xff, 1);
1599 } 1507 }
1508 }
1600 1509
1601 if ((*state) == REMOTE_KEY_PRESSED) 1510 return 0;
1602 deb_rc("%s: found rc key: %x, %x, event: %x\n", 1511}
1603 __func__, key[0], key[1], (*event));
1604 else if (key[0] != 0xff)
1605 deb_rc("%s: unknown rc key: %x, %x\n",
1606 __func__, key[0], key[1]);
1607 1512
1513static int su3000_rc_query(struct dvb_usb_device *d)
1514{
1515 u8 key[2];
1516 struct i2c_msg msg = {
1517 .addr = DW2102_RC_QUERY,
1518 .flags = I2C_M_RD,
1519 .buf = key,
1520 .len = 2
1521 };
1522
1523 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1524 if (msg.buf[0] != 0xff) {
1525 deb_rc("%s: rc code: %x, %x\n",
1526 __func__, key[0], key[1]);
1527 rc_keydown(d->rc_dev, key[1] << 8 | key[0], 1);
1528 }
1608 } 1529 }
1609 1530
1610 return 0; 1531 return 0;
@@ -1630,6 +1551,7 @@ enum dw2102_table_entry {
1630 TEVII_S632, 1551 TEVII_S632,
1631 TERRATEC_CINERGY_S2_R2, 1552 TERRATEC_CINERGY_S2_R2,
1632 GOTVIEW_SAT_HD, 1553 GOTVIEW_SAT_HD,
1554 GENIATECH_T220,
1633}; 1555};
1634 1556
1635static struct usb_device_id dw2102_table[] = { 1557static struct usb_device_id dw2102_table[] = {
@@ -1652,6 +1574,7 @@ static struct usb_device_id dw2102_table[] = {
1652 [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)}, 1574 [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
1653 [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)}, 1575 [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
1654 [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, 1576 [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
1577 [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
1655 { } 1578 { }
1656}; 1579};
1657 1580
@@ -1711,9 +1634,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
1711 /* init registers */ 1634 /* init registers */
1712 switch (dev->descriptor.idProduct) { 1635 switch (dev->descriptor.idProduct) {
1713 case USB_PID_TEVII_S650: 1636 case USB_PID_TEVII_S650:
1714 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; 1637 dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC;
1715 dw2104_properties.rc.legacy.rc_map_size =
1716 ARRAY_SIZE(rc_map_tevii_table);
1717 case USB_PID_DW2104: 1638 case USB_PID_DW2104:
1718 reset = 1; 1639 reset = 1;
1719 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, 1640 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
@@ -1777,10 +1698,11 @@ static struct dvb_usb_device_properties dw2102_properties = {
1777 1698
1778 .i2c_algo = &dw2102_serit_i2c_algo, 1699 .i2c_algo = &dw2102_serit_i2c_algo,
1779 1700
1780 .rc.legacy = { 1701 .rc.core = {
1781 .rc_map_table = rc_map_dw210x_table,
1782 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1783 .rc_interval = 150, 1702 .rc_interval = 150,
1703 .rc_codes = RC_MAP_DM1105_NEC,
1704 .module_name = "dw2102",
1705 .allowed_protos = RC_BIT_NEC,
1784 .rc_query = dw2102_rc_query, 1706 .rc_query = dw2102_rc_query,
1785 }, 1707 },
1786 1708
@@ -1831,10 +1753,11 @@ static struct dvb_usb_device_properties dw2104_properties = {
1831 .no_reconnect = 1, 1753 .no_reconnect = 1,
1832 1754
1833 .i2c_algo = &dw2104_i2c_algo, 1755 .i2c_algo = &dw2104_i2c_algo,
1834 .rc.legacy = { 1756 .rc.core = {
1835 .rc_map_table = rc_map_dw210x_table,
1836 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1837 .rc_interval = 150, 1757 .rc_interval = 150,
1758 .rc_codes = RC_MAP_DM1105_NEC,
1759 .module_name = "dw2102",
1760 .allowed_protos = RC_BIT_NEC,
1838 .rc_query = dw2102_rc_query, 1761 .rc_query = dw2102_rc_query,
1839 }, 1762 },
1840 1763
@@ -1881,10 +1804,11 @@ static struct dvb_usb_device_properties dw3101_properties = {
1881 .no_reconnect = 1, 1804 .no_reconnect = 1,
1882 1805
1883 .i2c_algo = &dw3101_i2c_algo, 1806 .i2c_algo = &dw3101_i2c_algo,
1884 .rc.legacy = { 1807 .rc.core = {
1885 .rc_map_table = rc_map_dw210x_table,
1886 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1887 .rc_interval = 150, 1808 .rc_interval = 150,
1809 .rc_codes = RC_MAP_DM1105_NEC,
1810 .module_name = "dw2102",
1811 .allowed_protos = RC_BIT_NEC,
1888 .rc_query = dw2102_rc_query, 1812 .rc_query = dw2102_rc_query,
1889 }, 1813 },
1890 1814
@@ -1929,10 +1853,11 @@ static struct dvb_usb_device_properties s6x0_properties = {
1929 .no_reconnect = 1, 1853 .no_reconnect = 1,
1930 1854
1931 .i2c_algo = &s6x0_i2c_algo, 1855 .i2c_algo = &s6x0_i2c_algo,
1932 .rc.legacy = { 1856 .rc.core = {
1933 .rc_map_table = rc_map_tevii_table,
1934 .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
1935 .rc_interval = 150, 1857 .rc_interval = 150,
1858 .rc_codes = RC_MAP_TEVII_NEC,
1859 .module_name = "dw2102",
1860 .allowed_protos = RC_BIT_NEC,
1936 .rc_query = dw2102_rc_query, 1861 .rc_query = dw2102_rc_query,
1937 }, 1862 },
1938 1863
@@ -2022,11 +1947,12 @@ static struct dvb_usb_device_properties su3000_properties = {
2022 .identify_state = su3000_identify_state, 1947 .identify_state = su3000_identify_state,
2023 .i2c_algo = &su3000_i2c_algo, 1948 .i2c_algo = &su3000_i2c_algo,
2024 1949
2025 .rc.legacy = { 1950 .rc.core = {
2026 .rc_map_table = rc_map_su3000_table,
2027 .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
2028 .rc_interval = 150, 1951 .rc_interval = 150,
2029 .rc_query = dw2102_rc_query, 1952 .rc_codes = RC_MAP_SU3000,
1953 .module_name = "dw2102",
1954 .allowed_protos = RC_BIT_RC5,
1955 .rc_query = su3000_rc_query,
2030 }, 1956 },
2031 1957
2032 .read_mac_address = su3000_read_mac_address, 1958 .read_mac_address = su3000_read_mac_address,
@@ -2077,6 +2003,55 @@ static struct dvb_usb_device_properties su3000_properties = {
2077 } 2003 }
2078}; 2004};
2079 2005
2006static struct dvb_usb_device_properties t220_properties = {
2007 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2008 .usb_ctrl = DEVICE_SPECIFIC,
2009 .size_of_priv = sizeof(struct su3000_state),
2010 .power_ctrl = su3000_power_ctrl,
2011 .num_adapters = 1,
2012 .identify_state = su3000_identify_state,
2013 .i2c_algo = &su3000_i2c_algo,
2014
2015 .rc.core = {
2016 .rc_interval = 150,
2017 .rc_codes = RC_MAP_SU3000,
2018 .module_name = "dw2102",
2019 .allowed_protos = RC_BIT_RC5,
2020 .rc_query = su3000_rc_query,
2021 },
2022
2023 .read_mac_address = su3000_read_mac_address,
2024
2025 .generic_bulk_ctrl_endpoint = 0x01,
2026
2027 .adapter = {
2028 {
2029 .num_frontends = 1,
2030 .fe = { {
2031 .streaming_ctrl = su3000_streaming_ctrl,
2032 .frontend_attach = t220_frontend_attach,
2033 .stream = {
2034 .type = USB_BULK,
2035 .count = 8,
2036 .endpoint = 0x82,
2037 .u = {
2038 .bulk = {
2039 .buffersize = 4096,
2040 }
2041 }
2042 }
2043 } },
2044 }
2045 },
2046 .num_device_descs = 1,
2047 .devices = {
2048 { "Geniatech T220 DVB-T/T2 USB2.0",
2049 { &dw2102_table[GENIATECH_T220], NULL },
2050 { NULL },
2051 },
2052 }
2053};
2054
2080static int dw2102_probe(struct usb_interface *intf, 2055static int dw2102_probe(struct usb_interface *intf,
2081 const struct usb_device_id *id) 2056 const struct usb_device_id *id)
2082{ 2057{
@@ -2088,8 +2063,8 @@ static int dw2102_probe(struct usb_interface *intf,
2088 /* fill only different fields */ 2063 /* fill only different fields */
2089 p1100->firmware = P1100_FIRMWARE; 2064 p1100->firmware = P1100_FIRMWARE;
2090 p1100->devices[0] = d1100; 2065 p1100->devices[0] = d1100;
2091 p1100->rc.legacy.rc_map_table = rc_map_tbs_table; 2066 p1100->rc.core.rc_query = prof_rc_query;
2092 p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); 2067 p1100->rc.core.rc_codes = RC_MAP_TBS_NEC;
2093 p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; 2068 p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
2094 2069
2095 s660 = kmemdup(&s6x0_properties, 2070 s660 = kmemdup(&s6x0_properties,
@@ -2114,8 +2089,8 @@ static int dw2102_probe(struct usb_interface *intf,
2114 } 2089 }
2115 p7500->firmware = P7500_FIRMWARE; 2090 p7500->firmware = P7500_FIRMWARE;
2116 p7500->devices[0] = d7500; 2091 p7500->devices[0] = d7500;
2117 p7500->rc.legacy.rc_map_table = rc_map_tbs_table; 2092 p7500->rc.core.rc_query = prof_rc_query;
2118 p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); 2093 p7500->rc.core.rc_codes = RC_MAP_TBS_NEC;
2119 p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach; 2094 p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
2120 2095
2121 2096
@@ -2149,7 +2124,9 @@ static int dw2102_probe(struct usb_interface *intf,
2149 0 == dvb_usb_device_init(intf, s421, 2124 0 == dvb_usb_device_init(intf, s421,
2150 THIS_MODULE, NULL, adapter_nr) || 2125 THIS_MODULE, NULL, adapter_nr) ||
2151 0 == dvb_usb_device_init(intf, &su3000_properties, 2126 0 == dvb_usb_device_init(intf, &su3000_properties,
2152 THIS_MODULE, NULL, adapter_nr)) 2127 THIS_MODULE, NULL, adapter_nr) ||
2128 0 == dvb_usb_device_init(intf, &t220_properties,
2129 THIS_MODULE, NULL, adapter_nr))
2153 return 0; 2130 return 0;
2154 2131
2155 return -ENODEV; 2132 return -ENODEV;
@@ -2169,7 +2146,7 @@ MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
2169 " DVB-C 3101 USB2.0," 2146 " DVB-C 3101 USB2.0,"
2170 " TeVii S600, S630, S650, S660, S480, S421, S632" 2147 " TeVii S600, S630, S650, S660, S480, S421, S632"
2171 " Prof 1100, 7500 USB2.0," 2148 " Prof 1100, 7500 USB2.0,"
2172 " Geniatech SU3000 devices"); 2149 " Geniatech SU3000, T220 devices");
2173MODULE_VERSION("0.1"); 2150MODULE_VERSION("0.1");
2174MODULE_LICENSE("GPL"); 2151MODULE_LICENSE("GPL");
2175MODULE_FIRMWARE(DW2101_FIRMWARE); 2152MODULE_FIRMWARE(DW2101_FIRMWARE);
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
index ca5ee6aceb62..a1fccf3096de 100644
--- a/drivers/media/usb/em28xx/Kconfig
+++ b/drivers/media/usb/em28xx/Kconfig
@@ -1,8 +1,12 @@
1config VIDEO_EM28XX 1config VIDEO_EM28XX
2 tristate "Empia EM28xx USB video capture support" 2 tristate "Empia EM28xx USB devices support"
3 depends on VIDEO_DEV && I2C 3 depends on VIDEO_DEV && I2C
4 select VIDEO_TUNER 4 select VIDEO_TUNER
5 select VIDEO_TVEEPROM 5 select VIDEO_TVEEPROM
6
7config VIDEO_EM28XX_V4L2
8 tristate "Empia EM28xx analog TV, video capture and/or webcam support"
9 depends on VIDEO_EM28XX
6 select VIDEOBUF2_VMALLOC 10 select VIDEOBUF2_VMALLOC
7 select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT 11 select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
8 select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT 12 select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT
@@ -49,6 +53,8 @@ config VIDEO_EM28XX_DVB
49 select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT 53 select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
50 select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT 54 select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
51 select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT 55 select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
56 select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
57 select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
52 ---help--- 58 ---help---
53 This adds support for DVB cards based on the 59 This adds support for DVB cards based on the
54 Empiatech em28xx chips. 60 Empiatech em28xx chips.
diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
index ad6d48557940..3f850d5063d0 100644
--- a/drivers/media/usb/em28xx/Makefile
+++ b/drivers/media/usb/em28xx/Makefile
@@ -1,10 +1,11 @@
1em28xx-y += em28xx-video.o em28xx-i2c.o em28xx-cards.o 1em28xx-y += em28xx-core.o em28xx-i2c.o em28xx-cards.o em28xx-camera.o
2em28xx-y += em28xx-core.o em28xx-vbi.o em28xx-camera.o
3 2
3em28xx-v4l-objs := em28xx-video.o em28xx-vbi.o
4em28xx-alsa-objs := em28xx-audio.o 4em28xx-alsa-objs := em28xx-audio.o
5em28xx-rc-objs := em28xx-input.o 5em28xx-rc-objs := em28xx-input.o
6 6
7obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o 7obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
8obj-$(CONFIG_VIDEO_EM28XX_V4L2) += em28xx-v4l.o
8obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o 9obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
9obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o 10obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
10obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o 11obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 2fdb66ee44ab..05e9bd11a3ff 100644
--- a/drivers/media/usb/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> 4 * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com>
5 * 5 *
6 * Copyright (C) 2007-2011 Mauro Carvalho Chehab <mchehab@redhat.com> 6 * Copyright (C) 2007-2014 Mauro Carvalho Chehab
7 * - Port to work with the in-kernel driver 7 * - Port to work with the in-kernel driver
8 * - Cleanups, fixes, alsa-controls, etc. 8 * - Cleanups, fixes, alsa-controls, etc.
9 * 9 *
@@ -50,6 +50,9 @@ static int debug;
50module_param(debug, int, 0644); 50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "activates debug info"); 51MODULE_PARM_DESC(debug, "activates debug info");
52 52
53#define EM28XX_MAX_AUDIO_BUFS 5
54#define EM28XX_MIN_AUDIO_PACKETS 64
55
53#define dprintk(fmt, arg...) do { \ 56#define dprintk(fmt, arg...) do { \
54 if (debug) \ 57 if (debug) \
55 printk(KERN_INFO "em28xx-audio %s: " fmt, \ 58 printk(KERN_INFO "em28xx-audio %s: " fmt, \
@@ -63,17 +66,13 @@ static int em28xx_deinit_isoc_audio(struct em28xx *dev)
63 int i; 66 int i;
64 67
65 dprintk("Stopping isoc\n"); 68 dprintk("Stopping isoc\n");
66 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 69 for (i = 0; i < dev->adev.num_urb; i++) {
70 struct urb *urb = dev->adev.urb[i];
71
67 if (!irqs_disabled()) 72 if (!irqs_disabled())
68 usb_kill_urb(dev->adev.urb[i]); 73 usb_kill_urb(urb);
69 else 74 else
70 usb_unlink_urb(dev->adev.urb[i]); 75 usb_unlink_urb(urb);
71
72 usb_free_urb(dev->adev.urb[i]);
73 dev->adev.urb[i] = NULL;
74
75 kfree(dev->adev.transfer_buffer[i]);
76 dev->adev.transfer_buffer[i] = NULL;
77 } 76 }
78 77
79 return 0; 78 return 0;
@@ -91,6 +90,12 @@ static void em28xx_audio_isocirq(struct urb *urb)
91 struct snd_pcm_substream *substream; 90 struct snd_pcm_substream *substream;
92 struct snd_pcm_runtime *runtime; 91 struct snd_pcm_runtime *runtime;
93 92
93 if (dev->disconnected) {
94 dprintk("device disconnected while streaming. URB status=%d.\n", urb->status);
95 atomic_set(&dev->stream_started, 0);
96 return;
97 }
98
94 switch (urb->status) { 99 switch (urb->status) {
95 case 0: /* success */ 100 case 0: /* success */
96 case -ETIMEDOUT: /* NAK */ 101 case -ETIMEDOUT: /* NAK */
@@ -158,63 +163,27 @@ static void em28xx_audio_isocirq(struct urb *urb)
158 urb->status = 0; 163 urb->status = 0;
159 164
160 status = usb_submit_urb(urb, GFP_ATOMIC); 165 status = usb_submit_urb(urb, GFP_ATOMIC);
161 if (status < 0) { 166 if (status < 0)
162 em28xx_errdev("resubmit of audio urb failed (error=%i)\n", 167 em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
163 status); 168 status);
164 }
165 return; 169 return;
166} 170}
167 171
168static int em28xx_init_audio_isoc(struct em28xx *dev) 172static int em28xx_init_audio_isoc(struct em28xx *dev)
169{ 173{
170 int i, errCode; 174 int i, errCode;
171 const int sb_size = EM28XX_NUM_AUDIO_PACKETS *
172 EM28XX_AUDIO_MAX_PACKET_SIZE;
173 175
174 dprintk("Starting isoc transfers\n"); 176 dprintk("Starting isoc transfers\n");
175 177
176 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 178 /* Start streaming */
177 struct urb *urb; 179 for (i = 0; i < dev->adev.num_urb; i++) {
178 int j, k; 180 memset(dev->adev.transfer_buffer[i], 0x80,
179 181 dev->adev.urb[i]->transfer_buffer_length);
180 dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
181 if (!dev->adev.transfer_buffer[i])
182 return -ENOMEM;
183
184 memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
185 urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
186 if (!urb) {
187 em28xx_errdev("usb_alloc_urb failed!\n");
188 for (j = 0; j < i; j++) {
189 usb_free_urb(dev->adev.urb[j]);
190 kfree(dev->adev.transfer_buffer[j]);
191 }
192 return -ENOMEM;
193 }
194
195 urb->dev = dev->udev;
196 urb->context = dev;
197 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
198 urb->transfer_flags = URB_ISO_ASAP;
199 urb->transfer_buffer = dev->adev.transfer_buffer[i];
200 urb->interval = 1;
201 urb->complete = em28xx_audio_isocirq;
202 urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
203 urb->transfer_buffer_length = sb_size;
204
205 for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS;
206 j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
207 urb->iso_frame_desc[j].offset = k;
208 urb->iso_frame_desc[j].length =
209 EM28XX_AUDIO_MAX_PACKET_SIZE;
210 }
211 dev->adev.urb[i] = urb;
212 }
213 182
214 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
215 errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); 183 errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
216 if (errCode) { 184 if (errCode) {
217 em28xx_errdev("submit of audio urb failed\n"); 185 em28xx_errdev("submit of audio urb failed (error=%i)\n",
186 errCode);
218 em28xx_deinit_isoc_audio(dev); 187 em28xx_deinit_isoc_audio(dev);
219 atomic_set(&dev->stream_started, 0); 188 atomic_set(&dev->stream_started, 0);
220 return errCode; 189 return errCode;
@@ -255,15 +224,26 @@ static struct snd_pcm_hardware snd_em28xx_hw_capture = {
255 224
256 .formats = SNDRV_PCM_FMTBIT_S16_LE, 225 .formats = SNDRV_PCM_FMTBIT_S16_LE,
257 226
258 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT, 227 .rates = SNDRV_PCM_RATE_48000,
259 228
260 .rate_min = 48000, 229 .rate_min = 48000,
261 .rate_max = 48000, 230 .rate_max = 48000,
262 .channels_min = 2, 231 .channels_min = 2,
263 .channels_max = 2, 232 .channels_max = 2,
264 .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */ 233 .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
265 .period_bytes_min = 64, /* 12544/2, */ 234
266 .period_bytes_max = 12544, 235
236 /*
237 * The period is 12.288 bytes. Allow a 10% of variation along its
238 * value, in order to avoid overruns/underruns due to some clock
239 * drift.
240 *
241 * FIXME: This period assumes 64 packets, and a 48000 PCM rate.
242 * Calculate it dynamically.
243 */
244 .period_bytes_min = 11059,
245 .period_bytes_max = 13516,
246
267 .periods_min = 2, 247 .periods_min = 2,
268 .periods_max = 98, /* 12544, */ 248 .periods_max = 98, /* 12544, */
269}; 249};
@@ -274,28 +254,48 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
274 struct snd_pcm_runtime *runtime = substream->runtime; 254 struct snd_pcm_runtime *runtime = substream->runtime;
275 int ret = 0; 255 int ret = 0;
276 256
277 dprintk("opening device and trying to acquire exclusive lock\n");
278
279 if (!dev) { 257 if (!dev) {
280 em28xx_err("BUG: em28xx can't find device struct." 258 em28xx_err("BUG: em28xx can't find device struct."
281 " Can't proceed with open\n"); 259 " Can't proceed with open\n");
282 return -ENODEV; 260 return -ENODEV;
283 } 261 }
284 262
263 if (dev->disconnected)
264 return -ENODEV;
265
266 dprintk("opening device and trying to acquire exclusive lock\n");
267
285 runtime->hw = snd_em28xx_hw_capture; 268 runtime->hw = snd_em28xx_hw_capture;
286 if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) { 269 if ((dev->alt == 0 || dev->is_audio_only) && dev->adev.users == 0) {
287 if (dev->audio_ifnum) 270 int nonblock = !!(substream->f_flags & O_NONBLOCK);
271
272 if (nonblock) {
273 if (!mutex_trylock(&dev->lock))
274 return -EAGAIN;
275 } else
276 mutex_lock(&dev->lock);
277 if (dev->is_audio_only)
278 /* vendor audio is on a separate interface */
288 dev->alt = 1; 279 dev->alt = 1;
289 else 280 else
281 /* vendor audio is on the same interface as video */
290 dev->alt = 7; 282 dev->alt = 7;
283 /*
284 * FIXME: The intention seems to be to select the alt
285 * setting with the largest wMaxPacketSize for the video
286 * endpoint.
287 * At least dev->alt should be used instead, but we
288 * should probably not touch it at all if it is
289 * already >0, because wMaxPacketSize of the audio
290 * endpoints seems to be the same for all.
291 */
291 292
292 dprintk("changing alternate number on interface %d to %d\n", 293 dprintk("changing alternate number on interface %d to %d\n",
293 dev->audio_ifnum, dev->alt); 294 dev->ifnum, dev->alt);
294 usb_set_interface(dev->udev, dev->audio_ifnum, dev->alt); 295 usb_set_interface(dev->udev, dev->ifnum, dev->alt);
295 296
296 /* Sets volume, mute, etc */ 297 /* Sets volume, mute, etc */
297 dev->mute = 0; 298 dev->mute = 0;
298 mutex_lock(&dev->lock);
299 ret = em28xx_audio_analog_set(dev); 299 ret = em28xx_audio_analog_set(dev);
300 if (ret < 0) 300 if (ret < 0)
301 goto err; 301 goto err;
@@ -304,7 +304,12 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
304 mutex_unlock(&dev->lock); 304 mutex_unlock(&dev->lock);
305 } 305 }
306 306
307 /* Dynamically adjust the period size */
307 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 308 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
309 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
310 dev->adev.period * 95 / 100,
311 dev->adev.period * 105 / 100);
312
308 dev->adev.capture_pcm_substream = substream; 313 dev->adev.capture_pcm_substream = substream;
309 314
310 return 0; 315 return 0;
@@ -344,6 +349,10 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
344 struct snd_pcm_hw_params *hw_params) 349 struct snd_pcm_hw_params *hw_params)
345{ 350{
346 int ret; 351 int ret;
352 struct em28xx *dev = snd_pcm_substream_chip(substream);
353
354 if (dev->disconnected)
355 return -ENODEV;
347 356
348 dprintk("Setting capture parameters\n"); 357 dprintk("Setting capture parameters\n");
349 358
@@ -383,6 +392,9 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream)
383{ 392{
384 struct em28xx *dev = snd_pcm_substream_chip(substream); 393 struct em28xx *dev = snd_pcm_substream_chip(substream);
385 394
395 if (dev->disconnected)
396 return -ENODEV;
397
386 dev->adev.hwptr_done_capture = 0; 398 dev->adev.hwptr_done_capture = 0;
387 dev->adev.capture_transfer_done = 0; 399 dev->adev.capture_transfer_done = 0;
388 400
@@ -408,6 +420,9 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
408 struct em28xx *dev = snd_pcm_substream_chip(substream); 420 struct em28xx *dev = snd_pcm_substream_chip(substream);
409 int retval = 0; 421 int retval = 0;
410 422
423 if (dev->disconnected)
424 return -ENODEV;
425
411 switch (cmd) { 426 switch (cmd) {
412 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 427 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
413 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 428 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
@@ -434,6 +449,9 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
434 snd_pcm_uframes_t hwptr_done; 449 snd_pcm_uframes_t hwptr_done;
435 450
436 dev = snd_pcm_substream_chip(substream); 451 dev = snd_pcm_substream_chip(substream);
452 if (dev->disconnected)
453 return SNDRV_PCM_POS_XRUN;
454
437 spin_lock_irqsave(&dev->adev.slock, flags); 455 spin_lock_irqsave(&dev->adev.slock, flags);
438 hwptr_done = dev->adev.hwptr_done_capture; 456 hwptr_done = dev->adev.hwptr_done_capture;
439 spin_unlock_irqrestore(&dev->adev.slock, flags); 457 spin_unlock_irqrestore(&dev->adev.slock, flags);
@@ -455,6 +473,11 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
455static int em28xx_vol_info(struct snd_kcontrol *kcontrol, 473static int em28xx_vol_info(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_info *info) 474 struct snd_ctl_elem_info *info)
457{ 475{
476 struct em28xx *dev = snd_kcontrol_chip(kcontrol);
477
478 if (dev->disconnected)
479 return -ENODEV;
480
458 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 481 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
459 info->count = 2; 482 info->count = 2;
460 info->value.integer.min = 0; 483 info->value.integer.min = 0;
@@ -467,11 +490,22 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *value) 490 struct snd_ctl_elem_value *value)
468{ 491{
469 struct em28xx *dev = snd_kcontrol_chip(kcontrol); 492 struct em28xx *dev = snd_kcontrol_chip(kcontrol);
493 struct snd_pcm_substream *substream = dev->adev.capture_pcm_substream;
470 u16 val = (0x1f - (value->value.integer.value[0] & 0x1f)) | 494 u16 val = (0x1f - (value->value.integer.value[0] & 0x1f)) |
471 (0x1f - (value->value.integer.value[1] & 0x1f)) << 8; 495 (0x1f - (value->value.integer.value[1] & 0x1f)) << 8;
496 int nonblock = 0;
472 int rc; 497 int rc;
473 498
474 mutex_lock(&dev->lock); 499 if (dev->disconnected)
500 return -ENODEV;
501
502 if (substream)
503 nonblock = !!(substream->f_flags & O_NONBLOCK);
504 if (nonblock) {
505 if (!mutex_trylock(&dev->lock))
506 return -EAGAIN;
507 } else
508 mutex_lock(&dev->lock);
475 rc = em28xx_read_ac97(dev, kcontrol->private_value); 509 rc = em28xx_read_ac97(dev, kcontrol->private_value);
476 if (rc < 0) 510 if (rc < 0)
477 goto err; 511 goto err;
@@ -496,9 +530,20 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *value) 530 struct snd_ctl_elem_value *value)
497{ 531{
498 struct em28xx *dev = snd_kcontrol_chip(kcontrol); 532 struct em28xx *dev = snd_kcontrol_chip(kcontrol);
533 struct snd_pcm_substream *substream = dev->adev.capture_pcm_substream;
534 int nonblock = 0;
499 int val; 535 int val;
500 536
501 mutex_lock(&dev->lock); 537 if (dev->disconnected)
538 return -ENODEV;
539
540 if (substream)
541 nonblock = !!(substream->f_flags & O_NONBLOCK);
542 if (nonblock) {
543 if (!mutex_trylock(&dev->lock))
544 return -EAGAIN;
545 } else
546 mutex_lock(&dev->lock);
502 val = em28xx_read_ac97(dev, kcontrol->private_value); 547 val = em28xx_read_ac97(dev, kcontrol->private_value);
503 mutex_unlock(&dev->lock); 548 mutex_unlock(&dev->lock);
504 if (val < 0) 549 if (val < 0)
@@ -520,9 +565,20 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol,
520{ 565{
521 struct em28xx *dev = snd_kcontrol_chip(kcontrol); 566 struct em28xx *dev = snd_kcontrol_chip(kcontrol);
522 u16 val = value->value.integer.value[0]; 567 u16 val = value->value.integer.value[0];
568 struct snd_pcm_substream *substream = dev->adev.capture_pcm_substream;
569 int nonblock = 0;
523 int rc; 570 int rc;
524 571
525 mutex_lock(&dev->lock); 572 if (dev->disconnected)
573 return -ENODEV;
574
575 if (substream)
576 nonblock = !!(substream->f_flags & O_NONBLOCK);
577 if (nonblock) {
578 if (!mutex_trylock(&dev->lock))
579 return -EAGAIN;
580 } else
581 mutex_lock(&dev->lock);
526 rc = em28xx_read_ac97(dev, kcontrol->private_value); 582 rc = em28xx_read_ac97(dev, kcontrol->private_value);
527 if (rc < 0) 583 if (rc < 0)
528 goto err; 584 goto err;
@@ -550,9 +606,20 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *value) 606 struct snd_ctl_elem_value *value)
551{ 607{
552 struct em28xx *dev = snd_kcontrol_chip(kcontrol); 608 struct em28xx *dev = snd_kcontrol_chip(kcontrol);
609 struct snd_pcm_substream *substream = dev->adev.capture_pcm_substream;
610 int nonblock = 0;
553 int val; 611 int val;
554 612
555 mutex_lock(&dev->lock); 613 if (dev->disconnected)
614 return -ENODEV;
615
616 if (substream)
617 nonblock = !!(substream->f_flags & O_NONBLOCK);
618 if (nonblock) {
619 if (!mutex_trylock(&dev->lock))
620 return -EAGAIN;
621 } else
622 mutex_lock(&dev->lock);
556 val = em28xx_read_ac97(dev, kcontrol->private_value); 623 val = em28xx_read_ac97(dev, kcontrol->private_value);
557 mutex_unlock(&dev->lock); 624 mutex_unlock(&dev->lock);
558 if (val < 0) 625 if (val < 0)
@@ -634,25 +701,204 @@ static struct snd_pcm_ops snd_em28xx_pcm_capture = {
634 .page = snd_pcm_get_vmalloc_page, 701 .page = snd_pcm_get_vmalloc_page,
635}; 702};
636 703
704static void em28xx_audio_free_urb(struct em28xx *dev)
705{
706 int i;
707
708 for (i = 0; i < dev->adev.num_urb; i++) {
709 struct urb *urb = dev->adev.urb[i];
710
711 if (!urb)
712 continue;
713
714 usb_free_coherent(dev->udev, urb->transfer_buffer_length,
715 dev->adev.transfer_buffer[i],
716 urb->transfer_dma);
717
718 usb_free_urb(urb);
719 }
720 kfree(dev->adev.urb);
721 kfree(dev->adev.transfer_buffer);
722 dev->adev.num_urb = 0;
723}
724
725/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
726static int em28xx_audio_ep_packet_size(struct usb_device *udev,
727 struct usb_endpoint_descriptor *e)
728{
729 int size = le16_to_cpu(e->wMaxPacketSize);
730
731 if (udev->speed == USB_SPEED_HIGH)
732 return (size & 0x7ff) * (1 + (((size) >> 11) & 0x03));
733
734 return size & 0x7ff;
735}
736
737static int em28xx_audio_urb_init(struct em28xx *dev)
738{
739 struct usb_interface *intf;
740 struct usb_endpoint_descriptor *e, *ep = NULL;
741 int i, ep_size, interval, num_urb, npackets;
742 int urb_size, bytes_per_transfer;
743 u8 alt;
744
745 if (dev->ifnum)
746 alt = 1;
747 else
748 alt = 7;
749
750 intf = usb_ifnum_to_if(dev->udev, dev->ifnum);
751
752 if (intf->num_altsetting <= alt) {
753 em28xx_errdev("alt %d doesn't exist on interface %d\n",
754 dev->ifnum, alt);
755 return -ENODEV;
756 }
757
758 for (i = 0; i < intf->altsetting[alt].desc.bNumEndpoints; i++) {
759 e = &intf->altsetting[alt].endpoint[i].desc;
760 if (!usb_endpoint_dir_in(e))
761 continue;
762 if (e->bEndpointAddress == EM28XX_EP_AUDIO) {
763 ep = e;
764 break;
765 }
766 }
767
768 if (!ep) {
769 em28xx_errdev("Couldn't find an audio endpoint");
770 return -ENODEV;
771 }
772
773 ep_size = em28xx_audio_ep_packet_size(dev->udev, ep);
774 interval = 1 << (ep->bInterval - 1);
775
776 em28xx_info("Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n",
777 EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed),
778 dev->ifnum, alt,
779 interval,
780 ep_size);
781
782 /* Calculate the number and size of URBs to better fit the audio samples */
783
784 /*
785 * Estimate the number of bytes per DMA transfer.
786 *
787 * This is given by the bit rate (for now, only 48000 Hz) multiplied
788 * by 2 channels and 2 bytes/sample divided by the number of microframe
789 * intervals and by the microframe rate (125 us)
790 */
791 bytes_per_transfer = DIV_ROUND_UP(48000 * 2 * 2, 125 * interval);
792
793 /*
794 * Estimate the number of transfer URBs. Don't let it go past the
795 * maximum number of URBs that is known to be supported by the device.
796 */
797 num_urb = DIV_ROUND_UP(bytes_per_transfer, ep_size);
798 if (num_urb > EM28XX_MAX_AUDIO_BUFS)
799 num_urb = EM28XX_MAX_AUDIO_BUFS;
800
801 /*
802 * Now that we know the number of bytes per transfer and the number of
803 * URBs, estimate the typical size of an URB, in order to adjust the
804 * minimal number of packets.
805 */
806 urb_size = bytes_per_transfer / num_urb;
807
808 /*
809 * Now, calculate the amount of audio packets to be filled on each
810 * URB. In order to preserve the old behaviour, use a minimal
811 * threshold for this value.
812 */
813 npackets = EM28XX_MIN_AUDIO_PACKETS;
814 if (urb_size > ep_size * npackets)
815 npackets = DIV_ROUND_UP(urb_size, ep_size);
816
817 em28xx_info("Number of URBs: %d, with %d packets and %d size",
818 num_urb, npackets, urb_size);
819
820 /* Estimate the bytes per period */
821 dev->adev.period = urb_size * npackets;
822
823 /* Allocate space to store the number of URBs to be used */
824
825 dev->adev.transfer_buffer = kcalloc(num_urb,
826 sizeof(*dev->adev.transfer_buffer),
827 GFP_ATOMIC);
828 if (!dev->adev.transfer_buffer) {
829 return -ENOMEM;
830 }
831
832 dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC);
833 if (!dev->adev.urb) {
834 kfree(dev->adev.transfer_buffer);
835 return -ENOMEM;
836 }
837
838 /* Alloc memory for each URB and for each transfer buffer */
839 dev->adev.num_urb = num_urb;
840 for (i = 0; i < num_urb; i++) {
841 struct urb *urb;
842 int j, k;
843 void *buf;
844
845 urb = usb_alloc_urb(npackets, GFP_ATOMIC);
846 if (!urb) {
847 em28xx_errdev("usb_alloc_urb failed!\n");
848 em28xx_audio_free_urb(dev);
849 return -ENOMEM;
850 }
851 dev->adev.urb[i] = urb;
852
853 buf = usb_alloc_coherent(dev->udev, npackets * ep_size, GFP_ATOMIC,
854 &urb->transfer_dma);
855 if (!buf) {
856 em28xx_errdev("usb_alloc_coherent failed!\n");
857 em28xx_audio_free_urb(dev);
858 return -ENOMEM;
859 }
860 dev->adev.transfer_buffer[i] = buf;
861
862 urb->dev = dev->udev;
863 urb->context = dev;
864 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
865 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
866 urb->transfer_buffer = buf;
867 urb->interval = interval;
868 urb->complete = em28xx_audio_isocirq;
869 urb->number_of_packets = npackets;
870 urb->transfer_buffer_length = ep_size * npackets;
871
872 for (j = k = 0; j < npackets; j++, k += ep_size) {
873 urb->iso_frame_desc[j].offset = k;
874 urb->iso_frame_desc[j].length = ep_size;
875 }
876 }
877
878 return 0;
879}
880
637static int em28xx_audio_init(struct em28xx *dev) 881static int em28xx_audio_init(struct em28xx *dev)
638{ 882{
639 struct em28xx_audio *adev = &dev->adev; 883 struct em28xx_audio *adev = &dev->adev;
640 struct snd_pcm *pcm; 884 struct snd_pcm *pcm;
641 struct snd_card *card; 885 struct snd_card *card;
642 static int devnr; 886 static int devnr;
643 int err; 887 int err;
644 888
645 if (!dev->has_alsa_audio || dev->audio_ifnum < 0) { 889 if (!dev->has_alsa_audio) {
646 /* This device does not support the extension (in this case 890 /* This device does not support the extension (in this case
647 the device is expecting the snd-usb-audio module or 891 the device is expecting the snd-usb-audio module or
648 doesn't have analog audio support at all) */ 892 doesn't have analog audio support at all) */
649 return 0; 893 return 0;
650 } 894 }
651 895
652 printk(KERN_INFO "em28xx-audio.c: probing for em28xx Audio Vendor Class\n"); 896 em28xx_info("Binding audio extension\n");
897
653 printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " 898 printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
654 "Rechberger\n"); 899 "Rechberger\n");
655 printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2007-2011 Mauro Carvalho Chehab\n"); 900 printk(KERN_INFO
901 "em28xx-audio.c: Copyright (C) 2007-2014 Mauro Carvalho Chehab\n");
656 902
657 err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0, 903 err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
658 &card); 904 &card);
@@ -660,11 +906,12 @@ static int em28xx_audio_init(struct em28xx *dev)
660 return err; 906 return err;
661 907
662 spin_lock_init(&adev->slock); 908 spin_lock_init(&adev->slock);
909 adev->sndcard = card;
910 adev->udev = dev->udev;
911
663 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); 912 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
664 if (err < 0) { 913 if (err < 0)
665 snd_card_free(card); 914 goto card_free;
666 return err;
667 }
668 915
669 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); 916 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
670 pcm->info_flags = 0; 917 pcm->info_flags = 0;
@@ -694,15 +941,25 @@ static int em28xx_audio_init(struct em28xx *dev)
694 em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER); 941 em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER);
695 } 942 }
696 943
944 err = em28xx_audio_urb_init(dev);
945 if (err)
946 goto card_free;
947
697 err = snd_card_register(card); 948 err = snd_card_register(card);
698 if (err < 0) { 949 if (err < 0)
699 snd_card_free(card); 950 goto urb_free;
700 return err;
701 }
702 adev->sndcard = card;
703 adev->udev = dev->udev;
704 951
952 em28xx_info("Audio extension successfully initialized\n");
705 return 0; 953 return 0;
954
955urb_free:
956 em28xx_audio_free_urb(dev);
957
958card_free:
959 snd_card_free(card);
960 adev->sndcard = NULL;
961
962 return err;
706} 963}
707 964
708static int em28xx_audio_fini(struct em28xx *dev) 965static int em28xx_audio_fini(struct em28xx *dev)
@@ -717,7 +974,14 @@ static int em28xx_audio_fini(struct em28xx *dev)
717 return 0; 974 return 0;
718 } 975 }
719 976
977 em28xx_info("Closing audio extension");
978
720 if (dev->adev.sndcard) { 979 if (dev->adev.sndcard) {
980 snd_card_disconnect(dev->adev.sndcard);
981 flush_work(&dev->wq_trigger);
982
983 em28xx_audio_free_urb(dev);
984
721 snd_card_free(dev->adev.sndcard); 985 snd_card_free(dev->adev.sndcard);
722 dev->adev.sndcard = NULL; 986 dev->adev.sndcard = NULL;
723 } 987 }
@@ -745,7 +1009,8 @@ static void __exit em28xx_alsa_unregister(void)
745MODULE_LICENSE("GPL"); 1009MODULE_LICENSE("GPL");
746MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>"); 1010MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");
747MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); 1011MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
748MODULE_DESCRIPTION("Em28xx Audio driver"); 1012MODULE_DESCRIPTION(DRIVER_DESC " - audio interface");
1013MODULE_VERSION(EM28XX_VERSION);
749 1014
750module_init(em28xx_alsa_register); 1015module_init(em28xx_alsa_register);
751module_exit(em28xx_alsa_unregister); 1016module_exit(em28xx_alsa_unregister);
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c
index d666741797d4..c29f5c4e7b40 100644
--- a/drivers/media/usb/em28xx/em28xx-camera.c
+++ b/drivers/media/usb/em28xx/em28xx-camera.c
@@ -454,3 +454,4 @@ int em28xx_init_camera(struct em28xx *dev)
454 454
455 return ret; 455 return ret;
456} 456}
457EXPORT_SYMBOL_GPL(em28xx_init_camera);
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index a5196697627f..4d97a76cc3b0 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -36,7 +36,6 @@
36#include <media/tvaudio.h> 36#include <media/tvaudio.h>
37#include <media/i2c-addr.h> 37#include <media/i2c-addr.h>
38#include <media/tveeprom.h> 38#include <media/tveeprom.h>
39#include <media/v4l2-clk.h>
40#include <media/v4l2-common.h> 39#include <media/v4l2-common.h>
41 40
42#include "em28xx.h" 41#include "em28xx.h"
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(usb_xfer_mode,
67 66
68 67
69/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */ 68/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
70static unsigned long em28xx_devused; 69DECLARE_BITMAP(em28xx_devused, EM28XX_MAXBOARDS);
71 70
72struct em28xx_hash_table { 71struct em28xx_hash_table {
73 unsigned long hash; 72 unsigned long hash;
@@ -356,6 +355,28 @@ static struct em28xx_reg_seq c3tech_digital_duo_digital[] = {
356 { -1, -1, -1, -1}, 355 { -1, -1, -1, -1},
357}; 356};
358 357
358/*
359 * 2013:0258 PCTV DVB-S2 Stick (461e)
360 * GPIO 0 = POWER_ON
361 * GPIO 1 = BOOST
362 * GPIO 2 = VUV_LNB (red LED)
363 * GPIO 3 = #EXT_12V
364 * GPIO 4 = INT_DEM
365 * GPIO 5 = INT_LNB
366 * GPIO 6 = #RESET_DEM
367 * GPIO 7 = P07_LED (green LED)
368 */
369static struct em28xx_reg_seq pctv_461e[] = {
370 {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff, 0},
371 {0x0d, 0xff, 0xff, 0},
372 {EM2874_R80_GPIO_P0_CTRL, 0x3f, 0xff, 100}, /* reset demod */
373 {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff, 200}, /* reset demod */
374 {0x0d, 0x42, 0xff, 0},
375 {EM2874_R80_GPIO_P0_CTRL, 0xeb, 0xff, 0},
376 {EM2874_R5F_TS_ENABLE, 0x84, 0x84, 0}, /* parallel? | null discard */
377 { -1, -1, -1, -1},
378};
379
359#if 0 380#if 0
360static struct em28xx_reg_seq hauppauge_930c_gpio[] = { 381static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
361 {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, 382 {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10},
@@ -412,6 +433,70 @@ static struct em28xx_reg_seq pctv_520e[] = {
412 { -1, -1, -1, -1}, 433 { -1, -1, -1, -1},
413}; 434};
414 435
436/* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
437 * reg 0x80/0x84:
438 * GPIO_0: capturing LED, 0=on, 1=off
439 * GPIO_2: AV mute button, 0=pressed, 1=unpressed
440 * GPIO 3: illumination button, 0=pressed, 1=unpressed
441 * GPIO_6: illumination/flash LED, 0=on, 1=off
442 * reg 0x81/0x85:
443 * GPIO_7: snapshot button, 0=pressed, 1=unpressed
444 */
445static struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = {
446 {EM2820_R08_GPIO_CTRL, 0xf7, 0xff, 10},
447 {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xb2, 10},
448 { -1, -1, -1, -1},
449};
450
451/*
452 * Button definitions
453 */
454static struct em28xx_button std_snapshot_button[] = {
455 {
456 .role = EM28XX_BUTTON_SNAPSHOT,
457 .reg_r = EM28XX_R0C_USBSUSP,
458 .reg_clearing = EM28XX_R0C_USBSUSP,
459 .mask = EM28XX_R0C_USBSUSP_SNAPSHOT,
460 .inverted = 0,
461 },
462 {-1, 0, 0, 0, 0},
463};
464
465static struct em28xx_button speedlink_vad_laplace_buttons[] = {
466 {
467 .role = EM28XX_BUTTON_SNAPSHOT,
468 .reg_r = EM2874_R85_GPIO_P1_STATE,
469 .mask = 0x80,
470 .inverted = 1,
471 },
472 {
473 .role = EM28XX_BUTTON_ILLUMINATION,
474 .reg_r = EM2874_R84_GPIO_P0_STATE,
475 .mask = 0x08,
476 .inverted = 1,
477 },
478 {-1, 0, 0, 0, 0},
479};
480
481/*
482 * LED definitions
483 */
484static struct em28xx_led speedlink_vad_laplace_leds[] = {
485 {
486 .role = EM28XX_LED_ANALOG_CAPTURING,
487 .gpio_reg = EM2874_R80_GPIO_P0_CTRL,
488 .gpio_mask = 0x01,
489 .inverted = 1,
490 },
491 {
492 .role = EM28XX_LED_ILLUMINATION,
493 .gpio_reg = EM2874_R80_GPIO_P0_CTRL,
494 .gpio_mask = 0x40,
495 .inverted = 1,
496 },
497 {-1, 0, 0, 0},
498};
499
415/* 500/*
416 * Board definitions 501 * Board definitions
417 */ 502 */
@@ -1391,7 +1476,7 @@ struct em28xx_board em28xx_boards[] = {
1391 }, 1476 },
1392 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { 1477 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
1393 .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0", 1478 .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
1394 .has_snapshot_button = 1, 1479 .buttons = std_snapshot_button,
1395 .tda9887_conf = TDA9887_PRESENT, 1480 .tda9887_conf = TDA9887_PRESENT,
1396 .tuner_type = TUNER_YMEC_TVF_5533MF, 1481 .tuner_type = TUNER_YMEC_TVF_5533MF,
1397 .decoder = EM28XX_SAA711X, 1482 .decoder = EM28XX_SAA711X,
@@ -1413,7 +1498,7 @@ struct em28xx_board em28xx_boards[] = {
1413 }, 1498 },
1414 [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = { 1499 [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = {
1415 .name = "EM2860/SAA711X Reference Design", 1500 .name = "EM2860/SAA711X Reference Design",
1416 .has_snapshot_button = 1, 1501 .buttons = std_snapshot_button,
1417 .tuner_type = TUNER_ABSENT, 1502 .tuner_type = TUNER_ABSENT,
1418 .decoder = EM28XX_SAA711X, 1503 .decoder = EM28XX_SAA711X,
1419 .input = { { 1504 .input = { {
@@ -2020,7 +2105,7 @@ struct em28xx_board em28xx_boards[] = {
2020 }, 2105 },
2021 /* 1b80:e1cc Delock 61959 2106 /* 1b80:e1cc Delock 61959
2022 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 2107 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
2023 * mostly the same as MaxMedia UB-425-TC but different remote */ 2108 * mostly the same as MaxMedia UB-425-TC but different remote */
2024 [EM2874_BOARD_DELOCK_61959] = { 2109 [EM2874_BOARD_DELOCK_61959] = {
2025 .name = "Delock 61959", 2110 .name = "Delock 61959",
2026 .tuner_type = TUNER_ABSENT, 2111 .tuner_type = TUNER_ABSENT,
@@ -2043,7 +2128,38 @@ struct em28xx_board em28xx_boards[] = {
2043 .tuner_gpio = default_tuner_gpio, 2128 .tuner_gpio = default_tuner_gpio,
2044 .def_i2c_bus = 1, 2129 .def_i2c_bus = 1,
2045 }, 2130 },
2131 /* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
2132 * Empia EM2765 + OmniVision OV2640 */
2133 [EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = {
2134 .name = "SpeedLink Vicious And Devine Laplace webcam",
2135 .xclk = EM28XX_XCLK_FREQUENCY_24MHZ,
2136 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
2137 EM28XX_I2C_FREQ_100_KHZ,
2138 .def_i2c_bus = 1,
2139 .tuner_type = TUNER_ABSENT,
2140 .is_webcam = 1,
2141 .input = { {
2142 .type = EM28XX_VMUX_COMPOSITE1,
2143 .amux = EM28XX_AMUX_VIDEO,
2144 .gpio = speedlink_vad_laplace_reg_seq,
2145 } },
2146 .buttons = speedlink_vad_laplace_buttons,
2147 .leds = speedlink_vad_laplace_leds,
2148 },
2149 /* 2013:0258 PCTV DVB-S2 Stick (461e)
2150 * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293 */
2151 [EM28178_BOARD_PCTV_461E] = {
2152 .def_i2c_bus = 1,
2153 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ,
2154 .name = "PCTV DVB-S2 Stick (461e)",
2155 .tuner_type = TUNER_ABSENT,
2156 .tuner_gpio = pctv_461e,
2157 .has_dvb = 1,
2158 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
2159 },
2046}; 2160};
2161EXPORT_SYMBOL_GPL(em28xx_boards);
2162
2047const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 2163const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
2048 2164
2049/* table of devices that work with this driver */ 2165/* table of devices that work with this driver */
@@ -2208,6 +2324,12 @@ struct usb_device_id em28xx_id_table[] = {
2208 .driver_info = EM2884_BOARD_PCTV_520E }, 2324 .driver_info = EM2884_BOARD_PCTV_520E },
2209 { USB_DEVICE(0x1b80, 0xe1cc), 2325 { USB_DEVICE(0x1b80, 0xe1cc),
2210 .driver_info = EM2874_BOARD_DELOCK_61959 }, 2326 .driver_info = EM2874_BOARD_DELOCK_61959 },
2327 { USB_DEVICE(0x1ae7, 0x9003),
2328 .driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
2329 { USB_DEVICE(0x1ae7, 0x9004),
2330 .driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
2331 { USB_DEVICE(0x2013, 0x0258),
2332 .driver_info = EM28178_BOARD_PCTV_461E },
2211 { }, 2333 { },
2212}; 2334};
2213MODULE_DEVICE_TABLE(usb, em28xx_id_table); 2335MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2239,24 +2361,6 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
2239}; 2361};
2240/* NOTE: introduce a separate hash table for devices with 16 bit eeproms */ 2362/* NOTE: introduce a separate hash table for devices with 16 bit eeproms */
2241 2363
2242/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2243static unsigned short saa711x_addrs[] = {
2244 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2245 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2246 I2C_CLIENT_END };
2247
2248static unsigned short tvp5150_addrs[] = {
2249 0xb8 >> 1,
2250 0xba >> 1,
2251 I2C_CLIENT_END
2252};
2253
2254static unsigned short msp3400_addrs[] = {
2255 0x80 >> 1,
2256 0x88 >> 1,
2257 I2C_CLIENT_END
2258};
2259
2260int em28xx_tuner_callback(void *ptr, int component, int command, int arg) 2364int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
2261{ 2365{
2262 struct em28xx_i2c_bus *i2c_bus = ptr; 2366 struct em28xx_i2c_bus *i2c_bus = ptr;
@@ -2408,113 +2512,6 @@ static void em28xx_pre_card_setup(struct em28xx *dev)
2408 em28xx_set_mode(dev, EM28XX_SUSPEND); 2512 em28xx_set_mode(dev, EM28XX_SUSPEND);
2409} 2513}
2410 2514
2411static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2412{
2413 memset(ctl, 0, sizeof(*ctl));
2414
2415 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2416 ctl->max_len = 64;
2417 ctl->mts = em28xx_boards[dev->model].mts_firmware;
2418
2419 switch (dev->model) {
2420 case EM2880_BOARD_EMPIRE_DUAL_TV:
2421 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
2422 case EM2882_BOARD_TERRATEC_HYBRID_XS:
2423 ctl->demod = XC3028_FE_ZARLINK456;
2424 break;
2425 case EM2880_BOARD_TERRATEC_HYBRID_XS:
2426 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
2427 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
2428 ctl->demod = XC3028_FE_ZARLINK456;
2429 break;
2430 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
2431 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
2432 ctl->demod = XC3028_FE_DEFAULT;
2433 break;
2434 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
2435 ctl->demod = XC3028_FE_DEFAULT;
2436 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
2437 break;
2438 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
2439 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
2440 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
2441 /* FIXME: Better to specify the needed IF */
2442 ctl->demod = XC3028_FE_DEFAULT;
2443 break;
2444 case EM2883_BOARD_KWORLD_HYBRID_330U:
2445 case EM2882_BOARD_DIKOM_DK300:
2446 case EM2882_BOARD_KWORLD_VS_DVBT:
2447 ctl->demod = XC3028_FE_CHINA;
2448 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2449 break;
2450 case EM2882_BOARD_EVGA_INDTUBE:
2451 ctl->demod = XC3028_FE_CHINA;
2452 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
2453 break;
2454 default:
2455 ctl->demod = XC3028_FE_OREN538;
2456 }
2457}
2458
2459static void em28xx_tuner_setup(struct em28xx *dev)
2460{
2461 struct tuner_setup tun_setup;
2462 struct v4l2_frequency f;
2463
2464 if (dev->tuner_type == TUNER_ABSENT)
2465 return;
2466
2467 memset(&tun_setup, 0, sizeof(tun_setup));
2468
2469 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2470 tun_setup.tuner_callback = em28xx_tuner_callback;
2471
2472 if (dev->board.radio.type) {
2473 tun_setup.type = dev->board.radio.type;
2474 tun_setup.addr = dev->board.radio_addr;
2475
2476 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2477 }
2478
2479 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2480 tun_setup.type = dev->tuner_type;
2481 tun_setup.addr = dev->tuner_addr;
2482
2483 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2484 }
2485
2486 if (dev->tda9887_conf) {
2487 struct v4l2_priv_tun_config tda9887_cfg;
2488
2489 tda9887_cfg.tuner = TUNER_TDA9887;
2490 tda9887_cfg.priv = &dev->tda9887_conf;
2491
2492 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
2493 }
2494
2495 if (dev->tuner_type == TUNER_XC2028) {
2496 struct v4l2_priv_tun_config xc2028_cfg;
2497 struct xc2028_ctrl ctl;
2498
2499 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2500 memset(&ctl, 0, sizeof(ctl));
2501
2502 em28xx_setup_xc3028(dev, &ctl);
2503
2504 xc2028_cfg.tuner = TUNER_XC2028;
2505 xc2028_cfg.priv = &ctl;
2506
2507 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
2508 }
2509
2510 /* configure tuner */
2511 f.tuner = 0;
2512 f.type = V4L2_TUNER_ANALOG_TV;
2513 f.frequency = 9076; /* just a magic number */
2514 dev->ctl_freq = f.frequency;
2515 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
2516}
2517
2518static int em28xx_hint_board(struct em28xx *dev) 2515static int em28xx_hint_board(struct em28xx *dev)
2519{ 2516{
2520 int i; 2517 int i;
@@ -2768,57 +2765,56 @@ static void em28xx_card_setup(struct em28xx *dev)
2768 /* Allow override tuner type by a module parameter */ 2765 /* Allow override tuner type by a module parameter */
2769 if (tuner >= 0) 2766 if (tuner >= 0)
2770 dev->tuner_type = tuner; 2767 dev->tuner_type = tuner;
2768}
2771 2769
2772 /* request some modules */ 2770void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2773 if (dev->board.has_msp34xx) 2771{
2774 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], 2772 memset(ctl, 0, sizeof(*ctl));
2775 "msp3400", 0, msp3400_addrs);
2776
2777 if (dev->board.decoder == EM28XX_SAA711X)
2778 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2779 "saa7115_auto", 0, saa711x_addrs);
2780
2781 if (dev->board.decoder == EM28XX_TVP5150)
2782 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2783 "tvp5150", 0, tvp5150_addrs);
2784
2785 if (dev->board.adecoder == EM28XX_TVAUDIO)
2786 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2787 "tvaudio", dev->board.tvaudio_addr, NULL);
2788
2789 if (dev->board.tuner_type != TUNER_ABSENT) {
2790 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2791
2792 if (dev->board.radio.type)
2793 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2794 "tuner", dev->board.radio_addr, NULL);
2795
2796 if (has_demod)
2797 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2798 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2799 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2800 if (dev->tuner_addr == 0) {
2801 enum v4l2_i2c_tuner_type type =
2802 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2803 struct v4l2_subdev *sd;
2804
2805 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2806 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2807 0, v4l2_i2c_tuner_addrs(type));
2808
2809 if (sd)
2810 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2811 } else {
2812 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2813 "tuner", dev->tuner_addr, NULL);
2814 }
2815 }
2816 2773
2817 em28xx_tuner_setup(dev); 2774 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2775 ctl->max_len = 64;
2776 ctl->mts = em28xx_boards[dev->model].mts_firmware;
2818 2777
2819 em28xx_init_camera(dev); 2778 switch (dev->model) {
2779 case EM2880_BOARD_EMPIRE_DUAL_TV:
2780 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
2781 case EM2882_BOARD_TERRATEC_HYBRID_XS:
2782 ctl->demod = XC3028_FE_ZARLINK456;
2783 break;
2784 case EM2880_BOARD_TERRATEC_HYBRID_XS:
2785 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
2786 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
2787 ctl->demod = XC3028_FE_ZARLINK456;
2788 break;
2789 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
2790 case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
2791 ctl->demod = XC3028_FE_DEFAULT;
2792 break;
2793 case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
2794 ctl->demod = XC3028_FE_DEFAULT;
2795 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
2796 break;
2797 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
2798 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
2799 case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
2800 /* FIXME: Better to specify the needed IF */
2801 ctl->demod = XC3028_FE_DEFAULT;
2802 break;
2803 case EM2883_BOARD_KWORLD_HYBRID_330U:
2804 case EM2882_BOARD_DIKOM_DK300:
2805 case EM2882_BOARD_KWORLD_VS_DVBT:
2806 ctl->demod = XC3028_FE_CHINA;
2807 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2808 break;
2809 case EM2882_BOARD_EVGA_INDTUBE:
2810 ctl->demod = XC3028_FE_CHINA;
2811 ctl->fname = XC3028L_DEFAULT_FIRMWARE;
2812 break;
2813 default:
2814 ctl->demod = XC3028_FE_OREN538;
2815 }
2820} 2816}
2821 2817EXPORT_SYMBOL_GPL(em28xx_setup_xc3028);
2822 2818
2823static void request_module_async(struct work_struct *work) 2819static void request_module_async(struct work_struct *work)
2824{ 2820{
@@ -2831,17 +2827,30 @@ static void request_module_async(struct work_struct *work)
2831 * can be initialised right now. Otherwise, the module init 2827 * can be initialised right now. Otherwise, the module init
2832 * code will do it. 2828 * code will do it.
2833 */ 2829 */
2830
2831 /*
2832 * Devicdes with an audio-only interface also have a V4L/DVB/RC
2833 * interface. Don't register extensions twice on those devices.
2834 */
2835 if (dev->is_audio_only) {
2836#if defined(CONFIG_MODULES) && defined(MODULE)
2837 request_module("em28xx-alsa");
2838#endif
2839 return;
2840 }
2841
2834 em28xx_init_extension(dev); 2842 em28xx_init_extension(dev);
2835 2843
2836#if defined(CONFIG_MODULES) && defined(MODULE) 2844#if defined(CONFIG_MODULES) && defined(MODULE)
2845 if (dev->has_video)
2846 request_module("em28xx-v4l");
2837 if (dev->has_audio_class) 2847 if (dev->has_audio_class)
2838 request_module("snd-usb-audio"); 2848 request_module("snd-usb-audio");
2839 else if (dev->has_alsa_audio) 2849 else if (dev->has_alsa_audio)
2840 request_module("em28xx-alsa"); 2850 request_module("em28xx-alsa");
2841
2842 if (dev->board.has_dvb) 2851 if (dev->board.has_dvb)
2843 request_module("em28xx-dvb"); 2852 request_module("em28xx-dvb");
2844 if (dev->board.has_snapshot_button || 2853 if (dev->board.buttons ||
2845 ((dev->board.ir_codes || dev->board.has_ir_i2c) && !disable_ir)) 2854 ((dev->board.ir_codes || dev->board.has_ir_i2c) && !disable_ir))
2846 request_module("em28xx-rc"); 2855 request_module("em28xx-rc");
2847#endif /* CONFIG_MODULES */ 2856#endif /* CONFIG_MODULES */
@@ -2867,23 +2876,20 @@ void em28xx_release_resources(struct em28xx *dev)
2867{ 2876{
2868 /*FIXME: I2C IR should be disconnected */ 2877 /*FIXME: I2C IR should be disconnected */
2869 2878
2870 em28xx_release_analog_resources(dev); 2879 mutex_lock(&dev->lock);
2871 2880
2872 if (dev->def_i2c_bus) 2881 if (dev->def_i2c_bus)
2873 em28xx_i2c_unregister(dev, 1); 2882 em28xx_i2c_unregister(dev, 1);
2874 em28xx_i2c_unregister(dev, 0); 2883 em28xx_i2c_unregister(dev, 0);
2875 if (dev->clk)
2876 v4l2_clk_unregister_fixed(dev->clk);
2877
2878 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2879
2880 v4l2_device_unregister(&dev->v4l2_dev);
2881 2884
2882 usb_put_dev(dev->udev); 2885 usb_put_dev(dev->udev);
2883 2886
2884 /* Mark device as unused */ 2887 /* Mark device as unused */
2885 clear_bit(dev->devno, &em28xx_devused); 2888 clear_bit(dev->devno, em28xx_devused);
2889
2890 mutex_unlock(&dev->lock);
2886}; 2891};
2892EXPORT_SYMBOL_GPL(em28xx_release_resources);
2887 2893
2888/* 2894/*
2889 * em28xx_init_dev() 2895 * em28xx_init_dev()
@@ -2893,7 +2899,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
2893 struct usb_interface *interface, 2899 struct usb_interface *interface,
2894 int minor) 2900 int minor)
2895{ 2901{
2896 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2897 int retval; 2902 int retval;
2898 static const char *default_chip_name = "em28xx"; 2903 static const char *default_chip_name = "em28xx";
2899 const char *chip_name = default_chip_name; 2904 const char *chip_name = default_chip_name;
@@ -2968,6 +2973,11 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
2968 dev->wait_after_write = 0; 2973 dev->wait_after_write = 0;
2969 dev->eeprom_addrwidth_16bit = 1; 2974 dev->eeprom_addrwidth_16bit = 1;
2970 break; 2975 break;
2976 case CHIP_ID_EM28178:
2977 chip_name = "em28178";
2978 dev->wait_after_write = 0;
2979 dev->eeprom_addrwidth_16bit = 1;
2980 break;
2971 case CHIP_ID_EM2883: 2981 case CHIP_ID_EM2883:
2972 chip_name = "em2882/3"; 2982 chip_name = "em2882/3";
2973 dev->wait_after_write = 0; 2983 dev->wait_after_write = 0;
@@ -2983,6 +2993,16 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
2983 } 2993 }
2984 } 2994 }
2985 2995
2996 if (dev->chip_id == CHIP_ID_EM2870 ||
2997 dev->chip_id == CHIP_ID_EM2874 ||
2998 dev->chip_id == CHIP_ID_EM28174 ||
2999 dev->chip_id == CHIP_ID_EM28178) {
3000 /* Digital only device - don't load any alsa module */
3001 dev->audio_mode.has_audio = false;
3002 dev->has_audio_class = false;
3003 dev->has_alsa_audio = false;
3004 }
3005
2986 if (chip_name != default_chip_name) 3006 if (chip_name != default_chip_name)
2987 printk(KERN_INFO DRIVER_NAME 3007 printk(KERN_INFO DRIVER_NAME
2988 ": chip ID is %s\n", chip_name); 3008 ": chip ID is %s\n", chip_name);
@@ -3015,15 +3035,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3015 } 3035 }
3016 } 3036 }
3017 3037
3018 retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
3019 if (retval < 0) {
3020 em28xx_errdev("Call to v4l2_device_register() failed!\n");
3021 return retval;
3022 }
3023
3024 v4l2_ctrl_handler_init(hdl, 8);
3025 dev->v4l2_dev.ctrl_handler = hdl;
3026
3027 rt_mutex_init(&dev->i2c_bus_lock); 3038 rt_mutex_init(&dev->i2c_bus_lock);
3028 3039
3029 /* register i2c bus 0 */ 3040 /* register i2c bus 0 */
@@ -3034,7 +3045,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3034 if (retval < 0) { 3045 if (retval < 0) {
3035 em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n", 3046 em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n",
3036 __func__, retval); 3047 __func__, retval);
3037 goto unregister_dev; 3048 return retval;
3038 } 3049 }
3039 3050
3040 /* register i2c bus 1 */ 3051 /* register i2c bus 1 */
@@ -3048,88 +3059,17 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3048 if (retval < 0) { 3059 if (retval < 0) {
3049 em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n", 3060 em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n",
3050 __func__, retval); 3061 __func__, retval);
3051 goto unregister_dev;
3052 }
3053 }
3054
3055 /*
3056 * Default format, used for tvp5150 or saa711x output formats
3057 */
3058 dev->vinmode = 0x10;
3059 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
3060 EM28XX_VINCTRL_CCIR656_ENABLE;
3061 3062
3062 /* Do board specific init and eeprom reading */ 3063 em28xx_i2c_unregister(dev, 0);
3063 em28xx_card_setup(dev);
3064 3064
3065 /* Configure audio */ 3065 return retval;
3066 retval = em28xx_audio_setup(dev);
3067 if (retval < 0) {
3068 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
3069 __func__, retval);
3070 goto fail;
3071 }
3072 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
3073 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
3074 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
3075 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
3076 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
3077 } else {
3078 /* install the em28xx notify callback */
3079 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
3080 em28xx_ctrl_notify, dev);
3081 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
3082 em28xx_ctrl_notify, dev);
3083 }
3084
3085 /* wake i2c devices */
3086 em28xx_wake_i2c(dev);
3087
3088 /* init video dma queues */
3089 INIT_LIST_HEAD(&dev->vidq.active);
3090 INIT_LIST_HEAD(&dev->vbiq.active);
3091
3092 if (dev->board.has_msp34xx) {
3093 /* Send a reset to other chips via gpio */
3094 retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
3095 if (retval < 0) {
3096 em28xx_errdev("%s: em28xx_write_reg - "
3097 "msp34xx(1) failed! error [%d]\n",
3098 __func__, retval);
3099 goto fail;
3100 }
3101 msleep(3);
3102
3103 retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
3104 if (retval < 0) {
3105 em28xx_errdev("%s: em28xx_write_reg - "
3106 "msp34xx(2) failed! error [%d]\n",
3107 __func__, retval);
3108 goto fail;
3109 } 3066 }
3110 msleep(3);
3111 }
3112
3113 retval = em28xx_register_analog_devices(dev);
3114 if (retval < 0) {
3115 goto fail;
3116 } 3067 }
3117 3068
3118 /* Save some power by putting tuner to sleep */ 3069 /* Do board specific init and eeprom reading */
3119 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); 3070 em28xx_card_setup(dev);
3120 3071
3121 return 0; 3072 return 0;
3122
3123fail:
3124 if (dev->def_i2c_bus)
3125 em28xx_i2c_unregister(dev, 1);
3126 em28xx_i2c_unregister(dev, 0);
3127 v4l2_ctrl_handler_free(&dev->ctrl_handler);
3128
3129unregister_dev:
3130 v4l2_device_unregister(&dev->v4l2_dev);
3131
3132 return retval;
3133} 3073}
3134 3074
3135/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ 3075/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
@@ -3154,7 +3094,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3154 3094
3155 /* Check to see next free device and mark as used */ 3095 /* Check to see next free device and mark as used */
3156 do { 3096 do {
3157 nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); 3097 nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
3158 if (nr >= EM28XX_MAXBOARDS) { 3098 if (nr >= EM28XX_MAXBOARDS) {
3159 /* No free device slots */ 3099 /* No free device slots */
3160 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", 3100 printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
@@ -3162,7 +3102,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3162 retval = -ENOMEM; 3102 retval = -ENOMEM;
3163 goto err_no_slot; 3103 goto err_no_slot;
3164 } 3104 }
3165 } while (test_and_set_bit(nr, &em28xx_devused)); 3105 } while (test_and_set_bit(nr, em28xx_devused));
3166 3106
3167 /* Don't register audio interfaces */ 3107 /* Don't register audio interfaces */
3168 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { 3108 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
@@ -3332,7 +3272,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3332 dev->alt = -1; 3272 dev->alt = -1;
3333 dev->is_audio_only = has_audio && !(has_video || has_dvb); 3273 dev->is_audio_only = has_audio && !(has_video || has_dvb);
3334 dev->has_alsa_audio = has_audio; 3274 dev->has_alsa_audio = has_audio;
3335 dev->audio_ifnum = ifnum; 3275 dev->audio_mode.has_audio = has_audio;
3276 dev->has_video = has_video;
3277 dev->ifnum = ifnum;
3336 3278
3337 /* Checks if audio is provided by some interface */ 3279 /* Checks if audio is provided by some interface */
3338 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { 3280 for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
@@ -3369,15 +3311,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3369 /* save our data pointer in this interface device */ 3311 /* save our data pointer in this interface device */
3370 usb_set_intfdata(interface, dev); 3312 usb_set_intfdata(interface, dev);
3371 3313
3372 /* initialize videobuf2 stuff */
3373 em28xx_vb2_setup(dev);
3374
3375 /* allocate device struct */ 3314 /* allocate device struct */
3376 mutex_init(&dev->lock); 3315 mutex_init(&dev->lock);
3377 mutex_lock(&dev->lock);
3378 retval = em28xx_init_dev(dev, udev, interface, nr); 3316 retval = em28xx_init_dev(dev, udev, interface, nr);
3379 if (retval) { 3317 if (retval) {
3380 goto unlock_and_free; 3318 goto err_free;
3381 } 3319 }
3382 3320
3383 if (usb_xfer_mode < 0) { 3321 if (usb_xfer_mode < 0) {
@@ -3402,26 +3340,6 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3402 3340
3403 em28xx_info("dvb set to %s mode.\n", 3341 em28xx_info("dvb set to %s mode.\n",
3404 dev->dvb_xfer_bulk ? "bulk" : "isoc"); 3342 dev->dvb_xfer_bulk ? "bulk" : "isoc");
3405
3406 /* pre-allocate DVB usb transfer buffers */
3407 if (dev->dvb_xfer_bulk) {
3408 retval = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
3409 dev->dvb_xfer_bulk,
3410 EM28XX_DVB_NUM_BUFS,
3411 512,
3412 EM28XX_DVB_BULK_PACKET_MULTIPLIER);
3413 } else {
3414 retval = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
3415 dev->dvb_xfer_bulk,
3416 EM28XX_DVB_NUM_BUFS,
3417 dev->dvb_max_pkt_size_isoc,
3418 EM28XX_DVB_NUM_ISOC_PACKETS);
3419 }
3420 if (retval) {
3421 printk(DRIVER_NAME
3422 ": Failed to pre-allocate USB transfer buffers for DVB.\n");
3423 goto unlock_and_free;
3424 }
3425 } 3343 }
3426 3344
3427 request_modules(dev); 3345 request_modules(dev);
@@ -3429,19 +3347,15 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3429 /* Should be the last thing to do, to avoid newer udev's to 3347 /* Should be the last thing to do, to avoid newer udev's to
3430 open the device before fully initializing it 3348 open the device before fully initializing it
3431 */ 3349 */
3432 mutex_unlock(&dev->lock);
3433 3350
3434 return 0; 3351 return 0;
3435 3352
3436unlock_and_free:
3437 mutex_unlock(&dev->lock);
3438
3439err_free: 3353err_free:
3440 kfree(dev->alt_max_pkt_size_isoc); 3354 kfree(dev->alt_max_pkt_size_isoc);
3441 kfree(dev); 3355 kfree(dev);
3442 3356
3443err: 3357err:
3444 clear_bit(nr, &em28xx_devused); 3358 clear_bit(nr, em28xx_devused);
3445 3359
3446err_no_slot: 3360err_no_slot:
3447 usb_put_dev(udev); 3361 usb_put_dev(udev);
@@ -3465,36 +3379,13 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
3465 3379
3466 dev->disconnected = 1; 3380 dev->disconnected = 1;
3467 3381
3468 if (dev->is_audio_only) { 3382 em28xx_info("Disconnecting %s\n", dev->name);
3469 mutex_lock(&dev->lock);
3470 em28xx_close_extension(dev);
3471 mutex_unlock(&dev->lock);
3472 return;
3473 }
3474
3475 em28xx_info("disconnecting %s\n", dev->vdev->name);
3476 3383
3477 flush_request_modules(dev); 3384 flush_request_modules(dev);
3478 3385
3479 mutex_lock(&dev->lock);
3480
3481 v4l2_device_disconnect(&dev->v4l2_dev);
3482
3483 if (dev->users) {
3484 em28xx_warn("device %s is open! Deregistration and memory deallocation are deferred on close.\n",
3485 video_device_node_name(dev->vdev));
3486
3487 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
3488 em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
3489 }
3490
3491 em28xx_close_extension(dev); 3386 em28xx_close_extension(dev);
3492 /* NOTE: must be called BEFORE the resources are released */
3493
3494 if (!dev->users)
3495 em28xx_release_resources(dev);
3496 3387
3497 mutex_unlock(&dev->lock); 3388 em28xx_release_resources(dev);
3498 3389
3499 if (!dev->users) { 3390 if (!dev->users) {
3500 kfree(dev->alt_max_pkt_size_isoc); 3391 kfree(dev->alt_max_pkt_size_isoc);
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index fc157af5234a..898fb9bd88a2 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/jiffies.h>
26#include <linux/list.h> 27#include <linux/list.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
@@ -33,6 +34,16 @@
33 34
34#include "em28xx.h" 35#include "em28xx.h"
35 36
37#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
38 "Markus Rechberger <mrechberger@gmail.com>, " \
39 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
40 "Sascha Sommer <saschasommer@freenet.de>"
41
42MODULE_AUTHOR(DRIVER_AUTHOR);
43MODULE_DESCRIPTION(DRIVER_DESC);
44MODULE_LICENSE("GPL");
45MODULE_VERSION(EM28XX_VERSION);
46
36/* #define ENABLE_DEBUG_ISOC_FRAMES */ 47/* #define ENABLE_DEBUG_ISOC_FRAMES */
37 48
38static unsigned int core_debug; 49static unsigned int core_debug;
@@ -53,14 +64,6 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
53 printk(KERN_INFO "%s %s :"fmt, \ 64 printk(KERN_INFO "%s %s :"fmt, \
54 dev->name, __func__ , ##arg); } while (0) 65 dev->name, __func__ , ##arg); } while (0)
55 66
56static int alt;
57module_param(alt, int, 0644);
58MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
59
60static unsigned int disable_vbi;
61module_param(disable_vbi, int, 0644);
62MODULE_PARM_DESC(disable_vbi, "disable vbi support");
63
64/* FIXME */ 67/* FIXME */
65#define em28xx_isocdbg(fmt, arg...) do {\ 68#define em28xx_isocdbg(fmt, arg...) do {\
66 if (core_debug) \ 69 if (core_debug) \
@@ -226,21 +229,42 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
226EXPORT_SYMBOL_GPL(em28xx_write_reg_bits); 229EXPORT_SYMBOL_GPL(em28xx_write_reg_bits);
227 230
228/* 231/*
232 * em28xx_toggle_reg_bits()
233 * toggles/inverts the bits (specified by bitmask) of a register
234 */
235int em28xx_toggle_reg_bits(struct em28xx *dev, u16 reg, u8 bitmask)
236{
237 int oldval;
238 u8 newval;
239
240 oldval = em28xx_read_reg(dev, reg);
241 if (oldval < 0)
242 return oldval;
243
244 newval = (~oldval & bitmask) | (oldval & ~bitmask);
245
246 return em28xx_write_reg(dev, reg, newval);
247}
248EXPORT_SYMBOL_GPL(em28xx_toggle_reg_bits);
249
250/*
229 * em28xx_is_ac97_ready() 251 * em28xx_is_ac97_ready()
230 * Checks if ac97 is ready 252 * Checks if ac97 is ready
231 */ 253 */
232static int em28xx_is_ac97_ready(struct em28xx *dev) 254static int em28xx_is_ac97_ready(struct em28xx *dev)
233{ 255{
234 int ret, i; 256 unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_AC97_XFER_TIMEOUT);
257 int ret;
235 258
236 /* Wait up to 50 ms for AC97 command to complete */ 259 /* Wait up to 50 ms for AC97 command to complete */
237 for (i = 0; i < 10; i++, msleep(5)) { 260 while (time_is_after_jiffies(timeout)) {
238 ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); 261 ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY);
239 if (ret < 0) 262 if (ret < 0)
240 return ret; 263 return ret;
241 264
242 if (!(ret & 0x01)) 265 if (!(ret & 0x01))
243 return 0; 266 return 0;
267 msleep(5);
244 } 268 }
245 269
246 em28xx_warn("AC97 command still being executed: not handled properly!\n"); 270 em28xx_warn("AC97 command still being executed: not handled properly!\n");
@@ -482,16 +506,8 @@ int em28xx_audio_setup(struct em28xx *dev)
482 int vid1, vid2, feat, cfg; 506 int vid1, vid2, feat, cfg;
483 u32 vid; 507 u32 vid;
484 508
485 if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874 509 if (!dev->audio_mode.has_audio)
486 || dev->chip_id == CHIP_ID_EM28174) {
487 /* Digital only device - don't load any alsa module */
488 dev->audio_mode.has_audio = false;
489 dev->has_audio_class = false;
490 dev->has_alsa_audio = false;
491 return 0; 510 return 0;
492 }
493
494 dev->audio_mode.has_audio = true;
495 511
496 /* See how this device is configured */ 512 /* See how this device is configured */
497 cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); 513 cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG);
@@ -504,17 +520,19 @@ int em28xx_audio_setup(struct em28xx *dev)
504 dev->has_alsa_audio = false; 520 dev->has_alsa_audio = false;
505 dev->audio_mode.has_audio = false; 521 dev->audio_mode.has_audio = false;
506 return 0; 522 return 0;
507 } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 523 } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) {
508 EM28XX_CHIPCFG_I2S_3_SAMPRATES) { 524 if (dev->chip_id < CHIP_ID_EM2860 &&
509 em28xx_info("I2S Audio (3 sample rates)\n"); 525 (cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
510 dev->audio_mode.i2s_3rates = 1; 526 EM2820_CHIPCFG_I2S_1_SAMPRATE)
511 } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 527 dev->audio_mode.i2s_samplerates = 1;
512 EM28XX_CHIPCFG_I2S_5_SAMPRATES) { 528 else if (dev->chip_id >= CHIP_ID_EM2860 &&
513 em28xx_info("I2S Audio (5 sample rates)\n"); 529 (cfg & EM28XX_CHIPCFG_AUDIOMASK) ==
514 dev->audio_mode.i2s_5rates = 1; 530 EM2860_CHIPCFG_I2S_5_SAMPRATES)
515 } 531 dev->audio_mode.i2s_samplerates = 5;
516 532 else
517 if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) { 533 dev->audio_mode.i2s_samplerates = 3;
534 em28xx_info("I2S Audio (%d sample rate(s))\n",
535 dev->audio_mode.i2s_samplerates);
518 /* Skip the code that does AC97 vendor detection */ 536 /* Skip the code that does AC97 vendor detection */
519 dev->audio_mode.ac97 = EM28XX_NO_AC97; 537 dev->audio_mode.ac97 = EM28XX_NO_AC97;
520 goto init_audio; 538 goto init_audio;
@@ -582,23 +600,21 @@ init_audio:
582} 600}
583EXPORT_SYMBOL_GPL(em28xx_audio_setup); 601EXPORT_SYMBOL_GPL(em28xx_audio_setup);
584 602
585int em28xx_colorlevels_set_default(struct em28xx *dev) 603const struct em28xx_led *em28xx_find_led(struct em28xx *dev,
604 enum em28xx_led_role role)
586{ 605{
587 em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT); 606 if (dev->board.leds) {
588 em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT); 607 u8 k = 0;
589 em28xx_write_reg(dev, EM28XX_R22_UVGAIN, SATURATION_DEFAULT); 608 while (dev->board.leds[k].role >= 0 &&
590 em28xx_write_reg(dev, EM28XX_R23_UOFFSET, BLUE_BALANCE_DEFAULT); 609 dev->board.leds[k].role < EM28XX_NUM_LED_ROLES) {
591 em28xx_write_reg(dev, EM28XX_R24_VOFFSET, RED_BALANCE_DEFAULT); 610 if (dev->board.leds[k].role == role)
592 em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, SHARPNESS_DEFAULT); 611 return &dev->board.leds[k];
593 612 k++;
594 em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20); 613 }
595 em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20); 614 }
596 em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20); 615 return NULL;
597 em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
598 em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
599 em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
600 return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
601} 616}
617EXPORT_SYMBOL_GPL(em28xx_find_led);
602 618
603int em28xx_capture_start(struct em28xx *dev, int start) 619int em28xx_capture_start(struct em28xx *dev, int start)
604{ 620{
@@ -606,271 +622,57 @@ int em28xx_capture_start(struct em28xx *dev, int start)
606 622
607 if (dev->chip_id == CHIP_ID_EM2874 || 623 if (dev->chip_id == CHIP_ID_EM2874 ||
608 dev->chip_id == CHIP_ID_EM2884 || 624 dev->chip_id == CHIP_ID_EM2884 ||
609 dev->chip_id == CHIP_ID_EM28174) { 625 dev->chip_id == CHIP_ID_EM28174 ||
626 dev->chip_id == CHIP_ID_EM28178) {
610 /* The Transport Stream Enable Register moved in em2874 */ 627 /* The Transport Stream Enable Register moved in em2874 */
611 if (!start) {
612 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
613 0x00,
614 EM2874_TS1_CAPTURE_ENABLE);
615 return rc;
616 }
617
618 /* Enable Transport Stream */
619 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, 628 rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
620 EM2874_TS1_CAPTURE_ENABLE, 629 start ?
630 EM2874_TS1_CAPTURE_ENABLE : 0x00,
621 EM2874_TS1_CAPTURE_ENABLE); 631 EM2874_TS1_CAPTURE_ENABLE);
622 return rc;
623 }
624
625
626 /* FIXME: which is the best order? */
627 /* video registers are sampled by VREF */
628 rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP,
629 start ? 0x10 : 0x00, 0x10);
630 if (rc < 0)
631 return rc;
632
633 if (!start) {
634 /* disable video capture */
635 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27);
636 return rc;
637 }
638
639 if (dev->board.is_webcam)
640 rc = em28xx_write_reg(dev, 0x13, 0x0c);
641
642 /* enable video capture */
643 rc = em28xx_write_reg(dev, 0x48, 0x00);
644
645 if (dev->mode == EM28XX_ANALOG_MODE)
646 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
647 else
648 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
649
650 msleep(6);
651
652 return rc;
653}
654
655int em28xx_vbi_supported(struct em28xx *dev)
656{
657 /* Modprobe option to manually disable */
658 if (disable_vbi == 1)
659 return 0;
660
661 if (dev->board.is_webcam)
662 return 0;
663
664 /* FIXME: check subdevices for VBI support */
665
666 if (dev->chip_id == CHIP_ID_EM2860 ||
667 dev->chip_id == CHIP_ID_EM2883)
668 return 1;
669
670 /* Version of em28xx that does not support VBI */
671 return 0;
672}
673
674int em28xx_set_outfmt(struct em28xx *dev)
675{
676 int ret;
677 u8 fmt, vinctrl;
678
679 fmt = dev->format->reg;
680 if (!dev->is_em25xx)
681 fmt |= 0x20;
682 /*
683 * NOTE: it's not clear if this is really needed !
684 * The datasheets say bit 5 is a reserved bit and devices seem to work
685 * fine without it. But the Windows driver sets it for em2710/50+em28xx
686 * devices and we've always been setting it, too.
687 *
688 * em2765 (em25xx, em276x/7x/8x) devices do NOT work with this bit set,
689 * it's likely used for an additional (compressed ?) format there.
690 */
691 ret = em28xx_write_reg(dev, EM28XX_R27_OUTFMT, fmt);
692 if (ret < 0)
693 return ret;
694
695 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
696 if (ret < 0)
697 return ret;
698
699 vinctrl = dev->vinctl;
700 if (em28xx_vbi_supported(dev) == 1) {
701 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
702 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
703 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
704 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
705 if (dev->norm & V4L2_STD_525_60) {
706 /* NTSC */
707 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
708 } else if (dev->norm & V4L2_STD_625_50) {
709 /* PAL */
710 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
711 }
712 }
713
714 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
715}
716
717static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
718 u8 ymin, u8 ymax)
719{
720 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n",
721 xmin, ymin, xmax, ymax);
722
723 em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1);
724 em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1);
725 em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1);
726 return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1);
727}
728
729static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
730 u16 width, u16 height)
731{
732 u8 cwidth = width >> 2;
733 u8 cheight = height >> 2;
734 u8 overflow = (height >> 9 & 0x02) | (width >> 10 & 0x01);
735 /* NOTE: size limit: 2047x1023 = 2MPix */
736
737 em28xx_coredbg("capture area set to (%d,%d): %dx%d\n",
738 hstart, vstart,
739 ((overflow & 2) << 9 | cwidth << 2),
740 ((overflow & 1) << 10 | cheight << 2));
741
742 em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1);
743 em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1);
744 em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1);
745 em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1);
746 em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1);
747
748 /* FIXME: function/meaning of these registers ? */
749 /* FIXME: align width+height to multiples of 4 ?! */
750 if (dev->is_em25xx) {
751 em28xx_write_reg(dev, 0x34, width >> 4);
752 em28xx_write_reg(dev, 0x35, height >> 4);
753 }
754}
755
756static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
757{
758 u8 mode;
759 /* the em2800 scaler only supports scaling down to 50% */
760
761 if (dev->board.is_em2800) {
762 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
763 } else { 632 } else {
764 u8 buf[2]; 633 /* FIXME: which is the best order? */
765 634 /* video registers are sampled by VREF */
766 buf[0] = h; 635 rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP,
767 buf[1] = h >> 8; 636 start ? 0x10 : 0x00, 0x10);
768 em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2); 637 if (rc < 0)
769 638 return rc;
770 buf[0] = v;
771 buf[1] = v >> 8;
772 em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
773 /* it seems that both H and V scalers must be active
774 to work correctly */
775 mode = (h || v) ? 0x30 : 0x00;
776 }
777 return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
778}
779
780/* FIXME: this only function read values from dev */
781int em28xx_resolution_set(struct em28xx *dev)
782{
783 int width, height;
784 width = norm_maxw(dev);
785 height = norm_maxh(dev);
786
787 /* Properly setup VBI */
788 dev->vbi_width = 720;
789 if (dev->norm & V4L2_STD_525_60)
790 dev->vbi_height = 12;
791 else
792 dev->vbi_height = 18;
793
794 em28xx_set_outfmt(dev);
795 639
796 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); 640 if (start) {
641 if (dev->board.is_webcam)
642 rc = em28xx_write_reg(dev, 0x13, 0x0c);
797 643
798 /* If we don't set the start position to 2 in VBI mode, we end up 644 /* Enable video capture */
799 with line 20/21 being YUYV encoded instead of being in 8-bit 645 rc = em28xx_write_reg(dev, 0x48, 0x00);
800 greyscale. The core of the issue is that line 21 (and line 23 for
801 PAL WSS) are inside of active video region, and as a result they
802 get the pixelformatting associated with that area. So by cropping
803 it out, we end up with the same format as the rest of the VBI
804 region */
805 if (em28xx_vbi_supported(dev) == 1)
806 em28xx_capture_area_set(dev, 0, 2, width, height);
807 else
808 em28xx_capture_area_set(dev, 0, 0, width, height);
809 646
810 return em28xx_scaler_set(dev, dev->hscale, dev->vscale); 647 if (dev->mode == EM28XX_ANALOG_MODE)
811} 648 rc = em28xx_write_reg(dev,
649 EM28XX_R12_VINENABLE, 0x67);
650 else
651 rc = em28xx_write_reg(dev,
652 EM28XX_R12_VINENABLE, 0x37);
812 653
813/* Set USB alternate setting for analog video */ 654 msleep(6);
814int em28xx_set_alternate(struct em28xx *dev) 655 } else {
815{ 656 /* disable video capture */
816 int errCode; 657 rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27);
817 int i; 658 }
818 unsigned int min_pkt_size = dev->width * 2 + 4;
819
820 /* NOTE: for isoc transfers, only alt settings > 0 are allowed
821 bulk transfers seem to work only with alt=0 ! */
822 dev->alt = 0;
823 if ((alt > 0) && (alt < dev->num_alt)) {
824 em28xx_coredbg("alternate forced to %d\n", dev->alt);
825 dev->alt = alt;
826 goto set_alt;
827 } 659 }
828 if (dev->analog_xfer_bulk)
829 goto set_alt;
830 660
831 /* When image size is bigger than a certain value, 661 if (rc < 0)
832 the frame size should be increased, otherwise, only 662 return rc;
833 green screen will be received.
834 */
835 if (dev->width * 2 * dev->height > 720 * 240 * 2)
836 min_pkt_size *= 2;
837 663
838 for (i = 0; i < dev->num_alt; i++) { 664 /* Switch (explicitly controlled) analog capturing LED on/off */
839 /* stop when the selected alt setting offers enough bandwidth */ 665 if (dev->mode == EM28XX_ANALOG_MODE) {
840 if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) { 666 const struct em28xx_led *led;
841 dev->alt = i; 667 led = em28xx_find_led(dev, EM28XX_LED_ANALOG_CAPTURING);
842 break; 668 if (led)
843 /* otherwise make sure that we end up with the maximum bandwidth 669 em28xx_write_reg_bits(dev, led->gpio_reg,
844 because the min_pkt_size equation might be wrong... 670 (!start ^ led->inverted) ?
845 */ 671 ~led->gpio_mask : led->gpio_mask,
846 } else if (dev->alt_max_pkt_size_isoc[i] > 672 led->gpio_mask);
847 dev->alt_max_pkt_size_isoc[dev->alt])
848 dev->alt = i;
849 } 673 }
850 674
851set_alt: 675 return rc;
852 /* NOTE: for bulk transfers, we need to call usb_set_interface()
853 * even if the previous settings were the same. Otherwise streaming
854 * fails with all urbs having status = -EOVERFLOW ! */
855 if (dev->analog_xfer_bulk) {
856 dev->max_pkt_size = 512; /* USB 2.0 spec */
857 dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
858 } else { /* isoc */
859 em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
860 min_pkt_size, dev->alt);
861 dev->max_pkt_size =
862 dev->alt_max_pkt_size_isoc[dev->alt];
863 dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS;
864 }
865 em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
866 dev->alt, dev->max_pkt_size);
867 errCode = usb_set_interface(dev->udev, 0, dev->alt);
868 if (errCode < 0) {
869 em28xx_errdev("cannot change alternate number to %d (error=%i)\n",
870 dev->alt, errCode);
871 return errCode;
872 }
873 return 0;
874} 676}
875 677
876int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) 678int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
@@ -1238,18 +1040,6 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode,
1238EXPORT_SYMBOL_GPL(em28xx_init_usb_xfer); 1040EXPORT_SYMBOL_GPL(em28xx_init_usb_xfer);
1239 1041
1240/* 1042/*
1241 * em28xx_wake_i2c()
1242 * configure i2c attached devices
1243 */
1244void em28xx_wake_i2c(struct em28xx *dev)
1245{
1246 v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
1247 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
1248 INPUT(dev->ctl_input)->vmux, 0, 0);
1249 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
1250}
1251
1252/*
1253 * Device control list 1043 * Device control list
1254 */ 1044 */
1255 1045
@@ -1272,7 +1062,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
1272 ops->init(dev); 1062 ops->init(dev);
1273 } 1063 }
1274 mutex_unlock(&em28xx_devlist_mutex); 1064 mutex_unlock(&em28xx_devlist_mutex);
1275 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); 1065 printk(KERN_INFO "em28xx: Registered (%s) extension\n", ops->name);
1276 return 0; 1066 return 0;
1277} 1067}
1278EXPORT_SYMBOL(em28xx_register_extension); 1068EXPORT_SYMBOL(em28xx_register_extension);
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 344042bb845c..a0a669e81362 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -51,10 +51,14 @@
51#include "a8293.h" 51#include "a8293.h"
52#include "qt1010.h" 52#include "qt1010.h"
53#include "mb86a20s.h" 53#include "mb86a20s.h"
54#include "m88ds3103.h"
55#include "m88ts2022.h"
54 56
55MODULE_DESCRIPTION("driver for em28xx based DVB cards");
56MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 57MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
57MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
59MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface");
60MODULE_VERSION(EM28XX_VERSION);
61
58 62
59static unsigned int debug; 63static unsigned int debug;
60module_param(debug, int, 0644); 64module_param(debug, int, 0644);
@@ -87,6 +91,7 @@ struct em28xx_dvb {
87 struct semaphore pll_mutex; 91 struct semaphore pll_mutex;
88 bool dont_attach_fe1; 92 bool dont_attach_fe1;
89 int lna_gpio; 93 int lna_gpio;
94 struct i2c_client *i2c_client_tuner;
90}; 95};
91 96
92 97
@@ -198,7 +203,7 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb)
198 dvb_alt = dev->dvb_alt_isoc; 203 dvb_alt = dev->dvb_alt_isoc;
199 } 204 }
200 205
201 usb_set_interface(dev->udev, 0, dvb_alt); 206 usb_set_interface(dev->udev, dev->ifnum, dvb_alt);
202 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 207 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
203 if (rc < 0) 208 if (rc < 0)
204 return rc; 209 return rc;
@@ -271,7 +276,7 @@ static int em28xx_stop_feed(struct dvb_demux_feed *feed)
271static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) 276static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
272{ 277{
273 struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv; 278 struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv;
274 struct em28xx *dev = i2c_bus->dev; 279 struct em28xx *dev = i2c_bus->dev;
275 280
276 if (acquire) 281 if (acquire)
277 return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 282 return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
@@ -370,7 +375,6 @@ static struct drxk_config terratec_h5_drxk = {
370 .no_i2c_bridge = 1, 375 .no_i2c_bridge = 1,
371 .microcode_name = "dvb-usb-terratec-h5-drxk.fw", 376 .microcode_name = "dvb-usb-terratec-h5-drxk.fw",
372 .qam_demod_parameter_count = 2, 377 .qam_demod_parameter_count = 2,
373 .load_firmware_sync = true,
374}; 378};
375 379
376static struct drxk_config hauppauge_930c_drxk = { 380static struct drxk_config hauppauge_930c_drxk = {
@@ -380,7 +384,6 @@ static struct drxk_config hauppauge_930c_drxk = {
380 .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", 384 .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
381 .chunk_size = 56, 385 .chunk_size = 56,
382 .qam_demod_parameter_count = 2, 386 .qam_demod_parameter_count = 2,
383 .load_firmware_sync = true,
384}; 387};
385 388
386static struct drxk_config terratec_htc_stick_drxk = { 389static struct drxk_config terratec_htc_stick_drxk = {
@@ -394,7 +397,6 @@ static struct drxk_config terratec_htc_stick_drxk = {
394 .antenna_dvbt = true, 397 .antenna_dvbt = true,
395 /* The windows driver uses the same. This will disable LNA. */ 398 /* The windows driver uses the same. This will disable LNA. */
396 .antenna_gpio = 0x6, 399 .antenna_gpio = 0x6,
397 .load_firmware_sync = true,
398}; 400};
399 401
400static struct drxk_config maxmedia_ub425_tc_drxk = { 402static struct drxk_config maxmedia_ub425_tc_drxk = {
@@ -403,7 +405,6 @@ static struct drxk_config maxmedia_ub425_tc_drxk = {
403 .no_i2c_bridge = 1, 405 .no_i2c_bridge = 1,
404 .microcode_name = "dvb-demod-drxk-01.fw", 406 .microcode_name = "dvb-demod-drxk-01.fw",
405 .chunk_size = 62, 407 .chunk_size = 62,
406 .load_firmware_sync = true,
407 .qam_demod_parameter_count = 2, 408 .qam_demod_parameter_count = 2,
408}; 409};
409 410
@@ -415,7 +416,6 @@ static struct drxk_config pctv_520e_drxk = {
415 .chunk_size = 58, 416 .chunk_size = 58,
416 .antenna_dvbt = true, /* disable LNA */ 417 .antenna_dvbt = true, /* disable LNA */
417 .antenna_gpio = (1 << 2), /* disable LNA */ 418 .antenna_gpio = (1 << 2), /* disable LNA */
418 .load_firmware_sync = true,
419}; 419};
420 420
421static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 421static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
@@ -808,6 +808,14 @@ static struct tda18271_config c3tech_duo_tda18271_config = {
808 .small_i2c = TDA18271_03_BYTE_CHUNK_INIT, 808 .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
809}; 809};
810 810
811static const struct m88ds3103_config pctv_461e_m88ds3103_config = {
812 .i2c_addr = 0x68,
813 .clock = 27000000,
814 .i2c_wr_max = 33,
815 .clock_out = 0,
816 .ts_mode = M88DS3103_TS_PARALLEL_16,
817 .agc = 0x99,
818};
811 819
812/* ------------------------------------------------------------------ */ 820/* ------------------------------------------------------------------ */
813 821
@@ -815,11 +823,16 @@ static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
815{ 823{
816 struct dvb_frontend *fe; 824 struct dvb_frontend *fe;
817 struct xc2028_config cfg; 825 struct xc2028_config cfg;
826 struct xc2028_ctrl ctl;
818 827
819 memset(&cfg, 0, sizeof(cfg)); 828 memset(&cfg, 0, sizeof(cfg));
820 cfg.i2c_adap = &dev->i2c_adap[dev->def_i2c_bus]; 829 cfg.i2c_adap = &dev->i2c_adap[dev->def_i2c_bus];
821 cfg.i2c_addr = addr; 830 cfg.i2c_addr = addr;
822 831
832 memset(&ctl, 0, sizeof(ctl));
833 em28xx_setup_xc3028(dev, &ctl);
834 cfg.ctrl = &ctl;
835
823 if (!dev->dvb->fe[0]) { 836 if (!dev->dvb->fe[0]) {
824 em28xx_errdev("/2: dvb frontend not attached. " 837 em28xx_errdev("/2: dvb frontend not attached. "
825 "Can't attach xc3028\n"); 838 "Can't attach xc3028\n");
@@ -979,12 +992,18 @@ static int em28xx_dvb_init(struct em28xx *dev)
979 int result = 0, mfe_shared = 0; 992 int result = 0, mfe_shared = 0;
980 struct em28xx_dvb *dvb; 993 struct em28xx_dvb *dvb;
981 994
995 if (dev->is_audio_only) {
996 /* Shouldn't initialize IR for this interface */
997 return 0;
998 }
999
982 if (!dev->board.has_dvb) { 1000 if (!dev->board.has_dvb) {
983 /* This device does not support the extension */ 1001 /* This device does not support the extension */
984 printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n");
985 return 0; 1002 return 0;
986 } 1003 }
987 1004
1005 em28xx_info("Binding DVB extension\n");
1006
988 dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); 1007 dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
989 1008
990 if (dvb == NULL) { 1009 if (dvb == NULL) {
@@ -994,6 +1013,27 @@ static int em28xx_dvb_init(struct em28xx *dev)
994 dev->dvb = dvb; 1013 dev->dvb = dvb;
995 dvb->fe[0] = dvb->fe[1] = NULL; 1014 dvb->fe[0] = dvb->fe[1] = NULL;
996 1015
1016 /* pre-allocate DVB usb transfer buffers */
1017 if (dev->dvb_xfer_bulk) {
1018 result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
1019 dev->dvb_xfer_bulk,
1020 EM28XX_DVB_NUM_BUFS,
1021 512,
1022 EM28XX_DVB_BULK_PACKET_MULTIPLIER);
1023 } else {
1024 result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
1025 dev->dvb_xfer_bulk,
1026 EM28XX_DVB_NUM_BUFS,
1027 dev->dvb_max_pkt_size_isoc,
1028 EM28XX_DVB_NUM_ISOC_PACKETS);
1029 }
1030 if (result) {
1031 em28xx_errdev("em28xx_dvb: failed to pre-allocate USB transfer buffers for DVB.\n");
1032 kfree(dvb);
1033 dev->dvb = NULL;
1034 return result;
1035 }
1036
997 mutex_lock(&dev->lock); 1037 mutex_lock(&dev->lock);
998 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 1038 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
999 /* init frontend */ 1039 /* init frontend */
@@ -1330,6 +1370,48 @@ static int em28xx_dvb_init(struct em28xx *dev)
1330 goto out_free; 1370 goto out_free;
1331 } 1371 }
1332 break; 1372 break;
1373 case EM28178_BOARD_PCTV_461E:
1374 {
1375 /* demod I2C adapter */
1376 struct i2c_adapter *i2c_adapter;
1377 struct i2c_board_info info;
1378 struct m88ts2022_config m88ts2022_config = {
1379 .clock = 27000000,
1380 };
1381 memset(&info, 0, sizeof(struct i2c_board_info));
1382
1383 /* attach demod */
1384 dvb->fe[0] = dvb_attach(m88ds3103_attach,
1385 &pctv_461e_m88ds3103_config,
1386 &dev->i2c_adap[dev->def_i2c_bus],
1387 &i2c_adapter);
1388 if (dvb->fe[0] == NULL) {
1389 result = -ENODEV;
1390 goto out_free;
1391 }
1392
1393 /* attach tuner */
1394 m88ts2022_config.fe = dvb->fe[0];
1395 strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
1396 info.addr = 0x60;
1397 info.platform_data = &m88ts2022_config;
1398 request_module("m88ts2022");
1399 dvb->i2c_client_tuner = i2c_new_device(i2c_adapter, &info);
1400
1401 /* delegate signal strength measurement to tuner */
1402 dvb->fe[0]->ops.read_signal_strength =
1403 dvb->fe[0]->ops.tuner_ops.get_rf_strength;
1404
1405 /* attach SEC */
1406 if (!dvb_attach(a8293_attach, dvb->fe[0],
1407 &dev->i2c_adap[dev->def_i2c_bus],
1408 &em28xx_a8293_config)) {
1409 dvb_frontend_detach(dvb->fe[0]);
1410 result = -ENODEV;
1411 goto out_free;
1412 }
1413 }
1414 break;
1333 default: 1415 default:
1334 em28xx_errdev("/2: The frontend of your DVB/ATSC card" 1416 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
1335 " isn't supported yet\n"); 1417 " isn't supported yet\n");
@@ -1354,7 +1436,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
1354 /* MFE lock */ 1436 /* MFE lock */
1355 dvb->adapter.mfe_shared = mfe_shared; 1437 dvb->adapter.mfe_shared = mfe_shared;
1356 1438
1357 em28xx_info("Successfully loaded em28xx-dvb\n"); 1439 em28xx_info("DVB extension successfully initialized\n");
1358ret: 1440ret:
1359 em28xx_set_mode(dev, EM28XX_SUSPEND); 1441 em28xx_set_mode(dev, EM28XX_SUSPEND);
1360 mutex_unlock(&dev->lock); 1442 mutex_unlock(&dev->lock);
@@ -1375,14 +1457,23 @@ static inline void prevent_sleep(struct dvb_frontend_ops *ops)
1375 1457
1376static int em28xx_dvb_fini(struct em28xx *dev) 1458static int em28xx_dvb_fini(struct em28xx *dev)
1377{ 1459{
1460 if (dev->is_audio_only) {
1461 /* Shouldn't initialize IR for this interface */
1462 return 0;
1463 }
1464
1378 if (!dev->board.has_dvb) { 1465 if (!dev->board.has_dvb) {
1379 /* This device does not support the extension */ 1466 /* This device does not support the extension */
1380 return 0; 1467 return 0;
1381 } 1468 }
1382 1469
1470 em28xx_info("Closing DVB extension");
1471
1383 if (dev->dvb) { 1472 if (dev->dvb) {
1384 struct em28xx_dvb *dvb = dev->dvb; 1473 struct em28xx_dvb *dvb = dev->dvb;
1385 1474
1475 em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
1476
1386 if (dev->disconnected) { 1477 if (dev->disconnected) {
1387 /* We cannot tell the device to sleep 1478 /* We cannot tell the device to sleep
1388 * once it has been unplugged. */ 1479 * once it has been unplugged. */
@@ -1392,6 +1483,7 @@ static int em28xx_dvb_fini(struct em28xx *dev)
1392 prevent_sleep(&dvb->fe[1]->ops); 1483 prevent_sleep(&dvb->fe[1]->ops);
1393 } 1484 }
1394 1485
1486 i2c_release_client(dvb->i2c_client_tuner);
1395 em28xx_unregister_dvb(dvb); 1487 em28xx_unregister_dvb(dvb);
1396 kfree(dvb); 1488 kfree(dvb);
1397 dev->dvb = NULL; 1489 dev->dvb = NULL;
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index c4ff9739a7ae..7e1724076ac4 100644
--- a/drivers/media/usb/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/usb.h> 27#include <linux/usb.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/jiffies.h>
29 30
30#include "em28xx.h" 31#include "em28xx.h"
31#include "tuner-xc2028.h" 32#include "tuner-xc2028.h"
@@ -40,7 +41,7 @@ MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
40 41
41static unsigned int i2c_debug; 42static unsigned int i2c_debug;
42module_param(i2c_debug, int, 0644); 43module_param(i2c_debug, int, 0644);
43MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 44MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)");
44 45
45/* 46/*
46 * em2800_i2c_send_bytes() 47 * em2800_i2c_send_bytes()
@@ -48,8 +49,8 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
48 */ 49 */
49static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) 50static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
50{ 51{
52 unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT);
51 int ret; 53 int ret;
52 int write_timeout;
53 u8 b2[6]; 54 u8 b2[6];
54 55
55 if (len < 1 || len > 4) 56 if (len < 1 || len > 4)
@@ -74,22 +75,26 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
74 return (ret < 0) ? ret : -EIO; 75 return (ret < 0) ? ret : -EIO;
75 } 76 }
76 /* wait for completion */ 77 /* wait for completion */
77 for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; 78 while (time_is_after_jiffies(timeout)) {
78 write_timeout -= 5) {
79 ret = dev->em28xx_read_reg(dev, 0x05); 79 ret = dev->em28xx_read_reg(dev, 0x05);
80 if (ret == 0x80 + len - 1) { 80 if (ret == 0x80 + len - 1)
81 return len; 81 return len;
82 } else if (ret == 0x94 + len - 1) { 82 if (ret == 0x94 + len - 1) {
83 return -ENODEV; 83 if (i2c_debug == 1)
84 } else if (ret < 0) { 84 em28xx_warn("R05 returned 0x%02x: I2C timeout",
85 ret);
86 return -ENXIO;
87 }
88 if (ret < 0) {
85 em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", 89 em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
86 ret); 90 ret);
87 return ret; 91 return ret;
88 } 92 }
89 msleep(5); 93 msleep(5);
90 } 94 }
91 em28xx_warn("write to i2c device at 0x%x timed out\n", addr); 95 if (i2c_debug)
92 return -EIO; 96 em28xx_warn("write to i2c device at 0x%x timed out\n", addr);
97 return -ETIMEDOUT;
93} 98}
94 99
95/* 100/*
@@ -98,9 +103,9 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
98 */ 103 */
99static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) 104static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
100{ 105{
106 unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT);
101 u8 buf2[4]; 107 u8 buf2[4];
102 int ret; 108 int ret;
103 int read_timeout;
104 int i; 109 int i;
105 110
106 if (len < 1 || len > 4) 111 if (len < 1 || len > 4)
@@ -117,22 +122,28 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
117 } 122 }
118 123
119 /* wait for completion */ 124 /* wait for completion */
120 for (read_timeout = EM2800_I2C_XFER_TIMEOUT; read_timeout > 0; 125 while (time_is_after_jiffies(timeout)) {
121 read_timeout -= 5) {
122 ret = dev->em28xx_read_reg(dev, 0x05); 126 ret = dev->em28xx_read_reg(dev, 0x05);
123 if (ret == 0x84 + len - 1) { 127 if (ret == 0x84 + len - 1)
124 break; 128 break;
125 } else if (ret == 0x94 + len - 1) { 129 if (ret == 0x94 + len - 1) {
126 return -ENODEV; 130 if (i2c_debug == 1)
127 } else if (ret < 0) { 131 em28xx_warn("R05 returned 0x%02x: I2C timeout",
132 ret);
133 return -ENXIO;
134 }
135 if (ret < 0) {
128 em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", 136 em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
129 ret); 137 ret);
130 return ret; 138 return ret;
131 } 139 }
132 msleep(5); 140 msleep(5);
133 } 141 }
134 if (ret != 0x84 + len - 1) 142 if (ret != 0x84 + len - 1) {
135 em28xx_warn("read from i2c device at 0x%x timed out\n", addr); 143 if (i2c_debug)
144 em28xx_warn("read from i2c device at 0x%x timed out\n",
145 addr);
146 }
136 147
137 /* get the received message */ 148 /* get the received message */
138 ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); 149 ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len);
@@ -168,7 +179,8 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr)
168static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, 179static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
169 u16 len, int stop) 180 u16 len, int stop)
170{ 181{
171 int write_timeout, ret; 182 unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT);
183 int ret;
172 184
173 if (len < 1 || len > 64) 185 if (len < 1 || len > 64)
174 return -EOPNOTSUPP; 186 return -EOPNOTSUPP;
@@ -191,16 +203,19 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
191 } 203 }
192 } 204 }
193 205
194 /* Check success of the i2c operation */ 206 /* wait for completion */
195 for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; 207 while (time_is_after_jiffies(timeout)) {
196 write_timeout -= 5) {
197 ret = dev->em28xx_read_reg(dev, 0x05); 208 ret = dev->em28xx_read_reg(dev, 0x05);
198 if (ret == 0) { /* success */ 209 if (ret == 0) /* success */
199 return len; 210 return len;
200 } else if (ret == 0x10) { 211 if (ret == 0x10) {
201 return -ENODEV; 212 if (i2c_debug == 1)
202 } else if (ret < 0) { 213 em28xx_warn("I2C transfer timeout on writing to addr 0x%02x",
203 em28xx_warn("failed to read i2c transfer status from bridge (error=%i)\n", 214 addr);
215 return -ENXIO;
216 }
217 if (ret < 0) {
218 em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
204 ret); 219 ret);
205 return ret; 220 return ret;
206 } 221 }
@@ -211,8 +226,10 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
211 * (even with high payload) ... 226 * (even with high payload) ...
212 */ 227 */
213 } 228 }
214 em28xx_warn("write to i2c device at 0x%x timed out\n", addr); 229 if (i2c_debug)
215 return -EIO; 230 em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n",
231 addr, ret);
232 return -ETIMEDOUT;
216} 233}
217 234
218/* 235/*
@@ -242,26 +259,28 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
242 * bytes if we are on bus B AND there was no write attempt to the 259 * bytes if we are on bus B AND there was no write attempt to the
243 * specified slave address before AND no device is present at the 260 * specified slave address before AND no device is present at the
244 * requested slave address. 261 * requested slave address.
245 * Anyway, the next check will fail with -ENODEV in this case, so avoid 262 * Anyway, the next check will fail with -ENXIO in this case, so avoid
246 * spamming the system log on device probing and do nothing here. 263 * spamming the system log on device probing and do nothing here.
247 */ 264 */
248 265
249 /* Check success of the i2c operation */ 266 /* Check success of the i2c operation */
250 ret = dev->em28xx_read_reg(dev, 0x05); 267 ret = dev->em28xx_read_reg(dev, 0x05);
268 if (ret == 0) /* success */
269 return len;
251 if (ret < 0) { 270 if (ret < 0) {
252 em28xx_warn("failed to read i2c transfer status from bridge (error=%i)\n", 271 em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
253 ret); 272 ret);
254 return ret; 273 return ret;
255 } 274 }
256 if (ret > 0) { 275 if (ret == 0x10) {
257 if (ret == 0x10) { 276 if (i2c_debug == 1)
258 return -ENODEV; 277 em28xx_warn("I2C transfer timeout on writing to addr 0x%02x",
259 } else { 278 addr);
260 em28xx_warn("unknown i2c error (status=%i)\n", ret); 279 return -ENXIO;
261 return -EIO;
262 }
263 } 280 }
264 return len; 281
282 em28xx_warn("unknown i2c error (status=%i)\n", ret);
283 return -ETIMEDOUT;
265} 284}
266 285
267/* 286/*
@@ -316,8 +335,12 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
316 */ 335 */
317 if (!ret) 336 if (!ret)
318 return len; 337 return len;
319 else if (ret > 0) 338 else if (ret > 0) {
320 return -ENODEV; 339 if (i2c_debug == 1)
340 em28xx_warn("Bus B R08 returned 0x%02x: I2C timeout",
341 ret);
342 return -ENXIO;
343 }
321 344
322 return ret; 345 return ret;
323 /* 346 /*
@@ -355,7 +378,7 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
355 * bytes if we are on bus B AND there was no write attempt to the 378 * bytes if we are on bus B AND there was no write attempt to the
356 * specified slave address before AND no device is present at the 379 * specified slave address before AND no device is present at the
357 * requested slave address. 380 * requested slave address.
358 * Anyway, the next check will fail with -ENODEV in this case, so avoid 381 * Anyway, the next check will fail with -ENXIO in this case, so avoid
359 * spamming the system log on device probing and do nothing here. 382 * spamming the system log on device probing and do nothing here.
360 */ 383 */
361 384
@@ -367,8 +390,12 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
367 */ 390 */
368 if (!ret) 391 if (!ret)
369 return len; 392 return len;
370 else if (ret > 0) 393 else if (ret > 0) {
371 return -ENODEV; 394 if (i2c_debug == 1)
395 em28xx_warn("Bus B R08 returned 0x%02x: I2C timeout",
396 ret);
397 return -ENXIO;
398 }
372 399
373 return ret; 400 return ret;
374 /* 401 /*
@@ -409,10 +436,6 @@ static inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr)
409 rc = em2800_i2c_check_for_device(dev, addr); 436 rc = em2800_i2c_check_for_device(dev, addr);
410 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 437 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
411 rc = em25xx_bus_B_check_for_device(dev, addr); 438 rc = em25xx_bus_B_check_for_device(dev, addr);
412 if (rc == -ENODEV) {
413 if (i2c_debug)
414 printk(" no device\n");
415 }
416 return rc; 439 return rc;
417} 440}
418 441
@@ -421,7 +444,7 @@ static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus,
421{ 444{
422 struct em28xx *dev = i2c_bus->dev; 445 struct em28xx *dev = i2c_bus->dev;
423 u16 addr = msg.addr << 1; 446 u16 addr = msg.addr << 1;
424 int byte, rc = -EOPNOTSUPP; 447 int rc = -EOPNOTSUPP;
425 448
426 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 449 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
427 rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len); 450 rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
@@ -429,10 +452,6 @@ static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus,
429 rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len); 452 rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
430 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 453 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
431 rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len); 454 rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len);
432 if (i2c_debug) {
433 for (byte = 0; byte < msg.len; byte++)
434 printk(" %02x", msg.buf[byte]);
435 }
436 return rc; 455 return rc;
437} 456}
438 457
@@ -441,12 +460,8 @@ static inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus,
441{ 460{
442 struct em28xx *dev = i2c_bus->dev; 461 struct em28xx *dev = i2c_bus->dev;
443 u16 addr = msg.addr << 1; 462 u16 addr = msg.addr << 1;
444 int byte, rc = -EOPNOTSUPP; 463 int rc = -EOPNOTSUPP;
445 464
446 if (i2c_debug) {
447 for (byte = 0; byte < msg.len; byte++)
448 printk(" %02x", msg.buf[byte]);
449 }
450 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 465 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
451 rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop); 466 rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop);
452 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 467 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
@@ -491,33 +506,53 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
491 } 506 }
492 for (i = 0; i < num; i++) { 507 for (i = 0; i < num; i++) {
493 addr = msgs[i].addr << 1; 508 addr = msgs[i].addr << 1;
494 if (i2c_debug) 509 if (i2c_debug > 1)
495 printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", 510 printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:",
496 dev->name, __func__ , 511 dev->name, __func__ ,
497 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 512 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
498 i == num - 1 ? "stop" : "nonstop", 513 i == num - 1 ? "stop" : "nonstop",
499 addr, msgs[i].len); 514 addr, msgs[i].len);
500 if (!msgs[i].len) { /* no len: check only for device presence */ 515 if (!msgs[i].len) {
516 /*
517 * no len: check only for device presence
518 * This code is only called during device probe.
519 */
501 rc = i2c_check_for_device(i2c_bus, addr); 520 rc = i2c_check_for_device(i2c_bus, addr);
502 if (rc == -ENODEV) { 521 if (rc < 0) {
522 if (rc == -ENXIO) {
523 if (i2c_debug > 1)
524 printk(KERN_CONT " no device\n");
525 rc = -ENODEV;
526 } else {
527 if (i2c_debug > 1)
528 printk(KERN_CONT " ERROR: %i\n", rc);
529 }
503 rt_mutex_unlock(&dev->i2c_bus_lock); 530 rt_mutex_unlock(&dev->i2c_bus_lock);
504 return rc; 531 return rc;
505 } 532 }
506 } else if (msgs[i].flags & I2C_M_RD) { 533 } else if (msgs[i].flags & I2C_M_RD) {
507 /* read bytes */ 534 /* read bytes */
508 rc = i2c_recv_bytes(i2c_bus, msgs[i]); 535 rc = i2c_recv_bytes(i2c_bus, msgs[i]);
536
537 if (i2c_debug > 1 && rc >= 0)
538 printk(KERN_CONT " %*ph",
539 msgs[i].len, msgs[i].buf);
509 } else { 540 } else {
541 if (i2c_debug > 1)
542 printk(KERN_CONT " %*ph",
543 msgs[i].len, msgs[i].buf);
544
510 /* write bytes */ 545 /* write bytes */
511 rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1); 546 rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1);
512 } 547 }
513 if (rc < 0) { 548 if (rc < 0) {
514 if (i2c_debug) 549 if (i2c_debug > 1)
515 printk(" ERROR: %i\n", rc); 550 printk(KERN_CONT " ERROR: %i\n", rc);
516 rt_mutex_unlock(&dev->i2c_bus_lock); 551 rt_mutex_unlock(&dev->i2c_bus_lock);
517 return rc; 552 return rc;
518 } 553 }
519 if (i2c_debug) 554 if (i2c_debug > 1)
520 printk("\n"); 555 printk(KERN_CONT "\n");
521 } 556 }
522 557
523 rt_mutex_unlock(&dev->i2c_bus_lock); 558 rt_mutex_unlock(&dev->i2c_bus_lock);
@@ -600,7 +635,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus,
600 * calculation and returned device dataset. Simplifies the code a lot, 635 * calculation and returned device dataset. Simplifies the code a lot,
601 * but we might have to deal with multiple sizes in the future ! 636 * but we might have to deal with multiple sizes in the future !
602 */ 637 */
603 int i, err; 638 int err;
604 struct em28xx_eeprom *dev_config; 639 struct em28xx_eeprom *dev_config;
605 u8 buf, *data; 640 u8 buf, *data;
606 641
@@ -631,20 +666,14 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus,
631 goto error; 666 goto error;
632 } 667 }
633 668
634 /* Display eeprom content */ 669 if (i2c_debug) {
635 for (i = 0; i < len; i++) { 670 /* Display eeprom content */
636 if (0 == (i % 16)) { 671 print_hex_dump(KERN_INFO, "eeprom ", DUMP_PREFIX_OFFSET,
637 if (dev->eeprom_addrwidth_16bit) 672 16, 1, data, len, true);
638 em28xx_info("i2c eeprom %04x:", i); 673
639 else 674 if (dev->eeprom_addrwidth_16bit)
640 em28xx_info("i2c eeprom %02x:", i); 675 em28xx_info("eeprom %06x: ... (skipped)\n", 256);
641 }
642 printk(" %02x", data[i]);
643 if (15 == (i % 16))
644 printk("\n");
645 } 676 }
646 if (dev->eeprom_addrwidth_16bit)
647 em28xx_info("i2c eeprom %04x: ... (skipped)\n", i);
648 677
649 if (dev->eeprom_addrwidth_16bit && 678 if (dev->eeprom_addrwidth_16bit &&
650 data[0] == 0x26 && data[3] == 0x00) { 679 data[0] == 0x26 && data[3] == 0x00) {
@@ -736,10 +765,16 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus,
736 em28xx_info("\tAC97 audio (5 sample rates)\n"); 765 em28xx_info("\tAC97 audio (5 sample rates)\n");
737 break; 766 break;
738 case 2: 767 case 2:
739 em28xx_info("\tI2S audio, sample rate=32k\n"); 768 if (dev->chip_id < CHIP_ID_EM2860)
769 em28xx_info("\tI2S audio, sample rate=32k\n");
770 else
771 em28xx_info("\tI2S audio, 3 sample rates\n");
740 break; 772 break;
741 case 3: 773 case 3:
742 em28xx_info("\tI2S audio, 3 sample rates\n"); 774 if (dev->chip_id < CHIP_ID_EM2860)
775 em28xx_info("\tI2S audio, 3 sample rates\n");
776 else
777 em28xx_info("\tI2S audio, 5 sample rates\n");
743 break; 778 break;
744 } 779 }
745 780
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index ea181e4b68c5..18f65d89d4bc 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -30,8 +30,9 @@
30 30
31#include "em28xx.h" 31#include "em28xx.h"
32 32
33#define EM28XX_SNAPSHOT_KEY KEY_CAMERA 33#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
34#define EM28XX_SBUTTON_QUERY_INTERVAL 500 34#define EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL 500 /* [ms] */
35#define EM28XX_BUTTONS_VOLATILE_QUERY_INTERVAL 100 /* [ms] */
35 36
36static unsigned int ir_debug; 37static unsigned int ir_debug;
37module_param(ir_debug, int, 0644); 38module_param(ir_debug, int, 0644);
@@ -442,6 +443,7 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
442 case CHIP_ID_EM2884: 443 case CHIP_ID_EM2884:
443 case CHIP_ID_EM2874: 444 case CHIP_ID_EM2874:
444 case CHIP_ID_EM28174: 445 case CHIP_ID_EM28174:
446 case CHIP_ID_EM28178:
445 return em2874_ir_change_protocol(rc_dev, rc_type); 447 return em2874_ir_change_protocol(rc_dev, rc_type);
446 default: 448 default:
447 printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", 449 printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n",
@@ -470,54 +472,98 @@ static int em28xx_probe_i2c_ir(struct em28xx *dev)
470} 472}
471 473
472/********************************************************** 474/**********************************************************
473 Handle Webcam snapshot button 475 Handle buttons
474 **********************************************************/ 476 **********************************************************/
475 477
476static void em28xx_query_sbutton(struct work_struct *work) 478static void em28xx_query_buttons(struct work_struct *work)
477{ 479{
478 /* Poll the register and see if the button is depressed */
479 struct em28xx *dev = 480 struct em28xx *dev =
480 container_of(work, struct em28xx, sbutton_query_work.work); 481 container_of(work, struct em28xx, buttons_query_work.work);
481 int ret; 482 u8 i, j;
482 483 int regval;
483 ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP); 484 bool is_pressed, was_pressed;
484 485 const struct em28xx_led *led;
485 if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) { 486
486 u8 cleared; 487 /* Poll and evaluate all addresses */
487 /* Button is depressed, clear the register */ 488 for (i = 0; i < dev->num_button_polling_addresses; i++) {
488 cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT; 489 /* Read value from register */
489 em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1); 490 regval = em28xx_read_reg(dev, dev->button_polling_addresses[i]);
490 491 if (regval < 0)
491 /* Not emulate the keypress */ 492 continue;
492 input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, 493 /* Check states of the buttons and act */
493 1); 494 j = 0;
494 /* Now unpress the key */ 495 while (dev->board.buttons[j].role >= 0 &&
495 input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, 496 dev->board.buttons[j].role < EM28XX_NUM_BUTTON_ROLES) {
496 0); 497 struct em28xx_button *button = &dev->board.buttons[j];
498 /* Check if button uses the current address */
499 if (button->reg_r != dev->button_polling_addresses[i]) {
500 j++;
501 continue;
502 }
503 /* Determine if button is and was pressed last time */
504 is_pressed = regval & button->mask;
505 was_pressed = dev->button_polling_last_values[i]
506 & button->mask;
507 if (button->inverted) {
508 is_pressed = !is_pressed;
509 was_pressed = !was_pressed;
510 }
511 /* Clear button state (if needed) */
512 if (is_pressed && button->reg_clearing)
513 em28xx_write_reg(dev, button->reg_clearing,
514 (~regval & button->mask)
515 | (regval & ~button->mask));
516 /* Handle button state */
517 if (!is_pressed || was_pressed) {
518 j++;
519 continue;
520 }
521 switch (button->role) {
522 case EM28XX_BUTTON_SNAPSHOT:
523 /* Emulate the keypress */
524 input_report_key(dev->sbutton_input_dev,
525 EM28XX_SNAPSHOT_KEY, 1);
526 /* Unpress the key */
527 input_report_key(dev->sbutton_input_dev,
528 EM28XX_SNAPSHOT_KEY, 0);
529 break;
530 case EM28XX_BUTTON_ILLUMINATION:
531 led = em28xx_find_led(dev,
532 EM28XX_LED_ILLUMINATION);
533 /* Switch illumination LED on/off */
534 if (led)
535 em28xx_toggle_reg_bits(dev,
536 led->gpio_reg,
537 led->gpio_mask);
538 break;
539 default:
540 WARN_ONCE(1, "BUG: unhandled button role.");
541 }
542 /* Next button */
543 j++;
544 }
545 /* Save current value for comparison during the next polling */
546 dev->button_polling_last_values[i] = regval;
497 } 547 }
498
499 /* Schedule next poll */ 548 /* Schedule next poll */
500 schedule_delayed_work(&dev->sbutton_query_work, 549 schedule_delayed_work(&dev->buttons_query_work,
501 msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); 550 msecs_to_jiffies(dev->button_polling_interval));
502} 551}
503 552
504static void em28xx_register_snapshot_button(struct em28xx *dev) 553static int em28xx_register_snapshot_button(struct em28xx *dev)
505{ 554{
506 struct input_dev *input_dev; 555 struct input_dev *input_dev;
507 int err; 556 int err;
508 557
509 em28xx_info("Registering snapshot button...\n"); 558 em28xx_info("Registering snapshot button...\n");
510 input_dev = input_allocate_device(); 559 input_dev = input_allocate_device();
511 if (!input_dev) { 560 if (!input_dev)
512 em28xx_errdev("input_allocate_device failed\n"); 561 return -ENOMEM;
513 return;
514 }
515 562
516 usb_make_path(dev->udev, dev->snapshot_button_path, 563 usb_make_path(dev->udev, dev->snapshot_button_path,
517 sizeof(dev->snapshot_button_path)); 564 sizeof(dev->snapshot_button_path));
518 strlcat(dev->snapshot_button_path, "/sbutton", 565 strlcat(dev->snapshot_button_path, "/sbutton",
519 sizeof(dev->snapshot_button_path)); 566 sizeof(dev->snapshot_button_path));
520 INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);
521 567
522 input_dev->name = "em28xx snapshot button"; 568 input_dev->name = "em28xx snapshot button";
523 input_dev->phys = dev->snapshot_button_path; 569 input_dev->phys = dev->snapshot_button_path;
@@ -535,25 +581,86 @@ static void em28xx_register_snapshot_button(struct em28xx *dev)
535 if (err) { 581 if (err) {
536 em28xx_errdev("input_register_device failed\n"); 582 em28xx_errdev("input_register_device failed\n");
537 input_free_device(input_dev); 583 input_free_device(input_dev);
538 return; 584 return err;
539 } 585 }
540 586
541 dev->sbutton_input_dev = input_dev; 587 dev->sbutton_input_dev = input_dev;
542 schedule_delayed_work(&dev->sbutton_query_work, 588 return 0;
543 msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); 589}
544 return;
545 590
591static void em28xx_init_buttons(struct em28xx *dev)
592{
593 u8 i = 0, j = 0;
594 bool addr_new = 0;
595
596 dev->button_polling_interval = EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL;
597 while (dev->board.buttons[i].role >= 0 &&
598 dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) {
599 struct em28xx_button *button = &dev->board.buttons[i];
600 /* Check if polling address is already on the list */
601 addr_new = 1;
602 for (j = 0; j < dev->num_button_polling_addresses; j++) {
603 if (button->reg_r == dev->button_polling_addresses[j]) {
604 addr_new = 0;
605 break;
606 }
607 }
608 /* Check if max. number of polling addresses is exceeded */
609 if (addr_new && dev->num_button_polling_addresses
610 >= EM28XX_NUM_BUTTON_ADDRESSES_MAX) {
611 WARN_ONCE(1, "BUG: maximum number of button polling addresses exceeded.");
612 goto next_button;
613 }
614 /* Button role specific checks and actions */
615 if (button->role == EM28XX_BUTTON_SNAPSHOT) {
616 /* Register input device */
617 if (em28xx_register_snapshot_button(dev) < 0)
618 goto next_button;
619 } else if (button->role == EM28XX_BUTTON_ILLUMINATION) {
620 /* Check sanity */
621 if (!em28xx_find_led(dev, EM28XX_LED_ILLUMINATION)) {
622 em28xx_errdev("BUG: illumination button defined, but no illumination LED.\n");
623 goto next_button;
624 }
625 }
626 /* Add read address to list of polling addresses */
627 if (addr_new) {
628 unsigned int index = dev->num_button_polling_addresses;
629 dev->button_polling_addresses[index] = button->reg_r;
630 dev->num_button_polling_addresses++;
631 }
632 /* Reduce polling interval if necessary */
633 if (!button->reg_clearing)
634 dev->button_polling_interval =
635 EM28XX_BUTTONS_VOLATILE_QUERY_INTERVAL;
636next_button:
637 /* Next button */
638 i++;
639 }
640
641 /* Start polling */
642 if (dev->num_button_polling_addresses) {
643 memset(dev->button_polling_last_values, 0,
644 EM28XX_NUM_BUTTON_ADDRESSES_MAX);
645 INIT_DELAYED_WORK(&dev->buttons_query_work,
646 em28xx_query_buttons);
647 schedule_delayed_work(&dev->buttons_query_work,
648 msecs_to_jiffies(dev->button_polling_interval));
649 }
546} 650}
547 651
548static void em28xx_deregister_snapshot_button(struct em28xx *dev) 652static void em28xx_shutdown_buttons(struct em28xx *dev)
549{ 653{
654 /* Cancel polling */
655 cancel_delayed_work_sync(&dev->buttons_query_work);
656 /* Clear polling addresses list */
657 dev->num_button_polling_addresses = 0;
658 /* Deregister input devices */
550 if (dev->sbutton_input_dev != NULL) { 659 if (dev->sbutton_input_dev != NULL) {
551 em28xx_info("Deregistering snapshot button\n"); 660 em28xx_info("Deregistering snapshot button\n");
552 cancel_delayed_work_sync(&dev->sbutton_query_work);
553 input_unregister_device(dev->sbutton_input_dev); 661 input_unregister_device(dev->sbutton_input_dev);
554 dev->sbutton_input_dev = NULL; 662 dev->sbutton_input_dev = NULL;
555 } 663 }
556 return;
557} 664}
558 665
559static int em28xx_ir_init(struct em28xx *dev) 666static int em28xx_ir_init(struct em28xx *dev)
@@ -564,8 +671,13 @@ static int em28xx_ir_init(struct em28xx *dev)
564 u64 rc_type; 671 u64 rc_type;
565 u16 i2c_rc_dev_addr = 0; 672 u16 i2c_rc_dev_addr = 0;
566 673
567 if (dev->board.has_snapshot_button) 674 if (dev->is_audio_only) {
568 em28xx_register_snapshot_button(dev); 675 /* Shouldn't initialize IR for this interface */
676 return 0;
677 }
678
679 if (dev->board.buttons)
680 em28xx_init_buttons(dev);
569 681
570 if (dev->board.has_ir_i2c) { 682 if (dev->board.has_ir_i2c) {
571 i2c_rc_dev_addr = em28xx_probe_i2c_ir(dev); 683 i2c_rc_dev_addr = em28xx_probe_i2c_ir(dev);
@@ -583,6 +695,8 @@ static int em28xx_ir_init(struct em28xx *dev)
583 return 0; 695 return 0;
584 } 696 }
585 697
698 em28xx_info("Registering input extension\n");
699
586 ir = kzalloc(sizeof(*ir), GFP_KERNEL); 700 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
587 rc = rc_allocate_device(); 701 rc = rc_allocate_device();
588 if (!ir || !rc) 702 if (!ir || !rc)
@@ -633,6 +747,7 @@ static int em28xx_ir_init(struct em28xx *dev)
633 case CHIP_ID_EM2884: 747 case CHIP_ID_EM2884:
634 case CHIP_ID_EM2874: 748 case CHIP_ID_EM2874:
635 case CHIP_ID_EM28174: 749 case CHIP_ID_EM28174:
750 case CHIP_ID_EM28178:
636 ir->get_key = em2874_polling_getkey; 751 ir->get_key = em2874_polling_getkey;
637 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | 752 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC |
638 RC_BIT_RC6_0; 753 RC_BIT_RC6_0;
@@ -675,6 +790,8 @@ static int em28xx_ir_init(struct em28xx *dev)
675 if (err) 790 if (err)
676 goto error; 791 goto error;
677 792
793 em28xx_info("Input extension successfully initalized\n");
794
678 return 0; 795 return 0;
679 796
680error: 797error:
@@ -688,7 +805,14 @@ static int em28xx_ir_fini(struct em28xx *dev)
688{ 805{
689 struct em28xx_IR *ir = dev->ir; 806 struct em28xx_IR *ir = dev->ir;
690 807
691 em28xx_deregister_snapshot_button(dev); 808 if (dev->is_audio_only) {
809 /* Shouldn't initialize IR for this interface */
810 return 0;
811 }
812
813 em28xx_info("Closing input extension");
814
815 em28xx_shutdown_buttons(dev);
692 816
693 /* skip detach on non attached boards */ 817 /* skip detach on non attached boards */
694 if (!ir) 818 if (!ir)
@@ -722,7 +846,8 @@ static void __exit em28xx_rc_unregister(void)
722 846
723MODULE_LICENSE("GPL"); 847MODULE_LICENSE("GPL");
724MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); 848MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
725MODULE_DESCRIPTION("Em28xx Input driver"); 849MODULE_DESCRIPTION(DRIVER_DESC " - input interface");
850MODULE_VERSION(EM28XX_VERSION);
726 851
727module_init(em28xx_rc_register); 852module_init(em28xx_rc_register);
728module_exit(em28xx_rc_unregister); 853module_exit(em28xx_rc_unregister);
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 0e0477847965..311fb349dafa 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -25,10 +25,12 @@
25#define EM28XX_R00_CHIPCFG 0x00 25#define EM28XX_R00_CHIPCFG 0x00
26 26
27/* em28xx Chip Configuration 0x00 */ 27/* em28xx Chip Configuration 0x00 */
28#define EM28XX_CHIPCFG_VENDOR_AUDIO 0x80 28#define EM2860_CHIPCFG_VENDOR_AUDIO 0x80
29#define EM28XX_CHIPCFG_I2S_VOLUME_CAPABLE 0x40 29#define EM2860_CHIPCFG_I2S_VOLUME_CAPABLE 0x40
30#define EM28XX_CHIPCFG_I2S_5_SAMPRATES 0x30 30#define EM2820_CHIPCFG_I2S_3_SAMPRATES 0x30
31#define EM28XX_CHIPCFG_I2S_3_SAMPRATES 0x20 31#define EM2860_CHIPCFG_I2S_5_SAMPRATES 0x30
32#define EM2820_CHIPCFG_I2S_1_SAMPRATE 0x20
33#define EM2860_CHIPCFG_I2S_3_SAMPRATES 0x20
32#define EM28XX_CHIPCFG_AC97 0x10 34#define EM28XX_CHIPCFG_AC97 0x10
33#define EM28XX_CHIPCFG_AUDIOMASK 0x30 35#define EM28XX_CHIPCFG_AUDIOMASK 0x30
34 36
@@ -245,6 +247,7 @@ enum em28xx_chip_id {
245 CHIP_ID_EM2874 = 65, 247 CHIP_ID_EM2874 = 65,
246 CHIP_ID_EM2884 = 68, 248 CHIP_ID_EM2884 = 68,
247 CHIP_ID_EM28174 = 113, 249 CHIP_ID_EM28174 = 113,
250 CHIP_ID_EM28178 = 114,
248}; 251};
249 252
250/* 253/*
diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h
new file mode 100644
index 000000000000..bce438691e0e
--- /dev/null
+++ b/drivers/media/usb/em28xx/em28xx-v4l.h
@@ -0,0 +1,20 @@
1/*
2 em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB
3 video capture devices
4
5 Copyright (C) 2013-2014 Mauro Carvalho Chehab <m.chehab@samsung.com>
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 version 2 of the License.
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
18int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count);
19int em28xx_stop_vbi_streaming(struct vb2_queue *vq);
20extern struct vb2_ops em28xx_vbi_qops;
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c
index 39f39c527c13..db3d655600df 100644
--- a/drivers/media/usb/em28xx/em28xx-vbi.c
+++ b/drivers/media/usb/em28xx/em28xx-vbi.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28 28
29#include "em28xx.h" 29#include "em28xx.h"
30#include "em28xx-v4l.h"
30 31
31static unsigned int vbibufs = 5; 32static unsigned int vbibufs = 5;
32module_param(vbibufs, int, 0644); 33module_param(vbibufs, int, 0644);
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index dd19c9ff76e0..c3c928937dcd 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -38,9 +38,11 @@
38#include <linux/slab.h> 38#include <linux/slab.h>
39 39
40#include "em28xx.h" 40#include "em28xx.h"
41#include "em28xx-v4l.h"
41#include <media/v4l2-common.h> 42#include <media/v4l2-common.h>
42#include <media/v4l2-ioctl.h> 43#include <media/v4l2-ioctl.h>
43#include <media/v4l2-event.h> 44#include <media/v4l2-event.h>
45#include <media/v4l2-clk.h>
44#include <media/msp3400.h> 46#include <media/msp3400.h>
45#include <media/tuner.h> 47#include <media/tuner.h>
46 48
@@ -49,19 +51,23 @@
49 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ 51 "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
50 "Sascha Sommer <saschasommer@freenet.de>" 52 "Sascha Sommer <saschasommer@freenet.de>"
51 53
52#define DRIVER_DESC "Empia em28xx based USB video device driver" 54static unsigned int isoc_debug;
55module_param(isoc_debug, int, 0644);
56MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
57
58static unsigned int disable_vbi;
59module_param(disable_vbi, int, 0644);
60MODULE_PARM_DESC(disable_vbi, "disable vbi support");
53 61
54#define EM28XX_VERSION "0.2.0" 62static int alt;
63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
55 65
56#define em28xx_videodbg(fmt, arg...) do {\ 66#define em28xx_videodbg(fmt, arg...) do {\
57 if (video_debug) \ 67 if (video_debug) \
58 printk(KERN_INFO "%s %s :"fmt, \ 68 printk(KERN_INFO "%s %s :"fmt, \
59 dev->name, __func__ , ##arg); } while (0) 69 dev->name, __func__ , ##arg); } while (0)
60 70
61static unsigned int isoc_debug;
62module_param(isoc_debug, int, 0644);
63MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
64
65#define em28xx_isocdbg(fmt, arg...) \ 71#define em28xx_isocdbg(fmt, arg...) \
66do {\ 72do {\
67 if (isoc_debug) { \ 73 if (isoc_debug) { \
@@ -71,7 +77,7 @@ do {\
71 } while (0) 77 } while (0)
72 78
73MODULE_AUTHOR(DRIVER_AUTHOR); 79MODULE_AUTHOR(DRIVER_AUTHOR);
74MODULE_DESCRIPTION(DRIVER_DESC); 80MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface");
75MODULE_LICENSE("GPL"); 81MODULE_LICENSE("GPL");
76MODULE_VERSION(EM28XX_VERSION); 82MODULE_VERSION(EM28XX_VERSION);
77 83
@@ -135,6 +141,257 @@ static struct em28xx_fmt format[] = {
135 }, 141 },
136}; 142};
137 143
144static int em28xx_vbi_supported(struct em28xx *dev)
145{
146 /* Modprobe option to manually disable */
147 if (disable_vbi == 1)
148 return 0;
149
150 if (dev->board.is_webcam)
151 return 0;
152
153 /* FIXME: check subdevices for VBI support */
154
155 if (dev->chip_id == CHIP_ID_EM2860 ||
156 dev->chip_id == CHIP_ID_EM2883)
157 return 1;
158
159 /* Version of em28xx that does not support VBI */
160 return 0;
161}
162
163/*
164 * em28xx_wake_i2c()
165 * configure i2c attached devices
166 */
167static void em28xx_wake_i2c(struct em28xx *dev)
168{
169 v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
170 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
171 INPUT(dev->ctl_input)->vmux, 0, 0);
172 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
173}
174
175static int em28xx_colorlevels_set_default(struct em28xx *dev)
176{
177 em28xx_write_reg(dev, EM28XX_R20_YGAIN, CONTRAST_DEFAULT);
178 em28xx_write_reg(dev, EM28XX_R21_YOFFSET, BRIGHTNESS_DEFAULT);
179 em28xx_write_reg(dev, EM28XX_R22_UVGAIN, SATURATION_DEFAULT);
180 em28xx_write_reg(dev, EM28XX_R23_UOFFSET, BLUE_BALANCE_DEFAULT);
181 em28xx_write_reg(dev, EM28XX_R24_VOFFSET, RED_BALANCE_DEFAULT);
182 em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, SHARPNESS_DEFAULT);
183
184 em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
185 em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
186 em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
187 em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
188 em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
189 em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
190 return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
191}
192
193static int em28xx_set_outfmt(struct em28xx *dev)
194{
195 int ret;
196 u8 fmt, vinctrl;
197
198 fmt = dev->format->reg;
199 if (!dev->is_em25xx)
200 fmt |= 0x20;
201 /*
202 * NOTE: it's not clear if this is really needed !
203 * The datasheets say bit 5 is a reserved bit and devices seem to work
204 * fine without it. But the Windows driver sets it for em2710/50+em28xx
205 * devices and we've always been setting it, too.
206 *
207 * em2765 (em25xx, em276x/7x/8x) devices do NOT work with this bit set,
208 * it's likely used for an additional (compressed ?) format there.
209 */
210 ret = em28xx_write_reg(dev, EM28XX_R27_OUTFMT, fmt);
211 if (ret < 0)
212 return ret;
213
214 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode);
215 if (ret < 0)
216 return ret;
217
218 vinctrl = dev->vinctl;
219 if (em28xx_vbi_supported(dev) == 1) {
220 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
221 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
222 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4);
223 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height);
224 if (dev->norm & V4L2_STD_525_60) {
225 /* NTSC */
226 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
227 } else if (dev->norm & V4L2_STD_625_50) {
228 /* PAL */
229 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07);
230 }
231 }
232
233 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
234}
235
236static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
237 u8 ymin, u8 ymax)
238{
239 em28xx_videodbg("em28xx Scale: (%d,%d)-(%d,%d)\n",
240 xmin, ymin, xmax, ymax);
241
242 em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1);
243 em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1);
244 em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1);
245 return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1);
246}
247
248static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
249 u16 width, u16 height)
250{
251 u8 cwidth = width >> 2;
252 u8 cheight = height >> 2;
253 u8 overflow = (height >> 9 & 0x02) | (width >> 10 & 0x01);
254 /* NOTE: size limit: 2047x1023 = 2MPix */
255
256 em28xx_videodbg("capture area set to (%d,%d): %dx%d\n",
257 hstart, vstart,
258 ((overflow & 2) << 9 | cwidth << 2),
259 ((overflow & 1) << 10 | cheight << 2));
260
261 em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1);
262 em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1);
263 em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1);
264 em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1);
265 em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1);
266
267 /* FIXME: function/meaning of these registers ? */
268 /* FIXME: align width+height to multiples of 4 ?! */
269 if (dev->is_em25xx) {
270 em28xx_write_reg(dev, 0x34, width >> 4);
271 em28xx_write_reg(dev, 0x35, height >> 4);
272 }
273}
274
275static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
276{
277 u8 mode;
278 /* the em2800 scaler only supports scaling down to 50% */
279
280 if (dev->board.is_em2800) {
281 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
282 } else {
283 u8 buf[2];
284
285 buf[0] = h;
286 buf[1] = h >> 8;
287 em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2);
288
289 buf[0] = v;
290 buf[1] = v >> 8;
291 em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
292 /* it seems that both H and V scalers must be active
293 to work correctly */
294 mode = (h || v) ? 0x30 : 0x00;
295 }
296 return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
297}
298
299/* FIXME: this only function read values from dev */
300static int em28xx_resolution_set(struct em28xx *dev)
301{
302 int width, height;
303 width = norm_maxw(dev);
304 height = norm_maxh(dev);
305
306 /* Properly setup VBI */
307 dev->vbi_width = 720;
308 if (dev->norm & V4L2_STD_525_60)
309 dev->vbi_height = 12;
310 else
311 dev->vbi_height = 18;
312
313 em28xx_set_outfmt(dev);
314
315 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
316
317 /* If we don't set the start position to 2 in VBI mode, we end up
318 with line 20/21 being YUYV encoded instead of being in 8-bit
319 greyscale. The core of the issue is that line 21 (and line 23 for
320 PAL WSS) are inside of active video region, and as a result they
321 get the pixelformatting associated with that area. So by cropping
322 it out, we end up with the same format as the rest of the VBI
323 region */
324 if (em28xx_vbi_supported(dev) == 1)
325 em28xx_capture_area_set(dev, 0, 2, width, height);
326 else
327 em28xx_capture_area_set(dev, 0, 0, width, height);
328
329 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
330}
331
332/* Set USB alternate setting for analog video */
333static int em28xx_set_alternate(struct em28xx *dev)
334{
335 int errCode;
336 int i;
337 unsigned int min_pkt_size = dev->width * 2 + 4;
338
339 /* NOTE: for isoc transfers, only alt settings > 0 are allowed
340 bulk transfers seem to work only with alt=0 ! */
341 dev->alt = 0;
342 if ((alt > 0) && (alt < dev->num_alt)) {
343 em28xx_videodbg("alternate forced to %d\n", dev->alt);
344 dev->alt = alt;
345 goto set_alt;
346 }
347 if (dev->analog_xfer_bulk)
348 goto set_alt;
349
350 /* When image size is bigger than a certain value,
351 the frame size should be increased, otherwise, only
352 green screen will be received.
353 */
354 if (dev->width * 2 * dev->height > 720 * 240 * 2)
355 min_pkt_size *= 2;
356
357 for (i = 0; i < dev->num_alt; i++) {
358 /* stop when the selected alt setting offers enough bandwidth */
359 if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) {
360 dev->alt = i;
361 break;
362 /* otherwise make sure that we end up with the maximum bandwidth
363 because the min_pkt_size equation might be wrong...
364 */
365 } else if (dev->alt_max_pkt_size_isoc[i] >
366 dev->alt_max_pkt_size_isoc[dev->alt])
367 dev->alt = i;
368 }
369
370set_alt:
371 /* NOTE: for bulk transfers, we need to call usb_set_interface()
372 * even if the previous settings were the same. Otherwise streaming
373 * fails with all urbs having status = -EOVERFLOW ! */
374 if (dev->analog_xfer_bulk) {
375 dev->max_pkt_size = 512; /* USB 2.0 spec */
376 dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
377 } else { /* isoc */
378 em28xx_videodbg("minimum isoc packet size: %u (alt=%d)\n",
379 min_pkt_size, dev->alt);
380 dev->max_pkt_size =
381 dev->alt_max_pkt_size_isoc[dev->alt];
382 dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS;
383 }
384 em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n",
385 dev->alt, dev->max_pkt_size);
386 errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt);
387 if (errCode < 0) {
388 em28xx_errdev("cannot change alternate number to %d (error=%i)\n",
389 dev->alt, errCode);
390 return errCode;
391 }
392 return 0;
393}
394
138/* ------------------------------------------------------------------ 395/* ------------------------------------------------------------------
139 DMA and thread functions 396 DMA and thread functions
140 ------------------------------------------------------------------*/ 397 ------------------------------------------------------------------*/
@@ -763,7 +1020,7 @@ static struct vb2_ops em28xx_video_qops = {
763 .wait_finish = vb2_ops_wait_finish, 1020 .wait_finish = vb2_ops_wait_finish,
764}; 1021};
765 1022
766int em28xx_vb2_setup(struct em28xx *dev) 1023static int em28xx_vb2_setup(struct em28xx *dev)
767{ 1024{
768 int rc; 1025 int rc;
769 struct vb2_queue *q; 1026 struct vb2_queue *q;
@@ -831,7 +1088,7 @@ static void video_mux(struct em28xx *dev, int index)
831 em28xx_audio_analog_set(dev); 1088 em28xx_audio_analog_set(dev);
832} 1089}
833 1090
834void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) 1091static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
835{ 1092{
836 struct em28xx *dev = priv; 1093 struct em28xx *dev = priv;
837 1094
@@ -890,7 +1147,7 @@ static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
890 return (ret < 0) ? ret : 0; 1147 return (ret < 0) ? ret : 0;
891} 1148}
892 1149
893const struct v4l2_ctrl_ops em28xx_ctrl_ops = { 1150static const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
894 .s_ctrl = em28xx_s_ctrl, 1151 .s_ctrl = em28xx_s_ctrl,
895}; 1152};
896 1153
@@ -1368,7 +1625,7 @@ static int vidioc_g_register(struct file *file, void *priv,
1368 reg->val = ret; 1625 reg->val = ret;
1369 } else { 1626 } else {
1370 __le16 val = 0; 1627 __le16 val = 0;
1371 ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, 1628 ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
1372 reg->reg, (char *)&val, 2); 1629 reg->reg, (char *)&val, 2);
1373 if (ret < 0) 1630 if (ret < 0)
1374 return ret; 1631 return ret;
@@ -1570,6 +1827,10 @@ static int em28xx_v4l2_open(struct file *filp)
1570 case VFL_TYPE_VBI: 1827 case VFL_TYPE_VBI:
1571 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; 1828 fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1572 break; 1829 break;
1830 case VFL_TYPE_RADIO:
1831 break;
1832 default:
1833 return -EINVAL;
1573 } 1834 }
1574 1835
1575 em28xx_videodbg("open dev=%s type=%s users=%d\n", 1836 em28xx_videodbg("open dev=%s type=%s users=%d\n",
@@ -1590,15 +1851,17 @@ static int em28xx_v4l2_open(struct file *filp)
1590 fh->type = fh_type; 1851 fh->type = fh_type;
1591 filp->private_data = fh; 1852 filp->private_data = fh;
1592 1853
1593 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { 1854 if (dev->users == 0) {
1594 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 1855 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
1595 em28xx_resolution_set(dev);
1596 1856
1597 /* Needed, since GPIO might have disabled power of 1857 if (vdev->vfl_type != VFL_TYPE_RADIO)
1598 some i2c device 1858 em28xx_resolution_set(dev);
1859
1860 /*
1861 * Needed, since GPIO might have disabled power
1862 * of some i2c devices
1599 */ 1863 */
1600 em28xx_wake_i2c(dev); 1864 em28xx_wake_i2c(dev);
1601
1602 } 1865 }
1603 1866
1604 if (vdev->vfl_type == VFL_TYPE_RADIO) { 1867 if (vdev->vfl_type == VFL_TYPE_RADIO) {
@@ -1615,40 +1878,59 @@ static int em28xx_v4l2_open(struct file *filp)
1615} 1878}
1616 1879
1617/* 1880/*
1618 * em28xx_realease_resources() 1881 * em28xx_v4l2_fini()
1619 * unregisters the v4l2,i2c and usb devices 1882 * unregisters the v4l2,i2c and usb devices
1620 * called when the device gets disconected or at module unload 1883 * called when the device gets disconected or at module unload
1621*/ 1884*/
1622void em28xx_release_analog_resources(struct em28xx *dev) 1885static int em28xx_v4l2_fini(struct em28xx *dev)
1623{ 1886{
1887 if (dev->is_audio_only) {
1888 /* Shouldn't initialize IR for this interface */
1889 return 0;
1890 }
1891
1892 if (!dev->has_video) {
1893 /* This device does not support the v4l2 extension */
1894 return 0;
1895 }
1624 1896
1625 /*FIXME: I2C IR should be disconnected */ 1897 em28xx_info("Closing video extension");
1898
1899 mutex_lock(&dev->lock);
1900
1901 v4l2_device_disconnect(&dev->v4l2_dev);
1902
1903 em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
1626 1904
1627 if (dev->radio_dev) { 1905 if (dev->radio_dev) {
1628 if (video_is_registered(dev->radio_dev)) 1906 em28xx_info("V4L2 device %s deregistered\n",
1629 video_unregister_device(dev->radio_dev); 1907 video_device_node_name(dev->radio_dev));
1630 else 1908 video_unregister_device(dev->radio_dev);
1631 video_device_release(dev->radio_dev);
1632 dev->radio_dev = NULL;
1633 } 1909 }
1634 if (dev->vbi_dev) { 1910 if (dev->vbi_dev) {
1635 em28xx_info("V4L2 device %s deregistered\n", 1911 em28xx_info("V4L2 device %s deregistered\n",
1636 video_device_node_name(dev->vbi_dev)); 1912 video_device_node_name(dev->vbi_dev));
1637 if (video_is_registered(dev->vbi_dev)) 1913 video_unregister_device(dev->vbi_dev);
1638 video_unregister_device(dev->vbi_dev);
1639 else
1640 video_device_release(dev->vbi_dev);
1641 dev->vbi_dev = NULL;
1642 } 1914 }
1643 if (dev->vdev) { 1915 if (dev->vdev) {
1644 em28xx_info("V4L2 device %s deregistered\n", 1916 em28xx_info("V4L2 device %s deregistered\n",
1645 video_device_node_name(dev->vdev)); 1917 video_device_node_name(dev->vdev));
1646 if (video_is_registered(dev->vdev)) 1918 video_unregister_device(dev->vdev);
1647 video_unregister_device(dev->vdev);
1648 else
1649 video_device_release(dev->vdev);
1650 dev->vdev = NULL;
1651 } 1919 }
1920
1921 if (dev->clk) {
1922 v4l2_clk_unregister_fixed(dev->clk);
1923 dev->clk = NULL;
1924 }
1925
1926 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1927 v4l2_device_unregister(&dev->v4l2_dev);
1928
1929 if (dev->users)
1930 em28xx_warn("Device is open ! Memory deallocation is deferred on last close.\n");
1931 mutex_unlock(&dev->lock);
1932
1933 return 0;
1652} 1934}
1653 1935
1654/* 1936/*
@@ -1668,14 +1950,10 @@ static int em28xx_v4l2_close(struct file *filp)
1668 mutex_lock(&dev->lock); 1950 mutex_lock(&dev->lock);
1669 1951
1670 if (dev->users == 1) { 1952 if (dev->users == 1) {
1671 /* the device is already disconnect, 1953 /* free the remaining resources if device is disconnected */
1672 free the remaining resources */
1673 if (dev->disconnected) { 1954 if (dev->disconnected) {
1674 em28xx_release_resources(dev);
1675 kfree(dev->alt_max_pkt_size_isoc); 1955 kfree(dev->alt_max_pkt_size_isoc);
1676 mutex_unlock(&dev->lock); 1956 goto exit;
1677 kfree(dev);
1678 return 0;
1679 } 1957 }
1680 1958
1681 /* Save some power by putting tuner to sleep */ 1959 /* Save some power by putting tuner to sleep */
@@ -1694,11 +1972,29 @@ static int em28xx_v4l2_close(struct file *filp)
1694 } 1972 }
1695 } 1973 }
1696 1974
1975exit:
1697 dev->users--; 1976 dev->users--;
1698 mutex_unlock(&dev->lock); 1977 mutex_unlock(&dev->lock);
1699 return 0; 1978 return 0;
1700} 1979}
1701 1980
1981/*
1982 * em28xx_videodevice_release()
1983 * called when the last user of the video device exits and frees the memeory
1984 */
1985static void em28xx_videodevice_release(struct video_device *vdev)
1986{
1987 struct em28xx *dev = video_get_drvdata(vdev);
1988
1989 video_device_release(vdev);
1990 if (vdev == dev->vdev)
1991 dev->vdev = NULL;
1992 else if (vdev == dev->vbi_dev)
1993 dev->vbi_dev = NULL;
1994 else if (vdev == dev->radio_dev)
1995 dev->radio_dev = NULL;
1996}
1997
1702static const struct v4l2_file_operations em28xx_v4l_fops = { 1998static const struct v4l2_file_operations em28xx_v4l_fops = {
1703 .owner = THIS_MODULE, 1999 .owner = THIS_MODULE,
1704 .open = em28xx_v4l2_open, 2000 .open = em28xx_v4l2_open,
@@ -1753,11 +2049,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1753}; 2049};
1754 2050
1755static const struct video_device em28xx_video_template = { 2051static const struct video_device em28xx_video_template = {
1756 .fops = &em28xx_v4l_fops, 2052 .fops = &em28xx_v4l_fops,
1757 .release = video_device_release_empty, 2053 .ioctl_ops = &video_ioctl_ops,
1758 .ioctl_ops = &video_ioctl_ops, 2054 .release = em28xx_videodevice_release,
1759 2055 .tvnorms = V4L2_STD_ALL,
1760 .tvnorms = V4L2_STD_ALL,
1761}; 2056};
1762 2057
1763static const struct v4l2_file_operations radio_fops = { 2058static const struct v4l2_file_operations radio_fops = {
@@ -1783,14 +2078,30 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
1783}; 2078};
1784 2079
1785static struct video_device em28xx_radio_template = { 2080static struct video_device em28xx_radio_template = {
1786 .name = "em28xx-radio", 2081 .fops = &radio_fops,
1787 .fops = &radio_fops, 2082 .ioctl_ops = &radio_ioctl_ops,
1788 .ioctl_ops = &radio_ioctl_ops, 2083 .release = em28xx_videodevice_release,
1789}; 2084};
1790 2085
1791/******************************** usb interface ******************************/ 2086/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
2087static unsigned short saa711x_addrs[] = {
2088 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
2089 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
2090 I2C_CLIENT_END };
1792 2091
2092static unsigned short tvp5150_addrs[] = {
2093 0xb8 >> 1,
2094 0xba >> 1,
2095 I2C_CLIENT_END
2096};
1793 2097
2098static unsigned short msp3400_addrs[] = {
2099 0x80 >> 1,
2100 0x88 >> 1,
2101 I2C_CLIENT_END
2102};
2103
2104/******************************** usb interface ******************************/
1794 2105
1795static struct video_device *em28xx_vdev_init(struct em28xx *dev, 2106static struct video_device *em28xx_vdev_init(struct em28xx *dev,
1796 const struct video_device *template, 2107 const struct video_device *template,
@@ -1817,14 +2128,198 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
1817 return vfd; 2128 return vfd;
1818} 2129}
1819 2130
1820int em28xx_register_analog_devices(struct em28xx *dev) 2131static void em28xx_tuner_setup(struct em28xx *dev)
2132{
2133 struct tuner_setup tun_setup;
2134 struct v4l2_frequency f;
2135
2136 if (dev->tuner_type == TUNER_ABSENT)
2137 return;
2138
2139 memset(&tun_setup, 0, sizeof(tun_setup));
2140
2141 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
2142 tun_setup.tuner_callback = em28xx_tuner_callback;
2143
2144 if (dev->board.radio.type) {
2145 tun_setup.type = dev->board.radio.type;
2146 tun_setup.addr = dev->board.radio_addr;
2147
2148 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2149 }
2150
2151 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
2152 tun_setup.type = dev->tuner_type;
2153 tun_setup.addr = dev->tuner_addr;
2154
2155 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
2156 }
2157
2158 if (dev->tda9887_conf) {
2159 struct v4l2_priv_tun_config tda9887_cfg;
2160
2161 tda9887_cfg.tuner = TUNER_TDA9887;
2162 tda9887_cfg.priv = &dev->tda9887_conf;
2163
2164 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
2165 }
2166
2167 if (dev->tuner_type == TUNER_XC2028) {
2168 struct v4l2_priv_tun_config xc2028_cfg;
2169 struct xc2028_ctrl ctl;
2170
2171 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2172 memset(&ctl, 0, sizeof(ctl));
2173
2174 em28xx_setup_xc3028(dev, &ctl);
2175
2176 xc2028_cfg.tuner = TUNER_XC2028;
2177 xc2028_cfg.priv = &ctl;
2178
2179 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
2180 }
2181
2182 /* configure tuner */
2183 f.tuner = 0;
2184 f.type = V4L2_TUNER_ANALOG_TV;
2185 f.frequency = 9076; /* just a magic number */
2186 dev->ctl_freq = f.frequency;
2187 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
2188}
2189
2190static int em28xx_v4l2_init(struct em28xx *dev)
1821{ 2191{
1822 u8 val; 2192 u8 val;
1823 int ret; 2193 int ret;
1824 unsigned int maxw; 2194 unsigned int maxw;
2195 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
2196
2197 if (dev->is_audio_only) {
2198 /* Shouldn't initialize IR for this interface */
2199 return 0;
2200 }
2201
2202 if (!dev->has_video) {
2203 /* This device does not support the v4l2 extension */
2204 return 0;
2205 }
2206
2207 em28xx_info("Registering V4L2 extension\n");
2208
2209 mutex_lock(&dev->lock);
2210
2211 ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
2212 if (ret < 0) {
2213 em28xx_errdev("Call to v4l2_device_register() failed!\n");
2214 goto err;
2215 }
2216
2217 v4l2_ctrl_handler_init(hdl, 8);
2218 dev->v4l2_dev.ctrl_handler = hdl;
2219
2220 /*
2221 * Default format, used for tvp5150 or saa711x output formats
2222 */
2223 dev->vinmode = 0x10;
2224 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2225 EM28XX_VINCTRL_CCIR656_ENABLE;
2226
2227 /* request some modules */
2228
2229 if (dev->board.has_msp34xx)
2230 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2231 "msp3400", 0, msp3400_addrs);
2232
2233 if (dev->board.decoder == EM28XX_SAA711X)
2234 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2235 "saa7115_auto", 0, saa711x_addrs);
2236
2237 if (dev->board.decoder == EM28XX_TVP5150)
2238 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2239 "tvp5150", 0, tvp5150_addrs);
2240
2241 if (dev->board.adecoder == EM28XX_TVAUDIO)
2242 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2243 "tvaudio", dev->board.tvaudio_addr, NULL);
2244
2245 /* Initialize tuner and camera */
2246
2247 if (dev->board.tuner_type != TUNER_ABSENT) {
2248 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2249
2250 if (dev->board.radio.type)
2251 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2252 "tuner", dev->board.radio_addr, NULL);
2253
2254 if (has_demod)
2255 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2256 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2257 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2258 if (dev->tuner_addr == 0) {
2259 enum v4l2_i2c_tuner_type type =
2260 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2261 struct v4l2_subdev *sd;
2262
2263 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2264 &dev->i2c_adap[dev->def_i2c_bus], "tuner",
2265 0, v4l2_i2c_tuner_addrs(type));
2266
2267 if (sd)
2268 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2269 } else {
2270 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus],
2271 "tuner", dev->tuner_addr, NULL);
2272 }
2273 }
2274
2275 em28xx_tuner_setup(dev);
2276 em28xx_init_camera(dev);
2277
2278 /* Configure audio */
2279 ret = em28xx_audio_setup(dev);
2280 if (ret < 0) {
2281 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2282 __func__, ret);
2283 goto unregister_dev;
2284 }
2285 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
2286 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2287 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
2288 v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
2289 V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
2290 } else {
2291 /* install the em28xx notify callback */
2292 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
2293 em28xx_ctrl_notify, dev);
2294 v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
2295 em28xx_ctrl_notify, dev);
2296 }
2297
2298 /* wake i2c devices */
2299 em28xx_wake_i2c(dev);
2300
2301 /* init video dma queues */
2302 INIT_LIST_HEAD(&dev->vidq.active);
2303 INIT_LIST_HEAD(&dev->vbiq.active);
1825 2304
1826 printk(KERN_INFO "%s: v4l2 driver version %s\n", 2305 if (dev->board.has_msp34xx) {
1827 dev->name, EM28XX_VERSION); 2306 /* Send a reset to other chips via gpio */
2307 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
2308 if (ret < 0) {
2309 em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
2310 __func__, ret);
2311 goto unregister_dev;
2312 }
2313 msleep(3);
2314
2315 ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
2316 if (ret < 0) {
2317 em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
2318 __func__, ret);
2319 goto unregister_dev;
2320 }
2321 msleep(3);
2322 }
1828 2323
1829 /* set default norm */ 2324 /* set default norm */
1830 dev->norm = V4L2_STD_PAL; 2325 dev->norm = V4L2_STD_PAL;
@@ -1888,14 +2383,16 @@ int em28xx_register_analog_devices(struct em28xx *dev)
1888 /* Reset image controls */ 2383 /* Reset image controls */
1889 em28xx_colorlevels_set_default(dev); 2384 em28xx_colorlevels_set_default(dev);
1890 v4l2_ctrl_handler_setup(&dev->ctrl_handler); 2385 v4l2_ctrl_handler_setup(&dev->ctrl_handler);
1891 if (dev->ctrl_handler.error) 2386 ret = dev->ctrl_handler.error;
1892 return dev->ctrl_handler.error; 2387 if (ret)
2388 goto unregister_dev;
1893 2389
1894 /* allocate and fill video video_device struct */ 2390 /* allocate and fill video video_device struct */
1895 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); 2391 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
1896 if (!dev->vdev) { 2392 if (!dev->vdev) {
1897 em28xx_errdev("cannot allocate video_device.\n"); 2393 em28xx_errdev("cannot allocate video_device.\n");
1898 return -ENODEV; 2394 ret = -ENODEV;
2395 goto unregister_dev;
1899 } 2396 }
1900 dev->vdev->queue = &dev->vb_vidq; 2397 dev->vdev->queue = &dev->vb_vidq;
1901 dev->vdev->queue->lock = &dev->vb_queue_lock; 2398 dev->vdev->queue->lock = &dev->vb_queue_lock;
@@ -1925,7 +2422,7 @@ int em28xx_register_analog_devices(struct em28xx *dev)
1925 if (ret) { 2422 if (ret) {
1926 em28xx_errdev("unable to register video device (error=%i).\n", 2423 em28xx_errdev("unable to register video device (error=%i).\n",
1927 ret); 2424 ret);
1928 return ret; 2425 goto unregister_dev;
1929 } 2426 }
1930 2427
1931 /* Allocate and fill vbi video_device struct */ 2428 /* Allocate and fill vbi video_device struct */
@@ -1954,7 +2451,7 @@ int em28xx_register_analog_devices(struct em28xx *dev)
1954 vbi_nr[dev->devno]); 2451 vbi_nr[dev->devno]);
1955 if (ret < 0) { 2452 if (ret < 0) {
1956 em28xx_errdev("unable to register vbi device\n"); 2453 em28xx_errdev("unable to register vbi device\n");
1957 return ret; 2454 goto unregister_dev;
1958 } 2455 }
1959 } 2456 }
1960 2457
@@ -1963,13 +2460,14 @@ int em28xx_register_analog_devices(struct em28xx *dev)
1963 "radio"); 2460 "radio");
1964 if (!dev->radio_dev) { 2461 if (!dev->radio_dev) {
1965 em28xx_errdev("cannot allocate video_device.\n"); 2462 em28xx_errdev("cannot allocate video_device.\n");
1966 return -ENODEV; 2463 ret = -ENODEV;
2464 goto unregister_dev;
1967 } 2465 }
1968 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, 2466 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
1969 radio_nr[dev->devno]); 2467 radio_nr[dev->devno]);
1970 if (ret < 0) { 2468 if (ret < 0) {
1971 em28xx_errdev("can't register radio device\n"); 2469 em28xx_errdev("can't register radio device\n");
1972 return ret; 2470 goto unregister_dev;
1973 } 2471 }
1974 em28xx_info("Registered radio device as %s\n", 2472 em28xx_info("Registered radio device as %s\n",
1975 video_device_node_name(dev->radio_dev)); 2473 video_device_node_name(dev->radio_dev));
@@ -1982,5 +2480,41 @@ int em28xx_register_analog_devices(struct em28xx *dev)
1982 em28xx_info("V4L2 VBI device registered as %s\n", 2480 em28xx_info("V4L2 VBI device registered as %s\n",
1983 video_device_node_name(dev->vbi_dev)); 2481 video_device_node_name(dev->vbi_dev));
1984 2482
2483 /* Save some power by putting tuner to sleep */
2484 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2485
2486 /* initialize videobuf2 stuff */
2487 em28xx_vb2_setup(dev);
2488
2489 em28xx_info("V4L2 extension successfully initialized\n");
2490
2491 mutex_unlock(&dev->lock);
1985 return 0; 2492 return 0;
2493
2494unregister_dev:
2495 v4l2_ctrl_handler_free(&dev->ctrl_handler);
2496 v4l2_device_unregister(&dev->v4l2_dev);
2497err:
2498 mutex_unlock(&dev->lock);
2499 return ret;
2500}
2501
2502static struct em28xx_ops v4l2_ops = {
2503 .id = EM28XX_V4L2,
2504 .name = "Em28xx v4l2 Extension",
2505 .init = em28xx_v4l2_init,
2506 .fini = em28xx_v4l2_fini,
2507};
2508
2509static int __init em28xx_video_register(void)
2510{
2511 return em28xx_register_extension(&v4l2_ops);
2512}
2513
2514static void __exit em28xx_video_unregister(void)
2515{
2516 em28xx_unregister_extension(&v4l2_ops);
1986} 2517}
2518
2519module_init(em28xx_video_register);
2520module_exit(em28xx_video_unregister);
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index f8726ad5d0a8..32d8a4bb7961 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -26,6 +26,9 @@
26#ifndef _EM28XX_H 26#ifndef _EM28XX_H
27#define _EM28XX_H 27#define _EM28XX_H
28 28
29#define EM28XX_VERSION "0.2.1"
30#define DRIVER_DESC "Empia em28xx device driver"
31
29#include <linux/workqueue.h> 32#include <linux/workqueue.h>
30#include <linux/i2c.h> 33#include <linux/i2c.h>
31#include <linux/mutex.h> 34#include <linux/mutex.h>
@@ -132,6 +135,8 @@
132#define EM2884_BOARD_C3TECH_DIGITAL_DUO 88 135#define EM2884_BOARD_C3TECH_DIGITAL_DUO 88
133#define EM2874_BOARD_DELOCK_61959 89 136#define EM2874_BOARD_DELOCK_61959 89
134#define EM2874_BOARD_KWORLD_UB435Q_V2 90 137#define EM2874_BOARD_KWORLD_UB435Q_V2 90
138#define EM2765_BOARD_SPEEDLINK_VAD_LAPLACE 91
139#define EM28178_BOARD_PCTV_461E 92
135 140
136/* Limits minimum and default number of buffers */ 141/* Limits minimum and default number of buffers */
137#define EM28XX_MIN_BUF 4 142#define EM28XX_MIN_BUF 4
@@ -178,8 +183,27 @@
178 183
179#define EM28XX_INTERLACED_DEFAULT 1 184#define EM28XX_INTERLACED_DEFAULT 1
180 185
181/* time in msecs to wait for i2c writes to finish */ 186/*
182#define EM2800_I2C_XFER_TIMEOUT 20 187 * Time in msecs to wait for i2c xfers to finish.
188 * 35ms is the maximum time a SMBUS device could wait when
189 * clock stretching is used. As the transfer itself will take
190 * some time to happen, set it to 35 ms.
191 *
192 * Ok, I2C doesn't specify any limit. So, eventually, we may need
193 * to increase this timeout.
194 *
195 * FIXME: this assumes that an I2C message is not longer than 1ms.
196 * This is actually dependent on the I2C bus speed, although most
197 * devices use a 100kHz clock. So, this assumtion is true most of
198 * the time.
199 */
200#define EM28XX_I2C_XFER_TIMEOUT 36
201
202/* time in msecs to wait for AC97 xfers to finish */
203#define EM28XX_AC97_XFER_TIMEOUT 100
204
205/* max. number of button state polling addresses */
206#define EM28XX_NUM_BUTTON_ADDRESSES_MAX 5
183 207
184enum em28xx_mode { 208enum em28xx_mode {
185 EM28XX_SUSPEND, 209 EM28XX_SUSPEND,
@@ -287,8 +311,7 @@ struct em28xx_audio_mode {
287 311
288 unsigned int has_audio:1; 312 unsigned int has_audio:1;
289 313
290 unsigned int i2s_3rates:1; 314 u8 i2s_samplerates;
291 unsigned int i2s_5rates:1;
292}; 315};
293 316
294/* em28xx has two audio inputs: tuner and line in. 317/* em28xx has two audio inputs: tuner and line in.
@@ -374,6 +397,33 @@ enum em28xx_adecoder {
374 EM28XX_TVAUDIO, 397 EM28XX_TVAUDIO,
375}; 398};
376 399
400enum em28xx_led_role {
401 EM28XX_LED_ANALOG_CAPTURING = 0,
402 EM28XX_LED_ILLUMINATION,
403 EM28XX_NUM_LED_ROLES, /* must be the last */
404};
405
406struct em28xx_led {
407 enum em28xx_led_role role;
408 u8 gpio_reg;
409 u8 gpio_mask;
410 bool inverted;
411};
412
413enum em28xx_button_role {
414 EM28XX_BUTTON_SNAPSHOT = 0,
415 EM28XX_BUTTON_ILLUMINATION,
416 EM28XX_NUM_BUTTON_ROLES, /* must be the last */
417};
418
419struct em28xx_button {
420 enum em28xx_button_role role;
421 u8 reg_r;
422 u8 reg_clearing;
423 u8 mask;
424 bool inverted;
425};
426
377struct em28xx_board { 427struct em28xx_board {
378 char *name; 428 char *name;
379 int vchannels; 429 int vchannels;
@@ -395,7 +445,6 @@ struct em28xx_board {
395 unsigned int mts_firmware:1; 445 unsigned int mts_firmware:1;
396 unsigned int max_range_640_480:1; 446 unsigned int max_range_640_480:1;
397 unsigned int has_dvb:1; 447 unsigned int has_dvb:1;
398 unsigned int has_snapshot_button:1;
399 unsigned int is_webcam:1; 448 unsigned int is_webcam:1;
400 unsigned int valid:1; 449 unsigned int valid:1;
401 unsigned int has_ir_i2c:1; 450 unsigned int has_ir_i2c:1;
@@ -410,6 +459,12 @@ struct em28xx_board {
410 struct em28xx_input input[MAX_EM28XX_INPUT]; 459 struct em28xx_input input[MAX_EM28XX_INPUT];
411 struct em28xx_input radio; 460 struct em28xx_input radio;
412 char *ir_codes; 461 char *ir_codes;
462
463 /* LEDs that need to be controlled explicitly */
464 struct em28xx_led *leds;
465
466 /* Buttons */
467 struct em28xx_button *buttons;
413}; 468};
414 469
415struct em28xx_eeprom { 470struct em28xx_eeprom {
@@ -426,15 +481,13 @@ struct em28xx_eeprom {
426 u8 string_idx_table; 481 u8 string_idx_table;
427}; 482};
428 483
429#define EM28XX_AUDIO_BUFS 5
430#define EM28XX_NUM_AUDIO_PACKETS 64
431#define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */
432#define EM28XX_CAPTURE_STREAM_EN 1 484#define EM28XX_CAPTURE_STREAM_EN 1
433 485
434/* em28xx extensions */ 486/* em28xx extensions */
435#define EM28XX_AUDIO 0x10 487#define EM28XX_AUDIO 0x10
436#define EM28XX_DVB 0x20 488#define EM28XX_DVB 0x20
437#define EM28XX_RC 0x30 489#define EM28XX_RC 0x30
490#define EM28XX_V4L2 0x40
438 491
439/* em28xx resource types (used for res_get/res_lock etc */ 492/* em28xx resource types (used for res_get/res_lock etc */
440#define EM28XX_RESOURCE_VIDEO 0x01 493#define EM28XX_RESOURCE_VIDEO 0x01
@@ -442,8 +495,9 @@ struct em28xx_eeprom {
442 495
443struct em28xx_audio { 496struct em28xx_audio {
444 char name[50]; 497 char name[50];
445 char *transfer_buffer[EM28XX_AUDIO_BUFS]; 498 unsigned num_urb;
446 struct urb *urb[EM28XX_AUDIO_BUFS]; 499 char **transfer_buffer;
500 struct urb **urb;
447 struct usb_device *udev; 501 struct usb_device *udev;
448 unsigned int capture_transfer_done; 502 unsigned int capture_transfer_done;
449 struct snd_pcm_substream *capture_pcm_substream; 503 struct snd_pcm_substream *capture_pcm_substream;
@@ -451,6 +505,8 @@ struct em28xx_audio {
451 unsigned int hwptr_done_capture; 505 unsigned int hwptr_done_capture;
452 struct snd_card *sndcard; 506 struct snd_card *sndcard;
453 507
508 size_t period;
509
454 int users; 510 int users;
455 spinlock_t slock; 511 spinlock_t slock;
456}; 512};
@@ -485,11 +541,13 @@ struct em28xx {
485 int model; /* index in the device_data struct */ 541 int model; /* index in the device_data struct */
486 int devno; /* marks the number of this device */ 542 int devno; /* marks the number of this device */
487 enum em28xx_chip_id chip_id; 543 enum em28xx_chip_id chip_id;
488 unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */
489 544
545 unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */
490 unsigned char disconnected:1; /* device has been diconnected */ 546 unsigned char disconnected:1; /* device has been diconnected */
491 547 unsigned int has_video:1;
492 int audio_ifnum; 548 unsigned int has_audio_class:1;
549 unsigned int has_alsa_audio:1;
550 unsigned int is_audio_only:1;
493 551
494 struct v4l2_device v4l2_dev; 552 struct v4l2_device v4l2_dev;
495 struct v4l2_ctrl_handler ctrl_handler; 553 struct v4l2_ctrl_handler ctrl_handler;
@@ -507,10 +565,6 @@ struct em28xx {
507 /* Vinmode/Vinctl used at the driver */ 565 /* Vinmode/Vinctl used at the driver */
508 int vinmode, vinctl; 566 int vinmode, vinctl;
509 567
510 unsigned int has_audio_class:1;
511 unsigned int has_alsa_audio:1;
512 unsigned int is_audio_only:1;
513
514 /* Controls audio streaming */ 568 /* Controls audio streaming */
515 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ 569 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
516 atomic_t stream_started; /* stream should be running if true */ 570 atomic_t stream_started; /* stream should be running if true */
@@ -608,6 +662,7 @@ struct em28xx {
608 662
609 /* usb transfer */ 663 /* usb transfer */
610 struct usb_device *udev; /* the usb device */ 664 struct usb_device *udev; /* the usb device */
665 u8 ifnum; /* number of the assigned usb interface */
611 u8 analog_ep_isoc; /* address of isoc endpoint for analog */ 666 u8 analog_ep_isoc; /* address of isoc endpoint for analog */
612 u8 analog_ep_bulk; /* address of bulk endpoint for analog */ 667 u8 analog_ep_bulk; /* address of bulk endpoint for analog */
613 u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */ 668 u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */
@@ -639,10 +694,15 @@ struct em28xx {
639 694
640 enum em28xx_mode mode; 695 enum em28xx_mode mode;
641 696
642 /* Snapshot button */ 697 /* Button state polling */
698 struct delayed_work buttons_query_work;
699 u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
700 u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
701 u8 num_button_polling_addresses;
702 u16 button_polling_interval; /* [ms] */
703 /* Snapshot button input device */
643 char snapshot_button_path[30]; /* path of the input dev */ 704 char snapshot_button_path[30]; /* path of the input dev */
644 struct input_dev *sbutton_input_dev; 705 struct input_dev *sbutton_input_dev;
645 struct delayed_work sbutton_query_work;
646 706
647 struct em28xx_dvb *dvb; 707 struct em28xx_dvb *dvb;
648}; 708};
@@ -672,6 +732,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
672int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); 732int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
673int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, 733int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
674 u8 bitmask); 734 u8 bitmask);
735int em28xx_toggle_reg_bits(struct em28xx *dev, u16 reg, u8 bitmask);
675 736
676int em28xx_read_ac97(struct em28xx *dev, u8 reg); 737int em28xx_read_ac97(struct em28xx *dev, u8 reg);
677int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); 738int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
@@ -679,12 +740,9 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
679int em28xx_audio_analog_set(struct em28xx *dev); 740int em28xx_audio_analog_set(struct em28xx *dev);
680int em28xx_audio_setup(struct em28xx *dev); 741int em28xx_audio_setup(struct em28xx *dev);
681 742
682int em28xx_colorlevels_set_default(struct em28xx *dev); 743const struct em28xx_led *em28xx_find_led(struct em28xx *dev,
744 enum em28xx_led_role role);
683int em28xx_capture_start(struct em28xx *dev, int start); 745int em28xx_capture_start(struct em28xx *dev, int start);
684int em28xx_vbi_supported(struct em28xx *dev);
685int em28xx_set_outfmt(struct em28xx *dev);
686int em28xx_resolution_set(struct em28xx *dev);
687int em28xx_set_alternate(struct em28xx *dev);
688int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, 746int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk,
689 int num_bufs, int max_pkt_size, int packet_multiplier); 747 int num_bufs, int max_pkt_size, int packet_multiplier);
690int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, 748int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode,
@@ -696,30 +754,18 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode);
696void em28xx_stop_urbs(struct em28xx *dev); 754void em28xx_stop_urbs(struct em28xx *dev);
697int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 755int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
698int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); 756int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
699void em28xx_wake_i2c(struct em28xx *dev);
700int em28xx_register_extension(struct em28xx_ops *dev); 757int em28xx_register_extension(struct em28xx_ops *dev);
701void em28xx_unregister_extension(struct em28xx_ops *dev); 758void em28xx_unregister_extension(struct em28xx_ops *dev);
702void em28xx_init_extension(struct em28xx *dev); 759void em28xx_init_extension(struct em28xx *dev);
703void em28xx_close_extension(struct em28xx *dev); 760void em28xx_close_extension(struct em28xx *dev);
704 761
705/* Provided by em28xx-video.c */
706int em28xx_vb2_setup(struct em28xx *dev);
707int em28xx_register_analog_devices(struct em28xx *dev);
708void em28xx_release_analog_resources(struct em28xx *dev);
709void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv);
710int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count);
711int em28xx_stop_vbi_streaming(struct vb2_queue *vq);
712extern const struct v4l2_ctrl_ops em28xx_ctrl_ops;
713
714/* Provided by em28xx-cards.c */ 762/* Provided by em28xx-cards.c */
715extern struct em28xx_board em28xx_boards[]; 763extern struct em28xx_board em28xx_boards[];
716extern struct usb_device_id em28xx_id_table[]; 764extern struct usb_device_id em28xx_id_table[];
717int em28xx_tuner_callback(void *ptr, int component, int command, int arg); 765int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
766void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl);
718void em28xx_release_resources(struct em28xx *dev); 767void em28xx_release_resources(struct em28xx *dev);
719 768
720/* Provided by em28xx-vbi.c */
721extern struct vb2_ops em28xx_vbi_qops;
722
723/* Provided by em28xx-camera.c */ 769/* Provided by em28xx-camera.c */
724int em28xx_detect_sensor(struct em28xx *dev); 770int em28xx_detect_sensor(struct em28xx *dev);
725int em28xx_init_camera(struct em28xx *dev); 771int em28xx_init_camera(struct em28xx *dev);
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index 78c9bc8e7f56..abf365ab025d 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -1078,7 +1078,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1078 /* register webcam snapshot button input device */ 1078 /* register webcam snapshot button input device */
1079 pdev->button_dev = input_allocate_device(); 1079 pdev->button_dev = input_allocate_device();
1080 if (!pdev->button_dev) { 1080 if (!pdev->button_dev) {
1081 PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
1082 rc = -ENOMEM; 1081 rc = -ENOMEM;
1083 goto err_video_unreg; 1082 goto err_video_unreg;
1084 } 1083 }
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 8c05565a240e..2189bfb2e828 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -83,14 +83,3 @@ config VIDEOBUF2_DMA_SG
83 #depends on HAS_DMA 83 #depends on HAS_DMA
84 select VIDEOBUF2_CORE 84 select VIDEOBUF2_CORE
85 select VIDEOBUF2_MEMOPS 85 select VIDEOBUF2_MEMOPS
86
87config VIDEO_V4L2_INT_DEVICE
88 tristate "V4L2 int device (DEPRECATED)"
89 depends on VIDEO_V4L2
90 ---help---
91 An early framework for a hardware-independent interface for
92 image sensors and bridges etc. Currently used by omap24xxcam and
93 tcm825x drivers that should be converted to V4L2 subdev.
94
95 Do not use for new developments.
96
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 1a85eee581f8..c6ae7bad951e 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -15,7 +15,6 @@ ifeq ($(CONFIG_OF),y)
15endif 15endif
16 16
17obj-$(CONFIG_VIDEO_V4L2) += videodev.o 17obj-$(CONFIG_VIDEO_V4L2) += videodev.o
18obj-$(CONFIG_VIDEO_V4L2_INT_DEVICE) += v4l2-int-device.o
19obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o 18obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o
20obj-$(CONFIG_VIDEO_V4L2) += v4l2-dv-timings.o 19obj-$(CONFIG_VIDEO_V4L2) += v4l2-dv-timings.o
21 20
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index fb46790d0eca..6ff002bd5909 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -745,6 +745,11 @@ const char *v4l2_ctrl_get_name(u32 id)
745 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control"; 745 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control";
746 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period"; 746 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period";
747 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator"; 747 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator";
748 case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value";
749 case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value";
750 case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value";
751 case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value";
752 case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: return "VPX Profile";
748 753
749 /* CAMERA controls */ 754 /* CAMERA controls */
750 /* Keep the order of the 'case's the same as in videodev2.h! */ 755 /* Keep the order of the 'case's the same as in videodev2.h! */
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index b5aaaac427ad..0a30dbf3d05c 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -872,8 +872,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
872 872
873 /* Should not happen since we thought this minor was free */ 873 /* Should not happen since we thought this minor was free */
874 WARN_ON(video_device[vdev->minor] != NULL); 874 WARN_ON(video_device[vdev->minor] != NULL);
875 video_device[vdev->minor] = vdev;
876 vdev->index = get_index(vdev); 875 vdev->index = get_index(vdev);
876 video_device[vdev->minor] = vdev;
877 mutex_unlock(&videodev_lock); 877 mutex_unlock(&videodev_lock);
878 878
879 if (vdev->ioctl_ops) 879 if (vdev->ioctl_ops)
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 68e6b5e912ff..707aef705a47 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -28,6 +28,9 @@
28#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
29#include <media/videobuf2-core.h> 29#include <media/videobuf2-core.h>
30 30
31#define CREATE_TRACE_POINTS
32#include <trace/events/v4l2.h>
33
31/* Zero out the end of the struct pointed to by p. Everything after, but 34/* Zero out the end of the struct pointed to by p. Everything after, but
32 * not including, the specified field is cleared. */ 35 * not including, the specified field is cleared. */
33#define CLEAR_AFTER_FIELD(p, field) \ 36#define CLEAR_AFTER_FIELD(p, field) \
@@ -2338,6 +2341,12 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2338 err = func(file, cmd, parg); 2341 err = func(file, cmd, parg);
2339 if (err == -ENOIOCTLCMD) 2342 if (err == -ENOIOCTLCMD)
2340 err = -ENOTTY; 2343 err = -ENOTTY;
2344 if (err == 0) {
2345 if (cmd == VIDIOC_DQBUF)
2346 trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
2347 else if (cmd == VIDIOC_QBUF)
2348 trace_v4l2_qbuf(video_devdata(file)->minor, parg);
2349 }
2341 2350
2342 if (has_array_args) { 2351 if (has_array_args) {
2343 *kernel_ptr = user_ptr; 2352 *kernel_ptr = user_ptr;
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 73035ee0f4de..178ce96556c6 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -558,6 +558,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
558 558
559 if (m2m_ctx->m2m_dev->m2m_ops->unlock) 559 if (m2m_ctx->m2m_dev->m2m_ops->unlock)
560 m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv); 560 m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
561 else if (m2m_ctx->q_lock)
562 mutex_unlock(m2m_ctx->q_lock);
561 563
562 if (list_empty(&src_q->done_list)) 564 if (list_empty(&src_q->done_list))
563 poll_wait(file, &src_q->done_wq, wait); 565 poll_wait(file, &src_q->done_wq, wait);
@@ -566,6 +568,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
566 568
567 if (m2m_ctx->m2m_dev->m2m_ops->lock) 569 if (m2m_ctx->m2m_dev->m2m_ops->lock)
568 m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); 570 m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
571 else if (m2m_ctx->q_lock)
572 mutex_lock(m2m_ctx->q_lock);
569 573
570 spin_lock_irqsave(&src_q->done_lock, flags); 574 spin_lock_irqsave(&src_q->done_lock, flags);
571 if (!list_empty(&src_q->done_list)) 575 if (!list_empty(&src_q->done_list))
@@ -693,6 +697,13 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
693 697
694 if (ret) 698 if (ret)
695 goto err; 699 goto err;
700 /*
701 * If both queues use same mutex assign it as the common buffer
702 * queues lock to the m2m context. This lock is used in the
703 * v4l2_m2m_ioctl_* helpers.
704 */
705 if (out_q_ctx->q.lock == cap_q_ctx->q.lock)
706 m2m_ctx->q_lock = out_q_ctx->q.lock;
696 707
697 return m2m_ctx; 708 return m2m_ctx;
698err: 709err:
@@ -740,3 +751,118 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
740} 751}
741EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue); 752EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
742 753
754/* Videobuf2 ioctl helpers */
755
756int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
757 struct v4l2_requestbuffers *rb)
758{
759 struct v4l2_fh *fh = file->private_data;
760
761 return v4l2_m2m_reqbufs(file, fh->m2m_ctx, rb);
762}
763EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_reqbufs);
764
765int v4l2_m2m_ioctl_create_bufs(struct file *file, void *priv,
766 struct v4l2_create_buffers *create)
767{
768 struct v4l2_fh *fh = file->private_data;
769
770 return v4l2_m2m_create_bufs(file, fh->m2m_ctx, create);
771}
772EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_create_bufs);
773
774int v4l2_m2m_ioctl_querybuf(struct file *file, void *priv,
775 struct v4l2_buffer *buf)
776{
777 struct v4l2_fh *fh = file->private_data;
778
779 return v4l2_m2m_querybuf(file, fh->m2m_ctx, buf);
780}
781EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_querybuf);
782
783int v4l2_m2m_ioctl_qbuf(struct file *file, void *priv,
784 struct v4l2_buffer *buf)
785{
786 struct v4l2_fh *fh = file->private_data;
787
788 return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
789}
790EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_qbuf);
791
792int v4l2_m2m_ioctl_dqbuf(struct file *file, void *priv,
793 struct v4l2_buffer *buf)
794{
795 struct v4l2_fh *fh = file->private_data;
796
797 return v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
798}
799EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_dqbuf);
800
801int v4l2_m2m_ioctl_expbuf(struct file *file, void *priv,
802 struct v4l2_exportbuffer *eb)
803{
804 struct v4l2_fh *fh = file->private_data;
805
806 return v4l2_m2m_expbuf(file, fh->m2m_ctx, eb);
807}
808EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_expbuf);
809
810int v4l2_m2m_ioctl_streamon(struct file *file, void *priv,
811 enum v4l2_buf_type type)
812{
813 struct v4l2_fh *fh = file->private_data;
814
815 return v4l2_m2m_streamon(file, fh->m2m_ctx, type);
816}
817EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamon);
818
819int v4l2_m2m_ioctl_streamoff(struct file *file, void *priv,
820 enum v4l2_buf_type type)
821{
822 struct v4l2_fh *fh = file->private_data;
823
824 return v4l2_m2m_streamoff(file, fh->m2m_ctx, type);
825}
826EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamoff);
827
828/*
829 * v4l2_file_operations helpers. It is assumed here same lock is used
830 * for the output and the capture buffer queue.
831 */
832
833int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma)
834{
835 struct v4l2_fh *fh = file->private_data;
836 struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
837 int ret;
838
839 if (m2m_ctx->q_lock && mutex_lock_interruptible(m2m_ctx->q_lock))
840 return -ERESTARTSYS;
841
842 ret = v4l2_m2m_mmap(file, m2m_ctx, vma);
843
844 if (m2m_ctx->q_lock)
845 mutex_unlock(m2m_ctx->q_lock);
846
847 return ret;
848}
849EXPORT_SYMBOL_GPL(v4l2_m2m_fop_mmap);
850
851unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait)
852{
853 struct v4l2_fh *fh = file->private_data;
854 struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
855 unsigned int ret;
856
857 if (m2m_ctx->q_lock)
858 mutex_lock(m2m_ctx->q_lock);
859
860 ret = v4l2_m2m_poll(file, m2m_ctx, wait);
861
862 if (m2m_ctx->q_lock)
863 mutex_unlock(m2m_ctx->q_lock);
864
865 return ret;
866}
867EXPORT_SYMBOL_GPL(v4l2_m2m_fop_poll);
868
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
index a6478dca0cde..42e3e8a5e361 100644
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ b/drivers/media/v4l2-core/v4l2-of.c
@@ -121,9 +121,11 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node,
121 * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the 121 * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
122 * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. 122 * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
123 * The caller should hold a reference to @node. 123 * The caller should hold a reference to @node.
124 *
125 * Return: 0.
124 */ 126 */
125void v4l2_of_parse_endpoint(const struct device_node *node, 127int v4l2_of_parse_endpoint(const struct device_node *node,
126 struct v4l2_of_endpoint *endpoint) 128 struct v4l2_of_endpoint *endpoint)
127{ 129{
128 struct device_node *port_node = of_get_parent(node); 130 struct device_node *port_node = of_get_parent(node);
129 131
@@ -146,6 +148,8 @@ void v4l2_of_parse_endpoint(const struct device_node *node,
146 v4l2_of_parse_parallel_bus(node, endpoint); 148 v4l2_of_parse_parallel_bus(node, endpoint);
147 149
148 of_node_put(port_node); 150 of_node_put(port_node);
151
152 return 0;
149} 153}
150EXPORT_SYMBOL(v4l2_of_parse_endpoint); 154EXPORT_SYMBOL(v4l2_of_parse_endpoint);
151 155
@@ -262,6 +266,6 @@ struct device_node *v4l2_of_get_remote_port(const struct device_node *node)
262 np = of_parse_phandle(node, "remote-endpoint", 0); 266 np = of_parse_phandle(node, "remote-endpoint", 0);
263 if (!np) 267 if (!np)
264 return NULL; 268 return NULL;
265 return of_get_parent(np); 269 return of_get_next_parent(np);
266} 270}
267EXPORT_SYMBOL(v4l2_of_get_remote_port); 271EXPORT_SYMBOL(v4l2_of_get_remote_port);
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 0edc165f418d..5a5fb7f09b7b 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -298,10 +298,28 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
298 * related information, if no buffers are left return the queue to an 298 * related information, if no buffers are left return the queue to an
299 * uninitialized state. Might be called even if the queue has already been freed. 299 * uninitialized state. Might be called even if the queue has already been freed.
300 */ 300 */
301static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) 301static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
302{ 302{
303 unsigned int buffer; 303 unsigned int buffer;
304 304
305 /*
306 * Sanity check: when preparing a buffer the queue lock is released for
307 * a short while (see __buf_prepare for the details), which would allow
308 * a race with a reqbufs which can call this function. Removing the
309 * buffers from underneath __buf_prepare is obviously a bad idea, so we
310 * check if any of the buffers is in the state PREPARING, and if so we
311 * just return -EAGAIN.
312 */
313 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
314 ++buffer) {
315 if (q->bufs[buffer] == NULL)
316 continue;
317 if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
318 dprintk(1, "reqbufs: preparing buffers, cannot free\n");
319 return -EAGAIN;
320 }
321 }
322
305 /* Call driver-provided cleanup function for each buffer, if provided */ 323 /* Call driver-provided cleanup function for each buffer, if provided */
306 if (q->ops->buf_cleanup) { 324 if (q->ops->buf_cleanup) {
307 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; 325 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
@@ -326,6 +344,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
326 if (!q->num_buffers) 344 if (!q->num_buffers)
327 q->memory = 0; 345 q->memory = 0;
328 INIT_LIST_HEAD(&q->queued_list); 346 INIT_LIST_HEAD(&q->queued_list);
347 return 0;
329} 348}
330 349
331/** 350/**
@@ -481,6 +500,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
481 case VB2_BUF_STATE_PREPARED: 500 case VB2_BUF_STATE_PREPARED:
482 b->flags |= V4L2_BUF_FLAG_PREPARED; 501 b->flags |= V4L2_BUF_FLAG_PREPARED;
483 break; 502 break;
503 case VB2_BUF_STATE_PREPARING:
484 case VB2_BUF_STATE_DEQUEUED: 504 case VB2_BUF_STATE_DEQUEUED:
485 /* nothing */ 505 /* nothing */
486 break; 506 break;
@@ -657,7 +677,9 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
657 return -EBUSY; 677 return -EBUSY;
658 } 678 }
659 679
660 __vb2_queue_free(q, q->num_buffers); 680 ret = __vb2_queue_free(q, q->num_buffers);
681 if (ret)
682 return ret;
661 683
662 /* 684 /*
663 * In case of REQBUFS(0) return immediately without calling 685 * In case of REQBUFS(0) return immediately without calling
@@ -1116,7 +1138,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1116 int ret; 1138 int ret;
1117 int write = !V4L2_TYPE_IS_OUTPUT(q->type); 1139 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
1118 1140
1119 /* Verify and copy relevant information provided by the userspace */ 1141 /* Copy relevant information provided by the userspace */
1120 __fill_vb2_buffer(vb, b, planes); 1142 __fill_vb2_buffer(vb, b, planes);
1121 1143
1122 for (plane = 0; plane < vb->num_planes; ++plane) { 1144 for (plane = 0; plane < vb->num_planes; ++plane) {
@@ -1135,6 +1157,8 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1135 1157
1136 if (planes[plane].length < planes[plane].data_offset + 1158 if (planes[plane].length < planes[plane].data_offset +
1137 q->plane_sizes[plane]) { 1159 q->plane_sizes[plane]) {
1160 dprintk(1, "qbuf: invalid dmabuf length for plane %d\n",
1161 plane);
1138 ret = -EINVAL; 1162 ret = -EINVAL;
1139 goto err; 1163 goto err;
1140 } 1164 }
@@ -1226,6 +1250,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
1226static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) 1250static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1227{ 1251{
1228 struct vb2_queue *q = vb->vb2_queue; 1252 struct vb2_queue *q = vb->vb2_queue;
1253 struct rw_semaphore *mmap_sem;
1229 int ret; 1254 int ret;
1230 1255
1231 ret = __verify_length(vb, b); 1256 ret = __verify_length(vb, b);
@@ -1235,12 +1260,32 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1235 return ret; 1260 return ret;
1236 } 1261 }
1237 1262
1263 vb->state = VB2_BUF_STATE_PREPARING;
1238 switch (q->memory) { 1264 switch (q->memory) {
1239 case V4L2_MEMORY_MMAP: 1265 case V4L2_MEMORY_MMAP:
1240 ret = __qbuf_mmap(vb, b); 1266 ret = __qbuf_mmap(vb, b);
1241 break; 1267 break;
1242 case V4L2_MEMORY_USERPTR: 1268 case V4L2_MEMORY_USERPTR:
1269 /*
1270 * In case of user pointer buffers vb2 allocators need to get
1271 * direct access to userspace pages. This requires getting
1272 * the mmap semaphore for read access in the current process
1273 * structure. The same semaphore is taken before calling mmap
1274 * operation, while both qbuf/prepare_buf and mmap are called
1275 * by the driver or v4l2 core with the driver's lock held.
1276 * To avoid an AB-BA deadlock (mmap_sem then driver's lock in
1277 * mmap and driver's lock then mmap_sem in qbuf/prepare_buf),
1278 * the videobuf2 core releases the driver's lock, takes
1279 * mmap_sem and then takes the driver's lock again.
1280 */
1281 mmap_sem = &current->mm->mmap_sem;
1282 call_qop(q, wait_prepare, q);
1283 down_read(mmap_sem);
1284 call_qop(q, wait_finish, q);
1285
1243 ret = __qbuf_userptr(vb, b); 1286 ret = __qbuf_userptr(vb, b);
1287
1288 up_read(mmap_sem);
1244 break; 1289 break;
1245 case V4L2_MEMORY_DMABUF: 1290 case V4L2_MEMORY_DMABUF:
1246 ret = __qbuf_dmabuf(vb, b); 1291 ret = __qbuf_dmabuf(vb, b);
@@ -1254,105 +1299,36 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
1254 ret = call_qop(q, buf_prepare, vb); 1299 ret = call_qop(q, buf_prepare, vb);
1255 if (ret) 1300 if (ret)
1256 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret); 1301 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
1257 else 1302 vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED;
1258 vb->state = VB2_BUF_STATE_PREPARED;
1259 1303
1260 return ret; 1304 return ret;
1261} 1305}
1262 1306
1263static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b, 1307static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
1264 const char *opname, 1308 const char *opname)
1265 int (*handler)(struct vb2_queue *,
1266 struct v4l2_buffer *,
1267 struct vb2_buffer *))
1268{ 1309{
1269 struct rw_semaphore *mmap_sem = NULL;
1270 struct vb2_buffer *vb;
1271 int ret;
1272
1273 /*
1274 * In case of user pointer buffers vb2 allocators need to get direct
1275 * access to userspace pages. This requires getting the mmap semaphore
1276 * for read access in the current process structure. The same semaphore
1277 * is taken before calling mmap operation, while both qbuf/prepare_buf
1278 * and mmap are called by the driver or v4l2 core with the driver's lock
1279 * held. To avoid an AB-BA deadlock (mmap_sem then driver's lock in mmap
1280 * and driver's lock then mmap_sem in qbuf/prepare_buf) the videobuf2
1281 * core releases the driver's lock, takes mmap_sem and then takes the
1282 * driver's lock again.
1283 *
1284 * To avoid racing with other vb2 calls, which might be called after
1285 * releasing the driver's lock, this operation is performed at the
1286 * beginning of qbuf/prepare_buf processing. This way the queue status
1287 * is consistent after getting the driver's lock back.
1288 */
1289 if (q->memory == V4L2_MEMORY_USERPTR) {
1290 mmap_sem = &current->mm->mmap_sem;
1291 call_qop(q, wait_prepare, q);
1292 down_read(mmap_sem);
1293 call_qop(q, wait_finish, q);
1294 }
1295
1296 if (q->fileio) {
1297 dprintk(1, "%s(): file io in progress\n", opname);
1298 ret = -EBUSY;
1299 goto unlock;
1300 }
1301
1302 if (b->type != q->type) { 1310 if (b->type != q->type) {
1303 dprintk(1, "%s(): invalid buffer type\n", opname); 1311 dprintk(1, "%s(): invalid buffer type\n", opname);
1304 ret = -EINVAL; 1312 return -EINVAL;
1305 goto unlock;
1306 } 1313 }
1307 1314
1308 if (b->index >= q->num_buffers) { 1315 if (b->index >= q->num_buffers) {
1309 dprintk(1, "%s(): buffer index out of range\n", opname); 1316 dprintk(1, "%s(): buffer index out of range\n", opname);
1310 ret = -EINVAL; 1317 return -EINVAL;
1311 goto unlock;
1312 } 1318 }
1313 1319
1314 vb = q->bufs[b->index]; 1320 if (q->bufs[b->index] == NULL) {
1315 if (NULL == vb) {
1316 /* Should never happen */ 1321 /* Should never happen */
1317 dprintk(1, "%s(): buffer is NULL\n", opname); 1322 dprintk(1, "%s(): buffer is NULL\n", opname);
1318 ret = -EINVAL; 1323 return -EINVAL;
1319 goto unlock;
1320 } 1324 }
1321 1325
1322 if (b->memory != q->memory) { 1326 if (b->memory != q->memory) {
1323 dprintk(1, "%s(): invalid memory type\n", opname); 1327 dprintk(1, "%s(): invalid memory type\n", opname);
1324 ret = -EINVAL;
1325 goto unlock;
1326 }
1327
1328 ret = __verify_planes_array(vb, b);
1329 if (ret)
1330 goto unlock;
1331
1332 ret = handler(q, b, vb);
1333 if (ret)
1334 goto unlock;
1335
1336 /* Fill buffer information for the userspace */
1337 __fill_v4l2_buffer(vb, b);
1338
1339 dprintk(1, "%s() of buffer %d succeeded\n", opname, vb->v4l2_buf.index);
1340unlock:
1341 if (mmap_sem)
1342 up_read(mmap_sem);
1343 return ret;
1344}
1345
1346static int __vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
1347 struct vb2_buffer *vb)
1348{
1349 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1350 dprintk(1, "%s(): invalid buffer state %d\n", __func__,
1351 vb->state);
1352 return -EINVAL; 1328 return -EINVAL;
1353 } 1329 }
1354 1330
1355 return __buf_prepare(vb, b); 1331 return __verify_planes_array(q->bufs[b->index], b);
1356} 1332}
1357 1333
1358/** 1334/**
@@ -1372,22 +1348,95 @@ static int __vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
1372 */ 1348 */
1373int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) 1349int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
1374{ 1350{
1375 return vb2_queue_or_prepare_buf(q, b, "prepare_buf", __vb2_prepare_buf); 1351 struct vb2_buffer *vb;
1352 int ret;
1353
1354 if (q->fileio) {
1355 dprintk(1, "%s(): file io in progress\n", __func__);
1356 return -EBUSY;
1357 }
1358
1359 ret = vb2_queue_or_prepare_buf(q, b, "prepare_buf");
1360 if (ret)
1361 return ret;
1362
1363 vb = q->bufs[b->index];
1364 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1365 dprintk(1, "%s(): invalid buffer state %d\n", __func__,
1366 vb->state);
1367 return -EINVAL;
1368 }
1369
1370 ret = __buf_prepare(vb, b);
1371 if (!ret) {
1372 /* Fill buffer information for the userspace */
1373 __fill_v4l2_buffer(vb, b);
1374
1375 dprintk(1, "%s() of buffer %d succeeded\n", __func__, vb->v4l2_buf.index);
1376 }
1377 return ret;
1376} 1378}
1377EXPORT_SYMBOL_GPL(vb2_prepare_buf); 1379EXPORT_SYMBOL_GPL(vb2_prepare_buf);
1378 1380
1379static int __vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b, 1381/**
1380 struct vb2_buffer *vb) 1382 * vb2_start_streaming() - Attempt to start streaming.
1383 * @q: videobuf2 queue
1384 *
1385 * If there are not enough buffers, then retry_start_streaming is set to
1386 * 1 and 0 is returned. The next time a buffer is queued and
1387 * retry_start_streaming is 1, this function will be called again to
1388 * retry starting the DMA engine.
1389 */
1390static int vb2_start_streaming(struct vb2_queue *q)
1381{ 1391{
1382 int ret; 1392 int ret;
1383 1393
1394 /* Tell the driver to start streaming */
1395 ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
1396
1397 /*
1398 * If there are not enough buffers queued to start streaming, then
1399 * the start_streaming operation will return -ENOBUFS and you have to
1400 * retry when the next buffer is queued.
1401 */
1402 if (ret == -ENOBUFS) {
1403 dprintk(1, "qbuf: not enough buffers, retry when more buffers are queued.\n");
1404 q->retry_start_streaming = 1;
1405 return 0;
1406 }
1407 if (ret)
1408 dprintk(1, "qbuf: driver refused to start streaming\n");
1409 else
1410 q->retry_start_streaming = 0;
1411 return ret;
1412}
1413
1414static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
1415{
1416 int ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
1417 struct vb2_buffer *vb;
1418
1419 if (ret)
1420 return ret;
1421
1422 vb = q->bufs[b->index];
1423 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1424 dprintk(1, "%s(): invalid buffer state %d\n", __func__,
1425 vb->state);
1426 return -EINVAL;
1427 }
1428
1384 switch (vb->state) { 1429 switch (vb->state) {
1385 case VB2_BUF_STATE_DEQUEUED: 1430 case VB2_BUF_STATE_DEQUEUED:
1386 ret = __buf_prepare(vb, b); 1431 ret = __buf_prepare(vb, b);
1387 if (ret) 1432 if (ret)
1388 return ret; 1433 return ret;
1434 break;
1389 case VB2_BUF_STATE_PREPARED: 1435 case VB2_BUF_STATE_PREPARED:
1390 break; 1436 break;
1437 case VB2_BUF_STATE_PREPARING:
1438 dprintk(1, "qbuf: buffer still being prepared\n");
1439 return -EINVAL;
1391 default: 1440 default:
1392 dprintk(1, "qbuf: buffer already in use\n"); 1441 dprintk(1, "qbuf: buffer already in use\n");
1393 return -EINVAL; 1442 return -EINVAL;
@@ -1407,6 +1456,16 @@ static int __vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b,
1407 if (q->streaming) 1456 if (q->streaming)
1408 __enqueue_in_driver(vb); 1457 __enqueue_in_driver(vb);
1409 1458
1459 /* Fill buffer information for the userspace */
1460 __fill_v4l2_buffer(vb, b);
1461
1462 if (q->retry_start_streaming) {
1463 ret = vb2_start_streaming(q);
1464 if (ret)
1465 return ret;
1466 }
1467
1468 dprintk(1, "%s() of buffer %d succeeded\n", __func__, vb->v4l2_buf.index);
1410 return 0; 1469 return 0;
1411} 1470}
1412 1471
@@ -1429,7 +1488,12 @@ static int __vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b,
1429 */ 1488 */
1430int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) 1489int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
1431{ 1490{
1432 return vb2_queue_or_prepare_buf(q, b, "qbuf", __vb2_qbuf); 1491 if (q->fileio) {
1492 dprintk(1, "%s(): file io in progress\n", __func__);
1493 return -EBUSY;
1494 }
1495
1496 return vb2_internal_qbuf(q, b);
1433} 1497}
1434EXPORT_SYMBOL_GPL(vb2_qbuf); 1498EXPORT_SYMBOL_GPL(vb2_qbuf);
1435 1499
@@ -1550,7 +1614,8 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q)
1550 return -EINVAL; 1614 return -EINVAL;
1551 } 1615 }
1552 1616
1553 wait_event(q->done_wq, !atomic_read(&q->queued_count)); 1617 if (!q->retry_start_streaming)
1618 wait_event(q->done_wq, !atomic_read(&q->queued_count));
1554 return 0; 1619 return 0;
1555} 1620}
1556EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers); 1621EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
@@ -1579,37 +1644,11 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
1579 } 1644 }
1580} 1645}
1581 1646
1582/** 1647static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1583 * vb2_dqbuf() - Dequeue a buffer to the userspace
1584 * @q: videobuf2 queue
1585 * @b: buffer structure passed from userspace to vidioc_dqbuf handler
1586 * in driver
1587 * @nonblocking: if true, this call will not sleep waiting for a buffer if no
1588 * buffers ready for dequeuing are present. Normally the driver
1589 * would be passing (file->f_flags & O_NONBLOCK) here
1590 *
1591 * Should be called from vidioc_dqbuf ioctl handler of a driver.
1592 * This function:
1593 * 1) verifies the passed buffer,
1594 * 2) calls buf_finish callback in the driver (if provided), in which
1595 * driver can perform any additional operations that may be required before
1596 * returning the buffer to userspace, such as cache sync,
1597 * 3) the buffer struct members are filled with relevant information for
1598 * the userspace.
1599 *
1600 * The return values from this function are intended to be directly returned
1601 * from vidioc_dqbuf handler in driver.
1602 */
1603int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1604{ 1648{
1605 struct vb2_buffer *vb = NULL; 1649 struct vb2_buffer *vb = NULL;
1606 int ret; 1650 int ret;
1607 1651
1608 if (q->fileio) {
1609 dprintk(1, "dqbuf: file io in progress\n");
1610 return -EBUSY;
1611 }
1612
1613 if (b->type != q->type) { 1652 if (b->type != q->type) {
1614 dprintk(1, "dqbuf: invalid buffer type\n"); 1653 dprintk(1, "dqbuf: invalid buffer type\n");
1615 return -EINVAL; 1654 return -EINVAL;
@@ -1648,6 +1687,36 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1648 1687
1649 return 0; 1688 return 0;
1650} 1689}
1690
1691/**
1692 * vb2_dqbuf() - Dequeue a buffer to the userspace
1693 * @q: videobuf2 queue
1694 * @b: buffer structure passed from userspace to vidioc_dqbuf handler
1695 * in driver
1696 * @nonblocking: if true, this call will not sleep waiting for a buffer if no
1697 * buffers ready for dequeuing are present. Normally the driver
1698 * would be passing (file->f_flags & O_NONBLOCK) here
1699 *
1700 * Should be called from vidioc_dqbuf ioctl handler of a driver.
1701 * This function:
1702 * 1) verifies the passed buffer,
1703 * 2) calls buf_finish callback in the driver (if provided), in which
1704 * driver can perform any additional operations that may be required before
1705 * returning the buffer to userspace, such as cache sync,
1706 * 3) the buffer struct members are filled with relevant information for
1707 * the userspace.
1708 *
1709 * The return values from this function are intended to be directly returned
1710 * from vidioc_dqbuf handler in driver.
1711 */
1712int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1713{
1714 if (q->fileio) {
1715 dprintk(1, "dqbuf: file io in progress\n");
1716 return -EBUSY;
1717 }
1718 return vb2_internal_dqbuf(q, b, nonblocking);
1719}
1651EXPORT_SYMBOL_GPL(vb2_dqbuf); 1720EXPORT_SYMBOL_GPL(vb2_dqbuf);
1652 1721
1653/** 1722/**
@@ -1660,6 +1729,11 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
1660{ 1729{
1661 unsigned int i; 1730 unsigned int i;
1662 1731
1732 if (q->retry_start_streaming) {
1733 q->retry_start_streaming = 0;
1734 q->streaming = 0;
1735 }
1736
1663 /* 1737 /*
1664 * Tell driver to stop all transactions and release all queued 1738 * Tell driver to stop all transactions and release all queued
1665 * buffers. 1739 * buffers.
@@ -1687,37 +1761,19 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
1687 __vb2_dqbuf(q->bufs[i]); 1761 __vb2_dqbuf(q->bufs[i]);
1688} 1762}
1689 1763
1690/** 1764static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1691 * vb2_streamon - start streaming
1692 * @q: videobuf2 queue
1693 * @type: type argument passed from userspace to vidioc_streamon handler
1694 *
1695 * Should be called from vidioc_streamon handler of a driver.
1696 * This function:
1697 * 1) verifies current state
1698 * 2) passes any previously queued buffers to the driver and starts streaming
1699 *
1700 * The return values from this function are intended to be directly returned
1701 * from vidioc_streamon handler in the driver.
1702 */
1703int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1704{ 1765{
1705 struct vb2_buffer *vb; 1766 struct vb2_buffer *vb;
1706 int ret; 1767 int ret;
1707 1768
1708 if (q->fileio) {
1709 dprintk(1, "streamon: file io in progress\n");
1710 return -EBUSY;
1711 }
1712
1713 if (type != q->type) { 1769 if (type != q->type) {
1714 dprintk(1, "streamon: invalid stream type\n"); 1770 dprintk(1, "streamon: invalid stream type\n");
1715 return -EINVAL; 1771 return -EINVAL;
1716 } 1772 }
1717 1773
1718 if (q->streaming) { 1774 if (q->streaming) {
1719 dprintk(1, "streamon: already streaming\n"); 1775 dprintk(3, "streamon successful: already streaming\n");
1720 return -EBUSY; 1776 return 0;
1721 } 1777 }
1722 1778
1723 /* 1779 /*
@@ -1727,12 +1783,9 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1727 list_for_each_entry(vb, &q->queued_list, queued_entry) 1783 list_for_each_entry(vb, &q->queued_list, queued_entry)
1728 __enqueue_in_driver(vb); 1784 __enqueue_in_driver(vb);
1729 1785
1730 /* 1786 /* Tell driver to start streaming. */
1731 * Let driver notice that streaming state has been enabled. 1787 ret = vb2_start_streaming(q);
1732 */
1733 ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
1734 if (ret) { 1788 if (ret) {
1735 dprintk(1, "streamon: driver refused to start streaming\n");
1736 __vb2_queue_cancel(q); 1789 __vb2_queue_cancel(q);
1737 return ret; 1790 return ret;
1738 } 1791 }
@@ -1742,39 +1795,40 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1742 dprintk(3, "Streamon successful\n"); 1795 dprintk(3, "Streamon successful\n");
1743 return 0; 1796 return 0;
1744} 1797}
1745EXPORT_SYMBOL_GPL(vb2_streamon);
1746
1747 1798
1748/** 1799/**
1749 * vb2_streamoff - stop streaming 1800 * vb2_streamon - start streaming
1750 * @q: videobuf2 queue 1801 * @q: videobuf2 queue
1751 * @type: type argument passed from userspace to vidioc_streamoff handler 1802 * @type: type argument passed from userspace to vidioc_streamon handler
1752 * 1803 *
1753 * Should be called from vidioc_streamoff handler of a driver. 1804 * Should be called from vidioc_streamon handler of a driver.
1754 * This function: 1805 * This function:
1755 * 1) verifies current state, 1806 * 1) verifies current state
1756 * 2) stop streaming and dequeues any queued buffers, including those previously 1807 * 2) passes any previously queued buffers to the driver and starts streaming
1757 * passed to the driver (after waiting for the driver to finish).
1758 * 1808 *
1759 * This call can be used for pausing playback.
1760 * The return values from this function are intended to be directly returned 1809 * The return values from this function are intended to be directly returned
1761 * from vidioc_streamoff handler in the driver 1810 * from vidioc_streamon handler in the driver.
1762 */ 1811 */
1763int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) 1812int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1764{ 1813{
1765 if (q->fileio) { 1814 if (q->fileio) {
1766 dprintk(1, "streamoff: file io in progress\n"); 1815 dprintk(1, "streamon: file io in progress\n");
1767 return -EBUSY; 1816 return -EBUSY;
1768 } 1817 }
1818 return vb2_internal_streamon(q, type);
1819}
1820EXPORT_SYMBOL_GPL(vb2_streamon);
1769 1821
1822static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
1823{
1770 if (type != q->type) { 1824 if (type != q->type) {
1771 dprintk(1, "streamoff: invalid stream type\n"); 1825 dprintk(1, "streamoff: invalid stream type\n");
1772 return -EINVAL; 1826 return -EINVAL;
1773 } 1827 }
1774 1828
1775 if (!q->streaming) { 1829 if (!q->streaming) {
1776 dprintk(1, "streamoff: not streaming\n"); 1830 dprintk(3, "streamoff successful: not streaming\n");
1777 return -EINVAL; 1831 return 0;
1778 } 1832 }
1779 1833
1780 /* 1834 /*
@@ -1786,6 +1840,30 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
1786 dprintk(3, "Streamoff successful\n"); 1840 dprintk(3, "Streamoff successful\n");
1787 return 0; 1841 return 0;
1788} 1842}
1843
1844/**
1845 * vb2_streamoff - stop streaming
1846 * @q: videobuf2 queue
1847 * @type: type argument passed from userspace to vidioc_streamoff handler
1848 *
1849 * Should be called from vidioc_streamoff handler of a driver.
1850 * This function:
1851 * 1) verifies current state,
1852 * 2) stop streaming and dequeues any queued buffers, including those previously
1853 * passed to the driver (after waiting for the driver to finish).
1854 *
1855 * This call can be used for pausing playback.
1856 * The return values from this function are intended to be directly returned
1857 * from vidioc_streamoff handler in the driver
1858 */
1859int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
1860{
1861 if (q->fileio) {
1862 dprintk(1, "streamoff: file io in progress\n");
1863 return -EBUSY;
1864 }
1865 return vb2_internal_streamoff(q, type);
1866}
1789EXPORT_SYMBOL_GPL(vb2_streamoff); 1867EXPORT_SYMBOL_GPL(vb2_streamoff);
1790 1868
1791/** 1869/**
@@ -2277,15 +2355,16 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
2277 goto err_reqbufs; 2355 goto err_reqbufs;
2278 fileio->bufs[i].queued = 1; 2356 fileio->bufs[i].queued = 1;
2279 } 2357 }
2280 2358 fileio->index = q->num_buffers;
2281 /*
2282 * Start streaming.
2283 */
2284 ret = vb2_streamon(q, q->type);
2285 if (ret)
2286 goto err_reqbufs;
2287 } 2359 }
2288 2360
2361 /*
2362 * Start streaming.
2363 */
2364 ret = vb2_streamon(q, q->type);
2365 if (ret)
2366 goto err_reqbufs;
2367
2289 q->fileio = fileio; 2368 q->fileio = fileio;
2290 2369
2291 return ret; 2370 return ret;
@@ -2308,13 +2387,8 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q)
2308 struct vb2_fileio_data *fileio = q->fileio; 2387 struct vb2_fileio_data *fileio = q->fileio;
2309 2388
2310 if (fileio) { 2389 if (fileio) {
2311 /* 2390 vb2_internal_streamoff(q, q->type);
2312 * Hack fileio context to enable direct calls to vb2 ioctl
2313 * interface.
2314 */
2315 q->fileio = NULL; 2391 q->fileio = NULL;
2316
2317 vb2_streamoff(q, q->type);
2318 fileio->req.count = 0; 2392 fileio->req.count = 0;
2319 vb2_reqbufs(q, &fileio->req); 2393 vb2_reqbufs(q, &fileio->req);
2320 kfree(fileio); 2394 kfree(fileio);
@@ -2358,39 +2432,34 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
2358 fileio = q->fileio; 2432 fileio = q->fileio;
2359 2433
2360 /* 2434 /*
2361 * Hack fileio context to enable direct calls to vb2 ioctl interface.
2362 * The pointer will be restored before returning from this function.
2363 */
2364 q->fileio = NULL;
2365
2366 index = fileio->index;
2367 buf = &fileio->bufs[index];
2368
2369 /*
2370 * Check if we need to dequeue the buffer. 2435 * Check if we need to dequeue the buffer.
2371 */ 2436 */
2372 if (buf->queued) { 2437 index = fileio->index;
2373 struct vb2_buffer *vb; 2438 if (index >= q->num_buffers) {
2374
2375 /* 2439 /*
2376 * Call vb2_dqbuf to get buffer back. 2440 * Call vb2_dqbuf to get buffer back.
2377 */ 2441 */
2378 memset(&fileio->b, 0, sizeof(fileio->b)); 2442 memset(&fileio->b, 0, sizeof(fileio->b));
2379 fileio->b.type = q->type; 2443 fileio->b.type = q->type;
2380 fileio->b.memory = q->memory; 2444 fileio->b.memory = q->memory;
2381 fileio->b.index = index; 2445 ret = vb2_internal_dqbuf(q, &fileio->b, nonblock);
2382 ret = vb2_dqbuf(q, &fileio->b, nonblock);
2383 dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); 2446 dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
2384 if (ret) 2447 if (ret)
2385 goto end; 2448 return ret;
2386 fileio->dq_count += 1; 2449 fileio->dq_count += 1;
2387 2450
2451 index = fileio->b.index;
2452 buf = &fileio->bufs[index];
2453
2388 /* 2454 /*
2389 * Get number of bytes filled by the driver 2455 * Get number of bytes filled by the driver
2390 */ 2456 */
2391 vb = q->bufs[index]; 2457 buf->pos = 0;
2392 buf->size = vb2_get_plane_payload(vb, 0);
2393 buf->queued = 0; 2458 buf->queued = 0;
2459 buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0)
2460 : vb2_plane_size(q->bufs[index], 0);
2461 } else {
2462 buf = &fileio->bufs[index];
2394 } 2463 }
2395 2464
2396 /* 2465 /*
@@ -2412,8 +2481,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
2412 ret = copy_from_user(buf->vaddr + buf->pos, data, count); 2481 ret = copy_from_user(buf->vaddr + buf->pos, data, count);
2413 if (ret) { 2482 if (ret) {
2414 dprintk(3, "file io: error copying data\n"); 2483 dprintk(3, "file io: error copying data\n");
2415 ret = -EFAULT; 2484 return -EFAULT;
2416 goto end;
2417 } 2485 }
2418 2486
2419 /* 2487 /*
@@ -2433,10 +2501,6 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
2433 if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && 2501 if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) &&
2434 fileio->dq_count == 1) { 2502 fileio->dq_count == 1) {
2435 dprintk(3, "file io: read limit reached\n"); 2503 dprintk(3, "file io: read limit reached\n");
2436 /*
2437 * Restore fileio pointer and release the context.
2438 */
2439 q->fileio = fileio;
2440 return __vb2_cleanup_fileio(q); 2504 return __vb2_cleanup_fileio(q);
2441 } 2505 }
2442 2506
@@ -2448,32 +2512,20 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
2448 fileio->b.memory = q->memory; 2512 fileio->b.memory = q->memory;
2449 fileio->b.index = index; 2513 fileio->b.index = index;
2450 fileio->b.bytesused = buf->pos; 2514 fileio->b.bytesused = buf->pos;
2451 ret = vb2_qbuf(q, &fileio->b); 2515 ret = vb2_internal_qbuf(q, &fileio->b);
2452 dprintk(5, "file io: vb2_dbuf result: %d\n", ret); 2516 dprintk(5, "file io: vb2_dbuf result: %d\n", ret);
2453 if (ret) 2517 if (ret)
2454 goto end; 2518 return ret;
2455 2519
2456 /* 2520 /*
2457 * Buffer has been queued, update the status 2521 * Buffer has been queued, update the status
2458 */ 2522 */
2459 buf->pos = 0; 2523 buf->pos = 0;
2460 buf->queued = 1; 2524 buf->queued = 1;
2461 buf->size = q->bufs[0]->v4l2_planes[0].length; 2525 buf->size = vb2_plane_size(q->bufs[index], 0);
2462 fileio->q_count += 1; 2526 fileio->q_count += 1;
2463 2527 if (fileio->index < q->num_buffers)
2464 /* 2528 fileio->index++;
2465 * Switch to the next buffer
2466 */
2467 fileio->index = (index + 1) % q->num_buffers;
2468
2469 /*
2470 * Start streaming if required.
2471 */
2472 if (!read && !q->streaming) {
2473 ret = vb2_streamon(q, q->type);
2474 if (ret)
2475 goto end;
2476 }
2477 } 2529 }
2478 2530
2479 /* 2531 /*
@@ -2481,11 +2533,6 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
2481 */ 2533 */
2482 if (ret == 0) 2534 if (ret == 0)
2483 ret = count; 2535 ret = count;
2484end:
2485 /*
2486 * Restore the fileio context and block vb2 ioctl interface.
2487 */
2488 q->fileio = fileio;
2489 return ret; 2536 return ret;
2490} 2537}
2491 2538
@@ -2649,16 +2696,29 @@ int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
2649} 2696}
2650EXPORT_SYMBOL_GPL(vb2_fop_mmap); 2697EXPORT_SYMBOL_GPL(vb2_fop_mmap);
2651 2698
2652int vb2_fop_release(struct file *file) 2699int _vb2_fop_release(struct file *file, struct mutex *lock)
2653{ 2700{
2654 struct video_device *vdev = video_devdata(file); 2701 struct video_device *vdev = video_devdata(file);
2655 2702
2656 if (file->private_data == vdev->queue->owner) { 2703 if (file->private_data == vdev->queue->owner) {
2704 if (lock)
2705 mutex_lock(lock);
2657 vb2_queue_release(vdev->queue); 2706 vb2_queue_release(vdev->queue);
2658 vdev->queue->owner = NULL; 2707 vdev->queue->owner = NULL;
2708 if (lock)
2709 mutex_unlock(lock);
2659 } 2710 }
2660 return v4l2_fh_release(file); 2711 return v4l2_fh_release(file);
2661} 2712}
2713EXPORT_SYMBOL_GPL(_vb2_fop_release);
2714
2715int vb2_fop_release(struct file *file)
2716{
2717 struct video_device *vdev = video_devdata(file);
2718 struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
2719
2720 return _vb2_fop_release(file, lock);
2721}
2662EXPORT_SYMBOL_GPL(vb2_fop_release); 2722EXPORT_SYMBOL_GPL(vb2_fop_release);
2663 2723
2664ssize_t vb2_fop_write(struct file *file, const char __user *buf, 2724ssize_t vb2_fop_write(struct file *file, const char __user *buf,
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 0d3a8ffe47a3..c779f210d2c6 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -40,6 +40,7 @@ struct vb2_dma_sg_buf {
40 unsigned int num_pages; 40 unsigned int num_pages;
41 atomic_t refcount; 41 atomic_t refcount;
42 struct vb2_vmarea_handler handler; 42 struct vb2_vmarea_handler handler;
43 struct vm_area_struct *vma;
43}; 44};
44 45
45static void vb2_dma_sg_put(void *buf_priv); 46static void vb2_dma_sg_put(void *buf_priv);
@@ -155,12 +156,18 @@ static void vb2_dma_sg_put(void *buf_priv)
155 } 156 }
156} 157}
157 158
159static inline int vma_is_io(struct vm_area_struct *vma)
160{
161 return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
162}
163
158static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, 164static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
159 unsigned long size, int write) 165 unsigned long size, int write)
160{ 166{
161 struct vb2_dma_sg_buf *buf; 167 struct vb2_dma_sg_buf *buf;
162 unsigned long first, last; 168 unsigned long first, last;
163 int num_pages_from_user; 169 int num_pages_from_user;
170 struct vm_area_struct *vma;
164 171
165 buf = kzalloc(sizeof *buf, GFP_KERNEL); 172 buf = kzalloc(sizeof *buf, GFP_KERNEL);
166 if (!buf) 173 if (!buf)
@@ -180,7 +187,38 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
180 if (!buf->pages) 187 if (!buf->pages)
181 goto userptr_fail_alloc_pages; 188 goto userptr_fail_alloc_pages;
182 189
183 num_pages_from_user = get_user_pages(current, current->mm, 190 vma = find_vma(current->mm, vaddr);
191 if (!vma) {
192 dprintk(1, "no vma for address %lu\n", vaddr);
193 goto userptr_fail_find_vma;
194 }
195
196 if (vma->vm_end < vaddr + size) {
197 dprintk(1, "vma at %lu is too small for %lu bytes\n",
198 vaddr, size);
199 goto userptr_fail_find_vma;
200 }
201
202 buf->vma = vb2_get_vma(vma);
203 if (!buf->vma) {
204 dprintk(1, "failed to copy vma\n");
205 goto userptr_fail_find_vma;
206 }
207
208 if (vma_is_io(buf->vma)) {
209 for (num_pages_from_user = 0;
210 num_pages_from_user < buf->num_pages;
211 ++num_pages_from_user, vaddr += PAGE_SIZE) {
212 unsigned long pfn;
213
214 if (follow_pfn(buf->vma, vaddr, &pfn)) {
215 dprintk(1, "no page for address %lu\n", vaddr);
216 break;
217 }
218 buf->pages[num_pages_from_user] = pfn_to_page(pfn);
219 }
220 } else
221 num_pages_from_user = get_user_pages(current, current->mm,
184 vaddr & PAGE_MASK, 222 vaddr & PAGE_MASK,
185 buf->num_pages, 223 buf->num_pages,
186 write, 224 write,
@@ -200,9 +238,12 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
200userptr_fail_alloc_table_from_pages: 238userptr_fail_alloc_table_from_pages:
201userptr_fail_get_user_pages: 239userptr_fail_get_user_pages:
202 dprintk(1, "get_user_pages requested/got: %d/%d]\n", 240 dprintk(1, "get_user_pages requested/got: %d/%d]\n",
203 num_pages_from_user, buf->num_pages); 241 buf->num_pages, num_pages_from_user);
204 while (--num_pages_from_user >= 0) 242 if (!vma_is_io(buf->vma))
205 put_page(buf->pages[num_pages_from_user]); 243 while (--num_pages_from_user >= 0)
244 put_page(buf->pages[num_pages_from_user]);
245 vb2_put_vma(buf->vma);
246userptr_fail_find_vma:
206 kfree(buf->pages); 247 kfree(buf->pages);
207userptr_fail_alloc_pages: 248userptr_fail_alloc_pages:
208 kfree(buf); 249 kfree(buf);
@@ -226,9 +267,11 @@ static void vb2_dma_sg_put_userptr(void *buf_priv)
226 while (--i >= 0) { 267 while (--i >= 0) {
227 if (buf->write) 268 if (buf->write)
228 set_page_dirty_lock(buf->pages[i]); 269 set_page_dirty_lock(buf->pages[i]);
229 put_page(buf->pages[i]); 270 if (!vma_is_io(buf->vma))
271 put_page(buf->pages[i]);
230 } 272 }
231 kfree(buf->pages); 273 kfree(buf->pages);
274 vb2_put_vma(buf->vma);
232 kfree(buf); 275 kfree(buf);
233} 276}
234 277
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 46f1e619cbd8..22b0c9d6f046 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -21,6 +21,8 @@ if STAGING_MEDIA
21# Please keep them in alphabetic order 21# Please keep them in alphabetic order
22source "drivers/staging/media/as102/Kconfig" 22source "drivers/staging/media/as102/Kconfig"
23 23
24source "drivers/staging/media/bcm2048/Kconfig"
25
24source "drivers/staging/media/cxd2099/Kconfig" 26source "drivers/staging/media/cxd2099/Kconfig"
25 27
26source "drivers/staging/media/davinci_vpfe/Kconfig" 28source "drivers/staging/media/davinci_vpfe/Kconfig"
@@ -31,8 +33,14 @@ source "drivers/staging/media/go7007/Kconfig"
31 33
32source "drivers/staging/media/msi3101/Kconfig" 34source "drivers/staging/media/msi3101/Kconfig"
33 35
36source "drivers/staging/media/omap24xx/Kconfig"
37
38source "drivers/staging/media/sn9c102/Kconfig"
39
34source "drivers/staging/media/solo6x10/Kconfig" 40source "drivers/staging/media/solo6x10/Kconfig"
35 41
42source "drivers/staging/media/omap4iss/Kconfig"
43
36# Keep LIRC at the end, as it has sub-menus 44# Keep LIRC at the end, as it has sub-menus
37source "drivers/staging/media/lirc/Kconfig" 45source "drivers/staging/media/lirc/Kconfig"
38 46
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index eb7f30b1ccd8..bedc62aaede6 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_DVB_AS102) += as102/ 1obj-$(CONFIG_DVB_AS102) += as102/
2obj-$(CONFIG_I2C_BCM2048) += bcm2048/
2obj-$(CONFIG_DVB_CXD2099) += cxd2099/ 3obj-$(CONFIG_DVB_CXD2099) += cxd2099/
3obj-$(CONFIG_LIRC_STAGING) += lirc/ 4obj-$(CONFIG_LIRC_STAGING) += lirc/
4obj-$(CONFIG_SOLO6X10) += solo6x10/ 5obj-$(CONFIG_SOLO6X10) += solo6x10/
@@ -6,3 +7,7 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
6obj-$(CONFIG_VIDEO_GO7007) += go7007/ 7obj-$(CONFIG_VIDEO_GO7007) += go7007/
7obj-$(CONFIG_USB_MSI3101) += msi3101/ 8obj-$(CONFIG_USB_MSI3101) += msi3101/
8obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ 9obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
10obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
11obj-$(CONFIG_USB_SN9C102) += sn9c102/
12obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/
13obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
index 8b7bb9547079..09d64cd67502 100644
--- a/drivers/staging/media/as102/as102_drv.c
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -111,8 +111,6 @@ static int as10x_pid_filter(struct as102_dev_t *dev,
111 struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap; 111 struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap;
112 int ret = -EFAULT; 112 int ret = -EFAULT;
113 113
114 ENTER();
115
116 if (mutex_lock_interruptible(&dev->bus_adap.lock)) { 114 if (mutex_lock_interruptible(&dev->bus_adap.lock)) {
117 dprintk(debug, "mutex_lock_interruptible(lock) failed !\n"); 115 dprintk(debug, "mutex_lock_interruptible(lock) failed !\n");
118 return -EBUSY; 116 return -EBUSY;
@@ -133,15 +131,14 @@ static int as10x_pid_filter(struct as102_dev_t *dev,
133 filter.pid = pid; 131 filter.pid = pid;
134 132
135 ret = as10x_cmd_add_PID_filter(bus_adap, &filter); 133 ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
136 dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n", 134 dprintk(debug,
135 "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
137 index, filter.idx, filter.pid, ret); 136 index, filter.idx, filter.pid, ret);
138 break; 137 break;
139 } 138 }
140 } 139 }
141 140
142 mutex_unlock(&dev->bus_adap.lock); 141 mutex_unlock(&dev->bus_adap.lock);
143
144 LEAVE();
145 return ret; 142 return ret;
146} 143}
147 144
@@ -151,8 +148,6 @@ static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
151 struct dvb_demux *demux = dvbdmxfeed->demux; 148 struct dvb_demux *demux = dvbdmxfeed->demux;
152 struct as102_dev_t *as102_dev = demux->priv; 149 struct as102_dev_t *as102_dev = demux->priv;
153 150
154 ENTER();
155
156 if (mutex_lock_interruptible(&as102_dev->sem)) 151 if (mutex_lock_interruptible(&as102_dev->sem))
157 return -ERESTARTSYS; 152 return -ERESTARTSYS;
158 153
@@ -164,7 +159,6 @@ static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
164 ret = as102_start_stream(as102_dev); 159 ret = as102_start_stream(as102_dev);
165 160
166 mutex_unlock(&as102_dev->sem); 161 mutex_unlock(&as102_dev->sem);
167 LEAVE();
168 return ret; 162 return ret;
169} 163}
170 164
@@ -173,8 +167,6 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
173 struct dvb_demux *demux = dvbdmxfeed->demux; 167 struct dvb_demux *demux = dvbdmxfeed->demux;
174 struct as102_dev_t *as102_dev = demux->priv; 168 struct as102_dev_t *as102_dev = demux->priv;
175 169
176 ENTER();
177
178 if (mutex_lock_interruptible(&as102_dev->sem)) 170 if (mutex_lock_interruptible(&as102_dev->sem))
179 return -ERESTARTSYS; 171 return -ERESTARTSYS;
180 172
@@ -186,7 +178,6 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
186 dvbdmxfeed->pid, 0); 178 dvbdmxfeed->pid, 0);
187 179
188 mutex_unlock(&as102_dev->sem); 180 mutex_unlock(&as102_dev->sem);
189 LEAVE();
190 return 0; 181 return 0;
191} 182}
192 183
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h
index b0e5a23bd532..a06837dcc05d 100644
--- a/drivers/staging/media/as102/as102_drv.h
+++ b/drivers/staging/media/as102/as102_drv.h
@@ -38,14 +38,6 @@ extern int elna_enable;
38 printk(args); \ 38 printk(args); \
39 } } while (0) 39 } } while (0)
40 40
41#ifdef TRACE
42#define ENTER() pr_debug(">> enter %s\n", __func__)
43#define LEAVE() pr_debug("<< leave %s\n", __func__)
44#else
45#define ENTER()
46#define LEAVE()
47#endif
48
49#define AS102_DEVICE_MAJOR 192 41#define AS102_DEVICE_MAJOR 192
50 42
51#define AS102_USB_BUF_SIZE 512 43#define AS102_USB_BUF_SIZE 512
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
index 9ce8c9daa2e7..b686b7617cdc 100644
--- a/drivers/staging/media/as102/as102_fe.c
+++ b/drivers/staging/media/as102/as102_fe.c
@@ -34,8 +34,6 @@ static int as102_fe_set_frontend(struct dvb_frontend *fe)
34 struct as102_dev_t *dev; 34 struct as102_dev_t *dev;
35 struct as10x_tune_args tune_args = { 0 }; 35 struct as10x_tune_args tune_args = { 0 };
36 36
37 ENTER();
38
39 dev = (struct as102_dev_t *) fe->tuner_priv; 37 dev = (struct as102_dev_t *) fe->tuner_priv;
40 if (dev == NULL) 38 if (dev == NULL)
41 return -ENODEV; 39 return -ENODEV;
@@ -52,7 +50,6 @@ static int as102_fe_set_frontend(struct dvb_frontend *fe)
52 50
53 mutex_unlock(&dev->bus_adap.lock); 51 mutex_unlock(&dev->bus_adap.lock);
54 52
55 LEAVE();
56 return (ret < 0) ? -EINVAL : 0; 53 return (ret < 0) ? -EINVAL : 0;
57} 54}
58 55
@@ -63,8 +60,6 @@ static int as102_fe_get_frontend(struct dvb_frontend *fe)
63 struct as102_dev_t *dev; 60 struct as102_dev_t *dev;
64 struct as10x_tps tps = { 0 }; 61 struct as10x_tps tps = { 0 };
65 62
66 ENTER();
67
68 dev = (struct as102_dev_t *) fe->tuner_priv; 63 dev = (struct as102_dev_t *) fe->tuner_priv;
69 if (dev == NULL) 64 if (dev == NULL)
70 return -EINVAL; 65 return -EINVAL;
@@ -80,13 +75,11 @@ static int as102_fe_get_frontend(struct dvb_frontend *fe)
80 75
81 mutex_unlock(&dev->bus_adap.lock); 76 mutex_unlock(&dev->bus_adap.lock);
82 77
83 LEAVE();
84 return (ret < 0) ? -EINVAL : 0; 78 return (ret < 0) ? -EINVAL : 0;
85} 79}
86 80
87static int as102_fe_get_tune_settings(struct dvb_frontend *fe, 81static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
88 struct dvb_frontend_tune_settings *settings) { 82 struct dvb_frontend_tune_settings *settings) {
89 ENTER();
90 83
91#if 0 84#if 0
92 dprintk(debug, "step_size = %d\n", settings->step_size); 85 dprintk(debug, "step_size = %d\n", settings->step_size);
@@ -97,7 +90,6 @@ static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
97 90
98 settings->min_delay_ms = 1000; 91 settings->min_delay_ms = 1000;
99 92
100 LEAVE();
101 return 0; 93 return 0;
102} 94}
103 95
@@ -108,8 +100,6 @@ static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
108 struct as102_dev_t *dev; 100 struct as102_dev_t *dev;
109 struct as10x_tune_status tstate = { 0 }; 101 struct as10x_tune_status tstate = { 0 };
110 102
111 ENTER();
112
113 dev = (struct as102_dev_t *) fe->tuner_priv; 103 dev = (struct as102_dev_t *) fe->tuner_priv;
114 if (dev == NULL) 104 if (dev == NULL)
115 return -ENODEV; 105 return -ENODEV;
@@ -151,8 +141,8 @@ static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
151 if (as10x_cmd_get_demod_stats(&dev->bus_adap, 141 if (as10x_cmd_get_demod_stats(&dev->bus_adap,
152 (struct as10x_demod_stats *) &dev->demod_stats) < 0) { 142 (struct as10x_demod_stats *) &dev->demod_stats) < 0) {
153 memset(&dev->demod_stats, 0, sizeof(dev->demod_stats)); 143 memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
154 dprintk(debug, "as10x_cmd_get_demod_stats failed " 144 dprintk(debug,
155 "(probably not tuned)\n"); 145 "as10x_cmd_get_demod_stats failed (probably not tuned)\n");
156 } else { 146 } else {
157 dprintk(debug, 147 dprintk(debug,
158 "demod status: fc: 0x%08x, bad fc: 0x%08x, " 148 "demod status: fc: 0x%08x, bad fc: 0x%08x, "
@@ -168,7 +158,6 @@ static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
168 158
169out: 159out:
170 mutex_unlock(&dev->bus_adap.lock); 160 mutex_unlock(&dev->bus_adap.lock);
171 LEAVE();
172 return ret; 161 return ret;
173} 162}
174 163
@@ -183,15 +172,12 @@ static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
183{ 172{
184 struct as102_dev_t *dev; 173 struct as102_dev_t *dev;
185 174
186 ENTER();
187
188 dev = (struct as102_dev_t *) fe->tuner_priv; 175 dev = (struct as102_dev_t *) fe->tuner_priv;
189 if (dev == NULL) 176 if (dev == NULL)
190 return -ENODEV; 177 return -ENODEV;
191 178
192 *snr = dev->demod_stats.mer; 179 *snr = dev->demod_stats.mer;
193 180
194 LEAVE();
195 return 0; 181 return 0;
196} 182}
197 183
@@ -199,15 +185,12 @@ static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
199{ 185{
200 struct as102_dev_t *dev; 186 struct as102_dev_t *dev;
201 187
202 ENTER();
203
204 dev = (struct as102_dev_t *) fe->tuner_priv; 188 dev = (struct as102_dev_t *) fe->tuner_priv;
205 if (dev == NULL) 189 if (dev == NULL)
206 return -ENODEV; 190 return -ENODEV;
207 191
208 *ber = dev->ber; 192 *ber = dev->ber;
209 193
210 LEAVE();
211 return 0; 194 return 0;
212} 195}
213 196
@@ -216,15 +199,12 @@ static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
216{ 199{
217 struct as102_dev_t *dev; 200 struct as102_dev_t *dev;
218 201
219 ENTER();
220
221 dev = (struct as102_dev_t *) fe->tuner_priv; 202 dev = (struct as102_dev_t *) fe->tuner_priv;
222 if (dev == NULL) 203 if (dev == NULL)
223 return -ENODEV; 204 return -ENODEV;
224 205
225 *strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2); 206 *strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2);
226 207
227 LEAVE();
228 return 0; 208 return 0;
229} 209}
230 210
@@ -232,8 +212,6 @@ static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
232{ 212{
233 struct as102_dev_t *dev; 213 struct as102_dev_t *dev;
234 214
235 ENTER();
236
237 dev = (struct as102_dev_t *) fe->tuner_priv; 215 dev = (struct as102_dev_t *) fe->tuner_priv;
238 if (dev == NULL) 216 if (dev == NULL)
239 return -ENODEV; 217 return -ENODEV;
@@ -243,7 +221,6 @@ static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
243 else 221 else
244 *ucblocks = 0; 222 *ucblocks = 0;
245 223
246 LEAVE();
247 return 0; 224 return 0;
248} 225}
249 226
@@ -252,8 +229,6 @@ static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
252 struct as102_dev_t *dev; 229 struct as102_dev_t *dev;
253 int ret; 230 int ret;
254 231
255 ENTER();
256
257 dev = (struct as102_dev_t *) fe->tuner_priv; 232 dev = (struct as102_dev_t *) fe->tuner_priv;
258 if (dev == NULL) 233 if (dev == NULL)
259 return -ENODEV; 234 return -ENODEV;
@@ -263,7 +238,8 @@ static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
263 238
264 if (acquire) { 239 if (acquire) {
265 if (elna_enable) 240 if (elna_enable)
266 as10x_cmd_set_context(&dev->bus_adap, CONTEXT_LNA, dev->elna_cfg); 241 as10x_cmd_set_context(&dev->bus_adap,
242 CONTEXT_LNA, dev->elna_cfg);
267 243
268 ret = as10x_cmd_turn_on(&dev->bus_adap); 244 ret = as10x_cmd_turn_on(&dev->bus_adap);
269 } else { 245 } else {
@@ -272,7 +248,6 @@ static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
272 248
273 mutex_unlock(&dev->bus_adap.lock); 249 mutex_unlock(&dev->bus_adap.lock);
274 250
275 LEAVE();
276 return ret; 251 return ret;
277} 252}
278 253
@@ -581,8 +556,8 @@ static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args,
581 as102_fe_get_code_rate(params->code_rate_LP); 556 as102_fe_get_code_rate(params->code_rate_LP);
582 } 557 }
583 558
584 dprintk(debug, "\thierarchy: 0x%02x " 559 dprintk(debug,
585 "selected: %s code_rate_%s: 0x%02x\n", 560 "\thierarchy: 0x%02x selected: %s code_rate_%s: 0x%02x\n",
586 tune_args->hierarchy, 561 tune_args->hierarchy,
587 tune_args->hier_select == HIER_HIGH_PRIORITY ? 562 tune_args->hier_select == HIER_HIGH_PRIORITY ?
588 "HP" : "LP", 563 "HP" : "LP",
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
index b9670ee41b4e..f33f752c0aad 100644
--- a/drivers/staging/media/as102/as102_fw.c
+++ b/drivers/staging/media/as102/as102_fw.c
@@ -26,10 +26,10 @@
26#include "as102_drv.h" 26#include "as102_drv.h"
27#include "as102_fw.h" 27#include "as102_fw.h"
28 28
29char as102_st_fw1[] = "as102_data1_st.hex"; 29static const char as102_st_fw1[] = "as102_data1_st.hex";
30char as102_st_fw2[] = "as102_data2_st.hex"; 30static const char as102_st_fw2[] = "as102_data2_st.hex";
31char as102_dt_fw1[] = "as102_data1_dt.hex"; 31static const char as102_dt_fw1[] = "as102_data1_dt.hex";
32char as102_dt_fw2[] = "as102_data2_dt.hex"; 32static const char as102_dt_fw2[] = "as102_data2_dt.hex";
33 33
34static unsigned char atohx(unsigned char *dst, char *src) 34static unsigned char atohx(unsigned char *dst, char *src)
35{ 35{
@@ -109,8 +109,6 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
109 int total_read_bytes = 0, errno = 0; 109 int total_read_bytes = 0, errno = 0;
110 unsigned char addr_has_changed = 0; 110 unsigned char addr_has_changed = 0;
111 111
112 ENTER();
113
114 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) { 112 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
115 int read_bytes = 0, data_len = 0; 113 int read_bytes = 0, data_len = 0;
116 114
@@ -158,7 +156,6 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
158 } 156 }
159 } 157 }
160error: 158error:
161 LEAVE();
162 return (errno == 0) ? total_read_bytes : errno; 159 return (errno == 0) ? total_read_bytes : errno;
163} 160}
164 161
@@ -167,11 +164,9 @@ int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
167 int errno = -EFAULT; 164 int errno = -EFAULT;
168 const struct firmware *firmware = NULL; 165 const struct firmware *firmware = NULL;
169 unsigned char *cmd_buf = NULL; 166 unsigned char *cmd_buf = NULL;
170 char *fw1, *fw2; 167 const char *fw1, *fw2;
171 struct usb_device *dev = bus_adap->usb_dev; 168 struct usb_device *dev = bus_adap->usb_dev;
172 169
173 ENTER();
174
175 /* select fw file to upload */ 170 /* select fw file to upload */
176 if (dual_tuner) { 171 if (dual_tuner) {
177 fw1 = as102_dt_fw1; 172 fw1 = as102_dt_fw1;
@@ -233,6 +228,5 @@ error:
233 kfree(cmd_buf); 228 kfree(cmd_buf);
234 release_firmware(firmware); 229 release_firmware(firmware);
235 230
236 LEAVE();
237 return errno; 231 return errno;
238} 232}
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
index 9f275f020150..e4a69454ebeb 100644
--- a/drivers/staging/media/as102/as102_usb_drv.c
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -92,7 +92,6 @@ static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap,
92 unsigned char *recv_buf, int recv_buf_len) 92 unsigned char *recv_buf, int recv_buf_len)
93{ 93{
94 int ret = 0; 94 int ret = 0;
95 ENTER();
96 95
97 if (send_buf != NULL) { 96 if (send_buf != NULL) {
98 ret = usb_control_msg(bus_adap->usb_dev, 97 ret = usb_control_msg(bus_adap->usb_dev,
@@ -140,7 +139,6 @@ static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap,
140#endif 139#endif
141 } 140 }
142 141
143 LEAVE();
144 return ret; 142 return ret;
145} 143}
146 144
@@ -191,7 +189,7 @@ static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap,
191 return ret ? ret : actual_len; 189 return ret ? ret : actual_len;
192} 190}
193 191
194struct as102_priv_ops_t as102_priv_ops = { 192static struct as102_priv_ops_t as102_priv_ops = {
195 .upload_fw_pkt = as102_send_ep1, 193 .upload_fw_pkt = as102_send_ep1,
196 .xfer_cmd = as102_usb_xfer_cmd, 194 .xfer_cmd = as102_usb_xfer_cmd,
197 .as102_read_ep2 = as102_read_ep2, 195 .as102_read_ep2 = as102_read_ep2,
@@ -240,8 +238,6 @@ static void as102_free_usb_stream_buffer(struct as102_dev_t *dev)
240{ 238{
241 int i; 239 int i;
242 240
243 ENTER();
244
245 for (i = 0; i < MAX_STREAM_URB; i++) 241 for (i = 0; i < MAX_STREAM_URB; i++)
246 usb_free_urb(dev->stream_urb[i]); 242 usb_free_urb(dev->stream_urb[i]);
247 243
@@ -249,15 +245,12 @@ static void as102_free_usb_stream_buffer(struct as102_dev_t *dev)
249 MAX_STREAM_URB * AS102_USB_BUF_SIZE, 245 MAX_STREAM_URB * AS102_USB_BUF_SIZE,
250 dev->stream, 246 dev->stream,
251 dev->dma_addr); 247 dev->dma_addr);
252 LEAVE();
253} 248}
254 249
255static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) 250static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev)
256{ 251{
257 int i, ret = 0; 252 int i, ret = 0;
258 253
259 ENTER();
260
261 dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev, 254 dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev,
262 MAX_STREAM_URB * AS102_USB_BUF_SIZE, 255 MAX_STREAM_URB * AS102_USB_BUF_SIZE,
263 GFP_KERNEL, 256 GFP_KERNEL,
@@ -287,7 +280,6 @@ static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev)
287 280
288 dev->stream_urb[i] = urb; 281 dev->stream_urb[i] = urb;
289 } 282 }
290 LEAVE();
291 return ret; 283 return ret;
292} 284}
293 285
@@ -318,23 +310,17 @@ static void as102_usb_release(struct kref *kref)
318{ 310{
319 struct as102_dev_t *as102_dev; 311 struct as102_dev_t *as102_dev;
320 312
321 ENTER();
322
323 as102_dev = container_of(kref, struct as102_dev_t, kref); 313 as102_dev = container_of(kref, struct as102_dev_t, kref);
324 if (as102_dev != NULL) { 314 if (as102_dev != NULL) {
325 usb_put_dev(as102_dev->bus_adap.usb_dev); 315 usb_put_dev(as102_dev->bus_adap.usb_dev);
326 kfree(as102_dev); 316 kfree(as102_dev);
327 } 317 }
328
329 LEAVE();
330} 318}
331 319
332static void as102_usb_disconnect(struct usb_interface *intf) 320static void as102_usb_disconnect(struct usb_interface *intf)
333{ 321{
334 struct as102_dev_t *as102_dev; 322 struct as102_dev_t *as102_dev;
335 323
336 ENTER();
337
338 /* extract as102_dev_t from usb_device private data */ 324 /* extract as102_dev_t from usb_device private data */
339 as102_dev = usb_get_intfdata(intf); 325 as102_dev = usb_get_intfdata(intf);
340 326
@@ -353,8 +339,6 @@ static void as102_usb_disconnect(struct usb_interface *intf)
353 kref_put(&as102_dev->kref, as102_usb_release); 339 kref_put(&as102_dev->kref, as102_usb_release);
354 340
355 pr_info("%s: device has been disconnected\n", DRIVER_NAME); 341 pr_info("%s: device has been disconnected\n", DRIVER_NAME);
356
357 LEAVE();
358} 342}
359 343
360static int as102_usb_probe(struct usb_interface *intf, 344static int as102_usb_probe(struct usb_interface *intf,
@@ -364,8 +348,6 @@ static int as102_usb_probe(struct usb_interface *intf,
364 struct as102_dev_t *as102_dev; 348 struct as102_dev_t *as102_dev;
365 int i; 349 int i;
366 350
367 ENTER();
368
369 /* This should never actually happen */ 351 /* This should never actually happen */
370 if (ARRAY_SIZE(as102_usb_id_table) != 352 if (ARRAY_SIZE(as102_usb_id_table) !=
371 (sizeof(as102_device_names) / sizeof(const char *))) { 353 (sizeof(as102_device_names) / sizeof(const char *))) {
@@ -419,15 +401,21 @@ static int as102_usb_probe(struct usb_interface *intf,
419 /* request buffer allocation for streaming */ 401 /* request buffer allocation for streaming */
420 ret = as102_alloc_usb_stream_buffer(as102_dev); 402 ret = as102_alloc_usb_stream_buffer(as102_dev);
421 if (ret != 0) 403 if (ret != 0)
422 goto failed; 404 goto failed_stream;
423 405
424 /* register dvb layer */ 406 /* register dvb layer */
425 ret = as102_dvb_register(as102_dev); 407 ret = as102_dvb_register(as102_dev);
408 if (ret != 0)
409 goto failed_dvb;
426 410
427 LEAVE();
428 return ret; 411 return ret;
429 412
413failed_dvb:
414 as102_free_usb_stream_buffer(as102_dev);
415failed_stream:
416 usb_deregister_dev(intf, &as102_usb_class_driver);
430failed: 417failed:
418 usb_put_dev(as102_dev->bus_adap.usb_dev);
431 usb_set_intfdata(intf, NULL); 419 usb_set_intfdata(intf, NULL);
432 kfree(as102_dev); 420 kfree(as102_dev);
433 return ret; 421 return ret;
@@ -439,8 +427,6 @@ static int as102_open(struct inode *inode, struct file *file)
439 struct usb_interface *intf = NULL; 427 struct usb_interface *intf = NULL;
440 struct as102_dev_t *dev = NULL; 428 struct as102_dev_t *dev = NULL;
441 429
442 ENTER();
443
444 /* read minor from inode */ 430 /* read minor from inode */
445 minor = iminor(inode); 431 minor = iminor(inode);
446 432
@@ -467,7 +453,6 @@ static int as102_open(struct inode *inode, struct file *file)
467 kref_get(&dev->kref); 453 kref_get(&dev->kref);
468 454
469exit: 455exit:
470 LEAVE();
471 return ret; 456 return ret;
472} 457}
473 458
@@ -476,15 +461,12 @@ static int as102_release(struct inode *inode, struct file *file)
476 int ret = 0; 461 int ret = 0;
477 struct as102_dev_t *dev = NULL; 462 struct as102_dev_t *dev = NULL;
478 463
479 ENTER();
480
481 dev = file->private_data; 464 dev = file->private_data;
482 if (dev != NULL) { 465 if (dev != NULL) {
483 /* decrement the count on our device */ 466 /* decrement the count on our device */
484 kref_put(&dev->kref, as102_usb_release); 467 kref_put(&dev->kref, as102_usb_release);
485 } 468 }
486 469
487 LEAVE();
488 return ret; 470 return ret;
489} 471}
490 472
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
index a73df10982d0..9e49f15a7c9f 100644
--- a/drivers/staging/media/as102/as10x_cmd.c
+++ b/drivers/staging/media/as102/as10x_cmd.c
@@ -34,8 +34,6 @@ int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap)
34 int error = AS10X_CMD_ERROR; 34 int error = AS10X_CMD_ERROR;
35 struct as10x_cmd_t *pcmd, *prsp; 35 struct as10x_cmd_t *pcmd, *prsp;
36 36
37 ENTER();
38
39 pcmd = adap->cmd; 37 pcmd = adap->cmd;
40 prsp = adap->rsp; 38 prsp = adap->rsp;
41 39
@@ -63,7 +61,6 @@ int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap)
63 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP); 61 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP);
64 62
65out: 63out:
66 LEAVE();
67 return error; 64 return error;
68} 65}
69 66
@@ -78,8 +75,6 @@ int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap)
78 int error = AS10X_CMD_ERROR; 75 int error = AS10X_CMD_ERROR;
79 struct as10x_cmd_t *pcmd, *prsp; 76 struct as10x_cmd_t *pcmd, *prsp;
80 77
81 ENTER();
82
83 pcmd = adap->cmd; 78 pcmd = adap->cmd;
84 prsp = adap->rsp; 79 prsp = adap->rsp;
85 80
@@ -106,7 +101,6 @@ int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap)
106 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP); 101 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP);
107 102
108out: 103out:
109 LEAVE();
110 return error; 104 return error;
111} 105}
112 106
@@ -123,8 +117,6 @@ int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
123 int error = AS10X_CMD_ERROR; 117 int error = AS10X_CMD_ERROR;
124 struct as10x_cmd_t *preq, *prsp; 118 struct as10x_cmd_t *preq, *prsp;
125 119
126 ENTER();
127
128 preq = adap->cmd; 120 preq = adap->cmd;
129 prsp = adap->rsp; 121 prsp = adap->rsp;
130 122
@@ -164,7 +156,6 @@ int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
164 error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP); 156 error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP);
165 157
166out: 158out:
167 LEAVE();
168 return error; 159 return error;
169} 160}
170 161
@@ -181,8 +172,6 @@ int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
181 int error = AS10X_CMD_ERROR; 172 int error = AS10X_CMD_ERROR;
182 struct as10x_cmd_t *preq, *prsp; 173 struct as10x_cmd_t *preq, *prsp;
183 174
184 ENTER();
185
186 preq = adap->cmd; 175 preq = adap->cmd;
187 prsp = adap->rsp; 176 prsp = adap->rsp;
188 177
@@ -220,7 +209,6 @@ int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
220 pstatus->BER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER); 209 pstatus->BER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER);
221 210
222out: 211out:
223 LEAVE();
224 return error; 212 return error;
225} 213}
226 214
@@ -236,8 +224,6 @@ int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
236 int error = AS10X_CMD_ERROR; 224 int error = AS10X_CMD_ERROR;
237 struct as10x_cmd_t *pcmd, *prsp; 225 struct as10x_cmd_t *pcmd, *prsp;
238 226
239 ENTER();
240
241 pcmd = adap->cmd; 227 pcmd = adap->cmd;
242 prsp = adap->rsp; 228 prsp = adap->rsp;
243 229
@@ -281,7 +267,6 @@ int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
281 ptps->cell_ID = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID); 267 ptps->cell_ID = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID);
282 268
283out: 269out:
284 LEAVE();
285 return error; 270 return error;
286} 271}
287 272
@@ -298,8 +283,6 @@ int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap,
298 int error = AS10X_CMD_ERROR; 283 int error = AS10X_CMD_ERROR;
299 struct as10x_cmd_t *pcmd, *prsp; 284 struct as10x_cmd_t *pcmd, *prsp;
300 285
301 ENTER();
302
303 pcmd = adap->cmd; 286 pcmd = adap->cmd;
304 prsp = adap->rsp; 287 prsp = adap->rsp;
305 288
@@ -343,7 +326,6 @@ int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap,
343 prsp->body.get_demod_stats.rsp.stats.has_started; 326 prsp->body.get_demod_stats.rsp.stats.has_started;
344 327
345out: 328out:
346 LEAVE();
347 return error; 329 return error;
348} 330}
349 331
@@ -361,8 +343,6 @@ int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
361 int error = AS10X_CMD_ERROR; 343 int error = AS10X_CMD_ERROR;
362 struct as10x_cmd_t *pcmd, *prsp; 344 struct as10x_cmd_t *pcmd, *prsp;
363 345
364 ENTER();
365
366 pcmd = adap->cmd; 346 pcmd = adap->cmd;
367 prsp = adap->rsp; 347 prsp = adap->rsp;
368 348
@@ -397,7 +377,6 @@ int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
397 *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready; 377 *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
398 378
399out: 379out:
400 LEAVE();
401 return error; 380 return error;
402} 381}
403 382
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c
index 4a2bbd766655..b1e300d88753 100644
--- a/drivers/staging/media/as102/as10x_cmd_cfg.c
+++ b/drivers/staging/media/as102/as10x_cmd_cfg.c
@@ -40,8 +40,6 @@ int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
40 int error; 40 int error;
41 struct as10x_cmd_t *pcmd, *prsp; 41 struct as10x_cmd_t *pcmd, *prsp;
42 42
43 ENTER();
44
45 pcmd = adap->cmd; 43 pcmd = adap->cmd;
46 prsp = adap->rsp; 44 prsp = adap->rsp;
47 45
@@ -81,7 +79,6 @@ int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
81 } 79 }
82 80
83out: 81out:
84 LEAVE();
85 return error; 82 return error;
86} 83}
87 84
@@ -99,8 +96,6 @@ int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
99 int error; 96 int error;
100 struct as10x_cmd_t *pcmd, *prsp; 97 struct as10x_cmd_t *pcmd, *prsp;
101 98
102 ENTER();
103
104 pcmd = adap->cmd; 99 pcmd = adap->cmd;
105 prsp = adap->rsp; 100 prsp = adap->rsp;
106 101
@@ -136,7 +131,6 @@ int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
136 error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP); 131 error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
137 132
138out: 133out:
139 LEAVE();
140 return error; 134 return error;
141} 135}
142 136
@@ -156,8 +150,6 @@ int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode)
156 int error; 150 int error;
157 struct as10x_cmd_t *pcmd, *prsp; 151 struct as10x_cmd_t *pcmd, *prsp;
158 152
159 ENTER();
160
161 pcmd = adap->cmd; 153 pcmd = adap->cmd;
162 prsp = adap->rsp; 154 prsp = adap->rsp;
163 155
@@ -188,7 +180,6 @@ int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode)
188 error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP); 180 error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP);
189 181
190out: 182out:
191 LEAVE();
192 return error; 183 return error;
193} 184}
194 185
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c
index 6d000f60fb0e..1088ca1fe92f 100644
--- a/drivers/staging/media/as102/as10x_cmd_stream.c
+++ b/drivers/staging/media/as102/as10x_cmd_stream.c
@@ -34,8 +34,6 @@ int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
34 int error; 34 int error;
35 struct as10x_cmd_t *pcmd, *prsp; 35 struct as10x_cmd_t *pcmd, *prsp;
36 36
37 ENTER();
38
39 pcmd = adap->cmd; 37 pcmd = adap->cmd;
40 prsp = adap->rsp; 38 prsp = adap->rsp;
41 39
@@ -77,7 +75,6 @@ int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
77 } 75 }
78 76
79out: 77out:
80 LEAVE();
81 return error; 78 return error;
82} 79}
83 80
@@ -94,8 +91,6 @@ int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
94 int error; 91 int error;
95 struct as10x_cmd_t *pcmd, *prsp; 92 struct as10x_cmd_t *pcmd, *prsp;
96 93
97 ENTER();
98
99 pcmd = adap->cmd; 94 pcmd = adap->cmd;
100 prsp = adap->rsp; 95 prsp = adap->rsp;
101 96
@@ -126,7 +121,6 @@ int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
126 error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP); 121 error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
127 122
128out: 123out:
129 LEAVE();
130 return error; 124 return error;
131} 125}
132 126
@@ -141,8 +135,6 @@ int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap)
141 int error; 135 int error;
142 struct as10x_cmd_t *pcmd, *prsp; 136 struct as10x_cmd_t *pcmd, *prsp;
143 137
144 ENTER();
145
146 pcmd = adap->cmd; 138 pcmd = adap->cmd;
147 prsp = adap->rsp; 139 prsp = adap->rsp;
148 140
@@ -172,7 +164,6 @@ int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap)
172 error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP); 164 error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
173 165
174out: 166out:
175 LEAVE();
176 return error; 167 return error;
177} 168}
178 169
@@ -187,8 +178,6 @@ int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap)
187 int8_t error; 178 int8_t error;
188 struct as10x_cmd_t *pcmd, *prsp; 179 struct as10x_cmd_t *pcmd, *prsp;
189 180
190 ENTER();
191
192 pcmd = adap->cmd; 181 pcmd = adap->cmd;
193 prsp = adap->rsp; 182 prsp = adap->rsp;
194 183
@@ -218,6 +207,5 @@ int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap)
218 error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP); 207 error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
219 208
220out: 209out:
221 LEAVE();
222 return error; 210 return error;
223} 211}
diff --git a/drivers/staging/media/bcm2048/Kconfig b/drivers/staging/media/bcm2048/Kconfig
new file mode 100644
index 000000000000..a9fc6e186494
--- /dev/null
+++ b/drivers/staging/media/bcm2048/Kconfig
@@ -0,0 +1,13 @@
1#
2# Multimedia Video device configuration
3#
4
5config I2C_BCM2048
6 tristate "Broadcom BCM2048 FM Radio Receiver support"
7 depends on I2C && VIDEO_V4L2 && RADIO_ADAPTERS
8 ---help---
9 Say Y here if you want support to BCM2048 FM Radio Receiver.
10 This device driver supports only i2c bus.
11
12 To compile this driver as a module, choose M here: the
13 module will be called radio-bcm2048.
diff --git a/drivers/staging/media/bcm2048/Makefile b/drivers/staging/media/bcm2048/Makefile
new file mode 100644
index 000000000000..b4f5663d1408
--- /dev/null
+++ b/drivers/staging/media/bcm2048/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_I2C_BCM2048) += radio-bcm2048.o
diff --git a/drivers/staging/media/bcm2048/TODO b/drivers/staging/media/bcm2048/TODO
new file mode 100644
index 000000000000..051f85dbe89e
--- /dev/null
+++ b/drivers/staging/media/bcm2048/TODO
@@ -0,0 +1,24 @@
1TODO:
2
3From the initial code review:
4
5The main thing you need to do is to implement all the controls using the
6control framework (see Documentation/video4linux/v4l2-controls.txt).
7Most drivers are by now converted to the control framework, so you will
8find many examples of how to do this in drivers/media/radio.
9
10The sysfs stuff should be replaced by controls as well. A lot of the RDS
11support is now available as controls (although there may well be some
12missing features, but that is easy enough to add). Since the RDS data is
13actually read() from the device I am not sure whether the RDS
14properties/controls should be there at all.
15
16Correct Coding Style, as this driver also violates several Style
17rules, and do evil tricks, like returning from a function inside a
18macro.
19
20Finally this driver should probably be split up into two parts: one
21v4l2_subdev-based core driver and one platform driver. See e.g.
22radio-si4713/si4713-i2c.c as a good example. But I would wait with that
23until the rest of the driver is cleaned up. Then I have a better idea of
24whether this is necessary or not.
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c
new file mode 100644
index 000000000000..b2cd3a85166d
--- /dev/null
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.c
@@ -0,0 +1,2744 @@
1/*
2 * drivers/staging/media/radio-bcm2048.c
3 *
4 * Driver for I2C Broadcom BCM2048 FM Radio Receiver:
5 *
6 * Copyright (C) Nokia Corporation
7 * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
8 *
9 * Copyright (C) Nils Faerber <nils.faerber@kernelconcepts.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26/*
27 * History:
28 * Eero Nurkkala <ext-eero.nurkkala@nokia.com>
29 * Version 0.0.1
30 * - Initial implementation
31 * 2010-02-21 Nils Faerber <nils.faerber@kernelconcepts.de>
32 * Version 0.0.2
33 * - Add support for interrupt driven rds data reading
34 */
35
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/init.h>
39#include <linux/version.h>
40#include <linux/interrupt.h>
41#include <linux/sysfs.h>
42#include <linux/completion.h>
43#include <linux/delay.h>
44#include <linux/i2c.h>
45#include <linux/videodev2.h>
46#include <linux/mutex.h>
47#include <linux/slab.h>
48#include <media/v4l2-common.h>
49#include <media/v4l2-ioctl.h>
50#include "radio-bcm2048.h"
51
52/* driver definitions */
53#define BCM2048_DRIVER_AUTHOR "Eero Nurkkala <ext-eero.nurkkala@nokia.com>"
54#define BCM2048_DRIVER_NAME BCM2048_NAME
55#define BCM2048_DRIVER_VERSION KERNEL_VERSION(0, 0, 1)
56#define BCM2048_DRIVER_CARD "Broadcom bcm2048 FM Radio Receiver"
57#define BCM2048_DRIVER_DESC "I2C driver for BCM2048 FM Radio Receiver"
58
59/* I2C Control Registers */
60#define BCM2048_I2C_FM_RDS_SYSTEM 0x00
61#define BCM2048_I2C_FM_CTRL 0x01
62#define BCM2048_I2C_RDS_CTRL0 0x02
63#define BCM2048_I2C_RDS_CTRL1 0x03
64#define BCM2048_I2C_FM_AUDIO_PAUSE 0x04
65#define BCM2048_I2C_FM_AUDIO_CTRL0 0x05
66#define BCM2048_I2C_FM_AUDIO_CTRL1 0x06
67#define BCM2048_I2C_FM_SEARCH_CTRL0 0x07
68#define BCM2048_I2C_FM_SEARCH_CTRL1 0x08
69#define BCM2048_I2C_FM_SEARCH_TUNE_MODE 0x09
70#define BCM2048_I2C_FM_FREQ0 0x0a
71#define BCM2048_I2C_FM_FREQ1 0x0b
72#define BCM2048_I2C_FM_AF_FREQ0 0x0c
73#define BCM2048_I2C_FM_AF_FREQ1 0x0d
74#define BCM2048_I2C_FM_CARRIER 0x0e
75#define BCM2048_I2C_FM_RSSI 0x0f
76#define BCM2048_I2C_FM_RDS_MASK0 0x10
77#define BCM2048_I2C_FM_RDS_MASK1 0x11
78#define BCM2048_I2C_FM_RDS_FLAG0 0x12
79#define BCM2048_I2C_FM_RDS_FLAG1 0x13
80#define BCM2048_I2C_RDS_WLINE 0x14
81#define BCM2048_I2C_RDS_BLKB_MATCH0 0x16
82#define BCM2048_I2C_RDS_BLKB_MATCH1 0x17
83#define BCM2048_I2C_RDS_BLKB_MASK0 0x18
84#define BCM2048_I2C_RDS_BLKB_MASK1 0x19
85#define BCM2048_I2C_RDS_PI_MATCH0 0x1a
86#define BCM2048_I2C_RDS_PI_MATCH1 0x1b
87#define BCM2048_I2C_RDS_PI_MASK0 0x1c
88#define BCM2048_I2C_RDS_PI_MASK1 0x1d
89#define BCM2048_I2C_SPARE1 0x20
90#define BCM2048_I2C_SPARE2 0x21
91#define BCM2048_I2C_FM_RDS_REV 0x28
92#define BCM2048_I2C_SLAVE_CONFIGURATION 0x29
93#define BCM2048_I2C_RDS_DATA 0x80
94#define BCM2048_I2C_FM_BEST_TUNE_MODE 0x90
95
96/* BCM2048_I2C_FM_RDS_SYSTEM */
97#define BCM2048_FM_ON 0x01
98#define BCM2048_RDS_ON 0x02
99
100/* BCM2048_I2C_FM_CTRL */
101#define BCM2048_BAND_SELECT 0x01
102#define BCM2048_STEREO_MONO_AUTO_SELECT 0x02
103#define BCM2048_STEREO_MONO_MANUAL_SELECT 0x04
104#define BCM2048_STEREO_MONO_BLEND_SWITCH 0x08
105#define BCM2048_HI_LO_INJECTION 0x10
106
107/* BCM2048_I2C_RDS_CTRL0 */
108#define BCM2048_RBDS_RDS_SELECT 0x01
109#define BCM2048_FLUSH_FIFO 0x02
110
111/* BCM2048_I2C_FM_AUDIO_PAUSE */
112#define BCM2048_AUDIO_PAUSE_RSSI_TRESH 0x0f
113#define BCM2048_AUDIO_PAUSE_DURATION 0xf0
114
115/* BCM2048_I2C_FM_AUDIO_CTRL0 */
116#define BCM2048_RF_MUTE 0x01
117#define BCM2048_MANUAL_MUTE 0x02
118#define BCM2048_DAC_OUTPUT_LEFT 0x04
119#define BCM2048_DAC_OUTPUT_RIGHT 0x08
120#define BCM2048_AUDIO_ROUTE_DAC 0x10
121#define BCM2048_AUDIO_ROUTE_I2S 0x20
122#define BCM2048_DE_EMPHASIS_SELECT 0x40
123#define BCM2048_AUDIO_BANDWIDTH_SELECT 0x80
124
125/* BCM2048_I2C_FM_SEARCH_CTRL0 */
126#define BCM2048_SEARCH_RSSI_THRESHOLD 0x7f
127#define BCM2048_SEARCH_DIRECTION 0x80
128
129/* BCM2048_I2C_FM_SEARCH_TUNE_MODE */
130#define BCM2048_FM_AUTO_SEARCH 0x03
131
132/* BCM2048_I2C_FM_RSSI */
133#define BCM2048_RSSI_VALUE 0xff
134
135/* BCM2048_I2C_FM_RDS_MASK0 */
136/* BCM2048_I2C_FM_RDS_MASK1 */
137#define BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED 0x01
138#define BCM2048_FM_FLAG_SEARCH_TUNE_FAIL 0x02
139#define BCM2048_FM_FLAG_RSSI_LOW 0x04
140#define BCM2048_FM_FLAG_CARRIER_ERROR_HIGH 0x08
141#define BCM2048_FM_FLAG_AUDIO_PAUSE_INDICATION 0x10
142#define BCM2048_FLAG_STEREO_DETECTED 0x20
143#define BCM2048_FLAG_STEREO_ACTIVE 0x40
144
145/* BCM2048_I2C_RDS_DATA */
146#define BCM2048_SLAVE_ADDRESS 0x3f
147#define BCM2048_SLAVE_ENABLE 0x80
148
149/* BCM2048_I2C_FM_BEST_TUNE_MODE */
150#define BCM2048_BEST_TUNE_MODE 0x80
151
152#define BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED 0x01
153#define BCM2048_FM_FLAG_SEARCH_TUNE_FAIL 0x02
154#define BCM2048_FM_FLAG_RSSI_LOW 0x04
155#define BCM2048_FM_FLAG_CARRIER_ERROR_HIGH 0x08
156#define BCM2048_FM_FLAG_AUDIO_PAUSE_INDICATION 0x10
157#define BCM2048_FLAG_STEREO_DETECTED 0x20
158#define BCM2048_FLAG_STEREO_ACTIVE 0x40
159
160#define BCM2048_RDS_FLAG_FIFO_WLINE 0x02
161#define BCM2048_RDS_FLAG_B_BLOCK_MATCH 0x08
162#define BCM2048_RDS_FLAG_SYNC_LOST 0x10
163#define BCM2048_RDS_FLAG_PI_MATCH 0x20
164
165#define BCM2048_RDS_MARK_END_BYTE0 0x7C
166#define BCM2048_RDS_MARK_END_BYTEN 0xFF
167
168#define BCM2048_FM_FLAGS_ALL (FM_FLAG_SEARCH_TUNE_FINISHED | \
169 FM_FLAG_SEARCH_TUNE_FAIL | \
170 FM_FLAG_RSSI_LOW | \
171 FM_FLAG_CARRIER_ERROR_HIGH | \
172 FM_FLAG_AUDIO_PAUSE_INDICATION | \
173 FLAG_STEREO_DETECTED | FLAG_STEREO_ACTIVE)
174
175#define BCM2048_RDS_FLAGS_ALL (RDS_FLAG_FIFO_WLINE | \
176 RDS_FLAG_B_BLOCK_MATCH | \
177 RDS_FLAG_SYNC_LOST | RDS_FLAG_PI_MATCH)
178
179#define BCM2048_DEFAULT_TIMEOUT 1500
180#define BCM2048_AUTO_SEARCH_TIMEOUT 3000
181
182
183#define BCM2048_FREQDEV_UNIT 10000
184#define BCM2048_FREQV4L2_MULTI 625
185#define dev_to_v4l2(f) ((f * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI)
186#define v4l2_to_dev(f) ((f * BCM2048_FREQV4L2_MULTI) / BCM2048_FREQDEV_UNIT)
187
188#define msb(x) ((u8)((u16) x >> 8))
189#define lsb(x) ((u8)((u16) x & 0x00FF))
190#define compose_u16(msb, lsb) (((u16)msb << 8) | lsb)
191
192#define BCM2048_DEFAULT_POWERING_DELAY 20
193#define BCM2048_DEFAULT_REGION 0x02
194#define BCM2048_DEFAULT_MUTE 0x01
195#define BCM2048_DEFAULT_RSSI_THRESHOLD 0x64
196#define BCM2048_DEFAULT_RDS_WLINE 0x7E
197
198#define BCM2048_FM_SEARCH_INACTIVE 0x00
199#define BCM2048_FM_PRE_SET_MODE 0x01
200#define BCM2048_FM_AUTO_SEARCH_MODE 0x02
201#define BCM2048_FM_AF_JUMP_MODE 0x03
202
203#define BCM2048_FREQUENCY_BASE 64000
204
205#define BCM2048_POWER_ON 0x01
206#define BCM2048_POWER_OFF 0x00
207
208#define BCM2048_ITEM_ENABLED 0x01
209#define BCM2048_SEARCH_DIRECTION_UP 0x01
210
211#define BCM2048_DE_EMPHASIS_75us 75
212#define BCM2048_DE_EMPHASIS_50us 50
213
214#define BCM2048_SCAN_FAIL 0x00
215#define BCM2048_SCAN_OK 0x01
216
217#define BCM2048_FREQ_ERROR_FLOOR -20
218#define BCM2048_FREQ_ERROR_ROOF 20
219
220/* -60 dB is reported as full signal strenght */
221#define BCM2048_RSSI_LEVEL_BASE -60
222#define BCM2048_RSSI_LEVEL_ROOF -100
223#define BCM2048_RSSI_LEVEL_ROOF_NEG 100
224#define BCM2048_SIGNAL_MULTIPLIER (0xFFFF / \
225 (BCM2048_RSSI_LEVEL_ROOF_NEG + \
226 BCM2048_RSSI_LEVEL_BASE))
227
228#define BCM2048_RDS_FIFO_DUPLE_SIZE 0x03
229#define BCM2048_RDS_CRC_MASK 0x0F
230#define BCM2048_RDS_CRC_NONE 0x00
231#define BCM2048_RDS_CRC_MAX_2BITS 0x04
232#define BCM2048_RDS_CRC_LEAST_2BITS 0x08
233#define BCM2048_RDS_CRC_UNRECOVARABLE 0x0C
234
235#define BCM2048_RDS_BLOCK_MASK 0xF0
236#define BCM2048_RDS_BLOCK_A 0x00
237#define BCM2048_RDS_BLOCK_B 0x10
238#define BCM2048_RDS_BLOCK_C 0x20
239#define BCM2048_RDS_BLOCK_D 0x30
240#define BCM2048_RDS_BLOCK_C_SCORED 0x40
241#define BCM2048_RDS_BLOCK_E 0x60
242
243#define BCM2048_RDS_RT 0x20
244#define BCM2048_RDS_PS 0x00
245
246#define BCM2048_RDS_GROUP_AB_MASK 0x08
247#define BCM2048_RDS_GROUP_A 0x00
248#define BCM2048_RDS_GROUP_B 0x08
249
250#define BCM2048_RDS_RT_AB_MASK 0x10
251#define BCM2048_RDS_RT_A 0x00
252#define BCM2048_RDS_RT_B 0x10
253#define BCM2048_RDS_RT_INDEX 0x0F
254
255#define BCM2048_RDS_PS_INDEX 0x03
256
257struct rds_info {
258 u16 rds_pi;
259#define BCM2048_MAX_RDS_RT (64 + 1)
260 u8 rds_rt[BCM2048_MAX_RDS_RT];
261 u8 rds_rt_group_b;
262 u8 rds_rt_ab;
263#define BCM2048_MAX_RDS_PS (8 + 1)
264 u8 rds_ps[BCM2048_MAX_RDS_PS];
265 u8 rds_ps_group;
266 u8 rds_ps_group_cnt;
267#define BCM2048_MAX_RDS_RADIO_TEXT 255
268 u8 radio_text[BCM2048_MAX_RDS_RADIO_TEXT + 3];
269 u8 text_len;
270};
271
272struct region_info {
273 u32 bottom_frequency;
274 u32 top_frequency;
275 u8 deemphasis;
276 u8 channel_spacing;
277 u8 region;
278};
279
280struct bcm2048_device {
281 struct i2c_client *client;
282 struct video_device *videodev;
283 struct work_struct work;
284 struct completion compl;
285 struct mutex mutex;
286 struct bcm2048_platform_data *platform_data;
287 struct rds_info rds_info;
288 struct region_info region_info;
289 u16 frequency;
290 u8 cache_fm_rds_system;
291 u8 cache_fm_ctrl;
292 u8 cache_fm_audio_ctrl0;
293 u8 cache_fm_search_ctrl0;
294 u8 power_state;
295 u8 rds_state;
296 u8 fifo_size;
297 u8 scan_state;
298 u8 mute_state;
299
300 /* for rds data device read */
301 wait_queue_head_t read_queue;
302 unsigned int users;
303 unsigned char rds_data_available;
304 unsigned int rd_index;
305};
306
307static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */
308module_param(radio_nr, int, 0);
309MODULE_PARM_DESC(radio_nr,
310 "Minor number for radio device (-1 ==> auto assign)");
311
312static struct region_info region_configs[] = {
313 /* USA */
314 {
315 .channel_spacing = 20,
316 .bottom_frequency = 87500,
317 .top_frequency = 108000,
318 .deemphasis = 75,
319 .region = 0,
320 },
321 /* Australia */
322 {
323 .channel_spacing = 20,
324 .bottom_frequency = 87500,
325 .top_frequency = 108000,
326 .deemphasis = 50,
327 .region = 1,
328 },
329 /* Europe */
330 {
331 .channel_spacing = 10,
332 .bottom_frequency = 87500,
333 .top_frequency = 108000,
334 .deemphasis = 50,
335 .region = 2,
336 },
337 /* Japan */
338 {
339 .channel_spacing = 10,
340 .bottom_frequency = 76000,
341 .top_frequency = 90000,
342 .deemphasis = 50,
343 .region = 3,
344 },
345 /* Japan wide band */
346 {
347 .channel_spacing = 10,
348 .bottom_frequency = 76000,
349 .top_frequency = 108000,
350 .deemphasis = 50,
351 .region = 4,
352 },
353};
354
355/*
356 * I2C Interface read / write
357 */
358static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg,
359 unsigned int value)
360{
361 struct i2c_client *client = bdev->client;
362 u8 data[2];
363
364 if (!bdev->power_state) {
365 dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
366 return -EIO;
367 }
368
369 data[0] = reg & 0xff;
370 data[1] = value & 0xff;
371
372 if (i2c_master_send(client, data, 2) == 2) {
373 return 0;
374 } else {
375 dev_err(&bdev->client->dev, "BCM I2C error!\n");
376 dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
377 return -EIO;
378 }
379}
380
381static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg,
382 u8 *value)
383{
384 struct i2c_client *client = bdev->client;
385
386 if (!bdev->power_state) {
387 dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
388 return -EIO;
389 }
390
391 value[0] = i2c_smbus_read_byte_data(client, reg & 0xff);
392
393 return 0;
394}
395
396static int bcm2048_recv_duples(struct bcm2048_device *bdev, unsigned int reg,
397 u8 *value, u8 duples)
398{
399 struct i2c_client *client = bdev->client;
400 struct i2c_adapter *adap = client->adapter;
401 struct i2c_msg msg[2];
402 u8 buf;
403
404 if (!bdev->power_state) {
405 dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
406 return -EIO;
407 }
408
409 buf = reg & 0xff;
410
411 msg[0].addr = client->addr;
412 msg[0].flags = client->flags & I2C_M_TEN;
413 msg[0].len = 1;
414 msg[0].buf = &buf;
415
416 msg[1].addr = client->addr;
417 msg[1].flags = client->flags & I2C_M_TEN;
418 msg[1].flags |= I2C_M_RD;
419 msg[1].len = duples;
420 msg[1].buf = value;
421
422 return i2c_transfer(adap, msg, 2);
423}
424
425/*
426 * BCM2048 - I2C register programming helpers
427 */
428static int bcm2048_set_power_state(struct bcm2048_device *bdev, u8 power)
429{
430 int err = 0;
431
432 mutex_lock(&bdev->mutex);
433
434 if (power) {
435 bdev->power_state = BCM2048_POWER_ON;
436 bdev->cache_fm_rds_system |= BCM2048_FM_ON;
437 } else {
438 bdev->cache_fm_rds_system &= ~BCM2048_FM_ON;
439 }
440
441 /*
442 * Warning! FM cannot be turned off because then
443 * the I2C communications get ruined!
444 * Comment off the "if (power)" when the chip works!
445 */
446 if (power)
447 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
448 bdev->cache_fm_rds_system);
449 msleep(BCM2048_DEFAULT_POWERING_DELAY);
450
451 if (!power)
452 bdev->power_state = BCM2048_POWER_OFF;
453
454 mutex_unlock(&bdev->mutex);
455 return err;
456}
457
458static int bcm2048_get_power_state(struct bcm2048_device *bdev)
459{
460 int err;
461 u8 value;
462
463 mutex_lock(&bdev->mutex);
464
465 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, &value);
466
467 mutex_unlock(&bdev->mutex);
468
469 if (!err && (value & BCM2048_FM_ON))
470 return BCM2048_POWER_ON;
471
472 return err;
473}
474
475static int bcm2048_set_rds_no_lock(struct bcm2048_device *bdev, u8 rds_on)
476{
477 int err;
478 u8 flags;
479
480 bdev->cache_fm_rds_system &= ~BCM2048_RDS_ON;
481
482 if (rds_on) {
483 bdev->cache_fm_rds_system |= BCM2048_RDS_ON;
484 bdev->rds_state = BCM2048_RDS_ON;
485 flags = BCM2048_RDS_FLAG_FIFO_WLINE;
486 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
487 flags);
488 } else {
489 flags = 0;
490 bdev->rds_state = 0;
491 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
492 flags);
493 memset(&bdev->rds_info, 0, sizeof(bdev->rds_info));
494 }
495
496 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
497 bdev->cache_fm_rds_system);
498
499 return err;
500}
501
502static int bcm2048_get_rds_no_lock(struct bcm2048_device *bdev)
503{
504 int err;
505 u8 value;
506
507 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, &value);
508
509 if (!err && (value & BCM2048_RDS_ON))
510 return BCM2048_ITEM_ENABLED;
511
512 return err;
513}
514
515static int bcm2048_set_rds(struct bcm2048_device *bdev, u8 rds_on)
516{
517 int err;
518
519 mutex_lock(&bdev->mutex);
520
521 err = bcm2048_set_rds_no_lock(bdev, rds_on);
522
523 mutex_unlock(&bdev->mutex);
524 return err;
525}
526
527static int bcm2048_get_rds(struct bcm2048_device *bdev)
528{
529 int err;
530
531 mutex_lock(&bdev->mutex);
532
533 err = bcm2048_get_rds_no_lock(bdev);
534
535 mutex_unlock(&bdev->mutex);
536 return err;
537}
538
539static int bcm2048_get_rds_pi(struct bcm2048_device *bdev)
540{
541 return bdev->rds_info.rds_pi;
542}
543
544static int bcm2048_set_fm_automatic_stereo_mono(struct bcm2048_device *bdev,
545 u8 enabled)
546{
547 int err;
548
549 mutex_lock(&bdev->mutex);
550
551 bdev->cache_fm_ctrl &= ~BCM2048_STEREO_MONO_AUTO_SELECT;
552
553 if (enabled)
554 bdev->cache_fm_ctrl |= BCM2048_STEREO_MONO_AUTO_SELECT;
555
556 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
557 bdev->cache_fm_ctrl);
558
559 mutex_unlock(&bdev->mutex);
560 return err;
561}
562
563static int bcm2048_set_fm_hi_lo_injection(struct bcm2048_device *bdev,
564 u8 hi_lo)
565{
566 int err;
567
568 mutex_lock(&bdev->mutex);
569
570 bdev->cache_fm_ctrl &= ~BCM2048_HI_LO_INJECTION;
571
572 if (hi_lo)
573 bdev->cache_fm_ctrl |= BCM2048_HI_LO_INJECTION;
574
575 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
576 bdev->cache_fm_ctrl);
577
578 mutex_unlock(&bdev->mutex);
579 return err;
580}
581
582static int bcm2048_get_fm_hi_lo_injection(struct bcm2048_device *bdev)
583{
584 int err;
585 u8 value;
586
587 mutex_lock(&bdev->mutex);
588
589 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_CTRL, &value);
590
591 mutex_unlock(&bdev->mutex);
592
593 if (!err && (value & BCM2048_HI_LO_INJECTION))
594 return BCM2048_ITEM_ENABLED;
595
596 return err;
597}
598
599static int bcm2048_set_fm_frequency(struct bcm2048_device *bdev, u32 frequency)
600{
601 int err;
602
603 if (frequency < bdev->region_info.bottom_frequency ||
604 frequency > bdev->region_info.top_frequency)
605 return -EDOM;
606
607 frequency -= BCM2048_FREQUENCY_BASE;
608
609 mutex_lock(&bdev->mutex);
610
611 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ0, lsb(frequency));
612 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ1,
613 msb(frequency));
614
615 if (!err)
616 bdev->frequency = frequency;
617
618 mutex_unlock(&bdev->mutex);
619 return err;
620}
621
622static int bcm2048_get_fm_frequency(struct bcm2048_device *bdev)
623{
624 int err;
625 u8 lsb, msb;
626
627 mutex_lock(&bdev->mutex);
628
629 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_FREQ0, &lsb);
630 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_FREQ1, &msb);
631
632 mutex_unlock(&bdev->mutex);
633
634 if (err)
635 return err;
636
637 err = compose_u16(msb, lsb);
638 err += BCM2048_FREQUENCY_BASE;
639
640 return err;
641}
642
643static int bcm2048_set_fm_af_frequency(struct bcm2048_device *bdev,
644 u32 frequency)
645{
646 int err;
647
648 if (frequency < bdev->region_info.bottom_frequency ||
649 frequency > bdev->region_info.top_frequency)
650 return -EDOM;
651
652 frequency -= BCM2048_FREQUENCY_BASE;
653
654 mutex_lock(&bdev->mutex);
655
656 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ0,
657 lsb(frequency));
658 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ1,
659 msb(frequency));
660 if (!err)
661 bdev->frequency = frequency;
662
663 mutex_unlock(&bdev->mutex);
664 return err;
665}
666
667static int bcm2048_get_fm_af_frequency(struct bcm2048_device *bdev)
668{
669 int err;
670 u8 lsb, msb;
671
672 mutex_lock(&bdev->mutex);
673
674 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AF_FREQ0, &lsb);
675 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_AF_FREQ1, &msb);
676
677 mutex_unlock(&bdev->mutex);
678
679 if (err)
680 return err;
681
682 err = compose_u16(msb, lsb);
683 err += BCM2048_FREQUENCY_BASE;
684
685 return err;
686}
687
688static int bcm2048_set_fm_deemphasis(struct bcm2048_device *bdev, int d)
689{
690 int err;
691 u8 deemphasis;
692
693 if (d == BCM2048_DE_EMPHASIS_75us)
694 deemphasis = BCM2048_DE_EMPHASIS_SELECT;
695 else
696 deemphasis = 0;
697
698 mutex_lock(&bdev->mutex);
699
700 bdev->cache_fm_audio_ctrl0 &= ~BCM2048_DE_EMPHASIS_SELECT;
701 bdev->cache_fm_audio_ctrl0 |= deemphasis;
702
703 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
704 bdev->cache_fm_audio_ctrl0);
705
706 if (!err)
707 bdev->region_info.deemphasis = d;
708
709 mutex_unlock(&bdev->mutex);
710
711 return err;
712}
713
714static int bcm2048_get_fm_deemphasis(struct bcm2048_device *bdev)
715{
716 int err;
717 u8 value;
718
719 mutex_lock(&bdev->mutex);
720
721 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
722
723 mutex_unlock(&bdev->mutex);
724
725 if (!err) {
726 if (value & BCM2048_DE_EMPHASIS_SELECT)
727 return BCM2048_DE_EMPHASIS_75us;
728 else
729 return BCM2048_DE_EMPHASIS_50us;
730 }
731
732 return err;
733}
734
735static int bcm2048_set_region(struct bcm2048_device *bdev, u8 region)
736{
737 int err;
738 u32 new_frequency = 0;
739
740 if (region > ARRAY_SIZE(region_configs))
741 return -EINVAL;
742
743 mutex_lock(&bdev->mutex);
744 bdev->region_info = region_configs[region];
745 mutex_unlock(&bdev->mutex);
746
747 if (bdev->frequency < region_configs[region].bottom_frequency ||
748 bdev->frequency > region_configs[region].top_frequency)
749 new_frequency = region_configs[region].bottom_frequency;
750
751 if (new_frequency > 0) {
752 err = bcm2048_set_fm_frequency(bdev, new_frequency);
753
754 if (err)
755 goto done;
756 }
757
758 err = bcm2048_set_fm_deemphasis(bdev,
759 region_configs[region].deemphasis);
760
761done:
762 return err;
763}
764
765static int bcm2048_get_region(struct bcm2048_device *bdev)
766{
767 int err;
768
769 mutex_lock(&bdev->mutex);
770 err = bdev->region_info.region;
771 mutex_unlock(&bdev->mutex);
772
773 return err;
774}
775
776static int bcm2048_set_mute(struct bcm2048_device *bdev, u16 mute)
777{
778 int err;
779
780 mutex_lock(&bdev->mutex);
781
782 bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE);
783
784 if (mute)
785 bdev->cache_fm_audio_ctrl0 |= (BCM2048_RF_MUTE |
786 BCM2048_MANUAL_MUTE);
787
788 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
789 bdev->cache_fm_audio_ctrl0);
790
791 if (!err)
792 bdev->mute_state = mute;
793
794 mutex_unlock(&bdev->mutex);
795 return err;
796}
797
798static int bcm2048_get_mute(struct bcm2048_device *bdev)
799{
800 int err;
801 u8 value;
802
803 mutex_lock(&bdev->mutex);
804
805 if (bdev->power_state) {
806 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
807 &value);
808 if (!err)
809 err = value & (BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE);
810 } else {
811 err = bdev->mute_state;
812 }
813
814 mutex_unlock(&bdev->mutex);
815 return err;
816}
817
818static int bcm2048_set_audio_route(struct bcm2048_device *bdev, u8 route)
819{
820 int err;
821
822 mutex_lock(&bdev->mutex);
823
824 route &= (BCM2048_AUDIO_ROUTE_DAC | BCM2048_AUDIO_ROUTE_I2S);
825 bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_AUDIO_ROUTE_DAC |
826 BCM2048_AUDIO_ROUTE_I2S);
827 bdev->cache_fm_audio_ctrl0 |= route;
828
829 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
830 bdev->cache_fm_audio_ctrl0);
831
832 mutex_unlock(&bdev->mutex);
833 return err;
834}
835
836static int bcm2048_get_audio_route(struct bcm2048_device *bdev)
837{
838 int err;
839 u8 value;
840
841 mutex_lock(&bdev->mutex);
842
843 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
844
845 mutex_unlock(&bdev->mutex);
846
847 if (!err)
848 return value & (BCM2048_AUDIO_ROUTE_DAC |
849 BCM2048_AUDIO_ROUTE_I2S);
850
851 return err;
852}
853
854static int bcm2048_set_dac_output(struct bcm2048_device *bdev, u8 channels)
855{
856 int err;
857
858 mutex_lock(&bdev->mutex);
859
860 bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_DAC_OUTPUT_LEFT |
861 BCM2048_DAC_OUTPUT_RIGHT);
862 bdev->cache_fm_audio_ctrl0 |= channels;
863
864 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
865 bdev->cache_fm_audio_ctrl0);
866
867 mutex_unlock(&bdev->mutex);
868 return err;
869}
870
871static int bcm2048_get_dac_output(struct bcm2048_device *bdev)
872{
873 int err;
874 u8 value;
875
876 mutex_lock(&bdev->mutex);
877
878 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
879
880 mutex_unlock(&bdev->mutex);
881
882 if (!err)
883 return value & (BCM2048_DAC_OUTPUT_LEFT |
884 BCM2048_DAC_OUTPUT_RIGHT);
885
886 return err;
887}
888
889static int bcm2048_set_fm_search_rssi_threshold(struct bcm2048_device *bdev,
890 u8 threshold)
891{
892 int err;
893
894 mutex_lock(&bdev->mutex);
895
896 threshold &= BCM2048_SEARCH_RSSI_THRESHOLD;
897 bdev->cache_fm_search_ctrl0 &= ~BCM2048_SEARCH_RSSI_THRESHOLD;
898 bdev->cache_fm_search_ctrl0 |= threshold;
899
900 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0,
901 bdev->cache_fm_search_ctrl0);
902
903 mutex_unlock(&bdev->mutex);
904 return err;
905}
906
907static int bcm2048_get_fm_search_rssi_threshold(struct bcm2048_device *bdev)
908{
909 int err;
910 u8 value;
911
912 mutex_lock(&bdev->mutex);
913
914 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, &value);
915
916 mutex_unlock(&bdev->mutex);
917
918 if (!err)
919 return value & BCM2048_SEARCH_RSSI_THRESHOLD;
920
921 return err;
922}
923
924static int bcm2048_set_fm_search_mode_direction(struct bcm2048_device *bdev,
925 u8 direction)
926{
927 int err;
928
929 mutex_lock(&bdev->mutex);
930
931 bdev->cache_fm_search_ctrl0 &= ~BCM2048_SEARCH_DIRECTION;
932
933 if (direction)
934 bdev->cache_fm_search_ctrl0 |= BCM2048_SEARCH_DIRECTION;
935
936 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0,
937 bdev->cache_fm_search_ctrl0);
938
939 mutex_unlock(&bdev->mutex);
940 return err;
941}
942
943static int bcm2048_get_fm_search_mode_direction(struct bcm2048_device *bdev)
944{
945 int err;
946 u8 value;
947
948 mutex_lock(&bdev->mutex);
949
950 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, &value);
951
952 mutex_unlock(&bdev->mutex);
953
954 if (!err && (value & BCM2048_SEARCH_DIRECTION))
955 return BCM2048_SEARCH_DIRECTION_UP;
956
957 return err;
958}
959
960static int bcm2048_set_fm_search_tune_mode(struct bcm2048_device *bdev,
961 u8 mode)
962{
963 int err, timeout, restart_rds = 0;
964 u8 value, flags;
965
966 value = mode & BCM2048_FM_AUTO_SEARCH;
967
968 flags = BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
969 BCM2048_FM_FLAG_SEARCH_TUNE_FAIL;
970
971 mutex_lock(&bdev->mutex);
972
973 /*
974 * If RDS is enabled, and frequency is changed, RDS quits working.
975 * Thus, always restart RDS if it's enabled. Moreover, RDS must
976 * not be enabled while changing the frequency because it can
977 * provide a race to the mutex from the workqueue handler if RDS
978 * IRQ occurs while waiting for frequency changed IRQ.
979 */
980 if (bcm2048_get_rds_no_lock(bdev)) {
981 err = bcm2048_set_rds_no_lock(bdev, 0);
982 if (err)
983 goto unlock;
984 restart_rds = 1;
985 }
986
987 err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, flags);
988
989 if (err)
990 goto unlock;
991
992 bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE, value);
993
994 if (mode != BCM2048_FM_AUTO_SEARCH_MODE)
995 timeout = BCM2048_DEFAULT_TIMEOUT;
996 else
997 timeout = BCM2048_AUTO_SEARCH_TIMEOUT;
998
999 if (!wait_for_completion_timeout(&bdev->compl,
1000 msecs_to_jiffies(timeout)))
1001 dev_err(&bdev->client->dev, "IRQ timeout.\n");
1002
1003 if (value)
1004 if (!bdev->scan_state)
1005 err = -EIO;
1006
1007unlock:
1008 if (restart_rds)
1009 err |= bcm2048_set_rds_no_lock(bdev, 1);
1010
1011 mutex_unlock(&bdev->mutex);
1012
1013 return err;
1014}
1015
1016static int bcm2048_get_fm_search_tune_mode(struct bcm2048_device *bdev)
1017{
1018 int err;
1019 u8 value;
1020
1021 mutex_lock(&bdev->mutex);
1022
1023 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE,
1024 &value);
1025
1026 mutex_unlock(&bdev->mutex);
1027
1028 if (!err)
1029 return value & BCM2048_FM_AUTO_SEARCH;
1030
1031 return err;
1032}
1033
1034static int bcm2048_set_rds_b_block_mask(struct bcm2048_device *bdev, u16 mask)
1035{
1036 int err;
1037
1038 mutex_lock(&bdev->mutex);
1039
1040 err = bcm2048_send_command(bdev,
1041 BCM2048_I2C_RDS_BLKB_MASK0, lsb(mask));
1042 err |= bcm2048_send_command(bdev,
1043 BCM2048_I2C_RDS_BLKB_MASK1, msb(mask));
1044
1045 mutex_unlock(&bdev->mutex);
1046 return err;
1047}
1048
1049static int bcm2048_get_rds_b_block_mask(struct bcm2048_device *bdev)
1050{
1051 int err;
1052 u8 lsb, msb;
1053
1054 mutex_lock(&bdev->mutex);
1055
1056 err = bcm2048_recv_command(bdev,
1057 BCM2048_I2C_RDS_BLKB_MASK0, &lsb);
1058 err |= bcm2048_recv_command(bdev,
1059 BCM2048_I2C_RDS_BLKB_MASK1, &msb);
1060
1061 mutex_unlock(&bdev->mutex);
1062
1063 if (!err)
1064 return compose_u16(msb, lsb);
1065
1066 return err;
1067}
1068
1069static int bcm2048_set_rds_b_block_match(struct bcm2048_device *bdev,
1070 u16 match)
1071{
1072 int err;
1073
1074 mutex_lock(&bdev->mutex);
1075
1076 err = bcm2048_send_command(bdev,
1077 BCM2048_I2C_RDS_BLKB_MATCH0, lsb(match));
1078 err |= bcm2048_send_command(bdev,
1079 BCM2048_I2C_RDS_BLKB_MATCH1, msb(match));
1080
1081 mutex_unlock(&bdev->mutex);
1082 return err;
1083}
1084
1085static int bcm2048_get_rds_b_block_match(struct bcm2048_device *bdev)
1086{
1087 int err;
1088 u8 lsb, msb;
1089
1090 mutex_lock(&bdev->mutex);
1091
1092 err = bcm2048_recv_command(bdev,
1093 BCM2048_I2C_RDS_BLKB_MATCH0, &lsb);
1094 err |= bcm2048_recv_command(bdev,
1095 BCM2048_I2C_RDS_BLKB_MATCH1, &msb);
1096
1097 mutex_unlock(&bdev->mutex);
1098
1099 if (!err)
1100 return compose_u16(msb, lsb);
1101
1102 return err;
1103}
1104
1105static int bcm2048_set_rds_pi_mask(struct bcm2048_device *bdev, u16 mask)
1106{
1107 int err;
1108
1109 mutex_lock(&bdev->mutex);
1110
1111 err = bcm2048_send_command(bdev,
1112 BCM2048_I2C_RDS_PI_MASK0, lsb(mask));
1113 err |= bcm2048_send_command(bdev,
1114 BCM2048_I2C_RDS_PI_MASK1, msb(mask));
1115
1116 mutex_unlock(&bdev->mutex);
1117 return err;
1118}
1119
1120static int bcm2048_get_rds_pi_mask(struct bcm2048_device *bdev)
1121{
1122 int err;
1123 u8 lsb, msb;
1124
1125 mutex_lock(&bdev->mutex);
1126
1127 err = bcm2048_recv_command(bdev,
1128 BCM2048_I2C_RDS_PI_MASK0, &lsb);
1129 err |= bcm2048_recv_command(bdev,
1130 BCM2048_I2C_RDS_PI_MASK1, &msb);
1131
1132 mutex_unlock(&bdev->mutex);
1133
1134 if (!err)
1135 return compose_u16(msb, lsb);
1136
1137 return err;
1138}
1139
1140static int bcm2048_set_rds_pi_match(struct bcm2048_device *bdev, u16 match)
1141{
1142 int err;
1143
1144 mutex_lock(&bdev->mutex);
1145
1146 err = bcm2048_send_command(bdev,
1147 BCM2048_I2C_RDS_PI_MATCH0, lsb(match));
1148 err |= bcm2048_send_command(bdev,
1149 BCM2048_I2C_RDS_PI_MATCH1, msb(match));
1150
1151 mutex_unlock(&bdev->mutex);
1152 return err;
1153}
1154
1155static int bcm2048_get_rds_pi_match(struct bcm2048_device *bdev)
1156{
1157 int err;
1158 u8 lsb, msb;
1159
1160 mutex_lock(&bdev->mutex);
1161
1162 err = bcm2048_recv_command(bdev,
1163 BCM2048_I2C_RDS_PI_MATCH0, &lsb);
1164 err |= bcm2048_recv_command(bdev,
1165 BCM2048_I2C_RDS_PI_MATCH1, &msb);
1166
1167 mutex_unlock(&bdev->mutex);
1168
1169 if (!err)
1170 return compose_u16(msb, lsb);
1171
1172 return err;
1173}
1174
1175static int bcm2048_set_fm_rds_mask(struct bcm2048_device *bdev, u16 mask)
1176{
1177 int err;
1178
1179 mutex_lock(&bdev->mutex);
1180
1181 err = bcm2048_send_command(bdev,
1182 BCM2048_I2C_FM_RDS_MASK0, lsb(mask));
1183 err |= bcm2048_send_command(bdev,
1184 BCM2048_I2C_FM_RDS_MASK1, msb(mask));
1185
1186 mutex_unlock(&bdev->mutex);
1187 return err;
1188}
1189
1190static int bcm2048_get_fm_rds_mask(struct bcm2048_device *bdev)
1191{
1192 int err;
1193 u8 value0, value1;
1194
1195 mutex_lock(&bdev->mutex);
1196
1197 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_MASK0, &value0);
1198 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_MASK1, &value1);
1199
1200 mutex_unlock(&bdev->mutex);
1201
1202 if (!err)
1203 return compose_u16(value1, value0);
1204
1205 return err;
1206}
1207
1208static int bcm2048_get_fm_rds_flags(struct bcm2048_device *bdev)
1209{
1210 int err;
1211 u8 value0, value1;
1212
1213 mutex_lock(&bdev->mutex);
1214
1215 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &value0);
1216 err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &value1);
1217
1218 mutex_unlock(&bdev->mutex);
1219
1220 if (!err)
1221 return compose_u16(value1, value0);
1222
1223 return err;
1224}
1225
1226static int bcm2048_get_region_bottom_frequency(struct bcm2048_device *bdev)
1227{
1228 return bdev->region_info.bottom_frequency;
1229}
1230
1231static int bcm2048_get_region_top_frequency(struct bcm2048_device *bdev)
1232{
1233 return bdev->region_info.top_frequency;
1234}
1235
1236static int bcm2048_set_fm_best_tune_mode(struct bcm2048_device *bdev, u8 mode)
1237{
1238 int err;
1239 u8 value;
1240
1241 mutex_lock(&bdev->mutex);
1242
1243 /* Perform read as the manual indicates */
1244 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
1245 &value);
1246 value &= ~BCM2048_BEST_TUNE_MODE;
1247
1248 if (mode)
1249 value |= BCM2048_BEST_TUNE_MODE;
1250 err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
1251 value);
1252
1253 mutex_unlock(&bdev->mutex);
1254 return err;
1255}
1256
1257static int bcm2048_get_fm_best_tune_mode(struct bcm2048_device *bdev)
1258{
1259 int err;
1260 u8 value;
1261
1262 mutex_lock(&bdev->mutex);
1263
1264 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
1265 &value);
1266
1267 mutex_unlock(&bdev->mutex);
1268
1269 if (!err && (value & BCM2048_BEST_TUNE_MODE))
1270 return BCM2048_ITEM_ENABLED;
1271
1272 return err;
1273}
1274
1275static int bcm2048_get_fm_carrier_error(struct bcm2048_device *bdev)
1276{
1277 int err = 0;
1278 s8 value;
1279
1280 mutex_lock(&bdev->mutex);
1281 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_CARRIER, &value);
1282 mutex_unlock(&bdev->mutex);
1283
1284 if (!err)
1285 return value;
1286
1287 return err;
1288}
1289
1290static int bcm2048_get_fm_rssi(struct bcm2048_device *bdev)
1291{
1292 int err;
1293 s8 value;
1294
1295 mutex_lock(&bdev->mutex);
1296 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RSSI, &value);
1297 mutex_unlock(&bdev->mutex);
1298
1299 if (!err)
1300 return value;
1301
1302 return err;
1303}
1304
1305static int bcm2048_set_rds_wline(struct bcm2048_device *bdev, u8 wline)
1306{
1307 int err;
1308
1309 mutex_lock(&bdev->mutex);
1310
1311 err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_WLINE, wline);
1312
1313 if (!err)
1314 bdev->fifo_size = wline;
1315
1316 mutex_unlock(&bdev->mutex);
1317 return err;
1318}
1319
1320static int bcm2048_get_rds_wline(struct bcm2048_device *bdev)
1321{
1322 int err;
1323 u8 value;
1324
1325 mutex_lock(&bdev->mutex);
1326
1327 err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_WLINE, &value);
1328
1329 mutex_unlock(&bdev->mutex);
1330
1331 if (!err) {
1332 bdev->fifo_size = value;
1333 return value;
1334 }
1335
1336 return err;
1337}
1338
1339static int bcm2048_checkrev(struct bcm2048_device *bdev)
1340{
1341 int err;
1342 u8 version;
1343
1344 mutex_lock(&bdev->mutex);
1345
1346 err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_REV, &version);
1347
1348 mutex_unlock(&bdev->mutex);
1349
1350 if (!err) {
1351 dev_info(&bdev->client->dev, "BCM2048 Version 0x%x\n",
1352 version);
1353 return version;
1354 }
1355
1356 return err;
1357}
1358
1359static int bcm2048_get_rds_rt(struct bcm2048_device *bdev, char *data)
1360{
1361 int err = 0, i, j = 0, ce = 0, cr = 0;
1362 char data_buffer[BCM2048_MAX_RDS_RT+1];
1363
1364 mutex_lock(&bdev->mutex);
1365
1366 if (!bdev->rds_info.text_len) {
1367 err = -EINVAL;
1368 goto unlock;
1369 }
1370
1371 for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
1372 if (bdev->rds_info.rds_rt[i]) {
1373 ce = i;
1374 /* Skip the carriage return */
1375 if (bdev->rds_info.rds_rt[i] != 0x0d) {
1376 data_buffer[j++] = bdev->rds_info.rds_rt[i];
1377 } else {
1378 cr = i;
1379 break;
1380 }
1381 }
1382 }
1383
1384 if (j <= BCM2048_MAX_RDS_RT)
1385 data_buffer[j] = 0;
1386
1387 for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
1388 if (!bdev->rds_info.rds_rt[i]) {
1389 if (cr && (i < cr)) {
1390 err = -EBUSY;
1391 goto unlock;
1392 }
1393 if (i < ce) {
1394 if (cr && (i >= cr))
1395 break;
1396 err = -EBUSY;
1397 goto unlock;
1398 }
1399 }
1400 }
1401
1402 memcpy(data, data_buffer, sizeof(data_buffer));
1403
1404unlock:
1405 mutex_unlock(&bdev->mutex);
1406 return err;
1407}
1408
1409static int bcm2048_get_rds_ps(struct bcm2048_device *bdev, char *data)
1410{
1411 int err = 0, i, j = 0;
1412 char data_buffer[BCM2048_MAX_RDS_PS+1];
1413
1414 mutex_lock(&bdev->mutex);
1415
1416 if (!bdev->rds_info.text_len) {
1417 err = -EINVAL;
1418 goto unlock;
1419 }
1420
1421 for (i = 0; i < BCM2048_MAX_RDS_PS; i++) {
1422 if (bdev->rds_info.rds_ps[i]) {
1423 data_buffer[j++] = bdev->rds_info.rds_ps[i];
1424 } else {
1425 if (i < (BCM2048_MAX_RDS_PS - 1)) {
1426 err = -EBUSY;
1427 goto unlock;
1428 }
1429 }
1430 }
1431
1432 if (j <= BCM2048_MAX_RDS_PS)
1433 data_buffer[j] = 0;
1434
1435 memcpy(data, data_buffer, sizeof(data_buffer));
1436
1437unlock:
1438 mutex_unlock(&bdev->mutex);
1439 return err;
1440}
1441
1442static void bcm2048_parse_rds_pi(struct bcm2048_device *bdev)
1443{
1444 int i, cnt = 0;
1445 u16 pi;
1446
1447 for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
1448
1449 /* Block A match, only data without crc errors taken */
1450 if (bdev->rds_info.radio_text[i] == BCM2048_RDS_BLOCK_A) {
1451
1452 pi = ((bdev->rds_info.radio_text[i+1] << 8) +
1453 bdev->rds_info.radio_text[i+2]);
1454
1455 if (!bdev->rds_info.rds_pi) {
1456 bdev->rds_info.rds_pi = pi;
1457 return;
1458 }
1459 if (pi != bdev->rds_info.rds_pi) {
1460 cnt++;
1461 if (cnt > 3) {
1462 bdev->rds_info.rds_pi = pi;
1463 cnt = 0;
1464 }
1465 } else {
1466 cnt = 0;
1467 }
1468 }
1469 }
1470}
1471
1472static int bcm2048_rds_block_crc(struct bcm2048_device *bdev, int i)
1473{
1474 return bdev->rds_info.radio_text[i] & BCM2048_RDS_CRC_MASK;
1475}
1476
1477static void bcm2048_parse_rds_rt_block(struct bcm2048_device *bdev, int i,
1478 int index, int crc)
1479{
1480 /* Good data will overwrite poor data */
1481 if (crc) {
1482 if (!bdev->rds_info.rds_rt[index])
1483 bdev->rds_info.rds_rt[index] =
1484 bdev->rds_info.radio_text[i+1];
1485 if (!bdev->rds_info.rds_rt[index+1])
1486 bdev->rds_info.rds_rt[index+1] =
1487 bdev->rds_info.radio_text[i+2];
1488 } else {
1489 bdev->rds_info.rds_rt[index] = bdev->rds_info.radio_text[i+1];
1490 bdev->rds_info.rds_rt[index+1] =
1491 bdev->rds_info.radio_text[i+2];
1492 }
1493}
1494
1495static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i)
1496{
1497 int crc, rt_id, rt_group_b, rt_ab, index = 0;
1498
1499 crc = bcm2048_rds_block_crc(bdev, i);
1500
1501 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1502 return -EIO;
1503
1504 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1505 BCM2048_RDS_BLOCK_B) {
1506
1507 rt_id = (bdev->rds_info.radio_text[i+1] &
1508 BCM2048_RDS_BLOCK_MASK);
1509 rt_group_b = bdev->rds_info.radio_text[i+1] &
1510 BCM2048_RDS_GROUP_AB_MASK;
1511 rt_ab = bdev->rds_info.radio_text[i+2] &
1512 BCM2048_RDS_RT_AB_MASK;
1513
1514 if (rt_group_b != bdev->rds_info.rds_rt_group_b) {
1515 memset(bdev->rds_info.rds_rt, 0,
1516 sizeof(bdev->rds_info.rds_rt));
1517 bdev->rds_info.rds_rt_group_b = rt_group_b;
1518 }
1519
1520 if (rt_id == BCM2048_RDS_RT) {
1521 /* A to B or (vice versa), means: clear screen */
1522 if (rt_ab != bdev->rds_info.rds_rt_ab) {
1523 memset(bdev->rds_info.rds_rt, 0,
1524 sizeof(bdev->rds_info.rds_rt));
1525 bdev->rds_info.rds_rt_ab = rt_ab;
1526 }
1527
1528 index = bdev->rds_info.radio_text[i+2] &
1529 BCM2048_RDS_RT_INDEX;
1530
1531 if (bdev->rds_info.rds_rt_group_b)
1532 index <<= 1;
1533 else
1534 index <<= 2;
1535
1536 return index;
1537 }
1538 }
1539
1540 return -EIO;
1541}
1542
1543static int bcm2048_parse_rt_match_c(struct bcm2048_device *bdev, int i,
1544 int index)
1545{
1546 int crc;
1547
1548 crc = bcm2048_rds_block_crc(bdev, i);
1549
1550 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1551 return 0;
1552
1553 BUG_ON((index+2) >= BCM2048_MAX_RDS_RT);
1554
1555 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1556 BCM2048_RDS_BLOCK_C) {
1557 if (bdev->rds_info.rds_rt_group_b)
1558 return 1;
1559 bcm2048_parse_rds_rt_block(bdev, i, index, crc);
1560 return 1;
1561 }
1562
1563 return 0;
1564}
1565
1566static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i,
1567 int index)
1568{
1569 int crc;
1570
1571 crc = bcm2048_rds_block_crc(bdev, i);
1572
1573 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1574 return;
1575
1576 BUG_ON((index+4) >= BCM2048_MAX_RDS_RT);
1577
1578 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1579 BCM2048_RDS_BLOCK_D)
1580 bcm2048_parse_rds_rt_block(bdev, i, index+2, crc);
1581}
1582
1583static int bcm2048_parse_rds_rt(struct bcm2048_device *bdev)
1584{
1585 int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0;
1586
1587 for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
1588
1589 if (match_b) {
1590 match_b = 0;
1591 index = bcm2048_parse_rt_match_b(bdev, i);
1592 if (index >= 0 && index <= (BCM2048_MAX_RDS_RT - 5))
1593 match_c = 1;
1594 continue;
1595 } else if (match_c) {
1596 match_c = 0;
1597 if (bcm2048_parse_rt_match_c(bdev, i, index))
1598 match_d = 1;
1599 continue;
1600 } else if (match_d) {
1601 match_d = 0;
1602 bcm2048_parse_rt_match_d(bdev, i, index);
1603 continue;
1604 }
1605
1606 /* Skip erroneous blocks due to messed up A block altogether */
1607 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK)
1608 == BCM2048_RDS_BLOCK_A) {
1609 crc = bcm2048_rds_block_crc(bdev, i);
1610 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1611 continue;
1612 /* Syncronize to a good RDS PI */
1613 if (((bdev->rds_info.radio_text[i+1] << 8) +
1614 bdev->rds_info.radio_text[i+2]) ==
1615 bdev->rds_info.rds_pi)
1616 match_b = 1;
1617 }
1618 }
1619
1620 return 0;
1621}
1622
1623static void bcm2048_parse_rds_ps_block(struct bcm2048_device *bdev, int i,
1624 int index, int crc)
1625{
1626 /* Good data will overwrite poor data */
1627 if (crc) {
1628 if (!bdev->rds_info.rds_ps[index])
1629 bdev->rds_info.rds_ps[index] =
1630 bdev->rds_info.radio_text[i+1];
1631 if (!bdev->rds_info.rds_ps[index+1])
1632 bdev->rds_info.rds_ps[index+1] =
1633 bdev->rds_info.radio_text[i+2];
1634 } else {
1635 bdev->rds_info.rds_ps[index] = bdev->rds_info.radio_text[i+1];
1636 bdev->rds_info.rds_ps[index+1] =
1637 bdev->rds_info.radio_text[i+2];
1638 }
1639}
1640
1641static int bcm2048_parse_ps_match_c(struct bcm2048_device *bdev, int i,
1642 int index)
1643{
1644 int crc;
1645
1646 crc = bcm2048_rds_block_crc(bdev, i);
1647
1648 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1649 return 0;
1650
1651 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1652 BCM2048_RDS_BLOCK_C)
1653 return 1;
1654
1655 return 0;
1656}
1657
1658static void bcm2048_parse_ps_match_d(struct bcm2048_device *bdev, int i,
1659 int index)
1660{
1661 int crc;
1662
1663 crc = bcm2048_rds_block_crc(bdev, i);
1664
1665 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1666 return;
1667
1668 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1669 BCM2048_RDS_BLOCK_D)
1670 bcm2048_parse_rds_ps_block(bdev, i, index, crc);
1671}
1672
1673static int bcm2048_parse_ps_match_b(struct bcm2048_device *bdev, int i)
1674{
1675 int crc, index, ps_id, ps_group;
1676
1677 crc = bcm2048_rds_block_crc(bdev, i);
1678
1679 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1680 return -EIO;
1681
1682 /* Block B Radio PS match */
1683 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
1684 BCM2048_RDS_BLOCK_B) {
1685 ps_id = bdev->rds_info.radio_text[i+1] &
1686 BCM2048_RDS_BLOCK_MASK;
1687 ps_group = bdev->rds_info.radio_text[i+1] &
1688 BCM2048_RDS_GROUP_AB_MASK;
1689
1690 /*
1691 * Poor RSSI will lead to RDS data corruption
1692 * So using 3 (same) sequential values to justify major changes
1693 */
1694 if (ps_group != bdev->rds_info.rds_ps_group) {
1695 if (crc == BCM2048_RDS_CRC_NONE) {
1696 bdev->rds_info.rds_ps_group_cnt++;
1697 if (bdev->rds_info.rds_ps_group_cnt > 2) {
1698 bdev->rds_info.rds_ps_group = ps_group;
1699 bdev->rds_info.rds_ps_group_cnt = 0;
1700 dev_err(&bdev->client->dev,
1701 "RDS PS Group change!\n");
1702 } else {
1703 return -EIO;
1704 }
1705 } else {
1706 bdev->rds_info.rds_ps_group_cnt = 0;
1707 }
1708 }
1709
1710 if (ps_id == BCM2048_RDS_PS) {
1711 index = bdev->rds_info.radio_text[i+2] &
1712 BCM2048_RDS_PS_INDEX;
1713 index <<= 1;
1714 return index;
1715 }
1716 }
1717
1718 return -EIO;
1719}
1720
1721static void bcm2048_parse_rds_ps(struct bcm2048_device *bdev)
1722{
1723 int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0;
1724
1725 for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
1726
1727 if (match_b) {
1728 match_b = 0;
1729 index = bcm2048_parse_ps_match_b(bdev, i);
1730 if (index >= 0 && index < (BCM2048_MAX_RDS_PS - 1))
1731 match_c = 1;
1732 continue;
1733 } else if (match_c) {
1734 match_c = 0;
1735 if (bcm2048_parse_ps_match_c(bdev, i, index))
1736 match_d = 1;
1737 continue;
1738 } else if (match_d) {
1739 match_d = 0;
1740 bcm2048_parse_ps_match_d(bdev, i, index);
1741 continue;
1742 }
1743
1744 /* Skip erroneous blocks due to messed up A block altogether */
1745 if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK)
1746 == BCM2048_RDS_BLOCK_A) {
1747 crc = bcm2048_rds_block_crc(bdev, i);
1748 if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
1749 continue;
1750 /* Syncronize to a good RDS PI */
1751 if (((bdev->rds_info.radio_text[i+1] << 8) +
1752 bdev->rds_info.radio_text[i+2]) ==
1753 bdev->rds_info.rds_pi)
1754 match_b = 1;
1755 }
1756 }
1757}
1758
1759static void bcm2048_rds_fifo_receive(struct bcm2048_device *bdev)
1760{
1761 int err;
1762
1763 mutex_lock(&bdev->mutex);
1764
1765 err = bcm2048_recv_duples(bdev, BCM2048_I2C_RDS_DATA,
1766 bdev->rds_info.radio_text, bdev->fifo_size);
1767 if (err != 2) {
1768 dev_err(&bdev->client->dev, "RDS Read problem\n");
1769 mutex_unlock(&bdev->mutex);
1770 return;
1771 }
1772
1773 bdev->rds_info.text_len = bdev->fifo_size;
1774
1775 bcm2048_parse_rds_pi(bdev);
1776 bcm2048_parse_rds_rt(bdev);
1777 bcm2048_parse_rds_ps(bdev);
1778
1779 mutex_unlock(&bdev->mutex);
1780
1781 wake_up_interruptible(&bdev->read_queue);
1782}
1783
1784static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data)
1785{
1786 int err = 0, i, p = 0;
1787 char *data_buffer;
1788
1789 mutex_lock(&bdev->mutex);
1790
1791 if (!bdev->rds_info.text_len) {
1792 err = -EINVAL;
1793 goto unlock;
1794 }
1795
1796 data_buffer = kzalloc(BCM2048_MAX_RDS_RADIO_TEXT*5, GFP_KERNEL);
1797 if (!data_buffer) {
1798 err = -ENOMEM;
1799 goto unlock;
1800 }
1801
1802 for (i = 0; i < bdev->rds_info.text_len; i++) {
1803 p += sprintf(data_buffer+p, "%x ",
1804 bdev->rds_info.radio_text[i]);
1805 }
1806
1807 memcpy(data, data_buffer, p);
1808 kfree(data_buffer);
1809
1810unlock:
1811 mutex_unlock(&bdev->mutex);
1812 return err;
1813}
1814
1815/*
1816 * BCM2048 default initialization sequence
1817 */
1818static int bcm2048_init(struct bcm2048_device *bdev)
1819{
1820 int err;
1821
1822 err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
1823 if (err < 0)
1824 goto exit;
1825
1826 err = bcm2048_set_audio_route(bdev, BCM2048_AUDIO_ROUTE_DAC);
1827 if (err < 0)
1828 goto exit;
1829
1830 err = bcm2048_set_dac_output(bdev, BCM2048_DAC_OUTPUT_LEFT |
1831 BCM2048_DAC_OUTPUT_RIGHT);
1832
1833exit:
1834 return err;
1835}
1836
1837/*
1838 * BCM2048 default deinitialization sequence
1839 */
1840static int bcm2048_deinit(struct bcm2048_device *bdev)
1841{
1842 int err;
1843
1844 err = bcm2048_set_audio_route(bdev, 0);
1845 if (err < 0)
1846 goto exit;
1847
1848 err = bcm2048_set_dac_output(bdev, 0);
1849 if (err < 0)
1850 goto exit;
1851
1852 err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
1853 if (err < 0)
1854 goto exit;
1855
1856exit:
1857 return err;
1858}
1859
1860/*
1861 * BCM2048 probe sequence
1862 */
1863static int bcm2048_probe(struct bcm2048_device *bdev)
1864{
1865 int err;
1866
1867 err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
1868 if (err < 0)
1869 goto unlock;
1870
1871 err = bcm2048_checkrev(bdev);
1872 if (err < 0)
1873 goto unlock;
1874
1875 err = bcm2048_set_mute(bdev, BCM2048_DEFAULT_MUTE);
1876 if (err < 0)
1877 goto unlock;
1878
1879 err = bcm2048_set_region(bdev, BCM2048_DEFAULT_REGION);
1880 if (err < 0)
1881 goto unlock;
1882
1883 err = bcm2048_set_fm_search_rssi_threshold(bdev,
1884 BCM2048_DEFAULT_RSSI_THRESHOLD);
1885 if (err < 0)
1886 goto unlock;
1887
1888 err = bcm2048_set_fm_automatic_stereo_mono(bdev, BCM2048_ITEM_ENABLED);
1889 if (err < 0)
1890 goto unlock;
1891
1892 err = bcm2048_get_rds_wline(bdev);
1893 if (err < BCM2048_DEFAULT_RDS_WLINE)
1894 err = bcm2048_set_rds_wline(bdev, BCM2048_DEFAULT_RDS_WLINE);
1895 if (err < 0)
1896 goto unlock;
1897
1898 err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
1899
1900 init_waitqueue_head(&bdev->read_queue);
1901 bdev->rds_data_available = 0;
1902 bdev->rd_index = 0;
1903 bdev->users = 0;
1904
1905unlock:
1906 return err;
1907}
1908
1909/*
1910 * BCM2048 workqueue handler
1911 */
1912static void bcm2048_work(struct work_struct *work)
1913{
1914 struct bcm2048_device *bdev;
1915 u8 flag_lsb, flag_msb, flags;
1916
1917 bdev = container_of(work, struct bcm2048_device, work);
1918 bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &flag_lsb);
1919 bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &flag_msb);
1920
1921 if (flag_lsb & (BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
1922 BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)) {
1923
1924 if (flag_lsb & BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)
1925 bdev->scan_state = BCM2048_SCAN_FAIL;
1926 else
1927 bdev->scan_state = BCM2048_SCAN_OK;
1928
1929 complete(&bdev->compl);
1930 }
1931
1932 if (flag_msb & BCM2048_RDS_FLAG_FIFO_WLINE) {
1933 bcm2048_rds_fifo_receive(bdev);
1934 if (bdev->rds_state) {
1935 flags = BCM2048_RDS_FLAG_FIFO_WLINE;
1936 bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
1937 flags);
1938 }
1939 bdev->rds_data_available = 1;
1940 bdev->rd_index = 0; /* new data, new start */
1941 }
1942}
1943
1944/*
1945 * BCM2048 interrupt handler
1946 */
1947static irqreturn_t bcm2048_handler(int irq, void *dev)
1948{
1949 struct bcm2048_device *bdev = dev;
1950
1951 dev_dbg(&bdev->client->dev, "IRQ called, queuing work\n");
1952 if (bdev->power_state)
1953 schedule_work(&bdev->work);
1954
1955 return IRQ_HANDLED;
1956}
1957
1958/*
1959 * BCM2048 sysfs interface definitions
1960 */
1961#define property_write(prop, type, mask, check) \
1962static ssize_t bcm2048_##prop##_write(struct device *dev, \
1963 struct device_attribute *attr, \
1964 const char *buf, \
1965 size_t count) \
1966{ \
1967 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
1968 type value; \
1969 int err; \
1970 \
1971 if (!bdev) \
1972 return -ENODEV; \
1973 \
1974 sscanf(buf, mask, &value); \
1975 \
1976 if (check) \
1977 return -EDOM; \
1978 \
1979 err = bcm2048_set_##prop(bdev, value); \
1980 \
1981 return err < 0 ? err : count; \
1982}
1983
1984#define property_read(prop, size, mask) \
1985static ssize_t bcm2048_##prop##_read(struct device *dev, \
1986 struct device_attribute *attr, \
1987 char *buf) \
1988{ \
1989 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
1990 int value; \
1991 \
1992 if (!bdev) \
1993 return -ENODEV; \
1994 \
1995 value = bcm2048_get_##prop(bdev); \
1996 \
1997 if (value >= 0) \
1998 value = sprintf(buf, mask "\n", value); \
1999 \
2000 return value; \
2001}
2002
2003#define property_signed_read(prop, size, mask) \
2004static ssize_t bcm2048_##prop##_read(struct device *dev, \
2005 struct device_attribute *attr, \
2006 char *buf) \
2007{ \
2008 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
2009 size value; \
2010 \
2011 if (!bdev) \
2012 return -ENODEV; \
2013 \
2014 value = bcm2048_get_##prop(bdev); \
2015 \
2016 value = sprintf(buf, mask "\n", value); \
2017 \
2018 return value; \
2019}
2020
2021#define DEFINE_SYSFS_PROPERTY(prop, signal, size, mask, check) \
2022property_write(prop, signal size, mask, check) \
2023property_read(prop, size, mask)
2024
2025#define property_str_read(prop, size) \
2026static ssize_t bcm2048_##prop##_read(struct device *dev, \
2027 struct device_attribute *attr, \
2028 char *buf) \
2029{ \
2030 struct bcm2048_device *bdev = dev_get_drvdata(dev); \
2031 int count; \
2032 u8 *out; \
2033 \
2034 if (!bdev) \
2035 return -ENODEV; \
2036 \
2037 out = kzalloc(size + 1, GFP_KERNEL); \
2038 if (!out) \
2039 return -ENOMEM; \
2040 \
2041 bcm2048_get_##prop(bdev, out); \
2042 count = sprintf(buf, "%s\n", out); \
2043 \
2044 kfree(out); \
2045 \
2046 return count; \
2047}
2048
2049DEFINE_SYSFS_PROPERTY(power_state, unsigned, int, "%u", 0)
2050DEFINE_SYSFS_PROPERTY(mute, unsigned, int, "%u", 0)
2051DEFINE_SYSFS_PROPERTY(audio_route, unsigned, int, "%u", 0)
2052DEFINE_SYSFS_PROPERTY(dac_output, unsigned, int, "%u", 0)
2053
2054DEFINE_SYSFS_PROPERTY(fm_hi_lo_injection, unsigned, int, "%u", 0)
2055DEFINE_SYSFS_PROPERTY(fm_frequency, unsigned, int, "%u", 0)
2056DEFINE_SYSFS_PROPERTY(fm_af_frequency, unsigned, int, "%u", 0)
2057DEFINE_SYSFS_PROPERTY(fm_deemphasis, unsigned, int, "%u", 0)
2058DEFINE_SYSFS_PROPERTY(fm_rds_mask, unsigned, int, "%u", 0)
2059DEFINE_SYSFS_PROPERTY(fm_best_tune_mode, unsigned, int, "%u", 0)
2060DEFINE_SYSFS_PROPERTY(fm_search_rssi_threshold, unsigned, int, "%u", 0)
2061DEFINE_SYSFS_PROPERTY(fm_search_mode_direction, unsigned, int, "%u", 0)
2062DEFINE_SYSFS_PROPERTY(fm_search_tune_mode, unsigned, int, "%u", value > 3)
2063
2064DEFINE_SYSFS_PROPERTY(rds, unsigned, int, "%u", 0)
2065DEFINE_SYSFS_PROPERTY(rds_b_block_mask, unsigned, int, "%u", 0)
2066DEFINE_SYSFS_PROPERTY(rds_b_block_match, unsigned, int, "%u", 0)
2067DEFINE_SYSFS_PROPERTY(rds_pi_mask, unsigned, int, "%u", 0)
2068DEFINE_SYSFS_PROPERTY(rds_pi_match, unsigned, int, "%u", 0)
2069DEFINE_SYSFS_PROPERTY(rds_wline, unsigned, int, "%u", 0)
2070property_read(rds_pi, unsigned int, "%x")
2071property_str_read(rds_rt, (BCM2048_MAX_RDS_RT + 1))
2072property_str_read(rds_ps, (BCM2048_MAX_RDS_PS + 1))
2073
2074property_read(fm_rds_flags, unsigned int, "%u")
2075property_str_read(rds_data, BCM2048_MAX_RDS_RADIO_TEXT*5)
2076
2077property_read(region_bottom_frequency, unsigned int, "%u")
2078property_read(region_top_frequency, unsigned int, "%u")
2079property_signed_read(fm_carrier_error, int, "%d")
2080property_signed_read(fm_rssi, int, "%d")
2081DEFINE_SYSFS_PROPERTY(region, unsigned, int, "%u", 0)
2082
2083static struct device_attribute attrs[] = {
2084 __ATTR(power_state, S_IRUGO | S_IWUSR, bcm2048_power_state_read,
2085 bcm2048_power_state_write),
2086 __ATTR(mute, S_IRUGO | S_IWUSR, bcm2048_mute_read,
2087 bcm2048_mute_write),
2088 __ATTR(audio_route, S_IRUGO | S_IWUSR, bcm2048_audio_route_read,
2089 bcm2048_audio_route_write),
2090 __ATTR(dac_output, S_IRUGO | S_IWUSR, bcm2048_dac_output_read,
2091 bcm2048_dac_output_write),
2092 __ATTR(fm_hi_lo_injection, S_IRUGO | S_IWUSR,
2093 bcm2048_fm_hi_lo_injection_read,
2094 bcm2048_fm_hi_lo_injection_write),
2095 __ATTR(fm_frequency, S_IRUGO | S_IWUSR, bcm2048_fm_frequency_read,
2096 bcm2048_fm_frequency_write),
2097 __ATTR(fm_af_frequency, S_IRUGO | S_IWUSR,
2098 bcm2048_fm_af_frequency_read,
2099 bcm2048_fm_af_frequency_write),
2100 __ATTR(fm_deemphasis, S_IRUGO | S_IWUSR, bcm2048_fm_deemphasis_read,
2101 bcm2048_fm_deemphasis_write),
2102 __ATTR(fm_rds_mask, S_IRUGO | S_IWUSR, bcm2048_fm_rds_mask_read,
2103 bcm2048_fm_rds_mask_write),
2104 __ATTR(fm_best_tune_mode, S_IRUGO | S_IWUSR,
2105 bcm2048_fm_best_tune_mode_read,
2106 bcm2048_fm_best_tune_mode_write),
2107 __ATTR(fm_search_rssi_threshold, S_IRUGO | S_IWUSR,
2108 bcm2048_fm_search_rssi_threshold_read,
2109 bcm2048_fm_search_rssi_threshold_write),
2110 __ATTR(fm_search_mode_direction, S_IRUGO | S_IWUSR,
2111 bcm2048_fm_search_mode_direction_read,
2112 bcm2048_fm_search_mode_direction_write),
2113 __ATTR(fm_search_tune_mode, S_IRUGO | S_IWUSR,
2114 bcm2048_fm_search_tune_mode_read,
2115 bcm2048_fm_search_tune_mode_write),
2116 __ATTR(rds, S_IRUGO | S_IWUSR, bcm2048_rds_read,
2117 bcm2048_rds_write),
2118 __ATTR(rds_b_block_mask, S_IRUGO | S_IWUSR,
2119 bcm2048_rds_b_block_mask_read,
2120 bcm2048_rds_b_block_mask_write),
2121 __ATTR(rds_b_block_match, S_IRUGO | S_IWUSR,
2122 bcm2048_rds_b_block_match_read,
2123 bcm2048_rds_b_block_match_write),
2124 __ATTR(rds_pi_mask, S_IRUGO | S_IWUSR, bcm2048_rds_pi_mask_read,
2125 bcm2048_rds_pi_mask_write),
2126 __ATTR(rds_pi_match, S_IRUGO | S_IWUSR, bcm2048_rds_pi_match_read,
2127 bcm2048_rds_pi_match_write),
2128 __ATTR(rds_wline, S_IRUGO | S_IWUSR, bcm2048_rds_wline_read,
2129 bcm2048_rds_wline_write),
2130 __ATTR(rds_pi, S_IRUGO, bcm2048_rds_pi_read, NULL),
2131 __ATTR(rds_rt, S_IRUGO, bcm2048_rds_rt_read, NULL),
2132 __ATTR(rds_ps, S_IRUGO, bcm2048_rds_ps_read, NULL),
2133 __ATTR(fm_rds_flags, S_IRUGO, bcm2048_fm_rds_flags_read, NULL),
2134 __ATTR(region_bottom_frequency, S_IRUGO,
2135 bcm2048_region_bottom_frequency_read, NULL),
2136 __ATTR(region_top_frequency, S_IRUGO,
2137 bcm2048_region_top_frequency_read, NULL),
2138 __ATTR(fm_carrier_error, S_IRUGO,
2139 bcm2048_fm_carrier_error_read, NULL),
2140 __ATTR(fm_rssi, S_IRUGO,
2141 bcm2048_fm_rssi_read, NULL),
2142 __ATTR(region, S_IRUGO | S_IWUSR, bcm2048_region_read,
2143 bcm2048_region_write),
2144 __ATTR(rds_data, S_IRUGO, bcm2048_rds_data_read, NULL),
2145};
2146
2147static int bcm2048_sysfs_unregister_properties(struct bcm2048_device *bdev,
2148 int size)
2149{
2150 int i;
2151
2152 for (i = 0; i < size; i++)
2153 device_remove_file(&bdev->client->dev, &attrs[i]);
2154
2155 return 0;
2156}
2157
2158static int bcm2048_sysfs_register_properties(struct bcm2048_device *bdev)
2159{
2160 int err = 0;
2161 int i;
2162
2163 for (i = 0; i < ARRAY_SIZE(attrs); i++) {
2164 if (device_create_file(&bdev->client->dev, &attrs[i]) != 0) {
2165 dev_err(&bdev->client->dev,
2166 "could not register sysfs entry\n");
2167 err = -EBUSY;
2168 bcm2048_sysfs_unregister_properties(bdev, i);
2169 break;
2170 }
2171 }
2172
2173 return err;
2174}
2175
2176
2177static int bcm2048_fops_open(struct file *file)
2178{
2179 struct bcm2048_device *bdev = video_drvdata(file);
2180
2181 bdev->users++;
2182 bdev->rd_index = 0;
2183 bdev->rds_data_available = 0;
2184
2185 return 0;
2186}
2187
2188static int bcm2048_fops_release(struct file *file)
2189{
2190 struct bcm2048_device *bdev = video_drvdata(file);
2191
2192 bdev->users--;
2193
2194 return 0;
2195}
2196
2197static unsigned int bcm2048_fops_poll(struct file *file,
2198 struct poll_table_struct *pts)
2199{
2200 struct bcm2048_device *bdev = video_drvdata(file);
2201 int retval = 0;
2202
2203 poll_wait(file, &bdev->read_queue, pts);
2204
2205 if (bdev->rds_data_available)
2206 retval = POLLIN | POLLRDNORM;
2207
2208 return retval;
2209}
2210
2211static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
2212 size_t count, loff_t *ppos)
2213{
2214 struct bcm2048_device *bdev = video_drvdata(file);
2215 int i;
2216 int retval = 0;
2217
2218 /* we return at least 3 bytes, one block */
2219 count = (count / 3) * 3; /* only multiples of 3 */
2220 if (count < 3)
2221 return -ENOBUFS;
2222
2223 while (!bdev->rds_data_available) {
2224 if (file->f_flags & O_NONBLOCK) {
2225 retval = -EWOULDBLOCK;
2226 goto done;
2227 }
2228 /* interruptible_sleep_on(&bdev->read_queue); */
2229 if (wait_event_interruptible(bdev->read_queue,
2230 bdev->rds_data_available) < 0) {
2231 retval = -EINTR;
2232 goto done;
2233 }
2234 }
2235
2236 mutex_lock(&bdev->mutex);
2237 /* copy data to userspace */
2238 i = bdev->fifo_size - bdev->rd_index;
2239 if (count > i)
2240 count = (i / 3) * 3;
2241
2242 i = 0;
2243 while (i < count) {
2244 unsigned char tmpbuf[3];
2245 tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index+i+2];
2246 tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1];
2247 tmpbuf[i+2] = ((bdev->rds_info.radio_text[bdev->rd_index+i]
2248 & 0xf0) >> 4);
2249 if ((bdev->rds_info.radio_text[bdev->rd_index+i] &
2250 BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE)
2251 tmpbuf[i+2] |= 0x80;
2252 if (copy_to_user(buf+i, tmpbuf, 3)) {
2253 retval = -EFAULT;
2254 break;
2255 }
2256 i += 3;
2257 }
2258
2259 bdev->rd_index += i;
2260 if (bdev->rd_index >= bdev->fifo_size)
2261 bdev->rds_data_available = 0;
2262
2263 mutex_unlock(&bdev->mutex);
2264 if (retval == 0)
2265 retval = i;
2266
2267done:
2268 return retval;
2269}
2270
2271/*
2272 * bcm2048_fops - file operations interface
2273 */
2274static const struct v4l2_file_operations bcm2048_fops = {
2275 .owner = THIS_MODULE,
2276 .ioctl = video_ioctl2,
2277 /* for RDS read support */
2278 .open = bcm2048_fops_open,
2279 .release = bcm2048_fops_release,
2280 .read = bcm2048_fops_read,
2281 .poll = bcm2048_fops_poll
2282};
2283
2284/*
2285 * Video4Linux Interface
2286 */
2287static struct v4l2_queryctrl bcm2048_v4l2_queryctrl[] = {
2288 {
2289 .id = V4L2_CID_AUDIO_VOLUME,
2290 .flags = V4L2_CTRL_FLAG_DISABLED,
2291 },
2292 {
2293 .id = V4L2_CID_AUDIO_BALANCE,
2294 .flags = V4L2_CTRL_FLAG_DISABLED,
2295 },
2296 {
2297 .id = V4L2_CID_AUDIO_BASS,
2298 .flags = V4L2_CTRL_FLAG_DISABLED,
2299 },
2300 {
2301 .id = V4L2_CID_AUDIO_TREBLE,
2302 .flags = V4L2_CTRL_FLAG_DISABLED,
2303 },
2304 {
2305 .id = V4L2_CID_AUDIO_MUTE,
2306 .type = V4L2_CTRL_TYPE_BOOLEAN,
2307 .name = "Mute",
2308 .minimum = 0,
2309 .maximum = 1,
2310 .step = 1,
2311 .default_value = 1,
2312 },
2313 {
2314 .id = V4L2_CID_AUDIO_LOUDNESS,
2315 .flags = V4L2_CTRL_FLAG_DISABLED,
2316 },
2317};
2318
2319static int bcm2048_vidioc_querycap(struct file *file, void *priv,
2320 struct v4l2_capability *capability)
2321{
2322 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2323
2324 strlcpy(capability->driver, BCM2048_DRIVER_NAME,
2325 sizeof(capability->driver));
2326 strlcpy(capability->card, BCM2048_DRIVER_CARD,
2327 sizeof(capability->card));
2328 snprintf(capability->bus_info, 32, "I2C: 0x%X", bdev->client->addr);
2329 capability->version = BCM2048_DRIVER_VERSION;
2330 capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
2331 V4L2_CAP_HW_FREQ_SEEK;
2332
2333 return 0;
2334}
2335
2336static int bcm2048_vidioc_g_input(struct file *filp, void *priv,
2337 unsigned int *i)
2338{
2339 *i = 0;
2340
2341 return 0;
2342}
2343
2344static int bcm2048_vidioc_s_input(struct file *filp, void *priv,
2345 unsigned int i)
2346{
2347 if (i)
2348 return -EINVAL;
2349
2350 return 0;
2351}
2352
2353static int bcm2048_vidioc_queryctrl(struct file *file, void *priv,
2354 struct v4l2_queryctrl *qc)
2355{
2356 int i;
2357
2358 for (i = 0; i < ARRAY_SIZE(bcm2048_v4l2_queryctrl); i++) {
2359 if (qc->id && qc->id == bcm2048_v4l2_queryctrl[i].id) {
2360 *qc = bcm2048_v4l2_queryctrl[i];
2361 return 0;
2362 }
2363 }
2364
2365 return -EINVAL;
2366}
2367
2368static int bcm2048_vidioc_g_ctrl(struct file *file, void *priv,
2369 struct v4l2_control *ctrl)
2370{
2371 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2372 int err = 0;
2373
2374 if (!bdev)
2375 return -ENODEV;
2376
2377 switch (ctrl->id) {
2378 case V4L2_CID_AUDIO_MUTE:
2379 err = bcm2048_get_mute(bdev);
2380 if (err >= 0)
2381 ctrl->value = err;
2382 break;
2383 }
2384
2385 return err;
2386}
2387
2388static int bcm2048_vidioc_s_ctrl(struct file *file, void *priv,
2389 struct v4l2_control *ctrl)
2390{
2391 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2392 int err = 0;
2393
2394 if (!bdev)
2395 return -ENODEV;
2396
2397 switch (ctrl->id) {
2398 case V4L2_CID_AUDIO_MUTE:
2399 if (ctrl->value) {
2400 if (bdev->power_state) {
2401 err = bcm2048_set_mute(bdev, ctrl->value);
2402 err |= bcm2048_deinit(bdev);
2403 }
2404 } else {
2405 if (!bdev->power_state) {
2406 err = bcm2048_init(bdev);
2407 err |= bcm2048_set_mute(bdev, ctrl->value);
2408 }
2409 }
2410 break;
2411 }
2412
2413 return err;
2414}
2415
2416static int bcm2048_vidioc_g_audio(struct file *file, void *priv,
2417 struct v4l2_audio *audio)
2418{
2419 if (audio->index > 1)
2420 return -EINVAL;
2421
2422 strncpy(audio->name, "Radio", 32);
2423 audio->capability = V4L2_AUDCAP_STEREO;
2424
2425 return 0;
2426}
2427
2428static int bcm2048_vidioc_s_audio(struct file *file, void *priv,
2429 const struct v4l2_audio *audio)
2430{
2431 if (audio->index != 0)
2432 return -EINVAL;
2433
2434 return 0;
2435}
2436
2437static int bcm2048_vidioc_g_tuner(struct file *file, void *priv,
2438 struct v4l2_tuner *tuner)
2439{
2440 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2441 s8 f_error;
2442 s8 rssi;
2443
2444 if (!bdev)
2445 return -ENODEV;
2446
2447 if (tuner->index > 0)
2448 return -EINVAL;
2449
2450 strncpy(tuner->name, "FM Receiver", 32);
2451 tuner->type = V4L2_TUNER_RADIO;
2452 tuner->rangelow =
2453 dev_to_v4l2(bcm2048_get_region_bottom_frequency(bdev));
2454 tuner->rangehigh =
2455 dev_to_v4l2(bcm2048_get_region_top_frequency(bdev));
2456 tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
2457 tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW;
2458 tuner->audmode = V4L2_TUNER_MODE_STEREO;
2459 tuner->afc = 0;
2460 if (bdev->power_state) {
2461 /*
2462 * Report frequencies with high carrier errors to have zero
2463 * signal level
2464 */
2465 f_error = bcm2048_get_fm_carrier_error(bdev);
2466 if (f_error < BCM2048_FREQ_ERROR_FLOOR ||
2467 f_error > BCM2048_FREQ_ERROR_ROOF) {
2468 tuner->signal = 0;
2469 } else {
2470 /*
2471 * RSSI level -60 dB is defined to report full
2472 * signal strenght
2473 */
2474 rssi = bcm2048_get_fm_rssi(bdev);
2475 if (rssi >= BCM2048_RSSI_LEVEL_BASE) {
2476 tuner->signal = 0xFFFF;
2477 } else if (rssi > BCM2048_RSSI_LEVEL_ROOF) {
2478 tuner->signal = (rssi +
2479 BCM2048_RSSI_LEVEL_ROOF_NEG)
2480 * BCM2048_SIGNAL_MULTIPLIER;
2481 } else {
2482 tuner->signal = 0;
2483 }
2484 }
2485 } else {
2486 tuner->signal = 0;
2487 }
2488
2489 return 0;
2490}
2491
2492static int bcm2048_vidioc_s_tuner(struct file *file, void *priv,
2493 const struct v4l2_tuner *tuner)
2494{
2495 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2496
2497 if (!bdev)
2498 return -ENODEV;
2499
2500 if (tuner->index > 0)
2501 return -EINVAL;
2502
2503 return 0;
2504}
2505
2506static int bcm2048_vidioc_g_frequency(struct file *file, void *priv,
2507 struct v4l2_frequency *freq)
2508{
2509 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2510 int err = 0;
2511 int f;
2512
2513 if (!bdev->power_state)
2514 return -ENODEV;
2515
2516 freq->type = V4L2_TUNER_RADIO;
2517 f = bcm2048_get_fm_frequency(bdev);
2518
2519 if (f < 0)
2520 err = f;
2521 else
2522 freq->frequency = dev_to_v4l2(f);
2523
2524 return err;
2525}
2526
2527static int bcm2048_vidioc_s_frequency(struct file *file, void *priv,
2528 const struct v4l2_frequency *freq)
2529{
2530 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2531 int err;
2532
2533 if (freq->type != V4L2_TUNER_RADIO)
2534 return -EINVAL;
2535
2536 if (!bdev->power_state)
2537 return -ENODEV;
2538
2539 err = bcm2048_set_fm_frequency(bdev, v4l2_to_dev(freq->frequency));
2540 err |= bcm2048_set_fm_search_tune_mode(bdev, BCM2048_FM_PRE_SET_MODE);
2541
2542 return err;
2543}
2544
2545static int bcm2048_vidioc_s_hw_freq_seek(struct file *file, void *priv,
2546 const struct v4l2_hw_freq_seek *seek)
2547{
2548 struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
2549 int err;
2550
2551 if (!bdev->power_state)
2552 return -ENODEV;
2553
2554 if ((seek->tuner != 0) || (seek->type != V4L2_TUNER_RADIO))
2555 return -EINVAL;
2556
2557 err = bcm2048_set_fm_search_mode_direction(bdev, seek->seek_upward);
2558 err |= bcm2048_set_fm_search_tune_mode(bdev,
2559 BCM2048_FM_AUTO_SEARCH_MODE);
2560
2561 return err;
2562}
2563
2564static struct v4l2_ioctl_ops bcm2048_ioctl_ops = {
2565 .vidioc_querycap = bcm2048_vidioc_querycap,
2566 .vidioc_g_input = bcm2048_vidioc_g_input,
2567 .vidioc_s_input = bcm2048_vidioc_s_input,
2568 .vidioc_queryctrl = bcm2048_vidioc_queryctrl,
2569 .vidioc_g_ctrl = bcm2048_vidioc_g_ctrl,
2570 .vidioc_s_ctrl = bcm2048_vidioc_s_ctrl,
2571 .vidioc_g_audio = bcm2048_vidioc_g_audio,
2572 .vidioc_s_audio = bcm2048_vidioc_s_audio,
2573 .vidioc_g_tuner = bcm2048_vidioc_g_tuner,
2574 .vidioc_s_tuner = bcm2048_vidioc_s_tuner,
2575 .vidioc_g_frequency = bcm2048_vidioc_g_frequency,
2576 .vidioc_s_frequency = bcm2048_vidioc_s_frequency,
2577 .vidioc_s_hw_freq_seek = bcm2048_vidioc_s_hw_freq_seek,
2578};
2579
2580/*
2581 * bcm2048_viddev_template - video device interface
2582 */
2583static struct video_device bcm2048_viddev_template = {
2584 .fops = &bcm2048_fops,
2585 .name = BCM2048_DRIVER_NAME,
2586 .release = video_device_release,
2587 .ioctl_ops = &bcm2048_ioctl_ops,
2588};
2589
2590/*
2591 * I2C driver interface
2592 */
2593static int bcm2048_i2c_driver_probe(struct i2c_client *client,
2594 const struct i2c_device_id *id)
2595{
2596 struct bcm2048_device *bdev;
2597 int err, skip_release = 0;
2598
2599 bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
2600 if (!bdev) {
2601 dev_dbg(&client->dev, "Failed to alloc video device.\n");
2602 err = -ENOMEM;
2603 goto exit;
2604 }
2605
2606 bdev->videodev = video_device_alloc();
2607 if (!bdev->videodev) {
2608 dev_dbg(&client->dev, "Failed to alloc video device.\n");
2609 err = -ENOMEM;
2610 goto free_bdev;
2611 }
2612
2613 bdev->client = client;
2614 i2c_set_clientdata(client, bdev);
2615 mutex_init(&bdev->mutex);
2616 init_completion(&bdev->compl);
2617 INIT_WORK(&bdev->work, bcm2048_work);
2618
2619 if (client->irq) {
2620 err = request_irq(client->irq,
2621 bcm2048_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
2622 client->name, bdev);
2623 if (err < 0) {
2624 dev_err(&client->dev, "Could not request IRQ\n");
2625 goto free_vdev;
2626 }
2627 dev_dbg(&client->dev, "IRQ requested.\n");
2628 } else {
2629 dev_dbg(&client->dev, "IRQ not configured. Using timeouts.\n");
2630 }
2631
2632 *bdev->videodev = bcm2048_viddev_template;
2633 video_set_drvdata(bdev->videodev, bdev);
2634 if (video_register_device(bdev->videodev, VFL_TYPE_RADIO, radio_nr)) {
2635 dev_dbg(&client->dev, "Could not register video device.\n");
2636 err = -EIO;
2637 goto free_irq;
2638 }
2639
2640 err = bcm2048_sysfs_register_properties(bdev);
2641 if (err < 0) {
2642 dev_dbg(&client->dev, "Could not register sysfs interface.\n");
2643 goto free_registration;
2644 }
2645
2646 err = bcm2048_probe(bdev);
2647 if (err < 0) {
2648 dev_dbg(&client->dev, "Failed to probe device information.\n");
2649 goto free_sysfs;
2650 }
2651
2652 return 0;
2653
2654free_sysfs:
2655 bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
2656free_registration:
2657 video_unregister_device(bdev->videodev);
2658 /* video_unregister_device frees bdev->videodev */
2659 bdev->videodev = NULL;
2660 skip_release = 1;
2661free_irq:
2662 if (client->irq)
2663 free_irq(client->irq, bdev);
2664free_vdev:
2665 if (!skip_release)
2666 video_device_release(bdev->videodev);
2667 i2c_set_clientdata(client, NULL);
2668free_bdev:
2669 kfree(bdev);
2670exit:
2671 return err;
2672}
2673
2674static int __exit bcm2048_i2c_driver_remove(struct i2c_client *client)
2675{
2676 struct bcm2048_device *bdev = i2c_get_clientdata(client);
2677 struct video_device *vd;
2678
2679 if (!client->adapter)
2680 return -ENODEV;
2681
2682 if (bdev) {
2683 vd = bdev->videodev;
2684
2685 bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
2686
2687 if (vd)
2688 video_unregister_device(vd);
2689
2690 if (bdev->power_state)
2691 bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
2692
2693 if (client->irq > 0)
2694 free_irq(client->irq, bdev);
2695
2696 cancel_work_sync(&bdev->work);
2697
2698 kfree(bdev);
2699 }
2700
2701 i2c_set_clientdata(client, NULL);
2702
2703 return 0;
2704}
2705
2706/*
2707 * bcm2048_i2c_driver - i2c driver interface
2708 */
2709static const struct i2c_device_id bcm2048_id[] = {
2710 { "bcm2048" , 0 },
2711 { },
2712};
2713MODULE_DEVICE_TABLE(i2c, bcm2048_id);
2714
2715static struct i2c_driver bcm2048_i2c_driver = {
2716 .driver = {
2717 .name = BCM2048_DRIVER_NAME,
2718 },
2719 .probe = bcm2048_i2c_driver_probe,
2720 .remove = __exit_p(bcm2048_i2c_driver_remove),
2721 .id_table = bcm2048_id,
2722};
2723
2724/*
2725 * Module Interface
2726 */
2727static int __init bcm2048_module_init(void)
2728{
2729 pr_info(BCM2048_DRIVER_DESC "\n");
2730
2731 return i2c_add_driver(&bcm2048_i2c_driver);
2732}
2733module_init(bcm2048_module_init);
2734
2735static void __exit bcm2048_module_exit(void)
2736{
2737 i2c_del_driver(&bcm2048_i2c_driver);
2738}
2739module_exit(bcm2048_module_exit);
2740
2741MODULE_LICENSE("GPL");
2742MODULE_AUTHOR(BCM2048_DRIVER_AUTHOR);
2743MODULE_DESCRIPTION(BCM2048_DRIVER_DESC);
2744MODULE_VERSION("0.0.2");
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.h b/drivers/staging/media/bcm2048/radio-bcm2048.h
new file mode 100644
index 000000000000..4c90a32db795
--- /dev/null
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.h
@@ -0,0 +1,30 @@
1/*
2 * drivers/staging/media/radio-bcm2048.h
3 *
4 * Property and command definitions for bcm2048 radio receiver chip.
5 *
6 * Copyright (C) Nokia Corporation
7 * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#ifndef BCM2048_H
25#define BCM2048_H
26
27#define BCM2048_NAME "bcm2048"
28#define BCM2048_I2C_ADDR 0x22
29
30#endif /* ifndef BCM2048_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index ff48fce94fcb..b942bf73c43f 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -19,6 +19,7 @@
19 * Prabhakar Lad <prabhakar.lad@ti.com> 19 * Prabhakar Lad <prabhakar.lad@ti.com>
20 */ 20 */
21 21
22#include <linux/delay.h>
22#include "dm365_isif.h" 23#include "dm365_isif.h"
23#include "vpfe_mc_capture.h" 24#include "vpfe_mc_capture.h"
24 25
@@ -918,7 +919,7 @@ isif_config_dfc(struct vpfe_isif_device *isif, struct vpfe_isif_dfc *vdfc)
918 (0 << ISIF_VDFC_EN_SHIFT), DFCCTL); 919 (0 << ISIF_VDFC_EN_SHIFT), DFCCTL);
919 920
920 isif_write(isif->isif_cfg.base_addr, 0x6, DFCMEMCTL); 921 isif_write(isif->isif_cfg.base_addr, 0x6, DFCMEMCTL);
921 for (i = 0 ; i < vdfc->num_vdefects; i++) { 922 for (i = 0; i < vdfc->num_vdefects; i++) {
922 count = DFC_WRITE_WAIT_COUNT; 923 count = DFC_WRITE_WAIT_COUNT;
923 while (count && 924 while (count &&
924 (isif_read(isif->isif_cfg.base_addr, DFCMEMCTL) & 0x2)) 925 (isif_read(isif->isif_cfg.base_addr, DFCMEMCTL) & 0x2))
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 24d98a6866bb..1f3b0f9a8d10 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -346,7 +346,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
346 } 346 }
347 mutex_unlock(&mdev->graph_mutex); 347 mutex_unlock(&mdev->graph_mutex);
348 348
349 return (ret == 0) ? ret : -ETIMEDOUT ; 349 return ret ? -ETIMEDOUT : 0;
350} 350}
351 351
352/* 352/*
@@ -1201,6 +1201,8 @@ static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count)
1201 unsigned long addr; 1201 unsigned long addr;
1202 int ret; 1202 int ret;
1203 1203
1204 if (count == 0)
1205 return -ENOBUFS;
1204 ret = mutex_lock_interruptible(&video->lock); 1206 ret = mutex_lock_interruptible(&video->lock);
1205 if (ret) 1207 if (ret)
1206 goto streamoff; 1208 goto streamoff;
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 41d110f8bc02..0b589892351a 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -220,7 +220,7 @@ static void rbuf_write(int signal)
220 wptr = nwptr; 220 wptr = nwptr;
221} 221}
222 222
223static void irq_handler(void *blah) 223static void lirc_lirc_irq_handler(void *blah)
224{ 224{
225 struct timeval tv; 225 struct timeval tv;
226 static struct timeval lasttv; 226 static struct timeval lasttv;
@@ -659,7 +659,7 @@ static int __init lirc_parallel_init(void)
659 goto exit_device_put; 659 goto exit_device_put;
660 } 660 }
661 ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME, 661 ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
662 pf, kf, irq_handler, 0, NULL); 662 pf, kf, lirc_lirc_irq_handler, 0, NULL);
663 parport_put_port(pport); 663 parport_put_port(pport);
664 if (ppdevice == NULL) { 664 if (ppdevice == NULL) {
665 pr_notice("parport_register_device() failed\n"); 665 pr_notice("parport_register_device() failed\n");
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index abe0d5caa20b..10c685d5de7c 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -650,7 +650,7 @@ static void frbwrite(int l)
650 rbwrite(l); 650 rbwrite(l);
651} 651}
652 652
653static irqreturn_t irq_handler(int i, void *blah) 653static irqreturn_t lirc_irq_handler(int i, void *blah)
654{ 654{
655 struct timeval tv; 655 struct timeval tv;
656 int counter, dcd; 656 int counter, dcd;
@@ -852,7 +852,7 @@ static int lirc_serial_probe(struct platform_device *dev)
852 return result; 852 return result;
853#endif 853#endif
854 854
855 result = request_irq(irq, irq_handler, 855 result = request_irq(irq, lirc_irq_handler,
856 (share_irq ? IRQF_SHARED : 0), 856 (share_irq ? IRQF_SHARED : 0),
857 LIRC_DRIVER_NAME, (void *)&hardware); 857 LIRC_DRIVER_NAME, (void *)&hardware);
858 if (result < 0) { 858 if (result < 0) {
diff --git a/drivers/staging/media/omap24xx/Kconfig b/drivers/staging/media/omap24xx/Kconfig
new file mode 100644
index 000000000000..82e569a21c46
--- /dev/null
+++ b/drivers/staging/media/omap24xx/Kconfig
@@ -0,0 +1,35 @@
1config VIDEO_V4L2_INT_DEVICE
2 tristate
3
4config VIDEO_OMAP2
5 tristate "OMAP2 Camera Capture Interface driver (DEPRECATED)"
6 depends on VIDEO_DEV && ARCH_OMAP2
7 select VIDEOBUF_DMA_SG
8 select VIDEO_V4L2_INT_DEVICE
9 ---help---
10 This is a v4l2 driver for the TI OMAP2 camera capture interface
11
12 It uses the deprecated int-device API. Since this driver is no
13 longer actively maintained and nobody is interested in converting
14 it to the subdev API, this driver will be removed soon.
15
16 If you do want to keep this driver in the kernel, and are willing
17 to convert it to the subdev API, then please contact the linux-media
18 mailinglist.
19
20config VIDEO_TCM825X
21 tristate "TCM825x camera sensor support (DEPRECATED)"
22 depends on I2C && VIDEO_V4L2
23 depends on MEDIA_CAMERA_SUPPORT
24 select VIDEO_V4L2_INT_DEVICE
25 ---help---
26 This is a driver for the Toshiba TCM825x VGA camera sensor.
27 It is used for example in Nokia N800.
28
29 It uses the deprecated int-device API. Since this driver is no
30 longer actively maintained and nobody is interested in converting
31 it to the subdev API, this driver will be removed soon.
32
33 If you do want to keep this driver in the kernel, and are willing
34 to convert it to the subdev API, then please contact the linux-media
35 mailinglist.
diff --git a/drivers/staging/media/omap24xx/Makefile b/drivers/staging/media/omap24xx/Makefile
new file mode 100644
index 000000000000..c2e7175599c2
--- /dev/null
+++ b/drivers/staging/media/omap24xx/Makefile
@@ -0,0 +1,5 @@
1omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
2
3obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
4obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
5obj-$(CONFIG_VIDEO_V4L2_INT_DEVICE) += v4l2-int-device.o
diff --git a/drivers/media/platform/omap24xxcam-dma.c b/drivers/staging/media/omap24xx/omap24xxcam-dma.c
index 9c00776d6583..9c00776d6583 100644
--- a/drivers/media/platform/omap24xxcam-dma.c
+++ b/drivers/staging/media/omap24xx/omap24xxcam-dma.c
diff --git a/drivers/media/platform/omap24xxcam.c b/drivers/staging/media/omap24xx/omap24xxcam.c
index d2b440c842b3..d2b440c842b3 100644
--- a/drivers/media/platform/omap24xxcam.c
+++ b/drivers/staging/media/omap24xx/omap24xxcam.c
diff --git a/drivers/media/platform/omap24xxcam.h b/drivers/staging/media/omap24xx/omap24xxcam.h
index 7f6f79155537..233bb40cfec3 100644
--- a/drivers/media/platform/omap24xxcam.h
+++ b/drivers/staging/media/omap24xx/omap24xxcam.h
@@ -28,8 +28,8 @@
28#define OMAP24XXCAM_H 28#define OMAP24XXCAM_H
29 29
30#include <media/videobuf-dma-sg.h> 30#include <media/videobuf-dma-sg.h>
31#include <media/v4l2-int-device.h>
32#include <media/v4l2-device.h> 31#include <media/v4l2-device.h>
32#include "v4l2-int-device.h"
33 33
34/* 34/*
35 * 35 *
diff --git a/drivers/media/i2c/tcm825x.c b/drivers/staging/media/omap24xx/tcm825x.c
index 9252529fc5dd..b1ae8e9c7e14 100644
--- a/drivers/media/i2c/tcm825x.c
+++ b/drivers/staging/media/omap24xx/tcm825x.c
@@ -28,7 +28,7 @@
28 28
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <media/v4l2-int-device.h> 31#include "v4l2-int-device.h"
32 32
33#include "tcm825x.h" 33#include "tcm825x.h"
34 34
diff --git a/drivers/media/i2c/tcm825x.h b/drivers/staging/media/omap24xx/tcm825x.h
index 8ebab953963f..e2d1bcd0bcbe 100644
--- a/drivers/media/i2c/tcm825x.h
+++ b/drivers/staging/media/omap24xx/tcm825x.h
@@ -17,7 +17,7 @@
17 17
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19 19
20#include <media/v4l2-int-device.h> 20#include "v4l2-int-device.h"
21 21
22#define TCM825X_NAME "tcm825x" 22#define TCM825X_NAME "tcm825x"
23 23
diff --git a/drivers/media/v4l2-core/v4l2-int-device.c b/drivers/staging/media/omap24xx/v4l2-int-device.c
index f4473494af7a..427a89033a1d 100644
--- a/drivers/media/v4l2-core/v4l2-int-device.c
+++ b/drivers/staging/media/omap24xx/v4l2-int-device.c
@@ -28,7 +28,7 @@
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/module.h> 29#include <linux/module.h>
30 30
31#include <media/v4l2-int-device.h> 31#include "v4l2-int-device.h"
32 32
33static DEFINE_MUTEX(mutex); 33static DEFINE_MUTEX(mutex);
34static LIST_HEAD(int_list); 34static LIST_HEAD(int_list);
diff --git a/include/media/v4l2-int-device.h b/drivers/staging/media/omap24xx/v4l2-int-device.h
index 0286c95814ff..0286c95814ff 100644
--- a/include/media/v4l2-int-device.h
+++ b/drivers/staging/media/omap24xx/v4l2-int-device.h
diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig
new file mode 100644
index 000000000000..b9fe753969bd
--- /dev/null
+++ b/drivers/staging/media/omap4iss/Kconfig
@@ -0,0 +1,12 @@
1config VIDEO_OMAP4
2 bool "OMAP 4 Camera support"
3 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C && ARCH_OMAP4
4 select VIDEOBUF2_DMA_CONTIG
5 ---help---
6 Driver for an OMAP 4 ISS controller.
7
8config VIDEO_OMAP4_DEBUG
9 bool "OMAP 4 Camera debug messages"
10 depends on VIDEO_OMAP4
11 ---help---
12 Enable debug messages on OMAP 4 ISS controller driver.
diff --git a/drivers/staging/media/omap4iss/Makefile b/drivers/staging/media/omap4iss/Makefile
new file mode 100644
index 000000000000..a716ce936cf6
--- /dev/null
+++ b/drivers/staging/media/omap4iss/Makefile
@@ -0,0 +1,6 @@
1# Makefile for OMAP4 ISS driver
2
3omap4-iss-objs += \
4 iss.o iss_csi2.o iss_csiphy.o iss_ipipeif.o iss_ipipe.o iss_resizer.o iss_video.o
5
6obj-$(CONFIG_VIDEO_OMAP4) += omap4-iss.o
diff --git a/drivers/staging/media/omap4iss/TODO b/drivers/staging/media/omap4iss/TODO
new file mode 100644
index 000000000000..fcde88860a2c
--- /dev/null
+++ b/drivers/staging/media/omap4iss/TODO
@@ -0,0 +1,4 @@
1* Make the driver compile as a module
2* Fix FIFO/buffer overflows and underflows
3* Replace dummy resizer code with a real implementation
4* Fix checkpatch errors and warnings
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
new file mode 100644
index 000000000000..61fbfcd13582
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -0,0 +1,1563 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver
3 *
4 * Copyright (C) 2012, Texas Instruments
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/i2c.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/sched.h>
24#include <linux/vmalloc.h>
25
26#include <media/v4l2-common.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-ctrls.h>
29
30#include "iss.h"
31#include "iss_regs.h"
32
33#define ISS_PRINT_REGISTER(iss, name)\
34 dev_dbg(iss->dev, "###ISS " #name "=0x%08x\n", \
35 iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_##name))
36
37static void iss_print_status(struct iss_device *iss)
38{
39 dev_dbg(iss->dev, "-------------ISS HL Register dump-------------\n");
40
41 ISS_PRINT_REGISTER(iss, HL_REVISION);
42 ISS_PRINT_REGISTER(iss, HL_SYSCONFIG);
43 ISS_PRINT_REGISTER(iss, HL_IRQSTATUS(5));
44 ISS_PRINT_REGISTER(iss, HL_IRQENABLE_SET(5));
45 ISS_PRINT_REGISTER(iss, HL_IRQENABLE_CLR(5));
46 ISS_PRINT_REGISTER(iss, CTRL);
47 ISS_PRINT_REGISTER(iss, CLKCTRL);
48 ISS_PRINT_REGISTER(iss, CLKSTAT);
49
50 dev_dbg(iss->dev, "-----------------------------------------------\n");
51}
52
53/*
54 * omap4iss_flush - Post pending L3 bus writes by doing a register readback
55 * @iss: OMAP4 ISS device
56 *
57 * In order to force posting of pending writes, we need to write and
58 * readback the same register, in this case the revision register.
59 *
60 * See this link for reference:
61 * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
62 */
63void omap4iss_flush(struct iss_device *iss)
64{
65 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION, 0);
66 iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
67}
68
69/*
70 * iss_isp_enable_interrupts - Enable ISS ISP interrupts.
71 * @iss: OMAP4 ISS device
72 */
73static void omap4iss_isp_enable_interrupts(struct iss_device *iss)
74{
75 static const u32 isp_irq = ISP5_IRQ_OCP_ERR |
76 ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
77 ISP5_IRQ_RSZ_FIFO_OVF |
78 ISP5_IRQ_RSZ_INT_DMA |
79 ISP5_IRQ_ISIF_INT(0);
80
81 /* Enable ISP interrupts */
82 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0), isp_irq);
83 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_SET(0),
84 isp_irq);
85}
86
87/*
88 * iss_isp_disable_interrupts - Disable ISS interrupts.
89 * @iss: OMAP4 ISS device
90 */
91static void omap4iss_isp_disable_interrupts(struct iss_device *iss)
92{
93 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_CLR(0), ~0);
94}
95
96/*
97 * iss_enable_interrupts - Enable ISS interrupts.
98 * @iss: OMAP4 ISS device
99 */
100static void iss_enable_interrupts(struct iss_device *iss)
101{
102 static const u32 hl_irq = ISS_HL_IRQ_CSIA | ISS_HL_IRQ_CSIB
103 | ISS_HL_IRQ_ISP(0);
104
105 /* Enable HL interrupts */
106 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), hl_irq);
107 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_SET(5), hl_irq);
108
109 if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
110 omap4iss_isp_enable_interrupts(iss);
111}
112
113/*
114 * iss_disable_interrupts - Disable ISS interrupts.
115 * @iss: OMAP4 ISS device
116 */
117static void iss_disable_interrupts(struct iss_device *iss)
118{
119 if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
120 omap4iss_isp_disable_interrupts(iss);
121
122 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_CLR(5), ~0);
123}
124
125int omap4iss_get_external_info(struct iss_pipeline *pipe,
126 struct media_link *link)
127{
128 struct iss_device *iss =
129 container_of(pipe, struct iss_video, pipe)->iss;
130 struct v4l2_subdev_format fmt;
131 struct v4l2_ctrl *ctrl;
132 int ret;
133
134 if (!pipe->external)
135 return 0;
136
137 if (pipe->external_rate)
138 return 0;
139
140 memset(&fmt, 0, sizeof(fmt));
141
142 fmt.pad = link->source->index;
143 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
144 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
145 pad, get_fmt, NULL, &fmt);
146 if (ret < 0)
147 return -EPIPE;
148
149 pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp;
150
151 ctrl = v4l2_ctrl_find(pipe->external->ctrl_handler,
152 V4L2_CID_PIXEL_RATE);
153 if (ctrl == NULL) {
154 dev_warn(iss->dev, "no pixel rate control in subdev %s\n",
155 pipe->external->name);
156 return -EPIPE;
157 }
158
159 pipe->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
160
161 return 0;
162}
163
164/*
165 * Configure the bridge. Valid inputs are
166 *
167 * IPIPEIF_INPUT_CSI2A: CSI2a receiver
168 * IPIPEIF_INPUT_CSI2B: CSI2b receiver
169 *
170 * The bridge and lane shifter are configured according to the selected input
171 * and the ISP platform data.
172 */
173void omap4iss_configure_bridge(struct iss_device *iss,
174 enum ipipeif_input_entity input)
175{
176 u32 issctrl_val;
177 u32 isp5ctrl_val;
178
179 issctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL);
180 issctrl_val &= ~ISS_CTRL_INPUT_SEL_MASK;
181 issctrl_val &= ~ISS_CTRL_CLK_DIV_MASK;
182
183 isp5ctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL);
184
185 switch (input) {
186 case IPIPEIF_INPUT_CSI2A:
187 issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2A;
188 break;
189
190 case IPIPEIF_INPUT_CSI2B:
191 issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2B;
192 break;
193
194 default:
195 return;
196 }
197
198 issctrl_val |= ISS_CTRL_SYNC_DETECT_VS_RAISING;
199
200 isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT | ISP5_CTRL_PSYNC_CLK_SEL |
201 ISP5_CTRL_SYNC_ENABLE;
202
203 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL, issctrl_val);
204 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val);
205}
206
207#if defined(DEBUG) && defined(ISS_ISR_DEBUG)
208static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus)
209{
210 static const char * const name[] = {
211 "ISP_0",
212 "ISP_1",
213 "ISP_2",
214 "ISP_3",
215 "CSIA",
216 "CSIB",
217 "CCP2_0",
218 "CCP2_1",
219 "CCP2_2",
220 "CCP2_3",
221 "CBUFF",
222 "BTE",
223 "SIMCOP_0",
224 "SIMCOP_1",
225 "SIMCOP_2",
226 "SIMCOP_3",
227 "CCP2_8",
228 "HS_VS",
229 "18",
230 "19",
231 "20",
232 "21",
233 "22",
234 "23",
235 "24",
236 "25",
237 "26",
238 "27",
239 "28",
240 "29",
241 "30",
242 "31",
243 };
244 unsigned int i;
245
246 dev_dbg(iss->dev, "ISS IRQ: ");
247
248 for (i = 0; i < ARRAY_SIZE(name); i++) {
249 if ((1 << i) & irqstatus)
250 pr_cont("%s ", name[i]);
251 }
252 pr_cont("\n");
253}
254
255static void iss_isp_isr_dbg(struct iss_device *iss, u32 irqstatus)
256{
257 static const char * const name[] = {
258 "ISIF_0",
259 "ISIF_1",
260 "ISIF_2",
261 "ISIF_3",
262 "IPIPEREQ",
263 "IPIPELAST_PIX",
264 "IPIPEDMA",
265 "IPIPEBSC",
266 "IPIPEHST",
267 "IPIPEIF",
268 "AEW",
269 "AF",
270 "H3A",
271 "RSZ_REG",
272 "RSZ_LAST_PIX",
273 "RSZ_DMA",
274 "RSZ_CYC_RZA",
275 "RSZ_CYC_RZB",
276 "RSZ_FIFO_OVF",
277 "RSZ_FIFO_IN_BLK_ERR",
278 "20",
279 "21",
280 "RSZ_EOF0",
281 "RSZ_EOF1",
282 "H3A_EOF",
283 "IPIPE_EOF",
284 "26",
285 "IPIPE_DPC_INI",
286 "IPIPE_DPC_RNEW0",
287 "IPIPE_DPC_RNEW1",
288 "30",
289 "OCP_ERR",
290 };
291 unsigned int i;
292
293 dev_dbg(iss->dev, "ISP IRQ: ");
294
295 for (i = 0; i < ARRAY_SIZE(name); i++) {
296 if ((1 << i) & irqstatus)
297 pr_cont("%s ", name[i]);
298 }
299 pr_cont("\n");
300}
301#endif
302
303/*
304 * iss_isr - Interrupt Service Routine for ISS module.
305 * @irq: Not used currently.
306 * @_iss: Pointer to the OMAP4 ISS device
307 *
308 * Handles the corresponding callback if plugged in.
309 *
310 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
311 * IRQ wasn't handled.
312 */
313static irqreturn_t iss_isr(int irq, void *_iss)
314{
315 static const u32 ipipeif_events = ISP5_IRQ_IPIPEIF_IRQ |
316 ISP5_IRQ_ISIF_INT(0);
317 static const u32 resizer_events = ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
318 ISP5_IRQ_RSZ_FIFO_OVF |
319 ISP5_IRQ_RSZ_INT_DMA;
320 struct iss_device *iss = _iss;
321 u32 irqstatus;
322
323 irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5));
324 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), irqstatus);
325
326 if (irqstatus & ISS_HL_IRQ_CSIA)
327 omap4iss_csi2_isr(&iss->csi2a);
328
329 if (irqstatus & ISS_HL_IRQ_CSIB)
330 omap4iss_csi2_isr(&iss->csi2b);
331
332 if (irqstatus & ISS_HL_IRQ_ISP(0)) {
333 u32 isp_irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1,
334 ISP5_IRQSTATUS(0));
335 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0),
336 isp_irqstatus);
337
338 if (isp_irqstatus & ISP5_IRQ_OCP_ERR)
339 dev_dbg(iss->dev, "ISP5 OCP Error!\n");
340
341 if (isp_irqstatus & ipipeif_events) {
342 omap4iss_ipipeif_isr(&iss->ipipeif,
343 isp_irqstatus & ipipeif_events);
344 }
345
346 if (isp_irqstatus & resizer_events)
347 omap4iss_resizer_isr(&iss->resizer,
348 isp_irqstatus & resizer_events);
349
350#if defined(DEBUG) && defined(ISS_ISR_DEBUG)
351 iss_isp_isr_dbg(iss, isp_irqstatus);
352#endif
353 }
354
355 omap4iss_flush(iss);
356
357#if defined(DEBUG) && defined(ISS_ISR_DEBUG)
358 iss_isr_dbg(iss, irqstatus);
359#endif
360
361 return IRQ_HANDLED;
362}
363
364/* -----------------------------------------------------------------------------
365 * Pipeline power management
366 *
367 * Entities must be powered up when part of a pipeline that contains at least
368 * one open video device node.
369 *
370 * To achieve this use the entity use_count field to track the number of users.
371 * For entities corresponding to video device nodes the use_count field stores
372 * the users count of the node. For entities corresponding to subdevs the
373 * use_count field stores the total number of users of all video device nodes
374 * in the pipeline.
375 *
376 * The omap4iss_pipeline_pm_use() function must be called in the open() and
377 * close() handlers of video device nodes. It increments or decrements the use
378 * count of all subdev entities in the pipeline.
379 *
380 * To react to link management on powered pipelines, the link setup notification
381 * callback updates the use count of all entities in the source and sink sides
382 * of the link.
383 */
384
385/*
386 * iss_pipeline_pm_use_count - Count the number of users of a pipeline
387 * @entity: The entity
388 *
389 * Return the total number of users of all video device nodes in the pipeline.
390 */
391static int iss_pipeline_pm_use_count(struct media_entity *entity)
392{
393 struct media_entity_graph graph;
394 int use = 0;
395
396 media_entity_graph_walk_start(&graph, entity);
397
398 while ((entity = media_entity_graph_walk_next(&graph))) {
399 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
400 use += entity->use_count;
401 }
402
403 return use;
404}
405
406/*
407 * iss_pipeline_pm_power_one - Apply power change to an entity
408 * @entity: The entity
409 * @change: Use count change
410 *
411 * Change the entity use count by @change. If the entity is a subdev update its
412 * power state by calling the core::s_power operation when the use count goes
413 * from 0 to != 0 or from != 0 to 0.
414 *
415 * Return 0 on success or a negative error code on failure.
416 */
417static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
418{
419 struct v4l2_subdev *subdev;
420
421 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
422 ? media_entity_to_v4l2_subdev(entity) : NULL;
423
424 if (entity->use_count == 0 && change > 0 && subdev != NULL) {
425 int ret;
426
427 ret = v4l2_subdev_call(subdev, core, s_power, 1);
428 if (ret < 0 && ret != -ENOIOCTLCMD)
429 return ret;
430 }
431
432 entity->use_count += change;
433 WARN_ON(entity->use_count < 0);
434
435 if (entity->use_count == 0 && change < 0 && subdev != NULL)
436 v4l2_subdev_call(subdev, core, s_power, 0);
437
438 return 0;
439}
440
441/*
442 * iss_pipeline_pm_power - Apply power change to all entities in a pipeline
443 * @entity: The entity
444 * @change: Use count change
445 *
446 * Walk the pipeline to update the use count and the power state of all non-node
447 * entities.
448 *
449 * Return 0 on success or a negative error code on failure.
450 */
451static int iss_pipeline_pm_power(struct media_entity *entity, int change)
452{
453 struct media_entity_graph graph;
454 struct media_entity *first = entity;
455 int ret = 0;
456
457 if (!change)
458 return 0;
459
460 media_entity_graph_walk_start(&graph, entity);
461
462 while (!ret && (entity = media_entity_graph_walk_next(&graph)))
463 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
464 ret = iss_pipeline_pm_power_one(entity, change);
465
466 if (!ret)
467 return 0;
468
469 media_entity_graph_walk_start(&graph, first);
470
471 while ((first = media_entity_graph_walk_next(&graph))
472 && first != entity)
473 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
474 iss_pipeline_pm_power_one(first, -change);
475
476 return ret;
477}
478
479/*
480 * omap4iss_pipeline_pm_use - Update the use count of an entity
481 * @entity: The entity
482 * @use: Use (1) or stop using (0) the entity
483 *
484 * Update the use count of all entities in the pipeline and power entities on or
485 * off accordingly.
486 *
487 * Return 0 on success or a negative error code on failure. Powering entities
488 * off is assumed to never fail. No failure can occur when the use parameter is
489 * set to 0.
490 */
491int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
492{
493 int change = use ? 1 : -1;
494 int ret;
495
496 mutex_lock(&entity->parent->graph_mutex);
497
498 /* Apply use count to node. */
499 entity->use_count += change;
500 WARN_ON(entity->use_count < 0);
501
502 /* Apply power change to connected non-nodes. */
503 ret = iss_pipeline_pm_power(entity, change);
504 if (ret < 0)
505 entity->use_count -= change;
506
507 mutex_unlock(&entity->parent->graph_mutex);
508
509 return ret;
510}
511
512/*
513 * iss_pipeline_link_notify - Link management notification callback
514 * @link: The link
515 * @flags: New link flags that will be applied
516 *
517 * React to link management on powered pipelines by updating the use count of
518 * all entities in the source and sink sides of the link. Entities are powered
519 * on or off accordingly.
520 *
521 * Return 0 on success or a negative error code on failure. Powering entities
522 * off is assumed to never fail. This function will not fail for disconnection
523 * events.
524 */
525static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
526 unsigned int notification)
527{
528 struct media_entity *source = link->source->entity;
529 struct media_entity *sink = link->sink->entity;
530 int source_use = iss_pipeline_pm_use_count(source);
531 int sink_use = iss_pipeline_pm_use_count(sink);
532 int ret;
533
534 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
535 !(link->flags & MEDIA_LNK_FL_ENABLED)) {
536 /* Powering off entities is assumed to never fail. */
537 iss_pipeline_pm_power(source, -sink_use);
538 iss_pipeline_pm_power(sink, -source_use);
539 return 0;
540 }
541
542 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
543 (flags & MEDIA_LNK_FL_ENABLED)) {
544 ret = iss_pipeline_pm_power(source, sink_use);
545 if (ret < 0)
546 return ret;
547
548 ret = iss_pipeline_pm_power(sink, source_use);
549 if (ret < 0)
550 iss_pipeline_pm_power(source, -sink_use);
551
552 return ret;
553 }
554
555 return 0;
556}
557
558/* -----------------------------------------------------------------------------
559 * Pipeline stream management
560 */
561
562/*
563 * iss_pipeline_enable - Enable streaming on a pipeline
564 * @pipe: ISS pipeline
565 * @mode: Stream mode (single shot or continuous)
566 *
567 * Walk the entities chain starting at the pipeline output video node and start
568 * all modules in the chain in the given mode.
569 *
570 * Return 0 if successful, or the return value of the failed video::s_stream
571 * operation otherwise.
572 */
573static int iss_pipeline_enable(struct iss_pipeline *pipe,
574 enum iss_pipeline_stream_state mode)
575{
576 struct iss_device *iss = pipe->output->iss;
577 struct media_entity *entity;
578 struct media_pad *pad;
579 struct v4l2_subdev *subdev;
580 unsigned long flags;
581 int ret;
582
583 /* If one of the entities in the pipeline has crashed it will not work
584 * properly. Refuse to start streaming in that case. This check must be
585 * performed before the loop below to avoid starting entities if the
586 * pipeline won't start anyway (those entities would then likely fail to
587 * stop, making the problem worse).
588 */
589 if (pipe->entities & iss->crashed)
590 return -EIO;
591
592 spin_lock_irqsave(&pipe->lock, flags);
593 pipe->state &= ~(ISS_PIPELINE_IDLE_INPUT | ISS_PIPELINE_IDLE_OUTPUT);
594 spin_unlock_irqrestore(&pipe->lock, flags);
595
596 pipe->do_propagation = false;
597
598 entity = &pipe->output->video.entity;
599 while (1) {
600 pad = &entity->pads[0];
601 if (!(pad->flags & MEDIA_PAD_FL_SINK))
602 break;
603
604 pad = media_entity_remote_pad(pad);
605 if (pad == NULL ||
606 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
607 break;
608
609 entity = pad->entity;
610 subdev = media_entity_to_v4l2_subdev(entity);
611
612 ret = v4l2_subdev_call(subdev, video, s_stream, mode);
613 if (ret < 0 && ret != -ENOIOCTLCMD)
614 return ret;
615 }
616 iss_print_status(pipe->output->iss);
617 return 0;
618}
619
620/*
621 * iss_pipeline_disable - Disable streaming on a pipeline
622 * @pipe: ISS pipeline
623 *
624 * Walk the entities chain starting at the pipeline output video node and stop
625 * all modules in the chain. Wait synchronously for the modules to be stopped if
626 * necessary.
627 */
628static int iss_pipeline_disable(struct iss_pipeline *pipe)
629{
630 struct iss_device *iss = pipe->output->iss;
631 struct media_entity *entity;
632 struct media_pad *pad;
633 struct v4l2_subdev *subdev;
634 int failure = 0;
635 int ret;
636
637 entity = &pipe->output->video.entity;
638 while (1) {
639 pad = &entity->pads[0];
640 if (!(pad->flags & MEDIA_PAD_FL_SINK))
641 break;
642
643 pad = media_entity_remote_pad(pad);
644 if (pad == NULL ||
645 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
646 break;
647
648 entity = pad->entity;
649 subdev = media_entity_to_v4l2_subdev(entity);
650
651 ret = v4l2_subdev_call(subdev, video, s_stream, 0);
652 if (ret < 0) {
653 dev_dbg(iss->dev, "%s: module stop timeout.\n",
654 subdev->name);
655 /* If the entity failed to stopped, assume it has
656 * crashed. Mark it as such, the ISS will be reset when
657 * applications will release it.
658 */
659 iss->crashed |= 1U << subdev->entity.id;
660 failure = -ETIMEDOUT;
661 }
662 }
663
664 return failure;
665}
666
667/*
668 * omap4iss_pipeline_set_stream - Enable/disable streaming on a pipeline
669 * @pipe: ISS pipeline
670 * @state: Stream state (stopped, single shot or continuous)
671 *
672 * Set the pipeline to the given stream state. Pipelines can be started in
673 * single-shot or continuous mode.
674 *
675 * Return 0 if successful, or the return value of the failed video::s_stream
676 * operation otherwise. The pipeline state is not updated when the operation
677 * fails, except when stopping the pipeline.
678 */
679int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
680 enum iss_pipeline_stream_state state)
681{
682 int ret;
683
684 if (state == ISS_PIPELINE_STREAM_STOPPED)
685 ret = iss_pipeline_disable(pipe);
686 else
687 ret = iss_pipeline_enable(pipe, state);
688
689 if (ret == 0 || state == ISS_PIPELINE_STREAM_STOPPED)
690 pipe->stream_state = state;
691
692 return ret;
693}
694
695/*
696 * omap4iss_pipeline_cancel_stream - Cancel stream on a pipeline
697 * @pipe: ISS pipeline
698 *
699 * Cancelling a stream mark all buffers on all video nodes in the pipeline as
700 * erroneous and makes sure no new buffer can be queued. This function is called
701 * when a fatal error that prevents any further operation on the pipeline
702 * occurs.
703 */
704void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe)
705{
706 if (pipe->input)
707 omap4iss_video_cancel_stream(pipe->input);
708 if (pipe->output)
709 omap4iss_video_cancel_stream(pipe->output);
710}
711
712/*
713 * iss_pipeline_is_last - Verify if entity has an enabled link to the output
714 * video node
715 * @me: ISS module's media entity
716 *
717 * Returns 1 if the entity has an enabled link to the output video node or 0
718 * otherwise. It's true only while pipeline can have no more than one output
719 * node.
720 */
721static int iss_pipeline_is_last(struct media_entity *me)
722{
723 struct iss_pipeline *pipe;
724 struct media_pad *pad;
725
726 if (!me->pipe)
727 return 0;
728 pipe = to_iss_pipeline(me);
729 if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED)
730 return 0;
731 pad = media_entity_remote_pad(&pipe->output->pad);
732 return pad->entity == me;
733}
734
735static int iss_reset(struct iss_device *iss)
736{
737 unsigned long timeout = 0;
738
739 iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG,
740 ISS_HL_SYSCONFIG_SOFTRESET);
741
742 while (iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
743 ISS_HL_SYSCONFIG_SOFTRESET) {
744 if (timeout++ > 100) {
745 dev_alert(iss->dev, "cannot reset ISS\n");
746 return -ETIMEDOUT;
747 }
748 usleep_range(10, 10);
749 }
750
751 iss->crashed = 0;
752 return 0;
753}
754
755static int iss_isp_reset(struct iss_device *iss)
756{
757 unsigned long timeout = 0;
758
759 /* Fist, ensure that the ISP is IDLE (no transactions happening) */
760 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
761 ISP5_SYSCONFIG_STANDBYMODE_MASK,
762 ISP5_SYSCONFIG_STANDBYMODE_SMART);
763
764 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY);
765
766 for (;;) {
767 if (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
768 ISP5_CTRL_MSTANDBY_WAIT)
769 break;
770 if (timeout++ > 1000) {
771 dev_alert(iss->dev, "cannot set ISP5 to standby\n");
772 return -ETIMEDOUT;
773 }
774 usleep_range(1000, 1500);
775 }
776
777 /* Now finally, do the reset */
778 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
779 ISP5_SYSCONFIG_SOFTRESET);
780
781 timeout = 0;
782 while (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
783 ISP5_SYSCONFIG_SOFTRESET) {
784 if (timeout++ > 1000) {
785 dev_alert(iss->dev, "cannot reset ISP5\n");
786 return -ETIMEDOUT;
787 }
788 usleep_range(1000, 1500);
789 }
790
791 return 0;
792}
793
794/*
795 * iss_module_sync_idle - Helper to sync module with its idle state
796 * @me: ISS submodule's media entity
797 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
798 * @stopping: flag which tells module wants to stop
799 *
800 * This function checks if ISS submodule needs to wait for next interrupt. If
801 * yes, makes the caller to sleep while waiting for such event.
802 */
803int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
804 atomic_t *stopping)
805{
806 struct iss_pipeline *pipe = to_iss_pipeline(me);
807 struct iss_video *video = pipe->output;
808 unsigned long flags;
809
810 if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED ||
811 (pipe->stream_state == ISS_PIPELINE_STREAM_SINGLESHOT &&
812 !iss_pipeline_ready(pipe)))
813 return 0;
814
815 /*
816 * atomic_set() doesn't include memory barrier on ARM platform for SMP
817 * scenario. We'll call it here to avoid race conditions.
818 */
819 atomic_set(stopping, 1);
820 smp_wmb();
821
822 /*
823 * If module is the last one, it's writing to memory. In this case,
824 * it's necessary to check if the module is already paused due to
825 * DMA queue underrun or if it has to wait for next interrupt to be
826 * idle.
827 * If it isn't the last one, the function won't sleep but *stopping
828 * will still be set to warn next submodule caller's interrupt the
829 * module wants to be idle.
830 */
831 if (!iss_pipeline_is_last(me))
832 return 0;
833
834 spin_lock_irqsave(&video->qlock, flags);
835 if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
836 spin_unlock_irqrestore(&video->qlock, flags);
837 atomic_set(stopping, 0);
838 smp_wmb();
839 return 0;
840 }
841 spin_unlock_irqrestore(&video->qlock, flags);
842 if (!wait_event_timeout(*wait, !atomic_read(stopping),
843 msecs_to_jiffies(1000))) {
844 atomic_set(stopping, 0);
845 smp_wmb();
846 return -ETIMEDOUT;
847 }
848
849 return 0;
850}
851
852/*
853 * omap4iss_module_sync_is_stopped - Helper to verify if module was stopping
854 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
855 * @stopping: flag which tells module wants to stop
856 *
857 * This function checks if ISS submodule was stopping. In case of yes, it
858 * notices the caller by setting stopping to 0 and waking up the wait queue.
859 * Returns 1 if it was stopping or 0 otherwise.
860 */
861int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
862 atomic_t *stopping)
863{
864 if (atomic_cmpxchg(stopping, 1, 0)) {
865 wake_up(wait);
866 return 1;
867 }
868
869 return 0;
870}
871
872/* --------------------------------------------------------------------------
873 * Clock management
874 */
875
876#define ISS_CLKCTRL_MASK (ISS_CLKCTRL_CSI2_A |\
877 ISS_CLKCTRL_CSI2_B |\
878 ISS_CLKCTRL_ISP)
879
880static int __iss_subclk_update(struct iss_device *iss)
881{
882 u32 clk = 0;
883 int ret = 0, timeout = 1000;
884
885 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_A)
886 clk |= ISS_CLKCTRL_CSI2_A;
887
888 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_B)
889 clk |= ISS_CLKCTRL_CSI2_B;
890
891 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_ISP)
892 clk |= ISS_CLKCTRL_ISP;
893
894 iss_reg_update(iss, OMAP4_ISS_MEM_TOP, ISS_CLKCTRL,
895 ISS_CLKCTRL_MASK, clk);
896
897 /* Wait for HW assertion */
898 while (--timeout > 0) {
899 udelay(1);
900 if ((iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CLKSTAT) &
901 ISS_CLKCTRL_MASK) == clk)
902 break;
903 }
904
905 if (!timeout)
906 ret = -EBUSY;
907
908 return ret;
909}
910
911int omap4iss_subclk_enable(struct iss_device *iss,
912 enum iss_subclk_resource res)
913{
914 iss->subclk_resources |= res;
915
916 return __iss_subclk_update(iss);
917}
918
919int omap4iss_subclk_disable(struct iss_device *iss,
920 enum iss_subclk_resource res)
921{
922 iss->subclk_resources &= ~res;
923
924 return __iss_subclk_update(iss);
925}
926
927#define ISS_ISP5_CLKCTRL_MASK (ISP5_CTRL_BL_CLK_ENABLE |\
928 ISP5_CTRL_ISIF_CLK_ENABLE |\
929 ISP5_CTRL_H3A_CLK_ENABLE |\
930 ISP5_CTRL_RSZ_CLK_ENABLE |\
931 ISP5_CTRL_IPIPE_CLK_ENABLE |\
932 ISP5_CTRL_IPIPEIF_CLK_ENABLE)
933
934static void __iss_isp_subclk_update(struct iss_device *iss)
935{
936 u32 clk = 0;
937
938 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_ISIF)
939 clk |= ISP5_CTRL_ISIF_CLK_ENABLE;
940
941 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_H3A)
942 clk |= ISP5_CTRL_H3A_CLK_ENABLE;
943
944 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_RSZ)
945 clk |= ISP5_CTRL_RSZ_CLK_ENABLE;
946
947 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPE)
948 clk |= ISP5_CTRL_IPIPE_CLK_ENABLE;
949
950 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPEIF)
951 clk |= ISP5_CTRL_IPIPEIF_CLK_ENABLE;
952
953 if (clk)
954 clk |= ISP5_CTRL_BL_CLK_ENABLE;
955
956 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL,
957 ISS_ISP5_CLKCTRL_MASK, clk);
958}
959
960void omap4iss_isp_subclk_enable(struct iss_device *iss,
961 enum iss_isp_subclk_resource res)
962{
963 iss->isp_subclk_resources |= res;
964
965 __iss_isp_subclk_update(iss);
966}
967
968void omap4iss_isp_subclk_disable(struct iss_device *iss,
969 enum iss_isp_subclk_resource res)
970{
971 iss->isp_subclk_resources &= ~res;
972
973 __iss_isp_subclk_update(iss);
974}
975
976/*
977 * iss_enable_clocks - Enable ISS clocks
978 * @iss: OMAP4 ISS device
979 *
980 * Return 0 if successful, or clk_enable return value if any of tthem fails.
981 */
982static int iss_enable_clocks(struct iss_device *iss)
983{
984 int ret;
985
986 ret = clk_enable(iss->iss_fck);
987 if (ret) {
988 dev_err(iss->dev, "clk_enable iss_fck failed\n");
989 return ret;
990 }
991
992 ret = clk_enable(iss->iss_ctrlclk);
993 if (ret) {
994 dev_err(iss->dev, "clk_enable iss_ctrlclk failed\n");
995 clk_disable(iss->iss_fck);
996 return ret;
997 }
998
999 return 0;
1000}
1001
1002/*
1003 * iss_disable_clocks - Disable ISS clocks
1004 * @iss: OMAP4 ISS device
1005 */
1006static void iss_disable_clocks(struct iss_device *iss)
1007{
1008 clk_disable(iss->iss_ctrlclk);
1009 clk_disable(iss->iss_fck);
1010}
1011
1012static void iss_put_clocks(struct iss_device *iss)
1013{
1014 if (iss->iss_fck) {
1015 clk_put(iss->iss_fck);
1016 iss->iss_fck = NULL;
1017 }
1018
1019 if (iss->iss_ctrlclk) {
1020 clk_put(iss->iss_ctrlclk);
1021 iss->iss_ctrlclk = NULL;
1022 }
1023}
1024
1025static int iss_get_clocks(struct iss_device *iss)
1026{
1027 iss->iss_fck = clk_get(iss->dev, "iss_fck");
1028 if (IS_ERR(iss->iss_fck)) {
1029 dev_err(iss->dev, "Unable to get iss_fck clock info\n");
1030 iss_put_clocks(iss);
1031 return PTR_ERR(iss->iss_fck);
1032 }
1033
1034 iss->iss_ctrlclk = clk_get(iss->dev, "iss_ctrlclk");
1035 if (IS_ERR(iss->iss_ctrlclk)) {
1036 dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n");
1037 iss_put_clocks(iss);
1038 return PTR_ERR(iss->iss_fck);
1039 }
1040
1041 return 0;
1042}
1043
1044/*
1045 * omap4iss_get - Acquire the ISS resource.
1046 *
1047 * Initializes the clocks for the first acquire.
1048 *
1049 * Increment the reference count on the ISS. If the first reference is taken,
1050 * enable clocks and power-up all submodules.
1051 *
1052 * Return a pointer to the ISS device structure, or NULL if an error occurred.
1053 */
1054struct iss_device *omap4iss_get(struct iss_device *iss)
1055{
1056 struct iss_device *__iss = iss;
1057
1058 if (iss == NULL)
1059 return NULL;
1060
1061 mutex_lock(&iss->iss_mutex);
1062 if (iss->ref_count > 0)
1063 goto out;
1064
1065 if (iss_enable_clocks(iss) < 0) {
1066 __iss = NULL;
1067 goto out;
1068 }
1069
1070 iss_enable_interrupts(iss);
1071
1072out:
1073 if (__iss != NULL)
1074 iss->ref_count++;
1075 mutex_unlock(&iss->iss_mutex);
1076
1077 return __iss;
1078}
1079
1080/*
1081 * omap4iss_put - Release the ISS
1082 *
1083 * Decrement the reference count on the ISS. If the last reference is released,
1084 * power-down all submodules, disable clocks and free temporary buffers.
1085 */
1086void omap4iss_put(struct iss_device *iss)
1087{
1088 if (iss == NULL)
1089 return;
1090
1091 mutex_lock(&iss->iss_mutex);
1092 BUG_ON(iss->ref_count == 0);
1093 if (--iss->ref_count == 0) {
1094 iss_disable_interrupts(iss);
1095 /* Reset the ISS if an entity has failed to stop. This is the
1096 * only way to recover from such conditions, although it would
1097 * be worth investigating whether resetting the ISP only can't
1098 * fix the problem in some cases.
1099 */
1100 if (iss->crashed)
1101 iss_reset(iss);
1102 iss_disable_clocks(iss);
1103 }
1104 mutex_unlock(&iss->iss_mutex);
1105}
1106
1107static int iss_map_mem_resource(struct platform_device *pdev,
1108 struct iss_device *iss,
1109 enum iss_mem_resources res)
1110{
1111 struct resource *mem;
1112
1113 /* request the mem region for the camera registers */
1114
1115 mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
1116 if (!mem) {
1117 dev_err(iss->dev, "no mem resource?\n");
1118 return -ENODEV;
1119 }
1120
1121 if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
1122 dev_err(iss->dev,
1123 "cannot reserve camera register I/O region\n");
1124 return -ENODEV;
1125 }
1126 iss->res[res] = mem;
1127
1128 /* map the region */
1129 iss->regs[res] = ioremap_nocache(mem->start, resource_size(mem));
1130 if (!iss->regs[res]) {
1131 dev_err(iss->dev, "cannot map camera register I/O region\n");
1132 return -ENODEV;
1133 }
1134
1135 return 0;
1136}
1137
1138static void iss_unregister_entities(struct iss_device *iss)
1139{
1140 omap4iss_resizer_unregister_entities(&iss->resizer);
1141 omap4iss_ipipe_unregister_entities(&iss->ipipe);
1142 omap4iss_ipipeif_unregister_entities(&iss->ipipeif);
1143 omap4iss_csi2_unregister_entities(&iss->csi2a);
1144 omap4iss_csi2_unregister_entities(&iss->csi2b);
1145
1146 v4l2_device_unregister(&iss->v4l2_dev);
1147 media_device_unregister(&iss->media_dev);
1148}
1149
1150/*
1151 * iss_register_subdev_group - Register a group of subdevices
1152 * @iss: OMAP4 ISS device
1153 * @board_info: I2C subdevs board information array
1154 *
1155 * Register all I2C subdevices in the board_info array. The array must be
1156 * terminated by a NULL entry, and the first entry must be the sensor.
1157 *
1158 * Return a pointer to the sensor media entity if it has been successfully
1159 * registered, or NULL otherwise.
1160 */
1161static struct v4l2_subdev *
1162iss_register_subdev_group(struct iss_device *iss,
1163 struct iss_subdev_i2c_board_info *board_info)
1164{
1165 struct v4l2_subdev *sensor = NULL;
1166 unsigned int first;
1167
1168 if (board_info->board_info == NULL)
1169 return NULL;
1170
1171 for (first = 1; board_info->board_info; ++board_info, first = 0) {
1172 struct v4l2_subdev *subdev;
1173 struct i2c_adapter *adapter;
1174
1175 adapter = i2c_get_adapter(board_info->i2c_adapter_id);
1176 if (adapter == NULL) {
1177 dev_err(iss->dev,
1178 "%s: Unable to get I2C adapter %d for device %s\n",
1179 __func__, board_info->i2c_adapter_id,
1180 board_info->board_info->type);
1181 continue;
1182 }
1183
1184 subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter,
1185 board_info->board_info, NULL);
1186 if (subdev == NULL) {
1187 dev_err(iss->dev, "%s: Unable to register subdev %s\n",
1188 __func__, board_info->board_info->type);
1189 continue;
1190 }
1191
1192 if (first)
1193 sensor = subdev;
1194 }
1195
1196 return sensor;
1197}
1198
1199static int iss_register_entities(struct iss_device *iss)
1200{
1201 struct iss_platform_data *pdata = iss->pdata;
1202 struct iss_v4l2_subdevs_group *subdevs;
1203 int ret;
1204
1205 iss->media_dev.dev = iss->dev;
1206 strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
1207 sizeof(iss->media_dev.model));
1208 iss->media_dev.hw_revision = iss->revision;
1209 iss->media_dev.link_notify = iss_pipeline_link_notify;
1210 ret = media_device_register(&iss->media_dev);
1211 if (ret < 0) {
1212 dev_err(iss->dev, "%s: Media device registration failed (%d)\n",
1213 __func__, ret);
1214 return ret;
1215 }
1216
1217 iss->v4l2_dev.mdev = &iss->media_dev;
1218 ret = v4l2_device_register(iss->dev, &iss->v4l2_dev);
1219 if (ret < 0) {
1220 dev_err(iss->dev, "%s: V4L2 device registration failed (%d)\n",
1221 __func__, ret);
1222 goto done;
1223 }
1224
1225 /* Register internal entities */
1226 ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev);
1227 if (ret < 0)
1228 goto done;
1229
1230 ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev);
1231 if (ret < 0)
1232 goto done;
1233
1234 ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev);
1235 if (ret < 0)
1236 goto done;
1237
1238 ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev);
1239 if (ret < 0)
1240 goto done;
1241
1242 ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev);
1243 if (ret < 0)
1244 goto done;
1245
1246 /* Register external entities */
1247 for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
1248 struct v4l2_subdev *sensor;
1249 struct media_entity *input;
1250 unsigned int flags;
1251 unsigned int pad;
1252
1253 sensor = iss_register_subdev_group(iss, subdevs->subdevs);
1254 if (sensor == NULL)
1255 continue;
1256
1257 sensor->host_priv = subdevs;
1258
1259 /* Connect the sensor to the correct interface module.
1260 * CSI2a receiver through CSIPHY1, or
1261 * CSI2b receiver through CSIPHY2
1262 */
1263 switch (subdevs->interface) {
1264 case ISS_INTERFACE_CSI2A_PHY1:
1265 input = &iss->csi2a.subdev.entity;
1266 pad = CSI2_PAD_SINK;
1267 flags = MEDIA_LNK_FL_IMMUTABLE
1268 | MEDIA_LNK_FL_ENABLED;
1269 break;
1270
1271 case ISS_INTERFACE_CSI2B_PHY2:
1272 input = &iss->csi2b.subdev.entity;
1273 pad = CSI2_PAD_SINK;
1274 flags = MEDIA_LNK_FL_IMMUTABLE
1275 | MEDIA_LNK_FL_ENABLED;
1276 break;
1277
1278 default:
1279 dev_err(iss->dev, "%s: invalid interface type %u\n",
1280 __func__, subdevs->interface);
1281 ret = -EINVAL;
1282 goto done;
1283 }
1284
1285 ret = media_entity_create_link(&sensor->entity, 0, input, pad,
1286 flags);
1287 if (ret < 0)
1288 goto done;
1289 }
1290
1291 ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev);
1292
1293done:
1294 if (ret < 0)
1295 iss_unregister_entities(iss);
1296
1297 return ret;
1298}
1299
1300static void iss_cleanup_modules(struct iss_device *iss)
1301{
1302 omap4iss_csi2_cleanup(iss);
1303 omap4iss_ipipeif_cleanup(iss);
1304 omap4iss_ipipe_cleanup(iss);
1305 omap4iss_resizer_cleanup(iss);
1306}
1307
1308static int iss_initialize_modules(struct iss_device *iss)
1309{
1310 int ret;
1311
1312 ret = omap4iss_csiphy_init(iss);
1313 if (ret < 0) {
1314 dev_err(iss->dev, "CSI PHY initialization failed\n");
1315 goto error_csiphy;
1316 }
1317
1318 ret = omap4iss_csi2_init(iss);
1319 if (ret < 0) {
1320 dev_err(iss->dev, "CSI2 initialization failed\n");
1321 goto error_csi2;
1322 }
1323
1324 ret = omap4iss_ipipeif_init(iss);
1325 if (ret < 0) {
1326 dev_err(iss->dev, "ISP IPIPEIF initialization failed\n");
1327 goto error_ipipeif;
1328 }
1329
1330 ret = omap4iss_ipipe_init(iss);
1331 if (ret < 0) {
1332 dev_err(iss->dev, "ISP IPIPE initialization failed\n");
1333 goto error_ipipe;
1334 }
1335
1336 ret = omap4iss_resizer_init(iss);
1337 if (ret < 0) {
1338 dev_err(iss->dev, "ISP RESIZER initialization failed\n");
1339 goto error_resizer;
1340 }
1341
1342 /* Connect the submodules. */
1343 ret = media_entity_create_link(
1344 &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
1345 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1346 if (ret < 0)
1347 goto error_link;
1348
1349 ret = media_entity_create_link(
1350 &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
1351 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1352 if (ret < 0)
1353 goto error_link;
1354
1355 ret = media_entity_create_link(
1356 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1357 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1358 if (ret < 0)
1359 goto error_link;
1360
1361 ret = media_entity_create_link(
1362 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1363 &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
1364 if (ret < 0)
1365 goto error_link;
1366
1367 ret = media_entity_create_link(
1368 &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
1369 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1370 if (ret < 0)
1371 goto error_link;
1372
1373 return 0;
1374
1375error_link:
1376 omap4iss_resizer_cleanup(iss);
1377error_resizer:
1378 omap4iss_ipipe_cleanup(iss);
1379error_ipipe:
1380 omap4iss_ipipeif_cleanup(iss);
1381error_ipipeif:
1382 omap4iss_csi2_cleanup(iss);
1383error_csi2:
1384error_csiphy:
1385 return ret;
1386}
1387
1388static int iss_probe(struct platform_device *pdev)
1389{
1390 struct iss_platform_data *pdata = pdev->dev.platform_data;
1391 struct iss_device *iss;
1392 unsigned int i;
1393 int ret;
1394
1395 if (pdata == NULL)
1396 return -EINVAL;
1397
1398 iss = kzalloc(sizeof(*iss), GFP_KERNEL);
1399 if (!iss) {
1400 dev_err(&pdev->dev, "Could not allocate memory\n");
1401 return -ENOMEM;
1402 }
1403
1404 mutex_init(&iss->iss_mutex);
1405
1406 iss->dev = &pdev->dev;
1407 iss->pdata = pdata;
1408
1409 iss->raw_dmamask = DMA_BIT_MASK(32);
1410 iss->dev->dma_mask = &iss->raw_dmamask;
1411 iss->dev->coherent_dma_mask = DMA_BIT_MASK(32);
1412
1413 platform_set_drvdata(pdev, iss);
1414
1415 /* Clocks */
1416 ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP);
1417 if (ret < 0)
1418 goto error;
1419
1420 ret = iss_get_clocks(iss);
1421 if (ret < 0)
1422 goto error;
1423
1424 if (omap4iss_get(iss) == NULL)
1425 goto error;
1426
1427 ret = iss_reset(iss);
1428 if (ret < 0)
1429 goto error_iss;
1430
1431 iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
1432 dev_info(iss->dev, "Revision %08x found\n", iss->revision);
1433
1434 for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) {
1435 ret = iss_map_mem_resource(pdev, iss, i);
1436 if (ret)
1437 goto error_iss;
1438 }
1439
1440 /* Configure BTE BW_LIMITER field to max recommended value (1 GB) */
1441 iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL,
1442 BTE_CTRL_BW_LIMITER_MASK,
1443 18 << BTE_CTRL_BW_LIMITER_SHIFT);
1444
1445 /* Perform ISP reset */
1446 ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP);
1447 if (ret < 0)
1448 goto error_iss;
1449
1450 ret = iss_isp_reset(iss);
1451 if (ret < 0)
1452 goto error_iss;
1453
1454 dev_info(iss->dev, "ISP Revision %08x found\n",
1455 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION));
1456
1457 /* Interrupt */
1458 iss->irq_num = platform_get_irq(pdev, 0);
1459 if (iss->irq_num <= 0) {
1460 dev_err(iss->dev, "No IRQ resource\n");
1461 ret = -ENODEV;
1462 goto error_iss;
1463 }
1464
1465 if (request_irq(iss->irq_num, iss_isr, IRQF_SHARED, "OMAP4 ISS", iss)) {
1466 dev_err(iss->dev, "Unable to request IRQ\n");
1467 ret = -EINVAL;
1468 goto error_iss;
1469 }
1470
1471 /* Entities */
1472 ret = iss_initialize_modules(iss);
1473 if (ret < 0)
1474 goto error_irq;
1475
1476 ret = iss_register_entities(iss);
1477 if (ret < 0)
1478 goto error_modules;
1479
1480 omap4iss_put(iss);
1481
1482 return 0;
1483
1484error_modules:
1485 iss_cleanup_modules(iss);
1486error_irq:
1487 free_irq(iss->irq_num, iss);
1488error_iss:
1489 omap4iss_put(iss);
1490error:
1491 iss_put_clocks(iss);
1492
1493 for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) {
1494 if (iss->regs[i]) {
1495 iounmap(iss->regs[i]);
1496 iss->regs[i] = NULL;
1497 }
1498
1499 if (iss->res[i]) {
1500 release_mem_region(iss->res[i]->start,
1501 resource_size(iss->res[i]));
1502 iss->res[i] = NULL;
1503 }
1504 }
1505 platform_set_drvdata(pdev, NULL);
1506
1507 mutex_destroy(&iss->iss_mutex);
1508 kfree(iss);
1509
1510 return ret;
1511}
1512
1513static int iss_remove(struct platform_device *pdev)
1514{
1515 struct iss_device *iss = platform_get_drvdata(pdev);
1516 unsigned int i;
1517
1518 iss_unregister_entities(iss);
1519 iss_cleanup_modules(iss);
1520
1521 free_irq(iss->irq_num, iss);
1522 iss_put_clocks(iss);
1523
1524 for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) {
1525 if (iss->regs[i]) {
1526 iounmap(iss->regs[i]);
1527 iss->regs[i] = NULL;
1528 }
1529
1530 if (iss->res[i]) {
1531 release_mem_region(iss->res[i]->start,
1532 resource_size(iss->res[i]));
1533 iss->res[i] = NULL;
1534 }
1535 }
1536
1537 kfree(iss);
1538
1539 return 0;
1540}
1541
1542static struct platform_device_id omap4iss_id_table[] = {
1543 { "omap4iss", 0 },
1544 { },
1545};
1546MODULE_DEVICE_TABLE(platform, omap4iss_id_table);
1547
1548static struct platform_driver iss_driver = {
1549 .probe = iss_probe,
1550 .remove = iss_remove,
1551 .id_table = omap4iss_id_table,
1552 .driver = {
1553 .owner = THIS_MODULE,
1554 .name = "omap4iss",
1555 },
1556};
1557
1558module_platform_driver(iss_driver);
1559
1560MODULE_DESCRIPTION("TI OMAP4 ISS driver");
1561MODULE_AUTHOR("Sergio Aguirre <sergio.a.aguirre@gmail.com>");
1562MODULE_LICENSE("GPL");
1563MODULE_VERSION(ISS_VIDEO_DRIVER_VERSION);
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
new file mode 100644
index 000000000000..346db9233171
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -0,0 +1,236 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver
3 *
4 * Copyright (C) 2012 Texas Instruments.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef _OMAP4_ISS_H_
15#define _OMAP4_ISS_H_
16
17#include <media/v4l2-device.h>
18#include <linux/device.h>
19#include <linux/io.h>
20#include <linux/platform_device.h>
21#include <linux/wait.h>
22
23#include <media/omap4iss.h>
24
25#include "iss_regs.h"
26#include "iss_csiphy.h"
27#include "iss_csi2.h"
28#include "iss_ipipeif.h"
29#include "iss_ipipe.h"
30#include "iss_resizer.h"
31
32#define to_iss_device(ptr_module) \
33 container_of(ptr_module, struct iss_device, ptr_module)
34#define to_device(ptr_module) \
35 (to_iss_device(ptr_module)->dev)
36
37enum iss_mem_resources {
38 OMAP4_ISS_MEM_TOP,
39 OMAP4_ISS_MEM_CSI2_A_REGS1,
40 OMAP4_ISS_MEM_CAMERARX_CORE1,
41 OMAP4_ISS_MEM_CSI2_B_REGS1,
42 OMAP4_ISS_MEM_CAMERARX_CORE2,
43 OMAP4_ISS_MEM_BTE,
44 OMAP4_ISS_MEM_ISP_SYS1,
45 OMAP4_ISS_MEM_ISP_RESIZER,
46 OMAP4_ISS_MEM_ISP_IPIPE,
47 OMAP4_ISS_MEM_ISP_ISIF,
48 OMAP4_ISS_MEM_ISP_IPIPEIF,
49 OMAP4_ISS_MEM_LAST,
50};
51
52enum iss_subclk_resource {
53 OMAP4_ISS_SUBCLK_SIMCOP = (1 << 0),
54 OMAP4_ISS_SUBCLK_ISP = (1 << 1),
55 OMAP4_ISS_SUBCLK_CSI2_A = (1 << 2),
56 OMAP4_ISS_SUBCLK_CSI2_B = (1 << 3),
57 OMAP4_ISS_SUBCLK_CCP2 = (1 << 4),
58};
59
60enum iss_isp_subclk_resource {
61 OMAP4_ISS_ISP_SUBCLK_BL = (1 << 0),
62 OMAP4_ISS_ISP_SUBCLK_ISIF = (1 << 1),
63 OMAP4_ISS_ISP_SUBCLK_H3A = (1 << 2),
64 OMAP4_ISS_ISP_SUBCLK_RSZ = (1 << 3),
65 OMAP4_ISS_ISP_SUBCLK_IPIPE = (1 << 4),
66 OMAP4_ISS_ISP_SUBCLK_IPIPEIF = (1 << 5),
67};
68
69/*
70 * struct iss_reg - Structure for ISS register values.
71 * @reg: 32-bit Register address.
72 * @val: 32-bit Register value.
73 */
74struct iss_reg {
75 enum iss_mem_resources mmio_range;
76 u32 reg;
77 u32 val;
78};
79
80/*
81 * struct iss_device - ISS device structure.
82 * @crashed: Bitmask of crashed entities (indexed by entity ID)
83 */
84struct iss_device {
85 struct v4l2_device v4l2_dev;
86 struct media_device media_dev;
87 struct device *dev;
88 u32 revision;
89
90 /* platform HW resources */
91 struct iss_platform_data *pdata;
92 unsigned int irq_num;
93
94 struct resource *res[OMAP4_ISS_MEM_LAST];
95 void __iomem *regs[OMAP4_ISS_MEM_LAST];
96
97 u64 raw_dmamask;
98
99 struct mutex iss_mutex; /* For handling ref_count field */
100 bool crashed;
101 int has_context;
102 int ref_count;
103
104 struct clk *iss_fck;
105 struct clk *iss_ctrlclk;
106
107 /* ISS modules */
108 struct iss_csi2_device csi2a;
109 struct iss_csi2_device csi2b;
110 struct iss_csiphy csiphy1;
111 struct iss_csiphy csiphy2;
112 struct iss_ipipeif_device ipipeif;
113 struct iss_ipipe_device ipipe;
114 struct iss_resizer_device resizer;
115
116 unsigned int subclk_resources;
117 unsigned int isp_subclk_resources;
118};
119
120#define v4l2_dev_to_iss_device(dev) \
121 container_of(dev, struct iss_device, v4l2_dev)
122
123int omap4iss_get_external_info(struct iss_pipeline *pipe,
124 struct media_link *link);
125
126int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
127 atomic_t *stopping);
128
129int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
130 atomic_t *stopping);
131
132int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
133 enum iss_pipeline_stream_state state);
134void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);
135
136void omap4iss_configure_bridge(struct iss_device *iss,
137 enum ipipeif_input_entity input);
138
139struct iss_device *omap4iss_get(struct iss_device *iss);
140void omap4iss_put(struct iss_device *iss);
141int omap4iss_subclk_enable(struct iss_device *iss,
142 enum iss_subclk_resource res);
143int omap4iss_subclk_disable(struct iss_device *iss,
144 enum iss_subclk_resource res);
145void omap4iss_isp_subclk_enable(struct iss_device *iss,
146 enum iss_isp_subclk_resource res);
147void omap4iss_isp_subclk_disable(struct iss_device *iss,
148 enum iss_isp_subclk_resource res);
149
150int omap4iss_pipeline_pm_use(struct media_entity *entity, int use);
151
152int omap4iss_register_entities(struct platform_device *pdev,
153 struct v4l2_device *v4l2_dev);
154void omap4iss_unregister_entities(struct platform_device *pdev);
155
156/*
157 * iss_reg_read - Read the value of an OMAP4 ISS register
158 * @iss: the ISS device
159 * @res: memory resource in which the register is located
160 * @offset: register offset in the memory resource
161 *
162 * Return the register value.
163 */
164static inline
165u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res,
166 u32 offset)
167{
168 return readl(iss->regs[res] + offset);
169}
170
171/*
172 * iss_reg_write - Write a value to an OMAP4 ISS register
173 * @iss: the ISS device
174 * @res: memory resource in which the register is located
175 * @offset: register offset in the memory resource
176 * @value: value to be written
177 */
178static inline
179void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res,
180 u32 offset, u32 value)
181{
182 writel(value, iss->regs[res] + offset);
183}
184
185/*
186 * iss_reg_clr - Clear bits in an OMAP4 ISS register
187 * @iss: the ISS device
188 * @res: memory resource in which the register is located
189 * @offset: register offset in the memory resource
190 * @clr: bit mask to be cleared
191 */
192static inline
193void iss_reg_clr(struct iss_device *iss, enum iss_mem_resources res,
194 u32 offset, u32 clr)
195{
196 u32 v = iss_reg_read(iss, res, offset);
197
198 iss_reg_write(iss, res, offset, v & ~clr);
199}
200
201/*
202 * iss_reg_set - Set bits in an OMAP4 ISS register
203 * @iss: the ISS device
204 * @res: memory resource in which the register is located
205 * @offset: register offset in the memory resource
206 * @set: bit mask to be set
207 */
208static inline
209void iss_reg_set(struct iss_device *iss, enum iss_mem_resources res,
210 u32 offset, u32 set)
211{
212 u32 v = iss_reg_read(iss, res, offset);
213
214 iss_reg_write(iss, res, offset, v | set);
215}
216
217/*
218 * iss_reg_update - Clear and set bits in an OMAP4 ISS register
219 * @iss: the ISS device
220 * @res: memory resource in which the register is located
221 * @offset: register offset in the memory resource
222 * @clr: bit mask to be cleared
223 * @set: bit mask to be set
224 *
225 * Clear the clr mask first and then set the set mask.
226 */
227static inline
228void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res,
229 u32 offset, u32 clr, u32 set)
230{
231 u32 v = iss_reg_read(iss, res, offset);
232
233 iss_reg_write(iss, res, offset, (v & ~clr) | set);
234}
235
236#endif /* _OMAP4_ISS_H_ */
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
new file mode 100644
index 000000000000..61fc350eb251
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -0,0 +1,1343 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - CSI PHY module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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/delay.h>
15#include <media/v4l2-common.h>
16#include <linux/v4l2-mediabus.h>
17#include <linux/mm.h>
18
19#include "iss.h"
20#include "iss_regs.h"
21#include "iss_csi2.h"
22
23/*
24 * csi2_if_enable - Enable CSI2 Receiver interface.
25 * @enable: enable flag
26 *
27 */
28static void csi2_if_enable(struct iss_csi2_device *csi2, u8 enable)
29{
30 struct iss_csi2_ctrl_cfg *currctrl = &csi2->ctrl;
31
32 iss_reg_update(csi2->iss, csi2->regs1, CSI2_CTRL, CSI2_CTRL_IF_EN,
33 enable ? CSI2_CTRL_IF_EN : 0);
34
35 currctrl->if_enable = enable;
36}
37
38/*
39 * csi2_recv_config - CSI2 receiver module configuration.
40 * @currctrl: iss_csi2_ctrl_cfg structure
41 *
42 */
43static void csi2_recv_config(struct iss_csi2_device *csi2,
44 struct iss_csi2_ctrl_cfg *currctrl)
45{
46 u32 reg = 0;
47
48 if (currctrl->frame_mode)
49 reg |= CSI2_CTRL_FRAME;
50 else
51 reg &= ~CSI2_CTRL_FRAME;
52
53 if (currctrl->vp_clk_enable)
54 reg |= CSI2_CTRL_VP_CLK_EN;
55 else
56 reg &= ~CSI2_CTRL_VP_CLK_EN;
57
58 if (currctrl->vp_only_enable)
59 reg |= CSI2_CTRL_VP_ONLY_EN;
60 else
61 reg &= ~CSI2_CTRL_VP_ONLY_EN;
62
63 reg &= ~CSI2_CTRL_VP_OUT_CTRL_MASK;
64 reg |= currctrl->vp_out_ctrl << CSI2_CTRL_VP_OUT_CTRL_SHIFT;
65
66 if (currctrl->ecc_enable)
67 reg |= CSI2_CTRL_ECC_EN;
68 else
69 reg &= ~CSI2_CTRL_ECC_EN;
70
71 /*
72 * Set MFlag assertion boundaries to:
73 * Low: 4/8 of FIFO size
74 * High: 6/8 of FIFO size
75 */
76 reg &= ~(CSI2_CTRL_MFLAG_LEVH_MASK | CSI2_CTRL_MFLAG_LEVL_MASK);
77 reg |= (2 << CSI2_CTRL_MFLAG_LEVH_SHIFT) |
78 (4 << CSI2_CTRL_MFLAG_LEVL_SHIFT);
79
80 /* Generation of 16x64-bit bursts (Recommended) */
81 reg |= CSI2_CTRL_BURST_SIZE_EXPAND;
82
83 /* Do Non-Posted writes (Recommended) */
84 reg |= CSI2_CTRL_NON_POSTED_WRITE;
85
86 /*
87 * Enforce Little endian for all formats, including:
88 * YUV4:2:2 8-bit and YUV4:2:0 Legacy
89 */
90 reg |= CSI2_CTRL_ENDIANNESS;
91
92 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTRL, reg);
93}
94
95static const unsigned int csi2_input_fmts[] = {
96 V4L2_MBUS_FMT_SGRBG10_1X10,
97 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
98 V4L2_MBUS_FMT_SRGGB10_1X10,
99 V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
100 V4L2_MBUS_FMT_SBGGR10_1X10,
101 V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
102 V4L2_MBUS_FMT_SGBRG10_1X10,
103 V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
104 V4L2_MBUS_FMT_SBGGR8_1X8,
105 V4L2_MBUS_FMT_SGBRG8_1X8,
106 V4L2_MBUS_FMT_SGRBG8_1X8,
107 V4L2_MBUS_FMT_SRGGB8_1X8,
108 V4L2_MBUS_FMT_UYVY8_1X16,
109 V4L2_MBUS_FMT_YUYV8_1X16,
110};
111
112/* To set the format on the CSI2 requires a mapping function that takes
113 * the following inputs:
114 * - 3 different formats (at this time)
115 * - 2 destinations (mem, vp+mem) (vp only handled separately)
116 * - 2 decompression options (on, off)
117 * Output should be CSI2 frame format code
118 * Array indices as follows: [format][dest][decompr]
119 * Not all combinations are valid. 0 means invalid.
120 */
121static const u16 __csi2_fmt_map[][2][2] = {
122 /* RAW10 formats */
123 {
124 /* Output to memory */
125 {
126 /* No DPCM decompression */
127 CSI2_PIX_FMT_RAW10_EXP16,
128 /* DPCM decompression */
129 0,
130 },
131 /* Output to both */
132 {
133 /* No DPCM decompression */
134 CSI2_PIX_FMT_RAW10_EXP16_VP,
135 /* DPCM decompression */
136 0,
137 },
138 },
139 /* RAW10 DPCM8 formats */
140 {
141 /* Output to memory */
142 {
143 /* No DPCM decompression */
144 CSI2_USERDEF_8BIT_DATA1,
145 /* DPCM decompression */
146 CSI2_USERDEF_8BIT_DATA1_DPCM10,
147 },
148 /* Output to both */
149 {
150 /* No DPCM decompression */
151 CSI2_PIX_FMT_RAW8_VP,
152 /* DPCM decompression */
153 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP,
154 },
155 },
156 /* RAW8 formats */
157 {
158 /* Output to memory */
159 {
160 /* No DPCM decompression */
161 CSI2_PIX_FMT_RAW8,
162 /* DPCM decompression */
163 0,
164 },
165 /* Output to both */
166 {
167 /* No DPCM decompression */
168 CSI2_PIX_FMT_RAW8_VP,
169 /* DPCM decompression */
170 0,
171 },
172 },
173 /* YUV422 formats */
174 {
175 /* Output to memory */
176 {
177 /* No DPCM decompression */
178 CSI2_PIX_FMT_YUV422_8BIT,
179 /* DPCM decompression */
180 0,
181 },
182 /* Output to both */
183 {
184 /* No DPCM decompression */
185 CSI2_PIX_FMT_YUV422_8BIT_VP16,
186 /* DPCM decompression */
187 0,
188 },
189 },
190};
191
192/*
193 * csi2_ctx_map_format - Map CSI2 sink media bus format to CSI2 format ID
194 * @csi2: ISS CSI2 device
195 *
196 * Returns CSI2 physical format id
197 */
198static u16 csi2_ctx_map_format(struct iss_csi2_device *csi2)
199{
200 const struct v4l2_mbus_framefmt *fmt = &csi2->formats[CSI2_PAD_SINK];
201 int fmtidx, destidx;
202
203 switch (fmt->code) {
204 case V4L2_MBUS_FMT_SGRBG10_1X10:
205 case V4L2_MBUS_FMT_SRGGB10_1X10:
206 case V4L2_MBUS_FMT_SBGGR10_1X10:
207 case V4L2_MBUS_FMT_SGBRG10_1X10:
208 fmtidx = 0;
209 break;
210 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
211 case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8:
212 case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8:
213 case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
214 fmtidx = 1;
215 break;
216 case V4L2_MBUS_FMT_SBGGR8_1X8:
217 case V4L2_MBUS_FMT_SGBRG8_1X8:
218 case V4L2_MBUS_FMT_SGRBG8_1X8:
219 case V4L2_MBUS_FMT_SRGGB8_1X8:
220 fmtidx = 2;
221 break;
222 case V4L2_MBUS_FMT_UYVY8_1X16:
223 case V4L2_MBUS_FMT_YUYV8_1X16:
224 fmtidx = 3;
225 break;
226 default:
227 WARN(1, KERN_ERR "CSI2: pixel format %08x unsupported!\n",
228 fmt->code);
229 return 0;
230 }
231
232 if (!(csi2->output & CSI2_OUTPUT_IPIPEIF) &&
233 !(csi2->output & CSI2_OUTPUT_MEMORY)) {
234 /* Neither output enabled is a valid combination */
235 return CSI2_PIX_FMT_OTHERS;
236 }
237
238 /* If we need to skip frames at the beginning of the stream disable the
239 * video port to avoid sending the skipped frames to the IPIPEIF.
240 */
241 destidx = csi2->frame_skip ? 0 : !!(csi2->output & CSI2_OUTPUT_IPIPEIF);
242
243 return __csi2_fmt_map[fmtidx][destidx][csi2->dpcm_decompress];
244}
245
246/*
247 * csi2_set_outaddr - Set memory address to save output image
248 * @csi2: Pointer to ISS CSI2a device.
249 * @addr: 32-bit memory address aligned on 32 byte boundary.
250 *
251 * Sets the memory address where the output will be saved.
252 *
253 * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte
254 * boundary.
255 */
256static void csi2_set_outaddr(struct iss_csi2_device *csi2, u32 addr)
257{
258 struct iss_csi2_ctx_cfg *ctx = &csi2->contexts[0];
259
260 ctx->ping_addr = addr;
261 ctx->pong_addr = addr;
262 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_PING_ADDR(ctx->ctxnum),
263 ctx->ping_addr);
264 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_PONG_ADDR(ctx->ctxnum),
265 ctx->pong_addr);
266}
267
268/*
269 * is_usr_def_mapping - Checks whether USER_DEF_MAPPING should
270 * be enabled by CSI2.
271 * @format_id: mapped format id
272 *
273 */
274static inline int is_usr_def_mapping(u32 format_id)
275{
276 return (format_id & 0xf0) == 0x40 ? 1 : 0;
277}
278
279/*
280 * csi2_ctx_enable - Enable specified CSI2 context
281 * @ctxnum: Context number, valid between 0 and 7 values.
282 * @enable: enable
283 *
284 */
285static void csi2_ctx_enable(struct iss_csi2_device *csi2, u8 ctxnum, u8 enable)
286{
287 struct iss_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum];
288 u32 reg;
289
290 reg = iss_reg_read(csi2->iss, csi2->regs1, CSI2_CTX_CTRL1(ctxnum));
291
292 if (enable) {
293 unsigned int skip = 0;
294
295 if (csi2->frame_skip)
296 skip = csi2->frame_skip;
297 else if (csi2->output & CSI2_OUTPUT_MEMORY)
298 skip = 1;
299
300 reg &= ~CSI2_CTX_CTRL1_COUNT_MASK;
301 reg |= CSI2_CTX_CTRL1_COUNT_UNLOCK
302 | (skip << CSI2_CTX_CTRL1_COUNT_SHIFT)
303 | CSI2_CTX_CTRL1_CTX_EN;
304 } else {
305 reg &= ~CSI2_CTX_CTRL1_CTX_EN;
306 }
307
308 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_CTRL1(ctxnum), reg);
309 ctx->enabled = enable;
310}
311
312/*
313 * csi2_ctx_config - CSI2 context configuration.
314 * @ctx: context configuration
315 *
316 */
317static void csi2_ctx_config(struct iss_csi2_device *csi2,
318 struct iss_csi2_ctx_cfg *ctx)
319{
320 u32 reg;
321
322 /* Set up CSI2_CTx_CTRL1 */
323 if (ctx->eof_enabled)
324 reg = CSI2_CTX_CTRL1_EOF_EN;
325
326 if (ctx->eol_enabled)
327 reg |= CSI2_CTX_CTRL1_EOL_EN;
328
329 if (ctx->checksum_enabled)
330 reg |= CSI2_CTX_CTRL1_CS_EN;
331
332 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_CTRL1(ctx->ctxnum), reg);
333
334 /* Set up CSI2_CTx_CTRL2 */
335 reg = ctx->virtual_id << CSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
336 reg |= ctx->format_id << CSI2_CTX_CTRL2_FORMAT_SHIFT;
337
338 if (ctx->dpcm_decompress && ctx->dpcm_predictor)
339 reg |= CSI2_CTX_CTRL2_DPCM_PRED;
340
341 if (is_usr_def_mapping(ctx->format_id))
342 reg |= 2 << CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT;
343
344 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_CTRL2(ctx->ctxnum), reg);
345
346 /* Set up CSI2_CTx_CTRL3 */
347 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_CTRL3(ctx->ctxnum),
348 ctx->alpha << CSI2_CTX_CTRL3_ALPHA_SHIFT);
349
350 /* Set up CSI2_CTx_DAT_OFST */
351 iss_reg_update(csi2->iss, csi2->regs1, CSI2_CTX_DAT_OFST(ctx->ctxnum),
352 CSI2_CTX_DAT_OFST_MASK, ctx->data_offset);
353
354 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_PING_ADDR(ctx->ctxnum),
355 ctx->ping_addr);
356 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_PONG_ADDR(ctx->ctxnum),
357 ctx->pong_addr);
358}
359
360/*
361 * csi2_timing_config - CSI2 timing configuration.
362 * @timing: csi2_timing_cfg structure
363 */
364static void csi2_timing_config(struct iss_csi2_device *csi2,
365 struct iss_csi2_timing_cfg *timing)
366{
367 u32 reg;
368
369 reg = iss_reg_read(csi2->iss, csi2->regs1, CSI2_TIMING);
370
371 if (timing->force_rx_mode)
372 reg |= CSI2_TIMING_FORCE_RX_MODE_IO1;
373 else
374 reg &= ~CSI2_TIMING_FORCE_RX_MODE_IO1;
375
376 if (timing->stop_state_16x)
377 reg |= CSI2_TIMING_STOP_STATE_X16_IO1;
378 else
379 reg &= ~CSI2_TIMING_STOP_STATE_X16_IO1;
380
381 if (timing->stop_state_4x)
382 reg |= CSI2_TIMING_STOP_STATE_X4_IO1;
383 else
384 reg &= ~CSI2_TIMING_STOP_STATE_X4_IO1;
385
386 reg &= ~CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK;
387 reg |= timing->stop_state_counter <<
388 CSI2_TIMING_STOP_STATE_COUNTER_IO1_SHIFT;
389
390 iss_reg_write(csi2->iss, csi2->regs1, CSI2_TIMING, reg);
391}
392
393/*
394 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
395 * @enable: Enable/disable CSI2 Context interrupts
396 */
397static void csi2_irq_ctx_set(struct iss_csi2_device *csi2, int enable)
398{
399 u32 reg = CSI2_CTX_IRQ_FE;
400 int i;
401
402 if (csi2->use_fs_irq)
403 reg |= CSI2_CTX_IRQ_FS;
404
405 for (i = 0; i < 8; i++) {
406 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(i),
407 reg);
408 if (enable)
409 iss_reg_set(csi2->iss, csi2->regs1,
410 CSI2_CTX_IRQENABLE(i), reg);
411 else
412 iss_reg_clr(csi2->iss, csi2->regs1,
413 CSI2_CTX_IRQENABLE(i), reg);
414 }
415}
416
417/*
418 * csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
419 * @enable: Enable/disable CSI2 ComplexIO #1 interrupts
420 */
421static void csi2_irq_complexio1_set(struct iss_csi2_device *csi2, int enable)
422{
423 u32 reg;
424 reg = CSI2_COMPLEXIO_IRQ_STATEALLULPMEXIT |
425 CSI2_COMPLEXIO_IRQ_STATEALLULPMENTER |
426 CSI2_COMPLEXIO_IRQ_STATEULPM5 |
427 CSI2_COMPLEXIO_IRQ_ERRCONTROL5 |
428 CSI2_COMPLEXIO_IRQ_ERRESC5 |
429 CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS5 |
430 CSI2_COMPLEXIO_IRQ_ERRSOTHS5 |
431 CSI2_COMPLEXIO_IRQ_STATEULPM4 |
432 CSI2_COMPLEXIO_IRQ_ERRCONTROL4 |
433 CSI2_COMPLEXIO_IRQ_ERRESC4 |
434 CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS4 |
435 CSI2_COMPLEXIO_IRQ_ERRSOTHS4 |
436 CSI2_COMPLEXIO_IRQ_STATEULPM3 |
437 CSI2_COMPLEXIO_IRQ_ERRCONTROL3 |
438 CSI2_COMPLEXIO_IRQ_ERRESC3 |
439 CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS3 |
440 CSI2_COMPLEXIO_IRQ_ERRSOTHS3 |
441 CSI2_COMPLEXIO_IRQ_STATEULPM2 |
442 CSI2_COMPLEXIO_IRQ_ERRCONTROL2 |
443 CSI2_COMPLEXIO_IRQ_ERRESC2 |
444 CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS2 |
445 CSI2_COMPLEXIO_IRQ_ERRSOTHS2 |
446 CSI2_COMPLEXIO_IRQ_STATEULPM1 |
447 CSI2_COMPLEXIO_IRQ_ERRCONTROL1 |
448 CSI2_COMPLEXIO_IRQ_ERRESC1 |
449 CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS1 |
450 CSI2_COMPLEXIO_IRQ_ERRSOTHS1;
451 iss_reg_write(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_IRQSTATUS, reg);
452 if (enable)
453 iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_IRQENABLE,
454 reg);
455 else
456 iss_reg_write(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_IRQENABLE,
457 0);
458}
459
460/*
461 * csi2_irq_status_set - Enables CSI2 Status IRQs.
462 * @enable: Enable/disable CSI2 Status interrupts
463 */
464static void csi2_irq_status_set(struct iss_csi2_device *csi2, int enable)
465{
466 u32 reg;
467 reg = CSI2_IRQ_OCP_ERR |
468 CSI2_IRQ_SHORT_PACKET |
469 CSI2_IRQ_ECC_CORRECTION |
470 CSI2_IRQ_ECC_NO_CORRECTION |
471 CSI2_IRQ_COMPLEXIO_ERR |
472 CSI2_IRQ_FIFO_OVF |
473 CSI2_IRQ_CONTEXT0;
474 iss_reg_write(csi2->iss, csi2->regs1, CSI2_IRQSTATUS, reg);
475 if (enable)
476 iss_reg_set(csi2->iss, csi2->regs1, CSI2_IRQENABLE, reg);
477 else
478 iss_reg_write(csi2->iss, csi2->regs1, CSI2_IRQENABLE, 0);
479}
480
481/*
482 * omap4iss_csi2_reset - Resets the CSI2 module.
483 *
484 * Must be called with the phy lock held.
485 *
486 * Returns 0 if successful, or -EBUSY if power command didn't respond.
487 */
488int omap4iss_csi2_reset(struct iss_csi2_device *csi2)
489{
490 u8 soft_reset_retries = 0;
491 u32 reg;
492 int i;
493
494 if (!csi2->available)
495 return -ENODEV;
496
497 if (csi2->phy->phy_in_use)
498 return -EBUSY;
499
500 iss_reg_set(csi2->iss, csi2->regs1, CSI2_SYSCONFIG,
501 CSI2_SYSCONFIG_SOFT_RESET);
502
503 do {
504 reg = iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS)
505 & CSI2_SYSSTATUS_RESET_DONE;
506 if (reg == CSI2_SYSSTATUS_RESET_DONE)
507 break;
508 soft_reset_retries++;
509 if (soft_reset_retries < 5)
510 usleep_range(100, 100);
511 } while (soft_reset_retries < 5);
512
513 if (soft_reset_retries == 5) {
514 dev_err(csi2->iss->dev,
515 "CSI2: Soft reset try count exceeded!\n");
516 return -EBUSY;
517 }
518
519 iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_CFG,
520 CSI2_COMPLEXIO_CFG_RESET_CTRL);
521
522 i = 100;
523 do {
524 reg = iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1)
525 & REGISTER1_RESET_DONE_CTRLCLK;
526 if (reg == REGISTER1_RESET_DONE_CTRLCLK)
527 break;
528 usleep_range(100, 100);
529 } while (--i > 0);
530
531 if (i == 0) {
532 dev_err(csi2->iss->dev,
533 "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
534 return -EBUSY;
535 }
536
537 iss_reg_update(csi2->iss, csi2->regs1, CSI2_SYSCONFIG,
538 CSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
539 CSI2_SYSCONFIG_AUTO_IDLE,
540 CSI2_SYSCONFIG_MSTANDBY_MODE_NO);
541
542 return 0;
543}
544
545static int csi2_configure(struct iss_csi2_device *csi2)
546{
547 const struct iss_v4l2_subdevs_group *pdata;
548 struct iss_csi2_timing_cfg *timing = &csi2->timing[0];
549 struct v4l2_subdev *sensor;
550 struct media_pad *pad;
551
552 /*
553 * CSI2 fields that can be updated while the context has
554 * been enabled or the interface has been enabled are not
555 * updated dynamically currently. So we do not allow to
556 * reconfigure if either has been enabled
557 */
558 if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
559 return -EBUSY;
560
561 pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
562 sensor = media_entity_to_v4l2_subdev(pad->entity);
563 pdata = sensor->host_priv;
564
565 csi2->frame_skip = 0;
566 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
567
568 csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
569 csi2->ctrl.frame_mode = ISS_CSI2_FRAME_IMMEDIATE;
570 csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
571
572 timing->force_rx_mode = 1;
573 timing->stop_state_16x = 1;
574 timing->stop_state_4x = 1;
575 timing->stop_state_counter = 0x1ff;
576
577 /*
578 * The CSI2 receiver can't do any format conversion except DPCM
579 * decompression, so every set_format call configures both pads
580 * and enables DPCM decompression as a special case:
581 */
582 if (csi2->formats[CSI2_PAD_SINK].code !=
583 csi2->formats[CSI2_PAD_SOURCE].code)
584 csi2->dpcm_decompress = true;
585 else
586 csi2->dpcm_decompress = false;
587
588 csi2->contexts[0].format_id = csi2_ctx_map_format(csi2);
589
590 if (csi2->video_out.bpl_padding == 0)
591 csi2->contexts[0].data_offset = 0;
592 else
593 csi2->contexts[0].data_offset = csi2->video_out.bpl_value;
594
595 /*
596 * Enable end of frame and end of line signals generation for
597 * context 0. These signals are generated from CSI2 receiver to
598 * qualify the last pixel of a frame and the last pixel of a line.
599 * Without enabling the signals CSI2 receiver writes data to memory
600 * beyond buffer size and/or data line offset is not handled correctly.
601 */
602 csi2->contexts[0].eof_enabled = 1;
603 csi2->contexts[0].eol_enabled = 1;
604
605 csi2_irq_complexio1_set(csi2, 1);
606 csi2_irq_ctx_set(csi2, 1);
607 csi2_irq_status_set(csi2, 1);
608
609 /* Set configuration (timings, format and links) */
610 csi2_timing_config(csi2, timing);
611 csi2_recv_config(csi2, &csi2->ctrl);
612 csi2_ctx_config(csi2, &csi2->contexts[0]);
613
614 return 0;
615}
616
617/*
618 * csi2_print_status - Prints CSI2 debug information.
619 */
620#define CSI2_PRINT_REGISTER(iss, regs, name)\
621 dev_dbg(iss->dev, "###CSI2 " #name "=0x%08x\n", \
622 iss_reg_read(iss, regs, CSI2_##name))
623
624static void csi2_print_status(struct iss_csi2_device *csi2)
625{
626 struct iss_device *iss = csi2->iss;
627
628 if (!csi2->available)
629 return;
630
631 dev_dbg(iss->dev, "-------------CSI2 Register dump-------------\n");
632
633 CSI2_PRINT_REGISTER(iss, csi2->regs1, SYSCONFIG);
634 CSI2_PRINT_REGISTER(iss, csi2->regs1, SYSSTATUS);
635 CSI2_PRINT_REGISTER(iss, csi2->regs1, IRQENABLE);
636 CSI2_PRINT_REGISTER(iss, csi2->regs1, IRQSTATUS);
637 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTRL);
638 CSI2_PRINT_REGISTER(iss, csi2->regs1, DBG_H);
639 CSI2_PRINT_REGISTER(iss, csi2->regs1, COMPLEXIO_CFG);
640 CSI2_PRINT_REGISTER(iss, csi2->regs1, COMPLEXIO_IRQSTATUS);
641 CSI2_PRINT_REGISTER(iss, csi2->regs1, SHORT_PACKET);
642 CSI2_PRINT_REGISTER(iss, csi2->regs1, COMPLEXIO_IRQENABLE);
643 CSI2_PRINT_REGISTER(iss, csi2->regs1, DBG_P);
644 CSI2_PRINT_REGISTER(iss, csi2->regs1, TIMING);
645 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_CTRL1(0));
646 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_CTRL2(0));
647 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_DAT_OFST(0));
648 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_PING_ADDR(0));
649 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_PONG_ADDR(0));
650 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_IRQENABLE(0));
651 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_IRQSTATUS(0));
652 CSI2_PRINT_REGISTER(iss, csi2->regs1, CTX_CTRL3(0));
653
654 dev_dbg(iss->dev, "--------------------------------------------\n");
655}
656
657/* -----------------------------------------------------------------------------
658 * Interrupt handling
659 */
660
661/*
662 * csi2_isr_buffer - Does buffer handling at end-of-frame
663 * when writing to memory.
664 */
665static void csi2_isr_buffer(struct iss_csi2_device *csi2)
666{
667 struct iss_buffer *buffer;
668
669 csi2_ctx_enable(csi2, 0, 0);
670
671 buffer = omap4iss_video_buffer_next(&csi2->video_out);
672
673 /*
674 * Let video queue operation restart engine if there is an underrun
675 * condition.
676 */
677 if (buffer == NULL)
678 return;
679
680 csi2_set_outaddr(csi2, buffer->iss_addr);
681 csi2_ctx_enable(csi2, 0, 1);
682}
683
684static void csi2_isr_ctx(struct iss_csi2_device *csi2,
685 struct iss_csi2_ctx_cfg *ctx)
686{
687 unsigned int n = ctx->ctxnum;
688 u32 status;
689
690 status = iss_reg_read(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(n));
691 iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(n), status);
692
693 /* Propagate frame number */
694 if (status & CSI2_CTX_IRQ_FS) {
695 struct iss_pipeline *pipe =
696 to_iss_pipeline(&csi2->subdev.entity);
697 if (pipe->do_propagation)
698 atomic_inc(&pipe->frame_number);
699 }
700
701 if (!(status & CSI2_CTX_IRQ_FE))
702 return;
703
704 /* Skip interrupts until we reach the frame skip count. The CSI2 will be
705 * automatically disabled, as the frame skip count has been programmed
706 * in the CSI2_CTx_CTRL1::COUNT field, so reenable it.
707 *
708 * It would have been nice to rely on the FRAME_NUMBER interrupt instead
709 * but it turned out that the interrupt is only generated when the CSI2
710 * writes to memory (the CSI2_CTx_CTRL1::COUNT field is decreased
711 * correctly and reaches 0 when data is forwarded to the video port only
712 * but no interrupt arrives). Maybe a CSI2 hardware bug.
713 */
714 if (csi2->frame_skip) {
715 csi2->frame_skip--;
716 if (csi2->frame_skip == 0) {
717 ctx->format_id = csi2_ctx_map_format(csi2);
718 csi2_ctx_config(csi2, ctx);
719 csi2_ctx_enable(csi2, n, 1);
720 }
721 return;
722 }
723
724 if (csi2->output & CSI2_OUTPUT_MEMORY)
725 csi2_isr_buffer(csi2);
726}
727
728/*
729 * omap4iss_csi2_isr - CSI2 interrupt handling.
730 */
731void omap4iss_csi2_isr(struct iss_csi2_device *csi2)
732{
733 struct iss_pipeline *pipe = to_iss_pipeline(&csi2->subdev.entity);
734 u32 csi2_irqstatus, cpxio1_irqstatus;
735 struct iss_device *iss = csi2->iss;
736
737 if (!csi2->available)
738 return;
739
740 csi2_irqstatus = iss_reg_read(csi2->iss, csi2->regs1, CSI2_IRQSTATUS);
741 iss_reg_write(csi2->iss, csi2->regs1, CSI2_IRQSTATUS, csi2_irqstatus);
742
743 /* Failure Cases */
744 if (csi2_irqstatus & CSI2_IRQ_COMPLEXIO_ERR) {
745 cpxio1_irqstatus = iss_reg_read(csi2->iss, csi2->regs1,
746 CSI2_COMPLEXIO_IRQSTATUS);
747 iss_reg_write(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_IRQSTATUS,
748 cpxio1_irqstatus);
749 dev_dbg(iss->dev, "CSI2: ComplexIO Error IRQ %x\n",
750 cpxio1_irqstatus);
751 pipe->error = true;
752 }
753
754 if (csi2_irqstatus & (CSI2_IRQ_OCP_ERR |
755 CSI2_IRQ_SHORT_PACKET |
756 CSI2_IRQ_ECC_NO_CORRECTION |
757 CSI2_IRQ_COMPLEXIO_ERR |
758 CSI2_IRQ_FIFO_OVF)) {
759 dev_dbg(iss->dev,
760 "CSI2 Err: OCP:%d SHORT:%d ECC:%d CPXIO:%d OVF:%d\n",
761 csi2_irqstatus & CSI2_IRQ_OCP_ERR ? 1 : 0,
762 csi2_irqstatus & CSI2_IRQ_SHORT_PACKET ? 1 : 0,
763 csi2_irqstatus & CSI2_IRQ_ECC_NO_CORRECTION ? 1 : 0,
764 csi2_irqstatus & CSI2_IRQ_COMPLEXIO_ERR ? 1 : 0,
765 csi2_irqstatus & CSI2_IRQ_FIFO_OVF ? 1 : 0);
766 pipe->error = true;
767 }
768
769 if (omap4iss_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
770 return;
771
772 /* Successful cases */
773 if (csi2_irqstatus & CSI2_IRQ_CONTEXT0)
774 csi2_isr_ctx(csi2, &csi2->contexts[0]);
775
776 if (csi2_irqstatus & CSI2_IRQ_ECC_CORRECTION)
777 dev_dbg(iss->dev, "CSI2: ECC correction done\n");
778}
779
780/* -----------------------------------------------------------------------------
781 * ISS video operations
782 */
783
784/*
785 * csi2_queue - Queues the first buffer when using memory output
786 * @video: The video node
787 * @buffer: buffer to queue
788 */
789static int csi2_queue(struct iss_video *video, struct iss_buffer *buffer)
790{
791 struct iss_csi2_device *csi2 = container_of(video,
792 struct iss_csi2_device, video_out);
793
794 csi2_set_outaddr(csi2, buffer->iss_addr);
795
796 /*
797 * If streaming was enabled before there was a buffer queued
798 * or underrun happened in the ISR, the hardware was not enabled
799 * and DMA queue flag ISS_VIDEO_DMAQUEUE_UNDERRUN is still set.
800 * Enable it now.
801 */
802 if (csi2->video_out.dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
803 /* Enable / disable context 0 and IRQs */
804 csi2_if_enable(csi2, 1);
805 csi2_ctx_enable(csi2, 0, 1);
806 iss_video_dmaqueue_flags_clr(&csi2->video_out);
807 }
808
809 return 0;
810}
811
812static const struct iss_video_operations csi2_issvideo_ops = {
813 .queue = csi2_queue,
814};
815
816/* -----------------------------------------------------------------------------
817 * V4L2 subdev operations
818 */
819
820static struct v4l2_mbus_framefmt *
821__csi2_get_format(struct iss_csi2_device *csi2, struct v4l2_subdev_fh *fh,
822 unsigned int pad, enum v4l2_subdev_format_whence which)
823{
824 if (which == V4L2_SUBDEV_FORMAT_TRY)
825 return v4l2_subdev_get_try_format(fh, pad);
826 else
827 return &csi2->formats[pad];
828}
829
830static void
831csi2_try_format(struct iss_csi2_device *csi2, struct v4l2_subdev_fh *fh,
832 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
833 enum v4l2_subdev_format_whence which)
834{
835 enum v4l2_mbus_pixelcode pixelcode;
836 struct v4l2_mbus_framefmt *format;
837 const struct iss_format_info *info;
838 unsigned int i;
839
840 switch (pad) {
841 case CSI2_PAD_SINK:
842 /* Clamp the width and height to valid range (1-8191). */
843 for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) {
844 if (fmt->code == csi2_input_fmts[i])
845 break;
846 }
847
848 /* If not found, use SGRBG10 as default */
849 if (i >= ARRAY_SIZE(csi2_input_fmts))
850 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
851
852 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
853 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
854 break;
855
856 case CSI2_PAD_SOURCE:
857 /* Source format same as sink format, except for DPCM
858 * compression.
859 */
860 pixelcode = fmt->code;
861 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which);
862 memcpy(fmt, format, sizeof(*fmt));
863
864 /*
865 * Only Allow DPCM decompression, and check that the
866 * pattern is preserved
867 */
868 info = omap4iss_video_format_info(fmt->code);
869 if (info->uncompressed == pixelcode)
870 fmt->code = pixelcode;
871 break;
872 }
873
874 /* RGB, non-interlaced */
875 fmt->colorspace = V4L2_COLORSPACE_SRGB;
876 fmt->field = V4L2_FIELD_NONE;
877}
878
879/*
880 * csi2_enum_mbus_code - Handle pixel format enumeration
881 * @sd : pointer to v4l2 subdev structure
882 * @fh : V4L2 subdev file handle
883 * @code : pointer to v4l2_subdev_mbus_code_enum structure
884 * return -EINVAL or zero on success
885 */
886static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
887 struct v4l2_subdev_fh *fh,
888 struct v4l2_subdev_mbus_code_enum *code)
889{
890 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
891 struct v4l2_mbus_framefmt *format;
892 const struct iss_format_info *info;
893
894 if (code->pad == CSI2_PAD_SINK) {
895 if (code->index >= ARRAY_SIZE(csi2_input_fmts))
896 return -EINVAL;
897
898 code->code = csi2_input_fmts[code->index];
899 } else {
900 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK,
901 V4L2_SUBDEV_FORMAT_TRY);
902 switch (code->index) {
903 case 0:
904 /* Passthrough sink pad code */
905 code->code = format->code;
906 break;
907 case 1:
908 /* Uncompressed code */
909 info = omap4iss_video_format_info(format->code);
910 if (info->uncompressed == format->code)
911 return -EINVAL;
912
913 code->code = info->uncompressed;
914 break;
915 default:
916 return -EINVAL;
917 }
918 }
919
920 return 0;
921}
922
923static int csi2_enum_frame_size(struct v4l2_subdev *sd,
924 struct v4l2_subdev_fh *fh,
925 struct v4l2_subdev_frame_size_enum *fse)
926{
927 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
928 struct v4l2_mbus_framefmt format;
929
930 if (fse->index != 0)
931 return -EINVAL;
932
933 format.code = fse->code;
934 format.width = 1;
935 format.height = 1;
936 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
937 fse->min_width = format.width;
938 fse->min_height = format.height;
939
940 if (format.code != fse->code)
941 return -EINVAL;
942
943 format.code = fse->code;
944 format.width = -1;
945 format.height = -1;
946 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
947 fse->max_width = format.width;
948 fse->max_height = format.height;
949
950 return 0;
951}
952
953/*
954 * csi2_get_format - Handle get format by pads subdev method
955 * @sd : pointer to v4l2 subdev structure
956 * @fh : V4L2 subdev file handle
957 * @fmt: pointer to v4l2 subdev format structure
958 * return -EINVAL or zero on success
959 */
960static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
961 struct v4l2_subdev_format *fmt)
962{
963 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
964 struct v4l2_mbus_framefmt *format;
965
966 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
967 if (format == NULL)
968 return -EINVAL;
969
970 fmt->format = *format;
971 return 0;
972}
973
974/*
975 * csi2_set_format - Handle set format by pads subdev method
976 * @sd : pointer to v4l2 subdev structure
977 * @fh : V4L2 subdev file handle
978 * @fmt: pointer to v4l2 subdev format structure
979 * return -EINVAL or zero on success
980 */
981static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
982 struct v4l2_subdev_format *fmt)
983{
984 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
985 struct v4l2_mbus_framefmt *format;
986
987 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
988 if (format == NULL)
989 return -EINVAL;
990
991 csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which);
992 *format = fmt->format;
993
994 /* Propagate the format from sink to source */
995 if (fmt->pad == CSI2_PAD_SINK) {
996 format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE,
997 fmt->which);
998 *format = fmt->format;
999 csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which);
1000 }
1001
1002 return 0;
1003}
1004
1005static int csi2_link_validate(struct v4l2_subdev *sd, struct media_link *link,
1006 struct v4l2_subdev_format *source_fmt,
1007 struct v4l2_subdev_format *sink_fmt)
1008{
1009 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1010 struct iss_pipeline *pipe = to_iss_pipeline(&csi2->subdev.entity);
1011 int rval;
1012
1013 pipe->external = media_entity_to_v4l2_subdev(link->source->entity);
1014 rval = omap4iss_get_external_info(pipe, link);
1015 if (rval < 0)
1016 return rval;
1017
1018 return v4l2_subdev_link_validate_default(sd, link, source_fmt,
1019 sink_fmt);
1020}
1021
1022/*
1023 * csi2_init_formats - Initialize formats on all pads
1024 * @sd: ISS CSI2 V4L2 subdevice
1025 * @fh: V4L2 subdev file handle
1026 *
1027 * Initialize all pad formats with default values. If fh is not NULL, try
1028 * formats are initialized on the file handle. Otherwise active formats are
1029 * initialized on the device.
1030 */
1031static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1032{
1033 struct v4l2_subdev_format format;
1034
1035 memset(&format, 0, sizeof(format));
1036 format.pad = CSI2_PAD_SINK;
1037 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1038 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1039 format.format.width = 4096;
1040 format.format.height = 4096;
1041 csi2_set_format(sd, fh, &format);
1042
1043 return 0;
1044}
1045
1046/*
1047 * csi2_set_stream - Enable/Disable streaming on the CSI2 module
1048 * @sd: ISS CSI2 V4L2 subdevice
1049 * @enable: ISS pipeline stream state
1050 *
1051 * Return 0 on success or a negative error code otherwise.
1052 */
1053static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
1054{
1055 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1056 struct iss_device *iss = csi2->iss;
1057 struct iss_pipeline *pipe = to_iss_pipeline(&csi2->subdev.entity);
1058 struct iss_video *video_out = &csi2->video_out;
1059 int ret = 0;
1060
1061 if (csi2->state == ISS_PIPELINE_STREAM_STOPPED) {
1062 if (enable == ISS_PIPELINE_STREAM_STOPPED)
1063 return 0;
1064
1065 omap4iss_subclk_enable(iss, csi2->subclk);
1066 }
1067
1068 switch (enable) {
1069 case ISS_PIPELINE_STREAM_CONTINUOUS: {
1070 ret = omap4iss_csiphy_config(iss, sd);
1071 if (ret < 0)
1072 return ret;
1073
1074 if (omap4iss_csiphy_acquire(csi2->phy) < 0)
1075 return -ENODEV;
1076 csi2->use_fs_irq = pipe->do_propagation;
1077 csi2_configure(csi2);
1078 csi2_print_status(csi2);
1079
1080 /*
1081 * When outputting to memory with no buffer available, let the
1082 * buffer queue handler start the hardware. A DMA queue flag
1083 * ISS_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
1084 * a buffer available.
1085 */
1086 if (csi2->output & CSI2_OUTPUT_MEMORY &&
1087 !(video_out->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_QUEUED))
1088 break;
1089 /* Enable context 0 and IRQs */
1090 atomic_set(&csi2->stopping, 0);
1091 csi2_ctx_enable(csi2, 0, 1);
1092 csi2_if_enable(csi2, 1);
1093 iss_video_dmaqueue_flags_clr(video_out);
1094 break;
1095 }
1096 case ISS_PIPELINE_STREAM_STOPPED:
1097 if (csi2->state == ISS_PIPELINE_STREAM_STOPPED)
1098 return 0;
1099 if (omap4iss_module_sync_idle(&sd->entity, &csi2->wait,
1100 &csi2->stopping))
1101 ret = -ETIMEDOUT;
1102 csi2_ctx_enable(csi2, 0, 0);
1103 csi2_if_enable(csi2, 0);
1104 csi2_irq_ctx_set(csi2, 0);
1105 omap4iss_csiphy_release(csi2->phy);
1106 omap4iss_subclk_disable(iss, csi2->subclk);
1107 iss_video_dmaqueue_flags_clr(video_out);
1108 break;
1109 }
1110
1111 csi2->state = enable;
1112 return ret;
1113}
1114
1115/* subdev video operations */
1116static const struct v4l2_subdev_video_ops csi2_video_ops = {
1117 .s_stream = csi2_set_stream,
1118};
1119
1120/* subdev pad operations */
1121static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
1122 .enum_mbus_code = csi2_enum_mbus_code,
1123 .enum_frame_size = csi2_enum_frame_size,
1124 .get_fmt = csi2_get_format,
1125 .set_fmt = csi2_set_format,
1126 .link_validate = csi2_link_validate,
1127};
1128
1129/* subdev operations */
1130static const struct v4l2_subdev_ops csi2_ops = {
1131 .video = &csi2_video_ops,
1132 .pad = &csi2_pad_ops,
1133};
1134
1135/* subdev internal operations */
1136static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
1137 .open = csi2_init_formats,
1138};
1139
1140/* -----------------------------------------------------------------------------
1141 * Media entity operations
1142 */
1143
1144/*
1145 * csi2_link_setup - Setup CSI2 connections.
1146 * @entity : Pointer to media entity structure
1147 * @local : Pointer to local pad array
1148 * @remote : Pointer to remote pad array
1149 * @flags : Link flags
1150 * return -EINVAL or zero on success
1151 */
1152static int csi2_link_setup(struct media_entity *entity,
1153 const struct media_pad *local,
1154 const struct media_pad *remote, u32 flags)
1155{
1156 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1157 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1158 struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
1159
1160 /*
1161 * The ISS core doesn't support pipelines with multiple video outputs.
1162 * Revisit this when it will be implemented, and return -EBUSY for now.
1163 */
1164
1165 switch (local->index | media_entity_type(remote->entity)) {
1166 case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1167 if (flags & MEDIA_LNK_FL_ENABLED) {
1168 if (csi2->output & ~CSI2_OUTPUT_MEMORY)
1169 return -EBUSY;
1170 csi2->output |= CSI2_OUTPUT_MEMORY;
1171 } else {
1172 csi2->output &= ~CSI2_OUTPUT_MEMORY;
1173 }
1174 break;
1175
1176 case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1177 if (flags & MEDIA_LNK_FL_ENABLED) {
1178 if (csi2->output & ~CSI2_OUTPUT_IPIPEIF)
1179 return -EBUSY;
1180 csi2->output |= CSI2_OUTPUT_IPIPEIF;
1181 } else {
1182 csi2->output &= ~CSI2_OUTPUT_IPIPEIF;
1183 }
1184 break;
1185
1186 default:
1187 /* Link from camera to CSI2 is fixed... */
1188 return -EINVAL;
1189 }
1190
1191 ctrl->vp_only_enable = csi2->output & CSI2_OUTPUT_MEMORY ? false : true;
1192 ctrl->vp_clk_enable = !!(csi2->output & CSI2_OUTPUT_IPIPEIF);
1193
1194 return 0;
1195}
1196
1197/* media operations */
1198static const struct media_entity_operations csi2_media_ops = {
1199 .link_setup = csi2_link_setup,
1200 .link_validate = v4l2_subdev_link_validate,
1201};
1202
1203void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2)
1204{
1205 v4l2_device_unregister_subdev(&csi2->subdev);
1206 omap4iss_video_unregister(&csi2->video_out);
1207}
1208
1209int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2,
1210 struct v4l2_device *vdev)
1211{
1212 int ret;
1213
1214 /* Register the subdev and video nodes. */
1215 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1216 if (ret < 0)
1217 goto error;
1218
1219 ret = omap4iss_video_register(&csi2->video_out, vdev);
1220 if (ret < 0)
1221 goto error;
1222
1223 return 0;
1224
1225error:
1226 omap4iss_csi2_unregister_entities(csi2);
1227 return ret;
1228}
1229
1230/* -----------------------------------------------------------------------------
1231 * ISS CSI2 initialisation and cleanup
1232 */
1233
1234/*
1235 * csi2_init_entities - Initialize subdev and media entity.
1236 * @csi2: Pointer to csi2 structure.
1237 * return -ENOMEM or zero on success
1238 */
1239static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
1240{
1241 struct v4l2_subdev *sd = &csi2->subdev;
1242 struct media_pad *pads = csi2->pads;
1243 struct media_entity *me = &sd->entity;
1244 int ret;
1245 char name[V4L2_SUBDEV_NAME_SIZE];
1246
1247 v4l2_subdev_init(sd, &csi2_ops);
1248 sd->internal_ops = &csi2_internal_ops;
1249 sprintf(name, "CSI2%s", subname);
1250 snprintf(sd->name, sizeof(sd->name), "OMAP4 ISS %s", name);
1251
1252 sd->grp_id = 1 << 16; /* group ID for iss subdevs */
1253 v4l2_set_subdevdata(sd, csi2);
1254 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1255
1256 pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1257 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1258
1259 me->ops = &csi2_media_ops;
1260 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
1261 if (ret < 0)
1262 return ret;
1263
1264 csi2_init_formats(sd, NULL);
1265
1266 /* Video device node */
1267 csi2->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1268 csi2->video_out.ops = &csi2_issvideo_ops;
1269 csi2->video_out.bpl_alignment = 32;
1270 csi2->video_out.bpl_zero_padding = 1;
1271 csi2->video_out.bpl_max = 0x1ffe0;
1272 csi2->video_out.iss = csi2->iss;
1273 csi2->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1274
1275 ret = omap4iss_video_init(&csi2->video_out, name);
1276 if (ret < 0)
1277 goto error_video;
1278
1279 /* Connect the CSI2 subdev to the video node. */
1280 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1281 &csi2->video_out.video.entity, 0, 0);
1282 if (ret < 0)
1283 goto error_link;
1284
1285 return 0;
1286
1287error_link:
1288 omap4iss_video_cleanup(&csi2->video_out);
1289error_video:
1290 media_entity_cleanup(&csi2->subdev.entity);
1291 return ret;
1292}
1293
1294/*
1295 * omap4iss_csi2_init - Routine for module driver init
1296 */
1297int omap4iss_csi2_init(struct iss_device *iss)
1298{
1299 struct iss_csi2_device *csi2a = &iss->csi2a;
1300 struct iss_csi2_device *csi2b = &iss->csi2b;
1301 int ret;
1302
1303 csi2a->iss = iss;
1304 csi2a->available = 1;
1305 csi2a->regs1 = OMAP4_ISS_MEM_CSI2_A_REGS1;
1306 csi2a->phy = &iss->csiphy1;
1307 csi2a->subclk = OMAP4_ISS_SUBCLK_CSI2_A;
1308 csi2a->state = ISS_PIPELINE_STREAM_STOPPED;
1309 init_waitqueue_head(&csi2a->wait);
1310
1311 ret = csi2_init_entities(csi2a, "a");
1312 if (ret < 0)
1313 return ret;
1314
1315 csi2b->iss = iss;
1316 csi2b->available = 1;
1317 csi2b->regs1 = OMAP4_ISS_MEM_CSI2_B_REGS1;
1318 csi2b->phy = &iss->csiphy2;
1319 csi2b->subclk = OMAP4_ISS_SUBCLK_CSI2_B;
1320 csi2b->state = ISS_PIPELINE_STREAM_STOPPED;
1321 init_waitqueue_head(&csi2b->wait);
1322
1323 ret = csi2_init_entities(csi2b, "b");
1324 if (ret < 0)
1325 return ret;
1326
1327 return 0;
1328}
1329
1330/*
1331 * omap4iss_csi2_cleanup - Routine for module driver cleanup
1332 */
1333void omap4iss_csi2_cleanup(struct iss_device *iss)
1334{
1335 struct iss_csi2_device *csi2a = &iss->csi2a;
1336 struct iss_csi2_device *csi2b = &iss->csi2b;
1337
1338 omap4iss_video_cleanup(&csi2a->video_out);
1339 media_entity_cleanup(&csi2a->subdev.entity);
1340
1341 omap4iss_video_cleanup(&csi2b->video_out);
1342 media_entity_cleanup(&csi2b->subdev.entity);
1343}
diff --git a/drivers/staging/media/omap4iss/iss_csi2.h b/drivers/staging/media/omap4iss/iss_csi2.h
new file mode 100644
index 000000000000..971aa7b08013
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_csi2.h
@@ -0,0 +1,158 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - CSI2 module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef OMAP4_ISS_CSI2_H
15#define OMAP4_ISS_CSI2_H
16
17#include <linux/types.h>
18#include <linux/videodev2.h>
19
20#include "iss_video.h"
21
22struct iss_csiphy;
23
24/* This is not an exhaustive list */
25enum iss_csi2_pix_formats {
26 CSI2_PIX_FMT_OTHERS = 0,
27 CSI2_PIX_FMT_YUV422_8BIT = 0x1e,
28 CSI2_PIX_FMT_YUV422_8BIT_VP = 0x9e,
29 CSI2_PIX_FMT_YUV422_8BIT_VP16 = 0xde,
30 CSI2_PIX_FMT_RAW10_EXP16 = 0xab,
31 CSI2_PIX_FMT_RAW10_EXP16_VP = 0x12f,
32 CSI2_PIX_FMT_RAW8 = 0x2a,
33 CSI2_PIX_FMT_RAW8_DPCM10_EXP16 = 0x2aa,
34 CSI2_PIX_FMT_RAW8_DPCM10_VP = 0x32a,
35 CSI2_PIX_FMT_RAW8_VP = 0x12a,
36 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP = 0x340,
37 CSI2_USERDEF_8BIT_DATA1_DPCM10 = 0x2c0,
38 CSI2_USERDEF_8BIT_DATA1 = 0x40,
39};
40
41enum iss_csi2_irqevents {
42 OCP_ERR_IRQ = 0x4000,
43 SHORT_PACKET_IRQ = 0x2000,
44 ECC_CORRECTION_IRQ = 0x1000,
45 ECC_NO_CORRECTION_IRQ = 0x800,
46 COMPLEXIO2_ERR_IRQ = 0x400,
47 COMPLEXIO1_ERR_IRQ = 0x200,
48 FIFO_OVF_IRQ = 0x100,
49 CONTEXT7 = 0x80,
50 CONTEXT6 = 0x40,
51 CONTEXT5 = 0x20,
52 CONTEXT4 = 0x10,
53 CONTEXT3 = 0x8,
54 CONTEXT2 = 0x4,
55 CONTEXT1 = 0x2,
56 CONTEXT0 = 0x1,
57};
58
59enum iss_csi2_ctx_irqevents {
60 CTX_ECC_CORRECTION = 0x100,
61 CTX_LINE_NUMBER = 0x80,
62 CTX_FRAME_NUMBER = 0x40,
63 CTX_CS = 0x20,
64 CTX_LE = 0x8,
65 CTX_LS = 0x4,
66 CTX_FE = 0x2,
67 CTX_FS = 0x1,
68};
69
70enum iss_csi2_frame_mode {
71 ISS_CSI2_FRAME_IMMEDIATE,
72 ISS_CSI2_FRAME_AFTERFEC,
73};
74
75#define ISS_CSI2_MAX_CTX_NUM 7
76
77struct iss_csi2_ctx_cfg {
78 u8 ctxnum; /* context number 0 - 7 */
79 u8 dpcm_decompress;
80
81 /* Fields in CSI2_CTx_CTRL2 - locked by CSI2_CTx_CTRL1.CTX_EN */
82 u8 virtual_id;
83 u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */
84 u8 dpcm_predictor; /* 1: simple, 0: advanced */
85
86 /* Fields in CSI2_CTx_CTRL1/3 - Shadowed */
87 u16 alpha;
88 u16 data_offset;
89 u32 ping_addr;
90 u32 pong_addr;
91 u8 eof_enabled;
92 u8 eol_enabled;
93 u8 checksum_enabled;
94 u8 enabled;
95};
96
97struct iss_csi2_timing_cfg {
98 u8 ionum; /* IO1 or IO2 as in CSI2_TIMING */
99 unsigned force_rx_mode:1;
100 unsigned stop_state_16x:1;
101 unsigned stop_state_4x:1;
102 u16 stop_state_counter;
103};
104
105struct iss_csi2_ctrl_cfg {
106 bool vp_clk_enable;
107 bool vp_only_enable;
108 u8 vp_out_ctrl;
109 enum iss_csi2_frame_mode frame_mode;
110 bool ecc_enable;
111 bool if_enable;
112};
113
114#define CSI2_PAD_SINK 0
115#define CSI2_PAD_SOURCE 1
116#define CSI2_PADS_NUM 2
117
118#define CSI2_OUTPUT_IPIPEIF (1 << 0)
119#define CSI2_OUTPUT_MEMORY (1 << 1)
120
121struct iss_csi2_device {
122 struct v4l2_subdev subdev;
123 struct media_pad pads[CSI2_PADS_NUM];
124 struct v4l2_mbus_framefmt formats[CSI2_PADS_NUM];
125
126 struct iss_video video_out;
127 struct iss_device *iss;
128
129 u8 available; /* Is the IP present on the silicon? */
130
131 /* memory resources, as defined in enum iss_mem_resources */
132 unsigned int regs1;
133 unsigned int regs2;
134 /* ISP subclock, as defined in enum iss_isp_subclk_resource */
135 unsigned int subclk;
136
137 u32 output; /* output to IPIPEIF, memory or both? */
138 bool dpcm_decompress;
139 unsigned int frame_skip;
140 bool use_fs_irq;
141
142 struct iss_csiphy *phy;
143 struct iss_csi2_ctx_cfg contexts[ISS_CSI2_MAX_CTX_NUM + 1];
144 struct iss_csi2_timing_cfg timing[2];
145 struct iss_csi2_ctrl_cfg ctrl;
146 enum iss_pipeline_stream_state state;
147 wait_queue_head_t wait;
148 atomic_t stopping;
149};
150
151void omap4iss_csi2_isr(struct iss_csi2_device *csi2);
152int omap4iss_csi2_reset(struct iss_csi2_device *csi2);
153int omap4iss_csi2_init(struct iss_device *iss);
154void omap4iss_csi2_cleanup(struct iss_device *iss);
155void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2);
156int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2,
157 struct v4l2_device *vdev);
158#endif /* OMAP4_ISS_CSI2_H */
diff --git a/drivers/staging/media/omap4iss/iss_csiphy.c b/drivers/staging/media/omap4iss/iss_csiphy.c
new file mode 100644
index 000000000000..7c3d55d811ef
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_csiphy.c
@@ -0,0 +1,279 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - CSI PHY module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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/delay.h>
15#include <linux/device.h>
16
17#include "../../../../arch/arm/mach-omap2/control.h"
18
19#include "iss.h"
20#include "iss_regs.h"
21#include "iss_csiphy.h"
22
23/*
24 * csiphy_lanes_config - Configuration of CSIPHY lanes.
25 *
26 * Updates HW configuration.
27 * Called with phy->mutex taken.
28 */
29static void csiphy_lanes_config(struct iss_csiphy *phy)
30{
31 unsigned int i;
32 u32 reg;
33
34 reg = iss_reg_read(phy->iss, phy->cfg_regs, CSI2_COMPLEXIO_CFG);
35
36 for (i = 0; i < phy->max_data_lanes; i++) {
37 reg &= ~(CSI2_COMPLEXIO_CFG_DATA_POL(i + 1) |
38 CSI2_COMPLEXIO_CFG_DATA_POSITION_MASK(i + 1));
39 reg |= (phy->lanes.data[i].pol ?
40 CSI2_COMPLEXIO_CFG_DATA_POL(i + 1) : 0);
41 reg |= (phy->lanes.data[i].pos <<
42 CSI2_COMPLEXIO_CFG_DATA_POSITION_SHIFT(i + 1));
43 }
44
45 reg &= ~(CSI2_COMPLEXIO_CFG_CLOCK_POL |
46 CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK);
47 reg |= phy->lanes.clk.pol ? CSI2_COMPLEXIO_CFG_CLOCK_POL : 0;
48 reg |= phy->lanes.clk.pos << CSI2_COMPLEXIO_CFG_CLOCK_POSITION_SHIFT;
49
50 iss_reg_write(phy->iss, phy->cfg_regs, CSI2_COMPLEXIO_CFG, reg);
51}
52
53/*
54 * csiphy_set_power
55 * @power: Power state to be set.
56 *
57 * Returns 0 if successful, or -EBUSY if the retry count is exceeded.
58 */
59static int csiphy_set_power(struct iss_csiphy *phy, u32 power)
60{
61 u32 reg;
62 u8 retry_count;
63
64 iss_reg_update(phy->iss, phy->cfg_regs, CSI2_COMPLEXIO_CFG,
65 CSI2_COMPLEXIO_CFG_PWD_CMD_MASK,
66 power | CSI2_COMPLEXIO_CFG_PWR_AUTO);
67
68 retry_count = 0;
69 do {
70 udelay(1);
71 reg = iss_reg_read(phy->iss, phy->cfg_regs, CSI2_COMPLEXIO_CFG)
72 & CSI2_COMPLEXIO_CFG_PWD_STATUS_MASK;
73
74 if (reg != power >> 2)
75 retry_count++;
76
77 } while ((reg != power >> 2) && (retry_count < 250));
78
79 if (retry_count == 250) {
80 dev_err(phy->iss->dev, "CSI2 CIO set power failed!\n");
81 return -EBUSY;
82 }
83
84 return 0;
85}
86
87/*
88 * csiphy_dphy_config - Configure CSI2 D-PHY parameters.
89 *
90 * Called with phy->mutex taken.
91 */
92static void csiphy_dphy_config(struct iss_csiphy *phy)
93{
94 u32 reg;
95
96 /* Set up REGISTER0 */
97 reg = phy->dphy.ths_term << REGISTER0_THS_TERM_SHIFT;
98 reg |= phy->dphy.ths_settle << REGISTER0_THS_SETTLE_SHIFT;
99
100 iss_reg_write(phy->iss, phy->phy_regs, REGISTER0, reg);
101
102 /* Set up REGISTER1 */
103 reg = phy->dphy.tclk_term << REGISTER1_TCLK_TERM_SHIFT;
104 reg |= phy->dphy.tclk_miss << REGISTER1_CTRLCLK_DIV_FACTOR_SHIFT;
105 reg |= phy->dphy.tclk_settle << REGISTER1_TCLK_SETTLE_SHIFT;
106 reg |= 0xb8 << REGISTER1_DPHY_HS_SYNC_PATTERN_SHIFT;
107
108 iss_reg_write(phy->iss, phy->phy_regs, REGISTER1, reg);
109}
110
111/*
112 * TCLK values are OK at their reset values
113 */
114#define TCLK_TERM 0
115#define TCLK_MISS 1
116#define TCLK_SETTLE 14
117
118int omap4iss_csiphy_config(struct iss_device *iss,
119 struct v4l2_subdev *csi2_subdev)
120{
121 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(csi2_subdev);
122 struct iss_pipeline *pipe = to_iss_pipeline(&csi2_subdev->entity);
123 struct iss_v4l2_subdevs_group *subdevs = pipe->external->host_priv;
124 struct iss_csiphy_dphy_cfg csi2phy;
125 int csi2_ddrclk_khz;
126 struct iss_csiphy_lanes_cfg *lanes;
127 unsigned int used_lanes = 0;
128 u32 cam_rx_ctrl;
129 unsigned int i;
130
131 lanes = &subdevs->bus.csi2.lanecfg;
132
133 /*
134 * SCM.CONTROL_CAMERA_RX
135 * - bit [31] : CSIPHY2 lane 2 enable (4460+ only)
136 * - bit [30:29] : CSIPHY2 per-lane enable (1 to 0)
137 * - bit [28:24] : CSIPHY1 per-lane enable (4 to 0)
138 * - bit [21] : CSIPHY2 CTRLCLK enable
139 * - bit [20:19] : CSIPHY2 config: 00 d-phy, 01/10 ccp2
140 * - bit [18] : CSIPHY1 CTRLCLK enable
141 * - bit [17:16] : CSIPHY1 config: 00 d-phy, 01/10 ccp2
142 */
143 cam_rx_ctrl = omap4_ctrl_pad_readl(
144 OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX);
145
146
147 if (subdevs->interface == ISS_INTERFACE_CSI2A_PHY1) {
148 cam_rx_ctrl &= ~(OMAP4_CAMERARX_CSI21_LANEENABLE_MASK |
149 OMAP4_CAMERARX_CSI21_CAMMODE_MASK);
150 /* NOTE: Leave CSIPHY1 config to 0x0: D-PHY mode */
151 /* Enable all lanes for now */
152 cam_rx_ctrl |=
153 0x1f << OMAP4_CAMERARX_CSI21_LANEENABLE_SHIFT;
154 /* Enable CTRLCLK */
155 cam_rx_ctrl |= OMAP4_CAMERARX_CSI21_CTRLCLKEN_MASK;
156 }
157
158 if (subdevs->interface == ISS_INTERFACE_CSI2B_PHY2) {
159 cam_rx_ctrl &= ~(OMAP4_CAMERARX_CSI22_LANEENABLE_MASK |
160 OMAP4_CAMERARX_CSI22_CAMMODE_MASK);
161 /* NOTE: Leave CSIPHY2 config to 0x0: D-PHY mode */
162 /* Enable all lanes for now */
163 cam_rx_ctrl |=
164 0x3 << OMAP4_CAMERARX_CSI22_LANEENABLE_SHIFT;
165 /* Enable CTRLCLK */
166 cam_rx_ctrl |= OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK;
167 }
168
169 omap4_ctrl_pad_writel(cam_rx_ctrl,
170 OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX);
171
172 /* Reset used lane count */
173 csi2->phy->used_data_lanes = 0;
174
175 /* Clock and data lanes verification */
176 for (i = 0; i < csi2->phy->max_data_lanes; i++) {
177 if (lanes->data[i].pos == 0)
178 continue;
179
180 if (lanes->data[i].pol > 1 ||
181 lanes->data[i].pos > (csi2->phy->max_data_lanes + 1))
182 return -EINVAL;
183
184 if (used_lanes & (1 << lanes->data[i].pos))
185 return -EINVAL;
186
187 used_lanes |= 1 << lanes->data[i].pos;
188 csi2->phy->used_data_lanes++;
189 }
190
191 if (lanes->clk.pol > 1 ||
192 lanes->clk.pos > (csi2->phy->max_data_lanes + 1))
193 return -EINVAL;
194
195 if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
196 return -EINVAL;
197
198 csi2_ddrclk_khz = pipe->external_rate / 1000
199 / (2 * csi2->phy->used_data_lanes)
200 * pipe->external_bpp;
201
202 /*
203 * THS_TERM: Programmed value = ceil(12.5 ns/DDRClk period) - 1.
204 * THS_SETTLE: Programmed value = ceil(90 ns/DDRClk period) + 3.
205 */
206 csi2phy.ths_term = DIV_ROUND_UP(25 * csi2_ddrclk_khz, 2000000) - 1;
207 csi2phy.ths_settle = DIV_ROUND_UP(90 * csi2_ddrclk_khz, 1000000) + 3;
208 csi2phy.tclk_term = TCLK_TERM;
209 csi2phy.tclk_miss = TCLK_MISS;
210 csi2phy.tclk_settle = TCLK_SETTLE;
211
212 mutex_lock(&csi2->phy->mutex);
213 csi2->phy->dphy = csi2phy;
214 csi2->phy->lanes = *lanes;
215 mutex_unlock(&csi2->phy->mutex);
216
217 return 0;
218}
219
220int omap4iss_csiphy_acquire(struct iss_csiphy *phy)
221{
222 int rval;
223
224 mutex_lock(&phy->mutex);
225
226 rval = omap4iss_csi2_reset(phy->csi2);
227 if (rval)
228 goto done;
229
230 csiphy_dphy_config(phy);
231 csiphy_lanes_config(phy);
232
233 rval = csiphy_set_power(phy, CSI2_COMPLEXIO_CFG_PWD_CMD_ON);
234 if (rval)
235 goto done;
236
237 phy->phy_in_use = 1;
238
239done:
240 mutex_unlock(&phy->mutex);
241 return rval;
242}
243
244void omap4iss_csiphy_release(struct iss_csiphy *phy)
245{
246 mutex_lock(&phy->mutex);
247 if (phy->phy_in_use) {
248 csiphy_set_power(phy, CSI2_COMPLEXIO_CFG_PWD_CMD_OFF);
249 phy->phy_in_use = 0;
250 }
251 mutex_unlock(&phy->mutex);
252}
253
254/*
255 * omap4iss_csiphy_init - Initialize the CSI PHY frontends
256 */
257int omap4iss_csiphy_init(struct iss_device *iss)
258{
259 struct iss_csiphy *phy1 = &iss->csiphy1;
260 struct iss_csiphy *phy2 = &iss->csiphy2;
261
262 phy1->iss = iss;
263 phy1->csi2 = &iss->csi2a;
264 phy1->max_data_lanes = ISS_CSIPHY1_NUM_DATA_LANES;
265 phy1->used_data_lanes = 0;
266 phy1->cfg_regs = OMAP4_ISS_MEM_CSI2_A_REGS1;
267 phy1->phy_regs = OMAP4_ISS_MEM_CAMERARX_CORE1;
268 mutex_init(&phy1->mutex);
269
270 phy2->iss = iss;
271 phy2->csi2 = &iss->csi2b;
272 phy2->max_data_lanes = ISS_CSIPHY2_NUM_DATA_LANES;
273 phy2->used_data_lanes = 0;
274 phy2->cfg_regs = OMAP4_ISS_MEM_CSI2_B_REGS1;
275 phy2->phy_regs = OMAP4_ISS_MEM_CAMERARX_CORE2;
276 mutex_init(&phy2->mutex);
277
278 return 0;
279}
diff --git a/drivers/staging/media/omap4iss/iss_csiphy.h b/drivers/staging/media/omap4iss/iss_csiphy.h
new file mode 100644
index 000000000000..e9ca43955654
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_csiphy.h
@@ -0,0 +1,51 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - CSI PHY module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef OMAP4_ISS_CSI_PHY_H
15#define OMAP4_ISS_CSI_PHY_H
16
17#include <media/omap4iss.h>
18
19struct iss_csi2_device;
20
21struct iss_csiphy_dphy_cfg {
22 u8 ths_term;
23 u8 ths_settle;
24 u8 tclk_term;
25 unsigned tclk_miss:1;
26 u8 tclk_settle;
27};
28
29struct iss_csiphy {
30 struct iss_device *iss;
31 struct mutex mutex; /* serialize csiphy configuration */
32 u8 phy_in_use;
33 struct iss_csi2_device *csi2;
34
35 /* memory resources, as defined in enum iss_mem_resources */
36 unsigned int cfg_regs;
37 unsigned int phy_regs;
38
39 u8 max_data_lanes; /* number of CSI2 Data Lanes supported */
40 u8 used_data_lanes; /* number of CSI2 Data Lanes used */
41 struct iss_csiphy_lanes_cfg lanes;
42 struct iss_csiphy_dphy_cfg dphy;
43};
44
45int omap4iss_csiphy_config(struct iss_device *iss,
46 struct v4l2_subdev *csi2_subdev);
47int omap4iss_csiphy_acquire(struct iss_csiphy *phy);
48void omap4iss_csiphy_release(struct iss_csiphy *phy);
49int omap4iss_csiphy_init(struct iss_device *iss);
50
51#endif /* OMAP4_ISS_CSI_PHY_H */
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c
new file mode 100644
index 000000000000..6eaafc5e2eea
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_ipipe.c
@@ -0,0 +1,570 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - ISP IPIPE module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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/module.h>
15#include <linux/uaccess.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/dma-mapping.h>
19#include <linux/mm.h>
20#include <linux/sched.h>
21
22#include "iss.h"
23#include "iss_regs.h"
24#include "iss_ipipe.h"
25
26static struct v4l2_mbus_framefmt *
27__ipipe_get_format(struct iss_ipipe_device *ipipe, struct v4l2_subdev_fh *fh,
28 unsigned int pad, enum v4l2_subdev_format_whence which);
29
30static const unsigned int ipipe_fmts[] = {
31 V4L2_MBUS_FMT_SGRBG10_1X10,
32 V4L2_MBUS_FMT_SRGGB10_1X10,
33 V4L2_MBUS_FMT_SBGGR10_1X10,
34 V4L2_MBUS_FMT_SGBRG10_1X10,
35};
36
37/*
38 * ipipe_print_status - Print current IPIPE Module register values.
39 * @ipipe: Pointer to ISS ISP IPIPE device.
40 *
41 * Also prints other debug information stored in the IPIPE module.
42 */
43#define IPIPE_PRINT_REGISTER(iss, name)\
44 dev_dbg(iss->dev, "###IPIPE " #name "=0x%08x\n", \
45 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_##name))
46
47static void ipipe_print_status(struct iss_ipipe_device *ipipe)
48{
49 struct iss_device *iss = to_iss_device(ipipe);
50
51 dev_dbg(iss->dev, "-------------IPIPE Register dump-------------\n");
52
53 IPIPE_PRINT_REGISTER(iss, SRC_EN);
54 IPIPE_PRINT_REGISTER(iss, SRC_MODE);
55 IPIPE_PRINT_REGISTER(iss, SRC_FMT);
56 IPIPE_PRINT_REGISTER(iss, SRC_COL);
57 IPIPE_PRINT_REGISTER(iss, SRC_VPS);
58 IPIPE_PRINT_REGISTER(iss, SRC_VSZ);
59 IPIPE_PRINT_REGISTER(iss, SRC_HPS);
60 IPIPE_PRINT_REGISTER(iss, SRC_HSZ);
61 IPIPE_PRINT_REGISTER(iss, GCK_MMR);
62 IPIPE_PRINT_REGISTER(iss, YUV_PHS);
63
64 dev_dbg(iss->dev, "-----------------------------------------------\n");
65}
66
67/*
68 * ipipe_enable - Enable/Disable IPIPE.
69 * @enable: enable flag
70 *
71 */
72static void ipipe_enable(struct iss_ipipe_device *ipipe, u8 enable)
73{
74 struct iss_device *iss = to_iss_device(ipipe);
75
76 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_EN,
77 IPIPE_SRC_EN_EN, enable ? IPIPE_SRC_EN_EN : 0);
78}
79
80/* -----------------------------------------------------------------------------
81 * Format- and pipeline-related configuration helpers
82 */
83
84static void ipipe_configure(struct iss_ipipe_device *ipipe)
85{
86 struct iss_device *iss = to_iss_device(ipipe);
87 struct v4l2_mbus_framefmt *format;
88
89 /* IPIPE_PAD_SINK */
90 format = &ipipe->formats[IPIPE_PAD_SINK];
91
92 /* NOTE: Currently just supporting pipeline IN: RGB, OUT: YUV422 */
93 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_FMT,
94 IPIPE_SRC_FMT_RAW2YUV);
95
96 /* Enable YUV444 -> YUV422 conversion */
97 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_YUV_PHS,
98 IPIPE_YUV_PHS_LPF);
99
100 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_VPS, 0);
101 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_HPS, 0);
102 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_VSZ,
103 (format->height - 2) & IPIPE_SRC_VSZ_MASK);
104 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_HSZ,
105 (format->width - 1) & IPIPE_SRC_HSZ_MASK);
106
107 /* Ignore ipipeif_wrt signal, and operate on-the-fly. */
108 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_MODE,
109 IPIPE_SRC_MODE_WRT | IPIPE_SRC_MODE_OST);
110
111 /* HACK: Values tuned for Ducati SW (OV) */
112 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_SRC_COL,
113 IPIPE_SRC_COL_EE_B | IPIPE_SRC_COL_EO_GB |
114 IPIPE_SRC_COL_OE_GR | IPIPE_SRC_COL_OO_R);
115
116 /* IPIPE_PAD_SOURCE_VP */
117 format = &ipipe->formats[IPIPE_PAD_SOURCE_VP];
118 /* Do nothing? */
119}
120
121/* -----------------------------------------------------------------------------
122 * V4L2 subdev operations
123 */
124
125/*
126 * ipipe_set_stream - Enable/Disable streaming on the IPIPE module
127 * @sd: ISP IPIPE V4L2 subdevice
128 * @enable: Enable/disable stream
129 */
130static int ipipe_set_stream(struct v4l2_subdev *sd, int enable)
131{
132 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
133 struct iss_device *iss = to_iss_device(ipipe);
134 int ret = 0;
135
136 if (ipipe->state == ISS_PIPELINE_STREAM_STOPPED) {
137 if (enable == ISS_PIPELINE_STREAM_STOPPED)
138 return 0;
139
140 omap4iss_isp_subclk_enable(iss, OMAP4_ISS_ISP_SUBCLK_IPIPE);
141
142 /* Enable clk_arm_g0 */
143 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_GCK_MMR,
144 IPIPE_GCK_MMR_REG);
145
146 /* Enable clk_pix_g[3:0] */
147 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_IPIPE, IPIPE_GCK_PIX,
148 IPIPE_GCK_PIX_G3 | IPIPE_GCK_PIX_G2 |
149 IPIPE_GCK_PIX_G1 | IPIPE_GCK_PIX_G0);
150 }
151
152 switch (enable) {
153 case ISS_PIPELINE_STREAM_CONTINUOUS:
154
155 ipipe_configure(ipipe);
156 ipipe_print_status(ipipe);
157
158 atomic_set(&ipipe->stopping, 0);
159 ipipe_enable(ipipe, 1);
160 break;
161
162 case ISS_PIPELINE_STREAM_STOPPED:
163 if (ipipe->state == ISS_PIPELINE_STREAM_STOPPED)
164 return 0;
165 if (omap4iss_module_sync_idle(&sd->entity, &ipipe->wait,
166 &ipipe->stopping))
167 ret = -ETIMEDOUT;
168
169 ipipe_enable(ipipe, 0);
170 omap4iss_isp_subclk_disable(iss, OMAP4_ISS_ISP_SUBCLK_IPIPE);
171 break;
172 }
173
174 ipipe->state = enable;
175 return ret;
176}
177
178static struct v4l2_mbus_framefmt *
179__ipipe_get_format(struct iss_ipipe_device *ipipe, struct v4l2_subdev_fh *fh,
180 unsigned int pad, enum v4l2_subdev_format_whence which)
181{
182 if (which == V4L2_SUBDEV_FORMAT_TRY)
183 return v4l2_subdev_get_try_format(fh, pad);
184 else
185 return &ipipe->formats[pad];
186}
187
188/*
189 * ipipe_try_format - Try video format on a pad
190 * @ipipe: ISS IPIPE device
191 * @fh : V4L2 subdev file handle
192 * @pad: Pad number
193 * @fmt: Format
194 */
195static void
196ipipe_try_format(struct iss_ipipe_device *ipipe, struct v4l2_subdev_fh *fh,
197 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
198 enum v4l2_subdev_format_whence which)
199{
200 struct v4l2_mbus_framefmt *format;
201 unsigned int width = fmt->width;
202 unsigned int height = fmt->height;
203 unsigned int i;
204
205 switch (pad) {
206 case IPIPE_PAD_SINK:
207 for (i = 0; i < ARRAY_SIZE(ipipe_fmts); i++) {
208 if (fmt->code == ipipe_fmts[i])
209 break;
210 }
211
212 /* If not found, use SGRBG10 as default */
213 if (i >= ARRAY_SIZE(ipipe_fmts))
214 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
215
216 /* Clamp the input size. */
217 fmt->width = clamp_t(u32, width, 1, 8192);
218 fmt->height = clamp_t(u32, height, 1, 8192);
219 fmt->colorspace = V4L2_COLORSPACE_SRGB;
220 break;
221
222 case IPIPE_PAD_SOURCE_VP:
223 format = __ipipe_get_format(ipipe, fh, IPIPE_PAD_SINK, which);
224 memcpy(fmt, format, sizeof(*fmt));
225
226 fmt->code = V4L2_MBUS_FMT_UYVY8_1X16;
227 fmt->width = clamp_t(u32, width, 32, fmt->width);
228 fmt->height = clamp_t(u32, height, 32, fmt->height);
229 fmt->colorspace = V4L2_COLORSPACE_JPEG;
230 break;
231 }
232
233 fmt->field = V4L2_FIELD_NONE;
234}
235
236/*
237 * ipipe_enum_mbus_code - Handle pixel format enumeration
238 * @sd : pointer to v4l2 subdev structure
239 * @fh : V4L2 subdev file handle
240 * @code : pointer to v4l2_subdev_mbus_code_enum structure
241 * return -EINVAL or zero on success
242 */
243static int ipipe_enum_mbus_code(struct v4l2_subdev *sd,
244 struct v4l2_subdev_fh *fh,
245 struct v4l2_subdev_mbus_code_enum *code)
246{
247 switch (code->pad) {
248 case IPIPE_PAD_SINK:
249 if (code->index >= ARRAY_SIZE(ipipe_fmts))
250 return -EINVAL;
251
252 code->code = ipipe_fmts[code->index];
253 break;
254
255 case IPIPE_PAD_SOURCE_VP:
256 /* FIXME: Forced format conversion inside IPIPE ? */
257 if (code->index != 0)
258 return -EINVAL;
259
260 code->code = V4L2_MBUS_FMT_UYVY8_1X16;
261 break;
262
263 default:
264 return -EINVAL;
265 }
266
267 return 0;
268}
269
270static int ipipe_enum_frame_size(struct v4l2_subdev *sd,
271 struct v4l2_subdev_fh *fh,
272 struct v4l2_subdev_frame_size_enum *fse)
273{
274 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
275 struct v4l2_mbus_framefmt format;
276
277 if (fse->index != 0)
278 return -EINVAL;
279
280 format.code = fse->code;
281 format.width = 1;
282 format.height = 1;
283 ipipe_try_format(ipipe, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
284 fse->min_width = format.width;
285 fse->min_height = format.height;
286
287 if (format.code != fse->code)
288 return -EINVAL;
289
290 format.code = fse->code;
291 format.width = -1;
292 format.height = -1;
293 ipipe_try_format(ipipe, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
294 fse->max_width = format.width;
295 fse->max_height = format.height;
296
297 return 0;
298}
299
300/*
301 * ipipe_get_format - Retrieve the video format on a pad
302 * @sd : ISP IPIPE V4L2 subdevice
303 * @fh : V4L2 subdev file handle
304 * @fmt: Format
305 *
306 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
307 * to the format type.
308 */
309static int ipipe_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
310 struct v4l2_subdev_format *fmt)
311{
312 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
313 struct v4l2_mbus_framefmt *format;
314
315 format = __ipipe_get_format(ipipe, fh, fmt->pad, fmt->which);
316 if (format == NULL)
317 return -EINVAL;
318
319 fmt->format = *format;
320 return 0;
321}
322
323/*
324 * ipipe_set_format - Set the video format on a pad
325 * @sd : ISP IPIPE V4L2 subdevice
326 * @fh : V4L2 subdev file handle
327 * @fmt: Format
328 *
329 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
330 * to the format type.
331 */
332static int ipipe_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
333 struct v4l2_subdev_format *fmt)
334{
335 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
336 struct v4l2_mbus_framefmt *format;
337
338 format = __ipipe_get_format(ipipe, fh, fmt->pad, fmt->which);
339 if (format == NULL)
340 return -EINVAL;
341
342 ipipe_try_format(ipipe, fh, fmt->pad, &fmt->format, fmt->which);
343 *format = fmt->format;
344
345 /* Propagate the format from sink to source */
346 if (fmt->pad == IPIPE_PAD_SINK) {
347 format = __ipipe_get_format(ipipe, fh, IPIPE_PAD_SOURCE_VP,
348 fmt->which);
349 *format = fmt->format;
350 ipipe_try_format(ipipe, fh, IPIPE_PAD_SOURCE_VP, format,
351 fmt->which);
352 }
353
354 return 0;
355}
356
357static int ipipe_link_validate(struct v4l2_subdev *sd, struct media_link *link,
358 struct v4l2_subdev_format *source_fmt,
359 struct v4l2_subdev_format *sink_fmt)
360{
361 /* Check if the two ends match */
362 if (source_fmt->format.width != sink_fmt->format.width ||
363 source_fmt->format.height != sink_fmt->format.height)
364 return -EPIPE;
365
366 if (source_fmt->format.code != sink_fmt->format.code)
367 return -EPIPE;
368
369 return 0;
370}
371
372/*
373 * ipipe_init_formats - Initialize formats on all pads
374 * @sd: ISP IPIPE V4L2 subdevice
375 * @fh: V4L2 subdev file handle
376 *
377 * Initialize all pad formats with default values. If fh is not NULL, try
378 * formats are initialized on the file handle. Otherwise active formats are
379 * initialized on the device.
380 */
381static int ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
382{
383 struct v4l2_subdev_format format;
384
385 memset(&format, 0, sizeof(format));
386 format.pad = IPIPE_PAD_SINK;
387 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
388 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
389 format.format.width = 4096;
390 format.format.height = 4096;
391 ipipe_set_format(sd, fh, &format);
392
393 return 0;
394}
395
396/* V4L2 subdev video operations */
397static const struct v4l2_subdev_video_ops ipipe_v4l2_video_ops = {
398 .s_stream = ipipe_set_stream,
399};
400
401/* V4L2 subdev pad operations */
402static const struct v4l2_subdev_pad_ops ipipe_v4l2_pad_ops = {
403 .enum_mbus_code = ipipe_enum_mbus_code,
404 .enum_frame_size = ipipe_enum_frame_size,
405 .get_fmt = ipipe_get_format,
406 .set_fmt = ipipe_set_format,
407 .link_validate = ipipe_link_validate,
408};
409
410/* V4L2 subdev operations */
411static const struct v4l2_subdev_ops ipipe_v4l2_ops = {
412 .video = &ipipe_v4l2_video_ops,
413 .pad = &ipipe_v4l2_pad_ops,
414};
415
416/* V4L2 subdev internal operations */
417static const struct v4l2_subdev_internal_ops ipipe_v4l2_internal_ops = {
418 .open = ipipe_init_formats,
419};
420
421/* -----------------------------------------------------------------------------
422 * Media entity operations
423 */
424
425/*
426 * ipipe_link_setup - Setup IPIPE connections
427 * @entity: IPIPE media entity
428 * @local: Pad at the local end of the link
429 * @remote: Pad at the remote end of the link
430 * @flags: Link flags
431 *
432 * return -EINVAL or zero on success
433 */
434static int ipipe_link_setup(struct media_entity *entity,
435 const struct media_pad *local,
436 const struct media_pad *remote, u32 flags)
437{
438 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
439 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
440 struct iss_device *iss = to_iss_device(ipipe);
441
442 switch (local->index | media_entity_type(remote->entity)) {
443 case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
444 /* Read from IPIPEIF. */
445 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
446 ipipe->input = IPIPE_INPUT_NONE;
447 break;
448 }
449
450 if (ipipe->input != IPIPE_INPUT_NONE)
451 return -EBUSY;
452
453 if (remote->entity == &iss->ipipeif.subdev.entity)
454 ipipe->input = IPIPE_INPUT_IPIPEIF;
455
456 break;
457
458 case IPIPE_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
459 /* Send to RESIZER */
460 if (flags & MEDIA_LNK_FL_ENABLED) {
461 if (ipipe->output & ~IPIPE_OUTPUT_VP)
462 return -EBUSY;
463 ipipe->output |= IPIPE_OUTPUT_VP;
464 } else {
465 ipipe->output &= ~IPIPE_OUTPUT_VP;
466 }
467 break;
468
469 default:
470 return -EINVAL;
471 }
472
473 return 0;
474}
475
476/* media operations */
477static const struct media_entity_operations ipipe_media_ops = {
478 .link_setup = ipipe_link_setup,
479 .link_validate = v4l2_subdev_link_validate,
480};
481
482/*
483 * ipipe_init_entities - Initialize V4L2 subdev and media entity
484 * @ipipe: ISS ISP IPIPE module
485 *
486 * Return 0 on success and a negative error code on failure.
487 */
488static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
489{
490 struct v4l2_subdev *sd = &ipipe->subdev;
491 struct media_pad *pads = ipipe->pads;
492 struct media_entity *me = &sd->entity;
493 int ret;
494
495 ipipe->input = IPIPE_INPUT_NONE;
496
497 v4l2_subdev_init(sd, &ipipe_v4l2_ops);
498 sd->internal_ops = &ipipe_v4l2_internal_ops;
499 strlcpy(sd->name, "OMAP4 ISS ISP IPIPE", sizeof(sd->name));
500 sd->grp_id = 1 << 16; /* group ID for iss subdevs */
501 v4l2_set_subdevdata(sd, ipipe);
502 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
503
504 pads[IPIPE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
505 pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
506
507 me->ops = &ipipe_media_ops;
508 ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
509 if (ret < 0)
510 return ret;
511
512 ipipe_init_formats(sd, NULL);
513
514 return 0;
515}
516
517void omap4iss_ipipe_unregister_entities(struct iss_ipipe_device *ipipe)
518{
519 media_entity_cleanup(&ipipe->subdev.entity);
520
521 v4l2_device_unregister_subdev(&ipipe->subdev);
522}
523
524int omap4iss_ipipe_register_entities(struct iss_ipipe_device *ipipe,
525 struct v4l2_device *vdev)
526{
527 int ret;
528
529 /* Register the subdev and video node. */
530 ret = v4l2_device_register_subdev(vdev, &ipipe->subdev);
531 if (ret < 0)
532 goto error;
533
534 return 0;
535
536error:
537 omap4iss_ipipe_unregister_entities(ipipe);
538 return ret;
539}
540
541/* -----------------------------------------------------------------------------
542 * ISP IPIPE initialisation and cleanup
543 */
544
545/*
546 * omap4iss_ipipe_init - IPIPE module initialization.
547 * @iss: Device pointer specific to the OMAP4 ISS.
548 *
549 * TODO: Get the initialisation values from platform data.
550 *
551 * Return 0 on success or a negative error code otherwise.
552 */
553int omap4iss_ipipe_init(struct iss_device *iss)
554{
555 struct iss_ipipe_device *ipipe = &iss->ipipe;
556
557 ipipe->state = ISS_PIPELINE_STREAM_STOPPED;
558 init_waitqueue_head(&ipipe->wait);
559
560 return ipipe_init_entities(ipipe);
561}
562
563/*
564 * omap4iss_ipipe_cleanup - IPIPE module cleanup.
565 * @iss: Device pointer specific to the OMAP4 ISS.
566 */
567void omap4iss_ipipe_cleanup(struct iss_device *iss)
568{
569 /* FIXME: are you sure there's nothing to do? */
570}
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.h b/drivers/staging/media/omap4iss/iss_ipipe.h
new file mode 100644
index 000000000000..c22d9041f2a5
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_ipipe.h
@@ -0,0 +1,67 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - ISP IPIPE module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef OMAP4_ISS_IPIPE_H
15#define OMAP4_ISS_IPIPE_H
16
17#include "iss_video.h"
18
19enum ipipe_input_entity {
20 IPIPE_INPUT_NONE,
21 IPIPE_INPUT_IPIPEIF,
22};
23
24#define IPIPE_OUTPUT_VP (1 << 0)
25
26/* Sink and source IPIPE pads */
27#define IPIPE_PAD_SINK 0
28#define IPIPE_PAD_SOURCE_VP 1
29#define IPIPE_PADS_NUM 2
30
31/*
32 * struct iss_ipipe_device - Structure for the IPIPE module to store its own
33 * information
34 * @subdev: V4L2 subdevice
35 * @pads: Sink and source media entity pads
36 * @formats: Active video formats
37 * @input: Active input
38 * @output: Active outputs
39 * @error: A hardware error occurred during capture
40 * @state: Streaming state
41 * @wait: Wait queue used to stop the module
42 * @stopping: Stopping state
43 */
44struct iss_ipipe_device {
45 struct v4l2_subdev subdev;
46 struct media_pad pads[IPIPE_PADS_NUM];
47 struct v4l2_mbus_framefmt formats[IPIPE_PADS_NUM];
48
49 enum ipipe_input_entity input;
50 unsigned int output;
51 unsigned int error;
52
53 enum iss_pipeline_stream_state state;
54 wait_queue_head_t wait;
55 atomic_t stopping;
56};
57
58struct iss_device;
59
60int omap4iss_ipipe_register_entities(struct iss_ipipe_device *ipipe,
61 struct v4l2_device *vdev);
62void omap4iss_ipipe_unregister_entities(struct iss_ipipe_device *ipipe);
63
64int omap4iss_ipipe_init(struct iss_device *iss);
65void omap4iss_ipipe_cleanup(struct iss_device *iss);
66
67#endif /* OMAP4_ISS_IPIPE_H */
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
new file mode 100644
index 000000000000..7bc145762499
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -0,0 +1,849 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - ISP IPIPEIF module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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/module.h>
15#include <linux/uaccess.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/dma-mapping.h>
19#include <linux/mm.h>
20#include <linux/sched.h>
21
22#include "iss.h"
23#include "iss_regs.h"
24#include "iss_ipipeif.h"
25
26static const unsigned int ipipeif_fmts[] = {
27 V4L2_MBUS_FMT_SGRBG10_1X10,
28 V4L2_MBUS_FMT_SRGGB10_1X10,
29 V4L2_MBUS_FMT_SBGGR10_1X10,
30 V4L2_MBUS_FMT_SGBRG10_1X10,
31 V4L2_MBUS_FMT_UYVY8_1X16,
32 V4L2_MBUS_FMT_YUYV8_1X16,
33};
34
35/*
36 * ipipeif_print_status - Print current IPIPEIF Module register values.
37 * @ipipeif: Pointer to ISS ISP IPIPEIF device.
38 *
39 * Also prints other debug information stored in the IPIPEIF module.
40 */
41#define IPIPEIF_PRINT_REGISTER(iss, name)\
42 dev_dbg(iss->dev, "###IPIPEIF " #name "=0x%08x\n", \
43 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_##name))
44
45#define ISIF_PRINT_REGISTER(iss, name)\
46 dev_dbg(iss->dev, "###ISIF " #name "=0x%08x\n", \
47 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_##name))
48
49#define ISP5_PRINT_REGISTER(iss, name)\
50 dev_dbg(iss->dev, "###ISP5 " #name "=0x%08x\n", \
51 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_##name))
52
53static void ipipeif_print_status(struct iss_ipipeif_device *ipipeif)
54{
55 struct iss_device *iss = to_iss_device(ipipeif);
56
57 dev_dbg(iss->dev, "-------------IPIPEIF Register dump-------------\n");
58
59 IPIPEIF_PRINT_REGISTER(iss, CFG1);
60 IPIPEIF_PRINT_REGISTER(iss, CFG2);
61
62 ISIF_PRINT_REGISTER(iss, SYNCEN);
63 ISIF_PRINT_REGISTER(iss, CADU);
64 ISIF_PRINT_REGISTER(iss, CADL);
65 ISIF_PRINT_REGISTER(iss, MODESET);
66 ISIF_PRINT_REGISTER(iss, CCOLP);
67 ISIF_PRINT_REGISTER(iss, SPH);
68 ISIF_PRINT_REGISTER(iss, LNH);
69 ISIF_PRINT_REGISTER(iss, LNV);
70 ISIF_PRINT_REGISTER(iss, VDINT(0));
71 ISIF_PRINT_REGISTER(iss, HSIZE);
72
73 ISP5_PRINT_REGISTER(iss, SYSCONFIG);
74 ISP5_PRINT_REGISTER(iss, CTRL);
75 ISP5_PRINT_REGISTER(iss, IRQSTATUS(0));
76 ISP5_PRINT_REGISTER(iss, IRQENABLE_SET(0));
77 ISP5_PRINT_REGISTER(iss, IRQENABLE_CLR(0));
78
79 dev_dbg(iss->dev, "-----------------------------------------------\n");
80}
81
82static void ipipeif_write_enable(struct iss_ipipeif_device *ipipeif, u8 enable)
83{
84 struct iss_device *iss = to_iss_device(ipipeif);
85
86 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_SYNCEN,
87 ISIF_SYNCEN_DWEN, enable ? ISIF_SYNCEN_DWEN : 0);
88}
89
90/*
91 * ipipeif_enable - Enable/Disable IPIPEIF.
92 * @enable: enable flag
93 *
94 */
95static void ipipeif_enable(struct iss_ipipeif_device *ipipeif, u8 enable)
96{
97 struct iss_device *iss = to_iss_device(ipipeif);
98
99 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_SYNCEN,
100 ISIF_SYNCEN_SYEN, enable ? ISIF_SYNCEN_SYEN : 0);
101}
102
103/* -----------------------------------------------------------------------------
104 * Format- and pipeline-related configuration helpers
105 */
106
107/*
108 * ipipeif_set_outaddr - Set memory address to save output image
109 * @ipipeif: Pointer to ISP IPIPEIF device.
110 * @addr: 32-bit memory address aligned on 32 byte boundary.
111 *
112 * Sets the memory address where the output will be saved.
113 */
114static void ipipeif_set_outaddr(struct iss_ipipeif_device *ipipeif, u32 addr)
115{
116 struct iss_device *iss = to_iss_device(ipipeif);
117
118 /* Save address splitted in Base Address H & L */
119 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_CADU,
120 (addr >> (16 + 5)) & ISIF_CADU_MASK);
121 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_CADL,
122 (addr >> 5) & ISIF_CADL_MASK);
123}
124
125static void ipipeif_configure(struct iss_ipipeif_device *ipipeif)
126{
127 struct iss_device *iss = to_iss_device(ipipeif);
128 const struct iss_format_info *info;
129 struct v4l2_mbus_framefmt *format;
130 u32 isif_ccolp = 0;
131
132 omap4iss_configure_bridge(iss, ipipeif->input);
133
134 /* IPIPEIF_PAD_SINK */
135 format = &ipipeif->formats[IPIPEIF_PAD_SINK];
136
137 /* IPIPEIF with YUV422 input from ISIF */
138 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_CFG1,
139 IPIPEIF_CFG1_INPSRC1_MASK | IPIPEIF_CFG1_INPSRC2_MASK);
140
141 /* Select ISIF/IPIPEIF input format */
142 switch (format->code) {
143 case V4L2_MBUS_FMT_UYVY8_1X16:
144 case V4L2_MBUS_FMT_YUYV8_1X16:
145 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_MODESET,
146 ISIF_MODESET_CCDMD | ISIF_MODESET_INPMOD_MASK |
147 ISIF_MODESET_CCDW_MASK,
148 ISIF_MODESET_INPMOD_YCBCR16);
149
150 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_CFG2,
151 IPIPEIF_CFG2_YUV8, IPIPEIF_CFG2_YUV16);
152
153 break;
154 case V4L2_MBUS_FMT_SGRBG10_1X10:
155 isif_ccolp = ISIF_CCOLP_CP0_F0_GR |
156 ISIF_CCOLP_CP1_F0_R |
157 ISIF_CCOLP_CP2_F0_B |
158 ISIF_CCOLP_CP3_F0_GB;
159 goto cont_raw;
160 case V4L2_MBUS_FMT_SRGGB10_1X10:
161 isif_ccolp = ISIF_CCOLP_CP0_F0_R |
162 ISIF_CCOLP_CP1_F0_GR |
163 ISIF_CCOLP_CP2_F0_GB |
164 ISIF_CCOLP_CP3_F0_B;
165 goto cont_raw;
166 case V4L2_MBUS_FMT_SBGGR10_1X10:
167 isif_ccolp = ISIF_CCOLP_CP0_F0_B |
168 ISIF_CCOLP_CP1_F0_GB |
169 ISIF_CCOLP_CP2_F0_GR |
170 ISIF_CCOLP_CP3_F0_R;
171 goto cont_raw;
172 case V4L2_MBUS_FMT_SGBRG10_1X10:
173 isif_ccolp = ISIF_CCOLP_CP0_F0_GB |
174 ISIF_CCOLP_CP1_F0_B |
175 ISIF_CCOLP_CP2_F0_R |
176 ISIF_CCOLP_CP3_F0_GR;
177cont_raw:
178 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_IPIPEIF, IPIPEIF_CFG2,
179 IPIPEIF_CFG2_YUV16);
180
181 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_MODESET,
182 ISIF_MODESET_CCDMD | ISIF_MODESET_INPMOD_MASK |
183 ISIF_MODESET_CCDW_MASK, ISIF_MODESET_INPMOD_RAW |
184 ISIF_MODESET_CCDW_2BIT);
185
186 info = omap4iss_video_format_info(format->code);
187 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_CGAMMAWD,
188 ISIF_CGAMMAWD_GWDI_MASK,
189 ISIF_CGAMMAWD_GWDI(info->bpp));
190
191 /* Set RAW Bayer pattern */
192 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_CCOLP,
193 isif_ccolp);
194 break;
195 }
196
197 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_SPH, 0 & ISIF_SPH_MASK);
198 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_LNH,
199 (format->width - 1) & ISIF_LNH_MASK);
200 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_LNV,
201 (format->height - 1) & ISIF_LNV_MASK);
202
203 /* Generate ISIF0 on the last line of the image */
204 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_VDINT(0),
205 format->height - 1);
206
207 /* IPIPEIF_PAD_SOURCE_ISIF_SF */
208 format = &ipipeif->formats[IPIPEIF_PAD_SOURCE_ISIF_SF];
209
210 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_ISIF, ISIF_HSIZE,
211 (ipipeif->video_out.bpl_value >> 5) &
212 ISIF_HSIZE_HSIZE_MASK);
213
214 /* IPIPEIF_PAD_SOURCE_VP */
215 /* Do nothing? */
216}
217
218/* -----------------------------------------------------------------------------
219 * Interrupt handling
220 */
221
222static void ipipeif_isr_buffer(struct iss_ipipeif_device *ipipeif)
223{
224 struct iss_buffer *buffer;
225
226 /* The ISIF generates VD0 interrupts even when writes are disabled.
227 * deal with it anyway). Disabling the ISIF when no buffer is available
228 * is thus not be enough, we need to handle the situation explicitly.
229 */
230 if (list_empty(&ipipeif->video_out.dmaqueue))
231 return;
232
233 ipipeif_write_enable(ipipeif, 0);
234
235 buffer = omap4iss_video_buffer_next(&ipipeif->video_out);
236 if (buffer == NULL)
237 return;
238
239 ipipeif_set_outaddr(ipipeif, buffer->iss_addr);
240
241 ipipeif_write_enable(ipipeif, 1);
242}
243
244/*
245 * ipipeif_isif0_isr - Handle ISIF0 event
246 * @ipipeif: Pointer to ISP IPIPEIF device.
247 *
248 * Executes LSC deferred enablement before next frame starts.
249 */
250static void ipipeif_isif0_isr(struct iss_ipipeif_device *ipipeif)
251{
252 struct iss_pipeline *pipe =
253 to_iss_pipeline(&ipipeif->subdev.entity);
254 if (pipe->do_propagation)
255 atomic_inc(&pipe->frame_number);
256
257 if (ipipeif->output & IPIPEIF_OUTPUT_MEMORY)
258 ipipeif_isr_buffer(ipipeif);
259}
260
261/*
262 * omap4iss_ipipeif_isr - Configure ipipeif during interframe time.
263 * @ipipeif: Pointer to ISP IPIPEIF device.
264 * @events: IPIPEIF events
265 */
266void omap4iss_ipipeif_isr(struct iss_ipipeif_device *ipipeif, u32 events)
267{
268 if (omap4iss_module_sync_is_stopping(&ipipeif->wait,
269 &ipipeif->stopping))
270 return;
271
272 if (events & ISP5_IRQ_ISIF_INT(0))
273 ipipeif_isif0_isr(ipipeif);
274}
275
276/* -----------------------------------------------------------------------------
277 * ISP video operations
278 */
279
280static int ipipeif_video_queue(struct iss_video *video,
281 struct iss_buffer *buffer)
282{
283 struct iss_ipipeif_device *ipipeif = container_of(video,
284 struct iss_ipipeif_device, video_out);
285
286 if (!(ipipeif->output & IPIPEIF_OUTPUT_MEMORY))
287 return -ENODEV;
288
289 ipipeif_set_outaddr(ipipeif, buffer->iss_addr);
290
291 /*
292 * If streaming was enabled before there was a buffer queued
293 * or underrun happened in the ISR, the hardware was not enabled
294 * and DMA queue flag ISS_VIDEO_DMAQUEUE_UNDERRUN is still set.
295 * Enable it now.
296 */
297 if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
298 if (ipipeif->output & IPIPEIF_OUTPUT_MEMORY)
299 ipipeif_write_enable(ipipeif, 1);
300 ipipeif_enable(ipipeif, 1);
301 iss_video_dmaqueue_flags_clr(video);
302 }
303
304 return 0;
305}
306
307static const struct iss_video_operations ipipeif_video_ops = {
308 .queue = ipipeif_video_queue,
309};
310
311/* -----------------------------------------------------------------------------
312 * V4L2 subdev operations
313 */
314
315#define IPIPEIF_DRV_SUBCLK_MASK (OMAP4_ISS_ISP_SUBCLK_IPIPEIF |\
316 OMAP4_ISS_ISP_SUBCLK_ISIF)
317/*
318 * ipipeif_set_stream - Enable/Disable streaming on the IPIPEIF module
319 * @sd: ISP IPIPEIF V4L2 subdevice
320 * @enable: Enable/disable stream
321 */
322static int ipipeif_set_stream(struct v4l2_subdev *sd, int enable)
323{
324 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
325 struct iss_device *iss = to_iss_device(ipipeif);
326 struct iss_video *video_out = &ipipeif->video_out;
327 int ret = 0;
328
329 if (ipipeif->state == ISS_PIPELINE_STREAM_STOPPED) {
330 if (enable == ISS_PIPELINE_STREAM_STOPPED)
331 return 0;
332
333 omap4iss_isp_subclk_enable(iss, IPIPEIF_DRV_SUBCLK_MASK);
334 }
335
336 switch (enable) {
337 case ISS_PIPELINE_STREAM_CONTINUOUS:
338
339 ipipeif_configure(ipipeif);
340 ipipeif_print_status(ipipeif);
341
342 /*
343 * When outputting to memory with no buffer available, let the
344 * buffer queue handler start the hardware. A DMA queue flag
345 * ISS_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
346 * a buffer available.
347 */
348 if (ipipeif->output & IPIPEIF_OUTPUT_MEMORY &&
349 !(video_out->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_QUEUED))
350 break;
351
352 atomic_set(&ipipeif->stopping, 0);
353 if (ipipeif->output & IPIPEIF_OUTPUT_MEMORY)
354 ipipeif_write_enable(ipipeif, 1);
355 ipipeif_enable(ipipeif, 1);
356 iss_video_dmaqueue_flags_clr(video_out);
357 break;
358
359 case ISS_PIPELINE_STREAM_STOPPED:
360 if (ipipeif->state == ISS_PIPELINE_STREAM_STOPPED)
361 return 0;
362 if (omap4iss_module_sync_idle(&sd->entity, &ipipeif->wait,
363 &ipipeif->stopping))
364 ret = -ETIMEDOUT;
365
366 if (ipipeif->output & IPIPEIF_OUTPUT_MEMORY)
367 ipipeif_write_enable(ipipeif, 0);
368 ipipeif_enable(ipipeif, 0);
369 omap4iss_isp_subclk_disable(iss, IPIPEIF_DRV_SUBCLK_MASK);
370 iss_video_dmaqueue_flags_clr(video_out);
371 break;
372 }
373
374 ipipeif->state = enable;
375 return ret;
376}
377
378static struct v4l2_mbus_framefmt *
379__ipipeif_get_format(struct iss_ipipeif_device *ipipeif,
380 struct v4l2_subdev_fh *fh, unsigned int pad,
381 enum v4l2_subdev_format_whence which)
382{
383 if (which == V4L2_SUBDEV_FORMAT_TRY)
384 return v4l2_subdev_get_try_format(fh, pad);
385 else
386 return &ipipeif->formats[pad];
387}
388
389/*
390 * ipipeif_try_format - Try video format on a pad
391 * @ipipeif: ISS IPIPEIF device
392 * @fh : V4L2 subdev file handle
393 * @pad: Pad number
394 * @fmt: Format
395 */
396static void
397ipipeif_try_format(struct iss_ipipeif_device *ipipeif,
398 struct v4l2_subdev_fh *fh, unsigned int pad,
399 struct v4l2_mbus_framefmt *fmt,
400 enum v4l2_subdev_format_whence which)
401{
402 struct v4l2_mbus_framefmt *format;
403 unsigned int width = fmt->width;
404 unsigned int height = fmt->height;
405 unsigned int i;
406
407 switch (pad) {
408 case IPIPEIF_PAD_SINK:
409 /* TODO: If the IPIPEIF output formatter pad is connected
410 * directly to the resizer, only YUV formats can be used.
411 */
412 for (i = 0; i < ARRAY_SIZE(ipipeif_fmts); i++) {
413 if (fmt->code == ipipeif_fmts[i])
414 break;
415 }
416
417 /* If not found, use SGRBG10 as default */
418 if (i >= ARRAY_SIZE(ipipeif_fmts))
419 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
420
421 /* Clamp the input size. */
422 fmt->width = clamp_t(u32, width, 1, 8192);
423 fmt->height = clamp_t(u32, height, 1, 8192);
424 break;
425
426 case IPIPEIF_PAD_SOURCE_ISIF_SF:
427 format = __ipipeif_get_format(ipipeif, fh, IPIPEIF_PAD_SINK,
428 which);
429 memcpy(fmt, format, sizeof(*fmt));
430
431 /* The data formatter truncates the number of horizontal output
432 * pixels to a multiple of 16. To avoid clipping data, allow
433 * callers to request an output size bigger than the input size
434 * up to the nearest multiple of 16.
435 */
436 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
437 fmt->width &= ~15;
438 fmt->height = clamp_t(u32, height, 32, fmt->height);
439 break;
440
441 case IPIPEIF_PAD_SOURCE_VP:
442 format = __ipipeif_get_format(ipipeif, fh, IPIPEIF_PAD_SINK,
443 which);
444 memcpy(fmt, format, sizeof(*fmt));
445
446 fmt->width = clamp_t(u32, width, 32, fmt->width);
447 fmt->height = clamp_t(u32, height, 32, fmt->height);
448 break;
449 }
450
451 /* Data is written to memory unpacked, each 10-bit or 12-bit pixel is
452 * stored on 2 bytes.
453 */
454 fmt->colorspace = V4L2_COLORSPACE_SRGB;
455 fmt->field = V4L2_FIELD_NONE;
456}
457
458/*
459 * ipipeif_enum_mbus_code - Handle pixel format enumeration
460 * @sd : pointer to v4l2 subdev structure
461 * @fh : V4L2 subdev file handle
462 * @code : pointer to v4l2_subdev_mbus_code_enum structure
463 * return -EINVAL or zero on success
464 */
465static int ipipeif_enum_mbus_code(struct v4l2_subdev *sd,
466 struct v4l2_subdev_fh *fh,
467 struct v4l2_subdev_mbus_code_enum *code)
468{
469 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
470 struct v4l2_mbus_framefmt *format;
471
472 switch (code->pad) {
473 case IPIPEIF_PAD_SINK:
474 if (code->index >= ARRAY_SIZE(ipipeif_fmts))
475 return -EINVAL;
476
477 code->code = ipipeif_fmts[code->index];
478 break;
479
480 case IPIPEIF_PAD_SOURCE_ISIF_SF:
481 case IPIPEIF_PAD_SOURCE_VP:
482 /* No format conversion inside IPIPEIF */
483 if (code->index != 0)
484 return -EINVAL;
485
486 format = __ipipeif_get_format(ipipeif, fh, IPIPEIF_PAD_SINK,
487 V4L2_SUBDEV_FORMAT_TRY);
488
489 code->code = format->code;
490 break;
491
492 default:
493 return -EINVAL;
494 }
495
496 return 0;
497}
498
499static int ipipeif_enum_frame_size(struct v4l2_subdev *sd,
500 struct v4l2_subdev_fh *fh,
501 struct v4l2_subdev_frame_size_enum *fse)
502{
503 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
504 struct v4l2_mbus_framefmt format;
505
506 if (fse->index != 0)
507 return -EINVAL;
508
509 format.code = fse->code;
510 format.width = 1;
511 format.height = 1;
512 ipipeif_try_format(ipipeif, fh, fse->pad, &format,
513 V4L2_SUBDEV_FORMAT_TRY);
514 fse->min_width = format.width;
515 fse->min_height = format.height;
516
517 if (format.code != fse->code)
518 return -EINVAL;
519
520 format.code = fse->code;
521 format.width = -1;
522 format.height = -1;
523 ipipeif_try_format(ipipeif, fh, fse->pad, &format,
524 V4L2_SUBDEV_FORMAT_TRY);
525 fse->max_width = format.width;
526 fse->max_height = format.height;
527
528 return 0;
529}
530
531/*
532 * ipipeif_get_format - Retrieve the video format on a pad
533 * @sd : ISP IPIPEIF V4L2 subdevice
534 * @fh : V4L2 subdev file handle
535 * @fmt: Format
536 *
537 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
538 * to the format type.
539 */
540static int ipipeif_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
541 struct v4l2_subdev_format *fmt)
542{
543 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
544 struct v4l2_mbus_framefmt *format;
545
546 format = __ipipeif_get_format(ipipeif, fh, fmt->pad, fmt->which);
547 if (format == NULL)
548 return -EINVAL;
549
550 fmt->format = *format;
551 return 0;
552}
553
554/*
555 * ipipeif_set_format - Set the video format on a pad
556 * @sd : ISP IPIPEIF V4L2 subdevice
557 * @fh : V4L2 subdev file handle
558 * @fmt: Format
559 *
560 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
561 * to the format type.
562 */
563static int ipipeif_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
564 struct v4l2_subdev_format *fmt)
565{
566 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
567 struct v4l2_mbus_framefmt *format;
568
569 format = __ipipeif_get_format(ipipeif, fh, fmt->pad, fmt->which);
570 if (format == NULL)
571 return -EINVAL;
572
573 ipipeif_try_format(ipipeif, fh, fmt->pad, &fmt->format, fmt->which);
574 *format = fmt->format;
575
576 /* Propagate the format from sink to source */
577 if (fmt->pad == IPIPEIF_PAD_SINK) {
578 format = __ipipeif_get_format(ipipeif, fh,
579 IPIPEIF_PAD_SOURCE_ISIF_SF,
580 fmt->which);
581 *format = fmt->format;
582 ipipeif_try_format(ipipeif, fh, IPIPEIF_PAD_SOURCE_ISIF_SF,
583 format, fmt->which);
584
585 format = __ipipeif_get_format(ipipeif, fh,
586 IPIPEIF_PAD_SOURCE_VP,
587 fmt->which);
588 *format = fmt->format;
589 ipipeif_try_format(ipipeif, fh, IPIPEIF_PAD_SOURCE_VP, format,
590 fmt->which);
591 }
592
593 return 0;
594}
595
596static int ipipeif_link_validate(struct v4l2_subdev *sd,
597 struct media_link *link,
598 struct v4l2_subdev_format *source_fmt,
599 struct v4l2_subdev_format *sink_fmt)
600{
601 /* Check if the two ends match */
602 if (source_fmt->format.width != sink_fmt->format.width ||
603 source_fmt->format.height != sink_fmt->format.height)
604 return -EPIPE;
605
606 if (source_fmt->format.code != sink_fmt->format.code)
607 return -EPIPE;
608
609 return 0;
610}
611
612/*
613 * ipipeif_init_formats - Initialize formats on all pads
614 * @sd: ISP IPIPEIF V4L2 subdevice
615 * @fh: V4L2 subdev file handle
616 *
617 * Initialize all pad formats with default values. If fh is not NULL, try
618 * formats are initialized on the file handle. Otherwise active formats are
619 * initialized on the device.
620 */
621static int ipipeif_init_formats(struct v4l2_subdev *sd,
622 struct v4l2_subdev_fh *fh)
623{
624 struct v4l2_subdev_format format;
625
626 memset(&format, 0, sizeof(format));
627 format.pad = IPIPEIF_PAD_SINK;
628 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
629 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
630 format.format.width = 4096;
631 format.format.height = 4096;
632 ipipeif_set_format(sd, fh, &format);
633
634 return 0;
635}
636
637/* V4L2 subdev video operations */
638static const struct v4l2_subdev_video_ops ipipeif_v4l2_video_ops = {
639 .s_stream = ipipeif_set_stream,
640};
641
642/* V4L2 subdev pad operations */
643static const struct v4l2_subdev_pad_ops ipipeif_v4l2_pad_ops = {
644 .enum_mbus_code = ipipeif_enum_mbus_code,
645 .enum_frame_size = ipipeif_enum_frame_size,
646 .get_fmt = ipipeif_get_format,
647 .set_fmt = ipipeif_set_format,
648 .link_validate = ipipeif_link_validate,
649};
650
651/* V4L2 subdev operations */
652static const struct v4l2_subdev_ops ipipeif_v4l2_ops = {
653 .video = &ipipeif_v4l2_video_ops,
654 .pad = &ipipeif_v4l2_pad_ops,
655};
656
657/* V4L2 subdev internal operations */
658static const struct v4l2_subdev_internal_ops ipipeif_v4l2_internal_ops = {
659 .open = ipipeif_init_formats,
660};
661
662/* -----------------------------------------------------------------------------
663 * Media entity operations
664 */
665
666/*
667 * ipipeif_link_setup - Setup IPIPEIF connections
668 * @entity: IPIPEIF media entity
669 * @local: Pad at the local end of the link
670 * @remote: Pad at the remote end of the link
671 * @flags: Link flags
672 *
673 * return -EINVAL or zero on success
674 */
675static int ipipeif_link_setup(struct media_entity *entity,
676 const struct media_pad *local,
677 const struct media_pad *remote, u32 flags)
678{
679 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
680 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
681 struct iss_device *iss = to_iss_device(ipipeif);
682
683 switch (local->index | media_entity_type(remote->entity)) {
684 case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
685 /* Read from the sensor CSI2a or CSI2b. */
686 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
687 ipipeif->input = IPIPEIF_INPUT_NONE;
688 break;
689 }
690
691 if (ipipeif->input != IPIPEIF_INPUT_NONE)
692 return -EBUSY;
693
694 if (remote->entity == &iss->csi2a.subdev.entity)
695 ipipeif->input = IPIPEIF_INPUT_CSI2A;
696 else if (remote->entity == &iss->csi2b.subdev.entity)
697 ipipeif->input = IPIPEIF_INPUT_CSI2B;
698
699 break;
700
701 case IPIPEIF_PAD_SOURCE_ISIF_SF | MEDIA_ENT_T_DEVNODE:
702 /* Write to memory */
703 if (flags & MEDIA_LNK_FL_ENABLED) {
704 if (ipipeif->output & ~IPIPEIF_OUTPUT_MEMORY)
705 return -EBUSY;
706 ipipeif->output |= IPIPEIF_OUTPUT_MEMORY;
707 } else {
708 ipipeif->output &= ~IPIPEIF_OUTPUT_MEMORY;
709 }
710 break;
711
712 case IPIPEIF_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
713 /* Send to IPIPE/RESIZER */
714 if (flags & MEDIA_LNK_FL_ENABLED) {
715 if (ipipeif->output & ~IPIPEIF_OUTPUT_VP)
716 return -EBUSY;
717 ipipeif->output |= IPIPEIF_OUTPUT_VP;
718 } else {
719 ipipeif->output &= ~IPIPEIF_OUTPUT_VP;
720 }
721 break;
722
723 default:
724 return -EINVAL;
725 }
726
727 return 0;
728}
729
730/* media operations */
731static const struct media_entity_operations ipipeif_media_ops = {
732 .link_setup = ipipeif_link_setup,
733 .link_validate = v4l2_subdev_link_validate,
734};
735
736/*
737 * ipipeif_init_entities - Initialize V4L2 subdev and media entity
738 * @ipipeif: ISS ISP IPIPEIF module
739 *
740 * Return 0 on success and a negative error code on failure.
741 */
742static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
743{
744 struct v4l2_subdev *sd = &ipipeif->subdev;
745 struct media_pad *pads = ipipeif->pads;
746 struct media_entity *me = &sd->entity;
747 int ret;
748
749 ipipeif->input = IPIPEIF_INPUT_NONE;
750
751 v4l2_subdev_init(sd, &ipipeif_v4l2_ops);
752 sd->internal_ops = &ipipeif_v4l2_internal_ops;
753 strlcpy(sd->name, "OMAP4 ISS ISP IPIPEIF", sizeof(sd->name));
754 sd->grp_id = 1 << 16; /* group ID for iss subdevs */
755 v4l2_set_subdevdata(sd, ipipeif);
756 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
757
758 pads[IPIPEIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
759 pads[IPIPEIF_PAD_SOURCE_ISIF_SF].flags = MEDIA_PAD_FL_SOURCE;
760 pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
761
762 me->ops = &ipipeif_media_ops;
763 ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0);
764 if (ret < 0)
765 return ret;
766
767 ipipeif_init_formats(sd, NULL);
768
769 ipipeif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
770 ipipeif->video_out.ops = &ipipeif_video_ops;
771 ipipeif->video_out.iss = to_iss_device(ipipeif);
772 ipipeif->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
773 ipipeif->video_out.bpl_alignment = 32;
774 ipipeif->video_out.bpl_zero_padding = 1;
775 ipipeif->video_out.bpl_max = 0x1ffe0;
776
777 ret = omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF");
778 if (ret < 0)
779 return ret;
780
781 /* Connect the IPIPEIF subdev to the video node. */
782 ret = media_entity_create_link(&ipipeif->subdev.entity,
783 IPIPEIF_PAD_SOURCE_ISIF_SF,
784 &ipipeif->video_out.video.entity, 0, 0);
785 if (ret < 0)
786 return ret;
787
788 return 0;
789}
790
791void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif)
792{
793 media_entity_cleanup(&ipipeif->subdev.entity);
794
795 v4l2_device_unregister_subdev(&ipipeif->subdev);
796 omap4iss_video_unregister(&ipipeif->video_out);
797}
798
799int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif,
800 struct v4l2_device *vdev)
801{
802 int ret;
803
804 /* Register the subdev and video node. */
805 ret = v4l2_device_register_subdev(vdev, &ipipeif->subdev);
806 if (ret < 0)
807 goto error;
808
809 ret = omap4iss_video_register(&ipipeif->video_out, vdev);
810 if (ret < 0)
811 goto error;
812
813 return 0;
814
815error:
816 omap4iss_ipipeif_unregister_entities(ipipeif);
817 return ret;
818}
819
820/* -----------------------------------------------------------------------------
821 * ISP IPIPEIF initialisation and cleanup
822 */
823
824/*
825 * omap4iss_ipipeif_init - IPIPEIF module initialization.
826 * @iss: Device pointer specific to the OMAP4 ISS.
827 *
828 * TODO: Get the initialisation values from platform data.
829 *
830 * Return 0 on success or a negative error code otherwise.
831 */
832int omap4iss_ipipeif_init(struct iss_device *iss)
833{
834 struct iss_ipipeif_device *ipipeif = &iss->ipipeif;
835
836 ipipeif->state = ISS_PIPELINE_STREAM_STOPPED;
837 init_waitqueue_head(&ipipeif->wait);
838
839 return ipipeif_init_entities(ipipeif);
840}
841
842/*
843 * omap4iss_ipipeif_cleanup - IPIPEIF module cleanup.
844 * @iss: Device pointer specific to the OMAP4 ISS.
845 */
846void omap4iss_ipipeif_cleanup(struct iss_device *iss)
847{
848 /* FIXME: are you sure there's nothing to do? */
849}
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.h b/drivers/staging/media/omap4iss/iss_ipipeif.h
new file mode 100644
index 000000000000..cbdccb982eee
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.h
@@ -0,0 +1,92 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - ISP IPIPEIF module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef OMAP4_ISS_IPIPEIF_H
15#define OMAP4_ISS_IPIPEIF_H
16
17#include "iss_video.h"
18
19enum ipipeif_input_entity {
20 IPIPEIF_INPUT_NONE,
21 IPIPEIF_INPUT_CSI2A,
22 IPIPEIF_INPUT_CSI2B
23};
24
25#define IPIPEIF_OUTPUT_MEMORY (1 << 0)
26#define IPIPEIF_OUTPUT_VP (1 << 1)
27
28/* Sink and source IPIPEIF pads */
29#define IPIPEIF_PAD_SINK 0
30#define IPIPEIF_PAD_SOURCE_ISIF_SF 1
31#define IPIPEIF_PAD_SOURCE_VP 2
32#define IPIPEIF_PADS_NUM 3
33
34/*
35 * struct iss_ipipeif_device - Structure for the IPIPEIF module to store its own
36 * information
37 * @subdev: V4L2 subdevice
38 * @pads: Sink and source media entity pads
39 * @formats: Active video formats
40 * @input: Active input
41 * @output: Active outputs
42 * @video_out: Output video node
43 * @error: A hardware error occurred during capture
44 * @alaw: A-law compression enabled (1) or disabled (0)
45 * @lpf: Low pass filter enabled (1) or disabled (0)
46 * @obclamp: Optical-black clamp enabled (1) or disabled (0)
47 * @fpc_en: Faulty pixels correction enabled (1) or disabled (0)
48 * @blcomp: Black level compensation configuration
49 * @clamp: Optical-black or digital clamp configuration
50 * @fpc: Faulty pixels correction configuration
51 * @lsc: Lens shading compensation configuration
52 * @update: Bitmask of controls to update during the next interrupt
53 * @shadow_update: Controls update in progress by userspace
54 * @syncif: Interface synchronization configuration
55 * @vpcfg: Video port configuration
56 * @underrun: A buffer underrun occurred and a new buffer has been queued
57 * @state: Streaming state
58 * @lock: Serializes shadow_update with interrupt handler
59 * @wait: Wait queue used to stop the module
60 * @stopping: Stopping state
61 * @ioctl_lock: Serializes ioctl calls and LSC requests freeing
62 */
63struct iss_ipipeif_device {
64 struct v4l2_subdev subdev;
65 struct media_pad pads[IPIPEIF_PADS_NUM];
66 struct v4l2_mbus_framefmt formats[IPIPEIF_PADS_NUM];
67
68 enum ipipeif_input_entity input;
69 unsigned int output;
70 struct iss_video video_out;
71 unsigned int error;
72
73 enum iss_pipeline_stream_state state;
74 wait_queue_head_t wait;
75 atomic_t stopping;
76};
77
78struct iss_device;
79
80int omap4iss_ipipeif_init(struct iss_device *iss);
81void omap4iss_ipipeif_cleanup(struct iss_device *iss);
82int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif,
83 struct v4l2_device *vdev);
84void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif);
85
86int omap4iss_ipipeif_busy(struct iss_ipipeif_device *ipipeif);
87void omap4iss_ipipeif_isr(struct iss_ipipeif_device *ipipeif, u32 events);
88void omap4iss_ipipeif_restore_context(struct iss_device *iss);
89void omap4iss_ipipeif_max_rate(struct iss_ipipeif_device *ipipeif,
90 unsigned int *max_rate);
91
92#endif /* OMAP4_ISS_IPIPEIF_H */
diff --git a/drivers/staging/media/omap4iss/iss_regs.h b/drivers/staging/media/omap4iss/iss_regs.h
new file mode 100644
index 000000000000..efd0291a86f7
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_regs.h
@@ -0,0 +1,901 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - Register defines
3 *
4 * Copyright (C) 2012 Texas Instruments.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef _OMAP4_ISS_REGS_H_
15#define _OMAP4_ISS_REGS_H_
16
17/* ISS */
18#define ISS_HL_REVISION 0x0
19
20#define ISS_HL_SYSCONFIG 0x10
21#define ISS_HL_SYSCONFIG_IDLEMODE_SHIFT 2
22#define ISS_HL_SYSCONFIG_IDLEMODE_FORCEIDLE 0x0
23#define ISS_HL_SYSCONFIG_IDLEMODE_NOIDLE 0x1
24#define ISS_HL_SYSCONFIG_IDLEMODE_SMARTIDLE 0x2
25#define ISS_HL_SYSCONFIG_SOFTRESET (1 << 0)
26
27#define ISS_HL_IRQSTATUS_RAW(i) (0x20 + (0x10 * (i)))
28#define ISS_HL_IRQSTATUS(i) (0x24 + (0x10 * (i)))
29#define ISS_HL_IRQENABLE_SET(i) (0x28 + (0x10 * (i)))
30#define ISS_HL_IRQENABLE_CLR(i) (0x2c + (0x10 * (i)))
31
32#define ISS_HL_IRQ_HS_VS (1 << 17)
33#define ISS_HL_IRQ_SIMCOP(i) (1 << (12 + (i)))
34#define ISS_HL_IRQ_BTE (1 << 11)
35#define ISS_HL_IRQ_CBUFF (1 << 10)
36#define ISS_HL_IRQ_CCP2(i) (1 << ((i) > 3 ? 16 : 14 + (i)))
37#define ISS_HL_IRQ_CSIB (1 << 5)
38#define ISS_HL_IRQ_CSIA (1 << 4)
39#define ISS_HL_IRQ_ISP(i) (1 << (i))
40
41#define ISS_CTRL 0x80
42#define ISS_CTRL_CLK_DIV_MASK (3 << 4)
43#define ISS_CTRL_INPUT_SEL_MASK (3 << 2)
44#define ISS_CTRL_INPUT_SEL_CSI2A (0 << 2)
45#define ISS_CTRL_INPUT_SEL_CSI2B (1 << 2)
46#define ISS_CTRL_SYNC_DETECT_VS_RAISING (3 << 0)
47
48#define ISS_CLKCTRL 0x84
49#define ISS_CLKCTRL_VPORT2_CLK (1 << 30)
50#define ISS_CLKCTRL_VPORT1_CLK (1 << 29)
51#define ISS_CLKCTRL_VPORT0_CLK (1 << 28)
52#define ISS_CLKCTRL_CCP2 (1 << 4)
53#define ISS_CLKCTRL_CSI2_B (1 << 3)
54#define ISS_CLKCTRL_CSI2_A (1 << 2)
55#define ISS_CLKCTRL_ISP (1 << 1)
56#define ISS_CLKCTRL_SIMCOP (1 << 0)
57
58#define ISS_CLKSTAT 0x88
59#define ISS_CLKSTAT_VPORT2_CLK (1 << 30)
60#define ISS_CLKSTAT_VPORT1_CLK (1 << 29)
61#define ISS_CLKSTAT_VPORT0_CLK (1 << 28)
62#define ISS_CLKSTAT_CCP2 (1 << 4)
63#define ISS_CLKSTAT_CSI2_B (1 << 3)
64#define ISS_CLKSTAT_CSI2_A (1 << 2)
65#define ISS_CLKSTAT_ISP (1 << 1)
66#define ISS_CLKSTAT_SIMCOP (1 << 0)
67
68#define ISS_PM_STATUS 0x8c
69#define ISS_PM_STATUS_CBUFF_PM_MASK (3 << 12)
70#define ISS_PM_STATUS_BTE_PM_MASK (3 << 10)
71#define ISS_PM_STATUS_SIMCOP_PM_MASK (3 << 8)
72#define ISS_PM_STATUS_ISP_PM_MASK (3 << 6)
73#define ISS_PM_STATUS_CCP2_PM_MASK (3 << 4)
74#define ISS_PM_STATUS_CSI2_B_PM_MASK (3 << 2)
75#define ISS_PM_STATUS_CSI2_A_PM_MASK (3 << 0)
76
77#define REGISTER0 0x0
78#define REGISTER0_HSCLOCKCONFIG (1 << 24)
79#define REGISTER0_THS_TERM_MASK (0xff << 8)
80#define REGISTER0_THS_TERM_SHIFT 8
81#define REGISTER0_THS_SETTLE_MASK (0xff << 0)
82#define REGISTER0_THS_SETTLE_SHIFT 0
83
84#define REGISTER1 0x4
85#define REGISTER1_RESET_DONE_CTRLCLK (1 << 29)
86#define REGISTER1_CLOCK_MISS_DETECTOR_STATUS (1 << 25)
87#define REGISTER1_TCLK_TERM_MASK (0x3f << 18)
88#define REGISTER1_TCLK_TERM_SHIFT 18
89#define REGISTER1_DPHY_HS_SYNC_PATTERN_SHIFT 10
90#define REGISTER1_CTRLCLK_DIV_FACTOR_MASK (0x3 << 8)
91#define REGISTER1_CTRLCLK_DIV_FACTOR_SHIFT 8
92#define REGISTER1_TCLK_SETTLE_MASK (0xff << 0)
93#define REGISTER1_TCLK_SETTLE_SHIFT 0
94
95#define REGISTER2 0x8
96
97#define CSI2_SYSCONFIG 0x10
98#define CSI2_SYSCONFIG_MSTANDBY_MODE_MASK (3 << 12)
99#define CSI2_SYSCONFIG_MSTANDBY_MODE_FORCE (0 << 12)
100#define CSI2_SYSCONFIG_MSTANDBY_MODE_NO (1 << 12)
101#define CSI2_SYSCONFIG_MSTANDBY_MODE_SMART (2 << 12)
102#define CSI2_SYSCONFIG_SOFT_RESET (1 << 1)
103#define CSI2_SYSCONFIG_AUTO_IDLE (1 << 0)
104
105#define CSI2_SYSSTATUS 0x14
106#define CSI2_SYSSTATUS_RESET_DONE (1 << 0)
107
108#define CSI2_IRQSTATUS 0x18
109#define CSI2_IRQENABLE 0x1c
110
111/* Shared bits across CSI2_IRQENABLE and IRQSTATUS */
112
113#define CSI2_IRQ_OCP_ERR (1 << 14)
114#define CSI2_IRQ_SHORT_PACKET (1 << 13)
115#define CSI2_IRQ_ECC_CORRECTION (1 << 12)
116#define CSI2_IRQ_ECC_NO_CORRECTION (1 << 11)
117#define CSI2_IRQ_COMPLEXIO_ERR (1 << 9)
118#define CSI2_IRQ_FIFO_OVF (1 << 8)
119#define CSI2_IRQ_CONTEXT0 (1 << 0)
120
121#define CSI2_CTRL 0x40
122#define CSI2_CTRL_MFLAG_LEVH_MASK (7 << 20)
123#define CSI2_CTRL_MFLAG_LEVH_SHIFT 20
124#define CSI2_CTRL_MFLAG_LEVL_MASK (7 << 17)
125#define CSI2_CTRL_MFLAG_LEVL_SHIFT 17
126#define CSI2_CTRL_BURST_SIZE_EXPAND (1 << 16)
127#define CSI2_CTRL_VP_CLK_EN (1 << 15)
128#define CSI2_CTRL_NON_POSTED_WRITE (1 << 13)
129#define CSI2_CTRL_VP_ONLY_EN (1 << 11)
130#define CSI2_CTRL_VP_OUT_CTRL_MASK (3 << 8)
131#define CSI2_CTRL_VP_OUT_CTRL_SHIFT 8
132#define CSI2_CTRL_DBG_EN (1 << 7)
133#define CSI2_CTRL_BURST_SIZE_MASK (3 << 5)
134#define CSI2_CTRL_ENDIANNESS (1 << 4)
135#define CSI2_CTRL_FRAME (1 << 3)
136#define CSI2_CTRL_ECC_EN (1 << 2)
137#define CSI2_CTRL_IF_EN (1 << 0)
138
139#define CSI2_DBG_H 0x44
140
141#define CSI2_COMPLEXIO_CFG 0x50
142#define CSI2_COMPLEXIO_CFG_RESET_CTRL (1 << 30)
143#define CSI2_COMPLEXIO_CFG_RESET_DONE (1 << 29)
144#define CSI2_COMPLEXIO_CFG_PWD_CMD_MASK (3 << 27)
145#define CSI2_COMPLEXIO_CFG_PWD_CMD_OFF (0 << 27)
146#define CSI2_COMPLEXIO_CFG_PWD_CMD_ON (1 << 27)
147#define CSI2_COMPLEXIO_CFG_PWD_CMD_ULP (2 << 27)
148#define CSI2_COMPLEXIO_CFG_PWD_STATUS_MASK (3 << 25)
149#define CSI2_COMPLEXIO_CFG_PWD_STATUS_OFF (0 << 25)
150#define CSI2_COMPLEXIO_CFG_PWD_STATUS_ON (1 << 25)
151#define CSI2_COMPLEXIO_CFG_PWD_STATUS_ULP (2 << 25)
152#define CSI2_COMPLEXIO_CFG_PWR_AUTO (1 << 24)
153#define CSI2_COMPLEXIO_CFG_DATA_POL(i) (1 << (((i) * 4) + 3))
154#define CSI2_COMPLEXIO_CFG_DATA_POSITION_MASK(i) (7 << ((i) * 4))
155#define CSI2_COMPLEXIO_CFG_DATA_POSITION_SHIFT(i) ((i) * 4)
156#define CSI2_COMPLEXIO_CFG_CLOCK_POL (1 << 3)
157#define CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK (7 << 0)
158#define CSI2_COMPLEXIO_CFG_CLOCK_POSITION_SHIFT 0
159
160#define CSI2_COMPLEXIO_IRQSTATUS 0x54
161
162#define CSI2_SHORT_PACKET 0x5c
163
164#define CSI2_COMPLEXIO_IRQENABLE 0x60
165
166/* Shared bits across CSI2_COMPLEXIO_IRQENABLE and IRQSTATUS */
167#define CSI2_COMPLEXIO_IRQ_STATEALLULPMEXIT (1 << 26)
168#define CSI2_COMPLEXIO_IRQ_STATEALLULPMENTER (1 << 25)
169#define CSI2_COMPLEXIO_IRQ_STATEULPM5 (1 << 24)
170#define CSI2_COMPLEXIO_IRQ_STATEULPM4 (1 << 23)
171#define CSI2_COMPLEXIO_IRQ_STATEULPM3 (1 << 22)
172#define CSI2_COMPLEXIO_IRQ_STATEULPM2 (1 << 21)
173#define CSI2_COMPLEXIO_IRQ_STATEULPM1 (1 << 20)
174#define CSI2_COMPLEXIO_IRQ_ERRCONTROL5 (1 << 19)
175#define CSI2_COMPLEXIO_IRQ_ERRCONTROL4 (1 << 18)
176#define CSI2_COMPLEXIO_IRQ_ERRCONTROL3 (1 << 17)
177#define CSI2_COMPLEXIO_IRQ_ERRCONTROL2 (1 << 16)
178#define CSI2_COMPLEXIO_IRQ_ERRCONTROL1 (1 << 15)
179#define CSI2_COMPLEXIO_IRQ_ERRESC5 (1 << 14)
180#define CSI2_COMPLEXIO_IRQ_ERRESC4 (1 << 13)
181#define CSI2_COMPLEXIO_IRQ_ERRESC3 (1 << 12)
182#define CSI2_COMPLEXIO_IRQ_ERRESC2 (1 << 11)
183#define CSI2_COMPLEXIO_IRQ_ERRESC1 (1 << 10)
184#define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS5 (1 << 9)
185#define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS4 (1 << 8)
186#define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS3 (1 << 7)
187#define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS2 (1 << 6)
188#define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS1 (1 << 5)
189#define CSI2_COMPLEXIO_IRQ_ERRSOTHS5 (1 << 4)
190#define CSI2_COMPLEXIO_IRQ_ERRSOTHS4 (1 << 3)
191#define CSI2_COMPLEXIO_IRQ_ERRSOTHS3 (1 << 2)
192#define CSI2_COMPLEXIO_IRQ_ERRSOTHS2 (1 << 1)
193#define CSI2_COMPLEXIO_IRQ_ERRSOTHS1 (1 << 0)
194
195#define CSI2_DBG_P 0x68
196
197#define CSI2_TIMING 0x6c
198#define CSI2_TIMING_FORCE_RX_MODE_IO1 (1 << 15)
199#define CSI2_TIMING_STOP_STATE_X16_IO1 (1 << 14)
200#define CSI2_TIMING_STOP_STATE_X4_IO1 (1 << 13)
201#define CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK (0x1fff << 0)
202#define CSI2_TIMING_STOP_STATE_COUNTER_IO1_SHIFT 0
203
204#define CSI2_CTX_CTRL1(i) (0x70 + (0x20 * i))
205#define CSI2_CTX_CTRL1_GENERIC (1 << 30)
206#define CSI2_CTX_CTRL1_TRANSCODE (0xf << 24)
207#define CSI2_CTX_CTRL1_FEC_NUMBER_MASK (0xff << 16)
208#define CSI2_CTX_CTRL1_COUNT_MASK (0xff << 8)
209#define CSI2_CTX_CTRL1_COUNT_SHIFT 8
210#define CSI2_CTX_CTRL1_EOF_EN (1 << 7)
211#define CSI2_CTX_CTRL1_EOL_EN (1 << 6)
212#define CSI2_CTX_CTRL1_CS_EN (1 << 5)
213#define CSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4)
214#define CSI2_CTX_CTRL1_PING_PONG (1 << 3)
215#define CSI2_CTX_CTRL1_CTX_EN (1 << 0)
216
217#define CSI2_CTX_CTRL2(i) (0x74 + (0x20 * i))
218#define CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13
219#define CSI2_CTX_CTRL2_USER_DEF_MAP_MASK \
220 (0x3 << CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT)
221#define CSI2_CTX_CTRL2_VIRTUAL_ID_MASK (3 << 11)
222#define CSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11
223#define CSI2_CTX_CTRL2_DPCM_PRED (1 << 10)
224#define CSI2_CTX_CTRL2_FORMAT_MASK (0x3ff << 0)
225#define CSI2_CTX_CTRL2_FORMAT_SHIFT 0
226
227#define CSI2_CTX_DAT_OFST(i) (0x78 + (0x20 * i))
228#define CSI2_CTX_DAT_OFST_MASK (0xfff << 5)
229
230#define CSI2_CTX_PING_ADDR(i) (0x7c + (0x20 * i))
231#define CSI2_CTX_PING_ADDR_MASK 0xffffffe0
232
233#define CSI2_CTX_PONG_ADDR(i) (0x80 + (0x20 * i))
234#define CSI2_CTX_PONG_ADDR_MASK CSI2_CTX_PING_ADDR_MASK
235
236#define CSI2_CTX_IRQENABLE(i) (0x84 + (0x20 * i))
237#define CSI2_CTX_IRQSTATUS(i) (0x88 + (0x20 * i))
238
239#define CSI2_CTX_CTRL3(i) (0x8c + (0x20 * i))
240#define CSI2_CTX_CTRL3_ALPHA_SHIFT 5
241#define CSI2_CTX_CTRL3_ALPHA_MASK \
242 (0x3fff << CSI2_CTX_CTRL3_ALPHA_SHIFT)
243
244/* Shared bits across CSI2_CTX_IRQENABLE and IRQSTATUS */
245#define CSI2_CTX_IRQ_ECC_CORRECTION (1 << 8)
246#define CSI2_CTX_IRQ_LINE_NUMBER (1 << 7)
247#define CSI2_CTX_IRQ_FRAME_NUMBER (1 << 6)
248#define CSI2_CTX_IRQ_CS (1 << 5)
249#define CSI2_CTX_IRQ_LE (1 << 3)
250#define CSI2_CTX_IRQ_LS (1 << 2)
251#define CSI2_CTX_IRQ_FE (1 << 1)
252#define CSI2_CTX_IRQ_FS (1 << 0)
253
254/* ISS BTE */
255#define BTE_CTRL (0x0030)
256#define BTE_CTRL_BW_LIMITER_MASK (0x3ff << 22)
257#define BTE_CTRL_BW_LIMITER_SHIFT 22
258
259/* ISS ISP_SYS1 */
260#define ISP5_REVISION (0x0000)
261#define ISP5_SYSCONFIG (0x0010)
262#define ISP5_SYSCONFIG_STANDBYMODE_MASK (3 << 4)
263#define ISP5_SYSCONFIG_STANDBYMODE_FORCE (0 << 4)
264#define ISP5_SYSCONFIG_STANDBYMODE_NO (1 << 4)
265#define ISP5_SYSCONFIG_STANDBYMODE_SMART (2 << 4)
266#define ISP5_SYSCONFIG_SOFTRESET (1 << 1)
267
268#define ISP5_IRQSTATUS(i) (0x0028 + (0x10 * (i)))
269#define ISP5_IRQENABLE_SET(i) (0x002c + (0x10 * (i)))
270#define ISP5_IRQENABLE_CLR(i) (0x0030 + (0x10 * (i)))
271
272/* Bits shared for ISP5_IRQ* registers */
273#define ISP5_IRQ_OCP_ERR (1 << 31)
274#define ISP5_IRQ_IPIPE_INT_DPC_RNEW1 (1 << 29)
275#define ISP5_IRQ_IPIPE_INT_DPC_RNEW0 (1 << 28)
276#define ISP5_IRQ_IPIPE_INT_DPC_INIT (1 << 27)
277#define ISP5_IRQ_IPIPE_INT_EOF (1 << 25)
278#define ISP5_IRQ_H3A_INT_EOF (1 << 24)
279#define ISP5_IRQ_RSZ_INT_EOF1 (1 << 23)
280#define ISP5_IRQ_RSZ_INT_EOF0 (1 << 22)
281#define ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR (1 << 19)
282#define ISP5_IRQ_RSZ_FIFO_OVF (1 << 18)
283#define ISP5_IRQ_RSZ_INT_CYC_RSZB (1 << 17)
284#define ISP5_IRQ_RSZ_INT_CYC_RSZA (1 << 16)
285#define ISP5_IRQ_RSZ_INT_DMA (1 << 15)
286#define ISP5_IRQ_RSZ_INT_LAST_PIX (1 << 14)
287#define ISP5_IRQ_RSZ_INT_REG (1 << 13)
288#define ISP5_IRQ_H3A_INT (1 << 12)
289#define ISP5_IRQ_AF_INT (1 << 11)
290#define ISP5_IRQ_AEW_INT (1 << 10)
291#define ISP5_IRQ_IPIPEIF_IRQ (1 << 9)
292#define ISP5_IRQ_IPIPE_INT_HST (1 << 8)
293#define ISP5_IRQ_IPIPE_INT_BSC (1 << 7)
294#define ISP5_IRQ_IPIPE_INT_DMA (1 << 6)
295#define ISP5_IRQ_IPIPE_INT_LAST_PIX (1 << 5)
296#define ISP5_IRQ_IPIPE_INT_REG (1 << 4)
297#define ISP5_IRQ_ISIF_INT(i) (1 << (i))
298
299#define ISP5_CTRL (0x006c)
300#define ISP5_CTRL_MSTANDBY (1 << 24)
301#define ISP5_CTRL_VD_PULSE_EXT (1 << 23)
302#define ISP5_CTRL_MSTANDBY_WAIT (1 << 20)
303#define ISP5_CTRL_BL_CLK_ENABLE (1 << 15)
304#define ISP5_CTRL_ISIF_CLK_ENABLE (1 << 14)
305#define ISP5_CTRL_H3A_CLK_ENABLE (1 << 13)
306#define ISP5_CTRL_RSZ_CLK_ENABLE (1 << 12)
307#define ISP5_CTRL_IPIPE_CLK_ENABLE (1 << 11)
308#define ISP5_CTRL_IPIPEIF_CLK_ENABLE (1 << 10)
309#define ISP5_CTRL_SYNC_ENABLE (1 << 9)
310#define ISP5_CTRL_PSYNC_CLK_SEL (1 << 8)
311
312/* ISS ISP ISIF register offsets */
313#define ISIF_SYNCEN (0x0000)
314#define ISIF_SYNCEN_DWEN (1 << 1)
315#define ISIF_SYNCEN_SYEN (1 << 0)
316
317#define ISIF_MODESET (0x0004)
318#define ISIF_MODESET_INPMOD_MASK (3 << 12)
319#define ISIF_MODESET_INPMOD_RAW (0 << 12)
320#define ISIF_MODESET_INPMOD_YCBCR16 (1 << 12)
321#define ISIF_MODESET_INPMOD_YCBCR8 (2 << 12)
322#define ISIF_MODESET_CCDW_MASK (7 << 8)
323#define ISIF_MODESET_CCDW_2BIT (2 << 8)
324#define ISIF_MODESET_CCDMD (1 << 7)
325#define ISIF_MODESET_SWEN (1 << 5)
326#define ISIF_MODESET_HDPOL (1 << 3)
327#define ISIF_MODESET_VDPOL (1 << 2)
328
329#define ISIF_SPH (0x0018)
330#define ISIF_SPH_MASK (0x7fff)
331
332#define ISIF_LNH (0x001c)
333#define ISIF_LNH_MASK (0x7fff)
334
335#define ISIF_LNV (0x0028)
336#define ISIF_LNV_MASK (0x7fff)
337
338#define ISIF_HSIZE (0x0034)
339#define ISIF_HSIZE_ADCR (1 << 12)
340#define ISIF_HSIZE_HSIZE_MASK (0xfff)
341
342#define ISIF_CADU (0x003c)
343#define ISIF_CADU_MASK (0x7ff)
344
345#define ISIF_CADL (0x0040)
346#define ISIF_CADL_MASK (0xffff)
347
348#define ISIF_CCOLP (0x004c)
349#define ISIF_CCOLP_CP0_F0_R (0 << 6)
350#define ISIF_CCOLP_CP0_F0_GR (1 << 6)
351#define ISIF_CCOLP_CP0_F0_B (3 << 6)
352#define ISIF_CCOLP_CP0_F0_GB (2 << 6)
353#define ISIF_CCOLP_CP1_F0_R (0 << 4)
354#define ISIF_CCOLP_CP1_F0_GR (1 << 4)
355#define ISIF_CCOLP_CP1_F0_B (3 << 4)
356#define ISIF_CCOLP_CP1_F0_GB (2 << 4)
357#define ISIF_CCOLP_CP2_F0_R (0 << 2)
358#define ISIF_CCOLP_CP2_F0_GR (1 << 2)
359#define ISIF_CCOLP_CP2_F0_B (3 << 2)
360#define ISIF_CCOLP_CP2_F0_GB (2 << 2)
361#define ISIF_CCOLP_CP3_F0_R (0 << 0)
362#define ISIF_CCOLP_CP3_F0_GR (1 << 0)
363#define ISIF_CCOLP_CP3_F0_B (3 << 0)
364#define ISIF_CCOLP_CP3_F0_GB (2 << 0)
365
366#define ISIF_VDINT(i) (0x0070 + (i) * 4)
367#define ISIF_VDINT_MASK (0x7fff)
368
369#define ISIF_CGAMMAWD (0x0080)
370#define ISIF_CGAMMAWD_GWDI_MASK (0xf << 1)
371#define ISIF_CGAMMAWD_GWDI(bpp) ((16 - (bpp)) << 1)
372
373#define ISIF_CCDCFG (0x0088)
374#define ISIF_CCDCFG_Y8POS (1 << 11)
375
376/* ISS ISP IPIPEIF register offsets */
377#define IPIPEIF_ENABLE (0x0000)
378
379#define IPIPEIF_CFG1 (0x0004)
380#define IPIPEIF_CFG1_INPSRC1_MASK (3 << 14)
381#define IPIPEIF_CFG1_INPSRC1_VPORT_RAW (0 << 14)
382#define IPIPEIF_CFG1_INPSRC1_SDRAM_RAW (1 << 14)
383#define IPIPEIF_CFG1_INPSRC1_ISIF_DARKFM (2 << 14)
384#define IPIPEIF_CFG1_INPSRC1_SDRAM_YUV (3 << 14)
385#define IPIPEIF_CFG1_INPSRC2_MASK (3 << 2)
386#define IPIPEIF_CFG1_INPSRC2_ISIF (0 << 2)
387#define IPIPEIF_CFG1_INPSRC2_SDRAM_RAW (1 << 2)
388#define IPIPEIF_CFG1_INPSRC2_ISIF_DARKFM (2 << 2)
389#define IPIPEIF_CFG1_INPSRC2_SDRAM_YUV (3 << 2)
390
391#define IPIPEIF_CFG2 (0x0030)
392#define IPIPEIF_CFG2_YUV8P (1 << 7)
393#define IPIPEIF_CFG2_YUV8 (1 << 6)
394#define IPIPEIF_CFG2_YUV16 (1 << 3)
395#define IPIPEIF_CFG2_VDPOL (1 << 2)
396#define IPIPEIF_CFG2_HDPOL (1 << 1)
397#define IPIPEIF_CFG2_INTSW (1 << 0)
398
399#define IPIPEIF_CLKDIV (0x0040)
400
401/* ISS ISP IPIPE register offsets */
402#define IPIPE_SRC_EN (0x0000)
403#define IPIPE_SRC_EN_EN (1 << 0)
404
405#define IPIPE_SRC_MODE (0x0004)
406#define IPIPE_SRC_MODE_WRT (1 << 1)
407#define IPIPE_SRC_MODE_OST (1 << 0)
408
409#define IPIPE_SRC_FMT (0x0008)
410#define IPIPE_SRC_FMT_RAW2YUV (0 << 0)
411#define IPIPE_SRC_FMT_RAW2RAW (1 << 0)
412#define IPIPE_SRC_FMT_RAW2STATS (2 << 0)
413#define IPIPE_SRC_FMT_YUV2YUV (3 << 0)
414
415#define IPIPE_SRC_COL (0x000c)
416#define IPIPE_SRC_COL_OO_R (0 << 6)
417#define IPIPE_SRC_COL_OO_GR (1 << 6)
418#define IPIPE_SRC_COL_OO_B (3 << 6)
419#define IPIPE_SRC_COL_OO_GB (2 << 6)
420#define IPIPE_SRC_COL_OE_R (0 << 4)
421#define IPIPE_SRC_COL_OE_GR (1 << 4)
422#define IPIPE_SRC_COL_OE_B (3 << 4)
423#define IPIPE_SRC_COL_OE_GB (2 << 4)
424#define IPIPE_SRC_COL_EO_R (0 << 2)
425#define IPIPE_SRC_COL_EO_GR (1 << 2)
426#define IPIPE_SRC_COL_EO_B (3 << 2)
427#define IPIPE_SRC_COL_EO_GB (2 << 2)
428#define IPIPE_SRC_COL_EE_R (0 << 0)
429#define IPIPE_SRC_COL_EE_GR (1 << 0)
430#define IPIPE_SRC_COL_EE_B (3 << 0)
431#define IPIPE_SRC_COL_EE_GB (2 << 0)
432
433#define IPIPE_SRC_VPS (0x0010)
434#define IPIPE_SRC_VPS_MASK (0xffff)
435
436#define IPIPE_SRC_VSZ (0x0014)
437#define IPIPE_SRC_VSZ_MASK (0x1fff)
438
439#define IPIPE_SRC_HPS (0x0018)
440#define IPIPE_SRC_HPS_MASK (0xffff)
441
442#define IPIPE_SRC_HSZ (0x001c)
443#define IPIPE_SRC_HSZ_MASK (0x1ffe)
444
445#define IPIPE_SEL_SBU (0x0020)
446
447#define IPIPE_SRC_STA (0x0024)
448
449#define IPIPE_GCK_MMR (0x0028)
450#define IPIPE_GCK_MMR_REG (1 << 0)
451
452#define IPIPE_GCK_PIX (0x002c)
453#define IPIPE_GCK_PIX_G3 (1 << 3)
454#define IPIPE_GCK_PIX_G2 (1 << 2)
455#define IPIPE_GCK_PIX_G1 (1 << 1)
456#define IPIPE_GCK_PIX_G0 (1 << 0)
457
458#define IPIPE_DPC_LUT_EN (0x0034)
459#define IPIPE_DPC_LUT_SEL (0x0038)
460#define IPIPE_DPC_LUT_ADR (0x003c)
461#define IPIPE_DPC_LUT_SIZ (0x0040)
462
463#define IPIPE_DPC_OTF_EN (0x0044)
464#define IPIPE_DPC_OTF_TYP (0x0048)
465#define IPIPE_DPC_OTF_2_D_THR_R (0x004c)
466#define IPIPE_DPC_OTF_2_D_THR_GR (0x0050)
467#define IPIPE_DPC_OTF_2_D_THR_GB (0x0054)
468#define IPIPE_DPC_OTF_2_D_THR_B (0x0058)
469#define IPIPE_DPC_OTF_2_C_THR_R (0x005c)
470#define IPIPE_DPC_OTF_2_C_THR_GR (0x0060)
471#define IPIPE_DPC_OTF_2_C_THR_GB (0x0064)
472#define IPIPE_DPC_OTF_2_C_THR_B (0x0068)
473#define IPIPE_DPC_OTF_3_SHF (0x006c)
474#define IPIPE_DPC_OTF_3_D_THR (0x0070)
475#define IPIPE_DPC_OTF_3_D_SPL (0x0074)
476#define IPIPE_DPC_OTF_3_D_MIN (0x0078)
477#define IPIPE_DPC_OTF_3_D_MAX (0x007c)
478#define IPIPE_DPC_OTF_3_C_THR (0x0080)
479#define IPIPE_DPC_OTF_3_C_SLP (0x0084)
480#define IPIPE_DPC_OTF_3_C_MIN (0x0088)
481#define IPIPE_DPC_OTF_3_C_MAX (0x008c)
482
483#define IPIPE_LSC_VOFT (0x0090)
484#define IPIPE_LSC_VA2 (0x0094)
485#define IPIPE_LSC_VA1 (0x0098)
486#define IPIPE_LSC_VS (0x009c)
487#define IPIPE_LSC_HOFT (0x00a0)
488#define IPIPE_LSC_HA2 (0x00a4)
489#define IPIPE_LSC_HA1 (0x00a8)
490#define IPIPE_LSC_HS (0x00ac)
491#define IPIPE_LSC_GAN_R (0x00b0)
492#define IPIPE_LSC_GAN_GR (0x00b4)
493#define IPIPE_LSC_GAN_GB (0x00b8)
494#define IPIPE_LSC_GAN_B (0x00bc)
495#define IPIPE_LSC_OFT_R (0x00c0)
496#define IPIPE_LSC_OFT_GR (0x00c4)
497#define IPIPE_LSC_OFT_GB (0x00c8)
498#define IPIPE_LSC_OFT_B (0x00cc)
499#define IPIPE_LSC_SHF (0x00d0)
500#define IPIPE_LSC_MAX (0x00d4)
501
502#define IPIPE_D2F_1ST_EN (0x00d8)
503#define IPIPE_D2F_1ST_TYP (0x00dc)
504#define IPIPE_D2F_1ST_THR_00 (0x00e0)
505#define IPIPE_D2F_1ST_THR_01 (0x00e4)
506#define IPIPE_D2F_1ST_THR_02 (0x00e8)
507#define IPIPE_D2F_1ST_THR_03 (0x00ec)
508#define IPIPE_D2F_1ST_THR_04 (0x00f0)
509#define IPIPE_D2F_1ST_THR_05 (0x00f4)
510#define IPIPE_D2F_1ST_THR_06 (0x00f8)
511#define IPIPE_D2F_1ST_THR_07 (0x00fc)
512#define IPIPE_D2F_1ST_STR_00 (0x0100)
513#define IPIPE_D2F_1ST_STR_01 (0x0104)
514#define IPIPE_D2F_1ST_STR_02 (0x0108)
515#define IPIPE_D2F_1ST_STR_03 (0x010c)
516#define IPIPE_D2F_1ST_STR_04 (0x0110)
517#define IPIPE_D2F_1ST_STR_05 (0x0114)
518#define IPIPE_D2F_1ST_STR_06 (0x0118)
519#define IPIPE_D2F_1ST_STR_07 (0x011c)
520#define IPIPE_D2F_1ST_SPR_00 (0x0120)
521#define IPIPE_D2F_1ST_SPR_01 (0x0124)
522#define IPIPE_D2F_1ST_SPR_02 (0x0128)
523#define IPIPE_D2F_1ST_SPR_03 (0x012c)
524#define IPIPE_D2F_1ST_SPR_04 (0x0130)
525#define IPIPE_D2F_1ST_SPR_05 (0x0134)
526#define IPIPE_D2F_1ST_SPR_06 (0x0138)
527#define IPIPE_D2F_1ST_SPR_07 (0x013c)
528#define IPIPE_D2F_1ST_EDG_MIN (0x0140)
529#define IPIPE_D2F_1ST_EDG_MAX (0x0144)
530#define IPIPE_D2F_2ND_EN (0x0148)
531#define IPIPE_D2F_2ND_TYP (0x014c)
532#define IPIPE_D2F_2ND_THR00 (0x0150)
533#define IPIPE_D2F_2ND_THR01 (0x0154)
534#define IPIPE_D2F_2ND_THR02 (0x0158)
535#define IPIPE_D2F_2ND_THR03 (0x015c)
536#define IPIPE_D2F_2ND_THR04 (0x0160)
537#define IPIPE_D2F_2ND_THR05 (0x0164)
538#define IPIPE_D2F_2ND_THR06 (0x0168)
539#define IPIPE_D2F_2ND_THR07 (0x016c)
540#define IPIPE_D2F_2ND_STR_00 (0x0170)
541#define IPIPE_D2F_2ND_STR_01 (0x0174)
542#define IPIPE_D2F_2ND_STR_02 (0x0178)
543#define IPIPE_D2F_2ND_STR_03 (0x017c)
544#define IPIPE_D2F_2ND_STR_04 (0x0180)
545#define IPIPE_D2F_2ND_STR_05 (0x0184)
546#define IPIPE_D2F_2ND_STR_06 (0x0188)
547#define IPIPE_D2F_2ND_STR_07 (0x018c)
548#define IPIPE_D2F_2ND_SPR_00 (0x0190)
549#define IPIPE_D2F_2ND_SPR_01 (0x0194)
550#define IPIPE_D2F_2ND_SPR_02 (0x0198)
551#define IPIPE_D2F_2ND_SPR_03 (0x019c)
552#define IPIPE_D2F_2ND_SPR_04 (0x01a0)
553#define IPIPE_D2F_2ND_SPR_05 (0x01a4)
554#define IPIPE_D2F_2ND_SPR_06 (0x01a8)
555#define IPIPE_D2F_2ND_SPR_07 (0x01ac)
556#define IPIPE_D2F_2ND_EDG_MIN (0x01b0)
557#define IPIPE_D2F_2ND_EDG_MAX (0x01b4)
558
559#define IPIPE_GIC_EN (0x01b8)
560#define IPIPE_GIC_TYP (0x01bc)
561#define IPIPE_GIC_GAN (0x01c0)
562#define IPIPE_GIC_NFGAIN (0x01c4)
563#define IPIPE_GIC_THR (0x01c8)
564#define IPIPE_GIC_SLP (0x01cc)
565
566#define IPIPE_WB2_OFT_R (0x01d0)
567#define IPIPE_WB2_OFT_GR (0x01d4)
568#define IPIPE_WB2_OFT_GB (0x01d8)
569#define IPIPE_WB2_OFT_B (0x01dc)
570
571#define IPIPE_WB2_WGN_R (0x01e0)
572#define IPIPE_WB2_WGN_GR (0x01e4)
573#define IPIPE_WB2_WGN_GB (0x01e8)
574#define IPIPE_WB2_WGN_B (0x01ec)
575
576#define IPIPE_CFA_MODE (0x01f0)
577#define IPIPE_CFA_2DIR_HPF_THR (0x01f4)
578#define IPIPE_CFA_2DIR_HPF_SLP (0x01f8)
579#define IPIPE_CFA_2DIR_MIX_THR (0x01fc)
580#define IPIPE_CFA_2DIR_MIX_SLP (0x0200)
581#define IPIPE_CFA_2DIR_DIR_TRH (0x0204)
582#define IPIPE_CFA_2DIR_DIR_SLP (0x0208)
583#define IPIPE_CFA_2DIR_NDWT (0x020c)
584#define IPIPE_CFA_MONO_HUE_FRA (0x0210)
585#define IPIPE_CFA_MONO_EDG_THR (0x0214)
586#define IPIPE_CFA_MONO_THR_MIN (0x0218)
587
588#define IPIPE_CFA_MONO_THR_SLP (0x021c)
589#define IPIPE_CFA_MONO_SLP_MIN (0x0220)
590#define IPIPE_CFA_MONO_SLP_SLP (0x0224)
591#define IPIPE_CFA_MONO_LPWT (0x0228)
592
593#define IPIPE_RGB1_MUL_RR (0x022c)
594#define IPIPE_RGB1_MUL_GR (0x0230)
595#define IPIPE_RGB1_MUL_BR (0x0234)
596#define IPIPE_RGB1_MUL_RG (0x0238)
597#define IPIPE_RGB1_MUL_GG (0x023c)
598#define IPIPE_RGB1_MUL_BG (0x0240)
599#define IPIPE_RGB1_MUL_RB (0x0244)
600#define IPIPE_RGB1_MUL_GB (0x0248)
601#define IPIPE_RGB1_MUL_BB (0x024c)
602#define IPIPE_RGB1_OFT_OR (0x0250)
603#define IPIPE_RGB1_OFT_OG (0x0254)
604#define IPIPE_RGB1_OFT_OB (0x0258)
605#define IPIPE_GMM_CFG (0x025c)
606#define IPIPE_RGB2_MUL_RR (0x0260)
607#define IPIPE_RGB2_MUL_GR (0x0264)
608#define IPIPE_RGB2_MUL_BR (0x0268)
609#define IPIPE_RGB2_MUL_RG (0x026c)
610#define IPIPE_RGB2_MUL_GG (0x0270)
611#define IPIPE_RGB2_MUL_BG (0x0274)
612#define IPIPE_RGB2_MUL_RB (0x0278)
613#define IPIPE_RGB2_MUL_GB (0x027c)
614#define IPIPE_RGB2_MUL_BB (0x0280)
615#define IPIPE_RGB2_OFT_OR (0x0284)
616#define IPIPE_RGB2_OFT_OG (0x0288)
617#define IPIPE_RGB2_OFT_OB (0x028c)
618
619#define IPIPE_YUV_ADJ (0x0294)
620#define IPIPE_YUV_MUL_RY (0x0298)
621#define IPIPE_YUV_MUL_GY (0x029c)
622#define IPIPE_YUV_MUL_BY (0x02a0)
623#define IPIPE_YUV_MUL_RCB (0x02a4)
624#define IPIPE_YUV_MUL_GCB (0x02a8)
625#define IPIPE_YUV_MUL_BCB (0x02ac)
626#define IPIPE_YUV_MUL_RCR (0x02b0)
627#define IPIPE_YUV_MUL_GCR (0x02b4)
628#define IPIPE_YUV_MUL_BCR (0x02b8)
629#define IPIPE_YUV_OFT_Y (0x02bc)
630#define IPIPE_YUV_OFT_CB (0x02c0)
631#define IPIPE_YUV_OFT_CR (0x02c4)
632
633#define IPIPE_YUV_PHS (0x02c8)
634#define IPIPE_YUV_PHS_LPF (1 << 1)
635#define IPIPE_YUV_PHS_POS (1 << 0)
636
637#define IPIPE_YEE_EN (0x02d4)
638#define IPIPE_YEE_TYP (0x02d8)
639#define IPIPE_YEE_SHF (0x02dc)
640#define IPIPE_YEE_MUL_00 (0x02e0)
641#define IPIPE_YEE_MUL_01 (0x02e4)
642#define IPIPE_YEE_MUL_02 (0x02e8)
643#define IPIPE_YEE_MUL_10 (0x02ec)
644#define IPIPE_YEE_MUL_11 (0x02f0)
645#define IPIPE_YEE_MUL_12 (0x02f4)
646#define IPIPE_YEE_MUL_20 (0x02f8)
647#define IPIPE_YEE_MUL_21 (0x02fc)
648#define IPIPE_YEE_MUL_22 (0x0300)
649#define IPIPE_YEE_THR (0x0304)
650#define IPIPE_YEE_E_GAN (0x0308)
651#define IPIPE_YEE_E_THR_1 (0x030c)
652#define IPIPE_YEE_E_THR_2 (0x0310)
653#define IPIPE_YEE_G_GAN (0x0314)
654#define IPIPE_YEE_G_OFT (0x0318)
655
656#define IPIPE_CAR_EN (0x031c)
657#define IPIPE_CAR_TYP (0x0320)
658#define IPIPE_CAR_SW (0x0324)
659#define IPIPE_CAR_HPF_TYP (0x0328)
660#define IPIPE_CAR_HPF_SHF (0x032c)
661#define IPIPE_CAR_HPF_THR (0x0330)
662#define IPIPE_CAR_GN1_GAN (0x0334)
663#define IPIPE_CAR_GN1_SHF (0x0338)
664#define IPIPE_CAR_GN1_MIN (0x033c)
665#define IPIPE_CAR_GN2_GAN (0x0340)
666#define IPIPE_CAR_GN2_SHF (0x0344)
667#define IPIPE_CAR_GN2_MIN (0x0348)
668#define IPIPE_CGS_EN (0x034c)
669#define IPIPE_CGS_GN1_L_THR (0x0350)
670#define IPIPE_CGS_GN1_L_GAIN (0x0354)
671#define IPIPE_CGS_GN1_L_SHF (0x0358)
672#define IPIPE_CGS_GN1_L_MIN (0x035c)
673#define IPIPE_CGS_GN1_H_THR (0x0360)
674#define IPIPE_CGS_GN1_H_GAIN (0x0364)
675#define IPIPE_CGS_GN1_H_SHF (0x0368)
676#define IPIPE_CGS_GN1_H_MIN (0x036c)
677#define IPIPE_CGS_GN2_L_THR (0x0370)
678#define IPIPE_CGS_GN2_L_GAIN (0x0374)
679#define IPIPE_CGS_GN2_L_SHF (0x0378)
680#define IPIPE_CGS_GN2_L_MIN (0x037c)
681
682#define IPIPE_BOX_EN (0x0380)
683#define IPIPE_BOX_MODE (0x0384)
684#define IPIPE_BOX_TYP (0x0388)
685#define IPIPE_BOX_SHF (0x038c)
686#define IPIPE_BOX_SDR_SAD_H (0x0390)
687#define IPIPE_BOX_SDR_SAD_L (0x0394)
688
689#define IPIPE_HST_EN (0x039c)
690#define IPIPE_HST_MODE (0x03a0)
691#define IPIPE_HST_SEL (0x03a4)
692#define IPIPE_HST_PARA (0x03a8)
693#define IPIPE_HST_0_VPS (0x03ac)
694#define IPIPE_HST_0_VSZ (0x03b0)
695#define IPIPE_HST_0_HPS (0x03b4)
696#define IPIPE_HST_0_HSZ (0x03b8)
697#define IPIPE_HST_1_VPS (0x03bc)
698#define IPIPE_HST_1_VSZ (0x03c0)
699#define IPIPE_HST_1_HPS (0x03c4)
700#define IPIPE_HST_1_HSZ (0x03c8)
701#define IPIPE_HST_2_VPS (0x03cc)
702#define IPIPE_HST_2_VSZ (0x03d0)
703#define IPIPE_HST_2_HPS (0x03d4)
704#define IPIPE_HST_2_HSZ (0x03d8)
705#define IPIPE_HST_3_VPS (0x03dc)
706#define IPIPE_HST_3_VSZ (0x03e0)
707#define IPIPE_HST_3_HPS (0x03e4)
708#define IPIPE_HST_3_HSZ (0x03e8)
709#define IPIPE_HST_TBL (0x03ec)
710#define IPIPE_HST_MUL_R (0x03f0)
711#define IPIPE_HST_MUL_GR (0x03f4)
712#define IPIPE_HST_MUL_GB (0x03f8)
713#define IPIPE_HST_MUL_B (0x03fc)
714
715#define IPIPE_BSC_EN (0x0400)
716#define IPIPE_BSC_MODE (0x0404)
717#define IPIPE_BSC_TYP (0x0408)
718#define IPIPE_BSC_ROW_VCT (0x040c)
719#define IPIPE_BSC_ROW_SHF (0x0410)
720#define IPIPE_BSC_ROW_VPO (0x0414)
721#define IPIPE_BSC_ROW_VNU (0x0418)
722#define IPIPE_BSC_ROW_VSKIP (0x041c)
723#define IPIPE_BSC_ROW_HPO (0x0420)
724#define IPIPE_BSC_ROW_HNU (0x0424)
725#define IPIPE_BSC_ROW_HSKIP (0x0428)
726#define IPIPE_BSC_COL_VCT (0x042c)
727#define IPIPE_BSC_COL_SHF (0x0430)
728#define IPIPE_BSC_COL_VPO (0x0434)
729#define IPIPE_BSC_COL_VNU (0x0438)
730#define IPIPE_BSC_COL_VSKIP (0x043c)
731#define IPIPE_BSC_COL_HPO (0x0440)
732#define IPIPE_BSC_COL_HNU (0x0444)
733#define IPIPE_BSC_COL_HSKIP (0x0448)
734
735#define IPIPE_BSC_EN (0x0400)
736
737/* ISS ISP Resizer register offsets */
738#define RSZ_REVISION (0x0000)
739#define RSZ_SYSCONFIG (0x0004)
740#define RSZ_SYSCONFIG_RSZB_CLK_EN (1 << 9)
741#define RSZ_SYSCONFIG_RSZA_CLK_EN (1 << 8)
742
743#define RSZ_IN_FIFO_CTRL (0x000c)
744#define RSZ_IN_FIFO_CTRL_THRLD_LOW_MASK (0x1ff << 16)
745#define RSZ_IN_FIFO_CTRL_THRLD_LOW_SHIFT 16
746#define RSZ_IN_FIFO_CTRL_THRLD_HIGH_MASK (0x1ff << 0)
747#define RSZ_IN_FIFO_CTRL_THRLD_HIGH_SHIFT 0
748
749#define RSZ_FRACDIV (0x0008)
750#define RSZ_FRACDIV_MASK (0xffff)
751
752#define RSZ_SRC_EN (0x0020)
753#define RSZ_SRC_EN_SRC_EN (1 << 0)
754
755#define RSZ_SRC_MODE (0x0024)
756#define RSZ_SRC_MODE_OST (1 << 0)
757#define RSZ_SRC_MODE_WRT (1 << 1)
758
759#define RSZ_SRC_FMT0 (0x0028)
760#define RSZ_SRC_FMT0_BYPASS (1 << 1)
761#define RSZ_SRC_FMT0_SEL (1 << 0)
762
763#define RSZ_SRC_FMT1 (0x002c)
764#define RSZ_SRC_FMT1_IN420 (1 << 1)
765
766#define RSZ_SRC_VPS (0x0030)
767#define RSZ_SRC_VSZ (0x0034)
768#define RSZ_SRC_HPS (0x0038)
769#define RSZ_SRC_HSZ (0x003c)
770#define RSZ_DMA_RZA (0x0040)
771#define RSZ_DMA_RZB (0x0044)
772#define RSZ_DMA_STA (0x0048)
773#define RSZ_GCK_MMR (0x004c)
774#define RSZ_GCK_MMR_MMR (1 << 0)
775
776#define RSZ_GCK_SDR (0x0054)
777#define RSZ_GCK_SDR_CORE (1 << 0)
778
779#define RSZ_IRQ_RZA (0x0058)
780#define RSZ_IRQ_RZA_MASK (0x1fff)
781
782#define RSZ_IRQ_RZB (0x005c)
783#define RSZ_IRQ_RZB_MASK (0x1fff)
784
785#define RSZ_YUV_Y_MIN (0x0060)
786#define RSZ_YUV_Y_MAX (0x0064)
787#define RSZ_YUV_C_MIN (0x0068)
788#define RSZ_YUV_C_MAX (0x006c)
789
790#define RSZ_SEQ (0x0074)
791#define RSZ_SEQ_HRVB (1 << 2)
792#define RSZ_SEQ_HRVA (1 << 0)
793
794#define RZA_EN (0x0078)
795#define RZA_MODE (0x007c)
796#define RZA_MODE_ONE_SHOT (1 << 0)
797
798#define RZA_420 (0x0080)
799#define RZA_I_VPS (0x0084)
800#define RZA_I_HPS (0x0088)
801#define RZA_O_VSZ (0x008c)
802#define RZA_O_HSZ (0x0090)
803#define RZA_V_PHS_Y (0x0094)
804#define RZA_V_PHS_C (0x0098)
805#define RZA_V_DIF (0x009c)
806#define RZA_V_TYP (0x00a0)
807#define RZA_V_LPF (0x00a4)
808#define RZA_H_PHS (0x00a8)
809#define RZA_H_DIF (0x00b0)
810#define RZA_H_TYP (0x00b4)
811#define RZA_H_LPF (0x00b8)
812#define RZA_DWN_EN (0x00bc)
813#define RZA_SDR_Y_BAD_H (0x00d0)
814#define RZA_SDR_Y_BAD_L (0x00d4)
815#define RZA_SDR_Y_SAD_H (0x00d8)
816#define RZA_SDR_Y_SAD_L (0x00dc)
817#define RZA_SDR_Y_OFT (0x00e0)
818#define RZA_SDR_Y_PTR_S (0x00e4)
819#define RZA_SDR_Y_PTR_E (0x00e8)
820#define RZA_SDR_C_BAD_H (0x00ec)
821#define RZA_SDR_C_BAD_L (0x00f0)
822#define RZA_SDR_C_SAD_H (0x00f4)
823#define RZA_SDR_C_SAD_L (0x00f8)
824#define RZA_SDR_C_OFT (0x00fc)
825#define RZA_SDR_C_PTR_S (0x0100)
826#define RZA_SDR_C_PTR_E (0x0104)
827
828#define RZB_EN (0x0108)
829#define RZB_MODE (0x010c)
830#define RZB_420 (0x0110)
831#define RZB_I_VPS (0x0114)
832#define RZB_I_HPS (0x0118)
833#define RZB_O_VSZ (0x011c)
834#define RZB_O_HSZ (0x0120)
835
836#define RZB_V_DIF (0x012c)
837#define RZB_V_TYP (0x0130)
838#define RZB_V_LPF (0x0134)
839
840#define RZB_H_DIF (0x0140)
841#define RZB_H_TYP (0x0144)
842#define RZB_H_LPF (0x0148)
843
844#define RZB_SDR_Y_BAD_H (0x0160)
845#define RZB_SDR_Y_BAD_L (0x0164)
846#define RZB_SDR_Y_SAD_H (0x0168)
847#define RZB_SDR_Y_SAD_L (0x016c)
848#define RZB_SDR_Y_OFT (0x0170)
849#define RZB_SDR_Y_PTR_S (0x0174)
850#define RZB_SDR_Y_PTR_E (0x0178)
851#define RZB_SDR_C_BAD_H (0x017c)
852#define RZB_SDR_C_BAD_L (0x0180)
853#define RZB_SDR_C_SAD_H (0x0184)
854#define RZB_SDR_C_SAD_L (0x0188)
855
856#define RZB_SDR_C_PTR_S (0x0190)
857#define RZB_SDR_C_PTR_E (0x0194)
858
859/* Shared Bitmasks between RZA & RZB */
860#define RSZ_EN_EN (1 << 0)
861
862#define RSZ_420_CEN (1 << 1)
863#define RSZ_420_YEN (1 << 0)
864
865#define RSZ_I_VPS_MASK (0x1fff)
866
867#define RSZ_I_HPS_MASK (0x1fff)
868
869#define RSZ_O_VSZ_MASK (0x1fff)
870
871#define RSZ_O_HSZ_MASK (0x1ffe)
872
873#define RSZ_V_PHS_Y_MASK (0x3fff)
874
875#define RSZ_V_PHS_C_MASK (0x3fff)
876
877#define RSZ_V_DIF_MASK (0x3fff)
878
879#define RSZ_V_TYP_C (1 << 1)
880#define RSZ_V_TYP_Y (1 << 0)
881
882#define RSZ_V_LPF_C_MASK (0x3f << 6)
883#define RSZ_V_LPF_C_SHIFT 6
884#define RSZ_V_LPF_Y_MASK (0x3f << 0)
885#define RSZ_V_LPF_Y_SHIFT 0
886
887#define RSZ_H_PHS_MASK (0x3fff)
888
889#define RSZ_H_DIF_MASK (0x3fff)
890
891#define RSZ_H_TYP_C (1 << 1)
892#define RSZ_H_TYP_Y (1 << 0)
893
894#define RSZ_H_LPF_C_MASK (0x3f << 6)
895#define RSZ_H_LPF_C_SHIFT 6
896#define RSZ_H_LPF_Y_MASK (0x3f << 0)
897#define RSZ_H_LPF_Y_SHIFT 0
898
899#define RSZ_DWN_EN_DWN_EN (1 << 0)
900
901#endif /* _OMAP4_ISS_REGS_H_ */
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
new file mode 100644
index 000000000000..ae831b8985c9
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -0,0 +1,893 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - ISP RESIZER module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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/module.h>
15#include <linux/uaccess.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/dma-mapping.h>
19#include <linux/mm.h>
20#include <linux/sched.h>
21
22#include "iss.h"
23#include "iss_regs.h"
24#include "iss_resizer.h"
25
26static const unsigned int resizer_fmts[] = {
27 V4L2_MBUS_FMT_UYVY8_1X16,
28 V4L2_MBUS_FMT_YUYV8_1X16,
29};
30
31/*
32 * resizer_print_status - Print current RESIZER Module register values.
33 * @resizer: Pointer to ISS ISP RESIZER device.
34 *
35 * Also prints other debug information stored in the RESIZER module.
36 */
37#define RSZ_PRINT_REGISTER(iss, name)\
38 dev_dbg(iss->dev, "###RSZ " #name "=0x%08x\n", \
39 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_##name))
40
41#define RZA_PRINT_REGISTER(iss, name)\
42 dev_dbg(iss->dev, "###RZA " #name "=0x%08x\n", \
43 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_##name))
44
45static void resizer_print_status(struct iss_resizer_device *resizer)
46{
47 struct iss_device *iss = to_iss_device(resizer);
48
49 dev_dbg(iss->dev, "-------------RESIZER Register dump-------------\n");
50
51 RSZ_PRINT_REGISTER(iss, SYSCONFIG);
52 RSZ_PRINT_REGISTER(iss, IN_FIFO_CTRL);
53 RSZ_PRINT_REGISTER(iss, FRACDIV);
54 RSZ_PRINT_REGISTER(iss, SRC_EN);
55 RSZ_PRINT_REGISTER(iss, SRC_MODE);
56 RSZ_PRINT_REGISTER(iss, SRC_FMT0);
57 RSZ_PRINT_REGISTER(iss, SRC_FMT1);
58 RSZ_PRINT_REGISTER(iss, SRC_VPS);
59 RSZ_PRINT_REGISTER(iss, SRC_VSZ);
60 RSZ_PRINT_REGISTER(iss, SRC_HPS);
61 RSZ_PRINT_REGISTER(iss, SRC_HSZ);
62 RSZ_PRINT_REGISTER(iss, DMA_RZA);
63 RSZ_PRINT_REGISTER(iss, DMA_RZB);
64 RSZ_PRINT_REGISTER(iss, DMA_STA);
65 RSZ_PRINT_REGISTER(iss, GCK_MMR);
66 RSZ_PRINT_REGISTER(iss, GCK_SDR);
67 RSZ_PRINT_REGISTER(iss, IRQ_RZA);
68 RSZ_PRINT_REGISTER(iss, IRQ_RZB);
69 RSZ_PRINT_REGISTER(iss, YUV_Y_MIN);
70 RSZ_PRINT_REGISTER(iss, YUV_Y_MAX);
71 RSZ_PRINT_REGISTER(iss, YUV_C_MIN);
72 RSZ_PRINT_REGISTER(iss, YUV_C_MAX);
73 RSZ_PRINT_REGISTER(iss, SEQ);
74
75 RZA_PRINT_REGISTER(iss, EN);
76 RZA_PRINT_REGISTER(iss, MODE);
77 RZA_PRINT_REGISTER(iss, 420);
78 RZA_PRINT_REGISTER(iss, I_VPS);
79 RZA_PRINT_REGISTER(iss, I_HPS);
80 RZA_PRINT_REGISTER(iss, O_VSZ);
81 RZA_PRINT_REGISTER(iss, O_HSZ);
82 RZA_PRINT_REGISTER(iss, V_PHS_Y);
83 RZA_PRINT_REGISTER(iss, V_PHS_C);
84 RZA_PRINT_REGISTER(iss, V_DIF);
85 RZA_PRINT_REGISTER(iss, V_TYP);
86 RZA_PRINT_REGISTER(iss, V_LPF);
87 RZA_PRINT_REGISTER(iss, H_PHS);
88 RZA_PRINT_REGISTER(iss, H_DIF);
89 RZA_PRINT_REGISTER(iss, H_TYP);
90 RZA_PRINT_REGISTER(iss, H_LPF);
91 RZA_PRINT_REGISTER(iss, DWN_EN);
92 RZA_PRINT_REGISTER(iss, SDR_Y_BAD_H);
93 RZA_PRINT_REGISTER(iss, SDR_Y_BAD_L);
94 RZA_PRINT_REGISTER(iss, SDR_Y_SAD_H);
95 RZA_PRINT_REGISTER(iss, SDR_Y_SAD_L);
96 RZA_PRINT_REGISTER(iss, SDR_Y_OFT);
97 RZA_PRINT_REGISTER(iss, SDR_Y_PTR_S);
98 RZA_PRINT_REGISTER(iss, SDR_Y_PTR_E);
99 RZA_PRINT_REGISTER(iss, SDR_C_BAD_H);
100 RZA_PRINT_REGISTER(iss, SDR_C_BAD_L);
101 RZA_PRINT_REGISTER(iss, SDR_C_SAD_H);
102 RZA_PRINT_REGISTER(iss, SDR_C_SAD_L);
103 RZA_PRINT_REGISTER(iss, SDR_C_OFT);
104 RZA_PRINT_REGISTER(iss, SDR_C_PTR_S);
105 RZA_PRINT_REGISTER(iss, SDR_C_PTR_E);
106
107 dev_dbg(iss->dev, "-----------------------------------------------\n");
108}
109
110/*
111 * resizer_enable - Enable/Disable RESIZER.
112 * @enable: enable flag
113 *
114 */
115static void resizer_enable(struct iss_resizer_device *resizer, u8 enable)
116{
117 struct iss_device *iss = to_iss_device(resizer);
118
119 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_EN,
120 RSZ_SRC_EN_SRC_EN, enable ? RSZ_SRC_EN_SRC_EN : 0);
121
122 /* TODO: Enable RSZB */
123 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_EN, RSZ_EN_EN,
124 enable ? RSZ_EN_EN : 0);
125}
126
127/* -----------------------------------------------------------------------------
128 * Format- and pipeline-related configuration helpers
129 */
130
131/*
132 * resizer_set_outaddr - Set memory address to save output image
133 * @resizer: Pointer to ISP RESIZER device.
134 * @addr: 32-bit memory address aligned on 32 byte boundary.
135 *
136 * Sets the memory address where the output will be saved.
137 */
138static void resizer_set_outaddr(struct iss_resizer_device *resizer, u32 addr)
139{
140 struct iss_device *iss = to_iss_device(resizer);
141 struct v4l2_mbus_framefmt *informat, *outformat;
142
143 informat = &resizer->formats[RESIZER_PAD_SINK];
144 outformat = &resizer->formats[RESIZER_PAD_SOURCE_MEM];
145
146 /* Save address splitted in Base Address H & L */
147 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_BAD_H,
148 (addr >> 16) & 0xffff);
149 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_BAD_L,
150 addr & 0xffff);
151
152 /* SAD = BAD */
153 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_SAD_H,
154 (addr >> 16) & 0xffff);
155 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_SAD_L,
156 addr & 0xffff);
157
158 /* Program UV buffer address... Hardcoded to be contiguous! */
159 if ((informat->code == V4L2_MBUS_FMT_UYVY8_1X16) &&
160 (outformat->code == V4L2_MBUS_FMT_YUYV8_1_5X8)) {
161 u32 c_addr = addr + (resizer->video_out.bpl_value *
162 (outformat->height - 1));
163
164 /* Ensure Y_BAD_L[6:0] = C_BAD_L[6:0]*/
165 if ((c_addr ^ addr) & 0x7f) {
166 c_addr &= ~0x7f;
167 c_addr += 0x80;
168 c_addr |= addr & 0x7f;
169 }
170
171 /* Save address splitted in Base Address H & L */
172 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_BAD_H,
173 (c_addr >> 16) & 0xffff);
174 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_BAD_L,
175 c_addr & 0xffff);
176
177 /* SAD = BAD */
178 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_SAD_H,
179 (c_addr >> 16) & 0xffff);
180 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_SAD_L,
181 c_addr & 0xffff);
182 }
183}
184
185static void resizer_configure(struct iss_resizer_device *resizer)
186{
187 struct iss_device *iss = to_iss_device(resizer);
188 struct v4l2_mbus_framefmt *informat, *outformat;
189
190 informat = &resizer->formats[RESIZER_PAD_SINK];
191 outformat = &resizer->formats[RESIZER_PAD_SOURCE_MEM];
192
193 /* Disable pass-through more. Despite its name, the BYPASS bit controls
194 * pass-through mode, not bypass mode.
195 */
196 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_FMT0,
197 RSZ_SRC_FMT0_BYPASS);
198
199 /* Select RSZ input */
200 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_FMT0,
201 RSZ_SRC_FMT0_SEL,
202 resizer->input == RESIZER_INPUT_IPIPEIF ?
203 RSZ_SRC_FMT0_SEL : 0);
204
205 /* RSZ ignores WEN signal from IPIPE/IPIPEIF */
206 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_MODE,
207 RSZ_SRC_MODE_WRT);
208
209 /* Set Resizer in free-running mode */
210 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_MODE,
211 RSZ_SRC_MODE_OST);
212
213 /* Init Resizer A */
214 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_MODE,
215 RZA_MODE_ONE_SHOT);
216
217 /* Set size related things now */
218 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_VPS, 0);
219 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_HPS, 0);
220 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_VSZ,
221 informat->height - 2);
222 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SRC_HSZ,
223 informat->width - 1);
224
225 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_I_VPS, 0);
226 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_I_HPS, 0);
227
228 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_O_VSZ,
229 outformat->height - 2);
230 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_O_HSZ,
231 outformat->width - 1);
232
233 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_V_DIF, 0x100);
234 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_H_DIF, 0x100);
235
236 /* Buffer output settings */
237 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_PTR_S, 0);
238 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_PTR_E,
239 outformat->height - 1);
240
241 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_Y_OFT,
242 resizer->video_out.bpl_value);
243
244 /* UYVY -> NV12 conversion */
245 if ((informat->code == V4L2_MBUS_FMT_UYVY8_1X16) &&
246 (outformat->code == V4L2_MBUS_FMT_YUYV8_1_5X8)) {
247 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_420,
248 RSZ_420_CEN | RSZ_420_YEN);
249
250 /* UV Buffer output settings */
251 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_PTR_S,
252 0);
253 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_PTR_E,
254 outformat->height - 1);
255
256 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_SDR_C_OFT,
257 resizer->video_out.bpl_value);
258 } else {
259 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_RESIZER, RZA_420, 0);
260 }
261}
262
263/* -----------------------------------------------------------------------------
264 * Interrupt handling
265 */
266
267static void resizer_isr_buffer(struct iss_resizer_device *resizer)
268{
269 struct iss_buffer *buffer;
270
271 /* The whole resizer needs to be stopped. Disabling RZA only produces
272 * input FIFO overflows, most probably when the next frame is received.
273 */
274 resizer_enable(resizer, 0);
275
276 buffer = omap4iss_video_buffer_next(&resizer->video_out);
277 if (buffer == NULL)
278 return;
279
280 resizer_set_outaddr(resizer, buffer->iss_addr);
281
282 resizer_enable(resizer, 1);
283}
284
285/*
286 * resizer_isif0_isr - Handle ISIF0 event
287 * @resizer: Pointer to ISP RESIZER device.
288 *
289 * Executes LSC deferred enablement before next frame starts.
290 */
291static void resizer_int_dma_isr(struct iss_resizer_device *resizer)
292{
293 struct iss_pipeline *pipe =
294 to_iss_pipeline(&resizer->subdev.entity);
295 if (pipe->do_propagation)
296 atomic_inc(&pipe->frame_number);
297
298 resizer_isr_buffer(resizer);
299}
300
301/*
302 * omap4iss_resizer_isr - Configure resizer during interframe time.
303 * @resizer: Pointer to ISP RESIZER device.
304 * @events: RESIZER events
305 */
306void omap4iss_resizer_isr(struct iss_resizer_device *resizer, u32 events)
307{
308 struct iss_device *iss = to_iss_device(resizer);
309 struct iss_pipeline *pipe =
310 to_iss_pipeline(&resizer->subdev.entity);
311
312 if (events & (ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
313 ISP5_IRQ_RSZ_FIFO_OVF)) {
314 dev_dbg(iss->dev, "RSZ Err: FIFO_IN_BLK:%d, FIFO_OVF:%d\n",
315 events & ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR ? 1 : 0,
316 events & ISP5_IRQ_RSZ_FIFO_OVF ? 1 : 0);
317 omap4iss_pipeline_cancel_stream(pipe);
318 }
319
320 if (omap4iss_module_sync_is_stopping(&resizer->wait,
321 &resizer->stopping))
322 return;
323
324 if (events & ISP5_IRQ_RSZ_INT_DMA)
325 resizer_int_dma_isr(resizer);
326}
327
328/* -----------------------------------------------------------------------------
329 * ISS video operations
330 */
331
332static int resizer_video_queue(struct iss_video *video,
333 struct iss_buffer *buffer)
334{
335 struct iss_resizer_device *resizer = container_of(video,
336 struct iss_resizer_device, video_out);
337
338 if (!(resizer->output & RESIZER_OUTPUT_MEMORY))
339 return -ENODEV;
340
341 resizer_set_outaddr(resizer, buffer->iss_addr);
342
343 /*
344 * If streaming was enabled before there was a buffer queued
345 * or underrun happened in the ISR, the hardware was not enabled
346 * and DMA queue flag ISS_VIDEO_DMAQUEUE_UNDERRUN is still set.
347 * Enable it now.
348 */
349 if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
350 resizer_enable(resizer, 1);
351 iss_video_dmaqueue_flags_clr(video);
352 }
353
354 return 0;
355}
356
357static const struct iss_video_operations resizer_video_ops = {
358 .queue = resizer_video_queue,
359};
360
361/* -----------------------------------------------------------------------------
362 * V4L2 subdev operations
363 */
364
365/*
366 * resizer_set_stream - Enable/Disable streaming on the RESIZER module
367 * @sd: ISP RESIZER V4L2 subdevice
368 * @enable: Enable/disable stream
369 */
370static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
371{
372 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
373 struct iss_device *iss = to_iss_device(resizer);
374 struct iss_video *video_out = &resizer->video_out;
375 int ret = 0;
376
377 if (resizer->state == ISS_PIPELINE_STREAM_STOPPED) {
378 if (enable == ISS_PIPELINE_STREAM_STOPPED)
379 return 0;
380
381 omap4iss_isp_subclk_enable(iss, OMAP4_ISS_ISP_SUBCLK_RSZ);
382
383 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_GCK_MMR,
384 RSZ_GCK_MMR_MMR);
385 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_GCK_SDR,
386 RSZ_GCK_SDR_CORE);
387
388 /* FIXME: Enable RSZB also */
389 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SYSCONFIG,
390 RSZ_SYSCONFIG_RSZA_CLK_EN);
391 }
392
393 switch (enable) {
394 case ISS_PIPELINE_STREAM_CONTINUOUS:
395
396 resizer_configure(resizer);
397 resizer_print_status(resizer);
398
399 /*
400 * When outputting to memory with no buffer available, let the
401 * buffer queue handler start the hardware. A DMA queue flag
402 * ISS_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
403 * a buffer available.
404 */
405 if (resizer->output & RESIZER_OUTPUT_MEMORY &&
406 !(video_out->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_QUEUED))
407 break;
408
409 atomic_set(&resizer->stopping, 0);
410 resizer_enable(resizer, 1);
411 iss_video_dmaqueue_flags_clr(video_out);
412 break;
413
414 case ISS_PIPELINE_STREAM_STOPPED:
415 if (resizer->state == ISS_PIPELINE_STREAM_STOPPED)
416 return 0;
417 if (omap4iss_module_sync_idle(&sd->entity, &resizer->wait,
418 &resizer->stopping))
419 ret = -ETIMEDOUT;
420
421 resizer_enable(resizer, 0);
422 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_SYSCONFIG,
423 RSZ_SYSCONFIG_RSZA_CLK_EN);
424 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_GCK_SDR,
425 RSZ_GCK_SDR_CORE);
426 iss_reg_clr(iss, OMAP4_ISS_MEM_ISP_RESIZER, RSZ_GCK_MMR,
427 RSZ_GCK_MMR_MMR);
428 omap4iss_isp_subclk_disable(iss, OMAP4_ISS_ISP_SUBCLK_RSZ);
429 iss_video_dmaqueue_flags_clr(video_out);
430 break;
431 }
432
433 resizer->state = enable;
434 return ret;
435}
436
437static struct v4l2_mbus_framefmt *
438__resizer_get_format(struct iss_resizer_device *resizer,
439 struct v4l2_subdev_fh *fh, unsigned int pad,
440 enum v4l2_subdev_format_whence which)
441{
442 if (which == V4L2_SUBDEV_FORMAT_TRY)
443 return v4l2_subdev_get_try_format(fh, pad);
444 else
445 return &resizer->formats[pad];
446}
447
448/*
449 * resizer_try_format - Try video format on a pad
450 * @resizer: ISS RESIZER device
451 * @fh : V4L2 subdev file handle
452 * @pad: Pad number
453 * @fmt: Format
454 */
455static void
456resizer_try_format(struct iss_resizer_device *resizer,
457 struct v4l2_subdev_fh *fh, unsigned int pad,
458 struct v4l2_mbus_framefmt *fmt,
459 enum v4l2_subdev_format_whence which)
460{
461 enum v4l2_mbus_pixelcode pixelcode;
462 struct v4l2_mbus_framefmt *format;
463 unsigned int width = fmt->width;
464 unsigned int height = fmt->height;
465 unsigned int i;
466
467 switch (pad) {
468 case RESIZER_PAD_SINK:
469 for (i = 0; i < ARRAY_SIZE(resizer_fmts); i++) {
470 if (fmt->code == resizer_fmts[i])
471 break;
472 }
473
474 /* If not found, use UYVY as default */
475 if (i >= ARRAY_SIZE(resizer_fmts))
476 fmt->code = V4L2_MBUS_FMT_UYVY8_1X16;
477
478 /* Clamp the input size. */
479 fmt->width = clamp_t(u32, width, 1, 8192);
480 fmt->height = clamp_t(u32, height, 1, 8192);
481 break;
482
483 case RESIZER_PAD_SOURCE_MEM:
484 pixelcode = fmt->code;
485 format = __resizer_get_format(resizer, fh, RESIZER_PAD_SINK,
486 which);
487 memcpy(fmt, format, sizeof(*fmt));
488
489 if ((pixelcode == V4L2_MBUS_FMT_YUYV8_1_5X8) &&
490 (fmt->code == V4L2_MBUS_FMT_UYVY8_1X16))
491 fmt->code = pixelcode;
492
493 /* The data formatter truncates the number of horizontal output
494 * pixels to a multiple of 16. To avoid clipping data, allow
495 * callers to request an output size bigger than the input size
496 * up to the nearest multiple of 16.
497 */
498 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
499 fmt->width &= ~15;
500 fmt->height = clamp_t(u32, height, 32, fmt->height);
501 break;
502
503 }
504
505 fmt->colorspace = V4L2_COLORSPACE_JPEG;
506 fmt->field = V4L2_FIELD_NONE;
507}
508
509/*
510 * resizer_enum_mbus_code - Handle pixel format enumeration
511 * @sd : pointer to v4l2 subdev structure
512 * @fh : V4L2 subdev file handle
513 * @code : pointer to v4l2_subdev_mbus_code_enum structure
514 * return -EINVAL or zero on success
515 */
516static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
517 struct v4l2_subdev_fh *fh,
518 struct v4l2_subdev_mbus_code_enum *code)
519{
520 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
521 struct v4l2_mbus_framefmt *format;
522
523 switch (code->pad) {
524 case RESIZER_PAD_SINK:
525 if (code->index >= ARRAY_SIZE(resizer_fmts))
526 return -EINVAL;
527
528 code->code = resizer_fmts[code->index];
529 break;
530
531 case RESIZER_PAD_SOURCE_MEM:
532 format = __resizer_get_format(resizer, fh, RESIZER_PAD_SINK,
533 V4L2_SUBDEV_FORMAT_TRY);
534
535 if (code->index == 0) {
536 code->code = format->code;
537 break;
538 }
539
540 switch (format->code) {
541 case V4L2_MBUS_FMT_UYVY8_1X16:
542 if (code->index == 1)
543 code->code = V4L2_MBUS_FMT_YUYV8_1_5X8;
544 else
545 return -EINVAL;
546 break;
547 default:
548 if (code->index != 0)
549 return -EINVAL;
550 }
551
552 break;
553
554 default:
555 return -EINVAL;
556 }
557
558 return 0;
559}
560
561static int resizer_enum_frame_size(struct v4l2_subdev *sd,
562 struct v4l2_subdev_fh *fh,
563 struct v4l2_subdev_frame_size_enum *fse)
564{
565 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
566 struct v4l2_mbus_framefmt format;
567
568 if (fse->index != 0)
569 return -EINVAL;
570
571 format.code = fse->code;
572 format.width = 1;
573 format.height = 1;
574 resizer_try_format(resizer, fh, fse->pad, &format,
575 V4L2_SUBDEV_FORMAT_TRY);
576 fse->min_width = format.width;
577 fse->min_height = format.height;
578
579 if (format.code != fse->code)
580 return -EINVAL;
581
582 format.code = fse->code;
583 format.width = -1;
584 format.height = -1;
585 resizer_try_format(resizer, fh, fse->pad, &format,
586 V4L2_SUBDEV_FORMAT_TRY);
587 fse->max_width = format.width;
588 fse->max_height = format.height;
589
590 return 0;
591}
592
593/*
594 * resizer_get_format - Retrieve the video format on a pad
595 * @sd : ISP RESIZER V4L2 subdevice
596 * @fh : V4L2 subdev file handle
597 * @fmt: Format
598 *
599 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
600 * to the format type.
601 */
602static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
603 struct v4l2_subdev_format *fmt)
604{
605 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
606 struct v4l2_mbus_framefmt *format;
607
608 format = __resizer_get_format(resizer, fh, fmt->pad, fmt->which);
609 if (format == NULL)
610 return -EINVAL;
611
612 fmt->format = *format;
613 return 0;
614}
615
616/*
617 * resizer_set_format - Set the video format on a pad
618 * @sd : ISP RESIZER V4L2 subdevice
619 * @fh : V4L2 subdev file handle
620 * @fmt: Format
621 *
622 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
623 * to the format type.
624 */
625static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
626 struct v4l2_subdev_format *fmt)
627{
628 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
629 struct v4l2_mbus_framefmt *format;
630
631 format = __resizer_get_format(resizer, fh, fmt->pad, fmt->which);
632 if (format == NULL)
633 return -EINVAL;
634
635 resizer_try_format(resizer, fh, fmt->pad, &fmt->format, fmt->which);
636 *format = fmt->format;
637
638 /* Propagate the format from sink to source */
639 if (fmt->pad == RESIZER_PAD_SINK) {
640 format = __resizer_get_format(resizer, fh,
641 RESIZER_PAD_SOURCE_MEM,
642 fmt->which);
643 *format = fmt->format;
644 resizer_try_format(resizer, fh, RESIZER_PAD_SOURCE_MEM, format,
645 fmt->which);
646 }
647
648 return 0;
649}
650
651static int resizer_link_validate(struct v4l2_subdev *sd,
652 struct media_link *link,
653 struct v4l2_subdev_format *source_fmt,
654 struct v4l2_subdev_format *sink_fmt)
655{
656 /* Check if the two ends match */
657 if (source_fmt->format.width != sink_fmt->format.width ||
658 source_fmt->format.height != sink_fmt->format.height)
659 return -EPIPE;
660
661 if (source_fmt->format.code != sink_fmt->format.code)
662 return -EPIPE;
663
664 return 0;
665}
666
667/*
668 * resizer_init_formats - Initialize formats on all pads
669 * @sd: ISP RESIZER V4L2 subdevice
670 * @fh: V4L2 subdev file handle
671 *
672 * Initialize all pad formats with default values. If fh is not NULL, try
673 * formats are initialized on the file handle. Otherwise active formats are
674 * initialized on the device.
675 */
676static int resizer_init_formats(struct v4l2_subdev *sd,
677 struct v4l2_subdev_fh *fh)
678{
679 struct v4l2_subdev_format format;
680
681 memset(&format, 0, sizeof(format));
682 format.pad = RESIZER_PAD_SINK;
683 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
684 format.format.code = V4L2_MBUS_FMT_UYVY8_1X16;
685 format.format.width = 4096;
686 format.format.height = 4096;
687 resizer_set_format(sd, fh, &format);
688
689 return 0;
690}
691
692/* V4L2 subdev video operations */
693static const struct v4l2_subdev_video_ops resizer_v4l2_video_ops = {
694 .s_stream = resizer_set_stream,
695};
696
697/* V4L2 subdev pad operations */
698static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
699 .enum_mbus_code = resizer_enum_mbus_code,
700 .enum_frame_size = resizer_enum_frame_size,
701 .get_fmt = resizer_get_format,
702 .set_fmt = resizer_set_format,
703 .link_validate = resizer_link_validate,
704};
705
706/* V4L2 subdev operations */
707static const struct v4l2_subdev_ops resizer_v4l2_ops = {
708 .video = &resizer_v4l2_video_ops,
709 .pad = &resizer_v4l2_pad_ops,
710};
711
712/* V4L2 subdev internal operations */
713static const struct v4l2_subdev_internal_ops resizer_v4l2_internal_ops = {
714 .open = resizer_init_formats,
715};
716
717/* -----------------------------------------------------------------------------
718 * Media entity operations
719 */
720
721/*
722 * resizer_link_setup - Setup RESIZER connections
723 * @entity: RESIZER media entity
724 * @local: Pad at the local end of the link
725 * @remote: Pad at the remote end of the link
726 * @flags: Link flags
727 *
728 * return -EINVAL or zero on success
729 */
730static int resizer_link_setup(struct media_entity *entity,
731 const struct media_pad *local,
732 const struct media_pad *remote, u32 flags)
733{
734 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
735 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
736 struct iss_device *iss = to_iss_device(resizer);
737
738 switch (local->index | media_entity_type(remote->entity)) {
739 case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
740 /* Read from IPIPE or IPIPEIF. */
741 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
742 resizer->input = RESIZER_INPUT_NONE;
743 break;
744 }
745
746 if (resizer->input != RESIZER_INPUT_NONE)
747 return -EBUSY;
748
749 if (remote->entity == &iss->ipipeif.subdev.entity)
750 resizer->input = RESIZER_INPUT_IPIPEIF;
751 else if (remote->entity == &iss->ipipe.subdev.entity)
752 resizer->input = RESIZER_INPUT_IPIPE;
753
754
755 break;
756
757 case RESIZER_PAD_SOURCE_MEM | MEDIA_ENT_T_DEVNODE:
758 /* Write to memory */
759 if (flags & MEDIA_LNK_FL_ENABLED) {
760 if (resizer->output & ~RESIZER_OUTPUT_MEMORY)
761 return -EBUSY;
762 resizer->output |= RESIZER_OUTPUT_MEMORY;
763 } else {
764 resizer->output &= ~RESIZER_OUTPUT_MEMORY;
765 }
766 break;
767
768 default:
769 return -EINVAL;
770 }
771
772 return 0;
773}
774
775/* media operations */
776static const struct media_entity_operations resizer_media_ops = {
777 .link_setup = resizer_link_setup,
778 .link_validate = v4l2_subdev_link_validate,
779};
780
781/*
782 * resizer_init_entities - Initialize V4L2 subdev and media entity
783 * @resizer: ISS ISP RESIZER module
784 *
785 * Return 0 on success and a negative error code on failure.
786 */
787static int resizer_init_entities(struct iss_resizer_device *resizer)
788{
789 struct v4l2_subdev *sd = &resizer->subdev;
790 struct media_pad *pads = resizer->pads;
791 struct media_entity *me = &sd->entity;
792 int ret;
793
794 resizer->input = RESIZER_INPUT_NONE;
795
796 v4l2_subdev_init(sd, &resizer_v4l2_ops);
797 sd->internal_ops = &resizer_v4l2_internal_ops;
798 strlcpy(sd->name, "OMAP4 ISS ISP resizer", sizeof(sd->name));
799 sd->grp_id = 1 << 16; /* group ID for iss subdevs */
800 v4l2_set_subdevdata(sd, resizer);
801 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
802
803 pads[RESIZER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
804 pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
805
806 me->ops = &resizer_media_ops;
807 ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
808 if (ret < 0)
809 return ret;
810
811 resizer_init_formats(sd, NULL);
812
813 resizer->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
814 resizer->video_out.ops = &resizer_video_ops;
815 resizer->video_out.iss = to_iss_device(resizer);
816 resizer->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
817 resizer->video_out.bpl_alignment = 32;
818 resizer->video_out.bpl_zero_padding = 1;
819 resizer->video_out.bpl_max = 0x1ffe0;
820
821 ret = omap4iss_video_init(&resizer->video_out, "ISP resizer a");
822 if (ret < 0)
823 return ret;
824
825 /* Connect the RESIZER subdev to the video node. */
826 ret = media_entity_create_link(&resizer->subdev.entity,
827 RESIZER_PAD_SOURCE_MEM,
828 &resizer->video_out.video.entity, 0, 0);
829 if (ret < 0)
830 return ret;
831
832 return 0;
833}
834
835void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer)
836{
837 media_entity_cleanup(&resizer->subdev.entity);
838
839 v4l2_device_unregister_subdev(&resizer->subdev);
840 omap4iss_video_unregister(&resizer->video_out);
841}
842
843int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer,
844 struct v4l2_device *vdev)
845{
846 int ret;
847
848 /* Register the subdev and video node. */
849 ret = v4l2_device_register_subdev(vdev, &resizer->subdev);
850 if (ret < 0)
851 goto error;
852
853 ret = omap4iss_video_register(&resizer->video_out, vdev);
854 if (ret < 0)
855 goto error;
856
857 return 0;
858
859error:
860 omap4iss_resizer_unregister_entities(resizer);
861 return ret;
862}
863
864/* -----------------------------------------------------------------------------
865 * ISP RESIZER initialisation and cleanup
866 */
867
868/*
869 * omap4iss_resizer_init - RESIZER module initialization.
870 * @iss: Device pointer specific to the OMAP4 ISS.
871 *
872 * TODO: Get the initialisation values from platform data.
873 *
874 * Return 0 on success or a negative error code otherwise.
875 */
876int omap4iss_resizer_init(struct iss_device *iss)
877{
878 struct iss_resizer_device *resizer = &iss->resizer;
879
880 resizer->state = ISS_PIPELINE_STREAM_STOPPED;
881 init_waitqueue_head(&resizer->wait);
882
883 return resizer_init_entities(resizer);
884}
885
886/*
887 * omap4iss_resizer_cleanup - RESIZER module cleanup.
888 * @iss: Device pointer specific to the OMAP4 ISS.
889 */
890void omap4iss_resizer_cleanup(struct iss_device *iss)
891{
892 /* FIXME: are you sure there's nothing to do? */
893}
diff --git a/drivers/staging/media/omap4iss/iss_resizer.h b/drivers/staging/media/omap4iss/iss_resizer.h
new file mode 100644
index 000000000000..3727498b06a3
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_resizer.h
@@ -0,0 +1,75 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - ISP RESIZER module
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef OMAP4_ISS_RESIZER_H
15#define OMAP4_ISS_RESIZER_H
16
17#include "iss_video.h"
18
19enum resizer_input_entity {
20 RESIZER_INPUT_NONE,
21 RESIZER_INPUT_IPIPE,
22 RESIZER_INPUT_IPIPEIF
23};
24
25#define RESIZER_OUTPUT_MEMORY (1 << 0)
26
27/* Sink and source RESIZER pads */
28#define RESIZER_PAD_SINK 0
29#define RESIZER_PAD_SOURCE_MEM 1
30#define RESIZER_PADS_NUM 2
31
32/*
33 * struct iss_resizer_device - Structure for the RESIZER module to store its own
34 * information
35 * @subdev: V4L2 subdevice
36 * @pads: Sink and source media entity pads
37 * @formats: Active video formats
38 * @input: Active input
39 * @output: Active outputs
40 * @video_out: Output video node
41 * @error: A hardware error occurred during capture
42 * @state: Streaming state
43 * @wait: Wait queue used to stop the module
44 * @stopping: Stopping state
45 */
46struct iss_resizer_device {
47 struct v4l2_subdev subdev;
48 struct media_pad pads[RESIZER_PADS_NUM];
49 struct v4l2_mbus_framefmt formats[RESIZER_PADS_NUM];
50
51 enum resizer_input_entity input;
52 unsigned int output;
53 struct iss_video video_out;
54 unsigned int error;
55
56 enum iss_pipeline_stream_state state;
57 wait_queue_head_t wait;
58 atomic_t stopping;
59};
60
61struct iss_device;
62
63int omap4iss_resizer_init(struct iss_device *iss);
64void omap4iss_resizer_cleanup(struct iss_device *iss);
65int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer,
66 struct v4l2_device *vdev);
67void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer);
68
69int omap4iss_resizer_busy(struct iss_resizer_device *resizer);
70void omap4iss_resizer_isr(struct iss_resizer_device *resizer, u32 events);
71void omap4iss_resizer_restore_context(struct iss_device *iss);
72void omap4iss_resizer_max_rate(struct iss_resizer_device *resizer,
73 unsigned int *max_rate);
74
75#endif /* OMAP4_ISS_RESIZER_H */
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
new file mode 100644
index 000000000000..8c7f35029cd5
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -0,0 +1,1226 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - Generic video node
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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 <asm/cacheflush.h>
15#include <linux/clk.h>
16#include <linux/mm.h>
17#include <linux/pagemap.h>
18#include <linux/sched.h>
19#include <linux/slab.h>
20#include <linux/vmalloc.h>
21#include <linux/module.h>
22#include <media/v4l2-dev.h>
23#include <media/v4l2-ioctl.h>
24
25#include "iss_video.h"
26#include "iss.h"
27
28
29/* -----------------------------------------------------------------------------
30 * Helper functions
31 */
32
33static struct iss_format_info formats[] = {
34 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
35 V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
36 V4L2_PIX_FMT_GREY, 8, "Greyscale 8 bpp", },
37 { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
38 V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
39 V4L2_PIX_FMT_Y10, 10, "Greyscale 10 bpp", },
40 { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
41 V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
42 V4L2_PIX_FMT_Y12, 12, "Greyscale 12 bpp", },
43 { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
44 V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
45 V4L2_PIX_FMT_SBGGR8, 8, "BGGR Bayer 8 bpp", },
46 { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
47 V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
48 V4L2_PIX_FMT_SGBRG8, 8, "GBRG Bayer 8 bpp", },
49 { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
50 V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
51 V4L2_PIX_FMT_SGRBG8, 8, "GRBG Bayer 8 bpp", },
52 { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
53 V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
54 V4L2_PIX_FMT_SRGGB8, 8, "RGGB Bayer 8 bpp", },
55 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
56 V4L2_MBUS_FMT_SGRBG10_1X10, 0,
57 V4L2_PIX_FMT_SGRBG10DPCM8, 8, "GRBG Bayer 10 bpp DPCM8", },
58 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
59 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
60 V4L2_PIX_FMT_SBGGR10, 10, "BGGR Bayer 10 bpp", },
61 { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
62 V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
63 V4L2_PIX_FMT_SGBRG10, 10, "GBRG Bayer 10 bpp", },
64 { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
65 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
66 V4L2_PIX_FMT_SGRBG10, 10, "GRBG Bayer 10 bpp", },
67 { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
68 V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
69 V4L2_PIX_FMT_SRGGB10, 10, "RGGB Bayer 10 bpp", },
70 { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
71 V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
72 V4L2_PIX_FMT_SBGGR12, 12, "BGGR Bayer 12 bpp", },
73 { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
74 V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
75 V4L2_PIX_FMT_SGBRG12, 12, "GBRG Bayer 12 bpp", },
76 { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
77 V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
78 V4L2_PIX_FMT_SGRBG12, 12, "GRBG Bayer 12 bpp", },
79 { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
80 V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
81 V4L2_PIX_FMT_SRGGB12, 12, "RGGB Bayer 12 bpp", },
82 { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
83 V4L2_MBUS_FMT_UYVY8_1X16, 0,
84 V4L2_PIX_FMT_UYVY, 16, "YUV 4:2:2 (UYVY)", },
85 { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
86 V4L2_MBUS_FMT_YUYV8_1X16, 0,
87 V4L2_PIX_FMT_YUYV, 16, "YUV 4:2:2 (YUYV)", },
88 { V4L2_MBUS_FMT_YUYV8_1_5X8, V4L2_MBUS_FMT_YUYV8_1_5X8,
89 V4L2_MBUS_FMT_YUYV8_1_5X8, 0,
90 V4L2_PIX_FMT_NV12, 8, "YUV 4:2:0 (NV12)", },
91};
92
93const struct iss_format_info *
94omap4iss_video_format_info(enum v4l2_mbus_pixelcode code)
95{
96 unsigned int i;
97
98 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
99 if (formats[i].code == code)
100 return &formats[i];
101 }
102
103 return NULL;
104}
105
106/*
107 * iss_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
108 * @video: ISS video instance
109 * @mbus: v4l2_mbus_framefmt format (input)
110 * @pix: v4l2_pix_format format (output)
111 *
112 * Fill the output pix structure with information from the input mbus format.
113 * The bytesperline and sizeimage fields are computed from the requested bytes
114 * per line value in the pix format and information from the video instance.
115 *
116 * Return the number of padding bytes at end of line.
117 */
118static unsigned int iss_video_mbus_to_pix(const struct iss_video *video,
119 const struct v4l2_mbus_framefmt *mbus,
120 struct v4l2_pix_format *pix)
121{
122 unsigned int bpl = pix->bytesperline;
123 unsigned int min_bpl;
124 unsigned int i;
125
126 memset(pix, 0, sizeof(*pix));
127 pix->width = mbus->width;
128 pix->height = mbus->height;
129
130 /* Skip the last format in the loop so that it will be selected if no
131 * match is found.
132 */
133 for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
134 if (formats[i].code == mbus->code)
135 break;
136 }
137
138 min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8;
139
140 /* Clamp the requested bytes per line value. If the maximum bytes per
141 * line value is zero, the module doesn't support user configurable line
142 * sizes. Override the requested value with the minimum in that case.
143 */
144 if (video->bpl_max)
145 bpl = clamp(bpl, min_bpl, video->bpl_max);
146 else
147 bpl = min_bpl;
148
149 if (!video->bpl_zero_padding || bpl != min_bpl)
150 bpl = ALIGN(bpl, video->bpl_alignment);
151
152 pix->pixelformat = formats[i].pixelformat;
153 pix->bytesperline = bpl;
154 pix->sizeimage = pix->bytesperline * pix->height;
155 pix->colorspace = mbus->colorspace;
156 pix->field = mbus->field;
157
158 /* FIXME: Special case for NV12! We should make this nicer... */
159 if (pix->pixelformat == V4L2_PIX_FMT_NV12)
160 pix->sizeimage += (pix->bytesperline * pix->height) / 2;
161
162 return bpl - min_bpl;
163}
164
165static void iss_video_pix_to_mbus(const struct v4l2_pix_format *pix,
166 struct v4l2_mbus_framefmt *mbus)
167{
168 unsigned int i;
169
170 memset(mbus, 0, sizeof(*mbus));
171 mbus->width = pix->width;
172 mbus->height = pix->height;
173
174 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
175 if (formats[i].pixelformat == pix->pixelformat)
176 break;
177 }
178
179 if (WARN_ON(i == ARRAY_SIZE(formats)))
180 return;
181
182 mbus->code = formats[i].code;
183 mbus->colorspace = pix->colorspace;
184 mbus->field = pix->field;
185}
186
187static struct v4l2_subdev *
188iss_video_remote_subdev(struct iss_video *video, u32 *pad)
189{
190 struct media_pad *remote;
191
192 remote = media_entity_remote_pad(&video->pad);
193
194 if (remote == NULL ||
195 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
196 return NULL;
197
198 if (pad)
199 *pad = remote->index;
200
201 return media_entity_to_v4l2_subdev(remote->entity);
202}
203
204/* Return a pointer to the ISS video instance at the far end of the pipeline. */
205static struct iss_video *
206iss_video_far_end(struct iss_video *video)
207{
208 struct media_entity_graph graph;
209 struct media_entity *entity = &video->video.entity;
210 struct media_device *mdev = entity->parent;
211 struct iss_video *far_end = NULL;
212
213 mutex_lock(&mdev->graph_mutex);
214 media_entity_graph_walk_start(&graph, entity);
215
216 while ((entity = media_entity_graph_walk_next(&graph))) {
217 if (entity == &video->video.entity)
218 continue;
219
220 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
221 continue;
222
223 far_end = to_iss_video(media_entity_to_video_device(entity));
224 if (far_end->type != video->type)
225 break;
226
227 far_end = NULL;
228 }
229
230 mutex_unlock(&mdev->graph_mutex);
231 return far_end;
232}
233
234static int
235__iss_video_get_format(struct iss_video *video,
236 struct v4l2_mbus_framefmt *format)
237{
238 struct v4l2_subdev_format fmt;
239 struct v4l2_subdev *subdev;
240 u32 pad;
241 int ret;
242
243 subdev = iss_video_remote_subdev(video, &pad);
244 if (subdev == NULL)
245 return -EINVAL;
246
247 memset(&fmt, 0, sizeof(fmt));
248 fmt.pad = pad;
249 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
250
251 mutex_lock(&video->mutex);
252 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
253 mutex_unlock(&video->mutex);
254
255 if (ret)
256 return ret;
257
258 *format = fmt.format;
259 return 0;
260}
261
262static int
263iss_video_check_format(struct iss_video *video, struct iss_video_fh *vfh)
264{
265 struct v4l2_mbus_framefmt format;
266 struct v4l2_pix_format pixfmt;
267 int ret;
268
269 ret = __iss_video_get_format(video, &format);
270 if (ret < 0)
271 return ret;
272
273 pixfmt.bytesperline = 0;
274 ret = iss_video_mbus_to_pix(video, &format, &pixfmt);
275
276 if (vfh->format.fmt.pix.pixelformat != pixfmt.pixelformat ||
277 vfh->format.fmt.pix.height != pixfmt.height ||
278 vfh->format.fmt.pix.width != pixfmt.width ||
279 vfh->format.fmt.pix.bytesperline != pixfmt.bytesperline ||
280 vfh->format.fmt.pix.sizeimage != pixfmt.sizeimage)
281 return -EINVAL;
282
283 return ret;
284}
285
286/* -----------------------------------------------------------------------------
287 * Video queue operations
288 */
289
290static int iss_video_queue_setup(struct vb2_queue *vq,
291 const struct v4l2_format *fmt,
292 unsigned int *count, unsigned int *num_planes,
293 unsigned int sizes[], void *alloc_ctxs[])
294{
295 struct iss_video_fh *vfh = vb2_get_drv_priv(vq);
296 struct iss_video *video = vfh->video;
297
298 /* Revisit multi-planar support for NV12 */
299 *num_planes = 1;
300
301 sizes[0] = vfh->format.fmt.pix.sizeimage;
302 if (sizes[0] == 0)
303 return -EINVAL;
304
305 alloc_ctxs[0] = video->alloc_ctx;
306
307 *count = min(*count, video->capture_mem / PAGE_ALIGN(sizes[0]));
308
309 return 0;
310}
311
312static void iss_video_buf_cleanup(struct vb2_buffer *vb)
313{
314 struct iss_buffer *buffer = container_of(vb, struct iss_buffer, vb);
315
316 if (buffer->iss_addr)
317 buffer->iss_addr = 0;
318}
319
320static int iss_video_buf_prepare(struct vb2_buffer *vb)
321{
322 struct iss_video_fh *vfh = vb2_get_drv_priv(vb->vb2_queue);
323 struct iss_buffer *buffer = container_of(vb, struct iss_buffer, vb);
324 struct iss_video *video = vfh->video;
325 unsigned long size = vfh->format.fmt.pix.sizeimage;
326 dma_addr_t addr;
327
328 if (vb2_plane_size(vb, 0) < size)
329 return -ENOBUFS;
330
331 /* Refuse to prepare the buffer is the video node has registered an
332 * error. We don't need to take any lock here as the operation is
333 * inherently racy. The authoritative check will be performed in the
334 * queue handler, which can't return an error, this check is just a best
335 * effort to notify userspace as early as possible.
336 */
337 if (unlikely(video->error))
338 return -EIO;
339
340 addr = vb2_dma_contig_plane_dma_addr(vb, 0);
341 if (!IS_ALIGNED(addr, 32)) {
342 dev_dbg(video->iss->dev,
343 "Buffer address must be aligned to 32 bytes boundary.\n");
344 return -EINVAL;
345 }
346
347 vb2_set_plane_payload(vb, 0, size);
348 buffer->iss_addr = addr;
349 return 0;
350}
351
352static void iss_video_buf_queue(struct vb2_buffer *vb)
353{
354 struct iss_video_fh *vfh = vb2_get_drv_priv(vb->vb2_queue);
355 struct iss_video *video = vfh->video;
356 struct iss_buffer *buffer = container_of(vb, struct iss_buffer, vb);
357 struct iss_pipeline *pipe = to_iss_pipeline(&video->video.entity);
358 unsigned long flags;
359 bool empty;
360
361 spin_lock_irqsave(&video->qlock, flags);
362
363 if (unlikely(video->error)) {
364 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
365 spin_unlock_irqrestore(&video->qlock, flags);
366 return;
367 }
368
369 empty = list_empty(&video->dmaqueue);
370 list_add_tail(&buffer->list, &video->dmaqueue);
371
372 spin_unlock_irqrestore(&video->qlock, flags);
373
374 if (empty) {
375 enum iss_pipeline_state state;
376 unsigned int start;
377
378 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
379 state = ISS_PIPELINE_QUEUE_OUTPUT;
380 else
381 state = ISS_PIPELINE_QUEUE_INPUT;
382
383 spin_lock_irqsave(&pipe->lock, flags);
384 pipe->state |= state;
385 video->ops->queue(video, buffer);
386 video->dmaqueue_flags |= ISS_VIDEO_DMAQUEUE_QUEUED;
387
388 start = iss_pipeline_ready(pipe);
389 if (start)
390 pipe->state |= ISS_PIPELINE_STREAM;
391 spin_unlock_irqrestore(&pipe->lock, flags);
392
393 if (start)
394 omap4iss_pipeline_set_stream(pipe,
395 ISS_PIPELINE_STREAM_SINGLESHOT);
396 }
397}
398
399static struct vb2_ops iss_video_vb2ops = {
400 .queue_setup = iss_video_queue_setup,
401 .buf_prepare = iss_video_buf_prepare,
402 .buf_queue = iss_video_buf_queue,
403 .buf_cleanup = iss_video_buf_cleanup,
404};
405
406/*
407 * omap4iss_video_buffer_next - Complete the current buffer and return the next
408 * @video: ISS video object
409 *
410 * Remove the current video buffer from the DMA queue and fill its timestamp,
411 * field count and state fields before waking up its completion handler.
412 *
413 * For capture video nodes, the buffer state is set to VB2_BUF_STATE_DONE if no
414 * error has been flagged in the pipeline, or to VB2_BUF_STATE_ERROR otherwise.
415 *
416 * The DMA queue is expected to contain at least one buffer.
417 *
418 * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
419 * empty.
420 */
421struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video)
422{
423 struct iss_pipeline *pipe = to_iss_pipeline(&video->video.entity);
424 enum iss_pipeline_state state;
425 struct iss_buffer *buf;
426 unsigned long flags;
427 struct timespec ts;
428
429 spin_lock_irqsave(&video->qlock, flags);
430 if (WARN_ON(list_empty(&video->dmaqueue))) {
431 spin_unlock_irqrestore(&video->qlock, flags);
432 return NULL;
433 }
434
435 buf = list_first_entry(&video->dmaqueue, struct iss_buffer,
436 list);
437 list_del(&buf->list);
438 spin_unlock_irqrestore(&video->qlock, flags);
439
440 ktime_get_ts(&ts);
441 buf->vb.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
442 buf->vb.v4l2_buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
443
444 /* Do frame number propagation only if this is the output video node.
445 * Frame number either comes from the CSI receivers or it gets
446 * incremented here if H3A is not active.
447 * Note: There is no guarantee that the output buffer will finish
448 * first, so the input number might lag behind by 1 in some cases.
449 */
450 if (video == pipe->output && !pipe->do_propagation)
451 buf->vb.v4l2_buf.sequence =
452 atomic_inc_return(&pipe->frame_number);
453 else
454 buf->vb.v4l2_buf.sequence = atomic_read(&pipe->frame_number);
455
456 vb2_buffer_done(&buf->vb, pipe->error ?
457 VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
458 pipe->error = false;
459
460 spin_lock_irqsave(&video->qlock, flags);
461 if (list_empty(&video->dmaqueue)) {
462 spin_unlock_irqrestore(&video->qlock, flags);
463 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
464 state = ISS_PIPELINE_QUEUE_OUTPUT
465 | ISS_PIPELINE_STREAM;
466 else
467 state = ISS_PIPELINE_QUEUE_INPUT
468 | ISS_PIPELINE_STREAM;
469
470 spin_lock_irqsave(&pipe->lock, flags);
471 pipe->state &= ~state;
472 if (video->pipe.stream_state == ISS_PIPELINE_STREAM_CONTINUOUS)
473 video->dmaqueue_flags |= ISS_VIDEO_DMAQUEUE_UNDERRUN;
474 spin_unlock_irqrestore(&pipe->lock, flags);
475 return NULL;
476 }
477
478 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
479 spin_lock(&pipe->lock);
480 pipe->state &= ~ISS_PIPELINE_STREAM;
481 spin_unlock(&pipe->lock);
482 }
483
484 buf = list_first_entry(&video->dmaqueue, struct iss_buffer,
485 list);
486 spin_unlock_irqrestore(&video->qlock, flags);
487 buf->vb.state = VB2_BUF_STATE_ACTIVE;
488 return buf;
489}
490
491/*
492 * omap4iss_video_cancel_stream - Cancel stream on a video node
493 * @video: ISS video object
494 *
495 * Cancelling a stream mark all buffers on the video node as erroneous and makes
496 * sure no new buffer can be queued.
497 */
498void omap4iss_video_cancel_stream(struct iss_video *video)
499{
500 unsigned long flags;
501
502 spin_lock_irqsave(&video->qlock, flags);
503
504 while (!list_empty(&video->dmaqueue)) {
505 struct iss_buffer *buf;
506
507 buf = list_first_entry(&video->dmaqueue, struct iss_buffer,
508 list);
509 list_del(&buf->list);
510 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
511 }
512
513 video->error = true;
514
515 spin_unlock_irqrestore(&video->qlock, flags);
516}
517
518/* -----------------------------------------------------------------------------
519 * V4L2 ioctls
520 */
521
522static int
523iss_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
524{
525 struct iss_video *video = video_drvdata(file);
526
527 strlcpy(cap->driver, ISS_VIDEO_DRIVER_NAME, sizeof(cap->driver));
528 strlcpy(cap->card, video->video.name, sizeof(cap->card));
529 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
530
531 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
532 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
533 else
534 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
535
536 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
537 | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
538
539 return 0;
540}
541
542static int
543iss_video_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
544{
545 struct iss_video *video = video_drvdata(file);
546 struct v4l2_mbus_framefmt format;
547 unsigned int index = f->index;
548 unsigned int i;
549 int ret;
550
551 if (f->type != video->type)
552 return -EINVAL;
553
554 ret = __iss_video_get_format(video, &format);
555 if (ret < 0)
556 return ret;
557
558 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
559 const struct iss_format_info *info = &formats[i];
560
561 if (format.code != info->code)
562 continue;
563
564 if (index == 0) {
565 f->pixelformat = info->pixelformat;
566 strlcpy(f->description, info->description,
567 sizeof(f->description));
568 return 0;
569 }
570
571 index--;
572 }
573
574 return -EINVAL;
575}
576
577static int
578iss_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
579{
580 struct iss_video_fh *vfh = to_iss_video_fh(fh);
581 struct iss_video *video = video_drvdata(file);
582
583 if (format->type != video->type)
584 return -EINVAL;
585
586 mutex_lock(&video->mutex);
587 *format = vfh->format;
588 mutex_unlock(&video->mutex);
589
590 return 0;
591}
592
593static int
594iss_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
595{
596 struct iss_video_fh *vfh = to_iss_video_fh(fh);
597 struct iss_video *video = video_drvdata(file);
598 struct v4l2_mbus_framefmt fmt;
599
600 if (format->type != video->type)
601 return -EINVAL;
602
603 mutex_lock(&video->mutex);
604
605 /* Fill the bytesperline and sizeimage fields by converting to media bus
606 * format and back to pixel format.
607 */
608 iss_video_pix_to_mbus(&format->fmt.pix, &fmt);
609 iss_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
610
611 vfh->format = *format;
612
613 mutex_unlock(&video->mutex);
614 return 0;
615}
616
617static int
618iss_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
619{
620 struct iss_video *video = video_drvdata(file);
621 struct v4l2_subdev_format fmt;
622 struct v4l2_subdev *subdev;
623 u32 pad;
624 int ret;
625
626 if (format->type != video->type)
627 return -EINVAL;
628
629 subdev = iss_video_remote_subdev(video, &pad);
630 if (subdev == NULL)
631 return -EINVAL;
632
633 iss_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
634
635 fmt.pad = pad;
636 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
637 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
638 if (ret)
639 return ret;
640
641 iss_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
642 return 0;
643}
644
645static int
646iss_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
647{
648 struct iss_video *video = video_drvdata(file);
649 struct v4l2_subdev *subdev;
650 int ret;
651
652 subdev = iss_video_remote_subdev(video, NULL);
653 if (subdev == NULL)
654 return -EINVAL;
655
656 mutex_lock(&video->mutex);
657 ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
658 mutex_unlock(&video->mutex);
659
660 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
661}
662
663static int
664iss_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
665{
666 struct iss_video *video = video_drvdata(file);
667 struct v4l2_subdev_format format;
668 struct v4l2_subdev *subdev;
669 u32 pad;
670 int ret;
671
672 subdev = iss_video_remote_subdev(video, &pad);
673 if (subdev == NULL)
674 return -EINVAL;
675
676 /* Try the get crop operation first and fallback to get format if not
677 * implemented.
678 */
679 ret = v4l2_subdev_call(subdev, video, g_crop, crop);
680 if (ret != -ENOIOCTLCMD)
681 return ret;
682
683 format.pad = pad;
684 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
685 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
686 if (ret < 0)
687 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
688
689 crop->c.left = 0;
690 crop->c.top = 0;
691 crop->c.width = format.format.width;
692 crop->c.height = format.format.height;
693
694 return 0;
695}
696
697static int
698iss_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
699{
700 struct iss_video *video = video_drvdata(file);
701 struct v4l2_subdev *subdev;
702 int ret;
703
704 subdev = iss_video_remote_subdev(video, NULL);
705 if (subdev == NULL)
706 return -EINVAL;
707
708 mutex_lock(&video->mutex);
709 ret = v4l2_subdev_call(subdev, video, s_crop, crop);
710 mutex_unlock(&video->mutex);
711
712 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
713}
714
715static int
716iss_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
717{
718 struct iss_video_fh *vfh = to_iss_video_fh(fh);
719 struct iss_video *video = video_drvdata(file);
720
721 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
722 video->type != a->type)
723 return -EINVAL;
724
725 memset(a, 0, sizeof(*a));
726 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
727 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
728 a->parm.output.timeperframe = vfh->timeperframe;
729
730 return 0;
731}
732
733static int
734iss_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
735{
736 struct iss_video_fh *vfh = to_iss_video_fh(fh);
737 struct iss_video *video = video_drvdata(file);
738
739 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
740 video->type != a->type)
741 return -EINVAL;
742
743 if (a->parm.output.timeperframe.denominator == 0)
744 a->parm.output.timeperframe.denominator = 1;
745
746 vfh->timeperframe = a->parm.output.timeperframe;
747
748 return 0;
749}
750
751static int
752iss_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
753{
754 struct iss_video_fh *vfh = to_iss_video_fh(fh);
755
756 return vb2_reqbufs(&vfh->queue, rb);
757}
758
759static int
760iss_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
761{
762 struct iss_video_fh *vfh = to_iss_video_fh(fh);
763
764 return vb2_querybuf(&vfh->queue, b);
765}
766
767static int
768iss_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
769{
770 struct iss_video_fh *vfh = to_iss_video_fh(fh);
771
772 return vb2_qbuf(&vfh->queue, b);
773}
774
775static int
776iss_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
777{
778 struct iss_video_fh *vfh = to_iss_video_fh(fh);
779
780 return vb2_dqbuf(&vfh->queue, b, file->f_flags & O_NONBLOCK);
781}
782
783/*
784 * Stream management
785 *
786 * Every ISS pipeline has a single input and a single output. The input can be
787 * either a sensor or a video node. The output is always a video node.
788 *
789 * As every pipeline has an output video node, the ISS video objects at the
790 * pipeline output stores the pipeline state. It tracks the streaming state of
791 * both the input and output, as well as the availability of buffers.
792 *
793 * In sensor-to-memory mode, frames are always available at the pipeline input.
794 * Starting the sensor usually requires I2C transfers and must be done in
795 * interruptible context. The pipeline is started and stopped synchronously
796 * to the stream on/off commands. All modules in the pipeline will get their
797 * subdev set stream handler called. The module at the end of the pipeline must
798 * delay starting the hardware until buffers are available at its output.
799 *
800 * In memory-to-memory mode, starting/stopping the stream requires
801 * synchronization between the input and output. ISS modules can't be stopped
802 * in the middle of a frame, and at least some of the modules seem to become
803 * busy as soon as they're started, even if they don't receive a frame start
804 * event. For that reason frames need to be processed in single-shot mode. The
805 * driver needs to wait until a frame is completely processed and written to
806 * memory before restarting the pipeline for the next frame. Pipelined
807 * processing might be possible but requires more testing.
808 *
809 * Stream start must be delayed until buffers are available at both the input
810 * and output. The pipeline must be started in the videobuf queue callback with
811 * the buffers queue spinlock held. The modules subdev set stream operation must
812 * not sleep.
813 */
814static int
815iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
816{
817 struct iss_video_fh *vfh = to_iss_video_fh(fh);
818 struct iss_video *video = video_drvdata(file);
819 struct media_entity_graph graph;
820 struct media_entity *entity;
821 enum iss_pipeline_state state;
822 struct iss_pipeline *pipe;
823 struct iss_video *far_end;
824 unsigned long flags;
825 int ret;
826
827 if (type != video->type)
828 return -EINVAL;
829
830 mutex_lock(&video->stream_lock);
831
832 /* Start streaming on the pipeline. No link touching an entity in the
833 * pipeline can be activated or deactivated once streaming is started.
834 */
835 pipe = video->video.entity.pipe
836 ? to_iss_pipeline(&video->video.entity) : &video->pipe;
837 pipe->external = NULL;
838 pipe->external_rate = 0;
839 pipe->external_bpp = 0;
840 pipe->entities = 0;
841
842 if (video->iss->pdata->set_constraints)
843 video->iss->pdata->set_constraints(video->iss, true);
844
845 ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
846 if (ret < 0)
847 goto err_media_entity_pipeline_start;
848
849 entity = &video->video.entity;
850 media_entity_graph_walk_start(&graph, entity);
851 while ((entity = media_entity_graph_walk_next(&graph)))
852 pipe->entities |= 1 << entity->id;
853
854 /* Verify that the currently configured format matches the output of
855 * the connected subdev.
856 */
857 ret = iss_video_check_format(video, vfh);
858 if (ret < 0)
859 goto err_iss_video_check_format;
860
861 video->bpl_padding = ret;
862 video->bpl_value = vfh->format.fmt.pix.bytesperline;
863
864 /* Find the ISS video node connected at the far end of the pipeline and
865 * update the pipeline.
866 */
867 far_end = iss_video_far_end(video);
868
869 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
870 state = ISS_PIPELINE_STREAM_OUTPUT | ISS_PIPELINE_IDLE_OUTPUT;
871 pipe->input = far_end;
872 pipe->output = video;
873 } else {
874 if (far_end == NULL) {
875 ret = -EPIPE;
876 goto err_iss_video_check_format;
877 }
878
879 state = ISS_PIPELINE_STREAM_INPUT | ISS_PIPELINE_IDLE_INPUT;
880 pipe->input = video;
881 pipe->output = far_end;
882 }
883
884 spin_lock_irqsave(&pipe->lock, flags);
885 pipe->state &= ~ISS_PIPELINE_STREAM;
886 pipe->state |= state;
887 spin_unlock_irqrestore(&pipe->lock, flags);
888
889 /* Set the maximum time per frame as the value requested by userspace.
890 * This is a soft limit that can be overridden if the hardware doesn't
891 * support the request limit.
892 */
893 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
894 pipe->max_timeperframe = vfh->timeperframe;
895
896 video->queue = &vfh->queue;
897 INIT_LIST_HEAD(&video->dmaqueue);
898 spin_lock_init(&video->qlock);
899 video->error = false;
900 atomic_set(&pipe->frame_number, -1);
901
902 ret = vb2_streamon(&vfh->queue, type);
903 if (ret < 0)
904 goto err_iss_video_check_format;
905
906 /* In sensor-to-memory mode, the stream can be started synchronously
907 * to the stream on command. In memory-to-memory mode, it will be
908 * started when buffers are queued on both the input and output.
909 */
910 if (pipe->input == NULL) {
911 unsigned long flags;
912 ret = omap4iss_pipeline_set_stream(pipe,
913 ISS_PIPELINE_STREAM_CONTINUOUS);
914 if (ret < 0)
915 goto err_omap4iss_set_stream;
916 spin_lock_irqsave(&video->qlock, flags);
917 if (list_empty(&video->dmaqueue))
918 video->dmaqueue_flags |= ISS_VIDEO_DMAQUEUE_UNDERRUN;
919 spin_unlock_irqrestore(&video->qlock, flags);
920 }
921
922 mutex_unlock(&video->stream_lock);
923 return 0;
924
925err_omap4iss_set_stream:
926 vb2_streamoff(&vfh->queue, type);
927err_iss_video_check_format:
928 media_entity_pipeline_stop(&video->video.entity);
929err_media_entity_pipeline_start:
930 if (video->iss->pdata->set_constraints)
931 video->iss->pdata->set_constraints(video->iss, false);
932 video->queue = NULL;
933
934 mutex_unlock(&video->stream_lock);
935 return ret;
936}
937
938static int
939iss_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
940{
941 struct iss_video_fh *vfh = to_iss_video_fh(fh);
942 struct iss_video *video = video_drvdata(file);
943 struct iss_pipeline *pipe = to_iss_pipeline(&video->video.entity);
944 enum iss_pipeline_state state;
945 unsigned long flags;
946
947 if (type != video->type)
948 return -EINVAL;
949
950 mutex_lock(&video->stream_lock);
951
952 if (!vb2_is_streaming(&vfh->queue))
953 goto done;
954
955 /* Update the pipeline state. */
956 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
957 state = ISS_PIPELINE_STREAM_OUTPUT
958 | ISS_PIPELINE_QUEUE_OUTPUT;
959 else
960 state = ISS_PIPELINE_STREAM_INPUT
961 | ISS_PIPELINE_QUEUE_INPUT;
962
963 spin_lock_irqsave(&pipe->lock, flags);
964 pipe->state &= ~state;
965 spin_unlock_irqrestore(&pipe->lock, flags);
966
967 /* Stop the stream. */
968 omap4iss_pipeline_set_stream(pipe, ISS_PIPELINE_STREAM_STOPPED);
969 vb2_streamoff(&vfh->queue, type);
970 video->queue = NULL;
971
972 if (video->iss->pdata->set_constraints)
973 video->iss->pdata->set_constraints(video->iss, false);
974 media_entity_pipeline_stop(&video->video.entity);
975
976done:
977 mutex_unlock(&video->stream_lock);
978 return 0;
979}
980
981static int
982iss_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
983{
984 if (input->index > 0)
985 return -EINVAL;
986
987 strlcpy(input->name, "camera", sizeof(input->name));
988 input->type = V4L2_INPUT_TYPE_CAMERA;
989
990 return 0;
991}
992
993static int
994iss_video_g_input(struct file *file, void *fh, unsigned int *input)
995{
996 *input = 0;
997
998 return 0;
999}
1000
1001static int
1002iss_video_s_input(struct file *file, void *fh, unsigned int input)
1003{
1004 return input == 0 ? 0 : -EINVAL;
1005}
1006
1007static const struct v4l2_ioctl_ops iss_video_ioctl_ops = {
1008 .vidioc_querycap = iss_video_querycap,
1009 .vidioc_enum_fmt_vid_cap = iss_video_enum_format,
1010 .vidioc_g_fmt_vid_cap = iss_video_get_format,
1011 .vidioc_s_fmt_vid_cap = iss_video_set_format,
1012 .vidioc_try_fmt_vid_cap = iss_video_try_format,
1013 .vidioc_g_fmt_vid_out = iss_video_get_format,
1014 .vidioc_s_fmt_vid_out = iss_video_set_format,
1015 .vidioc_try_fmt_vid_out = iss_video_try_format,
1016 .vidioc_cropcap = iss_video_cropcap,
1017 .vidioc_g_crop = iss_video_get_crop,
1018 .vidioc_s_crop = iss_video_set_crop,
1019 .vidioc_g_parm = iss_video_get_param,
1020 .vidioc_s_parm = iss_video_set_param,
1021 .vidioc_reqbufs = iss_video_reqbufs,
1022 .vidioc_querybuf = iss_video_querybuf,
1023 .vidioc_qbuf = iss_video_qbuf,
1024 .vidioc_dqbuf = iss_video_dqbuf,
1025 .vidioc_streamon = iss_video_streamon,
1026 .vidioc_streamoff = iss_video_streamoff,
1027 .vidioc_enum_input = iss_video_enum_input,
1028 .vidioc_g_input = iss_video_g_input,
1029 .vidioc_s_input = iss_video_s_input,
1030};
1031
1032/* -----------------------------------------------------------------------------
1033 * V4L2 file operations
1034 */
1035
1036static int iss_video_open(struct file *file)
1037{
1038 struct iss_video *video = video_drvdata(file);
1039 struct iss_video_fh *handle;
1040 struct vb2_queue *q;
1041 int ret = 0;
1042
1043 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1044 if (handle == NULL)
1045 return -ENOMEM;
1046
1047 v4l2_fh_init(&handle->vfh, &video->video);
1048 v4l2_fh_add(&handle->vfh);
1049
1050 /* If this is the first user, initialise the pipeline. */
1051 if (omap4iss_get(video->iss) == NULL) {
1052 ret = -EBUSY;
1053 goto done;
1054 }
1055
1056 ret = omap4iss_pipeline_pm_use(&video->video.entity, 1);
1057 if (ret < 0) {
1058 omap4iss_put(video->iss);
1059 goto done;
1060 }
1061
1062 video->alloc_ctx = vb2_dma_contig_init_ctx(video->iss->dev);
1063 if (IS_ERR(video->alloc_ctx)) {
1064 ret = PTR_ERR(video->alloc_ctx);
1065 omap4iss_put(video->iss);
1066 goto done;
1067 }
1068
1069 q = &handle->queue;
1070
1071 q->type = video->type;
1072 q->io_modes = VB2_MMAP;
1073 q->drv_priv = handle;
1074 q->ops = &iss_video_vb2ops;
1075 q->mem_ops = &vb2_dma_contig_memops;
1076 q->buf_struct_size = sizeof(struct iss_buffer);
1077 q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1078
1079 ret = vb2_queue_init(q);
1080 if (ret) {
1081 omap4iss_put(video->iss);
1082 goto done;
1083 }
1084
1085 memset(&handle->format, 0, sizeof(handle->format));
1086 handle->format.type = video->type;
1087 handle->timeperframe.denominator = 1;
1088
1089 handle->video = video;
1090 file->private_data = &handle->vfh;
1091
1092done:
1093 if (ret < 0) {
1094 v4l2_fh_del(&handle->vfh);
1095 kfree(handle);
1096 }
1097
1098 return ret;
1099}
1100
1101static int iss_video_release(struct file *file)
1102{
1103 struct iss_video *video = video_drvdata(file);
1104 struct v4l2_fh *vfh = file->private_data;
1105 struct iss_video_fh *handle = to_iss_video_fh(vfh);
1106
1107 /* Disable streaming and free the buffers queue resources. */
1108 iss_video_streamoff(file, vfh, video->type);
1109
1110 omap4iss_pipeline_pm_use(&video->video.entity, 0);
1111
1112 /* Release the videobuf2 queue */
1113 vb2_queue_release(&handle->queue);
1114
1115 /* Release the file handle. */
1116 v4l2_fh_del(vfh);
1117 kfree(handle);
1118 file->private_data = NULL;
1119
1120 omap4iss_put(video->iss);
1121
1122 return 0;
1123}
1124
1125static unsigned int iss_video_poll(struct file *file, poll_table *wait)
1126{
1127 struct iss_video_fh *vfh = to_iss_video_fh(file->private_data);
1128
1129 return vb2_poll(&vfh->queue, file, wait);
1130}
1131
1132static int iss_video_mmap(struct file *file, struct vm_area_struct *vma)
1133{
1134 struct iss_video_fh *vfh = to_iss_video_fh(file->private_data);
1135
1136 return vb2_mmap(&vfh->queue, vma);
1137}
1138
1139static struct v4l2_file_operations iss_video_fops = {
1140 .owner = THIS_MODULE,
1141 .unlocked_ioctl = video_ioctl2,
1142 .open = iss_video_open,
1143 .release = iss_video_release,
1144 .poll = iss_video_poll,
1145 .mmap = iss_video_mmap,
1146};
1147
1148/* -----------------------------------------------------------------------------
1149 * ISS video core
1150 */
1151
1152static const struct iss_video_operations iss_video_dummy_ops = {
1153};
1154
1155int omap4iss_video_init(struct iss_video *video, const char *name)
1156{
1157 const char *direction;
1158 int ret;
1159
1160 switch (video->type) {
1161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1162 direction = "output";
1163 video->pad.flags = MEDIA_PAD_FL_SINK;
1164 break;
1165 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1166 direction = "input";
1167 video->pad.flags = MEDIA_PAD_FL_SOURCE;
1168 break;
1169
1170 default:
1171 return -EINVAL;
1172 }
1173
1174 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
1175 if (ret < 0)
1176 return ret;
1177
1178 mutex_init(&video->mutex);
1179 atomic_set(&video->active, 0);
1180
1181 spin_lock_init(&video->pipe.lock);
1182 mutex_init(&video->stream_lock);
1183
1184 /* Initialize the video device. */
1185 if (video->ops == NULL)
1186 video->ops = &iss_video_dummy_ops;
1187
1188 video->video.fops = &iss_video_fops;
1189 snprintf(video->video.name, sizeof(video->video.name),
1190 "OMAP4 ISS %s %s", name, direction);
1191 video->video.vfl_type = VFL_TYPE_GRABBER;
1192 video->video.release = video_device_release_empty;
1193 video->video.ioctl_ops = &iss_video_ioctl_ops;
1194 video->pipe.stream_state = ISS_PIPELINE_STREAM_STOPPED;
1195
1196 video_set_drvdata(&video->video, video);
1197
1198 return 0;
1199}
1200
1201void omap4iss_video_cleanup(struct iss_video *video)
1202{
1203 media_entity_cleanup(&video->video.entity);
1204 mutex_destroy(&video->stream_lock);
1205 mutex_destroy(&video->mutex);
1206}
1207
1208int omap4iss_video_register(struct iss_video *video, struct v4l2_device *vdev)
1209{
1210 int ret;
1211
1212 video->video.v4l2_dev = vdev;
1213
1214 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1215 if (ret < 0)
1216 dev_err(video->iss->dev,
1217 "%s: could not register video device (%d)\n",
1218 __func__, ret);
1219
1220 return ret;
1221}
1222
1223void omap4iss_video_unregister(struct iss_video *video)
1224{
1225 video_unregister_device(&video->video);
1226}
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h
new file mode 100644
index 000000000000..878e4a3082e7
--- /dev/null
+++ b/drivers/staging/media/omap4iss/iss_video.h
@@ -0,0 +1,204 @@
1/*
2 * TI OMAP4 ISS V4L2 Driver - Generic video node
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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#ifndef OMAP4_ISS_VIDEO_H
15#define OMAP4_ISS_VIDEO_H
16
17#include <linux/v4l2-mediabus.h>
18#include <media/media-entity.h>
19#include <media/v4l2-dev.h>
20#include <media/v4l2-fh.h>
21#include <media/videobuf2-core.h>
22#include <media/videobuf2-dma-contig.h>
23
24#define ISS_VIDEO_DRIVER_NAME "issvideo"
25#define ISS_VIDEO_DRIVER_VERSION "0.0.2"
26
27struct iss_device;
28struct iss_video;
29struct v4l2_mbus_framefmt;
30struct v4l2_pix_format;
31
32/*
33 * struct iss_format_info - ISS media bus format information
34 * @code: V4L2 media bus format code
35 * @truncated: V4L2 media bus format code for the same format truncated to 10
36 * bits. Identical to @code if the format is 10 bits wide or less.
37 * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
38 * format. Identical to @code if the format is not DPCM compressed.
39 * @flavor: V4L2 media bus format code for the same pixel layout but
40 * shifted to be 8 bits per pixel. =0 if format is not shiftable.
41 * @pixelformat: V4L2 pixel format FCC identifier
42 * @bpp: Bits per pixel
43 * @description: Human-readable format description
44 */
45struct iss_format_info {
46 enum v4l2_mbus_pixelcode code;
47 enum v4l2_mbus_pixelcode truncated;
48 enum v4l2_mbus_pixelcode uncompressed;
49 enum v4l2_mbus_pixelcode flavor;
50 u32 pixelformat;
51 unsigned int bpp;
52 const char *description;
53};
54
55enum iss_pipeline_stream_state {
56 ISS_PIPELINE_STREAM_STOPPED = 0,
57 ISS_PIPELINE_STREAM_CONTINUOUS = 1,
58 ISS_PIPELINE_STREAM_SINGLESHOT = 2,
59};
60
61enum iss_pipeline_state {
62 /* The stream has been started on the input video node. */
63 ISS_PIPELINE_STREAM_INPUT = 1,
64 /* The stream has been started on the output video node. */
65 ISS_PIPELINE_STREAM_OUTPUT = (1 << 1),
66 /* At least one buffer is queued on the input video node. */
67 ISS_PIPELINE_QUEUE_INPUT = (1 << 2),
68 /* At least one buffer is queued on the output video node. */
69 ISS_PIPELINE_QUEUE_OUTPUT = (1 << 3),
70 /* The input entity is idle, ready to be started. */
71 ISS_PIPELINE_IDLE_INPUT = (1 << 4),
72 /* The output entity is idle, ready to be started. */
73 ISS_PIPELINE_IDLE_OUTPUT = (1 << 5),
74 /* The pipeline is currently streaming. */
75 ISS_PIPELINE_STREAM = (1 << 6),
76};
77
78/*
79 * struct iss_pipeline - An OMAP4 ISS hardware pipeline
80 * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
81 * @error: A hardware error occurred during capture
82 */
83struct iss_pipeline {
84 struct media_pipeline pipe;
85 spinlock_t lock; /* Pipeline state and queue flags */
86 unsigned int state;
87 enum iss_pipeline_stream_state stream_state;
88 struct iss_video *input;
89 struct iss_video *output;
90 unsigned int entities;
91 atomic_t frame_number;
92 bool do_propagation; /* of frame number */
93 bool error;
94 struct v4l2_fract max_timeperframe;
95 struct v4l2_subdev *external;
96 unsigned int external_rate;
97 int external_bpp;
98};
99
100#define to_iss_pipeline(__e) \
101 container_of((__e)->pipe, struct iss_pipeline, pipe)
102
103static inline int iss_pipeline_ready(struct iss_pipeline *pipe)
104{
105 return pipe->state == (ISS_PIPELINE_STREAM_INPUT |
106 ISS_PIPELINE_STREAM_OUTPUT |
107 ISS_PIPELINE_QUEUE_INPUT |
108 ISS_PIPELINE_QUEUE_OUTPUT |
109 ISS_PIPELINE_IDLE_INPUT |
110 ISS_PIPELINE_IDLE_OUTPUT);
111}
112
113/*
114 * struct iss_buffer - ISS buffer
115 * @buffer: ISS video buffer
116 * @iss_addr: Physical address of the buffer.
117 */
118struct iss_buffer {
119 /* common v4l buffer stuff -- must be first */
120 struct vb2_buffer vb;
121 struct list_head list;
122 dma_addr_t iss_addr;
123};
124
125#define to_iss_buffer(buf) container_of(buf, struct iss_buffer, buffer)
126
127enum iss_video_dmaqueue_flags {
128 /* Set if DMA queue becomes empty when ISS_PIPELINE_STREAM_CONTINUOUS */
129 ISS_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0),
130 /* Set when queuing buffer to an empty DMA queue */
131 ISS_VIDEO_DMAQUEUE_QUEUED = (1 << 1),
132};
133
134#define iss_video_dmaqueue_flags_clr(video) \
135 ({ (video)->dmaqueue_flags = 0; })
136
137/*
138 * struct iss_video_operations - ISS video operations
139 * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF
140 * if there was no buffer previously queued.
141 */
142struct iss_video_operations {
143 int(*queue)(struct iss_video *video, struct iss_buffer *buffer);
144};
145
146struct iss_video {
147 struct video_device video;
148 enum v4l2_buf_type type;
149 struct media_pad pad;
150
151 struct mutex mutex; /* format and crop settings */
152 atomic_t active;
153
154 struct iss_device *iss;
155
156 unsigned int capture_mem;
157 unsigned int bpl_alignment; /* alignment value */
158 unsigned int bpl_zero_padding; /* whether the alignment is optional */
159 unsigned int bpl_max; /* maximum bytes per line value */
160 unsigned int bpl_value; /* bytes per line value */
161 unsigned int bpl_padding; /* padding at end of line */
162
163 /* Pipeline state */
164 struct iss_pipeline pipe;
165 struct mutex stream_lock; /* pipeline and stream states */
166 bool error;
167
168 /* Video buffers queue */
169 struct vb2_queue *queue;
170 spinlock_t qlock; /* protects dmaqueue and error */
171 struct list_head dmaqueue;
172 enum iss_video_dmaqueue_flags dmaqueue_flags;
173 struct vb2_alloc_ctx *alloc_ctx;
174
175 const struct iss_video_operations *ops;
176};
177
178#define to_iss_video(vdev) container_of(vdev, struct iss_video, video)
179
180struct iss_video_fh {
181 struct v4l2_fh vfh;
182 struct iss_video *video;
183 struct vb2_queue queue;
184 struct v4l2_format format;
185 struct v4l2_fract timeperframe;
186};
187
188#define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh)
189#define iss_video_queue_to_iss_video_fh(q) \
190 container_of(q, struct iss_video_fh, queue)
191
192int omap4iss_video_init(struct iss_video *video, const char *name);
193void omap4iss_video_cleanup(struct iss_video *video);
194int omap4iss_video_register(struct iss_video *video,
195 struct v4l2_device *vdev);
196void omap4iss_video_unregister(struct iss_video *video);
197struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video);
198void omap4iss_video_cancel_stream(struct iss_video *video);
199struct media_pad *omap4iss_video_remote_pad(struct iss_video *video);
200
201const struct iss_format_info *
202omap4iss_video_format_info(enum v4l2_mbus_pixelcode code);
203
204#endif /* OMAP4_ISS_VIDEO_H */
diff --git a/drivers/media/usb/sn9c102/Kconfig b/drivers/staging/media/sn9c102/Kconfig
index 6ebaf2940d06..c9aba59258d9 100644
--- a/drivers/media/usb/sn9c102/Kconfig
+++ b/drivers/staging/media/sn9c102/Kconfig
@@ -1,14 +1,17 @@
1config USB_SN9C102 1config USB_SN9C102
2 tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)" 2 tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
3 depends on VIDEO_V4L2 3 depends on VIDEO_V4L2 && MEDIA_USB_SUPPORT
4 ---help--- 4 ---help---
5 This driver is DEPRECATED please use the gspca sonixb and 5 This driver is DEPRECATED, please use the gspca sonixb and
6 sonixj modules instead. 6 sonixj modules instead.
7 7
8 Say Y here if you want support for cameras based on SONiX SN9C101, 8 Say Y here if you want support for cameras based on SONiX SN9C101,
9 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. 9 SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
10 10
11 See <file:Documentation/video4linux/sn9c102.txt> for more info. 11 See <file:drivers/staging/media/sn9c102/sn9c102.txt> for more info.
12
13 If you have webcams that are only supported by this driver and not by
14 the gspca driver, then contact the linux-media mailinglist.
12 15
13 To compile this driver as a module, choose M here: the 16 To compile this driver as a module, choose M here: the
14 module will be called sn9c102. 17 module will be called sn9c102.
diff --git a/drivers/media/usb/sn9c102/Makefile b/drivers/staging/media/sn9c102/Makefile
index 7ecd5a90c7c9..7ecd5a90c7c9 100644
--- a/drivers/media/usb/sn9c102/Makefile
+++ b/drivers/staging/media/sn9c102/Makefile
diff --git a/drivers/media/usb/sn9c102/sn9c102.h b/drivers/staging/media/sn9c102/sn9c102.h
index 8a917f060503..8a917f060503 100644
--- a/drivers/media/usb/sn9c102/sn9c102.h
+++ b/drivers/staging/media/sn9c102/sn9c102.h
diff --git a/Documentation/video4linux/sn9c102.txt b/drivers/staging/media/sn9c102/sn9c102.txt
index b4f67040403a..b4f67040403a 100644
--- a/Documentation/video4linux/sn9c102.txt
+++ b/drivers/staging/media/sn9c102/sn9c102.txt
diff --git a/drivers/media/usb/sn9c102/sn9c102_config.h b/drivers/staging/media/sn9c102/sn9c102_config.h
index 0f4e0378b071..0f4e0378b071 100644
--- a/drivers/media/usb/sn9c102/sn9c102_config.h
+++ b/drivers/staging/media/sn9c102/sn9c102_config.h
diff --git a/drivers/media/usb/sn9c102/sn9c102_core.c b/drivers/staging/media/sn9c102/sn9c102_core.c
index 2cb44de2b92c..2cb44de2b92c 100644
--- a/drivers/media/usb/sn9c102/sn9c102_core.c
+++ b/drivers/staging/media/sn9c102/sn9c102_core.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_devtable.h b/drivers/staging/media/sn9c102/sn9c102_devtable.h
index b3d2cc729657..b3d2cc729657 100644
--- a/drivers/media/usb/sn9c102/sn9c102_devtable.h
+++ b/drivers/staging/media/sn9c102/sn9c102_devtable.h
diff --git a/drivers/media/usb/sn9c102/sn9c102_hv7131d.c b/drivers/staging/media/sn9c102/sn9c102_hv7131d.c
index 2dce5c908c8e..2dce5c908c8e 100644
--- a/drivers/media/usb/sn9c102/sn9c102_hv7131d.c
+++ b/drivers/staging/media/sn9c102/sn9c102_hv7131d.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_hv7131r.c b/drivers/staging/media/sn9c102/sn9c102_hv7131r.c
index 4295887ff609..4295887ff609 100644
--- a/drivers/media/usb/sn9c102/sn9c102_hv7131r.c
+++ b/drivers/staging/media/sn9c102/sn9c102_hv7131r.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_mi0343.c b/drivers/staging/media/sn9c102/sn9c102_mi0343.c
index 1f5b09bec89c..1f5b09bec89c 100644
--- a/drivers/media/usb/sn9c102/sn9c102_mi0343.c
+++ b/drivers/staging/media/sn9c102/sn9c102_mi0343.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_mi0360.c b/drivers/staging/media/sn9c102/sn9c102_mi0360.c
index d973fc1973d9..d973fc1973d9 100644
--- a/drivers/media/usb/sn9c102/sn9c102_mi0360.c
+++ b/drivers/staging/media/sn9c102/sn9c102_mi0360.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_mt9v111.c b/drivers/staging/media/sn9c102/sn9c102_mt9v111.c
index 95986eb492e4..95986eb492e4 100644
--- a/drivers/media/usb/sn9c102/sn9c102_mt9v111.c
+++ b/drivers/staging/media/sn9c102/sn9c102_mt9v111.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_ov7630.c b/drivers/staging/media/sn9c102/sn9c102_ov7630.c
index 803712c29f02..803712c29f02 100644
--- a/drivers/media/usb/sn9c102/sn9c102_ov7630.c
+++ b/drivers/staging/media/sn9c102/sn9c102_ov7630.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_ov7660.c b/drivers/staging/media/sn9c102/sn9c102_ov7660.c
index 7977795d342b..7977795d342b 100644
--- a/drivers/media/usb/sn9c102/sn9c102_ov7660.c
+++ b/drivers/staging/media/sn9c102/sn9c102_ov7660.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_pas106b.c b/drivers/staging/media/sn9c102/sn9c102_pas106b.c
index 81cd969c1b7b..81cd969c1b7b 100644
--- a/drivers/media/usb/sn9c102/sn9c102_pas106b.c
+++ b/drivers/staging/media/sn9c102/sn9c102_pas106b.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_pas202bcb.c b/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c
index 2e86fdc86989..2e86fdc86989 100644
--- a/drivers/media/usb/sn9c102/sn9c102_pas202bcb.c
+++ b/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_sensor.h b/drivers/staging/media/sn9c102/sn9c102_sensor.h
index 3679970dba2c..3679970dba2c 100644
--- a/drivers/media/usb/sn9c102/sn9c102_sensor.h
+++ b/drivers/staging/media/sn9c102/sn9c102_sensor.h
diff --git a/drivers/media/usb/sn9c102/sn9c102_tas5110c1b.c b/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c
index 04cdfdde8564..04cdfdde8564 100644
--- a/drivers/media/usb/sn9c102/sn9c102_tas5110c1b.c
+++ b/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_tas5110d.c b/drivers/staging/media/sn9c102/sn9c102_tas5110d.c
index 9372e6f9fcff..9372e6f9fcff 100644
--- a/drivers/media/usb/sn9c102/sn9c102_tas5110d.c
+++ b/drivers/staging/media/sn9c102/sn9c102_tas5110d.c
diff --git a/drivers/media/usb/sn9c102/sn9c102_tas5130d1b.c b/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c
index a30bbc4389f5..a30bbc4389f5 100644
--- a/drivers/media/usb/sn9c102/sn9c102_tas5130d1b.c
+++ b/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
index d582c5b84c14..ce9e5aaf7fd4 100644
--- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
@@ -964,7 +964,7 @@ static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id std)
964{ 964{
965 struct solo_enc_dev *solo_enc = video_drvdata(file); 965 struct solo_enc_dev *solo_enc = video_drvdata(file);
966 966
967 return solo_set_video_type(solo_enc->solo_dev, std & V4L2_STD_PAL); 967 return solo_set_video_type(solo_enc->solo_dev, std & V4L2_STD_625_50);
968} 968}
969 969
970static int solo_enum_framesizes(struct file *file, void *priv, 970static int solo_enum_framesizes(struct file *file, void *priv,
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2.c b/drivers/staging/media/solo6x10/solo6x10-v4l2.c
index 7b26de3488da..47e72dac9b13 100644
--- a/drivers/staging/media/solo6x10/solo6x10-v4l2.c
+++ b/drivers/staging/media/solo6x10/solo6x10-v4l2.c
@@ -527,7 +527,7 @@ static int solo_g_std(struct file *file, void *priv, v4l2_std_id *i)
527 return 0; 527 return 0;
528} 528}
529 529
530int solo_set_video_type(struct solo_dev *solo_dev, bool type) 530int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz)
531{ 531{
532 int i; 532 int i;
533 533
@@ -537,7 +537,8 @@ int solo_set_video_type(struct solo_dev *solo_dev, bool type)
537 for (i = 0; i < solo_dev->nr_chans; i++) 537 for (i = 0; i < solo_dev->nr_chans; i++)
538 if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq)) 538 if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq))
539 return -EBUSY; 539 return -EBUSY;
540 solo_dev->video_type = type; 540 solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL :
541 SOLO_VO_FMT_TYPE_NTSC;
541 /* Reconfigure for the new standard */ 542 /* Reconfigure for the new standard */
542 solo_disp_init(solo_dev); 543 solo_disp_init(solo_dev);
543 solo_enc_init(solo_dev); 544 solo_enc_init(solo_dev);
@@ -551,7 +552,7 @@ static int solo_s_std(struct file *file, void *priv, v4l2_std_id std)
551{ 552{
552 struct solo_dev *solo_dev = video_drvdata(file); 553 struct solo_dev *solo_dev = video_drvdata(file);
553 554
554 return solo_set_video_type(solo_dev, std & V4L2_STD_PAL); 555 return solo_set_video_type(solo_dev, std & V4L2_STD_625_50);
555} 556}
556 557
557static int solo_s_ctrl(struct v4l2_ctrl *ctrl) 558static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h
index f1bbb8cb74e6..8964f8be158e 100644
--- a/drivers/staging/media/solo6x10/solo6x10.h
+++ b/drivers/staging/media/solo6x10/solo6x10.h
@@ -398,7 +398,7 @@ int solo_p2m_dma_desc(struct solo_dev *solo_dev,
398 int desc_cnt); 398 int desc_cnt);
399 399
400/* Global s_std ioctl */ 400/* Global s_std ioctl */
401int solo_set_video_type(struct solo_dev *solo_dev, bool type); 401int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz);
402void solo_update_mode(struct solo_enc_dev *solo_enc); 402void solo_update_mode(struct solo_enc_dev *solo_enc);
403 403
404/* Set the threshold for motion detection */ 404/* Set the threshold for motion detection */
diff --git a/include/linux/platform_data/vsp1.h b/include/linux/platform_data/vsp1.h
index a73a456d7f11..63170e2614b3 100644
--- a/include/linux/platform_data/vsp1.h
+++ b/include/linux/platform_data/vsp1.h
@@ -14,6 +14,8 @@
14#define __PLATFORM_VSP1_H__ 14#define __PLATFORM_VSP1_H__
15 15
16#define VSP1_HAS_LIF (1 << 0) 16#define VSP1_HAS_LIF (1 << 0)
17#define VSP1_HAS_LUT (1 << 1)
18#define VSP1_HAS_SRU (1 << 2)
17 19
18struct vsp1_platform_data { 20struct vsp1_platform_data {
19 unsigned int features; 21 unsigned int features;
diff --git a/include/media/adv7604.h b/include/media/adv7604.h
index dc004bc926c9..d262a3a922bd 100644
--- a/include/media/adv7604.h
+++ b/include/media/adv7604.h
@@ -78,11 +78,14 @@ enum adv7604_op_format_sel {
78 ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE2 = 0x8a, 78 ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE2 = 0x8a,
79}; 79};
80 80
81enum adv7604_drive_strength {
82 ADV7604_DR_STR_MEDIUM_LOW = 1,
83 ADV7604_DR_STR_MEDIUM_HIGH = 2,
84 ADV7604_DR_STR_HIGH = 3,
85};
86
81/* Platform dependent definition */ 87/* Platform dependent definition */
82struct adv7604_platform_data { 88struct adv7604_platform_data {
83 /* connector - HDMI or DVI? */
84 unsigned connector_hdmi:1;
85
86 /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */ 89 /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */
87 unsigned disable_pwrdnb:1; 90 unsigned disable_pwrdnb:1;
88 91
@@ -110,6 +113,15 @@ struct adv7604_platform_data {
110 unsigned replicate_av_codes:1; 113 unsigned replicate_av_codes:1;
111 unsigned invert_cbcr:1; 114 unsigned invert_cbcr:1;
112 115
116 /* IO register 0x06 */
117 unsigned inv_vs_pol:1;
118 unsigned inv_hs_pol:1;
119
120 /* IO register 0x14 */
121 enum adv7604_drive_strength dr_str_data;
122 enum adv7604_drive_strength dr_str_clk;
123 enum adv7604_drive_strength dr_str_sync;
124
113 /* IO register 0x30 */ 125 /* IO register 0x30 */
114 unsigned output_bus_lsb_to_msb:1; 126 unsigned output_bus_lsb_to_msb:1;
115 127
@@ -131,16 +143,20 @@ struct adv7604_platform_data {
131 u8 i2c_vdp; 143 u8 i2c_vdp;
132}; 144};
133 145
134/* 146enum adv7604_input_port {
135 * Mode of operation. 147 ADV7604_INPUT_HDMI_PORT_A,
136 * This is used as the input argument of the s_routing video op. 148 ADV7604_INPUT_HDMI_PORT_B,
137 */ 149 ADV7604_INPUT_HDMI_PORT_C,
138enum adv7604_mode { 150 ADV7604_INPUT_HDMI_PORT_D,
139 ADV7604_MODE_COMP, 151 ADV7604_INPUT_VGA_RGB,
140 ADV7604_MODE_GR, 152 ADV7604_INPUT_VGA_COMP,
141 ADV7604_MODE_HDMI,
142}; 153};
143 154
155#define ADV7604_EDID_PORT_A 0
156#define ADV7604_EDID_PORT_B 1
157#define ADV7604_EDID_PORT_C 2
158#define ADV7604_EDID_PORT_D 3
159
144#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000) 160#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000)
145#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) 161#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001)
146#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) 162#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002)
diff --git a/include/media/adv7842.h b/include/media/adv7842.h
index c02201d1c092..39322091e8b0 100644
--- a/include/media/adv7842.h
+++ b/include/media/adv7842.h
@@ -108,6 +108,13 @@ enum adv7842_select_input {
108 ADV7842_SELECT_SDP_YC, 108 ADV7842_SELECT_SDP_YC,
109}; 109};
110 110
111enum adv7842_drive_strength {
112 ADV7842_DR_STR_LOW = 0,
113 ADV7842_DR_STR_MEDIUM_LOW = 1,
114 ADV7842_DR_STR_MEDIUM_HIGH = 2,
115 ADV7842_DR_STR_HIGH = 3,
116};
117
111struct adv7842_sdp_csc_coeff { 118struct adv7842_sdp_csc_coeff {
112 bool manual; 119 bool manual;
113 uint16_t scaling; 120 uint16_t scaling;
@@ -131,13 +138,18 @@ struct adv7842_sdp_io_sync_adjustment {
131 uint16_t hs_width; 138 uint16_t hs_width;
132 uint16_t de_beg; 139 uint16_t de_beg;
133 uint16_t de_end; 140 uint16_t de_end;
141 uint8_t vs_beg_o;
142 uint8_t vs_beg_e;
143 uint8_t vs_end_o;
144 uint8_t vs_end_e;
145 uint8_t de_v_beg_o;
146 uint8_t de_v_beg_e;
147 uint8_t de_v_end_o;
148 uint8_t de_v_end_e;
134}; 149};
135 150
136/* Platform dependent definition */ 151/* Platform dependent definition */
137struct adv7842_platform_data { 152struct adv7842_platform_data {
138 /* connector - HDMI or DVI? */
139 unsigned connector_hdmi:1;
140
141 /* chip reset during probe */ 153 /* chip reset during probe */
142 unsigned chip_reset:1; 154 unsigned chip_reset:1;
143 155
@@ -156,12 +168,12 @@ struct adv7842_platform_data {
156 /* Default mode */ 168 /* Default mode */
157 enum adv7842_mode mode; 169 enum adv7842_mode mode;
158 170
171 /* Default input */
172 unsigned input;
173
159 /* Video standard */ 174 /* Video standard */
160 enum adv7842_vid_std_select vid_std_select; 175 enum adv7842_vid_std_select vid_std_select;
161 176
162 /* Input Color Space */
163 enum adv7842_inp_color_space inp_color_space;
164
165 /* Select output format */ 177 /* Select output format */
166 enum adv7842_op_format_sel op_format_sel; 178 enum adv7842_op_format_sel op_format_sel;
167 179
@@ -181,22 +193,37 @@ struct adv7842_platform_data {
181 unsigned output_bus_lsb_to_msb:1; 193 unsigned output_bus_lsb_to_msb:1;
182 194
183 /* IO register 0x14 */ 195 /* IO register 0x14 */
184 struct { 196 enum adv7842_drive_strength dr_str_data;
185 unsigned data:2; 197 enum adv7842_drive_strength dr_str_clk;
186 unsigned clock:2; 198 enum adv7842_drive_strength dr_str_sync;
187 unsigned sync:2; 199
188 } drive_strength; 200 /*
201 * IO register 0x19: Adjustment to the LLC DLL phase in
202 * increments of 1/32 of a clock period.
203 */
204 unsigned llc_dll_phase:5;
189 205
190 /* External RAM for 3-D comb or frame synchronizer */ 206 /* External RAM for 3-D comb or frame synchronizer */
191 unsigned sd_ram_size; /* ram size in MB */ 207 unsigned sd_ram_size; /* ram size in MB */
192 unsigned sd_ram_ddr:1; /* ddr or sdr sdram */ 208 unsigned sd_ram_ddr:1; /* ddr or sdr sdram */
193 209
194 /* Free run */ 210 /* HDMI free run, CP-reg 0xBA */
195 unsigned hdmi_free_run_mode; 211 unsigned hdmi_free_run_enable:1;
212 /* 0 = Mode 0: run when there is no TMDS clock
213 1 = Mode 1: run when there is no TMDS clock or the
214 video resolution does not match programmed one. */
215 unsigned hdmi_free_run_mode:1;
216
217 /* SDP free run, CP-reg 0xDD */
218 unsigned sdp_free_run_auto:1;
219 unsigned sdp_free_run_man_col_en:1;
220 unsigned sdp_free_run_cbar_en:1;
221 unsigned sdp_free_run_force:1;
196 222
197 struct adv7842_sdp_csc_coeff sdp_csc_coeff; 223 struct adv7842_sdp_csc_coeff sdp_csc_coeff;
198 224
199 struct adv7842_sdp_io_sync_adjustment sdp_io_sync; 225 struct adv7842_sdp_io_sync_adjustment sdp_io_sync_625;
226 struct adv7842_sdp_io_sync_adjustment sdp_io_sync_525;
200 227
201 /* i2c addresses */ 228 /* i2c addresses */
202 u8 i2c_sdp_io; 229 u8 i2c_sdp_io;
@@ -223,4 +250,8 @@ struct adv7842_platform_data {
223 * deinterlacer. */ 250 * deinterlacer. */
224#define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE) 251#define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE)
225 252
253#define ADV7842_EDID_PORT_A 0
254#define ADV7842_EDID_PORT_B 1
255#define ADV7842_EDID_PORT_VGA 2
256
226#endif 257#endif
diff --git a/include/media/atmel-isi.h b/include/media/atmel-isi.h
index 656823075709..2b023471ac89 100644
--- a/include/media/atmel-isi.h
+++ b/include/media/atmel-isi.h
@@ -56,6 +56,7 @@
56#define ISI_CFG1_FRATE_DIV_6 (5 << 8) 56#define ISI_CFG1_FRATE_DIV_6 (5 << 8)
57#define ISI_CFG1_FRATE_DIV_7 (6 << 8) 57#define ISI_CFG1_FRATE_DIV_7 (6 << 8)
58#define ISI_CFG1_FRATE_DIV_8 (7 << 8) 58#define ISI_CFG1_FRATE_DIV_8 (7 << 8)
59#define ISI_CFG1_FRATE_DIV_MASK (7 << 8)
59#define ISI_CFG1_DISCR (1 << 11) 60#define ISI_CFG1_DISCR (1 << 11)
60#define ISI_CFG1_FULL_MODE (1 << 12) 61#define ISI_CFG1_FULL_MODE (1 << 12)
61 62
@@ -66,6 +67,7 @@
66#define ISI_CFG2_YCC_SWAP_MODE_1 (1 << 28) 67#define ISI_CFG2_YCC_SWAP_MODE_1 (1 << 28)
67#define ISI_CFG2_YCC_SWAP_MODE_2 (2 << 28) 68#define ISI_CFG2_YCC_SWAP_MODE_2 (2 << 28)
68#define ISI_CFG2_YCC_SWAP_MODE_3 (3 << 28) 69#define ISI_CFG2_YCC_SWAP_MODE_3 (3 << 28)
70#define ISI_CFG2_YCC_SWAP_MODE_MASK (3 << 28)
69#define ISI_CFG2_IM_VSIZE_OFFSET 0 71#define ISI_CFG2_IM_VSIZE_OFFSET 0
70#define ISI_CFG2_IM_HSIZE_OFFSET 16 72#define ISI_CFG2_IM_HSIZE_OFFSET 16
71#define ISI_CFG2_IM_VSIZE_MASK (0x7FF << ISI_CFG2_IM_VSIZE_OFFSET) 73#define ISI_CFG2_IM_VSIZE_MASK (0x7FF << ISI_CFG2_IM_VSIZE_OFFSET)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 10df55187981..e00459185d20 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -24,6 +24,7 @@
24#define _MEDIA_ENTITY_H 24#define _MEDIA_ENTITY_H
25 25
26#include <linux/bitops.h> 26#include <linux/bitops.h>
27#include <linux/kernel.h>
27#include <linux/list.h> 28#include <linux/list.h>
28#include <linux/media.h> 29#include <linux/media.h>
29 30
diff --git a/include/media/omap4iss.h b/include/media/omap4iss.h
new file mode 100644
index 000000000000..0d7620db5e32
--- /dev/null
+++ b/include/media/omap4iss.h
@@ -0,0 +1,65 @@
1#ifndef ARCH_ARM_PLAT_OMAP4_ISS_H
2#define ARCH_ARM_PLAT_OMAP4_ISS_H
3
4#include <linux/i2c.h>
5
6struct iss_device;
7
8enum iss_interface_type {
9 ISS_INTERFACE_CSI2A_PHY1,
10 ISS_INTERFACE_CSI2B_PHY2,
11};
12
13/**
14 * struct iss_csiphy_lane: CSI2 lane position and polarity
15 * @pos: position of the lane
16 * @pol: polarity of the lane
17 */
18struct iss_csiphy_lane {
19 u8 pos;
20 u8 pol;
21};
22
23#define ISS_CSIPHY1_NUM_DATA_LANES 4
24#define ISS_CSIPHY2_NUM_DATA_LANES 1
25
26/**
27 * struct iss_csiphy_lanes_cfg - CSI2 lane configuration
28 * @data: Configuration of one or two data lanes
29 * @clk: Clock lane configuration
30 */
31struct iss_csiphy_lanes_cfg {
32 struct iss_csiphy_lane data[ISS_CSIPHY1_NUM_DATA_LANES];
33 struct iss_csiphy_lane clk;
34};
35
36/**
37 * struct iss_csi2_platform_data - CSI2 interface platform data
38 * @crc: Enable the cyclic redundancy check
39 * @vpclk_div: Video port output clock control
40 */
41struct iss_csi2_platform_data {
42 unsigned crc:1;
43 unsigned vpclk_div:2;
44 struct iss_csiphy_lanes_cfg lanecfg;
45};
46
47struct iss_subdev_i2c_board_info {
48 struct i2c_board_info *board_info;
49 int i2c_adapter_id;
50};
51
52struct iss_v4l2_subdevs_group {
53 struct iss_subdev_i2c_board_info *subdevs;
54 enum iss_interface_type interface;
55 union {
56 struct iss_csi2_platform_data csi2;
57 } bus; /* gcc < 4.6.0 chokes on anonymous union initializers */
58};
59
60struct iss_platform_data {
61 struct iss_v4l2_subdevs_group *subdevs;
62 void (*set_constraints)(struct iss_device *iss, bool enable);
63};
64
65#endif
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 6628f5d01f52..a20ed97d7d8a 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -193,6 +193,7 @@ void rc_map_init(void);
193#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" 193#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
194#define RC_MAP_WINFAST "rc-winfast" 194#define RC_MAP_WINFAST "rc-winfast"
195#define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe" 195#define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe"
196#define RC_MAP_SU3000 "rc-su3000"
196 197
197/* 198/*
198 * Please, do not just append newer Remote Controller names at the end. 199 * Please, do not just append newer Remote Controller names at the end.
diff --git a/include/media/saa6588.h b/include/media/saa6588.h
index 2c3c4420a4eb..b5ec1aa60ed5 100644
--- a/include/media/saa6588.h
+++ b/include/media/saa6588.h
@@ -27,6 +27,7 @@
27 27
28struct saa6588_command { 28struct saa6588_command {
29 unsigned int block_count; 29 unsigned int block_count;
30 bool nonblocking;
30 int result; 31 int result;
31 unsigned char __user *buffer; 32 unsigned char __user *buffer;
32 struct file *instance; 33 struct file *instance;
@@ -34,7 +35,6 @@ struct saa6588_command {
34}; 35};
35 36
36/* These ioctls are internal to the kernel */ 37/* These ioctls are internal to the kernel */
37#define SAA6588_CMD_OPEN _IOW('R', 1, int)
38#define SAA6588_CMD_CLOSE _IOW('R', 2, int) 38#define SAA6588_CMD_CLOSE _IOW('R', 2, int)
39#define SAA6588_CMD_READ _IOR('R', 3, int) 39#define SAA6588_CMD_READ _IOR('R', 3, int)
40#define SAA6588_CMD_POLL _IOR('R', 4, int) 40#define SAA6588_CMD_POLL _IOR('R', 4, int)
diff --git a/include/media/saa6752hs.h b/include/media/saa6752hs.h
deleted file mode 100644
index 3b8686ead80d..000000000000
--- a/include/media/saa6752hs.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 saa6752hs.h - definition for saa6752hs MPEG encoder
3
4 Copyright (C) 2003 Andrew de Quincey <adq@lidskialf.net>
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 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21
22/*
23 * Local variables:
24 * c-basic-offset: 8
25 * End:
26 */
diff --git a/include/media/si4713.h b/include/media/si4713.h
index ed7353e8a982..f98a0a7af61c 100644
--- a/include/media/si4713.h
+++ b/include/media/si4713.h
@@ -23,6 +23,8 @@
23 * Platform dependent definition 23 * Platform dependent definition
24 */ 24 */
25struct si4713_platform_data { 25struct si4713_platform_data {
26 const char * const *supply_names;
27 unsigned supplies;
26 int gpio_reset; /* < 0 if not used */ 28 int gpio_reset; /* < 0 if not used */
27}; 29};
28 30
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index 528cdaf622e1..803516775162 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -45,6 +45,10 @@ struct v4l2_fh {
45 struct list_head available; /* Dequeueable event */ 45 struct list_head available; /* Dequeueable event */
46 unsigned int navailable; 46 unsigned int navailable;
47 u32 sequence; 47 u32 sequence;
48
49#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
50 struct v4l2_m2m_ctx *m2m_ctx;
51#endif
48}; 52};
49 53
50/* 54/*
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 44542a20ab81..12ea5a6a4331 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -64,6 +64,9 @@ struct v4l2_m2m_queue_ctx {
64}; 64};
65 65
66struct v4l2_m2m_ctx { 66struct v4l2_m2m_ctx {
67 /* optional cap/out vb2 queues lock */
68 struct mutex *q_lock;
69
67/* private: internal use only */ 70/* private: internal use only */
68 struct v4l2_m2m_dev *m2m_dev; 71 struct v4l2_m2m_dev *m2m_dev;
69 72
@@ -229,5 +232,26 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
229 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx); 232 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
230} 233}
231 234
235/* v4l2 ioctl helpers */
236
237int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
238 struct v4l2_requestbuffers *rb);
239int v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh,
240 struct v4l2_create_buffers *create);
241int v4l2_m2m_ioctl_querybuf(struct file *file, void *fh,
242 struct v4l2_buffer *buf);
243int v4l2_m2m_ioctl_expbuf(struct file *file, void *fh,
244 struct v4l2_exportbuffer *eb);
245int v4l2_m2m_ioctl_qbuf(struct file *file, void *fh,
246 struct v4l2_buffer *buf);
247int v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh,
248 struct v4l2_buffer *buf);
249int v4l2_m2m_ioctl_streamon(struct file *file, void *fh,
250 enum v4l2_buf_type type);
251int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
252 enum v4l2_buf_type type);
253int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
254unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
255
232#endif /* _MEDIA_V4L2_MEM2MEM_H */ 256#endif /* _MEDIA_V4L2_MEM2MEM_H */
233 257
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h
index 3a8a84124b44..541cea4122e9 100644
--- a/include/media/v4l2-of.h
+++ b/include/media/v4l2-of.h
@@ -53,7 +53,6 @@ struct v4l2_of_bus_parallel {
53 * @port: identifier (value of reg property) of a port this endpoint belongs to 53 * @port: identifier (value of reg property) of a port this endpoint belongs to
54 * @id: identifier (value of reg property) of this endpoint 54 * @id: identifier (value of reg property) of this endpoint
55 * @local_node: pointer to device_node of this endpoint 55 * @local_node: pointer to device_node of this endpoint
56 * @remote: phandle to remote endpoint node
57 * @bus_type: bus type 56 * @bus_type: bus type
58 * @bus: bus configuration data structure 57 * @bus: bus configuration data structure
59 * @head: list head for this structure 58 * @head: list head for this structure
@@ -62,7 +61,6 @@ struct v4l2_of_endpoint {
62 unsigned int port; 61 unsigned int port;
63 unsigned int id; 62 unsigned int id;
64 const struct device_node *local_node; 63 const struct device_node *local_node;
65 const __be32 *remote;
66 enum v4l2_mbus_type bus_type; 64 enum v4l2_mbus_type bus_type;
67 union { 65 union {
68 struct v4l2_of_bus_parallel parallel; 66 struct v4l2_of_bus_parallel parallel;
@@ -72,8 +70,8 @@ struct v4l2_of_endpoint {
72}; 70};
73 71
74#ifdef CONFIG_OF 72#ifdef CONFIG_OF
75void v4l2_of_parse_endpoint(const struct device_node *node, 73int v4l2_of_parse_endpoint(const struct device_node *node,
76 struct v4l2_of_endpoint *link); 74 struct v4l2_of_endpoint *endpoint);
77struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent, 75struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
78 struct device_node *previous); 76 struct device_node *previous);
79struct device_node *v4l2_of_get_remote_port_parent( 77struct device_node *v4l2_of_get_remote_port_parent(
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 941055e9d125..bef53ce555d2 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -142,6 +142,7 @@ enum vb2_fileio_flags {
142/** 142/**
143 * enum vb2_buffer_state - current video buffer state 143 * enum vb2_buffer_state - current video buffer state
144 * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control 144 * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control
145 * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf
145 * @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver 146 * @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver
146 * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver 147 * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver
147 * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used 148 * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
@@ -154,6 +155,7 @@ enum vb2_fileio_flags {
154 */ 155 */
155enum vb2_buffer_state { 156enum vb2_buffer_state {
156 VB2_BUF_STATE_DEQUEUED, 157 VB2_BUF_STATE_DEQUEUED,
158 VB2_BUF_STATE_PREPARING,
157 VB2_BUF_STATE_PREPARED, 159 VB2_BUF_STATE_PREPARED,
158 VB2_BUF_STATE_QUEUED, 160 VB2_BUF_STATE_QUEUED,
159 VB2_BUF_STATE_ACTIVE, 161 VB2_BUF_STATE_ACTIVE,
@@ -250,10 +252,13 @@ struct vb2_buffer {
250 * receive buffers with @buf_queue callback before 252 * receive buffers with @buf_queue callback before
251 * @start_streaming is called; the driver gets the number 253 * @start_streaming is called; the driver gets the number
252 * of already queued buffers in count parameter; driver 254 * of already queued buffers in count parameter; driver
253 * can return an error if hardware fails or not enough 255 * can return an error if hardware fails, in that case all
254 * buffers has been queued, in such case all buffers that 256 * buffers that have been already given by the @buf_queue
255 * have been already given by the @buf_queue callback are 257 * callback are invalidated.
256 * invalidated. 258 * If there were not enough queued buffers to start
259 * streaming, then this callback returns -ENOBUFS, and the
260 * vb2 core will retry calling @start_streaming when a new
261 * buffer is queued.
257 * @stop_streaming: called when 'streaming' state must be disabled; driver 262 * @stop_streaming: called when 'streaming' state must be disabled; driver
258 * should stop any DMA transactions or wait until they 263 * should stop any DMA transactions or wait until they
259 * finish and give back all buffers it got from buf_queue() 264 * finish and give back all buffers it got from buf_queue()
@@ -321,6 +326,9 @@ struct v4l2_fh;
321 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued 326 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
322 * @alloc_ctx: memory type/allocator-specific contexts for each plane 327 * @alloc_ctx: memory type/allocator-specific contexts for each plane
323 * @streaming: current streaming state 328 * @streaming: current streaming state
329 * @retry_start_streaming: start_streaming() was called, but there were not enough
330 * buffers queued. If set, then retry calling start_streaming when
331 * queuing a new buffer.
324 * @fileio: file io emulator internal data, used only if emulator is active 332 * @fileio: file io emulator internal data, used only if emulator is active
325 */ 333 */
326struct vb2_queue { 334struct vb2_queue {
@@ -353,6 +361,7 @@ struct vb2_queue {
353 unsigned int plane_sizes[VIDEO_MAX_PLANES]; 361 unsigned int plane_sizes[VIDEO_MAX_PLANES];
354 362
355 unsigned int streaming:1; 363 unsigned int streaming:1;
364 unsigned int retry_start_streaming:1;
356 365
357 struct vb2_fileio_data *fileio; 366 struct vb2_fileio_data *fileio;
358}; 367};
@@ -491,6 +500,7 @@ int vb2_ioctl_expbuf(struct file *file, void *priv,
491 500
492int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma); 501int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma);
493int vb2_fop_release(struct file *file); 502int vb2_fop_release(struct file *file);
503int _vb2_fop_release(struct file *file, struct mutex *lock);
494ssize_t vb2_fop_write(struct file *file, const char __user *buf, 504ssize_t vb2_fop_write(struct file *file, const char __user *buf,
495 size_t count, loff_t *ppos); 505 size_t count, loff_t *ppos);
496ssize_t vb2_fop_read(struct file *file, char __user *buf, 506ssize_t vb2_fop_read(struct file *file, char __user *buf,
diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
new file mode 100644
index 000000000000..ef94ecad1c94
--- /dev/null
+++ b/include/trace/events/v4l2.h
@@ -0,0 +1,157 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM v4l2
3
4#if !defined(_TRACE_V4L2_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_V4L2_H
6
7#include <linux/tracepoint.h>
8
9#define show_type(type) \
10 __print_symbolic(type, \
11 { V4L2_BUF_TYPE_VIDEO_CAPTURE, "VIDEO_CAPTURE" }, \
12 { V4L2_BUF_TYPE_VIDEO_OUTPUT, "VIDEO_OUTPUT" }, \
13 { V4L2_BUF_TYPE_VIDEO_OVERLAY, "VIDEO_OVERLAY" }, \
14 { V4L2_BUF_TYPE_VBI_CAPTURE, "VBI_CAPTURE" }, \
15 { V4L2_BUF_TYPE_VBI_OUTPUT, "VBI_OUTPUT" }, \
16 { V4L2_BUF_TYPE_SLICED_VBI_CAPTURE, "SLICED_VBI_CAPTURE" }, \
17 { V4L2_BUF_TYPE_SLICED_VBI_OUTPUT, "SLICED_VBI_OUTPUT" }, \
18 { V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" },\
19 { V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" },\
20 { V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, "VIDEO_OUTPUT_MPLANE" }, \
21 { V4L2_BUF_TYPE_PRIVATE, "PRIVATE" })
22
23#define show_field(field) \
24 __print_symbolic(field, \
25 { V4L2_FIELD_ANY, "ANY" }, \
26 { V4L2_FIELD_NONE, "NONE" }, \
27 { V4L2_FIELD_TOP, "TOP" }, \
28 { V4L2_FIELD_BOTTOM, "BOTTOM" }, \
29 { V4L2_FIELD_INTERLACED, "INTERLACED" }, \
30 { V4L2_FIELD_SEQ_TB, "SEQ_TB" }, \
31 { V4L2_FIELD_SEQ_BT, "SEQ_BT" }, \
32 { V4L2_FIELD_ALTERNATE, "ALTERNATE" }, \
33 { V4L2_FIELD_INTERLACED_TB, "INTERLACED_TB" }, \
34 { V4L2_FIELD_INTERLACED_BT, "INTERLACED_BT" })
35
36#define show_timecode_type(type) \
37 __print_symbolic(type, \
38 { V4L2_TC_TYPE_24FPS, "24FPS" }, \
39 { V4L2_TC_TYPE_25FPS, "25FPS" }, \
40 { V4L2_TC_TYPE_30FPS, "30FPS" }, \
41 { V4L2_TC_TYPE_50FPS, "50FPS" }, \
42 { V4L2_TC_TYPE_60FPS, "60FPS" })
43
44#define show_flags(flags) \
45 __print_flags(flags, "|", \
46 { V4L2_BUF_FLAG_MAPPED, "MAPPED" }, \
47 { V4L2_BUF_FLAG_QUEUED, "QUEUED" }, \
48 { V4L2_BUF_FLAG_DONE, "DONE" }, \
49 { V4L2_BUF_FLAG_KEYFRAME, "KEYFRAME" }, \
50 { V4L2_BUF_FLAG_PFRAME, "PFRAME" }, \
51 { V4L2_BUF_FLAG_BFRAME, "BFRAME" }, \
52 { V4L2_BUF_FLAG_ERROR, "ERROR" }, \
53 { V4L2_BUF_FLAG_TIMECODE, "TIMECODE" }, \
54 { V4L2_BUF_FLAG_PREPARED, "PREPARED" }, \
55 { V4L2_BUF_FLAG_NO_CACHE_INVALIDATE, "NO_CACHE_INVALIDATE" }, \
56 { V4L2_BUF_FLAG_NO_CACHE_CLEAN, "NO_CACHE_CLEAN" }, \
57 { V4L2_BUF_FLAG_TIMESTAMP_MASK, "TIMESTAMP_MASK" }, \
58 { V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN, "TIMESTAMP_UNKNOWN" }, \
59 { V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC, "TIMESTAMP_MONOTONIC" }, \
60 { V4L2_BUF_FLAG_TIMESTAMP_COPY, "TIMESTAMP_COPY" })
61
62#define show_timecode_flags(flags) \
63 __print_flags(flags, "|", \
64 { V4L2_TC_FLAG_DROPFRAME, "DROPFRAME" }, \
65 { V4L2_TC_FLAG_COLORFRAME, "COLORFRAME" }, \
66 { V4L2_TC_USERBITS_USERDEFINED, "USERBITS_USERDEFINED" }, \
67 { V4L2_TC_USERBITS_8BITCHARS, "USERBITS_8BITCHARS" })
68
69#define V4L2_TRACE_EVENT(event_name) \
70 TRACE_EVENT(event_name, \
71 TP_PROTO(int minor, struct v4l2_buffer *buf), \
72 \
73 TP_ARGS(minor, buf), \
74 \
75 TP_STRUCT__entry( \
76 __field(int, minor) \
77 __field(u32, index) \
78 __field(u32, type) \
79 __field(u32, bytesused) \
80 __field(u32, flags) \
81 __field(u32, field) \
82 __field(s64, timestamp) \
83 __field(u32, timecode_type) \
84 __field(u32, timecode_flags) \
85 __field(u8, timecode_frames) \
86 __field(u8, timecode_seconds) \
87 __field(u8, timecode_minutes) \
88 __field(u8, timecode_hours) \
89 __field(u8, timecode_userbits0) \
90 __field(u8, timecode_userbits1) \
91 __field(u8, timecode_userbits2) \
92 __field(u8, timecode_userbits3) \
93 __field(u32, sequence) \
94 ), \
95 \
96 TP_fast_assign( \
97 __entry->minor = minor; \
98 __entry->index = buf->index; \
99 __entry->type = buf->type; \
100 __entry->bytesused = buf->bytesused; \
101 __entry->flags = buf->flags; \
102 __entry->field = buf->field; \
103 __entry->timestamp = \
104 timeval_to_ns(&buf->timestamp); \
105 __entry->timecode_type = buf->timecode.type; \
106 __entry->timecode_flags = buf->timecode.flags; \
107 __entry->timecode_frames = \
108 buf->timecode.frames; \
109 __entry->timecode_seconds = \
110 buf->timecode.seconds; \
111 __entry->timecode_minutes = \
112 buf->timecode.minutes; \
113 __entry->timecode_hours = buf->timecode.hours; \
114 __entry->timecode_userbits0 = \
115 buf->timecode.userbits[0]; \
116 __entry->timecode_userbits1 = \
117 buf->timecode.userbits[1]; \
118 __entry->timecode_userbits2 = \
119 buf->timecode.userbits[2]; \
120 __entry->timecode_userbits3 = \
121 buf->timecode.userbits[3]; \
122 __entry->sequence = buf->sequence; \
123 ), \
124 \
125 TP_printk("minor = %d, index = %u, type = %s, " \
126 "bytesused = %u, flags = %s, " \
127 "field = %s, timestamp = %llu, timecode = { " \
128 "type = %s, flags = %s, frames = %u, " \
129 "seconds = %u, minutes = %u, hours = %u, " \
130 "userbits = { %u %u %u %u } }, " \
131 "sequence = %u", __entry->minor, \
132 __entry->index, show_type(__entry->type), \
133 __entry->bytesused, \
134 show_flags(__entry->flags), \
135 show_field(__entry->field), \
136 __entry->timestamp, \
137 show_timecode_type(__entry->timecode_type), \
138 show_timecode_flags(__entry->timecode_flags), \
139 __entry->timecode_frames, \
140 __entry->timecode_seconds, \
141 __entry->timecode_minutes, \
142 __entry->timecode_hours, \
143 __entry->timecode_userbits0, \
144 __entry->timecode_userbits1, \
145 __entry->timecode_userbits2, \
146 __entry->timecode_userbits3, \
147 __entry->sequence \
148 ) \
149 )
150
151V4L2_TRACE_EVENT(v4l2_dqbuf);
152V4L2_TRACE_EVENT(v4l2_qbuf);
153
154#endif /* if !defined(_TRACE_V4L2_H) || defined(TRACE_HEADER_MULTI_READ) */
155
156/* This part must be outside protection */
157#include <trace/define_trace.h>
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index ed49574ad757..d847c760e8f0 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -98,6 +98,7 @@ struct media_entity_desc {
98 98
99#define MEDIA_PAD_FL_SINK (1 << 0) 99#define MEDIA_PAD_FL_SINK (1 << 0)
100#define MEDIA_PAD_FL_SOURCE (1 << 1) 100#define MEDIA_PAD_FL_SOURCE (1 << 1)
101#define MEDIA_PAD_FL_MUST_CONNECT (1 << 2)
101 102
102struct media_pad_desc { 103struct media_pad_desc {
103 __u32 entity; /* entity ID */ 104 __u32 entity; /* entity ID */
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 1666aabbbb86..2cbe605bbe04 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -164,6 +164,10 @@ enum v4l2_colorfx {
164 * this driver */ 164 * this driver */
165#define V4L2_CID_USER_TI_VPE_BASE (V4L2_CID_USER_BASE + 0x1050) 165#define V4L2_CID_USER_TI_VPE_BASE (V4L2_CID_USER_BASE + 0x1050)
166 166
167/* The base for the saa7134 driver controls.
168 * We reserve 16 controls for this driver. */
169#define V4L2_CID_USER_SAA7134_BASE (V4L2_CID_USER_BASE + 0x1060)
170
167/* MPEG-class control IDs */ 171/* MPEG-class control IDs */
168/* The MPEG controls are applicable to all codec controls 172/* The MPEG controls are applicable to all codec controls
169 * and the 'MPEG' part of the define is historical */ 173 * and the 'MPEG' part of the define is historical */
@@ -554,6 +558,11 @@ enum v4l2_vp8_golden_frame_sel {
554 V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV = 0, 558 V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV = 0,
555 V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD = 1, 559 V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD = 1,
556}; 560};
561#define V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (V4L2_CID_MPEG_BASE+507)
562#define V4L2_CID_MPEG_VIDEO_VPX_MAX_QP (V4L2_CID_MPEG_BASE+508)
563#define V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP (V4L2_CID_MPEG_BASE+509)
564#define V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (V4L2_CID_MPEG_BASE+510)
565#define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511)
557 566
558/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ 567/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
559#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) 568#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h
index a9601257bb43..b5c3aab6e82c 100644
--- a/include/uapi/linux/v4l2-mediabus.h
+++ b/include/uapi/linux/v4l2-mediabus.h
@@ -110,6 +110,9 @@ enum v4l2_mbus_pixelcode {
110 110
111 /* S5C73M3 sensor specific interleaved UYVY and JPEG */ 111 /* S5C73M3 sensor specific interleaved UYVY and JPEG */
112 V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 = 0x5001, 112 V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 = 0x5001,
113
114 /* HSV - next is 0x6002 */
115 V4L2_MBUS_FMT_AHSV8888_1X32 = 0x6001,
113}; 116};
114 117
115/** 118/**
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 437f1b0f8937..6ae7bbe988cc 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -207,8 +207,8 @@ enum v4l2_priority {
207struct v4l2_rect { 207struct v4l2_rect {
208 __s32 left; 208 __s32 left;
209 __s32 top; 209 __s32 top;
210 __s32 width; 210 __u32 width;
211 __s32 height; 211 __u32 height;
212}; 212};
213 213
214struct v4l2_fract { 214struct v4l2_fract {
diff --git a/include/uapi/linux/vsp1.h b/include/uapi/linux/vsp1.h
new file mode 100644
index 000000000000..e18858f6e865
--- /dev/null
+++ b/include/uapi/linux/vsp1.h
@@ -0,0 +1,34 @@
1/*
2 * vsp1.h
3 *
4 * Renesas R-Car VSP1 - User-space API
5 *
6 * Copyright (C) 2013 Renesas Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __VSP1_USER_H__
16#define __VSP1_USER_H__
17
18#include <linux/types.h>
19#include <linux/videodev2.h>
20
21/*
22 * Private IOCTLs
23 *
24 * VIDIOC_VSP1_LUT_CONFIG - Configure the lookup table
25 */
26
27#define VIDIOC_VSP1_LUT_CONFIG \
28 _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct vsp1_lut_config)
29
30struct vsp1_lut_config {
31 u32 lut[256];
32};
33
34#endif /* __VSP1_USER_H__ */