aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 13:21:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 13:21:51 -0400
commitab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (patch)
tree987ec6c263f3dfa4a7a6f9ce4d5ece47cbc12e29
parentf9369910a6225b8d4892c3f20ae740a711cd5ace (diff)
parent71006fb22b0f5a2045605b3887ee99a0e9adafe4 (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: - some V4L2 API updates needed by embedded devices - DVB API extensions for ATSC-MH delivery system, used in US for mobile TV - new tuners for fc0011/0012/0013 and tua9001 - a new dvb driver for af9033/9035 - a new ATSC-MH frontend (lg2160) - new remote controller keymaps - Removal of a few legacy webcam driver that got replaced by gspca on several kernel versions ago - a new driver for Exynos 4/5 webcams(s5pp fimc-lite) - a new webcam sensor driver (smiapp) - a new video input driver for embedded (sta2x1xx) - several improvements, fixes, cleanups, etc inside the drivers. Manually fix up conflicts due to err() -> dev_err() conversion in drivers/staging/media/easycap/easycap_main.c * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (484 commits) [media] saa7134-cards: Remove a PCI entry added by mistake [media] radio-sf16fmi: add support for SF16-FMD [media] rc-loopback: remove duplicate line [media] patch for Asus My Cinema PS3-100 (1043:48cd) [media] au0828: Move the Kconfig knob under V4L_USB_DRIVERS [media] em28xx: simple comment fix [media] [resend] radio-sf16fmr2: add PnP support for SF16-FMD2 [media] smiapp: Use v4l2_ctrl_new_int_menu() instead of v4l2_ctrl_new_custom() [media] smiapp: Add support for 8-bit uncompressed formats [media] smiapp: Allow generic quirk registers [media] smiapp: Use non-binning limits if the binning limit is zero [media] smiapp: Initialise rval in smiapp_read_nvm() [media] smiapp: Round minimum pre_pll up rather than down in ip_clk_freq check [media] smiapp: Use 8-bit reads only before identifying the sensor [media] smiapp: Quirk for sensors that only do 8-bit reads [media] smiapp: Pass struct sensor to register writing commands instead of i2c_client [media] smiapp: Allow using external clock from the clock framework [media] zl10353: change .read_snr() to report SNR as a 0.1 dB [media] media: add support to gspca/pac7302.c for 093a:2627 (Genius FaceCam 300) [media] m88rs2000 - only flip bit 2 on reg 0x70 on 16th try ...
-rw-r--r--Documentation/DocBook/media/Makefile4
-rw-r--r--Documentation/DocBook/media/dvb/dvbproperty.xml160
-rw-r--r--Documentation/DocBook/media/v4l/biblio.xml29
-rw-r--r--Documentation/DocBook/media/v4l/common.xml38
-rw-r--r--Documentation/DocBook/media/v4l/compat.xml75
-rw-r--r--Documentation/DocBook/media/v4l/controls.xml708
-rw-r--r--Documentation/DocBook/media/v4l/dev-subdev.xml202
-rw-r--r--Documentation/DocBook/media/v4l/io.xml12
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt-srggb10.xml2
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml29
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt.xml6
-rw-r--r--Documentation/DocBook/media/v4l/subdev-image-processing-crop.dia614
-rw-r--r--Documentation/DocBook/media/v4l/subdev-image-processing-crop.svg63
-rw-r--r--Documentation/DocBook/media/v4l/subdev-image-processing-full.dia1588
-rw-r--r--Documentation/DocBook/media/v4l/subdev-image-processing-full.svg163
-rw-r--r--Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.dia1152
-rw-r--r--Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.svg116
-rw-r--r--Documentation/DocBook/media/v4l/v4l2.xml44
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-create-bufs.xml16
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-cropcap.xml4
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml211
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml4
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml119
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml4
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enuminput.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enumoutput.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-crop.xml4
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml130
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml26
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-fmt.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-frequency.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-parm.xml5
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-sliced-vbi-cap.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-tuner.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml4
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml104
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-queryctrl.xml41
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-reqbufs.xml7
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml5
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-subdev-g-crop.xml9
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml228
-rwxr-xr-xDocumentation/dvb/get_dvb_firmware20
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--Documentation/media-framework.txt19
-rw-r--r--Documentation/video4linux/4CCs.txt32
-rw-r--r--Documentation/video4linux/gspca.txt1
-rw-r--r--Documentation/video4linux/v4l2-controls.txt21
-rw-r--r--Documentation/video4linux/v4l2-framework.txt106
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2_cam.h2
-rw-r--r--drivers/input/ff-memless.c3
-rw-r--r--drivers/media/common/saa7146_fops.c126
-rw-r--r--drivers/media/common/saa7146_hlp.c23
-rw-r--r--drivers/media/common/saa7146_vbi.c54
-rw-r--r--drivers/media/common/saa7146_video.c367
-rw-r--r--drivers/media/common/tuners/Kconfig27
-rw-r--r--drivers/media/common/tuners/Makefile4
-rw-r--r--drivers/media/common/tuners/fc0011.c524
-rw-r--r--drivers/media/common/tuners/fc0011.h41
-rw-r--r--drivers/media/common/tuners/fc0012-priv.h43
-rw-r--r--drivers/media/common/tuners/fc0012.c467
-rw-r--r--drivers/media/common/tuners/fc0012.h44
-rw-r--r--drivers/media/common/tuners/fc0013-priv.h44
-rw-r--r--drivers/media/common/tuners/fc0013.c634
-rw-r--r--drivers/media/common/tuners/fc0013.h57
-rw-r--r--drivers/media/common/tuners/fc001x-common.h39
-rw-r--r--drivers/media/common/tuners/tua9001.c215
-rw-r--r--drivers/media/common/tuners/tua9001.h46
-rw-r--r--drivers/media/common/tuners/tua9001_priv.h34
-rw-r--r--drivers/media/common/tuners/xc5000.c7
-rw-r--r--drivers/media/common/tuners/xc5000.h2
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c2
-rw-r--r--drivers/media/dvb/ddbridge/ddbridge-core.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c10
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c80
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h18
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig13
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c495
-rw-r--r--drivers/media/dvb/dvb-usb/af9035.c1242
-rw-r--r--drivers/media/dvb/dvb-usb/af9035.h113
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c24
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h12
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c12
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c76
-rw-r--r--drivers/media/dvb/dvb-usb/it913x.c4
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c5
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf-tuner.c1
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.c850
-rw-r--r--drivers/media/dvb/dvb-usb/rtl28xxu.c28
-rw-r--r--drivers/media/dvb/frontends/Kconfig35
-rw-r--r--drivers/media/dvb/frontends/Makefile7
-rw-r--r--drivers/media/dvb/frontends/af9013.c13
-rw-r--r--drivers/media/dvb/frontends/af9033.c980
-rw-r--r--drivers/media/dvb/frontends/af9033.h75
-rw-r--r--drivers/media/dvb/frontends/af9033_priv.h470
-rw-r--r--drivers/media/dvb/frontends/au8522_common.c259
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c215
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h2
-rw-r--r--drivers/media/dvb/frontends/cx24110.c7
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_core.c4
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c5
-rw-r--r--drivers/media/dvb/frontends/dib9000.c131
-rw-r--r--drivers/media/dvb/frontends/drxd.h14
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c18
-rw-r--r--drivers/media/dvb/frontends/drxk_map.h2
-rw-r--r--drivers/media/dvb/frontends/ds3000.c5
-rw-r--r--drivers/media/dvb/frontends/it913x-fe.c26
-rw-r--r--drivers/media/dvb/frontends/lg2160.c1468
-rw-r--r--drivers/media/dvb/frontends/lg2160.h84
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c3
-rw-r--r--drivers/media/dvb/frontends/m88rs2000.c29
-rw-r--r--drivers/media/dvb/frontends/rtl2830.c201
-rw-r--r--drivers/media/dvb/frontends/rtl2830_priv.h1
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c8
-rw-r--r--drivers/media/dvb/frontends/stb6100.c3
-rw-r--r--drivers/media/dvb/frontends/stv0297.c2
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c2
-rw-r--r--drivers/media/dvb/frontends/stv090x.c2
-rw-r--r--drivers/media/dvb/frontends/zl10353.c5
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c3
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c3
-rw-r--r--drivers/media/dvb/mantis/mantis_dma.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_evm.c3
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c4
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c8
-rw-r--r--drivers/media/dvb/siano/smssdio.c4
-rw-r--r--drivers/media/dvb/siano/smsusb.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c72
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c6
-rw-r--r--drivers/media/media-entity.c57
-rw-r--r--drivers/media/radio/Kconfig4
-rw-r--r--drivers/media/radio/dsbr100.c528
-rw-r--r--drivers/media/radio/radio-gemtek.c25
-rw-r--r--drivers/media/radio/radio-isa.c173
-rw-r--r--drivers/media/radio/radio-isa.h9
-rw-r--r--drivers/media/radio/radio-keene.c36
-rw-r--r--drivers/media/radio/radio-mr800.c524
-rw-r--r--drivers/media/radio/radio-rtrack2.c1
-rw-r--r--drivers/media/radio/radio-sf16fmi.c14
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c144
-rw-r--r--drivers/media/radio/radio-timb.c2
-rw-r--r--drivers/media/radio/saa7706h.c2
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c305
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c65
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c265
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h14
-rw-r--r--drivers/media/radio/tef6862.c2
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.c4
-rw-r--r--drivers/media/rc/Kconfig1
-rw-r--r--drivers/media/rc/ati_remote.c146
-rw-r--r--drivers/media/rc/fintek-cir.c13
-rw-r--r--drivers/media/rc/imon.c2
-rw-r--r--drivers/media/rc/ir-raw.c8
-rw-r--r--drivers/media/rc/ir-sanyo-decoder.c4
-rw-r--r--drivers/media/rc/ite-cir.c14
-rw-r--r--drivers/media/rc/keymaps/Makefile3
-rw-r--r--drivers/media/rc/keymaps/rc-asus-ps3-100.c91
-rw-r--r--drivers/media/rc/keymaps/rc-it913x-v2.c2
-rw-r--r--drivers/media/rc/keymaps/rc-medion-x10-digitainer.c123
-rw-r--r--drivers/media/rc/keymaps/rc-medion-x10-or2x.c108
-rw-r--r--drivers/media/rc/mceusb.c5
-rw-r--r--drivers/media/rc/nuvoton-cir.c26
-rw-r--r--drivers/media/rc/rc-loopback.c1
-rw-r--r--drivers/media/rc/redrat3.c2
-rw-r--r--drivers/media/video/Kconfig48
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/adp1653.c9
-rw-r--r--drivers/media/video/adv7180.c417
-rw-r--r--drivers/media/video/adv7343.c4
-rw-r--r--drivers/media/video/aptina-pll.c5
-rw-r--r--drivers/media/video/arv.c7
-rw-r--r--drivers/media/video/as3645a.c10
-rw-r--r--drivers/media/video/atmel-isi.c18
-rw-r--r--drivers/media/video/au0828/Kconfig3
-rw-r--r--drivers/media/video/au0828/au0828-cards.c2
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c27
-rw-r--r--drivers/media/video/au0828/au0828-video.c25
-rw-r--r--drivers/media/video/blackfin/bfin_capture.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/video/bw-qcam.c132
-rw-r--r--drivers/media/video/c-qcam.c140
-rw-r--r--drivers/media/video/cpia2/cpia2.h34
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c142
-rw-r--r--drivers/media/video/cpia2/cpia2_usb.c78
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c850
-rw-r--r--drivers/media/video/cpia2/cpia2dev.h50
-rw-r--r--drivers/media/video/cx18/cx18-alsa-main.c1
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c10
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c2
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c6
-rw-r--r--drivers/media/video/cx18/cx18-streams.c3
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c18
-rw-r--r--drivers/media/video/cx231xx/cx231xx-audio.c18
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c148
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c76
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c6
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c20
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c9
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c7
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c7
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c4
-rw-r--r--drivers/media/video/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.c3
-rw-r--r--drivers/media/video/cx25821/cx25821-core.c14
-rw-r--r--drivers/media/video/cx25821/cx25821-i2c.c3
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.c13
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.c3
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.c3
-rw-r--r--drivers/media/video/cx25821/cx25821-video.c25
-rw-r--r--drivers/media/video/cx25821/cx25821-video.h2
-rw-r--r--drivers/media/video/cx25840/cx25840-ir.c6
-rw-r--r--drivers/media/video/davinci/Kconfig1
-rw-r--r--drivers/media/video/davinci/vpbe_display.c4
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2
-rw-r--r--drivers/media/video/davinci/vpif_capture.c4
-rw-r--r--drivers/media/video/davinci/vpif_display.c4
-rw-r--r--drivers/media/video/em28xx/Kconfig4
-rw-r--r--drivers/media/video/em28xx/Makefile5
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c11
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c81
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c30
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c11
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c250
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c13
-rw-r--r--drivers/media/video/em28xx/em28xx.h60
-rw-r--r--drivers/media/video/et61x251/Kconfig18
-rw-r--r--drivers/media/video/et61x251/Makefile4
-rw-r--r--drivers/media/video/et61x251/et61x251.h213
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c2683
-rw-r--r--drivers/media/video/et61x251/et61x251_sensor.h108
-rw-r--r--drivers/media/video/et61x251/et61x251_tas5130d1b.c143
-rw-r--r--drivers/media/video/fsl-viu.c4
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/autogain_functions.c178
-rw-r--r--drivers/media/video/gspca/autogain_functions.h6
-rw-r--r--drivers/media/video/gspca/conex.c4
-rw-r--r--drivers/media/video/gspca/finepix.c18
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c3
-rw-r--r--drivers/media/video/gspca/gspca.c545
-rw-r--r--drivers/media/video/gspca/gspca.h26
-rw-r--r--drivers/media/video/gspca/jl2005bcd.c10
-rw-r--r--drivers/media/video/gspca/mars.c292
-rw-r--r--drivers/media/video/gspca/nw80x.c2
-rw-r--r--drivers/media/video/gspca/ov519.c10
-rw-r--r--drivers/media/video/gspca/ov534.c146
-rw-r--r--drivers/media/video/gspca/pac207.c336
-rw-r--r--drivers/media/video/gspca/pac7302.c185
-rw-r--r--drivers/media/video/gspca/pac7311.c505
-rw-r--r--drivers/media/video/gspca/sn9c20x.c594
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c5
-rw-r--r--drivers/media/video/gspca/sq905.c12
-rw-r--r--drivers/media/video/gspca/sq905c.c10
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c21
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.h3
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c143
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h7
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c359
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h12
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h4
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c236
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.h4
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c198
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h8
-rw-r--r--drivers/media/video/gspca/topro.c6
-rw-r--r--drivers/media/video/gspca/vicam.c13
-rw-r--r--drivers/media/video/gspca/zc3xx.c620
-rw-r--r--drivers/media/video/hdpvr/hdpvr-control.c2
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c2
-rw-r--r--drivers/media/video/hexium_gemini.c129
-rw-r--r--drivers/media/video/hexium_orion.c24
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c4
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c2
-rw-r--r--drivers/media/video/m5mols/m5mols.h81
-rw-r--r--drivers/media/video/m5mols/m5mols_capture.c11
-rw-r--r--drivers/media/video/m5mols/m5mols_controls.c479
-rw-r--r--drivers/media/video/m5mols/m5mols_core.c93
-rw-r--r--drivers/media/video/m5mols/m5mols_reg.h1
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c1
-rw-r--r--drivers/media/video/mem2mem_testdev.c6
-rw-r--r--drivers/media/video/meye.c2
-rw-r--r--drivers/media/video/msp3400-driver.c15
-rw-r--r--drivers/media/video/mt9m032.c4
-rw-r--r--drivers/media/video/mt9p031.c161
-rw-r--r--drivers/media/video/mt9t112.c1
-rw-r--r--drivers/media/video/mt9v032.c2
-rw-r--r--drivers/media/video/mx1_camera.c14
-rw-r--r--drivers/media/video/mx2_camera.c78
-rw-r--r--drivers/media/video/mx2_emmaprp.c8
-rw-r--r--drivers/media/video/mx3_camera.c41
-rw-r--r--drivers/media/video/mxb.c351
-rw-r--r--drivers/media/video/mxb.h42
-rw-r--r--drivers/media/video/omap1_camera.c22
-rw-r--r--drivers/media/video/omap24xxcam-dma.c20
-rw-r--r--drivers/media/video/omap24xxcam.c3
-rw-r--r--drivers/media/video/omap24xxcam.h14
-rw-r--r--drivers/media/video/omap3isp/isp.c59
-rw-r--r--drivers/media/video/omap3isp/isp.h8
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c256
-rw-r--r--drivers/media/video/omap3isp/ispccdc.h12
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c24
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c21
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.h1
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.c4
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.h15
-rw-r--r--drivers/media/video/omap3isp/isppreview.c634
-rw-r--r--drivers/media/video/omap3isp/isppreview.h76
-rw-r--r--drivers/media/video/omap3isp/ispqueue.h2
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c139
-rw-r--r--drivers/media/video/omap3isp/ispstat.c2
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c303
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h5
-rw-r--r--drivers/media/video/ov5642.c2
-rw-r--r--drivers/media/video/pms.c239
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c193
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c1341
-rw-r--r--drivers/media/video/pwc/pwc-if.c191
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c145
-rw-r--r--drivers/media/video/pwc/pwc.h21
-rw-r--r--drivers/media/video/pxa_camera.c15
-rw-r--r--drivers/media/video/s2255drv.c11
-rw-r--r--drivers/media/video/s5p-fimc/Kconfig48
-rw-r--r--drivers/media/video/s5p-fimc/Makefile6
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c506
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c1159
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h272
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite-reg.c300
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite-reg.h150
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.c1576
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.h213
-rw-r--r--drivers/media/video/s5p-fimc/fimc-m2m.c824
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.c476
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.h18
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c616
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.h326
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.c21
-rw-r--r--drivers/media/video/s5p-fimc/regs-fimc.h301
-rw-r--r--drivers/media/video/s5p-g2d/g2d.c69
-rw-r--r--drivers/media/video/s5p-g2d/g2d.h1
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.c68
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.h2
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc.c81
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_common.h2
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c16
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.c6
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_opr.c28
-rw-r--r--drivers/media/video/s5p-tv/hdmi_drv.c480
-rw-r--r--drivers/media/video/s5p-tv/hdmiphy_drv.c225
-rw-r--r--drivers/media/video/s5p-tv/mixer.h3
-rw-r--r--drivers/media/video/s5p-tv/mixer_drv.c2
-rw-r--r--drivers/media/video/s5p-tv/mixer_reg.c15
-rw-r--r--drivers/media/video/s5p-tv/mixer_video.c10
-rw-r--r--drivers/media/video/s5p-tv/regs-hdmi.h1
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c45
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c39
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c7
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c4
-rw-r--r--drivers/media/video/saa7164/saa7164.h5
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c92
-rw-r--r--drivers/media/video/sh_vou.c4
-rw-r--r--drivers/media/video/smiapp-pll.c418
-rw-r--r--drivers/media/video/smiapp-pll.h103
-rw-r--r--drivers/media/video/smiapp/Kconfig6
-rw-r--r--drivers/media/video/smiapp/Makefile5
-rw-r--r--drivers/media/video/smiapp/smiapp-core.c2894
-rw-r--r--drivers/media/video/smiapp/smiapp-limits.c132
-rw-r--r--drivers/media/video/smiapp/smiapp-limits.h128
-rw-r--r--drivers/media/video/smiapp/smiapp-quirk.c306
-rw-r--r--drivers/media/video/smiapp/smiapp-quirk.h83
-rw-r--r--drivers/media/video/smiapp/smiapp-reg-defs.h503
-rw-r--r--drivers/media/video/smiapp/smiapp-reg.h122
-rw-r--r--drivers/media/video/smiapp/smiapp-regs.c273
-rw-r--r--drivers/media/video/smiapp/smiapp-regs.h49
-rw-r--r--drivers/media/video/smiapp/smiapp.h252
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c4
-rw-r--r--drivers/media/video/soc_camera.c55
-rw-r--r--drivers/media/video/soc_mediabus.c54
-rw-r--r--drivers/media/video/sta2x11_vip.c1550
-rw-r--r--drivers/media/video/sta2x11_vip.h40
-rw-r--r--drivers/media/video/stk-webcam.c8
-rw-r--r--drivers/media/video/tda9840.c75
-rw-r--r--drivers/media/video/tlg2300/pd-video.c1
-rw-r--r--drivers/media/video/tm6000/tm6000-input.c3
-rw-r--r--drivers/media/video/tm6000/tm6000-stds.c2
-rw-r--r--drivers/media/video/tm6000/tm6000-video.c14
-rw-r--r--drivers/media/video/tm6000/tm6000.h2
-rw-r--r--drivers/media/video/tuner-core.c15
-rw-r--r--drivers/media/video/tvp5150.c11
-rw-r--r--drivers/media/video/tvp7002.c105
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c12
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c4
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c330
-rw-r--r--drivers/media/video/uvc/uvc_queue.c43
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c50
-rw-r--r--drivers/media/video/uvc/uvcvideo.h26
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c15
-rw-r--r--drivers/media/video/v4l2-ctrls.c302
-rw-r--r--drivers/media/video/v4l2-dev.c218
-rw-r--r--drivers/media/video/v4l2-event.c71
-rw-r--r--drivers/media/video/v4l2-ioctl.c662
-rw-r--r--drivers/media/video/v4l2-subdev.c143
-rw-r--r--drivers/media/video/via-camera.c15
-rw-r--r--drivers/media/video/videobuf-core.c3
-rw-r--r--drivers/media/video/videobuf-dma-contig.c199
-rw-r--r--drivers/media/video/videobuf-dvb.c3
-rw-r--r--drivers/media/video/videobuf2-core.c50
-rw-r--r--drivers/media/video/vivi.c223
-rw-r--r--drivers/media/video/w9966.c94
-rw-r--r--drivers/media/video/zoran/zoran_device.c2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c20
-rw-r--r--drivers/media/video/zr364xx.c2
-rw-r--r--drivers/staging/android/ashmem.c2
-rw-r--r--drivers/staging/media/as102/as10x_cmd.c28
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.c4
-rw-r--r--drivers/staging/media/easycap/easycap_main.c1639
-rw-r--r--drivers/staging/media/go7007/go7007-v4l2.c2
-rw-r--r--drivers/staging/media/go7007/s2250-loader.c2
-rw-r--r--drivers/staging/media/lirc/lirc_imon.c4
-rw-r--r--drivers/staging/media/lirc/lirc_sasem.c4
-rw-r--r--drivers/usb/gadget/uvc_queue.c2
-rw-r--r--drivers/usb/gadget/uvc_v4l2.c2
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/dvb/frontend.h51
-rw-r--r--include/linux/dvb/version.h2
-rw-r--r--include/linux/fixp-arith.h (renamed from drivers/input/fixp-arith.h)0
-rw-r--r--include/linux/v4l2-dv-timings.h816
-rw-r--r--include/linux/v4l2-subdev.h41
-rw-r--r--include/linux/videodev2.h372
-rw-r--r--include/media/media-entity.h5
-rw-r--r--include/media/mt9p031.h19
-rw-r--r--include/media/omap3isp.h29
-rw-r--r--include/media/rc-map.h3
-rw-r--r--include/media/s5p_fimc.h16
-rw-r--r--include/media/saa7146.h4
-rw-r--r--include/media/saa7146_vv.h25
-rw-r--r--include/media/sh_mobile_ceu.h1
-rw-r--r--include/media/smiapp.h84
-rw-r--r--include/media/soc_camera.h6
-rw-r--r--include/media/soc_mediabus.h21
-rw-r--r--include/media/v4l2-ctrls.h40
-rw-r--r--include/media/v4l2-dev.h25
-rw-r--r--include/media/v4l2-event.h24
-rw-r--r--include/media/v4l2-ioctl.h6
-rw-r--r--include/media/v4l2-subdev.h55
-rw-r--r--include/media/videobuf-dma-contig.h10
-rw-r--r--kernel/kfifo.c1
-rw-r--r--sound/i2c/other/tea575x-tuner.c3
463 files changed, 39172 insertions, 16754 deletions
diff --git a/Documentation/DocBook/media/Makefile b/Documentation/DocBook/media/Makefile
index 6628b4b9cac4..362520992ced 100644
--- a/Documentation/DocBook/media/Makefile
+++ b/Documentation/DocBook/media/Makefile
@@ -70,6 +70,8 @@ IOCTLS = \
70 VIDIOC_SUBDEV_ENUM_MBUS_CODE \ 70 VIDIOC_SUBDEV_ENUM_MBUS_CODE \
71 VIDIOC_SUBDEV_ENUM_FRAME_SIZE \ 71 VIDIOC_SUBDEV_ENUM_FRAME_SIZE \
72 VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ 72 VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
73 VIDIOC_SUBDEV_G_SELECTION \
74 VIDIOC_SUBDEV_S_SELECTION \
73 75
74TYPES = \ 76TYPES = \
75 $(shell perl -ne 'print "$$1 " if /^typedef\s+[^\s]+\s+([^\s]+)\;/' $(srctree)/include/linux/videodev2.h) \ 77 $(shell perl -ne 'print "$$1 " if /^typedef\s+[^\s]+\s+([^\s]+)\;/' $(srctree)/include/linux/videodev2.h) \
@@ -193,7 +195,7 @@ DVB_DOCUMENTED = \
193# 195#
194 196
195install_media_images = \ 197install_media_images = \
196 $(Q)cp $(OBJIMGFILES) $(MEDIA_OBJ_DIR)/media_api 198 $(Q)cp $(OBJIMGFILES) $(MEDIA_SRC_DIR)/v4l/*.svg $(MEDIA_OBJ_DIR)/media_api
197 199
198$(MEDIA_OBJ_DIR)/%: $(MEDIA_SRC_DIR)/%.b64 200$(MEDIA_OBJ_DIR)/%: $(MEDIA_SRC_DIR)/%.b64
199 $(Q)base64 -d $< >$@ 201 $(Q)base64 -d $< >$@
diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml
index c7a4ca517859..e633c097a8d1 100644
--- a/Documentation/DocBook/media/dvb/dvbproperty.xml
+++ b/Documentation/DocBook/media/dvb/dvbproperty.xml
@@ -531,6 +531,139 @@ typedef enum fe_delivery_system {
531 here are referring to what can be found in the TMCC-structure - 531 here are referring to what can be found in the TMCC-structure -
532 independent of the mode.</para> 532 independent of the mode.</para>
533 </section> 533 </section>
534 <section id="DTV-ATSCMH-FIC-VER">
535 <title><constant>DTV_ATSCMH_FIC_VER</constant></title>
536 <para>Version number of the FIC (Fast Information Channel) signaling data.</para>
537 <para>FIC is used for relaying information to allow rapid service acquisition by the receiver.</para>
538 <para>Possible values: 0, 1, 2, 3, ..., 30, 31</para>
539 </section>
540 <section id="DTV-ATSCMH-PARADE-ID">
541 <title><constant>DTV_ATSCMH_PARADE_ID</constant></title>
542 <para>Parade identification number</para>
543 <para>A parade is a collection of up to eight MH groups, conveying one or two ensembles.</para>
544 <para>Possible values: 0, 1, 2, 3, ..., 126, 127</para>
545 </section>
546 <section id="DTV-ATSCMH-NOG">
547 <title><constant>DTV_ATSCMH_NOG</constant></title>
548 <para>Number of MH groups per MH subframe for a designated parade.</para>
549 <para>Possible values: 1, 2, 3, 4, 5, 6, 7, 8</para>
550 </section>
551 <section id="DTV-ATSCMH-TNOG">
552 <title><constant>DTV_ATSCMH_TNOG</constant></title>
553 <para>Total number of MH groups including all MH groups belonging to all MH parades in one MH subframe.</para>
554 <para>Possible values: 0, 1, 2, 3, ..., 30, 31</para>
555 </section>
556 <section id="DTV-ATSCMH-SGN">
557 <title><constant>DTV_ATSCMH_SGN</constant></title>
558 <para>Start group number.</para>
559 <para>Possible values: 0, 1, 2, 3, ..., 14, 15</para>
560 </section>
561 <section id="DTV-ATSCMH-PRC">
562 <title><constant>DTV_ATSCMH_PRC</constant></title>
563 <para>Parade repetition cycle.</para>
564 <para>Possible values: 1, 2, 3, 4, 5, 6, 7, 8</para>
565 </section>
566 <section id="DTV-ATSCMH-RS-FRAME-MODE">
567 <title><constant>DTV_ATSCMH_RS_FRAME_MODE</constant></title>
568 <para>RS frame mode.</para>
569 <para>Possible values are:</para>
570<programlisting>
571typedef enum atscmh_rs_frame_mode {
572 ATSCMH_RSFRAME_PRI_ONLY = 0,
573 ATSCMH_RSFRAME_PRI_SEC = 1,
574} atscmh_rs_frame_mode_t;
575</programlisting>
576 </section>
577 <section id="DTV-ATSCMH-RS-FRAME-ENSEMBLE">
578 <title><constant>DTV_ATSCMH_RS_FRAME_ENSEMBLE</constant></title>
579 <para>RS frame ensemble.</para>
580 <para>Possible values are:</para>
581<programlisting>
582typedef enum atscmh_rs_frame_ensemble {
583 ATSCMH_RSFRAME_ENS_PRI = 0,
584 ATSCMH_RSFRAME_ENS_SEC = 1,
585} atscmh_rs_frame_ensemble_t;
586</programlisting>
587 </section>
588 <section id="DTV-ATSCMH-RS-CODE-MODE-PRI">
589 <title><constant>DTV_ATSCMH_RS_CODE_MODE_PRI</constant></title>
590 <para>RS code mode (primary).</para>
591 <para>Possible values are:</para>
592<programlisting>
593typedef enum atscmh_rs_code_mode {
594 ATSCMH_RSCODE_211_187 = 0,
595 ATSCMH_RSCODE_223_187 = 1,
596 ATSCMH_RSCODE_235_187 = 2,
597} atscmh_rs_code_mode_t;
598</programlisting>
599 </section>
600 <section id="DTV-ATSCMH-RS-CODE-MODE-SEC">
601 <title><constant>DTV_ATSCMH_RS_CODE_MODE_SEC</constant></title>
602 <para>RS code mode (secondary).</para>
603 <para>Possible values are:</para>
604<programlisting>
605typedef enum atscmh_rs_code_mode {
606 ATSCMH_RSCODE_211_187 = 0,
607 ATSCMH_RSCODE_223_187 = 1,
608 ATSCMH_RSCODE_235_187 = 2,
609} atscmh_rs_code_mode_t;
610</programlisting>
611 </section>
612 <section id="DTV-ATSCMH-SCCC-BLOCK-MODE">
613 <title><constant>DTV_ATSCMH_SCCC_BLOCK_MODE</constant></title>
614 <para>Series Concatenated Convolutional Code Block Mode.</para>
615 <para>Possible values are:</para>
616<programlisting>
617typedef enum atscmh_sccc_block_mode {
618 ATSCMH_SCCC_BLK_SEP = 0,
619 ATSCMH_SCCC_BLK_COMB = 1,
620} atscmh_sccc_block_mode_t;
621</programlisting>
622 </section>
623 <section id="DTV-ATSCMH-SCCC-CODE-MODE-A">
624 <title><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></title>
625 <para>Series Concatenated Convolutional Code Rate.</para>
626 <para>Possible values are:</para>
627<programlisting>
628typedef enum atscmh_sccc_code_mode {
629 ATSCMH_SCCC_CODE_HLF = 0,
630 ATSCMH_SCCC_CODE_QTR = 1,
631} atscmh_sccc_code_mode_t;
632</programlisting>
633 </section>
634 <section id="DTV-ATSCMH-SCCC-CODE-MODE-B">
635 <title><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></title>
636 <para>Series Concatenated Convolutional Code Rate.</para>
637 <para>Possible values are:</para>
638<programlisting>
639typedef enum atscmh_sccc_code_mode {
640 ATSCMH_SCCC_CODE_HLF = 0,
641 ATSCMH_SCCC_CODE_QTR = 1,
642} atscmh_sccc_code_mode_t;
643</programlisting>
644 </section>
645 <section id="DTV-ATSCMH-SCCC-CODE-MODE-C">
646 <title><constant>DTV_ATSCMH_SCCC_CODE_MODE_C</constant></title>
647 <para>Series Concatenated Convolutional Code Rate.</para>
648 <para>Possible values are:</para>
649<programlisting>
650typedef enum atscmh_sccc_code_mode {
651 ATSCMH_SCCC_CODE_HLF = 0,
652 ATSCMH_SCCC_CODE_QTR = 1,
653} atscmh_sccc_code_mode_t;
654</programlisting>
655 </section>
656 <section id="DTV-ATSCMH-SCCC-CODE-MODE-D">
657 <title><constant>DTV_ATSCMH_SCCC_CODE_MODE_D</constant></title>
658 <para>Series Concatenated Convolutional Code Rate.</para>
659 <para>Possible values are:</para>
660<programlisting>
661typedef enum atscmh_sccc_code_mode {
662 ATSCMH_SCCC_CODE_HLF = 0,
663 ATSCMH_SCCC_CODE_QTR = 1,
664} atscmh_sccc_code_mode_t;
665</programlisting>
666 </section>
534 </section> 667 </section>
535 <section id="DTV-API-VERSION"> 668 <section id="DTV-API-VERSION">
536 <title><constant>DTV_API_VERSION</constant></title> 669 <title><constant>DTV_API_VERSION</constant></title>
@@ -774,6 +907,33 @@ typedef enum fe_hierarchy {
774 <listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem> 907 <listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem>
775 </itemizedlist> 908 </itemizedlist>
776 </section> 909 </section>
910 <section id="atscmh-params">
911 <title>ATSC-MH delivery system</title>
912 <para>The following parameters are valid for ATSC-MH:</para>
913 <itemizedlist mark='opencircle'>
914 <listitem><para><link linkend="DTV-API-VERSION"><constant>DTV_API_VERSION</constant></link></para></listitem>
915 <listitem><para><link linkend="DTV-DELIVERY-SYSTEM"><constant>DTV_DELIVERY_SYSTEM</constant></link></para></listitem>
916 <listitem><para><link linkend="DTV-TUNE"><constant>DTV_TUNE</constant></link></para></listitem>
917 <listitem><para><link linkend="DTV-CLEAR"><constant>DTV_CLEAR</constant></link></para></listitem>
918 <listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem>
919 <listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem>
920 <listitem><para><link linkend="DTV-ATSCMH-FIC-VER"><constant>DTV_ATSCMH_FIC_VER</constant></link></para></listitem>
921 <listitem><para><link linkend="DTV-ATSCMH-PARADE-ID"><constant>DTV_ATSCMH_PARADE_ID</constant></link></para></listitem>
922 <listitem><para><link linkend="DTV-ATSCMH-NOG"><constant>DTV_ATSCMH_NOG</constant></link></para></listitem>
923 <listitem><para><link linkend="DTV-ATSCMH-TNOG"><constant>DTV_ATSCMH_TNOG</constant></link></para></listitem>
924 <listitem><para><link linkend="DTV-ATSCMH-SGN"><constant>DTV_ATSCMH_SGN</constant></link></para></listitem>
925 <listitem><para><link linkend="DTV-ATSCMH-PRC"><constant>DTV_ATSCMH_PRC</constant></link></para></listitem>
926 <listitem><para><link linkend="DTV-ATSCMH-RS-FRAME-MODE"><constant>DTV_ATSCMH_RS_FRAME_MODE</constant></link></para></listitem>
927 <listitem><para><link linkend="DTV-ATSCMH-RS-FRAME-ENSEMBLE"><constant>DTV_ATSCMH_RS_FRAME_ENSEMBLE</constant></link></para></listitem>
928 <listitem><para><link linkend="DTV-ATSCMH-CODE-MODE-PRI"><constant>DTV_ATSCMH_CODE_MODE_PRI</constant></link></para></listitem>
929 <listitem><para><link linkend="DTV-ATSCMH-CODE-MODE-SEC"><constant>DTV_ATSCMH_CODE_MODE_SEC</constant></link></para></listitem>
930 <listitem><para><link linkend="DTV-ATSCMH-SCCC-BLOCK-MODE"><constant>DTV_ATSCMH_SCCC_BLOCK_MODE</constant></link></para></listitem>
931 <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-A"><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></link></para></listitem>
932 <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-B"><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></link></para></listitem>
933 <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-C"><constant>DTV_ATSCMH_SCCC_CODE_MODE_C</constant></link></para></listitem>
934 <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-D"><constant>DTV_ATSCMH_SCCC_CODE_MODE_D</constant></link></para></listitem>
935 </itemizedlist>
936 </section>
777 </section> 937 </section>
778 <section id="frontend-property-cable-systems"> 938 <section id="frontend-property-cable-systems">
779 <title>Properties used on cable delivery systems</title> 939 <title>Properties used on cable delivery systems</title>
diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml
index 7dc65c592a87..7c49facecd25 100644
--- a/Documentation/DocBook/media/v4l/biblio.xml
+++ b/Documentation/DocBook/media/v4l/biblio.xml
@@ -197,4 +197,33 @@ in the frequency range from 87,5 to 108,0 MHz</title>
197 <title>NTSC-4: United States RBDS Standard</title> 197 <title>NTSC-4: United States RBDS Standard</title>
198 </biblioentry> 198 </biblioentry>
199 199
200 <biblioentry id="iso12232">
201 <abbrev>ISO&nbsp;12232:2006</abbrev>
202 <authorgroup>
203 <corpauthor>International Organization for Standardization
204(<ulink url="http://www.iso.org">http://www.iso.org</ulink>)</corpauthor>
205 </authorgroup>
206 <title>Photography &mdash; Digital still cameras &mdash; Determination
207 of exposure index, ISO speed ratings, standard output sensitivity, and
208 recommended exposure index</title>
209 </biblioentry>
210
211 <biblioentry id="cea861">
212 <abbrev>CEA-861-E</abbrev>
213 <authorgroup>
214 <corpauthor>Consumer Electronics Association
215(<ulink url="http://www.ce.org">http://www.ce.org</ulink>)</corpauthor>
216 </authorgroup>
217 <title>A DTV Profile for Uncompressed High Speed Digital Interfaces</title>
218 </biblioentry>
219
220 <biblioentry id="vesadmt">
221 <abbrev>VESA&nbsp;DMT</abbrev>
222 <authorgroup>
223 <corpauthor>Video Electronics Standards Association
224(<ulink url="http://www.vesa.org">http://www.vesa.org</ulink>)</corpauthor>
225 </authorgroup>
226 <title>VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT)</title>
227 </biblioentry>
228
200 </bibliography> 229 </bibliography>
diff --git a/Documentation/DocBook/media/v4l/common.xml b/Documentation/DocBook/media/v4l/common.xml
index c79278acfb0e..4101aeb56540 100644
--- a/Documentation/DocBook/media/v4l/common.xml
+++ b/Documentation/DocBook/media/v4l/common.xml
@@ -724,41 +724,49 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
724} 724}
725 </programlisting> 725 </programlisting>
726 </example> 726 </example>
727 </section>
727 <section id="dv-timings"> 728 <section id="dv-timings">
728 <title>Digital Video (DV) Timings</title> 729 <title>Digital Video (DV) Timings</title>
729 <para> 730 <para>
730 The video standards discussed so far has been dealing with Analog TV and the 731 The video standards discussed so far have been dealing with Analog TV and the
731corresponding video timings. Today there are many more different hardware interfaces 732corresponding video timings. Today there are many more different hardware interfaces
732such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry 733such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry
733video signals and there is a need to extend the API to select the video timings 734video signals and there is a need to extend the API to select the video timings
734for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to 735for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to
735the limited bits available, a new set of IOCTLs is added to set/get video timings at 736the limited bits available, a new set of IOCTLs was added to set/get video timings at
736the input and output: </para><itemizedlist> 737the input and output: </para><itemizedlist>
737 <listitem> 738 <listitem>
738 <para>DV Presets: Digital Video (DV) presets. These are IDs representing a 739 <para>DV Timings: This will allow applications to define detailed
740video timings for the interface. This includes parameters such as width, height,
741polarities, frontporch, backporch etc. The <filename>linux/v4l2-dv-timings.h</filename>
742header can be used to get the timings of the formats in the <xref linkend="cea861" /> and
743<xref linkend="vesadmt" /> standards.
744 </para>
745 </listitem>
746 <listitem>
747 <para>DV Presets: Digital Video (DV) presets (<emphasis role="bold">deprecated</emphasis>).
748 These are IDs representing a
739video timing at the input/output. Presets are pre-defined timings implemented 749video timing at the input/output. Presets are pre-defined timings implemented
740by the hardware according to video standards. A __u32 data type is used to represent 750by the hardware according to video standards. A __u32 data type is used to represent
741a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions 751a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions
742to support as many different presets as needed.</para> 752to support as many different presets as needed. This API is deprecated in favor of the DV Timings
743 </listitem> 753API.</para>
744 <listitem>
745 <para>Custom DV Timings: This will allow applications to define more detailed
746custom video timings for the interface. This includes parameters such as width, height,
747polarities, frontporch, backporch etc.
748 </para>
749 </listitem> 754 </listitem>
750 </itemizedlist> 755 </itemizedlist>
756 <para>To enumerate and query the attributes of the DV timings supported by a device,
757 applications use the &VIDIOC-ENUM-DV-TIMINGS; and &VIDIOC-DV-TIMINGS-CAP; ioctls.
758 To set DV timings for the device, applications use the
759&VIDIOC-S-DV-TIMINGS; ioctl and to get current DV timings they use the
760&VIDIOC-G-DV-TIMINGS; ioctl. To detect the DV timings as seen by the video receiver applications
761use the &VIDIOC-QUERY-DV-TIMINGS; ioctl.</para>
751 <para>To enumerate and query the attributes of DV presets supported by a device, 762 <para>To enumerate and query the attributes of DV presets supported by a device,
752applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset, 763applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset,
753applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the 764applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the
754&VIDIOC-S-DV-PRESET; ioctl.</para> 765&VIDIOC-S-DV-PRESET; ioctl. To detect the preset as seen by the video receiver applications
755 <para>To set custom DV timings for the device, applications use the 766use the &VIDIOC-QUERY-DV-PRESET; ioctl.</para>
756&VIDIOC-S-DV-TIMINGS; ioctl and to get current custom DV timings they use the
757&VIDIOC-G-DV-TIMINGS; ioctl.</para>
758 <para>Applications can make use of the <xref linkend="input-capabilities" /> and 767 <para>Applications can make use of the <xref linkend="input-capabilities" /> and
759<xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the 768<xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the
760video timings for the device.</para> 769video timings for the device.</para>
761 </section>
762 </section> 770 </section>
763 771
764 &sub-controls; 772 &sub-controls;
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index bce97c50391b..ea42ef824948 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2407,6 +2407,54 @@ details.</para>
2407 <para>Added <link linkend="jpeg-controls">JPEG compression control 2407 <para>Added <link linkend="jpeg-controls">JPEG compression control
2408 class</link>.</para> 2408 class</link>.</para>
2409 </listitem> 2409 </listitem>
2410 <listitem>
2411 <para>Extended the DV Timings API:
2412 &VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
2413 &VIDIOC-DV-TIMINGS-CAP;.</para>
2414 </listitem>
2415 </orderedlist>
2416 </section>
2417
2418 <section>
2419 <title>V4L2 in Linux 3.5</title>
2420 <orderedlist>
2421 <listitem>
2422 <para>Added integer menus, the new type will be
2423 V4L2_CTRL_TYPE_INTEGER_MENU.</para>
2424 </listitem>
2425 <listitem>
2426 <para>Added selection API for V4L2 subdev interface:
2427 &VIDIOC-SUBDEV-G-SELECTION; and
2428 &VIDIOC-SUBDEV-S-SELECTION;.</para>
2429 </listitem>
2430 <listitem>
2431 <para> Added <constant>V4L2_COLORFX_ANTIQUE</constant>,
2432 <constant>V4L2_COLORFX_ART_FREEZE</constant>,
2433 <constant>V4L2_COLORFX_AQUA</constant>,
2434 <constant>V4L2_COLORFX_SILHOUETTE</constant>,
2435 <constant>V4L2_COLORFX_SOLARIZATION</constant>,
2436 <constant>V4L2_COLORFX_VIVID</constant> and
2437 <constant>V4L2_COLORFX_ARBITRARY_CBCR</constant> menu items
2438 to the <constant>V4L2_CID_COLORFX</constant> control.</para>
2439 </listitem>
2440 <listitem>
2441 <para> Added <constant>V4L2_CID_COLORFX_CBCR</constant> control.</para>
2442 </listitem>
2443 <listitem>
2444 <para> Added camera controls <constant>V4L2_CID_AUTO_EXPOSURE_BIAS</constant>,
2445 <constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant>,
2446 <constant>V4L2_CID_IMAGE_STABILIZATION</constant>,
2447 <constant>V4L2_CID_ISO_SENSITIVITY</constant>,
2448 <constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>,
2449 <constant>V4L2_CID_EXPOSURE_METERING</constant>,
2450 <constant>V4L2_CID_SCENE_MODE</constant>,
2451 <constant>V4L2_CID_3A_LOCK</constant>,
2452 <constant>V4L2_CID_AUTO_FOCUS_START</constant>,
2453 <constant>V4L2_CID_AUTO_FOCUS_STOP</constant>,
2454 <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant> and
2455 <constant>V4L2_CID_AUTO_FOCUS_RANGE</constant>.
2456 </para>
2457 </listitem>
2410 </orderedlist> 2458 </orderedlist>
2411 </section> 2459 </section>
2412 2460
@@ -2508,6 +2556,10 @@ and may change in the future.</para>
2508ioctls.</para> 2556ioctls.</para>
2509 </listitem> 2557 </listitem>
2510 <listitem> 2558 <listitem>
2559 <para>&VIDIOC-DECODER-CMD; and &VIDIOC-TRY-DECODER-CMD;
2560ioctls.</para>
2561 </listitem>
2562 <listitem>
2511 <para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER; 2563 <para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER;
2512ioctls.</para> 2564ioctls.</para>
2513 </listitem> 2565 </listitem>
@@ -2515,6 +2567,10 @@ ioctls.</para>
2515 <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para> 2567 <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
2516 </listitem> 2568 </listitem>
2517 <listitem> 2569 <listitem>
2570 <para>&VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
2571 &VIDIOC-DV-TIMINGS-CAP; ioctls.</para>
2572 </listitem>
2573 <listitem>
2518 <para>Flash API. <xref linkend="flash-controls" /></para> 2574 <para>Flash API. <xref linkend="flash-controls" /></para>
2519 </listitem> 2575 </listitem>
2520 <listitem> 2576 <listitem>
@@ -2523,6 +2579,14 @@ ioctls.</para>
2523 <listitem> 2579 <listitem>
2524 <para>Selection API. <xref linkend="selection-api" /></para> 2580 <para>Selection API. <xref linkend="selection-api" /></para>
2525 </listitem> 2581 </listitem>
2582 <listitem>
2583 <para>Sub-device selection API: &VIDIOC-SUBDEV-G-SELECTION;
2584 and &VIDIOC-SUBDEV-S-SELECTION; ioctls.</para>
2585 </listitem>
2586 <listitem>
2587 <para><link linkend="v4l2-auto-focus-area"><constant>
2588 V4L2_CID_AUTO_FOCUS_AREA</constant></link> control.</para>
2589 </listitem>
2526 </itemizedlist> 2590 </itemizedlist>
2527 </section> 2591 </section>
2528 2592
@@ -2538,6 +2602,17 @@ interfaces and should not be implemented in new drivers.</para>
2538<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls, 2602<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
2539<xref linkend="extended-controls" />.</para> 2603<xref linkend="extended-controls" />.</para>
2540 </listitem> 2604 </listitem>
2605 <listitem>
2606 <para>&VIDIOC-G-DV-PRESET;, &VIDIOC-S-DV-PRESET;, &VIDIOC-ENUM-DV-PRESETS; and
2607 &VIDIOC-QUERY-DV-PRESET; ioctls. Use the DV Timings API (<xref linkend="dv-timings" />).</para>
2608 </listitem>
2609 <listitem>
2610 <para><constant>VIDIOC_SUBDEV_G_CROP</constant> and
2611 <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctls. Use
2612 <constant>VIDIOC_SUBDEV_G_SELECTION</constant> and
2613 <constant>VIDIOC_SUBDEV_S_SELECTION</constant>, <xref
2614 linkend="vidioc-subdev-g-selection" />.</para>
2615 </listitem>
2541 </itemizedlist> 2616 </itemizedlist>
2542 </section> 2617 </section>
2543 </section> 2618 </section>
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index dd03cf4a6539..676bc46f9c52 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -285,18 +285,92 @@ minimum value disables backlight compensation.</entry>
285 <row id="v4l2-colorfx"> 285 <row id="v4l2-colorfx">
286 <entry><constant>V4L2_CID_COLORFX</constant></entry> 286 <entry><constant>V4L2_CID_COLORFX</constant></entry>
287 <entry>enum</entry> 287 <entry>enum</entry>
288 <entry>Selects a color effect. Possible values for 288 <entry>Selects a color effect. The following values are defined:
289<constant>enum v4l2_colorfx</constant> are: 289 </entry>
290<constant>V4L2_COLORFX_NONE</constant> (0), 290 </row><row>
291<constant>V4L2_COLORFX_BW</constant> (1), 291 <entry></entry>
292<constant>V4L2_COLORFX_SEPIA</constant> (2), 292 <entry></entry>
293<constant>V4L2_COLORFX_NEGATIVE</constant> (3), 293 <entrytbl spanname="descr" cols="2">
294<constant>V4L2_COLORFX_EMBOSS</constant> (4), 294 <tbody valign="top">
295<constant>V4L2_COLORFX_SKETCH</constant> (5), 295 <row>
296<constant>V4L2_COLORFX_SKY_BLUE</constant> (6), 296 <entry><constant>V4L2_COLORFX_NONE</constant>&nbsp;</entry>
297<constant>V4L2_COLORFX_GRASS_GREEN</constant> (7), 297 <entry>Color effect is disabled.</entry>
298<constant>V4L2_COLORFX_SKIN_WHITEN</constant> (8) and 298 </row>
299<constant>V4L2_COLORFX_VIVID</constant> (9).</entry> 299 <row>
300 <entry><constant>V4L2_COLORFX_ANTIQUE</constant>&nbsp;</entry>
301 <entry>An aging (old photo) effect.</entry>
302 </row>
303 <row>
304 <entry><constant>V4L2_COLORFX_ART_FREEZE</constant>&nbsp;</entry>
305 <entry>Frost color effect.</entry>
306 </row>
307 <row>
308 <entry><constant>V4L2_COLORFX_AQUA</constant>&nbsp;</entry>
309 <entry>Water color, cool tone.</entry>
310 </row>
311 <row>
312 <entry><constant>V4L2_COLORFX_BW</constant>&nbsp;</entry>
313 <entry>Black and white.</entry>
314 </row>
315 <row>
316 <entry><constant>V4L2_COLORFX_EMBOSS</constant>&nbsp;</entry>
317 <entry>Emboss, the highlights and shadows replace light/dark boundaries
318 and low contrast areas are set to a gray background.</entry>
319 </row>
320 <row>
321 <entry><constant>V4L2_COLORFX_GRASS_GREEN</constant>&nbsp;</entry>
322 <entry>Grass green.</entry>
323 </row>
324 <row>
325 <entry><constant>V4L2_COLORFX_NEGATIVE</constant>&nbsp;</entry>
326 <entry>Negative.</entry>
327 </row>
328 <row>
329 <entry><constant>V4L2_COLORFX_SEPIA</constant>&nbsp;</entry>
330 <entry>Sepia tone.</entry>
331 </row>
332 <row>
333 <entry><constant>V4L2_COLORFX_SKETCH</constant>&nbsp;</entry>
334 <entry>Sketch.</entry>
335 </row>
336 <row>
337 <entry><constant>V4L2_COLORFX_SKIN_WHITEN</constant>&nbsp;</entry>
338 <entry>Skin whiten.</entry>
339 </row>
340 <row>
341 <entry><constant>V4L2_COLORFX_SKY_BLUE</constant>&nbsp;</entry>
342 <entry>Sky blue.</entry>
343 </row>
344 <row>
345 <entry><constant>V4L2_COLORFX_SOLARIZATION</constant>&nbsp;</entry>
346 <entry>Solarization, the image is partially reversed in tone,
347 only color values above or below a certain threshold are inverted.
348 </entry>
349 </row>
350 <row>
351 <entry><constant>V4L2_COLORFX_SILHOUETTE</constant>&nbsp;</entry>
352 <entry>Silhouette (outline).</entry>
353 </row>
354 <row>
355 <entry><constant>V4L2_COLORFX_VIVID</constant>&nbsp;</entry>
356 <entry>Vivid colors.</entry>
357 </row>
358 <row>
359 <entry><constant>V4L2_COLORFX_SET_CBCR</constant>&nbsp;</entry>
360 <entry>The Cb and Cr chroma components are replaced by fixed
361 coefficients determined by <constant>V4L2_CID_COLORFX_CBCR</constant>
362 control.</entry>
363 </row>
364 </tbody>
365 </entrytbl>
366 </row>
367 <row>
368 <entry><constant>V4L2_CID_COLORFX_CBCR</constant></entry>
369 <entry>integer</entry>
370 <entry>Determines the Cb and Cr coefficients for <constant>V4L2_COLORFX_SET_CBCR</constant>
371 color effect. Bits [7:0] of the supplied 32 bit value are interpreted as
372 Cr component, bits [15:8] as Cb component and bits [31:16] must be zero.
373 </entry>
300 </row> 374 </row>
301 <row> 375 <row>
302 <entry><constant>V4L2_CID_ROTATE</constant></entry> 376 <entry><constant>V4L2_CID_ROTATE</constant></entry>
@@ -2775,6 +2849,51 @@ remain constant.</entry>
2775 <row><entry></entry></row> 2849 <row><entry></entry></row>
2776 2850
2777 <row> 2851 <row>
2852 <entry spanname="id"><constant>V4L2_CID_EXPOSURE_BIAS</constant>&nbsp;</entry>
2853 <entry>integer menu</entry>
2854 </row><row><entry spanname="descr"> Determines the automatic
2855exposure compensation, it is effective only when <constant>V4L2_CID_EXPOSURE_AUTO</constant>
2856control is set to <constant>AUTO</constant>, <constant>SHUTTER_PRIORITY </constant>
2857or <constant>APERTURE_PRIORITY</constant>.
2858It is expressed in terms of EV, drivers should interpret the values as 0.001 EV
2859units, where the value 1000 stands for +1 EV.
2860<para>Increasing the exposure compensation value is equivalent to decreasing
2861the exposure value (EV) and will increase the amount of light at the image
2862sensor. The camera performs the exposure compensation by adjusting absolute
2863exposure time and/or aperture.</para></entry>
2864 </row>
2865 <row><entry></entry></row>
2866
2867 <row id="v4l2-exposure-metering">
2868 <entry spanname="id"><constant>V4L2_CID_EXPOSURE_METERING</constant>&nbsp;</entry>
2869 <entry>enum&nbsp;v4l2_exposure_metering</entry>
2870 </row><row><entry spanname="descr">Determines how the camera measures
2871the amount of light available for the frame exposure. Possible values are:</entry>
2872 </row>
2873 <row>
2874 <entrytbl spanname="descr" cols="2">
2875 <tbody valign="top">
2876 <row>
2877 <entry><constant>V4L2_EXPOSURE_METERING_AVERAGE</constant>&nbsp;</entry>
2878 <entry>Use the light information coming from the entire frame
2879and average giving no weighting to any particular portion of the metered area.
2880 </entry>
2881 </row>
2882 <row>
2883 <entry><constant>V4L2_EXPOSURE_METERING_CENTER_WEIGHTED</constant>&nbsp;</entry>
2884 <entry>Average the light information coming from the entire frame
2885giving priority to the center of the metered area.</entry>
2886 </row>
2887 <row>
2888 <entry><constant>V4L2_EXPOSURE_METERING_SPOT</constant>&nbsp;</entry>
2889 <entry>Measure only very small area at the center of the frame.</entry>
2890 </row>
2891 </tbody>
2892 </entrytbl>
2893 </row>
2894 <row><entry></entry></row>
2895
2896 <row>
2778 <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry> 2897 <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
2779 <entry>integer</entry> 2898 <entry>integer</entry>
2780 </row><row><entry spanname="descr">This control turns the 2899 </row><row><entry spanname="descr">This control turns the
@@ -2857,13 +2976,107 @@ negative values towards infinity. This is a write-only control.</entry>
2857 <row> 2976 <row>
2858 <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry> 2977 <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry>
2859 <entry>boolean</entry> 2978 <entry>boolean</entry>
2860 </row><row><entry spanname="descr">Enables automatic focus 2979 </row><row><entry spanname="descr">Enables continuous automatic
2861adjustments. The effect of manual focus adjustments while this feature 2980focus adjustments. The effect of manual focus adjustments while this feature
2862is enabled is undefined, drivers should ignore such requests.</entry> 2981is enabled is undefined, drivers should ignore such requests.</entry>
2863 </row> 2982 </row>
2864 <row><entry></entry></row> 2983 <row><entry></entry></row>
2865 2984
2866 <row> 2985 <row>
2986 <entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_START</constant>&nbsp;</entry>
2987 <entry>button</entry>
2988 </row><row><entry spanname="descr">Starts single auto focus process.
2989The effect of setting this control when <constant>V4L2_CID_FOCUS_AUTO</constant>
2990is set to <constant>TRUE</constant> (1) is undefined, drivers should ignore
2991such requests.</entry>
2992 </row>
2993 <row><entry></entry></row>
2994
2995 <row>
2996 <entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_STOP</constant>&nbsp;</entry>
2997 <entry>button</entry>
2998 </row><row><entry spanname="descr">Aborts automatic focusing
2999started with <constant>V4L2_CID_AUTO_FOCUS_START</constant> control. It is
3000effective only when the continuous autofocus is disabled, that is when
3001<constant>V4L2_CID_FOCUS_AUTO</constant> control is set to <constant>FALSE
3002</constant> (0).</entry>
3003 </row>
3004 <row><entry></entry></row>
3005
3006 <row id="v4l2-auto-focus-status">
3007 <entry spanname="id">
3008 <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant>&nbsp;</entry>
3009 <entry>bitmask</entry>
3010 </row>
3011 <row><entry spanname="descr">The automatic focus status. This is a read-only
3012 control.</entry>
3013 </row>
3014 <row>
3015 <entrytbl spanname="descr" cols="2">
3016 <tbody valign="top">
3017 <row>
3018 <entry><constant>V4L2_AUTO_FOCUS_STATUS_IDLE</constant>&nbsp;</entry>
3019 <entry>Automatic focus is not active.</entry>
3020 </row>
3021 <row>
3022 <entry><constant>V4L2_AUTO_FOCUS_STATUS_BUSY</constant>&nbsp;</entry>
3023 <entry>Automatic focusing is in progress.</entry>
3024 </row>
3025 <row>
3026 <entry><constant>V4L2_AUTO_FOCUS_STATUS_REACHED</constant>&nbsp;</entry>
3027 <entry>Focus has been reached.</entry>
3028 </row>
3029 <row>
3030 <entry><constant>V4L2_AUTO_FOCUS_STATUS_FAILED</constant>&nbsp;</entry>
3031 <entry>Automatic focus has failed, the driver will not
3032 transition from this state until another action is
3033 performed by an application.</entry>
3034 </row>
3035 </tbody>
3036 </entrytbl>
3037 </row>
3038 <row><entry spanname="descr">
3039Setting <constant>V4L2_LOCK_FOCUS</constant> lock bit of the <constant>V4L2_CID_3A_LOCK
3040</constant> control may stop updates of the <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant>
3041control value.</entry>
3042 </row>
3043 <row><entry></entry></row>
3044
3045 <row id="v4l2-auto-focus-range">
3046 <entry spanname="id">
3047 <constant>V4L2_CID_AUTO_FOCUS_RANGE</constant>&nbsp;</entry>
3048 <entry>enum&nbsp;v4l2_auto_focus_range</entry>
3049 </row>
3050 <row><entry spanname="descr">Determines auto focus distance range
3051for which lens may be adjusted. </entry>
3052 </row>
3053 <row>
3054 <entrytbl spanname="descr" cols="2">
3055 <tbody valign="top">
3056 <row>
3057 <entry><constant>V4L2_AUTO_FOCUS_RANGE_AUTO</constant>&nbsp;</entry>
3058 <entry>The camera automatically selects the focus range.</entry>
3059 </row>
3060 <row>
3061 <entry><constant>V4L2_AUTO_FOCUS_RANGE_NORMAL</constant>&nbsp;</entry>
3062 <entry>Normal distance range, limited for best automatic focus
3063performance.</entry>
3064 </row>
3065 <row>
3066 <entry><constant>V4L2_AUTO_FOCUS_RANGE_MACRO</constant>&nbsp;</entry>
3067 <entry>Macro (close-up) auto focus. The camera will
3068use its minimum possible distance for auto focus.</entry>
3069 </row>
3070 <row>
3071 <entry><constant>V4L2_AUTO_FOCUS_RANGE_INFINITY</constant>&nbsp;</entry>
3072 <entry>The lens is set to focus on an object at infinite distance.</entry>
3073 </row>
3074 </tbody>
3075 </entrytbl>
3076 </row>
3077 <row><entry></entry></row>
3078
3079 <row>
2867 <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry> 3080 <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry>
2868 <entry>integer</entry> 3081 <entry>integer</entry>
2869 </row><row><entry spanname="descr">Specify the objective lens 3082 </row><row><entry spanname="descr">Specify the objective lens
@@ -2932,6 +3145,295 @@ camera sensor on or off, or specify its strength. Such band-stop filters can
2932be used, for example, to filter out the fluorescent light component.</entry> 3145be used, for example, to filter out the fluorescent light component.</entry>
2933 </row> 3146 </row>
2934 <row><entry></entry></row> 3147 <row><entry></entry></row>
3148
3149 <row id="v4l2-auto-n-preset-white-balance">
3150 <entry spanname="id"><constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant>&nbsp;</entry>
3151 <entry>enum&nbsp;v4l2_auto_n_preset_white_balance</entry>
3152 </row><row><entry spanname="descr">Sets white balance to automatic,
3153manual or a preset. The presets determine color temperature of the light as
3154a hint to the camera for white balance adjustments resulting in most accurate
3155color representation. The following white balance presets are listed in order
3156of increasing color temperature.</entry>
3157 </row>
3158 <row>
3159 <entrytbl spanname="descr" cols="2">
3160 <tbody valign="top">
3161 <row>
3162 <entry><constant>V4L2_WHITE_BALANCE_MANUAL</constant>&nbsp;</entry>
3163 <entry>Manual white balance.</entry>
3164 </row>
3165 <row>
3166 <entry><constant>V4L2_WHITE_BALANCE_AUTO</constant>&nbsp;</entry>
3167 <entry>Automatic white balance adjustments.</entry>
3168 </row>
3169 <row>
3170 <entry><constant>V4L2_WHITE_BALANCE_INCANDESCENT</constant>&nbsp;</entry>
3171 <entry>White balance setting for incandescent (tungsten) lighting.
3172It generally cools down the colors and corresponds approximately to 2500...3500 K
3173color temperature range.</entry>
3174 </row>
3175 <row>
3176 <entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT</constant>&nbsp;</entry>
3177 <entry>White balance preset for fluorescent lighting.
3178It corresponds approximately to 4000...5000 K color temperature.</entry>
3179 </row>
3180 <row>
3181 <entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT_H</constant>&nbsp;</entry>
3182 <entry>With this setting the camera will compensate for
3183fluorescent H lighting.</entry>
3184 </row>
3185 <row>
3186 <entry><constant>V4L2_WHITE_BALANCE_HORIZON</constant>&nbsp;</entry>
3187 <entry>White balance setting for horizon daylight.
3188It corresponds approximately to 5000 K color temperature.</entry>
3189 </row>
3190 <row>
3191 <entry><constant>V4L2_WHITE_BALANCE_DAYLIGHT</constant>&nbsp;</entry>
3192 <entry>White balance preset for daylight (with clear sky).
3193It corresponds approximately to 5000...6500 K color temperature.</entry>
3194 </row>
3195 <row>
3196 <entry><constant>V4L2_WHITE_BALANCE_FLASH</constant>&nbsp;</entry>
3197 <entry>With this setting the camera will compensate for the flash
3198light. It slightly warms up the colors and corresponds roughly to 5000...5500 K
3199color temperature.</entry>
3200 </row>
3201 <row>
3202 <entry><constant>V4L2_WHITE_BALANCE_CLOUDY</constant>&nbsp;</entry>
3203 <entry>White balance preset for moderately overcast sky.
3204This option corresponds approximately to 6500...8000 K color temperature
3205range.</entry>
3206 </row>
3207 <row>
3208 <entry><constant>V4L2_WHITE_BALANCE_SHADE</constant>&nbsp;</entry>
3209 <entry>White balance preset for shade or heavily overcast
3210sky. It corresponds approximately to 9000...10000 K color temperature.
3211</entry>
3212 </row>
3213 </tbody>
3214 </entrytbl>
3215 </row>
3216 <row><entry></entry></row>
3217
3218 <row id="v4l2-wide-dynamic-range">
3219 <entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
3220 <entry>boolean</entry>
3221 </row>
3222 <row>
3223 <entry spanname="descr">Enables or disables the camera's wide dynamic
3224range feature. This feature allows to obtain clear images in situations where
3225intensity of the illumination varies significantly throughout the scene, i.e.
3226there are simultaneously very dark and very bright areas. It is most commonly
3227realized in cameras by combining two subsequent frames with different exposure
3228times. <footnote id="ctypeconv"><para> This control may be changed to a menu
3229control in the future, if more options are required.</para></footnote></entry>
3230 </row>
3231 <row><entry></entry></row>
3232
3233 <row id="v4l2-image-stabilization">
3234 <entry spanname="id"><constant>V4L2_CID_IMAGE_STABILIZATION</constant></entry>
3235 <entry>boolean</entry>
3236 </row>
3237 <row>
3238 <entry spanname="descr">Enables or disables image stabilization.
3239 <footnoteref linkend="ctypeconv"/></entry>
3240 </row>
3241 <row><entry></entry></row>
3242
3243 <row>
3244 <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY</constant>&nbsp;</entry>
3245 <entry>integer menu</entry>
3246 </row><row><entry spanname="descr">Determines ISO equivalent of an
3247image sensor indicating the sensor's sensitivity to light. The numbers are
3248expressed in arithmetic scale, as per <xref linkend="iso12232" /> standard,
3249where doubling the sensor sensitivity is represented by doubling the numerical
3250ISO value. Applications should interpret the values as standard ISO values
3251multiplied by 1000, e.g. control value 800 stands for ISO 0.8. Drivers will
3252usually support only a subset of standard ISO values. The effect of setting
3253this control while the <constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>
3254control is set to a value other than <constant>V4L2_CID_ISO_SENSITIVITY_MANUAL
3255</constant> is undefined, drivers should ignore such requests.</entry>
3256 </row>
3257 <row><entry></entry></row>
3258
3259 <row id="v4l2-iso-sensitivity-auto-type">
3260 <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
3261 <entry>enum&nbsp;v4l2_iso_sensitivity_type</entry>
3262 </row><row><entry spanname="descr">Enables or disables automatic ISO
3263sensitivity adjustments.</entry>
3264 </row>
3265 <row>
3266 <entrytbl spanname="descr" cols="2">
3267 <tbody valign="top">
3268 <row>
3269 <entry><constant>V4L2_CID_ISO_SENSITIVITY_MANUAL</constant>&nbsp;</entry>
3270 <entry>Manual ISO sensitivity.</entry>
3271 </row>
3272 <row>
3273 <entry><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
3274 <entry>Automatic ISO sensitivity adjustments.</entry>
3275 </row>
3276 </tbody>
3277 </entrytbl>
3278 </row>
3279 <row><entry></entry></row>
3280
3281 <row id="v4l2-scene-mode">
3282 <entry spanname="id"><constant>V4L2_CID_SCENE_MODE</constant>&nbsp;</entry>
3283 <entry>enum&nbsp;v4l2_scene_mode</entry>
3284 </row><row><entry spanname="descr">This control allows to select
3285scene programs as the camera automatic modes optimized for common shooting
3286scenes. Within these modes the camera determines best exposure, aperture,
3287focusing, light metering, white balance and equivalent sensitivity. The
3288controls of those parameters are influenced by the scene mode control.
3289An exact behavior in each mode is subject to the camera specification.
3290
3291<para>When the scene mode feature is not used, this control should be set to
3292<constant>V4L2_SCENE_MODE_NONE</constant> to make sure the other possibly
3293related controls are accessible. The following scene programs are defined:
3294</para>
3295</entry>
3296 </row>
3297 <row>
3298 <entrytbl spanname="descr" cols="2">
3299 <tbody valign="top">
3300 <row>
3301 <entry><constant>V4L2_SCENE_MODE_NONE</constant>&nbsp;</entry>
3302 <entry>The scene mode feature is disabled.</entry>
3303 </row>
3304 <row>
3305 <entry><constant>V4L2_SCENE_MODE_BACKLIGHT</constant>&nbsp;</entry>
3306 <entry>Backlight. Compensates for dark shadows when light is
3307 coming from behind a subject, also by automatically turning
3308 on the flash.</entry>
3309 </row>
3310 <row>
3311 <entry><constant>V4L2_SCENE_MODE_BEACH_SNOW</constant>&nbsp;</entry>
3312 <entry>Beach and snow. This mode compensates for all-white or
3313bright scenes, which tend to look gray and low contrast, when camera's automatic
3314exposure is based on an average scene brightness. To compensate, this mode
3315automatically slightly overexposes the frames. The white balance may also be
3316adjusted to compensate for the fact that reflected snow looks bluish rather
3317than white.</entry>
3318 </row>
3319 <row>
3320 <entry><constant>V4L2_SCENE_MODE_CANDLELIGHT</constant>&nbsp;</entry>
3321 <entry>Candle light. The camera generally raises the ISO
3322sensitivity and lowers the shutter speed. This mode compensates for relatively
3323close subject in the scene. The flash is disabled in order to preserve the
3324ambiance of the light.</entry>
3325 </row>
3326 <row>
3327 <entry><constant>V4L2_SCENE_MODE_DAWN_DUSK</constant>&nbsp;</entry>
3328 <entry>Dawn and dusk. Preserves the colors seen in low
3329natural light before dusk and after down. The camera may turn off the flash,
3330and automatically focus at infinity. It will usually boost saturation and
3331lower the shutter speed.</entry>
3332 </row>
3333 <row>
3334 <entry><constant>V4L2_SCENE_MODE_FALL_COLORS</constant>&nbsp;</entry>
3335 <entry>Fall colors. Increases saturation and adjusts white
3336balance for color enhancement. Pictures of autumn leaves get saturated reds
3337and yellows.</entry>
3338 </row>
3339 <row>
3340 <entry><constant>V4L2_SCENE_MODE_FIREWORKS</constant>&nbsp;</entry>
3341 <entry>Fireworks. Long exposure times are used to capture
3342the expanding burst of light from a firework. The camera may invoke image
3343stabilization.</entry>
3344 </row>
3345 <row>
3346 <entry><constant>V4L2_SCENE_MODE_LANDSCAPE</constant>&nbsp;</entry>
3347 <entry>Landscape. The camera may choose a small aperture to
3348provide deep depth of field and long exposure duration to help capture detail
3349in dim light conditions. The focus is fixed at infinity. Suitable for distant
3350and wide scenery.</entry>
3351 </row>
3352 <row>
3353 <entry><constant>V4L2_SCENE_MODE_NIGHT</constant>&nbsp;</entry>
3354 <entry>Night, also known as Night Landscape. Designed for low
3355light conditions, it preserves detail in the dark areas without blowing out bright
3356objects. The camera generally sets itself to a medium-to-high ISO sensitivity,
3357with a relatively long exposure time, and turns flash off. As such, there will be
3358increased image noise and the possibility of blurred image.</entry>
3359 </row>
3360 <row>
3361 <entry><constant>V4L2_SCENE_MODE_PARTY_INDOOR</constant>&nbsp;</entry>
3362 <entry>Party and indoor. Designed to capture indoor scenes
3363that are lit by indoor background lighting as well as the flash. The camera
3364usually increases ISO sensitivity, and adjusts exposure for the low light
3365conditions.</entry>
3366 </row>
3367 <row>
3368 <entry><constant>V4L2_SCENE_MODE_PORTRAIT</constant>&nbsp;</entry>
3369 <entry>Portrait. The camera adjusts the aperture so that the
3370depth of field is reduced, which helps to isolate the subject against a smooth
3371background. Most cameras recognize the presence of faces in the scene and focus
3372on them. The color hue is adjusted to enhance skin tones. The intensity of the
3373flash is often reduced.</entry>
3374 </row>
3375 <row>
3376 <entry><constant>V4L2_SCENE_MODE_SPORTS</constant>&nbsp;</entry>
3377 <entry>Sports. Significantly increases ISO and uses a fast
3378shutter speed to freeze motion of rapidly-moving subjects. Increased image
3379noise may be seen in this mode.</entry>
3380 </row>
3381 <row>
3382 <entry><constant>V4L2_SCENE_MODE_SUNSET</constant>&nbsp;</entry>
3383 <entry>Sunset. Preserves deep hues seen in sunsets and
3384sunrises. It bumps up the saturation.</entry>
3385 </row>
3386 <row>
3387 <entry><constant>V4L2_SCENE_MODE_TEXT</constant>&nbsp;</entry>
3388 <entry>Text. It applies extra contrast and sharpness, it is
3389typically a black-and-white mode optimized for readability. Automatic focus
3390may be switched to close-up mode and this setting may also involve some
3391lens-distortion correction.</entry>
3392 </row>
3393 </tbody>
3394 </entrytbl>
3395 </row>
3396 <row><entry></entry></row>
3397
3398 <row>
3399 <entry spanname="id"><constant>V4L2_CID_3A_LOCK</constant></entry>
3400 <entry>bitmask</entry>
3401 </row>
3402 <row>
3403 <entry spanname="descr">This control locks or unlocks the automatic
3404focus, exposure and white balance. The automatic adjustments can be paused
3405independently by setting the corresponding lock bit to 1. The camera then retains
3406the settings until the lock bit is cleared. The following lock bits are defined:
3407</entry>
3408 </row>
3409 <row>
3410 <entrytbl spanname="descr" cols="2">
3411 <tbody valign="top">
3412 <row>
3413 <entry><constant>V4L2_LOCK_EXPOSURE</constant></entry>
3414 <entry>Automatic exposure adjustments lock.</entry>
3415 </row>
3416 <row>
3417 <entry><constant>V4L2_LOCK_WHITE_BALANCE</constant></entry>
3418 <entry>Automatic white balance adjustments lock.</entry>
3419 </row>
3420 <row>
3421 <entry><constant>V4L2_LOCK_FOCUS</constant></entry>
3422 <entry>Automatic focus lock.</entry>
3423 </row>
3424 </tbody>
3425 </entrytbl>
3426 </row>
3427 <row><entry spanname="descr">
3428When a given algorithm is not enabled, drivers should ignore requests
3429to lock it and should return no error. An example might be an application
3430setting bit <constant>V4L2_LOCK_WHITE_BALANCE</constant> when the
3431<constant>V4L2_CID_AUTO_WHITE_BALANCE</constant> control is set to
3432<constant>FALSE</constant>. The value of this control may be changed
3433by exposure, white balance or focus controls.</entry>
3434 </row>
3435 <row><entry></entry></row>
3436
2935 </tbody> 3437 </tbody>
2936 </tgroup> 3438 </tgroup>
2937 </table> 3439 </table>
@@ -3476,7 +3978,7 @@ interface and may change in the future.</para>
3476 <entry spanname="id"><constant>V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant></entry> 3978 <entry spanname="id"><constant>V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant></entry>
3477 <entry>menu</entry> 3979 <entry>menu</entry>
3478 </row> 3980 </row>
3479 <row id="jpeg-chroma-subsampling-control"> 3981 <row id="v4l2-jpeg-chroma-subsampling">
3480 <entry spanname="descr">The chroma subsampling factors describe how 3982 <entry spanname="descr">The chroma subsampling factors describe how
3481 each component of an input image is sampled, in respect to maximum 3983 each component of an input image is sampled, in respect to maximum
3482 sample rate in each spatial dimension. See <xref linkend="itu-t81"/>, 3984 sample rate in each spatial dimension. See <xref linkend="itu-t81"/>,
@@ -3486,7 +3988,7 @@ interface and may change in the future.</para>
3486 from RGB to Y'CbCr color space. 3988 from RGB to Y'CbCr color space.
3487 </entry> 3989 </entry>
3488 </row> 3990 </row>
3489 <row> 3991 <row id = "v4l2-jpeg-chroma-subsampling">
3490 <entrytbl spanname="descr" cols="2"> 3992 <entrytbl spanname="descr" cols="2">
3491 <tbody valign="top"> 3993 <tbody valign="top">
3492 <row> 3994 <row>
@@ -3538,12 +4040,12 @@ interface and may change in the future.</para>
3538 </entry> 4040 </entry>
3539 </row> 4041 </row>
3540 <row id="jpeg-quality-control"> 4042 <row id="jpeg-quality-control">
3541 <entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant></entry> 4043 <entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESSION_QUALITY</constant></entry>
3542 <entry>integer</entry> 4044 <entry>integer</entry>
3543 </row> 4045 </row>
3544 <row> 4046 <row>
3545 <entry spanname="descr"> 4047 <entry spanname="descr">
3546 <constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control 4048 <constant>V4L2_CID_JPEG_COMPRESSION_QUALITY</constant> control
3547 determines trade-off between image quality and size. 4049 determines trade-off between image quality and size.
3548 It provides simpler method for applications to control image quality, 4050 It provides simpler method for applications to control image quality,
3549 without a need for direct reconfiguration of luminance and chrominance 4051 without a need for direct reconfiguration of luminance and chrominance
@@ -3551,7 +4053,7 @@ interface and may change in the future.</para>
3551 4053
3552 In cases where a driver uses quantization tables configured directly 4054 In cases where a driver uses quantization tables configured directly
3553 by an application, using interfaces defined elsewhere, <constant> 4055 by an application, using interfaces defined elsewhere, <constant>
3554 V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control should be set 4056 V4L2_CID_JPEG_COMPRESSION_QUALITY</constant> control should be set
3555 by driver to 0. 4057 by driver to 0.
3556 4058
3557 <para>The value range of this control is driver-specific. Only 4059 <para>The value range of this control is driver-specific. Only
@@ -3599,4 +4101,172 @@ interface and may change in the future.</para>
3599 to <xref linkend="itu-t81"/>, <xref linkend="jfif"/>, 4101 to <xref linkend="itu-t81"/>, <xref linkend="jfif"/>,
3600 <xref linkend="w3c-jpeg-jfif"/>.</para> 4102 <xref linkend="w3c-jpeg-jfif"/>.</para>
3601 </section> 4103 </section>
4104
4105 <section id="image-source-controls">
4106 <title>Image Source Control Reference</title>
4107
4108 <note>
4109 <title>Experimental</title>
4110
4111 <para>This is an <link
4112 linkend="experimental">experimental</link> interface and may
4113 change in the future.</para>
4114 </note>
4115
4116 <para>
4117 The Image Source control class is intended for low-level
4118 control of image source devices such as image sensors. The
4119 devices feature an analogue to digital converter and a bus
4120 transmitter to transmit the image data out of the device.
4121 </para>
4122
4123 <table pgwide="1" frame="none" id="image-source-control-id">
4124 <title>Image Source Control IDs</title>
4125
4126 <tgroup cols="4">
4127 <colspec colname="c1" colwidth="1*" />
4128 <colspec colname="c2" colwidth="6*" />
4129 <colspec colname="c3" colwidth="2*" />
4130 <colspec colname="c4" colwidth="6*" />
4131 <spanspec namest="c1" nameend="c2" spanname="id" />
4132 <spanspec namest="c2" nameend="c4" spanname="descr" />
4133 <thead>
4134 <row>
4135 <entry spanname="id" align="left">ID</entry>
4136 <entry align="left">Type</entry>
4137 </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
4138 </row>
4139 </thead>
4140 <tbody valign="top">
4141 <row><entry></entry></row>
4142 <row>
4143 <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry>
4144 <entry>class</entry>
4145 </row>
4146 <row>
4147 <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
4148 </row>
4149 <row>
4150 <entry spanname="id"><constant>V4L2_CID_VBLANK</constant></entry>
4151 <entry>integer</entry>
4152 </row>
4153 <row>
4154 <entry spanname="descr">Vertical blanking. The idle period
4155 after every frame during which no image data is produced.
4156 The unit of vertical blanking is a line. Every line has
4157 length of the image width plus horizontal blanking at the
4158 pixel rate defined by
4159 <constant>V4L2_CID_PIXEL_RATE</constant> control in the
4160 same sub-device.</entry>
4161 </row>
4162 <row>
4163 <entry spanname="id"><constant>V4L2_CID_HBLANK</constant></entry>
4164 <entry>integer</entry>
4165 </row>
4166 <row>
4167 <entry spanname="descr">Horizontal blanking. The idle
4168 period after every line of image data during which no
4169 image data is produced. The unit of horizontal blanking is
4170 pixels.</entry>
4171 </row>
4172 <row>
4173 <entry spanname="id"><constant>V4L2_CID_ANALOGUE_GAIN</constant></entry>
4174 <entry>integer</entry>
4175 </row>
4176 <row>
4177 <entry spanname="descr">Analogue gain is gain affecting
4178 all colour components in the pixel matrix. The gain
4179 operation is performed in the analogue domain before A/D
4180 conversion.
4181 </entry>
4182 </row>
4183 <row><entry></entry></row>
4184 </tbody>
4185 </tgroup>
4186 </table>
4187
4188 </section>
4189
4190 <section id="image-process-controls">
4191 <title>Image Process Control Reference</title>
4192
4193 <note>
4194 <title>Experimental</title>
4195
4196 <para>This is an <link
4197 linkend="experimental">experimental</link> interface and may
4198 change in the future.</para>
4199 </note>
4200
4201 <para>
4202 The Image Source control class is intended for low-level control of
4203 image processing functions. Unlike
4204 <constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant>, the controls in
4205 this class affect processing the image, and do not control capturing
4206 of it.
4207 </para>
4208
4209 <table pgwide="1" frame="none" id="image-process-control-id">
4210 <title>Image Source Control IDs</title>
4211
4212 <tgroup cols="4">
4213 <colspec colname="c1" colwidth="1*" />
4214 <colspec colname="c2" colwidth="6*" />
4215 <colspec colname="c3" colwidth="2*" />
4216 <colspec colname="c4" colwidth="6*" />
4217 <spanspec namest="c1" nameend="c2" spanname="id" />
4218 <spanspec namest="c2" nameend="c4" spanname="descr" />
4219 <thead>
4220 <row>
4221 <entry spanname="id" align="left">ID</entry>
4222 <entry align="left">Type</entry>
4223 </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
4224 </row>
4225 </thead>
4226 <tbody valign="top">
4227 <row><entry></entry></row>
4228 <row>
4229 <entry spanname="id"><constant>V4L2_CID_IMAGE_PROC_CLASS</constant></entry>
4230 <entry>class</entry>
4231 </row>
4232 <row>
4233 <entry spanname="descr">The IMAGE_PROC class descriptor.</entry>
4234 </row>
4235 <row>
4236 <entry spanname="id"><constant>V4L2_CID_LINK_FREQ</constant></entry>
4237 <entry>integer menu</entry>
4238 </row>
4239 <row>
4240 <entry spanname="descr">Data bus frequency. Together with the
4241 media bus pixel code, bus type (clock cycles per sample), the
4242 data bus frequency defines the pixel rate
4243 (<constant>V4L2_CID_PIXEL_RATE</constant>) in the
4244 pixel array (or possibly elsewhere, if the device is not an
4245 image sensor). The frame rate can be calculated from the pixel
4246 clock, image width and height and horizontal and vertical
4247 blanking. While the pixel rate control may be defined elsewhere
4248 than in the subdev containing the pixel array, the frame rate
4249 cannot be obtained from that information. This is because only
4250 on the pixel array it can be assumed that the vertical and
4251 horizontal blanking information is exact: no other blanking is
4252 allowed in the pixel array. The selection of frame rate is
4253 performed by selecting the desired horizontal and vertical
4254 blanking. The unit of this control is Hz. </entry>
4255 </row>
4256 <row>
4257 <entry spanname="id"><constant>V4L2_CID_PIXEL_RATE</constant></entry>
4258 <entry>64-bit integer</entry>
4259 </row>
4260 <row>
4261 <entry spanname="descr">Pixel rate in the source pads of
4262 the subdev. This control is read-only and its unit is
4263 pixels / second.
4264 </entry>
4265 </row>
4266 <row><entry></entry></row>
4267 </tbody>
4268 </tgroup>
4269 </table>
4270
4271 </section>
3602</section> 4272</section>
diff --git a/Documentation/DocBook/media/v4l/dev-subdev.xml b/Documentation/DocBook/media/v4l/dev-subdev.xml
index 0916a7343a16..4afcbbec5eda 100644
--- a/Documentation/DocBook/media/v4l/dev-subdev.xml
+++ b/Documentation/DocBook/media/v4l/dev-subdev.xml
@@ -76,11 +76,12 @@
76 <wordasword>format</wordasword> means the combination of media bus data 76 <wordasword>format</wordasword> means the combination of media bus data
77 format, frame width and frame height.</para></note> 77 format, frame width and frame height.</para></note>
78 78
79 <para>Image formats are typically negotiated on video capture and output 79 <para>Image formats are typically negotiated on video capture and
80 devices using the <link linkend="crop">cropping and scaling</link> ioctls. 80 output devices using the format and <link
81 The driver is responsible for configuring every block in the video pipeline 81 linkend="vidioc-subdev-g-selection">selection</link> ioctls. The
82 according to the requested format at the pipeline input and/or 82 driver is responsible for configuring every block in the video
83 output.</para> 83 pipeline according to the requested format at the pipeline input
84 and/or output.</para>
84 85
85 <para>For complex devices, such as often found in embedded systems, 86 <para>For complex devices, such as often found in embedded systems,
86 identical image sizes at the output of a pipeline can be achieved using 87 identical image sizes at the output of a pipeline can be achieved using
@@ -276,11 +277,11 @@
276 </section> 277 </section>
277 278
278 <section> 279 <section>
279 <title>Cropping and scaling</title> 280 <title>Selections: cropping, scaling and composition</title>
280 281
281 <para>Many sub-devices support cropping frames on their input or output 282 <para>Many sub-devices support cropping frames on their input or output
282 pads (or possible even on both). Cropping is used to select the area of 283 pads (or possible even on both). Cropping is used to select the area of
283 interest in an image, typically on a video sensor or video decoder. It can 284 interest in an image, typically on an image sensor or a video decoder. It can
284 also be used as part of digital zoom implementations to select the area of 285 also be used as part of digital zoom implementations to select the area of
285 the image that will be scaled up.</para> 286 the image that will be scaled up.</para>
286 287
@@ -288,26 +289,179 @@
288 &v4l2-rect; by the coordinates of the top left corner and the rectangle 289 &v4l2-rect; by the coordinates of the top left corner and the rectangle
289 size. Both the coordinates and sizes are expressed in pixels.</para> 290 size. Both the coordinates and sizes are expressed in pixels.</para>
290 291
291 <para>The crop rectangle is retrieved and set using the 292 <para>As for pad formats, drivers store try and active
292 &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad 293 rectangles for the selection targets of ACTUAL type <xref
293 formats, drivers store try and active crop rectangles. The format 294 linkend="v4l2-subdev-selection-targets">.</xref></para>
294 negotiation mechanism applies to crop settings as well.</para> 295
295 296 <para>On sink pads, cropping is applied relative to the
296 <para>On input pads, cropping is applied relatively to the current pad 297 current pad format. The pad format represents the image size as
297 format. The pad format represents the image size as received by the 298 received by the sub-device from the previous block in the
298 sub-device from the previous block in the pipeline, and the crop rectangle 299 pipeline, and the crop rectangle represents the sub-image that
299 represents the sub-image that will be transmitted further inside the 300 will be transmitted further inside the sub-device for
300 sub-device for processing. The crop rectangle be entirely containted 301 processing.</para>
301 inside the input image size.</para> 302
302 303 <para>The scaling operation changes the size of the image by
303 <para>Input crop rectangle are reset to their default value when the input 304 scaling it to new dimensions. The scaling ratio isn't specified
304 image format is modified. Drivers should use the input image size as the 305 explicitly, but is implied from the original and scaled image
305 crop rectangle default value, but hardware requirements may prevent this. 306 sizes. Both sizes are represented by &v4l2-rect;.</para>
306 </para> 307
308 <para>Scaling support is optional. When supported by a subdev,
309 the crop rectangle on the subdev's sink pad is scaled to the
310 size configured using the &VIDIOC-SUBDEV-S-SELECTION; IOCTL
311 using <constant>V4L2_SUBDEV_SEL_COMPOSE_ACTUAL</constant>
312 selection target on the same pad. If the subdev supports scaling
313 but not composing, the top and left values are not used and must
314 always be set to zero.</para>
315
316 <para>On source pads, cropping is similar to sink pads, with the
317 exception that the source size from which the cropping is
318 performed, is the COMPOSE rectangle on the sink pad. In both
319 sink and source pads, the crop rectangle must be entirely
320 contained inside the source image size for the crop
321 operation.</para>
322
323 <para>The drivers should always use the closest possible
324 rectangle the user requests on all selection targets, unless
325 specifically told otherwise.
326 <constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant> and
327 <constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant> flags may be
328 used to round the image size either up or down. <xref
329 linkend="v4l2-subdev-selection-flags"></xref></para>
330 </section>
331
332 <section>
333 <title>Types of selection targets</title>
334
335 <section>
336 <title>ACTUAL targets</title>
337
338 <para>ACTUAL targets reflect the actual hardware configuration
339 at any point of time. There is a BOUNDS target
340 corresponding to every ACTUAL.</para>
341 </section>
342
343 <section>
344 <title>BOUNDS targets</title>
345
346 <para>BOUNDS targets is the smallest rectangle that contains
347 all valid ACTUAL rectangles. It may not be possible to set the
348 ACTUAL rectangle as large as the BOUNDS rectangle, however.
349 This may be because e.g. a sensor's pixel array is not
350 rectangular but cross-shaped or round. The maximum size may
351 also be smaller than the BOUNDS rectangle.</para>
352 </section>
307 353
308 <para>Cropping behaviour on output pads is not defined.</para> 354 </section>
355
356 <section>
357 <title>Order of configuration and format propagation</title>
358
359 <para>Inside subdevs, the order of image processing steps will
360 always be from the sink pad towards the source pad. This is also
361 reflected in the order in which the configuration must be
362 performed by the user: the changes made will be propagated to
363 any subsequent stages. If this behaviour is not desired, the
364 user must set
365 <constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant> flag. This
366 flag causes no propagation of the changes are allowed in any
367 circumstances. This may also cause the accessed rectangle to be
368 adjusted by the driver, depending on the properties of the
369 underlying hardware.</para>
370
371 <para>The coordinates to a step always refer to the actual size
372 of the previous step. The exception to this rule is the source
373 compose rectangle, which refers to the sink compose bounds
374 rectangle --- if it is supported by the hardware.</para>
375
376 <orderedlist>
377 <listitem>Sink pad format. The user configures the sink pad
378 format. This format defines the parameters of the image the
379 entity receives through the pad for further processing.</listitem>
380
381 <listitem>Sink pad actual crop selection. The sink pad crop
382 defines the crop performed to the sink pad format.</listitem>
383
384 <listitem>Sink pad actual compose selection. The size of the
385 sink pad compose rectangle defines the scaling ratio compared
386 to the size of the sink pad crop rectangle. The location of
387 the compose rectangle specifies the location of the actual
388 sink compose rectangle in the sink compose bounds
389 rectangle.</listitem>
390
391 <listitem>Source pad actual crop selection. Crop on the source
392 pad defines crop performed to the image in the sink compose
393 bounds rectangle.</listitem>
394
395 <listitem>Source pad format. The source pad format defines the
396 output pixel format of the subdev, as well as the other
397 parameters with the exception of the image width and height.
398 Width and height are defined by the size of the source pad
399 actual crop selection.</listitem>
400 </orderedlist>
401
402 <para>Accessing any of the above rectangles not supported by the
403 subdev will return <constant>EINVAL</constant>. Any rectangle
404 referring to a previous unsupported rectangle coordinates will
405 instead refer to the previous supported rectangle. For example,
406 if sink crop is not supported, the compose selection will refer
407 to the sink pad format dimensions instead.</para>
408
409 <figure id="subdev-image-processing-crop">
410 <title>Image processing in subdevs: simple crop example</title>
411 <mediaobject>
412 <imageobject>
413 <imagedata fileref="subdev-image-processing-crop.svg"
414 format="SVG" scale="200" />
415 </imageobject>
416 </mediaobject>
417 </figure>
418
419 <para>In the above example, the subdev supports cropping on its
420 sink pad. To configure it, the user sets the media bus format on
421 the subdev's sink pad. Now the actual crop rectangle can be set
422 on the sink pad --- the location and size of this rectangle
423 reflect the location and size of a rectangle to be cropped from
424 the sink format. The size of the sink crop rectangle will also
425 be the size of the format of the subdev's source pad.</para>
426
427 <figure id="subdev-image-processing-scaling-multi-source">
428 <title>Image processing in subdevs: scaling with multiple sources</title>
429 <mediaobject>
430 <imageobject>
431 <imagedata fileref="subdev-image-processing-scaling-multi-source.svg"
432 format="SVG" scale="200" />
433 </imageobject>
434 </mediaobject>
435 </figure>
436
437 <para>In this example, the subdev is capable of first cropping,
438 then scaling and finally cropping for two source pads
439 individually from the resulting scaled image. The location of
440 the scaled image in the cropped image is ignored in sink compose
441 target. Both of the locations of the source crop rectangles
442 refer to the sink scaling rectangle, independently cropping an
443 area at location specified by the source crop rectangle from
444 it.</para>
445
446 <figure id="subdev-image-processing-full">
447 <title>Image processing in subdevs: scaling and composition
448 with multiple sinks and sources</title>
449 <mediaobject>
450 <imageobject>
451 <imagedata fileref="subdev-image-processing-full.svg"
452 format="SVG" scale="200" />
453 </imageobject>
454 </mediaobject>
455 </figure>
456
457 <para>The subdev driver supports two sink pads and two source
458 pads. The images from both of the sink pads are individually
459 cropped, then scaled and further composed on the composition
460 bounds rectangle. From that, two independent streams are cropped
461 and sent out of the subdev from the source pads.</para>
309 462
310 </section> 463 </section>
464
311 </section> 465 </section>
312 466
313 &sub-subdev-formats; 467 &sub-subdev-formats;
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index b815929b5bba..fd6aca2922b6 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -543,12 +543,13 @@ and can range from zero to the number of buffers allocated
543with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry> 543with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
544 </row> 544 </row>
545 <row> 545 <row>
546 <entry>&v4l2-buf-type;</entry> 546 <entry>__u32</entry>
547 <entry><structfield>type</structfield></entry> 547 <entry><structfield>type</structfield></entry>
548 <entry></entry> 548 <entry></entry>
549 <entry>Type of the buffer, same as &v4l2-format; 549 <entry>Type of the buffer, same as &v4l2-format;
550<structfield>type</structfield> or &v4l2-requestbuffers; 550<structfield>type</structfield> or &v4l2-requestbuffers;
551<structfield>type</structfield>, set by the application.</entry> 551<structfield>type</structfield>, set by the application. See <xref
552linkend="v4l2-buf-type" /></entry>
552 </row> 553 </row>
553 <row> 554 <row>
554 <entry>__u32</entry> 555 <entry>__u32</entry>
@@ -568,7 +569,7 @@ refers to an input stream, applications when an output stream.</entry>
568linkend="buffer-flags" />.</entry> 569linkend="buffer-flags" />.</entry>
569 </row> 570 </row>
570 <row> 571 <row>
571 <entry>&v4l2-field;</entry> 572 <entry>__u32</entry>
572 <entry><structfield>field</structfield></entry> 573 <entry><structfield>field</structfield></entry>
573 <entry></entry> 574 <entry></entry>
574 <entry>Indicates the field order of the image in the 575 <entry>Indicates the field order of the image in the
@@ -630,11 +631,12 @@ bandwidth. These devices identify by not enumerating any video
630standards, see <xref linkend="standard" />.</para></entry> 631standards, see <xref linkend="standard" />.</para></entry>
631 </row> 632 </row>
632 <row> 633 <row>
633 <entry>&v4l2-memory;</entry> 634 <entry>__u32</entry>
634 <entry><structfield>memory</structfield></entry> 635 <entry><structfield>memory</structfield></entry>
635 <entry></entry> 636 <entry></entry>
636 <entry>This field must be set by applications and/or drivers 637 <entry>This field must be set by applications and/or drivers
637in accordance with the selected I/O method.</entry> 638in accordance with the selected I/O method. See <xref linkend="v4l2-memory"
639 /></entry>
638 </row> 640 </row>
639 <row> 641 <row>
640 <entry>union</entry> 642 <entry>union</entry>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-srggb10.xml b/Documentation/DocBook/media/v4l/pixfmt-srggb10.xml
index 7b274092e60c..c1c62a9acc2a 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-srggb10.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-srggb10.xml
@@ -1,4 +1,4 @@
1 <refentry> 1 <refentry id="pixfmt-srggb10">
2 <refmeta> 2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'), 3 <refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'),
4 V4L2_PIX_FMT_SGRBG10 ('BA10'), 4 V4L2_PIX_FMT_SGRBG10 ('BA10'),
diff --git a/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml b/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
new file mode 100644
index 000000000000..8eace3e2e7d4
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
@@ -0,0 +1,29 @@
1 <refentry id="pixfmt-srggb10dpcm8">
2 <refmeta>
3 <refentrytitle>
4 V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'),
5 V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
6 V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
7 V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8'),
8 </refentrytitle>
9 &manvol;
10 </refmeta>
11 <refnamediv>
12 <refname id="V4L2-PIX-FMT-SBGGR10DPCM8"><constant>V4L2_PIX_FMT_SBGGR10DPCM8</constant></refname>
13 <refname id="V4L2-PIX-FMT-SGBRG10DPCM8"><constant>V4L2_PIX_FMT_SGBRG10DPCM8</constant></refname>
14 <refname id="V4L2-PIX-FMT-SGRBG10DPCM8"><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></refname>
15 <refname id="V4L2-PIX-FMT-SRGGB10DPCM8"><constant>V4L2_PIX_FMT_SRGGB10DPCM8</constant></refname>
16 <refpurpose>10-bit Bayer formats compressed to 8 bits</refpurpose>
17 </refnamediv>
18 <refsect1>
19 <title>Description</title>
20
21 <para>The following four pixel formats are raw sRGB / Bayer formats
22 with 10 bits per colour compressed to 8 bits each, using DPCM
23 compression. DPCM, differential pulse-code modulation, is lossy.
24 Each colour component consumes 8 bits of memory. In other respects
25 this format is similar to <xref
26 linkend="pixfmt-srggb10">.</xref></para>
27
28 </refsect1>
29 </refentry>
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml
index 31eaae2469f9..f5ac15ed0549 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -673,6 +673,7 @@ access the palette, this must be done with ioctls of the Linux framebuffer API.<
673 &sub-srggb8; 673 &sub-srggb8;
674 &sub-sbggr16; 674 &sub-sbggr16;
675 &sub-srggb10; 675 &sub-srggb10;
676 &sub-srggb10dpcm8;
676 &sub-srggb12; 677 &sub-srggb12;
677 </section> 678 </section>
678 679
@@ -876,11 +877,6 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm
876 <entry>'S561'</entry> 877 <entry>'S561'</entry>
877 <entry>Compressed GBRG Bayer format used by the gspca driver.</entry> 878 <entry>Compressed GBRG Bayer format used by the gspca driver.</entry>
878 </row> 879 </row>
879 <row id="V4L2-PIX-FMT-SGRBG10DPCM8">
880 <entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry>
881 <entry>'DB10'</entry>
882 <entry>10 bit raw Bayer DPCM compressed to 8 bits.</entry>
883 </row>
884 <row id="V4L2-PIX-FMT-PAC207"> 880 <row id="V4L2-PIX-FMT-PAC207">
885 <entry><constant>V4L2_PIX_FMT_PAC207</constant></entry> 881 <entry><constant>V4L2_PIX_FMT_PAC207</constant></entry>
886 <entry>'P207'</entry> 882 <entry>'P207'</entry>
diff --git a/Documentation/DocBook/media/v4l/subdev-image-processing-crop.dia b/Documentation/DocBook/media/v4l/subdev-image-processing-crop.dia
new file mode 100644
index 000000000000..e32ba5362e1d
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/subdev-image-processing-crop.dia
@@ -0,0 +1,614 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
3 <dia:diagramdata>
4 <dia:attribute name="background">
5 <dia:color val="#ffffff"/>
6 </dia:attribute>
7 <dia:attribute name="pagebreak">
8 <dia:color val="#000099"/>
9 </dia:attribute>
10 <dia:attribute name="paper">
11 <dia:composite type="paper">
12 <dia:attribute name="name">
13 <dia:string>#A4#</dia:string>
14 </dia:attribute>
15 <dia:attribute name="tmargin">
16 <dia:real val="2.8222000598907471"/>
17 </dia:attribute>
18 <dia:attribute name="bmargin">
19 <dia:real val="2.8222000598907471"/>
20 </dia:attribute>
21 <dia:attribute name="lmargin">
22 <dia:real val="2.8222000598907471"/>
23 </dia:attribute>
24 <dia:attribute name="rmargin">
25 <dia:real val="2.8222000598907471"/>
26 </dia:attribute>
27 <dia:attribute name="is_portrait">
28 <dia:boolean val="false"/>
29 </dia:attribute>
30 <dia:attribute name="scaling">
31 <dia:real val="0.49000000953674316"/>
32 </dia:attribute>
33 <dia:attribute name="fitto">
34 <dia:boolean val="false"/>
35 </dia:attribute>
36 </dia:composite>
37 </dia:attribute>
38 <dia:attribute name="grid">
39 <dia:composite type="grid">
40 <dia:attribute name="width_x">
41 <dia:real val="1"/>
42 </dia:attribute>
43 <dia:attribute name="width_y">
44 <dia:real val="1"/>
45 </dia:attribute>
46 <dia:attribute name="visible_x">
47 <dia:int val="1"/>
48 </dia:attribute>
49 <dia:attribute name="visible_y">
50 <dia:int val="1"/>
51 </dia:attribute>
52 <dia:composite type="color"/>
53 </dia:composite>
54 </dia:attribute>
55 <dia:attribute name="color">
56 <dia:color val="#d8e5e5"/>
57 </dia:attribute>
58 <dia:attribute name="guides">
59 <dia:composite type="guides">
60 <dia:attribute name="hguides"/>
61 <dia:attribute name="vguides"/>
62 </dia:composite>
63 </dia:attribute>
64 </dia:diagramdata>
65 <dia:layer name="Background" visible="true" active="true">
66 <dia:object type="Standard - Box" version="0" id="O0">
67 <dia:attribute name="obj_pos">
68 <dia:point val="-0.4,6.5"/>
69 </dia:attribute>
70 <dia:attribute name="obj_bb">
71 <dia:rectangle val="-0.45,6.45;23.1387,16.2"/>
72 </dia:attribute>
73 <dia:attribute name="elem_corner">
74 <dia:point val="-0.4,6.5"/>
75 </dia:attribute>
76 <dia:attribute name="elem_width">
77 <dia:real val="23.48871579904775"/>
78 </dia:attribute>
79 <dia:attribute name="elem_height">
80 <dia:real val="9.6500000000000004"/>
81 </dia:attribute>
82 <dia:attribute name="border_width">
83 <dia:real val="0.10000000149011612"/>
84 </dia:attribute>
85 <dia:attribute name="show_background">
86 <dia:boolean val="false"/>
87 </dia:attribute>
88 </dia:object>
89 <dia:object type="Standard - Box" version="0" id="O1">
90 <dia:attribute name="obj_pos">
91 <dia:point val="0.225,9.45"/>
92 </dia:attribute>
93 <dia:attribute name="obj_bb">
94 <dia:rectangle val="0.175,9.4;8.225,14.7"/>
95 </dia:attribute>
96 <dia:attribute name="elem_corner">
97 <dia:point val="0.225,9.45"/>
98 </dia:attribute>
99 <dia:attribute name="elem_width">
100 <dia:real val="7.9499999999999975"/>
101 </dia:attribute>
102 <dia:attribute name="elem_height">
103 <dia:real val="5.1999999999999975"/>
104 </dia:attribute>
105 <dia:attribute name="border_width">
106 <dia:real val="0.10000000149011612"/>
107 </dia:attribute>
108 <dia:attribute name="border_color">
109 <dia:color val="#a52a2a"/>
110 </dia:attribute>
111 <dia:attribute name="show_background">
112 <dia:boolean val="true"/>
113 </dia:attribute>
114 </dia:object>
115 <dia:object type="Standard - Box" version="0" id="O2">
116 <dia:attribute name="obj_pos">
117 <dia:point val="3.175,10.55"/>
118 </dia:attribute>
119 <dia:attribute name="obj_bb">
120 <dia:rectangle val="3.125,10.5;7.925,14.45"/>
121 </dia:attribute>
122 <dia:attribute name="elem_corner">
123 <dia:point val="3.175,10.55"/>
124 </dia:attribute>
125 <dia:attribute name="elem_width">
126 <dia:real val="4.6999999999999975"/>
127 </dia:attribute>
128 <dia:attribute name="elem_height">
129 <dia:real val="3.8499999999999979"/>
130 </dia:attribute>
131 <dia:attribute name="border_width">
132 <dia:real val="0.10000000149011612"/>
133 </dia:attribute>
134 <dia:attribute name="border_color">
135 <dia:color val="#0000ff"/>
136 </dia:attribute>
137 <dia:attribute name="show_background">
138 <dia:boolean val="true"/>
139 </dia:attribute>
140 </dia:object>
141 <dia:object type="Standard - Text" version="1" id="O3">
142 <dia:attribute name="obj_pos">
143 <dia:point val="3.725,11.3875"/>
144 </dia:attribute>
145 <dia:attribute name="obj_bb">
146 <dia:rectangle val="3.725,10.7925;6.6025,13.14"/>
147 </dia:attribute>
148 <dia:attribute name="text">
149 <dia:composite type="text">
150 <dia:attribute name="string">
151 <dia:string>#sink
152crop
153selection#</dia:string>
154 </dia:attribute>
155 <dia:attribute name="font">
156 <dia:font family="sans" style="0" name="Helvetica"/>
157 </dia:attribute>
158 <dia:attribute name="height">
159 <dia:real val="0.80000000000000004"/>
160 </dia:attribute>
161 <dia:attribute name="pos">
162 <dia:point val="3.725,11.3875"/>
163 </dia:attribute>
164 <dia:attribute name="color">
165 <dia:color val="#0000ff"/>
166 </dia:attribute>
167 <dia:attribute name="alignment">
168 <dia:enum val="0"/>
169 </dia:attribute>
170 </dia:composite>
171 </dia:attribute>
172 <dia:attribute name="valign">
173 <dia:enum val="3"/>
174 </dia:attribute>
175 </dia:object>
176 <dia:object type="Standard - Text" version="1" id="O4">
177 <dia:attribute name="obj_pos">
178 <dia:point val="1.475,7.9"/>
179 </dia:attribute>
180 <dia:attribute name="obj_bb">
181 <dia:rectangle val="1.475,7.305;1.475,8.0525"/>
182 </dia:attribute>
183 <dia:attribute name="text">
184 <dia:composite type="text">
185 <dia:attribute name="string">
186 <dia:string>##</dia:string>
187 </dia:attribute>
188 <dia:attribute name="font">
189 <dia:font family="sans" style="0" name="Helvetica"/>
190 </dia:attribute>
191 <dia:attribute name="height">
192 <dia:real val="0.80000000000000004"/>
193 </dia:attribute>
194 <dia:attribute name="pos">
195 <dia:point val="1.475,7.9"/>
196 </dia:attribute>
197 <dia:attribute name="color">
198 <dia:color val="#000000"/>
199 </dia:attribute>
200 <dia:attribute name="alignment">
201 <dia:enum val="0"/>
202 </dia:attribute>
203 </dia:composite>
204 </dia:attribute>
205 <dia:attribute name="valign">
206 <dia:enum val="3"/>
207 </dia:attribute>
208 </dia:object>
209 <dia:object type="Standard - Text" version="1" id="O5">
210 <dia:attribute name="obj_pos">
211 <dia:point val="0.426918,7.89569"/>
212 </dia:attribute>
213 <dia:attribute name="obj_bb">
214 <dia:rectangle val="0.426918,7.30069;3.90942,8.84819"/>
215 </dia:attribute>
216 <dia:attribute name="text">
217 <dia:composite type="text">
218 <dia:attribute name="string">
219 <dia:string>#sink media
220bus format#</dia:string>
221 </dia:attribute>
222 <dia:attribute name="font">
223 <dia:font family="sans" style="0" name="Helvetica"/>
224 </dia:attribute>
225 <dia:attribute name="height">
226 <dia:real val="0.80000000000000004"/>
227 </dia:attribute>
228 <dia:attribute name="pos">
229 <dia:point val="0.426918,7.89569"/>
230 </dia:attribute>
231 <dia:attribute name="color">
232 <dia:color val="#a52a2a"/>
233 </dia:attribute>
234 <dia:attribute name="alignment">
235 <dia:enum val="0"/>
236 </dia:attribute>
237 </dia:composite>
238 </dia:attribute>
239 <dia:attribute name="valign">
240 <dia:enum val="3"/>
241 </dia:attribute>
242 </dia:object>
243 <dia:object type="Standard - Text" version="1" id="O6">
244 <dia:attribute name="obj_pos">
245 <dia:point val="17.4887,7.75"/>
246 </dia:attribute>
247 <dia:attribute name="obj_bb">
248 <dia:rectangle val="17.4887,7.155;21.8112,8.7025"/>
249 </dia:attribute>
250 <dia:attribute name="text">
251 <dia:composite type="text">
252 <dia:attribute name="string">
253 <dia:string>#source media
254bus format#</dia:string>
255 </dia:attribute>
256 <dia:attribute name="font">
257 <dia:font family="sans" style="0" name="Helvetica"/>
258 </dia:attribute>
259 <dia:attribute name="height">
260 <dia:real val="0.80000000000000004"/>
261 </dia:attribute>
262 <dia:attribute name="pos">
263 <dia:point val="17.4887,7.75"/>
264 </dia:attribute>
265 <dia:attribute name="color">
266 <dia:color val="#8b6914"/>
267 </dia:attribute>
268 <dia:attribute name="alignment">
269 <dia:enum val="0"/>
270 </dia:attribute>
271 </dia:composite>
272 </dia:attribute>
273 <dia:attribute name="valign">
274 <dia:enum val="3"/>
275 </dia:attribute>
276 </dia:object>
277 <dia:object type="Standard - Box" version="0" id="O7">
278 <dia:attribute name="obj_pos">
279 <dia:point val="17.5244,9.5417"/>
280 </dia:attribute>
281 <dia:attribute name="obj_bb">
282 <dia:rectangle val="17.4744,9.4917;22.2387,13.35"/>
283 </dia:attribute>
284 <dia:attribute name="elem_corner">
285 <dia:point val="17.5244,9.5417"/>
286 </dia:attribute>
287 <dia:attribute name="elem_width">
288 <dia:real val="4.6643157990477508"/>
289 </dia:attribute>
290 <dia:attribute name="elem_height">
291 <dia:real val="3.758300000000002"/>
292 </dia:attribute>
293 <dia:attribute name="border_width">
294 <dia:real val="0.10000000149011612"/>
295 </dia:attribute>
296 <dia:attribute name="border_color">
297 <dia:color val="#8b6914"/>
298 </dia:attribute>
299 <dia:attribute name="show_background">
300 <dia:boolean val="true"/>
301 </dia:attribute>
302 </dia:object>
303 <dia:object type="Standard - Line" version="0" id="O8">
304 <dia:attribute name="obj_pos">
305 <dia:point val="17.5244,13.3"/>
306 </dia:attribute>
307 <dia:attribute name="obj_bb">
308 <dia:rectangle val="3.12132,13.2463;17.5781,14.4537"/>
309 </dia:attribute>
310 <dia:attribute name="conn_endpoints">
311 <dia:point val="17.5244,13.3"/>
312 <dia:point val="3.175,14.4"/>
313 </dia:attribute>
314 <dia:attribute name="numcp">
315 <dia:int val="1"/>
316 </dia:attribute>
317 <dia:attribute name="line_color">
318 <dia:color val="#e60505"/>
319 </dia:attribute>
320 <dia:attribute name="line_style">
321 <dia:enum val="4"/>
322 </dia:attribute>
323 <dia:connections>
324 <dia:connection handle="0" to="O7" connection="5"/>
325 <dia:connection handle="1" to="O2" connection="5"/>
326 </dia:connections>
327 </dia:object>
328 <dia:object type="Standard - Line" version="0" id="O9">
329 <dia:attribute name="obj_pos">
330 <dia:point val="17.5244,9.5417"/>
331 </dia:attribute>
332 <dia:attribute name="obj_bb">
333 <dia:rectangle val="3.12162,9.48832;17.5778,10.6034"/>
334 </dia:attribute>
335 <dia:attribute name="conn_endpoints">
336 <dia:point val="17.5244,9.5417"/>
337 <dia:point val="3.175,10.55"/>
338 </dia:attribute>
339 <dia:attribute name="numcp">
340 <dia:int val="1"/>
341 </dia:attribute>
342 <dia:attribute name="line_color">
343 <dia:color val="#e60505"/>
344 </dia:attribute>
345 <dia:attribute name="line_style">
346 <dia:enum val="4"/>
347 </dia:attribute>
348 <dia:connections>
349 <dia:connection handle="0" to="O7" connection="0"/>
350 <dia:connection handle="1" to="O2" connection="0"/>
351 </dia:connections>
352 </dia:object>
353 <dia:object type="Standard - Line" version="0" id="O10">
354 <dia:attribute name="obj_pos">
355 <dia:point val="22.1887,13.3"/>
356 </dia:attribute>
357 <dia:attribute name="obj_bb">
358 <dia:rectangle val="7.82132,13.2463;22.2424,14.4537"/>
359 </dia:attribute>
360 <dia:attribute name="conn_endpoints">
361 <dia:point val="22.1887,13.3"/>
362 <dia:point val="7.875,14.4"/>
363 </dia:attribute>
364 <dia:attribute name="numcp">
365 <dia:int val="1"/>
366 </dia:attribute>
367 <dia:attribute name="line_color">
368 <dia:color val="#e60505"/>
369 </dia:attribute>
370 <dia:attribute name="line_style">
371 <dia:enum val="4"/>
372 </dia:attribute>
373 <dia:connections>
374 <dia:connection handle="0" to="O7" connection="7"/>
375 <dia:connection handle="1" to="O2" connection="7"/>
376 </dia:connections>
377 </dia:object>
378 <dia:object type="Standard - Line" version="0" id="O11">
379 <dia:attribute name="obj_pos">
380 <dia:point val="22.1887,9.5417"/>
381 </dia:attribute>
382 <dia:attribute name="obj_bb">
383 <dia:rectangle val="7.82161,9.48831;22.2421,10.6034"/>
384 </dia:attribute>
385 <dia:attribute name="conn_endpoints">
386 <dia:point val="22.1887,9.5417"/>
387 <dia:point val="7.875,10.55"/>
388 </dia:attribute>
389 <dia:attribute name="numcp">
390 <dia:int val="1"/>
391 </dia:attribute>
392 <dia:attribute name="line_color">
393 <dia:color val="#e60505"/>
394 </dia:attribute>
395 <dia:attribute name="line_style">
396 <dia:enum val="4"/>
397 </dia:attribute>
398 <dia:connections>
399 <dia:connection handle="0" to="O7" connection="2"/>
400 <dia:connection handle="1" to="O2" connection="2"/>
401 </dia:connections>
402 </dia:object>
403 <dia:object type="Geometric - Perfect Circle" version="1" id="O12">
404 <dia:attribute name="obj_pos">
405 <dia:point val="23.23,10.5742"/>
406 </dia:attribute>
407 <dia:attribute name="obj_bb">
408 <dia:rectangle val="23.18,10.5242;24.13,11.4742"/>
409 </dia:attribute>
410 <dia:attribute name="meta">
411 <dia:composite type="dict"/>
412 </dia:attribute>
413 <dia:attribute name="elem_corner">
414 <dia:point val="23.23,10.5742"/>
415 </dia:attribute>
416 <dia:attribute name="elem_width">
417 <dia:real val="0.84999999999999787"/>
418 </dia:attribute>
419 <dia:attribute name="elem_height">
420 <dia:real val="0.84999999999999787"/>
421 </dia:attribute>
422 <dia:attribute name="line_width">
423 <dia:real val="0.10000000000000001"/>
424 </dia:attribute>
425 <dia:attribute name="line_colour">
426 <dia:color val="#000000"/>
427 </dia:attribute>
428 <dia:attribute name="fill_colour">
429 <dia:color val="#ffffff"/>
430 </dia:attribute>
431 <dia:attribute name="show_background">
432 <dia:boolean val="true"/>
433 </dia:attribute>
434 <dia:attribute name="line_style">
435 <dia:enum val="0"/>
436 <dia:real val="1"/>
437 </dia:attribute>
438 <dia:attribute name="flip_horizontal">
439 <dia:boolean val="false"/>
440 </dia:attribute>
441 <dia:attribute name="flip_vertical">
442 <dia:boolean val="false"/>
443 </dia:attribute>
444 <dia:attribute name="subscale">
445 <dia:real val="1"/>
446 </dia:attribute>
447 </dia:object>
448 <dia:object type="Standard - Line" version="0" id="O13">
449 <dia:attribute name="obj_pos">
450 <dia:point val="24.08,10.9992"/>
451 </dia:attribute>
452 <dia:attribute name="obj_bb">
453 <dia:rectangle val="24.03,10.6388;32.4953,11.3624"/>
454 </dia:attribute>
455 <dia:attribute name="conn_endpoints">
456 <dia:point val="24.08,10.9992"/>
457 <dia:point val="32.3835,11.0007"/>
458 </dia:attribute>
459 <dia:attribute name="numcp">
460 <dia:int val="1"/>
461 </dia:attribute>
462 <dia:attribute name="end_arrow">
463 <dia:enum val="22"/>
464 </dia:attribute>
465 <dia:attribute name="end_arrow_length">
466 <dia:real val="0.5"/>
467 </dia:attribute>
468 <dia:attribute name="end_arrow_width">
469 <dia:real val="0.5"/>
470 </dia:attribute>
471 <dia:connections>
472 <dia:connection handle="0" to="O12" connection="3"/>
473 </dia:connections>
474 </dia:object>
475 <dia:object type="Standard - Text" version="1" id="O14">
476 <dia:attribute name="obj_pos">
477 <dia:point val="25.3454,10.49"/>
478 </dia:attribute>
479 <dia:attribute name="obj_bb">
480 <dia:rectangle val="25.3454,9.895;29.9904,10.6425"/>
481 </dia:attribute>
482 <dia:attribute name="text">
483 <dia:composite type="text">
484 <dia:attribute name="string">
485 <dia:string>#pad 1 (source)#</dia:string>
486 </dia:attribute>
487 <dia:attribute name="font">
488 <dia:font family="sans" style="0" name="Helvetica"/>
489 </dia:attribute>
490 <dia:attribute name="height">
491 <dia:real val="0.80000000000000004"/>
492 </dia:attribute>
493 <dia:attribute name="pos">
494 <dia:point val="25.3454,10.49"/>
495 </dia:attribute>
496 <dia:attribute name="color">
497 <dia:color val="#000000"/>
498 </dia:attribute>
499 <dia:attribute name="alignment">
500 <dia:enum val="0"/>
501 </dia:attribute>
502 </dia:composite>
503 </dia:attribute>
504 <dia:attribute name="valign">
505 <dia:enum val="3"/>
506 </dia:attribute>
507 </dia:object>
508 <dia:object type="Geometric - Perfect Circle" version="1" id="O15">
509 <dia:attribute name="obj_pos">
510 <dia:point val="-1.44491,11.6506"/>
511 </dia:attribute>
512 <dia:attribute name="obj_bb">
513 <dia:rectangle val="-1.49491,11.6006;-0.54491,12.5506"/>
514 </dia:attribute>
515 <dia:attribute name="meta">
516 <dia:composite type="dict"/>
517 </dia:attribute>
518 <dia:attribute name="elem_corner">
519 <dia:point val="-1.44491,11.6506"/>
520 </dia:attribute>
521 <dia:attribute name="elem_width">
522 <dia:real val="0.84999999999999787"/>
523 </dia:attribute>
524 <dia:attribute name="elem_height">
525 <dia:real val="0.84999999999999787"/>
526 </dia:attribute>
527 <dia:attribute name="line_width">
528 <dia:real val="0.10000000000000001"/>
529 </dia:attribute>
530 <dia:attribute name="line_colour">
531 <dia:color val="#000000"/>
532 </dia:attribute>
533 <dia:attribute name="fill_colour">
534 <dia:color val="#ffffff"/>
535 </dia:attribute>
536 <dia:attribute name="show_background">
537 <dia:boolean val="true"/>
538 </dia:attribute>
539 <dia:attribute name="line_style">
540 <dia:enum val="0"/>
541 <dia:real val="1"/>
542 </dia:attribute>
543 <dia:attribute name="flip_horizontal">
544 <dia:boolean val="false"/>
545 </dia:attribute>
546 <dia:attribute name="flip_vertical">
547 <dia:boolean val="false"/>
548 </dia:attribute>
549 <dia:attribute name="subscale">
550 <dia:real val="1"/>
551 </dia:attribute>
552 </dia:object>
553 <dia:object type="Standard - Line" version="0" id="O16">
554 <dia:attribute name="obj_pos">
555 <dia:point val="-9.61991,12.09"/>
556 </dia:attribute>
557 <dia:attribute name="obj_bb">
558 <dia:rectangle val="-9.67,11.7149;-1.33311,12.4385"/>
559 </dia:attribute>
560 <dia:attribute name="conn_endpoints">
561 <dia:point val="-9.61991,12.09"/>
562 <dia:point val="-1.44491,12.0756"/>
563 </dia:attribute>
564 <dia:attribute name="numcp">
565 <dia:int val="1"/>
566 </dia:attribute>
567 <dia:attribute name="end_arrow">
568 <dia:enum val="22"/>
569 </dia:attribute>
570 <dia:attribute name="end_arrow_length">
571 <dia:real val="0.5"/>
572 </dia:attribute>
573 <dia:attribute name="end_arrow_width">
574 <dia:real val="0.5"/>
575 </dia:attribute>
576 <dia:connections>
577 <dia:connection handle="1" to="O15" connection="2"/>
578 </dia:connections>
579 </dia:object>
580 <dia:object type="Standard - Text" version="1" id="O17">
581 <dia:attribute name="obj_pos">
582 <dia:point val="-7.39291,11.49"/>
583 </dia:attribute>
584 <dia:attribute name="obj_bb">
585 <dia:rectangle val="-7.39291,10.895;-3.58791,11.6425"/>
586 </dia:attribute>
587 <dia:attribute name="text">
588 <dia:composite type="text">
589 <dia:attribute name="string">
590 <dia:string>#pad 0 (sink)#</dia:string>
591 </dia:attribute>
592 <dia:attribute name="font">
593 <dia:font family="sans" style="0" name="Helvetica"/>
594 </dia:attribute>
595 <dia:attribute name="height">
596 <dia:real val="0.80000000000000004"/>
597 </dia:attribute>
598 <dia:attribute name="pos">
599 <dia:point val="-7.39291,11.49"/>
600 </dia:attribute>
601 <dia:attribute name="color">
602 <dia:color val="#000000"/>
603 </dia:attribute>
604 <dia:attribute name="alignment">
605 <dia:enum val="0"/>
606 </dia:attribute>
607 </dia:composite>
608 </dia:attribute>
609 <dia:attribute name="valign">
610 <dia:enum val="3"/>
611 </dia:attribute>
612 </dia:object>
613 </dia:layer>
614</dia:diagram>
diff --git a/Documentation/DocBook/media/v4l/subdev-image-processing-crop.svg b/Documentation/DocBook/media/v4l/subdev-image-processing-crop.svg
new file mode 100644
index 000000000000..18b0f5de9ed2
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/subdev-image-processing-crop.svg
@@ -0,0 +1,63 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
3<svg width="43cm" height="10cm" viewBox="-194 128 844 196" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="-8" y="130" width="469.774" height="193"/>
5 <g>
6 <rect style="fill: #ffffff" x="4.5" y="189" width="159" height="104"/>
7 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="4.5" y="189" width="159" height="104"/>
8 </g>
9 <g>
10 <rect style="fill: #ffffff" x="63.5" y="211" width="94" height="77"/>
11 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="63.5" y="211" width="94" height="77"/>
12 </g>
13 <text style="fill: #0000ff;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="74.5" y="227.75">
14 <tspan x="74.5" y="227.75">sink</tspan>
15 <tspan x="74.5" y="243.75">crop</tspan>
16 <tspan x="74.5" y="259.75">selection</tspan>
17 </text>
18 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="29.5" y="158">
19 <tspan x="29.5" y="158"></tspan>
20 </text>
21 <text style="fill: #a52a2a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="8.53836" y="157.914">
22 <tspan x="8.53836" y="157.914">sink media</tspan>
23 <tspan x="8.53836" y="173.914">bus format</tspan>
24 </text>
25 <text style="fill: #8b6914;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="349.774" y="155">
26 <tspan x="349.774" y="155">source media</tspan>
27 <tspan x="349.774" y="171">bus format</tspan>
28 </text>
29 <g>
30 <rect style="fill: #ffffff" x="350.488" y="190.834" width="93.2863" height="75.166"/>
31 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="350.488" y="190.834" width="93.2863" height="75.166"/>
32 </g>
33 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="350.488" y1="266" x2="63.5" y2="288"/>
34 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="350.488" y1="190.834" x2="63.5" y2="211"/>
35 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="443.774" y1="266" x2="157.5" y2="288"/>
36 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="443.774" y1="190.834" x2="157.5" y2="211"/>
37 <g>
38 <ellipse style="fill: #ffffff" cx="473.1" cy="219.984" rx="8.5" ry="8.5"/>
39 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="473.1" cy="219.984" rx="8.5" ry="8.5"/>
40 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="473.1" cy="219.984" rx="8.5" ry="8.5"/>
41 </g>
42 <g>
43 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="481.6" y1="219.984" x2="637.934" y2="220.012"/>
44 <polygon style="fill: #000000" points="645.434,220.014 635.433,225.012 637.934,220.012 635.435,215.012 "/>
45 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="645.434,220.014 635.433,225.012 637.934,220.012 635.435,215.012 "/>
46 </g>
47 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="506.908" y="209.8">
48 <tspan x="506.908" y="209.8">pad 1 (source)</tspan>
49 </text>
50 <g>
51 <ellipse style="fill: #ffffff" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
52 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
53 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
54 </g>
55 <g>
56 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-192.398" y1="241.8" x2="-38.6343" y2="241.529"/>
57 <polygon style="fill: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
58 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
59 </g>
60 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-147.858" y="229.8">
61 <tspan x="-147.858" y="229.8">pad 0 (sink)</tspan>
62 </text>
63</svg>
diff --git a/Documentation/DocBook/media/v4l/subdev-image-processing-full.dia b/Documentation/DocBook/media/v4l/subdev-image-processing-full.dia
new file mode 100644
index 000000000000..a0d782927840
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/subdev-image-processing-full.dia
@@ -0,0 +1,1588 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
3 <dia:diagramdata>
4 <dia:attribute name="background">
5 <dia:color val="#ffffff"/>
6 </dia:attribute>
7 <dia:attribute name="pagebreak">
8 <dia:color val="#000099"/>
9 </dia:attribute>
10 <dia:attribute name="paper">
11 <dia:composite type="paper">
12 <dia:attribute name="name">
13 <dia:string>#A4#</dia:string>
14 </dia:attribute>
15 <dia:attribute name="tmargin">
16 <dia:real val="2.8222000598907471"/>
17 </dia:attribute>
18 <dia:attribute name="bmargin">
19 <dia:real val="2.8222000598907471"/>
20 </dia:attribute>
21 <dia:attribute name="lmargin">
22 <dia:real val="2.8222000598907471"/>
23 </dia:attribute>
24 <dia:attribute name="rmargin">
25 <dia:real val="2.8222000598907471"/>
26 </dia:attribute>
27 <dia:attribute name="is_portrait">
28 <dia:boolean val="false"/>
29 </dia:attribute>
30 <dia:attribute name="scaling">
31 <dia:real val="0.49000000953674316"/>
32 </dia:attribute>
33 <dia:attribute name="fitto">
34 <dia:boolean val="false"/>
35 </dia:attribute>
36 </dia:composite>
37 </dia:attribute>
38 <dia:attribute name="grid">
39 <dia:composite type="grid">
40 <dia:attribute name="width_x">
41 <dia:real val="1"/>
42 </dia:attribute>
43 <dia:attribute name="width_y">
44 <dia:real val="1"/>
45 </dia:attribute>
46 <dia:attribute name="visible_x">
47 <dia:int val="1"/>
48 </dia:attribute>
49 <dia:attribute name="visible_y">
50 <dia:int val="1"/>
51 </dia:attribute>
52 <dia:composite type="color"/>
53 </dia:composite>
54 </dia:attribute>
55 <dia:attribute name="color">
56 <dia:color val="#d8e5e5"/>
57 </dia:attribute>
58 <dia:attribute name="guides">
59 <dia:composite type="guides">
60 <dia:attribute name="hguides"/>
61 <dia:attribute name="vguides"/>
62 </dia:composite>
63 </dia:attribute>
64 </dia:diagramdata>
65 <dia:layer name="Background" visible="true" active="true">
66 <dia:object type="Standard - Box" version="0" id="O0">
67 <dia:attribute name="obj_pos">
68 <dia:point val="15.945,6.45"/>
69 </dia:attribute>
70 <dia:attribute name="obj_bb">
71 <dia:rectangle val="15.895,6.4;26.4,18.95"/>
72 </dia:attribute>
73 <dia:attribute name="elem_corner">
74 <dia:point val="15.945,6.45"/>
75 </dia:attribute>
76 <dia:attribute name="elem_width">
77 <dia:real val="10.404999999254942"/>
78 </dia:attribute>
79 <dia:attribute name="elem_height">
80 <dia:real val="12.449999999999992"/>
81 </dia:attribute>
82 <dia:attribute name="border_width">
83 <dia:real val="0.10000000149011612"/>
84 </dia:attribute>
85 <dia:attribute name="border_color">
86 <dia:color val="#ff765a"/>
87 </dia:attribute>
88 <dia:attribute name="show_background">
89 <dia:boolean val="true"/>
90 </dia:attribute>
91 </dia:object>
92 <dia:object type="Standard - Box" version="0" id="O1">
93 <dia:attribute name="obj_pos">
94 <dia:point val="-0.1,3.65"/>
95 </dia:attribute>
96 <dia:attribute name="obj_bb">
97 <dia:rectangle val="-0.15,3.6;40.25,20.85"/>
98 </dia:attribute>
99 <dia:attribute name="elem_corner">
100 <dia:point val="-0.1,3.65"/>
101 </dia:attribute>
102 <dia:attribute name="elem_width">
103 <dia:real val="40.300000000000004"/>
104 </dia:attribute>
105 <dia:attribute name="elem_height">
106 <dia:real val="17.149999999999999"/>
107 </dia:attribute>
108 <dia:attribute name="border_width">
109 <dia:real val="0.10000000149011612"/>
110 </dia:attribute>
111 <dia:attribute name="show_background">
112 <dia:boolean val="false"/>
113 </dia:attribute>
114 </dia:object>
115 <dia:object type="Geometric - Perfect Circle" version="1" id="O2">
116 <dia:attribute name="obj_pos">
117 <dia:point val="-1.05,7.9106"/>
118 </dia:attribute>
119 <dia:attribute name="obj_bb">
120 <dia:rectangle val="-1.1,7.8606;-0.15,8.8106"/>
121 </dia:attribute>
122 <dia:attribute name="meta">
123 <dia:composite type="dict"/>
124 </dia:attribute>
125 <dia:attribute name="elem_corner">
126 <dia:point val="-1.05,7.9106"/>
127 </dia:attribute>
128 <dia:attribute name="elem_width">
129 <dia:real val="0.84999999999999787"/>
130 </dia:attribute>
131 <dia:attribute name="elem_height">
132 <dia:real val="0.84999999999999787"/>
133 </dia:attribute>
134 <dia:attribute name="line_width">
135 <dia:real val="0.10000000000000001"/>
136 </dia:attribute>
137 <dia:attribute name="line_colour">
138 <dia:color val="#000000"/>
139 </dia:attribute>
140 <dia:attribute name="fill_colour">
141 <dia:color val="#ffffff"/>
142 </dia:attribute>
143 <dia:attribute name="show_background">
144 <dia:boolean val="true"/>
145 </dia:attribute>
146 <dia:attribute name="line_style">
147 <dia:enum val="0"/>
148 <dia:real val="1"/>
149 </dia:attribute>
150 <dia:attribute name="flip_horizontal">
151 <dia:boolean val="false"/>
152 </dia:attribute>
153 <dia:attribute name="flip_vertical">
154 <dia:boolean val="false"/>
155 </dia:attribute>
156 <dia:attribute name="subscale">
157 <dia:real val="1"/>
158 </dia:attribute>
159 </dia:object>
160 <dia:object type="Geometric - Perfect Circle" version="1" id="O3">
161 <dia:attribute name="obj_pos">
162 <dia:point val="40.3366,9.8342"/>
163 </dia:attribute>
164 <dia:attribute name="obj_bb">
165 <dia:rectangle val="40.2866,9.7842;41.2366,10.7342"/>
166 </dia:attribute>
167 <dia:attribute name="meta">
168 <dia:composite type="dict"/>
169 </dia:attribute>
170 <dia:attribute name="elem_corner">
171 <dia:point val="40.3366,9.8342"/>
172 </dia:attribute>
173 <dia:attribute name="elem_width">
174 <dia:real val="0.84999999999999787"/>
175 </dia:attribute>
176 <dia:attribute name="elem_height">
177 <dia:real val="0.84999999999999787"/>
178 </dia:attribute>
179 <dia:attribute name="line_width">
180 <dia:real val="0.10000000000000001"/>
181 </dia:attribute>
182 <dia:attribute name="line_colour">
183 <dia:color val="#000000"/>
184 </dia:attribute>
185 <dia:attribute name="fill_colour">
186 <dia:color val="#ffffff"/>
187 </dia:attribute>
188 <dia:attribute name="show_background">
189 <dia:boolean val="true"/>
190 </dia:attribute>
191 <dia:attribute name="line_style">
192 <dia:enum val="0"/>
193 <dia:real val="1"/>
194 </dia:attribute>
195 <dia:attribute name="flip_horizontal">
196 <dia:boolean val="false"/>
197 </dia:attribute>
198 <dia:attribute name="flip_vertical">
199 <dia:boolean val="false"/>
200 </dia:attribute>
201 <dia:attribute name="subscale">
202 <dia:real val="1"/>
203 </dia:attribute>
204 </dia:object>
205 <dia:object type="Standard - Line" version="0" id="O4">
206 <dia:attribute name="obj_pos">
207 <dia:point val="-9.225,8.35"/>
208 </dia:attribute>
209 <dia:attribute name="obj_bb">
210 <dia:rectangle val="-9.27509,7.97487;-0.938197,8.69848"/>
211 </dia:attribute>
212 <dia:attribute name="conn_endpoints">
213 <dia:point val="-9.225,8.35"/>
214 <dia:point val="-1.05,8.3356"/>
215 </dia:attribute>
216 <dia:attribute name="numcp">
217 <dia:int val="1"/>
218 </dia:attribute>
219 <dia:attribute name="end_arrow">
220 <dia:enum val="22"/>
221 </dia:attribute>
222 <dia:attribute name="end_arrow_length">
223 <dia:real val="0.5"/>
224 </dia:attribute>
225 <dia:attribute name="end_arrow_width">
226 <dia:real val="0.5"/>
227 </dia:attribute>
228 <dia:connections>
229 <dia:connection handle="1" to="O2" connection="2"/>
230 </dia:connections>
231 </dia:object>
232 <dia:object type="Standard - Line" version="0" id="O5">
233 <dia:attribute name="obj_pos">
234 <dia:point val="41.1866,10.2592"/>
235 </dia:attribute>
236 <dia:attribute name="obj_bb">
237 <dia:rectangle val="41.1366,9.89879;49.6019,10.6224"/>
238 </dia:attribute>
239 <dia:attribute name="conn_endpoints">
240 <dia:point val="41.1866,10.2592"/>
241 <dia:point val="49.4901,10.2607"/>
242 </dia:attribute>
243 <dia:attribute name="numcp">
244 <dia:int val="1"/>
245 </dia:attribute>
246 <dia:attribute name="end_arrow">
247 <dia:enum val="22"/>
248 </dia:attribute>
249 <dia:attribute name="end_arrow_length">
250 <dia:real val="0.5"/>
251 </dia:attribute>
252 <dia:attribute name="end_arrow_width">
253 <dia:real val="0.5"/>
254 </dia:attribute>
255 <dia:connections>
256 <dia:connection handle="0" to="O3" connection="3"/>
257 </dia:connections>
258 </dia:object>
259 <dia:object type="Standard - Text" version="1" id="O6">
260 <dia:attribute name="obj_pos">
261 <dia:point val="-6.998,7.75"/>
262 </dia:attribute>
263 <dia:attribute name="obj_bb">
264 <dia:rectangle val="-6.998,7.155;-3.193,7.9025"/>
265 </dia:attribute>
266 <dia:attribute name="text">
267 <dia:composite type="text">
268 <dia:attribute name="string">
269 <dia:string>#pad 0 (sink)#</dia:string>
270 </dia:attribute>
271 <dia:attribute name="font">
272 <dia:font family="sans" style="0" name="Helvetica"/>
273 </dia:attribute>
274 <dia:attribute name="height">
275 <dia:real val="0.80000000000000004"/>
276 </dia:attribute>
277 <dia:attribute name="pos">
278 <dia:point val="-6.998,7.75"/>
279 </dia:attribute>
280 <dia:attribute name="color">
281 <dia:color val="#000000"/>
282 </dia:attribute>
283 <dia:attribute name="alignment">
284 <dia:enum val="0"/>
285 </dia:attribute>
286 </dia:composite>
287 </dia:attribute>
288 <dia:attribute name="valign">
289 <dia:enum val="3"/>
290 </dia:attribute>
291 </dia:object>
292 <dia:object type="Standard - Text" version="1" id="O7">
293 <dia:attribute name="obj_pos">
294 <dia:point val="42.452,9.75"/>
295 </dia:attribute>
296 <dia:attribute name="obj_bb">
297 <dia:rectangle val="42.452,9.155;47.097,9.9025"/>
298 </dia:attribute>
299 <dia:attribute name="text">
300 <dia:composite type="text">
301 <dia:attribute name="string">
302 <dia:string>#pad 2 (source)#</dia:string>
303 </dia:attribute>
304 <dia:attribute name="font">
305 <dia:font family="sans" style="0" name="Helvetica"/>
306 </dia:attribute>
307 <dia:attribute name="height">
308 <dia:real val="0.80000000000000004"/>
309 </dia:attribute>
310 <dia:attribute name="pos">
311 <dia:point val="42.452,9.75"/>
312 </dia:attribute>
313 <dia:attribute name="color">
314 <dia:color val="#000000"/>
315 </dia:attribute>
316 <dia:attribute name="alignment">
317 <dia:enum val="0"/>
318 </dia:attribute>
319 </dia:composite>
320 </dia:attribute>
321 <dia:attribute name="valign">
322 <dia:enum val="3"/>
323 </dia:attribute>
324 </dia:object>
325 <dia:object type="Standard - Box" version="0" id="O8">
326 <dia:attribute name="obj_pos">
327 <dia:point val="0.275,6"/>
328 </dia:attribute>
329 <dia:attribute name="obj_bb">
330 <dia:rectangle val="0.225,5.95;8.275,11.25"/>
331 </dia:attribute>
332 <dia:attribute name="elem_corner">
333 <dia:point val="0.275,6"/>
334 </dia:attribute>
335 <dia:attribute name="elem_width">
336 <dia:real val="7.9499999999999975"/>
337 </dia:attribute>
338 <dia:attribute name="elem_height">
339 <dia:real val="5.1999999999999975"/>
340 </dia:attribute>
341 <dia:attribute name="border_width">
342 <dia:real val="0.10000000149011612"/>
343 </dia:attribute>
344 <dia:attribute name="border_color">
345 <dia:color val="#a52a2a"/>
346 </dia:attribute>
347 <dia:attribute name="show_background">
348 <dia:boolean val="true"/>
349 </dia:attribute>
350 </dia:object>
351 <dia:object type="Standard - Box" version="0" id="O9">
352 <dia:attribute name="obj_pos">
353 <dia:point val="3.125,6.8"/>
354 </dia:attribute>
355 <dia:attribute name="obj_bb">
356 <dia:rectangle val="3.075,6.75;7.875,10.7"/>
357 </dia:attribute>
358 <dia:attribute name="elem_corner">
359 <dia:point val="3.125,6.8"/>
360 </dia:attribute>
361 <dia:attribute name="elem_width">
362 <dia:real val="4.6999999999999975"/>
363 </dia:attribute>
364 <dia:attribute name="elem_height">
365 <dia:real val="3.8499999999999979"/>
366 </dia:attribute>
367 <dia:attribute name="border_width">
368 <dia:real val="0.10000000149011612"/>
369 </dia:attribute>
370 <dia:attribute name="border_color">
371 <dia:color val="#0000ff"/>
372 </dia:attribute>
373 <dia:attribute name="show_background">
374 <dia:boolean val="true"/>
375 </dia:attribute>
376 </dia:object>
377 <dia:object type="Standard - Text" version="1" id="O10">
378 <dia:attribute name="obj_pos">
379 <dia:point val="1.525,4.45"/>
380 </dia:attribute>
381 <dia:attribute name="obj_bb">
382 <dia:rectangle val="1.525,3.855;1.525,4.6025"/>
383 </dia:attribute>
384 <dia:attribute name="text">
385 <dia:composite type="text">
386 <dia:attribute name="string">
387 <dia:string>##</dia:string>
388 </dia:attribute>
389 <dia:attribute name="font">
390 <dia:font family="sans" style="0" name="Helvetica"/>
391 </dia:attribute>
392 <dia:attribute name="height">
393 <dia:real val="0.80000000000000004"/>
394 </dia:attribute>
395 <dia:attribute name="pos">
396 <dia:point val="1.525,4.45"/>
397 </dia:attribute>
398 <dia:attribute name="color">
399 <dia:color val="#000000"/>
400 </dia:attribute>
401 <dia:attribute name="alignment">
402 <dia:enum val="0"/>
403 </dia:attribute>
404 </dia:composite>
405 </dia:attribute>
406 <dia:attribute name="valign">
407 <dia:enum val="3"/>
408 </dia:attribute>
409 </dia:object>
410 <dia:object type="Standard - Text" version="1" id="O11">
411 <dia:attribute name="obj_pos">
412 <dia:point val="0.476918,4.44569"/>
413 </dia:attribute>
414 <dia:attribute name="obj_bb">
415 <dia:rectangle val="0.476918,3.85069;3.95942,5.39819"/>
416 </dia:attribute>
417 <dia:attribute name="text">
418 <dia:composite type="text">
419 <dia:attribute name="string">
420 <dia:string>#sink media
421bus format#</dia:string>
422 </dia:attribute>
423 <dia:attribute name="font">
424 <dia:font family="sans" style="0" name="Helvetica"/>
425 </dia:attribute>
426 <dia:attribute name="height">
427 <dia:real val="0.80000000000000004"/>
428 </dia:attribute>
429 <dia:attribute name="pos">
430 <dia:point val="0.476918,4.44569"/>
431 </dia:attribute>
432 <dia:attribute name="color">
433 <dia:color val="#a52a2a"/>
434 </dia:attribute>
435 <dia:attribute name="alignment">
436 <dia:enum val="0"/>
437 </dia:attribute>
438 </dia:composite>
439 </dia:attribute>
440 <dia:attribute name="valign">
441 <dia:enum val="3"/>
442 </dia:attribute>
443 </dia:object>
444 <dia:object type="Standard - Box" version="0" id="O12">
445 <dia:attribute name="obj_pos">
446 <dia:point val="16.6822,9.28251"/>
447 </dia:attribute>
448 <dia:attribute name="obj_bb">
449 <dia:rectangle val="16.6322,9.23251;24.9922,17.9564"/>
450 </dia:attribute>
451 <dia:attribute name="elem_corner">
452 <dia:point val="16.6822,9.28251"/>
453 </dia:attribute>
454 <dia:attribute name="elem_width">
455 <dia:real val="8.2600228398861297"/>
456 </dia:attribute>
457 <dia:attribute name="elem_height">
458 <dia:real val="8.6238900617957164"/>
459 </dia:attribute>
460 <dia:attribute name="border_width">
461 <dia:real val="0.10000000149011612"/>
462 </dia:attribute>
463 <dia:attribute name="border_color">
464 <dia:color val="#00ff00"/>
465 </dia:attribute>
466 <dia:attribute name="show_background">
467 <dia:boolean val="true"/>
468 </dia:attribute>
469 </dia:object>
470 <dia:object type="Standard - Line" version="0" id="O13">
471 <dia:attribute name="obj_pos">
472 <dia:point val="16.6822,17.9064"/>
473 </dia:attribute>
474 <dia:attribute name="obj_bb">
475 <dia:rectangle val="3.05732,10.5823;16.7499,17.9741"/>
476 </dia:attribute>
477 <dia:attribute name="conn_endpoints">
478 <dia:point val="16.6822,17.9064"/>
479 <dia:point val="3.125,10.65"/>
480 </dia:attribute>
481 <dia:attribute name="numcp">
482 <dia:int val="1"/>
483 </dia:attribute>
484 <dia:attribute name="line_color">
485 <dia:color val="#e60505"/>
486 </dia:attribute>
487 <dia:attribute name="line_style">
488 <dia:enum val="4"/>
489 </dia:attribute>
490 <dia:connections>
491 <dia:connection handle="0" to="O12" connection="5"/>
492 <dia:connection handle="1" to="O9" connection="5"/>
493 </dia:connections>
494 </dia:object>
495 <dia:object type="Standard - Line" version="0" id="O14">
496 <dia:attribute name="obj_pos">
497 <dia:point val="16.6822,9.28251"/>
498 </dia:attribute>
499 <dia:attribute name="obj_bb">
500 <dia:rectangle val="3.06681,6.74181;16.7404,9.3407"/>
501 </dia:attribute>
502 <dia:attribute name="conn_endpoints">
503 <dia:point val="16.6822,9.28251"/>
504 <dia:point val="3.125,6.8"/>
505 </dia:attribute>
506 <dia:attribute name="numcp">
507 <dia:int val="1"/>
508 </dia:attribute>
509 <dia:attribute name="line_color">
510 <dia:color val="#e60505"/>
511 </dia:attribute>
512 <dia:attribute name="line_style">
513 <dia:enum val="4"/>
514 </dia:attribute>
515 <dia:connections>
516 <dia:connection handle="0" to="O12" connection="0"/>
517 <dia:connection handle="1" to="O9" connection="0"/>
518 </dia:connections>
519 </dia:object>
520 <dia:object type="Standard - Line" version="0" id="O15">
521 <dia:attribute name="obj_pos">
522 <dia:point val="24.9422,17.9064"/>
523 </dia:attribute>
524 <dia:attribute name="obj_bb">
525 <dia:rectangle val="7.75945,10.5845;25.0077,17.9719"/>
526 </dia:attribute>
527 <dia:attribute name="conn_endpoints">
528 <dia:point val="24.9422,17.9064"/>
529 <dia:point val="7.825,10.65"/>
530 </dia:attribute>
531 <dia:attribute name="numcp">
532 <dia:int val="1"/>
533 </dia:attribute>
534 <dia:attribute name="line_color">
535 <dia:color val="#e60505"/>
536 </dia:attribute>
537 <dia:attribute name="line_style">
538 <dia:enum val="4"/>
539 </dia:attribute>
540 <dia:connections>
541 <dia:connection handle="0" to="O12" connection="7"/>
542 <dia:connection handle="1" to="O9" connection="7"/>
543 </dia:connections>
544 </dia:object>
545 <dia:object type="Standard - Line" version="0" id="O16">
546 <dia:attribute name="obj_pos">
547 <dia:point val="24.9422,9.28251"/>
548 </dia:attribute>
549 <dia:attribute name="obj_bb">
550 <dia:rectangle val="7.76834,6.74334;24.9989,9.33917"/>
551 </dia:attribute>
552 <dia:attribute name="conn_endpoints">
553 <dia:point val="24.9422,9.28251"/>
554 <dia:point val="7.825,6.8"/>
555 </dia:attribute>
556 <dia:attribute name="numcp">
557 <dia:int val="1"/>
558 </dia:attribute>
559 <dia:attribute name="line_color">
560 <dia:color val="#e60505"/>
561 </dia:attribute>
562 <dia:attribute name="line_style">
563 <dia:enum val="4"/>
564 </dia:attribute>
565 <dia:connections>
566 <dia:connection handle="0" to="O12" connection="2"/>
567 <dia:connection handle="1" to="O9" connection="2"/>
568 </dia:connections>
569 </dia:object>
570 <dia:object type="Standard - Text" version="1" id="O17">
571 <dia:attribute name="obj_pos">
572 <dia:point val="16.7352,7.47209"/>
573 </dia:attribute>
574 <dia:attribute name="obj_bb">
575 <dia:rectangle val="16.7352,6.87709;22.5602,8.42459"/>
576 </dia:attribute>
577 <dia:attribute name="text">
578 <dia:composite type="text">
579 <dia:attribute name="string">
580 <dia:string>#sink compose
581selection (scaling)#</dia:string>
582 </dia:attribute>
583 <dia:attribute name="font">
584 <dia:font family="sans" style="0" name="Helvetica"/>
585 </dia:attribute>
586 <dia:attribute name="height">
587 <dia:real val="0.80000000000000004"/>
588 </dia:attribute>
589 <dia:attribute name="pos">
590 <dia:point val="16.7352,7.47209"/>
591 </dia:attribute>
592 <dia:attribute name="color">
593 <dia:color val="#00ff00"/>
594 </dia:attribute>
595 <dia:attribute name="alignment">
596 <dia:enum val="0"/>
597 </dia:attribute>
598 </dia:composite>
599 </dia:attribute>
600 <dia:attribute name="valign">
601 <dia:enum val="3"/>
602 </dia:attribute>
603 </dia:object>
604 <dia:object type="Standard - Box" version="0" id="O18">
605 <dia:attribute name="obj_pos">
606 <dia:point val="20.4661,9.72825"/>
607 </dia:attribute>
608 <dia:attribute name="obj_bb">
609 <dia:rectangle val="20.4161,9.67825;25.5254,13.3509"/>
610 </dia:attribute>
611 <dia:attribute name="elem_corner">
612 <dia:point val="20.4661,9.72825"/>
613 </dia:attribute>
614 <dia:attribute name="elem_width">
615 <dia:real val="5.009308462554376"/>
616 </dia:attribute>
617 <dia:attribute name="elem_height">
618 <dia:real val="3.5726155970598077"/>
619 </dia:attribute>
620 <dia:attribute name="border_width">
621 <dia:real val="0.10000000149011612"/>
622 </dia:attribute>
623 <dia:attribute name="border_color">
624 <dia:color val="#a020f0"/>
625 </dia:attribute>
626 <dia:attribute name="show_background">
627 <dia:boolean val="true"/>
628 </dia:attribute>
629 </dia:object>
630 <dia:object type="Standard - Text" version="1" id="O19">
631 <dia:attribute name="obj_pos">
632 <dia:point val="34.475,5.2564"/>
633 </dia:attribute>
634 <dia:attribute name="obj_bb">
635 <dia:rectangle val="34.475,4.6614;38.7975,6.2089"/>
636 </dia:attribute>
637 <dia:attribute name="text">
638 <dia:composite type="text">
639 <dia:attribute name="string">
640 <dia:string>#source media
641bus format#</dia:string>
642 </dia:attribute>
643 <dia:attribute name="font">
644 <dia:font family="sans" style="0" name="Helvetica"/>
645 </dia:attribute>
646 <dia:attribute name="height">
647 <dia:real val="0.80000000000000004"/>
648 </dia:attribute>
649 <dia:attribute name="pos">
650 <dia:point val="34.475,5.2564"/>
651 </dia:attribute>
652 <dia:attribute name="color">
653 <dia:color val="#8b6914"/>
654 </dia:attribute>
655 <dia:attribute name="alignment">
656 <dia:enum val="0"/>
657 </dia:attribute>
658 </dia:composite>
659 </dia:attribute>
660 <dia:attribute name="valign">
661 <dia:enum val="3"/>
662 </dia:attribute>
663 </dia:object>
664 <dia:object type="Standard - Box" version="0" id="O20">
665 <dia:attribute name="obj_pos">
666 <dia:point val="34.4244,8.6917"/>
667 </dia:attribute>
668 <dia:attribute name="obj_bb">
669 <dia:rectangle val="34.3744,8.6417;39.4837,12.3143"/>
670 </dia:attribute>
671 <dia:attribute name="elem_corner">
672 <dia:point val="34.4244,8.6917"/>
673 </dia:attribute>
674 <dia:attribute name="elem_width">
675 <dia:real val="5.009308462554376"/>
676 </dia:attribute>
677 <dia:attribute name="elem_height">
678 <dia:real val="3.5726155970598077"/>
679 </dia:attribute>
680 <dia:attribute name="border_width">
681 <dia:real val="0.10000000149011612"/>
682 </dia:attribute>
683 <dia:attribute name="border_color">
684 <dia:color val="#8b6914"/>
685 </dia:attribute>
686 <dia:attribute name="show_background">
687 <dia:boolean val="true"/>
688 </dia:attribute>
689 </dia:object>
690 <dia:object type="Standard - Line" version="0" id="O21">
691 <dia:attribute name="obj_pos">
692 <dia:point val="34.4244,12.2643"/>
693 </dia:attribute>
694 <dia:attribute name="obj_bb">
695 <dia:rectangle val="20.4125,12.2107;34.478,13.3545"/>
696 </dia:attribute>
697 <dia:attribute name="conn_endpoints">
698 <dia:point val="34.4244,12.2643"/>
699 <dia:point val="20.4661,13.3009"/>
700 </dia:attribute>
701 <dia:attribute name="numcp">
702 <dia:int val="1"/>
703 </dia:attribute>
704 <dia:attribute name="line_color">
705 <dia:color val="#e60505"/>
706 </dia:attribute>
707 <dia:attribute name="line_style">
708 <dia:enum val="4"/>
709 </dia:attribute>
710 <dia:connections>
711 <dia:connection handle="0" to="O20" connection="5"/>
712 <dia:connection handle="1" to="O18" connection="5"/>
713 </dia:connections>
714 </dia:object>
715 <dia:object type="Standard - Line" version="0" id="O22">
716 <dia:attribute name="obj_pos">
717 <dia:point val="34.4244,8.6917"/>
718 </dia:attribute>
719 <dia:attribute name="obj_bb">
720 <dia:rectangle val="20.4125,8.63813;34.478,9.78182"/>
721 </dia:attribute>
722 <dia:attribute name="conn_endpoints">
723 <dia:point val="34.4244,8.6917"/>
724 <dia:point val="20.4661,9.72825"/>
725 </dia:attribute>
726 <dia:attribute name="numcp">
727 <dia:int val="1"/>
728 </dia:attribute>
729 <dia:attribute name="line_color">
730 <dia:color val="#e60505"/>
731 </dia:attribute>
732 <dia:attribute name="line_style">
733 <dia:enum val="4"/>
734 </dia:attribute>
735 <dia:connections>
736 <dia:connection handle="0" to="O20" connection="0"/>
737 <dia:connection handle="1" to="O18" connection="0"/>
738 </dia:connections>
739 </dia:object>
740 <dia:object type="Standard - Line" version="0" id="O23">
741 <dia:attribute name="obj_pos">
742 <dia:point val="39.4337,12.2643"/>
743 </dia:attribute>
744 <dia:attribute name="obj_bb">
745 <dia:rectangle val="25.4218,12.2107;39.4873,13.3545"/>
746 </dia:attribute>
747 <dia:attribute name="conn_endpoints">
748 <dia:point val="39.4337,12.2643"/>
749 <dia:point val="25.4754,13.3009"/>
750 </dia:attribute>
751 <dia:attribute name="numcp">
752 <dia:int val="1"/>
753 </dia:attribute>
754 <dia:attribute name="line_color">
755 <dia:color val="#e60505"/>
756 </dia:attribute>
757 <dia:attribute name="line_style">
758 <dia:enum val="4"/>
759 </dia:attribute>
760 <dia:connections>
761 <dia:connection handle="0" to="O20" connection="7"/>
762 <dia:connection handle="1" to="O18" connection="7"/>
763 </dia:connections>
764 </dia:object>
765 <dia:object type="Standard - Line" version="0" id="O24">
766 <dia:attribute name="obj_pos">
767 <dia:point val="39.4337,8.6917"/>
768 </dia:attribute>
769 <dia:attribute name="obj_bb">
770 <dia:rectangle val="25.4218,8.63813;39.4873,9.78182"/>
771 </dia:attribute>
772 <dia:attribute name="conn_endpoints">
773 <dia:point val="39.4337,8.6917"/>
774 <dia:point val="25.4754,9.72825"/>
775 </dia:attribute>
776 <dia:attribute name="numcp">
777 <dia:int val="1"/>
778 </dia:attribute>
779 <dia:attribute name="line_color">
780 <dia:color val="#e60505"/>
781 </dia:attribute>
782 <dia:attribute name="line_style">
783 <dia:enum val="4"/>
784 </dia:attribute>
785 <dia:connections>
786 <dia:connection handle="0" to="O20" connection="2"/>
787 <dia:connection handle="1" to="O18" connection="2"/>
788 </dia:connections>
789 </dia:object>
790 <dia:object type="Standard - Text" version="1" id="O25">
791 <dia:attribute name="obj_pos">
792 <dia:point val="16.25,5.15"/>
793 </dia:attribute>
794 <dia:attribute name="obj_bb">
795 <dia:rectangle val="16.25,4.555;21.68,6.1025"/>
796 </dia:attribute>
797 <dia:attribute name="text">
798 <dia:composite type="text">
799 <dia:attribute name="string">
800 <dia:string>#sink compose
801bounds selection#</dia:string>
802 </dia:attribute>
803 <dia:attribute name="font">
804 <dia:font family="sans" style="0" name="Helvetica"/>
805 </dia:attribute>
806 <dia:attribute name="height">
807 <dia:real val="0.80000000000000004"/>
808 </dia:attribute>
809 <dia:attribute name="pos">
810 <dia:point val="16.25,5.15"/>
811 </dia:attribute>
812 <dia:attribute name="color">
813 <dia:color val="#ff765a"/>
814 </dia:attribute>
815 <dia:attribute name="alignment">
816 <dia:enum val="0"/>
817 </dia:attribute>
818 </dia:composite>
819 </dia:attribute>
820 <dia:attribute name="valign">
821 <dia:enum val="3"/>
822 </dia:attribute>
823 </dia:object>
824 <dia:object type="Geometric - Perfect Circle" version="1" id="O26">
825 <dia:attribute name="obj_pos">
826 <dia:point val="-1.02991,16.6506"/>
827 </dia:attribute>
828 <dia:attribute name="obj_bb">
829 <dia:rectangle val="-1.07991,16.6006;-0.12991,17.5506"/>
830 </dia:attribute>
831 <dia:attribute name="meta">
832 <dia:composite type="dict"/>
833 </dia:attribute>
834 <dia:attribute name="elem_corner">
835 <dia:point val="-1.02991,16.6506"/>
836 </dia:attribute>
837 <dia:attribute name="elem_width">
838 <dia:real val="0.84999999999999787"/>
839 </dia:attribute>
840 <dia:attribute name="elem_height">
841 <dia:real val="0.84999999999999787"/>
842 </dia:attribute>
843 <dia:attribute name="line_width">
844 <dia:real val="0.10000000000000001"/>
845 </dia:attribute>
846 <dia:attribute name="line_colour">
847 <dia:color val="#000000"/>
848 </dia:attribute>
849 <dia:attribute name="fill_colour">
850 <dia:color val="#ffffff"/>
851 </dia:attribute>
852 <dia:attribute name="show_background">
853 <dia:boolean val="true"/>
854 </dia:attribute>
855 <dia:attribute name="line_style">
856 <dia:enum val="0"/>
857 <dia:real val="1"/>
858 </dia:attribute>
859 <dia:attribute name="flip_horizontal">
860 <dia:boolean val="false"/>
861 </dia:attribute>
862 <dia:attribute name="flip_vertical">
863 <dia:boolean val="false"/>
864 </dia:attribute>
865 <dia:attribute name="subscale">
866 <dia:real val="1"/>
867 </dia:attribute>
868 </dia:object>
869 <dia:object type="Standard - Line" version="0" id="O27">
870 <dia:attribute name="obj_pos">
871 <dia:point val="-9.20491,17.09"/>
872 </dia:attribute>
873 <dia:attribute name="obj_bb">
874 <dia:rectangle val="-9.255,16.7149;-0.918107,17.4385"/>
875 </dia:attribute>
876 <dia:attribute name="conn_endpoints">
877 <dia:point val="-9.20491,17.09"/>
878 <dia:point val="-1.02991,17.0756"/>
879 </dia:attribute>
880 <dia:attribute name="numcp">
881 <dia:int val="1"/>
882 </dia:attribute>
883 <dia:attribute name="end_arrow">
884 <dia:enum val="22"/>
885 </dia:attribute>
886 <dia:attribute name="end_arrow_length">
887 <dia:real val="0.5"/>
888 </dia:attribute>
889 <dia:attribute name="end_arrow_width">
890 <dia:real val="0.5"/>
891 </dia:attribute>
892 <dia:connections>
893 <dia:connection handle="1" to="O26" connection="2"/>
894 </dia:connections>
895 </dia:object>
896 <dia:object type="Standard - Text" version="1" id="O28">
897 <dia:attribute name="obj_pos">
898 <dia:point val="-6.95,16.45"/>
899 </dia:attribute>
900 <dia:attribute name="obj_bb">
901 <dia:rectangle val="-6.95,15.855;-3.145,16.6025"/>
902 </dia:attribute>
903 <dia:attribute name="text">
904 <dia:composite type="text">
905 <dia:attribute name="string">
906 <dia:string>#pad 1 (sink)#</dia:string>
907 </dia:attribute>
908 <dia:attribute name="font">
909 <dia:font family="sans" style="0" name="Helvetica"/>
910 </dia:attribute>
911 <dia:attribute name="height">
912 <dia:real val="0.80000000000000004"/>
913 </dia:attribute>
914 <dia:attribute name="pos">
915 <dia:point val="-6.95,16.45"/>
916 </dia:attribute>
917 <dia:attribute name="color">
918 <dia:color val="#000000"/>
919 </dia:attribute>
920 <dia:attribute name="alignment">
921 <dia:enum val="0"/>
922 </dia:attribute>
923 </dia:composite>
924 </dia:attribute>
925 <dia:attribute name="valign">
926 <dia:enum val="3"/>
927 </dia:attribute>
928 </dia:object>
929 <dia:object type="Standard - Box" version="0" id="O29">
930 <dia:attribute name="obj_pos">
931 <dia:point val="0.390412,14.64"/>
932 </dia:attribute>
933 <dia:attribute name="obj_bb">
934 <dia:rectangle val="0.340412,14.59;6.045,18.8"/>
935 </dia:attribute>
936 <dia:attribute name="elem_corner">
937 <dia:point val="0.390412,14.64"/>
938 </dia:attribute>
939 <dia:attribute name="elem_width">
940 <dia:real val="5.604587512785236"/>
941 </dia:attribute>
942 <dia:attribute name="elem_height">
943 <dia:real val="4.1099999999999994"/>
944 </dia:attribute>
945 <dia:attribute name="border_width">
946 <dia:real val="0.10000000149011612"/>
947 </dia:attribute>
948 <dia:attribute name="border_color">
949 <dia:color val="#a52a2a"/>
950 </dia:attribute>
951 <dia:attribute name="show_background">
952 <dia:boolean val="true"/>
953 </dia:attribute>
954 </dia:object>
955 <dia:object type="Standard - Box" version="0" id="O30">
956 <dia:attribute name="obj_pos">
957 <dia:point val="2.645,15.74"/>
958 </dia:attribute>
959 <dia:attribute name="obj_bb">
960 <dia:rectangle val="2.595,15.69;5.6,18.3"/>
961 </dia:attribute>
962 <dia:attribute name="elem_corner">
963 <dia:point val="2.645,15.74"/>
964 </dia:attribute>
965 <dia:attribute name="elem_width">
966 <dia:real val="2.904999999254942"/>
967 </dia:attribute>
968 <dia:attribute name="elem_height">
969 <dia:real val="2.5100000000000016"/>
970 </dia:attribute>
971 <dia:attribute name="border_width">
972 <dia:real val="0.10000000149011612"/>
973 </dia:attribute>
974 <dia:attribute name="border_color">
975 <dia:color val="#0000ff"/>
976 </dia:attribute>
977 <dia:attribute name="show_background">
978 <dia:boolean val="true"/>
979 </dia:attribute>
980 </dia:object>
981 <dia:object type="Standard - Text" version="1" id="O31">
982 <dia:attribute name="obj_pos">
983 <dia:point val="1.595,12.99"/>
984 </dia:attribute>
985 <dia:attribute name="obj_bb">
986 <dia:rectangle val="1.595,12.395;1.595,13.1425"/>
987 </dia:attribute>
988 <dia:attribute name="text">
989 <dia:composite type="text">
990 <dia:attribute name="string">
991 <dia:string>##</dia:string>
992 </dia:attribute>
993 <dia:attribute name="font">
994 <dia:font family="sans" style="0" name="Helvetica"/>
995 </dia:attribute>
996 <dia:attribute name="height">
997 <dia:real val="0.80000000000000004"/>
998 </dia:attribute>
999 <dia:attribute name="pos">
1000 <dia:point val="1.595,12.99"/>
1001 </dia:attribute>
1002 <dia:attribute name="color">
1003 <dia:color val="#000000"/>
1004 </dia:attribute>
1005 <dia:attribute name="alignment">
1006 <dia:enum val="0"/>
1007 </dia:attribute>
1008 </dia:composite>
1009 </dia:attribute>
1010 <dia:attribute name="valign">
1011 <dia:enum val="3"/>
1012 </dia:attribute>
1013 </dia:object>
1014 <dia:object type="Standard - Line" version="0" id="O32">
1015 <dia:attribute name="obj_pos">
1016 <dia:point val="17.945,12.595"/>
1017 </dia:attribute>
1018 <dia:attribute name="obj_bb">
1019 <dia:rectangle val="2.58596,12.536;18.004,15.799"/>
1020 </dia:attribute>
1021 <dia:attribute name="conn_endpoints">
1022 <dia:point val="17.945,12.595"/>
1023 <dia:point val="2.645,15.74"/>
1024 </dia:attribute>
1025 <dia:attribute name="numcp">
1026 <dia:int val="1"/>
1027 </dia:attribute>
1028 <dia:attribute name="line_color">
1029 <dia:color val="#e60505"/>
1030 </dia:attribute>
1031 <dia:attribute name="line_style">
1032 <dia:enum val="4"/>
1033 </dia:attribute>
1034 <dia:connections>
1035 <dia:connection handle="0" to="O36" connection="0"/>
1036 <dia:connection handle="1" to="O30" connection="0"/>
1037 </dia:connections>
1038 </dia:object>
1039 <dia:object type="Standard - Line" version="0" id="O33">
1040 <dia:attribute name="obj_pos">
1041 <dia:point val="17.945,15.8"/>
1042 </dia:attribute>
1043 <dia:attribute name="obj_bb">
1044 <dia:rectangle val="2.58772,15.7427;18.0023,18.3073"/>
1045 </dia:attribute>
1046 <dia:attribute name="conn_endpoints">
1047 <dia:point val="17.945,15.8"/>
1048 <dia:point val="2.645,18.25"/>
1049 </dia:attribute>
1050 <dia:attribute name="numcp">
1051 <dia:int val="1"/>
1052 </dia:attribute>
1053 <dia:attribute name="line_color">
1054 <dia:color val="#e60505"/>
1055 </dia:attribute>
1056 <dia:attribute name="line_style">
1057 <dia:enum val="4"/>
1058 </dia:attribute>
1059 <dia:connections>
1060 <dia:connection handle="0" to="O36" connection="5"/>
1061 <dia:connection handle="1" to="O30" connection="5"/>
1062 </dia:connections>
1063 </dia:object>
1064 <dia:object type="Standard - Line" version="0" id="O34">
1065 <dia:attribute name="obj_pos">
1066 <dia:point val="21.7,15.8"/>
1067 </dia:attribute>
1068 <dia:attribute name="obj_bb">
1069 <dia:rectangle val="5.49307,15.7431;21.7569,18.3069"/>
1070 </dia:attribute>
1071 <dia:attribute name="conn_endpoints">
1072 <dia:point val="21.7,15.8"/>
1073 <dia:point val="5.55,18.25"/>
1074 </dia:attribute>
1075 <dia:attribute name="numcp">
1076 <dia:int val="1"/>
1077 </dia:attribute>
1078 <dia:attribute name="line_color">
1079 <dia:color val="#e60505"/>
1080 </dia:attribute>
1081 <dia:attribute name="line_style">
1082 <dia:enum val="4"/>
1083 </dia:attribute>
1084 <dia:connections>
1085 <dia:connection handle="0" to="O36" connection="7"/>
1086 <dia:connection handle="1" to="O30" connection="7"/>
1087 </dia:connections>
1088 </dia:object>
1089 <dia:object type="Standard - Line" version="0" id="O35">
1090 <dia:attribute name="obj_pos">
1091 <dia:point val="21.7,12.595"/>
1092 </dia:attribute>
1093 <dia:attribute name="obj_bb">
1094 <dia:rectangle val="5.49136,12.5364;21.7586,15.7986"/>
1095 </dia:attribute>
1096 <dia:attribute name="conn_endpoints">
1097 <dia:point val="21.7,12.595"/>
1098 <dia:point val="5.55,15.74"/>
1099 </dia:attribute>
1100 <dia:attribute name="numcp">
1101 <dia:int val="1"/>
1102 </dia:attribute>
1103 <dia:attribute name="line_color">
1104 <dia:color val="#e60505"/>
1105 </dia:attribute>
1106 <dia:attribute name="line_style">
1107 <dia:enum val="4"/>
1108 </dia:attribute>
1109 <dia:connections>
1110 <dia:connection handle="0" to="O36" connection="2"/>
1111 <dia:connection handle="1" to="O30" connection="2"/>
1112 </dia:connections>
1113 </dia:object>
1114 <dia:object type="Standard - Box" version="0" id="O36">
1115 <dia:attribute name="obj_pos">
1116 <dia:point val="17.945,12.595"/>
1117 </dia:attribute>
1118 <dia:attribute name="obj_bb">
1119 <dia:rectangle val="17.895,12.545;21.75,15.85"/>
1120 </dia:attribute>
1121 <dia:attribute name="elem_corner">
1122 <dia:point val="17.945,12.595"/>
1123 </dia:attribute>
1124 <dia:attribute name="elem_width">
1125 <dia:real val="3.7549999992549452"/>
1126 </dia:attribute>
1127 <dia:attribute name="elem_height">
1128 <dia:real val="3.2049999992549427"/>
1129 </dia:attribute>
1130 <dia:attribute name="border_width">
1131 <dia:real val="0.10000000149011612"/>
1132 </dia:attribute>
1133 <dia:attribute name="border_color">
1134 <dia:color val="#00ff00"/>
1135 </dia:attribute>
1136 <dia:attribute name="show_background">
1137 <dia:boolean val="false"/>
1138 </dia:attribute>
1139 </dia:object>
1140 <dia:object type="Standard - Box" version="0" id="O37">
1141 <dia:attribute name="obj_pos">
1142 <dia:point val="22.1631,14.2233"/>
1143 </dia:attribute>
1144 <dia:attribute name="obj_bb">
1145 <dia:rectangle val="22.1131,14.1733;25.45,16.7"/>
1146 </dia:attribute>
1147 <dia:attribute name="elem_corner">
1148 <dia:point val="22.1631,14.2233"/>
1149 </dia:attribute>
1150 <dia:attribute name="elem_width">
1151 <dia:real val="3.2369000000000021"/>
1152 </dia:attribute>
1153 <dia:attribute name="elem_height">
1154 <dia:real val="2.4267000000000003"/>
1155 </dia:attribute>
1156 <dia:attribute name="border_width">
1157 <dia:real val="0.10000000149011612"/>
1158 </dia:attribute>
1159 <dia:attribute name="border_color">
1160 <dia:color val="#a020f0"/>
1161 </dia:attribute>
1162 <dia:attribute name="show_background">
1163 <dia:boolean val="false"/>
1164 </dia:attribute>
1165 </dia:object>
1166 <dia:object type="Standard - Box" version="0" id="O38">
1167 <dia:attribute name="obj_pos">
1168 <dia:point val="34.6714,16.2367"/>
1169 </dia:attribute>
1170 <dia:attribute name="obj_bb">
1171 <dia:rectangle val="34.6214,16.1867;37.9,18.75"/>
1172 </dia:attribute>
1173 <dia:attribute name="elem_corner">
1174 <dia:point val="34.6714,16.2367"/>
1175 </dia:attribute>
1176 <dia:attribute name="elem_width">
1177 <dia:real val="3.178600000000003"/>
1178 </dia:attribute>
1179 <dia:attribute name="elem_height">
1180 <dia:real val="2.4632999999999967"/>
1181 </dia:attribute>
1182 <dia:attribute name="border_width">
1183 <dia:real val="0.10000000149011612"/>
1184 </dia:attribute>
1185 <dia:attribute name="border_color">
1186 <dia:color val="#8b6914"/>
1187 </dia:attribute>
1188 <dia:attribute name="show_background">
1189 <dia:boolean val="true"/>
1190 </dia:attribute>
1191 </dia:object>
1192 <dia:object type="Standard - Line" version="0" id="O39">
1193 <dia:attribute name="obj_pos">
1194 <dia:point val="34.6714,18.7"/>
1195 </dia:attribute>
1196 <dia:attribute name="obj_bb">
1197 <dia:rectangle val="22.1057,16.5926;34.7288,18.7574"/>
1198 </dia:attribute>
1199 <dia:attribute name="conn_endpoints">
1200 <dia:point val="34.6714,18.7"/>
1201 <dia:point val="22.1631,16.65"/>
1202 </dia:attribute>
1203 <dia:attribute name="numcp">
1204 <dia:int val="1"/>
1205 </dia:attribute>
1206 <dia:attribute name="line_color">
1207 <dia:color val="#e60505"/>
1208 </dia:attribute>
1209 <dia:attribute name="line_style">
1210 <dia:enum val="4"/>
1211 </dia:attribute>
1212 <dia:connections>
1213 <dia:connection handle="0" to="O38" connection="5"/>
1214 <dia:connection handle="1" to="O37" connection="5"/>
1215 </dia:connections>
1216 </dia:object>
1217 <dia:object type="Standard - Line" version="0" id="O40">
1218 <dia:attribute name="obj_pos">
1219 <dia:point val="34.6714,16.2367"/>
1220 </dia:attribute>
1221 <dia:attribute name="obj_bb">
1222 <dia:rectangle val="22.1058,14.166;34.7287,16.294"/>
1223 </dia:attribute>
1224 <dia:attribute name="conn_endpoints">
1225 <dia:point val="34.6714,16.2367"/>
1226 <dia:point val="22.1631,14.2233"/>
1227 </dia:attribute>
1228 <dia:attribute name="numcp">
1229 <dia:int val="1"/>
1230 </dia:attribute>
1231 <dia:attribute name="line_color">
1232 <dia:color val="#e60505"/>
1233 </dia:attribute>
1234 <dia:attribute name="line_style">
1235 <dia:enum val="4"/>
1236 </dia:attribute>
1237 <dia:connections>
1238 <dia:connection handle="0" to="O38" connection="0"/>
1239 <dia:connection handle="1" to="O37" connection="0"/>
1240 </dia:connections>
1241 </dia:object>
1242 <dia:object type="Standard - Line" version="0" id="O41">
1243 <dia:attribute name="obj_pos">
1244 <dia:point val="37.85,18.7"/>
1245 </dia:attribute>
1246 <dia:attribute name="obj_bb">
1247 <dia:rectangle val="25.3425,16.5925;37.9075,18.7575"/>
1248 </dia:attribute>
1249 <dia:attribute name="conn_endpoints">
1250 <dia:point val="37.85,18.7"/>
1251 <dia:point val="25.4,16.65"/>
1252 </dia:attribute>
1253 <dia:attribute name="numcp">
1254 <dia:int val="1"/>
1255 </dia:attribute>
1256 <dia:attribute name="line_color">
1257 <dia:color val="#e60505"/>
1258 </dia:attribute>
1259 <dia:attribute name="line_style">
1260 <dia:enum val="4"/>
1261 </dia:attribute>
1262 <dia:connections>
1263 <dia:connection handle="0" to="O38" connection="7"/>
1264 <dia:connection handle="1" to="O37" connection="7"/>
1265 </dia:connections>
1266 </dia:object>
1267 <dia:object type="Standard - Line" version="0" id="O42">
1268 <dia:attribute name="obj_pos">
1269 <dia:point val="37.85,16.2367"/>
1270 </dia:attribute>
1271 <dia:attribute name="obj_bb">
1272 <dia:rectangle val="25.3427,14.166;37.9073,16.294"/>
1273 </dia:attribute>
1274 <dia:attribute name="conn_endpoints">
1275 <dia:point val="37.85,16.2367"/>
1276 <dia:point val="25.4,14.2233"/>
1277 </dia:attribute>
1278 <dia:attribute name="numcp">
1279 <dia:int val="1"/>
1280 </dia:attribute>
1281 <dia:attribute name="line_color">
1282 <dia:color val="#e60505"/>
1283 </dia:attribute>
1284 <dia:attribute name="line_style">
1285 <dia:enum val="4"/>
1286 </dia:attribute>
1287 <dia:connections>
1288 <dia:connection handle="0" to="O38" connection="2"/>
1289 <dia:connection handle="1" to="O37" connection="2"/>
1290 </dia:connections>
1291 </dia:object>
1292 <dia:object type="Geometric - Perfect Circle" version="1" id="O43">
1293 <dia:attribute name="obj_pos">
1294 <dia:point val="40.347,16.7742"/>
1295 </dia:attribute>
1296 <dia:attribute name="obj_bb">
1297 <dia:rectangle val="40.297,16.7242;41.247,17.6742"/>
1298 </dia:attribute>
1299 <dia:attribute name="meta">
1300 <dia:composite type="dict"/>
1301 </dia:attribute>
1302 <dia:attribute name="elem_corner">
1303 <dia:point val="40.347,16.7742"/>
1304 </dia:attribute>
1305 <dia:attribute name="elem_width">
1306 <dia:real val="0.84999999999999787"/>
1307 </dia:attribute>
1308 <dia:attribute name="elem_height">
1309 <dia:real val="0.84999999999999787"/>
1310 </dia:attribute>
1311 <dia:attribute name="line_width">
1312 <dia:real val="0.10000000000000001"/>
1313 </dia:attribute>
1314 <dia:attribute name="line_colour">
1315 <dia:color val="#000000"/>
1316 </dia:attribute>
1317 <dia:attribute name="fill_colour">
1318 <dia:color val="#ffffff"/>
1319 </dia:attribute>
1320 <dia:attribute name="show_background">
1321 <dia:boolean val="true"/>
1322 </dia:attribute>
1323 <dia:attribute name="line_style">
1324 <dia:enum val="0"/>
1325 <dia:real val="1"/>
1326 </dia:attribute>
1327 <dia:attribute name="flip_horizontal">
1328 <dia:boolean val="false"/>
1329 </dia:attribute>
1330 <dia:attribute name="flip_vertical">
1331 <dia:boolean val="false"/>
1332 </dia:attribute>
1333 <dia:attribute name="subscale">
1334 <dia:real val="1"/>
1335 </dia:attribute>
1336 </dia:object>
1337 <dia:object type="Standard - Line" version="0" id="O44">
1338 <dia:attribute name="obj_pos">
1339 <dia:point val="41.197,17.1992"/>
1340 </dia:attribute>
1341 <dia:attribute name="obj_bb">
1342 <dia:rectangle val="41.147,16.8388;49.6123,17.5624"/>
1343 </dia:attribute>
1344 <dia:attribute name="conn_endpoints">
1345 <dia:point val="41.197,17.1992"/>
1346 <dia:point val="49.5005,17.2007"/>
1347 </dia:attribute>
1348 <dia:attribute name="numcp">
1349 <dia:int val="1"/>
1350 </dia:attribute>
1351 <dia:attribute name="end_arrow">
1352 <dia:enum val="22"/>
1353 </dia:attribute>
1354 <dia:attribute name="end_arrow_length">
1355 <dia:real val="0.5"/>
1356 </dia:attribute>
1357 <dia:attribute name="end_arrow_width">
1358 <dia:real val="0.5"/>
1359 </dia:attribute>
1360 <dia:connections>
1361 <dia:connection handle="0" to="O43" connection="3"/>
1362 </dia:connections>
1363 </dia:object>
1364 <dia:object type="Standard - Text" version="1" id="O45">
1365 <dia:attribute name="obj_pos">
1366 <dia:point val="42.4624,16.69"/>
1367 </dia:attribute>
1368 <dia:attribute name="obj_bb">
1369 <dia:rectangle val="42.4624,16.095;47.1074,16.8425"/>
1370 </dia:attribute>
1371 <dia:attribute name="text">
1372 <dia:composite type="text">
1373 <dia:attribute name="string">
1374 <dia:string>#pad 3 (source)#</dia:string>
1375 </dia:attribute>
1376 <dia:attribute name="font">
1377 <dia:font family="sans" style="0" name="Helvetica"/>
1378 </dia:attribute>
1379 <dia:attribute name="height">
1380 <dia:real val="0.80000000000000004"/>
1381 </dia:attribute>
1382 <dia:attribute name="pos">
1383 <dia:point val="42.4624,16.69"/>
1384 </dia:attribute>
1385 <dia:attribute name="color">
1386 <dia:color val="#000000"/>
1387 </dia:attribute>
1388 <dia:attribute name="alignment">
1389 <dia:enum val="0"/>
1390 </dia:attribute>
1391 </dia:composite>
1392 </dia:attribute>
1393 <dia:attribute name="valign">
1394 <dia:enum val="3"/>
1395 </dia:attribute>
1396 </dia:object>
1397 <dia:object type="Standard - Text" version="1" id="O46">
1398 <dia:attribute name="obj_pos">
1399 <dia:point val="9.85,4.55"/>
1400 </dia:attribute>
1401 <dia:attribute name="obj_bb">
1402 <dia:rectangle val="9.85,3.955;12.7275,6.3025"/>
1403 </dia:attribute>
1404 <dia:attribute name="text">
1405 <dia:composite type="text">
1406 <dia:attribute name="string">
1407 <dia:string>#sink
1408crop
1409selection#</dia:string>
1410 </dia:attribute>
1411 <dia:attribute name="font">
1412 <dia:font family="sans" style="0" name="Helvetica"/>
1413 </dia:attribute>
1414 <dia:attribute name="height">
1415 <dia:real val="0.80000000000000004"/>
1416 </dia:attribute>
1417 <dia:attribute name="pos">
1418 <dia:point val="9.85,4.55"/>
1419 </dia:attribute>
1420 <dia:attribute name="color">
1421 <dia:color val="#0000ff"/>
1422 </dia:attribute>
1423 <dia:attribute name="alignment">
1424 <dia:enum val="0"/>
1425 </dia:attribute>
1426 </dia:composite>
1427 </dia:attribute>
1428 <dia:attribute name="valign">
1429 <dia:enum val="3"/>
1430 </dia:attribute>
1431 </dia:object>
1432 <dia:object type="Standard - Text" version="1" id="O47">
1433 <dia:attribute name="obj_pos">
1434 <dia:point val="27.65,4.75"/>
1435 </dia:attribute>
1436 <dia:attribute name="obj_bb">
1437 <dia:rectangle val="27.65,4.155;30.5275,6.5025"/>
1438 </dia:attribute>
1439 <dia:attribute name="text">
1440 <dia:composite type="text">
1441 <dia:attribute name="string">
1442 <dia:string>#source
1443crop
1444selection#</dia:string>
1445 </dia:attribute>
1446 <dia:attribute name="font">
1447 <dia:font family="sans" style="0" name="Helvetica"/>
1448 </dia:attribute>
1449 <dia:attribute name="height">
1450 <dia:real val="0.80000000000000004"/>
1451 </dia:attribute>
1452 <dia:attribute name="pos">
1453 <dia:point val="27.65,4.75"/>
1454 </dia:attribute>
1455 <dia:attribute name="color">
1456 <dia:color val="#a020f0"/>
1457 </dia:attribute>
1458 <dia:attribute name="alignment">
1459 <dia:enum val="0"/>
1460 </dia:attribute>
1461 </dia:composite>
1462 </dia:attribute>
1463 <dia:attribute name="valign">
1464 <dia:enum val="3"/>
1465 </dia:attribute>
1466 </dia:object>
1467 <dia:object type="Standard - Line" version="0" id="O48">
1468 <dia:attribute name="obj_pos">
1469 <dia:point val="10.55,6.6"/>
1470 </dia:attribute>
1471 <dia:attribute name="obj_bb">
1472 <dia:rectangle val="7.7135,6.39438;10.6035,7.11605"/>
1473 </dia:attribute>
1474 <dia:attribute name="conn_endpoints">
1475 <dia:point val="10.55,6.6"/>
1476 <dia:point val="7.825,6.8"/>
1477 </dia:attribute>
1478 <dia:attribute name="numcp">
1479 <dia:int val="1"/>
1480 </dia:attribute>
1481 <dia:attribute name="line_color">
1482 <dia:color val="#0000ff"/>
1483 </dia:attribute>
1484 <dia:attribute name="end_arrow">
1485 <dia:enum val="22"/>
1486 </dia:attribute>
1487 <dia:attribute name="end_arrow_length">
1488 <dia:real val="0.5"/>
1489 </dia:attribute>
1490 <dia:attribute name="end_arrow_width">
1491 <dia:real val="0.5"/>
1492 </dia:attribute>
1493 <dia:connections>
1494 <dia:connection handle="1" to="O9" connection="2"/>
1495 </dia:connections>
1496 </dia:object>
1497 <dia:object type="Standard - Line" version="0" id="O49">
1498 <dia:attribute name="obj_pos">
1499 <dia:point val="10.45,6.55"/>
1500 </dia:attribute>
1501 <dia:attribute name="obj_bb">
1502 <dia:rectangle val="5.48029,6.48236;10.5176,15.8387"/>
1503 </dia:attribute>
1504 <dia:attribute name="conn_endpoints">
1505 <dia:point val="10.45,6.55"/>
1506 <dia:point val="5.55,15.74"/>
1507 </dia:attribute>
1508 <dia:attribute name="numcp">
1509 <dia:int val="1"/>
1510 </dia:attribute>
1511 <dia:attribute name="line_color">
1512 <dia:color val="#0000ff"/>
1513 </dia:attribute>
1514 <dia:attribute name="end_arrow">
1515 <dia:enum val="22"/>
1516 </dia:attribute>
1517 <dia:attribute name="end_arrow_length">
1518 <dia:real val="0.5"/>
1519 </dia:attribute>
1520 <dia:attribute name="end_arrow_width">
1521 <dia:real val="0.5"/>
1522 </dia:attribute>
1523 <dia:connections>
1524 <dia:connection handle="1" to="O30" connection="2"/>
1525 </dia:connections>
1526 </dia:object>
1527 <dia:object type="Standard - Line" version="0" id="O50">
1528 <dia:attribute name="obj_pos">
1529 <dia:point val="27.5246,6.66071"/>
1530 </dia:attribute>
1531 <dia:attribute name="obj_bb">
1532 <dia:rectangle val="25.406,6.59136;27.594,9.82122"/>
1533 </dia:attribute>
1534 <dia:attribute name="conn_endpoints">
1535 <dia:point val="27.5246,6.66071"/>
1536 <dia:point val="25.4754,9.72825"/>
1537 </dia:attribute>
1538 <dia:attribute name="numcp">
1539 <dia:int val="1"/>
1540 </dia:attribute>
1541 <dia:attribute name="line_color">
1542 <dia:color val="#a020f0"/>
1543 </dia:attribute>
1544 <dia:attribute name="end_arrow">
1545 <dia:enum val="22"/>
1546 </dia:attribute>
1547 <dia:attribute name="end_arrow_length">
1548 <dia:real val="0.5"/>
1549 </dia:attribute>
1550 <dia:attribute name="end_arrow_width">
1551 <dia:real val="0.5"/>
1552 </dia:attribute>
1553 <dia:connections>
1554 <dia:connection handle="1" to="O18" connection="2"/>
1555 </dia:connections>
1556 </dia:object>
1557 <dia:object type="Standard - Line" version="0" id="O51">
1558 <dia:attribute name="obj_pos">
1559 <dia:point val="27.5036,6.68935"/>
1560 </dia:attribute>
1561 <dia:attribute name="obj_bb">
1562 <dia:rectangle val="25.2161,6.62775;27.5652,14.331"/>
1563 </dia:attribute>
1564 <dia:attribute name="conn_endpoints">
1565 <dia:point val="27.5036,6.68935"/>
1566 <dia:point val="25.4,14.2233"/>
1567 </dia:attribute>
1568 <dia:attribute name="numcp">
1569 <dia:int val="1"/>
1570 </dia:attribute>
1571 <dia:attribute name="line_color">
1572 <dia:color val="#a020f0"/>
1573 </dia:attribute>
1574 <dia:attribute name="end_arrow">
1575 <dia:enum val="22"/>
1576 </dia:attribute>
1577 <dia:attribute name="end_arrow_length">
1578 <dia:real val="0.5"/>
1579 </dia:attribute>
1580 <dia:attribute name="end_arrow_width">
1581 <dia:real val="0.5"/>
1582 </dia:attribute>
1583 <dia:connections>
1584 <dia:connection handle="1" to="O37" connection="2"/>
1585 </dia:connections>
1586 </dia:object>
1587 </dia:layer>
1588</dia:diagram>
diff --git a/Documentation/DocBook/media/v4l/subdev-image-processing-full.svg b/Documentation/DocBook/media/v4l/subdev-image-processing-full.svg
new file mode 100644
index 000000000000..3322cf4c0093
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/subdev-image-processing-full.svg
@@ -0,0 +1,163 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
3<svg width="59cm" height="18cm" viewBox="-186 71 1178 346" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4 <g>
5 <rect style="fill: #ffffff" x="318.9" y="129" width="208.1" height="249"/>
6 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff765a" x="318.9" y="129" width="208.1" height="249"/>
7 </g>
8 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="-2" y="73" width="806" height="343"/>
9 <g>
10 <ellipse style="fill: #ffffff" cx="-12.5" cy="166.712" rx="8.5" ry="8.5"/>
11 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.5" cy="166.712" rx="8.5" ry="8.5"/>
12 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.5" cy="166.712" rx="8.5" ry="8.5"/>
13 </g>
14 <g>
15 <ellipse style="fill: #ffffff" cx="815.232" cy="205.184" rx="8.5" ry="8.5"/>
16 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.232" cy="205.184" rx="8.5" ry="8.5"/>
17 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.232" cy="205.184" rx="8.5" ry="8.5"/>
18 </g>
19 <g>
20 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-184.5" y1="167" x2="-30.7361" y2="166.729"/>
21 <polygon style="fill: #000000" points="-23.2361,166.716 -33.2272,171.734 -30.7361,166.729 -33.2449,161.734 "/>
22 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-23.2361,166.716 -33.2272,171.734 -30.7361,166.729 -33.2449,161.734 "/>
23 </g>
24 <g>
25 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="823.732" y1="205.184" x2="980.066" y2="205.212"/>
26 <polygon style="fill: #000000" points="987.566,205.214 977.565,210.212 980.066,205.212 977.567,200.212 "/>
27 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="987.566,205.214 977.565,210.212 980.066,205.212 977.567,200.212 "/>
28 </g>
29 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-139.96" y="155">
30 <tspan x="-139.96" y="155">pad 0 (sink)</tspan>
31 </text>
32 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="849.04" y="195">
33 <tspan x="849.04" y="195">pad 2 (source)</tspan>
34 </text>
35 <g>
36 <rect style="fill: #ffffff" x="5.5" y="120" width="159" height="104"/>
37 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="5.5" y="120" width="159" height="104"/>
38 </g>
39 <g>
40 <rect style="fill: #ffffff" x="62.5" y="136" width="94" height="77"/>
41 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="62.5" y="136" width="94" height="77"/>
42 </g>
43 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="30.5" y="89">
44 <tspan x="30.5" y="89"></tspan>
45 </text>
46 <text style="fill: #a52a2a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="9.53836" y="88.9138">
47 <tspan x="9.53836" y="88.9138">sink media</tspan>
48 <tspan x="9.53836" y="104.914">bus format</tspan>
49 </text>
50 <g>
51 <rect style="fill: #ffffff" x="333.644" y="185.65" width="165.2" height="172.478"/>
52 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" x="333.644" y="185.65" width="165.2" height="172.478"/>
53 </g>
54 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="358.128" x2="62.5" y2="213"/>
55 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="185.65" x2="62.5" y2="136"/>
56 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="358.128" x2="156.5" y2="213"/>
57 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="185.65" x2="156.5" y2="136"/>
58 <text style="fill: #00ff00;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="334.704" y="149.442">
59 <tspan x="334.704" y="149.442">sink compose</tspan>
60 <tspan x="334.704" y="165.442">selection (scaling)</tspan>
61 </text>
62 <g>
63 <rect style="fill: #ffffff" x="409.322" y="194.565" width="100.186" height="71.4523"/>
64 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="409.322" y="194.565" width="100.186" height="71.4523"/>
65 </g>
66 <text style="fill: #8b6914;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="689.5" y="105.128">
67 <tspan x="689.5" y="105.128">source media</tspan>
68 <tspan x="689.5" y="121.128">bus format</tspan>
69 </text>
70 <g>
71 <rect style="fill: #ffffff" x="688.488" y="173.834" width="100.186" height="71.4523"/>
72 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="688.488" y="173.834" width="100.186" height="71.4523"/>
73 </g>
74 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="688.488" y1="245.286" x2="409.322" y2="266.018"/>
75 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="688.488" y1="173.834" x2="409.322" y2="194.565"/>
76 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="788.674" y1="245.286" x2="509.508" y2="266.018"/>
77 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="788.674" y1="173.834" x2="509.508" y2="194.565"/>
78 <text style="fill: #ff765a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="325" y="103">
79 <tspan x="325" y="103">sink compose</tspan>
80 <tspan x="325" y="119">bounds selection</tspan>
81 </text>
82 <g>
83 <ellipse style="fill: #ffffff" cx="-12.0982" cy="341.512" rx="8.5" ry="8.5"/>
84 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.0982" cy="341.512" rx="8.5" ry="8.5"/>
85 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.0982" cy="341.512" rx="8.5" ry="8.5"/>
86 </g>
87 <g>
88 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-184.098" y1="341.8" x2="-30.3343" y2="341.529"/>
89 <polygon style="fill: #000000" points="-22.8343,341.516 -32.8254,346.534 -30.3343,341.529 -32.8431,336.534 "/>
90 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-22.8343,341.516 -32.8254,346.534 -30.3343,341.529 -32.8431,336.534 "/>
91 </g>
92 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-139" y="329">
93 <tspan x="-139" y="329">pad 1 (sink)</tspan>
94 </text>
95 <g>
96 <rect style="fill: #ffffff" x="7.80824" y="292.8" width="112.092" height="82.2"/>
97 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="7.80824" y="292.8" width="112.092" height="82.2"/>
98 </g>
99 <g>
100 <rect style="fill: #ffffff" x="52.9" y="314.8" width="58.1" height="50.2"/>
101 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="52.9" y="314.8" width="58.1" height="50.2"/>
102 </g>
103 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="31.9" y="259.8">
104 <tspan x="31.9" y="259.8"></tspan>
105 </text>
106 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="358.9" y1="251.9" x2="52.9" y2="314.8"/>
107 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="358.9" y1="316" x2="52.9" y2="365"/>
108 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="434" y1="316" x2="111" y2="365"/>
109 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="434" y1="251.9" x2="111" y2="314.8"/>
110 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" x="358.9" y="251.9" width="75.1" height="64.1"/>
111 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="443.262" y="284.466" width="64.738" height="48.534"/>
112 <g>
113 <rect style="fill: #ffffff" x="693.428" y="324.734" width="63.572" height="49.266"/>
114 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="693.428" y="324.734" width="63.572" height="49.266"/>
115 </g>
116 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="693.428" y1="374" x2="443.262" y2="333"/>
117 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="693.428" y1="324.734" x2="443.262" y2="284.466"/>
118 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="757" y1="374" x2="508" y2="333"/>
119 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="757" y1="324.734" x2="508" y2="284.466"/>
120 <g>
121 <ellipse style="fill: #ffffff" cx="815.44" cy="343.984" rx="8.5" ry="8.5"/>
122 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.44" cy="343.984" rx="8.5" ry="8.5"/>
123 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.44" cy="343.984" rx="8.5" ry="8.5"/>
124 </g>
125 <g>
126 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="823.94" y1="343.984" x2="980.274" y2="344.012"/>
127 <polygon style="fill: #000000" points="987.774,344.014 977.773,349.012 980.274,344.012 977.775,339.012 "/>
128 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="987.774,344.014 977.773,349.012 980.274,344.012 977.775,339.012 "/>
129 </g>
130 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="849.248" y="333.8">
131 <tspan x="849.248" y="333.8">pad 3 (source)</tspan>
132 </text>
133 <text style="fill: #0000ff;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="197" y="91">
134 <tspan x="197" y="91">sink</tspan>
135 <tspan x="197" y="107">crop</tspan>
136 <tspan x="197" y="123">selection</tspan>
137 </text>
138 <text style="fill: #a020f0;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="553" y="95">
139 <tspan x="553" y="95">source</tspan>
140 <tspan x="553" y="111">crop</tspan>
141 <tspan x="553" y="127">selection</tspan>
142 </text>
143 <g>
144 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x1="211" y1="132" x2="166.21" y2="135.287"/>
145 <polygon style="fill: #0000ff" points="158.73,135.836 168.337,130.118 166.21,135.287 169.069,140.091 "/>
146 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" points="158.73,135.836 168.337,130.118 166.21,135.287 169.069,140.091 "/>
147 </g>
148 <g>
149 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x1="209" y1="131" x2="115.581" y2="306.209"/>
150 <polygon style="fill: #0000ff" points="112.052,312.827 112.345,301.65 115.581,306.209 121.169,306.355 "/>
151 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" points="112.052,312.827 112.345,301.65 115.581,306.209 121.169,306.355 "/>
152 </g>
153 <g>
154 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="550.492" y1="133.214" x2="514.916" y2="186.469"/>
155 <polygon style="fill: #a020f0" points="510.75,192.706 512.147,181.613 514.916,186.469 520.463,187.168 "/>
156 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="510.75,192.706 512.147,181.613 514.916,186.469 520.463,187.168 "/>
157 </g>
158 <g>
159 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="550.072" y1="133.787" x2="510.618" y2="275.089"/>
160 <polygon style="fill: #a020f0" points="508.601,282.312 506.475,271.336 510.618,275.089 516.106,274.025 "/>
161 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="508.601,282.312 506.475,271.336 510.618,275.089 516.106,274.025 "/>
162 </g>
163</svg>
diff --git a/Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.dia b/Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.dia
new file mode 100644
index 000000000000..0cd50a7bda80
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.dia
@@ -0,0 +1,1152 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
3 <dia:diagramdata>
4 <dia:attribute name="background">
5 <dia:color val="#ffffff"/>
6 </dia:attribute>
7 <dia:attribute name="pagebreak">
8 <dia:color val="#000099"/>
9 </dia:attribute>
10 <dia:attribute name="paper">
11 <dia:composite type="paper">
12 <dia:attribute name="name">
13 <dia:string>#A4#</dia:string>
14 </dia:attribute>
15 <dia:attribute name="tmargin">
16 <dia:real val="2.8222000598907471"/>
17 </dia:attribute>
18 <dia:attribute name="bmargin">
19 <dia:real val="2.8222000598907471"/>
20 </dia:attribute>
21 <dia:attribute name="lmargin">
22 <dia:real val="2.8222000598907471"/>
23 </dia:attribute>
24 <dia:attribute name="rmargin">
25 <dia:real val="2.8222000598907471"/>
26 </dia:attribute>
27 <dia:attribute name="is_portrait">
28 <dia:boolean val="false"/>
29 </dia:attribute>
30 <dia:attribute name="scaling">
31 <dia:real val="0.49000000953674316"/>
32 </dia:attribute>
33 <dia:attribute name="fitto">
34 <dia:boolean val="false"/>
35 </dia:attribute>
36 </dia:composite>
37 </dia:attribute>
38 <dia:attribute name="grid">
39 <dia:composite type="grid">
40 <dia:attribute name="width_x">
41 <dia:real val="1"/>
42 </dia:attribute>
43 <dia:attribute name="width_y">
44 <dia:real val="1"/>
45 </dia:attribute>
46 <dia:attribute name="visible_x">
47 <dia:int val="1"/>
48 </dia:attribute>
49 <dia:attribute name="visible_y">
50 <dia:int val="1"/>
51 </dia:attribute>
52 <dia:composite type="color"/>
53 </dia:composite>
54 </dia:attribute>
55 <dia:attribute name="color">
56 <dia:color val="#d8e5e5"/>
57 </dia:attribute>
58 <dia:attribute name="guides">
59 <dia:composite type="guides">
60 <dia:attribute name="hguides"/>
61 <dia:attribute name="vguides"/>
62 </dia:composite>
63 </dia:attribute>
64 </dia:diagramdata>
65 <dia:layer name="Background" visible="true" active="true">
66 <dia:object type="Standard - Box" version="0" id="O0">
67 <dia:attribute name="obj_pos">
68 <dia:point val="-0.4,6.5"/>
69 </dia:attribute>
70 <dia:attribute name="obj_bb">
71 <dia:rectangle val="-0.45,6.45;39.95,22.9"/>
72 </dia:attribute>
73 <dia:attribute name="elem_corner">
74 <dia:point val="-0.4,6.5"/>
75 </dia:attribute>
76 <dia:attribute name="elem_width">
77 <dia:real val="40.299999999999997"/>
78 </dia:attribute>
79 <dia:attribute name="elem_height">
80 <dia:real val="16.349999999999998"/>
81 </dia:attribute>
82 <dia:attribute name="border_width">
83 <dia:real val="0.10000000149011612"/>
84 </dia:attribute>
85 <dia:attribute name="show_background">
86 <dia:boolean val="false"/>
87 </dia:attribute>
88 </dia:object>
89 <dia:object type="Standard - Box" version="0" id="O1">
90 <dia:attribute name="obj_pos">
91 <dia:point val="0.225,9.45"/>
92 </dia:attribute>
93 <dia:attribute name="obj_bb">
94 <dia:rectangle val="0.175,9.4;8.225,14.7"/>
95 </dia:attribute>
96 <dia:attribute name="elem_corner">
97 <dia:point val="0.225,9.45"/>
98 </dia:attribute>
99 <dia:attribute name="elem_width">
100 <dia:real val="7.9499999999999975"/>
101 </dia:attribute>
102 <dia:attribute name="elem_height">
103 <dia:real val="5.1999999999999975"/>
104 </dia:attribute>
105 <dia:attribute name="border_width">
106 <dia:real val="0.10000000149011612"/>
107 </dia:attribute>
108 <dia:attribute name="border_color">
109 <dia:color val="#a52a2a"/>
110 </dia:attribute>
111 <dia:attribute name="show_background">
112 <dia:boolean val="true"/>
113 </dia:attribute>
114 </dia:object>
115 <dia:object type="Standard - Box" version="0" id="O2">
116 <dia:attribute name="obj_pos">
117 <dia:point val="2.475,10.2"/>
118 </dia:attribute>
119 <dia:attribute name="obj_bb">
120 <dia:rectangle val="2.425,10.15;7.225,14.1"/>
121 </dia:attribute>
122 <dia:attribute name="elem_corner">
123 <dia:point val="2.475,10.2"/>
124 </dia:attribute>
125 <dia:attribute name="elem_width">
126 <dia:real val="4.6999999999999975"/>
127 </dia:attribute>
128 <dia:attribute name="elem_height">
129 <dia:real val="3.8499999999999979"/>
130 </dia:attribute>
131 <dia:attribute name="border_width">
132 <dia:real val="0.10000000149011612"/>
133 </dia:attribute>
134 <dia:attribute name="border_color">
135 <dia:color val="#0000ff"/>
136 </dia:attribute>
137 <dia:attribute name="show_background">
138 <dia:boolean val="true"/>
139 </dia:attribute>
140 </dia:object>
141 <dia:object type="Standard - Text" version="1" id="O3">
142 <dia:attribute name="obj_pos">
143 <dia:point val="3,11.2"/>
144 </dia:attribute>
145 <dia:attribute name="obj_bb">
146 <dia:rectangle val="3,10.605;5.8775,12.9525"/>
147 </dia:attribute>
148 <dia:attribute name="text">
149 <dia:composite type="text">
150 <dia:attribute name="string">
151 <dia:string>#sink
152crop
153selection#</dia:string>
154 </dia:attribute>
155 <dia:attribute name="font">
156 <dia:font family="sans" style="0" name="Helvetica"/>
157 </dia:attribute>
158 <dia:attribute name="height">
159 <dia:real val="0.80000000000000004"/>
160 </dia:attribute>
161 <dia:attribute name="pos">
162 <dia:point val="3,11.2"/>
163 </dia:attribute>
164 <dia:attribute name="color">
165 <dia:color val="#0000ff"/>
166 </dia:attribute>
167 <dia:attribute name="alignment">
168 <dia:enum val="0"/>
169 </dia:attribute>
170 </dia:composite>
171 </dia:attribute>
172 <dia:attribute name="valign">
173 <dia:enum val="3"/>
174 </dia:attribute>
175 </dia:object>
176 <dia:object type="Standard - Text" version="1" id="O4">
177 <dia:attribute name="obj_pos">
178 <dia:point val="1.475,7.9"/>
179 </dia:attribute>
180 <dia:attribute name="obj_bb">
181 <dia:rectangle val="1.475,7.305;1.475,8.0525"/>
182 </dia:attribute>
183 <dia:attribute name="text">
184 <dia:composite type="text">
185 <dia:attribute name="string">
186 <dia:string>##</dia:string>
187 </dia:attribute>
188 <dia:attribute name="font">
189 <dia:font family="sans" style="0" name="Helvetica"/>
190 </dia:attribute>
191 <dia:attribute name="height">
192 <dia:real val="0.80000000000000004"/>
193 </dia:attribute>
194 <dia:attribute name="pos">
195 <dia:point val="1.475,7.9"/>
196 </dia:attribute>
197 <dia:attribute name="color">
198 <dia:color val="#000000"/>
199 </dia:attribute>
200 <dia:attribute name="alignment">
201 <dia:enum val="0"/>
202 </dia:attribute>
203 </dia:composite>
204 </dia:attribute>
205 <dia:attribute name="valign">
206 <dia:enum val="3"/>
207 </dia:attribute>
208 </dia:object>
209 <dia:object type="Standard - Text" version="1" id="O5">
210 <dia:attribute name="obj_pos">
211 <dia:point val="0.426918,7.89569"/>
212 </dia:attribute>
213 <dia:attribute name="obj_bb">
214 <dia:rectangle val="0.426918,7.30069;3.90942,8.84819"/>
215 </dia:attribute>
216 <dia:attribute name="text">
217 <dia:composite type="text">
218 <dia:attribute name="string">
219 <dia:string>#sink media
220bus format#</dia:string>
221 </dia:attribute>
222 <dia:attribute name="font">
223 <dia:font family="sans" style="0" name="Helvetica"/>
224 </dia:attribute>
225 <dia:attribute name="height">
226 <dia:real val="0.80000000000000004"/>
227 </dia:attribute>
228 <dia:attribute name="pos">
229 <dia:point val="0.426918,7.89569"/>
230 </dia:attribute>
231 <dia:attribute name="color">
232 <dia:color val="#a52a2a"/>
233 </dia:attribute>
234 <dia:attribute name="alignment">
235 <dia:enum val="0"/>
236 </dia:attribute>
237 </dia:composite>
238 </dia:attribute>
239 <dia:attribute name="valign">
240 <dia:enum val="3"/>
241 </dia:attribute>
242 </dia:object>
243 <dia:object type="Standard - Box" version="0" id="O6">
244 <dia:attribute name="obj_pos">
245 <dia:point val="16.6822,9.28251"/>
246 </dia:attribute>
247 <dia:attribute name="obj_bb">
248 <dia:rectangle val="16.6322,9.23251;24.9922,17.9564"/>
249 </dia:attribute>
250 <dia:attribute name="elem_corner">
251 <dia:point val="16.6822,9.28251"/>
252 </dia:attribute>
253 <dia:attribute name="elem_width">
254 <dia:real val="8.2600228398861297"/>
255 </dia:attribute>
256 <dia:attribute name="elem_height">
257 <dia:real val="8.6238900617957164"/>
258 </dia:attribute>
259 <dia:attribute name="border_width">
260 <dia:real val="0.10000000149011612"/>
261 </dia:attribute>
262 <dia:attribute name="border_color">
263 <dia:color val="#00ff00"/>
264 </dia:attribute>
265 <dia:attribute name="show_background">
266 <dia:boolean val="true"/>
267 </dia:attribute>
268 </dia:object>
269 <dia:object type="Standard - Line" version="0" id="O7">
270 <dia:attribute name="obj_pos">
271 <dia:point val="16.6822,17.9064"/>
272 </dia:attribute>
273 <dia:attribute name="obj_bb">
274 <dia:rectangle val="2.41365,13.9886;16.7436,17.9678"/>
275 </dia:attribute>
276 <dia:attribute name="conn_endpoints">
277 <dia:point val="16.6822,17.9064"/>
278 <dia:point val="2.475,14.05"/>
279 </dia:attribute>
280 <dia:attribute name="numcp">
281 <dia:int val="1"/>
282 </dia:attribute>
283 <dia:attribute name="line_color">
284 <dia:color val="#e60505"/>
285 </dia:attribute>
286 <dia:attribute name="line_style">
287 <dia:enum val="4"/>
288 </dia:attribute>
289 <dia:connections>
290 <dia:connection handle="0" to="O6" connection="5"/>
291 <dia:connection handle="1" to="O2" connection="5"/>
292 </dia:connections>
293 </dia:object>
294 <dia:object type="Standard - Line" version="0" id="O8">
295 <dia:attribute name="obj_pos">
296 <dia:point val="16.6822,9.28251"/>
297 </dia:attribute>
298 <dia:attribute name="obj_bb">
299 <dia:rectangle val="2.42188,9.22939;16.7353,10.2531"/>
300 </dia:attribute>
301 <dia:attribute name="conn_endpoints">
302 <dia:point val="16.6822,9.28251"/>
303 <dia:point val="2.475,10.2"/>
304 </dia:attribute>
305 <dia:attribute name="numcp">
306 <dia:int val="1"/>
307 </dia:attribute>
308 <dia:attribute name="line_color">
309 <dia:color val="#e60505"/>
310 </dia:attribute>
311 <dia:attribute name="line_style">
312 <dia:enum val="4"/>
313 </dia:attribute>
314 <dia:connections>
315 <dia:connection handle="0" to="O6" connection="0"/>
316 <dia:connection handle="1" to="O2" connection="0"/>
317 </dia:connections>
318 </dia:object>
319 <dia:object type="Standard - Line" version="0" id="O9">
320 <dia:attribute name="obj_pos">
321 <dia:point val="24.9422,17.9064"/>
322 </dia:attribute>
323 <dia:attribute name="obj_bb">
324 <dia:rectangle val="7.11553,13.9905;25.0017,17.9659"/>
325 </dia:attribute>
326 <dia:attribute name="conn_endpoints">
327 <dia:point val="24.9422,17.9064"/>
328 <dia:point val="7.175,14.05"/>
329 </dia:attribute>
330 <dia:attribute name="numcp">
331 <dia:int val="1"/>
332 </dia:attribute>
333 <dia:attribute name="line_color">
334 <dia:color val="#e60505"/>
335 </dia:attribute>
336 <dia:attribute name="line_style">
337 <dia:enum val="4"/>
338 </dia:attribute>
339 <dia:connections>
340 <dia:connection handle="0" to="O6" connection="7"/>
341 <dia:connection handle="1" to="O2" connection="7"/>
342 </dia:connections>
343 </dia:object>
344 <dia:object type="Standard - Line" version="0" id="O10">
345 <dia:attribute name="obj_pos">
346 <dia:point val="24.9422,9.28251"/>
347 </dia:attribute>
348 <dia:attribute name="obj_bb">
349 <dia:rectangle val="7.12249,9.23;24.9947,10.2525"/>
350 </dia:attribute>
351 <dia:attribute name="conn_endpoints">
352 <dia:point val="24.9422,9.28251"/>
353 <dia:point val="7.175,10.2"/>
354 </dia:attribute>
355 <dia:attribute name="numcp">
356 <dia:int val="1"/>
357 </dia:attribute>
358 <dia:attribute name="line_color">
359 <dia:color val="#e60505"/>
360 </dia:attribute>
361 <dia:attribute name="line_style">
362 <dia:enum val="4"/>
363 </dia:attribute>
364 <dia:connections>
365 <dia:connection handle="0" to="O6" connection="2"/>
366 <dia:connection handle="1" to="O2" connection="2"/>
367 </dia:connections>
368 </dia:object>
369 <dia:object type="Standard - Text" version="1" id="O11">
370 <dia:attribute name="obj_pos">
371 <dia:point val="16.7352,7.47209"/>
372 </dia:attribute>
373 <dia:attribute name="obj_bb">
374 <dia:rectangle val="16.7352,6.87709;22.5602,8.42459"/>
375 </dia:attribute>
376 <dia:attribute name="text">
377 <dia:composite type="text">
378 <dia:attribute name="string">
379 <dia:string>#sink compose
380selection (scaling)#</dia:string>
381 </dia:attribute>
382 <dia:attribute name="font">
383 <dia:font family="sans" style="0" name="Helvetica"/>
384 </dia:attribute>
385 <dia:attribute name="height">
386 <dia:real val="0.80000000000000004"/>
387 </dia:attribute>
388 <dia:attribute name="pos">
389 <dia:point val="16.7352,7.47209"/>
390 </dia:attribute>
391 <dia:attribute name="color">
392 <dia:color val="#00ff00"/>
393 </dia:attribute>
394 <dia:attribute name="alignment">
395 <dia:enum val="0"/>
396 </dia:attribute>
397 </dia:composite>
398 </dia:attribute>
399 <dia:attribute name="valign">
400 <dia:enum val="3"/>
401 </dia:attribute>
402 </dia:object>
403 <dia:object type="Standard - Box" version="0" id="O12">
404 <dia:attribute name="obj_pos">
405 <dia:point val="19.1161,9.97825"/>
406 </dia:attribute>
407 <dia:attribute name="obj_bb">
408 <dia:rectangle val="19.0661,9.92825;24.1754,13.6009"/>
409 </dia:attribute>
410 <dia:attribute name="elem_corner">
411 <dia:point val="19.1161,9.97825"/>
412 </dia:attribute>
413 <dia:attribute name="elem_width">
414 <dia:real val="5.009308462554376"/>
415 </dia:attribute>
416 <dia:attribute name="elem_height">
417 <dia:real val="3.5726155970598077"/>
418 </dia:attribute>
419 <dia:attribute name="border_width">
420 <dia:real val="0.10000000149011612"/>
421 </dia:attribute>
422 <dia:attribute name="border_color">
423 <dia:color val="#a020f0"/>
424 </dia:attribute>
425 <dia:attribute name="show_background">
426 <dia:boolean val="true"/>
427 </dia:attribute>
428 </dia:object>
429 <dia:object type="Standard - Text" version="1" id="O13">
430 <dia:attribute name="obj_pos">
431 <dia:point val="27.1661,7.47209"/>
432 </dia:attribute>
433 <dia:attribute name="obj_bb">
434 <dia:rectangle val="27.1661,6.87709;30.0436,9.22459"/>
435 </dia:attribute>
436 <dia:attribute name="text">
437 <dia:composite type="text">
438 <dia:attribute name="string">
439 <dia:string>#source
440crop
441selection#</dia:string>
442 </dia:attribute>
443 <dia:attribute name="font">
444 <dia:font family="sans" style="0" name="Helvetica"/>
445 </dia:attribute>
446 <dia:attribute name="height">
447 <dia:real val="0.80000000000000004"/>
448 </dia:attribute>
449 <dia:attribute name="pos">
450 <dia:point val="27.1661,7.47209"/>
451 </dia:attribute>
452 <dia:attribute name="color">
453 <dia:color val="#a020f0"/>
454 </dia:attribute>
455 <dia:attribute name="alignment">
456 <dia:enum val="0"/>
457 </dia:attribute>
458 </dia:composite>
459 </dia:attribute>
460 <dia:attribute name="valign">
461 <dia:enum val="3"/>
462 </dia:attribute>
463 </dia:object>
464 <dia:object type="Standard - Text" version="1" id="O14">
465 <dia:attribute name="obj_pos">
466 <dia:point val="34.575,7.8564"/>
467 </dia:attribute>
468 <dia:attribute name="obj_bb">
469 <dia:rectangle val="34.575,7.2614;38.8975,8.8089"/>
470 </dia:attribute>
471 <dia:attribute name="text">
472 <dia:composite type="text">
473 <dia:attribute name="string">
474 <dia:string>#source media
475bus format#</dia:string>
476 </dia:attribute>
477 <dia:attribute name="font">
478 <dia:font family="sans" style="0" name="Helvetica"/>
479 </dia:attribute>
480 <dia:attribute name="height">
481 <dia:real val="0.80000000000000004"/>
482 </dia:attribute>
483 <dia:attribute name="pos">
484 <dia:point val="34.575,7.8564"/>
485 </dia:attribute>
486 <dia:attribute name="color">
487 <dia:color val="#8b6914"/>
488 </dia:attribute>
489 <dia:attribute name="alignment">
490 <dia:enum val="0"/>
491 </dia:attribute>
492 </dia:composite>
493 </dia:attribute>
494 <dia:attribute name="valign">
495 <dia:enum val="3"/>
496 </dia:attribute>
497 </dia:object>
498 <dia:object type="Standard - Box" version="0" id="O15">
499 <dia:attribute name="obj_pos">
500 <dia:point val="34.5244,11.2917"/>
501 </dia:attribute>
502 <dia:attribute name="obj_bb">
503 <dia:rectangle val="34.4744,11.2417;39.5837,14.9143"/>
504 </dia:attribute>
505 <dia:attribute name="elem_corner">
506 <dia:point val="34.5244,11.2917"/>
507 </dia:attribute>
508 <dia:attribute name="elem_width">
509 <dia:real val="5.009308462554376"/>
510 </dia:attribute>
511 <dia:attribute name="elem_height">
512 <dia:real val="3.5726155970598077"/>
513 </dia:attribute>
514 <dia:attribute name="border_width">
515 <dia:real val="0.10000000149011612"/>
516 </dia:attribute>
517 <dia:attribute name="border_color">
518 <dia:color val="#8b6914"/>
519 </dia:attribute>
520 <dia:attribute name="show_background">
521 <dia:boolean val="true"/>
522 </dia:attribute>
523 </dia:object>
524 <dia:object type="Standard - Line" version="0" id="O16">
525 <dia:attribute name="obj_pos">
526 <dia:point val="34.5244,14.8643"/>
527 </dia:attribute>
528 <dia:attribute name="obj_bb">
529 <dia:rectangle val="19.062,13.4968;34.5785,14.9184"/>
530 </dia:attribute>
531 <dia:attribute name="conn_endpoints">
532 <dia:point val="34.5244,14.8643"/>
533 <dia:point val="19.1161,13.5509"/>
534 </dia:attribute>
535 <dia:attribute name="numcp">
536 <dia:int val="1"/>
537 </dia:attribute>
538 <dia:attribute name="line_color">
539 <dia:color val="#e60505"/>
540 </dia:attribute>
541 <dia:attribute name="line_style">
542 <dia:enum val="4"/>
543 </dia:attribute>
544 <dia:connections>
545 <dia:connection handle="0" to="O15" connection="5"/>
546 <dia:connection handle="1" to="O12" connection="5"/>
547 </dia:connections>
548 </dia:object>
549 <dia:object type="Standard - Line" version="0" id="O17">
550 <dia:attribute name="obj_pos">
551 <dia:point val="34.5244,11.2917"/>
552 </dia:attribute>
553 <dia:attribute name="obj_bb">
554 <dia:rectangle val="19.062,9.92418;34.5785,11.3458"/>
555 </dia:attribute>
556 <dia:attribute name="conn_endpoints">
557 <dia:point val="34.5244,11.2917"/>
558 <dia:point val="19.1161,9.97825"/>
559 </dia:attribute>
560 <dia:attribute name="numcp">
561 <dia:int val="1"/>
562 </dia:attribute>
563 <dia:attribute name="line_color">
564 <dia:color val="#e60505"/>
565 </dia:attribute>
566 <dia:attribute name="line_style">
567 <dia:enum val="4"/>
568 </dia:attribute>
569 <dia:connections>
570 <dia:connection handle="0" to="O15" connection="0"/>
571 <dia:connection handle="1" to="O12" connection="0"/>
572 </dia:connections>
573 </dia:object>
574 <dia:object type="Standard - Line" version="0" id="O18">
575 <dia:attribute name="obj_pos">
576 <dia:point val="39.5337,14.8643"/>
577 </dia:attribute>
578 <dia:attribute name="obj_bb">
579 <dia:rectangle val="24.0713,13.4968;39.5878,14.9184"/>
580 </dia:attribute>
581 <dia:attribute name="conn_endpoints">
582 <dia:point val="39.5337,14.8643"/>
583 <dia:point val="24.1254,13.5509"/>
584 </dia:attribute>
585 <dia:attribute name="numcp">
586 <dia:int val="1"/>
587 </dia:attribute>
588 <dia:attribute name="line_color">
589 <dia:color val="#e60505"/>
590 </dia:attribute>
591 <dia:attribute name="line_style">
592 <dia:enum val="4"/>
593 </dia:attribute>
594 <dia:connections>
595 <dia:connection handle="0" to="O15" connection="7"/>
596 <dia:connection handle="1" to="O12" connection="7"/>
597 </dia:connections>
598 </dia:object>
599 <dia:object type="Standard - Line" version="0" id="O19">
600 <dia:attribute name="obj_pos">
601 <dia:point val="39.5337,11.2917"/>
602 </dia:attribute>
603 <dia:attribute name="obj_bb">
604 <dia:rectangle val="24.0713,9.92418;39.5878,11.3458"/>
605 </dia:attribute>
606 <dia:attribute name="conn_endpoints">
607 <dia:point val="39.5337,11.2917"/>
608 <dia:point val="24.1254,9.97825"/>
609 </dia:attribute>
610 <dia:attribute name="numcp">
611 <dia:int val="1"/>
612 </dia:attribute>
613 <dia:attribute name="line_color">
614 <dia:color val="#e60505"/>
615 </dia:attribute>
616 <dia:attribute name="line_style">
617 <dia:enum val="4"/>
618 </dia:attribute>
619 <dia:connections>
620 <dia:connection handle="0" to="O15" connection="2"/>
621 <dia:connection handle="1" to="O12" connection="2"/>
622 </dia:connections>
623 </dia:object>
624 <dia:object type="Geometric - Perfect Circle" version="1" id="O20">
625 <dia:attribute name="obj_pos">
626 <dia:point val="39.98,12.0742"/>
627 </dia:attribute>
628 <dia:attribute name="obj_bb">
629 <dia:rectangle val="39.93,12.0242;40.88,12.9742"/>
630 </dia:attribute>
631 <dia:attribute name="meta">
632 <dia:composite type="dict"/>
633 </dia:attribute>
634 <dia:attribute name="elem_corner">
635 <dia:point val="39.98,12.0742"/>
636 </dia:attribute>
637 <dia:attribute name="elem_width">
638 <dia:real val="0.84999999999999787"/>
639 </dia:attribute>
640 <dia:attribute name="elem_height">
641 <dia:real val="0.84999999999999787"/>
642 </dia:attribute>
643 <dia:attribute name="line_width">
644 <dia:real val="0.10000000000000001"/>
645 </dia:attribute>
646 <dia:attribute name="line_colour">
647 <dia:color val="#000000"/>
648 </dia:attribute>
649 <dia:attribute name="fill_colour">
650 <dia:color val="#ffffff"/>
651 </dia:attribute>
652 <dia:attribute name="show_background">
653 <dia:boolean val="true"/>
654 </dia:attribute>
655 <dia:attribute name="line_style">
656 <dia:enum val="0"/>
657 <dia:real val="1"/>
658 </dia:attribute>
659 <dia:attribute name="flip_horizontal">
660 <dia:boolean val="false"/>
661 </dia:attribute>
662 <dia:attribute name="flip_vertical">
663 <dia:boolean val="false"/>
664 </dia:attribute>
665 <dia:attribute name="subscale">
666 <dia:real val="1"/>
667 </dia:attribute>
668 </dia:object>
669 <dia:object type="Standard - Line" version="0" id="O21">
670 <dia:attribute name="obj_pos">
671 <dia:point val="40.83,12.4992"/>
672 </dia:attribute>
673 <dia:attribute name="obj_bb">
674 <dia:rectangle val="40.78,12.1388;49.2453,12.8624"/>
675 </dia:attribute>
676 <dia:attribute name="conn_endpoints">
677 <dia:point val="40.83,12.4992"/>
678 <dia:point val="49.1335,12.5007"/>
679 </dia:attribute>
680 <dia:attribute name="numcp">
681 <dia:int val="1"/>
682 </dia:attribute>
683 <dia:attribute name="end_arrow">
684 <dia:enum val="22"/>
685 </dia:attribute>
686 <dia:attribute name="end_arrow_length">
687 <dia:real val="0.5"/>
688 </dia:attribute>
689 <dia:attribute name="end_arrow_width">
690 <dia:real val="0.5"/>
691 </dia:attribute>
692 <dia:connections>
693 <dia:connection handle="0" to="O20" connection="3"/>
694 </dia:connections>
695 </dia:object>
696 <dia:object type="Standard - Text" version="1" id="O22">
697 <dia:attribute name="obj_pos">
698 <dia:point val="42.0954,11.99"/>
699 </dia:attribute>
700 <dia:attribute name="obj_bb">
701 <dia:rectangle val="42.0954,11.395;46.7404,12.1425"/>
702 </dia:attribute>
703 <dia:attribute name="text">
704 <dia:composite type="text">
705 <dia:attribute name="string">
706 <dia:string>#pad 1 (source)#</dia:string>
707 </dia:attribute>
708 <dia:attribute name="font">
709 <dia:font family="sans" style="0" name="Helvetica"/>
710 </dia:attribute>
711 <dia:attribute name="height">
712 <dia:real val="0.80000000000000004"/>
713 </dia:attribute>
714 <dia:attribute name="pos">
715 <dia:point val="42.0954,11.99"/>
716 </dia:attribute>
717 <dia:attribute name="color">
718 <dia:color val="#000000"/>
719 </dia:attribute>
720 <dia:attribute name="alignment">
721 <dia:enum val="0"/>
722 </dia:attribute>
723 </dia:composite>
724 </dia:attribute>
725 <dia:attribute name="valign">
726 <dia:enum val="3"/>
727 </dia:attribute>
728 </dia:object>
729 <dia:object type="Geometric - Perfect Circle" version="1" id="O23">
730 <dia:attribute name="obj_pos">
731 <dia:point val="-1.44491,11.6506"/>
732 </dia:attribute>
733 <dia:attribute name="obj_bb">
734 <dia:rectangle val="-1.49491,11.6006;-0.54491,12.5506"/>
735 </dia:attribute>
736 <dia:attribute name="meta">
737 <dia:composite type="dict"/>
738 </dia:attribute>
739 <dia:attribute name="elem_corner">
740 <dia:point val="-1.44491,11.6506"/>
741 </dia:attribute>
742 <dia:attribute name="elem_width">
743 <dia:real val="0.84999999999999787"/>
744 </dia:attribute>
745 <dia:attribute name="elem_height">
746 <dia:real val="0.84999999999999787"/>
747 </dia:attribute>
748 <dia:attribute name="line_width">
749 <dia:real val="0.10000000000000001"/>
750 </dia:attribute>
751 <dia:attribute name="line_colour">
752 <dia:color val="#000000"/>
753 </dia:attribute>
754 <dia:attribute name="fill_colour">
755 <dia:color val="#ffffff"/>
756 </dia:attribute>
757 <dia:attribute name="show_background">
758 <dia:boolean val="true"/>
759 </dia:attribute>
760 <dia:attribute name="line_style">
761 <dia:enum val="0"/>
762 <dia:real val="1"/>
763 </dia:attribute>
764 <dia:attribute name="flip_horizontal">
765 <dia:boolean val="false"/>
766 </dia:attribute>
767 <dia:attribute name="flip_vertical">
768 <dia:boolean val="false"/>
769 </dia:attribute>
770 <dia:attribute name="subscale">
771 <dia:real val="1"/>
772 </dia:attribute>
773 </dia:object>
774 <dia:object type="Standard - Line" version="0" id="O24">
775 <dia:attribute name="obj_pos">
776 <dia:point val="-9.61991,12.09"/>
777 </dia:attribute>
778 <dia:attribute name="obj_bb">
779 <dia:rectangle val="-9.67,11.7149;-1.33311,12.4385"/>
780 </dia:attribute>
781 <dia:attribute name="conn_endpoints">
782 <dia:point val="-9.61991,12.09"/>
783 <dia:point val="-1.44491,12.0756"/>
784 </dia:attribute>
785 <dia:attribute name="numcp">
786 <dia:int val="1"/>
787 </dia:attribute>
788 <dia:attribute name="end_arrow">
789 <dia:enum val="22"/>
790 </dia:attribute>
791 <dia:attribute name="end_arrow_length">
792 <dia:real val="0.5"/>
793 </dia:attribute>
794 <dia:attribute name="end_arrow_width">
795 <dia:real val="0.5"/>
796 </dia:attribute>
797 <dia:connections>
798 <dia:connection handle="1" to="O23" connection="2"/>
799 </dia:connections>
800 </dia:object>
801 <dia:object type="Standard - Text" version="1" id="O25">
802 <dia:attribute name="obj_pos">
803 <dia:point val="-7.39291,11.49"/>
804 </dia:attribute>
805 <dia:attribute name="obj_bb">
806 <dia:rectangle val="-7.39291,10.895;-3.58791,11.6425"/>
807 </dia:attribute>
808 <dia:attribute name="text">
809 <dia:composite type="text">
810 <dia:attribute name="string">
811 <dia:string>#pad 0 (sink)#</dia:string>
812 </dia:attribute>
813 <dia:attribute name="font">
814 <dia:font family="sans" style="0" name="Helvetica"/>
815 </dia:attribute>
816 <dia:attribute name="height">
817 <dia:real val="0.80000000000000004"/>
818 </dia:attribute>
819 <dia:attribute name="pos">
820 <dia:point val="-7.39291,11.49"/>
821 </dia:attribute>
822 <dia:attribute name="color">
823 <dia:color val="#000000"/>
824 </dia:attribute>
825 <dia:attribute name="alignment">
826 <dia:enum val="0"/>
827 </dia:attribute>
828 </dia:composite>
829 </dia:attribute>
830 <dia:attribute name="valign">
831 <dia:enum val="3"/>
832 </dia:attribute>
833 </dia:object>
834 <dia:object type="Standard - Box" version="0" id="O26">
835 <dia:attribute name="obj_pos">
836 <dia:point val="19.4911,13.8333"/>
837 </dia:attribute>
838 <dia:attribute name="obj_bb">
839 <dia:rectangle val="19.4411,13.7833;24.5504,17.4559"/>
840 </dia:attribute>
841 <dia:attribute name="elem_corner">
842 <dia:point val="19.4911,13.8333"/>
843 </dia:attribute>
844 <dia:attribute name="elem_width">
845 <dia:real val="5.009308462554376"/>
846 </dia:attribute>
847 <dia:attribute name="elem_height">
848 <dia:real val="3.5726155970598077"/>
849 </dia:attribute>
850 <dia:attribute name="border_width">
851 <dia:real val="0.10000000149011612"/>
852 </dia:attribute>
853 <dia:attribute name="border_color">
854 <dia:color val="#a020f0"/>
855 </dia:attribute>
856 <dia:attribute name="show_background">
857 <dia:boolean val="false"/>
858 </dia:attribute>
859 </dia:object>
860 <dia:object type="Standard - Box" version="0" id="O27">
861 <dia:attribute name="obj_pos">
862 <dia:point val="34.4994,17.2967"/>
863 </dia:attribute>
864 <dia:attribute name="obj_bb">
865 <dia:rectangle val="34.4494,17.2467;39.5587,20.9193"/>
866 </dia:attribute>
867 <dia:attribute name="elem_corner">
868 <dia:point val="34.4994,17.2967"/>
869 </dia:attribute>
870 <dia:attribute name="elem_width">
871 <dia:real val="5.009308462554376"/>
872 </dia:attribute>
873 <dia:attribute name="elem_height">
874 <dia:real val="3.5726155970598077"/>
875 </dia:attribute>
876 <dia:attribute name="border_width">
877 <dia:real val="0.10000000149011612"/>
878 </dia:attribute>
879 <dia:attribute name="border_color">
880 <dia:color val="#8b6914"/>
881 </dia:attribute>
882 <dia:attribute name="show_background">
883 <dia:boolean val="true"/>
884 </dia:attribute>
885 </dia:object>
886 <dia:object type="Standard - Line" version="0" id="O28">
887 <dia:attribute name="obj_pos">
888 <dia:point val="34.4994,20.8693"/>
889 </dia:attribute>
890 <dia:attribute name="obj_bb">
891 <dia:rectangle val="19.4311,17.3459;34.5594,20.9293"/>
892 </dia:attribute>
893 <dia:attribute name="conn_endpoints">
894 <dia:point val="34.4994,20.8693"/>
895 <dia:point val="19.4911,17.4059"/>
896 </dia:attribute>
897 <dia:attribute name="numcp">
898 <dia:int val="1"/>
899 </dia:attribute>
900 <dia:attribute name="line_color">
901 <dia:color val="#e60505"/>
902 </dia:attribute>
903 <dia:attribute name="line_style">
904 <dia:enum val="4"/>
905 </dia:attribute>
906 <dia:connections>
907 <dia:connection handle="0" to="O27" connection="5"/>
908 <dia:connection handle="1" to="O26" connection="5"/>
909 </dia:connections>
910 </dia:object>
911 <dia:object type="Standard - Line" version="0" id="O29">
912 <dia:attribute name="obj_pos">
913 <dia:point val="34.4994,17.2967"/>
914 </dia:attribute>
915 <dia:attribute name="obj_bb">
916 <dia:rectangle val="19.4311,13.7733;34.5594,17.3567"/>
917 </dia:attribute>
918 <dia:attribute name="conn_endpoints">
919 <dia:point val="34.4994,17.2967"/>
920 <dia:point val="19.4911,13.8333"/>
921 </dia:attribute>
922 <dia:attribute name="numcp">
923 <dia:int val="1"/>
924 </dia:attribute>
925 <dia:attribute name="line_color">
926 <dia:color val="#e60505"/>
927 </dia:attribute>
928 <dia:attribute name="line_style">
929 <dia:enum val="4"/>
930 </dia:attribute>
931 <dia:connections>
932 <dia:connection handle="0" to="O27" connection="0"/>
933 <dia:connection handle="1" to="O26" connection="0"/>
934 </dia:connections>
935 </dia:object>
936 <dia:object type="Standard - Line" version="0" id="O30">
937 <dia:attribute name="obj_pos">
938 <dia:point val="39.5087,20.8693"/>
939 </dia:attribute>
940 <dia:attribute name="obj_bb">
941 <dia:rectangle val="24.4404,17.3459;39.5687,20.9293"/>
942 </dia:attribute>
943 <dia:attribute name="conn_endpoints">
944 <dia:point val="39.5087,20.8693"/>
945 <dia:point val="24.5004,17.4059"/>
946 </dia:attribute>
947 <dia:attribute name="numcp">
948 <dia:int val="1"/>
949 </dia:attribute>
950 <dia:attribute name="line_color">
951 <dia:color val="#e60505"/>
952 </dia:attribute>
953 <dia:attribute name="line_style">
954 <dia:enum val="4"/>
955 </dia:attribute>
956 <dia:connections>
957 <dia:connection handle="0" to="O27" connection="7"/>
958 <dia:connection handle="1" to="O26" connection="7"/>
959 </dia:connections>
960 </dia:object>
961 <dia:object type="Standard - Line" version="0" id="O31">
962 <dia:attribute name="obj_pos">
963 <dia:point val="39.5087,17.2967"/>
964 </dia:attribute>
965 <dia:attribute name="obj_bb">
966 <dia:rectangle val="24.4404,13.7733;39.5687,17.3567"/>
967 </dia:attribute>
968 <dia:attribute name="conn_endpoints">
969 <dia:point val="39.5087,17.2967"/>
970 <dia:point val="24.5004,13.8333"/>
971 </dia:attribute>
972 <dia:attribute name="numcp">
973 <dia:int val="1"/>
974 </dia:attribute>
975 <dia:attribute name="line_color">
976 <dia:color val="#e60505"/>
977 </dia:attribute>
978 <dia:attribute name="line_style">
979 <dia:enum val="4"/>
980 </dia:attribute>
981 <dia:connections>
982 <dia:connection handle="0" to="O27" connection="2"/>
983 <dia:connection handle="1" to="O26" connection="2"/>
984 </dia:connections>
985 </dia:object>
986 <dia:object type="Geometric - Perfect Circle" version="1" id="O32">
987 <dia:attribute name="obj_pos">
988 <dia:point val="39.855,18.7792"/>
989 </dia:attribute>
990 <dia:attribute name="obj_bb">
991 <dia:rectangle val="39.805,18.7292;40.755,19.6792"/>
992 </dia:attribute>
993 <dia:attribute name="meta">
994 <dia:composite type="dict"/>
995 </dia:attribute>
996 <dia:attribute name="elem_corner">
997 <dia:point val="39.855,18.7792"/>
998 </dia:attribute>
999 <dia:attribute name="elem_width">
1000 <dia:real val="0.84999999999999787"/>
1001 </dia:attribute>
1002 <dia:attribute name="elem_height">
1003 <dia:real val="0.84999999999999787"/>
1004 </dia:attribute>
1005 <dia:attribute name="line_width">
1006 <dia:real val="0.10000000000000001"/>
1007 </dia:attribute>
1008 <dia:attribute name="line_colour">
1009 <dia:color val="#000000"/>
1010 </dia:attribute>
1011 <dia:attribute name="fill_colour">
1012 <dia:color val="#ffffff"/>
1013 </dia:attribute>
1014 <dia:attribute name="show_background">
1015 <dia:boolean val="true"/>
1016 </dia:attribute>
1017 <dia:attribute name="line_style">
1018 <dia:enum val="0"/>
1019 <dia:real val="1"/>
1020 </dia:attribute>
1021 <dia:attribute name="flip_horizontal">
1022 <dia:boolean val="false"/>
1023 </dia:attribute>
1024 <dia:attribute name="flip_vertical">
1025 <dia:boolean val="false"/>
1026 </dia:attribute>
1027 <dia:attribute name="subscale">
1028 <dia:real val="1"/>
1029 </dia:attribute>
1030 </dia:object>
1031 <dia:object type="Standard - Line" version="0" id="O33">
1032 <dia:attribute name="obj_pos">
1033 <dia:point val="40.705,19.2042"/>
1034 </dia:attribute>
1035 <dia:attribute name="obj_bb">
1036 <dia:rectangle val="40.655,18.8438;49.1203,19.5674"/>
1037 </dia:attribute>
1038 <dia:attribute name="conn_endpoints">
1039 <dia:point val="40.705,19.2042"/>
1040 <dia:point val="49.0085,19.2057"/>
1041 </dia:attribute>
1042 <dia:attribute name="numcp">
1043 <dia:int val="1"/>
1044 </dia:attribute>
1045 <dia:attribute name="end_arrow">
1046 <dia:enum val="22"/>
1047 </dia:attribute>
1048 <dia:attribute name="end_arrow_length">
1049 <dia:real val="0.5"/>
1050 </dia:attribute>
1051 <dia:attribute name="end_arrow_width">
1052 <dia:real val="0.5"/>
1053 </dia:attribute>
1054 <dia:connections>
1055 <dia:connection handle="0" to="O32" connection="3"/>
1056 </dia:connections>
1057 </dia:object>
1058 <dia:object type="Standard - Text" version="1" id="O34">
1059 <dia:attribute name="obj_pos">
1060 <dia:point val="41.9704,18.695"/>
1061 </dia:attribute>
1062 <dia:attribute name="obj_bb">
1063 <dia:rectangle val="41.9704,18.1;46.6154,18.8475"/>
1064 </dia:attribute>
1065 <dia:attribute name="text">
1066 <dia:composite type="text">
1067 <dia:attribute name="string">
1068 <dia:string>#pad 2 (source)#</dia:string>
1069 </dia:attribute>
1070 <dia:attribute name="font">
1071 <dia:font family="sans" style="0" name="Helvetica"/>
1072 </dia:attribute>
1073 <dia:attribute name="height">
1074 <dia:real val="0.80000000000000004"/>
1075 </dia:attribute>
1076 <dia:attribute name="pos">
1077 <dia:point val="41.9704,18.695"/>
1078 </dia:attribute>
1079 <dia:attribute name="color">
1080 <dia:color val="#000000"/>
1081 </dia:attribute>
1082 <dia:attribute name="alignment">
1083 <dia:enum val="0"/>
1084 </dia:attribute>
1085 </dia:composite>
1086 </dia:attribute>
1087 <dia:attribute name="valign">
1088 <dia:enum val="3"/>
1089 </dia:attribute>
1090 </dia:object>
1091 <dia:object type="Standard - Line" version="0" id="O35">
1092 <dia:attribute name="obj_pos">
1093 <dia:point val="27.3,9.55"/>
1094 </dia:attribute>
1095 <dia:attribute name="obj_bb">
1096 <dia:rectangle val="24.0146,9.49376;27.3562,10.255"/>
1097 </dia:attribute>
1098 <dia:attribute name="conn_endpoints">
1099 <dia:point val="27.3,9.55"/>
1100 <dia:point val="24.1254,9.97825"/>
1101 </dia:attribute>
1102 <dia:attribute name="numcp">
1103 <dia:int val="1"/>
1104 </dia:attribute>
1105 <dia:attribute name="line_color">
1106 <dia:color val="#a020f0"/>
1107 </dia:attribute>
1108 <dia:attribute name="end_arrow">
1109 <dia:enum val="22"/>
1110 </dia:attribute>
1111 <dia:attribute name="end_arrow_length">
1112 <dia:real val="0.5"/>
1113 </dia:attribute>
1114 <dia:attribute name="end_arrow_width">
1115 <dia:real val="0.5"/>
1116 </dia:attribute>
1117 <dia:connections>
1118 <dia:connection handle="1" to="O12" connection="2"/>
1119 </dia:connections>
1120 </dia:object>
1121 <dia:object type="Standard - Line" version="0" id="O36">
1122 <dia:attribute name="obj_pos">
1123 <dia:point val="27.3454,9.53624"/>
1124 </dia:attribute>
1125 <dia:attribute name="obj_bb">
1126 <dia:rectangle val="24.4311,9.46695;27.4147,13.9265"/>
1127 </dia:attribute>
1128 <dia:attribute name="conn_endpoints">
1129 <dia:point val="27.3454,9.53624"/>
1130 <dia:point val="24.5004,13.8333"/>
1131 </dia:attribute>
1132 <dia:attribute name="numcp">
1133 <dia:int val="1"/>
1134 </dia:attribute>
1135 <dia:attribute name="line_color">
1136 <dia:color val="#a020f0"/>
1137 </dia:attribute>
1138 <dia:attribute name="end_arrow">
1139 <dia:enum val="22"/>
1140 </dia:attribute>
1141 <dia:attribute name="end_arrow_length">
1142 <dia:real val="0.5"/>
1143 </dia:attribute>
1144 <dia:attribute name="end_arrow_width">
1145 <dia:real val="0.5"/>
1146 </dia:attribute>
1147 <dia:connections>
1148 <dia:connection handle="1" to="O26" connection="2"/>
1149 </dia:connections>
1150 </dia:object>
1151 </dia:layer>
1152</dia:diagram>
diff --git a/Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.svg b/Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.svg
new file mode 100644
index 000000000000..2340c0f8bc92
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.svg
@@ -0,0 +1,116 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
3<svg width="59cm" height="17cm" viewBox="-194 128 1179 330" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="-8" y="130" width="806" height="327"/>
5 <g>
6 <rect style="fill: #ffffff" x="4.5" y="189" width="159" height="104"/>
7 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="4.5" y="189" width="159" height="104"/>
8 </g>
9 <g>
10 <rect style="fill: #ffffff" x="49.5" y="204" width="94" height="77"/>
11 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="49.5" y="204" width="94" height="77"/>
12 </g>
13 <text style="fill: #0000ff;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="60" y="224">
14 <tspan x="60" y="224">sink</tspan>
15 <tspan x="60" y="240">crop</tspan>
16 <tspan x="60" y="256">selection</tspan>
17 </text>
18 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="29.5" y="158">
19 <tspan x="29.5" y="158"></tspan>
20 </text>
21 <text style="fill: #a52a2a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="8.53836" y="157.914">
22 <tspan x="8.53836" y="157.914">sink media</tspan>
23 <tspan x="8.53836" y="173.914">bus format</tspan>
24 </text>
25 <g>
26 <rect style="fill: #ffffff" x="333.644" y="185.65" width="165.2" height="172.478"/>
27 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" x="333.644" y="185.65" width="165.2" height="172.478"/>
28 </g>
29 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="358.128" x2="49.5" y2="281"/>
30 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="185.65" x2="49.5" y2="204"/>
31 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="358.128" x2="143.5" y2="281"/>
32 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="185.65" x2="143.5" y2="204"/>
33 <text style="fill: #00ff00;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="334.704" y="149.442">
34 <tspan x="334.704" y="149.442">sink compose</tspan>
35 <tspan x="334.704" y="165.442">selection (scaling)</tspan>
36 </text>
37 <g>
38 <rect style="fill: #ffffff" x="382.322" y="199.565" width="100.186" height="71.4523"/>
39 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="382.322" y="199.565" width="100.186" height="71.4523"/>
40 </g>
41 <text style="fill: #a020f0;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="543.322" y="149.442">
42 <tspan x="543.322" y="149.442">source</tspan>
43 <tspan x="543.322" y="165.442">crop</tspan>
44 <tspan x="543.322" y="181.442">selection</tspan>
45 </text>
46 <text style="fill: #8b6914;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="691.5" y="157.128">
47 <tspan x="691.5" y="157.128">source media</tspan>
48 <tspan x="691.5" y="173.128">bus format</tspan>
49 </text>
50 <g>
51 <rect style="fill: #ffffff" x="690.488" y="225.834" width="100.186" height="71.4523"/>
52 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="690.488" y="225.834" width="100.186" height="71.4523"/>
53 </g>
54 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="690.488" y1="297.286" x2="382.322" y2="271.018"/>
55 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="690.488" y1="225.834" x2="382.322" y2="199.565"/>
56 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.674" y1="297.286" x2="482.508" y2="271.018"/>
57 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.674" y1="225.834" x2="482.508" y2="199.565"/>
58 <g>
59 <ellipse style="fill: #ffffff" cx="808.1" cy="249.984" rx="8.5" ry="8.5"/>
60 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="808.1" cy="249.984" rx="8.5" ry="8.5"/>
61 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="808.1" cy="249.984" rx="8.5" ry="8.5"/>
62 </g>
63 <g>
64 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="816.6" y1="249.984" x2="972.934" y2="250.012"/>
65 <polygon style="fill: #000000" points="980.434,250.014 970.433,255.012 972.934,250.012 970.435,245.012 "/>
66 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="980.434,250.014 970.433,255.012 972.934,250.012 970.435,245.012 "/>
67 </g>
68 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="841.908" y="239.8">
69 <tspan x="841.908" y="239.8">pad 1 (source)</tspan>
70 </text>
71 <g>
72 <ellipse style="fill: #ffffff" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
73 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
74 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
75 </g>
76 <g>
77 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-192.398" y1="241.8" x2="-38.6343" y2="241.529"/>
78 <polygon style="fill: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
79 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
80 </g>
81 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-147.858" y="229.8">
82 <tspan x="-147.858" y="229.8">pad 0 (sink)</tspan>
83 </text>
84 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="389.822" y="276.666" width="100.186" height="71.4523"/>
85 <g>
86 <rect style="fill: #ffffff" x="689.988" y="345.934" width="100.186" height="71.4523"/>
87 <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="689.988" y="345.934" width="100.186" height="71.4523"/>
88 </g>
89 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="689.988" y1="417.386" x2="389.822" y2="348.118"/>
90 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="689.988" y1="345.934" x2="389.822" y2="276.666"/>
91 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.174" y1="417.386" x2="490.008" y2="348.118"/>
92 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.174" y1="345.934" x2="490.008" y2="276.666"/>
93 <g>
94 <ellipse style="fill: #ffffff" cx="805.6" cy="384.084" rx="8.5" ry="8.5"/>
95 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="805.6" cy="384.084" rx="8.5" ry="8.5"/>
96 <ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="805.6" cy="384.084" rx="8.5" ry="8.5"/>
97 </g>
98 <g>
99 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="814.1" y1="384.084" x2="970.434" y2="384.112"/>
100 <polygon style="fill: #000000" points="977.934,384.114 967.933,389.112 970.434,384.112 967.935,379.112 "/>
101 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="977.934,384.114 967.933,389.112 970.434,384.112 967.935,379.112 "/>
102 </g>
103 <text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="839.408" y="373.9">
104 <tspan x="839.408" y="373.9">pad 2 (source)</tspan>
105 </text>
106 <g>
107 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="546" y1="191" x2="492.157" y2="198.263"/>
108 <polygon style="fill: #a020f0" points="484.724,199.266 493.966,192.974 492.157,198.263 495.303,202.884 "/>
109 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="484.724,199.266 493.966,192.974 492.157,198.263 495.303,202.884 "/>
110 </g>
111 <g>
112 <line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="546.908" y1="190.725" x2="495.383" y2="268.548"/>
113 <polygon style="fill: #a020f0" points="491.242,274.802 492.594,263.703 495.383,268.548 500.932,269.224 "/>
114 <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="491.242,274.802 492.594,263.703 495.383,268.548 500.932,269.224 "/>
115 </g>
116</svg>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 8ae38876172e..015c561754b7 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -28,8 +28,8 @@ documentation.</contrib>
28 <firstname>Hans</firstname> 28 <firstname>Hans</firstname>
29 <surname>Verkuil</surname> 29 <surname>Verkuil</surname>
30 <contrib>Designed and documented the VIDIOC_LOG_STATUS ioctl, 30 <contrib>Designed and documented the VIDIOC_LOG_STATUS ioctl,
31the extended control ioctls and major parts of the sliced VBI 31the extended control ioctls, major parts of the sliced VBI API, the
32API.</contrib> 32MPEG encoder and decoder APIs and the DV Timings API.</contrib>
33 <affiliation> 33 <affiliation>
34 <address> 34 <address>
35 <email>hverkuil@xs4all.nl</email> 35 <email>hverkuil@xs4all.nl</email>
@@ -96,6 +96,17 @@ Remote Controller chapter.</contrib>
96 </address> 96 </address>
97 </affiliation> 97 </affiliation>
98 </author> 98 </author>
99
100 <author>
101 <firstname>Sakari</firstname>
102 <surname>Ailus</surname>
103 <contrib>Subdev selections API.</contrib>
104 <affiliation>
105 <address>
106 <email>sakari.ailus@iki.fi</email>
107 </address>
108 </affiliation>
109 </author>
99 </authorgroup> 110 </authorgroup>
100 111
101 <copyright> 112 <copyright>
@@ -112,6 +123,7 @@ Remote Controller chapter.</contrib>
112 <year>2009</year> 123 <year>2009</year>
113 <year>2010</year> 124 <year>2010</year>
114 <year>2011</year> 125 <year>2011</year>
126 <year>2012</year>
115 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin 127 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
116Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, 128Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
117 Pawel Osciak</holder> 129 Pawel Osciak</holder>
@@ -128,6 +140,28 @@ structs, ioctls) must be noted in more detail in the history chapter
128applications. --> 140applications. -->
129 141
130 <revision> 142 <revision>
143 <revnumber>3.5</revnumber>
144 <date>2012-05-07</date>
145 <authorinitials>sa, sn</authorinitials>
146 <revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU and V4L2 subdev
147 selections API. Improved the description of V4L2_CID_COLORFX
148 control, added V4L2_CID_COLORFX_CBCR control.
149 Added camera controls V4L2_CID_AUTO_EXPOSURE_BIAS,
150 V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, V4L2_CID_IMAGE_STABILIZATION,
151 V4L2_CID_ISO_SENSITIVITY, V4L2_CID_ISO_SENSITIVITY_AUTO,
152 V4L2_CID_EXPOSURE_METERING, V4L2_CID_SCENE_MODE,
153 V4L2_CID_3A_LOCK, V4L2_CID_AUTO_FOCUS_START,
154 V4L2_CID_AUTO_FOCUS_STOP, V4L2_CID_AUTO_FOCUS_STATUS
155 and V4L2_CID_AUTO_FOCUS_RANGE.
156 </revremark>
157 <date>2012-05-01</date>
158 <authorinitials>hv</authorinitials>
159 <revremark>Added VIDIOC_ENUM_DV_TIMINGS, VIDIOC_QUERY_DV_TIMINGS and
160 VIDIOC_DV_TIMINGS_CAP.
161 </revremark>
162 </revision>
163
164 <revision>
131 <revnumber>3.4</revnumber> 165 <revnumber>3.4</revnumber>
132 <date>2012-01-25</date> 166 <date>2012-01-25</date>
133 <authorinitials>sn</authorinitials> 167 <authorinitials>sn</authorinitials>
@@ -433,7 +467,7 @@ and discussions on the V4L mailing list.</revremark>
433</partinfo> 467</partinfo>
434 468
435<title>Video for Linux Two API Specification</title> 469<title>Video for Linux Two API Specification</title>
436 <subtitle>Revision 3.3</subtitle> 470 <subtitle>Revision 3.5</subtitle>
437 471
438 <chapter id="common"> 472 <chapter id="common">
439 &sub-common; 473 &sub-common;
@@ -491,10 +525,12 @@ and discussions on the V4L mailing list.</revremark>
491 &sub-dbg-g-register; 525 &sub-dbg-g-register;
492 &sub-decoder-cmd; 526 &sub-decoder-cmd;
493 &sub-dqevent; 527 &sub-dqevent;
528 &sub-dv-timings-cap;
494 &sub-encoder-cmd; 529 &sub-encoder-cmd;
495 &sub-enumaudio; 530 &sub-enumaudio;
496 &sub-enumaudioout; 531 &sub-enumaudioout;
497 &sub-enum-dv-presets; 532 &sub-enum-dv-presets;
533 &sub-enum-dv-timings;
498 &sub-enum-fmt; 534 &sub-enum-fmt;
499 &sub-enum-framesizes; 535 &sub-enum-framesizes;
500 &sub-enum-frameintervals; 536 &sub-enum-frameintervals;
@@ -529,6 +565,7 @@ and discussions on the V4L mailing list.</revremark>
529 &sub-querycap; 565 &sub-querycap;
530 &sub-queryctrl; 566 &sub-queryctrl;
531 &sub-query-dv-preset; 567 &sub-query-dv-preset;
568 &sub-query-dv-timings;
532 &sub-querystd; 569 &sub-querystd;
533 &sub-prepare-buf; 570 &sub-prepare-buf;
534 &sub-reqbufs; 571 &sub-reqbufs;
@@ -540,6 +577,7 @@ and discussions on the V4L mailing list.</revremark>
540 &sub-subdev-g-crop; 577 &sub-subdev-g-crop;
541 &sub-subdev-g-fmt; 578 &sub-subdev-g-fmt;
542 &sub-subdev-g-frame-interval; 579 &sub-subdev-g-frame-interval;
580 &sub-subdev-g-selection;
543 &sub-subscribe-event; 581 &sub-subscribe-event;
544 <!-- End of ioctls. --> 582 <!-- End of ioctls. -->
545 &sub-mmap; 583 &sub-mmap;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
index 73ae8a6cd004..765549ff8a71 100644
--- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
@@ -48,6 +48,12 @@
48 <refsect1> 48 <refsect1>
49 <title>Description</title> 49 <title>Description</title>
50 50
51 <note>
52 <title>Experimental</title>
53 <para>This is an <link linkend="experimental"> experimental </link>
54 interface and may change in the future.</para>
55 </note>
56
51 <para>This ioctl is used to create buffers for <link linkend="mmap">memory 57 <para>This ioctl is used to create buffers for <link linkend="mmap">memory
52mapped</link> or <link linkend="userp">user pointer</link> 58mapped</link> or <link linkend="userp">user pointer</link>
53I/O. It can be used as an alternative or in addition to the 59I/O. It can be used as an alternative or in addition to the
@@ -94,16 +100,18 @@ information.</para>
94 <entry>The number of buffers requested or granted.</entry> 100 <entry>The number of buffers requested or granted.</entry>
95 </row> 101 </row>
96 <row> 102 <row>
97 <entry>&v4l2-memory;</entry> 103 <entry>__u32</entry>
98 <entry><structfield>memory</structfield></entry> 104 <entry><structfield>memory</structfield></entry>
99 <entry>Applications set this field to 105 <entry>Applications set this field to
100<constant>V4L2_MEMORY_MMAP</constant> or 106<constant>V4L2_MEMORY_MMAP</constant> or
101<constant>V4L2_MEMORY_USERPTR</constant>.</entry> 107<constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory"
108/></entry>
102 </row> 109 </row>
103 <row> 110 <row>
104 <entry>&v4l2-format;</entry> 111 <entry>__u32</entry>
105 <entry><structfield>format</structfield></entry> 112 <entry><structfield>format</structfield></entry>
106 <entry>Filled in by the application, preserved by the driver.</entry> 113 <entry>Filled in by the application, preserved by the driver.
114 See <xref linkend="v4l2-format" />.</entry>
107 </row> 115 </row>
108 <row> 116 <row>
109 <entry>__u32</entry> 117 <entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-cropcap.xml b/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
index b4f2f255211e..f1bac2c6e978 100644
--- a/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
@@ -65,7 +65,7 @@ output.</para>
65 &cs-str; 65 &cs-str;
66 <tbody valign="top"> 66 <tbody valign="top">
67 <row> 67 <row>
68 <entry>&v4l2-buf-type;</entry> 68 <entry>__u32</entry>
69 <entry><structfield>type</structfield></entry> 69 <entry><structfield>type</structfield></entry>
70 <entry>Type of the data stream, set by the application. 70 <entry>Type of the data stream, set by the application.
71Only these types are valid here: 71Only these types are valid here:
@@ -73,7 +73,7 @@ Only these types are valid here:
73<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>, 73<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
74<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver 74<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
75defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant> 75defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
76and higher.</entry> 76and higher. See <xref linkend="v4l2-buf-type" />.</entry>
77 </row> 77 </row>
78 <row> 78 <row>
79 <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry> 79 <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml b/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml
new file mode 100644
index 000000000000..6673ce582050
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml
@@ -0,0 +1,211 @@
1<refentry id="vidioc-dv-timings-cap">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_DV_TIMINGS_CAP</refname>
9 <refpurpose>The capabilities of the Digital Video receiver/transmitter</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_dv_timings_cap *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_DV_TIMINGS_CAP</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <note>
52 <title>Experimental</title>
53 <para>This is an <link linkend="experimental"> experimental </link>
54 interface and may change in the future.</para>
55 </note>
56
57 <para>To query the available timings, applications initialize the
58<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-timings-cap;
59and call the <constant>VIDIOC_DV_TIMINGS_CAP</constant> ioctl with a pointer to this
60structure. Drivers fill the rest of the structure or return an
61&EINVAL; when the index is out of bounds. To enumerate all supported DV timings,
62applications shall begin at index zero, incrementing by one until the
63driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
64different set of DV timings after switching the video input or
65output.</para>
66
67 <table pgwide="1" frame="none" id="v4l2-bt-timings-cap">
68 <title>struct <structname>v4l2_bt_timings_cap</structname></title>
69 <tgroup cols="3">
70 &cs-str;
71 <tbody valign="top">
72 <row>
73 <entry>__u32</entry>
74 <entry><structfield>min_width</structfield></entry>
75 <entry>Minimum width of the active video in pixels.</entry>
76 </row>
77 <row>
78 <entry>__u32</entry>
79 <entry><structfield>max_width</structfield></entry>
80 <entry>Maximum width of the active video in pixels.</entry>
81 </row>
82 <row>
83 <entry>__u32</entry>
84 <entry><structfield>min_height</structfield></entry>
85 <entry>Minimum height of the active video in lines.</entry>
86 </row>
87 <row>
88 <entry>__u32</entry>
89 <entry><structfield>max_height</structfield></entry>
90 <entry>Maximum height of the active video in lines.</entry>
91 </row>
92 <row>
93 <entry>__u64</entry>
94 <entry><structfield>min_pixelclock</structfield></entry>
95 <entry>Minimum pixelclock frequency in Hz.</entry>
96 </row>
97 <row>
98 <entry>__u64</entry>
99 <entry><structfield>max_pixelclock</structfield></entry>
100 <entry>Maximum pixelclock frequency in Hz.</entry>
101 </row>
102 <row>
103 <entry>__u32</entry>
104 <entry><structfield>standards</structfield></entry>
105 <entry>The video standard(s) supported by the hardware.
106 See <xref linkend="dv-bt-standards"/> for a list of standards.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>capabilities</structfield></entry>
111 <entry>Several flags giving more information about the capabilities.
112 See <xref linkend="dv-bt-cap-capabilities"/> for a description of the flags.
113 </entry>
114 </row>
115 <row>
116 <entry>__u32</entry>
117 <entry><structfield>reserved</structfield>[16]</entry>
118 <entry></entry>
119 </row>
120 </tbody>
121 </tgroup>
122 </table>
123
124 <table pgwide="1" frame="none" id="v4l2-dv-timings-cap">
125 <title>struct <structname>v4l2_dv_timings_cap</structname></title>
126 <tgroup cols="4">
127 &cs-str;
128 <tbody valign="top">
129 <row>
130 <entry>__u32</entry>
131 <entry><structfield>type</structfield></entry>
132 <entry>Type of DV timings as listed in <xref linkend="dv-timing-types"/>.</entry>
133 </row>
134 <row>
135 <entry>__u32</entry>
136 <entry><structfield>reserved</structfield>[3]</entry>
137 <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
138 </row>
139 <row>
140 <entry>union</entry>
141 <entry><structfield></structfield></entry>
142 <entry></entry>
143 </row>
144 <row>
145 <entry></entry>
146 <entry>&v4l2-bt-timings-cap;</entry>
147 <entry><structfield>bt</structfield></entry>
148 <entry>BT.656/1120 timings capabilities of the hardware.</entry>
149 </row>
150 <row>
151 <entry></entry>
152 <entry>__u32</entry>
153 <entry><structfield>raw_data</structfield>[32]</entry>
154 <entry></entry>
155 </row>
156 </tbody>
157 </tgroup>
158 </table>
159
160 <table pgwide="1" frame="none" id="dv-bt-cap-capabilities">
161 <title>DV BT Timing capabilities</title>
162 <tgroup cols="2">
163 &cs-str;
164 <tbody valign="top">
165 <row>
166 <entry>Flag</entry>
167 <entry>Description</entry>
168 </row>
169 <row>
170 <entry></entry>
171 <entry></entry>
172 </row>
173 <row>
174 <entry>V4L2_DV_BT_CAP_INTERLACED</entry>
175 <entry>Interlaced formats are supported.
176 </entry>
177 </row>
178 <row>
179 <entry>V4L2_DV_BT_CAP_PROGRESSIVE</entry>
180 <entry>Progressive formats are supported.
181 </entry>
182 </row>
183 <row>
184 <entry>V4L2_DV_BT_CAP_REDUCED_BLANKING</entry>
185 <entry>CVT/GTF specific: the timings can make use of reduced blanking (CVT)
186or the 'Secondary GTF' curve (GTF).
187 </entry>
188 </row>
189 <row>
190 <entry>V4L2_DV_BT_CAP_CUSTOM</entry>
191 <entry>Can support non-standard timings, i.e. timings not belonging to the
192standards set in the <structfield>standards</structfield> field.
193 </entry>
194 </row>
195 </tbody>
196 </tgroup>
197 </table>
198 </refsect1>
199
200 <refsect1>
201 &return-value;
202 </refsect1>
203</refentry>
204
205<!--
206Local Variables:
207mode: sgml
208sgml-parent-document: "v4l2.sgml"
209indent-tabs-mode: nil
210End:
211-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
index 0be17c232d3a..509f0012d2a6 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
@@ -48,6 +48,10 @@
48 <refsect1> 48 <refsect1>
49 <title>Description</title> 49 <title>Description</title>
50 50
51 <para>This ioctl is <emphasis role="bold">deprecated</emphasis>.
52 New drivers and applications should use &VIDIOC-ENUM-DV-TIMINGS; instead.
53 </para>
54
51 <para>To query the attributes of a DV preset, applications initialize the 55 <para>To query the attributes of a DV preset, applications initialize the
52<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset; 56<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset;
53and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this 57and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml
new file mode 100644
index 000000000000..24c3bf4fd29a
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml
@@ -0,0 +1,119 @@
1<refentry id="vidioc-enum-dv-timings">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUM_DV_TIMINGS</refname>
9 <refpurpose>Enumerate supported Digital Video timings</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_enum_dv_timings *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_ENUM_DV_TIMINGS</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <note>
52 <title>Experimental</title>
53 <para>This is an <link linkend="experimental"> experimental </link>
54 interface and may change in the future.</para>
55 </note>
56
57 <para>While some DV receivers or transmitters support a wide range of timings, others
58support only a limited number of timings. With this ioctl applications can enumerate a list
59of known supported timings. Call &VIDIOC-DV-TIMINGS-CAP; to check if it also supports other
60standards or even custom timings that are not in this list.</para>
61
62 <para>To query the available timings, applications initialize the
63<structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings;
64and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl with a pointer to this
65structure. Drivers fill the rest of the structure or return an
66&EINVAL; when the index is out of bounds. To enumerate all supported DV timings,
67applications shall begin at index zero, incrementing by one until the
68driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
69different set of DV timings after switching the video input or
70output.</para>
71
72 <table pgwide="1" frame="none" id="v4l2-enum-dv-timings">
73 <title>struct <structname>v4l2_enum_dv_timings</structname></title>
74 <tgroup cols="3">
75 &cs-str;
76 <tbody valign="top">
77 <row>
78 <entry>__u32</entry>
79 <entry><structfield>index</structfield></entry>
80 <entry>Number of the DV timings, set by the
81application.</entry>
82 </row>
83 <row>
84 <entry>__u32</entry>
85 <entry><structfield>reserved</structfield>[3]</entry>
86 <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
87 </row>
88 <row>
89 <entry>&v4l2-dv-timings;</entry>
90 <entry><structfield>timings</structfield></entry>
91 <entry>The timings.</entry>
92 </row>
93 </tbody>
94 </tgroup>
95 </table>
96 </refsect1>
97
98 <refsect1>
99 &return-value;
100
101 <variablelist>
102 <varlistentry>
103 <term><errorcode>EINVAL</errorcode></term>
104 <listitem>
105 <para>The &v4l2-enum-dv-timings; <structfield>index</structfield>
106is out of bounds.</para>
107 </listitem>
108 </varlistentry>
109 </variablelist>
110 </refsect1>
111</refentry>
112
113<!--
114Local Variables:
115mode: sgml
116sgml-parent-document: "v4l2.sgml"
117indent-tabs-mode: nil
118End:
119-->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
index 347d142e7431..81ebe48317fe 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
@@ -71,7 +71,7 @@ the application. This is in no way related to the <structfield>
71pixelformat</structfield> field.</entry> 71pixelformat</structfield> field.</entry>
72 </row> 72 </row>
73 <row> 73 <row>
74 <entry>&v4l2-buf-type;</entry> 74 <entry>__u32</entry>
75 <entry><structfield>type</structfield></entry> 75 <entry><structfield>type</structfield></entry>
76 <entry>Type of the data stream, set by the application. 76 <entry>Type of the data stream, set by the application.
77Only these types are valid here: 77Only these types are valid here:
@@ -81,7 +81,7 @@ Only these types are valid here:
81<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>, 81<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>,
82<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver 82<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
83defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant> 83defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
84and higher.</entry> 84and higher. See <xref linkend="v4l2-buf-type" />.</entry>
85 </row> 85 </row>
86 <row> 86 <row>
87 <entry>__u32</entry> 87 <entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
index 9b8efcd6e947..46d5a044a537 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
@@ -285,7 +285,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
285 <row> 285 <row>
286 <entry><constant>V4L2_IN_CAP_CUSTOM_TIMINGS</constant></entry> 286 <entry><constant>V4L2_IN_CAP_CUSTOM_TIMINGS</constant></entry>
287 <entry>0x00000002</entry> 287 <entry>0x00000002</entry>
288 <entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry> 288 <entry>This input supports setting video timings by using VIDIOC_S_DV_TIMINGS.</entry>
289 </row> 289 </row>
290 <row> 290 <row>
291 <entry><constant>V4L2_IN_CAP_STD</constant></entry> 291 <entry><constant>V4L2_IN_CAP_STD</constant></entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
index a64d5ef103fa..428020000ef0 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
@@ -170,7 +170,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
170 <row> 170 <row>
171 <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry> 171 <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
172 <entry>0x00000002</entry> 172 <entry>0x00000002</entry>
173 <entry>This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry> 173 <entry>This output supports setting video timings by using VIDIOC_S_DV_TIMINGS.</entry>
174 </row> 174 </row>
175 <row> 175 <row>
176 <entry><constant>V4L2_OUT_CAP_STD</constant></entry> 176 <entry><constant>V4L2_OUT_CAP_STD</constant></entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-crop.xml b/Documentation/DocBook/media/v4l/vidioc-g-crop.xml
index 01a50640dce0..c4ff3b1887fb 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-crop.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-crop.xml
@@ -100,14 +100,14 @@ changed and <constant>VIDIOC_S_CROP</constant> returns the
100 &cs-str; 100 &cs-str;
101 <tbody valign="top"> 101 <tbody valign="top">
102 <row> 102 <row>
103 <entry>&v4l2-buf-type;</entry> 103 <entry>__u32</entry>
104 <entry><structfield>type</structfield></entry> 104 <entry><structfield>type</structfield></entry>
105 <entry>Type of the data stream, set by the application. 105 <entry>Type of the data stream, set by the application.
106Only these types are valid here: <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>, 106Only these types are valid here: <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
107<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>, 107<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
108<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver 108<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
109defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant> 109defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
110and higher.</entry> 110and higher. See <xref linkend="v4l2-buf-type" />.</entry>
111 </row> 111 </row>
112 <row> 112 <row>
113 <entry>&v4l2-rect;</entry> 113 <entry>&v4l2-rect;</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml b/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml
index 7940c1149393..61be9fa3803a 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml
@@ -48,6 +48,12 @@
48 48
49 <refsect1> 49 <refsect1>
50 <title>Description</title> 50 <title>Description</title>
51
52 <para>These ioctls are <emphasis role="bold">deprecated</emphasis>.
53 New drivers and applications should use &VIDIOC-G-DV-TIMINGS; and &VIDIOC-S-DV-TIMINGS;
54 instead.
55 </para>
56
51 <para>To query and select the current DV preset, applications 57 <para>To query and select the current DV preset, applications
52use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant> 58use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant>
53ioctls which take a pointer to a &v4l2-dv-preset; type as argument. 59ioctls which take a pointer to a &v4l2-dv-preset; type as argument.
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
index 4a8648ae9a63..eda1a2991bbe 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
@@ -7,7 +7,7 @@
7 <refnamediv> 7 <refnamediv>
8 <refname>VIDIOC_G_DV_TIMINGS</refname> 8 <refname>VIDIOC_G_DV_TIMINGS</refname>
9 <refname>VIDIOC_S_DV_TIMINGS</refname> 9 <refname>VIDIOC_S_DV_TIMINGS</refname>
10 <refpurpose>Get or set custom DV timings for input or output</refpurpose> 10 <refpurpose>Get or set DV timings for input or output</refpurpose>
11 </refnamediv> 11 </refnamediv>
12 12
13 <refsynopsisdiv> 13 <refsynopsisdiv>
@@ -48,12 +48,15 @@
48 48
49 <refsect1> 49 <refsect1>
50 <title>Description</title> 50 <title>Description</title>
51 <para>To set custom DV timings for the input or output, applications use the 51 <para>To set DV timings for the input or output, applications use the
52<constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current custom timings, 52<constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current timings,
53applications use the <constant>VIDIOC_G_DV_TIMINGS</constant> ioctl. The detailed timing 53applications use the <constant>VIDIOC_G_DV_TIMINGS</constant> ioctl. The detailed timing
54information is filled in using the structure &v4l2-dv-timings;. These ioctls take 54information is filled in using the structure &v4l2-dv-timings;. These ioctls take
55a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported 55a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported
56or the timing values are not correct, the driver returns &EINVAL;.</para> 56or the timing values are not correct, the driver returns &EINVAL;.</para>
57<para>The <filename>linux/v4l2-dv-timings.h</filename> header can be used to get the
58timings of the formats in the <xref linkend="cea861" /> and <xref linkend="vesadmt" />
59standards.</para>
57 </refsect1> 60 </refsect1>
58 61
59 <refsect1> 62 <refsect1>
@@ -83,12 +86,13 @@ or the timing values are not correct, the driver returns &EINVAL;.</para>
83 <row> 86 <row>
84 <entry>__u32</entry> 87 <entry>__u32</entry>
85 <entry><structfield>width</structfield></entry> 88 <entry><structfield>width</structfield></entry>
86 <entry>Width of the active video in pixels</entry> 89 <entry>Width of the active video in pixels.</entry>
87 </row> 90 </row>
88 <row> 91 <row>
89 <entry>__u32</entry> 92 <entry>__u32</entry>
90 <entry><structfield>height</structfield></entry> 93 <entry><structfield>height</structfield></entry>
91 <entry>Height of the active video in lines</entry> 94 <entry>Height of the active video frame in lines. So for interlaced formats the
95 height of the active video in each field is <structfield>height</structfield>/2.</entry>
92 </row> 96 </row>
93 <row> 97 <row>
94 <entry>__u32</entry> 98 <entry>__u32</entry>
@@ -125,32 +129,52 @@ bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_H
125 <row> 129 <row>
126 <entry>__u32</entry> 130 <entry>__u32</entry>
127 <entry><structfield>vfrontporch</structfield></entry> 131 <entry><structfield>vfrontporch</structfield></entry>
128 <entry>Vertical front porch in lines</entry> 132 <entry>Vertical front porch in lines. For interlaced formats this refers to the
133 odd field (aka field 1).</entry>
129 </row> 134 </row>
130 <row> 135 <row>
131 <entry>__u32</entry> 136 <entry>__u32</entry>
132 <entry><structfield>vsync</structfield></entry> 137 <entry><structfield>vsync</structfield></entry>
133 <entry>Vertical sync length in lines</entry> 138 <entry>Vertical sync length in lines. For interlaced formats this refers to the
139 odd field (aka field 1).</entry>
134 </row> 140 </row>
135 <row> 141 <row>
136 <entry>__u32</entry> 142 <entry>__u32</entry>
137 <entry><structfield>vbackporch</structfield></entry> 143 <entry><structfield>vbackporch</structfield></entry>
138 <entry>Vertical back porch in lines</entry> 144 <entry>Vertical back porch in lines. For interlaced formats this refers to the
145 odd field (aka field 1).</entry>
139 </row> 146 </row>
140 <row> 147 <row>
141 <entry>__u32</entry> 148 <entry>__u32</entry>
142 <entry><structfield>il_vfrontporch</structfield></entry> 149 <entry><structfield>il_vfrontporch</structfield></entry>
143 <entry>Vertical front porch in lines for bottom field of interlaced field formats</entry> 150 <entry>Vertical front porch in lines for the even field (aka field 2) of
151 interlaced field formats.</entry>
144 </row> 152 </row>
145 <row> 153 <row>
146 <entry>__u32</entry> 154 <entry>__u32</entry>
147 <entry><structfield>il_vsync</structfield></entry> 155 <entry><structfield>il_vsync</structfield></entry>
148 <entry>Vertical sync length in lines for bottom field of interlaced field formats</entry> 156 <entry>Vertical sync length in lines for the even field (aka field 2) of
157 interlaced field formats.</entry>
149 </row> 158 </row>
150 <row> 159 <row>
151 <entry>__u32</entry> 160 <entry>__u32</entry>
152 <entry><structfield>il_vbackporch</structfield></entry> 161 <entry><structfield>il_vbackporch</structfield></entry>
153 <entry>Vertical back porch in lines for bottom field of interlaced field formats</entry> 162 <entry>Vertical back porch in lines for the even field (aka field 2) of
163 interlaced field formats.</entry>
164 </row>
165 <row>
166 <entry>__u32</entry>
167 <entry><structfield>standards</structfield></entry>
168 <entry>The video standard(s) this format belongs to. This will be filled in by
169 the driver. Applications must set this to 0. See <xref linkend="dv-bt-standards"/>
170 for a list of standards.</entry>
171 </row>
172 <row>
173 <entry>__u32</entry>
174 <entry><structfield>flags</structfield></entry>
175 <entry>Several flags giving more information about the format.
176 See <xref linkend="dv-bt-flags"/> for a description of the flags.
177 </entry>
154 </row> 178 </row>
155 </tbody> 179 </tbody>
156 </tgroup> 180 </tgroup>
@@ -211,6 +235,90 @@ bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_H
211 </tbody> 235 </tbody>
212 </tgroup> 236 </tgroup>
213 </table> 237 </table>
238 <table pgwide="1" frame="none" id="dv-bt-standards">
239 <title>DV BT Timing standards</title>
240 <tgroup cols="2">
241 &cs-str;
242 <tbody valign="top">
243 <row>
244 <entry>Timing standard</entry>
245 <entry>Description</entry>
246 </row>
247 <row>
248 <entry></entry>
249 <entry></entry>
250 </row>
251 <row>
252 <entry>V4L2_DV_BT_STD_CEA861</entry>
253 <entry>The timings follow the CEA-861 Digital TV Profile standard</entry>
254 </row>
255 <row>
256 <entry>V4L2_DV_BT_STD_DMT</entry>
257 <entry>The timings follow the VESA Discrete Monitor Timings standard</entry>
258 </row>
259 <row>
260 <entry>V4L2_DV_BT_STD_CVT</entry>
261 <entry>The timings follow the VESA Coordinated Video Timings standard</entry>
262 </row>
263 <row>
264 <entry>V4L2_DV_BT_STD_GTF</entry>
265 <entry>The timings follow the VESA Generalized Timings Formula standard</entry>
266 </row>
267 </tbody>
268 </tgroup>
269 </table>
270 <table pgwide="1" frame="none" id="dv-bt-flags">
271 <title>DV BT Timing flags</title>
272 <tgroup cols="2">
273 &cs-str;
274 <tbody valign="top">
275 <row>
276 <entry>Flag</entry>
277 <entry>Description</entry>
278 </row>
279 <row>
280 <entry></entry>
281 <entry></entry>
282 </row>
283 <row>
284 <entry>V4L2_DV_FL_REDUCED_BLANKING</entry>
285 <entry>CVT/GTF specific: the timings use reduced blanking (CVT) or the 'Secondary
286GTF' curve (GTF). In both cases the horizontal and/or vertical blanking
287intervals are reduced, allowing a higher resolution over the same
288bandwidth. This is a read-only flag, applications must not set this.
289 </entry>
290 </row>
291 <row>
292 <entry>V4L2_DV_FL_CAN_REDUCE_FPS</entry>
293 <entry>CEA-861 specific: set for CEA-861 formats with a framerate that is a multiple
294of six. These formats can be optionally played at 1 / 1.001 speed to
295be compatible with 60 Hz based standards such as NTSC and PAL-M that use a framerate of
29629.97 frames per second. If the transmitter can't generate such frequencies, then the
297flag will also be cleared. This is a read-only flag, applications must not set this.
298 </entry>
299 </row>
300 <row>
301 <entry>V4L2_DV_FL_REDUCED_FPS</entry>
302 <entry>CEA-861 specific: only valid for video transmitters, the flag is cleared
303by receivers. It is also only valid for formats with the V4L2_DV_FL_CAN_REDUCE_FPS flag
304set, for other formats the flag will be cleared by the driver.
305
306If the application sets this flag, then the pixelclock used to set up the transmitter is
307divided by 1.001 to make it compatible with NTSC framerates. If the transmitter
308can't generate such frequencies, then the flag will also be cleared.
309 </entry>
310 </row>
311 <row>
312 <entry>V4L2_DV_FL_HALF_LINE</entry>
313 <entry>Specific to interlaced formats: if set, then field 1 (aka the odd field)
314is really one half-line longer and field 2 (aka the even field) is really one half-line
315shorter, so each field has exactly the same number of half-lines. Whether half-lines can be
316detected or used depends on the hardware.
317 </entry>
318 </row>
319 </tbody>
320 </tgroup>
321 </table>
214 </refsect1> 322 </refsect1>
215 <refsect1> 323 <refsect1>
216 &return-value; 324 &return-value;
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
index b17a7aac6997..e3d5afcdafbb 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
@@ -265,6 +265,32 @@ These controls are described in <xref
265These controls are described in <xref 265These controls are described in <xref
266 linkend="flash-controls" />.</entry> 266 linkend="flash-controls" />.</entry>
267 </row> 267 </row>
268 <row>
269 <entry><constant>V4L2_CTRL_CLASS_JPEG</constant></entry>
270 <entry>0x9d0000</entry>
271 <entry>The class containing JPEG compression controls.
272These controls are described in <xref
273 linkend="jpeg-controls" />.</entry>
274 </row>
275 <row>
276 <entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
277 <entry>0x9e0000</entry> <entry>The class containing image
278 source controls. These controls are described in <xref
279 linkend="image-source-controls" />.</entry>
280 </row>
281 <row>
282 <entry><constant>V4L2_CTRL_CLASS_IMAGE_PROC</constant></entry>
283 <entry>0x9f0000</entry> <entry>The class containing image
284 processing controls. These controls are described in <xref
285 linkend="image-process-controls" />.</entry>
286 </row>
287 <row>
288 <entry><constant>V4L2_CTRL_CLASS_JPEG</constant></entry>
289 <entry>0x9d0000</entry>
290 <entry>The class containing JPEG compression controls.
291These controls are described in <xref
292 linkend="jpeg-controls" />.</entry>
293 </row>
268 </tbody> 294 </tbody>
269 </tgroup> 295 </tgroup>
270 </table> 296 </table>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
index 17fbda15137b..52acff193a6f 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
@@ -116,7 +116,7 @@ this ioctl.</para>
116 <colspec colname="c4" /> 116 <colspec colname="c4" />
117 <tbody valign="top"> 117 <tbody valign="top">
118 <row> 118 <row>
119 <entry>&v4l2-buf-type;</entry> 119 <entry>__u32</entry>
120 <entry><structfield>type</structfield></entry> 120 <entry><structfield>type</structfield></entry>
121 <entry></entry> 121 <entry></entry>
122 <entry>Type of the data stream, see <xref 122 <entry>Type of the data stream, see <xref
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
index 66e9a5257861..69c178a4d205 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
@@ -95,14 +95,14 @@ the &v4l2-output; <structfield>modulator</structfield> field and the
95&v4l2-modulator; <structfield>index</structfield> field.</entry> 95&v4l2-modulator; <structfield>index</structfield> field.</entry>
96 </row> 96 </row>
97 <row> 97 <row>
98 <entry>&v4l2-tuner-type;</entry> 98 <entry>__u32</entry>
99 <entry><structfield>type</structfield></entry> 99 <entry><structfield>type</structfield></entry>
100 <entry>The tuner type. This is the same value as in the 100 <entry>The tuner type. This is the same value as in the
101&v4l2-tuner; <structfield>type</structfield> field. The type must be set 101&v4l2-tuner; <structfield>type</structfield> field. See The type must be set
102to <constant>V4L2_TUNER_RADIO</constant> for <filename>/dev/radioX</filename> 102to <constant>V4L2_TUNER_RADIO</constant> for <filename>/dev/radioX</filename>
103device nodes, and to <constant>V4L2_TUNER_ANALOG_TV</constant> 103device nodes, and to <constant>V4L2_TUNER_ANALOG_TV</constant>
104for all others. The field is not applicable to modulators, &ie; ignored 104for all others. The field is not applicable to modulators, &ie; ignored
105by drivers.</entry> 105by drivers. See <xref linkend="v4l2-tuner-type" /></entry>
106 </row> 106 </row>
107 <row> 107 <row>
108 <entry>__u32</entry> 108 <entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-parm.xml b/Documentation/DocBook/media/v4l/vidioc-g-parm.xml
index 19b1d85dd668..f83d2cdd1185 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-parm.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-parm.xml
@@ -75,11 +75,12 @@ devices.</para>
75 &cs-ustr; 75 &cs-ustr;
76 <tbody valign="top"> 76 <tbody valign="top">
77 <row> 77 <row>
78 <entry>&v4l2-buf-type;</entry> 78 <entry>__u32</entry>
79 <entry><structfield>type</structfield></entry> 79 <entry><structfield>type</structfield></entry>
80 <entry></entry> 80 <entry></entry>
81 <entry>The buffer (stream) type, same as &v4l2-format; 81 <entry>The buffer (stream) type, same as &v4l2-format;
82<structfield>type</structfield>, set by the application.</entry> 82<structfield>type</structfield>, set by the application. See <xref
83 linkend="v4l2-buf-type" /></entry>
83 </row> 84 </row>
84 <row> 85 <row>
85 <entry>union</entry> 86 <entry>union</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-sliced-vbi-cap.xml b/Documentation/DocBook/media/v4l/vidioc-g-sliced-vbi-cap.xml
index 71741daaf725..bd015d1563ff 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-sliced-vbi-cap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-sliced-vbi-cap.xml
@@ -148,7 +148,7 @@ using the &VIDIOC-S-FMT; ioctl as described in <xref
148<structfield>service_lines</structfield>[1][0] to zero.</entry> 148<structfield>service_lines</structfield>[1][0] to zero.</entry>
149 </row> 149 </row>
150 <row> 150 <row>
151 <entry>&v4l2-buf-type;</entry> 151 <entry>__u32</entry>
152 <entry><structfield>type</structfield></entry> 152 <entry><structfield>type</structfield></entry>
153 <entry>Type of the data stream, see <xref 153 <entry>Type of the data stream, see <xref
154 linkend="v4l2-buf-type" />. Should be 154 linkend="v4l2-buf-type" />. Should be
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
index 91ec2fb658f8..62a1aa200a36 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
@@ -107,7 +107,7 @@ user.<!-- FIXME Video inputs already have a name, the purpose of this
107field is not quite clear.--></para></entry> 107field is not quite clear.--></para></entry>
108 </row> 108 </row>
109 <row> 109 <row>
110 <entry>&v4l2-tuner-type;</entry> 110 <entry>__u32</entry>
111 <entry><structfield>type</structfield></entry> 111 <entry><structfield>type</structfield></entry>
112 <entry spanname="hspan">Type of the tuner, see <xref 112 <entry spanname="hspan">Type of the tuner, see <xref
113 linkend="v4l2-tuner-type" />.</entry> 113 linkend="v4l2-tuner-type" />.</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
index 7bde698760e4..fa7ad7e33228 100644
--- a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
@@ -48,6 +48,12 @@
48 <refsect1> 48 <refsect1>
49 <title>Description</title> 49 <title>Description</title>
50 50
51 <note>
52 <title>Experimental</title>
53 <para>This is an <link linkend="experimental"> experimental </link>
54 interface and may change in the future.</para>
55 </note>
56
51 <para>Applications can optionally call the 57 <para>Applications can optionally call the
52<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer 58<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
53to the driver before actually enqueuing it, using the 59to the driver before actually enqueuing it, using the
diff --git a/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml b/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml
index 23b17f604211..1bc8aeb3ff1f 100644
--- a/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml
@@ -49,6 +49,10 @@ input</refpurpose>
49 <refsect1> 49 <refsect1>
50 <title>Description</title> 50 <title>Description</title>
51 51
52 <para>This ioctl is <emphasis role="bold">deprecated</emphasis>.
53 New drivers and applications should use &VIDIOC-QUERY-DV-TIMINGS; instead.
54 </para>
55
52 <para>The hardware may be able to detect the current DV preset 56 <para>The hardware may be able to detect the current DV preset
53automatically, similar to sensing the video standard. To do so, applications 57automatically, similar to sensing the video standard. To do so, applications
54call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a 58call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
diff --git a/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml
new file mode 100644
index 000000000000..44935a0ffcf0
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml
@@ -0,0 +1,104 @@
1<refentry id="vidioc-query-dv-timings">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_QUERY_DV_TIMINGS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_QUERY_DV_TIMINGS</refname>
9 <refpurpose>Sense the DV preset received by the current
10input</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_dv_timings *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_QUERY_DV_TIMINGS</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54 <para>This is an <link linkend="experimental"> experimental </link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>The hardware may be able to detect the current DV timings
59automatically, similar to sensing the video standard. To do so, applications
60call <constant>VIDIOC_QUERY_DV_TIMINGS</constant> with a pointer to a
61&v4l2-dv-timings;. Once the hardware detects the timings, it will fill in the
62timings structure.
63
64If the timings could not be detected because there was no signal, then
65<errorcode>ENOLINK</errorcode> is returned. If a signal was detected, but
66it was unstable and the receiver could not lock to the signal, then
67<errorcode>ENOLCK</errorcode> is returned. If the receiver could lock to the signal,
68but the format is unsupported (e.g. because the pixelclock is out of range
69of the hardware capabilities), then the driver fills in whatever timings it
70could find and returns <errorcode>ERANGE</errorcode>. In that case the application
71can call &VIDIOC-DV-TIMINGS-CAP; to compare the found timings with the hardware's
72capabilities in order to give more precise feedback to the user.
73</para>
74 </refsect1>
75
76 <refsect1>
77 &return-value;
78
79 <variablelist>
80 <varlistentry>
81 <term><errorcode>ENOLINK</errorcode></term>
82 <listitem>
83 <para>No timings could be detected because no signal was found.
84</para>
85 </listitem>
86 </varlistentry>
87 <varlistentry>
88 <term><errorcode>ENOLCK</errorcode></term>
89 <listitem>
90 <para>The signal was unstable and the hardware could not lock on to it.
91</para>
92 </listitem>
93 </varlistentry>
94 <varlistentry>
95 <term><errorcode>ERANGE</errorcode></term>
96 <listitem>
97 <para>Timings were found, but they are out of range of the hardware
98capabilities.
99</para>
100 </listitem>
101 </varlistentry>
102 </variablelist>
103 </refsect1>
104</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
index 36660d311b51..e6645b996558 100644
--- a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
@@ -127,7 +127,7 @@ the first control with a higher ID. Drivers which do not support this
127flag yet always return an &EINVAL;.</entry> 127flag yet always return an &EINVAL;.</entry>
128 </row> 128 </row>
129 <row> 129 <row>
130 <entry>&v4l2-ctrl-type;</entry> 130 <entry>__u32</entry>
131 <entry><structfield>type</structfield></entry> 131 <entry><structfield>type</structfield></entry>
132 <entry>Type of control, see <xref 132 <entry>Type of control, see <xref
133 linkend="v4l2-ctrl-type" />.</entry> 133 linkend="v4l2-ctrl-type" />.</entry>
@@ -215,11 +215,12 @@ the array to zero.</entry>
215 215
216 <table pgwide="1" frame="none" id="v4l2-querymenu"> 216 <table pgwide="1" frame="none" id="v4l2-querymenu">
217 <title>struct <structname>v4l2_querymenu</structname></title> 217 <title>struct <structname>v4l2_querymenu</structname></title>
218 <tgroup cols="3"> 218 <tgroup cols="4">
219 &cs-str; 219 &cs-str;
220 <tbody valign="top"> 220 <tbody valign="top">
221 <row> 221 <row>
222 <entry>__u32</entry> 222 <entry>__u32</entry>
223 <entry></entry>
223 <entry><structfield>id</structfield></entry> 224 <entry><structfield>id</structfield></entry>
224 <entry>Identifies the control, set by the application 225 <entry>Identifies the control, set by the application
225from the respective &v4l2-queryctrl; 226from the respective &v4l2-queryctrl;
@@ -227,18 +228,38 @@ from the respective &v4l2-queryctrl;
227 </row> 228 </row>
228 <row> 229 <row>
229 <entry>__u32</entry> 230 <entry>__u32</entry>
231 <entry></entry>
230 <entry><structfield>index</structfield></entry> 232 <entry><structfield>index</structfield></entry>
231 <entry>Index of the menu item, starting at zero, set by 233 <entry>Index of the menu item, starting at zero, set by
232 the application.</entry> 234 the application.</entry>
233 </row> 235 </row>
234 <row> 236 <row>
237 <entry>union</entry>
238 <entry></entry>
239 <entry></entry>
240 <entry></entry>
241 </row>
242 <row>
243 <entry></entry>
235 <entry>__u8</entry> 244 <entry>__u8</entry>
236 <entry><structfield>name</structfield>[32]</entry> 245 <entry><structfield>name</structfield>[32]</entry>
237 <entry>Name of the menu item, a NUL-terminated ASCII 246 <entry>Name of the menu item, a NUL-terminated ASCII
238string. This information is intended for the user.</entry> 247string. This information is intended for the user. This field is valid
248for <constant>V4L2_CTRL_FLAG_MENU</constant> type controls.</entry>
249 </row>
250 <row>
251 <entry></entry>
252 <entry>__s64</entry>
253 <entry><structfield>value</structfield></entry>
254 <entry>
255 Value of the integer menu item. This field is valid for
256 <constant>V4L2_CTRL_FLAG_INTEGER_MENU</constant> type
257 controls.
258 </entry>
239 </row> 259 </row>
240 <row> 260 <row>
241 <entry>__u32</entry> 261 <entry>__u32</entry>
262 <entry></entry>
242 <entry><structfield>reserved</structfield></entry> 263 <entry><structfield>reserved</structfield></entry>
243 <entry>Reserved for future extensions. Drivers must set 264 <entry>Reserved for future extensions. Drivers must set
244the array to zero.</entry> 265the array to zero.</entry>
@@ -292,6 +313,20 @@ the menu items can be enumerated with the
292<constant>VIDIOC_QUERYMENU</constant> ioctl.</entry> 313<constant>VIDIOC_QUERYMENU</constant> ioctl.</entry>
293 </row> 314 </row>
294 <row> 315 <row>
316 <entry><constant>V4L2_CTRL_TYPE_INTEGER_MENU</constant></entry>
317 <entry>&ge; 0</entry>
318 <entry>1</entry>
319 <entry>N-1</entry>
320 <entry>
321 The control has a menu of N choices. The values of the
322 menu items can be enumerated with the
323 <constant>VIDIOC_QUERYMENU</constant> ioctl. This is
324 similar to <constant>V4L2_CTRL_TYPE_MENU</constant>
325 except that instead of strings, the menu items are
326 signed 64-bit integers.
327 </entry>
328 </row>
329 <row>
295 <entry><constant>V4L2_CTRL_TYPE_BITMASK</constant></entry> 330 <entry><constant>V4L2_CTRL_TYPE_BITMASK</constant></entry>
296 <entry>0</entry> 331 <entry>0</entry>
297 <entry>n/a</entry> 332 <entry>n/a</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
index 7be4b1d29b90..d7c95057bc51 100644
--- a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
@@ -92,18 +92,19 @@ streamoff.--></para>
92 <entry>The number of buffers requested or granted.</entry> 92 <entry>The number of buffers requested or granted.</entry>
93 </row> 93 </row>
94 <row> 94 <row>
95 <entry>&v4l2-buf-type;</entry> 95 <entry>__u32</entry>
96 <entry><structfield>type</structfield></entry> 96 <entry><structfield>type</structfield></entry>
97 <entry>Type of the stream or buffers, this is the same 97 <entry>Type of the stream or buffers, this is the same
98as the &v4l2-format; <structfield>type</structfield> field. See <xref 98as the &v4l2-format; <structfield>type</structfield> field. See <xref
99 linkend="v4l2-buf-type" /> for valid values.</entry> 99 linkend="v4l2-buf-type" /> for valid values.</entry>
100 </row> 100 </row>
101 <row> 101 <row>
102 <entry>&v4l2-memory;</entry> 102 <entry>__u32</entry>
103 <entry><structfield>memory</structfield></entry> 103 <entry><structfield>memory</structfield></entry>
104 <entry>Applications set this field to 104 <entry>Applications set this field to
105<constant>V4L2_MEMORY_MMAP</constant> or 105<constant>V4L2_MEMORY_MMAP</constant> or
106<constant>V4L2_MEMORY_USERPTR</constant>.</entry> 106<constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory"
107/>.</entry>
107 </row> 108 </row>
108 <row> 109 <row>
109 <entry>__u32</entry> 110 <entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
index 18b1a8266f7c..407dfceb71f0 100644
--- a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
@@ -73,10 +73,11 @@ same value as in the &v4l2-input; <structfield>tuner</structfield>
73field and the &v4l2-tuner; <structfield>index</structfield> field.</entry> 73field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
74 </row> 74 </row>
75 <row> 75 <row>
76 <entry>&v4l2-tuner-type;</entry> 76 <entry>__u32</entry>
77 <entry><structfield>type</structfield></entry> 77 <entry><structfield>type</structfield></entry>
78 <entry>The tuner type. This is the same value as in the 78 <entry>The tuner type. This is the same value as in the
79&v4l2-tuner; <structfield>type</structfield> field.</entry> 79&v4l2-tuner; <structfield>type</structfield> field. See <xref
80 linkend="v4l2-tuner-type" /></entry>
80 </row> 81 </row>
81 <row> 82 <row>
82 <entry>__u32</entry> 83 <entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-crop.xml b/Documentation/DocBook/media/v4l/vidioc-subdev-g-crop.xml
index 06197323a8cc..4cddd788c589 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subdev-g-crop.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-crop.xml
@@ -58,9 +58,12 @@
58 <title>Description</title> 58 <title>Description</title>
59 59
60 <note> 60 <note>
61 <title>Experimental</title> 61 <title>Obsolete</title>
62 <para>This is an <link linkend="experimental">experimental</link> 62
63 interface and may change in the future.</para> 63 <para>This is an <link linkend="obsolete">obsolete</link>
64 interface and may be removed in the future. It is superseded by
65 <link linkend="vidioc-subdev-g-selection">the selection
66 API</link>.</para>
64 </note> 67 </note>
65 68
66 <para>To retrieve the current crop rectangle applications set the 69 <para>To retrieve the current crop rectangle applications set the
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
new file mode 100644
index 000000000000..208e9f0da3f3
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
@@ -0,0 +1,228 @@
1<refentry id="vidioc-subdev-g-selection">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_SELECTION</refname>
9 <refname>VIDIOC_SUBDEV_S_SELECTION</refname>
10 <refpurpose>Get or set selection rectangles on a subdev pad</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_subdev_selection *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>The selections are used to configure various image
59 processing functionality performed by the subdevs which affect the
60 image size. This currently includes cropping, scaling and
61 composition.</para>
62
63 <para>The selection API replaces <link
64 linkend="vidioc-subdev-g-crop">the old subdev crop API</link>. All
65 the function of the crop API, and more, are supported by the
66 selections API.</para>
67
68 <para>See <xref linkend="subdev"></xref> for
69 more information on how each selection target affects the image
70 processing pipeline inside the subdevice.</para>
71
72 <section>
73 <title>Types of selection targets</title>
74
75 <para>There are two types of selection targets: actual and bounds.
76 The ACTUAL targets are the targets which configure the hardware.
77 The BOUNDS target will return a rectangle that contain all
78 possible ACTUAL rectangles.</para>
79 </section>
80
81 <section>
82 <title>Discovering supported features</title>
83
84 <para>To discover which targets are supported, the user can
85 perform <constant>VIDIOC_SUBDEV_G_SELECTION</constant> on them.
86 Any unsupported target will return
87 <constant>EINVAL</constant>.</para>
88 </section>
89
90 <table pgwide="1" frame="none" id="v4l2-subdev-selection-targets">
91 <title>V4L2 subdev selection targets</title>
92 <tgroup cols="3">
93 &cs-def;
94 <tbody valign="top">
95 <row>
96 <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL</constant></entry>
97 <entry>0x0000</entry>
98 <entry>Actual crop. Defines the cropping
99 performed by the processing step.</entry>
100 </row>
101 <row>
102 <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS</constant></entry>
103 <entry>0x0002</entry>
104 <entry>Bounds of the crop rectangle.</entry>
105 </row>
106 <row>
107 <entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL</constant></entry>
108 <entry>0x0100</entry>
109 <entry>Actual compose rectangle. Used to configure scaling
110 on sink pads and composition on source pads.</entry>
111 </row>
112 <row>
113 <entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS</constant></entry>
114 <entry>0x0102</entry>
115 <entry>Bounds of the compose rectangle.</entry>
116 </row>
117 </tbody>
118 </tgroup>
119 </table>
120
121 <table pgwide="1" frame="none" id="v4l2-subdev-selection-flags">
122 <title>V4L2 subdev selection flags</title>
123 <tgroup cols="3">
124 &cs-def;
125 <tbody valign="top">
126 <row>
127 <entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant></entry>
128 <entry>(1 &lt;&lt; 0)</entry> <entry>Suggest the driver it
129 should choose greater or equal rectangle (in size) than
130 was requested. Albeit the driver may choose a lesser size,
131 it will only do so due to hardware limitations. Without
132 this flag (and
133 <constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant>) the
134 behaviour is to choose the closest possible
135 rectangle.</entry>
136 </row>
137 <row>
138 <entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant></entry>
139 <entry>(1 &lt;&lt; 1)</entry> <entry>Suggest the driver it
140 should choose lesser or equal rectangle (in size) than was
141 requested. Albeit the driver may choose a greater size, it
142 will only do so due to hardware limitations.</entry>
143 </row>
144 <row>
145 <entry><constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant></entry>
146 <entry>(1 &lt;&lt; 2)</entry>
147 <entry>The configuration should not be propagated to any
148 further processing steps. If this flag is not given, the
149 configuration is propagated inside the subdevice to all
150 further processing steps.</entry>
151 </row>
152 </tbody>
153 </tgroup>
154 </table>
155
156 <table pgwide="1" frame="none" id="v4l2-subdev-selection">
157 <title>struct <structname>v4l2_subdev_selection</structname></title>
158 <tgroup cols="3">
159 &cs-str;
160 <tbody valign="top">
161 <row>
162 <entry>__u32</entry>
163 <entry><structfield>which</structfield></entry>
164 <entry>Active or try selection, from
165 &v4l2-subdev-format-whence;.</entry>
166 </row>
167 <row>
168 <entry>__u32</entry>
169 <entry><structfield>pad</structfield></entry>
170 <entry>Pad number as reported by the media framework.</entry>
171 </row>
172 <row>
173 <entry>__u32</entry>
174 <entry><structfield>target</structfield></entry>
175 <entry>Target selection rectangle. See
176 <xref linkend="v4l2-subdev-selection-targets">.</xref>.</entry>
177 </row>
178 <row>
179 <entry>__u32</entry>
180 <entry><structfield>flags</structfield></entry>
181 <entry>Flags. See
182 <xref linkend="v4l2-subdev-selection-flags">.</xref></entry>
183 </row>
184 <row>
185 <entry>&v4l2-rect;</entry>
186 <entry><structfield>rect</structfield></entry>
187 <entry>Selection rectangle, in pixels.</entry>
188 </row>
189 <row>
190 <entry>__u32</entry>
191 <entry><structfield>reserved</structfield>[8]</entry>
192 <entry>Reserved for future extensions. Applications and drivers must
193 set the array to zero.</entry>
194 </row>
195 </tbody>
196 </tgroup>
197 </table>
198
199 </refsect1>
200
201 <refsect1>
202 &return-value;
203
204 <variablelist>
205 <varlistentry>
206 <term><errorcode>EBUSY</errorcode></term>
207 <listitem>
208 <para>The selection rectangle can't be changed because the
209 pad is currently busy. This can be caused, for instance, by
210 an active video stream on the pad. The ioctl must not be
211 retried without performing another action to fix the problem
212 first. Only returned by
213 <constant>VIDIOC_SUBDEV_S_SELECTION</constant></para>
214 </listitem>
215 </varlistentry>
216 <varlistentry>
217 <term><errorcode>EINVAL</errorcode></term>
218 <listitem>
219 <para>The &v4l2-subdev-selection;
220 <structfield>pad</structfield> references a non-existing
221 pad, the <structfield>which</structfield> field references a
222 non-existing format, or the selection target is not
223 supported on the given subdev pad.</para>
224 </listitem>
225 </varlistentry>
226 </variablelist>
227 </refsect1>
228</refentry>
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index d1d4a179a382..fbb241174486 100755
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -28,7 +28,8 @@ use IO::Handle;
28 "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", 28 "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
29 "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", 29 "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
30 "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", 30 "lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
31 "drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137"); 31 "drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137",
32 "drxk_pctv");
32 33
33# Check args 34# Check args
34syntax() if (scalar(@ARGV) != 1); 35syntax() if (scalar(@ARGV) != 1);
@@ -730,6 +731,23 @@ sub tda10071 {
730 "$fwfile"; 731 "$fwfile";
731} 732}
732 733
734sub drxk_pctv {
735 my $sourcefile = "PCTV_460e_reference.zip";
736 my $url = "ftp://ftp.pctvsystems.com/TV/driver/PCTV%2070e%2080e%20100e%20320e%20330e%20800e/";
737 my $hash = "4403de903bf2593464c8d74bbc200a57";
738 my $fwfile = "dvb-demod-drxk-pctv.fw";
739 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
740
741 checkstandard();
742
743 wgetfile($sourcefile, $url . $sourcefile);
744 verify($sourcefile, $hash);
745 unzip($sourcefile, $tmpdir);
746 extract("$tmpdir/PCTV\ 70e\ 80e\ 100e\ 320e\ 330e\ 800e/32\ bit/emOEM.sys", 0x72b80, 42692, $fwfile);
747
748 "$fwfile";
749}
750
733# --------------------------------------------------------------- 751# ---------------------------------------------------------------
734# Utilities 752# Utilities
735 753
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 1e69a81e99d4..c59f6e59fc1e 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -549,6 +549,15 @@ Who: Sasikantha Babu <sasikanth.v19@gmail.com>
549 549
550---------------------------- 550----------------------------
551 551
552What: remove bogus DV presets V4L2_DV_1080I29_97, V4L2_DV_1080I30 and
553 V4L2_DV_1080I25
554When: 3.6
555Why: These HDTV formats do not exist and were added by a confused mind
556 (that was me, to be precise...)
557Who: Hans Verkuil <hans.verkuil@cisco.com>
558
559----------------------------
560
552What: V4L2_CID_HCENTER, V4L2_CID_VCENTER V4L2 controls 561What: V4L2_CID_HCENTER, V4L2_CID_VCENTER V4L2 controls
553When: 3.7 562When: 3.7
554Why: The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated 563Why: The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index 3a0f879533ce..802875413873 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -335,6 +335,9 @@ the media_entity pipe field.
335Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must 335Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
336be identical for all nested calls to the function. 336be identical for all nested calls to the function.
337 337
338media_entity_pipeline_start() may return an error. In that case, it will
339clean up any the changes it did by itself.
340
338When stopping the stream, drivers must notify the entities with 341When stopping the stream, drivers must notify the entities with
339 342
340 media_entity_pipeline_stop(struct media_entity *entity); 343 media_entity_pipeline_stop(struct media_entity *entity);
@@ -351,3 +354,19 @@ If other operations need to be disallowed on streaming entities (such as
351changing entities configuration parameters) drivers can explicitly check the 354changing entities configuration parameters) drivers can explicitly check the
352media_entity stream_count field to find out if an entity is streaming. This 355media_entity stream_count field to find out if an entity is streaming. This
353operation must be done with the media_device graph_mutex held. 356operation must be done with the media_device graph_mutex held.
357
358
359Link validation
360---------------
361
362Link validation is performed by media_entity_pipeline_start() for any
363entity which has sink pads in the pipeline. The
364media_entity::link_validate() callback is used for that purpose. In
365link_validate() callback, entity driver should check that the properties of
366the source pad of the connected entity and its own sink pad match. It is up
367to the type of the entity (and in the end, the properties of the hardware)
368what matching actually means.
369
370Subsystems should facilitate link validation by providing subsystem specific
371helper functions to provide easy access for commonly needed information, and
372in the end provide a way to use driver-specific callbacks.
diff --git a/Documentation/video4linux/4CCs.txt b/Documentation/video4linux/4CCs.txt
new file mode 100644
index 000000000000..41241af1ebfe
--- /dev/null
+++ b/Documentation/video4linux/4CCs.txt
@@ -0,0 +1,32 @@
1Guidelines for Linux4Linux pixel format 4CCs
2============================================
3
4Guidelines for Video4Linux 4CC codes defined using v4l2_fourcc() are
5specified in this document. First of the characters defines the nature of
6the pixel format, compression and colour space. The interpretation of the
7other three characters depends on the first one.
8
9Existing 4CCs may not obey these guidelines.
10
11Formats
12=======
13
14Raw bayer
15---------
16
17The following first characters are used by raw bayer formats:
18
19 B: raw bayer, uncompressed
20 b: raw bayer, DPCM compressed
21 a: A-law compressed
22 u: u-law compressed
23
242nd character: pixel order
25 B: BGGR
26 G: GBRG
27 g: GRBG
28 R: RGGB
29
303rd character: uncompressed bits-per-pixel 0--9, A--
31
324th character: compressed bits-per-pixel 0--9, A--
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index e6c2842407a4..1e6b6531bbcc 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -276,6 +276,7 @@ pac7302 093a:2622 Genius Eye 312
276pac7302 093a:2624 PAC7302 276pac7302 093a:2624 PAC7302
277pac7302 093a:2625 Genius iSlim 310 277pac7302 093a:2625 Genius iSlim 310
278pac7302 093a:2626 Labtec 2200 278pac7302 093a:2626 Labtec 2200
279pac7302 093a:2627 Genius FaceCam 300
279pac7302 093a:2628 Genius iLook 300 280pac7302 093a:2628 Genius iLook 300
280pac7302 093a:2629 Genious iSlim 300 281pac7302 093a:2629 Genious iSlim 300
281pac7302 093a:262a Webcam 300k 282pac7302 093a:262a Webcam 300k
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt
index e2492a9d1027..43da22b89728 100644
--- a/Documentation/video4linux/v4l2-controls.txt
+++ b/Documentation/video4linux/v4l2-controls.txt
@@ -130,8 +130,18 @@ Menu controls are added by calling v4l2_ctrl_new_std_menu:
130 const struct v4l2_ctrl_ops *ops, 130 const struct v4l2_ctrl_ops *ops,
131 u32 id, s32 max, s32 skip_mask, s32 def); 131 u32 id, s32 max, s32 skip_mask, s32 def);
132 132
133Or alternatively for integer menu controls, by calling v4l2_ctrl_new_int_menu:
134
135 struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
136 const struct v4l2_ctrl_ops *ops,
137 u32 id, s32 max, s32 def, const s64 *qmenu_int);
138
133These functions are typically called right after the v4l2_ctrl_handler_init: 139These functions are typically called right after the v4l2_ctrl_handler_init:
134 140
141 static const s64 exp_bias_qmenu[] = {
142 -2, -1, 0, 1, 2
143 };
144
135 v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls); 145 v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
136 v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops, 146 v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
137 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 147 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
@@ -141,6 +151,11 @@ These functions are typically called right after the v4l2_ctrl_handler_init:
141 V4L2_CID_POWER_LINE_FREQUENCY, 151 V4L2_CID_POWER_LINE_FREQUENCY,
142 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 152 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
143 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); 153 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
154 v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
155 V4L2_CID_EXPOSURE_BIAS,
156 ARRAY_SIZE(exp_bias_qmenu) - 1,
157 ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
158 exp_bias_qmenu);
144 ... 159 ...
145 if (foo->ctrl_handler.error) { 160 if (foo->ctrl_handler.error) {
146 int err = foo->ctrl_handler.error; 161 int err = foo->ctrl_handler.error;
@@ -164,6 +179,12 @@ controls. There is no min argument since that is always 0 for menu controls,
164and instead of a step there is a skip_mask argument: if bit X is 1, then menu 179and instead of a step there is a skip_mask argument: if bit X is 1, then menu
165item X is skipped. 180item X is skipped.
166 181
182The v4l2_ctrl_new_int_menu function creates a new standard integer menu
183control with driver-specific items in the menu. It differs from
184v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and takes
185as the last argument an array of signed 64-bit integers that form an exact
186menu item list.
187
167Note that if something fails, the function will return NULL or an error and 188Note that if something fails, the function will return NULL or an error and
168set ctrl_handler->error to the error code. If ctrl_handler->error was already 189set ctrl_handler->error to the error code. If ctrl_handler->error was already
169set, then it will just return and do nothing. This is also true for 190set, then it will just return and do nothing. This is also true for
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 659b2ba12a4f..1f5905270050 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev,
182} 182}
183 183
184If you have multiple device nodes then it can be difficult to know when it is 184If you have multiple device nodes then it can be difficult to know when it is
185safe to unregister v4l2_device. For this purpose v4l2_device has refcounting 185safe to unregister v4l2_device for hotpluggable devices. For this purpose
186support. The refcount is increased whenever video_register_device is called and 186v4l2_device has refcounting support. The refcount is increased whenever
187it is decreased whenever that device node is released. When the refcount reaches 187video_register_device is called and it is decreased whenever that device node
188zero, then the v4l2_device release() callback is called. You can do your final 188is released. When the refcount reaches zero, then the v4l2_device release()
189cleanup there. 189callback is called. You can do your final cleanup there.
190 190
191If other device nodes (e.g. ALSA) are created, then you can increase and 191If other device nodes (e.g. ALSA) are created, then you can increase and
192decrease the refcount manually as well by calling: 192decrease the refcount manually as well by calling:
@@ -197,6 +197,10 @@ or:
197 197
198int v4l2_device_put(struct v4l2_device *v4l2_dev); 198int v4l2_device_put(struct v4l2_device *v4l2_dev);
199 199
200Since the initial refcount is 1 you also need to call v4l2_device_put in the
201disconnect() callback (for USB devices) or in the remove() callback (for e.g.
202PCI devices), otherwise the refcount will never reach 0.
203
200struct v4l2_subdev 204struct v4l2_subdev
201------------------ 205------------------
202 206
@@ -262,11 +266,16 @@ struct v4l2_subdev_video_ops {
262 ... 266 ...
263}; 267};
264 268
269struct v4l2_subdev_pad_ops {
270 ...
271};
272
265struct v4l2_subdev_ops { 273struct v4l2_subdev_ops {
266 const struct v4l2_subdev_core_ops *core; 274 const struct v4l2_subdev_core_ops *core;
267 const struct v4l2_subdev_tuner_ops *tuner; 275 const struct v4l2_subdev_tuner_ops *tuner;
268 const struct v4l2_subdev_audio_ops *audio; 276 const struct v4l2_subdev_audio_ops *audio;
269 const struct v4l2_subdev_video_ops *video; 277 const struct v4l2_subdev_video_ops *video;
278 const struct v4l2_subdev_pad_ops *video;
270}; 279};
271 280
272The core ops are common to all subdevs, the other categories are implemented 281The core ops are common to all subdevs, the other categories are implemented
@@ -303,6 +312,22 @@ Don't forget to cleanup the media entity before the sub-device is destroyed:
303 312
304 media_entity_cleanup(&sd->entity); 313 media_entity_cleanup(&sd->entity);
305 314
315If the subdev driver intends to process video and integrate with the media
316framework, it must implement format related functionality using
317v4l2_subdev_pad_ops instead of v4l2_subdev_video_ops.
318
319In that case, the subdev driver may set the link_validate field to provide
320its own link validation function. The link validation function is called for
321every link in the pipeline where both of the ends of the links are V4L2
322sub-devices. The driver is still responsible for validating the correctness
323of the format configuration between sub-devices and video nodes.
324
325If link_validate op is not set, the default function
326v4l2_subdev_link_validate_default() is used instead. This function ensures
327that width, height and the media bus pixel code are equal on both source and
328sink of the link. Subdev drivers are also free to use this function to
329perform the checks mentioned above in addition to their own checks.
330
306A device (bridge) driver needs to register the v4l2_subdev with the 331A device (bridge) driver needs to register the v4l2_subdev with the
307v4l2_device: 332v4l2_device:
308 333
@@ -555,19 +580,25 @@ allocated memory.
555You should also set these fields: 580You should also set these fields:
556 581
557- v4l2_dev: set to the v4l2_device parent device. 582- v4l2_dev: set to the v4l2_device parent device.
583
558- name: set to something descriptive and unique. 584- name: set to something descriptive and unique.
585
559- fops: set to the v4l2_file_operations struct. 586- fops: set to the v4l2_file_operations struct.
587
560- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance 588- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
561 (highly recommended to use this and it might become compulsory in the 589 (highly recommended to use this and it might become compulsory in the
562 future!), then set this to your v4l2_ioctl_ops struct. 590 future!), then set this to your v4l2_ioctl_ops struct.
591
563- lock: leave to NULL if you want to do all the locking in the driver. 592- lock: leave to NULL if you want to do all the locking in the driver.
564 Otherwise you give it a pointer to a struct mutex_lock and before any 593 Otherwise you give it a pointer to a struct mutex_lock and before the
565 of the v4l2_file_operations is called this lock will be taken by the 594 unlocked_ioctl file operation is called this lock will be taken by the
566 core and released afterwards. 595 core and released afterwards. See the next section for more details.
596
567- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY. 597- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
568 If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device. 598 If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
569 If you want to have a separate priority state per (group of) device node(s), 599 If you want to have a separate priority state per (group of) device node(s),
570 then you can point it to your own struct v4l2_prio_state. 600 then you can point it to your own struct v4l2_prio_state.
601
571- parent: you only set this if v4l2_device was registered with NULL as 602- parent: you only set this if v4l2_device was registered with NULL as
572 the parent device struct. This only happens in cases where one hardware 603 the parent device struct. This only happens in cases where one hardware
573 device has multiple PCI devices that all share the same v4l2_device core. 604 device has multiple PCI devices that all share the same v4l2_device core.
@@ -577,6 +608,7 @@ You should also set these fields:
577 (cx8802). Since the v4l2_device cannot be associated with a particular 608 (cx8802). Since the v4l2_device cannot be associated with a particular
578 PCI device it is setup without a parent device. But when the struct 609 PCI device it is setup without a parent device. But when the struct
579 video_device is setup you do know which parent PCI device to use. 610 video_device is setup you do know which parent PCI device to use.
611
580- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework 612- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
581 handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct 613 handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
582 v4l2_fh. Eventually this flag will disappear once all drivers use the core 614 v4l2_fh. Eventually this flag will disappear once all drivers use the core
@@ -587,6 +619,16 @@ in your v4l2_file_operations struct.
587 619
588Do not use .ioctl! This is deprecated and will go away in the future. 620Do not use .ioctl! This is deprecated and will go away in the future.
589 621
622In some cases you want to tell the core that a function you had specified in
623your v4l2_ioctl_ops should be ignored. You can mark such ioctls by calling this
624function before video_device_register is called:
625
626void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd);
627
628This tends to be needed if based on external factors (e.g. which card is
629being used) you want to turns off certain features in v4l2_ioctl_ops without
630having to make a new struct.
631
590The v4l2_file_operations struct is a subset of file_operations. The main 632The v4l2_file_operations struct is a subset of file_operations. The main
591difference is that the inode argument is omitted since it is never used. 633difference is that the inode argument is omitted since it is never used.
592 634
@@ -609,8 +651,22 @@ v4l2_file_operations and locking
609-------------------------------- 651--------------------------------
610 652
611You can set a pointer to a mutex_lock in struct video_device. Usually this 653You can set a pointer to a mutex_lock in struct video_device. Usually this
612will be either a top-level mutex or a mutex per device node. If you want 654will be either a top-level mutex or a mutex per device node. By default this
613finer-grained locking then you have to set it to NULL and do you own locking. 655lock will be used for unlocked_ioctl, but you can disable locking for
656selected ioctls by calling:
657
658 void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd);
659
660E.g.: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF);
661
662You have to call this before you register the video_device.
663
664Particularly with USB drivers where certain commands such as setting controls
665can take a long time you may want to do your own locking for the buffer queuing
666ioctls.
667
668If you want still finer-grained locking then you have to set mutex_lock to NULL
669and do you own locking completely.
614 670
615It is up to the driver developer to decide which method to use. However, if 671It is up to the driver developer to decide which method to use. However, if
616your driver has high-latency operations (for example, changing the exposure 672your driver has high-latency operations (for example, changing the exposure
@@ -618,7 +674,7 @@ of a USB webcam might take a long time), then you might be better off with
618doing your own locking if you want to allow the user to do other things with 674doing your own locking if you want to allow the user to do other things with
619the device while waiting for the high-latency command to finish. 675the device while waiting for the high-latency command to finish.
620 676
621If a lock is specified then all file operations will be serialized on that 677If a lock is specified then all ioctl commands will be serialized on that
622lock. If you use videobuf then you must pass the same lock to the videobuf 678lock. If you use videobuf then you must pass the same lock to the videobuf
623queue initialize function: if videobuf has to wait for a frame to arrive, then 679queue initialize function: if videobuf has to wait for a frame to arrive, then
624it will temporarily unlock the lock and relock it afterwards. If your driver 680it will temporarily unlock the lock and relock it afterwards. If your driver
@@ -941,21 +997,35 @@ fast.
941 997
942Useful functions: 998Useful functions:
943 999
944- v4l2_event_queue() 1000void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
945 1001
946 Queue events to video device. The driver's only responsibility is to fill 1002 Queue events to video device. The driver's only responsibility is to fill
947 in the type and the data fields. The other fields will be filled in by 1003 in the type and the data fields. The other fields will be filled in by
948 V4L2. 1004 V4L2.
949 1005
950- v4l2_event_subscribe() 1006int v4l2_event_subscribe(struct v4l2_fh *fh,
1007 struct v4l2_event_subscription *sub, unsigned elems,
1008 const struct v4l2_subscribed_event_ops *ops)
951 1009
952 The video_device->ioctl_ops->vidioc_subscribe_event must check the driver 1010 The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
953 is able to produce events with specified event id. Then it calls 1011 is able to produce events with specified event id. Then it calls
954 v4l2_event_subscribe() to subscribe the event. The last argument is the 1012 v4l2_event_subscribe() to subscribe the event.
955 size of the event queue for this event. If it is 0, then the framework 1013
956 will fill in a default value (this depends on the event type). 1014 The elems argument is the size of the event queue for this event. If it is 0,
1015 then the framework will fill in a default value (this depends on the event
1016 type).
1017
1018 The ops argument allows the driver to specify a number of callbacks:
1019 * add: called when a new listener gets added (subscribing to the same
1020 event twice will only cause this callback to get called once)
1021 * del: called when a listener stops listening
1022 * replace: replace event 'old' with event 'new'.
1023 * merge: merge event 'old' into event 'new'.
1024 All 4 callbacks are optional, if you don't want to specify any callbacks
1025 the ops argument itself maybe NULL.
957 1026
958- v4l2_event_unsubscribe() 1027int v4l2_event_unsubscribe(struct v4l2_fh *fh,
1028 struct v4l2_event_subscription *sub)
959 1029
960 vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use 1030 vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
961 v4l2_event_unsubscribe() directly unless it wants to be involved in 1031 v4l2_event_unsubscribe() directly unless it wants to be involved in
@@ -964,7 +1034,7 @@ Useful functions:
964 The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The 1034 The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
965 drivers may want to handle this in a special way. 1035 drivers may want to handle this in a special way.
966 1036
967- v4l2_event_pending() 1037int v4l2_event_pending(struct v4l2_fh *fh)
968 1038
969 Returns the number of pending events. Useful when implementing poll. 1039 Returns the number of pending events. Useful when implementing poll.
970 1040
diff --git a/MAINTAINERS b/MAINTAINERS
index 27a1d3c6eec8..54c984e9d058 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2718,6 +2718,13 @@ S: Maintained
2718F: Documentation/hwmon/f71805f 2718F: Documentation/hwmon/f71805f
2719F: drivers/hwmon/f71805f.c 2719F: drivers/hwmon/f71805f.c
2720 2720
2721FC0011 TUNER DRIVER
2722M: Michael Buesch <m@bues.ch>
2723L: linux-media@vger.kernel.org
2724S: Maintained
2725F: drivers/media/common/tuners/fc0011.h
2726F: drivers/media/common/tuners/fc0011.c
2727
2721FANOTIFY 2728FANOTIFY
2722M: Eric Paris <eparis@redhat.com> 2729M: Eric Paris <eparis@redhat.com>
2723S: Maintained 2730S: Maintained
@@ -7191,7 +7198,7 @@ F: include/linux/usb/usbnet.h
7191 7198
7192USB VIDEO CLASS 7199USB VIDEO CLASS
7193M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 7200M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7194L: linux-uvc-devel@lists.berlios.de (subscribers-only) 7201L: linux-uvc-devel@lists.sourceforge.net (subscribers-only)
7195L: linux-media@vger.kernel.org 7202L: linux-media@vger.kernel.org
7196T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git 7203T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
7197W: http://www.ideasonboard.org/uvc/ 7204W: http://www.ideasonboard.org/uvc/
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 748ba2e311b5..dff82eb57cd9 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -178,7 +178,7 @@ static struct soc_camera_link iclink_tvp5150 = {
178 178
179static struct mx2_camera_platform_data visstrim_camera = { 179static struct mx2_camera_platform_data visstrim_camera = {
180 .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE | 180 .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
181 MX2_CAMERA_SWAP16 | MX2_CAMERA_PCLK_SAMPLE_RISING, 181 MX2_CAMERA_PCLK_SAMPLE_RISING,
182 .clk = 100000, 182 .clk = 100000,
183}; 183};
184 184
diff --git a/arch/arm/plat-mxc/include/mach/mx2_cam.h b/arch/arm/plat-mxc/include/mach/mx2_cam.h
index 3c080a32dbf5..7ded6f1f74bc 100644
--- a/arch/arm/plat-mxc/include/mach/mx2_cam.h
+++ b/arch/arm/plat-mxc/include/mach/mx2_cam.h
@@ -23,7 +23,6 @@
23#ifndef __MACH_MX2_CAM_H_ 23#ifndef __MACH_MX2_CAM_H_
24#define __MACH_MX2_CAM_H_ 24#define __MACH_MX2_CAM_H_
25 25
26#define MX2_CAMERA_SWAP16 (1 << 0)
27#define MX2_CAMERA_EXT_VSYNC (1 << 1) 26#define MX2_CAMERA_EXT_VSYNC (1 << 1)
28#define MX2_CAMERA_CCIR (1 << 2) 27#define MX2_CAMERA_CCIR (1 << 2)
29#define MX2_CAMERA_CCIR_INTERLACE (1 << 3) 28#define MX2_CAMERA_CCIR_INTERLACE (1 << 3)
@@ -31,7 +30,6 @@
31#define MX2_CAMERA_GATED_CLOCK (1 << 5) 30#define MX2_CAMERA_GATED_CLOCK (1 << 5)
32#define MX2_CAMERA_INV_DATA (1 << 6) 31#define MX2_CAMERA_INV_DATA (1 << 6)
33#define MX2_CAMERA_PCLK_SAMPLE_RISING (1 << 7) 32#define MX2_CAMERA_PCLK_SAMPLE_RISING (1 << 7)
34#define MX2_CAMERA_PACK_DIR_MSB (1 << 8)
35 33
36/** 34/**
37 * struct mx2_camera_platform_data - optional platform data for mx2_camera 35 * struct mx2_camera_platform_data - optional platform data for mx2_camera
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index 117a59aaa70e..5f558851d646 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -31,8 +31,7 @@
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/jiffies.h> 33#include <linux/jiffies.h>
34 34#include <linux/fixp-arith.h>
35#include "fixp-arith.h"
36 35
37MODULE_LICENSE("GPL"); 36MODULE_LICENSE("GPL");
38MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>"); 37MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>");
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 71f8e018e564..7d42c11c8684 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -198,7 +198,6 @@ static int fops_open(struct file *file)
198 struct saa7146_dev *dev = video_drvdata(file); 198 struct saa7146_dev *dev = video_drvdata(file);
199 struct saa7146_fh *fh = NULL; 199 struct saa7146_fh *fh = NULL;
200 int result = 0; 200 int result = 0;
201
202 enum v4l2_buf_type type; 201 enum v4l2_buf_type type;
203 202
204 DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); 203 DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
@@ -227,11 +226,12 @@ static int fops_open(struct file *file)
227 goto out; 226 goto out;
228 } 227 }
229 228
230 file->private_data = fh; 229 v4l2_fh_init(&fh->fh, vdev);
230
231 file->private_data = &fh->fh;
231 fh->dev = dev; 232 fh->dev = dev;
232 fh->type = type;
233 233
234 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 234 if (vdev->vfl_type == VFL_TYPE_VBI) {
235 DEB_S("initializing vbi...\n"); 235 DEB_S("initializing vbi...\n");
236 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 236 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
237 result = saa7146_vbi_uops.open(dev,file); 237 result = saa7146_vbi_uops.open(dev,file);
@@ -252,6 +252,7 @@ static int fops_open(struct file *file)
252 } 252 }
253 253
254 result = 0; 254 result = 0;
255 v4l2_fh_add(&fh->fh);
255out: 256out:
256 if (fh && result != 0) { 257 if (fh && result != 0) {
257 kfree(fh); 258 kfree(fh);
@@ -263,6 +264,7 @@ out:
263 264
264static int fops_release(struct file *file) 265static int fops_release(struct file *file)
265{ 266{
267 struct video_device *vdev = video_devdata(file);
266 struct saa7146_fh *fh = file->private_data; 268 struct saa7146_fh *fh = file->private_data;
267 struct saa7146_dev *dev = fh->dev; 269 struct saa7146_dev *dev = fh->dev;
268 270
@@ -271,7 +273,7 @@ static int fops_release(struct file *file)
271 if (mutex_lock_interruptible(&saa7146_devices_lock)) 273 if (mutex_lock_interruptible(&saa7146_devices_lock))
272 return -ERESTARTSYS; 274 return -ERESTARTSYS;
273 275
274 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 276 if (vdev->vfl_type == VFL_TYPE_VBI) {
275 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 277 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
276 saa7146_vbi_uops.release(dev,file); 278 saa7146_vbi_uops.release(dev,file);
277 if (dev->ext_vv_data->vbi_fops.release) 279 if (dev->ext_vv_data->vbi_fops.release)
@@ -280,6 +282,8 @@ static int fops_release(struct file *file)
280 saa7146_video_uops.release(dev,file); 282 saa7146_video_uops.release(dev,file);
281 } 283 }
282 284
285 v4l2_fh_del(&fh->fh);
286 v4l2_fh_exit(&fh->fh);
283 module_put(dev->ext->module); 287 module_put(dev->ext->module);
284 file->private_data = NULL; 288 file->private_data = NULL;
285 kfree(fh); 289 kfree(fh);
@@ -291,19 +295,22 @@ static int fops_release(struct file *file)
291 295
292static int fops_mmap(struct file *file, struct vm_area_struct * vma) 296static int fops_mmap(struct file *file, struct vm_area_struct * vma)
293{ 297{
298 struct video_device *vdev = video_devdata(file);
294 struct saa7146_fh *fh = file->private_data; 299 struct saa7146_fh *fh = file->private_data;
295 struct videobuf_queue *q; 300 struct videobuf_queue *q;
296 301
297 switch (fh->type) { 302 switch (vdev->vfl_type) {
298 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 303 case VFL_TYPE_GRABBER: {
299 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n", 304 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",
300 file, vma); 305 file, vma);
301 q = &fh->video_q; 306 q = &fh->video_q;
302 break; 307 break;
303 } 308 }
304 case V4L2_BUF_TYPE_VBI_CAPTURE: { 309 case VFL_TYPE_VBI: {
305 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n", 310 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",
306 file, vma); 311 file, vma);
312 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
313 return -ENODEV;
307 q = &fh->vbi_q; 314 q = &fh->vbi_q;
308 break; 315 break;
309 } 316 }
@@ -317,15 +324,19 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
317 324
318static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) 325static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
319{ 326{
327 struct video_device *vdev = video_devdata(file);
320 struct saa7146_fh *fh = file->private_data; 328 struct saa7146_fh *fh = file->private_data;
321 struct videobuf_buffer *buf = NULL; 329 struct videobuf_buffer *buf = NULL;
322 struct videobuf_queue *q; 330 struct videobuf_queue *q;
331 unsigned int res = v4l2_ctrl_poll(file, wait);
323 332
324 DEB_EE("file:%p, poll:%p\n", file, wait); 333 DEB_EE("file:%p, poll:%p\n", file, wait);
325 334
326 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 335 if (vdev->vfl_type == VFL_TYPE_VBI) {
336 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
337 return res | POLLOUT | POLLWRNORM;
327 if( 0 == fh->vbi_q.streaming ) 338 if( 0 == fh->vbi_q.streaming )
328 return videobuf_poll_stream(file, &fh->vbi_q, wait); 339 return res | videobuf_poll_stream(file, &fh->vbi_q, wait);
329 q = &fh->vbi_q; 340 q = &fh->vbi_q;
330 } else { 341 } else {
331 DEB_D("using video queue\n"); 342 DEB_D("using video queue\n");
@@ -337,31 +348,32 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
337 348
338 if (!buf) { 349 if (!buf) {
339 DEB_D("buf == NULL!\n"); 350 DEB_D("buf == NULL!\n");
340 return POLLERR; 351 return res | POLLERR;
341 } 352 }
342 353
343 poll_wait(file, &buf->done, wait); 354 poll_wait(file, &buf->done, wait);
344 if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { 355 if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) {
345 DEB_D("poll succeeded!\n"); 356 DEB_D("poll succeeded!\n");
346 return POLLIN|POLLRDNORM; 357 return res | POLLIN | POLLRDNORM;
347 } 358 }
348 359
349 DEB_D("nothing to poll for, buf->state:%d\n", buf->state); 360 DEB_D("nothing to poll for, buf->state:%d\n", buf->state);
350 return 0; 361 return res;
351} 362}
352 363
353static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 364static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
354{ 365{
366 struct video_device *vdev = video_devdata(file);
355 struct saa7146_fh *fh = file->private_data; 367 struct saa7146_fh *fh = file->private_data;
356 368
357 switch (fh->type) { 369 switch (vdev->vfl_type) {
358 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 370 case VFL_TYPE_GRABBER:
359/* 371/*
360 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", 372 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun",
361 file, data, (unsigned long)count); 373 file, data, (unsigned long)count);
362*/ 374*/
363 return saa7146_video_uops.read(file,data,count,ppos); 375 return saa7146_video_uops.read(file,data,count,ppos);
364 case V4L2_BUF_TYPE_VBI_CAPTURE: 376 case VFL_TYPE_VBI:
365/* 377/*
366 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", 378 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
367 file, data, (unsigned long)count); 379 file, data, (unsigned long)count);
@@ -377,12 +389,13 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
377 389
378static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) 390static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
379{ 391{
392 struct video_device *vdev = video_devdata(file);
380 struct saa7146_fh *fh = file->private_data; 393 struct saa7146_fh *fh = file->private_data;
381 394
382 switch (fh->type) { 395 switch (vdev->vfl_type) {
383 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 396 case VFL_TYPE_GRABBER:
384 return -EINVAL; 397 return -EINVAL;
385 case V4L2_BUF_TYPE_VBI_CAPTURE: 398 case VFL_TYPE_VBI:
386 if (fh->dev->ext_vv_data->vbi_fops.write) 399 if (fh->dev->ext_vv_data->vbi_fops.write)
387 return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); 400 return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
388 else 401 else
@@ -429,8 +442,15 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
429 } 442 }
430} 443}
431 444
445static const struct v4l2_ctrl_ops saa7146_ctrl_ops = {
446 .s_ctrl = saa7146_s_ctrl,
447};
448
432int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) 449int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
433{ 450{
451 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
452 struct v4l2_pix_format *fmt;
453 struct v4l2_vbi_format *vbi;
434 struct saa7146_vv *vv; 454 struct saa7146_vv *vv;
435 int err; 455 int err;
436 456
@@ -438,12 +458,32 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
438 if (err) 458 if (err)
439 return err; 459 return err;
440 460
461 v4l2_ctrl_handler_init(hdl, 6);
462 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
463 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
464 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
465 V4L2_CID_CONTRAST, 0, 127, 1, 64);
466 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
467 V4L2_CID_SATURATION, 0, 127, 1, 64);
468 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
469 V4L2_CID_VFLIP, 0, 1, 1, 0);
470 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
471 V4L2_CID_HFLIP, 0, 1, 1, 0);
472 if (hdl->error) {
473 err = hdl->error;
474 v4l2_ctrl_handler_free(hdl);
475 return err;
476 }
477 dev->v4l2_dev.ctrl_handler = hdl;
478
441 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); 479 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
442 if (vv == NULL) { 480 if (vv == NULL) {
443 ERR("out of memory. aborting.\n"); 481 ERR("out of memory. aborting.\n");
482 v4l2_ctrl_handler_free(hdl);
444 return -ENOMEM; 483 return -ENOMEM;
445 } 484 }
446 ext_vv->ops = saa7146_video_ioctl_ops; 485 ext_vv->vid_ops = saa7146_video_ioctl_ops;
486 ext_vv->vbi_ops = saa7146_vbi_ioctl_ops;
447 ext_vv->core_ops = &saa7146_video_ioctl_ops; 487 ext_vv->core_ops = &saa7146_video_ioctl_ops;
448 488
449 DEB_EE("dev:%p\n", dev); 489 DEB_EE("dev:%p\n", dev);
@@ -463,6 +503,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
463 if( NULL == vv->d_clipping.cpu_addr ) { 503 if( NULL == vv->d_clipping.cpu_addr ) {
464 ERR("out of memory. aborting.\n"); 504 ERR("out of memory. aborting.\n");
465 kfree(vv); 505 kfree(vv);
506 v4l2_ctrl_handler_free(hdl);
466 return -1; 507 return -1;
467 } 508 }
468 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); 509 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
@@ -471,6 +512,39 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
471 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 512 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
472 saa7146_vbi_uops.init(dev,vv); 513 saa7146_vbi_uops.init(dev,vv);
473 514
515 fmt = &vv->ov_fb.fmt;
516 fmt->width = vv->standard->h_max_out;
517 fmt->height = vv->standard->v_max_out;
518 fmt->pixelformat = V4L2_PIX_FMT_RGB565;
519 fmt->bytesperline = 2 * fmt->width;
520 fmt->sizeimage = fmt->bytesperline * fmt->height;
521 fmt->colorspace = V4L2_COLORSPACE_SRGB;
522
523 fmt = &vv->video_fmt;
524 fmt->width = 384;
525 fmt->height = 288;
526 fmt->pixelformat = V4L2_PIX_FMT_BGR24;
527 fmt->field = V4L2_FIELD_ANY;
528 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
529 fmt->bytesperline = 3 * fmt->width;
530 fmt->sizeimage = fmt->bytesperline * fmt->height;
531
532 vbi = &vv->vbi_fmt;
533 vbi->sampling_rate = 27000000;
534 vbi->offset = 248; /* todo */
535 vbi->samples_per_line = 720 * 2;
536 vbi->sample_format = V4L2_PIX_FMT_GREY;
537
538 /* fixme: this only works for PAL */
539 vbi->start[0] = 5;
540 vbi->count[0] = 16;
541 vbi->start[1] = 312;
542 vbi->count[1] = 16;
543
544 init_timer(&vv->vbi_read_timeout);
545
546 vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING;
547 vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY;
474 dev->vv_data = vv; 548 dev->vv_data = vv;
475 dev->vv_callback = &vv_callback; 549 dev->vv_callback = &vv_callback;
476 550
@@ -486,6 +560,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
486 560
487 v4l2_device_unregister(&dev->v4l2_dev); 561 v4l2_device_unregister(&dev->v4l2_dev);
488 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); 562 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
563 v4l2_ctrl_handler_free(&dev->ctrl_handler);
489 kfree(vv); 564 kfree(vv);
490 dev->vv_data = NULL; 565 dev->vv_data = NULL;
491 dev->vv_callback = NULL; 566 dev->vv_callback = NULL;
@@ -509,10 +584,19 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
509 return -ENOMEM; 584 return -ENOMEM;
510 585
511 vfd->fops = &video_fops; 586 vfd->fops = &video_fops;
512 vfd->ioctl_ops = &dev->ext_vv_data->ops; 587 if (type == VFL_TYPE_GRABBER)
588 vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
589 else
590 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
513 vfd->release = video_device_release; 591 vfd->release = video_device_release;
592 /* Locking in file operations other than ioctl should be done by
593 the driver, not the V4L2 core.
594 This driver needs auditing so that this flag can be removed. */
595 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
514 vfd->lock = &dev->v4l2_lock; 596 vfd->lock = &dev->v4l2_lock;
597 vfd->v4l2_dev = &dev->v4l2_dev;
515 vfd->tvnorms = 0; 598 vfd->tvnorms = 0;
599 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
516 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 600 for (i = 0; i < dev->ext_vv_data->num_stds; i++)
517 vfd->tvnorms |= dev->ext_vv_data->stds[i].id; 601 vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
518 strlcpy(vfd->name, name, sizeof(vfd->name)); 602 strlcpy(vfd->name, name, sizeof(vfd->name));
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index bc1f545c95cb..be746d1aee9a 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -343,9 +343,9 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
343 struct saa7146_vv *vv = dev->vv_data; 343 struct saa7146_vv *vv = dev->vv_data;
344 __le32 *clipping = vv->d_clipping.cpu_addr; 344 __le32 *clipping = vv->d_clipping.cpu_addr;
345 345
346 int width = fh->ov.win.w.width; 346 int width = vv->ov.win.w.width;
347 int height = fh->ov.win.w.height; 347 int height = vv->ov.win.w.height;
348 int clipcount = fh->ov.nclips; 348 int clipcount = vv->ov.nclips;
349 349
350 u32 line_list[32]; 350 u32 line_list[32];
351 u32 pixel_list[32]; 351 u32 pixel_list[32];
@@ -365,10 +365,10 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
365 for(i = 0; i < clipcount; i++) { 365 for(i = 0; i < clipcount; i++) {
366 int l = 0, r = 0, t = 0, b = 0; 366 int l = 0, r = 0, t = 0, b = 0;
367 367
368 x[i] = fh->ov.clips[i].c.left; 368 x[i] = vv->ov.clips[i].c.left;
369 y[i] = fh->ov.clips[i].c.top; 369 y[i] = vv->ov.clips[i].c.top;
370 w[i] = fh->ov.clips[i].c.width; 370 w[i] = vv->ov.clips[i].c.width;
371 h[i] = fh->ov.clips[i].c.height; 371 h[i] = vv->ov.clips[i].c.height;
372 372
373 if( w[i] < 0) { 373 if( w[i] < 0) {
374 x[i] += w[i]; w[i] = -w[i]; 374 x[i] += w[i]; w[i] = -w[i];
@@ -485,13 +485,14 @@ static void saa7146_disable_clipping(struct saa7146_dev *dev)
485static void saa7146_set_clipping_rect(struct saa7146_fh *fh) 485static void saa7146_set_clipping_rect(struct saa7146_fh *fh)
486{ 486{
487 struct saa7146_dev *dev = fh->dev; 487 struct saa7146_dev *dev = fh->dev;
488 enum v4l2_field field = fh->ov.win.field; 488 struct saa7146_vv *vv = dev->vv_data;
489 enum v4l2_field field = vv->ov.win.field;
489 struct saa7146_video_dma vdma2; 490 struct saa7146_video_dma vdma2;
490 u32 clip_format; 491 u32 clip_format;
491 u32 arbtr_ctrl; 492 u32 arbtr_ctrl;
492 493
493 /* check clipcount, disable clipping if clipcount == 0*/ 494 /* check clipcount, disable clipping if clipcount == 0*/
494 if( fh->ov.nclips == 0 ) { 495 if (vv->ov.nclips == 0) {
495 saa7146_disable_clipping(dev); 496 saa7146_disable_clipping(dev);
496 return; 497 return;
497 } 498 }
@@ -651,8 +652,8 @@ int saa7146_enable_overlay(struct saa7146_fh *fh)
651 struct saa7146_dev *dev = fh->dev; 652 struct saa7146_dev *dev = fh->dev;
652 struct saa7146_vv *vv = dev->vv_data; 653 struct saa7146_vv *vv = dev->vv_data;
653 654
654 saa7146_set_window(dev, fh->ov.win.w.width, fh->ov.win.w.height, fh->ov.win.field); 655 saa7146_set_window(dev, vv->ov.win.w.width, vv->ov.win.w.height, vv->ov.win.field);
655 saa7146_set_position(dev, fh->ov.win.w.left, fh->ov.win.w.top, fh->ov.win.w.height, fh->ov.win.field, vv->ov_fmt->pixelformat); 656 saa7146_set_position(dev, vv->ov.win.w.left, vv->ov.win.w.top, vv->ov.win.w.height, vv->ov.win.field, vv->ov_fmt->pixelformat);
656 saa7146_set_output_format(dev, vv->ov_fmt->trans); 657 saa7146_set_output_format(dev, vv->ov_fmt->trans);
657 saa7146_set_clipping_rect(fh); 658 saa7146_set_clipping_rect(fh);
658 659
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
index b2e718343739..1e71e374bbfe 100644
--- a/drivers/media/common/saa7146_vbi.c
+++ b/drivers/media/common/saa7146_vbi.c
@@ -211,7 +211,7 @@ static int buffer_activate(struct saa7146_dev *dev,
211 DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next); 211 DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
212 saa7146_set_vbi_capture(dev,buf,next); 212 saa7146_set_vbi_capture(dev,buf,next);
213 213
214 mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT); 214 mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
215 return 0; 215 return 0;
216} 216}
217 217
@@ -294,7 +294,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
294 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 294 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
295 295
296 DEB_VBI("vb:%p\n", vb); 296 DEB_VBI("vb:%p\n", vb);
297 saa7146_buffer_queue(dev,&vv->vbi_q,buf); 297 saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
298} 298}
299 299
300static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 300static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -335,16 +335,15 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file)
335 /* shut down dma 3 transfers */ 335 /* shut down dma 3 transfers */
336 saa7146_write(dev, MC1, MASK_20); 336 saa7146_write(dev, MC1, MASK_20);
337 337
338 if (vv->vbi_q.curr) { 338 if (vv->vbi_dmaq.curr)
339 saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE); 339 saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
340 }
341 340
342 videobuf_queue_cancel(&fh->vbi_q); 341 videobuf_queue_cancel(&fh->vbi_q);
343 342
344 vv->vbi_streaming = NULL; 343 vv->vbi_streaming = NULL;
345 344
346 del_timer(&vv->vbi_q.timeout); 345 del_timer(&vv->vbi_dmaq.timeout);
347 del_timer(&fh->vbi_read_timeout); 346 del_timer(&vv->vbi_read_timeout);
348 347
349 spin_unlock_irqrestore(&dev->slock, flags); 348 spin_unlock_irqrestore(&dev->slock, flags);
350} 349}
@@ -364,12 +363,12 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
364{ 363{
365 DEB_VBI("dev:%p\n", dev); 364 DEB_VBI("dev:%p\n", dev);
366 365
367 INIT_LIST_HEAD(&vv->vbi_q.queue); 366 INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
368 367
369 init_timer(&vv->vbi_q.timeout); 368 init_timer(&vv->vbi_dmaq.timeout);
370 vv->vbi_q.timeout.function = saa7146_buffer_timeout; 369 vv->vbi_dmaq.timeout.function = saa7146_buffer_timeout;
371 vv->vbi_q.timeout.data = (unsigned long)(&vv->vbi_q); 370 vv->vbi_dmaq.timeout.data = (unsigned long)(&vv->vbi_dmaq);
372 vv->vbi_q.dev = dev; 371 vv->vbi_dmaq.dev = dev;
373 372
374 init_waitqueue_head(&vv->vbi_wq); 373 init_waitqueue_head(&vv->vbi_wq);
375} 374}
@@ -377,6 +376,7 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
377static int vbi_open(struct saa7146_dev *dev, struct file *file) 376static int vbi_open(struct saa7146_dev *dev, struct file *file)
378{ 377{
379 struct saa7146_fh *fh = file->private_data; 378 struct saa7146_fh *fh = file->private_data;
379 struct saa7146_vv *vv = fh->dev->vv_data;
380 380
381 u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1); 381 u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
382 int ret = 0; 382 int ret = 0;
@@ -395,19 +395,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
395 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl); 395 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
396 saa7146_write(dev, MC2, (MASK_04|MASK_20)); 396 saa7146_write(dev, MC2, (MASK_04|MASK_20));
397 397
398 memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
399
400 fh->vbi_fmt.sampling_rate = 27000000;
401 fh->vbi_fmt.offset = 248; /* todo */
402 fh->vbi_fmt.samples_per_line = vbi_pixel_to_capture;
403 fh->vbi_fmt.sample_format = V4L2_PIX_FMT_GREY;
404
405 /* fixme: this only works for PAL */
406 fh->vbi_fmt.start[0] = 5;
407 fh->vbi_fmt.count[0] = 16;
408 fh->vbi_fmt.start[1] = 312;
409 fh->vbi_fmt.count[1] = 16;
410
411 videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops, 398 videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
412 &dev->pci->dev, &dev->slock, 399 &dev->pci->dev, &dev->slock,
413 V4L2_BUF_TYPE_VBI_CAPTURE, 400 V4L2_BUF_TYPE_VBI_CAPTURE,
@@ -415,9 +402,8 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
415 sizeof(struct saa7146_buf), 402 sizeof(struct saa7146_buf),
416 file, &dev->v4l2_lock); 403 file, &dev->v4l2_lock);
417 404
418 init_timer(&fh->vbi_read_timeout); 405 vv->vbi_read_timeout.function = vbi_read_timeout;
419 fh->vbi_read_timeout.function = vbi_read_timeout; 406 vv->vbi_read_timeout.data = (unsigned long)file;
420 fh->vbi_read_timeout.data = (unsigned long)file;
421 407
422 /* initialize the brs */ 408 /* initialize the brs */
423 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) { 409 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
@@ -453,16 +439,16 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
453 struct saa7146_vv *vv = dev->vv_data; 439 struct saa7146_vv *vv = dev->vv_data;
454 spin_lock(&dev->slock); 440 spin_lock(&dev->slock);
455 441
456 if (vv->vbi_q.curr) { 442 if (vv->vbi_dmaq.curr) {
457 DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_q.curr); 443 DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
458 /* this must be += 2, one count for each field */ 444 /* this must be += 2, one count for each field */
459 vv->vbi_fieldcount+=2; 445 vv->vbi_fieldcount+=2;
460 vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount; 446 vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
461 saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE); 447 saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
462 } else { 448 } else {
463 DEB_VBI("dev:%p\n", dev); 449 DEB_VBI("dev:%p\n", dev);
464 } 450 }
465 saa7146_buffer_next(dev,&vv->vbi_q,1); 451 saa7146_buffer_next(dev, &vv->vbi_dmaq, 1);
466 452
467 spin_unlock(&dev->slock); 453 spin_unlock(&dev->slock);
468} 454}
@@ -488,7 +474,7 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff
488 return -EBUSY; 474 return -EBUSY;
489 } 475 }
490 476
491 mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT); 477 mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
492 ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1, 478 ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
493 file->f_flags & O_NONBLOCK); 479 file->f_flags & O_NONBLOCK);
494/* 480/*
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index ce30533fd972..6d14785d4747 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -2,6 +2,8 @@
2 2
3#include <media/saa7146_vv.h> 3#include <media/saa7146_vv.h>
4#include <media/v4l2-chip-ident.h> 4#include <media/v4l2-chip-ident.h>
5#include <media/v4l2-event.h>
6#include <media/v4l2-ctrls.h>
5#include <linux/module.h> 7#include <linux/module.h>
6 8
7static int max_memory = 32; 9static int max_memory = 32;
@@ -112,8 +114,8 @@ int saa7146_start_preview(struct saa7146_fh *fh)
112 114
113 DEB_EE("dev:%p, fh:%p\n", dev, fh); 115 DEB_EE("dev:%p, fh:%p\n", dev, fh);
114 116
115 /* check if we have overlay informations */ 117 /* check if we have overlay information */
116 if( NULL == fh->ov.fh ) { 118 if (vv->ov.fh == NULL) {
117 DEB_D("no overlay data available. try S_FMT first.\n"); 119 DEB_D("no overlay data available. try S_FMT first.\n");
118 return -EAGAIN; 120 return -EAGAIN;
119 } 121 }
@@ -139,19 +141,18 @@ int saa7146_start_preview(struct saa7146_fh *fh)
139 return -EBUSY; 141 return -EBUSY;
140 } 142 }
141 143
142 fmt.fmt.win = fh->ov.win; 144 fmt.fmt.win = vv->ov.win;
143 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); 145 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
144 if (0 != err) { 146 if (0 != err) {
145 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 147 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
146 return -EBUSY; 148 return -EBUSY;
147 } 149 }
148 fh->ov.win = fmt.fmt.win; 150 vv->ov.win = fmt.fmt.win;
149 vv->ov_data = &fh->ov;
150 151
151 DEB_D("%dx%d+%d+%d %s field=%s\n", 152 DEB_D("%dx%d+%d+%d %s field=%s\n",
152 fh->ov.win.w.width, fh->ov.win.w.height, 153 vv->ov.win.w.width, vv->ov.win.w.height,
153 fh->ov.win.w.left, fh->ov.win.w.top, 154 vv->ov.win.w.left, vv->ov.win.w.top,
154 vv->ov_fmt->name, v4l2_field_names[fh->ov.win.field]); 155 vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]);
155 156
156 if (0 != (ret = saa7146_enable_overlay(fh))) { 157 if (0 != (ret = saa7146_enable_overlay(fh))) {
157 DEB_D("enabling overlay failed: %d\n", ret); 158 DEB_D("enabling overlay failed: %d\n", ret);
@@ -202,65 +203,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
202EXPORT_SYMBOL_GPL(saa7146_stop_preview); 203EXPORT_SYMBOL_GPL(saa7146_stop_preview);
203 204
204/********************************************************************************/ 205/********************************************************************************/
205/* device controls */
206
207static struct v4l2_queryctrl controls[] = {
208 {
209 .id = V4L2_CID_BRIGHTNESS,
210 .name = "Brightness",
211 .minimum = 0,
212 .maximum = 255,
213 .step = 1,
214 .default_value = 128,
215 .type = V4L2_CTRL_TYPE_INTEGER,
216 .flags = V4L2_CTRL_FLAG_SLIDER,
217 },{
218 .id = V4L2_CID_CONTRAST,
219 .name = "Contrast",
220 .minimum = 0,
221 .maximum = 127,
222 .step = 1,
223 .default_value = 64,
224 .type = V4L2_CTRL_TYPE_INTEGER,
225 .flags = V4L2_CTRL_FLAG_SLIDER,
226 },{
227 .id = V4L2_CID_SATURATION,
228 .name = "Saturation",
229 .minimum = 0,
230 .maximum = 127,
231 .step = 1,
232 .default_value = 64,
233 .type = V4L2_CTRL_TYPE_INTEGER,
234 .flags = V4L2_CTRL_FLAG_SLIDER,
235 },{
236 .id = V4L2_CID_VFLIP,
237 .name = "Vertical Flip",
238 .minimum = 0,
239 .maximum = 1,
240 .type = V4L2_CTRL_TYPE_BOOLEAN,
241 },{
242 .id = V4L2_CID_HFLIP,
243 .name = "Horizontal Flip",
244 .minimum = 0,
245 .maximum = 1,
246 .type = V4L2_CTRL_TYPE_BOOLEAN,
247 },
248};
249static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
250
251#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0)
252
253static struct v4l2_queryctrl* ctrl_by_id(int id)
254{
255 int i;
256
257 for (i = 0; i < NUM_CONTROLS; i++)
258 if (controls[i].id == id)
259 return controls+i;
260 return NULL;
261}
262
263/********************************************************************************/
264/* common pagetable functions */ 206/* common pagetable functions */
265 207
266static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) 208static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
@@ -413,7 +355,7 @@ static int video_begin(struct saa7146_fh *fh)
413 } 355 }
414 } 356 }
415 357
416 fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); 358 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
417 /* we need to have a valid format set here */ 359 /* we need to have a valid format set here */
418 BUG_ON(NULL == fmt); 360 BUG_ON(NULL == fmt);
419 361
@@ -465,7 +407,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
465 return -EBUSY; 407 return -EBUSY;
466 } 408 }
467 409
468 fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); 410 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
469 /* we need to have a valid format set here */ 411 /* we need to have a valid format set here */
470 BUG_ON(NULL == fmt); 412 BUG_ON(NULL == fmt);
471 413
@@ -504,18 +446,25 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
504 446
505static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 447static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
506{ 448{
449 struct video_device *vdev = video_devdata(file);
507 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 450 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
508 451
509 strcpy((char *)cap->driver, "saa7146 v4l2"); 452 strcpy((char *)cap->driver, "saa7146 v4l2");
510 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); 453 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
511 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); 454 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
512 cap->version = SAA7146_VERSION_CODE; 455 cap->device_caps =
513 cap->capabilities =
514 V4L2_CAP_VIDEO_CAPTURE | 456 V4L2_CAP_VIDEO_CAPTURE |
515 V4L2_CAP_VIDEO_OVERLAY | 457 V4L2_CAP_VIDEO_OVERLAY |
516 V4L2_CAP_READWRITE | 458 V4L2_CAP_READWRITE |
517 V4L2_CAP_STREAMING; 459 V4L2_CAP_STREAMING;
518 cap->capabilities |= dev->ext_vv_data->capabilities; 460 cap->device_caps |= dev->ext_vv_data->capabilities;
461 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
462 if (vdev->vfl_type == VFL_TYPE_GRABBER)
463 cap->device_caps &=
464 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
465 else
466 cap->device_caps &=
467 ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
519 return 0; 468 return 0;
520} 469}
521 470
@@ -526,6 +475,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
526 475
527 *fb = vv->ov_fb; 476 *fb = vv->ov_fb;
528 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; 477 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
478 fb->flags = V4L2_FBUF_FLAG_PRIMARY;
529 return 0; 479 return 0;
530} 480}
531 481
@@ -579,135 +529,58 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtd
579 return 0; 529 return 0;
580} 530}
581 531
582static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 532int saa7146_s_ctrl(struct v4l2_ctrl *ctrl)
583{ 533{
584 const struct v4l2_queryctrl *ctrl; 534 struct saa7146_dev *dev = container_of(ctrl->handler,
585 535 struct saa7146_dev, ctrl_handler);
586 if ((c->id < V4L2_CID_BASE ||
587 c->id >= V4L2_CID_LASTP1) &&
588 (c->id < V4L2_CID_PRIVATE_BASE ||
589 c->id >= V4L2_CID_PRIVATE_LASTP1))
590 return -EINVAL;
591
592 ctrl = ctrl_by_id(c->id);
593 if (ctrl == NULL)
594 return -EINVAL;
595
596 DEB_EE("VIDIOC_QUERYCTRL: id:%d\n", c->id);
597 *c = *ctrl;
598 return 0;
599}
600
601static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
602{
603 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
604 struct saa7146_vv *vv = dev->vv_data; 536 struct saa7146_vv *vv = dev->vv_data;
605 const struct v4l2_queryctrl *ctrl; 537 u32 val;
606 u32 value = 0;
607 538
608 ctrl = ctrl_by_id(c->id); 539 switch (ctrl->id) {
609 if (NULL == ctrl)
610 return -EINVAL;
611 switch (c->id) {
612 case V4L2_CID_BRIGHTNESS: 540 case V4L2_CID_BRIGHTNESS:
613 value = saa7146_read(dev, BCS_CTRL); 541 val = saa7146_read(dev, BCS_CTRL);
614 c->value = 0xff & (value >> 24); 542 val &= 0x00ffffff;
615 DEB_D("V4L2_CID_BRIGHTNESS: %d\n", c->value); 543 val |= (ctrl->val << 24);
616 break; 544 saa7146_write(dev, BCS_CTRL, val);
617 case V4L2_CID_CONTRAST:
618 value = saa7146_read(dev, BCS_CTRL);
619 c->value = 0x7f & (value >> 16);
620 DEB_D("V4L2_CID_CONTRAST: %d\n", c->value);
621 break;
622 case V4L2_CID_SATURATION:
623 value = saa7146_read(dev, BCS_CTRL);
624 c->value = 0x7f & (value >> 0);
625 DEB_D("V4L2_CID_SATURATION: %d\n", c->value);
626 break;
627 case V4L2_CID_VFLIP:
628 c->value = vv->vflip;
629 DEB_D("V4L2_CID_VFLIP: %d\n", c->value);
630 break;
631 case V4L2_CID_HFLIP:
632 c->value = vv->hflip;
633 DEB_D("V4L2_CID_HFLIP: %d\n", c->value);
634 break;
635 default:
636 return -EINVAL;
637 }
638 return 0;
639}
640
641static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
642{
643 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
644 struct saa7146_vv *vv = dev->vv_data;
645 const struct v4l2_queryctrl *ctrl;
646
647 ctrl = ctrl_by_id(c->id);
648 if (NULL == ctrl) {
649 DEB_D("unknown control %d\n", c->id);
650 return -EINVAL;
651 }
652
653 switch (ctrl->type) {
654 case V4L2_CTRL_TYPE_BOOLEAN:
655 case V4L2_CTRL_TYPE_MENU:
656 case V4L2_CTRL_TYPE_INTEGER:
657 if (c->value < ctrl->minimum)
658 c->value = ctrl->minimum;
659 if (c->value > ctrl->maximum)
660 c->value = ctrl->maximum;
661 break;
662 default:
663 /* nothing */;
664 }
665
666 switch (c->id) {
667 case V4L2_CID_BRIGHTNESS: {
668 u32 value = saa7146_read(dev, BCS_CTRL);
669 value &= 0x00ffffff;
670 value |= (c->value << 24);
671 saa7146_write(dev, BCS_CTRL, value);
672 saa7146_write(dev, MC2, MASK_22 | MASK_06); 545 saa7146_write(dev, MC2, MASK_22 | MASK_06);
673 break; 546 break;
674 } 547
675 case V4L2_CID_CONTRAST: { 548 case V4L2_CID_CONTRAST:
676 u32 value = saa7146_read(dev, BCS_CTRL); 549 val = saa7146_read(dev, BCS_CTRL);
677 value &= 0xff00ffff; 550 val &= 0xff00ffff;
678 value |= (c->value << 16); 551 val |= (ctrl->val << 16);
679 saa7146_write(dev, BCS_CTRL, value); 552 saa7146_write(dev, BCS_CTRL, val);
680 saa7146_write(dev, MC2, MASK_22 | MASK_06); 553 saa7146_write(dev, MC2, MASK_22 | MASK_06);
681 break; 554 break;
682 } 555
683 case V4L2_CID_SATURATION: { 556 case V4L2_CID_SATURATION:
684 u32 value = saa7146_read(dev, BCS_CTRL); 557 val = saa7146_read(dev, BCS_CTRL);
685 value &= 0xffffff00; 558 val &= 0xffffff00;
686 value |= (c->value << 0); 559 val |= (ctrl->val << 0);
687 saa7146_write(dev, BCS_CTRL, value); 560 saa7146_write(dev, BCS_CTRL, val);
688 saa7146_write(dev, MC2, MASK_22 | MASK_06); 561 saa7146_write(dev, MC2, MASK_22 | MASK_06);
689 break; 562 break;
690 } 563
691 case V4L2_CID_HFLIP: 564 case V4L2_CID_HFLIP:
692 /* fixme: we can support changing VFLIP and HFLIP here... */ 565 /* fixme: we can support changing VFLIP and HFLIP here... */
693 if (IS_CAPTURE_ACTIVE(fh) != 0) { 566 if ((vv->video_status & STATUS_CAPTURE))
694 DEB_D("V4L2_CID_HFLIP while active capture\n");
695 return -EBUSY; 567 return -EBUSY;
696 } 568 vv->hflip = ctrl->val;
697 vv->hflip = c->value;
698 break; 569 break;
570
699 case V4L2_CID_VFLIP: 571 case V4L2_CID_VFLIP:
700 if (IS_CAPTURE_ACTIVE(fh) != 0) { 572 if ((vv->video_status & STATUS_CAPTURE))
701 DEB_D("V4L2_CID_VFLIP while active capture\n");
702 return -EBUSY; 573 return -EBUSY;
703 } 574 vv->vflip = ctrl->val;
704 vv->vflip = c->value;
705 break; 575 break;
576
706 default: 577 default:
707 return -EINVAL; 578 return -EINVAL;
708 } 579 }
709 580
710 if (IS_OVERLAY_ACTIVE(fh) != 0) { 581 if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
582 struct saa7146_fh *fh = vv->video_fh;
583
711 saa7146_stop_preview(fh); 584 saa7146_stop_preview(fh);
712 saa7146_start_preview(fh); 585 saa7146_start_preview(fh);
713 } 586 }
@@ -720,6 +593,8 @@ static int vidioc_g_parm(struct file *file, void *fh,
720 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 593 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
721 struct saa7146_vv *vv = dev->vv_data; 594 struct saa7146_vv *vv = dev->vv_data;
722 595
596 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
597 return -EINVAL;
723 parm->parm.capture.readbuffers = 1; 598 parm->parm.capture.readbuffers = 1;
724 v4l2_video_std_frame_period(vv->standard->id, 599 v4l2_video_std_frame_period(vv->standard->id,
725 &parm->parm.capture.timeperframe); 600 &parm->parm.capture.timeperframe);
@@ -728,19 +603,28 @@ static int vidioc_g_parm(struct file *file, void *fh,
728 603
729static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 604static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
730{ 605{
731 f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt; 606 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
607 struct saa7146_vv *vv = dev->vv_data;
608
609 f->fmt.pix = vv->video_fmt;
732 return 0; 610 return 0;
733} 611}
734 612
735static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) 613static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
736{ 614{
737 f->fmt.win = ((struct saa7146_fh *)fh)->ov.win; 615 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
616 struct saa7146_vv *vv = dev->vv_data;
617
618 f->fmt.win = vv->ov.win;
738 return 0; 619 return 0;
739} 620}
740 621
741static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) 622static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
742{ 623{
743 f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt; 624 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
625 struct saa7146_vv *vv = dev->vv_data;
626
627 f->fmt.vbi = vv->vbi_fmt;
744 return 0; 628 return 0;
745} 629}
746 630
@@ -787,6 +671,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
787 } 671 }
788 672
789 f->fmt.pix.field = field; 673 f->fmt.pix.field = field;
674 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
790 if (f->fmt.pix.width > maxw) 675 if (f->fmt.pix.width > maxw)
791 f->fmt.pix.width = maxw; 676 f->fmt.pix.width = maxw;
792 if (f->fmt.pix.height > maxh) 677 if (f->fmt.pix.height > maxh)
@@ -883,9 +768,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_forma
883 err = vidioc_try_fmt_vid_cap(file, fh, f); 768 err = vidioc_try_fmt_vid_cap(file, fh, f);
884 if (0 != err) 769 if (0 != err)
885 return err; 770 return err;
886 fh->video_fmt = f->fmt.pix; 771 vv->video_fmt = f->fmt.pix;
887 DEB_EE("set to pixelformat '%4.4s'\n", 772 DEB_EE("set to pixelformat '%4.4s'\n",
888 (char *)&fh->video_fmt.pixelformat); 773 (char *)&vv->video_fmt.pixelformat);
889 return 0; 774 return 0;
890} 775}
891 776
@@ -900,17 +785,17 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f
900 err = vidioc_try_fmt_vid_overlay(file, fh, f); 785 err = vidioc_try_fmt_vid_overlay(file, fh, f);
901 if (0 != err) 786 if (0 != err)
902 return err; 787 return err;
903 fh->ov.win = f->fmt.win; 788 vv->ov.win = f->fmt.win;
904 fh->ov.nclips = f->fmt.win.clipcount; 789 vv->ov.nclips = f->fmt.win.clipcount;
905 if (fh->ov.nclips > 16) 790 if (vv->ov.nclips > 16)
906 fh->ov.nclips = 16; 791 vv->ov.nclips = 16;
907 if (copy_from_user(fh->ov.clips, f->fmt.win.clips, 792 if (copy_from_user(vv->ov.clips, f->fmt.win.clips,
908 sizeof(struct v4l2_clip) * fh->ov.nclips)) { 793 sizeof(struct v4l2_clip) * vv->ov.nclips)) {
909 return -EFAULT; 794 return -EFAULT;
910 } 795 }
911 796
912 /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ 797 /* vv->ov.fh is used to indicate that we have valid overlay informations, too */
913 fh->ov.fh = fh; 798 vv->ov.fh = fh;
914 799
915 /* check if our current overlay is active */ 800 /* check if our current overlay is active */
916 if (IS_OVERLAY_ACTIVE(fh) != 0) { 801 if (IS_OVERLAY_ACTIVE(fh) != 0) {
@@ -1111,10 +996,14 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh,
1111 996
1112 chip->ident = V4L2_IDENT_NONE; 997 chip->ident = V4L2_IDENT_NONE;
1113 chip->revision = 0; 998 chip->revision = 0;
1114 if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { 999 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
1115 chip->ident = V4L2_IDENT_SAA7146; 1000 if (v4l2_chip_match_host(&chip->match))
1001 chip->ident = V4L2_IDENT_SAA7146;
1116 return 0; 1002 return 0;
1117 } 1003 }
1004 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
1005 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
1006 return -EINVAL;
1118 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, 1007 return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1119 core, g_chip_ident, chip); 1008 core, g_chip_ident, chip);
1120} 1009}
@@ -1129,7 +1018,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1129 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, 1018 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
1130 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, 1019 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
1131 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, 1020 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
1132 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1133 .vidioc_g_chip_ident = vidioc_g_chip_ident, 1021 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1134 1022
1135 .vidioc_overlay = vidioc_overlay, 1023 .vidioc_overlay = vidioc_overlay,
@@ -1141,12 +1029,29 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1141 .vidioc_dqbuf = vidioc_dqbuf, 1029 .vidioc_dqbuf = vidioc_dqbuf,
1142 .vidioc_g_std = vidioc_g_std, 1030 .vidioc_g_std = vidioc_g_std,
1143 .vidioc_s_std = vidioc_s_std, 1031 .vidioc_s_std = vidioc_s_std,
1144 .vidioc_queryctrl = vidioc_queryctrl,
1145 .vidioc_g_ctrl = vidioc_g_ctrl,
1146 .vidioc_s_ctrl = vidioc_s_ctrl,
1147 .vidioc_streamon = vidioc_streamon, 1032 .vidioc_streamon = vidioc_streamon,
1148 .vidioc_streamoff = vidioc_streamoff, 1033 .vidioc_streamoff = vidioc_streamoff,
1149 .vidioc_g_parm = vidioc_g_parm, 1034 .vidioc_g_parm = vidioc_g_parm,
1035 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1036 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1037};
1038
1039const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
1040 .vidioc_querycap = vidioc_querycap,
1041 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1042 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1043
1044 .vidioc_reqbufs = vidioc_reqbufs,
1045 .vidioc_querybuf = vidioc_querybuf,
1046 .vidioc_qbuf = vidioc_qbuf,
1047 .vidioc_dqbuf = vidioc_dqbuf,
1048 .vidioc_g_std = vidioc_g_std,
1049 .vidioc_s_std = vidioc_s_std,
1050 .vidioc_streamon = vidioc_streamon,
1051 .vidioc_streamoff = vidioc_streamoff,
1052 .vidioc_g_parm = vidioc_g_parm,
1053 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1054 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1150}; 1055};
1151 1056
1152/*********************************************************************************/ 1057/*********************************************************************************/
@@ -1161,7 +1066,7 @@ static int buffer_activate (struct saa7146_dev *dev,
1161 buf->vb.state = VIDEOBUF_ACTIVE; 1066 buf->vb.state = VIDEOBUF_ACTIVE;
1162 saa7146_set_capture(dev,buf,next); 1067 saa7146_set_capture(dev,buf,next);
1163 1068
1164 mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT); 1069 mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
1165 return 0; 1070 return 0;
1166} 1071}
1167 1072
@@ -1185,44 +1090,44 @@ static int buffer_prepare(struct videobuf_queue *q,
1185 DEB_CAP("vbuf:%p\n", vb); 1090 DEB_CAP("vbuf:%p\n", vb);
1186 1091
1187 /* sanity checks */ 1092 /* sanity checks */
1188 if (fh->video_fmt.width < 48 || 1093 if (vv->video_fmt.width < 48 ||
1189 fh->video_fmt.height < 32 || 1094 vv->video_fmt.height < 32 ||
1190 fh->video_fmt.width > vv->standard->h_max_out || 1095 vv->video_fmt.width > vv->standard->h_max_out ||
1191 fh->video_fmt.height > vv->standard->v_max_out) { 1096 vv->video_fmt.height > vv->standard->v_max_out) {
1192 DEB_D("w (%d) / h (%d) out of bounds\n", 1097 DEB_D("w (%d) / h (%d) out of bounds\n",
1193 fh->video_fmt.width, fh->video_fmt.height); 1098 vv->video_fmt.width, vv->video_fmt.height);
1194 return -EINVAL; 1099 return -EINVAL;
1195 } 1100 }
1196 1101
1197 size = fh->video_fmt.sizeimage; 1102 size = vv->video_fmt.sizeimage;
1198 if (0 != buf->vb.baddr && buf->vb.bsize < size) { 1103 if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1199 DEB_D("size mismatch\n"); 1104 DEB_D("size mismatch\n");
1200 return -EINVAL; 1105 return -EINVAL;
1201 } 1106 }
1202 1107
1203 DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n", 1108 DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1204 fh->video_fmt.width, fh->video_fmt.height, 1109 vv->video_fmt.width, vv->video_fmt.height,
1205 size, v4l2_field_names[fh->video_fmt.field]); 1110 size, v4l2_field_names[vv->video_fmt.field]);
1206 if (buf->vb.width != fh->video_fmt.width || 1111 if (buf->vb.width != vv->video_fmt.width ||
1207 buf->vb.bytesperline != fh->video_fmt.bytesperline || 1112 buf->vb.bytesperline != vv->video_fmt.bytesperline ||
1208 buf->vb.height != fh->video_fmt.height || 1113 buf->vb.height != vv->video_fmt.height ||
1209 buf->vb.size != size || 1114 buf->vb.size != size ||
1210 buf->vb.field != field || 1115 buf->vb.field != field ||
1211 buf->vb.field != fh->video_fmt.field || 1116 buf->vb.field != vv->video_fmt.field ||
1212 buf->fmt != &fh->video_fmt) { 1117 buf->fmt != &vv->video_fmt) {
1213 saa7146_dma_free(dev,q,buf); 1118 saa7146_dma_free(dev,q,buf);
1214 } 1119 }
1215 1120
1216 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 1121 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
1217 struct saa7146_format *sfmt; 1122 struct saa7146_format *sfmt;
1218 1123
1219 buf->vb.bytesperline = fh->video_fmt.bytesperline; 1124 buf->vb.bytesperline = vv->video_fmt.bytesperline;
1220 buf->vb.width = fh->video_fmt.width; 1125 buf->vb.width = vv->video_fmt.width;
1221 buf->vb.height = fh->video_fmt.height; 1126 buf->vb.height = vv->video_fmt.height;
1222 buf->vb.size = size; 1127 buf->vb.size = size;
1223 buf->vb.field = field; 1128 buf->vb.field = field;
1224 buf->fmt = &fh->video_fmt; 1129 buf->fmt = &vv->video_fmt;
1225 buf->vb.field = fh->video_fmt.field; 1130 buf->vb.field = vv->video_fmt.field;
1226 1131
1227 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); 1132 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1228 1133
@@ -1258,11 +1163,12 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned
1258{ 1163{
1259 struct file *file = q->priv_data; 1164 struct file *file = q->priv_data;
1260 struct saa7146_fh *fh = file->private_data; 1165 struct saa7146_fh *fh = file->private_data;
1166 struct saa7146_vv *vv = fh->dev->vv_data;
1261 1167
1262 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS) 1168 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1263 *count = MAX_SAA7146_CAPTURE_BUFFERS; 1169 *count = MAX_SAA7146_CAPTURE_BUFFERS;
1264 1170
1265 *size = fh->video_fmt.sizeimage; 1171 *size = vv->video_fmt.sizeimage;
1266 1172
1267 /* check if we exceed the "max_memory" parameter */ 1173 /* check if we exceed the "max_memory" parameter */
1268 if( (*count * *size) > (max_memory*1048576) ) { 1174 if( (*count * *size) > (max_memory*1048576) ) {
@@ -1283,7 +1189,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1283 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1189 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1284 1190
1285 DEB_CAP("vbuf:%p\n", vb); 1191 DEB_CAP("vbuf:%p\n", vb);
1286 saa7146_buffer_queue(fh->dev,&vv->video_q,buf); 1192 saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf);
1287} 1193}
1288 1194
1289static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 1195static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -1312,12 +1218,12 @@ static struct videobuf_queue_ops video_qops = {
1312 1218
1313static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) 1219static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1314{ 1220{
1315 INIT_LIST_HEAD(&vv->video_q.queue); 1221 INIT_LIST_HEAD(&vv->video_dmaq.queue);
1316 1222
1317 init_timer(&vv->video_q.timeout); 1223 init_timer(&vv->video_dmaq.timeout);
1318 vv->video_q.timeout.function = saa7146_buffer_timeout; 1224 vv->video_dmaq.timeout.function = saa7146_buffer_timeout;
1319 vv->video_q.timeout.data = (unsigned long)(&vv->video_q); 1225 vv->video_dmaq.timeout.data = (unsigned long)(&vv->video_dmaq);
1320 vv->video_q.dev = dev; 1226 vv->video_dmaq.dev = dev;
1321 1227
1322 /* set some default values */ 1228 /* set some default values */
1323 vv->standard = &dev->ext_vv_data->stds[0]; 1229 vv->standard = &dev->ext_vv_data->stds[0];
@@ -1331,15 +1237,6 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1331static int video_open(struct saa7146_dev *dev, struct file *file) 1237static int video_open(struct saa7146_dev *dev, struct file *file)
1332{ 1238{
1333 struct saa7146_fh *fh = file->private_data; 1239 struct saa7146_fh *fh = file->private_data;
1334 struct saa7146_format *sfmt;
1335
1336 fh->video_fmt.width = 384;
1337 fh->video_fmt.height = 288;
1338 fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
1339 fh->video_fmt.bytesperline = 0;
1340 fh->video_fmt.field = V4L2_FIELD_ANY;
1341 sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
1342 fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
1343 1240
1344 videobuf_queue_sg_init(&fh->video_q, &video_qops, 1241 videobuf_queue_sg_init(&fh->video_q, &video_qops,
1345 &dev->pci->dev, &dev->slock, 1242 &dev->pci->dev, &dev->slock,
@@ -1371,7 +1268,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
1371static void video_irq_done(struct saa7146_dev *dev, unsigned long st) 1268static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1372{ 1269{
1373 struct saa7146_vv *vv = dev->vv_data; 1270 struct saa7146_vv *vv = dev->vv_data;
1374 struct saa7146_dmaqueue *q = &vv->video_q; 1271 struct saa7146_dmaqueue *q = &vv->video_dmaq;
1375 1272
1376 spin_lock(&dev->slock); 1273 spin_lock(&dev->slock);
1377 DEB_CAP("called\n"); 1274 DEB_CAP("called\n");
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 4a6d5cef3964..bbf4945149a9 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -204,6 +204,27 @@ config MEDIA_TUNER_TDA18218
204 help 204 help
205 NXP TDA18218 silicon tuner driver. 205 NXP TDA18218 silicon tuner driver.
206 206
207config MEDIA_TUNER_FC0011
208 tristate "Fitipower FC0011 silicon tuner"
209 depends on VIDEO_MEDIA && I2C
210 default m if MEDIA_TUNER_CUSTOMISE
211 help
212 Fitipower FC0011 silicon tuner driver.
213
214config MEDIA_TUNER_FC0012
215 tristate "Fitipower FC0012 silicon tuner"
216 depends on VIDEO_MEDIA && I2C
217 default m if MEDIA_TUNER_CUSTOMISE
218 help
219 Fitipower FC0012 silicon tuner driver.
220
221config MEDIA_TUNER_FC0013
222 tristate "Fitipower FC0013 silicon tuner"
223 depends on VIDEO_MEDIA && I2C
224 default m if MEDIA_TUNER_CUSTOMISE
225 help
226 Fitipower FC0013 silicon tuner driver.
227
207config MEDIA_TUNER_TDA18212 228config MEDIA_TUNER_TDA18212
208 tristate "NXP TDA18212 silicon tuner" 229 tristate "NXP TDA18212 silicon tuner"
209 depends on VIDEO_MEDIA && I2C 230 depends on VIDEO_MEDIA && I2C
@@ -211,4 +232,10 @@ config MEDIA_TUNER_TDA18212
211 help 232 help
212 NXP TDA18212 silicon tuner driver. 233 NXP TDA18212 silicon tuner driver.
213 234
235config MEDIA_TUNER_TUA9001
236 tristate "Infineon TUA 9001 silicon tuner"
237 depends on VIDEO_MEDIA && I2C
238 default m if MEDIA_TUNER_CUSTOMISE
239 help
240 Infineon TUA 9001 silicon tuner driver.
214endmenu 241endmenu
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index f80407eb8998..891b80e60808 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -28,6 +28,10 @@ obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
28obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o 28obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
29obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o 29obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
30obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o 30obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
31obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
32obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
33obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
34obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
31 35
32ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 36ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
33ccflags-y += -I$(srctree)/drivers/media/dvb/frontends 37ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/fc0011.c b/drivers/media/common/tuners/fc0011.c
new file mode 100644
index 000000000000..e4882546c283
--- /dev/null
+++ b/drivers/media/common/tuners/fc0011.c
@@ -0,0 +1,524 @@
1/*
2 * Fitipower FC0011 tuner driver
3 *
4 * Copyright (C) 2012 Michael Buesch <m@bues.ch>
5 *
6 * Derived from FC0012 tuner driver:
7 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "fc0011.h"
25
26
27/* Tuner registers */
28enum {
29 FC11_REG_0,
30 FC11_REG_FA, /* FA */
31 FC11_REG_FP, /* FP */
32 FC11_REG_XINHI, /* XIN high 8 bit */
33 FC11_REG_XINLO, /* XIN low 8 bit */
34 FC11_REG_VCO, /* VCO */
35 FC11_REG_VCOSEL, /* VCO select */
36 FC11_REG_7, /* Unknown tuner reg 7 */
37 FC11_REG_8, /* Unknown tuner reg 8 */
38 FC11_REG_9,
39 FC11_REG_10, /* Unknown tuner reg 10 */
40 FC11_REG_11, /* Unknown tuner reg 11 */
41 FC11_REG_12,
42 FC11_REG_RCCAL, /* RC calibrate */
43 FC11_REG_VCOCAL, /* VCO calibrate */
44 FC11_REG_15,
45 FC11_REG_16, /* Unknown tuner reg 16 */
46 FC11_REG_17,
47
48 FC11_NR_REGS, /* Number of registers */
49};
50
51enum FC11_REG_VCOSEL_bits {
52 FC11_VCOSEL_2 = 0x08, /* VCO select 2 */
53 FC11_VCOSEL_1 = 0x10, /* VCO select 1 */
54 FC11_VCOSEL_CLKOUT = 0x20, /* Fix clock out */
55 FC11_VCOSEL_BW7M = 0x40, /* 7MHz bw */
56 FC11_VCOSEL_BW6M = 0x80, /* 6MHz bw */
57};
58
59enum FC11_REG_RCCAL_bits {
60 FC11_RCCAL_FORCE = 0x10, /* force */
61};
62
63enum FC11_REG_VCOCAL_bits {
64 FC11_VCOCAL_RUN = 0, /* VCO calibration run */
65 FC11_VCOCAL_VALUEMASK = 0x3F, /* VCO calibration value mask */
66 FC11_VCOCAL_OK = 0x40, /* VCO calibration Ok */
67 FC11_VCOCAL_RESET = 0x80, /* VCO calibration reset */
68};
69
70
71struct fc0011_priv {
72 struct i2c_adapter *i2c;
73 u8 addr;
74
75 u32 frequency;
76 u32 bandwidth;
77};
78
79
80static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
81{
82 u8 buf[2] = { reg, val };
83 struct i2c_msg msg = { .addr = priv->addr,
84 .flags = 0, .buf = buf, .len = 2 };
85
86 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
87 dev_err(&priv->i2c->dev,
88 "I2C write reg failed, reg: %02x, val: %02x\n",
89 reg, val);
90 return -EIO;
91 }
92
93 return 0;
94}
95
96static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
97{
98 u8 dummy;
99 struct i2c_msg msg[2] = {
100 { .addr = priv->addr,
101 .flags = 0, .buf = &reg, .len = 1 },
102 { .addr = priv->addr,
103 .flags = I2C_M_RD, .buf = val ? : &dummy, .len = 1 },
104 };
105
106 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
107 dev_err(&priv->i2c->dev,
108 "I2C read failed, reg: %02x\n", reg);
109 return -EIO;
110 }
111
112 return 0;
113}
114
115static int fc0011_release(struct dvb_frontend *fe)
116{
117 kfree(fe->tuner_priv);
118 fe->tuner_priv = NULL;
119
120 return 0;
121}
122
123static int fc0011_init(struct dvb_frontend *fe)
124{
125 struct fc0011_priv *priv = fe->tuner_priv;
126 int err;
127
128 if (WARN_ON(!fe->callback))
129 return -EINVAL;
130
131 err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
132 FC0011_FE_CALLBACK_POWER, priv->addr);
133 if (err) {
134 dev_err(&priv->i2c->dev, "Power-on callback failed\n");
135 return err;
136 }
137 err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
138 FC0011_FE_CALLBACK_RESET, priv->addr);
139 if (err) {
140 dev_err(&priv->i2c->dev, "Reset callback failed\n");
141 return err;
142 }
143
144 return 0;
145}
146
147/* Initiate VCO calibration */
148static int fc0011_vcocal_trigger(struct fc0011_priv *priv)
149{
150 int err;
151
152 err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
153 if (err)
154 return err;
155 err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
156 if (err)
157 return err;
158
159 return 0;
160}
161
162/* Read VCO calibration value */
163static int fc0011_vcocal_read(struct fc0011_priv *priv, u8 *value)
164{
165 int err;
166
167 err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
168 if (err)
169 return err;
170 usleep_range(10000, 20000);
171 err = fc0011_readreg(priv, FC11_REG_VCOCAL, value);
172 if (err)
173 return err;
174
175 return 0;
176}
177
178static int fc0011_set_params(struct dvb_frontend *fe)
179{
180 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
181 struct fc0011_priv *priv = fe->tuner_priv;
182 int err;
183 unsigned int i, vco_retries;
184 u32 freq = p->frequency / 1000;
185 u32 bandwidth = p->bandwidth_hz / 1000;
186 u32 fvco, xin, xdiv, xdivr;
187 u16 frac;
188 u8 fa, fp, vco_sel, vco_cal;
189 u8 regs[FC11_NR_REGS] = { };
190
191 regs[FC11_REG_7] = 0x0F;
192 regs[FC11_REG_8] = 0x3E;
193 regs[FC11_REG_10] = 0xB8;
194 regs[FC11_REG_11] = 0x80;
195 regs[FC11_REG_RCCAL] = 0x04;
196 err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
197 err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
198 err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
199 err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
200 err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
201 if (err)
202 return -EIO;
203
204 /* Set VCO freq and VCO div */
205 if (freq < 54000) {
206 fvco = freq * 64;
207 regs[FC11_REG_VCO] = 0x82;
208 } else if (freq < 108000) {
209 fvco = freq * 32;
210 regs[FC11_REG_VCO] = 0x42;
211 } else if (freq < 216000) {
212 fvco = freq * 16;
213 regs[FC11_REG_VCO] = 0x22;
214 } else if (freq < 432000) {
215 fvco = freq * 8;
216 regs[FC11_REG_VCO] = 0x12;
217 } else {
218 fvco = freq * 4;
219 regs[FC11_REG_VCO] = 0x0A;
220 }
221
222 /* Calc XIN. The PLL reference frequency is 18 MHz. */
223 xdiv = fvco / 18000;
224 frac = fvco - xdiv * 18000;
225 frac = (frac << 15) / 18000;
226 if (frac >= 16384)
227 frac += 32786;
228 if (!frac)
229 xin = 0;
230 else if (frac < 511)
231 xin = 512;
232 else if (frac < 65026)
233 xin = frac;
234 else
235 xin = 65024;
236 regs[FC11_REG_XINHI] = xin >> 8;
237 regs[FC11_REG_XINLO] = xin;
238
239 /* Calc FP and FA */
240 xdivr = xdiv;
241 if (fvco - xdiv * 18000 >= 9000)
242 xdivr += 1; /* round */
243 fp = xdivr / 8;
244 fa = xdivr - fp * 8;
245 if (fa < 2) {
246 fp -= 1;
247 fa += 8;
248 }
249 if (fp > 0x1F) {
250 fp &= 0x1F;
251 fa &= 0xF;
252 }
253 if (fa >= fp) {
254 dev_warn(&priv->i2c->dev,
255 "fa %02X >= fp %02X, but trying to continue\n",
256 (unsigned int)(u8)fa, (unsigned int)(u8)fp);
257 }
258 regs[FC11_REG_FA] = fa;
259 regs[FC11_REG_FP] = fp;
260
261 /* Select bandwidth */
262 switch (bandwidth) {
263 case 8000:
264 break;
265 case 7000:
266 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
267 break;
268 default:
269 dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. "
270 "Using 6000 kHz.\n",
271 bandwidth);
272 bandwidth = 6000;
273 /* fallthrough */
274 case 6000:
275 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
276 break;
277 }
278
279 /* Pre VCO select */
280 if (fvco < 2320000) {
281 vco_sel = 0;
282 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
283 } else if (fvco < 3080000) {
284 vco_sel = 1;
285 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
286 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
287 } else {
288 vco_sel = 2;
289 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
290 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
291 }
292
293 /* Fix for low freqs */
294 if (freq < 45000) {
295 regs[FC11_REG_FA] = 0x6;
296 regs[FC11_REG_FP] = 0x11;
297 }
298
299 /* Clock out fix */
300 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;
301
302 /* Write the cached registers */
303 for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
304 err = fc0011_writereg(priv, i, regs[i]);
305 if (err)
306 return err;
307 }
308
309 /* VCO calibration */
310 err = fc0011_vcocal_trigger(priv);
311 if (err)
312 return err;
313 err = fc0011_vcocal_read(priv, &vco_cal);
314 if (err)
315 return err;
316 vco_retries = 0;
317 while (!(vco_cal & FC11_VCOCAL_OK) && vco_retries < 3) {
318 /* Reset the tuner and try again */
319 err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
320 FC0011_FE_CALLBACK_RESET, priv->addr);
321 if (err) {
322 dev_err(&priv->i2c->dev, "Failed to reset tuner\n");
323 return err;
324 }
325 /* Reinit tuner config */
326 err = 0;
327 for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
328 err |= fc0011_writereg(priv, i, regs[i]);
329 err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
330 err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
331 err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
332 err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
333 err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
334 if (err)
335 return -EIO;
336 /* VCO calibration */
337 err = fc0011_vcocal_trigger(priv);
338 if (err)
339 return err;
340 err = fc0011_vcocal_read(priv, &vco_cal);
341 if (err)
342 return err;
343 vco_retries++;
344 }
345 if (!(vco_cal & FC11_VCOCAL_OK)) {
346 dev_err(&priv->i2c->dev,
347 "Failed to read VCO calibration value (got %02X)\n",
348 (unsigned int)vco_cal);
349 return -EIO;
350 }
351 vco_cal &= FC11_VCOCAL_VALUEMASK;
352
353 switch (vco_sel) {
354 case 0:
355 if (vco_cal < 8) {
356 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
357 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
358 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
359 regs[FC11_REG_VCOSEL]);
360 if (err)
361 return err;
362 err = fc0011_vcocal_trigger(priv);
363 if (err)
364 return err;
365 } else {
366 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
367 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
368 regs[FC11_REG_VCOSEL]);
369 if (err)
370 return err;
371 }
372 break;
373 case 1:
374 if (vco_cal < 5) {
375 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
376 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
377 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
378 regs[FC11_REG_VCOSEL]);
379 if (err)
380 return err;
381 err = fc0011_vcocal_trigger(priv);
382 if (err)
383 return err;
384 } else if (vco_cal <= 48) {
385 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
386 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
387 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
388 regs[FC11_REG_VCOSEL]);
389 if (err)
390 return err;
391 } else {
392 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
393 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
394 regs[FC11_REG_VCOSEL]);
395 if (err)
396 return err;
397 err = fc0011_vcocal_trigger(priv);
398 if (err)
399 return err;
400 }
401 break;
402 case 2:
403 if (vco_cal > 53) {
404 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
405 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
406 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
407 regs[FC11_REG_VCOSEL]);
408 if (err)
409 return err;
410 err = fc0011_vcocal_trigger(priv);
411 if (err)
412 return err;
413 } else {
414 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
415 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
416 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
417 regs[FC11_REG_VCOSEL]);
418 if (err)
419 return err;
420 }
421 break;
422 }
423 err = fc0011_vcocal_read(priv, NULL);
424 if (err)
425 return err;
426 usleep_range(10000, 50000);
427
428 err = fc0011_readreg(priv, FC11_REG_RCCAL, &regs[FC11_REG_RCCAL]);
429 if (err)
430 return err;
431 regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
432 err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
433 if (err)
434 return err;
435 err = fc0011_writereg(priv, FC11_REG_16, 0xB);
436 if (err)
437 return err;
438
439 dev_dbg(&priv->i2c->dev, "Tuned to "
440 "fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X "
441 "vcocal=%02X(%u) bw=%u\n",
442 (unsigned int)regs[FC11_REG_FA],
443 (unsigned int)regs[FC11_REG_FP],
444 (unsigned int)regs[FC11_REG_XINHI],
445 (unsigned int)regs[FC11_REG_XINLO],
446 (unsigned int)regs[FC11_REG_VCO],
447 (unsigned int)regs[FC11_REG_VCOSEL],
448 (unsigned int)vco_cal, vco_retries,
449 (unsigned int)bandwidth);
450
451 priv->frequency = p->frequency;
452 priv->bandwidth = p->bandwidth_hz;
453
454 return 0;
455}
456
457static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
458{
459 struct fc0011_priv *priv = fe->tuner_priv;
460
461 *frequency = priv->frequency;
462
463 return 0;
464}
465
466static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
467{
468 *frequency = 0;
469
470 return 0;
471}
472
473static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
474{
475 struct fc0011_priv *priv = fe->tuner_priv;
476
477 *bandwidth = priv->bandwidth;
478
479 return 0;
480}
481
482static const struct dvb_tuner_ops fc0011_tuner_ops = {
483 .info = {
484 .name = "Fitipower FC0011",
485
486 .frequency_min = 45000000,
487 .frequency_max = 1000000000,
488 },
489
490 .release = fc0011_release,
491 .init = fc0011_init,
492
493 .set_params = fc0011_set_params,
494
495 .get_frequency = fc0011_get_frequency,
496 .get_if_frequency = fc0011_get_if_frequency,
497 .get_bandwidth = fc0011_get_bandwidth,
498};
499
500struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
501 struct i2c_adapter *i2c,
502 const struct fc0011_config *config)
503{
504 struct fc0011_priv *priv;
505
506 priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
507 if (!priv)
508 return NULL;
509
510 priv->i2c = i2c;
511 priv->addr = config->i2c_address;
512
513 fe->tuner_priv = priv;
514 fe->ops.tuner_ops = fc0011_tuner_ops;
515
516 dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");
517
518 return fe;
519}
520EXPORT_SYMBOL(fc0011_attach);
521
522MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
523MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
524MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/fc0011.h b/drivers/media/common/tuners/fc0011.h
new file mode 100644
index 000000000000..0ee581f122d2
--- /dev/null
+++ b/drivers/media/common/tuners/fc0011.h
@@ -0,0 +1,41 @@
1#ifndef LINUX_FC0011_H_
2#define LINUX_FC0011_H_
3
4#include "dvb_frontend.h"
5
6
7/** struct fc0011_config - fc0011 hardware config
8 *
9 * @i2c_address: I2C bus address.
10 */
11struct fc0011_config {
12 u8 i2c_address;
13};
14
15/** enum fc0011_fe_callback_commands - Frontend callbacks
16 *
17 * @FC0011_FE_CALLBACK_POWER: Power on tuner hardware.
18 * @FC0011_FE_CALLBACK_RESET: Request a tuner reset.
19 */
20enum fc0011_fe_callback_commands {
21 FC0011_FE_CALLBACK_POWER,
22 FC0011_FE_CALLBACK_RESET,
23};
24
25#if defined(CONFIG_MEDIA_TUNER_FC0011) ||\
26 defined(CONFIG_MEDIA_TUNER_FC0011_MODULE)
27struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
28 struct i2c_adapter *i2c,
29 const struct fc0011_config *config);
30#else
31static inline
32struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
33 struct i2c_adapter *i2c,
34 const struct fc0011_config *config)
35{
36 dev_err(&i2c->dev, "fc0011 driver disabled in Kconfig\n");
37 return NULL;
38}
39#endif
40
41#endif /* LINUX_FC0011_H_ */
diff --git a/drivers/media/common/tuners/fc0012-priv.h b/drivers/media/common/tuners/fc0012-priv.h
new file mode 100644
index 000000000000..4577c917e616
--- /dev/null
+++ b/drivers/media/common/tuners/fc0012-priv.h
@@ -0,0 +1,43 @@
1/*
2 * Fitipower FC0012 tuner driver - private includes
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.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#ifndef _FC0012_PRIV_H_
22#define _FC0012_PRIV_H_
23
24#define LOG_PREFIX "fc0012"
25
26#undef err
27#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
28#undef info
29#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
30#undef warn
31#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
32
33struct fc0012_priv {
34 struct i2c_adapter *i2c;
35 u8 addr;
36 u8 dual_master;
37 u8 xtal_freq;
38
39 u32 frequency;
40 u32 bandwidth;
41};
42
43#endif
diff --git a/drivers/media/common/tuners/fc0012.c b/drivers/media/common/tuners/fc0012.c
new file mode 100644
index 000000000000..308135abd54c
--- /dev/null
+++ b/drivers/media/common/tuners/fc0012.c
@@ -0,0 +1,467 @@
1/*
2 * Fitipower FC0012 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.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#include "fc0012.h"
22#include "fc0012-priv.h"
23
24static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
25{
26 u8 buf[2] = {reg, val};
27 struct i2c_msg msg = {
28 .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
29 };
30
31 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
32 err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
33 return -EREMOTEIO;
34 }
35 return 0;
36}
37
38static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
39{
40 struct i2c_msg msg[2] = {
41 { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
42 { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
43 };
44
45 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
46 err("I2C read reg failed, reg: %02x", reg);
47 return -EREMOTEIO;
48 }
49 return 0;
50}
51
52static int fc0012_release(struct dvb_frontend *fe)
53{
54 kfree(fe->tuner_priv);
55 fe->tuner_priv = NULL;
56 return 0;
57}
58
59static int fc0012_init(struct dvb_frontend *fe)
60{
61 struct fc0012_priv *priv = fe->tuner_priv;
62 int i, ret = 0;
63 unsigned char reg[] = {
64 0x00, /* dummy reg. 0 */
65 0x05, /* reg. 0x01 */
66 0x10, /* reg. 0x02 */
67 0x00, /* reg. 0x03 */
68 0x00, /* reg. 0x04 */
69 0x0f, /* reg. 0x05: may also be 0x0a */
70 0x00, /* reg. 0x06: divider 2, VCO slow */
71 0x00, /* reg. 0x07: may also be 0x0f */
72 0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
73 Loop Bw 1/8 */
74 0x6e, /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */
75 0xb8, /* reg. 0x0a: Disable LO Test Buffer */
76 0x82, /* reg. 0x0b: Output Clock is same as clock frequency,
77 may also be 0x83 */
78 0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
79 0x02, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */
80 0x00, /* reg. 0x0e */
81 0x00, /* reg. 0x0f */
82 0x00, /* reg. 0x10: may also be 0x0d */
83 0x00, /* reg. 0x11 */
84 0x1f, /* reg. 0x12: Set to maximum gain */
85 0x08, /* reg. 0x13: Set to Middle Gain: 0x08,
86 Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
87 0x00, /* reg. 0x14 */
88 0x04, /* reg. 0x15: Enable LNA COMPS */
89 };
90
91 switch (priv->xtal_freq) {
92 case FC_XTAL_27_MHZ:
93 case FC_XTAL_28_8_MHZ:
94 reg[0x07] |= 0x20;
95 break;
96 case FC_XTAL_36_MHZ:
97 default:
98 break;
99 }
100
101 if (priv->dual_master)
102 reg[0x0c] |= 0x02;
103
104 if (fe->ops.i2c_gate_ctrl)
105 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
106
107 for (i = 1; i < sizeof(reg); i++) {
108 ret = fc0012_writereg(priv, i, reg[i]);
109 if (ret)
110 break;
111 }
112
113 if (fe->ops.i2c_gate_ctrl)
114 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
115
116 if (ret)
117 err("fc0012_writereg failed: %d", ret);
118
119 return ret;
120}
121
122static int fc0012_sleep(struct dvb_frontend *fe)
123{
124 /* nothing to do here */
125 return 0;
126}
127
128static int fc0012_set_params(struct dvb_frontend *fe)
129{
130 struct fc0012_priv *priv = fe->tuner_priv;
131 int i, ret = 0;
132 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
133 u32 freq = p->frequency / 1000;
134 u32 delsys = p->delivery_system;
135 unsigned char reg[7], am, pm, multi, tmp;
136 unsigned long f_vco;
137 unsigned short xtal_freq_khz_2, xin, xdiv;
138 int vco_select = false;
139
140 if (fe->callback) {
141 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
142 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
143 if (ret)
144 goto exit;
145 }
146
147 switch (priv->xtal_freq) {
148 case FC_XTAL_27_MHZ:
149 xtal_freq_khz_2 = 27000 / 2;
150 break;
151 case FC_XTAL_36_MHZ:
152 xtal_freq_khz_2 = 36000 / 2;
153 break;
154 case FC_XTAL_28_8_MHZ:
155 default:
156 xtal_freq_khz_2 = 28800 / 2;
157 break;
158 }
159
160 /* select frequency divider and the frequency of VCO */
161 if (freq < 37084) { /* freq * 96 < 3560000 */
162 multi = 96;
163 reg[5] = 0x82;
164 reg[6] = 0x00;
165 } else if (freq < 55625) { /* freq * 64 < 3560000 */
166 multi = 64;
167 reg[5] = 0x82;
168 reg[6] = 0x02;
169 } else if (freq < 74167) { /* freq * 48 < 3560000 */
170 multi = 48;
171 reg[5] = 0x42;
172 reg[6] = 0x00;
173 } else if (freq < 111250) { /* freq * 32 < 3560000 */
174 multi = 32;
175 reg[5] = 0x42;
176 reg[6] = 0x02;
177 } else if (freq < 148334) { /* freq * 24 < 3560000 */
178 multi = 24;
179 reg[5] = 0x22;
180 reg[6] = 0x00;
181 } else if (freq < 222500) { /* freq * 16 < 3560000 */
182 multi = 16;
183 reg[5] = 0x22;
184 reg[6] = 0x02;
185 } else if (freq < 296667) { /* freq * 12 < 3560000 */
186 multi = 12;
187 reg[5] = 0x12;
188 reg[6] = 0x00;
189 } else if (freq < 445000) { /* freq * 8 < 3560000 */
190 multi = 8;
191 reg[5] = 0x12;
192 reg[6] = 0x02;
193 } else if (freq < 593334) { /* freq * 6 < 3560000 */
194 multi = 6;
195 reg[5] = 0x0a;
196 reg[6] = 0x00;
197 } else {
198 multi = 4;
199 reg[5] = 0x0a;
200 reg[6] = 0x02;
201 }
202
203 f_vco = freq * multi;
204
205 if (f_vco >= 3060000) {
206 reg[6] |= 0x08;
207 vco_select = true;
208 }
209
210 if (freq >= 45000) {
211 /* From divided value (XDIV) determined the FA and FP value */
212 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
213 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
214 xdiv++;
215
216 pm = (unsigned char)(xdiv / 8);
217 am = (unsigned char)(xdiv - (8 * pm));
218
219 if (am < 2) {
220 reg[1] = am + 8;
221 reg[2] = pm - 1;
222 } else {
223 reg[1] = am;
224 reg[2] = pm;
225 }
226 } else {
227 /* fix for frequency less than 45 MHz */
228 reg[1] = 0x06;
229 reg[2] = 0x11;
230 }
231
232 /* fix clock out */
233 reg[6] |= 0x20;
234
235 /* From VCO frequency determines the XIN ( fractional part of Delta
236 Sigma PLL) and divided value (XDIV) */
237 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
238 xin = (xin << 15) / xtal_freq_khz_2;
239 if (xin >= 16384)
240 xin += 32768;
241
242 reg[3] = xin >> 8; /* xin with 9 bit resolution */
243 reg[4] = xin & 0xff;
244
245 if (delsys == SYS_DVBT) {
246 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
247 switch (p->bandwidth_hz) {
248 case 6000000:
249 reg[6] |= 0x80;
250 break;
251 case 7000000:
252 reg[6] |= 0x40;
253 break;
254 case 8000000:
255 default:
256 break;
257 }
258 } else {
259 err("%s: modulation type not supported!", __func__);
260 return -EINVAL;
261 }
262
263 /* modified for Realtek demod */
264 reg[5] |= 0x07;
265
266 if (fe->ops.i2c_gate_ctrl)
267 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
268
269 for (i = 1; i <= 6; i++) {
270 ret = fc0012_writereg(priv, i, reg[i]);
271 if (ret)
272 goto exit;
273 }
274
275 /* VCO Calibration */
276 ret = fc0012_writereg(priv, 0x0e, 0x80);
277 if (!ret)
278 ret = fc0012_writereg(priv, 0x0e, 0x00);
279
280 /* VCO Re-Calibration if needed */
281 if (!ret)
282 ret = fc0012_writereg(priv, 0x0e, 0x00);
283
284 if (!ret) {
285 msleep(10);
286 ret = fc0012_readreg(priv, 0x0e, &tmp);
287 }
288 if (ret)
289 goto exit;
290
291 /* vco selection */
292 tmp &= 0x3f;
293
294 if (vco_select) {
295 if (tmp > 0x3c) {
296 reg[6] &= ~0x08;
297 ret = fc0012_writereg(priv, 0x06, reg[6]);
298 if (!ret)
299 ret = fc0012_writereg(priv, 0x0e, 0x80);
300 if (!ret)
301 ret = fc0012_writereg(priv, 0x0e, 0x00);
302 }
303 } else {
304 if (tmp < 0x02) {
305 reg[6] |= 0x08;
306 ret = fc0012_writereg(priv, 0x06, reg[6]);
307 if (!ret)
308 ret = fc0012_writereg(priv, 0x0e, 0x80);
309 if (!ret)
310 ret = fc0012_writereg(priv, 0x0e, 0x00);
311 }
312 }
313
314 priv->frequency = p->frequency;
315 priv->bandwidth = p->bandwidth_hz;
316
317exit:
318 if (fe->ops.i2c_gate_ctrl)
319 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
320 if (ret)
321 warn("%s: failed: %d", __func__, ret);
322 return ret;
323}
324
325static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
326{
327 struct fc0012_priv *priv = fe->tuner_priv;
328 *frequency = priv->frequency;
329 return 0;
330}
331
332static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
333{
334 /* CHECK: always ? */
335 *frequency = 0;
336 return 0;
337}
338
339static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
340{
341 struct fc0012_priv *priv = fe->tuner_priv;
342 *bandwidth = priv->bandwidth;
343 return 0;
344}
345
346#define INPUT_ADC_LEVEL -8
347
348static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
349{
350 struct fc0012_priv *priv = fe->tuner_priv;
351 int ret;
352 unsigned char tmp;
353 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
354 const int fc0012_lna_gain_table[] = {
355 /* low gain */
356 -63, -58, -99, -73,
357 -63, -65, -54, -60,
358 /* middle gain */
359 71, 70, 68, 67,
360 65, 63, 61, 58,
361 /* high gain */
362 197, 191, 188, 186,
363 184, 182, 181, 179,
364 };
365
366 if (fe->ops.i2c_gate_ctrl)
367 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
368
369 ret = fc0012_writereg(priv, 0x12, 0x00);
370 if (ret)
371 goto err;
372
373 ret = fc0012_readreg(priv, 0x12, &tmp);
374 if (ret)
375 goto err;
376 int_temp = tmp;
377
378 ret = fc0012_readreg(priv, 0x13, &tmp);
379 if (ret)
380 goto err;
381 lna_gain = tmp & 0x1f;
382
383 if (fe->ops.i2c_gate_ctrl)
384 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
385
386 if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
387 int_lna = fc0012_lna_gain_table[lna_gain];
388 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
389 (int_temp & 0x1f)) * 2;
390 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
391
392 if (power >= 45)
393 *strength = 255; /* 100% */
394 else if (power < -95)
395 *strength = 0;
396 else
397 *strength = (power + 95) * 255 / 140;
398
399 *strength |= *strength << 8;
400 } else {
401 ret = -1;
402 }
403
404 goto exit;
405
406err:
407 if (fe->ops.i2c_gate_ctrl)
408 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
409exit:
410 if (ret)
411 warn("%s: failed: %d", __func__, ret);
412 return ret;
413}
414
415static const struct dvb_tuner_ops fc0012_tuner_ops = {
416 .info = {
417 .name = "Fitipower FC0012",
418
419 .frequency_min = 37000000, /* estimate */
420 .frequency_max = 862000000, /* estimate */
421 .frequency_step = 0,
422 },
423
424 .release = fc0012_release,
425
426 .init = fc0012_init,
427 .sleep = fc0012_sleep,
428
429 .set_params = fc0012_set_params,
430
431 .get_frequency = fc0012_get_frequency,
432 .get_if_frequency = fc0012_get_if_frequency,
433 .get_bandwidth = fc0012_get_bandwidth,
434
435 .get_rf_strength = fc0012_get_rf_strength,
436};
437
438struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
439 struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
440 enum fc001x_xtal_freq xtal_freq)
441{
442 struct fc0012_priv *priv = NULL;
443
444 priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
445 if (priv == NULL)
446 return NULL;
447
448 priv->i2c = i2c;
449 priv->dual_master = dual_master;
450 priv->addr = i2c_address;
451 priv->xtal_freq = xtal_freq;
452
453 info("Fitipower FC0012 successfully attached.");
454
455 fe->tuner_priv = priv;
456
457 memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
458 sizeof(struct dvb_tuner_ops));
459
460 return fe;
461}
462EXPORT_SYMBOL(fc0012_attach);
463
464MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
465MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
466MODULE_LICENSE("GPL");
467MODULE_VERSION("0.6");
diff --git a/drivers/media/common/tuners/fc0012.h b/drivers/media/common/tuners/fc0012.h
new file mode 100644
index 000000000000..4dbd5efe8845
--- /dev/null
+++ b/drivers/media/common/tuners/fc0012.h
@@ -0,0 +1,44 @@
1/*
2 * Fitipower FC0012 tuner driver - include
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.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#ifndef _FC0012_H_
22#define _FC0012_H_
23
24#include "dvb_frontend.h"
25#include "fc001x-common.h"
26
27#if defined(CONFIG_MEDIA_TUNER_FC0012) || \
28 (defined(CONFIG_MEDIA_TUNER_FC0012_MODULE) && defined(MODULE))
29extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
30 struct i2c_adapter *i2c,
31 u8 i2c_address, int dual_master,
32 enum fc001x_xtal_freq xtal_freq);
33#else
34static inline struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c,
36 u8 i2c_address, int dual_master,
37 enum fc001x_xtal_freq xtal_freq)
38{
39 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
40 return NULL;
41}
42#endif
43
44#endif
diff --git a/drivers/media/common/tuners/fc0013-priv.h b/drivers/media/common/tuners/fc0013-priv.h
new file mode 100644
index 000000000000..bfd49dedea22
--- /dev/null
+++ b/drivers/media/common/tuners/fc0013-priv.h
@@ -0,0 +1,44 @@
1/*
2 * Fitipower FC0013 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.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#ifndef _FC0013_PRIV_H_
23#define _FC0013_PRIV_H_
24
25#define LOG_PREFIX "fc0013"
26
27#undef err
28#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
29#undef info
30#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
31#undef warn
32#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
33
34struct fc0013_priv {
35 struct i2c_adapter *i2c;
36 u8 addr;
37 u8 dual_master;
38 u8 xtal_freq;
39
40 u32 frequency;
41 u32 bandwidth;
42};
43
44#endif
diff --git a/drivers/media/common/tuners/fc0013.c b/drivers/media/common/tuners/fc0013.c
new file mode 100644
index 000000000000..bd8f0f1e8f3b
--- /dev/null
+++ b/drivers/media/common/tuners/fc0013.c
@@ -0,0 +1,634 @@
1/*
2 * Fitipower FC0013 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 * partially based on driver code from Fitipower
6 * Copyright (C) 2010 Fitipower Integrated Technology Inc
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 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "fc0013.h"
25#include "fc0013-priv.h"
26
27static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
28{
29 u8 buf[2] = {reg, val};
30 struct i2c_msg msg = {
31 .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
32 };
33
34 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
35 err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
36 return -EREMOTEIO;
37 }
38 return 0;
39}
40
41static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
42{
43 struct i2c_msg msg[2] = {
44 { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
45 { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
46 };
47
48 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
49 err("I2C read reg failed, reg: %02x", reg);
50 return -EREMOTEIO;
51 }
52 return 0;
53}
54
55static int fc0013_release(struct dvb_frontend *fe)
56{
57 kfree(fe->tuner_priv);
58 fe->tuner_priv = NULL;
59 return 0;
60}
61
62static int fc0013_init(struct dvb_frontend *fe)
63{
64 struct fc0013_priv *priv = fe->tuner_priv;
65 int i, ret = 0;
66 unsigned char reg[] = {
67 0x00, /* reg. 0x00: dummy */
68 0x09, /* reg. 0x01 */
69 0x16, /* reg. 0x02 */
70 0x00, /* reg. 0x03 */
71 0x00, /* reg. 0x04 */
72 0x17, /* reg. 0x05 */
73 0x02, /* reg. 0x06 */
74 0x0a, /* reg. 0x07: CHECK */
75 0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
76 Loop Bw 1/8 */
77 0x6f, /* reg. 0x09: enable LoopThrough */
78 0xb8, /* reg. 0x0a: Disable LO Test Buffer */
79 0x82, /* reg. 0x0b: CHECK */
80 0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
81 0x01, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, may need 0x02 */
82 0x00, /* reg. 0x0e */
83 0x00, /* reg. 0x0f */
84 0x00, /* reg. 0x10 */
85 0x00, /* reg. 0x11 */
86 0x00, /* reg. 0x12 */
87 0x00, /* reg. 0x13 */
88 0x50, /* reg. 0x14: DVB-t High Gain, UHF.
89 Middle Gain: 0x48, Low Gain: 0x40 */
90 0x01, /* reg. 0x15 */
91 };
92
93 switch (priv->xtal_freq) {
94 case FC_XTAL_27_MHZ:
95 case FC_XTAL_28_8_MHZ:
96 reg[0x07] |= 0x20;
97 break;
98 case FC_XTAL_36_MHZ:
99 default:
100 break;
101 }
102
103 if (priv->dual_master)
104 reg[0x0c] |= 0x02;
105
106 if (fe->ops.i2c_gate_ctrl)
107 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
108
109 for (i = 1; i < sizeof(reg); i++) {
110 ret = fc0013_writereg(priv, i, reg[i]);
111 if (ret)
112 break;
113 }
114
115 if (fe->ops.i2c_gate_ctrl)
116 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
117
118 if (ret)
119 err("fc0013_writereg failed: %d", ret);
120
121 return ret;
122}
123
124static int fc0013_sleep(struct dvb_frontend *fe)
125{
126 /* nothing to do here */
127 return 0;
128}
129
130int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
131{
132 struct fc0013_priv *priv = fe->tuner_priv;
133 int ret;
134 u8 rc_cal;
135 int val;
136
137 if (fe->ops.i2c_gate_ctrl)
138 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
139
140 /* push rc_cal value, get rc_cal value */
141 ret = fc0013_writereg(priv, 0x10, 0x00);
142 if (ret)
143 goto error_out;
144
145 /* get rc_cal value */
146 ret = fc0013_readreg(priv, 0x10, &rc_cal);
147 if (ret)
148 goto error_out;
149
150 rc_cal &= 0x0f;
151
152 val = (int)rc_cal + rc_val;
153
154 /* forcing rc_cal */
155 ret = fc0013_writereg(priv, 0x0d, 0x11);
156 if (ret)
157 goto error_out;
158
159 /* modify rc_cal value */
160 if (val > 15)
161 ret = fc0013_writereg(priv, 0x10, 0x0f);
162 else if (val < 0)
163 ret = fc0013_writereg(priv, 0x10, 0x00);
164 else
165 ret = fc0013_writereg(priv, 0x10, (u8)val);
166
167error_out:
168 if (fe->ops.i2c_gate_ctrl)
169 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
170
171 return ret;
172}
173EXPORT_SYMBOL(fc0013_rc_cal_add);
174
175int fc0013_rc_cal_reset(struct dvb_frontend *fe)
176{
177 struct fc0013_priv *priv = fe->tuner_priv;
178 int ret;
179
180 if (fe->ops.i2c_gate_ctrl)
181 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
182
183 ret = fc0013_writereg(priv, 0x0d, 0x01);
184 if (!ret)
185 ret = fc0013_writereg(priv, 0x10, 0x00);
186
187 if (fe->ops.i2c_gate_ctrl)
188 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
189
190 return ret;
191}
192EXPORT_SYMBOL(fc0013_rc_cal_reset);
193
194static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
195{
196 int ret;
197 u8 tmp;
198
199 ret = fc0013_readreg(priv, 0x1d, &tmp);
200 if (ret)
201 goto error_out;
202 tmp &= 0xe3;
203 if (freq <= 177500) { /* VHF Track: 7 */
204 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
205 } else if (freq <= 184500) { /* VHF Track: 6 */
206 ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
207 } else if (freq <= 191500) { /* VHF Track: 5 */
208 ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
209 } else if (freq <= 198500) { /* VHF Track: 4 */
210 ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
211 } else if (freq <= 205500) { /* VHF Track: 3 */
212 ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
213 } else if (freq <= 219500) { /* VHF Track: 2 */
214 ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
215 } else if (freq < 300000) { /* VHF Track: 1 */
216 ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
217 } else { /* UHF and GPS */
218 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
219 }
220 if (ret)
221 goto error_out;
222error_out:
223 return ret;
224}
225
226static int fc0013_set_params(struct dvb_frontend *fe)
227{
228 struct fc0013_priv *priv = fe->tuner_priv;
229 int i, ret = 0;
230 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
231 u32 freq = p->frequency / 1000;
232 u32 delsys = p->delivery_system;
233 unsigned char reg[7], am, pm, multi, tmp;
234 unsigned long f_vco;
235 unsigned short xtal_freq_khz_2, xin, xdiv;
236 int vco_select = false;
237
238 if (fe->callback) {
239 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
240 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
241 if (ret)
242 goto exit;
243 }
244
245 switch (priv->xtal_freq) {
246 case FC_XTAL_27_MHZ:
247 xtal_freq_khz_2 = 27000 / 2;
248 break;
249 case FC_XTAL_36_MHZ:
250 xtal_freq_khz_2 = 36000 / 2;
251 break;
252 case FC_XTAL_28_8_MHZ:
253 default:
254 xtal_freq_khz_2 = 28800 / 2;
255 break;
256 }
257
258 if (fe->ops.i2c_gate_ctrl)
259 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
260
261 /* set VHF track */
262 ret = fc0013_set_vhf_track(priv, freq);
263 if (ret)
264 goto exit;
265
266 if (freq < 300000) {
267 /* enable VHF filter */
268 ret = fc0013_readreg(priv, 0x07, &tmp);
269 if (ret)
270 goto exit;
271 ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
272 if (ret)
273 goto exit;
274
275 /* disable UHF & disable GPS */
276 ret = fc0013_readreg(priv, 0x14, &tmp);
277 if (ret)
278 goto exit;
279 ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
280 if (ret)
281 goto exit;
282 } else if (freq <= 862000) {
283 /* disable VHF filter */
284 ret = fc0013_readreg(priv, 0x07, &tmp);
285 if (ret)
286 goto exit;
287 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
288 if (ret)
289 goto exit;
290
291 /* enable UHF & disable GPS */
292 ret = fc0013_readreg(priv, 0x14, &tmp);
293 if (ret)
294 goto exit;
295 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
296 if (ret)
297 goto exit;
298 } else {
299 /* disable VHF filter */
300 ret = fc0013_readreg(priv, 0x07, &tmp);
301 if (ret)
302 goto exit;
303 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
304 if (ret)
305 goto exit;
306
307 /* disable UHF & enable GPS */
308 ret = fc0013_readreg(priv, 0x14, &tmp);
309 if (ret)
310 goto exit;
311 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
312 if (ret)
313 goto exit;
314 }
315
316 /* select frequency divider and the frequency of VCO */
317 if (freq < 37084) { /* freq * 96 < 3560000 */
318 multi = 96;
319 reg[5] = 0x82;
320 reg[6] = 0x00;
321 } else if (freq < 55625) { /* freq * 64 < 3560000 */
322 multi = 64;
323 reg[5] = 0x02;
324 reg[6] = 0x02;
325 } else if (freq < 74167) { /* freq * 48 < 3560000 */
326 multi = 48;
327 reg[5] = 0x42;
328 reg[6] = 0x00;
329 } else if (freq < 111250) { /* freq * 32 < 3560000 */
330 multi = 32;
331 reg[5] = 0x82;
332 reg[6] = 0x02;
333 } else if (freq < 148334) { /* freq * 24 < 3560000 */
334 multi = 24;
335 reg[5] = 0x22;
336 reg[6] = 0x00;
337 } else if (freq < 222500) { /* freq * 16 < 3560000 */
338 multi = 16;
339 reg[5] = 0x42;
340 reg[6] = 0x02;
341 } else if (freq < 296667) { /* freq * 12 < 3560000 */
342 multi = 12;
343 reg[5] = 0x12;
344 reg[6] = 0x00;
345 } else if (freq < 445000) { /* freq * 8 < 3560000 */
346 multi = 8;
347 reg[5] = 0x22;
348 reg[6] = 0x02;
349 } else if (freq < 593334) { /* freq * 6 < 3560000 */
350 multi = 6;
351 reg[5] = 0x0a;
352 reg[6] = 0x00;
353 } else if (freq < 950000) { /* freq * 4 < 3800000 */
354 multi = 4;
355 reg[5] = 0x12;
356 reg[6] = 0x02;
357 } else {
358 multi = 2;
359 reg[5] = 0x0a;
360 reg[6] = 0x02;
361 }
362
363 f_vco = freq * multi;
364
365 if (f_vco >= 3060000) {
366 reg[6] |= 0x08;
367 vco_select = true;
368 }
369
370 if (freq >= 45000) {
371 /* From divided value (XDIV) determined the FA and FP value */
372 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
373 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
374 xdiv++;
375
376 pm = (unsigned char)(xdiv / 8);
377 am = (unsigned char)(xdiv - (8 * pm));
378
379 if (am < 2) {
380 reg[1] = am + 8;
381 reg[2] = pm - 1;
382 } else {
383 reg[1] = am;
384 reg[2] = pm;
385 }
386 } else {
387 /* fix for frequency less than 45 MHz */
388 reg[1] = 0x06;
389 reg[2] = 0x11;
390 }
391
392 /* fix clock out */
393 reg[6] |= 0x20;
394
395 /* From VCO frequency determines the XIN ( fractional part of Delta
396 Sigma PLL) and divided value (XDIV) */
397 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
398 xin = (xin << 15) / xtal_freq_khz_2;
399 if (xin >= 16384)
400 xin += 32768;
401
402 reg[3] = xin >> 8;
403 reg[4] = xin & 0xff;
404
405 if (delsys == SYS_DVBT) {
406 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
407 switch (p->bandwidth_hz) {
408 case 6000000:
409 reg[6] |= 0x80;
410 break;
411 case 7000000:
412 reg[6] |= 0x40;
413 break;
414 case 8000000:
415 default:
416 break;
417 }
418 } else {
419 err("%s: modulation type not supported!", __func__);
420 return -EINVAL;
421 }
422
423 /* modified for Realtek demod */
424 reg[5] |= 0x07;
425
426 for (i = 1; i <= 6; i++) {
427 ret = fc0013_writereg(priv, i, reg[i]);
428 if (ret)
429 goto exit;
430 }
431
432 ret = fc0013_readreg(priv, 0x11, &tmp);
433 if (ret)
434 goto exit;
435 if (multi == 64)
436 ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
437 else
438 ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
439 if (ret)
440 goto exit;
441
442 /* VCO Calibration */
443 ret = fc0013_writereg(priv, 0x0e, 0x80);
444 if (!ret)
445 ret = fc0013_writereg(priv, 0x0e, 0x00);
446
447 /* VCO Re-Calibration if needed */
448 if (!ret)
449 ret = fc0013_writereg(priv, 0x0e, 0x00);
450
451 if (!ret) {
452 msleep(10);
453 ret = fc0013_readreg(priv, 0x0e, &tmp);
454 }
455 if (ret)
456 goto exit;
457
458 /* vco selection */
459 tmp &= 0x3f;
460
461 if (vco_select) {
462 if (tmp > 0x3c) {
463 reg[6] &= ~0x08;
464 ret = fc0013_writereg(priv, 0x06, reg[6]);
465 if (!ret)
466 ret = fc0013_writereg(priv, 0x0e, 0x80);
467 if (!ret)
468 ret = fc0013_writereg(priv, 0x0e, 0x00);
469 }
470 } else {
471 if (tmp < 0x02) {
472 reg[6] |= 0x08;
473 ret = fc0013_writereg(priv, 0x06, reg[6]);
474 if (!ret)
475 ret = fc0013_writereg(priv, 0x0e, 0x80);
476 if (!ret)
477 ret = fc0013_writereg(priv, 0x0e, 0x00);
478 }
479 }
480
481 priv->frequency = p->frequency;
482 priv->bandwidth = p->bandwidth_hz;
483
484exit:
485 if (fe->ops.i2c_gate_ctrl)
486 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
487 if (ret)
488 warn("%s: failed: %d", __func__, ret);
489 return ret;
490}
491
492static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
493{
494 struct fc0013_priv *priv = fe->tuner_priv;
495 *frequency = priv->frequency;
496 return 0;
497}
498
499static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
500{
501 /* always ? */
502 *frequency = 0;
503 return 0;
504}
505
506static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
507{
508 struct fc0013_priv *priv = fe->tuner_priv;
509 *bandwidth = priv->bandwidth;
510 return 0;
511}
512
513#define INPUT_ADC_LEVEL -8
514
515static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
516{
517 struct fc0013_priv *priv = fe->tuner_priv;
518 int ret;
519 unsigned char tmp;
520 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
521 const int fc0013_lna_gain_table[] = {
522 /* low gain */
523 -63, -58, -99, -73,
524 -63, -65, -54, -60,
525 /* middle gain */
526 71, 70, 68, 67,
527 65, 63, 61, 58,
528 /* high gain */
529 197, 191, 188, 186,
530 184, 182, 181, 179,
531 };
532
533 if (fe->ops.i2c_gate_ctrl)
534 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
535
536 ret = fc0013_writereg(priv, 0x13, 0x00);
537 if (ret)
538 goto err;
539
540 ret = fc0013_readreg(priv, 0x13, &tmp);
541 if (ret)
542 goto err;
543 int_temp = tmp;
544
545 ret = fc0013_readreg(priv, 0x14, &tmp);
546 if (ret)
547 goto err;
548 lna_gain = tmp & 0x1f;
549
550 if (fe->ops.i2c_gate_ctrl)
551 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
552
553 if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
554 int_lna = fc0013_lna_gain_table[lna_gain];
555 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
556 (int_temp & 0x1f)) * 2;
557 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
558
559 if (power >= 45)
560 *strength = 255; /* 100% */
561 else if (power < -95)
562 *strength = 0;
563 else
564 *strength = (power + 95) * 255 / 140;
565
566 *strength |= *strength << 8;
567 } else {
568 ret = -1;
569 }
570
571 goto exit;
572
573err:
574 if (fe->ops.i2c_gate_ctrl)
575 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
576exit:
577 if (ret)
578 warn("%s: failed: %d", __func__, ret);
579 return ret;
580}
581
582static const struct dvb_tuner_ops fc0013_tuner_ops = {
583 .info = {
584 .name = "Fitipower FC0013",
585
586 .frequency_min = 37000000, /* estimate */
587 .frequency_max = 1680000000, /* CHECK */
588 .frequency_step = 0,
589 },
590
591 .release = fc0013_release,
592
593 .init = fc0013_init,
594 .sleep = fc0013_sleep,
595
596 .set_params = fc0013_set_params,
597
598 .get_frequency = fc0013_get_frequency,
599 .get_if_frequency = fc0013_get_if_frequency,
600 .get_bandwidth = fc0013_get_bandwidth,
601
602 .get_rf_strength = fc0013_get_rf_strength,
603};
604
605struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
606 struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
607 enum fc001x_xtal_freq xtal_freq)
608{
609 struct fc0013_priv *priv = NULL;
610
611 priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
612 if (priv == NULL)
613 return NULL;
614
615 priv->i2c = i2c;
616 priv->dual_master = dual_master;
617 priv->addr = i2c_address;
618 priv->xtal_freq = xtal_freq;
619
620 info("Fitipower FC0013 successfully attached.");
621
622 fe->tuner_priv = priv;
623
624 memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
625 sizeof(struct dvb_tuner_ops));
626
627 return fe;
628}
629EXPORT_SYMBOL(fc0013_attach);
630
631MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
632MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
633MODULE_LICENSE("GPL");
634MODULE_VERSION("0.2");
diff --git a/drivers/media/common/tuners/fc0013.h b/drivers/media/common/tuners/fc0013.h
new file mode 100644
index 000000000000..594efd64aeec
--- /dev/null
+++ b/drivers/media/common/tuners/fc0013.h
@@ -0,0 +1,57 @@
1/*
2 * Fitipower FC0013 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.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#ifndef _FC0013_H_
23#define _FC0013_H_
24
25#include "dvb_frontend.h"
26#include "fc001x-common.h"
27
28#if defined(CONFIG_MEDIA_TUNER_FC0013) || \
29 (defined(CONFIG_MEDIA_TUNER_FC0013_MODULE) && defined(MODULE))
30extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
31 struct i2c_adapter *i2c,
32 u8 i2c_address, int dual_master,
33 enum fc001x_xtal_freq xtal_freq);
34extern int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val);
35extern int fc0013_rc_cal_reset(struct dvb_frontend *fe);
36#else
37static inline struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
38 struct i2c_adapter *i2c,
39 u8 i2c_address, int dual_master,
40 enum fc001x_xtal_freq xtal_freq)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45
46static inline int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
47{
48 return 0;
49}
50
51static inline int fc0013_rc_cal_reset(struct dvb_frontend *fe)
52{
53 return 0;
54}
55#endif
56
57#endif
diff --git a/drivers/media/common/tuners/fc001x-common.h b/drivers/media/common/tuners/fc001x-common.h
new file mode 100644
index 000000000000..718818156934
--- /dev/null
+++ b/drivers/media/common/tuners/fc001x-common.h
@@ -0,0 +1,39 @@
1/*
2 * Fitipower FC0012 & FC0013 tuner driver - common defines
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.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#ifndef _FC001X_COMMON_H_
22#define _FC001X_COMMON_H_
23
24enum fc001x_xtal_freq {
25 FC_XTAL_27_MHZ, /* 27000000 */
26 FC_XTAL_28_8_MHZ, /* 28800000 */
27 FC_XTAL_36_MHZ, /* 36000000 */
28};
29
30/*
31 * enum fc001x_fe_callback_commands - Frontend callbacks
32 *
33 * @FC_FE_CALLBACK_VHF_ENABLE: enable VHF or UHF
34 */
35enum fc001x_fe_callback_commands {
36 FC_FE_CALLBACK_VHF_ENABLE,
37};
38
39#endif
diff --git a/drivers/media/common/tuners/tua9001.c b/drivers/media/common/tuners/tua9001.c
new file mode 100644
index 000000000000..de2607084672
--- /dev/null
+++ b/drivers/media/common/tuners/tua9001.c
@@ -0,0 +1,215 @@
1/*
2 * Infineon TUA 9001 silicon tuner driver
3 *
4 * Copyright (C) 2009 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 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include "tua9001.h"
22#include "tua9001_priv.h"
23
24/* write register */
25static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
26{
27 int ret;
28 u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff };
29 struct i2c_msg msg[1] = {
30 {
31 .addr = priv->cfg->i2c_addr,
32 .flags = 0,
33 .len = sizeof(buf),
34 .buf = buf,
35 }
36 };
37
38 ret = i2c_transfer(priv->i2c, msg, 1);
39 if (ret == 1) {
40 ret = 0;
41 } else {
42 printk(KERN_WARNING "%s: I2C wr failed=%d reg=%02x\n",
43 __func__, ret, reg);
44 ret = -EREMOTEIO;
45 }
46
47 return ret;
48}
49
50static int tua9001_release(struct dvb_frontend *fe)
51{
52 kfree(fe->tuner_priv);
53 fe->tuner_priv = NULL;
54
55 return 0;
56}
57
58static int tua9001_init(struct dvb_frontend *fe)
59{
60 struct tua9001_priv *priv = fe->tuner_priv;
61 int ret = 0;
62 u8 i;
63 struct reg_val data[] = {
64 { 0x1e, 0x6512 },
65 { 0x25, 0xb888 },
66 { 0x39, 0x5460 },
67 { 0x3b, 0x00c0 },
68 { 0x3a, 0xf000 },
69 { 0x08, 0x0000 },
70 { 0x32, 0x0030 },
71 { 0x41, 0x703a },
72 { 0x40, 0x1c78 },
73 { 0x2c, 0x1c00 },
74 { 0x36, 0xc013 },
75 { 0x37, 0x6f18 },
76 { 0x27, 0x0008 },
77 { 0x2a, 0x0001 },
78 { 0x34, 0x0a40 },
79 };
80
81 if (fe->ops.i2c_gate_ctrl)
82 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
83
84 for (i = 0; i < ARRAY_SIZE(data); i++) {
85 ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
86 if (ret)
87 break;
88 }
89
90 if (fe->ops.i2c_gate_ctrl)
91 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
92
93 if (ret < 0)
94 pr_debug("%s: failed=%d\n", __func__, ret);
95
96 return ret;
97}
98
99static int tua9001_set_params(struct dvb_frontend *fe)
100{
101 struct tua9001_priv *priv = fe->tuner_priv;
102 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
103 int ret, i;
104 u16 val;
105 u32 frequency;
106 struct reg_val data[2];
107
108 pr_debug("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
109 __func__, c->delivery_system, c->frequency,
110 c->bandwidth_hz);
111
112 switch (c->delivery_system) {
113 case SYS_DVBT:
114 switch (c->bandwidth_hz) {
115 case 8000000:
116 val = 0x0000;
117 break;
118 case 7000000:
119 val = 0x1000;
120 break;
121 case 6000000:
122 val = 0x2000;
123 break;
124 case 5000000:
125 val = 0x3000;
126 break;
127 default:
128 ret = -EINVAL;
129 goto err;
130 }
131 break;
132 default:
133 ret = -EINVAL;
134 goto err;
135 }
136
137 data[0].reg = 0x04;
138 data[0].val = val;
139
140 frequency = (c->frequency - 150000000);
141 frequency /= 100;
142 frequency *= 48;
143 frequency /= 10000;
144
145 data[1].reg = 0x1f;
146 data[1].val = frequency;
147
148 if (fe->ops.i2c_gate_ctrl)
149 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
150
151 for (i = 0; i < ARRAY_SIZE(data); i++) {
152 ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
153 if (ret < 0)
154 break;
155 }
156
157 if (fe->ops.i2c_gate_ctrl)
158 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
159
160err:
161 if (ret < 0)
162 pr_debug("%s: failed=%d\n", __func__, ret);
163
164 return ret;
165}
166
167static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
168{
169 *frequency = 0; /* Zero-IF */
170
171 return 0;
172}
173
174static const struct dvb_tuner_ops tua9001_tuner_ops = {
175 .info = {
176 .name = "Infineon TUA 9001",
177
178 .frequency_min = 170000000,
179 .frequency_max = 862000000,
180 .frequency_step = 0,
181 },
182
183 .release = tua9001_release,
184
185 .init = tua9001_init,
186 .set_params = tua9001_set_params,
187
188 .get_if_frequency = tua9001_get_if_frequency,
189};
190
191struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
192 struct i2c_adapter *i2c, struct tua9001_config *cfg)
193{
194 struct tua9001_priv *priv = NULL;
195
196 priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
197 if (priv == NULL)
198 return NULL;
199
200 priv->cfg = cfg;
201 priv->i2c = i2c;
202
203 printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
204
205 memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
206 sizeof(struct dvb_tuner_ops));
207
208 fe->tuner_priv = priv;
209 return fe;
210}
211EXPORT_SYMBOL(tua9001_attach);
212
213MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver");
214MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
215MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tua9001.h b/drivers/media/common/tuners/tua9001.h
new file mode 100644
index 000000000000..38d6ae76b1d6
--- /dev/null
+++ b/drivers/media/common/tuners/tua9001.h
@@ -0,0 +1,46 @@
1/*
2 * Infineon TUA 9001 silicon tuner driver
3 *
4 * Copyright (C) 2009 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 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TUA9001_H
22#define TUA9001_H
23
24#include "dvb_frontend.h"
25
26struct tua9001_config {
27 /*
28 * I2C address
29 */
30 u8 i2c_addr;
31};
32
33#if defined(CONFIG_MEDIA_TUNER_TUA9001) || \
34 (defined(CONFIG_MEDIA_TUNER_TUA9001_MODULE) && defined(MODULE))
35extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c, struct tua9001_config *cfg);
37#else
38static inline struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
39 struct i2c_adapter *i2c, struct tua9001_config *cfg)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif
45
46#endif
diff --git a/drivers/media/common/tuners/tua9001_priv.h b/drivers/media/common/tuners/tua9001_priv.h
new file mode 100644
index 000000000000..73cc1ce0575c
--- /dev/null
+++ b/drivers/media/common/tuners/tua9001_priv.h
@@ -0,0 +1,34 @@
1/*
2 * Infineon TUA 9001 silicon tuner driver
3 *
4 * Copyright (C) 2009 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 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TUA9001_PRIV_H
22#define TUA9001_PRIV_H
23
24struct reg_val {
25 u8 reg;
26 u16 val;
27};
28
29struct tua9001_priv {
30 struct tua9001_config *cfg;
31 struct i2c_adapter *i2c;
32};
33
34#endif
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index eab2ea424200..dcca42ca57be 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -54,7 +54,7 @@ struct xc5000_priv {
54 struct list_head hybrid_tuner_instance_list; 54 struct list_head hybrid_tuner_instance_list;
55 55
56 u32 if_khz; 56 u32 if_khz;
57 u32 xtal_khz; 57 u16 xtal_khz;
58 u32 freq_hz; 58 u32 freq_hz;
59 u32 bandwidth; 59 u32 bandwidth;
60 u8 video_standard; 60 u8 video_standard;
@@ -631,7 +631,10 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
631 ret = xc_load_i2c_sequence(fe, fw->data); 631 ret = xc_load_i2c_sequence(fe, fw->data);
632 if (XC_RESULT_SUCCESS == ret) 632 if (XC_RESULT_SUCCESS == ret)
633 ret = xc_set_xtal(fe); 633 ret = xc_set_xtal(fe);
634 printk(KERN_INFO "xc5000: firmware upload complete...\n"); 634 if (XC_RESULT_SUCCESS == ret)
635 printk(KERN_INFO "xc5000: firmware upload complete...\n");
636 else
637 printk(KERN_ERR "xc5000: firmware upload failed...\n");
635 } 638 }
636 639
637out: 640out:
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 39a73bf01406..b1a547494625 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -34,7 +34,7 @@ struct xc5000_config {
34 u8 i2c_address; 34 u8 i2c_address;
35 u32 if_khz; 35 u32 if_khz;
36 u8 radio_input; 36 u8 radio_input;
37 u32 xtal_khz; 37 u16 xtal_khz;
38 38
39 int chip_id; 39 int chip_id;
40}; 40};
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 48e48e8af55a..66f52f116b60 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -477,7 +477,6 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
477static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) 477static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
478{ 478{
479 int i = 0; 479 int i = 0;
480 unsigned int ca_message_header_len;
481 480
482 u32 command = 0; 481 u32 command = 0;
483 struct ca_msg *hw_buffer; 482 struct ca_msg *hw_buffer;
@@ -496,7 +495,6 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
496 495
497 496
498 if (p_ca_message->msg) { 497 if (p_ca_message->msg) {
499 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
500 /* EN50221 tag */ 498 /* EN50221 tag */
501 command = 0; 499 command = 0;
502 500
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c
index d88c4aa7d24d..131b938e9e81 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/dvb/ddbridge/ddbridge-core.c
@@ -31,7 +31,6 @@
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <linux/pci_ids.h> 32#include <linux/pci_ids.h>
33#include <linux/timer.h> 33#include <linux/timer.h>
34#include <linux/version.h>
35#include <linux/i2c.h> 34#include <linux/i2c.h>
36#include <linux/swab.h> 35#include <linux/swab.h>
37#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
@@ -1696,7 +1695,7 @@ static struct pci_driver ddb_pci_driver = {
1696 .name = "DDBridge", 1695 .name = "DDBridge",
1697 .id_table = ddb_id_tbl, 1696 .id_table = ddb_id_tbl,
1698 .probe = ddb_probe, 1697 .probe = ddb_probe,
1699 .remove = ddb_remove, 1698 .remove = __devexit_p(ddb_remove),
1700}; 1699};
1701 1700
1702static __init int module_init_ddbridge(void) 1701static __init int module_init_ddbridge(void)
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index faa3671b649e..d82469f842e2 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -568,6 +568,16 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
568} 568}
569EXPORT_SYMBOL(dvb_dmx_swfilter_204); 569EXPORT_SYMBOL(dvb_dmx_swfilter_204);
570 570
571void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
572{
573 spin_lock(&demux->lock);
574
575 demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK);
576
577 spin_unlock(&demux->lock);
578}
579EXPORT_SYMBOL(dvb_dmx_swfilter_raw);
580
571static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) 581static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
572{ 582{
573 int i; 583 int i;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index a7d876fd02dd..fa7188a253aa 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -145,5 +145,7 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
145void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count); 145void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
146void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, 146void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
147 size_t count); 147 size_t count);
148void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
149 size_t count);
148 150
149#endif /* _DVB_DEMUX_H_ */ 151#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index cb888d835a89..aebcdf221dda 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -182,13 +182,13 @@ static enum dvbv3_emulation_type dvbv3_type(u32 delivery_system)
182 case SYS_DMBTH: 182 case SYS_DMBTH:
183 return DVBV3_OFDM; 183 return DVBV3_OFDM;
184 case SYS_ATSC: 184 case SYS_ATSC:
185 case SYS_ATSCMH:
185 case SYS_DVBC_ANNEX_B: 186 case SYS_DVBC_ANNEX_B:
186 return DVBV3_ATSC; 187 return DVBV3_ATSC;
187 case SYS_UNDEFINED: 188 case SYS_UNDEFINED:
188 case SYS_ISDBC: 189 case SYS_ISDBC:
189 case SYS_DVBH: 190 case SYS_DVBH:
190 case SYS_DAB: 191 case SYS_DAB:
191 case SYS_ATSCMH:
192 default: 192 default:
193 /* 193 /*
194 * Doesn't know how to emulate those types and/or 194 * Doesn't know how to emulate those types and/or
@@ -1030,6 +1030,25 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
1030 _DTV_CMD(DTV_HIERARCHY, 0, 0), 1030 _DTV_CMD(DTV_HIERARCHY, 0, 0),
1031 1031
1032 _DTV_CMD(DTV_ENUM_DELSYS, 0, 0), 1032 _DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
1033
1034 _DTV_CMD(DTV_ATSCMH_PARADE_ID, 1, 0),
1035 _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 1, 0),
1036
1037 _DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0),
1038 _DTV_CMD(DTV_ATSCMH_PARADE_ID, 0, 0),
1039 _DTV_CMD(DTV_ATSCMH_NOG, 0, 0),
1040 _DTV_CMD(DTV_ATSCMH_TNOG, 0, 0),
1041 _DTV_CMD(DTV_ATSCMH_SGN, 0, 0),
1042 _DTV_CMD(DTV_ATSCMH_PRC, 0, 0),
1043 _DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0),
1044 _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 0, 0),
1045 _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0),
1046 _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0),
1047 _DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0),
1048 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A, 0, 0),
1049 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
1050 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
1051 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
1033}; 1052};
1034 1053
1035static void dtv_property_dump(struct dtv_property *tvp) 1054static void dtv_property_dump(struct dtv_property *tvp)
@@ -1121,6 +1140,8 @@ static int dtv_property_cache_sync(struct dvb_frontend *fe,
1121 case DVBV3_ATSC: 1140 case DVBV3_ATSC:
1122 dprintk("%s() Preparing ATSC req\n", __func__); 1141 dprintk("%s() Preparing ATSC req\n", __func__);
1123 c->modulation = p->u.vsb.modulation; 1142 c->modulation = p->u.vsb.modulation;
1143 if (c->delivery_system == SYS_ATSCMH)
1144 break;
1124 if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) 1145 if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
1125 c->delivery_system = SYS_ATSC; 1146 c->delivery_system = SYS_ATSC;
1126 else 1147 else
@@ -1367,6 +1388,54 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1367 case DTV_DVBT2_PLP_ID: 1388 case DTV_DVBT2_PLP_ID:
1368 tvp->u.data = c->dvbt2_plp_id; 1389 tvp->u.data = c->dvbt2_plp_id;
1369 break; 1390 break;
1391
1392 /* ATSC-MH */
1393 case DTV_ATSCMH_FIC_VER:
1394 tvp->u.data = fe->dtv_property_cache.atscmh_fic_ver;
1395 break;
1396 case DTV_ATSCMH_PARADE_ID:
1397 tvp->u.data = fe->dtv_property_cache.atscmh_parade_id;
1398 break;
1399 case DTV_ATSCMH_NOG:
1400 tvp->u.data = fe->dtv_property_cache.atscmh_nog;
1401 break;
1402 case DTV_ATSCMH_TNOG:
1403 tvp->u.data = fe->dtv_property_cache.atscmh_tnog;
1404 break;
1405 case DTV_ATSCMH_SGN:
1406 tvp->u.data = fe->dtv_property_cache.atscmh_sgn;
1407 break;
1408 case DTV_ATSCMH_PRC:
1409 tvp->u.data = fe->dtv_property_cache.atscmh_prc;
1410 break;
1411 case DTV_ATSCMH_RS_FRAME_MODE:
1412 tvp->u.data = fe->dtv_property_cache.atscmh_rs_frame_mode;
1413 break;
1414 case DTV_ATSCMH_RS_FRAME_ENSEMBLE:
1415 tvp->u.data = fe->dtv_property_cache.atscmh_rs_frame_ensemble;
1416 break;
1417 case DTV_ATSCMH_RS_CODE_MODE_PRI:
1418 tvp->u.data = fe->dtv_property_cache.atscmh_rs_code_mode_pri;
1419 break;
1420 case DTV_ATSCMH_RS_CODE_MODE_SEC:
1421 tvp->u.data = fe->dtv_property_cache.atscmh_rs_code_mode_sec;
1422 break;
1423 case DTV_ATSCMH_SCCC_BLOCK_MODE:
1424 tvp->u.data = fe->dtv_property_cache.atscmh_sccc_block_mode;
1425 break;
1426 case DTV_ATSCMH_SCCC_CODE_MODE_A:
1427 tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_a;
1428 break;
1429 case DTV_ATSCMH_SCCC_CODE_MODE_B:
1430 tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_b;
1431 break;
1432 case DTV_ATSCMH_SCCC_CODE_MODE_C:
1433 tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_c;
1434 break;
1435 case DTV_ATSCMH_SCCC_CODE_MODE_D:
1436 tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_d;
1437 break;
1438
1370 default: 1439 default:
1371 return -EINVAL; 1440 return -EINVAL;
1372 } 1441 }
@@ -1708,6 +1777,15 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1708 case DTV_DVBT2_PLP_ID: 1777 case DTV_DVBT2_PLP_ID:
1709 c->dvbt2_plp_id = tvp->u.data; 1778 c->dvbt2_plp_id = tvp->u.data;
1710 break; 1779 break;
1780
1781 /* ATSC-MH */
1782 case DTV_ATSCMH_PARADE_ID:
1783 fe->dtv_property_cache.atscmh_parade_id = tvp->u.data;
1784 break;
1785 case DTV_ATSCMH_RS_FRAME_ENSEMBLE:
1786 fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data;
1787 break;
1788
1711 default: 1789 default:
1712 return -EINVAL; 1790 return -EINVAL;
1713 } 1791 }
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index d63a8215fe03..e929d5697b87 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -372,6 +372,24 @@ struct dtv_frontend_properties {
372 372
373 /* DVB-T2 specifics */ 373 /* DVB-T2 specifics */
374 u32 dvbt2_plp_id; 374 u32 dvbt2_plp_id;
375
376 /* ATSC-MH specifics */
377 u8 atscmh_fic_ver;
378 u8 atscmh_parade_id;
379 u8 atscmh_nog;
380 u8 atscmh_tnog;
381 u8 atscmh_sgn;
382 u8 atscmh_prc;
383
384 u8 atscmh_rs_frame_mode;
385 u8 atscmh_rs_frame_ensemble;
386 u8 atscmh_rs_code_mode_pri;
387 u8 atscmh_rs_code_mode_sec;
388 u8 atscmh_sccc_block_mode;
389 u8 atscmh_sccc_code_mode_a;
390 u8 atscmh_sccc_code_mode_b;
391 u8 atscmh_sccc_code_mode_c;
392 u8 atscmh_sccc_code_mode_d;
375}; 393};
376 394
377struct dvb_frontend { 395struct dvb_frontend {
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 63bf45679f98..a26949336b3d 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -409,6 +409,7 @@ config DVB_USB_MXL111SF
409 tristate "MxL111SF DTV USB2.0 support" 409 tristate "MxL111SF DTV USB2.0 support"
410 depends on DVB_USB 410 depends on DVB_USB
411 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE 411 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
412 select DVB_LG2160 if !DVB_FE_CUSTOMISE
412 select VIDEO_TVEEPROM 413 select VIDEO_TVEEPROM
413 help 414 help
414 Say Y here to support the MxL111SF USB2.0 DTV receiver. 415 Say Y here to support the MxL111SF USB2.0 DTV receiver.
@@ -422,3 +423,15 @@ config DVB_USB_RTL28XXU
422 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 423 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
423 help 424 help
424 Say Y here to support the Realtek RTL28xxU DVB USB receiver. 425 Say Y here to support the Realtek RTL28xxU DVB USB receiver.
426
427config DVB_USB_AF9035
428 tristate "Afatech AF9035 DVB-T USB2.0 support"
429 depends on DVB_USB
430 select DVB_AF9033
431 select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
432 select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
433 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
434 select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
435 help
436 Say Y here to support the Afatech AF9035 based DVB USB receiver.
437
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index b76acb5387e6..b667ac39a4e3 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -110,6 +110,9 @@ obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
110dvb-usb-rtl28xxu-objs = rtl28xxu.o 110dvb-usb-rtl28xxu-objs = rtl28xxu.o
111obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o 111obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
112 112
113dvb-usb-af9035-objs = af9035.o
114obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
115
113ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 116ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
114ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/ 117ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
115# due to tuner-xc3028 118# due to tuner-xc3028
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 7e70ea50ef26..677fed79b01e 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -244,8 +244,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
244 u8 uninitialized_var(mbox), addr_len; 244 u8 uninitialized_var(mbox), addr_len;
245 struct req_t req; 245 struct req_t req;
246 246
247/* TODO: implement bus lock 247/*
248
249The bus lock is needed because there is two tuners both using same I2C-address. 248The bus lock is needed because there is two tuners both using same I2C-address.
250Due to that the only way to select correct tuner is use demodulator I2C-gate. 249Due to that the only way to select correct tuner is use demodulator I2C-gate.
251 250
@@ -789,7 +788,7 @@ static void af9015_set_remote_config(struct usb_device *udev,
789 /* try to load remote based USB ID */ 788 /* try to load remote based USB ID */
790 if (!props->rc.core.rc_codes) 789 if (!props->rc.core.rc_codes)
791 props->rc.core.rc_codes = af9015_rc_setup_match( 790 props->rc.core.rc_codes = af9015_rc_setup_match(
792 (vid << 16) + pid, af9015_rc_setup_usbids); 791 (vid << 16) | pid, af9015_rc_setup_usbids);
793 792
794 /* try to load remote based USB iManufacturer string */ 793 /* try to load remote based USB iManufacturer string */
795 if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) { 794 if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
@@ -1220,8 +1219,8 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1220 } 1219 }
1221 1220
1222 /* attach demodulator */ 1221 /* attach demodulator */
1223 adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], 1222 adap->fe_adap[0].fe = dvb_attach(af9013_attach,
1224 &adap->dev->i2c_adap); 1223 &af9015_af9013_config[adap->id], &adap->dev->i2c_adap);
1225 1224
1226 /* 1225 /*
1227 * AF9015 firmware does not like if it gets interrupted by I2C adapter 1226 * AF9015 firmware does not like if it gets interrupted by I2C adapter
@@ -1324,14 +1323,15 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1324 switch (af9015_af9013_config[adap->id].tuner) { 1323 switch (af9015_af9013_config[adap->id].tuner) {
1325 case AF9013_TUNER_MT2060: 1324 case AF9013_TUNER_MT2060:
1326 case AF9013_TUNER_MT2060_2: 1325 case AF9013_TUNER_MT2060_2:
1327 ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 1326 ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe,
1328 &af9015_mt2060_config, 1327 &adap->dev->i2c_adap, &af9015_mt2060_config,
1329 af9015_config.mt2060_if1[adap->id]) 1328 af9015_config.mt2060_if1[adap->id])
1330 == NULL ? -ENODEV : 0; 1329 == NULL ? -ENODEV : 0;
1331 break; 1330 break;
1332 case AF9013_TUNER_QT1010: 1331 case AF9013_TUNER_QT1010:
1333 case AF9013_TUNER_QT1010A: 1332 case AF9013_TUNER_QT1010A:
1334 ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 1333 ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe,
1334 &adap->dev->i2c_adap,
1335 &af9015_qt1010_config) == NULL ? -ENODEV : 0; 1335 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1336 break; 1336 break;
1337 case AF9013_TUNER_TDA18271: 1337 case AF9013_TUNER_TDA18271:
@@ -1434,69 +1434,85 @@ enum af9015_usb_table_entry {
1434}; 1434};
1435 1435
1436static struct usb_device_id af9015_usb_table[] = { 1436static struct usb_device_id af9015_usb_table[] = {
1437 [AFATECH_9015] = 1437 [AFATECH_9015] = {
1438 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, 1438 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1439 [AFATECH_9016] = 1439 [AFATECH_9016] = {
1440 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, 1440 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1441 [WINFAST_DTV_GOLD] = 1441 [WINFAST_DTV_GOLD] = {
1442 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, 1442 USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1443 [PINNACLE_PCTV_71E] = 1443 [PINNACLE_PCTV_71E] = {
1444 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, 1444 USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1445 [KWORLD_PLUSTV_399U] = 1445 [KWORLD_PLUSTV_399U] = {
1446 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, 1446 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1447 [TINYTWIN] = {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)}, 1447 [TINYTWIN] = {
1448 [AZUREWAVE_TU700] = 1448 USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)},
1449 {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)}, 1449 [AZUREWAVE_TU700] = {
1450 [TERRATEC_AF9015] = {USB_DEVICE(USB_VID_TERRATEC, 1450 USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)},
1451 [TERRATEC_AF9015] = {
1452 USB_DEVICE(USB_VID_TERRATEC,
1451 USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, 1453 USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1452 [KWORLD_PLUSTV_PC160] = 1454 [KWORLD_PLUSTV_PC160] = {
1453 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, 1455 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1454 [AVERTV_VOLAR_X] = 1456 [AVERTV_VOLAR_X] = {
1455 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, 1457 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1456 [XTENSIONS_380U] = 1458 [XTENSIONS_380U] = {
1457 {USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, 1459 USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1458 [MSI_DIGIVOX_DUO] = 1460 [MSI_DIGIVOX_DUO] = {
1459 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, 1461 USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1460 [AVERTV_VOLAR_X_REV2] = 1462 [AVERTV_VOLAR_X_REV2] = {
1461 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, 1463 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
1462 [TELESTAR_STARSTICK_2] = 1464 [TELESTAR_STARSTICK_2] = {
1463 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, 1465 USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
1464 [AVERMEDIA_A309_USB] = 1466 [AVERMEDIA_A309_USB] = {
1465 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, 1467 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
1466 [MSI_DIGIVOX_MINI_III] = 1468 [MSI_DIGIVOX_MINI_III] = {
1467 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, 1469 USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
1468 [KWORLD_E396] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, 1470 [KWORLD_E396] = {
1469 [KWORLD_E39B] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, 1471 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
1470 [KWORLD_E395] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)}, 1472 [KWORLD_E39B] = {
1471 [TREKSTOR_DVBT] = {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)}, 1473 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
1472 [AVERTV_A850] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)}, 1474 [KWORLD_E395] = {
1473 [AVERTV_A805] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)}, 1475 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
1474 [CONCEPTRONIC_CTVDIGRCU] = 1476 [TREKSTOR_DVBT] = {
1475 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, 1477 USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
1476 [KWORLD_MC810] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, 1478 [AVERTV_A850] = {
1477 [GENIUS_TVGO_DVB_T03] = 1479 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
1478 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, 1480 [AVERTV_A805] = {
1479 [KWORLD_399U_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, 1481 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
1480 [KWORLD_PC160_T] = 1482 [CONCEPTRONIC_CTVDIGRCU] = {
1481 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, 1483 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
1482 [SVEON_STV20] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, 1484 [KWORLD_MC810] = {
1483 [TINYTWIN_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, 1485 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
1484 [WINFAST_DTV2000DS] = 1486 [GENIUS_TVGO_DVB_T03] = {
1485 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, 1487 USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
1486 [KWORLD_UB383_T] = 1488 [KWORLD_399U_2] = {
1487 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, 1489 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
1488 [KWORLD_E39A] = 1490 [KWORLD_PC160_T] = {
1489 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, 1491 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
1490 [AVERMEDIA_A815M] = 1492 [SVEON_STV20] = {
1491 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, 1493 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
1492 [CINERGY_T_STICK_RC] = {USB_DEVICE(USB_VID_TERRATEC, 1494 [TINYTWIN_2] = {
1495 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
1496 [WINFAST_DTV2000DS] = {
1497 USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
1498 [KWORLD_UB383_T] = {
1499 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
1500 [KWORLD_E39A] = {
1501 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
1502 [AVERMEDIA_A815M] = {
1503 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
1504 [CINERGY_T_STICK_RC] = {
1505 USB_DEVICE(USB_VID_TERRATEC,
1493 USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, 1506 USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
1494 [CINERGY_T_DUAL_RC] = {USB_DEVICE(USB_VID_TERRATEC, 1507 [CINERGY_T_DUAL_RC] = {
1508 USB_DEVICE(USB_VID_TERRATEC,
1495 USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, 1509 USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
1496 [AVERTV_A850T] = 1510 [AVERTV_A850T] = {
1497 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, 1511 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
1498 [TINYTWIN_3] = {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, 1512 [TINYTWIN_3] = {
1499 [SVEON_STV22] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)}, 1513 USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
1514 [SVEON_STV22] = {
1515 USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)},
1500 { } 1516 { }
1501}; 1517};
1502MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1518MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1516,43 +1532,44 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1516 .num_adapters = 2, 1532 .num_adapters = 2,
1517 .adapter = { 1533 .adapter = {
1518 { 1534 {
1519 .num_frontends = 1, 1535 .num_frontends = 1,
1520 .fe = {{ 1536 .fe = {
1521 .caps = DVB_USB_ADAP_HAS_PID_FILTER | 1537 {
1522 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1538 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1523 1539 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1524 .pid_filter_count = 32, 1540
1525 .pid_filter = af9015_pid_filter, 1541 .pid_filter_count = 32,
1526 .pid_filter_ctrl = af9015_pid_filter_ctrl, 1542 .pid_filter = af9015_pid_filter,
1527 1543 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1528 .frontend_attach = 1544
1529 af9015_af9013_frontend_attach, 1545 .frontend_attach = af9015_af9013_frontend_attach,
1530 .tuner_attach = af9015_tuner_attach, 1546 .tuner_attach = af9015_tuner_attach,
1531 .stream = { 1547 .stream = {
1532 .type = USB_BULK, 1548 .type = USB_BULK,
1533 .count = 6, 1549 .count = 6,
1534 .endpoint = 0x84, 1550 .endpoint = 0x84,
1551 },
1552 }
1535 }, 1553 },
1536 }},
1537 }, 1554 },
1538 { 1555 {
1539 .num_frontends = 1, 1556 .num_frontends = 1,
1540 .fe = {{ 1557 .fe = {
1541 .frontend_attach = 1558 {
1542 af9015_af9013_frontend_attach, 1559 .frontend_attach = af9015_af9013_frontend_attach,
1543 .tuner_attach = af9015_tuner_attach, 1560 .tuner_attach = af9015_tuner_attach,
1544 .stream = { 1561 .stream = {
1545 .type = USB_BULK, 1562 .type = USB_BULK,
1546 .count = 6, 1563 .count = 6,
1547 .endpoint = 0x85, 1564 .endpoint = 0x85,
1548 .u = { 1565 .u = {
1549 .bulk = { 1566 .bulk = {
1550 .buffersize = 1567 .buffersize = TS_USB20_FRAME_SIZE,
1551 TS_USB20_FRAME_SIZE, 1568 }
1552 } 1569 }
1570 },
1553 } 1571 }
1554 }, 1572 },
1555 }},
1556 } 1573 }
1557 }, 1574 },
1558 1575
@@ -1575,102 +1592,67 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1575 .cold_ids = { 1592 .cold_ids = {
1576 &af9015_usb_table[AFATECH_9015], 1593 &af9015_usb_table[AFATECH_9015],
1577 &af9015_usb_table[AFATECH_9016], 1594 &af9015_usb_table[AFATECH_9016],
1578 NULL
1579 }, 1595 },
1580 .warm_ids = {NULL}, 1596 }, {
1581 },
1582 {
1583 .name = "Leadtek WinFast DTV Dongle Gold", 1597 .name = "Leadtek WinFast DTV Dongle Gold",
1584 .cold_ids = { 1598 .cold_ids = {
1585 &af9015_usb_table[WINFAST_DTV_GOLD], 1599 &af9015_usb_table[WINFAST_DTV_GOLD],
1586 NULL
1587 }, 1600 },
1588 .warm_ids = {NULL}, 1601 }, {
1589 },
1590 {
1591 .name = "Pinnacle PCTV 71e", 1602 .name = "Pinnacle PCTV 71e",
1592 .cold_ids = { 1603 .cold_ids = {
1593 &af9015_usb_table[PINNACLE_PCTV_71E], 1604 &af9015_usb_table[PINNACLE_PCTV_71E],
1594 NULL
1595 }, 1605 },
1596 .warm_ids = {NULL}, 1606 }, {
1597 },
1598 {
1599 .name = "KWorld PlusTV Dual DVB-T Stick " \ 1607 .name = "KWorld PlusTV Dual DVB-T Stick " \
1600 "(DVB-T 399U)", 1608 "(DVB-T 399U)",
1601 .cold_ids = { 1609 .cold_ids = {
1602 &af9015_usb_table[KWORLD_PLUSTV_399U], 1610 &af9015_usb_table[KWORLD_PLUSTV_399U],
1603 &af9015_usb_table[KWORLD_399U_2], 1611 &af9015_usb_table[KWORLD_399U_2],
1604 NULL
1605 }, 1612 },
1606 .warm_ids = {NULL}, 1613 }, {
1607 },
1608 {
1609 .name = "DigitalNow TinyTwin DVB-T Receiver", 1614 .name = "DigitalNow TinyTwin DVB-T Receiver",
1610 .cold_ids = { 1615 .cold_ids = {
1611 &af9015_usb_table[TINYTWIN], 1616 &af9015_usb_table[TINYTWIN],
1612 &af9015_usb_table[TINYTWIN_2], 1617 &af9015_usb_table[TINYTWIN_2],
1613 &af9015_usb_table[TINYTWIN_3], 1618 &af9015_usb_table[TINYTWIN_3],
1614 NULL
1615 }, 1619 },
1616 .warm_ids = {NULL}, 1620 }, {
1617 },
1618 {
1619 .name = "TwinHan AzureWave AD-TU700(704J)", 1621 .name = "TwinHan AzureWave AD-TU700(704J)",
1620 .cold_ids = { 1622 .cold_ids = {
1621 &af9015_usb_table[AZUREWAVE_TU700], 1623 &af9015_usb_table[AZUREWAVE_TU700],
1622 NULL
1623 }, 1624 },
1624 .warm_ids = {NULL}, 1625 }, {
1625 },
1626 {
1627 .name = "TerraTec Cinergy T USB XE", 1626 .name = "TerraTec Cinergy T USB XE",
1628 .cold_ids = { 1627 .cold_ids = {
1629 &af9015_usb_table[TERRATEC_AF9015], 1628 &af9015_usb_table[TERRATEC_AF9015],
1630 NULL
1631 }, 1629 },
1632 .warm_ids = {NULL}, 1630 }, {
1633 },
1634 {
1635 .name = "KWorld PlusTV Dual DVB-T PCI " \ 1631 .name = "KWorld PlusTV Dual DVB-T PCI " \
1636 "(DVB-T PC160-2T)", 1632 "(DVB-T PC160-2T)",
1637 .cold_ids = { 1633 .cold_ids = {
1638 &af9015_usb_table[KWORLD_PLUSTV_PC160], 1634 &af9015_usb_table[KWORLD_PLUSTV_PC160],
1639 NULL
1640 }, 1635 },
1641 .warm_ids = {NULL}, 1636 }, {
1642 },
1643 {
1644 .name = "AVerMedia AVerTV DVB-T Volar X", 1637 .name = "AVerMedia AVerTV DVB-T Volar X",
1645 .cold_ids = { 1638 .cold_ids = {
1646 &af9015_usb_table[AVERTV_VOLAR_X], 1639 &af9015_usb_table[AVERTV_VOLAR_X],
1647 NULL
1648 }, 1640 },
1649 .warm_ids = {NULL}, 1641 }, {
1650 },
1651 {
1652 .name = "TerraTec Cinergy T Stick RC", 1642 .name = "TerraTec Cinergy T Stick RC",
1653 .cold_ids = { 1643 .cold_ids = {
1654 &af9015_usb_table[CINERGY_T_STICK_RC], 1644 &af9015_usb_table[CINERGY_T_STICK_RC],
1655 NULL
1656 }, 1645 },
1657 .warm_ids = {NULL}, 1646 }, {
1658 },
1659 {
1660 .name = "TerraTec Cinergy T Stick Dual RC", 1647 .name = "TerraTec Cinergy T Stick Dual RC",
1661 .cold_ids = { 1648 .cold_ids = {
1662 &af9015_usb_table[CINERGY_T_DUAL_RC], 1649 &af9015_usb_table[CINERGY_T_DUAL_RC],
1663 NULL
1664 }, 1650 },
1665 .warm_ids = {NULL}, 1651 }, {
1666 },
1667 {
1668 .name = "AverMedia AVerTV Red HD+ (A850T)", 1652 .name = "AverMedia AVerTV Red HD+ (A850T)",
1669 .cold_ids = { 1653 .cold_ids = {
1670 &af9015_usb_table[AVERTV_A850T], 1654 &af9015_usb_table[AVERTV_A850T],
1671 NULL
1672 }, 1655 },
1673 .warm_ids = {NULL},
1674 }, 1656 },
1675 } 1657 }
1676 }, { 1658 }, {
@@ -1686,43 +1668,44 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1686 .num_adapters = 2, 1668 .num_adapters = 2,
1687 .adapter = { 1669 .adapter = {
1688 { 1670 {
1689 .num_frontends = 1, 1671 .num_frontends = 1,
1690 .fe = {{ 1672 .fe = {
1691 .caps = DVB_USB_ADAP_HAS_PID_FILTER | 1673 {
1692 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1674 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1693 1675 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1694 .pid_filter_count = 32, 1676
1695 .pid_filter = af9015_pid_filter, 1677 .pid_filter_count = 32,
1696 .pid_filter_ctrl = af9015_pid_filter_ctrl, 1678 .pid_filter = af9015_pid_filter,
1697 1679 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1698 .frontend_attach = 1680
1699 af9015_af9013_frontend_attach, 1681 .frontend_attach = af9015_af9013_frontend_attach,
1700 .tuner_attach = af9015_tuner_attach, 1682 .tuner_attach = af9015_tuner_attach,
1701 .stream = { 1683 .stream = {
1702 .type = USB_BULK, 1684 .type = USB_BULK,
1703 .count = 6, 1685 .count = 6,
1704 .endpoint = 0x84, 1686 .endpoint = 0x84,
1687 },
1688 }
1705 }, 1689 },
1706 }},
1707 }, 1690 },
1708 { 1691 {
1709 .num_frontends = 1, 1692 .num_frontends = 1,
1710 .fe = {{ 1693 .fe = {
1711 .frontend_attach = 1694 {
1712 af9015_af9013_frontend_attach, 1695 .frontend_attach = af9015_af9013_frontend_attach,
1713 .tuner_attach = af9015_tuner_attach, 1696 .tuner_attach = af9015_tuner_attach,
1714 .stream = { 1697 .stream = {
1715 .type = USB_BULK, 1698 .type = USB_BULK,
1716 .count = 6, 1699 .count = 6,
1717 .endpoint = 0x85, 1700 .endpoint = 0x85,
1718 .u = { 1701 .u = {
1719 .bulk = { 1702 .bulk = {
1720 .buffersize = 1703 .buffersize = TS_USB20_FRAME_SIZE,
1721 TS_USB20_FRAME_SIZE, 1704 }
1722 } 1705 }
1706 },
1723 } 1707 }
1724 }, 1708 },
1725 }},
1726 } 1709 }
1727 }, 1710 },
1728 1711
@@ -1744,51 +1727,33 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1744 .name = "Xtensions XD-380", 1727 .name = "Xtensions XD-380",
1745 .cold_ids = { 1728 .cold_ids = {
1746 &af9015_usb_table[XTENSIONS_380U], 1729 &af9015_usb_table[XTENSIONS_380U],
1747 NULL
1748 }, 1730 },
1749 .warm_ids = {NULL}, 1731 }, {
1750 },
1751 {
1752 .name = "MSI DIGIVOX Duo", 1732 .name = "MSI DIGIVOX Duo",
1753 .cold_ids = { 1733 .cold_ids = {
1754 &af9015_usb_table[MSI_DIGIVOX_DUO], 1734 &af9015_usb_table[MSI_DIGIVOX_DUO],
1755 NULL
1756 }, 1735 },
1757 .warm_ids = {NULL}, 1736 }, {
1758 },
1759 {
1760 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T", 1737 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1761 .cold_ids = { 1738 .cold_ids = {
1762 &af9015_usb_table[AVERTV_VOLAR_X_REV2], 1739 &af9015_usb_table[AVERTV_VOLAR_X_REV2],
1763 NULL
1764 }, 1740 },
1765 .warm_ids = {NULL}, 1741 }, {
1766 },
1767 {
1768 .name = "Telestar Starstick 2", 1742 .name = "Telestar Starstick 2",
1769 .cold_ids = { 1743 .cold_ids = {
1770 &af9015_usb_table[TELESTAR_STARSTICK_2], 1744 &af9015_usb_table[TELESTAR_STARSTICK_2],
1771 NULL
1772 }, 1745 },
1773 .warm_ids = {NULL}, 1746 }, {
1774 },
1775 {
1776 .name = "AVerMedia A309", 1747 .name = "AVerMedia A309",
1777 .cold_ids = { 1748 .cold_ids = {
1778 &af9015_usb_table[AVERMEDIA_A309_USB], 1749 &af9015_usb_table[AVERMEDIA_A309_USB],
1779 NULL
1780 }, 1750 },
1781 .warm_ids = {NULL}, 1751 }, {
1782 },
1783 {
1784 .name = "MSI Digi VOX mini III", 1752 .name = "MSI Digi VOX mini III",
1785 .cold_ids = { 1753 .cold_ids = {
1786 &af9015_usb_table[MSI_DIGIVOX_MINI_III], 1754 &af9015_usb_table[MSI_DIGIVOX_MINI_III],
1787 NULL
1788 }, 1755 },
1789 .warm_ids = {NULL}, 1756 }, {
1790 },
1791 {
1792 .name = "KWorld USB DVB-T TV Stick II " \ 1757 .name = "KWorld USB DVB-T TV Stick II " \
1793 "(VS-DVB-T 395U)", 1758 "(VS-DVB-T 395U)",
1794 .cold_ids = { 1759 .cold_ids = {
@@ -1796,34 +1761,23 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1796 &af9015_usb_table[KWORLD_E39B], 1761 &af9015_usb_table[KWORLD_E39B],
1797 &af9015_usb_table[KWORLD_E395], 1762 &af9015_usb_table[KWORLD_E395],
1798 &af9015_usb_table[KWORLD_E39A], 1763 &af9015_usb_table[KWORLD_E39A],
1799 NULL
1800 }, 1764 },
1801 .warm_ids = {NULL}, 1765 }, {
1802 },
1803 {
1804 .name = "TrekStor DVB-T USB Stick", 1766 .name = "TrekStor DVB-T USB Stick",
1805 .cold_ids = { 1767 .cold_ids = {
1806 &af9015_usb_table[TREKSTOR_DVBT], 1768 &af9015_usb_table[TREKSTOR_DVBT],
1807 NULL
1808 }, 1769 },
1809 .warm_ids = {NULL}, 1770 }, {
1810 },
1811 {
1812 .name = "AverMedia AVerTV Volar Black HD " \ 1771 .name = "AverMedia AVerTV Volar Black HD " \
1813 "(A850)", 1772 "(A850)",
1814 .cold_ids = { 1773 .cold_ids = {
1815 &af9015_usb_table[AVERTV_A850], 1774 &af9015_usb_table[AVERTV_A850],
1816 NULL
1817 }, 1775 },
1818 .warm_ids = {NULL}, 1776 }, {
1819 },
1820 {
1821 .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV", 1777 .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV",
1822 .cold_ids = { 1778 .cold_ids = {
1823 &af9015_usb_table[SVEON_STV22], 1779 &af9015_usb_table[SVEON_STV22],
1824 NULL
1825 }, 1780 },
1826 .warm_ids = {NULL},
1827 }, 1781 },
1828 } 1782 }
1829 }, { 1783 }, {
@@ -1839,43 +1793,44 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1839 .num_adapters = 2, 1793 .num_adapters = 2,
1840 .adapter = { 1794 .adapter = {
1841 { 1795 {
1842 .num_frontends = 1, 1796 .num_frontends = 1,
1843 .fe = {{ 1797 .fe = {
1844 .caps = DVB_USB_ADAP_HAS_PID_FILTER | 1798 {
1845 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1799 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1846 1800 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1847 .pid_filter_count = 32, 1801
1848 .pid_filter = af9015_pid_filter, 1802 .pid_filter_count = 32,
1849 .pid_filter_ctrl = af9015_pid_filter_ctrl, 1803 .pid_filter = af9015_pid_filter,
1850 1804 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1851 .frontend_attach = 1805
1852 af9015_af9013_frontend_attach, 1806 .frontend_attach = af9015_af9013_frontend_attach,
1853 .tuner_attach = af9015_tuner_attach, 1807 .tuner_attach = af9015_tuner_attach,
1854 .stream = { 1808 .stream = {
1855 .type = USB_BULK, 1809 .type = USB_BULK,
1856 .count = 6, 1810 .count = 6,
1857 .endpoint = 0x84, 1811 .endpoint = 0x84,
1812 },
1813 }
1858 }, 1814 },
1859 }},
1860 }, 1815 },
1861 { 1816 {
1862 .num_frontends = 1, 1817 .num_frontends = 1,
1863 .fe = {{ 1818 .fe = {
1864 .frontend_attach = 1819 {
1865 af9015_af9013_frontend_attach, 1820 .frontend_attach = af9015_af9013_frontend_attach,
1866 .tuner_attach = af9015_tuner_attach, 1821 .tuner_attach = af9015_tuner_attach,
1867 .stream = { 1822 .stream = {
1868 .type = USB_BULK, 1823 .type = USB_BULK,
1869 .count = 6, 1824 .count = 6,
1870 .endpoint = 0x85, 1825 .endpoint = 0x85,
1871 .u = { 1826 .u = {
1872 .bulk = { 1827 .bulk = {
1873 .buffersize = 1828 .buffersize = TS_USB20_FRAME_SIZE,
1874 TS_USB20_FRAME_SIZE, 1829 }
1875 } 1830 }
1831 },
1876 } 1832 }
1877 }, 1833 },
1878 }},
1879 } 1834 }
1880 }, 1835 },
1881 1836
@@ -1897,76 +1852,50 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1897 .name = "AverMedia AVerTV Volar GPS 805 (A805)", 1852 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
1898 .cold_ids = { 1853 .cold_ids = {
1899 &af9015_usb_table[AVERTV_A805], 1854 &af9015_usb_table[AVERTV_A805],
1900 NULL
1901 }, 1855 },
1902 .warm_ids = {NULL}, 1856 }, {
1903 },
1904 {
1905 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \ 1857 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
1906 "V3.0", 1858 "V3.0",
1907 .cold_ids = { 1859 .cold_ids = {
1908 &af9015_usb_table[CONCEPTRONIC_CTVDIGRCU], 1860 &af9015_usb_table[CONCEPTRONIC_CTVDIGRCU],
1909 NULL
1910 }, 1861 },
1911 .warm_ids = {NULL}, 1862 }, {
1912 },
1913 {
1914 .name = "KWorld Digial MC-810", 1863 .name = "KWorld Digial MC-810",
1915 .cold_ids = { 1864 .cold_ids = {
1916 &af9015_usb_table[KWORLD_MC810], 1865 &af9015_usb_table[KWORLD_MC810],
1917 NULL
1918 }, 1866 },
1919 .warm_ids = {NULL}, 1867 }, {
1920 },
1921 {
1922 .name = "Genius TVGo DVB-T03", 1868 .name = "Genius TVGo DVB-T03",
1923 .cold_ids = { 1869 .cold_ids = {
1924 &af9015_usb_table[GENIUS_TVGO_DVB_T03], 1870 &af9015_usb_table[GENIUS_TVGO_DVB_T03],
1925 NULL
1926 }, 1871 },
1927 .warm_ids = {NULL}, 1872 }, {
1928 },
1929 {
1930 .name = "KWorld PlusTV DVB-T PCI Pro Card " \ 1873 .name = "KWorld PlusTV DVB-T PCI Pro Card " \
1931 "(DVB-T PC160-T)", 1874 "(DVB-T PC160-T)",
1932 .cold_ids = { 1875 .cold_ids = {
1933 &af9015_usb_table[KWORLD_PC160_T], 1876 &af9015_usb_table[KWORLD_PC160_T],
1934 NULL
1935 }, 1877 },
1936 .warm_ids = {NULL}, 1878 }, {
1937 },
1938 {
1939 .name = "Sveon STV20 Tuner USB DVB-T HDTV", 1879 .name = "Sveon STV20 Tuner USB DVB-T HDTV",
1940 .cold_ids = { 1880 .cold_ids = {
1941 &af9015_usb_table[SVEON_STV20], 1881 &af9015_usb_table[SVEON_STV20],
1942 NULL
1943 }, 1882 },
1944 .warm_ids = {NULL}, 1883 }, {
1945 },
1946 {
1947 .name = "Leadtek WinFast DTV2000DS", 1884 .name = "Leadtek WinFast DTV2000DS",
1948 .cold_ids = { 1885 .cold_ids = {
1949 &af9015_usb_table[WINFAST_DTV2000DS], 1886 &af9015_usb_table[WINFAST_DTV2000DS],
1950 NULL
1951 }, 1887 },
1952 .warm_ids = {NULL}, 1888 }, {
1953 },
1954 {
1955 .name = "KWorld USB DVB-T Stick Mobile " \ 1889 .name = "KWorld USB DVB-T Stick Mobile " \
1956 "(UB383-T)", 1890 "(UB383-T)",
1957 .cold_ids = { 1891 .cold_ids = {
1958 &af9015_usb_table[KWORLD_UB383_T], 1892 &af9015_usb_table[KWORLD_UB383_T],
1959 NULL
1960 }, 1893 },
1961 .warm_ids = {NULL}, 1894 }, {
1962 },
1963 {
1964 .name = "AverMedia AVerTV Volar M (A815Mac)", 1895 .name = "AverMedia AVerTV Volar M (A815Mac)",
1965 .cold_ids = { 1896 .cold_ids = {
1966 &af9015_usb_table[AVERMEDIA_A815M], 1897 &af9015_usb_table[AVERMEDIA_A815M],
1967 NULL
1968 }, 1898 },
1969 .warm_ids = {NULL},
1970 }, 1899 },
1971 } 1900 }
1972 }, 1901 },
@@ -2019,5 +1948,5 @@ static struct usb_driver af9015_usb_driver = {
2019module_usb_driver(af9015_usb_driver); 1948module_usb_driver(af9015_usb_driver);
2020 1949
2021MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 1950MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
2022MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T"); 1951MODULE_DESCRIPTION("Afatech AF9015 driver");
2023MODULE_LICENSE("GPL"); 1952MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9035.c b/drivers/media/dvb/dvb-usb/af9035.c
new file mode 100644
index 000000000000..e83b39d3993c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9035.c
@@ -0,0 +1,1242 @@
1/*
2 * Afatech AF9035 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "af9035.h"
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25static DEFINE_MUTEX(af9035_usb_mutex);
26static struct dvb_usb_device_properties af9035_properties[2];
27static int af9035_properties_count = ARRAY_SIZE(af9035_properties);
28
29static u16 af9035_checksum(const u8 *buf, size_t len)
30{
31 size_t i;
32 u16 checksum = 0;
33
34 for (i = 1; i < len; i++) {
35 if (i % 2)
36 checksum += buf[i] << 8;
37 else
38 checksum += buf[i];
39 }
40 checksum = ~checksum;
41
42 return checksum;
43}
44
45static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req)
46{
47#define BUF_LEN 64
48#define REQ_HDR_LEN 4 /* send header size */
49#define ACK_HDR_LEN 3 /* rece header size */
50#define CHECKSUM_LEN 2
51#define USB_TIMEOUT 2000
52
53 int ret, msg_len, act_len;
54 u8 buf[BUF_LEN];
55 static u8 seq; /* packet sequence number */
56 u16 checksum, tmp_checksum;
57
58 /* buffer overflow check */
59 if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
60 req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
61 pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
62 req->wlen, req->rlen);
63 return -EINVAL;
64 }
65
66 if (mutex_lock_interruptible(&af9035_usb_mutex) < 0)
67 return -EAGAIN;
68
69 buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
70 buf[1] = req->mbox;
71 buf[2] = req->cmd;
72 buf[3] = seq++;
73 if (req->wlen)
74 memcpy(&buf[4], req->wbuf, req->wlen);
75
76 /* calc and add checksum */
77 checksum = af9035_checksum(buf, buf[0] - 1);
78 buf[buf[0] - 1] = (checksum >> 8);
79 buf[buf[0] - 0] = (checksum & 0xff);
80
81 msg_len = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN ;
82
83 /* send req */
84 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
85 &act_len, USB_TIMEOUT);
86 if (ret < 0)
87 err("bulk message failed=%d (%d/%d)", ret, msg_len, act_len);
88 else
89 if (act_len != msg_len)
90 ret = -EIO; /* all data is not send */
91 if (ret < 0)
92 goto err_mutex_unlock;
93
94 /* no ack for those packets */
95 if (req->cmd == CMD_FW_DL)
96 goto exit_mutex_unlock;
97
98 /* receive ack and data if read req */
99 msg_len = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
100 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
101 &act_len, USB_TIMEOUT);
102 if (ret < 0) {
103 err("recv bulk message failed=%d", ret);
104 ret = -EIO;
105 goto err_mutex_unlock;
106 }
107
108 if (act_len != msg_len) {
109 err("recv bulk message truncated (%d != %d)", act_len, msg_len);
110 ret = -EIO;
111 goto err_mutex_unlock;
112 }
113
114 /* verify checksum */
115 checksum = af9035_checksum(buf, act_len - 2);
116 tmp_checksum = (buf[act_len - 2] << 8) | buf[act_len - 1];
117 if (tmp_checksum != checksum) {
118 err("%s: command=%02x checksum mismatch (%04x != %04x)",
119 __func__, req->cmd, tmp_checksum, checksum);
120 ret = -EIO;
121 goto err_mutex_unlock;
122 }
123
124 /* check status */
125 if (buf[2]) {
126 pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
127 req->cmd, buf[2]);
128 ret = -EIO;
129 goto err_mutex_unlock;
130 }
131
132 /* read request, copy returned data to return buf */
133 if (req->rlen)
134 memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
135
136err_mutex_unlock:
137exit_mutex_unlock:
138 mutex_unlock(&af9035_usb_mutex);
139
140 return ret;
141}
142
143/* write multiple registers */
144static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
145{
146 u8 wbuf[6 + len];
147 u8 mbox = (reg >> 16) & 0xff;
148 struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
149
150 wbuf[0] = len;
151 wbuf[1] = 2;
152 wbuf[2] = 0;
153 wbuf[3] = 0;
154 wbuf[4] = (reg >> 8) & 0xff;
155 wbuf[5] = (reg >> 0) & 0xff;
156 memcpy(&wbuf[6], val, len);
157
158 return af9035_ctrl_msg(d->udev, &req);
159}
160
161/* read multiple registers */
162static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
163{
164 u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
165 u8 mbox = (reg >> 16) & 0xff;
166 struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
167
168 return af9035_ctrl_msg(d->udev, &req);
169}
170
171/* write single register */
172static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
173{
174 return af9035_wr_regs(d, reg, &val, 1);
175}
176
177/* read single register */
178static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
179{
180 return af9035_rd_regs(d, reg, val, 1);
181}
182
183/* write single register with mask */
184static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
185 u8 mask)
186{
187 int ret;
188 u8 tmp;
189
190 /* no need for read if whole reg is written */
191 if (mask != 0xff) {
192 ret = af9035_rd_regs(d, reg, &tmp, 1);
193 if (ret)
194 return ret;
195
196 val &= mask;
197 tmp &= ~mask;
198 val |= tmp;
199 }
200
201 return af9035_wr_regs(d, reg, &val, 1);
202}
203
204static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
205 struct i2c_msg msg[], int num)
206{
207 struct dvb_usb_device *d = i2c_get_adapdata(adap);
208 struct state *state = d->priv;
209 int ret;
210
211 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
212 return -EAGAIN;
213
214 /*
215 * I2C sub header is 5 bytes long. Meaning of those bytes are:
216 * 0: data len
217 * 1: I2C addr << 1
218 * 2: reg addr len
219 * byte 3 and 4 can be used as reg addr
220 * 3: reg addr MSB
221 * used when reg addr len is set to 2
222 * 4: reg addr LSB
223 * used when reg addr len is set to 1 or 2
224 *
225 * For the simplify we do not use register addr at all.
226 * NOTE: As a firmware knows tuner type there is very small possibility
227 * there could be some tuner I2C hacks done by firmware and this may
228 * lead problems if firmware expects those bytes are used.
229 */
230 if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
231 (msg[1].flags & I2C_M_RD)) {
232 if (msg[0].len > 40 || msg[1].len > 40) {
233 /* TODO: correct limits > 40 */
234 ret = -EOPNOTSUPP;
235 } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
236 /* integrated demod */
237 u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
238 msg[0].buf[2];
239 ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
240 msg[1].len);
241 } else {
242 /* I2C */
243 u8 buf[5 + msg[0].len];
244 struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
245 buf, msg[1].len, msg[1].buf };
246 buf[0] = msg[1].len;
247 buf[1] = msg[0].addr << 1;
248 buf[2] = 0x00; /* reg addr len */
249 buf[3] = 0x00; /* reg addr MSB */
250 buf[4] = 0x00; /* reg addr LSB */
251 memcpy(&buf[5], msg[0].buf, msg[0].len);
252 ret = af9035_ctrl_msg(d->udev, &req);
253 }
254 } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
255 if (msg[0].len > 40) {
256 /* TODO: correct limits > 40 */
257 ret = -EOPNOTSUPP;
258 } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
259 /* integrated demod */
260 u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
261 msg[0].buf[2];
262 ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
263 msg[0].len - 3);
264 } else {
265 /* I2C */
266 u8 buf[5 + msg[0].len];
267 struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
268 0, NULL };
269 buf[0] = msg[0].len;
270 buf[1] = msg[0].addr << 1;
271 buf[2] = 0x00; /* reg addr len */
272 buf[3] = 0x00; /* reg addr MSB */
273 buf[4] = 0x00; /* reg addr LSB */
274 memcpy(&buf[5], msg[0].buf, msg[0].len);
275 ret = af9035_ctrl_msg(d->udev, &req);
276 }
277 } else {
278 /*
279 * We support only two kind of I2C transactions:
280 * 1) 1 x read + 1 x write
281 * 2) 1 x write
282 */
283 ret = -EOPNOTSUPP;
284 }
285
286 mutex_unlock(&d->i2c_mutex);
287
288 if (ret < 0)
289 return ret;
290 else
291 return num;
292}
293
294static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
295{
296 return I2C_FUNC_I2C;
297}
298
299static struct i2c_algorithm af9035_i2c_algo = {
300 .master_xfer = af9035_i2c_master_xfer,
301 .functionality = af9035_i2c_functionality,
302};
303
304#define AF9035_POLL 250
305static int af9035_rc_query(struct dvb_usb_device *d)
306{
307 unsigned int key;
308 unsigned char b[4];
309 int ret;
310 struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
311
312 ret = af9035_ctrl_msg(d->udev, &req);
313 if (ret < 0)
314 goto err;
315
316 if ((b[2] + b[3]) == 0xff) {
317 if ((b[0] + b[1]) == 0xff) {
318 /* NEC */
319 key = b[0] << 8 | b[2];
320 } else {
321 /* ext. NEC */
322 key = b[0] << 16 | b[1] << 8 | b[2];
323 }
324 } else {
325 key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
326 }
327
328 rc_keydown(d->rc_dev, key, 0);
329
330err:
331 /* ignore errors */
332 return 0;
333}
334
335static int af9035_init(struct dvb_usb_device *d)
336{
337 struct state *state = d->priv;
338 int ret, i;
339 u16 frame_size = 87 * 188 / 4;
340 u8 packet_size = 512 / 4;
341 struct reg_val_mask tab[] = {
342 { 0x80f99d, 0x01, 0x01 },
343 { 0x80f9a4, 0x01, 0x01 },
344 { 0x00dd11, 0x00, 0x20 },
345 { 0x00dd11, 0x00, 0x40 },
346 { 0x00dd13, 0x00, 0x20 },
347 { 0x00dd13, 0x00, 0x40 },
348 { 0x00dd11, 0x20, 0x20 },
349 { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
350 { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
351 { 0x00dd0c, packet_size, 0xff},
352 { 0x00dd11, state->dual_mode << 6, 0x40 },
353 { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
354 { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
355 { 0x00dd0d, packet_size, 0xff },
356 { 0x80f9a3, 0x00, 0x01 },
357 { 0x80f9cd, 0x00, 0x01 },
358 { 0x80f99d, 0x00, 0x01 },
359 { 0x80f9a4, 0x00, 0x01 },
360 };
361
362 pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
363 __func__, d->udev->speed, frame_size, packet_size);
364
365 /* init endpoints */
366 for (i = 0; i < ARRAY_SIZE(tab); i++) {
367 ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
368 tab[i].mask);
369 if (ret < 0)
370 goto err;
371 }
372
373 return 0;
374
375err:
376 pr_debug("%s: failed=%d\n", __func__, ret);
377
378 return ret;
379}
380
381static int af9035_identify_state(struct usb_device *udev,
382 struct dvb_usb_device_properties *props,
383 struct dvb_usb_device_description **desc,
384 int *cold)
385{
386 int ret;
387 u8 wbuf[1] = { 1 };
388 u8 rbuf[4];
389 struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
390 sizeof(rbuf), rbuf };
391
392 ret = af9035_ctrl_msg(udev, &req);
393 if (ret < 0)
394 goto err;
395
396 pr_debug("%s: reply=%02x %02x %02x %02x\n", __func__,
397 rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
398 if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
399 *cold = 0;
400 else
401 *cold = 1;
402
403 return 0;
404
405err:
406 pr_debug("%s: failed=%d\n", __func__, ret);
407
408 return ret;
409}
410
411static int af9035_download_firmware(struct usb_device *udev,
412 const struct firmware *fw)
413{
414 int ret, i, j, len;
415 u8 wbuf[1];
416 u8 rbuf[4];
417 struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
418 struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
419 struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
420 u8 hdr_core;
421 u16 hdr_addr, hdr_data_len, hdr_checksum;
422 #define MAX_DATA 58
423 #define HDR_SIZE 7
424
425 /*
426 * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
427 *
428 * byte 0: MCS 51 core
429 * There are two inside the AF9035 (1=Link and 2=OFDM) with separate
430 * address spaces
431 * byte 1-2: Big endian destination address
432 * byte 3-4: Big endian number of data bytes following the header
433 * byte 5-6: Big endian header checksum, apparently ignored by the chip
434 * Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
435 */
436
437 for (i = fw->size; i > HDR_SIZE;) {
438 hdr_core = fw->data[fw->size - i + 0];
439 hdr_addr = fw->data[fw->size - i + 1] << 8;
440 hdr_addr |= fw->data[fw->size - i + 2] << 0;
441 hdr_data_len = fw->data[fw->size - i + 3] << 8;
442 hdr_data_len |= fw->data[fw->size - i + 4] << 0;
443 hdr_checksum = fw->data[fw->size - i + 5] << 8;
444 hdr_checksum |= fw->data[fw->size - i + 6] << 0;
445
446 pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
447 __func__, hdr_core, hdr_addr, hdr_data_len,
448 hdr_checksum);
449
450 if (((hdr_core != 1) && (hdr_core != 2)) ||
451 (hdr_data_len > i)) {
452 pr_debug("%s: bad firmware\n", __func__);
453 break;
454 }
455
456 /* download begin packet */
457 req.cmd = CMD_FW_DL_BEGIN;
458 ret = af9035_ctrl_msg(udev, &req);
459 if (ret < 0)
460 goto err;
461
462 /* download firmware packet(s) */
463 for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
464 len = j;
465 if (len > MAX_DATA)
466 len = MAX_DATA;
467 req_fw_dl.wlen = len;
468 req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
469 HDR_SIZE + hdr_data_len - j];
470 ret = af9035_ctrl_msg(udev, &req_fw_dl);
471 if (ret < 0)
472 goto err;
473 }
474
475 /* download end packet */
476 req.cmd = CMD_FW_DL_END;
477 ret = af9035_ctrl_msg(udev, &req);
478 if (ret < 0)
479 goto err;
480
481 i -= hdr_data_len + HDR_SIZE;
482
483 pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
484 }
485
486 /* firmware loaded, request boot */
487 req.cmd = CMD_FW_BOOT;
488 ret = af9035_ctrl_msg(udev, &req);
489 if (ret < 0)
490 goto err;
491
492 /* ensure firmware starts */
493 wbuf[0] = 1;
494 ret = af9035_ctrl_msg(udev, &req_fw_ver);
495 if (ret < 0)
496 goto err;
497
498 if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
499 info("firmware did not run");
500 ret = -ENODEV;
501 goto err;
502 }
503
504 info("firmware version=%d.%d.%d.%d", rbuf[0], rbuf[1], rbuf[2],
505 rbuf[3]);
506
507 return 0;
508
509err:
510 pr_debug("%s: failed=%d\n", __func__, ret);
511
512 return ret;
513}
514
515static int af9035_download_firmware_it9135(struct usb_device *udev,
516 const struct firmware *fw)
517{
518 int ret, i, i_prev;
519 u8 wbuf[1];
520 u8 rbuf[4];
521 struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
522 struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
523 struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
524 #define HDR_SIZE 7
525
526 /*
527 * There seems to be following firmware header. Meaning of bytes 0-3
528 * is unknown.
529 *
530 * 0: 3
531 * 1: 0, 1
532 * 2: 0
533 * 3: 1, 2, 3
534 * 4: addr MSB
535 * 5: addr LSB
536 * 6: count of data bytes ?
537 */
538
539 for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
540 if (i == fw->size ||
541 (fw->data[i + 0] == 0x03 &&
542 (fw->data[i + 1] == 0x00 ||
543 fw->data[i + 1] == 0x01) &&
544 fw->data[i + 2] == 0x00)) {
545 req_fw_dl.wlen = i - i_prev;
546 req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
547 i_prev = i;
548 ret = af9035_ctrl_msg(udev, &req_fw_dl);
549 if (ret < 0)
550 goto err;
551
552 pr_debug("%s: data uploaded=%d\n", __func__, i);
553 }
554 }
555
556 /* firmware loaded, request boot */
557 req.cmd = CMD_FW_BOOT;
558 ret = af9035_ctrl_msg(udev, &req);
559 if (ret < 0)
560 goto err;
561
562 /* ensure firmware starts */
563 wbuf[0] = 1;
564 ret = af9035_ctrl_msg(udev, &req_fw_ver);
565 if (ret < 0)
566 goto err;
567
568 if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
569 info("firmware did not run");
570 ret = -ENODEV;
571 goto err;
572 }
573
574 info("firmware version=%d.%d.%d.%d", rbuf[0], rbuf[1], rbuf[2],
575 rbuf[3]);
576
577 return 0;
578
579err:
580 pr_debug("%s: failed=%d\n", __func__, ret);
581
582 return ret;
583}
584
585/* abuse that callback as there is no better one for reading eeprom */
586static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
587{
588 struct state *state = d->priv;
589 int ret, i, eeprom_shift = 0;
590 u8 tmp;
591 u16 tmp16;
592
593 /* check if there is dual tuners */
594 ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp);
595 if (ret < 0)
596 goto err;
597
598 state->dual_mode = tmp;
599 pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
600
601 for (i = 0; i < af9035_properties[0].num_adapters; i++) {
602 /* tuner */
603 ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
604 if (ret < 0)
605 goto err;
606
607 state->af9033_config[i].tuner = tmp;
608 pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
609
610 switch (tmp) {
611 case AF9033_TUNER_TUA9001:
612 case AF9033_TUNER_FC0011:
613 case AF9033_TUNER_MXL5007T:
614 case AF9033_TUNER_TDA18218:
615 state->af9033_config[i].spec_inv = 1;
616 break;
617 default:
618 warn("tuner ID=%02x not supported, please report!",
619 tmp);
620 };
621
622 /* tuner IF frequency */
623 ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
624 if (ret < 0)
625 goto err;
626
627 tmp16 = tmp;
628
629 ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp);
630 if (ret < 0)
631 goto err;
632
633 tmp16 |= tmp << 8;
634
635 pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
636
637 eeprom_shift = 0x10; /* shift for the 2nd tuner params */
638 }
639
640 /* get demod clock */
641 ret = af9035_rd_reg(d, 0x00d800, &tmp);
642 if (ret < 0)
643 goto err;
644
645 tmp = (tmp >> 0) & 0x0f;
646
647 for (i = 0; i < af9035_properties[0].num_adapters; i++)
648 state->af9033_config[i].clock = clock_lut[tmp];
649
650 ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
651 if (ret < 0)
652 goto err;
653 pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
654
655 /* don't activate rc if in HID mode or if not available */
656 if (tmp == 5) {
657 ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
658 if (ret < 0)
659 goto err;
660 pr_debug("%s: ir_type=%02x\n", __func__, tmp);
661
662 switch (tmp) {
663 case 0: /* NEC */
664 default:
665 d->props.rc.core.protocol = RC_TYPE_NEC;
666 d->props.rc.core.allowed_protos = RC_TYPE_NEC;
667 break;
668 case 1: /* RC6 */
669 d->props.rc.core.protocol = RC_TYPE_RC6;
670 d->props.rc.core.allowed_protos = RC_TYPE_RC6;
671 break;
672 }
673 d->props.rc.core.rc_query = af9035_rc_query;
674 }
675
676 return 0;
677
678err:
679 pr_debug("%s: failed=%d\n", __func__, ret);
680
681 return ret;
682}
683
684/* abuse that callback as there is no better one for reading eeprom */
685static int af9035_read_mac_address_it9135(struct dvb_usb_device *d, u8 mac[6])
686{
687 struct state *state = d->priv;
688 int ret, i;
689 u8 tmp;
690
691 state->dual_mode = false;
692
693 /* get demod clock */
694 ret = af9035_rd_reg(d, 0x00d800, &tmp);
695 if (ret < 0)
696 goto err;
697
698 tmp = (tmp >> 0) & 0x0f;
699
700 for (i = 0; i < af9035_properties[0].num_adapters; i++)
701 state->af9033_config[i].clock = clock_lut_it9135[tmp];
702
703 return 0;
704
705err:
706 pr_debug("%s: failed=%d\n", __func__, ret);
707
708 return ret;
709}
710
711static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
712 int cmd, int arg)
713{
714 int ret;
715
716 switch (cmd) {
717 case FC0011_FE_CALLBACK_POWER:
718 /* Tuner enable */
719 ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
720 if (ret < 0)
721 goto err;
722
723 ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
724 if (ret < 0)
725 goto err;
726
727 ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
728 if (ret < 0)
729 goto err;
730
731 /* LED */
732 ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
733 if (ret < 0)
734 goto err;
735
736 ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
737 if (ret < 0)
738 goto err;
739
740 usleep_range(10000, 50000);
741 break;
742 case FC0011_FE_CALLBACK_RESET:
743 ret = af9035_wr_reg(d, 0xd8e9, 1);
744 if (ret < 0)
745 goto err;
746
747 ret = af9035_wr_reg(d, 0xd8e8, 1);
748 if (ret < 0)
749 goto err;
750
751 ret = af9035_wr_reg(d, 0xd8e7, 1);
752 if (ret < 0)
753 goto err;
754
755 usleep_range(10000, 20000);
756
757 ret = af9035_wr_reg(d, 0xd8e7, 0);
758 if (ret < 0)
759 goto err;
760
761 usleep_range(10000, 20000);
762 break;
763 default:
764 ret = -EINVAL;
765 goto err;
766 }
767
768 return 0;
769
770err:
771 pr_debug("%s: failed=%d\n", __func__, ret);
772
773 return ret;
774}
775
776static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
777{
778 struct state *state = d->priv;
779
780 switch (state->af9033_config[0].tuner) {
781 case AF9033_TUNER_FC0011:
782 return af9035_fc0011_tuner_callback(d, cmd, arg);
783 default:
784 break;
785 }
786
787 return -ENODEV;
788}
789
790static int af9035_frontend_callback(void *adapter_priv, int component,
791 int cmd, int arg)
792{
793 struct i2c_adapter *adap = adapter_priv;
794 struct dvb_usb_device *d = i2c_get_adapdata(adap);
795
796 switch (component) {
797 case DVB_FRONTEND_COMPONENT_TUNER:
798 return af9035_tuner_callback(d, cmd, arg);
799 default:
800 break;
801 }
802
803 return -EINVAL;
804}
805
806static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
807{
808 struct state *state = adap->dev->priv;
809 int ret;
810
811 if (!state->af9033_config[adap->id].tuner) {
812 /* unsupported tuner */
813 ret = -ENODEV;
814 goto err;
815 }
816
817 if (adap->id == 0) {
818 state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
819 state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
820
821 ret = af9035_wr_reg(adap->dev, 0x00417f,
822 state->af9033_config[1].i2c_addr);
823 if (ret < 0)
824 goto err;
825
826 ret = af9035_wr_reg(adap->dev, 0x00d81a,
827 state->dual_mode);
828 if (ret < 0)
829 goto err;
830 }
831
832 /* attach demodulator */
833 adap->fe_adap[0].fe = dvb_attach(af9033_attach,
834 &state->af9033_config[adap->id], &adap->dev->i2c_adap);
835 if (adap->fe_adap[0].fe == NULL) {
836 ret = -ENODEV;
837 goto err;
838 }
839
840 /* disable I2C-gate */
841 adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL;
842 adap->fe_adap[0].fe->callback = af9035_frontend_callback;
843
844 return 0;
845
846err:
847 pr_debug("%s: failed=%d\n", __func__, ret);
848
849 return ret;
850}
851
852static struct tua9001_config af9035_tua9001_config = {
853 .i2c_addr = 0x60,
854};
855
856static const struct fc0011_config af9035_fc0011_config = {
857 .i2c_address = 0x60,
858};
859
860static struct mxl5007t_config af9035_mxl5007t_config = {
861 .xtal_freq_hz = MxL_XTAL_24_MHZ,
862 .if_freq_hz = MxL_IF_4_57_MHZ,
863 .invert_if = 0,
864 .loop_thru_enable = 0,
865 .clk_out_enable = 0,
866 .clk_out_amp = MxL_CLKOUT_AMP_0_94V,
867};
868
869static struct tda18218_config af9035_tda18218_config = {
870 .i2c_address = 0x60,
871 .i2c_wr_max = 21,
872};
873
874static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
875{
876 struct state *state = adap->dev->priv;
877 int ret;
878 struct dvb_frontend *fe;
879
880 switch (state->af9033_config[adap->id].tuner) {
881 case AF9033_TUNER_TUA9001:
882 /* AF9035 gpiot3 = TUA9001 RESETN
883 AF9035 gpiot2 = TUA9001 RXEN */
884
885 /* configure gpiot2 and gpiot2 as output */
886 ret = af9035_wr_reg_mask(adap->dev, 0x00d8ec, 0x01, 0x01);
887 if (ret < 0)
888 goto err;
889
890 ret = af9035_wr_reg_mask(adap->dev, 0x00d8ed, 0x01, 0x01);
891 if (ret < 0)
892 goto err;
893
894 ret = af9035_wr_reg_mask(adap->dev, 0x00d8e8, 0x01, 0x01);
895 if (ret < 0)
896 goto err;
897
898 ret = af9035_wr_reg_mask(adap->dev, 0x00d8e9, 0x01, 0x01);
899 if (ret < 0)
900 goto err;
901
902 /* reset tuner */
903 ret = af9035_wr_reg_mask(adap->dev, 0x00d8e7, 0x00, 0x01);
904 if (ret < 0)
905 goto err;
906
907 usleep_range(2000, 20000);
908
909 ret = af9035_wr_reg_mask(adap->dev, 0x00d8e7, 0x01, 0x01);
910 if (ret < 0)
911 goto err;
912
913 /* activate tuner RX */
914 /* TODO: use callback for TUA9001 RXEN */
915 ret = af9035_wr_reg_mask(adap->dev, 0x00d8eb, 0x01, 0x01);
916 if (ret < 0)
917 goto err;
918
919 /* attach tuner */
920 fe = dvb_attach(tua9001_attach, adap->fe_adap[0].fe,
921 &adap->dev->i2c_adap, &af9035_tua9001_config);
922 break;
923 case AF9033_TUNER_FC0011:
924 fe = dvb_attach(fc0011_attach, adap->fe_adap[0].fe,
925 &adap->dev->i2c_adap, &af9035_fc0011_config);
926 break;
927 case AF9033_TUNER_MXL5007T:
928 ret = af9035_wr_reg(adap->dev, 0x00d8e0, 1);
929 if (ret < 0)
930 goto err;
931 ret = af9035_wr_reg(adap->dev, 0x00d8e1, 1);
932 if (ret < 0)
933 goto err;
934 ret = af9035_wr_reg(adap->dev, 0x00d8df, 0);
935 if (ret < 0)
936 goto err;
937
938 msleep(30);
939
940 ret = af9035_wr_reg(adap->dev, 0x00d8df, 1);
941 if (ret < 0)
942 goto err;
943
944 msleep(300);
945
946 ret = af9035_wr_reg(adap->dev, 0x00d8c0, 1);
947 if (ret < 0)
948 goto err;
949 ret = af9035_wr_reg(adap->dev, 0x00d8c1, 1);
950 if (ret < 0)
951 goto err;
952 ret = af9035_wr_reg(adap->dev, 0x00d8bf, 0);
953 if (ret < 0)
954 goto err;
955 ret = af9035_wr_reg(adap->dev, 0x00d8b4, 1);
956 if (ret < 0)
957 goto err;
958 ret = af9035_wr_reg(adap->dev, 0x00d8b5, 1);
959 if (ret < 0)
960 goto err;
961 ret = af9035_wr_reg(adap->dev, 0x00d8b3, 1);
962 if (ret < 0)
963 goto err;
964
965 /* attach tuner */
966 fe = dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
967 &adap->dev->i2c_adap, 0x60, &af9035_mxl5007t_config);
968 break;
969 case AF9033_TUNER_TDA18218:
970 /* attach tuner */
971 fe = dvb_attach(tda18218_attach, adap->fe_adap[0].fe,
972 &adap->dev->i2c_adap, &af9035_tda18218_config);
973 break;
974 default:
975 fe = NULL;
976 }
977
978 if (fe == NULL) {
979 ret = -ENODEV;
980 goto err;
981 }
982
983 return 0;
984
985err:
986 pr_debug("%s: failed=%d\n", __func__, ret);
987
988 return ret;
989}
990
991enum af9035_id_entry {
992 AF9035_15A4_9035,
993 AF9035_15A4_1000,
994 AF9035_15A4_1001,
995 AF9035_15A4_1002,
996 AF9035_15A4_1003,
997 AF9035_0CCD_0093,
998 AF9035_07CA_A835,
999 AF9035_07CA_B835,
1000 AF9035_07CA_1867,
1001 AF9035_07CA_A867,
1002 AF9035_07CA_0825,
1003};
1004
1005static struct usb_device_id af9035_id[] = {
1006 [AF9035_15A4_9035] = {
1007 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035)},
1008 [AF9035_15A4_1000] = {
1009 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000)},
1010 [AF9035_15A4_1001] = {
1011 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001)},
1012 [AF9035_15A4_1002] = {
1013 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002)},
1014 [AF9035_15A4_1003] = {
1015 USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003)},
1016 [AF9035_0CCD_0093] = {
1017 USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK)},
1018 [AF9035_07CA_A835] = {
1019 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835)},
1020 [AF9035_07CA_B835] = {
1021 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835)},
1022 [AF9035_07CA_1867] = {
1023 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867)},
1024 [AF9035_07CA_A867] = {
1025 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867)},
1026 [AF9035_07CA_0825] = {
1027 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR)},
1028 {},
1029};
1030
1031MODULE_DEVICE_TABLE(usb, af9035_id);
1032
1033static struct dvb_usb_device_properties af9035_properties[] = {
1034 {
1035 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1036
1037 .usb_ctrl = DEVICE_SPECIFIC,
1038 .download_firmware = af9035_download_firmware,
1039 .firmware = "dvb-usb-af9035-02.fw",
1040 .no_reconnect = 1,
1041
1042 .size_of_priv = sizeof(struct state),
1043
1044 .num_adapters = 1,
1045 .adapter = {
1046 {
1047 .num_frontends = 1,
1048 .fe = {
1049 {
1050 .frontend_attach = af9035_frontend_attach,
1051 .tuner_attach = af9035_tuner_attach,
1052 .stream = {
1053 .type = USB_BULK,
1054 .count = 6,
1055 .endpoint = 0x84,
1056 .u = {
1057 .bulk = {
1058 .buffersize = (87 * 188),
1059 }
1060 }
1061 }
1062 }
1063 }
1064 }
1065 },
1066
1067 .identify_state = af9035_identify_state,
1068 .read_mac_address = af9035_read_mac_address,
1069
1070 .i2c_algo = &af9035_i2c_algo,
1071
1072 .rc.core = {
1073 .protocol = RC_TYPE_UNKNOWN,
1074 .module_name = "af9035",
1075 .rc_query = NULL,
1076 .rc_interval = AF9035_POLL,
1077 .allowed_protos = RC_TYPE_UNKNOWN,
1078 .rc_codes = RC_MAP_EMPTY,
1079 },
1080 .num_device_descs = 5,
1081 .devices = {
1082 {
1083 .name = "Afatech AF9035 reference design",
1084 .cold_ids = {
1085 &af9035_id[AF9035_15A4_9035],
1086 &af9035_id[AF9035_15A4_1000],
1087 &af9035_id[AF9035_15A4_1001],
1088 &af9035_id[AF9035_15A4_1002],
1089 &af9035_id[AF9035_15A4_1003],
1090 },
1091 }, {
1092 .name = "TerraTec Cinergy T Stick",
1093 .cold_ids = {
1094 &af9035_id[AF9035_0CCD_0093],
1095 },
1096 }, {
1097 .name = "AVerMedia AVerTV Volar HD/PRO (A835)",
1098 .cold_ids = {
1099 &af9035_id[AF9035_07CA_A835],
1100 &af9035_id[AF9035_07CA_B835],
1101 },
1102 }, {
1103 .name = "AVerMedia HD Volar (A867)",
1104 .cold_ids = {
1105 &af9035_id[AF9035_07CA_1867],
1106 &af9035_id[AF9035_07CA_A867],
1107 },
1108 }, {
1109 .name = "AVerMedia Twinstar (A825)",
1110 .cold_ids = {
1111 &af9035_id[AF9035_07CA_0825],
1112 },
1113 },
1114 }
1115 },
1116 {
1117 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1118
1119 .usb_ctrl = DEVICE_SPECIFIC,
1120 .download_firmware = af9035_download_firmware_it9135,
1121 .firmware = "dvb-usb-it9135-01.fw",
1122 .no_reconnect = 1,
1123
1124 .size_of_priv = sizeof(struct state),
1125
1126 .num_adapters = 1,
1127 .adapter = {
1128 {
1129 .num_frontends = 1,
1130 .fe = {
1131 {
1132 .frontend_attach = af9035_frontend_attach,
1133 .tuner_attach = af9035_tuner_attach,
1134 .stream = {
1135 .type = USB_BULK,
1136 .count = 6,
1137 .endpoint = 0x84,
1138 .u = {
1139 .bulk = {
1140 .buffersize = (87 * 188),
1141 }
1142 }
1143 }
1144 }
1145 }
1146 }
1147 },
1148
1149 .identify_state = af9035_identify_state,
1150 .read_mac_address = af9035_read_mac_address_it9135,
1151
1152 .i2c_algo = &af9035_i2c_algo,
1153
1154 .num_device_descs = 0, /* disabled as no support for IT9135 */
1155 .devices = {
1156 {
1157 .name = "ITE Tech. IT9135 reference design",
1158 },
1159 }
1160 },
1161};
1162
1163static int af9035_usb_probe(struct usb_interface *intf,
1164 const struct usb_device_id *id)
1165{
1166 int ret, i;
1167 struct dvb_usb_device *d = NULL;
1168 struct usb_device *udev;
1169 bool found;
1170
1171 pr_debug("%s: interface=%d\n", __func__,
1172 intf->cur_altsetting->desc.bInterfaceNumber);
1173
1174 /* interface 0 is used by DVB-T receiver and
1175 interface 1 is for remote controller (HID) */
1176 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
1177 return 0;
1178
1179 /* Dynamic USB ID support. Replaces first device ID with current one. */
1180 udev = interface_to_usbdev(intf);
1181
1182 for (i = 0, found = false; i < ARRAY_SIZE(af9035_id) - 1; i++) {
1183 if (af9035_id[i].idVendor ==
1184 le16_to_cpu(udev->descriptor.idVendor) &&
1185 af9035_id[i].idProduct ==
1186 le16_to_cpu(udev->descriptor.idProduct)) {
1187 found = true;
1188 break;
1189 }
1190 }
1191
1192 if (!found) {
1193 pr_debug("%s: using dynamic ID %04x:%04x\n", __func__,
1194 le16_to_cpu(udev->descriptor.idVendor),
1195 le16_to_cpu(udev->descriptor.idProduct));
1196 af9035_properties[0].devices[0].cold_ids[0]->idVendor =
1197 le16_to_cpu(udev->descriptor.idVendor);
1198 af9035_properties[0].devices[0].cold_ids[0]->idProduct =
1199 le16_to_cpu(udev->descriptor.idProduct);
1200 }
1201
1202
1203 for (i = 0; i < af9035_properties_count; i++) {
1204 ret = dvb_usb_device_init(intf, &af9035_properties[i],
1205 THIS_MODULE, &d, adapter_nr);
1206
1207 if (ret == -ENODEV)
1208 continue;
1209 else
1210 break;
1211 }
1212
1213 if (ret < 0)
1214 goto err;
1215
1216 if (d) {
1217 ret = af9035_init(d);
1218 if (ret < 0)
1219 goto err;
1220 }
1221
1222 return 0;
1223
1224err:
1225 pr_debug("%s: failed=%d\n", __func__, ret);
1226
1227 return ret;
1228}
1229
1230/* usb specific object needed to register this driver with the usb subsystem */
1231static struct usb_driver af9035_usb_driver = {
1232 .name = "dvb_usb_af9035",
1233 .probe = af9035_usb_probe,
1234 .disconnect = dvb_usb_device_exit,
1235 .id_table = af9035_id,
1236};
1237
1238module_usb_driver(af9035_usb_driver);
1239
1240MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1241MODULE_DESCRIPTION("Afatech AF9035 driver");
1242MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9035.h b/drivers/media/dvb/dvb-usb/af9035.h
new file mode 100644
index 000000000000..481a1a43dd2a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9035.h
@@ -0,0 +1,113 @@
1/*
2 * Afatech AF9035 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef AF9035_H
23#define AF9035_H
24
25/* prefix for dvb-usb log writings */
26#define DVB_USB_LOG_PREFIX "af9035"
27
28#include "dvb-usb.h"
29#include "af9033.h"
30#include "tua9001.h"
31#include "fc0011.h"
32#include "mxl5007t.h"
33#include "tda18218.h"
34
35struct reg_val {
36 u32 reg;
37 u8 val;
38};
39
40struct reg_val_mask {
41 u32 reg;
42 u8 val;
43 u8 mask;
44};
45
46struct usb_req {
47 u8 cmd;
48 u8 mbox;
49 u8 wlen;
50 u8 *wbuf;
51 u8 rlen;
52 u8 *rbuf;
53};
54
55struct state {
56 bool dual_mode;
57
58 struct af9033_config af9033_config[2];
59};
60
61u32 clock_lut[] = {
62 20480000, /* FPGA */
63 16384000, /* 16.38 MHz */
64 20480000, /* 20.48 MHz */
65 36000000, /* 36.00 MHz */
66 30000000, /* 30.00 MHz */
67 26000000, /* 26.00 MHz */
68 28000000, /* 28.00 MHz */
69 32000000, /* 32.00 MHz */
70 34000000, /* 34.00 MHz */
71 24000000, /* 24.00 MHz */
72 22000000, /* 22.00 MHz */
73 12000000, /* 12.00 MHz */
74};
75
76u32 clock_lut_it9135[] = {
77 12000000, /* 12.00 MHz */
78 20480000, /* 20.48 MHz */
79 36000000, /* 36.00 MHz */
80 30000000, /* 30.00 MHz */
81 26000000, /* 26.00 MHz */
82 28000000, /* 28.00 MHz */
83 32000000, /* 32.00 MHz */
84 34000000, /* 34.00 MHz */
85 24000000, /* 24.00 MHz */
86 22000000, /* 22.00 MHz */
87};
88
89/* EEPROM locations */
90#define EEPROM_IR_MODE 0x430d
91#define EEPROM_DUAL_MODE 0x4326
92#define EEPROM_IR_TYPE 0x4329
93#define EEPROM_1_IFFREQ_L 0x432d
94#define EEPROM_1_IFFREQ_H 0x432e
95#define EEPROM_1_TUNER_ID 0x4331
96#define EEPROM_2_IFFREQ_L 0x433d
97#define EEPROM_2_IFFREQ_H 0x433e
98#define EEPROM_2_TUNER_ID 0x4341
99
100/* USB commands */
101#define CMD_MEM_RD 0x00
102#define CMD_MEM_WR 0x01
103#define CMD_I2C_RD 0x02
104#define CMD_I2C_WR 0x03
105#define CMD_IR_GET 0x18
106#define CMD_FW_DL 0x21
107#define CMD_FW_QUERYINFO 0x22
108#define CMD_FW_BOOT 0x23
109#define CMD_FW_DL_BEGIN 0x24
110#define CMD_FW_DL_END 0x25
111#define CMD_FW_SCATTER_WR 0x29
112
113#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 02290c60f72f..7e9e00fae04e 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -32,7 +32,7 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
32 32
33 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 33 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
34 err("could not acquire lock"); 34 err("could not acquire lock");
35 return 0; 35 return -EINTR;
36 } 36 }
37 37
38 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), 38 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
@@ -118,7 +118,7 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
118 118
119 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 119 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
120 err("could not acquire lock"); 120 err("could not acquire lock");
121 return 0; 121 return -EINTR;
122 } 122 }
123 123
124 st->buf[0] = REQUEST_SET_GPIO; 124 st->buf[0] = REQUEST_SET_GPIO;
@@ -139,7 +139,7 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
139 if (st->fw_version >= 0x10201) { 139 if (st->fw_version >= 0x10201) {
140 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 140 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
141 err("could not acquire lock"); 141 err("could not acquire lock");
142 return 0; 142 return -EINTR;
143 } 143 }
144 144
145 st->buf[0] = REQUEST_SET_USB_XFER_LEN; 145 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
@@ -178,7 +178,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
178 /* Ensure nobody else hits the i2c bus while we're sending our 178 /* Ensure nobody else hits the i2c bus while we're sending our
179 sequence of messages, (such as the remote control thread) */ 179 sequence of messages, (such as the remote control thread) */
180 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 180 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
181 return -EAGAIN; 181 return -EINTR;
182 182
183 for (i = 0; i < num; i++) { 183 for (i = 0; i < num; i++) {
184 if (i == 0) { 184 if (i == 0) {
@@ -228,7 +228,8 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
228 /* Write request */ 228 /* Write request */
229 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 229 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
230 err("could not acquire lock"); 230 err("could not acquire lock");
231 return 0; 231 mutex_unlock(&d->i2c_mutex);
232 return -EINTR;
232 } 233 }
233 st->buf[0] = REQUEST_NEW_I2C_WRITE; 234 st->buf[0] = REQUEST_NEW_I2C_WRITE;
234 st->buf[1] = msg[i].addr << 1; 235 st->buf[1] = msg[i].addr << 1;
@@ -271,10 +272,11 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
271 int i,len; 272 int i,len;
272 273
273 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 274 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
274 return -EAGAIN; 275 return -EINTR;
275 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 276 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
276 err("could not acquire lock"); 277 err("could not acquire lock");
277 return 0; 278 mutex_unlock(&d->i2c_mutex);
279 return -EINTR;
278 } 280 }
279 281
280 for (i = 0; i < num; i++) { 282 for (i = 0; i < num; i++) {
@@ -369,7 +371,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
369 371
370 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 372 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
371 err("could not acquire lock"); 373 err("could not acquire lock");
372 return 0; 374 return -EINTR;
373 } 375 }
374 376
375 st->buf[0] = REQUEST_SET_CLOCK; 377 st->buf[0] = REQUEST_SET_CLOCK;
@@ -401,7 +403,7 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
401 403
402 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 404 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
403 err("could not acquire lock"); 405 err("could not acquire lock");
404 return 0; 406 return -EINTR;
405 } 407 }
406 408
407 st->buf[0] = REQUEST_SET_I2C_PARAM; 409 st->buf[0] = REQUEST_SET_I2C_PARAM;
@@ -561,7 +563,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
561 563
562 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) { 564 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
563 err("could not acquire lock"); 565 err("could not acquire lock");
564 return 0; 566 return -EINTR;
565 } 567 }
566 568
567 st->buf[0] = REQUEST_ENABLE_VIDEO; 569 st->buf[0] = REQUEST_ENABLE_VIDEO;
@@ -611,7 +613,7 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
611 613
612 if (mutex_lock_interruptible(&d->usb_mutex) < 0) { 614 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
613 err("could not acquire lock"); 615 err("could not acquire lock");
614 return 0; 616 return -EINTR;
615 } 617 }
616 618
617 st->buf[0] = REQUEST_SET_RC; 619 st->buf[0] = REQUEST_SET_RC;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index f9e966aa26e7..510001da6e83 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -3569,6 +3569,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
3569 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) }, 3569 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) },
3570 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) }, 3570 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) },
3571/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) }, 3571/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) },
3572 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_2) },
3572 { 0 } /* Terminating entry */ 3573 { 0 } /* Terminating entry */
3573}; 3574};
3574MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 3575MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -3832,7 +3833,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
3832 }, 3833 },
3833 }, 3834 },
3834 3835
3835 .num_device_descs = 11, 3836 .num_device_descs = 12,
3836 .devices = { 3837 .devices = {
3837 { "DiBcom STK7070P reference design", 3838 { "DiBcom STK7070P reference design",
3838 { &dib0700_usb_id_table[15], NULL }, 3839 { &dib0700_usb_id_table[15], NULL },
@@ -3878,6 +3879,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
3878 { &dib0700_usb_id_table[50], NULL }, 3879 { &dib0700_usb_id_table[50], NULL },
3879 { NULL }, 3880 { NULL },
3880 }, 3881 },
3882 { "Elgato EyeTV DTT rev. 2",
3883 { &dib0700_usb_id_table[81], NULL },
3884 { NULL },
3885 },
3881 }, 3886 },
3882 3887
3883 .rc.core = { 3888 .rc.core = {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 397d8f232731..7a6160bf54ba 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -76,6 +76,11 @@
76#define USB_PID_AFATECH_AF9005 0x9020 76#define USB_PID_AFATECH_AF9005 0x9020
77#define USB_PID_AFATECH_AF9015_9015 0x9015 77#define USB_PID_AFATECH_AF9015_9015 0x9015
78#define USB_PID_AFATECH_AF9015_9016 0x9016 78#define USB_PID_AFATECH_AF9015_9016 0x9016
79#define USB_PID_AFATECH_AF9035_1000 0x1000
80#define USB_PID_AFATECH_AF9035_1001 0x1001
81#define USB_PID_AFATECH_AF9035_1002 0x1002
82#define USB_PID_AFATECH_AF9035_1003 0x1003
83#define USB_PID_AFATECH_AF9035_9035 0x9035
79#define USB_PID_TREKSTOR_DVBT 0x901b 84#define USB_PID_TREKSTOR_DVBT 0x901b
80#define USB_VID_ALINK_DTU 0xf170 85#define USB_VID_ALINK_DTU 0xf170
81#define USB_PID_ANSONIC_DVBT_USB 0x6000 86#define USB_PID_ANSONIC_DVBT_USB 0x6000
@@ -152,6 +157,7 @@
152#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 157#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
153#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 158#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
154#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069 159#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
160#define USB_PID_TERRATEC_CINERGY_T_STICK 0x0093
155#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097 161#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
156#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099 162#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099
157#define USB_PID_TWINHAN_VP7041_COLD 0x3201 163#define USB_PID_TWINHAN_VP7041_COLD 0x3201
@@ -221,6 +227,11 @@
221#define USB_PID_AVERMEDIA_A850T 0x850b 227#define USB_PID_AVERMEDIA_A850T 0x850b
222#define USB_PID_AVERMEDIA_A805 0xa805 228#define USB_PID_AVERMEDIA_A805 0xa805
223#define USB_PID_AVERMEDIA_A815M 0x815a 229#define USB_PID_AVERMEDIA_A815M 0x815a
230#define USB_PID_AVERMEDIA_A835 0xa835
231#define USB_PID_AVERMEDIA_B835 0xb835
232#define USB_PID_AVERMEDIA_1867 0x1867
233#define USB_PID_AVERMEDIA_A867 0xa867
234#define USB_PID_AVERMEDIA_TWINSTAR 0x0825
224#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 235#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
225#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d 236#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
226#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 237#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
@@ -327,6 +338,7 @@
327#define USB_PID_MYGICA_D689 0xd811 338#define USB_PID_MYGICA_D689 0xd811
328#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011 339#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
329#define USB_PID_ELGATO_EYETV_DTT 0x0021 340#define USB_PID_ELGATO_EYETV_DTT 0x0021
341#define USB_PID_ELGATO_EYETV_DTT_2 0x003f
330#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 342#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
331#define USB_PID_ELGATO_EYETV_SAT 0x002a 343#define USB_PID_ELGATO_EYETV_SAT 0x002a
332#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 344#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index 53a5c30b51b2..5c8f651344fc 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -80,6 +80,14 @@ static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer
80 dvb_dmx_swfilter_204(&adap->demux, buffer, length); 80 dvb_dmx_swfilter_204(&adap->demux, buffer, length);
81} 81}
82 82
83static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
84 u8 *buffer, size_t length)
85{
86 struct dvb_usb_adapter *adap = stream->user_priv;
87 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
88 dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
89}
90
83int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap) 91int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
84{ 92{
85 int i, ret = 0; 93 int i, ret = 0;
@@ -90,6 +98,10 @@ int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
90 adap->fe_adap[i].stream.complete = 98 adap->fe_adap[i].stream.complete =
91 dvb_usb_data_complete_204; 99 dvb_usb_data_complete_204;
92 else 100 else
101 if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
102 adap->fe_adap[i].stream.complete =
103 dvb_usb_data_complete_raw;
104 else
93 adap->fe_adap[i].stream.complete = dvb_usb_data_complete; 105 adap->fe_adap[i].stream.complete = dvb_usb_data_complete;
94 adap->fe_adap[i].stream.user_priv = adap; 106 adap->fe_adap[i].stream.user_priv = adap;
95 ret = usb_urb_init(&adap->fe_adap[i].stream, 107 ret = usb_urb_init(&adap->fe_adap[i].stream,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 6d7d13f9ce68..99f94409efa1 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -141,6 +141,7 @@ struct dvb_usb_adapter_fe_properties {
141#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02 141#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
142#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04 142#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
143#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08 143#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08
144#define DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD 0x10
144 int caps; 145 int caps;
145 int pid_filter_count; 146 int pid_filter_count;
146 147
@@ -156,7 +157,7 @@ struct dvb_usb_adapter_fe_properties {
156 int size_of_priv; 157 int size_of_priv;
157}; 158};
158 159
159#define MAX_NO_OF_FE_PER_ADAP 2 160#define MAX_NO_OF_FE_PER_ADAP 3
160struct dvb_usb_adapter_properties { 161struct dvb_usb_adapter_properties {
161 int size_of_priv; 162 int size_of_priv;
162 163
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 451c5a7adfb2..9382895b1b88 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -148,7 +148,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
148 int num) 148 int num)
149{ 149{
150 struct dvb_usb_device *d = i2c_get_adapdata(adap); 150 struct dvb_usb_device *d = i2c_get_adapdata(adap);
151 int i = 0, ret = 0; 151 int i = 0;
152 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 152 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
153 u16 value; 153 u16 value;
154 154
@@ -162,7 +162,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
162 /* read stv0299 register */ 162 /* read stv0299 register */
163 value = msg[0].buf[0];/* register */ 163 value = msg[0].buf[0];/* register */
164 for (i = 0; i < msg[1].len; i++) { 164 for (i = 0; i < msg[1].len; i++) {
165 ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0, 165 dw210x_op_rw(d->udev, 0xb5, value + i, 0,
166 buf6, 2, DW210X_READ_MSG); 166 buf6, 2, DW210X_READ_MSG);
167 msg[1].buf[i] = buf6[0]; 167 msg[1].buf[i] = buf6[0];
168 } 168 }
@@ -174,7 +174,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
174 buf6[0] = 0x2a; 174 buf6[0] = 0x2a;
175 buf6[1] = msg[0].buf[0]; 175 buf6[1] = msg[0].buf[0];
176 buf6[2] = msg[0].buf[1]; 176 buf6[2] = msg[0].buf[1];
177 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 177 dw210x_op_rw(d->udev, 0xb2, 0, 0,
178 buf6, 3, DW210X_WRITE_MSG); 178 buf6, 3, DW210X_WRITE_MSG);
179 break; 179 break;
180 case 0x60: 180 case 0x60:
@@ -187,17 +187,17 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
187 buf6[4] = msg[0].buf[1]; 187 buf6[4] = msg[0].buf[1];
188 buf6[5] = msg[0].buf[2]; 188 buf6[5] = msg[0].buf[2];
189 buf6[6] = msg[0].buf[3]; 189 buf6[6] = msg[0].buf[3];
190 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 190 dw210x_op_rw(d->udev, 0xb2, 0, 0,
191 buf6, 7, DW210X_WRITE_MSG); 191 buf6, 7, DW210X_WRITE_MSG);
192 } else { 192 } else {
193 /* read from tuner */ 193 /* read from tuner */
194 ret = dw210x_op_rw(d->udev, 0xb5, 0, 0, 194 dw210x_op_rw(d->udev, 0xb5, 0, 0,
195 buf6, 1, DW210X_READ_MSG); 195 buf6, 1, DW210X_READ_MSG);
196 msg[0].buf[0] = buf6[0]; 196 msg[0].buf[0] = buf6[0];
197 } 197 }
198 break; 198 break;
199 case (DW2102_RC_QUERY): 199 case (DW2102_RC_QUERY):
200 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 200 dw210x_op_rw(d->udev, 0xb8, 0, 0,
201 buf6, 2, DW210X_READ_MSG); 201 buf6, 2, DW210X_READ_MSG);
202 msg[0].buf[0] = buf6[0]; 202 msg[0].buf[0] = buf6[0];
203 msg[0].buf[1] = buf6[1]; 203 msg[0].buf[1] = buf6[1];
@@ -205,7 +205,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
205 case (DW2102_VOLTAGE_CTRL): 205 case (DW2102_VOLTAGE_CTRL):
206 buf6[0] = 0x30; 206 buf6[0] = 0x30;
207 buf6[1] = msg[0].buf[0]; 207 buf6[1] = msg[0].buf[0];
208 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 208 dw210x_op_rw(d->udev, 0xb2, 0, 0,
209 buf6, 2, DW210X_WRITE_MSG); 209 buf6, 2, DW210X_WRITE_MSG);
210 break; 210 break;
211 } 211 }
@@ -221,7 +221,6 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
221 struct i2c_msg msg[], int num) 221 struct i2c_msg msg[], int num)
222{ 222{
223 struct dvb_usb_device *d = i2c_get_adapdata(adap); 223 struct dvb_usb_device *d = i2c_get_adapdata(adap);
224 int ret = 0;
225 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0}; 224 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
226 225
227 if (!d) 226 if (!d)
@@ -235,10 +234,10 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
235 buf6[0] = msg[0].addr << 1; 234 buf6[0] = msg[0].addr << 1;
236 buf6[1] = msg[0].len; 235 buf6[1] = msg[0].len;
237 buf6[2] = msg[0].buf[0]; 236 buf6[2] = msg[0].buf[0];
238 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 237 dw210x_op_rw(d->udev, 0xc2, 0, 0,
239 buf6, msg[0].len + 2, DW210X_WRITE_MSG); 238 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
240 /* read si2109 register */ 239 /* read si2109 register */
241 ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0, 240 dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
242 buf6, msg[1].len + 2, DW210X_READ_MSG); 241 buf6, msg[1].len + 2, DW210X_READ_MSG);
243 memcpy(msg[1].buf, buf6 + 2, msg[1].len); 242 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
244 243
@@ -250,11 +249,11 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
250 buf6[0] = msg[0].addr << 1; 249 buf6[0] = msg[0].addr << 1;
251 buf6[1] = msg[0].len; 250 buf6[1] = msg[0].len;
252 memcpy(buf6 + 2, msg[0].buf, msg[0].len); 251 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
253 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, 252 dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
254 msg[0].len + 2, DW210X_WRITE_MSG); 253 msg[0].len + 2, DW210X_WRITE_MSG);
255 break; 254 break;
256 case(DW2102_RC_QUERY): 255 case(DW2102_RC_QUERY):
257 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 256 dw210x_op_rw(d->udev, 0xb8, 0, 0,
258 buf6, 2, DW210X_READ_MSG); 257 buf6, 2, DW210X_READ_MSG);
259 msg[0].buf[0] = buf6[0]; 258 msg[0].buf[0] = buf6[0];
260 msg[0].buf[1] = buf6[1]; 259 msg[0].buf[1] = buf6[1];
@@ -262,7 +261,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
262 case(DW2102_VOLTAGE_CTRL): 261 case(DW2102_VOLTAGE_CTRL):
263 buf6[0] = 0x30; 262 buf6[0] = 0x30;
264 buf6[1] = msg[0].buf[0]; 263 buf6[1] = msg[0].buf[0];
265 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 264 dw210x_op_rw(d->udev, 0xb2, 0, 0,
266 buf6, 2, DW210X_WRITE_MSG); 265 buf6, 2, DW210X_WRITE_MSG);
267 break; 266 break;
268 } 267 }
@@ -276,7 +275,6 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
276static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 275static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
277{ 276{
278 struct dvb_usb_device *d = i2c_get_adapdata(adap); 277 struct dvb_usb_device *d = i2c_get_adapdata(adap);
279 int ret = 0;
280 278
281 if (!d) 279 if (!d)
282 return -ENODEV; 280 return -ENODEV;
@@ -291,10 +289,10 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
291 obuf[0] = msg[0].addr << 1; 289 obuf[0] = msg[0].addr << 1;
292 obuf[1] = msg[0].len; 290 obuf[1] = msg[0].len;
293 obuf[2] = msg[0].buf[0]; 291 obuf[2] = msg[0].buf[0];
294 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 292 dw210x_op_rw(d->udev, 0xc2, 0, 0,
295 obuf, msg[0].len + 2, DW210X_WRITE_MSG); 293 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
296 /* second read registers */ 294 /* second read registers */
297 ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, 295 dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
298 ibuf, msg[1].len + 2, DW210X_READ_MSG); 296 ibuf, msg[1].len + 2, DW210X_READ_MSG);
299 memcpy(msg[1].buf, ibuf + 2, msg[1].len); 297 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
300 298
@@ -308,7 +306,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
308 obuf[0] = msg[0].addr << 1; 306 obuf[0] = msg[0].addr << 1;
309 obuf[1] = msg[0].len; 307 obuf[1] = msg[0].len;
310 memcpy(obuf + 2, msg[0].buf, msg[0].len); 308 memcpy(obuf + 2, msg[0].buf, msg[0].len);
311 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 309 dw210x_op_rw(d->udev, 0xc2, 0, 0,
312 obuf, msg[0].len + 2, DW210X_WRITE_MSG); 310 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
313 break; 311 break;
314 } 312 }
@@ -318,13 +316,13 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
318 obuf[0] = msg[0].addr << 1; 316 obuf[0] = msg[0].addr << 1;
319 obuf[1] = msg[0].len; 317 obuf[1] = msg[0].len;
320 memcpy(obuf + 2, msg[0].buf, msg[0].len); 318 memcpy(obuf + 2, msg[0].buf, msg[0].len);
321 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 319 dw210x_op_rw(d->udev, 0xc2, 0, 0,
322 obuf, msg[0].len + 2, DW210X_WRITE_MSG); 320 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
323 break; 321 break;
324 } 322 }
325 case(DW2102_RC_QUERY): { 323 case(DW2102_RC_QUERY): {
326 u8 ibuf[2]; 324 u8 ibuf[2];
327 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 325 dw210x_op_rw(d->udev, 0xb8, 0, 0,
328 ibuf, 2, DW210X_READ_MSG); 326 ibuf, 2, DW210X_READ_MSG);
329 memcpy(msg[0].buf, ibuf , 2); 327 memcpy(msg[0].buf, ibuf , 2);
330 break; 328 break;
@@ -333,7 +331,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
333 u8 obuf[2]; 331 u8 obuf[2];
334 obuf[0] = 0x30; 332 obuf[0] = 0x30;
335 obuf[1] = msg[0].buf[0]; 333 obuf[1] = msg[0].buf[0];
336 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 334 dw210x_op_rw(d->udev, 0xb2, 0, 0,
337 obuf, 2, DW210X_WRITE_MSG); 335 obuf, 2, DW210X_WRITE_MSG);
338 break; 336 break;
339 } 337 }
@@ -349,7 +347,6 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
349static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 347static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
350{ 348{
351 struct dvb_usb_device *d = i2c_get_adapdata(adap); 349 struct dvb_usb_device *d = i2c_get_adapdata(adap);
352 int ret = 0;
353 int len, i, j; 350 int len, i, j;
354 351
355 if (!d) 352 if (!d)
@@ -361,7 +358,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
361 switch (msg[j].addr) { 358 switch (msg[j].addr) {
362 case(DW2102_RC_QUERY): { 359 case(DW2102_RC_QUERY): {
363 u8 ibuf[2]; 360 u8 ibuf[2];
364 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 361 dw210x_op_rw(d->udev, 0xb8, 0, 0,
365 ibuf, 2, DW210X_READ_MSG); 362 ibuf, 2, DW210X_READ_MSG);
366 memcpy(msg[j].buf, ibuf , 2); 363 memcpy(msg[j].buf, ibuf , 2);
367 break; 364 break;
@@ -370,7 +367,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
370 u8 obuf[2]; 367 u8 obuf[2];
371 obuf[0] = 0x30; 368 obuf[0] = 0x30;
372 obuf[1] = msg[j].buf[0]; 369 obuf[1] = msg[j].buf[0];
373 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 370 dw210x_op_rw(d->udev, 0xb2, 0, 0,
374 obuf, 2, DW210X_WRITE_MSG); 371 obuf, 2, DW210X_WRITE_MSG);
375 break; 372 break;
376 } 373 }
@@ -382,7 +379,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
382 if (msg[j].flags == I2C_M_RD) { 379 if (msg[j].flags == I2C_M_RD) {
383 /* read registers */ 380 /* read registers */
384 u8 ibuf[msg[j].len + 2]; 381 u8 ibuf[msg[j].len + 2];
385 ret = dw210x_op_rw(d->udev, 0xc3, 382 dw210x_op_rw(d->udev, 0xc3,
386 (msg[j].addr << 1) + 1, 0, 383 (msg[j].addr << 1) + 1, 0,
387 ibuf, msg[j].len + 2, 384 ibuf, msg[j].len + 2,
388 DW210X_READ_MSG); 385 DW210X_READ_MSG);
@@ -402,7 +399,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
402 do { 399 do {
403 memcpy(obuf + 3, msg[j].buf + i, 400 memcpy(obuf + 3, msg[j].buf + i,
404 (len > 16 ? 16 : len)); 401 (len > 16 ? 16 : len));
405 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 402 dw210x_op_rw(d->udev, 0xc2, 0, 0,
406 obuf, (len > 16 ? 16 : len) + 3, 403 obuf, (len > 16 ? 16 : len) + 3,
407 DW210X_WRITE_MSG); 404 DW210X_WRITE_MSG);
408 i += 16; 405 i += 16;
@@ -414,7 +411,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
414 obuf[0] = msg[j].addr << 1; 411 obuf[0] = msg[j].addr << 1;
415 obuf[1] = msg[j].len; 412 obuf[1] = msg[j].len;
416 memcpy(obuf + 2, msg[j].buf, msg[j].len); 413 memcpy(obuf + 2, msg[j].buf, msg[j].len);
417 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 414 dw210x_op_rw(d->udev, 0xc2, 0, 0,
418 obuf, msg[j].len + 2, 415 obuf, msg[j].len + 2,
419 DW210X_WRITE_MSG); 416 DW210X_WRITE_MSG);
420 } 417 }
@@ -432,7 +429,7 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
432 int num) 429 int num)
433{ 430{
434 struct dvb_usb_device *d = i2c_get_adapdata(adap); 431 struct dvb_usb_device *d = i2c_get_adapdata(adap);
435 int ret = 0, i; 432 int i;
436 433
437 if (!d) 434 if (!d)
438 return -ENODEV; 435 return -ENODEV;
@@ -447,10 +444,10 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
447 obuf[0] = msg[0].addr << 1; 444 obuf[0] = msg[0].addr << 1;
448 obuf[1] = msg[0].len; 445 obuf[1] = msg[0].len;
449 obuf[2] = msg[0].buf[0]; 446 obuf[2] = msg[0].buf[0];
450 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 447 dw210x_op_rw(d->udev, 0xc2, 0, 0,
451 obuf, msg[0].len + 2, DW210X_WRITE_MSG); 448 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
452 /* second read registers */ 449 /* second read registers */
453 ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0, 450 dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
454 ibuf, msg[1].len + 2, DW210X_READ_MSG); 451 ibuf, msg[1].len + 2, DW210X_READ_MSG);
455 memcpy(msg[1].buf, ibuf + 2, msg[1].len); 452 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
456 453
@@ -465,13 +462,13 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
465 obuf[0] = msg[0].addr << 1; 462 obuf[0] = msg[0].addr << 1;
466 obuf[1] = msg[0].len; 463 obuf[1] = msg[0].len;
467 memcpy(obuf + 2, msg[0].buf, msg[0].len); 464 memcpy(obuf + 2, msg[0].buf, msg[0].len);
468 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 465 dw210x_op_rw(d->udev, 0xc2, 0, 0,
469 obuf, msg[0].len + 2, DW210X_WRITE_MSG); 466 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
470 break; 467 break;
471 } 468 }
472 case(DW2102_RC_QUERY): { 469 case(DW2102_RC_QUERY): {
473 u8 ibuf[2]; 470 u8 ibuf[2];
474 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 471 dw210x_op_rw(d->udev, 0xb8, 0, 0,
475 ibuf, 2, DW210X_READ_MSG); 472 ibuf, 2, DW210X_READ_MSG);
476 memcpy(msg[0].buf, ibuf , 2); 473 memcpy(msg[0].buf, ibuf , 2);
477 break; 474 break;
@@ -496,7 +493,6 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
496{ 493{
497 struct dvb_usb_device *d = i2c_get_adapdata(adap); 494 struct dvb_usb_device *d = i2c_get_adapdata(adap);
498 struct usb_device *udev; 495 struct usb_device *udev;
499 int ret = 0;
500 int len, i, j; 496 int len, i, j;
501 497
502 if (!d) 498 if (!d)
@@ -509,7 +505,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
509 switch (msg[j].addr) { 505 switch (msg[j].addr) {
510 case (DW2102_RC_QUERY): { 506 case (DW2102_RC_QUERY): {
511 u8 ibuf[5]; 507 u8 ibuf[5];
512 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 508 dw210x_op_rw(d->udev, 0xb8, 0, 0,
513 ibuf, 5, DW210X_READ_MSG); 509 ibuf, 5, DW210X_READ_MSG);
514 memcpy(msg[j].buf, ibuf + 3, 2); 510 memcpy(msg[j].buf, ibuf + 3, 2);
515 break; 511 break;
@@ -519,11 +515,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
519 515
520 obuf[0] = 1; 516 obuf[0] = 1;
521 obuf[1] = msg[j].buf[1];/* off-on */ 517 obuf[1] = msg[j].buf[1];/* off-on */
522 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, 518 dw210x_op_rw(d->udev, 0x8a, 0, 0,
523 obuf, 2, DW210X_WRITE_MSG); 519 obuf, 2, DW210X_WRITE_MSG);
524 obuf[0] = 3; 520 obuf[0] = 3;
525 obuf[1] = msg[j].buf[0];/* 13v-18v */ 521 obuf[1] = msg[j].buf[0];/* 13v-18v */
526 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, 522 dw210x_op_rw(d->udev, 0x8a, 0, 0,
527 obuf, 2, DW210X_WRITE_MSG); 523 obuf, 2, DW210X_WRITE_MSG);
528 break; 524 break;
529 } 525 }
@@ -532,7 +528,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
532 528
533 obuf[0] = 5; 529 obuf[0] = 5;
534 obuf[1] = msg[j].buf[0]; 530 obuf[1] = msg[j].buf[0];
535 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, 531 dw210x_op_rw(d->udev, 0x8a, 0, 0,
536 obuf, 2, DW210X_WRITE_MSG); 532 obuf, 2, DW210X_WRITE_MSG);
537 break; 533 break;
538 } 534 }
@@ -545,7 +541,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
545 if (msg[j].flags == I2C_M_RD) { 541 if (msg[j].flags == I2C_M_RD) {
546 /* read registers */ 542 /* read registers */
547 u8 ibuf[msg[j].len]; 543 u8 ibuf[msg[j].len];
548 ret = dw210x_op_rw(d->udev, 0x91, 0, 0, 544 dw210x_op_rw(d->udev, 0x91, 0, 0,
549 ibuf, msg[j].len, 545 ibuf, msg[j].len,
550 DW210X_READ_MSG); 546 DW210X_READ_MSG);
551 memcpy(msg[j].buf, ibuf, msg[j].len); 547 memcpy(msg[j].buf, ibuf, msg[j].len);
@@ -563,7 +559,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
563 do { 559 do {
564 memcpy(obuf + 3, msg[j].buf + i, 560 memcpy(obuf + 3, msg[j].buf + i,
565 (len > 16 ? 16 : len)); 561 (len > 16 ? 16 : len));
566 ret = dw210x_op_rw(d->udev, 0x80, 0, 0, 562 dw210x_op_rw(d->udev, 0x80, 0, 0,
567 obuf, (len > 16 ? 16 : len) + 3, 563 obuf, (len > 16 ? 16 : len) + 3,
568 DW210X_WRITE_MSG); 564 DW210X_WRITE_MSG);
569 i += 16; 565 i += 16;
@@ -575,7 +571,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
575 obuf[0] = msg[j + 1].len; 571 obuf[0] = msg[j + 1].len;
576 obuf[1] = (msg[j].addr << 1); 572 obuf[1] = (msg[j].addr << 1);
577 memcpy(obuf + 2, msg[j].buf, msg[j].len); 573 memcpy(obuf + 2, msg[j].buf, msg[j].len);
578 ret = dw210x_op_rw(d->udev, 574 dw210x_op_rw(d->udev,
579 udev->descriptor.idProduct == 575 udev->descriptor.idProduct ==
580 0x7500 ? 0x92 : 0x90, 0, 0, 576 0x7500 ? 0x92 : 0x90, 0, 0,
581 obuf, msg[j].len + 2, 577 obuf, msg[j].len + 2,
@@ -587,7 +583,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
587 obuf[0] = msg[j].len + 1; 583 obuf[0] = msg[j].len + 1;
588 obuf[1] = (msg[j].addr << 1); 584 obuf[1] = (msg[j].addr << 1);
589 memcpy(obuf + 2, msg[j].buf, msg[j].len); 585 memcpy(obuf + 2, msg[j].buf, msg[j].len);
590 ret = dw210x_op_rw(d->udev, 0x80, 0, 0, 586 dw210x_op_rw(d->udev, 0x80, 0, 0,
591 obuf, msg[j].len + 2, 587 obuf, msg[j].len + 2,
592 DW210X_WRITE_MSG); 588 DW210X_WRITE_MSG);
593 break; 589 break;
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index 482d249ca7f3..6244fe9d1a3a 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -81,7 +81,7 @@ static int it913x_bulk_write(struct usb_device *dev,
81 for (i = 0; i < IT913X_RETRY; i++) { 81 for (i = 0; i < IT913X_RETRY; i++) {
82 ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), 82 ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
83 snd, len , &actual_l, IT913X_SND_TIMEOUT); 83 snd, len , &actual_l, IT913X_SND_TIMEOUT);
84 if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) 84 if (ret != -EBUSY && ret != -ETIMEDOUT)
85 break; 85 break;
86 } 86 }
87 87
@@ -99,7 +99,7 @@ static int it913x_bulk_read(struct usb_device *dev,
99 for (i = 0; i < IT913X_RETRY; i++) { 99 for (i = 0; i < IT913X_RETRY; i++) {
100 ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), 100 ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
101 rev, len , &actual_l, IT913X_RCV_TIMEOUT); 101 rev, len , &actual_l, IT913X_RCV_TIMEOUT);
102 if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT) 102 if (ret != -EBUSY && ret != -ETIMEDOUT)
103 break; 103 break;
104 } 104 }
105 105
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index 5dde06d066ff..25d1031460f8 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -373,7 +373,7 @@ static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
373 struct lme2510_state *st = adap->dev->priv; 373 struct lme2510_state *st = adap->dev->priv;
374 static u8 clear_pid_reg[] = LME_ALL_PIDS; 374 static u8 clear_pid_reg[] = LME_ALL_PIDS;
375 static u8 rbuf[1]; 375 static u8 rbuf[1];
376 int ret; 376 int ret = 0;
377 377
378 deb_info(1, "PID Clearing Filter"); 378 deb_info(1, "PID Clearing Filter");
379 379
@@ -1205,14 +1205,13 @@ static int lme2510_probe(struct usb_interface *intf,
1205 const struct usb_device_id *id) 1205 const struct usb_device_id *id)
1206{ 1206{
1207 struct usb_device *udev = interface_to_usbdev(intf); 1207 struct usb_device *udev = interface_to_usbdev(intf);
1208 int ret = 0;
1209 1208
1210 usb_reset_configuration(udev); 1209 usb_reset_configuration(udev);
1211 1210
1212 usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1); 1211 usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
1213 1212
1214 if (udev->speed != USB_SPEED_HIGH) { 1213 if (udev->speed != USB_SPEED_HIGH) {
1215 ret = usb_reset_device(udev); 1214 usb_reset_device(udev);
1216 info("DEV Failed to connect in HIGH SPEED mode"); 1215 info("DEV Failed to connect in HIGH SPEED mode");
1217 return -ENODEV; 1216 return -ENODEV;
1218 } 1217 }
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
index 72db6eef4b9c..74da5bb1ce99 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
@@ -284,6 +284,7 @@ static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
284 284
285 switch (delsys) { 285 switch (delsys) {
286 case SYS_ATSC: 286 case SYS_ATSC:
287 case SYS_ATSCMH:
287 bw = 0; /* ATSC */ 288 bw = 0; /* ATSC */
288 break; 289 break;
289 case SYS_DVBC_ANNEX_B: 290 case SYS_DVBC_ANNEX_B:
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
index 81305de2fea5..cd842798f5af 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.c
@@ -21,6 +21,7 @@
21#include "mxl111sf-tuner.h" 21#include "mxl111sf-tuner.h"
22 22
23#include "lgdt3305.h" 23#include "lgdt3305.h"
24#include "lg2160.h"
24 25
25int dvb_usb_mxl111sf_debug; 26int dvb_usb_mxl111sf_debug;
26module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644); 27module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
@@ -31,6 +32,10 @@ int dvb_usb_mxl111sf_isoc;
31module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644); 32module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
32MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc)."); 33MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
33 34
35int dvb_usb_mxl111sf_spi;
36module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
37MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
38
34#define ANT_PATH_AUTO 0 39#define ANT_PATH_AUTO 0
35#define ANT_PATH_EXTERNAL 1 40#define ANT_PATH_EXTERNAL 1
36#define ANT_PATH_INTERNAL 2 41#define ANT_PATH_INTERNAL 2
@@ -340,7 +345,6 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
340 struct mxl111sf_state *state = d->priv; 345 struct mxl111sf_state *state = d->priv;
341 struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv; 346 struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv;
342 int ret = 0; 347 int ret = 0;
343 u8 tmp;
344 348
345 deb_info("%s(%d)\n", __func__, onoff); 349 deb_info("%s(%d)\n", __func__, onoff);
346 350
@@ -361,6 +365,33 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
361 return ret; 365 return ret;
362} 366}
363 367
368static int mxl111sf_ep5_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
369{
370 struct dvb_usb_device *d = adap->dev;
371 struct mxl111sf_state *state = d->priv;
372 int ret = 0;
373
374 deb_info("%s(%d)\n", __func__, onoff);
375
376 if (onoff) {
377 ret = mxl111sf_enable_usb_output(state);
378 mxl_fail(ret);
379
380 ret = mxl111sf_init_i2s_port(state, 200);
381 mxl_fail(ret);
382 ret = mxl111sf_config_i2s(state, 0, 15);
383 mxl_fail(ret);
384 } else {
385 ret = mxl111sf_disable_i2s_port(state);
386 mxl_fail(ret);
387 }
388 if (state->chip_rev > MXL111SF_V6)
389 ret = mxl111sf_config_spi(state, onoff);
390 mxl_fail(ret);
391
392 return ret;
393}
394
364static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 395static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
365{ 396{
366 struct dvb_usb_device *d = adap->dev; 397 struct dvb_usb_device *d = adap->dev;
@@ -453,6 +484,255 @@ fail:
453 return ret; 484 return ret;
454} 485}
455 486
487static struct lg2160_config hauppauge_lg2160_config = {
488 .lg_chip = LG2160,
489 .i2c_addr = 0x1c >> 1,
490 .deny_i2c_rptr = 1,
491 .spectral_inversion = 0,
492 .if_khz = 6000,
493};
494
495static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap)
496{
497 struct dvb_usb_device *d = adap->dev;
498 struct mxl111sf_state *state = d->priv;
499 int fe_id = adap->num_frontends_initialized;
500 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
501 int ret;
502
503 deb_adv("%s()\n", __func__);
504
505 /* save a pointer to the dvb_usb_device in device state */
506 state->d = d;
507 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
508 state->alt_mode = adap_state->alt_mode;
509
510 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
511 err("set interface failed");
512
513 state->gpio_mode = MXL111SF_GPIO_MOD_MH;
514 adap_state->gpio_mode = state->gpio_mode;
515 adap_state->device_mode = MXL_TUNER_MODE;
516 adap_state->ep6_clockphase = 1;
517
518 ret = mxl1x1sf_soft_reset(state);
519 if (mxl_fail(ret))
520 goto fail;
521 ret = mxl111sf_init_tuner_demod(state);
522 if (mxl_fail(ret))
523 goto fail;
524
525 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
526 if (mxl_fail(ret))
527 goto fail;
528
529 ret = mxl111sf_enable_usb_output(state);
530 if (mxl_fail(ret))
531 goto fail;
532 ret = mxl1x1sf_top_master_ctrl(state, 1);
533 if (mxl_fail(ret))
534 goto fail;
535
536 ret = mxl111sf_init_port_expander(state);
537 if (mxl_fail(ret))
538 goto fail;
539 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
540 if (mxl_fail(ret))
541 goto fail;
542
543 ret = get_chip_info(state);
544 if (mxl_fail(ret))
545 goto fail;
546
547 adap->fe_adap[fe_id].fe = dvb_attach(lg2160_attach,
548 &hauppauge_lg2160_config,
549 &adap->dev->i2c_adap);
550 if (adap->fe_adap[fe_id].fe) {
551 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
552 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
553 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
554 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
555 return 0;
556 }
557 ret = -EIO;
558fail:
559 return ret;
560}
561
562static struct lg2160_config hauppauge_lg2161_1019_config = {
563 .lg_chip = LG2161_1019,
564 .i2c_addr = 0x1c >> 1,
565 .deny_i2c_rptr = 1,
566 .spectral_inversion = 0,
567 .if_khz = 6000,
568 .output_if = 2, /* LG2161_OIF_SPI_MAS */
569};
570
571static struct lg2160_config hauppauge_lg2161_1040_config = {
572 .lg_chip = LG2161_1040,
573 .i2c_addr = 0x1c >> 1,
574 .deny_i2c_rptr = 1,
575 .spectral_inversion = 0,
576 .if_khz = 6000,
577 .output_if = 4, /* LG2161_OIF_SPI_MAS */
578};
579
580static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap)
581{
582 struct dvb_usb_device *d = adap->dev;
583 struct mxl111sf_state *state = d->priv;
584 int fe_id = adap->num_frontends_initialized;
585 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
586 int ret;
587
588 deb_adv("%s()\n", __func__);
589
590 /* save a pointer to the dvb_usb_device in device state */
591 state->d = d;
592 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
593 state->alt_mode = adap_state->alt_mode;
594
595 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
596 err("set interface failed");
597
598 state->gpio_mode = MXL111SF_GPIO_MOD_MH;
599 adap_state->gpio_mode = state->gpio_mode;
600 adap_state->device_mode = MXL_TUNER_MODE;
601 adap_state->ep6_clockphase = 1;
602
603 ret = mxl1x1sf_soft_reset(state);
604 if (mxl_fail(ret))
605 goto fail;
606 ret = mxl111sf_init_tuner_demod(state);
607 if (mxl_fail(ret))
608 goto fail;
609
610 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
611 if (mxl_fail(ret))
612 goto fail;
613
614 ret = mxl111sf_enable_usb_output(state);
615 if (mxl_fail(ret))
616 goto fail;
617 ret = mxl1x1sf_top_master_ctrl(state, 1);
618 if (mxl_fail(ret))
619 goto fail;
620
621 ret = mxl111sf_init_port_expander(state);
622 if (mxl_fail(ret))
623 goto fail;
624 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
625 if (mxl_fail(ret))
626 goto fail;
627
628 ret = get_chip_info(state);
629 if (mxl_fail(ret))
630 goto fail;
631
632 adap->fe_adap[fe_id].fe = dvb_attach(lg2160_attach,
633 (MXL111SF_V8_200 == state->chip_rev) ?
634 &hauppauge_lg2161_1040_config :
635 &hauppauge_lg2161_1019_config,
636 &adap->dev->i2c_adap);
637 if (adap->fe_adap[fe_id].fe) {
638 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
639 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
640 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
641 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
642 return 0;
643 }
644 ret = -EIO;
645fail:
646 return ret;
647}
648
649static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
650 .lg_chip = LG2161_1019,
651 .i2c_addr = 0x1c >> 1,
652 .deny_i2c_rptr = 1,
653 .spectral_inversion = 0,
654 .if_khz = 6000,
655 .output_if = 1, /* LG2161_OIF_SERIAL_TS */
656};
657
658static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
659 .lg_chip = LG2161_1040,
660 .i2c_addr = 0x1c >> 1,
661 .deny_i2c_rptr = 1,
662 .spectral_inversion = 0,
663 .if_khz = 6000,
664 .output_if = 7, /* LG2161_OIF_SERIAL_TS */
665};
666
667static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap)
668{
669 struct dvb_usb_device *d = adap->dev;
670 struct mxl111sf_state *state = d->priv;
671 int fe_id = adap->num_frontends_initialized;
672 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
673 int ret;
674
675 deb_adv("%s()\n", __func__);
676
677 /* save a pointer to the dvb_usb_device in device state */
678 state->d = d;
679 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
680 state->alt_mode = adap_state->alt_mode;
681
682 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
683 err("set interface failed");
684
685 state->gpio_mode = MXL111SF_GPIO_MOD_MH;
686 adap_state->gpio_mode = state->gpio_mode;
687 adap_state->device_mode = MXL_TUNER_MODE;
688 adap_state->ep6_clockphase = 0;
689
690 ret = mxl1x1sf_soft_reset(state);
691 if (mxl_fail(ret))
692 goto fail;
693 ret = mxl111sf_init_tuner_demod(state);
694 if (mxl_fail(ret))
695 goto fail;
696
697 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
698 if (mxl_fail(ret))
699 goto fail;
700
701 ret = mxl111sf_enable_usb_output(state);
702 if (mxl_fail(ret))
703 goto fail;
704 ret = mxl1x1sf_top_master_ctrl(state, 1);
705 if (mxl_fail(ret))
706 goto fail;
707
708 ret = mxl111sf_init_port_expander(state);
709 if (mxl_fail(ret))
710 goto fail;
711 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
712 if (mxl_fail(ret))
713 goto fail;
714
715 ret = get_chip_info(state);
716 if (mxl_fail(ret))
717 goto fail;
718
719 adap->fe_adap[fe_id].fe = dvb_attach(lg2160_attach,
720 (MXL111SF_V8_200 == state->chip_rev) ?
721 &hauppauge_lg2161_1040_ep6_config :
722 &hauppauge_lg2161_1019_ep6_config,
723 &adap->dev->i2c_adap);
724 if (adap->fe_adap[fe_id].fe) {
725 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
726 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
727 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
728 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
729 return 0;
730 }
731 ret = -EIO;
732fail:
733 return ret;
734}
735
456static struct mxl111sf_demod_config mxl_demod_config = { 736static struct mxl111sf_demod_config mxl_demod_config = {
457 .read_reg = mxl111sf_read_reg, 737 .read_reg = mxl111sf_read_reg,
458 .write_reg = mxl111sf_write_reg, 738 .write_reg = mxl111sf_write_reg,
@@ -650,6 +930,18 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
650static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties; 930static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
651static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; 931static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
652static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; 932static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
933static struct dvb_usb_device_properties mxl111sf_atsc_mh_bulk_properties;
934static struct dvb_usb_device_properties mxl111sf_atsc_mh_isoc_properties;
935static struct dvb_usb_device_properties mxl111sf_mh_bulk_properties;
936static struct dvb_usb_device_properties mxl111sf_mh_isoc_properties;
937static struct dvb_usb_device_properties mxl111sf_mercury_spi_bulk_properties;
938static struct dvb_usb_device_properties mxl111sf_mercury_spi_isoc_properties;
939static struct dvb_usb_device_properties mxl111sf_mercury_tp_bulk_properties;
940static struct dvb_usb_device_properties mxl111sf_mercury_tp_isoc_properties;
941static struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_bulk_properties;
942static struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_isoc_properties;
943static struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_bulk_properties;
944static struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_isoc_properties;
653 945
654static int mxl111sf_probe(struct usb_interface *intf, 946static int mxl111sf_probe(struct usb_interface *intf,
655 const struct usb_device_id *id) 947 const struct usb_device_id *id)
@@ -664,12 +956,50 @@ static int mxl111sf_probe(struct usb_interface *intf,
664 THIS_MODULE, &d, adapter_nr) || 956 THIS_MODULE, &d, adapter_nr) ||
665 0 == dvb_usb_device_init(intf, 957 0 == dvb_usb_device_init(intf,
666 &mxl111sf_atsc_isoc_properties, 958 &mxl111sf_atsc_isoc_properties,
959 THIS_MODULE, &d, adapter_nr) ||
960 0 == dvb_usb_device_init(intf,
961 &mxl111sf_atsc_mh_isoc_properties,
962 THIS_MODULE, &d, adapter_nr) ||
963 0 == dvb_usb_device_init(intf,
964 &mxl111sf_mh_isoc_properties,
965 THIS_MODULE, &d, adapter_nr) ||
966 ((dvb_usb_mxl111sf_spi) &&
967 (0 == dvb_usb_device_init(intf,
968 &mxl111sf_mercury_spi_isoc_properties,
969 THIS_MODULE, &d, adapter_nr) ||
970 0 == dvb_usb_device_init(intf,
971 &mxl111sf_mercury_mh_spi_isoc_properties,
972 THIS_MODULE, &d, adapter_nr))) ||
973 0 == dvb_usb_device_init(intf,
974 &mxl111sf_mercury_tp_isoc_properties,
975 THIS_MODULE, &d, adapter_nr) ||
976 0 == dvb_usb_device_init(intf,
977 &mxl111sf_mercury_mh_tp_isoc_properties,
667 THIS_MODULE, &d, adapter_nr))) || 978 THIS_MODULE, &d, adapter_nr))) ||
668 0 == dvb_usb_device_init(intf, 979 0 == dvb_usb_device_init(intf,
669 &mxl111sf_dvbt_bulk_properties, 980 &mxl111sf_dvbt_bulk_properties,
670 THIS_MODULE, &d, adapter_nr) || 981 THIS_MODULE, &d, adapter_nr) ||
671 0 == dvb_usb_device_init(intf, 982 0 == dvb_usb_device_init(intf,
672 &mxl111sf_atsc_bulk_properties, 983 &mxl111sf_atsc_bulk_properties,
984 THIS_MODULE, &d, adapter_nr) ||
985 0 == dvb_usb_device_init(intf,
986 &mxl111sf_atsc_mh_bulk_properties,
987 THIS_MODULE, &d, adapter_nr) ||
988 0 == dvb_usb_device_init(intf,
989 &mxl111sf_mh_bulk_properties,
990 THIS_MODULE, &d, adapter_nr) ||
991 ((dvb_usb_mxl111sf_spi) &&
992 (0 == dvb_usb_device_init(intf,
993 &mxl111sf_mercury_spi_bulk_properties,
994 THIS_MODULE, &d, adapter_nr) ||
995 0 == dvb_usb_device_init(intf,
996 &mxl111sf_mercury_mh_spi_bulk_properties,
997 THIS_MODULE, &d, adapter_nr))) ||
998 0 == dvb_usb_device_init(intf,
999 &mxl111sf_mercury_tp_bulk_properties,
1000 THIS_MODULE, &d, adapter_nr) ||
1001 0 == dvb_usb_device_init(intf,
1002 &mxl111sf_mercury_mh_tp_bulk_properties,
673 THIS_MODULE, &d, adapter_nr) || 0) { 1003 THIS_MODULE, &d, adapter_nr) || 0) {
674 1004
675 struct mxl111sf_state *state = d->priv; 1005 struct mxl111sf_state *state = d->priv;
@@ -787,6 +1117,36 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table);
787 } \ 1117 } \
788 } 1118 }
789 1119
1120#define MXL111SF_EP5_BULK_STREAMING_CONFIG \
1121 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
1122 .streaming_ctrl = mxl111sf_ep5_streaming_ctrl, \
1123 .stream = { \
1124 .type = USB_BULK, \
1125 .count = 5, \
1126 .endpoint = 0x05, \
1127 .u = { \
1128 .bulk = { \
1129 .buffersize = 8192, \
1130 } \
1131 } \
1132 }
1133
1134#define MXL111SF_EP5_ISOC_STREAMING_CONFIG \
1135 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
1136 .streaming_ctrl = mxl111sf_ep5_streaming_ctrl, \
1137 .stream = { \
1138 .type = USB_ISOC, \
1139 .count = 5, \
1140 .endpoint = 0x05, \
1141 .u = { \
1142 .isoc = { \
1143 .framesperurb = 96, \
1144 .framesize = 200, \
1145 .interval = 1, \
1146 } \
1147 } \
1148 }
1149
790#define MXL111SF_EP6_BULK_STREAMING_CONFIG \ 1150#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
791 .size_of_priv = sizeof(struct mxl111sf_adap_state), \ 1151 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
792 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ 1152 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
@@ -848,7 +1208,7 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
848 } }, 1208 } },
849 }, 1209 },
850 }, 1210 },
851 .num_device_descs = 4, 1211 .num_device_descs = 3,
852 .devices = { 1212 .devices = {
853 { "Hauppauge 126xxx DVBT (bulk)", 1213 { "Hauppauge 126xxx DVBT (bulk)",
854 { NULL }, 1214 { NULL },
@@ -866,11 +1226,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
866 &mxl111sf_table[24], &mxl111sf_table[26], 1226 &mxl111sf_table[24], &mxl111sf_table[26],
867 NULL }, 1227 NULL },
868 }, 1228 },
869 { "Hauppauge 126xxx (tp-bulk)",
870 { NULL },
871 { &mxl111sf_table[28], &mxl111sf_table[30],
872 NULL },
873 },
874 } 1229 }
875}; 1230};
876 1231
@@ -890,7 +1245,7 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
890 } }, 1245 } },
891 }, 1246 },
892 }, 1247 },
893 .num_device_descs = 4, 1248 .num_device_descs = 3,
894 .devices = { 1249 .devices = {
895 { "Hauppauge 126xxx DVBT (isoc)", 1250 { "Hauppauge 126xxx DVBT (isoc)",
896 { NULL }, 1251 { NULL },
@@ -908,11 +1263,6 @@ static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
908 &mxl111sf_table[24], &mxl111sf_table[26], 1263 &mxl111sf_table[24], &mxl111sf_table[26],
909 NULL }, 1264 NULL },
910 }, 1265 },
911 { "Hauppauge 126xxx (tp-isoc)",
912 { NULL },
913 { &mxl111sf_table[28], &mxl111sf_table[30],
914 NULL },
915 },
916 } 1266 }
917}; 1267};
918 1268
@@ -923,33 +1273,159 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
923 .adapter = { 1273 .adapter = {
924 { 1274 {
925 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 1275 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
926 .num_frontends = 2, 1276 .num_frontends = 1,
927 .fe = {{ 1277 .fe = {{
928 .frontend_attach = mxl111sf_lgdt3305_frontend_attach, 1278 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
929 .tuner_attach = mxl111sf_attach_tuner, 1279 .tuner_attach = mxl111sf_attach_tuner,
930 1280
931 MXL111SF_EP6_BULK_STREAMING_CONFIG, 1281 MXL111SF_EP6_BULK_STREAMING_CONFIG,
1282 }},
932 }, 1283 },
1284 },
1285 .num_device_descs = 2,
1286 .devices = {
1287 { "Hauppauge 126xxx ATSC (bulk)",
1288 { NULL },
1289 { &mxl111sf_table[1], &mxl111sf_table[5],
1290 NULL },
1291 },
1292 { "Hauppauge 117xxx ATSC (bulk)",
1293 { NULL },
1294 { &mxl111sf_table[12],
1295 NULL },
1296 },
1297 }
1298};
1299
1300static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
1301 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1302
1303 .num_adapters = 1,
1304 .adapter = {
933 { 1305 {
934 .frontend_attach = mxl111sf_attach_demod, 1306 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1307 .num_frontends = 1,
1308 .fe = {{
1309 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
935 .tuner_attach = mxl111sf_attach_tuner, 1310 .tuner_attach = mxl111sf_attach_tuner,
936 1311
937 MXL111SF_EP4_BULK_STREAMING_CONFIG, 1312 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
938 }}, 1313 }},
939 }, 1314 },
940 }, 1315 },
941 .num_device_descs = 6, 1316 .num_device_descs = 2,
942 .devices = { 1317 .devices = {
943 { "Hauppauge 126xxx ATSC (bulk)", 1318 { "Hauppauge 126xxx ATSC (isoc)",
944 { NULL }, 1319 { NULL },
945 { &mxl111sf_table[1], &mxl111sf_table[5], 1320 { &mxl111sf_table[1], &mxl111sf_table[5],
946 NULL }, 1321 NULL },
947 }, 1322 },
948 { "Hauppauge 117xxx ATSC (bulk)", 1323 { "Hauppauge 117xxx ATSC (isoc)",
949 { NULL }, 1324 { NULL },
950 { &mxl111sf_table[12], 1325 { &mxl111sf_table[12],
951 NULL }, 1326 NULL },
952 }, 1327 },
1328 }
1329};
1330
1331static struct dvb_usb_device_properties mxl111sf_mh_bulk_properties = {
1332 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1333
1334 .num_adapters = 1,
1335 .adapter = {
1336 {
1337 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1338 .num_frontends = 1,
1339 .fe = {{
1340 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1341
1342 .frontend_attach = mxl111sf_lg2160_frontend_attach,
1343 .tuner_attach = mxl111sf_attach_tuner,
1344
1345 MXL111SF_EP5_BULK_STREAMING_CONFIG,
1346 }},
1347 },
1348 },
1349 .num_device_descs = 2,
1350 .devices = {
1351 { "HCW 126xxx (bulk)",
1352 { NULL },
1353 { &mxl111sf_table[2], &mxl111sf_table[6],
1354 NULL },
1355 },
1356 { "HCW 117xxx (bulk)",
1357 { NULL },
1358 { &mxl111sf_table[13],
1359 NULL },
1360 },
1361 }
1362};
1363
1364static struct dvb_usb_device_properties mxl111sf_mh_isoc_properties = {
1365 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1366
1367 .num_adapters = 1,
1368 .adapter = {
1369 {
1370 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1371 .num_frontends = 1,
1372 .fe = {{
1373 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1374
1375 .frontend_attach = mxl111sf_lg2160_frontend_attach,
1376 .tuner_attach = mxl111sf_attach_tuner,
1377
1378 MXL111SF_EP5_ISOC_STREAMING_CONFIG,
1379 }},
1380 },
1381 },
1382 .num_device_descs = 2,
1383 .devices = {
1384 { "HCW 126xxx (isoc)",
1385 { NULL },
1386 { &mxl111sf_table[2], &mxl111sf_table[6],
1387 NULL },
1388 },
1389 { "HCW 117xxx (isoc)",
1390 { NULL },
1391 { &mxl111sf_table[13],
1392 NULL },
1393 },
1394 }
1395};
1396
1397static struct dvb_usb_device_properties mxl111sf_atsc_mh_bulk_properties = {
1398 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1399
1400 .num_adapters = 1,
1401 .adapter = {
1402 {
1403 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1404 .num_frontends = 3,
1405 .fe = {{
1406 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
1407 .tuner_attach = mxl111sf_attach_tuner,
1408
1409 MXL111SF_EP6_BULK_STREAMING_CONFIG,
1410 },
1411 {
1412 .frontend_attach = mxl111sf_attach_demod,
1413 .tuner_attach = mxl111sf_attach_tuner,
1414
1415 MXL111SF_EP4_BULK_STREAMING_CONFIG,
1416 },
1417 {
1418 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1419
1420 .frontend_attach = mxl111sf_lg2160_frontend_attach,
1421 .tuner_attach = mxl111sf_attach_tuner,
1422
1423 MXL111SF_EP5_BULK_STREAMING_CONFIG,
1424 }},
1425 },
1426 },
1427 .num_device_descs = 2,
1428 .devices = {
953 { "Hauppauge 126xxx ATSC+ (bulk)", 1429 { "Hauppauge 126xxx ATSC+ (bulk)",
954 { NULL }, 1430 { NULL },
955 { &mxl111sf_table[0], &mxl111sf_table[3], 1431 { &mxl111sf_table[0], &mxl111sf_table[3],
@@ -963,13 +1439,96 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
963 &mxl111sf_table[32], &mxl111sf_table[33], 1439 &mxl111sf_table[32], &mxl111sf_table[33],
964 NULL }, 1440 NULL },
965 }, 1441 },
966 { "Hauppauge Mercury (tp-bulk)", 1442 }
1443};
1444
1445static struct dvb_usb_device_properties mxl111sf_atsc_mh_isoc_properties = {
1446 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1447
1448 .num_adapters = 1,
1449 .adapter = {
1450 {
1451 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1452 .num_frontends = 3,
1453 .fe = {{
1454 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
1455 .tuner_attach = mxl111sf_attach_tuner,
1456
1457 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
1458 },
1459 {
1460 .frontend_attach = mxl111sf_attach_demod,
1461 .tuner_attach = mxl111sf_attach_tuner,
1462
1463 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1464 },
1465 {
1466 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1467
1468 .frontend_attach = mxl111sf_lg2160_frontend_attach,
1469 .tuner_attach = mxl111sf_attach_tuner,
1470
1471 MXL111SF_EP5_ISOC_STREAMING_CONFIG,
1472 }},
1473 },
1474 },
1475 .num_device_descs = 2,
1476 .devices = {
1477 { "Hauppauge 126xxx ATSC+ (isoc)",
1478 { NULL },
1479 { &mxl111sf_table[0], &mxl111sf_table[3],
1480 &mxl111sf_table[7], &mxl111sf_table[9],
1481 &mxl111sf_table[10], NULL },
1482 },
1483 { "Hauppauge 117xxx ATSC+ (isoc)",
1484 { NULL },
1485 { &mxl111sf_table[11], &mxl111sf_table[14],
1486 &mxl111sf_table[16], &mxl111sf_table[17],
1487 &mxl111sf_table[32], &mxl111sf_table[33],
1488 NULL },
1489 },
1490 }
1491};
1492
1493static struct dvb_usb_device_properties mxl111sf_mercury_spi_bulk_properties = {
1494 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1495
1496 .num_adapters = 1,
1497 .adapter = {
1498 {
1499 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1500 .num_frontends = 3,
1501 .fe = {{
1502 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
1503 .tuner_attach = mxl111sf_attach_tuner,
1504
1505 MXL111SF_EP6_BULK_STREAMING_CONFIG,
1506 },
1507 {
1508 .frontend_attach = mxl111sf_attach_demod,
1509 .tuner_attach = mxl111sf_attach_tuner,
1510
1511 MXL111SF_EP4_BULK_STREAMING_CONFIG,
1512 },
1513 {
1514 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1515
1516 .frontend_attach = mxl111sf_lg2161_frontend_attach,
1517 .tuner_attach = mxl111sf_attach_tuner,
1518
1519 MXL111SF_EP5_BULK_STREAMING_CONFIG,
1520 }},
1521 },
1522 },
1523 .num_device_descs = 2,
1524 .devices = {
1525 { "Hauppauge Mercury (spi-bulk)",
967 { NULL }, 1526 { NULL },
968 { &mxl111sf_table[19], &mxl111sf_table[21], 1527 { &mxl111sf_table[19], &mxl111sf_table[21],
969 &mxl111sf_table[23], &mxl111sf_table[25], 1528 &mxl111sf_table[23], &mxl111sf_table[25],
970 &mxl111sf_table[27], NULL }, 1529 NULL },
971 }, 1530 },
972 { "Hauppauge WinTV-Aero-M", 1531 { "Hauppauge WinTV-Aero-M (spi-bulk)",
973 { NULL }, 1532 { NULL },
974 { &mxl111sf_table[29], &mxl111sf_table[31], 1533 { &mxl111sf_table[29], &mxl111sf_table[31],
975 NULL }, 1534 NULL },
@@ -977,14 +1536,14 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
977 } 1536 }
978}; 1537};
979 1538
980static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { 1539static struct dvb_usb_device_properties mxl111sf_mercury_spi_isoc_properties = {
981 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 1540 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
982 1541
983 .num_adapters = 1, 1542 .num_adapters = 1,
984 .adapter = { 1543 .adapter = {
985 { 1544 {
986 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 1545 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
987 .num_frontends = 2, 1546 .num_frontends = 3,
988 .fe = {{ 1547 .fe = {{
989 .frontend_attach = mxl111sf_lgdt3305_frontend_attach, 1548 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
990 .tuner_attach = mxl111sf_attach_tuner, 1549 .tuner_attach = mxl111sf_attach_tuner,
@@ -996,34 +1555,111 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
996 .tuner_attach = mxl111sf_attach_tuner, 1555 .tuner_attach = mxl111sf_attach_tuner,
997 1556
998 MXL111SF_EP4_ISOC_STREAMING_CONFIG, 1557 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1558 },
1559 {
1560 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1561
1562 .frontend_attach = mxl111sf_lg2161_frontend_attach,
1563 .tuner_attach = mxl111sf_attach_tuner,
1564
1565 MXL111SF_EP5_ISOC_STREAMING_CONFIG,
999 }}, 1566 }},
1000 }, 1567 },
1001 }, 1568 },
1002 .num_device_descs = 6, 1569 .num_device_descs = 2,
1003 .devices = { 1570 .devices = {
1004 { "Hauppauge 126xxx ATSC (isoc)", 1571 { "Hauppauge Mercury (spi-isoc)",
1005 { NULL }, 1572 { NULL },
1006 { &mxl111sf_table[1], &mxl111sf_table[5], 1573 { &mxl111sf_table[19], &mxl111sf_table[21],
1574 &mxl111sf_table[23], &mxl111sf_table[25],
1007 NULL }, 1575 NULL },
1008 }, 1576 },
1009 { "Hauppauge 117xxx ATSC (isoc)", 1577 { "Hauppauge WinTV-Aero-M (spi-isoc)",
1010 { NULL }, 1578 { NULL },
1011 { &mxl111sf_table[12], 1579 { &mxl111sf_table[29], &mxl111sf_table[31],
1012 NULL }, 1580 NULL },
1013 }, 1581 },
1014 { "Hauppauge 126xxx ATSC+ (isoc)", 1582 }
1583};
1584
1585static struct dvb_usb_device_properties mxl111sf_mercury_tp_bulk_properties = {
1586 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1587
1588 .num_adapters = 1,
1589 .adapter = {
1590 {
1591 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1592 .num_frontends = 3,
1593 .fe = {{
1594 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
1595 .tuner_attach = mxl111sf_attach_tuner,
1596
1597 MXL111SF_EP6_BULK_STREAMING_CONFIG,
1598 },
1599 {
1600 .frontend_attach = mxl111sf_attach_demod,
1601 .tuner_attach = mxl111sf_attach_tuner,
1602
1603 MXL111SF_EP4_BULK_STREAMING_CONFIG,
1604 },
1605 {
1606 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1607
1608 .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
1609 .tuner_attach = mxl111sf_attach_tuner,
1610
1611 MXL111SF_EP6_BULK_STREAMING_CONFIG,
1612 }},
1613 },
1614 },
1615 .num_device_descs = 2,
1616 .devices = {
1617 { "Hauppauge Mercury (tp-bulk)",
1015 { NULL }, 1618 { NULL },
1016 { &mxl111sf_table[0], &mxl111sf_table[3], 1619 { &mxl111sf_table[19], &mxl111sf_table[21],
1017 &mxl111sf_table[7], &mxl111sf_table[9], 1620 &mxl111sf_table[23], &mxl111sf_table[25],
1018 &mxl111sf_table[10], NULL }, 1621 &mxl111sf_table[27], NULL },
1019 }, 1622 },
1020 { "Hauppauge 117xxx ATSC+ (isoc)", 1623 { "Hauppauge WinTV-Aero-M",
1021 { NULL }, 1624 { NULL },
1022 { &mxl111sf_table[11], &mxl111sf_table[14], 1625 { &mxl111sf_table[29], &mxl111sf_table[31],
1023 &mxl111sf_table[16], &mxl111sf_table[17],
1024 &mxl111sf_table[32], &mxl111sf_table[33],
1025 NULL }, 1626 NULL },
1026 }, 1627 },
1628 }
1629};
1630
1631static struct dvb_usb_device_properties mxl111sf_mercury_tp_isoc_properties = {
1632 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1633
1634 .num_adapters = 1,
1635 .adapter = {
1636 {
1637 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1638 .num_frontends = 3,
1639 .fe = {{
1640 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
1641 .tuner_attach = mxl111sf_attach_tuner,
1642
1643 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
1644 },
1645 {
1646 .frontend_attach = mxl111sf_attach_demod,
1647 .tuner_attach = mxl111sf_attach_tuner,
1648
1649 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1650 },
1651 {
1652 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1653
1654 .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
1655 .tuner_attach = mxl111sf_attach_tuner,
1656
1657 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
1658 }},
1659 },
1660 },
1661 .num_device_descs = 2,
1662 .devices = {
1027 { "Hauppauge Mercury (tp-isoc)", 1663 { "Hauppauge Mercury (tp-isoc)",
1028 { NULL }, 1664 { NULL },
1029 { &mxl111sf_table[19], &mxl111sf_table[21], 1665 { &mxl111sf_table[19], &mxl111sf_table[21],
@@ -1038,6 +1674,146 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
1038 } 1674 }
1039}; 1675};
1040 1676
1677static
1678struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_bulk_properties = {
1679 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1680
1681 .num_adapters = 1,
1682 .adapter = {
1683 {
1684 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1685 .num_frontends = 2,
1686 .fe = {{
1687 .frontend_attach = mxl111sf_attach_demod,
1688 .tuner_attach = mxl111sf_attach_tuner,
1689
1690 MXL111SF_EP4_BULK_STREAMING_CONFIG,
1691 },
1692 {
1693 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1694
1695 .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
1696 .tuner_attach = mxl111sf_attach_tuner,
1697
1698 MXL111SF_EP6_BULK_STREAMING_CONFIG,
1699 }},
1700 },
1701 },
1702 .num_device_descs = 1,
1703 .devices = {
1704 { "Hauppauge 126xxx (tp-bulk)",
1705 { NULL },
1706 { &mxl111sf_table[28], &mxl111sf_table[30],
1707 NULL },
1708 },
1709 }
1710};
1711
1712static
1713struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_isoc_properties = {
1714 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1715
1716 .num_adapters = 1,
1717 .adapter = {
1718 {
1719 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1720 .num_frontends = 2,
1721 .fe = {{
1722 .frontend_attach = mxl111sf_attach_demod,
1723 .tuner_attach = mxl111sf_attach_tuner,
1724
1725 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1726 },
1727 {
1728 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1729
1730 .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
1731 .tuner_attach = mxl111sf_attach_tuner,
1732
1733 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
1734 }},
1735 },
1736 },
1737 .num_device_descs = 1,
1738 .devices = {
1739 { "Hauppauge 126xxx (tp-isoc)",
1740 { NULL },
1741 { &mxl111sf_table[28], &mxl111sf_table[30],
1742 NULL },
1743 },
1744 }
1745};
1746
1747static
1748struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_bulk_properties = {
1749 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1750
1751 .num_adapters = 1,
1752 .adapter = {
1753 {
1754 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1755 .num_frontends = 2,
1756 .fe = {{
1757 .frontend_attach = mxl111sf_attach_demod,
1758 .tuner_attach = mxl111sf_attach_tuner,
1759
1760 MXL111SF_EP4_BULK_STREAMING_CONFIG,
1761 },
1762 {
1763 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1764
1765 .frontend_attach = mxl111sf_lg2161_frontend_attach,
1766 .tuner_attach = mxl111sf_attach_tuner,
1767
1768 MXL111SF_EP5_BULK_STREAMING_CONFIG,
1769 }},
1770 },
1771 },
1772 .num_device_descs = 1,
1773 .devices = {
1774 { "Hauppauge 126xxx (spi-bulk)",
1775 { NULL },
1776 { &mxl111sf_table[28], &mxl111sf_table[30],
1777 NULL },
1778 },
1779 }
1780};
1781
1782static
1783struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_isoc_properties = {
1784 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
1785
1786 .num_adapters = 1,
1787 .adapter = {
1788 {
1789 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
1790 .num_frontends = 2,
1791 .fe = {{
1792 .frontend_attach = mxl111sf_attach_demod,
1793 .tuner_attach = mxl111sf_attach_tuner,
1794
1795 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1796 },
1797 {
1798 .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
1799
1800 .frontend_attach = mxl111sf_lg2161_frontend_attach,
1801 .tuner_attach = mxl111sf_attach_tuner,
1802
1803 MXL111SF_EP5_ISOC_STREAMING_CONFIG,
1804 }},
1805 },
1806 },
1807 .num_device_descs = 1,
1808 .devices = {
1809 { "Hauppauge 126xxx (spi-isoc)",
1810 { NULL },
1811 { &mxl111sf_table[28], &mxl111sf_table[30],
1812 NULL },
1813 },
1814 }
1815};
1816
1041static struct usb_driver mxl111sf_driver = { 1817static struct usb_driver mxl111sf_driver = {
1042 .name = "dvb_usb_mxl111sf", 1818 .name = "dvb_usb_mxl111sf",
1043 .probe = mxl111sf_probe, 1819 .probe = mxl111sf_probe,
diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.c b/drivers/media/dvb/dvb-usb/rtl28xxu.c
index 8f4736a10fc8..41e1f5537f44 100644
--- a/drivers/media/dvb/dvb-usb/rtl28xxu.c
+++ b/drivers/media/dvb/dvb-usb/rtl28xxu.c
@@ -322,6 +322,9 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
322 * since there is some demod params needed to set according to tuner. 322 * since there is some demod params needed to set according to tuner.
323 */ 323 */
324 324
325 /* demod needs some time to wake up */
326 msleep(20);
327
325 /* open demod I2C gate */ 328 /* open demod I2C gate */
326 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate); 329 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
327 if (ret) 330 if (ret)
@@ -909,6 +912,8 @@ static int rtl28xxu_probe(struct usb_interface *intf,
909 int ret, i; 912 int ret, i;
910 int properties_count = ARRAY_SIZE(rtl28xxu_properties); 913 int properties_count = ARRAY_SIZE(rtl28xxu_properties);
911 struct dvb_usb_device *d; 914 struct dvb_usb_device *d;
915 struct usb_device *udev;
916 bool found;
912 917
913 deb_info("%s: interface=%d\n", __func__, 918 deb_info("%s: interface=%d\n", __func__,
914 intf->cur_altsetting->desc.bInterfaceNumber); 919 intf->cur_altsetting->desc.bInterfaceNumber);
@@ -916,6 +921,29 @@ static int rtl28xxu_probe(struct usb_interface *intf,
916 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 921 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
917 return 0; 922 return 0;
918 923
924 /* Dynamic USB ID support. Replaces first device ID with current one .*/
925 udev = interface_to_usbdev(intf);
926
927 for (i = 0, found = false; i < ARRAY_SIZE(rtl28xxu_table) - 1; i++) {
928 if (rtl28xxu_table[i].idVendor ==
929 le16_to_cpu(udev->descriptor.idVendor) &&
930 rtl28xxu_table[i].idProduct ==
931 le16_to_cpu(udev->descriptor.idProduct)) {
932 found = true;
933 break;
934 }
935 }
936
937 if (!found) {
938 deb_info("%s: using dynamic ID %04x:%04x\n", __func__,
939 le16_to_cpu(udev->descriptor.idVendor),
940 le16_to_cpu(udev->descriptor.idProduct));
941 rtl28xxu_properties[0].devices[0].warm_ids[0]->idVendor =
942 le16_to_cpu(udev->descriptor.idVendor);
943 rtl28xxu_properties[0].devices[0].warm_ids[0]->idProduct =
944 le16_to_cpu(udev->descriptor.idProduct);
945 }
946
919 for (i = 0; i < properties_count; i++) { 947 for (i = 0; i < properties_count; i++) {
920 ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i], 948 ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i],
921 THIS_MODULE, &d, adapter_nr); 949 THIS_MODULE, &d, adapter_nr);
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 21246707fbfb..b98ebb264e29 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -531,6 +531,14 @@ config DVB_LGDT3305
531 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 531 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
532 to support this frontend. 532 to support this frontend.
533 533
534config DVB_LG2160
535 tristate "LG Electronics LG216x based"
536 depends on DVB_CORE && I2C
537 default m if DVB_FE_CUSTOMISE
538 help
539 An ATSC/MH demodulator module. Say Y when you want
540 to support this frontend.
541
534config DVB_S5H1409 542config DVB_S5H1409
535 tristate "Samsung S5H1409 based" 543 tristate "Samsung S5H1409 based"
536 depends on DVB_CORE && I2C 544 depends on DVB_CORE && I2C
@@ -540,12 +548,26 @@ config DVB_S5H1409
540 to support this frontend. 548 to support this frontend.
541 549
542config DVB_AU8522 550config DVB_AU8522
543 tristate "Auvitek AU8522 based" 551 depends on I2C
544 depends on DVB_CORE && I2C && VIDEO_V4L2 552 tristate
553
554config DVB_AU8522_DTV
555 tristate "Auvitek AU8522 based DTV demod"
556 depends on DVB_CORE && I2C
557 select DVB_AU8522
545 default m if DVB_FE_CUSTOMISE 558 default m if DVB_FE_CUSTOMISE
546 help 559 help
547 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 560 An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
548 to support this frontend. 561 you want to enable DTV demodulation support for this frontend.
562
563config DVB_AU8522_V4L
564 tristate "Auvitek AU8522 based ATV demod"
565 depends on VIDEO_V4L2 && I2C
566 select DVB_AU8522
567 default m if DVB_FE_CUSTOMISE
568 help
569 An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
570 you want to enable ATV demodulation support for this frontend.
549 571
550config DVB_S5H1411 572config DVB_S5H1411
551 tristate "Samsung S5H1411 based" 573 tristate "Samsung S5H1411 based"
@@ -713,6 +735,11 @@ config DVB_M88RS2000
713 A DVB-S tuner module. 735 A DVB-S tuner module.
714 Say Y when you want to support this frontend. 736 Say Y when you want to support this frontend.
715 737
738config DVB_AF9033
739 tristate "Afatech AF9033 DVB-T demodulator"
740 depends on DVB_CORE && I2C
741 default m if DVB_FE_CUSTOMISE
742
716comment "Tools to develop new frontends" 743comment "Tools to develop new frontends"
717 744
718config DVB_DUMMY_FE 745config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 86fa808bf589..cd1ac2fd5774 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -7,7 +7,6 @@ ccflags-y += -I$(srctree)/drivers/media/common/tuners/
7 7
8stb0899-objs = stb0899_drv.o stb0899_algo.o 8stb0899-objs = stb0899_drv.o stb0899_algo.o
9stv0900-objs = stv0900_core.o stv0900_sw.o 9stv0900-objs = stv0900_core.o stv0900_sw.o
10au8522-objs = au8522_dig.o au8522_decoder.o
11drxd-objs = drxd_firm.o drxd_hard.o 10drxd-objs = drxd_firm.o drxd_hard.o
12cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o 11cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
13drxk-objs := drxk_hard.o 12drxk-objs := drxk_hard.o
@@ -50,6 +49,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
50obj-$(CONFIG_DVB_S5H1420) += s5h1420.o 49obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
51obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o 50obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
52obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o 51obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
52obj-$(CONFIG_DVB_LG2160) += lg2160.o
53obj-$(CONFIG_DVB_CX24123) += cx24123.o 53obj-$(CONFIG_DVB_CX24123) += cx24123.o
54obj-$(CONFIG_DVB_LNBP21) += lnbp21.o 54obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
55obj-$(CONFIG_DVB_LNBP22) += lnbp22.o 55obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
@@ -63,7 +63,9 @@ obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
63obj-$(CONFIG_DVB_TUA6100) += tua6100.o 63obj-$(CONFIG_DVB_TUA6100) += tua6100.o
64obj-$(CONFIG_DVB_S5H1409) += s5h1409.o 64obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
65obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o 65obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
66obj-$(CONFIG_DVB_AU8522) += au8522.o 66obj-$(CONFIG_DVB_AU8522) += au8522_common.o
67obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o
68obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o
67obj-$(CONFIG_DVB_TDA10048) += tda10048.o 69obj-$(CONFIG_DVB_TDA10048) += tda10048.o
68obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o 70obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
69obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 71obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
@@ -98,4 +100,5 @@ obj-$(CONFIG_DVB_A8293) += a8293.o
98obj-$(CONFIG_DVB_TDA10071) += tda10071.o 100obj-$(CONFIG_DVB_TDA10071) += tda10071.o
99obj-$(CONFIG_DVB_RTL2830) += rtl2830.o 101obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
100obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o 102obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
103obj-$(CONFIG_DVB_AF9033) += af9033.o
101 104
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index 6bcbcf543b38..5bc570d77846 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -514,7 +514,6 @@ err:
514 514
515static void af9013_statistics_work(struct work_struct *work) 515static void af9013_statistics_work(struct work_struct *work)
516{ 516{
517 int ret;
518 struct af9013_state *state = container_of(work, 517 struct af9013_state *state = container_of(work,
519 struct af9013_state, statistics_work.work); 518 struct af9013_state, statistics_work.work);
520 unsigned int next_msec; 519 unsigned int next_msec;
@@ -530,27 +529,27 @@ static void af9013_statistics_work(struct work_struct *work)
530 default: 529 default:
531 state->statistics_step = 0; 530 state->statistics_step = 0;
532 case 0: 531 case 0:
533 ret = af9013_statistics_signal_strength(&state->fe); 532 af9013_statistics_signal_strength(&state->fe);
534 state->statistics_step++; 533 state->statistics_step++;
535 next_msec = 300; 534 next_msec = 300;
536 break; 535 break;
537 case 1: 536 case 1:
538 ret = af9013_statistics_snr_start(&state->fe); 537 af9013_statistics_snr_start(&state->fe);
539 state->statistics_step++; 538 state->statistics_step++;
540 next_msec = 200; 539 next_msec = 200;
541 break; 540 break;
542 case 2: 541 case 2:
543 ret = af9013_statistics_ber_unc_start(&state->fe); 542 af9013_statistics_ber_unc_start(&state->fe);
544 state->statistics_step++; 543 state->statistics_step++;
545 next_msec = 1000; 544 next_msec = 1000;
546 break; 545 break;
547 case 3: 546 case 3:
548 ret = af9013_statistics_snr_result(&state->fe); 547 af9013_statistics_snr_result(&state->fe);
549 state->statistics_step++; 548 state->statistics_step++;
550 next_msec = 400; 549 next_msec = 400;
551 break; 550 break;
552 case 4: 551 case 4:
553 ret = af9013_statistics_ber_unc_result(&state->fe); 552 af9013_statistics_ber_unc_result(&state->fe);
554 state->statistics_step++; 553 state->statistics_step++;
555 next_msec = 100; 554 next_msec = 100;
556 break; 555 break;
@@ -558,8 +557,6 @@ static void af9013_statistics_work(struct work_struct *work)
558 557
559 schedule_delayed_work(&state->statistics_work, 558 schedule_delayed_work(&state->statistics_work,
560 msecs_to_jiffies(next_msec)); 559 msecs_to_jiffies(next_msec));
561
562 return;
563} 560}
564 561
565static int af9013_get_tune_settings(struct dvb_frontend *fe, 562static int af9013_get_tune_settings(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/af9033.c b/drivers/media/dvb/frontends/af9033.c
new file mode 100644
index 000000000000..a38998286260
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9033.c
@@ -0,0 +1,980 @@
1/*
2 * Afatech AF9033 demodulator driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "af9033_priv.h"
23
24struct af9033_state {
25 struct i2c_adapter *i2c;
26 struct dvb_frontend fe;
27 struct af9033_config cfg;
28
29 u32 bandwidth_hz;
30 bool ts_mode_parallel;
31 bool ts_mode_serial;
32
33 u32 ber;
34 u32 ucb;
35 unsigned long last_stat_check;
36};
37
38/* write multiple registers */
39static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
40 int len)
41{
42 int ret;
43 u8 buf[3 + len];
44 struct i2c_msg msg[1] = {
45 {
46 .addr = state->cfg.i2c_addr,
47 .flags = 0,
48 .len = sizeof(buf),
49 .buf = buf,
50 }
51 };
52
53 buf[0] = (reg >> 16) & 0xff;
54 buf[1] = (reg >> 8) & 0xff;
55 buf[2] = (reg >> 0) & 0xff;
56 memcpy(&buf[3], val, len);
57
58 ret = i2c_transfer(state->i2c, msg, 1);
59 if (ret == 1) {
60 ret = 0;
61 } else {
62 printk(KERN_WARNING "%s: i2c wr failed=%d reg=%06x len=%d\n",
63 __func__, ret, reg, len);
64 ret = -EREMOTEIO;
65 }
66
67 return ret;
68}
69
70/* read multiple registers */
71static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
72{
73 int ret;
74 u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
75 (reg >> 0) & 0xff };
76 struct i2c_msg msg[2] = {
77 {
78 .addr = state->cfg.i2c_addr,
79 .flags = 0,
80 .len = sizeof(buf),
81 .buf = buf
82 }, {
83 .addr = state->cfg.i2c_addr,
84 .flags = I2C_M_RD,
85 .len = len,
86 .buf = val
87 }
88 };
89
90 ret = i2c_transfer(state->i2c, msg, 2);
91 if (ret == 2) {
92 ret = 0;
93 } else {
94 printk(KERN_WARNING "%s: i2c rd failed=%d reg=%06x len=%d\n",
95 __func__, ret, reg, len);
96 ret = -EREMOTEIO;
97 }
98
99 return ret;
100}
101
102
103/* write single register */
104static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val)
105{
106 return af9033_wr_regs(state, reg, &val, 1);
107}
108
109/* read single register */
110static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val)
111{
112 return af9033_rd_regs(state, reg, val, 1);
113}
114
115/* write single register with mask */
116static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
117 u8 mask)
118{
119 int ret;
120 u8 tmp;
121
122 /* no need for read if whole reg is written */
123 if (mask != 0xff) {
124 ret = af9033_rd_regs(state, reg, &tmp, 1);
125 if (ret)
126 return ret;
127
128 val &= mask;
129 tmp &= ~mask;
130 val |= tmp;
131 }
132
133 return af9033_wr_regs(state, reg, &val, 1);
134}
135
136/* read single register with mask */
137static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
138 u8 mask)
139{
140 int ret, i;
141 u8 tmp;
142
143 ret = af9033_rd_regs(state, reg, &tmp, 1);
144 if (ret)
145 return ret;
146
147 tmp &= mask;
148
149 /* find position of the first bit */
150 for (i = 0; i < 8; i++) {
151 if ((mask >> i) & 0x01)
152 break;
153 }
154 *val = tmp >> i;
155
156 return 0;
157}
158
159static u32 af9033_div(u32 a, u32 b, u32 x)
160{
161 u32 r = 0, c = 0, i;
162
163 pr_debug("%s: a=%d b=%d x=%d\n", __func__, a, b, x);
164
165 if (a > b) {
166 c = a / b;
167 a = a - c * b;
168 }
169
170 for (i = 0; i < x; i++) {
171 if (a >= b) {
172 r += 1;
173 a -= b;
174 }
175 a <<= 1;
176 r <<= 1;
177 }
178 r = (c << (u32)x) + r;
179
180 pr_debug("%s: a=%d b=%d x=%d r=%d r=%x\n", __func__, a, b, x, r, r);
181
182 return r;
183}
184
185static void af9033_release(struct dvb_frontend *fe)
186{
187 struct af9033_state *state = fe->demodulator_priv;
188
189 kfree(state);
190}
191
192static int af9033_init(struct dvb_frontend *fe)
193{
194 struct af9033_state *state = fe->demodulator_priv;
195 int ret, i, len;
196 const struct reg_val *init;
197 u8 buf[4];
198 u32 adc_cw, clock_cw;
199 struct reg_val_mask tab[] = {
200 { 0x80fb24, 0x00, 0x08 },
201 { 0x80004c, 0x00, 0xff },
202 { 0x00f641, state->cfg.tuner, 0xff },
203 { 0x80f5ca, 0x01, 0x01 },
204 { 0x80f715, 0x01, 0x01 },
205 { 0x00f41f, 0x04, 0x04 },
206 { 0x00f41a, 0x01, 0x01 },
207 { 0x80f731, 0x00, 0x01 },
208 { 0x00d91e, 0x00, 0x01 },
209 { 0x00d919, 0x00, 0x01 },
210 { 0x80f732, 0x00, 0x01 },
211 { 0x00d91f, 0x00, 0x01 },
212 { 0x00d91a, 0x00, 0x01 },
213 { 0x80f730, 0x00, 0x01 },
214 { 0x80f778, 0x00, 0xff },
215 { 0x80f73c, 0x01, 0x01 },
216 { 0x80f776, 0x00, 0x01 },
217 { 0x00d8fd, 0x01, 0xff },
218 { 0x00d830, 0x01, 0xff },
219 { 0x00d831, 0x00, 0xff },
220 { 0x00d832, 0x00, 0xff },
221 { 0x80f985, state->ts_mode_serial, 0x01 },
222 { 0x80f986, state->ts_mode_parallel, 0x01 },
223 { 0x00d827, 0x00, 0xff },
224 { 0x00d829, 0x00, 0xff },
225 };
226
227 /* program clock control */
228 clock_cw = af9033_div(state->cfg.clock, 1000000ul, 19ul);
229 buf[0] = (clock_cw >> 0) & 0xff;
230 buf[1] = (clock_cw >> 8) & 0xff;
231 buf[2] = (clock_cw >> 16) & 0xff;
232 buf[3] = (clock_cw >> 24) & 0xff;
233
234 pr_debug("%s: clock=%d clock_cw=%08x\n", __func__, state->cfg.clock,
235 clock_cw);
236
237 ret = af9033_wr_regs(state, 0x800025, buf, 4);
238 if (ret < 0)
239 goto err;
240
241 /* program ADC control */
242 for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
243 if (clock_adc_lut[i].clock == state->cfg.clock)
244 break;
245 }
246
247 adc_cw = af9033_div(clock_adc_lut[i].adc, 1000000ul, 19ul);
248 buf[0] = (adc_cw >> 0) & 0xff;
249 buf[1] = (adc_cw >> 8) & 0xff;
250 buf[2] = (adc_cw >> 16) & 0xff;
251
252 pr_debug("%s: adc=%d adc_cw=%06x\n", __func__, clock_adc_lut[i].adc,
253 adc_cw);
254
255 ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
256 if (ret < 0)
257 goto err;
258
259 /* program register table */
260 for (i = 0; i < ARRAY_SIZE(tab); i++) {
261 ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val,
262 tab[i].mask);
263 if (ret < 0)
264 goto err;
265 }
266
267 /* settings for TS interface */
268 if (state->cfg.ts_mode == AF9033_TS_MODE_USB) {
269 ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01);
270 if (ret < 0)
271 goto err;
272
273 ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01);
274 if (ret < 0)
275 goto err;
276 } else {
277 ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01);
278 if (ret < 0)
279 goto err;
280
281 ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01);
282 if (ret < 0)
283 goto err;
284 }
285
286 /* load OFSM settings */
287 pr_debug("%s: load ofsm settings\n", __func__);
288 len = ARRAY_SIZE(ofsm_init);
289 init = ofsm_init;
290 for (i = 0; i < len; i++) {
291 ret = af9033_wr_reg(state, init[i].reg, init[i].val);
292 if (ret < 0)
293 goto err;
294 }
295
296 /* load tuner specific settings */
297 pr_debug("%s: load tuner specific settings\n",
298 __func__);
299 switch (state->cfg.tuner) {
300 case AF9033_TUNER_TUA9001:
301 len = ARRAY_SIZE(tuner_init_tua9001);
302 init = tuner_init_tua9001;
303 break;
304 case AF9033_TUNER_FC0011:
305 len = ARRAY_SIZE(tuner_init_fc0011);
306 init = tuner_init_fc0011;
307 break;
308 case AF9033_TUNER_MXL5007T:
309 len = ARRAY_SIZE(tuner_init_mxl5007t);
310 init = tuner_init_mxl5007t;
311 break;
312 case AF9033_TUNER_TDA18218:
313 len = ARRAY_SIZE(tuner_init_tda18218);
314 init = tuner_init_tda18218;
315 break;
316 default:
317 pr_debug("%s: unsupported tuner ID=%d\n", __func__,
318 state->cfg.tuner);
319 ret = -ENODEV;
320 goto err;
321 }
322
323 for (i = 0; i < len; i++) {
324 ret = af9033_wr_reg(state, init[i].reg, init[i].val);
325 if (ret < 0)
326 goto err;
327 }
328
329 state->bandwidth_hz = 0; /* force to program all parameters */
330
331 return 0;
332
333err:
334 pr_debug("%s: failed=%d\n", __func__, ret);
335
336 return ret;
337}
338
339static int af9033_sleep(struct dvb_frontend *fe)
340{
341 struct af9033_state *state = fe->demodulator_priv;
342 int ret, i;
343 u8 tmp;
344
345 ret = af9033_wr_reg(state, 0x80004c, 1);
346 if (ret < 0)
347 goto err;
348
349 ret = af9033_wr_reg(state, 0x800000, 0);
350 if (ret < 0)
351 goto err;
352
353 for (i = 100, tmp = 1; i && tmp; i--) {
354 ret = af9033_rd_reg(state, 0x80004c, &tmp);
355 if (ret < 0)
356 goto err;
357
358 usleep_range(200, 10000);
359 }
360
361 pr_debug("%s: loop=%d\n", __func__, i);
362
363 if (i == 0) {
364 ret = -ETIMEDOUT;
365 goto err;
366 }
367
368 ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08);
369 if (ret < 0)
370 goto err;
371
372 /* prevent current leak (?) */
373 if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
374 /* enable parallel TS */
375 ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
376 if (ret < 0)
377 goto err;
378
379 ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01);
380 if (ret < 0)
381 goto err;
382 }
383
384 return 0;
385
386err:
387 pr_debug("%s: failed=%d\n", __func__, ret);
388
389 return ret;
390}
391
392static int af9033_get_tune_settings(struct dvb_frontend *fe,
393 struct dvb_frontend_tune_settings *fesettings)
394{
395 fesettings->min_delay_ms = 800;
396 fesettings->step_size = 0;
397 fesettings->max_drift = 0;
398
399 return 0;
400}
401
402static int af9033_set_frontend(struct dvb_frontend *fe)
403{
404 struct af9033_state *state = fe->demodulator_priv;
405 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
406 int ret, i, spec_inv;
407 u8 tmp, buf[3], bandwidth_reg_val;
408 u32 if_frequency, freq_cw, adc_freq;
409
410 pr_debug("%s: frequency=%d bandwidth_hz=%d\n", __func__, c->frequency,
411 c->bandwidth_hz);
412
413 /* check bandwidth */
414 switch (c->bandwidth_hz) {
415 case 6000000:
416 bandwidth_reg_val = 0x00;
417 break;
418 case 7000000:
419 bandwidth_reg_val = 0x01;
420 break;
421 case 8000000:
422 bandwidth_reg_val = 0x02;
423 break;
424 default:
425 pr_debug("%s: invalid bandwidth_hz\n", __func__);
426 ret = -EINVAL;
427 goto err;
428 }
429
430 /* program tuner */
431 if (fe->ops.tuner_ops.set_params)
432 fe->ops.tuner_ops.set_params(fe);
433
434 /* program CFOE coefficients */
435 if (c->bandwidth_hz != state->bandwidth_hz) {
436 for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
437 if (coeff_lut[i].clock == state->cfg.clock &&
438 coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
439 break;
440 }
441 }
442 ret = af9033_wr_regs(state, 0x800001,
443 coeff_lut[i].val, sizeof(coeff_lut[i].val));
444 }
445
446 /* program frequency control */
447 if (c->bandwidth_hz != state->bandwidth_hz) {
448 spec_inv = state->cfg.spec_inv ? -1 : 1;
449
450 for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
451 if (clock_adc_lut[i].clock == state->cfg.clock)
452 break;
453 }
454 adc_freq = clock_adc_lut[i].adc;
455
456 /* get used IF frequency */
457 if (fe->ops.tuner_ops.get_if_frequency)
458 fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
459 else
460 if_frequency = 0;
461
462 while (if_frequency > (adc_freq / 2))
463 if_frequency -= adc_freq;
464
465 if (if_frequency >= 0)
466 spec_inv *= -1;
467 else
468 if_frequency *= -1;
469
470 freq_cw = af9033_div(if_frequency, adc_freq, 23ul);
471
472 if (spec_inv == -1)
473 freq_cw *= -1;
474
475 /* get adc multiplies */
476 ret = af9033_rd_reg(state, 0x800045, &tmp);
477 if (ret < 0)
478 goto err;
479
480 if (tmp == 1)
481 freq_cw /= 2;
482
483 buf[0] = (freq_cw >> 0) & 0xff;
484 buf[1] = (freq_cw >> 8) & 0xff;
485 buf[2] = (freq_cw >> 16) & 0x7f;
486 ret = af9033_wr_regs(state, 0x800029, buf, 3);
487 if (ret < 0)
488 goto err;
489
490 state->bandwidth_hz = c->bandwidth_hz;
491 }
492
493 ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03);
494 if (ret < 0)
495 goto err;
496
497 ret = af9033_wr_reg(state, 0x800040, 0x00);
498 if (ret < 0)
499 goto err;
500
501 ret = af9033_wr_reg(state, 0x800047, 0x00);
502 if (ret < 0)
503 goto err;
504
505 ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01);
506 if (ret < 0)
507 goto err;
508
509 if (c->frequency <= 230000000)
510 tmp = 0x00; /* VHF */
511 else
512 tmp = 0x01; /* UHF */
513
514 ret = af9033_wr_reg(state, 0x80004b, tmp);
515 if (ret < 0)
516 goto err;
517
518 ret = af9033_wr_reg(state, 0x800000, 0x00);
519 if (ret < 0)
520 goto err;
521
522 return 0;
523
524err:
525 pr_debug("%s: failed=%d\n", __func__, ret);
526
527 return ret;
528}
529
530static int af9033_get_frontend(struct dvb_frontend *fe)
531{
532 struct af9033_state *state = fe->demodulator_priv;
533 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
534 int ret;
535 u8 buf[8];
536
537 pr_debug("%s\n", __func__);
538
539 /* read all needed registers */
540 ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
541 if (ret < 0)
542 goto err;
543
544 switch ((buf[0] >> 0) & 3) {
545 case 0:
546 c->transmission_mode = TRANSMISSION_MODE_2K;
547 break;
548 case 1:
549 c->transmission_mode = TRANSMISSION_MODE_8K;
550 break;
551 }
552
553 switch ((buf[1] >> 0) & 3) {
554 case 0:
555 c->guard_interval = GUARD_INTERVAL_1_32;
556 break;
557 case 1:
558 c->guard_interval = GUARD_INTERVAL_1_16;
559 break;
560 case 2:
561 c->guard_interval = GUARD_INTERVAL_1_8;
562 break;
563 case 3:
564 c->guard_interval = GUARD_INTERVAL_1_4;
565 break;
566 }
567
568 switch ((buf[2] >> 0) & 7) {
569 case 0:
570 c->hierarchy = HIERARCHY_NONE;
571 break;
572 case 1:
573 c->hierarchy = HIERARCHY_1;
574 break;
575 case 2:
576 c->hierarchy = HIERARCHY_2;
577 break;
578 case 3:
579 c->hierarchy = HIERARCHY_4;
580 break;
581 }
582
583 switch ((buf[3] >> 0) & 3) {
584 case 0:
585 c->modulation = QPSK;
586 break;
587 case 1:
588 c->modulation = QAM_16;
589 break;
590 case 2:
591 c->modulation = QAM_64;
592 break;
593 }
594
595 switch ((buf[4] >> 0) & 3) {
596 case 0:
597 c->bandwidth_hz = 6000000;
598 break;
599 case 1:
600 c->bandwidth_hz = 7000000;
601 break;
602 case 2:
603 c->bandwidth_hz = 8000000;
604 break;
605 }
606
607 switch ((buf[6] >> 0) & 7) {
608 case 0:
609 c->code_rate_HP = FEC_1_2;
610 break;
611 case 1:
612 c->code_rate_HP = FEC_2_3;
613 break;
614 case 2:
615 c->code_rate_HP = FEC_3_4;
616 break;
617 case 3:
618 c->code_rate_HP = FEC_5_6;
619 break;
620 case 4:
621 c->code_rate_HP = FEC_7_8;
622 break;
623 case 5:
624 c->code_rate_HP = FEC_NONE;
625 break;
626 }
627
628 switch ((buf[7] >> 0) & 7) {
629 case 0:
630 c->code_rate_LP = FEC_1_2;
631 break;
632 case 1:
633 c->code_rate_LP = FEC_2_3;
634 break;
635 case 2:
636 c->code_rate_LP = FEC_3_4;
637 break;
638 case 3:
639 c->code_rate_LP = FEC_5_6;
640 break;
641 case 4:
642 c->code_rate_LP = FEC_7_8;
643 break;
644 case 5:
645 c->code_rate_LP = FEC_NONE;
646 break;
647 }
648
649 return 0;
650
651err:
652 pr_debug("%s: failed=%d\n", __func__, ret);
653
654 return ret;
655}
656
657static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
658{
659 struct af9033_state *state = fe->demodulator_priv;
660 int ret;
661 u8 tmp;
662
663 *status = 0;
664
665 /* radio channel status, 0=no result, 1=has signal, 2=no signal */
666 ret = af9033_rd_reg(state, 0x800047, &tmp);
667 if (ret < 0)
668 goto err;
669
670 /* has signal */
671 if (tmp == 0x01)
672 *status |= FE_HAS_SIGNAL;
673
674 if (tmp != 0x02) {
675 /* TPS lock */
676 ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01);
677 if (ret < 0)
678 goto err;
679
680 if (tmp)
681 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
682 FE_HAS_VITERBI;
683
684 /* full lock */
685 ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01);
686 if (ret < 0)
687 goto err;
688
689 if (tmp)
690 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
691 FE_HAS_VITERBI | FE_HAS_SYNC |
692 FE_HAS_LOCK;
693 }
694
695 return 0;
696
697err:
698 pr_debug("%s: failed=%d\n", __func__, ret);
699
700 return ret;
701}
702
703static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
704{
705 struct af9033_state *state = fe->demodulator_priv;
706 int ret, i, len;
707 u8 buf[3], tmp;
708 u32 snr_val;
709 const struct val_snr *uninitialized_var(snr_lut);
710
711 /* read value */
712 ret = af9033_rd_regs(state, 0x80002c, buf, 3);
713 if (ret < 0)
714 goto err;
715
716 snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
717
718 /* read current modulation */
719 ret = af9033_rd_reg(state, 0x80f903, &tmp);
720 if (ret < 0)
721 goto err;
722
723 switch ((tmp >> 0) & 3) {
724 case 0:
725 len = ARRAY_SIZE(qpsk_snr_lut);
726 snr_lut = qpsk_snr_lut;
727 break;
728 case 1:
729 len = ARRAY_SIZE(qam16_snr_lut);
730 snr_lut = qam16_snr_lut;
731 break;
732 case 2:
733 len = ARRAY_SIZE(qam64_snr_lut);
734 snr_lut = qam64_snr_lut;
735 break;
736 default:
737 goto err;
738 }
739
740 for (i = 0; i < len; i++) {
741 tmp = snr_lut[i].snr;
742
743 if (snr_val < snr_lut[i].val)
744 break;
745 }
746
747 *snr = tmp * 10; /* dB/10 */
748
749 return 0;
750
751err:
752 pr_debug("%s: failed=%d\n", __func__, ret);
753
754 return ret;
755}
756
757static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
758{
759 struct af9033_state *state = fe->demodulator_priv;
760 int ret;
761 u8 strength2;
762
763 /* read signal strength of 0-100 scale */
764 ret = af9033_rd_reg(state, 0x800048, &strength2);
765 if (ret < 0)
766 goto err;
767
768 /* scale value to 0x0000-0xffff */
769 *strength = strength2 * 0xffff / 100;
770
771 return 0;
772
773err:
774 pr_debug("%s: failed=%d\n", __func__, ret);
775
776 return ret;
777}
778
779static int af9033_update_ch_stat(struct af9033_state *state)
780{
781 int ret = 0;
782 u32 err_cnt, bit_cnt;
783 u16 abort_cnt;
784 u8 buf[7];
785
786 /* only update data every half second */
787 if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) {
788 ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf));
789 if (ret < 0)
790 goto err;
791 /* in 8 byte packets? */
792 abort_cnt = (buf[1] << 8) + buf[0];
793 /* in bits */
794 err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2];
795 /* in 8 byte packets? always(?) 0x2710 = 10000 */
796 bit_cnt = (buf[6] << 8) + buf[5];
797
798 if (bit_cnt < abort_cnt) {
799 abort_cnt = 1000;
800 state->ber = 0xffffffff;
801 } else {
802 /* 8 byte packets, that have not been rejected already */
803 bit_cnt -= (u32)abort_cnt;
804 if (bit_cnt == 0) {
805 state->ber = 0xffffffff;
806 } else {
807 err_cnt -= (u32)abort_cnt * 8 * 8;
808 bit_cnt *= 8 * 8;
809 state->ber = err_cnt * (0xffffffff / bit_cnt);
810 }
811 }
812 state->ucb += abort_cnt;
813 state->last_stat_check = jiffies;
814 }
815
816 return 0;
817err:
818 pr_debug("%s: failed=%d\n", __func__, ret);
819 return ret;
820}
821
822static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber)
823{
824 struct af9033_state *state = fe->demodulator_priv;
825 int ret;
826
827 ret = af9033_update_ch_stat(state);
828 if (ret < 0)
829 return ret;
830
831 *ber = state->ber;
832
833 return 0;
834}
835
836static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
837{
838 struct af9033_state *state = fe->demodulator_priv;
839 int ret;
840
841 ret = af9033_update_ch_stat(state);
842 if (ret < 0)
843 return ret;
844
845 *ucblocks = state->ucb;
846
847 return 0;
848}
849
850static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
851{
852 struct af9033_state *state = fe->demodulator_priv;
853 int ret;
854
855 pr_debug("%s: enable=%d\n", __func__, enable);
856
857 ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
858 if (ret < 0)
859 goto err;
860
861 return 0;
862
863err:
864 pr_debug("%s: failed=%d\n", __func__, ret);
865
866 return ret;
867}
868
869static struct dvb_frontend_ops af9033_ops;
870
871struct dvb_frontend *af9033_attach(const struct af9033_config *config,
872 struct i2c_adapter *i2c)
873{
874 int ret;
875 struct af9033_state *state;
876 u8 buf[8];
877
878 pr_debug("%s:\n", __func__);
879
880 /* allocate memory for the internal state */
881 state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
882 if (state == NULL)
883 goto err;
884
885 /* setup the state */
886 state->i2c = i2c;
887 memcpy(&state->cfg, config, sizeof(struct af9033_config));
888
889 if (state->cfg.clock != 12000000) {
890 printk(KERN_INFO "af9033: unsupported clock=%d, only " \
891 "12000000 Hz is supported currently\n",
892 state->cfg.clock);
893 goto err;
894 }
895
896 /* firmware version */
897 ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4);
898 if (ret < 0)
899 goto err;
900
901 ret = af9033_rd_regs(state, 0x804191, &buf[4], 4);
902 if (ret < 0)
903 goto err;
904
905 printk(KERN_INFO "af9033: firmware version: LINK=%d.%d.%d.%d " \
906 "OFDM=%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3],
907 buf[4], buf[5], buf[6], buf[7]);
908
909 /* configure internal TS mode */
910 switch (state->cfg.ts_mode) {
911 case AF9033_TS_MODE_PARALLEL:
912 state->ts_mode_parallel = true;
913 break;
914 case AF9033_TS_MODE_SERIAL:
915 state->ts_mode_serial = true;
916 break;
917 case AF9033_TS_MODE_USB:
918 /* usb mode for AF9035 */
919 default:
920 break;
921 }
922
923 /* create dvb_frontend */
924 memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
925 state->fe.demodulator_priv = state;
926
927 return &state->fe;
928
929err:
930 kfree(state);
931 return NULL;
932}
933EXPORT_SYMBOL(af9033_attach);
934
935static struct dvb_frontend_ops af9033_ops = {
936 .delsys = { SYS_DVBT },
937 .info = {
938 .name = "Afatech AF9033 (DVB-T)",
939 .frequency_min = 174000000,
940 .frequency_max = 862000000,
941 .frequency_stepsize = 250000,
942 .frequency_tolerance = 0,
943 .caps = FE_CAN_FEC_1_2 |
944 FE_CAN_FEC_2_3 |
945 FE_CAN_FEC_3_4 |
946 FE_CAN_FEC_5_6 |
947 FE_CAN_FEC_7_8 |
948 FE_CAN_FEC_AUTO |
949 FE_CAN_QPSK |
950 FE_CAN_QAM_16 |
951 FE_CAN_QAM_64 |
952 FE_CAN_QAM_AUTO |
953 FE_CAN_TRANSMISSION_MODE_AUTO |
954 FE_CAN_GUARD_INTERVAL_AUTO |
955 FE_CAN_HIERARCHY_AUTO |
956 FE_CAN_RECOVER |
957 FE_CAN_MUTE_TS
958 },
959
960 .release = af9033_release,
961
962 .init = af9033_init,
963 .sleep = af9033_sleep,
964
965 .get_tune_settings = af9033_get_tune_settings,
966 .set_frontend = af9033_set_frontend,
967 .get_frontend = af9033_get_frontend,
968
969 .read_status = af9033_read_status,
970 .read_snr = af9033_read_snr,
971 .read_signal_strength = af9033_read_signal_strength,
972 .read_ber = af9033_read_ber,
973 .read_ucblocks = af9033_read_ucblocks,
974
975 .i2c_gate_ctrl = af9033_i2c_gate_ctrl,
976};
977
978MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
979MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver");
980MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/af9033.h b/drivers/media/dvb/frontends/af9033.h
new file mode 100644
index 000000000000..9e302c3f0f7d
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9033.h
@@ -0,0 +1,75 @@
1/*
2 * Afatech AF9033 demodulator driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef AF9033_H
23#define AF9033_H
24
25struct af9033_config {
26 /*
27 * I2C address
28 */
29 u8 i2c_addr;
30
31 /*
32 * clock Hz
33 * 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000,
34 * 30000000, 36000000, 20480000, 16384000
35 */
36 u32 clock;
37
38 /*
39 * tuner
40 */
41#define AF9033_TUNER_TUA9001 0x27 /* Infineon TUA 9001 */
42#define AF9033_TUNER_FC0011 0x28 /* Fitipower FC0011 */
43#define AF9033_TUNER_MXL5007T 0xa0 /* MaxLinear MxL5007T */
44#define AF9033_TUNER_TDA18218 0xa1 /* NXP TDA 18218HN */
45 u8 tuner;
46
47 /*
48 * TS settings
49 */
50#define AF9033_TS_MODE_USB 0
51#define AF9033_TS_MODE_PARALLEL 1
52#define AF9033_TS_MODE_SERIAL 2
53 u8 ts_mode:2;
54
55 /*
56 * input spectrum inversion
57 */
58 bool spec_inv;
59};
60
61
62#if defined(CONFIG_DVB_AF9033) || \
63 (defined(CONFIG_DVB_AF9033_MODULE) && defined(MODULE))
64extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
65 struct i2c_adapter *i2c);
66#else
67static inline struct dvb_frontend *af9033_attach(
68 const struct af9033_config *config, struct i2c_adapter *i2c)
69{
70 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
71 return NULL;
72}
73#endif
74
75#endif /* AF9033_H */
diff --git a/drivers/media/dvb/frontends/af9033_priv.h b/drivers/media/dvb/frontends/af9033_priv.h
new file mode 100644
index 000000000000..0b783b9ed75e
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9033_priv.h
@@ -0,0 +1,470 @@
1/*
2 * Afatech AF9033 demodulator driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef AF9033_PRIV_H
23#define AF9033_PRIV_H
24
25#include "dvb_frontend.h"
26#include "af9033.h"
27
28struct reg_val {
29 u32 reg;
30 u8 val;
31};
32
33struct reg_val_mask {
34 u32 reg;
35 u8 val;
36 u8 mask;
37};
38
39struct coeff {
40 u32 clock;
41 u32 bandwidth_hz;
42 u8 val[36];
43};
44
45struct clock_adc {
46 u32 clock;
47 u32 adc;
48};
49
50struct val_snr {
51 u32 val;
52 u8 snr;
53};
54
55/* Xtal clock vs. ADC clock lookup table */
56static const struct clock_adc clock_adc_lut[] = {
57 { 16384000, 20480000 },
58 { 20480000, 20480000 },
59 { 36000000, 20250000 },
60 { 30000000, 20156250 },
61 { 26000000, 20583333 },
62 { 28000000, 20416667 },
63 { 32000000, 20500000 },
64 { 34000000, 20187500 },
65 { 24000000, 20500000 },
66 { 22000000, 20625000 },
67 { 12000000, 20250000 },
68};
69
70/* pre-calculated coeff lookup table */
71static const struct coeff coeff_lut[] = {
72 /* 12.000 MHz */
73 { 12000000, 8000000, {
74 0x01, 0xce, 0x55, 0xc9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73,
75 0x99, 0x0f, 0x00, 0x73, 0x95, 0x72, 0x00, 0x73, 0x91, 0xd5,
76 0x00, 0x39, 0xca, 0xb9, 0x00, 0xe7, 0x2a, 0xe4, 0x00, 0x73,
77 0x95, 0x72, 0x37, 0x02, 0xce, 0x01 }
78 },
79 { 12000000, 7000000, {
80 0x01, 0x94, 0x8b, 0x10, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65,
81 0x25, 0xed, 0x00, 0x65, 0x22, 0xc4, 0x00, 0x65, 0x1f, 0x9b,
82 0x00, 0x32, 0x91, 0x62, 0x00, 0xca, 0x45, 0x88, 0x00, 0x65,
83 0x22, 0xc4, 0x88, 0x02, 0x95, 0x01 }
84 },
85 { 12000000, 6000000, {
86 0x01, 0x5a, 0xc0, 0x56, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56,
87 0xb2, 0xcb, 0x00, 0x56, 0xb0, 0x15, 0x00, 0x56, 0xad, 0x60,
88 0x00, 0x2b, 0x58, 0x0b, 0x00, 0xad, 0x60, 0x2b, 0x00, 0x56,
89 0xb0, 0x15, 0xf4, 0x02, 0x5b, 0x01 }
90 },
91};
92
93/* QPSK SNR lookup table */
94static const struct val_snr qpsk_snr_lut[] = {
95 { 0x0b4771, 0 },
96 { 0x0c1aed, 1 },
97 { 0x0d0d27, 2 },
98 { 0x0e4d19, 3 },
99 { 0x0e5da8, 4 },
100 { 0x107097, 5 },
101 { 0x116975, 6 },
102 { 0x1252d9, 7 },
103 { 0x131fa4, 8 },
104 { 0x13d5e1, 9 },
105 { 0x148e53, 10 },
106 { 0x15358b, 11 },
107 { 0x15dd29, 12 },
108 { 0x168112, 13 },
109 { 0x170b61, 14 },
110 { 0x17a532, 15 },
111 { 0x180f94, 16 },
112 { 0x186ed2, 17 },
113 { 0x18b271, 18 },
114 { 0x18e118, 19 },
115 { 0x18ff4b, 20 },
116 { 0x190af1, 21 },
117 { 0x191451, 22 },
118 { 0xffffff, 23 },
119};
120
121/* QAM16 SNR lookup table */
122static const struct val_snr qam16_snr_lut[] = {
123 { 0x04f0d5, 0 },
124 { 0x05387a, 1 },
125 { 0x0573a4, 2 },
126 { 0x05a99e, 3 },
127 { 0x05cc80, 4 },
128 { 0x05eb62, 5 },
129 { 0x05fecf, 6 },
130 { 0x060b80, 7 },
131 { 0x062501, 8 },
132 { 0x064865, 9 },
133 { 0x069604, 10 },
134 { 0x06f356, 11 },
135 { 0x07706a, 12 },
136 { 0x0804d3, 13 },
137 { 0x089d1a, 14 },
138 { 0x093e3d, 15 },
139 { 0x09e35d, 16 },
140 { 0x0a7c3c, 17 },
141 { 0x0afaf8, 18 },
142 { 0x0b719d, 19 },
143 { 0x0bda6a, 20 },
144 { 0x0c0c75, 21 },
145 { 0x0c3f7d, 22 },
146 { 0x0c5e62, 23 },
147 { 0x0c6c31, 24 },
148 { 0x0c7925, 25 },
149 { 0xffffff, 26 },
150};
151
152/* QAM64 SNR lookup table */
153static const struct val_snr qam64_snr_lut[] = {
154 { 0x0256d0, 0 },
155 { 0x027a65, 1 },
156 { 0x029873, 2 },
157 { 0x02b7fe, 3 },
158 { 0x02cf1e, 4 },
159 { 0x02e234, 5 },
160 { 0x02f409, 6 },
161 { 0x030046, 7 },
162 { 0x030844, 8 },
163 { 0x030a02, 9 },
164 { 0x030cde, 10 },
165 { 0x031031, 11 },
166 { 0x03144c, 12 },
167 { 0x0315dd, 13 },
168 { 0x031920, 14 },
169 { 0x0322d0, 15 },
170 { 0x0339fc, 16 },
171 { 0x0364a1, 17 },
172 { 0x038bcc, 18 },
173 { 0x03c7d3, 19 },
174 { 0x0408cc, 20 },
175 { 0x043bed, 21 },
176 { 0x048061, 22 },
177 { 0x04be95, 23 },
178 { 0x04fa7d, 24 },
179 { 0x052405, 25 },
180 { 0x05570d, 26 },
181 { 0x059feb, 27 },
182 { 0x05bf38, 28 },
183 { 0xffffff, 29 },
184};
185
186static const struct reg_val ofsm_init[] = {
187 { 0x800051, 0x01 },
188 { 0x800070, 0x0a },
189 { 0x80007e, 0x04 },
190 { 0x800081, 0x0a },
191 { 0x80008a, 0x01 },
192 { 0x80008e, 0x01 },
193 { 0x800092, 0x06 },
194 { 0x800099, 0x01 },
195 { 0x80009f, 0xe1 },
196 { 0x8000a0, 0xcf },
197 { 0x8000a3, 0x01 },
198 { 0x8000a5, 0x01 },
199 { 0x8000a6, 0x01 },
200 { 0x8000a9, 0x00 },
201 { 0x8000aa, 0x01 },
202 { 0x8000ab, 0x01 },
203 { 0x8000b0, 0x01 },
204 { 0x8000c0, 0x05 },
205 { 0x8000c4, 0x19 },
206 { 0x80f000, 0x0f },
207 { 0x80f016, 0x10 },
208 { 0x80f017, 0x04 },
209 { 0x80f018, 0x05 },
210 { 0x80f019, 0x04 },
211 { 0x80f01a, 0x05 },
212 { 0x80f021, 0x03 },
213 { 0x80f022, 0x0a },
214 { 0x80f023, 0x0a },
215 { 0x80f02b, 0x00 },
216 { 0x80f02c, 0x01 },
217 { 0x80f064, 0x03 },
218 { 0x80f065, 0xf9 },
219 { 0x80f066, 0x03 },
220 { 0x80f067, 0x01 },
221 { 0x80f06f, 0xe0 },
222 { 0x80f070, 0x03 },
223 { 0x80f072, 0x0f },
224 { 0x80f073, 0x03 },
225 { 0x80f078, 0x00 },
226 { 0x80f087, 0x00 },
227 { 0x80f09b, 0x3f },
228 { 0x80f09c, 0x00 },
229 { 0x80f09d, 0x20 },
230 { 0x80f09e, 0x00 },
231 { 0x80f09f, 0x0c },
232 { 0x80f0a0, 0x00 },
233 { 0x80f130, 0x04 },
234 { 0x80f132, 0x04 },
235 { 0x80f144, 0x1a },
236 { 0x80f146, 0x00 },
237 { 0x80f14a, 0x01 },
238 { 0x80f14c, 0x00 },
239 { 0x80f14d, 0x00 },
240 { 0x80f14f, 0x04 },
241 { 0x80f158, 0x7f },
242 { 0x80f15a, 0x00 },
243 { 0x80f15b, 0x08 },
244 { 0x80f15d, 0x03 },
245 { 0x80f15e, 0x05 },
246 { 0x80f163, 0x05 },
247 { 0x80f166, 0x01 },
248 { 0x80f167, 0x40 },
249 { 0x80f168, 0x0f },
250 { 0x80f17a, 0x00 },
251 { 0x80f17b, 0x00 },
252 { 0x80f183, 0x01 },
253 { 0x80f19d, 0x40 },
254 { 0x80f1bc, 0x36 },
255 { 0x80f1bd, 0x00 },
256 { 0x80f1cb, 0xa0 },
257 { 0x80f1cc, 0x01 },
258 { 0x80f204, 0x10 },
259 { 0x80f214, 0x00 },
260 { 0x80f40e, 0x0a },
261 { 0x80f40f, 0x40 },
262 { 0x80f410, 0x08 },
263 { 0x80f55f, 0x0a },
264 { 0x80f561, 0x15 },
265 { 0x80f562, 0x20 },
266 { 0x80f5df, 0xfb },
267 { 0x80f5e0, 0x00 },
268 { 0x80f5e3, 0x09 },
269 { 0x80f5e4, 0x01 },
270 { 0x80f5e5, 0x01 },
271 { 0x80f5f8, 0x01 },
272 { 0x80f5fd, 0x01 },
273 { 0x80f600, 0x05 },
274 { 0x80f601, 0x08 },
275 { 0x80f602, 0x0b },
276 { 0x80f603, 0x0e },
277 { 0x80f604, 0x11 },
278 { 0x80f605, 0x14 },
279 { 0x80f606, 0x17 },
280 { 0x80f607, 0x1f },
281 { 0x80f60e, 0x00 },
282 { 0x80f60f, 0x04 },
283 { 0x80f610, 0x32 },
284 { 0x80f611, 0x10 },
285 { 0x80f707, 0xfc },
286 { 0x80f708, 0x00 },
287 { 0x80f709, 0x37 },
288 { 0x80f70a, 0x00 },
289 { 0x80f78b, 0x01 },
290 { 0x80f80f, 0x40 },
291 { 0x80f810, 0x54 },
292 { 0x80f811, 0x5a },
293 { 0x80f905, 0x01 },
294 { 0x80fb06, 0x03 },
295 { 0x80fd8b, 0x00 },
296};
297
298/* Infineon TUA 9001 tuner init
299 AF9033_TUNER_TUA9001 = 0x27 */
300static const struct reg_val tuner_init_tua9001[] = {
301 { 0x800046, 0x27 },
302 { 0x800057, 0x00 },
303 { 0x800058, 0x01 },
304 { 0x80005f, 0x00 },
305 { 0x800060, 0x00 },
306 { 0x80006d, 0x00 },
307 { 0x800071, 0x05 },
308 { 0x800072, 0x02 },
309 { 0x800074, 0x01 },
310 { 0x800075, 0x03 },
311 { 0x800076, 0x02 },
312 { 0x800077, 0x00 },
313 { 0x800078, 0x01 },
314 { 0x800079, 0x00 },
315 { 0x80007a, 0x7e },
316 { 0x80007b, 0x3e },
317 { 0x800093, 0x00 },
318 { 0x800094, 0x01 },
319 { 0x800095, 0x02 },
320 { 0x800096, 0x01 },
321 { 0x800098, 0x0a },
322 { 0x80009b, 0x05 },
323 { 0x80009c, 0x80 },
324 { 0x8000b3, 0x00 },
325 { 0x8000c1, 0x01 },
326 { 0x8000c2, 0x00 },
327 { 0x80f007, 0x00 },
328 { 0x80f01f, 0x82 },
329 { 0x80f020, 0x00 },
330 { 0x80f029, 0x82 },
331 { 0x80f02a, 0x00 },
332 { 0x80f047, 0x00 },
333 { 0x80f054, 0x00 },
334 { 0x80f055, 0x00 },
335 { 0x80f077, 0x01 },
336 { 0x80f1e6, 0x00 },
337};
338
339/* Fitipower fc0011 tuner init
340 AF9033_TUNER_FC0011 = 0x28 */
341static const struct reg_val tuner_init_fc0011[] = {
342 { 0x800046, AF9033_TUNER_FC0011 },
343 { 0x800057, 0x00 },
344 { 0x800058, 0x01 },
345 { 0x80005f, 0x00 },
346 { 0x800060, 0x00 },
347 { 0x800068, 0xa5 },
348 { 0x80006e, 0x01 },
349 { 0x800071, 0x0A },
350 { 0x800072, 0x02 },
351 { 0x800074, 0x01 },
352 { 0x800079, 0x01 },
353 { 0x800093, 0x00 },
354 { 0x800094, 0x00 },
355 { 0x800095, 0x00 },
356 { 0x800096, 0x00 },
357 { 0x80009b, 0x2D },
358 { 0x80009c, 0x60 },
359 { 0x80009d, 0x23 },
360 { 0x8000a4, 0x50 },
361 { 0x8000ad, 0x50 },
362 { 0x8000b3, 0x01 },
363 { 0x8000b7, 0x88 },
364 { 0x8000b8, 0xa6 },
365 { 0x8000c3, 0x01 },
366 { 0x8000c4, 0x01 },
367 { 0x8000c7, 0x69 },
368 { 0x80F007, 0x00 },
369 { 0x80F00A, 0x1B },
370 { 0x80F00B, 0x1B },
371 { 0x80F00C, 0x1B },
372 { 0x80F00D, 0x1B },
373 { 0x80F00E, 0xFF },
374 { 0x80F00F, 0x01 },
375 { 0x80F010, 0x00 },
376 { 0x80F011, 0x02 },
377 { 0x80F012, 0xFF },
378 { 0x80F013, 0x01 },
379 { 0x80F014, 0x00 },
380 { 0x80F015, 0x02 },
381 { 0x80F01B, 0xEF },
382 { 0x80F01C, 0x01 },
383 { 0x80F01D, 0x0f },
384 { 0x80F01E, 0x02 },
385 { 0x80F01F, 0x6E },
386 { 0x80F020, 0x00 },
387 { 0x80F025, 0xDE },
388 { 0x80F026, 0x00 },
389 { 0x80F027, 0x0A },
390 { 0x80F028, 0x03 },
391 { 0x80F029, 0x6E },
392 { 0x80F02A, 0x00 },
393 { 0x80F047, 0x00 },
394 { 0x80F054, 0x00 },
395 { 0x80F055, 0x00 },
396 { 0x80F077, 0x01 },
397 { 0x80F1E6, 0x00 },
398};
399
400/* MaxLinear MxL5007T tuner init
401 AF9033_TUNER_MXL5007T = 0xa0 */
402static const struct reg_val tuner_init_mxl5007t[] = {
403 { 0x800046, 0x1b },
404 { 0x800057, 0x01 },
405 { 0x800058, 0x01 },
406 { 0x80005f, 0x00 },
407 { 0x800060, 0x00 },
408 { 0x800068, 0x96 },
409 { 0x800071, 0x05 },
410 { 0x800072, 0x02 },
411 { 0x800074, 0x01 },
412 { 0x800079, 0x01 },
413 { 0x800093, 0x00 },
414 { 0x800094, 0x00 },
415 { 0x800095, 0x00 },
416 { 0x800096, 0x00 },
417 { 0x8000b3, 0x01 },
418 { 0x8000c1, 0x01 },
419 { 0x8000c2, 0x00 },
420 { 0x80f007, 0x00 },
421 { 0x80f00c, 0x19 },
422 { 0x80f00d, 0x1a },
423 { 0x80f012, 0xda },
424 { 0x80f013, 0x00 },
425 { 0x80f014, 0x00 },
426 { 0x80f015, 0x02 },
427 { 0x80f01f, 0x82 },
428 { 0x80f020, 0x00 },
429 { 0x80f029, 0x82 },
430 { 0x80f02a, 0x00 },
431 { 0x80f077, 0x02 },
432 { 0x80f1e6, 0x00 },
433};
434
435/* NXP TDA 18218HN tuner init
436 AF9033_TUNER_TDA18218 = 0xa1 */
437static const struct reg_val tuner_init_tda18218[] = {
438 {0x800046, 0xa1},
439 {0x800057, 0x01},
440 {0x800058, 0x01},
441 {0x80005f, 0x00},
442 {0x800060, 0x00},
443 {0x800071, 0x05},
444 {0x800072, 0x02},
445 {0x800074, 0x01},
446 {0x800079, 0x01},
447 {0x800093, 0x00},
448 {0x800094, 0x00},
449 {0x800095, 0x00},
450 {0x800096, 0x00},
451 {0x8000b3, 0x01},
452 {0x8000c3, 0x01},
453 {0x8000c4, 0x00},
454 {0x80f007, 0x00},
455 {0x80f00c, 0x19},
456 {0x80f00d, 0x1a},
457 {0x80f012, 0xda},
458 {0x80f013, 0x00},
459 {0x80f014, 0x00},
460 {0x80f015, 0x02},
461 {0x80f01f, 0x82},
462 {0x80f020, 0x00},
463 {0x80f029, 0x82},
464 {0x80f02a, 0x00},
465 {0x80f077, 0x02},
466 {0x80f1e6, 0x00},
467};
468
469#endif /* AF9033_PRIV_H */
470
diff --git a/drivers/media/dvb/frontends/au8522_common.c b/drivers/media/dvb/frontends/au8522_common.c
new file mode 100644
index 000000000000..5cfe151ee394
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_common.c
@@ -0,0 +1,259 @@
1/*
2 Auvitek AU8522 QAM/8VSB demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
6 Copyright (C) 2005-2008 Auvitek International, Ltd.
7 Copyright (C) 2012 Michael Krufky <mkrufky@linuxtv.org>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#include <linux/i2c.h>
26#include "dvb_frontend.h"
27#include "au8522_priv.h"
28
29MODULE_LICENSE("GPL");
30
31static int debug;
32
33#define dprintk(arg...)\
34 do { if (debug)\
35 printk(arg);\
36 } while (0)
37
38/* Despite the name "hybrid_tuner", the framework works just as well for
39 hybrid demodulators as well... */
40static LIST_HEAD(hybrid_tuner_instance_list);
41static DEFINE_MUTEX(au8522_list_mutex);
42
43/* 16 bit registers, 8 bit values */
44int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
45{
46 int ret;
47 u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
48
49 struct i2c_msg msg = { .addr = state->config->demod_address,
50 .flags = 0, .buf = buf, .len = 3 };
51
52 ret = i2c_transfer(state->i2c, &msg, 1);
53
54 if (ret != 1)
55 printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
56 "ret == %i)\n", __func__, reg, data, ret);
57
58 return (ret != 1) ? -1 : 0;
59}
60EXPORT_SYMBOL(au8522_writereg);
61
62u8 au8522_readreg(struct au8522_state *state, u16 reg)
63{
64 int ret;
65 u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
66 u8 b1[] = { 0 };
67
68 struct i2c_msg msg[] = {
69 { .addr = state->config->demod_address, .flags = 0,
70 .buf = b0, .len = 2 },
71 { .addr = state->config->demod_address, .flags = I2C_M_RD,
72 .buf = b1, .len = 1 } };
73
74 ret = i2c_transfer(state->i2c, msg, 2);
75
76 if (ret != 2)
77 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
78 __func__, ret);
79 return b1[0];
80}
81EXPORT_SYMBOL(au8522_readreg);
82
83int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
84{
85 struct au8522_state *state = fe->demodulator_priv;
86
87 dprintk("%s(%d)\n", __func__, enable);
88
89 if (state->operational_mode == AU8522_ANALOG_MODE) {
90 /* We're being asked to manage the gate even though we're
91 not in digital mode. This can occur if we get switched
92 over to analog mode before the dvb_frontend kernel thread
93 has completely shutdown */
94 return 0;
95 }
96
97 if (enable)
98 return au8522_writereg(state, 0x106, 1);
99 else
100 return au8522_writereg(state, 0x106, 0);
101}
102EXPORT_SYMBOL(au8522_i2c_gate_ctrl);
103
104/* Reset the demod hardware and reset all of the configuration registers
105 to a default state. */
106int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
107 u8 client_address)
108{
109 int ret;
110
111 mutex_lock(&au8522_list_mutex);
112 ret = hybrid_tuner_request_state(struct au8522_state, (*state),
113 hybrid_tuner_instance_list,
114 i2c, client_address, "au8522");
115 mutex_unlock(&au8522_list_mutex);
116
117 return ret;
118}
119EXPORT_SYMBOL(au8522_get_state);
120
121void au8522_release_state(struct au8522_state *state)
122{
123 mutex_lock(&au8522_list_mutex);
124 if (state != NULL)
125 hybrid_tuner_release_state(state);
126 mutex_unlock(&au8522_list_mutex);
127}
128EXPORT_SYMBOL(au8522_release_state);
129
130static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
131{
132 struct au8522_led_config *led_config = state->config->led_cfg;
133 u8 val;
134
135 /* bail out if we can't control an LED */
136 if (!led_config || !led_config->gpio_output ||
137 !led_config->gpio_output_enable || !led_config->gpio_output_disable)
138 return 0;
139
140 val = au8522_readreg(state, 0x4000 |
141 (led_config->gpio_output & ~0xc000));
142 if (onoff) {
143 /* enable GPIO output */
144 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
145 val |= (led_config->gpio_output_enable & 0xff);
146 } else {
147 /* disable GPIO output */
148 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
149 val |= (led_config->gpio_output_disable & 0xff);
150 }
151 return au8522_writereg(state, 0x8000 |
152 (led_config->gpio_output & ~0xc000), val);
153}
154
155/* led = 0 | off
156 * led = 1 | signal ok
157 * led = 2 | signal strong
158 * led < 0 | only light led if leds are currently off
159 */
160int au8522_led_ctrl(struct au8522_state *state, int led)
161{
162 struct au8522_led_config *led_config = state->config->led_cfg;
163 int i, ret = 0;
164
165 /* bail out if we can't control an LED */
166 if (!led_config || !led_config->gpio_leds ||
167 !led_config->num_led_states || !led_config->led_states)
168 return 0;
169
170 if (led < 0) {
171 /* if LED is already lit, then leave it as-is */
172 if (state->led_state)
173 return 0;
174 else
175 led *= -1;
176 }
177
178 /* toggle LED if changing state */
179 if (state->led_state != led) {
180 u8 val;
181
182 dprintk("%s: %d\n", __func__, led);
183
184 au8522_led_gpio_enable(state, 1);
185
186 val = au8522_readreg(state, 0x4000 |
187 (led_config->gpio_leds & ~0xc000));
188
189 /* start with all leds off */
190 for (i = 0; i < led_config->num_led_states; i++)
191 val &= ~led_config->led_states[i];
192
193 /* set selected LED state */
194 if (led < led_config->num_led_states)
195 val |= led_config->led_states[led];
196 else if (led_config->num_led_states)
197 val |=
198 led_config->led_states[led_config->num_led_states - 1];
199
200 ret = au8522_writereg(state, 0x8000 |
201 (led_config->gpio_leds & ~0xc000), val);
202 if (ret < 0)
203 return ret;
204
205 state->led_state = led;
206
207 if (led == 0)
208 au8522_led_gpio_enable(state, 0);
209 }
210
211 return 0;
212}
213EXPORT_SYMBOL(au8522_led_ctrl);
214
215int au8522_init(struct dvb_frontend *fe)
216{
217 struct au8522_state *state = fe->demodulator_priv;
218 dprintk("%s()\n", __func__);
219
220 state->operational_mode = AU8522_DIGITAL_MODE;
221
222 /* Clear out any state associated with the digital side of the
223 chip, so that when it gets powered back up it won't think
224 that it is already tuned */
225 state->current_frequency = 0;
226
227 au8522_writereg(state, 0xa4, 1 << 5);
228
229 au8522_i2c_gate_ctrl(fe, 1);
230
231 return 0;
232}
233EXPORT_SYMBOL(au8522_init);
234
235int au8522_sleep(struct dvb_frontend *fe)
236{
237 struct au8522_state *state = fe->demodulator_priv;
238 dprintk("%s()\n", __func__);
239
240 /* Only power down if the digital side is currently using the chip */
241 if (state->operational_mode == AU8522_ANALOG_MODE) {
242 /* We're not in one of the expected power modes, which means
243 that the DVB thread is probably telling us to go to sleep
244 even though the analog frontend has already started using
245 the chip. So ignore the request */
246 return 0;
247 }
248
249 /* turn off led */
250 au8522_led_ctrl(state, 0);
251
252 /* Power down the chip */
253 au8522_writereg(state, 0xa4, 1 << 5);
254
255 state->current_frequency = 0;
256
257 return 0;
258}
259EXPORT_SYMBOL(au8522_sleep);
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index 25f650934c73..5fc70d6cd04f 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -30,74 +30,11 @@
30 30
31static int debug; 31static int debug;
32 32
33/* Despite the name "hybrid_tuner", the framework works just as well for
34 hybrid demodulators as well... */
35static LIST_HEAD(hybrid_tuner_instance_list);
36static DEFINE_MUTEX(au8522_list_mutex);
37
38#define dprintk(arg...)\ 33#define dprintk(arg...)\
39 do { if (debug)\ 34 do { if (debug)\
40 printk(arg);\ 35 printk(arg);\
41 } while (0) 36 } while (0)
42 37
43/* 16 bit registers, 8 bit values */
44int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
45{
46 int ret;
47 u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
48
49 struct i2c_msg msg = { .addr = state->config->demod_address,
50 .flags = 0, .buf = buf, .len = 3 };
51
52 ret = i2c_transfer(state->i2c, &msg, 1);
53
54 if (ret != 1)
55 printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
56 "ret == %i)\n", __func__, reg, data, ret);
57
58 return (ret != 1) ? -1 : 0;
59}
60
61u8 au8522_readreg(struct au8522_state *state, u16 reg)
62{
63 int ret;
64 u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
65 u8 b1[] = { 0 };
66
67 struct i2c_msg msg[] = {
68 { .addr = state->config->demod_address, .flags = 0,
69 .buf = b0, .len = 2 },
70 { .addr = state->config->demod_address, .flags = I2C_M_RD,
71 .buf = b1, .len = 1 } };
72
73 ret = i2c_transfer(state->i2c, msg, 2);
74
75 if (ret != 2)
76 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
77 __func__, ret);
78 return b1[0];
79}
80
81static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
82{
83 struct au8522_state *state = fe->demodulator_priv;
84
85 dprintk("%s(%d)\n", __func__, enable);
86
87 if (state->operational_mode == AU8522_ANALOG_MODE) {
88 /* We're being asked to manage the gate even though we're
89 not in digital mode. This can occur if we get switched
90 over to analog mode before the dvb_frontend kernel thread
91 has completely shutdown */
92 return 0;
93 }
94
95 if (enable)
96 return au8522_writereg(state, 0x106, 1);
97 else
98 return au8522_writereg(state, 0x106, 0);
99}
100
101struct mse2snr_tab { 38struct mse2snr_tab {
102 u16 val; 39 u16 val;
103 u16 data; 40 u16 data;
@@ -609,136 +546,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
609 return 0; 546 return 0;
610} 547}
611 548
612/* Reset the demod hardware and reset all of the configuration registers
613 to a default state. */
614int au8522_init(struct dvb_frontend *fe)
615{
616 struct au8522_state *state = fe->demodulator_priv;
617 dprintk("%s()\n", __func__);
618
619 state->operational_mode = AU8522_DIGITAL_MODE;
620
621 /* Clear out any state associated with the digital side of the
622 chip, so that when it gets powered back up it won't think
623 that it is already tuned */
624 state->current_frequency = 0;
625
626 au8522_writereg(state, 0xa4, 1 << 5);
627
628 au8522_i2c_gate_ctrl(fe, 1);
629
630 return 0;
631}
632
633static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
634{
635 struct au8522_led_config *led_config = state->config->led_cfg;
636 u8 val;
637
638 /* bail out if we can't control an LED */
639 if (!led_config || !led_config->gpio_output ||
640 !led_config->gpio_output_enable || !led_config->gpio_output_disable)
641 return 0;
642
643 val = au8522_readreg(state, 0x4000 |
644 (led_config->gpio_output & ~0xc000));
645 if (onoff) {
646 /* enable GPIO output */
647 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
648 val |= (led_config->gpio_output_enable & 0xff);
649 } else {
650 /* disable GPIO output */
651 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
652 val |= (led_config->gpio_output_disable & 0xff);
653 }
654 return au8522_writereg(state, 0x8000 |
655 (led_config->gpio_output & ~0xc000), val);
656}
657
658/* led = 0 | off
659 * led = 1 | signal ok
660 * led = 2 | signal strong
661 * led < 0 | only light led if leds are currently off
662 */
663static int au8522_led_ctrl(struct au8522_state *state, int led)
664{
665 struct au8522_led_config *led_config = state->config->led_cfg;
666 int i, ret = 0;
667
668 /* bail out if we can't control an LED */
669 if (!led_config || !led_config->gpio_leds ||
670 !led_config->num_led_states || !led_config->led_states)
671 return 0;
672
673 if (led < 0) {
674 /* if LED is already lit, then leave it as-is */
675 if (state->led_state)
676 return 0;
677 else
678 led *= -1;
679 }
680
681 /* toggle LED if changing state */
682 if (state->led_state != led) {
683 u8 val;
684
685 dprintk("%s: %d\n", __func__, led);
686
687 au8522_led_gpio_enable(state, 1);
688
689 val = au8522_readreg(state, 0x4000 |
690 (led_config->gpio_leds & ~0xc000));
691
692 /* start with all leds off */
693 for (i = 0; i < led_config->num_led_states; i++)
694 val &= ~led_config->led_states[i];
695
696 /* set selected LED state */
697 if (led < led_config->num_led_states)
698 val |= led_config->led_states[led];
699 else if (led_config->num_led_states)
700 val |=
701 led_config->led_states[led_config->num_led_states - 1];
702
703 ret = au8522_writereg(state, 0x8000 |
704 (led_config->gpio_leds & ~0xc000), val);
705 if (ret < 0)
706 return ret;
707
708 state->led_state = led;
709
710 if (led == 0)
711 au8522_led_gpio_enable(state, 0);
712 }
713
714 return 0;
715}
716
717int au8522_sleep(struct dvb_frontend *fe)
718{
719 struct au8522_state *state = fe->demodulator_priv;
720 dprintk("%s()\n", __func__);
721
722 /* Only power down if the digital side is currently using the chip */
723 if (state->operational_mode == AU8522_ANALOG_MODE) {
724 /* We're not in one of the expected power modes, which means
725 that the DVB thread is probably telling us to go to sleep
726 even though the analog frontend has already started using
727 the chip. So ignore the request */
728 return 0;
729 }
730
731 /* turn off led */
732 au8522_led_ctrl(state, 0);
733
734 /* Power down the chip */
735 au8522_writereg(state, 0xa4, 1 << 5);
736
737 state->current_frequency = 0;
738
739 return 0;
740}
741
742static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) 549static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
743{ 550{
744 struct au8522_state *state = fe->demodulator_priv; 551 struct au8522_state *state = fe->demodulator_priv;
@@ -931,28 +738,6 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
931 738
932static struct dvb_frontend_ops au8522_ops; 739static struct dvb_frontend_ops au8522_ops;
933 740
934int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
935 u8 client_address)
936{
937 int ret;
938
939 mutex_lock(&au8522_list_mutex);
940 ret = hybrid_tuner_request_state(struct au8522_state, (*state),
941 hybrid_tuner_instance_list,
942 i2c, client_address, "au8522");
943 mutex_unlock(&au8522_list_mutex);
944
945 return ret;
946}
947
948void au8522_release_state(struct au8522_state *state)
949{
950 mutex_lock(&au8522_list_mutex);
951 if (state != NULL)
952 hybrid_tuner_release_state(state);
953 mutex_unlock(&au8522_list_mutex);
954}
955
956 741
957static void au8522_release(struct dvb_frontend *fe) 742static void au8522_release(struct dvb_frontend *fe)
958{ 743{
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index 751e17d692a9..6e4a438732b5 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -81,6 +81,8 @@ int au8522_sleep(struct dvb_frontend *fe);
81int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, 81int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
82 u8 client_address); 82 u8 client_address);
83void au8522_release_state(struct au8522_state *state); 83void au8522_release_state(struct au8522_state *state);
84int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
85int au8522_led_ctrl(struct au8522_state *state, int led);
84 86
85/* REGISTERS */ 87/* REGISTERS */
86#define AU8522_INPUT_CONTROL_REG081H 0x081 88#define AU8522_INPUT_CONTROL_REG081H 0x081
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 5101f10f2d7a..98ecaf0900d6 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -512,14 +512,13 @@ static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
512static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 512static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
513{ 513{
514 struct cx24110_state *state = fe->demodulator_priv; 514 struct cx24110_state *state = fe->demodulator_priv;
515 u32 lastbyer;
516 515
517 if(cx24110_readreg(state,0x10)&0x40) { 516 if(cx24110_readreg(state,0x10)&0x40) {
518 /* the RS error counter has finished one counting window */ 517 /* the RS error counter has finished one counting window */
519 cx24110_writereg(state,0x10,0x60); /* select the byer reg */ 518 cx24110_writereg(state,0x10,0x60); /* select the byer reg */
520 lastbyer=cx24110_readreg(state,0x12)| 519 cx24110_readreg(state, 0x12) |
521 (cx24110_readreg(state,0x13)<<8)| 520 (cx24110_readreg(state, 0x13) << 8) |
522 (cx24110_readreg(state,0x14)<<16); 521 (cx24110_readreg(state, 0x14) << 16);
523 cx24110_writereg(state,0x10,0x70); /* select the bler reg */ 522 cx24110_writereg(state,0x10,0x70); /* select the bler reg */
524 state->lastbler=cx24110_readreg(state,0x12)| 523 state->lastbler=cx24110_readreg(state,0x12)|
525 (cx24110_readreg(state,0x13)<<8)| 524 (cx24110_readreg(state,0x13)<<8)|
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
index 5c7c2aaf9bf5..3bba37d74f57 100644
--- a/drivers/media/dvb/frontends/cxd2820r_core.c
+++ b/drivers/media/dvb/frontends/cxd2820r_core.c
@@ -526,12 +526,12 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
526 if (ret) 526 if (ret)
527 goto error; 527 goto error;
528 528
529 if (status & FE_HAS_SIGNAL) 529 if (status & FE_HAS_LOCK)
530 break; 530 break;
531 } 531 }
532 532
533 /* check if we have a valid signal */ 533 /* check if we have a valid signal */
534 if (status) { 534 if (status & FE_HAS_LOCK) {
535 priv->last_tune_failed = 0; 535 priv->last_tune_failed = 0;
536 return DVBFE_ALGO_SEARCH_SUCCESS; 536 return DVBFE_ALGO_SEARCH_SUCCESS;
537 } else { 537 } else {
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 5ceadc285b3a..3e1eefada0e8 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -2396,11 +2396,6 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
2396 more common) */ 2396 more common) */
2397 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; 2397 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2398 2398
2399 /* FIXME: make sure the dev.parent field is initialized, or else
2400 request_firmware() will hit an OOPS (this should be moved somewhere
2401 more common) */
2402 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2403
2404 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); 2399 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2405 2400
2406 /* init 7090 tuner adapter */ 2401 /* init 7090 tuner adapter */
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
index 80848b4c15d4..6201c59a78dd 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -31,13 +31,6 @@ struct i2c_device {
31 u8 *i2c_write_buffer; 31 u8 *i2c_write_buffer;
32}; 32};
33 33
34/* lock */
35#define DIB_LOCK struct mutex
36#define DibAcquireLock(lock) mutex_lock_interruptible(lock)
37#define DibReleaseLock(lock) mutex_unlock(lock)
38#define DibInitLock(lock) mutex_init(lock)
39#define DibFreeLock(lock)
40
41struct dib9000_pid_ctrl { 34struct dib9000_pid_ctrl {
42#define DIB9000_PID_FILTER_CTRL 0 35#define DIB9000_PID_FILTER_CTRL 0
43#define DIB9000_PID_FILTER 1 36#define DIB9000_PID_FILTER 1
@@ -82,11 +75,11 @@ struct dib9000_state {
82 } fe_mm[18]; 75 } fe_mm[18];
83 u8 memcmd; 76 u8 memcmd;
84 77
85 DIB_LOCK mbx_if_lock; /* to protect read/write operations */ 78 struct mutex mbx_if_lock; /* to protect read/write operations */
86 DIB_LOCK mbx_lock; /* to protect the whole mailbox handling */ 79 struct mutex mbx_lock; /* to protect the whole mailbox handling */
87 80
88 DIB_LOCK mem_lock; /* to protect the memory accesses */ 81 struct mutex mem_lock; /* to protect the memory accesses */
89 DIB_LOCK mem_mbx_lock; /* to protect the memory-based mailbox */ 82 struct mutex mem_mbx_lock; /* to protect the memory-based mailbox */
90 83
91#define MBX_MAX_WORDS (256 - 200 - 2) 84#define MBX_MAX_WORDS (256 - 200 - 2)
92#define DIB9000_MSG_CACHE_SIZE 2 85#define DIB9000_MSG_CACHE_SIZE 2
@@ -108,7 +101,7 @@ struct dib9000_state {
108 struct i2c_msg msg[2]; 101 struct i2c_msg msg[2];
109 u8 i2c_write_buffer[255]; 102 u8 i2c_write_buffer[255];
110 u8 i2c_read_buffer[255]; 103 u8 i2c_read_buffer[255];
111 DIB_LOCK demod_lock; 104 struct mutex demod_lock;
112 u8 get_frontend_internal; 105 u8 get_frontend_internal;
113 struct dib9000_pid_ctrl pid_ctrl[10]; 106 struct dib9000_pid_ctrl pid_ctrl[10];
114 s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */ 107 s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
@@ -446,13 +439,13 @@ static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u1
446 if (!state->platform.risc.fw_is_running) 439 if (!state->platform.risc.fw_is_running)
447 return -EIO; 440 return -EIO;
448 441
449 if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) { 442 if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
450 dprintk("could not get the lock"); 443 dprintk("could not get the lock");
451 return -EINTR; 444 return -EINTR;
452 } 445 }
453 dib9000_risc_mem_setup(state, cmd | 0x80); 446 dib9000_risc_mem_setup(state, cmd | 0x80);
454 dib9000_risc_mem_read_chunks(state, b, len); 447 dib9000_risc_mem_read_chunks(state, b, len);
455 DibReleaseLock(&state->platform.risc.mem_lock); 448 mutex_unlock(&state->platform.risc.mem_lock);
456 return 0; 449 return 0;
457} 450}
458 451
@@ -462,13 +455,13 @@ static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8
462 if (!state->platform.risc.fw_is_running) 455 if (!state->platform.risc.fw_is_running)
463 return -EIO; 456 return -EIO;
464 457
465 if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) { 458 if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
466 dprintk("could not get the lock"); 459 dprintk("could not get the lock");
467 return -EINTR; 460 return -EINTR;
468 } 461 }
469 dib9000_risc_mem_setup(state, cmd); 462 dib9000_risc_mem_setup(state, cmd);
470 dib9000_risc_mem_write_chunks(state, b, m->size); 463 dib9000_risc_mem_write_chunks(state, b, m->size);
471 DibReleaseLock(&state->platform.risc.mem_lock); 464 mutex_unlock(&state->platform.risc.mem_lock);
472 return 0; 465 return 0;
473} 466}
474 467
@@ -537,7 +530,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data,
537 if (!state->platform.risc.fw_is_running) 530 if (!state->platform.risc.fw_is_running)
538 return -EINVAL; 531 return -EINVAL;
539 532
540 if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) { 533 if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
541 dprintk("could not get the lock"); 534 dprintk("could not get the lock");
542 return -EINTR; 535 return -EINTR;
543 } 536 }
@@ -584,7 +577,7 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data,
584 ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr); 577 ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
585 578
586out: 579out:
587 DibReleaseLock(&state->platform.risc.mbx_if_lock); 580 mutex_unlock(&state->platform.risc.mbx_if_lock);
588 581
589 return ret; 582 return ret;
590} 583}
@@ -602,7 +595,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id,
602 if (!state->platform.risc.fw_is_running) 595 if (!state->platform.risc.fw_is_running)
603 return 0; 596 return 0;
604 597
605 if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) { 598 if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
606 dprintk("could not get the lock"); 599 dprintk("could not get the lock");
607 return 0; 600 return 0;
608 } 601 }
@@ -643,7 +636,7 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id,
643 /* Update register nb_mes_in_TX */ 636 /* Update register nb_mes_in_TX */
644 dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr); 637 dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
645 638
646 DibReleaseLock(&state->platform.risc.mbx_if_lock); 639 mutex_unlock(&state->platform.risc.mbx_if_lock);
647 640
648 return size + 1; 641 return size + 1;
649} 642}
@@ -708,12 +701,11 @@ static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
708static int dib9000_mbx_process(struct dib9000_state *state, u16 attr) 701static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
709{ 702{
710 int ret = 0; 703 int ret = 0;
711 u16 tmp;
712 704
713 if (!state->platform.risc.fw_is_running) 705 if (!state->platform.risc.fw_is_running)
714 return -1; 706 return -1;
715 707
716 if (DibAcquireLock(&state->platform.risc.mbx_lock) < 0) { 708 if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) {
717 dprintk("could not get the lock"); 709 dprintk("could not get the lock");
718 return -1; 710 return -1;
719 } 711 }
@@ -721,10 +713,10 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
721 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */ 713 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
722 ret = dib9000_mbx_fetch_to_cache(state, attr); 714 ret = dib9000_mbx_fetch_to_cache(state, attr);
723 715
724 tmp = dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */ 716 dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */
725/* if (tmp) */ 717/* if (tmp) */
726/* dprintk( "cleared IRQ: %x", tmp); */ 718/* dprintk( "cleared IRQ: %x", tmp); */
727 DibReleaseLock(&state->platform.risc.mbx_lock); 719 mutex_unlock(&state->platform.risc.mbx_lock);
728 720
729 return ret; 721 return ret;
730} 722}
@@ -1193,7 +1185,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe)
1193 struct dibDVBTChannel *ch; 1185 struct dibDVBTChannel *ch;
1194 int ret = 0; 1186 int ret = 0;
1195 1187
1196 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 1188 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
1197 dprintk("could not get the lock"); 1189 dprintk("could not get the lock");
1198 return -EINTR; 1190 return -EINTR;
1199 } 1191 }
@@ -1323,7 +1315,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe)
1323 } 1315 }
1324 1316
1325error: 1317error:
1326 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 1318 mutex_unlock(&state->platform.risc.mem_mbx_lock);
1327 return ret; 1319 return ret;
1328} 1320}
1329 1321
@@ -1678,7 +1670,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2
1678 p[12] = 0; 1670 p[12] = 0;
1679 } 1671 }
1680 1672
1681 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 1673 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
1682 dprintk("could not get the lock"); 1674 dprintk("could not get the lock");
1683 return 0; 1675 return 0;
1684 } 1676 }
@@ -1692,7 +1684,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2
1692 1684
1693 /* do the transaction */ 1685 /* do the transaction */
1694 if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) { 1686 if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
1695 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 1687 mutex_unlock(&state->platform.risc.mem_mbx_lock);
1696 return 0; 1688 return 0;
1697 } 1689 }
1698 1690
@@ -1700,7 +1692,7 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2
1700 if ((num > 1) && (msg[1].flags & I2C_M_RD)) 1692 if ((num > 1) && (msg[1].flags & I2C_M_RD))
1701 dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len); 1693 dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
1702 1694
1703 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 1695 mutex_unlock(&state->platform.risc.mem_mbx_lock);
1704 1696
1705 return num; 1697 return num;
1706} 1698}
@@ -1789,7 +1781,7 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1789 return 0; 1781 return 0;
1790 } 1782 }
1791 1783
1792 if (DibAcquireLock(&state->demod_lock) < 0) { 1784 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
1793 dprintk("could not get the lock"); 1785 dprintk("could not get the lock");
1794 return -EINTR; 1786 return -EINTR;
1795 } 1787 }
@@ -1799,7 +1791,7 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1799 1791
1800 dprintk("PID filter enabled %d", onoff); 1792 dprintk("PID filter enabled %d", onoff);
1801 ret = dib9000_write_word(state, 294 + 1, val); 1793 ret = dib9000_write_word(state, 294 + 1, val);
1802 DibReleaseLock(&state->demod_lock); 1794 mutex_unlock(&state->demod_lock);
1803 return ret; 1795 return ret;
1804 1796
1805} 1797}
@@ -1824,14 +1816,14 @@ int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1824 return 0; 1816 return 0;
1825 } 1817 }
1826 1818
1827 if (DibAcquireLock(&state->demod_lock) < 0) { 1819 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
1828 dprintk("could not get the lock"); 1820 dprintk("could not get the lock");
1829 return -EINTR; 1821 return -EINTR;
1830 } 1822 }
1831 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); 1823 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
1832 ret = dib9000_write_word(state, 300 + 1 + id, 1824 ret = dib9000_write_word(state, 300 + 1 + id,
1833 onoff ? (1 << 13) | pid : 0); 1825 onoff ? (1 << 13) | pid : 0);
1834 DibReleaseLock(&state->demod_lock); 1826 mutex_unlock(&state->demod_lock);
1835 return ret; 1827 return ret;
1836} 1828}
1837EXPORT_SYMBOL(dib9000_fw_pid_filter); 1829EXPORT_SYMBOL(dib9000_fw_pid_filter);
@@ -1851,11 +1843,6 @@ static void dib9000_release(struct dvb_frontend *demod)
1851 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) 1843 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
1852 dvb_frontend_detach(st->fe[index_frontend]); 1844 dvb_frontend_detach(st->fe[index_frontend]);
1853 1845
1854 DibFreeLock(&state->platform.risc.mbx_if_lock);
1855 DibFreeLock(&state->platform.risc.mbx_lock);
1856 DibFreeLock(&state->platform.risc.mem_lock);
1857 DibFreeLock(&state->platform.risc.mem_mbx_lock);
1858 DibFreeLock(&state->demod_lock);
1859 dibx000_exit_i2c_master(&st->i2c_master); 1846 dibx000_exit_i2c_master(&st->i2c_master);
1860 1847
1861 i2c_del_adapter(&st->tuner_adap); 1848 i2c_del_adapter(&st->tuner_adap);
@@ -1875,7 +1862,7 @@ static int dib9000_sleep(struct dvb_frontend *fe)
1875 u8 index_frontend; 1862 u8 index_frontend;
1876 int ret = 0; 1863 int ret = 0;
1877 1864
1878 if (DibAcquireLock(&state->demod_lock) < 0) { 1865 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
1879 dprintk("could not get the lock"); 1866 dprintk("could not get the lock");
1880 return -EINTR; 1867 return -EINTR;
1881 } 1868 }
@@ -1887,7 +1874,7 @@ static int dib9000_sleep(struct dvb_frontend *fe)
1887 ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0); 1874 ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
1888 1875
1889error: 1876error:
1890 DibReleaseLock(&state->demod_lock); 1877 mutex_unlock(&state->demod_lock);
1891 return ret; 1878 return ret;
1892} 1879}
1893 1880
@@ -1905,7 +1892,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe)
1905 int ret = 0; 1892 int ret = 0;
1906 1893
1907 if (state->get_frontend_internal == 0) { 1894 if (state->get_frontend_internal == 0) {
1908 if (DibAcquireLock(&state->demod_lock) < 0) { 1895 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
1909 dprintk("could not get the lock"); 1896 dprintk("could not get the lock");
1910 return -EINTR; 1897 return -EINTR;
1911 } 1898 }
@@ -1964,7 +1951,7 @@ static int dib9000_get_frontend(struct dvb_frontend *fe)
1964 1951
1965return_value: 1952return_value:
1966 if (state->get_frontend_internal == 0) 1953 if (state->get_frontend_internal == 0)
1967 DibReleaseLock(&state->demod_lock); 1954 mutex_unlock(&state->demod_lock);
1968 return ret; 1955 return ret;
1969} 1956}
1970 1957
@@ -2012,7 +1999,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe)
2012 } 1999 }
2013 2000
2014 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ 2001 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
2015 if (DibAcquireLock(&state->demod_lock) < 0) { 2002 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
2016 dprintk("could not get the lock"); 2003 dprintk("could not get the lock");
2017 return 0; 2004 return 0;
2018 } 2005 }
@@ -2081,7 +2068,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe)
2081 /* check the tune result */ 2068 /* check the tune result */
2082 if (exit_condition == 1) { /* tune failed */ 2069 if (exit_condition == 1) { /* tune failed */
2083 dprintk("tune failed"); 2070 dprintk("tune failed");
2084 DibReleaseLock(&state->demod_lock); 2071 mutex_unlock(&state->demod_lock);
2085 /* tune failed; put all the pid filtering cmd to junk */ 2072 /* tune failed; put all the pid filtering cmd to junk */
2086 state->pid_ctrl_index = -1; 2073 state->pid_ctrl_index = -1;
2087 return 0; 2074 return 0;
@@ -2137,7 +2124,7 @@ static int dib9000_set_frontend(struct dvb_frontend *fe)
2137 /* turn off the diversity for the last frontend */ 2124 /* turn off the diversity for the last frontend */
2138 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0); 2125 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
2139 2126
2140 DibReleaseLock(&state->demod_lock); 2127 mutex_unlock(&state->demod_lock);
2141 if (state->pid_ctrl_index >= 0) { 2128 if (state->pid_ctrl_index >= 0) {
2142 u8 index_pid_filter_cmd; 2129 u8 index_pid_filter_cmd;
2143 u8 pid_ctrl_index = state->pid_ctrl_index; 2130 u8 pid_ctrl_index = state->pid_ctrl_index;
@@ -2175,7 +2162,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2175 u8 index_frontend; 2162 u8 index_frontend;
2176 u16 lock = 0, lock_slave = 0; 2163 u16 lock = 0, lock_slave = 0;
2177 2164
2178 if (DibAcquireLock(&state->demod_lock) < 0) { 2165 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
2179 dprintk("could not get the lock"); 2166 dprintk("could not get the lock");
2180 return -EINTR; 2167 return -EINTR;
2181 } 2168 }
@@ -2197,7 +2184,7 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2197 if ((lock & 0x0008) || (lock_slave & 0x0008)) 2184 if ((lock & 0x0008) || (lock_slave & 0x0008))
2198 *stat |= FE_HAS_LOCK; 2185 *stat |= FE_HAS_LOCK;
2199 2186
2200 DibReleaseLock(&state->demod_lock); 2187 mutex_unlock(&state->demod_lock);
2201 2188
2202 return 0; 2189 return 0;
2203} 2190}
@@ -2208,30 +2195,30 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2208 u16 *c; 2195 u16 *c;
2209 int ret = 0; 2196 int ret = 0;
2210 2197
2211 if (DibAcquireLock(&state->demod_lock) < 0) { 2198 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
2212 dprintk("could not get the lock"); 2199 dprintk("could not get the lock");
2213 return -EINTR; 2200 return -EINTR;
2214 } 2201 }
2215 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2202 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
2216 dprintk("could not get the lock"); 2203 dprintk("could not get the lock");
2217 ret = -EINTR; 2204 ret = -EINTR;
2218 goto error; 2205 goto error;
2219 } 2206 }
2220 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2207 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2221 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2208 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2222 ret = -EIO; 2209 ret = -EIO;
2223 goto error; 2210 goto error;
2224 } 2211 }
2225 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, 2212 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
2226 state->i2c_read_buffer, 16 * 2); 2213 state->i2c_read_buffer, 16 * 2);
2227 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2214 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2228 2215
2229 c = (u16 *)state->i2c_read_buffer; 2216 c = (u16 *)state->i2c_read_buffer;
2230 2217
2231 *ber = c[10] << 16 | c[11]; 2218 *ber = c[10] << 16 | c[11];
2232 2219
2233error: 2220error:
2234 DibReleaseLock(&state->demod_lock); 2221 mutex_unlock(&state->demod_lock);
2235 return ret; 2222 return ret;
2236} 2223}
2237 2224
@@ -2243,7 +2230,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2243 u16 val; 2230 u16 val;
2244 int ret = 0; 2231 int ret = 0;
2245 2232
2246 if (DibAcquireLock(&state->demod_lock) < 0) { 2233 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
2247 dprintk("could not get the lock"); 2234 dprintk("could not get the lock");
2248 return -EINTR; 2235 return -EINTR;
2249 } 2236 }
@@ -2256,18 +2243,18 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2256 *strength += val; 2243 *strength += val;
2257 } 2244 }
2258 2245
2259 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2246 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
2260 dprintk("could not get the lock"); 2247 dprintk("could not get the lock");
2261 ret = -EINTR; 2248 ret = -EINTR;
2262 goto error; 2249 goto error;
2263 } 2250 }
2264 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2251 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2265 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2252 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2266 ret = -EIO; 2253 ret = -EIO;
2267 goto error; 2254 goto error;
2268 } 2255 }
2269 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); 2256 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2270 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2257 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2271 2258
2272 val = 65535 - c[4]; 2259 val = 65535 - c[4];
2273 if (val > 65535 - *strength) 2260 if (val > 65535 - *strength)
@@ -2276,7 +2263,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2276 *strength += val; 2263 *strength += val;
2277 2264
2278error: 2265error:
2279 DibReleaseLock(&state->demod_lock); 2266 mutex_unlock(&state->demod_lock);
2280 return ret; 2267 return ret;
2281} 2268}
2282 2269
@@ -2287,16 +2274,16 @@ static u32 dib9000_get_snr(struct dvb_frontend *fe)
2287 u32 n, s, exp; 2274 u32 n, s, exp;
2288 u16 val; 2275 u16 val;
2289 2276
2290 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2277 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
2291 dprintk("could not get the lock"); 2278 dprintk("could not get the lock");
2292 return 0; 2279 return 0;
2293 } 2280 }
2294 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2281 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2295 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2282 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2296 return 0; 2283 return 0;
2297 } 2284 }
2298 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); 2285 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2299 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2286 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2300 2287
2301 val = c[7]; 2288 val = c[7];
2302 n = (val >> 4) & 0xff; 2289 n = (val >> 4) & 0xff;
@@ -2326,7 +2313,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2326 u8 index_frontend; 2313 u8 index_frontend;
2327 u32 snr_master; 2314 u32 snr_master;
2328 2315
2329 if (DibAcquireLock(&state->demod_lock) < 0) { 2316 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
2330 dprintk("could not get the lock"); 2317 dprintk("could not get the lock");
2331 return -EINTR; 2318 return -EINTR;
2332 } 2319 }
@@ -2340,7 +2327,7 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2340 } else 2327 } else
2341 *snr = 0; 2328 *snr = 0;
2342 2329
2343 DibReleaseLock(&state->demod_lock); 2330 mutex_unlock(&state->demod_lock);
2344 2331
2345 return 0; 2332 return 0;
2346} 2333}
@@ -2351,27 +2338,27 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2351 u16 *c = (u16 *)state->i2c_read_buffer; 2338 u16 *c = (u16 *)state->i2c_read_buffer;
2352 int ret = 0; 2339 int ret = 0;
2353 2340
2354 if (DibAcquireLock(&state->demod_lock) < 0) { 2341 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
2355 dprintk("could not get the lock"); 2342 dprintk("could not get the lock");
2356 return -EINTR; 2343 return -EINTR;
2357 } 2344 }
2358 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2345 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
2359 dprintk("could not get the lock"); 2346 dprintk("could not get the lock");
2360 ret = -EINTR; 2347 ret = -EINTR;
2361 goto error; 2348 goto error;
2362 } 2349 }
2363 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2350 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2364 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2351 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2365 ret = -EIO; 2352 ret = -EIO;
2366 goto error; 2353 goto error;
2367 } 2354 }
2368 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); 2355 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2369 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2356 mutex_unlock(&state->platform.risc.mem_mbx_lock);
2370 2357
2371 *unc = c[12]; 2358 *unc = c[12];
2372 2359
2373error: 2360error:
2374 DibReleaseLock(&state->demod_lock); 2361 mutex_unlock(&state->demod_lock);
2375 return ret; 2362 return ret;
2376} 2363}
2377 2364
@@ -2514,11 +2501,11 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c
2514 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES; 2501 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
2515 st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS; 2502 st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
2516 2503
2517 DibInitLock(&st->platform.risc.mbx_if_lock); 2504 mutex_init(&st->platform.risc.mbx_if_lock);
2518 DibInitLock(&st->platform.risc.mbx_lock); 2505 mutex_init(&st->platform.risc.mbx_lock);
2519 DibInitLock(&st->platform.risc.mem_lock); 2506 mutex_init(&st->platform.risc.mem_lock);
2520 DibInitLock(&st->platform.risc.mem_mbx_lock); 2507 mutex_init(&st->platform.risc.mem_mbx_lock);
2521 DibInitLock(&st->demod_lock); 2508 mutex_init(&st->demod_lock);
2522 st->get_frontend_internal = 0; 2509 st->get_frontend_internal = 0;
2523 2510
2524 st->pid_ctrl_index = -2; 2511 st->pid_ctrl_index = -2;
diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb/frontends/drxd.h
index 34398738f9bc..216c8c3702f8 100644
--- a/drivers/media/dvb/frontends/drxd.h
+++ b/drivers/media/dvb/frontends/drxd.h
@@ -51,9 +51,23 @@ struct drxd_config {
51 s16(*osc_deviation) (void *priv, s16 dev, int flag); 51 s16(*osc_deviation) (void *priv, s16 dev, int flag);
52}; 52};
53 53
54#if defined(CONFIG_DVB_DRXD) || \
55 (defined(CONFIG_DVB_DRXD_MODULE) && defined(MODULE))
54extern 56extern
55struct dvb_frontend *drxd_attach(const struct drxd_config *config, 57struct dvb_frontend *drxd_attach(const struct drxd_config *config,
56 void *priv, struct i2c_adapter *i2c, 58 void *priv, struct i2c_adapter *i2c,
57 struct device *dev); 59 struct device *dev);
60#else
61static inline
62struct dvb_frontend *drxd_attach(const struct drxd_config *config,
63 void *priv, struct i2c_adapter *i2c,
64 struct device *dev)
65{
66 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
67 __func__);
68 return NULL;
69}
70#endif
71
58extern int drxd_config_i2c(struct dvb_frontend *, int); 72extern int drxd_config_i2c(struct dvb_frontend *, int);
59#endif 73#endif
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index a414b1f2b6a5..60b868faeacf 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -1380,20 +1380,20 @@ static int DownloadMicrocode(struct drxk_state *state,
1380 const u8 pMCImage[], u32 Length) 1380 const u8 pMCImage[], u32 Length)
1381{ 1381{
1382 const u8 *pSrc = pMCImage; 1382 const u8 *pSrc = pMCImage;
1383 u16 Flags;
1384 u16 Drain;
1385 u32 Address; 1383 u32 Address;
1386 u16 nBlocks; 1384 u16 nBlocks;
1387 u16 BlockSize; 1385 u16 BlockSize;
1388 u16 BlockCRC;
1389 u32 offset = 0; 1386 u32 offset = 0;
1390 u32 i; 1387 u32 i;
1391 int status = 0; 1388 int status = 0;
1392 1389
1393 dprintk(1, "\n"); 1390 dprintk(1, "\n");
1394 1391
1395 /* down the drain (we don care about MAGIC_WORD) */ 1392 /* down the drain (we don't care about MAGIC_WORD) */
1393#if 0
1394 /* For future reference */
1396 Drain = (pSrc[0] << 8) | pSrc[1]; 1395 Drain = (pSrc[0] << 8) | pSrc[1];
1396#endif
1397 pSrc += sizeof(u16); 1397 pSrc += sizeof(u16);
1398 offset += sizeof(u16); 1398 offset += sizeof(u16);
1399 nBlocks = (pSrc[0] << 8) | pSrc[1]; 1399 nBlocks = (pSrc[0] << 8) | pSrc[1];
@@ -1410,11 +1410,17 @@ static int DownloadMicrocode(struct drxk_state *state,
1410 pSrc += sizeof(u16); 1410 pSrc += sizeof(u16);
1411 offset += sizeof(u16); 1411 offset += sizeof(u16);
1412 1412
1413#if 0
1414 /* For future reference */
1413 Flags = (pSrc[0] << 8) | pSrc[1]; 1415 Flags = (pSrc[0] << 8) | pSrc[1];
1416#endif
1414 pSrc += sizeof(u16); 1417 pSrc += sizeof(u16);
1415 offset += sizeof(u16); 1418 offset += sizeof(u16);
1416 1419
1420#if 0
1421 /* For future reference */
1417 BlockCRC = (pSrc[0] << 8) | pSrc[1]; 1422 BlockCRC = (pSrc[0] << 8) | pSrc[1];
1423#endif
1418 pSrc += sizeof(u16); 1424 pSrc += sizeof(u16);
1419 offset += sizeof(u16); 1425 offset += sizeof(u16);
1420 1426
@@ -5829,7 +5835,7 @@ static int WriteGPIO(struct drxk_state *state)
5829 } 5835 }
5830 if (state->UIO_mask & 0x0002) { /* UIO-2 */ 5836 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5831 /* write to io pad configuration register - output mode */ 5837 /* write to io pad configuration register - output mode */
5832 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); 5838 status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
5833 if (status < 0) 5839 if (status < 0)
5834 goto error; 5840 goto error;
5835 5841
@@ -5848,7 +5854,7 @@ static int WriteGPIO(struct drxk_state *state)
5848 } 5854 }
5849 if (state->UIO_mask & 0x0004) { /* UIO-3 */ 5855 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5850 /* write to io pad configuration register - output mode */ 5856 /* write to io pad configuration register - output mode */
5851 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg); 5857 status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
5852 if (status < 0) 5858 if (status < 0)
5853 goto error; 5859 goto error;
5854 5860
diff --git a/drivers/media/dvb/frontends/drxk_map.h b/drivers/media/dvb/frontends/drxk_map.h
index 9b11a8328869..23e16c12f234 100644
--- a/drivers/media/dvb/frontends/drxk_map.h
+++ b/drivers/media/dvb/frontends/drxk_map.h
@@ -432,6 +432,7 @@
432#define SIO_PDR_UIO_OUT_LO__A 0x7F0016 432#define SIO_PDR_UIO_OUT_LO__A 0x7F0016
433#define SIO_PDR_OHW_CFG__A 0x7F001F 433#define SIO_PDR_OHW_CFG__A 0x7F001F
434#define SIO_PDR_OHW_CFG_FREF_SEL__M 0x3 434#define SIO_PDR_OHW_CFG_FREF_SEL__M 0x3
435#define SIO_PDR_GPIO_CFG__A 0x7F0021
435#define SIO_PDR_MSTRT_CFG__A 0x7F0025 436#define SIO_PDR_MSTRT_CFG__A 0x7F0025
436#define SIO_PDR_MERR_CFG__A 0x7F0026 437#define SIO_PDR_MERR_CFG__A 0x7F0026
437#define SIO_PDR_MCLK_CFG__A 0x7F0028 438#define SIO_PDR_MCLK_CFG__A 0x7F0028
@@ -446,4 +447,5 @@
446#define SIO_PDR_MD5_CFG__A 0x7F0030 447#define SIO_PDR_MD5_CFG__A 0x7F0030
447#define SIO_PDR_MD6_CFG__A 0x7F0031 448#define SIO_PDR_MD6_CFG__A 0x7F0031
448#define SIO_PDR_MD7_CFG__A 0x7F0032 449#define SIO_PDR_MD7_CFG__A 0x7F0032
450#define SIO_PDR_SMA_RX_CFG__A 0x7F0037
449#define SIO_PDR_SMA_TX_CFG__A 0x7F0038 451#define SIO_PDR_SMA_TX_CFG__A 0x7F0038
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
index af65d013db11..4c8ac2657c4a 100644
--- a/drivers/media/dvb/frontends/ds3000.c
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -1114,7 +1114,10 @@ static int ds3000_set_frontend(struct dvb_frontend *fe)
1114 ds3000_writereg(state, 1114 ds3000_writereg(state,
1115 ds3000_dvbs2_init_tab[i], 1115 ds3000_dvbs2_init_tab[i],
1116 ds3000_dvbs2_init_tab[i + 1]); 1116 ds3000_dvbs2_init_tab[i + 1]);
1117 ds3000_writereg(state, 0xfe, 0x98); 1117 if (c->symbol_rate >= 30000000)
1118 ds3000_writereg(state, 0xfe, 0x54);
1119 else
1120 ds3000_writereg(state, 0xfe, 0x98);
1118 break; 1121 break;
1119 default: 1122 default:
1120 return 1; 1123 return 1;
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c
index 84df03c29179..708cbf197913 100644
--- a/drivers/media/dvb/frontends/it913x-fe.c
+++ b/drivers/media/dvb/frontends/it913x-fe.c
@@ -633,10 +633,9 @@ static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
633static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber) 633static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
634{ 634{
635 struct it913x_fe_state *state = fe->demodulator_priv; 635 struct it913x_fe_state *state = fe->demodulator_priv;
636 int ret;
637 u8 reg[5]; 636 u8 reg[5];
638 /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */ 637 /* Read Aborted Packets and Pre-Viterbi error rate 5 bytes */
639 ret = it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg)); 638 it913x_read_reg(state, RSD_ABORT_PKT_LSB, reg, sizeof(reg));
640 state->ucblocks += (u32)(reg[1] << 8) | reg[0]; 639 state->ucblocks += (u32)(reg[1] << 8) | reg[0];
641 *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2]; 640 *ber = (u32)(reg[4] << 16) | (reg[3] << 8) | reg[2];
642 return 0; 641 return 0;
@@ -658,10 +657,9 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe)
658{ 657{
659 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 658 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
660 struct it913x_fe_state *state = fe->demodulator_priv; 659 struct it913x_fe_state *state = fe->demodulator_priv;
661 int ret;
662 u8 reg[8]; 660 u8 reg[8];
663 661
664 ret = it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg)); 662 it913x_read_reg(state, REG_TPSD_TX_MODE, reg, sizeof(reg));
665 663
666 if (reg[3] < 3) 664 if (reg[3] < 3)
667 p->modulation = fe_con[reg[3]]; 665 p->modulation = fe_con[reg[3]];
@@ -691,25 +689,25 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe)
691{ 689{
692 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 690 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
693 struct it913x_fe_state *state = fe->demodulator_priv; 691 struct it913x_fe_state *state = fe->demodulator_priv;
694 int ret, i; 692 int i;
695 u8 empty_ch, last_ch; 693 u8 empty_ch, last_ch;
696 694
697 state->it913x_status = 0; 695 state->it913x_status = 0;
698 696
699 /* Set bw*/ 697 /* Set bw*/
700 ret = it913x_fe_select_bw(state, p->bandwidth_hz, 698 it913x_fe_select_bw(state, p->bandwidth_hz,
701 state->adcFrequency); 699 state->adcFrequency);
702 700
703 /* Training Mode Off */ 701 /* Training Mode Off */
704 ret = it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0); 702 it913x_write_reg(state, PRO_LINK, TRAINING_MODE, 0x0);
705 703
706 /* Clear Empty Channel */ 704 /* Clear Empty Channel */
707 ret = it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0); 705 it913x_write_reg(state, PRO_DMOD, EMPTY_CHANNEL_STATUS, 0x0);
708 706
709 /* Clear bits */ 707 /* Clear bits */
710 ret = it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0); 708 it913x_write_reg(state, PRO_DMOD, MP2IF_SYNC_LK, 0x0);
711 /* LED on */ 709 /* LED on */
712 ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1); 710 it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x1);
713 /* Select Band*/ 711 /* Select Band*/
714 if ((p->frequency >= 51000000) && (p->frequency <= 230000000)) 712 if ((p->frequency >= 51000000) && (p->frequency <= 230000000))
715 i = 0; 713 i = 0;
@@ -720,7 +718,7 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe)
720 else 718 else
721 return -EOPNOTSUPP; 719 return -EOPNOTSUPP;
722 720
723 ret = it913x_write_reg(state, PRO_DMOD, FREE_BAND, i); 721 it913x_write_reg(state, PRO_DMOD, FREE_BAND, i);
724 722
725 deb_info("Frontend Set Tuner Type %02x", state->tuner_type); 723 deb_info("Frontend Set Tuner Type %02x", state->tuner_type);
726 switch (state->tuner_type) { 724 switch (state->tuner_type) {
@@ -730,7 +728,7 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe)
730 case IT9135_60: 728 case IT9135_60:
731 case IT9135_61: 729 case IT9135_61:
732 case IT9135_62: 730 case IT9135_62:
733 ret = it9137_set_tuner(state, 731 it9137_set_tuner(state,
734 p->bandwidth_hz, p->frequency); 732 p->bandwidth_hz, p->frequency);
735 break; 733 break;
736 default: 734 default:
@@ -742,9 +740,9 @@ static int it913x_fe_set_frontend(struct dvb_frontend *fe)
742 break; 740 break;
743 } 741 }
744 /* LED off */ 742 /* LED off */
745 ret = it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0); 743 it913x_write_reg(state, PRO_LINK, GPIOH3_O, 0x0);
746 /* Trigger ofsm */ 744 /* Trigger ofsm */
747 ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0); 745 it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x0);
748 last_ch = 2; 746 last_ch = 2;
749 for (i = 0; i < 40; ++i) { 747 for (i = 0; i < 40; ++i) {
750 empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS); 748 empty_ch = it913x_read_reg_u8(state, EMPTY_CHANNEL_STATUS);
diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb/frontends/lg2160.c
new file mode 100644
index 000000000000..a3ab1a5b6597
--- /dev/null
+++ b/drivers/media/dvb/frontends/lg2160.c
@@ -0,0 +1,1468 @@
1/*
2 * Support for LG2160 - ATSC/MH
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
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#include <linux/jiffies.h>
23#include <linux/dvb/frontend.h>
24#include "lg2160.h"
25
26static int debug;
27module_param(debug, int, 0644);
28MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
29
30#define DBG_INFO 1
31#define DBG_REG 2
32
33#define lg_printk(kern, fmt, arg...) \
34 printk(kern "%s: " fmt, __func__, ##arg)
35
36#define lg_info(fmt, arg...) printk(KERN_INFO "lg2160: " fmt, ##arg)
37#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
38#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
39#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
40 lg_printk(KERN_DEBUG, fmt, ##arg)
41#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
42 lg_printk(KERN_DEBUG, fmt, ##arg)
43
44#define lg_fail(ret) \
45({ \
46 int __ret; \
47 __ret = (ret < 0); \
48 if (__ret) \
49 lg_err("error %d on line %d\n", ret, __LINE__); \
50 __ret; \
51})
52
53struct lg216x_state {
54 struct i2c_adapter *i2c_adap;
55 const struct lg2160_config *cfg;
56
57 struct dvb_frontend frontend;
58
59 u32 current_frequency;
60 u8 parade_id;
61 u8 fic_ver;
62 unsigned int last_reset;
63};
64
65/* ------------------------------------------------------------------------ */
66
67static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val)
68{
69 int ret;
70 u8 buf[] = { reg >> 8, reg & 0xff, val };
71 struct i2c_msg msg = {
72 .addr = state->cfg->i2c_addr, .flags = 0,
73 .buf = buf, .len = 3,
74 };
75
76 lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
77
78 ret = i2c_transfer(state->i2c_adap, &msg, 1);
79
80 if (ret != 1) {
81 lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
82 msg.buf[0], msg.buf[1], msg.buf[2], ret);
83 if (ret < 0)
84 return ret;
85 else
86 return -EREMOTEIO;
87 }
88 return 0;
89}
90
91static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val)
92{
93 int ret;
94 u8 reg_buf[] = { reg >> 8, reg & 0xff };
95 struct i2c_msg msg[] = {
96 { .addr = state->cfg->i2c_addr,
97 .flags = 0, .buf = reg_buf, .len = 2 },
98 { .addr = state->cfg->i2c_addr,
99 .flags = I2C_M_RD, .buf = val, .len = 1 },
100 };
101
102 lg_reg("reg: 0x%04x\n", reg);
103
104 ret = i2c_transfer(state->i2c_adap, msg, 2);
105
106 if (ret != 2) {
107 lg_err("error (addr %02x reg %04x error (ret == %i)\n",
108 state->cfg->i2c_addr, reg, ret);
109 if (ret < 0)
110 return ret;
111 else
112 return -EREMOTEIO;
113 }
114 return 0;
115}
116
117struct lg216x_reg {
118 u16 reg;
119 u8 val;
120};
121
122static int lg216x_write_regs(struct lg216x_state *state,
123 struct lg216x_reg *regs, int len)
124{
125 int i, ret;
126
127 lg_reg("writing %d registers...\n", len);
128
129 for (i = 0; i < len - 1; i++) {
130 ret = lg216x_write_reg(state, regs[i].reg, regs[i].val);
131 if (lg_fail(ret))
132 return ret;
133 }
134 return 0;
135}
136
137static int lg216x_set_reg_bit(struct lg216x_state *state,
138 u16 reg, int bit, int onoff)
139{
140 u8 val;
141 int ret;
142
143 lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
144
145 ret = lg216x_read_reg(state, reg, &val);
146 if (lg_fail(ret))
147 goto fail;
148
149 val &= ~(1 << bit);
150 val |= (onoff & 1) << bit;
151
152 ret = lg216x_write_reg(state, reg, val);
153 lg_fail(ret);
154fail:
155 return ret;
156}
157
158/* ------------------------------------------------------------------------ */
159
160static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
161{
162 struct lg216x_state *state = fe->demodulator_priv;
163 int ret;
164
165 if (state->cfg->deny_i2c_rptr)
166 return 0;
167
168 lg_dbg("(%d)\n", enable);
169
170 ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1);
171
172 msleep(1);
173
174 return ret;
175}
176
177static int lg216x_soft_reset(struct lg216x_state *state)
178{
179 int ret;
180
181 lg_dbg("\n");
182
183 ret = lg216x_write_reg(state, 0x0002, 0x00);
184 if (lg_fail(ret))
185 goto fail;
186
187 msleep(20);
188 ret = lg216x_write_reg(state, 0x0002, 0x01);
189 if (lg_fail(ret))
190 goto fail;
191
192 state->last_reset = jiffies_to_msecs(jiffies);
193fail:
194 return ret;
195}
196
197static int lg216x_initialize(struct lg216x_state *state)
198{
199 int ret;
200
201 static struct lg216x_reg lg2160_init[] = {
202#if 0
203 { .reg = 0x0015, .val = 0xe6 },
204#else
205 { .reg = 0x0015, .val = 0xf7 },
206 { .reg = 0x001b, .val = 0x52 },
207 { .reg = 0x0208, .val = 0x00 },
208 { .reg = 0x0209, .val = 0x82 },
209 { .reg = 0x0210, .val = 0xf9 },
210 { .reg = 0x020a, .val = 0x00 },
211 { .reg = 0x020b, .val = 0x82 },
212 { .reg = 0x020d, .val = 0x28 },
213 { .reg = 0x020f, .val = 0x14 },
214#endif
215 };
216
217 static struct lg216x_reg lg2161_init[] = {
218 { .reg = 0x0000, .val = 0x41 },
219 { .reg = 0x0001, .val = 0xfb },
220 { .reg = 0x0216, .val = 0x00 },
221 { .reg = 0x0219, .val = 0x00 },
222 { .reg = 0x021b, .val = 0x55 },
223 { .reg = 0x0606, .val = 0x0a },
224 };
225
226 switch (state->cfg->lg_chip) {
227 case LG2160:
228 ret = lg216x_write_regs(state,
229 lg2160_init, ARRAY_SIZE(lg2160_init));
230 break;
231 case LG2161:
232 ret = lg216x_write_regs(state,
233 lg2161_init, ARRAY_SIZE(lg2161_init));
234 break;
235 default:
236 ret = -EINVAL;
237 break;
238 }
239 if (lg_fail(ret))
240 goto fail;
241
242 ret = lg216x_soft_reset(state);
243 lg_fail(ret);
244fail:
245 return ret;
246}
247
248/* ------------------------------------------------------------------------ */
249
250static int lg216x_set_if(struct lg216x_state *state)
251{
252 u8 val;
253 int ret;
254
255 lg_dbg("%d KHz\n", state->cfg->if_khz);
256
257 ret = lg216x_read_reg(state, 0x0132, &val);
258 if (lg_fail(ret))
259 goto fail;
260
261 val &= 0xfb;
262 val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00;
263
264 ret = lg216x_write_reg(state, 0x0132, val);
265 lg_fail(ret);
266
267 /* if NOT zero IF, 6 MHz is the default */
268fail:
269 return ret;
270}
271
272/* ------------------------------------------------------------------------ */
273
274static int lg2160_agc_fix(struct lg216x_state *state,
275 int if_agc_fix, int rf_agc_fix)
276{
277 u8 val;
278 int ret;
279
280 ret = lg216x_read_reg(state, 0x0100, &val);
281 if (lg_fail(ret))
282 goto fail;
283
284 val &= 0xf3;
285 val |= (if_agc_fix) ? 0x08 : 0x00;
286 val |= (rf_agc_fix) ? 0x04 : 0x00;
287
288 ret = lg216x_write_reg(state, 0x0100, val);
289 lg_fail(ret);
290fail:
291 return ret;
292}
293
294#if 0
295static int lg2160_agc_freeze(struct lg216x_state *state,
296 int if_agc_freeze, int rf_agc_freeze)
297{
298 u8 val;
299 int ret;
300
301 ret = lg216x_read_reg(state, 0x0100, &val);
302 if (lg_fail(ret))
303 goto fail;
304
305 val &= 0xcf;
306 val |= (if_agc_freeze) ? 0x20 : 0x00;
307 val |= (rf_agc_freeze) ? 0x10 : 0x00;
308
309 ret = lg216x_write_reg(state, 0x0100, val);
310 lg_fail(ret);
311fail:
312 return ret;
313}
314#endif
315
316static int lg2160_agc_polarity(struct lg216x_state *state,
317 int if_agc_polarity, int rf_agc_polarity)
318{
319 u8 val;
320 int ret;
321
322 ret = lg216x_read_reg(state, 0x0100, &val);
323 if (lg_fail(ret))
324 goto fail;
325
326 val &= 0xfc;
327 val |= (if_agc_polarity) ? 0x02 : 0x00;
328 val |= (rf_agc_polarity) ? 0x01 : 0x00;
329
330 ret = lg216x_write_reg(state, 0x0100, val);
331 lg_fail(ret);
332fail:
333 return ret;
334}
335
336static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state,
337 int polarity)
338{
339 u8 val;
340 int ret;
341
342 ret = lg216x_read_reg(state, 0x0008, &val);
343 if (lg_fail(ret))
344 goto fail;
345
346 val &= 0xfe;
347 val |= (polarity) ? 0x01 : 0x00;
348
349 ret = lg216x_write_reg(state, 0x0008, val);
350 lg_fail(ret);
351fail:
352 return ret;
353}
354
355static int lg2160_spectrum_polarity(struct lg216x_state *state,
356 int inverted)
357{
358 u8 val;
359 int ret;
360
361 ret = lg216x_read_reg(state, 0x0132, &val);
362 if (lg_fail(ret))
363 goto fail;
364
365 val &= 0xfd;
366 val |= (inverted) ? 0x02 : 0x00;
367
368 ret = lg216x_write_reg(state, 0x0132, val);
369 lg_fail(ret);
370fail:
371 return lg216x_soft_reset(state);
372}
373
374static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff)
375{
376 u8 val;
377 int ret;
378
379 ret = lg216x_read_reg(state, 0x0007, &val);
380 if (lg_fail(ret))
381 goto fail;
382
383 val &= 0xbf;
384 val |= (onoff) ? 0x40 : 0x00;
385
386 ret = lg216x_write_reg(state, 0x0007, val);
387 lg_fail(ret);
388fail:
389 return ret;
390}
391
392static int lg216x_set_parade(struct lg216x_state *state, int id)
393{
394 int ret;
395
396 ret = lg216x_write_reg(state, 0x013e, id & 0x7f);
397 if (lg_fail(ret))
398 goto fail;
399
400 state->parade_id = id & 0x7f;
401fail:
402 return ret;
403}
404
405static int lg216x_set_ensemble(struct lg216x_state *state, int id)
406{
407 int ret;
408 u16 reg;
409 u8 val;
410
411 switch (state->cfg->lg_chip) {
412 case LG2160:
413 reg = 0x0400;
414 break;
415 case LG2161:
416 default:
417 reg = 0x0500;
418 break;
419 }
420
421 ret = lg216x_read_reg(state, reg, &val);
422 if (lg_fail(ret))
423 goto fail;
424
425 val &= 0xfe;
426 val |= (id) ? 0x01 : 0x00;
427
428 ret = lg216x_write_reg(state, reg, val);
429 lg_fail(ret);
430fail:
431 return ret;
432}
433
434static int lg2160_set_spi_clock(struct lg216x_state *state)
435{
436 u8 val;
437 int ret;
438
439 ret = lg216x_read_reg(state, 0x0014, &val);
440 if (lg_fail(ret))
441 goto fail;
442
443 val &= 0xf3;
444 val |= (state->cfg->spi_clock << 2);
445
446 ret = lg216x_write_reg(state, 0x0014, val);
447 lg_fail(ret);
448fail:
449 return ret;
450}
451
452static int lg2161_set_output_interface(struct lg216x_state *state)
453{
454 u8 val;
455 int ret;
456
457 ret = lg216x_read_reg(state, 0x0014, &val);
458 if (lg_fail(ret))
459 goto fail;
460
461 val &= ~0x07;
462 val |= state->cfg->output_if; /* FIXME: needs sanity check */
463
464 ret = lg216x_write_reg(state, 0x0014, val);
465 lg_fail(ret);
466fail:
467 return ret;
468}
469
470static int lg216x_enable_fic(struct lg216x_state *state, int onoff)
471{
472 int ret;
473
474 ret = lg216x_write_reg(state, 0x0017, 0x23);
475 if (lg_fail(ret))
476 goto fail;
477
478 ret = lg216x_write_reg(state, 0x0016, 0xfc);
479 if (lg_fail(ret))
480 goto fail;
481
482 switch (state->cfg->lg_chip) {
483 case LG2160:
484 ret = lg216x_write_reg(state, 0x0016,
485 0xfc | ((onoff) ? 0x02 : 0x00));
486 break;
487 case LG2161:
488 ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00);
489 break;
490 }
491 if (lg_fail(ret))
492 goto fail;
493
494 ret = lg216x_initialize(state);
495 if (lg_fail(ret))
496 goto fail;
497
498 if (onoff) {
499 ret = lg216x_write_reg(state, 0x0017, 0x03);
500 lg_fail(ret);
501 }
502fail:
503 return ret;
504}
505
506/* ------------------------------------------------------------------------ */
507
508static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver)
509{
510 u8 val;
511 int ret;
512
513 *ficver = 0xff; /* invalid value */
514
515 ret = lg216x_read_reg(state, 0x0128, &val);
516 if (lg_fail(ret))
517 goto fail;
518
519 *ficver = (val >> 3) & 0x1f;
520fail:
521 return ret;
522}
523
524#if 0
525static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id)
526{
527 u8 val;
528 int ret;
529
530 *id = 0xff; /* invalid value */
531
532 ret = lg216x_read_reg(state, 0x0123, &val);
533 if (lg_fail(ret))
534 goto fail;
535
536 *id = val & 0x7f;
537fail:
538 return ret;
539}
540#endif
541
542static int lg216x_get_nog(struct lg216x_state *state, u8 *nog)
543{
544 u8 val;
545 int ret;
546
547 *nog = 0xff; /* invalid value */
548
549 ret = lg216x_read_reg(state, 0x0124, &val);
550 if (lg_fail(ret))
551 goto fail;
552
553 *nog = ((val >> 4) & 0x07) + 1;
554fail:
555 return ret;
556}
557
558static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog)
559{
560 u8 val;
561 int ret;
562
563 *tnog = 0xff; /* invalid value */
564
565 ret = lg216x_read_reg(state, 0x0125, &val);
566 if (lg_fail(ret))
567 goto fail;
568
569 *tnog = val & 0x1f;
570fail:
571 return ret;
572}
573
574static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn)
575{
576 u8 val;
577 int ret;
578
579 *sgn = 0xff; /* invalid value */
580
581 ret = lg216x_read_reg(state, 0x0124, &val);
582 if (lg_fail(ret))
583 goto fail;
584
585 *sgn = val & 0x0f;
586fail:
587 return ret;
588}
589
590static int lg216x_get_prc(struct lg216x_state *state, u8 *prc)
591{
592 u8 val;
593 int ret;
594
595 *prc = 0xff; /* invalid value */
596
597 ret = lg216x_read_reg(state, 0x0125, &val);
598 if (lg_fail(ret))
599 goto fail;
600
601 *prc = ((val >> 5) & 0x07) + 1;
602fail:
603 return ret;
604}
605
606/* ------------------------------------------------------------------------ */
607
608static int lg216x_get_rs_frame_mode(struct lg216x_state *state,
609 enum atscmh_rs_frame_mode *rs_framemode)
610{
611 u8 val;
612 int ret;
613
614 switch (state->cfg->lg_chip) {
615 case LG2160:
616 ret = lg216x_read_reg(state, 0x0410, &val);
617 break;
618 case LG2161:
619 ret = lg216x_read_reg(state, 0x0513, &val);
620 break;
621 default:
622 ret = -EINVAL;
623 }
624 if (lg_fail(ret))
625 goto fail;
626
627 switch ((val >> 4) & 0x03) {
628#if 1
629 default:
630#endif
631 case 0x00:
632 *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY;
633 break;
634 case 0x01:
635 *rs_framemode = ATSCMH_RSFRAME_PRI_SEC;
636 break;
637#if 0
638 default:
639 *rs_framemode = ATSCMH_RSFRAME_RES;
640 break;
641#endif
642 }
643fail:
644 return ret;
645}
646
647static
648int lg216x_get_rs_frame_ensemble(struct lg216x_state *state,
649 enum atscmh_rs_frame_ensemble *rs_frame_ens)
650{
651 u8 val;
652 int ret;
653
654 switch (state->cfg->lg_chip) {
655 case LG2160:
656 ret = lg216x_read_reg(state, 0x0400, &val);
657 break;
658 case LG2161:
659 ret = lg216x_read_reg(state, 0x0500, &val);
660 break;
661 default:
662 ret = -EINVAL;
663 }
664 if (lg_fail(ret))
665 goto fail;
666
667 val &= 0x01;
668 *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val;
669fail:
670 return ret;
671}
672
673static int lg216x_get_rs_code_mode(struct lg216x_state *state,
674 enum atscmh_rs_code_mode *rs_code_pri,
675 enum atscmh_rs_code_mode *rs_code_sec)
676{
677 u8 val;
678 int ret;
679
680 switch (state->cfg->lg_chip) {
681 case LG2160:
682 ret = lg216x_read_reg(state, 0x0410, &val);
683 break;
684 case LG2161:
685 ret = lg216x_read_reg(state, 0x0513, &val);
686 break;
687 default:
688 ret = -EINVAL;
689 }
690 if (lg_fail(ret))
691 goto fail;
692
693 *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03);
694 *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03);
695fail:
696 return ret;
697}
698
699static int lg216x_get_sccc_block_mode(struct lg216x_state *state,
700 enum atscmh_sccc_block_mode *sccc_block)
701{
702 u8 val;
703 int ret;
704
705 switch (state->cfg->lg_chip) {
706 case LG2160:
707 ret = lg216x_read_reg(state, 0x0315, &val);
708 break;
709 case LG2161:
710 ret = lg216x_read_reg(state, 0x0511, &val);
711 break;
712 default:
713 ret = -EINVAL;
714 }
715 if (lg_fail(ret))
716 goto fail;
717
718 switch (val & 0x03) {
719 case 0x00:
720 *sccc_block = ATSCMH_SCCC_BLK_SEP;
721 break;
722 case 0x01:
723 *sccc_block = ATSCMH_SCCC_BLK_COMB;
724 break;
725 default:
726 *sccc_block = ATSCMH_SCCC_BLK_RES;
727 break;
728 }
729fail:
730 return ret;
731}
732
733static int lg216x_get_sccc_code_mode(struct lg216x_state *state,
734 enum atscmh_sccc_code_mode *mode_a,
735 enum atscmh_sccc_code_mode *mode_b,
736 enum atscmh_sccc_code_mode *mode_c,
737 enum atscmh_sccc_code_mode *mode_d)
738{
739 u8 val;
740 int ret;
741
742 switch (state->cfg->lg_chip) {
743 case LG2160:
744 ret = lg216x_read_reg(state, 0x0316, &val);
745 break;
746 case LG2161:
747 ret = lg216x_read_reg(state, 0x0512, &val);
748 break;
749 default:
750 ret = -EINVAL;
751 }
752 if (lg_fail(ret))
753 goto fail;
754
755 switch ((val >> 6) & 0x03) {
756 case 0x00:
757 *mode_a = ATSCMH_SCCC_CODE_HLF;
758 break;
759 case 0x01:
760 *mode_a = ATSCMH_SCCC_CODE_QTR;
761 break;
762 default:
763 *mode_a = ATSCMH_SCCC_CODE_RES;
764 break;
765 }
766
767 switch ((val >> 4) & 0x03) {
768 case 0x00:
769 *mode_b = ATSCMH_SCCC_CODE_HLF;
770 break;
771 case 0x01:
772 *mode_b = ATSCMH_SCCC_CODE_QTR;
773 break;
774 default:
775 *mode_b = ATSCMH_SCCC_CODE_RES;
776 break;
777 }
778
779 switch ((val >> 2) & 0x03) {
780 case 0x00:
781 *mode_c = ATSCMH_SCCC_CODE_HLF;
782 break;
783 case 0x01:
784 *mode_c = ATSCMH_SCCC_CODE_QTR;
785 break;
786 default:
787 *mode_c = ATSCMH_SCCC_CODE_RES;
788 break;
789 }
790
791 switch (val & 0x03) {
792 case 0x00:
793 *mode_d = ATSCMH_SCCC_CODE_HLF;
794 break;
795 case 0x01:
796 *mode_d = ATSCMH_SCCC_CODE_QTR;
797 break;
798 default:
799 *mode_d = ATSCMH_SCCC_CODE_RES;
800 break;
801 }
802fail:
803 return ret;
804}
805
806/* ------------------------------------------------------------------------ */
807
808#if 0
809static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err)
810{
811 u8 fic_err;
812 int ret;
813
814 *err = 0;
815
816 switch (state->cfg->lg_chip) {
817 case LG2160:
818 ret = lg216x_read_reg(state, 0x0012, &fic_err);
819 break;
820 case LG2161:
821 ret = lg216x_read_reg(state, 0x001e, &fic_err);
822 break;
823 }
824 if (lg_fail(ret))
825 goto fail;
826
827 *err = fic_err;
828fail:
829 return ret;
830}
831
832static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err)
833{
834 u8 crc_err1, crc_err2;
835 int ret;
836
837 *err = 0;
838
839 ret = lg216x_read_reg(state, 0x0411, &crc_err1);
840 if (lg_fail(ret))
841 goto fail;
842
843 ret = lg216x_read_reg(state, 0x0412, &crc_err2);
844 if (lg_fail(ret))
845 goto fail;
846
847 *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1);
848fail:
849 return ret;
850}
851
852static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err)
853{
854 u8 crc_err;
855 int ret;
856
857 *err = 0;
858
859 ret = lg216x_read_reg(state, 0x0612, &crc_err);
860 if (lg_fail(ret))
861 goto fail;
862
863 *err = (u16)crc_err;
864fail:
865 return ret;
866}
867
868static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err)
869{
870 int ret;
871 switch (state->cfg->lg_chip) {
872 case LG2160:
873 ret = lg2160_read_crc_err_count(state, err);
874 break;
875 case LG2161:
876 ret = lg2161_read_crc_err_count(state, err);
877 break;
878 default:
879 ret = -EINVAL;
880 break;
881 }
882 return ret;
883}
884
885static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err)
886{
887 u8 rs_err1, rs_err2;
888 int ret;
889
890 *err = 0;
891
892 ret = lg216x_read_reg(state, 0x0413, &rs_err1);
893 if (lg_fail(ret))
894 goto fail;
895
896 ret = lg216x_read_reg(state, 0x0414, &rs_err2);
897 if (lg_fail(ret))
898 goto fail;
899
900 *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1);
901fail:
902 return ret;
903}
904
905static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err)
906{
907 u8 rs_err1, rs_err2;
908 int ret;
909
910 *err = 0;
911
912 ret = lg216x_read_reg(state, 0x0613, &rs_err1);
913 if (lg_fail(ret))
914 goto fail;
915
916 ret = lg216x_read_reg(state, 0x0614, &rs_err2);
917 if (lg_fail(ret))
918 goto fail;
919
920 *err = (u16)((rs_err1 << 8) | rs_err2);
921fail:
922 return ret;
923}
924
925static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err)
926{
927 int ret;
928 switch (state->cfg->lg_chip) {
929 case LG2160:
930 ret = lg2160_read_rs_err_count(state, err);
931 break;
932 case LG2161:
933 ret = lg2161_read_rs_err_count(state, err);
934 break;
935 default:
936 ret = -EINVAL;
937 break;
938 }
939 return ret;
940}
941#endif
942
943/* ------------------------------------------------------------------------ */
944
945static int lg216x_get_frontend(struct dvb_frontend *fe)
946{
947 struct lg216x_state *state = fe->demodulator_priv;
948 int ret;
949
950 lg_dbg("\n");
951
952 fe->dtv_property_cache.modulation = VSB_8;
953 fe->dtv_property_cache.frequency = state->current_frequency;
954 fe->dtv_property_cache.delivery_system = SYS_ATSCMH;
955
956 ret = lg216x_get_fic_version(state,
957 &fe->dtv_property_cache.atscmh_fic_ver);
958 if (lg_fail(ret))
959 goto fail;
960 if (state->fic_ver != fe->dtv_property_cache.atscmh_fic_ver) {
961 state->fic_ver = fe->dtv_property_cache.atscmh_fic_ver;
962
963#if 0
964 ret = lg2160_get_parade_id(state,
965 &fe->dtv_property_cache.atscmh_parade_id);
966 if (lg_fail(ret))
967 goto fail;
968/* #else */
969 fe->dtv_property_cache.atscmh_parade_id = state->parade_id;
970#endif
971 ret = lg216x_get_nog(state,
972 &fe->dtv_property_cache.atscmh_nog);
973 if (lg_fail(ret))
974 goto fail;
975 ret = lg216x_get_tnog(state,
976 &fe->dtv_property_cache.atscmh_tnog);
977 if (lg_fail(ret))
978 goto fail;
979 ret = lg216x_get_sgn(state,
980 &fe->dtv_property_cache.atscmh_sgn);
981 if (lg_fail(ret))
982 goto fail;
983 ret = lg216x_get_prc(state,
984 &fe->dtv_property_cache.atscmh_prc);
985 if (lg_fail(ret))
986 goto fail;
987
988 ret = lg216x_get_rs_frame_mode(state,
989 (enum atscmh_rs_frame_mode *)
990 &fe->dtv_property_cache.atscmh_rs_frame_mode);
991 if (lg_fail(ret))
992 goto fail;
993 ret = lg216x_get_rs_frame_ensemble(state,
994 (enum atscmh_rs_frame_ensemble *)
995 &fe->dtv_property_cache.atscmh_rs_frame_ensemble);
996 if (lg_fail(ret))
997 goto fail;
998 ret = lg216x_get_rs_code_mode(state,
999 (enum atscmh_rs_code_mode *)
1000 &fe->dtv_property_cache.atscmh_rs_code_mode_pri,
1001 (enum atscmh_rs_code_mode *)
1002 &fe->dtv_property_cache.atscmh_rs_code_mode_sec);
1003 if (lg_fail(ret))
1004 goto fail;
1005 ret = lg216x_get_sccc_block_mode(state,
1006 (enum atscmh_sccc_block_mode *)
1007 &fe->dtv_property_cache.atscmh_sccc_block_mode);
1008 if (lg_fail(ret))
1009 goto fail;
1010 ret = lg216x_get_sccc_code_mode(state,
1011 (enum atscmh_sccc_code_mode *)
1012 &fe->dtv_property_cache.atscmh_sccc_code_mode_a,
1013 (enum atscmh_sccc_code_mode *)
1014 &fe->dtv_property_cache.atscmh_sccc_code_mode_b,
1015 (enum atscmh_sccc_code_mode *)
1016 &fe->dtv_property_cache.atscmh_sccc_code_mode_c,
1017 (enum atscmh_sccc_code_mode *)
1018 &fe->dtv_property_cache.atscmh_sccc_code_mode_d);
1019 if (lg_fail(ret))
1020 goto fail;
1021 }
1022#if 0
1023 ret = lg216x_read_fic_err_count(state,
1024 (u8 *)&fe->dtv_property_cache.atscmh_fic_err);
1025 if (lg_fail(ret))
1026 goto fail;
1027 ret = lg216x_read_crc_err_count(state,
1028 &fe->dtv_property_cache.atscmh_crc_err);
1029 if (lg_fail(ret))
1030 goto fail;
1031 ret = lg216x_read_rs_err_count(state,
1032 &fe->dtv_property_cache.atscmh_rs_err);
1033 if (lg_fail(ret))
1034 goto fail;
1035
1036 switch (state->cfg->lg_chip) {
1037 case LG2160:
1038 if (((fe->dtv_property_cache.atscmh_rs_err >= 240) &&
1039 (fe->dtv_property_cache.atscmh_crc_err >= 240)) &&
1040 ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000))
1041 ret = lg216x_soft_reset(state);
1042 break;
1043 case LG2161:
1044 /* no fix needed here (as far as we know) */
1045 ret = 0;
1046 break;
1047 }
1048 lg_fail(ret);
1049#endif
1050fail:
1051 return ret;
1052}
1053
1054static int lg216x_get_property(struct dvb_frontend *fe,
1055 struct dtv_property *tvp)
1056{
1057 return (DTV_ATSCMH_FIC_VER == tvp->cmd) ?
1058 lg216x_get_frontend(fe) : 0;
1059}
1060
1061
1062static int lg2160_set_frontend(struct dvb_frontend *fe)
1063{
1064 struct lg216x_state *state = fe->demodulator_priv;
1065 int ret;
1066
1067 lg_dbg("(%d)\n", fe->dtv_property_cache.frequency);
1068
1069 if (fe->ops.tuner_ops.set_params) {
1070 ret = fe->ops.tuner_ops.set_params(fe);
1071 if (fe->ops.i2c_gate_ctrl)
1072 fe->ops.i2c_gate_ctrl(fe, 0);
1073 if (lg_fail(ret))
1074 goto fail;
1075 state->current_frequency = fe->dtv_property_cache.frequency;
1076 }
1077
1078 ret = lg2160_agc_fix(state, 0, 0);
1079 if (lg_fail(ret))
1080 goto fail;
1081 ret = lg2160_agc_polarity(state, 0, 0);
1082 if (lg_fail(ret))
1083 goto fail;
1084 ret = lg2160_tuner_pwr_save_polarity(state, 1);
1085 if (lg_fail(ret))
1086 goto fail;
1087 ret = lg216x_set_if(state);
1088 if (lg_fail(ret))
1089 goto fail;
1090 ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion);
1091 if (lg_fail(ret))
1092 goto fail;
1093
1094 /* be tuned before this point */
1095 ret = lg216x_soft_reset(state);
1096 if (lg_fail(ret))
1097 goto fail;
1098
1099 ret = lg2160_tuner_pwr_save(state, 0);
1100 if (lg_fail(ret))
1101 goto fail;
1102
1103 switch (state->cfg->lg_chip) {
1104 case LG2160:
1105 ret = lg2160_set_spi_clock(state);
1106 if (lg_fail(ret))
1107 goto fail;
1108 break;
1109 case LG2161:
1110 ret = lg2161_set_output_interface(state);
1111 if (lg_fail(ret))
1112 goto fail;
1113 break;
1114 }
1115
1116 ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id);
1117 if (lg_fail(ret))
1118 goto fail;
1119
1120 ret = lg216x_set_ensemble(state,
1121 fe->dtv_property_cache.atscmh_rs_frame_ensemble);
1122 if (lg_fail(ret))
1123 goto fail;
1124
1125 ret = lg216x_initialize(state);
1126 if (lg_fail(ret))
1127 goto fail;
1128
1129 ret = lg216x_enable_fic(state, 1);
1130 lg_fail(ret);
1131
1132 lg216x_get_frontend(fe);
1133fail:
1134 return ret;
1135}
1136
1137/* ------------------------------------------------------------------------ */
1138
1139static int lg2160_read_lock_status(struct lg216x_state *state,
1140 int *acq_lock, int *sync_lock)
1141{
1142 u8 val;
1143 int ret;
1144
1145 *acq_lock = 0;
1146 *sync_lock = 0;
1147
1148 ret = lg216x_read_reg(state, 0x011b, &val);
1149 if (lg_fail(ret))
1150 goto fail;
1151
1152 *sync_lock = (val & 0x20) ? 0 : 1;
1153 *acq_lock = (val & 0x40) ? 0 : 1;
1154fail:
1155 return ret;
1156}
1157
1158#ifdef USE_LG2161_LOCK_BITS
1159static int lg2161_read_lock_status(struct lg216x_state *state,
1160 int *acq_lock, int *sync_lock)
1161{
1162 u8 val;
1163 int ret;
1164
1165 *acq_lock = 0;
1166 *sync_lock = 0;
1167
1168 ret = lg216x_read_reg(state, 0x0304, &val);
1169 if (lg_fail(ret))
1170 goto fail;
1171
1172 *sync_lock = (val & 0x80) ? 0 : 1;
1173
1174 ret = lg216x_read_reg(state, 0x011b, &val);
1175 if (lg_fail(ret))
1176 goto fail;
1177
1178 *acq_lock = (val & 0x40) ? 0 : 1;
1179fail:
1180 return ret;
1181}
1182#endif
1183
1184static int lg216x_read_lock_status(struct lg216x_state *state,
1185 int *acq_lock, int *sync_lock)
1186{
1187#ifdef USE_LG2161_LOCK_BITS
1188 int ret;
1189 switch (state->cfg->lg_chip) {
1190 case LG2160:
1191 ret = lg2160_read_lock_status(state, acq_lock, sync_lock);
1192 break;
1193 case LG2161:
1194 ret = lg2161_read_lock_status(state, acq_lock, sync_lock);
1195 break;
1196 default:
1197 ret = -EINVAL;
1198 break;
1199 }
1200 return ret;
1201#else
1202 return lg2160_read_lock_status(state, acq_lock, sync_lock);
1203#endif
1204}
1205
1206static int lg216x_read_status(struct dvb_frontend *fe, fe_status_t *status)
1207{
1208 struct lg216x_state *state = fe->demodulator_priv;
1209 int ret, acq_lock, sync_lock;
1210
1211 *status = 0;
1212
1213 ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock);
1214 if (lg_fail(ret))
1215 goto fail;
1216
1217 lg_dbg("%s%s\n",
1218 acq_lock ? "SIGNALEXIST " : "",
1219 sync_lock ? "SYNCLOCK" : "");
1220
1221 if (acq_lock)
1222 *status |= FE_HAS_SIGNAL;
1223 if (sync_lock)
1224 *status |= FE_HAS_SYNC;
1225
1226 if (*status)
1227 *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
1228
1229fail:
1230 return ret;
1231}
1232
1233/* ------------------------------------------------------------------------ */
1234
1235static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr)
1236{
1237 struct lg216x_state *state = fe->demodulator_priv;
1238 u8 snr1, snr2;
1239 int ret;
1240
1241 *snr = 0;
1242
1243 ret = lg216x_read_reg(state, 0x0202, &snr1);
1244 if (lg_fail(ret))
1245 goto fail;
1246
1247 ret = lg216x_read_reg(state, 0x0203, &snr2);
1248 if (lg_fail(ret))
1249 goto fail;
1250
1251 if ((snr1 == 0xba) || (snr2 == 0xdf))
1252 *snr = 0;
1253 else
1254#if 1
1255 *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4);
1256#else /* BCD */
1257 *snr = (snr2 | (snr1 << 8));
1258#endif
1259fail:
1260 return ret;
1261}
1262
1263static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr)
1264{
1265 struct lg216x_state *state = fe->demodulator_priv;
1266 u8 snr1, snr2;
1267 int ret;
1268
1269 *snr = 0;
1270
1271 ret = lg216x_read_reg(state, 0x0302, &snr1);
1272 if (lg_fail(ret))
1273 goto fail;
1274
1275 ret = lg216x_read_reg(state, 0x0303, &snr2);
1276 if (lg_fail(ret))
1277 goto fail;
1278
1279 if ((snr1 == 0xba) || (snr2 == 0xfd))
1280 *snr = 0;
1281 else
1282
1283 *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f);
1284fail:
1285 return ret;
1286}
1287
1288static int lg216x_read_signal_strength(struct dvb_frontend *fe,
1289 u16 *strength)
1290{
1291#if 0
1292 /* borrowed from lgdt330x.c
1293 *
1294 * Calculate strength from SNR up to 35dB
1295 * Even though the SNR can go higher than 35dB,
1296 * there is some comfort factor in having a range of
1297 * strong signals that can show at 100%
1298 */
1299 struct lg216x_state *state = fe->demodulator_priv;
1300 u16 snr;
1301 int ret;
1302#endif
1303 *strength = 0;
1304#if 0
1305 ret = fe->ops.read_snr(fe, &snr);
1306 if (lg_fail(ret))
1307 goto fail;
1308 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
1309 /* scale the range 0 - 35*2^24 into 0 - 65535 */
1310 if (state->snr >= 8960 * 0x10000)
1311 *strength = 0xffff;
1312 else
1313 *strength = state->snr / 8960;
1314fail:
1315 return ret;
1316#else
1317 return 0;
1318#endif
1319}
1320
1321/* ------------------------------------------------------------------------ */
1322
1323static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1324{
1325#if 0
1326 struct lg216x_state *state = fe->demodulator_priv;
1327 int ret;
1328
1329 ret = lg216x_read_rs_err_count(state,
1330 &fe->dtv_property_cache.atscmh_rs_err);
1331 if (lg_fail(ret))
1332 goto fail;
1333
1334 *ucblocks = fe->dtv_property_cache.atscmh_rs_err;
1335fail:
1336#else
1337 *ucblocks = 0;
1338#endif
1339 return 0;
1340}
1341
1342static int lg216x_get_tune_settings(struct dvb_frontend *fe,
1343 struct dvb_frontend_tune_settings
1344 *fe_tune_settings)
1345{
1346 fe_tune_settings->min_delay_ms = 500;
1347 lg_dbg("\n");
1348 return 0;
1349}
1350
1351static void lg216x_release(struct dvb_frontend *fe)
1352{
1353 struct lg216x_state *state = fe->demodulator_priv;
1354 lg_dbg("\n");
1355 kfree(state);
1356}
1357
1358static struct dvb_frontend_ops lg2160_ops = {
1359 .delsys = { SYS_ATSCMH },
1360 .info = {
1361 .name = "LG Electronics LG2160 ATSC/MH Frontend",
1362 .frequency_min = 54000000,
1363 .frequency_max = 858000000,
1364 .frequency_stepsize = 62500,
1365 },
1366 .i2c_gate_ctrl = lg216x_i2c_gate_ctrl,
1367#if 0
1368 .init = lg216x_init,
1369 .sleep = lg216x_sleep,
1370#endif
1371 .get_property = lg216x_get_property,
1372
1373 .set_frontend = lg2160_set_frontend,
1374 .get_frontend = lg216x_get_frontend,
1375 .get_tune_settings = lg216x_get_tune_settings,
1376 .read_status = lg216x_read_status,
1377#if 0
1378 .read_ber = lg216x_read_ber,
1379#endif
1380 .read_signal_strength = lg216x_read_signal_strength,
1381 .read_snr = lg2160_read_snr,
1382 .read_ucblocks = lg216x_read_ucblocks,
1383 .release = lg216x_release,
1384};
1385
1386static struct dvb_frontend_ops lg2161_ops = {
1387 .delsys = { SYS_ATSCMH },
1388 .info = {
1389 .name = "LG Electronics LG2161 ATSC/MH Frontend",
1390 .frequency_min = 54000000,
1391 .frequency_max = 858000000,
1392 .frequency_stepsize = 62500,
1393 },
1394 .i2c_gate_ctrl = lg216x_i2c_gate_ctrl,
1395#if 0
1396 .init = lg216x_init,
1397 .sleep = lg216x_sleep,
1398#endif
1399 .get_property = lg216x_get_property,
1400
1401 .set_frontend = lg2160_set_frontend,
1402 .get_frontend = lg216x_get_frontend,
1403 .get_tune_settings = lg216x_get_tune_settings,
1404 .read_status = lg216x_read_status,
1405#if 0
1406 .read_ber = lg216x_read_ber,
1407#endif
1408 .read_signal_strength = lg216x_read_signal_strength,
1409 .read_snr = lg2161_read_snr,
1410 .read_ucblocks = lg216x_read_ucblocks,
1411 .release = lg216x_release,
1412};
1413
1414struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
1415 struct i2c_adapter *i2c_adap)
1416{
1417 struct lg216x_state *state = NULL;
1418
1419 lg_dbg("(%d-%04x)\n",
1420 i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
1421 config ? config->i2c_addr : 0);
1422
1423 state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL);
1424 if (state == NULL)
1425 goto fail;
1426
1427 state->cfg = config;
1428 state->i2c_adap = i2c_adap;
1429 state->fic_ver = 0xff;
1430 state->parade_id = 0xff;
1431
1432 switch (config->lg_chip) {
1433 default:
1434 lg_warn("invalid chip requested, defaulting to LG2160");
1435 /* fall-thru */
1436 case LG2160:
1437 memcpy(&state->frontend.ops, &lg2160_ops,
1438 sizeof(struct dvb_frontend_ops));
1439 break;
1440 case LG2161:
1441 memcpy(&state->frontend.ops, &lg2161_ops,
1442 sizeof(struct dvb_frontend_ops));
1443 break;
1444 }
1445
1446 state->frontend.demodulator_priv = state;
1447 state->current_frequency = -1;
1448 /* parade 1 by default */
1449 state->frontend.dtv_property_cache.atscmh_parade_id = 1;
1450
1451 return &state->frontend;
1452fail:
1453 lg_warn("unable to detect LG216x hardware\n");
1454 kfree(state);
1455 return NULL;
1456}
1457EXPORT_SYMBOL(lg2160_attach);
1458
1459MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver");
1460MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1461MODULE_LICENSE("GPL");
1462MODULE_VERSION("0.3");
1463
1464/*
1465 * Local variables:
1466 * c-basic-offset: 8
1467 * End:
1468 */
diff --git a/drivers/media/dvb/frontends/lg2160.h b/drivers/media/dvb/frontends/lg2160.h
new file mode 100644
index 000000000000..9e2c0f41199a
--- /dev/null
+++ b/drivers/media/dvb/frontends/lg2160.h
@@ -0,0 +1,84 @@
1/*
2 * Support for LG2160 - ATSC/MH
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org>
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#ifndef _LG2160_H_
23#define _LG2160_H_
24
25#include <linux/i2c.h>
26#include "dvb_frontend.h"
27
28enum lg_chip_type {
29 LG2160 = 0,
30 LG2161 = 1,
31};
32
33#define LG2161_1019 LG2161
34#define LG2161_1040 LG2161
35
36enum lg2160_spi_clock {
37 LG2160_SPI_3_125_MHZ = 0,
38 LG2160_SPI_6_25_MHZ = 1,
39 LG2160_SPI_12_5_MHZ = 2,
40};
41
42#if 0
43enum lg2161_oif {
44 LG2161_OIF_EBI2_SLA = 1,
45 LG2161_OIF_SDIO_SLA = 2,
46 LG2161_OIF_SPI_SLA = 3,
47 LG2161_OIF_SPI_MAS = 4,
48 LG2161_OIF_SERIAL_TS = 7,
49};
50#endif
51
52struct lg2160_config {
53 u8 i2c_addr;
54
55 /* user defined IF frequency in KHz */
56 u16 if_khz;
57
58 /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
59 int deny_i2c_rptr:1;
60
61 /* spectral inversion - 0:disabled 1:enabled */
62 int spectral_inversion:1;
63
64 unsigned int output_if;
65 enum lg2160_spi_clock spi_clock;
66 enum lg_chip_type lg_chip;
67};
68
69#if defined(CONFIG_DVB_LG2160) || (defined(CONFIG_DVB_LG2160_MODULE) && \
70 defined(MODULE))
71extern
72struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
73 struct i2c_adapter *i2c_adap);
74#else
75static inline
76struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
77 struct i2c_adapter *i2c_adap)
78{
79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
80 return NULL;
81}
82#endif /* CONFIG_DVB_LG2160 */
83
84#endif /* _LG2160_H_ */
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index 4de1d3520cd2..568363a10a31 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -262,7 +262,6 @@ static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
262 262
263static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) 263static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
264{ 264{
265 int ret = 0;
266 u8 t; 265 u8 t;
267 266
268 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) { 267 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
@@ -296,7 +295,7 @@ static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
296 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 295 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
297 lgs8gxx_write_reg(priv, 0xC1, 0); 296 lgs8gxx_write_reg(priv, 0xC1, 0);
298 297
299 ret = lgs8gxx_read_reg(priv, 0xC5, &t); 298 lgs8gxx_read_reg(priv, 0xC5, &t);
300 t = (t & 0xE0) | 0x06; 299 t = (t & 0xE0) | 0x06;
301 lgs8gxx_write_reg(priv, 0xC5, t); 300 lgs8gxx_write_reg(priv, 0xC5, t);
302 301
diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c
index 045ee5a6f7ae..312588e84dae 100644
--- a/drivers/media/dvb/frontends/m88rs2000.c
+++ b/drivers/media/dvb/frontends/m88rs2000.c
@@ -416,9 +416,25 @@ static int m88rs2000_tab_set(struct m88rs2000_state *state,
416 416
417static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) 417static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
418{ 418{
419 deb_info("%s: %s\n", __func__, 419 struct m88rs2000_state *state = fe->demodulator_priv;
420 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : 420 u8 data;
421 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); 421
422 data = m88rs2000_demod_read(state, 0xb2);
423 data |= 0x03; /* bit0 V/H, bit1 off/on */
424
425 switch (volt) {
426 case SEC_VOLTAGE_18:
427 data &= ~0x03;
428 break;
429 case SEC_VOLTAGE_13:
430 data &= ~0x03;
431 data |= 0x01;
432 break;
433 case SEC_VOLTAGE_OFF:
434 break;
435 }
436
437 m88rs2000_demod_write(state, 0xb2, data);
422 438
423 return 0; 439 return 0;
424} 440}
@@ -654,7 +670,6 @@ static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset)
654static int m88rs2000_set_fec(struct m88rs2000_state *state, 670static int m88rs2000_set_fec(struct m88rs2000_state *state,
655 fe_code_rate_t fec) 671 fe_code_rate_t fec)
656{ 672{
657 int ret;
658 u16 fec_set; 673 u16 fec_set;
659 switch (fec) { 674 switch (fec) {
660 /* This is not confirmed kept for reference */ 675 /* This is not confirmed kept for reference */
@@ -677,7 +692,7 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state,
677 default: 692 default:
678 fec_set = 0x08; 693 fec_set = 0x08;
679 } 694 }
680 ret = m88rs2000_demod_write(state, 0x76, fec_set); 695 m88rs2000_demod_write(state, 0x76, fec_set);
681 696
682 return 0; 697 return 0;
683} 698}
@@ -772,13 +787,13 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
772 return -ENODEV; 787 return -ENODEV;
773 788
774 for (i = 0; i < 25; i++) { 789 for (i = 0; i < 25; i++) {
775 u8 reg = m88rs2000_demod_read(state, 0x8c); 790 reg = m88rs2000_demod_read(state, 0x8c);
776 if ((reg & 0x7) == 0x7) { 791 if ((reg & 0x7) == 0x7) {
777 status = FE_HAS_LOCK; 792 status = FE_HAS_LOCK;
778 break; 793 break;
779 } 794 }
780 state->no_lock_count++; 795 state->no_lock_count++;
781 if (state->no_lock_count > 15) { 796 if (state->no_lock_count == 15) {
782 reg = m88rs2000_demod_read(state, 0x70); 797 reg = m88rs2000_demod_read(state, 0x70);
783 reg ^= 0x4; 798 reg ^= 0x4;
784 m88rs2000_demod_write(state, 0x70, reg); 799 m88rs2000_demod_write(state, 0x70, reg);
diff --git a/drivers/media/dvb/frontends/rtl2830.c b/drivers/media/dvb/frontends/rtl2830.c
index 45196c5b0736..93612ebac519 100644
--- a/drivers/media/dvb/frontends/rtl2830.c
+++ b/drivers/media/dvb/frontends/rtl2830.c
@@ -374,6 +374,118 @@ err:
374 return ret; 374 return ret;
375} 375}
376 376
377static int rtl2830_get_frontend(struct dvb_frontend *fe)
378{
379 struct rtl2830_priv *priv = fe->demodulator_priv;
380 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
381 int ret;
382 u8 buf[3];
383
384 if (priv->sleeping)
385 return 0;
386
387 ret = rtl2830_rd_regs(priv, 0x33c, buf, 2);
388 if (ret)
389 goto err;
390
391 ret = rtl2830_rd_reg(priv, 0x351, &buf[2]);
392 if (ret)
393 goto err;
394
395 dbg("%s: TPS=%02x %02x %02x", __func__, buf[0], buf[1], buf[2]);
396
397 switch ((buf[0] >> 2) & 3) {
398 case 0:
399 c->modulation = QPSK;
400 break;
401 case 1:
402 c->modulation = QAM_16;
403 break;
404 case 2:
405 c->modulation = QAM_64;
406 break;
407 }
408
409 switch ((buf[2] >> 2) & 1) {
410 case 0:
411 c->transmission_mode = TRANSMISSION_MODE_2K;
412 break;
413 case 1:
414 c->transmission_mode = TRANSMISSION_MODE_8K;
415 }
416
417 switch ((buf[2] >> 0) & 3) {
418 case 0:
419 c->guard_interval = GUARD_INTERVAL_1_32;
420 break;
421 case 1:
422 c->guard_interval = GUARD_INTERVAL_1_16;
423 break;
424 case 2:
425 c->guard_interval = GUARD_INTERVAL_1_8;
426 break;
427 case 3:
428 c->guard_interval = GUARD_INTERVAL_1_4;
429 break;
430 }
431
432 switch ((buf[0] >> 4) & 7) {
433 case 0:
434 c->hierarchy = HIERARCHY_NONE;
435 break;
436 case 1:
437 c->hierarchy = HIERARCHY_1;
438 break;
439 case 2:
440 c->hierarchy = HIERARCHY_2;
441 break;
442 case 3:
443 c->hierarchy = HIERARCHY_4;
444 break;
445 }
446
447 switch ((buf[1] >> 3) & 7) {
448 case 0:
449 c->code_rate_HP = FEC_1_2;
450 break;
451 case 1:
452 c->code_rate_HP = FEC_2_3;
453 break;
454 case 2:
455 c->code_rate_HP = FEC_3_4;
456 break;
457 case 3:
458 c->code_rate_HP = FEC_5_6;
459 break;
460 case 4:
461 c->code_rate_HP = FEC_7_8;
462 break;
463 }
464
465 switch ((buf[1] >> 0) & 7) {
466 case 0:
467 c->code_rate_LP = FEC_1_2;
468 break;
469 case 1:
470 c->code_rate_LP = FEC_2_3;
471 break;
472 case 2:
473 c->code_rate_LP = FEC_3_4;
474 break;
475 case 3:
476 c->code_rate_LP = FEC_5_6;
477 break;
478 case 4:
479 c->code_rate_LP = FEC_7_8;
480 break;
481 }
482
483 return 0;
484err:
485 dbg("%s: failed=%d", __func__, ret);
486 return ret;
487}
488
377static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status) 489static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
378{ 490{
379 struct rtl2830_priv *priv = fe->demodulator_priv; 491 struct rtl2830_priv *priv = fe->demodulator_priv;
@@ -404,14 +516,72 @@ err:
404 516
405static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr) 517static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
406{ 518{
407 *snr = 0; 519 struct rtl2830_priv *priv = fe->demodulator_priv;
520 int ret, hierarchy, constellation;
521 u8 buf[2], tmp;
522 u16 tmp16;
523#define CONSTELLATION_NUM 3
524#define HIERARCHY_NUM 4
525 static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
526 { 70705899, 70705899, 70705899, 70705899 },
527 { 82433173, 82433173, 87483115, 94445660 },
528 { 92888734, 92888734, 95487525, 99770748 },
529 };
530
531 if (priv->sleeping)
532 return 0;
533
534 /* reports SNR in resolution of 0.1 dB */
535
536 ret = rtl2830_rd_reg(priv, 0x33c, &tmp);
537 if (ret)
538 goto err;
539
540 constellation = (tmp >> 2) & 0x03; /* [3:2] */
541 if (constellation > CONSTELLATION_NUM - 1)
542 goto err;
543
544 hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
545 if (hierarchy > HIERARCHY_NUM - 1)
546 goto err;
547
548 ret = rtl2830_rd_regs(priv, 0x40c, buf, 2);
549 if (ret)
550 goto err;
551
552 tmp16 = buf[0] << 8 | buf[1];
553
554 if (tmp16)
555 *snr = (snr_constant[constellation][hierarchy] -
556 intlog10(tmp16)) / ((1 << 24) / 100);
557 else
558 *snr = 0;
559
408 return 0; 560 return 0;
561err:
562 dbg("%s: failed=%d", __func__, ret);
563 return ret;
409} 564}
410 565
411static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber) 566static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
412{ 567{
413 *ber = 0; 568 struct rtl2830_priv *priv = fe->demodulator_priv;
569 int ret;
570 u8 buf[2];
571
572 if (priv->sleeping)
573 return 0;
574
575 ret = rtl2830_rd_regs(priv, 0x34e, buf, 2);
576 if (ret)
577 goto err;
578
579 *ber = buf[0] << 8 | buf[1];
580
414 return 0; 581 return 0;
582err:
583 dbg("%s: failed=%d", __func__, ret);
584 return ret;
415} 585}
416 586
417static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 587static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
@@ -422,8 +592,32 @@ static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
422 592
423static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 593static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
424{ 594{
425 *strength = 0; 595 struct rtl2830_priv *priv = fe->demodulator_priv;
596 int ret;
597 u8 buf[2];
598 u16 if_agc_raw, if_agc;
599
600 if (priv->sleeping)
601 return 0;
602
603 ret = rtl2830_rd_regs(priv, 0x359, buf, 2);
604 if (ret)
605 goto err;
606
607 if_agc_raw = (buf[0] << 8 | buf[1]) & 0x3fff;
608
609 if (if_agc_raw & (1 << 9))
610 if_agc = -(~(if_agc_raw - 1) & 0x1ff);
611 else
612 if_agc = if_agc_raw;
613
614 *strength = (u8) (55 - if_agc / 182);
615 *strength |= *strength << 8;
616
426 return 0; 617 return 0;
618err:
619 dbg("%s: failed=%d", __func__, ret);
620 return ret;
427} 621}
428 622
429static struct dvb_frontend_ops rtl2830_ops; 623static struct dvb_frontend_ops rtl2830_ops;
@@ -549,6 +743,7 @@ static struct dvb_frontend_ops rtl2830_ops = {
549 .get_tune_settings = rtl2830_get_tune_settings, 743 .get_tune_settings = rtl2830_get_tune_settings,
550 744
551 .set_frontend = rtl2830_set_frontend, 745 .set_frontend = rtl2830_set_frontend,
746 .get_frontend = rtl2830_get_frontend,
552 747
553 .read_status = rtl2830_read_status, 748 .read_status = rtl2830_read_status,
554 .read_snr = rtl2830_read_snr, 749 .read_snr = rtl2830_read_snr,
diff --git a/drivers/media/dvb/frontends/rtl2830_priv.h b/drivers/media/dvb/frontends/rtl2830_priv.h
index 4a464761b5b8..9b20557ccf6c 100644
--- a/drivers/media/dvb/frontends/rtl2830_priv.h
+++ b/drivers/media/dvb/frontends/rtl2830_priv.h
@@ -22,6 +22,7 @@
22#define RTL2830_PRIV_H 22#define RTL2830_PRIV_H
23 23
24#include "dvb_frontend.h" 24#include "dvb_frontend.h"
25#include "dvb_math.h"
25#include "rtl2830.h" 26#include "rtl2830.h"
26 27
27#define LOG_PREFIX "rtl2830" 28#define LOG_PREFIX "rtl2830"
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index dd08f4ac64a8..8b0dc74a3298 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -637,11 +637,9 @@ static void stb0899_init_calc(struct stb0899_state *state)
637 struct stb0899_internal *internal = &state->internal; 637 struct stb0899_internal *internal = &state->internal;
638 int master_clk; 638 int master_clk;
639 u8 agc[2]; 639 u8 agc[2];
640 u8 agc1cn;
641 u32 reg; 640 u32 reg;
642 641
643 /* Read registers (in burst mode) */ 642 /* Read registers (in burst mode) */
644 agc1cn = stb0899_read_reg(state, STB0899_AGC1CN);
645 stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */ 643 stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */
646 644
647 /* Initial calculations */ 645 /* Initial calculations */
@@ -823,15 +821,12 @@ static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t
823 821
824static int stb0899_diseqc_init(struct stb0899_state *state) 822static int stb0899_diseqc_init(struct stb0899_state *state)
825{ 823{
826 struct dvb_diseqc_master_cmd tx_data;
827/* 824/*
828 struct dvb_diseqc_slave_reply rx_data; 825 struct dvb_diseqc_slave_reply rx_data;
829*/ 826*/
830 u8 f22_tx, f22_rx, reg; 827 u8 f22_tx, reg;
831 828
832 u32 mclk, tx_freq = 22000;/* count = 0, i; */ 829 u32 mclk, tx_freq = 22000;/* count = 0, i; */
833 tx_data.msg[0] = 0xe2;
834 tx_data.msg_len = 3;
835 reg = stb0899_read_reg(state, STB0899_DISCNTRL2); 830 reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
836 STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); 831 STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
837 stb0899_write_reg(state, STB0899_DISCNTRL2, reg); 832 stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
@@ -849,7 +844,6 @@ static int stb0899_diseqc_init(struct stb0899_state *state)
849 f22_tx = mclk / (tx_freq * 32); 844 f22_tx = mclk / (tx_freq * 32);
850 stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */ 845 stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */
851 state->rx_freq = 20000; 846 state->rx_freq = 20000;
852 f22_rx = mclk / (state->rx_freq * 32);
853 847
854 return 0; 848 return 0;
855} 849}
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index def88abb30bf..2e93e65d2cdb 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -158,7 +158,6 @@ static int stb6100_read_regs(struct stb6100_state *state, u8 regs[])
158static int stb6100_read_reg(struct stb6100_state *state, u8 reg) 158static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
159{ 159{
160 u8 regs[STB6100_NUMREGS]; 160 u8 regs[STB6100_NUMREGS];
161 int rc;
162 161
163 struct i2c_msg msg = { 162 struct i2c_msg msg = {
164 .addr = state->config->tuner_address + reg, 163 .addr = state->config->tuner_address + reg,
@@ -167,7 +166,7 @@ static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
167 .len = 1 166 .len = 1
168 }; 167 };
169 168
170 rc = i2c_transfer(state->i2c, &msg, 1); 169 i2c_transfer(state->i2c, &msg, 1);
171 170
172 if (unlikely(reg >= STB6100_NUMREGS)) { 171 if (unlikely(reg >= STB6100_NUMREGS)) {
173 dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); 172 dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 85c157a1fe5e..d40f226160ef 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -414,7 +414,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe)
414 int delay; 414 int delay;
415 int sweeprate; 415 int sweeprate;
416 int carrieroffset; 416 int carrieroffset;
417 unsigned long starttime;
418 unsigned long timeout; 417 unsigned long timeout;
419 fe_spectral_inversion_t inversion; 418 fe_spectral_inversion_t inversion;
420 419
@@ -543,7 +542,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe)
543 stv0297_writereg_mask(state, 0x43, 0x10, 0x10); 542 stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
544 543
545 /* wait for WGAGC lock */ 544 /* wait for WGAGC lock */
546 starttime = jiffies;
547 timeout = jiffies + msecs_to_jiffies(2000); 545 timeout = jiffies + msecs_to_jiffies(2000);
548 while (time_before(jiffies, timeout)) { 546 while (time_before(jiffies, timeout)) {
549 msleep(10); 547 msleep(10);
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
index ba0709b2d433..4af20780fb9c 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -835,7 +835,6 @@ static void stv0900_track_optimization(struct dvb_frontend *fe)
835 blind_tun_sw = 0, 835 blind_tun_sw = 0,
836 modulation; 836 modulation;
837 837
838 enum fe_stv0900_rolloff rolloff;
839 enum fe_stv0900_modcode foundModcod; 838 enum fe_stv0900_modcode foundModcod;
840 839
841 dprintk("%s\n", __func__); 840 dprintk("%s\n", __func__);
@@ -940,7 +939,6 @@ static void stv0900_track_optimization(struct dvb_frontend *fe)
940 939
941 freq1 = stv0900_read_reg(intp, CFR2); 940 freq1 = stv0900_read_reg(intp, CFR2);
942 freq0 = stv0900_read_reg(intp, CFR1); 941 freq0 = stv0900_read_reg(intp, CFR1);
943 rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
944 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { 942 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
945 stv0900_write_reg(intp, SFRSTEP, 0x00); 943 stv0900_write_reg(intp, SFRSTEP, 0x00);
946 stv0900_write_bits(intp, SCAN_ENABLE, 0); 944 stv0900_write_bits(intp, SCAN_ENABLE, 0);
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 4aef1877ed42..d79e69f65cbb 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -2842,7 +2842,6 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2842{ 2842{
2843 struct dvb_frontend *fe = &state->frontend; 2843 struct dvb_frontend *fe = &state->frontend;
2844 2844
2845 enum stv090x_rolloff rolloff;
2846 enum stv090x_modcod modcod; 2845 enum stv090x_modcod modcod;
2847 2846
2848 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; 2847 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
@@ -2966,7 +2965,6 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2966 f_1 = STV090x_READ_DEMOD(state, CFR2); 2965 f_1 = STV090x_READ_DEMOD(state, CFR2);
2967 f_0 = STV090x_READ_DEMOD(state, CFR1); 2966 f_0 = STV090x_READ_DEMOD(state, CFR1);
2968 reg = STV090x_READ_DEMOD(state, TMGOBS); 2967 reg = STV090x_READ_DEMOD(state, TMGOBS);
2969 rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
2970 2968
2971 if (state->algo == STV090x_BLIND_SEARCH) { 2969 if (state->algo == STV090x_BLIND_SEARCH) {
2972 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); 2970 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index ac7237891374..82946cd517f5 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -525,7 +525,7 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
525 zl10353_dump_regs(fe); 525 zl10353_dump_regs(fe);
526 526
527 _snr = zl10353_read_register(state, SNR); 527 _snr = zl10353_read_register(state, SNR);
528 *snr = (_snr << 8) | _snr; 528 *snr = 10 * _snr / 8;
529 529
530 return 0; 530 return 0;
531} 531}
@@ -559,7 +559,6 @@ static int zl10353_init(struct dvb_frontend *fe)
559{ 559{
560 struct zl10353_state *state = fe->demodulator_priv; 560 struct zl10353_state *state = fe->demodulator_priv;
561 u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; 561 u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
562 int rc = 0;
563 562
564 if (debug_regs) 563 if (debug_regs)
565 zl10353_dump_regs(fe); 564 zl10353_dump_regs(fe);
@@ -573,7 +572,7 @@ static int zl10353_init(struct dvb_frontend *fe)
573 /* Do a "hard" reset if not already done */ 572 /* Do a "hard" reset if not already done */
574 if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || 573 if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
575 zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) { 574 zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
576 rc = zl10353_write(fe, zl10353_reset_attach, 575 zl10353_write(fe, zl10353_reset_attach,
577 sizeof(zl10353_reset_attach)); 576 sizeof(zl10353_reset_attach));
578 if (debug_regs) 577 if (debug_regs)
579 zl10353_dump_regs(fe); 578 zl10353_dump_regs(fe);
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 71622f65c037..cc0251e01077 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -65,7 +65,7 @@ static int devs;
65 65
66static irqreturn_t hopper_irq_handler(int irq, void *dev_id) 66static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
67{ 67{
68 u32 stat = 0, mask = 0, lstat = 0; 68 u32 stat = 0, mask = 0;
69 u32 rst_stat = 0, rst_mask = 0; 69 u32 rst_stat = 0, rst_mask = 0;
70 70
71 struct mantis_pci *mantis; 71 struct mantis_pci *mantis;
@@ -80,7 +80,6 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
80 80
81 stat = mmread(MANTIS_INT_STAT); 81 stat = mmread(MANTIS_INT_STAT);
82 mask = mmread(MANTIS_INT_MASK); 82 mask = mmread(MANTIS_INT_MASK);
83 lstat = stat & ~MANTIS_INT_RISCSTAT;
84 if (!(stat & mask)) 83 if (!(stat & mask))
85 return IRQ_NONE; 84 return IRQ_NONE;
86 85
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index c2bb90b3e529..095cf3a994e2 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -73,7 +73,7 @@ static char *label[10] = {
73 73
74static irqreturn_t mantis_irq_handler(int irq, void *dev_id) 74static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
75{ 75{
76 u32 stat = 0, mask = 0, lstat = 0; 76 u32 stat = 0, mask = 0;
77 u32 rst_stat = 0, rst_mask = 0; 77 u32 rst_stat = 0, rst_mask = 0;
78 78
79 struct mantis_pci *mantis; 79 struct mantis_pci *mantis;
@@ -88,7 +88,6 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
88 88
89 stat = mmread(MANTIS_INT_STAT); 89 stat = mmread(MANTIS_INT_STAT);
90 mask = mmread(MANTIS_INT_MASK); 90 mask = mmread(MANTIS_INT_MASK);
91 lstat = stat & ~MANTIS_INT_RISCSTAT;
92 if (!(stat & mask)) 91 if (!(stat & mask))
93 return IRQ_NONE; 92 return IRQ_NONE;
94 93
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
index c61ca7d3daea..566c407175a4 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -199,10 +199,6 @@ void mantis_dma_start(struct mantis_pci *mantis)
199 199
200void mantis_dma_stop(struct mantis_pci *mantis) 200void mantis_dma_stop(struct mantis_pci *mantis)
201{ 201{
202 u32 stat = 0, mask = 0;
203
204 stat = mmread(MANTIS_INT_STAT);
205 mask = mmread(MANTIS_INT_MASK);
206 dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); 202 dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
207 203
208 mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); 204 mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR);
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c
index 36f2256ebb0e..71ce52875c38 100644
--- a/drivers/media/dvb/mantis/mantis_evm.c
+++ b/drivers/media/dvb/mantis/mantis_evm.c
@@ -41,10 +41,9 @@ static void mantis_hifevm_work(struct work_struct *work)
41 struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); 41 struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work);
42 struct mantis_pci *mantis = ca->ca_priv; 42 struct mantis_pci *mantis = ca->ca_priv;
43 43
44 u32 gpif_stat, gpif_mask; 44 u32 gpif_stat;
45 45
46 gpif_stat = mmread(MANTIS_GPIF_STATUS); 46 gpif_stat = mmread(MANTIS_GPIF_STATUS);
47 gpif_mask = mmread(MANTIS_GPIF_IRQCFG);
48 47
49 if (gpif_stat & MANTIS_GPIF_DETSTAT) { 48 if (gpif_stat & MANTIS_GPIF_DETSTAT) {
50 if (gpif_stat & MANTIS_CARD_PLUGIN) { 49 if (gpif_stat & MANTIS_CARD_PLUGIN) {
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index f129a9303f80..39857384af10 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -1409,10 +1409,8 @@ static int ngene_start(struct ngene *dev)
1409 if (stat < 0) 1409 if (stat < 0)
1410 goto fail; 1410 goto fail;
1411 1411
1412 if (!stat) 1412 return 0;
1413 return stat;
1414 1413
1415 /* otherwise error: fall through */
1416fail: 1414fail:
1417 ngwritel(0, NGENE_INT_ENABLE); 1415 ngwritel(0, NGENE_INT_ENABLE);
1418 free_irq(dev->pci_dev->irq, dev); 1416 free_irq(dev->pci_dev->irq, dev);
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index e1f20c236989..f148b19a206a 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -481,14 +481,6 @@ static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe)
481 if (p->bandwidth_hz == 8000000) 481 if (p->bandwidth_hz == 8000000)
482 buf[3] |= 0x08; 482 buf[3] |= 0x08;
483 483
484 if (sizeof(buf) == 6) {
485 buf[4] = buf[2];
486 buf[4] &= ~0x1c;
487 buf[4] |= 0x18;
488
489 buf[5] = (0 << 7) | (2 << 4);
490 }
491
492 msg.addr = I2C_ADDR_TUA6034 >> 1; 484 msg.addr = I2C_ADDR_TUA6034 >> 1;
493 msg.flags = 0; 485 msg.flags = 0;
494 msg.buf = buf; 486 msg.buf = buf;
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
index 91f8c8291e2b..d6f3f100699a 100644
--- a/drivers/media/dvb/siano/smssdio.c
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -114,7 +114,7 @@ out:
114 114
115static void smssdio_interrupt(struct sdio_func *func) 115static void smssdio_interrupt(struct sdio_func *func)
116{ 116{
117 int ret, isr; 117 int ret;
118 118
119 struct smssdio_device *smsdev; 119 struct smssdio_device *smsdev;
120 struct smscore_buffer_t *cb; 120 struct smscore_buffer_t *cb;
@@ -127,7 +127,7 @@ static void smssdio_interrupt(struct sdio_func *func)
127 * The interrupt register has no defined meaning. It is just 127 * The interrupt register has no defined meaning. It is just
128 * a way of turning of the level triggered interrupt. 128 * a way of turning of the level triggered interrupt.
129 */ 129 */
130 isr = sdio_readb(func, SMSSDIO_INT, &ret); 130 (void)sdio_readb(func, SMSSDIO_INT, &ret);
131 if (ret) { 131 if (ret) {
132 sms_err("Unable to read interrupt register!\n"); 132 sms_err("Unable to read interrupt register!\n");
133 return; 133 return;
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index b1fe5137df09..63c004a25e0b 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -542,6 +542,8 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = {
542 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 542 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
543 { USB_DEVICE(0x2040, 0xc090), 543 { USB_DEVICE(0x2040, 0xc090),
544 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, 544 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
545 { USB_DEVICE(0x2040, 0xc0a0),
546 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
545 { } /* Terminating entry */ 547 { } /* Terminating entry */
546 }; 548 };
547 549
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index ee8ee1d481fa..1b2d15140a1d 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -107,7 +107,7 @@ static struct v4l2_input inputs[4] = {
107 .index = 1, 107 .index = 1,
108 .name = "Television", 108 .name = "Television",
109 .type = V4L2_INPUT_TYPE_TUNER, 109 .type = V4L2_INPUT_TYPE_TUNER,
110 .audioset = 2, 110 .audioset = 1,
111 .tuner = 0, 111 .tuner = 0,
112 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 112 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
113 .status = 0, 113 .status = 0,
@@ -494,7 +494,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
494 dprintk(2, "VIDIOC_S_INPUT: %d\n", input); 494 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
495 495
496 if (!av7110->analog_tuner_flags) 496 if (!av7110->analog_tuner_flags)
497 return 0; 497 return input ? -EINVAL : 0;
498 498
499 if (input >= 4) 499 if (input >= 4)
500 return -EINVAL; 500 return -EINVAL;
@@ -503,19 +503,38 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
503 return av7110_dvb_c_switch(fh); 503 return av7110_dvb_c_switch(fh);
504} 504}
505 505
506static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
507{
508 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
509 if (a->index != 0)
510 return -EINVAL;
511 *a = msp3400_v4l2_audio;
512 return 0;
513}
514
506static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 515static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
507{ 516{
517 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
518 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
519
508 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); 520 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
509 if (a->index != 0) 521 if (a->index != 0)
510 return -EINVAL; 522 return -EINVAL;
511 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); 523 if (av7110->current_input >= 2)
524 return -EINVAL;
525 *a = msp3400_v4l2_audio;
512 return 0; 526 return 0;
513} 527}
514 528
515static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) 529static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
516{ 530{
531 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
532 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
533
517 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); 534 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
518 return 0; 535 if (av7110->current_input >= 2)
536 return -EINVAL;
537 return a->index ? -EINVAL : 0;
519} 538}
520 539
521static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, 540static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
@@ -802,26 +821,39 @@ int av7110_init_v4l(struct av7110 *av7110)
802 ERR("cannot init capture device. skipping\n"); 821 ERR("cannot init capture device. skipping\n");
803 return -ENODEV; 822 return -ENODEV;
804 } 823 }
805 vv_data->ops.vidioc_enum_input = vidioc_enum_input; 824 vv_data->vid_ops.vidioc_enum_input = vidioc_enum_input;
806 vv_data->ops.vidioc_g_input = vidioc_g_input; 825 vv_data->vid_ops.vidioc_g_input = vidioc_g_input;
807 vv_data->ops.vidioc_s_input = vidioc_s_input; 826 vv_data->vid_ops.vidioc_s_input = vidioc_s_input;
808 vv_data->ops.vidioc_g_tuner = vidioc_g_tuner; 827 vv_data->vid_ops.vidioc_g_tuner = vidioc_g_tuner;
809 vv_data->ops.vidioc_s_tuner = vidioc_s_tuner; 828 vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner;
810 vv_data->ops.vidioc_g_frequency = vidioc_g_frequency; 829 vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency;
811 vv_data->ops.vidioc_s_frequency = vidioc_s_frequency; 830 vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency;
812 vv_data->ops.vidioc_g_audio = vidioc_g_audio; 831 vv_data->vid_ops.vidioc_enumaudio = vidioc_enumaudio;
813 vv_data->ops.vidioc_s_audio = vidioc_s_audio; 832 vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio;
814 vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap; 833 vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio;
815 vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out; 834 vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL;
816 vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out; 835
836 vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner;
837 vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner;
838 vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency;
839 vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency;
840 vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL;
841 vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
842 vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
843 vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
844
845 if (FW_VERSION(av7110->arm_app) < 0x2623)
846 vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;
817 847
818 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { 848 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
819 ERR("cannot register capture device. skipping\n"); 849 ERR("cannot register capture device. skipping\n");
820 saa7146_vv_release(dev); 850 saa7146_vv_release(dev);
821 return -ENODEV; 851 return -ENODEV;
822 } 852 }
823 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) 853 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
824 ERR("cannot register vbi v4l2 device. skipping\n"); 854 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI))
855 ERR("cannot register vbi v4l2 device. skipping\n");
856 }
825 return 0; 857 return 0;
826} 858}
827 859
@@ -905,7 +937,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
905static struct saa7146_ext_vv av7110_vv_data_st = { 937static struct saa7146_ext_vv av7110_vv_data_st = {
906 .inputs = 1, 938 .inputs = 1,
907 .audios = 1, 939 .audios = 1,
908 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT, 940 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
909 .flags = 0, 941 .flags = 0,
910 942
911 .stds = &standard[0], 943 .stds = &standard[0],
@@ -920,7 +952,7 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
920static struct saa7146_ext_vv av7110_vv_data_c = { 952static struct saa7146_ext_vv av7110_vv_data_c = {
921 .inputs = 1, 953 .inputs = 1,
922 .audios = 1, 954 .audios = 1,
923 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT, 955 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
924 .flags = SAA7146_USE_PORT_B_FOR_VBI, 956 .flags = SAA7146_USE_PORT_B_FOR_VBI,
925 957
926 .stds = &standard[0], 958 .stds = &standard[0],
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 8b32e282bf5d..12ddb53c58dc 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1483,9 +1483,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1483 ERR("cannot init vv subsystem\n"); 1483 ERR("cannot init vv subsystem\n");
1484 return err; 1484 return err;
1485 } 1485 }
1486 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 1486 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
1487 vv_data.ops.vidioc_g_input = vidioc_g_input; 1487 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
1488 vv_data.ops.vidioc_s_input = vidioc_s_input; 1488 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
1489 1489
1490 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { 1490 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1491 /* fixme: proper cleanup here */ 1491 /* fixme: proper cleanup here */
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 056138f63c7d..e1cd13283407 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -214,23 +214,76 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
214 * pipeline pointer must be identical for all nested calls to 214 * pipeline pointer must be identical for all nested calls to
215 * media_entity_pipeline_start(). 215 * media_entity_pipeline_start().
216 */ 216 */
217void media_entity_pipeline_start(struct media_entity *entity, 217__must_check int media_entity_pipeline_start(struct media_entity *entity,
218 struct media_pipeline *pipe) 218 struct media_pipeline *pipe)
219{ 219{
220 struct media_device *mdev = entity->parent; 220 struct media_device *mdev = entity->parent;
221 struct media_entity_graph graph; 221 struct media_entity_graph graph;
222 struct media_entity *entity_err = entity;
223 int ret;
222 224
223 mutex_lock(&mdev->graph_mutex); 225 mutex_lock(&mdev->graph_mutex);
224 226
225 media_entity_graph_walk_start(&graph, entity); 227 media_entity_graph_walk_start(&graph, entity);
226 228
227 while ((entity = media_entity_graph_walk_next(&graph))) { 229 while ((entity = media_entity_graph_walk_next(&graph))) {
230 unsigned int i;
231
228 entity->stream_count++; 232 entity->stream_count++;
229 WARN_ON(entity->pipe && entity->pipe != pipe); 233 WARN_ON(entity->pipe && entity->pipe != pipe);
230 entity->pipe = pipe; 234 entity->pipe = pipe;
235
236 /* Already streaming --- no need to check. */
237 if (entity->stream_count > 1)
238 continue;
239
240 if (!entity->ops || !entity->ops->link_validate)
241 continue;
242
243 for (i = 0; i < entity->num_links; i++) {
244 struct media_link *link = &entity->links[i];
245
246 /* Is this pad part of an enabled link? */
247 if (!(link->flags & MEDIA_LNK_FL_ENABLED))
248 continue;
249
250 /* Are we the sink or not? */
251 if (link->sink->entity != entity)
252 continue;
253
254 ret = entity->ops->link_validate(link);
255 if (ret < 0 && ret != -ENOIOCTLCMD)
256 goto error;
257 }
231 } 258 }
232 259
233 mutex_unlock(&mdev->graph_mutex); 260 mutex_unlock(&mdev->graph_mutex);
261
262 return 0;
263
264error:
265 /*
266 * Link validation on graph failed. We revert what we did and
267 * return the error.
268 */
269 media_entity_graph_walk_start(&graph, entity_err);
270
271 while ((entity_err = media_entity_graph_walk_next(&graph))) {
272 entity_err->stream_count--;
273 if (entity_err->stream_count == 0)
274 entity_err->pipe = NULL;
275
276 /*
277 * We haven't increased stream_count further than this
278 * so we quit here.
279 */
280 if (entity_err == entity)
281 break;
282 }
283
284 mutex_unlock(&mdev->graph_mutex);
285
286 return ret;
234} 287}
235EXPORT_SYMBOL_GPL(media_entity_pipeline_start); 288EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
236 289
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 8db2d7f4b52a..c257da13d766 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -320,7 +320,7 @@ config RADIO_MIROPCM20
320 module will be called radio-miropcm20. 320 module will be called radio-miropcm20.
321 321
322config RADIO_SF16FMI 322config RADIO_SF16FMI
323 tristate "SF16-FMI/SF16-FMP Radio" 323 tristate "SF16-FMI/SF16-FMP/SF16-FMD Radio"
324 depends on ISA && VIDEO_V4L2 324 depends on ISA && VIDEO_V4L2
325 ---help--- 325 ---help---
326 Choose Y here if you have one of these FM radio cards. 326 Choose Y here if you have one of these FM radio cards.
@@ -329,7 +329,7 @@ config RADIO_SF16FMI
329 module will be called radio-sf16fmi. 329 module will be called radio-sf16fmi.
330 330
331config RADIO_SF16FMR2 331config RADIO_SF16FMR2
332 tristate "SF16FMR2 Radio" 332 tristate "SF16-FMR2/SF16-FMD2 Radio"
333 depends on ISA && VIDEO_V4L2 && SND 333 depends on ISA && VIDEO_V4L2 && SND
334 ---help--- 334 ---help---
335 Choose Y here if you have one of these FM radio cards. 335 Choose Y here if you have one of these FM radio cards.
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index f36905b63645..63b112b555b2 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -1,92 +1,37 @@
1/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21. 1/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21.
2 The device plugs into both the USB and an analog audio input, so this thing 2 * The device plugs into both the USB and an analog audio input, so this thing
3 only deals with initialisation and frequency setting, the 3 * only deals with initialisation and frequency setting, the
4 audio data has to be handled by a sound driver. 4 * audio data has to be handled by a sound driver.
5 5 *
6 Major issue: I can't find out where the device reports the signal 6 * Major issue: I can't find out where the device reports the signal
7 strength, and indeed the windows software appearantly just looks 7 * strength, and indeed the windows software appearantly just looks
8 at the stereo indicator as well. So, scanning will only find 8 * at the stereo indicator as well. So, scanning will only find
9 stereo stations. Sad, but I can't help it. 9 * stereo stations. Sad, but I can't help it.
10 10 *
11 Also, the windows program sends oodles of messages over to the 11 * Also, the windows program sends oodles of messages over to the
12 device, and I couldn't figure out their meaning. My suspicion 12 * device, and I couldn't figure out their meaning. My suspicion
13 is that they don't have any:-) 13 * is that they don't have any:-)
14 14 *
15 You might find some interesting stuff about this module at 15 * You might find some interesting stuff about this module at
16 http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr 16 * http://unimut.fsk.uni-heidelberg.de/unimut/demi/dsbr
17 17 *
18 Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.de> 18 * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
19 19 *
20 This program is free software; you can redistribute it and/or modify 20 * Copyright (c) 2000 Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
21 it under the terms of the GNU General Public License as published by 21 *
22 the Free Software Foundation; either version 2 of the License, or 22 * This program is free software; you can redistribute it and/or modify
23 (at your option) any later version. 23 * it under the terms of the GNU General Public License as published by
24 24 * the Free Software Foundation; either version 2 of the License, or
25 This program is distributed in the hope that it will be useful, 25 * (at your option) any later version.
26 but WITHOUT ANY WARRANTY; without even the implied warranty of 26 *
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * This program is distributed in the hope that it will be useful,
28 GNU General Public License for more details. 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 You should have received a copy of the GNU General Public License 30 * GNU General Public License for more details.
31 along with this program; if not, write to the Free Software 31 *
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32 * You should have received a copy of the GNU General Public License
33 33 * along with this program; if not, write to the Free Software
34 History: 34 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35
36 Version 0.46:
37 Removed usb_dsbr100_open/close calls and radio->users counter. Also,
38 radio->muted changed to radio->status and suspend/resume calls updated.
39
40 Version 0.45:
41 Converted to v4l2_device.
42
43 Version 0.44:
44 Add suspend/resume functions, fix unplug of device,
45 a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
46
47 Version 0.43:
48 Oliver Neukum: avoided DMA coherency issue
49
50 Version 0.42:
51 Converted dsbr100 to use video_ioctl2
52 by Douglas Landgraf <dougsland@gmail.com>
53
54 Version 0.41-ac1:
55 Alan Cox: Some cleanups and fixes
56
57 Version 0.41:
58 Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
59
60 Version 0.40:
61 Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
62
63 Version 0.30:
64 Markus: Updates for 2.5.x kernel and more ISO compliant source
65
66 Version 0.25:
67 PSL and Markus: Cleanup, radio now doesn't stop on device close
68
69 Version 0.24:
70 Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
71 right. Some minor cleanup, improved standalone compilation
72
73 Version 0.23:
74 Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
75
76 Version 0.22:
77 Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
78 thanks to Mike Cox for pointing the problem out.
79
80 Version 0.21:
81 Markus: Minor cleanup, warnings if something goes wrong, lame attempt
82 to adhere to Documentation/CodingStyle
83
84 Version 0.2:
85 Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
86 Markus: Copyright clarification
87
88 Version 0.01: Markus: initial release
89
90*/ 35*/
91 36
92#include <linux/kernel.h> 37#include <linux/kernel.h>
@@ -95,17 +40,19 @@
95#include <linux/slab.h> 40#include <linux/slab.h>
96#include <linux/input.h> 41#include <linux/input.h>
97#include <linux/videodev2.h> 42#include <linux/videodev2.h>
43#include <linux/usb.h>
98#include <media/v4l2-device.h> 44#include <media/v4l2-device.h>
99#include <media/v4l2-ioctl.h> 45#include <media/v4l2-ioctl.h>
100#include <linux/usb.h> 46#include <media/v4l2-ctrls.h>
47#include <media/v4l2-event.h>
101 48
102/* 49/*
103 * Version Information 50 * Version Information
104 */ 51 */
105#define DRIVER_VERSION "0.4.7" 52MODULE_AUTHOR("Markus Demleitner <msdemlei@tucana.harvard.edu>");
106 53MODULE_DESCRIPTION("D-Link DSB-R100 USB FM radio driver");
107#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" 54MODULE_LICENSE("GPL");
108#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" 55MODULE_VERSION("1.1.0");
109 56
110#define DSB100_VENDOR 0x04b4 57#define DSB100_VENDOR 0x04b4
111#define DSB100_PRODUCT 0x1002 58#define DSB100_PRODUCT 0x1002
@@ -122,19 +69,8 @@ devices, that would be 76 and 91. */
122#define FREQ_MAX 108.0 69#define FREQ_MAX 108.0
123#define FREQ_MUL 16000 70#define FREQ_MUL 16000
124 71
125/* defines for radio->status */
126#define STARTED 0
127#define STOPPED 1
128
129#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev) 72#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev)
130 73
131static int usb_dsbr100_probe(struct usb_interface *intf,
132 const struct usb_device_id *id);
133static void usb_dsbr100_disconnect(struct usb_interface *intf);
134static int usb_dsbr100_suspend(struct usb_interface *intf,
135 pm_message_t message);
136static int usb_dsbr100_resume(struct usb_interface *intf);
137
138static int radio_nr = -1; 74static int radio_nr = -1;
139module_param(radio_nr, int, 0); 75module_param(radio_nr, int, 0);
140 76
@@ -143,179 +79,92 @@ struct dsbr100_device {
143 struct usb_device *usbdev; 79 struct usb_device *usbdev;
144 struct video_device videodev; 80 struct video_device videodev;
145 struct v4l2_device v4l2_dev; 81 struct v4l2_device v4l2_dev;
82 struct v4l2_ctrl_handler hdl;
146 83
147 u8 *transfer_buffer; 84 u8 *transfer_buffer;
148 struct mutex v4l2_lock; 85 struct mutex v4l2_lock;
149 int curfreq; 86 int curfreq;
150 int stereo; 87 bool stereo;
151 int status; 88 bool muted;
152};
153
154static struct usb_device_id usb_dsbr100_device_table [] = {
155 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
156 { } /* Terminating entry */
157};
158
159MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table);
160
161/* USB subsystem interface */
162static struct usb_driver usb_dsbr100_driver = {
163 .name = "dsbr100",
164 .probe = usb_dsbr100_probe,
165 .disconnect = usb_dsbr100_disconnect,
166 .id_table = usb_dsbr100_device_table,
167 .suspend = usb_dsbr100_suspend,
168 .resume = usb_dsbr100_resume,
169 .reset_resume = usb_dsbr100_resume,
170 .supports_autosuspend = 0,
171}; 89};
172 90
173/* Low-level device interface begins here */ 91/* Low-level device interface begins here */
174 92
175/* switch on radio */ 93/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
176static int dsbr100_start(struct dsbr100_device *radio) 94static int dsbr100_setfreq(struct dsbr100_device *radio, unsigned freq)
177{ 95{
178 int retval; 96 unsigned f = (freq / 16 * 80) / 1000 + 856;
179 int request; 97 int retval = 0;
180 98
181 retval = usb_control_msg(radio->usbdev, 99 if (!radio->muted) {
182 usb_rcvctrlpipe(radio->usbdev, 0), 100 retval = usb_control_msg(radio->usbdev,
183 USB_REQ_GET_STATUS, 101 usb_rcvctrlpipe(radio->usbdev, 0),
184 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 102 DSB100_TUNE,
185 0x00, 0xC7, radio->transfer_buffer, 8, 300); 103 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
186 104 (f >> 8) & 0x00ff, f & 0xff,
187 if (retval < 0) { 105 radio->transfer_buffer, 8, 300);
188 request = USB_REQ_GET_STATUS; 106 if (retval >= 0)
189 goto usb_control_msg_failed; 107 mdelay(1);
190 } 108 }
191 109
192 retval = usb_control_msg(radio->usbdev, 110 if (retval >= 0) {
193 usb_rcvctrlpipe(radio->usbdev, 0), 111 radio->curfreq = freq;
194 DSB100_ONOFF, 112 return 0;
195 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
196 0x01, 0x00, radio->transfer_buffer, 8, 300);
197
198 if (retval < 0) {
199 request = DSB100_ONOFF;
200 goto usb_control_msg_failed;
201 } 113 }
202
203 radio->status = STARTED;
204 return (radio->transfer_buffer)[0];
205
206usb_control_msg_failed:
207 dev_err(&radio->usbdev->dev, 114 dev_err(&radio->usbdev->dev,
208 "%s - usb_control_msg returned %i, request %i\n", 115 "%s - usb_control_msg returned %i, request %i\n",
209 __func__, retval, request); 116 __func__, retval, DSB100_TUNE);
210 return retval; 117 return retval;
211
212} 118}
213 119
214/* switch off radio */ 120/* switch on radio */
215static int dsbr100_stop(struct dsbr100_device *radio) 121static int dsbr100_start(struct dsbr100_device *radio)
216{ 122{
217 int retval; 123 int retval = usb_control_msg(radio->usbdev,
218 int request;
219
220 retval = usb_control_msg(radio->usbdev,
221 usb_rcvctrlpipe(radio->usbdev, 0),
222 USB_REQ_GET_STATUS,
223 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
224 0x16, 0x1C, radio->transfer_buffer, 8, 300);
225
226 if (retval < 0) {
227 request = USB_REQ_GET_STATUS;
228 goto usb_control_msg_failed;
229 }
230
231 retval = usb_control_msg(radio->usbdev,
232 usb_rcvctrlpipe(radio->usbdev, 0), 124 usb_rcvctrlpipe(radio->usbdev, 0),
233 DSB100_ONOFF, 125 DSB100_ONOFF,
234 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 126 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
235 0x00, 0x00, radio->transfer_buffer, 8, 300); 127 0x01, 0x00, radio->transfer_buffer, 8, 300);
236
237 if (retval < 0) {
238 request = DSB100_ONOFF;
239 goto usb_control_msg_failed;
240 }
241
242 radio->status = STOPPED;
243 return (radio->transfer_buffer)[0];
244 128
245usb_control_msg_failed: 129 if (retval >= 0)
130 return dsbr100_setfreq(radio, radio->curfreq);
246 dev_err(&radio->usbdev->dev, 131 dev_err(&radio->usbdev->dev,
247 "%s - usb_control_msg returned %i, request %i\n", 132 "%s - usb_control_msg returned %i, request %i\n",
248 __func__, retval, request); 133 __func__, retval, DSB100_ONOFF);
249 return retval; 134 return retval;
250 135
251} 136}
252 137
253/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 138/* switch off radio */
254static int dsbr100_setfreq(struct dsbr100_device *radio) 139static int dsbr100_stop(struct dsbr100_device *radio)
255{ 140{
256 int retval; 141 int retval = usb_control_msg(radio->usbdev,
257 int request;
258 int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
259
260 retval = usb_control_msg(radio->usbdev,
261 usb_rcvctrlpipe(radio->usbdev, 0),
262 DSB100_TUNE,
263 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
264 (freq >> 8) & 0x00ff, freq & 0xff,
265 radio->transfer_buffer, 8, 300);
266
267 if (retval < 0) {
268 request = DSB100_TUNE;
269 goto usb_control_msg_failed;
270 }
271
272 retval = usb_control_msg(radio->usbdev,
273 usb_rcvctrlpipe(radio->usbdev, 0), 142 usb_rcvctrlpipe(radio->usbdev, 0),
274 USB_REQ_GET_STATUS, 143 DSB100_ONOFF,
275 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 144 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
276 0x96, 0xB7, radio->transfer_buffer, 8, 300); 145 0x00, 0x00, radio->transfer_buffer, 8, 300);
277
278 if (retval < 0) {
279 request = USB_REQ_GET_STATUS;
280 goto usb_control_msg_failed;
281 }
282
283 retval = usb_control_msg(radio->usbdev,
284 usb_rcvctrlpipe(radio->usbdev, 0),
285 USB_REQ_GET_STATUS,
286 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
287 0x00, 0x24, radio->transfer_buffer, 8, 300);
288
289 if (retval < 0) {
290 request = USB_REQ_GET_STATUS;
291 goto usb_control_msg_failed;
292 }
293
294 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
295 return (radio->transfer_buffer)[0];
296 146
297usb_control_msg_failed: 147 if (retval >= 0)
298 radio->stereo = -1; 148 return 0;
299 dev_err(&radio->usbdev->dev, 149 dev_err(&radio->usbdev->dev,
300 "%s - usb_control_msg returned %i, request %i\n", 150 "%s - usb_control_msg returned %i, request %i\n",
301 __func__, retval, request); 151 __func__, retval, DSB100_ONOFF);
302 return retval; 152 return retval;
153
303} 154}
304 155
305/* return the device status. This is, in effect, just whether it 156/* return the device status. This is, in effect, just whether it
306sees a stereo signal or not. Pity. */ 157sees a stereo signal or not. Pity. */
307static void dsbr100_getstat(struct dsbr100_device *radio) 158static void dsbr100_getstat(struct dsbr100_device *radio)
308{ 159{
309 int retval; 160 int retval = usb_control_msg(radio->usbdev,
310
311 retval = usb_control_msg(radio->usbdev,
312 usb_rcvctrlpipe(radio->usbdev, 0), 161 usb_rcvctrlpipe(radio->usbdev, 0),
313 USB_REQ_GET_STATUS, 162 USB_REQ_GET_STATUS,
314 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 163 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
315 0x00 , 0x24, radio->transfer_buffer, 8, 300); 164 0x00, 0x24, radio->transfer_buffer, 8, 300);
316 165
317 if (retval < 0) { 166 if (retval < 0) {
318 radio->stereo = -1; 167 radio->stereo = false;
319 dev_err(&radio->usbdev->dev, 168 dev_err(&radio->usbdev->dev,
320 "%s - usb_control_msg returned %i, request %i\n", 169 "%s - usb_control_msg returned %i, request %i\n",
321 __func__, retval, USB_REQ_GET_STATUS); 170 __func__, retval, USB_REQ_GET_STATUS);
@@ -332,7 +181,8 @@ static int vidioc_querycap(struct file *file, void *priv,
332 strlcpy(v->driver, "dsbr100", sizeof(v->driver)); 181 strlcpy(v->driver, "dsbr100", sizeof(v->driver));
333 strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card)); 182 strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
334 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); 183 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
335 v->capabilities = V4L2_CAP_TUNER; 184 v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
185 v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
336 return 0; 186 return 0;
337} 187}
338 188
@@ -349,13 +199,11 @@ static int vidioc_g_tuner(struct file *file, void *priv,
349 v->type = V4L2_TUNER_RADIO; 199 v->type = V4L2_TUNER_RADIO;
350 v->rangelow = FREQ_MIN * FREQ_MUL; 200 v->rangelow = FREQ_MIN * FREQ_MUL;
351 v->rangehigh = FREQ_MAX * FREQ_MUL; 201 v->rangehigh = FREQ_MAX * FREQ_MUL;
352 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 202 v->rxsubchans = radio->stereo ? V4L2_TUNER_SUB_STEREO :
353 v->capability = V4L2_TUNER_CAP_LOW; 203 V4L2_TUNER_SUB_MONO;
354 if(radio->stereo) 204 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
355 v->audmode = V4L2_TUNER_MODE_STEREO; 205 v->audmode = V4L2_TUNER_MODE_STEREO;
356 else 206 v->signal = radio->stereo ? 0xffff : 0; /* We can't get the signal strength */
357 v->audmode = V4L2_TUNER_MODE_MONO;
358 v->signal = 0xffff; /* We can't get the signal strength */
359 return 0; 207 return 0;
360} 208}
361 209
@@ -369,14 +217,12 @@ static int vidioc_s_frequency(struct file *file, void *priv,
369 struct v4l2_frequency *f) 217 struct v4l2_frequency *f)
370{ 218{
371 struct dsbr100_device *radio = video_drvdata(file); 219 struct dsbr100_device *radio = video_drvdata(file);
372 int retval;
373 220
374 radio->curfreq = f->frequency; 221 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
222 return -EINVAL;
375 223
376 retval = dsbr100_setfreq(radio); 224 return dsbr100_setfreq(radio, clamp_t(unsigned, f->frequency,
377 if (retval < 0) 225 FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL));
378 dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
379 return 0;
380} 226}
381 227
382static int vidioc_g_frequency(struct file *file, void *priv, 228static int vidioc_g_frequency(struct file *file, void *priv,
@@ -384,90 +230,26 @@ static int vidioc_g_frequency(struct file *file, void *priv,
384{ 230{
385 struct dsbr100_device *radio = video_drvdata(file); 231 struct dsbr100_device *radio = video_drvdata(file);
386 232
233 if (f->tuner)
234 return -EINVAL;
387 f->type = V4L2_TUNER_RADIO; 235 f->type = V4L2_TUNER_RADIO;
388 f->frequency = radio->curfreq; 236 f->frequency = radio->curfreq;
389 return 0; 237 return 0;
390} 238}
391 239
392static int vidioc_queryctrl(struct file *file, void *priv, 240static int usb_dsbr100_s_ctrl(struct v4l2_ctrl *ctrl)
393 struct v4l2_queryctrl *qc)
394{
395 switch (qc->id) {
396 case V4L2_CID_AUDIO_MUTE:
397 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
398 }
399
400 return -EINVAL;
401}
402
403static int vidioc_g_ctrl(struct file *file, void *priv,
404 struct v4l2_control *ctrl)
405{ 241{
406 struct dsbr100_device *radio = video_drvdata(file); 242 struct dsbr100_device *radio =
243 container_of(ctrl->handler, struct dsbr100_device, hdl);
407 244
408 switch (ctrl->id) { 245 switch (ctrl->id) {
409 case V4L2_CID_AUDIO_MUTE: 246 case V4L2_CID_AUDIO_MUTE:
410 ctrl->value = radio->status; 247 radio->muted = ctrl->val;
411 return 0; 248 return radio->muted ? dsbr100_stop(radio) : dsbr100_start(radio);
412 } 249 }
413 return -EINVAL; 250 return -EINVAL;
414} 251}
415 252
416static int vidioc_s_ctrl(struct file *file, void *priv,
417 struct v4l2_control *ctrl)
418{
419 struct dsbr100_device *radio = video_drvdata(file);
420 int retval;
421
422 switch (ctrl->id) {
423 case V4L2_CID_AUDIO_MUTE:
424 if (ctrl->value) {
425 retval = dsbr100_stop(radio);
426 if (retval < 0) {
427 dev_warn(&radio->usbdev->dev,
428 "Radio did not respond properly\n");
429 return -EBUSY;
430 }
431 } else {
432 retval = dsbr100_start(radio);
433 if (retval < 0) {
434 dev_warn(&radio->usbdev->dev,
435 "Radio did not respond properly\n");
436 return -EBUSY;
437 }
438 }
439 return 0;
440 }
441 return -EINVAL;
442}
443
444static int vidioc_g_audio(struct file *file, void *priv,
445 struct v4l2_audio *a)
446{
447 if (a->index > 1)
448 return -EINVAL;
449
450 strcpy(a->name, "Radio");
451 a->capability = V4L2_AUDCAP_STEREO;
452 return 0;
453}
454
455static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
456{
457 *i = 0;
458 return 0;
459}
460
461static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
462{
463 return i ? -EINVAL : 0;
464}
465
466static int vidioc_s_audio(struct file *file, void *priv,
467 struct v4l2_audio *a)
468{
469 return a->index ? -EINVAL : 0;
470}
471 253
472/* USB subsystem interface begins here */ 254/* USB subsystem interface begins here */
473 255
@@ -481,8 +263,17 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
481{ 263{
482 struct dsbr100_device *radio = usb_get_intfdata(intf); 264 struct dsbr100_device *radio = usb_get_intfdata(intf);
483 265
484 v4l2_device_get(&radio->v4l2_dev);
485 mutex_lock(&radio->v4l2_lock); 266 mutex_lock(&radio->v4l2_lock);
267 /*
268 * Disconnect is also called on unload, and in that case we need to
269 * mute the device. This call will silently fail if it is called
270 * after a physical disconnect.
271 */
272 usb_control_msg(radio->usbdev,
273 usb_rcvctrlpipe(radio->usbdev, 0),
274 DSB100_ONOFF,
275 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
276 0x00, 0x00, radio->transfer_buffer, 8, 300);
486 usb_set_intfdata(intf, NULL); 277 usb_set_intfdata(intf, NULL);
487 video_unregister_device(&radio->videodev); 278 video_unregister_device(&radio->videodev);
488 v4l2_device_disconnect(&radio->v4l2_dev); 279 v4l2_device_disconnect(&radio->v4l2_dev);
@@ -495,25 +286,13 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
495static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) 286static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
496{ 287{
497 struct dsbr100_device *radio = usb_get_intfdata(intf); 288 struct dsbr100_device *radio = usb_get_intfdata(intf);
498 int retval;
499 289
500 mutex_lock(&radio->v4l2_lock); 290 mutex_lock(&radio->v4l2_lock);
501 if (radio->status == STARTED) { 291 if (!radio->muted && dsbr100_stop(radio) < 0)
502 retval = dsbr100_stop(radio); 292 dev_warn(&intf->dev, "dsbr100_stop failed\n");
503 if (retval < 0)
504 dev_warn(&intf->dev, "dsbr100_stop failed\n");
505
506 /* After dsbr100_stop() status set to STOPPED.
507 * If we want driver to start radio on resume
508 * we set status equal to STARTED.
509 * On resume we will check status and run radio if needed.
510 */
511 radio->status = STARTED;
512 }
513 mutex_unlock(&radio->v4l2_lock); 293 mutex_unlock(&radio->v4l2_lock);
514 294
515 dev_info(&intf->dev, "going into suspend..\n"); 295 dev_info(&intf->dev, "going into suspend..\n");
516
517 return 0; 296 return 0;
518} 297}
519 298
@@ -521,18 +300,13 @@ static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
521static int usb_dsbr100_resume(struct usb_interface *intf) 300static int usb_dsbr100_resume(struct usb_interface *intf)
522{ 301{
523 struct dsbr100_device *radio = usb_get_intfdata(intf); 302 struct dsbr100_device *radio = usb_get_intfdata(intf);
524 int retval;
525 303
526 mutex_lock(&radio->v4l2_lock); 304 mutex_lock(&radio->v4l2_lock);
527 if (radio->status == STARTED) { 305 if (!radio->muted && dsbr100_start(radio) < 0)
528 retval = dsbr100_start(radio); 306 dev_warn(&intf->dev, "dsbr100_start failed\n");
529 if (retval < 0)
530 dev_warn(&intf->dev, "dsbr100_start failed\n");
531 }
532 mutex_unlock(&radio->v4l2_lock); 307 mutex_unlock(&radio->v4l2_lock);
533 308
534 dev_info(&intf->dev, "coming out of suspend..\n"); 309 dev_info(&intf->dev, "coming out of suspend..\n");
535
536 return 0; 310 return 0;
537} 311}
538 312
@@ -541,15 +315,23 @@ static void usb_dsbr100_release(struct v4l2_device *v4l2_dev)
541{ 315{
542 struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev); 316 struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev);
543 317
318 v4l2_ctrl_handler_free(&radio->hdl);
544 v4l2_device_unregister(&radio->v4l2_dev); 319 v4l2_device_unregister(&radio->v4l2_dev);
545 kfree(radio->transfer_buffer); 320 kfree(radio->transfer_buffer);
546 kfree(radio); 321 kfree(radio);
547} 322}
548 323
324static const struct v4l2_ctrl_ops usb_dsbr100_ctrl_ops = {
325 .s_ctrl = usb_dsbr100_s_ctrl,
326};
327
549/* File system interface */ 328/* File system interface */
550static const struct v4l2_file_operations usb_dsbr100_fops = { 329static const struct v4l2_file_operations usb_dsbr100_fops = {
551 .owner = THIS_MODULE, 330 .owner = THIS_MODULE,
552 .unlocked_ioctl = video_ioctl2, 331 .unlocked_ioctl = video_ioctl2,
332 .open = v4l2_fh_open,
333 .release = v4l2_fh_release,
334 .poll = v4l2_ctrl_poll,
553}; 335};
554 336
555static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { 337static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
@@ -558,13 +340,9 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
558 .vidioc_s_tuner = vidioc_s_tuner, 340 .vidioc_s_tuner = vidioc_s_tuner,
559 .vidioc_g_frequency = vidioc_g_frequency, 341 .vidioc_g_frequency = vidioc_g_frequency,
560 .vidioc_s_frequency = vidioc_s_frequency, 342 .vidioc_s_frequency = vidioc_s_frequency,
561 .vidioc_queryctrl = vidioc_queryctrl, 343 .vidioc_log_status = v4l2_ctrl_log_status,
562 .vidioc_g_ctrl = vidioc_g_ctrl, 344 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
563 .vidioc_s_ctrl = vidioc_s_ctrl, 345 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
564 .vidioc_g_audio = vidioc_g_audio,
565 .vidioc_s_audio = vidioc_s_audio,
566 .vidioc_g_input = vidioc_g_input,
567 .vidioc_s_input = vidioc_s_input,
568}; 346};
569 347
570/* check if the device is present and register with v4l and usb if it is */ 348/* check if the device is present and register with v4l and usb if it is */
@@ -593,11 +371,17 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
593 retval = v4l2_device_register(&intf->dev, v4l2_dev); 371 retval = v4l2_device_register(&intf->dev, v4l2_dev);
594 if (retval < 0) { 372 if (retval < 0) {
595 v4l2_err(v4l2_dev, "couldn't register v4l2_device\n"); 373 v4l2_err(v4l2_dev, "couldn't register v4l2_device\n");
596 kfree(radio->transfer_buffer); 374 goto err_reg_dev;
597 kfree(radio);
598 return retval;
599 } 375 }
600 376
377 v4l2_ctrl_handler_init(&radio->hdl, 1);
378 v4l2_ctrl_new_std(&radio->hdl, &usb_dsbr100_ctrl_ops,
379 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
380 if (radio->hdl.error) {
381 retval = radio->hdl.error;
382 v4l2_err(v4l2_dev, "couldn't register control\n");
383 goto err_reg_ctrl;
384 }
601 mutex_init(&radio->v4l2_lock); 385 mutex_init(&radio->v4l2_lock);
602 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name)); 386 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
603 radio->videodev.v4l2_dev = v4l2_dev; 387 radio->videodev.v4l2_dev = v4l2_dev;
@@ -605,28 +389,46 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
605 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; 389 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
606 radio->videodev.release = video_device_release_empty; 390 radio->videodev.release = video_device_release_empty;
607 radio->videodev.lock = &radio->v4l2_lock; 391 radio->videodev.lock = &radio->v4l2_lock;
392 radio->videodev.ctrl_handler = &radio->hdl;
393 set_bit(V4L2_FL_USE_FH_PRIO, &radio->videodev.flags);
608 394
609 radio->usbdev = interface_to_usbdev(intf); 395 radio->usbdev = interface_to_usbdev(intf);
610 radio->curfreq = FREQ_MIN * FREQ_MUL; 396 radio->curfreq = FREQ_MIN * FREQ_MUL;
611 radio->status = STOPPED; 397 radio->muted = true;
612 398
613 video_set_drvdata(&radio->videodev, radio); 399 video_set_drvdata(&radio->videodev, radio);
400 usb_set_intfdata(intf, radio);
614 401
615 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr); 402 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
616 if (retval < 0) { 403 if (retval == 0)
617 v4l2_err(v4l2_dev, "couldn't register video device\n"); 404 return 0;
618 v4l2_device_unregister(v4l2_dev); 405 v4l2_err(v4l2_dev, "couldn't register video device\n");
619 kfree(radio->transfer_buffer); 406
620 kfree(radio); 407err_reg_ctrl:
621 return -EIO; 408 v4l2_ctrl_handler_free(&radio->hdl);
622 } 409 v4l2_device_unregister(v4l2_dev);
623 usb_set_intfdata(intf, radio); 410err_reg_dev:
624 return 0; 411 kfree(radio->transfer_buffer);
412 kfree(radio);
413 return retval;
625} 414}
626 415
627module_usb_driver(usb_dsbr100_driver); 416static struct usb_device_id usb_dsbr100_device_table[] = {
417 { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
418 { } /* Terminating entry */
419};
628 420
629MODULE_AUTHOR( DRIVER_AUTHOR ); 421MODULE_DEVICE_TABLE(usb, usb_dsbr100_device_table);
630MODULE_DESCRIPTION( DRIVER_DESC ); 422
631MODULE_LICENSE("GPL"); 423/* USB subsystem interface */
632MODULE_VERSION(DRIVER_VERSION); 424static struct usb_driver usb_dsbr100_driver = {
425 .name = "dsbr100",
426 .probe = usb_dsbr100_probe,
427 .disconnect = usb_dsbr100_disconnect,
428 .id_table = usb_dsbr100_device_table,
429 .suspend = usb_dsbr100_suspend,
430 .resume = usb_dsbr100_resume,
431 .reset_resume = usb_dsbr100_resume,
432};
433
434module_usb_driver(usb_dsbr100_driver);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 2e639ce6f256..235c0e349820 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -29,6 +29,7 @@
29#include <linux/videodev2.h> /* kernel radio structs */ 29#include <linux/videodev2.h> /* kernel radio structs */
30#include <linux/mutex.h> 30#include <linux/mutex.h>
31#include <linux/io.h> /* outb, outb_p */ 31#include <linux/io.h> /* outb, outb_p */
32#include <linux/pnp.h>
32#include <linux/slab.h> 33#include <linux/slab.h>
33#include <media/v4l2-ioctl.h> 34#include <media/v4l2-ioctl.h>
34#include <media/v4l2-device.h> 35#include <media/v4l2-device.h>
@@ -283,6 +284,16 @@ static const struct radio_isa_ops gemtek_ops = {
283 284
284static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }; 285static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
285 286
287#ifdef CONFIG_PNP
288static struct pnp_device_id gemtek_pnp_devices[] = {
289 /* AOpen FX-3D/Pro Radio */
290 {.id = "ADS7183", .driver_data = 0},
291 {.id = ""}
292};
293
294MODULE_DEVICE_TABLE(pnp, gemtek_pnp_devices);
295#endif
296
286static struct radio_isa_driver gemtek_driver = { 297static struct radio_isa_driver gemtek_driver = {
287 .driver = { 298 .driver = {
288 .match = radio_isa_match, 299 .match = radio_isa_match,
@@ -292,6 +303,14 @@ static struct radio_isa_driver gemtek_driver = {
292 .name = "radio-gemtek", 303 .name = "radio-gemtek",
293 }, 304 },
294 }, 305 },
306#ifdef CONFIG_PNP
307 .pnp_driver = {
308 .name = "radio-gemtek",
309 .id_table = gemtek_pnp_devices,
310 .probe = radio_isa_pnp_probe,
311 .remove = radio_isa_pnp_remove,
312 },
313#endif
295 .io_params = io, 314 .io_params = io,
296 .radio_nr_params = radio_nr, 315 .radio_nr_params = radio_nr,
297 .io_ports = gemtek_ioports, 316 .io_ports = gemtek_ioports,
@@ -305,12 +324,18 @@ static struct radio_isa_driver gemtek_driver = {
305static int __init gemtek_init(void) 324static int __init gemtek_init(void)
306{ 325{
307 gemtek_driver.probe = probe; 326 gemtek_driver.probe = probe;
327#ifdef CONFIG_PNP
328 pnp_register_driver(&gemtek_driver.pnp_driver);
329#endif
308 return isa_register_driver(&gemtek_driver.driver, GEMTEK_MAX); 330 return isa_register_driver(&gemtek_driver.driver, GEMTEK_MAX);
309} 331}
310 332
311static void __exit gemtek_exit(void) 333static void __exit gemtek_exit(void)
312{ 334{
313 hardmute = 1; /* Turn off PLL */ 335 hardmute = 1; /* Turn off PLL */
336#ifdef CONFIG_PNP
337 pnp_unregister_driver(&gemtek_driver.pnp_driver);
338#endif
314 isa_unregister_driver(&gemtek_driver.driver); 339 isa_unregister_driver(&gemtek_driver.driver);
315} 340}
316 341
diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c
index 06f906351fad..3c0067de4324 100644
--- a/drivers/media/radio/radio-isa.c
+++ b/drivers/media/radio/radio-isa.c
@@ -150,14 +150,6 @@ static int radio_isa_log_status(struct file *file, void *priv)
150 return 0; 150 return 0;
151} 151}
152 152
153static int radio_isa_subscribe_event(struct v4l2_fh *fh,
154 struct v4l2_event_subscription *sub)
155{
156 if (sub->type == V4L2_EVENT_CTRL)
157 return v4l2_event_subscribe(fh, sub, 0);
158 return -EINVAL;
159}
160
161static const struct v4l2_ctrl_ops radio_isa_ctrl_ops = { 153static const struct v4l2_ctrl_ops radio_isa_ctrl_ops = {
162 .s_ctrl = radio_isa_s_ctrl, 154 .s_ctrl = radio_isa_s_ctrl,
163}; 155};
@@ -177,7 +169,7 @@ static const struct v4l2_ioctl_ops radio_isa_ioctl_ops = {
177 .vidioc_g_frequency = radio_isa_g_frequency, 169 .vidioc_g_frequency = radio_isa_g_frequency,
178 .vidioc_s_frequency = radio_isa_s_frequency, 170 .vidioc_s_frequency = radio_isa_s_frequency,
179 .vidioc_log_status = radio_isa_log_status, 171 .vidioc_log_status = radio_isa_log_status,
180 .vidioc_subscribe_event = radio_isa_subscribe_event, 172 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
181 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 173 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
182}; 174};
183 175
@@ -199,56 +191,31 @@ static bool radio_isa_valid_io(const struct radio_isa_driver *drv, int io)
199 return false; 191 return false;
200} 192}
201 193
202int radio_isa_probe(struct device *pdev, unsigned int dev) 194struct radio_isa_card *radio_isa_alloc(struct radio_isa_driver *drv,
195 struct device *pdev)
203{ 196{
204 struct radio_isa_driver *drv = pdev->platform_data;
205 const struct radio_isa_ops *ops = drv->ops;
206 struct v4l2_device *v4l2_dev; 197 struct v4l2_device *v4l2_dev;
207 struct radio_isa_card *isa; 198 struct radio_isa_card *isa = drv->ops->alloc();
208 int res; 199 if (!isa)
200 return NULL;
209 201
210 isa = drv->ops->alloc();
211 if (isa == NULL)
212 return -ENOMEM;
213 dev_set_drvdata(pdev, isa); 202 dev_set_drvdata(pdev, isa);
214 isa->drv = drv; 203 isa->drv = drv;
215 isa->io = drv->io_params[dev];
216 v4l2_dev = &isa->v4l2_dev; 204 v4l2_dev = &isa->v4l2_dev;
217 strlcpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name)); 205 strlcpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name));
218 206
219 if (drv->probe && ops->probe) { 207 return isa;
220 int i; 208}
221
222 for (i = 0; i < drv->num_of_io_ports; ++i) {
223 int io = drv->io_ports[i];
224
225 if (request_region(io, drv->region_size, v4l2_dev->name)) {
226 bool found = ops->probe(isa, io);
227
228 release_region(io, drv->region_size);
229 if (found) {
230 isa->io = io;
231 break;
232 }
233 }
234 }
235 }
236
237 if (!radio_isa_valid_io(drv, isa->io)) {
238 int i;
239 209
240 if (isa->io < 0) 210int radio_isa_common_probe(struct radio_isa_card *isa, struct device *pdev,
241 return -ENODEV; 211 int radio_nr, unsigned region_size)
242 v4l2_err(v4l2_dev, "you must set an I/O address with io=0x%03x", 212{
243 drv->io_ports[0]); 213 const struct radio_isa_driver *drv = isa->drv;
244 for (i = 1; i < drv->num_of_io_ports; i++) 214 const struct radio_isa_ops *ops = drv->ops;
245 printk(KERN_CONT "/0x%03x", drv->io_ports[i]); 215 struct v4l2_device *v4l2_dev = &isa->v4l2_dev;
246 printk(KERN_CONT ".\n"); 216 int res;
247 kfree(isa);
248 return -EINVAL;
249 }
250 217
251 if (!request_region(isa->io, drv->region_size, v4l2_dev->name)) { 218 if (!request_region(isa->io, region_size, v4l2_dev->name)) {
252 v4l2_err(v4l2_dev, "port 0x%x already in use\n", isa->io); 219 v4l2_err(v4l2_dev, "port 0x%x already in use\n", isa->io);
253 kfree(isa); 220 kfree(isa);
254 return -EBUSY; 221 return -EBUSY;
@@ -299,42 +266,126 @@ int radio_isa_probe(struct device *pdev, unsigned int dev)
299 res = ops->s_stereo(isa, isa->stereo); 266 res = ops->s_stereo(isa, isa->stereo);
300 if (res < 0) { 267 if (res < 0) {
301 v4l2_err(v4l2_dev, "Could not setup card\n"); 268 v4l2_err(v4l2_dev, "Could not setup card\n");
302 goto err_node_reg; 269 goto err_hdl;
303 } 270 }
304 res = video_register_device(&isa->vdev, VFL_TYPE_RADIO, 271 res = video_register_device(&isa->vdev, VFL_TYPE_RADIO, radio_nr);
305 drv->radio_nr_params[dev]); 272
306 if (res < 0) { 273 if (res < 0) {
307 v4l2_err(v4l2_dev, "Could not register device node\n"); 274 v4l2_err(v4l2_dev, "Could not register device node\n");
308 goto err_node_reg; 275 goto err_hdl;
309 } 276 }
310 277
311 v4l2_info(v4l2_dev, "Initialized radio card %s on port 0x%03x\n", 278 v4l2_info(v4l2_dev, "Initialized radio card %s on port 0x%03x\n",
312 drv->card, isa->io); 279 drv->card, isa->io);
313 return 0; 280 return 0;
314 281
315err_node_reg:
316 v4l2_ctrl_handler_free(&isa->hdl);
317err_hdl: 282err_hdl:
318 v4l2_device_unregister(&isa->v4l2_dev); 283 v4l2_ctrl_handler_free(&isa->hdl);
319err_dev_reg: 284err_dev_reg:
320 release_region(isa->io, drv->region_size); 285 release_region(isa->io, region_size);
321 kfree(isa); 286 kfree(isa);
322 return res; 287 return res;
323} 288}
324EXPORT_SYMBOL_GPL(radio_isa_probe);
325 289
326int radio_isa_remove(struct device *pdev, unsigned int dev) 290int radio_isa_common_remove(struct radio_isa_card *isa, unsigned region_size)
327{ 291{
328 struct radio_isa_card *isa = dev_get_drvdata(pdev);
329 const struct radio_isa_ops *ops = isa->drv->ops; 292 const struct radio_isa_ops *ops = isa->drv->ops;
330 293
331 ops->s_mute_volume(isa, true, isa->volume ? isa->volume->cur.val : 0); 294 ops->s_mute_volume(isa, true, isa->volume ? isa->volume->cur.val : 0);
332 video_unregister_device(&isa->vdev); 295 video_unregister_device(&isa->vdev);
333 v4l2_ctrl_handler_free(&isa->hdl); 296 v4l2_ctrl_handler_free(&isa->hdl);
334 v4l2_device_unregister(&isa->v4l2_dev); 297 v4l2_device_unregister(&isa->v4l2_dev);
335 release_region(isa->io, isa->drv->region_size); 298 release_region(isa->io, region_size);
336 v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card); 299 v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card);
337 kfree(isa); 300 kfree(isa);
338 return 0; 301 return 0;
339} 302}
303
304int radio_isa_probe(struct device *pdev, unsigned int dev)
305{
306 struct radio_isa_driver *drv = pdev->platform_data;
307 const struct radio_isa_ops *ops = drv->ops;
308 struct v4l2_device *v4l2_dev;
309 struct radio_isa_card *isa;
310
311 isa = radio_isa_alloc(drv, pdev);
312 if (!isa)
313 return -ENOMEM;
314 isa->io = drv->io_params[dev];
315 v4l2_dev = &isa->v4l2_dev;
316
317 if (drv->probe && ops->probe) {
318 int i;
319
320 for (i = 0; i < drv->num_of_io_ports; ++i) {
321 int io = drv->io_ports[i];
322
323 if (request_region(io, drv->region_size, v4l2_dev->name)) {
324 bool found = ops->probe(isa, io);
325
326 release_region(io, drv->region_size);
327 if (found) {
328 isa->io = io;
329 break;
330 }
331 }
332 }
333 }
334
335 if (!radio_isa_valid_io(drv, isa->io)) {
336 int i;
337
338 if (isa->io < 0)
339 return -ENODEV;
340 v4l2_err(v4l2_dev, "you must set an I/O address with io=0x%03x",
341 drv->io_ports[0]);
342 for (i = 1; i < drv->num_of_io_ports; i++)
343 printk(KERN_CONT "/0x%03x", drv->io_ports[i]);
344 printk(KERN_CONT ".\n");
345 kfree(isa);
346 return -EINVAL;
347 }
348
349 return radio_isa_common_probe(isa, pdev, drv->radio_nr_params[dev],
350 drv->region_size);
351}
352EXPORT_SYMBOL_GPL(radio_isa_probe);
353
354int radio_isa_remove(struct device *pdev, unsigned int dev)
355{
356 struct radio_isa_card *isa = dev_get_drvdata(pdev);
357
358 return radio_isa_common_remove(isa, isa->drv->region_size);
359}
340EXPORT_SYMBOL_GPL(radio_isa_remove); 360EXPORT_SYMBOL_GPL(radio_isa_remove);
361
362#ifdef CONFIG_PNP
363int radio_isa_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
364{
365 struct pnp_driver *pnp_drv = to_pnp_driver(dev->dev.driver);
366 struct radio_isa_driver *drv = container_of(pnp_drv,
367 struct radio_isa_driver, pnp_driver);
368 struct radio_isa_card *isa;
369
370 if (!pnp_port_valid(dev, 0))
371 return -ENODEV;
372
373 isa = radio_isa_alloc(drv, &dev->dev);
374 if (!isa)
375 return -ENOMEM;
376
377 isa->io = pnp_port_start(dev, 0);
378
379 return radio_isa_common_probe(isa, &dev->dev, drv->radio_nr_params[0],
380 pnp_port_len(dev, 0));
381}
382EXPORT_SYMBOL_GPL(radio_isa_pnp_probe);
383
384void radio_isa_pnp_remove(struct pnp_dev *dev)
385{
386 struct radio_isa_card *isa = dev_get_drvdata(&dev->dev);
387
388 radio_isa_common_remove(isa, pnp_port_len(dev, 0));
389}
390EXPORT_SYMBOL_GPL(radio_isa_pnp_remove);
391#endif
diff --git a/drivers/media/radio/radio-isa.h b/drivers/media/radio/radio-isa.h
index 8a0ea84d86de..ba4c01f1bd0c 100644
--- a/drivers/media/radio/radio-isa.h
+++ b/drivers/media/radio/radio-isa.h
@@ -24,6 +24,7 @@
24#define _RADIO_ISA_H_ 24#define _RADIO_ISA_H_
25 25
26#include <linux/isa.h> 26#include <linux/isa.h>
27#include <linux/pnp.h>
27#include <linux/videodev2.h> 28#include <linux/videodev2.h>
28#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
29#include <media/v4l2-ctrls.h> 30#include <media/v4l2-ctrls.h>
@@ -76,6 +77,9 @@ struct radio_isa_ops {
76/* Top level structure needed to instantiate the cards */ 77/* Top level structure needed to instantiate the cards */
77struct radio_isa_driver { 78struct radio_isa_driver {
78 struct isa_driver driver; 79 struct isa_driver driver;
80#ifdef CONFIG_PNP
81 struct pnp_driver pnp_driver;
82#endif
79 const struct radio_isa_ops *ops; 83 const struct radio_isa_ops *ops;
80 /* The module_param_array with the specified I/O ports */ 84 /* The module_param_array with the specified I/O ports */
81 int *io_params; 85 int *io_params;
@@ -101,5 +105,10 @@ struct radio_isa_driver {
101int radio_isa_match(struct device *pdev, unsigned int dev); 105int radio_isa_match(struct device *pdev, unsigned int dev);
102int radio_isa_probe(struct device *pdev, unsigned int dev); 106int radio_isa_probe(struct device *pdev, unsigned int dev);
103int radio_isa_remove(struct device *pdev, unsigned int dev); 107int radio_isa_remove(struct device *pdev, unsigned int dev);
108#ifdef CONFIG_PNP
109int radio_isa_pnp_probe(struct pnp_dev *dev,
110 const struct pnp_device_id *dev_id);
111void radio_isa_pnp_remove(struct pnp_dev *dev);
112#endif
104 113
105#endif 114#endif
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index 55bd1d2937c8..79adf3e654e5 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -28,7 +28,6 @@
28#include <media/v4l2-ctrls.h> 28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-event.h> 29#include <media/v4l2-event.h>
30#include <linux/usb.h> 30#include <linux/usb.h>
31#include <linux/version.h>
32#include <linux/mutex.h> 31#include <linux/mutex.h>
33 32
34/* driver and module definitions */ 33/* driver and module definitions */
@@ -149,7 +148,6 @@ static void usb_keene_disconnect(struct usb_interface *intf)
149{ 148{
150 struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf)); 149 struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
151 150
152 v4l2_device_get(&radio->v4l2_dev);
153 mutex_lock(&radio->lock); 151 mutex_lock(&radio->lock);
154 usb_set_intfdata(intf, NULL); 152 usb_set_intfdata(intf, NULL);
155 video_unregister_device(&radio->vdev); 153 video_unregister_device(&radio->vdev);
@@ -158,6 +156,23 @@ static void usb_keene_disconnect(struct usb_interface *intf)
158 v4l2_device_put(&radio->v4l2_dev); 156 v4l2_device_put(&radio->v4l2_dev);
159} 157}
160 158
159static int usb_keene_suspend(struct usb_interface *intf, pm_message_t message)
160{
161 struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
162
163 return keene_cmd_main(radio, 0, false);
164}
165
166static int usb_keene_resume(struct usb_interface *intf)
167{
168 struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
169
170 mdelay(50);
171 keene_cmd_set(radio);
172 keene_cmd_main(radio, radio->curfreq, true);
173 return 0;
174}
175
161static int vidioc_querycap(struct file *file, void *priv, 176static int vidioc_querycap(struct file *file, void *priv,
162 struct v4l2_capability *v) 177 struct v4l2_capability *v)
163{ 178{
@@ -256,18 +271,6 @@ static int keene_s_ctrl(struct v4l2_ctrl *ctrl)
256 return -EINVAL; 271 return -EINVAL;
257} 272}
258 273
259static int vidioc_subscribe_event(struct v4l2_fh *fh,
260 struct v4l2_event_subscription *sub)
261{
262 switch (sub->type) {
263 case V4L2_EVENT_CTRL:
264 return v4l2_event_subscribe(fh, sub, 0);
265 default:
266 return -EINVAL;
267 }
268}
269
270
271/* File system interface */ 274/* File system interface */
272static const struct v4l2_file_operations usb_keene_fops = { 275static const struct v4l2_file_operations usb_keene_fops = {
273 .owner = THIS_MODULE, 276 .owner = THIS_MODULE,
@@ -288,7 +291,7 @@ static const struct v4l2_ioctl_ops usb_keene_ioctl_ops = {
288 .vidioc_g_frequency = vidioc_g_frequency, 291 .vidioc_g_frequency = vidioc_g_frequency,
289 .vidioc_s_frequency = vidioc_s_frequency, 292 .vidioc_s_frequency = vidioc_s_frequency,
290 .vidioc_log_status = v4l2_ctrl_log_status, 293 .vidioc_log_status = v4l2_ctrl_log_status,
291 .vidioc_subscribe_event = vidioc_subscribe_event, 294 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
292 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 295 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
293}; 296};
294 297
@@ -404,6 +407,9 @@ static struct usb_driver usb_keene_driver = {
404 .probe = usb_keene_probe, 407 .probe = usb_keene_probe,
405 .disconnect = usb_keene_disconnect, 408 .disconnect = usb_keene_disconnect,
406 .id_table = usb_keene_device_table, 409 .id_table = usb_keene_device_table,
410 .suspend = usb_keene_suspend,
411 .resume = usb_keene_resume,
412 .reset_resume = usb_keene_resume,
407}; 413};
408 414
409static int __init keene_init(void) 415static int __init keene_init(void)
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index a860a72a58ec..94cb6bc690f5 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -62,6 +62,8 @@
62#include <linux/videodev2.h> 62#include <linux/videodev2.h>
63#include <media/v4l2-device.h> 63#include <media/v4l2-device.h>
64#include <media/v4l2-ioctl.h> 64#include <media/v4l2-ioctl.h>
65#include <media/v4l2-ctrls.h>
66#include <media/v4l2-event.h>
65#include <linux/usb.h> 67#include <linux/usb.h>
66#include <linux/mutex.h> 68#include <linux/mutex.h>
67 69
@@ -101,12 +103,17 @@ devices, that would be 76 and 91. */
101 * List isn't full and will be updated with implementation of new functions 103 * List isn't full and will be updated with implementation of new functions
102 */ 104 */
103#define AMRADIO_SET_FREQ 0xa4 105#define AMRADIO_SET_FREQ 0xa4
106#define AMRADIO_GET_READY_FLAG 0xa5
107#define AMRADIO_GET_SIGNAL 0xa7
108#define AMRADIO_GET_FREQ 0xa8
109#define AMRADIO_SET_SEARCH_UP 0xa9
110#define AMRADIO_SET_SEARCH_DOWN 0xaa
104#define AMRADIO_SET_MUTE 0xab 111#define AMRADIO_SET_MUTE 0xab
112#define AMRADIO_SET_RIGHT_MUTE 0xac
113#define AMRADIO_SET_LEFT_MUTE 0xad
105#define AMRADIO_SET_MONO 0xae 114#define AMRADIO_SET_MONO 0xae
106 115#define AMRADIO_SET_SEARCH_LVL 0xb0
107/* Comfortable defines for amradio_set_mute */ 116#define AMRADIO_STOP_SEARCH 0xb1
108#define AMRADIO_START 0x00
109#define AMRADIO_STOP 0x01
110 117
111/* Comfortable defines for amradio_set_stereo */ 118/* Comfortable defines for amradio_set_stereo */
112#define WANT_STEREO 0x00 119#define WANT_STEREO 0x00
@@ -117,29 +124,20 @@ static int radio_nr = -1;
117module_param(radio_nr, int, 0); 124module_param(radio_nr, int, 0);
118MODULE_PARM_DESC(radio_nr, "Radio Nr"); 125MODULE_PARM_DESC(radio_nr, "Radio Nr");
119 126
120static int usb_amradio_probe(struct usb_interface *intf,
121 const struct usb_device_id *id);
122static void usb_amradio_disconnect(struct usb_interface *intf);
123static int usb_amradio_open(struct file *file);
124static int usb_amradio_close(struct file *file);
125static int usb_amradio_suspend(struct usb_interface *intf,
126 pm_message_t message);
127static int usb_amradio_resume(struct usb_interface *intf);
128
129/* Data for one (physical) device */ 127/* Data for one (physical) device */
130struct amradio_device { 128struct amradio_device {
131 /* reference to USB and video device */ 129 /* reference to USB and video device */
132 struct usb_device *usbdev; 130 struct usb_device *usbdev;
133 struct usb_interface *intf; 131 struct usb_interface *intf;
134 struct video_device videodev; 132 struct video_device vdev;
135 struct v4l2_device v4l2_dev; 133 struct v4l2_device v4l2_dev;
134 struct v4l2_ctrl_handler hdl;
136 135
137 unsigned char *buffer; 136 u8 *buffer;
138 struct mutex lock; /* buffer locking */ 137 struct mutex lock; /* buffer locking */
139 int curfreq; 138 int curfreq;
140 int stereo; 139 int stereo;
141 int muted; 140 int muted;
142 int initialized;
143}; 141};
144 142
145static inline struct amradio_device *to_amradio_dev(struct v4l2_device *v4l2_dev) 143static inline struct amradio_device *to_amradio_dev(struct v4l2_device *v4l2_dev)
@@ -147,29 +145,8 @@ static inline struct amradio_device *to_amradio_dev(struct v4l2_device *v4l2_dev
147 return container_of(v4l2_dev, struct amradio_device, v4l2_dev); 145 return container_of(v4l2_dev, struct amradio_device, v4l2_dev);
148} 146}
149 147
150/* USB Device ID List */ 148static int amradio_send_cmd(struct amradio_device *radio, u8 cmd, u8 arg,
151static struct usb_device_id usb_amradio_device_table[] = { 149 u8 *extra, u8 extralen, bool reply)
152 {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
153 USB_CLASS_HID, 0, 0) },
154 { } /* Terminating entry */
155};
156
157MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
158
159/* USB subsystem interface */
160static struct usb_driver usb_amradio_driver = {
161 .name = MR800_DRIVER_NAME,
162 .probe = usb_amradio_probe,
163 .disconnect = usb_amradio_disconnect,
164 .suspend = usb_amradio_suspend,
165 .resume = usb_amradio_resume,
166 .reset_resume = usb_amradio_resume,
167 .id_table = usb_amradio_device_table,
168 .supports_autosuspend = 1,
169};
170
171/* switch on/off the radio. Send 8 bytes to device */
172static int amradio_set_mute(struct amradio_device *radio, char argument)
173{ 150{
174 int retval; 151 int retval;
175 int size; 152 int size;
@@ -177,99 +154,92 @@ static int amradio_set_mute(struct amradio_device *radio, char argument)
177 radio->buffer[0] = 0x00; 154 radio->buffer[0] = 0x00;
178 radio->buffer[1] = 0x55; 155 radio->buffer[1] = 0x55;
179 radio->buffer[2] = 0xaa; 156 radio->buffer[2] = 0xaa;
180 radio->buffer[3] = 0x00; 157 radio->buffer[3] = extralen;
181 radio->buffer[4] = AMRADIO_SET_MUTE; 158 radio->buffer[4] = cmd;
182 radio->buffer[5] = argument; 159 radio->buffer[5] = arg;
183 radio->buffer[6] = 0x00; 160 radio->buffer[6] = 0x00;
184 radio->buffer[7] = 0x00; 161 radio->buffer[7] = extra || reply ? 8 : 0;
185 162
186 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 163 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
187 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 164 radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT);
188 165
189 if (retval < 0 || size != BUFFER_LENGTH) { 166 if (retval < 0 || size != BUFFER_LENGTH) {
190 amradio_dev_warn(&radio->videodev.dev, "set mute failed\n"); 167 if (video_is_registered(&radio->vdev))
191 return retval; 168 amradio_dev_warn(&radio->vdev.dev,
169 "cmd %02x failed\n", cmd);
170 return retval ? retval : -EIO;
192 } 171 }
172 if (!extra && !reply)
173 return 0;
193 174
194 radio->muted = argument; 175 if (extra) {
176 memcpy(radio->buffer, extra, extralen);
177 memset(radio->buffer + extralen, 0, 8 - extralen);
178 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
179 radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT);
180 } else {
181 memset(radio->buffer, 0, 8);
182 retval = usb_bulk_msg(radio->usbdev, usb_rcvbulkpipe(radio->usbdev, 0x81),
183 radio->buffer, BUFFER_LENGTH, &size, USB_TIMEOUT);
184 }
185 if (retval == 0 && size == BUFFER_LENGTH)
186 return 0;
187 if (video_is_registered(&radio->vdev) && cmd != AMRADIO_GET_READY_FLAG)
188 amradio_dev_warn(&radio->vdev.dev, "follow-up to cmd %02x failed\n", cmd);
189 return retval ? retval : -EIO;
190}
195 191
196 return retval; 192/* switch on/off the radio. Send 8 bytes to device */
193static int amradio_set_mute(struct amradio_device *radio, bool mute)
194{
195 int ret = amradio_send_cmd(radio,
196 AMRADIO_SET_MUTE, mute, NULL, 0, false);
197
198 if (!ret)
199 radio->muted = mute;
200 return ret;
197} 201}
198 202
199/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 203/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
200static int amradio_setfreq(struct amradio_device *radio, int freq) 204static int amradio_set_freq(struct amradio_device *radio, int freq)
201{ 205{
202 int retval;
203 int size;
204 unsigned short freq_send = 0x10 + (freq >> 3) / 25; 206 unsigned short freq_send = 0x10 + (freq >> 3) / 25;
205 207 u8 buf[3];
206 radio->buffer[0] = 0x00; 208 int retval;
207 radio->buffer[1] = 0x55;
208 radio->buffer[2] = 0xaa;
209 radio->buffer[3] = 0x03;
210 radio->buffer[4] = AMRADIO_SET_FREQ;
211 radio->buffer[5] = 0x00;
212 radio->buffer[6] = 0x00;
213 radio->buffer[7] = 0x08;
214
215 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
216 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
217
218 if (retval < 0 || size != BUFFER_LENGTH)
219 goto out_err;
220 209
221 /* frequency is calculated from freq_send and placed in first 2 bytes */ 210 /* frequency is calculated from freq_send and placed in first 2 bytes */
222 radio->buffer[0] = (freq_send >> 8) & 0xff; 211 buf[0] = (freq_send >> 8) & 0xff;
223 radio->buffer[1] = freq_send & 0xff; 212 buf[1] = freq_send & 0xff;
224 radio->buffer[2] = 0x01; 213 buf[2] = 0x01;
225 radio->buffer[3] = 0x00;
226 radio->buffer[4] = 0x00;
227 /* 5 and 6 bytes of buffer already = 0x00 */
228 radio->buffer[7] = 0x00;
229
230 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
231 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
232
233 if (retval < 0 || size != BUFFER_LENGTH)
234 goto out_err;
235 214
215 retval = amradio_send_cmd(radio, AMRADIO_SET_FREQ, 0, buf, 3, false);
216 if (retval)
217 return retval;
236 radio->curfreq = freq; 218 radio->curfreq = freq;
237 goto out; 219 msleep(40);
238 220 return 0;
239out_err:
240 amradio_dev_warn(&radio->videodev.dev, "set frequency failed\n");
241out:
242 return retval;
243} 221}
244 222
245static int amradio_set_stereo(struct amradio_device *radio, char argument) 223static int amradio_set_stereo(struct amradio_device *radio, bool stereo)
246{ 224{
247 int retval; 225 int ret = amradio_send_cmd(radio,
248 int size; 226 AMRADIO_SET_MONO, !stereo, NULL, 0, false);
249 227
250 radio->buffer[0] = 0x00; 228 if (!ret)
251 radio->buffer[1] = 0x55; 229 radio->stereo = stereo;
252 radio->buffer[2] = 0xaa; 230 return ret;
253 radio->buffer[3] = 0x00; 231}
254 radio->buffer[4] = AMRADIO_SET_MONO;
255 radio->buffer[5] = argument;
256 radio->buffer[6] = 0x00;
257 radio->buffer[7] = 0x00;
258
259 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
260 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
261
262 if (retval < 0 || size != BUFFER_LENGTH) {
263 amradio_dev_warn(&radio->videodev.dev, "set stereo failed\n");
264 return retval;
265 }
266 232
267 if (argument == WANT_STEREO) 233static int amradio_get_stat(struct amradio_device *radio, bool *is_stereo, u32 *signal)
268 radio->stereo = 1; 234{
269 else 235 int ret = amradio_send_cmd(radio,
270 radio->stereo = 0; 236 AMRADIO_GET_SIGNAL, 0, NULL, 0, true);
271 237
272 return retval; 238 if (ret)
239 return ret;
240 *is_stereo = radio->buffer[2] >> 7;
241 *signal = (radio->buffer[3] & 0xf0) << 8;
242 return 0;
273} 243}
274 244
275/* Handle unplugging the device. 245/* Handle unplugging the device.
@@ -282,25 +252,26 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
282 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); 252 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
283 253
284 mutex_lock(&radio->lock); 254 mutex_lock(&radio->lock);
285 /* increase the device node's refcount */ 255 video_unregister_device(&radio->vdev);
286 get_device(&radio->videodev.dev); 256 amradio_set_mute(radio, true);
257 usb_set_intfdata(intf, NULL);
287 v4l2_device_disconnect(&radio->v4l2_dev); 258 v4l2_device_disconnect(&radio->v4l2_dev);
288 video_unregister_device(&radio->videodev);
289 mutex_unlock(&radio->lock); 259 mutex_unlock(&radio->lock);
290 /* decrease the device node's refcount, allowing it to be released */ 260 v4l2_device_put(&radio->v4l2_dev);
291 put_device(&radio->videodev.dev);
292} 261}
293 262
294/* vidioc_querycap - query device capabilities */ 263/* vidioc_querycap - query device capabilities */
295static int vidioc_querycap(struct file *file, void *priv, 264static int vidioc_querycap(struct file *file, void *priv,
296 struct v4l2_capability *v) 265 struct v4l2_capability *v)
297{ 266{
298 struct amradio_device *radio = file->private_data; 267 struct amradio_device *radio = video_drvdata(file);
299 268
300 strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); 269 strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
301 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); 270 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
302 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); 271 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
303 v->capabilities = V4L2_CAP_TUNER; 272 v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER |
273 V4L2_CAP_HW_FREQ_SEEK;
274 v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
304 return 0; 275 return 0;
305} 276}
306 277
@@ -308,44 +279,34 @@ static int vidioc_querycap(struct file *file, void *priv,
308static int vidioc_g_tuner(struct file *file, void *priv, 279static int vidioc_g_tuner(struct file *file, void *priv,
309 struct v4l2_tuner *v) 280 struct v4l2_tuner *v)
310{ 281{
311 struct amradio_device *radio = file->private_data; 282 struct amradio_device *radio = video_drvdata(file);
283 bool is_stereo = false;
312 int retval; 284 int retval;
313 285
314 if (v->index > 0) 286 if (v->index > 0)
315 return -EINVAL; 287 return -EINVAL;
316 288
317/* TODO: Add function which look is signal stereo or not 289 v->signal = 0;
318 * amradio_getstat(radio); 290 retval = amradio_get_stat(radio, &is_stereo, &v->signal);
319 */ 291 if (retval)
320 292 return retval;
321/* we call amradio_set_stereo to set radio->stereo
322 * Honestly, amradio_getstat should cover this in future and
323 * amradio_set_stereo shouldn't be here
324 */
325 retval = amradio_set_stereo(radio, WANT_STEREO);
326 293
327 strcpy(v->name, "FM"); 294 strcpy(v->name, "FM");
328 v->type = V4L2_TUNER_RADIO; 295 v->type = V4L2_TUNER_RADIO;
329 v->rangelow = FREQ_MIN * FREQ_MUL; 296 v->rangelow = FREQ_MIN * FREQ_MUL;
330 v->rangehigh = FREQ_MAX * FREQ_MUL; 297 v->rangehigh = FREQ_MAX * FREQ_MUL;
331 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 298 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
332 v->capability = V4L2_TUNER_CAP_LOW; 299 v->rxsubchans = is_stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
333 if (radio->stereo) 300 v->audmode = radio->stereo ?
334 v->audmode = V4L2_TUNER_MODE_STEREO; 301 V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
335 else 302 return 0;
336 v->audmode = V4L2_TUNER_MODE_MONO;
337 v->signal = 0xffff; /* Can't get the signal strength, sad.. */
338 v->afc = 0; /* Don't know what is this */
339
340 return retval;
341} 303}
342 304
343/* vidioc_s_tuner - set tuner attributes */ 305/* vidioc_s_tuner - set tuner attributes */
344static int vidioc_s_tuner(struct file *file, void *priv, 306static int vidioc_s_tuner(struct file *file, void *priv,
345 struct v4l2_tuner *v) 307 struct v4l2_tuner *v)
346{ 308{
347 struct amradio_device *radio = file->private_data; 309 struct amradio_device *radio = video_drvdata(file);
348 int retval = -EINVAL;
349 310
350 if (v->index > 0) 311 if (v->index > 0)
351 return -EINVAL; 312 return -EINVAL;
@@ -353,34 +314,31 @@ static int vidioc_s_tuner(struct file *file, void *priv,
353 /* mono/stereo selector */ 314 /* mono/stereo selector */
354 switch (v->audmode) { 315 switch (v->audmode) {
355 case V4L2_TUNER_MODE_MONO: 316 case V4L2_TUNER_MODE_MONO:
356 retval = amradio_set_stereo(radio, WANT_MONO); 317 return amradio_set_stereo(radio, WANT_MONO);
357 break; 318 default:
358 case V4L2_TUNER_MODE_STEREO: 319 return amradio_set_stereo(radio, WANT_STEREO);
359 retval = amradio_set_stereo(radio, WANT_STEREO);
360 break;
361 } 320 }
362
363 return retval;
364} 321}
365 322
366/* vidioc_s_frequency - set tuner radio frequency */ 323/* vidioc_s_frequency - set tuner radio frequency */
367static int vidioc_s_frequency(struct file *file, void *priv, 324static int vidioc_s_frequency(struct file *file, void *priv,
368 struct v4l2_frequency *f) 325 struct v4l2_frequency *f)
369{ 326{
370 struct amradio_device *radio = file->private_data; 327 struct amradio_device *radio = video_drvdata(file);
371 328
372 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 329 if (f->tuner != 0)
373 return -EINVAL; 330 return -EINVAL;
374 return amradio_setfreq(radio, f->frequency); 331 return amradio_set_freq(radio, clamp_t(unsigned, f->frequency,
332 FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL));
375} 333}
376 334
377/* vidioc_g_frequency - get tuner radio frequency */ 335/* vidioc_g_frequency - get tuner radio frequency */
378static int vidioc_g_frequency(struct file *file, void *priv, 336static int vidioc_g_frequency(struct file *file, void *priv,
379 struct v4l2_frequency *f) 337 struct v4l2_frequency *f)
380{ 338{
381 struct amradio_device *radio = file->private_data; 339 struct amradio_device *radio = video_drvdata(file);
382 340
383 if (f->tuner != 0) 341 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
384 return -EINVAL; 342 return -EINVAL;
385 f->type = V4L2_TUNER_RADIO; 343 f->type = V4L2_TUNER_RADIO;
386 f->frequency = radio->curfreq; 344 f->frequency = radio->curfreq;
@@ -388,148 +346,101 @@ static int vidioc_g_frequency(struct file *file, void *priv,
388 return 0; 346 return 0;
389} 347}
390 348
391/* vidioc_queryctrl - enumerate control items */ 349static int vidioc_s_hw_freq_seek(struct file *file, void *priv,
392static int vidioc_queryctrl(struct file *file, void *priv, 350 struct v4l2_hw_freq_seek *seek)
393 struct v4l2_queryctrl *qc)
394{ 351{
395 switch (qc->id) { 352 static u8 buf[8] = {
396 case V4L2_CID_AUDIO_MUTE: 353 0x3d, 0x32, 0x0f, 0x08, 0x3d, 0x32, 0x0f, 0x08
397 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 354 };
398 } 355 struct amradio_device *radio = video_drvdata(file);
399 356 unsigned long timeout;
400 return -EINVAL; 357 int retval;
401}
402 358
403/* vidioc_g_ctrl - get the value of a control */ 359 if (seek->tuner != 0 || !seek->wrap_around)
404static int vidioc_g_ctrl(struct file *file, void *priv, 360 return -EINVAL;
405 struct v4l2_control *ctrl)
406{
407 struct amradio_device *radio = file->private_data;
408 361
409 switch (ctrl->id) { 362 retval = amradio_send_cmd(radio,
410 case V4L2_CID_AUDIO_MUTE: 363 AMRADIO_SET_SEARCH_LVL, 0, buf, 8, false);
411 ctrl->value = radio->muted; 364 if (retval)
412 return 0; 365 return retval;
366 amradio_set_freq(radio, radio->curfreq);
367 retval = amradio_send_cmd(radio,
368 seek->seek_upward ? AMRADIO_SET_SEARCH_UP : AMRADIO_SET_SEARCH_DOWN,
369 0, NULL, 0, false);
370 if (retval)
371 return retval;
372 timeout = jiffies + msecs_to_jiffies(30000);
373 for (;;) {
374 if (time_after(jiffies, timeout)) {
375 retval = -EAGAIN;
376 break;
377 }
378 if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
379 retval = -ERESTARTSYS;
380 break;
381 }
382 retval = amradio_send_cmd(radio, AMRADIO_GET_READY_FLAG,
383 0, NULL, 0, true);
384 if (retval)
385 continue;
386 amradio_send_cmd(radio, AMRADIO_GET_FREQ, 0, NULL, 0, true);
387 if (radio->buffer[1] || radio->buffer[2]) {
388 radio->curfreq = (radio->buffer[1] << 8) | radio->buffer[2];
389 radio->curfreq = (radio->curfreq - 0x10) * 200;
390 amradio_send_cmd(radio, AMRADIO_STOP_SEARCH,
391 0, NULL, 0, false);
392 amradio_set_freq(radio, radio->curfreq);
393 retval = 0;
394 break;
395 }
413 } 396 }
414 397 amradio_send_cmd(radio, AMRADIO_STOP_SEARCH, 0, NULL, 0, false);
415 return -EINVAL; 398 amradio_set_freq(radio, radio->curfreq);
399 return retval;
416} 400}
417 401
418/* vidioc_s_ctrl - set the value of a control */ 402static int usb_amradio_s_ctrl(struct v4l2_ctrl *ctrl)
419static int vidioc_s_ctrl(struct file *file, void *priv,
420 struct v4l2_control *ctrl)
421{ 403{
422 struct amradio_device *radio = file->private_data; 404 struct amradio_device *radio =
423 int retval = -EINVAL; 405 container_of(ctrl->handler, struct amradio_device, hdl);
424 406
425 switch (ctrl->id) { 407 switch (ctrl->id) {
426 case V4L2_CID_AUDIO_MUTE: 408 case V4L2_CID_AUDIO_MUTE:
427 if (ctrl->value) 409 return amradio_set_mute(radio, ctrl->val);
428 retval = amradio_set_mute(radio, AMRADIO_STOP);
429 else
430 retval = amradio_set_mute(radio, AMRADIO_START);
431
432 break;
433 } 410 }
434 411
435 return retval; 412 return -EINVAL;
436}
437
438/* vidioc_g_audio - get audio attributes */
439static int vidioc_g_audio(struct file *file, void *priv,
440 struct v4l2_audio *a)
441{
442 if (a->index > 1)
443 return -EINVAL;
444
445 strcpy(a->name, "Radio");
446 a->capability = V4L2_AUDCAP_STEREO;
447 return 0;
448}
449
450/* vidioc_s_audio - set audio attributes */
451static int vidioc_s_audio(struct file *file, void *priv,
452 struct v4l2_audio *a)
453{
454 if (a->index != 0)
455 return -EINVAL;
456 return 0;
457}
458
459/* vidioc_g_input - get input */
460static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
461{
462 *i = 0;
463 return 0;
464}
465
466/* vidioc_s_input - set input */
467static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
468{
469 if (i != 0)
470 return -EINVAL;
471 return 0;
472} 413}
473 414
474static int usb_amradio_init(struct amradio_device *radio) 415static int usb_amradio_init(struct amradio_device *radio)
475{ 416{
476 int retval; 417 int retval;
477 418
478 retval = amradio_set_mute(radio, AMRADIO_STOP); 419 retval = amradio_set_mute(radio, true);
479 if (retval) 420 if (retval)
480 goto out_err; 421 goto out_err;
481 422 retval = amradio_set_stereo(radio, true);
482 retval = amradio_set_stereo(radio, WANT_STEREO);
483 if (retval) 423 if (retval)
484 goto out_err; 424 goto out_err;
485 425 retval = amradio_set_freq(radio, radio->curfreq);
486 radio->initialized = 1;
487 goto out;
488
489out_err:
490 amradio_dev_err(&radio->videodev.dev, "initialization failed\n");
491out:
492 return retval;
493}
494
495/* open device - amradio_start() and amradio_setfreq() */
496static int usb_amradio_open(struct file *file)
497{
498 struct amradio_device *radio = video_drvdata(file);
499 int retval;
500
501 file->private_data = radio;
502 retval = usb_autopm_get_interface(radio->intf);
503 if (retval) 426 if (retval)
504 return retval; 427 goto out_err;
428 return 0;
505 429
506 if (unlikely(!radio->initialized)) { 430out_err:
507 retval = usb_amradio_init(radio); 431 amradio_dev_err(&radio->vdev.dev, "initialization failed\n");
508 if (retval)
509 usb_autopm_put_interface(radio->intf);
510 }
511 return retval; 432 return retval;
512} 433}
513 434
514/*close device */
515static int usb_amradio_close(struct file *file)
516{
517 struct amradio_device *radio = file->private_data;
518
519 if (video_is_registered(&radio->videodev))
520 usb_autopm_put_interface(radio->intf);
521 return 0;
522}
523
524/* Suspend device - stop device. Need to be checked and fixed */ 435/* Suspend device - stop device. Need to be checked and fixed */
525static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) 436static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
526{ 437{
527 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); 438 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
528 439
529 mutex_lock(&radio->lock); 440 mutex_lock(&radio->lock);
530 if (!radio->muted && radio->initialized) { 441 if (!radio->muted) {
531 amradio_set_mute(radio, AMRADIO_STOP); 442 amradio_set_mute(radio, true);
532 radio->muted = 0; 443 radio->muted = false;
533 } 444 }
534 mutex_unlock(&radio->lock); 445 mutex_unlock(&radio->lock);
535 446
@@ -543,31 +454,28 @@ static int usb_amradio_resume(struct usb_interface *intf)
543 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf)); 454 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
544 455
545 mutex_lock(&radio->lock); 456 mutex_lock(&radio->lock);
546 if (unlikely(!radio->initialized)) 457 amradio_set_stereo(radio, radio->stereo);
547 goto unlock; 458 amradio_set_freq(radio, radio->curfreq);
548
549 if (radio->stereo)
550 amradio_set_stereo(radio, WANT_STEREO);
551 else
552 amradio_set_stereo(radio, WANT_MONO);
553
554 amradio_setfreq(radio, radio->curfreq);
555 459
556 if (!radio->muted) 460 if (!radio->muted)
557 amradio_set_mute(radio, AMRADIO_START); 461 amradio_set_mute(radio, false);
558 462
559unlock:
560 mutex_unlock(&radio->lock); 463 mutex_unlock(&radio->lock);
561 464
562 dev_info(&intf->dev, "coming out of suspend..\n"); 465 dev_info(&intf->dev, "coming out of suspend..\n");
563 return 0; 466 return 0;
564} 467}
565 468
469static const struct v4l2_ctrl_ops usb_amradio_ctrl_ops = {
470 .s_ctrl = usb_amradio_s_ctrl,
471};
472
566/* File system interface */ 473/* File system interface */
567static const struct v4l2_file_operations usb_amradio_fops = { 474static const struct v4l2_file_operations usb_amradio_fops = {
568 .owner = THIS_MODULE, 475 .owner = THIS_MODULE,
569 .open = usb_amradio_open, 476 .open = v4l2_fh_open,
570 .release = usb_amradio_close, 477 .release = v4l2_fh_release,
478 .poll = v4l2_ctrl_poll,
571 .unlocked_ioctl = video_ioctl2, 479 .unlocked_ioctl = video_ioctl2,
572}; 480};
573 481
@@ -577,20 +485,19 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
577 .vidioc_s_tuner = vidioc_s_tuner, 485 .vidioc_s_tuner = vidioc_s_tuner,
578 .vidioc_g_frequency = vidioc_g_frequency, 486 .vidioc_g_frequency = vidioc_g_frequency,
579 .vidioc_s_frequency = vidioc_s_frequency, 487 .vidioc_s_frequency = vidioc_s_frequency,
580 .vidioc_queryctrl = vidioc_queryctrl, 488 .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
581 .vidioc_g_ctrl = vidioc_g_ctrl, 489 .vidioc_log_status = v4l2_ctrl_log_status,
582 .vidioc_s_ctrl = vidioc_s_ctrl, 490 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
583 .vidioc_g_audio = vidioc_g_audio, 491 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
584 .vidioc_s_audio = vidioc_s_audio,
585 .vidioc_g_input = vidioc_g_input,
586 .vidioc_s_input = vidioc_s_input,
587}; 492};
588 493
589static void usb_amradio_video_device_release(struct video_device *videodev) 494static void usb_amradio_release(struct v4l2_device *v4l2_dev)
590{ 495{
591 struct amradio_device *radio = video_get_drvdata(videodev); 496 struct amradio_device *radio = to_amradio_dev(v4l2_dev);
592 497
593 /* free rest memory */ 498 /* free rest memory */
499 v4l2_ctrl_handler_free(&radio->hdl);
500 v4l2_device_unregister(&radio->v4l2_dev);
594 kfree(radio->buffer); 501 kfree(radio->buffer);
595 kfree(radio); 502 kfree(radio);
596} 503}
@@ -624,23 +531,38 @@ static int usb_amradio_probe(struct usb_interface *intf,
624 goto err_v4l2; 531 goto err_v4l2;
625 } 532 }
626 533
534 v4l2_ctrl_handler_init(&radio->hdl, 1);
535 v4l2_ctrl_new_std(&radio->hdl, &usb_amradio_ctrl_ops,
536 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
537 if (radio->hdl.error) {
538 retval = radio->hdl.error;
539 dev_err(&intf->dev, "couldn't register control\n");
540 goto err_ctrl;
541 }
627 mutex_init(&radio->lock); 542 mutex_init(&radio->lock);
628 543
629 strlcpy(radio->videodev.name, radio->v4l2_dev.name, 544 radio->v4l2_dev.ctrl_handler = &radio->hdl;
630 sizeof(radio->videodev.name)); 545 radio->v4l2_dev.release = usb_amradio_release;
631 radio->videodev.v4l2_dev = &radio->v4l2_dev; 546 strlcpy(radio->vdev.name, radio->v4l2_dev.name,
632 radio->videodev.fops = &usb_amradio_fops; 547 sizeof(radio->vdev.name));
633 radio->videodev.ioctl_ops = &usb_amradio_ioctl_ops; 548 radio->vdev.v4l2_dev = &radio->v4l2_dev;
634 radio->videodev.release = usb_amradio_video_device_release; 549 radio->vdev.fops = &usb_amradio_fops;
635 radio->videodev.lock = &radio->lock; 550 radio->vdev.ioctl_ops = &usb_amradio_ioctl_ops;
551 radio->vdev.release = video_device_release_empty;
552 radio->vdev.lock = &radio->lock;
553 set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
636 554
637 radio->usbdev = interface_to_usbdev(intf); 555 radio->usbdev = interface_to_usbdev(intf);
638 radio->intf = intf; 556 radio->intf = intf;
557 usb_set_intfdata(intf, &radio->v4l2_dev);
639 radio->curfreq = 95.16 * FREQ_MUL; 558 radio->curfreq = 95.16 * FREQ_MUL;
640 559
641 video_set_drvdata(&radio->videodev, radio); 560 video_set_drvdata(&radio->vdev, radio);
561 retval = usb_amradio_init(radio);
562 if (retval)
563 goto err_vdev;
642 564
643 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, 565 retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO,
644 radio_nr); 566 radio_nr);
645 if (retval < 0) { 567 if (retval < 0) {
646 dev_err(&intf->dev, "could not register video device\n"); 568 dev_err(&intf->dev, "could not register video device\n");
@@ -650,6 +572,8 @@ static int usb_amradio_probe(struct usb_interface *intf,
650 return 0; 572 return 0;
651 573
652err_vdev: 574err_vdev:
575 v4l2_ctrl_handler_free(&radio->hdl);
576err_ctrl:
653 v4l2_device_unregister(&radio->v4l2_dev); 577 v4l2_device_unregister(&radio->v4l2_dev);
654err_v4l2: 578err_v4l2:
655 kfree(radio->buffer); 579 kfree(radio->buffer);
@@ -659,4 +583,24 @@ err:
659 return retval; 583 return retval;
660} 584}
661 585
586/* USB Device ID List */
587static struct usb_device_id usb_amradio_device_table[] = {
588 { USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
589 USB_CLASS_HID, 0, 0) },
590 { } /* Terminating entry */
591};
592
593MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
594
595/* USB subsystem interface */
596static struct usb_driver usb_amradio_driver = {
597 .name = MR800_DRIVER_NAME,
598 .probe = usb_amradio_probe,
599 .disconnect = usb_amradio_disconnect,
600 .suspend = usb_amradio_suspend,
601 .resume = usb_amradio_resume,
602 .reset_resume = usb_amradio_resume,
603 .id_table = usb_amradio_device_table,
604};
605
662module_usb_driver(usb_amradio_driver); 606module_usb_driver(usb_amradio_driver);
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index b275c5d0fe9a..b1f844c64fde 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -17,6 +17,7 @@
17#include <linux/videodev2.h> /* kernel radio structs */ 17#include <linux/videodev2.h> /* kernel radio structs */
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19#include <linux/io.h> /* outb, outb_p */ 19#include <linux/io.h> /* outb, outb_p */
20#include <linux/slab.h>
20#include <media/v4l2-device.h> 21#include <media/v4l2-device.h>
21#include <media/v4l2-ioctl.h> 22#include <media/v4l2-ioctl.h>
22#include "radio-isa.h" 23#include "radio-isa.h"
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 22c5743bf9db..a81d723b8c77 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -1,4 +1,4 @@
1/* SF16-FMI and SF16-FMP radio driver for Linux radio support 1/* SF16-FMI, SF16-FMP and SF16-FMD radio driver for Linux radio support
2 * heavily based on rtrack driver... 2 * heavily based on rtrack driver...
3 * (c) 1997 M. Kirkwood 3 * (c) 1997 M. Kirkwood
4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz 4 * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
@@ -11,7 +11,7 @@
11 * 11 *
12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); 12 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
13 * No volume control - only mute/unmute - you have to use line volume 13 * No volume control - only mute/unmute - you have to use line volume
14 * control on SB-part of SF16-FMI/SF16-FMP 14 * control on SB-part of SF16-FMI/SF16-FMP/SF16-FMD
15 * 15 *
16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
17 */ 17 */
@@ -29,7 +29,7 @@
29#include <media/v4l2-ioctl.h> 29#include <media/v4l2-ioctl.h>
30 30
31MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); 31MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
32MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio."); 32MODULE_DESCRIPTION("A driver for the SF16-FMI, SF16-FMP and SF16-FMD radio.");
33MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
34MODULE_VERSION("0.0.3"); 34MODULE_VERSION("0.0.3");
35 35
@@ -37,7 +37,7 @@ static int io = -1;
37static int radio_nr = -1; 37static int radio_nr = -1;
38 38
39module_param(io, int, 0); 39module_param(io, int, 0);
40MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)"); 40MODULE_PARM_DESC(io, "I/O address of the SF16-FMI/SF16-FMP/SF16-FMD card (0x284 or 0x384)");
41module_param(radio_nr, int, 0); 41module_param(radio_nr, int, 0);
42 42
43struct fmi 43struct fmi
@@ -130,7 +130,7 @@ static int vidioc_querycap(struct file *file, void *priv,
130 struct v4l2_capability *v) 130 struct v4l2_capability *v)
131{ 131{
132 strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver)); 132 strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
133 strlcpy(v->card, "SF16-FMx radio", sizeof(v->card)); 133 strlcpy(v->card, "SF16-FMI/FMP/FMD radio", sizeof(v->card));
134 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 134 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
135 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 135 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
136 return 0; 136 return 0;
@@ -277,8 +277,12 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
277 277
278/* ladis: this is my card. does any other types exist? */ 278/* ladis: this is my card. does any other types exist? */
279static struct isapnp_device_id id_table[] __devinitdata = { 279static struct isapnp_device_id id_table[] __devinitdata = {
280 /* SF16-FMI */
280 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, 281 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
281 ISAPNP_VENDOR('M','F','R'), ISAPNP_FUNCTION(0xad10), 0}, 282 ISAPNP_VENDOR('M','F','R'), ISAPNP_FUNCTION(0xad10), 0},
283 /* SF16-FMD */
284 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
285 ISAPNP_VENDOR('M','F','R'), ISAPNP_FUNCTION(0xad12), 0},
282 { ISAPNP_CARD_END, }, 286 { ISAPNP_CARD_END, },
283}; 287};
284 288
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 7c69214334bf..52b8011f1b23 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -1,4 +1,4 @@
1/* SF16-FMR2 radio driver for Linux 1/* SF16-FMR2 and SF16-FMD2 radio driver for Linux
2 * Copyright (c) 2011 Ondrej Zary 2 * Copyright (c) 2011 Ondrej Zary
3 * 3 *
4 * Original driver was (c) 2000-2002 Ziglio Frediano, freddy77@angelfire.com 4 * Original driver was (c) 2000-2002 Ziglio Frediano, freddy77@angelfire.com
@@ -13,15 +13,19 @@
13#include <linux/ioport.h> /* request_region */ 13#include <linux/ioport.h> /* request_region */
14#include <linux/io.h> /* outb, outb_p */ 14#include <linux/io.h> /* outb, outb_p */
15#include <linux/isa.h> 15#include <linux/isa.h>
16#include <linux/pnp.h>
16#include <sound/tea575x-tuner.h> 17#include <sound/tea575x-tuner.h>
17 18
18MODULE_AUTHOR("Ondrej Zary"); 19MODULE_AUTHOR("Ondrej Zary");
19MODULE_DESCRIPTION("MediaForte SF16-FMR2 FM radio card driver"); 20MODULE_DESCRIPTION("MediaForte SF16-FMR2 and SF16-FMD2 FM radio card driver");
20MODULE_LICENSE("GPL"); 21MODULE_LICENSE("GPL");
21 22
22static int radio_nr = -1; 23/* these cards can only use two different ports (0x384 and 0x284) */
23module_param(radio_nr, int, 0444); 24#define FMR2_MAX 2
24MODULE_PARM_DESC(radio_nr, "Radio device number"); 25
26static int radio_nr[FMR2_MAX] = { [0 ... (FMR2_MAX - 1)] = -1 };
27module_param_array(radio_nr, int, NULL, 0444);
28MODULE_PARM_DESC(radio_nr, "Radio device numbers");
25 29
26struct fmr2 { 30struct fmr2 {
27 int io; 31 int io;
@@ -29,9 +33,15 @@ struct fmr2 {
29 struct snd_tea575x tea; 33 struct snd_tea575x tea;
30 struct v4l2_ctrl *volume; 34 struct v4l2_ctrl *volume;
31 struct v4l2_ctrl *balance; 35 struct v4l2_ctrl *balance;
36 bool is_fmd2;
32}; 37};
33 38
34/* the port is hardwired so no need to support multiple cards */ 39static int num_fmr2_cards;
40static struct fmr2 *fmr2_cards[FMR2_MAX];
41static bool isa_registered;
42static bool pnp_registered;
43
44/* the port is hardwired on SF16-FMR2 */
35#define FMR2_PORT 0x384 45#define FMR2_PORT 0x384
36 46
37/* TEA575x tuner pins */ 47/* TEA575x tuner pins */
@@ -174,7 +184,8 @@ static int fmr2_tea_ext_init(struct snd_tea575x *tea)
174{ 184{
175 struct fmr2 *fmr2 = tea->private_data; 185 struct fmr2 *fmr2 = tea->private_data;
176 186
177 if (inb(fmr2->io) & FMR2_HASVOL) { 187 /* FMR2 can have volume control, FMD2 can't (uses SB16 mixer) */
188 if (!fmr2->is_fmd2 && inb(fmr2->io) & FMR2_HASVOL) {
178 fmr2->volume = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 68, 2, 56); 189 fmr2->volume = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 68, 2, 56);
179 fmr2->balance = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_BALANCE, -68, 68, 2, 0); 190 fmr2->balance = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_BALANCE, -68, 68, 2, 0);
180 if (tea->ctrl_handler.error) { 191 if (tea->ctrl_handler.error) {
@@ -186,22 +197,28 @@ static int fmr2_tea_ext_init(struct snd_tea575x *tea)
186 return 0; 197 return 0;
187} 198}
188 199
189static int __devinit fmr2_probe(struct device *pdev, unsigned int dev) 200static struct pnp_device_id fmr2_pnp_ids[] __devinitdata = {
201 { .id = "MFRad13" }, /* tuner subdevice of SF16-FMD2 */
202 { .id = "" }
203};
204MODULE_DEVICE_TABLE(pnp, fmr2_pnp_ids);
205
206static int __devinit fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io)
190{ 207{
191 struct fmr2 *fmr2; 208 int err, i;
192 int err; 209 char *card_name = fmr2->is_fmd2 ? "SF16-FMD2" : "SF16-FMR2";
193 210
194 fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL); 211 /* avoid errors if a card was already registered at given port */
195 if (fmr2 == NULL) 212 for (i = 0; i < num_fmr2_cards; i++)
196 return -ENOMEM; 213 if (io == fmr2_cards[i]->io)
214 return -EBUSY;
197 215
198 strlcpy(fmr2->v4l2_dev.name, dev_name(pdev), 216 strlcpy(fmr2->v4l2_dev.name, "radio-sf16fmr2",
199 sizeof(fmr2->v4l2_dev.name)); 217 sizeof(fmr2->v4l2_dev.name)),
200 fmr2->io = FMR2_PORT; 218 fmr2->io = io;
201 219
202 if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) { 220 if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) {
203 printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io); 221 printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io);
204 kfree(fmr2);
205 return -EBUSY; 222 return -EBUSY;
206 } 223 }
207 224
@@ -210,56 +227,121 @@ static int __devinit fmr2_probe(struct device *pdev, unsigned int dev)
210 if (err < 0) { 227 if (err < 0) {
211 v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n"); 228 v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n");
212 release_region(fmr2->io, 2); 229 release_region(fmr2->io, 2);
213 kfree(fmr2);
214 return err; 230 return err;
215 } 231 }
216 fmr2->tea.v4l2_dev = &fmr2->v4l2_dev; 232 fmr2->tea.v4l2_dev = &fmr2->v4l2_dev;
217 fmr2->tea.private_data = fmr2; 233 fmr2->tea.private_data = fmr2;
218 fmr2->tea.radio_nr = radio_nr; 234 fmr2->tea.radio_nr = radio_nr[num_fmr2_cards];
219 fmr2->tea.ops = &fmr2_tea_ops; 235 fmr2->tea.ops = &fmr2_tea_ops;
220 fmr2->tea.ext_init = fmr2_tea_ext_init; 236 fmr2->tea.ext_init = fmr2_tea_ext_init;
221 strlcpy(fmr2->tea.card, "SF16-FMR2", sizeof(fmr2->tea.card)); 237 strlcpy(fmr2->tea.card, card_name, sizeof(fmr2->tea.card));
222 snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "ISA:%s", 238 snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s",
223 fmr2->v4l2_dev.name); 239 fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev));
224 240
225 if (snd_tea575x_init(&fmr2->tea)) { 241 if (snd_tea575x_init(&fmr2->tea)) {
226 printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); 242 printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n");
227 release_region(fmr2->io, 2); 243 release_region(fmr2->io, 2);
228 kfree(fmr2);
229 return -ENODEV; 244 return -ENODEV;
230 } 245 }
231 246
232 printk(KERN_INFO "radio-sf16fmr2: SF16-FMR2 radio card at 0x%x.\n", fmr2->io); 247 printk(KERN_INFO "radio-sf16fmr2: %s radio card at 0x%x.\n",
248 card_name, fmr2->io);
233 return 0; 249 return 0;
234} 250}
235 251
236static int __exit fmr2_remove(struct device *pdev, unsigned int dev) 252static int __devinit fmr2_isa_match(struct device *pdev, unsigned int ndev)
253{
254 struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL);
255 if (!fmr2)
256 return 0;
257
258 if (fmr2_probe(fmr2, pdev, FMR2_PORT)) {
259 kfree(fmr2);
260 return 0;
261 }
262 dev_set_drvdata(pdev, fmr2);
263 fmr2_cards[num_fmr2_cards++] = fmr2;
264
265 return 1;
266}
267
268static int __devinit fmr2_pnp_probe(struct pnp_dev *pdev,
269 const struct pnp_device_id *id)
237{ 270{
238 struct fmr2 *fmr2 = dev_get_drvdata(pdev); 271 int ret;
272 struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL);
273 if (!fmr2)
274 return -ENOMEM;
239 275
276 fmr2->is_fmd2 = true;
277 ret = fmr2_probe(fmr2, &pdev->dev, pnp_port_start(pdev, 0));
278 if (ret) {
279 kfree(fmr2);
280 return ret;
281 }
282 pnp_set_drvdata(pdev, fmr2);
283 fmr2_cards[num_fmr2_cards++] = fmr2;
284
285 return 0;
286}
287
288static void __devexit fmr2_remove(struct fmr2 *fmr2)
289{
240 snd_tea575x_exit(&fmr2->tea); 290 snd_tea575x_exit(&fmr2->tea);
241 release_region(fmr2->io, 2); 291 release_region(fmr2->io, 2);
242 v4l2_device_unregister(&fmr2->v4l2_dev); 292 v4l2_device_unregister(&fmr2->v4l2_dev);
243 kfree(fmr2); 293 kfree(fmr2);
294}
295
296static int __devexit fmr2_isa_remove(struct device *pdev, unsigned int ndev)
297{
298 fmr2_remove(dev_get_drvdata(pdev));
299 dev_set_drvdata(pdev, NULL);
300
244 return 0; 301 return 0;
245} 302}
246 303
247struct isa_driver fmr2_driver = { 304static void __devexit fmr2_pnp_remove(struct pnp_dev *pdev)
248 .probe = fmr2_probe, 305{
249 .remove = fmr2_remove, 306 fmr2_remove(pnp_get_drvdata(pdev));
307 pnp_set_drvdata(pdev, NULL);
308}
309
310struct isa_driver fmr2_isa_driver = {
311 .match = fmr2_isa_match,
312 .remove = __devexit_p(fmr2_isa_remove),
250 .driver = { 313 .driver = {
251 .name = "radio-sf16fmr2", 314 .name = "radio-sf16fmr2",
252 }, 315 },
253}; 316};
254 317
318struct pnp_driver fmr2_pnp_driver = {
319 .name = "radio-sf16fmr2",
320 .id_table = fmr2_pnp_ids,
321 .probe = fmr2_pnp_probe,
322 .remove = __devexit_p(fmr2_pnp_remove),
323};
324
255static int __init fmr2_init(void) 325static int __init fmr2_init(void)
256{ 326{
257 return isa_register_driver(&fmr2_driver, 1); 327 int ret;
328
329 ret = pnp_register_driver(&fmr2_pnp_driver);
330 if (!ret)
331 pnp_registered = true;
332 ret = isa_register_driver(&fmr2_isa_driver, 1);
333 if (!ret)
334 isa_registered = true;
335
336 return (pnp_registered || isa_registered) ? 0 : ret;
258} 337}
259 338
260static void __exit fmr2_exit(void) 339static void __exit fmr2_exit(void)
261{ 340{
262 isa_unregister_driver(&fmr2_driver); 341 if (pnp_registered)
342 pnp_unregister_driver(&fmr2_pnp_driver);
343 if (isa_registered)
344 isa_unregister_driver(&fmr2_isa_driver);
263} 345}
264 346
265module_init(fmr2_init); 347module_init(fmr2_init);
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index 5d9a90ac3a1c..7052adc0c0b0 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -223,7 +223,7 @@ static struct platform_driver timbradio_platform_driver = {
223 .owner = THIS_MODULE, 223 .owner = THIS_MODULE,
224 }, 224 },
225 .probe = timbradio_probe, 225 .probe = timbradio_probe,
226 .remove = timbradio_remove, 226 .remove = __devexit_p(timbradio_remove),
227}; 227};
228 228
229module_platform_driver(timbradio_platform_driver); 229module_platform_driver(timbradio_platform_driver);
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
index 9474706350f8..bb953ef75f61 100644
--- a/drivers/media/radio/saa7706h.c
+++ b/drivers/media/radio/saa7706h.c
@@ -430,7 +430,7 @@ static struct i2c_driver saa7706h_driver = {
430 .name = DRIVER_NAME, 430 .name = DRIVER_NAME,
431 }, 431 },
432 .probe = saa7706h_probe, 432 .probe = saa7706h_probe,
433 .remove = saa7706h_remove, 433 .remove = __devexit_p(saa7706h_remove),
434 .id_table = saa7706h_id, 434 .id_table = saa7706h_id,
435}; 435};
436 436
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 0e740c98786c..969cf494d85b 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -196,9 +196,9 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
196 } 196 }
197 197
198 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 198 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
199 dev_warn(&radio->videodev->dev, "tune does not complete\n"); 199 dev_warn(&radio->videodev.dev, "tune does not complete\n");
200 if (timed_out) 200 if (timed_out)
201 dev_warn(&radio->videodev->dev, 201 dev_warn(&radio->videodev.dev,
202 "tune timed out after %u ms\n", tune_timeout); 202 "tune timed out after %u ms\n", tune_timeout);
203 203
204stop: 204stop:
@@ -262,7 +262,7 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
262 */ 262 */
263int si470x_set_freq(struct si470x_device *radio, unsigned int freq) 263int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
264{ 264{
265 unsigned int spacing, band_bottom; 265 unsigned int spacing, band_bottom, band_top;
266 unsigned short chan; 266 unsigned short chan;
267 267
268 /* Spacing (kHz) */ 268 /* Spacing (kHz) */
@@ -278,19 +278,26 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
278 spacing = 0.050 * FREQ_MUL; break; 278 spacing = 0.050 * FREQ_MUL; break;
279 }; 279 };
280 280
281 /* Bottom of Band (MHz) */ 281 /* Bottom/Top of Band (MHz) */
282 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { 282 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
283 /* 0: 87.5 - 108 MHz (USA, Europe) */ 283 /* 0: 87.5 - 108 MHz (USA, Europe) */
284 case 0: 284 case 0:
285 band_bottom = 87.5 * FREQ_MUL; break; 285 band_bottom = 87.5 * FREQ_MUL;
286 band_top = 108 * FREQ_MUL;
287 break;
286 /* 1: 76 - 108 MHz (Japan wide band) */ 288 /* 1: 76 - 108 MHz (Japan wide band) */
287 default: 289 default:
288 band_bottom = 76 * FREQ_MUL; break; 290 band_bottom = 76 * FREQ_MUL;
291 band_top = 108 * FREQ_MUL;
292 break;
289 /* 2: 76 - 90 MHz (Japan) */ 293 /* 2: 76 - 90 MHz (Japan) */
290 case 2: 294 case 2:
291 band_bottom = 76 * FREQ_MUL; break; 295 band_bottom = 76 * FREQ_MUL;
296 band_top = 90 * FREQ_MUL;
297 break;
292 }; 298 };
293 299
300 freq = clamp(freq, band_bottom, band_top);
294 /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */ 301 /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
295 chan = (freq - band_bottom) / spacing; 302 chan = (freq - band_bottom) / spacing;
296 303
@@ -320,7 +327,7 @@ static int si470x_set_seek(struct si470x_device *radio,
320 radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP; 327 radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
321 retval = si470x_set_register(radio, POWERCFG); 328 retval = si470x_set_register(radio, POWERCFG);
322 if (retval < 0) 329 if (retval < 0)
323 goto done; 330 return retval;
324 331
325 /* currently I2C driver only uses interrupt way to seek */ 332 /* currently I2C driver only uses interrupt way to seek */
326 if (radio->stci_enabled) { 333 if (radio->stci_enabled) {
@@ -344,24 +351,19 @@ static int si470x_set_seek(struct si470x_device *radio,
344 } 351 }
345 352
346 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) 353 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
347 dev_warn(&radio->videodev->dev, "seek does not complete\n"); 354 dev_warn(&radio->videodev.dev, "seek does not complete\n");
348 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) 355 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
349 dev_warn(&radio->videodev->dev, 356 dev_warn(&radio->videodev.dev,
350 "seek failed / band limit reached\n"); 357 "seek failed / band limit reached\n");
351 if (timed_out)
352 dev_warn(&radio->videodev->dev,
353 "seek timed out after %u ms\n", seek_timeout);
354 358
355stop: 359stop:
356 /* stop seeking */ 360 /* stop seeking */
357 radio->registers[POWERCFG] &= ~POWERCFG_SEEK; 361 radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
358 retval = si470x_set_register(radio, POWERCFG); 362 retval = si470x_set_register(radio, POWERCFG);
359 363
360done:
361 /* try again, if timed out */ 364 /* try again, if timed out */
362 if ((retval == 0) && timed_out) 365 if (retval == 0 && timed_out)
363 retval = -EAGAIN; 366 return -EAGAIN;
364
365 return retval; 367 return retval;
366} 368}
367 369
@@ -463,7 +465,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
463 unsigned int block_count = 0; 465 unsigned int block_count = 0;
464 466
465 /* switch on rds reception */ 467 /* switch on rds reception */
466 mutex_lock(&radio->lock);
467 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 468 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
468 si470x_rds_on(radio); 469 si470x_rds_on(radio);
469 470
@@ -505,7 +506,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
505 } 506 }
506 507
507done: 508done:
508 mutex_unlock(&radio->lock);
509 return retval; 509 return retval;
510} 510}
511 511
@@ -517,19 +517,19 @@ static unsigned int si470x_fops_poll(struct file *file,
517 struct poll_table_struct *pts) 517 struct poll_table_struct *pts)
518{ 518{
519 struct si470x_device *radio = video_drvdata(file); 519 struct si470x_device *radio = video_drvdata(file);
520 int retval = 0; 520 unsigned long req_events = poll_requested_events(pts);
521 int retval = v4l2_ctrl_poll(file, pts);
521 522
522 /* switch on rds reception */ 523 if (req_events & (POLLIN | POLLRDNORM)) {
523 524 /* switch on rds reception */
524 mutex_lock(&radio->lock); 525 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
525 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 526 si470x_rds_on(radio);
526 si470x_rds_on(radio);
527 mutex_unlock(&radio->lock);
528 527
529 poll_wait(file, &radio->read_queue, pts); 528 poll_wait(file, &radio->read_queue, pts);
530 529
531 if (radio->rd_index != radio->wr_index) 530 if (radio->rd_index != radio->wr_index)
532 retval = POLLIN | POLLRDNORM; 531 retval |= POLLIN | POLLRDNORM;
532 }
533 533
534 return retval; 534 return retval;
535} 535}
@@ -553,134 +553,26 @@ static const struct v4l2_file_operations si470x_fops = {
553 * Video4Linux Interface 553 * Video4Linux Interface
554 **************************************************************************/ 554 **************************************************************************/
555 555
556/*
557 * si470x_vidioc_queryctrl - enumerate control items
558 */
559static int si470x_vidioc_queryctrl(struct file *file, void *priv,
560 struct v4l2_queryctrl *qc)
561{
562 struct si470x_device *radio = video_drvdata(file);
563 int retval = -EINVAL;
564
565 /* abort if qc->id is below V4L2_CID_BASE */
566 if (qc->id < V4L2_CID_BASE)
567 goto done;
568
569 /* search video control */
570 switch (qc->id) {
571 case V4L2_CID_AUDIO_VOLUME:
572 return v4l2_ctrl_query_fill(qc, 0, 15, 1, 15);
573 case V4L2_CID_AUDIO_MUTE:
574 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
575 }
576
577 /* disable unsupported base controls */
578 /* to satisfy kradio and such apps */
579 if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
580 qc->flags = V4L2_CTRL_FLAG_DISABLED;
581 retval = 0;
582 }
583 556
584done: 557static int si470x_s_ctrl(struct v4l2_ctrl *ctrl)
585 if (retval < 0)
586 dev_warn(&radio->videodev->dev,
587 "query controls failed with %d\n", retval);
588 return retval;
589}
590
591
592/*
593 * si470x_vidioc_g_ctrl - get the value of a control
594 */
595static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
596 struct v4l2_control *ctrl)
597{
598 struct si470x_device *radio = video_drvdata(file);
599 int retval = 0;
600
601 mutex_lock(&radio->lock);
602 /* safety checks */
603 retval = si470x_disconnect_check(radio);
604 if (retval)
605 goto done;
606
607 switch (ctrl->id) {
608 case V4L2_CID_AUDIO_VOLUME:
609 ctrl->value = radio->registers[SYSCONFIG2] &
610 SYSCONFIG2_VOLUME;
611 break;
612 case V4L2_CID_AUDIO_MUTE:
613 ctrl->value = ((radio->registers[POWERCFG] &
614 POWERCFG_DMUTE) == 0) ? 1 : 0;
615 break;
616 default:
617 retval = -EINVAL;
618 }
619
620done:
621 if (retval < 0)
622 dev_warn(&radio->videodev->dev,
623 "get control failed with %d\n", retval);
624
625 mutex_unlock(&radio->lock);
626 return retval;
627}
628
629
630/*
631 * si470x_vidioc_s_ctrl - set the value of a control
632 */
633static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
634 struct v4l2_control *ctrl)
635{ 558{
636 struct si470x_device *radio = video_drvdata(file); 559 struct si470x_device *radio =
637 int retval = 0; 560 container_of(ctrl->handler, struct si470x_device, hdl);
638
639 mutex_lock(&radio->lock);
640 /* safety checks */
641 retval = si470x_disconnect_check(radio);
642 if (retval)
643 goto done;
644 561
645 switch (ctrl->id) { 562 switch (ctrl->id) {
646 case V4L2_CID_AUDIO_VOLUME: 563 case V4L2_CID_AUDIO_VOLUME:
647 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; 564 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
648 radio->registers[SYSCONFIG2] |= ctrl->value; 565 radio->registers[SYSCONFIG2] |= ctrl->val;
649 retval = si470x_set_register(radio, SYSCONFIG2); 566 return si470x_set_register(radio, SYSCONFIG2);
650 break;
651 case V4L2_CID_AUDIO_MUTE: 567 case V4L2_CID_AUDIO_MUTE:
652 if (ctrl->value == 1) 568 if (ctrl->val)
653 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; 569 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
654 else 570 else
655 radio->registers[POWERCFG] |= POWERCFG_DMUTE; 571 radio->registers[POWERCFG] |= POWERCFG_DMUTE;
656 retval = si470x_set_register(radio, POWERCFG); 572 return si470x_set_register(radio, POWERCFG);
657 break;
658 default: 573 default:
659 retval = -EINVAL; 574 return -EINVAL;
660 } 575 }
661
662done:
663 if (retval < 0)
664 dev_warn(&radio->videodev->dev,
665 "set control failed with %d\n", retval);
666 mutex_unlock(&radio->lock);
667 return retval;
668}
669
670
671/*
672 * si470x_vidioc_g_audio - get audio attributes
673 */
674static int si470x_vidioc_g_audio(struct file *file, void *priv,
675 struct v4l2_audio *audio)
676{
677 /* driver constants */
678 audio->index = 0;
679 strcpy(audio->name, "Radio");
680 audio->capability = V4L2_AUDCAP_STEREO;
681 audio->mode = 0;
682
683 return 0;
684} 576}
685 577
686 578
@@ -691,22 +583,14 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
691 struct v4l2_tuner *tuner) 583 struct v4l2_tuner *tuner)
692{ 584{
693 struct si470x_device *radio = video_drvdata(file); 585 struct si470x_device *radio = video_drvdata(file);
694 int retval = 0; 586 int retval;
695
696 mutex_lock(&radio->lock);
697 /* safety checks */
698 retval = si470x_disconnect_check(radio);
699 if (retval)
700 goto done;
701 587
702 if (tuner->index != 0) { 588 if (tuner->index != 0)
703 retval = -EINVAL; 589 return -EINVAL;
704 goto done;
705 }
706 590
707 retval = si470x_get_register(radio, STATUSRSSI); 591 retval = si470x_get_register(radio, STATUSRSSI);
708 if (retval < 0) 592 if (retval < 0)
709 goto done; 593 return retval;
710 594
711 /* driver constants */ 595 /* driver constants */
712 strcpy(tuner->name, "FM"); 596 strcpy(tuner->name, "FM");
@@ -737,7 +621,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
737 if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) 621 if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
738 tuner->rxsubchans = V4L2_TUNER_SUB_MONO; 622 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
739 else 623 else
740 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 624 tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
741 /* If there is a reliable method of detecting an RDS channel, 625 /* If there is a reliable method of detecting an RDS channel,
742 then this code should check for that before setting this 626 then this code should check for that before setting this
743 RDS subchannel. */ 627 RDS subchannel. */
@@ -754,16 +638,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
754 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); 638 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
755 /* the ideal factor is 0xffff/75 = 873,8 */ 639 /* the ideal factor is 0xffff/75 = 873,8 */
756 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); 640 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
641 if (tuner->signal > 0xffff)
642 tuner->signal = 0xffff;
757 643
758 /* automatic frequency control: -1: freq to low, 1 freq to high */ 644 /* automatic frequency control: -1: freq to low, 1 freq to high */
759 /* AFCRL does only indicate that freq. differs, not if too low/high */ 645 /* AFCRL does only indicate that freq. differs, not if too low/high */
760 tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0; 646 tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
761 647
762done:
763 if (retval < 0)
764 dev_warn(&radio->videodev->dev,
765 "get tuner failed with %d\n", retval);
766 mutex_unlock(&radio->lock);
767 return retval; 648 return retval;
768} 649}
769 650
@@ -775,16 +656,9 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
775 struct v4l2_tuner *tuner) 656 struct v4l2_tuner *tuner)
776{ 657{
777 struct si470x_device *radio = video_drvdata(file); 658 struct si470x_device *radio = video_drvdata(file);
778 int retval = 0;
779
780 mutex_lock(&radio->lock);
781 /* safety checks */
782 retval = si470x_disconnect_check(radio);
783 if (retval)
784 goto done;
785 659
786 if (tuner->index != 0) 660 if (tuner->index != 0)
787 goto done; 661 return -EINVAL;
788 662
789 /* mono/stereo selector */ 663 /* mono/stereo selector */
790 switch (tuner->audmode) { 664 switch (tuner->audmode) {
@@ -792,20 +666,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
792 radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ 666 radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
793 break; 667 break;
794 case V4L2_TUNER_MODE_STEREO: 668 case V4L2_TUNER_MODE_STEREO:
669 default:
795 radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ 670 radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
796 break; 671 break;
797 default:
798 goto done;
799 } 672 }
800 673
801 retval = si470x_set_register(radio, POWERCFG); 674 return si470x_set_register(radio, POWERCFG);
802
803done:
804 if (retval < 0)
805 dev_warn(&radio->videodev->dev,
806 "set tuner failed with %d\n", retval);
807 mutex_unlock(&radio->lock);
808 return retval;
809} 675}
810 676
811 677
@@ -816,28 +682,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
816 struct v4l2_frequency *freq) 682 struct v4l2_frequency *freq)
817{ 683{
818 struct si470x_device *radio = video_drvdata(file); 684 struct si470x_device *radio = video_drvdata(file);
819 int retval = 0;
820
821 /* safety checks */
822 mutex_lock(&radio->lock);
823 retval = si470x_disconnect_check(radio);
824 if (retval)
825 goto done;
826 685
827 if (freq->tuner != 0) { 686 if (freq->tuner != 0)
828 retval = -EINVAL; 687 return -EINVAL;
829 goto done;
830 }
831 688
832 freq->type = V4L2_TUNER_RADIO; 689 freq->type = V4L2_TUNER_RADIO;
833 retval = si470x_get_freq(radio, &freq->frequency); 690 return si470x_get_freq(radio, &freq->frequency);
834
835done:
836 if (retval < 0)
837 dev_warn(&radio->videodev->dev,
838 "get frequency failed with %d\n", retval);
839 mutex_unlock(&radio->lock);
840 return retval;
841} 691}
842 692
843 693
@@ -848,27 +698,11 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
848 struct v4l2_frequency *freq) 698 struct v4l2_frequency *freq)
849{ 699{
850 struct si470x_device *radio = video_drvdata(file); 700 struct si470x_device *radio = video_drvdata(file);
851 int retval = 0;
852
853 mutex_lock(&radio->lock);
854 /* safety checks */
855 retval = si470x_disconnect_check(radio);
856 if (retval)
857 goto done;
858 701
859 if (freq->tuner != 0) { 702 if (freq->tuner != 0)
860 retval = -EINVAL; 703 return -EINVAL;
861 goto done;
862 }
863 704
864 retval = si470x_set_freq(radio, freq->frequency); 705 return si470x_set_freq(radio, freq->frequency);
865
866done:
867 if (retval < 0)
868 dev_warn(&radio->videodev->dev,
869 "set frequency failed with %d\n", retval);
870 mutex_unlock(&radio->lock);
871 return retval;
872} 706}
873 707
874 708
@@ -879,44 +713,29 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
879 struct v4l2_hw_freq_seek *seek) 713 struct v4l2_hw_freq_seek *seek)
880{ 714{
881 struct si470x_device *radio = video_drvdata(file); 715 struct si470x_device *radio = video_drvdata(file);
882 int retval = 0;
883
884 mutex_lock(&radio->lock);
885 /* safety checks */
886 retval = si470x_disconnect_check(radio);
887 if (retval)
888 goto done;
889
890 if (seek->tuner != 0) {
891 retval = -EINVAL;
892 goto done;
893 }
894 716
895 retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward); 717 if (seek->tuner != 0)
718 return -EINVAL;
896 719
897done: 720 return si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
898 if (retval < 0)
899 dev_warn(&radio->videodev->dev,
900 "set hardware frequency seek failed with %d\n", retval);
901 mutex_unlock(&radio->lock);
902 return retval;
903} 721}
904 722
723const struct v4l2_ctrl_ops si470x_ctrl_ops = {
724 .s_ctrl = si470x_s_ctrl,
725};
905 726
906/* 727/*
907 * si470x_ioctl_ops - video device ioctl operations 728 * si470x_ioctl_ops - video device ioctl operations
908 */ 729 */
909static const struct v4l2_ioctl_ops si470x_ioctl_ops = { 730static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
910 .vidioc_querycap = si470x_vidioc_querycap, 731 .vidioc_querycap = si470x_vidioc_querycap,
911 .vidioc_queryctrl = si470x_vidioc_queryctrl,
912 .vidioc_g_ctrl = si470x_vidioc_g_ctrl,
913 .vidioc_s_ctrl = si470x_vidioc_s_ctrl,
914 .vidioc_g_audio = si470x_vidioc_g_audio,
915 .vidioc_g_tuner = si470x_vidioc_g_tuner, 732 .vidioc_g_tuner = si470x_vidioc_g_tuner,
916 .vidioc_s_tuner = si470x_vidioc_s_tuner, 733 .vidioc_s_tuner = si470x_vidioc_s_tuner,
917 .vidioc_g_frequency = si470x_vidioc_g_frequency, 734 .vidioc_g_frequency = si470x_vidioc_g_frequency,
918 .vidioc_s_frequency = si470x_vidioc_s_frequency, 735 .vidioc_s_frequency = si470x_vidioc_s_frequency,
919 .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, 736 .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
737 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
738 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
920}; 739};
921 740
922 741
@@ -926,6 +745,6 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
926struct video_device si470x_viddev_template = { 745struct video_device si470x_viddev_template = {
927 .fops = &si470x_fops, 746 .fops = &si470x_fops,
928 .name = DRIVER_NAME, 747 .name = DRIVER_NAME,
929 .release = video_device_release, 748 .release = video_device_release_empty,
930 .ioctl_ops = &si470x_ioctl_ops, 749 .ioctl_ops = &si470x_ioctl_ops,
931}; 750};
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 9b546a5523f3..a80044c5874e 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -162,20 +162,6 @@ static int si470x_get_all_registers(struct si470x_device *radio)
162 162
163 163
164/************************************************************************** 164/**************************************************************************
165 * General Driver Functions - DISCONNECT_CHECK
166 **************************************************************************/
167
168/*
169 * si470x_disconnect_check - check whether radio disconnects
170 */
171int si470x_disconnect_check(struct si470x_device *radio)
172{
173 return 0;
174}
175
176
177
178/**************************************************************************
179 * File Operations Interface 165 * File Operations Interface
180 **************************************************************************/ 166 **************************************************************************/
181 167
@@ -185,12 +171,12 @@ int si470x_disconnect_check(struct si470x_device *radio)
185int si470x_fops_open(struct file *file) 171int si470x_fops_open(struct file *file)
186{ 172{
187 struct si470x_device *radio = video_drvdata(file); 173 struct si470x_device *radio = video_drvdata(file);
188 int retval = 0; 174 int retval = v4l2_fh_open(file);
189 175
190 mutex_lock(&radio->lock); 176 if (retval)
191 radio->users++; 177 return retval;
192 178
193 if (radio->users == 1) { 179 if (v4l2_fh_is_singular_file(file)) {
194 /* start radio */ 180 /* start radio */
195 retval = si470x_start(radio); 181 retval = si470x_start(radio);
196 if (retval < 0) 182 if (retval < 0)
@@ -205,7 +191,8 @@ int si470x_fops_open(struct file *file)
205 } 191 }
206 192
207done: 193done:
208 mutex_unlock(&radio->lock); 194 if (retval)
195 v4l2_fh_release(file);
209 return retval; 196 return retval;
210} 197}
211 198
@@ -216,21 +203,12 @@ done:
216int si470x_fops_release(struct file *file) 203int si470x_fops_release(struct file *file)
217{ 204{
218 struct si470x_device *radio = video_drvdata(file); 205 struct si470x_device *radio = video_drvdata(file);
219 int retval = 0;
220
221 /* safety check */
222 if (!radio)
223 return -ENODEV;
224 206
225 mutex_lock(&radio->lock); 207 if (v4l2_fh_is_singular_file(file))
226 radio->users--;
227 if (radio->users == 0)
228 /* stop radio */ 208 /* stop radio */
229 retval = si470x_stop(radio); 209 si470x_stop(radio);
230 210
231 mutex_unlock(&radio->lock); 211 return v4l2_fh_release(file);
232
233 return retval;
234} 212}
235 213
236 214
@@ -371,32 +349,25 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
371 goto err_initial; 349 goto err_initial;
372 } 350 }
373 351
374 radio->users = 0;
375 radio->client = client; 352 radio->client = client;
376 mutex_init(&radio->lock); 353 mutex_init(&radio->lock);
377 354
378 /* video device allocation and initialization */ 355 /* video device initialization */
379 radio->videodev = video_device_alloc(); 356 radio->videodev = si470x_viddev_template;
380 if (!radio->videodev) { 357 video_set_drvdata(&radio->videodev, radio);
381 retval = -ENOMEM;
382 goto err_radio;
383 }
384 memcpy(radio->videodev, &si470x_viddev_template,
385 sizeof(si470x_viddev_template));
386 video_set_drvdata(radio->videodev, radio);
387 358
388 /* power up : need 110ms */ 359 /* power up : need 110ms */
389 radio->registers[POWERCFG] = POWERCFG_ENABLE; 360 radio->registers[POWERCFG] = POWERCFG_ENABLE;
390 if (si470x_set_register(radio, POWERCFG) < 0) { 361 if (si470x_set_register(radio, POWERCFG) < 0) {
391 retval = -EIO; 362 retval = -EIO;
392 goto err_video; 363 goto err_radio;
393 } 364 }
394 msleep(110); 365 msleep(110);
395 366
396 /* get device and chip versions */ 367 /* get device and chip versions */
397 if (si470x_get_all_registers(radio) < 0) { 368 if (si470x_get_all_registers(radio) < 0) {
398 retval = -EIO; 369 retval = -EIO;
399 goto err_video; 370 goto err_radio;
400 } 371 }
401 dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", 372 dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
402 radio->registers[DEVICEID], radio->registers[CHIPID]); 373 radio->registers[DEVICEID], radio->registers[CHIPID]);
@@ -427,7 +398,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
427 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); 398 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
428 if (!radio->buffer) { 399 if (!radio->buffer) {
429 retval = -EIO; 400 retval = -EIO;
430 goto err_video; 401 goto err_radio;
431 } 402 }
432 403
433 /* rds buffer configuration */ 404 /* rds buffer configuration */
@@ -447,7 +418,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
447 } 418 }
448 419
449 /* register video device */ 420 /* register video device */
450 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, 421 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
451 radio_nr); 422 radio_nr);
452 if (retval) { 423 if (retval) {
453 dev_warn(&client->dev, "Could not register video device\n"); 424 dev_warn(&client->dev, "Could not register video device\n");
@@ -460,8 +431,6 @@ err_all:
460 free_irq(client->irq, radio); 431 free_irq(client->irq, radio);
461err_rds: 432err_rds:
462 kfree(radio->buffer); 433 kfree(radio->buffer);
463err_video:
464 video_device_release(radio->videodev);
465err_radio: 434err_radio:
466 kfree(radio); 435 kfree(radio);
467err_initial: 436err_initial:
@@ -477,7 +446,7 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
477 struct si470x_device *radio = i2c_get_clientdata(client); 446 struct si470x_device *radio = i2c_get_clientdata(client);
478 447
479 free_irq(client->irq, radio); 448 free_irq(client->irq, radio);
480 video_unregister_device(radio->videodev); 449 video_unregister_device(&radio->videodev);
481 kfree(radio); 450 kfree(radio);
482 451
483 return 0; 452 return 0;
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index b7debb67932a..e9f638761296 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -367,23 +367,6 @@ static int si470x_get_scratch_page_versions(struct si470x_device *radio)
367 367
368 368
369/************************************************************************** 369/**************************************************************************
370 * General Driver Functions - DISCONNECT_CHECK
371 **************************************************************************/
372
373/*
374 * si470x_disconnect_check - check whether radio disconnects
375 */
376int si470x_disconnect_check(struct si470x_device *radio)
377{
378 if (radio->disconnected)
379 return -EIO;
380 else
381 return 0;
382}
383
384
385
386/**************************************************************************
387 * RDS Driver Functions 370 * RDS Driver Functions
388 **************************************************************************/ 371 **************************************************************************/
389 372
@@ -414,9 +397,6 @@ static void si470x_int_in_callback(struct urb *urb)
414 } 397 }
415 } 398 }
416 399
417 /* safety checks */
418 if (radio->disconnected)
419 return;
420 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 400 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
421 goto resubmit; 401 goto resubmit;
422 402
@@ -501,112 +481,30 @@ resubmit:
501} 481}
502 482
503 483
504
505/**************************************************************************
506 * File Operations Interface
507 **************************************************************************/
508
509/*
510 * si470x_fops_open - file open
511 */
512int si470x_fops_open(struct file *file) 484int si470x_fops_open(struct file *file)
513{ 485{
514 struct si470x_device *radio = video_drvdata(file); 486 return v4l2_fh_open(file);
515 int retval;
516
517 mutex_lock(&radio->lock);
518 radio->users++;
519
520 retval = usb_autopm_get_interface(radio->intf);
521 if (retval < 0) {
522 radio->users--;
523 retval = -EIO;
524 goto done;
525 }
526
527 if (radio->users == 1) {
528 /* start radio */
529 retval = si470x_start(radio);
530 if (retval < 0) {
531 usb_autopm_put_interface(radio->intf);
532 goto done;
533 }
534
535 /* initialize interrupt urb */
536 usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
537 usb_rcvintpipe(radio->usbdev,
538 radio->int_in_endpoint->bEndpointAddress),
539 radio->int_in_buffer,
540 le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
541 si470x_int_in_callback,
542 radio,
543 radio->int_in_endpoint->bInterval);
544
545 radio->int_in_running = 1;
546 mb();
547
548 retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
549 if (retval) {
550 dev_info(&radio->intf->dev,
551 "submitting int urb failed (%d)\n", retval);
552 radio->int_in_running = 0;
553 usb_autopm_put_interface(radio->intf);
554 }
555 }
556
557done:
558 mutex_unlock(&radio->lock);
559 return retval;
560} 487}
561 488
562
563/*
564 * si470x_fops_release - file release
565 */
566int si470x_fops_release(struct file *file) 489int si470x_fops_release(struct file *file)
567{ 490{
568 struct si470x_device *radio = video_drvdata(file); 491 return v4l2_fh_release(file);
569 int retval = 0; 492}
570
571 /* safety check */
572 if (!radio) {
573 retval = -ENODEV;
574 goto done;
575 }
576
577 mutex_lock(&radio->lock);
578 radio->users--;
579 if (radio->users == 0) {
580 /* shutdown interrupt handler */
581 if (radio->int_in_running) {
582 radio->int_in_running = 0;
583 if (radio->int_in_urb)
584 usb_kill_urb(radio->int_in_urb);
585 }
586
587 if (radio->disconnected) {
588 video_unregister_device(radio->videodev);
589 kfree(radio->int_in_buffer);
590 kfree(radio->buffer);
591 mutex_unlock(&radio->lock);
592 kfree(radio);
593 goto done;
594 }
595 493
596 /* cancel read processes */ 494static void si470x_usb_release(struct v4l2_device *v4l2_dev)
597 wake_up_interruptible(&radio->read_queue); 495{
496 struct si470x_device *radio =
497 container_of(v4l2_dev, struct si470x_device, v4l2_dev);
598 498
599 /* stop radio */ 499 usb_free_urb(radio->int_in_urb);
600 retval = si470x_stop(radio); 500 v4l2_ctrl_handler_free(&radio->hdl);
601 usb_autopm_put_interface(radio->intf); 501 v4l2_device_unregister(&radio->v4l2_dev);
602 } 502 kfree(radio->int_in_buffer);
603 mutex_unlock(&radio->lock); 503 kfree(radio->buffer);
604done: 504 kfree(radio);
605 return retval;
606} 505}
607 506
608 507
609
610/************************************************************************** 508/**************************************************************************
611 * Video4Linux Interface 509 * Video4Linux Interface
612 **************************************************************************/ 510 **************************************************************************/
@@ -623,13 +521,45 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
623 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); 521 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
624 usb_make_path(radio->usbdev, capability->bus_info, 522 usb_make_path(radio->usbdev, capability->bus_info,
625 sizeof(capability->bus_info)); 523 sizeof(capability->bus_info));
626 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | 524 capability->device_caps = V4L2_CAP_HW_FREQ_SEEK |
627 V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; 525 V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
628 526 capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
629 return 0; 527 return 0;
630} 528}
631 529
632 530
531static int si470x_start_usb(struct si470x_device *radio)
532{
533 int retval;
534
535 /* start radio */
536 retval = si470x_start(radio);
537 if (retval < 0)
538 return retval;
539
540 v4l2_ctrl_handler_setup(&radio->hdl);
541
542 /* initialize interrupt urb */
543 usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
544 usb_rcvintpipe(radio->usbdev,
545 radio->int_in_endpoint->bEndpointAddress),
546 radio->int_in_buffer,
547 le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
548 si470x_int_in_callback,
549 radio,
550 radio->int_in_endpoint->bInterval);
551
552 radio->int_in_running = 1;
553 mb();
554
555 retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
556 if (retval) {
557 dev_info(&radio->intf->dev,
558 "submitting int urb failed (%d)\n", retval);
559 radio->int_in_running = 0;
560 }
561 return retval;
562}
633 563
634/************************************************************************** 564/**************************************************************************
635 * USB Interface 565 * USB Interface
@@ -653,8 +583,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
653 retval = -ENOMEM; 583 retval = -ENOMEM;
654 goto err_initial; 584 goto err_initial;
655 } 585 }
656 radio->users = 0;
657 radio->disconnected = 0;
658 radio->usbdev = interface_to_usbdev(intf); 586 radio->usbdev = interface_to_usbdev(intf);
659 radio->intf = intf; 587 radio->intf = intf;
660 mutex_init(&radio->lock); 588 mutex_init(&radio->lock);
@@ -691,20 +619,35 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
691 goto err_intbuffer; 619 goto err_intbuffer;
692 } 620 }
693 621
694 /* video device allocation and initialization */ 622 radio->v4l2_dev.release = si470x_usb_release;
695 radio->videodev = video_device_alloc(); 623 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
696 if (!radio->videodev) { 624 if (retval < 0) {
697 retval = -ENOMEM; 625 dev_err(&intf->dev, "couldn't register v4l2_device\n");
698 goto err_urb; 626 goto err_urb;
699 } 627 }
700 memcpy(radio->videodev, &si470x_viddev_template, 628
701 sizeof(si470x_viddev_template)); 629 v4l2_ctrl_handler_init(&radio->hdl, 2);
702 video_set_drvdata(radio->videodev, radio); 630 v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
631 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
632 v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops,
633 V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15);
634 if (radio->hdl.error) {
635 retval = radio->hdl.error;
636 dev_err(&intf->dev, "couldn't register control\n");
637 goto err_dev;
638 }
639 radio->videodev = si470x_viddev_template;
640 radio->videodev.ctrl_handler = &radio->hdl;
641 radio->videodev.lock = &radio->lock;
642 radio->videodev.v4l2_dev = &radio->v4l2_dev;
643 radio->videodev.release = video_device_release_empty;
644 set_bit(V4L2_FL_USE_FH_PRIO, &radio->videodev.flags);
645 video_set_drvdata(&radio->videodev, radio);
703 646
704 /* get device and chip versions */ 647 /* get device and chip versions */
705 if (si470x_get_all_registers(radio) < 0) { 648 if (si470x_get_all_registers(radio) < 0) {
706 retval = -EIO; 649 retval = -EIO;
707 goto err_video; 650 goto err_ctrl;
708 } 651 }
709 dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", 652 dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
710 radio->registers[DEVICEID], radio->registers[CHIPID]); 653 radio->registers[DEVICEID], radio->registers[CHIPID]);
@@ -721,7 +664,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
721 /* get software and hardware versions */ 664 /* get software and hardware versions */
722 if (si470x_get_scratch_page_versions(radio) < 0) { 665 if (si470x_get_scratch_page_versions(radio) < 0) {
723 retval = -EIO; 666 retval = -EIO;
724 goto err_video; 667 goto err_ctrl;
725 } 668 }
726 dev_info(&intf->dev, "software version %d, hardware version %d\n", 669 dev_info(&intf->dev, "software version %d, hardware version %d\n",
727 radio->software_version, radio->hardware_version); 670 radio->software_version, radio->hardware_version);
@@ -764,28 +707,35 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
764 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); 707 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
765 if (!radio->buffer) { 708 if (!radio->buffer) {
766 retval = -EIO; 709 retval = -EIO;
767 goto err_video; 710 goto err_ctrl;
768 } 711 }
769 712
770 /* rds buffer configuration */ 713 /* rds buffer configuration */
771 radio->wr_index = 0; 714 radio->wr_index = 0;
772 radio->rd_index = 0; 715 radio->rd_index = 0;
773 init_waitqueue_head(&radio->read_queue); 716 init_waitqueue_head(&radio->read_queue);
717 usb_set_intfdata(intf, radio);
718
719 /* start radio */
720 retval = si470x_start_usb(radio);
721 if (retval < 0)
722 goto err_all;
774 723
775 /* register video device */ 724 /* register video device */
776 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, 725 retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO,
777 radio_nr); 726 radio_nr);
778 if (retval) { 727 if (retval) {
779 dev_warn(&intf->dev, "Could not register video device\n"); 728 dev_err(&intf->dev, "Could not register video device\n");
780 goto err_all; 729 goto err_all;
781 } 730 }
782 usb_set_intfdata(intf, radio);
783 731
784 return 0; 732 return 0;
785err_all: 733err_all:
786 kfree(radio->buffer); 734 kfree(radio->buffer);
787err_video: 735err_ctrl:
788 video_device_release(radio->videodev); 736 v4l2_ctrl_handler_free(&radio->hdl);
737err_dev:
738 v4l2_device_unregister(&radio->v4l2_dev);
789err_urb: 739err_urb:
790 usb_free_urb(radio->int_in_urb); 740 usb_free_urb(radio->int_in_urb);
791err_intbuffer: 741err_intbuffer:
@@ -803,8 +753,22 @@ err_initial:
803static int si470x_usb_driver_suspend(struct usb_interface *intf, 753static int si470x_usb_driver_suspend(struct usb_interface *intf,
804 pm_message_t message) 754 pm_message_t message)
805{ 755{
756 struct si470x_device *radio = usb_get_intfdata(intf);
757
806 dev_info(&intf->dev, "suspending now...\n"); 758 dev_info(&intf->dev, "suspending now...\n");
807 759
760 /* shutdown interrupt handler */
761 if (radio->int_in_running) {
762 radio->int_in_running = 0;
763 if (radio->int_in_urb)
764 usb_kill_urb(radio->int_in_urb);
765 }
766
767 /* cancel read processes */
768 wake_up_interruptible(&radio->read_queue);
769
770 /* stop radio */
771 si470x_stop(radio);
808 return 0; 772 return 0;
809} 773}
810 774
@@ -814,9 +778,12 @@ static int si470x_usb_driver_suspend(struct usb_interface *intf,
814 */ 778 */
815static int si470x_usb_driver_resume(struct usb_interface *intf) 779static int si470x_usb_driver_resume(struct usb_interface *intf)
816{ 780{
781 struct si470x_device *radio = usb_get_intfdata(intf);
782
817 dev_info(&intf->dev, "resuming now...\n"); 783 dev_info(&intf->dev, "resuming now...\n");
818 784
819 return 0; 785 /* start radio */
786 return si470x_start_usb(radio);
820} 787}
821 788
822 789
@@ -828,28 +795,22 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
828 struct si470x_device *radio = usb_get_intfdata(intf); 795 struct si470x_device *radio = usb_get_intfdata(intf);
829 796
830 mutex_lock(&radio->lock); 797 mutex_lock(&radio->lock);
831 radio->disconnected = 1; 798 v4l2_device_disconnect(&radio->v4l2_dev);
799 video_unregister_device(&radio->videodev);
832 usb_set_intfdata(intf, NULL); 800 usb_set_intfdata(intf, NULL);
833 if (radio->users == 0) { 801 mutex_unlock(&radio->lock);
834 /* set led to disconnect state */ 802 v4l2_device_put(&radio->v4l2_dev);
835 si470x_set_led_state(radio, BLINK_ORANGE_LED);
836
837 /* Free data structures. */
838 usb_free_urb(radio->int_in_urb);
839
840 kfree(radio->int_in_buffer);
841 video_unregister_device(radio->videodev);
842 kfree(radio->buffer);
843 mutex_unlock(&radio->lock);
844 kfree(radio);
845 } else {
846 mutex_unlock(&radio->lock);
847 }
848} 803}
849 804
850 805
851/* 806/*
852 * si470x_usb_driver - usb driver interface 807 * si470x_usb_driver - usb driver interface
808 *
809 * A note on suspend/resume: this driver had only empty suspend/resume
810 * functions, and when I tried to test suspend/resume it always disconnected
811 * instead of resuming (using my ADS InstantFM stick). So I've decided to
812 * remove these callbacks until someone else with better hardware can
813 * implement and test this.
853 */ 814 */
854static struct usb_driver si470x_usb_driver = { 815static struct usb_driver si470x_usb_driver = {
855 .name = DRIVER_NAME, 816 .name = DRIVER_NAME,
@@ -857,8 +818,8 @@ static struct usb_driver si470x_usb_driver = {
857 .disconnect = si470x_usb_driver_disconnect, 818 .disconnect = si470x_usb_driver_disconnect,
858 .suspend = si470x_usb_driver_suspend, 819 .suspend = si470x_usb_driver_suspend,
859 .resume = si470x_usb_driver_resume, 820 .resume = si470x_usb_driver_resume,
821 .reset_resume = si470x_usb_driver_resume,
860 .id_table = si470x_usb_driver_id_table, 822 .id_table = si470x_usb_driver_id_table,
861 .supports_autosuspend = 1,
862}; 823};
863 824
864module_usb_driver(si470x_usb_driver); 825module_usb_driver(si470x_usb_driver);
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index f300a55ed85c..4921cab8e0fa 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -36,6 +36,9 @@
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-ioctl.h> 38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-ctrls.h>
40#include <media/v4l2-event.h>
41#include <media/v4l2-device.h>
39#include <asm/unaligned.h> 42#include <asm/unaligned.h>
40 43
41 44
@@ -141,10 +144,9 @@
141 * si470x_device - private data 144 * si470x_device - private data
142 */ 145 */
143struct si470x_device { 146struct si470x_device {
144 struct video_device *videodev; 147 struct v4l2_device v4l2_dev;
145 148 struct video_device videodev;
146 /* driver management */ 149 struct v4l2_ctrl_handler hdl;
147 unsigned int users;
148 150
149 /* Silabs internal registers (0..15) */ 151 /* Silabs internal registers (0..15) */
150 unsigned short registers[RADIO_REGISTER_NUM]; 152 unsigned short registers[RADIO_REGISTER_NUM];
@@ -174,9 +176,6 @@ struct si470x_device {
174 /* scratch page */ 176 /* scratch page */
175 unsigned char software_version; 177 unsigned char software_version;
176 unsigned char hardware_version; 178 unsigned char hardware_version;
177
178 /* driver management */
179 unsigned char disconnected;
180#endif 179#endif
181 180
182#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) 181#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
@@ -213,6 +212,7 @@ struct si470x_device {
213 * Common Functions 212 * Common Functions
214 **************************************************************************/ 213 **************************************************************************/
215extern struct video_device si470x_viddev_template; 214extern struct video_device si470x_viddev_template;
215extern const struct v4l2_ctrl_ops si470x_ctrl_ops;
216int si470x_get_register(struct si470x_device *radio, int regnr); 216int si470x_get_register(struct si470x_device *radio, int regnr);
217int si470x_set_register(struct si470x_device *radio, int regnr); 217int si470x_set_register(struct si470x_device *radio, int regnr);
218int si470x_disconnect_check(struct si470x_device *radio); 218int si470x_disconnect_check(struct si470x_device *radio);
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 6418c4c9faf1..06d47e5cce9f 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -211,7 +211,7 @@ static struct i2c_driver tef6862_driver = {
211 .name = DRIVER_NAME, 211 .name = DRIVER_NAME,
212 }, 212 },
213 .probe = tef6862_probe, 213 .probe = tef6862_probe,
214 .remove = tef6862_remove, 214 .remove = __devexit_p(tef6862_remove),
215 .id_table = tef6862_id, 215 .id_table = tef6862_id,
216}; 216};
217 217
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
index 077d369a0173..080b96a61f1a 100644
--- a/drivers/media/radio/wl128x/fmdrv_v4l2.c
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -518,6 +518,10 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
518 video_set_drvdata(gradio_dev, fmdev); 518 video_set_drvdata(gradio_dev, fmdev);
519 519
520 gradio_dev->lock = &fmdev->mutex; 520 gradio_dev->lock = &fmdev->mutex;
521 /* Locking in file operations other than ioctl should be done
522 by the driver, not the V4L2 core.
523 This driver needs auditing so that this flag can be removed. */
524 set_bit(V4L2_FL_LOCK_ALL_FOPS, &gradio_dev->flags);
521 525
522 /* Register with V4L2 subsystem as RADIO device */ 526 /* Register with V4L2 subsystem as RADIO device */
523 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) { 527 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index a3fbb21350e9..f97eeb870455 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -69,6 +69,7 @@ config IR_JVC_DECODER
69config IR_SONY_DECODER 69config IR_SONY_DECODER
70 tristate "Enable IR raw decoder for the Sony protocol" 70 tristate "Enable IR raw decoder for the Sony protocol"
71 depends on RC_CORE 71 depends on RC_CORE
72 select BITREVERSE
72 default y 73 default y
73 74
74 ---help--- 75 ---help---
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index baf907b3ce76..7be377fc1be8 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * USB ATI Remote support 2 * USB ATI Remote support
3 * 3 *
4 * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi> 4 * Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi>
5 * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net> 5 * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
6 * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev 6 * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
7 * 7 *
@@ -151,13 +151,57 @@ MODULE_PARM_DESC(mouse, "Enable mouse device, default = yes");
151#undef err 151#undef err
152#define err(format, arg...) printk(KERN_ERR format , ## arg) 152#define err(format, arg...) printk(KERN_ERR format , ## arg)
153 153
154struct ati_receiver_type {
155 /* either default_keymap or get_default_keymap should be set */
156 const char *default_keymap;
157 const char *(*get_default_keymap)(struct usb_interface *interface);
158};
159
160static const char *get_medion_keymap(struct usb_interface *interface)
161{
162 struct usb_device *udev = interface_to_usbdev(interface);
163
164 /*
165 * There are many different Medion remotes shipped with a receiver
166 * with the same usb id, but the receivers have subtle differences
167 * in the USB descriptors allowing us to detect them.
168 */
169
170 if (udev->manufacturer && udev->product) {
171 if (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP) {
172
173 if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc")
174 && !strcmp(udev->product, "USB Receiver"))
175 return RC_MAP_MEDION_X10_DIGITAINER;
176
177 if (!strcmp(udev->manufacturer, "X10 WTI")
178 && !strcmp(udev->product, "RF receiver"))
179 return RC_MAP_MEDION_X10_OR2X;
180 } else {
181
182 if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc")
183 && !strcmp(udev->product, "USB Receiver"))
184 return RC_MAP_MEDION_X10;
185 }
186 }
187
188 dev_info(&interface->dev,
189 "Unknown Medion X10 receiver, using default ati_remote Medion keymap\n");
190
191 return RC_MAP_MEDION_X10;
192}
193
194static const struct ati_receiver_type type_ati = { .default_keymap = RC_MAP_ATI_X10 };
195static const struct ati_receiver_type type_medion = { .get_default_keymap = get_medion_keymap };
196static const struct ati_receiver_type type_firefly = { .default_keymap = RC_MAP_SNAPSTREAM_FIREFLY };
197
154static struct usb_device_id ati_remote_table[] = { 198static struct usb_device_id ati_remote_table[] = {
155 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 199 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
156 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 200 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
157 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 201 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
158 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 202 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
159 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_MEDION_X10 }, 203 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_medion },
160 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_SNAPSTREAM_FIREFLY }, 204 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_firefly },
161 {} /* Terminating entry */ 205 {} /* Terminating entry */
162}; 206};
163 207
@@ -445,6 +489,7 @@ static void ati_remote_input_report(struct urb *urb)
445 int acc; 489 int acc;
446 int remote_num; 490 int remote_num;
447 unsigned char scancode; 491 unsigned char scancode;
492 u32 wheel_keycode = KEY_RESERVED;
448 int i; 493 int i;
449 494
450 /* 495 /*
@@ -484,26 +529,33 @@ static void ati_remote_input_report(struct urb *urb)
484 */ 529 */
485 scancode = data[2] & 0x7f; 530 scancode = data[2] & 0x7f;
486 531
487 /* Look up event code index in the mouse translation table. */ 532 dbginfo(&ati_remote->interface->dev,
488 for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { 533 "channel 0x%02x; key data %02x, scancode %02x\n",
489 if (scancode == ati_remote_tbl[i].data) { 534 remote_num, data[2], scancode);
490 index = i; 535
491 break; 536 if (scancode >= 0x70) {
537 /*
538 * This is either a mouse or scrollwheel event, depending on
539 * the remote/keymap.
540 * Get the keycode assigned to scancode 0x78/0x70. If it is
541 * set, assume this is a scrollwheel up/down event.
542 */
543 wheel_keycode = rc_g_keycode_from_table(ati_remote->rdev,
544 scancode & 0x78);
545
546 if (wheel_keycode == KEY_RESERVED) {
547 /* scrollwheel was not mapped, assume mouse */
548
549 /* Look up event code index in the mouse translation table. */
550 for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
551 if (scancode == ati_remote_tbl[i].data) {
552 index = i;
553 break;
554 }
555 }
492 } 556 }
493 } 557 }
494 558
495 if (index >= 0) {
496 dbginfo(&ati_remote->interface->dev,
497 "channel 0x%02x; mouse data %02x; index %d; keycode %d\n",
498 remote_num, data[2], index, ati_remote_tbl[index].code);
499 if (!dev)
500 return; /* no mouse device */
501 } else
502 dbginfo(&ati_remote->interface->dev,
503 "channel 0x%02x; key data %02x, scancode %02x\n",
504 remote_num, data[2], scancode);
505
506
507 if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { 559 if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
508 input_event(dev, ati_remote_tbl[index].type, 560 input_event(dev, ati_remote_tbl[index].type,
509 ati_remote_tbl[index].code, 561 ati_remote_tbl[index].code,
@@ -542,15 +594,29 @@ static void ati_remote_input_report(struct urb *urb)
542 594
543 if (index < 0) { 595 if (index < 0) {
544 /* Not a mouse event, hand it to rc-core. */ 596 /* Not a mouse event, hand it to rc-core. */
545 597 int count = 1;
546 /* 598
547 * We don't use the rc-core repeat handling yet as 599 if (wheel_keycode != KEY_RESERVED) {
548 * it would cause ghost repeats which would be a 600 /*
549 * regression for this driver. 601 * This is a scrollwheel event, send the
550 */ 602 * scroll up (0x78) / down (0x70) scancode
551 rc_keydown_notimeout(ati_remote->rdev, scancode, 603 * repeatedly as many times as indicated by
552 data[2]); 604 * rest of the scancode.
553 rc_keyup(ati_remote->rdev); 605 */
606 count = (scancode & 0x07) + 1;
607 scancode &= 0x78;
608 }
609
610 while (count--) {
611 /*
612 * We don't use the rc-core repeat handling yet as
613 * it would cause ghost repeats which would be a
614 * regression for this driver.
615 */
616 rc_keydown_notimeout(ati_remote->rdev, scancode,
617 data[2]);
618 rc_keyup(ati_remote->rdev);
619 }
554 return; 620 return;
555 } 621 }
556 622
@@ -766,6 +832,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
766 struct usb_device *udev = interface_to_usbdev(interface); 832 struct usb_device *udev = interface_to_usbdev(interface);
767 struct usb_host_interface *iface_host = interface->cur_altsetting; 833 struct usb_host_interface *iface_host = interface->cur_altsetting;
768 struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; 834 struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
835 struct ati_receiver_type *type = (struct ati_receiver_type *)id->driver_info;
769 struct ati_remote *ati_remote; 836 struct ati_remote *ati_remote;
770 struct input_dev *input_dev; 837 struct input_dev *input_dev;
771 struct rc_dev *rc_dev; 838 struct rc_dev *rc_dev;
@@ -827,10 +894,15 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
827 snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name), 894 snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name),
828 "%s mouse", ati_remote->rc_name); 895 "%s mouse", ati_remote->rc_name);
829 896
830 if (id->driver_info) 897 rc_dev->map_name = RC_MAP_ATI_X10; /* default map */
831 rc_dev->map_name = (const char *)id->driver_info; 898
832 else 899 /* set default keymap according to receiver model */
833 rc_dev->map_name = RC_MAP_ATI_X10; 900 if (type) {
901 if (type->default_keymap)
902 rc_dev->map_name = type->default_keymap;
903 else if (type->get_default_keymap)
904 rc_dev->map_name = type->get_default_keymap(interface);
905 }
834 906
835 ati_remote_rc_init(ati_remote); 907 ati_remote_rc_init(ati_remote);
836 mutex_init(&ati_remote->open_mutex); 908 mutex_init(&ati_remote->open_mutex);
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 4a3a238bcfbc..6aabf7ae3a31 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -556,11 +556,11 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
556 556
557 if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, 557 if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
558 FINTEK_DRIVER_NAME, (void *)fintek)) 558 FINTEK_DRIVER_NAME, (void *)fintek))
559 goto failure; 559 goto failure2;
560 560
561 ret = rc_register_device(rdev); 561 ret = rc_register_device(rdev);
562 if (ret) 562 if (ret)
563 goto failure; 563 goto failure3;
564 564
565 device_init_wakeup(&pdev->dev, true); 565 device_init_wakeup(&pdev->dev, true);
566 fintek->rdev = rdev; 566 fintek->rdev = rdev;
@@ -570,12 +570,11 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
570 570
571 return 0; 571 return 0;
572 572
573failure3:
574 free_irq(fintek->cir_irq, fintek);
575failure2:
576 release_region(fintek->cir_addr, fintek->cir_port_len);
573failure: 577failure:
574 if (fintek->cir_irq)
575 free_irq(fintek->cir_irq, fintek);
576 if (fintek->cir_addr)
577 release_region(fintek->cir_addr, fintek->cir_port_len);
578
579 rc_free_device(rdev); 578 rc_free_device(rdev);
580 kfree(fintek); 579 kfree(fintek);
581 580
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 7f26fdf2e54e..5dd0386604f0 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -255,7 +255,7 @@ static struct usb_device_id imon_usb_id_table[] = {
255static struct usb_driver imon_driver = { 255static struct usb_driver imon_driver = {
256 .name = MOD_NAME, 256 .name = MOD_NAME,
257 .probe = imon_probe, 257 .probe = imon_probe,
258 .disconnect = imon_disconnect, 258 .disconnect = __devexit_p(imon_disconnect),
259 .suspend = imon_suspend, 259 .suspend = imon_suspend,
260 .resume = imon_resume, 260 .resume = imon_resume,
261 .id_table = imon_usb_id_table, 261 .id_table = imon_usb_id_table,
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 95e630998aaf..a82025121345 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -46,9 +46,9 @@ static int ir_raw_event_thread(void *data)
46 while (!kthread_should_stop()) { 46 while (!kthread_should_stop()) {
47 47
48 spin_lock_irq(&raw->lock); 48 spin_lock_irq(&raw->lock);
49 retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); 49 retval = kfifo_len(&raw->kfifo);
50 50
51 if (!retval) { 51 if (retval < sizeof(ev)) {
52 set_current_state(TASK_INTERRUPTIBLE); 52 set_current_state(TASK_INTERRUPTIBLE);
53 53
54 if (kthread_should_stop()) 54 if (kthread_should_stop())
@@ -59,11 +59,9 @@ static int ir_raw_event_thread(void *data)
59 continue; 59 continue;
60 } 60 }
61 61
62 retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
62 spin_unlock_irq(&raw->lock); 63 spin_unlock_irq(&raw->lock);
63 64
64
65 BUG_ON(retval != sizeof(ev));
66
67 mutex_lock(&ir_raw_handler_lock); 65 mutex_lock(&ir_raw_handler_lock);
68 list_for_each_entry(handler, &ir_raw_handler_list, list) 66 list_for_each_entry(handler, &ir_raw_handler_list, list)
69 handler->decode(raw->dev, ev); 67 handler->decode(raw->dev, ev);
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
index d38fbdd0b25a..7e54ec57bcf9 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -56,7 +56,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
56{ 56{
57 struct sanyo_dec *data = &dev->raw->sanyo; 57 struct sanyo_dec *data = &dev->raw->sanyo;
58 u32 scancode; 58 u32 scancode;
59 u8 address, not_address, command, not_command; 59 u8 address, command, not_command;
60 60
61 if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO)) 61 if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO))
62 return 0; 62 return 0;
@@ -154,7 +154,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
154 break; 154 break;
155 155
156 address = bitrev16((data->bits >> 29) & 0x1fff) >> 3; 156 address = bitrev16((data->bits >> 29) & 0x1fff) >> 3;
157 not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; 157 /* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */
158 command = bitrev8((data->bits >> 8) & 0xff); 158 command = bitrev8((data->bits >> 8) & 0xff);
159 not_command = bitrev8((data->bits >> 0) & 0xff); 159 not_command = bitrev8((data->bits >> 0) & 0xff);
160 160
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 0e49c99abf68..36fe5a349b95 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1598,24 +1598,22 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
1598 1598
1599 if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, 1599 if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
1600 ITE_DRIVER_NAME, (void *)itdev)) 1600 ITE_DRIVER_NAME, (void *)itdev))
1601 goto failure; 1601 goto failure2;
1602 1602
1603 ret = rc_register_device(rdev); 1603 ret = rc_register_device(rdev);
1604 if (ret) 1604 if (ret)
1605 goto failure; 1605 goto failure3;
1606 1606
1607 itdev->rdev = rdev; 1607 itdev->rdev = rdev;
1608 ite_pr(KERN_NOTICE, "driver has been successfully loaded\n"); 1608 ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
1609 1609
1610 return 0; 1610 return 0;
1611 1611
1612failure3:
1613 free_irq(itdev->cir_irq, itdev);
1614failure2:
1615 release_region(itdev->cir_addr, itdev->params.io_region_size);
1612failure: 1616failure:
1613 if (itdev->cir_irq)
1614 free_irq(itdev->cir_irq, itdev);
1615
1616 if (itdev->cir_addr)
1617 release_region(itdev->cir_addr, itdev->params.io_region_size);
1618
1619 rc_free_device(rdev); 1617 rc_free_device(rdev);
1620 kfree(itdev); 1618 kfree(itdev);
1621 1619
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 49ce2662f56b..ab84d66c67c1 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
3 rc-anysee.o \ 3 rc-anysee.o \
4 rc-apac-viewcomp.o \ 4 rc-apac-viewcomp.o \
5 rc-asus-pc39.o \ 5 rc-asus-pc39.o \
6 rc-asus-ps3-100.o \
6 rc-ati-tv-wonder-hd-600.o \ 7 rc-ati-tv-wonder-hd-600.o \
7 rc-ati-x10.o \ 8 rc-ati-x10.o \
8 rc-avermedia-a16d.o \ 9 rc-avermedia-a16d.o \
@@ -52,6 +53,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
52 rc-lme2510.o \ 53 rc-lme2510.o \
53 rc-manli.o \ 54 rc-manli.o \
54 rc-medion-x10.o \ 55 rc-medion-x10.o \
56 rc-medion-x10-digitainer.o \
57 rc-medion-x10-or2x.o \
55 rc-msi-digivox-ii.o \ 58 rc-msi-digivox-ii.o \
56 rc-msi-digivox-iii.o \ 59 rc-msi-digivox-iii.o \
57 rc-msi-tvanywhere.o \ 60 rc-msi-tvanywhere.o \
diff --git a/drivers/media/rc/keymaps/rc-asus-ps3-100.c b/drivers/media/rc/keymaps/rc-asus-ps3-100.c
new file mode 100644
index 000000000000..ba76609c5936
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-asus-ps3-100.c
@@ -0,0 +1,91 @@
1/* asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
2 *
3 * Copyright (c) 2012 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * Based on a previous patch from Remi Schwartz <remi.schwartz@gmail.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; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14#include <linux/module.h>
15
16static struct rc_map_table asus_ps3_100[] = {
17 { 0x081c, KEY_HOME }, /* home */
18 { 0x081e, KEY_TV }, /* tv */
19 { 0x0803, KEY_TEXT }, /* teletext */
20 { 0x0829, KEY_POWER }, /* close */
21
22 { 0x080b, KEY_RED }, /* red */
23 { 0x080d, KEY_YELLOW }, /* yellow */
24 { 0x0806, KEY_BLUE }, /* blue */
25 { 0x0807, KEY_GREEN }, /* green */
26
27 /* Keys 0 to 9 */
28 { 0x082a, KEY_0 },
29 { 0x0816, KEY_1 },
30 { 0x0812, KEY_2 },
31 { 0x0814, KEY_3 },
32 { 0x0836, KEY_4 },
33 { 0x0832, KEY_5 },
34 { 0x0834, KEY_6 },
35 { 0x080e, KEY_7 },
36 { 0x080a, KEY_8 },
37 { 0x080c, KEY_9 },
38
39 { 0x0815, KEY_VOLUMEUP },
40 { 0x0826, KEY_VOLUMEDOWN },
41 { 0x0835, KEY_CHANNELUP }, /* channel / program + */
42 { 0x0824, KEY_CHANNELDOWN }, /* channel / program - */
43
44 { 0x0808, KEY_UP },
45 { 0x0804, KEY_DOWN },
46 { 0x0818, KEY_LEFT },
47 { 0x0810, KEY_RIGHT },
48 { 0x0825, KEY_ENTER }, /* enter */
49
50 { 0x0822, KEY_EXIT }, /* back */
51 { 0x082c, KEY_AB }, /* recall */
52
53 { 0x0820, KEY_AUDIO }, /* TV audio */
54 { 0x0837, KEY_SCREEN }, /* snapshot */
55 { 0x082e, KEY_ZOOM }, /* full screen */
56 { 0x0802, KEY_MUTE }, /* mute */
57
58 { 0x0831, KEY_REWIND }, /* backward << */
59 { 0x0811, KEY_RECORD }, /* recording */
60 { 0x0809, KEY_STOP },
61 { 0x0805, KEY_FASTFORWARD }, /* forward >> */
62 { 0x0821, KEY_PREVIOUS }, /* rew */
63 { 0x081a, KEY_PAUSE }, /* pause */
64 { 0x0839, KEY_PLAY }, /* play */
65 { 0x0819, KEY_NEXT }, /* forward */
66};
67
68static struct rc_map_list asus_ps3_100_map = {
69.map = {
70 .scan = asus_ps3_100,
71 .size = ARRAY_SIZE(asus_ps3_100),
72 .rc_type = RC_TYPE_RC5,
73 .name = RC_MAP_ASUS_PS3_100,
74}
75};
76
77static int __init init_rc_map_asus_ps3_100(void)
78{
79return rc_map_register(&asus_ps3_100_map);
80}
81
82static void __exit exit_rc_map_asus_ps3_100(void)
83{
84rc_map_unregister(&asus_ps3_100_map);
85}
86
87module_init(init_rc_map_asus_ps3_100)
88module_exit(exit_rc_map_asus_ps3_100)
89
90MODULE_LICENSE("GPL");
91MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-it913x-v2.c b/drivers/media/rc/keymaps/rc-it913x-v2.c
index 28e376e18b99..bd42a30ec06f 100644
--- a/drivers/media/rc/keymaps/rc-it913x-v2.c
+++ b/drivers/media/rc/keymaps/rc-it913x-v2.c
@@ -40,7 +40,7 @@ static struct rc_map_table it913x_v2_rc[] = {
40 /* Type 2 */ 40 /* Type 2 */
41 /* keys stereo, snapshot unassigned */ 41 /* keys stereo, snapshot unassigned */
42 { 0x866b00, KEY_0 }, 42 { 0x866b00, KEY_0 },
43 { 0x866b1b, KEY_1 }, 43 { 0x866b01, KEY_1 },
44 { 0x866b02, KEY_2 }, 44 { 0x866b02, KEY_2 },
45 { 0x866b03, KEY_3 }, 45 { 0x866b03, KEY_3 },
46 { 0x866b04, KEY_4 }, 46 { 0x866b04, KEY_4 },
diff --git a/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c b/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c
new file mode 100644
index 000000000000..966f9b3c71da
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c
@@ -0,0 +1,123 @@
1/*
2 * Medion X10 RF remote keytable (Digitainer variant)
3 *
4 * Copyright (C) 2012 Anssi Hannula <anssi.hannula@iki.fi>
5 *
6 * This keymap is for a variant that has a distinctive scrollwheel instead of
7 * up/down buttons (tested with P/N 40009936 / 20018268), reportedly
8 * originally shipped with Medion Digitainer but now sold separately simply as
9 * an "X10" remote.
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 as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include <linux/module.h>
27#include <media/rc-map.h>
28
29static struct rc_map_table medion_x10_digitainer[] = {
30 { 0x02, KEY_POWER },
31
32 { 0x2c, KEY_TV },
33 { 0x2d, KEY_VIDEO },
34 { 0x04, KEY_DVD }, /* CD/DVD */
35 { 0x16, KEY_TEXT }, /* "teletext" icon, i.e. a screen with lines */
36 { 0x06, KEY_AUDIO },
37 { 0x2e, KEY_RADIO },
38 { 0x31, KEY_EPG }, /* a screen with an open book */
39 { 0x05, KEY_IMAGES }, /* Photo */
40 { 0x2f, KEY_INFO },
41
42 { 0x78, KEY_UP }, /* scrollwheel up 1 notch */
43 /* 0x79..0x7f: 2-8 notches, driver repeats 0x78 entry */
44
45 { 0x70, KEY_DOWN }, /* scrollwheel down 1 notch */
46 /* 0x71..0x77: 2-8 notches, driver repeats 0x70 entry */
47
48 { 0x19, KEY_MENU },
49 { 0x1d, KEY_LEFT },
50 { 0x1e, KEY_OK }, /* scrollwheel press */
51 { 0x1f, KEY_RIGHT },
52 { 0x20, KEY_BACK },
53
54 { 0x09, KEY_VOLUMEUP },
55 { 0x08, KEY_VOLUMEDOWN },
56 { 0x00, KEY_MUTE },
57
58 { 0x1b, KEY_SELECT }, /* also has "U" rotated 90 degrees CCW */
59
60 { 0x0b, KEY_CHANNELUP },
61 { 0x0c, KEY_CHANNELDOWN },
62 { 0x1c, KEY_LAST },
63
64 { 0x32, KEY_RED }, /* also Audio */
65 { 0x33, KEY_GREEN }, /* also Subtitle */
66 { 0x34, KEY_YELLOW }, /* also Angle */
67 { 0x35, KEY_BLUE }, /* also Title */
68
69 { 0x28, KEY_STOP },
70 { 0x29, KEY_PAUSE },
71 { 0x25, KEY_PLAY },
72 { 0x21, KEY_PREVIOUS },
73 { 0x18, KEY_CAMERA },
74 { 0x23, KEY_NEXT },
75 { 0x24, KEY_REWIND },
76 { 0x27, KEY_RECORD },
77 { 0x26, KEY_FORWARD },
78
79 { 0x0d, KEY_1 },
80 { 0x0e, KEY_2 },
81 { 0x0f, KEY_3 },
82 { 0x10, KEY_4 },
83 { 0x11, KEY_5 },
84 { 0x12, KEY_6 },
85 { 0x13, KEY_7 },
86 { 0x14, KEY_8 },
87 { 0x15, KEY_9 },
88 { 0x17, KEY_0 },
89
90 /* these do not actually exist on this remote, but these scancodes
91 * exist on all other Medion X10 remotes and adding them here allows
92 * such remotes to be adequately usable with this keymap in case
93 * this keymap is wrongly used with them (which is quite possible as
94 * there are lots of different Medion X10 remotes): */
95 { 0x1a, KEY_UP },
96 { 0x22, KEY_DOWN },
97};
98
99static struct rc_map_list medion_x10_digitainer_map = {
100 .map = {
101 .scan = medion_x10_digitainer,
102 .size = ARRAY_SIZE(medion_x10_digitainer),
103 .rc_type = RC_TYPE_OTHER,
104 .name = RC_MAP_MEDION_X10_DIGITAINER,
105 }
106};
107
108static int __init init_rc_map_medion_x10_digitainer(void)
109{
110 return rc_map_register(&medion_x10_digitainer_map);
111}
112
113static void __exit exit_rc_map_medion_x10_digitainer(void)
114{
115 rc_map_unregister(&medion_x10_digitainer_map);
116}
117
118module_init(init_rc_map_medion_x10_digitainer)
119module_exit(exit_rc_map_medion_x10_digitainer)
120
121MODULE_DESCRIPTION("Medion X10 RF remote keytable (Digitainer variant)");
122MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
123MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/keymaps/rc-medion-x10-or2x.c b/drivers/media/rc/keymaps/rc-medion-x10-or2x.c
new file mode 100644
index 000000000000..b077300ecb5c
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-medion-x10-or2x.c
@@ -0,0 +1,108 @@
1/*
2 * Medion X10 OR22/OR24 RF remote keytable
3 *
4 * Copyright (C) 2012 Anssi Hannula <anssi.hannula@iki.fi>
5 *
6 * This keymap is for several Medion X10 remotes that have the Windows MCE
7 * button. This has been tested with a "RF VISTA Remote Control", OR24V,
8 * P/N 20035335, but should work with other variants that have the same
9 * buttons, such as OR22V and OR24E.
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 as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include <linux/module.h>
27#include <media/rc-map.h>
28
29static struct rc_map_table medion_x10_or2x[] = {
30 { 0x02, KEY_POWER },
31 { 0x16, KEY_TEXT }, /* "T" in a box, for teletext */
32
33 { 0x09, KEY_VOLUMEUP },
34 { 0x08, KEY_VOLUMEDOWN },
35 { 0x00, KEY_MUTE },
36 { 0x0b, KEY_CHANNELUP },
37 { 0x0c, KEY_CHANNELDOWN },
38
39 { 0x32, KEY_RED },
40 { 0x33, KEY_GREEN },
41 { 0x34, KEY_YELLOW },
42 { 0x35, KEY_BLUE },
43
44 { 0x18, KEY_PVR }, /* record symbol inside a tv symbol */
45 { 0x04, KEY_DVD }, /* disc symbol */
46 { 0x31, KEY_EPG }, /* a tv schedule symbol */
47 { 0x1c, KEY_TV }, /* play symbol inside a tv symbol */
48 { 0x20, KEY_BACK },
49 { 0x2f, KEY_INFO },
50
51 { 0x1a, KEY_UP },
52 { 0x22, KEY_DOWN },
53 { 0x1d, KEY_LEFT },
54 { 0x1f, KEY_RIGHT },
55 { 0x1e, KEY_OK },
56
57 { 0x1b, KEY_MEDIA }, /* Windows MCE button */
58
59 { 0x21, KEY_PREVIOUS },
60 { 0x23, KEY_NEXT },
61 { 0x24, KEY_REWIND },
62 { 0x26, KEY_FORWARD },
63 { 0x25, KEY_PLAY },
64 { 0x28, KEY_STOP },
65 { 0x29, KEY_PAUSE },
66 { 0x27, KEY_RECORD },
67
68 { 0x0d, KEY_1 },
69 { 0x0e, KEY_2 },
70 { 0x0f, KEY_3 },
71 { 0x10, KEY_4 },
72 { 0x11, KEY_5 },
73 { 0x12, KEY_6 },
74 { 0x13, KEY_7 },
75 { 0x14, KEY_8 },
76 { 0x15, KEY_9 },
77 { 0x17, KEY_0 },
78 { 0x30, KEY_CLEAR },
79 { 0x36, KEY_ENTER },
80 { 0x37, KEY_NUMERIC_STAR },
81 { 0x38, KEY_NUMERIC_POUND },
82};
83
84static struct rc_map_list medion_x10_or2x_map = {
85 .map = {
86 .scan = medion_x10_or2x,
87 .size = ARRAY_SIZE(medion_x10_or2x),
88 .rc_type = RC_TYPE_OTHER,
89 .name = RC_MAP_MEDION_X10_OR2X,
90 }
91};
92
93static int __init init_rc_map_medion_x10_or2x(void)
94{
95 return rc_map_register(&medion_x10_or2x_map);
96}
97
98static void __exit exit_rc_map_medion_x10_or2x(void)
99{
100 rc_map_unregister(&medion_x10_or2x_map);
101}
102
103module_init(init_rc_map_medion_x10_or2x)
104module_exit(exit_rc_map_medion_x10_or2x)
105
106MODULE_DESCRIPTION("Medion X10 OR22/OR24 RF remote keytable");
107MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
108MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index e150a2e29a4b..84e06d3aa696 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -520,7 +520,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
520{ 520{
521 char codes[USB_BUFLEN * 3 + 1]; 521 char codes[USB_BUFLEN * 3 + 1];
522 char inout[9]; 522 char inout[9];
523 u8 cmd, subcmd, data1, data2, data3, data4, data5; 523 u8 cmd, subcmd, data1, data2, data3, data4;
524 struct device *dev = ir->dev; 524 struct device *dev = ir->dev;
525 int i, start, skip = 0; 525 int i, start, skip = 0;
526 u32 carrier, period; 526 u32 carrier, period;
@@ -553,7 +553,6 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
553 data2 = buf[start + 3] & 0xff; 553 data2 = buf[start + 3] & 0xff;
554 data3 = buf[start + 4] & 0xff; 554 data3 = buf[start + 4] & 0xff;
555 data4 = buf[start + 5] & 0xff; 555 data4 = buf[start + 5] & 0xff;
556 data5 = buf[start + 6] & 0xff;
557 556
558 switch (cmd) { 557 switch (cmd) {
559 case MCE_CMD_NULL: 558 case MCE_CMD_NULL:
@@ -1443,7 +1442,7 @@ static int mceusb_dev_resume(struct usb_interface *intf)
1443static struct usb_driver mceusb_dev_driver = { 1442static struct usb_driver mceusb_dev_driver = {
1444 .name = DRIVER_NAME, 1443 .name = DRIVER_NAME,
1445 .probe = mceusb_dev_probe, 1444 .probe = mceusb_dev_probe,
1446 .disconnect = mceusb_dev_disconnect, 1445 .disconnect = __devexit_p(mceusb_dev_disconnect),
1447 .suspend = mceusb_dev_suspend, 1446 .suspend = mceusb_dev_suspend,
1448 .resume = mceusb_dev_resume, 1447 .resume = mceusb_dev_resume,
1449 .reset_resume = mceusb_dev_resume, 1448 .reset_resume = mceusb_dev_resume,
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 8b2c071ac0ab..dc8a7dddccd4 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1075,19 +1075,19 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
1075 1075
1076 if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, 1076 if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED,
1077 NVT_DRIVER_NAME, (void *)nvt)) 1077 NVT_DRIVER_NAME, (void *)nvt))
1078 goto failure; 1078 goto failure2;
1079 1079
1080 if (!request_region(nvt->cir_wake_addr, 1080 if (!request_region(nvt->cir_wake_addr,
1081 CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) 1081 CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
1082 goto failure; 1082 goto failure3;
1083 1083
1084 if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, 1084 if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED,
1085 NVT_DRIVER_NAME, (void *)nvt)) 1085 NVT_DRIVER_NAME, (void *)nvt))
1086 goto failure; 1086 goto failure4;
1087 1087
1088 ret = rc_register_device(rdev); 1088 ret = rc_register_device(rdev);
1089 if (ret) 1089 if (ret)
1090 goto failure; 1090 goto failure5;
1091 1091
1092 device_init_wakeup(&pdev->dev, true); 1092 device_init_wakeup(&pdev->dev, true);
1093 nvt->rdev = rdev; 1093 nvt->rdev = rdev;
@@ -1099,17 +1099,15 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
1099 1099
1100 return 0; 1100 return 0;
1101 1101
1102failure5:
1103 free_irq(nvt->cir_wake_irq, nvt);
1104failure4:
1105 release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
1106failure3:
1107 free_irq(nvt->cir_irq, nvt);
1108failure2:
1109 release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
1102failure: 1110failure:
1103 if (nvt->cir_irq)
1104 free_irq(nvt->cir_irq, nvt);
1105 if (nvt->cir_addr)
1106 release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
1107
1108 if (nvt->cir_wake_irq)
1109 free_irq(nvt->cir_wake_irq, nvt);
1110 if (nvt->cir_wake_addr)
1111 release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
1112
1113 rc_free_device(rdev); 1111 rc_free_device(rdev);
1114 kfree(nvt); 1112 kfree(nvt);
1115 1113
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index efc6a514348a..fae1615e0ff2 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -221,7 +221,6 @@ static int __init loop_init(void)
221 rc->s_idle = loop_set_idle; 221 rc->s_idle = loop_set_idle;
222 rc->s_learning_mode = loop_set_learning_mode; 222 rc->s_learning_mode = loop_set_learning_mode;
223 rc->s_carrier_report = loop_set_carrier_report; 223 rc->s_carrier_report = loop_set_carrier_report;
224 rc->priv = &loopdev;
225 224
226 loopdev.txmask = RXMASK_REGULAR; 225 loopdev.txmask = RXMASK_REGULAR;
227 loopdev.txcarrier = 36000; 226 loopdev.txcarrier = 36000;
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index ad95c67a4dba..2878b0ed9741 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -1277,7 +1277,7 @@ static int redrat3_dev_resume(struct usb_interface *intf)
1277static struct usb_driver redrat3_dev_driver = { 1277static struct usb_driver redrat3_dev_driver = {
1278 .name = DRIVER_NAME, 1278 .name = DRIVER_NAME,
1279 .probe = redrat3_dev_probe, 1279 .probe = redrat3_dev_probe,
1280 .disconnect = redrat3_dev_disconnect, 1280 .disconnect = __devexit_p(redrat3_dev_disconnect),
1281 .suspend = redrat3_dev_suspend, 1281 .suspend = redrat3_dev_suspend,
1282 .resume = redrat3_dev_resume, 1282 .resume = redrat3_dev_resume,
1283 .reset_resume = redrat3_dev_resume, 1283 .reset_resume = redrat3_dev_resume,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ce1e7ba940f6..99937c94d7df 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -472,6 +472,9 @@ comment "Camera sensor devices"
472config VIDEO_APTINA_PLL 472config VIDEO_APTINA_PLL
473 tristate 473 tristate
474 474
475config VIDEO_SMIAPP_PLL
476 tristate
477
475config VIDEO_OV7670 478config VIDEO_OV7670
476 tristate "OmniVision OV7670 sensor support" 479 tristate "OmniVision OV7670 sensor support"
477 depends on I2C && VIDEO_V4L2 480 depends on I2C && VIDEO_V4L2
@@ -556,6 +559,8 @@ config VIDEO_S5K6AA
556 This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M 559 This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
557 camera sensor with an embedded SoC image signal processor. 560 camera sensor with an embedded SoC image signal processor.
558 561
562source "drivers/media/video/smiapp/Kconfig"
563
559comment "Flash devices" 564comment "Flash devices"
560 565
561config VIDEO_ADP1653 566config VIDEO_ADP1653
@@ -644,6 +649,8 @@ menuconfig V4L_USB_DRIVERS
644 649
645if V4L_USB_DRIVERS 650if V4L_USB_DRIVERS
646 651
652source "drivers/media/video/au0828/Kconfig"
653
647source "drivers/media/video/uvc/Kconfig" 654source "drivers/media/video/uvc/Kconfig"
648 655
649source "drivers/media/video/gspca/Kconfig" 656source "drivers/media/video/gspca/Kconfig"
@@ -662,8 +669,6 @@ source "drivers/media/video/tm6000/Kconfig"
662 669
663source "drivers/media/video/usbvision/Kconfig" 670source "drivers/media/video/usbvision/Kconfig"
664 671
665source "drivers/media/video/et61x251/Kconfig"
666
667source "drivers/media/video/sn9c102/Kconfig" 672source "drivers/media/video/sn9c102/Kconfig"
668 673
669source "drivers/media/video/pwc/Kconfig" 674source "drivers/media/video/pwc/Kconfig"
@@ -721,8 +726,6 @@ menuconfig V4L_PCI_DRIVERS
721 726
722if V4L_PCI_DRIVERS 727if V4L_PCI_DRIVERS
723 728
724source "drivers/media/video/au0828/Kconfig"
725
726source "drivers/media/video/bt8xx/Kconfig" 729source "drivers/media/video/bt8xx/Kconfig"
727 730
728source "drivers/media/video/cx18/Kconfig" 731source "drivers/media/video/cx18/Kconfig"
@@ -794,6 +797,19 @@ source "drivers/media/video/saa7164/Kconfig"
794 797
795source "drivers/media/video/zoran/Kconfig" 798source "drivers/media/video/zoran/Kconfig"
796 799
800config STA2X11_VIP
801 tristate "STA2X11 VIP Video For Linux"
802 depends on STA2X11
803 select VIDEO_ADV7180 if VIDEO_HELPER_CHIPS_AUTO
804 select VIDEOBUF_DMA_CONTIG
805 depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS
806 help
807 Say Y for support for STA2X11 VIP (Video Input Port) capture
808 device.
809
810 To compile this driver as a module, choose M here: the
811 module will be called sta2x11_vip.
812
797endif # V4L_PCI_DRIVERS 813endif # V4L_PCI_DRIVERS
798 814
799# 815#
@@ -1127,19 +1143,6 @@ config VIDEO_MX2
1127 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor 1143 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
1128 Interface 1144 Interface
1129 1145
1130config VIDEO_SAMSUNG_S5P_FIMC
1131 tristate "Samsung S5P and EXYNOS4 camera interface driver (EXPERIMENTAL)"
1132 depends on VIDEO_V4L2 && I2C && PLAT_S5P && PM_RUNTIME && \
1133 VIDEO_V4L2_SUBDEV_API && EXPERIMENTAL
1134 select VIDEOBUF2_DMA_CONTIG
1135 select V4L2_MEM2MEM_DEV
1136 ---help---
1137 This is a v4l2 driver for Samsung S5P and EXYNOS4 camera
1138 host interface and video postprocessor.
1139
1140 To compile this driver as a module, choose M here: the
1141 module will be called s5p-fimc.
1142
1143config VIDEO_ATMEL_ISI 1146config VIDEO_ATMEL_ISI
1144 tristate "ATMEL Image Sensor Interface (ISI) support" 1147 tristate "ATMEL Image Sensor Interface (ISI) support"
1145 depends on VIDEO_DEV && SOC_CAMERA && ARCH_AT91 1148 depends on VIDEO_DEV && SOC_CAMERA && ARCH_AT91
@@ -1148,16 +1151,7 @@ config VIDEO_ATMEL_ISI
1148 This module makes the ATMEL Image Sensor Interface available 1151 This module makes the ATMEL Image Sensor Interface available
1149 as a v4l2 device. 1152 as a v4l2 device.
1150 1153
1151config VIDEO_S5P_MIPI_CSIS 1154source "drivers/media/video/s5p-fimc/Kconfig"
1152 tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver"
1153 depends on VIDEO_V4L2 && PM_RUNTIME && PLAT_S5P
1154 depends on VIDEO_V4L2_SUBDEV_API && REGULATOR
1155 ---help---
1156 This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver.
1157
1158 To compile this driver as a module, choose M here: the
1159 module will be called s5p-csis.
1160
1161source "drivers/media/video/s5p-tv/Kconfig" 1155source "drivers/media/video/s5p-tv/Kconfig"
1162 1156
1163endif # V4L_PLATFORM_DRIVERS 1157endif # V4L_PLATFORM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index a6282a3a6a82..d209de0e0ca8 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -79,9 +79,12 @@ obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
79obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 79obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
80obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ 80obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
81obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o 81obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
82obj-$(CONFIG_VIDEO_SMIAPP) += smiapp/
82obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o 83obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
83obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o 84obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
84 85
86obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
87
85obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o 88obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
86obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o 89obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
87obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o 90obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
@@ -120,6 +123,7 @@ obj-$(CONFIG_VIDEO_TM6000) += tm6000/
120obj-$(CONFIG_VIDEO_MXB) += mxb.o 123obj-$(CONFIG_VIDEO_MXB) += mxb.o
121obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o 124obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
122obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o 125obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
126obj-$(CONFIG_STA2X11_VIP) += sta2x11_vip.o
123obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o 127obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
124 128
125obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o 129obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
@@ -152,7 +156,6 @@ obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
152obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o 156obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
153 157
154obj-$(CONFIG_USB_SN9C102) += sn9c102/ 158obj-$(CONFIG_USB_SN9C102) += sn9c102/
155obj-$(CONFIG_USB_ET61X251) += et61x251/
156obj-$(CONFIG_USB_PWC) += pwc/ 159obj-$(CONFIG_USB_PWC) += pwc/
157obj-$(CONFIG_USB_GSPCA) += gspca/ 160obj-$(CONFIG_USB_GSPCA) += gspca/
158 161
diff --git a/drivers/media/video/adp1653.c b/drivers/media/video/adp1653.c
index 5b045b4a66fe..57e87090388d 100644
--- a/drivers/media/video/adp1653.c
+++ b/drivers/media/video/adp1653.c
@@ -34,7 +34,6 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/i2c.h> 35#include <linux/i2c.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/version.h>
38#include <media/adp1653.h> 37#include <media/adp1653.h>
39#include <media/v4l2-device.h> 38#include <media/v4l2-device.h>
40 39
@@ -282,19 +281,19 @@ adp1653_init_device(struct adp1653_flash *flash)
282 return -EIO; 281 return -EIO;
283 } 282 }
284 283
285 mutex_lock(&flash->ctrls.lock); 284 mutex_lock(flash->ctrls.lock);
286 /* Reset faults before reading new ones. */ 285 /* Reset faults before reading new ones. */
287 flash->fault = 0; 286 flash->fault = 0;
288 rval = adp1653_get_fault(flash); 287 rval = adp1653_get_fault(flash);
289 mutex_unlock(&flash->ctrls.lock); 288 mutex_unlock(flash->ctrls.lock);
290 if (rval > 0) { 289 if (rval > 0) {
291 dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval); 290 dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
292 return -EIO; 291 return -EIO;
293 } 292 }
294 293
295 mutex_lock(&flash->ctrls.lock); 294 mutex_lock(flash->ctrls.lock);
296 rval = adp1653_update_hw(flash); 295 rval = adp1653_update_hw(flash);
297 mutex_unlock(&flash->ctrls.lock); 296 mutex_unlock(flash->ctrls.lock);
298 if (rval) { 297 if (rval) {
299 dev_err(&client->dev, 298 dev_err(&client->dev,
300 "adp1653_update_hw failed at %s\n", __func__); 299 "adp1653_update_hw failed at %s\n", __func__);
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index b8b6c4b0cad4..174bffacf117 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -48,6 +48,7 @@
48#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0 48#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
49#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0 49#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0
50#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0 50#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0
51#define ADV7180_INPUT_CONTROL_INSEL_MASK 0x0f
51 52
52#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04 53#define ADV7180_EXTENDED_OUTPUT_CONTROL_REG 0x04
53#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5 54#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
@@ -55,9 +56,29 @@
55#define ADV7180_AUTODETECT_ENABLE_REG 0x07 56#define ADV7180_AUTODETECT_ENABLE_REG 0x07
56#define ADV7180_AUTODETECT_DEFAULT 0x7f 57#define ADV7180_AUTODETECT_DEFAULT 0x7f
57 58
59#define ADV7180_CON_REG 0x08 /*Unsigned */
60#define CON_REG_MIN 0
61#define CON_REG_DEF 128
62#define CON_REG_MAX 255
63
64#define ADV7180_BRI_REG 0x0a /*Signed */
65#define BRI_REG_MIN -128
66#define BRI_REG_DEF 0
67#define BRI_REG_MAX 127
68
69#define ADV7180_HUE_REG 0x0b /*Signed, inverted */
70#define HUE_REG_MIN -127
71#define HUE_REG_DEF 0
72#define HUE_REG_MAX 128
73
58#define ADV7180_ADI_CTRL_REG 0x0e 74#define ADV7180_ADI_CTRL_REG 0x0e
59#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20 75#define ADV7180_ADI_CTRL_IRQ_SPACE 0x20
60 76
77#define ADV7180_PWR_MAN_REG 0x0f
78#define ADV7180_PWR_MAN_ON 0x04
79#define ADV7180_PWR_MAN_OFF 0x24
80#define ADV7180_PWR_MAN_RES 0x80
81
61#define ADV7180_STATUS1_REG 0x10 82#define ADV7180_STATUS1_REG 0x10
62#define ADV7180_STATUS1_IN_LOCK 0x01 83#define ADV7180_STATUS1_IN_LOCK 0x01
63#define ADV7180_STATUS1_AUTOD_MASK 0x70 84#define ADV7180_STATUS1_AUTOD_MASK 0x70
@@ -78,6 +99,12 @@
78#define ADV7180_ICONF1_PSYNC_ONLY 0x10 99#define ADV7180_ICONF1_PSYNC_ONLY 0x10
79#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0 100#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
80 101
102#define ADV7180_SD_SAT_CB_REG 0xe3 /*Unsigned */
103#define ADV7180_SD_SAT_CR_REG 0xe4 /*Unsigned */
104#define SAT_REG_MIN 0
105#define SAT_REG_DEF 128
106#define SAT_REG_MAX 255
107
81#define ADV7180_IRQ1_LOCK 0x01 108#define ADV7180_IRQ1_LOCK 0x01
82#define ADV7180_IRQ1_UNLOCK 0x02 109#define ADV7180_IRQ1_UNLOCK 0x02
83#define ADV7180_ISR1_ADI 0x42 110#define ADV7180_ISR1_ADI 0x42
@@ -90,6 +117,9 @@
90#define ADV7180_IMR3_ADI 0x4C 117#define ADV7180_IMR3_ADI 0x4C
91#define ADV7180_IMR4_ADI 0x50 118#define ADV7180_IMR4_ADI 0x50
92 119
120#define ADV7180_NTSC_V_BIT_END_REG 0xE6
121#define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F
122
93struct adv7180_state { 123struct adv7180_state {
94 struct v4l2_subdev sd; 124 struct v4l2_subdev sd;
95 struct work_struct work; 125 struct work_struct work;
@@ -97,6 +127,11 @@ struct adv7180_state {
97 int irq; 127 int irq;
98 v4l2_std_id curr_norm; 128 v4l2_std_id curr_norm;
99 bool autodetect; 129 bool autodetect;
130 s8 brightness;
131 s16 hue;
132 u8 contrast;
133 u8 saturation;
134 u8 input;
100}; 135};
101 136
102static v4l2_std_id adv7180_std_to_v4l2(u8 status1) 137static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
@@ -155,7 +190,7 @@ static u32 adv7180_status_to_v4l2(u8 status1)
155} 190}
156 191
157static int __adv7180_status(struct i2c_client *client, u32 *status, 192static int __adv7180_status(struct i2c_client *client, u32 *status,
158 v4l2_std_id *std) 193 v4l2_std_id *std)
159{ 194{
160 int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG); 195 int status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
161 196
@@ -192,6 +227,36 @@ static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
192 return err; 227 return err;
193} 228}
194 229
230static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
231 u32 output, u32 config)
232{
233 struct adv7180_state *state = to_state(sd);
234 int ret = mutex_lock_interruptible(&state->mutex);
235 struct i2c_client *client = v4l2_get_subdevdata(sd);
236
237 if (ret)
238 return ret;
239
240 /*We cannot discriminate between LQFP and 40-pin LFCSP, so accept
241 * all inputs and let the card driver take care of validation
242 */
243 if ((input & ADV7180_INPUT_CONTROL_INSEL_MASK) != input)
244 goto out;
245
246 ret = i2c_smbus_read_byte_data(client, ADV7180_INPUT_CONTROL_REG);
247
248 if (ret < 0)
249 goto out;
250
251 ret &= ~ADV7180_INPUT_CONTROL_INSEL_MASK;
252 ret = i2c_smbus_write_byte_data(client,
253 ADV7180_INPUT_CONTROL_REG, ret | input);
254 state->input = input;
255out:
256 mutex_unlock(&state->mutex);
257 return ret;
258}
259
195static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status) 260static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
196{ 261{
197 struct adv7180_state *state = to_state(sd); 262 struct adv7180_state *state = to_state(sd);
@@ -205,7 +270,7 @@ static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
205} 270}
206 271
207static int adv7180_g_chip_ident(struct v4l2_subdev *sd, 272static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
208 struct v4l2_dbg_chip_ident *chip) 273 struct v4l2_dbg_chip_ident *chip)
209{ 274{
210 struct i2c_client *client = v4l2_get_subdevdata(sd); 275 struct i2c_client *client = v4l2_get_subdevdata(sd);
211 276
@@ -222,9 +287,10 @@ static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
222 287
223 /* all standards -> autodetect */ 288 /* all standards -> autodetect */
224 if (std == V4L2_STD_ALL) { 289 if (std == V4L2_STD_ALL) {
225 ret = i2c_smbus_write_byte_data(client, 290 ret =
226 ADV7180_INPUT_CONTROL_REG, 291 i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
227 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); 292 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
293 | state->input);
228 if (ret < 0) 294 if (ret < 0)
229 goto out; 295 goto out;
230 296
@@ -236,7 +302,8 @@ static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
236 goto out; 302 goto out;
237 303
238 ret = i2c_smbus_write_byte_data(client, 304 ret = i2c_smbus_write_byte_data(client,
239 ADV7180_INPUT_CONTROL_REG, ret); 305 ADV7180_INPUT_CONTROL_REG,
306 ret | state->input);
240 if (ret < 0) 307 if (ret < 0)
241 goto out; 308 goto out;
242 309
@@ -249,14 +316,138 @@ out:
249 return ret; 316 return ret;
250} 317}
251 318
319static int adv7180_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
320{
321 switch (qc->id) {
322 case V4L2_CID_BRIGHTNESS:
323 return v4l2_ctrl_query_fill(qc, BRI_REG_MIN, BRI_REG_MAX,
324 1, BRI_REG_DEF);
325 case V4L2_CID_HUE:
326 return v4l2_ctrl_query_fill(qc, HUE_REG_MIN, HUE_REG_MAX,
327 1, HUE_REG_DEF);
328 case V4L2_CID_CONTRAST:
329 return v4l2_ctrl_query_fill(qc, CON_REG_MIN, CON_REG_MAX,
330 1, CON_REG_DEF);
331 case V4L2_CID_SATURATION:
332 return v4l2_ctrl_query_fill(qc, SAT_REG_MIN, SAT_REG_MAX,
333 1, SAT_REG_DEF);
334 default:
335 break;
336 }
337
338 return -EINVAL;
339}
340
341static int adv7180_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
342{
343 struct adv7180_state *state = to_state(sd);
344 int ret = mutex_lock_interruptible(&state->mutex);
345 if (ret)
346 return ret;
347
348 switch (ctrl->id) {
349 case V4L2_CID_BRIGHTNESS:
350 ctrl->value = state->brightness;
351 break;
352 case V4L2_CID_HUE:
353 ctrl->value = state->hue;
354 break;
355 case V4L2_CID_CONTRAST:
356 ctrl->value = state->contrast;
357 break;
358 case V4L2_CID_SATURATION:
359 ctrl->value = state->saturation;
360 break;
361 default:
362 ret = -EINVAL;
363 }
364
365 mutex_unlock(&state->mutex);
366 return ret;
367}
368
369static int adv7180_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
370{
371 struct adv7180_state *state = to_state(sd);
372 struct i2c_client *client = v4l2_get_subdevdata(sd);
373 int ret = mutex_lock_interruptible(&state->mutex);
374 if (ret)
375 return ret;
376
377 switch (ctrl->id) {
378 case V4L2_CID_BRIGHTNESS:
379 if ((ctrl->value > BRI_REG_MAX)
380 || (ctrl->value < BRI_REG_MIN)) {
381 ret = -ERANGE;
382 break;
383 }
384 state->brightness = ctrl->value;
385 ret = i2c_smbus_write_byte_data(client,
386 ADV7180_BRI_REG,
387 state->brightness);
388 break;
389 case V4L2_CID_HUE:
390 if ((ctrl->value > HUE_REG_MAX)
391 || (ctrl->value < HUE_REG_MIN)) {
392 ret = -ERANGE;
393 break;
394 }
395 state->hue = ctrl->value;
396 /*Hue is inverted according to HSL chart */
397 ret = i2c_smbus_write_byte_data(client,
398 ADV7180_HUE_REG, -state->hue);
399 break;
400 case V4L2_CID_CONTRAST:
401 if ((ctrl->value > CON_REG_MAX)
402 || (ctrl->value < CON_REG_MIN)) {
403 ret = -ERANGE;
404 break;
405 }
406 state->contrast = ctrl->value;
407 ret = i2c_smbus_write_byte_data(client,
408 ADV7180_CON_REG,
409 state->contrast);
410 break;
411 case V4L2_CID_SATURATION:
412 if ((ctrl->value > SAT_REG_MAX)
413 || (ctrl->value < SAT_REG_MIN)) {
414 ret = -ERANGE;
415 break;
416 }
417 /*
418 *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE
419 *Let's not confuse the user, everybody understands saturation
420 */
421 state->saturation = ctrl->value;
422 ret = i2c_smbus_write_byte_data(client,
423 ADV7180_SD_SAT_CB_REG,
424 state->saturation);
425 if (ret < 0)
426 break;
427 ret = i2c_smbus_write_byte_data(client,
428 ADV7180_SD_SAT_CR_REG,
429 state->saturation);
430 break;
431 default:
432 ret = -EINVAL;
433 }
434
435 mutex_unlock(&state->mutex);
436 return ret;
437}
438
252static const struct v4l2_subdev_video_ops adv7180_video_ops = { 439static const struct v4l2_subdev_video_ops adv7180_video_ops = {
253 .querystd = adv7180_querystd, 440 .querystd = adv7180_querystd,
254 .g_input_status = adv7180_g_input_status, 441 .g_input_status = adv7180_g_input_status,
442 .s_routing = adv7180_s_routing,
255}; 443};
256 444
257static const struct v4l2_subdev_core_ops adv7180_core_ops = { 445static const struct v4l2_subdev_core_ops adv7180_core_ops = {
258 .g_chip_ident = adv7180_g_chip_ident, 446 .g_chip_ident = adv7180_g_chip_ident,
259 .s_std = adv7180_s_std, 447 .s_std = adv7180_s_std,
448 .queryctrl = adv7180_queryctrl,
449 .g_ctrl = adv7180_g_ctrl,
450 .s_ctrl = adv7180_s_ctrl,
260}; 451};
261 452
262static const struct v4l2_subdev_ops adv7180_ops = { 453static const struct v4l2_subdev_ops adv7180_ops = {
@@ -267,13 +458,13 @@ static const struct v4l2_subdev_ops adv7180_ops = {
267static void adv7180_work(struct work_struct *work) 458static void adv7180_work(struct work_struct *work)
268{ 459{
269 struct adv7180_state *state = container_of(work, struct adv7180_state, 460 struct adv7180_state *state = container_of(work, struct adv7180_state,
270 work); 461 work);
271 struct i2c_client *client = v4l2_get_subdevdata(&state->sd); 462 struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
272 u8 isr3; 463 u8 isr3;
273 464
274 mutex_lock(&state->mutex); 465 mutex_lock(&state->mutex);
275 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 466 i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
276 ADV7180_ADI_CTRL_IRQ_SPACE); 467 ADV7180_ADI_CTRL_IRQ_SPACE);
277 isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI); 468 isr3 = i2c_smbus_read_byte_data(client, ADV7180_ISR3_ADI);
278 /* clear */ 469 /* clear */
279 i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3); 470 i2c_smbus_write_byte_data(client, ADV7180_ICR3_ADI, isr3);
@@ -297,56 +488,51 @@ static irqreturn_t adv7180_irq(int irq, void *devid)
297 return IRQ_HANDLED; 488 return IRQ_HANDLED;
298} 489}
299 490
300/* 491static int init_device(struct i2c_client *client, struct adv7180_state *state)
301 * Generic i2c probe
302 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
303 */
304
305static __devinit int adv7180_probe(struct i2c_client *client,
306 const struct i2c_device_id *id)
307{ 492{
308 struct adv7180_state *state;
309 struct v4l2_subdev *sd;
310 int ret; 493 int ret;
311 494
312 /* Check if the adapter supports the needed features */
313 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
314 return -EIO;
315
316 v4l_info(client, "chip found @ 0x%02x (%s)\n",
317 client->addr << 1, client->adapter->name);
318
319 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
320 if (state == NULL) {
321 ret = -ENOMEM;
322 goto err;
323 }
324
325 state->irq = client->irq;
326 INIT_WORK(&state->work, adv7180_work);
327 mutex_init(&state->mutex);
328 state->autodetect = true;
329 sd = &state->sd;
330 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
331
332 /* Initialize adv7180 */ 495 /* Initialize adv7180 */
333 /* Enable autodetection */ 496 /* Enable autodetection */
334 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG, 497 if (state->autodetect) {
335 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM); 498 ret =
336 if (ret < 0) 499 i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
337 goto err_unreg_subdev; 500 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
501 | state->input);
502 if (ret < 0)
503 return ret;
338 504
339 ret = i2c_smbus_write_byte_data(client, ADV7180_AUTODETECT_ENABLE_REG, 505 ret =
340 ADV7180_AUTODETECT_DEFAULT); 506 i2c_smbus_write_byte_data(client,
341 if (ret < 0) 507 ADV7180_AUTODETECT_ENABLE_REG,
342 goto err_unreg_subdev; 508 ADV7180_AUTODETECT_DEFAULT);
509 if (ret < 0)
510 return ret;
511 } else {
512 ret = v4l2_std_to_adv7180(state->curr_norm);
513 if (ret < 0)
514 return ret;
343 515
516 ret =
517 i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
518 ret | state->input);
519 if (ret < 0)
520 return ret;
521
522 }
344 /* ITU-R BT.656-4 compatible */ 523 /* ITU-R BT.656-4 compatible */
345 ret = i2c_smbus_write_byte_data(client, 524 ret = i2c_smbus_write_byte_data(client,
346 ADV7180_EXTENDED_OUTPUT_CONTROL_REG, 525 ADV7180_EXTENDED_OUTPUT_CONTROL_REG,
347 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS); 526 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
348 if (ret < 0) 527 if (ret < 0)
349 goto err_unreg_subdev; 528 return ret;
529
530 /* Manually set V bit end position in NTSC mode */
531 ret = i2c_smbus_write_byte_data(client,
532 ADV7180_NTSC_V_BIT_END_REG,
533 ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
534 if (ret < 0)
535 return ret;
350 536
351 /* read current norm */ 537 /* read current norm */
352 __adv7180_status(client, NULL, &state->curr_norm); 538 __adv7180_status(client, NULL, &state->curr_norm);
@@ -354,45 +540,109 @@ static __devinit int adv7180_probe(struct i2c_client *client,
354 /* register for interrupts */ 540 /* register for interrupts */
355 if (state->irq > 0) { 541 if (state->irq > 0) {
356 ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME, 542 ret = request_irq(state->irq, adv7180_irq, 0, DRIVER_NAME,
357 state); 543 state);
358 if (ret) 544 if (ret)
359 goto err_unreg_subdev; 545 return ret;
360 546
361 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 547 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
362 ADV7180_ADI_CTRL_IRQ_SPACE); 548 ADV7180_ADI_CTRL_IRQ_SPACE);
363 if (ret < 0) 549 if (ret < 0)
364 goto err_unreg_subdev; 550 return ret;
365 551
366 /* config the Interrupt pin to be active low */ 552 /* config the Interrupt pin to be active low */
367 ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI, 553 ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
368 ADV7180_ICONF1_ACTIVE_LOW | ADV7180_ICONF1_PSYNC_ONLY); 554 ADV7180_ICONF1_ACTIVE_LOW |
555 ADV7180_ICONF1_PSYNC_ONLY);
369 if (ret < 0) 556 if (ret < 0)
370 goto err_unreg_subdev; 557 return ret;
371 558
372 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0); 559 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
373 if (ret < 0) 560 if (ret < 0)
374 goto err_unreg_subdev; 561 return ret;
375 562
376 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0); 563 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
377 if (ret < 0) 564 if (ret < 0)
378 goto err_unreg_subdev; 565 return ret;
379 566
380 /* enable AD change interrupts interrupts */ 567 /* enable AD change interrupts interrupts */
381 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI, 568 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
382 ADV7180_IRQ3_AD_CHANGE); 569 ADV7180_IRQ3_AD_CHANGE);
383 if (ret < 0) 570 if (ret < 0)
384 goto err_unreg_subdev; 571 return ret;
385 572
386 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0); 573 ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
387 if (ret < 0) 574 if (ret < 0)
388 goto err_unreg_subdev; 575 return ret;
389 576
390 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG, 577 ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
391 0); 578 0);
392 if (ret < 0) 579 if (ret < 0)
393 goto err_unreg_subdev; 580 return ret;
394 } 581 }
395 582
583 /*Set default value for controls */
584 ret = i2c_smbus_write_byte_data(client, ADV7180_BRI_REG,
585 state->brightness);
586 if (ret < 0)
587 return ret;
588
589 ret = i2c_smbus_write_byte_data(client, ADV7180_HUE_REG, state->hue);
590 if (ret < 0)
591 return ret;
592
593 ret = i2c_smbus_write_byte_data(client, ADV7180_CON_REG,
594 state->contrast);
595 if (ret < 0)
596 return ret;
597
598 ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CB_REG,
599 state->saturation);
600 if (ret < 0)
601 return ret;
602
603 ret = i2c_smbus_write_byte_data(client, ADV7180_SD_SAT_CR_REG,
604 state->saturation);
605 if (ret < 0)
606 return ret;
607
608 return 0;
609}
610
611static __devinit int adv7180_probe(struct i2c_client *client,
612 const struct i2c_device_id *id)
613{
614 struct adv7180_state *state;
615 struct v4l2_subdev *sd;
616 int ret;
617
618 /* Check if the adapter supports the needed features */
619 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
620 return -EIO;
621
622 v4l_info(client, "chip found @ 0x%02x (%s)\n",
623 client->addr, client->adapter->name);
624
625 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
626 if (state == NULL) {
627 ret = -ENOMEM;
628 goto err;
629 }
630
631 state->irq = client->irq;
632 INIT_WORK(&state->work, adv7180_work);
633 mutex_init(&state->mutex);
634 state->autodetect = true;
635 state->brightness = BRI_REG_DEF;
636 state->hue = HUE_REG_DEF;
637 state->contrast = CON_REG_DEF;
638 state->saturation = SAT_REG_DEF;
639 state->input = 0;
640 sd = &state->sd;
641 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
642
643 ret = init_device(client, state);
644 if (0 != ret)
645 goto err_unreg_subdev;
396 return 0; 646 return 0;
397 647
398err_unreg_subdev: 648err_unreg_subdev:
@@ -432,16 +682,49 @@ static const struct i2c_device_id adv7180_id[] = {
432 {}, 682 {},
433}; 683};
434 684
685#ifdef CONFIG_PM
686static int adv7180_suspend(struct i2c_client *client, pm_message_t state)
687{
688 int ret;
689
690 ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
691 ADV7180_PWR_MAN_OFF);
692 if (ret < 0)
693 return ret;
694 return 0;
695}
696
697static int adv7180_resume(struct i2c_client *client)
698{
699 struct v4l2_subdev *sd = i2c_get_clientdata(client);
700 struct adv7180_state *state = to_state(sd);
701 int ret;
702
703 ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
704 ADV7180_PWR_MAN_ON);
705 if (ret < 0)
706 return ret;
707 ret = init_device(client, state);
708 if (ret < 0)
709 return ret;
710 return 0;
711}
712#endif
713
435MODULE_DEVICE_TABLE(i2c, adv7180_id); 714MODULE_DEVICE_TABLE(i2c, adv7180_id);
436 715
437static struct i2c_driver adv7180_driver = { 716static struct i2c_driver adv7180_driver = {
438 .driver = { 717 .driver = {
439 .owner = THIS_MODULE, 718 .owner = THIS_MODULE,
440 .name = DRIVER_NAME, 719 .name = DRIVER_NAME,
441 }, 720 },
442 .probe = adv7180_probe, 721 .probe = adv7180_probe,
443 .remove = __devexit_p(adv7180_remove), 722 .remove = __devexit_p(adv7180_remove),
444 .id_table = adv7180_id, 723#ifdef CONFIG_PM
724 .suspend = adv7180_suspend,
725 .resume = adv7180_resume,
726#endif
727 .id_table = adv7180_id,
445}; 728};
446 729
447module_i2c_driver(adv7180_driver); 730module_i2c_driver(adv7180_driver);
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 119b60401bf3..2b5aa676a84e 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -130,14 +130,12 @@ static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
130{ 130{
131 struct adv7343_state *state = to_state(sd); 131 struct adv7343_state *state = to_state(sd);
132 struct adv7343_std_info *std_info; 132 struct adv7343_std_info *std_info;
133 int output_idx, num_std; 133 int num_std;
134 char *fsc_ptr; 134 char *fsc_ptr;
135 u8 reg, val; 135 u8 reg, val;
136 int err = 0; 136 int err = 0;
137 int i = 0; 137 int i = 0;
138 138
139 output_idx = state->output;
140
141 std_info = (struct adv7343_std_info *)stdinfo; 139 std_info = (struct adv7343_std_info *)stdinfo;
142 num_std = ARRAY_SIZE(stdinfo); 140 num_std = ARRAY_SIZE(stdinfo);
143 141
diff --git a/drivers/media/video/aptina-pll.c b/drivers/media/video/aptina-pll.c
index 0bd3813bb59d..8153a449846b 100644
--- a/drivers/media/video/aptina-pll.c
+++ b/drivers/media/video/aptina-pll.c
@@ -148,9 +148,8 @@ int aptina_pll_calculate(struct device *dev,
148 unsigned int mf_high; 148 unsigned int mf_high;
149 unsigned int mf_low; 149 unsigned int mf_low;
150 150
151 mf_low = max(roundup(mf_min, mf_inc), 151 mf_low = roundup(max(mf_min, DIV_ROUND_UP(pll->ext_clock * p1,
152 DIV_ROUND_UP(pll->ext_clock * p1, 152 limits->int_clock_max * div)), mf_inc);
153 limits->int_clock_max * div));
154 mf_high = min(mf_max, pll->ext_clock * p1 / 153 mf_high = min(mf_max, pll->ext_clock * p1 /
155 (limits->int_clock_min * div)); 154 (limits->int_clock_min * div));
156 155
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index b6ed44aebe30..e346d32d08ce 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -31,6 +31,7 @@
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32#include <media/v4l2-device.h> 32#include <media/v4l2-device.h>
33#include <media/v4l2-ioctl.h> 33#include <media/v4l2-ioctl.h>
34#include <media/v4l2-fh.h>
34#include <linux/mutex.h> 35#include <linux/mutex.h>
35 36
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -403,7 +404,8 @@ static int ar_querycap(struct file *file, void *priv,
403 strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver)); 404 strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver));
404 strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card)); 405 strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card));
405 strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info)); 406 strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info));
406 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 407 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
408 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
407 return 0; 409 return 0;
408} 410}
409 411
@@ -709,6 +711,8 @@ static int ar_initialize(struct ar *ar)
709 711
710static const struct v4l2_file_operations ar_fops = { 712static const struct v4l2_file_operations ar_fops = {
711 .owner = THIS_MODULE, 713 .owner = THIS_MODULE,
714 .open = v4l2_fh_open,
715 .release = v4l2_fh_release,
712 .read = ar_read, 716 .read = ar_read,
713 .unlocked_ioctl = video_ioctl2, 717 .unlocked_ioctl = video_ioctl2,
714}; 718};
@@ -769,6 +773,7 @@ static int __init ar_init(void)
769 ar->vdev.fops = &ar_fops; 773 ar->vdev.fops = &ar_fops;
770 ar->vdev.ioctl_ops = &ar_ioctl_ops; 774 ar->vdev.ioctl_ops = &ar_ioctl_ops;
771 ar->vdev.release = video_device_release_empty; 775 ar->vdev.release = video_device_release_empty;
776 set_bit(V4L2_FL_USE_FH_PRIO, &ar->vdev.flags);
772 video_set_drvdata(&ar->vdev, ar); 777 video_set_drvdata(&ar->vdev, ar);
773 778
774 if (vga) { 779 if (vga) {
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c
index 7a3371f044fc..c4b03572dce8 100644
--- a/drivers/media/video/as3645a.c
+++ b/drivers/media/video/as3645a.c
@@ -713,7 +713,7 @@ static int as3645a_resume(struct device *dev)
713 * The number of LEDs reported in platform data is used to compute default 713 * The number of LEDs reported in platform data is used to compute default
714 * limits. Parameters passed through platform data can override those limits. 714 * limits. Parameters passed through platform data can override those limits.
715 */ 715 */
716static int as3645a_init_controls(struct as3645a *flash) 716static int __devinit as3645a_init_controls(struct as3645a *flash)
717{ 717{
718 const struct as3645a_platform_data *pdata = flash->pdata; 718 const struct as3645a_platform_data *pdata = flash->pdata;
719 struct v4l2_ctrl *ctrl; 719 struct v4l2_ctrl *ctrl;
@@ -804,8 +804,8 @@ static int as3645a_init_controls(struct as3645a *flash)
804 return flash->ctrls.error; 804 return flash->ctrls.error;
805} 805}
806 806
807static int as3645a_probe(struct i2c_client *client, 807static int __devinit as3645a_probe(struct i2c_client *client,
808 const struct i2c_device_id *devid) 808 const struct i2c_device_id *devid)
809{ 809{
810 struct as3645a *flash; 810 struct as3645a *flash;
811 int ret; 811 int ret;
@@ -846,7 +846,7 @@ done:
846 return ret; 846 return ret;
847} 847}
848 848
849static int __exit as3645a_remove(struct i2c_client *client) 849static int __devexit as3645a_remove(struct i2c_client *client)
850{ 850{
851 struct v4l2_subdev *subdev = i2c_get_clientdata(client); 851 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
852 struct as3645a *flash = to_as3645a(subdev); 852 struct as3645a *flash = to_as3645a(subdev);
@@ -877,7 +877,7 @@ static struct i2c_driver as3645a_i2c_driver = {
877 .pm = &as3645a_pm_ops, 877 .pm = &as3645a_pm_ops,
878 }, 878 },
879 .probe = as3645a_probe, 879 .probe = as3645a_probe,
880 .remove = __exit_p(as3645a_remove), 880 .remove = __devexit_p(as3645a_remove),
881 .id_table = as3645a_id_table, 881 .id_table = as3645a_id_table,
882}; 882};
883 883
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index ec3f6a06f9c3..6274a91c25c7 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -260,7 +260,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
260 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 260 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
261 struct atmel_isi *isi = ici->priv; 261 struct atmel_isi *isi = ici->priv;
262 unsigned long size; 262 unsigned long size;
263 int ret, bytes_per_line; 263 int ret;
264 264
265 /* Reset ISI */ 265 /* Reset ISI */
266 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); 266 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
@@ -271,13 +271,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
271 /* Disable all interrupts */ 271 /* Disable all interrupts */
272 isi_writel(isi, ISI_INTDIS, ~0UL); 272 isi_writel(isi, ISI_INTDIS, ~0UL);
273 273
274 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 274 size = icd->sizeimage;
275 icd->current_fmt->host_fmt);
276
277 if (bytes_per_line < 0)
278 return bytes_per_line;
279
280 size = bytes_per_line * icd->user_height;
281 275
282 if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM) 276 if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM)
283 *nbuffers = MAX_BUFFER_NUM; 277 *nbuffers = MAX_BUFFER_NUM;
@@ -316,13 +310,8 @@ static int buffer_prepare(struct vb2_buffer *vb)
316 struct atmel_isi *isi = ici->priv; 310 struct atmel_isi *isi = ici->priv;
317 unsigned long size; 311 unsigned long size;
318 struct isi_dma_desc *desc; 312 struct isi_dma_desc *desc;
319 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
320 icd->current_fmt->host_fmt);
321
322 if (bytes_per_line < 0)
323 return bytes_per_line;
324 313
325 size = bytes_per_line * icd->user_height; 314 size = icd->sizeimage;
326 315
327 if (vb2_plane_size(vb, 0) < size) { 316 if (vb2_plane_size(vb, 0) < size) {
328 dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n", 317 dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n",
@@ -638,6 +627,7 @@ static const struct soc_mbus_pixelfmt isi_camera_formats[] = {
638 .bits_per_sample = 8, 627 .bits_per_sample = 8,
639 .packing = SOC_MBUS_PACKING_2X8_PADHI, 628 .packing = SOC_MBUS_PACKING_2X8_PADHI,
640 .order = SOC_MBUS_ORDER_LE, 629 .order = SOC_MBUS_ORDER_LE,
630 .layout = SOC_MBUS_LAYOUT_PACKED,
641 }, 631 },
642}; 632};
643 633
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 81ba9d9d1b52..23f7fd22f0eb 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -6,7 +6,8 @@ config VIDEO_AU0828
6 select I2C_ALGOBIT 6 select I2C_ALGOBIT
7 select VIDEO_TVEEPROM 7 select VIDEO_TVEEPROM
8 select VIDEOBUF_VMALLOC 8 select VIDEOBUF_VMALLOC
9 select DVB_AU8522 if !DVB_FE_CUSTOMISE 9 select DVB_AU8522_DTV if !DVB_FE_CUSTOMISE
10 select DVB_AU8522_V4L if !DVB_FE_CUSTOMISE
10 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE 11 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
11 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE 12 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
12 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE 13 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 1c6015a04f96..e3fe9a6637f6 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -325,6 +325,8 @@ struct usb_device_id au0828_usb_id_table[] = {
325 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, 325 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
326 { USB_DEVICE(0x2040, 0x7281), 326 { USB_DEVICE(0x2040, 0x7281),
327 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, 327 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
328 { USB_DEVICE(0x05e1, 0x0480),
329 .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
328 { USB_DEVICE(0x2040, 0x8200), 330 { USB_DEVICE(0x2040, 0x8200),
329 .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY }, 331 .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
330 { USB_DEVICE(0x2040, 0x7260), 332 { USB_DEVICE(0x2040, 0x7260),
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 518216743c9c..39ece8e24985 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/suspend.h> 26#include <linux/suspend.h>
27#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
28#include <media/tuner.h>
28 29
29#include "au0828.h" 30#include "au0828.h"
30#include "au8522.h" 31#include "au8522.h"
@@ -79,9 +80,16 @@ static struct au8522_config hauppauge_woodbury_config = {
79 .vsb_if = AU8522_IF_3_25MHZ, 80 .vsb_if = AU8522_IF_3_25MHZ,
80}; 81};
81 82
82static struct xc5000_config hauppauge_hvr950q_tunerconfig = { 83static struct xc5000_config hauppauge_xc5000a_config = {
83 .i2c_address = 0x61, 84 .i2c_address = 0x61,
84 .if_khz = 6000, 85 .if_khz = 6000,
86 .chip_id = XC5000A,
87};
88
89static struct xc5000_config hauppauge_xc5000c_config = {
90 .i2c_address = 0x61,
91 .if_khz = 6000,
92 .chip_id = XC5000C,
85}; 93};
86 94
87static struct mxl5007t_config mxl5007t_hvr950q_config = { 95static struct mxl5007t_config mxl5007t_hvr950q_config = {
@@ -383,8 +391,19 @@ int au0828_dvb_register(struct au0828_dev *dev)
383 &hauppauge_hvr950q_config, 391 &hauppauge_hvr950q_config,
384 &dev->i2c_adap); 392 &dev->i2c_adap);
385 if (dvb->frontend != NULL) 393 if (dvb->frontend != NULL)
386 dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, 394 switch (dev->board.tuner_type) {
387 &hauppauge_hvr950q_tunerconfig); 395 default:
396 case TUNER_XC5000:
397 dvb_attach(xc5000_attach, dvb->frontend,
398 &dev->i2c_adap,
399 &hauppauge_xc5000a_config);
400 break;
401 case TUNER_XC5000C:
402 dvb_attach(xc5000_attach, dvb->frontend,
403 &dev->i2c_adap,
404 &hauppauge_xc5000c_config);
405 break;
406 }
388 break; 407 break;
389 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: 408 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
390 dvb->frontend = dvb_attach(au8522_attach, 409 dvb->frontend = dvb_attach(au8522_attach,
@@ -411,7 +430,7 @@ int au0828_dvb_register(struct au0828_dev *dev)
411 if (dvb->frontend != NULL) { 430 if (dvb->frontend != NULL) {
412 dvb_attach(xc5000_attach, dvb->frontend, 431 dvb_attach(xc5000_attach, dvb->frontend,
413 &dev->i2c_adap, 432 &dev->i2c_adap,
414 &hauppauge_hvr950q_tunerconfig); 433 &hauppauge_xc5000a_config);
415 } 434 }
416 break; 435 break;
417 default: 436 default:
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 0b3e481ffe8c..ac3dd733ab81 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -120,7 +120,7 @@ static void au0828_irq_callback(struct urb *urb)
120 struct au0828_dmaqueue *dma_q = urb->context; 120 struct au0828_dmaqueue *dma_q = urb->context;
121 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq); 121 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
122 unsigned long flags = 0; 122 unsigned long flags = 0;
123 int rc, i; 123 int i;
124 124
125 switch (urb->status) { 125 switch (urb->status) {
126 case 0: /* success */ 126 case 0: /* success */
@@ -138,7 +138,7 @@ static void au0828_irq_callback(struct urb *urb)
138 138
139 /* Copy data from URB */ 139 /* Copy data from URB */
140 spin_lock_irqsave(&dev->slock, flags); 140 spin_lock_irqsave(&dev->slock, flags);
141 rc = dev->isoc_ctl.isoc_copy(dev, urb); 141 dev->isoc_ctl.isoc_copy(dev, urb);
142 spin_unlock_irqrestore(&dev->slock, flags); 142 spin_unlock_irqrestore(&dev->slock, flags);
143 143
144 /* Reset urb buffers */ 144 /* Reset urb buffers */
@@ -1881,7 +1881,7 @@ int au0828_analog_register(struct au0828_dev *dev,
1881 int retval = -ENOMEM; 1881 int retval = -ENOMEM;
1882 struct usb_host_interface *iface_desc; 1882 struct usb_host_interface *iface_desc;
1883 struct usb_endpoint_descriptor *endpoint; 1883 struct usb_endpoint_descriptor *endpoint;
1884 int i; 1884 int i, ret;
1885 1885
1886 dprintk(1, "au0828_analog_register called!\n"); 1886 dprintk(1, "au0828_analog_register called!\n");
1887 1887
@@ -1951,8 +1951,8 @@ int au0828_analog_register(struct au0828_dev *dev,
1951 dev->vbi_dev = video_device_alloc(); 1951 dev->vbi_dev = video_device_alloc();
1952 if (NULL == dev->vbi_dev) { 1952 if (NULL == dev->vbi_dev) {
1953 dprintk(1, "Can't allocate vbi_device.\n"); 1953 dprintk(1, "Can't allocate vbi_device.\n");
1954 kfree(dev->vdev); 1954 ret = -ENOMEM;
1955 return -ENOMEM; 1955 goto err_vdev;
1956 } 1956 }
1957 1957
1958 /* Fill the video capture device struct */ 1958 /* Fill the video capture device struct */
@@ -1971,8 +1971,8 @@ int au0828_analog_register(struct au0828_dev *dev,
1971 if (retval != 0) { 1971 if (retval != 0) {
1972 dprintk(1, "unable to register video device (error = %d).\n", 1972 dprintk(1, "unable to register video device (error = %d).\n",
1973 retval); 1973 retval);
1974 video_device_release(dev->vdev); 1974 ret = -ENODEV;
1975 return -ENODEV; 1975 goto err_vbi_dev;
1976 } 1976 }
1977 1977
1978 /* Register the vbi device */ 1978 /* Register the vbi device */
@@ -1981,13 +1981,18 @@ int au0828_analog_register(struct au0828_dev *dev,
1981 if (retval != 0) { 1981 if (retval != 0) {
1982 dprintk(1, "unable to register vbi device (error = %d).\n", 1982 dprintk(1, "unable to register vbi device (error = %d).\n",
1983 retval); 1983 retval);
1984 video_device_release(dev->vbi_dev); 1984 ret = -ENODEV;
1985 video_device_release(dev->vdev); 1985 goto err_vbi_dev;
1986 return -ENODEV;
1987 } 1986 }
1988 1987
1989 dprintk(1, "%s completed!\n", __func__); 1988 dprintk(1, "%s completed!\n", __func__);
1990 1989
1991 return 0; 1990 return 0;
1991
1992err_vbi_dev:
1993 video_device_release(dev->vbi_dev);
1994err_vdev:
1995 video_device_release(dev->vdev);
1996 return ret;
1992} 1997}
1993 1998
diff --git a/drivers/media/video/blackfin/bfin_capture.c b/drivers/media/video/blackfin/bfin_capture.c
index 514fcf742f5a..0aba45e34f70 100644
--- a/drivers/media/video/blackfin/bfin_capture.c
+++ b/drivers/media/video/blackfin/bfin_capture.c
@@ -942,6 +942,10 @@ static int __devinit bcap_probe(struct platform_device *pdev)
942 INIT_LIST_HEAD(&bcap_dev->dma_queue); 942 INIT_LIST_HEAD(&bcap_dev->dma_queue);
943 943
944 vfd->lock = &bcap_dev->mutex; 944 vfd->lock = &bcap_dev->mutex;
945 /* Locking in file operations other than ioctl should be done
946 by the driver, not the V4L2 core.
947 This driver needs auditing so that this flag can be removed. */
948 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
945 949
946 /* register video device */ 950 /* register video device */
947 ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); 951 ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1);
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index e581b37be789..a9cfb0f4be48 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -663,7 +663,7 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
663 .minimum = 0, 663 .minimum = 0,
664 .maximum = 65535, 664 .maximum = 65535,
665 .step = 128, 665 .step = 128,
666 .default_value = 32768, 666 .default_value = 27648,
667 .type = V4L2_CTRL_TYPE_INTEGER, 667 .type = V4L2_CTRL_TYPE_INTEGER,
668 },{ 668 },{
669 .id = V4L2_CID_SATURATION, 669 .id = V4L2_CID_SATURATION,
@@ -4394,7 +4394,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4394 if (!bttv_tvcards[btv->c.type].no_video) { 4394 if (!bttv_tvcards[btv->c.type].no_video) {
4395 bttv_register_video(btv); 4395 bttv_register_video(btv);
4396 bt848_bright(btv,32768); 4396 bt848_bright(btv,32768);
4397 bt848_contrast(btv,32768); 4397 bt848_contrast(btv, 27648);
4398 bt848_hue(btv,32768); 4398 bt848_hue(btv,32768);
4399 bt848_sat(btv,32768); 4399 bt848_sat(btv,32768);
4400 audio_mute(btv, 1); 4400 audio_mute(btv, 1);
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index f09df9dffaae..2520219f01ba 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -77,6 +77,9 @@ OTHER DEALINGS IN THE SOFTWARE.
77#include <media/v4l2-common.h> 77#include <media/v4l2-common.h>
78#include <media/v4l2-ioctl.h> 78#include <media/v4l2-ioctl.h>
79#include <media/v4l2-device.h> 79#include <media/v4l2-device.h>
80#include <media/v4l2-fh.h>
81#include <media/v4l2-ctrls.h>
82#include <media/v4l2-event.h>
80 83
81/* One from column A... */ 84/* One from column A... */
82#define QC_NOTSET 0 85#define QC_NOTSET 0
@@ -103,6 +106,7 @@ OTHER DEALINGS IN THE SOFTWARE.
103struct qcam { 106struct qcam {
104 struct v4l2_device v4l2_dev; 107 struct v4l2_device v4l2_dev;
105 struct video_device vdev; 108 struct video_device vdev;
109 struct v4l2_ctrl_handler hdl;
106 struct pardevice *pdev; 110 struct pardevice *pdev;
107 struct parport *pport; 111 struct parport *pport;
108 struct mutex lock; 112 struct mutex lock;
@@ -646,7 +650,8 @@ static int qcam_querycap(struct file *file, void *priv,
646 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); 650 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
647 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); 651 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
648 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); 652 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
649 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 653 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
654 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
650 return 0; 655 return 0;
651} 656}
652 657
@@ -674,72 +679,6 @@ static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
674 return (inp > 0) ? -EINVAL : 0; 679 return (inp > 0) ? -EINVAL : 0;
675} 680}
676 681
677static int qcam_queryctrl(struct file *file, void *priv,
678 struct v4l2_queryctrl *qc)
679{
680 switch (qc->id) {
681 case V4L2_CID_BRIGHTNESS:
682 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
683 case V4L2_CID_CONTRAST:
684 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
685 case V4L2_CID_GAMMA:
686 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
687 }
688 return -EINVAL;
689}
690
691static int qcam_g_ctrl(struct file *file, void *priv,
692 struct v4l2_control *ctrl)
693{
694 struct qcam *qcam = video_drvdata(file);
695 int ret = 0;
696
697 switch (ctrl->id) {
698 case V4L2_CID_BRIGHTNESS:
699 ctrl->value = qcam->brightness;
700 break;
701 case V4L2_CID_CONTRAST:
702 ctrl->value = qcam->contrast;
703 break;
704 case V4L2_CID_GAMMA:
705 ctrl->value = qcam->whitebal;
706 break;
707 default:
708 ret = -EINVAL;
709 break;
710 }
711 return ret;
712}
713
714static int qcam_s_ctrl(struct file *file, void *priv,
715 struct v4l2_control *ctrl)
716{
717 struct qcam *qcam = video_drvdata(file);
718 int ret = 0;
719
720 mutex_lock(&qcam->lock);
721 switch (ctrl->id) {
722 case V4L2_CID_BRIGHTNESS:
723 qcam->brightness = ctrl->value;
724 break;
725 case V4L2_CID_CONTRAST:
726 qcam->contrast = ctrl->value;
727 break;
728 case V4L2_CID_GAMMA:
729 qcam->whitebal = ctrl->value;
730 break;
731 default:
732 ret = -EINVAL;
733 break;
734 }
735 if (ret == 0) {
736 qc_setscanmode(qcam);
737 qcam->status |= QC_PARAM_CHANGE;
738 }
739 mutex_unlock(&qcam->lock);
740 return ret;
741}
742
743static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 682static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
744{ 683{
745 struct qcam *qcam = video_drvdata(file); 684 struct qcam *qcam = video_drvdata(file);
@@ -856,8 +795,40 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
856 return len; 795 return len;
857} 796}
858 797
798static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
799{
800 struct qcam *qcam =
801 container_of(ctrl->handler, struct qcam, hdl);
802 int ret = 0;
803
804 mutex_lock(&qcam->lock);
805 switch (ctrl->id) {
806 case V4L2_CID_BRIGHTNESS:
807 qcam->brightness = ctrl->val;
808 break;
809 case V4L2_CID_CONTRAST:
810 qcam->contrast = ctrl->val;
811 break;
812 case V4L2_CID_GAMMA:
813 qcam->whitebal = ctrl->val;
814 break;
815 default:
816 ret = -EINVAL;
817 break;
818 }
819 if (ret == 0) {
820 qc_setscanmode(qcam);
821 qcam->status |= QC_PARAM_CHANGE;
822 }
823 mutex_unlock(&qcam->lock);
824 return ret;
825}
826
859static const struct v4l2_file_operations qcam_fops = { 827static const struct v4l2_file_operations qcam_fops = {
860 .owner = THIS_MODULE, 828 .owner = THIS_MODULE,
829 .open = v4l2_fh_open,
830 .release = v4l2_fh_release,
831 .poll = v4l2_ctrl_poll,
861 .unlocked_ioctl = video_ioctl2, 832 .unlocked_ioctl = video_ioctl2,
862 .read = qcam_read, 833 .read = qcam_read,
863}; 834};
@@ -867,13 +838,17 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
867 .vidioc_g_input = qcam_g_input, 838 .vidioc_g_input = qcam_g_input,
868 .vidioc_s_input = qcam_s_input, 839 .vidioc_s_input = qcam_s_input,
869 .vidioc_enum_input = qcam_enum_input, 840 .vidioc_enum_input = qcam_enum_input,
870 .vidioc_queryctrl = qcam_queryctrl,
871 .vidioc_g_ctrl = qcam_g_ctrl,
872 .vidioc_s_ctrl = qcam_s_ctrl,
873 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, 841 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
874 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, 842 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
875 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, 843 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
876 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, 844 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
845 .vidioc_log_status = v4l2_ctrl_log_status,
846 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
847 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
848};
849
850static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
851 .s_ctrl = qcam_s_ctrl,
877}; 852};
878 853
879/* Initialize the QuickCam driver control structure. This is where 854/* Initialize the QuickCam driver control structure. This is where
@@ -897,19 +872,35 @@ static struct qcam *qcam_init(struct parport *port)
897 return NULL; 872 return NULL;
898 } 873 }
899 874
875 v4l2_ctrl_handler_init(&qcam->hdl, 3);
876 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
877 V4L2_CID_BRIGHTNESS, 0, 255, 1, 180);
878 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
879 V4L2_CID_CONTRAST, 0, 255, 1, 192);
880 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
881 V4L2_CID_GAMMA, 0, 255, 1, 105);
882 if (qcam->hdl.error) {
883 v4l2_err(v4l2_dev, "couldn't register controls\n");
884 v4l2_ctrl_handler_free(&qcam->hdl);
885 kfree(qcam);
886 return NULL;
887 }
900 qcam->pport = port; 888 qcam->pport = port;
901 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, 889 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
902 NULL, 0, NULL); 890 NULL, 0, NULL);
903 if (qcam->pdev == NULL) { 891 if (qcam->pdev == NULL) {
904 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); 892 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
893 v4l2_ctrl_handler_free(&qcam->hdl);
905 kfree(qcam); 894 kfree(qcam);
906 return NULL; 895 return NULL;
907 } 896 }
908 897
909 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); 898 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
910 qcam->vdev.v4l2_dev = v4l2_dev; 899 qcam->vdev.v4l2_dev = v4l2_dev;
900 qcam->vdev.ctrl_handler = &qcam->hdl;
911 qcam->vdev.fops = &qcam_fops; 901 qcam->vdev.fops = &qcam_fops;
912 qcam->vdev.ioctl_ops = &qcam_ioctl_ops; 902 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
903 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
913 qcam->vdev.release = video_device_release_empty; 904 qcam->vdev.release = video_device_release_empty;
914 video_set_drvdata(&qcam->vdev, qcam); 905 video_set_drvdata(&qcam->vdev, qcam);
915 906
@@ -1003,6 +994,7 @@ static int init_bwqcam(struct parport *port)
1003static void close_bwqcam(struct qcam *qcam) 994static void close_bwqcam(struct qcam *qcam)
1004{ 995{
1005 video_unregister_device(&qcam->vdev); 996 video_unregister_device(&qcam->vdev);
997 v4l2_ctrl_handler_free(&qcam->hdl);
1006 parport_unregister_device(qcam->pdev); 998 parport_unregister_device(qcam->pdev);
1007 kfree(qcam); 999 kfree(qcam);
1008} 1000}
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index fda32f52554a..ec51e1f12e82 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -40,10 +40,14 @@
40#include <media/v4l2-device.h> 40#include <media/v4l2-device.h>
41#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
42#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
43#include <media/v4l2-fh.h>
44#include <media/v4l2-ctrls.h>
45#include <media/v4l2-event.h>
43 46
44struct qcam { 47struct qcam {
45 struct v4l2_device v4l2_dev; 48 struct v4l2_device v4l2_dev;
46 struct video_device vdev; 49 struct video_device vdev;
50 struct v4l2_ctrl_handler hdl;
47 struct pardevice *pdev; 51 struct pardevice *pdev;
48 struct parport *pport; 52 struct parport *pport;
49 int width, height; 53 int width, height;
@@ -378,7 +382,7 @@ get_fragment:
378static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len) 382static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
379{ 383{
380 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; 384 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
381 unsigned lines, pixelsperline, bitsperxfer; 385 unsigned lines, pixelsperline;
382 unsigned int is_bi_dir = qcam->bidirectional; 386 unsigned int is_bi_dir = qcam->bidirectional;
383 size_t wantlen, outptr = 0; 387 size_t wantlen, outptr = 0;
384 char tmpbuf[BUFSZ]; 388 char tmpbuf[BUFSZ];
@@ -404,7 +408,6 @@ static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
404 408
405 lines = qcam->height; 409 lines = qcam->height;
406 pixelsperline = qcam->width; 410 pixelsperline = qcam->width;
407 bitsperxfer = (is_bi_dir) ? 24 : 8;
408 411
409 if (is_bi_dir) { 412 if (is_bi_dir) {
410 /* Turn the port around */ 413 /* Turn the port around */
@@ -516,7 +519,8 @@ static int qcam_querycap(struct file *file, void *priv,
516 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); 519 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
517 strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card)); 520 strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card));
518 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); 521 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
519 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 522 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
523 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
520 return 0; 524 return 0;
521} 525}
522 526
@@ -544,73 +548,6 @@ static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
544 return (inp > 0) ? -EINVAL : 0; 548 return (inp > 0) ? -EINVAL : 0;
545} 549}
546 550
547static int qcam_queryctrl(struct file *file, void *priv,
548 struct v4l2_queryctrl *qc)
549{
550 switch (qc->id) {
551 case V4L2_CID_BRIGHTNESS:
552 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 240);
553 case V4L2_CID_CONTRAST:
554 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
555 case V4L2_CID_GAMMA:
556 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
557 }
558 return -EINVAL;
559}
560
561static int qcam_g_ctrl(struct file *file, void *priv,
562 struct v4l2_control *ctrl)
563{
564 struct qcam *qcam = video_drvdata(file);
565 int ret = 0;
566
567 switch (ctrl->id) {
568 case V4L2_CID_BRIGHTNESS:
569 ctrl->value = qcam->brightness;
570 break;
571 case V4L2_CID_CONTRAST:
572 ctrl->value = qcam->contrast;
573 break;
574 case V4L2_CID_GAMMA:
575 ctrl->value = qcam->whitebal;
576 break;
577 default:
578 ret = -EINVAL;
579 break;
580 }
581 return ret;
582}
583
584static int qcam_s_ctrl(struct file *file, void *priv,
585 struct v4l2_control *ctrl)
586{
587 struct qcam *qcam = video_drvdata(file);
588 int ret = 0;
589
590 mutex_lock(&qcam->lock);
591 switch (ctrl->id) {
592 case V4L2_CID_BRIGHTNESS:
593 qcam->brightness = ctrl->value;
594 break;
595 case V4L2_CID_CONTRAST:
596 qcam->contrast = ctrl->value;
597 break;
598 case V4L2_CID_GAMMA:
599 qcam->whitebal = ctrl->value;
600 break;
601 default:
602 ret = -EINVAL;
603 break;
604 }
605 if (ret == 0) {
606 parport_claim_or_block(qcam->pdev);
607 qc_setup(qcam);
608 parport_release(qcam->pdev);
609 }
610 mutex_unlock(&qcam->lock);
611 return ret;
612}
613
614static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 551static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
615{ 552{
616 struct qcam *qcam = video_drvdata(file); 553 struct qcam *qcam = video_drvdata(file);
@@ -714,8 +651,41 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
714 return len; 651 return len;
715} 652}
716 653
654static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
655{
656 struct qcam *qcam =
657 container_of(ctrl->handler, struct qcam, hdl);
658 int ret = 0;
659
660 mutex_lock(&qcam->lock);
661 switch (ctrl->id) {
662 case V4L2_CID_BRIGHTNESS:
663 qcam->brightness = ctrl->val;
664 break;
665 case V4L2_CID_CONTRAST:
666 qcam->contrast = ctrl->val;
667 break;
668 case V4L2_CID_GAMMA:
669 qcam->whitebal = ctrl->val;
670 break;
671 default:
672 ret = -EINVAL;
673 break;
674 }
675 if (ret == 0) {
676 parport_claim_or_block(qcam->pdev);
677 qc_setup(qcam);
678 parport_release(qcam->pdev);
679 }
680 mutex_unlock(&qcam->lock);
681 return ret;
682}
683
717static const struct v4l2_file_operations qcam_fops = { 684static const struct v4l2_file_operations qcam_fops = {
718 .owner = THIS_MODULE, 685 .owner = THIS_MODULE,
686 .open = v4l2_fh_open,
687 .release = v4l2_fh_release,
688 .poll = v4l2_ctrl_poll,
719 .unlocked_ioctl = video_ioctl2, 689 .unlocked_ioctl = video_ioctl2,
720 .read = qcam_read, 690 .read = qcam_read,
721}; 691};
@@ -725,13 +695,17 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
725 .vidioc_g_input = qcam_g_input, 695 .vidioc_g_input = qcam_g_input,
726 .vidioc_s_input = qcam_s_input, 696 .vidioc_s_input = qcam_s_input,
727 .vidioc_enum_input = qcam_enum_input, 697 .vidioc_enum_input = qcam_enum_input,
728 .vidioc_queryctrl = qcam_queryctrl, 698 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
729 .vidioc_g_ctrl = qcam_g_ctrl,
730 .vidioc_s_ctrl = qcam_s_ctrl,
731 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
732 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, 699 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
733 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, 700 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
734 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, 701 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
702 .vidioc_log_status = v4l2_ctrl_log_status,
703 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
704 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
705};
706
707static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
708 .s_ctrl = qcam_s_ctrl,
735}; 709};
736 710
737/* Initialize the QuickCam driver control structure. */ 711/* Initialize the QuickCam driver control structure. */
@@ -754,6 +728,20 @@ static struct qcam *qcam_init(struct parport *port)
754 return NULL; 728 return NULL;
755 } 729 }
756 730
731 v4l2_ctrl_handler_init(&qcam->hdl, 3);
732 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
733 V4L2_CID_BRIGHTNESS, 0, 255, 1, 240);
734 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
735 V4L2_CID_CONTRAST, 0, 255, 1, 192);
736 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
737 V4L2_CID_GAMMA, 0, 255, 1, 128);
738 if (qcam->hdl.error) {
739 v4l2_err(v4l2_dev, "couldn't register controls\n");
740 v4l2_ctrl_handler_free(&qcam->hdl);
741 kfree(qcam);
742 return NULL;
743 }
744
757 qcam->pport = port; 745 qcam->pport = port;
758 qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL, 746 qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
759 NULL, 0, NULL); 747 NULL, 0, NULL);
@@ -762,6 +750,7 @@ static struct qcam *qcam_init(struct parport *port)
762 750
763 if (qcam->pdev == NULL) { 751 if (qcam->pdev == NULL) {
764 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); 752 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
753 v4l2_ctrl_handler_free(&qcam->hdl);
765 kfree(qcam); 754 kfree(qcam);
766 return NULL; 755 return NULL;
767 } 756 }
@@ -771,6 +760,8 @@ static struct qcam *qcam_init(struct parport *port)
771 qcam->vdev.fops = &qcam_fops; 760 qcam->vdev.fops = &qcam_fops;
772 qcam->vdev.ioctl_ops = &qcam_ioctl_ops; 761 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
773 qcam->vdev.release = video_device_release_empty; 762 qcam->vdev.release = video_device_release_empty;
763 qcam->vdev.ctrl_handler = &qcam->hdl;
764 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
774 video_set_drvdata(&qcam->vdev, qcam); 765 video_set_drvdata(&qcam->vdev, qcam);
775 766
776 mutex_init(&qcam->lock); 767 mutex_init(&qcam->lock);
@@ -845,6 +836,7 @@ static int init_cqcam(struct parport *port)
845static void close_cqcam(struct qcam *qcam) 836static void close_cqcam(struct qcam *qcam)
846{ 837{
847 video_unregister_device(&qcam->vdev); 838 video_unregister_device(&qcam->vdev);
839 v4l2_ctrl_handler_free(&qcam->hdl);
848 parport_unregister_device(qcam->pdev); 840 parport_unregister_device(qcam->pdev);
849 kfree(qcam); 841 kfree(qcam);
850} 842}
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h
index ab252188981b..cdef677d57ec 100644
--- a/drivers/media/video/cpia2/cpia2.h
+++ b/drivers/media/video/cpia2/cpia2.h
@@ -32,11 +32,12 @@
32#define __CPIA2_H__ 32#define __CPIA2_H__
33 33
34#include <linux/videodev2.h> 34#include <linux/videodev2.h>
35#include <media/v4l2-common.h>
36#include <linux/usb.h> 35#include <linux/usb.h>
37#include <linux/poll.h> 36#include <linux/poll.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-ctrls.h>
38 40
39#include "cpia2dev.h"
40#include "cpia2_registers.h" 41#include "cpia2_registers.h"
41 42
42/* define for verbose debug output */ 43/* define for verbose debug output */
@@ -65,7 +66,6 @@
65 66
66/* Flicker Modes */ 67/* Flicker Modes */
67#define NEVER_FLICKER 0 68#define NEVER_FLICKER 0
68#define ANTI_FLICKER_ON 1
69#define FLICKER_60 60 69#define FLICKER_60 60
70#define FLICKER_50 50 70#define FLICKER_50 50
71 71
@@ -148,7 +148,6 @@ enum {
148#define DEFAULT_BRIGHTNESS 0x46 148#define DEFAULT_BRIGHTNESS 0x46
149#define DEFAULT_CONTRAST 0x93 149#define DEFAULT_CONTRAST 0x93
150#define DEFAULT_SATURATION 0x7f 150#define DEFAULT_SATURATION 0x7f
151#define DEFAULT_TARGET_KB 0x30
152 151
153/* Power state */ 152/* Power state */
154#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER 153#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER
@@ -287,7 +286,6 @@ struct camera_params {
287 struct { 286 struct {
288 u8 cam_register; 287 u8 cam_register;
289 u8 flicker_mode_req; /* 1 if flicker on, else never flicker */ 288 u8 flicker_mode_req; /* 1 if flicker on, else never flicker */
290 int mains_frequency;
291 } flicker_control; 289 } flicker_control;
292 290
293 struct { 291 struct {
@@ -337,7 +335,7 @@ struct camera_params {
337 u8 vc_control; 335 u8 vc_control;
338 u8 vc_mp_direction; 336 u8 vc_mp_direction;
339 u8 vc_mp_data; 337 u8 vc_mp_data;
340 u8 target_kb; 338 u8 quality;
341 } vc_params; 339 } vc_params;
342 340
343 struct { 341 struct {
@@ -366,23 +364,23 @@ struct framebuf {
366 struct framebuf *next; 364 struct framebuf *next;
367}; 365};
368 366
369struct cpia2_fh {
370 enum v4l2_priority prio;
371 u8 mmapped;
372};
373
374struct camera_data { 367struct camera_data {
375 /* locks */ 368 /* locks */
369 struct v4l2_device v4l2_dev;
376 struct mutex v4l2_lock; /* serialize file operations */ 370 struct mutex v4l2_lock; /* serialize file operations */
377 struct v4l2_prio_state prio; 371 struct v4l2_ctrl_handler hdl;
372 struct {
373 /* Lights control cluster */
374 struct v4l2_ctrl *top_light;
375 struct v4l2_ctrl *bottom_light;
376 };
377 struct v4l2_ctrl *usb_alt;
378 378
379 /* camera status */ 379 /* camera status */
380 volatile int present; /* Is the camera still present? */
381 int open_count; /* # of process that have camera open */
382 int first_image_seen; 380 int first_image_seen;
383 u8 mains_freq; /* for flicker control */
384 enum sensors sensor_type; 381 enum sensors sensor_type;
385 u8 flush; 382 u8 flush;
383 struct v4l2_fh *stream_fh;
386 u8 mmapped; 384 u8 mmapped;
387 int streaming; /* 0 = no, 1 = yes */ 385 int streaming; /* 0 = no, 1 = yes */
388 int xfer_mode; /* XFER_BULK or XFER_ISOC */ 386 int xfer_mode; /* XFER_BULK or XFER_ISOC */
@@ -390,7 +388,7 @@ struct camera_data {
390 388
391 /* v4l */ 389 /* v4l */
392 int video_size; /* VIDEO_SIZE_ */ 390 int video_size; /* VIDEO_SIZE_ */
393 struct video_device *vdev; /* v4l videodev */ 391 struct video_device vdev; /* v4l videodev */
394 u32 width; 392 u32 width;
395 u32 height; /* Its size */ 393 u32 height; /* Its size */
396 __u32 pixelformat; /* Format fourcc */ 394 __u32 pixelformat; /* Format fourcc */
@@ -425,6 +423,7 @@ struct camera_data {
425/* v4l */ 423/* v4l */
426int cpia2_register_camera(struct camera_data *cam); 424int cpia2_register_camera(struct camera_data *cam);
427void cpia2_unregister_camera(struct camera_data *cam); 425void cpia2_unregister_camera(struct camera_data *cam);
426void cpia2_camera_release(struct v4l2_device *v4l2_dev);
428 427
429/* core */ 428/* core */
430int cpia2_reset_camera(struct camera_data *cam); 429int cpia2_reset_camera(struct camera_data *cam);
@@ -443,7 +442,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
443int cpia2_do_command(struct camera_data *cam, 442int cpia2_do_command(struct camera_data *cam,
444 unsigned int command, 443 unsigned int command,
445 unsigned char direction, unsigned char param); 444 unsigned char direction, unsigned char param);
446struct camera_data *cpia2_init_camera_struct(void); 445struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf);
447int cpia2_init_camera(struct camera_data *cam); 446int cpia2_init_camera(struct camera_data *cam);
448int cpia2_allocate_buffers(struct camera_data *cam); 447int cpia2_allocate_buffers(struct camera_data *cam);
449void cpia2_free_buffers(struct camera_data *cam); 448void cpia2_free_buffers(struct camera_data *cam);
@@ -454,7 +453,6 @@ unsigned int cpia2_poll(struct camera_data *cam,
454int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma); 453int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
455void cpia2_set_property_flip(struct camera_data *cam, int prop_val); 454void cpia2_set_property_flip(struct camera_data *cam, int prop_val);
456void cpia2_set_property_mirror(struct camera_data *cam, int prop_val); 455void cpia2_set_property_mirror(struct camera_data *cam, int prop_val);
457int cpia2_set_target_kb(struct camera_data *cam, unsigned char value);
458int cpia2_set_gpio(struct camera_data *cam, unsigned char setting); 456int cpia2_set_gpio(struct camera_data *cam, unsigned char setting);
459int cpia2_set_fps(struct camera_data *cam, int framerate); 457int cpia2_set_fps(struct camera_data *cam, int framerate);
460 458
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index ee91e295c90a..17188e234770 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -66,7 +66,6 @@ static int config_sensor_410(struct camera_data *cam,
66static int config_sensor_500(struct camera_data *cam, 66static int config_sensor_500(struct camera_data *cam,
67 int reqwidth, int reqheight); 67 int reqwidth, int reqheight);
68static int set_all_properties(struct camera_data *cam); 68static int set_all_properties(struct camera_data *cam);
69static void get_color_params(struct camera_data *cam);
70static void wake_system(struct camera_data *cam); 69static void wake_system(struct camera_data *cam);
71static void set_lowlight_boost(struct camera_data *cam); 70static void set_lowlight_boost(struct camera_data *cam);
72static void reset_camera_struct(struct camera_data *cam); 71static void reset_camera_struct(struct camera_data *cam);
@@ -453,15 +452,6 @@ int cpia2_do_command(struct camera_data *cam,
453 cam->params.version.vp_device_hi = cmd.buffer.block_data[0]; 452 cam->params.version.vp_device_hi = cmd.buffer.block_data[0];
454 cam->params.version.vp_device_lo = cmd.buffer.block_data[1]; 453 cam->params.version.vp_device_lo = cmd.buffer.block_data[1];
455 break; 454 break;
456 case CPIA2_CMD_GET_VP_BRIGHTNESS:
457 cam->params.color_params.brightness = cmd.buffer.block_data[0];
458 break;
459 case CPIA2_CMD_GET_CONTRAST:
460 cam->params.color_params.contrast = cmd.buffer.block_data[0];
461 break;
462 case CPIA2_CMD_GET_VP_SATURATION:
463 cam->params.color_params.saturation = cmd.buffer.block_data[0];
464 break;
465 case CPIA2_CMD_GET_VP_GPIO_DATA: 455 case CPIA2_CMD_GET_VP_GPIO_DATA:
466 cam->params.vp_params.gpio_data = cmd.buffer.block_data[0]; 456 cam->params.vp_params.gpio_data = cmd.buffer.block_data[0];
467 break; 457 break;
@@ -617,6 +607,7 @@ int cpia2_reset_camera(struct camera_data *cam)
617{ 607{
618 u8 tmp_reg; 608 u8 tmp_reg;
619 int retval = 0; 609 int retval = 0;
610 int target_kb;
620 int i; 611 int i;
621 struct cpia2_command cmd; 612 struct cpia2_command cmd;
622 613
@@ -800,9 +791,16 @@ int cpia2_reset_camera(struct camera_data *cam)
800 } 791 }
801 cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg); 792 cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg);
802 793
803 /* Set target size (kb) on vc */ 794 /* Set target size (kb) on vc
795 This is a heuristic based on the quality parameter and the raw
796 framesize in kB divided by 16 (the compression factor when the
797 quality is 100%) */
798 target_kb = (cam->width * cam->height * 2 / 16384) *
799 cam->params.vc_params.quality / 100;
800 if (target_kb < 1)
801 target_kb = 1;
804 cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB, 802 cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB,
805 TRANSFER_WRITE, cam->params.vc_params.target_kb); 803 TRANSFER_WRITE, target_kb);
806 804
807 /* Wiggle VC Reset */ 805 /* Wiggle VC Reset */
808 /*** 806 /***
@@ -1538,23 +1536,17 @@ static int set_all_properties(struct camera_data *cam)
1538 * framerate and user_mode were already set (set_default_user_mode). 1536 * framerate and user_mode were already set (set_default_user_mode).
1539 **/ 1537 **/
1540 1538
1541 cpia2_set_color_params(cam);
1542
1543 cpia2_usb_change_streaming_alternate(cam, 1539 cpia2_usb_change_streaming_alternate(cam,
1544 cam->params.camera_state.stream_mode); 1540 cam->params.camera_state.stream_mode);
1545 1541
1546 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1547 cam->params.vp_params.user_effects);
1548
1549 cpia2_set_flicker_mode(cam,
1550 cam->params.flicker_control.flicker_mode_req);
1551
1552 cpia2_do_command(cam, 1542 cpia2_do_command(cam,
1553 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION, 1543 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
1554 TRANSFER_WRITE, cam->params.vp_params.gpio_direction); 1544 TRANSFER_WRITE, cam->params.vp_params.gpio_direction);
1555 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE, 1545 cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE,
1556 cam->params.vp_params.gpio_data); 1546 cam->params.vp_params.gpio_data);
1557 1547
1548 v4l2_ctrl_handler_setup(&cam->hdl);
1549
1558 wake_system(cam); 1550 wake_system(cam);
1559 1551
1560 set_lowlight_boost(cam); 1552 set_lowlight_boost(cam);
@@ -1569,7 +1561,6 @@ static int set_all_properties(struct camera_data *cam)
1569 *****************************************************************************/ 1561 *****************************************************************************/
1570void cpia2_save_camera_state(struct camera_data *cam) 1562void cpia2_save_camera_state(struct camera_data *cam)
1571{ 1563{
1572 get_color_params(cam);
1573 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0); 1564 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
1574 cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ, 1565 cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ,
1575 0); 1566 0);
@@ -1577,30 +1568,6 @@ void cpia2_save_camera_state(struct camera_data *cam)
1577 /* Don't get framerate or target_kb. Trust the values we already have */ 1568 /* Don't get framerate or target_kb. Trust the values we already have */
1578} 1569}
1579 1570
1580/******************************************************************************
1581 *
1582 * get_color_params
1583 *
1584 *****************************************************************************/
1585static void get_color_params(struct camera_data *cam)
1586{
1587 cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0);
1588 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0);
1589 cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0);
1590}
1591
1592/******************************************************************************
1593 *
1594 * cpia2_set_color_params
1595 *
1596 *****************************************************************************/
1597void cpia2_set_color_params(struct camera_data *cam)
1598{
1599 DBG("Setting color params\n");
1600 cpia2_set_brightness(cam, cam->params.color_params.brightness);
1601 cpia2_set_contrast(cam, cam->params.color_params.contrast);
1602 cpia2_set_saturation(cam, cam->params.color_params.saturation);
1603}
1604 1571
1605/****************************************************************************** 1572/******************************************************************************
1606 * 1573 *
@@ -1664,15 +1631,9 @@ int cpia2_set_flicker_mode(struct camera_data *cam, int mode)
1664 1631
1665 switch(mode) { 1632 switch(mode) {
1666 case NEVER_FLICKER: 1633 case NEVER_FLICKER:
1667 cam->params.flicker_control.flicker_mode_req = mode;
1668 break;
1669 case FLICKER_60: 1634 case FLICKER_60:
1670 cam->params.flicker_control.flicker_mode_req = mode;
1671 cam->params.flicker_control.mains_frequency = 60;
1672 break;
1673 case FLICKER_50: 1635 case FLICKER_50:
1674 cam->params.flicker_control.flicker_mode_req = mode; 1636 cam->params.flicker_control.flicker_mode_req = mode;
1675 cam->params.flicker_control.mains_frequency = 50;
1676 break; 1637 break;
1677 default: 1638 default:
1678 err = -EINVAL; 1639 err = -EINVAL;
@@ -1701,6 +1662,7 @@ void cpia2_set_property_flip(struct camera_data *cam, int prop_val)
1701 { 1662 {
1702 cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP; 1663 cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP;
1703 } 1664 }
1665 cam->params.vp_params.user_effects = cam_reg;
1704 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, 1666 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1705 cam_reg); 1667 cam_reg);
1706} 1668}
@@ -1725,37 +1687,13 @@ void cpia2_set_property_mirror(struct camera_data *cam, int prop_val)
1725 { 1687 {
1726 cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR; 1688 cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR;
1727 } 1689 }
1690 cam->params.vp_params.user_effects = cam_reg;
1728 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, 1691 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
1729 cam_reg); 1692 cam_reg);
1730} 1693}
1731 1694
1732/****************************************************************************** 1695/******************************************************************************
1733 * 1696 *
1734 * set_target_kb
1735 *
1736 * The new Target KB is set in cam->params.vc_params.target_kb and
1737 * activates on reset.
1738 *****************************************************************************/
1739
1740int cpia2_set_target_kb(struct camera_data *cam, unsigned char value)
1741{
1742 DBG("Requested target_kb = %d\n", value);
1743 if (value != cam->params.vc_params.target_kb) {
1744
1745 cpia2_usb_stream_pause(cam);
1746
1747 /* reset camera for new target_kb */
1748 cam->params.vc_params.target_kb = value;
1749 cpia2_reset_camera(cam);
1750
1751 cpia2_usb_stream_resume(cam);
1752 }
1753
1754 return 0;
1755}
1756
1757/******************************************************************************
1758 *
1759 * cpia2_set_gpio 1697 * cpia2_set_gpio
1760 * 1698 *
1761 *****************************************************************************/ 1699 *****************************************************************************/
@@ -1843,7 +1781,7 @@ void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
1843 if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0) 1781 if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0)
1844 value++; 1782 value++;
1845 DBG("Setting brightness to %d (0x%0x)\n", value, value); 1783 DBG("Setting brightness to %d (0x%0x)\n", value, value);
1846 cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value); 1784 cpia2_do_command(cam, CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE, value);
1847} 1785}
1848 1786
1849/****************************************************************************** 1787/******************************************************************************
@@ -1854,7 +1792,6 @@ void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
1854void cpia2_set_contrast(struct camera_data *cam, unsigned char value) 1792void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
1855{ 1793{
1856 DBG("Setting contrast to %d (0x%0x)\n", value, value); 1794 DBG("Setting contrast to %d (0x%0x)\n", value, value);
1857 cam->params.color_params.contrast = value;
1858 cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value); 1795 cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value);
1859} 1796}
1860 1797
@@ -1866,7 +1803,6 @@ void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
1866void cpia2_set_saturation(struct camera_data *cam, unsigned char value) 1803void cpia2_set_saturation(struct camera_data *cam, unsigned char value)
1867{ 1804{
1868 DBG("Setting saturation to %d (0x%0x)\n", value, value); 1805 DBG("Setting saturation to %d (0x%0x)\n", value, value);
1869 cam->params.color_params.saturation = value;
1870 cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value); 1806 cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value);
1871} 1807}
1872 1808
@@ -2168,14 +2104,10 @@ static void reset_camera_struct(struct camera_data *cam)
2168 /*** 2104 /***
2169 * The following parameter values are the defaults from the register map. 2105 * The following parameter values are the defaults from the register map.
2170 ***/ 2106 ***/
2171 cam->params.color_params.brightness = DEFAULT_BRIGHTNESS;
2172 cam->params.color_params.contrast = DEFAULT_CONTRAST;
2173 cam->params.color_params.saturation = DEFAULT_SATURATION;
2174 cam->params.vp_params.lowlight_boost = 0; 2107 cam->params.vp_params.lowlight_boost = 0;
2175 2108
2176 /* FlickerModes */ 2109 /* FlickerModes */
2177 cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER; 2110 cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER;
2178 cam->params.flicker_control.mains_frequency = 60;
2179 2111
2180 /* jpeg params */ 2112 /* jpeg params */
2181 cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT; 2113 cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
@@ -2188,7 +2120,7 @@ static void reset_camera_struct(struct camera_data *cam)
2188 cam->params.vp_params.gpio_data = 0; 2120 cam->params.vp_params.gpio_data = 0;
2189 2121
2190 /* Target kb params */ 2122 /* Target kb params */
2191 cam->params.vc_params.target_kb = DEFAULT_TARGET_KB; 2123 cam->params.vc_params.quality = 100;
2192 2124
2193 /*** 2125 /***
2194 * Set Sensor FPS as fast as possible. 2126 * Set Sensor FPS as fast as possible.
@@ -2228,7 +2160,7 @@ static void reset_camera_struct(struct camera_data *cam)
2228 * 2160 *
2229 * Initializes camera struct, does not call reset to fill in defaults. 2161 * Initializes camera struct, does not call reset to fill in defaults.
2230 *****************************************************************************/ 2162 *****************************************************************************/
2231struct camera_data *cpia2_init_camera_struct(void) 2163struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf)
2232{ 2164{
2233 struct camera_data *cam; 2165 struct camera_data *cam;
2234 2166
@@ -2239,8 +2171,13 @@ struct camera_data *cpia2_init_camera_struct(void)
2239 return NULL; 2171 return NULL;
2240 } 2172 }
2241 2173
2174 cam->v4l2_dev.release = cpia2_camera_release;
2175 if (v4l2_device_register(&intf->dev, &cam->v4l2_dev) < 0) {
2176 v4l2_err(&cam->v4l2_dev, "couldn't register v4l2_device\n");
2177 kfree(cam);
2178 return NULL;
2179 }
2242 2180
2243 cam->present = 1;
2244 mutex_init(&cam->v4l2_lock); 2181 mutex_init(&cam->v4l2_lock);
2245 init_waitqueue_head(&cam->wq_stream); 2182 init_waitqueue_head(&cam->wq_stream);
2246 2183
@@ -2373,11 +2310,6 @@ long cpia2_read(struct camera_data *cam,
2373 return -EINVAL; 2310 return -EINVAL;
2374 } 2311 }
2375 2312
2376 if (!cam->present) {
2377 LOG("%s: camera removed\n",__func__);
2378 return 0; /* EOF */
2379 }
2380
2381 if (!cam->streaming) { 2313 if (!cam->streaming) {
2382 /* Start streaming */ 2314 /* Start streaming */
2383 cpia2_usb_stream_start(cam, 2315 cpia2_usb_stream_start(cam,
@@ -2393,12 +2325,12 @@ long cpia2_read(struct camera_data *cam,
2393 if (frame->status != FRAME_READY) { 2325 if (frame->status != FRAME_READY) {
2394 mutex_unlock(&cam->v4l2_lock); 2326 mutex_unlock(&cam->v4l2_lock);
2395 wait_event_interruptible(cam->wq_stream, 2327 wait_event_interruptible(cam->wq_stream,
2396 !cam->present || 2328 !video_is_registered(&cam->vdev) ||
2397 (frame = cam->curbuff)->status == FRAME_READY); 2329 (frame = cam->curbuff)->status == FRAME_READY);
2398 mutex_lock(&cam->v4l2_lock); 2330 mutex_lock(&cam->v4l2_lock);
2399 if (signal_pending(current)) 2331 if (signal_pending(current))
2400 return -ERESTARTSYS; 2332 return -ERESTARTSYS;
2401 if (!cam->present) 2333 if (!video_is_registered(&cam->vdev))
2402 return 0; 2334 return 0;
2403 } 2335 }
2404 2336
@@ -2423,17 +2355,10 @@ long cpia2_read(struct camera_data *cam,
2423unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, 2355unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
2424 poll_table *wait) 2356 poll_table *wait)
2425{ 2357{
2426 unsigned int status=0; 2358 unsigned int status = v4l2_ctrl_poll(filp, wait);
2427 2359
2428 if (!cam) { 2360 if ((poll_requested_events(wait) & (POLLIN | POLLRDNORM)) &&
2429 ERR("%s: Internal error, camera_data not found!\n",__func__); 2361 !cam->streaming) {
2430 return POLLERR;
2431 }
2432
2433 if (!cam->present)
2434 return POLLHUP;
2435
2436 if(!cam->streaming) {
2437 /* Start streaming */ 2362 /* Start streaming */
2438 cpia2_usb_stream_start(cam, 2363 cpia2_usb_stream_start(cam,
2439 cam->params.camera_state.stream_mode); 2364 cam->params.camera_state.stream_mode);
@@ -2441,10 +2366,8 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
2441 2366
2442 poll_wait(filp, &cam->wq_stream, wait); 2367 poll_wait(filp, &cam->wq_stream, wait);
2443 2368
2444 if(!cam->present) 2369 if (cam->curbuff->status == FRAME_READY)
2445 status = POLLHUP; 2370 status |= POLLIN | POLLRDNORM;
2446 else if(cam->curbuff->status == FRAME_READY)
2447 status = POLLIN | POLLRDNORM;
2448 2371
2449 return status; 2372 return status;
2450} 2373}
@@ -2462,12 +2385,9 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
2462 unsigned long start = (unsigned long) adr; 2385 unsigned long start = (unsigned long) adr;
2463 unsigned long page, pos; 2386 unsigned long page, pos;
2464 2387
2465 if (!cam)
2466 return -ENODEV;
2467
2468 DBG("mmap offset:%ld size:%ld\n", start_offset, size); 2388 DBG("mmap offset:%ld size:%ld\n", start_offset, size);
2469 2389
2470 if (!cam->present) 2390 if (!video_is_registered(&cam->vdev))
2471 return -ENODEV; 2391 return -ENODEV;
2472 2392
2473 if (size > cam->frame_size*cam->num_frames || 2393 if (size > cam->frame_size*cam->num_frames ||
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
index 59c797c15277..95b5d6e7cdc4 100644
--- a/drivers/media/video/cpia2/cpia2_usb.c
+++ b/drivers/media/video/cpia2/cpia2_usb.c
@@ -54,6 +54,8 @@ static void cpia2_usb_complete(struct urb *urb);
54static int cpia2_usb_probe(struct usb_interface *intf, 54static int cpia2_usb_probe(struct usb_interface *intf,
55 const struct usb_device_id *id); 55 const struct usb_device_id *id);
56static void cpia2_usb_disconnect(struct usb_interface *intf); 56static void cpia2_usb_disconnect(struct usb_interface *intf);
57static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message);
58static int cpia2_usb_resume(struct usb_interface *intf);
57 59
58static void free_sbufs(struct camera_data *cam); 60static void free_sbufs(struct camera_data *cam);
59static void add_APPn(struct camera_data *cam); 61static void add_APPn(struct camera_data *cam);
@@ -74,6 +76,9 @@ static struct usb_driver cpia2_driver = {
74 .name = "cpia2", 76 .name = "cpia2",
75 .probe = cpia2_usb_probe, 77 .probe = cpia2_usb_probe,
76 .disconnect = cpia2_usb_disconnect, 78 .disconnect = cpia2_usb_disconnect,
79 .suspend = cpia2_usb_suspend,
80 .resume = cpia2_usb_resume,
81 .reset_resume = cpia2_usb_resume,
77 .id_table = cpia2_id_table 82 .id_table = cpia2_id_table
78}; 83};
79 84
@@ -218,10 +223,9 @@ static void cpia2_usb_complete(struct urb *urb)
218 return; 223 return;
219 } 224 }
220 225
221 if (!cam->streaming || !cam->present || cam->open_count == 0) { 226 if (!cam->streaming || !video_is_registered(&cam->vdev)) {
222 LOG("Will now stop the streaming: streaming = %d, " 227 LOG("Will now stop the streaming: streaming = %d, present=%d\n",
223 "present=%d, open_count=%d\n", 228 cam->streaming, video_is_registered(&cam->vdev));
224 cam->streaming, cam->present, cam->open_count);
225 return; 229 return;
226 } 230 }
227 231
@@ -392,7 +396,7 @@ static int configure_transfer_mode(struct camera_data *cam, unsigned int alt)
392 struct cpia2_command cmd; 396 struct cpia2_command cmd;
393 unsigned char reg; 397 unsigned char reg;
394 398
395 if(!cam->present) 399 if (!video_is_registered(&cam->vdev))
396 return -ENODEV; 400 return -ENODEV;
397 401
398 /*** 402 /***
@@ -752,8 +756,8 @@ int cpia2_usb_stream_pause(struct camera_data *cam)
752{ 756{
753 int ret = 0; 757 int ret = 0;
754 if(cam->streaming) { 758 if(cam->streaming) {
755 ret = set_alternate(cam, USBIF_CMDONLY);
756 free_sbufs(cam); 759 free_sbufs(cam);
760 ret = set_alternate(cam, USBIF_CMDONLY);
757 } 761 }
758 return ret; 762 return ret;
759} 763}
@@ -770,6 +774,10 @@ int cpia2_usb_stream_resume(struct camera_data *cam)
770 cam->first_image_seen = 0; 774 cam->first_image_seen = 0;
771 ret = set_alternate(cam, cam->params.camera_state.stream_mode); 775 ret = set_alternate(cam, cam->params.camera_state.stream_mode);
772 if(ret == 0) { 776 if(ret == 0) {
777 /* for some reason the user effects need to be set
778 again when starting streaming. */
779 cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
780 cam->params.vp_params.user_effects);
773 ret = submit_urbs(cam); 781 ret = submit_urbs(cam);
774 } 782 }
775 } 783 }
@@ -784,6 +792,7 @@ int cpia2_usb_stream_resume(struct camera_data *cam)
784int cpia2_usb_stream_stop(struct camera_data *cam) 792int cpia2_usb_stream_stop(struct camera_data *cam)
785{ 793{
786 int ret; 794 int ret;
795
787 ret = cpia2_usb_stream_pause(cam); 796 ret = cpia2_usb_stream_pause(cam);
788 cam->streaming = 0; 797 cam->streaming = 0;
789 configure_transfer_mode(cam, 0); 798 configure_transfer_mode(cam, 0);
@@ -812,7 +821,8 @@ static int cpia2_usb_probe(struct usb_interface *intf,
812 /* If we get to this point, we found a CPiA2 camera */ 821 /* If we get to this point, we found a CPiA2 camera */
813 LOG("CPiA2 USB camera found\n"); 822 LOG("CPiA2 USB camera found\n");
814 823
815 if((cam = cpia2_init_camera_struct()) == NULL) 824 cam = cpia2_init_camera_struct(intf);
825 if (cam == NULL)
816 return -ENOMEM; 826 return -ENOMEM;
817 827
818 cam->dev = udev; 828 cam->dev = udev;
@@ -825,16 +835,9 @@ static int cpia2_usb_probe(struct usb_interface *intf,
825 return ret; 835 return ret;
826 } 836 }
827 837
828 if ((ret = cpia2_register_camera(cam)) < 0) {
829 ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
830 kfree(cam);
831 return ret;
832 }
833
834 838
835 if((ret = cpia2_init_camera(cam)) < 0) { 839 if((ret = cpia2_init_camera(cam)) < 0) {
836 ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); 840 ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
837 cpia2_unregister_camera(cam);
838 kfree(cam); 841 kfree(cam);
839 return ret; 842 return ret;
840 } 843 }
@@ -853,6 +856,13 @@ static int cpia2_usb_probe(struct usb_interface *intf,
853 856
854 usb_set_intfdata(intf, cam); 857 usb_set_intfdata(intf, cam);
855 858
859 ret = cpia2_register_camera(cam);
860 if (ret < 0) {
861 ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
862 kfree(cam);
863 return ret;
864 }
865
856 return 0; 866 return 0;
857} 867}
858 868
@@ -865,13 +875,16 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
865{ 875{
866 struct camera_data *cam = usb_get_intfdata(intf); 876 struct camera_data *cam = usb_get_intfdata(intf);
867 usb_set_intfdata(intf, NULL); 877 usb_set_intfdata(intf, NULL);
868 cam->present = 0;
869 878
870 DBG("Stopping stream\n"); 879 DBG("Stopping stream\n");
871 cpia2_usb_stream_stop(cam); 880 cpia2_usb_stream_stop(cam);
872 881
882 mutex_lock(&cam->v4l2_lock);
873 DBG("Unregistering camera\n"); 883 DBG("Unregistering camera\n");
874 cpia2_unregister_camera(cam); 884 cpia2_unregister_camera(cam);
885 v4l2_device_disconnect(&cam->v4l2_dev);
886 mutex_unlock(&cam->v4l2_lock);
887 v4l2_device_put(&cam->v4l2_dev);
875 888
876 if(cam->buffers) { 889 if(cam->buffers) {
877 DBG("Wakeup waiting processes\n"); 890 DBG("Wakeup waiting processes\n");
@@ -884,14 +897,41 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
884 DBG("Releasing interface\n"); 897 DBG("Releasing interface\n");
885 usb_driver_release_interface(&cpia2_driver, intf); 898 usb_driver_release_interface(&cpia2_driver, intf);
886 899
887 if (cam->open_count == 0) { 900 LOG("CPiA2 camera disconnected.\n");
888 DBG("Freeing camera structure\n"); 901}
889 kfree(cam); 902
903static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message)
904{
905 struct camera_data *cam = usb_get_intfdata(intf);
906
907 mutex_lock(&cam->v4l2_lock);
908 if (cam->streaming) {
909 cpia2_usb_stream_stop(cam);
910 cam->streaming = 1;
890 } 911 }
912 mutex_unlock(&cam->v4l2_lock);
891 913
892 LOG("CPiA2 camera disconnected.\n"); 914 dev_info(&intf->dev, "going into suspend..\n");
915 return 0;
893} 916}
894 917
918/* Resume device - start device. */
919static int cpia2_usb_resume(struct usb_interface *intf)
920{
921 struct camera_data *cam = usb_get_intfdata(intf);
922
923 mutex_lock(&cam->v4l2_lock);
924 v4l2_ctrl_handler_setup(&cam->hdl);
925 if (cam->streaming) {
926 cam->streaming = 0;
927 cpia2_usb_stream_start(cam,
928 cam->params.camera_state.stream_mode);
929 }
930 mutex_unlock(&cam->v4l2_lock);
931
932 dev_info(&intf->dev, "coming out of suspend..\n");
933 return 0;
934}
895 935
896/****************************************************************************** 936/******************************************************************************
897 * 937 *
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 077eb1db80a1..55e92902a76c 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -39,15 +39,15 @@
39#include <linux/videodev2.h> 39#include <linux/videodev2.h>
40#include <linux/stringify.h> 40#include <linux/stringify.h>
41#include <media/v4l2-ioctl.h> 41#include <media/v4l2-ioctl.h>
42#include <media/v4l2-event.h>
42 43
43#include "cpia2.h" 44#include "cpia2.h"
44#include "cpia2dev.h"
45 45
46static int video_nr = -1; 46static int video_nr = -1;
47module_param(video_nr, int, 0); 47module_param(video_nr, int, 0);
48MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); 48MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
49 49
50static int buffer_size = 68*1024; 50static int buffer_size = 68 * 1024;
51module_param(buffer_size, int, 0); 51module_param(buffer_size, int, 0);
52MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)"); 52MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
53 53
@@ -62,18 +62,10 @@ MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
62 __stringify(USBIF_ISO_6) ", default " 62 __stringify(USBIF_ISO_6) ", default "
63 __stringify(DEFAULT_ALT) ")"); 63 __stringify(DEFAULT_ALT) ")");
64 64
65static int flicker_freq = 60; 65static int flicker_mode;
66module_param(flicker_freq, int, 0);
67MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or"
68 __stringify(60) ", default "
69 __stringify(60) ")");
70
71static int flicker_mode = NEVER_FLICKER;
72module_param(flicker_mode, int, 0); 66module_param(flicker_mode, int, 0);
73MODULE_PARM_DESC(flicker_mode, 67MODULE_PARM_DESC(flicker_mode, "Flicker frequency (0 (disabled), " __stringify(50) " or "
74 "Flicker supression (" __stringify(NEVER_FLICKER) "or" 68 __stringify(60) ", default 0)");
75 __stringify(ANTI_FLICKER_ON) ", default "
76 __stringify(NEVER_FLICKER) ")");
77 69
78MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); 70MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
79MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); 71MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
@@ -82,153 +74,7 @@ MODULE_LICENSE("GPL");
82MODULE_VERSION(CPIA_VERSION); 74MODULE_VERSION(CPIA_VERSION);
83 75
84#define ABOUT "V4L-Driver for Vision CPiA2 based cameras" 76#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
85 77#define CPIA2_CID_USB_ALT (V4L2_CID_USER_BASE | 0xf000)
86struct control_menu_info {
87 int value;
88 char name[32];
89};
90
91static struct control_menu_info framerate_controls[] =
92{
93 { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" },
94 { CPIA2_VP_FRAMERATE_7_5, "7.5 fps" },
95 { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" },
96 { CPIA2_VP_FRAMERATE_15, "15 fps" },
97 { CPIA2_VP_FRAMERATE_25, "25 fps" },
98 { CPIA2_VP_FRAMERATE_30, "30 fps" },
99};
100#define NUM_FRAMERATE_CONTROLS (ARRAY_SIZE(framerate_controls))
101
102static struct control_menu_info flicker_controls[] =
103{
104 { NEVER_FLICKER, "Off" },
105 { FLICKER_50, "50 Hz" },
106 { FLICKER_60, "60 Hz" },
107};
108#define NUM_FLICKER_CONTROLS (ARRAY_SIZE(flicker_controls))
109
110static struct control_menu_info lights_controls[] =
111{
112 { 0, "Off" },
113 { 64, "Top" },
114 { 128, "Bottom" },
115 { 192, "Both" },
116};
117#define NUM_LIGHTS_CONTROLS (ARRAY_SIZE(lights_controls))
118#define GPIO_LIGHTS_MASK 192
119
120static struct v4l2_queryctrl controls[] = {
121 {
122 .id = V4L2_CID_BRIGHTNESS,
123 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Brightness",
125 .minimum = 0,
126 .maximum = 255,
127 .step = 1,
128 .default_value = DEFAULT_BRIGHTNESS,
129 },
130 {
131 .id = V4L2_CID_CONTRAST,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Contrast",
134 .minimum = 0,
135 .maximum = 255,
136 .step = 1,
137 .default_value = DEFAULT_CONTRAST,
138 },
139 {
140 .id = V4L2_CID_SATURATION,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Saturation",
143 .minimum = 0,
144 .maximum = 255,
145 .step = 1,
146 .default_value = DEFAULT_SATURATION,
147 },
148 {
149 .id = V4L2_CID_HFLIP,
150 .type = V4L2_CTRL_TYPE_BOOLEAN,
151 .name = "Mirror Horizontally",
152 .minimum = 0,
153 .maximum = 1,
154 .step = 1,
155 .default_value = 0,
156 },
157 {
158 .id = V4L2_CID_VFLIP,
159 .type = V4L2_CTRL_TYPE_BOOLEAN,
160 .name = "Flip Vertically",
161 .minimum = 0,
162 .maximum = 1,
163 .step = 1,
164 .default_value = 0,
165 },
166 {
167 .id = CPIA2_CID_TARGET_KB,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Target KB",
170 .minimum = 0,
171 .maximum = 255,
172 .step = 1,
173 .default_value = DEFAULT_TARGET_KB,
174 },
175 {
176 .id = CPIA2_CID_GPIO,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "GPIO",
179 .minimum = 0,
180 .maximum = 255,
181 .step = 1,
182 .default_value = 0,
183 },
184 {
185 .id = CPIA2_CID_FLICKER_MODE,
186 .type = V4L2_CTRL_TYPE_MENU,
187 .name = "Flicker Reduction",
188 .minimum = 0,
189 .maximum = NUM_FLICKER_CONTROLS-1,
190 .step = 1,
191 .default_value = 0,
192 },
193 {
194 .id = CPIA2_CID_FRAMERATE,
195 .type = V4L2_CTRL_TYPE_MENU,
196 .name = "Framerate",
197 .minimum = 0,
198 .maximum = NUM_FRAMERATE_CONTROLS-1,
199 .step = 1,
200 .default_value = NUM_FRAMERATE_CONTROLS-1,
201 },
202 {
203 .id = CPIA2_CID_USB_ALT,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "USB Alternate",
206 .minimum = USBIF_ISO_1,
207 .maximum = USBIF_ISO_6,
208 .step = 1,
209 .default_value = DEFAULT_ALT,
210 },
211 {
212 .id = CPIA2_CID_LIGHTS,
213 .type = V4L2_CTRL_TYPE_MENU,
214 .name = "Lights",
215 .minimum = 0,
216 .maximum = NUM_LIGHTS_CONTROLS-1,
217 .step = 1,
218 .default_value = 0,
219 },
220 {
221 .id = CPIA2_CID_RESET_CAMERA,
222 .type = V4L2_CTRL_TYPE_BUTTON,
223 .name = "Reset Camera",
224 .minimum = 0,
225 .maximum = 0,
226 .step = 0,
227 .default_value = 0,
228 },
229};
230#define NUM_CONTROLS (ARRAY_SIZE(controls))
231
232 78
233/****************************************************************************** 79/******************************************************************************
234 * 80 *
@@ -238,38 +84,27 @@ static struct v4l2_queryctrl controls[] = {
238static int cpia2_open(struct file *file) 84static int cpia2_open(struct file *file)
239{ 85{
240 struct camera_data *cam = video_drvdata(file); 86 struct camera_data *cam = video_drvdata(file);
241 struct cpia2_fh *fh; 87 int retval = v4l2_fh_open(file);
242
243 if (!cam) {
244 ERR("Internal error, camera_data not found!\n");
245 return -ENODEV;
246 }
247 88
248 if (!cam->present) 89 if (retval)
249 return -ENODEV; 90 return retval;
250 91
251 if (cam->open_count == 0) { 92 if (v4l2_fh_is_singular_file(file)) {
252 if (cpia2_allocate_buffers(cam)) 93 if (cpia2_allocate_buffers(cam)) {
94 v4l2_fh_release(file);
253 return -ENOMEM; 95 return -ENOMEM;
96 }
254 97
255 /* reset the camera */ 98 /* reset the camera */
256 if (cpia2_reset_camera(cam) < 0) 99 if (cpia2_reset_camera(cam) < 0) {
100 v4l2_fh_release(file);
257 return -EIO; 101 return -EIO;
102 }
258 103
259 cam->APP_len = 0; 104 cam->APP_len = 0;
260 cam->COM_len = 0; 105 cam->COM_len = 0;
261 } 106 }
262 107
263 fh = kmalloc(sizeof(*fh), GFP_KERNEL);
264 if (!fh)
265 return -ENOMEM;
266 file->private_data = fh;
267 fh->prio = V4L2_PRIORITY_UNSET;
268 v4l2_prio_open(&cam->prio, &fh->prio);
269 fh->mmapped = 0;
270
271 ++cam->open_count;
272
273 cpia2_dbg_dump_registers(cam); 108 cpia2_dbg_dump_registers(cam);
274 return 0; 109 return 0;
275} 110}
@@ -283,37 +118,22 @@ static int cpia2_close(struct file *file)
283{ 118{
284 struct video_device *dev = video_devdata(file); 119 struct video_device *dev = video_devdata(file);
285 struct camera_data *cam = video_get_drvdata(dev); 120 struct camera_data *cam = video_get_drvdata(dev);
286 struct cpia2_fh *fh = file->private_data;
287 121
288 if (cam->present && 122 if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) {
289 (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) {
290 cpia2_usb_stream_stop(cam); 123 cpia2_usb_stream_stop(cam);
291 124
292 if (cam->open_count == 1) { 125 /* save camera state for later open */
293 /* save camera state for later open */ 126 cpia2_save_camera_state(cam);
294 cpia2_save_camera_state(cam);
295 127
296 cpia2_set_low_power(cam); 128 cpia2_set_low_power(cam);
297 cpia2_free_buffers(cam); 129 cpia2_free_buffers(cam);
298 }
299 } 130 }
300 131
301 if (fh->mmapped) 132 if (cam->stream_fh == file->private_data) {
133 cam->stream_fh = NULL;
302 cam->mmapped = 0; 134 cam->mmapped = 0;
303 v4l2_prio_close(&cam->prio, fh->prio);
304 file->private_data = NULL;
305 kfree(fh);
306
307 if (--cam->open_count == 0) {
308 cpia2_free_buffers(cam);
309 if (!cam->present) {
310 video_unregister_device(dev);
311 kfree(cam);
312 return 0;
313 }
314 } 135 }
315 136 return v4l2_fh_release(file);
316 return 0;
317} 137}
318 138
319/****************************************************************************** 139/******************************************************************************
@@ -327,16 +147,9 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
327 struct camera_data *cam = video_drvdata(file); 147 struct camera_data *cam = video_drvdata(file);
328 int noblock = file->f_flags&O_NONBLOCK; 148 int noblock = file->f_flags&O_NONBLOCK;
329 149
330 struct cpia2_fh *fh = file->private_data;
331
332 if(!cam) 150 if(!cam)
333 return -EINVAL; 151 return -EINVAL;
334 152
335 /* Priority check */
336 if(fh->prio != V4L2_PRIORITY_RECORD) {
337 return -EBUSY;
338 }
339
340 return cpia2_read(cam, buf, count, noblock); 153 return cpia2_read(cam, buf, count, noblock);
341} 154}
342 155
@@ -349,15 +162,6 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
349static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait) 162static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
350{ 163{
351 struct camera_data *cam = video_drvdata(filp); 164 struct camera_data *cam = video_drvdata(filp);
352 struct cpia2_fh *fh = filp->private_data;
353
354 if(!cam)
355 return POLLERR;
356
357 /* Priority check */
358 if(fh->prio != V4L2_PRIORITY_RECORD) {
359 return POLLERR;
360 }
361 165
362 return cpia2_poll(cam, filp, wait); 166 return cpia2_poll(cam, filp, wait);
363} 167}
@@ -384,36 +188,13 @@ static int sync(struct camera_data *cam, int frame_nr)
384 mutex_lock(&cam->v4l2_lock); 188 mutex_lock(&cam->v4l2_lock);
385 if (signal_pending(current)) 189 if (signal_pending(current))
386 return -ERESTARTSYS; 190 return -ERESTARTSYS;
387 if(!cam->present) 191 if (!video_is_registered(&cam->vdev))
388 return -ENOTTY; 192 return -ENOTTY;
389 } 193 }
390} 194}
391 195
392/****************************************************************************** 196/******************************************************************************
393 * 197 *
394 * ioctl_set_gpio
395 *
396 *****************************************************************************/
397
398static long cpia2_default(struct file *file, void *fh, bool valid_prio,
399 int cmd, void *arg)
400{
401 struct camera_data *cam = video_drvdata(file);
402 __u32 gpio_val;
403
404 if (cmd != CPIA2_CID_GPIO)
405 return -EINVAL;
406
407 gpio_val = *(__u32*) arg;
408
409 if (gpio_val &~ 0xFFU)
410 return -EINVAL;
411
412 return cpia2_set_gpio(cam, (unsigned char)gpio_val);
413}
414
415/******************************************************************************
416 *
417 * ioctl_querycap 198 * ioctl_querycap
418 * 199 *
419 * V4L2 device capabilities 200 * V4L2 device capabilities
@@ -465,9 +246,11 @@ static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *v
465 if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) 246 if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
466 memset(vc->bus_info,0, sizeof(vc->bus_info)); 247 memset(vc->bus_info,0, sizeof(vc->bus_info));
467 248
468 vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | 249 vc->device_caps = V4L2_CAP_VIDEO_CAPTURE |
469 V4L2_CAP_READWRITE | 250 V4L2_CAP_READWRITE |
470 V4L2_CAP_STREAMING; 251 V4L2_CAP_STREAMING;
252 vc->capabilities = vc->device_caps |
253 V4L2_CAP_DEVICE_CAPS;
471 254
472 return 0; 255 return 0;
473} 256}
@@ -610,22 +393,12 @@ static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh,
610 struct v4l2_format *f) 393 struct v4l2_format *f)
611{ 394{
612 struct camera_data *cam = video_drvdata(file); 395 struct camera_data *cam = video_drvdata(file);
613 struct cpia2_fh *fh = _fh;
614 int err, frame; 396 int err, frame;
615 397
616 err = v4l2_prio_check(&cam->prio, fh->prio);
617 if (err)
618 return err;
619 err = cpia2_try_fmt_vid_cap(file, _fh, f); 398 err = cpia2_try_fmt_vid_cap(file, _fh, f);
620 if(err != 0) 399 if(err != 0)
621 return err; 400 return err;
622 401
623 /* Ensure that only this process can change the format. */
624 err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
625 if(err != 0) {
626 return err;
627 }
628
629 cam->pixelformat = f->fmt.pix.pixelformat; 402 cam->pixelformat = f->fmt.pix.pixelformat;
630 403
631 /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle 404 /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
@@ -713,240 +486,126 @@ static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c)
713 return 0; 486 return 0;
714} 487}
715 488
716/****************************************************************************** 489struct framerate_info {
717 * 490 int value;
718 * ioctl_queryctrl 491 struct v4l2_fract period;
719 * 492};
720 * V4L2 query possible control variables
721 *
722 *****************************************************************************/
723 493
724static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 494static const struct framerate_info framerate_controls[] = {
495 { CPIA2_VP_FRAMERATE_6_25, { 4, 25 } },
496 { CPIA2_VP_FRAMERATE_7_5, { 2, 15 } },
497 { CPIA2_VP_FRAMERATE_12_5, { 2, 25 } },
498 { CPIA2_VP_FRAMERATE_15, { 1, 15 } },
499 { CPIA2_VP_FRAMERATE_25, { 1, 25 } },
500 { CPIA2_VP_FRAMERATE_30, { 1, 30 } },
501};
502
503static int cpia2_g_parm(struct file *file, void *fh, struct v4l2_streamparm *p)
725{ 504{
726 struct camera_data *cam = video_drvdata(file); 505 struct camera_data *cam = video_drvdata(file);
506 struct v4l2_captureparm *cap = &p->parm.capture;
727 int i; 507 int i;
728 508
729 for(i=0; i<NUM_CONTROLS; ++i) { 509 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
730 if(c->id == controls[i].id) {
731 memcpy(c, controls+i, sizeof(*c));
732 break;
733 }
734 }
735
736 if(i == NUM_CONTROLS)
737 return -EINVAL; 510 return -EINVAL;
738 511
739 /* Some devices have additional limitations */ 512 cap->capability = V4L2_CAP_TIMEPERFRAME;
740 switch(c->id) { 513 cap->readbuffers = cam->num_frames;
741 case V4L2_CID_BRIGHTNESS: 514 for (i = 0; i < ARRAY_SIZE(framerate_controls); i++)
742 /*** 515 if (cam->params.vp_params.frame_rate == framerate_controls[i].value) {
743 * Don't let the register be set to zero - bug in VP4 516 cap->timeperframe = framerate_controls[i].period;
744 * flash of full brightness 517 break;
745 ***/
746 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
747 c->minimum = 1;
748 break;
749 case V4L2_CID_VFLIP:
750 // VP5 Only
751 if(cam->params.pnp_id.device_type == DEVICE_STV_672)
752 c->flags |= V4L2_CTRL_FLAG_DISABLED;
753 break;
754 case CPIA2_CID_FRAMERATE:
755 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
756 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
757 // Maximum 15fps
758 for(i=0; i<c->maximum; ++i) {
759 if(framerate_controls[i].value ==
760 CPIA2_VP_FRAMERATE_15) {
761 c->maximum = i;
762 c->default_value = i;
763 }
764 }
765 } 518 }
766 break;
767 case CPIA2_CID_FLICKER_MODE:
768 // Flicker control only valid for 672.
769 if(cam->params.pnp_id.device_type != DEVICE_STV_672)
770 c->flags |= V4L2_CTRL_FLAG_DISABLED;
771 break;
772 case CPIA2_CID_LIGHTS:
773 // Light control only valid for the QX5 Microscope.
774 if(cam->params.pnp_id.product != 0x151)
775 c->flags |= V4L2_CTRL_FLAG_DISABLED;
776 break;
777 default:
778 break;
779 }
780
781 return 0; 519 return 0;
782} 520}
783 521
784/****************************************************************************** 522static int cpia2_s_parm(struct file *file, void *fh, struct v4l2_streamparm *p)
785 *
786 * ioctl_querymenu
787 *
788 * V4L2 query possible control variables
789 *
790 *****************************************************************************/
791
792static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m)
793{ 523{
794 struct camera_data *cam = video_drvdata(file); 524 struct camera_data *cam = video_drvdata(file);
525 struct v4l2_captureparm *cap = &p->parm.capture;
526 struct v4l2_fract tpf = cap->timeperframe;
527 int max = ARRAY_SIZE(framerate_controls) - 1;
528 int ret;
529 int i;
795 530
796 switch(m->id) { 531 ret = cpia2_g_parm(file, fh, p);
797 case CPIA2_CID_FLICKER_MODE: 532 if (ret || !tpf.denominator || !tpf.numerator)
798 if (m->index >= NUM_FLICKER_CONTROLS) 533 return ret;
799 return -EINVAL; 534
535 /* Maximum 15 fps for this model */
536 if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
537 cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
538 max -= 2;
539 for (i = 0; i <= max; i++) {
540 struct v4l2_fract f1 = tpf;
541 struct v4l2_fract f2 = framerate_controls[i].period;
542
543 f1.numerator *= f2.denominator;
544 f2.numerator *= f1.denominator;
545 if (f1.numerator >= f2.numerator)
546 break;
547 }
548 if (i > max)
549 i = max;
550 cap->timeperframe = framerate_controls[i].period;
551 return cpia2_set_fps(cam, framerate_controls[i].value);
552}
800 553
801 strcpy(m->name, flicker_controls[m->index].name); 554static const struct {
802 break; 555 u32 width;
803 case CPIA2_CID_FRAMERATE: 556 u32 height;
804 { 557} cpia2_framesizes[] = {
805 int maximum = NUM_FRAMERATE_CONTROLS - 1; 558 { 640, 480 },
806 if(cam->params.pnp_id.device_type == DEVICE_STV_672 && 559 { 352, 288 },
807 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ 560 { 320, 240 },
808 // Maximum 15fps 561 { 288, 216 },
809 int i; 562 { 256, 192 },
810 for(i=0; i<maximum; ++i) { 563 { 224, 168 },
811 if(framerate_controls[i].value == 564 { 192, 144 },
812 CPIA2_VP_FRAMERATE_15) 565 { 176, 144 },
813 maximum = i; 566};
814 }
815 }
816 if (m->index > maximum)
817 return -EINVAL;
818 567
819 strcpy(m->name, framerate_controls[m->index].name); 568static int cpia2_enum_framesizes(struct file *file, void *fh,
820 break; 569 struct v4l2_frmsizeenum *fsize)
821 } 570{
822 case CPIA2_CID_LIGHTS:
823 if (m->index >= NUM_LIGHTS_CONTROLS)
824 return -EINVAL;
825 571
826 strcpy(m->name, lights_controls[m->index].name); 572 if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG &&
827 break; 573 fsize->pixel_format != V4L2_PIX_FMT_JPEG)
828 default:
829 return -EINVAL; 574 return -EINVAL;
830 } 575 if (fsize->index >= ARRAY_SIZE(cpia2_framesizes))
576 return -EINVAL;
577 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
578 fsize->discrete.width = cpia2_framesizes[fsize->index].width;
579 fsize->discrete.height = cpia2_framesizes[fsize->index].height;
831 580
832 return 0; 581 return 0;
833} 582}
834 583
835/****************************************************************************** 584static int cpia2_enum_frameintervals(struct file *file, void *fh,
836 * 585 struct v4l2_frmivalenum *fival)
837 * ioctl_g_ctrl
838 *
839 * V4L2 get the value of a control variable
840 *
841 *****************************************************************************/
842
843static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
844{ 586{
845 struct camera_data *cam = video_drvdata(file); 587 struct camera_data *cam = video_drvdata(file);
588 int max = ARRAY_SIZE(framerate_controls) - 1;
589 int i;
846 590
847 switch(c->id) { 591 if (fival->pixel_format != V4L2_PIX_FMT_MJPEG &&
848 case V4L2_CID_BRIGHTNESS: 592 fival->pixel_format != V4L2_PIX_FMT_JPEG)
849 cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS,
850 TRANSFER_READ, 0);
851 c->value = cam->params.color_params.brightness;
852 break;
853 case V4L2_CID_CONTRAST:
854 cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST,
855 TRANSFER_READ, 0);
856 c->value = cam->params.color_params.contrast;
857 break;
858 case V4L2_CID_SATURATION:
859 cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION,
860 TRANSFER_READ, 0);
861 c->value = cam->params.color_params.saturation;
862 break;
863 case V4L2_CID_HFLIP:
864 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
865 TRANSFER_READ, 0);
866 c->value = (cam->params.vp_params.user_effects &
867 CPIA2_VP_USER_EFFECTS_MIRROR) != 0;
868 break;
869 case V4L2_CID_VFLIP:
870 cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
871 TRANSFER_READ, 0);
872 c->value = (cam->params.vp_params.user_effects &
873 CPIA2_VP_USER_EFFECTS_FLIP) != 0;
874 break;
875 case CPIA2_CID_TARGET_KB:
876 c->value = cam->params.vc_params.target_kb;
877 break;
878 case CPIA2_CID_GPIO:
879 cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
880 TRANSFER_READ, 0);
881 c->value = cam->params.vp_params.gpio_data;
882 break;
883 case CPIA2_CID_FLICKER_MODE:
884 {
885 int i, mode;
886 cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
887 TRANSFER_READ, 0);
888 if(cam->params.flicker_control.cam_register &
889 CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) {
890 mode = NEVER_FLICKER;
891 } else {
892 if(cam->params.flicker_control.cam_register &
893 CPIA2_VP_FLICKER_MODES_50HZ) {
894 mode = FLICKER_50;
895 } else {
896 mode = FLICKER_60;
897 }
898 }
899 for(i=0; i<NUM_FLICKER_CONTROLS; i++) {
900 if(flicker_controls[i].value == mode) {
901 c->value = i;
902 break;
903 }
904 }
905 if(i == NUM_FLICKER_CONTROLS)
906 return -EINVAL;
907 break;
908 }
909 case CPIA2_CID_FRAMERATE:
910 {
911 int maximum = NUM_FRAMERATE_CONTROLS - 1;
912 int i;
913 for(i=0; i<= maximum; i++) {
914 if(cam->params.vp_params.frame_rate ==
915 framerate_controls[i].value)
916 break;
917 }
918 if(i > maximum)
919 return -EINVAL;
920 c->value = i;
921 break;
922 }
923 case CPIA2_CID_USB_ALT:
924 c->value = cam->params.camera_state.stream_mode;
925 break;
926 case CPIA2_CID_LIGHTS:
927 {
928 int i;
929 cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
930 TRANSFER_READ, 0);
931 for(i=0; i<NUM_LIGHTS_CONTROLS; i++) {
932 if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) ==
933 lights_controls[i].value) {
934 break;
935 }
936 }
937 if(i == NUM_LIGHTS_CONTROLS)
938 return -EINVAL;
939 c->value = i;
940 break;
941 }
942 case CPIA2_CID_RESET_CAMERA:
943 return -EINVAL; 593 return -EINVAL;
944 default:
945 return -EINVAL;
946 }
947
948 DBG("Get control id:%d, value:%d\n", c->id, c->value);
949 594
595 /* Maximum 15 fps for this model */
596 if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
597 cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
598 max -= 2;
599 if (fival->index > max)
600 return -EINVAL;
601 for (i = 0; i < ARRAY_SIZE(cpia2_framesizes); i++)
602 if (fival->width == cpia2_framesizes[i].width &&
603 fival->height == cpia2_framesizes[i].height)
604 break;
605 if (i == ARRAY_SIZE(cpia2_framesizes))
606 return -EINVAL;
607 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
608 fival->discrete = framerate_controls[fival->index].period;
950 return 0; 609 return 0;
951} 610}
952 611
@@ -958,72 +617,54 @@ static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
958 * 617 *
959 *****************************************************************************/ 618 *****************************************************************************/
960 619
961static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) 620static int cpia2_s_ctrl(struct v4l2_ctrl *ctrl)
962{ 621{
963 struct camera_data *cam = video_drvdata(file); 622 struct camera_data *cam =
964 int i; 623 container_of(ctrl->handler, struct camera_data, hdl);
965 int retval = 0; 624 static const int flicker_table[] = {
625 NEVER_FLICKER,
626 FLICKER_50,
627 FLICKER_60,
628 };
966 629
967 DBG("Set control id:%d, value:%d\n", c->id, c->value); 630 DBG("Set control id:%d, value:%d\n", ctrl->id, ctrl->val);
968
969 /* Check that the value is in range */
970 for(i=0; i<NUM_CONTROLS; i++) {
971 if(c->id == controls[i].id) {
972 if(c->value < controls[i].minimum ||
973 c->value > controls[i].maximum) {
974 return -EINVAL;
975 }
976 break;
977 }
978 }
979 if(i == NUM_CONTROLS)
980 return -EINVAL;
981 631
982 switch(c->id) { 632 switch (ctrl->id) {
983 case V4L2_CID_BRIGHTNESS: 633 case V4L2_CID_BRIGHTNESS:
984 cpia2_set_brightness(cam, c->value); 634 cpia2_set_brightness(cam, ctrl->val);
985 break; 635 break;
986 case V4L2_CID_CONTRAST: 636 case V4L2_CID_CONTRAST:
987 cpia2_set_contrast(cam, c->value); 637 cpia2_set_contrast(cam, ctrl->val);
988 break; 638 break;
989 case V4L2_CID_SATURATION: 639 case V4L2_CID_SATURATION:
990 cpia2_set_saturation(cam, c->value); 640 cpia2_set_saturation(cam, ctrl->val);
991 break; 641 break;
992 case V4L2_CID_HFLIP: 642 case V4L2_CID_HFLIP:
993 cpia2_set_property_mirror(cam, c->value); 643 cpia2_set_property_mirror(cam, ctrl->val);
994 break; 644 break;
995 case V4L2_CID_VFLIP: 645 case V4L2_CID_VFLIP:
996 cpia2_set_property_flip(cam, c->value); 646 cpia2_set_property_flip(cam, ctrl->val);
997 break; 647 break;
998 case CPIA2_CID_TARGET_KB: 648 case V4L2_CID_POWER_LINE_FREQUENCY:
999 retval = cpia2_set_target_kb(cam, c->value); 649 return cpia2_set_flicker_mode(cam, flicker_table[ctrl->val]);
650 case V4L2_CID_ILLUMINATORS_1:
651 return cpia2_set_gpio(cam, (cam->top_light->val << 6) |
652 (cam->bottom_light->val << 7));
653 case V4L2_CID_JPEG_ACTIVE_MARKER:
654 cam->params.compression.inhibit_htables =
655 !(ctrl->val & V4L2_JPEG_ACTIVE_MARKER_DHT);
1000 break; 656 break;
1001 case CPIA2_CID_GPIO: 657 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1002 retval = cpia2_set_gpio(cam, c->value); 658 cam->params.vc_params.quality = ctrl->val;
1003 break;
1004 case CPIA2_CID_FLICKER_MODE:
1005 retval = cpia2_set_flicker_mode(cam,
1006 flicker_controls[c->value].value);
1007 break;
1008 case CPIA2_CID_FRAMERATE:
1009 retval = cpia2_set_fps(cam, framerate_controls[c->value].value);
1010 break; 659 break;
1011 case CPIA2_CID_USB_ALT: 660 case CPIA2_CID_USB_ALT:
1012 retval = cpia2_usb_change_streaming_alternate(cam, c->value); 661 cam->params.camera_state.stream_mode = ctrl->val;
1013 break;
1014 case CPIA2_CID_LIGHTS:
1015 retval = cpia2_set_gpio(cam, lights_controls[c->value].value);
1016 break;
1017 case CPIA2_CID_RESET_CAMERA:
1018 cpia2_usb_stream_pause(cam);
1019 cpia2_reset_camera(cam);
1020 cpia2_usb_stream_resume(cam);
1021 break; 662 break;
1022 default: 663 default:
1023 retval = -EINVAL; 664 return -EINVAL;
1024 } 665 }
1025 666
1026 return retval; 667 return 0;
1027} 668}
1028 669
1029/****************************************************************************** 670/******************************************************************************
@@ -1084,6 +725,8 @@ static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompres
1084 725
1085 cam->params.compression.inhibit_htables = 726 cam->params.compression.inhibit_htables =
1086 !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT); 727 !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
728 parms->jpeg_markers &= V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI |
729 V4L2_JPEG_MARKER_DHT;
1087 730
1088 if(parms->APP_len != 0) { 731 if(parms->APP_len != 0) {
1089 if(parms->APP_len > 0 && 732 if(parms->APP_len > 0 &&
@@ -1270,12 +913,12 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1270 struct framebuf *cb=cam->curbuff; 913 struct framebuf *cb=cam->curbuff;
1271 mutex_unlock(&cam->v4l2_lock); 914 mutex_unlock(&cam->v4l2_lock);
1272 wait_event_interruptible(cam->wq_stream, 915 wait_event_interruptible(cam->wq_stream,
1273 !cam->present || 916 !video_is_registered(&cam->vdev) ||
1274 (cb=cam->curbuff)->status == FRAME_READY); 917 (cb=cam->curbuff)->status == FRAME_READY);
1275 mutex_lock(&cam->v4l2_lock); 918 mutex_lock(&cam->v4l2_lock);
1276 if (signal_pending(current)) 919 if (signal_pending(current))
1277 return -ERESTARTSYS; 920 return -ERESTARTSYS;
1278 if(!cam->present) 921 if (!video_is_registered(&cam->vdev))
1279 return -ENOTTY; 922 return -ENOTTY;
1280 frame = cb->num; 923 frame = cb->num;
1281 } 924 }
@@ -1299,56 +942,39 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1299 return 0; 942 return 0;
1300} 943}
1301 944
1302static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p)
1303{
1304 struct cpia2_fh *fh = _fh;
1305
1306 *p = fh->prio;
1307 return 0;
1308}
1309
1310static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
1311{
1312 struct camera_data *cam = video_drvdata(file);
1313 struct cpia2_fh *fh = _fh;
1314
1315 if (cam->streaming && prio != fh->prio &&
1316 fh->prio == V4L2_PRIORITY_RECORD)
1317 /* Can't drop record priority while streaming */
1318 return -EBUSY;
1319
1320 if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio &&
1321 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD)
1322 /* Only one program can record at a time */
1323 return -EBUSY;
1324 return v4l2_prio_change(&cam->prio, &fh->prio, prio);
1325}
1326
1327static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) 945static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1328{ 946{
1329 struct camera_data *cam = video_drvdata(file); 947 struct camera_data *cam = video_drvdata(file);
948 int ret = -EINVAL;
1330 949
1331 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); 950 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1332 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 951 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1333 return -EINVAL; 952 return -EINVAL;
1334 953
1335 if (!cam->streaming) 954 if (!cam->streaming) {
1336 return cpia2_usb_stream_start(cam, 955 ret = cpia2_usb_stream_start(cam,
1337 cam->params.camera_state.stream_mode); 956 cam->params.camera_state.stream_mode);
1338 return -EINVAL; 957 if (!ret)
958 v4l2_ctrl_grab(cam->usb_alt, true);
959 }
960 return ret;
1339} 961}
1340 962
1341static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) 963static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1342{ 964{
1343 struct camera_data *cam = video_drvdata(file); 965 struct camera_data *cam = video_drvdata(file);
966 int ret = -EINVAL;
1344 967
1345 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); 968 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1346 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 969 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL; 970 return -EINVAL;
1348 971
1349 if (cam->streaming) 972 if (cam->streaming) {
1350 return cpia2_usb_stream_stop(cam); 973 ret = cpia2_usb_stream_stop(cam);
1351 return -EINVAL; 974 if (!ret)
975 v4l2_ctrl_grab(cam->usb_alt, false);
976 }
977 return ret;
1352} 978}
1353 979
1354/****************************************************************************** 980/******************************************************************************
@@ -1361,16 +987,10 @@ static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
1361 struct camera_data *cam = video_drvdata(file); 987 struct camera_data *cam = video_drvdata(file);
1362 int retval; 988 int retval;
1363 989
1364 /* Priority check */
1365 struct cpia2_fh *fh = file->private_data;
1366 if(fh->prio != V4L2_PRIORITY_RECORD) {
1367 return -EBUSY;
1368 }
1369
1370 retval = cpia2_remap_buffer(cam, area); 990 retval = cpia2_remap_buffer(cam, area);
1371 991
1372 if(!retval) 992 if(!retval)
1373 fh->mmapped = 1; 993 cam->stream_fh = file->private_data;
1374 return retval; 994 return retval;
1375} 995}
1376 996
@@ -1388,15 +1008,13 @@ static void reset_camera_struct_v4l(struct camera_data *cam)
1388 cam->frame_size = buffer_size; 1008 cam->frame_size = buffer_size;
1389 cam->num_frames = num_buffers; 1009 cam->num_frames = num_buffers;
1390 1010
1391 /* FlickerModes */ 1011 /* Flicker modes */
1392 cam->params.flicker_control.flicker_mode_req = flicker_mode; 1012 cam->params.flicker_control.flicker_mode_req = flicker_mode;
1393 cam->params.flicker_control.mains_frequency = flicker_freq;
1394 1013
1395 /* streamMode */ 1014 /* stream modes */
1396 cam->params.camera_state.stream_mode = alternate; 1015 cam->params.camera_state.stream_mode = alternate;
1397 1016
1398 cam->pixelformat = V4L2_PIX_FMT_JPEG; 1017 cam->pixelformat = V4L2_PIX_FMT_JPEG;
1399 v4l2_prio_init(&cam->prio);
1400} 1018}
1401 1019
1402static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { 1020static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
@@ -1408,10 +1026,6 @@ static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
1408 .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap, 1026 .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap,
1409 .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap, 1027 .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap,
1410 .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap, 1028 .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap,
1411 .vidioc_queryctrl = cpia2_queryctrl,
1412 .vidioc_querymenu = cpia2_querymenu,
1413 .vidioc_g_ctrl = cpia2_g_ctrl,
1414 .vidioc_s_ctrl = cpia2_s_ctrl,
1415 .vidioc_g_jpegcomp = cpia2_g_jpegcomp, 1029 .vidioc_g_jpegcomp = cpia2_g_jpegcomp,
1416 .vidioc_s_jpegcomp = cpia2_s_jpegcomp, 1030 .vidioc_s_jpegcomp = cpia2_s_jpegcomp,
1417 .vidioc_cropcap = cpia2_cropcap, 1031 .vidioc_cropcap = cpia2_cropcap,
@@ -1421,9 +1035,12 @@ static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
1421 .vidioc_dqbuf = cpia2_dqbuf, 1035 .vidioc_dqbuf = cpia2_dqbuf,
1422 .vidioc_streamon = cpia2_streamon, 1036 .vidioc_streamon = cpia2_streamon,
1423 .vidioc_streamoff = cpia2_streamoff, 1037 .vidioc_streamoff = cpia2_streamoff,
1424 .vidioc_g_priority = cpia2_g_priority, 1038 .vidioc_s_parm = cpia2_s_parm,
1425 .vidioc_s_priority = cpia2_s_priority, 1039 .vidioc_g_parm = cpia2_g_parm,
1426 .vidioc_default = cpia2_default, 1040 .vidioc_enum_framesizes = cpia2_enum_framesizes,
1041 .vidioc_enum_frameintervals = cpia2_enum_frameintervals,
1042 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1043 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1427}; 1044};
1428 1045
1429/*** 1046/***
@@ -1444,7 +1061,21 @@ static struct video_device cpia2_template = {
1444 .name = "CPiA2 Camera", 1061 .name = "CPiA2 Camera",
1445 .fops = &cpia2_fops, 1062 .fops = &cpia2_fops,
1446 .ioctl_ops = &cpia2_ioctl_ops, 1063 .ioctl_ops = &cpia2_ioctl_ops,
1447 .release = video_device_release, 1064 .release = video_device_release_empty,
1065};
1066
1067void cpia2_camera_release(struct v4l2_device *v4l2_dev)
1068{
1069 struct camera_data *cam =
1070 container_of(v4l2_dev, struct camera_data, v4l2_dev);
1071
1072 v4l2_ctrl_handler_free(&cam->hdl);
1073 v4l2_device_unregister(&cam->v4l2_dev);
1074 kfree(cam);
1075}
1076
1077static const struct v4l2_ctrl_ops cpia2_ctrl_ops = {
1078 .s_ctrl = cpia2_s_ctrl,
1448}; 1079};
1449 1080
1450/****************************************************************************** 1081/******************************************************************************
@@ -1454,20 +1085,78 @@ static struct video_device cpia2_template = {
1454 *****************************************************************************/ 1085 *****************************************************************************/
1455int cpia2_register_camera(struct camera_data *cam) 1086int cpia2_register_camera(struct camera_data *cam)
1456{ 1087{
1457 cam->vdev = video_device_alloc(); 1088 struct v4l2_ctrl_handler *hdl = &cam->hdl;
1458 if(!cam->vdev) 1089 struct v4l2_ctrl_config cpia2_usb_alt = {
1459 return -ENOMEM; 1090 .ops = &cpia2_ctrl_ops,
1091 .id = CPIA2_CID_USB_ALT,
1092 .name = "USB Alternate",
1093 .type = V4L2_CTRL_TYPE_INTEGER,
1094 .min = USBIF_ISO_1,
1095 .max = USBIF_ISO_6,
1096 .step = 1,
1097 };
1098 int ret;
1099
1100 v4l2_ctrl_handler_init(hdl, 12);
1101 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1102 V4L2_CID_BRIGHTNESS,
1103 cam->params.pnp_id.device_type == DEVICE_STV_672 ? 1 : 0,
1104 255, 1, DEFAULT_BRIGHTNESS);
1105 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1106 V4L2_CID_CONTRAST, 0, 255, 1, DEFAULT_CONTRAST);
1107 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1108 V4L2_CID_SATURATION, 0, 255, 1, DEFAULT_SATURATION);
1109 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1110 V4L2_CID_HFLIP, 0, 1, 1, 0);
1111 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1112 V4L2_CID_JPEG_ACTIVE_MARKER, 0,
1113 V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
1114 V4L2_JPEG_ACTIVE_MARKER_DHT);
1115 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1116 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1,
1117 100, 1, 100);
1118 cpia2_usb_alt.def = alternate;
1119 cam->usb_alt = v4l2_ctrl_new_custom(hdl, &cpia2_usb_alt, NULL);
1120 /* VP5 Only */
1121 if (cam->params.pnp_id.device_type != DEVICE_STV_672)
1122 v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1123 V4L2_CID_VFLIP, 0, 1, 1, 0);
1124 /* Flicker control only valid for 672 */
1125 if (cam->params.pnp_id.device_type == DEVICE_STV_672)
1126 v4l2_ctrl_new_std_menu(hdl, &cpia2_ctrl_ops,
1127 V4L2_CID_POWER_LINE_FREQUENCY,
1128 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
1129 /* Light control only valid for the QX5 Microscope */
1130 if (cam->params.pnp_id.product == 0x151) {
1131 cam->top_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1132 V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
1133 cam->bottom_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops,
1134 V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
1135 v4l2_ctrl_cluster(2, &cam->top_light);
1136 }
1460 1137
1461 memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template)); 1138 if (hdl->error) {
1462 video_set_drvdata(cam->vdev, cam); 1139 ret = hdl->error;
1463 cam->vdev->lock = &cam->v4l2_lock; 1140 v4l2_ctrl_handler_free(hdl);
1141 return ret;
1142 }
1143
1144 cam->vdev = cpia2_template;
1145 video_set_drvdata(&cam->vdev, cam);
1146 cam->vdev.lock = &cam->v4l2_lock;
1147 cam->vdev.ctrl_handler = hdl;
1148 cam->vdev.v4l2_dev = &cam->v4l2_dev;
1149 set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
1150 /* Locking in file operations other than ioctl should be done
1151 by the driver, not the V4L2 core.
1152 This driver needs auditing so that this flag can be removed. */
1153 set_bit(V4L2_FL_LOCK_ALL_FOPS, &cam->vdev.flags);
1464 1154
1465 reset_camera_struct_v4l(cam); 1155 reset_camera_struct_v4l(cam);
1466 1156
1467 /* register v4l device */ 1157 /* register v4l device */
1468 if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { 1158 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1469 ERR("video_register_device failed\n"); 1159 ERR("video_register_device failed\n");
1470 video_device_release(cam->vdev);
1471 return -ENODEV; 1160 return -ENODEV;
1472 } 1161 }
1473 1162
@@ -1481,13 +1170,7 @@ int cpia2_register_camera(struct camera_data *cam)
1481 *****************************************************************************/ 1170 *****************************************************************************/
1482void cpia2_unregister_camera(struct camera_data *cam) 1171void cpia2_unregister_camera(struct camera_data *cam)
1483{ 1172{
1484 if (!cam->open_count) { 1173 video_unregister_device(&cam->vdev);
1485 video_unregister_device(cam->vdev);
1486 } else {
1487 LOG("%s removed while open, deferring "
1488 "video_unregister_device\n",
1489 video_device_node_name(cam->vdev));
1490 }
1491} 1174}
1492 1175
1493/****************************************************************************** 1176/******************************************************************************
@@ -1524,23 +1207,12 @@ static void __init check_parameters(void)
1524 LOG("alternate specified is invalid, using %d\n", alternate); 1207 LOG("alternate specified is invalid, using %d\n", alternate);
1525 } 1208 }
1526 1209
1527 if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) { 1210 if (flicker_mode != 0 && flicker_mode != FLICKER_50 && flicker_mode != FLICKER_60) {
1528 flicker_mode = NEVER_FLICKER; 1211 flicker_mode = 0;
1529 LOG("Flicker mode specified is invalid, using %d\n", 1212 LOG("Flicker mode specified is invalid, using %d\n",
1530 flicker_mode); 1213 flicker_mode);
1531 } 1214 }
1532 1215
1533 if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) {
1534 flicker_freq = FLICKER_60;
1535 LOG("Flicker mode specified is invalid, using %d\n",
1536 flicker_freq);
1537 }
1538
1539 if(video_nr < -1 || video_nr > 64) {
1540 video_nr = -1;
1541 LOG("invalid video_nr specified, must be -1 to 64\n");
1542 }
1543
1544 DBG("Using %d buffers, each %d bytes, alternate=%d\n", 1216 DBG("Using %d buffers, each %d bytes, alternate=%d\n",
1545 num_buffers, buffer_size, alternate); 1217 num_buffers, buffer_size, alternate);
1546} 1218}
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h
deleted file mode 100644
index f66691fe5a35..000000000000
--- a/drivers/media/video/cpia2/cpia2dev.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/****************************************************************************
2 *
3 * Filename: cpia2dev.h
4 *
5 * Copyright 2001, STMicrolectronics, Inc.
6 *
7 * Contact: steve.miller@st.com
8 *
9 * Description:
10 * This file provides definitions for applications wanting to use the
11 * cpia2 driver beyond the generic v4l capabilities.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 ****************************************************************************/
28
29#ifndef CPIA2_DEV_HEADER
30#define CPIA2_DEV_HEADER
31
32#include <linux/videodev2.h>
33
34/***
35 * The following defines are ioctl numbers based on video4linux private ioctls,
36 * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int
37 * args
38 */
39#define CPIA2_IOC_SET_GPIO _IOW('v', BASE_VIDIOC_PRIVATE + 17, __u32)
40
41/* V4L2 driver specific controls */
42#define CPIA2_CID_TARGET_KB (V4L2_CID_PRIVATE_BASE+0)
43#define CPIA2_CID_GPIO (V4L2_CID_PRIVATE_BASE+1)
44#define CPIA2_CID_FLICKER_MODE (V4L2_CID_PRIVATE_BASE+2)
45#define CPIA2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE+3)
46#define CPIA2_CID_USB_ALT (V4L2_CID_PRIVATE_BASE+4)
47#define CPIA2_CID_LIGHTS (V4L2_CID_PRIVATE_BASE+5)
48#define CPIA2_CID_RESET_CAMERA (V4L2_CID_PRIVATE_BASE+6)
49
50#endif
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
index e118361c2e7b..6d2a98246b6d 100644
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -285,6 +285,7 @@ static void __exit cx18_alsa_exit(void)
285 285
286 drv = driver_find("cx18", &pci_bus_type); 286 drv = driver_find("cx18", &pci_bus_type);
287 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); 287 ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
288 (void)ret; /* suppress compiler warning */
288 289
289 cx18_ext_init = NULL; 290 cx18_ext_init = NULL;
290 printk(KERN_INFO "cx18-alsa: module unload complete\n"); 291 printk(KERN_INFO "cx18-alsa: module unload complete\n");
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
index 82d195be9197..7a5b84a86bb3 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -190,7 +190,7 @@ static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream)
190 ret = cx18_start_v4l2_encode_stream(s); 190 ret = cx18_start_v4l2_encode_stream(s);
191 snd_cx18_unlock(cxsc); 191 snd_cx18_unlock(cxsc);
192 192
193 return 0; 193 return ret;
194} 194}
195 195
196static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) 196static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
@@ -199,12 +199,11 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
199 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; 199 struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
200 struct cx18 *cx = to_cx18(v4l2_dev); 200 struct cx18 *cx = to_cx18(v4l2_dev);
201 struct cx18_stream *s; 201 struct cx18_stream *s;
202 int ret;
203 202
204 /* Instruct the cx18 to stop sending packets */ 203 /* Instruct the cx18 to stop sending packets */
205 snd_cx18_lock(cxsc); 204 snd_cx18_lock(cxsc);
206 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; 205 s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
207 ret = cx18_stop_v4l2_encode_stream(s, 0); 206 cx18_stop_v4l2_encode_stream(s, 0);
208 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 207 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
209 208
210 cx18_release_stream(s); 209 cx18_release_stream(s);
@@ -252,13 +251,10 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
252static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream, 251static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
253 struct snd_pcm_hw_params *params) 252 struct snd_pcm_hw_params *params)
254{ 253{
255 int ret;
256
257 dprintk("%s called\n", __func__); 254 dprintk("%s called\n", __func__);
258 255
259 ret = snd_pcm_alloc_vmalloc_buffer(substream, 256 return snd_pcm_alloc_vmalloc_buffer(substream,
260 params_buffer_bytes(params)); 257 params_buffer_bytes(params));
261 return 0;
262} 258}
263 259
264static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream) 260static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index be49f68ddf37..35fde4e931f5 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -1137,7 +1137,7 @@ static long cx18_default(struct file *file, void *fh, bool valid_prio,
1137 } 1137 }
1138 1138
1139 default: 1139 default:
1140 return -EINVAL; 1140 return -ENOTTY;
1141 } 1141 }
1142 return 0; 1142 return 0;
1143} 1143}
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 0c7796e76ac0..ed8118390b02 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -595,9 +595,8 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
595static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) 595static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
596{ 596{
597 const struct cx18_api_info *info = find_api_info(cmd); 597 const struct cx18_api_info *info = find_api_info(cmd);
598 u32 state, irq, req, ack, err; 598 u32 irq, req, ack, err;
599 struct cx18_mailbox __iomem *mb; 599 struct cx18_mailbox __iomem *mb;
600 u32 __iomem *xpu_state;
601 wait_queue_head_t *waitq; 600 wait_queue_head_t *waitq;
602 struct mutex *mb_lock; 601 struct mutex *mb_lock;
603 unsigned long int t0, timeout, ret; 602 unsigned long int t0, timeout, ret;
@@ -628,14 +627,12 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
628 mb_lock = &cx->epu2apu_mb_lock; 627 mb_lock = &cx->epu2apu_mb_lock;
629 irq = IRQ_EPU_TO_APU; 628 irq = IRQ_EPU_TO_APU;
630 mb = &cx->scb->epu2apu_mb; 629 mb = &cx->scb->epu2apu_mb;
631 xpu_state = &cx->scb->apu_state;
632 break; 630 break;
633 case CPU: 631 case CPU:
634 waitq = &cx->mb_cpu_waitq; 632 waitq = &cx->mb_cpu_waitq;
635 mb_lock = &cx->epu2cpu_mb_lock; 633 mb_lock = &cx->epu2cpu_mb_lock;
636 irq = IRQ_EPU_TO_CPU; 634 irq = IRQ_EPU_TO_CPU;
637 mb = &cx->scb->epu2cpu_mb; 635 mb = &cx->scb->epu2cpu_mb;
638 xpu_state = &cx->scb->cpu_state;
639 break; 636 break;
640 default: 637 default:
641 CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu); 638 CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu);
@@ -653,7 +650,6 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
653 * by a signal, we may get here and find a busy mailbox. After waiting, 650 * by a signal, we may get here and find a busy mailbox. After waiting,
654 * mark it "not busy" from our end, if the XPU hasn't ack'ed it still. 651 * mark it "not busy" from our end, if the XPU hasn't ack'ed it still.
655 */ 652 */
656 state = cx18_readl(cx, xpu_state);
657 req = cx18_readl(cx, &mb->request); 653 req = cx18_readl(cx, &mb->request);
658 timeout = msecs_to_jiffies(10); 654 timeout = msecs_to_jiffies(10);
659 ret = wait_event_timeout(*waitq, 655 ret = wait_event_timeout(*waitq,
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 638cca156b58..4185bcb80ca3 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -980,7 +980,6 @@ void cx18_stop_all_captures(struct cx18 *cx)
980int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) 980int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
981{ 981{
982 struct cx18 *cx = s->cx; 982 struct cx18 *cx = s->cx;
983 unsigned long then;
984 983
985 if (!cx18_stream_enabled(s)) 984 if (!cx18_stream_enabled(s))
986 return -EINVAL; 985 return -EINVAL;
@@ -999,8 +998,6 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
999 else 998 else
1000 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); 999 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
1001 1000
1002 then = jiffies;
1003
1004 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) { 1001 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
1005 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); 1002 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
1006 } 1003 }
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index d4327dab5a36..ce2f62238a19 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -1095,7 +1095,7 @@ static int cx231xx_initialize_codec(struct cx231xx *dev)
1095{ 1095{
1096 int version; 1096 int version;
1097 int retval; 1097 int retval;
1098 u32 i, data[7]; 1098 u32 i;
1099 u32 val = 0; 1099 u32 val = 0;
1100 1100
1101 dprintk(1, "%s()\n", __func__); 1101 dprintk(1, "%s()\n", __func__);
@@ -1154,6 +1154,11 @@ static int cx231xx_initialize_codec(struct cx231xx *dev)
1154 CX231xx_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1154 CX231xx_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1155 0, 0); 1155 0, 0);
1156*/ 1156*/
1157
1158#if 0
1159 /* TODO */
1160 u32 data[7];
1161
1157 /* Setup to capture VBI */ 1162 /* Setup to capture VBI */
1158 data[0] = 0x0001BD00; 1163 data[0] = 0x0001BD00;
1159 data[1] = 1; /* frames per interrupt */ 1164 data[1] = 1; /* frames per interrupt */
@@ -1162,7 +1167,7 @@ static int cx231xx_initialize_codec(struct cx231xx *dev)
1162 data[4] = 0x206080C0; /* stop codes */ 1167 data[4] = 0x206080C0; /* stop codes */
1163 data[5] = 6; /* lines */ 1168 data[5] = 6; /* lines */
1164 data[6] = 64; /* BPL */ 1169 data[6] = 64; /* BPL */
1165/* 1170
1166 cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1], 1171 cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1],
1167 data[2], data[3], data[4], data[5], data[6]); 1172 data[2], data[3], data[4], data[5], data[6]);
1168 1173
@@ -1175,7 +1180,7 @@ static int cx231xx_initialize_codec(struct cx231xx *dev)
1175 cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, 1180 cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0,
1176 i | 0x80000000, valid, 0, 0, 0); 1181 i | 0x80000000, valid, 0, 0, 0);
1177 } 1182 }
1178*/ 1183#endif
1179/* cx231xx_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX231xx_UNMUTE); 1184/* cx231xx_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX231xx_UNMUTE);
1180 msleep(60); 1185 msleep(60);
1181*/ 1186*/
@@ -1792,17 +1797,16 @@ static int vidioc_streamon(struct file *file, void *priv,
1792 struct cx231xx_fh *fh = file->private_data; 1797 struct cx231xx_fh *fh = file->private_data;
1793 1798
1794 struct cx231xx *dev = fh->dev; 1799 struct cx231xx *dev = fh->dev;
1795 int rc = 0;
1796 dprintk(3, "enter vidioc_streamon()\n"); 1800 dprintk(3, "enter vidioc_streamon()\n");
1797 cx231xx_set_alt_setting(dev, INDEX_TS1, 0); 1801 cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
1798 rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); 1802 cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
1799 if (dev->USE_ISO) 1803 if (dev->USE_ISO)
1800 rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, 1804 cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
1801 CX231XX_NUM_BUFS, 1805 CX231XX_NUM_BUFS,
1802 dev->video_mode.max_pkt_size, 1806 dev->video_mode.max_pkt_size,
1803 cx231xx_isoc_copy); 1807 cx231xx_isoc_copy);
1804 else { 1808 else {
1805 rc = cx231xx_init_bulk(dev, 320, 1809 cx231xx_init_bulk(dev, 320,
1806 5, 1810 5,
1807 dev->ts1_mode.max_pkt_size, 1811 dev->ts1_mode.max_pkt_size,
1808 cx231xx_bulk_copy); 1812 cx231xx_bulk_copy);
diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c
index a2c2b7d343ec..068f78dc5d13 100644
--- a/drivers/media/video/cx231xx/cx231xx-audio.c
+++ b/drivers/media/video/cx231xx/cx231xx-audio.c
@@ -523,21 +523,24 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
523static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, 523static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
524 struct snd_pcm_hw_params *hw_params) 524 struct snd_pcm_hw_params *hw_params)
525{ 525{
526 unsigned int channels, rate, format;
527 int ret; 526 int ret;
528 527
529 dprintk("Setting capture parameters\n"); 528 dprintk("Setting capture parameters\n");
530 529
531 ret = snd_pcm_alloc_vmalloc_buffer(substream, 530 ret = snd_pcm_alloc_vmalloc_buffer(substream,
532 params_buffer_bytes(hw_params)); 531 params_buffer_bytes(hw_params));
532#if 0
533 /* TODO: set up cx231xx audio chip to deliver the correct audio format,
534 current default is 48000hz multiplexed => 96000hz mono
535 which shouldn't matter since analogue TV only supports mono */
536 unsigned int channels, rate, format;
537
533 format = params_format(hw_params); 538 format = params_format(hw_params);
534 rate = params_rate(hw_params); 539 rate = params_rate(hw_params);
535 channels = params_channels(hw_params); 540 channels = params_channels(hw_params);
541#endif
536 542
537 /* TODO: set up cx231xx audio chip to deliver the correct audio format, 543 return ret;
538 current default is 48000hz multiplexed => 96000hz mono
539 which shouldn't matter since analogue TV only supports mono */
540 return 0;
541} 544}
542 545
543static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) 546static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream)
@@ -586,7 +589,7 @@ static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
586 int cmd) 589 int cmd)
587{ 590{
588 struct cx231xx *dev = snd_pcm_substream_chip(substream); 591 struct cx231xx *dev = snd_pcm_substream_chip(substream);
589 int retval; 592 int retval = 0;
590 593
591 if (dev->state & DEV_DISCONNECTED) 594 if (dev->state & DEV_DISCONNECTED)
592 return -ENODEV; 595 return -ENODEV;
@@ -601,12 +604,13 @@ static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
601 break; 604 break;
602 default: 605 default:
603 retval = -EINVAL; 606 retval = -EINVAL;
607 break;
604 } 608 }
605 spin_unlock(&dev->adev.slock); 609 spin_unlock(&dev->adev.slock);
606 610
607 schedule_work(&dev->wq_trigger); 611 schedule_work(&dev->wq_trigger);
608 612
609 return 0; 613 return retval;
610} 614}
611 615
612static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream 616static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 53ff26e7abf7..b085a3c6dc04 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -934,33 +934,29 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
934void cx231xx_enable656(struct cx231xx *dev) 934void cx231xx_enable656(struct cx231xx *dev)
935{ 935{
936 u8 temp = 0; 936 u8 temp = 0;
937 int status;
938 /*enable TS1 data[0:7] as output to export 656*/ 937 /*enable TS1 data[0:7] as output to export 656*/
939 938
940 status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0xFF); 939 vid_blk_write_byte(dev, TS1_PIN_CTL0, 0xFF);
941 940
942 /*enable TS1 clock as output to export 656*/ 941 /*enable TS1 clock as output to export 656*/
943 942
944 status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp); 943 vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
945 temp = temp|0x04; 944 temp = temp|0x04;
946 945
947 status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp); 946 vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
948
949} 947}
950EXPORT_SYMBOL_GPL(cx231xx_enable656); 948EXPORT_SYMBOL_GPL(cx231xx_enable656);
951 949
952void cx231xx_disable656(struct cx231xx *dev) 950void cx231xx_disable656(struct cx231xx *dev)
953{ 951{
954 u8 temp = 0; 952 u8 temp = 0;
955 int status;
956
957 953
958 status = vid_blk_write_byte(dev, TS1_PIN_CTL0, 0x00); 954 vid_blk_write_byte(dev, TS1_PIN_CTL0, 0x00);
959 955
960 status = vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp); 956 vid_blk_read_byte(dev, TS1_PIN_CTL1, &temp);
961 temp = temp&0xFB; 957 temp = temp&0xFB;
962 958
963 status = vid_blk_write_byte(dev, TS1_PIN_CTL1, temp); 959 vid_blk_write_byte(dev, TS1_PIN_CTL1, temp);
964} 960}
965EXPORT_SYMBOL_GPL(cx231xx_disable656); 961EXPORT_SYMBOL_GPL(cx231xx_disable656);
966 962
@@ -1320,117 +1316,115 @@ void update_HH_register_after_set_DIF(struct cx231xx *dev)
1320 1316
1321void cx231xx_dump_HH_reg(struct cx231xx *dev) 1317void cx231xx_dump_HH_reg(struct cx231xx *dev)
1322{ 1318{
1323 u8 status = 0;
1324 u32 value = 0; 1319 u32 value = 0;
1325 u16 i = 0; 1320 u16 i = 0;
1326 1321
1327 value = 0x45005390; 1322 value = 0x45005390;
1328 status = vid_blk_write_word(dev, 0x104, value); 1323 vid_blk_write_word(dev, 0x104, value);
1329 1324
1330 for (i = 0x100; i < 0x140; i++) { 1325 for (i = 0x100; i < 0x140; i++) {
1331 status = vid_blk_read_word(dev, i, &value); 1326 vid_blk_read_word(dev, i, &value);
1332 cx231xx_info("reg0x%x=0x%x\n", i, value); 1327 cx231xx_info("reg0x%x=0x%x\n", i, value);
1333 i = i+3; 1328 i = i+3;
1334 } 1329 }
1335 1330
1336 for (i = 0x300; i < 0x400; i++) { 1331 for (i = 0x300; i < 0x400; i++) {
1337 status = vid_blk_read_word(dev, i, &value); 1332 vid_blk_read_word(dev, i, &value);
1338 cx231xx_info("reg0x%x=0x%x\n", i, value); 1333 cx231xx_info("reg0x%x=0x%x\n", i, value);
1339 i = i+3; 1334 i = i+3;
1340 } 1335 }
1341 1336
1342 for (i = 0x400; i < 0x440; i++) { 1337 for (i = 0x400; i < 0x440; i++) {
1343 status = vid_blk_read_word(dev, i, &value); 1338 vid_blk_read_word(dev, i, &value);
1344 cx231xx_info("reg0x%x=0x%x\n", i, value); 1339 cx231xx_info("reg0x%x=0x%x\n", i, value);
1345 i = i+3; 1340 i = i+3;
1346 } 1341 }
1347 1342
1348 status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); 1343 vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
1349 cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); 1344 cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
1350 vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); 1345 vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390);
1351 status = vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); 1346 vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value);
1352 cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); 1347 cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value);
1353} 1348}
1354 1349
1355void cx231xx_dump_SC_reg(struct cx231xx *dev) 1350void cx231xx_dump_SC_reg(struct cx231xx *dev)
1356{ 1351{
1357 u8 value[4] = { 0, 0, 0, 0 }; 1352 u8 value[4] = { 0, 0, 0, 0 };
1358 int status = 0;
1359 cx231xx_info("cx231xx_dump_SC_reg!\n"); 1353 cx231xx_info("cx231xx_dump_SC_reg!\n");
1360 1354
1361 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, 1355 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
1362 value, 4); 1356 value, 4);
1363 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], 1357 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0],
1364 value[1], value[2], value[3]); 1358 value[1], value[2], value[3]);
1365 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, 1359 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG,
1366 value, 4); 1360 value, 4);
1367 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], 1361 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0],
1368 value[1], value[2], value[3]); 1362 value[1], value[2], value[3]);
1369 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, 1363 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG,
1370 value, 4); 1364 value, 4);
1371 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], 1365 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0],
1372 value[1], value[2], value[3]); 1366 value[1], value[2], value[3]);
1373 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, 1367 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG,
1374 value, 4); 1368 value, 4);
1375 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], 1369 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0],
1376 value[1], value[2], value[3]); 1370 value[1], value[2], value[3]);
1377 1371
1378 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, 1372 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG,
1379 value, 4); 1373 value, 4);
1380 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], 1374 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0],
1381 value[1], value[2], value[3]); 1375 value[1], value[2], value[3]);
1382 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, 1376 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG,
1383 value, 4); 1377 value, 4);
1384 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], 1378 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0],
1385 value[1], value[2], value[3]); 1379 value[1], value[2], value[3]);
1386 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, 1380 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
1387 value, 4); 1381 value, 4);
1388 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], 1382 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0],
1389 value[1], value[2], value[3]); 1383 value[1], value[2], value[3]);
1390 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, 1384 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1,
1391 value, 4); 1385 value, 4);
1392 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], 1386 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0],
1393 value[1], value[2], value[3]); 1387 value[1], value[2], value[3]);
1394 1388
1395 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, 1389 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2,
1396 value, 4); 1390 value, 4);
1397 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], 1391 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0],
1398 value[1], value[2], value[3]); 1392 value[1], value[2], value[3]);
1399 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, 1393 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3,
1400 value, 4); 1394 value, 4);
1401 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], 1395 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0],
1402 value[1], value[2], value[3]); 1396 value[1], value[2], value[3]);
1403 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, 1397 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0,
1404 value, 4); 1398 value, 4);
1405 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], 1399 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0],
1406 value[1], value[2], value[3]); 1400 value[1], value[2], value[3]);
1407 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, 1401 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1,
1408 value, 4); 1402 value, 4);
1409 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], 1403 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0],
1410 value[1], value[2], value[3]); 1404 value[1], value[2], value[3]);
1411 1405
1412 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, 1406 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2,
1413 value, 4); 1407 value, 4);
1414 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], 1408 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0],
1415 value[1], value[2], value[3]); 1409 value[1], value[2], value[3]);
1416 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, 1410 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN,
1417 value, 4); 1411 value, 4);
1418 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], 1412 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0],
1419 value[1], value[2], value[3]); 1413 value[1], value[2], value[3]);
1420 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, 1414 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG,
1421 value, 4); 1415 value, 4);
1422 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], 1416 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0],
1423 value[1], value[2], value[3]); 1417 value[1], value[2], value[3]);
1424 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, 1418 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1,
1425 value, 4); 1419 value, 4);
1426 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], 1420 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0],
1427 value[1], value[2], value[3]); 1421 value[1], value[2], value[3]);
1428 1422
1429 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, 1423 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2,
1430 value, 4); 1424 value, 4);
1431 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], 1425 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0],
1432 value[1], value[2], value[3]); 1426 value[1], value[2], value[3]);
1433 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, 1427 cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
1434 value, 4); 1428 value, 4);
1435 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], 1429 cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0],
1436 value[1], value[2], value[3]); 1430 value[1], value[2], value[3]);
@@ -1441,18 +1435,15 @@ void cx231xx_dump_SC_reg(struct cx231xx *dev)
1441void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev) 1435void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev)
1442 1436
1443{ 1437{
1444 u8 status = 0;
1445 u8 value = 0; 1438 u8 value = 0;
1446 1439
1447 1440 afe_read_byte(dev, ADC_STATUS2_CH3, &value);
1448
1449 status = afe_read_byte(dev, ADC_STATUS2_CH3, &value);
1450 value = (value & 0xFE)|0x01; 1441 value = (value & 0xFE)|0x01;
1451 status = afe_write_byte(dev, ADC_STATUS2_CH3, value); 1442 afe_write_byte(dev, ADC_STATUS2_CH3, value);
1452 1443
1453 status = afe_read_byte(dev, ADC_STATUS2_CH3, &value); 1444 afe_read_byte(dev, ADC_STATUS2_CH3, &value);
1454 value = (value & 0xFE)|0x00; 1445 value = (value & 0xFE)|0x00;
1455 status = afe_write_byte(dev, ADC_STATUS2_CH3, value); 1446 afe_write_byte(dev, ADC_STATUS2_CH3, value);
1456 1447
1457 1448
1458/* 1449/*
@@ -1464,44 +1455,43 @@ void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev)
1464 for low-if agc defect 1455 for low-if agc defect
1465*/ 1456*/
1466 1457
1467 status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value); 1458 afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3, &value);
1468 value = (value & 0xFC)|0x00; 1459 value = (value & 0xFC)|0x00;
1469 status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, value); 1460 afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, value);
1470 1461
1471 status = afe_read_byte(dev, ADC_INPUT_CH3, &value); 1462 afe_read_byte(dev, ADC_INPUT_CH3, &value);
1472 value = (value & 0xF9)|0x02; 1463 value = (value & 0xF9)|0x02;
1473 status = afe_write_byte(dev, ADC_INPUT_CH3, value); 1464 afe_write_byte(dev, ADC_INPUT_CH3, value);
1474 1465
1475 status = afe_read_byte(dev, ADC_FB_FRCRST_CH3, &value); 1466 afe_read_byte(dev, ADC_FB_FRCRST_CH3, &value);
1476 value = (value & 0xFB)|0x04; 1467 value = (value & 0xFB)|0x04;
1477 status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, value); 1468 afe_write_byte(dev, ADC_FB_FRCRST_CH3, value);
1478 1469
1479 status = afe_read_byte(dev, ADC_DCSERVO_DEM_CH3, &value); 1470 afe_read_byte(dev, ADC_DCSERVO_DEM_CH3, &value);
1480 value = (value & 0xFC)|0x03; 1471 value = (value & 0xFC)|0x03;
1481 status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, value); 1472 afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, value);
1482 1473
1483 status = afe_read_byte(dev, ADC_CTRL_DAC1_CH3, &value); 1474 afe_read_byte(dev, ADC_CTRL_DAC1_CH3, &value);
1484 value = (value & 0xFB)|0x04; 1475 value = (value & 0xFB)|0x04;
1485 status = afe_write_byte(dev, ADC_CTRL_DAC1_CH3, value); 1476 afe_write_byte(dev, ADC_CTRL_DAC1_CH3, value);
1486 1477
1487 status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value); 1478 afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
1488 value = (value & 0xF8)|0x06; 1479 value = (value & 0xF8)|0x06;
1489 status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value); 1480 afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);
1490 1481
1491 status = afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value); 1482 afe_read_byte(dev, ADC_CTRL_DAC23_CH3, &value);
1492 value = (value & 0x8F)|0x40; 1483 value = (value & 0x8F)|0x40;
1493 status = afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value); 1484 afe_write_byte(dev, ADC_CTRL_DAC23_CH3, value);
1494 1485
1495 status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH3, &value); 1486 afe_read_byte(dev, ADC_PWRDN_CLAMP_CH3, &value);
1496 value = (value & 0xDF)|0x20; 1487 value = (value & 0xDF)|0x20;
1497 status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, value); 1488 afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, value);
1498} 1489}
1499 1490
1500void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, 1491void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq,
1501 u8 spectral_invert, u32 mode) 1492 u8 spectral_invert, u32 mode)
1502{ 1493{
1503 u32 colibri_carrier_offset = 0; 1494 u32 colibri_carrier_offset = 0;
1504 u8 status = 0;
1505 u32 func_mode = 0x01; /* Device has a DIF if this function is called */ 1495 u32 func_mode = 0x01; /* Device has a DIF if this function is called */
1506 u32 standard = 0; 1496 u32 standard = 0;
1507 u8 value[4] = { 0, 0, 0, 0 }; 1497 u8 value[4] = { 0, 0, 0, 0 };
@@ -1511,15 +1501,15 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq,
1511 value[1] = (u8) 0x6F; 1501 value[1] = (u8) 0x6F;
1512 value[2] = (u8) 0x6F; 1502 value[2] = (u8) 0x6F;
1513 value[3] = (u8) 0x6F; 1503 value[3] = (u8) 0x6F;
1514 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, 1504 cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1515 PWR_CTL_EN, value, 4); 1505 PWR_CTL_EN, value, 4);
1516 1506
1517 /*Set colibri for low IF*/ 1507 /*Set colibri for low IF*/
1518 status = cx231xx_afe_set_mode(dev, AFE_MODE_LOW_IF); 1508 cx231xx_afe_set_mode(dev, AFE_MODE_LOW_IF);
1519 1509
1520 /* Set C2HH for low IF operation.*/ 1510 /* Set C2HH for low IF operation.*/
1521 standard = dev->norm; 1511 standard = dev->norm;
1522 status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode, 1512 cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
1523 func_mode, standard); 1513 func_mode, standard);
1524 1514
1525 /* Get colibri offsets.*/ 1515 /* Get colibri offsets.*/
@@ -1556,7 +1546,6 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
1556 u8 spectral_invert, u32 mode) 1546 u8 spectral_invert, u32 mode)
1557{ 1547{
1558 unsigned long pll_freq_word; 1548 unsigned long pll_freq_word;
1559 int status = 0;
1560 u32 dif_misc_ctrl_value = 0; 1549 u32 dif_misc_ctrl_value = 0;
1561 u64 pll_freq_u64 = 0; 1550 u64 pll_freq_u64 = 0;
1562 u32 i = 0; 1551 u32 i = 0;
@@ -1567,7 +1556,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
1567 1556
1568 if (mode == TUNER_MODE_FM_RADIO) { 1557 if (mode == TUNER_MODE_FM_RADIO) {
1569 pll_freq_word = 0x905A1CAC; 1558 pll_freq_word = 0x905A1CAC;
1570 status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word); 1559 vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
1571 1560
1572 } else /*KSPROPERTY_TUNER_MODE_TV*/{ 1561 } else /*KSPROPERTY_TUNER_MODE_TV*/{
1573 /* Calculate the PLL frequency word based on the adjusted if_freq*/ 1562 /* Calculate the PLL frequency word based on the adjusted if_freq*/
@@ -1576,23 +1565,23 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
1576 do_div(pll_freq_u64, 50000000); 1565 do_div(pll_freq_u64, 50000000);
1577 pll_freq_word = (u32)pll_freq_u64; 1566 pll_freq_word = (u32)pll_freq_u64;
1578 /*pll_freq_word = 0x3463497;*/ 1567 /*pll_freq_word = 0x3463497;*/
1579 status = vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word); 1568 vid_blk_write_word(dev, DIF_PLL_FREQ_WORD, pll_freq_word);
1580 1569
1581 if (spectral_invert) { 1570 if (spectral_invert) {
1582 if_freq -= 400000; 1571 if_freq -= 400000;
1583 /* Enable Spectral Invert*/ 1572 /* Enable Spectral Invert*/
1584 status = vid_blk_read_word(dev, DIF_MISC_CTRL, 1573 vid_blk_read_word(dev, DIF_MISC_CTRL,
1585 &dif_misc_ctrl_value); 1574 &dif_misc_ctrl_value);
1586 dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000; 1575 dif_misc_ctrl_value = dif_misc_ctrl_value | 0x00200000;
1587 status = vid_blk_write_word(dev, DIF_MISC_CTRL, 1576 vid_blk_write_word(dev, DIF_MISC_CTRL,
1588 dif_misc_ctrl_value); 1577 dif_misc_ctrl_value);
1589 } else { 1578 } else {
1590 if_freq += 400000; 1579 if_freq += 400000;
1591 /* Disable Spectral Invert*/ 1580 /* Disable Spectral Invert*/
1592 status = vid_blk_read_word(dev, DIF_MISC_CTRL, 1581 vid_blk_read_word(dev, DIF_MISC_CTRL,
1593 &dif_misc_ctrl_value); 1582 &dif_misc_ctrl_value);
1594 dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF; 1583 dif_misc_ctrl_value = dif_misc_ctrl_value & 0xFFDFFFFF;
1595 status = vid_blk_write_word(dev, DIF_MISC_CTRL, 1584 vid_blk_write_word(dev, DIF_MISC_CTRL,
1596 dif_misc_ctrl_value); 1585 dif_misc_ctrl_value);
1597 } 1586 }
1598 1587
@@ -1606,10 +1595,10 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq,
1606 } 1595 }
1607 1596
1608 cx231xx_info("Enter IF=%zd\n", 1597 cx231xx_info("Enter IF=%zd\n",
1609 sizeof(Dif_set_array)/sizeof(struct dif_settings)); 1598 ARRAY_SIZE(Dif_set_array));
1610 for (i = 0; i < sizeof(Dif_set_array)/sizeof(struct dif_settings); i++) { 1599 for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) {
1611 if (Dif_set_array[i].if_freq == if_freq) { 1600 if (Dif_set_array[i].if_freq == if_freq) {
1612 status = vid_blk_write_word(dev, 1601 vid_blk_write_word(dev,
1613 Dif_set_array[i].register_address, Dif_set_array[i].value); 1602 Dif_set_array[i].register_address, Dif_set_array[i].value);
1614 } 1603 }
1615 } 1604 }
@@ -3090,31 +3079,30 @@ int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
3090 */ 3079 */
3091int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len) 3080int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len)
3092{ 3081{
3093 int status = 0;
3094 int i = 0; 3082 int i = 0;
3095 3083
3096 /* get the lock */ 3084 /* get the lock */
3097 mutex_lock(&dev->gpio_i2c_lock); 3085 mutex_lock(&dev->gpio_i2c_lock);
3098 3086
3099 /* start */ 3087 /* start */
3100 status = cx231xx_gpio_i2c_start(dev); 3088 cx231xx_gpio_i2c_start(dev);
3101 3089
3102 /* write dev_addr */ 3090 /* write dev_addr */
3103 status = cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1); 3091 cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1);
3104 3092
3105 /* read Ack */ 3093 /* read Ack */
3106 status = cx231xx_gpio_i2c_read_ack(dev); 3094 cx231xx_gpio_i2c_read_ack(dev);
3107 3095
3108 for (i = 0; i < len; i++) { 3096 for (i = 0; i < len; i++) {
3109 /* Write data */ 3097 /* Write data */
3110 status = cx231xx_gpio_i2c_write_byte(dev, buf[i]); 3098 cx231xx_gpio_i2c_write_byte(dev, buf[i]);
3111 3099
3112 /* read Ack */ 3100 /* read Ack */
3113 status = cx231xx_gpio_i2c_read_ack(dev); 3101 cx231xx_gpio_i2c_read_ack(dev);
3114 } 3102 }
3115 3103
3116 /* write End */ 3104 /* write End */
3117 status = cx231xx_gpio_i2c_end(dev); 3105 cx231xx_gpio_i2c_end(dev);
3118 3106
3119 /* release the lock */ 3107 /* release the lock */
3120 mutex_unlock(&dev->gpio_i2c_lock); 3108 mutex_unlock(&dev->gpio_i2c_lock);
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index 08dd930f882a..05358d486135 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -754,7 +754,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
754 } 754 }
755 } 755 }
756 756
757 return 0; 757 return errCode ? -EINVAL : 0;
758} 758}
759EXPORT_SYMBOL_GPL(cx231xx_set_mode); 759EXPORT_SYMBOL_GPL(cx231xx_set_mode);
760 760
@@ -764,7 +764,7 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size)
764 int actlen, ret = -ENOMEM; 764 int actlen, ret = -ENOMEM;
765 u32 *buffer; 765 u32 *buffer;
766 766
767buffer = kzalloc(4096, GFP_KERNEL); 767 buffer = kzalloc(4096, GFP_KERNEL);
768 if (buffer == NULL) { 768 if (buffer == NULL) {
769 cx231xx_info("out of mem\n"); 769 cx231xx_info("out of mem\n");
770 return -ENOMEM; 770 return -ENOMEM;
@@ -772,16 +772,16 @@ buffer = kzalloc(4096, GFP_KERNEL);
772 memcpy(&buffer[0], firmware, 4096); 772 memcpy(&buffer[0], firmware, 4096);
773 773
774 ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 5), 774 ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 5),
775 buffer, 4096, &actlen, 2000); 775 buffer, 4096, &actlen, 2000);
776 776
777 if (ret) 777 if (ret)
778 cx231xx_info("bulk message failed: %d (%d/%d)", ret, 778 cx231xx_info("bulk message failed: %d (%d/%d)", ret,
779 size, actlen); 779 size, actlen);
780 else { 780 else {
781 errCode = actlen != size ? -1 : 0; 781 errCode = actlen != size ? -1 : 0;
782 } 782 }
783kfree(buffer); 783 kfree(buffer);
784 return 0; 784 return errCode;
785} 785}
786 786
787/***************************************************************** 787/*****************************************************************
@@ -797,7 +797,7 @@ static void cx231xx_isoc_irq_callback(struct urb *urb)
797 struct cx231xx_video_mode *vmode = 797 struct cx231xx_video_mode *vmode =
798 container_of(dma_q, struct cx231xx_video_mode, vidq); 798 container_of(dma_q, struct cx231xx_video_mode, vidq);
799 struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode); 799 struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
800 int rc, i; 800 int i;
801 801
802 switch (urb->status) { 802 switch (urb->status) {
803 case 0: /* success */ 803 case 0: /* success */
@@ -814,7 +814,7 @@ static void cx231xx_isoc_irq_callback(struct urb *urb)
814 814
815 /* Copy data from URB */ 815 /* Copy data from URB */
816 spin_lock(&dev->video_mode.slock); 816 spin_lock(&dev->video_mode.slock);
817 rc = dev->video_mode.isoc_ctl.isoc_copy(dev, urb); 817 dev->video_mode.isoc_ctl.isoc_copy(dev, urb);
818 spin_unlock(&dev->video_mode.slock); 818 spin_unlock(&dev->video_mode.slock);
819 819
820 /* Reset urb buffers */ 820 /* Reset urb buffers */
@@ -822,7 +822,6 @@ static void cx231xx_isoc_irq_callback(struct urb *urb)
822 urb->iso_frame_desc[i].status = 0; 822 urb->iso_frame_desc[i].status = 0;
823 urb->iso_frame_desc[i].actual_length = 0; 823 urb->iso_frame_desc[i].actual_length = 0;
824 } 824 }
825 urb->status = 0;
826 825
827 urb->status = usb_submit_urb(urb, GFP_ATOMIC); 826 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
828 if (urb->status) { 827 if (urb->status) {
@@ -843,7 +842,6 @@ static void cx231xx_bulk_irq_callback(struct urb *urb)
843 struct cx231xx_video_mode *vmode = 842 struct cx231xx_video_mode *vmode =
844 container_of(dma_q, struct cx231xx_video_mode, vidq); 843 container_of(dma_q, struct cx231xx_video_mode, vidq);
845 struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode); 844 struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
846 int rc;
847 845
848 switch (urb->status) { 846 switch (urb->status) {
849 case 0: /* success */ 847 case 0: /* success */
@@ -860,12 +858,10 @@ static void cx231xx_bulk_irq_callback(struct urb *urb)
860 858
861 /* Copy data from URB */ 859 /* Copy data from URB */
862 spin_lock(&dev->video_mode.slock); 860 spin_lock(&dev->video_mode.slock);
863 rc = dev->video_mode.bulk_ctl.bulk_copy(dev, urb); 861 dev->video_mode.bulk_ctl.bulk_copy(dev, urb);
864 spin_unlock(&dev->video_mode.slock); 862 spin_unlock(&dev->video_mode.slock);
865 863
866 /* Reset urb buffers */ 864 /* Reset urb buffers */
867 urb->status = 0;
868
869 urb->status = usb_submit_urb(urb, GFP_ATOMIC); 865 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
870 if (urb->status) { 866 if (urb->status) {
871 cx231xx_isocdbg("urb resubmit failed (error=%i)\n", 867 cx231xx_isocdbg("urb resubmit failed (error=%i)\n",
@@ -1231,42 +1227,40 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets,
1231EXPORT_SYMBOL_GPL(cx231xx_init_bulk); 1227EXPORT_SYMBOL_GPL(cx231xx_init_bulk);
1232void cx231xx_stop_TS1(struct cx231xx *dev) 1228void cx231xx_stop_TS1(struct cx231xx *dev)
1233{ 1229{
1234 int status = 0;
1235 u8 val[4] = { 0, 0, 0, 0 }; 1230 u8 val[4] = { 0, 0, 0, 0 };
1236 1231
1237 val[0] = 0x00; 1232 val[0] = 0x00;
1238 val[1] = 0x03; 1233 val[1] = 0x03;
1239 val[2] = 0x00; 1234 val[2] = 0x00;
1240 val[3] = 0x00; 1235 val[3] = 0x00;
1241 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, 1236 cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1242 TS_MODE_REG, val, 4); 1237 TS_MODE_REG, val, 4);
1243 1238
1244 val[0] = 0x00; 1239 val[0] = 0x00;
1245 val[1] = 0x70; 1240 val[1] = 0x70;
1246 val[2] = 0x04; 1241 val[2] = 0x04;
1247 val[3] = 0x00; 1242 val[3] = 0x00;
1248 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, 1243 cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1249 TS1_CFG_REG, val, 4); 1244 TS1_CFG_REG, val, 4);
1250} 1245}
1251/* EXPORT_SYMBOL_GPL(cx231xx_stop_TS1); */ 1246/* EXPORT_SYMBOL_GPL(cx231xx_stop_TS1); */
1252void cx231xx_start_TS1(struct cx231xx *dev) 1247void cx231xx_start_TS1(struct cx231xx *dev)
1253{ 1248{
1254 int status = 0;
1255 u8 val[4] = { 0, 0, 0, 0 }; 1249 u8 val[4] = { 0, 0, 0, 0 };
1256 1250
1257 val[0] = 0x03; 1251 val[0] = 0x03;
1258 val[1] = 0x03; 1252 val[1] = 0x03;
1259 val[2] = 0x00; 1253 val[2] = 0x00;
1260 val[3] = 0x00; 1254 val[3] = 0x00;
1261 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, 1255 cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1262 TS_MODE_REG, val, 4); 1256 TS_MODE_REG, val, 4);
1263 1257
1264 val[0] = 0x04; 1258 val[0] = 0x04;
1265 val[1] = 0xA3; 1259 val[1] = 0xA3;
1266 val[2] = 0x3B; 1260 val[2] = 0x3B;
1267 val[3] = 0x00; 1261 val[3] = 0x00;
1268 status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, 1262 cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
1269 TS1_CFG_REG, val, 4); 1263 TS1_CFG_REG, val, 4);
1270} 1264}
1271/* EXPORT_SYMBOL_GPL(cx231xx_start_TS1); */ 1265/* EXPORT_SYMBOL_GPL(cx231xx_start_TS1); */
1272/***************************************************************** 1266/*****************************************************************
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
index 8cdee5f78f13..3d15314e1f88 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -83,7 +83,6 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status)
83 */ 83 */
84static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) 84static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
85{ 85{
86 struct cx231xx_buffer *buf;
87 struct cx231xx_dmaqueue *dma_q = urb->context; 86 struct cx231xx_dmaqueue *dma_q = urb->context;
88 int rc = 1; 87 int rc = 1;
89 unsigned char *p_buffer; 88 unsigned char *p_buffer;
@@ -102,8 +101,6 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
102 return 0; 101 return 0;
103 } 102 }
104 103
105 buf = dev->vbi_mode.bulk_ctl.buf;
106
107 /* get buffer pointer and length */ 104 /* get buffer pointer and length */
108 p_buffer = urb->transfer_buffer; 105 p_buffer = urb->transfer_buffer;
109 buffer_size = urb->actual_length; 106 buffer_size = urb->actual_length;
@@ -310,7 +307,6 @@ static void cx231xx_irq_vbi_callback(struct urb *urb)
310 struct cx231xx_video_mode *vmode = 307 struct cx231xx_video_mode *vmode =
311 container_of(dma_q, struct cx231xx_video_mode, vidq); 308 container_of(dma_q, struct cx231xx_video_mode, vidq);
312 struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode); 309 struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
313 int rc;
314 310
315 switch (urb->status) { 311 switch (urb->status) {
316 case 0: /* success */ 312 case 0: /* success */
@@ -328,7 +324,7 @@ static void cx231xx_irq_vbi_callback(struct urb *urb)
328 324
329 /* Copy data from URB */ 325 /* Copy data from URB */
330 spin_lock(&dev->vbi_mode.slock); 326 spin_lock(&dev->vbi_mode.slock);
331 rc = dev->vbi_mode.bulk_ctl.bulk_copy(dev, urb); 327 dev->vbi_mode.bulk_ctl.bulk_copy(dev, urb);
332 spin_unlock(&dev->vbi_mode.slock); 328 spin_unlock(&dev->vbi_mode.slock);
333 329
334 /* Reset status */ 330 /* Reset status */
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 7f916f0685e9..523aa49d6b86 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -326,9 +326,7 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
326 */ 326 */
327static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) 327static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
328{ 328{
329 struct cx231xx_buffer *buf;
330 struct cx231xx_dmaqueue *dma_q = urb->context; 329 struct cx231xx_dmaqueue *dma_q = urb->context;
331 unsigned char *outp = NULL;
332 int i, rc = 1; 330 int i, rc = 1;
333 unsigned char *p_buffer; 331 unsigned char *p_buffer;
334 u32 bytes_parsed = 0, buffer_size = 0; 332 u32 bytes_parsed = 0, buffer_size = 0;
@@ -346,10 +344,6 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
346 return 0; 344 return 0;
347 } 345 }
348 346
349 buf = dev->video_mode.isoc_ctl.buf;
350 if (buf != NULL)
351 outp = videobuf_to_vmalloc(&buf->vb);
352
353 for (i = 0; i < urb->number_of_packets; i++) { 347 for (i = 0; i < urb->number_of_packets; i++) {
354 int status = urb->iso_frame_desc[i].status; 348 int status = urb->iso_frame_desc[i].status;
355 349
@@ -429,9 +423,7 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
429 423
430static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) 424static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
431{ 425{
432 struct cx231xx_buffer *buf;
433 struct cx231xx_dmaqueue *dma_q = urb->context; 426 struct cx231xx_dmaqueue *dma_q = urb->context;
434 unsigned char *outp = NULL;
435 int rc = 1; 427 int rc = 1;
436 unsigned char *p_buffer; 428 unsigned char *p_buffer;
437 u32 bytes_parsed = 0, buffer_size = 0; 429 u32 bytes_parsed = 0, buffer_size = 0;
@@ -449,10 +441,6 @@ static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
449 return 0; 441 return 0;
450 } 442 }
451 443
452 buf = dev->video_mode.bulk_ctl.buf;
453 if (buf != NULL)
454 outp = videobuf_to_vmalloc(&buf->vb);
455
456 if (1) { 444 if (1) {
457 445
458 /* get buffer pointer and length */ 446 /* get buffer pointer and length */
@@ -701,13 +689,9 @@ void cx231xx_reset_video_buffer(struct cx231xx *dev,
701 buf = dev->video_mode.bulk_ctl.buf; 689 buf = dev->video_mode.bulk_ctl.buf;
702 690
703 if (buf == NULL) { 691 if (buf == NULL) {
704 u8 *outp = NULL;
705 /* first try to get the buffer */ 692 /* first try to get the buffer */
706 get_next_buf(dma_q, &buf); 693 get_next_buf(dma_q, &buf);
707 694
708 if (buf)
709 outp = videobuf_to_vmalloc(&buf->vb);
710
711 dma_q->pos = 0; 695 dma_q->pos = 0;
712 dma_q->field1_done = 0; 696 dma_q->field1_done = 0;
713 dma_q->current_field = -1; 697 dma_q->current_field = -1;
@@ -2561,6 +2545,10 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
2561 vfd->release = video_device_release; 2545 vfd->release = video_device_release;
2562 vfd->debug = video_debug; 2546 vfd->debug = video_debug;
2563 vfd->lock = &dev->lock; 2547 vfd->lock = &dev->lock;
2548 /* Locking in file operations other than ioctl should be done
2549 by the driver, not the V4L2 core.
2550 This driver needs auditing so that this flag can be removed. */
2551 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
2564 2552
2565 snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); 2553 snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
2566 2554
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 19b5499d2624..13739e002a63 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -497,6 +497,10 @@ struct cx23885_board cx23885_boards[] = {
497 .name = "TerraTec Cinergy T PCIe Dual", 497 .name = "TerraTec Cinergy T PCIe Dual",
498 .portb = CX23885_MPEG_DVB, 498 .portb = CX23885_MPEG_DVB,
499 .portc = CX23885_MPEG_DVB, 499 .portc = CX23885_MPEG_DVB,
500 },
501 [CX23885_BOARD_TEVII_S471] = {
502 .name = "TeVii S471",
503 .portb = CX23885_MPEG_DVB,
500 } 504 }
501}; 505};
502const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 506const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -705,6 +709,10 @@ struct cx23885_subid cx23885_subids[] = {
705 .subvendor = 0x153b, 709 .subvendor = 0x153b,
706 .subdevice = 0x117e, 710 .subdevice = 0x117e,
707 .card = CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL, 711 .card = CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL,
712 }, {
713 .subvendor = 0xd471,
714 .subdevice = 0x9022,
715 .card = CX23885_BOARD_TEVII_S471,
708 }, 716 },
709}; 717};
710const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 718const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -1460,6 +1468,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1460 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1468 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1461 break; 1469 break;
1462 case CX23885_BOARD_TEVII_S470: 1470 case CX23885_BOARD_TEVII_S470:
1471 case CX23885_BOARD_TEVII_S471:
1463 case CX23885_BOARD_DVBWORLD_2005: 1472 case CX23885_BOARD_DVBWORLD_2005:
1464 ts1->gen_ctrl_val = 0x5; /* Parallel */ 1473 ts1->gen_ctrl_val = 0x5; /* Parallel */
1465 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1474 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 6ad227029a0f..697728f09430 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1046,6 +1046,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1046 if (cx23885_boards[dev->board].ci_type > 0) 1046 if (cx23885_boards[dev->board].ci_type > 0)
1047 cx_clear(RDR_RDRCTL1, 1 << 8); 1047 cx_clear(RDR_RDRCTL1, 1 << 8);
1048 1048
1049 switch (dev->board) {
1050 case CX23885_BOARD_TEVII_S470:
1051 case CX23885_BOARD_TEVII_S471:
1052 cx_clear(RDR_RDRCTL1, 1 << 8);
1053 break;
1054 }
1055
1049 return 0; 1056 return 0;
1050} 1057}
1051 1058
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 6835eb1fc093..a80a92c47455 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -1173,6 +1173,13 @@ static int dvb_register(struct cx23885_tsport *port)
1173 break; 1173 break;
1174 } 1174 }
1175 break; 1175 break;
1176 case CX23885_BOARD_TEVII_S471:
1177 i2c_bus = &dev->i2c_bus[1];
1178
1179 fe0->dvb.frontend = dvb_attach(ds3000_attach,
1180 &tevii_ds3000_config,
1181 &i2c_bus->i2c_adap);
1182 break;
1176 default: 1183 default:
1177 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 1184 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
1178 " isn't supported yet\n", 1185 " isn't supported yet\n",
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index f020f0568df4..d884784a1c85 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -89,6 +89,7 @@
89#define CX23885_BOARD_MPX885 32 89#define CX23885_BOARD_MPX885 32
90#define CX23885_BOARD_MYGICA_X8507 33 90#define CX23885_BOARD_MYGICA_X8507 33
91#define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34 91#define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34
92#define CX23885_BOARD_TEVII_S471 35
92 93
93#define GPIO_0 0x00000001 94#define GPIO_0 0x00000001
94#define GPIO_1 0x00000002 95#define GPIO_1 0x00000002
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
index bb1ce346425d..c2bc39c58f82 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -331,9 +331,7 @@ static u64 ns_to_pulse_clocks(u32 ns)
331 331
332static u16 pulse_clocks_to_clock_divider(u64 count) 332static u16 pulse_clocks_to_clock_divider(u64 count)
333{ 333{
334 u32 rem; 334 do_div(count, (FIFO_RXTX << 2) | 0x3);
335
336 rem = do_div(count, (FIFO_RXTX << 2) | 0x3);
337 335
338 /* net result needs to be rounded down and decremented by 1 */ 336 /* net result needs to be rounded down and decremented by 1 */
339 if (count > RXCLK_RCD + 1) 337 if (count > RXCLK_RCD + 1)
diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c
index 03cfac476b03..1858a45dd081 100644
--- a/drivers/media/video/cx25821/cx25821-alsa.c
+++ b/drivers/media/video/cx25821/cx25821-alsa.c
@@ -290,11 +290,9 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id)
290 u32 status, pci_status; 290 u32 status, pci_status;
291 u32 audint_status, audint_mask; 291 u32 audint_status, audint_mask;
292 int loop, handled = 0; 292 int loop, handled = 0;
293 int audint_count = 0;
294 293
295 audint_status = cx_read(AUD_A_INT_STAT); 294 audint_status = cx_read(AUD_A_INT_STAT);
296 audint_mask = cx_read(AUD_A_INT_MSK); 295 audint_mask = cx_read(AUD_A_INT_MSK);
297 audint_count = cx_read(AUD_A_GPCNT);
298 status = cx_read(PCI_INT_STAT); 296 status = cx_read(PCI_INT_STAT);
299 297
300 for (loop = 0; loop < 1; loop++) { 298 for (loop = 0; loop < 1; loop++) {
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c
index 20c7ca3351a8..8b2a99975c23 100644
--- a/drivers/media/video/cx25821/cx25821-audio-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c
@@ -585,7 +585,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
585static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) 585static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
586{ 586{
587 struct cx25821_dev *dev = dev_id; 587 struct cx25821_dev *dev = dev_id;
588 u32 msk_stat, audio_status; 588 u32 audio_status;
589 int handled = 0; 589 int handled = 0;
590 struct sram_channel *sram_ch; 590 struct sram_channel *sram_ch;
591 591
@@ -594,7 +594,6 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
594 594
595 sram_ch = dev->channels[dev->_audio_upstream_channel].sram_channels; 595 sram_ch = dev->channels[dev->_audio_upstream_channel].sram_channels;
596 596
597 msk_stat = cx_read(sram_ch->int_mstat);
598 audio_status = cx_read(sram_ch->int_stat); 597 audio_status = cx_read(sram_ch->int_stat);
599 598
600 /* Only deal with our interrupt */ 599 /* Only deal with our interrupt */
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
index 7930ca58349f..83c1aa6b2e6c 100644
--- a/drivers/media/video/cx25821/cx25821-core.c
+++ b/drivers/media/video/cx25821/cx25821-core.c
@@ -379,14 +379,6 @@ static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
379 return cx_read(bus->reg_stat) & 0x01; 379 return cx_read(bus->reg_stat) & 0x01;
380} 380}
381 381
382void cx_i2c_read_print(struct cx25821_dev *dev, u32 reg, const char *reg_string)
383{
384 int tmp = 0;
385 u32 value = 0;
386
387 value = cx25821_i2c_read(&dev->i2c_bus[0], reg, &tmp);
388}
389
390static void cx25821_registers_init(struct cx25821_dev *dev) 382static void cx25821_registers_init(struct cx25821_dev *dev)
391{ 383{
392 u32 tmp; 384 u32 tmp;
@@ -895,7 +887,7 @@ static void cx25821_iounmap(struct cx25821_dev *dev)
895 887
896static int cx25821_dev_setup(struct cx25821_dev *dev) 888static int cx25821_dev_setup(struct cx25821_dev *dev)
897{ 889{
898 int io_size = 0, i; 890 int i;
899 891
900 pr_info("\n***********************************\n"); 892 pr_info("\n***********************************\n");
901 pr_info("cx25821 set up\n"); 893 pr_info("cx25821 set up\n");
@@ -960,7 +952,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
960 952
961 /* PCIe stuff */ 953 /* PCIe stuff */
962 dev->base_io_addr = pci_resource_start(dev->pci, 0); 954 dev->base_io_addr = pci_resource_start(dev->pci, 0);
963 io_size = pci_resource_len(dev->pci, 0);
964 955
965 if (!dev->base_io_addr) { 956 if (!dev->base_io_addr) {
966 CX25821_ERR("No PCI Memory resources, exiting!\n"); 957 CX25821_ERR("No PCI Memory resources, exiting!\n");
@@ -1317,13 +1308,12 @@ void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
1317static irqreturn_t cx25821_irq(int irq, void *dev_id) 1308static irqreturn_t cx25821_irq(int irq, void *dev_id)
1318{ 1309{
1319 struct cx25821_dev *dev = dev_id; 1310 struct cx25821_dev *dev = dev_id;
1320 u32 pci_status, pci_mask; 1311 u32 pci_status;
1321 u32 vid_status; 1312 u32 vid_status;
1322 int i, handled = 0; 1313 int i, handled = 0;
1323 u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; 1314 u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
1324 1315
1325 pci_status = cx_read(PCI_INT_STAT); 1316 pci_status = cx_read(PCI_INT_STAT);
1326 pci_mask = cx_read(PCI_INT_MSK);
1327 1317
1328 if (pci_status == 0) 1318 if (pci_status == 0)
1329 goto out; 1319 goto out;
diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c
index 12d7300fa1e9..6311180f430c 100644
--- a/drivers/media/video/cx25821/cx25821-i2c.c
+++ b/drivers/media/video/cx25821/cx25821-i2c.c
@@ -361,7 +361,6 @@ void cx25821_av_clk(struct cx25821_dev *dev, int enable)
361int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value) 361int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
362{ 362{
363 struct i2c_client *client = &bus->i2c_client; 363 struct i2c_client *client = &bus->i2c_client;
364 int retval = 0;
365 int v = 0; 364 int v = 0;
366 u8 addr[2] = { 0, 0 }; 365 u8 addr[2] = { 0, 0 };
367 u8 buf[4] = { 0, 0, 0, 0 }; 366 u8 buf[4] = { 0, 0, 0, 0 };
@@ -385,7 +384,7 @@ int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
385 msgs[0].addr = 0x44; 384 msgs[0].addr = 0x44;
386 msgs[1].addr = 0x44; 385 msgs[1].addr = 0x44;
387 386
388 retval = i2c_xfer(client->adapter, msgs, 2); 387 i2c_xfer(client->adapter, msgs, 2);
389 388
390 v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 389 v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
391 *value = v; 390 *value = v;
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c
index 298a68d98c2f..313fb20a0b47 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-video.c
+++ b/drivers/media/video/cx25821/cx25821-medusa-video.c
@@ -35,7 +35,6 @@
35static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel, 35static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
36 int enable) 36 int enable)
37{ 37{
38 int ret_val = 1;
39 u32 value = 0; 38 u32 value = 0;
40 u32 tmp = 0; 39 u32 tmp = 0;
41 int out_ctrl = OUT_CTRL1; 40 int out_ctrl = OUT_CTRL1;
@@ -79,13 +78,13 @@ static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
79 value &= 0xFFFFFF7F; /* clear BLUE_FIELD_EN */ 78 value &= 0xFFFFFF7F; /* clear BLUE_FIELD_EN */
80 if (enable) 79 if (enable)
81 value |= 0x00000080; /* set BLUE_FIELD_EN */ 80 value |= 0x00000080; /* set BLUE_FIELD_EN */
82 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value); 81 cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
83 82
84 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp); 83 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
85 value &= 0xFFFFFF7F; 84 value &= 0xFFFFFF7F;
86 if (enable) 85 if (enable)
87 value |= 0x00000080; /* set BLUE_FIELD_EN */ 86 value |= 0x00000080; /* set BLUE_FIELD_EN */
88 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value); 87 cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
89} 88}
90 89
91static int medusa_initialize_ntsc(struct cx25821_dev *dev) 90static int medusa_initialize_ntsc(struct cx25821_dev *dev)
@@ -431,7 +430,6 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
431{ 430{
432 int decoder = 0; 431 int decoder = 0;
433 int decoder_count = 0; 432 int decoder_count = 0;
434 int ret_val = 0;
435 u32 hscale = 0x0; 433 u32 hscale = 0x0;
436 u32 vscale = 0x0; 434 u32 vscale = 0x0;
437 const int MAX_WIDTH = 720; 435 const int MAX_WIDTH = 720;
@@ -482,9 +480,9 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
482 480
483 for (; decoder < decoder_count; decoder++) { 481 for (; decoder < decoder_count; decoder++) {
484 /* write scaling values for each decoder */ 482 /* write scaling values for each decoder */
485 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 483 cx25821_i2c_write(&dev->i2c_bus[0],
486 HSCALE_CTRL + (0x200 * decoder), hscale); 484 HSCALE_CTRL + (0x200 * decoder), hscale);
487 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 485 cx25821_i2c_write(&dev->i2c_bus[0],
488 VSCALE_CTRL + (0x200 * decoder), vscale); 486 VSCALE_CTRL + (0x200 * decoder), vscale);
489 } 487 }
490 488
@@ -494,7 +492,6 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
494static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, 492static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
495 int duration) 493 int duration)
496{ 494{
497 int ret_val = 0;
498 u32 fld_cnt = 0; 495 u32 fld_cnt = 0;
499 u32 tmp = 0; 496 u32 tmp = 0;
500 u32 disp_cnt_reg = DISP_AB_CNT; 497 u32 disp_cnt_reg = DISP_AB_CNT;
@@ -537,7 +534,7 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
537 fld_cnt |= ((u32) duration) << 16; 534 fld_cnt |= ((u32) duration) << 16;
538 } 535 }
539 536
540 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt); 537 cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
541 538
542 mutex_unlock(&dev->lock); 539 mutex_unlock(&dev->lock);
543} 540}
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
index 5a157cf4a95e..c8c94fbf5d8d 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
@@ -587,7 +587,7 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
587static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) 587static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
588{ 588{
589 struct cx25821_dev *dev = dev_id; 589 struct cx25821_dev *dev = dev_id;
590 u32 msk_stat, vid_status; 590 u32 vid_status;
591 int handled = 0; 591 int handled = 0;
592 int channel_num = 0; 592 int channel_num = 0;
593 struct sram_channel *sram_ch; 593 struct sram_channel *sram_ch;
@@ -598,7 +598,6 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
598 channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; 598 channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
599 sram_ch = dev->channels[channel_num].sram_channels; 599 sram_ch = dev->channels[channel_num].sram_channels;
600 600
601 msk_stat = cx_read(sram_ch->int_mstat);
602 vid_status = cx_read(sram_ch->int_stat); 601 vid_status = cx_read(sram_ch->int_stat);
603 602
604 /* Only deal with our interrupt */ 603 /* Only deal with our interrupt */
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c
index 21e7d657f049..52c13e0b6492 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream.c
@@ -637,7 +637,7 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
637static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) 637static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
638{ 638{
639 struct cx25821_dev *dev = dev_id; 639 struct cx25821_dev *dev = dev_id;
640 u32 msk_stat, vid_status; 640 u32 vid_status;
641 int handled = 0; 641 int handled = 0;
642 int channel_num = 0; 642 int channel_num = 0;
643 struct sram_channel *sram_ch; 643 struct sram_channel *sram_ch;
@@ -649,7 +649,6 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
649 649
650 sram_ch = dev->channels[channel_num].sram_channels; 650 sram_ch = dev->channels[channel_num].sram_channels;
651 651
652 msk_stat = cx_read(sram_ch->int_mstat);
653 vid_status = cx_read(sram_ch->int_stat); 652 vid_status = cx_read(sram_ch->int_stat);
654 653
655 /* Only deal with our interrupt */ 654 /* Only deal with our interrupt */
diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c
index ffd8bc79c02e..b38d4379cc36 100644
--- a/drivers/media/video/cx25821/cx25821-video.c
+++ b/drivers/media/video/cx25821/cx25821-video.c
@@ -109,25 +109,6 @@ struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
109 return NULL; 109 return NULL;
110} 110}
111 111
112void cx25821_dump_video_queue(struct cx25821_dev *dev,
113 struct cx25821_dmaqueue *q)
114{
115 struct cx25821_buffer *buf;
116 struct list_head *item;
117 dprintk(1, "%s()\n", __func__);
118
119 if (!list_empty(&q->active)) {
120 list_for_each(item, &q->active)
121 buf = list_entry(item, struct cx25821_buffer, vb.queue);
122 }
123
124 if (!list_empty(&q->queued)) {
125 list_for_each(item, &q->queued)
126 buf = list_entry(item, struct cx25821_buffer, vb.queue);
127 }
128
129}
130
131void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, 112void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
132 u32 count) 113 u32 count)
133{ 114{
@@ -557,7 +538,7 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
557 struct cx25821_buffer *buf = 538 struct cx25821_buffer *buf =
558 container_of(vb, struct cx25821_buffer, vb); 539 container_of(vb, struct cx25821_buffer, vb);
559 int rc, init_buffer = 0; 540 int rc, init_buffer = 0;
560 u32 line0_offset, line1_offset; 541 u32 line0_offset;
561 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 542 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
562 int bpl_local = LINE_SIZE_D1; 543 int bpl_local = LINE_SIZE_D1;
563 int channel_opened = fh->channel_id; 544 int channel_opened = fh->channel_id;
@@ -639,7 +620,6 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
639 case V4L2_FIELD_INTERLACED: 620 case V4L2_FIELD_INTERLACED:
640 /* All other formats are top field first */ 621 /* All other formats are top field first */
641 line0_offset = 0; 622 line0_offset = 0;
642 line1_offset = buf->bpl;
643 dprintk(1, "top field first\n"); 623 dprintk(1, "top field first\n");
644 624
645 cx25821_risc_buffer(dev->pci, &buf->risc, 625 cx25821_risc_buffer(dev->pci, &buf->risc,
@@ -1830,7 +1810,6 @@ static long video_ioctl_set(struct file *file, unsigned int cmd,
1830 int i = 0; 1810 int i = 0;
1831 int cif_enable = 0; 1811 int cif_enable = 0;
1832 int cif_width = 0; 1812 int cif_width = 0;
1833 u32 value = 0;
1834 1813
1835 data_from_user = (struct downstream_user_struct *)arg; 1814 data_from_user = (struct downstream_user_struct *)arg;
1836 1815
@@ -1914,7 +1893,7 @@ static long video_ioctl_set(struct file *file, unsigned int cmd,
1914 cx_write(data_from_user->reg_address, data_from_user->reg_data); 1893 cx_write(data_from_user->reg_address, data_from_user->reg_data);
1915 break; 1894 break;
1916 case MEDUSA_READ: 1895 case MEDUSA_READ:
1917 value = cx25821_i2c_read(&dev->i2c_bus[0], 1896 cx25821_i2c_read(&dev->i2c_bus[0],
1918 (u16) data_from_user->reg_address, 1897 (u16) data_from_user->reg_address,
1919 &data_from_user->reg_data); 1898 &data_from_user->reg_data);
1920 break; 1899 break;
diff --git a/drivers/media/video/cx25821/cx25821-video.h b/drivers/media/video/cx25821/cx25821-video.h
index d0d9538ca5b3..9652a5e35ba2 100644
--- a/drivers/media/video/cx25821/cx25821-video.h
+++ b/drivers/media/video/cx25821/cx25821-video.h
@@ -86,8 +86,6 @@ extern struct cx25821_fmt formats[];
86extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); 86extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc);
87extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; 87extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
88 88
89extern void cx25821_dump_video_queue(struct cx25821_dev *dev,
90 struct cx25821_dmaqueue *q);
91extern void cx25821_video_wakeup(struct cx25821_dev *dev, 89extern void cx25821_video_wakeup(struct cx25821_dev *dev,
92 struct cx25821_dmaqueue *q, u32 count); 90 struct cx25821_dmaqueue *q, u32 count);
93 91
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c
index 13c380ebb562..38ce76ed1924 100644
--- a/drivers/media/video/cx25840/cx25840-ir.c
+++ b/drivers/media/video/cx25840/cx25840-ir.c
@@ -316,9 +316,7 @@ static u64 ns_to_pulse_clocks(u32 ns)
316 316
317static u16 pulse_clocks_to_clock_divider(u64 count) 317static u16 pulse_clocks_to_clock_divider(u64 count)
318{ 318{
319 u32 rem; 319 do_div(count, (FIFO_RXTX << 2) | 0x3);
320
321 rem = do_div(count, (FIFO_RXTX << 2) | 0x3);
322 320
323 /* net result needs to be rounded down and decremented by 1 */ 321 /* net result needs to be rounded down and decremented by 1 */
324 if (count > RXCLK_RCD + 1) 322 if (count > RXCLK_RCD + 1)
@@ -860,12 +858,10 @@ static int cx25840_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count,
860 ssize_t *num) 858 ssize_t *num)
861{ 859{
862 struct cx25840_ir_state *ir_state = to_ir_state(sd); 860 struct cx25840_ir_state *ir_state = to_ir_state(sd);
863 struct i2c_client *c;
864 861
865 if (ir_state == NULL) 862 if (ir_state == NULL)
866 return -ENODEV; 863 return -ENODEV;
867 864
868 c = ir_state->c;
869#if 0 865#if 0
870 /* 866 /*
871 * FIXME - the code below is an incomplete and untested sketch of what 867 * FIXME - the code below is an incomplete and untested sketch of what
diff --git a/drivers/media/video/davinci/Kconfig b/drivers/media/video/davinci/Kconfig
index 60a456ebdc7c..9337b5605c90 100644
--- a/drivers/media/video/davinci/Kconfig
+++ b/drivers/media/video/davinci/Kconfig
@@ -40,6 +40,7 @@ config VIDEO_VPSS_SYSTEM
40config VIDEO_VPFE_CAPTURE 40config VIDEO_VPFE_CAPTURE
41 tristate "VPFE Video Capture Driver" 41 tristate "VPFE Video Capture Driver"
42 depends on VIDEO_V4L2 && (ARCH_DAVINCI || ARCH_OMAP3) 42 depends on VIDEO_V4L2 && (ARCH_DAVINCI || ARCH_OMAP3)
43 depends on I2C
43 select VIDEOBUF_DMA_CONTIG 44 select VIDEOBUF_DMA_CONTIG
44 help 45 help
45 Support for DMx/AMx VPFE based frame grabber. This is the 46 Support for DMx/AMx VPFE based frame grabber. This is the
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c
index 1f3b1c729252..e106b72810a9 100644
--- a/drivers/media/video/davinci/vpbe_display.c
+++ b/drivers/media/video/davinci/vpbe_display.c
@@ -1618,6 +1618,10 @@ static __devinit int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
1618 vbd->ioctl_ops = &vpbe_ioctl_ops; 1618 vbd->ioctl_ops = &vpbe_ioctl_ops;
1619 vbd->minor = -1; 1619 vbd->minor = -1;
1620 vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev; 1620 vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
1621 /* Locking in file operations other than ioctl should be done
1622 by the driver, not the V4L2 core.
1623 This driver needs auditing so that this flag can be removed. */
1624 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vbd->flags);
1621 vbd->lock = &vpbe_display_layer->opslock; 1625 vbd->lock = &vpbe_display_layer->opslock;
1622 1626
1623 if (disp_dev->vpbe_dev->current_timings.timings_type & 1627 if (disp_dev->vpbe_dev->current_timings.timings_type &
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 20cf271a774b..49a845fb804a 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -1761,7 +1761,7 @@ static long vpfe_param_handler(struct file *file, void *priv,
1761 } 1761 }
1762 break; 1762 break;
1763 default: 1763 default:
1764 ret = -EINVAL; 1764 ret = -ENOTTY;
1765 } 1765 }
1766unlock_out: 1766unlock_out:
1767 mutex_unlock(&vpfe_dev->lock); 1767 mutex_unlock(&vpfe_dev->lock);
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index 6504e40a31dd..96046957bf21 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -2228,6 +2228,10 @@ static __init int vpif_probe(struct platform_device *pdev)
2228 common = &(ch->common[VPIF_VIDEO_INDEX]); 2228 common = &(ch->common[VPIF_VIDEO_INDEX]);
2229 spin_lock_init(&common->irqlock); 2229 spin_lock_init(&common->irqlock);
2230 mutex_init(&common->lock); 2230 mutex_init(&common->lock);
2231 /* Locking in file operations other than ioctl should be done
2232 by the driver, not the V4L2 core.
2233 This driver needs auditing so that this flag can be removed. */
2234 set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags);
2231 ch->video_dev->lock = &common->lock; 2235 ch->video_dev->lock = &common->lock;
2232 /* Initialize prio member of channel object */ 2236 /* Initialize prio member of channel object */
2233 v4l2_prio_init(&ch->prio); 2237 v4l2_prio_init(&ch->prio);
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 7fa34b4fae26..e6488ee7db18 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -1778,6 +1778,10 @@ static __init int vpif_probe(struct platform_device *pdev)
1778 v4l2_prio_init(&ch->prio); 1778 v4l2_prio_init(&ch->prio);
1779 ch->common[VPIF_VIDEO_INDEX].fmt.type = 1779 ch->common[VPIF_VIDEO_INDEX].fmt.type =
1780 V4L2_BUF_TYPE_VIDEO_OUTPUT; 1780 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1781 /* Locking in file operations other than ioctl should be done
1782 by the driver, not the V4L2 core.
1783 This driver needs auditing so that this flag can be removed. */
1784 set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags);
1781 ch->video_dev->lock = &common->lock; 1785 ch->video_dev->lock = &common->lock;
1782 1786
1783 /* register video device */ 1787 /* register video device */
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index f6f622e123bd..928ef0d0429f 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -49,10 +49,10 @@ config VIDEO_EM28XX_DVB
49 Empiatech em28xx chips. 49 Empiatech em28xx chips.
50 50
51config VIDEO_EM28XX_RC 51config VIDEO_EM28XX_RC
52 bool "EM28XX Remote Controller support" 52 tristate "EM28XX Remote Controller support"
53 depends on RC_CORE 53 depends on RC_CORE
54 depends on VIDEO_EM28XX 54 depends on VIDEO_EM28XX
55 depends on !(RC_CORE=m && VIDEO_EM28XX=y) 55 depends on !(RC_CORE=m && VIDEO_EM28XX=y)
56 default y 56 default VIDEO_EM28XX
57 ---help--- 57 ---help---
58 Enables Remote Controller support on em28xx driver. 58 Enables Remote Controller support on em28xx driver.
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index 2abdf76c5203..c8b338d4be05 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -1,16 +1,15 @@
1em28xx-y := em28xx-video.o em28xx-i2c.o em28xx-cards.o 1em28xx-y := em28xx-video.o em28xx-i2c.o em28xx-cards.o
2em28xx-y += em28xx-core.o em28xx-vbi.o 2em28xx-y += em28xx-core.o em28xx-vbi.o
3 3
4em28xx-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-input.o
5
6em28xx-alsa-objs := em28xx-audio.o 4em28xx-alsa-objs := em28xx-audio.o
5em28xx-rc-objs := em28xx-input.o
7 6
8obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o 7obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
9obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o 8obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
10obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o 9obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
10obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
11 11
12ccflags-y += -Idrivers/media/video 12ccflags-y += -Idrivers/media/video
13ccflags-y += -Idrivers/media/common/tuners 13ccflags-y += -Idrivers/media/common/tuners
14ccflags-y += -Idrivers/media/dvb/dvb-core 14ccflags-y += -Idrivers/media/dvb/dvb-core
15ccflags-y += -Idrivers/media/dvb/frontends 15ccflags-y += -Idrivers/media/dvb/frontends
16
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index e2a7b77c39c7..d7e2a3dc5525 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -343,7 +343,6 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
343static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, 343static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
344 struct snd_pcm_hw_params *hw_params) 344 struct snd_pcm_hw_params *hw_params)
345{ 345{
346 unsigned int channels, rate, format;
347 int ret; 346 int ret;
348 347
349 dprintk("Setting capture parameters\n"); 348 dprintk("Setting capture parameters\n");
@@ -352,13 +351,17 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
352 params_buffer_bytes(hw_params)); 351 params_buffer_bytes(hw_params));
353 if (ret < 0) 352 if (ret < 0)
354 return ret; 353 return ret;
354#if 0
355 /* TODO: set up em28xx audio chip to deliver the correct audio format,
356 current default is 48000hz multiplexed => 96000hz mono
357 which shouldn't matter since analogue TV only supports mono */
358 unsigned int channels, rate, format;
359
355 format = params_format(hw_params); 360 format = params_format(hw_params);
356 rate = params_rate(hw_params); 361 rate = params_rate(hw_params);
357 channels = params_channels(hw_params); 362 channels = params_channels(hw_params);
363#endif
358 364
359 /* TODO: set up em28xx audio chip to deliver the correct audio format,
360 current default is 48000hz multiplexed => 96000hz mono
361 which shouldn't matter since analogue TV only supports mono */
362 return 0; 365 return 0;
363} 366}
364 367
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 9fd8cc7dbb23..20a7e24de6fb 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -69,6 +69,8 @@ struct em28xx_hash_table {
69 unsigned int tuner; 69 unsigned int tuner;
70}; 70};
71 71
72static void em28xx_pre_card_setup(struct em28xx *dev);
73
72/* 74/*
73 * Reset sequences for analog/digital modes 75 * Reset sequences for analog/digital modes
74 */ 76 */
@@ -2361,7 +2363,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
2361/* Since em28xx_pre_card_setup() requires a proper dev->model, 2363/* Since em28xx_pre_card_setup() requires a proper dev->model,
2362 * this won't work for boards with generic PCI IDs 2364 * this won't work for boards with generic PCI IDs
2363 */ 2365 */
2364void em28xx_pre_card_setup(struct em28xx *dev) 2366static void em28xx_pre_card_setup(struct em28xx *dev)
2365{ 2367{
2366 /* Set the initial XCLK and I2C clock values based on the board 2368 /* Set the initial XCLK and I2C clock values based on the board
2367 definition */ 2369 definition */
@@ -2661,55 +2663,7 @@ static int em28xx_hint_board(struct em28xx *dev)
2661 return -1; 2663 return -1;
2662} 2664}
2663 2665
2664/* ----------------------------------------------------------------------- */ 2666static void em28xx_card_setup(struct em28xx *dev)
2665void em28xx_register_i2c_ir(struct em28xx *dev)
2666{
2667 /* Leadtek winfast tv USBII deluxe can find a non working IR-device */
2668 /* at address 0x18, so if that address is needed for another board in */
2669 /* the future, please put it after 0x1f. */
2670 struct i2c_board_info info;
2671 const unsigned short addr_list[] = {
2672 0x1f, 0x30, 0x47, I2C_CLIENT_END
2673 };
2674
2675 if (disable_ir)
2676 return;
2677
2678 memset(&info, 0, sizeof(struct i2c_board_info));
2679 memset(&dev->init_data, 0, sizeof(dev->init_data));
2680 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
2681
2682 /* detect & configure */
2683 switch (dev->model) {
2684 case EM2800_BOARD_TERRATEC_CINERGY_200:
2685 case EM2820_BOARD_TERRATEC_CINERGY_250:
2686 dev->init_data.ir_codes = RC_MAP_EM_TERRATEC;
2687 dev->init_data.get_key = em28xx_get_key_terratec;
2688 dev->init_data.name = "i2c IR (EM28XX Terratec)";
2689 break;
2690 case EM2820_BOARD_PINNACLE_USB_2:
2691 dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
2692 dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
2693 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
2694 break;
2695 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
2696 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
2697 dev->init_data.get_key = em28xx_get_key_em_haup;
2698 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2699 break;
2700 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
2701 dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
2702 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
2703 dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
2704 break;
2705 }
2706
2707 if (dev->init_data.name)
2708 info.platform_data = &dev->init_data;
2709 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL);
2710}
2711
2712void em28xx_card_setup(struct em28xx *dev)
2713{ 2667{
2714 /* 2668 /*
2715 * If the device can be a webcam, seek for a sensor. 2669 * If the device can be a webcam, seek for a sensor.
@@ -2849,13 +2803,6 @@ void em28xx_card_setup(struct em28xx *dev)
2849 break; 2803 break;
2850 } 2804 }
2851 2805
2852#if defined(CONFIG_MODULES) && defined(MODULE)
2853 if (dev->board.has_ir_i2c && !disable_ir)
2854 request_module("ir-kbd-i2c");
2855#endif
2856 if (dev->board.has_snapshot_button)
2857 em28xx_register_snapshot_button(dev);
2858
2859 if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { 2806 if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) {
2860 em28xx_errdev("\n\n"); 2807 em28xx_errdev("\n\n");
2861 em28xx_errdev("The support for this board weren't " 2808 em28xx_errdev("The support for this board weren't "
@@ -2929,9 +2876,6 @@ void em28xx_card_setup(struct em28xx *dev)
2929 } 2876 }
2930 2877
2931 em28xx_tuner_setup(dev); 2878 em28xx_tuner_setup(dev);
2932
2933 if(!disable_ir)
2934 em28xx_ir_init(dev);
2935} 2879}
2936 2880
2937 2881
@@ -2948,6 +2892,8 @@ static void request_module_async(struct work_struct *work)
2948 2892
2949 if (dev->board.has_dvb) 2893 if (dev->board.has_dvb)
2950 request_module("em28xx-dvb"); 2894 request_module("em28xx-dvb");
2895 if (dev->board.has_ir_i2c && !disable_ir)
2896 request_module("em28xx-rc");
2951} 2897}
2952 2898
2953static void request_modules(struct em28xx *dev) 2899static void request_modules(struct em28xx *dev)
@@ -2972,12 +2918,6 @@ static void flush_request_modules(struct em28xx *dev)
2972*/ 2918*/
2973void em28xx_release_resources(struct em28xx *dev) 2919void em28xx_release_resources(struct em28xx *dev)
2974{ 2920{
2975 if (dev->sbutton_input_dev)
2976 em28xx_deregister_snapshot_button(dev);
2977
2978 if (dev->ir)
2979 em28xx_ir_fini(dev);
2980
2981 /*FIXME: I2C IR should be disconnected */ 2921 /*FIXME: I2C IR should be disconnected */
2982 2922
2983 em28xx_release_analog_resources(dev); 2923 em28xx_release_analog_resources(dev);
@@ -3005,9 +2945,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3005 dev->udev = udev; 2945 dev->udev = udev;
3006 mutex_init(&dev->ctrl_urb_lock); 2946 mutex_init(&dev->ctrl_urb_lock);
3007 spin_lock_init(&dev->slock); 2947 spin_lock_init(&dev->slock);
3008 init_waitqueue_head(&dev->open);
3009 init_waitqueue_head(&dev->wait_frame);
3010 init_waitqueue_head(&dev->wait_stream);
3011 2948
3012 dev->em28xx_write_regs = em28xx_write_regs; 2949 dev->em28xx_write_regs = em28xx_write_regs;
3013 dev->em28xx_read_reg = em28xx_read_reg; 2950 dev->em28xx_read_reg = em28xx_read_reg;
@@ -3140,9 +3077,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3140 3077
3141 /* init video dma queues */ 3078 /* init video dma queues */
3142 INIT_LIST_HEAD(&dev->vidq.active); 3079 INIT_LIST_HEAD(&dev->vidq.active);
3143 INIT_LIST_HEAD(&dev->vidq.queued);
3144 INIT_LIST_HEAD(&dev->vbiq.active); 3080 INIT_LIST_HEAD(&dev->vbiq.active);
3145 INIT_LIST_HEAD(&dev->vbiq.queued);
3146 3081
3147 if (dev->board.has_msp34xx) { 3082 if (dev->board.has_msp34xx) {
3148 /* Send a reset to other chips via gpio */ 3083 /* Send a reset to other chips via gpio */
@@ -3447,8 +3382,6 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
3447 resources */ 3382 resources */
3448 mutex_lock(&dev->lock); 3383 mutex_lock(&dev->lock);
3449 3384
3450 wake_up_interruptible_all(&dev->open);
3451
3452 v4l2_device_disconnect(&dev->v4l2_dev); 3385 v4l2_device_disconnect(&dev->v4l2_dev);
3453 3386
3454 if (dev->users) { 3387 if (dev->users) {
@@ -3460,8 +3393,6 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
3460 dev->state |= DEV_MISCONFIGURED; 3393 dev->state |= DEV_MISCONFIGURED;
3461 em28xx_uninit_isoc(dev, dev->mode); 3394 em28xx_uninit_isoc(dev, dev->mode);
3462 dev->state |= DEV_DISCONNECTED; 3395 dev->state |= DEV_DISCONNECTED;
3463 wake_up_interruptible(&dev->wait_frame);
3464 wake_up_interruptible(&dev->wait_stream);
3465 } else { 3396 } else {
3466 dev->state |= DEV_DISCONNECTED; 3397 dev->state |= DEV_DISCONNECTED;
3467 em28xx_release_resources(dev); 3398 em28xx_release_resources(dev);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 53a9fb91e97e..5717bdee8f1b 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -139,6 +139,7 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg)
139{ 139{
140 return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg); 140 return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
141} 141}
142EXPORT_SYMBOL_GPL(em28xx_read_reg);
142 143
143/* 144/*
144 * em28xx_write_regs_req() 145 * em28xx_write_regs_req()
@@ -205,6 +206,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
205 206
206 return rc; 207 return rc;
207} 208}
209EXPORT_SYMBOL_GPL(em28xx_write_regs);
208 210
209/* Write a single register */ 211/* Write a single register */
210int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) 212int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val)
@@ -239,6 +241,7 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
239 241
240 return em28xx_write_regs(dev, reg, &newval, 1); 242 return em28xx_write_regs(dev, reg, &newval, 1);
241} 243}
244EXPORT_SYMBOL_GPL(em28xx_write_reg_bits);
242 245
243/* 246/*
244 * em28xx_is_ac97_ready() 247 * em28xx_is_ac97_ready()
@@ -666,7 +669,6 @@ int em28xx_capture_start(struct em28xx *dev, int start)
666 669
667 return rc; 670 return rc;
668} 671}
669EXPORT_SYMBOL_GPL(em28xx_capture_start);
670 672
671int em28xx_vbi_supported(struct em28xx *dev) 673int em28xx_vbi_supported(struct em28xx *dev)
672{ 674{
@@ -975,7 +977,6 @@ void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode)
975 else 977 else
976 isoc_bufs = &dev->isoc_ctl.analog_bufs; 978 isoc_bufs = &dev->isoc_ctl.analog_bufs;
977 979
978 dev->isoc_ctl.nfields = -1;
979 for (i = 0; i < isoc_bufs->num_bufs; i++) { 980 for (i = 0; i < isoc_bufs->num_bufs; i++) {
980 urb = isoc_bufs->urb[i]; 981 urb = isoc_bufs->urb[i];
981 if (urb) { 982 if (urb) {
@@ -1008,6 +1009,31 @@ void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode)
1008EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); 1009EXPORT_SYMBOL_GPL(em28xx_uninit_isoc);
1009 1010
1010/* 1011/*
1012 * Stop URBs
1013 */
1014void em28xx_stop_urbs(struct em28xx *dev)
1015{
1016 int i;
1017 struct urb *urb;
1018 struct em28xx_usb_isoc_bufs *isoc_bufs = &dev->isoc_ctl.digital_bufs;
1019
1020 em28xx_isocdbg("em28xx: called em28xx_stop_urbs\n");
1021
1022 for (i = 0; i < isoc_bufs->num_bufs; i++) {
1023 urb = isoc_bufs->urb[i];
1024 if (urb) {
1025 if (!irqs_disabled())
1026 usb_kill_urb(urb);
1027 else
1028 usb_unlink_urb(urb);
1029 }
1030 }
1031
1032 em28xx_capture_start(dev, 0);
1033}
1034EXPORT_SYMBOL_GPL(em28xx_stop_urbs);
1035
1036/*
1011 * Allocate URBs 1037 * Allocate URBs
1012 */ 1038 */
1013int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode, 1039int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode,
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 503a8d5b5382..16410ac20092 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -183,7 +183,7 @@ static int em28xx_stop_streaming(struct em28xx_dvb *dvb)
183{ 183{
184 struct em28xx *dev = dvb->adapter.priv; 184 struct em28xx *dev = dvb->adapter.priv;
185 185
186 em28xx_capture_start(dev, 0); 186 em28xx_stop_urbs(dev);
187 187
188 em28xx_set_mode(dev, EM28XX_SUSPEND); 188 em28xx_set_mode(dev, EM28XX_SUSPEND);
189 189
@@ -336,6 +336,8 @@ struct drxk_config pctv_520e_drxk = {
336 .single_master = 1, 336 .single_master = 1,
337 .microcode_name = "dvb-demod-drxk-pctv.fw", 337 .microcode_name = "dvb-demod-drxk-pctv.fw",
338 .chunk_size = 58, 338 .chunk_size = 58,
339 .antenna_dvbt = true, /* disable LNA */
340 .antenna_gpio = (1 << 2), /* disable LNA */
339}; 341};
340 342
341static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 343static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
@@ -474,8 +476,8 @@ static void terratec_h5_init(struct em28xx *dev)
474static void pctv_520e_init(struct em28xx *dev) 476static void pctv_520e_init(struct em28xx *dev)
475{ 477{
476 /* 478 /*
477 * Init TDA8295(?) analog demodulator. Looks like I2C traffic to 479 * Init AVF4910B analog decoder. Looks like I2C traffic to
478 * digital demodulator and tuner are routed via TDA8295. 480 * digital demodulator and tuner are routed via AVF4910B.
479 */ 481 */
480 int i; 482 int i;
481 struct { 483 struct {
@@ -542,7 +544,8 @@ static struct cxd2820r_config em28xx_cxd2820r_config = {
542 .i2c_address = (0xd8 >> 1), 544 .i2c_address = (0xd8 >> 1),
543 .ts_mode = CXD2820R_TS_SERIAL, 545 .ts_mode = CXD2820R_TS_SERIAL,
544 546
545 /* enable LNA for DVB-T2 and DVB-C */ 547 /* enable LNA for DVB-T, DVB-T2 and DVB-C */
548 .gpio_dvbt[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
546 .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, 549 .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
547 .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, 550 .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
548}; 551};
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index a88e169dba23..185db65b766e 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -553,9 +553,6 @@ int em28xx_i2c_register(struct em28xx *dev)
553 if (i2c_scan) 553 if (i2c_scan)
554 em28xx_do_i2c_scan(dev); 554 em28xx_do_i2c_scan(dev);
555 555
556 /* Instantiate the IR receiver device, if present */
557 em28xx_register_i2c_ir(dev);
558
559 return 0; 556 return 0;
560} 557}
561 558
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 2630b265b0e8..fce5f7680c99 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -80,7 +80,7 @@ struct em28xx_IR {
80 I2C IR based get keycodes - should be used with ir-kbd-i2c 80 I2C IR based get keycodes - should be used with ir-kbd-i2c
81 **********************************************************/ 81 **********************************************************/
82 82
83int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 83static int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
84{ 84{
85 unsigned char b; 85 unsigned char b;
86 86
@@ -108,7 +108,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
108 return 1; 108 return 1;
109} 109}
110 110
111int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 111static int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
112{ 112{
113 unsigned char buf[2]; 113 unsigned char buf[2];
114 u16 code; 114 u16 code;
@@ -157,7 +157,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
157 return 1; 157 return 1;
158} 158}
159 159
160int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, 160static int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
161 u32 *ir_raw) 161 u32 *ir_raw)
162{ 162{
163 unsigned char buf[3]; 163 unsigned char buf[3];
@@ -179,7 +179,8 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
179 return 1; 179 return 1;
180} 180}
181 181
182int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 182static int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
183 u32 *ir_raw)
183{ 184{
184 unsigned char subaddr, keydetect, key; 185 unsigned char subaddr, keydetect, key;
185 186
@@ -387,7 +388,138 @@ int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
387 return rc; 388 return rc;
388} 389}
389 390
390int em28xx_ir_init(struct em28xx *dev) 391static void em28xx_register_i2c_ir(struct em28xx *dev)
392{
393 /* Leadtek winfast tv USBII deluxe can find a non working IR-device */
394 /* at address 0x18, so if that address is needed for another board in */
395 /* the future, please put it after 0x1f. */
396 struct i2c_board_info info;
397 const unsigned short addr_list[] = {
398 0x1f, 0x30, 0x47, I2C_CLIENT_END
399 };
400
401 memset(&info, 0, sizeof(struct i2c_board_info));
402 memset(&dev->init_data, 0, sizeof(dev->init_data));
403 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
404
405 /* detect & configure */
406 switch (dev->model) {
407 case EM2800_BOARD_TERRATEC_CINERGY_200:
408 case EM2820_BOARD_TERRATEC_CINERGY_250:
409 dev->init_data.ir_codes = RC_MAP_EM_TERRATEC;
410 dev->init_data.get_key = em28xx_get_key_terratec;
411 dev->init_data.name = "i2c IR (EM28XX Terratec)";
412 break;
413 case EM2820_BOARD_PINNACLE_USB_2:
414 dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
415 dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
416 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
417 break;
418 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
419 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
420 dev->init_data.get_key = em28xx_get_key_em_haup;
421 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
422 break;
423 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
424 dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
425 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
426 dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
427 break;
428 }
429
430 if (dev->init_data.name)
431 info.platform_data = &dev->init_data;
432 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL);
433}
434
435/**********************************************************
436 Handle Webcam snapshot button
437 **********************************************************/
438
439static void em28xx_query_sbutton(struct work_struct *work)
440{
441 /* Poll the register and see if the button is depressed */
442 struct em28xx *dev =
443 container_of(work, struct em28xx, sbutton_query_work.work);
444 int ret;
445
446 ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP);
447
448 if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) {
449 u8 cleared;
450 /* Button is depressed, clear the register */
451 cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT;
452 em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1);
453
454 /* Not emulate the keypress */
455 input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
456 1);
457 /* Now unpress the key */
458 input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
459 0);
460 }
461
462 /* Schedule next poll */
463 schedule_delayed_work(&dev->sbutton_query_work,
464 msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
465}
466
467static void em28xx_register_snapshot_button(struct em28xx *dev)
468{
469 struct input_dev *input_dev;
470 int err;
471
472 em28xx_info("Registering snapshot button...\n");
473 input_dev = input_allocate_device();
474 if (!input_dev) {
475 em28xx_errdev("input_allocate_device failed\n");
476 return;
477 }
478
479 usb_make_path(dev->udev, dev->snapshot_button_path,
480 sizeof(dev->snapshot_button_path));
481 strlcat(dev->snapshot_button_path, "/sbutton",
482 sizeof(dev->snapshot_button_path));
483 INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);
484
485 input_dev->name = "em28xx snapshot button";
486 input_dev->phys = dev->snapshot_button_path;
487 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
488 set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit);
489 input_dev->keycodesize = 0;
490 input_dev->keycodemax = 0;
491 input_dev->id.bustype = BUS_USB;
492 input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
493 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
494 input_dev->id.version = 1;
495 input_dev->dev.parent = &dev->udev->dev;
496
497 err = input_register_device(input_dev);
498 if (err) {
499 em28xx_errdev("input_register_device failed\n");
500 input_free_device(input_dev);
501 return;
502 }
503
504 dev->sbutton_input_dev = input_dev;
505 schedule_delayed_work(&dev->sbutton_query_work,
506 msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
507 return;
508
509}
510
511static void em28xx_deregister_snapshot_button(struct em28xx *dev)
512{
513 if (dev->sbutton_input_dev != NULL) {
514 em28xx_info("Deregistering snapshot button\n");
515 cancel_delayed_work_sync(&dev->sbutton_query_work);
516 input_unregister_device(dev->sbutton_input_dev);
517 dev->sbutton_input_dev = NULL;
518 }
519 return;
520}
521
522static int em28xx_ir_init(struct em28xx *dev)
391{ 523{
392 struct em28xx_IR *ir; 524 struct em28xx_IR *ir;
393 struct rc_dev *rc; 525 struct rc_dev *rc;
@@ -448,6 +580,15 @@ int em28xx_ir_init(struct em28xx *dev)
448 if (err) 580 if (err)
449 goto err_out_stop; 581 goto err_out_stop;
450 582
583 em28xx_register_i2c_ir(dev);
584
585#if defined(CONFIG_MODULES) && defined(MODULE)
586 if (dev->board.has_ir_i2c)
587 request_module("ir-kbd-i2c");
588#endif
589 if (dev->board.has_snapshot_button)
590 em28xx_register_snapshot_button(dev);
591
451 return 0; 592 return 0;
452 593
453 err_out_stop: 594 err_out_stop:
@@ -458,10 +599,12 @@ int em28xx_ir_init(struct em28xx *dev)
458 return err; 599 return err;
459} 600}
460 601
461int em28xx_ir_fini(struct em28xx *dev) 602static int em28xx_ir_fini(struct em28xx *dev)
462{ 603{
463 struct em28xx_IR *ir = dev->ir; 604 struct em28xx_IR *ir = dev->ir;
464 605
606 em28xx_deregister_snapshot_button(dev);
607
465 /* skip detach on non attached boards */ 608 /* skip detach on non attached boards */
466 if (!ir) 609 if (!ir)
467 return 0; 610 return 0;
@@ -475,89 +618,26 @@ int em28xx_ir_fini(struct em28xx *dev)
475 return 0; 618 return 0;
476} 619}
477 620
478/********************************************************** 621static struct em28xx_ops rc_ops = {
479 Handle Webcam snapshot button 622 .id = EM28XX_RC,
480 **********************************************************/ 623 .name = "Em28xx Input Extension",
624 .init = em28xx_ir_init,
625 .fini = em28xx_ir_fini,
626};
481 627
482static void em28xx_query_sbutton(struct work_struct *work) 628static int __init em28xx_rc_register(void)
483{ 629{
484 /* Poll the register and see if the button is depressed */ 630 return em28xx_register_extension(&rc_ops);
485 struct em28xx *dev =
486 container_of(work, struct em28xx, sbutton_query_work.work);
487 int ret;
488
489 ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP);
490
491 if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) {
492 u8 cleared;
493 /* Button is depressed, clear the register */
494 cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT;
495 em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1);
496
497 /* Not emulate the keypress */
498 input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
499 1);
500 /* Now unpress the key */
501 input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
502 0);
503 }
504
505 /* Schedule next poll */
506 schedule_delayed_work(&dev->sbutton_query_work,
507 msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
508} 631}
509 632
510void em28xx_register_snapshot_button(struct em28xx *dev) 633static void __exit em28xx_rc_unregister(void)
511{ 634{
512 struct input_dev *input_dev; 635 em28xx_unregister_extension(&rc_ops);
513 int err;
514
515 em28xx_info("Registering snapshot button...\n");
516 input_dev = input_allocate_device();
517 if (!input_dev) {
518 em28xx_errdev("input_allocate_device failed\n");
519 return;
520 }
521
522 usb_make_path(dev->udev, dev->snapshot_button_path,
523 sizeof(dev->snapshot_button_path));
524 strlcat(dev->snapshot_button_path, "/sbutton",
525 sizeof(dev->snapshot_button_path));
526 INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);
527
528 input_dev->name = "em28xx snapshot button";
529 input_dev->phys = dev->snapshot_button_path;
530 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
531 set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit);
532 input_dev->keycodesize = 0;
533 input_dev->keycodemax = 0;
534 input_dev->id.bustype = BUS_USB;
535 input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
536 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
537 input_dev->id.version = 1;
538 input_dev->dev.parent = &dev->udev->dev;
539
540 err = input_register_device(input_dev);
541 if (err) {
542 em28xx_errdev("input_register_device failed\n");
543 input_free_device(input_dev);
544 return;
545 }
546
547 dev->sbutton_input_dev = input_dev;
548 schedule_delayed_work(&dev->sbutton_query_work,
549 msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
550 return;
551
552} 636}
553 637
554void em28xx_deregister_snapshot_button(struct em28xx *dev) 638MODULE_LICENSE("GPL");
555{ 639MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
556 if (dev->sbutton_input_dev != NULL) { 640MODULE_DESCRIPTION("Em28xx Input driver");
557 em28xx_info("Deregistering snapshot button\n"); 641
558 cancel_delayed_work_sync(&dev->sbutton_query_work); 642module_init(em28xx_rc_register);
559 input_unregister_device(dev->sbutton_input_dev); 643module_exit(em28xx_rc_unregister);
560 dev->sbutton_input_dev = NULL;
561 }
562 return;
563}
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 324b695c0724..50f5f4fc2148 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1305,9 +1305,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1305 if (0 == INPUT(i)->type) 1305 if (0 == INPUT(i)->type)
1306 return -EINVAL; 1306 return -EINVAL;
1307 1307
1308 dev->ctl_input = i; 1308 video_mux(dev, i);
1309
1310 video_mux(dev, dev->ctl_input);
1311 return 0; 1309 return 0;
1312} 1310}
1313 1311
@@ -2262,6 +2260,7 @@ static int em28xx_v4l2_close(struct file *filp)
2262 em28xx_release_resources(dev); 2260 em28xx_release_resources(dev);
2263 kfree(dev->alt_max_pkt_size); 2261 kfree(dev->alt_max_pkt_size);
2264 kfree(dev); 2262 kfree(dev);
2263 kfree(fh);
2265 return 0; 2264 return 0;
2266 } 2265 }
2267 2266
@@ -2286,7 +2285,6 @@ static int em28xx_v4l2_close(struct file *filp)
2286 videobuf_mmap_free(&fh->vb_vbiq); 2285 videobuf_mmap_free(&fh->vb_vbiq);
2287 kfree(fh); 2286 kfree(fh);
2288 dev->users--; 2287 dev->users--;
2289 wake_up_interruptible_nr(&dev->open, 1);
2290 return 0; 2288 return 0;
2291} 2289}
2292 2290
@@ -2497,6 +2495,10 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
2497 vfd->release = video_device_release; 2495 vfd->release = video_device_release;
2498 vfd->debug = video_debug; 2496 vfd->debug = video_debug;
2499 vfd->lock = &dev->lock; 2497 vfd->lock = &dev->lock;
2498 /* Locking in file operations other than ioctl should be done
2499 by the driver, not the V4L2 core.
2500 This driver needs auditing so that this flag can be removed. */
2501 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
2500 2502
2501 snprintf(vfd->name, sizeof(vfd->name), "%s %s", 2503 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
2502 dev->name, type_name); 2504 dev->name, type_name);
@@ -2518,7 +2520,6 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2518 dev->norm = em28xx_video_template.current_norm; 2520 dev->norm = em28xx_video_template.current_norm;
2519 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); 2521 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
2520 dev->interlaced = EM28XX_INTERLACED_DEFAULT; 2522 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
2521 dev->ctl_input = 0;
2522 2523
2523 /* Analog specific initialization */ 2524 /* Analog specific initialization */
2524 dev->format = &format[0]; 2525 dev->format = &format[0];
@@ -2532,7 +2533,7 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2532 em28xx_set_video_format(dev, format[0].fourcc, 2533 em28xx_set_video_format(dev, format[0].fourcc,
2533 maxw, norm_maxh(dev)); 2534 maxw, norm_maxh(dev));
2534 2535
2535 video_mux(dev, dev->ctl_input); 2536 video_mux(dev, 0);
2536 2537
2537 /* Audio defaults */ 2538 /* Audio defaults */
2538 dev->mute = 1; 2539 dev->mute = 1;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 2868b19f8b54..8757523e6863 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -226,24 +226,10 @@ struct em28xx_usb_isoc_ctl {
226 /* isoc transfer buffers for digital mode */ 226 /* isoc transfer buffers for digital mode */
227 struct em28xx_usb_isoc_bufs digital_bufs; 227 struct em28xx_usb_isoc_bufs digital_bufs;
228 228
229 /* Last buffer command and region */
230 u8 cmd;
231 int pos, size, pktsize;
232
233 /* Last field: ODD or EVEN? */
234 int field;
235
236 /* Stores incomplete commands */
237 u32 tmp_buf;
238 int tmp_buf_len;
239
240 /* Stores already requested buffers */ 229 /* Stores already requested buffers */
241 struct em28xx_buffer *vid_buf; 230 struct em28xx_buffer *vid_buf;
242 struct em28xx_buffer *vbi_buf; 231 struct em28xx_buffer *vbi_buf;
243 232
244 /* Stores the number of received fields */
245 int nfields;
246
247 /* isoc urb callback */ 233 /* isoc urb callback */
248 int (*isoc_copy) (struct em28xx *dev, struct urb *urb); 234 int (*isoc_copy) (struct em28xx *dev, struct urb *urb);
249 235
@@ -264,12 +250,10 @@ struct em28xx_buffer {
264 250
265 struct list_head frame; 251 struct list_head frame;
266 int top_field; 252 int top_field;
267 int receiving;
268}; 253};
269 254
270struct em28xx_dmaqueue { 255struct em28xx_dmaqueue {
271 struct list_head active; 256 struct list_head active;
272 struct list_head queued;
273 257
274 wait_queue_head_t wq; 258 wait_queue_head_t wq;
275 259
@@ -277,13 +261,6 @@ struct em28xx_dmaqueue {
277 int pos; 261 int pos;
278}; 262};
279 263
280/* io methods */
281enum em28xx_io_method {
282 IO_NONE,
283 IO_READ,
284 IO_MMAP,
285};
286
287/* inputs */ 264/* inputs */
288 265
289#define MAX_EM28XX_INPUT 4 266#define MAX_EM28XX_INPUT 4
@@ -467,6 +444,7 @@ enum em28xx_dev_state {
467/* em28xx extensions */ 444/* em28xx extensions */
468#define EM28XX_AUDIO 0x10 445#define EM28XX_AUDIO 0x10
469#define EM28XX_DVB 0x20 446#define EM28XX_DVB 0x20
447#define EM28XX_RC 0x30
470 448
471/* em28xx resource types (used for res_get/res_lock etc */ 449/* em28xx resource types (used for res_get/res_lock etc */
472#define EM28XX_RESOURCE_VIDEO 0x01 450#define EM28XX_RESOURCE_VIDEO 0x01
@@ -577,7 +555,6 @@ struct em28xx {
577 555
578 /* states */ 556 /* states */
579 enum em28xx_dev_state state; 557 enum em28xx_dev_state state;
580 enum em28xx_io_method io;
581 558
582 /* vbi related state tracking */ 559 /* vbi related state tracking */
583 int capture_type; 560 int capture_type;
@@ -593,7 +570,6 @@ struct em28xx {
593 struct mutex ctrl_urb_lock; /* protects urb_buf */ 570 struct mutex ctrl_urb_lock; /* protects urb_buf */
594 /* spinlock_t queue_lock; */ 571 /* spinlock_t queue_lock; */
595 struct list_head inqueue, outqueue; 572 struct list_head inqueue, outqueue;
596 wait_queue_head_t open, wait_frame, wait_stream;
597 struct video_device *vbi_dev; 573 struct video_device *vbi_dev;
598 struct video_device *radio_dev; 574 struct video_device *radio_dev;
599 575
@@ -695,6 +671,7 @@ int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode,
695 int max_packets, int num_bufs, int max_pkt_size, 671 int max_packets, int num_bufs, int max_pkt_size,
696 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); 672 int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
697void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode); 673void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode);
674void em28xx_stop_urbs(struct em28xx *dev);
698int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); 675int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
699int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 676int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
700int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); 677int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
@@ -710,45 +687,12 @@ void em28xx_release_analog_resources(struct em28xx *dev);
710 687
711/* Provided by em28xx-cards.c */ 688/* Provided by em28xx-cards.c */
712extern int em2800_variant_detect(struct usb_device *udev, int model); 689extern int em2800_variant_detect(struct usb_device *udev, int model);
713extern void em28xx_pre_card_setup(struct em28xx *dev);
714extern void em28xx_card_setup(struct em28xx *dev);
715extern struct em28xx_board em28xx_boards[]; 690extern struct em28xx_board em28xx_boards[];
716extern struct usb_device_id em28xx_id_table[]; 691extern struct usb_device_id em28xx_id_table[];
717extern const unsigned int em28xx_bcount; 692extern const unsigned int em28xx_bcount;
718void em28xx_register_i2c_ir(struct em28xx *dev);
719int em28xx_tuner_callback(void *ptr, int component, int command, int arg); 693int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
720void em28xx_release_resources(struct em28xx *dev); 694void em28xx_release_resources(struct em28xx *dev);
721 695
722/* Provided by em28xx-input.c */
723
724#ifdef CONFIG_VIDEO_EM28XX_RC
725
726int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
727int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
728int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
729 u32 *ir_raw);
730int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
731 u32 *ir_raw);
732void em28xx_register_snapshot_button(struct em28xx *dev);
733void em28xx_deregister_snapshot_button(struct em28xx *dev);
734
735int em28xx_ir_init(struct em28xx *dev);
736int em28xx_ir_fini(struct em28xx *dev);
737
738#else
739
740#define em28xx_get_key_terratec NULL
741#define em28xx_get_key_em_haup NULL
742#define em28xx_get_key_pinnacle_usb_grey NULL
743#define em28xx_get_key_winfast_usbii_deluxe NULL
744
745static inline void em28xx_register_snapshot_button(struct em28xx *dev) {}
746static inline void em28xx_deregister_snapshot_button(struct em28xx *dev) {}
747static inline int em28xx_ir_init(struct em28xx *dev) { return 0; }
748static inline int em28xx_ir_fini(struct em28xx *dev) { return 0; }
749
750#endif
751
752/* Provided by em28xx-vbi.c */ 696/* Provided by em28xx-vbi.c */
753extern struct videobuf_queue_ops em28xx_vbi_qops; 697extern struct videobuf_queue_ops em28xx_vbi_qops;
754 698
diff --git a/drivers/media/video/et61x251/Kconfig b/drivers/media/video/et61x251/Kconfig
deleted file mode 100644
index 87981b078fe6..000000000000
--- a/drivers/media/video/et61x251/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
1config USB_ET61X251
2 tristate "USB ET61X[12]51 PC Camera Controller support (DEPRECATED)"
3 depends on VIDEO_V4L2
4 default n
5 ---help---
6 This driver is DEPRECATED please use the gspca zc3xx module
7 instead.
8
9 Say Y here if you want support for cameras based on Etoms ET61X151
10 or ET61X251 PC Camera Controllers.
11
12 See <file:Documentation/video4linux/et61x251.txt> for more info.
13
14 This driver uses the Video For Linux API. You must say Y or M to
15 "Video For Linux" to use this driver.
16
17 To compile this driver as a module, choose M here: the
18 module will be called et61x251.
diff --git a/drivers/media/video/et61x251/Makefile b/drivers/media/video/et61x251/Makefile
deleted file mode 100644
index 2ff4db9ec882..000000000000
--- a/drivers/media/video/et61x251/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
1et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
2
3obj-$(CONFIG_USB_ET61X251) += et61x251.o
4
diff --git a/drivers/media/video/et61x251/et61x251.h b/drivers/media/video/et61x251/et61x251.h
deleted file mode 100644
index 337ded4a6388..000000000000
--- a/drivers/media/video/et61x251/et61x251.h
+++ /dev/null
@@ -1,213 +0,0 @@
1/***************************************************************************
2 * V4L2 driver for ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
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#ifndef _ET61X251_H_
22#define _ET61X251_H_
23
24#include <linux/usb.h>
25#include <linux/videodev2.h>
26#include <media/v4l2-common.h>
27#include <linux/device.h>
28#include <linux/list.h>
29#include <linux/spinlock.h>
30#include <linux/time.h>
31#include <linux/wait.h>
32#include <linux/types.h>
33#include <linux/param.h>
34#include <linux/rwsem.h>
35#include <linux/mutex.h>
36#include <linux/stddef.h>
37#include <linux/string.h>
38#include <linux/kref.h>
39
40#include "et61x251_sensor.h"
41
42/*****************************************************************************/
43
44#define ET61X251_DEBUG
45#define ET61X251_DEBUG_LEVEL 2
46#define ET61X251_MAX_DEVICES 64
47#define ET61X251_PRESERVE_IMGSCALE 0
48#define ET61X251_FORCE_MUNMAP 0
49#define ET61X251_MAX_FRAMES 32
50#define ET61X251_COMPRESSION_QUALITY 0
51#define ET61X251_URBS 2
52#define ET61X251_ISO_PACKETS 7
53#define ET61X251_ALTERNATE_SETTING 13
54#define ET61X251_URB_TIMEOUT msecs_to_jiffies(2 * ET61X251_ISO_PACKETS)
55#define ET61X251_CTRL_TIMEOUT 100
56#define ET61X251_FRAME_TIMEOUT 2
57
58/*****************************************************************************/
59
60static const struct usb_device_id et61x251_id_table[] = {
61 { USB_DEVICE(0x102c, 0x6251), },
62 { }
63};
64
65ET61X251_SENSOR_TABLE
66
67/*****************************************************************************/
68
69enum et61x251_frame_state {
70 F_UNUSED,
71 F_QUEUED,
72 F_GRABBING,
73 F_DONE,
74 F_ERROR,
75};
76
77struct et61x251_frame_t {
78 void* bufmem;
79 struct v4l2_buffer buf;
80 enum et61x251_frame_state state;
81 struct list_head frame;
82 unsigned long vma_use_count;
83};
84
85enum et61x251_dev_state {
86 DEV_INITIALIZED = 0x01,
87 DEV_DISCONNECTED = 0x02,
88 DEV_MISCONFIGURED = 0x04,
89};
90
91enum et61x251_io_method {
92 IO_NONE,
93 IO_READ,
94 IO_MMAP,
95};
96
97enum et61x251_stream_state {
98 STREAM_OFF,
99 STREAM_INTERRUPT,
100 STREAM_ON,
101};
102
103struct et61x251_sysfs_attr {
104 u8 reg, i2c_reg;
105};
106
107struct et61x251_module_param {
108 u8 force_munmap;
109 u16 frame_timeout;
110};
111
112static DEFINE_MUTEX(et61x251_sysfs_lock);
113static DECLARE_RWSEM(et61x251_dev_lock);
114
115struct et61x251_device {
116 struct video_device* v4ldev;
117
118 struct et61x251_sensor sensor;
119
120 struct usb_device* usbdev;
121 struct urb* urb[ET61X251_URBS];
122 void* transfer_buffer[ET61X251_URBS];
123 u8* control_buffer;
124
125 struct et61x251_frame_t *frame_current, frame[ET61X251_MAX_FRAMES];
126 struct list_head inqueue, outqueue;
127 u32 frame_count, nbuffers, nreadbuffers;
128
129 enum et61x251_io_method io;
130 enum et61x251_stream_state stream;
131
132 struct v4l2_jpegcompression compression;
133
134 struct et61x251_sysfs_attr sysfs;
135 struct et61x251_module_param module_param;
136
137 struct kref kref;
138 enum et61x251_dev_state state;
139 u8 users;
140
141 struct completion probe;
142 struct mutex open_mutex, fileop_mutex;
143 spinlock_t queue_lock;
144 wait_queue_head_t wait_open, wait_frame, wait_stream;
145};
146
147/*****************************************************************************/
148
149struct et61x251_device*
150et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id)
151{
152 return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
153}
154
155
156void
157et61x251_attach_sensor(struct et61x251_device* cam,
158 const struct et61x251_sensor* sensor)
159{
160 memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor));
161}
162
163/*****************************************************************************/
164
165#undef DBG
166#undef KDBG
167#ifdef ET61X251_DEBUG
168#define DBG(level, fmt, ...) \
169do { \
170 if (debug >= (level)) { \
171 if ((level) == 1) \
172 dev_err(&cam->usbdev->dev, fmt "\n", \
173 ##__VA_ARGS__); \
174 else if ((level) == 2) \
175 dev_info(&cam->usbdev->dev, fmt "\n", \
176 ##__VA_ARGS__); \
177 else if ((level) >= 3) \
178 dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \
179 __FILE__, __func__, __LINE__, \
180 ##__VA_ARGS__); \
181 } \
182} while (0)
183#define KDBG(level, fmt, ...) \
184do { \
185 if (debug >= (level)) { \
186 if ((level) == 1 || (level) == 2) \
187 pr_info(fmt "\n", ##__VA_ARGS__); \
188 else if ((level) == 3) \
189 pr_debug("[%s:%s:%d] " fmt "\n", \
190 __FILE__, __func__, __LINE__, \
191 ##__VA_ARGS__); \
192 } \
193} while (0)
194#define V4LDBG(level, name, cmd) \
195do { \
196 if (debug >= (level)) \
197 v4l_print_ioctl(name, cmd); \
198} while (0)
199#else
200#define DBG(level, fmt, ...) do {;} while(0)
201#define KDBG(level, fmt, ...) do {;} while(0)
202#define V4LDBG(level, name, cmd) do {;} while(0)
203#endif
204
205#undef PDBG
206#define PDBG(fmt, ...) \
207 dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \
208 __FILE__, __func__, __LINE__, ##__VA_ARGS__)
209
210#undef PDBGG
211#define PDBGG(fmt, args...) do {;} while (0) /* placeholder */
212
213#endif /* _ET61X251_H_ */
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
deleted file mode 100644
index 5539f09440ac..000000000000
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ /dev/null
@@ -1,2683 +0,0 @@
1/***************************************************************************
2 * V4L2 driver for ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/version.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/kernel.h>
27#include <linux/param.h>
28#include <linux/errno.h>
29#include <linux/slab.h>
30#include <linux/device.h>
31#include <linux/fs.h>
32#include <linux/delay.h>
33#include <linux/compiler.h>
34#include <linux/ioctl.h>
35#include <linux/poll.h>
36#include <linux/stat.h>
37#include <linux/mm.h>
38#include <linux/vmalloc.h>
39#include <linux/page-flags.h>
40#include <media/v4l2-ioctl.h>
41#include <asm/byteorder.h>
42#include <asm/page.h>
43#include <asm/uaccess.h>
44
45#include "et61x251.h"
46
47/*****************************************************************************/
48
49#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \
50 "PC Camera Controllers"
51#define ET61X251_MODULE_AUTHOR "(C) 2006-2007 Luca Risolia"
52#define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
53#define ET61X251_MODULE_LICENSE "GPL"
54#define ET61X251_MODULE_VERSION "1.1.10"
55
56/*****************************************************************************/
57
58MODULE_DEVICE_TABLE(usb, et61x251_id_table);
59
60MODULE_AUTHOR(ET61X251_MODULE_AUTHOR " " ET61X251_AUTHOR_EMAIL);
61MODULE_DESCRIPTION(ET61X251_MODULE_NAME);
62MODULE_VERSION(ET61X251_MODULE_VERSION);
63MODULE_LICENSE(ET61X251_MODULE_LICENSE);
64
65static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
66module_param_array(video_nr, short, NULL, 0444);
67MODULE_PARM_DESC(video_nr,
68 "\n<-1|n[,...]> Specify V4L2 minor mode number."
69 "\n -1 = use next available (default)"
70 "\n n = use minor number n (integer >= 0)"
71 "\nYou can specify up to "
72 __MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
73 "\nFor example:"
74 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
75 "\nthe second registered camera and use auto for the first"
76 "\none and for every other camera."
77 "\n");
78
79static bool force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
80 ET61X251_FORCE_MUNMAP};
81module_param_array(force_munmap, bool, NULL, 0444);
82MODULE_PARM_DESC(force_munmap,
83 "\n<0|1[,...]> Force the application to unmap previously"
84 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
85 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
86 "\nthis feature. This parameter is specific for each"
87 "\ndetected camera."
88 "\n 0 = do not force memory unmapping"
89 "\n 1 = force memory unmapping (save memory)"
90 "\nDefault value is "__MODULE_STRING(ET61X251_FORCE_MUNMAP)"."
91 "\n");
92
93static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] =
94 ET61X251_FRAME_TIMEOUT};
95module_param_array(frame_timeout, uint, NULL, 0644);
96MODULE_PARM_DESC(frame_timeout,
97 "\n<n[,...]> Timeout for a video frame in seconds."
98 "\nThis parameter is specific for each detected camera."
99 "\nDefault value is "
100 __MODULE_STRING(ET61X251_FRAME_TIMEOUT)"."
101 "\n");
102
103#ifdef ET61X251_DEBUG
104static unsigned short debug = ET61X251_DEBUG_LEVEL;
105module_param(debug, ushort, 0644);
106MODULE_PARM_DESC(debug,
107 "\n<n> Debugging information level, from 0 to 3:"
108 "\n0 = none (use carefully)"
109 "\n1 = critical errors"
110 "\n2 = significant informations"
111 "\n3 = more verbose messages"
112 "\nLevel 3 is useful for testing only, when only "
113 "one device is used."
114 "\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
115 "\n");
116#endif
117
118/*****************************************************************************/
119
120static u32
121et61x251_request_buffers(struct et61x251_device* cam, u32 count,
122 enum et61x251_io_method io)
123{
124 struct v4l2_pix_format* p = &(cam->sensor.pix_format);
125 struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
126 const size_t imagesize = cam->module_param.force_munmap ||
127 io == IO_READ ?
128 (p->width * p->height * p->priv) / 8 :
129 (r->width * r->height * p->priv) / 8;
130 void* buff = NULL;
131 u32 i;
132
133 if (count > ET61X251_MAX_FRAMES)
134 count = ET61X251_MAX_FRAMES;
135
136 cam->nbuffers = count;
137 while (cam->nbuffers > 0) {
138 if ((buff = vmalloc_32_user(cam->nbuffers *
139 PAGE_ALIGN(imagesize))))
140 break;
141 cam->nbuffers--;
142 }
143
144 for (i = 0; i < cam->nbuffers; i++) {
145 cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
146 cam->frame[i].buf.index = i;
147 cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
148 cam->frame[i].buf.length = imagesize;
149 cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
150 cam->frame[i].buf.sequence = 0;
151 cam->frame[i].buf.field = V4L2_FIELD_NONE;
152 cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
153 cam->frame[i].buf.flags = 0;
154 }
155
156 return cam->nbuffers;
157}
158
159
160static void et61x251_release_buffers(struct et61x251_device* cam)
161{
162 if (cam->nbuffers) {
163 vfree(cam->frame[0].bufmem);
164 cam->nbuffers = 0;
165 }
166 cam->frame_current = NULL;
167}
168
169
170static void et61x251_empty_framequeues(struct et61x251_device* cam)
171{
172 u32 i;
173
174 INIT_LIST_HEAD(&cam->inqueue);
175 INIT_LIST_HEAD(&cam->outqueue);
176
177 for (i = 0; i < ET61X251_MAX_FRAMES; i++) {
178 cam->frame[i].state = F_UNUSED;
179 cam->frame[i].buf.bytesused = 0;
180 }
181}
182
183
184static void et61x251_requeue_outqueue(struct et61x251_device* cam)
185{
186 struct et61x251_frame_t *i;
187
188 list_for_each_entry(i, &cam->outqueue, frame) {
189 i->state = F_QUEUED;
190 list_add(&i->frame, &cam->inqueue);
191 }
192
193 INIT_LIST_HEAD(&cam->outqueue);
194}
195
196
197static void et61x251_queue_unusedframes(struct et61x251_device* cam)
198{
199 unsigned long lock_flags;
200 u32 i;
201
202 for (i = 0; i < cam->nbuffers; i++)
203 if (cam->frame[i].state == F_UNUSED) {
204 cam->frame[i].state = F_QUEUED;
205 spin_lock_irqsave(&cam->queue_lock, lock_flags);
206 list_add_tail(&cam->frame[i].frame, &cam->inqueue);
207 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
208 }
209}
210
211/*****************************************************************************/
212
213int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index)
214{
215 struct usb_device* udev = cam->usbdev;
216 u8* buff = cam->control_buffer;
217 int res;
218
219 *buff = value;
220
221 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
222 0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
223 if (res < 0) {
224 DBG(3, "Failed to write a register (value 0x%02X, index "
225 "0x%02X, error %d)", value, index, res);
226 return -1;
227 }
228
229 return 0;
230}
231
232
233static int et61x251_read_reg(struct et61x251_device* cam, u16 index)
234{
235 struct usb_device* udev = cam->usbdev;
236 u8* buff = cam->control_buffer;
237 int res;
238
239 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
240 0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
241 if (res < 0)
242 DBG(3, "Failed to read a register (index 0x%02X, error %d)",
243 index, res);
244
245 return (res >= 0) ? (int)(*buff) : -1;
246}
247
248
249static int
250et61x251_i2c_wait(struct et61x251_device* cam,
251 const struct et61x251_sensor* sensor)
252{
253 int i, r;
254
255 for (i = 1; i <= 8; i++) {
256 if (sensor->interface == ET61X251_I2C_3WIRES) {
257 r = et61x251_read_reg(cam, 0x8e);
258 if (!(r & 0x02) && (r >= 0))
259 return 0;
260 } else {
261 r = et61x251_read_reg(cam, 0x8b);
262 if (!(r & 0x01) && (r >= 0))
263 return 0;
264 }
265 if (r < 0)
266 return -EIO;
267 udelay(8*8); /* minimum for sensors at 400kHz */
268 }
269
270 return -EBUSY;
271}
272
273
274int
275et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
276 u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
277 u8 data8, u8 address)
278{
279 struct usb_device* udev = cam->usbdev;
280 u8* data = cam->control_buffer;
281 int err = 0, res;
282
283 data[0] = data2;
284 data[1] = data3;
285 data[2] = data4;
286 data[3] = data5;
287 data[4] = data6;
288 data[5] = data7;
289 data[6] = data8;
290 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
291 0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT);
292 if (res < 0)
293 err += res;
294
295 data[0] = address;
296 data[1] = cam->sensor.i2c_slave_id;
297 data[2] = cam->sensor.rsta | 0x02 | (n << 4);
298 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
299 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
300 if (res < 0)
301 err += res;
302
303 /* Start writing through the serial interface */
304 data[0] = data1;
305 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
306 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
307 if (res < 0)
308 err += res;
309
310 err += et61x251_i2c_wait(cam, &cam->sensor);
311
312 if (err)
313 DBG(3, "I2C raw write failed for %s image sensor",
314 cam->sensor.name);
315
316 PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, "
317 "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X,"
318 " data6 = 0x%02X, data7 = 0x%02X, data8 = 0x%02X", n, address,
319 data1, data2, data3, data4, data5, data6, data7, data8);
320
321 return err ? -1 : 0;
322
323}
324
325
326/*****************************************************************************/
327
328static void et61x251_urb_complete(struct urb *urb)
329{
330 struct et61x251_device* cam = urb->context;
331 struct et61x251_frame_t** f;
332 size_t imagesize;
333 u8 i;
334 int err = 0;
335
336 if (urb->status == -ENOENT)
337 return;
338
339 f = &cam->frame_current;
340
341 if (cam->stream == STREAM_INTERRUPT) {
342 cam->stream = STREAM_OFF;
343 if ((*f))
344 (*f)->state = F_QUEUED;
345 DBG(3, "Stream interrupted");
346 wake_up(&cam->wait_stream);
347 }
348
349 if (cam->state & DEV_DISCONNECTED)
350 return;
351
352 if (cam->state & DEV_MISCONFIGURED) {
353 wake_up_interruptible(&cam->wait_frame);
354 return;
355 }
356
357 if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
358 goto resubmit_urb;
359
360 if (!(*f))
361 (*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
362 frame);
363
364 imagesize = (cam->sensor.pix_format.width *
365 cam->sensor.pix_format.height *
366 cam->sensor.pix_format.priv) / 8;
367
368 for (i = 0; i < urb->number_of_packets; i++) {
369 unsigned int len, status;
370 void *pos;
371 u8* b1, * b2, sof;
372 const u8 VOID_BYTES = 6;
373 size_t imglen;
374
375 len = urb->iso_frame_desc[i].actual_length;
376 status = urb->iso_frame_desc[i].status;
377 pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
378
379 if (status) {
380 DBG(3, "Error in isochronous frame");
381 (*f)->state = F_ERROR;
382 continue;
383 }
384
385 b1 = pos++;
386 b2 = pos++;
387 sof = ((*b1 & 0x3f) == 63);
388 imglen = ((*b1 & 0xc0) << 2) | *b2;
389
390 PDBGG("Isochrnous frame: length %u, #%u i, image length %zu",
391 len, i, imglen);
392
393 if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
394start_of_frame:
395 if (sof) {
396 (*f)->state = F_GRABBING;
397 (*f)->buf.bytesused = 0;
398 do_gettimeofday(&(*f)->buf.timestamp);
399 pos += 22;
400 DBG(3, "SOF detected: new video frame");
401 }
402
403 if ((*f)->state == F_GRABBING) {
404 if (sof && (*f)->buf.bytesused) {
405 if (cam->sensor.pix_format.pixelformat ==
406 V4L2_PIX_FMT_ET61X251)
407 goto end_of_frame;
408 else {
409 DBG(3, "Not expected SOF detected "
410 "after %lu bytes",
411 (unsigned long)(*f)->buf.bytesused);
412 (*f)->state = F_ERROR;
413 continue;
414 }
415 }
416
417 if ((*f)->buf.bytesused + imglen > imagesize) {
418 DBG(3, "Video frame size exceeded");
419 (*f)->state = F_ERROR;
420 continue;
421 }
422
423 pos += VOID_BYTES;
424
425 memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, imglen);
426 (*f)->buf.bytesused += imglen;
427
428 if ((*f)->buf.bytesused == imagesize) {
429 u32 b;
430end_of_frame:
431 b = (*f)->buf.bytesused;
432 (*f)->state = F_DONE;
433 (*f)->buf.sequence= ++cam->frame_count;
434 spin_lock(&cam->queue_lock);
435 list_move_tail(&(*f)->frame, &cam->outqueue);
436 if (!list_empty(&cam->inqueue))
437 (*f) = list_entry(cam->inqueue.next,
438 struct et61x251_frame_t,
439 frame);
440 else
441 (*f) = NULL;
442 spin_unlock(&cam->queue_lock);
443 DBG(3, "Video frame captured: : %lu bytes",
444 (unsigned long)(b));
445
446 if (!(*f))
447 goto resubmit_urb;
448
449 if (sof &&
450 cam->sensor.pix_format.pixelformat ==
451 V4L2_PIX_FMT_ET61X251)
452 goto start_of_frame;
453 }
454 }
455 }
456
457resubmit_urb:
458 urb->dev = cam->usbdev;
459 err = usb_submit_urb(urb, GFP_ATOMIC);
460 if (err < 0 && err != -EPERM) {
461 cam->state |= DEV_MISCONFIGURED;
462 DBG(1, "usb_submit_urb() failed");
463 }
464
465 wake_up_interruptible(&cam->wait_frame);
466}
467
468
469static int et61x251_start_transfer(struct et61x251_device* cam)
470{
471 struct usb_device *udev = cam->usbdev;
472 struct urb* urb;
473 struct usb_host_interface* altsetting = usb_altnum_to_altsetting(
474 usb_ifnum_to_if(udev, 0),
475 ET61X251_ALTERNATE_SETTING);
476 const unsigned int psz = le16_to_cpu(altsetting->
477 endpoint[0].desc.wMaxPacketSize);
478 s8 i, j;
479 int err = 0;
480
481 for (i = 0; i < ET61X251_URBS; i++) {
482 cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
483 GFP_KERNEL);
484 if (!cam->transfer_buffer[i]) {
485 err = -ENOMEM;
486 DBG(1, "Not enough memory");
487 goto free_buffers;
488 }
489 }
490
491 for (i = 0; i < ET61X251_URBS; i++) {
492 urb = usb_alloc_urb(ET61X251_ISO_PACKETS, GFP_KERNEL);
493 cam->urb[i] = urb;
494 if (!urb) {
495 err = -ENOMEM;
496 DBG(1, "usb_alloc_urb() failed");
497 goto free_urbs;
498 }
499 urb->dev = udev;
500 urb->context = cam;
501 urb->pipe = usb_rcvisocpipe(udev, 1);
502 urb->transfer_flags = URB_ISO_ASAP;
503 urb->number_of_packets = ET61X251_ISO_PACKETS;
504 urb->complete = et61x251_urb_complete;
505 urb->transfer_buffer = cam->transfer_buffer[i];
506 urb->transfer_buffer_length = psz * ET61X251_ISO_PACKETS;
507 urb->interval = 1;
508 for (j = 0; j < ET61X251_ISO_PACKETS; j++) {
509 urb->iso_frame_desc[j].offset = psz * j;
510 urb->iso_frame_desc[j].length = psz;
511 }
512 }
513
514 err = et61x251_write_reg(cam, 0x01, 0x03);
515 err = et61x251_write_reg(cam, 0x00, 0x03);
516 err = et61x251_write_reg(cam, 0x08, 0x03);
517 if (err) {
518 err = -EIO;
519 DBG(1, "I/O hardware error");
520 goto free_urbs;
521 }
522
523 err = usb_set_interface(udev, 0, ET61X251_ALTERNATE_SETTING);
524 if (err) {
525 DBG(1, "usb_set_interface() failed");
526 goto free_urbs;
527 }
528
529 cam->frame_current = NULL;
530
531 for (i = 0; i < ET61X251_URBS; i++) {
532 err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
533 if (err) {
534 for (j = i-1; j >= 0; j--)
535 usb_kill_urb(cam->urb[j]);
536 DBG(1, "usb_submit_urb() failed, error %d", err);
537 goto free_urbs;
538 }
539 }
540
541 return 0;
542
543free_urbs:
544 for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++)
545 usb_free_urb(cam->urb[i]);
546
547free_buffers:
548 for (i = 0; (i < ET61X251_URBS) && cam->transfer_buffer[i]; i++)
549 kfree(cam->transfer_buffer[i]);
550
551 return err;
552}
553
554
555static int et61x251_stop_transfer(struct et61x251_device* cam)
556{
557 struct usb_device *udev = cam->usbdev;
558 s8 i;
559 int err = 0;
560
561 if (cam->state & DEV_DISCONNECTED)
562 return 0;
563
564 for (i = ET61X251_URBS-1; i >= 0; i--) {
565 usb_kill_urb(cam->urb[i]);
566 usb_free_urb(cam->urb[i]);
567 kfree(cam->transfer_buffer[i]);
568 }
569
570 err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
571 if (err)
572 DBG(3, "usb_set_interface() failed");
573
574 return err;
575}
576
577
578static int et61x251_stream_interrupt(struct et61x251_device* cam)
579{
580 long timeout;
581
582 cam->stream = STREAM_INTERRUPT;
583 timeout = wait_event_timeout(cam->wait_stream,
584 (cam->stream == STREAM_OFF) ||
585 (cam->state & DEV_DISCONNECTED),
586 ET61X251_URB_TIMEOUT);
587 if (cam->state & DEV_DISCONNECTED)
588 return -ENODEV;
589 else if (cam->stream != STREAM_OFF) {
590 cam->state |= DEV_MISCONFIGURED;
591 DBG(1, "URB timeout reached. The camera is misconfigured. To "
592 "use it, close and open %s again.",
593 video_device_node_name(cam->v4ldev));
594 return -EIO;
595 }
596
597 return 0;
598}
599
600/*****************************************************************************/
601
602#ifdef CONFIG_VIDEO_ADV_DEBUG
603
604static int et61x251_i2c_try_read(struct et61x251_device* cam,
605 const struct et61x251_sensor* sensor,
606 u8 address)
607{
608 struct usb_device* udev = cam->usbdev;
609 u8* data = cam->control_buffer;
610 int err = 0, res;
611
612 data[0] = address;
613 data[1] = cam->sensor.i2c_slave_id;
614 data[2] = cam->sensor.rsta | 0x10;
615 data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
616 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
617 0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT);
618 if (res < 0)
619 err += res;
620
621 err += et61x251_i2c_wait(cam, sensor);
622
623 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
624 0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT);
625 if (res < 0)
626 err += res;
627
628 if (err)
629 DBG(3, "I2C read failed for %s image sensor", sensor->name);
630
631 PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[0]);
632
633 return err ? -1 : (int)data[0];
634}
635
636
637static int et61x251_i2c_try_write(struct et61x251_device* cam,
638 const struct et61x251_sensor* sensor,
639 u8 address, u8 value)
640{
641 struct usb_device* udev = cam->usbdev;
642 u8* data = cam->control_buffer;
643 int err = 0, res;
644
645 data[0] = address;
646 data[1] = cam->sensor.i2c_slave_id;
647 data[2] = cam->sensor.rsta | 0x12;
648 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
649 0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
650 if (res < 0)
651 err += res;
652
653 data[0] = value;
654 res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
655 0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
656 if (res < 0)
657 err += res;
658
659 err += et61x251_i2c_wait(cam, sensor);
660
661 if (err)
662 DBG(3, "I2C write failed for %s image sensor", sensor->name);
663
664 PDBGG("I2C write: address 0x%02X, value: 0x%02X", address, value);
665
666 return err ? -1 : 0;
667}
668
669static int et61x251_i2c_read(struct et61x251_device* cam, u8 address)
670{
671 return et61x251_i2c_try_read(cam, &cam->sensor, address);
672}
673
674static int et61x251_i2c_write(struct et61x251_device* cam,
675 u8 address, u8 value)
676{
677 return et61x251_i2c_try_write(cam, &cam->sensor, address, value);
678}
679
680static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count)
681{
682 char str[5];
683 char* endp;
684 unsigned long val;
685
686 if (len < 4) {
687 strncpy(str, buff, len);
688 str[len] = '\0';
689 } else {
690 strncpy(str, buff, 4);
691 str[4] = '\0';
692 }
693
694 val = simple_strtoul(str, &endp, 0);
695
696 *count = 0;
697 if (val <= 0xff)
698 *count = (ssize_t)(endp - str);
699 if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
700 *count += 1;
701
702 return (u8)val;
703}
704
705/*
706 NOTE 1: being inside one of the following methods implies that the v4l
707 device exists for sure (see kobjects and reference counters)
708 NOTE 2: buffers are PAGE_SIZE long
709*/
710
711static ssize_t et61x251_show_reg(struct device* cd,
712 struct device_attribute *attr, char* buf)
713{
714 struct et61x251_device* cam;
715 ssize_t count;
716
717 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
718 return -ERESTARTSYS;
719
720 cam = video_get_drvdata(to_video_device(cd));
721 if (!cam) {
722 mutex_unlock(&et61x251_sysfs_lock);
723 return -ENODEV;
724 }
725
726 count = sprintf(buf, "%u\n", cam->sysfs.reg);
727
728 mutex_unlock(&et61x251_sysfs_lock);
729
730 return count;
731}
732
733
734static ssize_t
735et61x251_store_reg(struct device* cd,
736 struct device_attribute *attr, const char* buf, size_t len)
737{
738 struct et61x251_device* cam;
739 u8 index;
740 ssize_t count;
741
742 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
743 return -ERESTARTSYS;
744
745 cam = video_get_drvdata(to_video_device(cd));
746 if (!cam) {
747 mutex_unlock(&et61x251_sysfs_lock);
748 return -ENODEV;
749 }
750
751 index = et61x251_strtou8(buf, len, &count);
752 if (index > 0x8e || !count) {
753 mutex_unlock(&et61x251_sysfs_lock);
754 return -EINVAL;
755 }
756
757 cam->sysfs.reg = index;
758
759 DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg);
760 DBG(3, "Written bytes: %zd", count);
761
762 mutex_unlock(&et61x251_sysfs_lock);
763
764 return count;
765}
766
767
768static ssize_t et61x251_show_val(struct device* cd,
769 struct device_attribute *attr, char* buf)
770{
771 struct et61x251_device* cam;
772 ssize_t count;
773 int val;
774
775 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
776 return -ERESTARTSYS;
777
778 cam = video_get_drvdata(to_video_device(cd));
779 if (!cam) {
780 mutex_unlock(&et61x251_sysfs_lock);
781 return -ENODEV;
782 }
783
784 if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) {
785 mutex_unlock(&et61x251_sysfs_lock);
786 return -EIO;
787 }
788
789 count = sprintf(buf, "%d\n", val);
790
791 DBG(3, "Read bytes: %zd", count);
792
793 mutex_unlock(&et61x251_sysfs_lock);
794
795 return count;
796}
797
798
799static ssize_t
800et61x251_store_val(struct device* cd, struct device_attribute *attr,
801 const char* buf, size_t len)
802{
803 struct et61x251_device* cam;
804 u8 value;
805 ssize_t count;
806 int err;
807
808 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
809 return -ERESTARTSYS;
810
811 cam = video_get_drvdata(to_video_device(cd));
812 if (!cam) {
813 mutex_unlock(&et61x251_sysfs_lock);
814 return -ENODEV;
815 }
816
817 value = et61x251_strtou8(buf, len, &count);
818 if (!count) {
819 mutex_unlock(&et61x251_sysfs_lock);
820 return -EINVAL;
821 }
822
823 err = et61x251_write_reg(cam, value, cam->sysfs.reg);
824 if (err) {
825 mutex_unlock(&et61x251_sysfs_lock);
826 return -EIO;
827 }
828
829 DBG(2, "Written ET61X[12]51 reg. 0x%02X, val. 0x%02X",
830 cam->sysfs.reg, value);
831 DBG(3, "Written bytes: %zd", count);
832
833 mutex_unlock(&et61x251_sysfs_lock);
834
835 return count;
836}
837
838
839static ssize_t et61x251_show_i2c_reg(struct device* cd,
840 struct device_attribute *attr, char* buf)
841{
842 struct et61x251_device* cam;
843 ssize_t count;
844
845 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
846 return -ERESTARTSYS;
847
848 cam = video_get_drvdata(to_video_device(cd));
849 if (!cam) {
850 mutex_unlock(&et61x251_sysfs_lock);
851 return -ENODEV;
852 }
853
854 count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
855
856 DBG(3, "Read bytes: %zd", count);
857
858 mutex_unlock(&et61x251_sysfs_lock);
859
860 return count;
861}
862
863
864static ssize_t
865et61x251_store_i2c_reg(struct device* cd, struct device_attribute *attr,
866 const char* buf, size_t len)
867{
868 struct et61x251_device* cam;
869 u8 index;
870 ssize_t count;
871
872 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
873 return -ERESTARTSYS;
874
875 cam = video_get_drvdata(to_video_device(cd));
876 if (!cam) {
877 mutex_unlock(&et61x251_sysfs_lock);
878 return -ENODEV;
879 }
880
881 index = et61x251_strtou8(buf, len, &count);
882 if (!count) {
883 mutex_unlock(&et61x251_sysfs_lock);
884 return -EINVAL;
885 }
886
887 cam->sysfs.i2c_reg = index;
888
889 DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
890 DBG(3, "Written bytes: %zd", count);
891
892 mutex_unlock(&et61x251_sysfs_lock);
893
894 return count;
895}
896
897
898static ssize_t et61x251_show_i2c_val(struct device* cd,
899 struct device_attribute *attr, char* buf)
900{
901 struct et61x251_device* cam;
902 ssize_t count;
903 int val;
904
905 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
906 return -ERESTARTSYS;
907
908 cam = video_get_drvdata(to_video_device(cd));
909 if (!cam) {
910 mutex_unlock(&et61x251_sysfs_lock);
911 return -ENODEV;
912 }
913
914 if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) {
915 mutex_unlock(&et61x251_sysfs_lock);
916 return -ENOSYS;
917 }
918
919 if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
920 mutex_unlock(&et61x251_sysfs_lock);
921 return -EIO;
922 }
923
924 count = sprintf(buf, "%d\n", val);
925
926 DBG(3, "Read bytes: %zd", count);
927
928 mutex_unlock(&et61x251_sysfs_lock);
929
930 return count;
931}
932
933
934static ssize_t
935et61x251_store_i2c_val(struct device* cd, struct device_attribute *attr,
936 const char* buf, size_t len)
937{
938 struct et61x251_device* cam;
939 u8 value;
940 ssize_t count;
941 int err;
942
943 if (mutex_lock_interruptible(&et61x251_sysfs_lock))
944 return -ERESTARTSYS;
945
946 cam = video_get_drvdata(to_video_device(cd));
947 if (!cam) {
948 mutex_unlock(&et61x251_sysfs_lock);
949 return -ENODEV;
950 }
951
952 if (!(cam->sensor.sysfs_ops & ET61X251_I2C_READ)) {
953 mutex_unlock(&et61x251_sysfs_lock);
954 return -ENOSYS;
955 }
956
957 value = et61x251_strtou8(buf, len, &count);
958 if (!count) {
959 mutex_unlock(&et61x251_sysfs_lock);
960 return -EINVAL;
961 }
962
963 err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value);
964 if (err) {
965 mutex_unlock(&et61x251_sysfs_lock);
966 return -EIO;
967 }
968
969 DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
970 cam->sysfs.i2c_reg, value);
971 DBG(3, "Written bytes: %zd", count);
972
973 mutex_unlock(&et61x251_sysfs_lock);
974
975 return count;
976}
977
978
979static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
980 et61x251_show_reg, et61x251_store_reg);
981static DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
982 et61x251_show_val, et61x251_store_val);
983static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
984 et61x251_show_i2c_reg, et61x251_store_i2c_reg);
985static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
986 et61x251_show_i2c_val, et61x251_store_i2c_val);
987
988
989static int et61x251_create_sysfs(struct et61x251_device* cam)
990{
991 struct device *classdev = &(cam->v4ldev->dev);
992 int err = 0;
993
994 if ((err = device_create_file(classdev, &dev_attr_reg)))
995 goto err_out;
996 if ((err = device_create_file(classdev, &dev_attr_val)))
997 goto err_reg;
998
999 if (cam->sensor.sysfs_ops) {
1000 if ((err = device_create_file(classdev, &dev_attr_i2c_reg)))
1001 goto err_val;
1002 if ((err = device_create_file(classdev, &dev_attr_i2c_val)))
1003 goto err_i2c_reg;
1004 }
1005
1006err_i2c_reg:
1007 if (cam->sensor.sysfs_ops)
1008 device_remove_file(classdev, &dev_attr_i2c_reg);
1009err_val:
1010 device_remove_file(classdev, &dev_attr_val);
1011err_reg:
1012 device_remove_file(classdev, &dev_attr_reg);
1013err_out:
1014 return err;
1015}
1016#endif /* CONFIG_VIDEO_ADV_DEBUG */
1017
1018/*****************************************************************************/
1019
1020static int
1021et61x251_set_pix_format(struct et61x251_device* cam,
1022 struct v4l2_pix_format* pix)
1023{
1024 int r, err = 0;
1025
1026 if ((r = et61x251_read_reg(cam, 0x12)) < 0)
1027 err += r;
1028 if (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
1029 err += et61x251_write_reg(cam, r & 0xfd, 0x12);
1030 else
1031 err += et61x251_write_reg(cam, r | 0x02, 0x12);
1032
1033 return err ? -EIO : 0;
1034}
1035
1036
1037static int
1038et61x251_set_compression(struct et61x251_device* cam,
1039 struct v4l2_jpegcompression* compression)
1040{
1041 int r, err = 0;
1042
1043 if ((r = et61x251_read_reg(cam, 0x12)) < 0)
1044 err += r;
1045 if (compression->quality == 0)
1046 err += et61x251_write_reg(cam, r & 0xfb, 0x12);
1047 else
1048 err += et61x251_write_reg(cam, r | 0x04, 0x12);
1049
1050 return err ? -EIO : 0;
1051}
1052
1053
1054static int et61x251_set_scale(struct et61x251_device* cam, u8 scale)
1055{
1056 int r = 0, err = 0;
1057
1058 r = et61x251_read_reg(cam, 0x12);
1059 if (r < 0)
1060 err += r;
1061
1062 if (scale == 1)
1063 err += et61x251_write_reg(cam, r & ~0x01, 0x12);
1064 else if (scale == 2)
1065 err += et61x251_write_reg(cam, r | 0x01, 0x12);
1066
1067 if (err)
1068 return -EIO;
1069
1070 PDBGG("Scaling factor: %u", scale);
1071
1072 return 0;
1073}
1074
1075
1076static int
1077et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect)
1078{
1079 struct et61x251_sensor* s = &cam->sensor;
1080 u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left +
1081 s->active_pixel.left),
1082 fmw_sy = (u16)(rect->top - s->cropcap.bounds.top +
1083 s->active_pixel.top),
1084 fmw_length = (u16)(rect->width),
1085 fmw_height = (u16)(rect->height);
1086 int err = 0;
1087
1088 err += et61x251_write_reg(cam, fmw_sx & 0xff, 0x69);
1089 err += et61x251_write_reg(cam, fmw_sy & 0xff, 0x6a);
1090 err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b);
1091 err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c);
1092 err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
1093 | ((fmw_length & 0x300) >> 4)
1094 | ((fmw_height & 0x300) >> 2), 0x6d);
1095 if (err)
1096 return -EIO;
1097
1098 PDBGG("fmw_sx, fmw_sy, fmw_length, fmw_height: %u %u %u %u",
1099 fmw_sx, fmw_sy, fmw_length, fmw_height);
1100
1101 return 0;
1102}
1103
1104
1105static int et61x251_init(struct et61x251_device* cam)
1106{
1107 struct et61x251_sensor* s = &cam->sensor;
1108 struct v4l2_control ctrl;
1109 struct v4l2_queryctrl *qctrl;
1110 struct v4l2_rect* rect;
1111 u8 i = 0;
1112 int err = 0;
1113
1114 if (!(cam->state & DEV_INITIALIZED)) {
1115 mutex_init(&cam->open_mutex);
1116 init_waitqueue_head(&cam->wait_open);
1117 qctrl = s->qctrl;
1118 rect = &(s->cropcap.defrect);
1119 cam->compression.quality = ET61X251_COMPRESSION_QUALITY;
1120 } else { /* use current values */
1121 qctrl = s->_qctrl;
1122 rect = &(s->_rect);
1123 }
1124
1125 err += et61x251_set_scale(cam, rect->width / s->pix_format.width);
1126 err += et61x251_set_crop(cam, rect);
1127 if (err)
1128 return err;
1129
1130 if (s->init) {
1131 err = s->init(cam);
1132 if (err) {
1133 DBG(3, "Sensor initialization failed");
1134 return err;
1135 }
1136 }
1137
1138 err += et61x251_set_compression(cam, &cam->compression);
1139 err += et61x251_set_pix_format(cam, &s->pix_format);
1140 if (s->set_pix_format)
1141 err += s->set_pix_format(cam, &s->pix_format);
1142 if (err)
1143 return err;
1144
1145 if (s->pix_format.pixelformat == V4L2_PIX_FMT_ET61X251)
1146 DBG(3, "Compressed video format is active, quality %d",
1147 cam->compression.quality);
1148 else
1149 DBG(3, "Uncompressed video format is active");
1150
1151 if (s->set_crop)
1152 if ((err = s->set_crop(cam, rect))) {
1153 DBG(3, "set_crop() failed");
1154 return err;
1155 }
1156
1157 if (s->set_ctrl) {
1158 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1159 if (s->qctrl[i].id != 0 &&
1160 !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
1161 ctrl.id = s->qctrl[i].id;
1162 ctrl.value = qctrl[i].default_value;
1163 err = s->set_ctrl(cam, &ctrl);
1164 if (err) {
1165 DBG(3, "Set %s control failed",
1166 s->qctrl[i].name);
1167 return err;
1168 }
1169 DBG(3, "Image sensor supports '%s' control",
1170 s->qctrl[i].name);
1171 }
1172 }
1173
1174 if (!(cam->state & DEV_INITIALIZED)) {
1175 mutex_init(&cam->fileop_mutex);
1176 spin_lock_init(&cam->queue_lock);
1177 init_waitqueue_head(&cam->wait_frame);
1178 init_waitqueue_head(&cam->wait_stream);
1179 cam->nreadbuffers = 2;
1180 memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
1181 memcpy(&(s->_rect), &(s->cropcap.defrect),
1182 sizeof(struct v4l2_rect));
1183 cam->state |= DEV_INITIALIZED;
1184 }
1185
1186 DBG(2, "Initialization succeeded");
1187 return 0;
1188}
1189
1190/*****************************************************************************/
1191
1192static void et61x251_release_resources(struct kref *kref)
1193{
1194 struct et61x251_device *cam;
1195
1196 mutex_lock(&et61x251_sysfs_lock);
1197
1198 cam = container_of(kref, struct et61x251_device, kref);
1199
1200 DBG(2, "V4L2 device %s deregistered",
1201 video_device_node_name(cam->v4ldev));
1202 video_set_drvdata(cam->v4ldev, NULL);
1203 video_unregister_device(cam->v4ldev);
1204 usb_put_dev(cam->usbdev);
1205 kfree(cam->control_buffer);
1206 kfree(cam);
1207
1208 mutex_unlock(&et61x251_sysfs_lock);
1209}
1210
1211
1212static int et61x251_open(struct file *filp)
1213{
1214 struct et61x251_device* cam;
1215 int err = 0;
1216
1217 if (!down_read_trylock(&et61x251_dev_lock))
1218 return -ERESTARTSYS;
1219
1220 cam = video_drvdata(filp);
1221
1222 if (wait_for_completion_interruptible(&cam->probe)) {
1223 up_read(&et61x251_dev_lock);
1224 return -ERESTARTSYS;
1225 }
1226
1227 kref_get(&cam->kref);
1228
1229 if (mutex_lock_interruptible(&cam->open_mutex)) {
1230 kref_put(&cam->kref, et61x251_release_resources);
1231 up_read(&et61x251_dev_lock);
1232 return -ERESTARTSYS;
1233 }
1234
1235 if (cam->state & DEV_DISCONNECTED) {
1236 DBG(1, "Device not present");
1237 err = -ENODEV;
1238 goto out;
1239 }
1240
1241 if (cam->users) {
1242 DBG(2, "Device %s is already in use",
1243 video_device_node_name(cam->v4ldev));
1244 DBG(3, "Simultaneous opens are not supported");
1245 if ((filp->f_flags & O_NONBLOCK) ||
1246 (filp->f_flags & O_NDELAY)) {
1247 err = -EWOULDBLOCK;
1248 goto out;
1249 }
1250 DBG(2, "A blocking open() has been requested. Wait for the "
1251 "device to be released...");
1252 up_read(&et61x251_dev_lock);
1253 err = wait_event_interruptible_exclusive(cam->wait_open,
1254 (cam->state & DEV_DISCONNECTED)
1255 || !cam->users);
1256 down_read(&et61x251_dev_lock);
1257 if (err)
1258 goto out;
1259 if (cam->state & DEV_DISCONNECTED) {
1260 err = -ENODEV;
1261 goto out;
1262 }
1263 }
1264
1265 if (cam->state & DEV_MISCONFIGURED) {
1266 err = et61x251_init(cam);
1267 if (err) {
1268 DBG(1, "Initialization failed again. "
1269 "I will retry on next open().");
1270 goto out;
1271 }
1272 cam->state &= ~DEV_MISCONFIGURED;
1273 }
1274
1275 if ((err = et61x251_start_transfer(cam)))
1276 goto out;
1277
1278 filp->private_data = cam;
1279 cam->users++;
1280 cam->io = IO_NONE;
1281 cam->stream = STREAM_OFF;
1282 cam->nbuffers = 0;
1283 cam->frame_count = 0;
1284 et61x251_empty_framequeues(cam);
1285
1286 DBG(3, "Video device %s is open",
1287 video_device_node_name(cam->v4ldev));
1288
1289out:
1290 mutex_unlock(&cam->open_mutex);
1291 if (err)
1292 kref_put(&cam->kref, et61x251_release_resources);
1293 up_read(&et61x251_dev_lock);
1294 return err;
1295}
1296
1297
1298static int et61x251_release(struct file *filp)
1299{
1300 struct et61x251_device* cam;
1301
1302 down_write(&et61x251_dev_lock);
1303
1304 cam = video_drvdata(filp);
1305
1306 et61x251_stop_transfer(cam);
1307 et61x251_release_buffers(cam);
1308 cam->users--;
1309 wake_up_interruptible_nr(&cam->wait_open, 1);
1310
1311 DBG(3, "Video device %s closed",
1312 video_device_node_name(cam->v4ldev));
1313
1314 kref_put(&cam->kref, et61x251_release_resources);
1315
1316 up_write(&et61x251_dev_lock);
1317
1318 return 0;
1319}
1320
1321
1322static ssize_t
1323et61x251_read(struct file* filp, char __user * buf,
1324 size_t count, loff_t* f_pos)
1325{
1326 struct et61x251_device *cam = video_drvdata(filp);
1327 struct et61x251_frame_t* f, * i;
1328 unsigned long lock_flags;
1329 long timeout;
1330 int err = 0;
1331
1332 if (mutex_lock_interruptible(&cam->fileop_mutex))
1333 return -ERESTARTSYS;
1334
1335 if (cam->state & DEV_DISCONNECTED) {
1336 DBG(1, "Device not present");
1337 mutex_unlock(&cam->fileop_mutex);
1338 return -ENODEV;
1339 }
1340
1341 if (cam->state & DEV_MISCONFIGURED) {
1342 DBG(1, "The camera is misconfigured. Close and open it "
1343 "again.");
1344 mutex_unlock(&cam->fileop_mutex);
1345 return -EIO;
1346 }
1347
1348 if (cam->io == IO_MMAP) {
1349 DBG(3, "Close and open the device again to choose the read "
1350 "method");
1351 mutex_unlock(&cam->fileop_mutex);
1352 return -EBUSY;
1353 }
1354
1355 if (cam->io == IO_NONE) {
1356 if (!et61x251_request_buffers(cam, cam->nreadbuffers,
1357 IO_READ)) {
1358 DBG(1, "read() failed, not enough memory");
1359 mutex_unlock(&cam->fileop_mutex);
1360 return -ENOMEM;
1361 }
1362 cam->io = IO_READ;
1363 cam->stream = STREAM_ON;
1364 }
1365
1366 if (list_empty(&cam->inqueue)) {
1367 if (!list_empty(&cam->outqueue))
1368 et61x251_empty_framequeues(cam);
1369 et61x251_queue_unusedframes(cam);
1370 }
1371
1372 if (!count) {
1373 mutex_unlock(&cam->fileop_mutex);
1374 return 0;
1375 }
1376
1377 if (list_empty(&cam->outqueue)) {
1378 if (filp->f_flags & O_NONBLOCK) {
1379 mutex_unlock(&cam->fileop_mutex);
1380 return -EAGAIN;
1381 }
1382 timeout = wait_event_interruptible_timeout
1383 ( cam->wait_frame,
1384 (!list_empty(&cam->outqueue)) ||
1385 (cam->state & DEV_DISCONNECTED) ||
1386 (cam->state & DEV_MISCONFIGURED),
1387 msecs_to_jiffies(
1388 cam->module_param.frame_timeout * 1000
1389 )
1390 );
1391 if (timeout < 0) {
1392 mutex_unlock(&cam->fileop_mutex);
1393 return timeout;
1394 }
1395 if (cam->state & DEV_DISCONNECTED) {
1396 mutex_unlock(&cam->fileop_mutex);
1397 return -ENODEV;
1398 }
1399 if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
1400 mutex_unlock(&cam->fileop_mutex);
1401 return -EIO;
1402 }
1403 }
1404
1405 f = list_entry(cam->outqueue.prev, struct et61x251_frame_t, frame);
1406
1407 if (count > f->buf.bytesused)
1408 count = f->buf.bytesused;
1409
1410 if (copy_to_user(buf, f->bufmem, count)) {
1411 err = -EFAULT;
1412 goto exit;
1413 }
1414 *f_pos += count;
1415
1416exit:
1417 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1418 list_for_each_entry(i, &cam->outqueue, frame)
1419 i->state = F_UNUSED;
1420 INIT_LIST_HEAD(&cam->outqueue);
1421 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1422
1423 et61x251_queue_unusedframes(cam);
1424
1425 PDBGG("Frame #%lu, bytes read: %zu",
1426 (unsigned long)f->buf.index, count);
1427
1428 mutex_unlock(&cam->fileop_mutex);
1429
1430 return err ? err : count;
1431}
1432
1433
1434static unsigned int et61x251_poll(struct file *filp, poll_table *wait)
1435{
1436 struct et61x251_device *cam = video_drvdata(filp);
1437 struct et61x251_frame_t* f;
1438 unsigned long lock_flags;
1439 unsigned int mask = 0;
1440
1441 if (mutex_lock_interruptible(&cam->fileop_mutex))
1442 return POLLERR;
1443
1444 if (cam->state & DEV_DISCONNECTED) {
1445 DBG(1, "Device not present");
1446 goto error;
1447 }
1448
1449 if (cam->state & DEV_MISCONFIGURED) {
1450 DBG(1, "The camera is misconfigured. Close and open it "
1451 "again.");
1452 goto error;
1453 }
1454
1455 if (cam->io == IO_NONE) {
1456 if (!et61x251_request_buffers(cam, cam->nreadbuffers,
1457 IO_READ)) {
1458 DBG(1, "poll() failed, not enough memory");
1459 goto error;
1460 }
1461 cam->io = IO_READ;
1462 cam->stream = STREAM_ON;
1463 }
1464
1465 if (cam->io == IO_READ) {
1466 spin_lock_irqsave(&cam->queue_lock, lock_flags);
1467 list_for_each_entry(f, &cam->outqueue, frame)
1468 f->state = F_UNUSED;
1469 INIT_LIST_HEAD(&cam->outqueue);
1470 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
1471 et61x251_queue_unusedframes(cam);
1472 }
1473
1474 poll_wait(filp, &cam->wait_frame, wait);
1475
1476 if (!list_empty(&cam->outqueue))
1477 mask |= POLLIN | POLLRDNORM;
1478
1479 mutex_unlock(&cam->fileop_mutex);
1480
1481 return mask;
1482
1483error:
1484 mutex_unlock(&cam->fileop_mutex);
1485 return POLLERR;
1486}
1487
1488
1489static void et61x251_vm_open(struct vm_area_struct* vma)
1490{
1491 struct et61x251_frame_t* f = vma->vm_private_data;
1492 f->vma_use_count++;
1493}
1494
1495
1496static void et61x251_vm_close(struct vm_area_struct* vma)
1497{
1498 /* NOTE: buffers are not freed here */
1499 struct et61x251_frame_t* f = vma->vm_private_data;
1500 f->vma_use_count--;
1501}
1502
1503
1504static const struct vm_operations_struct et61x251_vm_ops = {
1505 .open = et61x251_vm_open,
1506 .close = et61x251_vm_close,
1507};
1508
1509
1510static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma)
1511{
1512 struct et61x251_device *cam = video_drvdata(filp);
1513 unsigned long size = vma->vm_end - vma->vm_start,
1514 start = vma->vm_start;
1515 void *pos;
1516 u32 i;
1517
1518 if (mutex_lock_interruptible(&cam->fileop_mutex))
1519 return -ERESTARTSYS;
1520
1521 if (cam->state & DEV_DISCONNECTED) {
1522 DBG(1, "Device not present");
1523 mutex_unlock(&cam->fileop_mutex);
1524 return -ENODEV;
1525 }
1526
1527 if (cam->state & DEV_MISCONFIGURED) {
1528 DBG(1, "The camera is misconfigured. Close and open it "
1529 "again.");
1530 mutex_unlock(&cam->fileop_mutex);
1531 return -EIO;
1532 }
1533
1534 if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
1535 mutex_unlock(&cam->fileop_mutex);
1536 return -EACCES;
1537 }
1538
1539 if (cam->io != IO_MMAP ||
1540 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
1541 mutex_unlock(&cam->fileop_mutex);
1542 return -EINVAL;
1543 }
1544
1545 for (i = 0; i < cam->nbuffers; i++) {
1546 if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
1547 break;
1548 }
1549 if (i == cam->nbuffers) {
1550 mutex_unlock(&cam->fileop_mutex);
1551 return -EINVAL;
1552 }
1553
1554 vma->vm_flags |= VM_IO;
1555 vma->vm_flags |= VM_RESERVED;
1556
1557 pos = cam->frame[i].bufmem;
1558 while (size > 0) { /* size is page-aligned */
1559 if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
1560 mutex_unlock(&cam->fileop_mutex);
1561 return -EAGAIN;
1562 }
1563 start += PAGE_SIZE;
1564 pos += PAGE_SIZE;
1565 size -= PAGE_SIZE;
1566 }
1567
1568 vma->vm_ops = &et61x251_vm_ops;
1569 vma->vm_private_data = &cam->frame[i];
1570 et61x251_vm_open(vma);
1571
1572 mutex_unlock(&cam->fileop_mutex);
1573
1574 return 0;
1575}
1576
1577/*****************************************************************************/
1578
1579static int
1580et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
1581{
1582 struct v4l2_capability cap = {
1583 .driver = "et61x251",
1584 .version = LINUX_VERSION_CODE,
1585 .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1586 V4L2_CAP_STREAMING,
1587 };
1588
1589 strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
1590 if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
1591 strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
1592 sizeof(cap.bus_info));
1593
1594 if (copy_to_user(arg, &cap, sizeof(cap)))
1595 return -EFAULT;
1596
1597 return 0;
1598}
1599
1600
1601static int
1602et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg)
1603{
1604 struct v4l2_input i;
1605
1606 if (copy_from_user(&i, arg, sizeof(i)))
1607 return -EFAULT;
1608
1609 if (i.index)
1610 return -EINVAL;
1611
1612 memset(&i, 0, sizeof(i));
1613 strcpy(i.name, "Camera");
1614 i.type = V4L2_INPUT_TYPE_CAMERA;
1615 i.capabilities = V4L2_IN_CAP_STD;
1616
1617 if (copy_to_user(arg, &i, sizeof(i)))
1618 return -EFAULT;
1619
1620 return 0;
1621}
1622
1623
1624static int
1625et61x251_vidioc_g_input(struct et61x251_device* cam, void __user * arg)
1626{
1627 int index = 0;
1628
1629 if (copy_to_user(arg, &index, sizeof(index)))
1630 return -EFAULT;
1631
1632 return 0;
1633}
1634
1635
1636static int
1637et61x251_vidioc_s_input(struct et61x251_device* cam, void __user * arg)
1638{
1639 int index;
1640
1641 if (copy_from_user(&index, arg, sizeof(index)))
1642 return -EFAULT;
1643
1644 if (index != 0)
1645 return -EINVAL;
1646
1647 return 0;
1648}
1649
1650
1651static int
1652et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg)
1653{
1654 struct et61x251_sensor* s = &cam->sensor;
1655 struct v4l2_queryctrl qc;
1656 u8 i;
1657
1658 if (copy_from_user(&qc, arg, sizeof(qc)))
1659 return -EFAULT;
1660
1661 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1662 if (qc.id && qc.id == s->qctrl[i].id) {
1663 memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
1664 if (copy_to_user(arg, &qc, sizeof(qc)))
1665 return -EFAULT;
1666 return 0;
1667 }
1668
1669 return -EINVAL;
1670}
1671
1672
1673static int
1674et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg)
1675{
1676 struct et61x251_sensor* s = &cam->sensor;
1677 struct v4l2_control ctrl;
1678 int err = 0;
1679 u8 i;
1680
1681 if (!s->get_ctrl && !s->set_ctrl)
1682 return -EINVAL;
1683
1684 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1685 return -EFAULT;
1686
1687 if (!s->get_ctrl) {
1688 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
1689 if (ctrl.id == s->qctrl[i].id) {
1690 ctrl.value = s->_qctrl[i].default_value;
1691 goto exit;
1692 }
1693 return -EINVAL;
1694 } else
1695 err = s->get_ctrl(cam, &ctrl);
1696
1697exit:
1698 if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
1699 return -EFAULT;
1700
1701 return err;
1702}
1703
1704
1705static int
1706et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg)
1707{
1708 struct et61x251_sensor* s = &cam->sensor;
1709 struct v4l2_control ctrl;
1710 u8 i;
1711 int err = 0;
1712
1713 if (!s->set_ctrl)
1714 return -EINVAL;
1715
1716 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1717 return -EFAULT;
1718
1719 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
1720 if (ctrl.id == s->qctrl[i].id) {
1721 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
1722 return -EINVAL;
1723 if (ctrl.value < s->qctrl[i].minimum ||
1724 ctrl.value > s->qctrl[i].maximum)
1725 return -ERANGE;
1726 ctrl.value -= ctrl.value % s->qctrl[i].step;
1727 break;
1728 }
1729 }
1730 if (i == ARRAY_SIZE(s->qctrl))
1731 return -EINVAL;
1732 if ((err = s->set_ctrl(cam, &ctrl)))
1733 return err;
1734
1735 s->_qctrl[i].default_value = ctrl.value;
1736
1737 return 0;
1738}
1739
1740
1741static int
1742et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg)
1743{
1744 struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
1745
1746 cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1747 cc->pixelaspect.numerator = 1;
1748 cc->pixelaspect.denominator = 1;
1749
1750 if (copy_to_user(arg, cc, sizeof(*cc)))
1751 return -EFAULT;
1752
1753 return 0;
1754}
1755
1756
1757static int
1758et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg)
1759{
1760 struct et61x251_sensor* s = &cam->sensor;
1761 struct v4l2_crop crop = {
1762 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1763 };
1764
1765 memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
1766
1767 if (copy_to_user(arg, &crop, sizeof(crop)))
1768 return -EFAULT;
1769
1770 return 0;
1771}
1772
1773
1774static int
1775et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
1776{
1777 struct et61x251_sensor* s = &cam->sensor;
1778 struct v4l2_crop crop;
1779 struct v4l2_rect* rect;
1780 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1781 struct v4l2_pix_format* pix_format = &(s->pix_format);
1782 u8 scale;
1783 const enum et61x251_stream_state stream = cam->stream;
1784 const u32 nbuffers = cam->nbuffers;
1785 u32 i;
1786 int err = 0;
1787
1788 if (copy_from_user(&crop, arg, sizeof(crop)))
1789 return -EFAULT;
1790
1791 rect = &(crop.c);
1792
1793 if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1794 return -EINVAL;
1795
1796 if (cam->module_param.force_munmap)
1797 for (i = 0; i < cam->nbuffers; i++)
1798 if (cam->frame[i].vma_use_count) {
1799 DBG(3, "VIDIOC_S_CROP failed. "
1800 "Unmap the buffers first.");
1801 return -EBUSY;
1802 }
1803
1804 /* Preserve R,G or B origin */
1805 rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
1806 rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
1807
1808 if (rect->width < 16)
1809 rect->width = 16;
1810 if (rect->height < 16)
1811 rect->height = 16;
1812 if (rect->width > bounds->width)
1813 rect->width = bounds->width;
1814 if (rect->height > bounds->height)
1815 rect->height = bounds->height;
1816 if (rect->left < bounds->left)
1817 rect->left = bounds->left;
1818 if (rect->top < bounds->top)
1819 rect->top = bounds->top;
1820 if (rect->left + rect->width > bounds->left + bounds->width)
1821 rect->left = bounds->left+bounds->width - rect->width;
1822 if (rect->top + rect->height > bounds->top + bounds->height)
1823 rect->top = bounds->top+bounds->height - rect->height;
1824
1825 rect->width &= ~15L;
1826 rect->height &= ~15L;
1827
1828 if (ET61X251_PRESERVE_IMGSCALE) {
1829 /* Calculate the actual scaling factor */
1830 u32 a, b;
1831 a = rect->width * rect->height;
1832 b = pix_format->width * pix_format->height;
1833 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
1834 } else
1835 scale = 1;
1836
1837 if (cam->stream == STREAM_ON)
1838 if ((err = et61x251_stream_interrupt(cam)))
1839 return err;
1840
1841 if (copy_to_user(arg, &crop, sizeof(crop))) {
1842 cam->stream = stream;
1843 return -EFAULT;
1844 }
1845
1846 if (cam->module_param.force_munmap || cam->io == IO_READ)
1847 et61x251_release_buffers(cam);
1848
1849 err = et61x251_set_crop(cam, rect);
1850 if (s->set_crop)
1851 err += s->set_crop(cam, rect);
1852 err += et61x251_set_scale(cam, scale);
1853
1854 if (err) { /* atomic, no rollback in ioctl() */
1855 cam->state |= DEV_MISCONFIGURED;
1856 DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
1857 "use the camera, close and open %s again.",
1858 video_device_node_name(cam->v4ldev));
1859 return -EIO;
1860 }
1861
1862 s->pix_format.width = rect->width/scale;
1863 s->pix_format.height = rect->height/scale;
1864 memcpy(&(s->_rect), rect, sizeof(*rect));
1865
1866 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
1867 nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
1868 cam->state |= DEV_MISCONFIGURED;
1869 DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
1870 "use the camera, close and open %s again.",
1871 video_device_node_name(cam->v4ldev));
1872 return -ENOMEM;
1873 }
1874
1875 if (cam->io == IO_READ)
1876 et61x251_empty_framequeues(cam);
1877 else if (cam->module_param.force_munmap)
1878 et61x251_requeue_outqueue(cam);
1879
1880 cam->stream = stream;
1881
1882 return 0;
1883}
1884
1885
1886static int
1887et61x251_vidioc_enum_framesizes(struct et61x251_device* cam, void __user * arg)
1888{
1889 struct v4l2_frmsizeenum frmsize;
1890
1891 if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
1892 return -EFAULT;
1893
1894 if (frmsize.index != 0)
1895 return -EINVAL;
1896
1897 if (frmsize.pixel_format != V4L2_PIX_FMT_ET61X251 &&
1898 frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
1899 return -EINVAL;
1900
1901 frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
1902 frmsize.stepwise.min_width = frmsize.stepwise.step_width = 16;
1903 frmsize.stepwise.min_height = frmsize.stepwise.step_height = 16;
1904 frmsize.stepwise.max_width = cam->sensor.cropcap.bounds.width;
1905 frmsize.stepwise.max_height = cam->sensor.cropcap.bounds.height;
1906 memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
1907
1908 if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
1909 return -EFAULT;
1910
1911 return 0;
1912}
1913
1914
1915static int
1916et61x251_vidioc_enum_fmt(struct et61x251_device* cam, void __user * arg)
1917{
1918 struct v4l2_fmtdesc fmtd;
1919
1920 if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
1921 return -EFAULT;
1922
1923 if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1924 return -EINVAL;
1925
1926 if (fmtd.index == 0) {
1927 strcpy(fmtd.description, "bayer rgb");
1928 fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
1929 } else if (fmtd.index == 1) {
1930 strcpy(fmtd.description, "compressed");
1931 fmtd.pixelformat = V4L2_PIX_FMT_ET61X251;
1932 fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
1933 } else
1934 return -EINVAL;
1935
1936 fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1937 memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
1938
1939 if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
1940 return -EFAULT;
1941
1942 return 0;
1943}
1944
1945
1946static int
1947et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
1948{
1949 struct v4l2_format format;
1950 struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
1951
1952 if (copy_from_user(&format, arg, sizeof(format)))
1953 return -EFAULT;
1954
1955 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1956 return -EINVAL;
1957
1958 pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_ET61X251) ?
1959 0 : V4L2_COLORSPACE_SRGB;
1960 pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251)
1961 ? 0 : (pfmt->width * pfmt->priv) / 8;
1962 pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
1963 pfmt->field = V4L2_FIELD_NONE;
1964 memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
1965
1966 if (copy_to_user(arg, &format, sizeof(format)))
1967 return -EFAULT;
1968
1969 return 0;
1970}
1971
1972
1973static int
1974et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
1975 void __user * arg)
1976{
1977 struct et61x251_sensor* s = &cam->sensor;
1978 struct v4l2_format format;
1979 struct v4l2_pix_format* pix;
1980 struct v4l2_pix_format* pfmt = &(s->pix_format);
1981 struct v4l2_rect* bounds = &(s->cropcap.bounds);
1982 struct v4l2_rect rect;
1983 u8 scale;
1984 const enum et61x251_stream_state stream = cam->stream;
1985 const u32 nbuffers = cam->nbuffers;
1986 u32 i;
1987 int err = 0;
1988
1989 if (copy_from_user(&format, arg, sizeof(format)))
1990 return -EFAULT;
1991
1992 pix = &(format.fmt.pix);
1993
1994 if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1995 return -EINVAL;
1996
1997 memcpy(&rect, &(s->_rect), sizeof(rect));
1998
1999 { /* calculate the actual scaling factor */
2000 u32 a, b;
2001 a = rect.width * rect.height;
2002 b = pix->width * pix->height;
2003 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
2004 }
2005
2006 rect.width = scale * pix->width;
2007 rect.height = scale * pix->height;
2008
2009 if (rect.width < 16)
2010 rect.width = 16;
2011 if (rect.height < 16)
2012 rect.height = 16;
2013 if (rect.width > bounds->left + bounds->width - rect.left)
2014 rect.width = bounds->left + bounds->width - rect.left;
2015 if (rect.height > bounds->top + bounds->height - rect.top)
2016 rect.height = bounds->top + bounds->height - rect.top;
2017
2018 rect.width &= ~15L;
2019 rect.height &= ~15L;
2020
2021 { /* adjust the scaling factor */
2022 u32 a, b;
2023 a = rect.width * rect.height;
2024 b = pix->width * pix->height;
2025 scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
2026 }
2027
2028 pix->width = rect.width / scale;
2029 pix->height = rect.height / scale;
2030
2031 if (pix->pixelformat != V4L2_PIX_FMT_ET61X251 &&
2032 pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
2033 pix->pixelformat = pfmt->pixelformat;
2034 pix->priv = pfmt->priv; /* bpp */
2035 pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_ET61X251) ?
2036 0 : V4L2_COLORSPACE_SRGB;
2037 pix->colorspace = pfmt->colorspace;
2038 pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
2039 ? 0 : (pix->width * pix->priv) / 8;
2040 pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
2041 pix->field = V4L2_FIELD_NONE;
2042
2043 if (cmd == VIDIOC_TRY_FMT) {
2044 if (copy_to_user(arg, &format, sizeof(format)))
2045 return -EFAULT;
2046 return 0;
2047 }
2048
2049 if (cam->module_param.force_munmap)
2050 for (i = 0; i < cam->nbuffers; i++)
2051 if (cam->frame[i].vma_use_count) {
2052 DBG(3, "VIDIOC_S_FMT failed. "
2053 "Unmap the buffers first.");
2054 return -EBUSY;
2055 }
2056
2057 if (cam->stream == STREAM_ON)
2058 if ((err = et61x251_stream_interrupt(cam)))
2059 return err;
2060
2061 if (copy_to_user(arg, &format, sizeof(format))) {
2062 cam->stream = stream;
2063 return -EFAULT;
2064 }
2065
2066 if (cam->module_param.force_munmap || cam->io == IO_READ)
2067 et61x251_release_buffers(cam);
2068
2069 err += et61x251_set_pix_format(cam, pix);
2070 err += et61x251_set_crop(cam, &rect);
2071 if (s->set_pix_format)
2072 err += s->set_pix_format(cam, pix);
2073 if (s->set_crop)
2074 err += s->set_crop(cam, &rect);
2075 err += et61x251_set_scale(cam, scale);
2076
2077 if (err) { /* atomic, no rollback in ioctl() */
2078 cam->state |= DEV_MISCONFIGURED;
2079 DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
2080 "use the camera, close and open %s again.",
2081 video_device_node_name(cam->v4ldev));
2082 return -EIO;
2083 }
2084
2085 memcpy(pfmt, pix, sizeof(*pix));
2086 memcpy(&(s->_rect), &rect, sizeof(rect));
2087
2088 if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
2089 nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
2090 cam->state |= DEV_MISCONFIGURED;
2091 DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
2092 "use the camera, close and open %s again.",
2093 video_device_node_name(cam->v4ldev));
2094 return -ENOMEM;
2095 }
2096
2097 if (cam->io == IO_READ)
2098 et61x251_empty_framequeues(cam);
2099 else if (cam->module_param.force_munmap)
2100 et61x251_requeue_outqueue(cam);
2101
2102 cam->stream = stream;
2103
2104 return 0;
2105}
2106
2107
2108static int
2109et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
2110{
2111 if (copy_to_user(arg, &cam->compression,
2112 sizeof(cam->compression)))
2113 return -EFAULT;
2114
2115 return 0;
2116}
2117
2118
2119static int
2120et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg)
2121{
2122 struct v4l2_jpegcompression jc;
2123 const enum et61x251_stream_state stream = cam->stream;
2124 int err = 0;
2125
2126 if (copy_from_user(&jc, arg, sizeof(jc)))
2127 return -EFAULT;
2128
2129 if (jc.quality != 0 && jc.quality != 1)
2130 return -EINVAL;
2131
2132 if (cam->stream == STREAM_ON)
2133 if ((err = et61x251_stream_interrupt(cam)))
2134 return err;
2135
2136 err += et61x251_set_compression(cam, &jc);
2137 if (err) { /* atomic, no rollback in ioctl() */
2138 cam->state |= DEV_MISCONFIGURED;
2139 DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
2140 "problems. To use the camera, close and open "
2141 "%s again.", video_device_node_name(cam->v4ldev));
2142 return -EIO;
2143 }
2144
2145 cam->compression.quality = jc.quality;
2146
2147 cam->stream = stream;
2148
2149 return 0;
2150}
2151
2152
2153static int
2154et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg)
2155{
2156 struct v4l2_requestbuffers rb;
2157 u32 i;
2158 int err;
2159
2160 if (copy_from_user(&rb, arg, sizeof(rb)))
2161 return -EFAULT;
2162
2163 if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2164 rb.memory != V4L2_MEMORY_MMAP)
2165 return -EINVAL;
2166
2167 if (cam->io == IO_READ) {
2168 DBG(3, "Close and open the device again to choose the mmap "
2169 "I/O method");
2170 return -EBUSY;
2171 }
2172
2173 for (i = 0; i < cam->nbuffers; i++)
2174 if (cam->frame[i].vma_use_count) {
2175 DBG(3, "VIDIOC_REQBUFS failed. "
2176 "Previous buffers are still mapped.");
2177 return -EBUSY;
2178 }
2179
2180 if (cam->stream == STREAM_ON)
2181 if ((err = et61x251_stream_interrupt(cam)))
2182 return err;
2183
2184 et61x251_empty_framequeues(cam);
2185
2186 et61x251_release_buffers(cam);
2187 if (rb.count)
2188 rb.count = et61x251_request_buffers(cam, rb.count, IO_MMAP);
2189
2190 if (copy_to_user(arg, &rb, sizeof(rb))) {
2191 et61x251_release_buffers(cam);
2192 cam->io = IO_NONE;
2193 return -EFAULT;
2194 }
2195
2196 cam->io = rb.count ? IO_MMAP : IO_NONE;
2197
2198 return 0;
2199}
2200
2201
2202static int
2203et61x251_vidioc_querybuf(struct et61x251_device* cam, void __user * arg)
2204{
2205 struct v4l2_buffer b;
2206
2207 if (copy_from_user(&b, arg, sizeof(b)))
2208 return -EFAULT;
2209
2210 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2211 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2212 return -EINVAL;
2213
2214 memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
2215
2216 if (cam->frame[b.index].vma_use_count)
2217 b.flags |= V4L2_BUF_FLAG_MAPPED;
2218
2219 if (cam->frame[b.index].state == F_DONE)
2220 b.flags |= V4L2_BUF_FLAG_DONE;
2221 else if (cam->frame[b.index].state != F_UNUSED)
2222 b.flags |= V4L2_BUF_FLAG_QUEUED;
2223
2224 if (copy_to_user(arg, &b, sizeof(b)))
2225 return -EFAULT;
2226
2227 return 0;
2228}
2229
2230
2231static int
2232et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg)
2233{
2234 struct v4l2_buffer b;
2235 unsigned long lock_flags;
2236
2237 if (copy_from_user(&b, arg, sizeof(b)))
2238 return -EFAULT;
2239
2240 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2241 b.index >= cam->nbuffers || cam->io != IO_MMAP)
2242 return -EINVAL;
2243
2244 if (cam->frame[b.index].state != F_UNUSED)
2245 return -EINVAL;
2246
2247 cam->frame[b.index].state = F_QUEUED;
2248
2249 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2250 list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
2251 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2252
2253 PDBGG("Frame #%lu queued", (unsigned long)b.index);
2254
2255 return 0;
2256}
2257
2258
2259static int
2260et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
2261 void __user * arg)
2262{
2263 struct v4l2_buffer b;
2264 struct et61x251_frame_t *f;
2265 unsigned long lock_flags;
2266 long timeout;
2267
2268 if (copy_from_user(&b, arg, sizeof(b)))
2269 return -EFAULT;
2270
2271 if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
2272 return -EINVAL;
2273
2274 if (list_empty(&cam->outqueue)) {
2275 if (cam->stream == STREAM_OFF)
2276 return -EINVAL;
2277 if (filp->f_flags & O_NONBLOCK)
2278 return -EAGAIN;
2279 timeout = wait_event_interruptible_timeout
2280 ( cam->wait_frame,
2281 (!list_empty(&cam->outqueue)) ||
2282 (cam->state & DEV_DISCONNECTED) ||
2283 (cam->state & DEV_MISCONFIGURED),
2284 cam->module_param.frame_timeout *
2285 1000 * msecs_to_jiffies(1) );
2286 if (timeout < 0)
2287 return timeout;
2288 if (cam->state & DEV_DISCONNECTED)
2289 return -ENODEV;
2290 if (!timeout || (cam->state & DEV_MISCONFIGURED))
2291 return -EIO;
2292 }
2293
2294 spin_lock_irqsave(&cam->queue_lock, lock_flags);
2295 f = list_entry(cam->outqueue.next, struct et61x251_frame_t, frame);
2296 list_del(cam->outqueue.next);
2297 spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
2298
2299 f->state = F_UNUSED;
2300
2301 memcpy(&b, &f->buf, sizeof(b));
2302 if (f->vma_use_count)
2303 b.flags |= V4L2_BUF_FLAG_MAPPED;
2304
2305 if (copy_to_user(arg, &b, sizeof(b)))
2306 return -EFAULT;
2307
2308 PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
2309
2310 return 0;
2311}
2312
2313
2314static int
2315et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg)
2316{
2317 int type;
2318
2319 if (copy_from_user(&type, arg, sizeof(type)))
2320 return -EFAULT;
2321
2322 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2323 return -EINVAL;
2324
2325 cam->stream = STREAM_ON;
2326
2327 DBG(3, "Stream on");
2328
2329 return 0;
2330}
2331
2332
2333static int
2334et61x251_vidioc_streamoff(struct et61x251_device* cam, void __user * arg)
2335{
2336 int type, err;
2337
2338 if (copy_from_user(&type, arg, sizeof(type)))
2339 return -EFAULT;
2340
2341 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
2342 return -EINVAL;
2343
2344 if (cam->stream == STREAM_ON)
2345 if ((err = et61x251_stream_interrupt(cam)))
2346 return err;
2347
2348 et61x251_empty_framequeues(cam);
2349
2350 DBG(3, "Stream off");
2351
2352 return 0;
2353}
2354
2355
2356static int
2357et61x251_vidioc_g_parm(struct et61x251_device* cam, void __user * arg)
2358{
2359 struct v4l2_streamparm sp;
2360
2361 if (copy_from_user(&sp, arg, sizeof(sp)))
2362 return -EFAULT;
2363
2364 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2365 return -EINVAL;
2366
2367 sp.parm.capture.extendedmode = 0;
2368 sp.parm.capture.readbuffers = cam->nreadbuffers;
2369
2370 if (copy_to_user(arg, &sp, sizeof(sp)))
2371 return -EFAULT;
2372
2373 return 0;
2374}
2375
2376
2377static int
2378et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg)
2379{
2380 struct v4l2_streamparm sp;
2381
2382 if (copy_from_user(&sp, arg, sizeof(sp)))
2383 return -EFAULT;
2384
2385 if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2386 return -EINVAL;
2387
2388 sp.parm.capture.extendedmode = 0;
2389
2390 if (sp.parm.capture.readbuffers == 0)
2391 sp.parm.capture.readbuffers = cam->nreadbuffers;
2392
2393 if (sp.parm.capture.readbuffers > ET61X251_MAX_FRAMES)
2394 sp.parm.capture.readbuffers = ET61X251_MAX_FRAMES;
2395
2396 if (copy_to_user(arg, &sp, sizeof(sp)))
2397 return -EFAULT;
2398
2399 cam->nreadbuffers = sp.parm.capture.readbuffers;
2400
2401 return 0;
2402}
2403
2404
2405static long et61x251_ioctl_v4l2(struct file *filp,
2406 unsigned int cmd, void __user *arg)
2407{
2408 struct et61x251_device *cam = video_drvdata(filp);
2409
2410 switch (cmd) {
2411
2412 case VIDIOC_QUERYCAP:
2413 return et61x251_vidioc_querycap(cam, arg);
2414
2415 case VIDIOC_ENUMINPUT:
2416 return et61x251_vidioc_enuminput(cam, arg);
2417
2418 case VIDIOC_G_INPUT:
2419 return et61x251_vidioc_g_input(cam, arg);
2420
2421 case VIDIOC_S_INPUT:
2422 return et61x251_vidioc_s_input(cam, arg);
2423
2424 case VIDIOC_QUERYCTRL:
2425 return et61x251_vidioc_query_ctrl(cam, arg);
2426
2427 case VIDIOC_G_CTRL:
2428 return et61x251_vidioc_g_ctrl(cam, arg);
2429
2430 case VIDIOC_S_CTRL:
2431 return et61x251_vidioc_s_ctrl(cam, arg);
2432
2433 case VIDIOC_CROPCAP:
2434 return et61x251_vidioc_cropcap(cam, arg);
2435
2436 case VIDIOC_G_CROP:
2437 return et61x251_vidioc_g_crop(cam, arg);
2438
2439 case VIDIOC_S_CROP:
2440 return et61x251_vidioc_s_crop(cam, arg);
2441
2442 case VIDIOC_ENUM_FMT:
2443 return et61x251_vidioc_enum_fmt(cam, arg);
2444
2445 case VIDIOC_G_FMT:
2446 return et61x251_vidioc_g_fmt(cam, arg);
2447
2448 case VIDIOC_TRY_FMT:
2449 case VIDIOC_S_FMT:
2450 return et61x251_vidioc_try_s_fmt(cam, cmd, arg);
2451
2452 case VIDIOC_ENUM_FRAMESIZES:
2453 return et61x251_vidioc_enum_framesizes(cam, arg);
2454
2455 case VIDIOC_G_JPEGCOMP:
2456 return et61x251_vidioc_g_jpegcomp(cam, arg);
2457
2458 case VIDIOC_S_JPEGCOMP:
2459 return et61x251_vidioc_s_jpegcomp(cam, arg);
2460
2461 case VIDIOC_REQBUFS:
2462 return et61x251_vidioc_reqbufs(cam, arg);
2463
2464 case VIDIOC_QUERYBUF:
2465 return et61x251_vidioc_querybuf(cam, arg);
2466
2467 case VIDIOC_QBUF:
2468 return et61x251_vidioc_qbuf(cam, arg);
2469
2470 case VIDIOC_DQBUF:
2471 return et61x251_vidioc_dqbuf(cam, filp, arg);
2472
2473 case VIDIOC_STREAMON:
2474 return et61x251_vidioc_streamon(cam, arg);
2475
2476 case VIDIOC_STREAMOFF:
2477 return et61x251_vidioc_streamoff(cam, arg);
2478
2479 case VIDIOC_G_PARM:
2480 return et61x251_vidioc_g_parm(cam, arg);
2481
2482 case VIDIOC_S_PARM:
2483 return et61x251_vidioc_s_parm(cam, arg);
2484
2485 default:
2486 return -ENOTTY;
2487
2488 }
2489}
2490
2491
2492static long et61x251_ioctl(struct file *filp,
2493 unsigned int cmd, unsigned long arg)
2494{
2495 struct et61x251_device *cam = video_drvdata(filp);
2496 long err = 0;
2497
2498 if (mutex_lock_interruptible(&cam->fileop_mutex))
2499 return -ERESTARTSYS;
2500
2501 if (cam->state & DEV_DISCONNECTED) {
2502 DBG(1, "Device not present");
2503 mutex_unlock(&cam->fileop_mutex);
2504 return -ENODEV;
2505 }
2506
2507 if (cam->state & DEV_MISCONFIGURED) {
2508 DBG(1, "The camera is misconfigured. Close and open it "
2509 "again.");
2510 mutex_unlock(&cam->fileop_mutex);
2511 return -EIO;
2512 }
2513
2514 V4LDBG(3, "et61x251", cmd);
2515
2516 err = et61x251_ioctl_v4l2(filp, cmd, (void __user *)arg);
2517
2518 mutex_unlock(&cam->fileop_mutex);
2519
2520 return err;
2521}
2522
2523
2524static const struct v4l2_file_operations et61x251_fops = {
2525 .owner = THIS_MODULE,
2526 .open = et61x251_open,
2527 .release = et61x251_release,
2528 .unlocked_ioctl = et61x251_ioctl,
2529 .read = et61x251_read,
2530 .poll = et61x251_poll,
2531 .mmap = et61x251_mmap,
2532};
2533
2534/*****************************************************************************/
2535
2536/* It exists a single interface only. We do not need to validate anything. */
2537static int
2538et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2539{
2540 struct usb_device *udev = interface_to_usbdev(intf);
2541 struct et61x251_device* cam;
2542 static unsigned int dev_nr;
2543 unsigned int i;
2544 int err = 0;
2545
2546 if (!(cam = kzalloc(sizeof(struct et61x251_device), GFP_KERNEL)))
2547 return -ENOMEM;
2548
2549 cam->usbdev = udev;
2550
2551 if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
2552 DBG(1, "kmalloc() failed");
2553 err = -ENOMEM;
2554 goto fail;
2555 }
2556
2557 if (!(cam->v4ldev = video_device_alloc())) {
2558 DBG(1, "video_device_alloc() failed");
2559 err = -ENOMEM;
2560 goto fail;
2561 }
2562
2563 DBG(2, "ET61X[12]51 PC Camera Controller detected "
2564 "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct);
2565
2566 for (i = 0; et61x251_sensor_table[i]; i++) {
2567 err = et61x251_sensor_table[i](cam);
2568 if (!err)
2569 break;
2570 }
2571
2572 if (!err)
2573 DBG(2, "%s image sensor detected", cam->sensor.name);
2574 else {
2575 DBG(1, "No supported image sensor detected");
2576 err = -ENODEV;
2577 goto fail;
2578 }
2579
2580 if (et61x251_init(cam)) {
2581 DBG(1, "Initialization failed. I will retry on open().");
2582 cam->state |= DEV_MISCONFIGURED;
2583 }
2584
2585 strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
2586 cam->v4ldev->fops = &et61x251_fops;
2587 cam->v4ldev->release = video_device_release;
2588 cam->v4ldev->parent = &udev->dev;
2589 video_set_drvdata(cam->v4ldev, cam);
2590
2591 init_completion(&cam->probe);
2592
2593 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
2594 video_nr[dev_nr]);
2595 if (err) {
2596 DBG(1, "V4L2 device registration failed");
2597 if (err == -ENFILE && video_nr[dev_nr] == -1)
2598 DBG(1, "Free /dev/videoX node not found");
2599 video_nr[dev_nr] = -1;
2600 dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
2601 complete_all(&cam->probe);
2602 goto fail;
2603 }
2604
2605 DBG(2, "V4L2 device registered as %s",
2606 video_device_node_name(cam->v4ldev));
2607
2608 cam->module_param.force_munmap = force_munmap[dev_nr];
2609 cam->module_param.frame_timeout = frame_timeout[dev_nr];
2610
2611 dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
2612
2613#ifdef CONFIG_VIDEO_ADV_DEBUG
2614 err = et61x251_create_sysfs(cam);
2615 if (!err)
2616 DBG(2, "Optional device control through 'sysfs' "
2617 "interface ready");
2618 else
2619 DBG(2, "Failed to create 'sysfs' interface for optional "
2620 "device controlling. Error #%d", err);
2621#else
2622 DBG(2, "Optional device control through 'sysfs' interface disabled");
2623 DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
2624 "configuration option to enable it.");
2625#endif
2626
2627 usb_set_intfdata(intf, cam);
2628 kref_init(&cam->kref);
2629 usb_get_dev(cam->usbdev);
2630
2631 complete_all(&cam->probe);
2632
2633 return 0;
2634
2635fail:
2636 if (cam) {
2637 kfree(cam->control_buffer);
2638 if (cam->v4ldev)
2639 video_device_release(cam->v4ldev);
2640 kfree(cam);
2641 }
2642 return err;
2643}
2644
2645
2646static void et61x251_usb_disconnect(struct usb_interface* intf)
2647{
2648 struct et61x251_device* cam;
2649
2650 down_write(&et61x251_dev_lock);
2651
2652 cam = usb_get_intfdata(intf);
2653
2654 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2655
2656 if (cam->users) {
2657 DBG(2, "Device %s is open! Deregistration and memory "
2658 "deallocation are deferred.",
2659 video_device_node_name(cam->v4ldev));
2660 cam->state |= DEV_MISCONFIGURED;
2661 et61x251_stop_transfer(cam);
2662 cam->state |= DEV_DISCONNECTED;
2663 wake_up_interruptible(&cam->wait_frame);
2664 wake_up(&cam->wait_stream);
2665 } else
2666 cam->state |= DEV_DISCONNECTED;
2667
2668 wake_up_interruptible_all(&cam->wait_open);
2669
2670 kref_put(&cam->kref, et61x251_release_resources);
2671
2672 up_write(&et61x251_dev_lock);
2673}
2674
2675
2676static struct usb_driver et61x251_usb_driver = {
2677 .name = "et61x251",
2678 .id_table = et61x251_id_table,
2679 .probe = et61x251_usb_probe,
2680 .disconnect = et61x251_usb_disconnect,
2681};
2682
2683module_usb_driver(et61x251_usb_driver);
diff --git a/drivers/media/video/et61x251/et61x251_sensor.h b/drivers/media/video/et61x251/et61x251_sensor.h
deleted file mode 100644
index 71a03148cb09..000000000000
--- a/drivers/media/video/et61x251/et61x251_sensor.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/***************************************************************************
2 * API for image sensors connected to ET61X[12]51 PC Camera Controllers *
3 * *
4 * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
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#ifndef _ET61X251_SENSOR_H_
22#define _ET61X251_SENSOR_H_
23
24#include <linux/usb.h>
25#include <linux/videodev2.h>
26#include <linux/device.h>
27#include <linux/stddef.h>
28#include <linux/errno.h>
29#include <asm/types.h>
30
31struct et61x251_device;
32struct et61x251_sensor;
33
34/*****************************************************************************/
35
36extern int et61x251_probe_tas5130d1b(struct et61x251_device* cam);
37
38#define ET61X251_SENSOR_TABLE \
39/* Weak detections must go at the end of the list */ \
40static int (*et61x251_sensor_table[])(struct et61x251_device*) = { \
41 &et61x251_probe_tas5130d1b, \
42 NULL, \
43};
44
45extern struct et61x251_device*
46et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id);
47
48extern void
49et61x251_attach_sensor(struct et61x251_device* cam,
50 const struct et61x251_sensor* sensor);
51
52/*****************************************************************************/
53
54extern int et61x251_write_reg(struct et61x251_device*, u8 value, u16 index);
55extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1,
56 u8 data2, u8 data3, u8 data4, u8 data5,
57 u8 data6, u8 data7, u8 data8, u8 address);
58
59/*****************************************************************************/
60
61enum et61x251_i2c_sysfs_ops {
62 ET61X251_I2C_READ = 0x01,
63 ET61X251_I2C_WRITE = 0x02,
64};
65
66enum et61x251_i2c_interface {
67 ET61X251_I2C_2WIRES,
68 ET61X251_I2C_3WIRES,
69};
70
71/* Repeat start condition when RSTA is high */
72enum et61x251_i2c_rsta {
73 ET61X251_I2C_RSTA_STOP = 0x00, /* stop then start */
74 ET61X251_I2C_RSTA_REPEAT = 0x01, /* repeat start */
75};
76
77#define ET61X251_MAX_CTRLS (V4L2_CID_LASTP1-V4L2_CID_BASE+10)
78
79struct et61x251_sensor {
80 char name[32];
81
82 enum et61x251_i2c_sysfs_ops sysfs_ops;
83
84 enum et61x251_i2c_interface interface;
85 u8 i2c_slave_id;
86 enum et61x251_i2c_rsta rsta;
87 struct v4l2_rect active_pixel; /* left and top define FVSX and FVSY */
88
89 struct v4l2_queryctrl qctrl[ET61X251_MAX_CTRLS];
90 struct v4l2_cropcap cropcap;
91 struct v4l2_pix_format pix_format;
92
93 int (*init)(struct et61x251_device* cam);
94 int (*get_ctrl)(struct et61x251_device* cam,
95 struct v4l2_control* ctrl);
96 int (*set_ctrl)(struct et61x251_device* cam,
97 const struct v4l2_control* ctrl);
98 int (*set_crop)(struct et61x251_device* cam,
99 const struct v4l2_rect* rect);
100 int (*set_pix_format)(struct et61x251_device* cam,
101 const struct v4l2_pix_format* pix);
102
103 /* Private */
104 struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS];
105 struct v4l2_rect _rect;
106};
107
108#endif /* _ET61X251_SENSOR_H_ */
diff --git a/drivers/media/video/et61x251/et61x251_tas5130d1b.c b/drivers/media/video/et61x251/et61x251_tas5130d1b.c
deleted file mode 100644
index ced2e167935d..000000000000
--- a/drivers/media/video/et61x251/et61x251_tas5130d1b.c
+++ /dev/null
@@ -1,143 +0,0 @@
1/***************************************************************************
2 * Plug-in for TAS5130D1B image sensor connected to the ET61X[12]51 *
3 * PC Camera Controllers *
4 * *
5 * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
20 ***************************************************************************/
21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include "et61x251_sensor.h"
25
26
27static int tas5130d1b_init(struct et61x251_device* cam)
28{
29 int err = 0;
30
31 err += et61x251_write_reg(cam, 0x14, 0x01);
32 err += et61x251_write_reg(cam, 0x1b, 0x02);
33 err += et61x251_write_reg(cam, 0x02, 0x12);
34 err += et61x251_write_reg(cam, 0x0e, 0x60);
35 err += et61x251_write_reg(cam, 0x80, 0x61);
36 err += et61x251_write_reg(cam, 0xf0, 0x62);
37 err += et61x251_write_reg(cam, 0x03, 0x63);
38 err += et61x251_write_reg(cam, 0x14, 0x64);
39 err += et61x251_write_reg(cam, 0xf4, 0x65);
40 err += et61x251_write_reg(cam, 0x01, 0x66);
41 err += et61x251_write_reg(cam, 0x05, 0x67);
42 err += et61x251_write_reg(cam, 0x8f, 0x68);
43 err += et61x251_write_reg(cam, 0x0f, 0x8d);
44 err += et61x251_write_reg(cam, 0x08, 0x8e);
45
46 return err;
47}
48
49
50static int tas5130d1b_set_ctrl(struct et61x251_device* cam,
51 const struct v4l2_control* ctrl)
52{
53 int err = 0;
54
55 switch (ctrl->id) {
56 case V4L2_CID_GAIN:
57 err += et61x251_i2c_raw_write(cam, 2, 0x20,
58 0xf6-ctrl->value, 0, 0, 0,
59 0, 0, 0, 0);
60 break;
61 case V4L2_CID_EXPOSURE:
62 err += et61x251_i2c_raw_write(cam, 2, 0x40,
63 0x47-ctrl->value, 0, 0, 0,
64 0, 0, 0, 0);
65 break;
66 default:
67 return -EINVAL;
68 }
69
70 return err ? -EIO : 0;
71}
72
73
74static const struct et61x251_sensor tas5130d1b = {
75 .name = "TAS5130D1B",
76 .interface = ET61X251_I2C_3WIRES,
77 .rsta = ET61X251_I2C_RSTA_STOP,
78 .active_pixel = {
79 .left = 106,
80 .top = 13,
81 },
82 .init = &tas5130d1b_init,
83 .qctrl = {
84 {
85 .id = V4L2_CID_GAIN,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "global gain",
88 .minimum = 0x00,
89 .maximum = 0xf6,
90 .step = 0x02,
91 .default_value = 0x0d,
92 .flags = 0,
93 },
94 {
95 .id = V4L2_CID_EXPOSURE,
96 .type = V4L2_CTRL_TYPE_INTEGER,
97 .name = "exposure",
98 .minimum = 0x00,
99 .maximum = 0x47,
100 .step = 0x01,
101 .default_value = 0x23,
102 .flags = 0,
103 },
104 },
105 .set_ctrl = &tas5130d1b_set_ctrl,
106 .cropcap = {
107 .bounds = {
108 .left = 0,
109 .top = 0,
110 .width = 640,
111 .height = 480,
112 },
113 .defrect = {
114 .left = 0,
115 .top = 0,
116 .width = 640,
117 .height = 480,
118 },
119 },
120 .pix_format = {
121 .width = 640,
122 .height = 480,
123 .pixelformat = V4L2_PIX_FMT_SBGGR8,
124 .priv = 8,
125 },
126};
127
128
129int et61x251_probe_tas5130d1b(struct et61x251_device* cam)
130{
131 const struct usb_device_id tas5130d1b_id_table[] = {
132 { USB_DEVICE(0x102c, 0x6251), },
133 { }
134 };
135
136 /* Sensor detection is based on USB pid/vid */
137 if (!et61x251_match_id(cam, tas5130d1b_id_table))
138 return -ENODEV;
139
140 et61x251_attach_sensor(cam, &tas5130d1b);
141
142 return 0;
143}
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
index 27e3e0c0b219..777486f7cadb 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/video/fsl-viu.c
@@ -1544,6 +1544,10 @@ static int __devinit viu_of_probe(struct platform_device *op)
1544 1544
1545 /* initialize locks */ 1545 /* initialize locks */
1546 mutex_init(&viu_dev->lock); 1546 mutex_init(&viu_dev->lock);
1547 /* Locking in file operations other than ioctl should be done
1548 by the driver, not the V4L2 core.
1549 This driver needs auditing so that this flag can be removed. */
1550 set_bit(V4L2_FL_LOCK_ALL_FOPS, &viu_dev->vdev->flags);
1547 viu_dev->vdev->lock = &viu_dev->lock; 1551 viu_dev->vdev->lock = &viu_dev->lock;
1548 spin_lock_init(&viu_dev->slock); 1552 spin_lock_init(&viu_dev->slock);
1549 1553
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 79ebe46e1ad7..c901da0bd657 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -43,7 +43,7 @@ obj-$(CONFIG_USB_GSPCA_VICAM) += gspca_vicam.o
43obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o 43obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o
44obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o 44obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
45 45
46gspca_main-objs := gspca.o 46gspca_main-objs := gspca.o autogain_functions.o
47gspca_benq-objs := benq.o 47gspca_benq-objs := benq.o
48gspca_conex-objs := conex.o 48gspca_conex-objs := conex.o
49gspca_cpia1-objs := cpia1.o 49gspca_cpia1-objs := cpia1.o
diff --git a/drivers/media/video/gspca/autogain_functions.c b/drivers/media/video/gspca/autogain_functions.c
new file mode 100644
index 000000000000..67db674bb044
--- /dev/null
+++ b/drivers/media/video/gspca/autogain_functions.c
@@ -0,0 +1,178 @@
1/*
2 * Functions for auto gain.
3 *
4 * Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include "gspca.h"
21
22/* auto gain and exposure algorithm based on the knee algorithm described here:
23 http://ytse.tricolour.net/docs/LowLightOptimization.html
24
25 Returns 0 if no changes were made, 1 if the gain and or exposure settings
26 where changed. */
27int gspca_expo_autogain(
28 struct gspca_dev *gspca_dev,
29 int avg_lum,
30 int desired_avg_lum,
31 int deadzone,
32 int gain_knee,
33 int exposure_knee)
34{
35 s32 gain, orig_gain, exposure, orig_exposure;
36 int i, steps, retval = 0;
37
38 if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
39 return 0;
40
41 orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
42 orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
43
44 /* If we are of a multiple of deadzone, do multiple steps to reach the
45 desired lumination fast (with the risc of a slight overshoot) */
46 steps = abs(desired_avg_lum - avg_lum) / deadzone;
47
48 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
49 avg_lum, desired_avg_lum, steps);
50
51 for (i = 0; i < steps; i++) {
52 if (avg_lum > desired_avg_lum) {
53 if (gain > gain_knee)
54 gain--;
55 else if (exposure > exposure_knee)
56 exposure--;
57 else if (gain > gspca_dev->gain->default_value)
58 gain--;
59 else if (exposure > gspca_dev->exposure->minimum)
60 exposure--;
61 else if (gain > gspca_dev->gain->minimum)
62 gain--;
63 else
64 break;
65 } else {
66 if (gain < gspca_dev->gain->default_value)
67 gain++;
68 else if (exposure < exposure_knee)
69 exposure++;
70 else if (gain < gain_knee)
71 gain++;
72 else if (exposure < gspca_dev->exposure->maximum)
73 exposure++;
74 else if (gain < gspca_dev->gain->maximum)
75 gain++;
76 else
77 break;
78 }
79 }
80
81 if (gain != orig_gain) {
82 v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
83 retval = 1;
84 }
85 if (exposure != orig_exposure) {
86 v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
87 retval = 1;
88 }
89
90 if (retval)
91 PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
92 gain, exposure);
93 return retval;
94}
95EXPORT_SYMBOL(gspca_expo_autogain);
96
97/* Autogain + exposure algorithm for cameras with a coarse exposure control
98 (usually this means we can only control the clockdiv to change exposure)
99 As changing the clockdiv so that the fps drops from 30 to 15 fps for
100 example, will lead to a huge exposure change (it effectively doubles),
101 this algorithm normally tries to only adjust the gain (between 40 and
102 80 %) and if that does not help, only then changes exposure. This leads
103 to a much more stable image then using the knee algorithm which at
104 certain points of the knee graph will only try to adjust exposure,
105 which leads to oscilating as one exposure step is huge.
106
107 Returns 0 if no changes were made, 1 if the gain and or exposure settings
108 where changed. */
109int gspca_coarse_grained_expo_autogain(
110 struct gspca_dev *gspca_dev,
111 int avg_lum,
112 int desired_avg_lum,
113 int deadzone)
114{
115 s32 gain_low, gain_high, gain, orig_gain, exposure, orig_exposure;
116 int steps, retval = 0;
117
118 if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
119 return 0;
120
121 orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
122 orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
123
124 gain_low = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
125 5 * 2 + gspca_dev->gain->minimum;
126 gain_high = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
127 5 * 4 + gspca_dev->gain->minimum;
128
129 /* If we are of a multiple of deadzone, do multiple steps to reach the
130 desired lumination fast (with the risc of a slight overshoot) */
131 steps = (desired_avg_lum - avg_lum) / deadzone;
132
133 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
134 avg_lum, desired_avg_lum, steps);
135
136 if ((gain + steps) > gain_high &&
137 exposure < gspca_dev->exposure->maximum) {
138 gain = gain_high;
139 gspca_dev->exp_too_low_cnt++;
140 gspca_dev->exp_too_high_cnt = 0;
141 } else if ((gain + steps) < gain_low &&
142 exposure > gspca_dev->exposure->minimum) {
143 gain = gain_low;
144 gspca_dev->exp_too_high_cnt++;
145 gspca_dev->exp_too_low_cnt = 0;
146 } else {
147 gain += steps;
148 if (gain > gspca_dev->gain->maximum)
149 gain = gspca_dev->gain->maximum;
150 else if (gain < gspca_dev->gain->minimum)
151 gain = gspca_dev->gain->minimum;
152 gspca_dev->exp_too_high_cnt = 0;
153 gspca_dev->exp_too_low_cnt = 0;
154 }
155
156 if (gspca_dev->exp_too_high_cnt > 3) {
157 exposure--;
158 gspca_dev->exp_too_high_cnt = 0;
159 } else if (gspca_dev->exp_too_low_cnt > 3) {
160 exposure++;
161 gspca_dev->exp_too_low_cnt = 0;
162 }
163
164 if (gain != orig_gain) {
165 v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
166 retval = 1;
167 }
168 if (exposure != orig_exposure) {
169 v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
170 retval = 1;
171 }
172
173 if (retval)
174 PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
175 gain, exposure);
176 return retval;
177}
178EXPORT_SYMBOL(gspca_coarse_grained_expo_autogain);
diff --git a/drivers/media/video/gspca/autogain_functions.h b/drivers/media/video/gspca/autogain_functions.h
index 46777eee678b..d625eafe63eb 100644
--- a/drivers/media/video/gspca/autogain_functions.h
+++ b/drivers/media/video/gspca/autogain_functions.h
@@ -18,6 +18,7 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#ifdef WANT_REGULAR_AUTOGAIN
21/* auto gain and exposure algorithm based on the knee algorithm described here: 22/* auto gain and exposure algorithm based on the knee algorithm described here:
22 http://ytse.tricolour.net/docs/LowLightOptimization.html 23 http://ytse.tricolour.net/docs/LowLightOptimization.html
23 24
@@ -91,7 +92,9 @@ static inline int auto_gain_n_exposure(
91 gain, exposure); 92 gain, exposure);
92 return retval; 93 return retval;
93} 94}
95#endif
94 96
97#ifdef WANT_COARSE_EXPO_AUTOGAIN
95/* Autogain + exposure algorithm for cameras with a coarse exposure control 98/* Autogain + exposure algorithm for cameras with a coarse exposure control
96 (usually this means we can only control the clockdiv to change exposure) 99 (usually this means we can only control the clockdiv to change exposure)
97 As changing the clockdiv so that the fps drops from 30 to 15 fps for 100 As changing the clockdiv so that the fps drops from 30 to 15 fps for
@@ -103,7 +106,7 @@ static inline int auto_gain_n_exposure(
103 which leads to oscilating as one exposure step is huge. 106 which leads to oscilating as one exposure step is huge.
104 107
105 Note this assumes that the sd struct for the cam in question has 108 Note this assumes that the sd struct for the cam in question has
106 exp_too_high_cnt and exp_too_high_cnt int members for use by this function. 109 exp_too_low_cnt and exp_too_high_cnt int members for use by this function.
107 110
108 Returns 0 if no changes were made, 1 if the gain and or exposure settings 111 Returns 0 if no changes were made, 1 if the gain and or exposure settings
109 where changed. */ 112 where changed. */
@@ -177,3 +180,4 @@ static inline int coarse_grained_expo_autogain(
177 gain, exposure); 180 gain, exposure);
178 return retval; 181 return retval;
179} 182}
183#endif
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index ea17b5d94ea4..f39fee0fd10f 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -306,7 +306,7 @@ static void cx_sensor(struct gspca_dev*gspca_dev)
306 306
307 reg_w(gspca_dev, 0x0020, reg20, 8); 307 reg_w(gspca_dev, 0x0020, reg20, 8);
308 reg_w(gspca_dev, 0x0028, reg28, 8); 308 reg_w(gspca_dev, 0x0028, reg28, 8);
309 reg_w(gspca_dev, 0x0010, reg10, 8); 309 reg_w(gspca_dev, 0x0010, reg10, 2);
310 reg_w_val(gspca_dev, 0x0092, 0x03); 310 reg_w_val(gspca_dev, 0x0092, 0x03);
311 311
312 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 312 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
@@ -326,7 +326,7 @@ static void cx_sensor(struct gspca_dev*gspca_dev)
326 } 326 }
327 reg_w(gspca_dev, 0x007b, reg7b, 6); 327 reg_w(gspca_dev, 0x007b, reg7b, 6);
328 reg_w_val(gspca_dev, 0x00f8, 0x00); 328 reg_w_val(gspca_dev, 0x00f8, 0x00);
329 reg_w(gspca_dev, 0x0010, reg10, 8); 329 reg_w(gspca_dev, 0x0010, reg10, 2);
330 reg_w_val(gspca_dev, 0x0098, 0x41); 330 reg_w_val(gspca_dev, 0x0098, 0x41);
331 for (i = 0; i < 11; i++) { 331 for (i = 0; i < 11; i++) {
332 if (i == 3 || i == 5 || i == 8) 332 if (i == 3 || i == 5 || i == 8)
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 0107513cd728..6e26c93b4656 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -94,7 +94,11 @@ static void dostream(struct work_struct *work)
94 94
95 /* loop reading a frame */ 95 /* loop reading a frame */
96again: 96again:
97 while (gspca_dev->present && gspca_dev->streaming) { 97 while (gspca_dev->dev && gspca_dev->streaming) {
98#ifdef CONFIG_PM
99 if (gspca_dev->frozen)
100 break;
101#endif
98 102
99 /* request a frame */ 103 /* request a frame */
100 mutex_lock(&gspca_dev->usb_lock); 104 mutex_lock(&gspca_dev->usb_lock);
@@ -102,7 +106,11 @@ again:
102 mutex_unlock(&gspca_dev->usb_lock); 106 mutex_unlock(&gspca_dev->usb_lock);
103 if (ret < 0) 107 if (ret < 0)
104 break; 108 break;
105 if (!gspca_dev->present || !gspca_dev->streaming) 109#ifdef CONFIG_PM
110 if (gspca_dev->frozen)
111 break;
112#endif
113 if (!gspca_dev->dev || !gspca_dev->streaming)
106 break; 114 break;
107 115
108 /* the frame comes in parts */ 116 /* the frame comes in parts */
@@ -117,7 +125,11 @@ again:
117 * error. Just restart. */ 125 * error. Just restart. */
118 goto again; 126 goto again;
119 } 127 }
120 if (!gspca_dev->present || !gspca_dev->streaming) 128#ifdef CONFIG_PM
129 if (gspca_dev->frozen)
130 goto out;
131#endif
132 if (!gspca_dev->dev || !gspca_dev->streaming)
121 goto out; 133 goto out;
122 if (len < FPIX_MAX_TRANSFER || 134 if (len < FPIX_MAX_TRANSFER ||
123 (data[len - 2] == 0xff && 135 (data[len - 2] == 0xff &&
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index c84e26006fc3..c549574c1c7e 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -405,6 +405,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
405{ 405{
406 struct sd *sd = (struct sd *) gspca_dev; 406 struct sd *sd = (struct sd *) gspca_dev;
407 407
408 if (!sd->gspca_dev.present)
409 return;
410
408 return sd->dev_post_unset_alt(gspca_dev); 411 return sd->dev_post_unset_alt(gspca_dev);
409} 412}
410 413
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index ca5a2b139d0b..137166d73945 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -38,6 +38,9 @@
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/ktime.h> 39#include <linux/ktime.h>
40#include <media/v4l2-ioctl.h> 40#include <media/v4l2-ioctl.h>
41#include <media/v4l2-ctrls.h>
42#include <media/v4l2-fh.h>
43#include <media/v4l2-event.h>
41 44
42#include "gspca.h" 45#include "gspca.h"
43 46
@@ -592,16 +595,13 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
592static void gspca_stream_off(struct gspca_dev *gspca_dev) 595static void gspca_stream_off(struct gspca_dev *gspca_dev)
593{ 596{
594 gspca_dev->streaming = 0; 597 gspca_dev->streaming = 0;
595 if (gspca_dev->present) { 598 gspca_dev->usb_err = 0;
596 if (gspca_dev->sd_desc->stopN) 599 if (gspca_dev->sd_desc->stopN)
597 gspca_dev->sd_desc->stopN(gspca_dev); 600 gspca_dev->sd_desc->stopN(gspca_dev);
598 destroy_urbs(gspca_dev); 601 destroy_urbs(gspca_dev);
599 gspca_input_destroy_urb(gspca_dev); 602 gspca_input_destroy_urb(gspca_dev);
600 gspca_set_alt0(gspca_dev); 603 gspca_set_alt0(gspca_dev);
601 gspca_input_create_urb(gspca_dev); 604 gspca_input_create_urb(gspca_dev);
602 }
603
604 /* always call stop0 to free the subdriver's resources */
605 if (gspca_dev->sd_desc->stop0) 605 if (gspca_dev->sd_desc->stop0)
606 gspca_dev->sd_desc->stop0(gspca_dev); 606 gspca_dev->sd_desc->stop0(gspca_dev);
607 PDEBUG(D_STREAM, "stream off OK"); 607 PDEBUG(D_STREAM, "stream off OK");
@@ -847,14 +847,6 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
847 struct ep_tb_s ep_tb[MAX_ALT]; 847 struct ep_tb_s ep_tb[MAX_ALT];
848 int n, ret, xfer, alt, alt_idx; 848 int n, ret, xfer, alt, alt_idx;
849 849
850 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
851 return -ERESTARTSYS;
852
853 if (!gspca_dev->present) {
854 ret = -ENODEV;
855 goto unlock;
856 }
857
858 /* reset the streaming variables */ 850 /* reset the streaming variables */
859 gspca_dev->image = NULL; 851 gspca_dev->image = NULL;
860 gspca_dev->image_len = 0; 852 gspca_dev->image_len = 0;
@@ -869,7 +861,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
869 if (gspca_dev->sd_desc->isoc_init) { 861 if (gspca_dev->sd_desc->isoc_init) {
870 ret = gspca_dev->sd_desc->isoc_init(gspca_dev); 862 ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
871 if (ret < 0) 863 if (ret < 0)
872 goto unlock; 864 return ret;
873 } 865 }
874 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK 866 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
875 : USB_ENDPOINT_XFER_ISOC; 867 : USB_ENDPOINT_XFER_ISOC;
@@ -880,8 +872,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
880 ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer); 872 ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer);
881 if (ep == NULL) { 873 if (ep == NULL) {
882 pr_err("bad altsetting %d\n", gspca_dev->alt); 874 pr_err("bad altsetting %d\n", gspca_dev->alt);
883 ret = -EIO; 875 return -EIO;
884 goto out;
885 } 876 }
886 ep_tb[0].alt = gspca_dev->alt; 877 ep_tb[0].alt = gspca_dev->alt;
887 alt_idx = 1; 878 alt_idx = 1;
@@ -892,8 +883,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
892 alt_idx = build_isoc_ep_tb(gspca_dev, intf, ep_tb); 883 alt_idx = build_isoc_ep_tb(gspca_dev, intf, ep_tb);
893 if (alt_idx <= 0) { 884 if (alt_idx <= 0) {
894 pr_err("no transfer endpoint found\n"); 885 pr_err("no transfer endpoint found\n");
895 ret = -EIO; 886 return -EIO;
896 goto unlock;
897 } 887 }
898 } 888 }
899 889
@@ -988,8 +978,6 @@ retry:
988 } 978 }
989out: 979out:
990 gspca_input_create_urb(gspca_dev); 980 gspca_input_create_urb(gspca_dev);
991unlock:
992 mutex_unlock(&gspca_dev->usb_lock);
993 return ret; 981 return ret;
994} 982}
995 983
@@ -1006,6 +994,8 @@ static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
1006 994
1007 /* set the current control values to their default values 995 /* set the current control values to their default values
1008 * which may have changed in sd_init() */ 996 * which may have changed in sd_init() */
997 /* does nothing if ctrl_handler == NULL */
998 v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler);
1009 ctrl = gspca_dev->cam.ctrls; 999 ctrl = gspca_dev->cam.ctrls;
1010 if (ctrl != NULL) { 1000 if (ctrl != NULL) {
1011 for (i = 0; 1001 for (i = 0;
@@ -1057,77 +1047,50 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev,
1057static int vidioc_g_register(struct file *file, void *priv, 1047static int vidioc_g_register(struct file *file, void *priv,
1058 struct v4l2_dbg_register *reg) 1048 struct v4l2_dbg_register *reg)
1059{ 1049{
1060 int ret; 1050 struct gspca_dev *gspca_dev = video_drvdata(file);
1061 struct gspca_dev *gspca_dev = priv;
1062 1051
1063 if (!gspca_dev->sd_desc->get_chip_ident) 1052 if (!gspca_dev->sd_desc->get_chip_ident)
1064 return -EINVAL; 1053 return -ENOTTY;
1065 1054
1066 if (!gspca_dev->sd_desc->get_register) 1055 if (!gspca_dev->sd_desc->get_register)
1067 return -EINVAL; 1056 return -ENOTTY;
1068 1057
1069 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1070 return -ERESTARTSYS;
1071 gspca_dev->usb_err = 0; 1058 gspca_dev->usb_err = 0;
1072 if (gspca_dev->present) 1059 return gspca_dev->sd_desc->get_register(gspca_dev, reg);
1073 ret = gspca_dev->sd_desc->get_register(gspca_dev, reg);
1074 else
1075 ret = -ENODEV;
1076 mutex_unlock(&gspca_dev->usb_lock);
1077
1078 return ret;
1079} 1060}
1080 1061
1081static int vidioc_s_register(struct file *file, void *priv, 1062static int vidioc_s_register(struct file *file, void *priv,
1082 struct v4l2_dbg_register *reg) 1063 struct v4l2_dbg_register *reg)
1083{ 1064{
1084 int ret; 1065 struct gspca_dev *gspca_dev = video_drvdata(file);
1085 struct gspca_dev *gspca_dev = priv;
1086 1066
1087 if (!gspca_dev->sd_desc->get_chip_ident) 1067 if (!gspca_dev->sd_desc->get_chip_ident)
1088 return -EINVAL; 1068 return -ENOTTY;
1089 1069
1090 if (!gspca_dev->sd_desc->set_register) 1070 if (!gspca_dev->sd_desc->set_register)
1091 return -EINVAL; 1071 return -ENOTTY;
1092 1072
1093 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1094 return -ERESTARTSYS;
1095 gspca_dev->usb_err = 0; 1073 gspca_dev->usb_err = 0;
1096 if (gspca_dev->present) 1074 return gspca_dev->sd_desc->set_register(gspca_dev, reg);
1097 ret = gspca_dev->sd_desc->set_register(gspca_dev, reg);
1098 else
1099 ret = -ENODEV;
1100 mutex_unlock(&gspca_dev->usb_lock);
1101
1102 return ret;
1103} 1075}
1104#endif 1076#endif
1105 1077
1106static int vidioc_g_chip_ident(struct file *file, void *priv, 1078static int vidioc_g_chip_ident(struct file *file, void *priv,
1107 struct v4l2_dbg_chip_ident *chip) 1079 struct v4l2_dbg_chip_ident *chip)
1108{ 1080{
1109 int ret; 1081 struct gspca_dev *gspca_dev = video_drvdata(file);
1110 struct gspca_dev *gspca_dev = priv;
1111 1082
1112 if (!gspca_dev->sd_desc->get_chip_ident) 1083 if (!gspca_dev->sd_desc->get_chip_ident)
1113 return -EINVAL; 1084 return -ENOTTY;
1114 1085
1115 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1116 return -ERESTARTSYS;
1117 gspca_dev->usb_err = 0; 1086 gspca_dev->usb_err = 0;
1118 if (gspca_dev->present) 1087 return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
1119 ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
1120 else
1121 ret = -ENODEV;
1122 mutex_unlock(&gspca_dev->usb_lock);
1123
1124 return ret;
1125} 1088}
1126 1089
1127static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 1090static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1128 struct v4l2_fmtdesc *fmtdesc) 1091 struct v4l2_fmtdesc *fmtdesc)
1129{ 1092{
1130 struct gspca_dev *gspca_dev = priv; 1093 struct gspca_dev *gspca_dev = video_drvdata(file);
1131 int i, j, index; 1094 int i, j, index;
1132 __u32 fmt_tb[8]; 1095 __u32 fmt_tb[8];
1133 1096
@@ -1169,7 +1132,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1169static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 1132static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1170 struct v4l2_format *fmt) 1133 struct v4l2_format *fmt)
1171{ 1134{
1172 struct gspca_dev *gspca_dev = priv; 1135 struct gspca_dev *gspca_dev = video_drvdata(file);
1173 int mode; 1136 int mode;
1174 1137
1175 mode = gspca_dev->curr_mode; 1138 mode = gspca_dev->curr_mode;
@@ -1214,7 +1177,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file,
1214 void *priv, 1177 void *priv,
1215 struct v4l2_format *fmt) 1178 struct v4l2_format *fmt)
1216{ 1179{
1217 struct gspca_dev *gspca_dev = priv; 1180 struct gspca_dev *gspca_dev = video_drvdata(file);
1218 int ret; 1181 int ret;
1219 1182
1220 ret = try_fmt_vid_cap(gspca_dev, fmt); 1183 ret = try_fmt_vid_cap(gspca_dev, fmt);
@@ -1226,7 +1189,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file,
1226static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 1189static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1227 struct v4l2_format *fmt) 1190 struct v4l2_format *fmt)
1228{ 1191{
1229 struct gspca_dev *gspca_dev = priv; 1192 struct gspca_dev *gspca_dev = video_drvdata(file);
1230 int ret; 1193 int ret;
1231 1194
1232 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1195 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
@@ -1265,7 +1228,7 @@ out:
1265static int vidioc_enum_framesizes(struct file *file, void *priv, 1228static int vidioc_enum_framesizes(struct file *file, void *priv,
1266 struct v4l2_frmsizeenum *fsize) 1229 struct v4l2_frmsizeenum *fsize)
1267{ 1230{
1268 struct gspca_dev *gspca_dev = priv; 1231 struct gspca_dev *gspca_dev = video_drvdata(file);
1269 int i; 1232 int i;
1270 __u32 index = 0; 1233 __u32 index = 0;
1271 1234
@@ -1291,7 +1254,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
1291static int vidioc_enum_frameintervals(struct file *filp, void *priv, 1254static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1292 struct v4l2_frmivalenum *fival) 1255 struct v4l2_frmivalenum *fival)
1293{ 1256{
1294 struct gspca_dev *gspca_dev = priv; 1257 struct gspca_dev *gspca_dev = video_drvdata(filp);
1295 int mode = wxh_to_mode(gspca_dev, fival->width, fival->height); 1258 int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
1296 __u32 i; 1259 __u32 i;
1297 1260
@@ -1316,31 +1279,30 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1316 return -EINVAL; 1279 return -EINVAL;
1317} 1280}
1318 1281
1319static void gspca_release(struct video_device *vfd) 1282static void gspca_release(struct v4l2_device *v4l2_device)
1320{ 1283{
1321 struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); 1284 struct gspca_dev *gspca_dev =
1285 container_of(v4l2_device, struct gspca_dev, v4l2_dev);
1322 1286
1323 PDEBUG(D_PROBE, "%s released", 1287 PDEBUG(D_PROBE, "%s released",
1324 video_device_node_name(&gspca_dev->vdev)); 1288 video_device_node_name(&gspca_dev->vdev));
1325 1289
1290 v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
1291 v4l2_device_unregister(&gspca_dev->v4l2_dev);
1326 kfree(gspca_dev->usb_buf); 1292 kfree(gspca_dev->usb_buf);
1327 kfree(gspca_dev); 1293 kfree(gspca_dev);
1328} 1294}
1329 1295
1330static int dev_open(struct file *file) 1296static int dev_open(struct file *file)
1331{ 1297{
1332 struct gspca_dev *gspca_dev; 1298 struct gspca_dev *gspca_dev = video_drvdata(file);
1333 1299
1334 PDEBUG(D_STREAM, "[%s] open", current->comm); 1300 PDEBUG(D_STREAM, "[%s] open", current->comm);
1335 gspca_dev = (struct gspca_dev *) video_devdata(file);
1336 if (!gspca_dev->present)
1337 return -ENODEV;
1338 1301
1339 /* protect the subdriver against rmmod */ 1302 /* protect the subdriver against rmmod */
1340 if (!try_module_get(gspca_dev->module)) 1303 if (!try_module_get(gspca_dev->module))
1341 return -ENODEV; 1304 return -ENODEV;
1342 1305
1343 file->private_data = gspca_dev;
1344#ifdef GSPCA_DEBUG 1306#ifdef GSPCA_DEBUG
1345 /* activate the v4l2 debug */ 1307 /* activate the v4l2 debug */
1346 if (gspca_debug & D_V4L2) 1308 if (gspca_debug & D_V4L2)
@@ -1350,49 +1312,44 @@ static int dev_open(struct file *file)
1350 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL 1312 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
1351 | V4L2_DEBUG_IOCTL_ARG); 1313 | V4L2_DEBUG_IOCTL_ARG);
1352#endif 1314#endif
1353 return 0; 1315 return v4l2_fh_open(file);
1354} 1316}
1355 1317
1356static int dev_close(struct file *file) 1318static int dev_close(struct file *file)
1357{ 1319{
1358 struct gspca_dev *gspca_dev = file->private_data; 1320 struct gspca_dev *gspca_dev = video_drvdata(file);
1359 1321
1360 PDEBUG(D_STREAM, "[%s] close", current->comm); 1322 PDEBUG(D_STREAM, "[%s] close", current->comm);
1361 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1323
1324 /* Needed for gspca_stream_off, always lock before queue_lock! */
1325 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1362 return -ERESTARTSYS; 1326 return -ERESTARTSYS;
1363 1327
1328 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) {
1329 mutex_unlock(&gspca_dev->usb_lock);
1330 return -ERESTARTSYS;
1331 }
1332
1364 /* if the file did the capture, free the streaming resources */ 1333 /* if the file did the capture, free the streaming resources */
1365 if (gspca_dev->capt_file == file) { 1334 if (gspca_dev->capt_file == file) {
1366 if (gspca_dev->streaming) { 1335 if (gspca_dev->streaming)
1367 mutex_lock(&gspca_dev->usb_lock);
1368 gspca_dev->usb_err = 0;
1369 gspca_stream_off(gspca_dev); 1336 gspca_stream_off(gspca_dev);
1370 mutex_unlock(&gspca_dev->usb_lock);
1371 }
1372 frame_free(gspca_dev); 1337 frame_free(gspca_dev);
1373 } 1338 }
1374 file->private_data = NULL;
1375 module_put(gspca_dev->module); 1339 module_put(gspca_dev->module);
1376 mutex_unlock(&gspca_dev->queue_lock); 1340 mutex_unlock(&gspca_dev->queue_lock);
1341 mutex_unlock(&gspca_dev->usb_lock);
1377 1342
1378 PDEBUG(D_STREAM, "close done"); 1343 PDEBUG(D_STREAM, "close done");
1379 1344
1380 return 0; 1345 return v4l2_fh_release(file);
1381} 1346}
1382 1347
1383static int vidioc_querycap(struct file *file, void *priv, 1348static int vidioc_querycap(struct file *file, void *priv,
1384 struct v4l2_capability *cap) 1349 struct v4l2_capability *cap)
1385{ 1350{
1386 struct gspca_dev *gspca_dev = priv; 1351 struct gspca_dev *gspca_dev = video_drvdata(file);
1387 int ret;
1388 1352
1389 /* protect the access to the usb device */
1390 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1391 return -ERESTARTSYS;
1392 if (!gspca_dev->present) {
1393 ret = -ENODEV;
1394 goto out;
1395 }
1396 strlcpy((char *) cap->driver, gspca_dev->sd_desc->name, 1353 strlcpy((char *) cap->driver, gspca_dev->sd_desc->name,
1397 sizeof cap->driver); 1354 sizeof cap->driver);
1398 if (gspca_dev->dev->product != NULL) { 1355 if (gspca_dev->dev->product != NULL) {
@@ -1406,13 +1363,11 @@ static int vidioc_querycap(struct file *file, void *priv,
1406 } 1363 }
1407 usb_make_path(gspca_dev->dev, (char *) cap->bus_info, 1364 usb_make_path(gspca_dev->dev, (char *) cap->bus_info,
1408 sizeof(cap->bus_info)); 1365 sizeof(cap->bus_info));
1409 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE 1366 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
1410 | V4L2_CAP_STREAMING 1367 | V4L2_CAP_STREAMING
1411 | V4L2_CAP_READWRITE; 1368 | V4L2_CAP_READWRITE;
1412 ret = 0; 1369 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1413out: 1370 return 0;
1414 mutex_unlock(&gspca_dev->usb_lock);
1415 return ret;
1416} 1371}
1417 1372
1418static int get_ctrl(struct gspca_dev *gspca_dev, 1373static int get_ctrl(struct gspca_dev *gspca_dev,
@@ -1435,7 +1390,7 @@ static int get_ctrl(struct gspca_dev *gspca_dev,
1435static int vidioc_queryctrl(struct file *file, void *priv, 1390static int vidioc_queryctrl(struct file *file, void *priv,
1436 struct v4l2_queryctrl *q_ctrl) 1391 struct v4l2_queryctrl *q_ctrl)
1437{ 1392{
1438 struct gspca_dev *gspca_dev = priv; 1393 struct gspca_dev *gspca_dev = video_drvdata(file);
1439 const struct ctrl *ctrls; 1394 const struct ctrl *ctrls;
1440 struct gspca_ctrl *gspca_ctrl; 1395 struct gspca_ctrl *gspca_ctrl;
1441 int i, idx; 1396 int i, idx;
@@ -1478,10 +1433,10 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1478static int vidioc_s_ctrl(struct file *file, void *priv, 1433static int vidioc_s_ctrl(struct file *file, void *priv,
1479 struct v4l2_control *ctrl) 1434 struct v4l2_control *ctrl)
1480{ 1435{
1481 struct gspca_dev *gspca_dev = priv; 1436 struct gspca_dev *gspca_dev = video_drvdata(file);
1482 const struct ctrl *ctrls; 1437 const struct ctrl *ctrls;
1483 struct gspca_ctrl *gspca_ctrl; 1438 struct gspca_ctrl *gspca_ctrl;
1484 int idx, ret; 1439 int idx;
1485 1440
1486 idx = get_ctrl(gspca_dev, ctrl->id); 1441 idx = get_ctrl(gspca_dev, ctrl->id);
1487 if (idx < 0) 1442 if (idx < 0)
@@ -1501,74 +1456,52 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1501 return -ERANGE; 1456 return -ERANGE;
1502 } 1457 }
1503 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); 1458 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
1504 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1505 return -ERESTARTSYS;
1506 if (!gspca_dev->present) {
1507 ret = -ENODEV;
1508 goto out;
1509 }
1510 gspca_dev->usb_err = 0; 1459 gspca_dev->usb_err = 0;
1511 if (ctrls->set != NULL) { 1460 if (ctrls->set != NULL)
1512 ret = ctrls->set(gspca_dev, ctrl->value); 1461 return ctrls->set(gspca_dev, ctrl->value);
1513 goto out;
1514 }
1515 if (gspca_ctrl != NULL) { 1462 if (gspca_ctrl != NULL) {
1516 gspca_ctrl->val = ctrl->value; 1463 gspca_ctrl->val = ctrl->value;
1517 if (ctrls->set_control != NULL 1464 if (ctrls->set_control != NULL
1518 && gspca_dev->streaming) 1465 && gspca_dev->streaming)
1519 ctrls->set_control(gspca_dev); 1466 ctrls->set_control(gspca_dev);
1520 } 1467 }
1521 ret = gspca_dev->usb_err; 1468 return gspca_dev->usb_err;
1522out:
1523 mutex_unlock(&gspca_dev->usb_lock);
1524 return ret;
1525} 1469}
1526 1470
1527static int vidioc_g_ctrl(struct file *file, void *priv, 1471static int vidioc_g_ctrl(struct file *file, void *priv,
1528 struct v4l2_control *ctrl) 1472 struct v4l2_control *ctrl)
1529{ 1473{
1530 struct gspca_dev *gspca_dev = priv; 1474 struct gspca_dev *gspca_dev = video_drvdata(file);
1531 const struct ctrl *ctrls; 1475 const struct ctrl *ctrls;
1532 int idx, ret; 1476 int idx;
1533 1477
1534 idx = get_ctrl(gspca_dev, ctrl->id); 1478 idx = get_ctrl(gspca_dev, ctrl->id);
1535 if (idx < 0) 1479 if (idx < 0)
1536 return -EINVAL; 1480 return -EINVAL;
1537 ctrls = &gspca_dev->sd_desc->ctrls[idx]; 1481 ctrls = &gspca_dev->sd_desc->ctrls[idx];
1538 1482
1539 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1540 return -ERESTARTSYS;
1541 if (!gspca_dev->present) {
1542 ret = -ENODEV;
1543 goto out;
1544 }
1545 gspca_dev->usb_err = 0; 1483 gspca_dev->usb_err = 0;
1546 if (ctrls->get != NULL) { 1484 if (ctrls->get != NULL)
1547 ret = ctrls->get(gspca_dev, &ctrl->value); 1485 return ctrls->get(gspca_dev, &ctrl->value);
1548 goto out;
1549 }
1550 if (gspca_dev->cam.ctrls != NULL) 1486 if (gspca_dev->cam.ctrls != NULL)
1551 ctrl->value = gspca_dev->cam.ctrls[idx].val; 1487 ctrl->value = gspca_dev->cam.ctrls[idx].val;
1552 ret = 0; 1488 return 0;
1553out:
1554 mutex_unlock(&gspca_dev->usb_lock);
1555 return ret;
1556} 1489}
1557 1490
1558static int vidioc_querymenu(struct file *file, void *priv, 1491static int vidioc_querymenu(struct file *file, void *priv,
1559 struct v4l2_querymenu *qmenu) 1492 struct v4l2_querymenu *qmenu)
1560{ 1493{
1561 struct gspca_dev *gspca_dev = priv; 1494 struct gspca_dev *gspca_dev = video_drvdata(file);
1562 1495
1563 if (!gspca_dev->sd_desc->querymenu) 1496 if (!gspca_dev->sd_desc->querymenu)
1564 return -EINVAL; 1497 return -ENOTTY;
1565 return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu); 1498 return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu);
1566} 1499}
1567 1500
1568static int vidioc_enum_input(struct file *file, void *priv, 1501static int vidioc_enum_input(struct file *file, void *priv,
1569 struct v4l2_input *input) 1502 struct v4l2_input *input)
1570{ 1503{
1571 struct gspca_dev *gspca_dev = priv; 1504 struct gspca_dev *gspca_dev = video_drvdata(file);
1572 1505
1573 if (input->index != 0) 1506 if (input->index != 0)
1574 return -EINVAL; 1507 return -EINVAL;
@@ -1595,7 +1528,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1595static int vidioc_reqbufs(struct file *file, void *priv, 1528static int vidioc_reqbufs(struct file *file, void *priv,
1596 struct v4l2_requestbuffers *rb) 1529 struct v4l2_requestbuffers *rb)
1597{ 1530{
1598 struct gspca_dev *gspca_dev = priv; 1531 struct gspca_dev *gspca_dev = video_drvdata(file);
1599 int i, ret = 0, streaming; 1532 int i, ret = 0, streaming;
1600 1533
1601 i = rb->memory; /* (avoid compilation warning) */ 1534 i = rb->memory; /* (avoid compilation warning) */
@@ -1635,10 +1568,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1635 /* stop streaming */ 1568 /* stop streaming */
1636 streaming = gspca_dev->streaming; 1569 streaming = gspca_dev->streaming;
1637 if (streaming) { 1570 if (streaming) {
1638 mutex_lock(&gspca_dev->usb_lock);
1639 gspca_dev->usb_err = 0;
1640 gspca_stream_off(gspca_dev); 1571 gspca_stream_off(gspca_dev);
1641 mutex_unlock(&gspca_dev->usb_lock);
1642 1572
1643 /* Don't restart the stream when switching from read 1573 /* Don't restart the stream when switching from read
1644 * to mmap mode */ 1574 * to mmap mode */
@@ -1666,7 +1596,7 @@ out:
1666static int vidioc_querybuf(struct file *file, void *priv, 1596static int vidioc_querybuf(struct file *file, void *priv,
1667 struct v4l2_buffer *v4l2_buf) 1597 struct v4l2_buffer *v4l2_buf)
1668{ 1598{
1669 struct gspca_dev *gspca_dev = priv; 1599 struct gspca_dev *gspca_dev = video_drvdata(file);
1670 struct gspca_frame *frame; 1600 struct gspca_frame *frame;
1671 1601
1672 if (v4l2_buf->index < 0 1602 if (v4l2_buf->index < 0
@@ -1681,7 +1611,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
1681static int vidioc_streamon(struct file *file, void *priv, 1611static int vidioc_streamon(struct file *file, void *priv,
1682 enum v4l2_buf_type buf_type) 1612 enum v4l2_buf_type buf_type)
1683{ 1613{
1684 struct gspca_dev *gspca_dev = priv; 1614 struct gspca_dev *gspca_dev = video_drvdata(file);
1685 int ret; 1615 int ret;
1686 1616
1687 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1617 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1722,7 +1652,7 @@ out:
1722static int vidioc_streamoff(struct file *file, void *priv, 1652static int vidioc_streamoff(struct file *file, void *priv,
1723 enum v4l2_buf_type buf_type) 1653 enum v4l2_buf_type buf_type)
1724{ 1654{
1725 struct gspca_dev *gspca_dev = priv; 1655 struct gspca_dev *gspca_dev = video_drvdata(file);
1726 int ret; 1656 int ret;
1727 1657
1728 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1658 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1743,13 +1673,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
1743 } 1673 }
1744 1674
1745 /* stop streaming */ 1675 /* stop streaming */
1746 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
1747 ret = -ERESTARTSYS;
1748 goto out;
1749 }
1750 gspca_dev->usb_err = 0;
1751 gspca_stream_off(gspca_dev); 1676 gspca_stream_off(gspca_dev);
1752 mutex_unlock(&gspca_dev->usb_lock);
1753 /* In case another thread is waiting in dqbuf */ 1677 /* In case another thread is waiting in dqbuf */
1754 wake_up_interruptible(&gspca_dev->wq); 1678 wake_up_interruptible(&gspca_dev->wq);
1755 1679
@@ -1766,71 +1690,44 @@ out:
1766static int vidioc_g_jpegcomp(struct file *file, void *priv, 1690static int vidioc_g_jpegcomp(struct file *file, void *priv,
1767 struct v4l2_jpegcompression *jpegcomp) 1691 struct v4l2_jpegcompression *jpegcomp)
1768{ 1692{
1769 struct gspca_dev *gspca_dev = priv; 1693 struct gspca_dev *gspca_dev = video_drvdata(file);
1770 int ret;
1771 1694
1772 if (!gspca_dev->sd_desc->get_jcomp) 1695 if (!gspca_dev->sd_desc->get_jcomp)
1773 return -EINVAL; 1696 return -ENOTTY;
1774 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1775 return -ERESTARTSYS;
1776 gspca_dev->usb_err = 0; 1697 gspca_dev->usb_err = 0;
1777 if (gspca_dev->present) 1698 return gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
1778 ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
1779 else
1780 ret = -ENODEV;
1781 mutex_unlock(&gspca_dev->usb_lock);
1782 return ret;
1783} 1699}
1784 1700
1785static int vidioc_s_jpegcomp(struct file *file, void *priv, 1701static int vidioc_s_jpegcomp(struct file *file, void *priv,
1786 struct v4l2_jpegcompression *jpegcomp) 1702 struct v4l2_jpegcompression *jpegcomp)
1787{ 1703{
1788 struct gspca_dev *gspca_dev = priv; 1704 struct gspca_dev *gspca_dev = video_drvdata(file);
1789 int ret;
1790 1705
1791 if (!gspca_dev->sd_desc->set_jcomp) 1706 if (!gspca_dev->sd_desc->set_jcomp)
1792 return -EINVAL; 1707 return -ENOTTY;
1793 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1794 return -ERESTARTSYS;
1795 gspca_dev->usb_err = 0; 1708 gspca_dev->usb_err = 0;
1796 if (gspca_dev->present) 1709 return gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
1797 ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
1798 else
1799 ret = -ENODEV;
1800 mutex_unlock(&gspca_dev->usb_lock);
1801 return ret;
1802} 1710}
1803 1711
1804static int vidioc_g_parm(struct file *filp, void *priv, 1712static int vidioc_g_parm(struct file *filp, void *priv,
1805 struct v4l2_streamparm *parm) 1713 struct v4l2_streamparm *parm)
1806{ 1714{
1807 struct gspca_dev *gspca_dev = priv; 1715 struct gspca_dev *gspca_dev = video_drvdata(filp);
1808 1716
1809 parm->parm.capture.readbuffers = gspca_dev->nbufread; 1717 parm->parm.capture.readbuffers = gspca_dev->nbufread;
1810 1718
1811 if (gspca_dev->sd_desc->get_streamparm) { 1719 if (gspca_dev->sd_desc->get_streamparm) {
1812 int ret; 1720 gspca_dev->usb_err = 0;
1813 1721 gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
1814 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 1722 return gspca_dev->usb_err;
1815 return -ERESTARTSYS;
1816 if (gspca_dev->present) {
1817 gspca_dev->usb_err = 0;
1818 gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
1819 ret = gspca_dev->usb_err;
1820 } else {
1821 ret = -ENODEV;
1822 }
1823 mutex_unlock(&gspca_dev->usb_lock);
1824 return ret;
1825 } 1723 }
1826
1827 return 0; 1724 return 0;
1828} 1725}
1829 1726
1830static int vidioc_s_parm(struct file *filp, void *priv, 1727static int vidioc_s_parm(struct file *filp, void *priv,
1831 struct v4l2_streamparm *parm) 1728 struct v4l2_streamparm *parm)
1832{ 1729{
1833 struct gspca_dev *gspca_dev = priv; 1730 struct gspca_dev *gspca_dev = video_drvdata(filp);
1834 int n; 1731 int n;
1835 1732
1836 n = parm->parm.capture.readbuffers; 1733 n = parm->parm.capture.readbuffers;
@@ -1840,19 +1737,9 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1840 gspca_dev->nbufread = n; 1737 gspca_dev->nbufread = n;
1841 1738
1842 if (gspca_dev->sd_desc->set_streamparm) { 1739 if (gspca_dev->sd_desc->set_streamparm) {
1843 int ret; 1740 gspca_dev->usb_err = 0;
1844 1741 gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
1845 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 1742 return gspca_dev->usb_err;
1846 return -ERESTARTSYS;
1847 if (gspca_dev->present) {
1848 gspca_dev->usb_err = 0;
1849 gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
1850 ret = gspca_dev->usb_err;
1851 } else {
1852 ret = -ENODEV;
1853 }
1854 mutex_unlock(&gspca_dev->usb_lock);
1855 return ret;
1856 } 1743 }
1857 1744
1858 return 0; 1745 return 0;
@@ -1860,7 +1747,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1860 1747
1861static int dev_mmap(struct file *file, struct vm_area_struct *vma) 1748static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1862{ 1749{
1863 struct gspca_dev *gspca_dev = file->private_data; 1750 struct gspca_dev *gspca_dev = video_drvdata(file);
1864 struct gspca_frame *frame; 1751 struct gspca_frame *frame;
1865 struct page *page; 1752 struct page *page;
1866 unsigned long addr, start, size; 1753 unsigned long addr, start, size;
@@ -1872,10 +1759,6 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1872 1759
1873 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1760 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1874 return -ERESTARTSYS; 1761 return -ERESTARTSYS;
1875 if (!gspca_dev->present) {
1876 ret = -ENODEV;
1877 goto out;
1878 }
1879 if (gspca_dev->capt_file != file) { 1762 if (gspca_dev->capt_file != file) {
1880 ret = -EINVAL; 1763 ret = -EINVAL;
1881 goto out; 1764 goto out;
@@ -1963,7 +1846,7 @@ static int frame_ready(struct gspca_dev *gspca_dev, struct file *file,
1963static int vidioc_dqbuf(struct file *file, void *priv, 1846static int vidioc_dqbuf(struct file *file, void *priv,
1964 struct v4l2_buffer *v4l2_buf) 1847 struct v4l2_buffer *v4l2_buf)
1965{ 1848{
1966 struct gspca_dev *gspca_dev = priv; 1849 struct gspca_dev *gspca_dev = video_drvdata(file);
1967 struct gspca_frame *frame; 1850 struct gspca_frame *frame;
1968 int i, j, ret; 1851 int i, j, ret;
1969 1852
@@ -2003,14 +1886,6 @@ static int vidioc_dqbuf(struct file *file, void *priv,
2003 1886
2004 gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES; 1887 gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
2005 1888
2006 if (gspca_dev->sd_desc->dq_callback) {
2007 mutex_lock(&gspca_dev->usb_lock);
2008 gspca_dev->usb_err = 0;
2009 if (gspca_dev->present)
2010 gspca_dev->sd_desc->dq_callback(gspca_dev);
2011 mutex_unlock(&gspca_dev->usb_lock);
2012 }
2013
2014 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; 1889 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
2015 memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); 1890 memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
2016 PDEBUG(D_FRAM, "dqbuf %d", j); 1891 PDEBUG(D_FRAM, "dqbuf %d", j);
@@ -2027,6 +1902,15 @@ static int vidioc_dqbuf(struct file *file, void *priv,
2027 } 1902 }
2028out: 1903out:
2029 mutex_unlock(&gspca_dev->queue_lock); 1904 mutex_unlock(&gspca_dev->queue_lock);
1905
1906 if (ret == 0 && gspca_dev->sd_desc->dq_callback) {
1907 mutex_lock(&gspca_dev->usb_lock);
1908 gspca_dev->usb_err = 0;
1909 if (gspca_dev->present)
1910 gspca_dev->sd_desc->dq_callback(gspca_dev);
1911 mutex_unlock(&gspca_dev->usb_lock);
1912 }
1913
2030 return ret; 1914 return ret;
2031} 1915}
2032 1916
@@ -2039,7 +1923,7 @@ out:
2039static int vidioc_qbuf(struct file *file, void *priv, 1923static int vidioc_qbuf(struct file *file, void *priv,
2040 struct v4l2_buffer *v4l2_buf) 1924 struct v4l2_buffer *v4l2_buf)
2041{ 1925{
2042 struct gspca_dev *gspca_dev = priv; 1926 struct gspca_dev *gspca_dev = video_drvdata(file);
2043 struct gspca_frame *frame; 1927 struct gspca_frame *frame;
2044 int i, index, ret; 1928 int i, index, ret;
2045 1929
@@ -2098,6 +1982,10 @@ static int read_alloc(struct gspca_dev *gspca_dev,
2098 int i, ret; 1982 int i, ret;
2099 1983
2100 PDEBUG(D_STREAM, "read alloc"); 1984 PDEBUG(D_STREAM, "read alloc");
1985
1986 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1987 return -ERESTARTSYS;
1988
2101 if (gspca_dev->nframes == 0) { 1989 if (gspca_dev->nframes == 0) {
2102 struct v4l2_requestbuffers rb; 1990 struct v4l2_requestbuffers rb;
2103 1991
@@ -2108,7 +1996,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
2108 ret = vidioc_reqbufs(file, gspca_dev, &rb); 1996 ret = vidioc_reqbufs(file, gspca_dev, &rb);
2109 if (ret != 0) { 1997 if (ret != 0) {
2110 PDEBUG(D_STREAM, "read reqbuf err %d", ret); 1998 PDEBUG(D_STREAM, "read reqbuf err %d", ret);
2111 return ret; 1999 goto out;
2112 } 2000 }
2113 memset(&v4l2_buf, 0, sizeof v4l2_buf); 2001 memset(&v4l2_buf, 0, sizeof v4l2_buf);
2114 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2002 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -2118,61 +2006,69 @@ static int read_alloc(struct gspca_dev *gspca_dev,
2118 ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); 2006 ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
2119 if (ret != 0) { 2007 if (ret != 0) {
2120 PDEBUG(D_STREAM, "read qbuf err: %d", ret); 2008 PDEBUG(D_STREAM, "read qbuf err: %d", ret);
2121 return ret; 2009 goto out;
2122 } 2010 }
2123 } 2011 }
2124 gspca_dev->memory = GSPCA_MEMORY_READ;
2125 } 2012 }
2126 2013
2127 /* start streaming */ 2014 /* start streaming */
2128 ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE); 2015 ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
2129 if (ret != 0) 2016 if (ret != 0)
2130 PDEBUG(D_STREAM, "read streamon err %d", ret); 2017 PDEBUG(D_STREAM, "read streamon err %d", ret);
2018out:
2019 mutex_unlock(&gspca_dev->usb_lock);
2131 return ret; 2020 return ret;
2132} 2021}
2133 2022
2134static unsigned int dev_poll(struct file *file, poll_table *wait) 2023static unsigned int dev_poll(struct file *file, poll_table *wait)
2135{ 2024{
2136 struct gspca_dev *gspca_dev = file->private_data; 2025 struct gspca_dev *gspca_dev = video_drvdata(file);
2137 int ret; 2026 unsigned long req_events = poll_requested_events(wait);
2027 int ret = 0;
2138 2028
2139 PDEBUG(D_FRAM, "poll"); 2029 PDEBUG(D_FRAM, "poll");
2140 2030
2141 poll_wait(file, &gspca_dev->wq, wait); 2031 if (req_events & POLLPRI)
2032 ret |= v4l2_ctrl_poll(file, wait);
2142 2033
2143 /* if reqbufs is not done, the user would use read() */ 2034 if (req_events & (POLLIN | POLLRDNORM)) {
2144 if (gspca_dev->memory == GSPCA_MEMORY_NO) { 2035 /* if reqbufs is not done, the user would use read() */
2145 ret = read_alloc(gspca_dev, file); 2036 if (gspca_dev->memory == GSPCA_MEMORY_NO) {
2146 if (ret != 0) 2037 if (read_alloc(gspca_dev, file) != 0) {
2147 return POLLERR; 2038 ret |= POLLERR;
2148 } 2039 goto out;
2040 }
2041 }
2149 2042
2150 if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) 2043 poll_wait(file, &gspca_dev->wq, wait);
2151 return POLLERR;
2152 2044
2153 /* check if an image has been received */ 2045 /* check if an image has been received */
2154 if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i)) 2046 if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) {
2155 ret = POLLIN | POLLRDNORM; /* yes */ 2047 ret |= POLLERR;
2156 else 2048 goto out;
2157 ret = 0; 2049 }
2158 mutex_unlock(&gspca_dev->queue_lock); 2050 if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i))
2051 ret |= POLLIN | POLLRDNORM;
2052 mutex_unlock(&gspca_dev->queue_lock);
2053 }
2054
2055out:
2159 if (!gspca_dev->present) 2056 if (!gspca_dev->present)
2160 return POLLHUP; 2057 ret |= POLLHUP;
2058
2161 return ret; 2059 return ret;
2162} 2060}
2163 2061
2164static ssize_t dev_read(struct file *file, char __user *data, 2062static ssize_t dev_read(struct file *file, char __user *data,
2165 size_t count, loff_t *ppos) 2063 size_t count, loff_t *ppos)
2166{ 2064{
2167 struct gspca_dev *gspca_dev = file->private_data; 2065 struct gspca_dev *gspca_dev = video_drvdata(file);
2168 struct gspca_frame *frame; 2066 struct gspca_frame *frame;
2169 struct v4l2_buffer v4l2_buf; 2067 struct v4l2_buffer v4l2_buf;
2170 struct timeval timestamp; 2068 struct timeval timestamp;
2171 int n, ret, ret2; 2069 int n, ret, ret2;
2172 2070
2173 PDEBUG(D_FRAM, "read (%zd)", count); 2071 PDEBUG(D_FRAM, "read (%zd)", count);
2174 if (!gspca_dev->present)
2175 return -ENODEV;
2176 if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */ 2072 if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
2177 ret = read_alloc(gspca_dev, file); 2073 ret = read_alloc(gspca_dev, file);
2178 if (ret != 0) 2074 if (ret != 0)
@@ -2266,13 +2162,15 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
2266 .vidioc_s_register = vidioc_s_register, 2162 .vidioc_s_register = vidioc_s_register,
2267#endif 2163#endif
2268 .vidioc_g_chip_ident = vidioc_g_chip_ident, 2164 .vidioc_g_chip_ident = vidioc_g_chip_ident,
2165 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
2166 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2269}; 2167};
2270 2168
2271static const struct video_device gspca_template = { 2169static const struct video_device gspca_template = {
2272 .name = "gspca main driver", 2170 .name = "gspca main driver",
2273 .fops = &dev_fops, 2171 .fops = &dev_fops,
2274 .ioctl_ops = &dev_ioctl_ops, 2172 .ioctl_ops = &dev_ioctl_ops,
2275 .release = gspca_release, 2173 .release = video_device_release_empty, /* We use v4l2_dev.release */
2276}; 2174};
2277 2175
2278/* initialize the controls */ 2176/* initialize the controls */
@@ -2344,9 +2242,24 @@ int gspca_dev_probe2(struct usb_interface *intf,
2344 } 2242 }
2345 } 2243 }
2346 2244
2245 gspca_dev->v4l2_dev.release = gspca_release;
2246 ret = v4l2_device_register(&intf->dev, &gspca_dev->v4l2_dev);
2247 if (ret)
2248 goto out;
2347 gspca_dev->sd_desc = sd_desc; 2249 gspca_dev->sd_desc = sd_desc;
2348 gspca_dev->nbufread = 2; 2250 gspca_dev->nbufread = 2;
2349 gspca_dev->empty_packet = -1; /* don't check the empty packets */ 2251 gspca_dev->empty_packet = -1; /* don't check the empty packets */
2252 gspca_dev->vdev = gspca_template;
2253 gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev;
2254 video_set_drvdata(&gspca_dev->vdev, gspca_dev);
2255 set_bit(V4L2_FL_USE_FH_PRIO, &gspca_dev->vdev.flags);
2256 gspca_dev->module = module;
2257 gspca_dev->present = 1;
2258
2259 mutex_init(&gspca_dev->usb_lock);
2260 gspca_dev->vdev.lock = &gspca_dev->usb_lock;
2261 mutex_init(&gspca_dev->queue_lock);
2262 init_waitqueue_head(&gspca_dev->wq);
2350 2263
2351 /* configure the subdriver and initialize the USB device */ 2264 /* configure the subdriver and initialize the USB device */
2352 ret = sd_desc->config(gspca_dev, id); 2265 ret = sd_desc->config(gspca_dev, id);
@@ -2357,21 +2270,26 @@ int gspca_dev_probe2(struct usb_interface *intf,
2357 ret = sd_desc->init(gspca_dev); 2270 ret = sd_desc->init(gspca_dev);
2358 if (ret < 0) 2271 if (ret < 0)
2359 goto out; 2272 goto out;
2273 if (sd_desc->init_controls)
2274 ret = sd_desc->init_controls(gspca_dev);
2275 if (ret < 0)
2276 goto out;
2360 gspca_set_default_mode(gspca_dev); 2277 gspca_set_default_mode(gspca_dev);
2361 2278
2362 ret = gspca_input_connect(gspca_dev); 2279 ret = gspca_input_connect(gspca_dev);
2363 if (ret) 2280 if (ret)
2364 goto out; 2281 goto out;
2365 2282
2366 mutex_init(&gspca_dev->usb_lock); 2283 /*
2367 mutex_init(&gspca_dev->queue_lock); 2284 * Don't take usb_lock for these ioctls. This improves latency if
2368 init_waitqueue_head(&gspca_dev->wq); 2285 * usb_lock is taken for a long time, e.g. when changing a control
2286 * value, and a new frame is ready to be dequeued.
2287 */
2288 v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF);
2289 v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF);
2290 v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF);
2369 2291
2370 /* init video stuff */ 2292 /* init video stuff */
2371 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
2372 gspca_dev->vdev.parent = &intf->dev;
2373 gspca_dev->module = module;
2374 gspca_dev->present = 1;
2375 ret = video_register_device(&gspca_dev->vdev, 2293 ret = video_register_device(&gspca_dev->vdev,
2376 VFL_TYPE_GRABBER, 2294 VFL_TYPE_GRABBER,
2377 -1); 2295 -1);
@@ -2391,6 +2309,7 @@ out:
2391 if (gspca_dev->input_dev) 2309 if (gspca_dev->input_dev)
2392 input_unregister_device(gspca_dev->input_dev); 2310 input_unregister_device(gspca_dev->input_dev);
2393#endif 2311#endif
2312 v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
2394 kfree(gspca_dev->usb_buf); 2313 kfree(gspca_dev->usb_buf);
2395 kfree(gspca_dev); 2314 kfree(gspca_dev);
2396 return ret; 2315 return ret;
@@ -2437,11 +2356,12 @@ void gspca_disconnect(struct usb_interface *intf)
2437 2356
2438 PDEBUG(D_PROBE, "%s disconnect", 2357 PDEBUG(D_PROBE, "%s disconnect",
2439 video_device_node_name(&gspca_dev->vdev)); 2358 video_device_node_name(&gspca_dev->vdev));
2359
2440 mutex_lock(&gspca_dev->usb_lock); 2360 mutex_lock(&gspca_dev->usb_lock);
2441 2361
2362 usb_set_intfdata(intf, NULL);
2363 gspca_dev->dev = NULL;
2442 gspca_dev->present = 0; 2364 gspca_dev->present = 0;
2443 wake_up_interruptible(&gspca_dev->wq);
2444
2445 destroy_urbs(gspca_dev); 2365 destroy_urbs(gspca_dev);
2446 2366
2447#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 2367#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
@@ -2452,18 +2372,19 @@ void gspca_disconnect(struct usb_interface *intf)
2452 input_unregister_device(input_dev); 2372 input_unregister_device(input_dev);
2453 } 2373 }
2454#endif 2374#endif
2375 /* Free subdriver's streaming resources / stop sd workqueue(s) */
2376 if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming)
2377 gspca_dev->sd_desc->stop0(gspca_dev);
2378 gspca_dev->streaming = 0;
2379 wake_up_interruptible(&gspca_dev->wq);
2455 2380
2456 /* the device is freed at exit of this function */ 2381 v4l2_device_disconnect(&gspca_dev->v4l2_dev);
2457 gspca_dev->dev = NULL; 2382 video_unregister_device(&gspca_dev->vdev);
2458 mutex_unlock(&gspca_dev->usb_lock);
2459 2383
2460 usb_set_intfdata(intf, NULL); 2384 mutex_unlock(&gspca_dev->usb_lock);
2461 2385
2462 /* release the device */
2463 /* (this will call gspca_release() immediately or on last close) */ 2386 /* (this will call gspca_release() immediately or on last close) */
2464 video_unregister_device(&gspca_dev->vdev); 2387 v4l2_device_put(&gspca_dev->v4l2_dev);
2465
2466/* PDEBUG(D_PROBE, "disconnect complete"); */
2467} 2388}
2468EXPORT_SYMBOL(gspca_disconnect); 2389EXPORT_SYMBOL(gspca_disconnect);
2469 2390
@@ -2474,7 +2395,9 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message)
2474 2395
2475 if (!gspca_dev->streaming) 2396 if (!gspca_dev->streaming)
2476 return 0; 2397 return 0;
2398 mutex_lock(&gspca_dev->usb_lock);
2477 gspca_dev->frozen = 1; /* avoid urb error messages */ 2399 gspca_dev->frozen = 1; /* avoid urb error messages */
2400 gspca_dev->usb_err = 0;
2478 if (gspca_dev->sd_desc->stopN) 2401 if (gspca_dev->sd_desc->stopN)
2479 gspca_dev->sd_desc->stopN(gspca_dev); 2402 gspca_dev->sd_desc->stopN(gspca_dev);
2480 destroy_urbs(gspca_dev); 2403 destroy_urbs(gspca_dev);
@@ -2482,6 +2405,7 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message)
2482 gspca_set_alt0(gspca_dev); 2405 gspca_set_alt0(gspca_dev);
2483 if (gspca_dev->sd_desc->stop0) 2406 if (gspca_dev->sd_desc->stop0)
2484 gspca_dev->sd_desc->stop0(gspca_dev); 2407 gspca_dev->sd_desc->stop0(gspca_dev);
2408 mutex_unlock(&gspca_dev->usb_lock);
2485 return 0; 2409 return 0;
2486} 2410}
2487EXPORT_SYMBOL(gspca_suspend); 2411EXPORT_SYMBOL(gspca_suspend);
@@ -2489,105 +2413,28 @@ EXPORT_SYMBOL(gspca_suspend);
2489int gspca_resume(struct usb_interface *intf) 2413int gspca_resume(struct usb_interface *intf)
2490{ 2414{
2491 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2415 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2416 int streaming, ret = 0;
2492 2417
2418 mutex_lock(&gspca_dev->usb_lock);
2493 gspca_dev->frozen = 0; 2419 gspca_dev->frozen = 0;
2420 gspca_dev->usb_err = 0;
2494 gspca_dev->sd_desc->init(gspca_dev); 2421 gspca_dev->sd_desc->init(gspca_dev);
2495 gspca_input_create_urb(gspca_dev); 2422 gspca_input_create_urb(gspca_dev);
2496 if (gspca_dev->streaming) 2423 /*
2497 return gspca_init_transfer(gspca_dev); 2424 * Most subdrivers send all ctrl values on sd_start and thus
2498 return 0; 2425 * only write to the device registers on s_ctrl when streaming ->
2426 * Clear streaming to avoid setting all ctrls twice.
2427 */
2428 streaming = gspca_dev->streaming;
2429 gspca_dev->streaming = 0;
2430 v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler);
2431 if (streaming)
2432 ret = gspca_init_transfer(gspca_dev);
2433 mutex_unlock(&gspca_dev->usb_lock);
2434 return ret;
2499} 2435}
2500EXPORT_SYMBOL(gspca_resume); 2436EXPORT_SYMBOL(gspca_resume);
2501#endif 2437#endif
2502/* -- cam driver utility functions -- */
2503
2504/* auto gain and exposure algorithm based on the knee algorithm described here:
2505 http://ytse.tricolour.net/docs/LowLightOptimization.html
2506
2507 Returns 0 if no changes were made, 1 if the gain and or exposure settings
2508 where changed. */
2509int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
2510 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee)
2511{
2512 int i, steps, gain, orig_gain, exposure, orig_exposure, autogain;
2513 const struct ctrl *gain_ctrl = NULL;
2514 const struct ctrl *exposure_ctrl = NULL;
2515 const struct ctrl *autogain_ctrl = NULL;
2516 int retval = 0;
2517
2518 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
2519 if (gspca_dev->ctrl_dis & (1 << i))
2520 continue;
2521 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
2522 gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
2523 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
2524 exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
2525 if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_AUTOGAIN)
2526 autogain_ctrl = &gspca_dev->sd_desc->ctrls[i];
2527 }
2528 if (!gain_ctrl || !exposure_ctrl || !autogain_ctrl) {
2529 PDEBUG(D_ERR, "Error: gspca_auto_gain_n_exposure called "
2530 "on cam without (auto)gain/exposure");
2531 return 0;
2532 }
2533
2534 if (gain_ctrl->get(gspca_dev, &gain) ||
2535 exposure_ctrl->get(gspca_dev, &exposure) ||
2536 autogain_ctrl->get(gspca_dev, &autogain) || !autogain)
2537 return 0;
2538
2539 orig_gain = gain;
2540 orig_exposure = exposure;
2541
2542 /* If we are of a multiple of deadzone, do multiple steps to reach the
2543 desired lumination fast (with the risc of a slight overshoot) */
2544 steps = abs(desired_avg_lum - avg_lum) / deadzone;
2545
2546 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
2547 avg_lum, desired_avg_lum, steps);
2548
2549 for (i = 0; i < steps; i++) {
2550 if (avg_lum > desired_avg_lum) {
2551 if (gain > gain_knee)
2552 gain--;
2553 else if (exposure > exposure_knee)
2554 exposure--;
2555 else if (gain > gain_ctrl->qctrl.default_value)
2556 gain--;
2557 else if (exposure > exposure_ctrl->qctrl.minimum)
2558 exposure--;
2559 else if (gain > gain_ctrl->qctrl.minimum)
2560 gain--;
2561 else
2562 break;
2563 } else {
2564 if (gain < gain_ctrl->qctrl.default_value)
2565 gain++;
2566 else if (exposure < exposure_knee)
2567 exposure++;
2568 else if (gain < gain_knee)
2569 gain++;
2570 else if (exposure < exposure_ctrl->qctrl.maximum)
2571 exposure++;
2572 else if (gain < gain_ctrl->qctrl.maximum)
2573 gain++;
2574 else
2575 break;
2576 }
2577 }
2578
2579 if (gain != orig_gain) {
2580 gain_ctrl->set(gspca_dev, gain);
2581 retval = 1;
2582 }
2583 if (exposure != orig_exposure) {
2584 exposure_ctrl->set(gspca_dev, exposure);
2585 retval = 1;
2586 }
2587
2588 return retval;
2589}
2590EXPORT_SYMBOL(gspca_auto_gain_n_exposure);
2591 2438
2592/* -- module insert / remove -- */ 2439/* -- module insert / remove -- */
2593static int __init gspca_init(void) 2440static int __init gspca_init(void)
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 589009f4496f..dc688c7f5e48 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -6,6 +6,8 @@
6#include <linux/usb.h> 6#include <linux/usb.h>
7#include <linux/videodev2.h> 7#include <linux/videodev2.h>
8#include <media/v4l2-common.h> 8#include <media/v4l2-common.h>
9#include <media/v4l2-ctrls.h>
10#include <media/v4l2-device.h>
9#include <linux/mutex.h> 11#include <linux/mutex.h>
10 12
11/* compilation option */ 13/* compilation option */
@@ -115,6 +117,7 @@ struct sd_desc {
115/* mandatory operations */ 117/* mandatory operations */
116 cam_cf_op config; /* called on probe */ 118 cam_cf_op config; /* called on probe */
117 cam_op init; /* called on probe and resume */ 119 cam_op init; /* called on probe and resume */
120 cam_op init_controls; /* called on probe */
118 cam_op start; /* called on stream on after URBs creation */ 121 cam_op start; /* called on stream on after URBs creation */
119 cam_pkt_op pkt_scan; 122 cam_pkt_op pkt_scan;
120/* optional operations */ 123/* optional operations */
@@ -158,8 +161,10 @@ struct gspca_frame {
158struct gspca_dev { 161struct gspca_dev {
159 struct video_device vdev; /* !! must be the first item */ 162 struct video_device vdev; /* !! must be the first item */
160 struct module *module; /* subdriver handling the device */ 163 struct module *module; /* subdriver handling the device */
164 struct v4l2_device v4l2_dev;
161 struct usb_device *dev; 165 struct usb_device *dev;
162 struct file *capt_file; /* file doing video capture */ 166 struct file *capt_file; /* file doing video capture */
167 /* protected by queue_lock */
163#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 168#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
164 struct input_dev *input_dev; 169 struct input_dev *input_dev;
165 char phys[64]; /* physical device path */ 170 char phys[64]; /* physical device path */
@@ -169,6 +174,16 @@ struct gspca_dev {
169 const struct sd_desc *sd_desc; /* subdriver description */ 174 const struct sd_desc *sd_desc; /* subdriver description */
170 unsigned ctrl_dis; /* disabled controls (bit map) */ 175 unsigned ctrl_dis; /* disabled controls (bit map) */
171 unsigned ctrl_inac; /* inactive controls (bit map) */ 176 unsigned ctrl_inac; /* inactive controls (bit map) */
177 struct v4l2_ctrl_handler ctrl_handler;
178
179 /* autogain and exposure or gain control cluster, these are global as
180 the autogain/exposure functions in autogain_functions.c use them */
181 struct {
182 struct v4l2_ctrl *autogain;
183 struct v4l2_ctrl *exposure;
184 struct v4l2_ctrl *gain;
185 int exp_too_low_cnt, exp_too_high_cnt;
186 };
172 187
173#define USB_BUF_SZ 64 188#define USB_BUF_SZ 64
174 __u8 *usb_buf; /* buffer for USB exchanges */ 189 __u8 *usb_buf; /* buffer for USB exchanges */
@@ -189,7 +204,7 @@ struct gspca_dev {
189 u8 fr_o; /* next frame to dequeue */ 204 u8 fr_o; /* next frame to dequeue */
190 __u8 last_packet_type; 205 __u8 last_packet_type;
191 __s8 empty_packet; /* if (-1) don't check empty packets */ 206 __s8 empty_packet; /* if (-1) don't check empty packets */
192 __u8 streaming; 207 __u8 streaming; /* protected by both mutexes (*) */
193 208
194 __u8 curr_mode; /* current camera mode */ 209 __u8 curr_mode; /* current camera mode */
195 __u32 pixfmt; /* current mode parameters */ 210 __u32 pixfmt; /* current mode parameters */
@@ -211,6 +226,10 @@ struct gspca_dev {
211 __u8 iface; /* USB interface number */ 226 __u8 iface; /* USB interface number */
212 __u8 alt; /* USB alternate setting */ 227 __u8 alt; /* USB alternate setting */
213 u8 audio; /* presence of audio device */ 228 u8 audio; /* presence of audio device */
229
230 /* (*) These variables are proteced by both usb_lock and queue_lock,
231 that is any code setting them is holding *both*, which means that
232 any code getting them needs to hold at least one of them */
214}; 233};
215 234
216int gspca_dev_probe(struct usb_interface *intf, 235int gspca_dev_probe(struct usb_interface *intf,
@@ -232,6 +251,9 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
232int gspca_suspend(struct usb_interface *intf, pm_message_t message); 251int gspca_suspend(struct usb_interface *intf, pm_message_t message);
233int gspca_resume(struct usb_interface *intf); 252int gspca_resume(struct usb_interface *intf);
234#endif 253#endif
235int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, 254int gspca_expo_autogain(struct gspca_dev *gspca_dev, int avg_lum,
236 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); 255 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
256int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
257 int avg_lum, int desired_avg_lum, int deadzone);
258
237#endif /* GSPCAV2_H */ 259#endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c
index 53f58ef367cf..9c591c7c6f54 100644
--- a/drivers/media/video/gspca/jl2005bcd.c
+++ b/drivers/media/video/gspca/jl2005bcd.c
@@ -335,7 +335,11 @@ static void jl2005c_dostream(struct work_struct *work)
335 goto quit_stream; 335 goto quit_stream;
336 } 336 }
337 337
338 while (gspca_dev->present && gspca_dev->streaming) { 338 while (gspca_dev->dev && gspca_dev->streaming) {
339#ifdef CONFIG_PM
340 if (gspca_dev->frozen)
341 break;
342#endif
339 /* Check if this is a new frame. If so, start the frame first */ 343 /* Check if this is a new frame. If so, start the frame first */
340 if (!header_read) { 344 if (!header_read) {
341 mutex_lock(&gspca_dev->usb_lock); 345 mutex_lock(&gspca_dev->usb_lock);
@@ -367,7 +371,7 @@ static void jl2005c_dostream(struct work_struct *work)
367 buffer, act_len); 371 buffer, act_len);
368 header_read = 1; 372 header_read = 1;
369 } 373 }
370 while (bytes_left > 0 && gspca_dev->present) { 374 while (bytes_left > 0 && gspca_dev->dev) {
371 data_len = bytes_left > JL2005C_MAX_TRANSFER ? 375 data_len = bytes_left > JL2005C_MAX_TRANSFER ?
372 JL2005C_MAX_TRANSFER : bytes_left; 376 JL2005C_MAX_TRANSFER : bytes_left;
373 ret = usb_bulk_msg(gspca_dev->dev, 377 ret = usb_bulk_msg(gspca_dev->dev,
@@ -390,7 +394,7 @@ static void jl2005c_dostream(struct work_struct *work)
390 } 394 }
391 } 395 }
392quit_stream: 396quit_stream:
393 if (gspca_dev->present) { 397 if (gspca_dev->dev) {
394 mutex_lock(&gspca_dev->usb_lock); 398 mutex_lock(&gspca_dev->usb_lock);
395 jl2005c_stop(gspca_dev); 399 jl2005c_stop(gspca_dev);
396 mutex_unlock(&gspca_dev->usb_lock); 400 mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index b0231465afae..ec7b21ee79fb 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -30,22 +30,19 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); 30MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33/* controls */
34enum e_ctrl {
35 BRIGHTNESS,
36 COLORS,
37 GAMMA,
38 SHARPNESS,
39 ILLUM_TOP,
40 ILLUM_BOT,
41 NCTRLS /* number of controls */
42};
43
44/* specific webcam descriptor */ 33/* specific webcam descriptor */
45struct sd { 34struct sd {
46 struct gspca_dev gspca_dev; /* !! must be the first item */ 35 struct gspca_dev gspca_dev; /* !! must be the first item */
47 36
48 struct gspca_ctrl ctrls[NCTRLS]; 37 struct v4l2_ctrl *brightness;
38 struct v4l2_ctrl *saturation;
39 struct v4l2_ctrl *sharpness;
40 struct v4l2_ctrl *gamma;
41 struct { /* illuminator control cluster */
42 struct v4l2_ctrl *illum_top;
43 struct v4l2_ctrl *illum_bottom;
44 };
45 struct v4l2_ctrl *jpegqual;
49 46
50 u8 quality; 47 u8 quality;
51#define QUALITY_MIN 40 48#define QUALITY_MIN 40
@@ -56,89 +53,10 @@ struct sd {
56}; 53};
57 54
58/* V4L2 controls supported by the driver */ 55/* V4L2 controls supported by the driver */
59static void setbrightness(struct gspca_dev *gspca_dev); 56static void setbrightness(struct gspca_dev *gspca_dev, s32 val);
60static void setcolors(struct gspca_dev *gspca_dev); 57static void setcolors(struct gspca_dev *gspca_dev, s32 val);
61static void setgamma(struct gspca_dev *gspca_dev); 58static void setgamma(struct gspca_dev *gspca_dev, s32 val);
62static void setsharpness(struct gspca_dev *gspca_dev); 59static void setsharpness(struct gspca_dev *gspca_dev, s32 val);
63static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val);
64static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val);
65
66static const struct ctrl sd_ctrls[NCTRLS] = {
67[BRIGHTNESS] = {
68 {
69 .id = V4L2_CID_BRIGHTNESS,
70 .type = V4L2_CTRL_TYPE_INTEGER,
71 .name = "Brightness",
72 .minimum = 0,
73 .maximum = 30,
74 .step = 1,
75 .default_value = 15,
76 },
77 .set_control = setbrightness
78 },
79[COLORS] = {
80 {
81 .id = V4L2_CID_SATURATION,
82 .type = V4L2_CTRL_TYPE_INTEGER,
83 .name = "Color",
84 .minimum = 1,
85 .maximum = 255,
86 .step = 1,
87 .default_value = 200,
88 },
89 .set_control = setcolors
90 },
91[GAMMA] = {
92 {
93 .id = V4L2_CID_GAMMA,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "Gamma",
96 .minimum = 0,
97 .maximum = 3,
98 .step = 1,
99 .default_value = 1,
100 },
101 .set_control = setgamma
102 },
103[SHARPNESS] = {
104 {
105 .id = V4L2_CID_SHARPNESS,
106 .type = V4L2_CTRL_TYPE_INTEGER,
107 .name = "Sharpness",
108 .minimum = 0,
109 .maximum = 2,
110 .step = 1,
111 .default_value = 1,
112 },
113 .set_control = setsharpness
114 },
115[ILLUM_TOP] = {
116 {
117 .id = V4L2_CID_ILLUMINATORS_1,
118 .type = V4L2_CTRL_TYPE_BOOLEAN,
119 .name = "Top illuminator",
120 .minimum = 0,
121 .maximum = 1,
122 .step = 1,
123 .default_value = 0,
124 .flags = V4L2_CTRL_FLAG_UPDATE,
125 },
126 .set = sd_setilluminator1
127 },
128[ILLUM_BOT] = {
129 {
130 .id = V4L2_CID_ILLUMINATORS_2,
131 .type = V4L2_CTRL_TYPE_BOOLEAN,
132 .name = "Bottom illuminator",
133 .minimum = 0,
134 .maximum = 1,
135 .step = 1,
136 .default_value = 0,
137 .flags = V4L2_CTRL_FLAG_UPDATE,
138 },
139 .set = sd_setilluminator2
140 },
141};
142 60
143static const struct v4l2_pix_format vga_mode[] = { 61static const struct v4l2_pix_format vga_mode[] = {
144 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 62 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -198,59 +116,130 @@ static void mi_w(struct gspca_dev *gspca_dev,
198 reg_w(gspca_dev, 4); 116 reg_w(gspca_dev, 4);
199} 117}
200 118
201static void setbrightness(struct gspca_dev *gspca_dev) 119static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
202{ 120{
203 struct sd *sd = (struct sd *) gspca_dev;
204
205 gspca_dev->usb_buf[0] = 0x61; 121 gspca_dev->usb_buf[0] = 0x61;
206 gspca_dev->usb_buf[1] = sd->ctrls[BRIGHTNESS].val; 122 gspca_dev->usb_buf[1] = val;
207 reg_w(gspca_dev, 2); 123 reg_w(gspca_dev, 2);
208} 124}
209 125
210static void setcolors(struct gspca_dev *gspca_dev) 126static void setcolors(struct gspca_dev *gspca_dev, s32 val)
211{ 127{
212 struct sd *sd = (struct sd *) gspca_dev;
213 s16 val;
214
215 val = sd->ctrls[COLORS].val;
216 gspca_dev->usb_buf[0] = 0x5f; 128 gspca_dev->usb_buf[0] = 0x5f;
217 gspca_dev->usb_buf[1] = val << 3; 129 gspca_dev->usb_buf[1] = val << 3;
218 gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04; 130 gspca_dev->usb_buf[2] = ((val >> 2) & 0xf8) | 0x04;
219 reg_w(gspca_dev, 3); 131 reg_w(gspca_dev, 3);
220} 132}
221 133
222static void setgamma(struct gspca_dev *gspca_dev) 134static void setgamma(struct gspca_dev *gspca_dev, s32 val)
223{ 135{
224 struct sd *sd = (struct sd *) gspca_dev;
225
226 gspca_dev->usb_buf[0] = 0x06; 136 gspca_dev->usb_buf[0] = 0x06;
227 gspca_dev->usb_buf[1] = sd->ctrls[GAMMA].val * 0x40; 137 gspca_dev->usb_buf[1] = val * 0x40;
228 reg_w(gspca_dev, 2); 138 reg_w(gspca_dev, 2);
229} 139}
230 140
231static void setsharpness(struct gspca_dev *gspca_dev) 141static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
232{ 142{
233 struct sd *sd = (struct sd *) gspca_dev;
234
235 gspca_dev->usb_buf[0] = 0x67; 143 gspca_dev->usb_buf[0] = 0x67;
236 gspca_dev->usb_buf[1] = sd->ctrls[SHARPNESS].val * 4 + 3; 144 gspca_dev->usb_buf[1] = val * 4 + 3;
237 reg_w(gspca_dev, 2); 145 reg_w(gspca_dev, 2);
238} 146}
239 147
240static void setilluminators(struct gspca_dev *gspca_dev) 148static void setilluminators(struct gspca_dev *gspca_dev, bool top, bool bottom)
241{ 149{
242 struct sd *sd = (struct sd *) gspca_dev; 150 /* both are off if not streaming */
243
244 gspca_dev->usb_buf[0] = 0x22; 151 gspca_dev->usb_buf[0] = 0x22;
245 if (sd->ctrls[ILLUM_TOP].val) 152 if (top)
246 gspca_dev->usb_buf[1] = 0x76; 153 gspca_dev->usb_buf[1] = 0x76;
247 else if (sd->ctrls[ILLUM_BOT].val) 154 else if (bottom)
248 gspca_dev->usb_buf[1] = 0x7a; 155 gspca_dev->usb_buf[1] = 0x7a;
249 else 156 else
250 gspca_dev->usb_buf[1] = 0x7e; 157 gspca_dev->usb_buf[1] = 0x7e;
251 reg_w(gspca_dev, 2); 158 reg_w(gspca_dev, 2);
252} 159}
253 160
161static int mars_s_ctrl(struct v4l2_ctrl *ctrl)
162{
163 struct gspca_dev *gspca_dev =
164 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
165 struct sd *sd = (struct sd *)gspca_dev;
166
167 gspca_dev->usb_err = 0;
168
169 if (ctrl->id == V4L2_CID_ILLUMINATORS_1) {
170 /* only one can be on at a time */
171 if (ctrl->is_new && ctrl->val)
172 sd->illum_bottom->val = 0;
173 if (sd->illum_bottom->is_new && sd->illum_bottom->val)
174 sd->illum_top->val = 0;
175 }
176
177 if (!gspca_dev->streaming)
178 return 0;
179
180 switch (ctrl->id) {
181 case V4L2_CID_BRIGHTNESS:
182 setbrightness(gspca_dev, ctrl->val);
183 break;
184 case V4L2_CID_SATURATION:
185 setcolors(gspca_dev, ctrl->val);
186 break;
187 case V4L2_CID_GAMMA:
188 setgamma(gspca_dev, ctrl->val);
189 break;
190 case V4L2_CID_ILLUMINATORS_1:
191 setilluminators(gspca_dev, sd->illum_top->val,
192 sd->illum_bottom->val);
193 break;
194 case V4L2_CID_SHARPNESS:
195 setsharpness(gspca_dev, ctrl->val);
196 break;
197 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
198 jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
199 break;
200 default:
201 return -EINVAL;
202 }
203 return gspca_dev->usb_err;
204}
205
206static const struct v4l2_ctrl_ops mars_ctrl_ops = {
207 .s_ctrl = mars_s_ctrl,
208};
209
210/* this function is called at probe time */
211static int sd_init_controls(struct gspca_dev *gspca_dev)
212{
213 struct sd *sd = (struct sd *) gspca_dev;
214 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
215
216 gspca_dev->vdev.ctrl_handler = hdl;
217 v4l2_ctrl_handler_init(hdl, 7);
218 sd->brightness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
219 V4L2_CID_BRIGHTNESS, 0, 30, 1, 15);
220 sd->saturation = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
221 V4L2_CID_SATURATION, 0, 255, 1, 200);
222 sd->gamma = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
223 V4L2_CID_GAMMA, 0, 3, 1, 1);
224 sd->sharpness = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
225 V4L2_CID_SHARPNESS, 0, 2, 1, 1);
226 sd->illum_top = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
227 V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
228 sd->illum_top->flags |= V4L2_CTRL_FLAG_UPDATE;
229 sd->illum_bottom = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
230 V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
231 sd->illum_bottom->flags |= V4L2_CTRL_FLAG_UPDATE;
232 sd->jpegqual = v4l2_ctrl_new_std(hdl, &mars_ctrl_ops,
233 V4L2_CID_JPEG_COMPRESSION_QUALITY,
234 QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
235 if (hdl->error) {
236 pr_err("Could not initialize controls\n");
237 return hdl->error;
238 }
239 v4l2_ctrl_cluster(2, &sd->illum_top);
240 return 0;
241}
242
254/* this function is called at probe time */ 243/* this function is called at probe time */
255static int sd_config(struct gspca_dev *gspca_dev, 244static int sd_config(struct gspca_dev *gspca_dev,
256 const struct usb_device_id *id) 245 const struct usb_device_id *id)
@@ -261,7 +250,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
261 cam = &gspca_dev->cam; 250 cam = &gspca_dev->cam;
262 cam->cam_mode = vga_mode; 251 cam->cam_mode = vga_mode;
263 cam->nmodes = ARRAY_SIZE(vga_mode); 252 cam->nmodes = ARRAY_SIZE(vga_mode);
264 cam->ctrls = sd->ctrls;
265 sd->quality = QUALITY_DEF; 253 sd->quality = QUALITY_DEF;
266 return 0; 254 return 0;
267} 255}
@@ -269,7 +257,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
269/* this function is called at probe and resume time */ 257/* this function is called at probe and resume time */
270static int sd_init(struct gspca_dev *gspca_dev) 258static int sd_init(struct gspca_dev *gspca_dev)
271{ 259{
272 gspca_dev->ctrl_inac = (1 << ILLUM_TOP) | (1 << ILLUM_BOT);
273 return 0; 260 return 0;
274} 261}
275 262
@@ -282,7 +269,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
282 /* create the JPEG header */ 269 /* create the JPEG header */
283 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 270 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
284 0x21); /* JPEG 422 */ 271 0x21); /* JPEG 422 */
285 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 272 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
286 273
287 data = gspca_dev->usb_buf; 274 data = gspca_dev->usb_buf;
288 275
@@ -301,7 +288,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
301 data[5] = 0x30; /* reg 4, MI, PAS5101 : 288 data[5] = 0x30; /* reg 4, MI, PAS5101 :
302 * 0x30 for 24mhz , 0x28 for 12mhz */ 289 * 0x30 for 24mhz , 0x28 for 12mhz */
303 data[6] = 0x02; /* reg 5, H start - was 0x04 */ 290 data[6] = 0x02; /* reg 5, H start - was 0x04 */
304 data[7] = sd->ctrls[GAMMA].val * 0x40; /* reg 0x06: gamma */ 291 data[7] = v4l2_ctrl_g_ctrl(sd->gamma) * 0x40; /* reg 0x06: gamma */
305 data[8] = 0x01; /* reg 7, V start - was 0x03 */ 292 data[8] = 0x01; /* reg 7, V start - was 0x03 */
306/* if (h_size == 320 ) */ 293/* if (h_size == 320 ) */
307/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ 294/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
@@ -333,16 +320,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
333 /* reg 0x5f/0x60 (LE) = saturation */ 320 /* reg 0x5f/0x60 (LE) = saturation */
334 /* h (60): xxxx x100 321 /* h (60): xxxx x100
335 * l (5f): xxxx x000 */ 322 * l (5f): xxxx x000 */
336 data[2] = sd->ctrls[COLORS].val << 3; 323 data[2] = v4l2_ctrl_g_ctrl(sd->saturation) << 3;
337 data[3] = ((sd->ctrls[COLORS].val >> 2) & 0xf8) | 0x04; 324 data[3] = ((v4l2_ctrl_g_ctrl(sd->saturation) >> 2) & 0xf8) | 0x04;
338 data[4] = sd->ctrls[BRIGHTNESS].val; /* reg 0x61 = brightness */ 325 data[4] = v4l2_ctrl_g_ctrl(sd->brightness); /* reg 0x61 = brightness */
339 data[5] = 0x00; 326 data[5] = 0x00;
340 327
341 reg_w(gspca_dev, 6); 328 reg_w(gspca_dev, 6);
342 329
343 data[0] = 0x67; 330 data[0] = 0x67;
344/*jfm: from win trace*/ 331/*jfm: from win trace*/
345 data[1] = sd->ctrls[SHARPNESS].val * 4 + 3; 332 data[1] = v4l2_ctrl_g_ctrl(sd->sharpness) * 4 + 3;
346 data[2] = 0x14; 333 data[2] = 0x14;
347 reg_w(gspca_dev, 3); 334 reg_w(gspca_dev, 3);
348 335
@@ -365,7 +352,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
365 data[1] = 0x4d; /* ISOC transferring enable... */ 352 data[1] = 0x4d; /* ISOC transferring enable... */
366 reg_w(gspca_dev, 2); 353 reg_w(gspca_dev, 2);
367 354
368 gspca_dev->ctrl_inac = 0; /* activate the illuminator controls */ 355 setilluminators(gspca_dev, v4l2_ctrl_g_ctrl(sd->illum_top),
356 v4l2_ctrl_g_ctrl(sd->illum_bottom));
357
369 return gspca_dev->usb_err; 358 return gspca_dev->usb_err;
370} 359}
371 360
@@ -373,11 +362,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
373{ 362{
374 struct sd *sd = (struct sd *) gspca_dev; 363 struct sd *sd = (struct sd *) gspca_dev;
375 364
376 gspca_dev->ctrl_inac = (1 << ILLUM_TOP) | (1 << ILLUM_BOT); 365 if (v4l2_ctrl_g_ctrl(sd->illum_top) ||
377 if (sd->ctrls[ILLUM_TOP].val || sd->ctrls[ILLUM_BOT].val) { 366 v4l2_ctrl_g_ctrl(sd->illum_bottom)) {
378 sd->ctrls[ILLUM_TOP].val = 0; 367 setilluminators(gspca_dev, false, false);
379 sd->ctrls[ILLUM_BOT].val = 0;
380 setilluminators(gspca_dev);
381 msleep(20); 368 msleep(20);
382 } 369 }
383 370
@@ -424,43 +411,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
424 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 411 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
425} 412}
426 413
427static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val)
428{
429 struct sd *sd = (struct sd *) gspca_dev;
430
431 /* only one illuminator may be on */
432 sd->ctrls[ILLUM_TOP].val = val;
433 if (val)
434 sd->ctrls[ILLUM_BOT].val = 0;
435 setilluminators(gspca_dev);
436 return gspca_dev->usb_err;
437}
438
439static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val)
440{
441 struct sd *sd = (struct sd *) gspca_dev;
442
443 /* only one illuminator may be on */
444 sd->ctrls[ILLUM_BOT].val = val;
445 if (val)
446 sd->ctrls[ILLUM_TOP].val = 0;
447 setilluminators(gspca_dev);
448 return gspca_dev->usb_err;
449}
450
451static int sd_set_jcomp(struct gspca_dev *gspca_dev, 414static int sd_set_jcomp(struct gspca_dev *gspca_dev,
452 struct v4l2_jpegcompression *jcomp) 415 struct v4l2_jpegcompression *jcomp)
453{ 416{
454 struct sd *sd = (struct sd *) gspca_dev; 417 struct sd *sd = (struct sd *) gspca_dev;
418 int ret;
455 419
456 if (jcomp->quality < QUALITY_MIN) 420 ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
457 sd->quality = QUALITY_MIN; 421 if (ret)
458 else if (jcomp->quality > QUALITY_MAX) 422 return ret;
459 sd->quality = QUALITY_MAX; 423 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
460 else
461 sd->quality = jcomp->quality;
462 if (gspca_dev->streaming)
463 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
464 return 0; 424 return 0;
465} 425}
466 426
@@ -470,7 +430,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
470 struct sd *sd = (struct sd *) gspca_dev; 430 struct sd *sd = (struct sd *) gspca_dev;
471 431
472 memset(jcomp, 0, sizeof *jcomp); 432 memset(jcomp, 0, sizeof *jcomp);
473 jcomp->quality = sd->quality; 433 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
474 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 434 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
475 | V4L2_JPEG_MARKER_DQT; 435 | V4L2_JPEG_MARKER_DQT;
476 return 0; 436 return 0;
@@ -479,10 +439,9 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
479/* sub-driver description */ 439/* sub-driver description */
480static const struct sd_desc sd_desc = { 440static const struct sd_desc sd_desc = {
481 .name = MODULE_NAME, 441 .name = MODULE_NAME,
482 .ctrls = sd_ctrls,
483 .nctrls = NCTRLS,
484 .config = sd_config, 442 .config = sd_config,
485 .init = sd_init, 443 .init = sd_init,
444 .init_controls = sd_init_controls,
486 .start = sd_start, 445 .start = sd_start,
487 .stopN = sd_stopN, 446 .stopN = sd_stopN,
488 .pkt_scan = sd_pkt_scan, 447 .pkt_scan = sd_pkt_scan,
@@ -513,6 +472,7 @@ static struct usb_driver sd_driver = {
513#ifdef CONFIG_PM 472#ifdef CONFIG_PM
514 .suspend = gspca_suspend, 473 .suspend = gspca_suspend,
515 .resume = gspca_resume, 474 .resume = gspca_resume,
475 .reset_resume = gspca_resume,
516#endif 476#endif
517}; 477};
518 478
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c
index 7167cac7359c..42e021931e60 100644
--- a/drivers/media/video/gspca/nw80x.c
+++ b/drivers/media/video/gspca/nw80x.c
@@ -2001,6 +2001,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2001 return gspca_dev->usb_err; 2001 return gspca_dev->usb_err;
2002} 2002}
2003 2003
2004#define WANT_REGULAR_AUTOGAIN
2005#define WANT_COARSE_EXPO_AUTOGAIN
2004#include "autogain_functions.h" 2006#include "autogain_functions.h"
2005 2007
2006static void do_autogain(struct gspca_dev *gspca_dev) 2008static void do_autogain(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 739e8a2a2d30..183457c5cfdb 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -2804,7 +2804,7 @@ static void ov7xx0_configure(struct sd *sd)
2804 /* add OV7670 here 2804 /* add OV7670 here
2805 * it appears to be wrongly detected as a 7610 by default */ 2805 * it appears to be wrongly detected as a 7610 by default */
2806 if (rc < 0) { 2806 if (rc < 0) {
2807 PDEBUG(D_ERR, "Error detecting sensor type"); 2807 pr_err("Error detecting sensor type\n");
2808 return; 2808 return;
2809 } 2809 }
2810 if ((rc & 3) == 3) { 2810 if ((rc & 3) == 3) {
@@ -2832,12 +2832,12 @@ static void ov7xx0_configure(struct sd *sd)
2832 /* try to read product id registers */ 2832 /* try to read product id registers */
2833 high = i2c_r(sd, 0x0a); 2833 high = i2c_r(sd, 0x0a);
2834 if (high < 0) { 2834 if (high < 0) {
2835 PDEBUG(D_ERR, "Error detecting camera chip PID"); 2835 pr_err("Error detecting camera chip PID\n");
2836 return; 2836 return;
2837 } 2837 }
2838 low = i2c_r(sd, 0x0b); 2838 low = i2c_r(sd, 0x0b);
2839 if (low < 0) { 2839 if (low < 0) {
2840 PDEBUG(D_ERR, "Error detecting camera chip VER"); 2840 pr_err("Error detecting camera chip VER\n");
2841 return; 2841 return;
2842 } 2842 }
2843 if (high == 0x76) { 2843 if (high == 0x76) {
@@ -2863,7 +2863,7 @@ static void ov7xx0_configure(struct sd *sd)
2863 sd->sensor = SEN_OV7660; 2863 sd->sensor = SEN_OV7660;
2864 break; 2864 break;
2865 default: 2865 default:
2866 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); 2866 pr_err("Unknown sensor: 0x76%02x\n", low);
2867 return; 2867 return;
2868 } 2868 }
2869 } else { 2869 } else {
@@ -2884,7 +2884,7 @@ static void ov6xx0_configure(struct sd *sd)
2884 /* Detect sensor (sub)type */ 2884 /* Detect sensor (sub)type */
2885 rc = i2c_r(sd, OV7610_REG_COM_I); 2885 rc = i2c_r(sd, OV7610_REG_COM_I);
2886 if (rc < 0) { 2886 if (rc < 0) {
2887 PDEBUG(D_ERR, "Error detecting sensor type"); 2887 pr_err("Error detecting sensor type\n");
2888 return; 2888 return;
2889 } 2889 }
2890 2890
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 04753391de3e..b5acb1e4b4e7 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -34,6 +34,8 @@
34 34
35#include "gspca.h" 35#include "gspca.h"
36 36
37#include <linux/fixp-arith.h>
38
37#define OV534_REG_ADDRESS 0xf1 /* sensor address */ 39#define OV534_REG_ADDRESS 0xf1 /* sensor address */
38#define OV534_REG_SUBADDR 0xf2 40#define OV534_REG_SUBADDR 0xf2
39#define OV534_REG_WRITE 0xf3 41#define OV534_REG_WRITE 0xf3
@@ -53,6 +55,8 @@ MODULE_LICENSE("GPL");
53 55
54/* controls */ 56/* controls */
55enum e_ctrl { 57enum e_ctrl {
58 HUE,
59 SATURATION,
56 BRIGHTNESS, 60 BRIGHTNESS,
57 CONTRAST, 61 CONTRAST,
58 GAIN, 62 GAIN,
@@ -63,7 +67,6 @@ enum e_ctrl {
63 SHARPNESS, 67 SHARPNESS,
64 HFLIP, 68 HFLIP,
65 VFLIP, 69 VFLIP,
66 COLORS,
67 LIGHTFREQ, 70 LIGHTFREQ,
68 NCTRLS /* number of controls */ 71 NCTRLS /* number of controls */
69}; 72};
@@ -87,6 +90,8 @@ enum sensors {
87}; 90};
88 91
89/* V4L2 controls supported by the driver */ 92/* V4L2 controls supported by the driver */
93static void sethue(struct gspca_dev *gspca_dev);
94static void setsaturation(struct gspca_dev *gspca_dev);
90static void setbrightness(struct gspca_dev *gspca_dev); 95static void setbrightness(struct gspca_dev *gspca_dev);
91static void setcontrast(struct gspca_dev *gspca_dev); 96static void setcontrast(struct gspca_dev *gspca_dev);
92static void setgain(struct gspca_dev *gspca_dev); 97static void setgain(struct gspca_dev *gspca_dev);
@@ -96,13 +101,36 @@ static void setawb(struct gspca_dev *gspca_dev);
96static void setaec(struct gspca_dev *gspca_dev); 101static void setaec(struct gspca_dev *gspca_dev);
97static void setsharpness(struct gspca_dev *gspca_dev); 102static void setsharpness(struct gspca_dev *gspca_dev);
98static void sethvflip(struct gspca_dev *gspca_dev); 103static void sethvflip(struct gspca_dev *gspca_dev);
99static void setcolors(struct gspca_dev *gspca_dev);
100static void setlightfreq(struct gspca_dev *gspca_dev); 104static void setlightfreq(struct gspca_dev *gspca_dev);
101 105
102static int sd_start(struct gspca_dev *gspca_dev); 106static int sd_start(struct gspca_dev *gspca_dev);
103static void sd_stopN(struct gspca_dev *gspca_dev); 107static void sd_stopN(struct gspca_dev *gspca_dev);
104 108
105static const struct ctrl sd_ctrls[] = { 109static const struct ctrl sd_ctrls[] = {
110[HUE] = {
111 {
112 .id = V4L2_CID_HUE,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Hue",
115 .minimum = -90,
116 .maximum = 90,
117 .step = 1,
118 .default_value = 0,
119 },
120 .set_control = sethue
121 },
122[SATURATION] = {
123 {
124 .id = V4L2_CID_SATURATION,
125 .type = V4L2_CTRL_TYPE_INTEGER,
126 .name = "Saturation",
127 .minimum = 0,
128 .maximum = 255,
129 .step = 1,
130 .default_value = 64,
131 },
132 .set_control = setsaturation
133 },
106[BRIGHTNESS] = { 134[BRIGHTNESS] = {
107 { 135 {
108 .id = V4L2_CID_BRIGHTNESS, 136 .id = V4L2_CID_BRIGHTNESS,
@@ -223,18 +251,6 @@ static const struct ctrl sd_ctrls[] = {
223 }, 251 },
224 .set_control = sethvflip 252 .set_control = sethvflip
225 }, 253 },
226[COLORS] = {
227 {
228 .id = V4L2_CID_SATURATION,
229 .type = V4L2_CTRL_TYPE_INTEGER,
230 .name = "Saturation",
231 .minimum = 0,
232 .maximum = 6,
233 .step = 1,
234 .default_value = 3,
235 },
236 .set_control = setcolors
237 },
238[LIGHTFREQ] = { 254[LIGHTFREQ] = {
239 { 255 {
240 .id = V4L2_CID_POWER_LINE_FREQUENCY, 256 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -684,7 +700,7 @@ static const u8 sensor_init_772x[][2] = {
684 { 0x9c, 0x20 }, 700 { 0x9c, 0x20 },
685 { 0x9e, 0x81 }, 701 { 0x9e, 0x81 },
686 702
687 { 0xa6, 0x04 }, 703 { 0xa6, 0x07 },
688 { 0x7e, 0x0c }, 704 { 0x7e, 0x0c },
689 { 0x7f, 0x16 }, 705 { 0x7f, 0x16 },
690 { 0x80, 0x2a }, 706 { 0x80, 0x2a },
@@ -955,6 +971,74 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
955 PDEBUG(D_PROBE, "frame_rate: %d", r->fps); 971 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
956} 972}
957 973
974static void sethue(struct gspca_dev *gspca_dev)
975{
976 struct sd *sd = (struct sd *) gspca_dev;
977 int val;
978
979 val = sd->ctrls[HUE].val;
980 if (sd->sensor == SENSOR_OV767x) {
981 /* TBD */
982 } else {
983 s16 huesin;
984 s16 huecos;
985
986 /* fixp_sin and fixp_cos accept only positive values, while
987 * our val is between -90 and 90
988 */
989 val += 360;
990
991 /* According to the datasheet the registers expect HUESIN and
992 * HUECOS to be the result of the trigonometric functions,
993 * scaled by 0x80.
994 *
995 * The 0x100 here represents the maximun absolute value
996 * returned byt fixp_sin and fixp_cos, so the scaling will
997 * consider the result like in the interval [-1.0, 1.0].
998 */
999 huesin = fixp_sin(val) * 0x80 / 0x100;
1000 huecos = fixp_cos(val) * 0x80 / 0x100;
1001
1002 if (huesin < 0) {
1003 sccb_reg_write(gspca_dev, 0xab,
1004 sccb_reg_read(gspca_dev, 0xab) | 0x2);
1005 huesin = -huesin;
1006 } else {
1007 sccb_reg_write(gspca_dev, 0xab,
1008 sccb_reg_read(gspca_dev, 0xab) & ~0x2);
1009
1010 }
1011 sccb_reg_write(gspca_dev, 0xa9, (u8)huecos);
1012 sccb_reg_write(gspca_dev, 0xaa, (u8)huesin);
1013 }
1014}
1015
1016static void setsaturation(struct gspca_dev *gspca_dev)
1017{
1018 struct sd *sd = (struct sd *) gspca_dev;
1019 int val;
1020
1021 val = sd->ctrls[SATURATION].val;
1022 if (sd->sensor == SENSOR_OV767x) {
1023 int i;
1024 static u8 color_tb[][6] = {
1025 {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1026 {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1027 {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1028 {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1029 {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1030 {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1031 {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1032 };
1033
1034 for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
1035 sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
1036 } else {
1037 sccb_reg_write(gspca_dev, 0xa7, val); /* U saturation */
1038 sccb_reg_write(gspca_dev, 0xa8, val); /* V saturation */
1039 }
1040}
1041
958static void setbrightness(struct gspca_dev *gspca_dev) 1042static void setbrightness(struct gspca_dev *gspca_dev)
959{ 1043{
960 struct sd *sd = (struct sd *) gspca_dev; 1044 struct sd *sd = (struct sd *) gspca_dev;
@@ -1132,26 +1216,6 @@ static void sethvflip(struct gspca_dev *gspca_dev)
1132 } 1216 }
1133} 1217}
1134 1218
1135static void setcolors(struct gspca_dev *gspca_dev)
1136{
1137 struct sd *sd = (struct sd *) gspca_dev;
1138 u8 val;
1139 int i;
1140 static u8 color_tb[][6] = {
1141 {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1142 {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1143 {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1144 {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1145 {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1146 {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1147 {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1148 };
1149
1150 val = sd->ctrls[COLORS].val;
1151 for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
1152 sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
1153}
1154
1155static void setlightfreq(struct gspca_dev *gspca_dev) 1219static void setlightfreq(struct gspca_dev *gspca_dev)
1156{ 1220{
1157 struct sd *sd = (struct sd *) gspca_dev; 1221 struct sd *sd = (struct sd *) gspca_dev;
@@ -1225,9 +1289,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
1225 1289
1226 if ((sensor_id & 0xfff0) == 0x7670) { 1290 if ((sensor_id & 0xfff0) == 0x7670) {
1227 sd->sensor = SENSOR_OV767x; 1291 sd->sensor = SENSOR_OV767x;
1228 gspca_dev->ctrl_dis = (1 << GAIN) | 1292 gspca_dev->ctrl_dis = (1 << HUE) |
1293 (1 << GAIN) |
1229 (1 << AGC) | 1294 (1 << AGC) |
1230 (1 << SHARPNESS); /* auto */ 1295 (1 << SHARPNESS); /* auto */
1296 sd->ctrls[SATURATION].min = 0,
1297 sd->ctrls[SATURATION].max = 6,
1298 sd->ctrls[SATURATION].def = 3,
1231 sd->ctrls[BRIGHTNESS].min = -127; 1299 sd->ctrls[BRIGHTNESS].min = -127;
1232 sd->ctrls[BRIGHTNESS].max = 127; 1300 sd->ctrls[BRIGHTNESS].max = 127;
1233 sd->ctrls[BRIGHTNESS].def = 0; 1301 sd->ctrls[BRIGHTNESS].def = 0;
@@ -1243,7 +1311,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1243 gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode); 1311 gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode);
1244 } else { 1312 } else {
1245 sd->sensor = SENSOR_OV772x; 1313 sd->sensor = SENSOR_OV772x;
1246 gspca_dev->ctrl_dis = (1 << COLORS);
1247 gspca_dev->cam.bulk = 1; 1314 gspca_dev->cam.bulk = 1;
1248 gspca_dev->cam.bulk_size = 16384; 1315 gspca_dev->cam.bulk_size = 16384;
1249 gspca_dev->cam.bulk_nurbs = 2; 1316 gspca_dev->cam.bulk_nurbs = 2;
@@ -1302,6 +1369,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1302 1369
1303 set_frame_rate(gspca_dev); 1370 set_frame_rate(gspca_dev);
1304 1371
1372 if (!(gspca_dev->ctrl_dis & (1 << HUE)))
1373 sethue(gspca_dev);
1374 setsaturation(gspca_dev);
1305 if (!(gspca_dev->ctrl_dis & (1 << AGC))) 1375 if (!(gspca_dev->ctrl_dis & (1 << AGC)))
1306 setagc(gspca_dev); 1376 setagc(gspca_dev);
1307 setawb(gspca_dev); 1377 setawb(gspca_dev);
@@ -1314,8 +1384,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1314 if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS))) 1384 if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS)))
1315 setsharpness(gspca_dev); 1385 setsharpness(gspca_dev);
1316 sethvflip(gspca_dev); 1386 sethvflip(gspca_dev);
1317 if (!(gspca_dev->ctrl_dis & (1 << COLORS)))
1318 setcolors(gspca_dev);
1319 setlightfreq(gspca_dev); 1387 setlightfreq(gspca_dev);
1320 1388
1321 ov534_set_led(gspca_dev, 1); 1389 ov534_set_led(gspca_dev, 1);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 3844c49f269c..fa661c6d6d55 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -29,6 +29,8 @@
29 29
30#include <linux/input.h> 30#include <linux/input.h>
31#include "gspca.h" 31#include "gspca.h"
32/* Include pac common sof detection functions */
33#include "pac_common.h"
32 34
33MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 35MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
34MODULE_DESCRIPTION("Pixart PAC207"); 36MODULE_DESCRIPTION("Pixart PAC207");
@@ -39,16 +41,17 @@ MODULE_LICENSE("GPL");
39#define PAC207_BRIGHTNESS_MIN 0 41#define PAC207_BRIGHTNESS_MIN 0
40#define PAC207_BRIGHTNESS_MAX 255 42#define PAC207_BRIGHTNESS_MAX 255
41#define PAC207_BRIGHTNESS_DEFAULT 46 43#define PAC207_BRIGHTNESS_DEFAULT 46
44#define PAC207_BRIGHTNESS_REG 0x08
42 45
43#define PAC207_EXPOSURE_MIN 3 46#define PAC207_EXPOSURE_MIN 3
44#define PAC207_EXPOSURE_MAX 90 /* 1 sec expo time / 1 fps */ 47#define PAC207_EXPOSURE_MAX 90 /* 1 sec expo time / 1 fps */
45#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */ 48#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */
46#define PAC207_EXPOSURE_KNEE 9 /* fps: 90 / exposure -> 9: 10 fps */ 49#define PAC207_EXPOSURE_REG 0x02
47 50
48#define PAC207_GAIN_MIN 0 51#define PAC207_GAIN_MIN 0
49#define PAC207_GAIN_MAX 31 52#define PAC207_GAIN_MAX 31
50#define PAC207_GAIN_DEFAULT 7 /* power on default: 9 */ 53#define PAC207_GAIN_DEFAULT 7 /* power on default: 9 */
51#define PAC207_GAIN_KNEE 15 54#define PAC207_GAIN_REG 0x0e
52 55
53#define PAC207_AUTOGAIN_DEADZONE 30 56#define PAC207_AUTOGAIN_DEADZONE 30
54 57
@@ -56,13 +59,9 @@ MODULE_LICENSE("GPL");
56struct sd { 59struct sd {
57 struct gspca_dev gspca_dev; /* !! must be the first item */ 60 struct gspca_dev gspca_dev; /* !! must be the first item */
58 61
59 u8 mode; 62 struct v4l2_ctrl *brightness;
60
61 u8 brightness;
62 u8 exposure;
63 u8 autogain;
64 u8 gain;
65 63
64 u8 mode;
66 u8 sof_read; 65 u8 sof_read;
67 u8 header_read; 66 u8 header_read;
68 u8 autogain_ignore_frames; 67 u8 autogain_ignore_frames;
@@ -70,80 +69,6 @@ struct sd {
70 atomic_t avg_lum; 69 atomic_t avg_lum;
71}; 70};
72 71
73/* V4L2 controls supported by the driver */
74static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
82
83static const struct ctrl sd_ctrls[] = {
84#define SD_BRIGHTNESS 0
85 {
86 {
87 .id = V4L2_CID_BRIGHTNESS,
88 .type = V4L2_CTRL_TYPE_INTEGER,
89 .name = "Brightness",
90 .minimum = PAC207_BRIGHTNESS_MIN,
91 .maximum = PAC207_BRIGHTNESS_MAX,
92 .step = 1,
93 .default_value = PAC207_BRIGHTNESS_DEFAULT,
94 .flags = 0,
95 },
96 .set = sd_setbrightness,
97 .get = sd_getbrightness,
98 },
99#define SD_EXPOSURE 1
100 {
101 {
102 .id = V4L2_CID_EXPOSURE,
103 .type = V4L2_CTRL_TYPE_INTEGER,
104 .name = "Exposure",
105 .minimum = PAC207_EXPOSURE_MIN,
106 .maximum = PAC207_EXPOSURE_MAX,
107 .step = 1,
108 .default_value = PAC207_EXPOSURE_DEFAULT,
109 .flags = 0,
110 },
111 .set = sd_setexposure,
112 .get = sd_getexposure,
113 },
114#define SD_AUTOGAIN 2
115 {
116 {
117 .id = V4L2_CID_AUTOGAIN,
118 .type = V4L2_CTRL_TYPE_BOOLEAN,
119 .name = "Auto Gain",
120 .minimum = 0,
121 .maximum = 1,
122 .step = 1,
123#define AUTOGAIN_DEF 1
124 .default_value = AUTOGAIN_DEF,
125 .flags = 0,
126 },
127 .set = sd_setautogain,
128 .get = sd_getautogain,
129 },
130#define SD_GAIN 3
131 {
132 {
133 .id = V4L2_CID_GAIN,
134 .type = V4L2_CTRL_TYPE_INTEGER,
135 .name = "Gain",
136 .minimum = PAC207_GAIN_MIN,
137 .maximum = PAC207_GAIN_MAX,
138 .step = 1,
139 .default_value = PAC207_GAIN_DEFAULT,
140 .flags = 0,
141 },
142 .set = sd_setgain,
143 .get = sd_getgain,
144 },
145};
146
147static const struct v4l2_pix_format sif_mode[] = { 72static const struct v4l2_pix_format sif_mode[] = {
148 {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, 73 {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
149 .bytesperline = 176, 74 .bytesperline = 176,
@@ -167,39 +92,44 @@ static const __u8 pac207_sensor_init[][8] = {
167 {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00}, 92 {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00},
168}; 93};
169 94
170static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, 95static void pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
171 const u8 *buffer, u16 length) 96 const u8 *buffer, u16 length)
172{ 97{
173 struct usb_device *udev = gspca_dev->dev; 98 struct usb_device *udev = gspca_dev->dev;
174 int err; 99 int err;
175 100
101 if (gspca_dev->usb_err < 0)
102 return;
103
176 memcpy(gspca_dev->usb_buf, buffer, length); 104 memcpy(gspca_dev->usb_buf, buffer, length);
177 105
178 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, 106 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
179 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 107 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
180 0x00, index, 108 0x00, index,
181 gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT); 109 gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
182 if (err < 0) 110 if (err < 0) {
183 pr_err("Failed to write registers to index 0x%04X, error %d\n", 111 pr_err("Failed to write registers to index 0x%04X, error %d\n",
184 index, err); 112 index, err);
185 113 gspca_dev->usb_err = err;
186 return err; 114 }
187} 115}
188 116
189 117static void pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
190static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
191{ 118{
192 struct usb_device *udev = gspca_dev->dev; 119 struct usb_device *udev = gspca_dev->dev;
193 int err; 120 int err;
194 121
122 if (gspca_dev->usb_err < 0)
123 return;
124
195 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 125 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
196 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 126 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
197 value, index, NULL, 0, PAC207_CTRL_TIMEOUT); 127 value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
198 if (err) 128 if (err) {
199 pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n", 129 pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
200 index, value, err); 130 index, value, err);
201 131 gspca_dev->usb_err = err;
202 return err; 132 }
203} 133}
204 134
205static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) 135static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
@@ -207,6 +137,9 @@ static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
207 struct usb_device *udev = gspca_dev->dev; 137 struct usb_device *udev = gspca_dev->dev;
208 int res; 138 int res;
209 139
140 if (gspca_dev->usb_err < 0)
141 return 0;
142
210 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 143 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
211 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 144 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
212 0x00, index, 145 0x00, index,
@@ -214,7 +147,8 @@ static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
214 if (res < 0) { 147 if (res < 0) {
215 pr_err("Failed to read a register (index 0x%04X, error %d)\n", 148 pr_err("Failed to read a register (index 0x%04X, error %d)\n",
216 index, res); 149 index, res);
217 return res; 150 gspca_dev->usb_err = res;
151 return 0;
218 } 152 }
219 153
220 return gspca_dev->usb_buf[0]; 154 return gspca_dev->usb_buf[0];
@@ -224,7 +158,6 @@ static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
224static int sd_config(struct gspca_dev *gspca_dev, 158static int sd_config(struct gspca_dev *gspca_dev,
225 const struct usb_device_id *id) 159 const struct usb_device_id *id)
226{ 160{
227 struct sd *sd = (struct sd *) gspca_dev;
228 struct cam *cam; 161 struct cam *cam;
229 u8 idreg[2]; 162 u8 idreg[2];
230 163
@@ -247,10 +180,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
247 cam = &gspca_dev->cam; 180 cam = &gspca_dev->cam;
248 cam->cam_mode = sif_mode; 181 cam->cam_mode = sif_mode;
249 cam->nmodes = ARRAY_SIZE(sif_mode); 182 cam->nmodes = ARRAY_SIZE(sif_mode);
250 sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
251 sd->exposure = PAC207_EXPOSURE_DEFAULT;
252 sd->gain = PAC207_GAIN_DEFAULT;
253 sd->autogain = AUTOGAIN_DEF;
254 183
255 return 0; 184 return 0;
256} 185}
@@ -264,6 +193,87 @@ static int sd_init(struct gspca_dev *gspca_dev)
264 * Bit_2=Compression test mode enable */ 193 * Bit_2=Compression test mode enable */
265 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ 194 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
266 195
196 return gspca_dev->usb_err;
197}
198
199static void setcontrol(struct gspca_dev *gspca_dev, u16 reg, u16 val)
200{
201 pac207_write_reg(gspca_dev, reg, val);
202 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
203 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
204}
205
206static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
207{
208 struct gspca_dev *gspca_dev =
209 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
210 struct sd *sd = (struct sd *)gspca_dev;
211
212 gspca_dev->usb_err = 0;
213
214 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
215 /* when switching to autogain set defaults to make sure
216 we are on a valid point of the autogain gain /
217 exposure knee graph, and give this change time to
218 take effect before doing autogain. */
219 gspca_dev->exposure->val = PAC207_EXPOSURE_DEFAULT;
220 gspca_dev->gain->val = PAC207_GAIN_DEFAULT;
221 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
222 }
223
224 if (!gspca_dev->streaming)
225 return 0;
226
227 switch (ctrl->id) {
228 case V4L2_CID_BRIGHTNESS:
229 setcontrol(gspca_dev, PAC207_BRIGHTNESS_REG, ctrl->val);
230 break;
231 case V4L2_CID_AUTOGAIN:
232 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
233 setcontrol(gspca_dev, PAC207_EXPOSURE_REG,
234 gspca_dev->exposure->val);
235 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
236 setcontrol(gspca_dev, PAC207_GAIN_REG,
237 gspca_dev->gain->val);
238 break;
239 default:
240 return -EINVAL;
241 }
242 return gspca_dev->usb_err;
243}
244
245static const struct v4l2_ctrl_ops sd_ctrl_ops = {
246 .s_ctrl = sd_s_ctrl,
247};
248
249/* this function is called at probe time */
250static int sd_init_controls(struct gspca_dev *gspca_dev)
251{
252 struct sd *sd = (struct sd *) gspca_dev;
253 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
254
255 gspca_dev->vdev.ctrl_handler = hdl;
256 v4l2_ctrl_handler_init(hdl, 4);
257
258 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
259 V4L2_CID_BRIGHTNESS,
260 PAC207_BRIGHTNESS_MIN, PAC207_BRIGHTNESS_MAX,
261 1, PAC207_BRIGHTNESS_DEFAULT);
262 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
263 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
264 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
265 V4L2_CID_EXPOSURE,
266 PAC207_EXPOSURE_MIN, PAC207_EXPOSURE_MAX,
267 1, PAC207_EXPOSURE_DEFAULT);
268 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
269 V4L2_CID_GAIN,
270 PAC207_GAIN_MIN, PAC207_GAIN_MAX,
271 1, PAC207_GAIN_DEFAULT);
272 if (hdl->error) {
273 pr_err("Could not initialize controls\n");
274 return hdl->error;
275 }
276 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
267 return 0; 277 return 0;
268} 278}
269 279
@@ -285,11 +295,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
285 else 295 else
286 pac207_write_reg(gspca_dev, 0x4a, 0x30); 296 pac207_write_reg(gspca_dev, 0x4a, 0x30);
287 pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */ 297 pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
288 pac207_write_reg(gspca_dev, 0x08, sd->brightness); 298 pac207_write_reg(gspca_dev, 0x08, v4l2_ctrl_g_ctrl(sd->brightness));
289 299
290 /* PGA global gain (Bit 4-0) */ 300 /* PGA global gain (Bit 4-0) */
291 pac207_write_reg(gspca_dev, 0x0e, sd->gain); 301 pac207_write_reg(gspca_dev, 0x0e,
292 pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */ 302 v4l2_ctrl_g_ctrl(gspca_dev->gain));
303 pac207_write_reg(gspca_dev, 0x02,
304 v4l2_ctrl_g_ctrl(gspca_dev->exposure)); /* PXCK = 12MHz /n */
293 305
294 mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */ 306 mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
295 if (gspca_dev->width == 176) { /* 176x144 */ 307 if (gspca_dev->width == 176) { /* 176x144 */
@@ -308,7 +320,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
308 sd->sof_read = 0; 320 sd->sof_read = 0;
309 sd->autogain_ignore_frames = 0; 321 sd->autogain_ignore_frames = 0;
310 atomic_set(&sd->avg_lum, -1); 322 atomic_set(&sd->avg_lum, -1);
311 return 0; 323 return gspca_dev->usb_err;
312} 324}
313 325
314static void sd_stopN(struct gspca_dev *gspca_dev) 326static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -318,8 +330,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
318 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ 330 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
319} 331}
320 332
321/* Include pac common sof detection functions */
322#include "pac_common.h"
323 333
324static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) 334static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
325{ 335{
@@ -331,9 +341,8 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
331 341
332 if (sd->autogain_ignore_frames > 0) 342 if (sd->autogain_ignore_frames > 0)
333 sd->autogain_ignore_frames--; 343 sd->autogain_ignore_frames--;
334 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 344 else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
335 90, PAC207_AUTOGAIN_DEADZONE, 345 90, PAC207_AUTOGAIN_DEADZONE))
336 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
337 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 346 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
338} 347}
339 348
@@ -384,118 +393,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
384 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 393 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
385} 394}
386 395
387static void setbrightness(struct gspca_dev *gspca_dev)
388{
389 struct sd *sd = (struct sd *) gspca_dev;
390
391 pac207_write_reg(gspca_dev, 0x08, sd->brightness);
392 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
393 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
394}
395
396static void setexposure(struct gspca_dev *gspca_dev)
397{
398 struct sd *sd = (struct sd *) gspca_dev;
399
400 pac207_write_reg(gspca_dev, 0x02, sd->exposure);
401 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
402 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
403}
404
405static void setgain(struct gspca_dev *gspca_dev)
406{
407 struct sd *sd = (struct sd *) gspca_dev;
408
409 pac207_write_reg(gspca_dev, 0x0e, sd->gain);
410 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
411 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
412}
413
414static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
415{
416 struct sd *sd = (struct sd *) gspca_dev;
417
418 sd->brightness = val;
419 if (gspca_dev->streaming)
420 setbrightness(gspca_dev);
421 return 0;
422}
423
424static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
425{
426 struct sd *sd = (struct sd *) gspca_dev;
427
428 *val = sd->brightness;
429 return 0;
430}
431
432static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
433{
434 struct sd *sd = (struct sd *) gspca_dev;
435
436 sd->exposure = val;
437 if (gspca_dev->streaming)
438 setexposure(gspca_dev);
439 return 0;
440}
441
442static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
443{
444 struct sd *sd = (struct sd *) gspca_dev;
445
446 *val = sd->exposure;
447 return 0;
448}
449
450static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
451{
452 struct sd *sd = (struct sd *) gspca_dev;
453
454 sd->gain = val;
455 if (gspca_dev->streaming)
456 setgain(gspca_dev);
457 return 0;
458}
459
460static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
461{
462 struct sd *sd = (struct sd *) gspca_dev;
463
464 *val = sd->gain;
465 return 0;
466}
467
468static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
469{
470 struct sd *sd = (struct sd *) gspca_dev;
471
472 sd->autogain = val;
473 /* when switching to autogain set defaults to make sure
474 we are on a valid point of the autogain gain /
475 exposure knee graph, and give this change time to
476 take effect before doing autogain. */
477 if (sd->autogain) {
478 sd->exposure = PAC207_EXPOSURE_DEFAULT;
479 sd->gain = PAC207_GAIN_DEFAULT;
480 if (gspca_dev->streaming) {
481 sd->autogain_ignore_frames =
482 PAC_AUTOGAIN_IGNORE_FRAMES;
483 setexposure(gspca_dev);
484 setgain(gspca_dev);
485 }
486 }
487
488 return 0;
489}
490
491static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
492{
493 struct sd *sd = (struct sd *) gspca_dev;
494
495 *val = sd->autogain;
496 return 0;
497}
498
499#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 396#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
500static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 397static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
501 u8 *data, /* interrupt packet data */ 398 u8 *data, /* interrupt packet data */
@@ -518,10 +415,9 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
518/* sub-driver description */ 415/* sub-driver description */
519static const struct sd_desc sd_desc = { 416static const struct sd_desc sd_desc = {
520 .name = MODULE_NAME, 417 .name = MODULE_NAME,
521 .ctrls = sd_ctrls,
522 .nctrls = ARRAY_SIZE(sd_ctrls),
523 .config = sd_config, 418 .config = sd_config,
524 .init = sd_init, 419 .init = sd_init,
420 .init_controls = sd_init_controls,
525 .start = sd_start, 421 .start = sd_start,
526 .stopN = sd_stopN, 422 .stopN = sd_stopN,
527 .dq_callback = pac207_do_auto_gain, 423 .dq_callback = pac207_do_auto_gain,
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index 30662fccb0cf..a0369a58c4bb 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -23,43 +23,58 @@
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 24 */
25 25
26/* Some documentation about various registers as determined by trial and error. 26/*
27 27 * Some documentation about various registers as determined by trial and error.
28 Register page 1: 28 *
29 29 * Register page 1:
30 Address Description 30 *
31 0x78 Global control, bit 6 controls the LED (inverted) 31 * Address Description
32 32 * 0x78 Global control, bit 6 controls the LED (inverted)
33 Register page 3: 33 * 0x80 Compression balance, 2 interesting settings:
34 34 * 0x0f Default
35 Address Description 35 * 0x50 Values >= this switch the camera to a lower compression,
36 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on 36 * using the same table for both luminance and chrominance.
37 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 37 * This gives a sharper picture. Only usable when running
38 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps 38 * at < 15 fps! Note currently the driver does not use this
39 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps, 39 * as the quality gain is small and the generated JPG-s are
40 63 -> ~27 fps, the 2 msb's must always be 1 !! 40 * only understood by v4l-utils >= 0.8.9
41 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0: 41 *
42 1 -> ~30 fps, 2 -> ~20 fps 42 * Register page 3:
43 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time 43 *
44 0x0f Exposure bit 8, 0-448, 448 = no exposure at all 44 * Address Description
45 0x10 Master gain 0-31 45 * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 46 * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
47 47 * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
48 The registers are accessed in the following functions: 48 * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
49 49 * 63 -> ~27 fps, the 2 msb's must always be 1 !!
50 Page | Register | Function 50 * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
51 -----+------------+--------------------------------------------------- 51 * 1 -> ~30 fps, 2 -> ~20 fps
52 0 | 0x0f..0x20 | setcolors() 52 * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
53 0 | 0xa2..0xab | setbrightcont() 53 * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
54 0 | 0xc5 | setredbalance() 54 * 0x10 Gain 0-31
55 0 | 0xc6 | setwhitebalance() 55 * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an
56 0 | 0xc7 | setbluebalance() 56 * amplification value of 1 rather then 0 at its lowest setting
57 0 | 0xdc | setbrightcont(), setcolors() 57 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
58 3 | 0x02 | setexposure() 58 * 0x80 Another framerate control, best left at 1, moving it from 1 to
59 3 | 0x10 | setgain() 59 * 2 causes the framerate to become 3/4th of what it was, and
60 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip() 60 * also seems to cause pixel averaging, resulting in an effective
61 3 | 0x21 | sethvflip() 61 * resolution of 320x240 and thus a much blockier image
62*/ 62 *
63 * The registers are accessed in the following functions:
64 *
65 * Page | Register | Function
66 * -----+------------+---------------------------------------------------
67 * 0 | 0x0f..0x20 | setcolors()
68 * 0 | 0xa2..0xab | setbrightcont()
69 * 0 | 0xc5 | setredbalance()
70 * 0 | 0xc6 | setwhitebalance()
71 * 0 | 0xc7 | setbluebalance()
72 * 0 | 0xdc | setbrightcont(), setcolors()
73 * 3 | 0x02 | setexposure()
74 * 3 | 0x10, 0x12 | setgain()
75 * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
76 * 3 | 0x21 | sethvflip()
77 */
63 78
64#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 79#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
65 80
@@ -89,7 +104,6 @@ enum e_ctrl {
89 NCTRLS /* number of controls */ 104 NCTRLS /* number of controls */
90}; 105};
91 106
92/* specific webcam descriptor for pac7302 */
93struct sd { 107struct sd {
94 struct gspca_dev gspca_dev; /* !! must be the first item */ 108 struct gspca_dev gspca_dev; /* !! must be the first item */
95 109
@@ -198,10 +212,10 @@ static const struct ctrl sd_ctrls[] = {
198 .type = V4L2_CTRL_TYPE_INTEGER, 212 .type = V4L2_CTRL_TYPE_INTEGER,
199 .name = "Gain", 213 .name = "Gain",
200 .minimum = 0, 214 .minimum = 0,
201 .maximum = 255, 215 .maximum = 62,
202 .step = 1, 216 .step = 1,
203#define GAIN_DEF 127 217#define GAIN_DEF 15
204#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ 218#define GAIN_KNEE 46
205 .default_value = GAIN_DEF, 219 .default_value = GAIN_DEF,
206 }, 220 },
207 .set_control = setgain 221 .set_control = setgain
@@ -270,7 +284,6 @@ static const struct v4l2_pix_format vga_mode[] = {
270#define LOAD_PAGE3 255 284#define LOAD_PAGE3 255
271#define END_OF_SEQUENCE 0 285#define END_OF_SEQUENCE 0
272 286
273/* pac 7302 */
274static const u8 init_7302[] = { 287static const u8 init_7302[] = {
275/* index,value */ 288/* index,value */
276 0xff, 0x01, /* page 1 */ 289 0xff, 0x01, /* page 1 */
@@ -509,7 +522,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
509 return 0; 522 return 0;
510} 523}
511 524
512/* This function is used by pac7302 only */
513static void setbrightcont(struct gspca_dev *gspca_dev) 525static void setbrightcont(struct gspca_dev *gspca_dev)
514{ 526{
515 struct sd *sd = (struct sd *) gspca_dev; 527 struct sd *sd = (struct sd *) gspca_dev;
@@ -536,7 +548,6 @@ static void setbrightcont(struct gspca_dev *gspca_dev)
536 reg_w(gspca_dev, 0xdc, 0x01); 548 reg_w(gspca_dev, 0xdc, 0x01);
537} 549}
538 550
539/* This function is used by pac7302 only */
540static void setcolors(struct gspca_dev *gspca_dev) 551static void setcolors(struct gspca_dev *gspca_dev)
541{ 552{
542 struct sd *sd = (struct sd *) gspca_dev; 553 struct sd *sd = (struct sd *) gspca_dev;
@@ -590,9 +601,19 @@ static void setbluebalance(struct gspca_dev *gspca_dev)
590static void setgain(struct gspca_dev *gspca_dev) 601static void setgain(struct gspca_dev *gspca_dev)
591{ 602{
592 struct sd *sd = (struct sd *) gspca_dev; 603 struct sd *sd = (struct sd *) gspca_dev;
604 u8 reg10, reg12;
605
606 if (sd->ctrls[GAIN].val < 32) {
607 reg10 = sd->ctrls[GAIN].val;
608 reg12 = 0;
609 } else {
610 reg10 = 31;
611 reg12 = sd->ctrls[GAIN].val - 31;
612 }
593 613
594 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 614 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
595 reg_w(gspca_dev, 0x10, sd->ctrls[GAIN].val >> 3); 615 reg_w(gspca_dev, 0x10, reg10);
616 reg_w(gspca_dev, 0x12, reg12);
596 617
597 /* load registers to sensor (Bit 0, auto clear) */ 618 /* load registers to sensor (Bit 0, auto clear) */
598 reg_w(gspca_dev, 0x11, 0x01); 619 reg_w(gspca_dev, 0x11, 0x01);
@@ -604,28 +625,36 @@ static void setexposure(struct gspca_dev *gspca_dev)
604 u8 clockdiv; 625 u8 clockdiv;
605 u16 exposure; 626 u16 exposure;
606 627
607 /* register 2 of frame 3 contains the clock divider configuring the 628 /*
608 no fps according to the formula: 90 / reg. sd->exposure is the 629 * Register 2 of frame 3 contains the clock divider configuring the
609 desired exposure time in 0.5 ms. */ 630 * no fps according to the formula: 90 / reg. sd->exposure is the
631 * desired exposure time in 0.5 ms.
632 */
610 clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000; 633 clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000;
611 634
612 /* Note clockdiv = 3 also works, but when running at 30 fps, depending 635 /*
613 on the scene being recorded, the camera switches to another 636 * Note clockdiv = 3 also works, but when running at 30 fps, depending
614 quantization table for certain JPEG blocks, and we don't know how 637 * on the scene being recorded, the camera switches to another
615 to decompress these blocks. So we cap the framerate at 15 fps */ 638 * quantization table for certain JPEG blocks, and we don't know how
639 * to decompress these blocks. So we cap the framerate at 15 fps.
640 */
616 if (clockdiv < 6) 641 if (clockdiv < 6)
617 clockdiv = 6; 642 clockdiv = 6;
618 else if (clockdiv > 63) 643 else if (clockdiv > 63)
619 clockdiv = 63; 644 clockdiv = 63;
620 645
621 /* reg2 MUST be a multiple of 3, except when between 6 and 12? 646 /*
622 Always round up, otherwise we cannot get the desired frametime 647 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
623 using the partial frame time exposure control */ 648 * Always round up, otherwise we cannot get the desired frametime
649 * using the partial frame time exposure control.
650 */
624 if (clockdiv < 6 || clockdiv > 12) 651 if (clockdiv < 6 || clockdiv > 12)
625 clockdiv = ((clockdiv + 2) / 3) * 3; 652 clockdiv = ((clockdiv + 2) / 3) * 3;
626 653
627 /* frame exposure time in ms = 1000 * clockdiv / 90 -> 654 /*
628 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */ 655 * frame exposure time in ms = 1000 * clockdiv / 90 ->
656 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
657 */
629 exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv); 658 exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv);
630 /* 0 = use full frametime, 448 = no exposure, reverse it */ 659 /* 0 = use full frametime, 448 = no exposure, reverse it */
631 exposure = 448 - exposure; 660 exposure = 448 - exposure;
@@ -643,10 +672,12 @@ static void setautogain(struct gspca_dev *gspca_dev)
643{ 672{
644 struct sd *sd = (struct sd *) gspca_dev; 673 struct sd *sd = (struct sd *) gspca_dev;
645 674
646 /* when switching to autogain set defaults to make sure 675 /*
647 we are on a valid point of the autogain gain / 676 * When switching to autogain set defaults to make sure
648 exposure knee graph, and give this change time to 677 * we are on a valid point of the autogain gain /
649 take effect before doing autogain. */ 678 * exposure knee graph, and give this change time to
679 * take effect before doing autogain.
680 */
650 if (sd->ctrls[AUTOGAIN].val) { 681 if (sd->ctrls[AUTOGAIN].val) {
651 sd->ctrls[EXPOSURE].val = EXPOSURE_DEF; 682 sd->ctrls[EXPOSURE].val = EXPOSURE_DEF;
652 sd->ctrls[GAIN].val = GAIN_DEF; 683 sd->ctrls[GAIN].val = GAIN_DEF;
@@ -700,8 +731,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
700 setautogain(gspca_dev); 731 setautogain(gspca_dev);
701 sethvflip(gspca_dev); 732 sethvflip(gspca_dev);
702 733
703 /* only resolution 640x480 is supported for pac7302 */
704
705 sd->sof_read = 0; 734 sd->sof_read = 0;
706 atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val); 735 atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val);
707 736
@@ -729,9 +758,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
729 reg_w(gspca_dev, 0x78, 0x40); 758 reg_w(gspca_dev, 0x78, 0x40);
730} 759}
731 760
732/* !! coarse_grained_expo_autogain is not used !! */ 761#define WANT_REGULAR_AUTOGAIN
733#define exp_too_low_cnt flags
734#define exp_too_high_cnt sof_read
735#include "autogain_functions.h" 762#include "autogain_functions.h"
736 763
737static void do_autogain(struct gspca_dev *gspca_dev) 764static void do_autogain(struct gspca_dev *gspca_dev)
@@ -792,10 +819,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
792 if (sof) { 819 if (sof) {
793 int n, lum_offset, footer_length; 820 int n, lum_offset, footer_length;
794 821
795 /* 6 bytes after the FF D9 EOF marker a number of lumination 822 /*
796 bytes are send corresponding to different parts of the 823 * 6 bytes after the FF D9 EOF marker a number of lumination
797 image, the 14th and 15th byte after the EOF seem to 824 * bytes are send corresponding to different parts of the
798 correspond to the center of the image */ 825 * image, the 14th and 15th byte after the EOF seem to
826 * correspond to the center of the image.
827 */
799 lum_offset = 61 + sizeof pac_sof_marker; 828 lum_offset = 61 + sizeof pac_sof_marker;
800 footer_length = 74; 829 footer_length = 74;
801 830
@@ -839,9 +868,10 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
839 u8 index; 868 u8 index;
840 u8 value; 869 u8 value;
841 870
842 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit 871 /*
843 long on the USB bus) 872 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
844 */ 873 * long on the USB bus)
874 */
845 if (reg->match.type == V4L2_CHIP_MATCH_HOST && 875 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
846 reg->match.addr == 0 && 876 reg->match.addr == 0 &&
847 (reg->reg < 0x000000ff) && 877 (reg->reg < 0x000000ff) &&
@@ -852,9 +882,11 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
852 index = reg->reg; 882 index = reg->reg;
853 value = reg->val; 883 value = reg->val;
854 884
855 /* Note that there shall be no access to other page 885 /*
856 by any other function between the page swith and 886 * Note that there shall be no access to other page
857 the actual register write */ 887 * by any other function between the page switch and
888 * the actual register write.
889 */
858 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 890 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
859 reg_w(gspca_dev, index, value); 891 reg_w(gspca_dev, index, value);
860 892
@@ -940,6 +972,7 @@ static const struct usb_device_id device_table[] = {
940 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, 972 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
941 {USB_DEVICE(0x093a, 0x2625)}, 973 {USB_DEVICE(0x093a, 0x2625)},
942 {USB_DEVICE(0x093a, 0x2626)}, 974 {USB_DEVICE(0x093a, 0x2626)},
975 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
943 {USB_DEVICE(0x093a, 0x2628)}, 976 {USB_DEVICE(0x093a, 0x2628)},
944 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, 977 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
945 {USB_DEVICE(0x093a, 0x262a)}, 978 {USB_DEVICE(0x093a, 0x262a)},
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 1ac111176ffa..2cb7d95f7be7 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -20,34 +20,42 @@
20 */ 20 */
21 21
22/* Some documentation about various registers as determined by trial and error. 22/* Some documentation about various registers as determined by trial and error.
23 When the register addresses differ between the 7202 and the 7311 the 2 23 *
24 different addresses are written as 7302addr/7311addr, when one of the 2 24 * Register page 1:
25 addresses is a - sign that register description is not valid for the 25 *
26 matching IC. 26 * Address Description
27 27 * 0x08 Unknown compressor related, must always be 8 except when not
28 Register page 1: 28 * in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
29 29 * 0x1b Auto white balance related, bit 0 is AWB enable (inverted)
30 Address Description 30 * bits 345 seem to toggle per color gains on/off (inverted)
31 -/0x08 Unknown compressor related, must always be 8 except when not 31 * 0x78 Global control, bit 6 controls the LED (inverted)
32 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 ! 32 * 0x80 Compression balance, interesting settings:
33 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted) 33 * 0x01 Use this to allow the camera to switch to higher compr.
34 bits 345 seem to toggle per color gains on/off (inverted) 34 * on the fly. Needed to stay within bandwidth @ 640x480@30
35 0x78 Global control, bit 6 controls the LED (inverted) 35 * 0x1c From usb captures under Windows for 640x480
36 -/0x80 JPEG compression ratio ? Best not touched 36 * 0x2a Values >= this switch the camera to a lower compression,
37 37 * using the same table for both luminance and chrominance.
38 Register page 3/4: 38 * This gives a sharper picture. Usable only at 640x480@ <
39 39 * 15 fps or 320x240 / 160x120. Note currently the driver
40 Address Description 40 * does not use this as the quality gain is small and the
41 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on 41 * generated JPG-s are only understood by v4l-utils >= 0.8.9
42 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12? 42 * 0x3f From usb captures under Windows for 320x240
43 -/0x0f Master gain 1-245, low value = high gain 43 * 0x69 From usb captures under Windows for 160x120
44 0x10/- Master gain 0-31 44 *
45 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess) 45 * Register page 4:
46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused 46 *
47 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to 47 * Address Description
48 completely disable the analog amplification block. Set to 0x68 48 * 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
49 for max gain, 0x14 for minimal gain. 49 * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
50*/ 50 * 0x0f Master gain 1-245, low value = high gain
51 * 0x10 Another gain 0-15, limited influence (1-2x gain I guess)
52 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
53 * Note setting vflip disabled leads to a much lower image quality,
54 * so we always vflip, and tell userspace to flip it back
55 * 0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
56 * completely disable the analog amplification block. Set to 0x68
57 * for max gain, 0x14 for minimal gain.
58 */
51 59
52#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 60#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
53 61
@@ -55,21 +63,21 @@
55 63
56#include <linux/input.h> 64#include <linux/input.h>
57#include "gspca.h" 65#include "gspca.h"
66/* Include pac common sof detection functions */
67#include "pac_common.h"
68
69#define PAC7311_GAIN_DEFAULT 122
70#define PAC7311_EXPOSURE_DEFAULT 3 /* 20 fps, avoid using high compr. */
58 71
59MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 72MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
60MODULE_DESCRIPTION("Pixart PAC7311"); 73MODULE_DESCRIPTION("Pixart PAC7311");
61MODULE_LICENSE("GPL"); 74MODULE_LICENSE("GPL");
62 75
63/* specific webcam descriptor for pac7311 */
64struct sd { 76struct sd {
65 struct gspca_dev gspca_dev; /* !! must be the first item */ 77 struct gspca_dev gspca_dev; /* !! must be the first item */
66 78
67 unsigned char contrast; 79 struct v4l2_ctrl *contrast;
68 unsigned char gain; 80 struct v4l2_ctrl *hflip;
69 unsigned char exposure;
70 unsigned char autogain;
71 __u8 hflip;
72 __u8 vflip;
73 81
74 u8 sof_read; 82 u8 sof_read;
75 u8 autogain_ignore_frames; 83 u8 autogain_ignore_frames;
@@ -77,114 +85,6 @@ struct sd {
77 atomic_t avg_lum; 85 atomic_t avg_lum;
78}; 86};
79 87
80/* V4L2 controls supported by the driver */
81static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
93
94static const struct ctrl sd_ctrls[] = {
95/* This control is for both the 7302 and the 7311 */
96 {
97 {
98 .id = V4L2_CID_CONTRAST,
99 .type = V4L2_CTRL_TYPE_INTEGER,
100 .name = "Contrast",
101 .minimum = 0,
102#define CONTRAST_MAX 255
103 .maximum = CONTRAST_MAX,
104 .step = 1,
105#define CONTRAST_DEF 127
106 .default_value = CONTRAST_DEF,
107 },
108 .set = sd_setcontrast,
109 .get = sd_getcontrast,
110 },
111/* All controls below are for both the 7302 and the 7311 */
112 {
113 {
114 .id = V4L2_CID_GAIN,
115 .type = V4L2_CTRL_TYPE_INTEGER,
116 .name = "Gain",
117 .minimum = 0,
118#define GAIN_MAX 255
119 .maximum = GAIN_MAX,
120 .step = 1,
121#define GAIN_DEF 127
122#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
123 .default_value = GAIN_DEF,
124 },
125 .set = sd_setgain,
126 .get = sd_getgain,
127 },
128 {
129 {
130 .id = V4L2_CID_EXPOSURE,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "Exposure",
133 .minimum = 0,
134#define EXPOSURE_MAX 255
135 .maximum = EXPOSURE_MAX,
136 .step = 1,
137#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
138#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
139 .default_value = EXPOSURE_DEF,
140 },
141 .set = sd_setexposure,
142 .get = sd_getexposure,
143 },
144 {
145 {
146 .id = V4L2_CID_AUTOGAIN,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Auto Gain",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
152#define AUTOGAIN_DEF 1
153 .default_value = AUTOGAIN_DEF,
154 },
155 .set = sd_setautogain,
156 .get = sd_getautogain,
157 },
158 {
159 {
160 .id = V4L2_CID_HFLIP,
161 .type = V4L2_CTRL_TYPE_BOOLEAN,
162 .name = "Mirror",
163 .minimum = 0,
164 .maximum = 1,
165 .step = 1,
166#define HFLIP_DEF 0
167 .default_value = HFLIP_DEF,
168 },
169 .set = sd_sethflip,
170 .get = sd_gethflip,
171 },
172 {
173 {
174 .id = V4L2_CID_VFLIP,
175 .type = V4L2_CTRL_TYPE_BOOLEAN,
176 .name = "Vflip",
177 .minimum = 0,
178 .maximum = 1,
179 .step = 1,
180#define VFLIP_DEF 0
181 .default_value = VFLIP_DEF,
182 },
183 .set = sd_setvflip,
184 .get = sd_getvflip,
185 },
186};
187
188static const struct v4l2_pix_format vga_mode[] = { 88static const struct v4l2_pix_format vga_mode[] = {
189 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE, 89 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
190 .bytesperline = 160, 90 .bytesperline = 160,
@@ -206,8 +106,8 @@ static const struct v4l2_pix_format vga_mode[] = {
206#define LOAD_PAGE4 254 106#define LOAD_PAGE4 254
207#define END_OF_SEQUENCE 0 107#define END_OF_SEQUENCE 0
208 108
209/* pac 7311 */
210static const __u8 init_7311[] = { 109static const __u8 init_7311[] = {
110 0xff, 0x01,
211 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */ 111 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
212 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */ 112 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
213 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */ 113 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */
@@ -387,90 +287,73 @@ static void reg_w_var(struct gspca_dev *gspca_dev,
387static int sd_config(struct gspca_dev *gspca_dev, 287static int sd_config(struct gspca_dev *gspca_dev,
388 const struct usb_device_id *id) 288 const struct usb_device_id *id)
389{ 289{
390 struct sd *sd = (struct sd *) gspca_dev; 290 struct cam *cam = &gspca_dev->cam;
391 struct cam *cam;
392 291
393 cam = &gspca_dev->cam;
394
395 PDEBUG(D_CONF, "Find Sensor PAC7311");
396 cam->cam_mode = vga_mode; 292 cam->cam_mode = vga_mode;
397 cam->nmodes = ARRAY_SIZE(vga_mode); 293 cam->nmodes = ARRAY_SIZE(vga_mode);
294 cam->input_flags = V4L2_IN_ST_VFLIP;
398 295
399 sd->contrast = CONTRAST_DEF;
400 sd->gain = GAIN_DEF;
401 sd->exposure = EXPOSURE_DEF;
402 sd->autogain = AUTOGAIN_DEF;
403 sd->hflip = HFLIP_DEF;
404 sd->vflip = VFLIP_DEF;
405 return 0; 296 return 0;
406} 297}
407 298
408/* This function is used by pac7311 only */ 299static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
409static void setcontrast(struct gspca_dev *gspca_dev)
410{ 300{
411 struct sd *sd = (struct sd *) gspca_dev;
412
413 reg_w(gspca_dev, 0xff, 0x04); 301 reg_w(gspca_dev, 0xff, 0x04);
414 reg_w(gspca_dev, 0x10, sd->contrast >> 4); 302 reg_w(gspca_dev, 0x10, val);
415 /* load registers to sensor (Bit 0, auto clear) */ 303 /* load registers to sensor (Bit 0, auto clear) */
416 reg_w(gspca_dev, 0x11, 0x01); 304 reg_w(gspca_dev, 0x11, 0x01);
417} 305}
418 306
419static void setgain(struct gspca_dev *gspca_dev) 307static void setgain(struct gspca_dev *gspca_dev, s32 val)
420{ 308{
421 struct sd *sd = (struct sd *) gspca_dev;
422 int gain = GAIN_MAX - sd->gain;
423
424 if (gain < 1)
425 gain = 1;
426 else if (gain > 245)
427 gain = 245;
428 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 309 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
429 reg_w(gspca_dev, 0x0e, 0x00); 310 reg_w(gspca_dev, 0x0e, 0x00);
430 reg_w(gspca_dev, 0x0f, gain); 311 reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
431 312
432 /* load registers to sensor (Bit 0, auto clear) */ 313 /* load registers to sensor (Bit 0, auto clear) */
433 reg_w(gspca_dev, 0x11, 0x01); 314 reg_w(gspca_dev, 0x11, 0x01);
434} 315}
435 316
436static void setexposure(struct gspca_dev *gspca_dev) 317static void setexposure(struct gspca_dev *gspca_dev, s32 val)
437{ 318{
438 struct sd *sd = (struct sd *) gspca_dev;
439 __u8 reg;
440
441 /* register 2 of frame 3/4 contains the clock divider configuring the
442 no fps according to the formula: 60 / reg. sd->exposure is the
443 desired exposure time in ms. */
444 reg = 120 * sd->exposure / 1000;
445 if (reg < 2)
446 reg = 2;
447 else if (reg > 63)
448 reg = 63;
449
450 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 319 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
451 reg_w(gspca_dev, 0x02, reg); 320 reg_w(gspca_dev, 0x02, val);
452 321
453 /* Page 1 register 8 must always be 0x08 except when not in 322 /* load registers to sensor (Bit 0, auto clear) */
454 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */ 323 reg_w(gspca_dev, 0x11, 0x01);
324
325 /*
326 * Page 1 register 8 must always be 0x08 except when not in
327 * 640x480 mode and page 4 reg 2 <= 3 then it must be 9
328 */
455 reg_w(gspca_dev, 0xff, 0x01); 329 reg_w(gspca_dev, 0xff, 0x01);
456 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv && 330 if (gspca_dev->width != 640 && val <= 3)
457 reg <= 3) {
458 reg_w(gspca_dev, 0x08, 0x09); 331 reg_w(gspca_dev, 0x08, 0x09);
459 } else { 332 else
460 reg_w(gspca_dev, 0x08, 0x08); 333 reg_w(gspca_dev, 0x08, 0x08);
461 } 334
335 /*
336 * Page1 register 80 sets the compression balance, normally we
337 * want / use 0x1c, but for 640x480@30fps we must allow the
338 * camera to use higher compression or we may run out of
339 * bandwidth.
340 */
341 if (gspca_dev->width == 640 && val == 2)
342 reg_w(gspca_dev, 0x80, 0x01);
343 else
344 reg_w(gspca_dev, 0x80, 0x1c);
462 345
463 /* load registers to sensor (Bit 0, auto clear) */ 346 /* load registers to sensor (Bit 0, auto clear) */
464 reg_w(gspca_dev, 0x11, 0x01); 347 reg_w(gspca_dev, 0x11, 0x01);
465} 348}
466 349
467static void sethvflip(struct gspca_dev *gspca_dev) 350static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
468{ 351{
469 struct sd *sd = (struct sd *) gspca_dev;
470 __u8 data; 352 __u8 data;
471 353
472 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */ 354 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
473 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00); 355 data = (hflip ? 0x04 : 0x00) |
356 (vflip ? 0x08 : 0x00);
474 reg_w(gspca_dev, 0x21, data); 357 reg_w(gspca_dev, 0x21, data);
475 358
476 /* load registers to sensor (Bit 0, auto clear) */ 359 /* load registers to sensor (Bit 0, auto clear) */
@@ -484,6 +367,82 @@ static int sd_init(struct gspca_dev *gspca_dev)
484 return gspca_dev->usb_err; 367 return gspca_dev->usb_err;
485} 368}
486 369
370static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
371{
372 struct gspca_dev *gspca_dev =
373 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
374 struct sd *sd = (struct sd *)gspca_dev;
375
376 gspca_dev->usb_err = 0;
377
378 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
379 /* when switching to autogain set defaults to make sure
380 we are on a valid point of the autogain gain /
381 exposure knee graph, and give this change time to
382 take effect before doing autogain. */
383 gspca_dev->exposure->val = PAC7311_EXPOSURE_DEFAULT;
384 gspca_dev->gain->val = PAC7311_GAIN_DEFAULT;
385 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
386 }
387
388 if (!gspca_dev->streaming)
389 return 0;
390
391 switch (ctrl->id) {
392 case V4L2_CID_CONTRAST:
393 setcontrast(gspca_dev, ctrl->val);
394 break;
395 case V4L2_CID_AUTOGAIN:
396 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
397 setexposure(gspca_dev, gspca_dev->exposure->val);
398 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
399 setgain(gspca_dev, gspca_dev->gain->val);
400 break;
401 case V4L2_CID_HFLIP:
402 sethvflip(gspca_dev, sd->hflip->val, 1);
403 break;
404 default:
405 return -EINVAL;
406 }
407 return gspca_dev->usb_err;
408}
409
410static const struct v4l2_ctrl_ops sd_ctrl_ops = {
411 .s_ctrl = sd_s_ctrl,
412};
413
414/* this function is called at probe time */
415static int sd_init_controls(struct gspca_dev *gspca_dev)
416{
417 struct sd *sd = (struct sd *) gspca_dev;
418 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
419
420 gspca_dev->vdev.ctrl_handler = hdl;
421 v4l2_ctrl_handler_init(hdl, 4);
422
423 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
424 V4L2_CID_CONTRAST, 0, 15, 1, 7);
425 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
426 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
427 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
428 V4L2_CID_EXPOSURE, 2, 63, 1,
429 PAC7311_EXPOSURE_DEFAULT);
430 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
431 V4L2_CID_GAIN, 0, 244, 1,
432 PAC7311_GAIN_DEFAULT);
433 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
434 V4L2_CID_HFLIP, 0, 1, 1, 0);
435
436 if (hdl->error) {
437 pr_err("Could not initialize controls\n");
438 return hdl->error;
439 }
440
441 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
442 return 0;
443}
444
445/* -- start the camera -- */
487static int sd_start(struct gspca_dev *gspca_dev) 446static int sd_start(struct gspca_dev *gspca_dev)
488{ 447{
489 struct sd *sd = (struct sd *) gspca_dev; 448 struct sd *sd = (struct sd *) gspca_dev;
@@ -492,19 +451,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
492 451
493 reg_w_var(gspca_dev, start_7311, 452 reg_w_var(gspca_dev, start_7311,
494 page4_7311, sizeof(page4_7311)); 453 page4_7311, sizeof(page4_7311));
495 setcontrast(gspca_dev); 454 setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
496 setgain(gspca_dev); 455 setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
497 setexposure(gspca_dev); 456 setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
498 sethvflip(gspca_dev); 457 sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
499 458
500 /* set correct resolution */ 459 /* set correct resolution */
501 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 460 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
502 case 2: /* 160x120 pac7311 */ 461 case 2: /* 160x120 */
503 reg_w(gspca_dev, 0xff, 0x01); 462 reg_w(gspca_dev, 0xff, 0x01);
504 reg_w(gspca_dev, 0x17, 0x20); 463 reg_w(gspca_dev, 0x17, 0x20);
505 reg_w(gspca_dev, 0x87, 0x10); 464 reg_w(gspca_dev, 0x87, 0x10);
506 break; 465 break;
507 case 1: /* 320x240 pac7311 */ 466 case 1: /* 320x240 */
508 reg_w(gspca_dev, 0xff, 0x01); 467 reg_w(gspca_dev, 0xff, 0x01);
509 reg_w(gspca_dev, 0x17, 0x30); 468 reg_w(gspca_dev, 0x17, 0x30);
510 reg_w(gspca_dev, 0x87, 0x11); 469 reg_w(gspca_dev, 0x87, 0x11);
@@ -541,14 +500,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
541 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */ 500 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
542} 501}
543 502
544/* called on streamoff with alt 0 and on disconnect for 7311 */
545static void sd_stop0(struct gspca_dev *gspca_dev)
546{
547}
548
549/* Include pac common sof detection functions */
550#include "pac_common.h"
551
552static void do_autogain(struct gspca_dev *gspca_dev) 503static void do_autogain(struct gspca_dev *gspca_dev)
553{ 504{
554 struct sd *sd = (struct sd *) gspca_dev; 505 struct sd *sd = (struct sd *) gspca_dev;
@@ -558,13 +509,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
558 if (avg_lum == -1) 509 if (avg_lum == -1)
559 return; 510 return;
560 511
561 desired_lum = 200; 512 desired_lum = 170;
562 deadzone = 20; 513 deadzone = 20;
563 514
564 if (sd->autogain_ignore_frames > 0) 515 if (sd->autogain_ignore_frames > 0)
565 sd->autogain_ignore_frames--; 516 sd->autogain_ignore_frames--;
566 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 517 else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
567 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) 518 desired_lum, deadzone))
568 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 519 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
569} 520}
570 521
@@ -628,10 +579,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
628 if (sof) { 579 if (sof) {
629 int n, lum_offset, footer_length; 580 int n, lum_offset, footer_length;
630 581
631 /* 6 bytes after the FF D9 EOF marker a number of lumination 582 /*
632 bytes are send corresponding to different parts of the 583 * 6 bytes after the FF D9 EOF marker a number of lumination
633 image, the 14th and 15th byte after the EOF seem to 584 * bytes are send corresponding to different parts of the
634 correspond to the center of the image */ 585 * image, the 14th and 15th byte after the EOF seem to
586 * correspond to the center of the image.
587 */
635 lum_offset = 24 + sizeof pac_sof_marker; 588 lum_offset = 24 + sizeof pac_sof_marker;
636 footer_length = 26; 589 footer_length = 26;
637 590
@@ -668,127 +621,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
668 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 621 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
669} 622}
670 623
671static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
672{
673 struct sd *sd = (struct sd *) gspca_dev;
674
675 sd->contrast = val;
676 if (gspca_dev->streaming)
677 setcontrast(gspca_dev);
678 return gspca_dev->usb_err;
679}
680
681static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
682{
683 struct sd *sd = (struct sd *) gspca_dev;
684
685 *val = sd->contrast;
686 return 0;
687}
688
689static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
690{
691 struct sd *sd = (struct sd *) gspca_dev;
692
693 sd->gain = val;
694 if (gspca_dev->streaming)
695 setgain(gspca_dev);
696 return gspca_dev->usb_err;
697}
698
699static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
700{
701 struct sd *sd = (struct sd *) gspca_dev;
702
703 *val = sd->gain;
704 return 0;
705}
706
707static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
708{
709 struct sd *sd = (struct sd *) gspca_dev;
710
711 sd->exposure = val;
712 if (gspca_dev->streaming)
713 setexposure(gspca_dev);
714 return gspca_dev->usb_err;
715}
716
717static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
718{
719 struct sd *sd = (struct sd *) gspca_dev;
720
721 *val = sd->exposure;
722 return 0;
723}
724
725static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
726{
727 struct sd *sd = (struct sd *) gspca_dev;
728
729 sd->autogain = val;
730 /* when switching to autogain set defaults to make sure
731 we are on a valid point of the autogain gain /
732 exposure knee graph, and give this change time to
733 take effect before doing autogain. */
734 if (sd->autogain) {
735 sd->exposure = EXPOSURE_DEF;
736 sd->gain = GAIN_DEF;
737 if (gspca_dev->streaming) {
738 sd->autogain_ignore_frames =
739 PAC_AUTOGAIN_IGNORE_FRAMES;
740 setexposure(gspca_dev);
741 setgain(gspca_dev);
742 }
743 }
744
745 return gspca_dev->usb_err;
746}
747
748static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
749{
750 struct sd *sd = (struct sd *) gspca_dev;
751
752 *val = sd->autogain;
753 return 0;
754}
755
756static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
757{
758 struct sd *sd = (struct sd *) gspca_dev;
759
760 sd->hflip = val;
761 if (gspca_dev->streaming)
762 sethvflip(gspca_dev);
763 return gspca_dev->usb_err;
764}
765
766static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
767{
768 struct sd *sd = (struct sd *) gspca_dev;
769
770 *val = sd->hflip;
771 return 0;
772}
773
774static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
775{
776 struct sd *sd = (struct sd *) gspca_dev;
777
778 sd->vflip = val;
779 if (gspca_dev->streaming)
780 sethvflip(gspca_dev);
781 return gspca_dev->usb_err;
782}
783
784static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
785{
786 struct sd *sd = (struct sd *) gspca_dev;
787
788 *val = sd->vflip;
789 return 0;
790}
791
792#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 624#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
793static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 625static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
794 u8 *data, /* interrupt packet data */ 626 u8 *data, /* interrupt packet data */
@@ -820,16 +652,13 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
820} 652}
821#endif 653#endif
822 654
823/* sub-driver description for pac7311 */
824static const struct sd_desc sd_desc = { 655static const struct sd_desc sd_desc = {
825 .name = MODULE_NAME, 656 .name = MODULE_NAME,
826 .ctrls = sd_ctrls,
827 .nctrls = ARRAY_SIZE(sd_ctrls),
828 .config = sd_config, 657 .config = sd_config,
829 .init = sd_init, 658 .init = sd_init,
659 .init_controls = sd_init_controls,
830 .start = sd_start, 660 .start = sd_start,
831 .stopN = sd_stopN, 661 .stopN = sd_stopN,
832 .stop0 = sd_stop0,
833 .pkt_scan = sd_pkt_scan, 662 .pkt_scan = sd_pkt_scan,
834 .dq_callback = do_autogain, 663 .dq_callback = do_autogain,
835#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 664#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 7e71aa2d2522..ad098202d7f0 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -59,35 +59,38 @@ MODULE_LICENSE("GPL");
59#define SENSOR_MT9M111 9 59#define SENSOR_MT9M111 9
60#define SENSOR_MT9M112 10 60#define SENSOR_MT9M112 10
61#define SENSOR_HV7131R 11 61#define SENSOR_HV7131R 11
62#define SENSOR_MT9VPRB 20 62#define SENSOR_MT9VPRB 12
63 63
64/* camera flags */ 64/* camera flags */
65#define HAS_NO_BUTTON 0x1 65#define HAS_NO_BUTTON 0x1
66#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ 66#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
67#define FLIP_DETECT 0x4 67#define FLIP_DETECT 0x4
68 68
69enum e_ctrl {
70 BRIGHTNESS,
71 CONTRAST,
72 SATURATION,
73 HUE,
74 GAMMA,
75 BLUE,
76 RED,
77 VFLIP,
78 HFLIP,
79 EXPOSURE,
80 GAIN,
81 AUTOGAIN,
82 QUALITY,
83 NCTRLS /* number of controls */
84};
85
86/* specific webcam descriptor */ 69/* specific webcam descriptor */
87struct sd { 70struct sd {
88 struct gspca_dev gspca_dev; 71 struct gspca_dev gspca_dev;
89 72
90 struct gspca_ctrl ctrls[NCTRLS]; 73 struct { /* color control cluster */
74 struct v4l2_ctrl *brightness;
75 struct v4l2_ctrl *contrast;
76 struct v4l2_ctrl *saturation;
77 struct v4l2_ctrl *hue;
78 };
79 struct { /* blue/red balance control cluster */
80 struct v4l2_ctrl *blue;
81 struct v4l2_ctrl *red;
82 };
83 struct { /* h/vflip control cluster */
84 struct v4l2_ctrl *hflip;
85 struct v4l2_ctrl *vflip;
86 };
87 struct v4l2_ctrl *gamma;
88 struct { /* autogain and exposure or gain control cluster */
89 struct v4l2_ctrl *autogain;
90 struct v4l2_ctrl *exposure;
91 struct v4l2_ctrl *gain;
92 };
93 struct v4l2_ctrl *jpegqual;
91 94
92 struct work_struct work; 95 struct work_struct work;
93 struct workqueue_struct *work_thread; 96 struct workqueue_struct *work_thread;
@@ -105,6 +108,7 @@ struct sd {
105 u8 exposure_step; 108 u8 exposure_step;
106 109
107 u8 i2c_addr; 110 u8 i2c_addr;
111 u8 i2c_intf;
108 u8 sensor; 112 u8 sensor;
109 u8 hstart; 113 u8 hstart;
110 u8 vstart; 114 u8 vstart;
@@ -166,175 +170,6 @@ static const struct dmi_system_id flip_dmi_table[] = {
166 {} 170 {}
167}; 171};
168 172
169static void set_cmatrix(struct gspca_dev *gspca_dev);
170static void set_gamma(struct gspca_dev *gspca_dev);
171static void set_redblue(struct gspca_dev *gspca_dev);
172static void set_hvflip(struct gspca_dev *gspca_dev);
173static void set_exposure(struct gspca_dev *gspca_dev);
174static void set_gain(struct gspca_dev *gspca_dev);
175static void set_quality(struct gspca_dev *gspca_dev);
176
177static const struct ctrl sd_ctrls[NCTRLS] = {
178[BRIGHTNESS] = {
179 {
180 .id = V4L2_CID_BRIGHTNESS,
181 .type = V4L2_CTRL_TYPE_INTEGER,
182 .name = "Brightness",
183 .minimum = 0,
184 .maximum = 0xff,
185 .step = 1,
186 .default_value = 0x7f
187 },
188 .set_control = set_cmatrix
189 },
190[CONTRAST] = {
191 {
192 .id = V4L2_CID_CONTRAST,
193 .type = V4L2_CTRL_TYPE_INTEGER,
194 .name = "Contrast",
195 .minimum = 0,
196 .maximum = 0xff,
197 .step = 1,
198 .default_value = 0x7f
199 },
200 .set_control = set_cmatrix
201 },
202[SATURATION] = {
203 {
204 .id = V4L2_CID_SATURATION,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Saturation",
207 .minimum = 0,
208 .maximum = 0xff,
209 .step = 1,
210 .default_value = 0x7f
211 },
212 .set_control = set_cmatrix
213 },
214[HUE] = {
215 {
216 .id = V4L2_CID_HUE,
217 .type = V4L2_CTRL_TYPE_INTEGER,
218 .name = "Hue",
219 .minimum = -180,
220 .maximum = 180,
221 .step = 1,
222 .default_value = 0
223 },
224 .set_control = set_cmatrix
225 },
226[GAMMA] = {
227 {
228 .id = V4L2_CID_GAMMA,
229 .type = V4L2_CTRL_TYPE_INTEGER,
230 .name = "Gamma",
231 .minimum = 0,
232 .maximum = 0xff,
233 .step = 1,
234 .default_value = 0x10
235 },
236 .set_control = set_gamma
237 },
238[BLUE] = {
239 {
240 .id = V4L2_CID_BLUE_BALANCE,
241 .type = V4L2_CTRL_TYPE_INTEGER,
242 .name = "Blue Balance",
243 .minimum = 0,
244 .maximum = 0x7f,
245 .step = 1,
246 .default_value = 0x28
247 },
248 .set_control = set_redblue
249 },
250[RED] = {
251 {
252 .id = V4L2_CID_RED_BALANCE,
253 .type = V4L2_CTRL_TYPE_INTEGER,
254 .name = "Red Balance",
255 .minimum = 0,
256 .maximum = 0x7f,
257 .step = 1,
258 .default_value = 0x28
259 },
260 .set_control = set_redblue
261 },
262[HFLIP] = {
263 {
264 .id = V4L2_CID_HFLIP,
265 .type = V4L2_CTRL_TYPE_BOOLEAN,
266 .name = "Horizontal Flip",
267 .minimum = 0,
268 .maximum = 1,
269 .step = 1,
270 .default_value = 0,
271 },
272 .set_control = set_hvflip
273 },
274[VFLIP] = {
275 {
276 .id = V4L2_CID_VFLIP,
277 .type = V4L2_CTRL_TYPE_BOOLEAN,
278 .name = "Vertical Flip",
279 .minimum = 0,
280 .maximum = 1,
281 .step = 1,
282 .default_value = 0,
283 },
284 .set_control = set_hvflip
285 },
286[EXPOSURE] = {
287 {
288 .id = V4L2_CID_EXPOSURE,
289 .type = V4L2_CTRL_TYPE_INTEGER,
290 .name = "Exposure",
291 .minimum = 0,
292 .maximum = 0x1780,
293 .step = 1,
294 .default_value = 0x33,
295 },
296 .set_control = set_exposure
297 },
298[GAIN] = {
299 {
300 .id = V4L2_CID_GAIN,
301 .type = V4L2_CTRL_TYPE_INTEGER,
302 .name = "Gain",
303 .minimum = 0,
304 .maximum = 28,
305 .step = 1,
306 .default_value = 0,
307 },
308 .set_control = set_gain
309 },
310[AUTOGAIN] = {
311 {
312 .id = V4L2_CID_AUTOGAIN,
313 .type = V4L2_CTRL_TYPE_BOOLEAN,
314 .name = "Auto Exposure",
315 .minimum = 0,
316 .maximum = 1,
317 .step = 1,
318 .default_value = 1,
319 },
320 },
321[QUALITY] = {
322 {
323 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
324 .type = V4L2_CTRL_TYPE_INTEGER,
325 .name = "Compression Quality",
326#define QUALITY_MIN 50
327#define QUALITY_MAX 90
328#define QUALITY_DEF 80
329 .minimum = QUALITY_MIN,
330 .maximum = QUALITY_MAX,
331 .step = 1,
332 .default_value = QUALITY_DEF,
333 },
334 .set_control = set_quality
335 },
336};
337
338static const struct v4l2_pix_format vga_mode[] = { 173static const struct v4l2_pix_format vga_mode[] = {
339 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 174 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
340 .bytesperline = 160, 175 .bytesperline = 160,
@@ -747,7 +582,7 @@ static const s16 hsv_blue_y[] = {
747 4, 2, 0, -1, -3, -5, -7, -9, -11 582 4, 2, 0, -1, -3, -5, -7, -9, -11
748}; 583};
749 584
750static u16 i2c_ident[] = { 585static const u16 i2c_ident[] = {
751 V4L2_IDENT_OV9650, 586 V4L2_IDENT_OV9650,
752 V4L2_IDENT_OV9655, 587 V4L2_IDENT_OV9655,
753 V4L2_IDENT_SOI968, 588 V4L2_IDENT_SOI968,
@@ -760,9 +595,10 @@ static u16 i2c_ident[] = {
760 V4L2_IDENT_MT9M111, 595 V4L2_IDENT_MT9M111,
761 V4L2_IDENT_MT9M112, 596 V4L2_IDENT_MT9M112,
762 V4L2_IDENT_HV7131R, 597 V4L2_IDENT_HV7131R,
598[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
763}; 599};
764 600
765static u16 bridge_init[][2] = { 601static const u16 bridge_init[][2] = {
766 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c}, 602 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
767 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40}, 603 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
768 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10}, 604 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
@@ -786,7 +622,7 @@ static u16 bridge_init[][2] = {
786}; 622};
787 623
788/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ 624/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
789static u8 ov_gain[] = { 625static const u8 ov_gain[] = {
790 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */, 626 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
791 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */, 627 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
792 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */, 628 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
@@ -798,7 +634,7 @@ static u8 ov_gain[] = {
798}; 634};
799 635
800/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */ 636/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
801static u16 micron1_gain[] = { 637static const u16 micron1_gain[] = {
802 /* 1x 1.25x 1.5x 1.75x */ 638 /* 1x 1.25x 1.5x 1.75x */
803 0x0020, 0x0028, 0x0030, 0x0038, 639 0x0020, 0x0028, 0x0030, 0x0038,
804 /* 2x 2.25x 2.5x 2.75x */ 640 /* 2x 2.25x 2.5x 2.75x */
@@ -819,7 +655,7 @@ static u16 micron1_gain[] = {
819 655
820/* mt9m001 sensor uses a different gain formula then other micron sensors */ 656/* mt9m001 sensor uses a different gain formula then other micron sensors */
821/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */ 657/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
822static u16 micron2_gain[] = { 658static const u16 micron2_gain[] = {
823 /* 1x 1.25x 1.5x 1.75x */ 659 /* 1x 1.25x 1.5x 1.75x */
824 0x0008, 0x000a, 0x000c, 0x000e, 660 0x0008, 0x000a, 0x000c, 0x000e,
825 /* 2x 2.25x 2.5x 2.75x */ 661 /* 2x 2.25x 2.5x 2.75x */
@@ -839,7 +675,7 @@ static u16 micron2_gain[] = {
839}; 675};
840 676
841/* Gain = .5 + bit[7:0] / 16 */ 677/* Gain = .5 + bit[7:0] / 16 */
842static u8 hv7131r_gain[] = { 678static const u8 hv7131r_gain[] = {
843 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */, 679 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
844 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */, 680 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
845 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */, 681 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
@@ -850,7 +686,7 @@ static u8 hv7131r_gain[] = {
850 0x78 /* 8x */ 686 0x78 /* 8x */
851}; 687};
852 688
853static struct i2c_reg_u8 soi968_init[] = { 689static const struct i2c_reg_u8 soi968_init[] = {
854 {0x0c, 0x00}, {0x0f, 0x1f}, 690 {0x0c, 0x00}, {0x0f, 0x1f},
855 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 691 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
856 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 692 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
@@ -864,7 +700,7 @@ static struct i2c_reg_u8 soi968_init[] = {
864 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, 700 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
865}; 701};
866 702
867static struct i2c_reg_u8 ov7660_init[] = { 703static const struct i2c_reg_u8 ov7660_init[] = {
868 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 704 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
869 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 705 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
870 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 706 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
@@ -872,11 +708,11 @@ static struct i2c_reg_u8 ov7660_init[] = {
872 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */ 708 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
873 {0x17, 0x10}, {0x18, 0x61}, 709 {0x17, 0x10}, {0x18, 0x61},
874 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, 710 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
875 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6}, 711 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
876 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50}, 712 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
877}; 713};
878 714
879static struct i2c_reg_u8 ov7670_init[] = { 715static const struct i2c_reg_u8 ov7670_init[] = {
880 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 716 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
881 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 717 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
882 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 718 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
@@ -933,7 +769,7 @@ static struct i2c_reg_u8 ov7670_init[] = {
933 {0x93, 0x00}, 769 {0x93, 0x00},
934}; 770};
935 771
936static struct i2c_reg_u8 ov9650_init[] = { 772static const struct i2c_reg_u8 ov9650_init[] = {
937 {0x00, 0x00}, {0x01, 0x78}, 773 {0x00, 0x00}, {0x01, 0x78},
938 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 774 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
939 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 775 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
@@ -963,7 +799,7 @@ static struct i2c_reg_u8 ov9650_init[] = {
963 {0xaa, 0x92}, {0xab, 0x0a}, 799 {0xaa, 0x92}, {0xab, 0x0a},
964}; 800};
965 801
966static struct i2c_reg_u8 ov9655_init[] = { 802static const struct i2c_reg_u8 ov9655_init[] = {
967 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, 803 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
968 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, 804 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
969 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, 805 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
@@ -990,7 +826,7 @@ static struct i2c_reg_u8 ov9655_init[] = {
990 {0x04, 0x03}, {0x00, 0x13}, 826 {0x04, 0x03}, {0x00, 0x13},
991}; 827};
992 828
993static struct i2c_reg_u16 mt9v112_init[] = { 829static const struct i2c_reg_u16 mt9v112_init[] = {
994 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, 830 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
995 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, 831 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
996 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, 832 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
@@ -1009,7 +845,7 @@ static struct i2c_reg_u16 mt9v112_init[] = {
1009 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, 845 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1010}; 846};
1011 847
1012static struct i2c_reg_u16 mt9v111_init[] = { 848static const struct i2c_reg_u16 mt9v111_init[] = {
1013 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, 849 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1014 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0}, 850 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1015 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e}, 851 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
@@ -1019,7 +855,7 @@ static struct i2c_reg_u16 mt9v111_init[] = {
1019 {0x0e, 0x0008}, {0x20, 0x0000} 855 {0x0e, 0x0008}, {0x20, 0x0000}
1020}; 856};
1021 857
1022static struct i2c_reg_u16 mt9v011_init[] = { 858static const struct i2c_reg_u16 mt9v011_init[] = {
1023 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, 859 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1024 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, 860 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1025 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, 861 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
@@ -1046,7 +882,7 @@ static struct i2c_reg_u16 mt9v011_init[] = {
1046 {0x06, 0x0029}, {0x05, 0x0009}, 882 {0x06, 0x0029}, {0x05, 0x0009},
1047}; 883};
1048 884
1049static struct i2c_reg_u16 mt9m001_init[] = { 885static const struct i2c_reg_u16 mt9m001_init[] = {
1050 {0x0d, 0x0001}, 886 {0x0d, 0x0001},
1051 {0x0d, 0x0000}, 887 {0x0d, 0x0000},
1052 {0x04, 0x0500}, /* hres = 1280 */ 888 {0x04, 0x0500}, /* hres = 1280 */
@@ -1062,21 +898,21 @@ static struct i2c_reg_u16 mt9m001_init[] = {
1062 {0x35, 0x0057}, 898 {0x35, 0x0057},
1063}; 899};
1064 900
1065static struct i2c_reg_u16 mt9m111_init[] = { 901static const struct i2c_reg_u16 mt9m111_init[] = {
1066 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, 902 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1067 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, 903 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1068 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, 904 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1069 {0xf0, 0x0000}, 905 {0xf0, 0x0000},
1070}; 906};
1071 907
1072static struct i2c_reg_u16 mt9m112_init[] = { 908static const struct i2c_reg_u16 mt9m112_init[] = {
1073 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, 909 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1074 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, 910 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1075 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, 911 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1076 {0xf0, 0x0000}, 912 {0xf0, 0x0000},
1077}; 913};
1078 914
1079static struct i2c_reg_u8 hv7131r_init[] = { 915static const struct i2c_reg_u8 hv7131r_init[] = {
1080 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, 916 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1081 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, 917 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1082 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, 918 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
@@ -1167,7 +1003,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1167 * from the point of view of the bridge, the length 1003 * from the point of view of the bridge, the length
1168 * includes the address 1004 * includes the address
1169 */ 1005 */
1170 row[0] = 0x81 | (2 << 4); 1006 row[0] = sd->i2c_intf | (2 << 4);
1171 row[1] = sd->i2c_addr; 1007 row[1] = sd->i2c_addr;
1172 row[2] = reg; 1008 row[2] = reg;
1173 row[3] = val; 1009 row[3] = val;
@@ -1180,7 +1016,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1180} 1016}
1181 1017
1182static void i2c_w1_buf(struct gspca_dev *gspca_dev, 1018static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1183 struct i2c_reg_u8 *buf, int sz) 1019 const struct i2c_reg_u8 *buf, int sz)
1184{ 1020{
1185 while (--sz >= 0) { 1021 while (--sz >= 0) {
1186 i2c_w1(gspca_dev, buf->reg, buf->val); 1022 i2c_w1(gspca_dev, buf->reg, buf->val);
@@ -1197,7 +1033,7 @@ static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1197 * from the point of view of the bridge, the length 1033 * from the point of view of the bridge, the length
1198 * includes the address 1034 * includes the address
1199 */ 1035 */
1200 row[0] = 0x81 | (3 << 4); 1036 row[0] = sd->i2c_intf | (3 << 4);
1201 row[1] = sd->i2c_addr; 1037 row[1] = sd->i2c_addr;
1202 row[2] = reg; 1038 row[2] = reg;
1203 row[3] = val >> 8; 1039 row[3] = val >> 8;
@@ -1210,7 +1046,7 @@ static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1210} 1046}
1211 1047
1212static void i2c_w2_buf(struct gspca_dev *gspca_dev, 1048static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1213 struct i2c_reg_u16 *buf, int sz) 1049 const struct i2c_reg_u16 *buf, int sz)
1214{ 1050{
1215 while (--sz >= 0) { 1051 while (--sz >= 0) {
1216 i2c_w2(gspca_dev, buf->reg, buf->val); 1052 i2c_w2(gspca_dev, buf->reg, buf->val);
@@ -1223,7 +1059,7 @@ static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1223 struct sd *sd = (struct sd *) gspca_dev; 1059 struct sd *sd = (struct sd *) gspca_dev;
1224 u8 row[8]; 1060 u8 row[8];
1225 1061
1226 row[0] = 0x81 | (1 << 4); 1062 row[0] = sd->i2c_intf | (1 << 4);
1227 row[1] = sd->i2c_addr; 1063 row[1] = sd->i2c_addr;
1228 row[2] = reg; 1064 row[2] = reg;
1229 row[3] = 0; 1065 row[3] = 0;
@@ -1232,7 +1068,7 @@ static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1232 row[6] = 0; 1068 row[6] = 0;
1233 row[7] = 0x10; 1069 row[7] = 0x10;
1234 i2c_w(gspca_dev, row); 1070 i2c_w(gspca_dev, row);
1235 row[0] = 0x81 | (1 << 4) | 0x02; 1071 row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1236 row[2] = 0; 1072 row[2] = 0;
1237 i2c_w(gspca_dev, row); 1073 i2c_w(gspca_dev, row);
1238 reg_r(gspca_dev, 0x10c2, 5); 1074 reg_r(gspca_dev, 0x10c2, 5);
@@ -1244,7 +1080,7 @@ static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1244 struct sd *sd = (struct sd *) gspca_dev; 1080 struct sd *sd = (struct sd *) gspca_dev;
1245 u8 row[8]; 1081 u8 row[8];
1246 1082
1247 row[0] = 0x81 | (1 << 4); 1083 row[0] = sd->i2c_intf | (1 << 4);
1248 row[1] = sd->i2c_addr; 1084 row[1] = sd->i2c_addr;
1249 row[2] = reg; 1085 row[2] = reg;
1250 row[3] = 0; 1086 row[3] = 0;
@@ -1253,7 +1089,7 @@ static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1253 row[6] = 0; 1089 row[6] = 0;
1254 row[7] = 0x10; 1090 row[7] = 0x10;
1255 i2c_w(gspca_dev, row); 1091 i2c_w(gspca_dev, row);
1256 row[0] = 0x81 | (2 << 4) | 0x02; 1092 row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1257 row[2] = 0; 1093 row[2] = 0;
1258 i2c_w(gspca_dev, row); 1094 i2c_w(gspca_dev, row);
1259 reg_r(gspca_dev, 0x10c2, 5); 1095 reg_r(gspca_dev, 0x10c2, 5);
@@ -1294,8 +1130,6 @@ static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1294 if (gspca_dev->usb_err < 0) 1130 if (gspca_dev->usb_err < 0)
1295 pr_err("OV9655 sensor initialization failed\n"); 1131 pr_err("OV9655 sensor initialization failed\n");
1296 1132
1297 /* disable hflip and vflip */
1298 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1299 sd->hstart = 1; 1133 sd->hstart = 1;
1300 sd->vstart = 2; 1134 sd->vstart = 2;
1301} 1135}
@@ -1310,9 +1144,6 @@ static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1310 if (gspca_dev->usb_err < 0) 1144 if (gspca_dev->usb_err < 0)
1311 pr_err("SOI968 sensor initialization failed\n"); 1145 pr_err("SOI968 sensor initialization failed\n");
1312 1146
1313 /* disable hflip and vflip */
1314 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
1315 | (1 << EXPOSURE);
1316 sd->hstart = 60; 1147 sd->hstart = 60;
1317 sd->vstart = 11; 1148 sd->vstart = 11;
1318} 1149}
@@ -1340,8 +1171,6 @@ static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1340 if (gspca_dev->usb_err < 0) 1171 if (gspca_dev->usb_err < 0)
1341 pr_err("OV7670 sensor initialization failed\n"); 1172 pr_err("OV7670 sensor initialization failed\n");
1342 1173
1343 /* disable hflip and vflip */
1344 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1345 sd->hstart = 0; 1174 sd->hstart = 0;
1346 sd->vstart = 1; 1175 sd->vstart = 1;
1347} 1176}
@@ -1378,9 +1207,6 @@ static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1378 pr_err("MT9V111 sensor initialization failed\n"); 1207 pr_err("MT9V111 sensor initialization failed\n");
1379 return; 1208 return;
1380 } 1209 }
1381 gspca_dev->ctrl_dis = (1 << EXPOSURE)
1382 | (1 << AUTOGAIN)
1383 | (1 << GAIN);
1384 sd->hstart = 2; 1210 sd->hstart = 2;
1385 sd->vstart = 2; 1211 sd->vstart = 2;
1386 sd->sensor = SENSOR_MT9V111; 1212 sd->sensor = SENSOR_MT9V111;
@@ -1422,8 +1248,6 @@ static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1422 if (gspca_dev->usb_err < 0) 1248 if (gspca_dev->usb_err < 0)
1423 pr_err("MT9M112 sensor initialization failed\n"); 1249 pr_err("MT9M112 sensor initialization failed\n");
1424 1250
1425 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1426 | (1 << GAIN);
1427 sd->hstart = 0; 1251 sd->hstart = 0;
1428 sd->vstart = 2; 1252 sd->vstart = 2;
1429} 1253}
@@ -1436,8 +1260,6 @@ static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1436 if (gspca_dev->usb_err < 0) 1260 if (gspca_dev->usb_err < 0)
1437 pr_err("MT9M111 sensor initialization failed\n"); 1261 pr_err("MT9M111 sensor initialization failed\n");
1438 1262
1439 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1440 | (1 << GAIN);
1441 sd->hstart = 0; 1263 sd->hstart = 0;
1442 sd->vstart = 2; 1264 sd->vstart = 2;
1443} 1265}
@@ -1470,8 +1292,6 @@ static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1470 if (gspca_dev->usb_err < 0) 1292 if (gspca_dev->usb_err < 0)
1471 pr_err("MT9M001 sensor initialization failed\n"); 1293 pr_err("MT9M001 sensor initialization failed\n");
1472 1294
1473 /* disable hflip and vflip */
1474 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1475 sd->hstart = 1; 1295 sd->hstart = 1;
1476 sd->vstart = 1; 1296 sd->vstart = 1;
1477} 1297}
@@ -1488,20 +1308,18 @@ static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1488 sd->vstart = 1; 1308 sd->vstart = 1;
1489} 1309}
1490 1310
1491static void set_cmatrix(struct gspca_dev *gspca_dev) 1311static void set_cmatrix(struct gspca_dev *gspca_dev,
1312 s32 brightness, s32 contrast, s32 satur, s32 hue)
1492{ 1313{
1493 struct sd *sd = (struct sd *) gspca_dev; 1314 s32 hue_coord, hue_index = 180 + hue;
1494 int satur;
1495 s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1496 u8 cmatrix[21]; 1315 u8 cmatrix[21];
1497 1316
1498 memset(cmatrix, 0, sizeof cmatrix); 1317 memset(cmatrix, 0, sizeof cmatrix);
1499 cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26; 1318 cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1500 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1319 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1501 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1320 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1502 cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80; 1321 cmatrix[18] = brightness - 0x80;
1503 1322
1504 satur = sd->ctrls[SATURATION].val;
1505 hue_coord = (hsv_red_x[hue_index] * satur) >> 8; 1323 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1506 cmatrix[6] = hue_coord; 1324 cmatrix[6] = hue_coord;
1507 cmatrix[7] = (hue_coord >> 8) & 0x0f; 1325 cmatrix[7] = (hue_coord >> 8) & 0x0f;
@@ -1529,11 +1347,10 @@ static void set_cmatrix(struct gspca_dev *gspca_dev)
1529 reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1347 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1530} 1348}
1531 1349
1532static void set_gamma(struct gspca_dev *gspca_dev) 1350static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1533{ 1351{
1534 struct sd *sd = (struct sd *) gspca_dev;
1535 u8 gamma[17]; 1352 u8 gamma[17];
1536 u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100; 1353 u8 gval = val * 0xb8 / 0x100;
1537 1354
1538 gamma[0] = 0x0a; 1355 gamma[0] = 0x0a;
1539 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); 1356 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
@@ -1556,26 +1373,21 @@ static void set_gamma(struct gspca_dev *gspca_dev)
1556 reg_w(gspca_dev, 0x1190, gamma, 17); 1373 reg_w(gspca_dev, 0x1190, gamma, 17);
1557} 1374}
1558 1375
1559static void set_redblue(struct gspca_dev *gspca_dev) 1376static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1560{ 1377{
1561 struct sd *sd = (struct sd *) gspca_dev; 1378 reg_w1(gspca_dev, 0x118c, red);
1562 1379 reg_w1(gspca_dev, 0x118f, blue);
1563 reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
1564 reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1565} 1380}
1566 1381
1567static void set_hvflip(struct gspca_dev *gspca_dev) 1382static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1568{ 1383{
1569 u8 value, tslb, hflip, vflip; 1384 u8 value, tslb;
1570 u16 value2; 1385 u16 value2;
1571 struct sd *sd = (struct sd *) gspca_dev; 1386 struct sd *sd = (struct sd *) gspca_dev;
1572 1387
1573 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { 1388 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1574 hflip = !sd->ctrls[HFLIP].val; 1389 hflip = !hflip;
1575 vflip = !sd->ctrls[VFLIP].val; 1390 vflip = !vflip;
1576 } else {
1577 hflip = sd->ctrls[HFLIP].val;
1578 vflip = sd->ctrls[VFLIP].val;
1579 } 1391 }
1580 1392
1581 switch (sd->sensor) { 1393 switch (sd->sensor) {
@@ -1638,20 +1450,38 @@ static void set_hvflip(struct gspca_dev *gspca_dev)
1638 } 1450 }
1639} 1451}
1640 1452
1641static void set_exposure(struct gspca_dev *gspca_dev) 1453static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1642{ 1454{
1643 struct sd *sd = (struct sd *) gspca_dev; 1455 struct sd *sd = (struct sd *) gspca_dev;
1644 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; 1456 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1645 int expo; 1457 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1458 int expo2;
1459
1460 if (gspca_dev->streaming)
1461 exp[7] = 0x1e;
1646 1462
1647 expo = sd->ctrls[EXPOSURE].val;
1648 switch (sd->sensor) { 1463 switch (sd->sensor) {
1649 case SENSOR_OV7660: 1464 case SENSOR_OV7660:
1650 case SENSOR_OV7670: 1465 case SENSOR_OV7670:
1651 case SENSOR_OV9655: 1466 case SENSOR_OV9655:
1652 case SENSOR_OV9650: 1467 case SENSOR_OV9650:
1468 if (expo > 547)
1469 expo2 = 547;
1470 else
1471 expo2 = expo;
1472 exp[0] |= (2 << 4);
1473 exp[2] = 0x10; /* AECH */
1474 exp[3] = expo2 >> 2;
1475 exp[7] = 0x10;
1476 i2c_w(gspca_dev, exp);
1477 exp[2] = 0x04; /* COM1 */
1478 exp[3] = expo2 & 0x0003;
1479 exp[7] = 0x10;
1480 i2c_w(gspca_dev, exp);
1481 expo -= expo2;
1482 exp[7] = 0x1e;
1653 exp[0] |= (3 << 4); 1483 exp[0] |= (3 << 4);
1654 exp[2] = 0x2d; 1484 exp[2] = 0x2d; /* ADVFL & ADVFH */
1655 exp[3] = expo; 1485 exp[3] = expo;
1656 exp[4] = expo >> 8; 1486 exp[4] = expo >> 8;
1657 break; 1487 break;
@@ -1676,13 +1506,15 @@ static void set_exposure(struct gspca_dev *gspca_dev)
1676 i2c_w(gspca_dev, exp); 1506 i2c_w(gspca_dev, exp);
1677} 1507}
1678 1508
1679static void set_gain(struct gspca_dev *gspca_dev) 1509static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1680{ 1510{
1681 struct sd *sd = (struct sd *) gspca_dev; 1511 struct sd *sd = (struct sd *) gspca_dev;
1682 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; 1512 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1683 int g; 1513 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1514
1515 if (gspca_dev->streaming)
1516 gain[7] = 0x15; /* or 1d ? */
1684 1517
1685 g = sd->ctrls[GAIN].val;
1686 switch (sd->sensor) { 1518 switch (sd->sensor) {
1687 case SENSOR_OV7660: 1519 case SENSOR_OV7660:
1688 case SENSOR_OV7670: 1520 case SENSOR_OV7670:
@@ -1721,11 +1553,11 @@ static void set_gain(struct gspca_dev *gspca_dev)
1721 i2c_w(gspca_dev, gain); 1553 i2c_w(gspca_dev, gain);
1722} 1554}
1723 1555
1724static void set_quality(struct gspca_dev *gspca_dev) 1556static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1725{ 1557{
1726 struct sd *sd = (struct sd *) gspca_dev; 1558 struct sd *sd = (struct sd *) gspca_dev;
1727 1559
1728 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); 1560 jpeg_set_qual(sd->jpeg_hdr, val);
1729 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */ 1561 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1730 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */ 1562 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1731 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); 1563 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
@@ -1827,6 +1659,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1827 sd->sensor = id->driver_info >> 8; 1659 sd->sensor = id->driver_info >> 8;
1828 sd->i2c_addr = id->driver_info; 1660 sd->i2c_addr = id->driver_info;
1829 sd->flags = id->driver_info >> 16; 1661 sd->flags = id->driver_info >> 16;
1662 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
1830 1663
1831 switch (sd->sensor) { 1664 switch (sd->sensor) {
1832 case SENSOR_MT9M112: 1665 case SENSOR_MT9M112:
@@ -1840,6 +1673,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
1840 cam->cam_mode = mono_mode; 1673 cam->cam_mode = mono_mode;
1841 cam->nmodes = ARRAY_SIZE(mono_mode); 1674 cam->nmodes = ARRAY_SIZE(mono_mode);
1842 break; 1675 break;
1676 case SENSOR_HV7131R:
1677 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
1678 /* fall thru */
1843 default: 1679 default:
1844 cam->cam_mode = vga_mode; 1680 cam->cam_mode = vga_mode;
1845 cam->nmodes = ARRAY_SIZE(vga_mode); 1681 cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1850,13 +1686,133 @@ static int sd_config(struct gspca_dev *gspca_dev,
1850 sd->older_step = 0; 1686 sd->older_step = 0;
1851 sd->exposure_step = 16; 1687 sd->exposure_step = 16;
1852 1688
1853 gspca_dev->cam.ctrls = sd->ctrls;
1854
1855 INIT_WORK(&sd->work, qual_upd); 1689 INIT_WORK(&sd->work, qual_upd);
1856 1690
1857 return 0; 1691 return 0;
1858} 1692}
1859 1693
1694static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1695{
1696 struct gspca_dev *gspca_dev =
1697 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1698 struct sd *sd = (struct sd *)gspca_dev;
1699
1700 gspca_dev->usb_err = 0;
1701
1702 if (!gspca_dev->streaming)
1703 return 0;
1704
1705 switch (ctrl->id) {
1706 /* color control cluster */
1707 case V4L2_CID_BRIGHTNESS:
1708 set_cmatrix(gspca_dev, sd->brightness->val,
1709 sd->contrast->val, sd->saturation->val, sd->hue->val);
1710 break;
1711 case V4L2_CID_GAMMA:
1712 set_gamma(gspca_dev, ctrl->val);
1713 break;
1714 /* blue/red balance cluster */
1715 case V4L2_CID_BLUE_BALANCE:
1716 set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1717 break;
1718 /* h/vflip cluster */
1719 case V4L2_CID_HFLIP:
1720 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1721 break;
1722 /* standalone exposure control */
1723 case V4L2_CID_EXPOSURE:
1724 set_exposure(gspca_dev, ctrl->val);
1725 break;
1726 /* standalone gain control */
1727 case V4L2_CID_GAIN:
1728 set_gain(gspca_dev, ctrl->val);
1729 break;
1730 /* autogain + exposure or gain control cluster */
1731 case V4L2_CID_AUTOGAIN:
1732 if (sd->sensor == SENSOR_SOI968)
1733 set_gain(gspca_dev, sd->gain->val);
1734 else
1735 set_exposure(gspca_dev, sd->exposure->val);
1736 break;
1737 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1738 set_quality(gspca_dev, ctrl->val);
1739 break;
1740 }
1741 return gspca_dev->usb_err;
1742}
1743
1744static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1745 .s_ctrl = sd_s_ctrl,
1746};
1747
1748static int sd_init_controls(struct gspca_dev *gspca_dev)
1749{
1750 struct sd *sd = (struct sd *) gspca_dev;
1751 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1752
1753 gspca_dev->vdev.ctrl_handler = hdl;
1754 v4l2_ctrl_handler_init(hdl, 13);
1755
1756 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1757 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1758 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1759 V4L2_CID_CONTRAST, 0, 255, 1, 127);
1760 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1761 V4L2_CID_SATURATION, 0, 255, 1, 127);
1762 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1763 V4L2_CID_HUE, -180, 180, 1, 0);
1764 v4l2_ctrl_cluster(4, &sd->brightness);
1765
1766 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767 V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1768
1769 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1770 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1771 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1772 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1773 v4l2_ctrl_cluster(2, &sd->blue);
1774
1775 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1776 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1777 sd->sensor != SENSOR_MT9VPRB) {
1778 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1779 V4L2_CID_HFLIP, 0, 1, 1, 0);
1780 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1781 V4L2_CID_VFLIP, 0, 1, 1, 0);
1782 v4l2_ctrl_cluster(2, &sd->hflip);
1783 }
1784
1785 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1786 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1787 sd->sensor != SENSOR_MT9V111)
1788 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1789 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1790
1791 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1792 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1793 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1794 V4L2_CID_GAIN, 0, 28, 1, 0);
1795 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1796 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1797 if (sd->sensor == SENSOR_SOI968)
1798 /* this sensor doesn't have the exposure control and
1799 autogain is clustered with gain instead. This works
1800 because sd->exposure == NULL. */
1801 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1802 else
1803 /* Otherwise autogain is clustered with exposure. */
1804 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1805 }
1806
1807 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1808 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1809 if (hdl->error) {
1810 pr_err("Could not initialize controls\n");
1811 return hdl->error;
1812 }
1813 return 0;
1814}
1815
1860static int sd_init(struct gspca_dev *gspca_dev) 1816static int sd_init(struct gspca_dev *gspca_dev)
1861{ 1817{
1862 struct sd *sd = (struct sd *) gspca_dev; 1818 struct sd *sd = (struct sd *) gspca_dev;
@@ -1949,7 +1905,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
1949 pr_err("Unsupported sensor\n"); 1905 pr_err("Unsupported sensor\n");
1950 gspca_dev->usb_err = -ENODEV; 1906 gspca_dev->usb_err = -ENODEV;
1951 } 1907 }
1952
1953 return gspca_dev->usb_err; 1908 return gspca_dev->usb_err;
1954} 1909}
1955 1910
@@ -2025,8 +1980,8 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev)
2025 1980
2026 if (intf->num_altsetting != 9) { 1981 if (intf->num_altsetting != 9) {
2027 pr_warn("sn9c20x camera with unknown number of alt " 1982 pr_warn("sn9c20x camera with unknown number of alt "
2028 "settings (%d), please report!\n", 1983 "settings (%d), please report!\n",
2029 intf->num_altsetting); 1984 intf->num_altsetting);
2030 gspca_dev->alt = intf->num_altsetting; 1985 gspca_dev->alt = intf->num_altsetting;
2031 return 0; 1986 return 0;
2032 } 1987 }
@@ -2067,7 +2022,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2067 2022
2068 jpeg_define(sd->jpeg_hdr, height, width, 2023 jpeg_define(sd->jpeg_hdr, height, width,
2069 0x21); 2024 0x21);
2070 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); 2025 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2071 2026
2072 if (mode & MODE_RAW) 2027 if (mode & MODE_RAW)
2073 fmt = 0x2d; 2028 fmt = 0x2d;
@@ -2104,12 +2059,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
2104 reg_w1(gspca_dev, 0x1189, scale); 2059 reg_w1(gspca_dev, 0x1189, scale);
2105 reg_w1(gspca_dev, 0x10e0, fmt); 2060 reg_w1(gspca_dev, 0x10e0, fmt);
2106 2061
2107 set_cmatrix(gspca_dev); 2062 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2108 set_gamma(gspca_dev); 2063 v4l2_ctrl_g_ctrl(sd->contrast),
2109 set_redblue(gspca_dev); 2064 v4l2_ctrl_g_ctrl(sd->saturation),
2110 set_gain(gspca_dev); 2065 v4l2_ctrl_g_ctrl(sd->hue));
2111 set_exposure(gspca_dev); 2066 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2112 set_hvflip(gspca_dev); 2067 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2068 v4l2_ctrl_g_ctrl(sd->red));
2069 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2070 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2071 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2072 v4l2_ctrl_g_ctrl(sd->vflip));
2113 2073
2114 reg_w1(gspca_dev, 0x1007, 0x20); 2074 reg_w1(gspca_dev, 0x1007, 0x20);
2115 reg_w1(gspca_dev, 0x1061, 0x03); 2075 reg_w1(gspca_dev, 0x1061, 0x03);
@@ -2148,6 +2108,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2148static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) 2108static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2149{ 2109{
2150 struct sd *sd = (struct sd *) gspca_dev; 2110 struct sd *sd = (struct sd *) gspca_dev;
2111 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2112 s32 max = sd->exposure->maximum - sd->exposure_step;
2113 s32 min = sd->exposure->minimum + sd->exposure_step;
2151 s16 new_exp; 2114 s16 new_exp;
2152 2115
2153 /* 2116 /*
@@ -2156,16 +2119,15 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2156 * and exposure steps 2119 * and exposure steps
2157 */ 2120 */
2158 if (avg_lum < MIN_AVG_LUM) { 2121 if (avg_lum < MIN_AVG_LUM) {
2159 if (sd->ctrls[EXPOSURE].val > 0x1770) 2122 if (cur_exp > max)
2160 return; 2123 return;
2161 2124
2162 new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step; 2125 new_exp = cur_exp + sd->exposure_step;
2163 if (new_exp > 0x1770) 2126 if (new_exp > max)
2164 new_exp = 0x1770; 2127 new_exp = max;
2165 if (new_exp < 0x10) 2128 if (new_exp < min)
2166 new_exp = 0x10; 2129 new_exp = min;
2167 sd->ctrls[EXPOSURE].val = new_exp; 2130 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2168 set_exposure(gspca_dev);
2169 2131
2170 sd->older_step = sd->old_step; 2132 sd->older_step = sd->old_step;
2171 sd->old_step = 1; 2133 sd->old_step = 1;
@@ -2176,15 +2138,14 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2176 sd->exposure_step += 2; 2138 sd->exposure_step += 2;
2177 } 2139 }
2178 if (avg_lum > MAX_AVG_LUM) { 2140 if (avg_lum > MAX_AVG_LUM) {
2179 if (sd->ctrls[EXPOSURE].val < 0x10) 2141 if (cur_exp < min)
2180 return; 2142 return;
2181 new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step; 2143 new_exp = cur_exp - sd->exposure_step;
2182 if (new_exp > 0x1700) 2144 if (new_exp > max)
2183 new_exp = 0x1770; 2145 new_exp = max;
2184 if (new_exp < 0x10) 2146 if (new_exp < min)
2185 new_exp = 0x10; 2147 new_exp = min;
2186 sd->ctrls[EXPOSURE].val = new_exp; 2148 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2187 set_exposure(gspca_dev);
2188 sd->older_step = sd->old_step; 2149 sd->older_step = sd->old_step;
2189 sd->old_step = 0; 2150 sd->old_step = 0;
2190 2151
@@ -2198,19 +2159,12 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2198static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum) 2159static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2199{ 2160{
2200 struct sd *sd = (struct sd *) gspca_dev; 2161 struct sd *sd = (struct sd *) gspca_dev;
2162 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2201 2163
2202 if (avg_lum < MIN_AVG_LUM) { 2164 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2203 if (sd->ctrls[GAIN].val + 1 <= 28) { 2165 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2204 sd->ctrls[GAIN].val++; 2166 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2205 set_gain(gspca_dev); 2167 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2206 }
2207 }
2208 if (avg_lum > MAX_AVG_LUM) {
2209 if (sd->ctrls[GAIN].val > 0) {
2210 sd->ctrls[GAIN].val--;
2211 set_gain(gspca_dev);
2212 }
2213 }
2214} 2168}
2215 2169
2216static void sd_dqcallback(struct gspca_dev *gspca_dev) 2170static void sd_dqcallback(struct gspca_dev *gspca_dev)
@@ -2218,7 +2172,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2218 struct sd *sd = (struct sd *) gspca_dev; 2172 struct sd *sd = (struct sd *) gspca_dev;
2219 int avg_lum; 2173 int avg_lum;
2220 2174
2221 if (!sd->ctrls[AUTOGAIN].val) 2175 if (!v4l2_ctrl_g_ctrl(sd->autogain))
2222 return; 2176 return;
2223 2177
2224 avg_lum = atomic_read(&sd->avg_lum); 2178 avg_lum = atomic_read(&sd->avg_lum);
@@ -2234,10 +2188,11 @@ static void qual_upd(struct work_struct *work)
2234{ 2188{
2235 struct sd *sd = container_of(work, struct sd, work); 2189 struct sd *sd = container_of(work, struct sd, work);
2236 struct gspca_dev *gspca_dev = &sd->gspca_dev; 2190 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2191 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2237 2192
2238 mutex_lock(&gspca_dev->usb_lock); 2193 mutex_lock(&gspca_dev->usb_lock);
2239 PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val); 2194 PDEBUG(D_STREAM, "qual_upd %d%%", qual);
2240 set_quality(gspca_dev); 2195 set_quality(gspca_dev, qual);
2241 mutex_unlock(&gspca_dev->usb_lock); 2196 mutex_unlock(&gspca_dev->usb_lock);
2242} 2197}
2243 2198
@@ -2286,14 +2241,18 @@ static void transfer_check(struct gspca_dev *gspca_dev,
2286 if (new_qual != 0) { 2241 if (new_qual != 0) {
2287 sd->nchg += new_qual; 2242 sd->nchg += new_qual;
2288 if (sd->nchg < -6 || sd->nchg >= 12) { 2243 if (sd->nchg < -6 || sd->nchg >= 12) {
2244 /* Note: we are in interrupt context, so we can't
2245 use v4l2_ctrl_g/s_ctrl here. Access the value
2246 directly instead. */
2247 s32 curqual = sd->jpegqual->cur.val;
2289 sd->nchg = 0; 2248 sd->nchg = 0;
2290 new_qual += sd->ctrls[QUALITY].val; 2249 new_qual += curqual;
2291 if (new_qual < QUALITY_MIN) 2250 if (new_qual < sd->jpegqual->minimum)
2292 new_qual = QUALITY_MIN; 2251 new_qual = sd->jpegqual->minimum;
2293 else if (new_qual > QUALITY_MAX) 2252 else if (new_qual > sd->jpegqual->maximum)
2294 new_qual = QUALITY_MAX; 2253 new_qual = sd->jpegqual->maximum;
2295 if (new_qual != sd->ctrls[QUALITY].val) { 2254 if (new_qual != curqual) {
2296 sd->ctrls[QUALITY].val = new_qual; 2255 sd->jpegqual->cur.val = new_qual;
2297 queue_work(sd->work_thread, &sd->work); 2256 queue_work(sd->work_thread, &sd->work);
2298 } 2257 }
2299 } 2258 }
@@ -2309,7 +2268,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2309{ 2268{
2310 struct sd *sd = (struct sd *) gspca_dev; 2269 struct sd *sd = (struct sd *) gspca_dev;
2311 int avg_lum, is_jpeg; 2270 int avg_lum, is_jpeg;
2312 static u8 frame_header[] = 2271 static const u8 frame_header[] =
2313 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 2272 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2314 2273
2315 is_jpeg = (sd->fmt & 0x03) == 0; 2274 is_jpeg = (sd->fmt & 0x03) == 0;
@@ -2373,10 +2332,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2373/* sub-driver description */ 2332/* sub-driver description */
2374static const struct sd_desc sd_desc = { 2333static const struct sd_desc sd_desc = {
2375 .name = KBUILD_MODNAME, 2334 .name = KBUILD_MODNAME,
2376 .ctrls = sd_ctrls,
2377 .nctrls = ARRAY_SIZE(sd_ctrls),
2378 .config = sd_config, 2335 .config = sd_config,
2379 .init = sd_init, 2336 .init = sd_init,
2337 .init_controls = sd_init_controls,
2380 .isoc_init = sd_isoc_init, 2338 .isoc_init = sd_isoc_init,
2381 .start = sd_start, 2339 .start = sd_start,
2382 .stopN = sd_stopN, 2340 .stopN = sd_stopN,
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 6a1148d7fe92..e2bdf8f632f4 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1000,6 +1000,8 @@ static void setfreq(struct gspca_dev *gspca_dev)
1000 } 1000 }
1001} 1001}
1002 1002
1003#define WANT_REGULAR_AUTOGAIN
1004#define WANT_COARSE_EXPO_AUTOGAIN
1003#include "autogain_functions.h" 1005#include "autogain_functions.h"
1004 1006
1005static void do_autogain(struct gspca_dev *gspca_dev) 1007static void do_autogain(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 863c755dd2b7..4d1696d1a7f4 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -2800,10 +2800,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2800 } 2800 }
2801} 2801}
2802 2802
2803/* !! coarse_grained_expo_autogain is not used !! */ 2803#define WANT_REGULAR_AUTOGAIN
2804#define exp_too_low_cnt bridge
2805#define exp_too_high_cnt sensor
2806
2807#include "autogain_functions.h" 2804#include "autogain_functions.h"
2808 2805
2809static void do_autogain(struct gspca_dev *gspca_dev) 2806static void do_autogain(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 2fe3c29bd6b7..04f54654a026 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -232,7 +232,11 @@ static void sq905_dostream(struct work_struct *work)
232 frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage 232 frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
233 + FRAME_HEADER_LEN; 233 + FRAME_HEADER_LEN;
234 234
235 while (gspca_dev->present && gspca_dev->streaming) { 235 while (gspca_dev->dev && gspca_dev->streaming) {
236#ifdef CONFIG_PM
237 if (gspca_dev->frozen)
238 break;
239#endif
236 /* request some data and then read it until we have 240 /* request some data and then read it until we have
237 * a complete frame. */ 241 * a complete frame. */
238 bytes_left = frame_sz; 242 bytes_left = frame_sz;
@@ -242,7 +246,7 @@ static void sq905_dostream(struct work_struct *work)
242 we must finish reading an entire frame, otherwise the 246 we must finish reading an entire frame, otherwise the
243 next time we stream we start reading in the middle of a 247 next time we stream we start reading in the middle of a
244 frame. */ 248 frame. */
245 while (bytes_left > 0 && gspca_dev->present) { 249 while (bytes_left > 0 && gspca_dev->dev) {
246 data_len = bytes_left > SQ905_MAX_TRANSFER ? 250 data_len = bytes_left > SQ905_MAX_TRANSFER ?
247 SQ905_MAX_TRANSFER : bytes_left; 251 SQ905_MAX_TRANSFER : bytes_left;
248 ret = sq905_read_data(gspca_dev, buffer, data_len, 1); 252 ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
@@ -274,7 +278,7 @@ static void sq905_dostream(struct work_struct *work)
274 gspca_frame_add(gspca_dev, LAST_PACKET, 278 gspca_frame_add(gspca_dev, LAST_PACKET,
275 NULL, 0); 279 NULL, 0);
276 } 280 }
277 if (gspca_dev->present) { 281 if (gspca_dev->dev) {
278 /* acknowledge the frame */ 282 /* acknowledge the frame */
279 mutex_lock(&gspca_dev->usb_lock); 283 mutex_lock(&gspca_dev->usb_lock);
280 ret = sq905_ack_frame(gspca_dev); 284 ret = sq905_ack_frame(gspca_dev);
@@ -284,7 +288,7 @@ static void sq905_dostream(struct work_struct *work)
284 } 288 }
285 } 289 }
286quit_stream: 290quit_stream:
287 if (gspca_dev->present) { 291 if (gspca_dev->dev) {
288 mutex_lock(&gspca_dev->usb_lock); 292 mutex_lock(&gspca_dev->usb_lock);
289 sq905_command(gspca_dev, SQ905_CLEAR); 293 sq905_command(gspca_dev, SQ905_CLEAR);
290 mutex_unlock(&gspca_dev->usb_lock); 294 mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
index ae783634712f..f34ddb0570c8 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/video/gspca/sq905c.c
@@ -150,7 +150,11 @@ static void sq905c_dostream(struct work_struct *work)
150 goto quit_stream; 150 goto quit_stream;
151 } 151 }
152 152
153 while (gspca_dev->present && gspca_dev->streaming) { 153 while (gspca_dev->dev && gspca_dev->streaming) {
154#ifdef CONFIG_PM
155 if (gspca_dev->frozen)
156 break;
157#endif
154 /* Request the header, which tells the size to download */ 158 /* Request the header, which tells the size to download */
155 ret = usb_bulk_msg(gspca_dev->dev, 159 ret = usb_bulk_msg(gspca_dev->dev,
156 usb_rcvbulkpipe(gspca_dev->dev, 0x81), 160 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
@@ -169,7 +173,7 @@ static void sq905c_dostream(struct work_struct *work)
169 packet_type = FIRST_PACKET; 173 packet_type = FIRST_PACKET;
170 gspca_frame_add(gspca_dev, packet_type, 174 gspca_frame_add(gspca_dev, packet_type,
171 buffer, FRAME_HEADER_LEN); 175 buffer, FRAME_HEADER_LEN);
172 while (bytes_left > 0 && gspca_dev->present) { 176 while (bytes_left > 0 && gspca_dev->dev) {
173 data_len = bytes_left > SQ905C_MAX_TRANSFER ? 177 data_len = bytes_left > SQ905C_MAX_TRANSFER ?
174 SQ905C_MAX_TRANSFER : bytes_left; 178 SQ905C_MAX_TRANSFER : bytes_left;
175 ret = usb_bulk_msg(gspca_dev->dev, 179 ret = usb_bulk_msg(gspca_dev->dev,
@@ -191,7 +195,7 @@ static void sq905c_dostream(struct work_struct *work)
191 } 195 }
192 } 196 }
193quit_stream: 197quit_stream:
194 if (gspca_dev->present) { 198 if (gspca_dev->dev) {
195 mutex_lock(&gspca_dev->usb_lock); 199 mutex_lock(&gspca_dev->usb_lock);
196 sq905c_command(gspca_dev, SQ905C_CLEAR, 0); 200 sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
197 mutex_unlock(&gspca_dev->usb_lock); 201 mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 91d99b4cc57b..999ec7764449 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -261,6 +261,17 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
261 return (err < 0) ? err : 0; 261 return (err < 0) ? err : 0;
262} 262}
263 263
264/* this function is called at probe time */
265static int stv06xx_init_controls(struct gspca_dev *gspca_dev)
266{
267 struct sd *sd = (struct sd *) gspca_dev;
268
269 PDEBUG(D_PROBE, "Initializing controls");
270
271 gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler;
272 return sd->sensor->init_controls(sd);
273}
274
264/* Start the camera */ 275/* Start the camera */
265static int stv06xx_start(struct gspca_dev *gspca_dev) 276static int stv06xx_start(struct gspca_dev *gspca_dev)
266{ 277{
@@ -512,6 +523,7 @@ static const struct sd_desc sd_desc = {
512 .name = MODULE_NAME, 523 .name = MODULE_NAME,
513 .config = stv06xx_config, 524 .config = stv06xx_config,
514 .init = stv06xx_init, 525 .init = stv06xx_init,
526 .init_controls = stv06xx_init_controls,
515 .start = stv06xx_start, 527 .start = stv06xx_start,
516 .stopN = stv06xx_stopN, 528 .stopN = stv06xx_stopN,
517 .pkt_scan = stv06xx_pkt_scan, 529 .pkt_scan = stv06xx_pkt_scan,
@@ -530,9 +542,8 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
530 542
531 PDEBUG(D_PROBE, "Configuring camera"); 543 PDEBUG(D_PROBE, "Configuring camera");
532 544
533 sd->desc = sd_desc;
534 sd->bridge = id->driver_info; 545 sd->bridge = id->driver_info;
535 gspca_dev->sd_desc = &sd->desc; 546 gspca_dev->sd_desc = &sd_desc;
536 547
537 if (dump_bridge) 548 if (dump_bridge)
538 stv06xx_dump_bridge(sd); 549 stv06xx_dump_bridge(sd);
@@ -594,11 +605,12 @@ static void sd_disconnect(struct usb_interface *intf)
594{ 605{
595 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 606 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
596 struct sd *sd = (struct sd *) gspca_dev; 607 struct sd *sd = (struct sd *) gspca_dev;
608 void *priv = sd->sensor_priv;
597 PDEBUG(D_PROBE, "Disconnecting the stv06xx device"); 609 PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
598 610
599 if (sd->sensor->disconnect) 611 sd->sensor = NULL;
600 sd->sensor->disconnect(sd);
601 gspca_disconnect(intf); 612 gspca_disconnect(intf);
613 kfree(priv);
602} 614}
603 615
604static struct usb_driver sd_driver = { 616static struct usb_driver sd_driver = {
@@ -609,6 +621,7 @@ static struct usb_driver sd_driver = {
609#ifdef CONFIG_PM 621#ifdef CONFIG_PM
610 .suspend = gspca_suspend, 622 .suspend = gspca_suspend,
611 .resume = gspca_resume, 623 .resume = gspca_resume,
624 .reset_resume = gspca_resume,
612#endif 625#endif
613}; 626};
614 627
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
index d270a5981afe..34957a4ec150 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -89,9 +89,6 @@ struct sd {
89 /* A pointer to the currently connected sensor */ 89 /* A pointer to the currently connected sensor */
90 const struct stv06xx_sensor *sensor; 90 const struct stv06xx_sensor *sensor;
91 91
92 /* A pointer to the sd_desc struct */
93 struct sd_desc desc;
94
95 /* Sensor private data */ 92 /* Sensor private data */
96 void *sensor_priv; 93 void *sensor_priv;
97 94
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index a8698b7a7566..06fa54c5efb2 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -32,36 +32,6 @@
32 32
33#include "stv06xx_hdcs.h" 33#include "stv06xx_hdcs.h"
34 34
35static const struct ctrl hdcs1x00_ctrl[] = {
36 {
37 {
38 .id = V4L2_CID_EXPOSURE,
39 .type = V4L2_CTRL_TYPE_INTEGER,
40 .name = "exposure",
41 .minimum = 0x00,
42 .maximum = 0xff,
43 .step = 0x1,
44 .default_value = HDCS_DEFAULT_EXPOSURE,
45 .flags = V4L2_CTRL_FLAG_SLIDER
46 },
47 .set = hdcs_set_exposure,
48 .get = hdcs_get_exposure
49 }, {
50 {
51 .id = V4L2_CID_GAIN,
52 .type = V4L2_CTRL_TYPE_INTEGER,
53 .name = "gain",
54 .minimum = 0x00,
55 .maximum = 0xff,
56 .step = 0x1,
57 .default_value = HDCS_DEFAULT_GAIN,
58 .flags = V4L2_CTRL_FLAG_SLIDER
59 },
60 .set = hdcs_set_gain,
61 .get = hdcs_get_gain
62 }
63};
64
65static struct v4l2_pix_format hdcs1x00_mode[] = { 35static struct v4l2_pix_format hdcs1x00_mode[] = {
66 { 36 {
67 HDCS_1X00_DEF_WIDTH, 37 HDCS_1X00_DEF_WIDTH,
@@ -76,36 +46,6 @@ static struct v4l2_pix_format hdcs1x00_mode[] = {
76 } 46 }
77}; 47};
78 48
79static const struct ctrl hdcs1020_ctrl[] = {
80 {
81 {
82 .id = V4L2_CID_EXPOSURE,
83 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "exposure",
85 .minimum = 0x00,
86 .maximum = 0xffff,
87 .step = 0x1,
88 .default_value = HDCS_DEFAULT_EXPOSURE,
89 .flags = V4L2_CTRL_FLAG_SLIDER
90 },
91 .set = hdcs_set_exposure,
92 .get = hdcs_get_exposure
93 }, {
94 {
95 .id = V4L2_CID_GAIN,
96 .type = V4L2_CTRL_TYPE_INTEGER,
97 .name = "gain",
98 .minimum = 0x00,
99 .maximum = 0xff,
100 .step = 0x1,
101 .default_value = HDCS_DEFAULT_GAIN,
102 .flags = V4L2_CTRL_FLAG_SLIDER
103 },
104 .set = hdcs_set_gain,
105 .get = hdcs_get_gain
106 }
107};
108
109static struct v4l2_pix_format hdcs1020_mode[] = { 49static struct v4l2_pix_format hdcs1020_mode[] = {
110 { 50 {
111 HDCS_1020_DEF_WIDTH, 51 HDCS_1020_DEF_WIDTH,
@@ -150,7 +90,6 @@ struct hdcs {
150 } exp; 90 } exp;
151 91
152 int psmp; 92 int psmp;
153 u8 exp_cache, gain_cache;
154}; 93};
155 94
156static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) 95static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
@@ -232,16 +171,6 @@ static int hdcs_reset(struct sd *sd)
232 return err; 171 return err;
233} 172}
234 173
235static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
236{
237 struct sd *sd = (struct sd *) gspca_dev;
238 struct hdcs *hdcs = sd->sensor_priv;
239
240 *val = hdcs->exp_cache;
241
242 return 0;
243}
244
245static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 174static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
246{ 175{
247 struct sd *sd = (struct sd *) gspca_dev; 176 struct sd *sd = (struct sd *) gspca_dev;
@@ -260,9 +189,6 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
260 int cycles, err; 189 int cycles, err;
261 u8 exp[14]; 190 u8 exp[14];
262 191
263 val &= 0xff;
264 hdcs->exp_cache = val;
265
266 cycles = val * HDCS_CLK_FREQ_MHZ * 257; 192 cycles = val * HDCS_CLK_FREQ_MHZ * 257;
267 193
268 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); 194 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
@@ -336,12 +262,9 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
336 262
337static int hdcs_set_gains(struct sd *sd, u8 g) 263static int hdcs_set_gains(struct sd *sd, u8 g)
338{ 264{
339 struct hdcs *hdcs = sd->sensor_priv;
340 int err; 265 int err;
341 u8 gains[4]; 266 u8 gains[4];
342 267
343 hdcs->gain_cache = g;
344
345 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ 268 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
346 if (g > 127) 269 if (g > 127)
347 g = 0x80 | (g / 2); 270 g = 0x80 | (g / 2);
@@ -352,17 +275,7 @@ static int hdcs_set_gains(struct sd *sd, u8 g)
352 gains[3] = g; 275 gains[3] = g;
353 276
354 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); 277 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
355 return err; 278 return err;
356}
357
358static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
359{
360 struct sd *sd = (struct sd *) gspca_dev;
361 struct hdcs *hdcs = sd->sensor_priv;
362
363 *val = hdcs->gain_cache;
364
365 return 0;
366} 279}
367 280
368static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) 281static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -420,6 +333,39 @@ static int hdcs_set_size(struct sd *sd,
420 return err; 333 return err;
421} 334}
422 335
336static int hdcs_s_ctrl(struct v4l2_ctrl *ctrl)
337{
338 struct gspca_dev *gspca_dev =
339 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
340 int err = -EINVAL;
341
342 switch (ctrl->id) {
343 case V4L2_CID_GAIN:
344 err = hdcs_set_gain(gspca_dev, ctrl->val);
345 break;
346 case V4L2_CID_EXPOSURE:
347 err = hdcs_set_exposure(gspca_dev, ctrl->val);
348 break;
349 }
350 return err;
351}
352
353static const struct v4l2_ctrl_ops hdcs_ctrl_ops = {
354 .s_ctrl = hdcs_s_ctrl,
355};
356
357static int hdcs_init_controls(struct sd *sd)
358{
359 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
360
361 v4l2_ctrl_handler_init(hdl, 2);
362 v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
363 V4L2_CID_EXPOSURE, 0, 0xff, 1, HDCS_DEFAULT_EXPOSURE);
364 v4l2_ctrl_new_std(hdl, &hdcs_ctrl_ops,
365 V4L2_CID_GAIN, 0, 0xff, 1, HDCS_DEFAULT_GAIN);
366 return hdl->error;
367}
368
423static int hdcs_probe_1x00(struct sd *sd) 369static int hdcs_probe_1x00(struct sd *sd)
424{ 370{
425 struct hdcs *hdcs; 371 struct hdcs *hdcs;
@@ -434,8 +380,6 @@ static int hdcs_probe_1x00(struct sd *sd)
434 380
435 sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; 381 sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
436 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); 382 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
437 sd->desc.ctrls = hdcs1x00_ctrl;
438 sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
439 383
440 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); 384 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
441 if (!hdcs) 385 if (!hdcs)
@@ -493,8 +437,6 @@ static int hdcs_probe_1020(struct sd *sd)
493 437
494 sd->gspca_dev.cam.cam_mode = hdcs1020_mode; 438 sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
495 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); 439 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
496 sd->desc.ctrls = hdcs1020_ctrl;
497 sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
498 440
499 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); 441 hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
500 if (!hdcs) 442 if (!hdcs)
@@ -537,12 +479,6 @@ static int hdcs_stop(struct sd *sd)
537 return hdcs_set_state(sd, HDCS_STATE_SLEEP); 479 return hdcs_set_state(sd, HDCS_STATE_SLEEP);
538} 480}
539 481
540static void hdcs_disconnect(struct sd *sd)
541{
542 PDEBUG(D_PROBE, "Disconnecting the sensor");
543 kfree(sd->sensor_priv);
544}
545
546static int hdcs_init(struct sd *sd) 482static int hdcs_init(struct sd *sd)
547{ 483{
548 struct hdcs *hdcs = sd->sensor_priv; 484 struct hdcs *hdcs = sd->sensor_priv;
@@ -587,16 +523,7 @@ static int hdcs_init(struct sd *sd)
587 if (err < 0) 523 if (err < 0)
588 return err; 524 return err;
589 525
590 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN); 526 return hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
591 if (err < 0)
592 return err;
593
594 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
595 if (err < 0)
596 return err;
597
598 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
599 return err;
600} 527}
601 528
602static int hdcs_dump(struct sd *sd) 529static int hdcs_dump(struct sd *sd)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index a14a84a5079b..1ba9158d0102 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -131,14 +131,12 @@ static int hdcs_probe_1x00(struct sd *sd);
131static int hdcs_probe_1020(struct sd *sd); 131static int hdcs_probe_1020(struct sd *sd);
132static int hdcs_start(struct sd *sd); 132static int hdcs_start(struct sd *sd);
133static int hdcs_init(struct sd *sd); 133static int hdcs_init(struct sd *sd);
134static int hdcs_init_controls(struct sd *sd);
134static int hdcs_stop(struct sd *sd); 135static int hdcs_stop(struct sd *sd);
135static int hdcs_dump(struct sd *sd); 136static int hdcs_dump(struct sd *sd);
136static void hdcs_disconnect(struct sd *sd);
137 137
138static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
139static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 138static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
140static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val); 139static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val);
141static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
142 140
143const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = { 141const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
144 .name = "HP HDCS-1000/1100", 142 .name = "HP HDCS-1000/1100",
@@ -152,10 +150,10 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
152 .max_packet_size = { 847 }, 150 .max_packet_size = { 847 },
153 151
154 .init = hdcs_init, 152 .init = hdcs_init,
153 .init_controls = hdcs_init_controls,
155 .probe = hdcs_probe_1x00, 154 .probe = hdcs_probe_1x00,
156 .start = hdcs_start, 155 .start = hdcs_start,
157 .stop = hdcs_stop, 156 .stop = hdcs_stop,
158 .disconnect = hdcs_disconnect,
159 .dump = hdcs_dump, 157 .dump = hdcs_dump,
160}; 158};
161 159
@@ -171,6 +169,7 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
171 .max_packet_size = { 847 }, 169 .max_packet_size = { 847 },
172 170
173 .init = hdcs_init, 171 .init = hdcs_init,
172 .init_controls = hdcs_init_controls,
174 .probe = hdcs_probe_1020, 173 .probe = hdcs_probe_1020,
175 .start = hdcs_start, 174 .start = hdcs_start,
176 .stop = hdcs_stop, 175 .stop = hdcs_stop,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index 26f14fc4a135..cdfc3d05ab6b 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -48,105 +48,16 @@
48 48
49#include "stv06xx_pb0100.h" 49#include "stv06xx_pb0100.h"
50 50
51static const struct ctrl pb0100_ctrl[] = { 51struct pb0100_ctrls {
52#define GAIN_IDX 0 52 struct { /* one big happy control cluster... */
53 { 53 struct v4l2_ctrl *autogain;
54 { 54 struct v4l2_ctrl *gain;
55 .id = V4L2_CID_GAIN, 55 struct v4l2_ctrl *exposure;
56 .type = V4L2_CTRL_TYPE_INTEGER, 56 struct v4l2_ctrl *red;
57 .name = "Gain", 57 struct v4l2_ctrl *blue;
58 .minimum = 0, 58 struct v4l2_ctrl *natural;
59 .maximum = 255, 59 };
60 .step = 1, 60 struct v4l2_ctrl *target;
61 .default_value = 128
62 },
63 .set = pb0100_set_gain,
64 .get = pb0100_get_gain
65 },
66#define RED_BALANCE_IDX 1
67 {
68 {
69 .id = V4L2_CID_RED_BALANCE,
70 .type = V4L2_CTRL_TYPE_INTEGER,
71 .name = "Red Balance",
72 .minimum = -255,
73 .maximum = 255,
74 .step = 1,
75 .default_value = 0
76 },
77 .set = pb0100_set_red_balance,
78 .get = pb0100_get_red_balance
79 },
80#define BLUE_BALANCE_IDX 2
81 {
82 {
83 .id = V4L2_CID_BLUE_BALANCE,
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 .name = "Blue Balance",
86 .minimum = -255,
87 .maximum = 255,
88 .step = 1,
89 .default_value = 0
90 },
91 .set = pb0100_set_blue_balance,
92 .get = pb0100_get_blue_balance
93 },
94#define EXPOSURE_IDX 3
95 {
96 {
97 .id = V4L2_CID_EXPOSURE,
98 .type = V4L2_CTRL_TYPE_INTEGER,
99 .name = "Exposure",
100 .minimum = 0,
101 .maximum = 511,
102 .step = 1,
103 .default_value = 12
104 },
105 .set = pb0100_set_exposure,
106 .get = pb0100_get_exposure
107 },
108#define AUTOGAIN_IDX 4
109 {
110 {
111 .id = V4L2_CID_AUTOGAIN,
112 .type = V4L2_CTRL_TYPE_BOOLEAN,
113 .name = "Automatic Gain and Exposure",
114 .minimum = 0,
115 .maximum = 1,
116 .step = 1,
117 .default_value = 1
118 },
119 .set = pb0100_set_autogain,
120 .get = pb0100_get_autogain
121 },
122#define AUTOGAIN_TARGET_IDX 5
123 {
124 {
125 .id = V4L2_CTRL_CLASS_USER + 0x1000,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Automatic Gain Target",
128 .minimum = 0,
129 .maximum = 255,
130 .step = 1,
131 .default_value = 128
132 },
133 .set = pb0100_set_autogain_target,
134 .get = pb0100_get_autogain_target
135 },
136#define NATURAL_IDX 6
137 {
138 {
139 .id = V4L2_CTRL_CLASS_USER + 0x1001,
140 .type = V4L2_CTRL_TYPE_BOOLEAN,
141 .name = "Natural Light Source",
142 .minimum = 0,
143 .maximum = 1,
144 .step = 1,
145 .default_value = 1
146 },
147 .set = pb0100_set_natural,
148 .get = pb0100_get_natural
149 }
150}; 61};
151 62
152static struct v4l2_pix_format pb0100_mode[] = { 63static struct v4l2_pix_format pb0100_mode[] = {
@@ -174,38 +85,104 @@ static struct v4l2_pix_format pb0100_mode[] = {
174 } 85 }
175}; 86};
176 87
88static int pb0100_s_ctrl(struct v4l2_ctrl *ctrl)
89{
90 struct gspca_dev *gspca_dev =
91 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
92 struct sd *sd = (struct sd *)gspca_dev;
93 struct pb0100_ctrls *ctrls = sd->sensor_priv;
94 int err = -EINVAL;
95
96 switch (ctrl->id) {
97 case V4L2_CID_AUTOGAIN:
98 err = pb0100_set_autogain(gspca_dev, ctrl->val);
99 if (err)
100 break;
101 if (ctrl->val)
102 break;
103 err = pb0100_set_gain(gspca_dev, ctrls->gain->val);
104 if (err)
105 break;
106 err = pb0100_set_exposure(gspca_dev, ctrls->exposure->val);
107 break;
108 case V4L2_CTRL_CLASS_USER + 0x1001:
109 err = pb0100_set_autogain_target(gspca_dev, ctrl->val);
110 break;
111 }
112 return err;
113}
114
115static const struct v4l2_ctrl_ops pb0100_ctrl_ops = {
116 .s_ctrl = pb0100_s_ctrl,
117};
118
119static int pb0100_init_controls(struct sd *sd)
120{
121 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
122 struct pb0100_ctrls *ctrls;
123 static const struct v4l2_ctrl_config autogain_target = {
124 .ops = &pb0100_ctrl_ops,
125 .id = V4L2_CTRL_CLASS_USER + 0x1000,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Automatic Gain Target",
128 .max = 255,
129 .step = 1,
130 .def = 128,
131 };
132 static const struct v4l2_ctrl_config natural_light = {
133 .ops = &pb0100_ctrl_ops,
134 .id = V4L2_CTRL_CLASS_USER + 0x1001,
135 .type = V4L2_CTRL_TYPE_BOOLEAN,
136 .name = "Natural Light Source",
137 .max = 1,
138 .step = 1,
139 .def = 1,
140 };
141
142 ctrls = kzalloc(sizeof(*ctrls), GFP_KERNEL);
143 if (!ctrls)
144 return -ENOMEM;
145
146 v4l2_ctrl_handler_init(hdl, 6);
147 ctrls->autogain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
148 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
149 ctrls->exposure = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
150 V4L2_CID_EXPOSURE, 0, 511, 1, 12);
151 ctrls->gain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
152 V4L2_CID_GAIN, 0, 255, 1, 128);
153 ctrls->red = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
154 V4L2_CID_RED_BALANCE, -255, 255, 1, 0);
155 ctrls->blue = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
156 V4L2_CID_BLUE_BALANCE, -255, 255, 1, 0);
157 ctrls->natural = v4l2_ctrl_new_custom(hdl, &natural_light, NULL);
158 ctrls->target = v4l2_ctrl_new_custom(hdl, &autogain_target, NULL);
159 if (hdl->error) {
160 kfree(ctrls);
161 return hdl->error;
162 }
163 sd->sensor_priv = ctrls;
164 v4l2_ctrl_auto_cluster(5, &ctrls->autogain, 0, false);
165 return 0;
166}
167
177static int pb0100_probe(struct sd *sd) 168static int pb0100_probe(struct sd *sd)
178{ 169{
179 u16 sensor; 170 u16 sensor;
180 int i, err; 171 int err;
181 s32 *sensor_settings;
182 172
183 err = stv06xx_read_sensor(sd, PB_IDENT, &sensor); 173 err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
184 174
185 if (err < 0) 175 if (err < 0)
186 return -ENODEV; 176 return -ENODEV;
177 if ((sensor >> 8) != 0x64)
178 return -ENODEV;
187 179
188 if ((sensor >> 8) == 0x64) { 180 pr_info("Photobit pb0100 sensor detected\n");
189 sensor_settings = kmalloc(
190 ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
191 GFP_KERNEL);
192 if (!sensor_settings)
193 return -ENOMEM;
194
195 pr_info("Photobit pb0100 sensor detected\n");
196
197 sd->gspca_dev.cam.cam_mode = pb0100_mode;
198 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
199 sd->desc.ctrls = pb0100_ctrl;
200 sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
201 for (i = 0; i < sd->desc.nctrls; i++)
202 sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
203 sd->sensor_priv = sensor_settings;
204 181
205 return 0; 182 sd->gspca_dev.cam.cam_mode = pb0100_mode;
206 } 183 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
207 184
208 return -ENODEV; 185 return 0;
209} 186}
210 187
211static int pb0100_start(struct sd *sd) 188static int pb0100_start(struct sd *sd)
@@ -214,7 +191,6 @@ static int pb0100_start(struct sd *sd)
214 struct usb_host_interface *alt; 191 struct usb_host_interface *alt;
215 struct usb_interface *intf; 192 struct usb_interface *intf;
216 struct cam *cam = &sd->gspca_dev.cam; 193 struct cam *cam = &sd->gspca_dev.cam;
217 s32 *sensor_settings = sd->sensor_priv;
218 u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 194 u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
219 195
220 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); 196 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
@@ -255,13 +231,6 @@ static int pb0100_start(struct sd *sd)
255 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20); 231 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
256 } 232 }
257 233
258 /* set_gain also sets red and blue balance */
259 pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
260 pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
261 pb0100_set_autogain_target(&sd->gspca_dev,
262 sensor_settings[AUTOGAIN_TARGET_IDX]);
263 pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
264
265 err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1)); 234 err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
266 PDEBUG(D_STREAM, "Started stream, status: %d", err); 235 PDEBUG(D_STREAM, "Started stream, status: %d", err);
267 236
@@ -285,12 +254,6 @@ out:
285 return (err < 0) ? err : 0; 254 return (err < 0) ? err : 0;
286} 255}
287 256
288static void pb0100_disconnect(struct sd *sd)
289{
290 sd->sensor = NULL;
291 kfree(sd->sensor_priv);
292}
293
294/* FIXME: Sort the init commands out and put them into tables, 257/* FIXME: Sort the init commands out and put them into tables,
295 this is only for getting the camera to work */ 258 this is only for getting the camera to work */
296/* FIXME: No error handling for now, 259/* FIXME: No error handling for now,
@@ -362,62 +325,32 @@ static int pb0100_dump(struct sd *sd)
362 return 0; 325 return 0;
363} 326}
364 327
365static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
366{
367 struct sd *sd = (struct sd *) gspca_dev;
368 s32 *sensor_settings = sd->sensor_priv;
369
370 *val = sensor_settings[GAIN_IDX];
371
372 return 0;
373}
374
375static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val) 328static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
376{ 329{
377 int err; 330 int err;
378 struct sd *sd = (struct sd *) gspca_dev; 331 struct sd *sd = (struct sd *) gspca_dev;
379 s32 *sensor_settings = sd->sensor_priv; 332 struct pb0100_ctrls *ctrls = sd->sensor_priv;
380 333
381 if (sensor_settings[AUTOGAIN_IDX])
382 return -EBUSY;
383
384 sensor_settings[GAIN_IDX] = val;
385 err = stv06xx_write_sensor(sd, PB_G1GAIN, val); 334 err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
386 if (!err) 335 if (!err)
387 err = stv06xx_write_sensor(sd, PB_G2GAIN, val); 336 err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
388 PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err); 337 PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
389 338
390 if (!err) 339 if (!err)
391 err = pb0100_set_red_balance(gspca_dev, 340 err = pb0100_set_red_balance(gspca_dev, ctrls->red->val);
392 sensor_settings[RED_BALANCE_IDX]);
393 if (!err) 341 if (!err)
394 err = pb0100_set_blue_balance(gspca_dev, 342 err = pb0100_set_blue_balance(gspca_dev, ctrls->blue->val);
395 sensor_settings[BLUE_BALANCE_IDX]);
396 343
397 return err; 344 return err;
398} 345}
399 346
400static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
401{
402 struct sd *sd = (struct sd *) gspca_dev;
403 s32 *sensor_settings = sd->sensor_priv;
404
405 *val = sensor_settings[RED_BALANCE_IDX];
406
407 return 0;
408}
409
410static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 347static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
411{ 348{
412 int err; 349 int err;
413 struct sd *sd = (struct sd *) gspca_dev; 350 struct sd *sd = (struct sd *) gspca_dev;
414 s32 *sensor_settings = sd->sensor_priv; 351 struct pb0100_ctrls *ctrls = sd->sensor_priv;
415 352
416 if (sensor_settings[AUTOGAIN_IDX]) 353 val += ctrls->gain->val;
417 return -EBUSY;
418
419 sensor_settings[RED_BALANCE_IDX] = val;
420 val += sensor_settings[GAIN_IDX];
421 if (val < 0) 354 if (val < 0)
422 val = 0; 355 val = 0;
423 else if (val > 255) 356 else if (val > 255)
@@ -429,27 +362,13 @@ static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
429 return err; 362 return err;
430} 363}
431 364
432static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
433{
434 struct sd *sd = (struct sd *) gspca_dev;
435 s32 *sensor_settings = sd->sensor_priv;
436
437 *val = sensor_settings[BLUE_BALANCE_IDX];
438
439 return 0;
440}
441
442static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 365static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
443{ 366{
444 int err; 367 int err;
445 struct sd *sd = (struct sd *) gspca_dev; 368 struct sd *sd = (struct sd *) gspca_dev;
446 s32 *sensor_settings = sd->sensor_priv; 369 struct pb0100_ctrls *ctrls = sd->sensor_priv;
447 370
448 if (sensor_settings[AUTOGAIN_IDX]) 371 val += ctrls->gain->val;
449 return -EBUSY;
450
451 sensor_settings[BLUE_BALANCE_IDX] = val;
452 val += sensor_settings[GAIN_IDX];
453 if (val < 0) 372 if (val < 0)
454 val = 0; 373 val = 0;
455 else if (val > 255) 374 else if (val > 255)
@@ -461,51 +380,25 @@ static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
461 return err; 380 return err;
462} 381}
463 382
464static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
465{
466 struct sd *sd = (struct sd *) gspca_dev;
467 s32 *sensor_settings = sd->sensor_priv;
468
469 *val = sensor_settings[EXPOSURE_IDX];
470
471 return 0;
472}
473
474static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 383static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
475{ 384{
476 int err;
477 struct sd *sd = (struct sd *) gspca_dev; 385 struct sd *sd = (struct sd *) gspca_dev;
478 s32 *sensor_settings = sd->sensor_priv; 386 int err;
479
480 if (sensor_settings[AUTOGAIN_IDX])
481 return -EBUSY;
482 387
483 sensor_settings[EXPOSURE_IDX] = val;
484 err = stv06xx_write_sensor(sd, PB_RINTTIME, val); 388 err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
485 PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err); 389 PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
486 390
487 return err; 391 return err;
488} 392}
489 393
490static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
491{
492 struct sd *sd = (struct sd *) gspca_dev;
493 s32 *sensor_settings = sd->sensor_priv;
494
495 *val = sensor_settings[AUTOGAIN_IDX];
496
497 return 0;
498}
499
500static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val) 394static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
501{ 395{
502 int err; 396 int err;
503 struct sd *sd = (struct sd *) gspca_dev; 397 struct sd *sd = (struct sd *) gspca_dev;
504 s32 *sensor_settings = sd->sensor_priv; 398 struct pb0100_ctrls *ctrls = sd->sensor_priv;
505 399
506 sensor_settings[AUTOGAIN_IDX] = val; 400 if (val) {
507 if (sensor_settings[AUTOGAIN_IDX]) { 401 if (ctrls->natural->val)
508 if (sensor_settings[NATURAL_IDX])
509 val = BIT(6)|BIT(4)|BIT(0); 402 val = BIT(6)|BIT(4)|BIT(0);
510 else 403 else
511 val = BIT(4)|BIT(0); 404 val = BIT(4)|BIT(0);
@@ -514,29 +407,15 @@ static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
514 407
515 err = stv06xx_write_sensor(sd, PB_EXPGAIN, val); 408 err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
516 PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d", 409 PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
517 sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX], 410 val, ctrls->natural->val, err);
518 err);
519 411
520 return err; 412 return err;
521} 413}
522 414
523static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
524{
525 struct sd *sd = (struct sd *) gspca_dev;
526 s32 *sensor_settings = sd->sensor_priv;
527
528 *val = sensor_settings[AUTOGAIN_TARGET_IDX];
529
530 return 0;
531}
532
533static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val) 415static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
534{ 416{
535 int err, totalpixels, brightpixels, darkpixels; 417 int err, totalpixels, brightpixels, darkpixels;
536 struct sd *sd = (struct sd *) gspca_dev; 418 struct sd *sd = (struct sd *) gspca_dev;
537 s32 *sensor_settings = sd->sensor_priv;
538
539 sensor_settings[AUTOGAIN_TARGET_IDX] = val;
540 419
541 /* Number of pixels counted by the sensor when subsampling the pixels. 420 /* Number of pixels counted by the sensor when subsampling the pixels.
542 * Slightly larger than the real value to avoid oscillation */ 421 * Slightly larger than the real value to avoid oscillation */
@@ -553,23 +432,3 @@ static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
553 432
554 return err; 433 return err;
555} 434}
556
557static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
558{
559 struct sd *sd = (struct sd *) gspca_dev;
560 s32 *sensor_settings = sd->sensor_priv;
561
562 *val = sensor_settings[NATURAL_IDX];
563
564 return 0;
565}
566
567static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
568{
569 struct sd *sd = (struct sd *) gspca_dev;
570 s32 *sensor_settings = sd->sensor_priv;
571
572 sensor_settings[NATURAL_IDX] = val;
573
574 return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
575}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 757de246dc75..5071e5353fd3 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -112,25 +112,17 @@
112static int pb0100_probe(struct sd *sd); 112static int pb0100_probe(struct sd *sd);
113static int pb0100_start(struct sd *sd); 113static int pb0100_start(struct sd *sd);
114static int pb0100_init(struct sd *sd); 114static int pb0100_init(struct sd *sd);
115static int pb0100_init_controls(struct sd *sd);
115static int pb0100_stop(struct sd *sd); 116static int pb0100_stop(struct sd *sd);
116static int pb0100_dump(struct sd *sd); 117static int pb0100_dump(struct sd *sd);
117static void pb0100_disconnect(struct sd *sd);
118 118
119/* V4L2 controls supported by the driver */ 119/* V4L2 controls supported by the driver */
120static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
121static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val); 120static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val);
122static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
123static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); 121static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
124static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
125static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); 122static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
126static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
127static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 123static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
128static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val);
129static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val); 124static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val);
130static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val);
131static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val); 125static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val);
132static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val);
133static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val);
134 126
135const struct stv06xx_sensor stv06xx_sensor_pb0100 = { 127const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
136 .name = "PB-0100", 128 .name = "PB-0100",
@@ -142,11 +134,11 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
142 .max_packet_size = { 847, 923 }, 134 .max_packet_size = { 847, 923 },
143 135
144 .init = pb0100_init, 136 .init = pb0100_init,
137 .init_controls = pb0100_init_controls,
145 .probe = pb0100_probe, 138 .probe = pb0100_probe,
146 .start = pb0100_start, 139 .start = pb0100_start,
147 .stop = pb0100_stop, 140 .stop = pb0100_stop,
148 .dump = pb0100_dump, 141 .dump = pb0100_dump,
149 .disconnect = pb0100_disconnect,
150}; 142};
151 143
152#endif 144#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index fb229d8ded58..3a498c2495c6 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -63,8 +63,8 @@ struct stv06xx_sensor {
63 /* Performs a initialization sequence */ 63 /* Performs a initialization sequence */
64 int (*init)(struct sd *sd); 64 int (*init)(struct sd *sd);
65 65
66 /* Executed at device disconnect */ 66 /* Initializes the controls */
67 void (*disconnect)(struct sd *sd); 67 int (*init_controls)(struct sd *sd);
68 68
69 /* Reads a sensor register */ 69 /* Reads a sensor register */
70 int (*read_sensor)(struct sd *sd, const u8 address, 70 int (*read_sensor)(struct sd *sd, const u8 address,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 9940e035b3ab..8a57990dfe0f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -30,20 +30,6 @@
30 30
31#include "stv06xx_st6422.h" 31#include "stv06xx_st6422.h"
32 32
33/* controls */
34enum e_ctrl {
35 BRIGHTNESS,
36 CONTRAST,
37 GAIN,
38 EXPOSURE,
39 NCTRLS /* number of controls */
40};
41
42/* sensor settings */
43struct st6422_settings {
44 struct gspca_ctrl ctrls[NCTRLS];
45};
46
47static struct v4l2_pix_format st6422_mode[] = { 33static struct v4l2_pix_format st6422_mode[] = {
48 /* Note we actually get 124 lines of data, of which we skip the 4st 34 /* Note we actually get 124 lines of data, of which we skip the 4st
49 4 as they are garbage */ 35 4 as they are garbage */
@@ -74,83 +60,70 @@ static struct v4l2_pix_format st6422_mode[] = {
74}; 60};
75 61
76/* V4L2 controls supported by the driver */ 62/* V4L2 controls supported by the driver */
77static void st6422_set_brightness(struct gspca_dev *gspca_dev); 63static int setbrightness(struct sd *sd, s32 val);
78static void st6422_set_contrast(struct gspca_dev *gspca_dev); 64static int setcontrast(struct sd *sd, s32 val);
79static void st6422_set_gain(struct gspca_dev *gspca_dev); 65static int setgain(struct sd *sd, u8 gain);
80static void st6422_set_exposure(struct gspca_dev *gspca_dev); 66static int setexposure(struct sd *sd, s16 expo);
81 67
82static const struct ctrl st6422_ctrl[NCTRLS] = { 68static int st6422_s_ctrl(struct v4l2_ctrl *ctrl)
83[BRIGHTNESS] = { 69{
84 { 70 struct gspca_dev *gspca_dev =
85 .id = V4L2_CID_BRIGHTNESS, 71 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
86 .type = V4L2_CTRL_TYPE_INTEGER, 72 struct sd *sd = (struct sd *)gspca_dev;
87 .name = "Brightness", 73 int err = -EINVAL;
88 .minimum = 0, 74
89 .maximum = 31, 75 switch (ctrl->id) {
90 .step = 1, 76 case V4L2_CID_BRIGHTNESS:
91 .default_value = 3 77 err = setbrightness(sd, ctrl->val);
92 }, 78 break;
93 .set_control = st6422_set_brightness 79 case V4L2_CID_CONTRAST:
94 }, 80 err = setcontrast(sd, ctrl->val);
95[CONTRAST] = { 81 break;
96 { 82 case V4L2_CID_GAIN:
97 .id = V4L2_CID_CONTRAST, 83 err = setgain(sd, ctrl->val);
98 .type = V4L2_CTRL_TYPE_INTEGER, 84 break;
99 .name = "Contrast", 85 case V4L2_CID_EXPOSURE:
100 .minimum = 0, 86 err = setexposure(sd, ctrl->val);
101 .maximum = 15, 87 break;
102 .step = 1, 88 }
103 .default_value = 11 89
104 }, 90 /* commit settings */
105 .set_control = st6422_set_contrast 91 if (err >= 0)
106 }, 92 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
107[GAIN] = { 93 sd->gspca_dev.usb_err = err;
108 { 94 return err;
109 .id = V4L2_CID_GAIN, 95}
110 .type = V4L2_CTRL_TYPE_INTEGER, 96
111 .name = "Gain", 97static const struct v4l2_ctrl_ops st6422_ctrl_ops = {
112 .minimum = 0, 98 .s_ctrl = st6422_s_ctrl,
113 .maximum = 255,
114 .step = 1,
115 .default_value = 64
116 },
117 .set_control = st6422_set_gain
118 },
119[EXPOSURE] = {
120 {
121 .id = V4L2_CID_EXPOSURE,
122 .type = V4L2_CTRL_TYPE_INTEGER,
123 .name = "Exposure",
124 .minimum = 0,
125#define EXPOSURE_MAX 1023
126 .maximum = EXPOSURE_MAX,
127 .step = 1,
128 .default_value = 256
129 },
130 .set_control = st6422_set_exposure
131 },
132}; 99};
133 100
134static int st6422_probe(struct sd *sd) 101static int st6422_init_controls(struct sd *sd)
135{ 102{
136 struct st6422_settings *sensor_settings; 103 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
104
105 v4l2_ctrl_handler_init(hdl, 4);
106 v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
107 V4L2_CID_BRIGHTNESS, 0, 31, 1, 3);
108 v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
109 V4L2_CID_CONTRAST, 0, 15, 1, 11);
110 v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
111 V4L2_CID_EXPOSURE, 0, 1023, 1, 256);
112 v4l2_ctrl_new_std(hdl, &st6422_ctrl_ops,
113 V4L2_CID_GAIN, 0, 255, 1, 64);
114
115 return hdl->error;
116}
137 117
118static int st6422_probe(struct sd *sd)
119{
138 if (sd->bridge != BRIDGE_ST6422) 120 if (sd->bridge != BRIDGE_ST6422)
139 return -ENODEV; 121 return -ENODEV;
140 122
141 pr_info("st6422 sensor detected\n"); 123 pr_info("st6422 sensor detected\n");
142 124
143 sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL);
144 if (!sensor_settings)
145 return -ENOMEM;
146
147 sd->gspca_dev.cam.cam_mode = st6422_mode; 125 sd->gspca_dev.cam.cam_mode = st6422_mode;
148 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); 126 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
149 sd->gspca_dev.cam.ctrls = sensor_settings->ctrls;
150 sd->desc.ctrls = st6422_ctrl;
151 sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
152 sd->sensor_priv = sensor_settings;
153
154 return 0; 127 return 0;
155} 128}
156 129
@@ -239,38 +212,22 @@ static int st6422_init(struct sd *sd)
239 return err; 212 return err;
240} 213}
241 214
242static void st6422_disconnect(struct sd *sd) 215static int setbrightness(struct sd *sd, s32 val)
243{
244 sd->sensor = NULL;
245 kfree(sd->sensor_priv);
246}
247
248static int setbrightness(struct sd *sd)
249{ 216{
250 struct st6422_settings *sensor_settings = sd->sensor_priv;
251
252 /* val goes from 0 -> 31 */ 217 /* val goes from 0 -> 31 */
253 return stv06xx_write_bridge(sd, 0x1432, 218 return stv06xx_write_bridge(sd, 0x1432, val);
254 sensor_settings->ctrls[BRIGHTNESS].val);
255} 219}
256 220
257static int setcontrast(struct sd *sd) 221static int setcontrast(struct sd *sd, s32 val)
258{ 222{
259 struct st6422_settings *sensor_settings = sd->sensor_priv;
260
261 /* Val goes from 0 -> 15 */ 223 /* Val goes from 0 -> 15 */
262 return stv06xx_write_bridge(sd, 0x143a, 224 return stv06xx_write_bridge(sd, 0x143a, val | 0xf0);
263 sensor_settings->ctrls[CONTRAST].val | 0xf0);
264} 225}
265 226
266static int setgain(struct sd *sd) 227static int setgain(struct sd *sd, u8 gain)
267{ 228{
268 struct st6422_settings *sensor_settings = sd->sensor_priv;
269 u8 gain;
270 int err; 229 int err;
271 230
272 gain = sensor_settings->ctrls[GAIN].val;
273
274 /* Set red, green, blue, gain */ 231 /* Set red, green, blue, gain */
275 err = stv06xx_write_bridge(sd, 0x0509, gain); 232 err = stv06xx_write_bridge(sd, 0x0509, gain);
276 if (err < 0) 233 if (err < 0)
@@ -292,13 +249,10 @@ static int setgain(struct sd *sd)
292 return stv06xx_write_bridge(sd, 0x050d, 0x01); 249 return stv06xx_write_bridge(sd, 0x050d, 0x01);
293} 250}
294 251
295static int setexposure(struct sd *sd) 252static int setexposure(struct sd *sd, s16 expo)
296{ 253{
297 struct st6422_settings *sensor_settings = sd->sensor_priv;
298 u16 expo;
299 int err; 254 int err;
300 255
301 expo = sensor_settings->ctrls[EXPOSURE].val;
302 err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff); 256 err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff);
303 if (err < 0) 257 if (err < 0)
304 return err; 258 return err;
@@ -318,22 +272,6 @@ static int st6422_start(struct sd *sd)
318 if (err < 0) 272 if (err < 0)
319 return err; 273 return err;
320 274
321 err = setbrightness(sd);
322 if (err < 0)
323 return err;
324
325 err = setcontrast(sd);
326 if (err < 0)
327 return err;
328
329 err = setexposure(sd);
330 if (err < 0)
331 return err;
332
333 err = setgain(sd);
334 if (err < 0)
335 return err;
336
337 /* commit settings */ 275 /* commit settings */
338 err = stv06xx_write_bridge(sd, 0x143f, 0x01); 276 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
339 return (err < 0) ? err : 0; 277 return (err < 0) ? err : 0;
@@ -345,59 +283,3 @@ static int st6422_stop(struct sd *sd)
345 283
346 return 0; 284 return 0;
347} 285}
348
349static void st6422_set_brightness(struct gspca_dev *gspca_dev)
350{
351 int err;
352 struct sd *sd = (struct sd *) gspca_dev;
353
354 err = setbrightness(sd);
355
356 /* commit settings */
357 if (err >= 0)
358 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
359
360 gspca_dev->usb_err = err;
361}
362
363static void st6422_set_contrast(struct gspca_dev *gspca_dev)
364{
365 int err;
366 struct sd *sd = (struct sd *) gspca_dev;
367
368 err = setcontrast(sd);
369
370 /* commit settings */
371 if (err >= 0)
372 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
373
374 gspca_dev->usb_err = err;
375}
376
377static void st6422_set_gain(struct gspca_dev *gspca_dev)
378{
379 int err;
380 struct sd *sd = (struct sd *) gspca_dev;
381
382 err = setgain(sd);
383
384 /* commit settings */
385 if (err >= 0)
386 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
387
388 gspca_dev->usb_err = err;
389}
390
391static void st6422_set_exposure(struct gspca_dev *gspca_dev)
392{
393 int err;
394 struct sd *sd = (struct sd *) gspca_dev;
395
396 err = setexposure(sd);
397
398 /* commit settings */
399 if (err >= 0)
400 err = stv06xx_write_bridge(sd, 0x143f, 0x01);
401
402 gspca_dev->usb_err = err;
403}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
index d7498e06432b..8f20fbf30f33 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
@@ -34,8 +34,8 @@
34static int st6422_probe(struct sd *sd); 34static int st6422_probe(struct sd *sd);
35static int st6422_start(struct sd *sd); 35static int st6422_start(struct sd *sd);
36static int st6422_init(struct sd *sd); 36static int st6422_init(struct sd *sd);
37static int st6422_init_controls(struct sd *sd);
37static int st6422_stop(struct sd *sd); 38static int st6422_stop(struct sd *sd);
38static void st6422_disconnect(struct sd *sd);
39 39
40const struct stv06xx_sensor stv06xx_sensor_st6422 = { 40const struct stv06xx_sensor stv06xx_sensor_st6422 = {
41 .name = "ST6422", 41 .name = "ST6422",
@@ -43,10 +43,10 @@ const struct stv06xx_sensor stv06xx_sensor_st6422 = {
43 .min_packet_size = { 300, 847 }, 43 .min_packet_size = { 300, 847 },
44 .max_packet_size = { 300, 847 }, 44 .max_packet_size = { 300, 847 },
45 .init = st6422_init, 45 .init = st6422_init,
46 .init_controls = st6422_init_controls,
46 .probe = st6422_probe, 47 .probe = st6422_probe,
47 .start = st6422_start, 48 .start = st6422_start,
48 .stop = st6422_stop, 49 .stop = st6422_stop,
49 .disconnect = st6422_disconnect,
50}; 50};
51 51
52#endif 52#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index a5c69d9ebdd4..748e1421d6d8 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -44,130 +44,83 @@ static struct v4l2_pix_format vv6410_mode[] = {
44 } 44 }
45}; 45};
46 46
47static const struct ctrl vv6410_ctrl[] = { 47static int vv6410_s_ctrl(struct v4l2_ctrl *ctrl)
48#define HFLIP_IDX 0 48{
49 { 49 struct gspca_dev *gspca_dev =
50 { 50 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
51 .id = V4L2_CID_HFLIP, 51 int err = -EINVAL;
52 .type = V4L2_CTRL_TYPE_BOOLEAN, 52
53 .name = "horizontal flip", 53 switch (ctrl->id) {
54 .minimum = 0, 54 case V4L2_CID_HFLIP:
55 .maximum = 1, 55 err = vv6410_set_hflip(gspca_dev, ctrl->val);
56 .step = 1, 56 break;
57 .default_value = 0 57 case V4L2_CID_VFLIP:
58 }, 58 err = vv6410_set_vflip(gspca_dev, ctrl->val);
59 .set = vv6410_set_hflip, 59 break;
60 .get = vv6410_get_hflip 60 case V4L2_CID_GAIN:
61 }, 61 err = vv6410_set_analog_gain(gspca_dev, ctrl->val);
62#define VFLIP_IDX 1 62 break;
63 { 63 case V4L2_CID_EXPOSURE:
64 { 64 err = vv6410_set_exposure(gspca_dev, ctrl->val);
65 .id = V4L2_CID_VFLIP, 65 break;
66 .type = V4L2_CTRL_TYPE_BOOLEAN,
67 .name = "vertical flip",
68 .minimum = 0,
69 .maximum = 1,
70 .step = 1,
71 .default_value = 0
72 },
73 .set = vv6410_set_vflip,
74 .get = vv6410_get_vflip
75 },
76#define GAIN_IDX 2
77 {
78 {
79 .id = V4L2_CID_GAIN,
80 .type = V4L2_CTRL_TYPE_INTEGER,
81 .name = "analog gain",
82 .minimum = 0,
83 .maximum = 15,
84 .step = 1,
85 .default_value = 10
86 },
87 .set = vv6410_set_analog_gain,
88 .get = vv6410_get_analog_gain
89 },
90#define EXPOSURE_IDX 3
91 {
92 {
93 .id = V4L2_CID_EXPOSURE,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "exposure",
96 .minimum = 0,
97 .maximum = 32768,
98 .step = 1,
99 .default_value = 20000
100 },
101 .set = vv6410_set_exposure,
102 .get = vv6410_get_exposure
103 } 66 }
104 }; 67 return err;
68}
69
70static const struct v4l2_ctrl_ops vv6410_ctrl_ops = {
71 .s_ctrl = vv6410_s_ctrl,
72};
105 73
106static int vv6410_probe(struct sd *sd) 74static int vv6410_probe(struct sd *sd)
107{ 75{
108 u16 data; 76 u16 data;
109 int err, i; 77 int err;
110 s32 *sensor_settings;
111 78
112 err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); 79 err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
113 if (err < 0) 80 if (err < 0)
114 return -ENODEV; 81 return -ENODEV;
115 82
116 if (data == 0x19) { 83 if (data != 0x19)
117 pr_info("vv6410 sensor detected\n"); 84 return -ENODEV;
118 85
119 sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32), 86 pr_info("vv6410 sensor detected\n");
120 GFP_KERNEL);
121 if (!sensor_settings)
122 return -ENOMEM;
123 87
124 sd->gspca_dev.cam.cam_mode = vv6410_mode; 88 sd->gspca_dev.cam.cam_mode = vv6410_mode;
125 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); 89 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
126 sd->desc.ctrls = vv6410_ctrl; 90 return 0;
127 sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl); 91}
128 92
129 for (i = 0; i < sd->desc.nctrls; i++) 93static int vv6410_init_controls(struct sd *sd)
130 sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value; 94{
131 sd->sensor_priv = sensor_settings; 95 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
132 return 0; 96
133 } 97 v4l2_ctrl_handler_init(hdl, 4);
134 return -ENODEV; 98 v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
99 V4L2_CID_HFLIP, 0, 1, 1, 0);
100 v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
101 V4L2_CID_VFLIP, 0, 1, 1, 0);
102 v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
103 V4L2_CID_EXPOSURE, 0, 32768, 1, 20000);
104 v4l2_ctrl_new_std(hdl, &vv6410_ctrl_ops,
105 V4L2_CID_GAIN, 0, 15, 1, 10);
106 return hdl->error;
135} 107}
136 108
137static int vv6410_init(struct sd *sd) 109static int vv6410_init(struct sd *sd)
138{ 110{
139 int err = 0, i; 111 int err = 0, i;
140 s32 *sensor_settings = sd->sensor_priv;
141 112
142 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { 113 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++)
143 stv06xx_write_bridge(sd, stv_bridge_init[i].addr, stv_bridge_init[i].data); 114 stv06xx_write_bridge(sd, stv_bridge_init[i].addr, stv_bridge_init[i].data);
144 }
145 115
146 if (err < 0) 116 if (err < 0)
147 return err; 117 return err;
148 118
149 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, 119 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
150 ARRAY_SIZE(vv6410_sensor_init)); 120 ARRAY_SIZE(vv6410_sensor_init));
151 if (err < 0)
152 return err;
153
154 err = vv6410_set_exposure(&sd->gspca_dev,
155 sensor_settings[EXPOSURE_IDX]);
156 if (err < 0)
157 return err;
158
159 err = vv6410_set_analog_gain(&sd->gspca_dev,
160 sensor_settings[GAIN_IDX]);
161
162 return (err < 0) ? err : 0; 121 return (err < 0) ? err : 0;
163} 122}
164 123
165static void vv6410_disconnect(struct sd *sd)
166{
167 sd->sensor = NULL;
168 kfree(sd->sensor_priv);
169}
170
171static int vv6410_start(struct sd *sd) 124static int vv6410_start(struct sd *sd)
172{ 125{
173 int err; 126 int err;
@@ -233,25 +186,12 @@ static int vv6410_dump(struct sd *sd)
233 return (err < 0) ? err : 0; 186 return (err < 0) ? err : 0;
234} 187}
235 188
236static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
237{
238 struct sd *sd = (struct sd *) gspca_dev;
239 s32 *sensor_settings = sd->sensor_priv;
240
241 *val = sensor_settings[HFLIP_IDX];
242 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
243
244 return 0;
245}
246
247static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 189static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
248{ 190{
249 int err; 191 int err;
250 u16 i2c_data; 192 u16 i2c_data;
251 struct sd *sd = (struct sd *) gspca_dev; 193 struct sd *sd = (struct sd *) gspca_dev;
252 s32 *sensor_settings = sd->sensor_priv;
253 194
254 sensor_settings[HFLIP_IDX] = val;
255 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); 195 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
256 if (err < 0) 196 if (err < 0)
257 return err; 197 return err;
@@ -267,25 +207,12 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
267 return (err < 0) ? err : 0; 207 return (err < 0) ? err : 0;
268} 208}
269 209
270static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
271{
272 struct sd *sd = (struct sd *) gspca_dev;
273 s32 *sensor_settings = sd->sensor_priv;
274
275 *val = sensor_settings[VFLIP_IDX];
276 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
277
278 return 0;
279}
280
281static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 210static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
282{ 211{
283 int err; 212 int err;
284 u16 i2c_data; 213 u16 i2c_data;
285 struct sd *sd = (struct sd *) gspca_dev; 214 struct sd *sd = (struct sd *) gspca_dev;
286 s32 *sensor_settings = sd->sensor_priv;
287 215
288 sensor_settings[VFLIP_IDX] = val;
289 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); 216 err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
290 if (err < 0) 217 if (err < 0)
291 return err; 218 return err;
@@ -301,52 +228,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
301 return (err < 0) ? err : 0; 228 return (err < 0) ? err : 0;
302} 229}
303 230
304static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
305{
306 struct sd *sd = (struct sd *) gspca_dev;
307 s32 *sensor_settings = sd->sensor_priv;
308
309 *val = sensor_settings[GAIN_IDX];
310
311 PDEBUG(D_V4L2, "Read analog gain %d", *val);
312
313 return 0;
314}
315
316static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) 231static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
317{ 232{
318 int err; 233 int err;
319 struct sd *sd = (struct sd *) gspca_dev; 234 struct sd *sd = (struct sd *) gspca_dev;
320 s32 *sensor_settings = sd->sensor_priv;
321 235
322 sensor_settings[GAIN_IDX] = val;
323 PDEBUG(D_V4L2, "Set analog gain to %d", val); 236 PDEBUG(D_V4L2, "Set analog gain to %d", val);
324 err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); 237 err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
325 238
326 return (err < 0) ? err : 0; 239 return (err < 0) ? err : 0;
327} 240}
328 241
329static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
330{
331 struct sd *sd = (struct sd *) gspca_dev;
332 s32 *sensor_settings = sd->sensor_priv;
333
334 *val = sensor_settings[EXPOSURE_IDX];
335
336 PDEBUG(D_V4L2, "Read exposure %d", *val);
337
338 return 0;
339}
340
341static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 242static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
342{ 243{
343 int err; 244 int err;
344 struct sd *sd = (struct sd *) gspca_dev; 245 struct sd *sd = (struct sd *) gspca_dev;
345 s32 *sensor_settings = sd->sensor_priv;
346 unsigned int fine, coarse; 246 unsigned int fine, coarse;
347 247
348 sensor_settings[EXPOSURE_IDX] = val;
349
350 val = (val * val >> 14) + val / 4; 248 val = (val * val >> 14) + val / 4;
351 249
352 fine = val % VV6410_CIF_LINELENGTH; 250 fine = val % VV6410_CIF_LINELENGTH;
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index a25b8873f2e6..53e67b40ca05 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -178,18 +178,14 @@
178static int vv6410_probe(struct sd *sd); 178static int vv6410_probe(struct sd *sd);
179static int vv6410_start(struct sd *sd); 179static int vv6410_start(struct sd *sd);
180static int vv6410_init(struct sd *sd); 180static int vv6410_init(struct sd *sd);
181static int vv6410_init_controls(struct sd *sd);
181static int vv6410_stop(struct sd *sd); 182static int vv6410_stop(struct sd *sd);
182static int vv6410_dump(struct sd *sd); 183static int vv6410_dump(struct sd *sd);
183static void vv6410_disconnect(struct sd *sd);
184 184
185/* V4L2 controls supported by the driver */ 185/* V4L2 controls supported by the driver */
186static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
187static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 186static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
188static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
189static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 187static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
190static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
191static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); 188static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
192static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
193static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 189static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
194 190
195const struct stv06xx_sensor stv06xx_sensor_vv6410 = { 191const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
@@ -202,11 +198,11 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
202 .min_packet_size = { 1023 }, 198 .min_packet_size = { 1023 },
203 .max_packet_size = { 1023 }, 199 .max_packet_size = { 1023 },
204 .init = vv6410_init, 200 .init = vv6410_init,
201 .init_controls = vv6410_init_controls,
205 .probe = vv6410_probe, 202 .probe = vv6410_probe,
206 .start = vv6410_start, 203 .start = vv6410_start,
207 .stop = vv6410_stop, 204 .stop = vv6410_stop,
208 .dump = vv6410_dump, 205 .dump = vv6410_dump,
209 .disconnect = vv6410_disconnect,
210}; 206};
211 207
212/* If NULL, only single value to write, stored in len */ 208/* If NULL, only single value to write, stored in len */
diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c
index 444d3c5b9079..c6326d177a3d 100644
--- a/drivers/media/video/gspca/topro.c
+++ b/drivers/media/video/gspca/topro.c
@@ -4675,11 +4675,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
4675/* -- do autogain -- */ 4675/* -- do autogain -- */
4676/* gain setting is done in setexposure() for tp6810 */ 4676/* gain setting is done in setexposure() for tp6810 */
4677static void setgain(struct gspca_dev *gspca_dev) {} 4677static void setgain(struct gspca_dev *gspca_dev) {}
4678/* !! coarse_grained_expo_autogain is not used !! */ 4678#define WANT_REGULAR_AUTOGAIN
4679#define exp_too_low_cnt bridge
4680#define exp_too_high_cnt sensor
4681
4682#include "autogain_functions.h" 4679#include "autogain_functions.h"
4680
4683static void sd_dq_callback(struct gspca_dev *gspca_dev) 4681static void sd_dq_callback(struct gspca_dev *gspca_dev)
4684{ 4682{
4685 struct sd *sd = (struct sd *) gspca_dev; 4683 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c
index 911152e169d6..15a30f7a4b2a 100644
--- a/drivers/media/video/gspca/vicam.c
+++ b/drivers/media/video/gspca/vicam.c
@@ -37,9 +37,12 @@
37#include <linux/ihex.h> 37#include <linux/ihex.h>
38#include "gspca.h" 38#include "gspca.h"
39 39
40#define VICAM_FIRMWARE "vicam/firmware.fw"
41
40MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 42MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
41MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver"); 43MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver");
42MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
45MODULE_FIRMWARE(VICAM_FIRMWARE);
43 46
44enum e_ctrl { 47enum e_ctrl {
45 GAIN, 48 GAIN,
@@ -222,7 +225,11 @@ static void vicam_dostream(struct work_struct *work)
222 goto exit; 225 goto exit;
223 } 226 }
224 227
225 while (gspca_dev->present && gspca_dev->streaming) { 228 while (gspca_dev->dev && gspca_dev->streaming) {
229#ifdef CONFIG_PM
230 if (gspca_dev->frozen)
231 break;
232#endif
226 ret = vicam_read_frame(gspca_dev, buffer, frame_sz); 233 ret = vicam_read_frame(gspca_dev, buffer, frame_sz);
227 if (ret < 0) 234 if (ret < 0)
228 break; 235 break;
@@ -268,7 +275,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
268 const struct firmware *uninitialized_var(fw); 275 const struct firmware *uninitialized_var(fw);
269 u8 *firmware_buf; 276 u8 *firmware_buf;
270 277
271 ret = request_ihex_firmware(&fw, "vicam/firmware.fw", 278 ret = request_ihex_firmware(&fw, VICAM_FIRMWARE,
272 &gspca_dev->dev->dev); 279 &gspca_dev->dev->dev);
273 if (ret) { 280 if (ret) {
274 pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret); 281 pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
@@ -324,7 +331,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
324 dev->work_thread = NULL; 331 dev->work_thread = NULL;
325 mutex_lock(&gspca_dev->usb_lock); 332 mutex_lock(&gspca_dev->usb_lock);
326 333
327 if (gspca_dev->present) 334 if (gspca_dev->dev)
328 vicam_set_camera_power(gspca_dev, 0); 335 vicam_set_camera_power(gspca_dev, 0);
329} 336}
330 337
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 7d9a4f1be9dc..f0bacee33ef9 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -32,29 +32,25 @@ MODULE_LICENSE("GPL");
32 32
33static int force_sensor = -1; 33static int force_sensor = -1;
34 34
35#define REG08_DEF 3 /* default JPEG compression (70%) */ 35#define REG08_DEF 3 /* default JPEG compression (75%) */
36#include "zc3xx-reg.h" 36#include "zc3xx-reg.h"
37 37
38/* controls */
39enum e_ctrl {
40 BRIGHTNESS,
41 CONTRAST,
42 EXPOSURE,
43 GAMMA,
44 AUTOGAIN,
45 LIGHTFREQ,
46 SHARPNESS,
47 QUALITY,
48 NCTRLS /* number of controls */
49};
50
51#define AUTOGAIN_DEF 1
52
53/* specific webcam descriptor */ 38/* specific webcam descriptor */
54struct sd { 39struct sd {
55 struct gspca_dev gspca_dev; /* !! must be the first item */ 40 struct gspca_dev gspca_dev; /* !! must be the first item */
56 41
57 struct gspca_ctrl ctrls[NCTRLS]; 42 struct { /* gamma/brightness/contrast control cluster */
43 struct v4l2_ctrl *gamma;
44 struct v4l2_ctrl *brightness;
45 struct v4l2_ctrl *contrast;
46 };
47 struct { /* autogain/exposure control cluster */
48 struct v4l2_ctrl *autogain;
49 struct v4l2_ctrl *exposure;
50 };
51 struct v4l2_ctrl *plfreq;
52 struct v4l2_ctrl *sharpness;
53 struct v4l2_ctrl *jpegqual;
58 54
59 struct work_struct work; 55 struct work_struct work;
60 struct workqueue_struct *work_thread; 56 struct workqueue_struct *work_thread;
@@ -94,114 +90,6 @@ enum sensors {
94 SENSOR_MAX 90 SENSOR_MAX
95}; 91};
96 92
97/* V4L2 controls supported by the driver */
98static void setcontrast(struct gspca_dev *gspca_dev);
99static void setexposure(struct gspca_dev *gspca_dev);
100static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
101static void setlightfreq(struct gspca_dev *gspca_dev);
102static void setsharpness(struct gspca_dev *gspca_dev);
103static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val);
104
105static const struct ctrl sd_ctrls[NCTRLS] = {
106[BRIGHTNESS] = {
107 {
108 .id = V4L2_CID_BRIGHTNESS,
109 .type = V4L2_CTRL_TYPE_INTEGER,
110 .name = "Brightness",
111 .minimum = 0,
112 .maximum = 255,
113 .step = 1,
114 .default_value = 128,
115 },
116 .set_control = setcontrast
117 },
118[CONTRAST] = {
119 {
120 .id = V4L2_CID_CONTRAST,
121 .type = V4L2_CTRL_TYPE_INTEGER,
122 .name = "Contrast",
123 .minimum = 0,
124 .maximum = 255,
125 .step = 1,
126 .default_value = 128,
127 },
128 .set_control = setcontrast
129 },
130[EXPOSURE] = {
131 {
132 .id = V4L2_CID_EXPOSURE,
133 .type = V4L2_CTRL_TYPE_INTEGER,
134 .name = "Exposure",
135 .minimum = 0x30d,
136 .maximum = 0x493e,
137 .step = 1,
138 .default_value = 0x927
139 },
140 .set_control = setexposure
141 },
142[GAMMA] = {
143 {
144 .id = V4L2_CID_GAMMA,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Gamma",
147 .minimum = 1,
148 .maximum = 6,
149 .step = 1,
150 .default_value = 4,
151 },
152 .set_control = setcontrast
153 },
154[AUTOGAIN] = {
155 {
156 .id = V4L2_CID_AUTOGAIN,
157 .type = V4L2_CTRL_TYPE_BOOLEAN,
158 .name = "Auto Gain",
159 .minimum = 0,
160 .maximum = 1,
161 .step = 1,
162 .default_value = AUTOGAIN_DEF,
163 .flags = V4L2_CTRL_FLAG_UPDATE
164 },
165 .set = sd_setautogain
166 },
167[LIGHTFREQ] = {
168 {
169 .id = V4L2_CID_POWER_LINE_FREQUENCY,
170 .type = V4L2_CTRL_TYPE_MENU,
171 .name = "Light frequency filter",
172 .minimum = 0,
173 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
174 .step = 1,
175 .default_value = 0,
176 },
177 .set_control = setlightfreq
178 },
179[SHARPNESS] = {
180 {
181 .id = V4L2_CID_SHARPNESS,
182 .type = V4L2_CTRL_TYPE_INTEGER,
183 .name = "Sharpness",
184 .minimum = 0,
185 .maximum = 3,
186 .step = 1,
187 .default_value = 2,
188 },
189 .set_control = setsharpness
190 },
191[QUALITY] = {
192 {
193 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Compression Quality",
196 .minimum = 40,
197 .maximum = 70,
198 .step = 1,
199 .default_value = 70 /* updated in sd_init() */
200 },
201 .set = sd_setquality
202 },
203};
204
205static const struct v4l2_pix_format vga_mode[] = { 93static const struct v4l2_pix_format vga_mode[] = {
206 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 94 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
207 .bytesperline = 320, 95 .bytesperline = 320,
@@ -241,8 +129,11 @@ static const struct v4l2_pix_format sif_mode[] = {
241 .priv = 0}, 129 .priv = 0},
242}; 130};
243 131
244/* bridge reg08 -> JPEG quality conversion table */ 132/*
245static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/}; 133 * Bridge reg08 bits 1-2 -> JPEG quality conversion table. Note the highest
134 * quality setting is not usable as USB 1 does not have enough bandwidth.
135 */
136static u8 jpeg_qual[] = {50, 75, 87, /* 94 */};
246 137
247/* usb exchanges */ 138/* usb exchanges */
248struct usb_action { 139struct usb_action {
@@ -5818,10 +5709,8 @@ static void setmatrix(struct gspca_dev *gspca_dev)
5818 reg_w(gspca_dev, matrix[i], 0x010a + i); 5709 reg_w(gspca_dev, matrix[i], 0x010a + i);
5819} 5710}
5820 5711
5821static void setsharpness(struct gspca_dev *gspca_dev) 5712static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
5822{ 5713{
5823 struct sd *sd = (struct sd *) gspca_dev;
5824 int sharpness;
5825 static const u8 sharpness_tb[][2] = { 5714 static const u8 sharpness_tb[][2] = {
5826 {0x02, 0x03}, 5715 {0x02, 0x03},
5827 {0x04, 0x07}, 5716 {0x04, 0x07},
@@ -5829,19 +5718,18 @@ static void setsharpness(struct gspca_dev *gspca_dev)
5829 {0x10, 0x1e} 5718 {0x10, 0x1e}
5830 }; 5719 };
5831 5720
5832 sharpness = sd->ctrls[SHARPNESS].val; 5721 reg_w(gspca_dev, sharpness_tb[val][0], 0x01c6);
5833 reg_w(gspca_dev, sharpness_tb[sharpness][0], 0x01c6);
5834 reg_r(gspca_dev, 0x01c8); 5722 reg_r(gspca_dev, 0x01c8);
5835 reg_r(gspca_dev, 0x01c9); 5723 reg_r(gspca_dev, 0x01c9);
5836 reg_r(gspca_dev, 0x01ca); 5724 reg_r(gspca_dev, 0x01ca);
5837 reg_w(gspca_dev, sharpness_tb[sharpness][1], 0x01cb); 5725 reg_w(gspca_dev, sharpness_tb[val][1], 0x01cb);
5838} 5726}
5839 5727
5840static void setcontrast(struct gspca_dev *gspca_dev) 5728static void setcontrast(struct gspca_dev *gspca_dev,
5729 s32 gamma, s32 brightness, s32 contrast)
5841{ 5730{
5842 struct sd *sd = (struct sd *) gspca_dev;
5843 const u8 *Tgamma; 5731 const u8 *Tgamma;
5844 int g, i, brightness, contrast, adj, gp1, gp2; 5732 int g, i, adj, gp1, gp2;
5845 u8 gr[16]; 5733 u8 gr[16];
5846 static const u8 delta_b[16] = /* delta for brightness */ 5734 static const u8 delta_b[16] = /* delta for brightness */
5847 {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d, 5735 {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
@@ -5864,10 +5752,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
5864 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}, 5752 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
5865 }; 5753 };
5866 5754
5867 Tgamma = gamma_tb[sd->ctrls[GAMMA].val - 1]; 5755 Tgamma = gamma_tb[gamma - 1];
5868 5756
5869 contrast = ((int) sd->ctrls[CONTRAST].val - 128); /* -128 / 127 */ 5757 contrast -= 128; /* -128 / 127 */
5870 brightness = ((int) sd->ctrls[BRIGHTNESS].val - 128); /* -128 / 92 */ 5758 brightness -= 128; /* -128 / 92 */
5871 adj = 0; 5759 adj = 0;
5872 gp1 = gp2 = 0; 5760 gp1 = gp2 = 0;
5873 for (i = 0; i < 16; i++) { 5761 for (i = 0; i < 16; i++) {
@@ -5894,25 +5782,15 @@ static void setcontrast(struct gspca_dev *gspca_dev)
5894 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */ 5782 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */
5895} 5783}
5896 5784
5897static void getexposure(struct gspca_dev *gspca_dev) 5785static s32 getexposure(struct gspca_dev *gspca_dev)
5898{ 5786{
5899 struct sd *sd = (struct sd *) gspca_dev; 5787 return (i2c_read(gspca_dev, 0x25) << 9)
5900
5901 if (sd->sensor != SENSOR_HV7131R)
5902 return;
5903 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
5904 | (i2c_read(gspca_dev, 0x26) << 1) 5788 | (i2c_read(gspca_dev, 0x26) << 1)
5905 | (i2c_read(gspca_dev, 0x27) >> 7); 5789 | (i2c_read(gspca_dev, 0x27) >> 7);
5906} 5790}
5907 5791
5908static void setexposure(struct gspca_dev *gspca_dev) 5792static void setexposure(struct gspca_dev *gspca_dev, s32 val)
5909{ 5793{
5910 struct sd *sd = (struct sd *) gspca_dev;
5911 int val;
5912
5913 if (sd->sensor != SENSOR_HV7131R)
5914 return;
5915 val = sd->ctrls[EXPOSURE].val;
5916 i2c_write(gspca_dev, 0x25, val >> 9, 0x00); 5794 i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
5917 i2c_write(gspca_dev, 0x26, val >> 1, 0x00); 5795 i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
5918 i2c_write(gspca_dev, 0x27, val << 7, 0x00); 5796 i2c_write(gspca_dev, 0x27, val << 7, 0x00);
@@ -5921,20 +5799,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
5921static void setquality(struct gspca_dev *gspca_dev) 5799static void setquality(struct gspca_dev *gspca_dev)
5922{ 5800{
5923 struct sd *sd = (struct sd *) gspca_dev; 5801 struct sd *sd = (struct sd *) gspca_dev;
5924 s8 reg07; 5802 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08 >> 1]);
5925
5926 reg07 = 0;
5927 switch (sd->sensor) {
5928 case SENSOR_OV7620:
5929 reg07 = 0x30;
5930 break;
5931 case SENSOR_HV7131R:
5932 case SENSOR_PAS202B:
5933 return; /* done by work queue */
5934 }
5935 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); 5803 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
5936 if (reg07 != 0)
5937 reg_w(gspca_dev, reg07, 0x0007);
5938} 5804}
5939 5805
5940/* Matches the sensor's internal frame rate to the lighting frequency. 5806/* Matches the sensor's internal frame rate to the lighting frequency.
@@ -5943,7 +5809,7 @@ static void setquality(struct gspca_dev *gspca_dev)
5943 * 60Hz, for American lighting 5809 * 60Hz, for American lighting
5944 * 0 = No Fliker (for outdoore usage) 5810 * 0 = No Fliker (for outdoore usage)
5945 */ 5811 */
5946static void setlightfreq(struct gspca_dev *gspca_dev) 5812static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
5947{ 5813{
5948 struct sd *sd = (struct sd *) gspca_dev; 5814 struct sd *sd = (struct sd *) gspca_dev;
5949 int i, mode; 5815 int i, mode;
@@ -6027,7 +5893,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
6027 tas5130c_60HZ, tas5130c_60HZScale}, 5893 tas5130c_60HZ, tas5130c_60HZScale},
6028 }; 5894 };
6029 5895
6030 i = sd->ctrls[LIGHTFREQ].val * 2; 5896 i = val * 2;
6031 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 5897 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6032 if (mode) 5898 if (mode)
6033 i++; /* 320x240 */ 5899 i++; /* 320x240 */
@@ -6037,14 +5903,14 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
6037 usb_exchange(gspca_dev, zc3_freq); 5903 usb_exchange(gspca_dev, zc3_freq);
6038 switch (sd->sensor) { 5904 switch (sd->sensor) {
6039 case SENSOR_GC0305: 5905 case SENSOR_GC0305:
6040 if (mode /* if 320x240 */ 5906 if (mode /* if 320x240 */
6041 && sd->ctrls[LIGHTFREQ].val == 1) /* and 50Hz */ 5907 && val == 1) /* and 50Hz */
6042 reg_w(gspca_dev, 0x85, 0x018d); 5908 reg_w(gspca_dev, 0x85, 0x018d);
6043 /* win: 0x80, 0x018d */ 5909 /* win: 0x80, 0x018d */
6044 break; 5910 break;
6045 case SENSOR_OV7620: 5911 case SENSOR_OV7620:
6046 if (!mode) { /* if 640x480 */ 5912 if (!mode) { /* if 640x480 */
6047 if (sd->ctrls[LIGHTFREQ].val != 0) /* and filter */ 5913 if (val != 0) /* and filter */
6048 reg_w(gspca_dev, 0x40, 0x0002); 5914 reg_w(gspca_dev, 0x40, 0x0002);
6049 else 5915 else
6050 reg_w(gspca_dev, 0x44, 0x0002); 5916 reg_w(gspca_dev, 0x44, 0x0002);
@@ -6056,22 +5922,15 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
6056 } 5922 }
6057} 5923}
6058 5924
6059static void setautogain(struct gspca_dev *gspca_dev) 5925static void setautogain(struct gspca_dev *gspca_dev, s32 val)
6060{ 5926{
6061 struct sd *sd = (struct sd *) gspca_dev; 5927 reg_w(gspca_dev, val ? 0x42 : 0x02, 0x0180);
6062 u8 autoval;
6063
6064 if (sd->ctrls[AUTOGAIN].val)
6065 autoval = 0x42;
6066 else
6067 autoval = 0x02;
6068 reg_w(gspca_dev, autoval, 0x0180);
6069} 5928}
6070 5929
6071/* update the transfer parameters */ 5930/*
6072/* This function is executed from a work queue. */ 5931 * Update the transfer parameters.
6073/* The exact use of the bridge registers 07 and 08 is not known. 5932 * This function is executed from a work queue.
6074 * The following algorithm has been adapted from ms-win traces */ 5933 */
6075static void transfer_update(struct work_struct *work) 5934static void transfer_update(struct work_struct *work)
6076{ 5935{
6077 struct sd *sd = container_of(work, struct sd, work); 5936 struct sd *sd = container_of(work, struct sd, work);
@@ -6079,96 +5938,55 @@ static void transfer_update(struct work_struct *work)
6079 int change, good; 5938 int change, good;
6080 u8 reg07, reg11; 5939 u8 reg07, reg11;
6081 5940
6082 /* synchronize with the main driver and initialize the registers */ 5941 /* reg07 gets set to 0 by sd_start before starting us */
6083 mutex_lock(&gspca_dev->usb_lock); 5942 reg07 = 0;
6084 reg07 = 0; /* max */
6085 reg_w(gspca_dev, reg07, 0x0007);
6086 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
6087 mutex_unlock(&gspca_dev->usb_lock);
6088 5943
6089 good = 0; 5944 good = 0;
6090 for (;;) { 5945 for (;;) {
6091 msleep(100); 5946 msleep(100);
6092 5947
6093 /* get the transfer status */
6094 /* the bit 0 of the bridge register 11 indicates overflow */
6095 mutex_lock(&gspca_dev->usb_lock); 5948 mutex_lock(&gspca_dev->usb_lock);
6096 if (!gspca_dev->present || !gspca_dev->streaming) 5949#ifdef CONFIG_PM
5950 if (gspca_dev->frozen)
6097 goto err; 5951 goto err;
5952#endif
5953 if (!gspca_dev->dev || !gspca_dev->streaming)
5954 goto err;
5955
5956 /* Bit 0 of register 11 indicates FIFO overflow */
5957 gspca_dev->usb_err = 0;
6098 reg11 = reg_r(gspca_dev, 0x0011); 5958 reg11 = reg_r(gspca_dev, 0x0011);
6099 if (gspca_dev->usb_err < 0 5959 if (gspca_dev->usb_err)
6100 || !gspca_dev->present || !gspca_dev->streaming)
6101 goto err; 5960 goto err;
6102 5961
6103 change = reg11 & 0x01; 5962 change = reg11 & 0x01;
6104 if (change) { /* overflow */ 5963 if (change) { /* overflow */
6105 switch (reg07) {
6106 case 0: /* max */
6107 reg07 = sd->sensor == SENSOR_HV7131R
6108 ? 0x30 : 0x32;
6109 if (sd->reg08 != 0) {
6110 change = 3;
6111 sd->reg08--;
6112 }
6113 break;
6114 case 0x32:
6115 reg07 -= 4;
6116 break;
6117 default:
6118 reg07 -= 2;
6119 break;
6120 case 2:
6121 change = 0; /* already min */
6122 break;
6123 }
6124 good = 0; 5964 good = 0;
5965
5966 if (reg07 == 0) /* Bit Rate Control not enabled? */
5967 reg07 = 0x32; /* Allow 98 bytes / unit */
5968 else if (reg07 > 2)
5969 reg07 -= 2; /* Decrease allowed bytes / unit */
5970 else
5971 change = 0;
6125 } else { /* no overflow */ 5972 } else { /* no overflow */
6126 if (reg07 != 0) { /* if not max */ 5973 good++;
6127 good++; 5974 if (good >= 10) {
6128 if (good >= 10) { 5975 good = 0;
6129 good = 0; 5976 if (reg07) { /* BRC enabled? */
6130 change = 1; 5977 change = 1;
6131 reg07 += 2; 5978 if (reg07 < 0x32)
6132 switch (reg07) { 5979 reg07 += 2;
6133 case 0x30: 5980 else
6134 if (sd->sensor == SENSOR_PAS202B)
6135 reg07 += 2;
6136 break;
6137 case 0x32:
6138 case 0x34:
6139 reg07 = 0; 5981 reg07 = 0;
6140 break;
6141 }
6142 }
6143 } else { /* reg07 max */
6144 if (sd->reg08 < sizeof jpeg_qual - 1) {
6145 good++;
6146 if (good > 10) {
6147 sd->reg08++;
6148 change = 2;
6149 }
6150 } 5982 }
6151 } 5983 }
6152 } 5984 }
6153 if (change) { 5985 if (change) {
6154 if (change & 1) { 5986 gspca_dev->usb_err = 0;
6155 reg_w(gspca_dev, reg07, 0x0007); 5987 reg_w(gspca_dev, reg07, 0x0007);
6156 if (gspca_dev->usb_err < 0 5988 if (gspca_dev->usb_err)
6157 || !gspca_dev->present 5989 goto err;
6158 || !gspca_dev->streaming)
6159 goto err;
6160 }
6161 if (change & 2) {
6162 reg_w(gspca_dev, sd->reg08,
6163 ZC3XX_R008_CLOCKSETTING);
6164 if (gspca_dev->usb_err < 0
6165 || !gspca_dev->present
6166 || !gspca_dev->streaming)
6167 goto err;
6168 sd->ctrls[QUALITY].val = jpeg_qual[sd->reg08];
6169 jpeg_set_qual(sd->jpeg_hdr,
6170 jpeg_qual[sd->reg08]);
6171 }
6172 } 5990 }
6173 mutex_unlock(&gspca_dev->usb_lock); 5991 mutex_unlock(&gspca_dev->usb_lock);
6174 } 5992 }
@@ -6503,7 +6321,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
6503 /* define some sensors from the vendor/product */ 6321 /* define some sensors from the vendor/product */
6504 sd->sensor = id->driver_info; 6322 sd->sensor = id->driver_info;
6505 6323
6506 gspca_dev->cam.ctrls = sd->ctrls;
6507 sd->reg08 = REG08_DEF; 6324 sd->reg08 = REG08_DEF;
6508 6325
6509 INIT_WORK(&sd->work, transfer_update); 6326 INIT_WORK(&sd->work, transfer_update);
@@ -6511,12 +6328,87 @@ static int sd_config(struct gspca_dev *gspca_dev,
6511 return 0; 6328 return 0;
6512} 6329}
6513 6330
6514/* this function is called at probe and resume time */ 6331static int zcxx_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
6515static int sd_init(struct gspca_dev *gspca_dev)
6516{ 6332{
6517 struct sd *sd = (struct sd *) gspca_dev; 6333 struct gspca_dev *gspca_dev =
6518 struct cam *cam; 6334 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
6519 int sensor; 6335 struct sd *sd = (struct sd *)gspca_dev;
6336
6337 switch (ctrl->id) {
6338 case V4L2_CID_AUTOGAIN:
6339 gspca_dev->usb_err = 0;
6340 if (ctrl->val && sd->exposure && gspca_dev->streaming)
6341 sd->exposure->val = getexposure(gspca_dev);
6342 return gspca_dev->usb_err;
6343 }
6344 return -EINVAL;
6345}
6346
6347static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl)
6348{
6349 struct gspca_dev *gspca_dev =
6350 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
6351 struct sd *sd = (struct sd *)gspca_dev;
6352 int i, qual;
6353
6354 gspca_dev->usb_err = 0;
6355
6356 if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY) {
6357 qual = sd->reg08 >> 1;
6358
6359 for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) {
6360 if (ctrl->val <= jpeg_qual[i])
6361 break;
6362 }
6363 if (i > 0 && i == qual && ctrl->val < jpeg_qual[i])
6364 i--;
6365
6366 /* With high quality settings we need max bandwidth */
6367 if (i >= 2 && gspca_dev->streaming &&
6368 !gspca_dev->cam.needs_full_bandwidth)
6369 return -EBUSY;
6370
6371 sd->reg08 = (i << 1) | 1;
6372 ctrl->val = jpeg_qual[i];
6373 }
6374
6375 if (!gspca_dev->streaming)
6376 return 0;
6377
6378 switch (ctrl->id) {
6379 /* gamma/brightness/contrast cluster */
6380 case V4L2_CID_GAMMA:
6381 setcontrast(gspca_dev, sd->gamma->val,
6382 sd->brightness->val, sd->contrast->val);
6383 break;
6384 /* autogain/exposure cluster */
6385 case V4L2_CID_AUTOGAIN:
6386 setautogain(gspca_dev, ctrl->val);
6387 if (!gspca_dev->usb_err && !ctrl->val && sd->exposure)
6388 setexposure(gspca_dev, sd->exposure->val);
6389 break;
6390 case V4L2_CID_POWER_LINE_FREQUENCY:
6391 setlightfreq(gspca_dev, ctrl->val);
6392 break;
6393 case V4L2_CID_SHARPNESS:
6394 setsharpness(gspca_dev, ctrl->val);
6395 break;
6396 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
6397 setquality(gspca_dev);
6398 break;
6399 }
6400 return gspca_dev->usb_err;
6401}
6402
6403static const struct v4l2_ctrl_ops zcxx_ctrl_ops = {
6404 .g_volatile_ctrl = zcxx_g_volatile_ctrl,
6405 .s_ctrl = zcxx_s_ctrl,
6406};
6407
6408static int sd_init_controls(struct gspca_dev *gspca_dev)
6409{
6410 struct sd *sd = (struct sd *)gspca_dev;
6411 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
6520 static const u8 gamma[SENSOR_MAX] = { 6412 static const u8 gamma[SENSOR_MAX] = {
6521 [SENSOR_ADCM2700] = 4, 6413 [SENSOR_ADCM2700] = 4,
6522 [SENSOR_CS2102] = 4, 6414 [SENSOR_CS2102] = 4,
@@ -6538,6 +6430,48 @@ static int sd_init(struct gspca_dev *gspca_dev)
6538 [SENSOR_PO2030] = 4, 6430 [SENSOR_PO2030] = 4,
6539 [SENSOR_TAS5130C] = 3, 6431 [SENSOR_TAS5130C] = 3,
6540 }; 6432 };
6433
6434 gspca_dev->vdev.ctrl_handler = hdl;
6435 v4l2_ctrl_handler_init(hdl, 8);
6436 sd->brightness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6437 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
6438 sd->contrast = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6439 V4L2_CID_CONTRAST, 0, 255, 1, 128);
6440 sd->gamma = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6441 V4L2_CID_GAMMA, 1, 6, 1, gamma[sd->sensor]);
6442 if (sd->sensor == SENSOR_HV7131R)
6443 sd->exposure = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6444 V4L2_CID_EXPOSURE, 0x30d, 0x493e, 1, 0x927);
6445 sd->autogain = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6446 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
6447 if (sd->sensor != SENSOR_OV7630C)
6448 sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &zcxx_ctrl_ops,
6449 V4L2_CID_POWER_LINE_FREQUENCY,
6450 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
6451 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
6452 sd->sharpness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6453 V4L2_CID_SHARPNESS, 0, 3, 1,
6454 sd->sensor == SENSOR_PO2030 ? 0 : 2);
6455 sd->jpegqual = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
6456 V4L2_CID_JPEG_COMPRESSION_QUALITY,
6457 jpeg_qual[0], jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1], 1,
6458 jpeg_qual[REG08_DEF >> 1]);
6459 if (hdl->error) {
6460 pr_err("Could not initialize controls\n");
6461 return hdl->error;
6462 }
6463 v4l2_ctrl_cluster(3, &sd->gamma);
6464 if (sd->sensor == SENSOR_HV7131R)
6465 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true);
6466 return 0;
6467}
6468
6469/* this function is called at probe and resume time */
6470static int sd_init(struct gspca_dev *gspca_dev)
6471{
6472 struct sd *sd = (struct sd *) gspca_dev;
6473 struct cam *cam;
6474 int sensor;
6541 static const u8 mode_tb[SENSOR_MAX] = { 6475 static const u8 mode_tb[SENSOR_MAX] = {
6542 [SENSOR_ADCM2700] = 2, 6476 [SENSOR_ADCM2700] = 2,
6543 [SENSOR_CS2102] = 1, 6477 [SENSOR_CS2102] = 1,
@@ -6559,27 +6493,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
6559 [SENSOR_PO2030] = 1, 6493 [SENSOR_PO2030] = 1,
6560 [SENSOR_TAS5130C] = 1, 6494 [SENSOR_TAS5130C] = 1,
6561 }; 6495 };
6562 static const u8 reg08_tb[SENSOR_MAX] = {
6563 [SENSOR_ADCM2700] = 1,
6564 [SENSOR_CS2102] = 3,
6565 [SENSOR_CS2102K] = 3,
6566 [SENSOR_GC0303] = 2,
6567 [SENSOR_GC0305] = 3,
6568 [SENSOR_HDCS2020] = 1,
6569 [SENSOR_HV7131B] = 3,
6570 [SENSOR_HV7131R] = 3,
6571 [SENSOR_ICM105A] = 3,
6572 [SENSOR_MC501CB] = 3,
6573 [SENSOR_MT9V111_1] = 3,
6574 [SENSOR_MT9V111_3] = 3,
6575 [SENSOR_OV7620] = 1,
6576 [SENSOR_OV7630C] = 3,
6577 [SENSOR_PAS106] = 3,
6578 [SENSOR_PAS202B] = 3,
6579 [SENSOR_PB0330] = 3,
6580 [SENSOR_PO2030] = 2,
6581 [SENSOR_TAS5130C] = 3,
6582 };
6583 6496
6584 sensor = zcxx_probeSensor(gspca_dev); 6497 sensor = zcxx_probeSensor(gspca_dev);
6585 if (sensor >= 0) 6498 if (sensor >= 0)
@@ -6688,7 +6601,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
6688 case 0x2030: 6601 case 0x2030:
6689 PDEBUG(D_PROBE, "Find Sensor PO2030"); 6602 PDEBUG(D_PROBE, "Find Sensor PO2030");
6690 sd->sensor = SENSOR_PO2030; 6603 sd->sensor = SENSOR_PO2030;
6691 sd->ctrls[SHARPNESS].def = 0; /* from win traces */
6692 break; 6604 break;
6693 case 0x7620: 6605 case 0x7620:
6694 PDEBUG(D_PROBE, "Find Sensor OV7620"); 6606 PDEBUG(D_PROBE, "Find Sensor OV7620");
@@ -6730,36 +6642,18 @@ static int sd_init(struct gspca_dev *gspca_dev)
6730 break; 6642 break;
6731 } 6643 }
6732 6644
6733 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6734 sd->reg08 = reg08_tb[sd->sensor];
6735 sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08];
6736 sd->ctrls[QUALITY].min = jpeg_qual[0];
6737 sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1];
6738
6739 switch (sd->sensor) {
6740 case SENSOR_HV7131R:
6741 gspca_dev->ctrl_dis = (1 << QUALITY);
6742 break;
6743 case SENSOR_OV7630C:
6744 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6745 break;
6746 case SENSOR_PAS202B:
6747 gspca_dev->ctrl_dis = (1 << QUALITY) | (1 << EXPOSURE);
6748 break;
6749 default:
6750 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6751 break;
6752 }
6753#if AUTOGAIN_DEF
6754 if (sd->ctrls[AUTOGAIN].val)
6755 gspca_dev->ctrl_inac = (1 << EXPOSURE);
6756#endif
6757
6758 /* switch off the led */ 6645 /* switch off the led */
6759 reg_w(gspca_dev, 0x01, 0x0000); 6646 reg_w(gspca_dev, 0x01, 0x0000);
6760 return gspca_dev->usb_err; 6647 return gspca_dev->usb_err;
6761} 6648}
6762 6649
6650static int sd_pre_start(struct gspca_dev *gspca_dev)
6651{
6652 struct sd *sd = (struct sd *) gspca_dev;
6653 gspca_dev->cam.needs_full_bandwidth = (sd->reg08 >= 4) ? 1 : 0;
6654 return 0;
6655}
6656
6763static int sd_start(struct gspca_dev *gspca_dev) 6657static int sd_start(struct gspca_dev *gspca_dev)
6764{ 6658{
6765 struct sd *sd = (struct sd *) gspca_dev; 6659 struct sd *sd = (struct sd *) gspca_dev;
@@ -6864,7 +6758,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6864 reg_w(gspca_dev, 0x03, 0x0008); 6758 reg_w(gspca_dev, 0x03, 0x0008);
6865 break; 6759 break;
6866 } 6760 }
6867 setsharpness(gspca_dev); 6761 setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
6868 6762
6869 /* set the gamma tables when not set */ 6763 /* set the gamma tables when not set */
6870 switch (sd->sensor) { 6764 switch (sd->sensor) {
@@ -6873,7 +6767,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
6873 case SENSOR_OV7630C: 6767 case SENSOR_OV7630C:
6874 break; 6768 break;
6875 default: 6769 default:
6876 setcontrast(gspca_dev); 6770 setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma),
6771 v4l2_ctrl_g_ctrl(sd->brightness),
6772 v4l2_ctrl_g_ctrl(sd->contrast));
6877 break; 6773 break;
6878 } 6774 }
6879 setmatrix(gspca_dev); /* one more time? */ 6775 setmatrix(gspca_dev); /* one more time? */
@@ -6885,8 +6781,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
6885 break; 6781 break;
6886 } 6782 }
6887 setquality(gspca_dev); 6783 setquality(gspca_dev);
6888 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]); 6784 /* Start with BRC disabled, transfer_update will enable it if needed */
6889 setlightfreq(gspca_dev); 6785 reg_w(gspca_dev, 0x00, 0x0007);
6786 if (sd->plfreq)
6787 setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq));
6890 6788
6891 switch (sd->sensor) { 6789 switch (sd->sensor) {
6892 case SENSOR_ADCM2700: 6790 case SENSOR_ADCM2700:
@@ -6897,7 +6795,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6897 reg_w(gspca_dev, 0x40, 0x0117); 6795 reg_w(gspca_dev, 0x40, 0x0117);
6898 break; 6796 break;
6899 case SENSOR_HV7131R: 6797 case SENSOR_HV7131R:
6900 setexposure(gspca_dev); 6798 setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
6901 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6799 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
6902 break; 6800 break;
6903 case SENSOR_GC0305: 6801 case SENSOR_GC0305:
@@ -6921,21 +6819,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
6921 break; 6819 break;
6922 } 6820 }
6923 6821
6924 setautogain(gspca_dev); 6822 setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
6925 6823
6926 /* start the transfer update thread if needed */ 6824 if (gspca_dev->usb_err < 0)
6927 if (gspca_dev->usb_err >= 0) { 6825 return gspca_dev->usb_err;
6928 switch (sd->sensor) {
6929 case SENSOR_HV7131R:
6930 case SENSOR_PAS202B:
6931 sd->work_thread =
6932 create_singlethread_workqueue(KBUILD_MODNAME);
6933 queue_work(sd->work_thread, &sd->work);
6934 break;
6935 }
6936 }
6937 6826
6938 return gspca_dev->usb_err; 6827 /* Start the transfer parameters update thread */
6828 sd->work_thread = create_singlethread_workqueue(KBUILD_MODNAME);
6829 queue_work(sd->work_thread, &sd->work);
6830
6831 return 0;
6939} 6832}
6940 6833
6941/* called on streamoff with alt 0 and on disconnect */ 6834/* called on streamoff with alt 0 and on disconnect */
@@ -6949,7 +6842,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
6949 mutex_lock(&gspca_dev->usb_lock); 6842 mutex_lock(&gspca_dev->usb_lock);
6950 sd->work_thread = NULL; 6843 sd->work_thread = NULL;
6951 } 6844 }
6952 if (!gspca_dev->present) 6845 if (!gspca_dev->dev)
6953 return; 6846 return;
6954 send_unknown(gspca_dev, sd->sensor); 6847 send_unknown(gspca_dev, sd->sensor);
6955} 6848}
@@ -6987,72 +6880,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
6987 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 6880 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
6988} 6881}
6989 6882
6990static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
6991{
6992 struct sd *sd = (struct sd *) gspca_dev;
6993
6994 sd->ctrls[AUTOGAIN].val = val;
6995 if (val) {
6996 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
6997 } else {
6998 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
6999 if (gspca_dev->streaming)
7000 getexposure(gspca_dev);
7001 }
7002 if (gspca_dev->streaming)
7003 setautogain(gspca_dev);
7004 return gspca_dev->usb_err;
7005}
7006
7007static int sd_querymenu(struct gspca_dev *gspca_dev,
7008 struct v4l2_querymenu *menu)
7009{
7010 switch (menu->id) {
7011 case V4L2_CID_POWER_LINE_FREQUENCY:
7012 switch (menu->index) {
7013 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
7014 strcpy((char *) menu->name, "NoFliker");
7015 return 0;
7016 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
7017 strcpy((char *) menu->name, "50 Hz");
7018 return 0;
7019 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
7020 strcpy((char *) menu->name, "60 Hz");
7021 return 0;
7022 }
7023 break;
7024 }
7025 return -EINVAL;
7026}
7027
7028static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val)
7029{
7030 struct sd *sd = (struct sd *) gspca_dev;
7031 int i;
7032
7033 for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
7034 if (val <= jpeg_qual[i])
7035 break;
7036 }
7037 if (i > 0
7038 && i == sd->reg08
7039 && val < jpeg_qual[sd->reg08])
7040 i--;
7041 sd->reg08 = i;
7042 sd->ctrls[QUALITY].val = jpeg_qual[i];
7043 if (gspca_dev->streaming)
7044 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
7045 return gspca_dev->usb_err;
7046}
7047
7048static int sd_set_jcomp(struct gspca_dev *gspca_dev, 6883static int sd_set_jcomp(struct gspca_dev *gspca_dev,
7049 struct v4l2_jpegcompression *jcomp) 6884 struct v4l2_jpegcompression *jcomp)
7050{ 6885{
7051 struct sd *sd = (struct sd *) gspca_dev; 6886 struct sd *sd = (struct sd *) gspca_dev;
6887 int ret;
7052 6888
7053 sd_setquality(gspca_dev, jcomp->quality); 6889 ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
7054 jcomp->quality = sd->ctrls[QUALITY].val; 6890 if (ret)
7055 return gspca_dev->usb_err; 6891 return ret;
6892 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
6893 return 0;
7056} 6894}
7057 6895
7058static int sd_get_jcomp(struct gspca_dev *gspca_dev, 6896static int sd_get_jcomp(struct gspca_dev *gspca_dev,
@@ -7061,7 +6899,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
7061 struct sd *sd = (struct sd *) gspca_dev; 6899 struct sd *sd = (struct sd *) gspca_dev;
7062 6900
7063 memset(jcomp, 0, sizeof *jcomp); 6901 memset(jcomp, 0, sizeof *jcomp);
7064 jcomp->quality = sd->ctrls[QUALITY].val; 6902 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
7065 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 6903 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
7066 | V4L2_JPEG_MARKER_DQT; 6904 | V4L2_JPEG_MARKER_DQT;
7067 return 0; 6905 return 0;
@@ -7085,14 +6923,13 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
7085 6923
7086static const struct sd_desc sd_desc = { 6924static const struct sd_desc sd_desc = {
7087 .name = KBUILD_MODNAME, 6925 .name = KBUILD_MODNAME,
7088 .ctrls = sd_ctrls,
7089 .nctrls = ARRAY_SIZE(sd_ctrls),
7090 .config = sd_config, 6926 .config = sd_config,
7091 .init = sd_init, 6927 .init = sd_init,
6928 .init_controls = sd_init_controls,
6929 .isoc_init = sd_pre_start,
7092 .start = sd_start, 6930 .start = sd_start,
7093 .stop0 = sd_stop0, 6931 .stop0 = sd_stop0,
7094 .pkt_scan = sd_pkt_scan, 6932 .pkt_scan = sd_pkt_scan,
7095 .querymenu = sd_querymenu,
7096 .get_jcomp = sd_get_jcomp, 6933 .get_jcomp = sd_get_jcomp,
7097 .set_jcomp = sd_set_jcomp, 6934 .set_jcomp = sd_set_jcomp,
7098#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 6935#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
@@ -7176,6 +7013,7 @@ static struct usb_driver sd_driver = {
7176#ifdef CONFIG_PM 7013#ifdef CONFIG_PM
7177 .suspend = gspca_suspend, 7014 .suspend = gspca_suspend,
7178 .resume = gspca_resume, 7015 .resume = gspca_resume,
7016 .reset_resume = gspca_resume,
7179#endif 7017#endif
7180}; 7018};
7181 7019
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
index 068df4ba3f51..ae8f229d1141 100644
--- a/drivers/media/video/hdpvr/hdpvr-control.c
+++ b/drivers/media/video/hdpvr/hdpvr-control.c
@@ -113,6 +113,8 @@ int get_input_lines_info(struct hdpvr_device *dev)
113 "get input lines info returned: %d, %s\n", ret, 113 "get input lines info returned: %d, %s\n", ret,
114 print_buf); 114 print_buf);
115 } 115 }
116#else
117 (void)ret; /* suppress compiler warning */
116#endif 118#endif
117 lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0]; 119 lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
118 mutex_unlock(&dev->usbc_mutex); 120 mutex_unlock(&dev->usbc_mutex);
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 11ffe9cc1780..0e9e156bb2aa 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -994,7 +994,7 @@ static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
994 default: 994 default:
995 return -EINVAL; 995 return -EINVAL;
996 } 996 }
997 return 0; 997 return ret;
998} 998}
999 999
1000static int vidioc_try_ext_ctrls(struct file *file, void *priv, 1000static int vidioc_try_ext_ctrls(struct file *file, void *priv,
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index a62322d5c0d8..366434f5647e 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -40,15 +40,15 @@ static int hexium_num;
40 40
41#define HEXIUM_INPUTS 9 41#define HEXIUM_INPUTS 9
42static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { 42static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
43 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 43 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
44 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 44 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
45 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 45 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
46 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 46 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
47 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 47 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
48 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 48 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
49 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 49 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
50 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 50 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
51 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 51 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
52}; 52};
53 53
54#define HEXIUM_AUDIOS 0 54#define HEXIUM_AUDIOS 0
@@ -59,11 +59,6 @@ struct hexium_data
59 u8 byte; 59 u8 byte;
60}; 60};
61 61
62#define HEXIUM_CONTROLS 1
63static struct v4l2_queryctrl hexium_controls[] = {
64 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
65};
66
67#define HEXIUM_GEMINI_V_1_0 1 62#define HEXIUM_GEMINI_V_1_0 1
68#define HEXIUM_GEMINI_DUAL_V_1_0 2 63#define HEXIUM_GEMINI_DUAL_V_1_0 2
69 64
@@ -76,7 +71,6 @@ struct hexium
76 71
77 int cur_input; /* current input */ 72 int cur_input; /* current input */
78 v4l2_std_id cur_std; /* current standard */ 73 v4l2_std_id cur_std; /* current standard */
79 int cur_bw; /* current black/white status */
80}; 74};
81 75
82/* Samsung KS0127B decoder default registers */ 76/* Samsung KS0127B decoder default registers */
@@ -119,18 +113,10 @@ static struct hexium_data hexium_pal[] = {
119 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF } 113 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
120}; 114};
121 115
122static struct hexium_data hexium_pal_bw[] = {
123 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
124};
125
126static struct hexium_data hexium_ntsc[] = { 116static struct hexium_data hexium_ntsc[] = {
127 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF } 117 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
128}; 118};
129 119
130static struct hexium_data hexium_ntsc_bw[] = {
131 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
132};
133
134static struct hexium_data hexium_secam[] = { 120static struct hexium_data hexium_secam[] = {
135 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF } 121 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
136}; 122};
@@ -264,93 +250,6 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
264 return 0; 250 return 0;
265} 251}
266 252
267/* the saa7146 provides some controls (brightness, contrast, saturation)
268 which gets registered *after* this function. because of this we have
269 to return with a value != 0 even if the function succeeded.. */
270static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
271{
272 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
273 int i;
274
275 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
276 if (hexium_controls[i].id == qc->id) {
277 *qc = hexium_controls[i];
278 DEB_D("VIDIOC_QUERYCTRL %d\n", qc->id);
279 return 0;
280 }
281 }
282 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
283}
284
285static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
286{
287 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
288 struct hexium *hexium = (struct hexium *) dev->ext_priv;
289 int i;
290
291 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
292 if (hexium_controls[i].id == vc->id)
293 break;
294 }
295
296 if (i < 0)
297 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
298
299 if (vc->id == V4L2_CID_PRIVATE_BASE) {
300 vc->value = hexium->cur_bw;
301 DEB_D("VIDIOC_G_CTRL BW:%d\n", vc->value);
302 return 0;
303 }
304 return -EINVAL;
305}
306
307static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
308{
309 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
310 struct hexium *hexium = (struct hexium *) dev->ext_priv;
311 int i = 0;
312
313 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
314 if (hexium_controls[i].id == vc->id)
315 break;
316 }
317
318 if (i < 0)
319 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
320
321 if (vc->id == V4L2_CID_PRIVATE_BASE)
322 hexium->cur_bw = vc->value;
323
324 DEB_D("VIDIOC_S_CTRL BW:%d\n", hexium->cur_bw);
325
326 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
327 hexium_set_standard(hexium, hexium_pal);
328 return 0;
329 }
330 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
331 hexium_set_standard(hexium, hexium_ntsc);
332 return 0;
333 }
334 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
335 hexium_set_standard(hexium, hexium_secam);
336 return 0;
337 }
338 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
339 hexium_set_standard(hexium, hexium_pal_bw);
340 return 0;
341 }
342 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
343 hexium_set_standard(hexium, hexium_ntsc_bw);
344 return 0;
345 }
346 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
347 /* fixme: is there no bw secam mode? */
348 return -EINVAL;
349
350 return -EINVAL;
351}
352
353
354static struct saa7146_ext_vv vv_data; 253static struct saa7146_ext_vv vv_data;
355 254
356/* this function only gets called when the probing was successful */ 255/* this function only gets called when the probing was successful */
@@ -399,12 +298,10 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
399 hexium->cur_input = 0; 298 hexium->cur_input = 0;
400 299
401 saa7146_vv_init(dev, &vv_data); 300 saa7146_vv_init(dev, &vv_data);
402 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl; 301
403 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl; 302 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
404 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl; 303 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
405 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 304 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
406 vv_data.ops.vidioc_g_input = vidioc_g_input;
407 vv_data.ops.vidioc_s_input = vidioc_s_input;
408 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER); 305 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
409 if (ret < 0) { 306 if (ret < 0) {
410 pr_err("cannot register capture v4l2 device. skipping.\n"); 307 pr_err("cannot register capture v4l2 device. skipping.\n");
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 23debc967d94..a1eb26d11070 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -41,15 +41,15 @@ static int hexium_num;
41 41
42#define HEXIUM_INPUTS 9 42#define HEXIUM_INPUTS 9
43static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { 43static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
44 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 44 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
45 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 45 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
46 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 46 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
47 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 47 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
48 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 48 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
49 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 49 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
50 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 50 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
51 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 51 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
52 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 52 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
53}; 53};
54 54
55#define HEXIUM_AUDIOS 0 55#define HEXIUM_AUDIOS 0
@@ -371,9 +371,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
371 DEB_EE("\n"); 371 DEB_EE("\n");
372 372
373 saa7146_vv_init(dev, &vv_data); 373 saa7146_vv_init(dev, &vv_data);
374 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 374 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
375 vv_data.ops.vidioc_g_input = vidioc_g_input; 375 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
376 vv_data.ops.vidioc_s_input = vidioc_s_input; 376 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
377 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) { 377 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
378 pr_err("cannot register capture v4l2 device. skipping.\n"); 378 pr_err("cannot register capture v4l2 device. skipping.\n");
379 return -1; 379 return -1;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 679262ed13bc..057929e165ab 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1201,9 +1201,9 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
1201 struct v4l2_ctrl_handler *hdl = itv->v4l2_dev.ctrl_handler; 1201 struct v4l2_ctrl_handler *hdl = itv->v4l2_dev.ctrl_handler;
1202 1202
1203 itv->ctrl_pts = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops, 1203 itv->ctrl_pts = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
1204 V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 1, 0); 1204 V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 0, 0);
1205 itv->ctrl_frame = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops, 1205 itv->ctrl_frame = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
1206 V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0x7fffffff, 1, 0); 1206 V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0, 0, 0);
1207 /* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported, 1207 /* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported,
1208 mask that menu item. */ 1208 mask that menu item. */
1209 itv->ctrl_audio_playback = 1209 itv->ctrl_audio_playback =
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index c9663e885b9f..9ff69b5a87e2 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -746,8 +746,9 @@ unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
746 return res; 746 return res;
747} 747}
748 748
749unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) 749unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table *wait)
750{ 750{
751 unsigned long req_events = poll_requested_events(wait);
751 struct ivtv_open_id *id = fh2id(filp->private_data); 752 struct ivtv_open_id *id = fh2id(filp->private_data);
752 struct ivtv *itv = id->itv; 753 struct ivtv *itv = id->itv;
753 struct ivtv_stream *s = &itv->streams[id->type]; 754 struct ivtv_stream *s = &itv->streams[id->type];
@@ -755,7 +756,8 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
755 unsigned res = 0; 756 unsigned res = 0;
756 757
757 /* Start a capture if there is none */ 758 /* Start a capture if there is none */
758 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 759 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags) &&
760 (req_events & (POLLIN | POLLRDNORM))) {
759 int rc; 761 int rc;
760 762
761 rc = ivtv_start_capture(id); 763 rc = ivtv_start_capture(id);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 989e556913ed..f7d57b3f2842 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -135,7 +135,6 @@ void ivtv_set_osd_alpha(struct ivtv *itv)
135int ivtv_set_speed(struct ivtv *itv, int speed) 135int ivtv_set_speed(struct ivtv *itv, int speed)
136{ 136{
137 u32 data[CX2341X_MBOX_MAX_DATA]; 137 u32 data[CX2341X_MBOX_MAX_DATA];
138 struct ivtv_stream *s;
139 int single_step = (speed == 1 || speed == -1); 138 int single_step = (speed == 1 || speed == -1);
140 DEFINE_WAIT(wait); 139 DEFINE_WAIT(wait);
141 140
@@ -145,8 +144,6 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
145 if (speed == itv->speed && !single_step) 144 if (speed == itv->speed && !single_step)
146 return 0; 145 return 0;
147 146
148 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
149
150 if (single_step && (speed < 0) == (itv->speed < 0)) { 147 if (single_step && (speed < 0) == (itv->speed < 0)) {
151 /* Single step video and no need to change direction */ 148 /* Single step video and no need to change direction */
152 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0); 149 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
@@ -1468,8 +1465,9 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscripti
1468 switch (sub->type) { 1465 switch (sub->type) {
1469 case V4L2_EVENT_VSYNC: 1466 case V4L2_EVENT_VSYNC:
1470 case V4L2_EVENT_EOS: 1467 case V4L2_EVENT_EOS:
1468 return v4l2_event_subscribe(fh, sub, 0, NULL);
1471 case V4L2_EVENT_CTRL: 1469 case V4L2_EVENT_CTRL:
1472 return v4l2_event_subscribe(fh, sub, 0); 1470 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
1473 default: 1471 default:
1474 return -EINVAL; 1472 return -EINVAL;
1475 } 1473 }
@@ -1827,7 +1825,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1827 return ivtv_decoder_ioctls(file, cmd, (void *)arg); 1825 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1828 1826
1829 default: 1827 default:
1830 return -EINVAL; 1828 return -ENOTTY;
1831 } 1829 }
1832 return 0; 1830 return 0;
1833} 1831}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 7ea5ca7f012b..6738592aa35d 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -228,6 +228,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
228 s->vdev->release = video_device_release; 228 s->vdev->release = video_device_release;
229 s->vdev->tvnorms = V4L2_STD_ALL; 229 s->vdev->tvnorms = V4L2_STD_ALL;
230 s->vdev->lock = &itv->serialize_lock; 230 s->vdev->lock = &itv->serialize_lock;
231 /* Locking in file operations other than ioctl should be done
232 by the driver, not the V4L2 core.
233 This driver needs auditing so that this flag can be removed. */
234 set_bit(V4L2_FL_LOCK_ALL_FOPS, &s->vdev->flags);
231 set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); 235 set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
232 ivtv_set_funcs(s->vdev); 236 ivtv_set_funcs(s->vdev);
233 return 0; 237 return 0;
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index e5e7fa9e737b..05b94aa8ba32 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1293,6 +1293,7 @@ static int __init ivtvfb_init(void)
1293 1293
1294 drv = driver_find("ivtv", &pci_bus_type); 1294 drv = driver_find("ivtv", &pci_bus_type);
1295 err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init); 1295 err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1296 (void)err; /* suppress compiler warning */
1296 if (!registered) { 1297 if (!registered) {
1297 printk(KERN_ERR "ivtvfb: no cards found\n"); 1298 printk(KERN_ERR "ivtvfb: no cards found\n");
1298 return -ENODEV; 1299 return -ENODEV;
@@ -1309,6 +1310,7 @@ static void ivtvfb_cleanup(void)
1309 1310
1310 drv = driver_find("ivtv", &pci_bus_type); 1311 drv = driver_find("ivtv", &pci_bus_type);
1311 err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup); 1312 err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1313 (void)err; /* suppress compiler warning */
1312} 1314}
1313 1315
1314module_init(ivtvfb_init); 1316module_init(ivtvfb_init);
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h
index 4b021e1ee5f2..bb589917b65b 100644
--- a/drivers/media/video/m5mols/m5mols.h
+++ b/drivers/media/video/m5mols/m5mols.h
@@ -21,11 +21,6 @@
21 21
22extern int m5mols_debug; 22extern int m5mols_debug;
23 23
24#define to_m5mols(__sd) container_of(__sd, struct m5mols_info, sd)
25
26#define to_sd(__ctrl) \
27 (&container_of(__ctrl->handler, struct m5mols_info, handle)->sd)
28
29enum m5mols_restype { 24enum m5mols_restype {
30 M5MOLS_RESTYPE_MONITOR, 25 M5MOLS_RESTYPE_MONITOR,
31 M5MOLS_RESTYPE_CAPTURE, 26 M5MOLS_RESTYPE_CAPTURE,
@@ -163,21 +158,27 @@ struct m5mols_version {
163 * @ffmt: current fmt according to resolution type 158 * @ffmt: current fmt according to resolution type
164 * @res_type: current resolution type 159 * @res_type: current resolution type
165 * @irq_waitq: waitqueue for the capture 160 * @irq_waitq: waitqueue for the capture
166 * @flags: state variable for the interrupt handler 161 * @irq_done: set to 1 in the interrupt handler
167 * @handle: control handler 162 * @handle: control handler
168 * @autoexposure: Auto Exposure control 163 * @auto_exposure: auto/manual exposure control
169 * @exposure: Exposure control 164 * @exposure_bias: exposure compensation control
170 * @autowb: Auto White Balance control 165 * @exposure: manual exposure control
171 * @colorfx: Color effect control 166 * @metering: exposure metering control
172 * @saturation: Saturation control 167 * @auto_iso: auto/manual ISO sensitivity control
173 * @zoom: Zoom control 168 * @iso: manual ISO sensitivity control
169 * @auto_wb: auto white balance control
170 * @lock_3a: 3A lock control
171 * @colorfx: color effect control
172 * @saturation: saturation control
173 * @zoom: zoom control
174 * @wdr: wide dynamic range control
175 * @stabilization: image stabilization control
176 * @jpeg_quality: JPEG compression quality control
174 * @ver: information of the version 177 * @ver: information of the version
175 * @cap: the capture mode attributes 178 * @cap: the capture mode attributes
176 * @power: current sensor's power status
177 * @isp_ready: 1 when the ISP controller has completed booting 179 * @isp_ready: 1 when the ISP controller has completed booting
180 * @power: current sensor's power status
178 * @ctrl_sync: 1 when the control handler state is restored in H/W 181 * @ctrl_sync: 1 when the control handler state is restored in H/W
179 * @lock_ae: true means the Auto Exposure is locked
180 * @lock_awb: true means the Aut WhiteBalance is locked
181 * @resolution: register value for current resolution 182 * @resolution: register value for current resolution
182 * @mode: register value for current operation mode 183 * @mode: register value for current operation mode
183 * @set_power: optional power callback to the board code 184 * @set_power: optional power callback to the board code
@@ -193,15 +194,27 @@ struct m5mols_info {
193 atomic_t irq_done; 194 atomic_t irq_done;
194 195
195 struct v4l2_ctrl_handler handle; 196 struct v4l2_ctrl_handler handle;
197 struct {
198 /* exposure/exposure bias/auto exposure cluster */
199 struct v4l2_ctrl *auto_exposure;
200 struct v4l2_ctrl *exposure_bias;
201 struct v4l2_ctrl *exposure;
202 struct v4l2_ctrl *metering;
203 };
204 struct {
205 /* iso/auto iso cluster */
206 struct v4l2_ctrl *auto_iso;
207 struct v4l2_ctrl *iso;
208 };
209 struct v4l2_ctrl *auto_wb;
196 210
197 /* Autoexposure/exposure control cluster */ 211 struct v4l2_ctrl *lock_3a;
198 struct v4l2_ctrl *autoexposure;
199 struct v4l2_ctrl *exposure;
200
201 struct v4l2_ctrl *autowb;
202 struct v4l2_ctrl *colorfx; 212 struct v4l2_ctrl *colorfx;
203 struct v4l2_ctrl *saturation; 213 struct v4l2_ctrl *saturation;
204 struct v4l2_ctrl *zoom; 214 struct v4l2_ctrl *zoom;
215 struct v4l2_ctrl *wdr;
216 struct v4l2_ctrl *stabilization;
217 struct v4l2_ctrl *jpeg_quality;
205 218
206 struct m5mols_version ver; 219 struct m5mols_version ver;
207 struct m5mols_capture cap; 220 struct m5mols_capture cap;
@@ -210,8 +223,6 @@ struct m5mols_info {
210 unsigned int power:1; 223 unsigned int power:1;
211 unsigned int ctrl_sync:1; 224 unsigned int ctrl_sync:1;
212 225
213 bool lock_ae;
214 bool lock_awb;
215 u8 resolution; 226 u8 resolution;
216 u8 mode; 227 u8 mode;
217 228
@@ -282,7 +293,7 @@ int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
282 * The available executing order between each modes are as follows: 293 * The available executing order between each modes are as follows:
283 * PARAMETER <---> MONITOR <---> CAPTURE 294 * PARAMETER <---> MONITOR <---> CAPTURE
284 */ 295 */
285int m5mols_mode(struct m5mols_info *info, u8 mode); 296int m5mols_set_mode(struct m5mols_info *info, u8 mode);
286 297
287int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg); 298int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
288int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout); 299int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout);
@@ -291,9 +302,33 @@ int m5mols_start_capture(struct m5mols_info *info);
291int m5mols_do_scenemode(struct m5mols_info *info, u8 mode); 302int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
292int m5mols_lock_3a(struct m5mols_info *info, bool lock); 303int m5mols_lock_3a(struct m5mols_info *info, bool lock);
293int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); 304int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
305int m5mols_init_controls(struct v4l2_subdev *sd);
294 306
295/* The firmware function */ 307/* The firmware function */
296int m5mols_update_fw(struct v4l2_subdev *sd, 308int m5mols_update_fw(struct v4l2_subdev *sd,
297 int (*set_power)(struct m5mols_info *, bool)); 309 int (*set_power)(struct m5mols_info *, bool));
298 310
311static inline struct m5mols_info *to_m5mols(struct v4l2_subdev *subdev)
312{
313 return container_of(subdev, struct m5mols_info, sd);
314}
315
316static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
317{
318 struct m5mols_info *info = container_of(ctrl->handler,
319 struct m5mols_info, handle);
320 return &info->sd;
321}
322
323static inline void m5mols_set_ctrl_mode(struct v4l2_ctrl *ctrl,
324 unsigned int mode)
325{
326 ctrl->priv = (void *)mode;
327}
328
329static inline unsigned int m5mols_get_ctrl_mode(struct v4l2_ctrl *ctrl)
330{
331 return (unsigned int)ctrl->priv;
332}
333
299#endif /* M5MOLS_H */ 334#endif /* M5MOLS_H */
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/video/m5mols/m5mols_capture.c
index ba25e8e2ba4c..cb243bd278ce 100644
--- a/drivers/media/video/m5mols/m5mols_capture.c
+++ b/drivers/media/video/m5mols/m5mols_capture.c
@@ -106,7 +106,6 @@ static int m5mols_capture_info(struct m5mols_info *info)
106int m5mols_start_capture(struct m5mols_info *info) 106int m5mols_start_capture(struct m5mols_info *info)
107{ 107{
108 struct v4l2_subdev *sd = &info->sd; 108 struct v4l2_subdev *sd = &info->sd;
109 u8 resolution = info->resolution;
110 int ret; 109 int ret;
111 110
112 /* 111 /*
@@ -114,22 +113,18 @@ int m5mols_start_capture(struct m5mols_info *info)
114 * format. The frame capture is initiated during switching from Monitor 113 * format. The frame capture is initiated during switching from Monitor
115 * to Capture mode. 114 * to Capture mode.
116 */ 115 */
117 ret = m5mols_mode(info, REG_MONITOR); 116 ret = m5mols_set_mode(info, REG_MONITOR);
118 if (!ret) 117 if (!ret)
119 ret = m5mols_restore_controls(info); 118 ret = m5mols_restore_controls(info);
120 if (!ret) 119 if (!ret)
121 ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG); 120 ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
122 if (!ret) 121 if (!ret)
123 ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, resolution); 122 ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
124 if (!ret) 123 if (!ret)
125 ret = m5mols_lock_3a(info, true); 124 ret = m5mols_set_mode(info, REG_CAPTURE);
126 if (!ret)
127 ret = m5mols_mode(info, REG_CAPTURE);
128 if (!ret) 125 if (!ret)
129 /* Wait until a frame is captured to ISP internal memory */ 126 /* Wait until a frame is captured to ISP internal memory */
130 ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000); 127 ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
131 if (!ret)
132 ret = m5mols_lock_3a(info, false);
133 if (ret) 128 if (ret)
134 return ret; 129 return ret;
135 130
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/video/m5mols/m5mols_controls.c
index d135d20d09cf..392a028730e2 100644
--- a/drivers/media/video/m5mols/m5mols_controls.c
+++ b/drivers/media/video/m5mols/m5mols_controls.c
@@ -139,7 +139,7 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
139 if (mode > REG_SCENE_CANDLE) 139 if (mode > REG_SCENE_CANDLE)
140 return -EINVAL; 140 return -EINVAL;
141 141
142 ret = m5mols_lock_3a(info, false); 142 ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
143 if (!ret) 143 if (!ret)
144 ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode); 144 ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
145 if (!ret) 145 if (!ret)
@@ -169,7 +169,7 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
169 if (!ret) 169 if (!ret)
170 ret = m5mols_write(sd, AE_ISO, scenemode.iso); 170 ret = m5mols_write(sd, AE_ISO, scenemode.iso);
171 if (!ret) 171 if (!ret)
172 ret = m5mols_mode(info, REG_CAPTURE); 172 ret = m5mols_set_mode(info, REG_CAPTURE);
173 if (!ret) 173 if (!ret)
174 ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr); 174 ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
175 if (!ret) 175 if (!ret)
@@ -181,119 +181,448 @@ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
181 if (!ret) 181 if (!ret)
182 ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode); 182 ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
183 if (!ret) 183 if (!ret)
184 ret = m5mols_mode(info, REG_MONITOR); 184 ret = m5mols_set_mode(info, REG_MONITOR);
185 185
186 return ret; 186 return ret;
187} 187}
188 188
189static int m5mols_lock_ae(struct m5mols_info *info, bool lock) 189static int m5mols_3a_lock(struct m5mols_info *info, struct v4l2_ctrl *ctrl)
190{ 190{
191 bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
191 int ret = 0; 192 int ret = 0;
192 193
193 if (info->lock_ae != lock) 194 if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
194 ret = m5mols_write(&info->sd, AE_LOCK, 195 bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
195 lock ? REG_AE_LOCK : REG_AE_UNLOCK); 196
196 if (!ret) 197 ret = m5mols_write(&info->sd, AE_LOCK, ae_lock ?
197 info->lock_ae = lock; 198 REG_AE_LOCK : REG_AE_UNLOCK);
199 if (ret)
200 return ret;
201 }
202
203 if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
204 && info->auto_wb->val) {
205 bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
206
207 ret = m5mols_write(&info->sd, AWB_LOCK, awb_lock ?
208 REG_AWB_LOCK : REG_AWB_UNLOCK);
209 if (ret)
210 return ret;
211 }
212
213 if (!info->ver.af || !af_lock)
214 return ret;
215
216 if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
217 ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
218
219 return ret;
220}
221
222static int m5mols_set_metering_mode(struct m5mols_info *info, int mode)
223{
224 unsigned int metering;
225
226 switch (mode) {
227 case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
228 metering = REG_AE_CENTER;
229 break;
230 case V4L2_EXPOSURE_METERING_SPOT:
231 metering = REG_AE_SPOT;
232 break;
233 default:
234 metering = REG_AE_ALL;
235 break;
236 }
237
238 return m5mols_write(&info->sd, AE_MODE, metering);
239}
240
241static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
242{
243 struct v4l2_subdev *sd = &info->sd;
244 int ret = 0;
245
246 if (exposure == V4L2_EXPOSURE_AUTO) {
247 /* Unlock auto exposure */
248 info->lock_3a->val &= ~V4L2_LOCK_EXPOSURE;
249 m5mols_3a_lock(info, info->lock_3a);
250
251 ret = m5mols_set_metering_mode(info, info->metering->val);
252 if (ret < 0)
253 return ret;
254
255 v4l2_dbg(1, m5mols_debug, sd,
256 "%s: exposure bias: %#x, metering: %#x\n",
257 __func__, info->exposure_bias->val,
258 info->metering->val);
259
260 return m5mols_write(sd, AE_INDEX, info->exposure_bias->val);
261 }
262
263 if (exposure == V4L2_EXPOSURE_MANUAL) {
264 ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
265 if (ret == 0)
266 ret = m5mols_write(sd, AE_MAN_GAIN_MON,
267 info->exposure->val);
268 if (ret == 0)
269 ret = m5mols_write(sd, AE_MAN_GAIN_CAP,
270 info->exposure->val);
271
272 v4l2_dbg(1, m5mols_debug, sd, "%s: exposure: %#x\n",
273 __func__, info->exposure->val);
274 }
275
276 return ret;
277}
278
279static int m5mols_set_white_balance(struct m5mols_info *info, int val)
280{
281 static const unsigned short wb[][2] = {
282 { V4L2_WHITE_BALANCE_INCANDESCENT, REG_AWB_INCANDESCENT },
283 { V4L2_WHITE_BALANCE_FLUORESCENT, REG_AWB_FLUORESCENT_1 },
284 { V4L2_WHITE_BALANCE_FLUORESCENT_H, REG_AWB_FLUORESCENT_2 },
285 { V4L2_WHITE_BALANCE_HORIZON, REG_AWB_HORIZON },
286 { V4L2_WHITE_BALANCE_DAYLIGHT, REG_AWB_DAYLIGHT },
287 { V4L2_WHITE_BALANCE_FLASH, REG_AWB_LEDLIGHT },
288 { V4L2_WHITE_BALANCE_CLOUDY, REG_AWB_CLOUDY },
289 { V4L2_WHITE_BALANCE_SHADE, REG_AWB_SHADE },
290 { V4L2_WHITE_BALANCE_AUTO, REG_AWB_AUTO },
291 };
292 int i;
293 struct v4l2_subdev *sd = &info->sd;
294 int ret = -EINVAL;
295
296 for (i = 0; i < ARRAY_SIZE(wb); i++) {
297 int awb;
298 if (wb[i][0] != val)
299 continue;
300
301 v4l2_dbg(1, m5mols_debug, sd,
302 "Setting white balance to: %#x\n", wb[i][0]);
303
304 awb = wb[i][0] == V4L2_WHITE_BALANCE_AUTO;
305 ret = m5mols_write(sd, AWB_MODE, awb ? REG_AWB_AUTO :
306 REG_AWB_PRESET);
307 if (ret < 0)
308 return ret;
309
310 if (!awb)
311 ret = m5mols_write(sd, AWB_MANUAL, wb[i][1]);
312 }
198 313
199 return ret; 314 return ret;
200} 315}
201 316
202static int m5mols_lock_awb(struct m5mols_info *info, bool lock) 317static int m5mols_set_saturation(struct m5mols_info *info, int val)
318{
319 int ret = m5mols_write(&info->sd, MON_CHROMA_LVL, val);
320 if (ret < 0)
321 return ret;
322
323 return m5mols_write(&info->sd, MON_CHROMA_EN, REG_CHROMA_ON);
324}
325
326static int m5mols_set_color_effect(struct m5mols_info *info, int val)
203{ 327{
328 unsigned int m_effect = REG_COLOR_EFFECT_OFF;
329 unsigned int p_effect = REG_EFFECT_OFF;
330 unsigned int cfix_r = 0, cfix_b = 0;
331 struct v4l2_subdev *sd = &info->sd;
204 int ret = 0; 332 int ret = 0;
205 333
206 if (info->lock_awb != lock) 334 switch (val) {
207 ret = m5mols_write(&info->sd, AWB_LOCK, 335 case V4L2_COLORFX_BW:
208 lock ? REG_AWB_LOCK : REG_AWB_UNLOCK); 336 m_effect = REG_COLOR_EFFECT_ON;
337 break;
338 case V4L2_COLORFX_NEGATIVE:
339 p_effect = REG_EFFECT_NEGA;
340 break;
341 case V4L2_COLORFX_EMBOSS:
342 p_effect = REG_EFFECT_EMBOSS;
343 break;
344 case V4L2_COLORFX_SEPIA:
345 m_effect = REG_COLOR_EFFECT_ON;
346 cfix_r = REG_CFIXR_SEPIA;
347 cfix_b = REG_CFIXB_SEPIA;
348 break;
349 }
350
351 ret = m5mols_write(sd, PARM_EFFECT, p_effect);
209 if (!ret) 352 if (!ret)
210 info->lock_awb = lock; 353 ret = m5mols_write(sd, MON_EFFECT, m_effect);
354
355 if (ret == 0 && m_effect == REG_COLOR_EFFECT_ON) {
356 ret = m5mols_write(sd, MON_CFIXR, cfix_r);
357 if (!ret)
358 ret = m5mols_write(sd, MON_CFIXB, cfix_b);
359 }
360
361 v4l2_dbg(1, m5mols_debug, sd,
362 "p_effect: %#x, m_effect: %#x, r: %#x, b: %#x (%d)\n",
363 p_effect, m_effect, cfix_r, cfix_b, ret);
211 364
212 return ret; 365 return ret;
213} 366}
214 367
215/* m5mols_lock_3a() - Lock 3A(Auto Exposure, Auto Whitebalance, Auto Focus) */ 368static int m5mols_set_iso(struct m5mols_info *info, int auto_iso)
216int m5mols_lock_3a(struct m5mols_info *info, bool lock) 369{
370 u32 iso = auto_iso ? 0 : info->iso->val + 1;
371
372 return m5mols_write(&info->sd, AE_ISO, iso);
373}
374
375static int m5mols_set_wdr(struct m5mols_info *info, int wdr)
217{ 376{
218 int ret; 377 int ret;
219 378
220 ret = m5mols_lock_ae(info, lock); 379 ret = m5mols_write(&info->sd, MON_TONE_CTL, wdr ? 9 : 5);
221 if (!ret) 380 if (ret < 0)
222 ret = m5mols_lock_awb(info, lock); 381 return ret;
223 /* Don't need to handle unlocking AF */ 382
224 if (!ret && is_available_af(info) && lock) 383 ret = m5mols_set_mode(info, REG_CAPTURE);
225 ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP); 384 if (ret < 0)
385 return ret;
386
387 return m5mols_write(&info->sd, CAPP_WDR_EN, wdr);
388}
389
390static int m5mols_set_stabilization(struct m5mols_info *info, int val)
391{
392 struct v4l2_subdev *sd = &info->sd;
393 unsigned int evp = val ? 0xe : 0x0;
394 int ret;
395
396 ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, evp);
397 if (ret < 0)
398 return ret;
399
400 return m5mols_write(sd, AE_EV_PRESET_CAPTURE, evp);
401}
402
403static int m5mols_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
404{
405 struct v4l2_subdev *sd = to_sd(ctrl);
406 struct m5mols_info *info = to_m5mols(sd);
407 int ret = 0;
408 u8 status;
409
410 v4l2_dbg(1, m5mols_debug, sd, "%s: ctrl: %s (%d)\n",
411 __func__, ctrl->name, info->isp_ready);
412
413 if (!info->isp_ready)
414 return -EBUSY;
415
416 switch (ctrl->id) {
417 case V4L2_CID_ISO_SENSITIVITY_AUTO:
418 ret = m5mols_read_u8(sd, AE_ISO, &status);
419 if (ret == 0)
420 ctrl->val = !status;
421 if (status != REG_ISO_AUTO)
422 info->iso->val = status - 1;
423 break;
424
425 case V4L2_CID_3A_LOCK:
426 ctrl->val &= ~0x7;
427
428 ret = m5mols_read_u8(sd, AE_LOCK, &status);
429 if (ret)
430 return ret;
431 if (status)
432 info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
433
434 ret = m5mols_read_u8(sd, AWB_LOCK, &status);
435 if (ret)
436 return ret;
437 if (status)
438 info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
439
440 ret = m5mols_read_u8(sd, AF_EXECUTE, &status);
441 if (!status)
442 info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
443 break;
444 }
226 445
227 return ret; 446 return ret;
228} 447}
229 448
230/* m5mols_set_ctrl() - The main s_ctrl function called by m5mols_set_ctrl() */ 449static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
231int m5mols_set_ctrl(struct v4l2_ctrl *ctrl)
232{ 450{
451 unsigned int ctrl_mode = m5mols_get_ctrl_mode(ctrl);
233 struct v4l2_subdev *sd = to_sd(ctrl); 452 struct v4l2_subdev *sd = to_sd(ctrl);
234 struct m5mols_info *info = to_m5mols(sd); 453 struct m5mols_info *info = to_m5mols(sd);
235 int ret; 454 int last_mode = info->mode;
455 int ret = 0;
456
457 /*
458 * If needed, defer restoring the controls until
459 * the device is fully initialized.
460 */
461 if (!info->isp_ready) {
462 info->ctrl_sync = 0;
463 return 0;
464 }
465
466 v4l2_dbg(1, m5mols_debug, sd, "%s: %s, val: %d, priv: %#x\n",
467 __func__, ctrl->name, ctrl->val, (int)ctrl->priv);
468
469 if (ctrl_mode && ctrl_mode != info->mode) {
470 ret = m5mols_set_mode(info, ctrl_mode);
471 if (ret < 0)
472 return ret;
473 }
236 474
237 switch (ctrl->id) { 475 switch (ctrl->id) {
476 case V4L2_CID_3A_LOCK:
477 ret = m5mols_3a_lock(info, ctrl);
478 break;
479
238 case V4L2_CID_ZOOM_ABSOLUTE: 480 case V4L2_CID_ZOOM_ABSOLUTE:
239 return m5mols_write(sd, MON_ZOOM, ctrl->val); 481 ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
482 break;
240 483
241 case V4L2_CID_EXPOSURE_AUTO: 484 case V4L2_CID_EXPOSURE_AUTO:
242 ret = m5mols_lock_ae(info, 485 ret = m5mols_set_exposure(info, ctrl->val);
243 ctrl->val == V4L2_EXPOSURE_AUTO ? false : true); 486 break;
244 if (!ret && ctrl->val == V4L2_EXPOSURE_AUTO)
245 ret = m5mols_write(sd, AE_MODE, REG_AE_ALL);
246 if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL) {
247 int val = info->exposure->val;
248 ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
249 if (!ret)
250 ret = m5mols_write(sd, AE_MAN_GAIN_MON, val);
251 if (!ret)
252 ret = m5mols_write(sd, AE_MAN_GAIN_CAP, val);
253 }
254 return ret;
255 487
256 case V4L2_CID_AUTO_WHITE_BALANCE: 488 case V4L2_CID_ISO_SENSITIVITY:
257 ret = m5mols_lock_awb(info, ctrl->val ? false : true); 489 ret = m5mols_set_iso(info, ctrl->val);
258 if (!ret) 490 break;
259 ret = m5mols_write(sd, AWB_MODE, ctrl->val ? 491
260 REG_AWB_AUTO : REG_AWB_PRESET); 492 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
261 return ret; 493 ret = m5mols_set_white_balance(info, ctrl->val);
494 break;
262 495
263 case V4L2_CID_SATURATION: 496 case V4L2_CID_SATURATION:
264 ret = m5mols_write(sd, MON_CHROMA_LVL, ctrl->val); 497 ret = m5mols_set_saturation(info, ctrl->val);
265 if (!ret) 498 break;
266 ret = m5mols_write(sd, MON_CHROMA_EN, REG_CHROMA_ON);
267 return ret;
268 499
269 case V4L2_CID_COLORFX: 500 case V4L2_CID_COLORFX:
270 /* 501 ret = m5mols_set_color_effect(info, ctrl->val);
271 * This control uses two kinds of registers: normal & color. 502 break;
272 * The normal effect belongs to category 1, while the color 503
273 * one belongs to category 2. 504 case V4L2_CID_WIDE_DYNAMIC_RANGE:
274 * 505 ret = m5mols_set_wdr(info, ctrl->val);
275 * The normal effect uses one register: CAT1_EFFECT. 506 break;
276 * The color effect uses three registers: 507
277 * CAT2_COLOR_EFFECT, CAT2_CFIXR, CAT2_CFIXB. 508 case V4L2_CID_IMAGE_STABILIZATION:
278 */ 509 ret = m5mols_set_stabilization(info, ctrl->val);
279 ret = m5mols_write(sd, PARM_EFFECT, 510 break;
280 ctrl->val == V4L2_COLORFX_NEGATIVE ? REG_EFFECT_NEGA : 511
281 ctrl->val == V4L2_COLORFX_EMBOSS ? REG_EFFECT_EMBOSS : 512 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
282 REG_EFFECT_OFF); 513 ret = m5mols_write(sd, CAPP_JPEG_RATIO, ctrl->val);
283 if (!ret) 514 break;
284 ret = m5mols_write(sd, MON_EFFECT, 515 }
285 ctrl->val == V4L2_COLORFX_SEPIA ? 516
286 REG_COLOR_EFFECT_ON : REG_COLOR_EFFECT_OFF); 517 if (ret == 0 && info->mode != last_mode)
287 if (!ret) 518 ret = m5mols_set_mode(info, last_mode);
288 ret = m5mols_write(sd, MON_CFIXR, 519
289 ctrl->val == V4L2_COLORFX_SEPIA ? 520 return ret;
290 REG_CFIXR_SEPIA : 0); 521}
291 if (!ret) 522
292 ret = m5mols_write(sd, MON_CFIXB, 523static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
293 ctrl->val == V4L2_COLORFX_SEPIA ? 524 .g_volatile_ctrl = m5mols_g_volatile_ctrl,
294 REG_CFIXB_SEPIA : 0); 525 .s_ctrl = m5mols_s_ctrl,
526};
527
528/* Supported manual ISO values */
529static const s64 iso_qmenu[] = {
530 /* AE_ISO: 0x01...0x07 */
531 50, 100, 200, 400, 800, 1600, 3200
532};
533
534/* Supported Exposure Bias values, -2.0EV...+2.0EV */
535static const s64 ev_bias_qmenu[] = {
536 /* AE_INDEX: 0x00...0x08 */
537 -2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
538};
539
540int m5mols_init_controls(struct v4l2_subdev *sd)
541{
542 struct m5mols_info *info = to_m5mols(sd);
543 u16 exposure_max;
544 u16 zoom_step;
545 int ret;
546
547 /* Determine the firmware dependant control range and step values */
548 ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
549 if (ret < 0)
550 return ret;
551
552 zoom_step = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
553 v4l2_ctrl_handler_init(&info->handle, 20);
554
555 info->auto_wb = v4l2_ctrl_new_std_menu(&info->handle,
556 &m5mols_ctrl_ops, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
557 9, ~0x3fe, V4L2_WHITE_BALANCE_AUTO);
558
559 /* Exposure control cluster */
560 info->auto_exposure = v4l2_ctrl_new_std_menu(&info->handle,
561 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
562 1, ~0x03, V4L2_EXPOSURE_AUTO);
563
564 info->exposure = v4l2_ctrl_new_std(&info->handle,
565 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
566 0, exposure_max, 1, exposure_max / 2);
567
568 info->exposure_bias = v4l2_ctrl_new_int_menu(&info->handle,
569 &m5mols_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
570 ARRAY_SIZE(ev_bias_qmenu) - 1,
571 ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
572 ev_bias_qmenu);
573
574 info->metering = v4l2_ctrl_new_std_menu(&info->handle,
575 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_METERING,
576 2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
577
578 /* ISO control cluster */
579 info->auto_iso = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
580 V4L2_CID_ISO_SENSITIVITY_AUTO, 1, ~0x03, 1);
581
582 info->iso = v4l2_ctrl_new_int_menu(&info->handle, &m5mols_ctrl_ops,
583 V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
584 ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
585
586 info->saturation = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
587 V4L2_CID_SATURATION, 1, 5, 1, 3);
588
589 info->zoom = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
590 V4L2_CID_ZOOM_ABSOLUTE, 1, 70, zoom_step, 1);
591
592 info->colorfx = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
593 V4L2_CID_COLORFX, 4, 0, V4L2_COLORFX_NONE);
594
595 info->wdr = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
596 V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
597
598 info->stabilization = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
599 V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
600
601 info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
602 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
603
604 info->lock_3a = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
605 V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
606
607 if (info->handle.error) {
608 int ret = info->handle.error;
609 v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
610 v4l2_ctrl_handler_free(&info->handle);
295 return ret; 611 return ret;
296 } 612 }
297 613
298 return -EINVAL; 614 v4l2_ctrl_auto_cluster(4, &info->auto_exposure, 1, false);
615 info->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
616 V4L2_CTRL_FLAG_UPDATE;
617 v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false);
618
619 info->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
620
621 m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER);
622 m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER);
623 m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR);
624
625 sd->ctrl_handler = &info->handle;
626
627 return 0;
299} 628}
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c
index d718aee01c77..ac7d28b6ddf2 100644
--- a/drivers/media/video/m5mols/m5mols_core.c
+++ b/drivers/media/video/m5mols/m5mols_core.c
@@ -362,14 +362,14 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
362} 362}
363 363
364/** 364/**
365 * m5mols_mode - manage the M-5MOLS's mode 365 * m5mols_set_mode - set the M-5MOLS controller mode
366 * @mode: the required operation mode 366 * @mode: the required operation mode
367 * 367 *
368 * The commands of M-5MOLS are grouped into specific modes. Each functionality 368 * The commands of M-5MOLS are grouped into specific modes. Each functionality
369 * can be guaranteed only when the sensor is operating in mode which which 369 * can be guaranteed only when the sensor is operating in mode which a command
370 * a command belongs to. 370 * belongs to.
371 */ 371 */
372int m5mols_mode(struct m5mols_info *info, u8 mode) 372int m5mols_set_mode(struct m5mols_info *info, u8 mode)
373{ 373{
374 struct v4l2_subdev *sd = &info->sd; 374 struct v4l2_subdev *sd = &info->sd;
375 int ret = -EINVAL; 375 int ret = -EINVAL;
@@ -645,13 +645,13 @@ static int m5mols_start_monitor(struct m5mols_info *info)
645 struct v4l2_subdev *sd = &info->sd; 645 struct v4l2_subdev *sd = &info->sd;
646 int ret; 646 int ret;
647 647
648 ret = m5mols_mode(info, REG_PARAMETER); 648 ret = m5mols_set_mode(info, REG_PARAMETER);
649 if (!ret) 649 if (!ret)
650 ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution); 650 ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
651 if (!ret) 651 if (!ret)
652 ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30); 652 ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
653 if (!ret) 653 if (!ret)
654 ret = m5mols_mode(info, REG_MONITOR); 654 ret = m5mols_set_mode(info, REG_MONITOR);
655 if (!ret) 655 if (!ret)
656 ret = m5mols_restore_controls(info); 656 ret = m5mols_restore_controls(info);
657 657
@@ -674,42 +674,13 @@ static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
674 return ret; 674 return ret;
675 } 675 }
676 676
677 return m5mols_mode(info, REG_PARAMETER); 677 return m5mols_set_mode(info, REG_PARAMETER);
678} 678}
679 679
680static const struct v4l2_subdev_video_ops m5mols_video_ops = { 680static const struct v4l2_subdev_video_ops m5mols_video_ops = {
681 .s_stream = m5mols_s_stream, 681 .s_stream = m5mols_s_stream,
682}; 682};
683 683
684static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
685{
686 struct v4l2_subdev *sd = to_sd(ctrl);
687 struct m5mols_info *info = to_m5mols(sd);
688 int ispstate = info->mode;
689 int ret;
690
691 /*
692 * If needed, defer restoring the controls until
693 * the device is fully initialized.
694 */
695 if (!info->isp_ready) {
696 info->ctrl_sync = 0;
697 return 0;
698 }
699
700 ret = m5mols_mode(info, REG_PARAMETER);
701 if (ret < 0)
702 return ret;
703 ret = m5mols_set_ctrl(ctrl);
704 if (ret < 0)
705 return ret;
706 return m5mols_mode(info, ispstate);
707}
708
709static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
710 .s_ctrl = m5mols_s_ctrl,
711};
712
713static int m5mols_sensor_power(struct m5mols_info *info, bool enable) 684static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
714{ 685{
715 struct v4l2_subdev *sd = &info->sd; 686 struct v4l2_subdev *sd = &info->sd;
@@ -802,52 +773,6 @@ static int m5mols_fw_start(struct v4l2_subdev *sd)
802 return ret; 773 return ret;
803} 774}
804 775
805static int m5mols_init_controls(struct m5mols_info *info)
806{
807 struct v4l2_subdev *sd = &info->sd;
808 u16 max_exposure;
809 u16 step_zoom;
810 int ret;
811
812 /* Determine value's range & step of controls for various FW version */
813 ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure);
814 if (!ret)
815 step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
816 if (ret)
817 return ret;
818
819 v4l2_ctrl_handler_init(&info->handle, 6);
820 info->autowb = v4l2_ctrl_new_std(&info->handle,
821 &m5mols_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE,
822 0, 1, 1, 0);
823 info->saturation = v4l2_ctrl_new_std(&info->handle,
824 &m5mols_ctrl_ops, V4L2_CID_SATURATION,
825 1, 5, 1, 3);
826 info->zoom = v4l2_ctrl_new_std(&info->handle,
827 &m5mols_ctrl_ops, V4L2_CID_ZOOM_ABSOLUTE,
828 1, 70, step_zoom, 1);
829 info->exposure = v4l2_ctrl_new_std(&info->handle,
830 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
831 0, max_exposure, 1, (int)max_exposure/2);
832 info->colorfx = v4l2_ctrl_new_std_menu(&info->handle,
833 &m5mols_ctrl_ops, V4L2_CID_COLORFX,
834 4, (1 << V4L2_COLORFX_BW), V4L2_COLORFX_NONE);
835 info->autoexposure = v4l2_ctrl_new_std_menu(&info->handle,
836 &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
837 1, 0, V4L2_EXPOSURE_AUTO);
838
839 sd->ctrl_handler = &info->handle;
840 if (info->handle.error) {
841 v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
842 v4l2_ctrl_handler_free(&info->handle);
843 return info->handle.error;
844 }
845
846 v4l2_ctrl_cluster(2, &info->autoexposure);
847
848 return 0;
849}
850
851/** 776/**
852 * m5mols_s_power - Main sensor power control function 777 * m5mols_s_power - Main sensor power control function
853 * 778 *
@@ -868,7 +793,7 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
868 } 793 }
869 794
870 if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) { 795 if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
871 ret = m5mols_mode(info, REG_MONITOR); 796 ret = m5mols_set_mode(info, REG_MONITOR);
872 if (!ret) 797 if (!ret)
873 ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP); 798 ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
874 if (!ret) 799 if (!ret)
@@ -1010,7 +935,7 @@ static int __devinit m5mols_probe(struct i2c_client *client,
1010 935
1011 ret = m5mols_fw_start(sd); 936 ret = m5mols_fw_start(sd);
1012 if (!ret) 937 if (!ret)
1013 ret = m5mols_init_controls(info); 938 ret = m5mols_init_controls(sd);
1014 939
1015 m5mols_sensor_power(info, false); 940 m5mols_sensor_power(info, false);
1016 if (!ret) 941 if (!ret)
diff --git a/drivers/media/video/m5mols/m5mols_reg.h b/drivers/media/video/m5mols/m5mols_reg.h
index ae4aced0f9b2..14d4be72aeff 100644
--- a/drivers/media/video/m5mols/m5mols_reg.h
+++ b/drivers/media/video/m5mols/m5mols_reg.h
@@ -310,6 +310,7 @@
310#define REG_JPEG 0x10 310#define REG_JPEG 0x10
311 311
312#define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1) 312#define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1)
313#define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1)
313 314
314#define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1) 315#define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1)
315#define REG_MCC_OFF 0x00 316#define REG_MCC_OFF 0x00
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 996ac34d9a89..ce2b7b4788d6 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -1356,7 +1356,6 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
1356 goto out; 1356 goto out;
1357 } 1357 }
1358 mcam_set_config_needed(cam, 1); 1358 mcam_set_config_needed(cam, 1);
1359 ret = 0;
1360out: 1359out:
1361 mutex_unlock(&cam->s_mutex); 1360 mutex_unlock(&cam->s_mutex);
1362 return ret; 1361 return ret;
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index 12897e8a3314..d2dec585e61b 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -40,7 +40,7 @@ MODULE_VERSION("0.1.1");
40#define MIN_H 32 40#define MIN_H 32
41#define MAX_W 640 41#define MAX_W 640
42#define MAX_H 480 42#define MAX_H 480
43#define DIM_ALIGN_MASK 0x08 /* 8-alignment for dimensions */ 43#define DIM_ALIGN_MASK 7 /* 8-byte alignment for line length */
44 44
45/* Flags that indicate a format can be used for capture/output */ 45/* Flags that indicate a format can be used for capture/output */
46#define MEM2MEM_CAPTURE (1 << 0) 46#define MEM2MEM_CAPTURE (1 << 0)
@@ -958,6 +958,10 @@ static int m2mtest_probe(struct platform_device *pdev)
958 } 958 }
959 959
960 *vfd = m2mtest_videodev; 960 *vfd = m2mtest_videodev;
961 /* Locking in file operations other than ioctl should be done
962 by the driver, not the V4L2 core.
963 This driver needs auditing so that this flag can be removed. */
964 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
961 vfd->lock = &dev->dev_mutex; 965 vfd->lock = &dev->dev_mutex;
962 966
963 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 967 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index b09a3c80a15e..7bc775219f97 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1570,7 +1570,7 @@ static long vidioc_default(struct file *file, void *fh, bool valid_prio,
1570 return meyeioc_stilljcapt((int *) arg); 1570 return meyeioc_stilljcapt((int *) arg);
1571 1571
1572 default: 1572 default:
1573 return -EINVAL; 1573 return -ENOTTY;
1574 } 1574 }
1575 1575
1576} 1576}
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 82ce50721de3..aeb22be7dcbd 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -597,19 +597,23 @@ static int msp_log_status(struct v4l2_subdev *sd)
597 return 0; 597 return 0;
598} 598}
599 599
600static int msp_suspend(struct i2c_client *client, pm_message_t state) 600#ifdef CONFIG_PM_SLEEP
601static int msp_suspend(struct device *dev)
601{ 602{
603 struct i2c_client *client = to_i2c_client(dev);
602 v4l_dbg(1, msp_debug, client, "suspend\n"); 604 v4l_dbg(1, msp_debug, client, "suspend\n");
603 msp_reset(client); 605 msp_reset(client);
604 return 0; 606 return 0;
605} 607}
606 608
607static int msp_resume(struct i2c_client *client) 609static int msp_resume(struct device *dev)
608{ 610{
611 struct i2c_client *client = to_i2c_client(dev);
609 v4l_dbg(1, msp_debug, client, "resume\n"); 612 v4l_dbg(1, msp_debug, client, "resume\n");
610 msp_wake_thread(client); 613 msp_wake_thread(client);
611 return 0; 614 return 0;
612} 615}
616#endif
613 617
614/* ----------------------------------------------------------------------- */ 618/* ----------------------------------------------------------------------- */
615 619
@@ -863,6 +867,10 @@ static int msp_remove(struct i2c_client *client)
863 867
864/* ----------------------------------------------------------------------- */ 868/* ----------------------------------------------------------------------- */
865 869
870static const struct dev_pm_ops msp3400_pm_ops = {
871 SET_SYSTEM_SLEEP_PM_OPS(msp_suspend, msp_resume)
872};
873
866static const struct i2c_device_id msp_id[] = { 874static const struct i2c_device_id msp_id[] = {
867 { "msp3400", 0 }, 875 { "msp3400", 0 },
868 { } 876 { }
@@ -873,11 +881,10 @@ static struct i2c_driver msp_driver = {
873 .driver = { 881 .driver = {
874 .owner = THIS_MODULE, 882 .owner = THIS_MODULE,
875 .name = "msp3400", 883 .name = "msp3400",
884 .pm = &msp3400_pm_ops,
876 }, 885 },
877 .probe = msp_probe, 886 .probe = msp_probe,
878 .remove = msp_remove, 887 .remove = msp_remove,
879 .suspend = msp_suspend,
880 .resume = msp_resume,
881 .id_table = msp_id, 888 .id_table = msp_id,
882}; 889};
883 890
diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c
index 645973c5feb0..3c1e626139b7 100644
--- a/drivers/media/video/mt9m032.c
+++ b/drivers/media/video/mt9m032.c
@@ -838,9 +838,9 @@ static int mt9m032_remove(struct i2c_client *client)
838 struct v4l2_subdev *subdev = i2c_get_clientdata(client); 838 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
839 struct mt9m032 *sensor = to_mt9m032(subdev); 839 struct mt9m032 *sensor = to_mt9m032(subdev);
840 840
841 v4l2_device_unregister_subdev(&sensor->subdev); 841 v4l2_device_unregister_subdev(subdev);
842 v4l2_ctrl_handler_free(&sensor->ctrls); 842 v4l2_ctrl_handler_free(&sensor->ctrls);
843 media_entity_cleanup(&sensor->subdev.entity); 843 media_entity_cleanup(&subdev->entity);
844 mutex_destroy(&sensor->lock); 844 mutex_destroy(&sensor->lock);
845 kfree(sensor); 845 kfree(sensor);
846 return 0; 846 return 0;
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
index c81eaf4fbe01..8f061d9ac443 100644
--- a/drivers/media/video/mt9p031.c
+++ b/drivers/media/video/mt9p031.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/gpio.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
19#include <linux/log2.h> 20#include <linux/log2.h>
@@ -90,7 +91,14 @@
90#define MT9P031_GLOBAL_GAIN_MAX 1024 91#define MT9P031_GLOBAL_GAIN_MAX 1024
91#define MT9P031_GLOBAL_GAIN_DEF 8 92#define MT9P031_GLOBAL_GAIN_DEF 8
92#define MT9P031_GLOBAL_GAIN_MULT (1 << 6) 93#define MT9P031_GLOBAL_GAIN_MULT (1 << 6)
94#define MT9P031_ROW_BLACK_TARGET 0x49
93#define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b 95#define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b
96#define MT9P031_GREEN1_OFFSET 0x60
97#define MT9P031_GREEN2_OFFSET 0x61
98#define MT9P031_BLACK_LEVEL_CALIBRATION 0x62
99#define MT9P031_BLC_MANUAL_BLC (1 << 0)
100#define MT9P031_RED_OFFSET 0x63
101#define MT9P031_BLUE_OFFSET 0x64
94#define MT9P031_TEST_PATTERN 0xa0 102#define MT9P031_TEST_PATTERN 0xa0
95#define MT9P031_TEST_PATTERN_SHIFT 3 103#define MT9P031_TEST_PATTERN_SHIFT 3
96#define MT9P031_TEST_PATTERN_ENABLE (1 << 0) 104#define MT9P031_TEST_PATTERN_ENABLE (1 << 0)
@@ -99,17 +107,27 @@
99#define MT9P031_TEST_PATTERN_RED 0xa2 107#define MT9P031_TEST_PATTERN_RED 0xa2
100#define MT9P031_TEST_PATTERN_BLUE 0xa3 108#define MT9P031_TEST_PATTERN_BLUE 0xa3
101 109
110enum mt9p031_model {
111 MT9P031_MODEL_COLOR,
112 MT9P031_MODEL_MONOCHROME,
113};
114
102struct mt9p031 { 115struct mt9p031 {
103 struct v4l2_subdev subdev; 116 struct v4l2_subdev subdev;
104 struct media_pad pad; 117 struct media_pad pad;
105 struct v4l2_rect crop; /* Sensor window */ 118 struct v4l2_rect crop; /* Sensor window */
106 struct v4l2_mbus_framefmt format; 119 struct v4l2_mbus_framefmt format;
107 struct v4l2_ctrl_handler ctrls;
108 struct mt9p031_platform_data *pdata; 120 struct mt9p031_platform_data *pdata;
109 struct mutex power_lock; /* lock to protect power_count */ 121 struct mutex power_lock; /* lock to protect power_count */
110 int power_count; 122 int power_count;
111 123
124 enum mt9p031_model model;
112 struct aptina_pll pll; 125 struct aptina_pll pll;
126 int reset;
127
128 struct v4l2_ctrl_handler ctrls;
129 struct v4l2_ctrl *blc_auto;
130 struct v4l2_ctrl *blc_offset;
113 131
114 /* Registers cache */ 132 /* Registers cache */
115 u16 output_control; 133 u16 output_control;
@@ -241,8 +259,8 @@ static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
241static int mt9p031_power_on(struct mt9p031 *mt9p031) 259static int mt9p031_power_on(struct mt9p031 *mt9p031)
242{ 260{
243 /* Ensure RESET_BAR is low */ 261 /* Ensure RESET_BAR is low */
244 if (mt9p031->pdata->reset) { 262 if (mt9p031->reset != -1) {
245 mt9p031->pdata->reset(&mt9p031->subdev, 1); 263 gpio_set_value(mt9p031->reset, 0);
246 usleep_range(1000, 2000); 264 usleep_range(1000, 2000);
247 } 265 }
248 266
@@ -252,8 +270,8 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031)
252 mt9p031->pdata->ext_freq); 270 mt9p031->pdata->ext_freq);
253 271
254 /* Now RESET_BAR must be high */ 272 /* Now RESET_BAR must be high */
255 if (mt9p031->pdata->reset) { 273 if (mt9p031->reset != -1) {
256 mt9p031->pdata->reset(&mt9p031->subdev, 0); 274 gpio_set_value(mt9p031->reset, 1);
257 usleep_range(1000, 2000); 275 usleep_range(1000, 2000);
258 } 276 }
259 277
@@ -262,8 +280,8 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031)
262 280
263static void mt9p031_power_off(struct mt9p031 *mt9p031) 281static void mt9p031_power_off(struct mt9p031 *mt9p031)
264{ 282{
265 if (mt9p031->pdata->reset) { 283 if (mt9p031->reset != -1) {
266 mt9p031->pdata->reset(&mt9p031->subdev, 1); 284 gpio_set_value(mt9p031->reset, 0);
267 usleep_range(1000, 2000); 285 usleep_range(1000, 2000);
268 } 286 }
269 287
@@ -557,6 +575,10 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev,
557 */ 575 */
558 576
559#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001) 577#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
578#define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002)
579#define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003)
580#define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
581#define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005)
560 582
561static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) 583static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
562{ 584{
@@ -621,11 +643,17 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
621 643
622 case V4L2_CID_TEST_PATTERN: 644 case V4L2_CID_TEST_PATTERN:
623 if (!ctrl->val) { 645 if (!ctrl->val) {
624 ret = mt9p031_set_mode2(mt9p031, 646 /* Restore the black level compensation settings. */
625 0, MT9P031_READ_MODE_2_ROW_BLC); 647 if (mt9p031->blc_auto->cur.val != 0) {
626 if (ret < 0) 648 ret = mt9p031_s_ctrl(mt9p031->blc_auto);
627 return ret; 649 if (ret < 0)
628 650 return ret;
651 }
652 if (mt9p031->blc_offset->cur.val != 0) {
653 ret = mt9p031_s_ctrl(mt9p031->blc_offset);
654 if (ret < 0)
655 return ret;
656 }
629 return mt9p031_write(client, MT9P031_TEST_PATTERN, 657 return mt9p031_write(client, MT9P031_TEST_PATTERN,
630 MT9P031_TEST_PATTERN_DISABLE); 658 MT9P031_TEST_PATTERN_DISABLE);
631 } 659 }
@@ -640,10 +668,14 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
640 if (ret < 0) 668 if (ret < 0)
641 return ret; 669 return ret;
642 670
671 /* Disable digital black level compensation when using a test
672 * pattern.
673 */
643 ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC, 674 ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
644 0); 675 0);
645 if (ret < 0) 676 if (ret < 0)
646 return ret; 677 return ret;
678
647 ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0); 679 ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0);
648 if (ret < 0) 680 if (ret < 0)
649 return ret; 681 return ret;
@@ -651,7 +683,40 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
651 return mt9p031_write(client, MT9P031_TEST_PATTERN, 683 return mt9p031_write(client, MT9P031_TEST_PATTERN,
652 ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT) 684 ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT)
653 | MT9P031_TEST_PATTERN_ENABLE); 685 | MT9P031_TEST_PATTERN_ENABLE);
686
687 case V4L2_CID_BLC_AUTO:
688 ret = mt9p031_set_mode2(mt9p031,
689 ctrl->val ? 0 : MT9P031_READ_MODE_2_ROW_BLC,
690 ctrl->val ? MT9P031_READ_MODE_2_ROW_BLC : 0);
691 if (ret < 0)
692 return ret;
693
694 return mt9p031_write(client, MT9P031_BLACK_LEVEL_CALIBRATION,
695 ctrl->val ? 0 : MT9P031_BLC_MANUAL_BLC);
696
697 case V4L2_CID_BLC_TARGET_LEVEL:
698 return mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
699 ctrl->val);
700
701 case V4L2_CID_BLC_ANALOG_OFFSET:
702 data = ctrl->val & ((1 << 9) - 1);
703
704 ret = mt9p031_write(client, MT9P031_GREEN1_OFFSET, data);
705 if (ret < 0)
706 return ret;
707 ret = mt9p031_write(client, MT9P031_GREEN2_OFFSET, data);
708 if (ret < 0)
709 return ret;
710 ret = mt9p031_write(client, MT9P031_RED_OFFSET, data);
711 if (ret < 0)
712 return ret;
713 return mt9p031_write(client, MT9P031_BLUE_OFFSET, data);
714
715 case V4L2_CID_BLC_DIGITAL_OFFSET:
716 return mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET,
717 ctrl->val & ((1 << 12) - 1));
654 } 718 }
719
655 return 0; 720 return 0;
656} 721}
657 722
@@ -685,6 +750,46 @@ static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
685 .flags = 0, 750 .flags = 0,
686 .menu_skip_mask = 0, 751 .menu_skip_mask = 0,
687 .qmenu = mt9p031_test_pattern_menu, 752 .qmenu = mt9p031_test_pattern_menu,
753 }, {
754 .ops = &mt9p031_ctrl_ops,
755 .id = V4L2_CID_BLC_AUTO,
756 .type = V4L2_CTRL_TYPE_BOOLEAN,
757 .name = "BLC, Auto",
758 .min = 0,
759 .max = 1,
760 .step = 1,
761 .def = 1,
762 .flags = 0,
763 }, {
764 .ops = &mt9p031_ctrl_ops,
765 .id = V4L2_CID_BLC_TARGET_LEVEL,
766 .type = V4L2_CTRL_TYPE_INTEGER,
767 .name = "BLC Target Level",
768 .min = 0,
769 .max = 4095,
770 .step = 1,
771 .def = 168,
772 .flags = 0,
773 }, {
774 .ops = &mt9p031_ctrl_ops,
775 .id = V4L2_CID_BLC_ANALOG_OFFSET,
776 .type = V4L2_CTRL_TYPE_INTEGER,
777 .name = "BLC Analog Offset",
778 .min = -255,
779 .max = 255,
780 .step = 1,
781 .def = 32,
782 .flags = 0,
783 }, {
784 .ops = &mt9p031_ctrl_ops,
785 .id = V4L2_CID_BLC_DIGITAL_OFFSET,
786 .type = V4L2_CTRL_TYPE_INTEGER,
787 .name = "BLC Digital Offset",
788 .min = -2048,
789 .max = 2047,
790 .step = 1,
791 .def = 40,
792 .flags = 0,
688 } 793 }
689}; 794};
690 795
@@ -764,7 +869,7 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
764 869
765 format = v4l2_subdev_get_try_format(fh, 0); 870 format = v4l2_subdev_get_try_format(fh, 0);
766 871
767 if (mt9p031->pdata->version == MT9P031_MONOCHROME_VERSION) 872 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
768 format->code = V4L2_MBUS_FMT_Y12_1X12; 873 format->code = V4L2_MBUS_FMT_Y12_1X12;
769 else 874 else
770 format->code = V4L2_MBUS_FMT_SGRBG12_1X12; 875 format->code = V4L2_MBUS_FMT_SGRBG12_1X12;
@@ -842,6 +947,8 @@ static int mt9p031_probe(struct i2c_client *client,
842 mt9p031->pdata = pdata; 947 mt9p031->pdata = pdata;
843 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; 948 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
844 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; 949 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
950 mt9p031->model = did->driver_data;
951 mt9p031->reset = -1;
845 952
846 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4); 953 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4);
847 954
@@ -862,9 +969,16 @@ static int mt9p031_probe(struct i2c_client *client,
862 969
863 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls; 970 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
864 971
865 if (mt9p031->ctrls.error) 972 if (mt9p031->ctrls.error) {
866 printk(KERN_INFO "%s: control initialization error %d\n", 973 printk(KERN_INFO "%s: control initialization error %d\n",
867 __func__, mt9p031->ctrls.error); 974 __func__, mt9p031->ctrls.error);
975 ret = mt9p031->ctrls.error;
976 goto done;
977 }
978
979 mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO);
980 mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls,
981 V4L2_CID_BLC_DIGITAL_OFFSET);
868 982
869 mutex_init(&mt9p031->power_lock); 983 mutex_init(&mt9p031->power_lock);
870 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops); 984 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
@@ -882,7 +996,7 @@ static int mt9p031_probe(struct i2c_client *client,
882 mt9p031->crop.left = MT9P031_COLUMN_START_DEF; 996 mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
883 mt9p031->crop.top = MT9P031_ROW_START_DEF; 997 mt9p031->crop.top = MT9P031_ROW_START_DEF;
884 998
885 if (mt9p031->pdata->version == MT9P031_MONOCHROME_VERSION) 999 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
886 mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12; 1000 mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12;
887 else 1001 else
888 mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12; 1002 mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12;
@@ -892,10 +1006,22 @@ static int mt9p031_probe(struct i2c_client *client,
892 mt9p031->format.field = V4L2_FIELD_NONE; 1006 mt9p031->format.field = V4L2_FIELD_NONE;
893 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; 1007 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
894 1008
1009 if (pdata->reset != -1) {
1010 ret = gpio_request_one(pdata->reset, GPIOF_OUT_INIT_LOW,
1011 "mt9p031_rst");
1012 if (ret < 0)
1013 goto done;
1014
1015 mt9p031->reset = pdata->reset;
1016 }
1017
895 ret = mt9p031_pll_setup(mt9p031); 1018 ret = mt9p031_pll_setup(mt9p031);
896 1019
897done: 1020done:
898 if (ret < 0) { 1021 if (ret < 0) {
1022 if (mt9p031->reset != -1)
1023 gpio_free(mt9p031->reset);
1024
899 v4l2_ctrl_handler_free(&mt9p031->ctrls); 1025 v4l2_ctrl_handler_free(&mt9p031->ctrls);
900 media_entity_cleanup(&mt9p031->subdev.entity); 1026 media_entity_cleanup(&mt9p031->subdev.entity);
901 kfree(mt9p031); 1027 kfree(mt9p031);
@@ -912,13 +1038,16 @@ static int mt9p031_remove(struct i2c_client *client)
912 v4l2_ctrl_handler_free(&mt9p031->ctrls); 1038 v4l2_ctrl_handler_free(&mt9p031->ctrls);
913 v4l2_device_unregister_subdev(subdev); 1039 v4l2_device_unregister_subdev(subdev);
914 media_entity_cleanup(&subdev->entity); 1040 media_entity_cleanup(&subdev->entity);
1041 if (mt9p031->reset != -1)
1042 gpio_free(mt9p031->reset);
915 kfree(mt9p031); 1043 kfree(mt9p031);
916 1044
917 return 0; 1045 return 0;
918} 1046}
919 1047
920static const struct i2c_device_id mt9p031_id[] = { 1048static const struct i2c_device_id mt9p031_id[] = {
921 { "mt9p031", 0 }, 1049 { "mt9p031", MT9P031_MODEL_COLOR },
1050 { "mt9p031m", MT9P031_MODEL_MONOCHROME },
922 { } 1051 { }
923}; 1052};
924MODULE_DEVICE_TABLE(i2c, mt9p031_id); 1053MODULE_DEVICE_TABLE(i2c, mt9p031_id);
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index 8d1445f12708..e1ae46a7ee96 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -453,6 +453,7 @@ static int mt9t112_init_pll(const struct i2c_client *client)
453 * I2C Master Clock Divider 453 * I2C Master Clock Divider
454 */ 454 */
455 mt9t112_reg_write(ret, client, 0x0014, 0x3046); 455 mt9t112_reg_write(ret, client, 0x0014, 0x3046);
456 mt9t112_reg_write(ret, client, 0x0016, 0x0400); /* JPEG initialization workaround */
456 mt9t112_reg_write(ret, client, 0x0022, 0x0190); 457 mt9t112_reg_write(ret, client, 0x0022, 0x0190);
457 mt9t112_reg_write(ret, client, 0x3B84, 0x0212); 458 mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
458 459
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
index 75e253a343c5..4ba4884c016e 100644
--- a/drivers/media/video/mt9v032.c
+++ b/drivers/media/video/mt9v032.c
@@ -481,7 +481,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
481 481
482 case V4L2_CID_EXPOSURE_AUTO: 482 case V4L2_CID_EXPOSURE_AUTO:
483 return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE, 483 return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
484 ctrl->val); 484 !ctrl->val);
485 485
486 case V4L2_CID_EXPOSURE: 486 case V4L2_CID_EXPOSURE:
487 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH, 487 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 055d11ddb038..4296a8350298 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -126,13 +126,8 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
126 unsigned int *size) 126 unsigned int *size)
127{ 127{
128 struct soc_camera_device *icd = vq->priv_data; 128 struct soc_camera_device *icd = vq->priv_data;
129 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
130 icd->current_fmt->host_fmt);
131 129
132 if (bytes_per_line < 0) 130 *size = icd->sizeimage;
133 return bytes_per_line;
134
135 *size = bytes_per_line * icd->user_height;
136 131
137 if (!*count) 132 if (!*count)
138 *count = 32; 133 *count = 32;
@@ -171,11 +166,6 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
171 struct soc_camera_device *icd = vq->priv_data; 166 struct soc_camera_device *icd = vq->priv_data;
172 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 167 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
173 int ret; 168 int ret;
174 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
175 icd->current_fmt->host_fmt);
176
177 if (bytes_per_line < 0)
178 return bytes_per_line;
179 169
180 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 170 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
181 vb, vb->baddr, vb->bsize); 171 vb, vb->baddr, vb->bsize);
@@ -202,7 +192,7 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
202 vb->state = VIDEOBUF_NEEDS_INIT; 192 vb->state = VIDEOBUF_NEEDS_INIT;
203 } 193 }
204 194
205 vb->size = bytes_per_line * vb->height; 195 vb->size = icd->sizeimage;
206 if (0 != vb->baddr && vb->bsize < vb->size) { 196 if (0 != vb->baddr && vb->bsize < vb->size) {
207 ret = -EINVAL; 197 ret = -EINVAL;
208 goto out; 198 goto out;
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 18afaeeadb7b..ded26b7286fa 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -22,6 +22,7 @@
22#include <linux/gcd.h> 22#include <linux/gcd.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/math64.h>
25#include <linux/mm.h> 26#include <linux/mm.h>
26#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
27#include <linux/time.h> 28#include <linux/time.h>
@@ -344,6 +345,19 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
344 PRP_INTR_CH2OVF, 345 PRP_INTR_CH2OVF,
345 } 346 }
346 }, 347 },
348 {
349 .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8,
350 .out_fmt = V4L2_PIX_FMT_YUV420,
351 .cfg = {
352 .channel = 2,
353 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
354 .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
355 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
356 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
357 PRP_INTR_CH2FC | PRP_INTR_LBOVF |
358 PRP_INTR_CH2OVF,
359 }
360 },
347}; 361};
348 362
349static struct mx2_fmt_cfg *mx27_emma_prp_get_format( 363static struct mx2_fmt_cfg *mx27_emma_prp_get_format(
@@ -525,8 +539,6 @@ static int mx2_videobuf_setup(struct vb2_queue *vq,
525 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 539 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
526 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 540 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
527 struct mx2_camera_dev *pcdev = ici->priv; 541 struct mx2_camera_dev *pcdev = ici->priv;
528 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
529 icd->current_fmt->host_fmt);
530 542
531 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]); 543 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]);
532 544
@@ -534,12 +546,9 @@ static int mx2_videobuf_setup(struct vb2_queue *vq,
534 if (fmt != NULL) 546 if (fmt != NULL)
535 return -ENOTTY; 547 return -ENOTTY;
536 548
537 if (bytes_per_line < 0)
538 return bytes_per_line;
539
540 alloc_ctxs[0] = pcdev->alloc_ctx; 549 alloc_ctxs[0] = pcdev->alloc_ctx;
541 550
542 sizes[0] = bytes_per_line * icd->user_height; 551 sizes[0] = icd->sizeimage;
543 552
544 if (0 == *count) 553 if (0 == *count)
545 *count = 32; 554 *count = 32;
@@ -555,16 +564,11 @@ static int mx2_videobuf_setup(struct vb2_queue *vq,
555static int mx2_videobuf_prepare(struct vb2_buffer *vb) 564static int mx2_videobuf_prepare(struct vb2_buffer *vb)
556{ 565{
557 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 566 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
558 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
559 icd->current_fmt->host_fmt);
560 int ret = 0; 567 int ret = 0;
561 568
562 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 569 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
563 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 570 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
564 571
565 if (bytes_per_line < 0)
566 return bytes_per_line;
567
568#ifdef DEBUG 572#ifdef DEBUG
569 /* 573 /*
570 * This can be useful if you want to see if we actually fill 574 * This can be useful if you want to see if we actually fill
@@ -574,7 +578,7 @@ static int mx2_videobuf_prepare(struct vb2_buffer *vb)
574 0xaa, vb2_get_plane_payload(vb, 0)); 578 0xaa, vb2_get_plane_payload(vb, 0));
575#endif 579#endif
576 580
577 vb2_set_plane_payload(vb, 0, bytes_per_line * icd->user_height); 581 vb2_set_plane_payload(vb, 0, icd->sizeimage);
578 if (vb2_plane_vaddr(vb, 0) && 582 if (vb2_plane_vaddr(vb, 0) &&
579 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { 583 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
580 ret = -EINVAL; 584 ret = -EINVAL;
@@ -980,6 +984,7 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
980 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 984 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
981 struct mx2_camera_dev *pcdev = ici->priv; 985 struct mx2_camera_dev *pcdev = ici->priv;
982 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; 986 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
987 const struct soc_camera_format_xlate *xlate;
983 unsigned long common_flags; 988 unsigned long common_flags;
984 int ret; 989 int ret;
985 int bytesperline; 990 int bytesperline;
@@ -1024,14 +1029,31 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
1024 return ret; 1029 return ret;
1025 } 1030 }
1026 1031
1032 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1033 if (!xlate) {
1034 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
1035 return -EINVAL;
1036 }
1037
1038 if (xlate->code == V4L2_MBUS_FMT_YUYV8_2X8) {
1039 csicr1 |= CSICR1_PACK_DIR;
1040 csicr1 &= ~CSICR1_SWAP16_EN;
1041 dev_dbg(icd->parent, "already yuyv format, don't convert\n");
1042 } else if (xlate->code == V4L2_MBUS_FMT_UYVY8_2X8) {
1043 csicr1 &= ~CSICR1_PACK_DIR;
1044 csicr1 |= CSICR1_SWAP16_EN;
1045 dev_dbg(icd->parent, "convert uyvy mbus format into yuyv\n");
1046 } else {
1047 dev_warn(icd->parent, "mbus format not supported\n");
1048 return -EINVAL;
1049 }
1050
1027 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) 1051 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
1028 csicr1 |= CSICR1_REDGE; 1052 csicr1 |= CSICR1_REDGE;
1029 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) 1053 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
1030 csicr1 |= CSICR1_SOF_POL; 1054 csicr1 |= CSICR1_SOF_POL;
1031 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) 1055 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
1032 csicr1 |= CSICR1_HSYNC_POL; 1056 csicr1 |= CSICR1_HSYNC_POL;
1033 if (pcdev->platform_flags & MX2_CAMERA_SWAP16)
1034 csicr1 |= CSICR1_SWAP16_EN;
1035 if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC) 1057 if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC)
1036 csicr1 |= CSICR1_EXT_VSYNC; 1058 csicr1 |= CSICR1_EXT_VSYNC;
1037 if (pcdev->platform_flags & MX2_CAMERA_CCIR) 1059 if (pcdev->platform_flags & MX2_CAMERA_CCIR)
@@ -1042,8 +1064,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
1042 csicr1 |= CSICR1_GCLK_MODE; 1064 csicr1 |= CSICR1_GCLK_MODE;
1043 if (pcdev->platform_flags & MX2_CAMERA_INV_DATA) 1065 if (pcdev->platform_flags & MX2_CAMERA_INV_DATA)
1044 csicr1 |= CSICR1_INV_DATA; 1066 csicr1 |= CSICR1_INV_DATA;
1045 if (pcdev->platform_flags & MX2_CAMERA_PACK_DIR_MSB)
1046 csicr1 |= CSICR1_PACK_DIR;
1047 1067
1048 pcdev->csicr1 = csicr1; 1068 pcdev->csicr1 = csicr1;
1049 1069
@@ -1118,7 +1138,8 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd,
1118 return 0; 1138 return 0;
1119 } 1139 }
1120 1140
1121 if (code == V4L2_MBUS_FMT_YUYV8_2X8) { 1141 if (code == V4L2_MBUS_FMT_YUYV8_2X8 ||
1142 code == V4L2_MBUS_FMT_UYVY8_2X8) {
1122 formats++; 1143 formats++;
1123 if (xlate) { 1144 if (xlate) {
1124 /* 1145 /*
@@ -1134,6 +1155,18 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd,
1134 } 1155 }
1135 } 1156 }
1136 1157
1158 if (code == V4L2_MBUS_FMT_UYVY8_2X8) {
1159 formats++;
1160 if (xlate) {
1161 xlate->host_fmt =
1162 soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8);
1163 xlate->code = code;
1164 dev_dbg(dev, "Providing host format %s for sensor code %d\n",
1165 xlate->host_fmt->name, code);
1166 xlate++;
1167 }
1168 }
1169
1137 /* Generic pass-trough */ 1170 /* Generic pass-trough */
1138 formats++; 1171 formats++;
1139 if (xlate) { 1172 if (xlate) {
@@ -1363,17 +1396,20 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1363 xlate->host_fmt); 1396 xlate->host_fmt);
1364 if (pix->bytesperline < 0) 1397 if (pix->bytesperline < 0)
1365 return pix->bytesperline; 1398 return pix->bytesperline;
1366 pix->sizeimage = pix->height * pix->bytesperline; 1399 pix->sizeimage = soc_mbus_image_size(xlate->host_fmt,
1400 pix->bytesperline, pix->height);
1367 /* Check against the CSIRXCNT limit */ 1401 /* Check against the CSIRXCNT limit */
1368 if (pix->sizeimage > 4 * 0x3ffff) { 1402 if (pix->sizeimage > 4 * 0x3ffff) {
1369 /* Adjust geometry, preserve aspect ratio */ 1403 /* Adjust geometry, preserve aspect ratio */
1370 unsigned int new_height = int_sqrt(4 * 0x3ffff * 1404 unsigned int new_height = int_sqrt(div_u64(0x3ffffULL *
1371 pix->height / pix->bytesperline); 1405 4 * pix->height, pix->bytesperline));
1372 pix->width = new_height * pix->width / pix->height; 1406 pix->width = new_height * pix->width / pix->height;
1373 pix->height = new_height; 1407 pix->height = new_height;
1374 pix->bytesperline = soc_mbus_bytes_per_line(pix->width, 1408 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
1375 xlate->host_fmt); 1409 xlate->host_fmt);
1376 BUG_ON(pix->bytesperline < 0); 1410 BUG_ON(pix->bytesperline < 0);
1411 pix->sizeimage = soc_mbus_image_size(xlate->host_fmt,
1412 pix->bytesperline, pix->height);
1377 } 1413 }
1378 } 1414 }
1379 1415
@@ -1752,6 +1788,8 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1752 pcdev->soc_host.priv = pcdev; 1788 pcdev->soc_host.priv = pcdev;
1753 pcdev->soc_host.v4l2_dev.dev = &pdev->dev; 1789 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1754 pcdev->soc_host.nr = pdev->id; 1790 pcdev->soc_host.nr = pdev->id;
1791 if (cpu_is_mx25())
1792 pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE;
1755 1793
1756 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 1794 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1757 if (IS_ERR(pcdev->alloc_ctx)) { 1795 if (IS_ERR(pcdev->alloc_ctx)) {
diff --git a/drivers/media/video/mx2_emmaprp.c b/drivers/media/video/mx2_emmaprp.c
index ba89a7401c8c..0bd5815de369 100644
--- a/drivers/media/video/mx2_emmaprp.c
+++ b/drivers/media/video/mx2_emmaprp.c
@@ -755,7 +755,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
755 755
756 memset(src_vq, 0, sizeof(*src_vq)); 756 memset(src_vq, 0, sizeof(*src_vq));
757 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 757 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
758 src_vq->io_modes = VB2_MMAP; 758 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
759 src_vq->drv_priv = ctx; 759 src_vq->drv_priv = ctx;
760 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 760 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
761 src_vq->ops = &emmaprp_qops; 761 src_vq->ops = &emmaprp_qops;
@@ -767,7 +767,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
767 767
768 memset(dst_vq, 0, sizeof(*dst_vq)); 768 memset(dst_vq, 0, sizeof(*dst_vq));
769 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 769 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
770 dst_vq->io_modes = VB2_MMAP; 770 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
771 dst_vq->drv_priv = ctx; 771 dst_vq->drv_priv = ctx;
772 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 772 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
773 dst_vq->ops = &emmaprp_qops; 773 dst_vq->ops = &emmaprp_qops;
@@ -904,6 +904,10 @@ static int emmaprp_probe(struct platform_device *pdev)
904 } 904 }
905 905
906 *vfd = emmaprp_videodev; 906 *vfd = emmaprp_videodev;
907 /* Locking in file operations other than ioctl should be done
908 by the driver, not the V4L2 core.
909 This driver needs auditing so that this flag can be removed. */
910 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
907 vfd->lock = &pcdev->dev_mutex; 911 vfd->lock = &pcdev->dev_mutex;
908 912
909 video_set_drvdata(vfd, pcdev); 913 video_set_drvdata(vfd, pcdev);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 93c35ef5f0ad..02d54a057b60 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -199,8 +199,6 @@ static int mx3_videobuf_setup(struct vb2_queue *vq,
199 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 199 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
200 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 200 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
201 struct mx3_camera_dev *mx3_cam = ici->priv; 201 struct mx3_camera_dev *mx3_cam = ici->priv;
202 int bytes_per_line;
203 unsigned int height;
204 202
205 if (!mx3_cam->idmac_channel[0]) 203 if (!mx3_cam->idmac_channel[0])
206 return -EINVAL; 204 return -EINVAL;
@@ -208,21 +206,29 @@ static int mx3_videobuf_setup(struct vb2_queue *vq,
208 if (fmt) { 206 if (fmt) {
209 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd, 207 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
210 fmt->fmt.pix.pixelformat); 208 fmt->fmt.pix.pixelformat);
209 unsigned int bytes_per_line;
210 int ret;
211
211 if (!xlate) 212 if (!xlate)
212 return -EINVAL; 213 return -EINVAL;
213 bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width, 214
214 xlate->host_fmt); 215 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
215 height = fmt->fmt.pix.height; 216 xlate->host_fmt);
217 if (ret < 0)
218 return ret;
219
220 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
221
222 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
223 fmt->fmt.pix.height);
224 if (ret < 0)
225 return ret;
226
227 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
216 } else { 228 } else {
217 /* Called from VIDIOC_REQBUFS or in compatibility mode */ 229 /* Called from VIDIOC_REQBUFS or in compatibility mode */
218 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 230 sizes[0] = icd->sizeimage;
219 icd->current_fmt->host_fmt);
220 height = icd->user_height;
221 } 231 }
222 if (bytes_per_line < 0)
223 return bytes_per_line;
224
225 sizes[0] = bytes_per_line * height;
226 232
227 alloc_ctxs[0] = mx3_cam->alloc_ctx; 233 alloc_ctxs[0] = mx3_cam->alloc_ctx;
228 234
@@ -267,14 +273,11 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
267 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 273 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
268 struct idmac_video_param *video = &ichan->params.video; 274 struct idmac_video_param *video = &ichan->params.video;
269 const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt; 275 const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
270 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, host_fmt);
271 unsigned long flags; 276 unsigned long flags;
272 dma_cookie_t cookie; 277 dma_cookie_t cookie;
273 size_t new_size; 278 size_t new_size;
274 279
275 BUG_ON(bytes_per_line <= 0); 280 new_size = icd->sizeimage;
276
277 new_size = bytes_per_line * icd->user_height;
278 281
279 if (vb2_plane_size(vb, 0) < new_size) { 282 if (vb2_plane_size(vb, 0) < new_size) {
280 dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n", 283 dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
@@ -314,9 +317,9 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
314 * horizontal parameters in this case are expressed in bytes, 317 * horizontal parameters in this case are expressed in bytes,
315 * not in pixels. 318 * not in pixels.
316 */ 319 */
317 video->out_width = bytes_per_line; 320 video->out_width = icd->bytesperline;
318 video->out_height = icd->user_height; 321 video->out_height = icd->user_height;
319 video->out_stride = bytes_per_line; 322 video->out_stride = icd->bytesperline;
320 } else { 323 } else {
321 /* 324 /*
322 * For IPU known formats the pixel unit will be managed 325 * For IPU known formats the pixel unit will be managed
@@ -642,12 +645,14 @@ static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
642 .bits_per_sample = 8, 645 .bits_per_sample = 8,
643 .packing = SOC_MBUS_PACKING_NONE, 646 .packing = SOC_MBUS_PACKING_NONE,
644 .order = SOC_MBUS_ORDER_LE, 647 .order = SOC_MBUS_ORDER_LE,
648 .layout = SOC_MBUS_LAYOUT_PACKED,
645 }, { 649 }, {
646 .fourcc = V4L2_PIX_FMT_GREY, 650 .fourcc = V4L2_PIX_FMT_GREY,
647 .name = "Monochrome 8 bit", 651 .name = "Monochrome 8 bit",
648 .bits_per_sample = 8, 652 .bits_per_sample = 8,
649 .packing = SOC_MBUS_PACKING_NONE, 653 .packing = SOC_MBUS_PACKING_NONE,
650 .order = SOC_MBUS_ORDER_LE, 654 .order = SOC_MBUS_ORDER_LE,
655 .layout = SOC_MBUS_LAYOUT_PACKED,
651 }, 656 },
652}; 657};
653 658
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 2e4131748438..b520a45cb3f3 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -31,10 +31,11 @@
31#include <media/saa7115.h> 31#include <media/saa7115.h>
32#include <linux/module.h> 32#include <linux/module.h>
33 33
34#include "mxb.h"
35#include "tea6415c.h" 34#include "tea6415c.h"
36#include "tea6420.h" 35#include "tea6420.h"
37 36
37#define MXB_AUDIOS 6
38
38#define I2C_SAA7111A 0x24 39#define I2C_SAA7111A 0x24
39#define I2C_TDA9840 0x42 40#define I2C_TDA9840 0x42
40#define I2C_TEA6415C 0x43 41#define I2C_TEA6415C 0x43
@@ -62,10 +63,14 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
62enum { TUNER, AUX1, AUX3, AUX3_YC }; 63enum { TUNER, AUX1, AUX3, AUX3_YC };
63 64
64static struct v4l2_input mxb_inputs[MXB_INPUTS] = { 65static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
65 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 66 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x3f, 0,
66 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 67 V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD },
67 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 68 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
68 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 69 V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
70 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
71 V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
72 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
73 V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
69}; 74};
70 75
71/* this array holds the information, which port of the saa7146 each 76/* this array holds the information, which port of the saa7146 each
@@ -90,6 +95,36 @@ struct mxb_routing {
90 u32 output; 95 u32 output;
91}; 96};
92 97
98/* these are the available audio sources, which can switched
99 to the line- and cd-output individually */
100static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
101 {
102 .index = 0,
103 .name = "Tuner",
104 .capability = V4L2_AUDCAP_STEREO,
105 } , {
106 .index = 1,
107 .name = "AUX1",
108 .capability = V4L2_AUDCAP_STEREO,
109 } , {
110 .index = 2,
111 .name = "AUX2",
112 .capability = V4L2_AUDCAP_STEREO,
113 } , {
114 .index = 3,
115 .name = "AUX3",
116 .capability = V4L2_AUDCAP_STEREO,
117 } , {
118 .index = 4,
119 .name = "Radio (X9)",
120 .capability = V4L2_AUDCAP_STEREO,
121 } , {
122 .index = 5,
123 .name = "CD-ROM (X10)",
124 .capability = V4L2_AUDCAP_STEREO,
125 }
126};
127
93/* These are the necessary input-output-pins for bringing one audio source 128/* These are the necessary input-output-pins for bringing one audio source
94 (see above) to the CD-output. Note that gain is set to 0 in this table. */ 129 (see above) to the CD-output. Note that gain is set to 0 in this table. */
95static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = { 130static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
@@ -114,11 +149,6 @@ static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
114 { { 6, 3 }, { 6, 2 } } /* Mute */ 149 { { 6, 3 }, { 6, 2 } } /* Mute */
115}; 150};
116 151
117#define MAXCONTROLS 1
118static struct v4l2_queryctrl mxb_controls[] = {
119 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
120};
121
122struct mxb 152struct mxb
123{ 153{
124 struct video_device *video_dev; 154 struct video_device *video_dev;
@@ -135,6 +165,7 @@ struct mxb
135 165
136 int cur_mode; /* current audio mode (mono, stereo, ...) */ 166 int cur_mode; /* current audio mode (mono, stereo, ...) */
137 int cur_input; /* current input */ 167 int cur_input; /* current input */
168 int cur_audinput; /* current audio input */
138 int cur_mute; /* current mute status */ 169 int cur_mute; /* current mute status */
139 struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ 170 struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
140}; 171};
@@ -150,16 +181,21 @@ struct mxb
150#define call_all(dev, o, f, args...) \ 181#define call_all(dev, o, f, args...) \
151 v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) 182 v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
152 183
153static inline void tea6420_route_cd(struct mxb *mxb, int idx) 184static void mxb_update_audmode(struct mxb *mxb)
185{
186 struct v4l2_tuner t = {
187 .audmode = mxb->cur_mode,
188 };
189
190 tda9840_call(mxb, tuner, s_tuner, &t);
191}
192
193static inline void tea6420_route(struct mxb *mxb, int idx)
154{ 194{
155 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, 195 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
156 TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0); 196 TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
157 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, 197 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
158 TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0); 198 TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
159}
160
161static inline void tea6420_route_line(struct mxb *mxb, int idx)
162{
163 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, 199 v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
164 TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0); 200 TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
165 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, 201 v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
@@ -168,16 +204,45 @@ static inline void tea6420_route_line(struct mxb *mxb, int idx)
168 204
169static struct saa7146_extension extension; 205static struct saa7146_extension extension;
170 206
207static int mxb_s_ctrl(struct v4l2_ctrl *ctrl)
208{
209 struct saa7146_dev *dev = container_of(ctrl->handler,
210 struct saa7146_dev, ctrl_handler);
211 struct mxb *mxb = dev->ext_priv;
212
213 switch (ctrl->id) {
214 case V4L2_CID_AUDIO_MUTE:
215 mxb->cur_mute = ctrl->val;
216 /* switch the audio-source */
217 tea6420_route(mxb, ctrl->val ? 6 :
218 video_audio_connect[mxb->cur_input]);
219 break;
220 default:
221 return -EINVAL;
222 }
223 return 0;
224}
225
226static const struct v4l2_ctrl_ops mxb_ctrl_ops = {
227 .s_ctrl = mxb_s_ctrl,
228};
229
171static int mxb_probe(struct saa7146_dev *dev) 230static int mxb_probe(struct saa7146_dev *dev)
172{ 231{
232 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
173 struct mxb *mxb = NULL; 233 struct mxb *mxb = NULL;
174 234
235 v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops,
236 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
237 if (hdl->error)
238 return hdl->error;
175 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); 239 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
176 if (mxb == NULL) { 240 if (mxb == NULL) {
177 DEB_D("not enough kernel memory\n"); 241 DEB_D("not enough kernel memory\n");
178 return -ENOMEM; 242 return -ENOMEM;
179 } 243 }
180 244
245
181 snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); 246 snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
182 247
183 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); 248 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
@@ -214,6 +279,8 @@ static int mxb_probe(struct saa7146_dev *dev)
214 /* we store the pointer in our private data field */ 279 /* we store the pointer in our private data field */
215 dev->ext_priv = mxb; 280 dev->ext_priv = mxb;
216 281
282 v4l2_ctrl_handler_setup(hdl);
283
217 return 0; 284 return 0;
218} 285}
219 286
@@ -286,6 +353,9 @@ static int mxb_init_done(struct saa7146_dev* dev)
286 353
287 int i = 0, err = 0; 354 int i = 0, err = 0;
288 355
356 /* mute audio on tea6420s */
357 tea6420_route(mxb, 6);
358
289 /* select video mode in saa7111a */ 359 /* select video mode in saa7111a */
290 saa7111a_call(mxb, core, s_std, std); 360 saa7111a_call(mxb, core, s_std, std);
291 361
@@ -306,12 +376,12 @@ static int mxb_init_done(struct saa7146_dev* dev)
306 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); 376 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
307 377
308 /* set a default video standard */ 378 /* set a default video standard */
379 /* These two gpio calls set the GPIO pins that control the tda9820 */
380 saa7146_write(dev, GPIO_CTRL, 0x00404050);
381 saa7111a_call(mxb, core, s_gpio, 1);
382 saa7111a_call(mxb, core, s_std, std);
309 tuner_call(mxb, core, s_std, std); 383 tuner_call(mxb, core, s_std, std);
310 384
311 /* mute audio on tea6420s */
312 tea6420_route_line(mxb, 6);
313 tea6420_route_cd(mxb, 6);
314
315 /* switch to tuner-channel on tea6415c */ 385 /* switch to tuner-channel on tea6415c */
316 tea6415c_call(mxb, video, s_routing, 3, 17, 0); 386 tea6415c_call(mxb, video, s_routing, 3, 17, 0);
317 387
@@ -320,9 +390,11 @@ static int mxb_init_done(struct saa7146_dev* dev)
320 390
321 /* the rest for mxb */ 391 /* the rest for mxb */
322 mxb->cur_input = 0; 392 mxb->cur_input = 0;
393 mxb->cur_audinput = video_audio_connect[mxb->cur_input];
323 mxb->cur_mute = 1; 394 mxb->cur_mute = 1;
324 395
325 mxb->cur_mode = V4L2_TUNER_MODE_STEREO; 396 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
397 mxb_update_audmode(mxb);
326 398
327 /* check if the saa7740 (aka 'sound arena module') is present 399 /* check if the saa7740 (aka 'sound arena module') is present
328 on the mxb. if so, we must initialize it. due to lack of 400 on the mxb. if so, we must initialize it. due to lack of
@@ -385,69 +457,6 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
385} 457}
386*/ 458*/
387 459
388static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
389{
390 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
391 int i;
392
393 for (i = MAXCONTROLS - 1; i >= 0; i--) {
394 if (mxb_controls[i].id == qc->id) {
395 *qc = mxb_controls[i];
396 DEB_D("VIDIOC_QUERYCTRL %d\n", qc->id);
397 return 0;
398 }
399 }
400 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
401}
402
403static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
404{
405 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
406 struct mxb *mxb = (struct mxb *)dev->ext_priv;
407 int i;
408
409 for (i = MAXCONTROLS - 1; i >= 0; i--) {
410 if (mxb_controls[i].id == vc->id)
411 break;
412 }
413
414 if (i < 0)
415 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
416
417 if (vc->id == V4L2_CID_AUDIO_MUTE) {
418 vc->value = mxb->cur_mute;
419 DEB_D("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d\n", vc->value);
420 return 0;
421 }
422
423 DEB_EE("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d\n", vc->value);
424 return 0;
425}
426
427static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
428{
429 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
430 struct mxb *mxb = (struct mxb *)dev->ext_priv;
431 int i = 0;
432
433 for (i = MAXCONTROLS - 1; i >= 0; i--) {
434 if (mxb_controls[i].id == vc->id)
435 break;
436 }
437
438 if (i < 0)
439 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
440
441 if (vc->id == V4L2_CID_AUDIO_MUTE) {
442 mxb->cur_mute = vc->value;
443 /* switch the audio-source */
444 tea6420_route_line(mxb, vc->value ? 6 :
445 video_audio_connect[mxb->cur_input]);
446 DEB_EE("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d\n", vc->value);
447 }
448 return 0;
449}
450
451static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) 460static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
452{ 461{
453 DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index); 462 DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
@@ -519,9 +528,12 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
519 if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0)) 528 if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
520 pr_err("VIDIOC_S_INPUT: could not address saa7111a\n"); 529 pr_err("VIDIOC_S_INPUT: could not address saa7111a\n");
521 530
531 mxb->cur_audinput = video_audio_connect[input];
522 /* switch the audio-source only if necessary */ 532 /* switch the audio-source only if necessary */
523 if (0 == mxb->cur_mute) 533 if (0 == mxb->cur_mute)
524 tea6420_route_line(mxb, video_audio_connect[input]); 534 tea6420_route(mxb, mxb->cur_audinput);
535 if (mxb->cur_audinput == 0)
536 mxb_update_audmode(mxb);
525 537
526 return 0; 538 return 0;
527} 539}
@@ -563,17 +575,20 @@ static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
563 return call_all(dev, tuner, s_tuner, t); 575 return call_all(dev, tuner, s_tuner, t);
564} 576}
565 577
578static int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm)
579{
580 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
581
582 return call_all(dev, video, querystd, norm);
583}
584
566static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) 585static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
567{ 586{
568 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 587 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
569 struct mxb *mxb = (struct mxb *)dev->ext_priv; 588 struct mxb *mxb = (struct mxb *)dev->ext_priv;
570 589
571 if (mxb->cur_input) { 590 if (f->tuner)
572 DEB_D("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
573 mxb->cur_input);
574 return -EINVAL; 591 return -EINVAL;
575 }
576
577 *f = mxb->cur_freq; 592 *f = mxb->cur_freq;
578 593
579 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency); 594 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency);
@@ -592,17 +607,18 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency
592 if (V4L2_TUNER_ANALOG_TV != f->type) 607 if (V4L2_TUNER_ANALOG_TV != f->type)
593 return -EINVAL; 608 return -EINVAL;
594 609
595 if (mxb->cur_input) {
596 DEB_D("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",
597 mxb->cur_input);
598 return -EINVAL;
599 }
600
601 mxb->cur_freq = *f;
602 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency); 610 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency);
603 611
604 /* tune in desired frequency */ 612 /* tune in desired frequency */
605 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); 613 tuner_call(mxb, tuner, s_frequency, f);
614 /* let the tuner subdev clamp the frequency to the tuner range */
615 tuner_call(mxb, tuner, g_frequency, f);
616 mxb->cur_freq = *f;
617 if (mxb->cur_audinput == 0)
618 mxb_update_audmode(mxb);
619
620 if (mxb->cur_input)
621 return 0;
606 622
607 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ 623 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
608 spin_lock(&dev->slock); 624 spin_lock(&dev->slock);
@@ -612,25 +628,40 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency
612 return 0; 628 return 0;
613} 629}
614 630
631static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
632{
633 if (a->index >= MXB_AUDIOS)
634 return -EINVAL;
635 *a = mxb_audios[a->index];
636 return 0;
637}
638
615static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 639static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
616{ 640{
617 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 641 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
618 struct mxb *mxb = (struct mxb *)dev->ext_priv; 642 struct mxb *mxb = (struct mxb *)dev->ext_priv;
619 643
620 if (a->index > MXB_INPUTS) { 644 DEB_EE("VIDIOC_G_AUDIO\n");
621 DEB_D("VIDIOC_G_AUDIO %d out of range\n", a->index); 645 *a = mxb_audios[mxb->cur_audinput];
622 return -EINVAL;
623 }
624
625 DEB_EE("VIDIOC_G_AUDIO %d\n", a->index);
626 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
627 return 0; 646 return 0;
628} 647}
629 648
630static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) 649static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
631{ 650{
651 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
652 struct mxb *mxb = (struct mxb *)dev->ext_priv;
653
632 DEB_D("VIDIOC_S_AUDIO %d\n", a->index); 654 DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
633 return 0; 655 if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) {
656 if (mxb->cur_audinput != a->index) {
657 mxb->cur_audinput = a->index;
658 tea6420_route(mxb, a->index);
659 if (mxb->cur_audinput == 0)
660 mxb_update_audmode(mxb);
661 }
662 return 0;
663 }
664 return -EINVAL;
634} 665}
635 666
636#ifdef CONFIG_VIDEO_ADV_DEBUG 667#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -638,60 +669,31 @@ static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_regist
638{ 669{
639 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 670 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
640 671
641 return call_all(dev, core, g_register, reg); 672 if (!capable(CAP_SYS_ADMIN))
673 return -EPERM;
674 if (v4l2_chip_match_host(&reg->match)) {
675 reg->val = saa7146_read(dev, reg->reg);
676 reg->size = 4;
677 return 0;
678 }
679 call_all(dev, core, g_register, reg);
680 return 0;
642} 681}
643 682
644static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) 683static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
645{ 684{
646 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 685 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
647 686
648 return call_all(dev, core, s_register, reg); 687 if (!capable(CAP_SYS_ADMIN))
649} 688 return -EPERM;
650#endif 689 if (v4l2_chip_match_host(&reg->match)) {
651 690 saa7146_write(dev, reg->reg, reg->val);
652static long vidioc_default(struct file *file, void *fh, bool valid_prio, 691 reg->size = 4;
653 int cmd, void *arg)
654{
655 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
656 struct mxb *mxb = (struct mxb *)dev->ext_priv;
657
658 switch (cmd) {
659 case MXB_S_AUDIO_CD:
660 {
661 int i = *(int *)arg;
662
663 if (i < 0 || i >= MXB_AUDIOS) {
664 DEB_D("invalid argument to MXB_S_AUDIO_CD: i:%d\n", i);
665 return -EINVAL;
666 }
667
668 DEB_EE("MXB_S_AUDIO_CD: i:%d\n", i);
669
670 tea6420_route_cd(mxb, i);
671 return 0;
672 }
673 case MXB_S_AUDIO_LINE:
674 {
675 int i = *(int *)arg;
676
677 if (i < 0 || i >= MXB_AUDIOS) {
678 DEB_D("invalid argument to MXB_S_AUDIO_LINE: i:%d\n",
679 i);
680 return -EINVAL;
681 }
682
683 DEB_EE("MXB_S_AUDIO_LINE: i:%d\n", i);
684 tea6420_route_line(mxb, i);
685 return 0; 692 return 0;
686 } 693 }
687 default: 694 return call_all(dev, core, s_register, reg);
688/*
689 DEB2(pr_err("does not handle this ioctl\n"));
690*/
691 return -ENOIOCTLCMD;
692 }
693 return 0;
694} 695}
696#endif
695 697
696static struct saa7146_ext_vv vv_data; 698static struct saa7146_ext_vv vv_data;
697 699
@@ -709,23 +711,21 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data
709 } 711 }
710 mxb = (struct mxb *)dev->ext_priv; 712 mxb = (struct mxb *)dev->ext_priv;
711 713
712 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl; 714 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
713 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl; 715 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
714 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl; 716 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
715 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 717 vv_data.vid_ops.vidioc_querystd = vidioc_querystd;
716 vv_data.ops.vidioc_g_input = vidioc_g_input; 718 vv_data.vid_ops.vidioc_g_tuner = vidioc_g_tuner;
717 vv_data.ops.vidioc_s_input = vidioc_s_input; 719 vv_data.vid_ops.vidioc_s_tuner = vidioc_s_tuner;
718 vv_data.ops.vidioc_g_tuner = vidioc_g_tuner; 720 vv_data.vid_ops.vidioc_g_frequency = vidioc_g_frequency;
719 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner; 721 vv_data.vid_ops.vidioc_s_frequency = vidioc_s_frequency;
720 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency; 722 vv_data.vid_ops.vidioc_enumaudio = vidioc_enumaudio;
721 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency; 723 vv_data.vid_ops.vidioc_g_audio = vidioc_g_audio;
722 vv_data.ops.vidioc_g_audio = vidioc_g_audio; 724 vv_data.vid_ops.vidioc_s_audio = vidioc_s_audio;
723 vv_data.ops.vidioc_s_audio = vidioc_s_audio;
724#ifdef CONFIG_VIDEO_ADV_DEBUG 725#ifdef CONFIG_VIDEO_ADV_DEBUG
725 vv_data.ops.vidioc_g_register = vidioc_g_register; 726 vv_data.vid_ops.vidioc_g_register = vidioc_g_register;
726 vv_data.ops.vidioc_s_register = vidioc_s_register; 727 vv_data.vid_ops.vidioc_s_register = vidioc_s_register;
727#endif 728#endif
728 vv_data.ops.vidioc_default = vidioc_default;
729 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { 729 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
730 ERR("cannot register capture v4l2 device. skipping.\n"); 730 ERR("cannot register capture v4l2 device. skipping.\n");
731 saa7146_vv_release(dev); 731 saa7146_vv_release(dev);
@@ -752,6 +752,9 @@ static int mxb_detach(struct saa7146_dev *dev)
752 752
753 DEB_EE("dev:%p\n", dev); 753 DEB_EE("dev:%p\n", dev);
754 754
755 /* mute audio on tea6420s */
756 tea6420_route(mxb, 6);
757
755 saa7146_unregister_device(&mxb->video_dev,dev); 758 saa7146_unregister_device(&mxb->video_dev,dev);
756 if (MXB_BOARD_CAN_DO_VBI(dev)) 759 if (MXB_BOARD_CAN_DO_VBI(dev))
757 saa7146_unregister_device(&mxb->vbi_dev, dev); 760 saa7146_unregister_device(&mxb->vbi_dev, dev);
@@ -773,20 +776,24 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
773 v4l2_std_id std = V4L2_STD_PAL_I; 776 v4l2_std_id std = V4L2_STD_PAL_I;
774 777
775 DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n"); 778 DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n");
776 /* set the 7146 gpio register -- I don't know what this does exactly */ 779 /* These two gpio calls set the GPIO pins that control the tda9820 */
777 saa7146_write(dev, GPIO_CTRL, 0x00404050); 780 saa7146_write(dev, GPIO_CTRL, 0x00404050);
778 /* unset the 7111 gpio register -- I don't know what this does exactly */
779 saa7111a_call(mxb, core, s_gpio, 0); 781 saa7111a_call(mxb, core, s_gpio, 0);
780 tuner_call(mxb, core, s_std, std); 782 saa7111a_call(mxb, core, s_std, std);
783 if (mxb->cur_input == 0)
784 tuner_call(mxb, core, s_std, std);
781 } else { 785 } else {
782 v4l2_std_id std = V4L2_STD_PAL_BG; 786 v4l2_std_id std = V4L2_STD_PAL_BG;
783 787
788 if (mxb->cur_input)
789 std = standard->id;
784 DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n"); 790 DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n");
785 /* set the 7146 gpio register -- I don't know what this does exactly */ 791 /* These two gpio calls set the GPIO pins that control the tda9820 */
786 saa7146_write(dev, GPIO_CTRL, 0x00404050); 792 saa7146_write(dev, GPIO_CTRL, 0x00404050);
787 /* set the 7111 gpio register -- I don't know what this does exactly */
788 saa7111a_call(mxb, core, s_gpio, 1); 793 saa7111a_call(mxb, core, s_gpio, 1);
789 tuner_call(mxb, core, s_std, std); 794 saa7111a_call(mxb, core, s_std, std);
795 if (mxb->cur_input == 0)
796 tuner_call(mxb, core, s_std, std);
790 } 797 }
791 return 0; 798 return 0;
792} 799}
@@ -836,14 +843,14 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
836 843
837static struct saa7146_ext_vv vv_data = { 844static struct saa7146_ext_vv vv_data = {
838 .inputs = MXB_INPUTS, 845 .inputs = MXB_INPUTS,
839 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, 846 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO,
840 .stds = &standard[0], 847 .stds = &standard[0],
841 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), 848 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
842 .std_callback = &std_callback, 849 .std_callback = &std_callback,
843}; 850};
844 851
845static struct saa7146_extension extension = { 852static struct saa7146_extension extension = {
846 .name = MXB_IDENTIFIER, 853 .name = "Multimedia eXtension Board",
847 .flags = SAA7146_USE_I2C_IRQ, 854 .flags = SAA7146_USE_I2C_IRQ,
848 855
849 .pci_tbl = &pci_tbl[0], 856 .pci_tbl = &pci_tbl[0],
diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h
deleted file mode 100644
index 400a57ba62ec..000000000000
--- a/drivers/media/video/mxb.h
+++ /dev/null
@@ -1,42 +0,0 @@
1#ifndef __MXB__
2#define __MXB__
3
4#define BASE_VIDIOC_MXB 10
5
6#define MXB_S_AUDIO_CD _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+0, int)
7#define MXB_S_AUDIO_LINE _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+1, int)
8
9#define MXB_IDENTIFIER "Multimedia eXtension Board"
10
11#define MXB_AUDIOS 6
12
13/* these are the available audio sources, which can switched
14 to the line- and cd-output individually */
15static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
16 {
17 .index = 0,
18 .name = "Tuner",
19 .capability = V4L2_AUDCAP_STEREO,
20 } , {
21 .index = 1,
22 .name = "AUX1",
23 .capability = V4L2_AUDCAP_STEREO,
24 } , {
25 .index = 2,
26 .name = "AUX2",
27 .capability = V4L2_AUDCAP_STEREO,
28 } , {
29 .index = 3,
30 .name = "AUX3",
31 .capability = V4L2_AUDCAP_STEREO,
32 } , {
33 .index = 4,
34 .name = "Radio (X9)",
35 .capability = V4L2_AUDCAP_STEREO,
36 } , {
37 .index = 5,
38 .name = "CD-ROM (X10)",
39 .capability = V4L2_AUDCAP_STEREO,
40 }
41};
42#endif
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index c20f5ecd6790..c7e41145041f 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -206,15 +206,10 @@ static int omap1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
206 unsigned int *size) 206 unsigned int *size)
207{ 207{
208 struct soc_camera_device *icd = vq->priv_data; 208 struct soc_camera_device *icd = vq->priv_data;
209 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
210 icd->current_fmt->host_fmt);
211 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 209 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
212 struct omap1_cam_dev *pcdev = ici->priv; 210 struct omap1_cam_dev *pcdev = ici->priv;
213 211
214 if (bytes_per_line < 0) 212 *size = icd->sizeimage;
215 return bytes_per_line;
216
217 *size = bytes_per_line * icd->user_height;
218 213
219 if (!*count || *count < OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode)) 214 if (!*count || *count < OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode))
220 *count = OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode); 215 *count = OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode);
@@ -256,15 +251,10 @@ static int omap1_videobuf_prepare(struct videobuf_queue *vq,
256{ 251{
257 struct soc_camera_device *icd = vq->priv_data; 252 struct soc_camera_device *icd = vq->priv_data;
258 struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb); 253 struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb);
259 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
260 icd->current_fmt->host_fmt);
261 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 254 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
262 struct omap1_cam_dev *pcdev = ici->priv; 255 struct omap1_cam_dev *pcdev = ici->priv;
263 int ret; 256 int ret;
264 257
265 if (bytes_per_line < 0)
266 return bytes_per_line;
267
268 WARN_ON(!list_empty(&vb->queue)); 258 WARN_ON(!list_empty(&vb->queue));
269 259
270 BUG_ON(NULL == icd->current_fmt); 260 BUG_ON(NULL == icd->current_fmt);
@@ -281,7 +271,7 @@ static int omap1_videobuf_prepare(struct videobuf_queue *vq,
281 vb->state = VIDEOBUF_NEEDS_INIT; 271 vb->state = VIDEOBUF_NEEDS_INIT;
282 } 272 }
283 273
284 vb->size = bytes_per_line * vb->height; 274 vb->size = icd->sizeimage;
285 275
286 if (vb->baddr && vb->bsize < vb->size) { 276 if (vb->baddr && vb->bsize < vb->size) {
287 ret = -EINVAL; 277 ret = -EINVAL;
@@ -999,6 +989,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
999 .bits_per_sample = 8, 989 .bits_per_sample = 8,
1000 .packing = SOC_MBUS_PACKING_2X8_PADHI, 990 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1001 .order = SOC_MBUS_ORDER_BE, 991 .order = SOC_MBUS_ORDER_BE,
992 .layout = SOC_MBUS_LAYOUT_PACKED,
1002 }, 993 },
1003}, { 994}, {
1004 .code = V4L2_MBUS_FMT_VYUY8_2X8, 995 .code = V4L2_MBUS_FMT_VYUY8_2X8,
@@ -1008,6 +999,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1008 .bits_per_sample = 8, 999 .bits_per_sample = 8,
1009 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1000 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1010 .order = SOC_MBUS_ORDER_BE, 1001 .order = SOC_MBUS_ORDER_BE,
1002 .layout = SOC_MBUS_LAYOUT_PACKED,
1011 }, 1003 },
1012}, { 1004}, {
1013 .code = V4L2_MBUS_FMT_YUYV8_2X8, 1005 .code = V4L2_MBUS_FMT_YUYV8_2X8,
@@ -1017,6 +1009,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1017 .bits_per_sample = 8, 1009 .bits_per_sample = 8,
1018 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1010 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1019 .order = SOC_MBUS_ORDER_BE, 1011 .order = SOC_MBUS_ORDER_BE,
1012 .layout = SOC_MBUS_LAYOUT_PACKED,
1020 }, 1013 },
1021}, { 1014}, {
1022 .code = V4L2_MBUS_FMT_YVYU8_2X8, 1015 .code = V4L2_MBUS_FMT_YVYU8_2X8,
@@ -1026,6 +1019,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1026 .bits_per_sample = 8, 1019 .bits_per_sample = 8,
1027 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1020 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1028 .order = SOC_MBUS_ORDER_BE, 1021 .order = SOC_MBUS_ORDER_BE,
1022 .layout = SOC_MBUS_LAYOUT_PACKED,
1029 }, 1023 },
1030}, { 1024}, {
1031 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, 1025 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
@@ -1035,6 +1029,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1035 .bits_per_sample = 8, 1029 .bits_per_sample = 8,
1036 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1030 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1037 .order = SOC_MBUS_ORDER_BE, 1031 .order = SOC_MBUS_ORDER_BE,
1032 .layout = SOC_MBUS_LAYOUT_PACKED,
1038 }, 1033 },
1039}, { 1034}, {
1040 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 1035 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
@@ -1044,6 +1039,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1044 .bits_per_sample = 8, 1039 .bits_per_sample = 8,
1045 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1040 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1046 .order = SOC_MBUS_ORDER_BE, 1041 .order = SOC_MBUS_ORDER_BE,
1042 .layout = SOC_MBUS_LAYOUT_PACKED,
1047 }, 1043 },
1048}, { 1044}, {
1049 .code = V4L2_MBUS_FMT_RGB565_2X8_BE, 1045 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
@@ -1053,6 +1049,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1053 .bits_per_sample = 8, 1049 .bits_per_sample = 8,
1054 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1050 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1055 .order = SOC_MBUS_ORDER_BE, 1051 .order = SOC_MBUS_ORDER_BE,
1052 .layout = SOC_MBUS_LAYOUT_PACKED,
1056 }, 1053 },
1057}, { 1054}, {
1058 .code = V4L2_MBUS_FMT_RGB565_2X8_LE, 1055 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
@@ -1062,6 +1059,7 @@ static const struct soc_mbus_lookup omap1_cam_formats[] = {
1062 .bits_per_sample = 8, 1059 .bits_per_sample = 8,
1063 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1060 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1064 .order = SOC_MBUS_ORDER_BE, 1061 .order = SOC_MBUS_ORDER_BE,
1062 .layout = SOC_MBUS_LAYOUT_PACKED,
1065 }, 1063 },
1066}, 1064},
1067}; 1065};
diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/video/omap24xxcam-dma.c
index 3ea38a8def8e..b5ae170de4a5 100644
--- a/drivers/media/video/omap24xxcam-dma.c
+++ b/drivers/media/video/omap24xxcam-dma.c
@@ -38,7 +38,7 @@
38 */ 38 */
39 39
40/* Ack all interrupt on CSR and IRQSTATUS_L0 */ 40/* Ack all interrupt on CSR and IRQSTATUS_L0 */
41static void omap24xxcam_dmahw_ack_all(unsigned long base) 41static void omap24xxcam_dmahw_ack_all(void __iomem *base)
42{ 42{
43 u32 csr; 43 u32 csr;
44 int i; 44 int i;
@@ -52,7 +52,7 @@ static void omap24xxcam_dmahw_ack_all(unsigned long base)
52} 52}
53 53
54/* Ack dmach on CSR and IRQSTATUS_L0 */ 54/* Ack dmach on CSR and IRQSTATUS_L0 */
55static u32 omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach) 55static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach)
56{ 56{
57 u32 csr; 57 u32 csr;
58 58
@@ -65,12 +65,12 @@ static u32 omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach)
65 return csr; 65 return csr;
66} 66}
67 67
68static int omap24xxcam_dmahw_running(unsigned long base, int dmach) 68static int omap24xxcam_dmahw_running(void __iomem *base, int dmach)
69{ 69{
70 return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE; 70 return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE;
71} 71}
72 72
73static void omap24xxcam_dmahw_transfer_setup(unsigned long base, int dmach, 73static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach,
74 dma_addr_t start, u32 len) 74 dma_addr_t start, u32 len)
75{ 75{
76 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), 76 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
@@ -112,7 +112,7 @@ static void omap24xxcam_dmahw_transfer_setup(unsigned long base, int dmach,
112 | CAMDMA_CICR_DROP_IE); 112 | CAMDMA_CICR_DROP_IE);
113} 113}
114 114
115static void omap24xxcam_dmahw_transfer_start(unsigned long base, int dmach) 115static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach)
116{ 116{
117 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), 117 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
118 CAMDMA_CCR_SEL_SRC_DST_SYNC 118 CAMDMA_CCR_SEL_SRC_DST_SYNC
@@ -124,7 +124,7 @@ static void omap24xxcam_dmahw_transfer_start(unsigned long base, int dmach)
124 | CAMDMA_CCR_SYNCHRO_CAMERA); 124 | CAMDMA_CCR_SYNCHRO_CAMERA);
125} 125}
126 126
127static void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach, 127static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach,
128 int free_dmach) 128 int free_dmach)
129{ 129{
130 int prev_dmach, ch; 130 int prev_dmach, ch;
@@ -160,7 +160,7 @@ static void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach,
160 * controller may not be idle after this routine completes, because 160 * controller may not be idle after this routine completes, because
161 * the completion routines might start new transfers. 161 * the completion routines might start new transfers.
162 */ 162 */
163static void omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach) 163static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach)
164{ 164{
165 /* mask all interrupts from this channel */ 165 /* mask all interrupts from this channel */
166 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0); 166 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
@@ -171,7 +171,7 @@ static void omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach)
171 omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE); 171 omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
172} 172}
173 173
174static void omap24xxcam_dmahw_init(unsigned long base) 174static void omap24xxcam_dmahw_init(void __iomem *base)
175{ 175{
176 omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG, 176 omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
177 CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY 177 CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
@@ -362,7 +362,7 @@ void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma)
362} 362}
363 363
364static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma, 364static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma,
365 unsigned long base) 365 void __iomem *base)
366{ 366{
367 int ch; 367 int ch;
368 368
@@ -577,7 +577,7 @@ void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
577} 577}
578 578
579void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, 579void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
580 unsigned long base, 580 void __iomem *base,
581 void (*reset_callback)(unsigned long data), 581 void (*reset_callback)(unsigned long data),
582 unsigned long reset_callback_data) 582 unsigned long reset_callback_data)
583{ 583{
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 7d3864144368..e5015b0d5508 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -1776,8 +1776,7 @@ static int __devinit omap24xxcam_probe(struct platform_device *pdev)
1776 cam->mmio_size = resource_size(mem); 1776 cam->mmio_size = resource_size(mem);
1777 1777
1778 /* map the region */ 1778 /* map the region */
1779 cam->mmio_base = (unsigned long) 1779 cam->mmio_base = ioremap_nocache(cam->mmio_base_phys, cam->mmio_size);
1780 ioremap_nocache(cam->mmio_base_phys, cam->mmio_size);
1781 if (!cam->mmio_base) { 1780 if (!cam->mmio_base) {
1782 dev_err(cam->dev, "cannot map camera register I/O region\n"); 1781 dev_err(cam->dev, "cannot map camera register I/O region\n");
1783 goto err; 1782 goto err;
diff --git a/drivers/media/video/omap24xxcam.h b/drivers/media/video/omap24xxcam.h
index 2ce67f5a48d5..d59727afe894 100644
--- a/drivers/media/video/omap24xxcam.h
+++ b/drivers/media/video/omap24xxcam.h
@@ -429,7 +429,7 @@ struct sgdma_state {
429struct omap24xxcam_dma { 429struct omap24xxcam_dma {
430 spinlock_t lock; /* Lock for the whole structure. */ 430 spinlock_t lock; /* Lock for the whole structure. */
431 431
432 unsigned long base; /* base address for dma controller */ 432 void __iomem *base; /* base address for dma controller */
433 433
434 /* While dma_stop!=0, an attempt to start a new DMA transfer will 434 /* While dma_stop!=0, an attempt to start a new DMA transfer will
435 * fail. 435 * fail.
@@ -491,7 +491,7 @@ struct omap24xxcam_device {
491 491
492 /*** hardware resources ***/ 492 /*** hardware resources ***/
493 unsigned int irq; 493 unsigned int irq;
494 unsigned long mmio_base; 494 void __iomem *mmio_base;
495 unsigned long mmio_base_phys; 495 unsigned long mmio_base_phys;
496 unsigned long mmio_size; 496 unsigned long mmio_size;
497 497
@@ -544,22 +544,22 @@ struct omap24xxcam_fh {
544 * 544 *
545 */ 545 */
546 546
547static inline u32 omap24xxcam_reg_in(unsigned long base, u32 offset) 547static inline u32 omap24xxcam_reg_in(u32 __iomem *base, u32 offset)
548{ 548{
549 return readl(base + offset); 549 return readl(base + offset);
550} 550}
551 551
552static inline u32 omap24xxcam_reg_out(unsigned long base, u32 offset, 552static inline u32 omap24xxcam_reg_out(u32 __iomem *base, u32 offset,
553 u32 val) 553 u32 val)
554{ 554{
555 writel(val, base + offset); 555 writel(val, base + offset);
556 return val; 556 return val;
557} 557}
558 558
559static inline u32 omap24xxcam_reg_merge(unsigned long base, u32 offset, 559static inline u32 omap24xxcam_reg_merge(u32 __iomem *base, u32 offset,
560 u32 val, u32 mask) 560 u32 val, u32 mask)
561{ 561{
562 u32 addr = base + offset; 562 u32 __iomem *addr = base + offset;
563 u32 new_val = (readl(addr) & ~mask) | (val & mask); 563 u32 new_val = (readl(addr) & ~mask) | (val & mask);
564 564
565 writel(new_val, addr); 565 writel(new_val, addr);
@@ -585,7 +585,7 @@ int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
585 int len, sgdma_callback_t callback, void *arg); 585 int len, sgdma_callback_t callback, void *arg);
586void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma); 586void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma);
587void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma, 587void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
588 unsigned long base, 588 void __iomem *base,
589 void (*reset_callback)(unsigned long data), 589 void (*reset_callback)(unsigned long data),
590 unsigned long reset_callback_data); 590 unsigned long reset_callback_data);
591void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma); 591void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma);
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
index 12d5f923e1d0..1c347633e663 100644
--- a/drivers/media/video/omap3isp/isp.c
+++ b/drivers/media/video/omap3isp/isp.c
@@ -329,19 +329,6 @@ void omap3isp_configure_bridge(struct isp_device *isp,
329 isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL); 329 isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
330} 330}
331 331
332/**
333 * isp_set_pixel_clock - Configures the ISP pixel clock
334 * @isp: OMAP3 ISP device
335 * @pixelclk: Average pixel clock in Hz
336 *
337 * Set the average pixel clock required by the sensor. The ISP will use the
338 * lowest possible memory bandwidth settings compatible with the clock.
339 **/
340static void isp_set_pixel_clock(struct isp_device *isp, unsigned int pixelclk)
341{
342 isp->isp_ccdc.vpcfg.pixelclk = pixelclk;
343}
344
345void omap3isp_hist_dma_done(struct isp_device *isp) 332void omap3isp_hist_dma_done(struct isp_device *isp)
346{ 333{
347 if (omap3isp_ccdc_busy(&isp->isp_ccdc) || 334 if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||
@@ -739,6 +726,17 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
739 unsigned long flags; 726 unsigned long flags;
740 int ret; 727 int ret;
741 728
729 /* If the preview engine crashed it might not respond to read/write
730 * operations on the L4 bus. This would result in a bus fault and a
731 * kernel oops. Refuse to start streaming in that case. This check must
732 * be performed before the loop below to avoid starting entities if the
733 * pipeline won't start anyway (those entities would then likely fail to
734 * stop, making the problem worse).
735 */
736 if ((pipe->entities & isp->crashed) &
737 (1U << isp->isp_prev.subdev.entity.id))
738 return -EIO;
739
742 spin_lock_irqsave(&pipe->lock, flags); 740 spin_lock_irqsave(&pipe->lock, flags);
743 pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT); 741 pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);
744 spin_unlock_irqrestore(&pipe->lock, flags); 742 spin_unlock_irqrestore(&pipe->lock, flags);
@@ -774,14 +772,6 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
774 } 772 }
775 } 773 }
776 774
777 /* Frame number propagation. In continuous streaming mode the number
778 * is incremented in the frame start ISR. In mem-to-mem mode
779 * singleshot is used and frame start IRQs are not available.
780 * Thus we have to increment the number here.
781 */
782 if (pipe->do_propagation && mode == ISP_PIPELINE_STREAM_SINGLESHOT)
783 atomic_inc(&pipe->frame_number);
784
785 return 0; 775 return 0;
786} 776}
787 777
@@ -879,13 +869,15 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
879 869
880 if (ret) { 870 if (ret) {
881 dev_info(isp->dev, "Unable to stop %s\n", subdev->name); 871 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
872 /* If the entity failed to stopped, assume it has
873 * crashed. Mark it as such, the ISP will be reset when
874 * applications will release it.
875 */
876 isp->crashed |= 1U << subdev->entity.id;
882 failure = -ETIMEDOUT; 877 failure = -ETIMEDOUT;
883 } 878 }
884 } 879 }
885 880
886 if (failure < 0)
887 isp->needs_reset = true;
888
889 return failure; 881 return failure;
890} 882}
891 883
@@ -1069,6 +1061,7 @@ static int isp_reset(struct isp_device *isp)
1069 udelay(1); 1061 udelay(1);
1070 } 1062 }
1071 1063
1064 isp->crashed = 0;
1072 return 0; 1065 return 0;
1073} 1066}
1074 1067
@@ -1495,11 +1488,13 @@ void omap3isp_put(struct isp_device *isp)
1495 BUG_ON(isp->ref_count == 0); 1488 BUG_ON(isp->ref_count == 0);
1496 if (--isp->ref_count == 0) { 1489 if (--isp->ref_count == 0) {
1497 isp_disable_interrupts(isp); 1490 isp_disable_interrupts(isp);
1498 isp_save_ctx(isp); 1491 if (isp->domain)
1499 if (isp->needs_reset) { 1492 isp_save_ctx(isp);
1493 /* Reset the ISP if an entity has failed to stop. This is the
1494 * only way to recover from such conditions.
1495 */
1496 if (isp->crashed)
1500 isp_reset(isp); 1497 isp_reset(isp);
1501 isp->needs_reset = false;
1502 }
1503 isp_disable_clocks(isp); 1498 isp_disable_clocks(isp);
1504 } 1499 }
1505 mutex_unlock(&isp->isp_mutex); 1500 mutex_unlock(&isp->isp_mutex);
@@ -1970,7 +1965,7 @@ error_csiphy:
1970 * 1965 *
1971 * Always returns 0. 1966 * Always returns 0.
1972 */ 1967 */
1973static int isp_remove(struct platform_device *pdev) 1968static int __devexit isp_remove(struct platform_device *pdev)
1974{ 1969{
1975 struct isp_device *isp = platform_get_drvdata(pdev); 1970 struct isp_device *isp = platform_get_drvdata(pdev);
1976 int i; 1971 int i;
@@ -1981,6 +1976,7 @@ static int isp_remove(struct platform_device *pdev)
1981 omap3isp_get(isp); 1976 omap3isp_get(isp);
1982 iommu_detach_device(isp->domain, &pdev->dev); 1977 iommu_detach_device(isp->domain, &pdev->dev);
1983 iommu_domain_free(isp->domain); 1978 iommu_domain_free(isp->domain);
1979 isp->domain = NULL;
1984 omap3isp_put(isp); 1980 omap3isp_put(isp);
1985 1981
1986 free_irq(isp->irq_num, isp); 1982 free_irq(isp->irq_num, isp);
@@ -2050,7 +2046,7 @@ static int isp_map_mem_resource(struct platform_device *pdev,
2050 * -EINVAL if couldn't install ISR, 2046 * -EINVAL if couldn't install ISR,
2051 * or clk_get return error value. 2047 * or clk_get return error value.
2052 */ 2048 */
2053static int isp_probe(struct platform_device *pdev) 2049static int __devinit isp_probe(struct platform_device *pdev)
2054{ 2050{
2055 struct isp_platform_data *pdata = pdev->dev.platform_data; 2051 struct isp_platform_data *pdata = pdev->dev.platform_data;
2056 struct isp_device *isp; 2052 struct isp_device *isp;
@@ -2068,7 +2064,6 @@ static int isp_probe(struct platform_device *pdev)
2068 2064
2069 isp->autoidle = autoidle; 2065 isp->autoidle = autoidle;
2070 isp->platform_cb.set_xclk = isp_set_xclk; 2066 isp->platform_cb.set_xclk = isp_set_xclk;
2071 isp->platform_cb.set_pixel_clock = isp_set_pixel_clock;
2072 2067
2073 mutex_init(&isp->isp_mutex); 2068 mutex_init(&isp->isp_mutex);
2074 spin_lock_init(&isp->stat_lock); 2069 spin_lock_init(&isp->stat_lock);
@@ -2218,7 +2213,7 @@ MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
2218 2213
2219static struct platform_driver omap3isp_driver = { 2214static struct platform_driver omap3isp_driver = {
2220 .probe = isp_probe, 2215 .probe = isp_probe,
2221 .remove = isp_remove, 2216 .remove = __devexit_p(isp_remove),
2222 .id_table = omap3isp_id_table, 2217 .id_table = omap3isp_id_table,
2223 .driver = { 2218 .driver = {
2224 .owner = THIS_MODULE, 2219 .owner = THIS_MODULE,
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h
index d96603eb0d17..fc7af3e32efd 100644
--- a/drivers/media/video/omap3isp/isp.h
+++ b/drivers/media/video/omap3isp/isp.h
@@ -129,7 +129,6 @@ struct isp_platform_callback {
129 int (*csiphy_config)(struct isp_csiphy *phy, 129 int (*csiphy_config)(struct isp_csiphy *phy,
130 struct isp_csiphy_dphy_cfg *dphy, 130 struct isp_csiphy_dphy_cfg *dphy,
131 struct isp_csiphy_lanes_cfg *lanes); 131 struct isp_csiphy_lanes_cfg *lanes);
132 void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
133}; 132};
134 133
135/* 134/*
@@ -145,6 +144,7 @@ struct isp_platform_callback {
145 * @raw_dmamask: Raw DMA mask 144 * @raw_dmamask: Raw DMA mask
146 * @stat_lock: Spinlock for handling statistics 145 * @stat_lock: Spinlock for handling statistics
147 * @isp_mutex: Mutex for serializing requests to ISP. 146 * @isp_mutex: Mutex for serializing requests to ISP.
147 * @crashed: Bitmask of crashed entities (indexed by entity ID)
148 * @has_context: Context has been saved at least once and can be restored. 148 * @has_context: Context has been saved at least once and can be restored.
149 * @ref_count: Reference count for handling multiple ISP requests. 149 * @ref_count: Reference count for handling multiple ISP requests.
150 * @cam_ick: Pointer to camera interface clock structure. 150 * @cam_ick: Pointer to camera interface clock structure.
@@ -184,7 +184,7 @@ struct isp_device {
184 /* ISP Obj */ 184 /* ISP Obj */
185 spinlock_t stat_lock; /* common lock for statistic drivers */ 185 spinlock_t stat_lock; /* common lock for statistic drivers */
186 struct mutex isp_mutex; /* For handling ref_count field */ 186 struct mutex isp_mutex; /* For handling ref_count field */
187 bool needs_reset; 187 u32 crashed;
188 int has_context; 188 int has_context;
189 int ref_count; 189 int ref_count;
190 unsigned int autoidle; 190 unsigned int autoidle;
@@ -237,10 +237,6 @@ void omap3isp_configure_bridge(struct isp_device *isp,
237 const struct isp_parallel_platform_data *pdata, 237 const struct isp_parallel_platform_data *pdata,
238 unsigned int shift); 238 unsigned int shift);
239 239
240#define ISP_XCLK_NONE 0
241#define ISP_XCLK_A 1
242#define ISP_XCLK_B 2
243
244struct isp_device *omap3isp_get(struct isp_device *isp); 240struct isp_device *omap3isp_get(struct isp_device *isp);
245void omap3isp_put(struct isp_device *isp); 241void omap3isp_put(struct isp_device *isp);
246 242
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index eaabc27f0fa2..7e32331b60fb 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -38,6 +38,9 @@
38#include "ispreg.h" 38#include "ispreg.h"
39#include "ispccdc.h" 39#include "ispccdc.h"
40 40
41#define CCDC_MIN_WIDTH 32
42#define CCDC_MIN_HEIGHT 32
43
41static struct v4l2_mbus_framefmt * 44static struct v4l2_mbus_framefmt *
42__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, 45__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
43 unsigned int pad, enum v4l2_subdev_format_whence which); 46 unsigned int pad, enum v4l2_subdev_format_whence which);
@@ -836,8 +839,8 @@ static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
836 839
837 if (pipe->input) 840 if (pipe->input)
838 div = DIV_ROUND_UP(l3_ick, pipe->max_rate); 841 div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
839 else if (ccdc->vpcfg.pixelclk) 842 else if (pipe->external_rate)
840 div = l3_ick / ccdc->vpcfg.pixelclk; 843 div = l3_ick / pipe->external_rate;
841 844
842 div = clamp(div, 2U, max_div); 845 div = clamp(div, 2U, max_div);
843 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT; 846 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
@@ -1118,6 +1121,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
1118 struct isp_parallel_platform_data *pdata = NULL; 1121 struct isp_parallel_platform_data *pdata = NULL;
1119 struct v4l2_subdev *sensor; 1122 struct v4l2_subdev *sensor;
1120 struct v4l2_mbus_framefmt *format; 1123 struct v4l2_mbus_framefmt *format;
1124 const struct v4l2_rect *crop;
1121 const struct isp_format_info *fmt_info; 1125 const struct isp_format_info *fmt_info;
1122 struct v4l2_subdev_format fmt_src; 1126 struct v4l2_subdev_format fmt_src;
1123 unsigned int depth_out; 1127 unsigned int depth_out;
@@ -1211,14 +1215,14 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
1211 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT); 1215 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
1212 1216
1213 /* CCDC_PAD_SOURCE_OF */ 1217 /* CCDC_PAD_SOURCE_OF */
1214 format = &ccdc->formats[CCDC_PAD_SOURCE_OF]; 1218 crop = &ccdc->crop;
1215 1219
1216 isp_reg_writel(isp, (0 << ISPCCDC_HORZ_INFO_SPH_SHIFT) | 1220 isp_reg_writel(isp, (crop->left << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
1217 ((format->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT), 1221 ((crop->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
1218 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO); 1222 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
1219 isp_reg_writel(isp, 0 << ISPCCDC_VERT_START_SLV0_SHIFT, 1223 isp_reg_writel(isp, crop->top << ISPCCDC_VERT_START_SLV0_SHIFT,
1220 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START); 1224 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
1221 isp_reg_writel(isp, (format->height - 1) 1225 isp_reg_writel(isp, (crop->height - 1)
1222 << ISPCCDC_VERT_LINES_NLV_SHIFT, 1226 << ISPCCDC_VERT_LINES_NLV_SHIFT,
1223 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES); 1227 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
1224 1228
@@ -1410,6 +1414,9 @@ static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
1410 struct video_device *vdev = ccdc->subdev.devnode; 1414 struct video_device *vdev = ccdc->subdev.devnode;
1411 struct v4l2_event event; 1415 struct v4l2_event event;
1412 1416
1417 /* Frame number propagation */
1418 atomic_inc(&pipe->frame_number);
1419
1413 memset(&event, 0, sizeof(event)); 1420 memset(&event, 0, sizeof(event));
1414 event.type = V4L2_EVENT_FRAME_SYNC; 1421 event.type = V4L2_EVENT_FRAME_SYNC;
1415 event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number); 1422 event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number);
@@ -1703,7 +1710,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1703 if (sub->id != 0) 1710 if (sub->id != 0)
1704 return -EINVAL; 1711 return -EINVAL;
1705 1712
1706 return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS); 1713 return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
1707} 1714}
1708 1715
1709static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, 1716static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
@@ -1790,6 +1797,16 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1790 return &ccdc->formats[pad]; 1797 return &ccdc->formats[pad];
1791} 1798}
1792 1799
1800static struct v4l2_rect *
1801__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1802 enum v4l2_subdev_format_whence which)
1803{
1804 if (which == V4L2_SUBDEV_FORMAT_TRY)
1805 return v4l2_subdev_get_try_crop(fh, CCDC_PAD_SOURCE_OF);
1806 else
1807 return &ccdc->crop;
1808}
1809
1793/* 1810/*
1794 * ccdc_try_format - Try video format on a pad 1811 * ccdc_try_format - Try video format on a pad
1795 * @ccdc: ISP CCDC device 1812 * @ccdc: ISP CCDC device
@@ -1806,6 +1823,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1806 const struct isp_format_info *info; 1823 const struct isp_format_info *info;
1807 unsigned int width = fmt->width; 1824 unsigned int width = fmt->width;
1808 unsigned int height = fmt->height; 1825 unsigned int height = fmt->height;
1826 struct v4l2_rect *crop;
1809 unsigned int i; 1827 unsigned int i;
1810 1828
1811 switch (pad) { 1829 switch (pad) {
@@ -1831,14 +1849,10 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1831 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which); 1849 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1832 memcpy(fmt, format, sizeof(*fmt)); 1850 memcpy(fmt, format, sizeof(*fmt));
1833 1851
1834 /* The data formatter truncates the number of horizontal output 1852 /* Hardcode the output size to the crop rectangle size. */
1835 * pixels to a multiple of 16. To avoid clipping data, allow 1853 crop = __ccdc_get_crop(ccdc, fh, which);
1836 * callers to request an output size bigger than the input size 1854 fmt->width = crop->width;
1837 * up to the nearest multiple of 16. 1855 fmt->height = crop->height;
1838 */
1839 fmt->width = clamp_t(u32, width, 32, fmt->width + 15);
1840 fmt->width &= ~15;
1841 fmt->height = clamp_t(u32, height, 32, fmt->height);
1842 break; 1856 break;
1843 1857
1844 case CCDC_PAD_SOURCE_VP: 1858 case CCDC_PAD_SOURCE_VP:
@@ -1866,6 +1880,49 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1866} 1880}
1867 1881
1868/* 1882/*
1883 * ccdc_try_crop - Validate a crop rectangle
1884 * @ccdc: ISP CCDC device
1885 * @sink: format on the sink pad
1886 * @crop: crop rectangle to be validated
1887 */
1888static void ccdc_try_crop(struct isp_ccdc_device *ccdc,
1889 const struct v4l2_mbus_framefmt *sink,
1890 struct v4l2_rect *crop)
1891{
1892 const struct isp_format_info *info;
1893 unsigned int max_width;
1894
1895 /* For Bayer formats, restrict left/top and width/height to even values
1896 * to keep the Bayer pattern.
1897 */
1898 info = omap3isp_video_format_info(sink->code);
1899 if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
1900 crop->left &= ~1;
1901 crop->top &= ~1;
1902 }
1903
1904 crop->left = clamp_t(u32, crop->left, 0, sink->width - CCDC_MIN_WIDTH);
1905 crop->top = clamp_t(u32, crop->top, 0, sink->height - CCDC_MIN_HEIGHT);
1906
1907 /* The data formatter truncates the number of horizontal output pixels
1908 * to a multiple of 16. To avoid clipping data, allow callers to request
1909 * an output size bigger than the input size up to the nearest multiple
1910 * of 16.
1911 */
1912 max_width = (sink->width - crop->left + 15) & ~15;
1913 crop->width = clamp_t(u32, crop->width, CCDC_MIN_WIDTH, max_width)
1914 & ~15;
1915 crop->height = clamp_t(u32, crop->height, CCDC_MIN_HEIGHT,
1916 sink->height - crop->top);
1917
1918 /* Odd width/height values don't make sense for Bayer formats. */
1919 if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
1920 crop->width &= ~1;
1921 crop->height &= ~1;
1922 }
1923}
1924
1925/*
1869 * ccdc_enum_mbus_code - Handle pixel format enumeration 1926 * ccdc_enum_mbus_code - Handle pixel format enumeration
1870 * @sd : pointer to v4l2 subdev structure 1927 * @sd : pointer to v4l2 subdev structure
1871 * @fh : V4L2 subdev file handle 1928 * @fh : V4L2 subdev file handle
@@ -1937,6 +1994,93 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
1937} 1994}
1938 1995
1939/* 1996/*
1997 * ccdc_get_selection - Retrieve a selection rectangle on a pad
1998 * @sd: ISP CCDC V4L2 subdevice
1999 * @fh: V4L2 subdev file handle
2000 * @sel: Selection rectangle
2001 *
2002 * The only supported rectangles are the crop rectangles on the output formatter
2003 * source pad.
2004 *
2005 * Return 0 on success or a negative error code otherwise.
2006 */
2007static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2008 struct v4l2_subdev_selection *sel)
2009{
2010 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2011 struct v4l2_mbus_framefmt *format;
2012
2013 if (sel->pad != CCDC_PAD_SOURCE_OF)
2014 return -EINVAL;
2015
2016 switch (sel->target) {
2017 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
2018 sel->r.left = 0;
2019 sel->r.top = 0;
2020 sel->r.width = INT_MAX;
2021 sel->r.height = INT_MAX;
2022
2023 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
2024 ccdc_try_crop(ccdc, format, &sel->r);
2025 break;
2026
2027 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
2028 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2029 break;
2030
2031 default:
2032 return -EINVAL;
2033 }
2034
2035 return 0;
2036}
2037
2038/*
2039 * ccdc_set_selection - Set a selection rectangle on a pad
2040 * @sd: ISP CCDC V4L2 subdevice
2041 * @fh: V4L2 subdev file handle
2042 * @sel: Selection rectangle
2043 *
2044 * The only supported rectangle is the actual crop rectangle on the output
2045 * formatter source pad.
2046 *
2047 * Return 0 on success or a negative error code otherwise.
2048 */
2049static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2050 struct v4l2_subdev_selection *sel)
2051{
2052 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2053 struct v4l2_mbus_framefmt *format;
2054
2055 if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
2056 sel->pad != CCDC_PAD_SOURCE_OF)
2057 return -EINVAL;
2058
2059 /* The crop rectangle can't be changed while streaming. */
2060 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
2061 return -EBUSY;
2062
2063 /* Modifying the crop rectangle always changes the format on the source
2064 * pad. If the KEEP_CONFIG flag is set, just return the current crop
2065 * rectangle.
2066 */
2067 if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) {
2068 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2069 return 0;
2070 }
2071
2072 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
2073 ccdc_try_crop(ccdc, format, &sel->r);
2074 *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r;
2075
2076 /* Update the source format. */
2077 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, sel->which);
2078 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, sel->which);
2079
2080 return 0;
2081}
2082
2083/*
1940 * ccdc_get_format - Retrieve the video format on a pad 2084 * ccdc_get_format - Retrieve the video format on a pad
1941 * @sd : ISP CCDC V4L2 subdevice 2085 * @sd : ISP CCDC V4L2 subdevice
1942 * @fh : V4L2 subdev file handle 2086 * @fh : V4L2 subdev file handle
@@ -1973,6 +2117,7 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1973{ 2117{
1974 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2118 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1975 struct v4l2_mbus_framefmt *format; 2119 struct v4l2_mbus_framefmt *format;
2120 struct v4l2_rect *crop;
1976 2121
1977 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which); 2122 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1978 if (format == NULL) 2123 if (format == NULL)
@@ -1983,6 +2128,16 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1983 2128
1984 /* Propagate the format from sink to source */ 2129 /* Propagate the format from sink to source */
1985 if (fmt->pad == CCDC_PAD_SINK) { 2130 if (fmt->pad == CCDC_PAD_SINK) {
2131 /* Reset the crop rectangle. */
2132 crop = __ccdc_get_crop(ccdc, fh, fmt->which);
2133 crop->left = 0;
2134 crop->top = 0;
2135 crop->width = fmt->format.width;
2136 crop->height = fmt->format.height;
2137
2138 ccdc_try_crop(ccdc, &fmt->format, crop);
2139
2140 /* Update the source formats. */
1986 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, 2141 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
1987 fmt->which); 2142 fmt->which);
1988 *format = fmt->format; 2143 *format = fmt->format;
@@ -2000,6 +2155,69 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2000} 2155}
2001 2156
2002/* 2157/*
2158 * Decide whether desired output pixel code can be obtained with
2159 * the lane shifter by shifting the input pixel code.
2160 * @in: input pixelcode to shifter
2161 * @out: output pixelcode from shifter
2162 * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
2163 *
2164 * return true if the combination is possible
2165 * return false otherwise
2166 */
2167static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
2168 enum v4l2_mbus_pixelcode out,
2169 unsigned int additional_shift)
2170{
2171 const struct isp_format_info *in_info, *out_info;
2172
2173 if (in == out)
2174 return true;
2175
2176 in_info = omap3isp_video_format_info(in);
2177 out_info = omap3isp_video_format_info(out);
2178
2179 if ((in_info->flavor == 0) || (out_info->flavor == 0))
2180 return false;
2181
2182 if (in_info->flavor != out_info->flavor)
2183 return false;
2184
2185 return in_info->bpp - out_info->bpp + additional_shift <= 6;
2186}
2187
2188static int ccdc_link_validate(struct v4l2_subdev *sd,
2189 struct media_link *link,
2190 struct v4l2_subdev_format *source_fmt,
2191 struct v4l2_subdev_format *sink_fmt)
2192{
2193 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2194 unsigned long parallel_shift;
2195
2196 /* Check if the two ends match */
2197 if (source_fmt->format.width != sink_fmt->format.width ||
2198 source_fmt->format.height != sink_fmt->format.height)
2199 return -EPIPE;
2200
2201 /* We've got a parallel sensor here. */
2202 if (ccdc->input == CCDC_INPUT_PARALLEL) {
2203 struct isp_parallel_platform_data *pdata =
2204 &((struct isp_v4l2_subdevs_group *)
2205 media_entity_to_v4l2_subdev(link->source->entity)
2206 ->host_priv)->bus.parallel;
2207 parallel_shift = pdata->data_lane_shift * 2;
2208 } else {
2209 parallel_shift = 0;
2210 }
2211
2212 /* Lane shifter may be used to drop bits on CCDC sink pad */
2213 if (!ccdc_is_shiftable(source_fmt->format.code,
2214 sink_fmt->format.code, parallel_shift))
2215 return -EPIPE;
2216
2217 return 0;
2218}
2219
2220/*
2003 * ccdc_init_formats - Initialize formats on all pads 2221 * ccdc_init_formats - Initialize formats on all pads
2004 * @sd: ISP CCDC V4L2 subdevice 2222 * @sd: ISP CCDC V4L2 subdevice
2005 * @fh: V4L2 subdev file handle 2223 * @fh: V4L2 subdev file handle
@@ -2041,6 +2259,9 @@ static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
2041 .enum_frame_size = ccdc_enum_frame_size, 2259 .enum_frame_size = ccdc_enum_frame_size,
2042 .get_fmt = ccdc_get_format, 2260 .get_fmt = ccdc_get_format,
2043 .set_fmt = ccdc_set_format, 2261 .set_fmt = ccdc_set_format,
2262 .get_selection = ccdc_get_selection,
2263 .set_selection = ccdc_set_selection,
2264 .link_validate = ccdc_link_validate,
2044}; 2265};
2045 2266
2046/* V4L2 subdev operations */ 2267/* V4L2 subdev operations */
@@ -2150,6 +2371,7 @@ static int ccdc_link_setup(struct media_entity *entity,
2150/* media operations */ 2371/* media operations */
2151static const struct media_entity_operations ccdc_media_ops = { 2372static const struct media_entity_operations ccdc_media_ops = {
2152 .link_setup = ccdc_link_setup, 2373 .link_setup = ccdc_link_setup,
2374 .link_validate = v4l2_subdev_link_validate,
2153}; 2375};
2154 2376
2155void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc) 2377void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
@@ -2276,8 +2498,6 @@ int omap3isp_ccdc_init(struct isp_device *isp)
2276 ccdc->clamp.oblen = 0; 2498 ccdc->clamp.oblen = 0;
2277 ccdc->clamp.dcsubval = 0; 2499 ccdc->clamp.dcsubval = 0;
2278 2500
2279 ccdc->vpcfg.pixelclk = 0;
2280
2281 ccdc->update = OMAP3ISP_CCDC_BLCLAMP; 2501 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2282 ccdc_apply_controls(ccdc); 2502 ccdc_apply_controls(ccdc);
2283 2503
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h
index 6d0264bab75b..890f6b3a68fd 100644
--- a/drivers/media/video/omap3isp/ispccdc.h
+++ b/drivers/media/video/omap3isp/ispccdc.h
@@ -80,14 +80,6 @@ struct ispccdc_syncif {
80 u8 bt_r656_en; 80 u8 bt_r656_en;
81}; 81};
82 82
83/*
84 * struct ispccdc_vp - Structure for Video Port parameters
85 * @pixelclk: Input pixel clock in Hz
86 */
87struct ispccdc_vp {
88 unsigned int pixelclk;
89};
90
91enum ispccdc_lsc_state { 83enum ispccdc_lsc_state {
92 LSC_STATE_STOPPED = 0, 84 LSC_STATE_STOPPED = 0,
93 LSC_STATE_STOPPING = 1, 85 LSC_STATE_STOPPING = 1,
@@ -147,6 +139,7 @@ struct ispccdc_lsc {
147 * @subdev: V4L2 subdevice 139 * @subdev: V4L2 subdevice
148 * @pads: Sink and source media entity pads 140 * @pads: Sink and source media entity pads
149 * @formats: Active video formats 141 * @formats: Active video formats
142 * @crop: Active crop rectangle on the OF source pad
150 * @input: Active input 143 * @input: Active input
151 * @output: Active outputs 144 * @output: Active outputs
152 * @video_out: Output video node 145 * @video_out: Output video node
@@ -161,7 +154,6 @@ struct ispccdc_lsc {
161 * @update: Bitmask of controls to update during the next interrupt 154 * @update: Bitmask of controls to update during the next interrupt
162 * @shadow_update: Controls update in progress by userspace 155 * @shadow_update: Controls update in progress by userspace
163 * @syncif: Interface synchronization configuration 156 * @syncif: Interface synchronization configuration
164 * @vpcfg: Video port configuration
165 * @underrun: A buffer underrun occurred and a new buffer has been queued 157 * @underrun: A buffer underrun occurred and a new buffer has been queued
166 * @state: Streaming state 158 * @state: Streaming state
167 * @lock: Serializes shadow_update with interrupt handler 159 * @lock: Serializes shadow_update with interrupt handler
@@ -173,6 +165,7 @@ struct isp_ccdc_device {
173 struct v4l2_subdev subdev; 165 struct v4l2_subdev subdev;
174 struct media_pad pads[CCDC_PADS_NUM]; 166 struct media_pad pads[CCDC_PADS_NUM];
175 struct v4l2_mbus_framefmt formats[CCDC_PADS_NUM]; 167 struct v4l2_mbus_framefmt formats[CCDC_PADS_NUM];
168 struct v4l2_rect crop;
176 169
177 enum ccdc_input_entity input; 170 enum ccdc_input_entity input;
178 unsigned int output; 171 unsigned int output;
@@ -190,7 +183,6 @@ struct isp_ccdc_device {
190 unsigned int shadow_update; 183 unsigned int shadow_update;
191 184
192 struct ispccdc_syncif syncif; 185 struct ispccdc_syncif syncif;
193 struct ispccdc_vp vpcfg;
194 186
195 unsigned int underrun:1; 187 unsigned int underrun:1;
196 enum isp_pipeline_stream_state state; 188 enum isp_pipeline_stream_state state;
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
index 70ddbf35b223..85f0de85f37c 100644
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -161,7 +161,6 @@ static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)
161static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable) 161static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
162{ 162{
163 struct isp_device *isp = to_isp_device(ccp2); 163 struct isp_device *isp = to_isp_device(ccp2);
164 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
165 int i; 164 int i;
166 165
167 if (enable && ccp2->vdds_csib) 166 if (enable && ccp2->vdds_csib)
@@ -178,19 +177,6 @@ static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
178 ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN, 177 ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
179 enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0); 178 enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);
180 179
181 /* For frame count propagation */
182 if (pipe->do_propagation) {
183 /* We may want the Frame Start IRQ from LC0 */
184 if (enable)
185 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2,
186 ISPCCP2_LC01_IRQENABLE,
187 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
188 else
189 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCP2,
190 ISPCCP2_LC01_IRQENABLE,
191 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
192 }
193
194 if (!enable && ccp2->vdds_csib) 180 if (!enable && ccp2->vdds_csib)
195 regulator_disable(ccp2->vdds_csib); 181 regulator_disable(ccp2->vdds_csib);
196} 182}
@@ -350,7 +336,6 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
350 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ | 336 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
351 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ | 337 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
352 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ | 338 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
353 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ |
354 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ | 339 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
355 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ; 340 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
356 341
@@ -613,14 +598,6 @@ void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
613 if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping)) 598 if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
614 return; 599 return;
615 600
616 /* Frame number propagation */
617 if (lcx_irqstatus & ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ) {
618 struct isp_pipeline *pipe =
619 to_isp_pipeline(&ccp2->subdev.entity);
620 if (pipe->do_propagation)
621 atomic_inc(&pipe->frame_number);
622 }
623
624 /* Handle queued buffers on frame end interrupts */ 601 /* Handle queued buffers on frame end interrupts */
625 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ) 602 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
626 ccp2_isr_buffer(ccp2); 603 ccp2_isr_buffer(ccp2);
@@ -1021,6 +998,7 @@ static int ccp2_link_setup(struct media_entity *entity,
1021/* media operations */ 998/* media operations */
1022static const struct media_entity_operations ccp2_media_ops = { 999static const struct media_entity_operations ccp2_media_ops = {
1023 .link_setup = ccp2_link_setup, 1000 .link_setup = ccp2_link_setup,
1001 .link_validate = v4l2_subdev_link_validate,
1024}; 1002};
1025 1003
1026/* 1004/*
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
index fcb5168996a7..a1724362b6d5 100644
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -378,21 +378,17 @@ static void csi2_timing_config(struct isp_device *isp,
378static void csi2_irq_ctx_set(struct isp_device *isp, 378static void csi2_irq_ctx_set(struct isp_device *isp,
379 struct isp_csi2_device *csi2, int enable) 379 struct isp_csi2_device *csi2, int enable)
380{ 380{
381 u32 reg = ISPCSI2_CTX_IRQSTATUS_FE_IRQ;
382 int i; 381 int i;
383 382
384 if (csi2->use_fs_irq)
385 reg |= ISPCSI2_CTX_IRQSTATUS_FS_IRQ;
386
387 for (i = 0; i < 8; i++) { 383 for (i = 0; i < 8; i++) {
388 isp_reg_writel(isp, reg, csi2->regs1, 384 isp_reg_writel(isp, ISPCSI2_CTX_IRQSTATUS_FE_IRQ, csi2->regs1,
389 ISPCSI2_CTX_IRQSTATUS(i)); 385 ISPCSI2_CTX_IRQSTATUS(i));
390 if (enable) 386 if (enable)
391 isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i), 387 isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
392 reg); 388 ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
393 else 389 else
394 isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i), 390 isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
395 reg); 391 ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
396 } 392 }
397} 393}
398 394
@@ -690,14 +686,6 @@ static void csi2_isr_ctx(struct isp_csi2_device *csi2,
690 status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n)); 686 status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
691 isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n)); 687 isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
692 688
693 /* Propagate frame number */
694 if (status & ISPCSI2_CTX_IRQSTATUS_FS_IRQ) {
695 struct isp_pipeline *pipe =
696 to_isp_pipeline(&csi2->subdev.entity);
697 if (pipe->do_propagation)
698 atomic_inc(&pipe->frame_number);
699 }
700
701 if (!(status & ISPCSI2_CTX_IRQSTATUS_FE_IRQ)) 689 if (!(status & ISPCSI2_CTX_IRQSTATUS_FE_IRQ))
702 return; 690 return;
703 691
@@ -1047,14 +1035,12 @@ static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
1047{ 1035{
1048 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); 1036 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1049 struct isp_device *isp = csi2->isp; 1037 struct isp_device *isp = csi2->isp;
1050 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
1051 struct isp_video *video_out = &csi2->video_out; 1038 struct isp_video *video_out = &csi2->video_out;
1052 1039
1053 switch (enable) { 1040 switch (enable) {
1054 case ISP_PIPELINE_STREAM_CONTINUOUS: 1041 case ISP_PIPELINE_STREAM_CONTINUOUS:
1055 if (omap3isp_csiphy_acquire(csi2->phy) < 0) 1042 if (omap3isp_csiphy_acquire(csi2->phy) < 0)
1056 return -ENODEV; 1043 return -ENODEV;
1057 csi2->use_fs_irq = pipe->do_propagation;
1058 if (csi2->output & CSI2_OUTPUT_MEMORY) 1044 if (csi2->output & CSI2_OUTPUT_MEMORY)
1059 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE); 1045 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1060 csi2_configure(csi2); 1046 csi2_configure(csi2);
@@ -1181,6 +1167,7 @@ static int csi2_link_setup(struct media_entity *entity,
1181/* media operations */ 1167/* media operations */
1182static const struct media_entity_operations csi2_media_ops = { 1168static const struct media_entity_operations csi2_media_ops = {
1183 .link_setup = csi2_link_setup, 1169 .link_setup = csi2_link_setup,
1170 .link_validate = v4l2_subdev_link_validate,
1184}; 1171};
1185 1172
1186void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2) 1173void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h
index 885ad79a7678..c57729b7e86e 100644
--- a/drivers/media/video/omap3isp/ispcsi2.h
+++ b/drivers/media/video/omap3isp/ispcsi2.h
@@ -145,7 +145,6 @@ struct isp_csi2_device {
145 u32 output; /* output to CCDC, memory or both? */ 145 u32 output; /* output to CCDC, memory or both? */
146 bool dpcm_decompress; 146 bool dpcm_decompress;
147 unsigned int frame_skip; 147 unsigned int frame_skip;
148 bool use_fs_irq;
149 148
150 struct isp_csiphy *phy; 149 struct isp_csiphy *phy;
151 struct isp_csi2_ctx_cfg contexts[ISP_CSI2_MAX_CTX_NUM + 1]; 150 struct isp_csi2_ctx_cfg contexts[ISP_CSI2_MAX_CTX_NUM + 1];
diff --git a/drivers/media/video/omap3isp/ispcsiphy.c b/drivers/media/video/omap3isp/ispcsiphy.c
index 5be37ce7d0c2..348f67ebbbc9 100644
--- a/drivers/media/video/omap3isp/ispcsiphy.c
+++ b/drivers/media/video/omap3isp/ispcsiphy.c
@@ -186,7 +186,9 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy)
186 if (rval < 0) 186 if (rval < 0)
187 goto done; 187 goto done;
188 188
189 omap3isp_csi2_reset(phy->csi2); 189 rval = omap3isp_csi2_reset(phy->csi2);
190 if (rval < 0)
191 goto done;
190 192
191 csiphy_dphy_config(phy); 193 csiphy_dphy_config(phy);
192 csiphy_lanes_config(phy); 194 csiphy_lanes_config(phy);
diff --git a/drivers/media/video/omap3isp/ispcsiphy.h b/drivers/media/video/omap3isp/ispcsiphy.h
index 9596dc6830a6..e93a661e65d9 100644
--- a/drivers/media/video/omap3isp/ispcsiphy.h
+++ b/drivers/media/video/omap3isp/ispcsiphy.h
@@ -27,22 +27,11 @@
27#ifndef OMAP3_ISP_CSI_PHY_H 27#ifndef OMAP3_ISP_CSI_PHY_H
28#define OMAP3_ISP_CSI_PHY_H 28#define OMAP3_ISP_CSI_PHY_H
29 29
30#include <media/omap3isp.h>
31
30struct isp_csi2_device; 32struct isp_csi2_device;
31struct regulator; 33struct regulator;
32 34
33struct csiphy_lane {
34 u8 pos;
35 u8 pol;
36};
37
38#define ISP_CSIPHY2_NUM_DATA_LANES 2
39#define ISP_CSIPHY1_NUM_DATA_LANES 1
40
41struct isp_csiphy_lanes_cfg {
42 struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
43 struct csiphy_lane clk;
44};
45
46struct isp_csiphy_dphy_cfg { 35struct isp_csiphy_dphy_cfg {
47 u8 ths_term; 36 u8 ths_term;
48 u8 ths_settle; 37 u8 ths_settle;
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index 6d0fb2c8c26d..8a4935ecc655 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -441,23 +441,6 @@ preview_enable_dcor(struct isp_prev_device *prev, u8 enable)
441} 441}
442 442
443/* 443/*
444 * preview_enable_cfa - Enable/Disable the CFA Interpolation.
445 * @enable: 1 - Enables the CFA.
446 */
447static void
448preview_enable_cfa(struct isp_prev_device *prev, u8 enable)
449{
450 struct isp_device *isp = to_isp_device(prev);
451
452 if (enable)
453 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
454 ISPPRV_PCR_CFAEN);
455 else
456 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
457 ISPPRV_PCR_CFAEN);
458}
459
460/*
461 * preview_enable_gammabypass - Enables/Disables the GammaByPass 444 * preview_enable_gammabypass - Enables/Disables the GammaByPass
462 * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB. 445 * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
463 * 0 - Goes through Gamma Correction. input and output is 10bit. 446 * 0 - Goes through Gamma Correction. input and output is 10bit.
@@ -608,12 +591,12 @@ preview_config_rgb_blending(struct isp_prev_device *prev, const void *rgb2rgb)
608} 591}
609 592
610/* 593/*
611 * Configures the RGB-YCbYCr conversion matrix 594 * Configures the color space conversion (RGB toYCbYCr) matrix
612 * @prev_csc: Structure containing the RGB to YCbYCr matrix and the 595 * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
613 * YCbCr offset. 596 * YCbCr offset.
614 */ 597 */
615static void 598static void
616preview_config_rgb_to_ycbcr(struct isp_prev_device *prev, const void *prev_csc) 599preview_config_csc(struct isp_prev_device *prev, const void *prev_csc)
617{ 600{
618 struct isp_device *isp = to_isp_device(prev); 601 struct isp_device *isp = to_isp_device(prev);
619 const struct omap3isp_prev_csc *csc = prev_csc; 602 const struct omap3isp_prev_csc *csc = prev_csc;
@@ -649,12 +632,18 @@ preview_config_rgb_to_ycbcr(struct isp_prev_device *prev, const void *prev_csc)
649static void 632static void
650preview_update_contrast(struct isp_prev_device *prev, u8 contrast) 633preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
651{ 634{
652 struct prev_params *params = &prev->params; 635 struct prev_params *params;
636 unsigned long flags;
637
638 spin_lock_irqsave(&prev->params.lock, flags);
639 params = (prev->params.active & OMAP3ISP_PREV_CONTRAST)
640 ? &prev->params.params[0] : &prev->params.params[1];
653 641
654 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) { 642 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) {
655 params->contrast = contrast * ISPPRV_CONTRAST_UNITS; 643 params->contrast = contrast * ISPPRV_CONTRAST_UNITS;
656 prev->update |= PREV_CONTRAST; 644 params->update |= OMAP3ISP_PREV_CONTRAST;
657 } 645 }
646 spin_unlock_irqrestore(&prev->params.lock, flags);
658} 647}
659 648
660/* 649/*
@@ -681,12 +670,18 @@ preview_config_contrast(struct isp_prev_device *prev, const void *params)
681static void 670static void
682preview_update_brightness(struct isp_prev_device *prev, u8 brightness) 671preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
683{ 672{
684 struct prev_params *params = &prev->params; 673 struct prev_params *params;
674 unsigned long flags;
675
676 spin_lock_irqsave(&prev->params.lock, flags);
677 params = (prev->params.active & OMAP3ISP_PREV_BRIGHTNESS)
678 ? &prev->params.params[0] : &prev->params.params[1];
685 679
686 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) { 680 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) {
687 params->brightness = brightness * ISPPRV_BRIGHT_UNITS; 681 params->brightness = brightness * ISPPRV_BRIGHT_UNITS;
688 prev->update |= PREV_BRIGHTNESS; 682 params->update |= OMAP3ISP_PREV_BRIGHTNESS;
689 } 683 }
684 spin_unlock_irqrestore(&prev->params.lock, flags);
690} 685}
691 686
692/* 687/*
@@ -721,159 +716,188 @@ preview_config_yc_range(struct isp_prev_device *prev, const void *yclimit)
721 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC); 716 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
722} 717}
723 718
719static u32
720preview_params_lock(struct isp_prev_device *prev, u32 update, bool shadow)
721{
722 u32 active = prev->params.active;
723
724 if (shadow) {
725 /* Mark all shadow parameters we are going to touch as busy. */
726 prev->params.params[0].busy |= ~active & update;
727 prev->params.params[1].busy |= active & update;
728 } else {
729 /* Mark all active parameters we are going to touch as busy. */
730 update = (prev->params.params[0].update & active)
731 | (prev->params.params[1].update & ~active);
732
733 prev->params.params[0].busy |= active & update;
734 prev->params.params[1].busy |= ~active & update;
735 }
736
737 return update;
738}
739
740static void
741preview_params_unlock(struct isp_prev_device *prev, u32 update, bool shadow)
742{
743 u32 active = prev->params.active;
744
745 if (shadow) {
746 /* Set the update flag for shadow parameters that have been
747 * updated and clear the busy flag for all shadow parameters.
748 */
749 prev->params.params[0].update |= (~active & update);
750 prev->params.params[1].update |= (active & update);
751 prev->params.params[0].busy &= active;
752 prev->params.params[1].busy &= ~active;
753 } else {
754 /* Clear the update flag for active parameters that have been
755 * applied and the busy flag for all active parameters.
756 */
757 prev->params.params[0].update &= ~(active & update);
758 prev->params.params[1].update &= ~(~active & update);
759 prev->params.params[0].busy &= ~active;
760 prev->params.params[1].busy &= active;
761 }
762}
763
764static void preview_params_switch(struct isp_prev_device *prev)
765{
766 u32 to_switch;
767
768 /* Switch active parameters with updated shadow parameters when the
769 * shadow parameter has been updated and neither the active not the
770 * shadow parameter is busy.
771 */
772 to_switch = (prev->params.params[0].update & ~prev->params.active)
773 | (prev->params.params[1].update & prev->params.active);
774 to_switch &= ~(prev->params.params[0].busy |
775 prev->params.params[1].busy);
776 if (to_switch == 0)
777 return;
778
779 prev->params.active ^= to_switch;
780
781 /* Remove the update flag for the shadow copy of parameters we have
782 * switched.
783 */
784 prev->params.params[0].update &= ~(~prev->params.active & to_switch);
785 prev->params.params[1].update &= ~(prev->params.active & to_switch);
786}
787
724/* preview parameters update structure */ 788/* preview parameters update structure */
725struct preview_update { 789struct preview_update {
726 int cfg_bit;
727 int feature_bit;
728 void (*config)(struct isp_prev_device *, const void *); 790 void (*config)(struct isp_prev_device *, const void *);
729 void (*enable)(struct isp_prev_device *, u8); 791 void (*enable)(struct isp_prev_device *, u8);
792 unsigned int param_offset;
793 unsigned int param_size;
794 unsigned int config_offset;
795 bool skip;
730}; 796};
731 797
732static struct preview_update update_attrs[] = { 798/* Keep the array indexed by the OMAP3ISP_PREV_* bit number. */
733 {OMAP3ISP_PREV_LUMAENH, PREV_LUMA_ENHANCE, 799static const struct preview_update update_attrs[] = {
800 /* OMAP3ISP_PREV_LUMAENH */ {
734 preview_config_luma_enhancement, 801 preview_config_luma_enhancement,
735 preview_enable_luma_enhancement}, 802 preview_enable_luma_enhancement,
736 {OMAP3ISP_PREV_INVALAW, PREV_INVERSE_ALAW, 803 offsetof(struct prev_params, luma),
804 FIELD_SIZEOF(struct prev_params, luma),
805 offsetof(struct omap3isp_prev_update_config, luma),
806 }, /* OMAP3ISP_PREV_INVALAW */ {
737 NULL, 807 NULL,
738 preview_enable_invalaw}, 808 preview_enable_invalaw,
739 {OMAP3ISP_PREV_HRZ_MED, PREV_HORZ_MEDIAN_FILTER, 809 }, /* OMAP3ISP_PREV_HRZ_MED */ {
740 preview_config_hmed, 810 preview_config_hmed,
741 preview_enable_hmed}, 811 preview_enable_hmed,
742 {OMAP3ISP_PREV_CFA, PREV_CFA, 812 offsetof(struct prev_params, hmed),
813 FIELD_SIZEOF(struct prev_params, hmed),
814 offsetof(struct omap3isp_prev_update_config, hmed),
815 }, /* OMAP3ISP_PREV_CFA */ {
743 preview_config_cfa, 816 preview_config_cfa,
744 preview_enable_cfa}, 817 NULL,
745 {OMAP3ISP_PREV_CHROMA_SUPP, PREV_CHROMA_SUPPRESS, 818 offsetof(struct prev_params, cfa),
819 FIELD_SIZEOF(struct prev_params, cfa),
820 offsetof(struct omap3isp_prev_update_config, cfa),
821 }, /* OMAP3ISP_PREV_CHROMA_SUPP */ {
746 preview_config_chroma_suppression, 822 preview_config_chroma_suppression,
747 preview_enable_chroma_suppression}, 823 preview_enable_chroma_suppression,
748 {OMAP3ISP_PREV_WB, PREV_WB, 824 offsetof(struct prev_params, csup),
825 FIELD_SIZEOF(struct prev_params, csup),
826 offsetof(struct omap3isp_prev_update_config, csup),
827 }, /* OMAP3ISP_PREV_WB */ {
749 preview_config_whitebalance, 828 preview_config_whitebalance,
750 NULL}, 829 NULL,
751 {OMAP3ISP_PREV_BLKADJ, PREV_BLKADJ, 830 offsetof(struct prev_params, wbal),
831 FIELD_SIZEOF(struct prev_params, wbal),
832 offsetof(struct omap3isp_prev_update_config, wbal),
833 }, /* OMAP3ISP_PREV_BLKADJ */ {
752 preview_config_blkadj, 834 preview_config_blkadj,
753 NULL}, 835 NULL,
754 {OMAP3ISP_PREV_RGB2RGB, PREV_RGB2RGB, 836 offsetof(struct prev_params, blkadj),
837 FIELD_SIZEOF(struct prev_params, blkadj),
838 offsetof(struct omap3isp_prev_update_config, blkadj),
839 }, /* OMAP3ISP_PREV_RGB2RGB */ {
755 preview_config_rgb_blending, 840 preview_config_rgb_blending,
756 NULL}, 841 NULL,
757 {OMAP3ISP_PREV_COLOR_CONV, PREV_COLOR_CONV, 842 offsetof(struct prev_params, rgb2rgb),
758 preview_config_rgb_to_ycbcr, 843 FIELD_SIZEOF(struct prev_params, rgb2rgb),
759 NULL}, 844 offsetof(struct omap3isp_prev_update_config, rgb2rgb),
760 {OMAP3ISP_PREV_YC_LIMIT, PREV_YCLIMITS, 845 }, /* OMAP3ISP_PREV_COLOR_CONV */ {
846 preview_config_csc,
847 NULL,
848 offsetof(struct prev_params, csc),
849 FIELD_SIZEOF(struct prev_params, csc),
850 offsetof(struct omap3isp_prev_update_config, csc),
851 }, /* OMAP3ISP_PREV_YC_LIMIT */ {
761 preview_config_yc_range, 852 preview_config_yc_range,
762 NULL}, 853 NULL,
763 {OMAP3ISP_PREV_DEFECT_COR, PREV_DEFECT_COR, 854 offsetof(struct prev_params, yclimit),
855 FIELD_SIZEOF(struct prev_params, yclimit),
856 offsetof(struct omap3isp_prev_update_config, yclimit),
857 }, /* OMAP3ISP_PREV_DEFECT_COR */ {
764 preview_config_dcor, 858 preview_config_dcor,
765 preview_enable_dcor}, 859 preview_enable_dcor,
766 {OMAP3ISP_PREV_GAMMABYPASS, PREV_GAMMA_BYPASS, 860 offsetof(struct prev_params, dcor),
861 FIELD_SIZEOF(struct prev_params, dcor),
862 offsetof(struct omap3isp_prev_update_config, dcor),
863 }, /* OMAP3ISP_PREV_GAMMABYPASS */ {
767 NULL, 864 NULL,
768 preview_enable_gammabypass}, 865 preview_enable_gammabypass,
769 {OMAP3ISP_PREV_DRK_FRM_CAPTURE, PREV_DARK_FRAME_CAPTURE, 866 }, /* OMAP3ISP_PREV_DRK_FRM_CAPTURE */ {
770 NULL, 867 NULL,
771 preview_enable_drkframe_capture}, 868 preview_enable_drkframe_capture,
772 {OMAP3ISP_PREV_DRK_FRM_SUBTRACT, PREV_DARK_FRAME_SUBTRACT, 869 }, /* OMAP3ISP_PREV_DRK_FRM_SUBTRACT */ {
773 NULL, 870 NULL,
774 preview_enable_drkframe}, 871 preview_enable_drkframe,
775 {OMAP3ISP_PREV_LENS_SHADING, PREV_LENS_SHADING, 872 }, /* OMAP3ISP_PREV_LENS_SHADING */ {
776 preview_config_drkf_shadcomp, 873 preview_config_drkf_shadcomp,
777 preview_enable_drkframe}, 874 preview_enable_drkframe,
778 {OMAP3ISP_PREV_NF, PREV_NOISE_FILTER, 875 }, /* OMAP3ISP_PREV_NF */ {
779 preview_config_noisefilter, 876 preview_config_noisefilter,
780 preview_enable_noisefilter}, 877 preview_enable_noisefilter,
781 {OMAP3ISP_PREV_GAMMA, PREV_GAMMA, 878 offsetof(struct prev_params, nf),
879 FIELD_SIZEOF(struct prev_params, nf),
880 offsetof(struct omap3isp_prev_update_config, nf),
881 }, /* OMAP3ISP_PREV_GAMMA */ {
782 preview_config_gammacorrn, 882 preview_config_gammacorrn,
783 NULL}, 883 NULL,
784 {-1, PREV_CONTRAST, 884 offsetof(struct prev_params, gamma),
885 FIELD_SIZEOF(struct prev_params, gamma),
886 offsetof(struct omap3isp_prev_update_config, gamma),
887 }, /* OMAP3ISP_PREV_CONTRAST */ {
785 preview_config_contrast, 888 preview_config_contrast,
786 NULL}, 889 NULL,
787 {-1, PREV_BRIGHTNESS, 890 offsetof(struct prev_params, contrast),
891 0, true,
892 }, /* OMAP3ISP_PREV_BRIGHTNESS */ {
788 preview_config_brightness, 893 preview_config_brightness,
789 NULL}, 894 NULL,
895 offsetof(struct prev_params, brightness),
896 0, true,
897 },
790}; 898};
791 899
792/* 900/*
793 * __preview_get_ptrs - helper function which return pointers to members
794 * of params and config structures.
795 * @params - pointer to preview_params structure.
796 * @param - return pointer to appropriate structure field.
797 * @configs - pointer to update config structure.
798 * @config - return pointer to appropriate structure field.
799 * @bit - for which feature to return pointers.
800 * Return size of corresponding prev_params member
801 */
802static u32
803__preview_get_ptrs(struct prev_params *params, void **param,
804 struct omap3isp_prev_update_config *configs,
805 void __user **config, u32 bit)
806{
807#define CHKARG(cfgs, cfg, field) \
808 if (cfgs && cfg) { \
809 *(cfg) = (cfgs)->field; \
810 }
811
812 switch (bit) {
813 case PREV_HORZ_MEDIAN_FILTER:
814 *param = &params->hmed;
815 CHKARG(configs, config, hmed)
816 return sizeof(params->hmed);
817 case PREV_NOISE_FILTER:
818 *param = &params->nf;
819 CHKARG(configs, config, nf)
820 return sizeof(params->nf);
821 break;
822 case PREV_CFA:
823 *param = &params->cfa;
824 CHKARG(configs, config, cfa)
825 return sizeof(params->cfa);
826 case PREV_LUMA_ENHANCE:
827 *param = &params->luma;
828 CHKARG(configs, config, luma)
829 return sizeof(params->luma);
830 case PREV_CHROMA_SUPPRESS:
831 *param = &params->csup;
832 CHKARG(configs, config, csup)
833 return sizeof(params->csup);
834 case PREV_DEFECT_COR:
835 *param = &params->dcor;
836 CHKARG(configs, config, dcor)
837 return sizeof(params->dcor);
838 case PREV_BLKADJ:
839 *param = &params->blk_adj;
840 CHKARG(configs, config, blkadj)
841 return sizeof(params->blk_adj);
842 case PREV_YCLIMITS:
843 *param = &params->yclimit;
844 CHKARG(configs, config, yclimit)
845 return sizeof(params->yclimit);
846 case PREV_RGB2RGB:
847 *param = &params->rgb2rgb;
848 CHKARG(configs, config, rgb2rgb)
849 return sizeof(params->rgb2rgb);
850 case PREV_COLOR_CONV:
851 *param = &params->rgb2ycbcr;
852 CHKARG(configs, config, csc)
853 return sizeof(params->rgb2ycbcr);
854 case PREV_WB:
855 *param = &params->wbal;
856 CHKARG(configs, config, wbal)
857 return sizeof(params->wbal);
858 case PREV_GAMMA:
859 *param = &params->gamma;
860 CHKARG(configs, config, gamma)
861 return sizeof(params->gamma);
862 case PREV_CONTRAST:
863 *param = &params->contrast;
864 return 0;
865 case PREV_BRIGHTNESS:
866 *param = &params->brightness;
867 return 0;
868 default:
869 *param = NULL;
870 *config = NULL;
871 break;
872 }
873 return 0;
874}
875
876/*
877 * preview_config - Copy and update local structure with userspace preview 901 * preview_config - Copy and update local structure with userspace preview
878 * configuration. 902 * configuration.
879 * @prev: ISP preview engine 903 * @prev: ISP preview engine
@@ -885,84 +909,103 @@ __preview_get_ptrs(struct prev_params *params, void **param,
885static int preview_config(struct isp_prev_device *prev, 909static int preview_config(struct isp_prev_device *prev,
886 struct omap3isp_prev_update_config *cfg) 910 struct omap3isp_prev_update_config *cfg)
887{ 911{
888 struct prev_params *params; 912 unsigned long flags;
889 struct preview_update *attr; 913 unsigned int i;
890 int i, bit, rval = 0; 914 int rval = 0;
915 u32 update;
916 u32 active;
891 917
892 params = &prev->params; 918 if (cfg->update == 0)
919 return 0;
893 920
894 if (prev->state != ISP_PIPELINE_STREAM_STOPPED) { 921 /* Mark the shadow parameters we're going to update as busy. */
895 unsigned long flags; 922 spin_lock_irqsave(&prev->params.lock, flags);
923 preview_params_lock(prev, cfg->update, true);
924 active = prev->params.active;
925 spin_unlock_irqrestore(&prev->params.lock, flags);
896 926
897 spin_lock_irqsave(&prev->lock, flags); 927 update = 0;
898 prev->shadow_update = 1;
899 spin_unlock_irqrestore(&prev->lock, flags);
900 }
901 928
902 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) { 929 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
903 attr = &update_attrs[i]; 930 const struct preview_update *attr = &update_attrs[i];
904 bit = 0; 931 struct prev_params *params;
932 unsigned int bit = 1 << i;
905 933
906 if (!(cfg->update & attr->cfg_bit)) 934 if (attr->skip || !(cfg->update & bit))
907 continue; 935 continue;
908 936
909 bit = cfg->flag & attr->cfg_bit; 937 params = &prev->params.params[!!(active & bit)];
910 if (bit) { 938
911 void *to = NULL, __user *from = NULL; 939 if (cfg->flag & bit) {
912 unsigned long sz = 0; 940 void __user *from = *(void * __user *)
941 ((void *)cfg + attr->config_offset);
942 void *to = (void *)params + attr->param_offset;
943 size_t size = attr->param_size;
913 944
914 sz = __preview_get_ptrs(params, &to, cfg, &from, 945 if (to && from && size) {
915 bit); 946 if (copy_from_user(to, from, size)) {
916 if (to && from && sz) {
917 if (copy_from_user(to, from, sz)) {
918 rval = -EFAULT; 947 rval = -EFAULT;
919 break; 948 break;
920 } 949 }
921 } 950 }
922 params->features |= attr->feature_bit; 951 params->features |= bit;
923 } else { 952 } else {
924 params->features &= ~attr->feature_bit; 953 params->features &= ~bit;
925 } 954 }
926 955
927 prev->update |= attr->feature_bit; 956 update |= bit;
928 } 957 }
929 958
930 prev->shadow_update = 0; 959 spin_lock_irqsave(&prev->params.lock, flags);
960 preview_params_unlock(prev, update, true);
961 preview_params_switch(prev);
962 spin_unlock_irqrestore(&prev->params.lock, flags);
963
931 return rval; 964 return rval;
932} 965}
933 966
934/* 967/*
935 * preview_setup_hw - Setup preview registers and/or internal memory 968 * preview_setup_hw - Setup preview registers and/or internal memory
936 * @prev: pointer to preview private structure 969 * @prev: pointer to preview private structure
970 * @update: Bitmask of parameters to setup
971 * @active: Bitmask of parameters active in set 0
937 * Note: can be called from interrupt context 972 * Note: can be called from interrupt context
938 * Return none 973 * Return none
939 */ 974 */
940static void preview_setup_hw(struct isp_prev_device *prev) 975static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
976 u32 active)
941{ 977{
942 struct prev_params *params = &prev->params; 978 unsigned int i;
943 struct preview_update *attr; 979 u32 features;
944 int i, bit; 980
945 void *param_ptr; 981 if (update == 0)
982 return;
983
984 features = (prev->params.params[0].features & active)
985 | (prev->params.params[1].features & ~active);
946 986
947 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) { 987 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
948 attr = &update_attrs[i]; 988 const struct preview_update *attr = &update_attrs[i];
989 struct prev_params *params;
990 unsigned int bit = 1 << i;
991 void *param_ptr;
949 992
950 if (!(prev->update & attr->feature_bit)) 993 if (!(update & bit))
951 continue; 994 continue;
952 bit = params->features & attr->feature_bit; 995
953 if (bit) { 996 params = &prev->params.params[!(active & bit)];
997
998 if (params->features & bit) {
954 if (attr->config) { 999 if (attr->config) {
955 __preview_get_ptrs(params, &param_ptr, NULL, 1000 param_ptr = (void *)params + attr->param_offset;
956 NULL, bit);
957 attr->config(prev, param_ptr); 1001 attr->config(prev, param_ptr);
958 } 1002 }
959 if (attr->enable) 1003 if (attr->enable)
960 attr->enable(prev, 1); 1004 attr->enable(prev, 1);
961 } else 1005 } else {
962 if (attr->enable) 1006 if (attr->enable)
963 attr->enable(prev, 0); 1007 attr->enable(prev, 0);
964 1008 }
965 prev->update &= ~attr->feature_bit;
966 } 1009 }
967} 1010}
968 1011
@@ -1000,13 +1043,17 @@ preview_config_ycpos(struct isp_prev_device *prev,
1000static void preview_config_averager(struct isp_prev_device *prev, u8 average) 1043static void preview_config_averager(struct isp_prev_device *prev, u8 average)
1001{ 1044{
1002 struct isp_device *isp = to_isp_device(prev); 1045 struct isp_device *isp = to_isp_device(prev);
1046 struct prev_params *params;
1003 int reg = 0; 1047 int reg = 0;
1004 1048
1005 if (prev->params.cfa.format == OMAP3ISP_CFAFMT_BAYER) 1049 params = (prev->params.active & OMAP3ISP_PREV_CFA)
1050 ? &prev->params.params[0] : &prev->params.params[1];
1051
1052 if (params->cfa.format == OMAP3ISP_CFAFMT_BAYER)
1006 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT | 1053 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
1007 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT | 1054 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
1008 average; 1055 average;
1009 else if (prev->params.cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON) 1056 else if (params->cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
1010 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT | 1057 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
1011 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT | 1058 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
1012 average; 1059 average;
@@ -1014,6 +1061,27 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
1014} 1061}
1015 1062
1016/* 1063/*
1064 * preview_config_input_format - Configure the input format
1065 * @prev: The preview engine
1066 * @format: Format on the preview engine sink pad
1067 *
1068 * Enable CFA interpolation for Bayer formats and disable it for greyscale
1069 * formats.
1070 */
1071static void preview_config_input_format(struct isp_prev_device *prev,
1072 const struct v4l2_mbus_framefmt *format)
1073{
1074 struct isp_device *isp = to_isp_device(prev);
1075
1076 if (format->code != V4L2_MBUS_FMT_Y10_1X10)
1077 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1078 ISPPRV_PCR_CFAEN);
1079 else
1080 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1081 ISPPRV_PCR_CFAEN);
1082}
1083
1084/*
1017 * preview_config_input_size - Configure the input frame size 1085 * preview_config_input_size - Configure the input frame size
1018 * 1086 *
1019 * The preview engine crops several rows and columns internally depending on 1087 * The preview engine crops several rows and columns internally depending on
@@ -1024,32 +1092,37 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
1024 * 1092 *
1025 * See the explanation at the PREV_MARGIN_* definitions for more details. 1093 * See the explanation at the PREV_MARGIN_* definitions for more details.
1026 */ 1094 */
1027static void preview_config_input_size(struct isp_prev_device *prev) 1095static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
1028{ 1096{
1097 const struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
1029 struct isp_device *isp = to_isp_device(prev); 1098 struct isp_device *isp = to_isp_device(prev);
1030 struct prev_params *params = &prev->params;
1031 unsigned int sph = prev->crop.left; 1099 unsigned int sph = prev->crop.left;
1032 unsigned int eph = prev->crop.left + prev->crop.width - 1; 1100 unsigned int eph = prev->crop.left + prev->crop.width - 1;
1033 unsigned int slv = prev->crop.top; 1101 unsigned int slv = prev->crop.top;
1034 unsigned int elv = prev->crop.top + prev->crop.height - 1; 1102 unsigned int elv = prev->crop.top + prev->crop.height - 1;
1103 u32 features;
1035 1104
1036 if (params->features & PREV_CFA) { 1105 if (format->code == V4L2_MBUS_FMT_Y10_1X10) {
1037 sph -= 2; 1106 sph -= 2;
1038 eph += 2; 1107 eph += 2;
1039 slv -= 2; 1108 slv -= 2;
1040 elv += 2; 1109 elv += 2;
1041 } 1110 }
1042 if (params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER)) { 1111
1112 features = (prev->params.params[0].features & active)
1113 | (prev->params.params[1].features & ~active);
1114
1115 if (features & (OMAP3ISP_PREV_DEFECT_COR | OMAP3ISP_PREV_NF)) {
1043 sph -= 2; 1116 sph -= 2;
1044 eph += 2; 1117 eph += 2;
1045 slv -= 2; 1118 slv -= 2;
1046 elv += 2; 1119 elv += 2;
1047 } 1120 }
1048 if (params->features & PREV_HORZ_MEDIAN_FILTER) { 1121 if (features & OMAP3ISP_PREV_HRZ_MED) {
1049 sph -= 2; 1122 sph -= 2;
1050 eph += 2; 1123 eph += 2;
1051 } 1124 }
1052 if (params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)) 1125 if (features & (OMAP3ISP_PREV_CHROMA_SUPP | OMAP3ISP_PREV_LUMAENH))
1053 sph -= 2; 1126 sph -= 2;
1054 1127
1055 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph, 1128 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
@@ -1184,8 +1257,16 @@ int omap3isp_preview_busy(struct isp_prev_device *prev)
1184 */ 1257 */
1185void omap3isp_preview_restore_context(struct isp_device *isp) 1258void omap3isp_preview_restore_context(struct isp_device *isp)
1186{ 1259{
1187 isp->isp_prev.update = PREV_FEATURES_END - 1; 1260 struct isp_prev_device *prev = &isp->isp_prev;
1188 preview_setup_hw(&isp->isp_prev); 1261 const u32 update = OMAP3ISP_PREV_FEATURES_END - 1;
1262
1263 prev->params.params[0].update = prev->params.active & update;
1264 prev->params.params[1].update = ~prev->params.active & update;
1265
1266 preview_setup_hw(prev, update, prev->params.active);
1267
1268 prev->params.params[0].update = 0;
1269 prev->params.params[1].update = 0;
1189} 1270}
1190 1271
1191/* 1272/*
@@ -1244,12 +1325,21 @@ static void preview_print_status(struct isp_prev_device *prev)
1244/* 1325/*
1245 * preview_init_params - init image processing parameters. 1326 * preview_init_params - init image processing parameters.
1246 * @prev: pointer to previewer private structure 1327 * @prev: pointer to previewer private structure
1247 * return none
1248 */ 1328 */
1249static void preview_init_params(struct isp_prev_device *prev) 1329static void preview_init_params(struct isp_prev_device *prev)
1250{ 1330{
1251 struct prev_params *params = &prev->params; 1331 struct prev_params *params;
1252 int i = 0; 1332 unsigned int i;
1333
1334 spin_lock_init(&prev->params.lock);
1335
1336 prev->params.active = ~0;
1337 prev->params.params[0].busy = 0;
1338 prev->params.params[0].update = OMAP3ISP_PREV_FEATURES_END - 1;
1339 prev->params.params[1].busy = 0;
1340 prev->params.params[1].update = 0;
1341
1342 params = &prev->params.params[0];
1253 1343
1254 /* Init values */ 1344 /* Init values */
1255 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS; 1345 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
@@ -1277,22 +1367,22 @@ static void preview_init_params(struct isp_prev_device *prev)
1277 params->wbal.coef1 = FLR_WBAL_COEF; 1367 params->wbal.coef1 = FLR_WBAL_COEF;
1278 params->wbal.coef2 = FLR_WBAL_COEF; 1368 params->wbal.coef2 = FLR_WBAL_COEF;
1279 params->wbal.coef3 = FLR_WBAL_COEF; 1369 params->wbal.coef3 = FLR_WBAL_COEF;
1280 params->blk_adj.red = FLR_BLKADJ_RED; 1370 params->blkadj.red = FLR_BLKADJ_RED;
1281 params->blk_adj.green = FLR_BLKADJ_GREEN; 1371 params->blkadj.green = FLR_BLKADJ_GREEN;
1282 params->blk_adj.blue = FLR_BLKADJ_BLUE; 1372 params->blkadj.blue = FLR_BLKADJ_BLUE;
1283 params->rgb2rgb = flr_rgb2rgb; 1373 params->rgb2rgb = flr_rgb2rgb;
1284 params->rgb2ycbcr = flr_prev_csc; 1374 params->csc = flr_prev_csc;
1285 params->yclimit.minC = ISPPRV_YC_MIN; 1375 params->yclimit.minC = ISPPRV_YC_MIN;
1286 params->yclimit.maxC = ISPPRV_YC_MAX; 1376 params->yclimit.maxC = ISPPRV_YC_MAX;
1287 params->yclimit.minY = ISPPRV_YC_MIN; 1377 params->yclimit.minY = ISPPRV_YC_MIN;
1288 params->yclimit.maxY = ISPPRV_YC_MAX; 1378 params->yclimit.maxY = ISPPRV_YC_MAX;
1289 1379
1290 params->features = PREV_CFA | PREV_DEFECT_COR | PREV_NOISE_FILTER 1380 params->features = OMAP3ISP_PREV_CFA | OMAP3ISP_PREV_DEFECT_COR
1291 | PREV_GAMMA | PREV_BLKADJ | PREV_YCLIMITS 1381 | OMAP3ISP_PREV_NF | OMAP3ISP_PREV_GAMMA
1292 | PREV_RGB2RGB | PREV_COLOR_CONV | PREV_WB 1382 | OMAP3ISP_PREV_BLKADJ | OMAP3ISP_PREV_YC_LIMIT
1293 | PREV_BRIGHTNESS | PREV_CONTRAST; 1383 | OMAP3ISP_PREV_RGB2RGB | OMAP3ISP_PREV_COLOR_CONV
1294 1384 | OMAP3ISP_PREV_WB | OMAP3ISP_PREV_BRIGHTNESS
1295 prev->update = PREV_FEATURES_END - 1; 1385 | OMAP3ISP_PREV_CONTRAST;
1296} 1386}
1297 1387
1298/* 1388/*
@@ -1321,8 +1411,17 @@ static void preview_configure(struct isp_prev_device *prev)
1321{ 1411{
1322 struct isp_device *isp = to_isp_device(prev); 1412 struct isp_device *isp = to_isp_device(prev);
1323 struct v4l2_mbus_framefmt *format; 1413 struct v4l2_mbus_framefmt *format;
1414 unsigned long flags;
1415 u32 update;
1416 u32 active;
1324 1417
1325 preview_setup_hw(prev); 1418 spin_lock_irqsave(&prev->params.lock, flags);
1419 /* Mark all active parameters we are going to touch as busy. */
1420 update = preview_params_lock(prev, 0, false);
1421 active = prev->params.active;
1422 spin_unlock_irqrestore(&prev->params.lock, flags);
1423
1424 preview_setup_hw(prev, update, active);
1326 1425
1327 if (prev->output & PREVIEW_OUTPUT_MEMORY) 1426 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1328 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, 1427 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
@@ -1343,7 +1442,8 @@ static void preview_configure(struct isp_prev_device *prev)
1343 1442
1344 preview_adjust_bandwidth(prev); 1443 preview_adjust_bandwidth(prev);
1345 1444
1346 preview_config_input_size(prev); 1445 preview_config_input_format(prev, format);
1446 preview_config_input_size(prev, active);
1347 1447
1348 if (prev->input == PREVIEW_INPUT_CCDC) 1448 if (prev->input == PREVIEW_INPUT_CCDC)
1349 preview_config_inlineoffset(prev, 0); 1449 preview_config_inlineoffset(prev, 0);
@@ -1360,6 +1460,10 @@ static void preview_configure(struct isp_prev_device *prev)
1360 1460
1361 preview_config_averager(prev, 0); 1461 preview_config_averager(prev, 0);
1362 preview_config_ycpos(prev, format->code); 1462 preview_config_ycpos(prev, format->code);
1463
1464 spin_lock_irqsave(&prev->params.lock, flags);
1465 preview_params_unlock(prev, update, false);
1466 spin_unlock_irqrestore(&prev->params.lock, flags);
1363} 1467}
1364 1468
1365/* ----------------------------------------------------------------------------- 1469/* -----------------------------------------------------------------------------
@@ -1448,25 +1552,30 @@ static void preview_isr_buffer(struct isp_prev_device *prev)
1448void omap3isp_preview_isr(struct isp_prev_device *prev) 1552void omap3isp_preview_isr(struct isp_prev_device *prev)
1449{ 1553{
1450 unsigned long flags; 1554 unsigned long flags;
1555 u32 update;
1556 u32 active;
1451 1557
1452 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping)) 1558 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping))
1453 return; 1559 return;
1454 1560
1455 spin_lock_irqsave(&prev->lock, flags); 1561 spin_lock_irqsave(&prev->params.lock, flags);
1456 if (prev->shadow_update) 1562 preview_params_switch(prev);
1457 goto done; 1563 update = preview_params_lock(prev, 0, false);
1564 active = prev->params.active;
1565 spin_unlock_irqrestore(&prev->params.lock, flags);
1458 1566
1459 preview_setup_hw(prev); 1567 preview_setup_hw(prev, update, active);
1460 preview_config_input_size(prev); 1568 preview_config_input_size(prev, active);
1461
1462done:
1463 spin_unlock_irqrestore(&prev->lock, flags);
1464 1569
1465 if (prev->input == PREVIEW_INPUT_MEMORY || 1570 if (prev->input == PREVIEW_INPUT_MEMORY ||
1466 prev->output & PREVIEW_OUTPUT_MEMORY) 1571 prev->output & PREVIEW_OUTPUT_MEMORY)
1467 preview_isr_buffer(prev); 1572 preview_isr_buffer(prev);
1468 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS) 1573 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1469 preview_enable_oneshot(prev); 1574 preview_enable_oneshot(prev);
1575
1576 spin_lock_irqsave(&prev->params.lock, flags);
1577 preview_params_unlock(prev, update, false);
1578 spin_unlock_irqrestore(&prev->params.lock, flags);
1470} 1579}
1471 1580
1472/* ----------------------------------------------------------------------------- 1581/* -----------------------------------------------------------------------------
@@ -1552,7 +1661,6 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1552 struct isp_video *video_out = &prev->video_out; 1661 struct isp_video *video_out = &prev->video_out;
1553 struct isp_device *isp = to_isp_device(prev); 1662 struct isp_device *isp = to_isp_device(prev);
1554 struct device *dev = to_device(prev); 1663 struct device *dev = to_device(prev);
1555 unsigned long flags;
1556 1664
1557 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) { 1665 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) {
1558 if (enable == ISP_PIPELINE_STREAM_STOPPED) 1666 if (enable == ISP_PIPELINE_STREAM_STOPPED)
@@ -1589,11 +1697,9 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1589 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait, 1697 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait,
1590 &prev->stopping)) 1698 &prev->stopping))
1591 dev_dbg(dev, "%s: stop timeout.\n", sd->name); 1699 dev_dbg(dev, "%s: stop timeout.\n", sd->name);
1592 spin_lock_irqsave(&prev->lock, flags);
1593 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ); 1700 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1594 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE); 1701 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1595 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW); 1702 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1596 spin_unlock_irqrestore(&prev->lock, flags);
1597 isp_video_dmaqueue_flags_clr(video_out); 1703 isp_video_dmaqueue_flags_clr(video_out);
1598 break; 1704 break;
1599 } 1705 }
@@ -1624,6 +1730,7 @@ __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1624 1730
1625/* previewer format descriptions */ 1731/* previewer format descriptions */
1626static const unsigned int preview_input_fmts[] = { 1732static const unsigned int preview_input_fmts[] = {
1733 V4L2_MBUS_FMT_Y10_1X10,
1627 V4L2_MBUS_FMT_SGRBG10_1X10, 1734 V4L2_MBUS_FMT_SGRBG10_1X10,
1628 V4L2_MBUS_FMT_SRGGB10_1X10, 1735 V4L2_MBUS_FMT_SRGGB10_1X10,
1629 V4L2_MBUS_FMT_SBGGR10_1X10, 1736 V4L2_MBUS_FMT_SBGGR10_1X10,
@@ -1822,55 +1929,89 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1822} 1929}
1823 1930
1824/* 1931/*
1825 * preview_get_crop - Retrieve the crop rectangle on a pad 1932 * preview_get_selection - Retrieve a selection rectangle on a pad
1826 * @sd: ISP preview V4L2 subdevice 1933 * @sd: ISP preview V4L2 subdevice
1827 * @fh: V4L2 subdev file handle 1934 * @fh: V4L2 subdev file handle
1828 * @crop: crop rectangle 1935 * @sel: Selection rectangle
1936 *
1937 * The only supported rectangles are the crop rectangles on the sink pad.
1829 * 1938 *
1830 * Return 0 on success or a negative error code otherwise. 1939 * Return 0 on success or a negative error code otherwise.
1831 */ 1940 */
1832static int preview_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 1941static int preview_get_selection(struct v4l2_subdev *sd,
1833 struct v4l2_subdev_crop *crop) 1942 struct v4l2_subdev_fh *fh,
1943 struct v4l2_subdev_selection *sel)
1834{ 1944{
1835 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1945 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1946 struct v4l2_mbus_framefmt *format;
1947
1948 if (sel->pad != PREV_PAD_SINK)
1949 return -EINVAL;
1950
1951 switch (sel->target) {
1952 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
1953 sel->r.left = 0;
1954 sel->r.top = 0;
1955 sel->r.width = INT_MAX;
1956 sel->r.height = INT_MAX;
1957
1958 format = __preview_get_format(prev, fh, PREV_PAD_SINK,
1959 sel->which);
1960 preview_try_crop(prev, format, &sel->r);
1961 break;
1962
1963 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1964 sel->r = *__preview_get_crop(prev, fh, sel->which);
1965 break;
1836 1966
1837 /* Cropping is only supported on the sink pad. */ 1967 default:
1838 if (crop->pad != PREV_PAD_SINK)
1839 return -EINVAL; 1968 return -EINVAL;
1969 }
1840 1970
1841 crop->rect = *__preview_get_crop(prev, fh, crop->which);
1842 return 0; 1971 return 0;
1843} 1972}
1844 1973
1845/* 1974/*
1846 * preview_set_crop - Retrieve the crop rectangle on a pad 1975 * preview_set_selection - Set a selection rectangle on a pad
1847 * @sd: ISP preview V4L2 subdevice 1976 * @sd: ISP preview V4L2 subdevice
1848 * @fh: V4L2 subdev file handle 1977 * @fh: V4L2 subdev file handle
1849 * @crop: crop rectangle 1978 * @sel: Selection rectangle
1979 *
1980 * The only supported rectangle is the actual crop rectangle on the sink pad.
1850 * 1981 *
1851 * Return 0 on success or a negative error code otherwise. 1982 * Return 0 on success or a negative error code otherwise.
1852 */ 1983 */
1853static int preview_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 1984static int preview_set_selection(struct v4l2_subdev *sd,
1854 struct v4l2_subdev_crop *crop) 1985 struct v4l2_subdev_fh *fh,
1986 struct v4l2_subdev_selection *sel)
1855{ 1987{
1856 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1988 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1857 struct v4l2_mbus_framefmt *format; 1989 struct v4l2_mbus_framefmt *format;
1858 1990
1859 /* Cropping is only supported on the sink pad. */ 1991 if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
1860 if (crop->pad != PREV_PAD_SINK) 1992 sel->pad != PREV_PAD_SINK)
1861 return -EINVAL; 1993 return -EINVAL;
1862 1994
1863 /* The crop rectangle can't be changed while streaming. */ 1995 /* The crop rectangle can't be changed while streaming. */
1864 if (prev->state != ISP_PIPELINE_STREAM_STOPPED) 1996 if (prev->state != ISP_PIPELINE_STREAM_STOPPED)
1865 return -EBUSY; 1997 return -EBUSY;
1866 1998
1867 format = __preview_get_format(prev, fh, PREV_PAD_SINK, crop->which); 1999 /* Modifying the crop rectangle always changes the format on the source
1868 preview_try_crop(prev, format, &crop->rect); 2000 * pad. If the KEEP_CONFIG flag is set, just return the current crop
1869 *__preview_get_crop(prev, fh, crop->which) = crop->rect; 2001 * rectangle.
2002 */
2003 if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) {
2004 sel->r = *__preview_get_crop(prev, fh, sel->which);
2005 return 0;
2006 }
2007
2008 format = __preview_get_format(prev, fh, PREV_PAD_SINK, sel->which);
2009 preview_try_crop(prev, format, &sel->r);
2010 *__preview_get_crop(prev, fh, sel->which) = sel->r;
1870 2011
1871 /* Update the source format. */ 2012 /* Update the source format. */
1872 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, crop->which); 2013 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, sel->which);
1873 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, crop->which); 2014 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, sel->which);
1874 2015
1875 return 0; 2016 return 0;
1876} 2017}
@@ -1979,8 +2120,8 @@ static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
1979 .enum_frame_size = preview_enum_frame_size, 2120 .enum_frame_size = preview_enum_frame_size,
1980 .get_fmt = preview_get_format, 2121 .get_fmt = preview_get_format,
1981 .set_fmt = preview_set_format, 2122 .set_fmt = preview_set_format,
1982 .get_crop = preview_get_crop, 2123 .get_selection = preview_get_selection,
1983 .set_crop = preview_set_crop, 2124 .set_selection = preview_set_selection,
1984}; 2125};
1985 2126
1986/* subdev operations */ 2127/* subdev operations */
@@ -2076,6 +2217,7 @@ static int preview_link_setup(struct media_entity *entity,
2076/* media operations */ 2217/* media operations */
2077static const struct media_entity_operations preview_media_ops = { 2218static const struct media_entity_operations preview_media_ops = {
2078 .link_setup = preview_link_setup, 2219 .link_setup = preview_link_setup,
2220 .link_validate = v4l2_subdev_link_validate,
2079}; 2221};
2080 2222
2081void omap3isp_preview_unregister_entities(struct isp_prev_device *prev) 2223void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
@@ -2201,7 +2343,7 @@ error_video_in:
2201} 2343}
2202 2344
2203/* 2345/*
2204 * isp_preview_init - Previewer initialization. 2346 * omap3isp_preview_init - Previewer initialization.
2205 * @dev : Pointer to ISP device 2347 * @dev : Pointer to ISP device
2206 * return -ENOMEM or zero on success 2348 * return -ENOMEM or zero on success
2207 */ 2349 */
@@ -2209,8 +2351,8 @@ int omap3isp_preview_init(struct isp_device *isp)
2209{ 2351{
2210 struct isp_prev_device *prev = &isp->isp_prev; 2352 struct isp_prev_device *prev = &isp->isp_prev;
2211 2353
2212 spin_lock_init(&prev->lock);
2213 init_waitqueue_head(&prev->wait); 2354 init_waitqueue_head(&prev->wait);
2355
2214 preview_init_params(prev); 2356 preview_init_params(prev);
2215 2357
2216 return preview_init_entities(prev); 2358 return preview_init_entities(prev);
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
index 09686607973c..6663ab64e4b1 100644
--- a/drivers/media/video/omap3isp/isppreview.h
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -45,29 +45,10 @@
45#define ISPPRV_CONTRAST_HIGH 0xFF 45#define ISPPRV_CONTRAST_HIGH 0xFF
46#define ISPPRV_CONTRAST_UNITS 0x1 46#define ISPPRV_CONTRAST_UNITS 0x1
47 47
48/* Features list */ 48/* Additional features not listed in linux/omap3isp.h */
49#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH 49#define OMAP3ISP_PREV_CONTRAST (1 << 17)
50#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW 50#define OMAP3ISP_PREV_BRIGHTNESS (1 << 18)
51#define PREV_HORZ_MEDIAN_FILTER OMAP3ISP_PREV_HRZ_MED 51#define OMAP3ISP_PREV_FEATURES_END (1 << 19)
52#define PREV_CFA OMAP3ISP_PREV_CFA
53#define PREV_CHROMA_SUPPRESS OMAP3ISP_PREV_CHROMA_SUPP
54#define PREV_WB OMAP3ISP_PREV_WB
55#define PREV_BLKADJ OMAP3ISP_PREV_BLKADJ
56#define PREV_RGB2RGB OMAP3ISP_PREV_RGB2RGB
57#define PREV_COLOR_CONV OMAP3ISP_PREV_COLOR_CONV
58#define PREV_YCLIMITS OMAP3ISP_PREV_YC_LIMIT
59#define PREV_DEFECT_COR OMAP3ISP_PREV_DEFECT_COR
60#define PREV_GAMMA_BYPASS OMAP3ISP_PREV_GAMMABYPASS
61#define PREV_DARK_FRAME_CAPTURE OMAP3ISP_PREV_DRK_FRM_CAPTURE
62#define PREV_DARK_FRAME_SUBTRACT OMAP3ISP_PREV_DRK_FRM_SUBTRACT
63#define PREV_LENS_SHADING OMAP3ISP_PREV_LENS_SHADING
64#define PREV_NOISE_FILTER OMAP3ISP_PREV_NF
65#define PREV_GAMMA OMAP3ISP_PREV_GAMMA
66
67#define PREV_CONTRAST (1 << 17)
68#define PREV_BRIGHTNESS (1 << 18)
69#define PREV_AVERAGER (1 << 19)
70#define PREV_FEATURES_END (1 << 20)
71 52
72enum preview_input_entity { 53enum preview_input_entity {
73 PREVIEW_INPUT_NONE, 54 PREVIEW_INPUT_NONE,
@@ -88,6 +69,8 @@ enum preview_ycpos_mode {
88 69
89/* 70/*
90 * struct prev_params - Structure for all configuration 71 * struct prev_params - Structure for all configuration
72 * @busy: Bitmask of busy parameters (being updated or used)
73 * @update: Bitmask of the parameters to be updated
91 * @features: Set of features enabled. 74 * @features: Set of features enabled.
92 * @cfa: CFA coefficients. 75 * @cfa: CFA coefficients.
93 * @csup: Chroma suppression coefficients. 76 * @csup: Chroma suppression coefficients.
@@ -96,15 +79,17 @@ enum preview_ycpos_mode {
96 * @dcor: Noise filter coefficients. 79 * @dcor: Noise filter coefficients.
97 * @gamma: Gamma coefficients. 80 * @gamma: Gamma coefficients.
98 * @wbal: White Balance parameters. 81 * @wbal: White Balance parameters.
99 * @blk_adj: Black adjustment parameters. 82 * @blkadj: Black adjustment parameters.
100 * @rgb2rgb: RGB blending parameters. 83 * @rgb2rgb: RGB blending parameters.
101 * @rgb2ycbcr: RGB to ycbcr parameters. 84 * @csc: Color space conversion (RGB to YCbCr) parameters.
102 * @hmed: Horizontal median filter. 85 * @hmed: Horizontal median filter.
103 * @yclimit: YC limits parameters. 86 * @yclimit: YC limits parameters.
104 * @contrast: Contrast. 87 * @contrast: Contrast.
105 * @brightness: Brightness. 88 * @brightness: Brightness.
106 */ 89 */
107struct prev_params { 90struct prev_params {
91 u32 busy;
92 u32 update;
108 u32 features; 93 u32 features;
109 struct omap3isp_prev_cfa cfa; 94 struct omap3isp_prev_cfa cfa;
110 struct omap3isp_prev_csup csup; 95 struct omap3isp_prev_csup csup;
@@ -113,35 +98,15 @@ struct prev_params {
113 struct omap3isp_prev_dcor dcor; 98 struct omap3isp_prev_dcor dcor;
114 struct omap3isp_prev_gtables gamma; 99 struct omap3isp_prev_gtables gamma;
115 struct omap3isp_prev_wbal wbal; 100 struct omap3isp_prev_wbal wbal;
116 struct omap3isp_prev_blkadj blk_adj; 101 struct omap3isp_prev_blkadj blkadj;
117 struct omap3isp_prev_rgbtorgb rgb2rgb; 102 struct omap3isp_prev_rgbtorgb rgb2rgb;
118 struct omap3isp_prev_csc rgb2ycbcr; 103 struct omap3isp_prev_csc csc;
119 struct omap3isp_prev_hmed hmed; 104 struct omap3isp_prev_hmed hmed;
120 struct omap3isp_prev_yclimit yclimit; 105 struct omap3isp_prev_yclimit yclimit;
121 u8 contrast; 106 u8 contrast;
122 u8 brightness; 107 u8 brightness;
123}; 108};
124 109
125/*
126 * struct isptables_update - Structure for Table Configuration.
127 * @update: Specifies which tables should be updated.
128 * @flag: Specifies which tables should be enabled.
129 * @nf: Pointer to structure for Noise Filter
130 * @lsc: Pointer to LSC gain table. (currently not used)
131 * @gamma: Pointer to gamma correction tables.
132 * @cfa: Pointer to color filter array configuration.
133 * @wbal: Pointer to colour and digital gain configuration.
134 */
135struct isptables_update {
136 u32 update;
137 u32 flag;
138 struct omap3isp_prev_nf *nf;
139 u32 *lsc;
140 struct omap3isp_prev_gtables *gamma;
141 struct omap3isp_prev_cfa *cfa;
142 struct omap3isp_prev_wbal *wbal;
143};
144
145/* Sink and source previewer pads */ 110/* Sink and source previewer pads */
146#define PREV_PAD_SINK 0 111#define PREV_PAD_SINK 0
147#define PREV_PAD_SOURCE 1 112#define PREV_PAD_SOURCE 1
@@ -157,12 +122,11 @@ struct isptables_update {
157 * @output: Bitmask of the active output 122 * @output: Bitmask of the active output
158 * @video_in: Input video entity 123 * @video_in: Input video entity
159 * @video_out: Output video entity 124 * @video_out: Output video entity
160 * @params: Module configuration data 125 * @params.params : Active and shadow parameters sets
161 * @shadow_update: If set, update the hardware configured in the next interrupt 126 * @params.active: Bitmask of parameters active in set 0
127 * @params.lock: Parameters lock, protects params.active and params.shadow
162 * @underrun: Whether the preview entity has queued buffers on the output 128 * @underrun: Whether the preview entity has queued buffers on the output
163 * @state: Current preview pipeline state 129 * @state: Current preview pipeline state
164 * @lock: Shadow update lock
165 * @update: Bitmask of the parameters to be updated
166 * 130 *
167 * This structure is used to store the OMAP ISP Preview module Information. 131 * This structure is used to store the OMAP ISP Preview module Information.
168 */ 132 */
@@ -179,13 +143,15 @@ struct isp_prev_device {
179 struct isp_video video_in; 143 struct isp_video video_in;
180 struct isp_video video_out; 144 struct isp_video video_out;
181 145
182 struct prev_params params; 146 struct {
183 unsigned int shadow_update:1; 147 struct prev_params params[2];
148 u32 active;
149 spinlock_t lock;
150 } params;
151
184 enum isp_pipeline_stream_state state; 152 enum isp_pipeline_stream_state state;
185 wait_queue_head_t wait; 153 wait_queue_head_t wait;
186 atomic_t stopping; 154 atomic_t stopping;
187 spinlock_t lock;
188 u32 update;
189}; 155};
190 156
191struct isp_device; 157struct isp_device;
diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/video/omap3isp/ispqueue.h
index 92c5a12157d5..908dfd712e8e 100644
--- a/drivers/media/video/omap3isp/ispqueue.h
+++ b/drivers/media/video/omap3isp/ispqueue.h
@@ -90,7 +90,7 @@ struct isp_video_buffer {
90 void *vaddr; 90 void *vaddr;
91 91
92 /* For userspace buffers. */ 92 /* For userspace buffers. */
93 unsigned long vm_flags; 93 vm_flags_t vm_flags;
94 unsigned long offset; 94 unsigned long offset;
95 unsigned int npages; 95 unsigned int npages;
96 struct page **pages; 96 struct page **pages;
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 6958a9e3dc22..14041c9c8643 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -1188,32 +1188,6 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
1188} 1188}
1189 1189
1190/* 1190/*
1191 * resizer_g_crop - handle get crop subdev operation
1192 * @sd : pointer to v4l2 subdev structure
1193 * @pad : subdev pad
1194 * @crop : pointer to crop structure
1195 * @which : active or try format
1196 * return zero
1197 */
1198static int resizer_g_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1199 struct v4l2_subdev_crop *crop)
1200{
1201 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1202 struct v4l2_mbus_framefmt *format;
1203 struct resizer_ratio ratio;
1204
1205 /* Only sink pad has crop capability */
1206 if (crop->pad != RESZ_PAD_SINK)
1207 return -EINVAL;
1208
1209 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, crop->which);
1210 crop->rect = *__resizer_get_crop(res, fh, crop->which);
1211 resizer_calc_ratios(res, &crop->rect, format, &ratio);
1212
1213 return 0;
1214}
1215
1216/*
1217 * resizer_try_crop - mangles crop parameters. 1191 * resizer_try_crop - mangles crop parameters.
1218 */ 1192 */
1219static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, 1193static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
@@ -1223,7 +1197,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1223 const unsigned int spv = DEFAULT_PHASE; 1197 const unsigned int spv = DEFAULT_PHASE;
1224 const unsigned int sph = DEFAULT_PHASE; 1198 const unsigned int sph = DEFAULT_PHASE;
1225 1199
1226 /* Crop rectangle is constrained to the output size so that zoom ratio 1200 /* Crop rectangle is constrained by the output size so that zoom ratio
1227 * cannot exceed +/-4.0. 1201 * cannot exceed +/-4.0.
1228 */ 1202 */
1229 unsigned int min_width = 1203 unsigned int min_width =
@@ -1248,51 +1222,115 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1248} 1222}
1249 1223
1250/* 1224/*
1251 * resizer_s_crop - handle set crop subdev operation 1225 * resizer_get_selection - Retrieve a selection rectangle on a pad
1252 * @sd : pointer to v4l2 subdev structure 1226 * @sd: ISP resizer V4L2 subdevice
1253 * @pad : subdev pad 1227 * @fh: V4L2 subdev file handle
1254 * @crop : pointer to crop structure 1228 * @sel: Selection rectangle
1255 * @which : active or try format 1229 *
1256 * return -EINVAL or zero when succeed 1230 * The only supported rectangles are the crop rectangles on the sink pad.
1231 *
1232 * Return 0 on success or a negative error code otherwise.
1257 */ 1233 */
1258static int resizer_s_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 1234static int resizer_get_selection(struct v4l2_subdev *sd,
1259 struct v4l2_subdev_crop *crop) 1235 struct v4l2_subdev_fh *fh,
1236 struct v4l2_subdev_selection *sel)
1237{
1238 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1239 struct v4l2_mbus_framefmt *format_source;
1240 struct v4l2_mbus_framefmt *format_sink;
1241 struct resizer_ratio ratio;
1242
1243 if (sel->pad != RESZ_PAD_SINK)
1244 return -EINVAL;
1245
1246 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1247 sel->which);
1248 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1249 sel->which);
1250
1251 switch (sel->target) {
1252 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
1253 sel->r.left = 0;
1254 sel->r.top = 0;
1255 sel->r.width = INT_MAX;
1256 sel->r.height = INT_MAX;
1257
1258 resizer_try_crop(format_sink, format_source, &sel->r);
1259 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1260 break;
1261
1262 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1263 sel->r = *__resizer_get_crop(res, fh, sel->which);
1264 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1265 break;
1266
1267 default:
1268 return -EINVAL;
1269 }
1270
1271 return 0;
1272}
1273
1274/*
1275 * resizer_set_selection - Set a selection rectangle on a pad
1276 * @sd: ISP resizer V4L2 subdevice
1277 * @fh: V4L2 subdev file handle
1278 * @sel: Selection rectangle
1279 *
1280 * The only supported rectangle is the actual crop rectangle on the sink pad.
1281 *
1282 * FIXME: This function currently behaves as if the KEEP_CONFIG selection flag
1283 * was always set.
1284 *
1285 * Return 0 on success or a negative error code otherwise.
1286 */
1287static int resizer_set_selection(struct v4l2_subdev *sd,
1288 struct v4l2_subdev_fh *fh,
1289 struct v4l2_subdev_selection *sel)
1260{ 1290{
1261 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1291 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1262 struct isp_device *isp = to_isp_device(res); 1292 struct isp_device *isp = to_isp_device(res);
1263 struct v4l2_mbus_framefmt *format_sink, *format_source; 1293 struct v4l2_mbus_framefmt *format_sink, *format_source;
1264 struct resizer_ratio ratio; 1294 struct resizer_ratio ratio;
1265 1295
1266 /* Only sink pad has crop capability */ 1296 if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
1267 if (crop->pad != RESZ_PAD_SINK) 1297 sel->pad != RESZ_PAD_SINK)
1268 return -EINVAL; 1298 return -EINVAL;
1269 1299
1270 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, 1300 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1271 crop->which); 1301 sel->which);
1272 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, 1302 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1273 crop->which); 1303 sel->which);
1274 1304
1275 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__, 1305 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__,
1276 crop->rect.left, crop->rect.top, crop->rect.width, 1306 sel->r.left, sel->r.top, sel->r.width, sel->r.height,
1277 crop->rect.height, crop->which); 1307 sel->which);
1278 1308
1279 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__, 1309 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__,
1280 format_sink->width, format_sink->height, 1310 format_sink->width, format_sink->height,
1281 format_source->width, format_source->height); 1311 format_source->width, format_source->height);
1282 1312
1283 resizer_try_crop(format_sink, format_source, &crop->rect); 1313 /* Clamp the crop rectangle to the bounds, and then mangle it further to
1284 *__resizer_get_crop(res, fh, crop->which) = crop->rect; 1314 * fulfill the TRM equations. Store the clamped but otherwise unmangled
1285 resizer_calc_ratios(res, &crop->rect, format_source, &ratio); 1315 * rectangle to avoid cropping the input multiple times: when an
1316 * application sets the output format, the current crop rectangle is
1317 * mangled during crop rectangle computation, which would lead to a new,
1318 * smaller input crop rectangle every time the output size is set if we
1319 * stored the mangled rectangle.
1320 */
1321 resizer_try_crop(format_sink, format_source, &sel->r);
1322 *__resizer_get_crop(res, fh, sel->which) = sel->r;
1323 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1286 1324
1287 if (crop->which == V4L2_SUBDEV_FORMAT_TRY) 1325 if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1288 return 0; 1326 return 0;
1289 1327
1290 res->ratio = ratio; 1328 res->ratio = ratio;
1291 res->crop.active = crop->rect; 1329 res->crop.active = sel->r;
1292 1330
1293 /* 1331 /*
1294 * s_crop can be called while streaming is on. In this case 1332 * set_selection can be called while streaming is on. In this case the
1295 * the crop values will be set in the next IRQ. 1333 * crop values will be set in the next IRQ.
1296 */ 1334 */
1297 if (res->state != ISP_PIPELINE_STREAM_STOPPED) 1335 if (res->state != ISP_PIPELINE_STREAM_STOPPED)
1298 res->applycrop = 1; 1336 res->applycrop = 1;
@@ -1530,8 +1568,8 @@ static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
1530 .enum_frame_size = resizer_enum_frame_size, 1568 .enum_frame_size = resizer_enum_frame_size,
1531 .get_fmt = resizer_get_format, 1569 .get_fmt = resizer_get_format,
1532 .set_fmt = resizer_set_format, 1570 .set_fmt = resizer_set_format,
1533 .get_crop = resizer_g_crop, 1571 .get_selection = resizer_get_selection,
1534 .set_crop = resizer_s_crop, 1572 .set_selection = resizer_set_selection,
1535}; 1573};
1536 1574
1537/* subdev operations */ 1575/* subdev operations */
@@ -1603,6 +1641,7 @@ static int resizer_link_setup(struct media_entity *entity,
1603/* media operations */ 1641/* media operations */
1604static const struct media_entity_operations resizer_media_ops = { 1642static const struct media_entity_operations resizer_media_ops = {
1605 .link_setup = resizer_link_setup, 1643 .link_setup = resizer_link_setup,
1644 .link_validate = v4l2_subdev_link_validate,
1606}; 1645};
1607 1646
1608void omap3isp_resizer_unregister_entities(struct isp_res_device *res) 1647void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
index 11871ecc6d25..b8640be692f1 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1032,7 +1032,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
1032 if (sub->type != stat->event_type) 1032 if (sub->type != stat->event_type)
1033 return -EINVAL; 1033 return -EINVAL;
1034 1034
1035 return v4l2_event_subscribe(fh, sub, STAT_NEVENTS); 1035 return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
1036} 1036}
1037 1037
1038int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, 1038int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
index b02070057724..b37379d39cdd 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -46,6 +46,10 @@
46 * Helper functions 46 * Helper functions
47 */ 47 */
48 48
49/*
50 * NOTE: When adding new media bus codes, always remember to add
51 * corresponding in-memory formats to the table below!!!
52 */
49static struct isp_format_info formats[] = { 53static struct isp_format_info formats[] = {
50 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, 54 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
51 V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, 55 V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
@@ -68,9 +72,18 @@ static struct isp_format_info formats[] = {
68 { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, 72 { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
69 V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, 73 V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
70 V4L2_PIX_FMT_SRGGB8, 8, }, 74 V4L2_PIX_FMT_SRGGB8, 8, },
75 { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
76 V4L2_MBUS_FMT_SBGGR10_1X10, 0,
77 V4L2_PIX_FMT_SBGGR10DPCM8, 8, },
78 { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
79 V4L2_MBUS_FMT_SGBRG10_1X10, 0,
80 V4L2_PIX_FMT_SGBRG10DPCM8, 8, },
71 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 81 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
72 V4L2_MBUS_FMT_SGRBG10_1X10, 0, 82 V4L2_MBUS_FMT_SGRBG10_1X10, 0,
73 V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, 83 V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
84 { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
85 V4L2_MBUS_FMT_SRGGB10_1X10, 0,
86 V4L2_PIX_FMT_SRGGB10DPCM8, 8, },
74 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, 87 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
75 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, 88 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
76 V4L2_PIX_FMT_SBGGR10, 10, }, 89 V4L2_PIX_FMT_SBGGR10, 10, },
@@ -117,37 +130,6 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
117} 130}
118 131
119/* 132/*
120 * Decide whether desired output pixel code can be obtained with
121 * the lane shifter by shifting the input pixel code.
122 * @in: input pixelcode to shifter
123 * @out: output pixelcode from shifter
124 * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
125 *
126 * return true if the combination is possible
127 * return false otherwise
128 */
129static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in,
130 enum v4l2_mbus_pixelcode out,
131 unsigned int additional_shift)
132{
133 const struct isp_format_info *in_info, *out_info;
134
135 if (in == out)
136 return true;
137
138 in_info = omap3isp_video_format_info(in);
139 out_info = omap3isp_video_format_info(out);
140
141 if ((in_info->flavor == 0) || (out_info->flavor == 0))
142 return false;
143
144 if (in_info->flavor != out_info->flavor)
145 return false;
146
147 return in_info->bpp - out_info->bpp + additional_shift <= 6;
148}
149
150/*
151 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format 133 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
152 * @video: ISP video instance 134 * @video: ISP video instance
153 * @mbus: v4l2_mbus_framefmt format (input) 135 * @mbus: v4l2_mbus_framefmt format (input)
@@ -242,8 +224,8 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
242} 224}
243 225
244/* Return a pointer to the ISP video instance at the far end of the pipeline. */ 226/* Return a pointer to the ISP video instance at the far end of the pipeline. */
245static struct isp_video * 227static int isp_video_get_graph_data(struct isp_video *video,
246isp_video_far_end(struct isp_video *video) 228 struct isp_pipeline *pipe)
247{ 229{
248 struct media_entity_graph graph; 230 struct media_entity_graph graph;
249 struct media_entity *entity = &video->video.entity; 231 struct media_entity *entity = &video->video.entity;
@@ -254,21 +236,38 @@ isp_video_far_end(struct isp_video *video)
254 media_entity_graph_walk_start(&graph, entity); 236 media_entity_graph_walk_start(&graph, entity);
255 237
256 while ((entity = media_entity_graph_walk_next(&graph))) { 238 while ((entity = media_entity_graph_walk_next(&graph))) {
239 struct isp_video *__video;
240
241 pipe->entities |= 1 << entity->id;
242
243 if (far_end != NULL)
244 continue;
245
257 if (entity == &video->video.entity) 246 if (entity == &video->video.entity)
258 continue; 247 continue;
259 248
260 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 249 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
261 continue; 250 continue;
262 251
263 far_end = to_isp_video(media_entity_to_video_device(entity)); 252 __video = to_isp_video(media_entity_to_video_device(entity));
264 if (far_end->type != video->type) 253 if (__video->type != video->type)
265 break; 254 far_end = __video;
266
267 far_end = NULL;
268 } 255 }
269 256
270 mutex_unlock(&mdev->graph_mutex); 257 mutex_unlock(&mdev->graph_mutex);
271 return far_end; 258
259 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
260 pipe->input = far_end;
261 pipe->output = video;
262 } else {
263 if (far_end == NULL)
264 return -EPIPE;
265
266 pipe->input = video;
267 pipe->output = far_end;
268 }
269
270 return 0;
272} 271}
273 272
274/* 273/*
@@ -285,52 +284,24 @@ isp_video_far_end(struct isp_video *video)
285static int isp_video_validate_pipeline(struct isp_pipeline *pipe) 284static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
286{ 285{
287 struct isp_device *isp = pipe->output->isp; 286 struct isp_device *isp = pipe->output->isp;
288 struct v4l2_subdev_format fmt_source;
289 struct v4l2_subdev_format fmt_sink;
290 struct media_pad *pad; 287 struct media_pad *pad;
291 struct v4l2_subdev *subdev; 288 struct v4l2_subdev *subdev;
292 int ret;
293
294 pipe->max_rate = pipe->l3_ick;
295 289
296 subdev = isp_video_remote_subdev(pipe->output, NULL); 290 subdev = isp_video_remote_subdev(pipe->output, NULL);
297 if (subdev == NULL) 291 if (subdev == NULL)
298 return -EPIPE; 292 return -EPIPE;
299 293
300 while (1) { 294 while (1) {
301 unsigned int shifter_link;
302 /* Retrieve the sink format */ 295 /* Retrieve the sink format */
303 pad = &subdev->entity.pads[0]; 296 pad = &subdev->entity.pads[0];
304 if (!(pad->flags & MEDIA_PAD_FL_SINK)) 297 if (!(pad->flags & MEDIA_PAD_FL_SINK))
305 break; 298 break;
306 299
307 fmt_sink.pad = pad->index;
308 fmt_sink.which = V4L2_SUBDEV_FORMAT_ACTIVE;
309 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_sink);
310 if (ret < 0 && ret != -ENOIOCTLCMD)
311 return -EPIPE;
312
313 /* Update the maximum frame rate */ 300 /* Update the maximum frame rate */
314 if (subdev == &isp->isp_res.subdev) 301 if (subdev == &isp->isp_res.subdev)
315 omap3isp_resizer_max_rate(&isp->isp_res, 302 omap3isp_resizer_max_rate(&isp->isp_res,
316 &pipe->max_rate); 303 &pipe->max_rate);
317 304
318 /* Check ccdc maximum data rate when data comes from sensor
319 * TODO: Include ccdc rate in pipe->max_rate and compare the
320 * total pipe rate with the input data rate from sensor.
321 */
322 if (subdev == &isp->isp_ccdc.subdev && pipe->input == NULL) {
323 unsigned int rate = UINT_MAX;
324
325 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
326 if (isp->isp_ccdc.vpcfg.pixelclk > rate)
327 return -ENOSPC;
328 }
329
330 /* If sink pad is on CCDC, the link has the lane shifter
331 * in the middle of it. */
332 shifter_link = subdev == &isp->isp_ccdc.subdev;
333
334 /* Retrieve the source format. Return an error if no source 305 /* Retrieve the source format. Return an error if no source
335 * entity can be found, and stop checking the pipeline if the 306 * entity can be found, and stop checking the pipeline if the
336 * source entity isn't a subdev. 307 * source entity isn't a subdev.
@@ -343,32 +314,6 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
343 break; 314 break;
344 315
345 subdev = media_entity_to_v4l2_subdev(pad->entity); 316 subdev = media_entity_to_v4l2_subdev(pad->entity);
346
347 fmt_source.pad = pad->index;
348 fmt_source.which = V4L2_SUBDEV_FORMAT_ACTIVE;
349 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_source);
350 if (ret < 0 && ret != -ENOIOCTLCMD)
351 return -EPIPE;
352
353 /* Check if the two ends match */
354 if (fmt_source.format.width != fmt_sink.format.width ||
355 fmt_source.format.height != fmt_sink.format.height)
356 return -EPIPE;
357
358 if (shifter_link) {
359 unsigned int parallel_shift = 0;
360 if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) {
361 struct isp_parallel_platform_data *pdata =
362 &((struct isp_v4l2_subdevs_group *)
363 subdev->host_priv)->bus.parallel;
364 parallel_shift = pdata->data_lane_shift * 2;
365 }
366 if (!isp_video_is_shiftable(fmt_source.format.code,
367 fmt_sink.format.code,
368 parallel_shift))
369 return -EPIPE;
370 } else if (fmt_source.format.code != fmt_sink.format.code)
371 return -EPIPE;
372 } 317 }
373 318
374 return 0; 319 return 0;
@@ -923,6 +868,92 @@ isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
923 file->f_flags & O_NONBLOCK); 868 file->f_flags & O_NONBLOCK);
924} 869}
925 870
871static int isp_video_check_external_subdevs(struct isp_video *video,
872 struct isp_pipeline *pipe)
873{
874 struct isp_device *isp = video->isp;
875 struct media_entity *ents[] = {
876 &isp->isp_csi2a.subdev.entity,
877 &isp->isp_csi2c.subdev.entity,
878 &isp->isp_ccp2.subdev.entity,
879 &isp->isp_ccdc.subdev.entity
880 };
881 struct media_pad *source_pad;
882 struct media_entity *source = NULL;
883 struct media_entity *sink;
884 struct v4l2_subdev_format fmt;
885 struct v4l2_ext_controls ctrls;
886 struct v4l2_ext_control ctrl;
887 unsigned int i;
888 int ret = 0;
889
890 for (i = 0; i < ARRAY_SIZE(ents); i++) {
891 /* Is the entity part of the pipeline? */
892 if (!(pipe->entities & (1 << ents[i]->id)))
893 continue;
894
895 /* ISP entities have always sink pad == 0. Find source. */
896 source_pad = media_entity_remote_source(&ents[i]->pads[0]);
897 if (source_pad == NULL)
898 continue;
899
900 source = source_pad->entity;
901 sink = ents[i];
902 break;
903 }
904
905 if (!source) {
906 dev_warn(isp->dev, "can't find source, failing now\n");
907 return ret;
908 }
909
910 if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
911 return 0;
912
913 pipe->external = media_entity_to_v4l2_subdev(source);
914
915 fmt.pad = source_pad->index;
916 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
917 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
918 pad, get_fmt, NULL, &fmt);
919 if (unlikely(ret < 0)) {
920 dev_warn(isp->dev, "get_fmt returned null!\n");
921 return ret;
922 }
923
924 pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
925
926 memset(&ctrls, 0, sizeof(ctrls));
927 memset(&ctrl, 0, sizeof(ctrl));
928
929 ctrl.id = V4L2_CID_PIXEL_RATE;
930
931 ctrls.count = 1;
932 ctrls.controls = &ctrl;
933
934 ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
935 if (ret < 0) {
936 dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
937 pipe->external->name);
938 return ret;
939 }
940
941 pipe->external_rate = ctrl.value64;
942
943 if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
944 unsigned int rate = UINT_MAX;
945 /*
946 * Check that maximum allowed CCDC pixel rate isn't
947 * exceeded by the pixel rate.
948 */
949 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
950 if (pipe->external_rate > rate)
951 return -ENOSPC;
952 }
953
954 return 0;
955}
956
926/* 957/*
927 * Stream management 958 * Stream management
928 * 959 *
@@ -961,7 +992,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
961 struct isp_video *video = video_drvdata(file); 992 struct isp_video *video = video_drvdata(file);
962 enum isp_pipeline_state state; 993 enum isp_pipeline_state state;
963 struct isp_pipeline *pipe; 994 struct isp_pipeline *pipe;
964 struct isp_video *far_end;
965 unsigned long flags; 995 unsigned long flags;
966 int ret; 996 int ret;
967 997
@@ -980,46 +1010,45 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
980 */ 1010 */
981 pipe = video->video.entity.pipe 1011 pipe = video->video.entity.pipe
982 ? to_isp_pipeline(&video->video.entity) : &video->pipe; 1012 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
983 media_entity_pipeline_start(&video->video.entity, &pipe->pipe); 1013
1014 pipe->entities = 0;
1015
1016 if (video->isp->pdata->set_constraints)
1017 video->isp->pdata->set_constraints(video->isp, true);
1018 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
1019 pipe->max_rate = pipe->l3_ick;
1020
1021 ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
1022 if (ret < 0)
1023 goto err_pipeline_start;
984 1024
985 /* Verify that the currently configured format matches the output of 1025 /* Verify that the currently configured format matches the output of
986 * the connected subdev. 1026 * the connected subdev.
987 */ 1027 */
988 ret = isp_video_check_format(video, vfh); 1028 ret = isp_video_check_format(video, vfh);
989 if (ret < 0) 1029 if (ret < 0)
990 goto error; 1030 goto err_check_format;
991 1031
992 video->bpl_padding = ret; 1032 video->bpl_padding = ret;
993 video->bpl_value = vfh->format.fmt.pix.bytesperline; 1033 video->bpl_value = vfh->format.fmt.pix.bytesperline;
994 1034
995 /* Find the ISP video node connected at the far end of the pipeline and 1035 ret = isp_video_get_graph_data(video, pipe);
996 * update the pipeline. 1036 if (ret < 0)
997 */ 1037 goto err_check_format;
998 far_end = isp_video_far_end(video);
999 1038
1000 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1039 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1001 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT; 1040 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
1002 pipe->input = far_end; 1041 else
1003 pipe->output = video;
1004 } else {
1005 if (far_end == NULL) {
1006 ret = -EPIPE;
1007 goto error;
1008 }
1009
1010 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT; 1042 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
1011 pipe->input = video;
1012 pipe->output = far_end;
1013 }
1014 1043
1015 if (video->isp->pdata->set_constraints) 1044 ret = isp_video_check_external_subdevs(video, pipe);
1016 video->isp->pdata->set_constraints(video->isp, true); 1045 if (ret < 0)
1017 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); 1046 goto err_check_format;
1018 1047
1019 /* Validate the pipeline and update its state. */ 1048 /* Validate the pipeline and update its state. */
1020 ret = isp_video_validate_pipeline(pipe); 1049 ret = isp_video_validate_pipeline(pipe);
1021 if (ret < 0) 1050 if (ret < 0)
1022 goto error; 1051 goto err_check_format;
1023 1052
1024 pipe->error = false; 1053 pipe->error = false;
1025 1054
@@ -1041,7 +1070,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1041 1070
1042 ret = omap3isp_video_queue_streamon(&vfh->queue); 1071 ret = omap3isp_video_queue_streamon(&vfh->queue);
1043 if (ret < 0) 1072 if (ret < 0)
1044 goto error; 1073 goto err_check_format;
1045 1074
1046 /* In sensor-to-memory mode, the stream can be started synchronously 1075 /* In sensor-to-memory mode, the stream can be started synchronously
1047 * to the stream on command. In memory-to-memory mode, it will be 1076 * to the stream on command. In memory-to-memory mode, it will be
@@ -1051,32 +1080,34 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1051 ret = omap3isp_pipeline_set_stream(pipe, 1080 ret = omap3isp_pipeline_set_stream(pipe,
1052 ISP_PIPELINE_STREAM_CONTINUOUS); 1081 ISP_PIPELINE_STREAM_CONTINUOUS);
1053 if (ret < 0) 1082 if (ret < 0)
1054 goto error; 1083 goto err_set_stream;
1055 spin_lock_irqsave(&video->queue->irqlock, flags); 1084 spin_lock_irqsave(&video->queue->irqlock, flags);
1056 if (list_empty(&video->dmaqueue)) 1085 if (list_empty(&video->dmaqueue))
1057 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN; 1086 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
1058 spin_unlock_irqrestore(&video->queue->irqlock, flags); 1087 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1059 } 1088 }
1060 1089
1061error: 1090 video->streaming = 1;
1062 if (ret < 0) { 1091
1063 omap3isp_video_queue_streamoff(&vfh->queue); 1092 mutex_unlock(&video->stream_lock);
1064 if (video->isp->pdata->set_constraints) 1093 return 0;
1065 video->isp->pdata->set_constraints(video->isp, false);
1066 media_entity_pipeline_stop(&video->video.entity);
1067 /* The DMA queue must be emptied here, otherwise CCDC interrupts
1068 * that will get triggered the next time the CCDC is powered up
1069 * will try to access buffers that might have been freed but
1070 * still present in the DMA queue. This can easily get triggered
1071 * if the above omap3isp_pipeline_set_stream() call fails on a
1072 * system with a free-running sensor.
1073 */
1074 INIT_LIST_HEAD(&video->dmaqueue);
1075 video->queue = NULL;
1076 }
1077 1094
1078 if (!ret) 1095err_set_stream:
1079 video->streaming = 1; 1096 omap3isp_video_queue_streamoff(&vfh->queue);
1097err_check_format:
1098 media_entity_pipeline_stop(&video->video.entity);
1099err_pipeline_start:
1100 if (video->isp->pdata->set_constraints)
1101 video->isp->pdata->set_constraints(video->isp, false);
1102 /* The DMA queue must be emptied here, otherwise CCDC interrupts that
1103 * will get triggered the next time the CCDC is powered up will try to
1104 * access buffers that might have been freed but still present in the
1105 * DMA queue. This can easily get triggered if the above
1106 * omap3isp_pipeline_set_stream() call fails on a system with a
1107 * free-running sensor.
1108 */
1109 INIT_LIST_HEAD(&video->dmaqueue);
1110 video->queue = NULL;
1080 1111
1081 mutex_unlock(&video->stream_lock); 1112 mutex_unlock(&video->stream_lock);
1082 return ret; 1113 return ret;
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
index d91bdb919be0..5acc909500ec 100644
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ b/drivers/media/video/omap3isp/ispvideo.h
@@ -88,6 +88,7 @@ enum isp_pipeline_state {
88/* 88/*
89 * struct isp_pipeline - An ISP hardware pipeline 89 * struct isp_pipeline - An ISP hardware pipeline
90 * @error: A hardware error occurred during capture 90 * @error: A hardware error occurred during capture
91 * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
91 */ 92 */
92struct isp_pipeline { 93struct isp_pipeline {
93 struct media_pipeline pipe; 94 struct media_pipeline pipe;
@@ -96,12 +97,16 @@ struct isp_pipeline {
96 enum isp_pipeline_stream_state stream_state; 97 enum isp_pipeline_stream_state stream_state;
97 struct isp_video *input; 98 struct isp_video *input;
98 struct isp_video *output; 99 struct isp_video *output;
100 u32 entities;
99 unsigned long l3_ick; 101 unsigned long l3_ick;
100 unsigned int max_rate; 102 unsigned int max_rate;
101 atomic_t frame_number; 103 atomic_t frame_number;
102 bool do_propagation; /* of frame number */ 104 bool do_propagation; /* of frame number */
103 bool error; 105 bool error;
104 struct v4l2_fract max_timeperframe; 106 struct v4l2_fract max_timeperframe;
107 struct v4l2_subdev *external;
108 unsigned int external_rate;
109 unsigned int external_bpp;
105}; 110};
106 111
107#define to_isp_pipeline(__e) \ 112#define to_isp_pipeline(__e) \
diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c
index 80e07794ac8e..0bc93313d37a 100644
--- a/drivers/media/video/ov5642.c
+++ b/drivers/media/video/ov5642.c
@@ -1025,8 +1025,6 @@ static int ov5642_probe(struct i2c_client *client,
1025 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT; 1025 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
1026 priv->crop_rect.left = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2; 1026 priv->crop_rect.left = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
1027 priv->crop_rect.top = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2; 1027 priv->crop_rect.top = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
1028 priv->crop_rect.width = OV5642_DEFAULT_WIDTH;
1029 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
1030 priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH; 1028 priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
1031 priv->total_height = BLANKING_MIN_HEIGHT; 1029 priv->total_height = BLANKING_MIN_HEIGHT;
1032 1030
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index e753b5e4d2ce..af2d9086d7e8 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -30,15 +30,19 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33#include <linux/isa.h>
33#include <asm/io.h> 34#include <asm/io.h>
34 35
35#include <linux/videodev2.h> 36#include <linux/videodev2.h>
36#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h> 38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-ctrls.h>
40#include <media/v4l2-fh.h>
41#include <media/v4l2-event.h>
38#include <media/v4l2-device.h> 42#include <media/v4l2-device.h>
39 43
40MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
41MODULE_VERSION("0.0.4"); 45MODULE_VERSION("0.0.5");
42 46
43#define MOTOROLA 1 47#define MOTOROLA 1
44#define PHILIPS2 2 /* SAA7191 */ 48#define PHILIPS2 2 /* SAA7191 */
@@ -55,11 +59,11 @@ struct i2c_info {
55struct pms { 59struct pms {
56 struct v4l2_device v4l2_dev; 60 struct v4l2_device v4l2_dev;
57 struct video_device vdev; 61 struct video_device vdev;
62 struct v4l2_ctrl_handler hdl;
58 int height; 63 int height;
59 int width; 64 int width;
60 int depth; 65 int depth;
61 int input; 66 int input;
62 s32 brightness, saturation, hue, contrast;
63 struct mutex lock; 67 struct mutex lock;
64 int i2c_count; 68 int i2c_count;
65 struct i2c_info i2cinfo[64]; 69 struct i2c_info i2cinfo[64];
@@ -72,8 +76,6 @@ struct pms {
72 void __iomem *mem; 76 void __iomem *mem;
73}; 77};
74 78
75static struct pms pms_card;
76
77/* 79/*
78 * I/O ports and Shared Memory 80 * I/O ports and Shared Memory
79 */ 81 */
@@ -676,8 +678,10 @@ static int pms_querycap(struct file *file, void *priv,
676 678
677 strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver)); 679 strlcpy(vcap->driver, dev->v4l2_dev.name, sizeof(vcap->driver));
678 strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card)); 680 strlcpy(vcap->card, "Mediavision PMS", sizeof(vcap->card));
679 strlcpy(vcap->bus_info, "ISA", sizeof(vcap->bus_info)); 681 snprintf(vcap->bus_info, sizeof(vcap->bus_info),
680 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 682 "ISA:%s", dev->v4l2_dev.name);
683 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
684 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
681 return 0; 685 return 0;
682} 686}
683 687
@@ -716,11 +720,9 @@ static int pms_s_input(struct file *file, void *fh, unsigned int inp)
716 if (inp > 3) 720 if (inp > 3)
717 return -EINVAL; 721 return -EINVAL;
718 722
719 mutex_lock(&dev->lock);
720 dev->input = inp; 723 dev->input = inp;
721 pms_videosource(dev, inp & 1); 724 pms_videosource(dev, inp & 1);
722 pms_vcrinput(dev, inp >> 1); 725 pms_vcrinput(dev, inp >> 1);
723 mutex_unlock(&dev->lock);
724 return 0; 726 return 0;
725} 727}
726 728
@@ -738,7 +740,6 @@ static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
738 int ret = 0; 740 int ret = 0;
739 741
740 dev->std = *std; 742 dev->std = *std;
741 mutex_lock(&dev->lock);
742 if (dev->std & V4L2_STD_NTSC) { 743 if (dev->std & V4L2_STD_NTSC) {
743 pms_framerate(dev, 30); 744 pms_framerate(dev, 30);
744 pms_secamcross(dev, 0); 745 pms_secamcross(dev, 0);
@@ -762,81 +763,31 @@ static int pms_s_std(struct file *file, void *fh, v4l2_std_id *std)
762 pms_format(dev, 0); 763 pms_format(dev, 0);
763 break; 764 break;
764 }*/ 765 }*/
765 mutex_unlock(&dev->lock);
766 return 0;
767}
768
769static int pms_queryctrl(struct file *file, void *priv,
770 struct v4l2_queryctrl *qc)
771{
772 switch (qc->id) {
773 case V4L2_CID_BRIGHTNESS:
774 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 139);
775 case V4L2_CID_CONTRAST:
776 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 70);
777 case V4L2_CID_SATURATION:
778 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 64);
779 case V4L2_CID_HUE:
780 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
781 }
782 return -EINVAL;
783}
784
785static int pms_g_ctrl(struct file *file, void *priv,
786 struct v4l2_control *ctrl)
787{
788 struct pms *dev = video_drvdata(file);
789 int ret = 0;
790
791 switch (ctrl->id) {
792 case V4L2_CID_BRIGHTNESS:
793 ctrl->value = dev->brightness;
794 break;
795 case V4L2_CID_CONTRAST:
796 ctrl->value = dev->contrast;
797 break;
798 case V4L2_CID_SATURATION:
799 ctrl->value = dev->saturation;
800 break;
801 case V4L2_CID_HUE:
802 ctrl->value = dev->hue;
803 break;
804 default:
805 ret = -EINVAL;
806 break;
807 }
808 return ret; 766 return ret;
809} 767}
810 768
811static int pms_s_ctrl(struct file *file, void *priv, 769static int pms_s_ctrl(struct v4l2_ctrl *ctrl)
812 struct v4l2_control *ctrl)
813{ 770{
814 struct pms *dev = video_drvdata(file); 771 struct pms *dev = container_of(ctrl->handler, struct pms, hdl);
815 int ret = 0; 772 int ret = 0;
816 773
817 mutex_lock(&dev->lock);
818 switch (ctrl->id) { 774 switch (ctrl->id) {
819 case V4L2_CID_BRIGHTNESS: 775 case V4L2_CID_BRIGHTNESS:
820 dev->brightness = ctrl->value; 776 pms_brightness(dev, ctrl->val);
821 pms_brightness(dev, dev->brightness);
822 break; 777 break;
823 case V4L2_CID_CONTRAST: 778 case V4L2_CID_CONTRAST:
824 dev->contrast = ctrl->value; 779 pms_contrast(dev, ctrl->val);
825 pms_contrast(dev, dev->contrast);
826 break; 780 break;
827 case V4L2_CID_SATURATION: 781 case V4L2_CID_SATURATION:
828 dev->saturation = ctrl->value; 782 pms_saturation(dev, ctrl->val);
829 pms_saturation(dev, dev->saturation);
830 break; 783 break;
831 case V4L2_CID_HUE: 784 case V4L2_CID_HUE:
832 dev->hue = ctrl->value; 785 pms_hue(dev, ctrl->val);
833 pms_hue(dev, dev->hue);
834 break; 786 break;
835 default: 787 default:
836 ret = -EINVAL; 788 ret = -EINVAL;
837 break; 789 break;
838 } 790 }
839 mutex_unlock(&dev->lock);
840 return ret; 791 return ret;
841} 792}
842 793
@@ -884,13 +835,11 @@ static int pms_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fm
884 835
885 if (ret) 836 if (ret)
886 return ret; 837 return ret;
887 mutex_lock(&dev->lock);
888 dev->width = pix->width; 838 dev->width = pix->width;
889 dev->height = pix->height; 839 dev->height = pix->height;
890 dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16; 840 dev->depth = (pix->pixelformat == V4L2_PIX_FMT_RGB555) ? 15 : 16;
891 pms_resolution(dev, dev->width, dev->height); 841 pms_resolution(dev, dev->width, dev->height);
892 /* Ok we figured out what to use from our wide choice */ 842 /* Ok we figured out what to use from our wide choice */
893 mutex_unlock(&dev->lock);
894 return 0; 843 return 0;
895} 844}
896 845
@@ -901,7 +850,7 @@ static int pms_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc
901 "RGB 5:5:5", V4L2_PIX_FMT_RGB555, 850 "RGB 5:5:5", V4L2_PIX_FMT_RGB555,
902 { 0, 0, 0, 0 } 851 { 0, 0, 0, 0 }
903 }, 852 },
904 { 0, 0, 0, 853 { 1, 0, 0,
905 "RGB 5:6:5", V4L2_PIX_FMT_RGB565, 854 "RGB 5:6:5", V4L2_PIX_FMT_RGB565,
906 { 0, 0, 0, 0 } 855 { 0, 0, 0, 0 }
907 }, 856 },
@@ -922,32 +871,43 @@ static ssize_t pms_read(struct file *file, char __user *buf,
922 struct pms *dev = video_drvdata(file); 871 struct pms *dev = video_drvdata(file);
923 int len; 872 int len;
924 873
925 mutex_lock(&dev->lock);
926 len = pms_capture(dev, buf, (dev->depth == 15), count); 874 len = pms_capture(dev, buf, (dev->depth == 15), count);
927 mutex_unlock(&dev->lock);
928 return len; 875 return len;
929} 876}
930 877
878static unsigned int pms_poll(struct file *file, struct poll_table_struct *wait)
879{
880 struct v4l2_fh *fh = file->private_data;
881 unsigned int res = POLLIN | POLLRDNORM;
882
883 if (v4l2_event_pending(fh))
884 res |= POLLPRI;
885 poll_wait(file, &fh->wait, wait);
886 return res;
887}
888
931static const struct v4l2_file_operations pms_fops = { 889static const struct v4l2_file_operations pms_fops = {
932 .owner = THIS_MODULE, 890 .owner = THIS_MODULE,
891 .open = v4l2_fh_open,
892 .release = v4l2_fh_release,
893 .poll = pms_poll,
933 .unlocked_ioctl = video_ioctl2, 894 .unlocked_ioctl = video_ioctl2,
934 .read = pms_read, 895 .read = pms_read,
935}; 896};
936 897
937static const struct v4l2_ioctl_ops pms_ioctl_ops = { 898static const struct v4l2_ioctl_ops pms_ioctl_ops = {
938 .vidioc_querycap = pms_querycap, 899 .vidioc_querycap = pms_querycap,
939 .vidioc_g_input = pms_g_input, 900 .vidioc_g_input = pms_g_input,
940 .vidioc_s_input = pms_s_input, 901 .vidioc_s_input = pms_s_input,
941 .vidioc_enum_input = pms_enum_input, 902 .vidioc_enum_input = pms_enum_input,
942 .vidioc_g_std = pms_g_std, 903 .vidioc_g_std = pms_g_std,
943 .vidioc_s_std = pms_s_std, 904 .vidioc_s_std = pms_s_std,
944 .vidioc_queryctrl = pms_queryctrl, 905 .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap,
945 .vidioc_g_ctrl = pms_g_ctrl, 906 .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap,
946 .vidioc_s_ctrl = pms_s_ctrl, 907 .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap,
947 .vidioc_enum_fmt_vid_cap = pms_enum_fmt_vid_cap, 908 .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
948 .vidioc_g_fmt_vid_cap = pms_g_fmt_vid_cap, 909 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
949 .vidioc_s_fmt_vid_cap = pms_s_fmt_vid_cap, 910 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
950 .vidioc_try_fmt_vid_cap = pms_try_fmt_vid_cap,
951}; 911};
952 912
953/* 913/*
@@ -956,7 +916,6 @@ static const struct v4l2_ioctl_ops pms_ioctl_ops = {
956 916
957static int init_mediavision(struct pms *dev) 917static int init_mediavision(struct pms *dev)
958{ 918{
959 int id;
960 int idec, decst; 919 int idec, decst;
961 int i; 920 int i;
962 static const unsigned char i2c_defs[] = { 921 static const unsigned char i2c_defs[] = {
@@ -988,7 +947,6 @@ static int init_mediavision(struct pms *dev)
988 outb(dev->io >> 4, 0x9a01); /* Set IO port */ 947 outb(dev->io >> 4, 0x9a01); /* Set IO port */
989 948
990 949
991 id = mvv_read(dev, 3);
992 decst = pms_i2c_stat(dev, 0x43); 950 decst = pms_i2c_stat(dev, 0x43);
993 951
994 if (decst != -1) 952 if (decst != -1)
@@ -1068,76 +1026,125 @@ static int enable;
1068module_param(enable, int, 0); 1026module_param(enable, int, 0);
1069#endif 1027#endif
1070 1028
1071static int __init pms_init(void) 1029static const struct v4l2_ctrl_ops pms_ctrl_ops = {
1030 .s_ctrl = pms_s_ctrl,
1031};
1032
1033static int pms_probe(struct device *pdev, unsigned int card)
1072{ 1034{
1073 struct pms *dev = &pms_card; 1035 struct pms *dev;
1074 struct v4l2_device *v4l2_dev = &dev->v4l2_dev; 1036 struct v4l2_device *v4l2_dev;
1037 struct v4l2_ctrl_handler *hdl;
1075 int res; 1038 int res;
1076 1039
1077 strlcpy(v4l2_dev->name, "pms", sizeof(v4l2_dev->name));
1078
1079 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.03\n");
1080
1081#ifndef MODULE 1040#ifndef MODULE
1082 if (!enable) { 1041 if (!enable) {
1083 v4l2_err(v4l2_dev, 1042 pr_err("PMS: not enabled, use pms.enable=1 to probe\n");
1084 "PMS: not enabled, use pms.enable=1 to probe\n");
1085 return -ENODEV; 1043 return -ENODEV;
1086 } 1044 }
1087#endif 1045#endif
1088 1046
1047 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1048 if (dev == NULL)
1049 return -ENOMEM;
1050
1089 dev->decoder = PHILIPS2; 1051 dev->decoder = PHILIPS2;
1090 dev->io = io_port; 1052 dev->io = io_port;
1091 dev->data = io_port + 1; 1053 dev->data = io_port + 1;
1054 v4l2_dev = &dev->v4l2_dev;
1055 hdl = &dev->hdl;
1092 1056
1093 if (init_mediavision(dev)) { 1057 res = v4l2_device_register(pdev, v4l2_dev);
1058 if (res < 0) {
1059 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1060 goto free_dev;
1061 }
1062 v4l2_info(v4l2_dev, "Mediavision Pro Movie Studio driver 0.05\n");
1063
1064 res = init_mediavision(dev);
1065 if (res) {
1094 v4l2_err(v4l2_dev, "Board not found.\n"); 1066 v4l2_err(v4l2_dev, "Board not found.\n");
1095 return -ENODEV; 1067 goto free_io;
1096 } 1068 }
1097 1069
1098 res = v4l2_device_register(NULL, v4l2_dev); 1070 v4l2_ctrl_handler_init(hdl, 4);
1099 if (res < 0) { 1071 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1100 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 1072 V4L2_CID_BRIGHTNESS, 0, 255, 1, 139);
1101 return res; 1073 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1074 V4L2_CID_CONTRAST, 0, 255, 1, 70);
1075 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1076 V4L2_CID_SATURATION, 0, 255, 1, 64);
1077 v4l2_ctrl_new_std(hdl, &pms_ctrl_ops,
1078 V4L2_CID_HUE, 0, 255, 1, 0);
1079 if (hdl->error) {
1080 res = hdl->error;
1081 goto free_hdl;
1102 } 1082 }
1103 1083
1084 mutex_init(&dev->lock);
1104 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); 1085 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
1105 dev->vdev.v4l2_dev = v4l2_dev; 1086 dev->vdev.v4l2_dev = v4l2_dev;
1087 dev->vdev.ctrl_handler = hdl;
1106 dev->vdev.fops = &pms_fops; 1088 dev->vdev.fops = &pms_fops;
1107 dev->vdev.ioctl_ops = &pms_ioctl_ops; 1089 dev->vdev.ioctl_ops = &pms_ioctl_ops;
1108 dev->vdev.release = video_device_release_empty; 1090 dev->vdev.release = video_device_release_empty;
1091 dev->vdev.lock = &dev->lock;
1092 dev->vdev.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1093 set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
1109 video_set_drvdata(&dev->vdev, dev); 1094 video_set_drvdata(&dev->vdev, dev);
1110 mutex_init(&dev->lock);
1111 dev->std = V4L2_STD_NTSC_M; 1095 dev->std = V4L2_STD_NTSC_M;
1112 dev->height = 240; 1096 dev->height = 240;
1113 dev->width = 320; 1097 dev->width = 320;
1114 dev->depth = 15; 1098 dev->depth = 16;
1115 dev->brightness = 139;
1116 dev->contrast = 70;
1117 dev->hue = 0;
1118 dev->saturation = 64;
1119 pms_swsense(dev, 75); 1099 pms_swsense(dev, 75);
1120 pms_resolution(dev, 320, 240); 1100 pms_resolution(dev, 320, 240);
1121 pms_videosource(dev, 0); 1101 pms_videosource(dev, 0);
1122 pms_vcrinput(dev, 0); 1102 pms_vcrinput(dev, 0);
1123 if (video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { 1103 v4l2_ctrl_handler_setup(hdl);
1124 v4l2_device_unregister(&dev->v4l2_dev); 1104 res = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);
1125 release_region(dev->io, 3); 1105 if (res >= 0)
1126 release_region(0x9a01, 1); 1106 return 0;
1127 iounmap(dev->mem); 1107
1128 return -EINVAL; 1108free_hdl:
1129 } 1109 v4l2_ctrl_handler_free(hdl);
1130 return 0; 1110 v4l2_device_unregister(&dev->v4l2_dev);
1111free_io:
1112 release_region(dev->io, 3);
1113 release_region(0x9a01, 1);
1114 iounmap(dev->mem);
1115free_dev:
1116 kfree(dev);
1117 return res;
1131} 1118}
1132 1119
1133static void __exit pms_exit(void) 1120static int pms_remove(struct device *pdev, unsigned int card)
1134{ 1121{
1135 struct pms *dev = &pms_card; 1122 struct pms *dev = dev_get_drvdata(pdev);
1136 1123
1137 video_unregister_device(&dev->vdev); 1124 video_unregister_device(&dev->vdev);
1125 v4l2_ctrl_handler_free(&dev->hdl);
1138 release_region(dev->io, 3); 1126 release_region(dev->io, 3);
1139 release_region(0x9a01, 1); 1127 release_region(0x9a01, 1);
1140 iounmap(dev->mem); 1128 iounmap(dev->mem);
1129 return 0;
1130}
1131
1132static struct isa_driver pms_driver = {
1133 .probe = pms_probe,
1134 .remove = pms_remove,
1135 .driver = {
1136 .name = "pms",
1137 },
1138};
1139
1140static int __init pms_init(void)
1141{
1142 return isa_register_driver(&pms_driver, 1);
1143}
1144
1145static void __exit pms_exit(void)
1146{
1147 isa_unregister_driver(&pms_driver);
1141} 1148}
1142 1149
1143module_init(pms_init); 1150module_init(pms_init);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 305e6aaa844a..036952f2a3cb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -317,18 +317,16 @@ struct pvr2_hdw {
317 v4l2_std_id std_mask_eeprom; // Hardware supported selections 317 v4l2_std_id std_mask_eeprom; // Hardware supported selections
318 v4l2_std_id std_mask_avail; // Which standards we may select from 318 v4l2_std_id std_mask_avail; // Which standards we may select from
319 v4l2_std_id std_mask_cur; // Currently selected standard(s) 319 v4l2_std_id std_mask_cur; // Currently selected standard(s)
320 unsigned int std_enum_cnt; // # of enumerated standards
321 int std_enum_cur; // selected standard enumeration value 320 int std_enum_cur; // selected standard enumeration value
322 int std_dirty; // True if std_mask_cur has changed 321 int std_dirty; // True if std_mask_cur has changed
323 struct pvr2_ctl_info std_info_enum; 322 struct pvr2_ctl_info std_info_enum;
324 struct pvr2_ctl_info std_info_avail; 323 struct pvr2_ctl_info std_info_avail;
325 struct pvr2_ctl_info std_info_cur; 324 struct pvr2_ctl_info std_info_cur;
326 struct v4l2_standard *std_defs; 325 struct pvr2_ctl_info std_info_detect;
327 const char **std_enum_names;
328 326
329 // Generated string names, one per actual V4L2 standard 327 // Generated string names, one per actual V4L2 standard
330 const char *std_mask_ptrs[32]; 328 const char *std_mask_ptrs[32];
331 char std_mask_names[32][10]; 329 char std_mask_names[32][16];
332 330
333 int unit_number; /* ID for driver instance */ 331 int unit_number; /* ID for driver instance */
334 unsigned long serial_number; /* ID for hardware itself */ 332 unsigned long serial_number; /* ID for hardware itself */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index ebc2c7e39233..fb828ba1dbbe 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -334,8 +334,6 @@ static void pvr2_hdw_state_log_state(struct pvr2_hdw *);
334static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); 334static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
335static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw); 335static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw);
336static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); 336static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
337static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
338static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
339static void pvr2_hdw_quiescent_timeout(unsigned long); 337static void pvr2_hdw_quiescent_timeout(unsigned long);
340static void pvr2_hdw_decoder_stabilization_timeout(unsigned long); 338static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
341static void pvr2_hdw_encoder_wait_timeout(unsigned long); 339static void pvr2_hdw_encoder_wait_timeout(unsigned long);
@@ -346,7 +344,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
346 void *write_data,unsigned int write_len, 344 void *write_data,unsigned int write_len,
347 void *read_data,unsigned int read_len); 345 void *read_data,unsigned int read_len);
348static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw); 346static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw);
349 347static v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw);
350 348
351static void trace_stbit(const char *name,int val) 349static void trace_stbit(const char *name,int val)
352{ 350{
@@ -840,6 +838,12 @@ static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
840 return 0; 838 return 0;
841} 839}
842 840
841static int ctrl_stddetect_get(struct pvr2_ctrl *cptr, int *vp)
842{
843 *vp = pvr2_hdw_get_detected_std(cptr->hdw);
844 return 0;
845}
846
843static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp) 847static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
844{ 848{
845 *vp = cptr->hdw->std_mask_avail; 849 *vp = cptr->hdw->std_mask_avail;
@@ -854,8 +858,7 @@ static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
854 ns = (ns & ~m) | (v & m); 858 ns = (ns & ~m) | (v & m);
855 if (ns == hdw->std_mask_avail) return 0; 859 if (ns == hdw->std_mask_avail) return 0;
856 hdw->std_mask_avail = ns; 860 hdw->std_mask_avail = ns;
857 pvr2_hdw_internal_set_std_avail(hdw); 861 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
858 pvr2_hdw_internal_find_stdenum(hdw);
859 return 0; 862 return 0;
860} 863}
861 864
@@ -895,7 +898,6 @@ static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
895 if (ns == hdw->std_mask_cur) return 0; 898 if (ns == hdw->std_mask_cur) return 0;
896 hdw->std_mask_cur = ns; 899 hdw->std_mask_cur = ns;
897 hdw->std_dirty = !0; 900 hdw->std_dirty = !0;
898 pvr2_hdw_internal_find_stdenum(hdw);
899 return 0; 901 return 0;
900} 902}
901 903
@@ -941,40 +943,6 @@ static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
941} 943}
942 944
943 945
944static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
945{
946 struct pvr2_hdw *hdw = cptr->hdw;
947 if (v < 0) return -EINVAL;
948 if (v > hdw->std_enum_cnt) return -EINVAL;
949 hdw->std_enum_cur = v;
950 if (!v) return 0;
951 v--;
952 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
953 hdw->std_mask_cur = hdw->std_defs[v].id;
954 hdw->std_dirty = !0;
955 return 0;
956}
957
958
959static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
960{
961 *vp = cptr->hdw->std_enum_cur;
962 return 0;
963}
964
965
966static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
967{
968 return cptr->hdw->std_dirty != 0;
969}
970
971
972static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
973{
974 cptr->hdw->std_dirty = 0;
975}
976
977
978#define DEFINT(vmin,vmax) \ 946#define DEFINT(vmin,vmax) \
979 .type = pvr2_ctl_int, \ 947 .type = pvr2_ctl_int, \
980 .def.type_int.min_value = vmin, \ 948 .def.type_int.min_value = vmin, \
@@ -1293,15 +1261,14 @@ static const struct pvr2_ctl_info control_defs[] = {
1293 .sym_to_val = ctrl_std_sym_to_val, 1261 .sym_to_val = ctrl_std_sym_to_val,
1294 .type = pvr2_ctl_bitmask, 1262 .type = pvr2_ctl_bitmask,
1295 },{ 1263 },{
1296 .desc = "Video Standard Name", 1264 .desc = "Video Standards Detected Mask",
1297 .name = "video_standard", 1265 .name = "video_standard_mask_detected",
1298 .internal_id = PVR2_CID_STDENUM, 1266 .internal_id = PVR2_CID_STDDETECT,
1299 .skip_init = !0, 1267 .skip_init = !0,
1300 .get_value = ctrl_stdenumcur_get, 1268 .get_value = ctrl_stddetect_get,
1301 .set_value = ctrl_stdenumcur_set, 1269 .val_to_sym = ctrl_std_val_to_sym,
1302 .is_dirty = ctrl_stdenumcur_is_dirty, 1270 .sym_to_val = ctrl_std_sym_to_val,
1303 .clear_dirty = ctrl_stdenumcur_clear_dirty, 1271 .type = pvr2_ctl_bitmask,
1304 .type = pvr2_ctl_enum,
1305 } 1272 }
1306}; 1273};
1307 1274
@@ -1936,7 +1903,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1936 hdw->std_mask_avail |= std2; 1903 hdw->std_mask_avail |= std2;
1937 } 1904 }
1938 1905
1939 pvr2_hdw_internal_set_std_avail(hdw); 1906 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
1940 1907
1941 if (std1) { 1908 if (std1) {
1942 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); 1909 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
@@ -1945,7 +1912,6 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1945 bcnt,buf); 1912 bcnt,buf);
1946 hdw->std_mask_cur = std1; 1913 hdw->std_mask_cur = std1;
1947 hdw->std_dirty = !0; 1914 hdw->std_dirty = !0;
1948 pvr2_hdw_internal_find_stdenum(hdw);
1949 return; 1915 return;
1950 } 1916 }
1951 if (std3) { 1917 if (std3) {
@@ -1955,7 +1921,6 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1955 " (determined by device type): %.*s",bcnt,buf); 1921 " (determined by device type): %.*s",bcnt,buf);
1956 hdw->std_mask_cur = std3; 1922 hdw->std_mask_cur = std3;
1957 hdw->std_dirty = !0; 1923 hdw->std_dirty = !0;
1958 pvr2_hdw_internal_find_stdenum(hdw);
1959 return; 1924 return;
1960 } 1925 }
1961 1926
@@ -1975,24 +1940,10 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1975 bcnt,buf); 1940 bcnt,buf);
1976 hdw->std_mask_cur = std_eeprom_maps[idx].std; 1941 hdw->std_mask_cur = std_eeprom_maps[idx].std;
1977 hdw->std_dirty = !0; 1942 hdw->std_dirty = !0;
1978 pvr2_hdw_internal_find_stdenum(hdw);
1979 return; 1943 return;
1980 } 1944 }
1981 } 1945 }
1982 1946
1983 if (hdw->std_enum_cnt > 1) {
1984 // Autoselect the first listed standard
1985 hdw->std_enum_cur = 1;
1986 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1987 hdw->std_dirty = !0;
1988 pvr2_trace(PVR2_TRACE_STD,
1989 "Initial video standard auto-selected to %s",
1990 hdw->std_defs[hdw->std_enum_cur-1].name);
1991 return;
1992 }
1993
1994 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1995 "Unable to select a viable initial video standard");
1996} 1947}
1997 1948
1998 1949
@@ -2594,14 +2545,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2594 cptr->info = ciptr; 2545 cptr->info = ciptr;
2595 } 2546 }
2596 2547
2597 // Initialize video standard enum dynamic control
2598 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2599 if (cptr) {
2600 memcpy(&hdw->std_info_enum,cptr->info,
2601 sizeof(hdw->std_info_enum));
2602 cptr->info = &hdw->std_info_enum;
2603
2604 }
2605 // Initialize control data regarding video standard masks 2548 // Initialize control data regarding video standard masks
2606 valid_std_mask = pvr2_std_get_usable(); 2549 valid_std_mask = pvr2_std_get_usable();
2607 for (idx = 0; idx < 32; idx++) { 2550 for (idx = 0; idx < 32; idx++) {
@@ -2629,7 +2572,17 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2629 cptr->info = &hdw->std_info_cur; 2572 cptr->info = &hdw->std_info_cur;
2630 hdw->std_info_cur.def.type_bitmask.bit_names = 2573 hdw->std_info_cur.def.type_bitmask.bit_names =
2631 hdw->std_mask_ptrs; 2574 hdw->std_mask_ptrs;
2632 hdw->std_info_avail.def.type_bitmask.valid_bits = 2575 hdw->std_info_cur.def.type_bitmask.valid_bits =
2576 valid_std_mask;
2577 }
2578 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDDETECT);
2579 if (cptr) {
2580 memcpy(&hdw->std_info_detect,cptr->info,
2581 sizeof(hdw->std_info_detect));
2582 cptr->info = &hdw->std_info_detect;
2583 hdw->std_info_detect.def.type_bitmask.bit_names =
2584 hdw->std_mask_ptrs;
2585 hdw->std_info_detect.def.type_bitmask.valid_bits =
2633 valid_std_mask; 2586 valid_std_mask;
2634 } 2587 }
2635 2588
@@ -2711,8 +2664,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2711 kfree(hdw->ctl_write_buffer); 2664 kfree(hdw->ctl_write_buffer);
2712 kfree(hdw->controls); 2665 kfree(hdw->controls);
2713 kfree(hdw->mpeg_ctrl_info); 2666 kfree(hdw->mpeg_ctrl_info);
2714 kfree(hdw->std_defs);
2715 kfree(hdw->std_enum_names);
2716 kfree(hdw); 2667 kfree(hdw);
2717 } 2668 }
2718 return NULL; 2669 return NULL;
@@ -2788,8 +2739,6 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2788 } while (0); mutex_unlock(&pvr2_unit_mtx); 2739 } while (0); mutex_unlock(&pvr2_unit_mtx);
2789 kfree(hdw->controls); 2740 kfree(hdw->controls);
2790 kfree(hdw->mpeg_ctrl_info); 2741 kfree(hdw->mpeg_ctrl_info);
2791 kfree(hdw->std_defs);
2792 kfree(hdw->std_enum_names);
2793 kfree(hdw); 2742 kfree(hdw);
2794} 2743}
2795 2744
@@ -2812,86 +2761,6 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2812} 2761}
2813 2762
2814 2763
2815// Attempt to autoselect an appropriate value for std_enum_cur given
2816// whatever is currently in std_mask_cur
2817static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
2818{
2819 unsigned int idx;
2820 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2821 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2822 hdw->std_enum_cur = idx;
2823 return;
2824 }
2825 }
2826 hdw->std_enum_cur = 0;
2827}
2828
2829
2830// Calculate correct set of enumerated standards based on currently known
2831// set of available standards bits.
2832static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
2833{
2834 struct v4l2_standard *newstd;
2835 unsigned int std_cnt;
2836 unsigned int idx;
2837
2838 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2839
2840 if (hdw->std_defs) {
2841 kfree(hdw->std_defs);
2842 hdw->std_defs = NULL;
2843 }
2844 hdw->std_enum_cnt = 0;
2845 if (hdw->std_enum_names) {
2846 kfree(hdw->std_enum_names);
2847 hdw->std_enum_names = NULL;
2848 }
2849
2850 if (!std_cnt) {
2851 pvr2_trace(
2852 PVR2_TRACE_ERROR_LEGS,
2853 "WARNING: Failed to identify any viable standards");
2854 }
2855
2856 /* Set up the dynamic control for this standard */
2857 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2858 if (hdw->std_enum_names) {
2859 hdw->std_enum_names[0] = "none";
2860 for (idx = 0; idx < std_cnt; idx++)
2861 hdw->std_enum_names[idx+1] = newstd[idx].name;
2862 hdw->std_info_enum.def.type_enum.value_names =
2863 hdw->std_enum_names;
2864 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2865 } else {
2866 pvr2_trace(
2867 PVR2_TRACE_ERROR_LEGS,
2868 "WARNING: Failed to alloc memory for names");
2869 hdw->std_info_enum.def.type_enum.value_names = NULL;
2870 hdw->std_info_enum.def.type_enum.count = 0;
2871 }
2872 hdw->std_defs = newstd;
2873 hdw->std_enum_cnt = std_cnt+1;
2874 hdw->std_enum_cur = 0;
2875 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2876}
2877
2878
2879int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2880 struct v4l2_standard *std,
2881 unsigned int idx)
2882{
2883 int ret = -EINVAL;
2884 if (!idx) return ret;
2885 LOCK_TAKE(hdw->big_lock); do {
2886 if (idx >= hdw->std_enum_cnt) break;
2887 idx--;
2888 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2889 ret = 0;
2890 } while (0); LOCK_GIVE(hdw->big_lock);
2891 return ret;
2892}
2893
2894
2895/* Get the number of defined controls */ 2764/* Get the number of defined controls */
2896unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw) 2765unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2897{ 2766{
@@ -2995,11 +2864,13 @@ static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
2995 pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \ 2864 pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
2996 } 2865 }
2997 2866
2998int pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw, v4l2_std_id *std) 2867v4l2_std_id pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw)
2999{ 2868{
2869 v4l2_std_id std;
2870 std = (v4l2_std_id)hdw->std_mask_avail;
3000 v4l2_device_call_all(&hdw->v4l2_dev, 0, 2871 v4l2_device_call_all(&hdw->v4l2_dev, 0,
3001 video, querystd, std); 2872 video, querystd, &std);
3002 return 0; 2873 return std;
3003} 2874}
3004 2875
3005/* Execute whatever commands are required to update the state of all the 2876/* Execute whatever commands are required to update the state of all the
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 66546580b17d..8060fc666eeb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -28,7 +28,6 @@
28 28
29/* Private internal control ids, look these up with 29/* Private internal control ids, look these up with
30 pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ 30 pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */
31#define PVR2_CID_STDENUM 1
32#define PVR2_CID_STDCUR 2 31#define PVR2_CID_STDCUR 2
33#define PVR2_CID_STDAVAIL 3 32#define PVR2_CID_STDAVAIL 3
34#define PVR2_CID_INPUT 4 33#define PVR2_CID_INPUT 4
@@ -46,6 +45,7 @@
46#define PVR2_CID_CROPCAPBT 16 45#define PVR2_CID_CROPCAPBT 16
47#define PVR2_CID_CROPCAPBW 17 46#define PVR2_CID_CROPCAPBW 17
48#define PVR2_CID_CROPCAPBH 18 47#define PVR2_CID_CROPCAPBH 18
48#define PVR2_CID_STDDETECT 19
49 49
50/* Legal values for the INPUT state variable */ 50/* Legal values for the INPUT state variable */
51#define PVR2_CVAL_INPUT_TV 0 51#define PVR2_CVAL_INPUT_TV 0
@@ -210,13 +210,6 @@ int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config);
210/* Get handle to video output stream */ 210/* Get handle to video output stream */
211struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); 211struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *);
212 212
213/* Emit a video standard struct */
214int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std,
215 unsigned int idx);
216
217/* Get the detected video standard */
218int pvr2_hdw_get_detected_std(struct pvr2_hdw *hdw, v4l2_std_id *std);
219
220/* Enable / disable retrieval of CPU firmware or prom contents. This must 213/* Enable / disable retrieval of CPU firmware or prom contents. This must
221 be enabled before pvr2_hdw_cpufw_get() will function. Note that doing 214 be enabled before pvr2_hdw_cpufw_get() will function. Note that doing
222 this may prevent the device from running (and leaving this mode may 215 this may prevent the device from running (and leaving this mode may
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index e1111d968a3d..7bddfaeeafc3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -107,7 +107,6 @@ static struct v4l2_fmtdesc pvr_fmtdesc [] = {
107 // This should really be V4L2_PIX_FMT_MPEG, but xawtv 107 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
108 // breaks when I do that. 108 // breaks when I do that.
109 .pixelformat = 0, // V4L2_PIX_FMT_MPEG, 109 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
110 .reserved = { 0, 0, 0, 0 }
111 } 110 }
112}; 111};
113 112
@@ -145,740 +144,739 @@ static struct v4l2_format pvr_format [] = {
145 .start = { 0, 0 }, 144 .start = { 0, 0 },
146 .count = { 0, 0 }, 145 .count = { 0, 0 },
147 .flags = 0, 146 .flags = 0,
148 .reserved = { 0, 0 }
149 } 147 }
150 } 148 }
151 } 149 }
152}; 150};
153 151
154 152
153
155/* 154/*
156 * pvr_ioctl() 155 * This is part of Video 4 Linux API. These procedures handle ioctl() calls.
157 *
158 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
159 *
160 */ 156 */
161static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) 157static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
162{ 158{
163 struct pvr2_v4l2_fh *fh = file->private_data; 159 struct pvr2_v4l2_fh *fh = file->private_data;
164 struct pvr2_v4l2 *vp = fh->vhead;
165 struct pvr2_v4l2_dev *pdi = fh->pdi;
166 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; 160 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
167 long ret = -EINVAL;
168 161
169 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { 162 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
170 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); 163 strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
171 } 164 sizeof(cap->bus_info));
165 strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
166 return 0;
167}
172 168
173 if (!pvr2_hdw_dev_ok(hdw)) { 169static int pvr2_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
174 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 170{
175 "ioctl failed - bad or no context"); 171 struct pvr2_v4l2_fh *fh = file->private_data;
176 return -EFAULT; 172 struct pvr2_v4l2 *vp = fh->vhead;
177 }
178 173
179 /* check priority */ 174 *p = v4l2_prio_max(&vp->prio);
180 switch (cmd) { 175 return 0;
181 case VIDIOC_S_CTRL: 176}
182 case VIDIOC_S_STD:
183 case VIDIOC_S_INPUT:
184 case VIDIOC_S_TUNER:
185 case VIDIOC_S_FREQUENCY:
186 ret = v4l2_prio_check(&vp->prio, fh->prio);
187 if (ret)
188 return ret;
189 }
190 177
191 switch (cmd) { 178static int pvr2_s_priority(struct file *file, void *priv, enum v4l2_priority prio)
192 case VIDIOC_QUERYCAP: 179{
193 { 180 struct pvr2_v4l2_fh *fh = file->private_data;
194 struct v4l2_capability *cap = arg; 181 struct pvr2_v4l2 *vp = fh->vhead;
195 182
196 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); 183 return v4l2_prio_change(&vp->prio, &fh->prio, prio);
197 strlcpy(cap->bus_info,pvr2_hdw_get_bus_info(hdw), 184}
198 sizeof(cap->bus_info));
199 strlcpy(cap->card,pvr2_hdw_get_desc(hdw),sizeof(cap->card));
200 185
201 ret = 0; 186static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
202 break; 187{
203 } 188 struct pvr2_v4l2_fh *fh = file->private_data;
189 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
190 int val = 0;
191 int ret;
204 192
205 case VIDIOC_G_PRIORITY: 193 ret = pvr2_ctrl_get_value(
206 { 194 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), &val);
207 enum v4l2_priority *p = arg; 195 *std = val;
196 return ret;
197}
208 198
209 *p = v4l2_prio_max(&vp->prio); 199int pvr2_s_std(struct file *file, void *priv, v4l2_std_id *std)
210 ret = 0; 200{
211 break; 201 struct pvr2_v4l2_fh *fh = file->private_data;
212 } 202 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
213 203
214 case VIDIOC_S_PRIORITY: 204 return pvr2_ctrl_set_value(
215 { 205 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), *std);
216 enum v4l2_priority *prio = arg; 206}
217 207
218 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio); 208static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
219 break; 209{
220 } 210 struct pvr2_v4l2_fh *fh = file->private_data;
211 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
212 int val = 0;
213 int ret;
221 214
222 case VIDIOC_ENUMSTD: 215 ret = pvr2_ctrl_get_value(
223 { 216 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDDETECT), &val);
224 struct v4l2_standard *vs = (struct v4l2_standard *)arg; 217 *std = val;
225 int idx = vs->index; 218 return ret;
226 ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1); 219}
227 break;
228 }
229 220
230 case VIDIOC_QUERYSTD: 221static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
231 { 222{
232 v4l2_std_id *std = arg; 223 struct pvr2_v4l2_fh *fh = file->private_data;
233 *std = V4L2_STD_ALL; 224 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
234 ret = pvr2_hdw_get_detected_std(hdw, std); 225 struct pvr2_ctrl *cptr;
235 break; 226 struct v4l2_input tmp;
236 } 227 unsigned int cnt;
228 int val;
229 int ret;
237 230
238 case VIDIOC_G_STD: 231 cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
239 { 232
240 int val = 0; 233 memset(&tmp, 0, sizeof(tmp));
241 ret = pvr2_ctrl_get_value( 234 tmp.index = vi->index;
242 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val); 235 ret = 0;
243 *(v4l2_std_id *)arg = val; 236 if (vi->index >= fh->input_cnt)
237 return -EINVAL;
238 val = fh->input_map[vi->index];
239 switch (val) {
240 case PVR2_CVAL_INPUT_TV:
241 case PVR2_CVAL_INPUT_DTV:
242 case PVR2_CVAL_INPUT_RADIO:
243 tmp.type = V4L2_INPUT_TYPE_TUNER;
244 break; 244 break;
245 } 245 case PVR2_CVAL_INPUT_SVIDEO:
246 246 case PVR2_CVAL_INPUT_COMPOSITE:
247 case VIDIOC_S_STD: 247 tmp.type = V4L2_INPUT_TYPE_CAMERA;
248 {
249 ret = pvr2_ctrl_set_value(
250 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
251 *(v4l2_std_id *)arg);
252 break; 248 break;
249 default:
250 return -EINVAL;
253 } 251 }
254 252
255 case VIDIOC_ENUMINPUT: 253 cnt = 0;
256 { 254 pvr2_ctrl_get_valname(cptr, val,
257 struct pvr2_ctrl *cptr; 255 tmp.name, sizeof(tmp.name) - 1, &cnt);
258 struct v4l2_input *vi = (struct v4l2_input *)arg; 256 tmp.name[cnt] = 0;
259 struct v4l2_input tmp;
260 unsigned int cnt;
261 int val;
262 257
263 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); 258 /* Don't bother with audioset, since this driver currently
259 always switches the audio whenever the video is
260 switched. */
264 261
265 memset(&tmp,0,sizeof(tmp)); 262 /* Handling std is a tougher problem. It doesn't make
266 tmp.index = vi->index; 263 sense in cases where a device might be multi-standard.
267 ret = 0; 264 We could just copy out the current value for the
268 if (vi->index >= fh->input_cnt) { 265 standard, but it can change over time. For now just
269 ret = -EINVAL; 266 leave it zero. */
270 break; 267 *vi = tmp;
271 } 268 return 0;
272 val = fh->input_map[vi->index]; 269}
273 switch (val) {
274 case PVR2_CVAL_INPUT_TV:
275 case PVR2_CVAL_INPUT_DTV:
276 case PVR2_CVAL_INPUT_RADIO:
277 tmp.type = V4L2_INPUT_TYPE_TUNER;
278 break;
279 case PVR2_CVAL_INPUT_SVIDEO:
280 case PVR2_CVAL_INPUT_COMPOSITE:
281 tmp.type = V4L2_INPUT_TYPE_CAMERA;
282 break;
283 default:
284 ret = -EINVAL;
285 break;
286 }
287 if (ret < 0) break;
288
289 cnt = 0;
290 pvr2_ctrl_get_valname(cptr,val,
291 tmp.name,sizeof(tmp.name)-1,&cnt);
292 tmp.name[cnt] = 0;
293
294 /* Don't bother with audioset, since this driver currently
295 always switches the audio whenever the video is
296 switched. */
297
298 /* Handling std is a tougher problem. It doesn't make
299 sense in cases where a device might be multi-standard.
300 We could just copy out the current value for the
301 standard, but it can change over time. For now just
302 leave it zero. */
303
304 memcpy(vi, &tmp, sizeof(tmp));
305
306 ret = 0;
307 break;
308 }
309 270
310 case VIDIOC_G_INPUT: 271static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
311 { 272{
312 unsigned int idx; 273 struct pvr2_v4l2_fh *fh = file->private_data;
313 struct pvr2_ctrl *cptr; 274 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
314 struct v4l2_input *vi = (struct v4l2_input *)arg; 275 unsigned int idx;
315 int val; 276 struct pvr2_ctrl *cptr;
316 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); 277 int val;
317 val = 0; 278 int ret;
318 ret = pvr2_ctrl_get_value(cptr,&val);
319 vi->index = 0;
320 for (idx = 0; idx < fh->input_cnt; idx++) {
321 if (fh->input_map[idx] == val) {
322 vi->index = idx;
323 break;
324 }
325 }
326 break;
327 }
328 279
329 case VIDIOC_S_INPUT: 280 cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
330 { 281 val = 0;
331 struct v4l2_input *vi = (struct v4l2_input *)arg; 282 ret = pvr2_ctrl_get_value(cptr, &val);
332 if (vi->index >= fh->input_cnt) { 283 *i = 0;
333 ret = -ERANGE; 284 for (idx = 0; idx < fh->input_cnt; idx++) {
285 if (fh->input_map[idx] == val) {
286 *i = idx;
334 break; 287 break;
335 } 288 }
336 ret = pvr2_ctrl_set_value(
337 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
338 fh->input_map[vi->index]);
339 break;
340 } 289 }
290 return ret;
291}
341 292
342 case VIDIOC_ENUMAUDIO: 293static int pvr2_s_input(struct file *file, void *priv, unsigned int inp)
343 { 294{
344 /* pkt: FIXME: We are returning one "fake" input here 295 struct pvr2_v4l2_fh *fh = file->private_data;
345 which could very well be called "whatever_we_like". 296 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
346 This is for apps that want to see an audio input
347 just to feel comfortable, as well as to test if
348 it can do stereo or sth. There is actually no guarantee
349 that the actual audio input cannot change behind the app's
350 back, but most applications should not mind that either.
351
352 Hopefully, mplayer people will work with us on this (this
353 whole mess is to support mplayer pvr://), or Hans will come
354 up with a more standard way to say "we have inputs but we
355 don 't want you to change them independent of video" which
356 will sort this mess.
357 */
358 struct v4l2_audio *vin = arg;
359 ret = -EINVAL;
360 if (vin->index > 0) break;
361 strncpy(vin->name, "PVRUSB2 Audio",14);
362 vin->capability = V4L2_AUDCAP_STEREO;
363 ret = 0;
364 break;
365 break;
366 }
367 297
368 case VIDIOC_G_AUDIO: 298 if (inp >= fh->input_cnt)
369 { 299 return -EINVAL;
370 /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */ 300 return pvr2_ctrl_set_value(
371 struct v4l2_audio *vin = arg; 301 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
372 memset(vin,0,sizeof(*vin)); 302 fh->input_map[inp]);
373 vin->index = 0; 303}
374 strncpy(vin->name, "PVRUSB2 Audio",14);
375 vin->capability = V4L2_AUDCAP_STEREO;
376 ret = 0;
377 break;
378 }
379 304
380 case VIDIOC_G_TUNER: 305static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
381 { 306{
382 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 307 /* pkt: FIXME: We are returning one "fake" input here
308 which could very well be called "whatever_we_like".
309 This is for apps that want to see an audio input
310 just to feel comfortable, as well as to test if
311 it can do stereo or sth. There is actually no guarantee
312 that the actual audio input cannot change behind the app's
313 back, but most applications should not mind that either.
314
315 Hopefully, mplayer people will work with us on this (this
316 whole mess is to support mplayer pvr://), or Hans will come
317 up with a more standard way to say "we have inputs but we
318 don 't want you to change them independent of video" which
319 will sort this mess.
320 */
321
322 if (vin->index > 0)
323 return -EINVAL;
324 strncpy(vin->name, "PVRUSB2 Audio", 14);
325 vin->capability = V4L2_AUDCAP_STEREO;
326 return 0;
327}
383 328
384 if (vt->index != 0) break; /* Only answer for the 1st tuner */ 329static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
330{
331 /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
332 vin->index = 0;
333 strncpy(vin->name, "PVRUSB2 Audio", 14);
334 vin->capability = V4L2_AUDCAP_STEREO;
335 return 0;
336}
385 337
386 pvr2_hdw_execute_tuner_poll(hdw); 338static int pvr2_s_audio(struct file *file, void *priv, struct v4l2_audio *vout)
387 ret = pvr2_hdw_get_tuner_status(hdw,vt); 339{
388 break; 340 if (vout->index)
389 } 341 return -EINVAL;
342 return 0;
343}
390 344
391 case VIDIOC_S_TUNER: 345static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
392 { 346{
393 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; 347 struct pvr2_v4l2_fh *fh = file->private_data;
348 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
394 349
395 if (vt->index != 0) 350 if (vt->index != 0)
396 break; 351 return -EINVAL; /* Only answer for the 1st tuner */
397 352
398 ret = pvr2_ctrl_set_value( 353 pvr2_hdw_execute_tuner_poll(hdw);
399 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), 354 return pvr2_hdw_get_tuner_status(hdw, vt);
355}
356
357static int pvr2_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
358{
359 struct pvr2_v4l2_fh *fh = file->private_data;
360 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
361
362 if (vt->index != 0)
363 return -EINVAL;
364
365 return pvr2_ctrl_set_value(
366 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_AUDIOMODE),
400 vt->audmode); 367 vt->audmode);
401 break; 368}
402 }
403 369
404 case VIDIOC_S_FREQUENCY: 370int pvr2_s_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
405 { 371{
406 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; 372 struct pvr2_v4l2_fh *fh = file->private_data;
407 unsigned long fv; 373 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
408 struct v4l2_tuner vt; 374 unsigned long fv;
409 int cur_input; 375 struct v4l2_tuner vt;
410 struct pvr2_ctrl *ctrlp; 376 int cur_input;
411 ret = pvr2_hdw_get_tuner_status(hdw,&vt); 377 struct pvr2_ctrl *ctrlp;
412 if (ret != 0) break; 378 int ret;
413 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); 379
414 ret = pvr2_ctrl_get_value(ctrlp,&cur_input); 380 ret = pvr2_hdw_get_tuner_status(hdw, &vt);
415 if (ret != 0) break; 381 if (ret != 0)
416 if (vf->type == V4L2_TUNER_RADIO) { 382 return ret;
417 if (cur_input != PVR2_CVAL_INPUT_RADIO) { 383 ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
418 pvr2_ctrl_set_value(ctrlp, 384 ret = pvr2_ctrl_get_value(ctrlp, &cur_input);
419 PVR2_CVAL_INPUT_RADIO); 385 if (ret != 0)
420 } 386 return ret;
421 } else { 387 if (vf->type == V4L2_TUNER_RADIO) {
422 if (cur_input == PVR2_CVAL_INPUT_RADIO) { 388 if (cur_input != PVR2_CVAL_INPUT_RADIO)
423 pvr2_ctrl_set_value(ctrlp, 389 pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO);
424 PVR2_CVAL_INPUT_TV); 390 } else {
425 } 391 if (cur_input == PVR2_CVAL_INPUT_RADIO)
426 } 392 pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV);
427 fv = vf->frequency; 393 }
428 if (vt.capability & V4L2_TUNER_CAP_LOW) { 394 fv = vf->frequency;
429 fv = (fv * 125) / 2; 395 if (vt.capability & V4L2_TUNER_CAP_LOW)
430 } else { 396 fv = (fv * 125) / 2;
431 fv = fv * 62500; 397 else
432 } 398 fv = fv * 62500;
433 ret = pvr2_ctrl_set_value( 399 return pvr2_ctrl_set_value(
434 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv); 400 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
435 break; 401}
436 }
437 402
438 case VIDIOC_G_FREQUENCY: 403static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
439 { 404{
440 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; 405 struct pvr2_v4l2_fh *fh = file->private_data;
441 int val = 0; 406 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
442 int cur_input; 407 int val = 0;
443 struct v4l2_tuner vt; 408 int cur_input;
444 ret = pvr2_hdw_get_tuner_status(hdw,&vt); 409 struct v4l2_tuner vt;
445 if (ret != 0) break; 410 int ret;
446 ret = pvr2_ctrl_get_value( 411
447 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), 412 ret = pvr2_hdw_get_tuner_status(hdw, &vt);
413 if (ret != 0)
414 return ret;
415 ret = pvr2_ctrl_get_value(
416 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY),
448 &val); 417 &val);
449 if (ret != 0) break; 418 if (ret != 0)
450 pvr2_ctrl_get_value( 419 return ret;
451 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), 420 pvr2_ctrl_get_value(
421 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
452 &cur_input); 422 &cur_input);
453 if (cur_input == PVR2_CVAL_INPUT_RADIO) { 423 if (cur_input == PVR2_CVAL_INPUT_RADIO)
454 vf->type = V4L2_TUNER_RADIO; 424 vf->type = V4L2_TUNER_RADIO;
455 } else { 425 else
456 vf->type = V4L2_TUNER_ANALOG_TV; 426 vf->type = V4L2_TUNER_ANALOG_TV;
457 } 427 if (vt.capability & V4L2_TUNER_CAP_LOW)
458 if (vt.capability & V4L2_TUNER_CAP_LOW) { 428 val = (val * 2) / 125;
459 val = (val * 2) / 125; 429 else
460 } else { 430 val /= 62500;
461 val /= 62500; 431 vf->frequency = val;
462 } 432 return 0;
463 vf->frequency = val; 433}
464 break;
465 }
466 434
467 case VIDIOC_ENUM_FMT: 435static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
468 { 436{
469 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg; 437 /* Only one format is supported : mpeg.*/
438 if (fd->index != 0)
439 return -EINVAL;
470 440
471 /* Only one format is supported : mpeg.*/ 441 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
472 if (fd->index != 0) 442 return 0;
473 break; 443}
474 444
475 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc)); 445static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
476 ret = 0; 446{
477 break; 447 struct pvr2_v4l2_fh *fh = file->private_data;
478 } 448 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
449 int val;
479 450
480 case VIDIOC_G_FMT: 451 memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format));
481 { 452 val = 0;
482 struct v4l2_format *vf = (struct v4l2_format *)arg; 453 pvr2_ctrl_get_value(
483 int val; 454 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES),
484 switch(vf->type) { 455 &val);
485 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 456 vf->fmt.pix.width = val;
486 memcpy(vf, &pvr_format[PVR_FORMAT_PIX], 457 val = 0;
487 sizeof(struct v4l2_format)); 458 pvr2_ctrl_get_value(
488 val = 0; 459 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES),
489 pvr2_ctrl_get_value( 460 &val);
490 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES), 461 vf->fmt.pix.height = val;
491 &val); 462 return 0;
492 vf->fmt.pix.width = val; 463}
493 val = 0;
494 pvr2_ctrl_get_value(
495 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
496 &val);
497 vf->fmt.pix.height = val;
498 ret = 0;
499 break;
500 case V4L2_BUF_TYPE_VBI_CAPTURE:
501 // ????? Still need to figure out to do VBI correctly
502 ret = -EINVAL;
503 break;
504 default:
505 ret = -EINVAL;
506 break;
507 }
508 break;
509 }
510 464
511 case VIDIOC_TRY_FMT: 465static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
512 case VIDIOC_S_FMT: 466{
513 { 467 struct pvr2_v4l2_fh *fh = file->private_data;
514 struct v4l2_format *vf = (struct v4l2_format *)arg; 468 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
515 469 int lmin, lmax, ldef;
516 ret = 0; 470 struct pvr2_ctrl *hcp, *vcp;
517 switch(vf->type) { 471 int h = vf->fmt.pix.height;
518 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 472 int w = vf->fmt.pix.width;
519 int lmin,lmax,ldef; 473
520 struct pvr2_ctrl *hcp,*vcp; 474 hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
521 int h = vf->fmt.pix.height; 475 vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
522 int w = vf->fmt.pix.width; 476
523 hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES); 477 lmin = pvr2_ctrl_get_min(hcp);
524 vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES); 478 lmax = pvr2_ctrl_get_max(hcp);
525 479 pvr2_ctrl_get_def(hcp, &ldef);
526 lmin = pvr2_ctrl_get_min(hcp); 480 if (w == -1)
527 lmax = pvr2_ctrl_get_max(hcp); 481 w = ldef;
528 pvr2_ctrl_get_def(hcp, &ldef); 482 else if (w < lmin)
529 if (w == -1) { 483 w = lmin;
530 w = ldef; 484 else if (w > lmax)
531 } else if (w < lmin) { 485 w = lmax;
532 w = lmin; 486 lmin = pvr2_ctrl_get_min(vcp);
533 } else if (w > lmax) { 487 lmax = pvr2_ctrl_get_max(vcp);
534 w = lmax; 488 pvr2_ctrl_get_def(vcp, &ldef);
535 } 489 if (h == -1)
536 lmin = pvr2_ctrl_get_min(vcp); 490 h = ldef;
537 lmax = pvr2_ctrl_get_max(vcp); 491 else if (h < lmin)
538 pvr2_ctrl_get_def(vcp, &ldef); 492 h = lmin;
539 if (h == -1) { 493 else if (h > lmax)
540 h = ldef; 494 h = lmax;
541 } else if (h < lmin) { 495
542 h = lmin; 496 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
543 } else if (h > lmax) { 497 sizeof(struct v4l2_format));
544 h = lmax; 498 vf->fmt.pix.width = w;
545 } 499 vf->fmt.pix.height = h;
500 return 0;
501}
546 502
547 memcpy(vf, &pvr_format[PVR_FORMAT_PIX], 503static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
548 sizeof(struct v4l2_format)); 504{
549 vf->fmt.pix.width = w; 505 struct pvr2_v4l2_fh *fh = file->private_data;
550 vf->fmt.pix.height = h; 506 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
507 struct pvr2_ctrl *hcp, *vcp;
508 int ret = pvr2_try_fmt_vid_cap(file, fh, vf);
551 509
552 if (cmd == VIDIOC_S_FMT) { 510 if (ret)
553 pvr2_ctrl_set_value(hcp,vf->fmt.pix.width); 511 return ret;
554 pvr2_ctrl_set_value(vcp,vf->fmt.pix.height); 512 hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
555 } 513 vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
556 } break; 514 pvr2_ctrl_set_value(hcp, vf->fmt.pix.width);
557 case V4L2_BUF_TYPE_VBI_CAPTURE: 515 pvr2_ctrl_set_value(vcp, vf->fmt.pix.height);
558 // ????? Still need to figure out to do VBI correctly 516 return 0;
559 ret = -EINVAL; 517}
560 break;
561 default:
562 ret = -EINVAL;
563 break;
564 }
565 break;
566 }
567 518
568 case VIDIOC_STREAMON: 519static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
569 { 520{
570 if (!fh->pdi->stream) { 521 struct pvr2_v4l2_fh *fh = file->private_data;
571 /* No stream defined for this node. This means 522 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
572 that we're not currently allowed to stream from 523 struct pvr2_v4l2_dev *pdi = fh->pdi;
573 this node. */ 524 int ret;
574 ret = -EPERM; 525
575 break; 526 if (!fh->pdi->stream) {
576 } 527 /* No stream defined for this node. This means
577 ret = pvr2_hdw_set_stream_type(hdw,pdi->config); 528 that we're not currently allowed to stream from
578 if (ret < 0) return ret; 529 this node. */
579 ret = pvr2_hdw_set_streaming(hdw,!0); 530 return -EPERM;
580 break;
581 } 531 }
532 ret = pvr2_hdw_set_stream_type(hdw, pdi->config);
533 if (ret < 0)
534 return ret;
535 return pvr2_hdw_set_streaming(hdw, !0);
536}
582 537
583 case VIDIOC_STREAMOFF: 538static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
584 { 539{
585 if (!fh->pdi->stream) { 540 struct pvr2_v4l2_fh *fh = file->private_data;
586 /* No stream defined for this node. This means 541 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
587 that we're not currently allowed to stream from 542
588 this node. */ 543 if (!fh->pdi->stream) {
589 ret = -EPERM; 544 /* No stream defined for this node. This means
590 break; 545 that we're not currently allowed to stream from
591 } 546 this node. */
592 ret = pvr2_hdw_set_streaming(hdw,0); 547 return -EPERM;
593 break;
594 } 548 }
549 return pvr2_hdw_set_streaming(hdw, 0);
550}
595 551
596 case VIDIOC_QUERYCTRL: 552static int pvr2_queryctrl(struct file *file, void *priv,
597 { 553 struct v4l2_queryctrl *vc)
598 struct pvr2_ctrl *cptr; 554{
599 int val; 555 struct pvr2_v4l2_fh *fh = file->private_data;
600 struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; 556 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
601 ret = 0; 557 struct pvr2_ctrl *cptr;
602 if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { 558 int val;
603 cptr = pvr2_hdw_get_ctrl_nextv4l( 559 int ret;
604 hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
605 if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr);
606 } else {
607 cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
608 }
609 if (!cptr) {
610 pvr2_trace(PVR2_TRACE_V4LIOCTL,
611 "QUERYCTRL id=0x%x not implemented here",
612 vc->id);
613 ret = -EINVAL;
614 break;
615 }
616 560
561 ret = 0;
562 if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
563 cptr = pvr2_hdw_get_ctrl_nextv4l(
564 hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
565 if (cptr)
566 vc->id = pvr2_ctrl_get_v4lid(cptr);
567 } else {
568 cptr = pvr2_hdw_get_ctrl_v4l(hdw, vc->id);
569 }
570 if (!cptr) {
617 pvr2_trace(PVR2_TRACE_V4LIOCTL, 571 pvr2_trace(PVR2_TRACE_V4LIOCTL,
618 "QUERYCTRL id=0x%x mapping name=%s (%s)", 572 "QUERYCTRL id=0x%x not implemented here",
619 vc->id,pvr2_ctrl_get_name(cptr), 573 vc->id);
620 pvr2_ctrl_get_desc(cptr)); 574 return -EINVAL;
621 strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); 575 }
622 vc->flags = pvr2_ctrl_get_v4lflags(cptr); 576
623 pvr2_ctrl_get_def(cptr, &val); 577 pvr2_trace(PVR2_TRACE_V4LIOCTL,
624 vc->default_value = val; 578 "QUERYCTRL id=0x%x mapping name=%s (%s)",
625 switch (pvr2_ctrl_get_type(cptr)) { 579 vc->id, pvr2_ctrl_get_name(cptr),
626 case pvr2_ctl_enum: 580 pvr2_ctrl_get_desc(cptr));
627 vc->type = V4L2_CTRL_TYPE_MENU; 581 strlcpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
628 vc->minimum = 0; 582 vc->flags = pvr2_ctrl_get_v4lflags(cptr);
629 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; 583 pvr2_ctrl_get_def(cptr, &val);
630 vc->step = 1; 584 vc->default_value = val;
631 break; 585 switch (pvr2_ctrl_get_type(cptr)) {
632 case pvr2_ctl_bool: 586 case pvr2_ctl_enum:
633 vc->type = V4L2_CTRL_TYPE_BOOLEAN; 587 vc->type = V4L2_CTRL_TYPE_MENU;
634 vc->minimum = 0; 588 vc->minimum = 0;
635 vc->maximum = 1; 589 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
636 vc->step = 1; 590 vc->step = 1;
637 break;
638 case pvr2_ctl_int:
639 vc->type = V4L2_CTRL_TYPE_INTEGER;
640 vc->minimum = pvr2_ctrl_get_min(cptr);
641 vc->maximum = pvr2_ctrl_get_max(cptr);
642 vc->step = 1;
643 break;
644 default:
645 pvr2_trace(PVR2_TRACE_V4LIOCTL,
646 "QUERYCTRL id=0x%x name=%s not mappable",
647 vc->id,pvr2_ctrl_get_name(cptr));
648 ret = -EINVAL;
649 break;
650 }
651 break; 591 break;
652 } 592 case pvr2_ctl_bool:
653 593 vc->type = V4L2_CTRL_TYPE_BOOLEAN;
654 case VIDIOC_QUERYMENU: 594 vc->minimum = 0;
655 { 595 vc->maximum = 1;
656 struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg; 596 vc->step = 1;
657 unsigned int cnt = 0;
658 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
659 vm->index,
660 vm->name,sizeof(vm->name)-1,
661 &cnt);
662 vm->name[cnt] = 0;
663 break; 597 break;
664 } 598 case pvr2_ctl_int:
665 599 vc->type = V4L2_CTRL_TYPE_INTEGER;
666 case VIDIOC_G_CTRL: 600 vc->minimum = pvr2_ctrl_get_min(cptr);
667 { 601 vc->maximum = pvr2_ctrl_get_max(cptr);
668 struct v4l2_control *vc = (struct v4l2_control *)arg; 602 vc->step = 1;
669 int val = 0;
670 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
671 &val);
672 vc->value = val;
673 break; 603 break;
604 default:
605 pvr2_trace(PVR2_TRACE_V4LIOCTL,
606 "QUERYCTRL id=0x%x name=%s not mappable",
607 vc->id, pvr2_ctrl_get_name(cptr));
608 return -EINVAL;
674 } 609 }
610 return 0;
611}
675 612
676 case VIDIOC_S_CTRL: 613static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm)
677 { 614{
678 struct v4l2_control *vc = (struct v4l2_control *)arg; 615 struct pvr2_v4l2_fh *fh = file->private_data;
679 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), 616 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
680 vc->value); 617 unsigned int cnt = 0;
681 break; 618 int ret;
682 }
683 619
684 case VIDIOC_G_EXT_CTRLS: 620 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw, vm->id),
685 { 621 vm->index,
686 struct v4l2_ext_controls *ctls = 622 vm->name, sizeof(vm->name) - 1,
687 (struct v4l2_ext_controls *)arg; 623 &cnt);
688 struct v4l2_ext_control *ctrl; 624 vm->name[cnt] = 0;
689 unsigned int idx; 625 return ret;
690 int val; 626}
691 ret = 0; 627
692 for (idx = 0; idx < ctls->count; idx++) { 628static int pvr2_g_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
693 ctrl = ctls->controls + idx; 629{
694 ret = pvr2_ctrl_get_value( 630 struct pvr2_v4l2_fh *fh = file->private_data;
695 pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val); 631 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
696 if (ret) { 632 int val = 0;
697 ctls->error_idx = idx; 633 int ret;
698 break; 634
699 } 635 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
700 /* Ensure that if read as a 64 bit value, the user 636 &val);
701 will still get a hopefully sane value */ 637 vc->value = val;
702 ctrl->value64 = 0; 638 return ret;
703 ctrl->value = val; 639}
640
641static int pvr2_s_ctrl(struct file *file, void *priv, struct v4l2_control *vc)
642{
643 struct pvr2_v4l2_fh *fh = file->private_data;
644 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
645
646 return pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw, vc->id),
647 vc->value);
648}
649
650static int pvr2_g_ext_ctrls(struct file *file, void *priv,
651 struct v4l2_ext_controls *ctls)
652{
653 struct pvr2_v4l2_fh *fh = file->private_data;
654 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
655 struct v4l2_ext_control *ctrl;
656 unsigned int idx;
657 int val;
658 int ret;
659
660 ret = 0;
661 for (idx = 0; idx < ctls->count; idx++) {
662 ctrl = ctls->controls + idx;
663 ret = pvr2_ctrl_get_value(
664 pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id), &val);
665 if (ret) {
666 ctls->error_idx = idx;
667 return ret;
704 } 668 }
705 break; 669 /* Ensure that if read as a 64 bit value, the user
670 will still get a hopefully sane value */
671 ctrl->value64 = 0;
672 ctrl->value = val;
706 } 673 }
674 return 0;
675}
707 676
708 case VIDIOC_S_EXT_CTRLS: 677static int pvr2_s_ext_ctrls(struct file *file, void *priv,
709 { 678 struct v4l2_ext_controls *ctls)
710 struct v4l2_ext_controls *ctls = 679{
711 (struct v4l2_ext_controls *)arg; 680 struct pvr2_v4l2_fh *fh = file->private_data;
712 struct v4l2_ext_control *ctrl; 681 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
713 unsigned int idx; 682 struct v4l2_ext_control *ctrl;
714 ret = 0; 683 unsigned int idx;
715 for (idx = 0; idx < ctls->count; idx++) { 684 int ret;
716 ctrl = ctls->controls + idx; 685
717 ret = pvr2_ctrl_set_value( 686 ret = 0;
718 pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id), 687 for (idx = 0; idx < ctls->count; idx++) {
688 ctrl = ctls->controls + idx;
689 ret = pvr2_ctrl_set_value(
690 pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id),
719 ctrl->value); 691 ctrl->value);
720 if (ret) { 692 if (ret) {
721 ctls->error_idx = idx; 693 ctls->error_idx = idx;
722 break; 694 return ret;
723 }
724 } 695 }
725 break;
726 } 696 }
697 return 0;
698}
727 699
728 case VIDIOC_TRY_EXT_CTRLS: 700static int pvr2_try_ext_ctrls(struct file *file, void *priv,
729 { 701 struct v4l2_ext_controls *ctls)
730 struct v4l2_ext_controls *ctls = 702{
731 (struct v4l2_ext_controls *)arg; 703 struct pvr2_v4l2_fh *fh = file->private_data;
732 struct v4l2_ext_control *ctrl; 704 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
733 struct pvr2_ctrl *pctl; 705 struct v4l2_ext_control *ctrl;
734 unsigned int idx; 706 struct pvr2_ctrl *pctl;
735 /* For the moment just validate that the requested control 707 unsigned int idx;
736 actually exists. */ 708 int ret;
737 ret = 0;
738 for (idx = 0; idx < ctls->count; idx++) {
739 ctrl = ctls->controls + idx;
740 pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id);
741 if (!pctl) {
742 ret = -EINVAL;
743 ctls->error_idx = idx;
744 break;
745 }
746 }
747 break;
748 }
749 709
750 case VIDIOC_CROPCAP: 710 /* For the moment just validate that the requested control
751 { 711 actually exists. */
752 struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg; 712 ret = 0;
753 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 713 for (idx = 0; idx < ctls->count; idx++) {
754 ret = -EINVAL; 714 ctrl = ctls->controls + idx;
755 break; 715 pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
716 if (!pctl) {
717 ctls->error_idx = idx;
718 return -EINVAL;
756 } 719 }
757 ret = pvr2_hdw_get_cropcap(hdw, cap);
758 cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
759 break;
760 } 720 }
761 case VIDIOC_G_CROP: 721 return 0;
762 { 722}
763 struct v4l2_crop *crop = (struct v4l2_crop *)arg; 723
764 int val = 0; 724static int pvr2_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap)
765 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 725{
766 ret = -EINVAL; 726 struct pvr2_v4l2_fh *fh = file->private_data;
767 break; 727 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
768 } 728 int ret;
769 ret = pvr2_ctrl_get_value( 729
730 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
731 return -EINVAL;
732 ret = pvr2_hdw_get_cropcap(hdw, cap);
733 cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
734 return ret;
735}
736
737static int pvr2_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
738{
739 struct pvr2_v4l2_fh *fh = file->private_data;
740 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
741 int val = 0;
742 int ret;
743
744 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
745 return -EINVAL;
746 ret = pvr2_ctrl_get_value(
770 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val); 747 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
771 if (ret != 0) { 748 if (ret != 0)
772 ret = -EINVAL; 749 return -EINVAL;
773 break; 750 crop->c.left = val;
774 } 751 ret = pvr2_ctrl_get_value(
775 crop->c.left = val;
776 ret = pvr2_ctrl_get_value(
777 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val); 752 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
778 if (ret != 0) { 753 if (ret != 0)
779 ret = -EINVAL; 754 return -EINVAL;
780 break; 755 crop->c.top = val;
781 } 756 ret = pvr2_ctrl_get_value(
782 crop->c.top = val;
783 ret = pvr2_ctrl_get_value(
784 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val); 757 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
785 if (ret != 0) { 758 if (ret != 0)
786 ret = -EINVAL; 759 return -EINVAL;
787 break; 760 crop->c.width = val;
788 } 761 ret = pvr2_ctrl_get_value(
789 crop->c.width = val;
790 ret = pvr2_ctrl_get_value(
791 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val); 762 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
792 if (ret != 0) { 763 if (ret != 0)
793 ret = -EINVAL; 764 return -EINVAL;
794 break; 765 crop->c.height = val;
795 } 766 return 0;
796 crop->c.height = val; 767}
797 } 768
798 case VIDIOC_S_CROP: 769static int pvr2_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
799 { 770{
800 struct v4l2_crop *crop = (struct v4l2_crop *)arg; 771 struct pvr2_v4l2_fh *fh = file->private_data;
801 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 772 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
802 ret = -EINVAL; 773 struct v4l2_cropcap cap;
803 break; 774 int ret;
804 } 775
805 ret = pvr2_ctrl_set_value( 776 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
777 return -EINVAL;
778 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
779 ret = pvr2_ctrl_set_value(
806 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), 780 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
807 crop->c.left); 781 crop->c.left);
808 if (ret != 0) { 782 if (ret != 0)
809 ret = -EINVAL; 783 return -EINVAL;
810 break; 784 ret = pvr2_ctrl_set_value(
811 }
812 ret = pvr2_ctrl_set_value(
813 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), 785 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
814 crop->c.top); 786 crop->c.top);
815 if (ret != 0) { 787 if (ret != 0)
816 ret = -EINVAL; 788 return -EINVAL;
817 break; 789 ret = pvr2_ctrl_set_value(
818 }
819 ret = pvr2_ctrl_set_value(
820 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), 790 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
821 crop->c.width); 791 crop->c.width);
822 if (ret != 0) { 792 if (ret != 0)
823 ret = -EINVAL; 793 return -EINVAL;
824 break; 794 ret = pvr2_ctrl_set_value(
825 }
826 ret = pvr2_ctrl_set_value(
827 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), 795 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
828 crop->c.height); 796 crop->c.height);
829 if (ret != 0) { 797 if (ret != 0)
830 ret = -EINVAL; 798 return -EINVAL;
831 break; 799 return 0;
832 } 800}
833 } 801
834 case VIDIOC_LOG_STATUS: 802static int pvr2_log_status(struct file *file, void *priv)
835 { 803{
836 pvr2_hdw_trigger_module_log(hdw); 804 struct pvr2_v4l2_fh *fh = file->private_data;
837 ret = 0; 805 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
838 break; 806
839 } 807 pvr2_hdw_trigger_module_log(hdw);
808 return 0;
809}
810
840#ifdef CONFIG_VIDEO_ADV_DEBUG 811#ifdef CONFIG_VIDEO_ADV_DEBUG
841 case VIDIOC_DBG_S_REGISTER: 812static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
842 case VIDIOC_DBG_G_REGISTER: 813{
843 { 814 struct pvr2_v4l2_fh *fh = file->private_data;
844 u64 val; 815 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
845 struct v4l2_dbg_register *req = (struct v4l2_dbg_register *)arg; 816 u64 val;
846 if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val; 817 int ret;
847 ret = pvr2_hdw_register_access(
848 hdw, &req->match, req->reg,
849 cmd == VIDIOC_DBG_S_REGISTER, &val);
850 if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
851 break;
852 }
853#endif
854 818
855 default : 819 ret = pvr2_hdw_register_access(
856 ret = -ENOTTY; 820 hdw, &req->match, req->reg,
857 break; 821 0, &val);
858 } 822 req->val = val;
823 return ret;
824}
859 825
860 pvr2_hdw_commit_ctl(hdw); 826static int pvr2_s_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
827{
828 struct pvr2_v4l2_fh *fh = file->private_data;
829 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
830 u64 val;
831 int ret;
861 832
862 if (ret < 0) { 833 val = req->val;
863 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { 834 ret = pvr2_hdw_register_access(
864 pvr2_trace(PVR2_TRACE_V4LIOCTL, 835 hdw, &req->match, req->reg,
865 "pvr2_v4l2_do_ioctl failure, ret=%ld", ret); 836 1, &val);
866 } else {
867 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
868 pvr2_trace(PVR2_TRACE_V4LIOCTL,
869 "pvr2_v4l2_do_ioctl failure, ret=%ld"
870 " command was:", ret);
871 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
872 cmd);
873 }
874 }
875 } else {
876 pvr2_trace(PVR2_TRACE_V4LIOCTL,
877 "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
878 ret, ret);
879 }
880 return ret; 837 return ret;
881} 838}
839#endif
840
841static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
842 .vidioc_querycap = pvr2_querycap,
843 .vidioc_g_priority = pvr2_g_priority,
844 .vidioc_s_priority = pvr2_s_priority,
845 .vidioc_s_audio = pvr2_s_audio,
846 .vidioc_g_audio = pvr2_g_audio,
847 .vidioc_enumaudio = pvr2_enumaudio,
848 .vidioc_enum_input = pvr2_enum_input,
849 .vidioc_cropcap = pvr2_cropcap,
850 .vidioc_s_crop = pvr2_s_crop,
851 .vidioc_g_crop = pvr2_g_crop,
852 .vidioc_g_input = pvr2_g_input,
853 .vidioc_s_input = pvr2_s_input,
854 .vidioc_g_frequency = pvr2_g_frequency,
855 .vidioc_s_frequency = pvr2_s_frequency,
856 .vidioc_s_tuner = pvr2_s_tuner,
857 .vidioc_g_tuner = pvr2_g_tuner,
858 .vidioc_g_std = pvr2_g_std,
859 .vidioc_s_std = pvr2_s_std,
860 .vidioc_querystd = pvr2_querystd,
861 .vidioc_log_status = pvr2_log_status,
862 .vidioc_enum_fmt_vid_cap = pvr2_enum_fmt_vid_cap,
863 .vidioc_g_fmt_vid_cap = pvr2_g_fmt_vid_cap,
864 .vidioc_s_fmt_vid_cap = pvr2_s_fmt_vid_cap,
865 .vidioc_try_fmt_vid_cap = pvr2_try_fmt_vid_cap,
866 .vidioc_streamon = pvr2_streamon,
867 .vidioc_streamoff = pvr2_streamoff,
868 .vidioc_queryctrl = pvr2_queryctrl,
869 .vidioc_querymenu = pvr2_querymenu,
870 .vidioc_g_ctrl = pvr2_g_ctrl,
871 .vidioc_s_ctrl = pvr2_s_ctrl,
872 .vidioc_g_ext_ctrls = pvr2_g_ext_ctrls,
873 .vidioc_s_ext_ctrls = pvr2_s_ext_ctrls,
874 .vidioc_try_ext_ctrls = pvr2_try_ext_ctrls,
875#ifdef CONFIG_VIDEO_ADV_DEBUG
876 .vidioc_g_register = pvr2_g_register,
877 .vidioc_s_register = pvr2_s_register,
878#endif
879};
882 880
883static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) 881static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
884{ 882{
@@ -961,7 +959,56 @@ static long pvr2_v4l2_ioctl(struct file *file,
961 unsigned int cmd, unsigned long arg) 959 unsigned int cmd, unsigned long arg)
962{ 960{
963 961
964 return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl); 962 struct pvr2_v4l2_fh *fh = file->private_data;
963 struct pvr2_v4l2 *vp = fh->vhead;
964 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
965 long ret = -EINVAL;
966
967 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL)
968 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
969
970 if (!pvr2_hdw_dev_ok(hdw)) {
971 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
972 "ioctl failed - bad or no context");
973 return -EFAULT;
974 }
975
976 /* check priority */
977 switch (cmd) {
978 case VIDIOC_S_CTRL:
979 case VIDIOC_S_STD:
980 case VIDIOC_S_INPUT:
981 case VIDIOC_S_TUNER:
982 case VIDIOC_S_FREQUENCY:
983 ret = v4l2_prio_check(&vp->prio, fh->prio);
984 if (ret)
985 return ret;
986 }
987
988 ret = video_ioctl2(file, cmd, arg);
989
990 pvr2_hdw_commit_ctl(hdw);
991
992 if (ret < 0) {
993 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
994 pvr2_trace(PVR2_TRACE_V4LIOCTL,
995 "pvr2_v4l2_do_ioctl failure, ret=%ld", ret);
996 } else {
997 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
998 pvr2_trace(PVR2_TRACE_V4LIOCTL,
999 "pvr2_v4l2_do_ioctl failure, ret=%ld"
1000 " command was:", ret);
1001 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
1002 cmd);
1003 }
1004 }
1005 } else {
1006 pvr2_trace(PVR2_TRACE_V4LIOCTL,
1007 "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
1008 ret, ret);
1009 }
1010 return ret;
1011
965} 1012}
966 1013
967 1014
@@ -1262,10 +1309,12 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1262 struct usb_device *usbdev; 1309 struct usb_device *usbdev;
1263 int mindevnum; 1310 int mindevnum;
1264 int unit_number; 1311 int unit_number;
1312 struct pvr2_hdw *hdw;
1265 int *nr_ptr = NULL; 1313 int *nr_ptr = NULL;
1266 dip->v4lp = vp; 1314 dip->v4lp = vp;
1267 1315
1268 usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw); 1316 hdw = vp->channel.mc_head->hdw;
1317 usbdev = pvr2_hdw_get_dev(hdw);
1269 dip->v4l_type = v4l_type; 1318 dip->v4l_type = v4l_type;
1270 switch (v4l_type) { 1319 switch (v4l_type) {
1271 case VFL_TYPE_GRABBER: 1320 case VFL_TYPE_GRABBER:
@@ -1300,9 +1349,17 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1300 1349
1301 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template)); 1350 memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
1302 dip->devbase.release = pvr2_video_device_release; 1351 dip->devbase.release = pvr2_video_device_release;
1352 dip->devbase.ioctl_ops = &pvr2_ioctl_ops;
1353 {
1354 int val;
1355 pvr2_ctrl_get_value(
1356 pvr2_hdw_get_ctrl_by_id(hdw,
1357 PVR2_CID_STDAVAIL), &val);
1358 dip->devbase.tvnorms = (v4l2_std_id)val;
1359 }
1303 1360
1304 mindevnum = -1; 1361 mindevnum = -1;
1305 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw); 1362 unit_number = pvr2_hdw_get_unit_number(hdw);
1306 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) { 1363 if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1307 mindevnum = nr_ptr[unit_number]; 1364 mindevnum = nr_ptr[unit_number];
1308 } 1365 }
@@ -1319,7 +1376,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1319 video_device_node_name(&dip->devbase), 1376 video_device_node_name(&dip->devbase),
1320 pvr2_config_get_name(dip->config)); 1377 pvr2_config_get_name(dip->config));
1321 1378
1322 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, 1379 pvr2_hdw_v4l_store_minor_number(hdw,
1323 dip->minor_type,dip->devbase.minor); 1380 dip->minor_type,dip->devbase.minor);
1324} 1381}
1325 1382
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 122fbd0081eb..ec4e2ef54e65 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -357,6 +357,7 @@ handler_end:
357 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); 357 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
358} 358}
359 359
360/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
360static int pwc_isoc_init(struct pwc_device *pdev) 361static int pwc_isoc_init(struct pwc_device *pdev)
361{ 362{
362 struct usb_device *udev; 363 struct usb_device *udev;
@@ -366,9 +367,6 @@ static int pwc_isoc_init(struct pwc_device *pdev)
366 struct usb_host_interface *idesc = NULL; 367 struct usb_host_interface *idesc = NULL;
367 int compression = 0; /* 0..3 = uncompressed..high */ 368 int compression = 0; /* 0..3 = uncompressed..high */
368 369
369 if (pdev->iso_init)
370 return 0;
371
372 pdev->vsync = 0; 370 pdev->vsync = 0;
373 pdev->vlast_packet_size = 0; 371 pdev->vlast_packet_size = 0;
374 pdev->fill_buf = NULL; 372 pdev->fill_buf = NULL;
@@ -418,7 +416,6 @@ retry:
418 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); 416 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
419 if (urb == NULL) { 417 if (urb == NULL) {
420 PWC_ERROR("Failed to allocate urb %d\n", i); 418 PWC_ERROR("Failed to allocate urb %d\n", i);
421 pdev->iso_init = 1;
422 pwc_isoc_cleanup(pdev); 419 pwc_isoc_cleanup(pdev);
423 return -ENOMEM; 420 return -ENOMEM;
424 } 421 }
@@ -435,7 +432,6 @@ retry:
435 &urb->transfer_dma); 432 &urb->transfer_dma);
436 if (urb->transfer_buffer == NULL) { 433 if (urb->transfer_buffer == NULL) {
437 PWC_ERROR("Failed to allocate urb buffer %d\n", i); 434 PWC_ERROR("Failed to allocate urb buffer %d\n", i);
438 pdev->iso_init = 1;
439 pwc_isoc_cleanup(pdev); 435 pwc_isoc_cleanup(pdev);
440 return -ENOMEM; 436 return -ENOMEM;
441 } 437 }
@@ -455,13 +451,11 @@ retry:
455 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); 451 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
456 if (ret == -ENOSPC && compression < 3) { 452 if (ret == -ENOSPC && compression < 3) {
457 compression++; 453 compression++;
458 pdev->iso_init = 1;
459 pwc_isoc_cleanup(pdev); 454 pwc_isoc_cleanup(pdev);
460 goto retry; 455 goto retry;
461 } 456 }
462 if (ret) { 457 if (ret) {
463 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 458 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
464 pdev->iso_init = 1;
465 pwc_isoc_cleanup(pdev); 459 pwc_isoc_cleanup(pdev);
466 return ret; 460 return ret;
467 } 461 }
@@ -469,7 +463,6 @@ retry:
469 } 463 }
470 464
471 /* All is done... */ 465 /* All is done... */
472 pdev->iso_init = 1;
473 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n"); 466 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
474 return 0; 467 return 0;
475} 468}
@@ -507,21 +500,19 @@ static void pwc_iso_free(struct pwc_device *pdev)
507 } 500 }
508} 501}
509 502
503/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
510static void pwc_isoc_cleanup(struct pwc_device *pdev) 504static void pwc_isoc_cleanup(struct pwc_device *pdev)
511{ 505{
512 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); 506 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
513 507
514 if (pdev->iso_init == 0)
515 return;
516
517 pwc_iso_stop(pdev); 508 pwc_iso_stop(pdev);
518 pwc_iso_free(pdev); 509 pwc_iso_free(pdev);
519 usb_set_interface(pdev->udev, 0, 0); 510 usb_set_interface(pdev->udev, 0, 0);
520 511
521 pdev->iso_init = 0;
522 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); 512 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
523} 513}
524 514
515/* Must be called with vb_queue_lock hold */
525static void pwc_cleanup_queued_bufs(struct pwc_device *pdev) 516static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
526{ 517{
527 unsigned long flags = 0; 518 unsigned long flags = 0;
@@ -573,18 +564,13 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
573 564
574int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file) 565int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file)
575{ 566{
576 int r = 0;
577
578 mutex_lock(&pdev->capt_file_lock);
579 if (pdev->capt_file != NULL && 567 if (pdev->capt_file != NULL &&
580 pdev->capt_file != file) { 568 pdev->capt_file != file)
581 r = -EBUSY; 569 return -EBUSY;
582 goto leave; 570
583 }
584 pdev->capt_file = file; 571 pdev->capt_file = file;
585leave: 572
586 mutex_unlock(&pdev->capt_file_lock); 573 return 0;
587 return r;
588} 574}
589 575
590static void pwc_video_release(struct v4l2_device *v) 576static void pwc_video_release(struct v4l2_device *v)
@@ -592,6 +578,7 @@ static void pwc_video_release(struct v4l2_device *v)
592 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); 578 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
593 579
594 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 580 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
581 v4l2_device_unregister(&pdev->v4l2_dev);
595 kfree(pdev->ctrl_buf); 582 kfree(pdev->ctrl_buf);
596 kfree(pdev); 583 kfree(pdev);
597} 584}
@@ -600,10 +587,25 @@ static int pwc_video_close(struct file *file)
600{ 587{
601 struct pwc_device *pdev = video_drvdata(file); 588 struct pwc_device *pdev = video_drvdata(file);
602 589
590 /*
591 * If we're still streaming vb2_queue_release will call stream_stop
592 * so we must take both the v4l2_lock and the vb_queue_lock.
593 */
594 if (mutex_lock_interruptible(&pdev->v4l2_lock))
595 return -ERESTARTSYS;
596 if (mutex_lock_interruptible(&pdev->vb_queue_lock)) {
597 mutex_unlock(&pdev->v4l2_lock);
598 return -ERESTARTSYS;
599 }
600
603 if (pdev->capt_file == file) { 601 if (pdev->capt_file == file) {
604 vb2_queue_release(&pdev->vb_queue); 602 vb2_queue_release(&pdev->vb_queue);
605 pdev->capt_file = NULL; 603 pdev->capt_file = NULL;
606 } 604 }
605
606 mutex_unlock(&pdev->vb_queue_lock);
607 mutex_unlock(&pdev->v4l2_lock);
608
607 return v4l2_fh_release(file); 609 return v4l2_fh_release(file);
608} 610}
609 611
@@ -611,35 +613,81 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
611 size_t count, loff_t *ppos) 613 size_t count, loff_t *ppos)
612{ 614{
613 struct pwc_device *pdev = video_drvdata(file); 615 struct pwc_device *pdev = video_drvdata(file);
616 int lock_v4l2 = 0;
617 ssize_t ret;
614 618
615 if (!pdev->udev) 619 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
616 return -ENODEV; 620 return -ERESTARTSYS;
617 621
618 if (pwc_test_n_set_capt_file(pdev, file)) 622 ret = pwc_test_n_set_capt_file(pdev, file);
619 return -EBUSY; 623 if (ret)
624 goto out;
620 625
621 return vb2_read(&pdev->vb_queue, buf, count, ppos, 626 /* stream_start will get called so we must take the v4l2_lock */
622 file->f_flags & O_NONBLOCK); 627 if (pdev->vb_queue.fileio == NULL)
628 lock_v4l2 = 1;
629
630 /* Use try_lock, since we're taking the locks in the *wrong* order! */
631 if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock)) {
632 ret = -ERESTARTSYS;
633 goto out;
634 }
635 ret = vb2_read(&pdev->vb_queue, buf, count, ppos,
636 file->f_flags & O_NONBLOCK);
637 if (lock_v4l2)
638 mutex_unlock(&pdev->v4l2_lock);
639out:
640 mutex_unlock(&pdev->vb_queue_lock);
641 return ret;
623} 642}
624 643
625static unsigned int pwc_video_poll(struct file *file, poll_table *wait) 644static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
626{ 645{
627 struct pwc_device *pdev = video_drvdata(file); 646 struct pwc_device *pdev = video_drvdata(file);
647 struct vb2_queue *q = &pdev->vb_queue;
648 unsigned long req_events = poll_requested_events(wait);
649 unsigned int ret = POLL_ERR;
650 int lock_v4l2 = 0;
628 651
629 if (!pdev->udev) 652 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
630 return POLL_ERR; 653 return POLL_ERR;
631 654
632 return vb2_poll(&pdev->vb_queue, file, wait); 655 /* Will this start fileio and thus call start_stream? */
656 if ((req_events & (POLLIN | POLLRDNORM)) &&
657 q->num_buffers == 0 && !q->streaming && q->fileio == NULL) {
658 if (pwc_test_n_set_capt_file(pdev, file))
659 goto out;
660 lock_v4l2 = 1;
661 }
662
663 /* Use try_lock, since we're taking the locks in the *wrong* order! */
664 if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock))
665 goto out;
666 ret = vb2_poll(&pdev->vb_queue, file, wait);
667 if (lock_v4l2)
668 mutex_unlock(&pdev->v4l2_lock);
669
670out:
671 if (!pdev->udev)
672 ret |= POLLHUP;
673 mutex_unlock(&pdev->vb_queue_lock);
674 return ret;
633} 675}
634 676
635static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 677static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
636{ 678{
637 struct pwc_device *pdev = video_drvdata(file); 679 struct pwc_device *pdev = video_drvdata(file);
680 int ret;
638 681
639 if (pdev->capt_file != file) 682 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
640 return -EBUSY; 683 return -ERESTARTSYS;
641 684
642 return vb2_mmap(&pdev->vb_queue, vma); 685 ret = pwc_test_n_set_capt_file(pdev, file);
686 if (ret == 0)
687 ret = vb2_mmap(&pdev->vb_queue, vma);
688
689 mutex_unlock(&pdev->vb_queue_lock);
690 return ret;
643} 691}
644 692
645/***************************************************************************/ 693/***************************************************************************/
@@ -715,12 +763,14 @@ static void buffer_queue(struct vb2_buffer *vb)
715 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); 763 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
716 unsigned long flags = 0; 764 unsigned long flags = 0;
717 765
718 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
719 /* Check the device has not disconnected between prep and queuing */ 766 /* Check the device has not disconnected between prep and queuing */
720 if (pdev->udev) 767 if (!pdev->udev) {
721 list_add_tail(&buf->list, &pdev->queued_bufs);
722 else
723 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); 768 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
769 return;
770 }
771
772 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
773 list_add_tail(&buf->list, &pdev->queued_bufs);
724 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); 774 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
725} 775}
726 776
@@ -729,11 +779,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
729 struct pwc_device *pdev = vb2_get_drv_priv(vq); 779 struct pwc_device *pdev = vb2_get_drv_priv(vq);
730 int r; 780 int r;
731 781
732 mutex_lock(&pdev->udevlock); 782 if (!pdev->udev)
733 if (!pdev->udev) { 783 return -ENODEV;
734 r = -ENODEV;
735 goto leave;
736 }
737 784
738 /* Turn on camera and set LEDS on */ 785 /* Turn on camera and set LEDS on */
739 pwc_camera_power(pdev, 1); 786 pwc_camera_power(pdev, 1);
@@ -747,8 +794,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
747 /* And cleanup any queued bufs!! */ 794 /* And cleanup any queued bufs!! */
748 pwc_cleanup_queued_bufs(pdev); 795 pwc_cleanup_queued_bufs(pdev);
749 } 796 }
750leave: 797
751 mutex_unlock(&pdev->udevlock);
752 return r; 798 return r;
753} 799}
754 800
@@ -756,19 +802,29 @@ static int stop_streaming(struct vb2_queue *vq)
756{ 802{
757 struct pwc_device *pdev = vb2_get_drv_priv(vq); 803 struct pwc_device *pdev = vb2_get_drv_priv(vq);
758 804
759 mutex_lock(&pdev->udevlock);
760 if (pdev->udev) { 805 if (pdev->udev) {
761 pwc_set_leds(pdev, 0, 0); 806 pwc_set_leds(pdev, 0, 0);
762 pwc_camera_power(pdev, 0); 807 pwc_camera_power(pdev, 0);
763 pwc_isoc_cleanup(pdev); 808 pwc_isoc_cleanup(pdev);
764 } 809 }
765 mutex_unlock(&pdev->udevlock);
766 810
767 pwc_cleanup_queued_bufs(pdev); 811 pwc_cleanup_queued_bufs(pdev);
768 812
769 return 0; 813 return 0;
770} 814}
771 815
816static void wait_prepare(struct vb2_queue *vq)
817{
818 struct pwc_device *pdev = vb2_get_drv_priv(vq);
819 mutex_unlock(&pdev->vb_queue_lock);
820}
821
822static void wait_finish(struct vb2_queue *vq)
823{
824 struct pwc_device *pdev = vb2_get_drv_priv(vq);
825 mutex_lock(&pdev->vb_queue_lock);
826}
827
772static struct vb2_ops pwc_vb_queue_ops = { 828static struct vb2_ops pwc_vb_queue_ops = {
773 .queue_setup = queue_setup, 829 .queue_setup = queue_setup,
774 .buf_init = buffer_init, 830 .buf_init = buffer_init,
@@ -778,6 +834,8 @@ static struct vb2_ops pwc_vb_queue_ops = {
778 .buf_queue = buffer_queue, 834 .buf_queue = buffer_queue,
779 .start_streaming = start_streaming, 835 .start_streaming = start_streaming,
780 .stop_streaming = stop_streaming, 836 .stop_streaming = stop_streaming,
837 .wait_prepare = wait_prepare,
838 .wait_finish = wait_finish,
781}; 839};
782 840
783/***************************************************************************/ 841/***************************************************************************/
@@ -1057,8 +1115,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1057 pdev->features = features; 1115 pdev->features = features;
1058 pwc_construct(pdev); /* set min/max sizes correct */ 1116 pwc_construct(pdev); /* set min/max sizes correct */
1059 1117
1060 mutex_init(&pdev->capt_file_lock); 1118 mutex_init(&pdev->v4l2_lock);
1061 mutex_init(&pdev->udevlock); 1119 mutex_init(&pdev->vb_queue_lock);
1062 spin_lock_init(&pdev->queued_bufs_lock); 1120 spin_lock_init(&pdev->queued_bufs_lock);
1063 INIT_LIST_HEAD(&pdev->queued_bufs); 1121 INIT_LIST_HEAD(&pdev->queued_bufs);
1064 1122
@@ -1130,6 +1188,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1130 1188
1131 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; 1189 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1132 pdev->vdev.v4l2_dev = &pdev->v4l2_dev; 1190 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
1191 pdev->vdev.lock = &pdev->v4l2_lock;
1192
1193 /*
1194 * Don't take v4l2_lock for these ioctls. This improves latency if
1195 * v4l2_lock is taken for a long time, e.g. when changing a control
1196 * value, and a new frame is ready to be dequeued.
1197 */
1198 v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_DQBUF);
1199 v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QBUF);
1200 v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QUERYBUF);
1133 1201
1134 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); 1202 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
1135 if (rc < 0) { 1203 if (rc < 0) {
@@ -1185,16 +1253,20 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1185 struct v4l2_device *v = usb_get_intfdata(intf); 1253 struct v4l2_device *v = usb_get_intfdata(intf);
1186 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); 1254 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
1187 1255
1188 mutex_lock(&pdev->udevlock); 1256 mutex_lock(&pdev->v4l2_lock);
1257
1258 mutex_lock(&pdev->vb_queue_lock);
1189 /* No need to keep the urbs around after disconnection */ 1259 /* No need to keep the urbs around after disconnection */
1190 pwc_isoc_cleanup(pdev); 1260 if (pdev->vb_queue.streaming)
1261 pwc_isoc_cleanup(pdev);
1191 pdev->udev = NULL; 1262 pdev->udev = NULL;
1192 mutex_unlock(&pdev->udevlock);
1193
1194 pwc_cleanup_queued_bufs(pdev); 1263 pwc_cleanup_queued_bufs(pdev);
1264 mutex_unlock(&pdev->vb_queue_lock);
1195 1265
1266 v4l2_device_disconnect(&pdev->v4l2_dev);
1196 video_unregister_device(&pdev->vdev); 1267 video_unregister_device(&pdev->vdev);
1197 v4l2_device_unregister(&pdev->v4l2_dev); 1268
1269 mutex_unlock(&pdev->v4l2_lock);
1198 1270
1199#ifdef CONFIG_USB_PWC_INPUT_EVDEV 1271#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1200 if (pdev->button_dev) 1272 if (pdev->button_dev)
@@ -1229,15 +1301,4 @@ MODULE_LICENSE("GPL");
1229MODULE_ALIAS("pwcx"); 1301MODULE_ALIAS("pwcx");
1230MODULE_VERSION( PWC_VERSION ); 1302MODULE_VERSION( PWC_VERSION );
1231 1303
1232static int __init usb_pwc_init(void) 1304module_usb_driver(pwc_driver);
1233{
1234 return usb_register(&pwc_driver);
1235}
1236
1237static void __exit usb_pwc_exit(void)
1238{
1239 usb_deregister(&pwc_driver);
1240}
1241
1242module_init(usb_pwc_init);
1243module_exit(usb_pwc_exit);
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 2834e3e65b39..c691e29cc36e 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -464,26 +464,24 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
464 struct pwc_device *pdev = video_drvdata(file); 464 struct pwc_device *pdev = video_drvdata(file);
465 int ret, pixelformat, compression = 0; 465 int ret, pixelformat, compression = 0;
466 466
467 if (pwc_test_n_set_capt_file(pdev, file))
468 return -EBUSY;
469
470 ret = pwc_vidioc_try_fmt(pdev, f); 467 ret = pwc_vidioc_try_fmt(pdev, f);
471 if (ret < 0) 468 if (ret < 0)
472 return ret; 469 return ret;
473 470
474 pixelformat = f->fmt.pix.pixelformat; 471 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
472 return -ERESTARTSYS;
475 473
476 mutex_lock(&pdev->udevlock); 474 ret = pwc_test_n_set_capt_file(pdev, file);
477 if (!pdev->udev) { 475 if (ret)
478 ret = -ENODEV;
479 goto leave; 476 goto leave;
480 }
481 477
482 if (pdev->iso_init) { 478 if (pdev->vb_queue.streaming) {
483 ret = -EBUSY; 479 ret = -EBUSY;
484 goto leave; 480 goto leave;
485 } 481 }
486 482
483 pixelformat = f->fmt.pix.pixelformat;
484
487 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " 485 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
488 "format=%c%c%c%c\n", 486 "format=%c%c%c%c\n",
489 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes, 487 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes,
@@ -499,7 +497,7 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
499 497
500 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); 498 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
501leave: 499leave:
502 mutex_unlock(&pdev->udevlock); 500 mutex_unlock(&pdev->vb_queue_lock);
503 return ret; 501 return ret;
504} 502}
505 503
@@ -507,9 +505,6 @@ static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap
507{ 505{
508 struct pwc_device *pdev = video_drvdata(file); 506 struct pwc_device *pdev = video_drvdata(file);
509 507
510 if (!pdev->udev)
511 return -ENODEV;
512
513 strcpy(cap->driver, PWC_NAME); 508 strcpy(cap->driver, PWC_NAME);
514 strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card)); 509 strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
515 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); 510 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
@@ -540,15 +535,12 @@ static int pwc_s_input(struct file *file, void *fh, unsigned int i)
540 return i ? -EINVAL : 0; 535 return i ? -EINVAL : 0;
541} 536}
542 537
543static int pwc_g_volatile_ctrl_unlocked(struct v4l2_ctrl *ctrl) 538static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
544{ 539{
545 struct pwc_device *pdev = 540 struct pwc_device *pdev =
546 container_of(ctrl->handler, struct pwc_device, ctrl_handler); 541 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
547 int ret = 0; 542 int ret = 0;
548 543
549 if (!pdev->udev)
550 return -ENODEV;
551
552 switch (ctrl->id) { 544 switch (ctrl->id) {
553 case V4L2_CID_AUTO_WHITE_BALANCE: 545 case V4L2_CID_AUTO_WHITE_BALANCE:
554 if (pdev->color_bal_valid && 546 if (pdev->color_bal_valid &&
@@ -615,18 +607,6 @@ static int pwc_g_volatile_ctrl_unlocked(struct v4l2_ctrl *ctrl)
615 return ret; 607 return ret;
616} 608}
617 609
618static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
619{
620 struct pwc_device *pdev =
621 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
622 int ret;
623
624 mutex_lock(&pdev->udevlock);
625 ret = pwc_g_volatile_ctrl_unlocked(ctrl);
626 mutex_unlock(&pdev->udevlock);
627 return ret;
628}
629
630static int pwc_set_awb(struct pwc_device *pdev) 610static int pwc_set_awb(struct pwc_device *pdev)
631{ 611{
632 int ret; 612 int ret;
@@ -648,7 +628,7 @@ static int pwc_set_awb(struct pwc_device *pdev)
648 if (pdev->auto_white_balance->val == awb_indoor || 628 if (pdev->auto_white_balance->val == awb_indoor ||
649 pdev->auto_white_balance->val == awb_outdoor || 629 pdev->auto_white_balance->val == awb_outdoor ||
650 pdev->auto_white_balance->val == awb_fl) 630 pdev->auto_white_balance->val == awb_fl)
651 pwc_g_volatile_ctrl_unlocked(pdev->auto_white_balance); 631 pwc_g_volatile_ctrl(pdev->auto_white_balance);
652 } 632 }
653 if (pdev->auto_white_balance->val != awb_manual) 633 if (pdev->auto_white_balance->val != awb_manual)
654 return 0; 634 return 0;
@@ -812,13 +792,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
812 container_of(ctrl->handler, struct pwc_device, ctrl_handler); 792 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
813 int ret = 0; 793 int ret = 0;
814 794
815 mutex_lock(&pdev->udevlock);
816
817 if (!pdev->udev) {
818 ret = -ENODEV;
819 goto leave;
820 }
821
822 switch (ctrl->id) { 795 switch (ctrl->id) {
823 case V4L2_CID_BRIGHTNESS: 796 case V4L2_CID_BRIGHTNESS:
824 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, 797 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
@@ -915,8 +888,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
915 if (ret) 888 if (ret)
916 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret); 889 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret);
917 890
918leave:
919 mutex_unlock(&pdev->udevlock);
920 return ret; 891 return ret;
921} 892}
922 893
@@ -949,11 +920,9 @@ static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
949 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 920 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
950 return -EINVAL; 921 return -EINVAL;
951 922
952 mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */
953 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", 923 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
954 pdev->width, pdev->height); 924 pdev->width, pdev->height);
955 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); 925 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
956 mutex_unlock(&pdev->udevlock);
957 return 0; 926 return 0;
958} 927}
959 928
@@ -968,70 +937,98 @@ static int pwc_reqbufs(struct file *file, void *fh,
968 struct v4l2_requestbuffers *rb) 937 struct v4l2_requestbuffers *rb)
969{ 938{
970 struct pwc_device *pdev = video_drvdata(file); 939 struct pwc_device *pdev = video_drvdata(file);
940 int ret;
971 941
972 if (pwc_test_n_set_capt_file(pdev, file)) 942 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
973 return -EBUSY; 943 return -ERESTARTSYS;
974 944
975 return vb2_reqbufs(&pdev->vb_queue, rb); 945 ret = pwc_test_n_set_capt_file(pdev, file);
946 if (ret == 0)
947 ret = vb2_reqbufs(&pdev->vb_queue, rb);
948
949 mutex_unlock(&pdev->vb_queue_lock);
950 return ret;
976} 951}
977 952
978static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) 953static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
979{ 954{
980 struct pwc_device *pdev = video_drvdata(file); 955 struct pwc_device *pdev = video_drvdata(file);
956 int ret;
981 957
982 return vb2_querybuf(&pdev->vb_queue, buf); 958 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
959 return -ERESTARTSYS;
960
961 ret = pwc_test_n_set_capt_file(pdev, file);
962 if (ret == 0)
963 ret = vb2_querybuf(&pdev->vb_queue, buf);
964
965 mutex_unlock(&pdev->vb_queue_lock);
966 return ret;
983} 967}
984 968
985static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 969static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
986{ 970{
987 struct pwc_device *pdev = video_drvdata(file); 971 struct pwc_device *pdev = video_drvdata(file);
972 int ret;
988 973
989 if (!pdev->udev) 974 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
990 return -ENODEV; 975 return -ERESTARTSYS;
991 976
992 if (pdev->capt_file != file) 977 ret = pwc_test_n_set_capt_file(pdev, file);
993 return -EBUSY; 978 if (ret == 0)
979 ret = vb2_qbuf(&pdev->vb_queue, buf);
994 980
995 return vb2_qbuf(&pdev->vb_queue, buf); 981 mutex_unlock(&pdev->vb_queue_lock);
982 return ret;
996} 983}
997 984
998static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 985static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
999{ 986{
1000 struct pwc_device *pdev = video_drvdata(file); 987 struct pwc_device *pdev = video_drvdata(file);
988 int ret;
1001 989
1002 if (!pdev->udev) 990 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1003 return -ENODEV; 991 return -ERESTARTSYS;
1004 992
1005 if (pdev->capt_file != file) 993 ret = pwc_test_n_set_capt_file(pdev, file);
1006 return -EBUSY; 994 if (ret == 0)
995 ret = vb2_dqbuf(&pdev->vb_queue, buf,
996 file->f_flags & O_NONBLOCK);
1007 997
1008 return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); 998 mutex_unlock(&pdev->vb_queue_lock);
999 return ret;
1009} 1000}
1010 1001
1011static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) 1002static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1012{ 1003{
1013 struct pwc_device *pdev = video_drvdata(file); 1004 struct pwc_device *pdev = video_drvdata(file);
1005 int ret;
1014 1006
1015 if (!pdev->udev) 1007 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1016 return -ENODEV; 1008 return -ERESTARTSYS;
1017 1009
1018 if (pdev->capt_file != file) 1010 ret = pwc_test_n_set_capt_file(pdev, file);
1019 return -EBUSY; 1011 if (ret == 0)
1012 ret = vb2_streamon(&pdev->vb_queue, i);
1020 1013
1021 return vb2_streamon(&pdev->vb_queue, i); 1014 mutex_unlock(&pdev->vb_queue_lock);
1015 return ret;
1022} 1016}
1023 1017
1024static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) 1018static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1025{ 1019{
1026 struct pwc_device *pdev = video_drvdata(file); 1020 struct pwc_device *pdev = video_drvdata(file);
1021 int ret;
1027 1022
1028 if (!pdev->udev) 1023 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1029 return -ENODEV; 1024 return -ERESTARTSYS;
1030 1025
1031 if (pdev->capt_file != file) 1026 ret = pwc_test_n_set_capt_file(pdev, file);
1032 return -EBUSY; 1027 if (ret == 0)
1028 ret = vb2_streamoff(&pdev->vb_queue, i);
1033 1029
1034 return vb2_streamoff(&pdev->vb_queue, i); 1030 mutex_unlock(&pdev->vb_queue_lock);
1031 return ret;
1035} 1032}
1036 1033
1037static int pwc_enum_framesizes(struct file *file, void *fh, 1034static int pwc_enum_framesizes(struct file *file, void *fh,
@@ -1119,19 +1116,17 @@ static int pwc_s_parm(struct file *file, void *fh,
1119 parm->parm.capture.timeperframe.numerator == 0) 1116 parm->parm.capture.timeperframe.numerator == 0)
1120 return -EINVAL; 1117 return -EINVAL;
1121 1118
1122 if (pwc_test_n_set_capt_file(pdev, file))
1123 return -EBUSY;
1124
1125 fps = parm->parm.capture.timeperframe.denominator / 1119 fps = parm->parm.capture.timeperframe.denominator /
1126 parm->parm.capture.timeperframe.numerator; 1120 parm->parm.capture.timeperframe.numerator;
1127 1121
1128 mutex_lock(&pdev->udevlock); 1122 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1129 if (!pdev->udev) { 1123 return -ERESTARTSYS;
1130 ret = -ENODEV; 1124
1125 ret = pwc_test_n_set_capt_file(pdev, file);
1126 if (ret)
1131 goto leave; 1127 goto leave;
1132 }
1133 1128
1134 if (pdev->iso_init) { 1129 if (pdev->vb_queue.streaming) {
1135 ret = -EBUSY; 1130 ret = -EBUSY;
1136 goto leave; 1131 goto leave;
1137 } 1132 }
@@ -1142,7 +1137,7 @@ static int pwc_s_parm(struct file *file, void *fh,
1142 pwc_g_parm(file, fh, parm); 1137 pwc_g_parm(file, fh, parm);
1143 1138
1144leave: 1139leave:
1145 mutex_unlock(&pdev->udevlock); 1140 mutex_unlock(&pdev->vb_queue_lock);
1146 return ret; 1141 return ret;
1147} 1142}
1148 1143
@@ -1166,4 +1161,6 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
1166 .vidioc_enum_frameintervals = pwc_enum_frameintervals, 1161 .vidioc_enum_frameintervals = pwc_enum_frameintervals,
1167 .vidioc_g_parm = pwc_g_parm, 1162 .vidioc_g_parm = pwc_g_parm,
1168 .vidioc_s_parm = pwc_s_parm, 1163 .vidioc_s_parm = pwc_s_parm,
1164 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1165 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1169}; 1166};
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index e4d4d711dd1f..d6b5b216b9d6 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -221,9 +221,17 @@ struct pwc_device
221 struct video_device vdev; 221 struct video_device vdev;
222 struct v4l2_device v4l2_dev; 222 struct v4l2_device v4l2_dev;
223 223
224 /* Pointer to our usb_device, may be NULL after unplug */ 224 /* videobuf2 queue and queued buffers list */
225 struct usb_device *udev; 225 struct vb2_queue vb_queue;
226 struct mutex udevlock; 226 struct list_head queued_bufs;
227 spinlock_t queued_bufs_lock; /* Protects queued_bufs */
228
229 /* Note if taking both locks v4l2_lock must always be locked first! */
230 struct mutex v4l2_lock; /* Protects everything else */
231 struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
232
233 /* Pointer to our usb_device, will be NULL after unplug */
234 struct usb_device *udev; /* Both mutexes most be hold when setting! */
227 235
228 /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ 236 /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
229 int type; 237 int type;
@@ -232,7 +240,6 @@ struct pwc_device
232 240
233 /*** Video data ***/ 241 /*** Video data ***/
234 struct file *capt_file; /* file doing video capture */ 242 struct file *capt_file; /* file doing video capture */
235 struct mutex capt_file_lock;
236 int vendpoint; /* video isoc endpoint */ 243 int vendpoint; /* video isoc endpoint */
237 int vcinterface; /* video control interface */ 244 int vcinterface; /* video control interface */
238 int valternate; /* alternate interface needed */ 245 int valternate; /* alternate interface needed */
@@ -251,12 +258,6 @@ struct pwc_device
251 unsigned char *ctrl_buf; 258 unsigned char *ctrl_buf;
252 259
253 struct urb *urbs[MAX_ISO_BUFS]; 260 struct urb *urbs[MAX_ISO_BUFS];
254 char iso_init;
255
256 /* videobuf2 queue and queued buffers list */
257 struct vb2_queue vb_queue;
258 struct list_head queued_bufs;
259 spinlock_t queued_bufs_lock;
260 261
261 /* 262 /*
262 * Frame currently being filled, this only gets touched by the 263 * Frame currently being filled, this only gets touched by the
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 5a413f4427e0..9c21e01f2c24 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -241,15 +241,10 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
241 unsigned int *size) 241 unsigned int *size)
242{ 242{
243 struct soc_camera_device *icd = vq->priv_data; 243 struct soc_camera_device *icd = vq->priv_data;
244 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
245 icd->current_fmt->host_fmt);
246
247 if (bytes_per_line < 0)
248 return bytes_per_line;
249 244
250 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size); 245 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
251 246
252 *size = bytes_per_line * icd->user_height; 247 *size = icd->sizeimage;
253 248
254 if (0 == *count) 249 if (0 == *count)
255 *count = 32; 250 *count = 32;
@@ -435,11 +430,6 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
435 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 430 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
436 int ret; 431 int ret;
437 int size_y, size_u = 0, size_v = 0; 432 int size_y, size_u = 0, size_v = 0;
438 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
439 icd->current_fmt->host_fmt);
440
441 if (bytes_per_line < 0)
442 return bytes_per_line;
443 433
444 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 434 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
445 vb, vb->baddr, vb->bsize); 435 vb, vb->baddr, vb->bsize);
@@ -474,7 +464,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
474 vb->state = VIDEOBUF_NEEDS_INIT; 464 vb->state = VIDEOBUF_NEEDS_INIT;
475 } 465 }
476 466
477 vb->size = bytes_per_line * vb->height; 467 vb->size = icd->sizeimage;
478 if (0 != vb->baddr && vb->bsize < vb->size) { 468 if (0 != vb->baddr && vb->bsize < vb->size) {
479 ret = -EINVAL; 469 ret = -EINVAL;
480 goto out; 470 goto out;
@@ -1244,6 +1234,7 @@ static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
1244 .bits_per_sample = 8, 1234 .bits_per_sample = 8,
1245 .packing = SOC_MBUS_PACKING_2X8_PADHI, 1235 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1246 .order = SOC_MBUS_ORDER_LE, 1236 .order = SOC_MBUS_ORDER_LE,
1237 .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_U_V,
1247 }, 1238 },
1248}; 1239};
1249 1240
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 4894cbb1c547..01c2179f0520 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -634,13 +634,11 @@ static void s2255_fillbuff(struct s2255_channel *channel,
634 const char *tmpbuf; 634 const char *tmpbuf;
635 char *vbuf = videobuf_to_vmalloc(&buf->vb); 635 char *vbuf = videobuf_to_vmalloc(&buf->vb);
636 unsigned long last_frame; 636 unsigned long last_frame;
637 struct s2255_framei *frm;
638 637
639 if (!vbuf) 638 if (!vbuf)
640 return; 639 return;
641 last_frame = channel->last_frame; 640 last_frame = channel->last_frame;
642 if (last_frame != -1) { 641 if (last_frame != -1) {
643 frm = &channel->buffer.frame[last_frame];
644 tmpbuf = 642 tmpbuf =
645 (const char *)channel->buffer.frame[last_frame].lpvbits; 643 (const char *)channel->buffer.frame[last_frame].lpvbits;
646 switch (buf->fmt->fourcc) { 644 switch (buf->fmt->fourcc) {
@@ -987,7 +985,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
987 struct videobuf_queue *q = &fh->vb_vidq; 985 struct videobuf_queue *q = &fh->vb_vidq;
988 struct s2255_mode mode; 986 struct s2255_mode mode;
989 int ret; 987 int ret;
990 int norm;
991 988
992 ret = vidioc_try_fmt_vid_cap(file, fh, f); 989 ret = vidioc_try_fmt_vid_cap(file, fh, f);
993 990
@@ -1018,7 +1015,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1018 channel->height = f->fmt.pix.height; 1015 channel->height = f->fmt.pix.height;
1019 fh->vb_vidq.field = f->fmt.pix.field; 1016 fh->vb_vidq.field = f->fmt.pix.field;
1020 fh->type = f->type; 1017 fh->type = f->type;
1021 norm = norm_minw(&channel->vdev);
1022 if (channel->width > norm_minw(&channel->vdev)) { 1018 if (channel->width > norm_minw(&channel->vdev)) {
1023 if (channel->height > norm_minh(&channel->vdev)) { 1019 if (channel->height > norm_minh(&channel->vdev)) {
1024 if (channel->cap_parm.capturemode & 1020 if (channel->cap_parm.capturemode &
@@ -1826,8 +1822,7 @@ static void s2255_destroy(struct s2255_dev *dev)
1826 usb_free_urb(dev->fw_data->fw_urb); 1822 usb_free_urb(dev->fw_data->fw_urb);
1827 dev->fw_data->fw_urb = NULL; 1823 dev->fw_data->fw_urb = NULL;
1828 } 1824 }
1829 if (dev->fw_data->fw) 1825 release_firmware(dev->fw_data->fw);
1830 release_firmware(dev->fw_data->fw);
1831 kfree(dev->fw_data->pfw_data); 1826 kfree(dev->fw_data->pfw_data);
1832 kfree(dev->fw_data); 1827 kfree(dev->fw_data);
1833 /* reset the DSP so firmware can be reloaded next time */ 1828 /* reset the DSP so firmware can be reloaded next time */
@@ -1949,6 +1944,10 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
1949 /* register 4 video devices */ 1944 /* register 4 video devices */
1950 channel->vdev = template; 1945 channel->vdev = template;
1951 channel->vdev.lock = &dev->lock; 1946 channel->vdev.lock = &dev->lock;
1947 /* Locking in file operations other than ioctl should be done
1948 by the driver, not the V4L2 core.
1949 This driver needs auditing so that this flag can be removed. */
1950 set_bit(V4L2_FL_LOCK_ALL_FOPS, &channel->vdev.flags);
1952 channel->vdev.v4l2_dev = &dev->v4l2_dev; 1951 channel->vdev.v4l2_dev = &dev->v4l2_dev;
1953 video_set_drvdata(&channel->vdev, channel); 1952 video_set_drvdata(&channel->vdev, channel);
1954 if (video_nr == -1) 1953 if (video_nr == -1)
diff --git a/drivers/media/video/s5p-fimc/Kconfig b/drivers/media/video/s5p-fimc/Kconfig
new file mode 100644
index 000000000000..a564f7eeb064
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/Kconfig
@@ -0,0 +1,48 @@
1
2config VIDEO_SAMSUNG_S5P_FIMC
3 bool "Samsung S5P/EXYNOS SoC camera interface driver (experimental)"
4 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PLAT_S5P && PM_RUNTIME
5 depends on EXPERIMENTAL
6 help
7 Say Y here to enable camera host interface devices for
8 Samsung S5P and EXYNOS SoC series.
9
10if VIDEO_SAMSUNG_S5P_FIMC
11
12config VIDEO_S5P_FIMC
13 tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
14 depends on I2C
15 select VIDEOBUF2_DMA_CONTIG
16 select V4L2_MEM2MEM_DEV
17 help
18 This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
19 interface and video postprocessor (FIMC and FIMC-LITE) devices.
20
21 To compile this driver as a module, choose M here: the
22 module will be called s5p-fimc.
23
24config VIDEO_S5P_MIPI_CSIS
25 tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
26 depends on REGULATOR
27 help
28 This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
29 receiver (MIPI-CSIS) devices.
30
31 To compile this driver as a module, choose M here: the
32 module will be called s5p-csis.
33
34if ARCH_EXYNOS
35
36config VIDEO_EXYNOS_FIMC_LITE
37 tristate "EXYNOS FIMC-LITE camera interface driver"
38 depends on I2C
39 select VIDEOBUF2_DMA_CONTIG
40 help
41 This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
42 host interface.
43
44 To compile this driver as a module, choose M here: the
45 module will be called exynos-fimc-lite.
46endif
47
48endif # VIDEO_SAMSUNG_S5P_FIMC
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/video/s5p-fimc/Makefile
index 33dec7f890e7..46485143e1ca 100644
--- a/drivers/media/video/s5p-fimc/Makefile
+++ b/drivers/media/video/s5p-fimc/Makefile
@@ -1,5 +1,7 @@
1s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-capture.o fimc-mdevice.o 1s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o fimc-mdevice.o
2exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
2s5p-csis-objs := mipi-csis.o 3s5p-csis-objs := mipi-csis.o
3 4
4obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o 5obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
5obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc.o 6obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o
7obj-$(CONFIG_VIDEO_S5P_FIMC) += s5p-fimc.o
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 7e9b2c612b03..354574591908 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver 2 * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
3 * 3 *
4 * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com> 5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -29,20 +29,22 @@
29 29
30#include "fimc-mdevice.h" 30#include "fimc-mdevice.h"
31#include "fimc-core.h" 31#include "fimc-core.h"
32#include "fimc-reg.h"
32 33
33static int fimc_init_capture(struct fimc_dev *fimc) 34static int fimc_capture_hw_init(struct fimc_dev *fimc)
34{ 35{
35 struct fimc_ctx *ctx = fimc->vid_cap.ctx; 36 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
37 struct fimc_pipeline *p = &fimc->pipeline;
36 struct fimc_sensor_info *sensor; 38 struct fimc_sensor_info *sensor;
37 unsigned long flags; 39 unsigned long flags;
38 int ret = 0; 40 int ret = 0;
39 41
40 if (fimc->pipeline.sensor == NULL || ctx == NULL) 42 if (p->subdevs[IDX_SENSOR] == NULL || ctx == NULL)
41 return -ENXIO; 43 return -ENXIO;
42 if (ctx->s_frame.fmt == NULL) 44 if (ctx->s_frame.fmt == NULL)
43 return -EINVAL; 45 return -EINVAL;
44 46
45 sensor = v4l2_get_subdev_hostdata(fimc->pipeline.sensor); 47 sensor = v4l2_get_subdev_hostdata(p->subdevs[IDX_SENSOR]);
46 48
47 spin_lock_irqsave(&fimc->slock, flags); 49 spin_lock_irqsave(&fimc->slock, flags);
48 fimc_prepare_dma_offset(ctx, &ctx->d_frame); 50 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
@@ -60,7 +62,7 @@ static int fimc_init_capture(struct fimc_dev *fimc)
60 fimc_hw_set_mainscaler(ctx); 62 fimc_hw_set_mainscaler(ctx);
61 fimc_hw_set_target_format(ctx); 63 fimc_hw_set_target_format(ctx);
62 fimc_hw_set_rotation(ctx); 64 fimc_hw_set_rotation(ctx);
63 fimc_hw_set_effect(ctx, false); 65 fimc_hw_set_effect(ctx);
64 fimc_hw_set_output_path(ctx); 66 fimc_hw_set_output_path(ctx);
65 fimc_hw_set_out_dma(ctx); 67 fimc_hw_set_out_dma(ctx);
66 if (fimc->variant->has_alpha) 68 if (fimc->variant->has_alpha)
@@ -71,6 +73,14 @@ static int fimc_init_capture(struct fimc_dev *fimc)
71 return ret; 73 return ret;
72} 74}
73 75
76/*
77 * Reinitialize the driver so it is ready to start the streaming again.
78 * Set fimc->state to indicate stream off and the hardware shut down state.
79 * If not suspending (@suspend is false), return any buffers to videobuf2.
80 * Otherwise put any owned buffers onto the pending buffers queue, so they
81 * can be re-spun when the device is being resumed. Also perform FIMC
82 * software reset and disable streaming on the whole pipeline if required.
83 */
74static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend) 84static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
75{ 85{
76 struct fimc_vid_cap *cap = &fimc->vid_cap; 86 struct fimc_vid_cap *cap = &fimc->vid_cap;
@@ -83,7 +93,9 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
83 93
84 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT | 94 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
85 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM); 95 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
86 if (!suspend) 96 if (suspend)
97 fimc->state |= (1 << ST_CAPT_SUSPENDED);
98 else
87 fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED); 99 fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);
88 100
89 /* Release unused buffers */ 101 /* Release unused buffers */
@@ -99,7 +111,6 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
99 else 111 else
100 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); 112 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
101 } 113 }
102 set_bit(ST_CAPT_SUSPENDED, &fimc->state);
103 114
104 fimc_hw_reset(fimc); 115 fimc_hw_reset(fimc);
105 cap->buf_index = 0; 116 cap->buf_index = 0;
@@ -107,7 +118,7 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
107 spin_unlock_irqrestore(&fimc->slock, flags); 118 spin_unlock_irqrestore(&fimc->slock, flags);
108 119
109 if (streaming) 120 if (streaming)
110 return fimc_pipeline_s_stream(fimc, 0); 121 return fimc_pipeline_s_stream(&fimc->pipeline, 0);
111 else 122 else
112 return 0; 123 return 0;
113} 124}
@@ -138,32 +149,96 @@ static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
138 * spinlock held. It updates the camera pixel crop, rotation and 149 * spinlock held. It updates the camera pixel crop, rotation and
139 * image flip in H/W. 150 * image flip in H/W.
140 */ 151 */
141int fimc_capture_config_update(struct fimc_ctx *ctx) 152static int fimc_capture_config_update(struct fimc_ctx *ctx)
142{ 153{
143 struct fimc_dev *fimc = ctx->fimc_dev; 154 struct fimc_dev *fimc = ctx->fimc_dev;
144 int ret; 155 int ret;
145 156
146 if (!test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
147 return 0;
148
149 spin_lock(&ctx->slock);
150 fimc_hw_set_camera_offset(fimc, &ctx->s_frame); 157 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
158
151 ret = fimc_set_scaler_info(ctx); 159 ret = fimc_set_scaler_info(ctx);
152 if (ret == 0) { 160 if (ret)
153 fimc_hw_set_prescaler(ctx); 161 return ret;
154 fimc_hw_set_mainscaler(ctx); 162
155 fimc_hw_set_target_format(ctx); 163 fimc_hw_set_prescaler(ctx);
156 fimc_hw_set_rotation(ctx); 164 fimc_hw_set_mainscaler(ctx);
157 fimc_prepare_dma_offset(ctx, &ctx->d_frame); 165 fimc_hw_set_target_format(ctx);
158 fimc_hw_set_out_dma(ctx); 166 fimc_hw_set_rotation(ctx);
159 if (fimc->variant->has_alpha) 167 fimc_hw_set_effect(ctx);
160 fimc_hw_set_rgb_alpha(ctx); 168 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
161 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state); 169 fimc_hw_set_out_dma(ctx);
162 } 170 if (fimc->variant->has_alpha)
163 spin_unlock(&ctx->slock); 171 fimc_hw_set_rgb_alpha(ctx);
172
173 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
164 return ret; 174 return ret;
165} 175}
166 176
177void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
178{
179 struct fimc_vid_cap *cap = &fimc->vid_cap;
180 struct fimc_vid_buffer *v_buf;
181 struct timeval *tv;
182 struct timespec ts;
183
184 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
185 wake_up(&fimc->irq_queue);
186 goto done;
187 }
188
189 if (!list_empty(&cap->active_buf_q) &&
190 test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
191 ktime_get_real_ts(&ts);
192
193 v_buf = fimc_active_queue_pop(cap);
194
195 tv = &v_buf->vb.v4l2_buf.timestamp;
196 tv->tv_sec = ts.tv_sec;
197 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
198 v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
199
200 vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
201 }
202
203 if (!list_empty(&cap->pending_buf_q)) {
204
205 v_buf = fimc_pending_queue_pop(cap);
206 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
207 v_buf->index = cap->buf_index;
208
209 /* Move the buffer to the capture active queue */
210 fimc_active_queue_add(cap, v_buf);
211
212 dbg("next frame: %d, done frame: %d",
213 fimc_hw_get_frame_index(fimc), v_buf->index);
214
215 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
216 cap->buf_index = 0;
217 }
218
219 if (cap->active_buf_cnt == 0) {
220 if (deq_buf)
221 clear_bit(ST_CAPT_RUN, &fimc->state);
222
223 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
224 cap->buf_index = 0;
225 } else {
226 set_bit(ST_CAPT_RUN, &fimc->state);
227 }
228
229 if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
230 fimc_capture_config_update(cap->ctx);
231done:
232 if (cap->active_buf_cnt == 1) {
233 fimc_deactivate_capture(fimc);
234 clear_bit(ST_CAPT_STREAM, &fimc->state);
235 }
236
237 dbg("frame: %d, active_buf_cnt: %d",
238 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
239}
240
241
167static int start_streaming(struct vb2_queue *q, unsigned int count) 242static int start_streaming(struct vb2_queue *q, unsigned int count)
168{ 243{
169 struct fimc_ctx *ctx = q->drv_priv; 244 struct fimc_ctx *ctx = q->drv_priv;
@@ -174,9 +249,11 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
174 249
175 vid_cap->frame_count = 0; 250 vid_cap->frame_count = 0;
176 251
177 ret = fimc_init_capture(fimc); 252 ret = fimc_capture_hw_init(fimc);
178 if (ret) 253 if (ret) {
179 goto error; 254 fimc_capture_state_cleanup(fimc, false);
255 return ret;
256 }
180 257
181 set_bit(ST_CAPT_PEND, &fimc->state); 258 set_bit(ST_CAPT_PEND, &fimc->state);
182 259
@@ -187,13 +264,10 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
187 fimc_activate_capture(ctx); 264 fimc_activate_capture(ctx);
188 265
189 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) 266 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
190 fimc_pipeline_s_stream(fimc, 1); 267 fimc_pipeline_s_stream(&fimc->pipeline, 1);
191 } 268 }
192 269
193 return 0; 270 return 0;
194error:
195 fimc_capture_state_cleanup(fimc, false);
196 return ret;
197} 271}
198 272
199static int stop_streaming(struct vb2_queue *q) 273static int stop_streaming(struct vb2_queue *q)
@@ -214,7 +288,7 @@ int fimc_capture_suspend(struct fimc_dev *fimc)
214 int ret = fimc_stop_capture(fimc, suspend); 288 int ret = fimc_stop_capture(fimc, suspend);
215 if (ret) 289 if (ret)
216 return ret; 290 return ret;
217 return fimc_pipeline_shutdown(fimc); 291 return fimc_pipeline_shutdown(&fimc->pipeline);
218} 292}
219 293
220static void buffer_queue(struct vb2_buffer *vb); 294static void buffer_queue(struct vb2_buffer *vb);
@@ -230,9 +304,9 @@ int fimc_capture_resume(struct fimc_dev *fimc)
230 304
231 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); 305 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
232 vid_cap->buf_index = 0; 306 vid_cap->buf_index = 0;
233 fimc_pipeline_initialize(fimc, &fimc->vid_cap.vfd->entity, 307 fimc_pipeline_initialize(&fimc->pipeline, &vid_cap->vfd->entity,
234 false); 308 false);
235 fimc_init_capture(fimc); 309 fimc_capture_hw_init(fimc);
236 310
237 clear_bit(ST_CAPT_SUSPENDED, &fimc->state); 311 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
238 312
@@ -347,7 +421,7 @@ static void buffer_queue(struct vb2_buffer *vb)
347 spin_unlock_irqrestore(&fimc->slock, flags); 421 spin_unlock_irqrestore(&fimc->slock, flags);
348 422
349 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state)) 423 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
350 fimc_pipeline_s_stream(fimc, 1); 424 fimc_pipeline_s_stream(&fimc->pipeline, 1);
351 return; 425 return;
352 } 426 }
353 spin_unlock_irqrestore(&fimc->slock, flags); 427 spin_unlock_irqrestore(&fimc->slock, flags);
@@ -389,15 +463,15 @@ int fimc_capture_ctrls_create(struct fimc_dev *fimc)
389 463
390 if (WARN_ON(vid_cap->ctx == NULL)) 464 if (WARN_ON(vid_cap->ctx == NULL))
391 return -ENXIO; 465 return -ENXIO;
392 if (vid_cap->ctx->ctrls_rdy) 466 if (vid_cap->ctx->ctrls.ready)
393 return 0; 467 return 0;
394 468
395 ret = fimc_ctrls_create(vid_cap->ctx); 469 ret = fimc_ctrls_create(vid_cap->ctx);
396 if (ret || vid_cap->user_subdev_api) 470 if (ret || vid_cap->user_subdev_api || !vid_cap->ctx->ctrls.ready)
397 return ret; 471 return ret;
398 472
399 return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrl_handler, 473 return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
400 fimc->pipeline.sensor->ctrl_handler); 474 fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler);
401} 475}
402 476
403static int fimc_capture_set_default_format(struct fimc_dev *fimc); 477static int fimc_capture_set_default_format(struct fimc_dev *fimc);
@@ -420,7 +494,7 @@ static int fimc_capture_open(struct file *file)
420 pm_runtime_get_sync(&fimc->pdev->dev); 494 pm_runtime_get_sync(&fimc->pdev->dev);
421 495
422 if (++fimc->vid_cap.refcnt == 1) { 496 if (++fimc->vid_cap.refcnt == 1) {
423 ret = fimc_pipeline_initialize(fimc, 497 ret = fimc_pipeline_initialize(&fimc->pipeline,
424 &fimc->vid_cap.vfd->entity, true); 498 &fimc->vid_cap.vfd->entity, true);
425 if (ret < 0) { 499 if (ret < 0) {
426 dev_err(&fimc->pdev->dev, 500 dev_err(&fimc->pdev->dev,
@@ -448,7 +522,7 @@ static int fimc_capture_close(struct file *file)
448 if (--fimc->vid_cap.refcnt == 0) { 522 if (--fimc->vid_cap.refcnt == 0) {
449 clear_bit(ST_CAPT_BUSY, &fimc->state); 523 clear_bit(ST_CAPT_BUSY, &fimc->state);
450 fimc_stop_capture(fimc, false); 524 fimc_stop_capture(fimc, false);
451 fimc_pipeline_shutdown(fimc); 525 fimc_pipeline_shutdown(&fimc->pipeline);
452 clear_bit(ST_CAPT_SUSPENDED, &fimc->state); 526 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
453 } 527 }
454 528
@@ -495,7 +569,7 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
495{ 569{
496 bool rotation = ctx->rotation == 90 || ctx->rotation == 270; 570 bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
497 struct fimc_dev *fimc = ctx->fimc_dev; 571 struct fimc_dev *fimc = ctx->fimc_dev;
498 struct samsung_fimc_variant *var = fimc->variant; 572 struct fimc_variant *var = fimc->variant;
499 struct fimc_pix_limit *pl = var->pix_limit; 573 struct fimc_pix_limit *pl = var->pix_limit;
500 struct fimc_frame *dst = &ctx->d_frame; 574 struct fimc_frame *dst = &ctx->d_frame;
501 u32 depth, min_w, max_w, min_h, align_h = 3; 575 u32 depth, min_w, max_w, min_h, align_h = 3;
@@ -537,8 +611,13 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
537 } 611 }
538 /* Apply the scaler and the output DMA constraints */ 612 /* Apply the scaler and the output DMA constraints */
539 max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; 613 max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w;
540 min_w = ctx->state & FIMC_DST_CROP ? dst->width : var->min_out_pixsize; 614 if (ctx->state & FIMC_COMPOSE) {
541 min_h = ctx->state & FIMC_DST_CROP ? dst->height : var->min_out_pixsize; 615 min_w = dst->offs_h + dst->width;
616 min_h = dst->offs_v + dst->height;
617 } else {
618 min_w = var->min_out_pixsize;
619 min_h = var->min_out_pixsize;
620 }
542 if (var->min_vsize_align == 1 && !rotation) 621 if (var->min_vsize_align == 1 && !rotation)
543 align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; 622 align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1;
544 623
@@ -556,12 +635,13 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
556 return ffmt; 635 return ffmt;
557} 636}
558 637
559static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r, 638static void fimc_capture_try_selection(struct fimc_ctx *ctx,
560 int pad) 639 struct v4l2_rect *r,
640 int target)
561{ 641{
562 bool rotate = ctx->rotation == 90 || ctx->rotation == 270; 642 bool rotate = ctx->rotation == 90 || ctx->rotation == 270;
563 struct fimc_dev *fimc = ctx->fimc_dev; 643 struct fimc_dev *fimc = ctx->fimc_dev;
564 struct samsung_fimc_variant *var = fimc->variant; 644 struct fimc_variant *var = fimc->variant;
565 struct fimc_pix_limit *pl = var->pix_limit; 645 struct fimc_pix_limit *pl = var->pix_limit;
566 struct fimc_frame *sink = &ctx->s_frame; 646 struct fimc_frame *sink = &ctx->s_frame;
567 u32 max_w, max_h, min_w = 0, min_h = 0, min_sz; 647 u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
@@ -575,7 +655,7 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r,
575 r->left = r->top = 0; 655 r->left = r->top = 0;
576 return; 656 return;
577 } 657 }
578 if (pad == FIMC_SD_PAD_SOURCE) { 658 if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) {
579 if (ctx->rotation != 90 && ctx->rotation != 270) 659 if (ctx->rotation != 90 && ctx->rotation != 270)
580 align_h = 1; 660 align_h = 1;
581 max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3)); 661 max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3));
@@ -589,8 +669,7 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r,
589 max_sc_h = max_sc_v = 1; 669 max_sc_h = max_sc_v = 1;
590 } 670 }
591 /* 671 /*
592 * For the crop rectangle at source pad the following constraints 672 * For the compose rectangle the following constraints must be met:
593 * must be met:
594 * - it must fit in the sink pad format rectangle (f_width/f_height); 673 * - it must fit in the sink pad format rectangle (f_width/f_height);
595 * - maximum downscaling ratio is 64; 674 * - maximum downscaling ratio is 64;
596 * - maximum crop size depends if the rotator is used or not; 675 * - maximum crop size depends if the rotator is used or not;
@@ -602,7 +681,8 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r,
602 rotate ? pl->out_rot_en_w : pl->out_rot_dis_w, 681 rotate ? pl->out_rot_en_w : pl->out_rot_dis_w,
603 rotate ? sink->f_height : sink->f_width); 682 rotate ? sink->f_height : sink->f_width);
604 max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height); 683 max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
605 if (pad == FIMC_SD_PAD_SOURCE) { 684
685 if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) {
606 min_w = min_t(u32, max_w, sink->f_width / max_sc_h); 686 min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
607 min_h = min_t(u32, max_h, sink->f_height / max_sc_v); 687 min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
608 if (rotate) { 688 if (rotate) {
@@ -613,13 +693,13 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r,
613 v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1, 693 v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1,
614 &r->height, min_h, max_h, align_h, 694 &r->height, min_h, max_h, align_h,
615 align_sz); 695 align_sz);
616 /* Adjust left/top if cropping rectangle is out of bounds */ 696 /* Adjust left/top if crop/compose rectangle is out of bounds */
617 r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width); 697 r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width);
618 r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height); 698 r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height);
619 r->left = round_down(r->left, var->hor_offs_align); 699 r->left = round_down(r->left, var->hor_offs_align);
620 700
621 dbg("pad%d: (%d,%d)/%dx%d, sink fmt: %dx%d", 701 dbg("target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d",
622 pad, r->left, r->top, r->width, r->height, 702 target, r->left, r->top, r->width, r->height,
623 sink->f_width, sink->f_height); 703 sink->f_width, sink->f_height);
624} 704}
625 705
@@ -669,8 +749,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
669 bool set) 749 bool set)
670{ 750{
671 struct fimc_dev *fimc = ctx->fimc_dev; 751 struct fimc_dev *fimc = ctx->fimc_dev;
672 struct v4l2_subdev *sd = fimc->pipeline.sensor; 752 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
673 struct v4l2_subdev *csis = fimc->pipeline.csis; 753 struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
674 struct v4l2_subdev_format sfmt; 754 struct v4l2_subdev_format sfmt;
675 struct v4l2_mbus_framefmt *mf = &sfmt.format; 755 struct v4l2_mbus_framefmt *mf = &sfmt.format;
676 struct fimc_fmt *ffmt = NULL; 756 struct fimc_fmt *ffmt = NULL;
@@ -851,7 +931,7 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
851 931
852 set_frame_bounds(ff, pix->width, pix->height); 932 set_frame_bounds(ff, pix->width, pix->height);
853 /* Reset the composition rectangle if not yet configured */ 933 /* Reset the composition rectangle if not yet configured */
854 if (!(ctx->state & FIMC_DST_CROP)) 934 if (!(ctx->state & FIMC_COMPOSE))
855 set_frame_crop(ff, 0, 0, pix->width, pix->height); 935 set_frame_crop(ff, 0, 0, pix->width, pix->height);
856 936
857 fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color)); 937 fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color));
@@ -878,7 +958,7 @@ static int fimc_cap_enum_input(struct file *file, void *priv,
878 struct v4l2_input *i) 958 struct v4l2_input *i)
879{ 959{
880 struct fimc_dev *fimc = video_drvdata(file); 960 struct fimc_dev *fimc = video_drvdata(file);
881 struct v4l2_subdev *sd = fimc->pipeline.sensor; 961 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
882 962
883 if (i->index != 0) 963 if (i->index != 0)
884 return -EINVAL; 964 return -EINVAL;
@@ -927,7 +1007,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
927 if (!(pad->flags & MEDIA_PAD_FL_SINK)) 1007 if (!(pad->flags & MEDIA_PAD_FL_SINK))
928 break; 1008 break;
929 /* Don't call FIMC subdev operation to avoid nested locking */ 1009 /* Don't call FIMC subdev operation to avoid nested locking */
930 if (sd == fimc->vid_cap.subdev) { 1010 if (sd == &fimc->vid_cap.subdev) {
931 struct fimc_frame *ff = &vid_cap->ctx->s_frame; 1011 struct fimc_frame *ff = &vid_cap->ctx->s_frame;
932 sink_fmt.format.width = ff->f_width; 1012 sink_fmt.format.width = ff->f_width;
933 sink_fmt.format.height = ff->f_height; 1013 sink_fmt.format.height = ff->f_height;
@@ -970,7 +1050,8 @@ static int fimc_cap_streamon(struct file *file, void *priv,
970 if (fimc_capture_active(fimc)) 1050 if (fimc_capture_active(fimc))
971 return -EBUSY; 1051 return -EBUSY;
972 1052
973 media_entity_pipeline_start(&p->sensor->entity, p->pipe); 1053 media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity,
1054 p->m_pipeline);
974 1055
975 if (fimc->vid_cap.user_subdev_api) { 1056 if (fimc->vid_cap.user_subdev_api) {
976 ret = fimc_pipeline_validate(fimc); 1057 ret = fimc_pipeline_validate(fimc);
@@ -984,7 +1065,7 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
984 enum v4l2_buf_type type) 1065 enum v4l2_buf_type type)
985{ 1066{
986 struct fimc_dev *fimc = video_drvdata(file); 1067 struct fimc_dev *fimc = video_drvdata(file);
987 struct v4l2_subdev *sd = fimc->pipeline.sensor; 1068 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
988 int ret; 1069 int ret;
989 1070
990 ret = vb2_streamoff(&fimc->vid_cap.vbq, type); 1071 ret = vb2_streamoff(&fimc->vid_cap.vbq, type);
@@ -1100,29 +1181,18 @@ static int fimc_cap_s_selection(struct file *file, void *fh,
1100 struct v4l2_rect rect = s->r; 1181 struct v4l2_rect rect = s->r;
1101 struct fimc_frame *f; 1182 struct fimc_frame *f;
1102 unsigned long flags; 1183 unsigned long flags;
1103 unsigned int pad;
1104 1184
1105 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1185 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1106 return -EINVAL; 1186 return -EINVAL;
1107 1187
1108 switch (s->target) { 1188 if (s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE)
1109 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1110 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1111 case V4L2_SEL_TGT_COMPOSE_ACTIVE:
1112 f = &ctx->d_frame; 1189 f = &ctx->d_frame;
1113 pad = FIMC_SD_PAD_SOURCE; 1190 else if (s->target == V4L2_SEL_TGT_CROP_ACTIVE)
1114 break;
1115 case V4L2_SEL_TGT_CROP_BOUNDS:
1116 case V4L2_SEL_TGT_CROP_DEFAULT:
1117 case V4L2_SEL_TGT_CROP_ACTIVE:
1118 f = &ctx->s_frame; 1191 f = &ctx->s_frame;
1119 pad = FIMC_SD_PAD_SINK; 1192 else
1120 break;
1121 default:
1122 return -EINVAL; 1193 return -EINVAL;
1123 }
1124 1194
1125 fimc_capture_try_crop(ctx, &rect, pad); 1195 fimc_capture_try_selection(ctx, &rect, s->target);
1126 1196
1127 if (s->flags & V4L2_SEL_FLAG_LE && 1197 if (s->flags & V4L2_SEL_FLAG_LE &&
1128 !enclosed_rectangle(&rect, &s->r)) 1198 !enclosed_rectangle(&rect, &s->r))
@@ -1243,7 +1313,7 @@ void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1243 struct fimc_vid_buffer, list); 1313 struct fimc_vid_buffer, list);
1244 vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg)); 1314 vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
1245 } 1315 }
1246 fimc_capture_irq_handler(fimc, true); 1316 fimc_capture_irq_handler(fimc, 1);
1247 fimc_deactivate_capture(fimc); 1317 fimc_deactivate_capture(fimc);
1248 spin_unlock_irqrestore(&fimc->slock, irq_flags); 1318 spin_unlock_irqrestore(&fimc->slock, irq_flags);
1249 } 1319 }
@@ -1334,77 +1404,122 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1334 ff->fmt = ffmt; 1404 ff->fmt = ffmt;
1335 1405
1336 /* Reset the crop rectangle if required. */ 1406 /* Reset the crop rectangle if required. */
1337 if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_DST_CROP))) 1407 if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE)))
1338 set_frame_crop(ff, 0, 0, mf->width, mf->height); 1408 set_frame_crop(ff, 0, 0, mf->width, mf->height);
1339 1409
1340 if (fmt->pad == FIMC_SD_PAD_SINK) 1410 if (fmt->pad == FIMC_SD_PAD_SINK)
1341 ctx->state &= ~FIMC_DST_CROP; 1411 ctx->state &= ~FIMC_COMPOSE;
1342 mutex_unlock(&fimc->lock); 1412 mutex_unlock(&fimc->lock);
1343 return 0; 1413 return 0;
1344} 1414}
1345 1415
1346static int fimc_subdev_get_crop(struct v4l2_subdev *sd, 1416static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
1347 struct v4l2_subdev_fh *fh, 1417 struct v4l2_subdev_fh *fh,
1348 struct v4l2_subdev_crop *crop) 1418 struct v4l2_subdev_selection *sel)
1349{ 1419{
1350 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); 1420 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1351 struct fimc_ctx *ctx = fimc->vid_cap.ctx; 1421 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1352 struct v4l2_rect *r = &crop->rect; 1422 struct fimc_frame *f = &ctx->s_frame;
1353 struct fimc_frame *ff; 1423 struct v4l2_rect *r = &sel->r;
1424 struct v4l2_rect *try_sel;
1354 1425
1355 if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { 1426 if (sel->pad != FIMC_SD_PAD_SINK)
1356 crop->rect = *v4l2_subdev_get_try_crop(fh, crop->pad); 1427 return -EINVAL;
1428
1429 mutex_lock(&fimc->lock);
1430
1431 switch (sel->target) {
1432 case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS:
1433 f = &ctx->d_frame;
1434 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
1435 r->width = f->o_width;
1436 r->height = f->o_height;
1437 r->left = 0;
1438 r->top = 0;
1439 mutex_unlock(&fimc->lock);
1357 return 0; 1440 return 0;
1441
1442 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1443 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1444 break;
1445 case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
1446 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1447 f = &ctx->d_frame;
1448 break;
1449 default:
1450 mutex_unlock(&fimc->lock);
1451 return -EINVAL;
1358 } 1452 }
1359 ff = crop->pad == FIMC_SD_PAD_SINK ?
1360 &ctx->s_frame : &ctx->d_frame;
1361 1453
1362 mutex_lock(&fimc->lock); 1454 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1363 r->left = ff->offs_h; 1455 sel->r = *try_sel;
1364 r->top = ff->offs_v; 1456 } else {
1365 r->width = ff->width; 1457 r->left = f->offs_h;
1366 r->height = ff->height; 1458 r->top = f->offs_v;
1367 mutex_unlock(&fimc->lock); 1459 r->width = f->width;
1460 r->height = f->height;
1461 }
1368 1462
1369 dbg("ff:%p, pad%d: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d", 1463 dbg("target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
1370 ff, crop->pad, r->left, r->top, r->width, r->height, 1464 sel->pad, r->left, r->top, r->width, r->height,
1371 ff->f_width, ff->f_height); 1465 f->f_width, f->f_height);
1372 1466
1467 mutex_unlock(&fimc->lock);
1373 return 0; 1468 return 0;
1374} 1469}
1375 1470
1376static int fimc_subdev_set_crop(struct v4l2_subdev *sd, 1471static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
1377 struct v4l2_subdev_fh *fh, 1472 struct v4l2_subdev_fh *fh,
1378 struct v4l2_subdev_crop *crop) 1473 struct v4l2_subdev_selection *sel)
1379{ 1474{
1380 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); 1475 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1381 struct fimc_ctx *ctx = fimc->vid_cap.ctx; 1476 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1382 struct v4l2_rect *r = &crop->rect; 1477 struct fimc_frame *f = &ctx->s_frame;
1383 struct fimc_frame *ff; 1478 struct v4l2_rect *r = &sel->r;
1479 struct v4l2_rect *try_sel;
1384 unsigned long flags; 1480 unsigned long flags;
1385 1481
1386 dbg("(%d,%d)/%dx%d", r->left, r->top, r->width, r->height); 1482 if (sel->pad != FIMC_SD_PAD_SINK)
1387 1483 return -EINVAL;
1388 ff = crop->pad == FIMC_SD_PAD_SOURCE ?
1389 &ctx->d_frame : &ctx->s_frame;
1390 1484
1391 mutex_lock(&fimc->lock); 1485 mutex_lock(&fimc->lock);
1392 fimc_capture_try_crop(ctx, r, crop->pad); 1486 fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP_ACTIVE);
1393 1487
1394 if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { 1488 switch (sel->target) {
1489 case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS:
1490 f = &ctx->d_frame;
1491 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
1492 r->width = f->o_width;
1493 r->height = f->o_height;
1494 r->left = 0;
1495 r->top = 0;
1395 mutex_unlock(&fimc->lock); 1496 mutex_unlock(&fimc->lock);
1396 *v4l2_subdev_get_try_crop(fh, crop->pad) = *r;
1397 return 0; 1497 return 0;
1498
1499 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1500 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1501 break;
1502 case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
1503 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1504 f = &ctx->d_frame;
1505 break;
1506 default:
1507 mutex_unlock(&fimc->lock);
1508 return -EINVAL;
1398 } 1509 }
1399 spin_lock_irqsave(&fimc->slock, flags);
1400 set_frame_crop(ff, r->left, r->top, r->width, r->height);
1401 if (crop->pad == FIMC_SD_PAD_SOURCE)
1402 ctx->state |= FIMC_DST_CROP;
1403 1510
1404 set_bit(ST_CAPT_APPLY_CFG, &fimc->state); 1511 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1405 spin_unlock_irqrestore(&fimc->slock, flags); 1512 *try_sel = sel->r;
1513 } else {
1514 spin_lock_irqsave(&fimc->slock, flags);
1515 set_frame_crop(f, r->left, r->top, r->width, r->height);
1516 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
1517 spin_unlock_irqrestore(&fimc->slock, flags);
1518 if (sel->target == V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL)
1519 ctx->state |= FIMC_COMPOSE;
1520 }
1406 1521
1407 dbg("pad%d: (%d,%d)/%dx%d", crop->pad, r->left, r->top, 1522 dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top,
1408 r->width, r->height); 1523 r->width, r->height);
1409 1524
1410 mutex_unlock(&fimc->lock); 1525 mutex_unlock(&fimc->lock);
@@ -1413,63 +1528,16 @@ static int fimc_subdev_set_crop(struct v4l2_subdev *sd,
1413 1528
1414static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = { 1529static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
1415 .enum_mbus_code = fimc_subdev_enum_mbus_code, 1530 .enum_mbus_code = fimc_subdev_enum_mbus_code,
1531 .get_selection = fimc_subdev_get_selection,
1532 .set_selection = fimc_subdev_set_selection,
1416 .get_fmt = fimc_subdev_get_fmt, 1533 .get_fmt = fimc_subdev_get_fmt,
1417 .set_fmt = fimc_subdev_set_fmt, 1534 .set_fmt = fimc_subdev_set_fmt,
1418 .get_crop = fimc_subdev_get_crop,
1419 .set_crop = fimc_subdev_set_crop,
1420}; 1535};
1421 1536
1422static struct v4l2_subdev_ops fimc_subdev_ops = { 1537static struct v4l2_subdev_ops fimc_subdev_ops = {
1423 .pad = &fimc_subdev_pad_ops, 1538 .pad = &fimc_subdev_pad_ops,
1424}; 1539};
1425 1540
1426static int fimc_create_capture_subdev(struct fimc_dev *fimc,
1427 struct v4l2_device *v4l2_dev)
1428{
1429 struct v4l2_subdev *sd;
1430 int ret;
1431
1432 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
1433 if (!sd)
1434 return -ENOMEM;
1435
1436 v4l2_subdev_init(sd, &fimc_subdev_ops);
1437 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1438 snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);
1439
1440 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1441 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1442 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1443 fimc->vid_cap.sd_pads, 0);
1444 if (ret)
1445 goto me_err;
1446 ret = v4l2_device_register_subdev(v4l2_dev, sd);
1447 if (ret)
1448 goto sd_err;
1449
1450 fimc->vid_cap.subdev = sd;
1451 v4l2_set_subdevdata(sd, fimc);
1452 sd->entity.ops = &fimc_sd_media_ops;
1453 return 0;
1454sd_err:
1455 media_entity_cleanup(&sd->entity);
1456me_err:
1457 kfree(sd);
1458 return ret;
1459}
1460
1461static void fimc_destroy_capture_subdev(struct fimc_dev *fimc)
1462{
1463 struct v4l2_subdev *sd = fimc->vid_cap.subdev;
1464
1465 if (!sd)
1466 return;
1467 media_entity_cleanup(&sd->entity);
1468 v4l2_device_unregister_subdev(sd);
1469 kfree(sd);
1470 fimc->vid_cap.subdev = NULL;
1471}
1472
1473/* Set default format at the sensor and host interface */ 1541/* Set default format at the sensor and host interface */
1474static int fimc_capture_set_default_format(struct fimc_dev *fimc) 1542static int fimc_capture_set_default_format(struct fimc_dev *fimc)
1475{ 1543{
@@ -1488,7 +1556,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc)
1488} 1556}
1489 1557
1490/* fimc->lock must be already initialized */ 1558/* fimc->lock must be already initialized */
1491int fimc_register_capture_device(struct fimc_dev *fimc, 1559static int fimc_register_capture_device(struct fimc_dev *fimc,
1492 struct v4l2_device *v4l2_dev) 1560 struct v4l2_device *v4l2_dev)
1493{ 1561{
1494 struct video_device *vfd; 1562 struct video_device *vfd;
@@ -1502,11 +1570,11 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
1502 return -ENOMEM; 1570 return -ENOMEM;
1503 1571
1504 ctx->fimc_dev = fimc; 1572 ctx->fimc_dev = fimc;
1505 ctx->in_path = FIMC_CAMERA; 1573 ctx->in_path = FIMC_IO_CAMERA;
1506 ctx->out_path = FIMC_DMA; 1574 ctx->out_path = FIMC_IO_DMA;
1507 ctx->state = FIMC_CTX_CAP; 1575 ctx->state = FIMC_CTX_CAP;
1508 ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); 1576 ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
1509 ctx->d_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); 1577 ctx->d_frame.fmt = ctx->s_frame.fmt;
1510 1578
1511 vfd = video_device_alloc(); 1579 vfd = video_device_alloc();
1512 if (!vfd) { 1580 if (!vfd) {
@@ -1514,8 +1582,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
1514 goto err_vd_alloc; 1582 goto err_vd_alloc;
1515 } 1583 }
1516 1584
1517 snprintf(vfd->name, sizeof(vfd->name), "%s.capture", 1585 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);
1518 dev_name(&fimc->pdev->dev));
1519 1586
1520 vfd->fops = &fimc_capture_fops; 1587 vfd->fops = &fimc_capture_fops;
1521 vfd->ioctl_ops = &fimc_capture_ioctl_ops; 1588 vfd->ioctl_ops = &fimc_capture_ioctl_ops;
@@ -1523,6 +1590,10 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
1523 vfd->minor = -1; 1590 vfd->minor = -1;
1524 vfd->release = video_device_release; 1591 vfd->release = video_device_release;
1525 vfd->lock = &fimc->lock; 1592 vfd->lock = &fimc->lock;
1593 /* Locking in file operations other than ioctl should be done
1594 by the driver, not the V4L2 core.
1595 This driver needs auditing so that this flag can be removed. */
1596 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
1526 video_set_drvdata(vfd, fimc); 1597 video_set_drvdata(vfd, fimc);
1527 1598
1528 vid_cap = &fimc->vid_cap; 1599 vid_cap = &fimc->vid_cap;
@@ -1533,7 +1604,6 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
1533 1604
1534 INIT_LIST_HEAD(&vid_cap->pending_buf_q); 1605 INIT_LIST_HEAD(&vid_cap->pending_buf_q);
1535 INIT_LIST_HEAD(&vid_cap->active_buf_q); 1606 INIT_LIST_HEAD(&vid_cap->active_buf_q);
1536 spin_lock_init(&ctx->slock);
1537 vid_cap->ctx = ctx; 1607 vid_cap->ctx = ctx;
1538 1608
1539 q = &fimc->vid_cap.vbq; 1609 q = &fimc->vid_cap.vbq;
@@ -1547,18 +1617,22 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
1547 1617
1548 vb2_queue_init(q); 1618 vb2_queue_init(q);
1549 1619
1550 fimc->vid_cap.vd_pad.flags = MEDIA_PAD_FL_SINK; 1620 vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
1551 ret = media_entity_init(&vfd->entity, 1, &fimc->vid_cap.vd_pad, 0); 1621 ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
1552 if (ret) 1622 if (ret)
1553 goto err_ent; 1623 goto err_ent;
1554 ret = fimc_create_capture_subdev(fimc, v4l2_dev); 1624
1625 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1555 if (ret) 1626 if (ret)
1556 goto err_sd_reg; 1627 goto err_vd;
1557 1628
1558 vfd->ctrl_handler = &ctx->ctrl_handler; 1629 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
1630 vfd->name, video_device_node_name(vfd));
1631
1632 vfd->ctrl_handler = &ctx->ctrls.handler;
1559 return 0; 1633 return 0;
1560 1634
1561err_sd_reg: 1635err_vd:
1562 media_entity_cleanup(&vfd->entity); 1636 media_entity_cleanup(&vfd->entity);
1563err_ent: 1637err_ent:
1564 video_device_release(vfd); 1638 video_device_release(vfd);
@@ -1567,17 +1641,73 @@ err_vd_alloc:
1567 return ret; 1641 return ret;
1568} 1642}
1569 1643
1570void fimc_unregister_capture_device(struct fimc_dev *fimc) 1644static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
1571{ 1645{
1572 struct video_device *vfd = fimc->vid_cap.vfd; 1646 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1647 int ret;
1648
1649 ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
1650 if (ret)
1651 return ret;
1573 1652
1574 if (vfd) { 1653 ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
1575 media_entity_cleanup(&vfd->entity); 1654 if (ret)
1576 /* Can also be called if video device was 1655 fimc_unregister_m2m_device(fimc);
1577 not registered */ 1656
1578 video_unregister_device(vfd); 1657 return ret;
1658}
1659
1660static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
1661{
1662 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1663
1664 if (fimc == NULL)
1665 return;
1666
1667 fimc_unregister_m2m_device(fimc);
1668
1669 if (fimc->vid_cap.vfd) {
1670 media_entity_cleanup(&fimc->vid_cap.vfd->entity);
1671 video_unregister_device(fimc->vid_cap.vfd);
1672 fimc->vid_cap.vfd = NULL;
1579 } 1673 }
1580 fimc_destroy_capture_subdev(fimc); 1674
1581 kfree(fimc->vid_cap.ctx); 1675 kfree(fimc->vid_cap.ctx);
1582 fimc->vid_cap.ctx = NULL; 1676 fimc->vid_cap.ctx = NULL;
1583} 1677}
1678
1679static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
1680 .registered = fimc_capture_subdev_registered,
1681 .unregistered = fimc_capture_subdev_unregistered,
1682};
1683
1684int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
1685{
1686 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
1687 int ret;
1688
1689 v4l2_subdev_init(sd, &fimc_subdev_ops);
1690 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1691 snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);
1692
1693 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1694 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1695 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1696 fimc->vid_cap.sd_pads, 0);
1697 if (ret)
1698 return ret;
1699
1700 sd->entity.ops = &fimc_sd_media_ops;
1701 sd->internal_ops = &fimc_capture_sd_internal_ops;
1702 v4l2_set_subdevdata(sd, fimc);
1703 return 0;
1704}
1705
1706void fimc_unregister_capture_subdev(struct fimc_dev *fimc)
1707{
1708 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
1709
1710 v4l2_device_unregister_subdev(sd);
1711 media_entity_cleanup(&sd->entity);
1712 v4l2_set_subdevdata(sd, NULL);
1713}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index e09ba7b0076e..fedcd561ba27 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Samsung S5P/EXYNOS4 SoC series camera interface (video postprocessor) driver 2 * Samsung S5P/EXYNOS4 SoC series FIMC (CAMIF) driver
3 * 3 *
4 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2010-2012 Samsung Electronics Co., Ltd.
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com> 5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published
@@ -28,6 +28,7 @@
28#include <media/videobuf2-dma-contig.h> 28#include <media/videobuf2-dma-contig.h>
29 29
30#include "fimc-core.h" 30#include "fimc-core.h"
31#include "fimc-reg.h"
31#include "fimc-mdevice.h" 32#include "fimc-mdevice.h"
32 33
33static char *fimc_clocks[MAX_FIMC_CLOCKS] = { 34static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
@@ -39,7 +40,7 @@ static struct fimc_fmt fimc_formats[] = {
39 .name = "RGB565", 40 .name = "RGB565",
40 .fourcc = V4L2_PIX_FMT_RGB565, 41 .fourcc = V4L2_PIX_FMT_RGB565,
41 .depth = { 16 }, 42 .depth = { 16 },
42 .color = S5P_FIMC_RGB565, 43 .color = FIMC_FMT_RGB565,
43 .memplanes = 1, 44 .memplanes = 1,
44 .colplanes = 1, 45 .colplanes = 1,
45 .flags = FMT_FLAGS_M2M, 46 .flags = FMT_FLAGS_M2M,
@@ -47,7 +48,7 @@ static struct fimc_fmt fimc_formats[] = {
47 .name = "BGR666", 48 .name = "BGR666",
48 .fourcc = V4L2_PIX_FMT_BGR666, 49 .fourcc = V4L2_PIX_FMT_BGR666,
49 .depth = { 32 }, 50 .depth = { 32 },
50 .color = S5P_FIMC_RGB666, 51 .color = FIMC_FMT_RGB666,
51 .memplanes = 1, 52 .memplanes = 1,
52 .colplanes = 1, 53 .colplanes = 1,
53 .flags = FMT_FLAGS_M2M, 54 .flags = FMT_FLAGS_M2M,
@@ -55,7 +56,7 @@ static struct fimc_fmt fimc_formats[] = {
55 .name = "ARGB8888, 32 bpp", 56 .name = "ARGB8888, 32 bpp",
56 .fourcc = V4L2_PIX_FMT_RGB32, 57 .fourcc = V4L2_PIX_FMT_RGB32,
57 .depth = { 32 }, 58 .depth = { 32 },
58 .color = S5P_FIMC_RGB888, 59 .color = FIMC_FMT_RGB888,
59 .memplanes = 1, 60 .memplanes = 1,
60 .colplanes = 1, 61 .colplanes = 1,
61 .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA, 62 .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA,
@@ -63,7 +64,7 @@ static struct fimc_fmt fimc_formats[] = {
63 .name = "ARGB1555", 64 .name = "ARGB1555",
64 .fourcc = V4L2_PIX_FMT_RGB555, 65 .fourcc = V4L2_PIX_FMT_RGB555,
65 .depth = { 16 }, 66 .depth = { 16 },
66 .color = S5P_FIMC_RGB555, 67 .color = FIMC_FMT_RGB555,
67 .memplanes = 1, 68 .memplanes = 1,
68 .colplanes = 1, 69 .colplanes = 1,
69 .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA, 70 .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
@@ -71,7 +72,7 @@ static struct fimc_fmt fimc_formats[] = {
71 .name = "ARGB4444", 72 .name = "ARGB4444",
72 .fourcc = V4L2_PIX_FMT_RGB444, 73 .fourcc = V4L2_PIX_FMT_RGB444,
73 .depth = { 16 }, 74 .depth = { 16 },
74 .color = S5P_FIMC_RGB444, 75 .color = FIMC_FMT_RGB444,
75 .memplanes = 1, 76 .memplanes = 1,
76 .colplanes = 1, 77 .colplanes = 1,
77 .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA, 78 .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
@@ -79,7 +80,7 @@ static struct fimc_fmt fimc_formats[] = {
79 .name = "YUV 4:2:2 packed, YCbYCr", 80 .name = "YUV 4:2:2 packed, YCbYCr",
80 .fourcc = V4L2_PIX_FMT_YUYV, 81 .fourcc = V4L2_PIX_FMT_YUYV,
81 .depth = { 16 }, 82 .depth = { 16 },
82 .color = S5P_FIMC_YCBYCR422, 83 .color = FIMC_FMT_YCBYCR422,
83 .memplanes = 1, 84 .memplanes = 1,
84 .colplanes = 1, 85 .colplanes = 1,
85 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, 86 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
@@ -88,7 +89,7 @@ static struct fimc_fmt fimc_formats[] = {
88 .name = "YUV 4:2:2 packed, CbYCrY", 89 .name = "YUV 4:2:2 packed, CbYCrY",
89 .fourcc = V4L2_PIX_FMT_UYVY, 90 .fourcc = V4L2_PIX_FMT_UYVY,
90 .depth = { 16 }, 91 .depth = { 16 },
91 .color = S5P_FIMC_CBYCRY422, 92 .color = FIMC_FMT_CBYCRY422,
92 .memplanes = 1, 93 .memplanes = 1,
93 .colplanes = 1, 94 .colplanes = 1,
94 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, 95 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
@@ -97,7 +98,7 @@ static struct fimc_fmt fimc_formats[] = {
97 .name = "YUV 4:2:2 packed, CrYCbY", 98 .name = "YUV 4:2:2 packed, CrYCbY",
98 .fourcc = V4L2_PIX_FMT_VYUY, 99 .fourcc = V4L2_PIX_FMT_VYUY,
99 .depth = { 16 }, 100 .depth = { 16 },
100 .color = S5P_FIMC_CRYCBY422, 101 .color = FIMC_FMT_CRYCBY422,
101 .memplanes = 1, 102 .memplanes = 1,
102 .colplanes = 1, 103 .colplanes = 1,
103 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, 104 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
@@ -106,7 +107,7 @@ static struct fimc_fmt fimc_formats[] = {
106 .name = "YUV 4:2:2 packed, YCrYCb", 107 .name = "YUV 4:2:2 packed, YCrYCb",
107 .fourcc = V4L2_PIX_FMT_YVYU, 108 .fourcc = V4L2_PIX_FMT_YVYU,
108 .depth = { 16 }, 109 .depth = { 16 },
109 .color = S5P_FIMC_YCRYCB422, 110 .color = FIMC_FMT_YCRYCB422,
110 .memplanes = 1, 111 .memplanes = 1,
111 .colplanes = 1, 112 .colplanes = 1,
112 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, 113 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
@@ -115,7 +116,7 @@ static struct fimc_fmt fimc_formats[] = {
115 .name = "YUV 4:2:2 planar, Y/Cb/Cr", 116 .name = "YUV 4:2:2 planar, Y/Cb/Cr",
116 .fourcc = V4L2_PIX_FMT_YUV422P, 117 .fourcc = V4L2_PIX_FMT_YUV422P,
117 .depth = { 12 }, 118 .depth = { 12 },
118 .color = S5P_FIMC_YCBYCR422, 119 .color = FIMC_FMT_YCBYCR422,
119 .memplanes = 1, 120 .memplanes = 1,
120 .colplanes = 3, 121 .colplanes = 3,
121 .flags = FMT_FLAGS_M2M, 122 .flags = FMT_FLAGS_M2M,
@@ -123,7 +124,7 @@ static struct fimc_fmt fimc_formats[] = {
123 .name = "YUV 4:2:2 planar, Y/CbCr", 124 .name = "YUV 4:2:2 planar, Y/CbCr",
124 .fourcc = V4L2_PIX_FMT_NV16, 125 .fourcc = V4L2_PIX_FMT_NV16,
125 .depth = { 16 }, 126 .depth = { 16 },
126 .color = S5P_FIMC_YCBYCR422, 127 .color = FIMC_FMT_YCBYCR422,
127 .memplanes = 1, 128 .memplanes = 1,
128 .colplanes = 2, 129 .colplanes = 2,
129 .flags = FMT_FLAGS_M2M, 130 .flags = FMT_FLAGS_M2M,
@@ -131,7 +132,7 @@ static struct fimc_fmt fimc_formats[] = {
131 .name = "YUV 4:2:2 planar, Y/CrCb", 132 .name = "YUV 4:2:2 planar, Y/CrCb",
132 .fourcc = V4L2_PIX_FMT_NV61, 133 .fourcc = V4L2_PIX_FMT_NV61,
133 .depth = { 16 }, 134 .depth = { 16 },
134 .color = S5P_FIMC_YCRYCB422, 135 .color = FIMC_FMT_YCRYCB422,
135 .memplanes = 1, 136 .memplanes = 1,
136 .colplanes = 2, 137 .colplanes = 2,
137 .flags = FMT_FLAGS_M2M, 138 .flags = FMT_FLAGS_M2M,
@@ -139,7 +140,7 @@ static struct fimc_fmt fimc_formats[] = {
139 .name = "YUV 4:2:0 planar, YCbCr", 140 .name = "YUV 4:2:0 planar, YCbCr",
140 .fourcc = V4L2_PIX_FMT_YUV420, 141 .fourcc = V4L2_PIX_FMT_YUV420,
141 .depth = { 12 }, 142 .depth = { 12 },
142 .color = S5P_FIMC_YCBCR420, 143 .color = FIMC_FMT_YCBCR420,
143 .memplanes = 1, 144 .memplanes = 1,
144 .colplanes = 3, 145 .colplanes = 3,
145 .flags = FMT_FLAGS_M2M, 146 .flags = FMT_FLAGS_M2M,
@@ -147,14 +148,14 @@ static struct fimc_fmt fimc_formats[] = {
147 .name = "YUV 4:2:0 planar, Y/CbCr", 148 .name = "YUV 4:2:0 planar, Y/CbCr",
148 .fourcc = V4L2_PIX_FMT_NV12, 149 .fourcc = V4L2_PIX_FMT_NV12,
149 .depth = { 12 }, 150 .depth = { 12 },
150 .color = S5P_FIMC_YCBCR420, 151 .color = FIMC_FMT_YCBCR420,
151 .memplanes = 1, 152 .memplanes = 1,
152 .colplanes = 2, 153 .colplanes = 2,
153 .flags = FMT_FLAGS_M2M, 154 .flags = FMT_FLAGS_M2M,
154 }, { 155 }, {
155 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr", 156 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr",
156 .fourcc = V4L2_PIX_FMT_NV12M, 157 .fourcc = V4L2_PIX_FMT_NV12M,
157 .color = S5P_FIMC_YCBCR420, 158 .color = FIMC_FMT_YCBCR420,
158 .depth = { 8, 4 }, 159 .depth = { 8, 4 },
159 .memplanes = 2, 160 .memplanes = 2,
160 .colplanes = 2, 161 .colplanes = 2,
@@ -162,7 +163,7 @@ static struct fimc_fmt fimc_formats[] = {
162 }, { 163 }, {
163 .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr", 164 .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr",
164 .fourcc = V4L2_PIX_FMT_YUV420M, 165 .fourcc = V4L2_PIX_FMT_YUV420M,
165 .color = S5P_FIMC_YCBCR420, 166 .color = FIMC_FMT_YCBCR420,
166 .depth = { 8, 2, 2 }, 167 .depth = { 8, 2, 2 },
167 .memplanes = 3, 168 .memplanes = 3,
168 .colplanes = 3, 169 .colplanes = 3,
@@ -170,7 +171,7 @@ static struct fimc_fmt fimc_formats[] = {
170 }, { 171 }, {
171 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled", 172 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled",
172 .fourcc = V4L2_PIX_FMT_NV12MT, 173 .fourcc = V4L2_PIX_FMT_NV12MT,
173 .color = S5P_FIMC_YCBCR420, 174 .color = FIMC_FMT_YCBCR420,
174 .depth = { 8, 4 }, 175 .depth = { 8, 4 },
175 .memplanes = 2, 176 .memplanes = 2,
176 .colplanes = 2, 177 .colplanes = 2,
@@ -178,7 +179,7 @@ static struct fimc_fmt fimc_formats[] = {
178 }, { 179 }, {
179 .name = "JPEG encoded data", 180 .name = "JPEG encoded data",
180 .fourcc = V4L2_PIX_FMT_JPEG, 181 .fourcc = V4L2_PIX_FMT_JPEG,
181 .color = S5P_FIMC_JPEG, 182 .color = FIMC_FMT_JPEG,
182 .depth = { 8 }, 183 .depth = { 8 },
183 .memplanes = 1, 184 .memplanes = 1,
184 .colplanes = 1, 185 .colplanes = 1,
@@ -187,12 +188,12 @@ static struct fimc_fmt fimc_formats[] = {
187 }, 188 },
188}; 189};
189 190
190static unsigned int get_m2m_fmt_flags(unsigned int stream_type) 191struct fimc_fmt *fimc_get_format(unsigned int index)
191{ 192{
192 if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 193 if (index >= ARRAY_SIZE(fimc_formats))
193 return FMT_FLAGS_M2M_IN; 194 return NULL;
194 else 195
195 return FMT_FLAGS_M2M_OUT; 196 return &fimc_formats[index];
196} 197}
197 198
198int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, 199int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
@@ -230,7 +231,7 @@ static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
230 231
231int fimc_set_scaler_info(struct fimc_ctx *ctx) 232int fimc_set_scaler_info(struct fimc_ctx *ctx)
232{ 233{
233 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 234 struct fimc_variant *variant = ctx->fimc_dev->variant;
234 struct device *dev = &ctx->fimc_dev->pdev->dev; 235 struct device *dev = &ctx->fimc_dev->pdev->dev;
235 struct fimc_scaler *sc = &ctx->scaler; 236 struct fimc_scaler *sc = &ctx->scaler;
236 struct fimc_frame *s_frame = &ctx->s_frame; 237 struct fimc_frame *s_frame = &ctx->s_frame;
@@ -293,126 +294,9 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
293 return 0; 294 return 0;
294} 295}
295 296
296static void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
297{
298 struct vb2_buffer *src_vb, *dst_vb;
299
300 if (!ctx || !ctx->m2m_ctx)
301 return;
302
303 src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
304 dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
305
306 if (src_vb && dst_vb) {
307 v4l2_m2m_buf_done(src_vb, vb_state);
308 v4l2_m2m_buf_done(dst_vb, vb_state);
309 v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
310 ctx->m2m_ctx);
311 }
312}
313
314/* Complete the transaction which has been scheduled for execution. */
315static int fimc_m2m_shutdown(struct fimc_ctx *ctx)
316{
317 struct fimc_dev *fimc = ctx->fimc_dev;
318 int ret;
319
320 if (!fimc_m2m_pending(fimc))
321 return 0;
322
323 fimc_ctx_state_lock_set(FIMC_CTX_SHUT, ctx);
324
325 ret = wait_event_timeout(fimc->irq_queue,
326 !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
327 FIMC_SHUTDOWN_TIMEOUT);
328
329 return ret == 0 ? -ETIMEDOUT : ret;
330}
331
332static int start_streaming(struct vb2_queue *q, unsigned int count)
333{
334 struct fimc_ctx *ctx = q->drv_priv;
335 int ret;
336
337 ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
338 return ret > 0 ? 0 : ret;
339}
340
341static int stop_streaming(struct vb2_queue *q)
342{
343 struct fimc_ctx *ctx = q->drv_priv;
344 int ret;
345
346 ret = fimc_m2m_shutdown(ctx);
347 if (ret == -ETIMEDOUT)
348 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
349
350 pm_runtime_put(&ctx->fimc_dev->pdev->dev);
351 return 0;
352}
353
354void fimc_capture_irq_handler(struct fimc_dev *fimc, bool final)
355{
356 struct fimc_vid_cap *cap = &fimc->vid_cap;
357 struct fimc_vid_buffer *v_buf;
358 struct timeval *tv;
359 struct timespec ts;
360
361 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
362 wake_up(&fimc->irq_queue);
363 return;
364 }
365
366 if (!list_empty(&cap->active_buf_q) &&
367 test_bit(ST_CAPT_RUN, &fimc->state) && final) {
368 ktime_get_real_ts(&ts);
369
370 v_buf = fimc_active_queue_pop(cap);
371
372 tv = &v_buf->vb.v4l2_buf.timestamp;
373 tv->tv_sec = ts.tv_sec;
374 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
375 v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
376
377 vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
378 }
379
380 if (!list_empty(&cap->pending_buf_q)) {
381
382 v_buf = fimc_pending_queue_pop(cap);
383 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
384 v_buf->index = cap->buf_index;
385
386 /* Move the buffer to the capture active queue */
387 fimc_active_queue_add(cap, v_buf);
388
389 dbg("next frame: %d, done frame: %d",
390 fimc_hw_get_frame_index(fimc), v_buf->index);
391
392 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
393 cap->buf_index = 0;
394 }
395
396 if (cap->active_buf_cnt == 0) {
397 if (final)
398 clear_bit(ST_CAPT_RUN, &fimc->state);
399
400 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
401 cap->buf_index = 0;
402 } else {
403 set_bit(ST_CAPT_RUN, &fimc->state);
404 }
405
406 fimc_capture_config_update(cap->ctx);
407
408 dbg("frame: %d, active_buf_cnt: %d",
409 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
410}
411
412static irqreturn_t fimc_irq_handler(int irq, void *priv) 297static irqreturn_t fimc_irq_handler(int irq, void *priv)
413{ 298{
414 struct fimc_dev *fimc = priv; 299 struct fimc_dev *fimc = priv;
415 struct fimc_vid_cap *cap = &fimc->vid_cap;
416 struct fimc_ctx *ctx; 300 struct fimc_ctx *ctx;
417 301
418 fimc_hw_clear_irq(fimc); 302 fimc_hw_clear_irq(fimc);
@@ -430,21 +314,16 @@ static irqreturn_t fimc_irq_handler(int irq, void *priv)
430 spin_unlock(&fimc->slock); 314 spin_unlock(&fimc->slock);
431 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE); 315 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
432 316
433 spin_lock(&ctx->slock);
434 if (ctx->state & FIMC_CTX_SHUT) { 317 if (ctx->state & FIMC_CTX_SHUT) {
435 ctx->state &= ~FIMC_CTX_SHUT; 318 ctx->state &= ~FIMC_CTX_SHUT;
436 wake_up(&fimc->irq_queue); 319 wake_up(&fimc->irq_queue);
437 } 320 }
438 spin_unlock(&ctx->slock); 321 return IRQ_HANDLED;
439 } 322 }
440 return IRQ_HANDLED;
441 } else if (test_bit(ST_CAPT_PEND, &fimc->state)) { 323 } else if (test_bit(ST_CAPT_PEND, &fimc->state)) {
442 fimc_capture_irq_handler(fimc, 324 int last_buf = test_bit(ST_CAPT_JPEG, &fimc->state) &&
443 !test_bit(ST_CAPT_JPEG, &fimc->state)); 325 fimc->vid_cap.reqbufs_count == 1;
444 if (cap->active_buf_cnt == 1) { 326 fimc_capture_irq_handler(fimc, !last_buf);
445 fimc_deactivate_capture(fimc);
446 clear_bit(ST_CAPT_STREAM, &fimc->state);
447 }
448 } 327 }
449out: 328out:
450 spin_unlock(&fimc->slock); 329 spin_unlock(&fimc->slock);
@@ -482,7 +361,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
482 case 3: 361 case 3:
483 paddr->cb = (u32)(paddr->y + pix_size); 362 paddr->cb = (u32)(paddr->y + pix_size);
484 /* decompose Y into Y/Cb/Cr */ 363 /* decompose Y into Y/Cb/Cr */
485 if (S5P_FIMC_YCBCR420 == frame->fmt->color) 364 if (FIMC_FMT_YCBCR420 == frame->fmt->color)
486 paddr->cr = (u32)(paddr->cb 365 paddr->cr = (u32)(paddr->cb
487 + (pix_size >> 2)); 366 + (pix_size >> 2));
488 else /* 422 */ 367 else /* 422 */
@@ -510,40 +389,40 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
510void fimc_set_yuv_order(struct fimc_ctx *ctx) 389void fimc_set_yuv_order(struct fimc_ctx *ctx)
511{ 390{
512 /* The one only mode supported in SoC. */ 391 /* The one only mode supported in SoC. */
513 ctx->in_order_2p = S5P_FIMC_LSB_CRCB; 392 ctx->in_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
514 ctx->out_order_2p = S5P_FIMC_LSB_CRCB; 393 ctx->out_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
515 394
516 /* Set order for 1 plane input formats. */ 395 /* Set order for 1 plane input formats. */
517 switch (ctx->s_frame.fmt->color) { 396 switch (ctx->s_frame.fmt->color) {
518 case S5P_FIMC_YCRYCB422: 397 case FIMC_FMT_YCRYCB422:
519 ctx->in_order_1p = S5P_MSCTRL_ORDER422_CBYCRY; 398 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CBYCRY;
520 break; 399 break;
521 case S5P_FIMC_CBYCRY422: 400 case FIMC_FMT_CBYCRY422:
522 ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCRYCB; 401 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCRYCB;
523 break; 402 break;
524 case S5P_FIMC_CRYCBY422: 403 case FIMC_FMT_CRYCBY422:
525 ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCBYCR; 404 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCBYCR;
526 break; 405 break;
527 case S5P_FIMC_YCBYCR422: 406 case FIMC_FMT_YCBYCR422:
528 default: 407 default:
529 ctx->in_order_1p = S5P_MSCTRL_ORDER422_CRYCBY; 408 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CRYCBY;
530 break; 409 break;
531 } 410 }
532 dbg("ctx->in_order_1p= %d", ctx->in_order_1p); 411 dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
533 412
534 switch (ctx->d_frame.fmt->color) { 413 switch (ctx->d_frame.fmt->color) {
535 case S5P_FIMC_YCRYCB422: 414 case FIMC_FMT_YCRYCB422:
536 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CBYCRY; 415 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CBYCRY;
537 break; 416 break;
538 case S5P_FIMC_CBYCRY422: 417 case FIMC_FMT_CBYCRY422:
539 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCRYCB; 418 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCRYCB;
540 break; 419 break;
541 case S5P_FIMC_CRYCBY422: 420 case FIMC_FMT_CRYCBY422:
542 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCBYCR; 421 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCBYCR;
543 break; 422 break;
544 case S5P_FIMC_YCBYCR422: 423 case FIMC_FMT_YCBYCR422:
545 default: 424 default:
546 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CRYCBY; 425 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CRYCBY;
547 break; 426 break;
548 } 427 }
549 dbg("ctx->out_order_1p= %d", ctx->out_order_1p); 428 dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
@@ -551,7 +430,7 @@ void fimc_set_yuv_order(struct fimc_ctx *ctx)
551 430
552void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) 431void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
553{ 432{
554 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 433 struct fimc_variant *variant = ctx->fimc_dev->variant;
555 u32 i, depth = 0; 434 u32 i, depth = 0;
556 435
557 for (i = 0; i < f->fmt->colplanes; i++) 436 for (i = 0; i < f->fmt->colplanes; i++)
@@ -574,7 +453,7 @@ void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
574 f->dma_offset.cb_h >>= 1; 453 f->dma_offset.cb_h >>= 1;
575 f->dma_offset.cr_h >>= 1; 454 f->dma_offset.cr_h >>= 1;
576 } 455 }
577 if (f->fmt->color == S5P_FIMC_YCBCR420) { 456 if (f->fmt->color == FIMC_FMT_YCBCR420) {
578 f->dma_offset.cb_v >>= 1; 457 f->dma_offset.cb_v >>= 1;
579 f->dma_offset.cr_v >>= 1; 458 f->dma_offset.cr_v >>= 1;
580 } 459 }
@@ -584,203 +463,58 @@ void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
584 f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); 463 f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
585} 464}
586 465
587/** 466int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
588 * fimc_prepare_config - check dimensions, operation and color mode
589 * and pre-calculate offset and the scaling coefficients.
590 *
591 * @ctx: hardware context information
592 * @flags: flags indicating which parameters to check/update
593 *
594 * Return: 0 if dimensions are valid or non zero otherwise.
595 */
596int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
597{
598 struct fimc_frame *s_frame, *d_frame;
599 struct vb2_buffer *vb = NULL;
600 int ret = 0;
601
602 s_frame = &ctx->s_frame;
603 d_frame = &ctx->d_frame;
604
605 if (flags & FIMC_PARAMS) {
606 /* Prepare the DMA offset ratios for scaler. */
607 fimc_prepare_dma_offset(ctx, &ctx->s_frame);
608 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
609
610 if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) ||
611 s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) {
612 err("out of scaler range");
613 return -EINVAL;
614 }
615 fimc_set_yuv_order(ctx);
616 }
617
618 if (flags & FIMC_SRC_ADDR) {
619 vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
620 ret = fimc_prepare_addr(ctx, vb, s_frame, &s_frame->paddr);
621 if (ret)
622 return ret;
623 }
624
625 if (flags & FIMC_DST_ADDR) {
626 vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
627 ret = fimc_prepare_addr(ctx, vb, d_frame, &d_frame->paddr);
628 }
629
630 return ret;
631}
632
633static void fimc_dma_run(void *priv)
634{
635 struct fimc_ctx *ctx = priv;
636 struct fimc_dev *fimc;
637 unsigned long flags;
638 u32 ret;
639
640 if (WARN(!ctx, "null hardware context\n"))
641 return;
642
643 fimc = ctx->fimc_dev;
644 spin_lock_irqsave(&fimc->slock, flags);
645 set_bit(ST_M2M_PEND, &fimc->state);
646
647 spin_lock(&ctx->slock);
648 ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR);
649 ret = fimc_prepare_config(ctx, ctx->state);
650 if (ret)
651 goto dma_unlock;
652
653 /* Reconfigure hardware if the context has changed. */
654 if (fimc->m2m.ctx != ctx) {
655 ctx->state |= FIMC_PARAMS;
656 fimc->m2m.ctx = ctx;
657 }
658 fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr);
659
660 if (ctx->state & FIMC_PARAMS) {
661 fimc_hw_set_input_path(ctx);
662 fimc_hw_set_in_dma(ctx);
663 ret = fimc_set_scaler_info(ctx);
664 if (ret) {
665 spin_unlock(&fimc->slock);
666 goto dma_unlock;
667 }
668 fimc_hw_set_prescaler(ctx);
669 fimc_hw_set_mainscaler(ctx);
670 fimc_hw_set_target_format(ctx);
671 fimc_hw_set_rotation(ctx);
672 fimc_hw_set_effect(ctx, false);
673 }
674
675 fimc_hw_set_output_path(ctx);
676 if (ctx->state & (FIMC_DST_ADDR | FIMC_PARAMS))
677 fimc_hw_set_output_addr(fimc, &ctx->d_frame.paddr, -1);
678
679 if (ctx->state & FIMC_PARAMS) {
680 fimc_hw_set_out_dma(ctx);
681 if (fimc->variant->has_alpha)
682 fimc_hw_set_rgb_alpha(ctx);
683 }
684
685 fimc_activate_capture(ctx);
686
687 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
688 FIMC_SRC_FMT | FIMC_DST_FMT);
689 fimc_hw_activate_input_dma(fimc, true);
690dma_unlock:
691 spin_unlock(&ctx->slock);
692 spin_unlock_irqrestore(&fimc->slock, flags);
693}
694
695static void fimc_job_abort(void *priv)
696{ 467{
697 fimc_m2m_shutdown(priv); 468 struct fimc_effect *effect = &ctx->effect;
698}
699
700static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
701 unsigned int *num_buffers, unsigned int *num_planes,
702 unsigned int sizes[], void *allocators[])
703{
704 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
705 struct fimc_frame *f;
706 int i;
707 469
708 f = ctx_get_frame(ctx, vq->type); 470 switch (colorfx) {
709 if (IS_ERR(f)) 471 case V4L2_COLORFX_NONE:
710 return PTR_ERR(f); 472 effect->type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
711 /* 473 break;
712 * Return number of non-contigous planes (plane buffers) 474 case V4L2_COLORFX_BW:
713 * depending on the configured color format. 475 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
714 */ 476 effect->pat_cb = 128;
715 if (!f->fmt) 477 effect->pat_cr = 128;
478 break;
479 case V4L2_COLORFX_SEPIA:
480 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
481 effect->pat_cb = 115;
482 effect->pat_cr = 145;
483 break;
484 case V4L2_COLORFX_NEGATIVE:
485 effect->type = FIMC_REG_CIIMGEFF_FIN_NEGATIVE;
486 break;
487 case V4L2_COLORFX_EMBOSS:
488 effect->type = FIMC_REG_CIIMGEFF_FIN_EMBOSSING;
489 break;
490 case V4L2_COLORFX_ART_FREEZE:
491 effect->type = FIMC_REG_CIIMGEFF_FIN_ARTFREEZE;
492 break;
493 case V4L2_COLORFX_SILHOUETTE:
494 effect->type = FIMC_REG_CIIMGEFF_FIN_SILHOUETTE;
495 break;
496 case V4L2_COLORFX_SET_CBCR:
497 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
498 effect->pat_cb = ctx->ctrls.colorfx_cbcr->val >> 8;
499 effect->pat_cr = ctx->ctrls.colorfx_cbcr->val & 0xff;
500 break;
501 default:
716 return -EINVAL; 502 return -EINVAL;
717
718 *num_planes = f->fmt->memplanes;
719 for (i = 0; i < f->fmt->memplanes; i++) {
720 sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
721 allocators[i] = ctx->fimc_dev->alloc_ctx;
722 } 503 }
723 return 0;
724}
725
726static int fimc_buf_prepare(struct vb2_buffer *vb)
727{
728 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
729 struct fimc_frame *frame;
730 int i;
731
732 frame = ctx_get_frame(ctx, vb->vb2_queue->type);
733 if (IS_ERR(frame))
734 return PTR_ERR(frame);
735
736 for (i = 0; i < frame->fmt->memplanes; i++)
737 vb2_set_plane_payload(vb, i, frame->payload[i]);
738 504
739 return 0; 505 return 0;
740} 506}
741 507
742static void fimc_buf_queue(struct vb2_buffer *vb)
743{
744 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
745
746 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
747
748 if (ctx->m2m_ctx)
749 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
750}
751
752static void fimc_lock(struct vb2_queue *vq)
753{
754 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
755 mutex_lock(&ctx->fimc_dev->lock);
756}
757
758static void fimc_unlock(struct vb2_queue *vq)
759{
760 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
761 mutex_unlock(&ctx->fimc_dev->lock);
762}
763
764static struct vb2_ops fimc_qops = {
765 .queue_setup = fimc_queue_setup,
766 .buf_prepare = fimc_buf_prepare,
767 .buf_queue = fimc_buf_queue,
768 .wait_prepare = fimc_unlock,
769 .wait_finish = fimc_lock,
770 .stop_streaming = stop_streaming,
771 .start_streaming = start_streaming,
772};
773
774/* 508/*
775 * V4L2 controls handling 509 * V4L2 controls handling
776 */ 510 */
777#define ctrl_to_ctx(__ctrl) \ 511#define ctrl_to_ctx(__ctrl) \
778 container_of((__ctrl)->handler, struct fimc_ctx, ctrl_handler) 512 container_of((__ctrl)->handler, struct fimc_ctx, ctrls.handler)
779 513
780static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) 514static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
781{ 515{
782 struct fimc_dev *fimc = ctx->fimc_dev; 516 struct fimc_dev *fimc = ctx->fimc_dev;
783 struct samsung_fimc_variant *variant = fimc->variant; 517 struct fimc_variant *variant = fimc->variant;
784 unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT; 518 unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
785 int ret = 0; 519 int ret = 0;
786 520
@@ -815,7 +549,14 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
815 case V4L2_CID_ALPHA_COMPONENT: 549 case V4L2_CID_ALPHA_COMPONENT:
816 ctx->d_frame.alpha = ctrl->val; 550 ctx->d_frame.alpha = ctrl->val;
817 break; 551 break;
552
553 case V4L2_CID_COLORFX:
554 ret = fimc_set_color_effect(ctx, ctrl->val);
555 if (ret)
556 return ret;
557 break;
818 } 558 }
559
819 ctx->state |= FIMC_PARAMS; 560 ctx->state |= FIMC_PARAMS;
820 set_bit(ST_CAPT_APPLY_CFG, &fimc->state); 561 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
821 return 0; 562 return 0;
@@ -827,9 +568,9 @@ static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
827 unsigned long flags; 568 unsigned long flags;
828 int ret; 569 int ret;
829 570
830 spin_lock_irqsave(&ctx->slock, flags); 571 spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
831 ret = __fimc_s_ctrl(ctx, ctrl); 572 ret = __fimc_s_ctrl(ctx, ctrl);
832 spin_unlock_irqrestore(&ctx->slock, flags); 573 spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
833 574
834 return ret; 575 return ret;
835} 576}
@@ -840,71 +581,93 @@ static const struct v4l2_ctrl_ops fimc_ctrl_ops = {
840 581
841int fimc_ctrls_create(struct fimc_ctx *ctx) 582int fimc_ctrls_create(struct fimc_ctx *ctx)
842{ 583{
843 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 584 struct fimc_variant *variant = ctx->fimc_dev->variant;
844 unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt); 585 unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);
586 struct fimc_ctrls *ctrls = &ctx->ctrls;
587 struct v4l2_ctrl_handler *handler = &ctrls->handler;
845 588
846 if (ctx->ctrls_rdy) 589 if (ctx->ctrls.ready)
847 return 0; 590 return 0;
848 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
849 591
850 ctx->ctrl_rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, 592 v4l2_ctrl_handler_init(handler, 6);
593
594 ctrls->rotate = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
851 V4L2_CID_ROTATE, 0, 270, 90, 0); 595 V4L2_CID_ROTATE, 0, 270, 90, 0);
852 ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, 596 ctrls->hflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
853 V4L2_CID_HFLIP, 0, 1, 1, 0); 597 V4L2_CID_HFLIP, 0, 1, 1, 0);
854 ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &fimc_ctrl_ops, 598 ctrls->vflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
855 V4L2_CID_VFLIP, 0, 1, 1, 0); 599 V4L2_CID_VFLIP, 0, 1, 1, 0);
600
856 if (variant->has_alpha) 601 if (variant->has_alpha)
857 ctx->ctrl_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler, 602 ctrls->alpha = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
858 &fimc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, 603 V4L2_CID_ALPHA_COMPONENT,
859 0, max_alpha, 1, 0); 604 0, max_alpha, 1, 0);
860 else 605 else
861 ctx->ctrl_alpha = NULL; 606 ctrls->alpha = NULL;
862 607
863 ctx->ctrls_rdy = ctx->ctrl_handler.error == 0; 608 ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, &fimc_ctrl_ops,
609 V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
610 ~0x983f, V4L2_COLORFX_NONE);
864 611
865 return ctx->ctrl_handler.error; 612 ctrls->colorfx_cbcr = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
613 V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
614
615 ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
616
617 if (!handler->error) {
618 v4l2_ctrl_cluster(3, &ctrls->colorfx);
619 ctrls->ready = true;
620 }
621
622 return handler->error;
866} 623}
867 624
868void fimc_ctrls_delete(struct fimc_ctx *ctx) 625void fimc_ctrls_delete(struct fimc_ctx *ctx)
869{ 626{
870 if (ctx->ctrls_rdy) { 627 struct fimc_ctrls *ctrls = &ctx->ctrls;
871 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 628
872 ctx->ctrls_rdy = false; 629 if (ctrls->ready) {
873 ctx->ctrl_alpha = NULL; 630 v4l2_ctrl_handler_free(&ctrls->handler);
631 ctrls->ready = false;
632 ctrls->alpha = NULL;
874 } 633 }
875} 634}
876 635
877void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) 636void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
878{ 637{
879 unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA; 638 unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;
639 struct fimc_ctrls *ctrls = &ctx->ctrls;
880 640
881 if (!ctx->ctrls_rdy) 641 if (!ctrls->ready)
882 return; 642 return;
883 643
884 mutex_lock(&ctx->ctrl_handler.lock); 644 mutex_lock(&ctrls->handler.lock);
885 v4l2_ctrl_activate(ctx->ctrl_rotate, active); 645 v4l2_ctrl_activate(ctrls->rotate, active);
886 v4l2_ctrl_activate(ctx->ctrl_hflip, active); 646 v4l2_ctrl_activate(ctrls->hflip, active);
887 v4l2_ctrl_activate(ctx->ctrl_vflip, active); 647 v4l2_ctrl_activate(ctrls->vflip, active);
888 if (ctx->ctrl_alpha) 648 v4l2_ctrl_activate(ctrls->colorfx, active);
889 v4l2_ctrl_activate(ctx->ctrl_alpha, active && has_alpha); 649 if (ctrls->alpha)
650 v4l2_ctrl_activate(ctrls->alpha, active && has_alpha);
890 651
891 if (active) { 652 if (active) {
892 ctx->rotation = ctx->ctrl_rotate->val; 653 fimc_set_color_effect(ctx, ctrls->colorfx->cur.val);
893 ctx->hflip = ctx->ctrl_hflip->val; 654 ctx->rotation = ctrls->rotate->val;
894 ctx->vflip = ctx->ctrl_vflip->val; 655 ctx->hflip = ctrls->hflip->val;
656 ctx->vflip = ctrls->vflip->val;
895 } else { 657 } else {
658 ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
896 ctx->rotation = 0; 659 ctx->rotation = 0;
897 ctx->hflip = 0; 660 ctx->hflip = 0;
898 ctx->vflip = 0; 661 ctx->vflip = 0;
899 } 662 }
900 mutex_unlock(&ctx->ctrl_handler.lock); 663 mutex_unlock(&ctrls->handler.lock);
901} 664}
902 665
903/* Update maximum value of the alpha color control */ 666/* Update maximum value of the alpha color control */
904void fimc_alpha_ctrl_update(struct fimc_ctx *ctx) 667void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
905{ 668{
906 struct fimc_dev *fimc = ctx->fimc_dev; 669 struct fimc_dev *fimc = ctx->fimc_dev;
907 struct v4l2_ctrl *ctrl = ctx->ctrl_alpha; 670 struct v4l2_ctrl *ctrl = ctx->ctrls.alpha;
908 671
909 if (ctrl == NULL || !fimc->variant->has_alpha) 672 if (ctrl == NULL || !fimc->variant->has_alpha)
910 return; 673 return;
@@ -918,39 +681,6 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
918 v4l2_ctrl_unlock(ctrl); 681 v4l2_ctrl_unlock(ctrl);
919} 682}
920 683
921/*
922 * V4L2 ioctl handlers
923 */
924static int fimc_m2m_querycap(struct file *file, void *fh,
925 struct v4l2_capability *cap)
926{
927 struct fimc_ctx *ctx = fh_to_ctx(fh);
928 struct fimc_dev *fimc = ctx->fimc_dev;
929
930 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
931 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
932 cap->bus_info[0] = 0;
933 cap->capabilities = V4L2_CAP_STREAMING |
934 V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
935
936 return 0;
937}
938
939static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
940 struct v4l2_fmtdesc *f)
941{
942 struct fimc_fmt *fmt;
943
944 fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
945 f->index);
946 if (!fmt)
947 return -EINVAL;
948
949 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
950 f->pixelformat = fmt->fourcc;
951 return 0;
952}
953
954int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f) 684int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
955{ 685{
956 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; 686 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
@@ -1029,18 +759,6 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
1029 } 759 }
1030} 760}
1031 761
1032static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
1033 struct v4l2_format *f)
1034{
1035 struct fimc_ctx *ctx = fh_to_ctx(fh);
1036 struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
1037
1038 if (IS_ERR(frame))
1039 return PTR_ERR(frame);
1040
1041 return fimc_fill_format(frame, f);
1042}
1043
1044/** 762/**
1045 * fimc_find_format - lookup fimc color format by fourcc or media bus format 763 * fimc_find_format - lookup fimc color format by fourcc or media bus format
1046 * @pixelformat: fourcc to match, ignored if null 764 * @pixelformat: fourcc to match, ignored if null
@@ -1073,535 +791,10 @@ struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
1073 return def_fmt; 791 return def_fmt;
1074} 792}
1075 793
1076static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
1077{
1078 struct fimc_dev *fimc = ctx->fimc_dev;
1079 struct samsung_fimc_variant *variant = fimc->variant;
1080 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1081 struct fimc_fmt *fmt;
1082 u32 max_w, mod_x, mod_y;
1083
1084 if (!IS_M2M(f->type))
1085 return -EINVAL;
1086
1087 dbg("w: %d, h: %d", pix->width, pix->height);
1088
1089 fmt = fimc_find_format(&pix->pixelformat, NULL,
1090 get_m2m_fmt_flags(f->type), 0);
1091 if (WARN(fmt == NULL, "Pixel format lookup failed"))
1092 return -EINVAL;
1093
1094 if (pix->field == V4L2_FIELD_ANY)
1095 pix->field = V4L2_FIELD_NONE;
1096 else if (pix->field != V4L2_FIELD_NONE)
1097 return -EINVAL;
1098
1099 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1100 max_w = variant->pix_limit->scaler_dis_w;
1101 mod_x = ffs(variant->min_inp_pixsize) - 1;
1102 } else {
1103 max_w = variant->pix_limit->out_rot_dis_w;
1104 mod_x = ffs(variant->min_out_pixsize) - 1;
1105 }
1106
1107 if (tiled_fmt(fmt)) {
1108 mod_x = 6; /* 64 x 32 pixels tile */
1109 mod_y = 5;
1110 } else {
1111 if (variant->min_vsize_align == 1)
1112 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
1113 else
1114 mod_y = ffs(variant->min_vsize_align) - 1;
1115 }
1116
1117 v4l_bound_align_image(&pix->width, 16, max_w, mod_x,
1118 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
1119
1120 fimc_adjust_mplane_format(fmt, pix->width, pix->height, &f->fmt.pix_mp);
1121 return 0;
1122}
1123
1124static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
1125 struct v4l2_format *f)
1126{
1127 struct fimc_ctx *ctx = fh_to_ctx(fh);
1128
1129 return fimc_try_fmt_mplane(ctx, f);
1130}
1131
1132static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
1133 struct v4l2_format *f)
1134{
1135 struct fimc_ctx *ctx = fh_to_ctx(fh);
1136 struct fimc_dev *fimc = ctx->fimc_dev;
1137 struct vb2_queue *vq;
1138 struct fimc_frame *frame;
1139 struct v4l2_pix_format_mplane *pix;
1140 int i, ret = 0;
1141
1142 ret = fimc_try_fmt_mplane(ctx, f);
1143 if (ret)
1144 return ret;
1145
1146 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
1147
1148 if (vb2_is_busy(vq)) {
1149 v4l2_err(fimc->m2m.vfd, "queue (%d) busy\n", f->type);
1150 return -EBUSY;
1151 }
1152
1153 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1154 frame = &ctx->s_frame;
1155 else
1156 frame = &ctx->d_frame;
1157
1158 pix = &f->fmt.pix_mp;
1159 frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
1160 get_m2m_fmt_flags(f->type), 0);
1161 if (!frame->fmt)
1162 return -EINVAL;
1163
1164 /* Update RGB Alpha control state and value range */
1165 fimc_alpha_ctrl_update(ctx);
1166
1167 for (i = 0; i < frame->fmt->colplanes; i++) {
1168 frame->payload[i] =
1169 (pix->width * pix->height * frame->fmt->depth[i]) / 8;
1170 }
1171
1172 fimc_fill_frame(frame, f);
1173
1174 ctx->scaler.enabled = 1;
1175
1176 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1177 fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
1178 else
1179 fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
1180
1181 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
1182
1183 return 0;
1184}
1185
1186static int fimc_m2m_reqbufs(struct file *file, void *fh,
1187 struct v4l2_requestbuffers *reqbufs)
1188{
1189 struct fimc_ctx *ctx = fh_to_ctx(fh);
1190
1191 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
1192}
1193
1194static int fimc_m2m_querybuf(struct file *file, void *fh,
1195 struct v4l2_buffer *buf)
1196{
1197 struct fimc_ctx *ctx = fh_to_ctx(fh);
1198
1199 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
1200}
1201
1202static int fimc_m2m_qbuf(struct file *file, void *fh,
1203 struct v4l2_buffer *buf)
1204{
1205 struct fimc_ctx *ctx = fh_to_ctx(fh);
1206
1207 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
1208}
1209
1210static int fimc_m2m_dqbuf(struct file *file, void *fh,
1211 struct v4l2_buffer *buf)
1212{
1213 struct fimc_ctx *ctx = fh_to_ctx(fh);
1214
1215 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
1216}
1217
1218static int fimc_m2m_streamon(struct file *file, void *fh,
1219 enum v4l2_buf_type type)
1220{
1221 struct fimc_ctx *ctx = fh_to_ctx(fh);
1222
1223 /* The source and target color format need to be set */
1224 if (V4L2_TYPE_IS_OUTPUT(type)) {
1225 if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
1226 return -EINVAL;
1227 } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
1228 return -EINVAL;
1229 }
1230
1231 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
1232}
1233
1234static int fimc_m2m_streamoff(struct file *file, void *fh,
1235 enum v4l2_buf_type type)
1236{
1237 struct fimc_ctx *ctx = fh_to_ctx(fh);
1238
1239 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
1240}
1241
1242static int fimc_m2m_cropcap(struct file *file, void *fh,
1243 struct v4l2_cropcap *cr)
1244{
1245 struct fimc_ctx *ctx = fh_to_ctx(fh);
1246 struct fimc_frame *frame;
1247
1248 frame = ctx_get_frame(ctx, cr->type);
1249 if (IS_ERR(frame))
1250 return PTR_ERR(frame);
1251
1252 cr->bounds.left = 0;
1253 cr->bounds.top = 0;
1254 cr->bounds.width = frame->o_width;
1255 cr->bounds.height = frame->o_height;
1256 cr->defrect = cr->bounds;
1257
1258 return 0;
1259}
1260
1261static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1262{
1263 struct fimc_ctx *ctx = fh_to_ctx(fh);
1264 struct fimc_frame *frame;
1265
1266 frame = ctx_get_frame(ctx, cr->type);
1267 if (IS_ERR(frame))
1268 return PTR_ERR(frame);
1269
1270 cr->c.left = frame->offs_h;
1271 cr->c.top = frame->offs_v;
1272 cr->c.width = frame->width;
1273 cr->c.height = frame->height;
1274
1275 return 0;
1276}
1277
1278static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1279{
1280 struct fimc_dev *fimc = ctx->fimc_dev;
1281 struct fimc_frame *f;
1282 u32 min_size, halign, depth = 0;
1283 int i;
1284
1285 if (cr->c.top < 0 || cr->c.left < 0) {
1286 v4l2_err(fimc->m2m.vfd,
1287 "doesn't support negative values for top & left\n");
1288 return -EINVAL;
1289 }
1290 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1291 f = &ctx->d_frame;
1292 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1293 f = &ctx->s_frame;
1294 else
1295 return -EINVAL;
1296
1297 min_size = (f == &ctx->s_frame) ?
1298 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
1299
1300 /* Get pixel alignment constraints. */
1301 if (fimc->variant->min_vsize_align == 1)
1302 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
1303 else
1304 halign = ffs(fimc->variant->min_vsize_align) - 1;
1305
1306 for (i = 0; i < f->fmt->colplanes; i++)
1307 depth += f->fmt->depth[i];
1308
1309 v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
1310 ffs(min_size) - 1,
1311 &cr->c.height, min_size, f->o_height,
1312 halign, 64/(ALIGN(depth, 8)));
1313
1314 /* adjust left/top if cropping rectangle is out of bounds */
1315 if (cr->c.left + cr->c.width > f->o_width)
1316 cr->c.left = f->o_width - cr->c.width;
1317 if (cr->c.top + cr->c.height > f->o_height)
1318 cr->c.top = f->o_height - cr->c.height;
1319
1320 cr->c.left = round_down(cr->c.left, min_size);
1321 cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align);
1322
1323 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
1324 cr->c.left, cr->c.top, cr->c.width, cr->c.height,
1325 f->f_width, f->f_height);
1326
1327 return 0;
1328}
1329
1330static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1331{
1332 struct fimc_ctx *ctx = fh_to_ctx(fh);
1333 struct fimc_dev *fimc = ctx->fimc_dev;
1334 struct fimc_frame *f;
1335 int ret;
1336
1337 ret = fimc_m2m_try_crop(ctx, cr);
1338 if (ret)
1339 return ret;
1340
1341 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
1342 &ctx->s_frame : &ctx->d_frame;
1343
1344 /* Check to see if scaling ratio is within supported range */
1345 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
1346 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1347 ret = fimc_check_scaler_ratio(ctx, cr->c.width,
1348 cr->c.height, ctx->d_frame.width,
1349 ctx->d_frame.height, ctx->rotation);
1350 } else {
1351 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
1352 ctx->s_frame.height, cr->c.width,
1353 cr->c.height, ctx->rotation);
1354 }
1355 if (ret) {
1356 v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
1357 return -EINVAL;
1358 }
1359 }
1360
1361 f->offs_h = cr->c.left;
1362 f->offs_v = cr->c.top;
1363 f->width = cr->c.width;
1364 f->height = cr->c.height;
1365
1366 fimc_ctx_state_lock_set(FIMC_PARAMS, ctx);
1367
1368 return 0;
1369}
1370
1371static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
1372 .vidioc_querycap = fimc_m2m_querycap,
1373
1374 .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
1375 .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
1376
1377 .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
1378 .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
1379
1380 .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
1381 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
1382
1383 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
1384 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
1385
1386 .vidioc_reqbufs = fimc_m2m_reqbufs,
1387 .vidioc_querybuf = fimc_m2m_querybuf,
1388
1389 .vidioc_qbuf = fimc_m2m_qbuf,
1390 .vidioc_dqbuf = fimc_m2m_dqbuf,
1391
1392 .vidioc_streamon = fimc_m2m_streamon,
1393 .vidioc_streamoff = fimc_m2m_streamoff,
1394
1395 .vidioc_g_crop = fimc_m2m_g_crop,
1396 .vidioc_s_crop = fimc_m2m_s_crop,
1397 .vidioc_cropcap = fimc_m2m_cropcap
1398
1399};
1400
1401static int queue_init(void *priv, struct vb2_queue *src_vq,
1402 struct vb2_queue *dst_vq)
1403{
1404 struct fimc_ctx *ctx = priv;
1405 int ret;
1406
1407 memset(src_vq, 0, sizeof(*src_vq));
1408 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1409 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1410 src_vq->drv_priv = ctx;
1411 src_vq->ops = &fimc_qops;
1412 src_vq->mem_ops = &vb2_dma_contig_memops;
1413 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1414
1415 ret = vb2_queue_init(src_vq);
1416 if (ret)
1417 return ret;
1418
1419 memset(dst_vq, 0, sizeof(*dst_vq));
1420 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1421 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1422 dst_vq->drv_priv = ctx;
1423 dst_vq->ops = &fimc_qops;
1424 dst_vq->mem_ops = &vb2_dma_contig_memops;
1425 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1426
1427 return vb2_queue_init(dst_vq);
1428}
1429
1430static int fimc_m2m_open(struct file *file)
1431{
1432 struct fimc_dev *fimc = video_drvdata(file);
1433 struct fimc_ctx *ctx;
1434 int ret;
1435
1436 dbg("pid: %d, state: 0x%lx, refcnt: %d",
1437 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
1438
1439 /*
1440 * Return if the corresponding video capture node
1441 * is already opened.
1442 */
1443 if (fimc->vid_cap.refcnt > 0)
1444 return -EBUSY;
1445
1446 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1447 if (!ctx)
1448 return -ENOMEM;
1449 v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
1450 ctx->fimc_dev = fimc;
1451
1452 /* Default color format */
1453 ctx->s_frame.fmt = &fimc_formats[0];
1454 ctx->d_frame.fmt = &fimc_formats[0];
1455
1456 ret = fimc_ctrls_create(ctx);
1457 if (ret)
1458 goto error_fh;
1459
1460 /* Use separate control handler per file handle */
1461 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
1462 file->private_data = &ctx->fh;
1463 v4l2_fh_add(&ctx->fh);
1464
1465 /* Setup the device context for memory-to-memory mode */
1466 ctx->state = FIMC_CTX_M2M;
1467 ctx->flags = 0;
1468 ctx->in_path = FIMC_DMA;
1469 ctx->out_path = FIMC_DMA;
1470 spin_lock_init(&ctx->slock);
1471
1472 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
1473 if (IS_ERR(ctx->m2m_ctx)) {
1474 ret = PTR_ERR(ctx->m2m_ctx);
1475 goto error_c;
1476 }
1477
1478 if (fimc->m2m.refcnt++ == 0)
1479 set_bit(ST_M2M_RUN, &fimc->state);
1480 return 0;
1481
1482error_c:
1483 fimc_ctrls_delete(ctx);
1484error_fh:
1485 v4l2_fh_del(&ctx->fh);
1486 v4l2_fh_exit(&ctx->fh);
1487 kfree(ctx);
1488 return ret;
1489}
1490
1491static int fimc_m2m_release(struct file *file)
1492{
1493 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
1494 struct fimc_dev *fimc = ctx->fimc_dev;
1495
1496 dbg("pid: %d, state: 0x%lx, refcnt= %d",
1497 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
1498
1499 v4l2_m2m_ctx_release(ctx->m2m_ctx);
1500 fimc_ctrls_delete(ctx);
1501 v4l2_fh_del(&ctx->fh);
1502 v4l2_fh_exit(&ctx->fh);
1503
1504 if (--fimc->m2m.refcnt <= 0)
1505 clear_bit(ST_M2M_RUN, &fimc->state);
1506 kfree(ctx);
1507 return 0;
1508}
1509
1510static unsigned int fimc_m2m_poll(struct file *file,
1511 struct poll_table_struct *wait)
1512{
1513 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
1514
1515 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
1516}
1517
1518
1519static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
1520{
1521 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
1522
1523 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
1524}
1525
1526static const struct v4l2_file_operations fimc_m2m_fops = {
1527 .owner = THIS_MODULE,
1528 .open = fimc_m2m_open,
1529 .release = fimc_m2m_release,
1530 .poll = fimc_m2m_poll,
1531 .unlocked_ioctl = video_ioctl2,
1532 .mmap = fimc_m2m_mmap,
1533};
1534
1535static struct v4l2_m2m_ops m2m_ops = {
1536 .device_run = fimc_dma_run,
1537 .job_abort = fimc_job_abort,
1538};
1539
1540int fimc_register_m2m_device(struct fimc_dev *fimc,
1541 struct v4l2_device *v4l2_dev)
1542{
1543 struct video_device *vfd;
1544 struct platform_device *pdev;
1545 int ret = 0;
1546
1547 if (!fimc)
1548 return -ENODEV;
1549
1550 pdev = fimc->pdev;
1551 fimc->v4l2_dev = v4l2_dev;
1552
1553 vfd = video_device_alloc();
1554 if (!vfd) {
1555 v4l2_err(v4l2_dev, "Failed to allocate video device\n");
1556 return -ENOMEM;
1557 }
1558
1559 vfd->fops = &fimc_m2m_fops;
1560 vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
1561 vfd->v4l2_dev = v4l2_dev;
1562 vfd->minor = -1;
1563 vfd->release = video_device_release;
1564 vfd->lock = &fimc->lock;
1565
1566 snprintf(vfd->name, sizeof(vfd->name), "%s.m2m", dev_name(&pdev->dev));
1567 video_set_drvdata(vfd, fimc);
1568
1569 fimc->m2m.vfd = vfd;
1570 fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
1571 if (IS_ERR(fimc->m2m.m2m_dev)) {
1572 v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
1573 ret = PTR_ERR(fimc->m2m.m2m_dev);
1574 goto err_init;
1575 }
1576
1577 ret = media_entity_init(&vfd->entity, 0, NULL, 0);
1578 if (!ret)
1579 return 0;
1580
1581 v4l2_m2m_release(fimc->m2m.m2m_dev);
1582err_init:
1583 video_device_release(fimc->m2m.vfd);
1584 return ret;
1585}
1586
1587void fimc_unregister_m2m_device(struct fimc_dev *fimc)
1588{
1589 if (!fimc)
1590 return;
1591
1592 if (fimc->m2m.m2m_dev)
1593 v4l2_m2m_release(fimc->m2m.m2m_dev);
1594 if (fimc->m2m.vfd) {
1595 media_entity_cleanup(&fimc->m2m.vfd->entity);
1596 /* Can also be called if video device wasn't registered */
1597 video_unregister_device(fimc->m2m.vfd);
1598 }
1599}
1600
1601static void fimc_clk_put(struct fimc_dev *fimc) 794static void fimc_clk_put(struct fimc_dev *fimc)
1602{ 795{
1603 int i; 796 int i;
1604 for (i = 0; i < fimc->num_clocks; i++) { 797 for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
1605 if (IS_ERR_OR_NULL(fimc->clock[i])) 798 if (IS_ERR_OR_NULL(fimc->clock[i]))
1606 continue; 799 continue;
1607 clk_unprepare(fimc->clock[i]); 800 clk_unprepare(fimc->clock[i]);
@@ -1614,7 +807,7 @@ static int fimc_clk_get(struct fimc_dev *fimc)
1614{ 807{
1615 int i, ret; 808 int i, ret;
1616 809
1617 for (i = 0; i < fimc->num_clocks; i++) { 810 for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
1618 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]); 811 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
1619 if (IS_ERR(fimc->clock[i])) 812 if (IS_ERR(fimc->clock[i]))
1620 goto err; 813 goto err;
@@ -1672,15 +865,12 @@ static int fimc_m2m_resume(struct fimc_dev *fimc)
1672 865
1673static int fimc_probe(struct platform_device *pdev) 866static int fimc_probe(struct platform_device *pdev)
1674{ 867{
868 struct fimc_drvdata *drv_data = fimc_get_drvdata(pdev);
869 struct s5p_platform_fimc *pdata;
1675 struct fimc_dev *fimc; 870 struct fimc_dev *fimc;
1676 struct resource *res; 871 struct resource *res;
1677 struct samsung_fimc_driverdata *drv_data;
1678 struct s5p_platform_fimc *pdata;
1679 int ret = 0; 872 int ret = 0;
1680 873
1681 drv_data = (struct samsung_fimc_driverdata *)
1682 platform_get_device_id(pdev)->driver_data;
1683
1684 if (pdev->id >= drv_data->num_entities) { 874 if (pdev->id >= drv_data->num_entities) {
1685 dev_err(&pdev->dev, "Invalid platform device id: %d\n", 875 dev_err(&pdev->dev, "Invalid platform device id: %d\n",
1686 pdev->id); 876 pdev->id);
@@ -1714,28 +904,29 @@ static int fimc_probe(struct platform_device *pdev)
1714 dev_err(&pdev->dev, "Failed to get IRQ resource\n"); 904 dev_err(&pdev->dev, "Failed to get IRQ resource\n");
1715 return -ENXIO; 905 return -ENXIO;
1716 } 906 }
1717 fimc->irq = res->start;
1718 907
1719 fimc->num_clocks = MAX_FIMC_CLOCKS;
1720 ret = fimc_clk_get(fimc); 908 ret = fimc_clk_get(fimc);
1721 if (ret) 909 if (ret)
1722 return ret; 910 return ret;
1723 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency); 911 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
1724 clk_enable(fimc->clock[CLK_BUS]); 912 clk_enable(fimc->clock[CLK_BUS]);
1725 913
1726 platform_set_drvdata(pdev, fimc); 914 ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler,
1727 915 0, dev_name(&pdev->dev), fimc);
1728 ret = devm_request_irq(&pdev->dev, fimc->irq, fimc_irq_handler,
1729 0, pdev->name, fimc);
1730 if (ret) { 916 if (ret) {
1731 dev_err(&pdev->dev, "failed to install irq (%d)\n", ret); 917 dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
1732 goto err_clk; 918 goto err_clk;
1733 } 919 }
1734 920
921 ret = fimc_initialize_capture_subdev(fimc);
922 if (ret)
923 goto err_clk;
924
925 platform_set_drvdata(pdev, fimc);
1735 pm_runtime_enable(&pdev->dev); 926 pm_runtime_enable(&pdev->dev);
1736 ret = pm_runtime_get_sync(&pdev->dev); 927 ret = pm_runtime_get_sync(&pdev->dev);
1737 if (ret < 0) 928 if (ret < 0)
1738 goto err_clk; 929 goto err_sd;
1739 /* Initialize contiguous memory allocator */ 930 /* Initialize contiguous memory allocator */
1740 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 931 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1741 if (IS_ERR(fimc->alloc_ctx)) { 932 if (IS_ERR(fimc->alloc_ctx)) {
@@ -1747,9 +938,10 @@ static int fimc_probe(struct platform_device *pdev)
1747 938
1748 pm_runtime_put(&pdev->dev); 939 pm_runtime_put(&pdev->dev);
1749 return 0; 940 return 0;
1750
1751err_pm: 941err_pm:
1752 pm_runtime_put(&pdev->dev); 942 pm_runtime_put(&pdev->dev);
943err_sd:
944 fimc_unregister_capture_subdev(fimc);
1753err_clk: 945err_clk:
1754 fimc_clk_put(fimc); 946 fimc_clk_put(fimc);
1755 return ret; 947 return ret;
@@ -1834,6 +1026,7 @@ static int __devexit fimc_remove(struct platform_device *pdev)
1834 pm_runtime_disable(&pdev->dev); 1026 pm_runtime_disable(&pdev->dev);
1835 pm_runtime_set_suspended(&pdev->dev); 1027 pm_runtime_set_suspended(&pdev->dev);
1836 1028
1029 fimc_unregister_capture_subdev(fimc);
1837 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); 1030 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1838 1031
1839 clk_disable(fimc->clock[CLK_BUS]); 1032 clk_disable(fimc->clock[CLK_BUS]);
@@ -1879,7 +1072,7 @@ static struct fimc_pix_limit s5p_pix_limit[4] = {
1879 }, 1072 },
1880}; 1073};
1881 1074
1882static struct samsung_fimc_variant fimc0_variant_s5p = { 1075static struct fimc_variant fimc0_variant_s5p = {
1883 .has_inp_rot = 1, 1076 .has_inp_rot = 1,
1884 .has_out_rot = 1, 1077 .has_out_rot = 1,
1885 .has_cam_if = 1, 1078 .has_cam_if = 1,
@@ -1891,17 +1084,17 @@ static struct samsung_fimc_variant fimc0_variant_s5p = {
1891 .pix_limit = &s5p_pix_limit[0], 1084 .pix_limit = &s5p_pix_limit[0],
1892}; 1085};
1893 1086
1894static struct samsung_fimc_variant fimc2_variant_s5p = { 1087static struct fimc_variant fimc2_variant_s5p = {
1895 .has_cam_if = 1, 1088 .has_cam_if = 1,
1896 .min_inp_pixsize = 16, 1089 .min_inp_pixsize = 16,
1897 .min_out_pixsize = 16, 1090 .min_out_pixsize = 16,
1898 .hor_offs_align = 8, 1091 .hor_offs_align = 8,
1899 .min_vsize_align = 16, 1092 .min_vsize_align = 16,
1900 .out_buf_count = 4, 1093 .out_buf_count = 4,
1901 .pix_limit = &s5p_pix_limit[1], 1094 .pix_limit = &s5p_pix_limit[1],
1902}; 1095};
1903 1096
1904static struct samsung_fimc_variant fimc0_variant_s5pv210 = { 1097static struct fimc_variant fimc0_variant_s5pv210 = {
1905 .pix_hoff = 1, 1098 .pix_hoff = 1,
1906 .has_inp_rot = 1, 1099 .has_inp_rot = 1,
1907 .has_out_rot = 1, 1100 .has_out_rot = 1,
@@ -1914,7 +1107,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv210 = {
1914 .pix_limit = &s5p_pix_limit[1], 1107 .pix_limit = &s5p_pix_limit[1],
1915}; 1108};
1916 1109
1917static struct samsung_fimc_variant fimc1_variant_s5pv210 = { 1110static struct fimc_variant fimc1_variant_s5pv210 = {
1918 .pix_hoff = 1, 1111 .pix_hoff = 1,
1919 .has_inp_rot = 1, 1112 .has_inp_rot = 1,
1920 .has_out_rot = 1, 1113 .has_out_rot = 1,
@@ -1928,7 +1121,7 @@ static struct samsung_fimc_variant fimc1_variant_s5pv210 = {
1928 .pix_limit = &s5p_pix_limit[2], 1121 .pix_limit = &s5p_pix_limit[2],
1929}; 1122};
1930 1123
1931static struct samsung_fimc_variant fimc2_variant_s5pv210 = { 1124static struct fimc_variant fimc2_variant_s5pv210 = {
1932 .has_cam_if = 1, 1125 .has_cam_if = 1,
1933 .pix_hoff = 1, 1126 .pix_hoff = 1,
1934 .min_inp_pixsize = 16, 1127 .min_inp_pixsize = 16,
@@ -1939,7 +1132,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
1939 .pix_limit = &s5p_pix_limit[2], 1132 .pix_limit = &s5p_pix_limit[2],
1940}; 1133};
1941 1134
1942static struct samsung_fimc_variant fimc0_variant_exynos4 = { 1135static struct fimc_variant fimc0_variant_exynos4 = {
1943 .pix_hoff = 1, 1136 .pix_hoff = 1,
1944 .has_inp_rot = 1, 1137 .has_inp_rot = 1,
1945 .has_out_rot = 1, 1138 .has_out_rot = 1,
@@ -1955,7 +1148,7 @@ static struct samsung_fimc_variant fimc0_variant_exynos4 = {
1955 .pix_limit = &s5p_pix_limit[1], 1148 .pix_limit = &s5p_pix_limit[1],
1956}; 1149};
1957 1150
1958static struct samsung_fimc_variant fimc3_variant_exynos4 = { 1151static struct fimc_variant fimc3_variant_exynos4 = {
1959 .pix_hoff = 1, 1152 .pix_hoff = 1,
1960 .has_cam_if = 1, 1153 .has_cam_if = 1,
1961 .has_cistatus2 = 1, 1154 .has_cistatus2 = 1,
@@ -1970,7 +1163,7 @@ static struct samsung_fimc_variant fimc3_variant_exynos4 = {
1970}; 1163};
1971 1164
1972/* S5PC100 */ 1165/* S5PC100 */
1973static struct samsung_fimc_driverdata fimc_drvdata_s5p = { 1166static struct fimc_drvdata fimc_drvdata_s5p = {
1974 .variant = { 1167 .variant = {
1975 [0] = &fimc0_variant_s5p, 1168 [0] = &fimc0_variant_s5p,
1976 [1] = &fimc0_variant_s5p, 1169 [1] = &fimc0_variant_s5p,
@@ -1981,7 +1174,7 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5p = {
1981}; 1174};
1982 1175
1983/* S5PV210, S5PC110 */ 1176/* S5PV210, S5PC110 */
1984static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { 1177static struct fimc_drvdata fimc_drvdata_s5pv210 = {
1985 .variant = { 1178 .variant = {
1986 [0] = &fimc0_variant_s5pv210, 1179 [0] = &fimc0_variant_s5pv210,
1987 [1] = &fimc1_variant_s5pv210, 1180 [1] = &fimc1_variant_s5pv210,
@@ -1991,8 +1184,8 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = {
1991 .lclk_frequency = 166000000UL, 1184 .lclk_frequency = 166000000UL,
1992}; 1185};
1993 1186
1994/* S5PV310, S5PC210 */ 1187/* EXYNOS4210, S5PV310, S5PC210 */
1995static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = { 1188static struct fimc_drvdata fimc_drvdata_exynos4 = {
1996 .variant = { 1189 .variant = {
1997 [0] = &fimc0_variant_exynos4, 1190 [0] = &fimc0_variant_exynos4,
1998 [1] = &fimc0_variant_exynos4, 1191 [1] = &fimc0_variant_exynos4,
@@ -2036,7 +1229,7 @@ static struct platform_driver fimc_driver = {
2036 1229
2037int __init fimc_register_driver(void) 1230int __init fimc_register_driver(void)
2038{ 1231{
2039 return platform_driver_probe(&fimc_driver, fimc_probe); 1232 return platform_driver_register(&fimc_driver);
2040} 1233}
2041 1234
2042void __exit fimc_unregister_driver(void) 1235void __exit fimc_unregister_driver(void)
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 84fd83550bd7..95b27ae5cf27 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. 2 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
@@ -17,6 +17,7 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <asm/sizes.h>
20 21
21#include <media/media-entity.h> 22#include <media/media-entity.h>
22#include <media/videobuf2-core.h> 23#include <media/videobuf2-core.h>
@@ -26,8 +27,6 @@
26#include <media/v4l2-mediabus.h> 27#include <media/v4l2-mediabus.h>
27#include <media/s5p_fimc.h> 28#include <media/s5p_fimc.h>
28 29
29#include "regs-fimc.h"
30
31#define err(fmt, args...) \ 30#define err(fmt, args...) \
32 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args) 31 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
33 32
@@ -78,26 +77,31 @@ enum fimc_dev_flags {
78#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state) 77#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
79 78
80enum fimc_datapath { 79enum fimc_datapath {
81 FIMC_CAMERA, 80 FIMC_IO_NONE,
82 FIMC_DMA, 81 FIMC_IO_CAMERA,
83 FIMC_LCDFIFO, 82 FIMC_IO_DMA,
84 FIMC_WRITEBACK 83 FIMC_IO_LCDFIFO,
84 FIMC_IO_WRITEBACK,
85 FIMC_IO_ISP,
85}; 86};
86 87
87enum fimc_color_fmt { 88enum fimc_color_fmt {
88 S5P_FIMC_RGB444 = 0x10, 89 FIMC_FMT_RGB444 = 0x10,
89 S5P_FIMC_RGB555, 90 FIMC_FMT_RGB555,
90 S5P_FIMC_RGB565, 91 FIMC_FMT_RGB565,
91 S5P_FIMC_RGB666, 92 FIMC_FMT_RGB666,
92 S5P_FIMC_RGB888, 93 FIMC_FMT_RGB888,
93 S5P_FIMC_RGB30_LOCAL, 94 FIMC_FMT_RGB30_LOCAL,
94 S5P_FIMC_YCBCR420 = 0x20, 95 FIMC_FMT_YCBCR420 = 0x20,
95 S5P_FIMC_YCBYCR422, 96 FIMC_FMT_YCBYCR422,
96 S5P_FIMC_YCRYCB422, 97 FIMC_FMT_YCRYCB422,
97 S5P_FIMC_CBYCRY422, 98 FIMC_FMT_CBYCRY422,
98 S5P_FIMC_CRYCBY422, 99 FIMC_FMT_CRYCBY422,
99 S5P_FIMC_YCBCR444_LOCAL, 100 FIMC_FMT_YCBCR444_LOCAL,
100 S5P_FIMC_JPEG = 0x40, 101 FIMC_FMT_JPEG = 0x40,
102 FIMC_FMT_RAW8 = 0x80,
103 FIMC_FMT_RAW10,
104 FIMC_FMT_RAW12,
101}; 105};
102 106
103#define fimc_fmt_is_rgb(x) (!!((x) & 0x10)) 107#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
@@ -106,24 +110,11 @@ enum fimc_color_fmt {
106#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \ 110#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
107 __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 111 __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
108 112
109/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */
110#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB
111
112/* The embedded image effect selection */
113#define S5P_FIMC_EFFECT_ORIGINAL S5P_CIIMGEFF_FIN_BYPASS
114#define S5P_FIMC_EFFECT_ARBITRARY S5P_CIIMGEFF_FIN_ARBITRARY
115#define S5P_FIMC_EFFECT_NEGATIVE S5P_CIIMGEFF_FIN_NEGATIVE
116#define S5P_FIMC_EFFECT_ARTFREEZE S5P_CIIMGEFF_FIN_ARTFREEZE
117#define S5P_FIMC_EFFECT_EMBOSSING S5P_CIIMGEFF_FIN_EMBOSSING
118#define S5P_FIMC_EFFECT_SIKHOUETTE S5P_CIIMGEFF_FIN_SILHOUETTE
119
120/* The hardware context state. */ 113/* The hardware context state. */
121#define FIMC_PARAMS (1 << 0) 114#define FIMC_PARAMS (1 << 0)
122#define FIMC_SRC_ADDR (1 << 1)
123#define FIMC_DST_ADDR (1 << 2)
124#define FIMC_SRC_FMT (1 << 3) 115#define FIMC_SRC_FMT (1 << 3)
125#define FIMC_DST_FMT (1 << 4) 116#define FIMC_DST_FMT (1 << 4)
126#define FIMC_DST_CROP (1 << 5) 117#define FIMC_COMPOSE (1 << 5)
127#define FIMC_CTX_M2M (1 << 16) 118#define FIMC_CTX_M2M (1 << 16)
128#define FIMC_CTX_CAP (1 << 17) 119#define FIMC_CTX_CAP (1 << 17)
129#define FIMC_CTX_SHUT (1 << 18) 120#define FIMC_CTX_SHUT (1 << 18)
@@ -333,7 +324,7 @@ struct fimc_vid_cap {
333 struct fimc_ctx *ctx; 324 struct fimc_ctx *ctx;
334 struct vb2_alloc_ctx *alloc_ctx; 325 struct vb2_alloc_ctx *alloc_ctx;
335 struct video_device *vfd; 326 struct video_device *vfd;
336 struct v4l2_subdev *subdev; 327 struct v4l2_subdev subdev;
337 struct media_pad vd_pad; 328 struct media_pad vd_pad;
338 struct v4l2_mbus_framefmt mf; 329 struct v4l2_mbus_framefmt mf;
339 struct media_pad sd_pads[FIMC_SD_PADS_NUM]; 330 struct media_pad sd_pads[FIMC_SD_PADS_NUM];
@@ -370,8 +361,7 @@ struct fimc_pix_limit {
370}; 361};
371 362
372/** 363/**
373 * struct samsung_fimc_variant - camera interface variant information 364 * struct fimc_variant - FIMC device variant information
374 *
375 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes 365 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
376 * @has_inp_rot: set if has input rotator 366 * @has_inp_rot: set if has input rotator
377 * @has_out_rot: set if has output rotator 367 * @has_out_rot: set if has output rotator
@@ -386,7 +376,7 @@ struct fimc_pix_limit {
386 * @min_vsize_align: minimum vertical pixel size alignment 376 * @min_vsize_align: minimum vertical pixel size alignment
387 * @out_buf_count: the number of buffers in output DMA sequence 377 * @out_buf_count: the number of buffers in output DMA sequence
388 */ 378 */
389struct samsung_fimc_variant { 379struct fimc_variant {
390 unsigned int pix_hoff:1; 380 unsigned int pix_hoff:1;
391 unsigned int has_inp_rot:1; 381 unsigned int has_inp_rot:1;
392 unsigned int has_out_rot:1; 382 unsigned int has_out_rot:1;
@@ -403,23 +393,19 @@ struct samsung_fimc_variant {
403}; 393};
404 394
405/** 395/**
406 * struct samsung_fimc_driverdata - per device type driver data for init time. 396 * struct fimc_drvdata - per device type driver data
407 * 397 * @variant: variant information for this device
408 * @variant: the variant information for this driver. 398 * @num_entities: number of fimc instances available in a SoC
409 * @dev_cnt: number of fimc sub-devices available in SoC 399 * @lclk_frequency: local bus clock frequency
410 * @lclk_frequency: fimc bus clock frequency
411 */ 400 */
412struct samsung_fimc_driverdata { 401struct fimc_drvdata {
413 struct samsung_fimc_variant *variant[FIMC_MAX_DEVS]; 402 struct fimc_variant *variant[FIMC_MAX_DEVS];
414 unsigned long lclk_frequency; 403 int num_entities;
415 int num_entities; 404 unsigned long lclk_frequency;
416}; 405};
417 406
418struct fimc_pipeline { 407#define fimc_get_drvdata(_pdev) \
419 struct media_pipeline *pipe; 408 ((struct fimc_drvdata *) platform_get_device_id(_pdev)->driver_data)
420 struct v4l2_subdev *sensor;
421 struct v4l2_subdev *csis;
422};
423 409
424struct fimc_ctx; 410struct fimc_ctx;
425 411
@@ -431,10 +417,8 @@ struct fimc_ctx;
431 * @pdata: pointer to the device platform data 417 * @pdata: pointer to the device platform data
432 * @variant: the IP variant information 418 * @variant: the IP variant information
433 * @id: FIMC device index (0..FIMC_MAX_DEVS) 419 * @id: FIMC device index (0..FIMC_MAX_DEVS)
434 * @num_clocks: the number of clocks managed by this device instance
435 * @clock: clocks required for FIMC operation 420 * @clock: clocks required for FIMC operation
436 * @regs: the mapped hardware registers 421 * @regs: the mapped hardware registers
437 * @irq: FIMC interrupt number
438 * @irq_queue: interrupt handler waitqueue 422 * @irq_queue: interrupt handler waitqueue
439 * @v4l2_dev: root v4l2_device 423 * @v4l2_dev: root v4l2_device
440 * @m2m: memory-to-memory V4L2 device information 424 * @m2m: memory-to-memory V4L2 device information
@@ -448,12 +432,10 @@ struct fimc_dev {
448 struct mutex lock; 432 struct mutex lock;
449 struct platform_device *pdev; 433 struct platform_device *pdev;
450 struct s5p_platform_fimc *pdata; 434 struct s5p_platform_fimc *pdata;
451 struct samsung_fimc_variant *variant; 435 struct fimc_variant *variant;
452 u16 id; 436 u16 id;
453 u16 num_clocks;
454 struct clk *clock[MAX_FIMC_CLOCKS]; 437 struct clk *clock[MAX_FIMC_CLOCKS];
455 void __iomem *regs; 438 void __iomem *regs;
456 int irq;
457 wait_queue_head_t irq_queue; 439 wait_queue_head_t irq_queue;
458 struct v4l2_device *v4l2_dev; 440 struct v4l2_device *v4l2_dev;
459 struct fimc_m2m_device m2m; 441 struct fimc_m2m_device m2m;
@@ -464,8 +446,31 @@ struct fimc_dev {
464}; 446};
465 447
466/** 448/**
449 * struct fimc_ctrls - v4l2 controls structure
450 * @handler: the control handler
451 * @colorfx: image effect control
452 * @colorfx_cbcr: Cb/Cr coefficients control
453 * @rotate: image rotation control
454 * @hflip: horizontal flip control
455 * @vflip: vertical flip control
456 * @alpha: RGB alpha control
457 * @ready: true if @handler is initialized
458 */
459struct fimc_ctrls {
460 struct v4l2_ctrl_handler handler;
461 struct {
462 struct v4l2_ctrl *colorfx;
463 struct v4l2_ctrl *colorfx_cbcr;
464 };
465 struct v4l2_ctrl *rotate;
466 struct v4l2_ctrl *hflip;
467 struct v4l2_ctrl *vflip;
468 struct v4l2_ctrl *alpha;
469 bool ready;
470};
471
472/**
467 * fimc_ctx - the device context data 473 * fimc_ctx - the device context data
468 * @slock: spinlock protecting this data structure
469 * @s_frame: source frame properties 474 * @s_frame: source frame properties
470 * @d_frame: destination frame properties 475 * @d_frame: destination frame properties
471 * @out_order_1p: output 1-plane YCBCR order 476 * @out_order_1p: output 1-plane YCBCR order
@@ -484,15 +489,9 @@ struct fimc_dev {
484 * @fimc_dev: the FIMC device this context applies to 489 * @fimc_dev: the FIMC device this context applies to
485 * @m2m_ctx: memory-to-memory device context 490 * @m2m_ctx: memory-to-memory device context
486 * @fh: v4l2 file handle 491 * @fh: v4l2 file handle
487 * @ctrl_handler: v4l2 controls handler 492 * @ctrls: v4l2 controls structure
488 * @ctrl_rotate image rotation control
489 * @ctrl_hflip horizontal flip control
490 * @ctrl_vflip vertical flip control
491 * @ctrl_alpha RGB alpha control
492 * @ctrls_rdy: true if the control handler is initialized
493 */ 493 */
494struct fimc_ctx { 494struct fimc_ctx {
495 spinlock_t slock;
496 struct fimc_frame s_frame; 495 struct fimc_frame s_frame;
497 struct fimc_frame d_frame; 496 struct fimc_frame d_frame;
498 u32 out_order_1p; 497 u32 out_order_1p;
@@ -511,12 +510,7 @@ struct fimc_ctx {
511 struct fimc_dev *fimc_dev; 510 struct fimc_dev *fimc_dev;
512 struct v4l2_m2m_ctx *m2m_ctx; 511 struct v4l2_m2m_ctx *m2m_ctx;
513 struct v4l2_fh fh; 512 struct v4l2_fh fh;
514 struct v4l2_ctrl_handler ctrl_handler; 513 struct fimc_ctrls ctrls;
515 struct v4l2_ctrl *ctrl_rotate;
516 struct v4l2_ctrl *ctrl_hflip;
517 struct v4l2_ctrl *ctrl_vflip;
518 struct v4l2_ctrl *ctrl_alpha;
519 bool ctrls_rdy;
520}; 514};
521 515
522#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh) 516#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
@@ -560,13 +554,13 @@ static inline bool fimc_capture_active(struct fimc_dev *fimc)
560 return ret; 554 return ret;
561} 555}
562 556
563static inline void fimc_ctx_state_lock_set(u32 state, struct fimc_ctx *ctx) 557static inline void fimc_ctx_state_set(u32 state, struct fimc_ctx *ctx)
564{ 558{
565 unsigned long flags; 559 unsigned long flags;
566 560
567 spin_lock_irqsave(&ctx->slock, flags); 561 spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
568 ctx->state |= state; 562 ctx->state |= state;
569 spin_unlock_irqrestore(&ctx->slock, flags); 563 spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
570} 564}
571 565
572static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx) 566static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
@@ -574,9 +568,9 @@ static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
574 unsigned long flags; 568 unsigned long flags;
575 bool ret; 569 bool ret;
576 570
577 spin_lock_irqsave(&ctx->slock, flags); 571 spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
578 ret = (ctx->state & mask) == mask; 572 ret = (ctx->state & mask) == mask;
579 spin_unlock_irqrestore(&ctx->slock, flags); 573 spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
580 return ret; 574 return ret;
581} 575}
582 576
@@ -589,61 +583,13 @@ static inline int tiled_fmt(struct fimc_fmt *fmt)
589static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt) 583static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
590{ 584{
591 switch (fmt->color) { 585 switch (fmt->color) {
592 case S5P_FIMC_RGB444: return 0x0f; 586 case FIMC_FMT_RGB444: return 0x0f;
593 case S5P_FIMC_RGB555: return 0x01; 587 case FIMC_FMT_RGB555: return 0x01;
594 case S5P_FIMC_RGB888: return 0xff; 588 case FIMC_FMT_RGB888: return 0xff;
595 default: return 0; 589 default: return 0;
596 }; 590 };
597} 591}
598 592
599static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
600{
601 u32 cfg = readl(dev->regs + S5P_CIGCTRL);
602 cfg |= S5P_CIGCTRL_IRQ_CLR;
603 writel(cfg, dev->regs + S5P_CIGCTRL);
604}
605
606static inline void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
607{
608 u32 cfg = readl(dev->regs + S5P_CISCCTRL);
609 if (on)
610 cfg |= S5P_CISCCTRL_SCALERSTART;
611 else
612 cfg &= ~S5P_CISCCTRL_SCALERSTART;
613 writel(cfg, dev->regs + S5P_CISCCTRL);
614}
615
616static inline void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
617{
618 u32 cfg = readl(dev->regs + S5P_MSCTRL);
619 if (on)
620 cfg |= S5P_MSCTRL_ENVID;
621 else
622 cfg &= ~S5P_MSCTRL_ENVID;
623 writel(cfg, dev->regs + S5P_MSCTRL);
624}
625
626static inline void fimc_hw_dis_capture(struct fimc_dev *dev)
627{
628 u32 cfg = readl(dev->regs + S5P_CIIMGCPT);
629 cfg &= ~(S5P_CIIMGCPT_IMGCPTEN | S5P_CIIMGCPT_IMGCPTEN_SC);
630 writel(cfg, dev->regs + S5P_CIIMGCPT);
631}
632
633/**
634 * fimc_hw_set_dma_seq - configure output DMA buffer sequence
635 * @mask: each bit corresponds to one of 32 output buffer registers set
636 * 1 to include buffer in the sequence, 0 to disable
637 *
638 * This function mask output DMA ring buffers, i.e. it allows to configure
639 * which of the output buffer address registers will be used by the DMA
640 * engine.
641 */
642static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
643{
644 writel(mask, dev->regs + S5P_CIFCNTSEQ);
645}
646
647static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, 593static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
648 enum v4l2_buf_type type) 594 enum v4l2_buf_type type)
649{ 595{
@@ -665,48 +611,6 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
665 return frame; 611 return frame;
666} 612}
667 613
668/* Return an index to the buffer actually being written. */
669static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
670{
671 u32 reg;
672
673 if (dev->variant->has_cistatus2) {
674 reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
675 return reg > 0 ? --reg : reg;
676 } else {
677 reg = readl(dev->regs + S5P_CISTATUS);
678 return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
679 S5P_CISTATUS_FRAMECNT_SHIFT;
680 }
681}
682
683/* -----------------------------------------------------*/
684/* fimc-reg.c */
685void fimc_hw_reset(struct fimc_dev *fimc);
686void fimc_hw_set_rotation(struct fimc_ctx *ctx);
687void fimc_hw_set_target_format(struct fimc_ctx *ctx);
688void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
689void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
690void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
691void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
692void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
693void fimc_hw_en_capture(struct fimc_ctx *ctx);
694void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active);
695void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
696void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
697void fimc_hw_set_input_path(struct fimc_ctx *ctx);
698void fimc_hw_set_output_path(struct fimc_ctx *ctx);
699void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
700void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
701 int index);
702int fimc_hw_set_camera_source(struct fimc_dev *fimc,
703 struct s5p_fimc_isp_info *cam);
704int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
705int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
706 struct s5p_fimc_isp_info *cam);
707int fimc_hw_set_camera_type(struct fimc_dev *fimc,
708 struct s5p_fimc_isp_info *cam);
709
710/* -----------------------------------------------------*/ 614/* -----------------------------------------------------*/
711/* fimc-core.c */ 615/* fimc-core.c */
712int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv, 616int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
@@ -720,6 +624,7 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
720 struct v4l2_pix_format_mplane *pix); 624 struct v4l2_pix_format_mplane *pix);
721struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, 625struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
722 unsigned int mask, int index); 626 unsigned int mask, int index);
627struct fimc_fmt *fimc_get_format(unsigned int index);
723 628
724int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, 629int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
725 int dw, int dh, int rotation); 630 int dw, int dh, int rotation);
@@ -730,7 +635,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
730void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); 635void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
731void fimc_set_yuv_order(struct fimc_ctx *ctx); 636void fimc_set_yuv_order(struct fimc_ctx *ctx);
732void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f); 637void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
733void fimc_capture_irq_handler(struct fimc_dev *fimc, bool done); 638void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
734 639
735int fimc_register_m2m_device(struct fimc_dev *fimc, 640int fimc_register_m2m_device(struct fimc_dev *fimc,
736 struct v4l2_device *v4l2_dev); 641 struct v4l2_device *v4l2_dev);
@@ -739,33 +644,18 @@ int fimc_register_driver(void);
739void fimc_unregister_driver(void); 644void fimc_unregister_driver(void);
740 645
741/* -----------------------------------------------------*/ 646/* -----------------------------------------------------*/
647/* fimc-m2m.c */
648void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state);
649
650/* -----------------------------------------------------*/
742/* fimc-capture.c */ 651/* fimc-capture.c */
743int fimc_register_capture_device(struct fimc_dev *fimc, 652int fimc_initialize_capture_subdev(struct fimc_dev *fimc);
744 struct v4l2_device *v4l2_dev); 653void fimc_unregister_capture_subdev(struct fimc_dev *fimc);
745void fimc_unregister_capture_device(struct fimc_dev *fimc);
746int fimc_capture_ctrls_create(struct fimc_dev *fimc); 654int fimc_capture_ctrls_create(struct fimc_dev *fimc);
747int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
748 struct fimc_vid_buffer *fimc_vb);
749void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, 655void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
750 void *arg); 656 void *arg);
751int fimc_capture_suspend(struct fimc_dev *fimc); 657int fimc_capture_suspend(struct fimc_dev *fimc);
752int fimc_capture_resume(struct fimc_dev *fimc); 658int fimc_capture_resume(struct fimc_dev *fimc);
753int fimc_capture_config_update(struct fimc_ctx *ctx);
754
755/* Locking: the caller holds fimc->slock */
756static inline void fimc_activate_capture(struct fimc_ctx *ctx)
757{
758 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
759 fimc_hw_en_capture(ctx);
760}
761
762static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
763{
764 fimc_hw_en_lastirq(fimc, true);
765 fimc_hw_dis_capture(fimc);
766 fimc_hw_enable_scaler(fimc, false);
767 fimc_hw_en_lastirq(fimc, false);
768}
769 659
770/* 660/*
771 * Buffer list manipulation functions. Must be called with fimc.slock held. 661 * Buffer list manipulation functions. Must be called with fimc.slock held.
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.c b/drivers/media/video/s5p-fimc/fimc-lite-reg.c
new file mode 100644
index 000000000000..419adfb7cdf9
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-lite-reg.c
@@ -0,0 +1,300 @@
1/*
2 * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@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 version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/io.h>
13#include <linux/delay.h>
14#include <media/s5p_fimc.h>
15
16#include "fimc-lite-reg.h"
17#include "fimc-lite.h"
18#include "fimc-core.h"
19
20#define FLITE_RESET_TIMEOUT 50 /* in ms */
21
22void flite_hw_reset(struct fimc_lite *dev)
23{
24 unsigned long end = jiffies + msecs_to_jiffies(FLITE_RESET_TIMEOUT);
25 u32 cfg;
26
27 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
28 cfg |= FLITE_REG_CIGCTRL_SWRST_REQ;
29 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
30
31 while (time_is_after_jiffies(end)) {
32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
33 if (cfg & FLITE_REG_CIGCTRL_SWRST_RDY)
34 break;
35 usleep_range(1000, 5000);
36 }
37
38 cfg |= FLITE_REG_CIGCTRL_SWRST;
39 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
40}
41
42void flite_hw_clear_pending_irq(struct fimc_lite *dev)
43{
44 u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS);
45 cfg &= ~FLITE_REG_CISTATUS_IRQ_CAM;
46 writel(cfg, dev->regs + FLITE_REG_CISTATUS);
47}
48
49u32 flite_hw_get_interrupt_source(struct fimc_lite *dev)
50{
51 u32 intsrc = readl(dev->regs + FLITE_REG_CISTATUS);
52 return intsrc & FLITE_REG_CISTATUS_IRQ_MASK;
53}
54
55void flite_hw_clear_last_capture_end(struct fimc_lite *dev)
56{
57
58 u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS2);
59 cfg &= ~FLITE_REG_CISTATUS2_LASTCAPEND;
60 writel(cfg, dev->regs + FLITE_REG_CISTATUS2);
61}
62
63void flite_hw_set_interrupt_mask(struct fimc_lite *dev)
64{
65 u32 cfg, intsrc;
66
67 /* Select interrupts to be enabled for each output mode */
68 if (dev->out_path == FIMC_IO_DMA) {
69 intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
70 FLITE_REG_CIGCTRL_IRQ_LASTEN |
71 FLITE_REG_CIGCTRL_IRQ_STARTEN;
72 } else {
73 /* An output to the FIMC-IS */
74 intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
75 FLITE_REG_CIGCTRL_IRQ_LASTEN;
76 }
77
78 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
79 cfg |= FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK;
80 cfg &= ~intsrc;
81 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
82}
83
84void flite_hw_capture_start(struct fimc_lite *dev)
85{
86 u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
87 cfg |= FLITE_REG_CIIMGCPT_IMGCPTEN;
88 writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
89}
90
91void flite_hw_capture_stop(struct fimc_lite *dev)
92{
93 u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
94 cfg &= ~FLITE_REG_CIIMGCPT_IMGCPTEN;
95 writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
96}
97
98/*
99 * Test pattern (color bars) enable/disable. External sensor
100 * pixel clock must be active for the test pattern to work.
101 */
102void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on)
103{
104 u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
105 if (on)
106 cfg |= FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
107 else
108 cfg &= ~FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
109 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
110}
111
112static const u32 src_pixfmt_map[8][3] = {
113 { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR,
114 FLITE_REG_CIGCTRL_YUV422_1P },
115 { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB,
116 FLITE_REG_CIGCTRL_YUV422_1P },
117 { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY,
118 FLITE_REG_CIGCTRL_YUV422_1P },
119 { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY,
120 FLITE_REG_CIGCTRL_YUV422_1P },
121 { V4L2_PIX_FMT_SGRBG8, 0, FLITE_REG_CIGCTRL_RAW8 },
122 { V4L2_PIX_FMT_SGRBG10, 0, FLITE_REG_CIGCTRL_RAW10 },
123 { V4L2_PIX_FMT_SGRBG12, 0, FLITE_REG_CIGCTRL_RAW12 },
124 { V4L2_MBUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) },
125};
126
127/* Set camera input pixel format and resolution */
128void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
129{
130 enum v4l2_mbus_pixelcode pixelcode = dev->fmt->mbus_code;
131 unsigned int i = ARRAY_SIZE(src_pixfmt_map);
132 u32 cfg;
133
134 while (i-- >= 0) {
135 if (src_pixfmt_map[i][0] == pixelcode)
136 break;
137 }
138
139 if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
140 v4l2_err(dev->vfd,
141 "Unsupported pixel code, falling back to %#08x\n",
142 src_pixfmt_map[i][0]);
143 }
144
145 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
146 cfg &= ~FLITE_REG_CIGCTRL_FMT_MASK;
147 cfg |= src_pixfmt_map[i][2];
148 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
149
150 cfg = readl(dev->regs + FLITE_REG_CISRCSIZE);
151 cfg &= ~(FLITE_REG_CISRCSIZE_ORDER422_MASK |
152 FLITE_REG_CISRCSIZE_SIZE_CAM_MASK);
153 cfg |= (f->f_width << 16) | f->f_height;
154 cfg |= src_pixfmt_map[i][1];
155 writel(cfg, dev->regs + FLITE_REG_CISRCSIZE);
156}
157
158/* Set the camera host input window offsets (cropping) */
159void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f)
160{
161 u32 hoff2, voff2;
162 u32 cfg;
163
164 cfg = readl(dev->regs + FLITE_REG_CIWDOFST);
165 cfg &= ~FLITE_REG_CIWDOFST_OFST_MASK;
166 cfg |= (f->rect.left << 16) | f->rect.top;
167 cfg |= FLITE_REG_CIWDOFST_WINOFSEN;
168 writel(cfg, dev->regs + FLITE_REG_CIWDOFST);
169
170 hoff2 = f->f_width - f->rect.width - f->rect.left;
171 voff2 = f->f_height - f->rect.height - f->rect.top;
172
173 cfg = (hoff2 << 16) | voff2;
174 writel(cfg, dev->regs + FLITE_REG_CIWDOFST2);
175}
176
177/* Select camera port (A, B) */
178static void flite_hw_set_camera_port(struct fimc_lite *dev, int id)
179{
180 u32 cfg = readl(dev->regs + FLITE_REG_CIGENERAL);
181 if (id == 0)
182 cfg &= ~FLITE_REG_CIGENERAL_CAM_B;
183 else
184 cfg |= FLITE_REG_CIGENERAL_CAM_B;
185 writel(cfg, dev->regs + FLITE_REG_CIGENERAL);
186}
187
188/* Select serial or parallel bus, camera port (A,B) and set signals polarity */
189void flite_hw_set_camera_bus(struct fimc_lite *dev,
190 struct s5p_fimc_isp_info *s_info)
191{
192 u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
193 unsigned int flags = s_info->flags;
194
195 if (s_info->bus_type != FIMC_MIPI_CSI2) {
196 cfg &= ~(FLITE_REG_CIGCTRL_SELCAM_MIPI |
197 FLITE_REG_CIGCTRL_INVPOLPCLK |
198 FLITE_REG_CIGCTRL_INVPOLVSYNC |
199 FLITE_REG_CIGCTRL_INVPOLHREF);
200
201 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
202 cfg |= FLITE_REG_CIGCTRL_INVPOLPCLK;
203
204 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
205 cfg |= FLITE_REG_CIGCTRL_INVPOLVSYNC;
206
207 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
208 cfg |= FLITE_REG_CIGCTRL_INVPOLHREF;
209 } else {
210 cfg |= FLITE_REG_CIGCTRL_SELCAM_MIPI;
211 }
212
213 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
214
215 flite_hw_set_camera_port(dev, s_info->mux_id);
216}
217
218void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
219{
220 static const u32 pixcode[4][2] = {
221 { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR },
222 { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB },
223 { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY },
224 { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY },
225 };
226 u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
227 unsigned int i = ARRAY_SIZE(pixcode);
228
229 while (i-- >= 0)
230 if (pixcode[i][0] == dev->fmt->mbus_code)
231 break;
232 cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK;
233 writel(cfg | pixcode[i][1], dev->regs + FLITE_REG_CIODMAFMT);
234}
235
236void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f)
237{
238 u32 cfg;
239
240 /* Maximum output pixel size */
241 cfg = readl(dev->regs + FLITE_REG_CIOCAN);
242 cfg &= ~FLITE_REG_CIOCAN_MASK;
243 cfg = (f->f_height << 16) | f->f_width;
244 writel(cfg, dev->regs + FLITE_REG_CIOCAN);
245
246 /* DMA offsets */
247 cfg = readl(dev->regs + FLITE_REG_CIOOFF);
248 cfg &= ~FLITE_REG_CIOOFF_MASK;
249 cfg |= (f->rect.top << 16) | f->rect.left;
250 writel(cfg, dev->regs + FLITE_REG_CIOOFF);
251}
252
253/* Enable/disable output DMA, set output pixel size and offsets (composition) */
254void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
255 bool enable)
256{
257 u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
258
259 if (!enable) {
260 cfg |= FLITE_REG_CIGCTRL_ODMA_DISABLE;
261 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
262 return;
263 }
264
265 cfg &= ~FLITE_REG_CIGCTRL_ODMA_DISABLE;
266 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
267
268 flite_hw_set_out_order(dev, f);
269 flite_hw_set_dma_window(dev, f);
270}
271
272void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
273{
274 struct {
275 u32 offset;
276 const char * const name;
277 } registers[] = {
278 { 0x00, "CISRCSIZE" },
279 { 0x04, "CIGCTRL" },
280 { 0x08, "CIIMGCPT" },
281 { 0x0c, "CICPTSEQ" },
282 { 0x10, "CIWDOFST" },
283 { 0x14, "CIWDOFST2" },
284 { 0x18, "CIODMAFMT" },
285 { 0x20, "CIOCAN" },
286 { 0x24, "CIOOFF" },
287 { 0x30, "CIOSA" },
288 { 0x40, "CISTATUS" },
289 { 0x44, "CISTATUS2" },
290 { 0xf0, "CITHOLD" },
291 { 0xfc, "CIGENERAL" },
292 };
293 u32 i;
294
295 pr_info("--- %s ---\n", label);
296 for (i = 0; i < ARRAY_SIZE(registers); i++) {
297 u32 cfg = readl(dev->regs + registers[i].offset);
298 pr_info("%s: %s:\t0x%08x\n", __func__, registers[i].name, cfg);
299 }
300}
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.h b/drivers/media/video/s5p-fimc/fimc-lite-reg.h
new file mode 100644
index 000000000000..adb9e9e6f3c2
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-lite-reg.h
@@ -0,0 +1,150 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FIMC_LITE_REG_H_
10#define FIMC_LITE_REG_H_
11
12#include "fimc-lite.h"
13
14/* Camera Source size */
15#define FLITE_REG_CISRCSIZE 0x00
16#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR (0 << 14)
17#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB (1 << 14)
18#define FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY (2 << 14)
19#define FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY (3 << 14)
20#define FLITE_REG_CISRCSIZE_ORDER422_MASK (0x3 << 14)
21#define FLITE_REG_CISRCSIZE_SIZE_CAM_MASK (0x3fff << 16 | 0x3fff)
22
23/* Global control */
24#define FLITE_REG_CIGCTRL 0x04
25#define FLITE_REG_CIGCTRL_YUV422_1P (0x1e << 24)
26#define FLITE_REG_CIGCTRL_RAW8 (0x2a << 24)
27#define FLITE_REG_CIGCTRL_RAW10 (0x2b << 24)
28#define FLITE_REG_CIGCTRL_RAW12 (0x2c << 24)
29#define FLITE_REG_CIGCTRL_RAW14 (0x2d << 24)
30/* User defined formats. x = 0...15 */
31#define FLITE_REG_CIGCTRL_USER(x) ((0x30 + x - 1) << 24)
32#define FLITE_REG_CIGCTRL_FMT_MASK (0x3f << 24)
33#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE (1 << 21)
34#define FLITE_REG_CIGCTRL_ODMA_DISABLE (1 << 20)
35#define FLITE_REG_CIGCTRL_SWRST_REQ (1 << 19)
36#define FLITE_REG_CIGCTRL_SWRST_RDY (1 << 18)
37#define FLITE_REG_CIGCTRL_SWRST (1 << 17)
38#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR (1 << 15)
39#define FLITE_REG_CIGCTRL_INVPOLPCLK (1 << 14)
40#define FLITE_REG_CIGCTRL_INVPOLVSYNC (1 << 13)
41#define FLITE_REG_CIGCTRL_INVPOLHREF (1 << 12)
42/* Interrupts mask bits (1 disables an interrupt) */
43#define FLITE_REG_CIGCTRL_IRQ_LASTEN (1 << 8)
44#define FLITE_REG_CIGCTRL_IRQ_ENDEN (1 << 7)
45#define FLITE_REG_CIGCTRL_IRQ_STARTEN (1 << 6)
46#define FLITE_REG_CIGCTRL_IRQ_OVFEN (1 << 5)
47#define FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK (0xf << 5)
48#define FLITE_REG_CIGCTRL_SELCAM_MIPI (1 << 3)
49
50/* Image Capture Enable */
51#define FLITE_REG_CIIMGCPT 0x08
52#define FLITE_REG_CIIMGCPT_IMGCPTEN (1 << 31)
53#define FLITE_REG_CIIMGCPT_CPT_FREN (1 << 25)
54#define FLITE_REG_CIIMGCPT_CPT_MOD_FRCNT (1 << 18)
55#define FLITE_REG_CIIMGCPT_CPT_MOD_FREN (0 << 18)
56
57/* Capture Sequence */
58#define FLITE_REG_CICPTSEQ 0x0c
59
60/* Camera Window Offset */
61#define FLITE_REG_CIWDOFST 0x10
62#define FLITE_REG_CIWDOFST_WINOFSEN (1 << 31)
63#define FLITE_REG_CIWDOFST_CLROVIY (1 << 31)
64#define FLITE_REG_CIWDOFST_CLROVFICB (1 << 15)
65#define FLITE_REG_CIWDOFST_CLROVFICR (1 << 14)
66#define FLITE_REG_CIWDOFST_OFST_MASK ((0x1fff << 16) | 0x1fff)
67
68/* Camera Window Offset2 */
69#define FLITE_REG_CIWDOFST2 0x14
70
71/* Camera Output DMA Format */
72#define FLITE_REG_CIODMAFMT 0x18
73#define FLITE_REG_CIODMAFMT_RAW_CON (1 << 15)
74#define FLITE_REG_CIODMAFMT_PACK12 (1 << 14)
75#define FLITE_REG_CIODMAFMT_CRYCBY (0 << 4)
76#define FLITE_REG_CIODMAFMT_CBYCRY (1 << 4)
77#define FLITE_REG_CIODMAFMT_YCRYCB (2 << 4)
78#define FLITE_REG_CIODMAFMT_YCBYCR (3 << 4)
79#define FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK (0x3 << 4)
80
81/* Camera Output Canvas */
82#define FLITE_REG_CIOCAN 0x20
83#define FLITE_REG_CIOCAN_MASK ((0x3fff << 16) | 0x3fff)
84
85/* Camera Output DMA Offset */
86#define FLITE_REG_CIOOFF 0x24
87#define FLITE_REG_CIOOFF_MASK ((0x3fff << 16) | 0x3fff)
88
89/* Camera Output DMA Start Address */
90#define FLITE_REG_CIOSA 0x30
91
92/* Camera Status */
93#define FLITE_REG_CISTATUS 0x40
94#define FLITE_REG_CISTATUS_MIPI_VVALID (1 << 22)
95#define FLITE_REG_CISTATUS_MIPI_HVALID (1 << 21)
96#define FLITE_REG_CISTATUS_MIPI_DVALID (1 << 20)
97#define FLITE_REG_CISTATUS_ITU_VSYNC (1 << 14)
98#define FLITE_REG_CISTATUS_ITU_HREFF (1 << 13)
99#define FLITE_REG_CISTATUS_OVFIY (1 << 10)
100#define FLITE_REG_CISTATUS_OVFICB (1 << 9)
101#define FLITE_REG_CISTATUS_OVFICR (1 << 8)
102#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW (1 << 7)
103#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND (1 << 6)
104#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART (1 << 5)
105#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND (1 << 4)
106#define FLITE_REG_CISTATUS_IRQ_CAM (1 << 0)
107#define FLITE_REG_CISTATUS_IRQ_MASK (0xf << 4)
108
109/* Camera Status2 */
110#define FLITE_REG_CISTATUS2 0x44
111#define FLITE_REG_CISTATUS2_LASTCAPEND (1 << 1)
112#define FLITE_REG_CISTATUS2_FRMEND (1 << 0)
113
114/* Qos Threshold */
115#define FLITE_REG_CITHOLD 0xf0
116#define FLITE_REG_CITHOLD_W_QOS_EN (1 << 30)
117
118/* Camera General Purpose */
119#define FLITE_REG_CIGENERAL 0xfc
120/* b0: 1 - camera B, 0 - camera A */
121#define FLITE_REG_CIGENERAL_CAM_B (1 << 0)
122
123/* ----------------------------------------------------------------------------
124 * Function declarations
125 */
126void flite_hw_reset(struct fimc_lite *dev);
127void flite_hw_clear_pending_irq(struct fimc_lite *dev);
128u32 flite_hw_get_interrupt_source(struct fimc_lite *dev);
129void flite_hw_clear_last_capture_end(struct fimc_lite *dev);
130void flite_hw_set_interrupt_mask(struct fimc_lite *dev);
131void flite_hw_capture_start(struct fimc_lite *dev);
132void flite_hw_capture_stop(struct fimc_lite *dev);
133void flite_hw_set_camera_bus(struct fimc_lite *dev,
134 struct s5p_fimc_isp_info *s_info);
135void flite_hw_set_camera_polarity(struct fimc_lite *dev,
136 struct s5p_fimc_isp_info *cam);
137void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f);
138void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f);
139
140void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
141 bool enable);
142void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
143void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
144void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
145
146static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
147{
148 writel(paddr, dev->regs + FLITE_REG_CIOSA);
149}
150#endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c
new file mode 100644
index 000000000000..400d701aef04
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-lite.c
@@ -0,0 +1,1576 @@
1/*
2 * Samsung EXYNOS FIMC-LITE (camera host interface) driver
3*
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@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 version 2 as
9 * published by the Free Software Foundation.
10 */
11#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
12
13#include <linux/bug.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
23#include <linux/slab.h>
24#include <linux/videodev2.h>
25
26#include <media/v4l2-device.h>
27#include <media/v4l2-ioctl.h>
28#include <media/v4l2-mem2mem.h>
29#include <media/videobuf2-core.h>
30#include <media/videobuf2-dma-contig.h>
31
32#include "fimc-mdevice.h"
33#include "fimc-core.h"
34#include "fimc-lite-reg.h"
35
36static int debug;
37module_param(debug, int, 0644);
38
39static const struct fimc_fmt fimc_lite_formats[] = {
40 {
41 .name = "YUV 4:2:2 packed, YCbYCr",
42 .fourcc = V4L2_PIX_FMT_YUYV,
43 .depth = { 16 },
44 .color = FIMC_FMT_YCBYCR422,
45 .memplanes = 1,
46 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
47 }, {
48 .name = "YUV 4:2:2 packed, CbYCrY",
49 .fourcc = V4L2_PIX_FMT_UYVY,
50 .depth = { 16 },
51 .color = FIMC_FMT_CBYCRY422,
52 .memplanes = 1,
53 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
54 }, {
55 .name = "YUV 4:2:2 packed, CrYCbY",
56 .fourcc = V4L2_PIX_FMT_VYUY,
57 .depth = { 16 },
58 .color = FIMC_FMT_CRYCBY422,
59 .memplanes = 1,
60 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
61 }, {
62 .name = "YUV 4:2:2 packed, YCrYCb",
63 .fourcc = V4L2_PIX_FMT_YVYU,
64 .depth = { 16 },
65 .color = FIMC_FMT_YCRYCB422,
66 .memplanes = 1,
67 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
68 }, {
69 .name = "RAW8 (GRBG)",
70 .fourcc = V4L2_PIX_FMT_SGRBG8,
71 .depth = { 8 },
72 .color = FIMC_FMT_RAW8,
73 .memplanes = 1,
74 .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8,
75 }, {
76 .name = "RAW10 (GRBG)",
77 .fourcc = V4L2_PIX_FMT_SGRBG10,
78 .depth = { 10 },
79 .color = FIMC_FMT_RAW10,
80 .memplanes = 1,
81 .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10,
82 }, {
83 .name = "RAW12 (GRBG)",
84 .fourcc = V4L2_PIX_FMT_SGRBG12,
85 .depth = { 12 },
86 .color = FIMC_FMT_RAW12,
87 .memplanes = 1,
88 .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12,
89 },
90};
91
92/**
93 * fimc_lite_find_format - lookup fimc color format by fourcc or media bus code
94 * @pixelformat: fourcc to match, ignored if null
95 * @mbus_code: media bus code to match, ignored if null
96 * @index: index to the fimc_lite_formats array, ignored if negative
97 */
98static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
99 const u32 *mbus_code, int index)
100{
101 const struct fimc_fmt *fmt, *def_fmt = NULL;
102 unsigned int i;
103 int id = 0;
104
105 if (index >= (int)ARRAY_SIZE(fimc_lite_formats))
106 return NULL;
107
108 for (i = 0; i < ARRAY_SIZE(fimc_lite_formats); ++i) {
109 fmt = &fimc_lite_formats[i];
110 if (pixelformat && fmt->fourcc == *pixelformat)
111 return fmt;
112 if (mbus_code && fmt->mbus_code == *mbus_code)
113 return fmt;
114 if (index == id)
115 def_fmt = fmt;
116 id++;
117 }
118 return def_fmt;
119}
120
121static int fimc_lite_hw_init(struct fimc_lite *fimc)
122{
123 struct fimc_pipeline *pipeline = &fimc->pipeline;
124 struct fimc_sensor_info *sensor;
125 unsigned long flags;
126
127 if (pipeline->subdevs[IDX_SENSOR] == NULL)
128 return -ENXIO;
129
130 if (fimc->fmt == NULL)
131 return -EINVAL;
132
133 sensor = v4l2_get_subdev_hostdata(pipeline->subdevs[IDX_SENSOR]);
134 spin_lock_irqsave(&fimc->slock, flags);
135
136 flite_hw_set_camera_bus(fimc, sensor->pdata);
137 flite_hw_set_source_format(fimc, &fimc->inp_frame);
138 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
139 flite_hw_set_output_dma(fimc, &fimc->out_frame, true);
140 flite_hw_set_interrupt_mask(fimc);
141 flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
142
143 if (debug > 0)
144 flite_hw_dump_regs(fimc, __func__);
145
146 spin_unlock_irqrestore(&fimc->slock, flags);
147 return 0;
148}
149
150/*
151 * Reinitialize the driver so it is ready to start the streaming again.
152 * Set fimc->state to indicate stream off and the hardware shut down state.
153 * If not suspending (@suspend is false), return any buffers to videobuf2.
154 * Otherwise put any owned buffers onto the pending buffers queue, so they
155 * can be re-spun when the device is being resumed. Also perform FIMC
156 * software reset and disable streaming on the whole pipeline if required.
157 */
158static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
159{
160 struct flite_buffer *buf;
161 unsigned long flags;
162 bool streaming;
163
164 spin_lock_irqsave(&fimc->slock, flags);
165 streaming = fimc->state & (1 << ST_SENSOR_STREAM);
166
167 fimc->state &= ~(1 << ST_FLITE_RUN | 1 << ST_FLITE_OFF |
168 1 << ST_FLITE_STREAM | 1 << ST_SENSOR_STREAM);
169 if (suspend)
170 fimc->state |= (1 << ST_FLITE_SUSPENDED);
171 else
172 fimc->state &= ~(1 << ST_FLITE_PENDING |
173 1 << ST_FLITE_SUSPENDED);
174
175 /* Release unused buffers */
176 while (!suspend && !list_empty(&fimc->pending_buf_q)) {
177 buf = fimc_lite_pending_queue_pop(fimc);
178 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
179 }
180 /* If suspending put unused buffers onto pending queue */
181 while (!list_empty(&fimc->active_buf_q)) {
182 buf = fimc_lite_active_queue_pop(fimc);
183 if (suspend)
184 fimc_lite_pending_queue_add(fimc, buf);
185 else
186 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
187 }
188
189 spin_unlock_irqrestore(&fimc->slock, flags);
190
191 flite_hw_reset(fimc);
192
193 if (!streaming)
194 return 0;
195
196 return fimc_pipeline_s_stream(&fimc->pipeline, 0);
197}
198
199static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
200{
201 unsigned long flags;
202
203 if (!fimc_lite_active(fimc))
204 return 0;
205
206 spin_lock_irqsave(&fimc->slock, flags);
207 set_bit(ST_FLITE_OFF, &fimc->state);
208 flite_hw_capture_stop(fimc);
209 spin_unlock_irqrestore(&fimc->slock, flags);
210
211 wait_event_timeout(fimc->irq_queue,
212 !test_bit(ST_FLITE_OFF, &fimc->state),
213 (2*HZ/10)); /* 200 ms */
214
215 return fimc_lite_reinit(fimc, suspend);
216}
217
218/* Must be called with fimc.slock spinlock held. */
219static void fimc_lite_config_update(struct fimc_lite *fimc)
220{
221 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
222 flite_hw_set_dma_window(fimc, &fimc->out_frame);
223 flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
224 clear_bit(ST_FLITE_CONFIG, &fimc->state);
225}
226
227static irqreturn_t flite_irq_handler(int irq, void *priv)
228{
229 struct fimc_lite *fimc = priv;
230 struct flite_buffer *vbuf;
231 unsigned long flags;
232 struct timeval *tv;
233 struct timespec ts;
234 u32 intsrc;
235
236 spin_lock_irqsave(&fimc->slock, flags);
237
238 intsrc = flite_hw_get_interrupt_source(fimc);
239 flite_hw_clear_pending_irq(fimc);
240
241 if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
242 wake_up(&fimc->irq_queue);
243 goto done;
244 }
245
246 if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
247 clear_bit(ST_FLITE_RUN, &fimc->state);
248 fimc->events.data_overflow++;
249 }
250
251 if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
252 flite_hw_clear_last_capture_end(fimc);
253 clear_bit(ST_FLITE_STREAM, &fimc->state);
254 wake_up(&fimc->irq_queue);
255 }
256
257 if (fimc->out_path != FIMC_IO_DMA)
258 goto done;
259
260 if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
261 test_bit(ST_FLITE_RUN, &fimc->state) &&
262 !list_empty(&fimc->active_buf_q) &&
263 !list_empty(&fimc->pending_buf_q)) {
264 vbuf = fimc_lite_active_queue_pop(fimc);
265 ktime_get_ts(&ts);
266 tv = &vbuf->vb.v4l2_buf.timestamp;
267 tv->tv_sec = ts.tv_sec;
268 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
269 vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
270 vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
271
272 vbuf = fimc_lite_pending_queue_pop(fimc);
273 flite_hw_set_output_addr(fimc, vbuf->paddr);
274 fimc_lite_active_queue_add(fimc, vbuf);
275 }
276
277 if (test_bit(ST_FLITE_CONFIG, &fimc->state))
278 fimc_lite_config_update(fimc);
279
280 if (list_empty(&fimc->pending_buf_q)) {
281 flite_hw_capture_stop(fimc);
282 clear_bit(ST_FLITE_STREAM, &fimc->state);
283 }
284done:
285 set_bit(ST_FLITE_RUN, &fimc->state);
286 spin_unlock_irqrestore(&fimc->slock, flags);
287 return IRQ_HANDLED;
288}
289
290static int start_streaming(struct vb2_queue *q, unsigned int count)
291{
292 struct fimc_lite *fimc = q->drv_priv;
293 int ret;
294
295 fimc->frame_count = 0;
296
297 ret = fimc_lite_hw_init(fimc);
298 if (ret) {
299 fimc_lite_reinit(fimc, false);
300 return ret;
301 }
302
303 set_bit(ST_FLITE_PENDING, &fimc->state);
304
305 if (!list_empty(&fimc->active_buf_q) &&
306 !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
307 flite_hw_capture_start(fimc);
308
309 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
310 fimc_pipeline_s_stream(&fimc->pipeline, 1);
311 }
312 if (debug > 0)
313 flite_hw_dump_regs(fimc, __func__);
314
315 return 0;
316}
317
318static int stop_streaming(struct vb2_queue *q)
319{
320 struct fimc_lite *fimc = q->drv_priv;
321
322 if (!fimc_lite_active(fimc))
323 return -EINVAL;
324
325 return fimc_lite_stop_capture(fimc, false);
326}
327
328static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
329 unsigned int *num_buffers, unsigned int *num_planes,
330 unsigned int sizes[], void *allocators[])
331{
332 const struct v4l2_pix_format_mplane *pixm = NULL;
333 struct fimc_lite *fimc = vq->drv_priv;
334 struct flite_frame *frame = &fimc->out_frame;
335 const struct fimc_fmt *fmt = fimc->fmt;
336 unsigned long wh;
337 int i;
338
339 if (pfmt) {
340 pixm = &pfmt->fmt.pix_mp;
341 fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, -1);
342 wh = pixm->width * pixm->height;
343 } else {
344 wh = frame->f_width * frame->f_height;
345 }
346
347 if (fmt == NULL)
348 return -EINVAL;
349
350 *num_planes = fmt->memplanes;
351
352 for (i = 0; i < fmt->memplanes; i++) {
353 unsigned int size = (wh * fmt->depth[i]) / 8;
354 if (pixm)
355 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
356 else
357 sizes[i] = size;
358 allocators[i] = fimc->alloc_ctx;
359 }
360
361 return 0;
362}
363
364static int buffer_prepare(struct vb2_buffer *vb)
365{
366 struct vb2_queue *vq = vb->vb2_queue;
367 struct fimc_lite *fimc = vq->drv_priv;
368 int i;
369
370 if (fimc->fmt == NULL)
371 return -EINVAL;
372
373 for (i = 0; i < fimc->fmt->memplanes; i++) {
374 unsigned long size = fimc->payload[i];
375
376 if (vb2_plane_size(vb, i) < size) {
377 v4l2_err(fimc->vfd,
378 "User buffer too small (%ld < %ld)\n",
379 vb2_plane_size(vb, i), size);
380 return -EINVAL;
381 }
382 vb2_set_plane_payload(vb, i, size);
383 }
384
385 return 0;
386}
387
388static void buffer_queue(struct vb2_buffer *vb)
389{
390 struct flite_buffer *buf
391 = container_of(vb, struct flite_buffer, vb);
392 struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
393 unsigned long flags;
394
395 spin_lock_irqsave(&fimc->slock, flags);
396 buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
397
398 if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
399 !test_bit(ST_FLITE_STREAM, &fimc->state) &&
400 list_empty(&fimc->active_buf_q)) {
401 flite_hw_set_output_addr(fimc, buf->paddr);
402 fimc_lite_active_queue_add(fimc, buf);
403 } else {
404 fimc_lite_pending_queue_add(fimc, buf);
405 }
406
407 if (vb2_is_streaming(&fimc->vb_queue) &&
408 !list_empty(&fimc->pending_buf_q) &&
409 !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
410 flite_hw_capture_start(fimc);
411 spin_unlock_irqrestore(&fimc->slock, flags);
412
413 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
414 fimc_pipeline_s_stream(&fimc->pipeline, 1);
415 return;
416 }
417 spin_unlock_irqrestore(&fimc->slock, flags);
418}
419
420static void fimc_lock(struct vb2_queue *vq)
421{
422 struct fimc_lite *fimc = vb2_get_drv_priv(vq);
423 mutex_lock(&fimc->lock);
424}
425
426static void fimc_unlock(struct vb2_queue *vq)
427{
428 struct fimc_lite *fimc = vb2_get_drv_priv(vq);
429 mutex_unlock(&fimc->lock);
430}
431
432static const struct vb2_ops fimc_lite_qops = {
433 .queue_setup = queue_setup,
434 .buf_prepare = buffer_prepare,
435 .buf_queue = buffer_queue,
436 .wait_prepare = fimc_unlock,
437 .wait_finish = fimc_lock,
438 .start_streaming = start_streaming,
439 .stop_streaming = stop_streaming,
440};
441
442static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
443{
444 unsigned long flags;
445
446 spin_lock_irqsave(&fimc->slock, flags);
447 memset(&fimc->events, 0, sizeof(fimc->events));
448 spin_unlock_irqrestore(&fimc->slock, flags);
449}
450
451static int fimc_lite_open(struct file *file)
452{
453 struct fimc_lite *fimc = video_drvdata(file);
454 int ret = v4l2_fh_open(file);
455
456 if (ret)
457 return ret;
458
459 set_bit(ST_FLITE_IN_USE, &fimc->state);
460 pm_runtime_get_sync(&fimc->pdev->dev);
461
462 if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA)
463 return ret;
464
465 ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity,
466 true);
467 if (ret < 0) {
468 v4l2_err(fimc->vfd, "Video pipeline initialization failed\n");
469 pm_runtime_put_sync(&fimc->pdev->dev);
470 fimc->ref_count--;
471 v4l2_fh_release(file);
472 clear_bit(ST_FLITE_IN_USE, &fimc->state);
473 }
474
475 fimc_lite_clear_event_counters(fimc);
476 return ret;
477}
478
479static int fimc_lite_close(struct file *file)
480{
481 struct fimc_lite *fimc = video_drvdata(file);
482
483 if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
484 clear_bit(ST_FLITE_IN_USE, &fimc->state);
485 fimc_lite_stop_capture(fimc, false);
486 fimc_pipeline_shutdown(&fimc->pipeline);
487 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
488 }
489
490 pm_runtime_put(&fimc->pdev->dev);
491
492 if (fimc->ref_count == 0)
493 vb2_queue_release(&fimc->vb_queue);
494
495 return v4l2_fh_release(file);
496}
497
498static unsigned int fimc_lite_poll(struct file *file,
499 struct poll_table_struct *wait)
500{
501 struct fimc_lite *fimc = video_drvdata(file);
502 return vb2_poll(&fimc->vb_queue, file, wait);
503}
504
505static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma)
506{
507 struct fimc_lite *fimc = video_drvdata(file);
508 return vb2_mmap(&fimc->vb_queue, vma);
509}
510
511static const struct v4l2_file_operations fimc_lite_fops = {
512 .owner = THIS_MODULE,
513 .open = fimc_lite_open,
514 .release = fimc_lite_close,
515 .poll = fimc_lite_poll,
516 .unlocked_ioctl = video_ioctl2,
517 .mmap = fimc_lite_mmap,
518};
519
520/*
521 * Format and crop negotiation helpers
522 */
523
524static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
525 u32 *width, u32 *height,
526 u32 *code, u32 *fourcc, int pad)
527{
528 struct flite_variant *variant = fimc->variant;
529 const struct fimc_fmt *fmt;
530
531 fmt = fimc_lite_find_format(fourcc, code, 0);
532 if (WARN_ON(!fmt))
533 return NULL;
534
535 if (code)
536 *code = fmt->mbus_code;
537 if (fourcc)
538 *fourcc = fmt->fourcc;
539
540 if (pad == FLITE_SD_PAD_SINK) {
541 v4l_bound_align_image(width, 8, variant->max_width,
542 ffs(variant->out_width_align) - 1,
543 height, 0, variant->max_height, 0, 0);
544 } else {
545 v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
546 ffs(variant->out_width_align) - 1,
547 height, 0, fimc->inp_frame.rect.height,
548 0, 0);
549 }
550
551 v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
552 code ? *code : 0, *width, *height);
553
554 return fmt;
555}
556
557static void fimc_lite_try_crop(struct fimc_lite *fimc, struct v4l2_rect *r)
558{
559 struct flite_frame *frame = &fimc->inp_frame;
560
561 v4l_bound_align_image(&r->width, 0, frame->f_width, 0,
562 &r->height, 0, frame->f_height, 0, 0);
563
564 /* Adjust left/top if cropping rectangle got out of bounds */
565 r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
566 r->left = round_down(r->left, fimc->variant->win_hor_offs_align);
567 r->top = clamp_t(u32, r->top, 0, frame->f_height - r->height);
568
569 v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, sink fmt: %dx%d",
570 r->left, r->top, r->width, r->height,
571 frame->f_width, frame->f_height);
572}
573
574static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
575{
576 struct flite_frame *frame = &fimc->out_frame;
577 struct v4l2_rect *crop_rect = &fimc->inp_frame.rect;
578
579 /* Scaling is not supported so we enforce compose rectangle size
580 same as size of the sink crop rectangle. */
581 r->width = crop_rect->width;
582 r->height = crop_rect->height;
583
584 /* Adjust left/top if the composing rectangle got out of bounds */
585 r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
586 r->left = round_down(r->left, fimc->variant->out_hor_offs_align);
587 r->top = clamp_t(u32, r->top, 0, fimc->out_frame.f_height - r->height);
588
589 v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, source fmt: %dx%d",
590 r->left, r->top, r->width, r->height,
591 frame->f_width, frame->f_height);
592}
593
594/*
595 * Video node ioctl operations
596 */
597static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
598 struct v4l2_capability *cap)
599{
600 strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
601 cap->bus_info[0] = 0;
602 cap->card[0] = 0;
603 cap->capabilities = V4L2_CAP_STREAMING;
604 return 0;
605}
606
607static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv,
608 struct v4l2_fmtdesc *f)
609{
610 const struct fimc_fmt *fmt;
611
612 if (f->index >= ARRAY_SIZE(fimc_lite_formats))
613 return -EINVAL;
614
615 fmt = &fimc_lite_formats[f->index];
616 strlcpy(f->description, fmt->name, sizeof(f->description));
617 f->pixelformat = fmt->fourcc;
618
619 return 0;
620}
621
622static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
623 struct v4l2_format *f)
624{
625 struct fimc_lite *fimc = video_drvdata(file);
626 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
627 struct v4l2_plane_pix_format *plane_fmt = &pixm->plane_fmt[0];
628 struct flite_frame *frame = &fimc->out_frame;
629 const struct fimc_fmt *fmt = fimc->fmt;
630
631 plane_fmt->bytesperline = (frame->f_width * fmt->depth[0]) / 8;
632 plane_fmt->sizeimage = plane_fmt->bytesperline * frame->f_height;
633
634 pixm->num_planes = fmt->memplanes;
635 pixm->pixelformat = fmt->fourcc;
636 pixm->width = frame->f_width;
637 pixm->height = frame->f_height;
638 pixm->field = V4L2_FIELD_NONE;
639 pixm->colorspace = V4L2_COLORSPACE_JPEG;
640 return 0;
641}
642
643static int fimc_lite_try_fmt(struct fimc_lite *fimc,
644 struct v4l2_pix_format_mplane *pixm,
645 const struct fimc_fmt **ffmt)
646{
647 struct flite_variant *variant = fimc->variant;
648 u32 bpl = pixm->plane_fmt[0].bytesperline;
649 const struct fimc_fmt *fmt;
650
651 fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, 0);
652 if (WARN_ON(fmt == NULL))
653 return -EINVAL;
654 if (ffmt)
655 *ffmt = fmt;
656 v4l_bound_align_image(&pixm->width, 8, variant->max_width,
657 ffs(variant->out_width_align) - 1,
658 &pixm->height, 0, variant->max_height, 0, 0);
659
660 if ((bpl == 0 || ((bpl * 8) / fmt->depth[0]) < pixm->width))
661 pixm->plane_fmt[0].bytesperline = (pixm->width *
662 fmt->depth[0]) / 8;
663
664 if (pixm->plane_fmt[0].sizeimage == 0)
665 pixm->plane_fmt[0].sizeimage = (pixm->width * pixm->height *
666 fmt->depth[0]) / 8;
667 pixm->num_planes = fmt->memplanes;
668 pixm->pixelformat = fmt->fourcc;
669 pixm->colorspace = V4L2_COLORSPACE_JPEG;
670 pixm->field = V4L2_FIELD_NONE;
671 return 0;
672}
673
674static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
675 struct v4l2_format *f)
676{
677 struct fimc_lite *fimc = video_drvdata(file);
678
679 return fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, NULL);
680}
681
682static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
683 struct v4l2_format *f)
684{
685 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
686 struct fimc_lite *fimc = video_drvdata(file);
687 struct flite_frame *frame = &fimc->out_frame;
688 const struct fimc_fmt *fmt = NULL;
689 int ret;
690
691 if (vb2_is_busy(&fimc->vb_queue))
692 return -EBUSY;
693
694 ret = fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, &fmt);
695 if (ret < 0)
696 return ret;
697
698 fimc->fmt = fmt;
699 fimc->payload[0] = max((pixm->width * pixm->height * fmt->depth[0]) / 8,
700 pixm->plane_fmt[0].sizeimage);
701 frame->f_width = pixm->width;
702 frame->f_height = pixm->height;
703
704 return 0;
705}
706
707static int fimc_pipeline_validate(struct fimc_lite *fimc)
708{
709 struct v4l2_subdev *sd = &fimc->subdev;
710 struct v4l2_subdev_format sink_fmt, src_fmt;
711 struct media_pad *pad;
712 int ret;
713
714 while (1) {
715 /* Retrieve format at the sink pad */
716 pad = &sd->entity.pads[0];
717 if (!(pad->flags & MEDIA_PAD_FL_SINK))
718 break;
719 /* Don't call FIMC subdev operation to avoid nested locking */
720 if (sd == &fimc->subdev) {
721 struct flite_frame *ff = &fimc->out_frame;
722 sink_fmt.format.width = ff->f_width;
723 sink_fmt.format.height = ff->f_height;
724 sink_fmt.format.code = fimc->fmt->mbus_code;
725 } else {
726 sink_fmt.pad = pad->index;
727 sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
728 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
729 &sink_fmt);
730 if (ret < 0 && ret != -ENOIOCTLCMD)
731 return -EPIPE;
732 }
733 /* Retrieve format at the source pad */
734 pad = media_entity_remote_source(pad);
735 if (pad == NULL ||
736 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
737 break;
738
739 sd = media_entity_to_v4l2_subdev(pad->entity);
740 src_fmt.pad = pad->index;
741 src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
742 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
743 if (ret < 0 && ret != -ENOIOCTLCMD)
744 return -EPIPE;
745
746 if (src_fmt.format.width != sink_fmt.format.width ||
747 src_fmt.format.height != sink_fmt.format.height ||
748 src_fmt.format.code != sink_fmt.format.code)
749 return -EPIPE;
750 }
751 return 0;
752}
753
754static int fimc_lite_streamon(struct file *file, void *priv,
755 enum v4l2_buf_type type)
756{
757 struct fimc_lite *fimc = video_drvdata(file);
758 struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
759 struct fimc_pipeline *p = &fimc->pipeline;
760 int ret;
761
762 if (fimc_lite_active(fimc))
763 return -EBUSY;
764
765 media_entity_pipeline_start(&sensor->entity, p->m_pipeline);
766
767 ret = fimc_pipeline_validate(fimc);
768 if (ret) {
769 media_entity_pipeline_stop(&sensor->entity);
770 return ret;
771 }
772
773 return vb2_streamon(&fimc->vb_queue, type);
774}
775
776static int fimc_lite_streamoff(struct file *file, void *priv,
777 enum v4l2_buf_type type)
778{
779 struct fimc_lite *fimc = video_drvdata(file);
780 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
781 int ret;
782
783 ret = vb2_streamoff(&fimc->vb_queue, type);
784 if (ret == 0)
785 media_entity_pipeline_stop(&sd->entity);
786 return ret;
787}
788
789static int fimc_lite_reqbufs(struct file *file, void *priv,
790 struct v4l2_requestbuffers *reqbufs)
791{
792 struct fimc_lite *fimc = video_drvdata(file);
793 int ret;
794
795 reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
796 ret = vb2_reqbufs(&fimc->vb_queue, reqbufs);
797 if (!ret < 0)
798 fimc->reqbufs_count = reqbufs->count;
799
800 return ret;
801}
802
803static int fimc_lite_querybuf(struct file *file, void *priv,
804 struct v4l2_buffer *buf)
805{
806 struct fimc_lite *fimc = video_drvdata(file);
807
808 return vb2_querybuf(&fimc->vb_queue, buf);
809}
810
811static int fimc_lite_qbuf(struct file *file, void *priv,
812 struct v4l2_buffer *buf)
813{
814 struct fimc_lite *fimc = video_drvdata(file);
815
816 return vb2_qbuf(&fimc->vb_queue, buf);
817}
818
819static int fimc_lite_dqbuf(struct file *file, void *priv,
820 struct v4l2_buffer *buf)
821{
822 struct fimc_lite *fimc = video_drvdata(file);
823
824 return vb2_dqbuf(&fimc->vb_queue, buf, file->f_flags & O_NONBLOCK);
825}
826
827static int fimc_lite_create_bufs(struct file *file, void *priv,
828 struct v4l2_create_buffers *create)
829{
830 struct fimc_lite *fimc = video_drvdata(file);
831
832 return vb2_create_bufs(&fimc->vb_queue, create);
833}
834
835static int fimc_lite_prepare_buf(struct file *file, void *priv,
836 struct v4l2_buffer *b)
837{
838 struct fimc_lite *fimc = video_drvdata(file);
839
840 return vb2_prepare_buf(&fimc->vb_queue, b);
841}
842
843/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
844static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
845{
846 if (a->left < b->left || a->top < b->top)
847 return 0;
848 if (a->left + a->width > b->left + b->width)
849 return 0;
850 if (a->top + a->height > b->top + b->height)
851 return 0;
852
853 return 1;
854}
855
856static int fimc_lite_g_selection(struct file *file, void *fh,
857 struct v4l2_selection *sel)
858{
859 struct fimc_lite *fimc = video_drvdata(file);
860 struct flite_frame *f = &fimc->out_frame;
861
862 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
863 return -EINVAL;
864
865 switch (sel->target) {
866 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
867 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
868 sel->r.left = 0;
869 sel->r.top = 0;
870 sel->r.width = f->f_width;
871 sel->r.height = f->f_height;
872 return 0;
873
874 case V4L2_SEL_TGT_COMPOSE_ACTIVE:
875 sel->r = f->rect;
876 return 0;
877 }
878
879 return -EINVAL;
880}
881
882static int fimc_lite_s_selection(struct file *file, void *fh,
883 struct v4l2_selection *sel)
884{
885 struct fimc_lite *fimc = video_drvdata(file);
886 struct flite_frame *f = &fimc->out_frame;
887 struct v4l2_rect rect = sel->r;
888 unsigned long flags;
889
890 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
891 sel->target != V4L2_SEL_TGT_COMPOSE_ACTIVE)
892 return -EINVAL;
893
894 fimc_lite_try_compose(fimc, &rect);
895
896 if ((sel->flags & V4L2_SEL_FLAG_LE) &&
897 !enclosed_rectangle(&rect, &sel->r))
898 return -ERANGE;
899
900 if ((sel->flags & V4L2_SEL_FLAG_GE) &&
901 !enclosed_rectangle(&sel->r, &rect))
902 return -ERANGE;
903
904 sel->r = rect;
905 spin_lock_irqsave(&fimc->slock, flags);
906 f->rect = rect;
907 set_bit(ST_FLITE_CONFIG, &fimc->state);
908 spin_unlock_irqrestore(&fimc->slock, flags);
909
910 return 0;
911}
912
913static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
914 .vidioc_querycap = fimc_vidioc_querycap_capture,
915 .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
916 .vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane,
917 .vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane,
918 .vidioc_g_fmt_vid_cap_mplane = fimc_lite_g_fmt_mplane,
919 .vidioc_g_selection = fimc_lite_g_selection,
920 .vidioc_s_selection = fimc_lite_s_selection,
921 .vidioc_reqbufs = fimc_lite_reqbufs,
922 .vidioc_querybuf = fimc_lite_querybuf,
923 .vidioc_prepare_buf = fimc_lite_prepare_buf,
924 .vidioc_create_bufs = fimc_lite_create_bufs,
925 .vidioc_qbuf = fimc_lite_qbuf,
926 .vidioc_dqbuf = fimc_lite_dqbuf,
927 .vidioc_streamon = fimc_lite_streamon,
928 .vidioc_streamoff = fimc_lite_streamoff,
929};
930
931/* Capture subdev media entity operations */
932static int fimc_lite_link_setup(struct media_entity *entity,
933 const struct media_pad *local,
934 const struct media_pad *remote, u32 flags)
935{
936 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
937 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
938 unsigned int remote_ent_type = media_entity_type(remote->entity);
939
940 if (WARN_ON(fimc == NULL))
941 return 0;
942
943 v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x",
944 __func__, local->entity->name, remote->entity->name,
945 flags, fimc->source_subdev_grp_id);
946
947 switch (local->index) {
948 case FIMC_SD_PAD_SINK:
949 if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV)
950 return -EINVAL;
951
952 if (flags & MEDIA_LNK_FL_ENABLED) {
953 if (fimc->source_subdev_grp_id != 0)
954 return -EBUSY;
955 fimc->source_subdev_grp_id = sd->grp_id;
956 return 0;
957 }
958
959 fimc->source_subdev_grp_id = 0;
960 break;
961
962 case FIMC_SD_PAD_SOURCE:
963 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
964 fimc->out_path = FIMC_IO_NONE;
965 return 0;
966 }
967 if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
968 fimc->out_path = FIMC_IO_ISP;
969 else
970 fimc->out_path = FIMC_IO_DMA;
971 break;
972
973 default:
974 v4l2_err(sd, "Invalid pad index\n");
975 return -EINVAL;
976 }
977
978 return 0;
979}
980
981static const struct media_entity_operations fimc_lite_subdev_media_ops = {
982 .link_setup = fimc_lite_link_setup,
983};
984
985static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
986 struct v4l2_subdev_fh *fh,
987 struct v4l2_subdev_mbus_code_enum *code)
988{
989 const struct fimc_fmt *fmt;
990
991 fmt = fimc_lite_find_format(NULL, NULL, code->index);
992 if (!fmt)
993 return -EINVAL;
994 code->code = fmt->mbus_code;
995 return 0;
996}
997
998static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
999 struct v4l2_subdev_fh *fh,
1000 struct v4l2_subdev_format *fmt)
1001{
1002 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1003 struct v4l2_mbus_framefmt *mf = &fmt->format;
1004 struct flite_frame *f = &fimc->out_frame;
1005
1006 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1007 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1008 fmt->format = *mf;
1009 return 0;
1010 }
1011 mf->colorspace = V4L2_COLORSPACE_JPEG;
1012
1013 mutex_lock(&fimc->lock);
1014 mf->code = fimc->fmt->mbus_code;
1015
1016 if (fmt->pad == FLITE_SD_PAD_SINK) {
1017 /* full camera input frame size */
1018 mf->width = f->f_width;
1019 mf->height = f->f_height;
1020 } else {
1021 /* crop size */
1022 mf->width = f->rect.width;
1023 mf->height = f->rect.height;
1024 }
1025 mutex_unlock(&fimc->lock);
1026 return 0;
1027}
1028
1029static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1030 struct v4l2_subdev_fh *fh,
1031 struct v4l2_subdev_format *fmt)
1032{
1033 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1034 struct v4l2_mbus_framefmt *mf = &fmt->format;
1035 struct flite_frame *sink = &fimc->inp_frame;
1036 const struct fimc_fmt *ffmt;
1037
1038 v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d",
1039 fmt->pad, mf->code, mf->width, mf->height);
1040
1041 mf->colorspace = V4L2_COLORSPACE_JPEG;
1042 mutex_lock(&fimc->lock);
1043
1044 if ((fimc->out_path == FIMC_IO_ISP && sd->entity.stream_count > 0) ||
1045 (fimc->out_path == FIMC_IO_DMA && vb2_is_busy(&fimc->vb_queue))) {
1046 mutex_unlock(&fimc->lock);
1047 return -EBUSY;
1048 }
1049
1050 ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
1051 &mf->code, NULL, fmt->pad);
1052
1053 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1054 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1055 *mf = fmt->format;
1056 mutex_unlock(&fimc->lock);
1057 return 0;
1058 }
1059
1060 if (fmt->pad == FLITE_SD_PAD_SINK) {
1061 sink->f_width = mf->width;
1062 sink->f_height = mf->height;
1063 fimc->fmt = ffmt;
1064 /* Set sink crop rectangle */
1065 sink->rect.width = mf->width;
1066 sink->rect.height = mf->height;
1067 sink->rect.left = 0;
1068 sink->rect.top = 0;
1069 /* Reset source crop rectangle */
1070 fimc->out_frame.rect = sink->rect;
1071 } else {
1072 /* Allow changing format only on sink pad */
1073 mf->code = fimc->fmt->mbus_code;
1074 mf->width = sink->rect.width;
1075 mf->height = sink->rect.height;
1076 }
1077
1078 mutex_unlock(&fimc->lock);
1079 return 0;
1080}
1081
1082static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1083 struct v4l2_subdev_fh *fh,
1084 struct v4l2_subdev_selection *sel)
1085{
1086 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1087 struct flite_frame *f = &fimc->inp_frame;
1088
1089 if ((sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL &&
1090 sel->target != V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS) ||
1091 sel->pad != FLITE_SD_PAD_SINK)
1092 return -EINVAL;
1093
1094 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1095 sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
1096 return 0;
1097 }
1098
1099 mutex_lock(&fimc->lock);
1100 if (sel->target == V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL) {
1101 sel->r = f->rect;
1102 } else {
1103 sel->r.left = 0;
1104 sel->r.top = 0;
1105 sel->r.width = f->f_width;
1106 sel->r.height = f->f_height;
1107 }
1108 mutex_unlock(&fimc->lock);
1109
1110 v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1111 __func__, f->rect.left, f->rect.top, f->rect.width,
1112 f->rect.height, f->f_width, f->f_height);
1113
1114 return 0;
1115}
1116
1117static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
1118 struct v4l2_subdev_fh *fh,
1119 struct v4l2_subdev_selection *sel)
1120{
1121 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1122 struct flite_frame *f = &fimc->inp_frame;
1123 int ret = 0;
1124
1125 if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
1126 sel->pad != FLITE_SD_PAD_SINK)
1127 return -EINVAL;
1128
1129 mutex_lock(&fimc->lock);
1130 fimc_lite_try_crop(fimc, &sel->r);
1131
1132 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1133 *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
1134 } else {
1135 unsigned long flags;
1136 spin_lock_irqsave(&fimc->slock, flags);
1137 f->rect = sel->r;
1138 /* Same crop rectangle on the source pad */
1139 fimc->out_frame.rect = sel->r;
1140 set_bit(ST_FLITE_CONFIG, &fimc->state);
1141 spin_unlock_irqrestore(&fimc->slock, flags);
1142 }
1143 mutex_unlock(&fimc->lock);
1144
1145 v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1146 __func__, f->rect.left, f->rect.top, f->rect.width,
1147 f->rect.height, f->f_width, f->f_height);
1148
1149 return ret;
1150}
1151
1152static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
1153{
1154 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1155
1156 if (fimc->out_path == FIMC_IO_DMA)
1157 return -ENOIOCTLCMD;
1158
1159 /* TODO: */
1160
1161 return 0;
1162}
1163
1164static int fimc_lite_subdev_s_power(struct v4l2_subdev *sd, int on)
1165{
1166 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1167
1168 if (fimc->out_path == FIMC_IO_DMA)
1169 return -ENOIOCTLCMD;
1170
1171 /* TODO: */
1172
1173 return 0;
1174}
1175
1176static int fimc_lite_log_status(struct v4l2_subdev *sd)
1177{
1178 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1179
1180 flite_hw_dump_regs(fimc, __func__);
1181 return 0;
1182}
1183
1184static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
1185{
1186 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1187 struct vb2_queue *q = &fimc->vb_queue;
1188 struct video_device *vfd;
1189 int ret;
1190
1191 fimc->fmt = &fimc_lite_formats[0];
1192 fimc->out_path = FIMC_IO_DMA;
1193
1194 vfd = video_device_alloc();
1195 if (!vfd) {
1196 v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n");
1197 return -ENOMEM;
1198 }
1199
1200 snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
1201 fimc->index);
1202
1203 vfd->fops = &fimc_lite_fops;
1204 vfd->ioctl_ops = &fimc_lite_ioctl_ops;
1205 vfd->v4l2_dev = sd->v4l2_dev;
1206 vfd->minor = -1;
1207 vfd->release = video_device_release;
1208 vfd->lock = &fimc->lock;
1209 fimc->vfd = vfd;
1210 fimc->ref_count = 0;
1211 fimc->reqbufs_count = 0;
1212
1213 INIT_LIST_HEAD(&fimc->pending_buf_q);
1214 INIT_LIST_HEAD(&fimc->active_buf_q);
1215
1216 memset(q, 0, sizeof(*q));
1217 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1218 q->io_modes = VB2_MMAP | VB2_USERPTR;
1219 q->ops = &fimc_lite_qops;
1220 q->mem_ops = &vb2_dma_contig_memops;
1221 q->buf_struct_size = sizeof(struct flite_buffer);
1222 q->drv_priv = fimc;
1223
1224 vb2_queue_init(q);
1225
1226 fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
1227 ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
1228 if (ret)
1229 goto err;
1230
1231 video_set_drvdata(vfd, fimc);
1232
1233 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1234 if (ret)
1235 goto err_vd;
1236
1237 v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
1238 vfd->name, video_device_node_name(vfd));
1239 return 0;
1240
1241 err_vd:
1242 media_entity_cleanup(&vfd->entity);
1243 err:
1244 video_device_release(vfd);
1245 return ret;
1246}
1247
1248static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
1249{
1250 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1251
1252 if (fimc == NULL)
1253 return;
1254
1255 if (fimc->vfd) {
1256 video_unregister_device(fimc->vfd);
1257 media_entity_cleanup(&fimc->vfd->entity);
1258 fimc->vfd = NULL;
1259 }
1260}
1261
1262static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
1263 .registered = fimc_lite_subdev_registered,
1264 .unregistered = fimc_lite_subdev_unregistered,
1265};
1266
1267static const struct v4l2_subdev_pad_ops fimc_lite_subdev_pad_ops = {
1268 .enum_mbus_code = fimc_lite_subdev_enum_mbus_code,
1269 .get_selection = fimc_lite_subdev_get_selection,
1270 .set_selection = fimc_lite_subdev_set_selection,
1271 .get_fmt = fimc_lite_subdev_get_fmt,
1272 .set_fmt = fimc_lite_subdev_set_fmt,
1273};
1274
1275static const struct v4l2_subdev_video_ops fimc_lite_subdev_video_ops = {
1276 .s_stream = fimc_lite_subdev_s_stream,
1277};
1278
1279static const struct v4l2_subdev_core_ops fimc_lite_core_ops = {
1280 .s_power = fimc_lite_subdev_s_power,
1281 .log_status = fimc_lite_log_status,
1282};
1283
1284static struct v4l2_subdev_ops fimc_lite_subdev_ops = {
1285 .core = &fimc_lite_core_ops,
1286 .video = &fimc_lite_subdev_video_ops,
1287 .pad = &fimc_lite_subdev_pad_ops,
1288};
1289
1290static int fimc_lite_s_ctrl(struct v4l2_ctrl *ctrl)
1291{
1292 struct fimc_lite *fimc = container_of(ctrl->handler, struct fimc_lite,
1293 ctrl_handler);
1294 set_bit(ST_FLITE_CONFIG, &fimc->state);
1295 return 0;
1296}
1297
1298static const struct v4l2_ctrl_ops fimc_lite_ctrl_ops = {
1299 .s_ctrl = fimc_lite_s_ctrl,
1300};
1301
1302static const struct v4l2_ctrl_config fimc_lite_ctrl = {
1303 .ops = &fimc_lite_ctrl_ops,
1304 .id = V4L2_CTRL_CLASS_USER | 0x1001,
1305 .type = V4L2_CTRL_TYPE_BOOLEAN,
1306 .name = "Test Pattern 640x480",
1307};
1308
1309static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
1310{
1311 struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
1312 struct v4l2_subdev *sd = &fimc->subdev;
1313 int ret;
1314
1315 v4l2_subdev_init(sd, &fimc_lite_subdev_ops);
1316 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1317 snprintf(sd->name, sizeof(sd->name), "FIMC-LITE.%d", fimc->index);
1318
1319 fimc->subdev_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1320 fimc->subdev_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1321 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1322 fimc->subdev_pads, 0);
1323 if (ret)
1324 return ret;
1325
1326 v4l2_ctrl_handler_init(handler, 1);
1327 fimc->test_pattern = v4l2_ctrl_new_custom(handler, &fimc_lite_ctrl,
1328 NULL);
1329 if (handler->error) {
1330 media_entity_cleanup(&sd->entity);
1331 return handler->error;
1332 }
1333
1334 sd->ctrl_handler = handler;
1335 sd->internal_ops = &fimc_lite_subdev_internal_ops;
1336 sd->entity.ops = &fimc_lite_subdev_media_ops;
1337 v4l2_set_subdevdata(sd, fimc);
1338
1339 return 0;
1340}
1341
1342static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
1343{
1344 struct v4l2_subdev *sd = &fimc->subdev;
1345
1346 v4l2_device_unregister_subdev(sd);
1347 media_entity_cleanup(&sd->entity);
1348 v4l2_ctrl_handler_free(&fimc->ctrl_handler);
1349 v4l2_set_subdevdata(sd, NULL);
1350}
1351
1352static void fimc_lite_clk_put(struct fimc_lite *fimc)
1353{
1354 if (IS_ERR_OR_NULL(fimc->clock))
1355 return;
1356
1357 clk_unprepare(fimc->clock);
1358 clk_put(fimc->clock);
1359 fimc->clock = NULL;
1360}
1361
1362static int fimc_lite_clk_get(struct fimc_lite *fimc)
1363{
1364 int ret;
1365
1366 fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
1367 if (IS_ERR(fimc->clock))
1368 return PTR_ERR(fimc->clock);
1369
1370 ret = clk_prepare(fimc->clock);
1371 if (ret < 0) {
1372 clk_put(fimc->clock);
1373 fimc->clock = NULL;
1374 }
1375 return ret;
1376}
1377
1378static int __devinit fimc_lite_probe(struct platform_device *pdev)
1379{
1380 struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev);
1381 struct fimc_lite *fimc;
1382 struct resource *res;
1383 int ret;
1384
1385 fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
1386 if (!fimc)
1387 return -ENOMEM;
1388
1389 fimc->index = pdev->id;
1390 fimc->variant = drv_data->variant[fimc->index];
1391 fimc->pdev = pdev;
1392
1393 init_waitqueue_head(&fimc->irq_queue);
1394 spin_lock_init(&fimc->slock);
1395 mutex_init(&fimc->lock);
1396
1397 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1398 fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
1399 if (fimc->regs == NULL) {
1400 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1401 return -ENOENT;
1402 }
1403
1404 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1405 if (res == NULL) {
1406 dev_err(&pdev->dev, "Failed to get IRQ resource\n");
1407 return -ENXIO;
1408 }
1409
1410 ret = fimc_lite_clk_get(fimc);
1411 if (ret)
1412 return ret;
1413
1414 ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler,
1415 0, dev_name(&pdev->dev), fimc);
1416 if (ret) {
1417 dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
1418 goto err_clk;
1419 }
1420
1421 /* The video node will be created within the subdev's registered() op */
1422 ret = fimc_lite_create_capture_subdev(fimc);
1423 if (ret)
1424 goto err_clk;
1425
1426 platform_set_drvdata(pdev, fimc);
1427 pm_runtime_enable(&pdev->dev);
1428 ret = pm_runtime_get_sync(&pdev->dev);
1429 if (ret < 0)
1430 goto err_sd;
1431
1432 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1433 if (IS_ERR(fimc->alloc_ctx)) {
1434 ret = PTR_ERR(fimc->alloc_ctx);
1435 goto err_pm;
1436 }
1437 pm_runtime_put(&pdev->dev);
1438
1439 dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n",
1440 fimc->index);
1441 return 0;
1442err_pm:
1443 pm_runtime_put(&pdev->dev);
1444err_sd:
1445 fimc_lite_unregister_capture_subdev(fimc);
1446err_clk:
1447 fimc_lite_clk_put(fimc);
1448 return ret;
1449}
1450
1451static int fimc_lite_runtime_resume(struct device *dev)
1452{
1453 struct fimc_lite *fimc = dev_get_drvdata(dev);
1454
1455 clk_enable(fimc->clock);
1456 return 0;
1457}
1458
1459static int fimc_lite_runtime_suspend(struct device *dev)
1460{
1461 struct fimc_lite *fimc = dev_get_drvdata(dev);
1462
1463 clk_disable(fimc->clock);
1464 return 0;
1465}
1466
1467#ifdef CONFIG_PM_SLEEP
1468static int fimc_lite_resume(struct device *dev)
1469{
1470 struct fimc_lite *fimc = dev_get_drvdata(dev);
1471 struct flite_buffer *buf;
1472 unsigned long flags;
1473 int i;
1474
1475 spin_lock_irqsave(&fimc->slock, flags);
1476 if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
1477 !test_bit(ST_FLITE_IN_USE, &fimc->state)) {
1478 spin_unlock_irqrestore(&fimc->slock, flags);
1479 return 0;
1480 }
1481 flite_hw_reset(fimc);
1482 spin_unlock_irqrestore(&fimc->slock, flags);
1483
1484 if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state))
1485 return 0;
1486
1487 INIT_LIST_HEAD(&fimc->active_buf_q);
1488 fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, false);
1489 fimc_lite_hw_init(fimc);
1490 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
1491
1492 for (i = 0; i < fimc->reqbufs_count; i++) {
1493 if (list_empty(&fimc->pending_buf_q))
1494 break;
1495 buf = fimc_lite_pending_queue_pop(fimc);
1496 buffer_queue(&buf->vb);
1497 }
1498 return 0;
1499}
1500
1501static int fimc_lite_suspend(struct device *dev)
1502{
1503 struct fimc_lite *fimc = dev_get_drvdata(dev);
1504 bool suspend = test_bit(ST_FLITE_IN_USE, &fimc->state);
1505 int ret;
1506
1507 if (test_and_set_bit(ST_LPM, &fimc->state))
1508 return 0;
1509
1510 ret = fimc_lite_stop_capture(fimc, suspend);
1511 if (ret)
1512 return ret;
1513
1514 return fimc_pipeline_shutdown(&fimc->pipeline);
1515}
1516#endif /* CONFIG_PM_SLEEP */
1517
1518static int __devexit fimc_lite_remove(struct platform_device *pdev)
1519{
1520 struct fimc_lite *fimc = platform_get_drvdata(pdev);
1521 struct device *dev = &pdev->dev;
1522
1523 pm_runtime_disable(dev);
1524 pm_runtime_set_suspended(dev);
1525 fimc_lite_unregister_capture_subdev(fimc);
1526 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1527 fimc_lite_clk_put(fimc);
1528
1529 dev_info(dev, "Driver unloaded\n");
1530 return 0;
1531}
1532
1533static struct flite_variant fimc_lite0_variant_exynos4 = {
1534 .max_width = 8192,
1535 .max_height = 8192,
1536 .out_width_align = 8,
1537 .win_hor_offs_align = 2,
1538 .out_hor_offs_align = 8,
1539};
1540
1541/* EXYNOS4212, EXYNOS4412 */
1542static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
1543 .variant = {
1544 [0] = &fimc_lite0_variant_exynos4,
1545 [1] = &fimc_lite0_variant_exynos4,
1546 },
1547};
1548
1549static struct platform_device_id fimc_lite_driver_ids[] = {
1550 {
1551 .name = "exynos-fimc-lite",
1552 .driver_data = (unsigned long)&fimc_lite_drvdata_exynos4,
1553 },
1554 { /* sentinel */ },
1555};
1556MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
1557
1558static const struct dev_pm_ops fimc_lite_pm_ops = {
1559 SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume)
1560 SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume,
1561 NULL)
1562};
1563
1564static struct platform_driver fimc_lite_driver = {
1565 .probe = fimc_lite_probe,
1566 .remove = __devexit_p(fimc_lite_remove),
1567 .id_table = fimc_lite_driver_ids,
1568 .driver = {
1569 .name = FIMC_LITE_DRV_NAME,
1570 .owner = THIS_MODULE,
1571 .pm = &fimc_lite_pm_ops,
1572 }
1573};
1574module_platform_driver(fimc_lite_driver);
1575MODULE_LICENSE("GPL");
1576MODULE_ALIAS("platform:" FIMC_LITE_DRV_NAME);
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.h b/drivers/media/video/s5p-fimc/fimc-lite.h
new file mode 100644
index 000000000000..44424eee81d8
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-lite.h
@@ -0,0 +1,213 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FIMC_LITE_H_
10#define FIMC_LITE_H_
11
12#include <asm/sizes.h>
13#include <linux/io.h>
14#include <linux/irqreturn.h>
15#include <linux/platform_device.h>
16#include <linux/sched.h>
17#include <linux/spinlock.h>
18#include <linux/types.h>
19#include <linux/videodev2.h>
20
21#include <media/media-entity.h>
22#include <media/videobuf2-core.h>
23#include <media/v4l2-device.h>
24#include <media/v4l2-mediabus.h>
25#include <media/s5p_fimc.h>
26
27#include "fimc-core.h"
28
29#define FIMC_LITE_DRV_NAME "exynos-fimc-lite"
30#define FLITE_CLK_NAME "flite"
31#define FIMC_LITE_MAX_DEVS 2
32#define FLITE_REQ_BUFS_MIN 2
33
34/* Bit index definitions for struct fimc_lite::state */
35enum {
36 ST_FLITE_LPM,
37 ST_FLITE_PENDING,
38 ST_FLITE_RUN,
39 ST_FLITE_STREAM,
40 ST_FLITE_SUSPENDED,
41 ST_FLITE_OFF,
42 ST_FLITE_IN_USE,
43 ST_FLITE_CONFIG,
44 ST_SENSOR_STREAM,
45};
46
47#define FLITE_SD_PAD_SINK 0
48#define FLITE_SD_PAD_SOURCE 1
49#define FLITE_SD_PADS_NUM 2
50
51struct flite_variant {
52 unsigned short max_width;
53 unsigned short max_height;
54 unsigned short out_width_align;
55 unsigned short win_hor_offs_align;
56 unsigned short out_hor_offs_align;
57};
58
59struct flite_drvdata {
60 struct flite_variant *variant[FIMC_LITE_MAX_DEVS];
61};
62
63#define fimc_lite_get_drvdata(_pdev) \
64 ((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
65
66struct fimc_lite_events {
67 unsigned int data_overflow;
68};
69
70#define FLITE_MAX_PLANES 1
71
72/**
73 * struct flite_frame - source/target frame properties
74 * @f_width: full pixel width
75 * @f_height: full pixel height
76 * @rect: crop/composition rectangle
77 */
78struct flite_frame {
79 u16 f_width;
80 u16 f_height;
81 struct v4l2_rect rect;
82};
83
84/**
85 * struct flite_buffer - video buffer structure
86 * @vb: vb2 buffer
87 * @list: list head for the buffers queue
88 * @paddr: precalculated physical address
89 */
90struct flite_buffer {
91 struct vb2_buffer vb;
92 struct list_head list;
93 dma_addr_t paddr;
94};
95
96/**
97 * struct fimc_lite - fimc lite structure
98 * @pdev: pointer to FIMC-LITE platform device
99 * @variant: variant information for this IP
100 * @v4l2_dev: pointer to top the level v4l2_device
101 * @vfd: video device node
102 * @fh: v4l2 file handle
103 * @alloc_ctx: videobuf2 memory allocator context
104 * @subdev: FIMC-LITE subdev
105 * @vd_pad: media (sink) pad for the capture video node
106 * @subdev_pads: the subdev media pads
107 * @ctrl_handler: v4l2 control handler
108 * @test_pattern: test pattern controls
109 * @index: FIMC-LITE platform device index
110 * @pipeline: video capture pipeline data structure
111 * @slock: spinlock protecting this data structure and the hw registers
112 * @lock: mutex serializing video device and the subdev operations
113 * @clock: FIMC-LITE gate clock
114 * @regs: memory mapped io registers
115 * @irq_queue: interrupt handler waitqueue
116 * @fmt: pointer to color format description structure
117 * @payload: image size in bytes (w x h x bpp)
118 * @inp_frame: camera input frame structure
119 * @out_frame: DMA output frame structure
120 * @out_path: output data path (DMA or FIFO)
121 * @source_subdev_grp_id: source subdev group id
122 * @state: driver state flags
123 * @pending_buf_q: pending buffers queue head
124 * @active_buf_q: the queue head of buffers scheduled in hardware
125 * @vb_queue: vb2 buffers queue
126 * @active_buf_count: number of video buffers scheduled in hardware
127 * @frame_count: the captured frames counter
128 * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
129 * @ref_count: driver's private reference counter
130 */
131struct fimc_lite {
132 struct platform_device *pdev;
133 struct flite_variant *variant;
134 struct v4l2_device *v4l2_dev;
135 struct video_device *vfd;
136 struct v4l2_fh fh;
137 struct vb2_alloc_ctx *alloc_ctx;
138 struct v4l2_subdev subdev;
139 struct media_pad vd_pad;
140 struct media_pad subdev_pads[FLITE_SD_PADS_NUM];
141 struct v4l2_ctrl_handler ctrl_handler;
142 struct v4l2_ctrl *test_pattern;
143 u32 index;
144 struct fimc_pipeline pipeline;
145
146 struct mutex lock;
147 spinlock_t slock;
148
149 struct clk *clock;
150 void __iomem *regs;
151 wait_queue_head_t irq_queue;
152
153 const struct fimc_fmt *fmt;
154 unsigned long payload[FLITE_MAX_PLANES];
155 struct flite_frame inp_frame;
156 struct flite_frame out_frame;
157 enum fimc_datapath out_path;
158 unsigned int source_subdev_grp_id;
159
160 unsigned long state;
161 struct list_head pending_buf_q;
162 struct list_head active_buf_q;
163 struct vb2_queue vb_queue;
164 unsigned int frame_count;
165 unsigned int reqbufs_count;
166 int ref_count;
167
168 struct fimc_lite_events events;
169};
170
171static inline bool fimc_lite_active(struct fimc_lite *fimc)
172{
173 unsigned long flags;
174 bool ret;
175
176 spin_lock_irqsave(&fimc->slock, flags);
177 ret = fimc->state & (1 << ST_FLITE_RUN) ||
178 fimc->state & (1 << ST_FLITE_PENDING);
179 spin_unlock_irqrestore(&fimc->slock, flags);
180 return ret;
181}
182
183static inline void fimc_lite_active_queue_add(struct fimc_lite *dev,
184 struct flite_buffer *buf)
185{
186 list_add_tail(&buf->list, &dev->active_buf_q);
187}
188
189static inline struct flite_buffer *fimc_lite_active_queue_pop(
190 struct fimc_lite *dev)
191{
192 struct flite_buffer *buf = list_entry(dev->active_buf_q.next,
193 struct flite_buffer, list);
194 list_del(&buf->list);
195 return buf;
196}
197
198static inline void fimc_lite_pending_queue_add(struct fimc_lite *dev,
199 struct flite_buffer *buf)
200{
201 list_add_tail(&buf->list, &dev->pending_buf_q);
202}
203
204static inline struct flite_buffer *fimc_lite_pending_queue_pop(
205 struct fimc_lite *dev)
206{
207 struct flite_buffer *buf = list_entry(dev->pending_buf_q.next,
208 struct flite_buffer, list);
209 list_del(&buf->list);
210 return buf;
211}
212
213#endif /* FIMC_LITE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c
new file mode 100644
index 000000000000..4c58e0570962
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-m2m.c
@@ -0,0 +1,824 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki, <s.nawrocki@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
9 * by the Free Software Foundation, either version 2 of the License,
10 * or (at your option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/bug.h>
18#include <linux/interrupt.h>
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/list.h>
23#include <linux/io.h>
24#include <linux/slab.h>
25#include <linux/clk.h>
26#include <media/v4l2-ioctl.h>
27#include <media/videobuf2-core.h>
28#include <media/videobuf2-dma-contig.h>
29
30#include "fimc-core.h"
31#include "fimc-reg.h"
32#include "fimc-mdevice.h"
33
34
35static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
36{
37 if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
38 return FMT_FLAGS_M2M_IN;
39 else
40 return FMT_FLAGS_M2M_OUT;
41}
42
43void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
44{
45 struct vb2_buffer *src_vb, *dst_vb;
46
47 if (!ctx || !ctx->m2m_ctx)
48 return;
49
50 src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
51 dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
52
53 if (src_vb && dst_vb) {
54 v4l2_m2m_buf_done(src_vb, vb_state);
55 v4l2_m2m_buf_done(dst_vb, vb_state);
56 v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
57 ctx->m2m_ctx);
58 }
59}
60
61/* Complete the transaction which has been scheduled for execution. */
62static int fimc_m2m_shutdown(struct fimc_ctx *ctx)
63{
64 struct fimc_dev *fimc = ctx->fimc_dev;
65 int ret;
66
67 if (!fimc_m2m_pending(fimc))
68 return 0;
69
70 fimc_ctx_state_set(FIMC_CTX_SHUT, ctx);
71
72 ret = wait_event_timeout(fimc->irq_queue,
73 !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
74 FIMC_SHUTDOWN_TIMEOUT);
75
76 return ret == 0 ? -ETIMEDOUT : ret;
77}
78
79static int start_streaming(struct vb2_queue *q, unsigned int count)
80{
81 struct fimc_ctx *ctx = q->drv_priv;
82 int ret;
83
84 ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
85 return ret > 0 ? 0 : ret;
86}
87
88static int stop_streaming(struct vb2_queue *q)
89{
90 struct fimc_ctx *ctx = q->drv_priv;
91 int ret;
92
93 ret = fimc_m2m_shutdown(ctx);
94 if (ret == -ETIMEDOUT)
95 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
96
97 pm_runtime_put(&ctx->fimc_dev->pdev->dev);
98 return 0;
99}
100
101static void fimc_device_run(void *priv)
102{
103 struct vb2_buffer *vb = NULL;
104 struct fimc_ctx *ctx = priv;
105 struct fimc_frame *sf, *df;
106 struct fimc_dev *fimc;
107 unsigned long flags;
108 u32 ret;
109
110 if (WARN(!ctx, "Null context\n"))
111 return;
112
113 fimc = ctx->fimc_dev;
114 spin_lock_irqsave(&fimc->slock, flags);
115
116 set_bit(ST_M2M_PEND, &fimc->state);
117 sf = &ctx->s_frame;
118 df = &ctx->d_frame;
119
120 if (ctx->state & FIMC_PARAMS) {
121 /* Prepare the DMA offsets for scaler */
122 fimc_prepare_dma_offset(ctx, sf);
123 fimc_prepare_dma_offset(ctx, df);
124 }
125
126 vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
127 ret = fimc_prepare_addr(ctx, vb, sf, &sf->paddr);
128 if (ret)
129 goto dma_unlock;
130
131 vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
132 ret = fimc_prepare_addr(ctx, vb, df, &df->paddr);
133 if (ret)
134 goto dma_unlock;
135
136 /* Reconfigure hardware if the context has changed. */
137 if (fimc->m2m.ctx != ctx) {
138 ctx->state |= FIMC_PARAMS;
139 fimc->m2m.ctx = ctx;
140 }
141
142 if (ctx->state & FIMC_PARAMS) {
143 fimc_set_yuv_order(ctx);
144 fimc_hw_set_input_path(ctx);
145 fimc_hw_set_in_dma(ctx);
146 ret = fimc_set_scaler_info(ctx);
147 if (ret)
148 goto dma_unlock;
149 fimc_hw_set_prescaler(ctx);
150 fimc_hw_set_mainscaler(ctx);
151 fimc_hw_set_target_format(ctx);
152 fimc_hw_set_rotation(ctx);
153 fimc_hw_set_effect(ctx);
154 fimc_hw_set_out_dma(ctx);
155 if (fimc->variant->has_alpha)
156 fimc_hw_set_rgb_alpha(ctx);
157 fimc_hw_set_output_path(ctx);
158 }
159 fimc_hw_set_input_addr(fimc, &sf->paddr);
160 fimc_hw_set_output_addr(fimc, &df->paddr, -1);
161
162 fimc_activate_capture(ctx);
163 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
164 FIMC_SRC_FMT | FIMC_DST_FMT);
165 fimc_hw_activate_input_dma(fimc, true);
166
167dma_unlock:
168 spin_unlock_irqrestore(&fimc->slock, flags);
169}
170
171static void fimc_job_abort(void *priv)
172{
173 fimc_m2m_shutdown(priv);
174}
175
176static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
177 unsigned int *num_buffers, unsigned int *num_planes,
178 unsigned int sizes[], void *allocators[])
179{
180 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
181 struct fimc_frame *f;
182 int i;
183
184 f = ctx_get_frame(ctx, vq->type);
185 if (IS_ERR(f))
186 return PTR_ERR(f);
187 /*
188 * Return number of non-contigous planes (plane buffers)
189 * depending on the configured color format.
190 */
191 if (!f->fmt)
192 return -EINVAL;
193
194 *num_planes = f->fmt->memplanes;
195 for (i = 0; i < f->fmt->memplanes; i++) {
196 sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
197 allocators[i] = ctx->fimc_dev->alloc_ctx;
198 }
199 return 0;
200}
201
202static int fimc_buf_prepare(struct vb2_buffer *vb)
203{
204 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
205 struct fimc_frame *frame;
206 int i;
207
208 frame = ctx_get_frame(ctx, vb->vb2_queue->type);
209 if (IS_ERR(frame))
210 return PTR_ERR(frame);
211
212 for (i = 0; i < frame->fmt->memplanes; i++)
213 vb2_set_plane_payload(vb, i, frame->payload[i]);
214
215 return 0;
216}
217
218static void fimc_buf_queue(struct vb2_buffer *vb)
219{
220 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
221
222 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
223
224 if (ctx->m2m_ctx)
225 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
226}
227
228static void fimc_lock(struct vb2_queue *vq)
229{
230 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
231 mutex_lock(&ctx->fimc_dev->lock);
232}
233
234static void fimc_unlock(struct vb2_queue *vq)
235{
236 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
237 mutex_unlock(&ctx->fimc_dev->lock);
238}
239
240static struct vb2_ops fimc_qops = {
241 .queue_setup = fimc_queue_setup,
242 .buf_prepare = fimc_buf_prepare,
243 .buf_queue = fimc_buf_queue,
244 .wait_prepare = fimc_unlock,
245 .wait_finish = fimc_lock,
246 .stop_streaming = stop_streaming,
247 .start_streaming = start_streaming,
248};
249
250/*
251 * V4L2 ioctl handlers
252 */
253static int fimc_m2m_querycap(struct file *file, void *fh,
254 struct v4l2_capability *cap)
255{
256 struct fimc_ctx *ctx = fh_to_ctx(fh);
257 struct fimc_dev *fimc = ctx->fimc_dev;
258
259 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
260 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
261 cap->bus_info[0] = 0;
262 cap->capabilities = V4L2_CAP_STREAMING |
263 V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
264
265 return 0;
266}
267
268static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
269 struct v4l2_fmtdesc *f)
270{
271 struct fimc_fmt *fmt;
272
273 fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
274 f->index);
275 if (!fmt)
276 return -EINVAL;
277
278 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
279 f->pixelformat = fmt->fourcc;
280 return 0;
281}
282
283static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
284 struct v4l2_format *f)
285{
286 struct fimc_ctx *ctx = fh_to_ctx(fh);
287 struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
288
289 if (IS_ERR(frame))
290 return PTR_ERR(frame);
291
292 return fimc_fill_format(frame, f);
293}
294
295static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
296{
297 struct fimc_dev *fimc = ctx->fimc_dev;
298 struct fimc_variant *variant = fimc->variant;
299 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
300 struct fimc_fmt *fmt;
301 u32 max_w, mod_x, mod_y;
302
303 if (!IS_M2M(f->type))
304 return -EINVAL;
305
306 dbg("w: %d, h: %d", pix->width, pix->height);
307
308 fmt = fimc_find_format(&pix->pixelformat, NULL,
309 get_m2m_fmt_flags(f->type), 0);
310 if (WARN(fmt == NULL, "Pixel format lookup failed"))
311 return -EINVAL;
312
313 if (pix->field == V4L2_FIELD_ANY)
314 pix->field = V4L2_FIELD_NONE;
315 else if (pix->field != V4L2_FIELD_NONE)
316 return -EINVAL;
317
318 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
319 max_w = variant->pix_limit->scaler_dis_w;
320 mod_x = ffs(variant->min_inp_pixsize) - 1;
321 } else {
322 max_w = variant->pix_limit->out_rot_dis_w;
323 mod_x = ffs(variant->min_out_pixsize) - 1;
324 }
325
326 if (tiled_fmt(fmt)) {
327 mod_x = 6; /* 64 x 32 pixels tile */
328 mod_y = 5;
329 } else {
330 if (variant->min_vsize_align == 1)
331 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
332 else
333 mod_y = ffs(variant->min_vsize_align) - 1;
334 }
335
336 v4l_bound_align_image(&pix->width, 16, max_w, mod_x,
337 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
338
339 fimc_adjust_mplane_format(fmt, pix->width, pix->height, &f->fmt.pix_mp);
340 return 0;
341}
342
343static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
344 struct v4l2_format *f)
345{
346 struct fimc_ctx *ctx = fh_to_ctx(fh);
347
348 return fimc_try_fmt_mplane(ctx, f);
349}
350
351static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
352 struct v4l2_format *f)
353{
354 struct fimc_ctx *ctx = fh_to_ctx(fh);
355 struct fimc_dev *fimc = ctx->fimc_dev;
356 struct vb2_queue *vq;
357 struct fimc_frame *frame;
358 struct v4l2_pix_format_mplane *pix;
359 int i, ret = 0;
360
361 ret = fimc_try_fmt_mplane(ctx, f);
362 if (ret)
363 return ret;
364
365 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
366
367 if (vb2_is_busy(vq)) {
368 v4l2_err(fimc->m2m.vfd, "queue (%d) busy\n", f->type);
369 return -EBUSY;
370 }
371
372 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
373 frame = &ctx->s_frame;
374 else
375 frame = &ctx->d_frame;
376
377 pix = &f->fmt.pix_mp;
378 frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
379 get_m2m_fmt_flags(f->type), 0);
380 if (!frame->fmt)
381 return -EINVAL;
382
383 /* Update RGB Alpha control state and value range */
384 fimc_alpha_ctrl_update(ctx);
385
386 for (i = 0; i < frame->fmt->colplanes; i++) {
387 frame->payload[i] =
388 (pix->width * pix->height * frame->fmt->depth[i]) / 8;
389 }
390
391 fimc_fill_frame(frame, f);
392
393 ctx->scaler.enabled = 1;
394
395 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
396 fimc_ctx_state_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
397 else
398 fimc_ctx_state_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
399
400 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
401
402 return 0;
403}
404
405static int fimc_m2m_reqbufs(struct file *file, void *fh,
406 struct v4l2_requestbuffers *reqbufs)
407{
408 struct fimc_ctx *ctx = fh_to_ctx(fh);
409
410 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
411}
412
413static int fimc_m2m_querybuf(struct file *file, void *fh,
414 struct v4l2_buffer *buf)
415{
416 struct fimc_ctx *ctx = fh_to_ctx(fh);
417
418 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
419}
420
421static int fimc_m2m_qbuf(struct file *file, void *fh,
422 struct v4l2_buffer *buf)
423{
424 struct fimc_ctx *ctx = fh_to_ctx(fh);
425
426 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
427}
428
429static int fimc_m2m_dqbuf(struct file *file, void *fh,
430 struct v4l2_buffer *buf)
431{
432 struct fimc_ctx *ctx = fh_to_ctx(fh);
433
434 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
435}
436
437static int fimc_m2m_streamon(struct file *file, void *fh,
438 enum v4l2_buf_type type)
439{
440 struct fimc_ctx *ctx = fh_to_ctx(fh);
441
442 /* The source and target color format need to be set */
443 if (V4L2_TYPE_IS_OUTPUT(type)) {
444 if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
445 return -EINVAL;
446 } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
447 return -EINVAL;
448 }
449
450 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
451}
452
453static int fimc_m2m_streamoff(struct file *file, void *fh,
454 enum v4l2_buf_type type)
455{
456 struct fimc_ctx *ctx = fh_to_ctx(fh);
457
458 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
459}
460
461static int fimc_m2m_cropcap(struct file *file, void *fh,
462 struct v4l2_cropcap *cr)
463{
464 struct fimc_ctx *ctx = fh_to_ctx(fh);
465 struct fimc_frame *frame;
466
467 frame = ctx_get_frame(ctx, cr->type);
468 if (IS_ERR(frame))
469 return PTR_ERR(frame);
470
471 cr->bounds.left = 0;
472 cr->bounds.top = 0;
473 cr->bounds.width = frame->o_width;
474 cr->bounds.height = frame->o_height;
475 cr->defrect = cr->bounds;
476
477 return 0;
478}
479
480static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
481{
482 struct fimc_ctx *ctx = fh_to_ctx(fh);
483 struct fimc_frame *frame;
484
485 frame = ctx_get_frame(ctx, cr->type);
486 if (IS_ERR(frame))
487 return PTR_ERR(frame);
488
489 cr->c.left = frame->offs_h;
490 cr->c.top = frame->offs_v;
491 cr->c.width = frame->width;
492 cr->c.height = frame->height;
493
494 return 0;
495}
496
497static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
498{
499 struct fimc_dev *fimc = ctx->fimc_dev;
500 struct fimc_frame *f;
501 u32 min_size, halign, depth = 0;
502 int i;
503
504 if (cr->c.top < 0 || cr->c.left < 0) {
505 v4l2_err(fimc->m2m.vfd,
506 "doesn't support negative values for top & left\n");
507 return -EINVAL;
508 }
509 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
510 f = &ctx->d_frame;
511 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
512 f = &ctx->s_frame;
513 else
514 return -EINVAL;
515
516 min_size = (f == &ctx->s_frame) ?
517 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
518
519 /* Get pixel alignment constraints. */
520 if (fimc->variant->min_vsize_align == 1)
521 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
522 else
523 halign = ffs(fimc->variant->min_vsize_align) - 1;
524
525 for (i = 0; i < f->fmt->colplanes; i++)
526 depth += f->fmt->depth[i];
527
528 v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
529 ffs(min_size) - 1,
530 &cr->c.height, min_size, f->o_height,
531 halign, 64/(ALIGN(depth, 8)));
532
533 /* adjust left/top if cropping rectangle is out of bounds */
534 if (cr->c.left + cr->c.width > f->o_width)
535 cr->c.left = f->o_width - cr->c.width;
536 if (cr->c.top + cr->c.height > f->o_height)
537 cr->c.top = f->o_height - cr->c.height;
538
539 cr->c.left = round_down(cr->c.left, min_size);
540 cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align);
541
542 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
543 cr->c.left, cr->c.top, cr->c.width, cr->c.height,
544 f->f_width, f->f_height);
545
546 return 0;
547}
548
549static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
550{
551 struct fimc_ctx *ctx = fh_to_ctx(fh);
552 struct fimc_dev *fimc = ctx->fimc_dev;
553 struct fimc_frame *f;
554 int ret;
555
556 ret = fimc_m2m_try_crop(ctx, cr);
557 if (ret)
558 return ret;
559
560 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
561 &ctx->s_frame : &ctx->d_frame;
562
563 /* Check to see if scaling ratio is within supported range */
564 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
565 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
566 ret = fimc_check_scaler_ratio(ctx, cr->c.width,
567 cr->c.height, ctx->d_frame.width,
568 ctx->d_frame.height, ctx->rotation);
569 } else {
570 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
571 ctx->s_frame.height, cr->c.width,
572 cr->c.height, ctx->rotation);
573 }
574 if (ret) {
575 v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
576 return -EINVAL;
577 }
578 }
579
580 f->offs_h = cr->c.left;
581 f->offs_v = cr->c.top;
582 f->width = cr->c.width;
583 f->height = cr->c.height;
584
585 fimc_ctx_state_set(FIMC_PARAMS, ctx);
586
587 return 0;
588}
589
590static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
591 .vidioc_querycap = fimc_m2m_querycap,
592 .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
593 .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
594 .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
595 .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
596 .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
597 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
598 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
599 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
600 .vidioc_reqbufs = fimc_m2m_reqbufs,
601 .vidioc_querybuf = fimc_m2m_querybuf,
602 .vidioc_qbuf = fimc_m2m_qbuf,
603 .vidioc_dqbuf = fimc_m2m_dqbuf,
604 .vidioc_streamon = fimc_m2m_streamon,
605 .vidioc_streamoff = fimc_m2m_streamoff,
606 .vidioc_g_crop = fimc_m2m_g_crop,
607 .vidioc_s_crop = fimc_m2m_s_crop,
608 .vidioc_cropcap = fimc_m2m_cropcap
609
610};
611
612static int queue_init(void *priv, struct vb2_queue *src_vq,
613 struct vb2_queue *dst_vq)
614{
615 struct fimc_ctx *ctx = priv;
616 int ret;
617
618 memset(src_vq, 0, sizeof(*src_vq));
619 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
620 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
621 src_vq->drv_priv = ctx;
622 src_vq->ops = &fimc_qops;
623 src_vq->mem_ops = &vb2_dma_contig_memops;
624 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
625
626 ret = vb2_queue_init(src_vq);
627 if (ret)
628 return ret;
629
630 memset(dst_vq, 0, sizeof(*dst_vq));
631 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
632 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
633 dst_vq->drv_priv = ctx;
634 dst_vq->ops = &fimc_qops;
635 dst_vq->mem_ops = &vb2_dma_contig_memops;
636 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
637
638 return vb2_queue_init(dst_vq);
639}
640
641static int fimc_m2m_open(struct file *file)
642{
643 struct fimc_dev *fimc = video_drvdata(file);
644 struct fimc_ctx *ctx;
645 int ret;
646
647 dbg("pid: %d, state: 0x%lx, refcnt: %d",
648 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
649
650 /*
651 * Return if the corresponding video capture node
652 * is already opened.
653 */
654 if (fimc->vid_cap.refcnt > 0)
655 return -EBUSY;
656
657 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
658 if (!ctx)
659 return -ENOMEM;
660 v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
661 ctx->fimc_dev = fimc;
662
663 /* Default color format */
664 ctx->s_frame.fmt = fimc_get_format(0);
665 ctx->d_frame.fmt = fimc_get_format(0);
666
667 ret = fimc_ctrls_create(ctx);
668 if (ret)
669 goto error_fh;
670
671 /* Use separate control handler per file handle */
672 ctx->fh.ctrl_handler = &ctx->ctrls.handler;
673 file->private_data = &ctx->fh;
674 v4l2_fh_add(&ctx->fh);
675
676 /* Setup the device context for memory-to-memory mode */
677 ctx->state = FIMC_CTX_M2M;
678 ctx->flags = 0;
679 ctx->in_path = FIMC_IO_DMA;
680 ctx->out_path = FIMC_IO_DMA;
681
682 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
683 if (IS_ERR(ctx->m2m_ctx)) {
684 ret = PTR_ERR(ctx->m2m_ctx);
685 goto error_c;
686 }
687
688 if (fimc->m2m.refcnt++ == 0)
689 set_bit(ST_M2M_RUN, &fimc->state);
690 return 0;
691
692error_c:
693 fimc_ctrls_delete(ctx);
694error_fh:
695 v4l2_fh_del(&ctx->fh);
696 v4l2_fh_exit(&ctx->fh);
697 kfree(ctx);
698 return ret;
699}
700
701static int fimc_m2m_release(struct file *file)
702{
703 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
704 struct fimc_dev *fimc = ctx->fimc_dev;
705
706 dbg("pid: %d, state: 0x%lx, refcnt= %d",
707 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
708
709 v4l2_m2m_ctx_release(ctx->m2m_ctx);
710 fimc_ctrls_delete(ctx);
711 v4l2_fh_del(&ctx->fh);
712 v4l2_fh_exit(&ctx->fh);
713
714 if (--fimc->m2m.refcnt <= 0)
715 clear_bit(ST_M2M_RUN, &fimc->state);
716 kfree(ctx);
717 return 0;
718}
719
720static unsigned int fimc_m2m_poll(struct file *file,
721 struct poll_table_struct *wait)
722{
723 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
724
725 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
726}
727
728
729static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
730{
731 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
732
733 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
734}
735
736static const struct v4l2_file_operations fimc_m2m_fops = {
737 .owner = THIS_MODULE,
738 .open = fimc_m2m_open,
739 .release = fimc_m2m_release,
740 .poll = fimc_m2m_poll,
741 .unlocked_ioctl = video_ioctl2,
742 .mmap = fimc_m2m_mmap,
743};
744
745static struct v4l2_m2m_ops m2m_ops = {
746 .device_run = fimc_device_run,
747 .job_abort = fimc_job_abort,
748};
749
750int fimc_register_m2m_device(struct fimc_dev *fimc,
751 struct v4l2_device *v4l2_dev)
752{
753 struct video_device *vfd;
754 struct platform_device *pdev;
755 int ret = 0;
756
757 if (!fimc)
758 return -ENODEV;
759
760 pdev = fimc->pdev;
761 fimc->v4l2_dev = v4l2_dev;
762
763 vfd = video_device_alloc();
764 if (!vfd) {
765 v4l2_err(v4l2_dev, "Failed to allocate video device\n");
766 return -ENOMEM;
767 }
768
769 vfd->fops = &fimc_m2m_fops;
770 vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
771 vfd->v4l2_dev = v4l2_dev;
772 vfd->minor = -1;
773 vfd->release = video_device_release;
774 vfd->lock = &fimc->lock;
775 /* Locking in file operations other than ioctl should be done
776 by the driver, not the V4L2 core.
777 This driver needs auditing so that this flag can be removed. */
778 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
779
780 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
781 video_set_drvdata(vfd, fimc);
782
783 fimc->m2m.vfd = vfd;
784 fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
785 if (IS_ERR(fimc->m2m.m2m_dev)) {
786 v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
787 ret = PTR_ERR(fimc->m2m.m2m_dev);
788 goto err_init;
789 }
790
791 ret = media_entity_init(&vfd->entity, 0, NULL, 0);
792 if (ret)
793 goto err_me;
794
795 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
796 if (ret)
797 goto err_vd;
798
799 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
800 vfd->name, video_device_node_name(vfd));
801 return 0;
802
803err_vd:
804 media_entity_cleanup(&vfd->entity);
805err_me:
806 v4l2_m2m_release(fimc->m2m.m2m_dev);
807err_init:
808 video_device_release(fimc->m2m.vfd);
809 return ret;
810}
811
812void fimc_unregister_m2m_device(struct fimc_dev *fimc)
813{
814 if (!fimc)
815 return;
816
817 if (fimc->m2m.m2m_dev)
818 v4l2_m2m_release(fimc->m2m.m2m_dev);
819 if (fimc->m2m.vfd) {
820 media_entity_cleanup(&fimc->m2m.vfd->entity);
821 /* Can also be called if video device wasn't registered */
822 video_unregister_device(fimc->m2m.vfd);
823 }
824}
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
index 62ed37e40149..6753c45631b8 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c
@@ -25,6 +25,7 @@
25#include <media/media-device.h> 25#include <media/media-device.h>
26 26
27#include "fimc-core.h" 27#include "fimc-core.h"
28#include "fimc-lite.h"
28#include "fimc-mdevice.h" 29#include "fimc-mdevice.h"
29#include "mipi-csis.h" 30#include "mipi-csis.h"
30 31
@@ -37,22 +38,46 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
37 * 38 *
38 * Caller holds the graph mutex. 39 * Caller holds the graph mutex.
39 */ 40 */
40void fimc_pipeline_prepare(struct fimc_dev *fimc, struct media_entity *me) 41void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me)
41{ 42{
42 struct media_entity_graph graph; 43 struct media_pad *pad = &me->pads[0];
43 struct v4l2_subdev *sd; 44 struct v4l2_subdev *sd;
45 int i;
44 46
45 media_entity_graph_walk_start(&graph, me); 47 for (i = 0; i < IDX_MAX; i++)
48 p->subdevs[i] = NULL;
46 49
47 while ((me = media_entity_graph_walk_next(&graph))) { 50 while (1) {
48 if (media_entity_type(me) != MEDIA_ENT_T_V4L2_SUBDEV) 51 if (!(pad->flags & MEDIA_PAD_FL_SINK))
49 continue; 52 break;
50 sd = media_entity_to_v4l2_subdev(me); 53
54 /* source pad */
55 pad = media_entity_remote_source(pad);
56 if (pad == NULL ||
57 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
58 break;
59
60 sd = media_entity_to_v4l2_subdev(pad->entity);
51 61
52 if (sd->grp_id == SENSOR_GROUP_ID) 62 switch (sd->grp_id) {
53 fimc->pipeline.sensor = sd; 63 case SENSOR_GROUP_ID:
54 else if (sd->grp_id == CSIS_GROUP_ID) 64 p->subdevs[IDX_SENSOR] = sd;
55 fimc->pipeline.csis = sd; 65 break;
66 case CSIS_GROUP_ID:
67 p->subdevs[IDX_CSIS] = sd;
68 break;
69 case FLITE_GROUP_ID:
70 p->subdevs[IDX_FLITE] = sd;
71 break;
72 case FIMC_GROUP_ID:
73 /* No need to control FIMC subdev through subdev ops */
74 break;
75 default:
76 pr_warn("%s: Unknown subdev grp_id: %#x\n",
77 __func__, sd->grp_id);
78 }
79 /* sink pad */
80 pad = &sd->entity.pads[0];
56 } 81 }
57} 82}
58 83
@@ -85,30 +110,27 @@ static int __subdev_set_power(struct v4l2_subdev *sd, int on)
85/** 110/**
86 * fimc_pipeline_s_power - change power state of all pipeline subdevs 111 * fimc_pipeline_s_power - change power state of all pipeline subdevs
87 * @fimc: fimc device terminating the pipeline 112 * @fimc: fimc device terminating the pipeline
88 * @state: 1 to enable power or 0 for power down 113 * @state: true to power on, false to power off
89 * 114 *
90 * Need to be called with the graph mutex held. 115 * Needs to be called with the graph mutex held.
91 */ 116 */
92int fimc_pipeline_s_power(struct fimc_dev *fimc, int state) 117int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
93{ 118{
94 int ret = 0; 119 unsigned int i;
120 int ret;
95 121
96 if (fimc->pipeline.sensor == NULL) 122 if (p->subdevs[IDX_SENSOR] == NULL)
97 return -ENXIO; 123 return -ENXIO;
98 124
99 if (state) { 125 for (i = 0; i < IDX_MAX; i++) {
100 ret = __subdev_set_power(fimc->pipeline.csis, 1); 126 unsigned int idx = state ? (IDX_MAX - 1) - i : i;
101 if (ret && ret != -ENXIO) 127
128 ret = __subdev_set_power(p->subdevs[idx], state);
129 if (ret < 0 && ret != -ENXIO)
102 return ret; 130 return ret;
103 return __subdev_set_power(fimc->pipeline.sensor, 1);
104 } 131 }
105 132
106 ret = __subdev_set_power(fimc->pipeline.sensor, 0); 133 return 0;
107 if (ret)
108 return ret;
109 ret = __subdev_set_power(fimc->pipeline.csis, 0);
110
111 return ret == -ENXIO ? 0 : ret;
112} 134}
113 135
114/** 136/**
@@ -119,32 +141,36 @@ int fimc_pipeline_s_power(struct fimc_dev *fimc, int state)
119 * 141 *
120 * This function must be called with the graph mutex held. 142 * This function must be called with the graph mutex held.
121 */ 143 */
122static int __fimc_pipeline_initialize(struct fimc_dev *fimc, 144static int __fimc_pipeline_initialize(struct fimc_pipeline *p,
123 struct media_entity *me, bool prep) 145 struct media_entity *me, bool prep)
124{ 146{
125 int ret; 147 int ret;
126 148
127 if (prep) 149 if (prep)
128 fimc_pipeline_prepare(fimc, me); 150 fimc_pipeline_prepare(p, me);
129 if (fimc->pipeline.sensor == NULL) 151
152 if (p->subdevs[IDX_SENSOR] == NULL)
130 return -EINVAL; 153 return -EINVAL;
131 ret = fimc_md_set_camclk(fimc->pipeline.sensor, true); 154
155 ret = fimc_md_set_camclk(p->subdevs[IDX_SENSOR], true);
132 if (ret) 156 if (ret)
133 return ret; 157 return ret;
134 return fimc_pipeline_s_power(fimc, 1); 158
159 return fimc_pipeline_s_power(p, 1);
135} 160}
136 161
137int fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me, 162int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
138 bool prep) 163 bool prep)
139{ 164{
140 int ret; 165 int ret;
141 166
142 mutex_lock(&me->parent->graph_mutex); 167 mutex_lock(&me->parent->graph_mutex);
143 ret = __fimc_pipeline_initialize(fimc, me, prep); 168 ret = __fimc_pipeline_initialize(p, me, prep);
144 mutex_unlock(&me->parent->graph_mutex); 169 mutex_unlock(&me->parent->graph_mutex);
145 170
146 return ret; 171 return ret;
147} 172}
173EXPORT_SYMBOL_GPL(fimc_pipeline_initialize);
148 174
149/** 175/**
150 * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power 176 * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power
@@ -154,52 +180,55 @@ int fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me,
154 * sensor clock. 180 * sensor clock.
155 * Called with the graph mutex held. 181 * Called with the graph mutex held.
156 */ 182 */
157int __fimc_pipeline_shutdown(struct fimc_dev *fimc) 183int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
158{ 184{
159 int ret = 0; 185 int ret = 0;
160 186
161 if (fimc->pipeline.sensor) { 187 if (p->subdevs[IDX_SENSOR]) {
162 ret = fimc_pipeline_s_power(fimc, 0); 188 ret = fimc_pipeline_s_power(p, 0);
163 fimc_md_set_camclk(fimc->pipeline.sensor, false); 189 fimc_md_set_camclk(p->subdevs[IDX_SENSOR], false);
164 } 190 }
165 return ret == -ENXIO ? 0 : ret; 191 return ret == -ENXIO ? 0 : ret;
166} 192}
167 193
168int fimc_pipeline_shutdown(struct fimc_dev *fimc) 194int fimc_pipeline_shutdown(struct fimc_pipeline *p)
169{ 195{
170 struct media_entity *me = &fimc->vid_cap.vfd->entity; 196 struct media_entity *me = &p->subdevs[IDX_SENSOR]->entity;
171 int ret; 197 int ret;
172 198
173 mutex_lock(&me->parent->graph_mutex); 199 mutex_lock(&me->parent->graph_mutex);
174 ret = __fimc_pipeline_shutdown(fimc); 200 ret = __fimc_pipeline_shutdown(p);
175 mutex_unlock(&me->parent->graph_mutex); 201 mutex_unlock(&me->parent->graph_mutex);
176 202
177 return ret; 203 return ret;
178} 204}
205EXPORT_SYMBOL_GPL(fimc_pipeline_shutdown);
179 206
180/** 207/**
181 * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs 208 * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs
182 * @fimc: fimc device terminating the pipeline 209 * @pipeline: video pipeline structure
183 * @on: passed as the s_stream call argument 210 * @on: passed as the s_stream call argument
184 */ 211 */
185int fimc_pipeline_s_stream(struct fimc_dev *fimc, int on) 212int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
186{ 213{
187 struct fimc_pipeline *p = &fimc->pipeline; 214 int i, ret;
188 int ret = 0;
189 215
190 if (p->sensor == NULL) 216 if (p->subdevs[IDX_SENSOR] == NULL)
191 return -ENODEV; 217 return -ENODEV;
192 218
193 if ((on && p->csis) || !on) 219 for (i = 0; i < IDX_MAX; i++) {
194 ret = v4l2_subdev_call(on ? p->csis : p->sensor, 220 unsigned int idx = on ? (IDX_MAX - 1) - i : i;
195 video, s_stream, on); 221
196 if (ret < 0 && ret != -ENOIOCTLCMD) 222 ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on);
197 return ret; 223
198 if ((!on && p->csis) || on) 224 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
199 ret = v4l2_subdev_call(on ? p->sensor : p->csis, 225 return ret;
200 video, s_stream, on); 226 }
201 return ret == -ENOIOCTLCMD ? 0 : ret; 227
228 return 0;
229
202} 230}
231EXPORT_SYMBOL_GPL(fimc_pipeline_s_stream);
203 232
204/* 233/*
205 * Sensor subdevice helper functions 234 * Sensor subdevice helper functions
@@ -214,14 +243,20 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
214 return NULL; 243 return NULL;
215 244
216 adapter = i2c_get_adapter(s_info->pdata->i2c_bus_num); 245 adapter = i2c_get_adapter(s_info->pdata->i2c_bus_num);
217 if (!adapter) 246 if (!adapter) {
218 return NULL; 247 v4l2_warn(&fmd->v4l2_dev,
248 "Failed to get I2C adapter %d, deferring probe\n",
249 s_info->pdata->i2c_bus_num);
250 return ERR_PTR(-EPROBE_DEFER);
251 }
219 sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, 252 sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
220 s_info->pdata->board_info, NULL); 253 s_info->pdata->board_info, NULL);
221 if (IS_ERR_OR_NULL(sd)) { 254 if (IS_ERR_OR_NULL(sd)) {
222 i2c_put_adapter(adapter); 255 i2c_put_adapter(adapter);
223 v4l2_err(&fmd->v4l2_dev, "Failed to acquire subdev\n"); 256 v4l2_warn(&fmd->v4l2_dev,
224 return NULL; 257 "Failed to acquire subdev %s, deferring probe\n",
258 s_info->pdata->board_info->type);
259 return ERR_PTR(-EPROBE_DEFER);
225 } 260 }
226 v4l2_set_subdev_hostdata(sd, s_info); 261 v4l2_set_subdev_hostdata(sd, s_info);
227 sd->grp_id = SENSOR_GROUP_ID; 262 sd->grp_id = SENSOR_GROUP_ID;
@@ -269,13 +304,22 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
269 304
270 fmd->num_sensors = num_clients; 305 fmd->num_sensors = num_clients;
271 for (i = 0; i < num_clients; i++) { 306 for (i = 0; i < num_clients; i++) {
307 struct v4l2_subdev *sd;
308
272 fmd->sensor[i].pdata = &pdata->isp_info[i]; 309 fmd->sensor[i].pdata = &pdata->isp_info[i];
273 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true); 310 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true);
274 if (ret) 311 if (ret)
275 break; 312 break;
276 fmd->sensor[i].subdev = 313 sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]);
277 fimc_md_register_sensor(fmd, &fmd->sensor[i]);
278 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false); 314 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false);
315
316 if (!IS_ERR(sd)) {
317 fmd->sensor[i].subdev = sd;
318 } else {
319 fmd->sensor[i].subdev = NULL;
320 ret = PTR_ERR(sd);
321 break;
322 }
279 if (ret) 323 if (ret)
280 break; 324 break;
281 } 325 }
@@ -289,21 +333,50 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
289static int fimc_register_callback(struct device *dev, void *p) 333static int fimc_register_callback(struct device *dev, void *p)
290{ 334{
291 struct fimc_dev *fimc = dev_get_drvdata(dev); 335 struct fimc_dev *fimc = dev_get_drvdata(dev);
336 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
292 struct fimc_md *fmd = p; 337 struct fimc_md *fmd = p;
293 int ret; 338 int ret = 0;
294 339
295 if (!fimc || !fimc->pdev) 340 if (!fimc || !fimc->pdev)
296 return 0; 341 return 0;
342
297 if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS) 343 if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
298 return 0; 344 return 0;
299 345
300 fmd->fimc[fimc->pdev->id] = fimc; 346 fmd->fimc[fimc->pdev->id] = fimc;
301 ret = fimc_register_m2m_device(fimc, &fmd->v4l2_dev); 347 sd->grp_id = FIMC_GROUP_ID;
302 if (ret) 348
303 return ret; 349 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
304 ret = fimc_register_capture_device(fimc, &fmd->v4l2_dev); 350 if (ret) {
305 if (!ret) 351 v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
306 fimc->vid_cap.user_subdev_api = fmd->user_subdev_api; 352 fimc->id, ret);
353 }
354
355 return ret;
356}
357
358static int fimc_lite_register_callback(struct device *dev, void *p)
359{
360 struct fimc_lite *fimc = dev_get_drvdata(dev);
361 struct v4l2_subdev *sd = &fimc->subdev;
362 struct fimc_md *fmd = p;
363 int ret;
364
365 if (fimc == NULL)
366 return 0;
367
368 if (fimc->index >= FIMC_LITE_MAX_DEVS)
369 return 0;
370
371 fmd->fimc_lite[fimc->index] = fimc;
372 sd->grp_id = FLITE_GROUP_ID;
373
374 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
375 if (ret) {
376 v4l2_err(&fmd->v4l2_dev,
377 "Failed to register FIMC-LITE.%d (%d)\n",
378 fimc->index, ret);
379 }
307 return ret; 380 return ret;
308} 381}
309 382
@@ -336,22 +409,56 @@ static int csis_register_callback(struct device *dev, void *p)
336 */ 409 */
337static int fimc_md_register_platform_entities(struct fimc_md *fmd) 410static int fimc_md_register_platform_entities(struct fimc_md *fmd)
338{ 411{
412 struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
339 struct device_driver *driver; 413 struct device_driver *driver;
340 int ret; 414 int ret, i;
341 415
342 driver = driver_find(FIMC_MODULE_NAME, &platform_bus_type); 416 driver = driver_find(FIMC_MODULE_NAME, &platform_bus_type);
343 if (!driver) 417 if (!driver) {
344 return -ENODEV; 418 v4l2_warn(&fmd->v4l2_dev,
419 "%s driver not found, deffering probe\n",
420 FIMC_MODULE_NAME);
421 return -EPROBE_DEFER;
422 }
423
345 ret = driver_for_each_device(driver, NULL, fmd, 424 ret = driver_for_each_device(driver, NULL, fmd,
346 fimc_register_callback); 425 fimc_register_callback);
347 if (ret) 426 if (ret)
348 return ret; 427 return ret;
349 428
350 driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type); 429 driver = driver_find(FIMC_LITE_DRV_NAME, &platform_bus_type);
351 if (driver) 430 if (driver && try_module_get(driver->owner)) {
352 ret = driver_for_each_device(driver, NULL, fmd, 431 ret = driver_for_each_device(driver, NULL, fmd,
353 csis_register_callback); 432 fimc_lite_register_callback);
354 return ret; 433 if (ret)
434 return ret;
435 module_put(driver->owner);
436 }
437 /*
438 * Check if there is any sensor on the MIPI-CSI2 bus and
439 * if not skip the s5p-csis module loading.
440 */
441 if (pdata == NULL)
442 return 0;
443 for (i = 0; i < pdata->num_clients; i++) {
444 if (pdata->isp_info[i].bus_type == FIMC_MIPI_CSI2) {
445 ret = 1;
446 break;
447 }
448 }
449 if (!ret)
450 return 0;
451
452 driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type);
453 if (!driver || !try_module_get(driver->owner)) {
454 v4l2_warn(&fmd->v4l2_dev,
455 "%s driver not found, deffering probe\n",
456 CSIS_DRIVER_NAME);
457 return -EPROBE_DEFER;
458 }
459
460 return driver_for_each_device(driver, NULL, fmd,
461 csis_register_callback);
355} 462}
356 463
357static void fimc_md_unregister_entities(struct fimc_md *fmd) 464static void fimc_md_unregister_entities(struct fimc_md *fmd)
@@ -361,14 +468,20 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
361 for (i = 0; i < FIMC_MAX_DEVS; i++) { 468 for (i = 0; i < FIMC_MAX_DEVS; i++) {
362 if (fmd->fimc[i] == NULL) 469 if (fmd->fimc[i] == NULL)
363 continue; 470 continue;
364 fimc_unregister_m2m_device(fmd->fimc[i]); 471 v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
365 fimc_unregister_capture_device(fmd->fimc[i]);
366 fmd->fimc[i] = NULL; 472 fmd->fimc[i] = NULL;
367 } 473 }
474 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
475 if (fmd->fimc_lite[i] == NULL)
476 continue;
477 v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
478 fmd->fimc_lite[i] = NULL;
479 }
368 for (i = 0; i < CSIS_MAX_ENTITIES; i++) { 480 for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
369 if (fmd->csis[i].sd == NULL) 481 if (fmd->csis[i].sd == NULL)
370 continue; 482 continue;
371 v4l2_device_unregister_subdev(fmd->csis[i].sd); 483 v4l2_device_unregister_subdev(fmd->csis[i].sd);
484 module_put(fmd->csis[i].sd->owner);
372 fmd->csis[i].sd = NULL; 485 fmd->csis[i].sd = NULL;
373 } 486 }
374 for (i = 0; i < fmd->num_sensors; i++) { 487 for (i = 0; i < fmd->num_sensors; i++) {
@@ -379,35 +492,6 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
379 } 492 }
380} 493}
381 494
382static int fimc_md_register_video_nodes(struct fimc_md *fmd)
383{
384 struct video_device *vdev;
385 int i, ret = 0;
386
387 for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) {
388 if (!fmd->fimc[i])
389 continue;
390
391 vdev = fmd->fimc[i]->m2m.vfd;
392 if (vdev) {
393 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
394 if (ret)
395 break;
396 v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n",
397 vdev->name, video_device_node_name(vdev));
398 }
399
400 vdev = fmd->fimc[i]->vid_cap.vfd;
401 if (vdev == NULL)
402 continue;
403 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
404 v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n",
405 vdev->name, video_device_node_name(vdev));
406 }
407
408 return ret;
409}
410
411/** 495/**
412 * __fimc_md_create_fimc_links - create links to all FIMC entities 496 * __fimc_md_create_fimc_links - create links to all FIMC entities
413 * @fmd: fimc media device 497 * @fmd: fimc media device
@@ -416,29 +500,29 @@ static int fimc_md_register_video_nodes(struct fimc_md *fmd)
416 * @pad: the source entity pad index 500 * @pad: the source entity pad index
417 * @fimc_id: index of the fimc device for which link should be enabled 501 * @fimc_id: index of the fimc device for which link should be enabled
418 */ 502 */
419static int __fimc_md_create_fimc_links(struct fimc_md *fmd, 503static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
420 struct media_entity *source, 504 struct media_entity *source,
421 struct v4l2_subdev *sensor, 505 struct v4l2_subdev *sensor,
422 int pad, int fimc_id) 506 int pad, int fimc_id)
423{ 507{
424 struct fimc_sensor_info *s_info; 508 struct fimc_sensor_info *s_info;
425 struct media_entity *sink; 509 struct media_entity *sink;
426 unsigned int flags; 510 unsigned int flags = 0;
427 int ret, i; 511 int ret, i;
428 512
429 for (i = 0; i < FIMC_MAX_DEVS; i++) { 513 for (i = 0; i < FIMC_MAX_DEVS; i++) {
430 if (!fmd->fimc[i]) 514 if (!fmd->fimc[i])
431 break; 515 continue;
432 /* 516 /*
433 * Some FIMC variants are not fitted with camera capture 517 * Some FIMC variants are not fitted with camera capture
434 * interface. Skip creating a link from sensor for those. 518 * interface. Skip creating a link from sensor for those.
435 */ 519 */
436 if (sensor->grp_id == SENSOR_GROUP_ID && 520 if (!fmd->fimc[i]->variant->has_cam_if)
437 !fmd->fimc[i]->variant->has_cam_if)
438 continue; 521 continue;
439 522
440 flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; 523 flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0;
441 sink = &fmd->fimc[i]->vid_cap.subdev->entity; 524
525 sink = &fmd->fimc[i]->vid_cap.subdev.entity;
442 ret = media_entity_create_link(source, pad, sink, 526 ret = media_entity_create_link(source, pad, sink,
443 FIMC_SD_PAD_SINK, flags); 527 FIMC_SD_PAD_SINK, flags);
444 if (ret) 528 if (ret)
@@ -453,7 +537,7 @@ static int __fimc_md_create_fimc_links(struct fimc_md *fmd,
453 v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]", 537 v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
454 source->name, flags ? '=' : '-', sink->name); 538 source->name, flags ? '=' : '-', sink->name);
455 539
456 if (flags == 0) 540 if (flags == 0 || sensor == NULL)
457 continue; 541 continue;
458 s_info = v4l2_get_subdev_hostdata(sensor); 542 s_info = v4l2_get_subdev_hostdata(sensor);
459 if (!WARN_ON(s_info == NULL)) { 543 if (!WARN_ON(s_info == NULL)) {
@@ -463,9 +547,55 @@ static int __fimc_md_create_fimc_links(struct fimc_md *fmd,
463 spin_unlock_irqrestore(&fmd->slock, irq_flags); 547 spin_unlock_irqrestore(&fmd->slock, irq_flags);
464 } 548 }
465 } 549 }
550
551 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
552 if (!fmd->fimc_lite[i])
553 continue;
554
555 flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0;
556
557 sink = &fmd->fimc_lite[i]->subdev.entity;
558 ret = media_entity_create_link(source, pad, sink,
559 FLITE_SD_PAD_SINK, flags);
560 if (ret)
561 return ret;
562
563 /* Notify FIMC-LITE subdev entity */
564 ret = media_entity_call(sink, link_setup, &sink->pads[0],
565 &source->pads[pad], flags);
566 if (ret)
567 break;
568
569 v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
570 source->name, flags ? '=' : '-', sink->name);
571 }
466 return 0; 572 return 0;
467} 573}
468 574
575/* Create links from FIMC-LITE source pads to other entities */
576static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
577{
578 struct media_entity *source, *sink;
579 unsigned int flags = MEDIA_LNK_FL_ENABLED;
580 int i, ret;
581
582 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
583 struct fimc_lite *fimc = fmd->fimc_lite[i];
584 if (fimc == NULL)
585 continue;
586 source = &fimc->subdev.entity;
587 sink = &fimc->vfd->entity;
588 /* FIMC-LITE's subdev and video node */
589 ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
590 sink, 0, flags);
591 if (ret)
592 break;
593 /* TODO: create links to other entities */
594 }
595
596 return ret;
597}
598
469/** 599/**
470 * fimc_md_create_links - create default links between registered entities 600 * fimc_md_create_links - create default links between registered entities
471 * 601 *
@@ -522,8 +652,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
522 v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]", 652 v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]",
523 sensor->entity.name, csis->entity.name); 653 sensor->entity.name, csis->entity.name);
524 654
525 source = &csis->entity; 655 source = NULL;
526 pad = CSIS_PAD_SOURCE;
527 break; 656 break;
528 657
529 case FIMC_ITU_601...FIMC_ITU_656: 658 case FIMC_ITU_601...FIMC_ITU_656:
@@ -539,15 +668,27 @@ static int fimc_md_create_links(struct fimc_md *fmd)
539 if (source == NULL) 668 if (source == NULL)
540 continue; 669 continue;
541 670
542 ret = __fimc_md_create_fimc_links(fmd, source, sensor, pad, 671 ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
543 fimc_id++); 672 pad, fimc_id++);
544 } 673 }
674
675 fimc_id = 0;
676 for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) {
677 if (fmd->csis[i].sd == NULL)
678 continue;
679 source = &fmd->csis[i].sd->entity;
680 pad = CSIS_PAD_SOURCE;
681
682 ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL,
683 pad, fimc_id++);
684 }
685
545 /* Create immutable links between each FIMC's subdev and video node */ 686 /* Create immutable links between each FIMC's subdev and video node */
546 flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED; 687 flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
547 for (i = 0; i < FIMC_MAX_DEVS; i++) { 688 for (i = 0; i < FIMC_MAX_DEVS; i++) {
548 if (!fmd->fimc[i]) 689 if (!fmd->fimc[i])
549 continue; 690 continue;
550 source = &fmd->fimc[i]->vid_cap.subdev->entity; 691 source = &fmd->fimc[i]->vid_cap.subdev.entity;
551 sink = &fmd->fimc[i]->vid_cap.vfd->entity; 692 sink = &fmd->fimc[i]->vid_cap.vfd->entity;
552 ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, 693 ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
553 sink, 0, flags); 694 sink, 0, flags);
@@ -555,7 +696,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
555 break; 696 break;
556 } 697 }
557 698
558 return ret; 699 return __fimc_md_create_flite_source_links(fmd);
559} 700}
560 701
561/* 702/*
@@ -663,24 +804,40 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
663static int fimc_md_link_notify(struct media_pad *source, 804static int fimc_md_link_notify(struct media_pad *source,
664 struct media_pad *sink, u32 flags) 805 struct media_pad *sink, u32 flags)
665{ 806{
807 struct fimc_lite *fimc_lite = NULL;
808 struct fimc_dev *fimc = NULL;
809 struct fimc_pipeline *pipeline;
666 struct v4l2_subdev *sd; 810 struct v4l2_subdev *sd;
667 struct fimc_dev *fimc;
668 int ret = 0; 811 int ret = 0;
669 812
670 if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 813 if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
671 return 0; 814 return 0;
672 815
673 sd = media_entity_to_v4l2_subdev(sink->entity); 816 sd = media_entity_to_v4l2_subdev(sink->entity);
674 fimc = v4l2_get_subdevdata(sd);
675 817
676 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 818 switch (sd->grp_id) {
677 ret = __fimc_pipeline_shutdown(fimc); 819 case FLITE_GROUP_ID:
678 fimc->pipeline.sensor = NULL; 820 fimc_lite = v4l2_get_subdevdata(sd);
679 fimc->pipeline.csis = NULL; 821 pipeline = &fimc_lite->pipeline;
822 break;
823 case FIMC_GROUP_ID:
824 fimc = v4l2_get_subdevdata(sd);
825 pipeline = &fimc->pipeline;
826 break;
827 default:
828 return 0;
829 }
680 830
681 mutex_lock(&fimc->lock); 831 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
682 fimc_ctrls_delete(fimc->vid_cap.ctx); 832 ret = __fimc_pipeline_shutdown(pipeline);
683 mutex_unlock(&fimc->lock); 833 pipeline->subdevs[IDX_SENSOR] = NULL;
834 pipeline->subdevs[IDX_CSIS] = NULL;
835
836 if (fimc) {
837 mutex_lock(&fimc->lock);
838 fimc_ctrls_delete(fimc->vid_cap.ctx);
839 mutex_unlock(&fimc->lock);
840 }
684 return ret; 841 return ret;
685 } 842 }
686 /* 843 /*
@@ -688,14 +845,23 @@ static int fimc_md_link_notify(struct media_pad *source,
688 * pipeline is already in use, i.e. its video node is opened. 845 * pipeline is already in use, i.e. its video node is opened.
689 * Recreate the controls destroyed during the link deactivation. 846 * Recreate the controls destroyed during the link deactivation.
690 */ 847 */
691 mutex_lock(&fimc->lock); 848 if (fimc) {
692 if (fimc->vid_cap.refcnt > 0) { 849 mutex_lock(&fimc->lock);
693 ret = __fimc_pipeline_initialize(fimc, source->entity, true); 850 if (fimc->vid_cap.refcnt > 0) {
851 ret = __fimc_pipeline_initialize(pipeline,
852 source->entity, true);
694 if (!ret) 853 if (!ret)
695 ret = fimc_capture_ctrls_create(fimc); 854 ret = fimc_capture_ctrls_create(fimc);
855 }
856 mutex_unlock(&fimc->lock);
857 } else {
858 mutex_lock(&fimc_lite->lock);
859 if (fimc_lite->ref_count > 0) {
860 ret = __fimc_pipeline_initialize(pipeline,
861 source->entity, true);
862 }
863 mutex_unlock(&fimc_lite->lock);
696 } 864 }
697 mutex_unlock(&fimc->lock);
698
699 return ret ? -EPIPE : ret; 865 return ret ? -EPIPE : ret;
700} 866}
701 867
@@ -744,7 +910,7 @@ static ssize_t fimc_md_sysfs_store(struct device *dev,
744static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO, 910static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
745 fimc_md_sysfs_show, fimc_md_sysfs_store); 911 fimc_md_sysfs_show, fimc_md_sysfs_store);
746 912
747static int __devinit fimc_md_probe(struct platform_device *pdev) 913static int fimc_md_probe(struct platform_device *pdev)
748{ 914{
749 struct v4l2_device *v4l2_dev; 915 struct v4l2_device *v4l2_dev;
750 struct fimc_md *fmd; 916 struct fimc_md *fmd;
@@ -776,42 +942,48 @@ static int __devinit fimc_md_probe(struct platform_device *pdev)
776 ret = media_device_register(&fmd->media_dev); 942 ret = media_device_register(&fmd->media_dev);
777 if (ret < 0) { 943 if (ret < 0) {
778 v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); 944 v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
779 goto err2; 945 goto err_md;
780 } 946 }
781 ret = fimc_md_get_clocks(fmd); 947 ret = fimc_md_get_clocks(fmd);
782 if (ret) 948 if (ret)
783 goto err3; 949 goto err_clk;
784 950
785 fmd->user_subdev_api = false; 951 fmd->user_subdev_api = false;
952
953 /* Protect the media graph while we're registering entities */
954 mutex_lock(&fmd->media_dev.graph_mutex);
955
786 ret = fimc_md_register_platform_entities(fmd); 956 ret = fimc_md_register_platform_entities(fmd);
787 if (ret) 957 if (ret)
788 goto err3; 958 goto err_unlock;
789 959
790 if (pdev->dev.platform_data) { 960 if (pdev->dev.platform_data) {
791 ret = fimc_md_register_sensor_entities(fmd); 961 ret = fimc_md_register_sensor_entities(fmd);
792 if (ret) 962 if (ret)
793 goto err3; 963 goto err_unlock;
794 } 964 }
795 ret = fimc_md_create_links(fmd); 965 ret = fimc_md_create_links(fmd);
796 if (ret) 966 if (ret)
797 goto err3; 967 goto err_unlock;
798 ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); 968 ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
799 if (ret) 969 if (ret)
800 goto err3; 970 goto err_unlock;
801 ret = fimc_md_register_video_nodes(fmd);
802 if (ret)
803 goto err3;
804 971
805 ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); 972 ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
806 if (!ret) { 973 if (ret)
807 platform_set_drvdata(pdev, fmd); 974 goto err_unlock;
808 return 0; 975
809 } 976 platform_set_drvdata(pdev, fmd);
810err3: 977 mutex_unlock(&fmd->media_dev.graph_mutex);
978 return 0;
979
980err_unlock:
981 mutex_unlock(&fmd->media_dev.graph_mutex);
982err_clk:
811 media_device_unregister(&fmd->media_dev); 983 media_device_unregister(&fmd->media_dev);
812 fimc_md_put_clocks(fmd); 984 fimc_md_put_clocks(fmd);
813 fimc_md_unregister_entities(fmd); 985 fimc_md_unregister_entities(fmd);
814err2: 986err_md:
815 v4l2_device_unregister(&fmd->v4l2_dev); 987 v4l2_device_unregister(&fmd->v4l2_dev);
816 return ret; 988 return ret;
817} 989}
@@ -841,10 +1013,12 @@ static struct platform_driver fimc_md_driver = {
841int __init fimc_md_init(void) 1013int __init fimc_md_init(void)
842{ 1014{
843 int ret; 1015 int ret;
1016
844 request_module("s5p-csis"); 1017 request_module("s5p-csis");
845 ret = fimc_register_driver(); 1018 ret = fimc_register_driver();
846 if (ret) 1019 if (ret)
847 return ret; 1020 return ret;
1021
848 return platform_driver_register(&fimc_md_driver); 1022 return platform_driver_register(&fimc_md_driver);
849} 1023}
850void __exit fimc_md_exit(void) 1024void __exit fimc_md_exit(void)
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h
index da3780823e7d..3b8a3492a176 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.h
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2011 Samsung Electronics Co., Ltd. 2 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
@@ -18,12 +18,15 @@
18#include <media/v4l2-subdev.h> 18#include <media/v4l2-subdev.h>
19 19
20#include "fimc-core.h" 20#include "fimc-core.h"
21#include "fimc-lite.h"
21#include "mipi-csis.h" 22#include "mipi-csis.h"
22 23
23/* Group IDs of sensor, MIPI CSIS and the writeback subdevs. */ 24/* Group IDs of sensor, MIPI-CSIS, FIMC-LITE and the writeback subdevs. */
24#define SENSOR_GROUP_ID (1 << 8) 25#define SENSOR_GROUP_ID (1 << 8)
25#define CSIS_GROUP_ID (1 << 9) 26#define CSIS_GROUP_ID (1 << 9)
26#define WRITEBACK_GROUP_ID (1 << 10) 27#define WRITEBACK_GROUP_ID (1 << 10)
28#define FIMC_GROUP_ID (1 << 11)
29#define FLITE_GROUP_ID (1 << 12)
27 30
28#define FIMC_MAX_SENSORS 8 31#define FIMC_MAX_SENSORS 8
29#define FIMC_MAX_CAMCLKS 2 32#define FIMC_MAX_CAMCLKS 2
@@ -73,6 +76,7 @@ struct fimc_md {
73 struct fimc_sensor_info sensor[FIMC_MAX_SENSORS]; 76 struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
74 int num_sensors; 77 int num_sensors;
75 struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS]; 78 struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];
79 struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
76 struct fimc_dev *fimc[FIMC_MAX_DEVS]; 80 struct fimc_dev *fimc[FIMC_MAX_DEVS];
77 struct media_device media_dev; 81 struct media_device media_dev;
78 struct v4l2_device v4l2_dev; 82 struct v4l2_device v4l2_dev;
@@ -108,11 +112,11 @@ static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
108} 112}
109 113
110int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); 114int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
111void fimc_pipeline_prepare(struct fimc_dev *fimc, struct media_entity *me); 115void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me);
112int fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me, 116int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
113 bool resume); 117 bool resume);
114int fimc_pipeline_shutdown(struct fimc_dev *fimc); 118int fimc_pipeline_shutdown(struct fimc_pipeline *p);
115int fimc_pipeline_s_power(struct fimc_dev *fimc, int state); 119int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state);
116int fimc_pipeline_s_stream(struct fimc_dev *fimc, int state); 120int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool state);
117 121
118#endif 122#endif
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
index 15466d0529c1..1fc4ce8446f5 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/video/s5p-fimc/fimc-reg.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Register interface file for Samsung Camera Interface (FIMC) driver 2 * Register interface file for Samsung Camera Interface (FIMC) driver
3 * 3 *
4 * Copyright (c) 2010 Samsung Electronics 4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 * 5 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 * Sylwester Nawrocki, s.nawrocki@samsung.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify 7 * 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 8 * it under the terms of the GNU General Public License version 2 as
@@ -12,9 +11,9 @@
12 11
13#include <linux/io.h> 12#include <linux/io.h>
14#include <linux/delay.h> 13#include <linux/delay.h>
15#include <mach/map.h>
16#include <media/s5p_fimc.h> 14#include <media/s5p_fimc.h>
17 15
16#include "fimc-reg.h"
18#include "fimc-core.h" 17#include "fimc-core.h"
19 18
20 19
@@ -22,19 +21,19 @@ void fimc_hw_reset(struct fimc_dev *dev)
22{ 21{
23 u32 cfg; 22 u32 cfg;
24 23
25 cfg = readl(dev->regs + S5P_CISRCFMT); 24 cfg = readl(dev->regs + FIMC_REG_CISRCFMT);
26 cfg |= S5P_CISRCFMT_ITU601_8BIT; 25 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
27 writel(cfg, dev->regs + S5P_CISRCFMT); 26 writel(cfg, dev->regs + FIMC_REG_CISRCFMT);
28 27
29 /* Software reset. */ 28 /* Software reset. */
30 cfg = readl(dev->regs + S5P_CIGCTRL); 29 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
31 cfg |= (S5P_CIGCTRL_SWRST | S5P_CIGCTRL_IRQ_LEVEL); 30 cfg |= (FIMC_REG_CIGCTRL_SWRST | FIMC_REG_CIGCTRL_IRQ_LEVEL);
32 writel(cfg, dev->regs + S5P_CIGCTRL); 31 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
33 udelay(10); 32 udelay(10);
34 33
35 cfg = readl(dev->regs + S5P_CIGCTRL); 34 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
36 cfg &= ~S5P_CIGCTRL_SWRST; 35 cfg &= ~FIMC_REG_CIGCTRL_SWRST;
37 writel(cfg, dev->regs + S5P_CIGCTRL); 36 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
38 37
39 if (dev->variant->out_buf_count > 4) 38 if (dev->variant->out_buf_count > 4)
40 fimc_hw_set_dma_seq(dev, 0xF); 39 fimc_hw_set_dma_seq(dev, 0xF);
@@ -42,32 +41,32 @@ void fimc_hw_reset(struct fimc_dev *dev)
42 41
43static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx) 42static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
44{ 43{
45 u32 flip = S5P_MSCTRL_FLIP_NORMAL; 44 u32 flip = FIMC_REG_MSCTRL_FLIP_NORMAL;
46 45
47 if (ctx->hflip) 46 if (ctx->hflip)
48 flip = S5P_MSCTRL_FLIP_X_MIRROR; 47 flip = FIMC_REG_MSCTRL_FLIP_X_MIRROR;
49 if (ctx->vflip) 48 if (ctx->vflip)
50 flip = S5P_MSCTRL_FLIP_Y_MIRROR; 49 flip = FIMC_REG_MSCTRL_FLIP_Y_MIRROR;
51 50
52 if (ctx->rotation <= 90) 51 if (ctx->rotation <= 90)
53 return flip; 52 return flip;
54 53
55 return (flip ^ S5P_MSCTRL_FLIP_180) & S5P_MSCTRL_FLIP_180; 54 return (flip ^ FIMC_REG_MSCTRL_FLIP_180) & FIMC_REG_MSCTRL_FLIP_180;
56} 55}
57 56
58static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx) 57static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
59{ 58{
60 u32 flip = S5P_CITRGFMT_FLIP_NORMAL; 59 u32 flip = FIMC_REG_CITRGFMT_FLIP_NORMAL;
61 60
62 if (ctx->hflip) 61 if (ctx->hflip)
63 flip |= S5P_CITRGFMT_FLIP_X_MIRROR; 62 flip |= FIMC_REG_CITRGFMT_FLIP_X_MIRROR;
64 if (ctx->vflip) 63 if (ctx->vflip)
65 flip |= S5P_CITRGFMT_FLIP_Y_MIRROR; 64 flip |= FIMC_REG_CITRGFMT_FLIP_Y_MIRROR;
66 65
67 if (ctx->rotation <= 90) 66 if (ctx->rotation <= 90)
68 return flip; 67 return flip;
69 68
70 return (flip ^ S5P_CITRGFMT_FLIP_180) & S5P_CITRGFMT_FLIP_180; 69 return (flip ^ FIMC_REG_CITRGFMT_FLIP_180) & FIMC_REG_CITRGFMT_FLIP_180;
71} 70}
72 71
73void fimc_hw_set_rotation(struct fimc_ctx *ctx) 72void fimc_hw_set_rotation(struct fimc_ctx *ctx)
@@ -75,9 +74,9 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
75 u32 cfg, flip; 74 u32 cfg, flip;
76 struct fimc_dev *dev = ctx->fimc_dev; 75 struct fimc_dev *dev = ctx->fimc_dev;
77 76
78 cfg = readl(dev->regs + S5P_CITRGFMT); 77 cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
79 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 | 78 cfg &= ~(FIMC_REG_CITRGFMT_INROT90 | FIMC_REG_CITRGFMT_OUTROT90 |
80 S5P_CITRGFMT_FLIP_180); 79 FIMC_REG_CITRGFMT_FLIP_180);
81 80
82 /* 81 /*
83 * The input and output rotator cannot work simultaneously. 82 * The input and output rotator cannot work simultaneously.
@@ -85,21 +84,21 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
85 * in direct fifo output mode. 84 * in direct fifo output mode.
86 */ 85 */
87 if (ctx->rotation == 90 || ctx->rotation == 270) { 86 if (ctx->rotation == 90 || ctx->rotation == 270) {
88 if (ctx->out_path == FIMC_LCDFIFO) 87 if (ctx->out_path == FIMC_IO_LCDFIFO)
89 cfg |= S5P_CITRGFMT_INROT90; 88 cfg |= FIMC_REG_CITRGFMT_INROT90;
90 else 89 else
91 cfg |= S5P_CITRGFMT_OUTROT90; 90 cfg |= FIMC_REG_CITRGFMT_OUTROT90;
92 } 91 }
93 92
94 if (ctx->out_path == FIMC_DMA) { 93 if (ctx->out_path == FIMC_IO_DMA) {
95 cfg |= fimc_hw_get_target_flip(ctx); 94 cfg |= fimc_hw_get_target_flip(ctx);
96 writel(cfg, dev->regs + S5P_CITRGFMT); 95 writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
97 } else { 96 } else {
98 /* LCD FIFO path */ 97 /* LCD FIFO path */
99 flip = readl(dev->regs + S5P_MSCTRL); 98 flip = readl(dev->regs + FIMC_REG_MSCTRL);
100 flip &= ~S5P_MSCTRL_FLIP_MASK; 99 flip &= ~FIMC_REG_MSCTRL_FLIP_MASK;
101 flip |= fimc_hw_get_in_flip(ctx); 100 flip |= fimc_hw_get_in_flip(ctx);
102 writel(flip, dev->regs + S5P_MSCTRL); 101 writel(flip, dev->regs + FIMC_REG_MSCTRL);
103 } 102 }
104} 103}
105 104
@@ -110,43 +109,40 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx)
110 struct fimc_frame *frame = &ctx->d_frame; 109 struct fimc_frame *frame = &ctx->d_frame;
111 110
112 dbg("w= %d, h= %d color: %d", frame->width, 111 dbg("w= %d, h= %d color: %d", frame->width,
113 frame->height, frame->fmt->color); 112 frame->height, frame->fmt->color);
114 113
115 cfg = readl(dev->regs + S5P_CITRGFMT); 114 cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
116 cfg &= ~(S5P_CITRGFMT_FMT_MASK | S5P_CITRGFMT_HSIZE_MASK | 115 cfg &= ~(FIMC_REG_CITRGFMT_FMT_MASK | FIMC_REG_CITRGFMT_HSIZE_MASK |
117 S5P_CITRGFMT_VSIZE_MASK); 116 FIMC_REG_CITRGFMT_VSIZE_MASK);
118 117
119 switch (frame->fmt->color) { 118 switch (frame->fmt->color) {
120 case S5P_FIMC_RGB444...S5P_FIMC_RGB888: 119 case FIMC_FMT_RGB444...FIMC_FMT_RGB888:
121 cfg |= S5P_CITRGFMT_RGB; 120 cfg |= FIMC_REG_CITRGFMT_RGB;
122 break; 121 break;
123 case S5P_FIMC_YCBCR420: 122 case FIMC_FMT_YCBCR420:
124 cfg |= S5P_CITRGFMT_YCBCR420; 123 cfg |= FIMC_REG_CITRGFMT_YCBCR420;
125 break; 124 break;
126 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422: 125 case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
127 if (frame->fmt->colplanes == 1) 126 if (frame->fmt->colplanes == 1)
128 cfg |= S5P_CITRGFMT_YCBCR422_1P; 127 cfg |= FIMC_REG_CITRGFMT_YCBCR422_1P;
129 else 128 else
130 cfg |= S5P_CITRGFMT_YCBCR422; 129 cfg |= FIMC_REG_CITRGFMT_YCBCR422;
131 break; 130 break;
132 default: 131 default:
133 break; 132 break;
134 } 133 }
135 134
136 if (ctx->rotation == 90 || ctx->rotation == 270) { 135 if (ctx->rotation == 90 || ctx->rotation == 270)
137 cfg |= S5P_CITRGFMT_HSIZE(frame->height); 136 cfg |= (frame->height << 16) | frame->width;
138 cfg |= S5P_CITRGFMT_VSIZE(frame->width); 137 else
139 } else { 138 cfg |= (frame->width << 16) | frame->height;
140
141 cfg |= S5P_CITRGFMT_HSIZE(frame->width);
142 cfg |= S5P_CITRGFMT_VSIZE(frame->height);
143 }
144 139
145 writel(cfg, dev->regs + S5P_CITRGFMT); 140 writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
146 141
147 cfg = readl(dev->regs + S5P_CITAREA) & ~S5P_CITAREA_MASK; 142 cfg = readl(dev->regs + FIMC_REG_CITAREA);
143 cfg &= ~FIMC_REG_CITAREA_MASK;
148 cfg |= (frame->width * frame->height); 144 cfg |= (frame->width * frame->height);
149 writel(cfg, dev->regs + S5P_CITAREA); 145 writel(cfg, dev->regs + FIMC_REG_CITAREA);
150} 146}
151 147
152static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx) 148static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
@@ -155,87 +151,82 @@ static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
155 struct fimc_frame *frame = &ctx->d_frame; 151 struct fimc_frame *frame = &ctx->d_frame;
156 u32 cfg; 152 u32 cfg;
157 153
158 cfg = S5P_ORIG_SIZE_HOR(frame->f_width); 154 cfg = (frame->f_height << 16) | frame->f_width;
159 cfg |= S5P_ORIG_SIZE_VER(frame->f_height); 155 writel(cfg, dev->regs + FIMC_REG_ORGOSIZE);
160 writel(cfg, dev->regs + S5P_ORGOSIZE);
161 156
162 /* Select color space conversion equation (HD/SD size).*/ 157 /* Select color space conversion equation (HD/SD size).*/
163 cfg = readl(dev->regs + S5P_CIGCTRL); 158 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
164 if (frame->f_width >= 1280) /* HD */ 159 if (frame->f_width >= 1280) /* HD */
165 cfg |= S5P_CIGCTRL_CSC_ITU601_709; 160 cfg |= FIMC_REG_CIGCTRL_CSC_ITU601_709;
166 else /* SD */ 161 else /* SD */
167 cfg &= ~S5P_CIGCTRL_CSC_ITU601_709; 162 cfg &= ~FIMC_REG_CIGCTRL_CSC_ITU601_709;
168 writel(cfg, dev->regs + S5P_CIGCTRL); 163 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
169 164
170} 165}
171 166
172void fimc_hw_set_out_dma(struct fimc_ctx *ctx) 167void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
173{ 168{
174 u32 cfg;
175 struct fimc_dev *dev = ctx->fimc_dev; 169 struct fimc_dev *dev = ctx->fimc_dev;
176 struct fimc_frame *frame = &ctx->d_frame; 170 struct fimc_frame *frame = &ctx->d_frame;
177 struct fimc_dma_offset *offset = &frame->dma_offset; 171 struct fimc_dma_offset *offset = &frame->dma_offset;
178 struct fimc_fmt *fmt = frame->fmt; 172 struct fimc_fmt *fmt = frame->fmt;
173 u32 cfg;
179 174
180 /* Set the input dma offsets. */ 175 /* Set the input dma offsets. */
181 cfg = 0; 176 cfg = (offset->y_v << 16) | offset->y_h;
182 cfg |= S5P_CIO_OFFS_HOR(offset->y_h); 177 writel(cfg, dev->regs + FIMC_REG_CIOYOFF);
183 cfg |= S5P_CIO_OFFS_VER(offset->y_v);
184 writel(cfg, dev->regs + S5P_CIOYOFF);
185 178
186 cfg = 0; 179 cfg = (offset->cb_v << 16) | offset->cb_h;
187 cfg |= S5P_CIO_OFFS_HOR(offset->cb_h); 180 writel(cfg, dev->regs + FIMC_REG_CIOCBOFF);
188 cfg |= S5P_CIO_OFFS_VER(offset->cb_v);
189 writel(cfg, dev->regs + S5P_CIOCBOFF);
190 181
191 cfg = 0; 182 cfg = (offset->cr_v << 16) | offset->cr_h;
192 cfg |= S5P_CIO_OFFS_HOR(offset->cr_h); 183 writel(cfg, dev->regs + FIMC_REG_CIOCROFF);
193 cfg |= S5P_CIO_OFFS_VER(offset->cr_v);
194 writel(cfg, dev->regs + S5P_CIOCROFF);
195 184
196 fimc_hw_set_out_dma_size(ctx); 185 fimc_hw_set_out_dma_size(ctx);
197 186
198 /* Configure chroma components order. */ 187 /* Configure chroma components order. */
199 cfg = readl(dev->regs + S5P_CIOCTRL); 188 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
200 189
201 cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK | 190 cfg &= ~(FIMC_REG_CIOCTRL_ORDER2P_MASK |
202 S5P_CIOCTRL_YCBCR_PLANE_MASK | S5P_CIOCTRL_RGB16FMT_MASK); 191 FIMC_REG_CIOCTRL_ORDER422_MASK |
192 FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK |
193 FIMC_REG_CIOCTRL_RGB16FMT_MASK);
203 194
204 if (fmt->colplanes == 1) 195 if (fmt->colplanes == 1)
205 cfg |= ctx->out_order_1p; 196 cfg |= ctx->out_order_1p;
206 else if (fmt->colplanes == 2) 197 else if (fmt->colplanes == 2)
207 cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE; 198 cfg |= ctx->out_order_2p | FIMC_REG_CIOCTRL_YCBCR_2PLANE;
208 else if (fmt->colplanes == 3) 199 else if (fmt->colplanes == 3)
209 cfg |= S5P_CIOCTRL_YCBCR_3PLANE; 200 cfg |= FIMC_REG_CIOCTRL_YCBCR_3PLANE;
210 201
211 if (fmt->color == S5P_FIMC_RGB565) 202 if (fmt->color == FIMC_FMT_RGB565)
212 cfg |= S5P_CIOCTRL_RGB565; 203 cfg |= FIMC_REG_CIOCTRL_RGB565;
213 else if (fmt->color == S5P_FIMC_RGB555) 204 else if (fmt->color == FIMC_FMT_RGB555)
214 cfg |= S5P_CIOCTRL_ARGB1555; 205 cfg |= FIMC_REG_CIOCTRL_ARGB1555;
215 else if (fmt->color == S5P_FIMC_RGB444) 206 else if (fmt->color == FIMC_FMT_RGB444)
216 cfg |= S5P_CIOCTRL_ARGB4444; 207 cfg |= FIMC_REG_CIOCTRL_ARGB4444;
217 208
218 writel(cfg, dev->regs + S5P_CIOCTRL); 209 writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
219} 210}
220 211
221static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable) 212static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable)
222{ 213{
223 u32 cfg = readl(dev->regs + S5P_ORGISIZE); 214 u32 cfg = readl(dev->regs + FIMC_REG_ORGISIZE);
224 if (enable) 215 if (enable)
225 cfg |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; 216 cfg |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
226 else 217 else
227 cfg &= ~S5P_CIREAL_ISIZE_AUTOLOAD_EN; 218 cfg &= ~FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
228 writel(cfg, dev->regs + S5P_ORGISIZE); 219 writel(cfg, dev->regs + FIMC_REG_ORGISIZE);
229} 220}
230 221
231void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable) 222void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
232{ 223{
233 u32 cfg = readl(dev->regs + S5P_CIOCTRL); 224 u32 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
234 if (enable) 225 if (enable)
235 cfg |= S5P_CIOCTRL_LASTIRQ_ENABLE; 226 cfg |= FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
236 else 227 else
237 cfg &= ~S5P_CIOCTRL_LASTIRQ_ENABLE; 228 cfg &= ~FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
238 writel(cfg, dev->regs + S5P_CIOCTRL); 229 writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
239} 230}
240 231
241void fimc_hw_set_prescaler(struct fimc_ctx *ctx) 232void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
@@ -245,15 +236,13 @@ void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
245 u32 cfg, shfactor; 236 u32 cfg, shfactor;
246 237
247 shfactor = 10 - (sc->hfactor + sc->vfactor); 238 shfactor = 10 - (sc->hfactor + sc->vfactor);
239 cfg = shfactor << 28;
248 240
249 cfg = S5P_CISCPRERATIO_SHFACTOR(shfactor); 241 cfg |= (sc->pre_hratio << 16) | sc->pre_vratio;
250 cfg |= S5P_CISCPRERATIO_HOR(sc->pre_hratio); 242 writel(cfg, dev->regs + FIMC_REG_CISCPRERATIO);
251 cfg |= S5P_CISCPRERATIO_VER(sc->pre_vratio);
252 writel(cfg, dev->regs + S5P_CISCPRERATIO);
253 243
254 cfg = S5P_CISCPREDST_WIDTH(sc->pre_dst_width); 244 cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
255 cfg |= S5P_CISCPREDST_HEIGHT(sc->pre_dst_height); 245 writel(cfg, dev->regs + FIMC_REG_CISCPREDST);
256 writel(cfg, dev->regs + S5P_CISCPREDST);
257} 246}
258 247
259static void fimc_hw_set_scaler(struct fimc_ctx *ctx) 248static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
@@ -263,93 +252,95 @@ static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
263 struct fimc_frame *src_frame = &ctx->s_frame; 252 struct fimc_frame *src_frame = &ctx->s_frame;
264 struct fimc_frame *dst_frame = &ctx->d_frame; 253 struct fimc_frame *dst_frame = &ctx->d_frame;
265 254
266 u32 cfg = readl(dev->regs + S5P_CISCCTRL); 255 u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
267 256
268 cfg &= ~(S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE | 257 cfg &= ~(FIMC_REG_CISCCTRL_CSCR2Y_WIDE | FIMC_REG_CISCCTRL_CSCY2R_WIDE |
269 S5P_CISCCTRL_SCALEUP_H | S5P_CISCCTRL_SCALEUP_V | 258 FIMC_REG_CISCCTRL_SCALEUP_H | FIMC_REG_CISCCTRL_SCALEUP_V |
270 S5P_CISCCTRL_SCALERBYPASS | S5P_CISCCTRL_ONE2ONE | 259 FIMC_REG_CISCCTRL_SCALERBYPASS | FIMC_REG_CISCCTRL_ONE2ONE |
271 S5P_CISCCTRL_INRGB_FMT_MASK | S5P_CISCCTRL_OUTRGB_FMT_MASK | 260 FIMC_REG_CISCCTRL_INRGB_FMT_MASK | FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK |
272 S5P_CISCCTRL_INTERLACE | S5P_CISCCTRL_RGB_EXT); 261 FIMC_REG_CISCCTRL_INTERLACE | FIMC_REG_CISCCTRL_RGB_EXT);
273 262
274 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) 263 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
275 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); 264 cfg |= (FIMC_REG_CISCCTRL_CSCR2Y_WIDE |
265 FIMC_REG_CISCCTRL_CSCY2R_WIDE);
276 266
277 if (!sc->enabled) 267 if (!sc->enabled)
278 cfg |= S5P_CISCCTRL_SCALERBYPASS; 268 cfg |= FIMC_REG_CISCCTRL_SCALERBYPASS;
279 269
280 if (sc->scaleup_h) 270 if (sc->scaleup_h)
281 cfg |= S5P_CISCCTRL_SCALEUP_H; 271 cfg |= FIMC_REG_CISCCTRL_SCALEUP_H;
282 272
283 if (sc->scaleup_v) 273 if (sc->scaleup_v)
284 cfg |= S5P_CISCCTRL_SCALEUP_V; 274 cfg |= FIMC_REG_CISCCTRL_SCALEUP_V;
285 275
286 if (sc->copy_mode) 276 if (sc->copy_mode)
287 cfg |= S5P_CISCCTRL_ONE2ONE; 277 cfg |= FIMC_REG_CISCCTRL_ONE2ONE;
288 278
289 if (ctx->in_path == FIMC_DMA) { 279 if (ctx->in_path == FIMC_IO_DMA) {
290 switch (src_frame->fmt->color) { 280 switch (src_frame->fmt->color) {
291 case S5P_FIMC_RGB565: 281 case FIMC_FMT_RGB565:
292 cfg |= S5P_CISCCTRL_INRGB_FMT_RGB565; 282 cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB565;
293 break; 283 break;
294 case S5P_FIMC_RGB666: 284 case FIMC_FMT_RGB666:
295 cfg |= S5P_CISCCTRL_INRGB_FMT_RGB666; 285 cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB666;
296 break; 286 break;
297 case S5P_FIMC_RGB888: 287 case FIMC_FMT_RGB888:
298 cfg |= S5P_CISCCTRL_INRGB_FMT_RGB888; 288 cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB888;
299 break; 289 break;
300 } 290 }
301 } 291 }
302 292
303 if (ctx->out_path == FIMC_DMA) { 293 if (ctx->out_path == FIMC_IO_DMA) {
304 u32 color = dst_frame->fmt->color; 294 u32 color = dst_frame->fmt->color;
305 295
306 if (color >= S5P_FIMC_RGB444 && color <= S5P_FIMC_RGB565) 296 if (color >= FIMC_FMT_RGB444 && color <= FIMC_FMT_RGB565)
307 cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB565; 297 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565;
308 else if (color == S5P_FIMC_RGB666) 298 else if (color == FIMC_FMT_RGB666)
309 cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB666; 299 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666;
310 else if (color == S5P_FIMC_RGB888) 300 else if (color == FIMC_FMT_RGB888)
311 cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888; 301 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
312 } else { 302 } else {
313 cfg |= S5P_CISCCTRL_OUTRGB_FMT_RGB888; 303 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
314 304
315 if (ctx->flags & FIMC_SCAN_MODE_INTERLACED) 305 if (ctx->flags & FIMC_SCAN_MODE_INTERLACED)
316 cfg |= S5P_CISCCTRL_INTERLACE; 306 cfg |= FIMC_REG_CISCCTRL_INTERLACE;
317 } 307 }
318 308
319 writel(cfg, dev->regs + S5P_CISCCTRL); 309 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
320} 310}
321 311
322void fimc_hw_set_mainscaler(struct fimc_ctx *ctx) 312void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
323{ 313{
324 struct fimc_dev *dev = ctx->fimc_dev; 314 struct fimc_dev *dev = ctx->fimc_dev;
325 struct samsung_fimc_variant *variant = dev->variant; 315 struct fimc_variant *variant = dev->variant;
326 struct fimc_scaler *sc = &ctx->scaler; 316 struct fimc_scaler *sc = &ctx->scaler;
327 u32 cfg; 317 u32 cfg;
328 318
329 dbg("main_hratio= 0x%X main_vratio= 0x%X", 319 dbg("main_hratio= 0x%X main_vratio= 0x%X",
330 sc->main_hratio, sc->main_vratio); 320 sc->main_hratio, sc->main_vratio);
331 321
332 fimc_hw_set_scaler(ctx); 322 fimc_hw_set_scaler(ctx);
333 323
334 cfg = readl(dev->regs + S5P_CISCCTRL); 324 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
335 cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); 325 cfg &= ~(FIMC_REG_CISCCTRL_MHRATIO_MASK |
326 FIMC_REG_CISCCTRL_MVRATIO_MASK);
336 327
337 if (variant->has_mainscaler_ext) { 328 if (variant->has_mainscaler_ext) {
338 cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio); 329 cfg |= FIMC_REG_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
339 cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio); 330 cfg |= FIMC_REG_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
340 writel(cfg, dev->regs + S5P_CISCCTRL); 331 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
341 332
342 cfg = readl(dev->regs + S5P_CIEXTEN); 333 cfg = readl(dev->regs + FIMC_REG_CIEXTEN);
343 334
344 cfg &= ~(S5P_CIEXTEN_MVRATIO_EXT_MASK | 335 cfg &= ~(FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK |
345 S5P_CIEXTEN_MHRATIO_EXT_MASK); 336 FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK);
346 cfg |= S5P_CIEXTEN_MHRATIO_EXT(sc->main_hratio); 337 cfg |= FIMC_REG_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
347 cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio); 338 cfg |= FIMC_REG_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
348 writel(cfg, dev->regs + S5P_CIEXTEN); 339 writel(cfg, dev->regs + FIMC_REG_CIEXTEN);
349 } else { 340 } else {
350 cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio); 341 cfg |= FIMC_REG_CISCCTRL_MHRATIO(sc->main_hratio);
351 cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio); 342 cfg |= FIMC_REG_CISCCTRL_MVRATIO(sc->main_vratio);
352 writel(cfg, dev->regs + S5P_CISCCTRL); 343 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
353 } 344 }
354} 345}
355 346
@@ -357,40 +348,41 @@ void fimc_hw_en_capture(struct fimc_ctx *ctx)
357{ 348{
358 struct fimc_dev *dev = ctx->fimc_dev; 349 struct fimc_dev *dev = ctx->fimc_dev;
359 350
360 u32 cfg = readl(dev->regs + S5P_CIIMGCPT); 351 u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
361 352
362 if (ctx->out_path == FIMC_DMA) { 353 if (ctx->out_path == FIMC_IO_DMA) {
363 /* one shot mode */ 354 /* one shot mode */
364 cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE | S5P_CIIMGCPT_IMGCPTEN; 355 cfg |= FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE |
356 FIMC_REG_CIIMGCPT_IMGCPTEN;
365 } else { 357 } else {
366 /* Continuous frame capture mode (freerun). */ 358 /* Continuous frame capture mode (freerun). */
367 cfg &= ~(S5P_CIIMGCPT_CPT_FREN_ENABLE | 359 cfg &= ~(FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE |
368 S5P_CIIMGCPT_CPT_FRMOD_CNT); 360 FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT);
369 cfg |= S5P_CIIMGCPT_IMGCPTEN; 361 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
370 } 362 }
371 363
372 if (ctx->scaler.enabled) 364 if (ctx->scaler.enabled)
373 cfg |= S5P_CIIMGCPT_IMGCPTEN_SC; 365 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
374 366
375 writel(cfg | S5P_CIIMGCPT_IMGCPTEN, dev->regs + S5P_CIIMGCPT); 367 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
368 writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
376} 369}
377 370
378void fimc_hw_set_effect(struct fimc_ctx *ctx, bool active) 371void fimc_hw_set_effect(struct fimc_ctx *ctx)
379{ 372{
380 struct fimc_dev *dev = ctx->fimc_dev; 373 struct fimc_dev *dev = ctx->fimc_dev;
381 struct fimc_effect *effect = &ctx->effect; 374 struct fimc_effect *effect = &ctx->effect;
382 u32 cfg = 0; 375 u32 cfg = 0;
383 376
384 if (active) { 377 if (effect->type != FIMC_REG_CIIMGEFF_FIN_BYPASS) {
385 cfg |= S5P_CIIMGEFF_IE_SC_AFTER | S5P_CIIMGEFF_IE_ENABLE; 378 cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER |
379 FIMC_REG_CIIMGEFF_IE_ENABLE;
386 cfg |= effect->type; 380 cfg |= effect->type;
387 if (effect->type == S5P_FIMC_EFFECT_ARBITRARY) { 381 if (effect->type == FIMC_REG_CIIMGEFF_FIN_ARBITRARY)
388 cfg |= S5P_CIIMGEFF_PAT_CB(effect->pat_cb); 382 cfg |= (effect->pat_cb << 13) | effect->pat_cr;
389 cfg |= S5P_CIIMGEFF_PAT_CR(effect->pat_cr);
390 }
391 } 383 }
392 384
393 writel(cfg, dev->regs + S5P_CIIMGEFF); 385 writel(cfg, dev->regs + FIMC_REG_CIIMGEFF);
394} 386}
395 387
396void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx) 388void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
@@ -402,10 +394,10 @@ void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
402 if (!(frame->fmt->flags & FMT_HAS_ALPHA)) 394 if (!(frame->fmt->flags & FMT_HAS_ALPHA))
403 return; 395 return;
404 396
405 cfg = readl(dev->regs + S5P_CIOCTRL); 397 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
406 cfg &= ~S5P_CIOCTRL_ALPHA_OUT_MASK; 398 cfg &= ~FIMC_REG_CIOCTRL_ALPHA_OUT_MASK;
407 cfg |= (frame->alpha << 4); 399 cfg |= (frame->alpha << 4);
408 writel(cfg, dev->regs + S5P_CIOCTRL); 400 writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
409} 401}
410 402
411static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx) 403static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
@@ -415,16 +407,14 @@ static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
415 u32 cfg_o = 0; 407 u32 cfg_o = 0;
416 u32 cfg_r = 0; 408 u32 cfg_r = 0;
417 409
418 if (FIMC_LCDFIFO == ctx->out_path) 410 if (FIMC_IO_LCDFIFO == ctx->out_path)
419 cfg_r |= S5P_CIREAL_ISIZE_AUTOLOAD_EN; 411 cfg_r |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
420 412
421 cfg_o |= S5P_ORIG_SIZE_HOR(frame->f_width); 413 cfg_o |= (frame->f_height << 16) | frame->f_width;
422 cfg_o |= S5P_ORIG_SIZE_VER(frame->f_height); 414 cfg_r |= (frame->height << 16) | frame->width;
423 cfg_r |= S5P_CIREAL_ISIZE_WIDTH(frame->width);
424 cfg_r |= S5P_CIREAL_ISIZE_HEIGHT(frame->height);
425 415
426 writel(cfg_o, dev->regs + S5P_ORGISIZE); 416 writel(cfg_o, dev->regs + FIMC_REG_ORGISIZE);
427 writel(cfg_r, dev->regs + S5P_CIREAL_ISIZE); 417 writel(cfg_r, dev->regs + FIMC_REG_CIREAL_ISIZE);
428} 418}
429 419
430void fimc_hw_set_in_dma(struct fimc_ctx *ctx) 420void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
@@ -435,80 +425,77 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
435 u32 cfg; 425 u32 cfg;
436 426
437 /* Set the pixel offsets. */ 427 /* Set the pixel offsets. */
438 cfg = S5P_CIO_OFFS_HOR(offset->y_h); 428 cfg = (offset->y_v << 16) | offset->y_h;
439 cfg |= S5P_CIO_OFFS_VER(offset->y_v); 429 writel(cfg, dev->regs + FIMC_REG_CIIYOFF);
440 writel(cfg, dev->regs + S5P_CIIYOFF);
441 430
442 cfg = S5P_CIO_OFFS_HOR(offset->cb_h); 431 cfg = (offset->cb_v << 16) | offset->cb_h;
443 cfg |= S5P_CIO_OFFS_VER(offset->cb_v); 432 writel(cfg, dev->regs + FIMC_REG_CIICBOFF);
444 writel(cfg, dev->regs + S5P_CIICBOFF);
445 433
446 cfg = S5P_CIO_OFFS_HOR(offset->cr_h); 434 cfg = (offset->cr_v << 16) | offset->cr_h;
447 cfg |= S5P_CIO_OFFS_VER(offset->cr_v); 435 writel(cfg, dev->regs + FIMC_REG_CIICROFF);
448 writel(cfg, dev->regs + S5P_CIICROFF);
449 436
450 /* Input original and real size. */ 437 /* Input original and real size. */
451 fimc_hw_set_in_dma_size(ctx); 438 fimc_hw_set_in_dma_size(ctx);
452 439
453 /* Use DMA autoload only in FIFO mode. */ 440 /* Use DMA autoload only in FIFO mode. */
454 fimc_hw_en_autoload(dev, ctx->out_path == FIMC_LCDFIFO); 441 fimc_hw_en_autoload(dev, ctx->out_path == FIMC_IO_LCDFIFO);
455 442
456 /* Set the input DMA to process single frame only. */ 443 /* Set the input DMA to process single frame only. */
457 cfg = readl(dev->regs + S5P_MSCTRL); 444 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
458 cfg &= ~(S5P_MSCTRL_INFORMAT_MASK 445 cfg &= ~(FIMC_REG_MSCTRL_INFORMAT_MASK
459 | S5P_MSCTRL_IN_BURST_COUNT_MASK 446 | FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK
460 | S5P_MSCTRL_INPUT_MASK 447 | FIMC_REG_MSCTRL_INPUT_MASK
461 | S5P_MSCTRL_C_INT_IN_MASK 448 | FIMC_REG_MSCTRL_C_INT_IN_MASK
462 | S5P_MSCTRL_2P_IN_ORDER_MASK); 449 | FIMC_REG_MSCTRL_2P_IN_ORDER_MASK);
463 450
464 cfg |= (S5P_MSCTRL_IN_BURST_COUNT(4) 451 cfg |= (FIMC_REG_MSCTRL_IN_BURST_COUNT(4)
465 | S5P_MSCTRL_INPUT_MEMORY 452 | FIMC_REG_MSCTRL_INPUT_MEMORY
466 | S5P_MSCTRL_FIFO_CTRL_FULL); 453 | FIMC_REG_MSCTRL_FIFO_CTRL_FULL);
467 454
468 switch (frame->fmt->color) { 455 switch (frame->fmt->color) {
469 case S5P_FIMC_RGB565...S5P_FIMC_RGB888: 456 case FIMC_FMT_RGB565...FIMC_FMT_RGB888:
470 cfg |= S5P_MSCTRL_INFORMAT_RGB; 457 cfg |= FIMC_REG_MSCTRL_INFORMAT_RGB;
471 break; 458 break;
472 case S5P_FIMC_YCBCR420: 459 case FIMC_FMT_YCBCR420:
473 cfg |= S5P_MSCTRL_INFORMAT_YCBCR420; 460 cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR420;
474 461
475 if (frame->fmt->colplanes == 2) 462 if (frame->fmt->colplanes == 2)
476 cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE; 463 cfg |= ctx->in_order_2p | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
477 else 464 else
478 cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; 465 cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
479 466
480 break; 467 break;
481 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422: 468 case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
482 if (frame->fmt->colplanes == 1) { 469 if (frame->fmt->colplanes == 1) {
483 cfg |= ctx->in_order_1p 470 cfg |= ctx->in_order_1p
484 | S5P_MSCTRL_INFORMAT_YCBCR422_1P; 471 | FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P;
485 } else { 472 } else {
486 cfg |= S5P_MSCTRL_INFORMAT_YCBCR422; 473 cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR422;
487 474
488 if (frame->fmt->colplanes == 2) 475 if (frame->fmt->colplanes == 2)
489 cfg |= ctx->in_order_2p 476 cfg |= ctx->in_order_2p
490 | S5P_MSCTRL_C_INT_IN_2PLANE; 477 | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
491 else 478 else
492 cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; 479 cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
493 } 480 }
494 break; 481 break;
495 default: 482 default:
496 break; 483 break;
497 } 484 }
498 485
499 writel(cfg, dev->regs + S5P_MSCTRL); 486 writel(cfg, dev->regs + FIMC_REG_MSCTRL);
500 487
501 /* Input/output DMA linear/tiled mode. */ 488 /* Input/output DMA linear/tiled mode. */
502 cfg = readl(dev->regs + S5P_CIDMAPARAM); 489 cfg = readl(dev->regs + FIMC_REG_CIDMAPARAM);
503 cfg &= ~S5P_CIDMAPARAM_TILE_MASK; 490 cfg &= ~FIMC_REG_CIDMAPARAM_TILE_MASK;
504 491
505 if (tiled_fmt(ctx->s_frame.fmt)) 492 if (tiled_fmt(ctx->s_frame.fmt))
506 cfg |= S5P_CIDMAPARAM_R_64X32; 493 cfg |= FIMC_REG_CIDMAPARAM_R_64X32;
507 494
508 if (tiled_fmt(ctx->d_frame.fmt)) 495 if (tiled_fmt(ctx->d_frame.fmt))
509 cfg |= S5P_CIDMAPARAM_W_64X32; 496 cfg |= FIMC_REG_CIDMAPARAM_W_64X32;
510 497
511 writel(cfg, dev->regs + S5P_CIDMAPARAM); 498 writel(cfg, dev->regs + FIMC_REG_CIDMAPARAM);
512} 499}
513 500
514 501
@@ -516,40 +503,40 @@ void fimc_hw_set_input_path(struct fimc_ctx *ctx)
516{ 503{
517 struct fimc_dev *dev = ctx->fimc_dev; 504 struct fimc_dev *dev = ctx->fimc_dev;
518 505
519 u32 cfg = readl(dev->regs + S5P_MSCTRL); 506 u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
520 cfg &= ~S5P_MSCTRL_INPUT_MASK; 507 cfg &= ~FIMC_REG_MSCTRL_INPUT_MASK;
521 508
522 if (ctx->in_path == FIMC_DMA) 509 if (ctx->in_path == FIMC_IO_DMA)
523 cfg |= S5P_MSCTRL_INPUT_MEMORY; 510 cfg |= FIMC_REG_MSCTRL_INPUT_MEMORY;
524 else 511 else
525 cfg |= S5P_MSCTRL_INPUT_EXTCAM; 512 cfg |= FIMC_REG_MSCTRL_INPUT_EXTCAM;
526 513
527 writel(cfg, dev->regs + S5P_MSCTRL); 514 writel(cfg, dev->regs + FIMC_REG_MSCTRL);
528} 515}
529 516
530void fimc_hw_set_output_path(struct fimc_ctx *ctx) 517void fimc_hw_set_output_path(struct fimc_ctx *ctx)
531{ 518{
532 struct fimc_dev *dev = ctx->fimc_dev; 519 struct fimc_dev *dev = ctx->fimc_dev;
533 520
534 u32 cfg = readl(dev->regs + S5P_CISCCTRL); 521 u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
535 cfg &= ~S5P_CISCCTRL_LCDPATHEN_FIFO; 522 cfg &= ~FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
536 if (ctx->out_path == FIMC_LCDFIFO) 523 if (ctx->out_path == FIMC_IO_LCDFIFO)
537 cfg |= S5P_CISCCTRL_LCDPATHEN_FIFO; 524 cfg |= FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
538 writel(cfg, dev->regs + S5P_CISCCTRL); 525 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
539} 526}
540 527
541void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr) 528void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr)
542{ 529{
543 u32 cfg = readl(dev->regs + S5P_CIREAL_ISIZE); 530 u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE);
544 cfg |= S5P_CIREAL_ISIZE_ADDR_CH_DIS; 531 cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
545 writel(cfg, dev->regs + S5P_CIREAL_ISIZE); 532 writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
546 533
547 writel(paddr->y, dev->regs + S5P_CIIYSA(0)); 534 writel(paddr->y, dev->regs + FIMC_REG_CIIYSA(0));
548 writel(paddr->cb, dev->regs + S5P_CIICBSA(0)); 535 writel(paddr->cb, dev->regs + FIMC_REG_CIICBSA(0));
549 writel(paddr->cr, dev->regs + S5P_CIICRSA(0)); 536 writel(paddr->cr, dev->regs + FIMC_REG_CIICRSA(0));
550 537
551 cfg &= ~S5P_CIREAL_ISIZE_ADDR_CH_DIS; 538 cfg &= ~FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
552 writel(cfg, dev->regs + S5P_CIREAL_ISIZE); 539 writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
553} 540}
554 541
555void fimc_hw_set_output_addr(struct fimc_dev *dev, 542void fimc_hw_set_output_addr(struct fimc_dev *dev,
@@ -557,9 +544,9 @@ void fimc_hw_set_output_addr(struct fimc_dev *dev,
557{ 544{
558 int i = (index == -1) ? 0 : index; 545 int i = (index == -1) ? 0 : index;
559 do { 546 do {
560 writel(paddr->y, dev->regs + S5P_CIOYSA(i)); 547 writel(paddr->y, dev->regs + FIMC_REG_CIOYSA(i));
561 writel(paddr->cb, dev->regs + S5P_CIOCBSA(i)); 548 writel(paddr->cb, dev->regs + FIMC_REG_CIOCBSA(i));
562 writel(paddr->cr, dev->regs + S5P_CIOCRSA(i)); 549 writel(paddr->cr, dev->regs + FIMC_REG_CIOCRSA(i));
563 dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X", 550 dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
564 i, paddr->y, paddr->cb, paddr->cr); 551 i, paddr->y, paddr->cb, paddr->cr);
565 } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS); 552 } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS);
@@ -568,32 +555,45 @@ void fimc_hw_set_output_addr(struct fimc_dev *dev,
568int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, 555int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
569 struct s5p_fimc_isp_info *cam) 556 struct s5p_fimc_isp_info *cam)
570{ 557{
571 u32 cfg = readl(fimc->regs + S5P_CIGCTRL); 558 u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
572 559
573 cfg &= ~(S5P_CIGCTRL_INVPOLPCLK | S5P_CIGCTRL_INVPOLVSYNC | 560 cfg &= ~(FIMC_REG_CIGCTRL_INVPOLPCLK | FIMC_REG_CIGCTRL_INVPOLVSYNC |
574 S5P_CIGCTRL_INVPOLHREF | S5P_CIGCTRL_INVPOLHSYNC | 561 FIMC_REG_CIGCTRL_INVPOLHREF | FIMC_REG_CIGCTRL_INVPOLHSYNC |
575 S5P_CIGCTRL_INVPOLFIELD); 562 FIMC_REG_CIGCTRL_INVPOLFIELD);
576 563
577 if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) 564 if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
578 cfg |= S5P_CIGCTRL_INVPOLPCLK; 565 cfg |= FIMC_REG_CIGCTRL_INVPOLPCLK;
579 566
580 if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) 567 if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
581 cfg |= S5P_CIGCTRL_INVPOLVSYNC; 568 cfg |= FIMC_REG_CIGCTRL_INVPOLVSYNC;
582 569
583 if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) 570 if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
584 cfg |= S5P_CIGCTRL_INVPOLHREF; 571 cfg |= FIMC_REG_CIGCTRL_INVPOLHREF;
585 572
586 if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) 573 if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
587 cfg |= S5P_CIGCTRL_INVPOLHSYNC; 574 cfg |= FIMC_REG_CIGCTRL_INVPOLHSYNC;
588 575
589 if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW) 576 if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW)
590 cfg |= S5P_CIGCTRL_INVPOLFIELD; 577 cfg |= FIMC_REG_CIGCTRL_INVPOLFIELD;
591 578
592 writel(cfg, fimc->regs + S5P_CIGCTRL); 579 writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
593 580
594 return 0; 581 return 0;
595} 582}
596 583
584struct mbus_pixfmt_desc {
585 u32 pixelcode;
586 u32 cisrcfmt;
587 u16 bus_width;
588};
589
590static const struct mbus_pixfmt_desc pix_desc[] = {
591 { V4L2_MBUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 },
592 { V4L2_MBUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 },
593 { V4L2_MBUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 },
594 { V4L2_MBUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 },
595};
596
597int fimc_hw_set_camera_source(struct fimc_dev *fimc, 597int fimc_hw_set_camera_source(struct fimc_dev *fimc,
598 struct s5p_fimc_isp_info *cam) 598 struct s5p_fimc_isp_info *cam)
599{ 599{
@@ -602,18 +602,6 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
602 u32 bus_width; 602 u32 bus_width;
603 int i; 603 int i;
604 604
605 static const struct {
606 u32 pixelcode;
607 u32 cisrcfmt;
608 u16 bus_width;
609 } pix_desc[] = {
610 { V4L2_MBUS_FMT_YUYV8_2X8, S5P_CISRCFMT_ORDER422_YCBYCR, 8 },
611 { V4L2_MBUS_FMT_YVYU8_2X8, S5P_CISRCFMT_ORDER422_YCRYCB, 8 },
612 { V4L2_MBUS_FMT_VYUY8_2X8, S5P_CISRCFMT_ORDER422_CRYCBY, 8 },
613 { V4L2_MBUS_FMT_UYVY8_2X8, S5P_CISRCFMT_ORDER422_CBYCRY, 8 },
614 /* TODO: Add pixel codes for 16-bit bus width */
615 };
616
617 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) { 605 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) {
618 for (i = 0; i < ARRAY_SIZE(pix_desc); i++) { 606 for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
619 if (fimc->vid_cap.mf.code == pix_desc[i].pixelcode) { 607 if (fimc->vid_cap.mf.code == pix_desc[i].pixelcode) {
@@ -632,41 +620,37 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
632 620
633 if (cam->bus_type == FIMC_ITU_601) { 621 if (cam->bus_type == FIMC_ITU_601) {
634 if (bus_width == 8) 622 if (bus_width == 8)
635 cfg |= S5P_CISRCFMT_ITU601_8BIT; 623 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
636 else if (bus_width == 16) 624 else if (bus_width == 16)
637 cfg |= S5P_CISRCFMT_ITU601_16BIT; 625 cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
638 } /* else defaults to ITU-R BT.656 8-bit */ 626 } /* else defaults to ITU-R BT.656 8-bit */
639 } else if (cam->bus_type == FIMC_MIPI_CSI2) { 627 } else if (cam->bus_type == FIMC_MIPI_CSI2) {
640 if (fimc_fmt_is_jpeg(f->fmt->color)) 628 if (fimc_fmt_is_jpeg(f->fmt->color))
641 cfg |= S5P_CISRCFMT_ITU601_8BIT; 629 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
642 } 630 }
643 631
644 cfg |= S5P_CISRCFMT_HSIZE(f->o_width) | S5P_CISRCFMT_VSIZE(f->o_height); 632 cfg |= (f->o_width << 16) | f->o_height;
645 writel(cfg, fimc->regs + S5P_CISRCFMT); 633 writel(cfg, fimc->regs + FIMC_REG_CISRCFMT);
646 return 0; 634 return 0;
647} 635}
648 636
649 637void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
650int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
651{ 638{
652 u32 hoff2, voff2; 639 u32 hoff2, voff2;
653 640
654 u32 cfg = readl(fimc->regs + S5P_CIWDOFST); 641 u32 cfg = readl(fimc->regs + FIMC_REG_CIWDOFST);
655 642
656 cfg &= ~(S5P_CIWDOFST_HOROFF_MASK | S5P_CIWDOFST_VEROFF_MASK); 643 cfg &= ~(FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK);
657 cfg |= S5P_CIWDOFST_OFF_EN | 644 cfg |= FIMC_REG_CIWDOFST_OFF_EN |
658 S5P_CIWDOFST_HOROFF(f->offs_h) | 645 (f->offs_h << 16) | f->offs_v;
659 S5P_CIWDOFST_VEROFF(f->offs_v);
660 646
661 writel(cfg, fimc->regs + S5P_CIWDOFST); 647 writel(cfg, fimc->regs + FIMC_REG_CIWDOFST);
662 648
663 /* See CIWDOFSTn register description in the datasheet for details. */ 649 /* See CIWDOFSTn register description in the datasheet for details. */
664 hoff2 = f->o_width - f->width - f->offs_h; 650 hoff2 = f->o_width - f->width - f->offs_h;
665 voff2 = f->o_height - f->height - f->offs_v; 651 voff2 = f->o_height - f->height - f->offs_v;
666 cfg = S5P_CIWDOFST2_HOROFF(hoff2) | S5P_CIWDOFST2_VEROFF(voff2); 652 cfg = (hoff2 << 16) | voff2;
667 653 writel(cfg, fimc->regs + FIMC_REG_CIWDOFST2);
668 writel(cfg, fimc->regs + S5P_CIWDOFST2);
669 return 0;
670} 654}
671 655
672int fimc_hw_set_camera_type(struct fimc_dev *fimc, 656int fimc_hw_set_camera_type(struct fimc_dev *fimc,
@@ -674,28 +658,29 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
674{ 658{
675 u32 cfg, tmp; 659 u32 cfg, tmp;
676 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 660 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
661 u32 csis_data_alignment = 32;
677 662
678 cfg = readl(fimc->regs + S5P_CIGCTRL); 663 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
679 664
680 /* Select ITU B interface, disable Writeback path and test pattern. */ 665 /* Select ITU B interface, disable Writeback path and test pattern. */
681 cfg &= ~(S5P_CIGCTRL_TESTPAT_MASK | S5P_CIGCTRL_SELCAM_ITU_A | 666 cfg &= ~(FIMC_REG_CIGCTRL_TESTPAT_MASK | FIMC_REG_CIGCTRL_SELCAM_ITU_A |
682 S5P_CIGCTRL_SELCAM_MIPI | S5P_CIGCTRL_CAMIF_SELWB | 667 FIMC_REG_CIGCTRL_SELCAM_MIPI | FIMC_REG_CIGCTRL_CAMIF_SELWB |
683 S5P_CIGCTRL_SELCAM_MIPI_A | S5P_CIGCTRL_CAM_JPEG); 668 FIMC_REG_CIGCTRL_SELCAM_MIPI_A | FIMC_REG_CIGCTRL_CAM_JPEG);
684 669
685 if (cam->bus_type == FIMC_MIPI_CSI2) { 670 if (cam->bus_type == FIMC_MIPI_CSI2) {
686 cfg |= S5P_CIGCTRL_SELCAM_MIPI; 671 cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI;
687 672
688 if (cam->mux_id == 0) 673 if (cam->mux_id == 0)
689 cfg |= S5P_CIGCTRL_SELCAM_MIPI_A; 674 cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI_A;
690 675
691 /* TODO: add remaining supported formats. */ 676 /* TODO: add remaining supported formats. */
692 switch (vid_cap->mf.code) { 677 switch (vid_cap->mf.code) {
693 case V4L2_MBUS_FMT_VYUY8_2X8: 678 case V4L2_MBUS_FMT_VYUY8_2X8:
694 tmp = S5P_CSIIMGFMT_YCBCR422_8BIT; 679 tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
695 break; 680 break;
696 case V4L2_MBUS_FMT_JPEG_1X8: 681 case V4L2_MBUS_FMT_JPEG_1X8:
697 tmp = S5P_CSIIMGFMT_USER(1); 682 tmp = FIMC_REG_CSIIMGFMT_USER(1);
698 cfg |= S5P_CIGCTRL_CAM_JPEG; 683 cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
699 break; 684 break;
700 default: 685 default:
701 v4l2_err(fimc->vid_cap.vfd, 686 v4l2_err(fimc->vid_cap.vfd,
@@ -703,21 +688,86 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
703 vid_cap->mf.code); 688 vid_cap->mf.code);
704 return -EINVAL; 689 return -EINVAL;
705 } 690 }
706 tmp |= (cam->csi_data_align == 32) << 8; 691 tmp |= (csis_data_alignment == 32) << 8;
707 692
708 writel(tmp, fimc->regs + S5P_CSIIMGFMT); 693 writel(tmp, fimc->regs + FIMC_REG_CSIIMGFMT);
709 694
710 } else if (cam->bus_type == FIMC_ITU_601 || 695 } else if (cam->bus_type == FIMC_ITU_601 ||
711 cam->bus_type == FIMC_ITU_656) { 696 cam->bus_type == FIMC_ITU_656) {
712 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */ 697 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
713 cfg |= S5P_CIGCTRL_SELCAM_ITU_A; 698 cfg |= FIMC_REG_CIGCTRL_SELCAM_ITU_A;
714 } else if (cam->bus_type == FIMC_LCD_WB) { 699 } else if (cam->bus_type == FIMC_LCD_WB) {
715 cfg |= S5P_CIGCTRL_CAMIF_SELWB; 700 cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
716 } else { 701 } else {
717 err("invalid camera bus type selected\n"); 702 err("invalid camera bus type selected\n");
718 return -EINVAL; 703 return -EINVAL;
719 } 704 }
720 writel(cfg, fimc->regs + S5P_CIGCTRL); 705 writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
721 706
722 return 0; 707 return 0;
723} 708}
709
710void fimc_hw_clear_irq(struct fimc_dev *dev)
711{
712 u32 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
713 cfg |= FIMC_REG_CIGCTRL_IRQ_CLR;
714 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
715}
716
717void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
718{
719 u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
720 if (on)
721 cfg |= FIMC_REG_CISCCTRL_SCALERSTART;
722 else
723 cfg &= ~FIMC_REG_CISCCTRL_SCALERSTART;
724 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
725}
726
727void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
728{
729 u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
730 if (on)
731 cfg |= FIMC_REG_MSCTRL_ENVID;
732 else
733 cfg &= ~FIMC_REG_MSCTRL_ENVID;
734 writel(cfg, dev->regs + FIMC_REG_MSCTRL);
735}
736
737void fimc_hw_dis_capture(struct fimc_dev *dev)
738{
739 u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
740 cfg &= ~(FIMC_REG_CIIMGCPT_IMGCPTEN | FIMC_REG_CIIMGCPT_IMGCPTEN_SC);
741 writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
742}
743
744/* Return an index to the buffer actually being written. */
745u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
746{
747 u32 reg;
748
749 if (dev->variant->has_cistatus2) {
750 reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3F;
751 return reg > 0 ? --reg : reg;
752 }
753
754 reg = readl(dev->regs + FIMC_REG_CISTATUS);
755
756 return (reg & FIMC_REG_CISTATUS_FRAMECNT_MASK) >>
757 FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
758}
759
760/* Locking: the caller holds fimc->slock */
761void fimc_activate_capture(struct fimc_ctx *ctx)
762{
763 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
764 fimc_hw_en_capture(ctx);
765}
766
767void fimc_deactivate_capture(struct fimc_dev *fimc)
768{
769 fimc_hw_en_lastirq(fimc, true);
770 fimc_hw_dis_capture(fimc);
771 fimc_hw_enable_scaler(fimc, false);
772 fimc_hw_en_lastirq(fimc, false);
773}
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.h b/drivers/media/video/s5p-fimc/fimc-reg.h
new file mode 100644
index 000000000000..579ac8ac03de
--- /dev/null
+++ b/drivers/media/video/s5p-fimc/fimc-reg.h
@@ -0,0 +1,326 @@
1/*
2 * Samsung camera host interface (FIMC) registers definition
3 *
4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef FIMC_REG_H_
12#define FIMC_REG_H_
13
14#include "fimc-core.h"
15
16/* Input source format */
17#define FIMC_REG_CISRCFMT 0x00
18#define FIMC_REG_CISRCFMT_ITU601_8BIT (1 << 31)
19#define FIMC_REG_CISRCFMT_ITU601_16BIT (1 << 29)
20#define FIMC_REG_CISRCFMT_ORDER422_YCBYCR (0 << 14)
21#define FIMC_REG_CISRCFMT_ORDER422_YCRYCB (1 << 14)
22#define FIMC_REG_CISRCFMT_ORDER422_CBYCRY (2 << 14)
23#define FIMC_REG_CISRCFMT_ORDER422_CRYCBY (3 << 14)
24
25/* Window offset */
26#define FIMC_REG_CIWDOFST 0x04
27#define FIMC_REG_CIWDOFST_OFF_EN (1 << 31)
28#define FIMC_REG_CIWDOFST_CLROVFIY (1 << 30)
29#define FIMC_REG_CIWDOFST_CLROVRLB (1 << 29)
30#define FIMC_REG_CIWDOFST_HOROFF_MASK (0x7ff << 16)
31#define FIMC_REG_CIWDOFST_CLROVFICB (1 << 15)
32#define FIMC_REG_CIWDOFST_CLROVFICR (1 << 14)
33#define FIMC_REG_CIWDOFST_VEROFF_MASK (0xfff << 0)
34
35/* Global control */
36#define FIMC_REG_CIGCTRL 0x08
37#define FIMC_REG_CIGCTRL_SWRST (1 << 31)
38#define FIMC_REG_CIGCTRL_CAMRST_A (1 << 30)
39#define FIMC_REG_CIGCTRL_SELCAM_ITU_A (1 << 29)
40#define FIMC_REG_CIGCTRL_TESTPAT_NORMAL (0 << 27)
41#define FIMC_REG_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27)
42#define FIMC_REG_CIGCTRL_TESTPAT_HOR_INC (2 << 27)
43#define FIMC_REG_CIGCTRL_TESTPAT_VER_INC (3 << 27)
44#define FIMC_REG_CIGCTRL_TESTPAT_MASK (3 << 27)
45#define FIMC_REG_CIGCTRL_TESTPAT_SHIFT 27
46#define FIMC_REG_CIGCTRL_INVPOLPCLK (1 << 26)
47#define FIMC_REG_CIGCTRL_INVPOLVSYNC (1 << 25)
48#define FIMC_REG_CIGCTRL_INVPOLHREF (1 << 24)
49#define FIMC_REG_CIGCTRL_IRQ_OVFEN (1 << 22)
50#define FIMC_REG_CIGCTRL_HREF_MASK (1 << 21)
51#define FIMC_REG_CIGCTRL_IRQ_LEVEL (1 << 20)
52#define FIMC_REG_CIGCTRL_IRQ_CLR (1 << 19)
53#define FIMC_REG_CIGCTRL_IRQ_ENABLE (1 << 16)
54#define FIMC_REG_CIGCTRL_SHDW_DISABLE (1 << 12)
55#define FIMC_REG_CIGCTRL_CAM_JPEG (1 << 8)
56#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A (1 << 7)
57#define FIMC_REG_CIGCTRL_CAMIF_SELWB (1 << 6)
58/* 0 - ITU601; 1 - ITU709 */
59#define FIMC_REG_CIGCTRL_CSC_ITU601_709 (1 << 5)
60#define FIMC_REG_CIGCTRL_INVPOLHSYNC (1 << 4)
61#define FIMC_REG_CIGCTRL_SELCAM_MIPI (1 << 3)
62#define FIMC_REG_CIGCTRL_INVPOLFIELD (1 << 1)
63#define FIMC_REG_CIGCTRL_INTERLACE (1 << 0)
64
65/* Window offset 2 */
66#define FIMC_REG_CIWDOFST2 0x14
67#define FIMC_REG_CIWDOFST2_HOROFF_MASK (0xfff << 16)
68#define FIMC_REG_CIWDOFST2_VEROFF_MASK (0xfff << 0)
69
70/* Output DMA Y/Cb/Cr plane start addresses */
71#define FIMC_REG_CIOYSA(n) (0x18 + (n) * 4)
72#define FIMC_REG_CIOCBSA(n) (0x28 + (n) * 4)
73#define FIMC_REG_CIOCRSA(n) (0x38 + (n) * 4)
74
75/* Target image format */
76#define FIMC_REG_CITRGFMT 0x48
77#define FIMC_REG_CITRGFMT_INROT90 (1 << 31)
78#define FIMC_REG_CITRGFMT_YCBCR420 (0 << 29)
79#define FIMC_REG_CITRGFMT_YCBCR422 (1 << 29)
80#define FIMC_REG_CITRGFMT_YCBCR422_1P (2 << 29)
81#define FIMC_REG_CITRGFMT_RGB (3 << 29)
82#define FIMC_REG_CITRGFMT_FMT_MASK (3 << 29)
83#define FIMC_REG_CITRGFMT_HSIZE_MASK (0xfff << 16)
84#define FIMC_REG_CITRGFMT_FLIP_SHIFT 14
85#define FIMC_REG_CITRGFMT_FLIP_NORMAL (0 << 14)
86#define FIMC_REG_CITRGFMT_FLIP_X_MIRROR (1 << 14)
87#define FIMC_REG_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
88#define FIMC_REG_CITRGFMT_FLIP_180 (3 << 14)
89#define FIMC_REG_CITRGFMT_FLIP_MASK (3 << 14)
90#define FIMC_REG_CITRGFMT_OUTROT90 (1 << 13)
91#define FIMC_REG_CITRGFMT_VSIZE_MASK (0xfff << 0)
92
93/* Output DMA control */
94#define FIMC_REG_CIOCTRL 0x4c
95#define FIMC_REG_CIOCTRL_ORDER422_MASK (3 << 0)
96#define FIMC_REG_CIOCTRL_ORDER422_CRYCBY (0 << 0)
97#define FIMC_REG_CIOCTRL_ORDER422_CBYCRY (1 << 0)
98#define FIMC_REG_CIOCTRL_ORDER422_YCRYCB (2 << 0)
99#define FIMC_REG_CIOCTRL_ORDER422_YCBYCR (3 << 0)
100#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
101#define FIMC_REG_CIOCTRL_YCBCR_3PLANE (0 << 3)
102#define FIMC_REG_CIOCTRL_YCBCR_2PLANE (1 << 3)
103#define FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
104#define FIMC_REG_CIOCTRL_ALPHA_OUT_MASK (0xff << 4)
105#define FIMC_REG_CIOCTRL_RGB16FMT_MASK (3 << 16)
106#define FIMC_REG_CIOCTRL_RGB565 (0 << 16)
107#define FIMC_REG_CIOCTRL_ARGB1555 (1 << 16)
108#define FIMC_REG_CIOCTRL_ARGB4444 (2 << 16)
109#define FIMC_REG_CIOCTRL_ORDER2P_SHIFT 24
110#define FIMC_REG_CIOCTRL_ORDER2P_MASK (3 << 24)
111#define FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB (0 << 24)
112
113/* Pre-scaler control 1 */
114#define FIMC_REG_CISCPRERATIO 0x50
115
116#define FIMC_REG_CISCPREDST 0x54
117
118/* Main scaler control */
119#define FIMC_REG_CISCCTRL 0x58
120#define FIMC_REG_CISCCTRL_SCALERBYPASS (1 << 31)
121#define FIMC_REG_CISCCTRL_SCALEUP_H (1 << 30)
122#define FIMC_REG_CISCCTRL_SCALEUP_V (1 << 29)
123#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE (1 << 28)
124#define FIMC_REG_CISCCTRL_CSCY2R_WIDE (1 << 27)
125#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
126#define FIMC_REG_CISCCTRL_INTERLACE (1 << 25)
127#define FIMC_REG_CISCCTRL_SCALERSTART (1 << 15)
128#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
129#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
130#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
131#define FIMC_REG_CISCCTRL_INRGB_FMT_MASK (3 << 13)
132#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
133#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
134#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
135#define FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
136#define FIMC_REG_CISCCTRL_RGB_EXT (1 << 10)
137#define FIMC_REG_CISCCTRL_ONE2ONE (1 << 9)
138#define FIMC_REG_CISCCTRL_MHRATIO(x) ((x) << 16)
139#define FIMC_REG_CISCCTRL_MVRATIO(x) ((x) << 0)
140#define FIMC_REG_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
141#define FIMC_REG_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
142#define FIMC_REG_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
143#define FIMC_REG_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
144
145/* Target area */
146#define FIMC_REG_CITAREA 0x5c
147#define FIMC_REG_CITAREA_MASK 0x0fffffff
148
149/* General status */
150#define FIMC_REG_CISTATUS 0x64
151#define FIMC_REG_CISTATUS_OVFIY (1 << 31)
152#define FIMC_REG_CISTATUS_OVFICB (1 << 30)
153#define FIMC_REG_CISTATUS_OVFICR (1 << 29)
154#define FIMC_REG_CISTATUS_VSYNC (1 << 28)
155#define FIMC_REG_CISTATUS_FRAMECNT_MASK (3 << 26)
156#define FIMC_REG_CISTATUS_FRAMECNT_SHIFT 26
157#define FIMC_REG_CISTATUS_WINOFF_EN (1 << 25)
158#define FIMC_REG_CISTATUS_IMGCPT_EN (1 << 22)
159#define FIMC_REG_CISTATUS_IMGCPT_SCEN (1 << 21)
160#define FIMC_REG_CISTATUS_VSYNC_A (1 << 20)
161#define FIMC_REG_CISTATUS_VSYNC_B (1 << 19)
162#define FIMC_REG_CISTATUS_OVRLB (1 << 18)
163#define FIMC_REG_CISTATUS_FRAME_END (1 << 17)
164#define FIMC_REG_CISTATUS_LASTCAPT_END (1 << 16)
165#define FIMC_REG_CISTATUS_VVALID_A (1 << 15)
166#define FIMC_REG_CISTATUS_VVALID_B (1 << 14)
167
168/* Indexes to the last and the currently processed buffer. */
169#define FIMC_REG_CISTATUS2 0x68
170
171/* Image capture control */
172#define FIMC_REG_CIIMGCPT 0xc0
173#define FIMC_REG_CIIMGCPT_IMGCPTEN (1 << 31)
174#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC (1 << 30)
175#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
176#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
177
178/* Frame capture sequence */
179#define FIMC_REG_CICPTSEQ 0xc4
180
181/* Image effect */
182#define FIMC_REG_CIIMGEFF 0xd0
183#define FIMC_REG_CIIMGEFF_IE_ENABLE (1 << 30)
184#define FIMC_REG_CIIMGEFF_IE_SC_BEFORE (0 << 29)
185#define FIMC_REG_CIIMGEFF_IE_SC_AFTER (1 << 29)
186#define FIMC_REG_CIIMGEFF_FIN_BYPASS (0 << 26)
187#define FIMC_REG_CIIMGEFF_FIN_ARBITRARY (1 << 26)
188#define FIMC_REG_CIIMGEFF_FIN_NEGATIVE (2 << 26)
189#define FIMC_REG_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
190#define FIMC_REG_CIIMGEFF_FIN_EMBOSSING (4 << 26)
191#define FIMC_REG_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
192#define FIMC_REG_CIIMGEFF_FIN_MASK (7 << 26)
193#define FIMC_REG_CIIMGEFF_PAT_CBCR_MASK ((0xff << 13) | 0xff)
194
195/* Input DMA Y/Cb/Cr plane start address 0/1 */
196#define FIMC_REG_CIIYSA(n) (0xd4 + (n) * 0x70)
197#define FIMC_REG_CIICBSA(n) (0xd8 + (n) * 0x70)
198#define FIMC_REG_CIICRSA(n) (0xdc + (n) * 0x70)
199
200/* Real input DMA image size */
201#define FIMC_REG_CIREAL_ISIZE 0xf8
202#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN (1 << 31)
203#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS (1 << 30)
204
205/* Input DMA control */
206#define FIMC_REG_MSCTRL 0xfc
207#define FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK (0xf << 24)
208#define FIMC_REG_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
209#define FIMC_REG_MSCTRL_2P_IN_ORDER_SHIFT 16
210#define FIMC_REG_MSCTRL_C_INT_IN_3PLANE (0 << 15)
211#define FIMC_REG_MSCTRL_C_INT_IN_2PLANE (1 << 15)
212#define FIMC_REG_MSCTRL_C_INT_IN_MASK (1 << 15)
213#define FIMC_REG_MSCTRL_FLIP_SHIFT 13
214#define FIMC_REG_MSCTRL_FLIP_MASK (3 << 13)
215#define FIMC_REG_MSCTRL_FLIP_NORMAL (0 << 13)
216#define FIMC_REG_MSCTRL_FLIP_X_MIRROR (1 << 13)
217#define FIMC_REG_MSCTRL_FLIP_Y_MIRROR (2 << 13)
218#define FIMC_REG_MSCTRL_FLIP_180 (3 << 13)
219#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL (1 << 12)
220#define FIMC_REG_MSCTRL_ORDER422_SHIFT 4
221#define FIMC_REG_MSCTRL_ORDER422_YCBYCR (0 << 4)
222#define FIMC_REG_MSCTRL_ORDER422_CBYCRY (1 << 4)
223#define FIMC_REG_MSCTRL_ORDER422_YCRYCB (2 << 4)
224#define FIMC_REG_MSCTRL_ORDER422_CRYCBY (3 << 4)
225#define FIMC_REG_MSCTRL_ORDER422_MASK (3 << 4)
226#define FIMC_REG_MSCTRL_INPUT_EXTCAM (0 << 3)
227#define FIMC_REG_MSCTRL_INPUT_MEMORY (1 << 3)
228#define FIMC_REG_MSCTRL_INPUT_MASK (1 << 3)
229#define FIMC_REG_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
230#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
231#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1)
232#define FIMC_REG_MSCTRL_INFORMAT_RGB (3 << 1)
233#define FIMC_REG_MSCTRL_INFORMAT_MASK (3 << 1)
234#define FIMC_REG_MSCTRL_ENVID (1 << 0)
235#define FIMC_REG_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
236
237/* Output DMA Y/Cb/Cr offset */
238#define FIMC_REG_CIOYOFF 0x168
239#define FIMC_REG_CIOCBOFF 0x16c
240#define FIMC_REG_CIOCROFF 0x170
241
242/* Input DMA Y/Cb/Cr offset */
243#define FIMC_REG_CIIYOFF 0x174
244#define FIMC_REG_CIICBOFF 0x178
245#define FIMC_REG_CIICROFF 0x17c
246
247/* Input DMA original image size */
248#define FIMC_REG_ORGISIZE 0x180
249
250/* Output DMA original image size */
251#define FIMC_REG_ORGOSIZE 0x184
252
253/* Real output DMA image size (extension register) */
254#define FIMC_REG_CIEXTEN 0x188
255#define FIMC_REG_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
256#define FIMC_REG_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
257#define FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
258#define FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK 0x3f
259
260#define FIMC_REG_CIDMAPARAM 0x18c
261#define FIMC_REG_CIDMAPARAM_R_LINEAR (0 << 29)
262#define FIMC_REG_CIDMAPARAM_R_64X32 (3 << 29)
263#define FIMC_REG_CIDMAPARAM_W_LINEAR (0 << 13)
264#define FIMC_REG_CIDMAPARAM_W_64X32 (3 << 13)
265#define FIMC_REG_CIDMAPARAM_TILE_MASK ((3 << 29) | (3 << 13))
266
267/* MIPI CSI image format */
268#define FIMC_REG_CSIIMGFMT 0x194
269#define FIMC_REG_CSIIMGFMT_YCBCR422_8BIT 0x1e
270#define FIMC_REG_CSIIMGFMT_RAW8 0x2a
271#define FIMC_REG_CSIIMGFMT_RAW10 0x2b
272#define FIMC_REG_CSIIMGFMT_RAW12 0x2c
273/* User defined formats. x = 0...16. */
274#define FIMC_REG_CSIIMGFMT_USER(x) (0x30 + x - 1)
275
276/* Output frame buffer sequence mask */
277#define FIMC_REG_CIFCNTSEQ 0x1fc
278
279/*
280 * Function declarations
281 */
282void fimc_hw_reset(struct fimc_dev *fimc);
283void fimc_hw_set_rotation(struct fimc_ctx *ctx);
284void fimc_hw_set_target_format(struct fimc_ctx *ctx);
285void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
286void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
287void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
288void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
289void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
290void fimc_hw_en_capture(struct fimc_ctx *ctx);
291void fimc_hw_set_effect(struct fimc_ctx *ctx);
292void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
293void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
294void fimc_hw_set_input_path(struct fimc_ctx *ctx);
295void fimc_hw_set_output_path(struct fimc_ctx *ctx);
296void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
297void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
298 int index);
299int fimc_hw_set_camera_source(struct fimc_dev *fimc,
300 struct s5p_fimc_isp_info *cam);
301void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
302int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
303 struct s5p_fimc_isp_info *cam);
304int fimc_hw_set_camera_type(struct fimc_dev *fimc,
305 struct s5p_fimc_isp_info *cam);
306void fimc_hw_clear_irq(struct fimc_dev *dev);
307void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
308void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
309void fimc_hw_dis_capture(struct fimc_dev *dev);
310u32 fimc_hw_get_frame_index(struct fimc_dev *dev);
311void fimc_activate_capture(struct fimc_ctx *ctx);
312void fimc_deactivate_capture(struct fimc_dev *fimc);
313
314/**
315 * fimc_hw_set_dma_seq - configure output DMA buffer sequence
316 * @mask: bitmask for the DMA output buffer registers, set to 0 to skip buffer
317 * This function masks output DMA ring buffers, it allows to select which of
318 * the 32 available output buffer address registers will be used by the DMA
319 * engine.
320 */
321static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
322{
323 writel(mask, dev->regs + FIMC_REG_CIFCNTSEQ);
324}
325
326#endif /* FIMC_REG_H_ */
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c
index f44f690397f7..2f73d9e3d0b7 100644
--- a/drivers/media/video/s5p-fimc/mipi-csis.c
+++ b/drivers/media/video/s5p-fimc/mipi-csis.c
@@ -127,20 +127,24 @@ struct csis_state {
127 * multiple of 2^pix_width_alignment 127 * multiple of 2^pix_width_alignment
128 * @code: corresponding media bus code 128 * @code: corresponding media bus code
129 * @fmt_reg: S5PCSIS_CONFIG register value 129 * @fmt_reg: S5PCSIS_CONFIG register value
130 * @data_alignment: MIPI-CSI data alignment in bits
130 */ 131 */
131struct csis_pix_format { 132struct csis_pix_format {
132 unsigned int pix_width_alignment; 133 unsigned int pix_width_alignment;
133 enum v4l2_mbus_pixelcode code; 134 enum v4l2_mbus_pixelcode code;
134 u32 fmt_reg; 135 u32 fmt_reg;
136 u8 data_alignment;
135}; 137};
136 138
137static const struct csis_pix_format s5pcsis_formats[] = { 139static const struct csis_pix_format s5pcsis_formats[] = {
138 { 140 {
139 .code = V4L2_MBUS_FMT_VYUY8_2X8, 141 .code = V4L2_MBUS_FMT_VYUY8_2X8,
140 .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT, 142 .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
143 .data_alignment = 32,
141 }, { 144 }, {
142 .code = V4L2_MBUS_FMT_JPEG_1X8, 145 .code = V4L2_MBUS_FMT_JPEG_1X8,
143 .fmt_reg = S5PCSIS_CFG_FMT_USER(1), 146 .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
147 .data_alignment = 32,
144 }, 148 },
145}; 149};
146 150
@@ -239,7 +243,7 @@ static void s5pcsis_set_params(struct csis_state *state)
239 s5pcsis_set_hsync_settle(state, pdata->hs_settle); 243 s5pcsis_set_hsync_settle(state, pdata->hs_settle);
240 244
241 val = s5pcsis_read(state, S5PCSIS_CTRL); 245 val = s5pcsis_read(state, S5PCSIS_CTRL);
242 if (pdata->alignment == 32) 246 if (state->csis_fmt->data_alignment == 32)
243 val |= S5PCSIS_CTRL_ALIGN_32BIT; 247 val |= S5PCSIS_CTRL_ALIGN_32BIT;
244 else /* 24-bits */ 248 else /* 24-bits */
245 val &= ~S5PCSIS_CTRL_ALIGN_32BIT; 249 val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
@@ -711,19 +715,8 @@ static struct platform_driver s5pcsis_driver = {
711 }, 715 },
712}; 716};
713 717
714static int __init s5pcsis_init(void) 718module_platform_driver(s5pcsis_driver);
715{
716 return platform_driver_probe(&s5pcsis_driver, s5pcsis_probe);
717}
718
719static void __exit s5pcsis_exit(void)
720{
721 platform_driver_unregister(&s5pcsis_driver);
722}
723
724module_init(s5pcsis_init);
725module_exit(s5pcsis_exit);
726 719
727MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 720MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
728MODULE_DESCRIPTION("S5P/EXYNOS4 MIPI CSI receiver driver"); 721MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
729MODULE_LICENSE("GPL"); 722MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h
deleted file mode 100644
index c7a5bc51d571..000000000000
--- a/drivers/media/video/s5p-fimc/regs-fimc.h
+++ /dev/null
@@ -1,301 +0,0 @@
1/*
2 * Register definition file for Samsung Camera Interface (FIMC) driver
3 *
4 * Copyright (c) 2010 Samsung Electronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef REGS_FIMC_H_
12#define REGS_FIMC_H_
13
14/* Input source format */
15#define S5P_CISRCFMT 0x00
16#define S5P_CISRCFMT_ITU601_8BIT (1 << 31)
17#define S5P_CISRCFMT_ITU601_16BIT (1 << 29)
18#define S5P_CISRCFMT_ORDER422_YCBYCR (0 << 14)
19#define S5P_CISRCFMT_ORDER422_YCRYCB (1 << 14)
20#define S5P_CISRCFMT_ORDER422_CBYCRY (2 << 14)
21#define S5P_CISRCFMT_ORDER422_CRYCBY (3 << 14)
22#define S5P_CISRCFMT_HSIZE(x) ((x) << 16)
23#define S5P_CISRCFMT_VSIZE(x) ((x) << 0)
24
25/* Window offset */
26#define S5P_CIWDOFST 0x04
27#define S5P_CIWDOFST_OFF_EN (1 << 31)
28#define S5P_CIWDOFST_CLROVFIY (1 << 30)
29#define S5P_CIWDOFST_CLROVRLB (1 << 29)
30#define S5P_CIWDOFST_HOROFF_MASK (0x7ff << 16)
31#define S5P_CIWDOFST_CLROVFICB (1 << 15)
32#define S5P_CIWDOFST_CLROVFICR (1 << 14)
33#define S5P_CIWDOFST_HOROFF(x) ((x) << 16)
34#define S5P_CIWDOFST_VEROFF(x) ((x) << 0)
35#define S5P_CIWDOFST_VEROFF_MASK (0xfff << 0)
36
37/* Global control */
38#define S5P_CIGCTRL 0x08
39#define S5P_CIGCTRL_SWRST (1 << 31)
40#define S5P_CIGCTRL_CAMRST_A (1 << 30)
41#define S5P_CIGCTRL_SELCAM_ITU_A (1 << 29)
42#define S5P_CIGCTRL_TESTPAT_NORMAL (0 << 27)
43#define S5P_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27)
44#define S5P_CIGCTRL_TESTPAT_HOR_INC (2 << 27)
45#define S5P_CIGCTRL_TESTPAT_VER_INC (3 << 27)
46#define S5P_CIGCTRL_TESTPAT_MASK (3 << 27)
47#define S5P_CIGCTRL_TESTPAT_SHIFT (27)
48#define S5P_CIGCTRL_INVPOLPCLK (1 << 26)
49#define S5P_CIGCTRL_INVPOLVSYNC (1 << 25)
50#define S5P_CIGCTRL_INVPOLHREF (1 << 24)
51#define S5P_CIGCTRL_IRQ_OVFEN (1 << 22)
52#define S5P_CIGCTRL_HREF_MASK (1 << 21)
53#define S5P_CIGCTRL_IRQ_LEVEL (1 << 20)
54#define S5P_CIGCTRL_IRQ_CLR (1 << 19)
55#define S5P_CIGCTRL_IRQ_ENABLE (1 << 16)
56#define S5P_CIGCTRL_SHDW_DISABLE (1 << 12)
57#define S5P_CIGCTRL_CAM_JPEG (1 << 8)
58#define S5P_CIGCTRL_SELCAM_MIPI_A (1 << 7)
59#define S5P_CIGCTRL_CAMIF_SELWB (1 << 6)
60/* 0 - ITU601; 1 - ITU709 */
61#define S5P_CIGCTRL_CSC_ITU601_709 (1 << 5)
62#define S5P_CIGCTRL_INVPOLHSYNC (1 << 4)
63#define S5P_CIGCTRL_SELCAM_MIPI (1 << 3)
64#define S5P_CIGCTRL_INVPOLFIELD (1 << 1)
65#define S5P_CIGCTRL_INTERLACE (1 << 0)
66
67/* Window offset 2 */
68#define S5P_CIWDOFST2 0x14
69#define S5P_CIWDOFST2_HOROFF_MASK (0xfff << 16)
70#define S5P_CIWDOFST2_VEROFF_MASK (0xfff << 0)
71#define S5P_CIWDOFST2_HOROFF(x) ((x) << 16)
72#define S5P_CIWDOFST2_VEROFF(x) ((x) << 0)
73
74/* Output DMA Y/Cb/Cr plane start addresses */
75#define S5P_CIOYSA(n) (0x18 + (n) * 4)
76#define S5P_CIOCBSA(n) (0x28 + (n) * 4)
77#define S5P_CIOCRSA(n) (0x38 + (n) * 4)
78
79/* Target image format */
80#define S5P_CITRGFMT 0x48
81#define S5P_CITRGFMT_INROT90 (1 << 31)
82#define S5P_CITRGFMT_YCBCR420 (0 << 29)
83#define S5P_CITRGFMT_YCBCR422 (1 << 29)
84#define S5P_CITRGFMT_YCBCR422_1P (2 << 29)
85#define S5P_CITRGFMT_RGB (3 << 29)
86#define S5P_CITRGFMT_FMT_MASK (3 << 29)
87#define S5P_CITRGFMT_HSIZE_MASK (0xfff << 16)
88#define S5P_CITRGFMT_FLIP_SHIFT (14)
89#define S5P_CITRGFMT_FLIP_NORMAL (0 << 14)
90#define S5P_CITRGFMT_FLIP_X_MIRROR (1 << 14)
91#define S5P_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
92#define S5P_CITRGFMT_FLIP_180 (3 << 14)
93#define S5P_CITRGFMT_FLIP_MASK (3 << 14)
94#define S5P_CITRGFMT_OUTROT90 (1 << 13)
95#define S5P_CITRGFMT_VSIZE_MASK (0xfff << 0)
96#define S5P_CITRGFMT_HSIZE(x) ((x) << 16)
97#define S5P_CITRGFMT_VSIZE(x) ((x) << 0)
98
99/* Output DMA control */
100#define S5P_CIOCTRL 0x4c
101#define S5P_CIOCTRL_ORDER422_MASK (3 << 0)
102#define S5P_CIOCTRL_ORDER422_CRYCBY (0 << 0)
103#define S5P_CIOCTRL_ORDER422_CBYCRY (1 << 0)
104#define S5P_CIOCTRL_ORDER422_YCRYCB (2 << 0)
105#define S5P_CIOCTRL_ORDER422_YCBYCR (3 << 0)
106#define S5P_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
107#define S5P_CIOCTRL_YCBCR_3PLANE (0 << 3)
108#define S5P_CIOCTRL_YCBCR_2PLANE (1 << 3)
109#define S5P_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
110#define S5P_CIOCTRL_ALPHA_OUT_MASK (0xff << 4)
111#define S5P_CIOCTRL_RGB16FMT_MASK (3 << 16)
112#define S5P_CIOCTRL_RGB565 (0 << 16)
113#define S5P_CIOCTRL_ARGB1555 (1 << 16)
114#define S5P_CIOCTRL_ARGB4444 (2 << 16)
115#define S5P_CIOCTRL_ORDER2P_SHIFT (24)
116#define S5P_CIOCTRL_ORDER2P_MASK (3 << 24)
117#define S5P_CIOCTRL_ORDER422_2P_LSB_CRCB (0 << 24)
118
119/* Pre-scaler control 1 */
120#define S5P_CISCPRERATIO 0x50
121#define S5P_CISCPRERATIO_SHFACTOR(x) ((x) << 28)
122#define S5P_CISCPRERATIO_HOR(x) ((x) << 16)
123#define S5P_CISCPRERATIO_VER(x) ((x) << 0)
124
125#define S5P_CISCPREDST 0x54
126#define S5P_CISCPREDST_WIDTH(x) ((x) << 16)
127#define S5P_CISCPREDST_HEIGHT(x) ((x) << 0)
128
129/* Main scaler control */
130#define S5P_CISCCTRL 0x58
131#define S5P_CISCCTRL_SCALERBYPASS (1 << 31)
132#define S5P_CISCCTRL_SCALEUP_H (1 << 30)
133#define S5P_CISCCTRL_SCALEUP_V (1 << 29)
134#define S5P_CISCCTRL_CSCR2Y_WIDE (1 << 28)
135#define S5P_CISCCTRL_CSCY2R_WIDE (1 << 27)
136#define S5P_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
137#define S5P_CISCCTRL_INTERLACE (1 << 25)
138#define S5P_CISCCTRL_SCALERSTART (1 << 15)
139#define S5P_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
140#define S5P_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
141#define S5P_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
142#define S5P_CISCCTRL_INRGB_FMT_MASK (3 << 13)
143#define S5P_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
144#define S5P_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
145#define S5P_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
146#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
147#define S5P_CISCCTRL_RGB_EXT (1 << 10)
148#define S5P_CISCCTRL_ONE2ONE (1 << 9)
149#define S5P_CISCCTRL_MHRATIO(x) ((x) << 16)
150#define S5P_CISCCTRL_MVRATIO(x) ((x) << 0)
151#define S5P_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
152#define S5P_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
153#define S5P_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
154#define S5P_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
155
156/* Target area */
157#define S5P_CITAREA 0x5c
158#define S5P_CITAREA_MASK 0x0fffffff
159
160/* General status */
161#define S5P_CISTATUS 0x64
162#define S5P_CISTATUS_OVFIY (1 << 31)
163#define S5P_CISTATUS_OVFICB (1 << 30)
164#define S5P_CISTATUS_OVFICR (1 << 29)
165#define S5P_CISTATUS_VSYNC (1 << 28)
166#define S5P_CISTATUS_FRAMECNT_MASK (3 << 26)
167#define S5P_CISTATUS_FRAMECNT_SHIFT 26
168#define S5P_CISTATUS_WINOFF_EN (1 << 25)
169#define S5P_CISTATUS_IMGCPT_EN (1 << 22)
170#define S5P_CISTATUS_IMGCPT_SCEN (1 << 21)
171#define S5P_CISTATUS_VSYNC_A (1 << 20)
172#define S5P_CISTATUS_VSYNC_B (1 << 19)
173#define S5P_CISTATUS_OVRLB (1 << 18)
174#define S5P_CISTATUS_FRAME_END (1 << 17)
175#define S5P_CISTATUS_LASTCAPT_END (1 << 16)
176#define S5P_CISTATUS_VVALID_A (1 << 15)
177#define S5P_CISTATUS_VVALID_B (1 << 14)
178
179/* Indexes to the last and the currently processed buffer. */
180#define S5P_CISTATUS2 0x68
181
182/* Image capture control */
183#define S5P_CIIMGCPT 0xc0
184#define S5P_CIIMGCPT_IMGCPTEN (1 << 31)
185#define S5P_CIIMGCPT_IMGCPTEN_SC (1 << 30)
186#define S5P_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
187#define S5P_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
188
189/* Frame capture sequence */
190#define S5P_CICPTSEQ 0xc4
191
192/* Image effect */
193#define S5P_CIIMGEFF 0xd0
194#define S5P_CIIMGEFF_IE_ENABLE (1 << 30)
195#define S5P_CIIMGEFF_IE_SC_BEFORE (0 << 29)
196#define S5P_CIIMGEFF_IE_SC_AFTER (1 << 29)
197#define S5P_CIIMGEFF_FIN_BYPASS (0 << 26)
198#define S5P_CIIMGEFF_FIN_ARBITRARY (1 << 26)
199#define S5P_CIIMGEFF_FIN_NEGATIVE (2 << 26)
200#define S5P_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
201#define S5P_CIIMGEFF_FIN_EMBOSSING (4 << 26)
202#define S5P_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
203#define S5P_CIIMGEFF_FIN_MASK (7 << 26)
204#define S5P_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0))
205#define S5P_CIIMGEFF_PAT_CB(x) ((x) << 13)
206#define S5P_CIIMGEFF_PAT_CR(x) ((x) << 0)
207
208/* Input DMA Y/Cb/Cr plane start address 0/1 */
209#define S5P_CIIYSA(n) (0xd4 + (n) * 0x70)
210#define S5P_CIICBSA(n) (0xd8 + (n) * 0x70)
211#define S5P_CIICRSA(n) (0xdc + (n) * 0x70)
212
213/* Real input DMA image size */
214#define S5P_CIREAL_ISIZE 0xf8
215#define S5P_CIREAL_ISIZE_AUTOLOAD_EN (1 << 31)
216#define S5P_CIREAL_ISIZE_ADDR_CH_DIS (1 << 30)
217#define S5P_CIREAL_ISIZE_HEIGHT(x) ((x) << 16)
218#define S5P_CIREAL_ISIZE_WIDTH(x) ((x) << 0)
219
220
221/* Input DMA control */
222#define S5P_MSCTRL 0xfc
223#define S5P_MSCTRL_IN_BURST_COUNT_MASK (0xF << 24)
224#define S5P_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
225#define S5P_MSCTRL_2P_IN_ORDER_SHIFT 16
226#define S5P_MSCTRL_C_INT_IN_3PLANE (0 << 15)
227#define S5P_MSCTRL_C_INT_IN_2PLANE (1 << 15)
228#define S5P_MSCTRL_C_INT_IN_MASK (1 << 15)
229#define S5P_MSCTRL_FLIP_SHIFT 13
230#define S5P_MSCTRL_FLIP_MASK (3 << 13)
231#define S5P_MSCTRL_FLIP_NORMAL (0 << 13)
232#define S5P_MSCTRL_FLIP_X_MIRROR (1 << 13)
233#define S5P_MSCTRL_FLIP_Y_MIRROR (2 << 13)
234#define S5P_MSCTRL_FLIP_180 (3 << 13)
235#define S5P_MSCTRL_FIFO_CTRL_FULL (1 << 12)
236#define S5P_MSCTRL_ORDER422_SHIFT 4
237#define S5P_MSCTRL_ORDER422_YCBYCR (0 << 4)
238#define S5P_MSCTRL_ORDER422_CBYCRY (1 << 4)
239#define S5P_MSCTRL_ORDER422_YCRYCB (2 << 4)
240#define S5P_MSCTRL_ORDER422_CRYCBY (3 << 4)
241#define S5P_MSCTRL_ORDER422_MASK (3 << 4)
242#define S5P_MSCTRL_INPUT_EXTCAM (0 << 3)
243#define S5P_MSCTRL_INPUT_MEMORY (1 << 3)
244#define S5P_MSCTRL_INPUT_MASK (1 << 3)
245#define S5P_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
246#define S5P_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
247#define S5P_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1)
248#define S5P_MSCTRL_INFORMAT_RGB (3 << 1)
249#define S5P_MSCTRL_INFORMAT_MASK (3 << 1)
250#define S5P_MSCTRL_ENVID (1 << 0)
251#define S5P_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
252
253/* Output DMA Y/Cb/Cr offset */
254#define S5P_CIOYOFF 0x168
255#define S5P_CIOCBOFF 0x16c
256#define S5P_CIOCROFF 0x170
257
258/* Input DMA Y/Cb/Cr offset */
259#define S5P_CIIYOFF 0x174
260#define S5P_CIICBOFF 0x178
261#define S5P_CIICROFF 0x17c
262
263#define S5P_CIO_OFFS_VER(x) ((x) << 16)
264#define S5P_CIO_OFFS_HOR(x) ((x) << 0)
265
266/* Input DMA original image size */
267#define S5P_ORGISIZE 0x180
268
269/* Output DMA original image size */
270#define S5P_ORGOSIZE 0x184
271
272#define S5P_ORIG_SIZE_VER(x) ((x) << 16)
273#define S5P_ORIG_SIZE_HOR(x) ((x) << 0)
274
275/* Real output DMA image size (extension register) */
276#define S5P_CIEXTEN 0x188
277#define S5P_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
278#define S5P_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
279#define S5P_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
280#define S5P_CIEXTEN_MVRATIO_EXT_MASK 0x3f
281
282#define S5P_CIDMAPARAM 0x18c
283#define S5P_CIDMAPARAM_R_LINEAR (0 << 29)
284#define S5P_CIDMAPARAM_R_64X32 (3 << 29)
285#define S5P_CIDMAPARAM_W_LINEAR (0 << 13)
286#define S5P_CIDMAPARAM_W_64X32 (3 << 13)
287#define S5P_CIDMAPARAM_TILE_MASK ((3 << 29) | (3 << 13))
288
289/* MIPI CSI image format */
290#define S5P_CSIIMGFMT 0x194
291#define S5P_CSIIMGFMT_YCBCR422_8BIT 0x1e
292#define S5P_CSIIMGFMT_RAW8 0x2a
293#define S5P_CSIIMGFMT_RAW10 0x2b
294#define S5P_CSIIMGFMT_RAW12 0x2c
295/* User defined formats. x = 0...16. */
296#define S5P_CSIIMGFMT_USER(x) (0x30 + x - 1)
297
298/* Output frame buffer sequence mask */
299#define S5P_CIFCNTSEQ 0x1FC
300
301#endif /* REGS_FIMC_H_ */
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c
index 789de74014e5..7c98ee7377ee 100644
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ b/drivers/media/video/s5p-g2d/g2d.c
@@ -65,7 +65,7 @@ static struct g2d_fmt formats[] = {
65}; 65};
66#define NUM_FORMATS ARRAY_SIZE(formats) 66#define NUM_FORMATS ARRAY_SIZE(formats)
67 67
68struct g2d_frame def_frame = { 68static struct g2d_frame def_frame = {
69 .width = DEFAULT_WIDTH, 69 .width = DEFAULT_WIDTH,
70 .height = DEFAULT_HEIGHT, 70 .height = DEFAULT_HEIGHT,
71 .c_width = DEFAULT_WIDTH, 71 .c_width = DEFAULT_WIDTH,
@@ -77,7 +77,7 @@ struct g2d_frame def_frame = {
77 .bottom = DEFAULT_HEIGHT, 77 .bottom = DEFAULT_HEIGHT,
78}; 78};
79 79
80struct g2d_fmt *find_fmt(struct v4l2_format *f) 80static struct g2d_fmt *find_fmt(struct v4l2_format *f)
81{ 81{
82 unsigned int i; 82 unsigned int i;
83 for (i = 0; i < NUM_FORMATS; i++) { 83 for (i = 0; i < NUM_FORMATS; i++) {
@@ -202,7 +202,7 @@ static const struct v4l2_ctrl_ops g2d_ctrl_ops = {
202 .s_ctrl = g2d_s_ctrl, 202 .s_ctrl = g2d_s_ctrl,
203}; 203};
204 204
205int g2d_setup_ctrls(struct g2d_ctx *ctx) 205static int g2d_setup_ctrls(struct g2d_ctx *ctx)
206{ 206{
207 struct g2d_dev *dev = ctx->dev; 207 struct g2d_dev *dev = ctx->dev;
208 208
@@ -546,11 +546,11 @@ static void job_abort(void *prv)
546 struct g2d_dev *dev = ctx->dev; 546 struct g2d_dev *dev = ctx->dev;
547 int ret; 547 int ret;
548 548
549 if (dev->curr == 0) /* No job currently running */ 549 if (dev->curr == NULL) /* No job currently running */
550 return; 550 return;
551 551
552 ret = wait_event_timeout(dev->irq_queue, 552 ret = wait_event_timeout(dev->irq_queue,
553 dev->curr == 0, 553 dev->curr == NULL,
554 msecs_to_jiffies(G2D_TIMEOUT)); 554 msecs_to_jiffies(G2D_TIMEOUT));
555} 555}
556 556
@@ -599,19 +599,19 @@ static irqreturn_t g2d_isr(int irq, void *prv)
599 g2d_clear_int(dev); 599 g2d_clear_int(dev);
600 clk_disable(dev->gate); 600 clk_disable(dev->gate);
601 601
602 BUG_ON(ctx == 0); 602 BUG_ON(ctx == NULL);
603 603
604 src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 604 src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
605 dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 605 dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
606 606
607 BUG_ON(src == 0); 607 BUG_ON(src == NULL);
608 BUG_ON(dst == 0); 608 BUG_ON(dst == NULL);
609 609
610 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); 610 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
611 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); 611 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
612 v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx); 612 v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
613 613
614 dev->curr = 0; 614 dev->curr = NULL;
615 wake_up(&dev->irq_queue); 615 wake_up(&dev->irq_queue);
616 return IRQ_HANDLED; 616 return IRQ_HANDLED;
617} 617}
@@ -674,42 +674,27 @@ static int g2d_probe(struct platform_device *pdev)
674 struct resource *res; 674 struct resource *res;
675 int ret = 0; 675 int ret = 0;
676 676
677 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 677 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
678 if (!dev) 678 if (!dev)
679 return -ENOMEM; 679 return -ENOMEM;
680
680 spin_lock_init(&dev->ctrl_lock); 681 spin_lock_init(&dev->ctrl_lock);
681 mutex_init(&dev->mutex); 682 mutex_init(&dev->mutex);
682 atomic_set(&dev->num_inst, 0); 683 atomic_set(&dev->num_inst, 0);
683 init_waitqueue_head(&dev->irq_queue); 684 init_waitqueue_head(&dev->irq_queue);
684 685
685 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 686 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
686 if (!res) {
687 dev_err(&pdev->dev, "failed to find registers\n");
688 ret = -ENOENT;
689 goto free_dev;
690 }
691 687
692 dev->res_regs = request_mem_region(res->start, resource_size(res), 688 dev->regs = devm_request_and_ioremap(&pdev->dev, res);
693 dev_name(&pdev->dev)); 689 if (dev->regs == NULL) {
694 690 dev_err(&pdev->dev, "Failed to obtain io memory\n");
695 if (!dev->res_regs) { 691 return -ENOENT;
696 dev_err(&pdev->dev, "failed to obtain register region\n");
697 ret = -ENOENT;
698 goto free_dev;
699 }
700
701 dev->regs = ioremap(res->start, resource_size(res));
702 if (!dev->regs) {
703 dev_err(&pdev->dev, "failed to map registers\n");
704 ret = -ENOENT;
705 goto rel_res_regs;
706 } 692 }
707 693
708 dev->clk = clk_get(&pdev->dev, "sclk_fimg2d"); 694 dev->clk = clk_get(&pdev->dev, "sclk_fimg2d");
709 if (IS_ERR_OR_NULL(dev->clk)) { 695 if (IS_ERR_OR_NULL(dev->clk)) {
710 dev_err(&pdev->dev, "failed to get g2d clock\n"); 696 dev_err(&pdev->dev, "failed to get g2d clock\n");
711 ret = -ENXIO; 697 return -ENXIO;
712 goto unmap_regs;
713 } 698 }
714 699
715 ret = clk_prepare(dev->clk); 700 ret = clk_prepare(dev->clk);
@@ -740,7 +725,8 @@ static int g2d_probe(struct platform_device *pdev)
740 725
741 dev->irq = res->start; 726 dev->irq = res->start;
742 727
743 ret = request_irq(dev->irq, g2d_isr, 0, pdev->name, dev); 728 ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr,
729 0, pdev->name, dev);
744 if (ret) { 730 if (ret) {
745 dev_err(&pdev->dev, "failed to install IRQ\n"); 731 dev_err(&pdev->dev, "failed to install IRQ\n");
746 goto put_clk_gate; 732 goto put_clk_gate;
@@ -749,7 +735,7 @@ static int g2d_probe(struct platform_device *pdev)
749 dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 735 dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
750 if (IS_ERR(dev->alloc_ctx)) { 736 if (IS_ERR(dev->alloc_ctx)) {
751 ret = PTR_ERR(dev->alloc_ctx); 737 ret = PTR_ERR(dev->alloc_ctx);
752 goto rel_irq; 738 goto unprep_clk_gate;
753 } 739 }
754 740
755 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); 741 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
@@ -762,6 +748,10 @@ static int g2d_probe(struct platform_device *pdev)
762 goto unreg_v4l2_dev; 748 goto unreg_v4l2_dev;
763 } 749 }
764 *vfd = g2d_videodev; 750 *vfd = g2d_videodev;
751 /* Locking in file operations other than ioctl should be done
752 by the driver, not the V4L2 core.
753 This driver needs auditing so that this flag can be removed. */
754 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
765 vfd->lock = &dev->mutex; 755 vfd->lock = &dev->mutex;
766 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 756 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
767 if (ret) { 757 if (ret) {
@@ -793,8 +783,6 @@ unreg_v4l2_dev:
793 v4l2_device_unregister(&dev->v4l2_dev); 783 v4l2_device_unregister(&dev->v4l2_dev);
794alloc_ctx_cleanup: 784alloc_ctx_cleanup:
795 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 785 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
796rel_irq:
797 free_irq(dev->irq, dev);
798unprep_clk_gate: 786unprep_clk_gate:
799 clk_unprepare(dev->gate); 787 clk_unprepare(dev->gate);
800put_clk_gate: 788put_clk_gate:
@@ -803,12 +791,7 @@ unprep_clk:
803 clk_unprepare(dev->clk); 791 clk_unprepare(dev->clk);
804put_clk: 792put_clk:
805 clk_put(dev->clk); 793 clk_put(dev->clk);
806unmap_regs: 794
807 iounmap(dev->regs);
808rel_res_regs:
809 release_resource(dev->res_regs);
810free_dev:
811 kfree(dev);
812 return ret; 795 return ret;
813} 796}
814 797
@@ -821,14 +804,10 @@ static int g2d_remove(struct platform_device *pdev)
821 video_unregister_device(dev->vfd); 804 video_unregister_device(dev->vfd);
822 v4l2_device_unregister(&dev->v4l2_dev); 805 v4l2_device_unregister(&dev->v4l2_dev);
823 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 806 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
824 free_irq(dev->irq, dev);
825 clk_unprepare(dev->gate); 807 clk_unprepare(dev->gate);
826 clk_put(dev->gate); 808 clk_put(dev->gate);
827 clk_unprepare(dev->clk); 809 clk_unprepare(dev->clk);
828 clk_put(dev->clk); 810 clk_put(dev->clk);
829 iounmap(dev->regs);
830 release_resource(dev->res_regs);
831 kfree(dev);
832 return 0; 811 return 0;
833} 812}
834 813
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h
index 1b82065aeaef..6b765b0216c5 100644
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ b/drivers/media/video/s5p-g2d/g2d.h
@@ -23,7 +23,6 @@ struct g2d_dev {
23 spinlock_t ctrl_lock; 23 spinlock_t ctrl_lock;
24 atomic_t num_inst; 24 atomic_t num_inst;
25 struct vb2_alloc_ctx *alloc_ctx; 25 struct vb2_alloc_ctx *alloc_ctx;
26 struct resource *res_regs;
27 void __iomem *regs; 26 void __iomem *regs;
28 struct clk *clk; 27 struct clk *clk;
29 struct clk *gate; 28 struct clk *gate;
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c
index 5a49c307f9c1..28b5225d94f5 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/video/s5p-jpeg/jpeg-core.c
@@ -813,7 +813,7 @@ static int s5p_jpeg_streamoff(struct file *file, void *priv,
813 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); 813 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
814} 814}
815 815
816int s5p_jpeg_g_selection(struct file *file, void *priv, 816static int s5p_jpeg_g_selection(struct file *file, void *priv,
817 struct v4l2_selection *s) 817 struct v4l2_selection *s)
818{ 818{
819 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 819 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
@@ -1290,7 +1290,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1290 int ret; 1290 int ret;
1291 1291
1292 /* JPEG IP abstraction struct */ 1292 /* JPEG IP abstraction struct */
1293 jpeg = kzalloc(sizeof(struct s5p_jpeg), GFP_KERNEL); 1293 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1294 if (!jpeg) 1294 if (!jpeg)
1295 return -ENOMEM; 1295 return -ENOMEM;
1296 1296
@@ -1300,43 +1300,25 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1300 1300
1301 /* memory-mapped registers */ 1301 /* memory-mapped registers */
1302 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1302 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1303 if (!res) {
1304 dev_err(&pdev->dev, "cannot find IO resource\n");
1305 ret = -ENOENT;
1306 goto jpeg_alloc_rollback;
1307 }
1308
1309 jpeg->ioarea = request_mem_region(res->start, resource_size(res),
1310 pdev->name);
1311 if (!jpeg->ioarea) {
1312 dev_err(&pdev->dev, "cannot request IO\n");
1313 ret = -ENXIO;
1314 goto jpeg_alloc_rollback;
1315 }
1316 1303
1317 jpeg->regs = ioremap(res->start, resource_size(res)); 1304 jpeg->regs = devm_request_and_ioremap(&pdev->dev, res);
1318 if (!jpeg->regs) { 1305 if (jpeg->regs == NULL) {
1319 dev_err(&pdev->dev, "cannot map IO\n"); 1306 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1320 ret = -ENXIO; 1307 return -ENOENT;
1321 goto mem_region_rollback;
1322 } 1308 }
1323 1309
1324 dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
1325 jpeg->regs, jpeg->ioarea, res);
1326
1327 /* interrupt service routine registration */ 1310 /* interrupt service routine registration */
1328 jpeg->irq = ret = platform_get_irq(pdev, 0); 1311 jpeg->irq = ret = platform_get_irq(pdev, 0);
1329 if (ret < 0) { 1312 if (ret < 0) {
1330 dev_err(&pdev->dev, "cannot find IRQ\n"); 1313 dev_err(&pdev->dev, "cannot find IRQ\n");
1331 goto ioremap_rollback; 1314 return ret;
1332 } 1315 }
1333 1316
1334 ret = request_irq(jpeg->irq, s5p_jpeg_irq, 0, 1317 ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0,
1335 dev_name(&pdev->dev), jpeg); 1318 dev_name(&pdev->dev), jpeg);
1336
1337 if (ret) { 1319 if (ret) {
1338 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq); 1320 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1339 goto ioremap_rollback; 1321 return ret;
1340 } 1322 }
1341 1323
1342 /* clocks */ 1324 /* clocks */
@@ -1344,7 +1326,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1344 if (IS_ERR(jpeg->clk)) { 1326 if (IS_ERR(jpeg->clk)) {
1345 dev_err(&pdev->dev, "cannot get clock\n"); 1327 dev_err(&pdev->dev, "cannot get clock\n");
1346 ret = PTR_ERR(jpeg->clk); 1328 ret = PTR_ERR(jpeg->clk);
1347 goto request_irq_rollback; 1329 return ret;
1348 } 1330 }
1349 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk); 1331 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1350 clk_enable(jpeg->clk); 1332 clk_enable(jpeg->clk);
@@ -1386,6 +1368,10 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1386 jpeg->vfd_encoder->release = video_device_release; 1368 jpeg->vfd_encoder->release = video_device_release;
1387 jpeg->vfd_encoder->lock = &jpeg->lock; 1369 jpeg->vfd_encoder->lock = &jpeg->lock;
1388 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev; 1370 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1371 /* Locking in file operations other than ioctl should be done
1372 by the driver, not the V4L2 core.
1373 This driver needs auditing so that this flag can be removed. */
1374 set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_encoder->flags);
1389 1375
1390 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1); 1376 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1391 if (ret) { 1377 if (ret) {
@@ -1413,6 +1399,10 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1413 jpeg->vfd_decoder->release = video_device_release; 1399 jpeg->vfd_decoder->release = video_device_release;
1414 jpeg->vfd_decoder->lock = &jpeg->lock; 1400 jpeg->vfd_decoder->lock = &jpeg->lock;
1415 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev; 1401 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1402 /* Locking in file operations other than ioctl should be done by the driver,
1403 not the V4L2 core.
1404 This driver needs auditing so that this flag can be removed. */
1405 set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_decoder->flags);
1416 1406
1417 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1); 1407 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1418 if (ret) { 1408 if (ret) {
@@ -1456,18 +1446,6 @@ clk_get_rollback:
1456 clk_disable(jpeg->clk); 1446 clk_disable(jpeg->clk);
1457 clk_put(jpeg->clk); 1447 clk_put(jpeg->clk);
1458 1448
1459request_irq_rollback:
1460 free_irq(jpeg->irq, jpeg);
1461
1462ioremap_rollback:
1463 iounmap(jpeg->regs);
1464
1465mem_region_rollback:
1466 release_resource(jpeg->ioarea);
1467 release_mem_region(jpeg->ioarea->start, resource_size(jpeg->ioarea));
1468
1469jpeg_alloc_rollback:
1470 kfree(jpeg);
1471 return ret; 1449 return ret;
1472} 1450}
1473 1451
@@ -1488,14 +1466,6 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
1488 clk_disable(jpeg->clk); 1466 clk_disable(jpeg->clk);
1489 clk_put(jpeg->clk); 1467 clk_put(jpeg->clk);
1490 1468
1491 free_irq(jpeg->irq, jpeg);
1492
1493 iounmap(jpeg->regs);
1494
1495 release_resource(jpeg->ioarea);
1496 release_mem_region(jpeg->ioarea->start, resource_size(jpeg->ioarea));
1497 kfree(jpeg);
1498
1499 return 0; 1469 return 0;
1500} 1470}
1501 1471
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.h b/drivers/media/video/s5p-jpeg/jpeg-core.h
index 38d7367f7a6d..9d0cd2b76f61 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/video/s5p-jpeg/jpeg-core.h
@@ -54,7 +54,6 @@
54 * @vfd_encoder: video device node for encoder mem2mem mode 54 * @vfd_encoder: video device node for encoder mem2mem mode
55 * @vfd_decoder: video device node for decoder mem2mem mode 55 * @vfd_decoder: video device node for decoder mem2mem mode
56 * @m2m_dev: v4l2 mem2mem device data 56 * @m2m_dev: v4l2 mem2mem device data
57 * @ioarea: JPEG IP memory region
58 * @regs: JPEG IP registers mapping 57 * @regs: JPEG IP registers mapping
59 * @irq: JPEG IP irq 58 * @irq: JPEG IP irq
60 * @clk: JPEG IP clock 59 * @clk: JPEG IP clock
@@ -70,7 +69,6 @@ struct s5p_jpeg {
70 struct video_device *vfd_decoder; 69 struct video_device *vfd_decoder;
71 struct v4l2_m2m_dev *m2m_dev; 70 struct v4l2_m2m_dev *m2m_dev;
72 71
73 struct resource *ioarea;
74 void __iomem *regs; 72 void __iomem *regs;
75 unsigned int irq; 73 unsigned int irq;
76 struct clk *clk; 74 struct clk *clk;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/video/s5p-mfc/s5p_mfc.c
index 83fe461af263..9bb68e7b5ae8 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc.c
@@ -70,7 +70,7 @@ static void wake_up_dev(struct s5p_mfc_dev *dev, unsigned int reason,
70 wake_up(&dev->queue); 70 wake_up(&dev->queue);
71} 71}
72 72
73void s5p_mfc_watchdog(unsigned long arg) 73static void s5p_mfc_watchdog(unsigned long arg)
74{ 74{
75 struct s5p_mfc_dev *dev = (struct s5p_mfc_dev *)arg; 75 struct s5p_mfc_dev *dev = (struct s5p_mfc_dev *)arg;
76 76
@@ -373,7 +373,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
373 373
374 /* If no context is available then all necessary 374 /* If no context is available then all necessary
375 * processing has been done. */ 375 * processing has been done. */
376 if (ctx == 0) 376 if (ctx == NULL)
377 return; 377 return;
378 378
379 dev = ctx->dev; 379 dev = ctx->dev;
@@ -429,7 +429,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
429 struct s5p_mfc_dev *dev; 429 struct s5p_mfc_dev *dev;
430 unsigned int guard_width, guard_height; 430 unsigned int guard_width, guard_height;
431 431
432 if (ctx == 0) 432 if (ctx == NULL)
433 return; 433 return;
434 dev = ctx->dev; 434 dev = ctx->dev;
435 if (ctx->c_ops->post_seq_start) { 435 if (ctx->c_ops->post_seq_start) {
@@ -496,7 +496,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
496 struct s5p_mfc_dev *dev; 496 struct s5p_mfc_dev *dev;
497 unsigned long flags; 497 unsigned long flags;
498 498
499 if (ctx == 0) 499 if (ctx == NULL)
500 return; 500 return;
501 dev = ctx->dev; 501 dev = ctx->dev;
502 s5p_mfc_clear_int_flags(dev); 502 s5p_mfc_clear_int_flags(dev);
@@ -772,7 +772,7 @@ err_queue_init:
772err_init_hw: 772err_init_hw:
773 s5p_mfc_release_firmware(dev); 773 s5p_mfc_release_firmware(dev);
774err_alloc_fw: 774err_alloc_fw:
775 dev->ctx[ctx->num] = 0; 775 dev->ctx[ctx->num] = NULL;
776 del_timer_sync(&dev->watchdog_timer); 776 del_timer_sync(&dev->watchdog_timer);
777 s5p_mfc_clock_off(); 777 s5p_mfc_clock_off();
778err_pwr_enable: 778err_pwr_enable:
@@ -849,7 +849,7 @@ static int s5p_mfc_release(struct file *file)
849 } 849 }
850 mfc_debug(2, "Shutting down clock\n"); 850 mfc_debug(2, "Shutting down clock\n");
851 s5p_mfc_clock_off(); 851 s5p_mfc_clock_off();
852 dev->ctx[ctx->num] = 0; 852 dev->ctx[ctx->num] = NULL;
853 s5p_mfc_dec_ctrls_delete(ctx); 853 s5p_mfc_dec_ctrls_delete(ctx);
854 v4l2_fh_del(&ctx->fh); 854 v4l2_fh_del(&ctx->fh);
855 v4l2_fh_exit(&ctx->fh); 855 v4l2_fh_exit(&ctx->fh);
@@ -948,7 +948,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
948 int ret; 948 int ret;
949 949
950 pr_debug("%s++\n", __func__); 950 pr_debug("%s++\n", __func__);
951 dev = kzalloc(sizeof *dev, GFP_KERNEL); 951 dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL);
952 if (!dev) { 952 if (!dev) {
953 dev_err(&pdev->dev, "Not enough memory for MFC device\n"); 953 dev_err(&pdev->dev, "Not enough memory for MFC device\n");
954 return -ENOMEM; 954 return -ENOMEM;
@@ -959,49 +959,35 @@ static int s5p_mfc_probe(struct platform_device *pdev)
959 dev->plat_dev = pdev; 959 dev->plat_dev = pdev;
960 if (!dev->plat_dev) { 960 if (!dev->plat_dev) {
961 dev_err(&pdev->dev, "No platform data specified\n"); 961 dev_err(&pdev->dev, "No platform data specified\n");
962 ret = -ENODEV; 962 return -ENODEV;
963 goto err_dev;
964 } 963 }
965 964
966 ret = s5p_mfc_init_pm(dev); 965 ret = s5p_mfc_init_pm(dev);
967 if (ret < 0) { 966 if (ret < 0) {
968 dev_err(&pdev->dev, "failed to get mfc clock source\n"); 967 dev_err(&pdev->dev, "failed to get mfc clock source\n");
969 goto err_clk; 968 return ret;
970 } 969 }
971 970
972 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 971 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
973 if (res == NULL) {
974 dev_err(&pdev->dev, "failed to get memory region resource\n");
975 ret = -ENOENT;
976 goto err_res;
977 }
978 972
979 dev->mfc_mem = request_mem_region(res->start, resource_size(res), 973 dev->regs_base = devm_request_and_ioremap(&pdev->dev, res);
980 pdev->name);
981 if (dev->mfc_mem == NULL) {
982 dev_err(&pdev->dev, "failed to get memory region\n");
983 ret = -ENOENT;
984 goto err_mem_reg;
985 }
986 dev->regs_base = ioremap(dev->mfc_mem->start, resource_size(dev->mfc_mem));
987 if (dev->regs_base == NULL) { 974 if (dev->regs_base == NULL) {
988 dev_err(&pdev->dev, "failed to ioremap address region\n"); 975 dev_err(&pdev->dev, "Failed to obtain io memory\n");
989 ret = -ENOENT; 976 return -ENOENT;
990 goto err_ioremap;
991 } 977 }
992 978
993 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 979 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
994 if (res == NULL) { 980 if (res == NULL) {
995 dev_err(&pdev->dev, "failed to get irq resource\n"); 981 dev_err(&pdev->dev, "failed to get irq resource\n");
996 ret = -ENOENT; 982 ret = -ENOENT;
997 goto err_get_res; 983 goto err_res;
998 } 984 }
999 dev->irq = res->start; 985 dev->irq = res->start;
1000 ret = request_irq(dev->irq, s5p_mfc_irq, IRQF_DISABLED, pdev->name, 986 ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq,
1001 dev); 987 IRQF_DISABLED, pdev->name, dev);
1002 if (ret) { 988 if (ret) {
1003 dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret); 989 dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
1004 goto err_req_irq; 990 goto err_res;
1005 } 991 }
1006 992
1007 dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, "s5p-mfc-l", 993 dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, "s5p-mfc-l",
@@ -1009,20 +995,20 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1009 if (!dev->mem_dev_l) { 995 if (!dev->mem_dev_l) {
1010 mfc_err("Mem child (L) device get failed\n"); 996 mfc_err("Mem child (L) device get failed\n");
1011 ret = -ENODEV; 997 ret = -ENODEV;
1012 goto err_find_child; 998 goto err_res;
1013 } 999 }
1014 dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r", 1000 dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
1015 match_child); 1001 match_child);
1016 if (!dev->mem_dev_r) { 1002 if (!dev->mem_dev_r) {
1017 mfc_err("Mem child (R) device get failed\n"); 1003 mfc_err("Mem child (R) device get failed\n");
1018 ret = -ENODEV; 1004 ret = -ENODEV;
1019 goto err_find_child; 1005 goto err_res;
1020 } 1006 }
1021 1007
1022 dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l); 1008 dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
1023 if (IS_ERR_OR_NULL(dev->alloc_ctx[0])) { 1009 if (IS_ERR_OR_NULL(dev->alloc_ctx[0])) {
1024 ret = PTR_ERR(dev->alloc_ctx[0]); 1010 ret = PTR_ERR(dev->alloc_ctx[0]);
1025 goto err_mem_init_ctx_0; 1011 goto err_res;
1026 } 1012 }
1027 dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r); 1013 dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r);
1028 if (IS_ERR_OR_NULL(dev->alloc_ctx[1])) { 1014 if (IS_ERR_OR_NULL(dev->alloc_ctx[1])) {
@@ -1048,6 +1034,10 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1048 vfd->ioctl_ops = get_dec_v4l2_ioctl_ops(); 1034 vfd->ioctl_ops = get_dec_v4l2_ioctl_ops();
1049 vfd->release = video_device_release, 1035 vfd->release = video_device_release,
1050 vfd->lock = &dev->mfc_mutex; 1036 vfd->lock = &dev->mfc_mutex;
1037 /* Locking in file operations other than ioctl should be done
1038 by the driver, not the V4L2 core.
1039 This driver needs auditing so that this flag can be removed. */
1040 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
1051 vfd->v4l2_dev = &dev->v4l2_dev; 1041 vfd->v4l2_dev = &dev->v4l2_dev;
1052 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME); 1042 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME);
1053 dev->vfd_dec = vfd; 1043 dev->vfd_dec = vfd;
@@ -1072,6 +1062,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1072 vfd->ioctl_ops = get_enc_v4l2_ioctl_ops(); 1062 vfd->ioctl_ops = get_enc_v4l2_ioctl_ops();
1073 vfd->release = video_device_release, 1063 vfd->release = video_device_release,
1074 vfd->lock = &dev->mfc_mutex; 1064 vfd->lock = &dev->mfc_mutex;
1065 /* This should not be necessary */
1066 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
1075 vfd->v4l2_dev = &dev->v4l2_dev; 1067 vfd->v4l2_dev = &dev->v4l2_dev;
1076 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME); 1068 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
1077 dev->vfd_enc = vfd; 1069 dev->vfd_enc = vfd;
@@ -1110,22 +1102,9 @@ err_v4l2_dev_reg:
1110 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]); 1102 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
1111err_mem_init_ctx_1: 1103err_mem_init_ctx_1:
1112 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]); 1104 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
1113err_mem_init_ctx_0:
1114err_find_child:
1115 free_irq(dev->irq, dev);
1116err_req_irq:
1117err_get_res:
1118 iounmap(dev->regs_base);
1119 dev->regs_base = NULL;
1120err_ioremap:
1121 release_resource(dev->mfc_mem);
1122 kfree(dev->mfc_mem);
1123err_mem_reg:
1124err_res: 1105err_res:
1125 s5p_mfc_final_pm(dev); 1106 s5p_mfc_final_pm(dev);
1126err_clk: 1107
1127err_dev:
1128 kfree(dev);
1129 pr_debug("%s-- with error\n", __func__); 1108 pr_debug("%s-- with error\n", __func__);
1130 return ret; 1109 return ret;
1131 1110
@@ -1148,15 +1127,7 @@ static int __devexit s5p_mfc_remove(struct platform_device *pdev)
1148 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]); 1127 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
1149 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]); 1128 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
1150 1129
1151 free_irq(dev->irq, dev);
1152 iounmap(dev->regs_base);
1153 if (dev->mfc_mem) {
1154 release_resource(dev->mfc_mem);
1155 kfree(dev->mfc_mem);
1156 dev->mfc_mem = NULL;
1157 }
1158 s5p_mfc_final_pm(dev); 1130 s5p_mfc_final_pm(dev);
1159 kfree(dev);
1160 return 0; 1131 return 0;
1161} 1132}
1162 1133
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_common.h b/drivers/media/video/s5p-mfc/s5p_mfc_common.h
index 91146fa622e4..bd5706a6bad1 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_common.h
@@ -185,7 +185,6 @@ struct s5p_mfc_pm {
185 * @mem_dev_r: child device of the right memory bank (1) 185 * @mem_dev_r: child device of the right memory bank (1)
186 * @regs_base: base address of the MFC hw registers 186 * @regs_base: base address of the MFC hw registers
187 * @irq: irq resource 187 * @irq: irq resource
188 * @mfc_mem: MFC registers memory resource
189 * @dec_ctrl_handler: control framework handler for decoding 188 * @dec_ctrl_handler: control framework handler for decoding
190 * @enc_ctrl_handler: control framework handler for encoding 189 * @enc_ctrl_handler: control framework handler for encoding
191 * @pm: power management control 190 * @pm: power management control
@@ -221,7 +220,6 @@ struct s5p_mfc_dev {
221 struct device *mem_dev_r; 220 struct device *mem_dev_r;
222 void __iomem *regs_base; 221 void __iomem *regs_base;
223 int irq; 222 int irq;
224 struct resource *mfc_mem;
225 struct v4l2_ctrl_handler dec_ctrl_handler; 223 struct v4l2_ctrl_handler dec_ctrl_handler;
226 struct v4l2_ctrl_handler enc_ctrl_handler; 224 struct v4l2_ctrl_handler enc_ctrl_handler;
227 struct s5p_mfc_pm pm; 225 struct s5p_mfc_pm pm;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
index f2481a85e0a2..08a5cfeaa59e 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
@@ -52,7 +52,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
52 s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc( 52 s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc(
53 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], dev->fw_size); 53 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], dev->fw_size);
54 if (IS_ERR(s5p_mfc_bitproc_buf)) { 54 if (IS_ERR(s5p_mfc_bitproc_buf)) {
55 s5p_mfc_bitproc_buf = 0; 55 s5p_mfc_bitproc_buf = NULL;
56 mfc_err("Allocating bitprocessor buffer failed\n"); 56 mfc_err("Allocating bitprocessor buffer failed\n");
57 release_firmware(fw_blob); 57 release_firmware(fw_blob);
58 return -ENOMEM; 58 return -ENOMEM;
@@ -63,7 +63,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
63 mfc_err("The base memory for bank 1 is not aligned to 128KB\n"); 63 mfc_err("The base memory for bank 1 is not aligned to 128KB\n");
64 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 64 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
65 s5p_mfc_bitproc_phys = 0; 65 s5p_mfc_bitproc_phys = 0;
66 s5p_mfc_bitproc_buf = 0; 66 s5p_mfc_bitproc_buf = NULL;
67 release_firmware(fw_blob); 67 release_firmware(fw_blob);
68 return -EIO; 68 return -EIO;
69 } 69 }
@@ -72,7 +72,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
72 mfc_err("Bitprocessor memory remap failed\n"); 72 mfc_err("Bitprocessor memory remap failed\n");
73 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 73 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
74 s5p_mfc_bitproc_phys = 0; 74 s5p_mfc_bitproc_phys = 0;
75 s5p_mfc_bitproc_buf = 0; 75 s5p_mfc_bitproc_buf = NULL;
76 release_firmware(fw_blob); 76 release_firmware(fw_blob);
77 return -EIO; 77 return -EIO;
78 } 78 }
@@ -82,7 +82,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
82 if (IS_ERR(b_base)) { 82 if (IS_ERR(b_base)) {
83 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 83 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
84 s5p_mfc_bitproc_phys = 0; 84 s5p_mfc_bitproc_phys = 0;
85 s5p_mfc_bitproc_buf = 0; 85 s5p_mfc_bitproc_buf = NULL;
86 mfc_err("Allocating bank2 base failed\n"); 86 mfc_err("Allocating bank2 base failed\n");
87 release_firmware(fw_blob); 87 release_firmware(fw_blob);
88 return -ENOMEM; 88 return -ENOMEM;
@@ -94,7 +94,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
94 mfc_err("The base memory for bank 2 is not aligned to 128KB\n"); 94 mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
95 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 95 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
96 s5p_mfc_bitproc_phys = 0; 96 s5p_mfc_bitproc_phys = 0;
97 s5p_mfc_bitproc_buf = 0; 97 s5p_mfc_bitproc_buf = NULL;
98 release_firmware(fw_blob); 98 release_firmware(fw_blob);
99 return -EIO; 99 return -EIO;
100 } 100 }
@@ -126,7 +126,7 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
126 release_firmware(fw_blob); 126 release_firmware(fw_blob);
127 return -ENOMEM; 127 return -ENOMEM;
128 } 128 }
129 if (s5p_mfc_bitproc_buf == 0 || s5p_mfc_bitproc_phys == 0) { 129 if (s5p_mfc_bitproc_buf == NULL || s5p_mfc_bitproc_phys == 0) {
130 mfc_err("MFC firmware is not allocated or was not mapped correctly\n"); 130 mfc_err("MFC firmware is not allocated or was not mapped correctly\n");
131 release_firmware(fw_blob); 131 release_firmware(fw_blob);
132 return -EINVAL; 132 return -EINVAL;
@@ -146,9 +146,9 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
146 if (!s5p_mfc_bitproc_buf) 146 if (!s5p_mfc_bitproc_buf)
147 return -EINVAL; 147 return -EINVAL;
148 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); 148 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
149 s5p_mfc_bitproc_virt = 0; 149 s5p_mfc_bitproc_virt = NULL;
150 s5p_mfc_bitproc_phys = 0; 150 s5p_mfc_bitproc_phys = 0;
151 s5p_mfc_bitproc_buf = 0; 151 s5p_mfc_bitproc_buf = NULL;
152 return 0; 152 return 0;
153} 153}
154 154
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index dff9dc798795..acedb2004be3 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1436,7 +1436,8 @@ static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = {
1436 .s_ctrl = s5p_mfc_enc_s_ctrl, 1436 .s_ctrl = s5p_mfc_enc_s_ctrl,
1437}; 1437};
1438 1438
1439int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *a) 1439static int vidioc_s_parm(struct file *file, void *priv,
1440 struct v4l2_streamparm *a)
1440{ 1441{
1441 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); 1442 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1442 1443
@@ -1452,7 +1453,8 @@ int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *a)
1452 return 0; 1453 return 0;
1453} 1454}
1454 1455
1455int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *a) 1456static int vidioc_g_parm(struct file *file, void *priv,
1457 struct v4l2_streamparm *a)
1456{ 1458{
1457 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); 1459 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1458 1460
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c b/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
index e08b21c50ebf..e6217cbfa4a3 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
@@ -43,7 +43,7 @@ int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
43 ctx->desc_buf = vb2_dma_contig_memops.alloc( 43 ctx->desc_buf = vb2_dma_contig_memops.alloc(
44 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE); 44 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE);
45 if (IS_ERR_VALUE((int)ctx->desc_buf)) { 45 if (IS_ERR_VALUE((int)ctx->desc_buf)) {
46 ctx->desc_buf = 0; 46 ctx->desc_buf = NULL;
47 mfc_err("Allocating DESC buffer failed\n"); 47 mfc_err("Allocating DESC buffer failed\n");
48 return -ENOMEM; 48 return -ENOMEM;
49 } 49 }
@@ -54,7 +54,7 @@ int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
54 if (desc_virt == NULL) { 54 if (desc_virt == NULL) {
55 vb2_dma_contig_memops.put(ctx->desc_buf); 55 vb2_dma_contig_memops.put(ctx->desc_buf);
56 ctx->desc_phys = 0; 56 ctx->desc_phys = 0;
57 ctx->desc_buf = 0; 57 ctx->desc_buf = NULL;
58 mfc_err("Remapping DESC buffer failed\n"); 58 mfc_err("Remapping DESC buffer failed\n");
59 return -ENOMEM; 59 return -ENOMEM;
60 } 60 }
@@ -69,7 +69,7 @@ void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
69 if (ctx->desc_phys) { 69 if (ctx->desc_phys) {
70 vb2_dma_contig_memops.put(ctx->desc_buf); 70 vb2_dma_contig_memops.put(ctx->desc_buf);
71 ctx->desc_phys = 0; 71 ctx->desc_phys = 0;
72 ctx->desc_buf = 0; 72 ctx->desc_buf = NULL;
73 } 73 }
74} 74}
75 75
@@ -186,7 +186,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
186 ctx->bank1_buf = vb2_dma_contig_memops.alloc( 186 ctx->bank1_buf = vb2_dma_contig_memops.alloc(
187 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size); 187 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
188 if (IS_ERR(ctx->bank1_buf)) { 188 if (IS_ERR(ctx->bank1_buf)) {
189 ctx->bank1_buf = 0; 189 ctx->bank1_buf = NULL;
190 printk(KERN_ERR 190 printk(KERN_ERR
191 "Buf alloc for decoding failed (port A)\n"); 191 "Buf alloc for decoding failed (port A)\n");
192 return -ENOMEM; 192 return -ENOMEM;
@@ -200,7 +200,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
200 ctx->bank2_buf = vb2_dma_contig_memops.alloc( 200 ctx->bank2_buf = vb2_dma_contig_memops.alloc(
201 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_size); 201 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_size);
202 if (IS_ERR(ctx->bank2_buf)) { 202 if (IS_ERR(ctx->bank2_buf)) {
203 ctx->bank2_buf = 0; 203 ctx->bank2_buf = NULL;
204 mfc_err("Buf alloc for decoding failed (port B)\n"); 204 mfc_err("Buf alloc for decoding failed (port B)\n");
205 return -ENOMEM; 205 return -ENOMEM;
206 } 206 }
@@ -216,13 +216,13 @@ void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
216{ 216{
217 if (ctx->bank1_buf) { 217 if (ctx->bank1_buf) {
218 vb2_dma_contig_memops.put(ctx->bank1_buf); 218 vb2_dma_contig_memops.put(ctx->bank1_buf);
219 ctx->bank1_buf = 0; 219 ctx->bank1_buf = NULL;
220 ctx->bank1_phys = 0; 220 ctx->bank1_phys = 0;
221 ctx->bank1_size = 0; 221 ctx->bank1_size = 0;
222 } 222 }
223 if (ctx->bank2_buf) { 223 if (ctx->bank2_buf) {
224 vb2_dma_contig_memops.put(ctx->bank2_buf); 224 vb2_dma_contig_memops.put(ctx->bank2_buf);
225 ctx->bank2_buf = 0; 225 ctx->bank2_buf = NULL;
226 ctx->bank2_phys = 0; 226 ctx->bank2_phys = 0;
227 ctx->bank2_size = 0; 227 ctx->bank2_size = 0;
228 } 228 }
@@ -244,7 +244,7 @@ int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
244 if (IS_ERR(ctx->ctx_buf)) { 244 if (IS_ERR(ctx->ctx_buf)) {
245 mfc_err("Allocating context buffer failed\n"); 245 mfc_err("Allocating context buffer failed\n");
246 ctx->ctx_phys = 0; 246 ctx->ctx_phys = 0;
247 ctx->ctx_buf = 0; 247 ctx->ctx_buf = NULL;
248 return -ENOMEM; 248 return -ENOMEM;
249 } 249 }
250 ctx->ctx_phys = s5p_mfc_mem_cookie( 250 ctx->ctx_phys = s5p_mfc_mem_cookie(
@@ -256,7 +256,7 @@ int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
256 mfc_err("Remapping instance buffer failed\n"); 256 mfc_err("Remapping instance buffer failed\n");
257 vb2_dma_contig_memops.put(ctx->ctx_buf); 257 vb2_dma_contig_memops.put(ctx->ctx_buf);
258 ctx->ctx_phys = 0; 258 ctx->ctx_phys = 0;
259 ctx->ctx_buf = 0; 259 ctx->ctx_buf = NULL;
260 return -ENOMEM; 260 return -ENOMEM;
261 } 261 }
262 /* Zero content of the allocated memory */ 262 /* Zero content of the allocated memory */
@@ -265,7 +265,7 @@ int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
265 if (s5p_mfc_init_shm(ctx) < 0) { 265 if (s5p_mfc_init_shm(ctx) < 0) {
266 vb2_dma_contig_memops.put(ctx->ctx_buf); 266 vb2_dma_contig_memops.put(ctx->ctx_buf);
267 ctx->ctx_phys = 0; 267 ctx->ctx_phys = 0;
268 ctx->ctx_buf = 0; 268 ctx->ctx_buf = NULL;
269 return -ENOMEM; 269 return -ENOMEM;
270 } 270 }
271 return 0; 271 return 0;
@@ -277,12 +277,12 @@ void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
277 if (ctx->ctx_buf) { 277 if (ctx->ctx_buf) {
278 vb2_dma_contig_memops.put(ctx->ctx_buf); 278 vb2_dma_contig_memops.put(ctx->ctx_buf);
279 ctx->ctx_phys = 0; 279 ctx->ctx_phys = 0;
280 ctx->ctx_buf = 0; 280 ctx->ctx_buf = NULL;
281 } 281 }
282 if (ctx->shm_alloc) { 282 if (ctx->shm_alloc) {
283 vb2_dma_contig_memops.put(ctx->shm_alloc); 283 vb2_dma_contig_memops.put(ctx->shm_alloc);
284 ctx->shm_alloc = 0; 284 ctx->shm_alloc = NULL;
285 ctx->shm = 0; 285 ctx->shm = NULL;
286 } 286 }
287} 287}
288 288
@@ -296,7 +296,7 @@ void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
296} 296}
297 297
298/* Set registers for shared buffer */ 298/* Set registers for shared buffer */
299void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx) 299static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
300{ 300{
301 struct s5p_mfc_dev *dev = ctx->dev; 301 struct s5p_mfc_dev *dev = ctx->dev;
302 mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR); 302 mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
index 4865d25a0e57..20cb6eef2979 100644
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ b/drivers/media/video/s5p-tv/hdmi_drv.c
@@ -42,7 +42,23 @@ MODULE_DESCRIPTION("Samsung HDMI");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43 43
44/* default preset configured on probe */ 44/* default preset configured on probe */
45#define HDMI_DEFAULT_PRESET V4L2_DV_1080P60 45#define HDMI_DEFAULT_PRESET V4L2_DV_480P59_94
46
47struct hdmi_pulse {
48 u32 beg;
49 u32 end;
50};
51
52struct hdmi_timings {
53 struct hdmi_pulse hact;
54 u32 hsyn_pol; /* 0 - high, 1 - low */
55 struct hdmi_pulse hsyn;
56 u32 interlaced;
57 struct hdmi_pulse vact[2];
58 u32 vsyn_pol; /* 0 - high, 1 - low */
59 u32 vsyn_off;
60 struct hdmi_pulse vsyn[2];
61};
46 62
47struct hdmi_resources { 63struct hdmi_resources {
48 struct clk *hdmi; 64 struct clk *hdmi;
@@ -70,64 +86,15 @@ struct hdmi_device {
70 /** subdev of MHL interface */ 86 /** subdev of MHL interface */
71 struct v4l2_subdev *mhl_sd; 87 struct v4l2_subdev *mhl_sd;
72 /** configuration of current graphic mode */ 88 /** configuration of current graphic mode */
73 const struct hdmi_preset_conf *cur_conf; 89 const struct hdmi_timings *cur_conf;
90 /** flag indicating that timings are dirty */
91 int cur_conf_dirty;
74 /** current preset */ 92 /** current preset */
75 u32 cur_preset; 93 u32 cur_preset;
76 /** other resources */ 94 /** other resources */
77 struct hdmi_resources res; 95 struct hdmi_resources res;
78}; 96};
79 97
80struct hdmi_tg_regs {
81 u8 cmd;
82 u8 h_fsz_l;
83 u8 h_fsz_h;
84 u8 hact_st_l;
85 u8 hact_st_h;
86 u8 hact_sz_l;
87 u8 hact_sz_h;
88 u8 v_fsz_l;
89 u8 v_fsz_h;
90 u8 vsync_l;
91 u8 vsync_h;
92 u8 vsync2_l;
93 u8 vsync2_h;
94 u8 vact_st_l;
95 u8 vact_st_h;
96 u8 vact_sz_l;
97 u8 vact_sz_h;
98 u8 field_chg_l;
99 u8 field_chg_h;
100 u8 vact_st2_l;
101 u8 vact_st2_h;
102 u8 vsync_top_hdmi_l;
103 u8 vsync_top_hdmi_h;
104 u8 vsync_bot_hdmi_l;
105 u8 vsync_bot_hdmi_h;
106 u8 field_top_hdmi_l;
107 u8 field_top_hdmi_h;
108 u8 field_bot_hdmi_l;
109 u8 field_bot_hdmi_h;
110};
111
112struct hdmi_core_regs {
113 u8 h_blank[2];
114 u8 v_blank[3];
115 u8 h_v_line[3];
116 u8 vsync_pol[1];
117 u8 int_pro_mode[1];
118 u8 v_blank_f[3];
119 u8 h_sync_gen[3];
120 u8 v_sync_gen1[3];
121 u8 v_sync_gen2[3];
122 u8 v_sync_gen3[3];
123};
124
125struct hdmi_preset_conf {
126 struct hdmi_core_regs core;
127 struct hdmi_tg_regs tg;
128 struct v4l2_mbus_framefmt mbus_fmt;
129};
130
131static struct platform_device_id hdmi_driver_types[] = { 98static struct platform_device_id hdmi_driver_types[] = {
132 { 99 {
133 .name = "s5pv210-hdmi", 100 .name = "s5pv210-hdmi",
@@ -165,6 +132,21 @@ void hdmi_writeb(struct hdmi_device *hdev, u32 reg_id, u8 value)
165 writeb(value, hdev->regs + reg_id); 132 writeb(value, hdev->regs + reg_id);
166} 133}
167 134
135static inline
136void hdmi_writebn(struct hdmi_device *hdev, u32 reg_id, int n, u32 value)
137{
138 switch (n) {
139 default:
140 writeb(value >> 24, hdev->regs + reg_id + 12);
141 case 3:
142 writeb(value >> 16, hdev->regs + reg_id + 8);
143 case 2:
144 writeb(value >> 8, hdev->regs + reg_id + 4);
145 case 1:
146 writeb(value >> 0, hdev->regs + reg_id + 0);
147 }
148}
149
168static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id) 150static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id)
169{ 151{
170 return readl(hdev->regs + reg_id); 152 return readl(hdev->regs + reg_id);
@@ -211,77 +193,72 @@ static void hdmi_reg_init(struct hdmi_device *hdev)
211} 193}
212 194
213static void hdmi_timing_apply(struct hdmi_device *hdev, 195static void hdmi_timing_apply(struct hdmi_device *hdev,
214 const struct hdmi_preset_conf *conf) 196 const struct hdmi_timings *t)
215{ 197{
216 const struct hdmi_core_regs *core = &conf->core;
217 const struct hdmi_tg_regs *tg = &conf->tg;
218
219 /* setting core registers */ 198 /* setting core registers */
220 hdmi_writeb(hdev, HDMI_H_BLANK_0, core->h_blank[0]); 199 hdmi_writebn(hdev, HDMI_H_BLANK_0, 2, t->hact.beg);
221 hdmi_writeb(hdev, HDMI_H_BLANK_1, core->h_blank[1]); 200 hdmi_writebn(hdev, HDMI_H_SYNC_GEN_0, 3,
222 hdmi_writeb(hdev, HDMI_V_BLANK_0, core->v_blank[0]); 201 (t->hsyn_pol << 20) | (t->hsyn.end << 10) | t->hsyn.beg);
223 hdmi_writeb(hdev, HDMI_V_BLANK_1, core->v_blank[1]); 202 hdmi_writeb(hdev, HDMI_VSYNC_POL, t->vsyn_pol);
224 hdmi_writeb(hdev, HDMI_V_BLANK_2, core->v_blank[2]); 203 hdmi_writebn(hdev, HDMI_V_BLANK_0, 3,
225 hdmi_writeb(hdev, HDMI_H_V_LINE_0, core->h_v_line[0]); 204 (t->vact[0].beg << 11) | t->vact[0].end);
226 hdmi_writeb(hdev, HDMI_H_V_LINE_1, core->h_v_line[1]); 205 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_1_0, 3,
227 hdmi_writeb(hdev, HDMI_H_V_LINE_2, core->h_v_line[2]); 206 (t->vsyn[0].beg << 12) | t->vsyn[0].end);
228 hdmi_writeb(hdev, HDMI_VSYNC_POL, core->vsync_pol[0]); 207 if (t->interlaced) {
229 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); 208 u32 vsyn_trans = t->hsyn.beg + t->vsyn_off;
230 hdmi_writeb(hdev, HDMI_V_BLANK_F_0, core->v_blank_f[0]); 209
231 hdmi_writeb(hdev, HDMI_V_BLANK_F_1, core->v_blank_f[1]); 210 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 1);
232 hdmi_writeb(hdev, HDMI_V_BLANK_F_2, core->v_blank_f[2]); 211 hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
233 hdmi_writeb(hdev, HDMI_H_SYNC_GEN_0, core->h_sync_gen[0]); 212 (t->hact.end << 12) | t->vact[1].end);
234 hdmi_writeb(hdev, HDMI_H_SYNC_GEN_1, core->h_sync_gen[1]); 213 hdmi_writebn(hdev, HDMI_V_BLANK_F_0, 3,
235 hdmi_writeb(hdev, HDMI_H_SYNC_GEN_2, core->h_sync_gen[2]); 214 (t->vact[1].end << 11) | t->vact[1].beg);
236 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); 215 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_2_0, 3,
237 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); 216 (t->vsyn[1].beg << 12) | t->vsyn[1].end);
238 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); 217 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_3_0, 3,
239 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); 218 (vsyn_trans << 12) | vsyn_trans);
240 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); 219 } else {
241 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); 220 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 0);
242 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); 221 hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
243 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); 222 (t->hact.end << 12) | t->vact[0].end);
244 hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); 223 }
224
245 /* Timing generator registers */ 225 /* Timing generator registers */
246 hdmi_writeb(hdev, HDMI_TG_H_FSZ_L, tg->h_fsz_l); 226 hdmi_writebn(hdev, HDMI_TG_H_FSZ_L, 2, t->hact.end);
247 hdmi_writeb(hdev, HDMI_TG_H_FSZ_H, tg->h_fsz_h); 227 hdmi_writebn(hdev, HDMI_TG_HACT_ST_L, 2, t->hact.beg);
248 hdmi_writeb(hdev, HDMI_TG_HACT_ST_L, tg->hact_st_l); 228 hdmi_writebn(hdev, HDMI_TG_HACT_SZ_L, 2, t->hact.end - t->hact.beg);
249 hdmi_writeb(hdev, HDMI_TG_HACT_ST_H, tg->hact_st_h); 229 hdmi_writebn(hdev, HDMI_TG_VSYNC_L, 2, t->vsyn[0].beg);
250 hdmi_writeb(hdev, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); 230 hdmi_writebn(hdev, HDMI_TG_VACT_ST_L, 2, t->vact[0].beg);
251 hdmi_writeb(hdev, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); 231 hdmi_writebn(hdev, HDMI_TG_VACT_SZ_L, 2,
252 hdmi_writeb(hdev, HDMI_TG_V_FSZ_L, tg->v_fsz_l); 232 t->vact[0].end - t->vact[0].beg);
253 hdmi_writeb(hdev, HDMI_TG_V_FSZ_H, tg->v_fsz_h); 233 hdmi_writebn(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, 2, t->vsyn[0].beg);
254 hdmi_writeb(hdev, HDMI_TG_VSYNC_L, tg->vsync_l); 234 hdmi_writebn(hdev, HDMI_TG_FIELD_TOP_HDMI_L, 2, t->vsyn[0].beg);
255 hdmi_writeb(hdev, HDMI_TG_VSYNC_H, tg->vsync_h); 235 if (t->interlaced) {
256 hdmi_writeb(hdev, HDMI_TG_VSYNC2_L, tg->vsync2_l); 236 hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_FIELD_EN);
257 hdmi_writeb(hdev, HDMI_TG_VSYNC2_H, tg->vsync2_h); 237 hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[1].end);
258 hdmi_writeb(hdev, HDMI_TG_VACT_ST_L, tg->vact_st_l); 238 hdmi_writebn(hdev, HDMI_TG_VSYNC2_L, 2, t->vsyn[1].beg);
259 hdmi_writeb(hdev, HDMI_TG_VACT_ST_H, tg->vact_st_h); 239 hdmi_writebn(hdev, HDMI_TG_FIELD_CHG_L, 2, t->vact[0].end);
260 hdmi_writeb(hdev, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); 240 hdmi_writebn(hdev, HDMI_TG_VACT_ST2_L, 2, t->vact[1].beg);
261 hdmi_writeb(hdev, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); 241 hdmi_writebn(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, 2, t->vsyn[1].beg);
262 hdmi_writeb(hdev, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); 242 hdmi_writebn(hdev, HDMI_TG_FIELD_BOT_HDMI_L, 2, t->vsyn[1].beg);
263 hdmi_writeb(hdev, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); 243 } else {
264 hdmi_writeb(hdev, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); 244 hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_FIELD_EN);
265 hdmi_writeb(hdev, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); 245 hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[0].end);
266 hdmi_writeb(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); 246 }
267 hdmi_writeb(hdev, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
268 hdmi_writeb(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
269 hdmi_writeb(hdev, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
270 hdmi_writeb(hdev, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
271 hdmi_writeb(hdev, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
272 hdmi_writeb(hdev, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
273 hdmi_writeb(hdev, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
274} 247}
275 248
276static int hdmi_conf_apply(struct hdmi_device *hdmi_dev) 249static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
277{ 250{
278 struct device *dev = hdmi_dev->dev; 251 struct device *dev = hdmi_dev->dev;
279 const struct hdmi_preset_conf *conf = hdmi_dev->cur_conf; 252 const struct hdmi_timings *conf = hdmi_dev->cur_conf;
280 struct v4l2_dv_preset preset; 253 struct v4l2_dv_preset preset;
281 int ret; 254 int ret;
282 255
283 dev_dbg(dev, "%s\n", __func__); 256 dev_dbg(dev, "%s\n", __func__);
284 257
258 /* skip if conf is already synchronized with HW */
259 if (!hdmi_dev->cur_conf_dirty)
260 return 0;
261
285 /* reset hdmiphy */ 262 /* reset hdmiphy */
286 hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); 263 hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
287 mdelay(10); 264 mdelay(10);
@@ -307,6 +284,8 @@ static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
307 /* setting core registers */ 284 /* setting core registers */
308 hdmi_timing_apply(hdmi_dev, conf); 285 hdmi_timing_apply(hdmi_dev, conf);
309 286
287 hdmi_dev->cur_conf_dirty = 0;
288
310 return 0; 289 return 0;
311} 290}
312 291
@@ -398,156 +377,126 @@ static void hdmi_dumpregs(struct hdmi_device *hdev, char *prefix)
398#undef DUMPREG 377#undef DUMPREG
399} 378}
400 379
401static const struct hdmi_preset_conf hdmi_conf_480p = { 380static const struct hdmi_timings hdmi_timings_480p = {
402 .core = { 381 .hact = { .beg = 138, .end = 858 },
403 .h_blank = {0x8a, 0x00}, 382 .hsyn_pol = 1,
404 .v_blank = {0x0d, 0x6a, 0x01}, 383 .hsyn = { .beg = 16, .end = 16 + 62 },
405 .h_v_line = {0x0d, 0xa2, 0x35}, 384 .interlaced = 0,
406 .vsync_pol = {0x01}, 385 .vact[0] = { .beg = 42 + 3, .end = 522 + 3 },
407 .int_pro_mode = {0x00}, 386 .vsyn_pol = 1,
408 .v_blank_f = {0x00, 0x00, 0x00}, 387 .vsyn[0] = { .beg = 6 + 3, .end = 12 + 3},
409 .h_sync_gen = {0x0e, 0x30, 0x11},
410 .v_sync_gen1 = {0x0f, 0x90, 0x00},
411 /* other don't care */
412 },
413 .tg = {
414 0x00, /* cmd */
415 0x5a, 0x03, /* h_fsz */
416 0x8a, 0x00, 0xd0, 0x02, /* hact */
417 0x0d, 0x02, /* v_fsz */
418 0x01, 0x00, 0x33, 0x02, /* vsync */
419 0x2d, 0x00, 0xe0, 0x01, /* vact */
420 0x33, 0x02, /* field_chg */
421 0x49, 0x02, /* vact_st2 */
422 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
423 0x01, 0x00, 0x33, 0x02, /* field top/bot */
424 },
425 .mbus_fmt = {
426 .width = 720,
427 .height = 480,
428 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
429 .field = V4L2_FIELD_NONE,
430 .colorspace = V4L2_COLORSPACE_SRGB,
431 },
432}; 388};
433 389
434static const struct hdmi_preset_conf hdmi_conf_720p60 = { 390static const struct hdmi_timings hdmi_timings_576p50 = {
435 .core = { 391 .hact = { .beg = 144, .end = 864 },
436 .h_blank = {0x72, 0x01}, 392 .hsyn_pol = 1,
437 .v_blank = {0xee, 0xf2, 0x00}, 393 .hsyn = { .beg = 12, .end = 12 + 64 },
438 .h_v_line = {0xee, 0x22, 0x67}, 394 .interlaced = 0,
439 .vsync_pol = {0x00}, 395 .vact[0] = { .beg = 44 + 5, .end = 620 + 5 },
440 .int_pro_mode = {0x00}, 396 .vsyn_pol = 1,
441 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 397 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
442 .h_sync_gen = {0x6c, 0x50, 0x02},
443 .v_sync_gen1 = {0x0a, 0x50, 0x00},
444 /* other don't care */
445 },
446 .tg = {
447 0x00, /* cmd */
448 0x72, 0x06, /* h_fsz */
449 0x72, 0x01, 0x00, 0x05, /* hact */
450 0xee, 0x02, /* v_fsz */
451 0x01, 0x00, 0x33, 0x02, /* vsync */
452 0x1e, 0x00, 0xd0, 0x02, /* vact */
453 0x33, 0x02, /* field_chg */
454 0x49, 0x02, /* vact_st2 */
455 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
456 0x01, 0x00, 0x33, 0x02, /* field top/bot */
457 },
458 .mbus_fmt = {
459 .width = 1280,
460 .height = 720,
461 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
462 .field = V4L2_FIELD_NONE,
463 .colorspace = V4L2_COLORSPACE_SRGB,
464 },
465}; 398};
466 399
467static const struct hdmi_preset_conf hdmi_conf_1080p50 = { 400static const struct hdmi_timings hdmi_timings_720p60 = {
468 .core = { 401 .hact = { .beg = 370, .end = 1650 },
469 .h_blank = {0xd0, 0x02}, 402 .hsyn_pol = 0,
470 .v_blank = {0x65, 0x6c, 0x01}, 403 .hsyn = { .beg = 110, .end = 110 + 40 },
471 .h_v_line = {0x65, 0x04, 0xa5}, 404 .interlaced = 0,
472 .vsync_pol = {0x00}, 405 .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
473 .int_pro_mode = {0x00}, 406 .vsyn_pol = 0,
474 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 407 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
475 .h_sync_gen = {0x0e, 0xea, 0x08},
476 .v_sync_gen1 = {0x09, 0x40, 0x00},
477 /* other don't care */
478 },
479 .tg = {
480 0x00, /* cmd */
481 0x98, 0x08, /* h_fsz */
482 0x18, 0x01, 0x80, 0x07, /* hact */
483 0x65, 0x04, /* v_fsz */
484 0x01, 0x00, 0x33, 0x02, /* vsync */
485 0x2d, 0x00, 0x38, 0x04, /* vact */
486 0x33, 0x02, /* field_chg */
487 0x49, 0x02, /* vact_st2 */
488 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
489 0x01, 0x00, 0x33, 0x02, /* field top/bot */
490 },
491 .mbus_fmt = {
492 .width = 1920,
493 .height = 1080,
494 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
495 .field = V4L2_FIELD_NONE,
496 .colorspace = V4L2_COLORSPACE_SRGB,
497 },
498}; 408};
499 409
500static const struct hdmi_preset_conf hdmi_conf_1080p60 = { 410static const struct hdmi_timings hdmi_timings_720p50 = {
501 .core = { 411 .hact = { .beg = 700, .end = 1980 },
502 .h_blank = {0x18, 0x01}, 412 .hsyn_pol = 0,
503 .v_blank = {0x65, 0x6c, 0x01}, 413 .hsyn = { .beg = 440, .end = 440 + 40 },
504 .h_v_line = {0x65, 0x84, 0x89}, 414 .interlaced = 0,
505 .vsync_pol = {0x00}, 415 .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
506 .int_pro_mode = {0x00}, 416 .vsyn_pol = 0,
507 .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ 417 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
508 .h_sync_gen = {0x56, 0x08, 0x02}, 418};
509 .v_sync_gen1 = {0x09, 0x40, 0x00}, 419
510 /* other don't care */ 420static const struct hdmi_timings hdmi_timings_1080p24 = {
511 }, 421 .hact = { .beg = 830, .end = 2750 },
512 .tg = { 422 .hsyn_pol = 0,
513 0x00, /* cmd */ 423 .hsyn = { .beg = 638, .end = 638 + 44 },
514 0x98, 0x08, /* h_fsz */ 424 .interlaced = 0,
515 0x18, 0x01, 0x80, 0x07, /* hact */ 425 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
516 0x65, 0x04, /* v_fsz */ 426 .vsyn_pol = 0,
517 0x01, 0x00, 0x33, 0x02, /* vsync */ 427 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
518 0x2d, 0x00, 0x38, 0x04, /* vact */ 428};
519 0x33, 0x02, /* field_chg */ 429
520 0x48, 0x02, /* vact_st2 */ 430static const struct hdmi_timings hdmi_timings_1080p60 = {
521 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ 431 .hact = { .beg = 280, .end = 2200 },
522 0x01, 0x00, 0x33, 0x02, /* field top/bot */ 432 .hsyn_pol = 0,
523 }, 433 .hsyn = { .beg = 88, .end = 88 + 44 },
524 .mbus_fmt = { 434 .interlaced = 0,
525 .width = 1920, 435 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
526 .height = 1080, 436 .vsyn_pol = 0,
527 .code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */ 437 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
528 .field = V4L2_FIELD_NONE, 438};
529 .colorspace = V4L2_COLORSPACE_SRGB, 439
530 }, 440static const struct hdmi_timings hdmi_timings_1080i60 = {
441 .hact = { .beg = 280, .end = 2200 },
442 .hsyn_pol = 0,
443 .hsyn = { .beg = 88, .end = 88 + 44 },
444 .interlaced = 1,
445 .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
446 .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
447 .vsyn_pol = 0,
448 .vsyn_off = 1100,
449 .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
450 .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
451};
452
453static const struct hdmi_timings hdmi_timings_1080i50 = {
454 .hact = { .beg = 720, .end = 2640 },
455 .hsyn_pol = 0,
456 .hsyn = { .beg = 528, .end = 528 + 44 },
457 .interlaced = 1,
458 .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
459 .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
460 .vsyn_pol = 0,
461 .vsyn_off = 1320,
462 .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
463 .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
464};
465
466static const struct hdmi_timings hdmi_timings_1080p50 = {
467 .hact = { .beg = 720, .end = 2640 },
468 .hsyn_pol = 0,
469 .hsyn = { .beg = 528, .end = 528 + 44 },
470 .interlaced = 0,
471 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
472 .vsyn_pol = 0,
473 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
531}; 474};
532 475
533static const struct { 476static const struct {
534 u32 preset; 477 u32 preset;
535 const struct hdmi_preset_conf *conf; 478 const struct hdmi_timings *timings;
536} hdmi_conf[] = { 479} hdmi_timings[] = {
537 { V4L2_DV_480P59_94, &hdmi_conf_480p }, 480 { V4L2_DV_480P59_94, &hdmi_timings_480p },
538 { V4L2_DV_720P59_94, &hdmi_conf_720p60 }, 481 { V4L2_DV_576P50, &hdmi_timings_576p50 },
539 { V4L2_DV_1080P50, &hdmi_conf_1080p50 }, 482 { V4L2_DV_720P50, &hdmi_timings_720p50 },
540 { V4L2_DV_1080P30, &hdmi_conf_1080p60 }, 483 { V4L2_DV_720P59_94, &hdmi_timings_720p60 },
541 { V4L2_DV_1080P60, &hdmi_conf_1080p60 }, 484 { V4L2_DV_720P60, &hdmi_timings_720p60 },
485 { V4L2_DV_1080P24, &hdmi_timings_1080p24 },
486 { V4L2_DV_1080P30, &hdmi_timings_1080p60 },
487 { V4L2_DV_1080P50, &hdmi_timings_1080p50 },
488 { V4L2_DV_1080I50, &hdmi_timings_1080i50 },
489 { V4L2_DV_1080I60, &hdmi_timings_1080i60 },
490 { V4L2_DV_1080P60, &hdmi_timings_1080p60 },
542}; 491};
543 492
544static const struct hdmi_preset_conf *hdmi_preset2conf(u32 preset) 493static const struct hdmi_timings *hdmi_preset2timings(u32 preset)
545{ 494{
546 int i; 495 int i;
547 496
548 for (i = 0; i < ARRAY_SIZE(hdmi_conf); ++i) 497 for (i = 0; i < ARRAY_SIZE(hdmi_timings); ++i)
549 if (hdmi_conf[i].preset == preset) 498 if (hdmi_timings[i].preset == preset)
550 return hdmi_conf[i].conf; 499 return hdmi_timings[i].timings;
551 return NULL; 500 return NULL;
552} 501}
553 502
@@ -559,6 +508,10 @@ static int hdmi_streamon(struct hdmi_device *hdev)
559 508
560 dev_dbg(dev, "%s\n", __func__); 509 dev_dbg(dev, "%s\n", __func__);
561 510
511 ret = hdmi_conf_apply(hdev);
512 if (ret)
513 return ret;
514
562 ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1); 515 ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
563 if (ret) 516 if (ret)
564 return ret; 517 return ret;
@@ -671,14 +624,15 @@ static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
671{ 624{
672 struct hdmi_device *hdev = sd_to_hdmi_dev(sd); 625 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
673 struct device *dev = hdev->dev; 626 struct device *dev = hdev->dev;
674 const struct hdmi_preset_conf *conf; 627 const struct hdmi_timings *conf;
675 628
676 conf = hdmi_preset2conf(preset->preset); 629 conf = hdmi_preset2timings(preset->preset);
677 if (conf == NULL) { 630 if (conf == NULL) {
678 dev_err(dev, "preset (%u) not supported\n", preset->preset); 631 dev_err(dev, "preset (%u) not supported\n", preset->preset);
679 return -EINVAL; 632 return -EINVAL;
680 } 633 }
681 hdev->cur_conf = conf; 634 hdev->cur_conf = conf;
635 hdev->cur_conf_dirty = 1;
682 hdev->cur_preset = preset->preset; 636 hdev->cur_preset = preset->preset;
683 return 0; 637 return 0;
684} 638}
@@ -695,21 +649,32 @@ static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd,
695 struct v4l2_mbus_framefmt *fmt) 649 struct v4l2_mbus_framefmt *fmt)
696{ 650{
697 struct hdmi_device *hdev = sd_to_hdmi_dev(sd); 651 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
698 struct device *dev = hdev->dev; 652 const struct hdmi_timings *t = hdev->cur_conf;
699 653
700 dev_dbg(dev, "%s\n", __func__); 654 dev_dbg(hdev->dev, "%s\n", __func__);
701 if (!hdev->cur_conf) 655 if (!hdev->cur_conf)
702 return -EINVAL; 656 return -EINVAL;
703 *fmt = hdev->cur_conf->mbus_fmt; 657 memset(fmt, 0, sizeof *fmt);
658 fmt->width = t->hact.end - t->hact.beg;
659 fmt->height = t->vact[0].end - t->vact[0].beg;
660 fmt->code = V4L2_MBUS_FMT_FIXED; /* means RGB888 */
661 fmt->colorspace = V4L2_COLORSPACE_SRGB;
662 if (t->interlaced) {
663 fmt->field = V4L2_FIELD_INTERLACED;
664 fmt->height *= 2;
665 } else {
666 fmt->field = V4L2_FIELD_NONE;
667 }
704 return 0; 668 return 0;
705} 669}
706 670
707static int hdmi_enum_dv_presets(struct v4l2_subdev *sd, 671static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
708 struct v4l2_dv_enum_preset *preset) 672 struct v4l2_dv_enum_preset *preset)
709{ 673{
710 if (preset->index >= ARRAY_SIZE(hdmi_conf)) 674 if (preset->index >= ARRAY_SIZE(hdmi_timings))
711 return -EINVAL; 675 return -EINVAL;
712 return v4l_fill_dv_preset_info(hdmi_conf[preset->index].preset, preset); 676 return v4l_fill_dv_preset_info(hdmi_timings[preset->index].preset,
677 preset);
713} 678}
714 679
715static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = { 680static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = {
@@ -737,6 +702,8 @@ static int hdmi_runtime_suspend(struct device *dev)
737 dev_dbg(dev, "%s\n", __func__); 702 dev_dbg(dev, "%s\n", __func__);
738 v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0); 703 v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0);
739 hdmi_resource_poweroff(&hdev->res); 704 hdmi_resource_poweroff(&hdev->res);
705 /* flag that device context is lost */
706 hdev->cur_conf_dirty = 1;
740 return 0; 707 return 0;
741} 708}
742 709
@@ -750,10 +717,6 @@ static int hdmi_runtime_resume(struct device *dev)
750 717
751 hdmi_resource_poweron(&hdev->res); 718 hdmi_resource_poweron(&hdev->res);
752 719
753 ret = hdmi_conf_apply(hdev);
754 if (ret)
755 goto fail;
756
757 /* starting MHL */ 720 /* starting MHL */
758 ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1); 721 ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
759 if (hdev->mhl_sd && ret) 722 if (hdev->mhl_sd && ret)
@@ -993,7 +956,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
993 strlcpy(sd->name, "s5p-hdmi", sizeof sd->name); 956 strlcpy(sd->name, "s5p-hdmi", sizeof sd->name);
994 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET; 957 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
995 /* FIXME: missing fail preset is not supported */ 958 /* FIXME: missing fail preset is not supported */
996 hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset); 959 hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset);
960 hdmi_dev->cur_conf_dirty = 1;
997 961
998 /* storing subdev for call that have only access to struct device */ 962 /* storing subdev for call that have only access to struct device */
999 dev_set_drvdata(dev, sd); 963 dev_set_drvdata(dev, sd);
diff --git a/drivers/media/video/s5p-tv/hdmiphy_drv.c b/drivers/media/video/s5p-tv/hdmiphy_drv.c
index 0afef77747e5..f67b38631801 100644
--- a/drivers/media/video/s5p-tv/hdmiphy_drv.c
+++ b/drivers/media/video/s5p-tv/hdmiphy_drv.c
@@ -26,53 +26,188 @@ MODULE_DESCRIPTION("Samsung HDMI Physical interface driver");
26MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
27 27
28struct hdmiphy_conf { 28struct hdmiphy_conf {
29 u32 preset; 29 unsigned long pixclk;
30 const u8 *data; 30 const u8 *data;
31}; 31};
32 32
33static const u8 hdmiphy_conf27[32] = { 33struct hdmiphy_ctx {
34 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 34 struct v4l2_subdev sd;
35 0x6B, 0x10, 0x02, 0x51, 0xDf, 0xF2, 0x54, 0x87, 35 const struct hdmiphy_conf *conf_tab;
36 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
37 0x22, 0x40, 0xe3, 0x26, 0x00, 0x00, 0x00, 0x00,
38}; 36};
39 37
40static const u8 hdmiphy_conf74_175[32] = { 38static const struct hdmiphy_conf hdmiphy_conf_s5pv210[] = {
41 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, 39 { .pixclk = 27000000, .data = (u8 [32]) {
42 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, 40 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
43 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 41 0x6B, 0x10, 0x02, 0x52, 0xDF, 0xF2, 0x54, 0x87,
44 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, 42 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
43 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, }
44 },
45 { .pixclk = 27027000, .data = (u8 [32]) {
46 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
47 0x6B, 0x10, 0x02, 0x52, 0xDF, 0xF2, 0x54, 0x87,
48 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
49 0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x00, }
50 },
51 { .pixclk = 74176000, .data = (u8 [32]) {
52 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
53 0x6D, 0x10, 0x01, 0x52, 0xEF, 0xF3, 0x54, 0xB9,
54 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
55 0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x00, }
56 },
57 { .pixclk = 74250000, .data = (u8 [32]) {
58 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
59 0x6A, 0x10, 0x01, 0x52, 0xFF, 0xF1, 0x54, 0xBA,
60 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
61 0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x00, }
62 },
63 { /* end marker */ }
45}; 64};
46 65
47static const u8 hdmiphy_conf74_25[32] = { 66static const struct hdmiphy_conf hdmiphy_conf_exynos4210[] = {
48 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, 67 { .pixclk = 27000000, .data = (u8 [32]) {
49 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, 68 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
50 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xe0, 69 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
51 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, 70 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
71 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, }
72 },
73 { .pixclk = 27027000, .data = (u8 [32]) {
74 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
75 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
76 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
77 0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x00, }
78 },
79 { .pixclk = 74176000, .data = (u8 [32]) {
80 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
81 0x6D, 0x10, 0x01, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
82 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
83 0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x00, }
84 },
85 { .pixclk = 74250000, .data = (u8 [32]) {
86 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
87 0x6A, 0x10, 0x01, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
88 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
89 0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x00, }
90 },
91 { .pixclk = 148352000, .data = (u8 [32]) {
92 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
93 0x6D, 0x18, 0x00, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
94 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
95 0x11, 0x40, 0xA5, 0x26, 0x02, 0x00, 0x00, 0x00, }
96 },
97 { .pixclk = 148500000, .data = (u8 [32]) {
98 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
99 0x6A, 0x18, 0x00, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
100 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
101 0x11, 0x40, 0xA4, 0x26, 0x02, 0x00, 0x00, 0x00, }
102 },
103 { /* end marker */ }
52}; 104};
53 105
54static const u8 hdmiphy_conf148_5[32] = { 106static const struct hdmiphy_conf hdmiphy_conf_exynos4212[] = {
55 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, 107 { .pixclk = 27000000, .data = (u8 [32]) {
56 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, 108 0x01, 0x11, 0x2D, 0x75, 0x00, 0x01, 0x00, 0x08,
57 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, 109 0x82, 0x00, 0x0E, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
58 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, 110 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x71,
111 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
112 },
113 { .pixclk = 27027000, .data = (u8 [32]) {
114 0x01, 0x91, 0x2D, 0x72, 0x00, 0x64, 0x12, 0x08,
115 0x43, 0x20, 0x0E, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
116 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x71,
117 0x54, 0xE2, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
118 },
119 { .pixclk = 74176000, .data = (u8 [32]) {
120 0x01, 0x91, 0x3E, 0x35, 0x00, 0x5B, 0xDE, 0x08,
121 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
122 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x52,
123 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
124 },
125 { .pixclk = 74250000, .data = (u8 [32]) {
126 0x01, 0x91, 0x3E, 0x35, 0x00, 0x40, 0xF0, 0x08,
127 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
128 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x52,
129 0x54, 0xA4, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
130 },
131 { .pixclk = 148500000, .data = (u8 [32]) {
132 0x01, 0x91, 0x3E, 0x15, 0x00, 0x40, 0xF0, 0x08,
133 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
134 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0xA4,
135 0x54, 0x4A, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, }
136 },
137 { /* end marker */ }
59}; 138};
60 139
61static const struct hdmiphy_conf hdmiphy_conf[] = { 140static const struct hdmiphy_conf hdmiphy_conf_exynos4412[] = {
62 { V4L2_DV_480P59_94, hdmiphy_conf27 }, 141 { .pixclk = 27000000, .data = (u8 [32]) {
63 { V4L2_DV_1080P30, hdmiphy_conf74_175 }, 142 0x01, 0x11, 0x2D, 0x75, 0x40, 0x01, 0x00, 0x08,
64 { V4L2_DV_720P59_94, hdmiphy_conf74_175 }, 143 0x82, 0x00, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
65 { V4L2_DV_720P60, hdmiphy_conf74_25 }, 144 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
66 { V4L2_DV_1080P50, hdmiphy_conf148_5 }, 145 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
67 { V4L2_DV_1080P60, hdmiphy_conf148_5 }, 146 },
147 { .pixclk = 27027000, .data = (u8 [32]) {
148 0x01, 0x91, 0x2D, 0x72, 0x40, 0x64, 0x12, 0x08,
149 0x43, 0x20, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
150 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
151 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
152 },
153 { .pixclk = 74176000, .data = (u8 [32]) {
154 0x01, 0x91, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0x08,
155 0x81, 0x20, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
156 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
157 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
158 },
159 { .pixclk = 74250000, .data = (u8 [32]) {
160 0x01, 0x91, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
161 0x81, 0x20, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
162 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
163 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
164 },
165 { .pixclk = 148500000, .data = (u8 [32]) {
166 0x01, 0x91, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
167 0x81, 0x20, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
168 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
169 0x54, 0x4B, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, }
170 },
171 { /* end marker */ }
68}; 172};
69 173
70const u8 *hdmiphy_preset2conf(u32 preset) 174static inline struct hdmiphy_ctx *sd_to_ctx(struct v4l2_subdev *sd)
175{
176 return container_of(sd, struct hdmiphy_ctx, sd);
177}
178
179static unsigned long hdmiphy_preset_to_pixclk(u32 preset)
180{
181 static const unsigned long pixclk[] = {
182 [V4L2_DV_480P59_94] = 27000000,
183 [V4L2_DV_576P50] = 27000000,
184 [V4L2_DV_720P59_94] = 74176000,
185 [V4L2_DV_720P50] = 74250000,
186 [V4L2_DV_720P60] = 74250000,
187 [V4L2_DV_1080P24] = 74250000,
188 [V4L2_DV_1080P30] = 74250000,
189 [V4L2_DV_1080I50] = 74250000,
190 [V4L2_DV_1080I60] = 74250000,
191 [V4L2_DV_1080P50] = 148500000,
192 [V4L2_DV_1080P60] = 148500000,
193 };
194 if (preset < ARRAY_SIZE(pixclk))
195 return pixclk[preset];
196 else
197 return 0;
198}
199
200static const u8 *hdmiphy_find_conf(u32 preset, const struct hdmiphy_conf *conf)
71{ 201{
72 int i; 202 unsigned long pixclk;
73 for (i = 0; i < ARRAY_SIZE(hdmiphy_conf); ++i) 203
74 if (hdmiphy_conf[i].preset == preset) 204 pixclk = hdmiphy_preset_to_pixclk(preset);
75 return hdmiphy_conf[i].data; 205 if (!pixclk)
206 return NULL;
207
208 for (; conf->pixclk; ++conf)
209 if (conf->pixclk == pixclk)
210 return conf->data;
76 return NULL; 211 return NULL;
77} 212}
78 213
@@ -88,11 +223,12 @@ static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd,
88 const u8 *data; 223 const u8 *data;
89 u8 buffer[32]; 224 u8 buffer[32];
90 int ret; 225 int ret;
226 struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
91 struct i2c_client *client = v4l2_get_subdevdata(sd); 227 struct i2c_client *client = v4l2_get_subdevdata(sd);
92 struct device *dev = &client->dev; 228 struct device *dev = &client->dev;
93 229
94 dev_info(dev, "s_dv_preset(preset = %d)\n", preset->preset); 230 dev_info(dev, "s_dv_preset(preset = %d)\n", preset->preset);
95 data = hdmiphy_preset2conf(preset->preset); 231 data = hdmiphy_find_conf(preset->preset, ctx->conf_tab);
96 if (!data) { 232 if (!data) {
97 dev_err(dev, "format not supported\n"); 233 dev_err(dev, "format not supported\n");
98 return -EINVAL; 234 return -EINVAL;
@@ -146,21 +282,36 @@ static const struct v4l2_subdev_ops hdmiphy_ops = {
146static int __devinit hdmiphy_probe(struct i2c_client *client, 282static int __devinit hdmiphy_probe(struct i2c_client *client,
147 const struct i2c_device_id *id) 283 const struct i2c_device_id *id)
148{ 284{
149 static struct v4l2_subdev sd; 285 struct hdmiphy_ctx *ctx;
286
287 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
288 if (!ctx)
289 return -ENOMEM;
290
291 ctx->conf_tab = (struct hdmiphy_conf *)id->driver_data;
292 v4l2_i2c_subdev_init(&ctx->sd, client, &hdmiphy_ops);
150 293
151 v4l2_i2c_subdev_init(&sd, client, &hdmiphy_ops);
152 dev_info(&client->dev, "probe successful\n"); 294 dev_info(&client->dev, "probe successful\n");
153 return 0; 295 return 0;
154} 296}
155 297
156static int __devexit hdmiphy_remove(struct i2c_client *client) 298static int __devexit hdmiphy_remove(struct i2c_client *client)
157{ 299{
300 struct v4l2_subdev *sd = i2c_get_clientdata(client);
301 struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
302
303 kfree(ctx);
158 dev_info(&client->dev, "remove successful\n"); 304 dev_info(&client->dev, "remove successful\n");
305
159 return 0; 306 return 0;
160} 307}
161 308
162static const struct i2c_device_id hdmiphy_id[] = { 309static const struct i2c_device_id hdmiphy_id[] = {
163 { "hdmiphy", 0 }, 310 { "hdmiphy", (unsigned long)hdmiphy_conf_exynos4210 },
311 { "hdmiphy-s5pv210", (unsigned long)hdmiphy_conf_s5pv210 },
312 { "hdmiphy-exynos4210", (unsigned long)hdmiphy_conf_exynos4210 },
313 { "hdmiphy-exynos4212", (unsigned long)hdmiphy_conf_exynos4212 },
314 { "hdmiphy-exynos4412", (unsigned long)hdmiphy_conf_exynos4412 },
164 { }, 315 { },
165}; 316};
166MODULE_DEVICE_TABLE(i2c, hdmiphy_id); 317MODULE_DEVICE_TABLE(i2c, hdmiphy_id);
diff --git a/drivers/media/video/s5p-tv/mixer.h b/drivers/media/video/s5p-tv/mixer.h
index 1597078c4a50..ddb422e23550 100644
--- a/drivers/media/video/s5p-tv/mixer.h
+++ b/drivers/media/video/s5p-tv/mixer.h
@@ -226,6 +226,7 @@ struct mxr_resources {
226/* event flags used */ 226/* event flags used */
227enum mxr_devide_flags { 227enum mxr_devide_flags {
228 MXR_EVENT_VSYNC = 0, 228 MXR_EVENT_VSYNC = 0,
229 MXR_EVENT_TOP = 1,
229}; 230};
230 231
231/** drivers instance */ 232/** drivers instance */
@@ -293,7 +294,7 @@ int __devinit mxr_acquire_video(struct mxr_device *mdev,
293 struct mxr_output_conf *output_cont, int output_count); 294 struct mxr_output_conf *output_cont, int output_count);
294 295
295/** releasing common video resources */ 296/** releasing common video resources */
296void __devexit mxr_release_video(struct mxr_device *mdev); 297void mxr_release_video(struct mxr_device *mdev);
297 298
298struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx); 299struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx);
299struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx); 300struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx);
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c
index a2c0c25ad130..edca06592883 100644
--- a/drivers/media/video/s5p-tv/mixer_drv.c
+++ b/drivers/media/video/s5p-tv/mixer_drv.c
@@ -461,7 +461,7 @@ static struct platform_driver mxr_driver __refdata = {
461static int __init mxr_init(void) 461static int __init mxr_init(void)
462{ 462{
463 int i, ret; 463 int i, ret;
464 static const char banner[] __initdata = KERN_INFO 464 static const char banner[] __initconst = KERN_INFO
465 "Samsung TV Mixer driver, " 465 "Samsung TV Mixer driver, "
466 "(c) 2010-2011 Samsung Electronics Co., Ltd.\n"; 466 "(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
467 printk(banner); 467 printk(banner);
diff --git a/drivers/media/video/s5p-tv/mixer_reg.c b/drivers/media/video/s5p-tv/mixer_reg.c
index 4800a3cbb297..3b1670a045f4 100644
--- a/drivers/media/video/s5p-tv/mixer_reg.c
+++ b/drivers/media/video/s5p-tv/mixer_reg.c
@@ -296,21 +296,25 @@ irqreturn_t mxr_irq_handler(int irq, void *dev_data)
296 /* wake up process waiting for VSYNC */ 296 /* wake up process waiting for VSYNC */
297 if (val & MXR_INT_STATUS_VSYNC) { 297 if (val & MXR_INT_STATUS_VSYNC) {
298 set_bit(MXR_EVENT_VSYNC, &mdev->event_flags); 298 set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
299 /* toggle TOP field event if working in interlaced mode */
300 if (~mxr_read(mdev, MXR_CFG) & MXR_CFG_SCAN_PROGRASSIVE)
301 change_bit(MXR_EVENT_TOP, &mdev->event_flags);
299 wake_up(&mdev->event_queue); 302 wake_up(&mdev->event_queue);
300 }
301
302 /* clear interrupts */
303 if (~val & MXR_INT_EN_VSYNC) {
304 /* vsync interrupt use different bit for read and clear */ 303 /* vsync interrupt use different bit for read and clear */
305 val &= ~MXR_INT_EN_VSYNC; 304 val &= ~MXR_INT_STATUS_VSYNC;
306 val |= MXR_INT_CLEAR_VSYNC; 305 val |= MXR_INT_CLEAR_VSYNC;
307 } 306 }
307
308 /* clear interrupts */
308 mxr_write(mdev, MXR_INT_STATUS, val); 309 mxr_write(mdev, MXR_INT_STATUS, val);
309 310
310 spin_unlock(&mdev->reg_slock); 311 spin_unlock(&mdev->reg_slock);
311 /* leave on non-vsync event */ 312 /* leave on non-vsync event */
312 if (~val & MXR_INT_CLEAR_VSYNC) 313 if (~val & MXR_INT_CLEAR_VSYNC)
313 return IRQ_HANDLED; 314 return IRQ_HANDLED;
315 /* skip layer update on bottom field */
316 if (!test_bit(MXR_EVENT_TOP, &mdev->event_flags))
317 return IRQ_HANDLED;
314 for (i = 0; i < MXR_MAX_LAYERS; ++i) 318 for (i = 0; i < MXR_MAX_LAYERS; ++i)
315 mxr_irq_layer_handle(mdev->layer[i]); 319 mxr_irq_layer_handle(mdev->layer[i]);
316 return IRQ_HANDLED; 320 return IRQ_HANDLED;
@@ -333,6 +337,7 @@ void mxr_reg_streamon(struct mxr_device *mdev)
333 337
334 /* start MIXER */ 338 /* start MIXER */
335 mxr_write_mask(mdev, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); 339 mxr_write_mask(mdev, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
340 set_bit(MXR_EVENT_TOP, &mdev->event_flags);
336 341
337 spin_unlock_irqrestore(&mdev->reg_slock, flags); 342 spin_unlock_irqrestore(&mdev->reg_slock, flags);
338} 343}
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
index f7ca5cc143c6..33fde2a763ec 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -140,7 +140,7 @@ fail:
140 return ret; 140 return ret;
141} 141}
142 142
143void __devexit mxr_release_video(struct mxr_device *mdev) 143void mxr_release_video(struct mxr_device *mdev)
144{ 144{
145 int i; 145 int i;
146 146
@@ -853,8 +853,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
853 *nplanes = fmt->num_subframes; 853 *nplanes = fmt->num_subframes;
854 for (i = 0; i < fmt->num_subframes; ++i) { 854 for (i = 0; i < fmt->num_subframes; ++i) {
855 alloc_ctxs[i] = layer->mdev->alloc_ctx; 855 alloc_ctxs[i] = layer->mdev->alloc_ctx;
856 sizes[i] = PAGE_ALIGN(planes[i].sizeimage); 856 sizes[i] = planes[i].sizeimage;
857 mxr_dbg(mdev, "size[%d] = %08lx\n", i, sizes[i]); 857 mxr_dbg(mdev, "size[%d] = %08x\n", i, sizes[i]);
858 } 858 }
859 859
860 if (*nbuffers == 0) 860 if (*nbuffers == 0)
@@ -1069,6 +1069,10 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
1069 set_bit(V4L2_FL_USE_FH_PRIO, &layer->vfd.flags); 1069 set_bit(V4L2_FL_USE_FH_PRIO, &layer->vfd.flags);
1070 1070
1071 video_set_drvdata(&layer->vfd, layer); 1071 video_set_drvdata(&layer->vfd, layer);
1072 /* Locking in file operations other than ioctl should be done
1073 by the driver, not the V4L2 core.
1074 This driver needs auditing so that this flag can be removed. */
1075 set_bit(V4L2_FL_LOCK_ALL_FOPS, &layer->vfd.flags);
1072 layer->vfd.lock = &layer->mutex; 1076 layer->vfd.lock = &layer->mutex;
1073 layer->vfd.v4l2_dev = &mdev->v4l2_dev; 1077 layer->vfd.v4l2_dev = &mdev->v4l2_dev;
1074 1078
diff --git a/drivers/media/video/s5p-tv/regs-hdmi.h b/drivers/media/video/s5p-tv/regs-hdmi.h
index 33247d13e4c0..a889d1f57f28 100644
--- a/drivers/media/video/s5p-tv/regs-hdmi.h
+++ b/drivers/media/video/s5p-tv/regs-hdmi.h
@@ -140,6 +140,7 @@
140#define HDMI_MODE_MASK (3 << 0) 140#define HDMI_MODE_MASK (3 << 0)
141 141
142/* HDMI_TG_CMD */ 142/* HDMI_TG_CMD */
143#define HDMI_TG_FIELD_EN (1 << 1)
143#define HDMI_TG_EN (1 << 0) 144#define HDMI_TG_EN (1 << 0)
144 145
145#endif /* SAMSUNG_REGS_HDMI_H */ 146#endif /* SAMSUNG_REGS_HDMI_H */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 53aae5968ffb..bc08f1dbc293 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5080,6 +5080,36 @@ struct saa7134_board saa7134_boards[] = {
5080 .gpio = 0x0200000, 5080 .gpio = 0x0200000,
5081 }, 5081 },
5082 }, 5082 },
5083 [SAA7134_BOARD_ASUSTeK_PS3_100] = {
5084 .name = "Asus My Cinema PS3-100",
5085 .audio_clock = 0x00187de7,
5086 .tuner_type = TUNER_PHILIPS_TDA8290,
5087 .radio_type = UNSET,
5088 .tuner_addr = ADDR_UNSET,
5089 .radio_addr = ADDR_UNSET,
5090 .tuner_config = 2,
5091 .gpiomask = 1 << 21,
5092 .mpeg = SAA7134_MPEG_DVB,
5093 .inputs = {{
5094 .name = name_tv,
5095 .vmux = 1,
5096 .amux = TV,
5097 .tv = 1,
5098 }, {
5099 .name = name_comp,
5100 .vmux = 0,
5101 .amux = LINE2,
5102 }, {
5103 .name = name_svideo,
5104 .vmux = 8,
5105 .amux = LINE2,
5106 } },
5107 .radio = {
5108 .name = name_radio,
5109 .amux = TV,
5110 .gpio = 0x0200000,
5111 },
5112 },
5083 [SAA7134_BOARD_REAL_ANGEL_220] = { 5113 [SAA7134_BOARD_REAL_ANGEL_220] = {
5084 .name = "Zogis Real Angel 220", 5114 .name = "Zogis Real Angel 220",
5085 .audio_clock = 0x00187de7, 5115 .audio_clock = 0x00187de7,
@@ -6877,6 +6907,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6877 .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1, 6907 .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1,
6878 }, { 6908 }, {
6879 .vendor = PCI_VENDOR_ID_PHILIPS, 6909 .vendor = PCI_VENDOR_ID_PHILIPS,
6910 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6911 .subvendor = 0x1043,
6912 .subdevice = 0x48cd,
6913 .driver_data = SAA7134_BOARD_ASUSTeK_PS3_100,
6914 }, {
6915 .vendor = PCI_VENDOR_ID_PHILIPS,
6880 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6916 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6881 .subvendor = 0x17de, 6917 .subvendor = 0x17de,
6882 .subdevice = 0x7128, 6918 .subdevice = 0x7128,
@@ -7347,6 +7383,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7347 case SAA7134_BOARD_KWORLD_TERMINATOR: 7383 case SAA7134_BOARD_KWORLD_TERMINATOR:
7348 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: 7384 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
7349 case SAA7134_BOARD_FLYDVBT_LR301: 7385 case SAA7134_BOARD_FLYDVBT_LR301:
7386 case SAA7134_BOARD_ASUSTeK_PS3_100:
7350 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 7387 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
7351 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: 7388 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
7352 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: 7389 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
@@ -7811,6 +7848,14 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7811 i2c_transfer(&dev->i2c_adap, &msg, 1); 7848 i2c_transfer(&dev->i2c_adap, &msg, 1);
7812 break; 7849 break;
7813 } 7850 }
7851 case SAA7134_BOARD_ASUSTeK_PS3_100:
7852 {
7853 u8 data[] = { 0x3c, 0x33, 0x60};
7854 struct i2c_msg msg = {.addr = 0x0b, .flags = 0, .buf = data,
7855 .len = sizeof(data)};
7856 i2c_transfer(&dev->i2c_adap, &msg, 1);
7857 break;
7858 }
7814 case SAA7134_BOARD_FLYDVB_TRIO: 7859 case SAA7134_BOARD_FLYDVB_TRIO:
7815 { 7860 {
7816 u8 temp = 0; 7861 u8 temp = 0;
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index aaa5c97a7216..5dfd826d734e 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -881,6 +881,20 @@ static struct tda1004x_config asus_tiger_3in1_config = {
881 .request_firmware = philips_tda1004x_request_firmware 881 .request_firmware = philips_tda1004x_request_firmware
882}; 882};
883 883
884static struct tda1004x_config asus_ps3_100_config = {
885 .demod_address = 0x0b,
886 .invert = 1,
887 .invert_oclk = 0,
888 .xtal_freq = TDA10046_XTAL_16M,
889 .agc_config = TDA10046_AGC_TDA827X,
890 .gpio_config = TDA10046_GP11_I,
891 .if_freq = TDA10046_FREQ_045,
892 .i2c_gate = 0x4b,
893 .tuner_address = 0x61,
894 .antenna_switch = 1,
895 .request_firmware = philips_tda1004x_request_firmware
896};
897
884/* ------------------------------------------------------------------ 898/* ------------------------------------------------------------------
885 * special case: this card uses saa713x GPIO22 for the mode switch 899 * special case: this card uses saa713x GPIO22 for the mode switch
886 */ 900 */
@@ -1647,6 +1661,31 @@ static int dvb_init(struct saa7134_dev *dev)
1647 &dev->i2c_adap, 0, 0) == NULL) { 1661 &dev->i2c_adap, 0, 0) == NULL) {
1648 wprintk("%s: Asus Tiger 3in1, no lnbp21" 1662 wprintk("%s: Asus Tiger 3in1, no lnbp21"
1649 " found!\n", __func__); 1663 " found!\n", __func__);
1664 goto dettach_frontend;
1665 }
1666 }
1667 }
1668 break;
1669 case SAA7134_BOARD_ASUSTeK_PS3_100:
1670 if (!use_frontend) { /* terrestrial */
1671 if (configure_tda827x_fe(dev, &asus_ps3_100_config,
1672 &tda827x_cfg_2) < 0)
1673 goto dettach_frontend;
1674 } else { /* satellite */
1675 fe0->dvb.frontend = dvb_attach(tda10086_attach,
1676 &flydvbs, &dev->i2c_adap);
1677 if (fe0->dvb.frontend) {
1678 if (dvb_attach(tda826x_attach,
1679 fe0->dvb.frontend, 0x60,
1680 &dev->i2c_adap, 0) == NULL) {
1681 wprintk("%s: Asus My Cinema PS3-100, no "
1682 "tda826x found!\n", __func__);
1683 goto dettach_frontend;
1684 }
1685 if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
1686 &dev->i2c_adap, 0, 0) == NULL) {
1687 wprintk("%s: Asus My Cinema PS3-100, no lnbp21"
1688 " found!\n", __func__);
1650 goto dettach_frontend; 1689 goto dettach_frontend;
1651 } 1690 }
1652 } 1691 }
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 48d2878699b7..05c6e217d8a7 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -753,6 +753,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
753 mask_keycode = 0xffff; 753 mask_keycode = 0xffff;
754 raw_decode = true; 754 raw_decode = true;
755 break; 755 break;
756 case SAA7134_BOARD_ASUSTeK_PS3_100:
757 ir_codes = RC_MAP_ASUS_PS3_100;
758 mask_keydown = 0x0040000;
759 mask_keyup = 0x0040000;
760 mask_keycode = 0xffff;
761 raw_decode = true;
762 break;
756 case SAA7134_BOARD_ENCORE_ENLTV: 763 case SAA7134_BOARD_ENCORE_ENLTV:
757 case SAA7134_BOARD_ENCORE_ENLTV_FM: 764 case SAA7134_BOARD_ENCORE_ENLTV_FM:
758 ir_codes = RC_MAP_ENCORE_ENLTV; 765 ir_codes = RC_MAP_ENCORE_ENLTV;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 417034eb6ad2..6de10b1e7251 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -2036,7 +2036,7 @@ static int saa7134_s_tuner(struct file *file, void *priv,
2036 mode = dev->thread.mode; 2036 mode = dev->thread.mode;
2037 if (UNSET == mode) { 2037 if (UNSET == mode) {
2038 rx = saa7134_tvaudio_getstereo(dev); 2038 rx = saa7134_tvaudio_getstereo(dev);
2039 mode = saa7134_tvaudio_rx2mode(t->rxsubchans); 2039 mode = saa7134_tvaudio_rx2mode(rx);
2040 } 2040 }
2041 if (mode != t->audmode) 2041 if (mode != t->audmode)
2042 dev->thread.mode = t->audmode; 2042 dev->thread.mode = t->audmode;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index f625060e6a0f..89c8333736a2 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -332,6 +332,7 @@ struct saa7134_card_ir {
332#define SAA7134_BOARD_BEHOLD_503FM 187 332#define SAA7134_BOARD_BEHOLD_503FM 187
333#define SAA7134_BOARD_SENSORAY811_911 188 333#define SAA7134_BOARD_SENSORAY811_911 188
334#define SAA7134_BOARD_KWORLD_PC150U 189 334#define SAA7134_BOARD_KWORLD_PC150U 189
335#define SAA7134_BOARD_ASUSTeK_PS3_100 190
335 336
336#define SAA7134_MAXBOARDS 32 337#define SAA7134_MAXBOARDS 32
337#define SAA7134_INPUT_MAX 8 338#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index 273cf807401c..d8e6c8f14079 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -952,7 +952,7 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port)
952 952
953 /* Stop the hardware, regardless */ 953 /* Stop the hardware, regardless */
954 result = saa7164_vbi_stop_port(port); 954 result = saa7164_vbi_stop_port(port);
955 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 955 if (result != SAA_OK) {
956 printk(KERN_ERR "%s() pause/forced stop transition " 956 printk(KERN_ERR "%s() pause/forced stop transition "
957 "failed, res = 0x%x\n", __func__, result); 957 "failed, res = 0x%x\n", __func__, result);
958 } 958 }
@@ -971,7 +971,7 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port)
971 /* Stop the hardware, regardless */ 971 /* Stop the hardware, regardless */
972 result = saa7164_vbi_acquire_port(port); 972 result = saa7164_vbi_acquire_port(port);
973 result = saa7164_vbi_stop_port(port); 973 result = saa7164_vbi_stop_port(port);
974 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 974 if (result != SAA_OK) {
975 printk(KERN_ERR "%s() run/forced stop transition " 975 printk(KERN_ERR "%s() run/forced stop transition "
976 "failed, res = 0x%x\n", __func__, result); 976 "failed, res = 0x%x\n", __func__, result);
977 } 977 }
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
index 742b34103b5d..8d120e3baf70 100644
--- a/drivers/media/video/saa7164/saa7164.h
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -611,11 +611,6 @@ extern unsigned int saa_debug;
611 printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\ 611 printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
612 } while (0) 612 } while (0)
613 613
614#define log_err(fmt, arg...)\
615 do { \
616 printk(KERN_ERROR "%s: " fmt, dev->name, ## arg);\
617 } while (0)
618
619#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2)) 614#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
620#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2)) 615#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
621 616
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 424dfacd263a..0baaf94db7e0 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -210,27 +210,33 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
210 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq); 210 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
211 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 211 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
212 struct sh_mobile_ceu_dev *pcdev = ici->priv; 212 struct sh_mobile_ceu_dev *pcdev = ici->priv;
213 int bytes_per_line;
214 unsigned int height;
215 213
216 if (fmt) { 214 if (fmt) {
217 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd, 215 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
218 fmt->fmt.pix.pixelformat); 216 fmt->fmt.pix.pixelformat);
217 unsigned int bytes_per_line;
218 int ret;
219
219 if (!xlate) 220 if (!xlate)
220 return -EINVAL; 221 return -EINVAL;
221 bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width, 222
222 xlate->host_fmt); 223 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
223 height = fmt->fmt.pix.height; 224 xlate->host_fmt);
225 if (ret < 0)
226 return ret;
227
228 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
229
230 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
231 fmt->fmt.pix.height);
232 if (ret < 0)
233 return ret;
234
235 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
224 } else { 236 } else {
225 /* Called from VIDIOC_REQBUFS or in compatibility mode */ 237 /* Called from VIDIOC_REQBUFS or in compatibility mode */
226 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 238 sizes[0] = icd->sizeimage;
227 icd->current_fmt->host_fmt);
228 height = icd->user_height;
229 } 239 }
230 if (bytes_per_line < 0)
231 return bytes_per_line;
232
233 sizes[0] = bytes_per_line * height;
234 240
235 alloc_ctxs[0] = pcdev->alloc_ctx; 241 alloc_ctxs[0] = pcdev->alloc_ctx;
236 242
@@ -336,21 +342,15 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
336 342
337 ceu_write(pcdev, top1, phys_addr_top); 343 ceu_write(pcdev, top1, phys_addr_top);
338 if (V4L2_FIELD_NONE != pcdev->field) { 344 if (V4L2_FIELD_NONE != pcdev->field) {
339 if (planar) 345 phys_addr_bottom = phys_addr_top + icd->bytesperline;
340 phys_addr_bottom = phys_addr_top + icd->user_width;
341 else
342 phys_addr_bottom = phys_addr_top +
343 soc_mbus_bytes_per_line(icd->user_width,
344 icd->current_fmt->host_fmt);
345 ceu_write(pcdev, bottom1, phys_addr_bottom); 346 ceu_write(pcdev, bottom1, phys_addr_bottom);
346 } 347 }
347 348
348 if (planar) { 349 if (planar) {
349 phys_addr_top += icd->user_width * 350 phys_addr_top += icd->bytesperline * icd->user_height;
350 icd->user_height;
351 ceu_write(pcdev, top2, phys_addr_top); 351 ceu_write(pcdev, top2, phys_addr_top);
352 if (V4L2_FIELD_NONE != pcdev->field) { 352 if (V4L2_FIELD_NONE != pcdev->field) {
353 phys_addr_bottom = phys_addr_top + icd->user_width; 353 phys_addr_bottom = phys_addr_top + icd->bytesperline;
354 ceu_write(pcdev, bottom2, phys_addr_bottom); 354 ceu_write(pcdev, bottom2, phys_addr_bottom);
355 } 355 }
356 } 356 }
@@ -377,13 +377,8 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
377 struct sh_mobile_ceu_dev *pcdev = ici->priv; 377 struct sh_mobile_ceu_dev *pcdev = ici->priv;
378 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 378 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
379 unsigned long size; 379 unsigned long size;
380 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
381 icd->current_fmt->host_fmt);
382 380
383 if (bytes_per_line < 0) 381 size = icd->sizeimage;
384 goto error;
385
386 size = icd->user_height * bytes_per_line;
387 382
388 if (vb2_plane_size(vb, 0) < size) { 383 if (vb2_plane_size(vb, 0) < size) {
389 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n", 384 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
@@ -682,10 +677,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
682 in_width *= 2; 677 in_width *= 2;
683 left_offset *= 2; 678 left_offset *= 2;
684 } 679 }
685 cdwdr_width = width;
686 } else { 680 } else {
687 int bytes_per_line = soc_mbus_bytes_per_line(width,
688 icd->current_fmt->host_fmt);
689 unsigned int w_factor; 681 unsigned int w_factor;
690 682
691 switch (icd->current_fmt->host_fmt->packing) { 683 switch (icd->current_fmt->host_fmt->packing) {
@@ -698,13 +690,10 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
698 690
699 in_width = cam->width * w_factor; 691 in_width = cam->width * w_factor;
700 left_offset *= w_factor; 692 left_offset *= w_factor;
701
702 if (bytes_per_line < 0)
703 cdwdr_width = width;
704 else
705 cdwdr_width = bytes_per_line;
706 } 693 }
707 694
695 cdwdr_width = icd->bytesperline;
696
708 height = icd->user_height; 697 height = icd->user_height;
709 in_height = cam->height; 698 in_height = cam->height;
710 if (V4L2_FIELD_NONE != pcdev->field) { 699 if (V4L2_FIELD_NONE != pcdev->field) {
@@ -881,11 +870,13 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
881 870
882 value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; 871 value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
883 value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; 872 value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
884 value |= pcdev->is_16bit ? 1 << 12 : 0;
885 873
886 /* CSI2 mode */ 874 if (pcdev->pdata->csi2) /* CSI2 mode */
887 if (pcdev->pdata->csi2)
888 value |= 3 << 12; 875 value |= 3 << 12;
876 else if (pcdev->is_16bit)
877 value |= 1 << 12;
878 else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
879 value |= 2 << 12;
889 880
890 ceu_write(pcdev, CAMCR, value); 881 ceu_write(pcdev, CAMCR, value);
891 882
@@ -964,24 +955,28 @@ static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
964 .bits_per_sample = 8, 955 .bits_per_sample = 8,
965 .packing = SOC_MBUS_PACKING_1_5X8, 956 .packing = SOC_MBUS_PACKING_1_5X8,
966 .order = SOC_MBUS_ORDER_LE, 957 .order = SOC_MBUS_ORDER_LE,
958 .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
967 }, { 959 }, {
968 .fourcc = V4L2_PIX_FMT_NV21, 960 .fourcc = V4L2_PIX_FMT_NV21,
969 .name = "NV21", 961 .name = "NV21",
970 .bits_per_sample = 8, 962 .bits_per_sample = 8,
971 .packing = SOC_MBUS_PACKING_1_5X8, 963 .packing = SOC_MBUS_PACKING_1_5X8,
972 .order = SOC_MBUS_ORDER_LE, 964 .order = SOC_MBUS_ORDER_LE,
965 .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
973 }, { 966 }, {
974 .fourcc = V4L2_PIX_FMT_NV16, 967 .fourcc = V4L2_PIX_FMT_NV16,
975 .name = "NV16", 968 .name = "NV16",
976 .bits_per_sample = 8, 969 .bits_per_sample = 8,
977 .packing = SOC_MBUS_PACKING_2X8_PADHI, 970 .packing = SOC_MBUS_PACKING_2X8_PADHI,
978 .order = SOC_MBUS_ORDER_LE, 971 .order = SOC_MBUS_ORDER_LE,
972 .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
979 }, { 973 }, {
980 .fourcc = V4L2_PIX_FMT_NV61, 974 .fourcc = V4L2_PIX_FMT_NV61,
981 .name = "NV61", 975 .name = "NV61",
982 .bits_per_sample = 8, 976 .bits_per_sample = 8,
983 .packing = SOC_MBUS_PACKING_2X8_PADHI, 977 .packing = SOC_MBUS_PACKING_2X8_PADHI,
984 .order = SOC_MBUS_ORDER_LE, 978 .order = SOC_MBUS_ORDER_LE,
979 .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
985 }, 980 },
986}; 981};
987 982
@@ -1845,6 +1840,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1845 return 0; 1840 return 0;
1846} 1841}
1847 1842
1843#define CEU_CHDW_MAX 8188U /* Maximum line stride */
1844
1848static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1845static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1849 struct v4l2_format *f) 1846 struct v4l2_format *f)
1850{ 1847{
@@ -1863,8 +1860,12 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1863 1860
1864 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1861 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1865 if (!xlate) { 1862 if (!xlate) {
1866 dev_warn(icd->parent, "Format %x not found\n", pixfmt); 1863 xlate = icd->current_fmt;
1867 return -EINVAL; 1864 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1865 pixfmt, xlate->host_fmt->fourcc);
1866 pixfmt = xlate->host_fmt->fourcc;
1867 pix->pixelformat = pixfmt;
1868 pix->colorspace = icd->colorspace;
1868 } 1869 }
1869 1870
1870 /* FIXME: calculate using depth and bus width */ 1871 /* FIXME: calculate using depth and bus width */
@@ -1923,10 +1924,20 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1923 pix->width = width; 1924 pix->width = width;
1924 if (mf.height > height) 1925 if (mf.height > height)
1925 pix->height = height; 1926 pix->height = height;
1927
1928 pix->bytesperline = max(pix->bytesperline, pix->width);
1929 pix->bytesperline = min(pix->bytesperline, CEU_CHDW_MAX);
1930 pix->bytesperline &= ~3;
1931 break;
1932
1933 default:
1934 /* Configurable stride isn't supported in pass-through mode. */
1935 pix->bytesperline = 0;
1926 } 1936 }
1927 1937
1928 pix->width &= ~3; 1938 pix->width &= ~3;
1929 pix->height &= ~3; 1939 pix->height &= ~3;
1940 pix->sizeimage = 0;
1930 1941
1931 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n", 1942 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1932 __func__, ret, pix->pixelformat, pix->width, pix->height); 1943 __func__, ret, pix->pixelformat, pix->width, pix->height);
@@ -2145,6 +2156,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2145 pcdev->ici.nr = pdev->id; 2156 pcdev->ici.nr = pdev->id;
2146 pcdev->ici.drv_name = dev_name(&pdev->dev); 2157 pcdev->ici.drv_name = dev_name(&pdev->dev);
2147 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 2158 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
2159 pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE;
2148 2160
2149 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 2161 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2150 if (IS_ERR(pcdev->alloc_ctx)) { 2162 if (IS_ERR(pcdev->alloc_ctx)) {
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
index 9644bd861abc..8fd1874382c6 100644
--- a/drivers/media/video/sh_vou.c
+++ b/drivers/media/video/sh_vou.c
@@ -1390,6 +1390,10 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
1390 vdev->v4l2_dev = &vou_dev->v4l2_dev; 1390 vdev->v4l2_dev = &vou_dev->v4l2_dev;
1391 vdev->release = video_device_release; 1391 vdev->release = video_device_release;
1392 vdev->lock = &vou_dev->fop_lock; 1392 vdev->lock = &vou_dev->fop_lock;
1393 /* Locking in file operations other than ioctl should be done
1394 by the driver, not the V4L2 core.
1395 This driver needs auditing so that this flag can be removed. */
1396 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
1393 1397
1394 vou_dev->vdev = vdev; 1398 vou_dev->vdev = vdev;
1395 video_set_drvdata(vdev, vou_dev); 1399 video_set_drvdata(vdev, vou_dev);
diff --git a/drivers/media/video/smiapp-pll.c b/drivers/media/video/smiapp-pll.c
new file mode 100644
index 000000000000..a2e41a21dc65
--- /dev/null
+++ b/drivers/media/video/smiapp-pll.c
@@ -0,0 +1,418 @@
1/*
2 * drivers/media/video/smiapp-pll.c
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#include <linux/gcd.h>
26#include <linux/lcm.h>
27#include <linux/module.h>
28
29#include "smiapp-pll.h"
30
31/* Return an even number or one. */
32static inline uint32_t clk_div_even(uint32_t a)
33{
34 return max_t(uint32_t, 1, a & ~1);
35}
36
37/* Return an even number or one. */
38static inline uint32_t clk_div_even_up(uint32_t a)
39{
40 if (a == 1)
41 return 1;
42 return (a + 1) & ~1;
43}
44
45static inline uint32_t is_one_or_even(uint32_t a)
46{
47 if (a == 1)
48 return 1;
49 if (a & 1)
50 return 0;
51
52 return 1;
53}
54
55static int bounds_check(struct device *dev, uint32_t val,
56 uint32_t min, uint32_t max, char *str)
57{
58 if (val >= min && val <= max)
59 return 0;
60
61 dev_warn(dev, "%s out of bounds: %d (%d--%d)\n", str, val, min, max);
62
63 return -EINVAL;
64}
65
66static void print_pll(struct device *dev, struct smiapp_pll *pll)
67{
68 dev_dbg(dev, "pre_pll_clk_div\t%d\n", pll->pre_pll_clk_div);
69 dev_dbg(dev, "pll_multiplier \t%d\n", pll->pll_multiplier);
70 if (pll->flags != SMIAPP_PLL_FLAG_NO_OP_CLOCKS) {
71 dev_dbg(dev, "op_sys_clk_div \t%d\n", pll->op_sys_clk_div);
72 dev_dbg(dev, "op_pix_clk_div \t%d\n", pll->op_pix_clk_div);
73 }
74 dev_dbg(dev, "vt_sys_clk_div \t%d\n", pll->vt_sys_clk_div);
75 dev_dbg(dev, "vt_pix_clk_div \t%d\n", pll->vt_pix_clk_div);
76
77 dev_dbg(dev, "ext_clk_freq_hz \t%d\n", pll->ext_clk_freq_hz);
78 dev_dbg(dev, "pll_ip_clk_freq_hz \t%d\n", pll->pll_ip_clk_freq_hz);
79 dev_dbg(dev, "pll_op_clk_freq_hz \t%d\n", pll->pll_op_clk_freq_hz);
80 if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) {
81 dev_dbg(dev, "op_sys_clk_freq_hz \t%d\n",
82 pll->op_sys_clk_freq_hz);
83 dev_dbg(dev, "op_pix_clk_freq_hz \t%d\n",
84 pll->op_pix_clk_freq_hz);
85 }
86 dev_dbg(dev, "vt_sys_clk_freq_hz \t%d\n", pll->vt_sys_clk_freq_hz);
87 dev_dbg(dev, "vt_pix_clk_freq_hz \t%d\n", pll->vt_pix_clk_freq_hz);
88}
89
90int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
91 struct smiapp_pll *pll)
92{
93 uint32_t sys_div;
94 uint32_t best_pix_div = INT_MAX >> 1;
95 uint32_t vt_op_binning_div;
96 uint32_t lane_op_clock_ratio;
97 uint32_t mul, div;
98 uint32_t more_mul_min, more_mul_max;
99 uint32_t more_mul_factor;
100 uint32_t min_vt_div, max_vt_div, vt_div;
101 uint32_t min_sys_div, max_sys_div;
102 unsigned int i;
103 int rval;
104
105 if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE)
106 lane_op_clock_ratio = pll->lanes;
107 else
108 lane_op_clock_ratio = 1;
109 dev_dbg(dev, "lane_op_clock_ratio: %d\n", lane_op_clock_ratio);
110
111 dev_dbg(dev, "binning: %dx%d\n", pll->binning_horizontal,
112 pll->binning_vertical);
113
114 /* CSI transfers 2 bits per clock per lane; thus times 2 */
115 pll->pll_op_clk_freq_hz = pll->link_freq * 2
116 * (pll->lanes / lane_op_clock_ratio);
117
118 /* Figure out limits for pre-pll divider based on extclk */
119 dev_dbg(dev, "min / max pre_pll_clk_div: %d / %d\n",
120 limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
121 limits->max_pre_pll_clk_div =
122 min_t(uint16_t, limits->max_pre_pll_clk_div,
123 clk_div_even(pll->ext_clk_freq_hz /
124 limits->min_pll_ip_freq_hz));
125 limits->min_pre_pll_clk_div =
126 max_t(uint16_t, limits->min_pre_pll_clk_div,
127 clk_div_even_up(
128 DIV_ROUND_UP(pll->ext_clk_freq_hz,
129 limits->max_pll_ip_freq_hz)));
130 dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %d / %d\n",
131 limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
132
133 i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz);
134 mul = div_u64(pll->pll_op_clk_freq_hz, i);
135 div = pll->ext_clk_freq_hz / i;
136 dev_dbg(dev, "mul %d / div %d\n", mul, div);
137
138 limits->min_pre_pll_clk_div =
139 max_t(uint16_t, limits->min_pre_pll_clk_div,
140 clk_div_even_up(
141 DIV_ROUND_UP(mul * pll->ext_clk_freq_hz,
142 limits->max_pll_op_freq_hz)));
143 dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %d / %d\n",
144 limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
145
146 if (limits->min_pre_pll_clk_div > limits->max_pre_pll_clk_div) {
147 dev_err(dev, "unable to compute pre_pll divisor\n");
148 return -EINVAL;
149 }
150
151 pll->pre_pll_clk_div = limits->min_pre_pll_clk_div;
152
153 /*
154 * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be
155 * too high.
156 */
157 dev_dbg(dev, "pre_pll_clk_div %d\n", pll->pre_pll_clk_div);
158
159 /* Don't go above max pll multiplier. */
160 more_mul_max = limits->max_pll_multiplier / mul;
161 dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %d\n",
162 more_mul_max);
163 /* Don't go above max pll op frequency. */
164 more_mul_max =
165 min_t(int,
166 more_mul_max,
167 limits->max_pll_op_freq_hz
168 / (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul));
169 dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %d\n",
170 more_mul_max);
171 /* Don't go above the division capability of op sys clock divider. */
172 more_mul_max = min(more_mul_max,
173 limits->max_op_sys_clk_div * pll->pre_pll_clk_div
174 / div);
175 dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %d\n",
176 more_mul_max);
177 /* Ensure we won't go above min_pll_multiplier. */
178 more_mul_max = min(more_mul_max,
179 DIV_ROUND_UP(limits->max_pll_multiplier, mul));
180 dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %d\n",
181 more_mul_max);
182
183 /* Ensure we won't go below min_pll_op_freq_hz. */
184 more_mul_min = DIV_ROUND_UP(limits->min_pll_op_freq_hz,
185 pll->ext_clk_freq_hz / pll->pre_pll_clk_div
186 * mul);
187 dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %d\n",
188 more_mul_min);
189 /* Ensure we won't go below min_pll_multiplier. */
190 more_mul_min = max(more_mul_min,
191 DIV_ROUND_UP(limits->min_pll_multiplier, mul));
192 dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %d\n",
193 more_mul_min);
194
195 if (more_mul_min > more_mul_max) {
196 dev_warn(dev,
197 "unable to compute more_mul_min and more_mul_max");
198 return -EINVAL;
199 }
200
201 more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div;
202 dev_dbg(dev, "more_mul_factor: %d\n", more_mul_factor);
203 more_mul_factor = lcm(more_mul_factor, limits->min_op_sys_clk_div);
204 dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n",
205 more_mul_factor);
206 i = roundup(more_mul_min, more_mul_factor);
207 if (!is_one_or_even(i))
208 i <<= 1;
209
210 dev_dbg(dev, "final more_mul: %d\n", i);
211 if (i > more_mul_max) {
212 dev_warn(dev, "final more_mul is bad, max %d", more_mul_max);
213 return -EINVAL;
214 }
215
216 pll->pll_multiplier = mul * i;
217 pll->op_sys_clk_div = div * i / pll->pre_pll_clk_div;
218 dev_dbg(dev, "op_sys_clk_div: %d\n", pll->op_sys_clk_div);
219
220 pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz
221 / pll->pre_pll_clk_div;
222
223 pll->pll_op_clk_freq_hz = pll->pll_ip_clk_freq_hz
224 * pll->pll_multiplier;
225
226 /* Derive pll_op_clk_freq_hz. */
227 pll->op_sys_clk_freq_hz =
228 pll->pll_op_clk_freq_hz / pll->op_sys_clk_div;
229
230 pll->op_pix_clk_div = pll->bits_per_pixel;
231 dev_dbg(dev, "op_pix_clk_div: %d\n", pll->op_pix_clk_div);
232
233 pll->op_pix_clk_freq_hz =
234 pll->op_sys_clk_freq_hz / pll->op_pix_clk_div;
235
236 /*
237 * Some sensors perform analogue binning and some do this
238 * digitally. The ones doing this digitally can be roughly be
239 * found out using this formula. The ones doing this digitally
240 * should run at higher clock rate, so smaller divisor is used
241 * on video timing side.
242 */
243 if (limits->min_line_length_pck_bin > limits->min_line_length_pck
244 / pll->binning_horizontal)
245 vt_op_binning_div = pll->binning_horizontal;
246 else
247 vt_op_binning_div = 1;
248 dev_dbg(dev, "vt_op_binning_div: %d\n", vt_op_binning_div);
249
250 /*
251 * Profile 2 supports vt_pix_clk_div E [4, 10]
252 *
253 * Horizontal binning can be used as a base for difference in
254 * divisors. One must make sure that horizontal blanking is
255 * enough to accommodate the CSI-2 sync codes.
256 *
257 * Take scaling factor into account as well.
258 *
259 * Find absolute limits for the factor of vt divider.
260 */
261 dev_dbg(dev, "scale_m: %d\n", pll->scale_m);
262 min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div
263 * pll->scale_n,
264 lane_op_clock_ratio * vt_op_binning_div
265 * pll->scale_m);
266
267 /* Find smallest and biggest allowed vt divisor. */
268 dev_dbg(dev, "min_vt_div: %d\n", min_vt_div);
269 min_vt_div = max(min_vt_div,
270 DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
271 limits->max_vt_pix_clk_freq_hz));
272 dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %d\n",
273 min_vt_div);
274 min_vt_div = max_t(uint32_t, min_vt_div,
275 limits->min_vt_pix_clk_div
276 * limits->min_vt_sys_clk_div);
277 dev_dbg(dev, "min_vt_div: min_vt_clk_div: %d\n", min_vt_div);
278
279 max_vt_div = limits->max_vt_sys_clk_div * limits->max_vt_pix_clk_div;
280 dev_dbg(dev, "max_vt_div: %d\n", max_vt_div);
281 max_vt_div = min(max_vt_div,
282 DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
283 limits->min_vt_pix_clk_freq_hz));
284 dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %d\n",
285 max_vt_div);
286
287 /*
288 * Find limitsits for sys_clk_div. Not all values are possible
289 * with all values of pix_clk_div.
290 */
291 min_sys_div = limits->min_vt_sys_clk_div;
292 dev_dbg(dev, "min_sys_div: %d\n", min_sys_div);
293 min_sys_div = max(min_sys_div,
294 DIV_ROUND_UP(min_vt_div,
295 limits->max_vt_pix_clk_div));
296 dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %d\n", min_sys_div);
297 min_sys_div = max(min_sys_div,
298 pll->pll_op_clk_freq_hz
299 / limits->max_vt_sys_clk_freq_hz);
300 dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %d\n", min_sys_div);
301 min_sys_div = clk_div_even_up(min_sys_div);
302 dev_dbg(dev, "min_sys_div: one or even: %d\n", min_sys_div);
303
304 max_sys_div = limits->max_vt_sys_clk_div;
305 dev_dbg(dev, "max_sys_div: %d\n", max_sys_div);
306 max_sys_div = min(max_sys_div,
307 DIV_ROUND_UP(max_vt_div,
308 limits->min_vt_pix_clk_div));
309 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %d\n", max_sys_div);
310 max_sys_div = min(max_sys_div,
311 DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
312 limits->min_vt_pix_clk_freq_hz));
313 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %d\n", max_sys_div);
314
315 /*
316 * Find pix_div such that a legal pix_div * sys_div results
317 * into a value which is not smaller than div, the desired
318 * divisor.
319 */
320 for (vt_div = min_vt_div; vt_div <= max_vt_div;
321 vt_div += 2 - (vt_div & 1)) {
322 for (sys_div = min_sys_div;
323 sys_div <= max_sys_div;
324 sys_div += 2 - (sys_div & 1)) {
325 int pix_div = DIV_ROUND_UP(vt_div, sys_div);
326
327 if (pix_div < limits->min_vt_pix_clk_div
328 || pix_div > limits->max_vt_pix_clk_div) {
329 dev_dbg(dev,
330 "pix_div %d too small or too big (%d--%d)\n",
331 pix_div,
332 limits->min_vt_pix_clk_div,
333 limits->max_vt_pix_clk_div);
334 continue;
335 }
336
337 /* Check if this one is better. */
338 if (pix_div * sys_div
339 <= roundup(min_vt_div, best_pix_div))
340 best_pix_div = pix_div;
341 }
342 if (best_pix_div < INT_MAX >> 1)
343 break;
344 }
345
346 pll->vt_sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div);
347 pll->vt_pix_clk_div = best_pix_div;
348
349 pll->vt_sys_clk_freq_hz =
350 pll->pll_op_clk_freq_hz / pll->vt_sys_clk_div;
351 pll->vt_pix_clk_freq_hz =
352 pll->vt_sys_clk_freq_hz / pll->vt_pix_clk_div;
353
354 pll->pixel_rate_csi =
355 pll->op_pix_clk_freq_hz * lane_op_clock_ratio;
356
357 print_pll(dev, pll);
358
359 rval = bounds_check(dev, pll->pre_pll_clk_div,
360 limits->min_pre_pll_clk_div,
361 limits->max_pre_pll_clk_div, "pre_pll_clk_div");
362 if (!rval)
363 rval = bounds_check(
364 dev, pll->pll_ip_clk_freq_hz,
365 limits->min_pll_ip_freq_hz, limits->max_pll_ip_freq_hz,
366 "pll_ip_clk_freq_hz");
367 if (!rval)
368 rval = bounds_check(
369 dev, pll->pll_multiplier,
370 limits->min_pll_multiplier, limits->max_pll_multiplier,
371 "pll_multiplier");
372 if (!rval)
373 rval = bounds_check(
374 dev, pll->pll_op_clk_freq_hz,
375 limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz,
376 "pll_op_clk_freq_hz");
377 if (!rval)
378 rval = bounds_check(
379 dev, pll->op_sys_clk_div,
380 limits->min_op_sys_clk_div, limits->max_op_sys_clk_div,
381 "op_sys_clk_div");
382 if (!rval)
383 rval = bounds_check(
384 dev, pll->op_pix_clk_div,
385 limits->min_op_pix_clk_div, limits->max_op_pix_clk_div,
386 "op_pix_clk_div");
387 if (!rval)
388 rval = bounds_check(
389 dev, pll->op_sys_clk_freq_hz,
390 limits->min_op_sys_clk_freq_hz,
391 limits->max_op_sys_clk_freq_hz,
392 "op_sys_clk_freq_hz");
393 if (!rval)
394 rval = bounds_check(
395 dev, pll->op_pix_clk_freq_hz,
396 limits->min_op_pix_clk_freq_hz,
397 limits->max_op_pix_clk_freq_hz,
398 "op_pix_clk_freq_hz");
399 if (!rval)
400 rval = bounds_check(
401 dev, pll->vt_sys_clk_freq_hz,
402 limits->min_vt_sys_clk_freq_hz,
403 limits->max_vt_sys_clk_freq_hz,
404 "vt_sys_clk_freq_hz");
405 if (!rval)
406 rval = bounds_check(
407 dev, pll->vt_pix_clk_freq_hz,
408 limits->min_vt_pix_clk_freq_hz,
409 limits->max_vt_pix_clk_freq_hz,
410 "vt_pix_clk_freq_hz");
411
412 return rval;
413}
414EXPORT_SYMBOL_GPL(smiapp_pll_calculate);
415
416MODULE_AUTHOR("Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>");
417MODULE_DESCRIPTION("Generic SMIA/SMIA++ PLL calculator");
418MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/smiapp-pll.h b/drivers/media/video/smiapp-pll.h
new file mode 100644
index 000000000000..9eab63f23afb
--- /dev/null
+++ b/drivers/media/video/smiapp-pll.h
@@ -0,0 +1,103 @@
1/*
2 * drivers/media/video/smiapp-pll.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#ifndef SMIAPP_PLL_H
26#define SMIAPP_PLL_H
27
28#include <linux/device.h>
29
30struct smiapp_pll {
31 uint8_t lanes;
32 uint8_t binning_horizontal;
33 uint8_t binning_vertical;
34 uint8_t scale_m;
35 uint8_t scale_n;
36 uint8_t bits_per_pixel;
37 uint16_t flags;
38 uint32_t link_freq;
39
40 uint16_t pre_pll_clk_div;
41 uint16_t pll_multiplier;
42 uint16_t op_sys_clk_div;
43 uint16_t op_pix_clk_div;
44 uint16_t vt_sys_clk_div;
45 uint16_t vt_pix_clk_div;
46
47 uint32_t ext_clk_freq_hz;
48 uint32_t pll_ip_clk_freq_hz;
49 uint32_t pll_op_clk_freq_hz;
50 uint32_t op_sys_clk_freq_hz;
51 uint32_t op_pix_clk_freq_hz;
52 uint32_t vt_sys_clk_freq_hz;
53 uint32_t vt_pix_clk_freq_hz;
54
55 uint32_t pixel_rate_csi;
56};
57
58struct smiapp_pll_limits {
59 /* Strict PLL limits */
60 uint32_t min_ext_clk_freq_hz;
61 uint32_t max_ext_clk_freq_hz;
62 uint16_t min_pre_pll_clk_div;
63 uint16_t max_pre_pll_clk_div;
64 uint32_t min_pll_ip_freq_hz;
65 uint32_t max_pll_ip_freq_hz;
66 uint16_t min_pll_multiplier;
67 uint16_t max_pll_multiplier;
68 uint32_t min_pll_op_freq_hz;
69 uint32_t max_pll_op_freq_hz;
70
71 uint16_t min_vt_sys_clk_div;
72 uint16_t max_vt_sys_clk_div;
73 uint32_t min_vt_sys_clk_freq_hz;
74 uint32_t max_vt_sys_clk_freq_hz;
75 uint16_t min_vt_pix_clk_div;
76 uint16_t max_vt_pix_clk_div;
77 uint32_t min_vt_pix_clk_freq_hz;
78 uint32_t max_vt_pix_clk_freq_hz;
79
80 uint16_t min_op_sys_clk_div;
81 uint16_t max_op_sys_clk_div;
82 uint32_t min_op_sys_clk_freq_hz;
83 uint32_t max_op_sys_clk_freq_hz;
84 uint16_t min_op_pix_clk_div;
85 uint16_t max_op_pix_clk_div;
86 uint32_t min_op_pix_clk_freq_hz;
87 uint32_t max_op_pix_clk_freq_hz;
88
89 /* Other relevant limits */
90 uint32_t min_line_length_pck_bin;
91 uint32_t min_line_length_pck;
92};
93
94/* op pix clock is for all lanes in total normally */
95#define SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0)
96#define SMIAPP_PLL_FLAG_NO_OP_CLOCKS (1 << 1)
97
98struct device;
99
100int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
101 struct smiapp_pll *pll);
102
103#endif /* SMIAPP_PLL_H */
diff --git a/drivers/media/video/smiapp/Kconfig b/drivers/media/video/smiapp/Kconfig
new file mode 100644
index 000000000000..f7b35ff443bf
--- /dev/null
+++ b/drivers/media/video/smiapp/Kconfig
@@ -0,0 +1,6 @@
1config VIDEO_SMIAPP
2 tristate "SMIA++/SMIA sensor support"
3 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
4 select VIDEO_SMIAPP_PLL
5 ---help---
6 This is a generic driver for SMIA++/SMIA camera modules.
diff --git a/drivers/media/video/smiapp/Makefile b/drivers/media/video/smiapp/Makefile
new file mode 100644
index 000000000000..36b0cfa2c541
--- /dev/null
+++ b/drivers/media/video/smiapp/Makefile
@@ -0,0 +1,5 @@
1smiapp-objs += smiapp-core.o smiapp-regs.o \
2 smiapp-quirk.o smiapp-limits.o
3obj-$(CONFIG_VIDEO_SMIAPP) += smiapp.o
4
5ccflags-y += -Idrivers/media/video
diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c
new file mode 100644
index 000000000000..f518026cb67b
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-core.c
@@ -0,0 +1,2894 @@
1/*
2 * drivers/media/video/smiapp/smiapp-core.c
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2010--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
8 *
9 * Based on smiapp driver by Vimarsh Zutshi
10 * Based on jt8ev1.c by Vimarsh Zutshi
11 * Based on smia-sensor.c by Tuukka Toivonen <tuukkat76@gmail.com>
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 *
27 */
28
29#include <linux/clk.h>
30#include <linux/delay.h>
31#include <linux/device.h>
32#include <linux/gpio.h>
33#include <linux/module.h>
34#include <linux/regulator/consumer.h>
35#include <linux/v4l2-mediabus.h>
36#include <media/v4l2-device.h>
37
38#include "smiapp.h"
39
40#define SMIAPP_ALIGN_DIM(dim, flags) \
41 ((flags) & V4L2_SUBDEV_SEL_FLAG_SIZE_GE \
42 ? ALIGN((dim), 2) \
43 : (dim) & ~1)
44
45/*
46 * smiapp_module_idents - supported camera modules
47 */
48static const struct smiapp_module_ident smiapp_module_idents[] = {
49 SMIAPP_IDENT_L(0x01, 0x022b, -1, "vs6555"),
50 SMIAPP_IDENT_L(0x01, 0x022e, -1, "vw6558"),
51 SMIAPP_IDENT_L(0x07, 0x7698, -1, "ovm7698"),
52 SMIAPP_IDENT_L(0x0b, 0x4242, -1, "smiapp-003"),
53 SMIAPP_IDENT_L(0x0c, 0x208a, -1, "tcm8330md"),
54 SMIAPP_IDENT_LQ(0x0c, 0x2134, -1, "tcm8500md", &smiapp_tcm8500md_quirk),
55 SMIAPP_IDENT_L(0x0c, 0x213e, -1, "et8en2"),
56 SMIAPP_IDENT_L(0x0c, 0x2184, -1, "tcm8580md"),
57 SMIAPP_IDENT_LQ(0x0c, 0x560f, -1, "jt8ew9", &smiapp_jt8ew9_quirk),
58 SMIAPP_IDENT_LQ(0x10, 0x4141, -1, "jt8ev1", &smiapp_jt8ev1_quirk),
59 SMIAPP_IDENT_LQ(0x10, 0x4241, -1, "imx125es", &smiapp_imx125es_quirk),
60};
61
62/*
63 *
64 * Dynamic Capability Identification
65 *
66 */
67
68static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor)
69{
70 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
71 u32 fmt_model_type, fmt_model_subtype, ncol_desc, nrow_desc;
72 unsigned int i;
73 int rval;
74 int line_count = 0;
75 int embedded_start = -1, embedded_end = -1;
76 int image_start = 0;
77
78 rval = smiapp_read(sensor, SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE,
79 &fmt_model_type);
80 if (rval)
81 return rval;
82
83 rval = smiapp_read(sensor, SMIAPP_REG_U8_FRAME_FORMAT_MODEL_SUBTYPE,
84 &fmt_model_subtype);
85 if (rval)
86 return rval;
87
88 ncol_desc = (fmt_model_subtype
89 & SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_MASK)
90 >> SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_SHIFT;
91 nrow_desc = fmt_model_subtype
92 & SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NROWS_MASK;
93
94 dev_dbg(&client->dev, "format_model_type %s\n",
95 fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE
96 ? "2 byte" :
97 fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE
98 ? "4 byte" : "is simply bad");
99
100 for (i = 0; i < ncol_desc + nrow_desc; i++) {
101 u32 desc;
102 u32 pixelcode;
103 u32 pixels;
104 char *which;
105 char *what;
106
107 if (fmt_model_type == SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE) {
108 rval = smiapp_read(
109 sensor,
110 SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(i),
111 &desc);
112 if (rval)
113 return rval;
114
115 pixelcode =
116 (desc
117 & SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_MASK)
118 >> SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_SHIFT;
119 pixels = desc & SMIAPP_FRAME_FORMAT_DESC_2_PIXELS_MASK;
120 } else if (fmt_model_type
121 == SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE) {
122 rval = smiapp_read(
123 sensor,
124 SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(i),
125 &desc);
126 if (rval)
127 return rval;
128
129 pixelcode =
130 (desc
131 & SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_MASK)
132 >> SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_SHIFT;
133 pixels = desc & SMIAPP_FRAME_FORMAT_DESC_4_PIXELS_MASK;
134 } else {
135 dev_dbg(&client->dev,
136 "invalid frame format model type %d\n",
137 fmt_model_type);
138 return -EINVAL;
139 }
140
141 if (i < ncol_desc)
142 which = "columns";
143 else
144 which = "rows";
145
146 switch (pixelcode) {
147 case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED:
148 what = "embedded";
149 break;
150 case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DUMMY:
151 what = "dummy";
152 break;
153 case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_BLACK:
154 what = "black";
155 break;
156 case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DARK:
157 what = "dark";
158 break;
159 case SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE:
160 what = "visible";
161 break;
162 default:
163 what = "invalid";
164 dev_dbg(&client->dev, "pixelcode %d\n", pixelcode);
165 break;
166 }
167
168 dev_dbg(&client->dev, "%s pixels: %d %s\n",
169 what, pixels, which);
170
171 if (i < ncol_desc)
172 continue;
173
174 /* Handle row descriptors */
175 if (pixelcode
176 == SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED) {
177 embedded_start = line_count;
178 } else {
179 if (pixelcode == SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE
180 || pixels >= sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES] / 2)
181 image_start = line_count;
182 if (embedded_start != -1 && embedded_end == -1)
183 embedded_end = line_count;
184 }
185 line_count += pixels;
186 }
187
188 if (embedded_start == -1 || embedded_end == -1) {
189 embedded_start = 0;
190 embedded_end = 0;
191 }
192
193 dev_dbg(&client->dev, "embedded data from lines %d to %d\n",
194 embedded_start, embedded_end);
195 dev_dbg(&client->dev, "image data starts at line %d\n", image_start);
196
197 return 0;
198}
199
200static int smiapp_pll_configure(struct smiapp_sensor *sensor)
201{
202 struct smiapp_pll *pll = &sensor->pll;
203 int rval;
204
205 rval = smiapp_write(
206 sensor, SMIAPP_REG_U16_VT_PIX_CLK_DIV, pll->vt_pix_clk_div);
207 if (rval < 0)
208 return rval;
209
210 rval = smiapp_write(
211 sensor, SMIAPP_REG_U16_VT_SYS_CLK_DIV, pll->vt_sys_clk_div);
212 if (rval < 0)
213 return rval;
214
215 rval = smiapp_write(
216 sensor, SMIAPP_REG_U16_PRE_PLL_CLK_DIV, pll->pre_pll_clk_div);
217 if (rval < 0)
218 return rval;
219
220 rval = smiapp_write(
221 sensor, SMIAPP_REG_U16_PLL_MULTIPLIER, pll->pll_multiplier);
222 if (rval < 0)
223 return rval;
224
225 /* Lane op clock ratio does not apply here. */
226 rval = smiapp_write(
227 sensor, SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS,
228 DIV_ROUND_UP(pll->op_sys_clk_freq_hz, 1000000 / 256 / 256));
229 if (rval < 0 || sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
230 return rval;
231
232 rval = smiapp_write(
233 sensor, SMIAPP_REG_U16_OP_PIX_CLK_DIV, pll->op_pix_clk_div);
234 if (rval < 0)
235 return rval;
236
237 return smiapp_write(
238 sensor, SMIAPP_REG_U16_OP_SYS_CLK_DIV, pll->op_sys_clk_div);
239}
240
241static int smiapp_pll_update(struct smiapp_sensor *sensor)
242{
243 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
244 struct smiapp_pll_limits lim = {
245 .min_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_PRE_PLL_CLK_DIV],
246 .max_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_PRE_PLL_CLK_DIV],
247 .min_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ],
248 .max_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_IP_FREQ_HZ],
249 .min_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MIN_PLL_MULTIPLIER],
250 .max_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MAX_PLL_MULTIPLIER],
251 .min_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ],
252 .max_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ],
253
254 .min_op_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV],
255 .max_op_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV],
256 .min_op_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV],
257 .max_op_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV],
258 .min_op_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ],
259 .max_op_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ],
260 .min_op_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ],
261 .max_op_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ],
262
263 .min_vt_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV],
264 .max_vt_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV],
265 .min_vt_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV],
266 .max_vt_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV],
267 .min_vt_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ],
268 .max_vt_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ],
269 .min_vt_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ],
270 .max_vt_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ],
271
272 .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN],
273 .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK],
274 };
275 struct smiapp_pll *pll = &sensor->pll;
276 int rval;
277
278 memset(&sensor->pll, 0, sizeof(sensor->pll));
279
280 pll->lanes = sensor->platform_data->lanes;
281 pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
282
283 if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) {
284 /*
285 * Fill in operational clock divisors limits from the
286 * video timing ones. On profile 0 sensors the
287 * requirements regarding them are essentially the
288 * same as on VT ones.
289 */
290 lim.min_op_sys_clk_div = lim.min_vt_sys_clk_div;
291 lim.max_op_sys_clk_div = lim.max_vt_sys_clk_div;
292 lim.min_op_pix_clk_div = lim.min_vt_pix_clk_div;
293 lim.max_op_pix_clk_div = lim.max_vt_pix_clk_div;
294 lim.min_op_sys_clk_freq_hz = lim.min_vt_sys_clk_freq_hz;
295 lim.max_op_sys_clk_freq_hz = lim.max_vt_sys_clk_freq_hz;
296 lim.min_op_pix_clk_freq_hz = lim.min_vt_pix_clk_freq_hz;
297 lim.max_op_pix_clk_freq_hz = lim.max_vt_pix_clk_freq_hz;
298 /* Profile 0 sensors have no separate OP clock branch. */
299 pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
300 }
301
302 if (smiapp_needs_quirk(sensor,
303 SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE))
304 pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
305
306 pll->binning_horizontal = sensor->binning_horizontal;
307 pll->binning_vertical = sensor->binning_vertical;
308 pll->link_freq =
309 sensor->link_freq->qmenu_int[sensor->link_freq->val];
310 pll->scale_m = sensor->scale_m;
311 pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
312 pll->bits_per_pixel = sensor->csi_format->compressed;
313
314 rval = smiapp_pll_calculate(&client->dev, &lim, pll);
315 if (rval < 0)
316 return rval;
317
318 sensor->pixel_rate_parray->cur.val64 = pll->vt_pix_clk_freq_hz;
319 sensor->pixel_rate_csi->cur.val64 = pll->pixel_rate_csi;
320
321 return 0;
322}
323
324
325/*
326 *
327 * V4L2 Controls handling
328 *
329 */
330
331static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
332{
333 struct v4l2_ctrl *ctrl = sensor->exposure;
334 int max;
335
336 max = sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
337 + sensor->vblank->val
338 - sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
339
340 ctrl->maximum = max;
341 if (ctrl->default_value > max)
342 ctrl->default_value = max;
343 if (ctrl->val > max)
344 ctrl->val = max;
345 if (ctrl->cur.val > max)
346 ctrl->cur.val = max;
347}
348
349/*
350 * Order matters.
351 *
352 * 1. Bits-per-pixel, descending.
353 * 2. Bits-per-pixel compressed, descending.
354 * 3. Pixel order, same as in pixel_order_str. Formats for all four pixel
355 * orders must be defined.
356 */
357static const struct smiapp_csi_data_format smiapp_csi_data_formats[] = {
358 { V4L2_MBUS_FMT_SGRBG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GRBG, },
359 { V4L2_MBUS_FMT_SRGGB12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_RGGB, },
360 { V4L2_MBUS_FMT_SBGGR12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_BGGR, },
361 { V4L2_MBUS_FMT_SGBRG12_1X12, 12, 12, SMIAPP_PIXEL_ORDER_GBRG, },
362 { V4L2_MBUS_FMT_SGRBG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GRBG, },
363 { V4L2_MBUS_FMT_SRGGB10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_RGGB, },
364 { V4L2_MBUS_FMT_SBGGR10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_BGGR, },
365 { V4L2_MBUS_FMT_SGBRG10_1X10, 10, 10, SMIAPP_PIXEL_ORDER_GBRG, },
366 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GRBG, },
367 { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_RGGB, },
368 { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_BGGR, },
369 { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 10, 8, SMIAPP_PIXEL_ORDER_GBRG, },
370 { V4L2_MBUS_FMT_SGRBG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GRBG, },
371 { V4L2_MBUS_FMT_SRGGB8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_RGGB, },
372 { V4L2_MBUS_FMT_SBGGR8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_BGGR, },
373 { V4L2_MBUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, },
374};
375
376const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" };
377
378#define to_csi_format_idx(fmt) (((unsigned long)(fmt) \
379 - (unsigned long)smiapp_csi_data_formats) \
380 / sizeof(*smiapp_csi_data_formats))
381
382static u32 smiapp_pixel_order(struct smiapp_sensor *sensor)
383{
384 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
385 int flip = 0;
386
387 if (sensor->hflip) {
388 if (sensor->hflip->val)
389 flip |= SMIAPP_IMAGE_ORIENTATION_HFLIP;
390
391 if (sensor->vflip->val)
392 flip |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
393 }
394
395 flip ^= sensor->hvflip_inv_mask;
396
397 dev_dbg(&client->dev, "flip %d\n", flip);
398 return sensor->default_pixel_order ^ flip;
399}
400
401static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor)
402{
403 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
404 unsigned int csi_format_idx =
405 to_csi_format_idx(sensor->csi_format) & ~3;
406 unsigned int internal_csi_format_idx =
407 to_csi_format_idx(sensor->internal_csi_format) & ~3;
408 unsigned int pixel_order = smiapp_pixel_order(sensor);
409
410 sensor->mbus_frame_fmts =
411 sensor->default_mbus_frame_fmts << pixel_order;
412 sensor->csi_format =
413 &smiapp_csi_data_formats[csi_format_idx + pixel_order];
414 sensor->internal_csi_format =
415 &smiapp_csi_data_formats[internal_csi_format_idx
416 + pixel_order];
417
418 BUG_ON(max(internal_csi_format_idx, csi_format_idx) + pixel_order
419 >= ARRAY_SIZE(smiapp_csi_data_formats));
420 BUG_ON(min(internal_csi_format_idx, csi_format_idx) < 0);
421
422 dev_dbg(&client->dev, "new pixel order %s\n",
423 pixel_order_str[pixel_order]);
424}
425
426static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
427{
428 struct smiapp_sensor *sensor =
429 container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
430 ->sensor;
431 u32 orient = 0;
432 int exposure;
433 int rval;
434
435 switch (ctrl->id) {
436 case V4L2_CID_ANALOGUE_GAIN:
437 return smiapp_write(
438 sensor,
439 SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
440
441 case V4L2_CID_EXPOSURE:
442 return smiapp_write(
443 sensor,
444 SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
445
446 case V4L2_CID_HFLIP:
447 case V4L2_CID_VFLIP:
448 if (sensor->streaming)
449 return -EBUSY;
450
451 if (sensor->hflip->val)
452 orient |= SMIAPP_IMAGE_ORIENTATION_HFLIP;
453
454 if (sensor->vflip->val)
455 orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
456
457 orient ^= sensor->hvflip_inv_mask;
458 rval = smiapp_write(sensor,
459 SMIAPP_REG_U8_IMAGE_ORIENTATION,
460 orient);
461 if (rval < 0)
462 return rval;
463
464 smiapp_update_mbus_formats(sensor);
465
466 return 0;
467
468 case V4L2_CID_VBLANK:
469 exposure = sensor->exposure->val;
470
471 __smiapp_update_exposure_limits(sensor);
472
473 if (exposure > sensor->exposure->maximum) {
474 sensor->exposure->val =
475 sensor->exposure->maximum;
476 rval = smiapp_set_ctrl(
477 sensor->exposure);
478 if (rval < 0)
479 return rval;
480 }
481
482 return smiapp_write(
483 sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
484 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
485 + ctrl->val);
486
487 case V4L2_CID_HBLANK:
488 return smiapp_write(
489 sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
490 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
491 + ctrl->val);
492
493 case V4L2_CID_LINK_FREQ:
494 if (sensor->streaming)
495 return -EBUSY;
496
497 return smiapp_pll_update(sensor);
498
499 default:
500 return -EINVAL;
501 }
502}
503
504static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
505 .s_ctrl = smiapp_set_ctrl,
506};
507
508static int smiapp_init_controls(struct smiapp_sensor *sensor)
509{
510 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
511 unsigned int max;
512 int rval;
513
514 rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 7);
515 if (rval)
516 return rval;
517 sensor->pixel_array->ctrl_handler.lock = &sensor->mutex;
518
519 sensor->analog_gain = v4l2_ctrl_new_std(
520 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
521 V4L2_CID_ANALOGUE_GAIN,
522 sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN],
523 sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX],
524 max(sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_STEP], 1U),
525 sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN]);
526
527 /* Exposure limits will be updated soon, use just something here. */
528 sensor->exposure = v4l2_ctrl_new_std(
529 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
530 V4L2_CID_EXPOSURE, 0, 0, 1, 0);
531
532 sensor->hflip = v4l2_ctrl_new_std(
533 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
534 V4L2_CID_HFLIP, 0, 1, 1, 0);
535 sensor->vflip = v4l2_ctrl_new_std(
536 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
537 V4L2_CID_VFLIP, 0, 1, 1, 0);
538
539 sensor->vblank = v4l2_ctrl_new_std(
540 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
541 V4L2_CID_VBLANK, 0, 1, 1, 0);
542
543 if (sensor->vblank)
544 sensor->vblank->flags |= V4L2_CTRL_FLAG_UPDATE;
545
546 sensor->hblank = v4l2_ctrl_new_std(
547 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
548 V4L2_CID_HBLANK, 0, 1, 1, 0);
549
550 if (sensor->hblank)
551 sensor->hblank->flags |= V4L2_CTRL_FLAG_UPDATE;
552
553 sensor->pixel_rate_parray = v4l2_ctrl_new_std(
554 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
555 V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
556
557 if (sensor->pixel_array->ctrl_handler.error) {
558 dev_err(&client->dev,
559 "pixel array controls initialization failed (%d)\n",
560 sensor->pixel_array->ctrl_handler.error);
561 rval = sensor->pixel_array->ctrl_handler.error;
562 goto error;
563 }
564
565 sensor->pixel_array->sd.ctrl_handler =
566 &sensor->pixel_array->ctrl_handler;
567
568 v4l2_ctrl_cluster(2, &sensor->hflip);
569
570 rval = v4l2_ctrl_handler_init(&sensor->src->ctrl_handler, 0);
571 if (rval)
572 goto error;
573 sensor->src->ctrl_handler.lock = &sensor->mutex;
574
575 for (max = 0; sensor->platform_data->op_sys_clock[max + 1]; max++);
576
577 sensor->link_freq = v4l2_ctrl_new_int_menu(
578 &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
579 V4L2_CID_LINK_FREQ, max, 0,
580 sensor->platform_data->op_sys_clock);
581
582 sensor->pixel_rate_csi = v4l2_ctrl_new_std(
583 &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
584 V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
585
586 if (sensor->src->ctrl_handler.error) {
587 dev_err(&client->dev,
588 "src controls initialization failed (%d)\n",
589 sensor->src->ctrl_handler.error);
590 rval = sensor->src->ctrl_handler.error;
591 goto error;
592 }
593
594 sensor->src->sd.ctrl_handler =
595 &sensor->src->ctrl_handler;
596
597 return 0;
598
599error:
600 v4l2_ctrl_handler_free(&sensor->pixel_array->ctrl_handler);
601 v4l2_ctrl_handler_free(&sensor->src->ctrl_handler);
602
603 return rval;
604}
605
606static void smiapp_free_controls(struct smiapp_sensor *sensor)
607{
608 unsigned int i;
609
610 for (i = 0; i < sensor->ssds_used; i++)
611 v4l2_ctrl_handler_free(&sensor->ssds[i].ctrl_handler);
612}
613
614static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit,
615 unsigned int n)
616{
617 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
618 unsigned int i;
619 u32 val;
620 int rval;
621
622 for (i = 0; i < n; i++) {
623 rval = smiapp_read(
624 sensor, smiapp_reg_limits[limit[i]].addr, &val);
625 if (rval)
626 return rval;
627 sensor->limits[limit[i]] = val;
628 dev_dbg(&client->dev, "0x%8.8x \"%s\" = %d, 0x%x\n",
629 smiapp_reg_limits[limit[i]].addr,
630 smiapp_reg_limits[limit[i]].what, val, val);
631 }
632
633 return 0;
634}
635
636static int smiapp_get_all_limits(struct smiapp_sensor *sensor)
637{
638 unsigned int i;
639 int rval;
640
641 for (i = 0; i < SMIAPP_LIMIT_LAST; i++) {
642 rval = smiapp_get_limits(sensor, &i, 1);
643 if (rval < 0)
644 return rval;
645 }
646
647 if (sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] == 0)
648 smiapp_replace_limit(sensor, SMIAPP_LIMIT_SCALER_N_MIN, 16);
649
650 return 0;
651}
652
653static int smiapp_get_limits_binning(struct smiapp_sensor *sensor)
654{
655 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
656 static u32 const limits[] = {
657 SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN,
658 SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN,
659 SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN,
660 SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN,
661 SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN,
662 SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN_BIN,
663 SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN,
664 };
665 static u32 const limits_replace[] = {
666 SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES,
667 SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES,
668 SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK,
669 SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK,
670 SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK,
671 SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN,
672 SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN,
673 };
674 unsigned int i;
675 int rval;
676
677 if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY] ==
678 SMIAPP_BINNING_CAPABILITY_NO) {
679 for (i = 0; i < ARRAY_SIZE(limits); i++)
680 sensor->limits[limits[i]] =
681 sensor->limits[limits_replace[i]];
682
683 return 0;
684 }
685
686 rval = smiapp_get_limits(sensor, limits, ARRAY_SIZE(limits));
687 if (rval < 0)
688 return rval;
689
690 /*
691 * Sanity check whether the binning limits are valid. If not,
692 * use the non-binning ones.
693 */
694 if (sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN]
695 && sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN]
696 && sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN])
697 return 0;
698
699 for (i = 0; i < ARRAY_SIZE(limits); i++) {
700 dev_dbg(&client->dev,
701 "replace limit 0x%8.8x \"%s\" = %d, 0x%x\n",
702 smiapp_reg_limits[limits[i]].addr,
703 smiapp_reg_limits[limits[i]].what,
704 sensor->limits[limits_replace[i]],
705 sensor->limits[limits_replace[i]]);
706 sensor->limits[limits[i]] =
707 sensor->limits[limits_replace[i]];
708 }
709
710 return 0;
711}
712
713static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
714{
715 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
716 unsigned int type, n;
717 unsigned int i, pixel_order;
718 int rval;
719
720 rval = smiapp_read(
721 sensor, SMIAPP_REG_U8_DATA_FORMAT_MODEL_TYPE, &type);
722 if (rval)
723 return rval;
724
725 dev_dbg(&client->dev, "data_format_model_type %d\n", type);
726
727 rval = smiapp_read(sensor, SMIAPP_REG_U8_PIXEL_ORDER,
728 &pixel_order);
729 if (rval)
730 return rval;
731
732 if (pixel_order >= ARRAY_SIZE(pixel_order_str)) {
733 dev_dbg(&client->dev, "bad pixel order %d\n", pixel_order);
734 return -EINVAL;
735 }
736
737 dev_dbg(&client->dev, "pixel order %d (%s)\n", pixel_order,
738 pixel_order_str[pixel_order]);
739
740 switch (type) {
741 case SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL:
742 n = SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL_N;
743 break;
744 case SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED:
745 n = SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED_N;
746 break;
747 default:
748 return -EINVAL;
749 }
750
751 sensor->default_pixel_order = pixel_order;
752 sensor->mbus_frame_fmts = 0;
753
754 for (i = 0; i < n; i++) {
755 unsigned int fmt, j;
756
757 rval = smiapp_read(
758 sensor,
759 SMIAPP_REG_U16_DATA_FORMAT_DESCRIPTOR(i), &fmt);
760 if (rval)
761 return rval;
762
763 dev_dbg(&client->dev, "bpp %d, compressed %d\n",
764 fmt >> 8, (u8)fmt);
765
766 for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) {
767 const struct smiapp_csi_data_format *f =
768 &smiapp_csi_data_formats[j];
769
770 if (f->pixel_order != SMIAPP_PIXEL_ORDER_GRBG)
771 continue;
772
773 if (f->width != fmt >> 8 || f->compressed != (u8)fmt)
774 continue;
775
776 dev_dbg(&client->dev, "jolly good! %d\n", j);
777
778 sensor->default_mbus_frame_fmts |= 1 << j;
779 if (!sensor->csi_format) {
780 sensor->csi_format = f;
781 sensor->internal_csi_format = f;
782 }
783 }
784 }
785
786 if (!sensor->csi_format) {
787 dev_err(&client->dev, "no supported mbus code found\n");
788 return -EINVAL;
789 }
790
791 smiapp_update_mbus_formats(sensor);
792
793 return 0;
794}
795
796static void smiapp_update_blanking(struct smiapp_sensor *sensor)
797{
798 struct v4l2_ctrl *vblank = sensor->vblank;
799 struct v4l2_ctrl *hblank = sensor->hblank;
800
801 vblank->minimum =
802 max_t(int,
803 sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
804 sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
805 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
806 vblank->maximum =
807 sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
808 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
809
810 vblank->val = clamp_t(int, vblank->val,
811 vblank->minimum, vblank->maximum);
812 vblank->default_value = vblank->minimum;
813 vblank->val = vblank->val;
814 vblank->cur.val = vblank->val;
815
816 hblank->minimum =
817 max_t(int,
818 sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
819 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
820 sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
821 hblank->maximum =
822 sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
823 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width;
824
825 hblank->val = clamp_t(int, hblank->val,
826 hblank->minimum, hblank->maximum);
827 hblank->default_value = hblank->minimum;
828 hblank->val = hblank->val;
829 hblank->cur.val = hblank->val;
830
831 __smiapp_update_exposure_limits(sensor);
832}
833
834static int smiapp_update_mode(struct smiapp_sensor *sensor)
835{
836 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
837 unsigned int binning_mode;
838 int rval;
839
840 dev_dbg(&client->dev, "frame size: %dx%d\n",
841 sensor->src->crop[SMIAPP_PAD_SRC].width,
842 sensor->src->crop[SMIAPP_PAD_SRC].height);
843 dev_dbg(&client->dev, "csi format width: %d\n",
844 sensor->csi_format->width);
845
846 /* Binning has to be set up here; it affects limits */
847 if (sensor->binning_horizontal == 1 &&
848 sensor->binning_vertical == 1) {
849 binning_mode = 0;
850 } else {
851 u8 binning_type =
852 (sensor->binning_horizontal << 4)
853 | sensor->binning_vertical;
854
855 rval = smiapp_write(
856 sensor, SMIAPP_REG_U8_BINNING_TYPE, binning_type);
857 if (rval < 0)
858 return rval;
859
860 binning_mode = 1;
861 }
862 rval = smiapp_write(sensor, SMIAPP_REG_U8_BINNING_MODE, binning_mode);
863 if (rval < 0)
864 return rval;
865
866 /* Get updated limits due to binning */
867 rval = smiapp_get_limits_binning(sensor);
868 if (rval < 0)
869 return rval;
870
871 rval = smiapp_pll_update(sensor);
872 if (rval < 0)
873 return rval;
874
875 /* Output from pixel array, including blanking */
876 smiapp_update_blanking(sensor);
877
878 dev_dbg(&client->dev, "vblank\t\t%d\n", sensor->vblank->val);
879 dev_dbg(&client->dev, "hblank\t\t%d\n", sensor->hblank->val);
880
881 dev_dbg(&client->dev, "real timeperframe\t100/%d\n",
882 sensor->pll.vt_pix_clk_freq_hz /
883 ((sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
884 + sensor->hblank->val) *
885 (sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
886 + sensor->vblank->val) / 100));
887
888 return 0;
889}
890
891/*
892 *
893 * SMIA++ NVM handling
894 *
895 */
896static int smiapp_read_nvm(struct smiapp_sensor *sensor,
897 unsigned char *nvm)
898{
899 u32 i, s, p, np, v;
900 int rval = 0, rval2;
901
902 np = sensor->nvm_size / SMIAPP_NVM_PAGE_SIZE;
903 for (p = 0; p < np; p++) {
904 rval = smiapp_write(
905 sensor,
906 SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT, p);
907 if (rval)
908 goto out;
909
910 rval = smiapp_write(sensor,
911 SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL,
912 SMIAPP_DATA_TRANSFER_IF_1_CTRL_EN |
913 SMIAPP_DATA_TRANSFER_IF_1_CTRL_RD_EN);
914 if (rval)
915 goto out;
916
917 for (i = 0; i < 1000; i++) {
918 rval = smiapp_read(
919 sensor,
920 SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS, &s);
921
922 if (rval)
923 goto out;
924
925 if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)
926 break;
927
928 if (--i == 0) {
929 rval = -ETIMEDOUT;
930 goto out;
931 }
932
933 }
934
935 for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) {
936 rval = smiapp_read(
937 sensor,
938 SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 + i,
939 &v);
940 if (rval)
941 goto out;
942
943 *nvm++ = v;
944 }
945 }
946
947out:
948 rval2 = smiapp_write(sensor, SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL, 0);
949 if (rval < 0)
950 return rval;
951 else
952 return rval2;
953}
954
955/*
956 *
957 * SMIA++ CCI address control
958 *
959 */
960static int smiapp_change_cci_addr(struct smiapp_sensor *sensor)
961{
962 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
963 int rval;
964 u32 val;
965
966 client->addr = sensor->platform_data->i2c_addr_dfl;
967
968 rval = smiapp_write(sensor,
969 SMIAPP_REG_U8_CCI_ADDRESS_CONTROL,
970 sensor->platform_data->i2c_addr_alt << 1);
971 if (rval)
972 return rval;
973
974 client->addr = sensor->platform_data->i2c_addr_alt;
975
976 /* verify addr change went ok */
977 rval = smiapp_read(sensor, SMIAPP_REG_U8_CCI_ADDRESS_CONTROL, &val);
978 if (rval)
979 return rval;
980
981 if (val != sensor->platform_data->i2c_addr_alt << 1)
982 return -ENODEV;
983
984 return 0;
985}
986
987/*
988 *
989 * SMIA++ Mode Control
990 *
991 */
992static int smiapp_setup_flash_strobe(struct smiapp_sensor *sensor)
993{
994 struct smiapp_flash_strobe_parms *strobe_setup;
995 unsigned int ext_freq = sensor->platform_data->ext_clk;
996 u32 tmp;
997 u32 strobe_adjustment;
998 u32 strobe_width_high_rs;
999 int rval;
1000
1001 strobe_setup = sensor->platform_data->strobe_setup;
1002
1003 /*
1004 * How to calculate registers related to strobe length. Please
1005 * do not change, or if you do at least know what you're
1006 * doing. :-)
1007 *
1008 * Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> 2010-10-25
1009 *
1010 * flash_strobe_length [us] / 10^6 = (tFlash_strobe_width_ctrl
1011 * / EXTCLK freq [Hz]) * flash_strobe_adjustment
1012 *
1013 * tFlash_strobe_width_ctrl E N, [1 - 0xffff]
1014 * flash_strobe_adjustment E N, [1 - 0xff]
1015 *
1016 * The formula above is written as below to keep it on one
1017 * line:
1018 *
1019 * l / 10^6 = w / e * a
1020 *
1021 * Let's mark w * a by x:
1022 *
1023 * x = w * a
1024 *
1025 * Thus, we get:
1026 *
1027 * x = l * e / 10^6
1028 *
1029 * The strobe width must be at least as long as requested,
1030 * thus rounding upwards is needed.
1031 *
1032 * x = (l * e + 10^6 - 1) / 10^6
1033 * -----------------------------
1034 *
1035 * Maximum possible accuracy is wanted at all times. Thus keep
1036 * a as small as possible.
1037 *
1038 * Calculate a, assuming maximum w, with rounding upwards:
1039 *
1040 * a = (x + (2^16 - 1) - 1) / (2^16 - 1)
1041 * -------------------------------------
1042 *
1043 * Thus, we also get w, with that a, with rounding upwards:
1044 *
1045 * w = (x + a - 1) / a
1046 * -------------------
1047 *
1048 * To get limits:
1049 *
1050 * x E [1, (2^16 - 1) * (2^8 - 1)]
1051 *
1052 * Substituting maximum x to the original formula (with rounding),
1053 * the maximum l is thus
1054 *
1055 * (2^16 - 1) * (2^8 - 1) * 10^6 = l * e + 10^6 - 1
1056 *
1057 * l = (10^6 * (2^16 - 1) * (2^8 - 1) - 10^6 + 1) / e
1058 * --------------------------------------------------
1059 *
1060 * flash_strobe_length must be clamped between 1 and
1061 * (10^6 * (2^16 - 1) * (2^8 - 1) - 10^6 + 1) / EXTCLK freq.
1062 *
1063 * Then,
1064 *
1065 * flash_strobe_adjustment = ((flash_strobe_length *
1066 * EXTCLK freq + 10^6 - 1) / 10^6 + (2^16 - 1) - 1) / (2^16 - 1)
1067 *
1068 * tFlash_strobe_width_ctrl = ((flash_strobe_length *
1069 * EXTCLK freq + 10^6 - 1) / 10^6 +
1070 * flash_strobe_adjustment - 1) / flash_strobe_adjustment
1071 */
1072 tmp = div_u64(1000000ULL * ((1 << 16) - 1) * ((1 << 8) - 1) -
1073 1000000 + 1, ext_freq);
1074 strobe_setup->strobe_width_high_us =
1075 clamp_t(u32, strobe_setup->strobe_width_high_us, 1, tmp);
1076
1077 tmp = div_u64(((u64)strobe_setup->strobe_width_high_us * (u64)ext_freq +
1078 1000000 - 1), 1000000ULL);
1079 strobe_adjustment = (tmp + (1 << 16) - 1 - 1) / ((1 << 16) - 1);
1080 strobe_width_high_rs = (tmp + strobe_adjustment - 1) /
1081 strobe_adjustment;
1082
1083 rval = smiapp_write(sensor, SMIAPP_REG_U8_FLASH_MODE_RS,
1084 strobe_setup->mode);
1085 if (rval < 0)
1086 goto out;
1087
1088 rval = smiapp_write(sensor, SMIAPP_REG_U8_FLASH_STROBE_ADJUSTMENT,
1089 strobe_adjustment);
1090 if (rval < 0)
1091 goto out;
1092
1093 rval = smiapp_write(
1094 sensor, SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_RS_CTRL,
1095 strobe_width_high_rs);
1096 if (rval < 0)
1097 goto out;
1098
1099 rval = smiapp_write(sensor, SMIAPP_REG_U16_TFLASH_STROBE_DELAY_RS_CTRL,
1100 strobe_setup->strobe_delay);
1101 if (rval < 0)
1102 goto out;
1103
1104 rval = smiapp_write(sensor, SMIAPP_REG_U16_FLASH_STROBE_START_POINT,
1105 strobe_setup->stobe_start_point);
1106 if (rval < 0)
1107 goto out;
1108
1109 rval = smiapp_write(sensor, SMIAPP_REG_U8_FLASH_TRIGGER_RS,
1110 strobe_setup->trigger);
1111
1112out:
1113 sensor->platform_data->strobe_setup->trigger = 0;
1114
1115 return rval;
1116}
1117
1118/* -----------------------------------------------------------------------------
1119 * Power management
1120 */
1121
1122static int smiapp_power_on(struct smiapp_sensor *sensor)
1123{
1124 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
1125 unsigned int sleep;
1126 int rval;
1127
1128 rval = regulator_enable(sensor->vana);
1129 if (rval) {
1130 dev_err(&client->dev, "failed to enable vana regulator\n");
1131 return rval;
1132 }
1133 usleep_range(1000, 1000);
1134
1135 if (sensor->platform_data->set_xclk)
1136 rval = sensor->platform_data->set_xclk(
1137 &sensor->src->sd, sensor->platform_data->ext_clk);
1138 else
1139 rval = clk_enable(sensor->ext_clk);
1140 if (rval < 0) {
1141 dev_dbg(&client->dev, "failed to set xclk\n");
1142 goto out_xclk_fail;
1143 }
1144 usleep_range(1000, 1000);
1145
1146 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
1147 gpio_set_value(sensor->platform_data->xshutdown, 1);
1148
1149 sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk);
1150 usleep_range(sleep, sleep);
1151
1152 /*
1153 * Failures to respond to the address change command have been noticed.
1154 * Those failures seem to be caused by the sensor requiring a longer
1155 * boot time than advertised. An additional 10ms delay seems to work
1156 * around the issue, but the SMIA++ I2C write retry hack makes the delay
1157 * unnecessary. The failures need to be investigated to find a proper
1158 * fix, and a delay will likely need to be added here if the I2C write
1159 * retry hack is reverted before the root cause of the boot time issue
1160 * is found.
1161 */
1162
1163 if (sensor->platform_data->i2c_addr_alt) {
1164 rval = smiapp_change_cci_addr(sensor);
1165 if (rval) {
1166 dev_err(&client->dev, "cci address change error\n");
1167 goto out_cci_addr_fail;
1168 }
1169 }
1170
1171 rval = smiapp_write(sensor, SMIAPP_REG_U8_SOFTWARE_RESET,
1172 SMIAPP_SOFTWARE_RESET);
1173 if (rval < 0) {
1174 dev_err(&client->dev, "software reset failed\n");
1175 goto out_cci_addr_fail;
1176 }
1177
1178 if (sensor->platform_data->i2c_addr_alt) {
1179 rval = smiapp_change_cci_addr(sensor);
1180 if (rval) {
1181 dev_err(&client->dev, "cci address change error\n");
1182 goto out_cci_addr_fail;
1183 }
1184 }
1185
1186 rval = smiapp_write(sensor, SMIAPP_REG_U16_COMPRESSION_MODE,
1187 SMIAPP_COMPRESSION_MODE_SIMPLE_PREDICTOR);
1188 if (rval) {
1189 dev_err(&client->dev, "compression mode set failed\n");
1190 goto out_cci_addr_fail;
1191 }
1192
1193 rval = smiapp_write(
1194 sensor, SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ,
1195 sensor->platform_data->ext_clk / (1000000 / (1 << 8)));
1196 if (rval) {
1197 dev_err(&client->dev, "extclk frequency set failed\n");
1198 goto out_cci_addr_fail;
1199 }
1200
1201 rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_LANE_MODE,
1202 sensor->platform_data->lanes - 1);
1203 if (rval) {
1204 dev_err(&client->dev, "csi lane mode set failed\n");
1205 goto out_cci_addr_fail;
1206 }
1207
1208 rval = smiapp_write(sensor, SMIAPP_REG_U8_FAST_STANDBY_CTRL,
1209 SMIAPP_FAST_STANDBY_CTRL_IMMEDIATE);
1210 if (rval) {
1211 dev_err(&client->dev, "fast standby set failed\n");
1212 goto out_cci_addr_fail;
1213 }
1214
1215 rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_SIGNALLING_MODE,
1216 sensor->platform_data->csi_signalling_mode);
1217 if (rval) {
1218 dev_err(&client->dev, "csi signalling mode set failed\n");
1219 goto out_cci_addr_fail;
1220 }
1221
1222 /* DPHY control done by sensor based on requested link rate */
1223 rval = smiapp_write(sensor, SMIAPP_REG_U8_DPHY_CTRL,
1224 SMIAPP_DPHY_CTRL_UI);
1225 if (rval < 0)
1226 return rval;
1227
1228 rval = smiapp_call_quirk(sensor, post_poweron);
1229 if (rval) {
1230 dev_err(&client->dev, "post_poweron quirks failed\n");
1231 goto out_cci_addr_fail;
1232 }
1233
1234 /* Are we still initialising...? If yes, return here. */
1235 if (!sensor->pixel_array)
1236 return 0;
1237
1238 rval = v4l2_ctrl_handler_setup(
1239 &sensor->pixel_array->ctrl_handler);
1240 if (rval)
1241 goto out_cci_addr_fail;
1242
1243 rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
1244 if (rval)
1245 goto out_cci_addr_fail;
1246
1247 mutex_lock(&sensor->mutex);
1248 rval = smiapp_update_mode(sensor);
1249 mutex_unlock(&sensor->mutex);
1250 if (rval < 0)
1251 goto out_cci_addr_fail;
1252
1253 return 0;
1254
1255out_cci_addr_fail:
1256 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
1257 gpio_set_value(sensor->platform_data->xshutdown, 0);
1258 if (sensor->platform_data->set_xclk)
1259 sensor->platform_data->set_xclk(&sensor->src->sd, 0);
1260 else
1261 clk_disable(sensor->ext_clk);
1262
1263out_xclk_fail:
1264 regulator_disable(sensor->vana);
1265 return rval;
1266}
1267
1268static void smiapp_power_off(struct smiapp_sensor *sensor)
1269{
1270 /*
1271 * Currently power/clock to lens are enable/disabled separately
1272 * but they are essentially the same signals. So if the sensor is
1273 * powered off while the lens is powered on the sensor does not
1274 * really see a power off and next time the cci address change
1275 * will fail. So do a soft reset explicitly here.
1276 */
1277 if (sensor->platform_data->i2c_addr_alt)
1278 smiapp_write(sensor,
1279 SMIAPP_REG_U8_SOFTWARE_RESET,
1280 SMIAPP_SOFTWARE_RESET);
1281
1282 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
1283 gpio_set_value(sensor->platform_data->xshutdown, 0);
1284 if (sensor->platform_data->set_xclk)
1285 sensor->platform_data->set_xclk(&sensor->src->sd, 0);
1286 else
1287 clk_disable(sensor->ext_clk);
1288 usleep_range(5000, 5000);
1289 regulator_disable(sensor->vana);
1290 sensor->streaming = 0;
1291}
1292
1293static int smiapp_set_power(struct v4l2_subdev *subdev, int on)
1294{
1295 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1296 int ret = 0;
1297
1298 mutex_lock(&sensor->power_mutex);
1299
1300 /*
1301 * If the power count is modified from 0 to != 0 or from != 0
1302 * to 0, update the power state.
1303 */
1304 if (!sensor->power_count == !on)
1305 goto out;
1306
1307 if (on) {
1308 /* Power on and perform initialisation. */
1309 ret = smiapp_power_on(sensor);
1310 if (ret < 0)
1311 goto out;
1312 } else {
1313 smiapp_power_off(sensor);
1314 }
1315
1316 /* Update the power count. */
1317 sensor->power_count += on ? 1 : -1;
1318 WARN_ON(sensor->power_count < 0);
1319
1320out:
1321 mutex_unlock(&sensor->power_mutex);
1322 return ret;
1323}
1324
1325/* -----------------------------------------------------------------------------
1326 * Video stream management
1327 */
1328
1329static int smiapp_start_streaming(struct smiapp_sensor *sensor)
1330{
1331 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
1332 int rval;
1333
1334 mutex_lock(&sensor->mutex);
1335
1336 rval = smiapp_write(sensor, SMIAPP_REG_U16_CSI_DATA_FORMAT,
1337 (sensor->csi_format->width << 8) |
1338 sensor->csi_format->compressed);
1339 if (rval)
1340 goto out;
1341
1342 rval = smiapp_pll_configure(sensor);
1343 if (rval)
1344 goto out;
1345
1346 /* Analog crop start coordinates */
1347 rval = smiapp_write(sensor, SMIAPP_REG_U16_X_ADDR_START,
1348 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].left);
1349 if (rval < 0)
1350 goto out;
1351
1352 rval = smiapp_write(sensor, SMIAPP_REG_U16_Y_ADDR_START,
1353 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].top);
1354 if (rval < 0)
1355 goto out;
1356
1357 /* Analog crop end coordinates */
1358 rval = smiapp_write(
1359 sensor, SMIAPP_REG_U16_X_ADDR_END,
1360 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].left
1361 + sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width - 1);
1362 if (rval < 0)
1363 goto out;
1364
1365 rval = smiapp_write(
1366 sensor, SMIAPP_REG_U16_Y_ADDR_END,
1367 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].top
1368 + sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height - 1);
1369 if (rval < 0)
1370 goto out;
1371
1372 /*
1373 * Output from pixel array, including blanking, is set using
1374 * controls below. No need to set here.
1375 */
1376
1377 /* Digital crop */
1378 if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
1379 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
1380 rval = smiapp_write(
1381 sensor, SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET,
1382 sensor->scaler->crop[SMIAPP_PAD_SINK].left);
1383 if (rval < 0)
1384 goto out;
1385
1386 rval = smiapp_write(
1387 sensor, SMIAPP_REG_U16_DIGITAL_CROP_Y_OFFSET,
1388 sensor->scaler->crop[SMIAPP_PAD_SINK].top);
1389 if (rval < 0)
1390 goto out;
1391
1392 rval = smiapp_write(
1393 sensor, SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_WIDTH,
1394 sensor->scaler->crop[SMIAPP_PAD_SINK].width);
1395 if (rval < 0)
1396 goto out;
1397
1398 rval = smiapp_write(
1399 sensor, SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_HEIGHT,
1400 sensor->scaler->crop[SMIAPP_PAD_SINK].height);
1401 if (rval < 0)
1402 goto out;
1403 }
1404
1405 /* Scaling */
1406 if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
1407 != SMIAPP_SCALING_CAPABILITY_NONE) {
1408 rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALING_MODE,
1409 sensor->scaling_mode);
1410 if (rval < 0)
1411 goto out;
1412
1413 rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALE_M,
1414 sensor->scale_m);
1415 if (rval < 0)
1416 goto out;
1417 }
1418
1419 /* Output size from sensor */
1420 rval = smiapp_write(sensor, SMIAPP_REG_U16_X_OUTPUT_SIZE,
1421 sensor->src->crop[SMIAPP_PAD_SRC].width);
1422 if (rval < 0)
1423 goto out;
1424 rval = smiapp_write(sensor, SMIAPP_REG_U16_Y_OUTPUT_SIZE,
1425 sensor->src->crop[SMIAPP_PAD_SRC].height);
1426 if (rval < 0)
1427 goto out;
1428
1429 if ((sensor->flash_capability &
1430 (SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE |
1431 SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE)) &&
1432 sensor->platform_data->strobe_setup != NULL &&
1433 sensor->platform_data->strobe_setup->trigger != 0) {
1434 rval = smiapp_setup_flash_strobe(sensor);
1435 if (rval)
1436 goto out;
1437 }
1438
1439 rval = smiapp_call_quirk(sensor, pre_streamon);
1440 if (rval) {
1441 dev_err(&client->dev, "pre_streamon quirks failed\n");
1442 goto out;
1443 }
1444
1445 rval = smiapp_write(sensor, SMIAPP_REG_U8_MODE_SELECT,
1446 SMIAPP_MODE_SELECT_STREAMING);
1447
1448out:
1449 mutex_unlock(&sensor->mutex);
1450
1451 return rval;
1452}
1453
1454static int smiapp_stop_streaming(struct smiapp_sensor *sensor)
1455{
1456 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
1457 int rval;
1458
1459 mutex_lock(&sensor->mutex);
1460 rval = smiapp_write(sensor, SMIAPP_REG_U8_MODE_SELECT,
1461 SMIAPP_MODE_SELECT_SOFTWARE_STANDBY);
1462 if (rval)
1463 goto out;
1464
1465 rval = smiapp_call_quirk(sensor, post_streamoff);
1466 if (rval)
1467 dev_err(&client->dev, "post_streamoff quirks failed\n");
1468
1469out:
1470 mutex_unlock(&sensor->mutex);
1471 return rval;
1472}
1473
1474/* -----------------------------------------------------------------------------
1475 * V4L2 subdev video operations
1476 */
1477
1478static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
1479{
1480 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1481 int rval;
1482
1483 if (sensor->streaming == enable)
1484 return 0;
1485
1486 if (enable) {
1487 sensor->streaming = 1;
1488 rval = smiapp_start_streaming(sensor);
1489 if (rval < 0)
1490 sensor->streaming = 0;
1491 } else {
1492 rval = smiapp_stop_streaming(sensor);
1493 sensor->streaming = 0;
1494 }
1495
1496 return rval;
1497}
1498
1499static int smiapp_enum_mbus_code(struct v4l2_subdev *subdev,
1500 struct v4l2_subdev_fh *fh,
1501 struct v4l2_subdev_mbus_code_enum *code)
1502{
1503 struct i2c_client *client = v4l2_get_subdevdata(subdev);
1504 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1505 unsigned int i;
1506 int idx = -1;
1507 int rval = -EINVAL;
1508
1509 mutex_lock(&sensor->mutex);
1510
1511 dev_err(&client->dev, "subdev %s, pad %d, index %d\n",
1512 subdev->name, code->pad, code->index);
1513
1514 if (subdev != &sensor->src->sd || code->pad != SMIAPP_PAD_SRC) {
1515 if (code->index)
1516 goto out;
1517
1518 code->code = sensor->internal_csi_format->code;
1519 rval = 0;
1520 goto out;
1521 }
1522
1523 for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
1524 if (sensor->mbus_frame_fmts & (1 << i))
1525 idx++;
1526
1527 if (idx == code->index) {
1528 code->code = smiapp_csi_data_formats[i].code;
1529 dev_err(&client->dev, "found index %d, i %d, code %x\n",
1530 code->index, i, code->code);
1531 rval = 0;
1532 break;
1533 }
1534 }
1535
1536out:
1537 mutex_unlock(&sensor->mutex);
1538
1539 return rval;
1540}
1541
1542static u32 __smiapp_get_mbus_code(struct v4l2_subdev *subdev,
1543 unsigned int pad)
1544{
1545 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1546
1547 if (subdev == &sensor->src->sd && pad == SMIAPP_PAD_SRC)
1548 return sensor->csi_format->code;
1549 else
1550 return sensor->internal_csi_format->code;
1551}
1552
1553static int __smiapp_get_format(struct v4l2_subdev *subdev,
1554 struct v4l2_subdev_fh *fh,
1555 struct v4l2_subdev_format *fmt)
1556{
1557 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
1558
1559 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1560 fmt->format = *v4l2_subdev_get_try_format(fh, fmt->pad);
1561 } else {
1562 struct v4l2_rect *r;
1563
1564 if (fmt->pad == ssd->source_pad)
1565 r = &ssd->crop[ssd->source_pad];
1566 else
1567 r = &ssd->sink_fmt;
1568
1569 fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
1570 fmt->format.width = r->width;
1571 fmt->format.height = r->height;
1572 }
1573
1574 return 0;
1575}
1576
1577static int smiapp_get_format(struct v4l2_subdev *subdev,
1578 struct v4l2_subdev_fh *fh,
1579 struct v4l2_subdev_format *fmt)
1580{
1581 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1582 int rval;
1583
1584 mutex_lock(&sensor->mutex);
1585 rval = __smiapp_get_format(subdev, fh, fmt);
1586 mutex_unlock(&sensor->mutex);
1587
1588 return rval;
1589}
1590
1591static void smiapp_get_crop_compose(struct v4l2_subdev *subdev,
1592 struct v4l2_subdev_fh *fh,
1593 struct v4l2_rect **crops,
1594 struct v4l2_rect **comps, int which)
1595{
1596 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
1597 unsigned int i;
1598
1599 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1600 if (crops)
1601 for (i = 0; i < subdev->entity.num_pads; i++)
1602 crops[i] = &ssd->crop[i];
1603 if (comps)
1604 *comps = &ssd->compose;
1605 } else {
1606 if (crops) {
1607 for (i = 0; i < subdev->entity.num_pads; i++) {
1608 crops[i] = v4l2_subdev_get_try_crop(fh, i);
1609 BUG_ON(!crops[i]);
1610 }
1611 }
1612 if (comps) {
1613 *comps = v4l2_subdev_get_try_compose(fh,
1614 SMIAPP_PAD_SINK);
1615 BUG_ON(!*comps);
1616 }
1617 }
1618}
1619
1620/* Changes require propagation only on sink pad. */
1621static void smiapp_propagate(struct v4l2_subdev *subdev,
1622 struct v4l2_subdev_fh *fh, int which,
1623 int target)
1624{
1625 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1626 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
1627 struct v4l2_rect *comp, *crops[SMIAPP_PADS];
1628
1629 smiapp_get_crop_compose(subdev, fh, crops, &comp, which);
1630
1631 switch (target) {
1632 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1633 comp->width = crops[SMIAPP_PAD_SINK]->width;
1634 comp->height = crops[SMIAPP_PAD_SINK]->height;
1635 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1636 if (ssd == sensor->scaler) {
1637 sensor->scale_m =
1638 sensor->limits[
1639 SMIAPP_LIMIT_SCALER_N_MIN];
1640 sensor->scaling_mode =
1641 SMIAPP_SCALING_MODE_NONE;
1642 } else if (ssd == sensor->binner) {
1643 sensor->binning_horizontal = 1;
1644 sensor->binning_vertical = 1;
1645 }
1646 }
1647 /* Fall through */
1648 case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
1649 *crops[SMIAPP_PAD_SRC] = *comp;
1650 break;
1651 default:
1652 BUG();
1653 }
1654}
1655
1656static const struct smiapp_csi_data_format
1657*smiapp_validate_csi_data_format(struct smiapp_sensor *sensor, u32 code)
1658{
1659 const struct smiapp_csi_data_format *csi_format = sensor->csi_format;
1660 unsigned int i;
1661
1662 for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
1663 if (sensor->mbus_frame_fmts & (1 << i)
1664 && smiapp_csi_data_formats[i].code == code)
1665 return &smiapp_csi_data_formats[i];
1666 }
1667
1668 return csi_format;
1669}
1670
1671static int smiapp_set_format(struct v4l2_subdev *subdev,
1672 struct v4l2_subdev_fh *fh,
1673 struct v4l2_subdev_format *fmt)
1674{
1675 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1676 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
1677 struct v4l2_rect *crops[SMIAPP_PADS];
1678
1679 mutex_lock(&sensor->mutex);
1680
1681 /*
1682 * Media bus code is changeable on src subdev's source pad. On
1683 * other source pads we just get format here.
1684 */
1685 if (fmt->pad == ssd->source_pad) {
1686 u32 code = fmt->format.code;
1687 int rval = __smiapp_get_format(subdev, fh, fmt);
1688
1689 if (!rval && subdev == &sensor->src->sd) {
1690 const struct smiapp_csi_data_format *csi_format =
1691 smiapp_validate_csi_data_format(sensor, code);
1692 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1693 sensor->csi_format = csi_format;
1694 fmt->format.code = csi_format->code;
1695 }
1696
1697 mutex_unlock(&sensor->mutex);
1698 return rval;
1699 }
1700
1701 /* Sink pad. Width and height are changeable here. */
1702 fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
1703 fmt->format.width &= ~1;
1704 fmt->format.height &= ~1;
1705
1706 fmt->format.width =
1707 clamp(fmt->format.width,
1708 sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
1709 sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
1710 fmt->format.height =
1711 clamp(fmt->format.height,
1712 sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
1713 sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
1714
1715 smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
1716
1717 crops[ssd->sink_pad]->left = 0;
1718 crops[ssd->sink_pad]->top = 0;
1719 crops[ssd->sink_pad]->width = fmt->format.width;
1720 crops[ssd->sink_pad]->height = fmt->format.height;
1721 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1722 ssd->sink_fmt = *crops[ssd->sink_pad];
1723 smiapp_propagate(subdev, fh, fmt->which,
1724 V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL);
1725
1726 mutex_unlock(&sensor->mutex);
1727
1728 return 0;
1729}
1730
1731/*
1732 * Calculate goodness of scaled image size compared to expected image
1733 * size and flags provided.
1734 */
1735#define SCALING_GOODNESS 100000
1736#define SCALING_GOODNESS_EXTREME 100000000
1737static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w,
1738 int h, int ask_h, u32 flags)
1739{
1740 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1741 struct i2c_client *client = v4l2_get_subdevdata(subdev);
1742 int val = 0;
1743
1744 w &= ~1;
1745 ask_w &= ~1;
1746 h &= ~1;
1747 ask_h &= ~1;
1748
1749 if (flags & V4L2_SUBDEV_SEL_FLAG_SIZE_GE) {
1750 if (w < ask_w)
1751 val -= SCALING_GOODNESS;
1752 if (h < ask_h)
1753 val -= SCALING_GOODNESS;
1754 }
1755
1756 if (flags & V4L2_SUBDEV_SEL_FLAG_SIZE_LE) {
1757 if (w > ask_w)
1758 val -= SCALING_GOODNESS;
1759 if (h > ask_h)
1760 val -= SCALING_GOODNESS;
1761 }
1762
1763 val -= abs(w - ask_w);
1764 val -= abs(h - ask_h);
1765
1766 if (w < sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
1767 val -= SCALING_GOODNESS_EXTREME;
1768
1769 dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",
1770 w, ask_h, h, ask_h, val);
1771
1772 return val;
1773}
1774
1775static void smiapp_set_compose_binner(struct v4l2_subdev *subdev,
1776 struct v4l2_subdev_fh *fh,
1777 struct v4l2_subdev_selection *sel,
1778 struct v4l2_rect **crops,
1779 struct v4l2_rect *comp)
1780{
1781 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1782 unsigned int i;
1783 unsigned int binh = 1, binv = 1;
1784 unsigned int best = scaling_goodness(
1785 subdev,
1786 crops[SMIAPP_PAD_SINK]->width, sel->r.width,
1787 crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags);
1788
1789 for (i = 0; i < sensor->nbinning_subtypes; i++) {
1790 int this = scaling_goodness(
1791 subdev,
1792 crops[SMIAPP_PAD_SINK]->width
1793 / sensor->binning_subtypes[i].horizontal,
1794 sel->r.width,
1795 crops[SMIAPP_PAD_SINK]->height
1796 / sensor->binning_subtypes[i].vertical,
1797 sel->r.height, sel->flags);
1798
1799 if (this > best) {
1800 binh = sensor->binning_subtypes[i].horizontal;
1801 binv = sensor->binning_subtypes[i].vertical;
1802 best = this;
1803 }
1804 }
1805 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1806 sensor->binning_vertical = binv;
1807 sensor->binning_horizontal = binh;
1808 }
1809
1810 sel->r.width = (crops[SMIAPP_PAD_SINK]->width / binh) & ~1;
1811 sel->r.height = (crops[SMIAPP_PAD_SINK]->height / binv) & ~1;
1812}
1813
1814/*
1815 * Calculate best scaling ratio and mode for given output resolution.
1816 *
1817 * Try all of these: horizontal ratio, vertical ratio and smallest
1818 * size possible (horizontally).
1819 *
1820 * Also try whether horizontal scaler or full scaler gives a better
1821 * result.
1822 */
1823static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev,
1824 struct v4l2_subdev_fh *fh,
1825 struct v4l2_subdev_selection *sel,
1826 struct v4l2_rect **crops,
1827 struct v4l2_rect *comp)
1828{
1829 struct i2c_client *client = v4l2_get_subdevdata(subdev);
1830 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1831 u32 min, max, a, b, max_m;
1832 u32 scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
1833 int mode = SMIAPP_SCALING_MODE_HORIZONTAL;
1834 u32 try[4];
1835 u32 ntry = 0;
1836 unsigned int i;
1837 int best = INT_MIN;
1838
1839 sel->r.width = min_t(unsigned int, sel->r.width,
1840 crops[SMIAPP_PAD_SINK]->width);
1841 sel->r.height = min_t(unsigned int, sel->r.height,
1842 crops[SMIAPP_PAD_SINK]->height);
1843
1844 a = crops[SMIAPP_PAD_SINK]->width
1845 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.width;
1846 b = crops[SMIAPP_PAD_SINK]->height
1847 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.height;
1848 max_m = crops[SMIAPP_PAD_SINK]->width
1849 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]
1850 / sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE];
1851
1852 a = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
1853 max(a, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
1854 b = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
1855 max(b, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
1856 max_m = min(sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX],
1857 max(max_m, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN]));
1858
1859 dev_dbg(&client->dev, "scaling: a %d b %d max_m %d\n", a, b, max_m);
1860
1861 min = min(max_m, min(a, b));
1862 max = min(max_m, max(a, b));
1863
1864 try[ntry] = min;
1865 ntry++;
1866 if (min != max) {
1867 try[ntry] = max;
1868 ntry++;
1869 }
1870 if (max != max_m) {
1871 try[ntry] = min + 1;
1872 ntry++;
1873 if (min != max) {
1874 try[ntry] = max + 1;
1875 ntry++;
1876 }
1877 }
1878
1879 for (i = 0; i < ntry; i++) {
1880 int this = scaling_goodness(
1881 subdev,
1882 crops[SMIAPP_PAD_SINK]->width
1883 / try[i]
1884 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
1885 sel->r.width,
1886 crops[SMIAPP_PAD_SINK]->height,
1887 sel->r.height,
1888 sel->flags);
1889
1890 dev_dbg(&client->dev, "trying factor %d (%d)\n", try[i], i);
1891
1892 if (this > best) {
1893 scale_m = try[i];
1894 mode = SMIAPP_SCALING_MODE_HORIZONTAL;
1895 best = this;
1896 }
1897
1898 if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
1899 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
1900 continue;
1901
1902 this = scaling_goodness(
1903 subdev, crops[SMIAPP_PAD_SINK]->width
1904 / try[i]
1905 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
1906 sel->r.width,
1907 crops[SMIAPP_PAD_SINK]->height
1908 / try[i]
1909 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],
1910 sel->r.height,
1911 sel->flags);
1912
1913 if (this > best) {
1914 scale_m = try[i];
1915 mode = SMIAPP_SCALING_MODE_BOTH;
1916 best = this;
1917 }
1918 }
1919
1920 sel->r.width =
1921 (crops[SMIAPP_PAD_SINK]->width
1922 / scale_m
1923 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]) & ~1;
1924 if (mode == SMIAPP_SCALING_MODE_BOTH)
1925 sel->r.height =
1926 (crops[SMIAPP_PAD_SINK]->height
1927 / scale_m
1928 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN])
1929 & ~1;
1930 else
1931 sel->r.height = crops[SMIAPP_PAD_SINK]->height;
1932
1933 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1934 sensor->scale_m = scale_m;
1935 sensor->scaling_mode = mode;
1936 }
1937}
1938/* We're only called on source pads. This function sets scaling. */
1939static int smiapp_set_compose(struct v4l2_subdev *subdev,
1940 struct v4l2_subdev_fh *fh,
1941 struct v4l2_subdev_selection *sel)
1942{
1943 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1944 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
1945 struct v4l2_rect *comp, *crops[SMIAPP_PADS];
1946
1947 smiapp_get_crop_compose(subdev, fh, crops, &comp, sel->which);
1948
1949 sel->r.top = 0;
1950 sel->r.left = 0;
1951
1952 if (ssd == sensor->binner)
1953 smiapp_set_compose_binner(subdev, fh, sel, crops, comp);
1954 else
1955 smiapp_set_compose_scaler(subdev, fh, sel, crops, comp);
1956
1957 *comp = sel->r;
1958 smiapp_propagate(subdev, fh, sel->which,
1959 V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL);
1960
1961 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
1962 return smiapp_update_mode(sensor);
1963
1964 return 0;
1965}
1966
1967static int __smiapp_sel_supported(struct v4l2_subdev *subdev,
1968 struct v4l2_subdev_selection *sel)
1969{
1970 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1971 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
1972
1973 /* We only implement crop in three places. */
1974 switch (sel->target) {
1975 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1976 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
1977 if (ssd == sensor->pixel_array
1978 && sel->pad == SMIAPP_PA_PAD_SRC)
1979 return 0;
1980 if (ssd == sensor->src
1981 && sel->pad == SMIAPP_PAD_SRC)
1982 return 0;
1983 if (ssd == sensor->scaler
1984 && sel->pad == SMIAPP_PAD_SINK
1985 && sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
1986 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP)
1987 return 0;
1988 return -EINVAL;
1989 case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
1990 case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS:
1991 if (sel->pad == ssd->source_pad)
1992 return -EINVAL;
1993 if (ssd == sensor->binner)
1994 return 0;
1995 if (ssd == sensor->scaler
1996 && sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
1997 != SMIAPP_SCALING_CAPABILITY_NONE)
1998 return 0;
1999 /* Fall through */
2000 default:
2001 return -EINVAL;
2002 }
2003}
2004
2005static int smiapp_set_crop(struct v4l2_subdev *subdev,
2006 struct v4l2_subdev_fh *fh,
2007 struct v4l2_subdev_selection *sel)
2008{
2009 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2010 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
2011 struct v4l2_rect *src_size, *crops[SMIAPP_PADS];
2012 struct v4l2_rect _r;
2013
2014 smiapp_get_crop_compose(subdev, fh, crops, NULL, sel->which);
2015
2016 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
2017 if (sel->pad == ssd->sink_pad)
2018 src_size = &ssd->sink_fmt;
2019 else
2020 src_size = &ssd->compose;
2021 } else {
2022 if (sel->pad == ssd->sink_pad) {
2023 _r.left = 0;
2024 _r.top = 0;
2025 _r.width = v4l2_subdev_get_try_format(fh, sel->pad)
2026 ->width;
2027 _r.height = v4l2_subdev_get_try_format(fh, sel->pad)
2028 ->height;
2029 src_size = &_r;
2030 } else {
2031 src_size =
2032 v4l2_subdev_get_try_compose(
2033 fh, ssd->sink_pad);
2034 }
2035 }
2036
2037 if (ssd == sensor->src && sel->pad == SMIAPP_PAD_SRC) {
2038 sel->r.left = 0;
2039 sel->r.top = 0;
2040 }
2041
2042 sel->r.width = min(sel->r.width, src_size->width);
2043 sel->r.height = min(sel->r.height, src_size->height);
2044
2045 sel->r.left = min(sel->r.left, src_size->width - sel->r.width);
2046 sel->r.top = min(sel->r.top, src_size->height - sel->r.height);
2047
2048 *crops[sel->pad] = sel->r;
2049
2050 if (ssd != sensor->pixel_array && sel->pad == SMIAPP_PAD_SINK)
2051 smiapp_propagate(subdev, fh, sel->which,
2052 V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL);
2053
2054 return 0;
2055}
2056
2057static int __smiapp_get_selection(struct v4l2_subdev *subdev,
2058 struct v4l2_subdev_fh *fh,
2059 struct v4l2_subdev_selection *sel)
2060{
2061 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2062 struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
2063 struct v4l2_rect *comp, *crops[SMIAPP_PADS];
2064 struct v4l2_rect sink_fmt;
2065 int ret;
2066
2067 ret = __smiapp_sel_supported(subdev, sel);
2068 if (ret)
2069 return ret;
2070
2071 smiapp_get_crop_compose(subdev, fh, crops, &comp, sel->which);
2072
2073 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
2074 sink_fmt = ssd->sink_fmt;
2075 } else {
2076 struct v4l2_mbus_framefmt *fmt =
2077 v4l2_subdev_get_try_format(fh, ssd->sink_pad);
2078
2079 sink_fmt.left = 0;
2080 sink_fmt.top = 0;
2081 sink_fmt.width = fmt->width;
2082 sink_fmt.height = fmt->height;
2083 }
2084
2085 switch (sel->target) {
2086 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
2087 if (ssd == sensor->pixel_array) {
2088 sel->r.width =
2089 sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
2090 sel->r.height =
2091 sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
2092 } else if (sel->pad == ssd->sink_pad) {
2093 sel->r = sink_fmt;
2094 } else {
2095 sel->r = *comp;
2096 }
2097 break;
2098 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
2099 case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS:
2100 sel->r = *crops[sel->pad];
2101 break;
2102 case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
2103 sel->r = *comp;
2104 break;
2105 }
2106
2107 return 0;
2108}
2109
2110static int smiapp_get_selection(struct v4l2_subdev *subdev,
2111 struct v4l2_subdev_fh *fh,
2112 struct v4l2_subdev_selection *sel)
2113{
2114 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2115 int rval;
2116
2117 mutex_lock(&sensor->mutex);
2118 rval = __smiapp_get_selection(subdev, fh, sel);
2119 mutex_unlock(&sensor->mutex);
2120
2121 return rval;
2122}
2123static int smiapp_set_selection(struct v4l2_subdev *subdev,
2124 struct v4l2_subdev_fh *fh,
2125 struct v4l2_subdev_selection *sel)
2126{
2127 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2128 int ret;
2129
2130 ret = __smiapp_sel_supported(subdev, sel);
2131 if (ret)
2132 return ret;
2133
2134 mutex_lock(&sensor->mutex);
2135
2136 sel->r.left = max(0, sel->r.left & ~1);
2137 sel->r.top = max(0, sel->r.top & ~1);
2138 sel->r.width = max(0, SMIAPP_ALIGN_DIM(sel->r.width, sel->flags));
2139 sel->r.height = max(0, SMIAPP_ALIGN_DIM(sel->r.height, sel->flags));
2140
2141 sel->r.width = max_t(unsigned int,
2142 sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
2143 sel->r.width);
2144 sel->r.height = max_t(unsigned int,
2145 sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
2146 sel->r.height);
2147
2148 switch (sel->target) {
2149 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
2150 ret = smiapp_set_crop(subdev, fh, sel);
2151 break;
2152 case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
2153 ret = smiapp_set_compose(subdev, fh, sel);
2154 break;
2155 default:
2156 BUG();
2157 }
2158
2159 mutex_unlock(&sensor->mutex);
2160 return ret;
2161}
2162
2163static int smiapp_get_skip_frames(struct v4l2_subdev *subdev, u32 *frames)
2164{
2165 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2166
2167 *frames = sensor->frame_skip;
2168 return 0;
2169}
2170
2171/* -----------------------------------------------------------------------------
2172 * sysfs attributes
2173 */
2174
2175static ssize_t
2176smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
2177 char *buf)
2178{
2179 struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
2180 struct i2c_client *client = v4l2_get_subdevdata(subdev);
2181 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2182 unsigned int nbytes;
2183
2184 if (!sensor->dev_init_done)
2185 return -EBUSY;
2186
2187 if (!sensor->nvm_size) {
2188 /* NVM not read yet - read it now */
2189 sensor->nvm_size = sensor->platform_data->nvm_size;
2190 if (smiapp_set_power(subdev, 1) < 0)
2191 return -ENODEV;
2192 if (smiapp_read_nvm(sensor, sensor->nvm)) {
2193 dev_err(&client->dev, "nvm read failed\n");
2194 return -ENODEV;
2195 }
2196 smiapp_set_power(subdev, 0);
2197 }
2198 /*
2199 * NVM is still way below a PAGE_SIZE, so we can safely
2200 * assume this for now.
2201 */
2202 nbytes = min_t(unsigned int, sensor->nvm_size, PAGE_SIZE);
2203 memcpy(buf, sensor->nvm, nbytes);
2204
2205 return nbytes;
2206}
2207static DEVICE_ATTR(nvm, S_IRUGO, smiapp_sysfs_nvm_read, NULL);
2208
2209/* -----------------------------------------------------------------------------
2210 * V4L2 subdev core operations
2211 */
2212
2213static int smiapp_identify_module(struct v4l2_subdev *subdev)
2214{
2215 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2216 struct i2c_client *client = v4l2_get_subdevdata(subdev);
2217 struct smiapp_module_info *minfo = &sensor->minfo;
2218 unsigned int i;
2219 int rval = 0;
2220
2221 minfo->name = SMIAPP_NAME;
2222
2223 /* Module info */
2224 rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_MANUFACTURER_ID,
2225 &minfo->manufacturer_id);
2226 if (!rval)
2227 rval = smiapp_read_8only(sensor, SMIAPP_REG_U16_MODEL_ID,
2228 &minfo->model_id);
2229 if (!rval)
2230 rval = smiapp_read_8only(sensor,
2231 SMIAPP_REG_U8_REVISION_NUMBER_MAJOR,
2232 &minfo->revision_number_major);
2233 if (!rval)
2234 rval = smiapp_read_8only(sensor,
2235 SMIAPP_REG_U8_REVISION_NUMBER_MINOR,
2236 &minfo->revision_number_minor);
2237 if (!rval)
2238 rval = smiapp_read_8only(sensor,
2239 SMIAPP_REG_U8_MODULE_DATE_YEAR,
2240 &minfo->module_year);
2241 if (!rval)
2242 rval = smiapp_read_8only(sensor,
2243 SMIAPP_REG_U8_MODULE_DATE_MONTH,
2244 &minfo->module_month);
2245 if (!rval)
2246 rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_MODULE_DATE_DAY,
2247 &minfo->module_day);
2248
2249 /* Sensor info */
2250 if (!rval)
2251 rval = smiapp_read_8only(sensor,
2252 SMIAPP_REG_U8_SENSOR_MANUFACTURER_ID,
2253 &minfo->sensor_manufacturer_id);
2254 if (!rval)
2255 rval = smiapp_read_8only(sensor,
2256 SMIAPP_REG_U16_SENSOR_MODEL_ID,
2257 &minfo->sensor_model_id);
2258 if (!rval)
2259 rval = smiapp_read_8only(sensor,
2260 SMIAPP_REG_U8_SENSOR_REVISION_NUMBER,
2261 &minfo->sensor_revision_number);
2262 if (!rval)
2263 rval = smiapp_read_8only(sensor,
2264 SMIAPP_REG_U8_SENSOR_FIRMWARE_VERSION,
2265 &minfo->sensor_firmware_version);
2266
2267 /* SMIA */
2268 if (!rval)
2269 rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_SMIA_VERSION,
2270 &minfo->smia_version);
2271 if (!rval)
2272 rval = smiapp_read_8only(sensor, SMIAPP_REG_U8_SMIAPP_VERSION,
2273 &minfo->smiapp_version);
2274
2275 if (rval) {
2276 dev_err(&client->dev, "sensor detection failed\n");
2277 return -ENODEV;
2278 }
2279
2280 dev_dbg(&client->dev, "module 0x%2.2x-0x%4.4x\n",
2281 minfo->manufacturer_id, minfo->model_id);
2282
2283 dev_dbg(&client->dev,
2284 "module revision 0x%2.2x-0x%2.2x date %2.2d-%2.2d-%2.2d\n",
2285 minfo->revision_number_major, minfo->revision_number_minor,
2286 minfo->module_year, minfo->module_month, minfo->module_day);
2287
2288 dev_dbg(&client->dev, "sensor 0x%2.2x-0x%4.4x\n",
2289 minfo->sensor_manufacturer_id, minfo->sensor_model_id);
2290
2291 dev_dbg(&client->dev,
2292 "sensor revision 0x%2.2x firmware version 0x%2.2x\n",
2293 minfo->sensor_revision_number, minfo->sensor_firmware_version);
2294
2295 dev_dbg(&client->dev, "smia version %2.2d smiapp version %2.2d\n",
2296 minfo->smia_version, minfo->smiapp_version);
2297
2298 /*
2299 * Some modules have bad data in the lvalues below. Hope the
2300 * rvalues have better stuff. The lvalues are module
2301 * parameters whereas the rvalues are sensor parameters.
2302 */
2303 if (!minfo->manufacturer_id && !minfo->model_id) {
2304 minfo->manufacturer_id = minfo->sensor_manufacturer_id;
2305 minfo->model_id = minfo->sensor_model_id;
2306 minfo->revision_number_major = minfo->sensor_revision_number;
2307 }
2308
2309 for (i = 0; i < ARRAY_SIZE(smiapp_module_idents); i++) {
2310 if (smiapp_module_idents[i].manufacturer_id
2311 != minfo->manufacturer_id)
2312 continue;
2313 if (smiapp_module_idents[i].model_id != minfo->model_id)
2314 continue;
2315 if (smiapp_module_idents[i].flags
2316 & SMIAPP_MODULE_IDENT_FLAG_REV_LE) {
2317 if (smiapp_module_idents[i].revision_number_major
2318 < minfo->revision_number_major)
2319 continue;
2320 } else {
2321 if (smiapp_module_idents[i].revision_number_major
2322 != minfo->revision_number_major)
2323 continue;
2324 }
2325
2326 minfo->name = smiapp_module_idents[i].name;
2327 minfo->quirk = smiapp_module_idents[i].quirk;
2328 break;
2329 }
2330
2331 if (i >= ARRAY_SIZE(smiapp_module_idents))
2332 dev_warn(&client->dev,
2333 "no quirks for this module; let's hope it's fully compliant\n");
2334
2335 dev_dbg(&client->dev, "the sensor is called %s, ident %2.2x%4.4x%2.2x\n",
2336 minfo->name, minfo->manufacturer_id, minfo->model_id,
2337 minfo->revision_number_major);
2338
2339 strlcpy(subdev->name, sensor->minfo.name, sizeof(subdev->name));
2340
2341 return 0;
2342}
2343
2344static const struct v4l2_subdev_ops smiapp_ops;
2345static const struct v4l2_subdev_internal_ops smiapp_internal_ops;
2346static const struct media_entity_operations smiapp_entity_ops;
2347
2348static int smiapp_registered(struct v4l2_subdev *subdev)
2349{
2350 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2351 struct i2c_client *client = v4l2_get_subdevdata(subdev);
2352 struct smiapp_subdev *last = NULL;
2353 u32 tmp;
2354 unsigned int i;
2355 int rval;
2356
2357 sensor->vana = regulator_get(&client->dev, "VANA");
2358 if (IS_ERR(sensor->vana)) {
2359 dev_err(&client->dev, "could not get regulator for vana\n");
2360 return -ENODEV;
2361 }
2362
2363 if (!sensor->platform_data->set_xclk) {
2364 sensor->ext_clk = clk_get(&client->dev,
2365 sensor->platform_data->ext_clk_name);
2366 if (IS_ERR(sensor->ext_clk)) {
2367 dev_err(&client->dev, "could not get clock %s\n",
2368 sensor->platform_data->ext_clk_name);
2369 rval = -ENODEV;
2370 goto out_clk_get;
2371 }
2372
2373 rval = clk_set_rate(sensor->ext_clk,
2374 sensor->platform_data->ext_clk);
2375 if (rval < 0) {
2376 dev_err(&client->dev,
2377 "unable to set clock %s freq to %u\n",
2378 sensor->platform_data->ext_clk_name,
2379 sensor->platform_data->ext_clk);
2380 rval = -ENODEV;
2381 goto out_clk_set_rate;
2382 }
2383 }
2384
2385 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
2386 if (gpio_request_one(sensor->platform_data->xshutdown, 0,
2387 "SMIA++ xshutdown") != 0) {
2388 dev_err(&client->dev,
2389 "unable to acquire reset gpio %d\n",
2390 sensor->platform_data->xshutdown);
2391 rval = -ENODEV;
2392 goto out_clk_set_rate;
2393 }
2394 }
2395
2396 rval = smiapp_power_on(sensor);
2397 if (rval) {
2398 rval = -ENODEV;
2399 goto out_smiapp_power_on;
2400 }
2401
2402 rval = smiapp_identify_module(subdev);
2403 if (rval) {
2404 rval = -ENODEV;
2405 goto out_power_off;
2406 }
2407
2408 rval = smiapp_get_all_limits(sensor);
2409 if (rval) {
2410 rval = -ENODEV;
2411 goto out_power_off;
2412 }
2413
2414 /*
2415 * Handle Sensor Module orientation on the board.
2416 *
2417 * The application of H-FLIP and V-FLIP on the sensor is modified by
2418 * the sensor orientation on the board.
2419 *
2420 * For SMIAPP_BOARD_SENSOR_ORIENT_180 the default behaviour is to set
2421 * both H-FLIP and V-FLIP for normal operation which also implies
2422 * that a set/unset operation for user space HFLIP and VFLIP v4l2
2423 * controls will need to be internally inverted.
2424 *
2425 * Rotation also changes the bayer pattern.
2426 */
2427 if (sensor->platform_data->module_board_orient ==
2428 SMIAPP_MODULE_BOARD_ORIENT_180)
2429 sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
2430 SMIAPP_IMAGE_ORIENTATION_VFLIP;
2431
2432 rval = smiapp_get_mbus_formats(sensor);
2433 if (rval) {
2434 rval = -ENODEV;
2435 goto out_power_off;
2436 }
2437
2438 if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {
2439 u32 val;
2440
2441 rval = smiapp_read(sensor,
2442 SMIAPP_REG_U8_BINNING_SUBTYPES, &val);
2443 if (rval < 0) {
2444 rval = -ENODEV;
2445 goto out_power_off;
2446 }
2447 sensor->nbinning_subtypes = min_t(u8, val,
2448 SMIAPP_BINNING_SUBTYPES);
2449
2450 for (i = 0; i < sensor->nbinning_subtypes; i++) {
2451 rval = smiapp_read(
2452 sensor, SMIAPP_REG_U8_BINNING_TYPE_n(i), &val);
2453 if (rval < 0) {
2454 rval = -ENODEV;
2455 goto out_power_off;
2456 }
2457 sensor->binning_subtypes[i] =
2458 *(struct smiapp_binning_subtype *)&val;
2459
2460 dev_dbg(&client->dev, "binning %xx%x\n",
2461 sensor->binning_subtypes[i].horizontal,
2462 sensor->binning_subtypes[i].vertical);
2463 }
2464 }
2465 sensor->binning_horizontal = 1;
2466 sensor->binning_vertical = 1;
2467
2468 /* SMIA++ NVM initialization - it will be read from the sensor
2469 * when it is first requested by userspace.
2470 */
2471 if (sensor->minfo.smiapp_version && sensor->platform_data->nvm_size) {
2472 sensor->nvm = kzalloc(sensor->platform_data->nvm_size,
2473 GFP_KERNEL);
2474 if (sensor->nvm == NULL) {
2475 dev_err(&client->dev, "nvm buf allocation failed\n");
2476 rval = -ENOMEM;
2477 goto out_power_off;
2478 }
2479
2480 if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
2481 dev_err(&client->dev, "sysfs nvm entry failed\n");
2482 rval = -EBUSY;
2483 goto out_power_off;
2484 }
2485 }
2486
2487 rval = smiapp_call_quirk(sensor, limits);
2488 if (rval) {
2489 dev_err(&client->dev, "limits quirks failed\n");
2490 goto out_nvm_release;
2491 }
2492
2493 /* We consider this as profile 0 sensor if any of these are zero. */
2494 if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
2495 !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
2496 !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] ||
2497 !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) {
2498 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;
2499 } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
2500 != SMIAPP_SCALING_CAPABILITY_NONE) {
2501 if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
2502 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
2503 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;
2504 else
2505 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;
2506 sensor->scaler = &sensor->ssds[sensor->ssds_used];
2507 sensor->ssds_used++;
2508 } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
2509 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
2510 sensor->scaler = &sensor->ssds[sensor->ssds_used];
2511 sensor->ssds_used++;
2512 }
2513 sensor->binner = &sensor->ssds[sensor->ssds_used];
2514 sensor->ssds_used++;
2515 sensor->pixel_array = &sensor->ssds[sensor->ssds_used];
2516 sensor->ssds_used++;
2517
2518 sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
2519
2520 for (i = 0; i < SMIAPP_SUBDEVS; i++) {
2521 struct {
2522 struct smiapp_subdev *ssd;
2523 char *name;
2524 } const __this[] = {
2525 { sensor->scaler, "scaler", },
2526 { sensor->binner, "binner", },
2527 { sensor->pixel_array, "pixel array", },
2528 }, *_this = &__this[i];
2529 struct smiapp_subdev *this = _this->ssd;
2530
2531 if (!this)
2532 continue;
2533
2534 if (this != sensor->src)
2535 v4l2_subdev_init(&this->sd, &smiapp_ops);
2536
2537 this->sensor = sensor;
2538
2539 if (this == sensor->pixel_array) {
2540 this->npads = 1;
2541 } else {
2542 this->npads = 2;
2543 this->source_pad = 1;
2544 }
2545
2546 snprintf(this->sd.name,
2547 sizeof(this->sd.name), "%s %s",
2548 sensor->minfo.name, _this->name);
2549
2550 this->sink_fmt.width =
2551 sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
2552 this->sink_fmt.height =
2553 sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
2554 this->compose.width = this->sink_fmt.width;
2555 this->compose.height = this->sink_fmt.height;
2556 this->crop[this->source_pad] = this->compose;
2557 this->pads[this->source_pad].flags = MEDIA_PAD_FL_SOURCE;
2558 if (this != sensor->pixel_array) {
2559 this->crop[this->sink_pad] = this->compose;
2560 this->pads[this->sink_pad].flags = MEDIA_PAD_FL_SINK;
2561 }
2562
2563 this->sd.entity.ops = &smiapp_entity_ops;
2564
2565 if (last == NULL) {
2566 last = this;
2567 continue;
2568 }
2569
2570 this->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2571 this->sd.internal_ops = &smiapp_internal_ops;
2572 this->sd.owner = NULL;
2573 v4l2_set_subdevdata(&this->sd, client);
2574
2575 rval = media_entity_init(&this->sd.entity,
2576 this->npads, this->pads, 0);
2577 if (rval) {
2578 dev_err(&client->dev,
2579 "media_entity_init failed\n");
2580 goto out_nvm_release;
2581 }
2582
2583 rval = media_entity_create_link(&this->sd.entity,
2584 this->source_pad,
2585 &last->sd.entity,
2586 last->sink_pad,
2587 MEDIA_LNK_FL_ENABLED |
2588 MEDIA_LNK_FL_IMMUTABLE);
2589 if (rval) {
2590 dev_err(&client->dev,
2591 "media_entity_create_link failed\n");
2592 goto out_nvm_release;
2593 }
2594
2595 rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev,
2596 &this->sd);
2597 if (rval) {
2598 dev_err(&client->dev,
2599 "v4l2_device_register_subdev failed\n");
2600 goto out_nvm_release;
2601 }
2602
2603 last = this;
2604 }
2605
2606 dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
2607
2608 sensor->pixel_array->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
2609
2610 /* final steps */
2611 smiapp_read_frame_fmt(sensor);
2612 rval = smiapp_init_controls(sensor);
2613 if (rval < 0)
2614 goto out_nvm_release;
2615
2616 rval = smiapp_update_mode(sensor);
2617 if (rval) {
2618 dev_err(&client->dev, "update mode failed\n");
2619 goto out_nvm_release;
2620 }
2621
2622 sensor->streaming = false;
2623 sensor->dev_init_done = true;
2624
2625 /* check flash capability */
2626 rval = smiapp_read(sensor, SMIAPP_REG_U8_FLASH_MODE_CAPABILITY, &tmp);
2627 sensor->flash_capability = tmp;
2628 if (rval)
2629 goto out_nvm_release;
2630
2631 smiapp_power_off(sensor);
2632
2633 return 0;
2634
2635out_nvm_release:
2636 device_remove_file(&client->dev, &dev_attr_nvm);
2637
2638out_power_off:
2639 kfree(sensor->nvm);
2640 sensor->nvm = NULL;
2641 smiapp_power_off(sensor);
2642
2643out_smiapp_power_on:
2644 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
2645 gpio_free(sensor->platform_data->xshutdown);
2646
2647out_clk_set_rate:
2648 clk_put(sensor->ext_clk);
2649 sensor->ext_clk = NULL;
2650
2651out_clk_get:
2652 regulator_put(sensor->vana);
2653 sensor->vana = NULL;
2654 return rval;
2655}
2656
2657static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2658{
2659 struct smiapp_subdev *ssd = to_smiapp_subdev(sd);
2660 struct smiapp_sensor *sensor = ssd->sensor;
2661 u32 mbus_code =
2662 smiapp_csi_data_formats[smiapp_pixel_order(sensor)].code;
2663 unsigned int i;
2664
2665 mutex_lock(&sensor->mutex);
2666
2667 for (i = 0; i < ssd->npads; i++) {
2668 struct v4l2_mbus_framefmt *try_fmt =
2669 v4l2_subdev_get_try_format(fh, i);
2670 struct v4l2_rect *try_crop = v4l2_subdev_get_try_crop(fh, i);
2671 struct v4l2_rect *try_comp;
2672
2673 try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
2674 try_fmt->height = sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
2675 try_fmt->code = mbus_code;
2676
2677 try_crop->top = 0;
2678 try_crop->left = 0;
2679 try_crop->width = try_fmt->width;
2680 try_crop->height = try_fmt->height;
2681
2682 if (ssd != sensor->pixel_array)
2683 continue;
2684
2685 try_comp = v4l2_subdev_get_try_compose(fh, i);
2686 *try_comp = *try_crop;
2687 }
2688
2689 mutex_unlock(&sensor->mutex);
2690
2691 return smiapp_set_power(sd, 1);
2692}
2693
2694static int smiapp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2695{
2696 return smiapp_set_power(sd, 0);
2697}
2698
2699static const struct v4l2_subdev_video_ops smiapp_video_ops = {
2700 .s_stream = smiapp_set_stream,
2701};
2702
2703static const struct v4l2_subdev_core_ops smiapp_core_ops = {
2704 .s_power = smiapp_set_power,
2705};
2706
2707static const struct v4l2_subdev_pad_ops smiapp_pad_ops = {
2708 .enum_mbus_code = smiapp_enum_mbus_code,
2709 .get_fmt = smiapp_get_format,
2710 .set_fmt = smiapp_set_format,
2711 .get_selection = smiapp_get_selection,
2712 .set_selection = smiapp_set_selection,
2713};
2714
2715static const struct v4l2_subdev_sensor_ops smiapp_sensor_ops = {
2716 .g_skip_frames = smiapp_get_skip_frames,
2717};
2718
2719static const struct v4l2_subdev_ops smiapp_ops = {
2720 .core = &smiapp_core_ops,
2721 .video = &smiapp_video_ops,
2722 .pad = &smiapp_pad_ops,
2723 .sensor = &smiapp_sensor_ops,
2724};
2725
2726static const struct media_entity_operations smiapp_entity_ops = {
2727 .link_validate = v4l2_subdev_link_validate,
2728};
2729
2730static const struct v4l2_subdev_internal_ops smiapp_internal_src_ops = {
2731 .registered = smiapp_registered,
2732 .open = smiapp_open,
2733 .close = smiapp_close,
2734};
2735
2736static const struct v4l2_subdev_internal_ops smiapp_internal_ops = {
2737 .open = smiapp_open,
2738 .close = smiapp_close,
2739};
2740
2741/* -----------------------------------------------------------------------------
2742 * I2C Driver
2743 */
2744
2745#ifdef CONFIG_PM
2746
2747static int smiapp_suspend(struct device *dev)
2748{
2749 struct i2c_client *client = to_i2c_client(dev);
2750 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
2751 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2752 bool streaming;
2753
2754 BUG_ON(mutex_is_locked(&sensor->mutex));
2755
2756 if (sensor->power_count == 0)
2757 return 0;
2758
2759 if (sensor->streaming)
2760 smiapp_stop_streaming(sensor);
2761
2762 streaming = sensor->streaming;
2763
2764 smiapp_power_off(sensor);
2765
2766 /* save state for resume */
2767 sensor->streaming = streaming;
2768
2769 return 0;
2770}
2771
2772static int smiapp_resume(struct device *dev)
2773{
2774 struct i2c_client *client = to_i2c_client(dev);
2775 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
2776 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2777 int rval;
2778
2779 if (sensor->power_count == 0)
2780 return 0;
2781
2782 rval = smiapp_power_on(sensor);
2783 if (rval)
2784 return rval;
2785
2786 if (sensor->streaming)
2787 rval = smiapp_start_streaming(sensor);
2788
2789 return rval;
2790}
2791
2792#else
2793
2794#define smiapp_suspend NULL
2795#define smiapp_resume NULL
2796
2797#endif /* CONFIG_PM */
2798
2799static int smiapp_probe(struct i2c_client *client,
2800 const struct i2c_device_id *devid)
2801{
2802 struct smiapp_sensor *sensor;
2803 int rval;
2804
2805 if (client->dev.platform_data == NULL)
2806 return -ENODEV;
2807
2808 sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
2809 if (sensor == NULL)
2810 return -ENOMEM;
2811
2812 sensor->platform_data = client->dev.platform_data;
2813 mutex_init(&sensor->mutex);
2814 mutex_init(&sensor->power_mutex);
2815 sensor->src = &sensor->ssds[sensor->ssds_used];
2816
2817 v4l2_i2c_subdev_init(&sensor->src->sd, client, &smiapp_ops);
2818 sensor->src->sd.internal_ops = &smiapp_internal_src_ops;
2819 sensor->src->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2820 sensor->src->sensor = sensor;
2821
2822 sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
2823 rval = media_entity_init(&sensor->src->sd.entity, 2,
2824 sensor->src->pads, 0);
2825 if (rval < 0)
2826 kfree(sensor);
2827
2828 return rval;
2829}
2830
2831static int __exit smiapp_remove(struct i2c_client *client)
2832{
2833 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
2834 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
2835 unsigned int i;
2836
2837 if (sensor->power_count) {
2838 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
2839 gpio_set_value(sensor->platform_data->xshutdown, 0);
2840 if (sensor->platform_data->set_xclk)
2841 sensor->platform_data->set_xclk(&sensor->src->sd, 0);
2842 else
2843 clk_disable(sensor->ext_clk);
2844 sensor->power_count = 0;
2845 }
2846
2847 if (sensor->nvm) {
2848 device_remove_file(&client->dev, &dev_attr_nvm);
2849 kfree(sensor->nvm);
2850 }
2851
2852 for (i = 0; i < sensor->ssds_used; i++) {
2853 media_entity_cleanup(&sensor->ssds[i].sd.entity);
2854 v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
2855 }
2856 smiapp_free_controls(sensor);
2857 if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
2858 gpio_free(sensor->platform_data->xshutdown);
2859 if (sensor->ext_clk)
2860 clk_put(sensor->ext_clk);
2861 if (sensor->vana)
2862 regulator_put(sensor->vana);
2863
2864 kfree(sensor);
2865
2866 return 0;
2867}
2868
2869static const struct i2c_device_id smiapp_id_table[] = {
2870 { SMIAPP_NAME, 0 },
2871 { },
2872};
2873MODULE_DEVICE_TABLE(i2c, smiapp_id_table);
2874
2875static const struct dev_pm_ops smiapp_pm_ops = {
2876 .suspend = smiapp_suspend,
2877 .resume = smiapp_resume,
2878};
2879
2880static struct i2c_driver smiapp_i2c_driver = {
2881 .driver = {
2882 .name = SMIAPP_NAME,
2883 .pm = &smiapp_pm_ops,
2884 },
2885 .probe = smiapp_probe,
2886 .remove = __exit_p(smiapp_remove),
2887 .id_table = smiapp_id_table,
2888};
2889
2890module_i2c_driver(smiapp_i2c_driver);
2891
2892MODULE_AUTHOR("Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>");
2893MODULE_DESCRIPTION("Generic SMIA/SMIA++ camera module driver");
2894MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/smiapp/smiapp-limits.c b/drivers/media/video/smiapp/smiapp-limits.c
new file mode 100644
index 000000000000..0800e095724e
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-limits.c
@@ -0,0 +1,132 @@
1/*
2 * drivers/media/video/smiapp/smiapp-limits.c
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#include "smiapp.h"
26
27struct smiapp_reg_limits smiapp_reg_limits[] = {
28 { SMIAPP_REG_U16_ANALOGUE_GAIN_CAPABILITY, "analogue_gain_capability" }, /* 0 */
29 { SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MIN, "analogue_gain_code_min" },
30 { SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MAX, "analogue_gain_code_max" },
31 { SMIAPP_REG_U8_THS_ZERO_MIN, "ths_zero_min" },
32 { SMIAPP_REG_U8_TCLK_TRAIL_MIN, "tclk_trail_min" },
33 { SMIAPP_REG_U16_INTEGRATION_TIME_CAPABILITY, "integration_time_capability" }, /* 5 */
34 { SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MIN, "coarse_integration_time_min" },
35 { SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MAX_MARGIN, "coarse_integration_time_max_margin" },
36 { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN, "fine_integration_time_min" },
37 { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN, "fine_integration_time_max_margin" },
38 { SMIAPP_REG_U16_DIGITAL_GAIN_CAPABILITY, "digital_gain_capability" }, /* 10 */
39 { SMIAPP_REG_U16_DIGITAL_GAIN_MIN, "digital_gain_min" },
40 { SMIAPP_REG_U16_DIGITAL_GAIN_MAX, "digital_gain_max" },
41 { SMIAPP_REG_F32_MIN_EXT_CLK_FREQ_HZ, "min_ext_clk_freq_hz" },
42 { SMIAPP_REG_F32_MAX_EXT_CLK_FREQ_HZ, "max_ext_clk_freq_hz" },
43 { SMIAPP_REG_U16_MIN_PRE_PLL_CLK_DIV, "min_pre_pll_clk_div" }, /* 15 */
44 { SMIAPP_REG_U16_MAX_PRE_PLL_CLK_DIV, "max_pre_pll_clk_div" },
45 { SMIAPP_REG_F32_MIN_PLL_IP_FREQ_HZ, "min_pll_ip_freq_hz" },
46 { SMIAPP_REG_F32_MAX_PLL_IP_FREQ_HZ, "max_pll_ip_freq_hz" },
47 { SMIAPP_REG_U16_MIN_PLL_MULTIPLIER, "min_pll_multiplier" },
48 { SMIAPP_REG_U16_MAX_PLL_MULTIPLIER, "max_pll_multiplier" }, /* 20 */
49 { SMIAPP_REG_F32_MIN_PLL_OP_FREQ_HZ, "min_pll_op_freq_hz" },
50 { SMIAPP_REG_F32_MAX_PLL_OP_FREQ_HZ, "max_pll_op_freq_hz" },
51 { SMIAPP_REG_U16_MIN_VT_SYS_CLK_DIV, "min_vt_sys_clk_div" },
52 { SMIAPP_REG_U16_MAX_VT_SYS_CLK_DIV, "max_vt_sys_clk_div" },
53 { SMIAPP_REG_F32_MIN_VT_SYS_CLK_FREQ_HZ, "min_vt_sys_clk_freq_hz" }, /* 25 */
54 { SMIAPP_REG_F32_MAX_VT_SYS_CLK_FREQ_HZ, "max_vt_sys_clk_freq_hz" },
55 { SMIAPP_REG_F32_MIN_VT_PIX_CLK_FREQ_HZ, "min_vt_pix_clk_freq_hz" },
56 { SMIAPP_REG_F32_MAX_VT_PIX_CLK_FREQ_HZ, "max_vt_pix_clk_freq_hz" },
57 { SMIAPP_REG_U16_MIN_VT_PIX_CLK_DIV, "min_vt_pix_clk_div" },
58 { SMIAPP_REG_U16_MAX_VT_PIX_CLK_DIV, "max_vt_pix_clk_div" }, /* 30 */
59 { SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES, "min_frame_length_lines" },
60 { SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES, "max_frame_length_lines" },
61 { SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK, "min_line_length_pck" },
62 { SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK, "max_line_length_pck" },
63 { SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK, "min_line_blanking_pck" }, /* 35 */
64 { SMIAPP_REG_U16_MIN_FRAME_BLANKING_LINES, "min_frame_blanking_lines" },
65 { SMIAPP_REG_U8_MIN_LINE_LENGTH_PCK_STEP_SIZE, "min_line_length_pck_step_size" },
66 { SMIAPP_REG_U16_MIN_OP_SYS_CLK_DIV, "min_op_sys_clk_div" },
67 { SMIAPP_REG_U16_MAX_OP_SYS_CLK_DIV, "max_op_sys_clk_div" },
68 { SMIAPP_REG_F32_MIN_OP_SYS_CLK_FREQ_HZ, "min_op_sys_clk_freq_hz" }, /* 40 */
69 { SMIAPP_REG_F32_MAX_OP_SYS_CLK_FREQ_HZ, "max_op_sys_clk_freq_hz" },
70 { SMIAPP_REG_U16_MIN_OP_PIX_CLK_DIV, "min_op_pix_clk_div" },
71 { SMIAPP_REG_U16_MAX_OP_PIX_CLK_DIV, "max_op_pix_clk_div" },
72 { SMIAPP_REG_F32_MIN_OP_PIX_CLK_FREQ_HZ, "min_op_pix_clk_freq_hz" },
73 { SMIAPP_REG_F32_MAX_OP_PIX_CLK_FREQ_HZ, "max_op_pix_clk_freq_hz" }, /* 45 */
74 { SMIAPP_REG_U16_X_ADDR_MIN, "x_addr_min" },
75 { SMIAPP_REG_U16_Y_ADDR_MIN, "y_addr_min" },
76 { SMIAPP_REG_U16_X_ADDR_MAX, "x_addr_max" },
77 { SMIAPP_REG_U16_Y_ADDR_MAX, "y_addr_max" },
78 { SMIAPP_REG_U16_MIN_X_OUTPUT_SIZE, "min_x_output_size" }, /* 50 */
79 { SMIAPP_REG_U16_MIN_Y_OUTPUT_SIZE, "min_y_output_size" },
80 { SMIAPP_REG_U16_MAX_X_OUTPUT_SIZE, "max_x_output_size" },
81 { SMIAPP_REG_U16_MAX_Y_OUTPUT_SIZE, "max_y_output_size" },
82 { SMIAPP_REG_U16_MIN_EVEN_INC, "min_even_inc" },
83 { SMIAPP_REG_U16_MAX_EVEN_INC, "max_even_inc" }, /* 55 */
84 { SMIAPP_REG_U16_MIN_ODD_INC, "min_odd_inc" },
85 { SMIAPP_REG_U16_MAX_ODD_INC, "max_odd_inc" },
86 { SMIAPP_REG_U16_SCALING_CAPABILITY, "scaling_capability" },
87 { SMIAPP_REG_U16_SCALER_M_MIN, "scaler_m_min" },
88 { SMIAPP_REG_U16_SCALER_M_MAX, "scaler_m_max" }, /* 60 */
89 { SMIAPP_REG_U16_SCALER_N_MIN, "scaler_n_min" },
90 { SMIAPP_REG_U16_SCALER_N_MAX, "scaler_n_max" },
91 { SMIAPP_REG_U16_SPATIAL_SAMPLING_CAPABILITY, "spatial_sampling_capability" },
92 { SMIAPP_REG_U8_DIGITAL_CROP_CAPABILITY, "digital_crop_capability" },
93 { SMIAPP_REG_U16_COMPRESSION_CAPABILITY, "compression_capability" }, /* 65 */
94 { SMIAPP_REG_U8_FIFO_SUPPORT_CAPABILITY, "fifo_support_capability" },
95 { SMIAPP_REG_U8_DPHY_CTRL_CAPABILITY, "dphy_ctrl_capability" },
96 { SMIAPP_REG_U8_CSI_LANE_MODE_CAPABILITY, "csi_lane_mode_capability" },
97 { SMIAPP_REG_U8_CSI_SIGNALLING_MODE_CAPABILITY, "csi_signalling_mode_capability" },
98 { SMIAPP_REG_U8_FAST_STANDBY_CAPABILITY, "fast_standby_capability" }, /* 70 */
99 { SMIAPP_REG_U8_CCI_ADDRESS_CONTROL_CAPABILITY, "cci_address_control_capability" },
100 { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS, "max_per_lane_bitrate_1_lane_mode_mbps" },
101 { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS, "max_per_lane_bitrate_2_lane_mode_mbps" },
102 { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS, "max_per_lane_bitrate_3_lane_mode_mbps" },
103 { SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS, "max_per_lane_bitrate_4_lane_mode_mbps" }, /* 75 */
104 { SMIAPP_REG_U8_TEMP_SENSOR_CAPABILITY, "temp_sensor_capability" },
105 { SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES_BIN, "min_frame_length_lines_bin" },
106 { SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES_BIN, "max_frame_length_lines_bin" },
107 { SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK_BIN, "min_line_length_pck_bin" },
108 { SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK_BIN, "max_line_length_pck_bin" }, /* 80 */
109 { SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK_BIN, "min_line_blanking_pck_bin" },
110 { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN_BIN, "fine_integration_time_min_bin" },
111 { SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN, "fine_integration_time_max_margin_bin" },
112 { SMIAPP_REG_U8_BINNING_CAPABILITY, "binning_capability" },
113 { SMIAPP_REG_U8_BINNING_WEIGHTING_CAPABILITY, "binning_weighting_capability" }, /* 85 */
114 { SMIAPP_REG_U8_DATA_TRANSFER_IF_CAPABILITY, "data_transfer_if_capability" },
115 { SMIAPP_REG_U8_SHADING_CORRECTION_CAPABILITY, "shading_correction_capability" },
116 { SMIAPP_REG_U8_GREEN_IMBALANCE_CAPABILITY, "green_imbalance_capability" },
117 { SMIAPP_REG_U8_BLACK_LEVEL_CAPABILITY, "black_level_capability" },
118 { SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_CAPABILITY, "module_specific_correction_capability" }, /* 90 */
119 { SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY, "defect_correction_capability" },
120 { SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY_2, "defect_correction_capability_2" },
121 { SMIAPP_REG_U8_EDOF_CAPABILITY, "edof_capability" },
122 { SMIAPP_REG_U8_COLOUR_FEEDBACK_CAPABILITY, "colour_feedback_capability" },
123 { SMIAPP_REG_U8_ESTIMATION_MODE_CAPABILITY, "estimation_mode_capability" }, /* 95 */
124 { SMIAPP_REG_U8_ESTIMATION_ZONE_CAPABILITY, "estimation_zone_capability" },
125 { SMIAPP_REG_U16_CAPABILITY_TRDY_MIN, "capability_trdy_min" },
126 { SMIAPP_REG_U8_FLASH_MODE_CAPABILITY, "flash_mode_capability" },
127 { SMIAPP_REG_U8_ACTUATOR_CAPABILITY, "actuator_capability" },
128 { SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_1, "bracketing_lut_capability_1" }, /* 100 */
129 { SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_2, "bracketing_lut_capability_2" },
130 { SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_STEP, "analogue_gain_code_step" },
131 { 0, NULL },
132};
diff --git a/drivers/media/video/smiapp/smiapp-limits.h b/drivers/media/video/smiapp/smiapp-limits.h
new file mode 100644
index 000000000000..7f4836bb78db
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-limits.h
@@ -0,0 +1,128 @@
1/*
2 * drivers/media/video/smiapp/smiapp-limits.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#define SMIAPP_LIMIT_ANALOGUE_GAIN_CAPABILITY 0
26#define SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN 1
27#define SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX 2
28#define SMIAPP_LIMIT_THS_ZERO_MIN 3
29#define SMIAPP_LIMIT_TCLK_TRAIL_MIN 4
30#define SMIAPP_LIMIT_INTEGRATION_TIME_CAPABILITY 5
31#define SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MIN 6
32#define SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN 7
33#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN 8
34#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN 9
35#define SMIAPP_LIMIT_DIGITAL_GAIN_CAPABILITY 10
36#define SMIAPP_LIMIT_DIGITAL_GAIN_MIN 11
37#define SMIAPP_LIMIT_DIGITAL_GAIN_MAX 12
38#define SMIAPP_LIMIT_MIN_EXT_CLK_FREQ_HZ 13
39#define SMIAPP_LIMIT_MAX_EXT_CLK_FREQ_HZ 14
40#define SMIAPP_LIMIT_MIN_PRE_PLL_CLK_DIV 15
41#define SMIAPP_LIMIT_MAX_PRE_PLL_CLK_DIV 16
42#define SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ 17
43#define SMIAPP_LIMIT_MAX_PLL_IP_FREQ_HZ 18
44#define SMIAPP_LIMIT_MIN_PLL_MULTIPLIER 19
45#define SMIAPP_LIMIT_MAX_PLL_MULTIPLIER 20
46#define SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ 21
47#define SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ 22
48#define SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV 23
49#define SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV 24
50#define SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ 25
51#define SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ 26
52#define SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ 27
53#define SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ 28
54#define SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV 29
55#define SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV 30
56#define SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES 31
57#define SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES 32
58#define SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK 33
59#define SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK 34
60#define SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK 35
61#define SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES 36
62#define SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_STEP_SIZE 37
63#define SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV 38
64#define SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV 39
65#define SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ 40
66#define SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ 41
67#define SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV 42
68#define SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV 43
69#define SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ 44
70#define SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ 45
71#define SMIAPP_LIMIT_X_ADDR_MIN 46
72#define SMIAPP_LIMIT_Y_ADDR_MIN 47
73#define SMIAPP_LIMIT_X_ADDR_MAX 48
74#define SMIAPP_LIMIT_Y_ADDR_MAX 49
75#define SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE 50
76#define SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE 51
77#define SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE 52
78#define SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE 53
79#define SMIAPP_LIMIT_MIN_EVEN_INC 54
80#define SMIAPP_LIMIT_MAX_EVEN_INC 55
81#define SMIAPP_LIMIT_MIN_ODD_INC 56
82#define SMIAPP_LIMIT_MAX_ODD_INC 57
83#define SMIAPP_LIMIT_SCALING_CAPABILITY 58
84#define SMIAPP_LIMIT_SCALER_M_MIN 59
85#define SMIAPP_LIMIT_SCALER_M_MAX 60
86#define SMIAPP_LIMIT_SCALER_N_MIN 61
87#define SMIAPP_LIMIT_SCALER_N_MAX 62
88#define SMIAPP_LIMIT_SPATIAL_SAMPLING_CAPABILITY 63
89#define SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY 64
90#define SMIAPP_LIMIT_COMPRESSION_CAPABILITY 65
91#define SMIAPP_LIMIT_FIFO_SUPPORT_CAPABILITY 66
92#define SMIAPP_LIMIT_DPHY_CTRL_CAPABILITY 67
93#define SMIAPP_LIMIT_CSI_LANE_MODE_CAPABILITY 68
94#define SMIAPP_LIMIT_CSI_SIGNALLING_MODE_CAPABILITY 69
95#define SMIAPP_LIMIT_FAST_STANDBY_CAPABILITY 70
96#define SMIAPP_LIMIT_CCI_ADDRESS_CONTROL_CAPABILITY 71
97#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS 72
98#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS 73
99#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS 74
100#define SMIAPP_LIMIT_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS 75
101#define SMIAPP_LIMIT_TEMP_SENSOR_CAPABILITY 76
102#define SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN 77
103#define SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN 78
104#define SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN 79
105#define SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN 80
106#define SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN 81
107#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MIN_BIN 82
108#define SMIAPP_LIMIT_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN 83
109#define SMIAPP_LIMIT_BINNING_CAPABILITY 84
110#define SMIAPP_LIMIT_BINNING_WEIGHTING_CAPABILITY 85
111#define SMIAPP_LIMIT_DATA_TRANSFER_IF_CAPABILITY 86
112#define SMIAPP_LIMIT_SHADING_CORRECTION_CAPABILITY 87
113#define SMIAPP_LIMIT_GREEN_IMBALANCE_CAPABILITY 88
114#define SMIAPP_LIMIT_BLACK_LEVEL_CAPABILITY 89
115#define SMIAPP_LIMIT_MODULE_SPECIFIC_CORRECTION_CAPABILITY 90
116#define SMIAPP_LIMIT_DEFECT_CORRECTION_CAPABILITY 91
117#define SMIAPP_LIMIT_DEFECT_CORRECTION_CAPABILITY_2 92
118#define SMIAPP_LIMIT_EDOF_CAPABILITY 93
119#define SMIAPP_LIMIT_COLOUR_FEEDBACK_CAPABILITY 94
120#define SMIAPP_LIMIT_ESTIMATION_MODE_CAPABILITY 95
121#define SMIAPP_LIMIT_ESTIMATION_ZONE_CAPABILITY 96
122#define SMIAPP_LIMIT_CAPABILITY_TRDY_MIN 97
123#define SMIAPP_LIMIT_FLASH_MODE_CAPABILITY 98
124#define SMIAPP_LIMIT_ACTUATOR_CAPABILITY 99
125#define SMIAPP_LIMIT_BRACKETING_LUT_CAPABILITY_1 100
126#define SMIAPP_LIMIT_BRACKETING_LUT_CAPABILITY_2 101
127#define SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_STEP 102
128#define SMIAPP_LIMIT_LAST 103
diff --git a/drivers/media/video/smiapp/smiapp-quirk.c b/drivers/media/video/smiapp/smiapp-quirk.c
new file mode 100644
index 000000000000..55e87950dcea
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-quirk.c
@@ -0,0 +1,306 @@
1/*
2 * drivers/media/video/smiapp/smiapp-quirk.c
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#include <linux/delay.h>
26
27#include "smiapp.h"
28
29static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val)
30{
31 return smiapp_write(sensor, (SMIA_REG_8BIT << 16) | reg, val);
32}
33
34static int smiapp_write_8s(struct smiapp_sensor *sensor,
35 struct smiapp_reg_8 *regs, int len)
36{
37 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
38 int rval;
39
40 for (; len > 0; len--, regs++) {
41 rval = smiapp_write_8(sensor, regs->reg, regs->val);
42 if (rval < 0) {
43 dev_err(&client->dev,
44 "error %d writing reg 0x%4.4x, val 0x%2.2x",
45 rval, regs->reg, regs->val);
46 return rval;
47 }
48 }
49
50 return 0;
51}
52
53void smiapp_replace_limit(struct smiapp_sensor *sensor,
54 u32 limit, u32 val)
55{
56 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
57
58 dev_dbg(&client->dev, "quirk: 0x%8.8x \"%s\" = %d, 0x%x\n",
59 smiapp_reg_limits[limit].addr,
60 smiapp_reg_limits[limit].what, val, val);
61 sensor->limits[limit] = val;
62}
63
64int smiapp_replace_limit_at(struct smiapp_sensor *sensor,
65 u32 reg, u32 val)
66{
67 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
68 int i;
69
70 for (i = 0; smiapp_reg_limits[i].addr; i++) {
71 if ((smiapp_reg_limits[i].addr & 0xffff) != reg)
72 continue;
73
74 smiapp_replace_limit(sensor, i, val);
75
76 return 0;
77 }
78
79 dev_dbg(&client->dev, "quirk: bad register 0x%4.4x\n", reg);
80
81 return -EINVAL;
82}
83
84bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
85 u32 reg, u32 *val)
86{
87 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
88 const struct smia_reg *sreg;
89
90 if (!sensor->minfo.quirk)
91 return false;
92
93 sreg = sensor->minfo.quirk->regs;
94
95 if (!sreg)
96 return false;
97
98 while (sreg->type) {
99 u16 type = reg >> 16;
100 u16 reg16 = reg;
101
102 if (sreg->type != type || sreg->reg != reg16) {
103 sreg++;
104 continue;
105 }
106
107 switch ((u8)type) {
108 case SMIA_REG_8BIT:
109 dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%2.2x\n",
110 reg, sreg->val);
111 break;
112 case SMIA_REG_16BIT:
113 dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%4.4x\n",
114 reg, sreg->val);
115 break;
116 case SMIA_REG_32BIT:
117 dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%8.8x\n",
118 reg, sreg->val);
119 break;
120 }
121
122 *val = sreg->val;
123
124 return true;
125 }
126
127 return false;
128}
129
130static int jt8ew9_limits(struct smiapp_sensor *sensor)
131{
132 if (sensor->minfo.revision_number_major < 0x03)
133 sensor->frame_skip = 1;
134
135 /* Below 24 gain doesn't have effect at all, */
136 /* but ~59 is needed for full dynamic range */
137 smiapp_replace_limit(sensor, SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN, 59);
138 smiapp_replace_limit(
139 sensor, SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX, 6000);
140
141 return 0;
142}
143
144static int jt8ew9_post_poweron(struct smiapp_sensor *sensor)
145{
146 struct smiapp_reg_8 regs[] = {
147 { 0x30a3, 0xd8 }, /* Output port control : LVDS ports only */
148 { 0x30ae, 0x00 }, /* 0x0307 pll_multiplier maximum value on PLL input 9.6MHz ( 19.2MHz is divided on pre_pll_div) */
149 { 0x30af, 0xd0 }, /* 0x0307 pll_multiplier maximum value on PLL input 9.6MHz ( 19.2MHz is divided on pre_pll_div) */
150 { 0x322d, 0x04 }, /* Adjusting Processing Image Size to Scaler Toshiba Recommendation Setting */
151 { 0x3255, 0x0f }, /* Horizontal Noise Reduction Control Toshiba Recommendation Setting */
152 { 0x3256, 0x15 }, /* Horizontal Noise Reduction Control Toshiba Recommendation Setting */
153 { 0x3258, 0x70 }, /* Analog Gain Control Toshiba Recommendation Setting */
154 { 0x3259, 0x70 }, /* Analog Gain Control Toshiba Recommendation Setting */
155 { 0x325f, 0x7c }, /* Analog Gain Control Toshiba Recommendation Setting */
156 { 0x3302, 0x06 }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
157 { 0x3304, 0x00 }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
158 { 0x3307, 0x22 }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
159 { 0x3308, 0x8d }, /* Pixel Reference Voltage Control Toshiba Recommendation Setting */
160 { 0x331e, 0x0f }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
161 { 0x3320, 0x30 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
162 { 0x3321, 0x11 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
163 { 0x3322, 0x98 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
164 { 0x3323, 0x64 }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
165 { 0x3325, 0x83 }, /* Read Out Timing Control Toshiba Recommendation Setting */
166 { 0x3330, 0x18 }, /* Read Out Timing Control Toshiba Recommendation Setting */
167 { 0x333c, 0x01 }, /* Read Out Timing Control Toshiba Recommendation Setting */
168 { 0x3345, 0x2f }, /* Black Hole Sun Correction Control Toshiba Recommendation Setting */
169 { 0x33de, 0x38 }, /* Horizontal Noise Reduction Control Toshiba Recommendation Setting */
170 /* Taken from v03. No idea what the rest are. */
171 { 0x32e0, 0x05 },
172 { 0x32e1, 0x05 },
173 { 0x32e2, 0x04 },
174 { 0x32e5, 0x04 },
175 { 0x32e6, 0x04 },
176
177 };
178
179 return smiapp_write_8s(sensor, regs, ARRAY_SIZE(regs));
180}
181
182const struct smiapp_quirk smiapp_jt8ew9_quirk = {
183 .limits = jt8ew9_limits,
184 .post_poweron = jt8ew9_post_poweron,
185};
186
187static int imx125es_post_poweron(struct smiapp_sensor *sensor)
188{
189 /* Taken from v02. No idea what the other two are. */
190 struct smiapp_reg_8 regs[] = {
191 /*
192 * 0x3302: clk during frame blanking:
193 * 0x00 - HS mode, 0x01 - LP11
194 */
195 { 0x3302, 0x01 },
196 { 0x302d, 0x00 },
197 { 0x3b08, 0x8c },
198 };
199
200 return smiapp_write_8s(sensor, regs, ARRAY_SIZE(regs));
201}
202
203const struct smiapp_quirk smiapp_imx125es_quirk = {
204 .post_poweron = imx125es_post_poweron,
205};
206
207static int jt8ev1_limits(struct smiapp_sensor *sensor)
208{
209 smiapp_replace_limit(sensor, SMIAPP_LIMIT_X_ADDR_MAX, 4271);
210 smiapp_replace_limit(sensor,
211 SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN, 184);
212
213 return 0;
214}
215
216static int jt8ev1_post_poweron(struct smiapp_sensor *sensor)
217{
218 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
219 int rval;
220
221 struct smiapp_reg_8 regs[] = {
222 { 0x3031, 0xcd }, /* For digital binning (EQ_MONI) */
223 { 0x30a3, 0xd0 }, /* FLASH STROBE enable */
224 { 0x3237, 0x00 }, /* For control of pulse timing for ADC */
225 { 0x3238, 0x43 },
226 { 0x3301, 0x06 }, /* For analog bias for sensor */
227 { 0x3302, 0x06 },
228 { 0x3304, 0x00 },
229 { 0x3305, 0x88 },
230 { 0x332a, 0x14 },
231 { 0x332c, 0x6b },
232 { 0x3336, 0x01 },
233 { 0x333f, 0x1f },
234 { 0x3355, 0x00 },
235 { 0x3356, 0x20 },
236 { 0x33bf, 0x20 }, /* Adjust the FBC speed */
237 { 0x33c9, 0x20 },
238 { 0x33ce, 0x30 }, /* Adjust the parameter for logic function */
239 { 0x33cf, 0xec }, /* For Black sun */
240 { 0x3328, 0x80 }, /* Ugh. No idea what's this. */
241 };
242
243 struct smiapp_reg_8 regs_96[] = {
244 { 0x30ae, 0x00 }, /* For control of ADC clock */
245 { 0x30af, 0xd0 },
246 { 0x30b0, 0x01 },
247 };
248
249 rval = smiapp_write_8s(sensor, regs, ARRAY_SIZE(regs));
250 if (rval < 0)
251 return rval;
252
253 switch (sensor->platform_data->ext_clk) {
254 case 9600000:
255 return smiapp_write_8s(sensor, regs_96,
256 ARRAY_SIZE(regs_96));
257 default:
258 dev_warn(&client->dev, "no MSRs for %d Hz ext_clk\n",
259 sensor->platform_data->ext_clk);
260 return 0;
261 }
262}
263
264static int jt8ev1_pre_streamon(struct smiapp_sensor *sensor)
265{
266 return smiapp_write_8(sensor, 0x3328, 0x00);
267}
268
269static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor)
270{
271 int rval;
272
273 /* Workaround: allows fast standby to work properly */
274 rval = smiapp_write_8(sensor, 0x3205, 0x04);
275 if (rval < 0)
276 return rval;
277
278 /* Wait for 1 ms + one line => 2 ms is likely enough */
279 usleep_range(2000, 2000);
280
281 /* Restore it */
282 rval = smiapp_write_8(sensor, 0x3205, 0x00);
283 if (rval < 0)
284 return rval;
285
286 return smiapp_write_8(sensor, 0x3328, 0x80);
287}
288
289const struct smiapp_quirk smiapp_jt8ev1_quirk = {
290 .limits = jt8ev1_limits,
291 .post_poweron = jt8ev1_post_poweron,
292 .pre_streamon = jt8ev1_pre_streamon,
293 .post_streamoff = jt8ev1_post_streamoff,
294 .flags = SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE,
295};
296
297static int tcm8500md_limits(struct smiapp_sensor *sensor)
298{
299 smiapp_replace_limit(sensor, SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ, 2700000);
300
301 return 0;
302}
303
304const struct smiapp_quirk smiapp_tcm8500md_quirk = {
305 .limits = tcm8500md_limits,
306};
diff --git a/drivers/media/video/smiapp/smiapp-quirk.h b/drivers/media/video/smiapp/smiapp-quirk.h
new file mode 100644
index 000000000000..f4dcaabaefe7
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-quirk.h
@@ -0,0 +1,83 @@
1/*
2 * drivers/media/video/smiapp/smiapp-quirk.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#ifndef __SMIAPP_QUIRK__
26#define __SMIAPP_QUIRK__
27
28struct smiapp_sensor;
29
30/**
31 * struct smiapp_quirk - quirks for sensors that deviate from SMIA++ standard
32 *
33 * @limits: Replace sensor->limits with values which can't be read from
34 * sensor registers. Called the first time the sensor is powered up.
35 * @post_poweron: Called always after the sensor has been fully powered on.
36 * @pre_streamon: Called just before streaming is enabled.
37 * @post_streamon: Called right after stopping streaming.
38 */
39struct smiapp_quirk {
40 int (*limits)(struct smiapp_sensor *sensor);
41 int (*post_poweron)(struct smiapp_sensor *sensor);
42 int (*pre_streamon)(struct smiapp_sensor *sensor);
43 int (*post_streamoff)(struct smiapp_sensor *sensor);
44 const struct smia_reg *regs;
45 unsigned long flags;
46};
47
48/* op pix clock is for all lanes in total normally */
49#define SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0)
50#define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY (1 << 1)
51
52struct smiapp_reg_8 {
53 u16 reg;
54 u8 val;
55};
56
57void smiapp_replace_limit(struct smiapp_sensor *sensor,
58 u32 limit, u32 val);
59bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
60 u32 reg, u32 *val);
61
62#define SMIAPP_MK_QUIRK_REG(_reg, _val) \
63 { \
64 .type = (_reg >> 16), \
65 .reg = (u16)_reg, \
66 .val = _val, \
67 }
68
69#define smiapp_call_quirk(_sensor, _quirk, ...) \
70 (_sensor->minfo.quirk && \
71 _sensor->minfo.quirk->_quirk ? \
72 _sensor->minfo.quirk->_quirk(_sensor, ##__VA_ARGS__) : 0)
73
74#define smiapp_needs_quirk(_sensor, _quirk) \
75 (_sensor->minfo.quirk ? \
76 _sensor->minfo.quirk->flags & _quirk : 0)
77
78extern const struct smiapp_quirk smiapp_jt8ev1_quirk;
79extern const struct smiapp_quirk smiapp_imx125es_quirk;
80extern const struct smiapp_quirk smiapp_jt8ew9_quirk;
81extern const struct smiapp_quirk smiapp_tcm8500md_quirk;
82
83#endif /* __SMIAPP_QUIRK__ */
diff --git a/drivers/media/video/smiapp/smiapp-reg-defs.h b/drivers/media/video/smiapp/smiapp-reg-defs.h
new file mode 100644
index 000000000000..a089eb8161e1
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-reg-defs.h
@@ -0,0 +1,503 @@
1/*
2 * drivers/media/video/smiapp/smiapp-reg-defs.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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#define SMIAPP_REG_MK_U8(r) ((SMIA_REG_8BIT << 16) | (r))
25#define SMIAPP_REG_MK_U16(r) ((SMIA_REG_16BIT << 16) | (r))
26#define SMIAPP_REG_MK_U32(r) ((SMIA_REG_32BIT << 16) | (r))
27
28#define SMIAPP_REG_MK_F32(r) (SMIA_REG_FLAG_FLOAT | (SMIA_REG_32BIT << 16) | (r))
29
30#define SMIAPP_REG_U16_MODEL_ID SMIAPP_REG_MK_U16(0x0000)
31#define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR SMIAPP_REG_MK_U8(0x0002)
32#define SMIAPP_REG_U8_MANUFACTURER_ID SMIAPP_REG_MK_U8(0x0003)
33#define SMIAPP_REG_U8_SMIA_VERSION SMIAPP_REG_MK_U8(0x0004)
34#define SMIAPP_REG_U8_FRAME_COUNT SMIAPP_REG_MK_U8(0x0005)
35#define SMIAPP_REG_U8_PIXEL_ORDER SMIAPP_REG_MK_U8(0x0006)
36#define SMIAPP_REG_U16_DATA_PEDESTAL SMIAPP_REG_MK_U16(0x0008)
37#define SMIAPP_REG_U8_PIXEL_DEPTH SMIAPP_REG_MK_U8(0x000c)
38#define SMIAPP_REG_U8_REVISION_NUMBER_MINOR SMIAPP_REG_MK_U8(0x0010)
39#define SMIAPP_REG_U8_SMIAPP_VERSION SMIAPP_REG_MK_U8(0x0011)
40#define SMIAPP_REG_U8_MODULE_DATE_YEAR SMIAPP_REG_MK_U8(0x0012)
41#define SMIAPP_REG_U8_MODULE_DATE_MONTH SMIAPP_REG_MK_U8(0x0013)
42#define SMIAPP_REG_U8_MODULE_DATE_DAY SMIAPP_REG_MK_U8(0x0014)
43#define SMIAPP_REG_U8_MODULE_DATE_PHASE SMIAPP_REG_MK_U8(0x0015)
44#define SMIAPP_REG_U16_SENSOR_MODEL_ID SMIAPP_REG_MK_U16(0x0016)
45#define SMIAPP_REG_U8_SENSOR_REVISION_NUMBER SMIAPP_REG_MK_U8(0x0018)
46#define SMIAPP_REG_U8_SENSOR_MANUFACTURER_ID SMIAPP_REG_MK_U8(0x0019)
47#define SMIAPP_REG_U8_SENSOR_FIRMWARE_VERSION SMIAPP_REG_MK_U8(0x001a)
48#define SMIAPP_REG_U32_SERIAL_NUMBER SMIAPP_REG_MK_U32(0x001c)
49#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE SMIAPP_REG_MK_U8(0x0040)
50#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_SUBTYPE SMIAPP_REG_MK_U8(0x0041)
51#define SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(n) SMIAPP_REG_MK_U16(0x0042 + ((n) << 1)) /* 0 <= n <= 14 */
52#define SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(n) SMIAPP_REG_MK_U32(0x0060 + ((n) << 2)) /* 0 <= n <= 7 */
53#define SMIAPP_REG_U16_ANALOGUE_GAIN_CAPABILITY SMIAPP_REG_MK_U16(0x0080)
54#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MIN SMIAPP_REG_MK_U16(0x0084)
55#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MAX SMIAPP_REG_MK_U16(0x0086)
56#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_STEP SMIAPP_REG_MK_U16(0x0088)
57#define SMIAPP_REG_U16_ANALOGUE_GAIN_TYPE SMIAPP_REG_MK_U16(0x008a)
58#define SMIAPP_REG_U16_ANALOGUE_GAIN_M0 SMIAPP_REG_MK_U16(0x008c)
59#define SMIAPP_REG_U16_ANALOGUE_GAIN_C0 SMIAPP_REG_MK_U16(0x008e)
60#define SMIAPP_REG_U16_ANALOGUE_GAIN_M1 SMIAPP_REG_MK_U16(0x0090)
61#define SMIAPP_REG_U16_ANALOGUE_GAIN_C1 SMIAPP_REG_MK_U16(0x0092)
62#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_TYPE SMIAPP_REG_MK_U8(0x00c0)
63#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_SUBTYPE SMIAPP_REG_MK_U8(0x00c1)
64#define SMIAPP_REG_U16_DATA_FORMAT_DESCRIPTOR(n) SMIAPP_REG_MK_U16(0x00c2 + ((n) << 1))
65#define SMIAPP_REG_U8_MODE_SELECT SMIAPP_REG_MK_U8(0x0100)
66#define SMIAPP_REG_U8_IMAGE_ORIENTATION SMIAPP_REG_MK_U8(0x0101)
67#define SMIAPP_REG_U8_SOFTWARE_RESET SMIAPP_REG_MK_U8(0x0103)
68#define SMIAPP_REG_U8_GROUPED_PARAMETER_HOLD SMIAPP_REG_MK_U8(0x0104)
69#define SMIAPP_REG_U8_MASK_CORRUPTED_FRAMES SMIAPP_REG_MK_U8(0x0105)
70#define SMIAPP_REG_U8_FAST_STANDBY_CTRL SMIAPP_REG_MK_U8(0x0106)
71#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL SMIAPP_REG_MK_U8(0x0107)
72#define SMIAPP_REG_U8_2ND_CCI_IF_CONTROL SMIAPP_REG_MK_U8(0x0108)
73#define SMIAPP_REG_U8_2ND_CCI_ADDRESS_CONTROL SMIAPP_REG_MK_U8(0x0109)
74#define SMIAPP_REG_U8_CSI_CHANNEL_IDENTIFIER SMIAPP_REG_MK_U8(0x0110)
75#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE SMIAPP_REG_MK_U8(0x0111)
76#define SMIAPP_REG_U16_CSI_DATA_FORMAT SMIAPP_REG_MK_U16(0x0112)
77#define SMIAPP_REG_U8_CSI_LANE_MODE SMIAPP_REG_MK_U8(0x0114)
78#define SMIAPP_REG_U8_CSI2_10_TO_8_DT SMIAPP_REG_MK_U8(0x0115)
79#define SMIAPP_REG_U8_CSI2_10_TO_7_DT SMIAPP_REG_MK_U8(0x0116)
80#define SMIAPP_REG_U8_CSI2_10_TO_6_DT SMIAPP_REG_MK_U8(0x0117)
81#define SMIAPP_REG_U8_CSI2_12_TO_8_DT SMIAPP_REG_MK_U8(0x0118)
82#define SMIAPP_REG_U8_CSI2_12_TO_7_DT SMIAPP_REG_MK_U8(0x0119)
83#define SMIAPP_REG_U8_CSI2_12_TO_6_DT SMIAPP_REG_MK_U8(0x011a)
84#define SMIAPP_REG_U8_CSI2_14_TO_10_DT SMIAPP_REG_MK_U8(0x011b)
85#define SMIAPP_REG_U8_CSI2_14_TO_8_DT SMIAPP_REG_MK_U8(0x011c)
86#define SMIAPP_REG_U8_CSI2_16_TO_10_DT SMIAPP_REG_MK_U8(0x011d)
87#define SMIAPP_REG_U8_CSI2_16_TO_8_DT SMIAPP_REG_MK_U8(0x011e)
88#define SMIAPP_REG_U8_GAIN_MODE SMIAPP_REG_MK_U8(0x0120)
89#define SMIAPP_REG_U16_VANA_VOLTAGE SMIAPP_REG_MK_U16(0x0130)
90#define SMIAPP_REG_U16_VDIG_VOLTAGE SMIAPP_REG_MK_U16(0x0132)
91#define SMIAPP_REG_U16_VIO_VOLTAGE SMIAPP_REG_MK_U16(0x0134)
92#define SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ SMIAPP_REG_MK_U16(0x0136)
93#define SMIAPP_REG_U8_TEMP_SENSOR_CONTROL SMIAPP_REG_MK_U8(0x0138)
94#define SMIAPP_REG_U8_TEMP_SENSOR_MODE SMIAPP_REG_MK_U8(0x0139)
95#define SMIAPP_REG_U8_TEMP_SENSOR_OUTPUT SMIAPP_REG_MK_U8(0x013a)
96#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME SMIAPP_REG_MK_U16(0x0200)
97#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME SMIAPP_REG_MK_U16(0x0202)
98#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL SMIAPP_REG_MK_U16(0x0204)
99#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENR SMIAPP_REG_MK_U16(0x0206)
100#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_RED SMIAPP_REG_MK_U16(0x0208)
101#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_BLUE SMIAPP_REG_MK_U16(0x020a)
102#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENB SMIAPP_REG_MK_U16(0x020c)
103#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENR SMIAPP_REG_MK_U16(0x020e)
104#define SMIAPP_REG_U16_DIGITAL_GAIN_RED SMIAPP_REG_MK_U16(0x0210)
105#define SMIAPP_REG_U16_DIGITAL_GAIN_BLUE SMIAPP_REG_MK_U16(0x0212)
106#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENB SMIAPP_REG_MK_U16(0x0214)
107#define SMIAPP_REG_U16_VT_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x0300)
108#define SMIAPP_REG_U16_VT_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x0302)
109#define SMIAPP_REG_U16_PRE_PLL_CLK_DIV SMIAPP_REG_MK_U16(0x0304)
110#define SMIAPP_REG_U16_PLL_MULTIPLIER SMIAPP_REG_MK_U16(0x0306)
111#define SMIAPP_REG_U16_OP_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x0308)
112#define SMIAPP_REG_U16_OP_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x030a)
113#define SMIAPP_REG_U16_FRAME_LENGTH_LINES SMIAPP_REG_MK_U16(0x0340)
114#define SMIAPP_REG_U16_LINE_LENGTH_PCK SMIAPP_REG_MK_U16(0x0342)
115#define SMIAPP_REG_U16_X_ADDR_START SMIAPP_REG_MK_U16(0x0344)
116#define SMIAPP_REG_U16_Y_ADDR_START SMIAPP_REG_MK_U16(0x0346)
117#define SMIAPP_REG_U16_X_ADDR_END SMIAPP_REG_MK_U16(0x0348)
118#define SMIAPP_REG_U16_Y_ADDR_END SMIAPP_REG_MK_U16(0x034a)
119#define SMIAPP_REG_U16_X_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x034c)
120#define SMIAPP_REG_U16_Y_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x034e)
121#define SMIAPP_REG_U16_X_EVEN_INC SMIAPP_REG_MK_U16(0x0380)
122#define SMIAPP_REG_U16_X_ODD_INC SMIAPP_REG_MK_U16(0x0382)
123#define SMIAPP_REG_U16_Y_EVEN_INC SMIAPP_REG_MK_U16(0x0384)
124#define SMIAPP_REG_U16_Y_ODD_INC SMIAPP_REG_MK_U16(0x0386)
125#define SMIAPP_REG_U16_SCALING_MODE SMIAPP_REG_MK_U16(0x0400)
126#define SMIAPP_REG_U16_SPATIAL_SAMPLING SMIAPP_REG_MK_U16(0x0402)
127#define SMIAPP_REG_U16_SCALE_M SMIAPP_REG_MK_U16(0x0404)
128#define SMIAPP_REG_U16_SCALE_N SMIAPP_REG_MK_U16(0x0406)
129#define SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET SMIAPP_REG_MK_U16(0x0408)
130#define SMIAPP_REG_U16_DIGITAL_CROP_Y_OFFSET SMIAPP_REG_MK_U16(0x040a)
131#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_WIDTH SMIAPP_REG_MK_U16(0x040c)
132#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_HEIGHT SMIAPP_REG_MK_U16(0x040e)
133#define SMIAPP_REG_U16_COMPRESSION_MODE SMIAPP_REG_MK_U16(0x0500)
134#define SMIAPP_REG_U16_TEST_PATTERN_MODE SMIAPP_REG_MK_U16(0x0600)
135#define SMIAPP_REG_U16_TEST_DATA_RED SMIAPP_REG_MK_U16(0x0602)
136#define SMIAPP_REG_U16_TEST_DATA_GREENR SMIAPP_REG_MK_U16(0x0604)
137#define SMIAPP_REG_U16_TEST_DATA_BLUE SMIAPP_REG_MK_U16(0x0606)
138#define SMIAPP_REG_U16_TEST_DATA_GREENB SMIAPP_REG_MK_U16(0x0608)
139#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_WIDTH SMIAPP_REG_MK_U16(0x060a)
140#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_POSITION SMIAPP_REG_MK_U16(0x060c)
141#define SMIAPP_REG_U16_VERTICAL_CURSOR_WIDTH SMIAPP_REG_MK_U16(0x060e)
142#define SMIAPP_REG_U16_VERTICAL_CURSOR_POSITION SMIAPP_REG_MK_U16(0x0610)
143#define SMIAPP_REG_U16_FIFO_WATER_MARK_PIXELS SMIAPP_REG_MK_U16(0x0700)
144#define SMIAPP_REG_U8_TCLK_POST SMIAPP_REG_MK_U8(0x0800)
145#define SMIAPP_REG_U8_THS_PREPARE SMIAPP_REG_MK_U8(0x0801)
146#define SMIAPP_REG_U8_THS_ZERO_MIN SMIAPP_REG_MK_U8(0x0802)
147#define SMIAPP_REG_U8_THS_TRAIL SMIAPP_REG_MK_U8(0x0803)
148#define SMIAPP_REG_U8_TCLK_TRAIL_MIN SMIAPP_REG_MK_U8(0x0804)
149#define SMIAPP_REG_U8_TCLK_PREPARE SMIAPP_REG_MK_U8(0x0805)
150#define SMIAPP_REG_U8_TCLK_ZERO SMIAPP_REG_MK_U8(0x0806)
151#define SMIAPP_REG_U8_TLPX SMIAPP_REG_MK_U8(0x0807)
152#define SMIAPP_REG_U8_DPHY_CTRL SMIAPP_REG_MK_U8(0x0808)
153#define SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS SMIAPP_REG_MK_U32(0x0820)
154#define SMIAPP_REG_U8_BINNING_MODE SMIAPP_REG_MK_U8(0x0900)
155#define SMIAPP_REG_U8_BINNING_TYPE SMIAPP_REG_MK_U8(0x0901)
156#define SMIAPP_REG_U8_BINNING_WEIGHTING SMIAPP_REG_MK_U8(0x0902)
157#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL SMIAPP_REG_MK_U8(0x0a00)
158#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS SMIAPP_REG_MK_U8(0x0a01)
159#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT SMIAPP_REG_MK_U8(0x0a02)
160#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 SMIAPP_REG_MK_U8(0x0a04)
161#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_1 SMIAPP_REG_MK_U8(0x0a05)
162#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_2 SMIAPP_REG_MK_U8(0x0a06)
163#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_3 SMIAPP_REG_MK_U8(0x0a07)
164#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_4 SMIAPP_REG_MK_U8(0x0a08)
165#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_5 SMIAPP_REG_MK_U8(0x0a09)
166#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_12 SMIAPP_REG_MK_U8(0x0a10)
167#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_13 SMIAPP_REG_MK_U8(0x0a11)
168#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_14 SMIAPP_REG_MK_U8(0x0a12)
169#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_15 SMIAPP_REG_MK_U8(0x0a13)
170#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_16 SMIAPP_REG_MK_U8(0x0a14)
171#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_17 SMIAPP_REG_MK_U8(0x0a15)
172#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_18 SMIAPP_REG_MK_U8(0x0a16)
173#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_19 SMIAPP_REG_MK_U8(0x0a17)
174#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_20 SMIAPP_REG_MK_U8(0x0a18)
175#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_21 SMIAPP_REG_MK_U8(0x0a19)
176#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_22 SMIAPP_REG_MK_U8(0x0a1a)
177#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_23 SMIAPP_REG_MK_U8(0x0a1b)
178#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_24 SMIAPP_REG_MK_U8(0x0a1c)
179#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_25 SMIAPP_REG_MK_U8(0x0a1d)
180#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_26 SMIAPP_REG_MK_U8(0x0a1e)
181#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_27 SMIAPP_REG_MK_U8(0x0a1f)
182#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_28 SMIAPP_REG_MK_U8(0x0a20)
183#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_29 SMIAPP_REG_MK_U8(0x0a21)
184#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_30 SMIAPP_REG_MK_U8(0x0a22)
185#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_31 SMIAPP_REG_MK_U8(0x0a23)
186#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_32 SMIAPP_REG_MK_U8(0x0a24)
187#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_33 SMIAPP_REG_MK_U8(0x0a25)
188#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_34 SMIAPP_REG_MK_U8(0x0a26)
189#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_35 SMIAPP_REG_MK_U8(0x0a27)
190#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_36 SMIAPP_REG_MK_U8(0x0a28)
191#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_37 SMIAPP_REG_MK_U8(0x0a29)
192#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_38 SMIAPP_REG_MK_U8(0x0a2a)
193#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_39 SMIAPP_REG_MK_U8(0x0a2b)
194#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_40 SMIAPP_REG_MK_U8(0x0a2c)
195#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_41 SMIAPP_REG_MK_U8(0x0a2d)
196#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_42 SMIAPP_REG_MK_U8(0x0a2e)
197#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_43 SMIAPP_REG_MK_U8(0x0a2f)
198#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_44 SMIAPP_REG_MK_U8(0x0a30)
199#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_45 SMIAPP_REG_MK_U8(0x0a31)
200#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_46 SMIAPP_REG_MK_U8(0x0a32)
201#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_47 SMIAPP_REG_MK_U8(0x0a33)
202#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_48 SMIAPP_REG_MK_U8(0x0a34)
203#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_49 SMIAPP_REG_MK_U8(0x0a35)
204#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_50 SMIAPP_REG_MK_U8(0x0a36)
205#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_51 SMIAPP_REG_MK_U8(0x0a37)
206#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_52 SMIAPP_REG_MK_U8(0x0a38)
207#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_53 SMIAPP_REG_MK_U8(0x0a39)
208#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_54 SMIAPP_REG_MK_U8(0x0a3a)
209#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_55 SMIAPP_REG_MK_U8(0x0a3b)
210#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_56 SMIAPP_REG_MK_U8(0x0a3c)
211#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_57 SMIAPP_REG_MK_U8(0x0a3d)
212#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_58 SMIAPP_REG_MK_U8(0x0a3e)
213#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_59 SMIAPP_REG_MK_U8(0x0a3f)
214#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_60 SMIAPP_REG_MK_U8(0x0a40)
215#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_61 SMIAPP_REG_MK_U8(0x0a41)
216#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_62 SMIAPP_REG_MK_U8(0x0a42)
217#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_63 SMIAPP_REG_MK_U8(0x0a43)
218#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_CTRL SMIAPP_REG_MK_U8(0x0a44)
219#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_STATUS SMIAPP_REG_MK_U8(0x0a45)
220#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_PAGE_SELECT SMIAPP_REG_MK_U8(0x0a46)
221#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_0 SMIAPP_REG_MK_U8(0x0a48)
222#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_1 SMIAPP_REG_MK_U8(0x0a49)
223#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_2 SMIAPP_REG_MK_U8(0x0a4a)
224#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_3 SMIAPP_REG_MK_U8(0x0a4b)
225#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_4 SMIAPP_REG_MK_U8(0x0a4c)
226#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_5 SMIAPP_REG_MK_U8(0x0a4d)
227#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_6 SMIAPP_REG_MK_U8(0x0a4e)
228#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_7 SMIAPP_REG_MK_U8(0x0a4f)
229#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_8 SMIAPP_REG_MK_U8(0x0a50)
230#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_9 SMIAPP_REG_MK_U8(0x0a51)
231#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_10 SMIAPP_REG_MK_U8(0x0a52)
232#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_11 SMIAPP_REG_MK_U8(0x0a53)
233#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_12 SMIAPP_REG_MK_U8(0x0a54)
234#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_13 SMIAPP_REG_MK_U8(0x0a55)
235#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_14 SMIAPP_REG_MK_U8(0x0a56)
236#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_15 SMIAPP_REG_MK_U8(0x0a57)
237#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_16 SMIAPP_REG_MK_U8(0x0a58)
238#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_17 SMIAPP_REG_MK_U8(0x0a59)
239#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_18 SMIAPP_REG_MK_U8(0x0a5a)
240#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_19 SMIAPP_REG_MK_U8(0x0a5b)
241#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_20 SMIAPP_REG_MK_U8(0x0a5c)
242#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_21 SMIAPP_REG_MK_U8(0x0a5d)
243#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_22 SMIAPP_REG_MK_U8(0x0a5e)
244#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_23 SMIAPP_REG_MK_U8(0x0a5f)
245#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_24 SMIAPP_REG_MK_U8(0x0a60)
246#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_25 SMIAPP_REG_MK_U8(0x0a61)
247#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_26 SMIAPP_REG_MK_U8(0x0a62)
248#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_27 SMIAPP_REG_MK_U8(0x0a63)
249#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_28 SMIAPP_REG_MK_U8(0x0a64)
250#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_29 SMIAPP_REG_MK_U8(0x0a65)
251#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_30 SMIAPP_REG_MK_U8(0x0a66)
252#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_31 SMIAPP_REG_MK_U8(0x0a67)
253#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_32 SMIAPP_REG_MK_U8(0x0a68)
254#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_33 SMIAPP_REG_MK_U8(0x0a69)
255#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_34 SMIAPP_REG_MK_U8(0x0a6a)
256#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_35 SMIAPP_REG_MK_U8(0x0a6b)
257#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_36 SMIAPP_REG_MK_U8(0x0a6c)
258#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_37 SMIAPP_REG_MK_U8(0x0a6d)
259#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_38 SMIAPP_REG_MK_U8(0x0a6e)
260#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_39 SMIAPP_REG_MK_U8(0x0a6f)
261#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_40 SMIAPP_REG_MK_U8(0x0a70)
262#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_41 SMIAPP_REG_MK_U8(0x0a71)
263#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_42 SMIAPP_REG_MK_U8(0x0a72)
264#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_43 SMIAPP_REG_MK_U8(0x0a73)
265#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_44 SMIAPP_REG_MK_U8(0x0a74)
266#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_45 SMIAPP_REG_MK_U8(0x0a75)
267#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_46 SMIAPP_REG_MK_U8(0x0a76)
268#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_47 SMIAPP_REG_MK_U8(0x0a77)
269#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_48 SMIAPP_REG_MK_U8(0x0a78)
270#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_49 SMIAPP_REG_MK_U8(0x0a79)
271#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_50 SMIAPP_REG_MK_U8(0x0a7a)
272#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_51 SMIAPP_REG_MK_U8(0x0a7b)
273#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_52 SMIAPP_REG_MK_U8(0x0a7c)
274#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_53 SMIAPP_REG_MK_U8(0x0a7d)
275#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_54 SMIAPP_REG_MK_U8(0x0a7e)
276#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_55 SMIAPP_REG_MK_U8(0x0a7f)
277#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_56 SMIAPP_REG_MK_U8(0x0a80)
278#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_57 SMIAPP_REG_MK_U8(0x0a81)
279#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_58 SMIAPP_REG_MK_U8(0x0a82)
280#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_59 SMIAPP_REG_MK_U8(0x0a83)
281#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_60 SMIAPP_REG_MK_U8(0x0a84)
282#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_61 SMIAPP_REG_MK_U8(0x0a85)
283#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_62 SMIAPP_REG_MK_U8(0x0a86)
284#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_63 SMIAPP_REG_MK_U8(0x0a87)
285#define SMIAPP_REG_U8_SHADING_CORRECTION_ENABLE SMIAPP_REG_MK_U8(0x0b00)
286#define SMIAPP_REG_U8_LUMINANCE_CORRECTION_LEVEL SMIAPP_REG_MK_U8(0x0b01)
287#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_ENABLE SMIAPP_REG_MK_U8(0x0b02)
288#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_WEIGHT SMIAPP_REG_MK_U8(0x0b03)
289#define SMIAPP_REG_U8_BLACK_LEVEL_CORRECTION_ENABLE SMIAPP_REG_MK_U8(0x0b04)
290#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b05)
291#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b06)
292#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_WEIGHT SMIAPP_REG_MK_U8(0x0b07)
293#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b08)
294#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_WEIGHT SMIAPP_REG_MK_U8(0x0b09)
295#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b0a)
296#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_WEIGHT SMIAPP_REG_MK_U8(0x0b0b)
297#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_ENABLE SMIAPP_REG_MK_U8(0x0b0c)
298#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_WEIGHT SMIAPP_REG_MK_U8(0x0b0d)
299#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b0e)
300#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b0f)
301#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b10)
302#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b11)
303#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b12)
304#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b13)
305#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b14)
306#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ENABLE SMIAPP_REG_MK_U8(0x0b15)
307#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ADJUST SMIAPP_REG_MK_U8(0x0b16)
308#define SMIAPP_REG_U8_EDOF_MODE SMIAPP_REG_MK_U8(0x0b80)
309#define SMIAPP_REG_U8_SHARPNESS SMIAPP_REG_MK_U8(0x0b83)
310#define SMIAPP_REG_U8_DENOISING SMIAPP_REG_MK_U8(0x0b84)
311#define SMIAPP_REG_U8_MODULE_SPECIFIC SMIAPP_REG_MK_U8(0x0b85)
312#define SMIAPP_REG_U16_DEPTH_OF_FIELD SMIAPP_REG_MK_U16(0x0b86)
313#define SMIAPP_REG_U16_FOCUS_DISTANCE SMIAPP_REG_MK_U16(0x0b88)
314#define SMIAPP_REG_U8_ESTIMATION_MODE_CTRL SMIAPP_REG_MK_U8(0x0b8a)
315#define SMIAPP_REG_U16_COLOUR_TEMPERATURE SMIAPP_REG_MK_U16(0x0b8c)
316#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENR SMIAPP_REG_MK_U16(0x0b8e)
317#define SMIAPP_REG_U16_ABSOLUTE_GAIN_RED SMIAPP_REG_MK_U16(0x0b90)
318#define SMIAPP_REG_U16_ABSOLUTE_GAIN_BLUE SMIAPP_REG_MK_U16(0x0b92)
319#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENB SMIAPP_REG_MK_U16(0x0b94)
320#define SMIAPP_REG_U8_ESTIMATION_ZONE_MODE SMIAPP_REG_MK_U8(0x0bc0)
321#define SMIAPP_REG_U16_FIXED_ZONE_WEIGHTING SMIAPP_REG_MK_U16(0x0bc2)
322#define SMIAPP_REG_U16_CUSTOM_ZONE_X_START SMIAPP_REG_MK_U16(0x0bc4)
323#define SMIAPP_REG_U16_CUSTOM_ZONE_Y_START SMIAPP_REG_MK_U16(0x0bc6)
324#define SMIAPP_REG_U16_CUSTOM_ZONE_WIDTH SMIAPP_REG_MK_U16(0x0bc8)
325#define SMIAPP_REG_U16_CUSTOM_ZONE_HEIGHT SMIAPP_REG_MK_U16(0x0bca)
326#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL1 SMIAPP_REG_MK_U8(0x0c00)
327#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL2 SMIAPP_REG_MK_U8(0x0c01)
328#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_1 SMIAPP_REG_MK_U8(0x0c02)
329#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_2 SMIAPP_REG_MK_U8(0x0c03)
330#define SMIAPP_REG_U16_TRDY_CTRL SMIAPP_REG_MK_U16(0x0c04)
331#define SMIAPP_REG_U16_TRDOUT_CTRL SMIAPP_REG_MK_U16(0x0c06)
332#define SMIAPP_REG_U16_TSHUTTER_STROBE_DELAY_CTRL SMIAPP_REG_MK_U16(0x0c08)
333#define SMIAPP_REG_U16_TSHUTTER_STROBE_WIDTH_CTRL SMIAPP_REG_MK_U16(0x0c0a)
334#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_CTRL SMIAPP_REG_MK_U16(0x0c0c)
335#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_CTRL SMIAPP_REG_MK_U16(0x0c0e)
336#define SMIAPP_REG_U16_TGRST_INTERVAL_CTRL SMIAPP_REG_MK_U16(0x0c10)
337#define SMIAPP_REG_U8_FLASH_STROBE_ADJUSTMENT SMIAPP_REG_MK_U8(0x0c12)
338#define SMIAPP_REG_U16_FLASH_STROBE_START_POINT SMIAPP_REG_MK_U16(0x0c14)
339#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_RS_CTRL SMIAPP_REG_MK_U16(0x0c16)
340#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_RS_CTRL SMIAPP_REG_MK_U16(0x0c18)
341#define SMIAPP_REG_U8_FLASH_MODE_RS SMIAPP_REG_MK_U8(0x0c1a)
342#define SMIAPP_REG_U8_FLASH_TRIGGER_RS SMIAPP_REG_MK_U8(0x0c1b)
343#define SMIAPP_REG_U8_FLASH_STATUS SMIAPP_REG_MK_U8(0x0c1c)
344#define SMIAPP_REG_U8_SA_STROBE_MODE SMIAPP_REG_MK_U8(0x0c1d)
345#define SMIAPP_REG_U16_SA_STROBE_START_POINT SMIAPP_REG_MK_U16(0x0c1e)
346#define SMIAPP_REG_U16_TSA_STROBE_DELAY_CTRL SMIAPP_REG_MK_U16(0x0c20)
347#define SMIAPP_REG_U16_TSA_STROBE_WIDTH_CTRL SMIAPP_REG_MK_U16(0x0c22)
348#define SMIAPP_REG_U8_SA_STROBE_TRIGGER SMIAPP_REG_MK_U8(0x0c24)
349#define SMIAPP_REG_U8_SPECIAL_ACTUATOR_STATUS SMIAPP_REG_MK_U8(0x0c25)
350#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_RS_CTRL SMIAPP_REG_MK_U16(0x0c26)
351#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_RS_CTRL SMIAPP_REG_MK_U16(0x0c28)
352#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_RS_CTRL SMIAPP_REG_MK_U8(0x0c2a)
353#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_CTRL SMIAPP_REG_MK_U8(0x0c2b)
354#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_CTRL SMIAPP_REG_MK_U16(0x0c2c)
355#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_CTRL SMIAPP_REG_MK_U16(0x0c2e)
356#define SMIAPP_REG_U8_LOW_LEVEL_CTRL SMIAPP_REG_MK_U8(0x0c80)
357#define SMIAPP_REG_U16_MAIN_TRIGGER_REF_POINT SMIAPP_REG_MK_U16(0x0c82)
358#define SMIAPP_REG_U16_MAIN_TRIGGER_T3 SMIAPP_REG_MK_U16(0x0c84)
359#define SMIAPP_REG_U8_MAIN_TRIGGER_COUNT SMIAPP_REG_MK_U8(0x0c86)
360#define SMIAPP_REG_U16_PHASE1_TRIGGER_T3 SMIAPP_REG_MK_U16(0x0c88)
361#define SMIAPP_REG_U8_PHASE1_TRIGGER_COUNT SMIAPP_REG_MK_U8(0x0c8a)
362#define SMIAPP_REG_U16_PHASE2_TRIGGER_T3 SMIAPP_REG_MK_U16(0x0c8c)
363#define SMIAPP_REG_U8_PHASE2_TRIGGER_COUNT SMIAPP_REG_MK_U8(0x0c8e)
364#define SMIAPP_REG_U8_MECH_SHUTTER_CTRL SMIAPP_REG_MK_U8(0x0d00)
365#define SMIAPP_REG_U8_OPERATION_MODE SMIAPP_REG_MK_U8(0x0d01)
366#define SMIAPP_REG_U8_ACT_STATE1 SMIAPP_REG_MK_U8(0x0d02)
367#define SMIAPP_REG_U8_ACT_STATE2 SMIAPP_REG_MK_U8(0x0d03)
368#define SMIAPP_REG_U16_FOCUS_CHANGE SMIAPP_REG_MK_U16(0x0d80)
369#define SMIAPP_REG_U16_FOCUS_CHANGE_CONTROL SMIAPP_REG_MK_U16(0x0d82)
370#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE1 SMIAPP_REG_MK_U16(0x0d84)
371#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE2 SMIAPP_REG_MK_U16(0x0d86)
372#define SMIAPP_REG_U8_STROBE_COUNT_PHASE1 SMIAPP_REG_MK_U8(0x0d88)
373#define SMIAPP_REG_U8_STROBE_COUNT_PHASE2 SMIAPP_REG_MK_U8(0x0d89)
374#define SMIAPP_REG_U8_POSITION SMIAPP_REG_MK_U8(0x0d8a)
375#define SMIAPP_REG_U8_BRACKETING_LUT_CONTROL SMIAPP_REG_MK_U8(0x0e00)
376#define SMIAPP_REG_U8_BRACKETING_LUT_MODE SMIAPP_REG_MK_U8(0x0e01)
377#define SMIAPP_REG_U8_BRACKETING_LUT_ENTRY_CONTROL SMIAPP_REG_MK_U8(0x0e02)
378#define SMIAPP_REG_U8_LUT_PARAMETERS_START SMIAPP_REG_MK_U8(0x0e10)
379#define SMIAPP_REG_U8_LUT_PARAMETERS_END SMIAPP_REG_MK_U8(0x0eff)
380#define SMIAPP_REG_U16_INTEGRATION_TIME_CAPABILITY SMIAPP_REG_MK_U16(0x1000)
381#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MIN SMIAPP_REG_MK_U16(0x1004)
382#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MAX_MARGIN SMIAPP_REG_MK_U16(0x1006)
383#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN SMIAPP_REG_MK_U16(0x1008)
384#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN SMIAPP_REG_MK_U16(0x100a)
385#define SMIAPP_REG_U16_DIGITAL_GAIN_CAPABILITY SMIAPP_REG_MK_U16(0x1080)
386#define SMIAPP_REG_U16_DIGITAL_GAIN_MIN SMIAPP_REG_MK_U16(0x1084)
387#define SMIAPP_REG_U16_DIGITAL_GAIN_MAX SMIAPP_REG_MK_U16(0x1086)
388#define SMIAPP_REG_U16_DIGITAL_GAIN_STEP_SIZE SMIAPP_REG_MK_U16(0x1088)
389#define SMIAPP_REG_F32_MIN_EXT_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1100)
390#define SMIAPP_REG_F32_MAX_EXT_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1104)
391#define SMIAPP_REG_U16_MIN_PRE_PLL_CLK_DIV SMIAPP_REG_MK_U16(0x1108)
392#define SMIAPP_REG_U16_MAX_PRE_PLL_CLK_DIV SMIAPP_REG_MK_U16(0x110a)
393#define SMIAPP_REG_F32_MIN_PLL_IP_FREQ_HZ SMIAPP_REG_MK_F32(0x110c)
394#define SMIAPP_REG_F32_MAX_PLL_IP_FREQ_HZ SMIAPP_REG_MK_F32(0x1110)
395#define SMIAPP_REG_U16_MIN_PLL_MULTIPLIER SMIAPP_REG_MK_U16(0x1114)
396#define SMIAPP_REG_U16_MAX_PLL_MULTIPLIER SMIAPP_REG_MK_U16(0x1116)
397#define SMIAPP_REG_F32_MIN_PLL_OP_FREQ_HZ SMIAPP_REG_MK_F32(0x1118)
398#define SMIAPP_REG_F32_MAX_PLL_OP_FREQ_HZ SMIAPP_REG_MK_F32(0x111c)
399#define SMIAPP_REG_U16_MIN_VT_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1120)
400#define SMIAPP_REG_U16_MAX_VT_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1122)
401#define SMIAPP_REG_F32_MIN_VT_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1124)
402#define SMIAPP_REG_F32_MAX_VT_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1128)
403#define SMIAPP_REG_F32_MIN_VT_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x112c)
404#define SMIAPP_REG_F32_MAX_VT_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1130)
405#define SMIAPP_REG_U16_MIN_VT_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x1134)
406#define SMIAPP_REG_U16_MAX_VT_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x1136)
407#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES SMIAPP_REG_MK_U16(0x1140)
408#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES SMIAPP_REG_MK_U16(0x1142)
409#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK SMIAPP_REG_MK_U16(0x1144)
410#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK SMIAPP_REG_MK_U16(0x1146)
411#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK SMIAPP_REG_MK_U16(0x1148)
412#define SMIAPP_REG_U16_MIN_FRAME_BLANKING_LINES SMIAPP_REG_MK_U16(0x114a)
413#define SMIAPP_REG_U8_MIN_LINE_LENGTH_PCK_STEP_SIZE SMIAPP_REG_MK_U8(0x114c)
414#define SMIAPP_REG_U16_MIN_OP_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1160)
415#define SMIAPP_REG_U16_MAX_OP_SYS_CLK_DIV SMIAPP_REG_MK_U16(0x1162)
416#define SMIAPP_REG_F32_MIN_OP_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1164)
417#define SMIAPP_REG_F32_MAX_OP_SYS_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1168)
418#define SMIAPP_REG_U16_MIN_OP_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x116c)
419#define SMIAPP_REG_U16_MAX_OP_PIX_CLK_DIV SMIAPP_REG_MK_U16(0x116e)
420#define SMIAPP_REG_F32_MIN_OP_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1170)
421#define SMIAPP_REG_F32_MAX_OP_PIX_CLK_FREQ_HZ SMIAPP_REG_MK_F32(0x1174)
422#define SMIAPP_REG_U16_X_ADDR_MIN SMIAPP_REG_MK_U16(0x1180)
423#define SMIAPP_REG_U16_Y_ADDR_MIN SMIAPP_REG_MK_U16(0x1182)
424#define SMIAPP_REG_U16_X_ADDR_MAX SMIAPP_REG_MK_U16(0x1184)
425#define SMIAPP_REG_U16_Y_ADDR_MAX SMIAPP_REG_MK_U16(0x1186)
426#define SMIAPP_REG_U16_MIN_X_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x1188)
427#define SMIAPP_REG_U16_MIN_Y_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x118a)
428#define SMIAPP_REG_U16_MAX_X_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x118c)
429#define SMIAPP_REG_U16_MAX_Y_OUTPUT_SIZE SMIAPP_REG_MK_U16(0x118e)
430#define SMIAPP_REG_U16_MIN_EVEN_INC SMIAPP_REG_MK_U16(0x11c0)
431#define SMIAPP_REG_U16_MAX_EVEN_INC SMIAPP_REG_MK_U16(0x11c2)
432#define SMIAPP_REG_U16_MIN_ODD_INC SMIAPP_REG_MK_U16(0x11c4)
433#define SMIAPP_REG_U16_MAX_ODD_INC SMIAPP_REG_MK_U16(0x11c6)
434#define SMIAPP_REG_U16_SCALING_CAPABILITY SMIAPP_REG_MK_U16(0x1200)
435#define SMIAPP_REG_U16_SCALER_M_MIN SMIAPP_REG_MK_U16(0x1204)
436#define SMIAPP_REG_U16_SCALER_M_MAX SMIAPP_REG_MK_U16(0x1206)
437#define SMIAPP_REG_U16_SCALER_N_MIN SMIAPP_REG_MK_U16(0x1208)
438#define SMIAPP_REG_U16_SCALER_N_MAX SMIAPP_REG_MK_U16(0x120a)
439#define SMIAPP_REG_U16_SPATIAL_SAMPLING_CAPABILITY SMIAPP_REG_MK_U16(0x120c)
440#define SMIAPP_REG_U8_DIGITAL_CROP_CAPABILITY SMIAPP_REG_MK_U8(0x120e)
441#define SMIAPP_REG_U16_COMPRESSION_CAPABILITY SMIAPP_REG_MK_U16(0x1300)
442#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINRED SMIAPP_REG_MK_U16(0x1400)
443#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINRED SMIAPP_REG_MK_U16(0x1402)
444#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINRED SMIAPP_REG_MK_U16(0x1404)
445#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINGREEN SMIAPP_REG_MK_U16(0x1406)
446#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINGREEN SMIAPP_REG_MK_U16(0x1408)
447#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINGREEN SMIAPP_REG_MK_U16(0x140a)
448#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINBLUE SMIAPP_REG_MK_U16(0x140c)
449#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINBLUE SMIAPP_REG_MK_U16(0x140e)
450#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINBLUE SMIAPP_REG_MK_U16(0x1410)
451#define SMIAPP_REG_U16_FIFO_SIZE_PIXELS SMIAPP_REG_MK_U16(0x1500)
452#define SMIAPP_REG_U8_FIFO_SUPPORT_CAPABILITY SMIAPP_REG_MK_U8(0x1502)
453#define SMIAPP_REG_U8_DPHY_CTRL_CAPABILITY SMIAPP_REG_MK_U8(0x1600)
454#define SMIAPP_REG_U8_CSI_LANE_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x1601)
455#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x1602)
456#define SMIAPP_REG_U8_FAST_STANDBY_CAPABILITY SMIAPP_REG_MK_U8(0x1603)
457#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL_CAPABILITY SMIAPP_REG_MK_U8(0x1604)
458#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x1608)
459#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x160c)
460#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x1610)
461#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS SMIAPP_REG_MK_U32(0x1614)
462#define SMIAPP_REG_U8_TEMP_SENSOR_CAPABILITY SMIAPP_REG_MK_U8(0x1618)
463#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES_BIN SMIAPP_REG_MK_U16(0x1700)
464#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES_BIN SMIAPP_REG_MK_U16(0x1702)
465#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK_BIN SMIAPP_REG_MK_U16(0x1704)
466#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK_BIN SMIAPP_REG_MK_U16(0x1706)
467#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK_BIN SMIAPP_REG_MK_U16(0x1708)
468#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN_BIN SMIAPP_REG_MK_U16(0x170a)
469#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN SMIAPP_REG_MK_U16(0x170c)
470#define SMIAPP_REG_U8_BINNING_CAPABILITY SMIAPP_REG_MK_U8(0x1710)
471#define SMIAPP_REG_U8_BINNING_WEIGHTING_CAPABILITY SMIAPP_REG_MK_U8(0x1711)
472#define SMIAPP_REG_U8_BINNING_SUBTYPES SMIAPP_REG_MK_U8(0x1712)
473#define SMIAPP_REG_U8_BINNING_TYPE_n(n) SMIAPP_REG_MK_U8(0x1713 + (n)) /* 1 <= n <= 237 */
474#define SMIAPP_REG_U8_DATA_TRANSFER_IF_CAPABILITY SMIAPP_REG_MK_U8(0x1800)
475#define SMIAPP_REG_U8_SHADING_CORRECTION_CAPABILITY SMIAPP_REG_MK_U8(0x1900)
476#define SMIAPP_REG_U8_GREEN_IMBALANCE_CAPABILITY SMIAPP_REG_MK_U8(0x1901)
477#define SMIAPP_REG_U8_BLACK_LEVEL_CAPABILITY SMIAPP_REG_MK_U8(0x1902)
478#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_CAPABILITY SMIAPP_REG_MK_U8(0x1903)
479#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY SMIAPP_REG_MK_U16(0x1904)
480#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY_2 SMIAPP_REG_MK_U16(0x1906)
481#define SMIAPP_REG_U8_EDOF_CAPABILITY SMIAPP_REG_MK_U8(0x1980)
482#define SMIAPP_REG_U8_ESTIMATION_FRAMES SMIAPP_REG_MK_U8(0x1981)
483#define SMIAPP_REG_U8_SUPPORTS_SHARPNESS_ADJ SMIAPP_REG_MK_U8(0x1982)
484#define SMIAPP_REG_U8_SUPPORTS_DENOISING_ADJ SMIAPP_REG_MK_U8(0x1983)
485#define SMIAPP_REG_U8_SUPPORTS_MODULE_SPECIFIC_ADJ SMIAPP_REG_MK_U8(0x1984)
486#define SMIAPP_REG_U8_SUPPORTS_DEPTH_OF_FIELD_ADJ SMIAPP_REG_MK_U8(0x1985)
487#define SMIAPP_REG_U8_SUPPORTS_FOCUS_DISTANCE_ADJ SMIAPP_REG_MK_U8(0x1986)
488#define SMIAPP_REG_U8_COLOUR_FEEDBACK_CAPABILITY SMIAPP_REG_MK_U8(0x1987)
489#define SMIAPP_REG_U8_EDOF_SUPPORT_AB_NXM SMIAPP_REG_MK_U8(0x1988)
490#define SMIAPP_REG_U8_ESTIMATION_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x19c0)
491#define SMIAPP_REG_U8_ESTIMATION_ZONE_CAPABILITY SMIAPP_REG_MK_U8(0x19c1)
492#define SMIAPP_REG_U16_EST_DEPTH_OF_FIELD SMIAPP_REG_MK_U16(0x19c2)
493#define SMIAPP_REG_U16_EST_FOCUS_DISTANCE SMIAPP_REG_MK_U16(0x19c4)
494#define SMIAPP_REG_U16_CAPABILITY_TRDY_MIN SMIAPP_REG_MK_U16(0x1a00)
495#define SMIAPP_REG_U8_FLASH_MODE_CAPABILITY SMIAPP_REG_MK_U8(0x1a02)
496#define SMIAPP_REG_U16_MECH_SHUT_AND_ACT_START_ADDR SMIAPP_REG_MK_U16(0x1b02)
497#define SMIAPP_REG_U8_ACTUATOR_CAPABILITY SMIAPP_REG_MK_U8(0x1b04)
498#define SMIAPP_REG_U16_ACTUATOR_TYPE SMIAPP_REG_MK_U16(0x1b40)
499#define SMIAPP_REG_U8_AF_DEVICE_ADDRESS SMIAPP_REG_MK_U8(0x1b42)
500#define SMIAPP_REG_U16_FOCUS_CHANGE_ADDRESS SMIAPP_REG_MK_U16(0x1b44)
501#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_1 SMIAPP_REG_MK_U8(0x1c00)
502#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_2 SMIAPP_REG_MK_U8(0x1c01)
503#define SMIAPP_REG_U8_BRACKETING_LUT_SIZE SMIAPP_REG_MK_U8(0x1c02)
diff --git a/drivers/media/video/smiapp/smiapp-reg.h b/drivers/media/video/smiapp/smiapp-reg.h
new file mode 100644
index 000000000000..d0167aa17534
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-reg.h
@@ -0,0 +1,122 @@
1/*
2 * drivers/media/video/smiapp/smiapp-reg.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#ifndef __SMIAPP_REG_H_
26#define __SMIAPP_REG_H_
27
28#include "smiapp-reg-defs.h"
29
30/* Bits for above register */
31#define SMIAPP_IMAGE_ORIENTATION_HFLIP (1 << 0)
32#define SMIAPP_IMAGE_ORIENTATION_VFLIP (1 << 1)
33
34#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_EN (1 << 0)
35#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_RD_EN (0 << 1)
36#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_WR_EN (1 << 1)
37#define SMIAPP_DATA_TRANSFER_IF_1_CTRL_ERR_CLEAR (1 << 2)
38#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY (1 << 0)
39#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_WR_READY (1 << 1)
40#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_EDATA (1 << 2)
41#define SMIAPP_DATA_TRANSFER_IF_1_STATUS_EUSAGE (1 << 3)
42
43#define SMIAPP_SOFTWARE_RESET (1 << 0)
44
45#define SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE (1 << 0)
46#define SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE (1 << 1)
47
48#define SMIAPP_DPHY_CTRL_AUTOMATIC 0
49/* DPHY control based on REQUESTED_LINK_BIT_RATE_MBPS */
50#define SMIAPP_DPHY_CTRL_UI 1
51#define SMIAPP_DPHY_CTRL_REGISTER 2
52
53#define SMIAPP_COMPRESSION_MODE_SIMPLE_PREDICTOR 1
54#define SMIAPP_COMPRESSION_MODE_ADVANCED_PREDICTOR 2
55
56#define SMIAPP_MODE_SELECT_SOFTWARE_STANDBY 0
57#define SMIAPP_MODE_SELECT_STREAMING 1
58
59#define SMIAPP_SCALING_MODE_NONE 0
60#define SMIAPP_SCALING_MODE_HORIZONTAL 1
61#define SMIAPP_SCALING_MODE_BOTH 2
62
63#define SMIAPP_SCALING_CAPABILITY_NONE 0
64#define SMIAPP_SCALING_CAPABILITY_HORIZONTAL 1
65#define SMIAPP_SCALING_CAPABILITY_BOTH 2 /* horizontal/both */
66
67/* digital crop right before scaler */
68#define SMIAPP_DIGITAL_CROP_CAPABILITY_NONE 0
69#define SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP 1
70
71#define SMIAPP_BINNING_CAPABILITY_NO 0
72#define SMIAPP_BINNING_CAPABILITY_YES 1
73
74/* Maximum number of binning subtypes */
75#define SMIAPP_BINNING_SUBTYPES 253
76
77#define SMIAPP_PIXEL_ORDER_GRBG 0
78#define SMIAPP_PIXEL_ORDER_RGGB 1
79#define SMIAPP_PIXEL_ORDER_BGGR 2
80#define SMIAPP_PIXEL_ORDER_GBRG 3
81
82#define SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL 1
83#define SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED 2
84#define SMIAPP_DATA_FORMAT_MODEL_TYPE_NORMAL_N 8
85#define SMIAPP_DATA_FORMAT_MODEL_TYPE_EXTENDED_N 16
86
87#define SMIAPP_FRAME_FORMAT_MODEL_TYPE_2BYTE 0x01
88#define SMIAPP_FRAME_FORMAT_MODEL_TYPE_4BYTE 0x02
89#define SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NROWS_MASK 0x0f
90#define SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_MASK 0xf0
91#define SMIAPP_FRAME_FORMAT_MODEL_SUBTYPE_NCOLS_SHIFT 4
92
93#define SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_MASK 0xf000
94#define SMIAPP_FRAME_FORMAT_DESC_2_PIXELCODE_SHIFT 12
95#define SMIAPP_FRAME_FORMAT_DESC_2_PIXELS_MASK 0x0fff
96
97#define SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_MASK 0xf0000000
98#define SMIAPP_FRAME_FORMAT_DESC_4_PIXELCODE_SHIFT 28
99#define SMIAPP_FRAME_FORMAT_DESC_4_PIXELS_MASK 0x0000ffff
100
101#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_EMBEDDED 1
102#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DUMMY 2
103#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_BLACK 3
104#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_DARK 4
105#define SMIAPP_FRAME_FORMAT_DESC_PIXELCODE_VISIBLE 5
106
107#define SMIAPP_FAST_STANDBY_CTRL_COMPLETE_FRAMES 0
108#define SMIAPP_FAST_STANDBY_CTRL_IMMEDIATE 1
109
110/* Scaling N factor */
111#define SMIAPP_SCALE_N 16
112
113/* Image statistics registers */
114/* Registers 0x2000 to 0x2fff are reserved for future
115 * use for statistics features.
116 */
117
118/* Manufacturer Specific Registers: 0x3000 to 0x3fff
119 * The manufacturer specifies these as a black box.
120 */
121
122#endif /* __SMIAPP_REG_H_ */
diff --git a/drivers/media/video/smiapp/smiapp-regs.c b/drivers/media/video/smiapp/smiapp-regs.c
new file mode 100644
index 000000000000..b1812b17a407
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-regs.c
@@ -0,0 +1,273 @@
1/*
2 * drivers/media/video/smiapp/smiapp-regs.c
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#include <linux/delay.h>
26#include <linux/i2c.h>
27
28#include "smiapp.h"
29#include "smiapp-regs.h"
30
31static uint32_t float_to_u32_mul_1000000(struct i2c_client *client,
32 uint32_t phloat)
33{
34 int32_t exp;
35 uint64_t man;
36
37 if (phloat >= 0x80000000) {
38 dev_err(&client->dev, "this is a negative number\n");
39 return 0;
40 }
41
42 if (phloat == 0x7f800000)
43 return ~0; /* Inf. */
44
45 if ((phloat & 0x7f800000) == 0x7f800000) {
46 dev_err(&client->dev, "NaN or other special number\n");
47 return 0;
48 }
49
50 /* Valid cases begin here */
51 if (phloat == 0)
52 return 0; /* Valid zero */
53
54 if (phloat > 0x4f800000)
55 return ~0; /* larger than 4294967295 */
56
57 /*
58 * Unbias exponent (note how phloat is now guaranteed to
59 * have 0 in the high bit)
60 */
61 exp = ((int32_t)phloat >> 23) - 127;
62
63 /* Extract mantissa, add missing '1' bit and it's in MHz */
64 man = ((phloat & 0x7fffff) | 0x800000) * 1000000ULL;
65
66 if (exp < 0)
67 man >>= -exp;
68 else
69 man <<= exp;
70
71 man >>= 23; /* Remove mantissa bias */
72
73 return man & 0xffffffff;
74}
75
76
77/*
78 * Read a 8/16/32-bit i2c register. The value is returned in 'val'.
79 * Returns zero if successful, or non-zero otherwise.
80 */
81static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg,
82 u16 len, u32 *val)
83{
84 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
85 struct i2c_msg msg;
86 unsigned char data[4];
87 u16 offset = reg;
88 int r;
89
90 msg.addr = client->addr;
91 msg.flags = 0;
92 msg.len = 2;
93 msg.buf = data;
94
95 /* high byte goes out first */
96 data[0] = (u8) (offset >> 8);
97 data[1] = (u8) offset;
98 r = i2c_transfer(client->adapter, &msg, 1);
99 if (r != 1) {
100 if (r >= 0)
101 r = -EBUSY;
102 goto err;
103 }
104
105 msg.len = len;
106 msg.flags = I2C_M_RD;
107 r = i2c_transfer(client->adapter, &msg, 1);
108 if (r != 1) {
109 if (r >= 0)
110 r = -EBUSY;
111 goto err;
112 }
113
114 *val = 0;
115 /* high byte comes first */
116 switch (len) {
117 case SMIA_REG_32BIT:
118 *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
119 data[3];
120 break;
121 case SMIA_REG_16BIT:
122 *val = (data[0] << 8) + data[1];
123 break;
124 case SMIA_REG_8BIT:
125 *val = data[0];
126 break;
127 default:
128 BUG();
129 }
130
131 return 0;
132
133err:
134 dev_err(&client->dev, "read from offset 0x%x error %d\n", offset, r);
135
136 return r;
137}
138
139/* Read a register using 8-bit access only. */
140static int ____smiapp_read_8only(struct smiapp_sensor *sensor, u16 reg,
141 u16 len, u32 *val)
142{
143 unsigned int i;
144 int rval;
145
146 *val = 0;
147
148 for (i = 0; i < len; i++) {
149 u32 val8;
150
151 rval = ____smiapp_read(sensor, reg + i, 1, &val8);
152 if (rval < 0)
153 return rval;
154 *val |= val8 << ((len - i - 1) << 3);
155 }
156
157 return 0;
158}
159
160/*
161 * Read a 8/16/32-bit i2c register. The value is returned in 'val'.
162 * Returns zero if successful, or non-zero otherwise.
163 */
164static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val,
165 bool only8)
166{
167 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
168 unsigned int len = (u8)(reg >> 16);
169 int rval;
170
171 if (len != SMIA_REG_8BIT && len != SMIA_REG_16BIT
172 && len != SMIA_REG_32BIT)
173 return -EINVAL;
174
175 if (smiapp_quirk_reg(sensor, reg, val))
176 goto found_quirk;
177
178 if (len == SMIA_REG_8BIT && !only8)
179 rval = ____smiapp_read(sensor, (u16)reg, len, val);
180 else
181 rval = ____smiapp_read_8only(sensor, (u16)reg, len, val);
182 if (rval < 0)
183 return rval;
184
185found_quirk:
186 if (reg & SMIA_REG_FLAG_FLOAT)
187 *val = float_to_u32_mul_1000000(client, *val);
188
189 return 0;
190}
191
192int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
193{
194 return __smiapp_read(
195 sensor, reg, val,
196 smiapp_needs_quirk(sensor,
197 SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
198}
199
200int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val)
201{
202 return __smiapp_read(sensor, reg, val, true);
203}
204
205/*
206 * Write to a 8/16-bit register.
207 * Returns zero if successful, or non-zero otherwise.
208 */
209int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
210{
211 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
212 struct i2c_msg msg;
213 unsigned char data[6];
214 unsigned int retries;
215 unsigned int flags = reg >> 24;
216 unsigned int len = (u8)(reg >> 16);
217 u16 offset = reg;
218 int r;
219
220 if ((len != SMIA_REG_8BIT && len != SMIA_REG_16BIT &&
221 len != SMIA_REG_32BIT) || flags)
222 return -EINVAL;
223
224 msg.addr = client->addr;
225 msg.flags = 0; /* Write */
226 msg.len = 2 + len;
227 msg.buf = data;
228
229 /* high byte goes out first */
230 data[0] = (u8) (reg >> 8);
231 data[1] = (u8) (reg & 0xff);
232
233 switch (len) {
234 case SMIA_REG_8BIT:
235 data[2] = val;
236 break;
237 case SMIA_REG_16BIT:
238 data[2] = val >> 8;
239 data[3] = val;
240 break;
241 case SMIA_REG_32BIT:
242 data[2] = val >> 24;
243 data[3] = val >> 16;
244 data[4] = val >> 8;
245 data[5] = val;
246 break;
247 default:
248 BUG();
249 }
250
251 for (retries = 0; retries < 5; retries++) {
252 /*
253 * Due to unknown reason sensor stops responding. This
254 * loop is a temporaty solution until the root cause
255 * is found.
256 */
257 r = i2c_transfer(client->adapter, &msg, 1);
258 if (r == 1) {
259 if (retries)
260 dev_err(&client->dev,
261 "sensor i2c stall encountered. "
262 "retries: %d\n", retries);
263 return 0;
264 }
265
266 usleep_range(2000, 2000);
267 }
268
269 dev_err(&client->dev,
270 "wrote 0x%x to offset 0x%x error %d\n", val, offset, r);
271
272 return r;
273}
diff --git a/drivers/media/video/smiapp/smiapp-regs.h b/drivers/media/video/smiapp/smiapp-regs.h
new file mode 100644
index 000000000000..7f9013b47971
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp-regs.h
@@ -0,0 +1,49 @@
1/*
2 * include/media/smiapp/smiapp-regs.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#ifndef SMIAPP_REGS_H
26#define SMIAPP_REGS_H
27
28#include <linux/i2c.h>
29#include <linux/types.h>
30
31/* Use upper 8 bits of the type field for flags */
32#define SMIA_REG_FLAG_FLOAT (1 << 24)
33
34#define SMIA_REG_8BIT 1
35#define SMIA_REG_16BIT 2
36#define SMIA_REG_32BIT 4
37struct smia_reg {
38 u16 type;
39 u16 reg; /* 16-bit offset */
40 u32 val; /* 8/16/32-bit value */
41};
42
43struct smiapp_sensor;
44
45int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
46int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
47int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
48
49#endif
diff --git a/drivers/media/video/smiapp/smiapp.h b/drivers/media/video/smiapp/smiapp.h
new file mode 100644
index 000000000000..587f7f11238d
--- /dev/null
+++ b/drivers/media/video/smiapp/smiapp.h
@@ -0,0 +1,252 @@
1/*
2 * drivers/media/video/smiapp/smiapp.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2010--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#ifndef __SMIAPP_PRIV_H_
26#define __SMIAPP_PRIV_H_
27
28#include <linux/mutex.h>
29#include <media/v4l2-ctrls.h>
30#include <media/v4l2-subdev.h>
31#include <media/smiapp.h>
32
33#include "smiapp-pll.h"
34#include "smiapp-reg.h"
35#include "smiapp-regs.h"
36#include "smiapp-quirk.h"
37
38/*
39 * Standard SMIA++ constants
40 */
41#define SMIA_VERSION_1 10
42#define SMIAPP_VERSION_0_8 8 /* Draft 0.8 */
43#define SMIAPP_VERSION_0_9 9 /* Draft 0.9 */
44#define SMIAPP_VERSION_1 10
45
46#define SMIAPP_PROFILE_0 0
47#define SMIAPP_PROFILE_1 1
48#define SMIAPP_PROFILE_2 2
49
50#define SMIAPP_NVM_PAGE_SIZE 64 /* bytes */
51
52#define SMIAPP_RESET_DELAY_CLOCKS 2400
53#define SMIAPP_RESET_DELAY(clk) \
54 (1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \
55 + (clk) / 1000 - 1) / ((clk) / 1000))
56
57#include "smiapp-limits.h"
58
59struct smiapp_quirk;
60
61#define SMIAPP_MODULE_IDENT_FLAG_REV_LE (1 << 0)
62
63struct smiapp_module_ident {
64 u8 manufacturer_id;
65 u16 model_id;
66 u8 revision_number_major;
67
68 u8 flags;
69
70 char *name;
71 const struct smiapp_quirk *quirk;
72};
73
74struct smiapp_module_info {
75 u32 manufacturer_id;
76 u32 model_id;
77 u32 revision_number_major;
78 u32 revision_number_minor;
79
80 u32 module_year;
81 u32 module_month;
82 u32 module_day;
83
84 u32 sensor_manufacturer_id;
85 u32 sensor_model_id;
86 u32 sensor_revision_number;
87 u32 sensor_firmware_version;
88
89 u32 smia_version;
90 u32 smiapp_version;
91
92 u32 smiapp_profile;
93
94 char *name;
95 const struct smiapp_quirk *quirk;
96};
97
98#define SMIAPP_IDENT_FQ(manufacturer, model, rev, fl, _name, _quirk) \
99 { .manufacturer_id = manufacturer, \
100 .model_id = model, \
101 .revision_number_major = rev, \
102 .flags = fl, \
103 .name = _name, \
104 .quirk = _quirk, }
105
106#define SMIAPP_IDENT_LQ(manufacturer, model, rev, _name, _quirk) \
107 { .manufacturer_id = manufacturer, \
108 .model_id = model, \
109 .revision_number_major = rev, \
110 .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE, \
111 .name = _name, \
112 .quirk = _quirk, }
113
114#define SMIAPP_IDENT_L(manufacturer, model, rev, _name) \
115 { .manufacturer_id = manufacturer, \
116 .model_id = model, \
117 .revision_number_major = rev, \
118 .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE, \
119 .name = _name, }
120
121#define SMIAPP_IDENT_Q(manufacturer, model, rev, _name, _quirk) \
122 { .manufacturer_id = manufacturer, \
123 .model_id = model, \
124 .revision_number_major = rev, \
125 .flags = 0, \
126 .name = _name, \
127 .quirk = _quirk, }
128
129#define SMIAPP_IDENT(manufacturer, model, rev, _name) \
130 { .manufacturer_id = manufacturer, \
131 .model_id = model, \
132 .revision_number_major = rev, \
133 .flags = 0, \
134 .name = _name, }
135
136struct smiapp_reg_limits {
137 u32 addr;
138 char *what;
139};
140
141extern struct smiapp_reg_limits smiapp_reg_limits[];
142
143struct smiapp_csi_data_format {
144 u32 code;
145 u8 width;
146 u8 compressed;
147 u8 pixel_order;
148};
149
150#define SMIAPP_SUBDEVS 3
151
152#define SMIAPP_PA_PAD_SRC 0
153#define SMIAPP_PAD_SINK 0
154#define SMIAPP_PAD_SRC 1
155#define SMIAPP_PADS 2
156
157struct smiapp_binning_subtype {
158 u8 horizontal:4;
159 u8 vertical:4;
160} __packed;
161
162struct smiapp_subdev {
163 struct v4l2_subdev sd;
164 struct media_pad pads[2];
165 struct v4l2_rect sink_fmt;
166 struct v4l2_rect crop[2];
167 struct v4l2_rect compose; /* compose on sink */
168 unsigned short sink_pad;
169 unsigned short source_pad;
170 int npads;
171 struct smiapp_sensor *sensor;
172 struct v4l2_ctrl_handler ctrl_handler;
173};
174
175/*
176 * struct smiapp_sensor - Main device structure
177 */
178struct smiapp_sensor {
179 /*
180 * "mutex" is used to serialise access to all fields here
181 * except v4l2_ctrls at the end of the struct. "mutex" is also
182 * used to serialise access to file handle specific
183 * information. The exception to this rule is the power_mutex
184 * below.
185 */
186 struct mutex mutex;
187 /*
188 * power_mutex is used to serialise power management related
189 * activities. Acquiring "mutex" at that time isn't necessary
190 * since there are no other users anyway.
191 */
192 struct mutex power_mutex;
193 struct smiapp_subdev ssds[SMIAPP_SUBDEVS];
194 u32 ssds_used;
195 struct smiapp_subdev *src;
196 struct smiapp_subdev *binner;
197 struct smiapp_subdev *scaler;
198 struct smiapp_subdev *pixel_array;
199 struct smiapp_platform_data *platform_data;
200 struct regulator *vana;
201 struct clk *ext_clk;
202 u32 limits[SMIAPP_LIMIT_LAST];
203 u8 nbinning_subtypes;
204 struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES];
205 u32 mbus_frame_fmts;
206 const struct smiapp_csi_data_format *csi_format;
207 const struct smiapp_csi_data_format *internal_csi_format;
208 u32 default_mbus_frame_fmts;
209 int default_pixel_order;
210
211 u8 binning_horizontal;
212 u8 binning_vertical;
213
214 u8 scale_m;
215 u8 scaling_mode;
216
217 u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
218 u8 flash_capability;
219 u8 frame_skip;
220
221 int power_count;
222
223 bool streaming;
224 bool dev_init_done;
225
226 u8 *nvm; /* nvm memory buffer */
227 unsigned int nvm_size; /* bytes */
228
229 struct smiapp_module_info minfo;
230
231 struct smiapp_pll pll;
232
233 /* Pixel array controls */
234 struct v4l2_ctrl *analog_gain;
235 struct v4l2_ctrl *exposure;
236 struct v4l2_ctrl *hflip;
237 struct v4l2_ctrl *vflip;
238 struct v4l2_ctrl *vblank;
239 struct v4l2_ctrl *hblank;
240 struct v4l2_ctrl *pixel_rate_parray;
241 /* src controls */
242 struct v4l2_ctrl *link_freq;
243 struct v4l2_ctrl *pixel_rate_csi;
244};
245
246#define to_smiapp_subdev(_sd) \
247 container_of(_sd, struct smiapp_subdev, sd)
248
249#define to_smiapp_sensor(_sd) \
250 (to_smiapp_subdev(_sd)->sensor)
251
252#endif /* __SMIAPP_PRIV_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index c2882fa5be85..19ea780b16ff 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -995,10 +995,8 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam)
995 995
996static int sn9c102_stream_interrupt(struct sn9c102_device* cam) 996static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
997{ 997{
998 long timeout;
999
1000 cam->stream = STREAM_INTERRUPT; 998 cam->stream = STREAM_INTERRUPT;
1001 timeout = wait_event_timeout(cam->wait_stream, 999 wait_event_timeout(cam->wait_stream,
1002 (cam->stream == STREAM_OFF) || 1000 (cam->stream == STREAM_OFF) ||
1003 (cam->state & DEV_DISCONNECTED), 1001 (cam->state & DEV_DISCONNECTED),
1004 SN9C102_URB_TIMEOUT); 1002 SN9C102_URB_TIMEOUT);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index aedb970d13f6..0421bf9453b4 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -164,35 +164,38 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd,
164 struct v4l2_format *f) 164 struct v4l2_format *f)
165{ 165{
166 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 166 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
167 const struct soc_camera_format_xlate *xlate;
167 struct v4l2_pix_format *pix = &f->fmt.pix; 168 struct v4l2_pix_format *pix = &f->fmt.pix;
168 int ret; 169 int ret;
169 170
170 dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", 171 dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n",
171 pixfmtstr(pix->pixelformat), pix->width, pix->height); 172 pixfmtstr(pix->pixelformat), pix->width, pix->height);
172 173
173 pix->bytesperline = 0; 174 if (!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) {
174 pix->sizeimage = 0; 175 pix->bytesperline = 0;
176 pix->sizeimage = 0;
177 }
175 178
176 ret = ici->ops->try_fmt(icd, f); 179 ret = ici->ops->try_fmt(icd, f);
177 if (ret < 0) 180 if (ret < 0)
178 return ret; 181 return ret;
179 182
180 if (!pix->sizeimage) { 183 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
181 if (!pix->bytesperline) { 184 if (!xlate)
182 const struct soc_camera_format_xlate *xlate; 185 return -EINVAL;
186
187 ret = soc_mbus_bytes_per_line(pix->width, xlate->host_fmt);
188 if (ret < 0)
189 return ret;
190
191 pix->bytesperline = max_t(u32, pix->bytesperline, ret);
183 192
184 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 193 ret = soc_mbus_image_size(xlate->host_fmt, pix->bytesperline,
185 if (!xlate) 194 pix->height);
186 return -EINVAL; 195 if (ret < 0)
196 return ret;
187 197
188 ret = soc_mbus_bytes_per_line(pix->width, 198 pix->sizeimage = max_t(u32, pix->sizeimage, ret);
189 xlate->host_fmt);
190 if (ret > 0)
191 pix->bytesperline = ret;
192 }
193 if (pix->bytesperline)
194 pix->sizeimage = pix->bytesperline * pix->height;
195 }
196 199
197 return 0; 200 return 0;
198} 201}
@@ -257,13 +260,13 @@ static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
257 return v4l2_subdev_call(sd, core, g_std, a); 260 return v4l2_subdev_call(sd, core, g_std, a);
258} 261}
259 262
260static int soc_camera_enum_fsizes(struct file *file, void *fh, 263static int soc_camera_enum_framesizes(struct file *file, void *fh,
261 struct v4l2_frmsizeenum *fsize) 264 struct v4l2_frmsizeenum *fsize)
262{ 265{
263 struct soc_camera_device *icd = file->private_data; 266 struct soc_camera_device *icd = file->private_data;
264 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 267 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
265 268
266 return ici->ops->enum_fsizes(icd, fsize); 269 return ici->ops->enum_framesizes(icd, fsize);
267} 270}
268 271
269static int soc_camera_reqbufs(struct file *file, void *priv, 272static int soc_camera_reqbufs(struct file *file, void *priv,
@@ -1244,8 +1247,8 @@ static int default_s_parm(struct soc_camera_device *icd,
1244 return v4l2_subdev_call(sd, video, s_parm, parm); 1247 return v4l2_subdev_call(sd, video, s_parm, parm);
1245} 1248}
1246 1249
1247static int default_enum_fsizes(struct soc_camera_device *icd, 1250static int default_enum_framesizes(struct soc_camera_device *icd,
1248 struct v4l2_frmsizeenum *fsize) 1251 struct v4l2_frmsizeenum *fsize)
1249{ 1252{
1250 int ret; 1253 int ret;
1251 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1254 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -1259,7 +1262,7 @@ static int default_enum_fsizes(struct soc_camera_device *icd,
1259 /* map xlate-code to pixel_format, sensor only handle xlate-code*/ 1262 /* map xlate-code to pixel_format, sensor only handle xlate-code*/
1260 fsize_mbus.pixel_format = xlate->code; 1263 fsize_mbus.pixel_format = xlate->code;
1261 1264
1262 ret = v4l2_subdev_call(sd, video, enum_mbus_fsizes, &fsize_mbus); 1265 ret = v4l2_subdev_call(sd, video, enum_framesizes, &fsize_mbus);
1263 if (ret < 0) 1266 if (ret < 0)
1264 return ret; 1267 return ret;
1265 1268
@@ -1298,8 +1301,8 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1298 ici->ops->set_parm = default_s_parm; 1301 ici->ops->set_parm = default_s_parm;
1299 if (!ici->ops->get_parm) 1302 if (!ici->ops->get_parm)
1300 ici->ops->get_parm = default_g_parm; 1303 ici->ops->get_parm = default_g_parm;
1301 if (!ici->ops->enum_fsizes) 1304 if (!ici->ops->enum_framesizes)
1302 ici->ops->enum_fsizes = default_enum_fsizes; 1305 ici->ops->enum_framesizes = default_enum_framesizes;
1303 1306
1304 mutex_lock(&list_lock); 1307 mutex_lock(&list_lock);
1305 list_for_each_entry(ix, &hosts, list) { 1308 list_for_each_entry(ix, &hosts, list) {
@@ -1390,7 +1393,7 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1390 .vidioc_s_input = soc_camera_s_input, 1393 .vidioc_s_input = soc_camera_s_input,
1391 .vidioc_s_std = soc_camera_s_std, 1394 .vidioc_s_std = soc_camera_s_std,
1392 .vidioc_g_std = soc_camera_g_std, 1395 .vidioc_g_std = soc_camera_g_std,
1393 .vidioc_enum_framesizes = soc_camera_enum_fsizes, 1396 .vidioc_enum_framesizes = soc_camera_enum_framesizes,
1394 .vidioc_reqbufs = soc_camera_reqbufs, 1397 .vidioc_reqbufs = soc_camera_reqbufs,
1395 .vidioc_querybuf = soc_camera_querybuf, 1398 .vidioc_querybuf = soc_camera_querybuf,
1396 .vidioc_qbuf = soc_camera_qbuf, 1399 .vidioc_qbuf = soc_camera_qbuf,
@@ -1429,6 +1432,10 @@ static int video_dev_create(struct soc_camera_device *icd)
1429 vdev->tvnorms = V4L2_STD_UNKNOWN; 1432 vdev->tvnorms = V4L2_STD_UNKNOWN;
1430 vdev->ctrl_handler = &icd->ctrl_handler; 1433 vdev->ctrl_handler = &icd->ctrl_handler;
1431 vdev->lock = &icd->video_lock; 1434 vdev->lock = &icd->video_lock;
1435 /* Locking in file operations other than ioctl should be done
1436 by the driver, not the V4L2 core.
1437 This driver needs auditing so that this flag can be removed. */
1438 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
1432 1439
1433 icd->vdev = vdev; 1440 icd->vdev = vdev;
1434 1441
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index cf7f2194ded4..89dce097a827 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -24,6 +24,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
24 .bits_per_sample = 8, 24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI, 25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE, 26 .order = SOC_MBUS_ORDER_LE,
27 .layout = SOC_MBUS_LAYOUT_PACKED,
27 }, 28 },
28}, { 29}, {
29 .code = V4L2_MBUS_FMT_YVYU8_2X8, 30 .code = V4L2_MBUS_FMT_YVYU8_2X8,
@@ -33,6 +34,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
33 .bits_per_sample = 8, 34 .bits_per_sample = 8,
34 .packing = SOC_MBUS_PACKING_2X8_PADHI, 35 .packing = SOC_MBUS_PACKING_2X8_PADHI,
35 .order = SOC_MBUS_ORDER_LE, 36 .order = SOC_MBUS_ORDER_LE,
37 .layout = SOC_MBUS_LAYOUT_PACKED,
36 }, 38 },
37}, { 39}, {
38 .code = V4L2_MBUS_FMT_UYVY8_2X8, 40 .code = V4L2_MBUS_FMT_UYVY8_2X8,
@@ -42,6 +44,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
42 .bits_per_sample = 8, 44 .bits_per_sample = 8,
43 .packing = SOC_MBUS_PACKING_2X8_PADHI, 45 .packing = SOC_MBUS_PACKING_2X8_PADHI,
44 .order = SOC_MBUS_ORDER_LE, 46 .order = SOC_MBUS_ORDER_LE,
47 .layout = SOC_MBUS_LAYOUT_PACKED,
45 }, 48 },
46}, { 49}, {
47 .code = V4L2_MBUS_FMT_VYUY8_2X8, 50 .code = V4L2_MBUS_FMT_VYUY8_2X8,
@@ -51,6 +54,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
51 .bits_per_sample = 8, 54 .bits_per_sample = 8,
52 .packing = SOC_MBUS_PACKING_2X8_PADHI, 55 .packing = SOC_MBUS_PACKING_2X8_PADHI,
53 .order = SOC_MBUS_ORDER_LE, 56 .order = SOC_MBUS_ORDER_LE,
57 .layout = SOC_MBUS_LAYOUT_PACKED,
54 }, 58 },
55}, { 59}, {
56 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 60 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
@@ -60,6 +64,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
60 .bits_per_sample = 8, 64 .bits_per_sample = 8,
61 .packing = SOC_MBUS_PACKING_2X8_PADHI, 65 .packing = SOC_MBUS_PACKING_2X8_PADHI,
62 .order = SOC_MBUS_ORDER_LE, 66 .order = SOC_MBUS_ORDER_LE,
67 .layout = SOC_MBUS_LAYOUT_PACKED,
63 }, 68 },
64}, { 69}, {
65 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, 70 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
@@ -69,6 +74,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
69 .bits_per_sample = 8, 74 .bits_per_sample = 8,
70 .packing = SOC_MBUS_PACKING_2X8_PADHI, 75 .packing = SOC_MBUS_PACKING_2X8_PADHI,
71 .order = SOC_MBUS_ORDER_LE, 76 .order = SOC_MBUS_ORDER_LE,
77 .layout = SOC_MBUS_LAYOUT_PACKED,
72 }, 78 },
73}, { 79}, {
74 .code = V4L2_MBUS_FMT_RGB565_2X8_LE, 80 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
@@ -78,6 +84,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
78 .bits_per_sample = 8, 84 .bits_per_sample = 8,
79 .packing = SOC_MBUS_PACKING_2X8_PADHI, 85 .packing = SOC_MBUS_PACKING_2X8_PADHI,
80 .order = SOC_MBUS_ORDER_LE, 86 .order = SOC_MBUS_ORDER_LE,
87 .layout = SOC_MBUS_LAYOUT_PACKED,
81 }, 88 },
82}, { 89}, {
83 .code = V4L2_MBUS_FMT_RGB565_2X8_BE, 90 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
@@ -87,6 +94,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
87 .bits_per_sample = 8, 94 .bits_per_sample = 8,
88 .packing = SOC_MBUS_PACKING_2X8_PADHI, 95 .packing = SOC_MBUS_PACKING_2X8_PADHI,
89 .order = SOC_MBUS_ORDER_LE, 96 .order = SOC_MBUS_ORDER_LE,
97 .layout = SOC_MBUS_LAYOUT_PACKED,
90 }, 98 },
91}, { 99}, {
92 .code = V4L2_MBUS_FMT_SBGGR8_1X8, 100 .code = V4L2_MBUS_FMT_SBGGR8_1X8,
@@ -96,6 +104,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
96 .bits_per_sample = 8, 104 .bits_per_sample = 8,
97 .packing = SOC_MBUS_PACKING_NONE, 105 .packing = SOC_MBUS_PACKING_NONE,
98 .order = SOC_MBUS_ORDER_LE, 106 .order = SOC_MBUS_ORDER_LE,
107 .layout = SOC_MBUS_LAYOUT_PACKED,
99 }, 108 },
100}, { 109}, {
101 .code = V4L2_MBUS_FMT_SBGGR10_1X10, 110 .code = V4L2_MBUS_FMT_SBGGR10_1X10,
@@ -105,6 +114,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
105 .bits_per_sample = 10, 114 .bits_per_sample = 10,
106 .packing = SOC_MBUS_PACKING_EXTEND16, 115 .packing = SOC_MBUS_PACKING_EXTEND16,
107 .order = SOC_MBUS_ORDER_LE, 116 .order = SOC_MBUS_ORDER_LE,
117 .layout = SOC_MBUS_LAYOUT_PACKED,
108 }, 118 },
109}, { 119}, {
110 .code = V4L2_MBUS_FMT_Y8_1X8, 120 .code = V4L2_MBUS_FMT_Y8_1X8,
@@ -114,6 +124,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
114 .bits_per_sample = 8, 124 .bits_per_sample = 8,
115 .packing = SOC_MBUS_PACKING_NONE, 125 .packing = SOC_MBUS_PACKING_NONE,
116 .order = SOC_MBUS_ORDER_LE, 126 .order = SOC_MBUS_ORDER_LE,
127 .layout = SOC_MBUS_LAYOUT_PACKED,
117 }, 128 },
118}, { 129}, {
119 .code = V4L2_MBUS_FMT_Y10_1X10, 130 .code = V4L2_MBUS_FMT_Y10_1X10,
@@ -123,6 +134,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
123 .bits_per_sample = 10, 134 .bits_per_sample = 10,
124 .packing = SOC_MBUS_PACKING_EXTEND16, 135 .packing = SOC_MBUS_PACKING_EXTEND16,
125 .order = SOC_MBUS_ORDER_LE, 136 .order = SOC_MBUS_ORDER_LE,
137 .layout = SOC_MBUS_LAYOUT_PACKED,
126 }, 138 },
127}, { 139}, {
128 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, 140 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
@@ -132,6 +144,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
132 .bits_per_sample = 8, 144 .bits_per_sample = 8,
133 .packing = SOC_MBUS_PACKING_2X8_PADHI, 145 .packing = SOC_MBUS_PACKING_2X8_PADHI,
134 .order = SOC_MBUS_ORDER_LE, 146 .order = SOC_MBUS_ORDER_LE,
147 .layout = SOC_MBUS_LAYOUT_PACKED,
135 }, 148 },
136}, { 149}, {
137 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, 150 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
@@ -141,6 +154,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
141 .bits_per_sample = 8, 154 .bits_per_sample = 8,
142 .packing = SOC_MBUS_PACKING_2X8_PADLO, 155 .packing = SOC_MBUS_PACKING_2X8_PADLO,
143 .order = SOC_MBUS_ORDER_LE, 156 .order = SOC_MBUS_ORDER_LE,
157 .layout = SOC_MBUS_LAYOUT_PACKED,
144 }, 158 },
145}, { 159}, {
146 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, 160 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
@@ -150,6 +164,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
150 .bits_per_sample = 8, 164 .bits_per_sample = 8,
151 .packing = SOC_MBUS_PACKING_2X8_PADHI, 165 .packing = SOC_MBUS_PACKING_2X8_PADHI,
152 .order = SOC_MBUS_ORDER_BE, 166 .order = SOC_MBUS_ORDER_BE,
167 .layout = SOC_MBUS_LAYOUT_PACKED,
153 }, 168 },
154}, { 169}, {
155 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, 170 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
@@ -159,6 +174,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
159 .bits_per_sample = 8, 174 .bits_per_sample = 8,
160 .packing = SOC_MBUS_PACKING_2X8_PADLO, 175 .packing = SOC_MBUS_PACKING_2X8_PADLO,
161 .order = SOC_MBUS_ORDER_BE, 176 .order = SOC_MBUS_ORDER_BE,
177 .layout = SOC_MBUS_LAYOUT_PACKED,
162 }, 178 },
163}, { 179}, {
164 .code = V4L2_MBUS_FMT_JPEG_1X8, 180 .code = V4L2_MBUS_FMT_JPEG_1X8,
@@ -168,6 +184,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
168 .bits_per_sample = 8, 184 .bits_per_sample = 8,
169 .packing = SOC_MBUS_PACKING_VARIABLE, 185 .packing = SOC_MBUS_PACKING_VARIABLE,
170 .order = SOC_MBUS_ORDER_LE, 186 .order = SOC_MBUS_ORDER_LE,
187 .layout = SOC_MBUS_LAYOUT_PACKED,
171 }, 188 },
172}, { 189}, {
173 .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, 190 .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
@@ -177,6 +194,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
177 .bits_per_sample = 8, 194 .bits_per_sample = 8,
178 .packing = SOC_MBUS_PACKING_2X8_PADHI, 195 .packing = SOC_MBUS_PACKING_2X8_PADHI,
179 .order = SOC_MBUS_ORDER_BE, 196 .order = SOC_MBUS_ORDER_BE,
197 .layout = SOC_MBUS_LAYOUT_PACKED,
180 }, 198 },
181}, { 199}, {
182 .code = V4L2_MBUS_FMT_YUYV8_1_5X8, 200 .code = V4L2_MBUS_FMT_YUYV8_1_5X8,
@@ -186,6 +204,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
186 .bits_per_sample = 8, 204 .bits_per_sample = 8,
187 .packing = SOC_MBUS_PACKING_1_5X8, 205 .packing = SOC_MBUS_PACKING_1_5X8,
188 .order = SOC_MBUS_ORDER_LE, 206 .order = SOC_MBUS_ORDER_LE,
207 .layout = SOC_MBUS_LAYOUT_PACKED,
189 }, 208 },
190}, { 209}, {
191 .code = V4L2_MBUS_FMT_YVYU8_1_5X8, 210 .code = V4L2_MBUS_FMT_YVYU8_1_5X8,
@@ -195,6 +214,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
195 .bits_per_sample = 8, 214 .bits_per_sample = 8,
196 .packing = SOC_MBUS_PACKING_1_5X8, 215 .packing = SOC_MBUS_PACKING_1_5X8,
197 .order = SOC_MBUS_ORDER_LE, 216 .order = SOC_MBUS_ORDER_LE,
217 .layout = SOC_MBUS_LAYOUT_PACKED,
198 }, 218 },
199}, { 219}, {
200 .code = V4L2_MBUS_FMT_UYVY8_1X16, 220 .code = V4L2_MBUS_FMT_UYVY8_1X16,
@@ -204,6 +224,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
204 .bits_per_sample = 16, 224 .bits_per_sample = 16,
205 .packing = SOC_MBUS_PACKING_EXTEND16, 225 .packing = SOC_MBUS_PACKING_EXTEND16,
206 .order = SOC_MBUS_ORDER_LE, 226 .order = SOC_MBUS_ORDER_LE,
227 .layout = SOC_MBUS_LAYOUT_PACKED,
207 }, 228 },
208}, { 229}, {
209 .code = V4L2_MBUS_FMT_VYUY8_1X16, 230 .code = V4L2_MBUS_FMT_VYUY8_1X16,
@@ -213,6 +234,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
213 .bits_per_sample = 16, 234 .bits_per_sample = 16,
214 .packing = SOC_MBUS_PACKING_EXTEND16, 235 .packing = SOC_MBUS_PACKING_EXTEND16,
215 .order = SOC_MBUS_ORDER_LE, 236 .order = SOC_MBUS_ORDER_LE,
237 .layout = SOC_MBUS_LAYOUT_PACKED,
216 }, 238 },
217}, { 239}, {
218 .code = V4L2_MBUS_FMT_YUYV8_1X16, 240 .code = V4L2_MBUS_FMT_YUYV8_1X16,
@@ -222,6 +244,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
222 .bits_per_sample = 16, 244 .bits_per_sample = 16,
223 .packing = SOC_MBUS_PACKING_EXTEND16, 245 .packing = SOC_MBUS_PACKING_EXTEND16,
224 .order = SOC_MBUS_ORDER_LE, 246 .order = SOC_MBUS_ORDER_LE,
247 .layout = SOC_MBUS_LAYOUT_PACKED,
225 }, 248 },
226}, { 249}, {
227 .code = V4L2_MBUS_FMT_YVYU8_1X16, 250 .code = V4L2_MBUS_FMT_YVYU8_1X16,
@@ -231,6 +254,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
231 .bits_per_sample = 16, 254 .bits_per_sample = 16,
232 .packing = SOC_MBUS_PACKING_EXTEND16, 255 .packing = SOC_MBUS_PACKING_EXTEND16,
233 .order = SOC_MBUS_ORDER_LE, 256 .order = SOC_MBUS_ORDER_LE,
257 .layout = SOC_MBUS_LAYOUT_PACKED,
234 }, 258 },
235}, { 259}, {
236 .code = V4L2_MBUS_FMT_SGRBG8_1X8, 260 .code = V4L2_MBUS_FMT_SGRBG8_1X8,
@@ -240,6 +264,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
240 .bits_per_sample = 8, 264 .bits_per_sample = 8,
241 .packing = SOC_MBUS_PACKING_NONE, 265 .packing = SOC_MBUS_PACKING_NONE,
242 .order = SOC_MBUS_ORDER_LE, 266 .order = SOC_MBUS_ORDER_LE,
267 .layout = SOC_MBUS_LAYOUT_PACKED,
243 }, 268 },
244}, { 269}, {
245 .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 270 .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
@@ -249,6 +274,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
249 .bits_per_sample = 8, 274 .bits_per_sample = 8,
250 .packing = SOC_MBUS_PACKING_NONE, 275 .packing = SOC_MBUS_PACKING_NONE,
251 .order = SOC_MBUS_ORDER_LE, 276 .order = SOC_MBUS_ORDER_LE,
277 .layout = SOC_MBUS_LAYOUT_PACKED,
252 }, 278 },
253}, { 279}, {
254 .code = V4L2_MBUS_FMT_SGBRG10_1X10, 280 .code = V4L2_MBUS_FMT_SGBRG10_1X10,
@@ -258,6 +284,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
258 .bits_per_sample = 10, 284 .bits_per_sample = 10,
259 .packing = SOC_MBUS_PACKING_EXTEND16, 285 .packing = SOC_MBUS_PACKING_EXTEND16,
260 .order = SOC_MBUS_ORDER_LE, 286 .order = SOC_MBUS_ORDER_LE,
287 .layout = SOC_MBUS_LAYOUT_PACKED,
261 }, 288 },
262}, { 289}, {
263 .code = V4L2_MBUS_FMT_SGRBG10_1X10, 290 .code = V4L2_MBUS_FMT_SGRBG10_1X10,
@@ -267,6 +294,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
267 .bits_per_sample = 10, 294 .bits_per_sample = 10,
268 .packing = SOC_MBUS_PACKING_EXTEND16, 295 .packing = SOC_MBUS_PACKING_EXTEND16,
269 .order = SOC_MBUS_ORDER_LE, 296 .order = SOC_MBUS_ORDER_LE,
297 .layout = SOC_MBUS_LAYOUT_PACKED,
270 }, 298 },
271}, { 299}, {
272 .code = V4L2_MBUS_FMT_SRGGB10_1X10, 300 .code = V4L2_MBUS_FMT_SRGGB10_1X10,
@@ -276,6 +304,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
276 .bits_per_sample = 10, 304 .bits_per_sample = 10,
277 .packing = SOC_MBUS_PACKING_EXTEND16, 305 .packing = SOC_MBUS_PACKING_EXTEND16,
278 .order = SOC_MBUS_ORDER_LE, 306 .order = SOC_MBUS_ORDER_LE,
307 .layout = SOC_MBUS_LAYOUT_PACKED,
279 }, 308 },
280}, { 309}, {
281 .code = V4L2_MBUS_FMT_SBGGR12_1X12, 310 .code = V4L2_MBUS_FMT_SBGGR12_1X12,
@@ -285,6 +314,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
285 .bits_per_sample = 12, 314 .bits_per_sample = 12,
286 .packing = SOC_MBUS_PACKING_EXTEND16, 315 .packing = SOC_MBUS_PACKING_EXTEND16,
287 .order = SOC_MBUS_ORDER_LE, 316 .order = SOC_MBUS_ORDER_LE,
317 .layout = SOC_MBUS_LAYOUT_PACKED,
288 }, 318 },
289}, { 319}, {
290 .code = V4L2_MBUS_FMT_SGBRG12_1X12, 320 .code = V4L2_MBUS_FMT_SGBRG12_1X12,
@@ -294,6 +324,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
294 .bits_per_sample = 12, 324 .bits_per_sample = 12,
295 .packing = SOC_MBUS_PACKING_EXTEND16, 325 .packing = SOC_MBUS_PACKING_EXTEND16,
296 .order = SOC_MBUS_ORDER_LE, 326 .order = SOC_MBUS_ORDER_LE,
327 .layout = SOC_MBUS_LAYOUT_PACKED,
297 }, 328 },
298}, { 329}, {
299 .code = V4L2_MBUS_FMT_SGRBG12_1X12, 330 .code = V4L2_MBUS_FMT_SGRBG12_1X12,
@@ -303,6 +334,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
303 .bits_per_sample = 12, 334 .bits_per_sample = 12,
304 .packing = SOC_MBUS_PACKING_EXTEND16, 335 .packing = SOC_MBUS_PACKING_EXTEND16,
305 .order = SOC_MBUS_ORDER_LE, 336 .order = SOC_MBUS_ORDER_LE,
337 .layout = SOC_MBUS_LAYOUT_PACKED,
306 }, 338 },
307}, { 339}, {
308 .code = V4L2_MBUS_FMT_SRGGB12_1X12, 340 .code = V4L2_MBUS_FMT_SRGGB12_1X12,
@@ -312,6 +344,7 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
312 .bits_per_sample = 12, 344 .bits_per_sample = 12,
313 .packing = SOC_MBUS_PACKING_EXTEND16, 345 .packing = SOC_MBUS_PACKING_EXTEND16,
314 .order = SOC_MBUS_ORDER_LE, 346 .order = SOC_MBUS_ORDER_LE,
347 .layout = SOC_MBUS_LAYOUT_PACKED,
315 }, 348 },
316}, 349},
317}; 350};
@@ -345,6 +378,9 @@ EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
345 378
346s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) 379s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
347{ 380{
381 if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
382 return width * mf->bits_per_sample / 8;
383
348 switch (mf->packing) { 384 switch (mf->packing) {
349 case SOC_MBUS_PACKING_NONE: 385 case SOC_MBUS_PACKING_NONE:
350 return width * mf->bits_per_sample / 8; 386 return width * mf->bits_per_sample / 8;
@@ -361,6 +397,24 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
361} 397}
362EXPORT_SYMBOL(soc_mbus_bytes_per_line); 398EXPORT_SYMBOL(soc_mbus_bytes_per_line);
363 399
400s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
401 u32 bytes_per_line, u32 height)
402{
403 if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
404 return bytes_per_line * height;
405
406 switch (mf->packing) {
407 case SOC_MBUS_PACKING_2X8_PADHI:
408 case SOC_MBUS_PACKING_2X8_PADLO:
409 return bytes_per_line * height * 2;
410 case SOC_MBUS_PACKING_1_5X8:
411 return bytes_per_line * height * 3 / 2;
412 default:
413 return -EINVAL;
414 }
415}
416EXPORT_SYMBOL(soc_mbus_image_size);
417
364const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc( 418const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
365 enum v4l2_mbus_pixelcode code, 419 enum v4l2_mbus_pixelcode code,
366 const struct soc_mbus_lookup *lookup, 420 const struct soc_mbus_lookup *lookup,
diff --git a/drivers/media/video/sta2x11_vip.c b/drivers/media/video/sta2x11_vip.c
new file mode 100644
index 000000000000..4c10205264d4
--- /dev/null
+++ b/drivers/media/video/sta2x11_vip.c
@@ -0,0 +1,1550 @@
1/*
2 * This is the driver for the STA2x11 Video Input Port.
3 *
4 * Copyright (C) 2010 WindRiver Systems, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * The full GNU General Public License is included in this distribution in
20 * the file called "COPYING".
21 *
22 * Author: Andreas Kies <andreas.kies@windriver.com>
23 * Vlad Lungu <vlad.lungu@windriver.com>
24 *
25 */
26
27#include <linux/types.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/vmalloc.h>
32
33#include <linux/videodev2.h>
34
35#include <linux/kmod.h>
36
37#include <linux/pci.h>
38#include <linux/interrupt.h>
39#include <linux/mutex.h>
40#include <linux/io.h>
41#include <linux/gpio.h>
42#include <linux/i2c.h>
43#include <linux/delay.h>
44#include <media/v4l2-common.h>
45#include <media/v4l2-device.h>
46#include <media/v4l2-ioctl.h>
47#include <media/videobuf-dma-contig.h>
48
49#include "sta2x11_vip.h"
50
51#define DRV_NAME "sta2x11_vip"
52#define DRV_VERSION "1.3"
53
54#ifndef PCI_DEVICE_ID_STMICRO_VIP
55#define PCI_DEVICE_ID_STMICRO_VIP 0xCC0D
56#endif
57
58#define MAX_FRAMES 4
59
60/*Register offsets*/
61#define DVP_CTL 0x00
62#define DVP_TFO 0x04
63#define DVP_TFS 0x08
64#define DVP_BFO 0x0C
65#define DVP_BFS 0x10
66#define DVP_VTP 0x14
67#define DVP_VBP 0x18
68#define DVP_VMP 0x1C
69#define DVP_ITM 0x98
70#define DVP_ITS 0x9C
71#define DVP_STA 0xA0
72#define DVP_HLFLN 0xA8
73#define DVP_RGB 0xC0
74#define DVP_PKZ 0xF0
75
76/*Register fields*/
77#define DVP_CTL_ENA 0x00000001
78#define DVP_CTL_RST 0x80000000
79#define DVP_CTL_DIS (~0x00040001)
80
81#define DVP_IT_VSB 0x00000008
82#define DVP_IT_VST 0x00000010
83#define DVP_IT_FIFO 0x00000020
84
85#define DVP_HLFLN_SD 0x00000001
86
87#define REG_WRITE(vip, reg, value) iowrite32((value), (vip->iomem)+(reg))
88#define REG_READ(vip, reg) ioread32((vip->iomem)+(reg))
89
90#define SAVE_COUNT 8
91#define AUX_COUNT 3
92#define IRQ_COUNT 1
93
94/**
95 * struct sta2x11_vip - All internal data for one instance of device
96 * @v4l2_dev: device registered in v4l layer
97 * @video_dev: properties of our device
98 * @pdev: PCI device
99 * @adapter: contains I2C adapter information
100 * @register_save_area: All relevant register are saved here during suspend
101 * @decoder: contains information about video DAC
102 * @format: pixel format, fixed UYVY
103 * @std: video standard (e.g. PAL/NTSC)
104 * @input: input line for video signal ( 0 or 1 )
105 * @users: Number of open of device ( max. 1 )
106 * @disabled: Device is in power down state
107 * @mutex: ensures exclusive opening of device
108 * @slock: for excluse acces of registers
109 * @vb_vidq: queue maintained by videobuf layer
110 * @capture: linked list of capture buffer
111 * @active: struct videobuf_buffer currently beingg filled
112 * @started: device is ready to capture frame
113 * @closing: device will be shut down
114 * @tcount: Number of top frames
115 * @bcount: Number of bottom frames
116 * @overflow: Number of FIFO overflows
117 * @mem_spare: small buffer of unused frame
118 * @dma_spare: dma addres of mem_spare
119 * @iomem: hardware base address
120 * @config: I2C and gpio config from platform
121 *
122 * All non-local data is accessed via this structure.
123 */
124
125struct sta2x11_vip {
126 struct v4l2_device v4l2_dev;
127 struct video_device *video_dev;
128 struct pci_dev *pdev;
129 struct i2c_adapter *adapter;
130 unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT];
131 struct v4l2_subdev *decoder;
132 struct v4l2_pix_format format;
133 v4l2_std_id std;
134 unsigned int input;
135 int users;
136 int disabled;
137 struct mutex mutex; /* exclusive access during open */
138 spinlock_t slock; /* spin lock for hardware and queue access */
139 struct videobuf_queue vb_vidq;
140 struct list_head capture;
141 struct videobuf_buffer *active;
142 int started, closing, tcount, bcount;
143 int overflow;
144 void *mem_spare;
145 dma_addr_t dma_spare;
146 void *iomem;
147 struct vip_config *config;
148};
149
150static const unsigned int registers_to_save[AUX_COUNT] = {
151 DVP_HLFLN, DVP_RGB, DVP_PKZ
152};
153
154static struct v4l2_pix_format formats_50[] = {
155 { /*PAL interlaced */
156 .width = 720,
157 .height = 576,
158 .pixelformat = V4L2_PIX_FMT_UYVY,
159 .field = V4L2_FIELD_INTERLACED,
160 .bytesperline = 720 * 2,
161 .sizeimage = 720 * 2 * 576,
162 .colorspace = V4L2_COLORSPACE_SMPTE170M},
163 { /*PAL top */
164 .width = 720,
165 .height = 288,
166 .pixelformat = V4L2_PIX_FMT_UYVY,
167 .field = V4L2_FIELD_TOP,
168 .bytesperline = 720 * 2,
169 .sizeimage = 720 * 2 * 288,
170 .colorspace = V4L2_COLORSPACE_SMPTE170M},
171 { /*PAL bottom */
172 .width = 720,
173 .height = 288,
174 .pixelformat = V4L2_PIX_FMT_UYVY,
175 .field = V4L2_FIELD_BOTTOM,
176 .bytesperline = 720 * 2,
177 .sizeimage = 720 * 2 * 288,
178 .colorspace = V4L2_COLORSPACE_SMPTE170M},
179
180};
181
182static struct v4l2_pix_format formats_60[] = {
183 { /*NTSC interlaced */
184 .width = 720,
185 .height = 480,
186 .pixelformat = V4L2_PIX_FMT_UYVY,
187 .field = V4L2_FIELD_INTERLACED,
188 .bytesperline = 720 * 2,
189 .sizeimage = 720 * 2 * 480,
190 .colorspace = V4L2_COLORSPACE_SMPTE170M},
191 { /*NTSC top */
192 .width = 720,
193 .height = 240,
194 .pixelformat = V4L2_PIX_FMT_UYVY,
195 .field = V4L2_FIELD_TOP,
196 .bytesperline = 720 * 2,
197 .sizeimage = 720 * 2 * 240,
198 .colorspace = V4L2_COLORSPACE_SMPTE170M},
199 { /*NTSC bottom */
200 .width = 720,
201 .height = 240,
202 .pixelformat = V4L2_PIX_FMT_UYVY,
203 .field = V4L2_FIELD_BOTTOM,
204 .bytesperline = 720 * 2,
205 .sizeimage = 720 * 2 * 240,
206 .colorspace = V4L2_COLORSPACE_SMPTE170M},
207};
208
209/**
210 * buf_setup - Get size and number of video buffer
211 * @vq: queue in videobuf
212 * @count: Number of buffers (1..MAX_FRAMES).
213 * 0 use default value.
214 * @size: size of buffer in bytes
215 *
216 * returns size and number of buffers
217 * a preset value of 0 returns the default number.
218 * return value: 0, always succesfull.
219 */
220static int buf_setup(struct videobuf_queue *vq, unsigned int *count,
221 unsigned int *size)
222{
223 struct sta2x11_vip *vip = vq->priv_data;
224
225 *size = vip->format.width * vip->format.height * 2;
226 if (0 == *count || MAX_FRAMES < *count)
227 *count = MAX_FRAMES;
228 return 0;
229};
230
231/**
232 * buf_prepare - prepare buffer for usage
233 * @vq: queue in videobuf layer
234 * @vb: buffer to be prepared
235 * @field: type of video data (interlaced/non-interlaced)
236 *
237 * Allocate or realloc buffer
238 * return value: 0, successful.
239 *
240 * -EINVAL, supplied buffer is too small.
241 *
242 * other, buffer could not be locked.
243 */
244static int buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
245 enum v4l2_field field)
246{
247 struct sta2x11_vip *vip = vq->priv_data;
248 int ret;
249
250 vb->size = vip->format.width * vip->format.height * 2;
251 if ((0 != vb->baddr) && (vb->bsize < vb->size))
252 return -EINVAL;
253 vb->width = vip->format.width;
254 vb->height = vip->format.height;
255 vb->field = field;
256
257 if (VIDEOBUF_NEEDS_INIT == vb->state) {
258 ret = videobuf_iolock(vq, vb, NULL);
259 if (ret)
260 goto fail;
261 }
262 vb->state = VIDEOBUF_PREPARED;
263 return 0;
264fail:
265 videobuf_dma_contig_free(vq, vb);
266 vb->state = VIDEOBUF_NEEDS_INIT;
267 return ret;
268}
269
270/**
271 * buf_queu - queue buffer for filling
272 * @vq: queue in videobuf layer
273 * @vb: buffer to be queued
274 *
275 * if capturing is already running, the buffer will be queued. Otherwise
276 * capture is started and the buffer is used directly.
277 */
278static void buf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
279{
280 struct sta2x11_vip *vip = vq->priv_data;
281 u32 dma;
282
283 vb->state = VIDEOBUF_QUEUED;
284
285 if (vip->active) {
286 list_add_tail(&vb->queue, &vip->capture);
287 return;
288 }
289
290 vip->started = 1;
291 vip->tcount = 0;
292 vip->bcount = 0;
293 vip->active = vb;
294 vb->state = VIDEOBUF_ACTIVE;
295
296 dma = videobuf_to_dma_contig(vb);
297
298 REG_WRITE(vip, DVP_TFO, (0 << 16) | (0));
299 /* despite of interlace mode, upper and lower frames start at zero */
300 REG_WRITE(vip, DVP_BFO, (0 << 16) | (0));
301
302 switch (vip->format.field) {
303 case V4L2_FIELD_INTERLACED:
304 REG_WRITE(vip, DVP_TFS,
305 ((vip->format.height / 2 - 1) << 16) |
306 (2 * vip->format.width - 1));
307 REG_WRITE(vip, DVP_BFS, ((vip->format.height / 2 - 1) << 16) |
308 (2 * vip->format.width - 1));
309 REG_WRITE(vip, DVP_VTP, dma);
310 REG_WRITE(vip, DVP_VBP, dma + vip->format.width * 2);
311 REG_WRITE(vip, DVP_VMP, 4 * vip->format.width);
312 break;
313 case V4L2_FIELD_TOP:
314 REG_WRITE(vip, DVP_TFS,
315 ((vip->format.height - 1) << 16) |
316 (2 * vip->format.width - 1));
317 REG_WRITE(vip, DVP_BFS, ((0) << 16) |
318 (2 * vip->format.width - 1));
319 REG_WRITE(vip, DVP_VTP, dma);
320 REG_WRITE(vip, DVP_VBP, dma);
321 REG_WRITE(vip, DVP_VMP, 2 * vip->format.width);
322 break;
323 case V4L2_FIELD_BOTTOM:
324 REG_WRITE(vip, DVP_TFS, ((0) << 16) |
325 (2 * vip->format.width - 1));
326 REG_WRITE(vip, DVP_BFS,
327 ((vip->format.height) << 16) |
328 (2 * vip->format.width - 1));
329 REG_WRITE(vip, DVP_VTP, dma);
330 REG_WRITE(vip, DVP_VBP, dma);
331 REG_WRITE(vip, DVP_VMP, 2 * vip->format.width);
332 break;
333
334 default:
335 pr_warning("VIP: unknown field format\n");
336 return;
337 }
338
339 REG_WRITE(vip, DVP_CTL, DVP_CTL_ENA);
340}
341
342/**
343 * buff_release - release buffer
344 * @vq: queue in videobuf layer
345 * @vb: buffer to be released
346 *
347 * release buffer in videobuf layer
348 */
349static void buf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
350{
351
352 videobuf_dma_contig_free(vq, vb);
353 vb->state = VIDEOBUF_NEEDS_INIT;
354}
355
356static struct videobuf_queue_ops vip_qops = {
357 .buf_setup = buf_setup,
358 .buf_prepare = buf_prepare,
359 .buf_queue = buf_queue,
360 .buf_release = buf_release,
361};
362
363/**
364 * vip_open - open video device
365 * @file: descriptor of device
366 *
367 * open device, make sure it is only opened once.
368 * return value: 0, no error.
369 *
370 * -EBUSY, device is already opened
371 *
372 * -ENOMEM, no memory for auxiliary DMA buffer
373 */
374static int vip_open(struct file *file)
375{
376 struct video_device *dev = video_devdata(file);
377 struct sta2x11_vip *vip = video_get_drvdata(dev);
378
379 mutex_lock(&vip->mutex);
380 vip->users++;
381
382 if (vip->users > 1) {
383 vip->users--;
384 mutex_unlock(&vip->mutex);
385 return -EBUSY;
386 }
387
388 file->private_data = dev;
389 vip->overflow = 0;
390 vip->started = 0;
391 vip->closing = 0;
392 vip->active = NULL;
393
394 INIT_LIST_HEAD(&vip->capture);
395 vip->mem_spare = dma_alloc_coherent(&vip->pdev->dev, 64,
396 &vip->dma_spare, GFP_KERNEL);
397 if (!vip->mem_spare) {
398 vip->users--;
399 mutex_unlock(&vip->mutex);
400 return -ENOMEM;
401 }
402
403 mutex_unlock(&vip->mutex);
404 videobuf_queue_dma_contig_init_cached(&vip->vb_vidq,
405 &vip_qops,
406 &vip->pdev->dev,
407 &vip->slock,
408 V4L2_BUF_TYPE_VIDEO_CAPTURE,
409 V4L2_FIELD_INTERLACED,
410 sizeof(struct videobuf_buffer),
411 vip, NULL);
412 REG_READ(vip, DVP_ITS);
413 REG_WRITE(vip, DVP_HLFLN, DVP_HLFLN_SD);
414 REG_WRITE(vip, DVP_ITM, DVP_IT_VSB | DVP_IT_VST);
415 REG_WRITE(vip, DVP_CTL, DVP_CTL_RST);
416 REG_WRITE(vip, DVP_CTL, 0);
417 REG_READ(vip, DVP_ITS);
418 return 0;
419}
420
421/**
422 * vip_close - close video device
423 * @file: descriptor of device
424 *
425 * close video device, wait until all pending operations are finished
426 * ( maximum FRAME_MAX buffers pending )
427 * Turn off interrupts.
428 *
429 * return value: 0, always succesful.
430 */
431static int vip_close(struct file *file)
432{
433 struct video_device *dev = video_devdata(file);
434 struct sta2x11_vip *vip = video_get_drvdata(dev);
435
436 vip->closing = 1;
437 if (vip->active)
438 videobuf_waiton(&vip->vb_vidq, vip->active, 0, 0);
439 spin_lock_irq(&vip->slock);
440
441 REG_WRITE(vip, DVP_ITM, 0);
442 REG_WRITE(vip, DVP_CTL, DVP_CTL_RST);
443 REG_WRITE(vip, DVP_CTL, 0);
444 REG_READ(vip, DVP_ITS);
445
446 vip->started = 0;
447 vip->active = NULL;
448
449 spin_unlock_irq(&vip->slock);
450
451 videobuf_stop(&vip->vb_vidq);
452 videobuf_mmap_free(&vip->vb_vidq);
453
454 dma_free_coherent(&vip->pdev->dev, 64, vip->mem_spare, vip->dma_spare);
455 file->private_data = NULL;
456 mutex_lock(&vip->mutex);
457 vip->users--;
458 mutex_unlock(&vip->mutex);
459 return 0;
460}
461
462/**
463 * vip_read - read from video input
464 * @file: descriptor of device
465 * @data: user buffer
466 * @count: number of bytes to be read
467 * @ppos: position within stream
468 *
469 * read video data from video device.
470 * handling is done in generic videobuf layer
471 * return value: provided by videobuf layer
472 */
473static ssize_t vip_read(struct file *file, char __user *data,
474 size_t count, loff_t *ppos)
475{
476 struct video_device *dev = file->private_data;
477 struct sta2x11_vip *vip = video_get_drvdata(dev);
478
479 return videobuf_read_stream(&vip->vb_vidq, data, count, ppos, 0,
480 file->f_flags & O_NONBLOCK);
481}
482
483/**
484 * vip_mmap - map user buffer
485 * @file: descriptor of device
486 * @vma: user buffer
487 *
488 * map user space buffer into kernel mode, including DMA address.
489 * handling is done in generic videobuf layer.
490 * return value: provided by videobuf layer
491 */
492static int vip_mmap(struct file *file, struct vm_area_struct *vma)
493{
494 struct video_device *dev = file->private_data;
495 struct sta2x11_vip *vip = video_get_drvdata(dev);
496
497 return videobuf_mmap_mapper(&vip->vb_vidq, vma);
498}
499
500/**
501 * vip_poll - poll for event
502 * @file: descriptor of device
503 * @wait: contains events to be waited for
504 *
505 * wait for event related to video device.
506 * handling is done in generic videobuf layer.
507 * return value: provided by videobuf layer
508 */
509static unsigned int vip_poll(struct file *file, struct poll_table_struct *wait)
510{
511 struct video_device *dev = file->private_data;
512 struct sta2x11_vip *vip = video_get_drvdata(dev);
513
514 return videobuf_poll_stream(file, &vip->vb_vidq, wait);
515}
516
517/**
518 * vidioc_querycap - return capabilities of device
519 * @file: descriptor of device (not used)
520 * @priv: points to current videodevice
521 * @cap: contains return values
522 *
523 * the capabilities of the device are returned
524 *
525 * return value: 0, no error.
526 */
527static int vidioc_querycap(struct file *file, void *priv,
528 struct v4l2_capability *cap)
529{
530 struct video_device *dev = priv;
531 struct sta2x11_vip *vip = video_get_drvdata(dev);
532
533 memset(cap, 0, sizeof(struct v4l2_capability));
534 strcpy(cap->driver, DRV_NAME);
535 strcpy(cap->card, DRV_NAME);
536 cap->version = 0;
537 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
538 pci_name(vip->pdev));
539 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
540 V4L2_CAP_STREAMING;
541
542 return 0;
543}
544
545/**
546 * vidioc_s_std - set video standard
547 * @file: descriptor of device (not used)
548 * @priv: points to current videodevice
549 * @std: contains standard to be set
550 *
551 * the video standard is set
552 *
553 * return value: 0, no error.
554 *
555 * -EIO, no input signal detected
556 *
557 * other, returned from video DAC.
558 */
559static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
560{
561 struct video_device *dev = priv;
562 struct sta2x11_vip *vip = video_get_drvdata(dev);
563 v4l2_std_id oldstd = vip->std, newstd;
564 int status;
565
566 if (V4L2_STD_ALL == *std) {
567 v4l2_subdev_call(vip->decoder, core, s_std, *std);
568 ssleep(2);
569 v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
570 v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
571 if (status & V4L2_IN_ST_NO_SIGNAL)
572 return -EIO;
573 *std = vip->std = newstd;
574 if (oldstd != *std) {
575 if (V4L2_STD_525_60 & (*std))
576 vip->format = formats_60[0];
577 else
578 vip->format = formats_50[0];
579 }
580 return 0;
581 }
582
583 if (oldstd != *std) {
584 if (V4L2_STD_525_60 & (*std))
585 vip->format = formats_60[0];
586 else
587 vip->format = formats_50[0];
588 }
589
590 return v4l2_subdev_call(vip->decoder, core, s_std, *std);
591}
592
593/**
594 * vidioc_g_std - get video standard
595 * @file: descriptor of device (not used)
596 * @priv: points to current videodevice
597 * @std: contains return values
598 *
599 * the current video standard is returned
600 *
601 * return value: 0, no error.
602 */
603static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
604{
605 struct video_device *dev = priv;
606 struct sta2x11_vip *vip = video_get_drvdata(dev);
607
608 *std = vip->std;
609 return 0;
610}
611
612/**
613 * vidioc_querystd - get possible video standards
614 * @file: descriptor of device (not used)
615 * @priv: points to current videodevice
616 * @std: contains return values
617 *
618 * all possible video standards are returned
619 *
620 * return value: delivered by video DAC routine.
621 */
622static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
623{
624 struct video_device *dev = priv;
625 struct sta2x11_vip *vip = video_get_drvdata(dev);
626
627 return v4l2_subdev_call(vip->decoder, video, querystd, std);
628
629}
630
631/**
632 * vidioc_queryctl - get possible control settings
633 * @file: descriptor of device (not used)
634 * @priv: points to current videodevice
635 * @ctrl: contains return values
636 *
637 * return possible values for a control
638 * return value: delivered by video DAC routine.
639 */
640static int vidioc_queryctrl(struct file *file, void *priv,
641 struct v4l2_queryctrl *ctrl)
642{
643 struct video_device *dev = priv;
644 struct sta2x11_vip *vip = video_get_drvdata(dev);
645
646 return v4l2_subdev_call(vip->decoder, core, queryctrl, ctrl);
647}
648
649/**
650 * vidioc_g_ctl - get control value
651 * @file: descriptor of device (not used)
652 * @priv: points to current videodevice
653 * @ctrl: contains return values
654 *
655 * return setting for a control value
656 * return value: delivered by video DAC routine.
657 */
658static int vidioc_g_ctrl(struct file *file, void *priv,
659 struct v4l2_control *ctrl)
660{
661 struct video_device *dev = priv;
662 struct sta2x11_vip *vip = video_get_drvdata(dev);
663
664 return v4l2_subdev_call(vip->decoder, core, g_ctrl, ctrl);
665}
666
667/**
668 * vidioc_s_ctl - set control value
669 * @file: descriptor of device (not used)
670 * @priv: points to current videodevice
671 * @ctrl: contains value to be set
672 *
673 * set value for a specific control
674 * return value: delivered by video DAC routine.
675 */
676static int vidioc_s_ctrl(struct file *file, void *priv,
677 struct v4l2_control *ctrl)
678{
679 struct video_device *dev = priv;
680 struct sta2x11_vip *vip = video_get_drvdata(dev);
681
682 return v4l2_subdev_call(vip->decoder, core, s_ctrl, ctrl);
683}
684
685/**
686 * vidioc_enum_input - return name of input line
687 * @file: descriptor of device (not used)
688 * @priv: points to current videodevice
689 * @inp: contains return values
690 *
691 * the user friendly name of the input line is returned
692 *
693 * return value: 0, no error.
694 *
695 * -EINVAL, input line number out of range
696 */
697static int vidioc_enum_input(struct file *file, void *priv,
698 struct v4l2_input *inp)
699{
700 if (inp->index > 1)
701 return -EINVAL;
702
703 inp->type = V4L2_INPUT_TYPE_CAMERA;
704 inp->std = V4L2_STD_ALL;
705 sprintf(inp->name, "Camera %u", inp->index);
706
707 return 0;
708}
709
710/**
711 * vidioc_s_input - set input line
712 * @file: descriptor of device ( not used)
713 * @priv: points to current videodevice
714 * @i: new input line number
715 *
716 * the current active input line is set
717 *
718 * return value: 0, no error.
719 *
720 * -EINVAL, line number out of range
721 */
722static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
723{
724 struct video_device *dev = priv;
725 struct sta2x11_vip *vip = video_get_drvdata(dev);
726 int ret;
727
728 if (i > 1)
729 return -EINVAL;
730 ret = v4l2_subdev_call(vip->decoder, video, s_routing, i, 0, 0);
731
732 if (!ret)
733 vip->input = i;
734
735 return 0;
736}
737
738/**
739 * vidioc_g_input - return input line
740 * @file: descriptor of device ( not used)
741 * @priv: points to current videodevice
742 * @i: returned input line number
743 *
744 * the current active input line is returned
745 *
746 * return value: always 0.
747 */
748static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
749{
750 struct video_device *dev = priv;
751 struct sta2x11_vip *vip = video_get_drvdata(dev);
752
753 *i = vip->input;
754 return 0;
755}
756
757/**
758 * vidioc_enum_fmt_vid_cap - return video capture format
759 * @file: descriptor of device ( not used)
760 * @priv: points to current videodevice
761 * @f: returned format information
762 *
763 * returns name and format of video capture
764 * Only UYVY is supported by hardware.
765 *
766 * return value: always 0.
767 */
768static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
769 struct v4l2_fmtdesc *f)
770{
771
772 if (f->index != 0)
773 return -EINVAL;
774
775 strcpy(f->description, "4:2:2, packed, UYVY");
776 f->pixelformat = V4L2_PIX_FMT_UYVY;
777 f->flags = 0;
778 return 0;
779}
780
781/**
782 * vidioc_try_fmt_vid_cap - set video capture format
783 * @file: descriptor of device ( not used)
784 * @priv: points to current videodevice
785 * @f: new format
786 *
787 * new video format is set which includes width and
788 * field type. width is fixed to 720, no scaling.
789 * Only UYVY is supported by this hardware.
790 * the minimum height is 200, the maximum is 576 (PAL)
791 *
792 * return value: 0, no error
793 *
794 * -EINVAL, pixel or field format not supported
795 *
796 */
797static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
798 struct v4l2_format *f)
799{
800 struct video_device *dev = priv;
801 struct sta2x11_vip *vip = video_get_drvdata(dev);
802 int interlace_lim;
803
804 if (V4L2_PIX_FMT_UYVY != f->fmt.pix.pixelformat)
805 return -EINVAL;
806
807 if (V4L2_STD_525_60 & vip->std)
808 interlace_lim = 240;
809 else
810 interlace_lim = 288;
811
812 switch (f->fmt.pix.field) {
813 case V4L2_FIELD_ANY:
814 if (interlace_lim < f->fmt.pix.height)
815 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
816 else
817 f->fmt.pix.field = V4L2_FIELD_BOTTOM;
818 break;
819 case V4L2_FIELD_TOP:
820 case V4L2_FIELD_BOTTOM:
821 if (interlace_lim < f->fmt.pix.height)
822 f->fmt.pix.height = interlace_lim;
823 break;
824 case V4L2_FIELD_INTERLACED:
825 break;
826 default:
827 return -EINVAL;
828 }
829
830 f->fmt.pix.height &= ~1;
831 if (2 * interlace_lim < f->fmt.pix.height)
832 f->fmt.pix.height = 2 * interlace_lim;
833 if (200 > f->fmt.pix.height)
834 f->fmt.pix.height = 200;
835 f->fmt.pix.width = 720;
836 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
837 f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height;
838 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
839 f->fmt.pix.priv = 0;
840 return 0;
841}
842
843/**
844 * vidioc_s_fmt_vid_cap - set current video format parameters
845 * @file: descriptor of device ( not used)
846 * @priv: points to current videodevice
847 * @f: returned format information
848 *
849 * set new capture format
850 * return value: 0, no error
851 *
852 * other, delivered by video DAC routine.
853 */
854static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
855 struct v4l2_format *f)
856{
857 struct video_device *dev = priv;
858 struct sta2x11_vip *vip = video_get_drvdata(dev);
859 int ret;
860
861 ret = vidioc_try_fmt_vid_cap(file, priv, f);
862 if (ret)
863 return ret;
864
865 memcpy(&vip->format, &f->fmt.pix, sizeof(struct v4l2_pix_format));
866 return 0;
867}
868
869/**
870 * vidioc_g_fmt_vid_cap - get current video format parameters
871 * @file: descriptor of device ( not used)
872 * @priv: points to current videodevice
873 * @f: contains format information
874 *
875 * returns current video format parameters
876 *
877 * return value: 0, always successful
878 */
879static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
880 struct v4l2_format *f)
881{
882 struct video_device *dev = priv;
883 struct sta2x11_vip *vip = video_get_drvdata(dev);
884
885 memcpy(&f->fmt.pix, &vip->format, sizeof(struct v4l2_pix_format));
886 return 0;
887}
888
889/**
890 * vidioc_reqfs - request buffer
891 * @file: descriptor of device ( not used)
892 * @priv: points to current videodevice
893 * @p: video buffer
894 *
895 * Handling is done in generic videobuf layer.
896 */
897static int vidioc_reqbufs(struct file *file, void *priv,
898 struct v4l2_requestbuffers *p)
899{
900 struct video_device *dev = priv;
901 struct sta2x11_vip *vip = video_get_drvdata(dev);
902
903 return videobuf_reqbufs(&vip->vb_vidq, p);
904}
905
906/**
907 * vidioc_querybuf - query buffer
908 * @file: descriptor of device ( not used)
909 * @priv: points to current videodevice
910 * @p: video buffer
911 *
912 * query buffer state.
913 * Handling is done in generic videobuf layer.
914 */
915static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
916{
917 struct video_device *dev = priv;
918 struct sta2x11_vip *vip = video_get_drvdata(dev);
919
920 return videobuf_querybuf(&vip->vb_vidq, p);
921}
922
923/**
924 * vidioc_qbuf - queue a buffer
925 * @file: descriptor of device ( not used)
926 * @priv: points to current videodevice
927 * @p: video buffer
928 *
929 * Handling is done in generic videobuf layer.
930 */
931static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
932{
933 struct video_device *dev = priv;
934 struct sta2x11_vip *vip = video_get_drvdata(dev);
935
936 return videobuf_qbuf(&vip->vb_vidq, p);
937}
938
939/**
940 * vidioc_dqbuf - dequeue a buffer
941 * @file: descriptor of device ( not used)
942 * @priv: points to current videodevice
943 * @p: video buffer
944 *
945 * Handling is done in generic videobuf layer.
946 */
947static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
948{
949 struct video_device *dev = priv;
950 struct sta2x11_vip *vip = video_get_drvdata(dev);
951
952 return videobuf_dqbuf(&vip->vb_vidq, p, file->f_flags & O_NONBLOCK);
953}
954
955/**
956 * vidioc_streamon - turn on streaming
957 * @file: descriptor of device ( not used)
958 * @priv: points to current videodevice
959 * @type: type of capture
960 *
961 * turn on streaming.
962 * Handling is done in generic videobuf layer.
963 */
964static int vidioc_streamon(struct file *file, void *priv,
965 enum v4l2_buf_type type)
966{
967 struct video_device *dev = priv;
968 struct sta2x11_vip *vip = video_get_drvdata(dev);
969
970 return videobuf_streamon(&vip->vb_vidq);
971}
972
973/**
974 * vidioc_streamoff - turn off streaming
975 * @file: descriptor of device ( not used)
976 * @priv: points to current videodevice
977 * @type: type of capture
978 *
979 * turn off streaming.
980 * Handling is done in generic videobuf layer.
981 */
982static int vidioc_streamoff(struct file *file, void *priv,
983 enum v4l2_buf_type type)
984{
985 struct video_device *dev = priv;
986 struct sta2x11_vip *vip = video_get_drvdata(dev);
987
988 return videobuf_streamoff(&vip->vb_vidq);
989}
990
991static const struct v4l2_file_operations vip_fops = {
992 .owner = THIS_MODULE,
993 .open = vip_open,
994 .release = vip_close,
995 .ioctl = video_ioctl2,
996 .read = vip_read,
997 .mmap = vip_mmap,
998 .poll = vip_poll
999};
1000
1001static const struct v4l2_ioctl_ops vip_ioctl_ops = {
1002 .vidioc_querycap = vidioc_querycap,
1003 .vidioc_s_std = vidioc_s_std,
1004 .vidioc_g_std = vidioc_g_std,
1005 .vidioc_querystd = vidioc_querystd,
1006 .vidioc_queryctrl = vidioc_queryctrl,
1007 .vidioc_g_ctrl = vidioc_g_ctrl,
1008 .vidioc_s_ctrl = vidioc_s_ctrl,
1009 .vidioc_enum_input = vidioc_enum_input,
1010 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1011 .vidioc_s_input = vidioc_s_input,
1012 .vidioc_g_input = vidioc_g_input,
1013 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1014 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1015 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1016 .vidioc_reqbufs = vidioc_reqbufs,
1017 .vidioc_querybuf = vidioc_querybuf,
1018 .vidioc_qbuf = vidioc_qbuf,
1019 .vidioc_dqbuf = vidioc_dqbuf,
1020 .vidioc_streamon = vidioc_streamon,
1021 .vidioc_streamoff = vidioc_streamoff,
1022};
1023
1024static struct video_device video_dev_template = {
1025 .name = DRV_NAME,
1026 .release = video_device_release,
1027 .fops = &vip_fops,
1028 .ioctl_ops = &vip_ioctl_ops,
1029 .tvnorms = V4L2_STD_ALL,
1030};
1031
1032/**
1033 * vip_irq - interrupt routine
1034 * @irq: Number of interrupt ( not used, correct number is assumed )
1035 * @vip: local data structure containing all information
1036 *
1037 * check for both frame interrupts set ( top and bottom ).
1038 * check FIFO overflow, but limit number of log messages after open.
1039 * signal a complete buffer if done.
1040 * dequeue a new buffer if available.
1041 * disable VIP if no buffer available.
1042 *
1043 * return value: IRQ_NONE, interrupt was not generated by VIP
1044 *
1045 * IRQ_HANDLED, interrupt done.
1046 */
1047static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
1048{
1049 u32 status, dma;
1050 unsigned long flags;
1051 struct videobuf_buffer *vb;
1052
1053 status = REG_READ(vip, DVP_ITS);
1054
1055 if (!status) {
1056 pr_debug("VIP: irq ignored\n");
1057 return IRQ_NONE;
1058 }
1059
1060 if (!vip->started)
1061 return IRQ_HANDLED;
1062
1063 if (status & DVP_IT_VSB)
1064 vip->bcount++;
1065
1066 if (status & DVP_IT_VST)
1067 vip->tcount++;
1068
1069 if ((DVP_IT_VSB | DVP_IT_VST) == (status & (DVP_IT_VST | DVP_IT_VSB))) {
1070 /* this is bad, we are too slow, hope the condition is gone
1071 * on the next frame */
1072 pr_info("VIP: both irqs\n");
1073 return IRQ_HANDLED;
1074 }
1075
1076 if (status & DVP_IT_FIFO) {
1077 if (5 > vip->overflow++)
1078 pr_info("VIP: fifo overflow\n");
1079 }
1080
1081 if (2 > vip->tcount)
1082 return IRQ_HANDLED;
1083
1084 if (status & DVP_IT_VSB)
1085 return IRQ_HANDLED;
1086
1087 spin_lock_irqsave(&vip->slock, flags);
1088
1089 REG_WRITE(vip, DVP_CTL, REG_READ(vip, DVP_CTL) & ~DVP_CTL_ENA);
1090 if (vip->active) {
1091 do_gettimeofday(&vip->active->ts);
1092 vip->active->field_count++;
1093 vip->active->state = VIDEOBUF_DONE;
1094 wake_up(&vip->active->done);
1095 vip->active = NULL;
1096 }
1097 if (!vip->closing) {
1098 if (list_empty(&vip->capture))
1099 goto done;
1100
1101 vb = list_first_entry(&vip->capture, struct videobuf_buffer,
1102 queue);
1103 if (NULL == vb) {
1104 pr_info("VIP: no buffer\n");
1105 goto done;
1106 }
1107 vb->state = VIDEOBUF_ACTIVE;
1108 list_del(&vb->queue);
1109 vip->active = vb;
1110 dma = videobuf_to_dma_contig(vb);
1111 switch (vip->format.field) {
1112 case V4L2_FIELD_INTERLACED:
1113 REG_WRITE(vip, DVP_VTP, dma);
1114 REG_WRITE(vip, DVP_VBP, dma + vip->format.width * 2);
1115 break;
1116 case V4L2_FIELD_TOP:
1117 case V4L2_FIELD_BOTTOM:
1118 REG_WRITE(vip, DVP_VTP, dma);
1119 REG_WRITE(vip, DVP_VBP, dma);
1120 break;
1121 default:
1122 pr_warning("VIP: unknown field format\n");
1123 goto done;
1124 break;
1125 }
1126 REG_WRITE(vip, DVP_CTL, REG_READ(vip, DVP_CTL) | DVP_CTL_ENA);
1127 }
1128done:
1129 spin_unlock_irqrestore(&vip->slock, flags);
1130 return IRQ_HANDLED;
1131}
1132
1133/**
1134 * vip_gpio_reserve - reserve gpio pin
1135 * @dev: device
1136 * @pin: GPIO pin number
1137 * @dir: direction, input or output
1138 * @name: GPIO pin name
1139 *
1140 */
1141static int vip_gpio_reserve(struct device *dev, int pin, int dir,
1142 const char *name)
1143{
1144 int ret;
1145
1146 if (pin == -1)
1147 return 0;
1148
1149 ret = gpio_request(pin, name);
1150 if (ret) {
1151 dev_err(dev, "Failed to allocate pin %d (%s)\n", pin, name);
1152 return ret;
1153 }
1154
1155 ret = gpio_direction_output(pin, dir);
1156 if (ret) {
1157 dev_err(dev, "Failed to set direction for pin %d (%s)\n",
1158 pin, name);
1159 gpio_free(pin);
1160 return ret;
1161 }
1162
1163 ret = gpio_export(pin, false);
1164 if (ret) {
1165 dev_err(dev, "Failed to export pin %d (%s)\n", pin, name);
1166 gpio_free(pin);
1167 return ret;
1168 }
1169
1170 return 0;
1171}
1172
1173/**
1174 * vip_gpio_release - release gpio pin
1175 * @dev: device
1176 * @pin: GPIO pin number
1177 * @name: GPIO pin name
1178 *
1179 */
1180static void vip_gpio_release(struct device *dev, int pin, const char *name)
1181{
1182 if (pin != -1) {
1183 dev_dbg(dev, "releasing pin %d (%s)\n", pin, name);
1184 gpio_unexport(pin);
1185 gpio_free(pin);
1186 }
1187}
1188
1189/**
1190 * sta2x11_vip_init_one - init one instance of video device
1191 * @pdev: PCI device
1192 * @ent: (not used)
1193 *
1194 * allocate reset pins for DAC.
1195 * Reset video DAC, this is done via reset line.
1196 * allocate memory for managing device
1197 * request interrupt
1198 * map IO region
1199 * register device
1200 * find and initialize video DAC
1201 *
1202 * return value: 0, no error
1203 *
1204 * -ENOMEM, no memory
1205 *
1206 * -ENODEV, device could not be detected or registered
1207 */
1208static int __devinit sta2x11_vip_init_one(struct pci_dev *pdev,
1209 const struct pci_device_id *ent)
1210{
1211 int ret;
1212 struct sta2x11_vip *vip;
1213 struct vip_config *config;
1214
1215 ret = pci_enable_device(pdev);
1216 if (ret)
1217 return ret;
1218
1219 config = dev_get_platdata(&pdev->dev);
1220 if (!config) {
1221 dev_info(&pdev->dev, "VIP slot disabled\n");
1222 ret = -EINVAL;
1223 goto disable;
1224 }
1225
1226 ret = vip_gpio_reserve(&pdev->dev, config->pwr_pin, 0,
1227 config->pwr_name);
1228 if (ret)
1229 goto disable;
1230
1231 if (config->reset_pin >= 0) {
1232 ret = vip_gpio_reserve(&pdev->dev, config->reset_pin, 0,
1233 config->reset_name);
1234 if (ret) {
1235 vip_gpio_release(&pdev->dev, config->pwr_pin,
1236 config->pwr_name);
1237 goto disable;
1238 }
1239 }
1240
1241 if (config->pwr_pin != -1) {
1242 /* Datasheet says 5ms between PWR and RST */
1243 usleep_range(5000, 25000);
1244 ret = gpio_direction_output(config->pwr_pin, 1);
1245 }
1246
1247 if (config->reset_pin != -1) {
1248 /* Datasheet says 5ms between PWR and RST */
1249 usleep_range(5000, 25000);
1250 ret = gpio_direction_output(config->reset_pin, 1);
1251 }
1252 usleep_range(5000, 25000);
1253
1254 vip = kzalloc(sizeof(struct sta2x11_vip), GFP_KERNEL);
1255 if (!vip) {
1256 ret = -ENOMEM;
1257 goto release_gpios;
1258 }
1259
1260 vip->pdev = pdev;
1261 vip->std = V4L2_STD_PAL;
1262 vip->format = formats_50[0];
1263 vip->config = config;
1264
1265 if (v4l2_device_register(&pdev->dev, &vip->v4l2_dev))
1266 goto free_mem;
1267
1268 dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
1269 (unsigned long)pci_resource_start(pdev, 0),
1270 (unsigned long)pci_resource_len(pdev, 0), pdev->irq);
1271
1272 pci_set_master(pdev);
1273
1274 ret = pci_request_regions(pdev, DRV_NAME);
1275 if (ret)
1276 goto unreg;
1277
1278 vip->iomem = pci_iomap(pdev, 0, 0x100);
1279 if (!vip->iomem) {
1280 ret = -ENOMEM; /* FIXME */
1281 goto release;
1282 }
1283
1284 pci_enable_msi(pdev);
1285
1286 INIT_LIST_HEAD(&vip->capture);
1287 spin_lock_init(&vip->slock);
1288 mutex_init(&vip->mutex);
1289 vip->started = 0;
1290 vip->disabled = 0;
1291
1292 ret = request_irq(pdev->irq,
1293 (irq_handler_t) vip_irq,
1294 IRQF_SHARED, DRV_NAME, vip);
1295 if (ret) {
1296 dev_err(&pdev->dev, "request_irq failed\n");
1297 ret = -ENODEV;
1298 goto unmap;
1299 }
1300
1301 vip->video_dev = video_device_alloc();
1302 if (!vip->video_dev) {
1303 ret = -ENOMEM;
1304 goto release_irq;
1305 }
1306
1307 *(vip->video_dev) = video_dev_template;
1308 video_set_drvdata(vip->video_dev, vip);
1309
1310 ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1);
1311 if (ret)
1312 goto vrelease;
1313
1314 vip->adapter = i2c_get_adapter(vip->config->i2c_id);
1315 if (!vip->adapter) {
1316 ret = -ENODEV;
1317 dev_err(&pdev->dev, "no I2C adapter found\n");
1318 goto vunreg;
1319 }
1320
1321 vip->decoder = v4l2_i2c_new_subdev(&vip->v4l2_dev, vip->adapter,
1322 "adv7180", vip->config->i2c_addr,
1323 NULL);
1324 if (!vip->decoder) {
1325 ret = -ENODEV;
1326 dev_err(&pdev->dev, "no decoder found\n");
1327 goto vunreg;
1328 }
1329
1330 i2c_put_adapter(vip->adapter);
1331
1332 v4l2_subdev_call(vip->decoder, core, init, 0);
1333
1334 pr_info("STA2X11 Video Input Port (VIP) loaded\n");
1335 return 0;
1336
1337vunreg:
1338 video_set_drvdata(vip->video_dev, NULL);
1339vrelease:
1340 if (video_is_registered(vip->video_dev))
1341 video_unregister_device(vip->video_dev);
1342 else
1343 video_device_release(vip->video_dev);
1344release_irq:
1345 free_irq(pdev->irq, vip);
1346 pci_disable_msi(pdev);
1347unmap:
1348 pci_iounmap(pdev, vip->iomem);
1349 mutex_destroy(&vip->mutex);
1350release:
1351 pci_release_regions(pdev);
1352unreg:
1353 v4l2_device_unregister(&vip->v4l2_dev);
1354free_mem:
1355 kfree(vip);
1356release_gpios:
1357 vip_gpio_release(&pdev->dev, config->reset_pin, config->reset_name);
1358 vip_gpio_release(&pdev->dev, config->pwr_pin, config->pwr_name);
1359disable:
1360 /*
1361 * do not call pci_disable_device on sta2x11 because it break all
1362 * other Bus masters on this EP
1363 */
1364 return ret;
1365}
1366
1367/**
1368 * sta2x11_vip_remove_one - release device
1369 * @pdev: PCI device
1370 *
1371 * Undo everything done in .._init_one
1372 *
1373 * unregister video device
1374 * free interrupt
1375 * unmap ioadresses
1376 * free memory
1377 * free GPIO pins
1378 */
1379static void __devexit sta2x11_vip_remove_one(struct pci_dev *pdev)
1380{
1381 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1382 struct sta2x11_vip *vip =
1383 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1384
1385 video_set_drvdata(vip->video_dev, NULL);
1386 video_unregister_device(vip->video_dev);
1387 /*do not call video_device_release() here, is already done */
1388 free_irq(pdev->irq, vip);
1389 pci_disable_msi(pdev);
1390 pci_iounmap(pdev, vip->iomem);
1391 pci_release_regions(pdev);
1392
1393 v4l2_device_unregister(&vip->v4l2_dev);
1394 mutex_destroy(&vip->mutex);
1395
1396 vip_gpio_release(&pdev->dev, vip->config->pwr_pin,
1397 vip->config->pwr_name);
1398 vip_gpio_release(&pdev->dev, vip->config->reset_pin,
1399 vip->config->reset_name);
1400
1401 kfree(vip);
1402 /*
1403 * do not call pci_disable_device on sta2x11 because it break all
1404 * other Bus masters on this EP
1405 */
1406}
1407
1408#ifdef CONFIG_PM
1409
1410/**
1411 * sta2x11_vip_suspend - set device into power save mode
1412 * @pdev: PCI device
1413 * @state: new state of device
1414 *
1415 * all relevant registers are saved and an attempt to set a new state is made.
1416 *
1417 * return value: 0 always indicate success,
1418 * even if device could not be disabled. (workaround for hardware problem)
1419 *
1420 * reurn value : 0, always succesful, even if hardware does not not support
1421 * power down mode.
1422 */
1423static int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state)
1424{
1425 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1426 struct sta2x11_vip *vip =
1427 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1428 unsigned long flags;
1429 int i;
1430
1431 spin_lock_irqsave(&vip->slock, flags);
1432 vip->register_save_area[0] = REG_READ(vip, DVP_CTL);
1433 REG_WRITE(vip, DVP_CTL, vip->register_save_area[0] & DVP_CTL_DIS);
1434 vip->register_save_area[SAVE_COUNT] = REG_READ(vip, DVP_ITM);
1435 REG_WRITE(vip, DVP_ITM, 0);
1436 for (i = 1; i < SAVE_COUNT; i++)
1437 vip->register_save_area[i] = REG_READ(vip, 4 * i);
1438 for (i = 0; i < AUX_COUNT; i++)
1439 vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] =
1440 REG_READ(vip, registers_to_save[i]);
1441 spin_unlock_irqrestore(&vip->slock, flags);
1442 /* save pci state */
1443 pci_save_state(pdev);
1444 if (pci_set_power_state(pdev, pci_choose_state(pdev, state))) {
1445 /*
1446 * do not call pci_disable_device on sta2x11 because it
1447 * break all other Bus masters on this EP
1448 */
1449 vip->disabled = 1;
1450 }
1451
1452 pr_info("VIP: suspend\n");
1453 return 0;
1454}
1455
1456/**
1457 * sta2x11_vip_resume - resume device operation
1458 * @pdev : PCI device
1459 *
1460 * re-enable device, set PCI state to powered and restore registers.
1461 * resume normal device operation afterwards.
1462 *
1463 * return value: 0, no error.
1464 *
1465 * other, could not set device to power on state.
1466 */
1467static int sta2x11_vip_resume(struct pci_dev *pdev)
1468{
1469 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
1470 struct sta2x11_vip *vip =
1471 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1472 unsigned long flags;
1473 int ret, i;
1474
1475 pr_info("VIP: resume\n");
1476 /* restore pci state */
1477 if (vip->disabled) {
1478 ret = pci_enable_device(pdev);
1479 if (ret) {
1480 pr_warning("VIP: Can't enable device.\n");
1481 return ret;
1482 }
1483 vip->disabled = 0;
1484 }
1485 ret = pci_set_power_state(pdev, PCI_D0);
1486 if (ret) {
1487 /*
1488 * do not call pci_disable_device on sta2x11 because it
1489 * break all other Bus masters on this EP
1490 */
1491 pr_warning("VIP: Can't enable device.\n");
1492 vip->disabled = 1;
1493 return ret;
1494 }
1495
1496 pci_restore_state(pdev);
1497
1498 spin_lock_irqsave(&vip->slock, flags);
1499 for (i = 1; i < SAVE_COUNT; i++)
1500 REG_WRITE(vip, 4 * i, vip->register_save_area[i]);
1501 for (i = 0; i < AUX_COUNT; i++)
1502 REG_WRITE(vip, registers_to_save[i],
1503 vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i]);
1504 REG_WRITE(vip, DVP_CTL, vip->register_save_area[0]);
1505 REG_WRITE(vip, DVP_ITM, vip->register_save_area[SAVE_COUNT]);
1506 spin_unlock_irqrestore(&vip->slock, flags);
1507 return 0;
1508}
1509
1510#endif
1511
1512static DEFINE_PCI_DEVICE_TABLE(sta2x11_vip_pci_tbl) = {
1513 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},
1514 {0,}
1515};
1516
1517static struct pci_driver sta2x11_vip_driver = {
1518 .name = DRV_NAME,
1519 .probe = sta2x11_vip_init_one,
1520 .remove = __devexit_p(sta2x11_vip_remove_one),
1521 .id_table = sta2x11_vip_pci_tbl,
1522#ifdef CONFIG_PM
1523 .suspend = sta2x11_vip_suspend,
1524 .resume = sta2x11_vip_resume,
1525#endif
1526};
1527
1528static int __init sta2x11_vip_init_module(void)
1529{
1530 return pci_register_driver(&sta2x11_vip_driver);
1531}
1532
1533static void __exit sta2x11_vip_exit_module(void)
1534{
1535 pci_unregister_driver(&sta2x11_vip_driver);
1536}
1537
1538#ifdef MODULE
1539module_init(sta2x11_vip_init_module);
1540module_exit(sta2x11_vip_exit_module);
1541#else
1542late_initcall_sync(sta2x11_vip_init_module);
1543#endif
1544
1545MODULE_DESCRIPTION("STA2X11 Video Input Port driver");
1546MODULE_AUTHOR("Wind River");
1547MODULE_LICENSE("GPL v2");
1548MODULE_SUPPORTED_DEVICE("sta2x11 video input");
1549MODULE_VERSION(DRV_VERSION);
1550MODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl);
diff --git a/drivers/media/video/sta2x11_vip.h b/drivers/media/video/sta2x11_vip.h
new file mode 100644
index 000000000000..4f81a13666eb
--- /dev/null
+++ b/drivers/media/video/sta2x11_vip.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 2011 Wind River Systems, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 * See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Anders Wallin <anders.wallin@windriver.com>
18 *
19 */
20
21#ifndef __STA2X11_VIP_H
22#define __STA2X11_VIP_H
23
24/**
25 * struct vip_config - video input configuration data
26 * @pwr_name: ADV powerdown name
27 * @pwr_pin: ADV powerdown pin
28 * @reset_name: ADV reset name
29 * @reset_pin: ADV reset pin
30 */
31struct vip_config {
32 const char *pwr_name;
33 int pwr_pin;
34 const char *reset_name;
35 int reset_pin;
36 int i2c_id;
37 int i2c_addr;
38};
39
40#endif /* __STA2X11_VIP_H */
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index d427f8436c70..86a0fc56c330 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -38,13 +38,13 @@
38#include "stk-webcam.h" 38#include "stk-webcam.h"
39 39
40 40
41static bool hflip = 1; 41static bool hflip;
42module_param(hflip, bool, 0444); 42module_param(hflip, bool, 0444);
43MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 1"); 43MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 0");
44 44
45static bool vflip = 1; 45static bool vflip;
46module_param(vflip, bool, 0444); 46module_param(vflip, bool, 0444);
47MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 1"); 47MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 0");
48 48
49static int debug; 49static int debug;
50module_param(debug, int, 0444); 50module_param(debug, int, 0444);
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 465d7086babf..3d7ddd93282d 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -66,29 +66,53 @@ static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
66 val, reg); 66 val, reg);
67} 67}
68 68
69static int tda9840_status(struct v4l2_subdev *sd)
70{
71 struct i2c_client *client = v4l2_get_subdevdata(sd);
72 u8 byte;
73
74 if (1 != i2c_master_recv(client, &byte, 1)) {
75 v4l2_dbg(1, debug, sd,
76 "i2c_master_recv() failed\n");
77 return -EIO;
78 }
79
80 if (byte & 0x80) {
81 v4l2_dbg(1, debug, sd,
82 "TDA9840_DETECT: register contents invalid\n");
83 return -EINVAL;
84 }
85
86 v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
87 return byte & 0x60;
88}
89
69static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) 90static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
70{ 91{
92 int stat = tda9840_status(sd);
71 int byte; 93 int byte;
72 94
73 if (t->index) 95 if (t->index)
74 return -EINVAL; 96 return -EINVAL;
75 97
76 switch (t->audmode) { 98 stat = stat < 0 ? 0 : stat;
77 case V4L2_TUNER_MODE_STEREO: 99 if (stat == 0 || stat == 0x60) /* mono input */
78 byte = TDA9840_SET_STEREO;
79 break;
80 case V4L2_TUNER_MODE_LANG1_LANG2:
81 byte = TDA9840_SET_BOTH;
82 break;
83 case V4L2_TUNER_MODE_LANG1:
84 byte = TDA9840_SET_LANG1;
85 break;
86 case V4L2_TUNER_MODE_LANG2:
87 byte = TDA9840_SET_LANG2;
88 break;
89 default:
90 byte = TDA9840_SET_MONO; 100 byte = TDA9840_SET_MONO;
91 break; 101 else if (stat == 0x40) /* stereo input */
102 byte = (t->audmode == V4L2_TUNER_MODE_MONO) ?
103 TDA9840_SET_MONO : TDA9840_SET_STEREO;
104 else { /* bilingual */
105 switch (t->audmode) {
106 case V4L2_TUNER_MODE_LANG1_LANG2:
107 byte = TDA9840_SET_BOTH;
108 break;
109 case V4L2_TUNER_MODE_LANG2:
110 byte = TDA9840_SET_LANG2;
111 break;
112 default:
113 byte = TDA9840_SET_LANG1;
114 break;
115 }
92 } 116 }
93 v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte); 117 v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
94 tda9840_write(sd, SWITCH, byte); 118 tda9840_write(sd, SWITCH, byte);
@@ -97,25 +121,14 @@ static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
97 121
98static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) 122static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
99{ 123{
100 struct i2c_client *client = v4l2_get_subdevdata(sd); 124 int stat = tda9840_status(sd);
101 u8 byte;
102
103 t->rxsubchans = V4L2_TUNER_SUB_MONO;
104 if (1 != i2c_master_recv(client, &byte, 1)) {
105 v4l2_dbg(1, debug, sd,
106 "i2c_master_recv() failed\n");
107 return -EIO;
108 }
109 125
110 if (byte & 0x80) { 126 if (stat < 0)
111 v4l2_dbg(1, debug, sd, 127 return stat;
112 "TDA9840_DETECT: register contents invalid\n");
113 return -EINVAL;
114 }
115 128
116 v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte); 129 t->rxsubchans = V4L2_TUNER_SUB_MONO;
117 130
118 switch (byte & 0x60) { 131 switch (stat & 0x60) {
119 case 0x00: 132 case 0x00:
120 t->rxsubchans = V4L2_TUNER_SUB_MONO; 133 t->rxsubchans = V4L2_TUNER_SUB_MONO;
121 break; 134 break;
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index a794ae62aebf..bfbf9e56b0a4 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -150,7 +150,6 @@ static int vidioc_querycap(struct file *file, void *fh,
150 strcpy(cap->driver, "tele-video"); 150 strcpy(cap->driver, "tele-video");
151 strcpy(cap->card, "Telegent Poseidon"); 151 strcpy(cap->card, "Telegent Poseidon");
152 usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info)); 152 usb_make_path(p->udev, cap->bus_info, sizeof(cap->bus_info));
153 cap->version = KERNEL_VERSION(0, 0, 1);
154 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | 153 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
155 V4L2_CAP_AUDIO | V4L2_CAP_STREAMING | 154 V4L2_CAP_AUDIO | V4L2_CAP_STREAMING |
156 V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE; 155 V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE;
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c
index 859eb90e4d56..e80b7e190471 100644
--- a/drivers/media/video/tm6000/tm6000-input.c
+++ b/drivers/media/video/tm6000/tm6000-input.c
@@ -168,7 +168,6 @@ static void tm6000_ir_urb_received(struct urb *urb)
168 struct tm6000_IR *ir = dev->ir; 168 struct tm6000_IR *ir = dev->ir;
169 struct tm6000_ir_poll_result poll_result; 169 struct tm6000_ir_poll_result poll_result;
170 char *buf; 170 char *buf;
171 int rc;
172 171
173 dprintk(2, "%s\n",__func__); 172 dprintk(2, "%s\n",__func__);
174 if (urb->status < 0 || urb->actual_length <= 0) { 173 if (urb->status < 0 || urb->actual_length <= 0) {
@@ -192,7 +191,7 @@ static void tm6000_ir_urb_received(struct urb *urb)
192 dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data); 191 dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
193 rc_keydown(ir->rc, poll_result.rc_data, 0); 192 rc_keydown(ir->rc, poll_result.rc_data, 0);
194 193
195 rc = usb_submit_urb(urb, GFP_ATOMIC); 194 usb_submit_urb(urb, GFP_ATOMIC);
196 /* 195 /*
197 * Flash the led. We can't do it here, as it is running on IRQ context. 196 * Flash the led. We can't do it here, as it is running on IRQ context.
198 * So, use the scheduler to do it, in a few ms. 197 * So, use the scheduler to do it, in a few ms.
diff --git a/drivers/media/video/tm6000/tm6000-stds.c b/drivers/media/video/tm6000/tm6000-stds.c
index 9dc0831d813f..5e28d6a2412f 100644
--- a/drivers/media/video/tm6000/tm6000-stds.c
+++ b/drivers/media/video/tm6000/tm6000-stds.c
@@ -338,7 +338,6 @@ static int tm6000_set_audio_std(struct tm6000_core *dev)
338 uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */ 338 uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */
339 uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */ 339 uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
340 uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */ 340 uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */
341 uint8_t nicam_flag = 0; /* No NICAM */
342 341
343 if (dev->radio) { 342 if (dev->radio) {
344 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); 343 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
@@ -398,7 +397,6 @@ static int tm6000_set_audio_std(struct tm6000_core *dev)
398 } else { 397 } else {
399 areg_05 = 0x07; 398 areg_05 = 0x07;
400 } 399 }
401 nicam_flag = 1;
402 break; 400 break;
403 /* other */ 401 /* other */
404 case 3: 402 case 3:
diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c
index bc13db736e24..f7034df94e0a 100644
--- a/drivers/media/video/tm6000/tm6000-video.c
+++ b/drivers/media/video/tm6000/tm6000-video.c
@@ -169,7 +169,6 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
169 struct tm6000_buffer **buf) 169 struct tm6000_buffer **buf)
170{ 170{
171 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); 171 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
172 char *outp;
173 172
174 if (list_empty(&dma_q->active)) { 173 if (list_empty(&dma_q->active)) {
175 dprintk(dev, V4L2_DEBUG_QUEUE, "No active queue to serve\n"); 174 dprintk(dev, V4L2_DEBUG_QUEUE, "No active queue to serve\n");
@@ -179,11 +178,6 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
179 178
180 *buf = list_entry(dma_q->active.next, 179 *buf = list_entry(dma_q->active.next,
181 struct tm6000_buffer, vb.queue); 180 struct tm6000_buffer, vb.queue);
182
183 /* Cleans up buffer - Useful for testing for frame/URB loss */
184 outp = videobuf_to_vmalloc(&(*buf)->vb);
185
186 return;
187} 181}
188 182
189/* 183/*
@@ -211,7 +205,7 @@ static int copy_streams(u8 *data, unsigned long len,
211{ 205{
212 struct tm6000_dmaqueue *dma_q = urb->context; 206 struct tm6000_dmaqueue *dma_q = urb->context;
213 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); 207 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
214 u8 *ptr = data, *endp = data+len, c; 208 u8 *ptr = data, *endp = data+len;
215 unsigned long header = 0; 209 unsigned long header = 0;
216 int rc = 0; 210 int rc = 0;
217 unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0; 211 unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
@@ -264,7 +258,6 @@ static int copy_streams(u8 *data, unsigned long len,
264 } 258 }
265 259
266 /* split the header fields */ 260 /* split the header fields */
267 c = (header >> 24) & 0xff;
268 size = ((header & 0x7e) << 1); 261 size = ((header & 0x7e) << 1);
269 if (size > 0) 262 if (size > 0)
270 size -= 4; 263 size -= 4;
@@ -889,7 +882,6 @@ static int vidioc_querycap(struct file *file, void *priv,
889 882
890 strlcpy(cap->driver, "tm6000", sizeof(cap->driver)); 883 strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
891 strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card)); 884 strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
892 cap->version = TM6000_VERSION;
893 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 885 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
894 V4L2_CAP_STREAMING | 886 V4L2_CAP_STREAMING |
895 V4L2_CAP_AUDIO | 887 V4L2_CAP_AUDIO |
@@ -1732,6 +1724,10 @@ static struct video_device *vdev_init(struct tm6000_core *dev,
1732 vfd->release = video_device_release; 1724 vfd->release = video_device_release;
1733 vfd->debug = tm6000_debug; 1725 vfd->debug = tm6000_debug;
1734 vfd->lock = &dev->lock; 1726 vfd->lock = &dev->lock;
1727 /* Locking in file operations other than ioctl should be done
1728 by the driver, not the V4L2 core.
1729 This driver needs auditing so that this flag can be removed. */
1730 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
1735 1731
1736 snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); 1732 snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
1737 1733
diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/video/tm6000/tm6000.h
index 27ba659cfa85..6df418658c9c 100644
--- a/drivers/media/video/tm6000/tm6000.h
+++ b/drivers/media/video/tm6000/tm6000.h
@@ -33,8 +33,6 @@
33#include "dvb_frontend.h" 33#include "dvb_frontend.h"
34#include "dmxdev.h" 34#include "dmxdev.h"
35 35
36#define TM6000_VERSION KERNEL_VERSION(0, 0, 2)
37
38/* Inputs */ 36/* Inputs */
39enum tm6000_itype { 37enum tm6000_itype {
40 TM6000_INPUT_TV = 1, 38 TM6000_INPUT_TV = 1,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index a5c6397ad591..3e050e12153b 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1241,8 +1241,10 @@ static int tuner_log_status(struct v4l2_subdev *sd)
1241 return 0; 1241 return 0;
1242} 1242}
1243 1243
1244static int tuner_suspend(struct i2c_client *c, pm_message_t state) 1244#ifdef CONFIG_PM_SLEEP
1245static int tuner_suspend(struct device *dev)
1245{ 1246{
1247 struct i2c_client *c = to_i2c_client(dev);
1246 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1248 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1247 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1249 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1248 1250
@@ -1254,8 +1256,9 @@ static int tuner_suspend(struct i2c_client *c, pm_message_t state)
1254 return 0; 1256 return 0;
1255} 1257}
1256 1258
1257static int tuner_resume(struct i2c_client *c) 1259static int tuner_resume(struct device *dev)
1258{ 1260{
1261 struct i2c_client *c = to_i2c_client(dev);
1259 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1262 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1260 1263
1261 tuner_dbg("resume\n"); 1264 tuner_dbg("resume\n");
@@ -1266,6 +1269,7 @@ static int tuner_resume(struct i2c_client *c)
1266 1269
1267 return 0; 1270 return 0;
1268} 1271}
1272#endif
1269 1273
1270static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg) 1274static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
1271{ 1275{
@@ -1310,6 +1314,10 @@ static const struct v4l2_subdev_ops tuner_ops = {
1310 * I2C structs and module init functions 1314 * I2C structs and module init functions
1311 */ 1315 */
1312 1316
1317static const struct dev_pm_ops tuner_pm_ops = {
1318 SET_SYSTEM_SLEEP_PM_OPS(tuner_suspend, tuner_resume)
1319};
1320
1313static const struct i2c_device_id tuner_id[] = { 1321static const struct i2c_device_id tuner_id[] = {
1314 { "tuner", }, /* autodetect */ 1322 { "tuner", }, /* autodetect */
1315 { } 1323 { }
@@ -1320,12 +1328,11 @@ static struct i2c_driver tuner_driver = {
1320 .driver = { 1328 .driver = {
1321 .owner = THIS_MODULE, 1329 .owner = THIS_MODULE,
1322 .name = "tuner", 1330 .name = "tuner",
1331 .pm = &tuner_pm_ops,
1323 }, 1332 },
1324 .probe = tuner_probe, 1333 .probe = tuner_probe,
1325 .remove = tuner_remove, 1334 .remove = tuner_remove,
1326 .command = tuner_command, 1335 .command = tuner_command,
1327 .suspend = tuner_suspend,
1328 .resume = tuner_resume,
1329 .id_table = tuner_id, 1336 .id_table = tuner_id,
1330}; 1337};
1331 1338
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 1326e11cf4a9..b7867427e5c4 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -822,7 +822,7 @@ static int tvp5150_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
822 if (index) 822 if (index)
823 return -EINVAL; 823 return -EINVAL;
824 824
825 *code = V4L2_MBUS_FMT_YUYV8_2X8; 825 *code = V4L2_MBUS_FMT_UYVY8_2X8;
826 return 0; 826 return 0;
827} 827}
828 828
@@ -830,23 +830,16 @@ static int tvp5150_mbus_fmt(struct v4l2_subdev *sd,
830 struct v4l2_mbus_framefmt *f) 830 struct v4l2_mbus_framefmt *f)
831{ 831{
832 struct tvp5150 *decoder = to_tvp5150(sd); 832 struct tvp5150 *decoder = to_tvp5150(sd);
833 v4l2_std_id std;
834 833
835 if (f == NULL) 834 if (f == NULL)
836 return -EINVAL; 835 return -EINVAL;
837 836
838 tvp5150_reset(sd, 0); 837 tvp5150_reset(sd, 0);
839 838
840 /* Calculate height and width based on current standard */
841 if (decoder->norm == V4L2_STD_ALL)
842 std = tvp5150_read_std(sd);
843 else
844 std = decoder->norm;
845
846 f->width = decoder->rect.width; 839 f->width = decoder->rect.width;
847 f->height = decoder->rect.height; 840 f->height = decoder->rect.height;
848 841
849 f->code = V4L2_MBUS_FMT_YUYV8_2X8; 842 f->code = V4L2_MBUS_FMT_UYVY8_2X8;
850 f->field = V4L2_FIELD_SEQ_TB; 843 f->field = V4L2_FIELD_SEQ_TB;
851 f->colorspace = V4L2_COLORSPACE_SMPTE170M; 844 f->colorspace = V4L2_COLORSPACE_SMPTE170M;
852 845
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index d7676d85c4df..fb6a5b57eb83 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -29,6 +29,7 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/videodev2.h> 30#include <linux/videodev2.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/v4l2-dv-timings.h>
32#include <media/tvp7002.h> 33#include <media/tvp7002.h>
33#include <media/v4l2-device.h> 34#include <media/v4l2-device.h>
34#include <media/v4l2-chip-ident.h> 35#include <media/v4l2-chip-ident.h>
@@ -328,6 +329,7 @@ static const struct i2c_reg_value tvp7002_parms_720P50[] = {
328/* Preset definition for handling device operation */ 329/* Preset definition for handling device operation */
329struct tvp7002_preset_definition { 330struct tvp7002_preset_definition {
330 u32 preset; 331 u32 preset;
332 struct v4l2_dv_timings timings;
331 const struct i2c_reg_value *p_settings; 333 const struct i2c_reg_value *p_settings;
332 enum v4l2_colorspace color_space; 334 enum v4l2_colorspace color_space;
333 enum v4l2_field scanmode; 335 enum v4l2_field scanmode;
@@ -341,6 +343,7 @@ struct tvp7002_preset_definition {
341static const struct tvp7002_preset_definition tvp7002_presets[] = { 343static const struct tvp7002_preset_definition tvp7002_presets[] = {
342 { 344 {
343 V4L2_DV_720P60, 345 V4L2_DV_720P60,
346 V4L2_DV_BT_CEA_1280X720P60,
344 tvp7002_parms_720P60, 347 tvp7002_parms_720P60,
345 V4L2_COLORSPACE_REC709, 348 V4L2_COLORSPACE_REC709,
346 V4L2_FIELD_NONE, 349 V4L2_FIELD_NONE,
@@ -351,6 +354,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
351 }, 354 },
352 { 355 {
353 V4L2_DV_1080I60, 356 V4L2_DV_1080I60,
357 V4L2_DV_BT_CEA_1920X1080I60,
354 tvp7002_parms_1080I60, 358 tvp7002_parms_1080I60,
355 V4L2_COLORSPACE_REC709, 359 V4L2_COLORSPACE_REC709,
356 V4L2_FIELD_INTERLACED, 360 V4L2_FIELD_INTERLACED,
@@ -361,6 +365,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
361 }, 365 },
362 { 366 {
363 V4L2_DV_1080I50, 367 V4L2_DV_1080I50,
368 V4L2_DV_BT_CEA_1920X1080I50,
364 tvp7002_parms_1080I50, 369 tvp7002_parms_1080I50,
365 V4L2_COLORSPACE_REC709, 370 V4L2_COLORSPACE_REC709,
366 V4L2_FIELD_INTERLACED, 371 V4L2_FIELD_INTERLACED,
@@ -371,6 +376,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
371 }, 376 },
372 { 377 {
373 V4L2_DV_720P50, 378 V4L2_DV_720P50,
379 V4L2_DV_BT_CEA_1280X720P50,
374 tvp7002_parms_720P50, 380 tvp7002_parms_720P50,
375 V4L2_COLORSPACE_REC709, 381 V4L2_COLORSPACE_REC709,
376 V4L2_FIELD_NONE, 382 V4L2_FIELD_NONE,
@@ -381,6 +387,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
381 }, 387 },
382 { 388 {
383 V4L2_DV_1080P60, 389 V4L2_DV_1080P60,
390 V4L2_DV_BT_CEA_1920X1080P60,
384 tvp7002_parms_1080P60, 391 tvp7002_parms_1080P60,
385 V4L2_COLORSPACE_REC709, 392 V4L2_COLORSPACE_REC709,
386 V4L2_FIELD_NONE, 393 V4L2_FIELD_NONE,
@@ -391,6 +398,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
391 }, 398 },
392 { 399 {
393 V4L2_DV_480P59_94, 400 V4L2_DV_480P59_94,
401 V4L2_DV_BT_CEA_720X480P59_94,
394 tvp7002_parms_480P, 402 tvp7002_parms_480P,
395 V4L2_COLORSPACE_SMPTE170M, 403 V4L2_COLORSPACE_SMPTE170M,
396 V4L2_FIELD_NONE, 404 V4L2_FIELD_NONE,
@@ -401,6 +409,7 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
401 }, 409 },
402 { 410 {
403 V4L2_DV_576P50, 411 V4L2_DV_576P50,
412 V4L2_DV_BT_CEA_720X576P50,
404 tvp7002_parms_576P, 413 tvp7002_parms_576P,
405 V4L2_COLORSPACE_SMPTE170M, 414 V4L2_COLORSPACE_SMPTE170M,
406 V4L2_FIELD_NONE, 415 V4L2_FIELD_NONE,
@@ -605,6 +614,35 @@ static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
605 return -EINVAL; 614 return -EINVAL;
606} 615}
607 616
617static int tvp7002_s_dv_timings(struct v4l2_subdev *sd,
618 struct v4l2_dv_timings *dv_timings)
619{
620 struct tvp7002 *device = to_tvp7002(sd);
621 const struct v4l2_bt_timings *bt = &dv_timings->bt;
622 int i;
623
624 if (dv_timings->type != V4L2_DV_BT_656_1120)
625 return -EINVAL;
626 for (i = 0; i < NUM_PRESETS; i++) {
627 const struct v4l2_bt_timings *t = &tvp7002_presets[i].timings.bt;
628
629 if (!memcmp(bt, t, &bt->standards - &bt->width)) {
630 device->current_preset = &tvp7002_presets[i];
631 return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
632 }
633 }
634 return -EINVAL;
635}
636
637static int tvp7002_g_dv_timings(struct v4l2_subdev *sd,
638 struct v4l2_dv_timings *dv_timings)
639{
640 struct tvp7002 *device = to_tvp7002(sd);
641
642 *dv_timings = device->current_preset->timings;
643 return 0;
644}
645
608/* 646/*
609 * tvp7002_s_ctrl() - Set a control 647 * tvp7002_s_ctrl() - Set a control
610 * @ctrl: ptr to v4l2_ctrl struct 648 * @ctrl: ptr to v4l2_ctrl struct
@@ -666,11 +704,9 @@ static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f
666 * Returns the current DV preset by TVP7002. If no active input is 704 * Returns the current DV preset by TVP7002. If no active input is
667 * detected, returns -EINVAL 705 * detected, returns -EINVAL
668 */ 706 */
669static int tvp7002_query_dv_preset(struct v4l2_subdev *sd, 707static int tvp7002_query_dv(struct v4l2_subdev *sd, int *index)
670 struct v4l2_dv_preset *qpreset)
671{ 708{
672 const struct tvp7002_preset_definition *presets = tvp7002_presets; 709 const struct tvp7002_preset_definition *presets = tvp7002_presets;
673 struct tvp7002 *device;
674 u8 progressive; 710 u8 progressive;
675 u32 lpfr; 711 u32 lpfr;
676 u32 cpln; 712 u32 cpln;
@@ -679,12 +715,9 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
679 u8 lpf_msb; 715 u8 lpf_msb;
680 u8 cpl_lsb; 716 u8 cpl_lsb;
681 u8 cpl_msb; 717 u8 cpl_msb;
682 int index;
683
684 /* Return invalid preset if no active input is detected */
685 qpreset->preset = V4L2_DV_INVALID;
686 718
687 device = to_tvp7002(sd); 719 /* Return invalid index if no active input is detected */
720 *index = NUM_PRESETS;
688 721
689 /* Read standards from device registers */ 722 /* Read standards from device registers */
690 tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error); 723 tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error);
@@ -705,8 +738,8 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
705 progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT; 738 progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT;
706 739
707 /* Do checking of video modes */ 740 /* Do checking of video modes */
708 for (index = 0; index < NUM_PRESETS; index++, presets++) 741 for (*index = 0; *index < NUM_PRESETS; (*index)++, presets++)
709 if (lpfr == presets->lines_per_frame && 742 if (lpfr == presets->lines_per_frame &&
710 progressive == presets->progressive) { 743 progressive == presets->progressive) {
711 if (presets->cpl_min == 0xffff) 744 if (presets->cpl_min == 0xffff)
712 break; 745 break;
@@ -714,17 +747,42 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
714 break; 747 break;
715 } 748 }
716 749
717 if (index == NUM_PRESETS) { 750 if (*index == NUM_PRESETS) {
718 v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n", 751 v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n",
719 lpfr, cpln); 752 lpfr, cpln);
720 return 0; 753 return -ENOLINK;
721 } 754 }
722 755
723 /* Set values in found preset */
724 qpreset->preset = presets->preset;
725
726 /* Update lines per frame and clocks per line info */ 756 /* Update lines per frame and clocks per line info */
727 v4l2_dbg(1, debug, sd, "detected preset: %d\n", presets->preset); 757 v4l2_dbg(1, debug, sd, "detected preset: %d\n", *index);
758 return 0;
759}
760
761static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
762 struct v4l2_dv_preset *qpreset)
763{
764 int index;
765 int err = tvp7002_query_dv(sd, &index);
766
767 if (err || index == NUM_PRESETS) {
768 qpreset->preset = V4L2_DV_INVALID;
769 if (err == -ENOLINK)
770 err = 0;
771 return err;
772 }
773 qpreset->preset = tvp7002_presets[index].preset;
774 return 0;
775}
776
777static int tvp7002_query_dv_timings(struct v4l2_subdev *sd,
778 struct v4l2_dv_timings *timings)
779{
780 int index;
781 int err = tvp7002_query_dv(sd, &index);
782
783 if (err)
784 return err;
785 *timings = tvp7002_presets[index].timings;
728 return 0; 786 return 0;
729} 787}
730 788
@@ -894,6 +952,17 @@ static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
894 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset); 952 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
895} 953}
896 954
955static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd,
956 struct v4l2_enum_dv_timings *timings)
957{
958 /* Check requested format index is within range */
959 if (timings->index >= NUM_PRESETS)
960 return -EINVAL;
961
962 timings->timings = tvp7002_presets[timings->index].timings;
963 return 0;
964}
965
897static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = { 966static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
898 .s_ctrl = tvp7002_s_ctrl, 967 .s_ctrl = tvp7002_s_ctrl,
899}; 968};
@@ -920,6 +989,10 @@ static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
920 .enum_dv_presets = tvp7002_enum_dv_presets, 989 .enum_dv_presets = tvp7002_enum_dv_presets,
921 .s_dv_preset = tvp7002_s_dv_preset, 990 .s_dv_preset = tvp7002_s_dv_preset,
922 .query_dv_preset = tvp7002_query_dv_preset, 991 .query_dv_preset = tvp7002_query_dv_preset,
992 .g_dv_timings = tvp7002_g_dv_timings,
993 .s_dv_timings = tvp7002_s_dv_timings,
994 .enum_dv_timings = tvp7002_enum_dv_timings,
995 .query_dv_timings = tvp7002_query_dv_timings,
923 .s_stream = tvp7002_s_stream, 996 .s_stream = tvp7002_s_stream,
924 .g_mbus_fmt = tvp7002_mbus_fmt, 997 .g_mbus_fmt = tvp7002_mbus_fmt,
925 .try_mbus_fmt = tvp7002_mbus_fmt, 998 .try_mbus_fmt = tvp7002_mbus_fmt,
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index f344411a4578..c9b2042f8bdf 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -601,13 +601,12 @@ static int usbvision_decompress(struct usb_usbvision *usbvision, unsigned char *
601 unsigned char *decompressed, int *start_pos, 601 unsigned char *decompressed, int *start_pos,
602 int *block_typestart_pos, int len) 602 int *block_typestart_pos, int len)
603{ 603{
604 int rest_pixel, idx, max_pos, pos, extra_pos, block_len, block_type_pos, block_type_len; 604 int rest_pixel, idx, pos, extra_pos, block_len, block_type_pos, block_type_len;
605 unsigned char block_byte, block_code, block_type, block_type_byte, integrator; 605 unsigned char block_byte, block_code, block_type, block_type_byte, integrator;
606 606
607 integrator = 0; 607 integrator = 0;
608 pos = *start_pos; 608 pos = *start_pos;
609 block_type_pos = *block_typestart_pos; 609 block_type_pos = *block_typestart_pos;
610 max_pos = 396; /* pos + len; */
611 extra_pos = pos; 610 extra_pos = pos;
612 block_len = 0; 611 block_len = 0;
613 block_byte = 0; 612 block_byte = 0;
@@ -702,7 +701,7 @@ static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision
702 unsigned char strip_data[USBVISION_STRIP_LEN_MAX]; 701 unsigned char strip_data[USBVISION_STRIP_LEN_MAX];
703 unsigned char strip_header[USBVISION_STRIP_HEADER_LEN]; 702 unsigned char strip_header[USBVISION_STRIP_HEADER_LEN];
704 int idx, idx_end, strip_len, strip_ptr, startblock_pos, block_pos, block_type_pos; 703 int idx, idx_end, strip_len, strip_ptr, startblock_pos, block_pos, block_type_pos;
705 int clipmask_index, bytes_per_pixel, rc; 704 int clipmask_index;
706 int image_size; 705 int image_size;
707 unsigned char rv, gv, bv; 706 unsigned char rv, gv, bv;
708 static unsigned char *Y, *U, *V; 707 static unsigned char *Y, *U, *V;
@@ -769,7 +768,6 @@ static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision
769 return parse_state_next_frame; 768 return parse_state_next_frame;
770 } 769 }
771 770
772 bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
773 clipmask_index = frame->curline * MAX_FRAME_WIDTH; 771 clipmask_index = frame->curline * MAX_FRAME_WIDTH;
774 772
775 scratch_get(usbvision, strip_data, strip_len); 773 scratch_get(usbvision, strip_data, strip_len);
@@ -781,14 +779,14 @@ static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision
781 779
782 usbvision->block_pos = block_pos; 780 usbvision->block_pos = block_pos;
783 781
784 rc = usbvision_decompress(usbvision, strip_data, Y, &block_pos, &block_type_pos, idx_end); 782 usbvision_decompress(usbvision, strip_data, Y, &block_pos, &block_type_pos, idx_end);
785 if (strip_len > usbvision->max_strip_len) 783 if (strip_len > usbvision->max_strip_len)
786 usbvision->max_strip_len = strip_len; 784 usbvision->max_strip_len = strip_len;
787 785
788 if (frame->curline % 2) 786 if (frame->curline % 2)
789 rc = usbvision_decompress(usbvision, strip_data, V, &block_pos, &block_type_pos, idx_end / 2); 787 usbvision_decompress(usbvision, strip_data, V, &block_pos, &block_type_pos, idx_end / 2);
790 else 788 else
791 rc = usbvision_decompress(usbvision, strip_data, U, &block_pos, &block_type_pos, idx_end / 2); 789 usbvision_decompress(usbvision, strip_data, U, &block_pos, &block_type_pos, idx_end / 2);
792 790
793 if (block_pos > usbvision->comprblock_pos) 791 if (block_pos > usbvision->comprblock_pos)
794 usbvision->comprblock_pos = block_pos; 792 usbvision->comprblock_pos = block_pos;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 5a74f5e07d7d..9bd8f084f348 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1296,6 +1296,10 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
1296 if (NULL == vdev) 1296 if (NULL == vdev)
1297 return NULL; 1297 return NULL;
1298 *vdev = *vdev_template; 1298 *vdev = *vdev_template;
1299 /* Locking in file operations other than ioctl should be done
1300 by the driver, not the V4L2 core.
1301 This driver needs auditing so that this flag can be removed. */
1302 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
1299 vdev->lock = &usbvision->v4l2_lock; 1303 vdev->lock = &usbvision->v4l2_lock;
1300 vdev->v4l2_dev = &usbvision->v4l2_dev; 1304 vdev->v4l2_dev = &usbvision->v4l2_dev;
1301 snprintf(vdev->name, sizeof(vdev->name), "%s", name); 1305 snprintf(vdev->name, sizeof(vdev->name), "%s", name);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 0efd3b10b353..af26bbe6f76e 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -21,6 +21,7 @@
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/atomic.h> 23#include <linux/atomic.h>
24#include <media/v4l2-ctrls.h>
24 25
25#include "uvcvideo.h" 26#include "uvcvideo.h"
26 27
@@ -420,6 +421,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
420 .offset = 0, 421 .offset = 0,
421 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 422 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
422 .data_type = UVC_CTRL_DATA_TYPE_SIGNED, 423 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
424 .master_id = V4L2_CID_HUE_AUTO,
425 .master_manual = 0,
423 }, 426 },
424 { 427 {
425 .id = V4L2_CID_SATURATION, 428 .id = V4L2_CID_SATURATION,
@@ -492,6 +495,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
492 .offset = 0, 495 .offset = 0,
493 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 496 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
494 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, 497 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
498 .slave_ids = { V4L2_CID_HUE, },
495 }, 499 },
496 { 500 {
497 .id = V4L2_CID_EXPOSURE_AUTO, 501 .id = V4L2_CID_EXPOSURE_AUTO,
@@ -504,6 +508,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
504 .data_type = UVC_CTRL_DATA_TYPE_BITMASK, 508 .data_type = UVC_CTRL_DATA_TYPE_BITMASK,
505 .menu_info = exposure_auto_controls, 509 .menu_info = exposure_auto_controls,
506 .menu_count = ARRAY_SIZE(exposure_auto_controls), 510 .menu_count = ARRAY_SIZE(exposure_auto_controls),
511 .slave_ids = { V4L2_CID_EXPOSURE_ABSOLUTE, },
507 }, 512 },
508 { 513 {
509 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY, 514 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
@@ -524,6 +529,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
524 .offset = 0, 529 .offset = 0,
525 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 530 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
526 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, 531 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
532 .master_id = V4L2_CID_EXPOSURE_AUTO,
533 .master_manual = V4L2_EXPOSURE_MANUAL,
527 }, 534 },
528 { 535 {
529 .id = V4L2_CID_AUTO_WHITE_BALANCE, 536 .id = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -534,6 +541,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
534 .offset = 0, 541 .offset = 0,
535 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 542 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
536 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, 543 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
544 .slave_ids = { V4L2_CID_WHITE_BALANCE_TEMPERATURE, },
537 }, 545 },
538 { 546 {
539 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 547 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
@@ -544,6 +552,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
544 .offset = 0, 552 .offset = 0,
545 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 553 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
546 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, 554 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
555 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
556 .master_manual = 0,
547 }, 557 },
548 { 558 {
549 .id = V4L2_CID_AUTO_WHITE_BALANCE, 559 .id = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -554,6 +564,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
554 .offset = 0, 564 .offset = 0,
555 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 565 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
556 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, 566 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
567 .slave_ids = { V4L2_CID_BLUE_BALANCE,
568 V4L2_CID_RED_BALANCE },
557 }, 569 },
558 { 570 {
559 .id = V4L2_CID_BLUE_BALANCE, 571 .id = V4L2_CID_BLUE_BALANCE,
@@ -564,6 +576,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
564 .offset = 0, 576 .offset = 0,
565 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 577 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
566 .data_type = UVC_CTRL_DATA_TYPE_SIGNED, 578 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
579 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
580 .master_manual = 0,
567 }, 581 },
568 { 582 {
569 .id = V4L2_CID_RED_BALANCE, 583 .id = V4L2_CID_RED_BALANCE,
@@ -574,6 +588,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
574 .offset = 16, 588 .offset = 16,
575 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 589 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
576 .data_type = UVC_CTRL_DATA_TYPE_SIGNED, 590 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
591 .master_id = V4L2_CID_AUTO_WHITE_BALANCE,
592 .master_manual = 0,
577 }, 593 },
578 { 594 {
579 .id = V4L2_CID_FOCUS_ABSOLUTE, 595 .id = V4L2_CID_FOCUS_ABSOLUTE,
@@ -584,6 +600,8 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
584 .offset = 0, 600 .offset = 0,
585 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 601 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
586 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, 602 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
603 .master_id = V4L2_CID_FOCUS_AUTO,
604 .master_manual = 0,
587 }, 605 },
588 { 606 {
589 .id = V4L2_CID_FOCUS_AUTO, 607 .id = V4L2_CID_FOCUS_AUTO,
@@ -594,6 +612,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
594 .offset = 0, 612 .offset = 0,
595 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 613 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
596 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, 614 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
615 .slave_ids = { V4L2_CID_FOCUS_ABSOLUTE, },
597 }, 616 },
598 { 617 {
599 .id = V4L2_CID_IRIS_ABSOLUTE, 618 .id = V4L2_CID_IRIS_ABSOLUTE,
@@ -899,25 +918,54 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
899 return 0; 918 return 0;
900} 919}
901 920
902int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, 921static int __uvc_ctrl_get(struct uvc_video_chain *chain,
903 struct v4l2_queryctrl *v4l2_ctrl) 922 struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
923 s32 *value)
904{ 924{
905 struct uvc_control *ctrl;
906 struct uvc_control_mapping *mapping;
907 struct uvc_menu_info *menu; 925 struct uvc_menu_info *menu;
908 unsigned int i; 926 unsigned int i;
909 int ret; 927 int ret;
910 928
911 ret = mutex_lock_interruptible(&chain->ctrl_mutex); 929 if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
912 if (ret < 0) 930 return -EINVAL;
913 return -ERESTARTSYS;
914 931
915 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); 932 if (!ctrl->loaded) {
916 if (ctrl == NULL) { 933 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
917 ret = -EINVAL; 934 chain->dev->intfnum, ctrl->info.selector,
918 goto done; 935 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
936 ctrl->info.size);
937 if (ret < 0)
938 return ret;
939
940 ctrl->loaded = 1;
919 } 941 }
920 942
943 *value = mapping->get(mapping, UVC_GET_CUR,
944 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
945
946 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
947 menu = mapping->menu_info;
948 for (i = 0; i < mapping->menu_count; ++i, ++menu) {
949 if (menu->value == *value) {
950 *value = i;
951 break;
952 }
953 }
954 }
955
956 return 0;
957}
958
959static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
960 struct uvc_control *ctrl,
961 struct uvc_control_mapping *mapping,
962 struct v4l2_queryctrl *v4l2_ctrl)
963{
964 struct uvc_control_mapping *master_map = NULL;
965 struct uvc_control *master_ctrl = NULL;
966 struct uvc_menu_info *menu;
967 unsigned int i;
968
921 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); 969 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
922 v4l2_ctrl->id = mapping->id; 970 v4l2_ctrl->id = mapping->id;
923 v4l2_ctrl->type = mapping->v4l2_type; 971 v4l2_ctrl->type = mapping->v4l2_type;
@@ -929,10 +977,23 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
929 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) 977 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
930 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 978 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
931 979
980 if (mapping->master_id)
981 __uvc_find_control(ctrl->entity, mapping->master_id,
982 &master_map, &master_ctrl, 0);
983 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
984 s32 val;
985 int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
986 if (ret < 0)
987 return ret;
988
989 if (val != mapping->master_manual)
990 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
991 }
992
932 if (!ctrl->cached) { 993 if (!ctrl->cached) {
933 ret = uvc_ctrl_populate_cache(chain, ctrl); 994 int ret = uvc_ctrl_populate_cache(chain, ctrl);
934 if (ret < 0) 995 if (ret < 0)
935 goto done; 996 return ret;
936 } 997 }
937 998
938 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) { 999 if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
@@ -954,19 +1015,19 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
954 } 1015 }
955 } 1016 }
956 1017
957 goto done; 1018 return 0;
958 1019
959 case V4L2_CTRL_TYPE_BOOLEAN: 1020 case V4L2_CTRL_TYPE_BOOLEAN:
960 v4l2_ctrl->minimum = 0; 1021 v4l2_ctrl->minimum = 0;
961 v4l2_ctrl->maximum = 1; 1022 v4l2_ctrl->maximum = 1;
962 v4l2_ctrl->step = 1; 1023 v4l2_ctrl->step = 1;
963 goto done; 1024 return 0;
964 1025
965 case V4L2_CTRL_TYPE_BUTTON: 1026 case V4L2_CTRL_TYPE_BUTTON:
966 v4l2_ctrl->minimum = 0; 1027 v4l2_ctrl->minimum = 0;
967 v4l2_ctrl->maximum = 0; 1028 v4l2_ctrl->maximum = 0;
968 v4l2_ctrl->step = 0; 1029 v4l2_ctrl->step = 0;
969 goto done; 1030 return 0;
970 1031
971 default: 1032 default:
972 break; 1033 break;
@@ -984,6 +1045,27 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
984 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, 1045 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
985 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); 1046 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
986 1047
1048 return 0;
1049}
1050
1051int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
1052 struct v4l2_queryctrl *v4l2_ctrl)
1053{
1054 struct uvc_control *ctrl;
1055 struct uvc_control_mapping *mapping;
1056 int ret;
1057
1058 ret = mutex_lock_interruptible(&chain->ctrl_mutex);
1059 if (ret < 0)
1060 return -ERESTARTSYS;
1061
1062 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
1063 if (ctrl == NULL) {
1064 ret = -EINVAL;
1065 goto done;
1066 }
1067
1068 ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl);
987done: 1069done:
988 mutex_unlock(&chain->ctrl_mutex); 1070 mutex_unlock(&chain->ctrl_mutex);
989 return ret; 1071 return ret;
@@ -1054,6 +1136,174 @@ done:
1054 return ret; 1136 return ret;
1055} 1137}
1056 1138
1139/* --------------------------------------------------------------------------
1140 * Ctrl event handling
1141 */
1142
1143static void uvc_ctrl_fill_event(struct uvc_video_chain *chain,
1144 struct v4l2_event *ev,
1145 struct uvc_control *ctrl,
1146 struct uvc_control_mapping *mapping,
1147 s32 value, u32 changes)
1148{
1149 struct v4l2_queryctrl v4l2_ctrl;
1150
1151 __uvc_query_v4l2_ctrl(chain, ctrl, mapping, &v4l2_ctrl);
1152
1153 memset(ev->reserved, 0, sizeof(ev->reserved));
1154 ev->type = V4L2_EVENT_CTRL;
1155 ev->id = v4l2_ctrl.id;
1156 ev->u.ctrl.value = value;
1157 ev->u.ctrl.changes = changes;
1158 ev->u.ctrl.type = v4l2_ctrl.type;
1159 ev->u.ctrl.flags = v4l2_ctrl.flags;
1160 ev->u.ctrl.minimum = v4l2_ctrl.minimum;
1161 ev->u.ctrl.maximum = v4l2_ctrl.maximum;
1162 ev->u.ctrl.step = v4l2_ctrl.step;
1163 ev->u.ctrl.default_value = v4l2_ctrl.default_value;
1164}
1165
1166static void uvc_ctrl_send_event(struct uvc_fh *handle,
1167 struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
1168 s32 value, u32 changes)
1169{
1170 struct v4l2_subscribed_event *sev;
1171 struct v4l2_event ev;
1172
1173 if (list_empty(&mapping->ev_subs))
1174 return;
1175
1176 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, value, changes);
1177
1178 list_for_each_entry(sev, &mapping->ev_subs, node) {
1179 if (sev->fh && (sev->fh != &handle->vfh ||
1180 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK) ||
1181 (changes & V4L2_EVENT_CTRL_CH_FLAGS)))
1182 v4l2_event_queue_fh(sev->fh, &ev);
1183 }
1184}
1185
1186static void uvc_ctrl_send_slave_event(struct uvc_fh *handle,
1187 struct uvc_control *master, u32 slave_id,
1188 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
1189{
1190 struct uvc_control_mapping *mapping = NULL;
1191 struct uvc_control *ctrl = NULL;
1192 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
1193 unsigned int i;
1194 s32 val = 0;
1195
1196 /*
1197 * We can skip sending an event for the slave if the slave
1198 * is being modified in the same transaction.
1199 */
1200 for (i = 0; i < xctrls_count; i++) {
1201 if (xctrls[i].id == slave_id)
1202 return;
1203 }
1204
1205 __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0);
1206 if (ctrl == NULL)
1207 return;
1208
1209 if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
1210 changes |= V4L2_EVENT_CTRL_CH_VALUE;
1211
1212 uvc_ctrl_send_event(handle, ctrl, mapping, val, changes);
1213}
1214
1215static void uvc_ctrl_send_events(struct uvc_fh *handle,
1216 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
1217{
1218 struct uvc_control_mapping *mapping;
1219 struct uvc_control *ctrl;
1220 u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
1221 unsigned int i;
1222 unsigned int j;
1223
1224 for (i = 0; i < xctrls_count; ++i) {
1225 ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
1226
1227 for (j = 0; j < ARRAY_SIZE(mapping->slave_ids); ++j) {
1228 if (!mapping->slave_ids[j])
1229 break;
1230 uvc_ctrl_send_slave_event(handle, ctrl,
1231 mapping->slave_ids[j],
1232 xctrls, xctrls_count);
1233 }
1234
1235 /*
1236 * If the master is being modified in the same transaction
1237 * flags may change too.
1238 */
1239 if (mapping->master_id) {
1240 for (j = 0; j < xctrls_count; j++) {
1241 if (xctrls[j].id == mapping->master_id) {
1242 changes |= V4L2_EVENT_CTRL_CH_FLAGS;
1243 break;
1244 }
1245 }
1246 }
1247
1248 uvc_ctrl_send_event(handle, ctrl, mapping, xctrls[i].value,
1249 changes);
1250 }
1251}
1252
1253static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
1254{
1255 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);
1256 struct uvc_control_mapping *mapping;
1257 struct uvc_control *ctrl;
1258 int ret;
1259
1260 ret = mutex_lock_interruptible(&handle->chain->ctrl_mutex);
1261 if (ret < 0)
1262 return -ERESTARTSYS;
1263
1264 ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
1265 if (ctrl == NULL) {
1266 ret = -EINVAL;
1267 goto done;
1268 }
1269
1270 list_add_tail(&sev->node, &mapping->ev_subs);
1271 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {
1272 struct v4l2_event ev;
1273 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
1274 s32 val = 0;
1275
1276 if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
1277 changes |= V4L2_EVENT_CTRL_CH_VALUE;
1278
1279 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,
1280 changes);
1281 /* Mark the queue as active, allowing this initial
1282 event to be accepted. */
1283 sev->elems = elems;
1284 v4l2_event_queue_fh(sev->fh, &ev);
1285 }
1286
1287done:
1288 mutex_unlock(&handle->chain->ctrl_mutex);
1289 return ret;
1290}
1291
1292static void uvc_ctrl_del_event(struct v4l2_subscribed_event *sev)
1293{
1294 struct uvc_fh *handle = container_of(sev->fh, struct uvc_fh, vfh);
1295
1296 mutex_lock(&handle->chain->ctrl_mutex);
1297 list_del(&sev->node);
1298 mutex_unlock(&handle->chain->ctrl_mutex);
1299}
1300
1301const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops = {
1302 .add = uvc_ctrl_add_event,
1303 .del = uvc_ctrl_del_event,
1304 .replace = v4l2_ctrl_replace,
1305 .merge = v4l2_ctrl_merge,
1306};
1057 1307
1058/* -------------------------------------------------------------------------- 1308/* --------------------------------------------------------------------------
1059 * Control transactions 1309 * Control transactions
@@ -1101,9 +1351,12 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1101 1351
1102 /* Reset the loaded flag for auto-update controls that were 1352 /* Reset the loaded flag for auto-update controls that were
1103 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent 1353 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
1104 * uvc_ctrl_get from using the cached value. 1354 * uvc_ctrl_get from using the cached value, and for write-only
1355 * controls to prevent uvc_ctrl_set from setting bits not
1356 * explicitly set by the user.
1105 */ 1357 */
1106 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE) 1358 if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE ||
1359 !(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
1107 ctrl->loaded = 0; 1360 ctrl->loaded = 0;
1108 1361
1109 if (!ctrl->dirty) 1362 if (!ctrl->dirty)
@@ -1131,8 +1384,11 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1131 return 0; 1384 return 0;
1132} 1385}
1133 1386
1134int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback) 1387int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
1388 const struct v4l2_ext_control *xctrls,
1389 unsigned int xctrls_count)
1135{ 1390{
1391 struct uvc_video_chain *chain = handle->chain;
1136 struct uvc_entity *entity; 1392 struct uvc_entity *entity;
1137 int ret = 0; 1393 int ret = 0;
1138 1394
@@ -1143,6 +1399,8 @@ int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
1143 goto done; 1399 goto done;
1144 } 1400 }
1145 1401
1402 if (!rollback)
1403 uvc_ctrl_send_events(handle, xctrls, xctrls_count);
1146done: 1404done:
1147 mutex_unlock(&chain->ctrl_mutex); 1405 mutex_unlock(&chain->ctrl_mutex);
1148 return ret; 1406 return ret;
@@ -1153,39 +1411,12 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
1153{ 1411{
1154 struct uvc_control *ctrl; 1412 struct uvc_control *ctrl;
1155 struct uvc_control_mapping *mapping; 1413 struct uvc_control_mapping *mapping;
1156 struct uvc_menu_info *menu;
1157 unsigned int i;
1158 int ret;
1159 1414
1160 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1415 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1161 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) 1416 if (ctrl == NULL)
1162 return -EINVAL; 1417 return -EINVAL;
1163 1418
1164 if (!ctrl->loaded) { 1419 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
1165 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
1166 chain->dev->intfnum, ctrl->info.selector,
1167 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1168 ctrl->info.size);
1169 if (ret < 0)
1170 return ret;
1171
1172 ctrl->loaded = 1;
1173 }
1174
1175 xctrl->value = mapping->get(mapping, UVC_GET_CUR,
1176 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
1177
1178 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
1179 menu = mapping->menu_info;
1180 for (i = 0; i < mapping->menu_count; ++i, ++menu) {
1181 if (menu->value == xctrl->value) {
1182 xctrl->value = i;
1183 break;
1184 }
1185 }
1186 }
1187
1188 return 0;
1189} 1420}
1190 1421
1191int uvc_ctrl_set(struct uvc_video_chain *chain, 1422int uvc_ctrl_set(struct uvc_video_chain *chain,
@@ -1641,6 +1872,8 @@ static int __uvc_ctrl_add_mapping(struct uvc_device *dev,
1641 if (map == NULL) 1872 if (map == NULL)
1642 return -ENOMEM; 1873 return -ENOMEM;
1643 1874
1875 INIT_LIST_HEAD(&map->ev_subs);
1876
1644 size = sizeof(*mapping->menu_info) * mapping->menu_count; 1877 size = sizeof(*mapping->menu_info) * mapping->menu_count;
1645 map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL); 1878 map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL);
1646 if (map->menu_info == NULL) { 1879 if (map->menu_info == NULL) {
@@ -1653,7 +1886,6 @@ static int __uvc_ctrl_add_mapping(struct uvc_device *dev,
1653 if (map->set == NULL) 1886 if (map->set == NULL)
1654 map->set = uvc_set_le_value; 1887 map->set = uvc_set_le_value;
1655 1888
1656 map->ctrl = &ctrl->info;
1657 list_add_tail(&map->list, &ctrl->info.mappings); 1889 list_add_tail(&map->list, &ctrl->info.mappings);
1658 uvc_trace(UVC_TRACE_CONTROL, 1890 uvc_trace(UVC_TRACE_CONTROL,
1659 "Adding mapping '%s' to control %pUl/%u.\n", 1891 "Adding mapping '%s' to control %pUl/%u.\n",
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 8f54e24e3f35..9288fbd5001b 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -207,6 +207,19 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
207 return ret; 207 return ret;
208} 208}
209 209
210#ifndef CONFIG_MMU
211unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
212 unsigned long pgoff)
213{
214 unsigned long ret;
215
216 mutex_lock(&queue->mutex);
217 ret = vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0);
218 mutex_unlock(&queue->mutex);
219 return ret;
220}
221#endif
222
210unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, 223unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
211 poll_table *wait) 224 poll_table *wait)
212{ 225{
@@ -237,36 +250,6 @@ int uvc_queue_allocated(struct uvc_video_queue *queue)
237 return allocated; 250 return allocated;
238} 251}
239 252
240#ifndef CONFIG_MMU
241/*
242 * Get unmapped area.
243 *
244 * NO-MMU arch need this function to make mmap() work correctly.
245 */
246unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
247 unsigned long pgoff)
248{
249 struct uvc_buffer *buffer;
250 unsigned int i;
251 unsigned long ret;
252
253 mutex_lock(&queue->mutex);
254 for (i = 0; i < queue->count; ++i) {
255 buffer = &queue->buffer[i];
256 if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff)
257 break;
258 }
259 if (i == queue->count) {
260 ret = -EINVAL;
261 goto done;
262 }
263 ret = (unsigned long)buf->mem;
264done:
265 mutex_unlock(&queue->mutex);
266 return ret;
267}
268#endif
269
270/* 253/*
271 * Enable or disable the video buffers queue. 254 * Enable or disable the video buffers queue.
272 * 255 *
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index ff2cdddf9bc6..759bef8897e9 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -25,6 +25,8 @@
25#include <linux/atomic.h> 25#include <linux/atomic.h>
26 26
27#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-event.h>
28#include <media/v4l2-ioctl.h> 30#include <media/v4l2-ioctl.h>
29 31
30#include "uvcvideo.h" 32#include "uvcvideo.h"
@@ -505,6 +507,8 @@ static int uvc_v4l2_open(struct file *file)
505 } 507 }
506 } 508 }
507 509
510 v4l2_fh_init(&handle->vfh, stream->vdev);
511 v4l2_fh_add(&handle->vfh);
508 handle->chain = stream->chain; 512 handle->chain = stream->chain;
509 handle->stream = stream; 513 handle->stream = stream;
510 handle->state = UVC_HANDLE_PASSIVE; 514 handle->state = UVC_HANDLE_PASSIVE;
@@ -528,6 +532,8 @@ static int uvc_v4l2_release(struct file *file)
528 532
529 /* Release the file handle. */ 533 /* Release the file handle. */
530 uvc_dismiss_privileges(handle); 534 uvc_dismiss_privileges(handle);
535 v4l2_fh_del(&handle->vfh);
536 v4l2_fh_exit(&handle->vfh);
531 kfree(handle); 537 kfree(handle);
532 file->private_data = NULL; 538 file->private_data = NULL;
533 539
@@ -584,7 +590,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
584 return ret; 590 return ret;
585 591
586 ret = uvc_ctrl_get(chain, &xctrl); 592 ret = uvc_ctrl_get(chain, &xctrl);
587 uvc_ctrl_rollback(chain); 593 uvc_ctrl_rollback(handle);
588 if (ret >= 0) 594 if (ret >= 0)
589 ctrl->value = xctrl.value; 595 ctrl->value = xctrl.value;
590 break; 596 break;
@@ -605,10 +611,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
605 611
606 ret = uvc_ctrl_set(chain, &xctrl); 612 ret = uvc_ctrl_set(chain, &xctrl);
607 if (ret < 0) { 613 if (ret < 0) {
608 uvc_ctrl_rollback(chain); 614 uvc_ctrl_rollback(handle);
609 return ret; 615 return ret;
610 } 616 }
611 ret = uvc_ctrl_commit(chain); 617 ret = uvc_ctrl_commit(handle, &xctrl, 1);
612 if (ret == 0) 618 if (ret == 0)
613 ctrl->value = xctrl.value; 619 ctrl->value = xctrl.value;
614 break; 620 break;
@@ -630,13 +636,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
630 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 636 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
631 ret = uvc_ctrl_get(chain, ctrl); 637 ret = uvc_ctrl_get(chain, ctrl);
632 if (ret < 0) { 638 if (ret < 0) {
633 uvc_ctrl_rollback(chain); 639 uvc_ctrl_rollback(handle);
634 ctrls->error_idx = i; 640 ctrls->error_idx = i;
635 return ret; 641 return ret;
636 } 642 }
637 } 643 }
638 ctrls->error_idx = 0; 644 ctrls->error_idx = 0;
639 ret = uvc_ctrl_rollback(chain); 645 ret = uvc_ctrl_rollback(handle);
640 break; 646 break;
641 } 647 }
642 648
@@ -654,7 +660,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
654 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 660 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
655 ret = uvc_ctrl_set(chain, ctrl); 661 ret = uvc_ctrl_set(chain, ctrl);
656 if (ret < 0) { 662 if (ret < 0) {
657 uvc_ctrl_rollback(chain); 663 uvc_ctrl_rollback(handle);
658 ctrls->error_idx = i; 664 ctrls->error_idx = i;
659 return ret; 665 return ret;
660 } 666 }
@@ -663,9 +669,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
663 ctrls->error_idx = 0; 669 ctrls->error_idx = 0;
664 670
665 if (cmd == VIDIOC_S_EXT_CTRLS) 671 if (cmd == VIDIOC_S_EXT_CTRLS)
666 ret = uvc_ctrl_commit(chain); 672 ret = uvc_ctrl_commit(handle,
673 ctrls->controls, ctrls->count);
667 else 674 else
668 ret = uvc_ctrl_rollback(chain); 675 ret = uvc_ctrl_rollback(handle);
669 break; 676 break;
670 } 677 }
671 678
@@ -687,7 +694,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
687 break; 694 break;
688 } 695 }
689 pin = iterm->id; 696 pin = iterm->id;
690 } else if (pin < selector->bNrInPins) { 697 } else if (index < selector->bNrInPins) {
691 pin = selector->baSourceID[index]; 698 pin = selector->baSourceID[index];
692 list_for_each_entry(iterm, &chain->entities, chain) { 699 list_for_each_entry(iterm, &chain->entities, chain) {
693 if (!UVC_ENTITY_IS_ITERM(iterm)) 700 if (!UVC_ENTITY_IS_ITERM(iterm))
@@ -990,6 +997,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
990 return uvc_video_enable(stream, 0); 997 return uvc_video_enable(stream, 0);
991 } 998 }
992 999
1000 case VIDIOC_SUBSCRIBE_EVENT:
1001 {
1002 struct v4l2_event_subscription *sub = arg;
1003
1004 switch (sub->type) {
1005 case V4L2_EVENT_CTRL:
1006 return v4l2_event_subscribe(&handle->vfh, sub, 0,
1007 &uvc_ctrl_sub_ev_ops);
1008 default:
1009 return -EINVAL;
1010 }
1011 }
1012
1013 case VIDIOC_UNSUBSCRIBE_EVENT:
1014 return v4l2_event_unsubscribe(&handle->vfh, arg);
1015
1016 case VIDIOC_DQEVENT:
1017 return v4l2_event_dequeue(&handle->vfh, arg,
1018 file->f_flags & O_NONBLOCK);
1019
993 /* Analog video standards make no sense for digital cameras. */ 1020 /* Analog video standards make no sense for digital cameras. */
994 case VIDIOC_ENUMSTD: 1021 case VIDIOC_ENUMSTD:
995 case VIDIOC_QUERYSTD: 1022 case VIDIOC_QUERYSTD:
@@ -1097,7 +1124,8 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1097 __put_user(kp->menu_count, &up->menu_count)) 1124 __put_user(kp->menu_count, &up->menu_count))
1098 return -EFAULT; 1125 return -EFAULT;
1099 1126
1100 __clear_user(up->reserved, sizeof(up->reserved)); 1127 if (__clear_user(up->reserved, sizeof(up->reserved)))
1128 return -EFAULT;
1101 1129
1102 if (kp->menu_count == 0) 1130 if (kp->menu_count == 0)
1103 return 0; 1131 return 0;
@@ -1105,8 +1133,6 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1105 if (get_user(p, &up->menu_info)) 1133 if (get_user(p, &up->menu_info))
1106 return -EFAULT; 1134 return -EFAULT;
1107 umenus = compat_ptr(p); 1135 umenus = compat_ptr(p);
1108 if (!access_ok(VERIFY_WRITE, umenus, kp->menu_count * sizeof(*umenus)))
1109 return -EFAULT;
1110 1136
1111 if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus))) 1137 if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
1112 return -EFAULT; 1138 return -EFAULT;
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 67f88d85bb16..7c3d082505b7 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -13,6 +13,8 @@
13#include <linux/videodev2.h> 13#include <linux/videodev2.h>
14#include <media/media-device.h> 14#include <media/media-device.h>
15#include <media/v4l2-device.h> 15#include <media/v4l2-device.h>
16#include <media/v4l2-event.h>
17#include <media/v4l2-fh.h>
16#include <media/videobuf2-core.h> 18#include <media/videobuf2-core.h>
17 19
18/* -------------------------------------------------------------------------- 20/* --------------------------------------------------------------------------
@@ -153,8 +155,7 @@ struct uvc_control_info {
153 155
154struct uvc_control_mapping { 156struct uvc_control_mapping {
155 struct list_head list; 157 struct list_head list;
156 158 struct list_head ev_subs;
157 struct uvc_control_info *ctrl;
158 159
159 __u32 id; 160 __u32 id;
160 __u8 name[32]; 161 __u8 name[32];
@@ -169,6 +170,10 @@ struct uvc_control_mapping {
169 struct uvc_menu_info *menu_info; 170 struct uvc_menu_info *menu_info;
170 __u32 menu_count; 171 __u32 menu_count;
171 172
173 __u32 master_id;
174 __s32 master_manual;
175 __u32 slave_ids[2];
176
172 __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query, 177 __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query,
173 const __u8 *data); 178 const __u8 *data);
174 void (*set) (struct uvc_control_mapping *mapping, __s32 value, 179 void (*set) (struct uvc_control_mapping *mapping, __s32 value,
@@ -524,6 +529,7 @@ enum uvc_handle_state {
524}; 529};
525 530
526struct uvc_fh { 531struct uvc_fh {
532 struct v4l2_fh vfh;
527 struct uvc_video_chain *chain; 533 struct uvc_video_chain *chain;
528 struct uvc_streaming *stream; 534 struct uvc_streaming *stream;
529 enum uvc_handle_state state; 535 enum uvc_handle_state state;
@@ -643,6 +649,8 @@ extern int uvc_status_suspend(struct uvc_device *dev);
643extern int uvc_status_resume(struct uvc_device *dev); 649extern int uvc_status_resume(struct uvc_device *dev);
644 650
645/* Controls */ 651/* Controls */
652extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
653
646extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, 654extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
647 struct v4l2_queryctrl *v4l2_ctrl); 655 struct v4l2_queryctrl *v4l2_ctrl);
648extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, 656extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
@@ -655,14 +663,18 @@ extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
655extern int uvc_ctrl_resume_device(struct uvc_device *dev); 663extern int uvc_ctrl_resume_device(struct uvc_device *dev);
656 664
657extern int uvc_ctrl_begin(struct uvc_video_chain *chain); 665extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
658extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback); 666extern int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
659static inline int uvc_ctrl_commit(struct uvc_video_chain *chain) 667 const struct v4l2_ext_control *xctrls,
668 unsigned int xctrls_count);
669static inline int uvc_ctrl_commit(struct uvc_fh *handle,
670 const struct v4l2_ext_control *xctrls,
671 unsigned int xctrls_count)
660{ 672{
661 return __uvc_ctrl_commit(chain, 0); 673 return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count);
662} 674}
663static inline int uvc_ctrl_rollback(struct uvc_video_chain *chain) 675static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
664{ 676{
665 return __uvc_ctrl_commit(chain, 1); 677 return __uvc_ctrl_commit(handle, 1, NULL, 0);
666} 678}
667 679
668extern int uvc_ctrl_get(struct uvc_video_chain *chain, 680extern int uvc_ctrl_get(struct uvc_video_chain *chain,
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 2829d256e4b7..5327ad3a6390 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -37,7 +37,7 @@ struct v4l2_clip32 {
37 37
38struct v4l2_window32 { 38struct v4l2_window32 {
39 struct v4l2_rect w; 39 struct v4l2_rect w;
40 enum v4l2_field field; 40 __u32 field; /* enum v4l2_field */
41 __u32 chromakey; 41 __u32 chromakey;
42 compat_caddr_t clips; /* actually struct v4l2_clip32 * */ 42 compat_caddr_t clips; /* actually struct v4l2_clip32 * */
43 __u32 clipcount; 43 __u32 clipcount;
@@ -147,7 +147,7 @@ static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp,
147} 147}
148 148
149struct v4l2_format32 { 149struct v4l2_format32 {
150 enum v4l2_buf_type type; 150 __u32 type; /* enum v4l2_buf_type */
151 union { 151 union {
152 struct v4l2_pix_format pix; 152 struct v4l2_pix_format pix;
153 struct v4l2_pix_format_mplane pix_mp; 153 struct v4l2_pix_format_mplane pix_mp;
@@ -170,7 +170,7 @@ struct v4l2_format32 {
170struct v4l2_create_buffers32 { 170struct v4l2_create_buffers32 {
171 __u32 index; 171 __u32 index;
172 __u32 count; 172 __u32 count;
173 enum v4l2_memory memory; 173 __u32 memory; /* enum v4l2_memory */
174 struct v4l2_format32 format; 174 struct v4l2_format32 format;
175 __u32 reserved[8]; 175 __u32 reserved[8];
176}; 176};
@@ -311,16 +311,16 @@ struct v4l2_plane32 {
311 311
312struct v4l2_buffer32 { 312struct v4l2_buffer32 {
313 __u32 index; 313 __u32 index;
314 enum v4l2_buf_type type; 314 __u32 type; /* enum v4l2_buf_type */
315 __u32 bytesused; 315 __u32 bytesused;
316 __u32 flags; 316 __u32 flags;
317 enum v4l2_field field; 317 __u32 field; /* enum v4l2_field */
318 struct compat_timeval timestamp; 318 struct compat_timeval timestamp;
319 struct v4l2_timecode timecode; 319 struct v4l2_timecode timecode;
320 __u32 sequence; 320 __u32 sequence;
321 321
322 /* memory location */ 322 /* memory location */
323 enum v4l2_memory memory; 323 __u32 memory; /* enum v4l2_memory */
324 union { 324 union {
325 __u32 offset; 325 __u32 offset;
326 compat_long_t userptr; 326 compat_long_t userptr;
@@ -1023,6 +1023,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1023 case VIDIOC_UNSUBSCRIBE_EVENT: 1023 case VIDIOC_UNSUBSCRIBE_EVENT:
1024 case VIDIOC_CREATE_BUFS32: 1024 case VIDIOC_CREATE_BUFS32:
1025 case VIDIOC_PREPARE_BUF32: 1025 case VIDIOC_PREPARE_BUF32:
1026 case VIDIOC_ENUM_DV_TIMINGS:
1027 case VIDIOC_QUERY_DV_TIMINGS:
1028 case VIDIOC_DV_TIMINGS_CAP:
1026 ret = do_video_ioctl(file, cmd, arg); 1029 ret = do_video_ioctl(file, cmd, arg);
1027 break; 1030 break;
1028 1031
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 18015c0a8d31..9abd9abd4502 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -230,6 +230,19 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
230 "Aperture Priority Mode", 230 "Aperture Priority Mode",
231 NULL 231 NULL
232 }; 232 };
233 static const char * const camera_exposure_metering[] = {
234 "Average",
235 "Center Weighted",
236 "Spot",
237 NULL
238 };
239 static const char * const camera_auto_focus_range[] = {
240 "Auto",
241 "Normal",
242 "Macro",
243 "Infinity",
244 NULL
245 };
233 static const char * const colorfx[] = { 246 static const char * const colorfx[] = {
234 "None", 247 "None",
235 "Black & White", 248 "Black & White",
@@ -241,6 +254,47 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
241 "Grass Green", 254 "Grass Green",
242 "Skin Whiten", 255 "Skin Whiten",
243 "Vivid", 256 "Vivid",
257 "Aqua",
258 "Art Freeze",
259 "Silhouette",
260 "Solarization",
261 "Antique",
262 "Set Cb/Cr",
263 NULL
264 };
265 static const char * const auto_n_preset_white_balance[] = {
266 "Manual",
267 "Auto",
268 "Incandescent",
269 "Fluorescent",
270 "Fluorescent H",
271 "Horizon",
272 "Daylight",
273 "Flash",
274 "Cloudy",
275 "Shade",
276 NULL,
277 };
278 static const char * const camera_iso_sensitivity_auto[] = {
279 "Manual",
280 "Auto",
281 NULL
282 };
283 static const char * const scene_mode[] = {
284 "None",
285 "Backlight",
286 "Beach/Snow",
287 "Candle Light",
288 "Dusk/Dawn",
289 "Fall Colors",
290 "Fireworks",
291 "Landscape",
292 "Night",
293 "Party/Indoor",
294 "Portrait",
295 "Sports",
296 "Sunset",
297 "Text",
244 NULL 298 NULL
245 }; 299 };
246 static const char * const tune_preemphasis[] = { 300 static const char * const tune_preemphasis[] = {
@@ -410,8 +464,18 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
410 return camera_power_line_frequency; 464 return camera_power_line_frequency;
411 case V4L2_CID_EXPOSURE_AUTO: 465 case V4L2_CID_EXPOSURE_AUTO:
412 return camera_exposure_auto; 466 return camera_exposure_auto;
467 case V4L2_CID_EXPOSURE_METERING:
468 return camera_exposure_metering;
469 case V4L2_CID_AUTO_FOCUS_RANGE:
470 return camera_auto_focus_range;
413 case V4L2_CID_COLORFX: 471 case V4L2_CID_COLORFX:
414 return colorfx; 472 return colorfx;
473 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
474 return auto_n_preset_white_balance;
475 case V4L2_CID_ISO_SENSITIVITY_AUTO:
476 return camera_iso_sensitivity_auto;
477 case V4L2_CID_SCENE_MODE:
478 return scene_mode;
415 case V4L2_CID_TUNE_PREEMPHASIS: 479 case V4L2_CID_TUNE_PREEMPHASIS:
416 return tune_preemphasis; 480 return tune_preemphasis;
417 case V4L2_CID_FLASH_LED_MODE: 481 case V4L2_CID_FLASH_LED_MODE:
@@ -493,6 +557,7 @@ const char *v4l2_ctrl_get_name(u32 id)
493 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; 557 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers";
494 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; 558 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers";
495 case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; 559 case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
560 case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
496 561
497 /* MPEG controls */ 562 /* MPEG controls */
498 /* Keep the order of the 'case's the same as in videodev2.h! */ 563 /* Keep the order of the 'case's the same as in videodev2.h! */
@@ -590,13 +655,26 @@ const char *v4l2_ctrl_get_name(u32 id)
590 case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute"; 655 case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute";
591 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute"; 656 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute";
592 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative"; 657 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative";
593 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic"; 658 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous";
594 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute"; 659 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute";
595 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative"; 660 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative";
596 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; 661 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
597 case V4L2_CID_PRIVACY: return "Privacy"; 662 case V4L2_CID_PRIVACY: return "Privacy";
598 case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute"; 663 case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute";
599 case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative"; 664 case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative";
665 case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias";
666 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset";
667 case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range";
668 case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization";
669 case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity";
670 case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto";
671 case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode";
672 case V4L2_CID_SCENE_MODE: return "Scene Mode";
673 case V4L2_CID_3A_LOCK: return "3A Lock";
674 case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start";
675 case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop";
676 case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status";
677 case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range";
600 678
601 /* FM Radio Modulator control */ 679 /* FM Radio Modulator control */
602 /* Keep the order of the 'case's the same as in videodev2.h! */ 680 /* Keep the order of the 'case's the same as in videodev2.h! */
@@ -644,6 +722,17 @@ const char *v4l2_ctrl_get_name(u32 id)
644 case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality"; 722 case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality";
645 case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers"; 723 case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers";
646 724
725 /* Image source controls */
726 case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls";
727 case V4L2_CID_VBLANK: return "Vertical Blanking";
728 case V4L2_CID_HBLANK: return "Horizontal Blanking";
729 case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain";
730
731 /* Image processing controls */
732 case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls";
733 case V4L2_CID_LINK_FREQ: return "Link Frequency";
734 case V4L2_CID_PIXEL_RATE: return "Pixel Rate";
735
647 default: 736 default:
648 return NULL; 737 return NULL;
649 } 738 }
@@ -688,6 +777,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
688 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: 777 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
689 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: 778 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
690 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: 779 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
780 case V4L2_CID_WIDE_DYNAMIC_RANGE:
781 case V4L2_CID_IMAGE_STABILIZATION:
691 *type = V4L2_CTRL_TYPE_BOOLEAN; 782 *type = V4L2_CTRL_TYPE_BOOLEAN;
692 *min = 0; 783 *min = 0;
693 *max = *step = 1; 784 *max = *step = 1;
@@ -696,6 +787,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
696 case V4L2_CID_TILT_RESET: 787 case V4L2_CID_TILT_RESET:
697 case V4L2_CID_FLASH_STROBE: 788 case V4L2_CID_FLASH_STROBE:
698 case V4L2_CID_FLASH_STROBE_STOP: 789 case V4L2_CID_FLASH_STROBE_STOP:
790 case V4L2_CID_AUTO_FOCUS_START:
791 case V4L2_CID_AUTO_FOCUS_STOP:
699 *type = V4L2_CTRL_TYPE_BUTTON; 792 *type = V4L2_CTRL_TYPE_BUTTON;
700 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY; 793 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
701 *min = *max = *step = *def = 0; 794 *min = *max = *step = *def = 0;
@@ -719,7 +812,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
719 case V4L2_CID_MPEG_STREAM_TYPE: 812 case V4L2_CID_MPEG_STREAM_TYPE:
720 case V4L2_CID_MPEG_STREAM_VBI_FMT: 813 case V4L2_CID_MPEG_STREAM_VBI_FMT:
721 case V4L2_CID_EXPOSURE_AUTO: 814 case V4L2_CID_EXPOSURE_AUTO:
815 case V4L2_CID_AUTO_FOCUS_RANGE:
722 case V4L2_CID_COLORFX: 816 case V4L2_CID_COLORFX:
817 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
723 case V4L2_CID_TUNE_PREEMPHASIS: 818 case V4L2_CID_TUNE_PREEMPHASIS:
724 case V4L2_CID_FLASH_LED_MODE: 819 case V4L2_CID_FLASH_LED_MODE:
725 case V4L2_CID_FLASH_STROBE_SOURCE: 820 case V4L2_CID_FLASH_STROBE_SOURCE:
@@ -733,18 +828,30 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
733 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 828 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
734 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 829 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
735 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: 830 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
831 case V4L2_CID_ISO_SENSITIVITY_AUTO:
832 case V4L2_CID_EXPOSURE_METERING:
833 case V4L2_CID_SCENE_MODE:
736 *type = V4L2_CTRL_TYPE_MENU; 834 *type = V4L2_CTRL_TYPE_MENU;
737 break; 835 break;
836 case V4L2_CID_LINK_FREQ:
837 *type = V4L2_CTRL_TYPE_INTEGER_MENU;
838 break;
738 case V4L2_CID_RDS_TX_PS_NAME: 839 case V4L2_CID_RDS_TX_PS_NAME:
739 case V4L2_CID_RDS_TX_RADIO_TEXT: 840 case V4L2_CID_RDS_TX_RADIO_TEXT:
740 *type = V4L2_CTRL_TYPE_STRING; 841 *type = V4L2_CTRL_TYPE_STRING;
741 break; 842 break;
843 case V4L2_CID_ISO_SENSITIVITY:
844 case V4L2_CID_AUTO_EXPOSURE_BIAS:
845 *type = V4L2_CTRL_TYPE_INTEGER_MENU;
846 break;
742 case V4L2_CID_USER_CLASS: 847 case V4L2_CID_USER_CLASS:
743 case V4L2_CID_CAMERA_CLASS: 848 case V4L2_CID_CAMERA_CLASS:
744 case V4L2_CID_MPEG_CLASS: 849 case V4L2_CID_MPEG_CLASS:
745 case V4L2_CID_FM_TX_CLASS: 850 case V4L2_CID_FM_TX_CLASS:
746 case V4L2_CID_FLASH_CLASS: 851 case V4L2_CID_FLASH_CLASS:
747 case V4L2_CID_JPEG_CLASS: 852 case V4L2_CID_JPEG_CLASS:
853 case V4L2_CID_IMAGE_SOURCE_CLASS:
854 case V4L2_CID_IMAGE_PROC_CLASS:
748 *type = V4L2_CTRL_TYPE_CTRL_CLASS; 855 *type = V4L2_CTRL_TYPE_CTRL_CLASS;
749 /* You can neither read not write these */ 856 /* You can neither read not write these */
750 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; 857 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -759,6 +866,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
759 break; 866 break;
760 case V4L2_CID_FLASH_FAULT: 867 case V4L2_CID_FLASH_FAULT:
761 case V4L2_CID_JPEG_ACTIVE_MARKER: 868 case V4L2_CID_JPEG_ACTIVE_MARKER:
869 case V4L2_CID_3A_LOCK:
870 case V4L2_CID_AUTO_FOCUS_STATUS:
762 *type = V4L2_CTRL_TYPE_BITMASK; 871 *type = V4L2_CTRL_TYPE_BITMASK;
763 break; 872 break;
764 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 873 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
@@ -768,8 +877,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
768 break; 877 break;
769 case V4L2_CID_MPEG_VIDEO_DEC_FRAME: 878 case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
770 case V4L2_CID_MPEG_VIDEO_DEC_PTS: 879 case V4L2_CID_MPEG_VIDEO_DEC_PTS:
880 *flags |= V4L2_CTRL_FLAG_VOLATILE;
881 /* Fall through */
882 case V4L2_CID_PIXEL_RATE:
771 *type = V4L2_CTRL_TYPE_INTEGER64; 883 *type = V4L2_CTRL_TYPE_INTEGER64;
772 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE; 884 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
885 *min = *max = *step = *def = 0;
773 break; 886 break;
774 default: 887 default:
775 *type = V4L2_CTRL_TYPE_INTEGER; 888 *type = V4L2_CTRL_TYPE_INTEGER;
@@ -817,6 +930,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
817 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY; 930 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
818 break; 931 break;
819 case V4L2_CID_FLASH_STROBE_STATUS: 932 case V4L2_CID_FLASH_STROBE_STATUS:
933 case V4L2_CID_AUTO_FOCUS_STATUS:
820 case V4L2_CID_FLASH_READY: 934 case V4L2_CID_FLASH_READY:
821 *flags |= V4L2_CTRL_FLAG_READ_ONLY; 935 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
822 break; 936 break;
@@ -852,7 +966,8 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change
852 ev->u.ctrl.value64 = ctrl->cur.val64; 966 ev->u.ctrl.value64 = ctrl->cur.val64;
853 ev->u.ctrl.minimum = ctrl->minimum; 967 ev->u.ctrl.minimum = ctrl->minimum;
854 ev->u.ctrl.maximum = ctrl->maximum; 968 ev->u.ctrl.maximum = ctrl->maximum;
855 if (ctrl->type == V4L2_CTRL_TYPE_MENU) 969 if (ctrl->type == V4L2_CTRL_TYPE_MENU
970 || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
856 ev->u.ctrl.step = 1; 971 ev->u.ctrl.step = 1;
857 else 972 else
858 ev->u.ctrl.step = ctrl->step; 973 ev->u.ctrl.step = ctrl->step;
@@ -1083,10 +1198,13 @@ static int validate_new_int(const struct v4l2_ctrl *ctrl, s32 *pval)
1083 return 0; 1198 return 0;
1084 1199
1085 case V4L2_CTRL_TYPE_MENU: 1200 case V4L2_CTRL_TYPE_MENU:
1201 case V4L2_CTRL_TYPE_INTEGER_MENU:
1086 if (val < ctrl->minimum || val > ctrl->maximum) 1202 if (val < ctrl->minimum || val > ctrl->maximum)
1087 return -ERANGE; 1203 return -ERANGE;
1088 if (ctrl->qmenu[val][0] == '\0' || 1204 if (ctrl->menu_skip_mask & (1 << val))
1089 (ctrl->menu_skip_mask & (1 << val))) 1205 return -EINVAL;
1206 if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
1207 ctrl->qmenu[val][0] == '\0')
1090 return -EINVAL; 1208 return -EINVAL;
1091 return 0; 1209 return 0;
1092 1210
@@ -1114,6 +1232,7 @@ static int validate_new(const struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c
1114 case V4L2_CTRL_TYPE_INTEGER: 1232 case V4L2_CTRL_TYPE_INTEGER:
1115 case V4L2_CTRL_TYPE_BOOLEAN: 1233 case V4L2_CTRL_TYPE_BOOLEAN:
1116 case V4L2_CTRL_TYPE_MENU: 1234 case V4L2_CTRL_TYPE_MENU:
1235 case V4L2_CTRL_TYPE_INTEGER_MENU:
1117 case V4L2_CTRL_TYPE_BITMASK: 1236 case V4L2_CTRL_TYPE_BITMASK:
1118 case V4L2_CTRL_TYPE_BUTTON: 1237 case V4L2_CTRL_TYPE_BUTTON:
1119 case V4L2_CTRL_TYPE_CTRL_CLASS: 1238 case V4L2_CTRL_TYPE_CTRL_CLASS:
@@ -1152,7 +1271,8 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
1152int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, 1271int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
1153 unsigned nr_of_controls_hint) 1272 unsigned nr_of_controls_hint)
1154{ 1273{
1155 mutex_init(&hdl->lock); 1274 hdl->lock = &hdl->_lock;
1275 mutex_init(hdl->lock);
1156 INIT_LIST_HEAD(&hdl->ctrls); 1276 INIT_LIST_HEAD(&hdl->ctrls);
1157 INIT_LIST_HEAD(&hdl->ctrl_refs); 1277 INIT_LIST_HEAD(&hdl->ctrl_refs);
1158 hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; 1278 hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
@@ -1173,7 +1293,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1173 if (hdl == NULL || hdl->buckets == NULL) 1293 if (hdl == NULL || hdl->buckets == NULL)
1174 return; 1294 return;
1175 1295
1176 mutex_lock(&hdl->lock); 1296 mutex_lock(hdl->lock);
1177 /* Free all nodes */ 1297 /* Free all nodes */
1178 list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { 1298 list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
1179 list_del(&ref->node); 1299 list_del(&ref->node);
@@ -1190,7 +1310,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1190 hdl->buckets = NULL; 1310 hdl->buckets = NULL;
1191 hdl->cached = NULL; 1311 hdl->cached = NULL;
1192 hdl->error = 0; 1312 hdl->error = 0;
1193 mutex_unlock(&hdl->lock); 1313 mutex_unlock(hdl->lock);
1194} 1314}
1195EXPORT_SYMBOL(v4l2_ctrl_handler_free); 1315EXPORT_SYMBOL(v4l2_ctrl_handler_free);
1196 1316
@@ -1255,9 +1375,9 @@ static struct v4l2_ctrl_ref *find_ref_lock(
1255 struct v4l2_ctrl_ref *ref = NULL; 1375 struct v4l2_ctrl_ref *ref = NULL;
1256 1376
1257 if (hdl) { 1377 if (hdl) {
1258 mutex_lock(&hdl->lock); 1378 mutex_lock(hdl->lock);
1259 ref = find_ref(hdl, id); 1379 ref = find_ref(hdl, id);
1260 mutex_unlock(&hdl->lock); 1380 mutex_unlock(hdl->lock);
1261 } 1381 }
1262 return ref; 1382 return ref;
1263} 1383}
@@ -1304,7 +1424,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
1304 1424
1305 INIT_LIST_HEAD(&new_ref->node); 1425 INIT_LIST_HEAD(&new_ref->node);
1306 1426
1307 mutex_lock(&hdl->lock); 1427 mutex_lock(hdl->lock);
1308 1428
1309 /* Add immediately at the end of the list if the list is empty, or if 1429 /* Add immediately at the end of the list if the list is empty, or if
1310 the last element in the list has a lower ID. 1430 the last element in the list has a lower ID.
@@ -1334,7 +1454,7 @@ insert_in_hash:
1334 hdl->buckets[bucket] = new_ref; 1454 hdl->buckets[bucket] = new_ref;
1335 1455
1336unlock: 1456unlock:
1337 mutex_unlock(&hdl->lock); 1457 mutex_unlock(hdl->lock);
1338 return 0; 1458 return 0;
1339} 1459}
1340 1460
@@ -1343,7 +1463,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1343 const struct v4l2_ctrl_ops *ops, 1463 const struct v4l2_ctrl_ops *ops,
1344 u32 id, const char *name, enum v4l2_ctrl_type type, 1464 u32 id, const char *name, enum v4l2_ctrl_type type,
1345 s32 min, s32 max, u32 step, s32 def, 1465 s32 min, s32 max, u32 step, s32 def,
1346 u32 flags, const char * const *qmenu, void *priv) 1466 u32 flags, const char * const *qmenu,
1467 const s64 *qmenu_int, void *priv)
1347{ 1468{
1348 struct v4l2_ctrl *ctrl; 1469 struct v4l2_ctrl *ctrl;
1349 unsigned sz_extra = 0; 1470 unsigned sz_extra = 0;
@@ -1356,6 +1477,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1356 (type == V4L2_CTRL_TYPE_INTEGER && step == 0) || 1477 (type == V4L2_CTRL_TYPE_INTEGER && step == 0) ||
1357 (type == V4L2_CTRL_TYPE_BITMASK && max == 0) || 1478 (type == V4L2_CTRL_TYPE_BITMASK && max == 0) ||
1358 (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || 1479 (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
1480 (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL) ||
1359 (type == V4L2_CTRL_TYPE_STRING && max == 0)) { 1481 (type == V4L2_CTRL_TYPE_STRING && max == 0)) {
1360 handler_set_err(hdl, -ERANGE); 1482 handler_set_err(hdl, -ERANGE);
1361 return NULL; 1483 return NULL;
@@ -1366,6 +1488,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1366 } 1488 }
1367 if ((type == V4L2_CTRL_TYPE_INTEGER || 1489 if ((type == V4L2_CTRL_TYPE_INTEGER ||
1368 type == V4L2_CTRL_TYPE_MENU || 1490 type == V4L2_CTRL_TYPE_MENU ||
1491 type == V4L2_CTRL_TYPE_INTEGER_MENU ||
1369 type == V4L2_CTRL_TYPE_BOOLEAN) && 1492 type == V4L2_CTRL_TYPE_BOOLEAN) &&
1370 (def < min || def > max)) { 1493 (def < min || def > max)) {
1371 handler_set_err(hdl, -ERANGE); 1494 handler_set_err(hdl, -ERANGE);
@@ -1400,7 +1523,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1400 ctrl->minimum = min; 1523 ctrl->minimum = min;
1401 ctrl->maximum = max; 1524 ctrl->maximum = max;
1402 ctrl->step = step; 1525 ctrl->step = step;
1403 ctrl->qmenu = qmenu; 1526 if (type == V4L2_CTRL_TYPE_MENU)
1527 ctrl->qmenu = qmenu;
1528 else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
1529 ctrl->qmenu_int = qmenu_int;
1404 ctrl->priv = priv; 1530 ctrl->priv = priv;
1405 ctrl->cur.val = ctrl->val = ctrl->default_value = def; 1531 ctrl->cur.val = ctrl->val = ctrl->default_value = def;
1406 1532
@@ -1414,9 +1540,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1414 kfree(ctrl); 1540 kfree(ctrl);
1415 return NULL; 1541 return NULL;
1416 } 1542 }
1417 mutex_lock(&hdl->lock); 1543 mutex_lock(hdl->lock);
1418 list_add_tail(&ctrl->node, &hdl->ctrls); 1544 list_add_tail(&ctrl->node, &hdl->ctrls);
1419 mutex_unlock(&hdl->lock); 1545 mutex_unlock(hdl->lock);
1420 return ctrl; 1546 return ctrl;
1421} 1547}
1422 1548
@@ -1427,6 +1553,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
1427 struct v4l2_ctrl *ctrl; 1553 struct v4l2_ctrl *ctrl;
1428 const char *name = cfg->name; 1554 const char *name = cfg->name;
1429 const char * const *qmenu = cfg->qmenu; 1555 const char * const *qmenu = cfg->qmenu;
1556 const s64 *qmenu_int = cfg->qmenu_int;
1430 enum v4l2_ctrl_type type = cfg->type; 1557 enum v4l2_ctrl_type type = cfg->type;
1431 u32 flags = cfg->flags; 1558 u32 flags = cfg->flags;
1432 s32 min = cfg->min; 1559 s32 min = cfg->min;
@@ -1438,18 +1565,24 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
1438 v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step, 1565 v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
1439 &def, &flags); 1566 &def, &flags);
1440 1567
1441 is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU); 1568 is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU ||
1569 cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU);
1442 if (is_menu) 1570 if (is_menu)
1443 WARN_ON(step); 1571 WARN_ON(step);
1444 else 1572 else
1445 WARN_ON(cfg->menu_skip_mask); 1573 WARN_ON(cfg->menu_skip_mask);
1446 if (is_menu && qmenu == NULL) 1574 if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL)
1447 qmenu = v4l2_ctrl_get_menu(cfg->id); 1575 qmenu = v4l2_ctrl_get_menu(cfg->id);
1576 else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU &&
1577 qmenu_int == NULL) {
1578 handler_set_err(hdl, -EINVAL);
1579 return NULL;
1580 }
1448 1581
1449 ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->id, name, 1582 ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->id, name,
1450 type, min, max, 1583 type, min, max,
1451 is_menu ? cfg->menu_skip_mask : step, 1584 is_menu ? cfg->menu_skip_mask : step,
1452 def, flags, qmenu, priv); 1585 def, flags, qmenu, qmenu_int, priv);
1453 if (ctrl) 1586 if (ctrl)
1454 ctrl->is_private = cfg->is_private; 1587 ctrl->is_private = cfg->is_private;
1455 return ctrl; 1588 return ctrl;
@@ -1466,12 +1599,13 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
1466 u32 flags; 1599 u32 flags;
1467 1600
1468 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); 1601 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
1469 if (type == V4L2_CTRL_TYPE_MENU) { 1602 if (type == V4L2_CTRL_TYPE_MENU
1603 || type == V4L2_CTRL_TYPE_INTEGER_MENU) {
1470 handler_set_err(hdl, -EINVAL); 1604 handler_set_err(hdl, -EINVAL);
1471 return NULL; 1605 return NULL;
1472 } 1606 }
1473 return v4l2_ctrl_new(hdl, ops, id, name, type, 1607 return v4l2_ctrl_new(hdl, ops, id, name, type,
1474 min, max, step, def, flags, NULL, NULL); 1608 min, max, step, def, flags, NULL, NULL, NULL);
1475} 1609}
1476EXPORT_SYMBOL(v4l2_ctrl_new_std); 1610EXPORT_SYMBOL(v4l2_ctrl_new_std);
1477 1611
@@ -1493,10 +1627,31 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
1493 return NULL; 1627 return NULL;
1494 } 1628 }
1495 return v4l2_ctrl_new(hdl, ops, id, name, type, 1629 return v4l2_ctrl_new(hdl, ops, id, name, type,
1496 0, max, mask, def, flags, qmenu, NULL); 1630 0, max, mask, def, flags, qmenu, NULL, NULL);
1497} 1631}
1498EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); 1632EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
1499 1633
1634/* Helper function for standard integer menu controls */
1635struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
1636 const struct v4l2_ctrl_ops *ops,
1637 u32 id, s32 max, s32 def, const s64 *qmenu_int)
1638{
1639 const char *name;
1640 enum v4l2_ctrl_type type;
1641 s32 min;
1642 s32 step;
1643 u32 flags;
1644
1645 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
1646 if (type != V4L2_CTRL_TYPE_INTEGER_MENU) {
1647 handler_set_err(hdl, -EINVAL);
1648 return NULL;
1649 }
1650 return v4l2_ctrl_new(hdl, ops, id, name, type,
1651 0, max, 0, def, flags, NULL, qmenu_int, NULL);
1652}
1653EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
1654
1500/* Add a control from another handler to this handler */ 1655/* Add a control from another handler to this handler */
1501struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl, 1656struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
1502 struct v4l2_ctrl *ctrl) 1657 struct v4l2_ctrl *ctrl)
@@ -1525,7 +1680,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
1525 return 0; 1680 return 0;
1526 if (hdl->error) 1681 if (hdl->error)
1527 return hdl->error; 1682 return hdl->error;
1528 mutex_lock(&add->lock); 1683 mutex_lock(add->lock);
1529 list_for_each_entry(ref, &add->ctrl_refs, node) { 1684 list_for_each_entry(ref, &add->ctrl_refs, node) {
1530 struct v4l2_ctrl *ctrl = ref->ctrl; 1685 struct v4l2_ctrl *ctrl = ref->ctrl;
1531 1686
@@ -1539,7 +1694,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
1539 if (ret) 1694 if (ret)
1540 break; 1695 break;
1541 } 1696 }
1542 mutex_unlock(&add->lock); 1697 mutex_unlock(add->lock);
1543 return ret; 1698 return ret;
1544} 1699}
1545EXPORT_SYMBOL(v4l2_ctrl_add_handler); 1700EXPORT_SYMBOL(v4l2_ctrl_add_handler);
@@ -1659,6 +1814,9 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
1659 case V4L2_CTRL_TYPE_MENU: 1814 case V4L2_CTRL_TYPE_MENU:
1660 printk(KERN_CONT "%s", ctrl->qmenu[ctrl->cur.val]); 1815 printk(KERN_CONT "%s", ctrl->qmenu[ctrl->cur.val]);
1661 break; 1816 break;
1817 case V4L2_CTRL_TYPE_INTEGER_MENU:
1818 printk(KERN_CONT "%lld", ctrl->qmenu_int[ctrl->cur.val]);
1819 break;
1662 case V4L2_CTRL_TYPE_BITMASK: 1820 case V4L2_CTRL_TYPE_BITMASK:
1663 printk(KERN_CONT "0x%08x", ctrl->cur.val); 1821 printk(KERN_CONT "0x%08x", ctrl->cur.val);
1664 break; 1822 break;
@@ -1700,11 +1858,11 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
1700 len = strlen(prefix); 1858 len = strlen(prefix);
1701 if (len && prefix[len - 1] != ' ') 1859 if (len && prefix[len - 1] != ' ')
1702 colon = ": "; 1860 colon = ": ";
1703 mutex_lock(&hdl->lock); 1861 mutex_lock(hdl->lock);
1704 list_for_each_entry(ctrl, &hdl->ctrls, node) 1862 list_for_each_entry(ctrl, &hdl->ctrls, node)
1705 if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) 1863 if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
1706 log_ctrl(ctrl, prefix, colon); 1864 log_ctrl(ctrl, prefix, colon);
1707 mutex_unlock(&hdl->lock); 1865 mutex_unlock(hdl->lock);
1708} 1866}
1709EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); 1867EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
1710 1868
@@ -1716,7 +1874,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
1716 1874
1717 if (hdl == NULL) 1875 if (hdl == NULL)
1718 return 0; 1876 return 0;
1719 mutex_lock(&hdl->lock); 1877 mutex_lock(hdl->lock);
1720 list_for_each_entry(ctrl, &hdl->ctrls, node) 1878 list_for_each_entry(ctrl, &hdl->ctrls, node)
1721 ctrl->done = false; 1879 ctrl->done = false;
1722 1880
@@ -1741,7 +1899,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
1741 if (ret) 1899 if (ret)
1742 break; 1900 break;
1743 } 1901 }
1744 mutex_unlock(&hdl->lock); 1902 mutex_unlock(hdl->lock);
1745 return ret; 1903 return ret;
1746} 1904}
1747EXPORT_SYMBOL(v4l2_ctrl_handler_setup); 1905EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
@@ -1756,7 +1914,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
1756 if (hdl == NULL) 1914 if (hdl == NULL)
1757 return -EINVAL; 1915 return -EINVAL;
1758 1916
1759 mutex_lock(&hdl->lock); 1917 mutex_lock(hdl->lock);
1760 1918
1761 /* Try to find it */ 1919 /* Try to find it */
1762 ref = find_ref(hdl, id); 1920 ref = find_ref(hdl, id);
@@ -1781,7 +1939,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
1781 break; 1939 break;
1782 } 1940 }
1783 } 1941 }
1784 mutex_unlock(&hdl->lock); 1942 mutex_unlock(hdl->lock);
1785 if (!ref) 1943 if (!ref)
1786 return -EINVAL; 1944 return -EINVAL;
1787 1945
@@ -1795,7 +1953,8 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
1795 qc->minimum = ctrl->minimum; 1953 qc->minimum = ctrl->minimum;
1796 qc->maximum = ctrl->maximum; 1954 qc->maximum = ctrl->maximum;
1797 qc->default_value = ctrl->default_value; 1955 qc->default_value = ctrl->default_value;
1798 if (ctrl->type == V4L2_CTRL_TYPE_MENU) 1956 if (ctrl->type == V4L2_CTRL_TYPE_MENU
1957 || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
1799 qc->step = 1; 1958 qc->step = 1;
1800 else 1959 else
1801 qc->step = ctrl->step; 1960 qc->step = ctrl->step;
@@ -1825,16 +1984,33 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
1825 1984
1826 qm->reserved = 0; 1985 qm->reserved = 0;
1827 /* Sanity checks */ 1986 /* Sanity checks */
1828 if (ctrl->qmenu == NULL || 1987 switch (ctrl->type) {
1829 i < ctrl->minimum || i > ctrl->maximum) 1988 case V4L2_CTRL_TYPE_MENU:
1989 if (ctrl->qmenu == NULL)
1990 return -EINVAL;
1991 break;
1992 case V4L2_CTRL_TYPE_INTEGER_MENU:
1993 if (ctrl->qmenu_int == NULL)
1994 return -EINVAL;
1995 break;
1996 default:
1830 return -EINVAL; 1997 return -EINVAL;
1998 }
1999
2000 if (i < ctrl->minimum || i > ctrl->maximum)
2001 return -EINVAL;
2002
1831 /* Use mask to see if this menu item should be skipped */ 2003 /* Use mask to see if this menu item should be skipped */
1832 if (ctrl->menu_skip_mask & (1 << i)) 2004 if (ctrl->menu_skip_mask & (1 << i))
1833 return -EINVAL; 2005 return -EINVAL;
1834 /* Empty menu items should also be skipped */ 2006 /* Empty menu items should also be skipped */
1835 if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0') 2007 if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
1836 return -EINVAL; 2008 if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
1837 strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name)); 2009 return -EINVAL;
2010 strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
2011 } else {
2012 qm->value = ctrl->qmenu_int[i];
2013 }
1838 return 0; 2014 return 0;
1839} 2015}
1840EXPORT_SYMBOL(v4l2_querymenu); 2016EXPORT_SYMBOL(v4l2_querymenu);
@@ -1940,7 +2116,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
1940 belong to the same cluster. */ 2116 belong to the same cluster. */
1941 2117
1942 /* This has to be done with the handler lock taken. */ 2118 /* This has to be done with the handler lock taken. */
1943 mutex_lock(&hdl->lock); 2119 mutex_lock(hdl->lock);
1944 2120
1945 /* First zero the helper field in the master control references */ 2121 /* First zero the helper field in the master control references */
1946 for (i = 0; i < cs->count; i++) 2122 for (i = 0; i < cs->count; i++)
@@ -1962,7 +2138,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
1962 /* Point the mref helper to the current helper struct. */ 2138 /* Point the mref helper to the current helper struct. */
1963 mref->helper = h; 2139 mref->helper = h;
1964 } 2140 }
1965 mutex_unlock(&hdl->lock); 2141 mutex_unlock(hdl->lock);
1966 return 0; 2142 return 0;
1967} 2143}
1968 2144
@@ -1996,7 +2172,8 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
1996 return class_check(hdl, cs->ctrl_class); 2172 return class_check(hdl, cs->ctrl_class);
1997 2173
1998 if (cs->count > ARRAY_SIZE(helper)) { 2174 if (cs->count > ARRAY_SIZE(helper)) {
1999 helpers = kmalloc(sizeof(helper[0]) * cs->count, GFP_KERNEL); 2175 helpers = kmalloc_array(cs->count, sizeof(helper[0]),
2176 GFP_KERNEL);
2000 if (helpers == NULL) 2177 if (helpers == NULL)
2001 return -ENOMEM; 2178 return -ENOMEM;
2002 } 2179 }
@@ -2218,7 +2395,8 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
2218 return class_check(hdl, cs->ctrl_class); 2395 return class_check(hdl, cs->ctrl_class);
2219 2396
2220 if (cs->count > ARRAY_SIZE(helper)) { 2397 if (cs->count > ARRAY_SIZE(helper)) {
2221 helpers = kmalloc(sizeof(helper[0]) * cs->count, GFP_KERNEL); 2398 helpers = kmalloc_array(cs->count, sizeof(helper[0]),
2399 GFP_KERNEL);
2222 if (!helpers) 2400 if (!helpers)
2223 return -ENOMEM; 2401 return -ENOMEM;
2224 } 2402 }
@@ -2381,9 +2559,13 @@ int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
2381} 2559}
2382EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); 2560EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);
2383 2561
2384void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl, 2562static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
2385 struct v4l2_subscribed_event *sev)
2386{ 2563{
2564 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
2565
2566 if (ctrl == NULL)
2567 return -EINVAL;
2568
2387 v4l2_ctrl_lock(ctrl); 2569 v4l2_ctrl_lock(ctrl);
2388 list_add_tail(&sev->node, &ctrl->ev_subs); 2570 list_add_tail(&sev->node, &ctrl->ev_subs);
2389 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && 2571 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
@@ -2394,20 +2576,46 @@ void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl,
2394 if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)) 2576 if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY))
2395 changes |= V4L2_EVENT_CTRL_CH_VALUE; 2577 changes |= V4L2_EVENT_CTRL_CH_VALUE;
2396 fill_event(&ev, ctrl, changes); 2578 fill_event(&ev, ctrl, changes);
2579 /* Mark the queue as active, allowing this initial
2580 event to be accepted. */
2581 sev->elems = elems;
2397 v4l2_event_queue_fh(sev->fh, &ev); 2582 v4l2_event_queue_fh(sev->fh, &ev);
2398 } 2583 }
2399 v4l2_ctrl_unlock(ctrl); 2584 v4l2_ctrl_unlock(ctrl);
2585 return 0;
2400} 2586}
2401EXPORT_SYMBOL(v4l2_ctrl_add_event);
2402 2587
2403void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, 2588static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
2404 struct v4l2_subscribed_event *sev)
2405{ 2589{
2590 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
2591
2406 v4l2_ctrl_lock(ctrl); 2592 v4l2_ctrl_lock(ctrl);
2407 list_del(&sev->node); 2593 list_del(&sev->node);
2408 v4l2_ctrl_unlock(ctrl); 2594 v4l2_ctrl_unlock(ctrl);
2409} 2595}
2410EXPORT_SYMBOL(v4l2_ctrl_del_event); 2596
2597void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
2598{
2599 u32 old_changes = old->u.ctrl.changes;
2600
2601 old->u.ctrl = new->u.ctrl;
2602 old->u.ctrl.changes |= old_changes;
2603}
2604EXPORT_SYMBOL(v4l2_ctrl_replace);
2605
2606void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
2607{
2608 new->u.ctrl.changes |= old->u.ctrl.changes;
2609}
2610EXPORT_SYMBOL(v4l2_ctrl_merge);
2611
2612const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
2613 .add = v4l2_ctrl_add_event,
2614 .del = v4l2_ctrl_del_event,
2615 .replace = v4l2_ctrl_replace,
2616 .merge = v4l2_ctrl_merge,
2617};
2618EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);
2411 2619
2412int v4l2_ctrl_log_status(struct file *file, void *fh) 2620int v4l2_ctrl_log_status(struct file *file, void *fh)
2413{ 2621{
@@ -2425,7 +2633,7 @@ int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
2425 struct v4l2_event_subscription *sub) 2633 struct v4l2_event_subscription *sub)
2426{ 2634{
2427 if (sub->type == V4L2_EVENT_CTRL) 2635 if (sub->type == V4L2_EVENT_CTRL)
2428 return v4l2_event_subscribe(fh, sub, 0); 2636 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
2429 return -EINVAL; 2637 return -EINVAL;
2430} 2638}
2431EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); 2639EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 70bec548d904..5ccbd4629f9c 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -274,11 +274,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
274 274
275 if (!vdev->fops->read) 275 if (!vdev->fops->read)
276 return -EINVAL; 276 return -EINVAL;
277 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) 277 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
278 mutex_lock_interruptible(vdev->lock))
278 return -ERESTARTSYS; 279 return -ERESTARTSYS;
279 if (video_is_registered(vdev)) 280 if (video_is_registered(vdev))
280 ret = vdev->fops->read(filp, buf, sz, off); 281 ret = vdev->fops->read(filp, buf, sz, off);
281 if (vdev->lock) 282 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
282 mutex_unlock(vdev->lock); 283 mutex_unlock(vdev->lock);
283 return ret; 284 return ret;
284} 285}
@@ -291,11 +292,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
291 292
292 if (!vdev->fops->write) 293 if (!vdev->fops->write)
293 return -EINVAL; 294 return -EINVAL;
294 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) 295 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
296 mutex_lock_interruptible(vdev->lock))
295 return -ERESTARTSYS; 297 return -ERESTARTSYS;
296 if (video_is_registered(vdev)) 298 if (video_is_registered(vdev))
297 ret = vdev->fops->write(filp, buf, sz, off); 299 ret = vdev->fops->write(filp, buf, sz, off);
298 if (vdev->lock) 300 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
299 mutex_unlock(vdev->lock); 301 mutex_unlock(vdev->lock);
300 return ret; 302 return ret;
301} 303}
@@ -307,11 +309,11 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
307 309
308 if (!vdev->fops->poll) 310 if (!vdev->fops->poll)
309 return DEFAULT_POLLMASK; 311 return DEFAULT_POLLMASK;
310 if (vdev->lock) 312 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
311 mutex_lock(vdev->lock); 313 mutex_lock(vdev->lock);
312 if (video_is_registered(vdev)) 314 if (video_is_registered(vdev))
313 ret = vdev->fops->poll(filp, poll); 315 ret = vdev->fops->poll(filp, poll);
314 if (vdev->lock) 316 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
315 mutex_unlock(vdev->lock); 317 mutex_unlock(vdev->lock);
316 return ret; 318 return ret;
317} 319}
@@ -322,11 +324,19 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
322 int ret = -ENODEV; 324 int ret = -ENODEV;
323 325
324 if (vdev->fops->unlocked_ioctl) { 326 if (vdev->fops->unlocked_ioctl) {
325 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) 327 bool locked = false;
326 return -ERESTARTSYS; 328
329 if (vdev->lock) {
330 /* always lock unless the cmd is marked as "don't use lock" */
331 locked = !v4l2_is_known_ioctl(cmd) ||
332 !test_bit(_IOC_NR(cmd), vdev->disable_locking);
333
334 if (locked && mutex_lock_interruptible(vdev->lock))
335 return -ERESTARTSYS;
336 }
327 if (video_is_registered(vdev)) 337 if (video_is_registered(vdev))
328 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); 338 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
329 if (vdev->lock) 339 if (locked)
330 mutex_unlock(vdev->lock); 340 mutex_unlock(vdev->lock);
331 } else if (vdev->fops->ioctl) { 341 } else if (vdev->fops->ioctl) {
332 /* This code path is a replacement for the BKL. It is a major 342 /* This code path is a replacement for the BKL. It is a major
@@ -391,11 +401,12 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
391 401
392 if (!vdev->fops->mmap) 402 if (!vdev->fops->mmap)
393 return ret; 403 return ret;
394 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) 404 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
405 mutex_lock_interruptible(vdev->lock))
395 return -ERESTARTSYS; 406 return -ERESTARTSYS;
396 if (video_is_registered(vdev)) 407 if (video_is_registered(vdev))
397 ret = vdev->fops->mmap(filp, vm); 408 ret = vdev->fops->mmap(filp, vm);
398 if (vdev->lock) 409 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
399 mutex_unlock(vdev->lock); 410 mutex_unlock(vdev->lock);
400 return ret; 411 return ret;
401} 412}
@@ -418,7 +429,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
418 video_get(vdev); 429 video_get(vdev);
419 mutex_unlock(&videodev_lock); 430 mutex_unlock(&videodev_lock);
420 if (vdev->fops->open) { 431 if (vdev->fops->open) {
421 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { 432 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
433 mutex_lock_interruptible(vdev->lock)) {
422 ret = -ERESTARTSYS; 434 ret = -ERESTARTSYS;
423 goto err; 435 goto err;
424 } 436 }
@@ -426,7 +438,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
426 ret = vdev->fops->open(filp); 438 ret = vdev->fops->open(filp);
427 else 439 else
428 ret = -ENODEV; 440 ret = -ENODEV;
429 if (vdev->lock) 441 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
430 mutex_unlock(vdev->lock); 442 mutex_unlock(vdev->lock);
431 } 443 }
432 444
@@ -444,10 +456,10 @@ static int v4l2_release(struct inode *inode, struct file *filp)
444 int ret = 0; 456 int ret = 0;
445 457
446 if (vdev->fops->release) { 458 if (vdev->fops->release) {
447 if (vdev->lock) 459 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
448 mutex_lock(vdev->lock); 460 mutex_lock(vdev->lock);
449 vdev->fops->release(filp); 461 vdev->fops->release(filp);
450 if (vdev->lock) 462 if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
451 mutex_unlock(vdev->lock); 463 mutex_unlock(vdev->lock);
452 } 464 }
453 /* decrease the refcount unconditionally since the release() 465 /* decrease the refcount unconditionally since the release()
@@ -508,6 +520,175 @@ static int get_index(struct video_device *vdev)
508 return find_first_zero_bit(used, VIDEO_NUM_DEVICES); 520 return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
509} 521}
510 522
523#define SET_VALID_IOCTL(ops, cmd, op) \
524 if (ops->op) \
525 set_bit(_IOC_NR(cmd), valid_ioctls)
526
527/* This determines which ioctls are actually implemented in the driver.
528 It's a one-time thing which simplifies video_ioctl2 as it can just do
529 a bit test.
530
531 Note that drivers can override this by setting bits to 1 in
532 vdev->valid_ioctls. If an ioctl is marked as 1 when this function is
533 called, then that ioctl will actually be marked as unimplemented.
534
535 It does that by first setting up the local valid_ioctls bitmap, and
536 at the end do a:
537
538 vdev->valid_ioctls = valid_ioctls & ~(vdev->valid_ioctls)
539 */
540static void determine_valid_ioctls(struct video_device *vdev)
541{
542 DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
543 const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
544
545 bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
546
547 SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap);
548 if (ops->vidioc_g_priority ||
549 test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
550 set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls);
551 if (ops->vidioc_s_priority ||
552 test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
553 set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls);
554 if (ops->vidioc_enum_fmt_vid_cap ||
555 ops->vidioc_enum_fmt_vid_out ||
556 ops->vidioc_enum_fmt_vid_cap_mplane ||
557 ops->vidioc_enum_fmt_vid_out_mplane ||
558 ops->vidioc_enum_fmt_vid_overlay ||
559 ops->vidioc_enum_fmt_type_private)
560 set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
561 if (ops->vidioc_g_fmt_vid_cap ||
562 ops->vidioc_g_fmt_vid_out ||
563 ops->vidioc_g_fmt_vid_cap_mplane ||
564 ops->vidioc_g_fmt_vid_out_mplane ||
565 ops->vidioc_g_fmt_vid_overlay ||
566 ops->vidioc_g_fmt_vbi_cap ||
567 ops->vidioc_g_fmt_vid_out_overlay ||
568 ops->vidioc_g_fmt_vbi_out ||
569 ops->vidioc_g_fmt_sliced_vbi_cap ||
570 ops->vidioc_g_fmt_sliced_vbi_out ||
571 ops->vidioc_g_fmt_type_private)
572 set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
573 if (ops->vidioc_s_fmt_vid_cap ||
574 ops->vidioc_s_fmt_vid_out ||
575 ops->vidioc_s_fmt_vid_cap_mplane ||
576 ops->vidioc_s_fmt_vid_out_mplane ||
577 ops->vidioc_s_fmt_vid_overlay ||
578 ops->vidioc_s_fmt_vbi_cap ||
579 ops->vidioc_s_fmt_vid_out_overlay ||
580 ops->vidioc_s_fmt_vbi_out ||
581 ops->vidioc_s_fmt_sliced_vbi_cap ||
582 ops->vidioc_s_fmt_sliced_vbi_out ||
583 ops->vidioc_s_fmt_type_private)
584 set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
585 if (ops->vidioc_try_fmt_vid_cap ||
586 ops->vidioc_try_fmt_vid_out ||
587 ops->vidioc_try_fmt_vid_cap_mplane ||
588 ops->vidioc_try_fmt_vid_out_mplane ||
589 ops->vidioc_try_fmt_vid_overlay ||
590 ops->vidioc_try_fmt_vbi_cap ||
591 ops->vidioc_try_fmt_vid_out_overlay ||
592 ops->vidioc_try_fmt_vbi_out ||
593 ops->vidioc_try_fmt_sliced_vbi_cap ||
594 ops->vidioc_try_fmt_sliced_vbi_out ||
595 ops->vidioc_try_fmt_type_private)
596 set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
597 SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
598 SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
599 SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
600 SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
601 SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
602 SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
603 SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf);
604 SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
605 SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
606 if (vdev->tvnorms)
607 set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
608 if (ops->vidioc_g_std || vdev->current_norm)
609 set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
610 SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
611 SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
612 SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
613 SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
614 SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
615 SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
616 SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
617 SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
618 /* Note: the control handler can also be passed through the filehandle,
619 and that can't be tested here. If the bit for these control ioctls
620 is set, then the ioctl is valid. But if it is 0, then it can still
621 be valid if the filehandle passed the control handler. */
622 if (vdev->ctrl_handler || ops->vidioc_queryctrl)
623 set_bit(_IOC_NR(VIDIOC_QUERYCTRL), valid_ioctls);
624 if (vdev->ctrl_handler || ops->vidioc_g_ctrl || ops->vidioc_g_ext_ctrls)
625 set_bit(_IOC_NR(VIDIOC_G_CTRL), valid_ioctls);
626 if (vdev->ctrl_handler || ops->vidioc_s_ctrl || ops->vidioc_s_ext_ctrls)
627 set_bit(_IOC_NR(VIDIOC_S_CTRL), valid_ioctls);
628 if (vdev->ctrl_handler || ops->vidioc_g_ext_ctrls)
629 set_bit(_IOC_NR(VIDIOC_G_EXT_CTRLS), valid_ioctls);
630 if (vdev->ctrl_handler || ops->vidioc_s_ext_ctrls)
631 set_bit(_IOC_NR(VIDIOC_S_EXT_CTRLS), valid_ioctls);
632 if (vdev->ctrl_handler || ops->vidioc_try_ext_ctrls)
633 set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);
634 if (vdev->ctrl_handler || ops->vidioc_querymenu)
635 set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls);
636 SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio);
637 SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
638 SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
639 SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout);
640 SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
641 SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
642 SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
643 SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
644 if (ops->vidioc_g_crop || ops->vidioc_g_selection)
645 set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls);
646 if (ops->vidioc_s_crop || ops->vidioc_s_selection)
647 set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);
648 SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);
649 SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection);
650 if (ops->vidioc_cropcap || ops->vidioc_g_selection)
651 set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
652 SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp);
653 SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp);
654 SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index);
655 SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd);
656 SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd);
657 SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd);
658 SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd);
659 if (ops->vidioc_g_parm || vdev->current_norm)
660 set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
661 SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
662 SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);
663 SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);
664 SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
665 SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
666 SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
667 SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
668#ifdef CONFIG_VIDEO_ADV_DEBUG
669 SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register);
670 SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register);
671#endif
672 SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
673 SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek);
674 SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
675 SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
676 SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets);
677 SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset);
678 SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset);
679 SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset);
680 SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
681 SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings);
682 /* yes, really vidioc_subscribe_event */
683 SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
684 SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
685 SET_VALID_IOCTL(ops, VIDIOC_UNSUBSCRIBE_EVENT, vidioc_unsubscribe_event);
686 SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs);
687 SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
688 bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls,
689 BASE_VIDIOC_PRIVATE);
690}
691
511/** 692/**
512 * __video_register_device - register video4linux devices 693 * __video_register_device - register video4linux devices
513 * @vdev: video device structure we want to register 694 * @vdev: video device structure we want to register
@@ -654,6 +835,13 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
654 WARN_ON(video_device[vdev->minor] != NULL); 835 WARN_ON(video_device[vdev->minor] != NULL);
655 vdev->index = get_index(vdev); 836 vdev->index = get_index(vdev);
656 mutex_unlock(&videodev_lock); 837 mutex_unlock(&videodev_lock);
838 /* if no lock was passed, then make sure the LOCK_ALL_FOPS bit is
839 clear and warn if it wasn't. */
840 if (vdev->lock == NULL)
841 WARN_ON(test_and_clear_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags));
842
843 if (vdev->ioctl_ops)
844 determine_valid_ioctls(vdev);
657 845
658 /* Part 3: Initialize the character device */ 846 /* Part 3: Initialize the character device */
659 vdev->cdev = cdev_alloc(); 847 vdev->cdev = cdev_alloc();
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
index c26ad9637143..ef2a33c94045 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/video/v4l2-event.c
@@ -25,7 +25,6 @@
25#include <media/v4l2-dev.h> 25#include <media/v4l2-dev.h>
26#include <media/v4l2-fh.h> 26#include <media/v4l2-fh.h>
27#include <media/v4l2-event.h> 27#include <media/v4l2-event.h>
28#include <media/v4l2-ctrls.h>
29 28
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
@@ -120,6 +119,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *e
120 if (sev == NULL) 119 if (sev == NULL)
121 return; 120 return;
122 121
122 /*
123 * If the event has been added to the fh->subscribed list, but its
124 * add op has not completed yet elems will be 0, treat this as
125 * not being subscribed.
126 */
127 if (!sev->elems)
128 return;
129
123 /* Increase event sequence number on fh. */ 130 /* Increase event sequence number on fh. */
124 fh->sequence++; 131 fh->sequence++;
125 132
@@ -132,14 +139,14 @@ static void __v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *e
132 sev->first = sev_pos(sev, 1); 139 sev->first = sev_pos(sev, 1);
133 fh->navailable--; 140 fh->navailable--;
134 if (sev->elems == 1) { 141 if (sev->elems == 1) {
135 if (sev->replace) { 142 if (sev->ops && sev->ops->replace) {
136 sev->replace(&kev->event, ev); 143 sev->ops->replace(&kev->event, ev);
137 copy_payload = false; 144 copy_payload = false;
138 } 145 }
139 } else if (sev->merge) { 146 } else if (sev->ops && sev->ops->merge) {
140 struct v4l2_kevent *second_oldest = 147 struct v4l2_kevent *second_oldest =
141 sev->events + sev_pos(sev, 0); 148 sev->events + sev_pos(sev, 0);
142 sev->merge(&kev->event, &second_oldest->event); 149 sev->ops->merge(&kev->event, &second_oldest->event);
143 } 150 }
144 } 151 }
145 152
@@ -195,24 +202,11 @@ int v4l2_event_pending(struct v4l2_fh *fh)
195} 202}
196EXPORT_SYMBOL_GPL(v4l2_event_pending); 203EXPORT_SYMBOL_GPL(v4l2_event_pending);
197 204
198static void ctrls_replace(struct v4l2_event *old, const struct v4l2_event *new)
199{
200 u32 old_changes = old->u.ctrl.changes;
201
202 old->u.ctrl = new->u.ctrl;
203 old->u.ctrl.changes |= old_changes;
204}
205
206static void ctrls_merge(const struct v4l2_event *old, struct v4l2_event *new)
207{
208 new->u.ctrl.changes |= old->u.ctrl.changes;
209}
210
211int v4l2_event_subscribe(struct v4l2_fh *fh, 205int v4l2_event_subscribe(struct v4l2_fh *fh,
212 struct v4l2_event_subscription *sub, unsigned elems) 206 struct v4l2_event_subscription *sub, unsigned elems,
207 const struct v4l2_subscribed_event_ops *ops)
213{ 208{
214 struct v4l2_subscribed_event *sev, *found_ev; 209 struct v4l2_subscribed_event *sev, *found_ev;
215 struct v4l2_ctrl *ctrl = NULL;
216 unsigned long flags; 210 unsigned long flags;
217 unsigned i; 211 unsigned i;
218 212
@@ -221,11 +215,6 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
221 215
222 if (elems < 1) 216 if (elems < 1)
223 elems = 1; 217 elems = 1;
224 if (sub->type == V4L2_EVENT_CTRL) {
225 ctrl = v4l2_ctrl_find(fh->ctrl_handler, sub->id);
226 if (ctrl == NULL)
227 return -EINVAL;
228 }
229 218
230 sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL); 219 sev = kzalloc(sizeof(*sev) + sizeof(struct v4l2_kevent) * elems, GFP_KERNEL);
231 if (!sev) 220 if (!sev)
@@ -236,11 +225,7 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
236 sev->id = sub->id; 225 sev->id = sub->id;
237 sev->flags = sub->flags; 226 sev->flags = sub->flags;
238 sev->fh = fh; 227 sev->fh = fh;
239 sev->elems = elems; 228 sev->ops = ops;
240 if (ctrl) {
241 sev->replace = ctrls_replace;
242 sev->merge = ctrls_merge;
243 }
244 229
245 spin_lock_irqsave(&fh->vdev->fh_lock, flags); 230 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
246 found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); 231 found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
@@ -248,11 +233,22 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
248 list_add(&sev->list, &fh->subscribed); 233 list_add(&sev->list, &fh->subscribed);
249 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 234 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
250 235
251 /* v4l2_ctrl_add_event uses a mutex, so do this outside the spin lock */ 236 if (found_ev) {
252 if (found_ev)
253 kfree(sev); 237 kfree(sev);
254 else if (ctrl) 238 return 0; /* Already listening */
255 v4l2_ctrl_add_event(ctrl, sev); 239 }
240
241 if (sev->ops && sev->ops->add) {
242 int ret = sev->ops->add(sev, elems);
243 if (ret) {
244 sev->ops = NULL;
245 v4l2_event_unsubscribe(fh, sub);
246 return ret;
247 }
248 }
249
250 /* Mark as ready for use */
251 sev->elems = elems;
256 252
257 return 0; 253 return 0;
258} 254}
@@ -306,12 +302,9 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
306 } 302 }
307 303
308 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 304 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
309 if (sev && sev->type == V4L2_EVENT_CTRL) {
310 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(fh->ctrl_handler, sev->id);
311 305
312 if (ctrl) 306 if (sev && sev->ops && sev->ops->del)
313 v4l2_ctrl_del_event(ctrl, sev); 307 sev->ops->del(sev);
314 }
315 308
316 kfree(sev); 309 kfree(sev);
317 310
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 5b2ec1fd2d0a..91be4e871f43 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -55,19 +55,6 @@
55 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ 55 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
56 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) 56 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
57 57
58#define have_fmt_ops(foo) ( \
59 ops->vidioc_##foo##_fmt_vid_cap || \
60 ops->vidioc_##foo##_fmt_vid_out || \
61 ops->vidioc_##foo##_fmt_vid_cap_mplane || \
62 ops->vidioc_##foo##_fmt_vid_out_mplane || \
63 ops->vidioc_##foo##_fmt_vid_overlay || \
64 ops->vidioc_##foo##_fmt_vbi_cap || \
65 ops->vidioc_##foo##_fmt_vid_out_overlay || \
66 ops->vidioc_##foo##_fmt_vbi_out || \
67 ops->vidioc_##foo##_fmt_sliced_vbi_cap || \
68 ops->vidioc_##foo##_fmt_sliced_vbi_out || \
69 ops->vidioc_##foo##_fmt_type_private)
70
71struct std_descr { 58struct std_descr {
72 v4l2_std_id std; 59 v4l2_std_id std;
73 const char *descr; 60 const char *descr;
@@ -195,93 +182,118 @@ static const char *v4l2_memory_names[] = {
195 182
196/* ------------------------------------------------------------------ */ 183/* ------------------------------------------------------------------ */
197/* debug help functions */ 184/* debug help functions */
198static const char *v4l2_ioctls[] = { 185
199 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", 186struct v4l2_ioctl_info {
200 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", 187 unsigned int ioctl;
201 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", 188 u16 flags;
202 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", 189 const char * const name;
203 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", 190};
204 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", 191
205 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", 192/* This control needs a priority check */
206 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", 193#define INFO_FL_PRIO (1 << 0)
207 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", 194/* This control can be valid if the filehandle passes a control handler. */
208 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", 195#define INFO_FL_CTRL (1 << 1)
209 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", 196
210 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", 197#define IOCTL_INFO(_ioctl, _flags) [_IOC_NR(_ioctl)] = { \
211 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", 198 .ioctl = _ioctl, \
212 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", 199 .flags = _flags, \
213 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", 200 .name = #_ioctl, \
214 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", 201}
215 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", 202
216 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", 203static struct v4l2_ioctl_info v4l2_ioctls[] = {
217 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", 204 IOCTL_INFO(VIDIOC_QUERYCAP, 0),
218 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", 205 IOCTL_INFO(VIDIOC_ENUM_FMT, 0),
219 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", 206 IOCTL_INFO(VIDIOC_G_FMT, 0),
220 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", 207 IOCTL_INFO(VIDIOC_S_FMT, INFO_FL_PRIO),
221 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", 208 IOCTL_INFO(VIDIOC_REQBUFS, INFO_FL_PRIO),
222 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", 209 IOCTL_INFO(VIDIOC_QUERYBUF, 0),
223 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", 210 IOCTL_INFO(VIDIOC_G_FBUF, 0),
224 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", 211 IOCTL_INFO(VIDIOC_S_FBUF, INFO_FL_PRIO),
225 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", 212 IOCTL_INFO(VIDIOC_OVERLAY, INFO_FL_PRIO),
226 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", 213 IOCTL_INFO(VIDIOC_QBUF, 0),
227 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", 214 IOCTL_INFO(VIDIOC_DQBUF, 0),
228 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", 215 IOCTL_INFO(VIDIOC_STREAMON, INFO_FL_PRIO),
229 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", 216 IOCTL_INFO(VIDIOC_STREAMOFF, INFO_FL_PRIO),
230 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", 217 IOCTL_INFO(VIDIOC_G_PARM, 0),
231 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", 218 IOCTL_INFO(VIDIOC_S_PARM, INFO_FL_PRIO),
232 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", 219 IOCTL_INFO(VIDIOC_G_STD, 0),
233 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", 220 IOCTL_INFO(VIDIOC_S_STD, INFO_FL_PRIO),
234 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", 221 IOCTL_INFO(VIDIOC_ENUMSTD, 0),
235 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", 222 IOCTL_INFO(VIDIOC_ENUMINPUT, 0),
236 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", 223 IOCTL_INFO(VIDIOC_G_CTRL, INFO_FL_CTRL),
237 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", 224 IOCTL_INFO(VIDIOC_S_CTRL, INFO_FL_PRIO | INFO_FL_CTRL),
238 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", 225 IOCTL_INFO(VIDIOC_G_TUNER, 0),
239 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", 226 IOCTL_INFO(VIDIOC_S_TUNER, INFO_FL_PRIO),
240 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", 227 IOCTL_INFO(VIDIOC_G_AUDIO, 0),
241 [_IOC_NR(VIDIOC_G_SELECTION)] = "VIDIOC_G_SELECTION", 228 IOCTL_INFO(VIDIOC_S_AUDIO, INFO_FL_PRIO),
242 [_IOC_NR(VIDIOC_S_SELECTION)] = "VIDIOC_S_SELECTION", 229 IOCTL_INFO(VIDIOC_QUERYCTRL, INFO_FL_CTRL),
243 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", 230 IOCTL_INFO(VIDIOC_QUERYMENU, INFO_FL_CTRL),
244 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", 231 IOCTL_INFO(VIDIOC_G_INPUT, 0),
245 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", 232 IOCTL_INFO(VIDIOC_S_INPUT, INFO_FL_PRIO),
246 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", 233 IOCTL_INFO(VIDIOC_G_OUTPUT, 0),
247 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", 234 IOCTL_INFO(VIDIOC_S_OUTPUT, INFO_FL_PRIO),
248 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", 235 IOCTL_INFO(VIDIOC_ENUMOUTPUT, 0),
249 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", 236 IOCTL_INFO(VIDIOC_G_AUDOUT, 0),
250 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", 237 IOCTL_INFO(VIDIOC_S_AUDOUT, INFO_FL_PRIO),
251 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", 238 IOCTL_INFO(VIDIOC_G_MODULATOR, 0),
252 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", 239 IOCTL_INFO(VIDIOC_S_MODULATOR, INFO_FL_PRIO),
253 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", 240 IOCTL_INFO(VIDIOC_G_FREQUENCY, 0),
254 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", 241 IOCTL_INFO(VIDIOC_S_FREQUENCY, INFO_FL_PRIO),
255 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", 242 IOCTL_INFO(VIDIOC_CROPCAP, 0),
256#if 1 243 IOCTL_INFO(VIDIOC_G_CROP, 0),
257 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", 244 IOCTL_INFO(VIDIOC_S_CROP, INFO_FL_PRIO),
258 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", 245 IOCTL_INFO(VIDIOC_G_SELECTION, 0),
259 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", 246 IOCTL_INFO(VIDIOC_S_SELECTION, INFO_FL_PRIO),
260 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", 247 IOCTL_INFO(VIDIOC_G_JPEGCOMP, 0),
261 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", 248 IOCTL_INFO(VIDIOC_S_JPEGCOMP, INFO_FL_PRIO),
262 249 IOCTL_INFO(VIDIOC_QUERYSTD, 0),
263 [_IOC_NR(VIDIOC_DECODER_CMD)] = "VIDIOC_DECODER_CMD", 250 IOCTL_INFO(VIDIOC_TRY_FMT, 0),
264 [_IOC_NR(VIDIOC_TRY_DECODER_CMD)] = "VIDIOC_TRY_DECODER_CMD", 251 IOCTL_INFO(VIDIOC_ENUMAUDIO, 0),
265 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", 252 IOCTL_INFO(VIDIOC_ENUMAUDOUT, 0),
266 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", 253 IOCTL_INFO(VIDIOC_G_PRIORITY, 0),
267 254 IOCTL_INFO(VIDIOC_S_PRIORITY, INFO_FL_PRIO),
268 [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", 255 IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP, 0),
269 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", 256 IOCTL_INFO(VIDIOC_LOG_STATUS, 0),
257 IOCTL_INFO(VIDIOC_G_EXT_CTRLS, INFO_FL_CTRL),
258 IOCTL_INFO(VIDIOC_S_EXT_CTRLS, INFO_FL_PRIO | INFO_FL_CTRL),
259 IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS, 0),
260 IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES, 0),
261 IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS, 0),
262 IOCTL_INFO(VIDIOC_G_ENC_INDEX, 0),
263 IOCTL_INFO(VIDIOC_ENCODER_CMD, INFO_FL_PRIO),
264 IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD, 0),
265 IOCTL_INFO(VIDIOC_DECODER_CMD, INFO_FL_PRIO),
266 IOCTL_INFO(VIDIOC_TRY_DECODER_CMD, 0),
267#ifdef CONFIG_VIDEO_ADV_DEBUG
268 IOCTL_INFO(VIDIOC_DBG_S_REGISTER, 0),
269 IOCTL_INFO(VIDIOC_DBG_G_REGISTER, 0),
270#endif 270#endif
271 [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS", 271 IOCTL_INFO(VIDIOC_DBG_G_CHIP_IDENT, 0),
272 [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET", 272 IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, INFO_FL_PRIO),
273 [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET", 273 IOCTL_INFO(VIDIOC_ENUM_DV_PRESETS, 0),
274 [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", 274 IOCTL_INFO(VIDIOC_S_DV_PRESET, INFO_FL_PRIO),
275 [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", 275 IOCTL_INFO(VIDIOC_G_DV_PRESET, 0),
276 [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", 276 IOCTL_INFO(VIDIOC_QUERY_DV_PRESET, 0),
277 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", 277 IOCTL_INFO(VIDIOC_S_DV_TIMINGS, INFO_FL_PRIO),
278 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", 278 IOCTL_INFO(VIDIOC_G_DV_TIMINGS, 0),
279 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", 279 IOCTL_INFO(VIDIOC_DQEVENT, 0),
280 [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS", 280 IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT, 0),
281 [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF", 281 IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT, 0),
282 IOCTL_INFO(VIDIOC_CREATE_BUFS, INFO_FL_PRIO),
283 IOCTL_INFO(VIDIOC_PREPARE_BUF, 0),
284 IOCTL_INFO(VIDIOC_ENUM_DV_TIMINGS, 0),
285 IOCTL_INFO(VIDIOC_QUERY_DV_TIMINGS, 0),
286 IOCTL_INFO(VIDIOC_DV_TIMINGS_CAP, 0),
282}; 287};
283#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 288#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
284 289
290bool v4l2_is_known_ioctl(unsigned int cmd)
291{
292 if (_IOC_NR(cmd) >= V4L2_IOCTLS)
293 return false;
294 return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
295}
296
285/* Common ioctl debug function. This function can be used by 297/* Common ioctl debug function. This function can be used by
286 external ioctl messages as well as internal V4L ioctl */ 298 external ioctl messages as well as internal V4L ioctl */
287void v4l_printk_ioctl(unsigned int cmd) 299void v4l_printk_ioctl(unsigned int cmd)
@@ -297,7 +309,7 @@ void v4l_printk_ioctl(unsigned int cmd)
297 type = "v4l2"; 309 type = "v4l2";
298 break; 310 break;
299 } 311 }
300 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); 312 printk("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
301 return; 313 return;
302 default: 314 default:
303 type = "unknown"; 315 type = "unknown";
@@ -359,6 +371,34 @@ static inline void dbgrect(struct video_device *vfd, char *s,
359 r->width, r->height); 371 r->width, r->height);
360}; 372};
361 373
374static void dbgtimings(struct video_device *vfd,
375 const struct v4l2_dv_timings *p)
376{
377 switch (p->type) {
378 case V4L2_DV_BT_656_1120:
379 dbgarg2("bt-656/1120:interlaced=%d,"
380 " pixelclock=%lld,"
381 " width=%d, height=%d, polarities=%x,"
382 " hfrontporch=%d, hsync=%d,"
383 " hbackporch=%d, vfrontporch=%d,"
384 " vsync=%d, vbackporch=%d,"
385 " il_vfrontporch=%d, il_vsync=%d,"
386 " il_vbackporch=%d, standards=%x, flags=%x\n",
387 p->bt.interlaced, p->bt.pixelclock,
388 p->bt.width, p->bt.height,
389 p->bt.polarities, p->bt.hfrontporch,
390 p->bt.hsync, p->bt.hbackporch,
391 p->bt.vfrontporch, p->bt.vsync,
392 p->bt.vbackporch, p->bt.il_vfrontporch,
393 p->bt.il_vsync, p->bt.il_vbackporch,
394 p->bt.standards, p->bt.flags);
395 break;
396 default:
397 dbgarg2("Unknown type %d!\n", p->type);
398 break;
399 }
400}
401
362static inline void v4l_print_pix_fmt(struct video_device *vfd, 402static inline void v4l_print_pix_fmt(struct video_device *vfd,
363 struct v4l2_pix_format *fmt) 403 struct v4l2_pix_format *fmt)
364{ 404{
@@ -504,7 +544,6 @@ static long __video_do_ioctl(struct file *file,
504 void *fh = file->private_data; 544 void *fh = file->private_data;
505 struct v4l2_fh *vfh = NULL; 545 struct v4l2_fh *vfh = NULL;
506 int use_fh_prio = 0; 546 int use_fh_prio = 0;
507 long ret_prio = 0;
508 long ret = -ENOTTY; 547 long ret = -ENOTTY;
509 548
510 if (ops == NULL) { 549 if (ops == NULL) {
@@ -513,19 +552,30 @@ static long __video_do_ioctl(struct file *file,
513 return ret; 552 return ret;
514 } 553 }
515 554
516 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
517 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
518 v4l_print_ioctl(vfd->name, cmd);
519 printk(KERN_CONT "\n");
520 }
521
522 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { 555 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
523 vfh = file->private_data; 556 vfh = file->private_data;
524 use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); 557 use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
525 } 558 }
526 559
527 if (use_fh_prio) 560 if (v4l2_is_known_ioctl(cmd)) {
528 ret_prio = v4l2_prio_check(vfd->prio, vfh->prio); 561 struct v4l2_ioctl_info *info = &v4l2_ioctls[_IOC_NR(cmd)];
562
563 if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
564 !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
565 return -ENOTTY;
566
567 if (use_fh_prio && (info->flags & INFO_FL_PRIO)) {
568 ret = v4l2_prio_check(vfd->prio, vfh->prio);
569 if (ret)
570 return ret;
571 }
572 }
573
574 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
575 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
576 v4l_print_ioctl(vfd->name, cmd);
577 printk(KERN_CONT "\n");
578 }
529 579
530 switch (cmd) { 580 switch (cmd) {
531 581
@@ -534,9 +584,6 @@ static long __video_do_ioctl(struct file *file,
534 { 584 {
535 struct v4l2_capability *cap = (struct v4l2_capability *)arg; 585 struct v4l2_capability *cap = (struct v4l2_capability *)arg;
536 586
537 if (!ops->vidioc_querycap)
538 break;
539
540 cap->version = LINUX_VERSION_CODE; 587 cap->version = LINUX_VERSION_CODE;
541 ret = ops->vidioc_querycap(file, fh, cap); 588 ret = ops->vidioc_querycap(file, fh, cap);
542 if (!ret) 589 if (!ret)
@@ -570,14 +617,11 @@ static long __video_do_ioctl(struct file *file,
570 { 617 {
571 enum v4l2_priority *p = arg; 618 enum v4l2_priority *p = arg;
572 619
573 if (!ops->vidioc_s_priority && !use_fh_prio)
574 break;
575 dbgarg(cmd, "setting priority to %d\n", *p); 620 dbgarg(cmd, "setting priority to %d\n", *p);
576 if (ops->vidioc_s_priority) 621 if (ops->vidioc_s_priority)
577 ret = ops->vidioc_s_priority(file, fh, *p); 622 ret = ops->vidioc_s_priority(file, fh, *p);
578 else 623 else
579 ret = ret_prio ? ret_prio : 624 ret = v4l2_prio_change(&vfd->v4l2_dev->prio,
580 v4l2_prio_change(&vfd->v4l2_dev->prio,
581 &vfh->prio, *p); 625 &vfh->prio, *p);
582 break; 626 break;
583 } 627 }
@@ -587,6 +631,7 @@ static long __video_do_ioctl(struct file *file,
587 { 631 {
588 struct v4l2_fmtdesc *f = arg; 632 struct v4l2_fmtdesc *f = arg;
589 633
634 ret = -EINVAL;
590 switch (f->type) { 635 switch (f->type) {
591 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 636 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
592 if (likely(ops->vidioc_enum_fmt_vid_cap)) 637 if (likely(ops->vidioc_enum_fmt_vid_cap))
@@ -619,7 +664,7 @@ static long __video_do_ioctl(struct file *file,
619 default: 664 default:
620 break; 665 break;
621 } 666 }
622 if (likely (!ret)) 667 if (likely(!ret))
623 dbgarg(cmd, "index=%d, type=%d, flags=%d, " 668 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
624 "pixelformat=%c%c%c%c, description='%s'\n", 669 "pixelformat=%c%c%c%c, description='%s'\n",
625 f->index, f->type, f->flags, 670 f->index, f->type, f->flags,
@@ -628,14 +673,6 @@ static long __video_do_ioctl(struct file *file,
628 (f->pixelformat >> 16) & 0xff, 673 (f->pixelformat >> 16) & 0xff,
629 (f->pixelformat >> 24) & 0xff, 674 (f->pixelformat >> 24) & 0xff,
630 f->description); 675 f->description);
631 else if (ret == -ENOTTY &&
632 (ops->vidioc_enum_fmt_vid_cap ||
633 ops->vidioc_enum_fmt_vid_out ||
634 ops->vidioc_enum_fmt_vid_cap_mplane ||
635 ops->vidioc_enum_fmt_vid_out_mplane ||
636 ops->vidioc_enum_fmt_vid_overlay ||
637 ops->vidioc_enum_fmt_type_private))
638 ret = -EINVAL;
639 break; 676 break;
640 } 677 }
641 case VIDIOC_G_FMT: 678 case VIDIOC_G_FMT:
@@ -645,6 +682,7 @@ static long __video_do_ioctl(struct file *file,
645 /* FIXME: Should be one dump per type */ 682 /* FIXME: Should be one dump per type */
646 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); 683 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
647 684
685 ret = -EINVAL;
648 switch (f->type) { 686 switch (f->type) {
649 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 687 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
650 if (ops->vidioc_g_fmt_vid_cap) 688 if (ops->vidioc_g_fmt_vid_cap)
@@ -706,21 +744,12 @@ static long __video_do_ioctl(struct file *file,
706 fh, f); 744 fh, f);
707 break; 745 break;
708 } 746 }
709 if (unlikely(ret == -ENOTTY && have_fmt_ops(g)))
710 ret = -EINVAL;
711
712 break; 747 break;
713 } 748 }
714 case VIDIOC_S_FMT: 749 case VIDIOC_S_FMT:
715 { 750 {
716 struct v4l2_format *f = (struct v4l2_format *)arg; 751 struct v4l2_format *f = (struct v4l2_format *)arg;
717 752
718 if (!have_fmt_ops(s))
719 break;
720 if (ret_prio) {
721 ret = ret_prio;
722 break;
723 }
724 ret = -EINVAL; 753 ret = -EINVAL;
725 754
726 /* FIXME: Should be one dump per type */ 755 /* FIXME: Should be one dump per type */
@@ -804,6 +833,7 @@ static long __video_do_ioctl(struct file *file,
804 /* FIXME: Should be one dump per type */ 833 /* FIXME: Should be one dump per type */
805 dbgarg(cmd, "type=%s\n", prt_names(f->type, 834 dbgarg(cmd, "type=%s\n", prt_names(f->type,
806 v4l2_type_names)); 835 v4l2_type_names));
836 ret = -EINVAL;
807 switch (f->type) { 837 switch (f->type) {
808 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 838 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
809 CLEAR_AFTER_FIELD(f, fmt.pix); 839 CLEAR_AFTER_FIELD(f, fmt.pix);
@@ -876,8 +906,6 @@ static long __video_do_ioctl(struct file *file,
876 fh, f); 906 fh, f);
877 break; 907 break;
878 } 908 }
879 if (unlikely(ret == -ENOTTY && have_fmt_ops(try)))
880 ret = -EINVAL;
881 break; 909 break;
882 } 910 }
883 /* FIXME: Those buf reqs could be handled here, 911 /* FIXME: Those buf reqs could be handled here,
@@ -888,12 +916,6 @@ static long __video_do_ioctl(struct file *file,
888 { 916 {
889 struct v4l2_requestbuffers *p = arg; 917 struct v4l2_requestbuffers *p = arg;
890 918
891 if (!ops->vidioc_reqbufs)
892 break;
893 if (ret_prio) {
894 ret = ret_prio;
895 break;
896 }
897 ret = check_fmt(ops, p->type); 919 ret = check_fmt(ops, p->type);
898 if (ret) 920 if (ret)
899 break; 921 break;
@@ -912,8 +934,6 @@ static long __video_do_ioctl(struct file *file,
912 { 934 {
913 struct v4l2_buffer *p = arg; 935 struct v4l2_buffer *p = arg;
914 936
915 if (!ops->vidioc_querybuf)
916 break;
917 ret = check_fmt(ops, p->type); 937 ret = check_fmt(ops, p->type);
918 if (ret) 938 if (ret)
919 break; 939 break;
@@ -927,8 +947,6 @@ static long __video_do_ioctl(struct file *file,
927 { 947 {
928 struct v4l2_buffer *p = arg; 948 struct v4l2_buffer *p = arg;
929 949
930 if (!ops->vidioc_qbuf)
931 break;
932 ret = check_fmt(ops, p->type); 950 ret = check_fmt(ops, p->type);
933 if (ret) 951 if (ret)
934 break; 952 break;
@@ -942,8 +960,6 @@ static long __video_do_ioctl(struct file *file,
942 { 960 {
943 struct v4l2_buffer *p = arg; 961 struct v4l2_buffer *p = arg;
944 962
945 if (!ops->vidioc_dqbuf)
946 break;
947 ret = check_fmt(ops, p->type); 963 ret = check_fmt(ops, p->type);
948 if (ret) 964 if (ret)
949 break; 965 break;
@@ -957,12 +973,6 @@ static long __video_do_ioctl(struct file *file,
957 { 973 {
958 int *i = arg; 974 int *i = arg;
959 975
960 if (!ops->vidioc_overlay)
961 break;
962 if (ret_prio) {
963 ret = ret_prio;
964 break;
965 }
966 dbgarg(cmd, "value=%d\n", *i); 976 dbgarg(cmd, "value=%d\n", *i);
967 ret = ops->vidioc_overlay(file, fh, *i); 977 ret = ops->vidioc_overlay(file, fh, *i);
968 break; 978 break;
@@ -971,8 +981,6 @@ static long __video_do_ioctl(struct file *file,
971 { 981 {
972 struct v4l2_framebuffer *p = arg; 982 struct v4l2_framebuffer *p = arg;
973 983
974 if (!ops->vidioc_g_fbuf)
975 break;
976 ret = ops->vidioc_g_fbuf(file, fh, arg); 984 ret = ops->vidioc_g_fbuf(file, fh, arg);
977 if (!ret) { 985 if (!ret) {
978 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", 986 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
@@ -986,12 +994,6 @@ static long __video_do_ioctl(struct file *file,
986 { 994 {
987 struct v4l2_framebuffer *p = arg; 995 struct v4l2_framebuffer *p = arg;
988 996
989 if (!ops->vidioc_s_fbuf)
990 break;
991 if (ret_prio) {
992 ret = ret_prio;
993 break;
994 }
995 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", 997 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
996 p->capability, p->flags, (unsigned long)p->base); 998 p->capability, p->flags, (unsigned long)p->base);
997 v4l_print_pix_fmt(vfd, &p->fmt); 999 v4l_print_pix_fmt(vfd, &p->fmt);
@@ -1002,12 +1004,6 @@ static long __video_do_ioctl(struct file *file,
1002 { 1004 {
1003 enum v4l2_buf_type i = *(int *)arg; 1005 enum v4l2_buf_type i = *(int *)arg;
1004 1006
1005 if (!ops->vidioc_streamon)
1006 break;
1007 if (ret_prio) {
1008 ret = ret_prio;
1009 break;
1010 }
1011 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); 1007 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1012 ret = ops->vidioc_streamon(file, fh, i); 1008 ret = ops->vidioc_streamon(file, fh, i);
1013 break; 1009 break;
@@ -1016,12 +1012,6 @@ static long __video_do_ioctl(struct file *file,
1016 { 1012 {
1017 enum v4l2_buf_type i = *(int *)arg; 1013 enum v4l2_buf_type i = *(int *)arg;
1018 1014
1019 if (!ops->vidioc_streamoff)
1020 break;
1021 if (ret_prio) {
1022 ret = ret_prio;
1023 break;
1024 }
1025 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); 1015 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1026 ret = ops->vidioc_streamoff(file, fh, i); 1016 ret = ops->vidioc_streamoff(file, fh, i);
1027 break; 1017 break;
@@ -1091,13 +1081,6 @@ static long __video_do_ioctl(struct file *file,
1091 1081
1092 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); 1082 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1093 1083
1094 if (!ops->vidioc_s_std)
1095 break;
1096
1097 if (ret_prio) {
1098 ret = ret_prio;
1099 break;
1100 }
1101 ret = -EINVAL; 1084 ret = -EINVAL;
1102 norm = (*id) & vfd->tvnorms; 1085 norm = (*id) & vfd->tvnorms;
1103 if (vfd->tvnorms && !norm) /* Check if std is supported */ 1086 if (vfd->tvnorms && !norm) /* Check if std is supported */
@@ -1115,8 +1098,6 @@ static long __video_do_ioctl(struct file *file,
1115 { 1098 {
1116 v4l2_std_id *p = arg; 1099 v4l2_std_id *p = arg;
1117 1100
1118 if (!ops->vidioc_querystd)
1119 break;
1120 /* 1101 /*
1121 * If nothing detected, it should return all supported 1102 * If nothing detected, it should return all supported
1122 * Drivers just need to mask the std argument, in order 1103 * Drivers just need to mask the std argument, in order
@@ -1150,9 +1131,6 @@ static long __video_do_ioctl(struct file *file,
1150 if (ops->vidioc_s_dv_timings) 1131 if (ops->vidioc_s_dv_timings)
1151 p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; 1132 p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
1152 1133
1153 if (!ops->vidioc_enum_input)
1154 break;
1155
1156 ret = ops->vidioc_enum_input(file, fh, p); 1134 ret = ops->vidioc_enum_input(file, fh, p);
1157 if (!ret) 1135 if (!ret)
1158 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1136 dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1168,8 +1146,6 @@ static long __video_do_ioctl(struct file *file,
1168 { 1146 {
1169 unsigned int *i = arg; 1147 unsigned int *i = arg;
1170 1148
1171 if (!ops->vidioc_g_input)
1172 break;
1173 ret = ops->vidioc_g_input(file, fh, i); 1149 ret = ops->vidioc_g_input(file, fh, i);
1174 if (!ret) 1150 if (!ret)
1175 dbgarg(cmd, "value=%d\n", *i); 1151 dbgarg(cmd, "value=%d\n", *i);
@@ -1179,12 +1155,6 @@ static long __video_do_ioctl(struct file *file,
1179 { 1155 {
1180 unsigned int *i = arg; 1156 unsigned int *i = arg;
1181 1157
1182 if (!ops->vidioc_s_input)
1183 break;
1184 if (ret_prio) {
1185 ret = ret_prio;
1186 break;
1187 }
1188 dbgarg(cmd, "value=%d\n", *i); 1158 dbgarg(cmd, "value=%d\n", *i);
1189 ret = ops->vidioc_s_input(file, fh, *i); 1159 ret = ops->vidioc_s_input(file, fh, *i);
1190 break; 1160 break;
@@ -1195,9 +1165,6 @@ static long __video_do_ioctl(struct file *file,
1195 { 1165 {
1196 struct v4l2_output *p = arg; 1166 struct v4l2_output *p = arg;
1197 1167
1198 if (!ops->vidioc_enum_output)
1199 break;
1200
1201 /* 1168 /*
1202 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & 1169 * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
1203 * CAP_STD here based on ioctl handler provided by the 1170 * CAP_STD here based on ioctl handler provided by the
@@ -1224,8 +1191,6 @@ static long __video_do_ioctl(struct file *file,
1224 { 1191 {
1225 unsigned int *i = arg; 1192 unsigned int *i = arg;
1226 1193
1227 if (!ops->vidioc_g_output)
1228 break;
1229 ret = ops->vidioc_g_output(file, fh, i); 1194 ret = ops->vidioc_g_output(file, fh, i);
1230 if (!ret) 1195 if (!ret)
1231 dbgarg(cmd, "value=%d\n", *i); 1196 dbgarg(cmd, "value=%d\n", *i);
@@ -1235,12 +1200,6 @@ static long __video_do_ioctl(struct file *file,
1235 { 1200 {
1236 unsigned int *i = arg; 1201 unsigned int *i = arg;
1237 1202
1238 if (!ops->vidioc_s_output)
1239 break;
1240 if (ret_prio) {
1241 ret = ret_prio;
1242 break;
1243 }
1244 dbgarg(cmd, "value=%d\n", *i); 1203 dbgarg(cmd, "value=%d\n", *i);
1245 ret = ops->vidioc_s_output(file, fh, *i); 1204 ret = ops->vidioc_s_output(file, fh, *i);
1246 break; 1205 break;
@@ -1310,10 +1269,6 @@ static long __video_do_ioctl(struct file *file,
1310 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && 1269 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler &&
1311 !ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) 1270 !ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
1312 break; 1271 break;
1313 if (ret_prio) {
1314 ret = ret_prio;
1315 break;
1316 }
1317 1272
1318 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); 1273 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1319 1274
@@ -1369,10 +1324,6 @@ static long __video_do_ioctl(struct file *file,
1369 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler && 1324 if (!(vfh && vfh->ctrl_handler) && !vfd->ctrl_handler &&
1370 !ops->vidioc_s_ext_ctrls) 1325 !ops->vidioc_s_ext_ctrls)
1371 break; 1326 break;
1372 if (ret_prio) {
1373 ret = ret_prio;
1374 break;
1375 }
1376 v4l_print_ext_ctrls(cmd, vfd, p, 1); 1327 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1377 if (vfh && vfh->ctrl_handler) 1328 if (vfh && vfh->ctrl_handler)
1378 ret = v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p); 1329 ret = v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
@@ -1428,8 +1379,6 @@ static long __video_do_ioctl(struct file *file,
1428 { 1379 {
1429 struct v4l2_audio *p = arg; 1380 struct v4l2_audio *p = arg;
1430 1381
1431 if (!ops->vidioc_enumaudio)
1432 break;
1433 ret = ops->vidioc_enumaudio(file, fh, p); 1382 ret = ops->vidioc_enumaudio(file, fh, p);
1434 if (!ret) 1383 if (!ret)
1435 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " 1384 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
@@ -1443,9 +1392,6 @@ static long __video_do_ioctl(struct file *file,
1443 { 1392 {
1444 struct v4l2_audio *p = arg; 1393 struct v4l2_audio *p = arg;
1445 1394
1446 if (!ops->vidioc_g_audio)
1447 break;
1448
1449 ret = ops->vidioc_g_audio(file, fh, p); 1395 ret = ops->vidioc_g_audio(file, fh, p);
1450 if (!ret) 1396 if (!ret)
1451 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " 1397 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
@@ -1459,12 +1405,6 @@ static long __video_do_ioctl(struct file *file,
1459 { 1405 {
1460 struct v4l2_audio *p = arg; 1406 struct v4l2_audio *p = arg;
1461 1407
1462 if (!ops->vidioc_s_audio)
1463 break;
1464 if (ret_prio) {
1465 ret = ret_prio;
1466 break;
1467 }
1468 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " 1408 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1469 "mode=0x%x\n", p->index, p->name, 1409 "mode=0x%x\n", p->index, p->name,
1470 p->capability, p->mode); 1410 p->capability, p->mode);
@@ -1475,8 +1415,6 @@ static long __video_do_ioctl(struct file *file,
1475 { 1415 {
1476 struct v4l2_audioout *p = arg; 1416 struct v4l2_audioout *p = arg;
1477 1417
1478 if (!ops->vidioc_enumaudout)
1479 break;
1480 dbgarg(cmd, "Enum for index=%d\n", p->index); 1418 dbgarg(cmd, "Enum for index=%d\n", p->index);
1481 ret = ops->vidioc_enumaudout(file, fh, p); 1419 ret = ops->vidioc_enumaudout(file, fh, p);
1482 if (!ret) 1420 if (!ret)
@@ -1489,9 +1427,6 @@ static long __video_do_ioctl(struct file *file,
1489 { 1427 {
1490 struct v4l2_audioout *p = arg; 1428 struct v4l2_audioout *p = arg;
1491 1429
1492 if (!ops->vidioc_g_audout)
1493 break;
1494
1495 ret = ops->vidioc_g_audout(file, fh, p); 1430 ret = ops->vidioc_g_audout(file, fh, p);
1496 if (!ret) 1431 if (!ret)
1497 dbgarg2("index=%d, name=%s, capability=%d, " 1432 dbgarg2("index=%d, name=%s, capability=%d, "
@@ -1503,12 +1438,6 @@ static long __video_do_ioctl(struct file *file,
1503 { 1438 {
1504 struct v4l2_audioout *p = arg; 1439 struct v4l2_audioout *p = arg;
1505 1440
1506 if (!ops->vidioc_s_audout)
1507 break;
1508 if (ret_prio) {
1509 ret = ret_prio;
1510 break;
1511 }
1512 dbgarg(cmd, "index=%d, name=%s, capability=%d, " 1441 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1513 "mode=%d\n", p->index, p->name, 1442 "mode=%d\n", p->index, p->name,
1514 p->capability, p->mode); 1443 p->capability, p->mode);
@@ -1520,8 +1449,6 @@ static long __video_do_ioctl(struct file *file,
1520 { 1449 {
1521 struct v4l2_modulator *p = arg; 1450 struct v4l2_modulator *p = arg;
1522 1451
1523 if (!ops->vidioc_g_modulator)
1524 break;
1525 ret = ops->vidioc_g_modulator(file, fh, p); 1452 ret = ops->vidioc_g_modulator(file, fh, p);
1526 if (!ret) 1453 if (!ret)
1527 dbgarg(cmd, "index=%d, name=%s, " 1454 dbgarg(cmd, "index=%d, name=%s, "
@@ -1536,12 +1463,6 @@ static long __video_do_ioctl(struct file *file,
1536 { 1463 {
1537 struct v4l2_modulator *p = arg; 1464 struct v4l2_modulator *p = arg;
1538 1465
1539 if (!ops->vidioc_s_modulator)
1540 break;
1541 if (ret_prio) {
1542 ret = ret_prio;
1543 break;
1544 }
1545 dbgarg(cmd, "index=%d, name=%s, capability=%d, " 1466 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1546 "rangelow=%d, rangehigh=%d, txsubchans=%d\n", 1467 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1547 p->index, p->name, p->capability, p->rangelow, 1468 p->index, p->name, p->capability, p->rangelow,
@@ -1553,9 +1474,6 @@ static long __video_do_ioctl(struct file *file,
1553 { 1474 {
1554 struct v4l2_crop *p = arg; 1475 struct v4l2_crop *p = arg;
1555 1476
1556 if (!ops->vidioc_g_crop && !ops->vidioc_g_selection)
1557 break;
1558
1559 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1477 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1560 1478
1561 if (ops->vidioc_g_crop) { 1479 if (ops->vidioc_g_crop) {
@@ -1587,13 +1505,6 @@ static long __video_do_ioctl(struct file *file,
1587 { 1505 {
1588 struct v4l2_crop *p = arg; 1506 struct v4l2_crop *p = arg;
1589 1507
1590 if (!ops->vidioc_s_crop && !ops->vidioc_s_selection)
1591 break;
1592
1593 if (ret_prio) {
1594 ret = ret_prio;
1595 break;
1596 }
1597 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1508 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1598 dbgrect(vfd, "", &p->c); 1509 dbgrect(vfd, "", &p->c);
1599 1510
@@ -1620,9 +1531,6 @@ static long __video_do_ioctl(struct file *file,
1620 { 1531 {
1621 struct v4l2_selection *p = arg; 1532 struct v4l2_selection *p = arg;
1622 1533
1623 if (!ops->vidioc_g_selection)
1624 break;
1625
1626 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1534 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1627 1535
1628 ret = ops->vidioc_g_selection(file, fh, p); 1536 ret = ops->vidioc_g_selection(file, fh, p);
@@ -1634,13 +1542,6 @@ static long __video_do_ioctl(struct file *file,
1634 { 1542 {
1635 struct v4l2_selection *p = arg; 1543 struct v4l2_selection *p = arg;
1636 1544
1637 if (!ops->vidioc_s_selection)
1638 break;
1639
1640 if (ret_prio) {
1641 ret = ret_prio;
1642 break;
1643 }
1644 1545
1645 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1546 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1646 dbgrect(vfd, "", &p->r); 1547 dbgrect(vfd, "", &p->r);
@@ -1653,9 +1554,6 @@ static long __video_do_ioctl(struct file *file,
1653 struct v4l2_cropcap *p = arg; 1554 struct v4l2_cropcap *p = arg;
1654 1555
1655 /*FIXME: Should also show v4l2_fract pixelaspect */ 1556 /*FIXME: Should also show v4l2_fract pixelaspect */
1656 if (!ops->vidioc_cropcap && !ops->vidioc_g_selection)
1657 break;
1658
1659 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1557 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1660 if (ops->vidioc_cropcap) { 1558 if (ops->vidioc_cropcap) {
1661 ret = ops->vidioc_cropcap(file, fh, p); 1559 ret = ops->vidioc_cropcap(file, fh, p);
@@ -1699,9 +1597,6 @@ static long __video_do_ioctl(struct file *file,
1699 { 1597 {
1700 struct v4l2_jpegcompression *p = arg; 1598 struct v4l2_jpegcompression *p = arg;
1701 1599
1702 if (!ops->vidioc_g_jpegcomp)
1703 break;
1704
1705 ret = ops->vidioc_g_jpegcomp(file, fh, p); 1600 ret = ops->vidioc_g_jpegcomp(file, fh, p);
1706 if (!ret) 1601 if (!ret)
1707 dbgarg(cmd, "quality=%d, APPn=%d, " 1602 dbgarg(cmd, "quality=%d, APPn=%d, "
@@ -1715,12 +1610,6 @@ static long __video_do_ioctl(struct file *file,
1715 { 1610 {
1716 struct v4l2_jpegcompression *p = arg; 1611 struct v4l2_jpegcompression *p = arg;
1717 1612
1718 if (!ops->vidioc_g_jpegcomp)
1719 break;
1720 if (ret_prio) {
1721 ret = ret_prio;
1722 break;
1723 }
1724 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " 1613 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
1725 "COM_len=%d, jpeg_markers=%d\n", 1614 "COM_len=%d, jpeg_markers=%d\n",
1726 p->quality, p->APPn, p->APP_len, 1615 p->quality, p->APPn, p->APP_len,
@@ -1732,8 +1621,6 @@ static long __video_do_ioctl(struct file *file,
1732 { 1621 {
1733 struct v4l2_enc_idx *p = arg; 1622 struct v4l2_enc_idx *p = arg;
1734 1623
1735 if (!ops->vidioc_g_enc_index)
1736 break;
1737 ret = ops->vidioc_g_enc_index(file, fh, p); 1624 ret = ops->vidioc_g_enc_index(file, fh, p);
1738 if (!ret) 1625 if (!ret)
1739 dbgarg(cmd, "entries=%d, entries_cap=%d\n", 1626 dbgarg(cmd, "entries=%d, entries_cap=%d\n",
@@ -1744,12 +1631,6 @@ static long __video_do_ioctl(struct file *file,
1744 { 1631 {
1745 struct v4l2_encoder_cmd *p = arg; 1632 struct v4l2_encoder_cmd *p = arg;
1746 1633
1747 if (!ops->vidioc_encoder_cmd)
1748 break;
1749 if (ret_prio) {
1750 ret = ret_prio;
1751 break;
1752 }
1753 ret = ops->vidioc_encoder_cmd(file, fh, p); 1634 ret = ops->vidioc_encoder_cmd(file, fh, p);
1754 if (!ret) 1635 if (!ret)
1755 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1636 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1759,8 +1640,6 @@ static long __video_do_ioctl(struct file *file,
1759 { 1640 {
1760 struct v4l2_encoder_cmd *p = arg; 1641 struct v4l2_encoder_cmd *p = arg;
1761 1642
1762 if (!ops->vidioc_try_encoder_cmd)
1763 break;
1764 ret = ops->vidioc_try_encoder_cmd(file, fh, p); 1643 ret = ops->vidioc_try_encoder_cmd(file, fh, p);
1765 if (!ret) 1644 if (!ret)
1766 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1645 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1770,12 +1649,6 @@ static long __video_do_ioctl(struct file *file,
1770 { 1649 {
1771 struct v4l2_decoder_cmd *p = arg; 1650 struct v4l2_decoder_cmd *p = arg;
1772 1651
1773 if (!ops->vidioc_decoder_cmd)
1774 break;
1775 if (ret_prio) {
1776 ret = ret_prio;
1777 break;
1778 }
1779 ret = ops->vidioc_decoder_cmd(file, fh, p); 1652 ret = ops->vidioc_decoder_cmd(file, fh, p);
1780 if (!ret) 1653 if (!ret)
1781 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1654 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1785,8 +1658,6 @@ static long __video_do_ioctl(struct file *file,
1785 { 1658 {
1786 struct v4l2_decoder_cmd *p = arg; 1659 struct v4l2_decoder_cmd *p = arg;
1787 1660
1788 if (!ops->vidioc_try_decoder_cmd)
1789 break;
1790 ret = ops->vidioc_try_decoder_cmd(file, fh, p); 1661 ret = ops->vidioc_try_decoder_cmd(file, fh, p);
1791 if (!ret) 1662 if (!ret)
1792 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1663 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1796,8 +1667,6 @@ static long __video_do_ioctl(struct file *file,
1796 { 1667 {
1797 struct v4l2_streamparm *p = arg; 1668 struct v4l2_streamparm *p = arg;
1798 1669
1799 if (!ops->vidioc_g_parm && !vfd->current_norm)
1800 break;
1801 if (ops->vidioc_g_parm) { 1670 if (ops->vidioc_g_parm) {
1802 ret = check_fmt(ops, p->type); 1671 ret = check_fmt(ops, p->type);
1803 if (ret) 1672 if (ret)
@@ -1825,12 +1694,6 @@ static long __video_do_ioctl(struct file *file,
1825 { 1694 {
1826 struct v4l2_streamparm *p = arg; 1695 struct v4l2_streamparm *p = arg;
1827 1696
1828 if (!ops->vidioc_s_parm)
1829 break;
1830 if (ret_prio) {
1831 ret = ret_prio;
1832 break;
1833 }
1834 ret = check_fmt(ops, p->type); 1697 ret = check_fmt(ops, p->type);
1835 if (ret) 1698 if (ret)
1836 break; 1699 break;
@@ -1843,9 +1706,6 @@ static long __video_do_ioctl(struct file *file,
1843 { 1706 {
1844 struct v4l2_tuner *p = arg; 1707 struct v4l2_tuner *p = arg;
1845 1708
1846 if (!ops->vidioc_g_tuner)
1847 break;
1848
1849 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1709 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1850 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1710 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1851 ret = ops->vidioc_g_tuner(file, fh, p); 1711 ret = ops->vidioc_g_tuner(file, fh, p);
@@ -1864,12 +1724,6 @@ static long __video_do_ioctl(struct file *file,
1864 { 1724 {
1865 struct v4l2_tuner *p = arg; 1725 struct v4l2_tuner *p = arg;
1866 1726
1867 if (!ops->vidioc_s_tuner)
1868 break;
1869 if (ret_prio) {
1870 ret = ret_prio;
1871 break;
1872 }
1873 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1727 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1874 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1728 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1875 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1729 dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1887,9 +1741,6 @@ static long __video_do_ioctl(struct file *file,
1887 { 1741 {
1888 struct v4l2_frequency *p = arg; 1742 struct v4l2_frequency *p = arg;
1889 1743
1890 if (!ops->vidioc_g_frequency)
1891 break;
1892
1893 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1744 p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1894 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1745 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1895 ret = ops->vidioc_g_frequency(file, fh, p); 1746 ret = ops->vidioc_g_frequency(file, fh, p);
@@ -1903,12 +1754,6 @@ static long __video_do_ioctl(struct file *file,
1903 struct v4l2_frequency *p = arg; 1754 struct v4l2_frequency *p = arg;
1904 enum v4l2_tuner_type type; 1755 enum v4l2_tuner_type type;
1905 1756
1906 if (!ops->vidioc_s_frequency)
1907 break;
1908 if (ret_prio) {
1909 ret = ret_prio;
1910 break;
1911 }
1912 type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1757 type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
1913 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1758 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1914 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", 1759 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1923,9 +1768,6 @@ static long __video_do_ioctl(struct file *file,
1923 { 1768 {
1924 struct v4l2_sliced_vbi_cap *p = arg; 1769 struct v4l2_sliced_vbi_cap *p = arg;
1925 1770
1926 if (!ops->vidioc_g_sliced_vbi_cap)
1927 break;
1928
1929 /* Clear up to type, everything after type is zerod already */ 1771 /* Clear up to type, everything after type is zerod already */
1930 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); 1772 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
1931 1773
@@ -1937,8 +1779,6 @@ static long __video_do_ioctl(struct file *file,
1937 } 1779 }
1938 case VIDIOC_LOG_STATUS: 1780 case VIDIOC_LOG_STATUS:
1939 { 1781 {
1940 if (!ops->vidioc_log_status)
1941 break;
1942 if (vfd->v4l2_dev) 1782 if (vfd->v4l2_dev)
1943 pr_info("%s: ================= START STATUS =================\n", 1783 pr_info("%s: ================= START STATUS =================\n",
1944 vfd->v4l2_dev->name); 1784 vfd->v4l2_dev->name);
@@ -1948,38 +1788,34 @@ static long __video_do_ioctl(struct file *file,
1948 vfd->v4l2_dev->name); 1788 vfd->v4l2_dev->name);
1949 break; 1789 break;
1950 } 1790 }
1951#ifdef CONFIG_VIDEO_ADV_DEBUG
1952 case VIDIOC_DBG_G_REGISTER: 1791 case VIDIOC_DBG_G_REGISTER:
1953 { 1792 {
1793#ifdef CONFIG_VIDEO_ADV_DEBUG
1954 struct v4l2_dbg_register *p = arg; 1794 struct v4l2_dbg_register *p = arg;
1955 1795
1956 if (ops->vidioc_g_register) { 1796 if (!capable(CAP_SYS_ADMIN))
1957 if (!capable(CAP_SYS_ADMIN)) 1797 ret = -EPERM;
1958 ret = -EPERM; 1798 else
1959 else 1799 ret = ops->vidioc_g_register(file, fh, p);
1960 ret = ops->vidioc_g_register(file, fh, p); 1800#endif
1961 }
1962 break; 1801 break;
1963 } 1802 }
1964 case VIDIOC_DBG_S_REGISTER: 1803 case VIDIOC_DBG_S_REGISTER:
1965 { 1804 {
1805#ifdef CONFIG_VIDEO_ADV_DEBUG
1966 struct v4l2_dbg_register *p = arg; 1806 struct v4l2_dbg_register *p = arg;
1967 1807
1968 if (ops->vidioc_s_register) { 1808 if (!capable(CAP_SYS_ADMIN))
1969 if (!capable(CAP_SYS_ADMIN)) 1809 ret = -EPERM;
1970 ret = -EPERM; 1810 else
1971 else 1811 ret = ops->vidioc_s_register(file, fh, p);
1972 ret = ops->vidioc_s_register(file, fh, p); 1812#endif
1973 }
1974 break; 1813 break;
1975 } 1814 }
1976#endif
1977 case VIDIOC_DBG_G_CHIP_IDENT: 1815 case VIDIOC_DBG_G_CHIP_IDENT:
1978 { 1816 {
1979 struct v4l2_dbg_chip_ident *p = arg; 1817 struct v4l2_dbg_chip_ident *p = arg;
1980 1818
1981 if (!ops->vidioc_g_chip_ident)
1982 break;
1983 p->ident = V4L2_IDENT_NONE; 1819 p->ident = V4L2_IDENT_NONE;
1984 p->revision = 0; 1820 p->revision = 0;
1985 ret = ops->vidioc_g_chip_ident(file, fh, p); 1821 ret = ops->vidioc_g_chip_ident(file, fh, p);
@@ -1992,12 +1828,6 @@ static long __video_do_ioctl(struct file *file,
1992 struct v4l2_hw_freq_seek *p = arg; 1828 struct v4l2_hw_freq_seek *p = arg;
1993 enum v4l2_tuner_type type; 1829 enum v4l2_tuner_type type;
1994 1830
1995 if (!ops->vidioc_s_hw_freq_seek)
1996 break;
1997 if (ret_prio) {
1998 ret = ret_prio;
1999 break;
2000 }
2001 type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1831 type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
2002 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1832 V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
2003 dbgarg(cmd, 1833 dbgarg(cmd,
@@ -2013,9 +1843,6 @@ static long __video_do_ioctl(struct file *file,
2013 { 1843 {
2014 struct v4l2_frmsizeenum *p = arg; 1844 struct v4l2_frmsizeenum *p = arg;
2015 1845
2016 if (!ops->vidioc_enum_framesizes)
2017 break;
2018
2019 ret = ops->vidioc_enum_framesizes(file, fh, p); 1846 ret = ops->vidioc_enum_framesizes(file, fh, p);
2020 dbgarg(cmd, 1847 dbgarg(cmd,
2021 "index=%d, pixelformat=%c%c%c%c, type=%d ", 1848 "index=%d, pixelformat=%c%c%c%c, type=%d ",
@@ -2049,9 +1876,6 @@ static long __video_do_ioctl(struct file *file,
2049 { 1876 {
2050 struct v4l2_frmivalenum *p = arg; 1877 struct v4l2_frmivalenum *p = arg;
2051 1878
2052 if (!ops->vidioc_enum_frameintervals)
2053 break;
2054
2055 ret = ops->vidioc_enum_frameintervals(file, fh, p); 1879 ret = ops->vidioc_enum_frameintervals(file, fh, p);
2056 dbgarg(cmd, 1880 dbgarg(cmd,
2057 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ", 1881 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
@@ -2084,9 +1908,6 @@ static long __video_do_ioctl(struct file *file,
2084 { 1908 {
2085 struct v4l2_dv_enum_preset *p = arg; 1909 struct v4l2_dv_enum_preset *p = arg;
2086 1910
2087 if (!ops->vidioc_enum_dv_presets)
2088 break;
2089
2090 ret = ops->vidioc_enum_dv_presets(file, fh, p); 1911 ret = ops->vidioc_enum_dv_presets(file, fh, p);
2091 if (!ret) 1912 if (!ret)
2092 dbgarg(cmd, 1913 dbgarg(cmd,
@@ -2100,13 +1921,6 @@ static long __video_do_ioctl(struct file *file,
2100 { 1921 {
2101 struct v4l2_dv_preset *p = arg; 1922 struct v4l2_dv_preset *p = arg;
2102 1923
2103 if (!ops->vidioc_s_dv_preset)
2104 break;
2105 if (ret_prio) {
2106 ret = ret_prio;
2107 break;
2108 }
2109
2110 dbgarg(cmd, "preset=%d\n", p->preset); 1924 dbgarg(cmd, "preset=%d\n", p->preset);
2111 ret = ops->vidioc_s_dv_preset(file, fh, p); 1925 ret = ops->vidioc_s_dv_preset(file, fh, p);
2112 break; 1926 break;
@@ -2115,9 +1929,6 @@ static long __video_do_ioctl(struct file *file,
2115 { 1929 {
2116 struct v4l2_dv_preset *p = arg; 1930 struct v4l2_dv_preset *p = arg;
2117 1931
2118 if (!ops->vidioc_g_dv_preset)
2119 break;
2120
2121 ret = ops->vidioc_g_dv_preset(file, fh, p); 1932 ret = ops->vidioc_g_dv_preset(file, fh, p);
2122 if (!ret) 1933 if (!ret)
2123 dbgarg(cmd, "preset=%d\n", p->preset); 1934 dbgarg(cmd, "preset=%d\n", p->preset);
@@ -2127,9 +1938,6 @@ static long __video_do_ioctl(struct file *file,
2127 { 1938 {
2128 struct v4l2_dv_preset *p = arg; 1939 struct v4l2_dv_preset *p = arg;
2129 1940
2130 if (!ops->vidioc_query_dv_preset)
2131 break;
2132
2133 ret = ops->vidioc_query_dv_preset(file, fh, p); 1941 ret = ops->vidioc_query_dv_preset(file, fh, p);
2134 if (!ret) 1942 if (!ret)
2135 dbgarg(cmd, "preset=%d\n", p->preset); 1943 dbgarg(cmd, "preset=%d\n", p->preset);
@@ -2139,32 +1947,13 @@ static long __video_do_ioctl(struct file *file,
2139 { 1947 {
2140 struct v4l2_dv_timings *p = arg; 1948 struct v4l2_dv_timings *p = arg;
2141 1949
2142 if (!ops->vidioc_s_dv_timings) 1950 dbgtimings(vfd, p);
2143 break;
2144 if (ret_prio) {
2145 ret = ret_prio;
2146 break;
2147 }
2148
2149 switch (p->type) { 1951 switch (p->type) {
2150 case V4L2_DV_BT_656_1120: 1952 case V4L2_DV_BT_656_1120:
2151 dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld,"
2152 " width=%d, height=%d, polarities=%x,"
2153 " hfrontporch=%d, hsync=%d, hbackporch=%d,"
2154 " vfrontporch=%d, vsync=%d, vbackporch=%d,"
2155 " il_vfrontporch=%d, il_vsync=%d,"
2156 " il_vbackporch=%d\n",
2157 p->bt.interlaced, p->bt.pixelclock,
2158 p->bt.width, p->bt.height, p->bt.polarities,
2159 p->bt.hfrontporch, p->bt.hsync,
2160 p->bt.hbackporch, p->bt.vfrontporch,
2161 p->bt.vsync, p->bt.vbackporch,
2162 p->bt.il_vfrontporch, p->bt.il_vsync,
2163 p->bt.il_vbackporch);
2164 ret = ops->vidioc_s_dv_timings(file, fh, p); 1953 ret = ops->vidioc_s_dv_timings(file, fh, p);
2165 break; 1954 break;
2166 default: 1955 default:
2167 dbgarg2("Unknown type %d!\n", p->type); 1956 ret = -EINVAL;
2168 break; 1957 break;
2169 } 1958 }
2170 break; 1959 break;
@@ -2173,43 +1962,68 @@ static long __video_do_ioctl(struct file *file,
2173 { 1962 {
2174 struct v4l2_dv_timings *p = arg; 1963 struct v4l2_dv_timings *p = arg;
2175 1964
2176 if (!ops->vidioc_g_dv_timings) 1965 ret = ops->vidioc_g_dv_timings(file, fh, p);
1966 if (!ret)
1967 dbgtimings(vfd, p);
1968 break;
1969 }
1970 case VIDIOC_ENUM_DV_TIMINGS:
1971 {
1972 struct v4l2_enum_dv_timings *p = arg;
1973
1974 if (!ops->vidioc_enum_dv_timings)
2177 break; 1975 break;
2178 1976
2179 ret = ops->vidioc_g_dv_timings(file, fh, p); 1977 ret = ops->vidioc_enum_dv_timings(file, fh, p);
2180 if (!ret) { 1978 if (!ret) {
2181 switch (p->type) { 1979 dbgarg(cmd, "index=%d: ", p->index);
2182 case V4L2_DV_BT_656_1120: 1980 dbgtimings(vfd, &p->timings);
2183 dbgarg2("bt-656/1120:interlaced=%d,"
2184 " pixelclock=%lld,"
2185 " width=%d, height=%d, polarities=%x,"
2186 " hfrontporch=%d, hsync=%d,"
2187 " hbackporch=%d, vfrontporch=%d,"
2188 " vsync=%d, vbackporch=%d,"
2189 " il_vfrontporch=%d, il_vsync=%d,"
2190 " il_vbackporch=%d\n",
2191 p->bt.interlaced, p->bt.pixelclock,
2192 p->bt.width, p->bt.height,
2193 p->bt.polarities, p->bt.hfrontporch,
2194 p->bt.hsync, p->bt.hbackporch,
2195 p->bt.vfrontporch, p->bt.vsync,
2196 p->bt.vbackporch, p->bt.il_vfrontporch,
2197 p->bt.il_vsync, p->bt.il_vbackporch);
2198 break;
2199 default:
2200 dbgarg2("Unknown type %d!\n", p->type);
2201 break;
2202 }
2203 } 1981 }
2204 break; 1982 break;
2205 } 1983 }
2206 case VIDIOC_DQEVENT: 1984 case VIDIOC_QUERY_DV_TIMINGS:
2207 { 1985 {
2208 struct v4l2_event *ev = arg; 1986 struct v4l2_dv_timings *p = arg;
1987
1988 if (!ops->vidioc_query_dv_timings)
1989 break;
2209 1990
2210 if (!ops->vidioc_subscribe_event) 1991 ret = ops->vidioc_query_dv_timings(file, fh, p);
1992 if (!ret)
1993 dbgtimings(vfd, p);
1994 break;
1995 }
1996 case VIDIOC_DV_TIMINGS_CAP:
1997 {
1998 struct v4l2_dv_timings_cap *p = arg;
1999
2000 if (!ops->vidioc_dv_timings_cap)
2211 break; 2001 break;
2212 2002
2003 ret = ops->vidioc_dv_timings_cap(file, fh, p);
2004 if (ret)
2005 break;
2006 switch (p->type) {
2007 case V4L2_DV_BT_656_1120:
2008 dbgarg(cmd,
2009 "type=%d, width=%u-%u, height=%u-%u, "
2010 "pixelclock=%llu-%llu, standards=%x, capabilities=%x ",
2011 p->type,
2012 p->bt.min_width, p->bt.max_width,
2013 p->bt.min_height, p->bt.max_height,
2014 p->bt.min_pixelclock, p->bt.max_pixelclock,
2015 p->bt.standards, p->bt.capabilities);
2016 break;
2017 default:
2018 dbgarg(cmd, "unknown type ");
2019 break;
2020 }
2021 break;
2022 }
2023 case VIDIOC_DQEVENT:
2024 {
2025 struct v4l2_event *ev = arg;
2026
2213 ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK); 2027 ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK);
2214 if (ret < 0) { 2028 if (ret < 0) {
2215 dbgarg(cmd, "no pending events?"); 2029 dbgarg(cmd, "no pending events?");
@@ -2226,9 +2040,6 @@ static long __video_do_ioctl(struct file *file,
2226 { 2040 {
2227 struct v4l2_event_subscription *sub = arg; 2041 struct v4l2_event_subscription *sub = arg;
2228 2042
2229 if (!ops->vidioc_subscribe_event)
2230 break;
2231
2232 ret = ops->vidioc_subscribe_event(fh, sub); 2043 ret = ops->vidioc_subscribe_event(fh, sub);
2233 if (ret < 0) { 2044 if (ret < 0) {
2234 dbgarg(cmd, "failed, ret=%ld", ret); 2045 dbgarg(cmd, "failed, ret=%ld", ret);
@@ -2241,9 +2052,6 @@ static long __video_do_ioctl(struct file *file,
2241 { 2052 {
2242 struct v4l2_event_subscription *sub = arg; 2053 struct v4l2_event_subscription *sub = arg;
2243 2054
2244 if (!ops->vidioc_unsubscribe_event)
2245 break;
2246
2247 ret = ops->vidioc_unsubscribe_event(fh, sub); 2055 ret = ops->vidioc_unsubscribe_event(fh, sub);
2248 if (ret < 0) { 2056 if (ret < 0) {
2249 dbgarg(cmd, "failed, ret=%ld", ret); 2057 dbgarg(cmd, "failed, ret=%ld", ret);
@@ -2256,12 +2064,6 @@ static long __video_do_ioctl(struct file *file,
2256 { 2064 {
2257 struct v4l2_create_buffers *create = arg; 2065 struct v4l2_create_buffers *create = arg;
2258 2066
2259 if (!ops->vidioc_create_bufs)
2260 break;
2261 if (ret_prio) {
2262 ret = ret_prio;
2263 break;
2264 }
2265 ret = check_fmt(ops, create->format.type); 2067 ret = check_fmt(ops, create->format.type);
2266 if (ret) 2068 if (ret)
2267 break; 2069 break;
@@ -2275,8 +2077,6 @@ static long __video_do_ioctl(struct file *file,
2275 { 2077 {
2276 struct v4l2_buffer *b = arg; 2078 struct v4l2_buffer *b = arg;
2277 2079
2278 if (!ops->vidioc_prepare_buf)
2279 break;
2280 ret = check_fmt(ops, b->type); 2080 ret = check_fmt(ops, b->type);
2281 if (ret) 2081 if (ret)
2282 break; 2082 break;
@@ -2289,7 +2089,9 @@ static long __video_do_ioctl(struct file *file,
2289 default: 2089 default:
2290 if (!ops->vidioc_default) 2090 if (!ops->vidioc_default)
2291 break; 2091 break;
2292 ret = ops->vidioc_default(file, fh, ret_prio >= 0, cmd, arg); 2092 ret = ops->vidioc_default(file, fh, use_fh_prio ?
2093 v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
2094 cmd, arg);
2293 break; 2095 break;
2294 } /* switch */ 2096 } /* switch */
2295 2097
@@ -2463,7 +2265,9 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2463 err = -EFAULT; 2265 err = -EFAULT;
2464 goto out_array_args; 2266 goto out_array_args;
2465 } 2267 }
2466 if (err < 0) 2268 /* VIDIOC_QUERY_DV_TIMINGS can return an error, but still have valid
2269 results that must be returned. */
2270 if (err < 0 && cmd != VIDIOC_QUERY_DV_TIMINGS)
2467 goto out; 2271 goto out;
2468 2272
2469out_array_args: 2273out_array_args:
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 6fe88e965a8c..db6e859b93d4 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -35,14 +35,9 @@
35static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) 35static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
36{ 36{
37#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 37#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
38 /* Allocate try format and crop in the same memory block */ 38 fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL);
39 fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)) 39 if (fh->pad == NULL)
40 * sd->entity.num_pads, GFP_KERNEL);
41 if (fh->try_fmt == NULL)
42 return -ENOMEM; 40 return -ENOMEM;
43
44 fh->try_crop = (struct v4l2_rect *)
45 (fh->try_fmt + sd->entity.num_pads);
46#endif 41#endif
47 return 0; 42 return 0;
48} 43}
@@ -50,9 +45,8 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
50static void subdev_fh_free(struct v4l2_subdev_fh *fh) 45static void subdev_fh_free(struct v4l2_subdev_fh *fh)
51{ 46{
52#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 47#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
53 kfree(fh->try_fmt); 48 kfree(fh->pad);
54 fh->try_fmt = NULL; 49 fh->pad = NULL;
55 fh->try_crop = NULL;
56#endif 50#endif
57} 51}
58 52
@@ -234,6 +228,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
234 228
235 case VIDIOC_SUBDEV_G_CROP: { 229 case VIDIOC_SUBDEV_G_CROP: {
236 struct v4l2_subdev_crop *crop = arg; 230 struct v4l2_subdev_crop *crop = arg;
231 struct v4l2_subdev_selection sel;
232 int rval;
237 233
238 if (crop->which != V4L2_SUBDEV_FORMAT_TRY && 234 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
239 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) 235 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
@@ -242,11 +238,27 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
242 if (crop->pad >= sd->entity.num_pads) 238 if (crop->pad >= sd->entity.num_pads)
243 return -EINVAL; 239 return -EINVAL;
244 240
245 return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop); 241 rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
242 if (rval != -ENOIOCTLCMD)
243 return rval;
244
245 memset(&sel, 0, sizeof(sel));
246 sel.which = crop->which;
247 sel.pad = crop->pad;
248 sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL;
249
250 rval = v4l2_subdev_call(
251 sd, pad, get_selection, subdev_fh, &sel);
252
253 crop->rect = sel.r;
254
255 return rval;
246 } 256 }
247 257
248 case VIDIOC_SUBDEV_S_CROP: { 258 case VIDIOC_SUBDEV_S_CROP: {
249 struct v4l2_subdev_crop *crop = arg; 259 struct v4l2_subdev_crop *crop = arg;
260 struct v4l2_subdev_selection sel;
261 int rval;
250 262
251 if (crop->which != V4L2_SUBDEV_FORMAT_TRY && 263 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
252 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) 264 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
@@ -255,7 +267,22 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
255 if (crop->pad >= sd->entity.num_pads) 267 if (crop->pad >= sd->entity.num_pads)
256 return -EINVAL; 268 return -EINVAL;
257 269
258 return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop); 270 rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
271 if (rval != -ENOIOCTLCMD)
272 return rval;
273
274 memset(&sel, 0, sizeof(sel));
275 sel.which = crop->which;
276 sel.pad = crop->pad;
277 sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL;
278 sel.r = crop->rect;
279
280 rval = v4l2_subdev_call(
281 sd, pad, set_selection, subdev_fh, &sel);
282
283 crop->rect = sel.r;
284
285 return rval;
259 } 286 }
260 287
261 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { 288 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
@@ -293,6 +320,34 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
293 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh, 320 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
294 fie); 321 fie);
295 } 322 }
323
324 case VIDIOC_SUBDEV_G_SELECTION: {
325 struct v4l2_subdev_selection *sel = arg;
326
327 if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
328 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
329 return -EINVAL;
330
331 if (sel->pad >= sd->entity.num_pads)
332 return -EINVAL;
333
334 return v4l2_subdev_call(
335 sd, pad, get_selection, subdev_fh, sel);
336 }
337
338 case VIDIOC_SUBDEV_S_SELECTION: {
339 struct v4l2_subdev_selection *sel = arg;
340
341 if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
342 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
343 return -EINVAL;
344
345 if (sel->pad >= sd->entity.num_pads)
346 return -EINVAL;
347
348 return v4l2_subdev_call(
349 sd, pad, set_selection, subdev_fh, sel);
350 }
296#endif 351#endif
297 default: 352 default:
298 return v4l2_subdev_call(sd, core, ioctl, cmd, arg); 353 return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
@@ -332,6 +387,70 @@ const struct v4l2_file_operations v4l2_subdev_fops = {
332 .poll = subdev_poll, 387 .poll = subdev_poll,
333}; 388};
334 389
390#ifdef CONFIG_MEDIA_CONTROLLER
391int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
392 struct media_link *link,
393 struct v4l2_subdev_format *source_fmt,
394 struct v4l2_subdev_format *sink_fmt)
395{
396 if (source_fmt->format.width != sink_fmt->format.width
397 || source_fmt->format.height != sink_fmt->format.height
398 || source_fmt->format.code != sink_fmt->format.code)
399 return -EINVAL;
400
401 return 0;
402}
403EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);
404
405static int
406v4l2_subdev_link_validate_get_format(struct media_pad *pad,
407 struct v4l2_subdev_format *fmt)
408{
409 switch (media_entity_type(pad->entity)) {
410 case MEDIA_ENT_T_V4L2_SUBDEV:
411 fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
412 fmt->pad = pad->index;
413 return v4l2_subdev_call(media_entity_to_v4l2_subdev(
414 pad->entity),
415 pad, get_fmt, NULL, fmt);
416 default:
417 WARN(1, "Driver bug! Wrong media entity type %d, entity %s\n",
418 media_entity_type(pad->entity), pad->entity->name);
419 /* Fall through */
420 case MEDIA_ENT_T_DEVNODE_V4L:
421 return -EINVAL;
422 }
423}
424
425int v4l2_subdev_link_validate(struct media_link *link)
426{
427 struct v4l2_subdev *sink;
428 struct v4l2_subdev_format sink_fmt, source_fmt;
429 int rval;
430
431 rval = v4l2_subdev_link_validate_get_format(
432 link->source, &source_fmt);
433 if (rval < 0)
434 return 0;
435
436 rval = v4l2_subdev_link_validate_get_format(
437 link->sink, &sink_fmt);
438 if (rval < 0)
439 return 0;
440
441 sink = media_entity_to_v4l2_subdev(link->sink->entity);
442
443 rval = v4l2_subdev_call(sink, pad, link_validate, link,
444 &source_fmt, &sink_fmt);
445 if (rval != -ENOIOCTLCMD)
446 return rval;
447
448 return v4l2_subdev_link_validate_default(
449 sink, link, &source_fmt, &sink_fmt);
450}
451EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);
452#endif /* CONFIG_MEDIA_CONTROLLER */
453
335void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) 454void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
336{ 455{
337 INIT_LIST_HEAD(&sd->list); 456 INIT_LIST_HEAD(&sd->list);
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 20f7237b8242..308e150a39bc 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -18,6 +18,7 @@
18#include <media/v4l2-device.h> 18#include <media/v4l2-device.h>
19#include <media/v4l2-ioctl.h> 19#include <media/v4l2-ioctl.h>
20#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
21#include <media/ov7670.h>
21#include <media/videobuf-dma-sg.h> 22#include <media/videobuf-dma-sg.h>
22#include <linux/delay.h> 23#include <linux/delay.h>
23#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
@@ -1347,11 +1348,21 @@ static __devinit bool viacam_serial_is_enabled(void)
1347 return false; 1348 return false;
1348} 1349}
1349 1350
1351static struct ov7670_config sensor_cfg = {
1352 /* The XO-1.5 (only known user) clocks the camera at 90MHz. */
1353 .clock_speed = 90,
1354};
1355
1350static __devinit int viacam_probe(struct platform_device *pdev) 1356static __devinit int viacam_probe(struct platform_device *pdev)
1351{ 1357{
1352 int ret; 1358 int ret;
1353 struct i2c_adapter *sensor_adapter; 1359 struct i2c_adapter *sensor_adapter;
1354 struct viafb_dev *viadev = pdev->dev.platform_data; 1360 struct viafb_dev *viadev = pdev->dev.platform_data;
1361 struct i2c_board_info ov7670_info = {
1362 .type = "ov7670",
1363 .addr = 0x42 >> 1,
1364 .platform_data = &sensor_cfg,
1365 };
1355 1366
1356 /* 1367 /*
1357 * Note that there are actually two capture channels on 1368 * Note that there are actually two capture channels on
@@ -1433,8 +1444,8 @@ static __devinit int viacam_probe(struct platform_device *pdev)
1433 * is OLPC-specific. 0x42 assumption is ov7670-specific. 1444 * is OLPC-specific. 0x42 assumption is ov7670-specific.
1434 */ 1445 */
1435 sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31); 1446 sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
1436 cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter, 1447 cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, sensor_adapter,
1437 "ov7670", 0x42 >> 1, NULL); 1448 &ov7670_info, NULL);
1438 if (cam->sensor == NULL) { 1449 if (cam->sensor == NULL) {
1439 dev_err(&pdev->dev, "Unable to find the sensor!\n"); 1450 dev_err(&pdev->dev, "Unable to find the sensor!\n");
1440 ret = -ENODEV; 1451 ret = -ENODEV;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index de4fa4eb8844..ffdf59cfe405 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -1129,6 +1129,7 @@ unsigned int videobuf_poll_stream(struct file *file,
1129 struct videobuf_queue *q, 1129 struct videobuf_queue *q,
1130 poll_table *wait) 1130 poll_table *wait)
1131{ 1131{
1132 unsigned long req_events = poll_requested_events(wait);
1132 struct videobuf_buffer *buf = NULL; 1133 struct videobuf_buffer *buf = NULL;
1133 unsigned int rc = 0; 1134 unsigned int rc = 0;
1134 1135
@@ -1137,7 +1138,7 @@ unsigned int videobuf_poll_stream(struct file *file,
1137 if (!list_empty(&q->stream)) 1138 if (!list_empty(&q->stream))
1138 buf = list_entry(q->stream.next, 1139 buf = list_entry(q->stream.next,
1139 struct videobuf_buffer, stream); 1140 struct videobuf_buffer, stream);
1140 } else { 1141 } else if (req_events & (POLLIN | POLLRDNORM)) {
1141 if (!q->reading) 1142 if (!q->reading)
1142 __videobuf_read_start(q); 1143 __videobuf_read_start(q);
1143 if (!q->reading) { 1144 if (!q->reading) {
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index c9691115f2d2..b6b5cc1a43cb 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -27,6 +27,7 @@ struct videobuf_dma_contig_memory {
27 u32 magic; 27 u32 magic;
28 void *vaddr; 28 void *vaddr;
29 dma_addr_t dma_handle; 29 dma_addr_t dma_handle;
30 bool cached;
30 unsigned long size; 31 unsigned long size;
31}; 32};
32 33
@@ -37,8 +38,58 @@ struct videobuf_dma_contig_memory {
37 BUG(); \ 38 BUG(); \
38 } 39 }
39 40
40static void 41static int __videobuf_dc_alloc(struct device *dev,
41videobuf_vm_open(struct vm_area_struct *vma) 42 struct videobuf_dma_contig_memory *mem,
43 unsigned long size, unsigned long flags)
44{
45 mem->size = size;
46 if (mem->cached) {
47 mem->vaddr = alloc_pages_exact(mem->size, flags | GFP_DMA);
48 if (mem->vaddr) {
49 int err;
50
51 mem->dma_handle = dma_map_single(dev, mem->vaddr,
52 mem->size,
53 DMA_FROM_DEVICE);
54 err = dma_mapping_error(dev, mem->dma_handle);
55 if (err) {
56 dev_err(dev, "dma_map_single failed\n");
57
58 free_pages_exact(mem->vaddr, mem->size);
59 mem->vaddr = 0;
60 return err;
61 }
62 }
63 } else
64 mem->vaddr = dma_alloc_coherent(dev, mem->size,
65 &mem->dma_handle, flags);
66
67 if (!mem->vaddr) {
68 dev_err(dev, "memory alloc size %ld failed\n", mem->size);
69 return -ENOMEM;
70 }
71
72 dev_dbg(dev, "dma mapped data is at %p (%ld)\n", mem->vaddr, mem->size);
73
74 return 0;
75}
76
77static void __videobuf_dc_free(struct device *dev,
78 struct videobuf_dma_contig_memory *mem)
79{
80 if (mem->cached) {
81 if (!mem->vaddr)
82 return;
83 dma_unmap_single(dev, mem->dma_handle, mem->size,
84 DMA_FROM_DEVICE);
85 free_pages_exact(mem->vaddr, mem->size);
86 } else
87 dma_free_coherent(dev, mem->size, mem->vaddr, mem->dma_handle);
88
89 mem->vaddr = NULL;
90}
91
92static void videobuf_vm_open(struct vm_area_struct *vma)
42{ 93{
43 struct videobuf_mapping *map = vma->vm_private_data; 94 struct videobuf_mapping *map = vma->vm_private_data;
44 95
@@ -91,12 +142,11 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
91 dev_dbg(q->dev, "buf[%d] freeing %p\n", 142 dev_dbg(q->dev, "buf[%d] freeing %p\n",
92 i, mem->vaddr); 143 i, mem->vaddr);
93 144
94 dma_free_coherent(q->dev, mem->size, 145 __videobuf_dc_free(q->dev, mem);
95 mem->vaddr, mem->dma_handle);
96 mem->vaddr = NULL; 146 mem->vaddr = NULL;
97 } 147 }
98 148
99 q->bufs[i]->map = NULL; 149 q->bufs[i]->map = NULL;
100 q->bufs[i]->baddr = 0; 150 q->bufs[i]->baddr = 0;
101 } 151 }
102 152
@@ -107,8 +157,8 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
107} 157}
108 158
109static const struct vm_operations_struct videobuf_vm_ops = { 159static const struct vm_operations_struct videobuf_vm_ops = {
110 .open = videobuf_vm_open, 160 .open = videobuf_vm_open,
111 .close = videobuf_vm_close, 161 .close = videobuf_vm_close,
112}; 162};
113 163
114/** 164/**
@@ -178,26 +228,38 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
178 pages_done++; 228 pages_done++;
179 } 229 }
180 230
181 out_up: 231out_up:
182 up_read(&current->mm->mmap_sem); 232 up_read(&current->mm->mmap_sem);
183 233
184 return ret; 234 return ret;
185} 235}
186 236
187static struct videobuf_buffer *__videobuf_alloc_vb(size_t size) 237static struct videobuf_buffer *__videobuf_alloc_vb(size_t size, bool cached)
188{ 238{
189 struct videobuf_dma_contig_memory *mem; 239 struct videobuf_dma_contig_memory *mem;
190 struct videobuf_buffer *vb; 240 struct videobuf_buffer *vb;
191 241
192 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL); 242 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
193 if (vb) { 243 if (vb) {
194 mem = vb->priv = ((char *)vb) + size; 244 vb->priv = ((char *)vb) + size;
245 mem = vb->priv;
195 mem->magic = MAGIC_DC_MEM; 246 mem->magic = MAGIC_DC_MEM;
247 mem->cached = cached;
196 } 248 }
197 249
198 return vb; 250 return vb;
199} 251}
200 252
253static struct videobuf_buffer *__videobuf_alloc_uncached(size_t size)
254{
255 return __videobuf_alloc_vb(size, false);
256}
257
258static struct videobuf_buffer *__videobuf_alloc_cached(size_t size)
259{
260 return __videobuf_alloc_vb(size, true);
261}
262
201static void *__videobuf_to_vaddr(struct videobuf_buffer *buf) 263static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
202{ 264{
203 struct videobuf_dma_contig_memory *mem = buf->priv; 265 struct videobuf_dma_contig_memory *mem = buf->priv;
@@ -235,28 +297,32 @@ static int __videobuf_iolock(struct videobuf_queue *q,
235 return videobuf_dma_contig_user_get(mem, vb); 297 return videobuf_dma_contig_user_get(mem, vb);
236 298
237 /* allocate memory for the read() method */ 299 /* allocate memory for the read() method */
238 mem->size = PAGE_ALIGN(vb->size); 300 if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
239 mem->vaddr = dma_alloc_coherent(q->dev, mem->size, 301 GFP_KERNEL))
240 &mem->dma_handle, GFP_KERNEL);
241 if (!mem->vaddr) {
242 dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
243 mem->size);
244 return -ENOMEM; 302 return -ENOMEM;
245 }
246
247 dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
248 mem->vaddr, mem->size);
249 break; 303 break;
250 case V4L2_MEMORY_OVERLAY: 304 case V4L2_MEMORY_OVERLAY:
251 default: 305 default:
252 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", 306 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__);
253 __func__);
254 return -EINVAL; 307 return -EINVAL;
255 } 308 }
256 309
257 return 0; 310 return 0;
258} 311}
259 312
313static int __videobuf_sync(struct videobuf_queue *q,
314 struct videobuf_buffer *buf)
315{
316 struct videobuf_dma_contig_memory *mem = buf->priv;
317 BUG_ON(!mem);
318 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
319
320 dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
321 DMA_FROM_DEVICE);
322
323 return 0;
324}
325
260static int __videobuf_mmap_mapper(struct videobuf_queue *q, 326static int __videobuf_mmap_mapper(struct videobuf_queue *q,
261 struct videobuf_buffer *buf, 327 struct videobuf_buffer *buf,
262 struct vm_area_struct *vma) 328 struct vm_area_struct *vma)
@@ -265,6 +331,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
265 struct videobuf_mapping *map; 331 struct videobuf_mapping *map;
266 int retval; 332 int retval;
267 unsigned long size; 333 unsigned long size;
334 unsigned long pos, start = vma->vm_start;
335 struct page *page;
268 336
269 dev_dbg(q->dev, "%s\n", __func__); 337 dev_dbg(q->dev, "%s\n", __func__);
270 338
@@ -282,41 +350,50 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
282 BUG_ON(!mem); 350 BUG_ON(!mem);
283 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); 351 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
284 352
285 mem->size = PAGE_ALIGN(buf->bsize); 353 if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
286 mem->vaddr = dma_alloc_coherent(q->dev, mem->size, 354 GFP_KERNEL | __GFP_COMP))
287 &mem->dma_handle, GFP_KERNEL);
288 if (!mem->vaddr) {
289 dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
290 mem->size);
291 goto error; 355 goto error;
292 }
293 dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
294 mem->vaddr, mem->size);
295 356
296 /* Try to remap memory */ 357 /* Try to remap memory */
297 358
298 size = vma->vm_end - vma->vm_start; 359 size = vma->vm_end - vma->vm_start;
299 size = (size < mem->size) ? size : mem->size; 360 size = (size < mem->size) ? size : mem->size;
300 361
301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 362 if (!mem->cached)
302 retval = remap_pfn_range(vma, vma->vm_start, 363 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
303 mem->dma_handle >> PAGE_SHIFT, 364
304 size, vma->vm_page_prot); 365 pos = (unsigned long)mem->vaddr;
305 if (retval) { 366
306 dev_err(q->dev, "mmap: remap failed with error %d. ", retval); 367 while (size > 0) {
307 dma_free_coherent(q->dev, mem->size, 368 page = virt_to_page((void *)pos);
308 mem->vaddr, mem->dma_handle); 369 if (NULL == page) {
309 goto error; 370 dev_err(q->dev, "mmap: virt_to_page failed\n");
371 __videobuf_dc_free(q->dev, mem);
372 goto error;
373 }
374 retval = vm_insert_page(vma, start, page);
375 if (retval) {
376 dev_err(q->dev, "mmap: insert failed with error %d\n",
377 retval);
378 __videobuf_dc_free(q->dev, mem);
379 goto error;
380 }
381 start += PAGE_SIZE;
382 pos += PAGE_SIZE;
383
384 if (size > PAGE_SIZE)
385 size -= PAGE_SIZE;
386 else
387 size = 0;
310 } 388 }
311 389
312 vma->vm_ops = &videobuf_vm_ops; 390 vma->vm_ops = &videobuf_vm_ops;
313 vma->vm_flags |= VM_DONTEXPAND; 391 vma->vm_flags |= VM_DONTEXPAND;
314 vma->vm_private_data = map; 392 vma->vm_private_data = map;
315 393
316 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", 394 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
317 map, q, vma->vm_start, vma->vm_end, 395 map, q, vma->vm_start, vma->vm_end,
318 (long int)buf->bsize, 396 (long int)buf->bsize, vma->vm_pgoff, buf->i);
319 vma->vm_pgoff, buf->i);
320 397
321 videobuf_vm_open(vma); 398 videobuf_vm_open(vma);
322 399
@@ -328,12 +405,20 @@ error:
328} 405}
329 406
330static struct videobuf_qtype_ops qops = { 407static struct videobuf_qtype_ops qops = {
331 .magic = MAGIC_QTYPE_OPS, 408 .magic = MAGIC_QTYPE_OPS,
409 .alloc_vb = __videobuf_alloc_uncached,
410 .iolock = __videobuf_iolock,
411 .mmap_mapper = __videobuf_mmap_mapper,
412 .vaddr = __videobuf_to_vaddr,
413};
332 414
333 .alloc_vb = __videobuf_alloc_vb, 415static struct videobuf_qtype_ops qops_cached = {
334 .iolock = __videobuf_iolock, 416 .magic = MAGIC_QTYPE_OPS,
335 .mmap_mapper = __videobuf_mmap_mapper, 417 .alloc_vb = __videobuf_alloc_cached,
336 .vaddr = __videobuf_to_vaddr, 418 .iolock = __videobuf_iolock,
419 .sync = __videobuf_sync,
420 .mmap_mapper = __videobuf_mmap_mapper,
421 .vaddr = __videobuf_to_vaddr,
337}; 422};
338 423
339void videobuf_queue_dma_contig_init(struct videobuf_queue *q, 424void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
@@ -351,6 +436,20 @@ void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
351} 436}
352EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init); 437EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
353 438
439void videobuf_queue_dma_contig_init_cached(struct videobuf_queue *q,
440 const struct videobuf_queue_ops *ops,
441 struct device *dev,
442 spinlock_t *irqlock,
443 enum v4l2_buf_type type,
444 enum v4l2_field field,
445 unsigned int msize,
446 void *priv, struct mutex *ext_lock)
447{
448 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
449 priv, &qops_cached, ext_lock);
450}
451EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init_cached);
452
354dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf) 453dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
355{ 454{
356 struct videobuf_dma_contig_memory *mem = buf->priv; 455 struct videobuf_dma_contig_memory *mem = buf->priv;
@@ -389,7 +488,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
389 488
390 /* read() method */ 489 /* read() method */
391 if (mem->vaddr) { 490 if (mem->vaddr) {
392 dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); 491 __videobuf_dc_free(q->dev, mem);
393 mem->vaddr = NULL; 492 mem->vaddr = NULL;
394 } 493 }
395} 494}
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 59cb54aa2946..94d83a41381b 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -45,7 +45,6 @@ static int videobuf_dvb_thread(void *data)
45 struct videobuf_dvb *dvb = data; 45 struct videobuf_dvb *dvb = data;
46 struct videobuf_buffer *buf; 46 struct videobuf_buffer *buf;
47 unsigned long flags; 47 unsigned long flags;
48 int err;
49 void *outp; 48 void *outp;
50 49
51 dprintk("dvb thread started\n"); 50 dprintk("dvb thread started\n");
@@ -57,7 +56,7 @@ static int videobuf_dvb_thread(void *data)
57 buf = list_entry(dvb->dvbq.stream.next, 56 buf = list_entry(dvb->dvbq.stream.next,
58 struct videobuf_buffer, stream); 57 struct videobuf_buffer, stream);
59 list_del(&buf->stream); 58 list_del(&buf->stream);
60 err = videobuf_waiton(&dvb->dvbq, buf, 0, 1); 59 videobuf_waiton(&dvb->dvbq, buf, 0, 1);
61 60
62 /* no more feeds left or stop_feed() asked us to quit */ 61 /* no more feeds left or stop_feed() asked us to quit */
63 if (0 == dvb->nfeeds) 62 if (0 == dvb->nfeeds)
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 2e8f1df775b6..9d4e9edbd2e7 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -19,6 +19,9 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21 21
22#include <media/v4l2-dev.h>
23#include <media/v4l2-fh.h>
24#include <media/v4l2-event.h>
22#include <media/videobuf2-core.h> 25#include <media/videobuf2-core.h>
23 26
24static int debug; 27static int debug;
@@ -1642,32 +1645,46 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q);
1642 * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor 1645 * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
1643 * will be reported as available for writing. 1646 * will be reported as available for writing.
1644 * 1647 *
1648 * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
1649 * pending events.
1650 *
1645 * The return values from this function are intended to be directly returned 1651 * The return values from this function are intended to be directly returned
1646 * from poll handler in driver. 1652 * from poll handler in driver.
1647 */ 1653 */
1648unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) 1654unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
1649{ 1655{
1650 unsigned long flags; 1656 struct video_device *vfd = video_devdata(file);
1651 unsigned int ret; 1657 unsigned long req_events = poll_requested_events(wait);
1652 struct vb2_buffer *vb = NULL; 1658 struct vb2_buffer *vb = NULL;
1659 unsigned int res = 0;
1660 unsigned long flags;
1661
1662 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
1663 struct v4l2_fh *fh = file->private_data;
1664
1665 if (v4l2_event_pending(fh))
1666 res = POLLPRI;
1667 else if (req_events & POLLPRI)
1668 poll_wait(file, &fh->wait, wait);
1669 }
1653 1670
1654 /* 1671 /*
1655 * Start file I/O emulator only if streaming API has not been used yet. 1672 * Start file I/O emulator only if streaming API has not been used yet.
1656 */ 1673 */
1657 if (q->num_buffers == 0 && q->fileio == NULL) { 1674 if (q->num_buffers == 0 && q->fileio == NULL) {
1658 if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ)) { 1675 if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) &&
1659 ret = __vb2_init_fileio(q, 1); 1676 (req_events & (POLLIN | POLLRDNORM))) {
1660 if (ret) 1677 if (__vb2_init_fileio(q, 1))
1661 return POLLERR; 1678 return res | POLLERR;
1662 } 1679 }
1663 if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE)) { 1680 if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE) &&
1664 ret = __vb2_init_fileio(q, 0); 1681 (req_events & (POLLOUT | POLLWRNORM))) {
1665 if (ret) 1682 if (__vb2_init_fileio(q, 0))
1666 return POLLERR; 1683 return res | POLLERR;
1667 /* 1684 /*
1668 * Write to OUTPUT queue can be done immediately. 1685 * Write to OUTPUT queue can be done immediately.
1669 */ 1686 */
1670 return POLLOUT | POLLWRNORM; 1687 return res | POLLOUT | POLLWRNORM;
1671 } 1688 }
1672 } 1689 }
1673 1690
@@ -1675,7 +1692,7 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
1675 * There is nothing to wait for if no buffers have already been queued. 1692 * There is nothing to wait for if no buffers have already been queued.
1676 */ 1693 */
1677 if (list_empty(&q->queued_list)) 1694 if (list_empty(&q->queued_list))
1678 return POLLERR; 1695 return res | POLLERR;
1679 1696
1680 poll_wait(file, &q->done_wq, wait); 1697 poll_wait(file, &q->done_wq, wait);
1681 1698
@@ -1690,10 +1707,11 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
1690 1707
1691 if (vb && (vb->state == VB2_BUF_STATE_DONE 1708 if (vb && (vb->state == VB2_BUF_STATE_DONE
1692 || vb->state == VB2_BUF_STATE_ERROR)) { 1709 || vb->state == VB2_BUF_STATE_ERROR)) {
1693 return (V4L2_TYPE_IS_OUTPUT(q->type)) ? POLLOUT | POLLWRNORM : 1710 return (V4L2_TYPE_IS_OUTPUT(q->type)) ?
1694 POLLIN | POLLRDNORM; 1711 res | POLLOUT | POLLWRNORM :
1712 res | POLLIN | POLLRDNORM;
1695 } 1713 }
1696 return 0; 1714 return res;
1697} 1715}
1698EXPORT_SYMBOL_GPL(vb2_poll); 1716EXPORT_SYMBOL_GPL(vb2_poll);
1699 1717
@@ -1839,7 +1857,6 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
1839 * (multiplane buffers are not supported). 1857 * (multiplane buffers are not supported).
1840 */ 1858 */
1841 if (q->bufs[0]->num_planes != 1) { 1859 if (q->bufs[0]->num_planes != 1) {
1842 fileio->req.count = 0;
1843 ret = -EBUSY; 1860 ret = -EBUSY;
1844 goto err_reqbufs; 1861 goto err_reqbufs;
1845 } 1862 }
@@ -1886,6 +1903,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
1886 return ret; 1903 return ret;
1887 1904
1888err_reqbufs: 1905err_reqbufs:
1906 fileio->req.count = 0;
1889 vb2_reqbufs(q, &fileio->req); 1907 vb2_reqbufs(q, &fileio->req);
1890 1908
1891err_kfree: 1909err_kfree:
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 5e8b0710105b..0960d7f0d394 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -95,6 +95,16 @@ static struct vivi_fmt formats[] = {
95 .depth = 16, 95 .depth = 16,
96 }, 96 },
97 { 97 {
98 .name = "4:2:2, packed, YVYU",
99 .fourcc = V4L2_PIX_FMT_YVYU,
100 .depth = 16,
101 },
102 {
103 .name = "4:2:2, packed, VYUY",
104 .fourcc = V4L2_PIX_FMT_VYUY,
105 .depth = 16,
106 },
107 {
98 .name = "RGB565 (LE)", 108 .name = "RGB565 (LE)",
99 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 109 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
100 .depth = 16, 110 .depth = 16,
@@ -114,6 +124,26 @@ static struct vivi_fmt formats[] = {
114 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ 124 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
115 .depth = 16, 125 .depth = 16,
116 }, 126 },
127 {
128 .name = "RGB24 (LE)",
129 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
130 .depth = 24,
131 },
132 {
133 .name = "RGB24 (BE)",
134 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
135 .depth = 24,
136 },
137 {
138 .name = "RGB32 (LE)",
139 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
140 .depth = 32,
141 },
142 {
143 .name = "RGB32 (BE)",
144 .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */
145 .depth = 32,
146 },
117}; 147};
118 148
119static struct vivi_fmt *get_format(struct v4l2_format *f) 149static struct vivi_fmt *get_format(struct v4l2_format *f)
@@ -170,6 +200,7 @@ struct vivi_dev {
170 struct v4l2_ctrl *gain; 200 struct v4l2_ctrl *gain;
171 }; 201 };
172 struct v4l2_ctrl *volume; 202 struct v4l2_ctrl *volume;
203 struct v4l2_ctrl *alpha;
173 struct v4l2_ctrl *button; 204 struct v4l2_ctrl *button;
174 struct v4l2_ctrl *boolean; 205 struct v4l2_ctrl *boolean;
175 struct v4l2_ctrl *int32; 206 struct v4l2_ctrl *int32;
@@ -177,6 +208,7 @@ struct vivi_dev {
177 struct v4l2_ctrl *menu; 208 struct v4l2_ctrl *menu;
178 struct v4l2_ctrl *string; 209 struct v4l2_ctrl *string;
179 struct v4l2_ctrl *bitmask; 210 struct v4l2_ctrl *bitmask;
211 struct v4l2_ctrl *int_menu;
180 212
181 spinlock_t slock; 213 spinlock_t slock;
182 struct mutex mutex; 214 struct mutex mutex;
@@ -203,8 +235,10 @@ struct vivi_dev {
203 enum v4l2_field field; 235 enum v4l2_field field;
204 unsigned int field_count; 236 unsigned int field_count;
205 237
206 u8 bars[9][3]; 238 u8 bars[9][3];
207 u8 line[MAX_WIDTH * 4]; 239 u8 line[MAX_WIDTH * 8];
240 unsigned int pixelsize;
241 u8 alpha_component;
208}; 242};
209 243
210/* ------------------------------------------------------------------ 244/* ------------------------------------------------------------------
@@ -283,6 +317,8 @@ static void precalculate_bars(struct vivi_dev *dev)
283 switch (dev->fmt->fourcc) { 317 switch (dev->fmt->fourcc) {
284 case V4L2_PIX_FMT_YUYV: 318 case V4L2_PIX_FMT_YUYV:
285 case V4L2_PIX_FMT_UYVY: 319 case V4L2_PIX_FMT_UYVY:
320 case V4L2_PIX_FMT_YVYU:
321 case V4L2_PIX_FMT_VYUY:
286 is_yuv = 1; 322 is_yuv = 1;
287 break; 323 break;
288 case V4L2_PIX_FMT_RGB565: 324 case V4L2_PIX_FMT_RGB565:
@@ -297,6 +333,11 @@ static void precalculate_bars(struct vivi_dev *dev)
297 g >>= 3; 333 g >>= 3;
298 b >>= 3; 334 b >>= 3;
299 break; 335 break;
336 case V4L2_PIX_FMT_RGB24:
337 case V4L2_PIX_FMT_BGR24:
338 case V4L2_PIX_FMT_RGB32:
339 case V4L2_PIX_FMT_BGR32:
340 break;
300 } 341 }
301 342
302 if (is_yuv) { 343 if (is_yuv) {
@@ -316,9 +357,11 @@ static void precalculate_bars(struct vivi_dev *dev)
316#define TSTAMP_INPUT_X 10 357#define TSTAMP_INPUT_X 10
317#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) 358#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
318 359
319static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) 360/* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
361static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
320{ 362{
321 u8 r_y, g_u, b_v; 363 u8 r_y, g_u, b_v;
364 u8 alpha = dev->alpha_component;
322 int color; 365 int color;
323 u8 *p; 366 u8 *p;
324 367
@@ -326,46 +369,56 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
326 g_u = dev->bars[colorpos][1]; /* G or precalculated U */ 369 g_u = dev->bars[colorpos][1]; /* G or precalculated U */
327 b_v = dev->bars[colorpos][2]; /* B or precalculated V */ 370 b_v = dev->bars[colorpos][2]; /* B or precalculated V */
328 371
329 for (color = 0; color < 4; color++) { 372 for (color = 0; color < dev->pixelsize; color++) {
330 p = buf + color; 373 p = buf + color;
331 374
332 switch (dev->fmt->fourcc) { 375 switch (dev->fmt->fourcc) {
333 case V4L2_PIX_FMT_YUYV: 376 case V4L2_PIX_FMT_YUYV:
334 switch (color) { 377 switch (color) {
335 case 0: 378 case 0:
336 case 2:
337 *p = r_y; 379 *p = r_y;
338 break; 380 break;
339 case 1: 381 case 1:
340 *p = g_u; 382 *p = odd ? b_v : g_u;
341 break;
342 case 3:
343 *p = b_v;
344 break; 383 break;
345 } 384 }
346 break; 385 break;
347 case V4L2_PIX_FMT_UYVY: 386 case V4L2_PIX_FMT_UYVY:
348 switch (color) { 387 switch (color) {
388 case 0:
389 *p = odd ? b_v : g_u;
390 break;
349 case 1: 391 case 1:
350 case 3:
351 *p = r_y; 392 *p = r_y;
352 break; 393 break;
394 }
395 break;
396 case V4L2_PIX_FMT_YVYU:
397 switch (color) {
353 case 0: 398 case 0:
354 *p = g_u; 399 *p = r_y;
355 break; 400 break;
356 case 2: 401 case 1:
357 *p = b_v; 402 *p = odd ? g_u : b_v;
403 break;
404 }
405 break;
406 case V4L2_PIX_FMT_VYUY:
407 switch (color) {
408 case 0:
409 *p = odd ? g_u : b_v;
410 break;
411 case 1:
412 *p = r_y;
358 break; 413 break;
359 } 414 }
360 break; 415 break;
361 case V4L2_PIX_FMT_RGB565: 416 case V4L2_PIX_FMT_RGB565:
362 switch (color) { 417 switch (color) {
363 case 0: 418 case 0:
364 case 2:
365 *p = (g_u << 5) | b_v; 419 *p = (g_u << 5) | b_v;
366 break; 420 break;
367 case 1: 421 case 1:
368 case 3:
369 *p = (r_y << 3) | (g_u >> 3); 422 *p = (r_y << 3) | (g_u >> 3);
370 break; 423 break;
371 } 424 }
@@ -373,11 +426,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
373 case V4L2_PIX_FMT_RGB565X: 426 case V4L2_PIX_FMT_RGB565X:
374 switch (color) { 427 switch (color) {
375 case 0: 428 case 0:
376 case 2:
377 *p = (r_y << 3) | (g_u >> 3); 429 *p = (r_y << 3) | (g_u >> 3);
378 break; 430 break;
379 case 1: 431 case 1:
380 case 3:
381 *p = (g_u << 5) | b_v; 432 *p = (g_u << 5) | b_v;
382 break; 433 break;
383 } 434 }
@@ -385,24 +436,78 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
385 case V4L2_PIX_FMT_RGB555: 436 case V4L2_PIX_FMT_RGB555:
386 switch (color) { 437 switch (color) {
387 case 0: 438 case 0:
388 case 2:
389 *p = (g_u << 5) | b_v; 439 *p = (g_u << 5) | b_v;
390 break; 440 break;
391 case 1: 441 case 1:
392 case 3: 442 *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
393 *p = (r_y << 2) | (g_u >> 3);
394 break; 443 break;
395 } 444 }
396 break; 445 break;
397 case V4L2_PIX_FMT_RGB555X: 446 case V4L2_PIX_FMT_RGB555X:
398 switch (color) { 447 switch (color) {
399 case 0: 448 case 0:
449 *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
450 break;
451 case 1:
452 *p = (g_u << 5) | b_v;
453 break;
454 }
455 break;
456 case V4L2_PIX_FMT_RGB24:
457 switch (color) {
458 case 0:
459 *p = r_y;
460 break;
461 case 1:
462 *p = g_u;
463 break;
400 case 2: 464 case 2:
401 *p = (r_y << 2) | (g_u >> 3); 465 *p = b_v;
466 break;
467 }
468 break;
469 case V4L2_PIX_FMT_BGR24:
470 switch (color) {
471 case 0:
472 *p = b_v;
402 break; 473 break;
403 case 1: 474 case 1:
475 *p = g_u;
476 break;
477 case 2:
478 *p = r_y;
479 break;
480 }
481 break;
482 case V4L2_PIX_FMT_RGB32:
483 switch (color) {
484 case 0:
485 *p = alpha;
486 break;
487 case 1:
488 *p = r_y;
489 break;
490 case 2:
491 *p = g_u;
492 break;
404 case 3: 493 case 3:
405 *p = (g_u << 5) | b_v; 494 *p = b_v;
495 break;
496 }
497 break;
498 case V4L2_PIX_FMT_BGR32:
499 switch (color) {
500 case 0:
501 *p = b_v;
502 break;
503 case 1:
504 *p = g_u;
505 break;
506 case 2:
507 *p = r_y;
508 break;
509 case 3:
510 *p = alpha;
406 break; 511 break;
407 } 512 }
408 break; 513 break;
@@ -414,10 +519,10 @@ static void precalculate_line(struct vivi_dev *dev)
414{ 519{
415 int w; 520 int w;
416 521
417 for (w = 0; w < dev->width * 2; w += 2) { 522 for (w = 0; w < dev->width * 2; w++) {
418 int colorpos = (w / (dev->width / 8) % 8); 523 int colorpos = w / (dev->width / 8) % 8;
419 524
420 gen_twopix(dev, dev->line + w * 2, colorpos); 525 gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1);
421 } 526 }
422} 527}
423 528
@@ -433,7 +538,7 @@ static void gen_text(struct vivi_dev *dev, char *basep,
433 /* Print stream time */ 538 /* Print stream time */
434 for (line = y; line < y + 16; line++) { 539 for (line = y; line < y + 16; line++) {
435 int j = 0; 540 int j = 0;
436 char *pos = basep + line * dev->width * 2 + x * 2; 541 char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize;
437 char *s; 542 char *s;
438 543
439 for (s = text; *s; s++) { 544 for (s = text; *s; s++) {
@@ -443,9 +548,9 @@ static void gen_text(struct vivi_dev *dev, char *basep,
443 for (i = 0; i < 7; i++, j++) { 548 for (i = 0; i < 7; i++, j++) {
444 /* Draw white font on black background */ 549 /* Draw white font on black background */
445 if (chr & (1 << (7 - i))) 550 if (chr & (1 << (7 - i)))
446 gen_twopix(dev, pos + j * 2, WHITE); 551 gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1);
447 else 552 else
448 gen_twopix(dev, pos + j * 2, TEXT_BLACK); 553 gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1);
449 } 554 }
450 } 555 }
451 } 556 }
@@ -466,7 +571,9 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
466 return; 571 return;
467 572
468 for (h = 0; h < hmax; h++) 573 for (h = 0; h < hmax; h++)
469 memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2); 574 memcpy(vbuf + h * wmax * dev->pixelsize,
575 dev->line + (dev->mv_count % wmax) * dev->pixelsize,
576 wmax * dev->pixelsize);
470 577
471 /* Updates stream time */ 578 /* Updates stream time */
472 579
@@ -484,15 +591,16 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
484 gen_text(dev, vbuf, line++ * 16, 16, str); 591 gen_text(dev, vbuf, line++ * 16, 16, str);
485 592
486 gain = v4l2_ctrl_g_ctrl(dev->gain); 593 gain = v4l2_ctrl_g_ctrl(dev->gain);
487 mutex_lock(&dev->ctrl_handler.lock); 594 mutex_lock(dev->ctrl_handler.lock);
488 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", 595 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
489 dev->brightness->cur.val, 596 dev->brightness->cur.val,
490 dev->contrast->cur.val, 597 dev->contrast->cur.val,
491 dev->saturation->cur.val, 598 dev->saturation->cur.val,
492 dev->hue->cur.val); 599 dev->hue->cur.val);
493 gen_text(dev, vbuf, line++ * 16, 16, str); 600 gen_text(dev, vbuf, line++ * 16, 16, str);
494 snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d ", 601 snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d, alpha 0x%02x ",
495 dev->autogain->cur.val, gain, dev->volume->cur.val); 602 dev->autogain->cur.val, gain, dev->volume->cur.val,
603 dev->alpha->cur.val);
496 gen_text(dev, vbuf, line++ * 16, 16, str); 604 gen_text(dev, vbuf, line++ * 16, 16, str);
497 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", 605 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
498 dev->int32->cur.val, 606 dev->int32->cur.val,
@@ -503,8 +611,12 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
503 dev->boolean->cur.val, 611 dev->boolean->cur.val,
504 dev->menu->qmenu[dev->menu->cur.val], 612 dev->menu->qmenu[dev->menu->cur.val],
505 dev->string->cur.string); 613 dev->string->cur.string);
506 mutex_unlock(&dev->ctrl_handler.lock);
507 gen_text(dev, vbuf, line++ * 16, 16, str); 614 gen_text(dev, vbuf, line++ * 16, 16, str);
615 snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
616 dev->int_menu->qmenu_int[dev->int_menu->cur.val],
617 dev->int_menu->cur.val);
618 gen_text(dev, vbuf, line++ * 16, 16, str);
619 mutex_unlock(dev->ctrl_handler.lock);
508 if (dev->button_pressed) { 620 if (dev->button_pressed) {
509 dev->button_pressed--; 621 dev->button_pressed--;
510 snprintf(str, sizeof(str), " button pressed!"); 622 snprintf(str, sizeof(str), " button pressed!");
@@ -657,7 +769,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
657 struct vivi_dev *dev = vb2_get_drv_priv(vq); 769 struct vivi_dev *dev = vb2_get_drv_priv(vq);
658 unsigned long size; 770 unsigned long size;
659 771
660 size = dev->width * dev->height * 2; 772 size = dev->width * dev->height * dev->pixelsize;
661 773
662 if (0 == *nbuffers) 774 if (0 == *nbuffers)
663 *nbuffers = 32; 775 *nbuffers = 32;
@@ -721,7 +833,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
721 dev->height < 32 || dev->height > MAX_HEIGHT) 833 dev->height < 32 || dev->height > MAX_HEIGHT)
722 return -EINVAL; 834 return -EINVAL;
723 835
724 size = dev->width * dev->height * 2; 836 size = dev->width * dev->height * dev->pixelsize;
725 if (vb2_plane_size(vb, 0) < size) { 837 if (vb2_plane_size(vb, 0) < size) {
726 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n", 838 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
727 __func__, vb2_plane_size(vb, 0), size); 839 __func__, vb2_plane_size(vb, 0), size);
@@ -915,6 +1027,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
915 } 1027 }
916 1028
917 dev->fmt = get_format(f); 1029 dev->fmt = get_format(f);
1030 dev->pixelsize = dev->fmt->depth / 8;
918 dev->width = f->fmt.pix.width; 1031 dev->width = f->fmt.pix.width;
919 dev->height = f->fmt.pix.height; 1032 dev->height = f->fmt.pix.height;
920 dev->field = f->fmt.pix.field; 1033 dev->field = f->fmt.pix.field;
@@ -1016,8 +1129,15 @@ static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
1016{ 1129{
1017 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler); 1130 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
1018 1131
1019 if (ctrl == dev->button) 1132 switch (ctrl->id) {
1020 dev->button_pressed = 30; 1133 case V4L2_CID_ALPHA_COMPONENT:
1134 dev->alpha_component = ctrl->val;
1135 break;
1136 default:
1137 if (ctrl == dev->button)
1138 dev->button_pressed = 30;
1139 break;
1140 }
1021 return 0; 1141 return 0;
1022} 1142}
1023 1143
@@ -1039,17 +1159,10 @@ static unsigned int
1039vivi_poll(struct file *file, struct poll_table_struct *wait) 1159vivi_poll(struct file *file, struct poll_table_struct *wait)
1040{ 1160{
1041 struct vivi_dev *dev = video_drvdata(file); 1161 struct vivi_dev *dev = video_drvdata(file);
1042 struct v4l2_fh *fh = file->private_data;
1043 struct vb2_queue *q = &dev->vb_vidq; 1162 struct vb2_queue *q = &dev->vb_vidq;
1044 unsigned int res;
1045 1163
1046 dprintk(dev, 1, "%s\n", __func__); 1164 dprintk(dev, 1, "%s\n", __func__);
1047 res = vb2_poll(q, file, wait); 1165 return vb2_poll(q, file, wait);
1048 if (v4l2_event_pending(fh))
1049 res |= POLLPRI;
1050 else
1051 poll_wait(file, &fh->wait, wait);
1052 return res;
1053} 1166}
1054 1167
1055static int vivi_close(struct file *file) 1168static int vivi_close(struct file *file)
@@ -1165,6 +1278,22 @@ static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
1165 .step = 0, 1278 .step = 0,
1166}; 1279};
1167 1280
1281static const s64 vivi_ctrl_int_menu_values[] = {
1282 1, 1, 2, 3, 5, 8, 13, 21, 42,
1283};
1284
1285static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
1286 .ops = &vivi_ctrl_ops,
1287 .id = VIVI_CID_CUSTOM_BASE + 7,
1288 .name = "Integer menu",
1289 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
1290 .min = 1,
1291 .max = 8,
1292 .def = 4,
1293 .menu_skip_mask = 0x02,
1294 .qmenu_int = vivi_ctrl_int_menu_values,
1295};
1296
1168static const struct v4l2_file_operations vivi_fops = { 1297static const struct v4l2_file_operations vivi_fops = {
1169 .owner = THIS_MODULE, 1298 .owner = THIS_MODULE,
1170 .open = v4l2_fh_open, 1299 .open = v4l2_fh_open,
@@ -1252,6 +1381,7 @@ static int __init vivi_create_instance(int inst)
1252 dev->fmt = &formats[0]; 1381 dev->fmt = &formats[0];
1253 dev->width = 640; 1382 dev->width = 640;
1254 dev->height = 480; 1383 dev->height = 480;
1384 dev->pixelsize = dev->fmt->depth / 8;
1255 hdl = &dev->ctrl_handler; 1385 hdl = &dev->ctrl_handler;
1256 v4l2_ctrl_handler_init(hdl, 11); 1386 v4l2_ctrl_handler_init(hdl, 11);
1257 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, 1387 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
@@ -1268,6 +1398,8 @@ static int __init vivi_create_instance(int inst)
1268 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1398 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1269 dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, 1399 dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1270 V4L2_CID_GAIN, 0, 255, 1, 100); 1400 V4L2_CID_GAIN, 0, 255, 1, 100);
1401 dev->alpha = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1402 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1271 dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL); 1403 dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
1272 dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL); 1404 dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
1273 dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL); 1405 dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
@@ -1275,6 +1407,7 @@ static int __init vivi_create_instance(int inst)
1275 dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL); 1407 dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
1276 dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL); 1408 dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
1277 dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL); 1409 dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
1410 dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
1278 if (hdl->error) { 1411 if (hdl->error) {
1279 ret = hdl->error; 1412 ret = hdl->error;
1280 goto unreg_dev; 1413 goto unreg_dev;
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 7fd7ac567e1a..db2a6003a1c3 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -62,6 +62,9 @@
62#include <media/v4l2-common.h> 62#include <media/v4l2-common.h>
63#include <media/v4l2-ioctl.h> 63#include <media/v4l2-ioctl.h>
64#include <media/v4l2-device.h> 64#include <media/v4l2-device.h>
65#include <media/v4l2-fh.h>
66#include <media/v4l2-ctrls.h>
67#include <media/v4l2-event.h>
65#include <linux/parport.h> 68#include <linux/parport.h>
66 69
67/*#define DEBUG*/ /* Undef me for production */ 70/*#define DEBUG*/ /* Undef me for production */
@@ -104,6 +107,7 @@
104 107
105struct w9966 { 108struct w9966 {
106 struct v4l2_device v4l2_dev; 109 struct v4l2_device v4l2_dev;
110 struct v4l2_ctrl_handler hdl;
107 unsigned char dev_state; 111 unsigned char dev_state;
108 unsigned char i2c_state; 112 unsigned char i2c_state;
109 unsigned short ppmode; 113 unsigned short ppmode;
@@ -567,7 +571,8 @@ static int cam_querycap(struct file *file, void *priv,
567 strlcpy(vcap->driver, cam->v4l2_dev.name, sizeof(vcap->driver)); 571 strlcpy(vcap->driver, cam->v4l2_dev.name, sizeof(vcap->driver));
568 strlcpy(vcap->card, W9966_DRIVERNAME, sizeof(vcap->card)); 572 strlcpy(vcap->card, W9966_DRIVERNAME, sizeof(vcap->card));
569 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); 573 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
570 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 574 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
575 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
571 return 0; 576 return 0;
572} 577}
573 578
@@ -595,67 +600,25 @@ static int cam_s_input(struct file *file, void *fh, unsigned int inp)
595 return (inp > 0) ? -EINVAL : 0; 600 return (inp > 0) ? -EINVAL : 0;
596} 601}
597 602
598static int cam_queryctrl(struct file *file, void *priv, 603static int cam_s_ctrl(struct v4l2_ctrl *ctrl)
599 struct v4l2_queryctrl *qc)
600{ 604{
601 switch (qc->id) { 605 struct w9966 *cam =
602 case V4L2_CID_BRIGHTNESS: 606 container_of(ctrl->handler, struct w9966, hdl);
603 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
604 case V4L2_CID_CONTRAST:
605 return v4l2_ctrl_query_fill(qc, -64, 64, 1, 64);
606 case V4L2_CID_SATURATION:
607 return v4l2_ctrl_query_fill(qc, -64, 64, 1, 64);
608 case V4L2_CID_HUE:
609 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
610 }
611 return -EINVAL;
612}
613
614static int cam_g_ctrl(struct file *file, void *priv,
615 struct v4l2_control *ctrl)
616{
617 struct w9966 *cam = video_drvdata(file);
618 int ret = 0;
619
620 switch (ctrl->id) {
621 case V4L2_CID_BRIGHTNESS:
622 ctrl->value = cam->brightness;
623 break;
624 case V4L2_CID_CONTRAST:
625 ctrl->value = cam->contrast;
626 break;
627 case V4L2_CID_SATURATION:
628 ctrl->value = cam->color;
629 break;
630 case V4L2_CID_HUE:
631 ctrl->value = cam->hue;
632 break;
633 default:
634 ret = -EINVAL;
635 break;
636 }
637 return ret;
638}
639
640static int cam_s_ctrl(struct file *file, void *priv,
641 struct v4l2_control *ctrl)
642{
643 struct w9966 *cam = video_drvdata(file);
644 int ret = 0; 607 int ret = 0;
645 608
646 mutex_lock(&cam->lock); 609 mutex_lock(&cam->lock);
647 switch (ctrl->id) { 610 switch (ctrl->id) {
648 case V4L2_CID_BRIGHTNESS: 611 case V4L2_CID_BRIGHTNESS:
649 cam->brightness = ctrl->value; 612 cam->brightness = ctrl->val;
650 break; 613 break;
651 case V4L2_CID_CONTRAST: 614 case V4L2_CID_CONTRAST:
652 cam->contrast = ctrl->value; 615 cam->contrast = ctrl->val;
653 break; 616 break;
654 case V4L2_CID_SATURATION: 617 case V4L2_CID_SATURATION:
655 cam->color = ctrl->value; 618 cam->color = ctrl->val;
656 break; 619 break;
657 case V4L2_CID_HUE: 620 case V4L2_CID_HUE:
658 cam->hue = ctrl->value; 621 cam->hue = ctrl->val;
659 break; 622 break;
660 default: 623 default:
661 ret = -EINVAL; 624 ret = -EINVAL;
@@ -813,6 +776,9 @@ out:
813 776
814static const struct v4l2_file_operations w9966_fops = { 777static const struct v4l2_file_operations w9966_fops = {
815 .owner = THIS_MODULE, 778 .owner = THIS_MODULE,
779 .open = v4l2_fh_open,
780 .release = v4l2_fh_release,
781 .poll = v4l2_ctrl_poll,
816 .unlocked_ioctl = video_ioctl2, 782 .unlocked_ioctl = video_ioctl2,
817 .read = w9966_v4l_read, 783 .read = w9966_v4l_read,
818}; 784};
@@ -822,13 +788,17 @@ static const struct v4l2_ioctl_ops w9966_ioctl_ops = {
822 .vidioc_g_input = cam_g_input, 788 .vidioc_g_input = cam_g_input,
823 .vidioc_s_input = cam_s_input, 789 .vidioc_s_input = cam_s_input,
824 .vidioc_enum_input = cam_enum_input, 790 .vidioc_enum_input = cam_enum_input,
825 .vidioc_queryctrl = cam_queryctrl,
826 .vidioc_g_ctrl = cam_g_ctrl,
827 .vidioc_s_ctrl = cam_s_ctrl,
828 .vidioc_enum_fmt_vid_cap = cam_enum_fmt_vid_cap, 791 .vidioc_enum_fmt_vid_cap = cam_enum_fmt_vid_cap,
829 .vidioc_g_fmt_vid_cap = cam_g_fmt_vid_cap, 792 .vidioc_g_fmt_vid_cap = cam_g_fmt_vid_cap,
830 .vidioc_s_fmt_vid_cap = cam_s_fmt_vid_cap, 793 .vidioc_s_fmt_vid_cap = cam_s_fmt_vid_cap,
831 .vidioc_try_fmt_vid_cap = cam_try_fmt_vid_cap, 794 .vidioc_try_fmt_vid_cap = cam_try_fmt_vid_cap,
795 .vidioc_log_status = v4l2_ctrl_log_status,
796 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
797 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
798};
799
800static const struct v4l2_ctrl_ops cam_ctrl_ops = {
801 .s_ctrl = cam_s_ctrl,
832}; 802};
833 803
834 804
@@ -849,6 +819,20 @@ static int w9966_init(struct w9966 *cam, struct parport *port)
849 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 819 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
850 return -1; 820 return -1;
851 } 821 }
822
823 v4l2_ctrl_handler_init(&cam->hdl, 4);
824 v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
825 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
826 v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
827 V4L2_CID_CONTRAST, -64, 64, 1, 64);
828 v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
829 V4L2_CID_SATURATION, -64, 64, 1, 64);
830 v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
831 V4L2_CID_HUE, -128, 127, 1, 0);
832 if (cam->hdl.error) {
833 v4l2_err(v4l2_dev, "couldn't register controls\n");
834 return -1;
835 }
852 cam->pport = port; 836 cam->pport = port;
853 cam->brightness = 128; 837 cam->brightness = 128;
854 cam->contrast = 64; 838 cam->contrast = 64;
@@ -898,6 +882,8 @@ static int w9966_init(struct w9966 *cam, struct parport *port)
898 cam->vdev.fops = &w9966_fops; 882 cam->vdev.fops = &w9966_fops;
899 cam->vdev.ioctl_ops = &w9966_ioctl_ops; 883 cam->vdev.ioctl_ops = &w9966_ioctl_ops;
900 cam->vdev.release = video_device_release_empty; 884 cam->vdev.release = video_device_release_empty;
885 cam->vdev.ctrl_handler = &cam->hdl;
886 set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
901 video_set_drvdata(&cam->vdev, cam); 887 video_set_drvdata(&cam->vdev, cam);
902 888
903 mutex_init(&cam->lock); 889 mutex_init(&cam->lock);
@@ -923,6 +909,8 @@ static void w9966_term(struct w9966 *cam)
923 w9966_set_state(cam, W9966_STATE_VDEV, 0); 909 w9966_set_state(cam, W9966_STATE_VDEV, 0);
924 } 910 }
925 911
912 v4l2_ctrl_handler_free(&cam->hdl);
913
926 /* Terminate from IEEE1284 mode and release pdev block */ 914 /* Terminate from IEEE1284 mode and release pdev block */
927 if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { 915 if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
928 w9966_pdev_claim(cam); 916 w9966_pdev_claim(cam);
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index e86173bd1327..a4cd504b8eee 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -542,11 +542,9 @@ void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count)
542 u32 *mask; 542 u32 *mask;
543 int x, y, width, height; 543 int x, y, width, height;
544 unsigned i, j, k; 544 unsigned i, j, k;
545 u32 reg;
546 545
547 /* fill mask with one bits */ 546 /* fill mask with one bits */
548 memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT); 547 memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);
549 reg = 0;
550 548
551 for (i = 0; i < count; ++i) { 549 for (i = 0; i < count; ++i) {
552 /* pick up local copy of clip */ 550 /* pick up local copy of clip */
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 4c09ab781ec3..c57310931810 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1131,8 +1131,14 @@ static int setup_fbuffer(struct zoran_fh *fh,
1131} 1131}
1132 1132
1133 1133
1134static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height, 1134static int setup_window(struct zoran_fh *fh,
1135 struct v4l2_clip __user *clips, int clipcount, void __user *bitmap) 1135 int x,
1136 int y,
1137 int width,
1138 int height,
1139 struct v4l2_clip __user *clips,
1140 unsigned int clipcount,
1141 void __user *bitmap)
1136{ 1142{
1137 struct zoran *zr = fh->zr; 1143 struct zoran *zr = fh->zr;
1138 struct v4l2_clip *vcp = NULL; 1144 struct v4l2_clip *vcp = NULL;
@@ -1155,6 +1161,14 @@ static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height
1155 return -EINVAL; 1161 return -EINVAL;
1156 } 1162 }
1157 1163
1164 if (clipcount > 2048) {
1165 dprintk(1,
1166 KERN_ERR
1167 "%s: %s - invalid clipcount\n",
1168 ZR_DEVNAME(zr), __func__);
1169 return -EINVAL;
1170 }
1171
1158 /* 1172 /*
1159 * The video front end needs 4-byte alinged line sizes, we correct that 1173 * The video front end needs 4-byte alinged line sizes, we correct that
1160 * silently here if necessary 1174 * silently here if necessary
@@ -1218,7 +1232,7 @@ static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height
1218 (width * height + 7) / 8)) { 1232 (width * height + 7) / 8)) {
1219 return -EFAULT; 1233 return -EFAULT;
1220 } 1234 }
1221 } else if (clipcount > 0) { 1235 } else if (clipcount) {
1222 /* write our own bitmap from the clips */ 1236 /* write our own bitmap from the clips */
1223 vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4)); 1237 vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4));
1224 if (vcp == NULL) { 1238 if (vcp == NULL) {
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index cd2e39fc4bf0..e44cb330bbc8 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -507,14 +507,12 @@ static void zr364xx_fillbuff(struct zr364xx_camera *cam,
507 const char *tmpbuf; 507 const char *tmpbuf;
508 char *vbuf = videobuf_to_vmalloc(&buf->vb); 508 char *vbuf = videobuf_to_vmalloc(&buf->vb);
509 unsigned long last_frame; 509 unsigned long last_frame;
510 struct zr364xx_framei *frm;
511 510
512 if (!vbuf) 511 if (!vbuf)
513 return; 512 return;
514 513
515 last_frame = cam->last_frame; 514 last_frame = cam->last_frame;
516 if (last_frame != -1) { 515 if (last_frame != -1) {
517 frm = &cam->buffer.frame[last_frame];
518 tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits; 516 tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits;
519 switch (buf->fmt->fourcc) { 517 switch (buf->fmt->fourcc) {
520 case V4L2_PIX_FMT_JPEG: 518 case V4L2_PIX_FMT_JPEG:
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 9f1f27e7c86e..4511420849bc 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -269,7 +269,7 @@ out:
269 return ret; 269 return ret;
270} 270}
271 271
272static inline unsigned long calc_vm_may_flags(unsigned long prot) 272static inline vm_flags_t calc_vm_may_flags(unsigned long prot)
273{ 273{
274 return _calc_vm_trans(prot, PROT_READ, VM_MAYREAD) | 274 return _calc_vm_trans(prot, PROT_READ, VM_MAYREAD) |
275 _calc_vm_trans(prot, PROT_WRITE, VM_MAYWRITE) | 275 _calc_vm_trans(prot, PROT_WRITE, VM_MAYWRITE) |
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
index 262bb94ad27e..a73df10982d0 100644
--- a/drivers/staging/media/as102/as10x_cmd.c
+++ b/drivers/staging/media/as102/as10x_cmd.c
@@ -31,7 +31,7 @@
31 */ 31 */
32int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap) 32int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap)
33{ 33{
34 int 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(); 37 ENTER();
@@ -54,8 +54,6 @@ int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap)
54 (uint8_t *) prsp, 54 (uint8_t *) prsp,
55 sizeof(prsp->body.turn_on.rsp) + 55 sizeof(prsp->body.turn_on.rsp) +
56 HEADER_SIZE); 56 HEADER_SIZE);
57 } else {
58 error = AS10X_CMD_ERROR;
59 } 57 }
60 58
61 if (error < 0) 59 if (error < 0)
@@ -77,7 +75,7 @@ out:
77 */ 75 */
78int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap) 76int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap)
79{ 77{
80 int error; 78 int error = AS10X_CMD_ERROR;
81 struct as10x_cmd_t *pcmd, *prsp; 79 struct as10x_cmd_t *pcmd, *prsp;
82 80
83 ENTER(); 81 ENTER();
@@ -99,8 +97,6 @@ int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap)
99 sizeof(pcmd->body.turn_off.req) + HEADER_SIZE, 97 sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
100 (uint8_t *) prsp, 98 (uint8_t *) prsp,
101 sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE); 99 sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
102 } else {
103 error = AS10X_CMD_ERROR;
104 } 100 }
105 101
106 if (error < 0) 102 if (error < 0)
@@ -124,7 +120,7 @@ out:
124int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap, 120int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
125 struct as10x_tune_args *ptune) 121 struct as10x_tune_args *ptune)
126{ 122{
127 int error; 123 int error = AS10X_CMD_ERROR;
128 struct as10x_cmd_t *preq, *prsp; 124 struct as10x_cmd_t *preq, *prsp;
129 125
130 ENTER(); 126 ENTER();
@@ -159,8 +155,6 @@ int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
159 (uint8_t *) prsp, 155 (uint8_t *) prsp,
160 sizeof(prsp->body.set_tune.rsp) 156 sizeof(prsp->body.set_tune.rsp)
161 + HEADER_SIZE); 157 + HEADER_SIZE);
162 } else {
163 error = AS10X_CMD_ERROR;
164 } 158 }
165 159
166 if (error < 0) 160 if (error < 0)
@@ -184,7 +178,7 @@ out:
184int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap, 178int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
185 struct as10x_tune_status *pstatus) 179 struct as10x_tune_status *pstatus)
186{ 180{
187 int error; 181 int error = AS10X_CMD_ERROR;
188 struct as10x_cmd_t *preq, *prsp; 182 struct as10x_cmd_t *preq, *prsp;
189 183
190 ENTER(); 184 ENTER();
@@ -208,8 +202,6 @@ int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
208 sizeof(preq->body.get_tune_status.req) + HEADER_SIZE, 202 sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
209 (uint8_t *) prsp, 203 (uint8_t *) prsp,
210 sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE); 204 sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
211 } else {
212 error = AS10X_CMD_ERROR;
213 } 205 }
214 206
215 if (error < 0) 207 if (error < 0)
@@ -241,7 +233,7 @@ out:
241 */ 233 */
242int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps) 234int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
243{ 235{
244 int error; 236 int error = AS10X_CMD_ERROR;
245 struct as10x_cmd_t *pcmd, *prsp; 237 struct as10x_cmd_t *pcmd, *prsp;
246 238
247 ENTER(); 239 ENTER();
@@ -266,8 +258,6 @@ int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
266 (uint8_t *) prsp, 258 (uint8_t *) prsp,
267 sizeof(prsp->body.get_tps.rsp) + 259 sizeof(prsp->body.get_tps.rsp) +
268 HEADER_SIZE); 260 HEADER_SIZE);
269 } else {
270 error = AS10X_CMD_ERROR;
271 } 261 }
272 262
273 if (error < 0) 263 if (error < 0)
@@ -305,7 +295,7 @@ out:
305int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap, 295int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap,
306 struct as10x_demod_stats *pdemod_stats) 296 struct as10x_demod_stats *pdemod_stats)
307{ 297{
308 int error; 298 int error = AS10X_CMD_ERROR;
309 struct as10x_cmd_t *pcmd, *prsp; 299 struct as10x_cmd_t *pcmd, *prsp;
310 300
311 ENTER(); 301 ENTER();
@@ -330,8 +320,6 @@ int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap,
330 (uint8_t *) prsp, 320 (uint8_t *) prsp,
331 sizeof(prsp->body.get_demod_stats.rsp) 321 sizeof(prsp->body.get_demod_stats.rsp)
332 + HEADER_SIZE); 322 + HEADER_SIZE);
333 } else {
334 error = AS10X_CMD_ERROR;
335 } 323 }
336 324
337 if (error < 0) 325 if (error < 0)
@@ -370,7 +358,7 @@ out:
370int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap, 358int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
371 uint8_t *is_ready) 359 uint8_t *is_ready)
372{ 360{
373 int error; 361 int error = AS10X_CMD_ERROR;
374 struct as10x_cmd_t *pcmd, *prsp; 362 struct as10x_cmd_t *pcmd, *prsp;
375 363
376 ENTER(); 364 ENTER();
@@ -395,8 +383,6 @@ int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
395 (uint8_t *) prsp, 383 (uint8_t *) prsp,
396 sizeof(prsp->body.get_impulse_rsp.rsp) 384 sizeof(prsp->body.get_impulse_rsp.rsp)
397 + HEADER_SIZE); 385 + HEADER_SIZE);
398 } else {
399 error = AS10X_CMD_ERROR;
400 } 386 }
401 387
402 if (error < 0) 388 if (error < 0)
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index 280c84ec4cc2..c365cdf714ea 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -898,6 +898,10 @@ dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
898 INIT_LIST_HEAD(&pd->dmaq); 898 INIT_LIST_HEAD(&pd->dmaq);
899 mutex_init(&pd->mux); 899 mutex_init(&pd->mux);
900 pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */ 900 pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */
901 /* Locking in file operations other than ioctl should be done
902 by the driver, not the V4L2 core.
903 This driver needs auditing so that this flag can be removed. */
904 set_bit(V4L2_FL_LOCK_ALL_FOPS, &pd->vdev->flags);
901 spin_lock_init(&pd->lock); 905 spin_lock_init(&pd->lock);
902 pd->csr2 = csr2_init; 906 pd->csr2 = csr2_init;
903 pd->config = config_init; 907 pd->config = config_init;
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index 6f83d362ab0d..a1c45e4dcdce 100644
--- a/drivers/staging/media/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
@@ -700,214 +700,7 @@ static int videodev_release(struct video_device *pvideo_device)
700 JOM(4, "ending successfully\n"); 700 JOM(4, "ending successfully\n");
701 return 0; 701 return 0;
702} 702}
703/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
704/*****************************************************************************/
705/*--------------------------------------------------------------------------*/
706/*
707 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
708 * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
709 *
710 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
711 * peasycap->pusb_device IS NO LONGER VALID.
712 */
713/*---------------------------------------------------------------------------*/
714static void easycap_delete(struct kref *pkref)
715{
716 struct easycap *peasycap;
717 struct data_urb *pdata_urb;
718 struct list_head *plist_head, *plist_next;
719 int k, m, gone, kd;
720 int allocation_video_urb;
721 int allocation_video_page;
722 int allocation_video_struct;
723 int allocation_audio_urb;
724 int allocation_audio_page;
725 int allocation_audio_struct;
726 int registered_video, registered_audio;
727
728 peasycap = container_of(pkref, struct easycap, kref);
729 if (!peasycap) {
730 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
731 return;
732 }
733 kd = easycap_isdongle(peasycap);
734/*---------------------------------------------------------------------------*/
735/*
736 * FREE VIDEO.
737 */
738/*---------------------------------------------------------------------------*/
739 if (peasycap->purb_video_head) {
740 m = 0;
741 list_for_each(plist_head, peasycap->purb_video_head) {
742 pdata_urb = list_entry(plist_head,
743 struct data_urb, list_head);
744 if (pdata_urb && pdata_urb->purb) {
745 usb_free_urb(pdata_urb->purb);
746 pdata_urb->purb = NULL;
747 peasycap->allocation_video_urb--;
748 m++;
749 }
750 }
751
752 JOM(4, "%i video urbs freed\n", m);
753/*---------------------------------------------------------------------------*/
754 JOM(4, "freeing video data_urb structures.\n");
755 m = 0;
756 list_for_each_safe(plist_head, plist_next,
757 peasycap->purb_video_head) {
758 pdata_urb = list_entry(plist_head,
759 struct data_urb, list_head);
760 if (pdata_urb) {
761 peasycap->allocation_video_struct -=
762 sizeof(struct data_urb);
763 kfree(pdata_urb);
764 m++;
765 }
766 }
767 JOM(4, "%i video data_urb structures freed\n", m);
768 JOM(4, "setting peasycap->purb_video_head=NULL\n");
769 peasycap->purb_video_head = NULL;
770 }
771/*---------------------------------------------------------------------------*/
772 JOM(4, "freeing video isoc buffers.\n");
773 m = 0;
774 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
775 if (peasycap->video_isoc_buffer[k].pgo) {
776 free_pages((unsigned long)
777 peasycap->video_isoc_buffer[k].pgo,
778 VIDEO_ISOC_ORDER);
779 peasycap->video_isoc_buffer[k].pgo = NULL;
780 peasycap->allocation_video_page -=
781 BIT(VIDEO_ISOC_ORDER);
782 m++;
783 }
784 }
785 JOM(4, "isoc video buffers freed: %i pages\n",
786 m * (0x01 << VIDEO_ISOC_ORDER));
787/*---------------------------------------------------------------------------*/
788 JOM(4, "freeing video field buffers.\n");
789 gone = 0;
790 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
791 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
792 if (peasycap->field_buffer[k][m].pgo) {
793 free_page((unsigned long)
794 peasycap->field_buffer[k][m].pgo);
795 peasycap->field_buffer[k][m].pgo = NULL;
796 peasycap->allocation_video_page -= 1;
797 gone++;
798 }
799 }
800 }
801 JOM(4, "video field buffers freed: %i pages\n", gone);
802/*---------------------------------------------------------------------------*/
803 JOM(4, "freeing video frame buffers.\n");
804 gone = 0;
805 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
806 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
807 if (peasycap->frame_buffer[k][m].pgo) {
808 free_page((unsigned long)
809 peasycap->frame_buffer[k][m].pgo);
810 peasycap->frame_buffer[k][m].pgo = NULL;
811 peasycap->allocation_video_page -= 1;
812 gone++;
813 }
814 }
815 }
816 JOM(4, "video frame buffers freed: %i pages\n", gone);
817/*---------------------------------------------------------------------------*/
818/*
819 * FREE AUDIO.
820 */
821/*---------------------------------------------------------------------------*/
822 if (peasycap->purb_audio_head) {
823 JOM(4, "freeing audio urbs\n");
824 m = 0;
825 list_for_each(plist_head, (peasycap->purb_audio_head)) {
826 pdata_urb = list_entry(plist_head,
827 struct data_urb, list_head);
828 if (pdata_urb && pdata_urb->purb) {
829 usb_free_urb(pdata_urb->purb);
830 pdata_urb->purb = NULL;
831 peasycap->allocation_audio_urb--;
832 m++;
833 }
834 }
835 JOM(4, "%i audio urbs freed\n", m);
836/*---------------------------------------------------------------------------*/
837 JOM(4, "freeing audio data_urb structures.\n");
838 m = 0;
839 list_for_each_safe(plist_head, plist_next,
840 peasycap->purb_audio_head) {
841 pdata_urb = list_entry(plist_head,
842 struct data_urb, list_head);
843 if (pdata_urb) {
844 peasycap->allocation_audio_struct -=
845 sizeof(struct data_urb);
846 kfree(pdata_urb);
847 m++;
848 }
849 }
850 JOM(4, "%i audio data_urb structures freed\n", m);
851 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
852 peasycap->purb_audio_head = NULL;
853 }
854/*---------------------------------------------------------------------------*/
855 JOM(4, "freeing audio isoc buffers.\n");
856 m = 0;
857 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
858 if (peasycap->audio_isoc_buffer[k].pgo) {
859 free_pages((unsigned long)
860 (peasycap->audio_isoc_buffer[k].pgo),
861 AUDIO_ISOC_ORDER);
862 peasycap->audio_isoc_buffer[k].pgo = NULL;
863 peasycap->allocation_audio_page -=
864 BIT(AUDIO_ISOC_ORDER);
865 m++;
866 }
867 }
868 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
869 m * (0x01 << AUDIO_ISOC_ORDER));
870/*---------------------------------------------------------------------------*/
871 JOM(4, "freeing easycap structure.\n");
872 allocation_video_urb = peasycap->allocation_video_urb;
873 allocation_video_page = peasycap->allocation_video_page;
874 allocation_video_struct = peasycap->allocation_video_struct;
875 registered_video = peasycap->registered_video;
876 allocation_audio_urb = peasycap->allocation_audio_urb;
877 allocation_audio_page = peasycap->allocation_audio_page;
878 allocation_audio_struct = peasycap->allocation_audio_struct;
879 registered_audio = peasycap->registered_audio;
880
881 if (0 <= kd && DONGLE_MANY > kd) {
882 if (mutex_lock_interruptible(&mutex_dongle)) {
883 SAY("ERROR: cannot down mutex_dongle\n");
884 } else {
885 JOM(4, "locked mutex_dongle\n");
886 easycapdc60_dongle[kd].peasycap = NULL;
887 mutex_unlock(&mutex_dongle);
888 JOM(4, "unlocked mutex_dongle\n");
889 JOT(4, " null-->dongle[%i].peasycap\n", kd);
890 allocation_video_struct -= sizeof(struct easycap);
891 }
892 } else {
893 SAY("ERROR: cannot purge dongle[].peasycap");
894 }
895 703
896 kfree(peasycap);
897
898/*---------------------------------------------------------------------------*/
899 SAY("%8i=video urbs after all deletions\n", allocation_video_urb);
900 SAY("%8i=video pages after all deletions\n", allocation_video_page);
901 SAY("%8i=video structs after all deletions\n", allocation_video_struct);
902 SAY("%8i=video devices after all deletions\n", registered_video);
903 SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb);
904 SAY("%8i=audio pages after all deletions\n", allocation_audio_page);
905 SAY("%8i=audio structs after all deletions\n", allocation_audio_struct);
906 SAY("%8i=audio devices after all deletions\n", registered_audio);
907
908 JOT(4, "ending.\n");
909 return;
910}
911/*****************************************************************************/ 704/*****************************************************************************/
912static unsigned int easycap_poll(struct file *file, poll_table *wait) 705static unsigned int easycap_poll(struct file *file, poll_table *wait)
913{ 706{
@@ -2842,6 +2635,813 @@ static void easycap_complete(struct urb *purb)
2842 return; 2635 return;
2843} 2636}
2844 2637
2638static struct easycap *alloc_easycap(u8 bInterfaceNumber)
2639{
2640 struct easycap *peasycap;
2641 int i;
2642
2643 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
2644 if (!peasycap) {
2645 SAY("ERROR: Could not allocate peasycap\n");
2646 return NULL;
2647 }
2648
2649 if (mutex_lock_interruptible(&mutex_dongle)) {
2650 SAY("ERROR: cannot lock mutex_dongle\n");
2651 kfree(peasycap);
2652 return NULL;
2653 }
2654
2655 /* Find a free dongle in easycapdc60_dongle array */
2656 for (i = 0; i < DONGLE_MANY; i++) {
2657
2658 if ((!easycapdc60_dongle[i].peasycap) &&
2659 (!mutex_is_locked(&easycapdc60_dongle[i].mutex_video)) &&
2660 (!mutex_is_locked(&easycapdc60_dongle[i].mutex_audio))) {
2661
2662 easycapdc60_dongle[i].peasycap = peasycap;
2663 peasycap->isdongle = i;
2664 JOM(8, "intf[%i]: peasycap-->easycap"
2665 "_dongle[%i].peasycap\n",
2666 bInterfaceNumber, i);
2667 break;
2668 }
2669 }
2670
2671 mutex_unlock(&mutex_dongle);
2672
2673 if (i >= DONGLE_MANY) {
2674 SAM("ERROR: too many dongles\n");
2675 kfree(peasycap);
2676 return NULL;
2677 }
2678
2679 return peasycap;
2680}
2681
2682static void free_easycap(struct easycap *peasycap)
2683{
2684 int allocation_video_urb;
2685 int allocation_video_page;
2686 int allocation_video_struct;
2687 int allocation_audio_urb;
2688 int allocation_audio_page;
2689 int allocation_audio_struct;
2690 int registered_video, registered_audio;
2691 int kd;
2692
2693 JOM(4, "freeing easycap structure.\n");
2694 allocation_video_urb = peasycap->allocation_video_urb;
2695 allocation_video_page = peasycap->allocation_video_page;
2696 allocation_video_struct = peasycap->allocation_video_struct;
2697 registered_video = peasycap->registered_video;
2698 allocation_audio_urb = peasycap->allocation_audio_urb;
2699 allocation_audio_page = peasycap->allocation_audio_page;
2700 allocation_audio_struct = peasycap->allocation_audio_struct;
2701 registered_audio = peasycap->registered_audio;
2702
2703 kd = easycap_isdongle(peasycap);
2704 if (0 <= kd && DONGLE_MANY > kd) {
2705 if (mutex_lock_interruptible(&mutex_dongle)) {
2706 SAY("ERROR: cannot down mutex_dongle\n");
2707 } else {
2708 JOM(4, "locked mutex_dongle\n");
2709 easycapdc60_dongle[kd].peasycap = NULL;
2710 mutex_unlock(&mutex_dongle);
2711 JOM(4, "unlocked mutex_dongle\n");
2712 JOT(4, " null-->dongle[%i].peasycap\n", kd);
2713 allocation_video_struct -= sizeof(struct easycap);
2714 }
2715 } else {
2716 SAY("ERROR: cannot purge dongle[].peasycap");
2717 }
2718
2719 /* Free device structure */
2720 kfree(peasycap);
2721
2722 SAY("%8i=video urbs after all deletions\n", allocation_video_urb);
2723 SAY("%8i=video pages after all deletions\n", allocation_video_page);
2724 SAY("%8i=video structs after all deletions\n", allocation_video_struct);
2725 SAY("%8i=video devices after all deletions\n", registered_video);
2726 SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb);
2727 SAY("%8i=audio pages after all deletions\n", allocation_audio_page);
2728 SAY("%8i=audio structs after all deletions\n", allocation_audio_struct);
2729 SAY("%8i=audio devices after all deletions\n", registered_audio);
2730}
2731
2732/*
2733 * FIXME: Identify the appropriate pointer peasycap for interfaces
2734 * 1 and 2. The address of peasycap->pusb_device is reluctantly used
2735 * for this purpose.
2736 */
2737static struct easycap *get_easycap(struct usb_device *usbdev,
2738 u8 bInterfaceNumber)
2739{
2740 int i;
2741 struct easycap *peasycap;
2742
2743 for (i = 0; i < DONGLE_MANY; i++) {
2744 if (easycapdc60_dongle[i].peasycap->pusb_device == usbdev) {
2745 peasycap = easycapdc60_dongle[i].peasycap;
2746 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
2747 bInterfaceNumber, i);
2748 break;
2749 }
2750 }
2751 if (i >= DONGLE_MANY) {
2752 SAY("ERROR: peasycap is unknown when probing interface %i\n",
2753 bInterfaceNumber);
2754 return NULL;
2755 }
2756 if (!peasycap) {
2757 SAY("ERROR: peasycap is NULL when probing interface %i\n",
2758 bInterfaceNumber);
2759 return NULL;
2760 }
2761
2762 return peasycap;
2763}
2764
2765static void init_easycap(struct easycap *peasycap,
2766 struct usb_device *usbdev,
2767 struct usb_interface *intf,
2768 u8 bInterfaceNumber)
2769{
2770 /* Save usb_device and usb_interface */
2771 peasycap->pusb_device = usbdev;
2772 peasycap->pusb_interface = intf;
2773
2774 peasycap->minor = -1;
2775 kref_init(&peasycap->kref);
2776 JOM(8, "intf[%i]: after kref_init(..._video) "
2777 "%i=peasycap->kref.refcount.counter\n",
2778 bInterfaceNumber, peasycap->kref.refcount.counter);
2779
2780 /* module params */
2781 peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
2782
2783 init_waitqueue_head(&peasycap->wq_video);
2784 init_waitqueue_head(&peasycap->wq_audio);
2785 init_waitqueue_head(&peasycap->wq_trigger);
2786
2787 peasycap->allocation_video_struct = sizeof(struct easycap);
2788
2789 peasycap->microphone = false;
2790
2791 peasycap->video_interface = -1;
2792 peasycap->video_altsetting_on = -1;
2793 peasycap->video_altsetting_off = -1;
2794 peasycap->video_endpointnumber = -1;
2795 peasycap->video_isoc_maxframesize = -1;
2796 peasycap->video_isoc_buffer_size = -1;
2797
2798 peasycap->audio_interface = -1;
2799 peasycap->audio_altsetting_on = -1;
2800 peasycap->audio_altsetting_off = -1;
2801 peasycap->audio_endpointnumber = -1;
2802 peasycap->audio_isoc_maxframesize = -1;
2803 peasycap->audio_isoc_buffer_size = -1;
2804
2805 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
2806
2807 peasycap->ntsc = easycap_ntsc;
2808 JOM(8, "defaulting initially to %s\n",
2809 easycap_ntsc ? "NTSC" : "PAL");
2810}
2811
2812static int populate_inputset(struct easycap *peasycap)
2813{
2814 struct inputset *inputset;
2815 struct easycap_format *peasycap_format;
2816 struct v4l2_pix_format *pix;
2817 int m, i, k, mask, fmtidx;
2818 s32 value;
2819
2820 inputset = peasycap->inputset;
2821
2822 fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
2823
2824 m = 0;
2825 mask = 0;
2826 for (i = 0; easycap_standard[i].mask != 0xffff; i++) {
2827 if (fmtidx == easycap_standard[i].v4l2_standard.index) {
2828 m++;
2829 for (k = 0; k < INPUT_MANY; k++)
2830 inputset[k].standard_offset = i;
2831 mask = easycap_standard[i].mask;
2832 }
2833 }
2834
2835 if (m != 1) {
2836 SAM("ERROR: inputset->standard_offset unpopulated, %i=m\n", m);
2837 return -ENOENT;
2838 }
2839
2840 peasycap_format = &easycap_format[0];
2841 m = 0;
2842 for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
2843 pix = &peasycap_format->v4l2_format.fmt.pix;
2844 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F))
2845 && pix->field == V4L2_FIELD_NONE
2846 && pix->pixelformat == V4L2_PIX_FMT_UYVY
2847 && pix->width == 640 && pix->height == 480) {
2848 m++;
2849 for (k = 0; k < INPUT_MANY; k++)
2850 inputset[k].format_offset = i;
2851 break;
2852 }
2853 peasycap_format++;
2854 }
2855 if (m != 1) {
2856 SAM("ERROR: inputset[]->format_offset unpopulated\n");
2857 return -ENOENT;
2858 }
2859
2860 m = 0;
2861 for (i = 0; easycap_control[i].id != 0xffffffff; i++) {
2862 value = easycap_control[i].default_value;
2863 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
2864 m++;
2865 for (k = 0; k < INPUT_MANY; k++)
2866 inputset[k].brightness = value;
2867 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
2868 m++;
2869 for (k = 0; k < INPUT_MANY; k++)
2870 inputset[k].contrast = value;
2871 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
2872 m++;
2873 for (k = 0; k < INPUT_MANY; k++)
2874 inputset[k].saturation = value;
2875 } else if (V4L2_CID_HUE == easycap_control[i].id) {
2876 m++;
2877 for (k = 0; k < INPUT_MANY; k++)
2878 inputset[k].hue = value;
2879 }
2880 }
2881
2882 if (m != 4) {
2883 SAM("ERROR: inputset[]->brightness underpopulated\n");
2884 return -ENOENT;
2885 }
2886
2887 for (k = 0; k < INPUT_MANY; k++)
2888 inputset[k].input = k;
2889 JOM(4, "populated inputset[]\n");
2890
2891 return 0;
2892}
2893
2894static int alloc_framebuffers(struct easycap *peasycap)
2895{
2896 int i, j;
2897 void *pbuf;
2898
2899 JOM(4, "allocating %i frame buffers of size %li\n",
2900 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
2901 JOM(4, ".... each scattered over %li pages\n",
2902 FRAME_BUFFER_SIZE/PAGE_SIZE);
2903
2904 for (i = 0; i < FRAME_BUFFER_MANY; i++) {
2905 for (j = 0; j < FRAME_BUFFER_SIZE/PAGE_SIZE; j++) {
2906 if (peasycap->frame_buffer[i][j].pgo)
2907 SAM("attempting to reallocate framebuffers\n");
2908 else {
2909 pbuf = (void *)__get_free_page(GFP_KERNEL);
2910 if (!pbuf) {
2911 SAM("ERROR: Could not allocate "
2912 "framebuffer %i page %i\n", i, j);
2913 return -ENOMEM;
2914 }
2915 peasycap->allocation_video_page += 1;
2916 peasycap->frame_buffer[i][j].pgo = pbuf;
2917 }
2918 peasycap->frame_buffer[i][j].pto =
2919 peasycap->frame_buffer[i][j].pgo;
2920 }
2921 }
2922
2923 peasycap->frame_fill = 0;
2924 peasycap->frame_read = 0;
2925 JOM(4, "allocation of frame buffers done: %i pages\n", i*j);
2926
2927 return 0;
2928}
2929
2930static void free_framebuffers(struct easycap *peasycap)
2931{
2932 int k, m, gone;
2933
2934 JOM(4, "freeing video frame buffers.\n");
2935 gone = 0;
2936 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
2937 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
2938 if (peasycap->frame_buffer[k][m].pgo) {
2939 free_page((unsigned long)
2940 peasycap->frame_buffer[k][m].pgo);
2941 peasycap->frame_buffer[k][m].pgo = NULL;
2942 peasycap->allocation_video_page -= 1;
2943 gone++;
2944 }
2945 }
2946 }
2947 JOM(4, "video frame buffers freed: %i pages\n", gone);
2948}
2949
2950static int alloc_fieldbuffers(struct easycap *peasycap)
2951{
2952 int i, j;
2953 void *pbuf;
2954
2955 JOM(4, "allocating %i field buffers of size %li\n",
2956 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
2957 JOM(4, ".... each scattered over %li pages\n",
2958 FIELD_BUFFER_SIZE/PAGE_SIZE);
2959
2960 for (i = 0; i < FIELD_BUFFER_MANY; i++) {
2961 for (j = 0; j < FIELD_BUFFER_SIZE/PAGE_SIZE; j++) {
2962 if (peasycap->field_buffer[i][j].pgo) {
2963 SAM("ERROR: attempting to reallocate "
2964 "fieldbuffers\n");
2965 } else {
2966 pbuf = (void *) __get_free_page(GFP_KERNEL);
2967 if (!pbuf) {
2968 SAM("ERROR: Could not allocate "
2969 "fieldbuffer %i page %i\n", i, j);
2970 return -ENOMEM;
2971 }
2972 peasycap->allocation_video_page += 1;
2973 peasycap->field_buffer[i][j].pgo = pbuf;
2974 }
2975 peasycap->field_buffer[i][j].pto =
2976 peasycap->field_buffer[i][j].pgo;
2977 }
2978 /* TODO: Hardcoded 0x0200 meaning? */
2979 peasycap->field_buffer[i][0].kount = 0x0200;
2980 }
2981 peasycap->field_fill = 0;
2982 peasycap->field_page = 0;
2983 peasycap->field_read = 0;
2984 JOM(4, "allocation of field buffers done: %i pages\n", i*j);
2985
2986 return 0;
2987}
2988
2989static void free_fieldbuffers(struct easycap *peasycap)
2990{
2991 int k, m, gone;
2992
2993 JOM(4, "freeing video field buffers.\n");
2994 gone = 0;
2995 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
2996 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
2997 if (peasycap->field_buffer[k][m].pgo) {
2998 free_page((unsigned long)
2999 peasycap->field_buffer[k][m].pgo);
3000 peasycap->field_buffer[k][m].pgo = NULL;
3001 peasycap->allocation_video_page -= 1;
3002 gone++;
3003 }
3004 }
3005 }
3006 JOM(4, "video field buffers freed: %i pages\n", gone);
3007}
3008
3009static int alloc_isocbuffers(struct easycap *peasycap)
3010{
3011 int i;
3012 void *pbuf;
3013
3014 JOM(4, "allocating %i isoc video buffers of size %i\n",
3015 VIDEO_ISOC_BUFFER_MANY,
3016 peasycap->video_isoc_buffer_size);
3017 JOM(4, ".... each occupying contiguous memory pages\n");
3018
3019 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
3020 pbuf = (void *)__get_free_pages(GFP_KERNEL,
3021 VIDEO_ISOC_ORDER);
3022 if (!pbuf) {
3023 SAM("ERROR: Could not allocate isoc "
3024 "video buffer %i\n", i);
3025 return -ENOMEM;
3026 }
3027 peasycap->allocation_video_page += BIT(VIDEO_ISOC_ORDER);
3028
3029 peasycap->video_isoc_buffer[i].pgo = pbuf;
3030 peasycap->video_isoc_buffer[i].pto =
3031 pbuf + peasycap->video_isoc_buffer_size;
3032 peasycap->video_isoc_buffer[i].kount = i;
3033 }
3034 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3035 i * (0x01 << VIDEO_ISOC_ORDER));
3036 return 0;
3037}
3038
3039static void free_isocbuffers(struct easycap *peasycap)
3040{
3041 int k, m;
3042
3043 JOM(4, "freeing video isoc buffers.\n");
3044 m = 0;
3045 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3046 if (peasycap->video_isoc_buffer[k].pgo) {
3047 free_pages((unsigned long)
3048 peasycap->video_isoc_buffer[k].pgo,
3049 VIDEO_ISOC_ORDER);
3050 peasycap->video_isoc_buffer[k].pgo = NULL;
3051 peasycap->allocation_video_page -=
3052 BIT(VIDEO_ISOC_ORDER);
3053 m++;
3054 }
3055 }
3056 JOM(4, "isoc video buffers freed: %i pages\n",
3057 m * (0x01 << VIDEO_ISOC_ORDER));
3058}
3059
3060static int create_video_urbs(struct easycap *peasycap)
3061{
3062 struct urb *purb;
3063 struct data_urb *pdata_urb;
3064 int i, j;
3065
3066 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3067 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3068 peasycap->video_isoc_framesperdesc);
3069 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3070 peasycap->video_isoc_maxframesize);
3071 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3072 peasycap->video_isoc_buffer_size);
3073
3074 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
3075 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
3076 GFP_KERNEL);
3077 if (!purb) {
3078 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3079 "%i\n", i);
3080 return -ENOMEM;
3081 }
3082
3083 peasycap->allocation_video_urb += 1;
3084 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3085 if (!pdata_urb) {
3086 SAM("ERROR: Could not allocate struct data_urb.\n");
3087 return -ENOMEM;
3088 }
3089
3090 peasycap->allocation_video_struct +=
3091 sizeof(struct data_urb);
3092
3093 pdata_urb->purb = purb;
3094 pdata_urb->isbuf = i;
3095 pdata_urb->length = 0;
3096 list_add_tail(&(pdata_urb->list_head),
3097 peasycap->purb_video_head);
3098
3099 if (!i) {
3100 JOM(4, "initializing video urbs thus:\n");
3101 JOM(4, " purb->interval = 1;\n");
3102 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3103 JOM(4, " purb->pipe = usb_rcvisocpipe"
3104 "(peasycap->pusb_device,%i);\n",
3105 peasycap->video_endpointnumber);
3106 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3107 JOM(4, " purb->transfer_buffer = peasycap->"
3108 "video_isoc_buffer[.].pgo;\n");
3109 JOM(4, " purb->transfer_buffer_length = %i;\n",
3110 peasycap->video_isoc_buffer_size);
3111 JOM(4, " purb->complete = easycap_complete;\n");
3112 JOM(4, " purb->context = peasycap;\n");
3113 JOM(4, " purb->start_frame = 0;\n");
3114 JOM(4, " purb->number_of_packets = %i;\n",
3115 peasycap->video_isoc_framesperdesc);
3116 JOM(4, " for (j = 0; j < %i; j++)\n",
3117 peasycap->video_isoc_framesperdesc);
3118 JOM(4, " {\n");
3119 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3120 peasycap->video_isoc_maxframesize);
3121 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3122 peasycap->video_isoc_maxframesize);
3123 JOM(4, " }\n");
3124 }
3125
3126 purb->interval = 1;
3127 purb->dev = peasycap->pusb_device;
3128 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3129 peasycap->video_endpointnumber);
3130
3131 purb->transfer_flags = URB_ISO_ASAP;
3132 purb->transfer_buffer = peasycap->video_isoc_buffer[i].pgo;
3133 purb->transfer_buffer_length =
3134 peasycap->video_isoc_buffer_size;
3135
3136 purb->complete = easycap_complete;
3137 purb->context = peasycap;
3138 purb->start_frame = 0;
3139 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3140
3141 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
3142 purb->iso_frame_desc[j].offset =
3143 j * peasycap->video_isoc_maxframesize;
3144 purb->iso_frame_desc[j].length =
3145 peasycap->video_isoc_maxframesize;
3146 }
3147 }
3148 JOM(4, "allocation of %i struct urb done.\n", i);
3149 return 0;
3150}
3151
3152static void free_video_urbs(struct easycap *peasycap)
3153{
3154 struct list_head *plist_head, *plist_next;
3155 struct data_urb *pdata_urb;
3156 int m;
3157
3158 if (peasycap->purb_video_head) {
3159 m = 0;
3160 list_for_each(plist_head, peasycap->purb_video_head) {
3161 pdata_urb = list_entry(plist_head,
3162 struct data_urb, list_head);
3163 if (pdata_urb && pdata_urb->purb) {
3164 usb_free_urb(pdata_urb->purb);
3165 pdata_urb->purb = NULL;
3166 peasycap->allocation_video_urb--;
3167 m++;
3168 }
3169 }
3170
3171 JOM(4, "%i video urbs freed\n", m);
3172 JOM(4, "freeing video data_urb structures.\n");
3173 m = 0;
3174 list_for_each_safe(plist_head, plist_next,
3175 peasycap->purb_video_head) {
3176 pdata_urb = list_entry(plist_head,
3177 struct data_urb, list_head);
3178 if (pdata_urb) {
3179 peasycap->allocation_video_struct -=
3180 sizeof(struct data_urb);
3181 kfree(pdata_urb);
3182 m++;
3183 }
3184 }
3185 JOM(4, "%i video data_urb structures freed\n", m);
3186 JOM(4, "setting peasycap->purb_video_head=NULL\n");
3187 peasycap->purb_video_head = NULL;
3188 }
3189}
3190
3191static int alloc_audio_buffers(struct easycap *peasycap)
3192{
3193 void *pbuf;
3194 int k;
3195
3196 JOM(4, "allocating %i isoc audio buffers of size %i\n",
3197 AUDIO_ISOC_BUFFER_MANY,
3198 peasycap->audio_isoc_buffer_size);
3199 JOM(4, ".... each occupying contiguous memory pages\n");
3200
3201 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3202 pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
3203 if (!pbuf) {
3204 SAM("ERROR: Could not allocate isoc audio buffer %i\n",
3205 k);
3206 return -ENOMEM;
3207 }
3208 peasycap->allocation_audio_page += BIT(AUDIO_ISOC_ORDER);
3209
3210 peasycap->audio_isoc_buffer[k].pgo = pbuf;
3211 peasycap->audio_isoc_buffer[k].pto =
3212 pbuf + peasycap->audio_isoc_buffer_size;
3213 peasycap->audio_isoc_buffer[k].kount = k;
3214 }
3215
3216 JOM(4, "allocation of isoc audio buffers done.\n");
3217 return 0;
3218}
3219
3220static void free_audio_buffers(struct easycap *peasycap)
3221{
3222 int k, m;
3223
3224 JOM(4, "freeing audio isoc buffers.\n");
3225 m = 0;
3226 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3227 if (peasycap->audio_isoc_buffer[k].pgo) {
3228 free_pages((unsigned long)
3229 (peasycap->audio_isoc_buffer[k].pgo),
3230 AUDIO_ISOC_ORDER);
3231 peasycap->audio_isoc_buffer[k].pgo = NULL;
3232 peasycap->allocation_audio_page -=
3233 BIT(AUDIO_ISOC_ORDER);
3234 m++;
3235 }
3236 }
3237 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
3238 m * (0x01 << AUDIO_ISOC_ORDER));
3239}
3240
3241static int create_audio_urbs(struct easycap *peasycap)
3242{
3243 struct urb *purb;
3244 struct data_urb *pdata_urb;
3245 int k, j;
3246
3247 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
3248 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
3249 peasycap->audio_isoc_framesperdesc);
3250 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
3251 peasycap->audio_isoc_maxframesize);
3252 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
3253 peasycap->audio_isoc_buffer_size);
3254
3255 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3256 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
3257 GFP_KERNEL);
3258 if (!purb) {
3259 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3260 "%i\n", k);
3261 return -ENOMEM;
3262 }
3263 peasycap->allocation_audio_urb += 1 ;
3264 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3265 if (!pdata_urb) {
3266 usb_free_urb(purb);
3267 SAM("ERROR: Could not allocate struct data_urb.\n");
3268 return -ENOMEM;
3269 }
3270 peasycap->allocation_audio_struct +=
3271 sizeof(struct data_urb);
3272
3273 pdata_urb->purb = purb;
3274 pdata_urb->isbuf = k;
3275 pdata_urb->length = 0;
3276 list_add_tail(&(pdata_urb->list_head),
3277 peasycap->purb_audio_head);
3278
3279 if (!k) {
3280 JOM(4, "initializing audio urbs thus:\n");
3281 JOM(4, " purb->interval = 1;\n");
3282 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3283 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
3284 "pusb_device,%i);\n",
3285 peasycap->audio_endpointnumber);
3286 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3287 JOM(4, " purb->transfer_buffer = "
3288 "peasycap->audio_isoc_buffer[.].pgo;\n");
3289 JOM(4, " purb->transfer_buffer_length = %i;\n",
3290 peasycap->audio_isoc_buffer_size);
3291 JOM(4, " purb->complete = easycap_alsa_complete;\n");
3292 JOM(4, " purb->context = peasycap;\n");
3293 JOM(4, " purb->start_frame = 0;\n");
3294 JOM(4, " purb->number_of_packets = %i;\n",
3295 peasycap->audio_isoc_framesperdesc);
3296 JOM(4, " for (j = 0; j < %i; j++)\n",
3297 peasycap->audio_isoc_framesperdesc);
3298 JOM(4, " {\n");
3299 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3300 peasycap->audio_isoc_maxframesize);
3301 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3302 peasycap->audio_isoc_maxframesize);
3303 JOM(4, " }\n");
3304 }
3305
3306 purb->interval = 1;
3307 purb->dev = peasycap->pusb_device;
3308 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3309 peasycap->audio_endpointnumber);
3310 purb->transfer_flags = URB_ISO_ASAP;
3311 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
3312 purb->transfer_buffer_length =
3313 peasycap->audio_isoc_buffer_size;
3314 purb->complete = easycap_alsa_complete;
3315 purb->context = peasycap;
3316 purb->start_frame = 0;
3317 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
3318 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
3319 purb->iso_frame_desc[j].offset =
3320 j * peasycap->audio_isoc_maxframesize;
3321 purb->iso_frame_desc[j].length =
3322 peasycap->audio_isoc_maxframesize;
3323 }
3324 }
3325 JOM(4, "allocation of %i struct urb done.\n", k);
3326 return 0;
3327}
3328
3329static void free_audio_urbs(struct easycap *peasycap)
3330{
3331 struct list_head *plist_head, *plist_next;
3332 struct data_urb *pdata_urb;
3333 int m;
3334
3335 if (peasycap->purb_audio_head) {
3336 JOM(4, "freeing audio urbs\n");
3337 m = 0;
3338 list_for_each(plist_head, (peasycap->purb_audio_head)) {
3339 pdata_urb = list_entry(plist_head,
3340 struct data_urb, list_head);
3341 if (pdata_urb && pdata_urb->purb) {
3342 usb_free_urb(pdata_urb->purb);
3343 pdata_urb->purb = NULL;
3344 peasycap->allocation_audio_urb--;
3345 m++;
3346 }
3347 }
3348 JOM(4, "%i audio urbs freed\n", m);
3349 JOM(4, "freeing audio data_urb structures.\n");
3350 m = 0;
3351 list_for_each_safe(plist_head, plist_next,
3352 peasycap->purb_audio_head) {
3353 pdata_urb = list_entry(plist_head,
3354 struct data_urb, list_head);
3355 if (pdata_urb) {
3356 peasycap->allocation_audio_struct -=
3357 sizeof(struct data_urb);
3358 kfree(pdata_urb);
3359 m++;
3360 }
3361 }
3362 JOM(4, "%i audio data_urb structures freed\n", m);
3363 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
3364 peasycap->purb_audio_head = NULL;
3365 }
3366}
3367
3368static void config_easycap(struct easycap *peasycap,
3369 u8 bInterfaceNumber,
3370 u8 bInterfaceClass,
3371 u8 bInterfaceSubClass)
3372{
3373 if ((USB_CLASS_VIDEO == bInterfaceClass) ||
3374 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
3375 if (-1 == peasycap->video_interface) {
3376 peasycap->video_interface = bInterfaceNumber;
3377 JOM(4, "setting peasycap->video_interface=%i\n",
3378 peasycap->video_interface);
3379 } else {
3380 if (peasycap->video_interface != bInterfaceNumber) {
3381 SAM("ERROR: attempting to reset "
3382 "peasycap->video_interface\n");
3383 SAM("...... continuing with "
3384 "%i=peasycap->video_interface\n",
3385 peasycap->video_interface);
3386 }
3387 }
3388 } else if ((USB_CLASS_AUDIO == bInterfaceClass) &&
3389 (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) {
3390 if (-1 == peasycap->audio_interface) {
3391 peasycap->audio_interface = bInterfaceNumber;
3392 JOM(4, "setting peasycap->audio_interface=%i\n",
3393 peasycap->audio_interface);
3394 } else {
3395 if (peasycap->audio_interface != bInterfaceNumber) {
3396 SAM("ERROR: attempting to reset "
3397 "peasycap->audio_interface\n");
3398 SAM("...... continuing with "
3399 "%i=peasycap->audio_interface\n",
3400 peasycap->audio_interface);
3401 }
3402 }
3403 }
3404}
3405
3406/*
3407 * This function is called from within easycap_usb_disconnect() and is
3408 * protected by semaphores set and cleared by easycap_usb_disconnect().
3409 * By this stage the device has already been physically unplugged,
3410 * so peasycap->pusb_device is no longer valid.
3411 */
3412static void easycap_delete(struct kref *pkref)
3413{
3414 struct easycap *peasycap;
3415
3416 peasycap = container_of(pkref, struct easycap, kref);
3417 if (!peasycap) {
3418 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
3419 return;
3420 }
3421
3422 /* Free video urbs */
3423 free_video_urbs(peasycap);
3424
3425 /* Free video isoc buffers */
3426 free_isocbuffers(peasycap);
3427
3428 /* Free video field buffers */
3429 free_fieldbuffers(peasycap);
3430
3431 /* Free video frame buffers */
3432 free_framebuffers(peasycap);
3433
3434 /* Free audio urbs */
3435 free_audio_urbs(peasycap);
3436
3437 /* Free audio isoc buffers */
3438 free_audio_buffers(peasycap);
3439
3440 free_easycap(peasycap);
3441
3442 JOT(4, "ending.\n");
3443}
3444
2845static const struct v4l2_file_operations v4l2_fops = { 3445static const struct v4l2_file_operations v4l2_fops = {
2846 .owner = THIS_MODULE, 3446 .owner = THIS_MODULE,
2847 .open = easycap_open_noinode, 3447 .open = easycap_open_noinode,
@@ -2850,6 +3450,36 @@ static const struct v4l2_file_operations v4l2_fops = {
2850 .mmap = easycap_mmap, 3450 .mmap = easycap_mmap,
2851}; 3451};
2852 3452
3453static int easycap_register_video(struct easycap *peasycap)
3454{
3455 /*
3456 * FIXME: This is believed to be harmless,
3457 * but may well be unnecessary or wrong.
3458 */
3459 peasycap->video_device.v4l2_dev = NULL;
3460
3461 strcpy(&peasycap->video_device.name[0], "easycapdc60");
3462 peasycap->video_device.fops = &v4l2_fops;
3463 peasycap->video_device.minor = -1;
3464 peasycap->video_device.release = (void *)(&videodev_release);
3465
3466 video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
3467
3468 if (0 != (video_register_device(&(peasycap->video_device),
3469 VFL_TYPE_GRABBER, -1))) {
3470 videodev_release(&(peasycap->video_device));
3471 return -ENODEV;
3472 }
3473
3474 peasycap->registered_video++;
3475
3476 SAM("registered with videodev: %i=minor\n",
3477 peasycap->video_device.minor);
3478 peasycap->minor = peasycap->video_device.minor;
3479
3480 return 0;
3481}
3482
2853/* 3483/*
2854 * When the device is plugged, this function is called three times, 3484 * When the device is plugged, this function is called three times,
2855 * one for each interface. 3485 * one for each interface.
@@ -2861,24 +3491,15 @@ static int easycap_usb_probe(struct usb_interface *intf,
2861 struct usb_host_interface *alt; 3491 struct usb_host_interface *alt;
2862 struct usb_endpoint_descriptor *ep; 3492 struct usb_endpoint_descriptor *ep;
2863 struct usb_interface_descriptor *interface; 3493 struct usb_interface_descriptor *interface;
2864 struct urb *purb;
2865 struct easycap *peasycap; 3494 struct easycap *peasycap;
2866 int ndong; 3495 int i, j, rc;
2867 struct data_urb *pdata_urb;
2868 int i, j, k, m, rc;
2869 u8 bInterfaceNumber; 3496 u8 bInterfaceNumber;
2870 u8 bInterfaceClass; 3497 u8 bInterfaceClass;
2871 u8 bInterfaceSubClass; 3498 u8 bInterfaceSubClass;
2872 void *pbuf;
2873 int okalt[8], isokalt; 3499 int okalt[8], isokalt;
2874 int okepn[8]; 3500 int okepn[8];
2875 int okmps[8]; 3501 int okmps[8];
2876 int maxpacketsize; 3502 int maxpacketsize;
2877 u16 mask;
2878 s32 value;
2879 struct easycap_format *peasycap_format;
2880 int fmtidx;
2881 struct inputset *inputset;
2882 3503
2883 usbdev = interface_to_usbdev(intf); 3504 usbdev = interface_to_usbdev(intf);
2884 3505
@@ -2916,76 +3537,16 @@ static int easycap_usb_probe(struct usb_interface *intf,
2916 * interfaces 1 and 2 are probed. 3537 * interfaces 1 and 2 are probed.
2917 */ 3538 */
2918 if (0 == bInterfaceNumber) { 3539 if (0 == bInterfaceNumber) {
2919 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); 3540 /*
2920 if (!peasycap) { 3541 * Alloc structure and save it in a free slot in
2921 SAY("ERROR: Could not allocate peasycap\n"); 3542 * easycapdc60_dongle array
2922 return -ENOMEM; 3543 */
2923 } 3544 peasycap = alloc_easycap(bInterfaceNumber);
2924 3545 if (!peasycap)
2925 /* Perform urgent initializations */
2926 peasycap->minor = -1;
2927 kref_init(&peasycap->kref);
2928 JOM(8, "intf[%i]: after kref_init(..._video) "
2929 "%i=peasycap->kref.refcount.counter\n",
2930 bInterfaceNumber, peasycap->kref.refcount.counter);
2931
2932 /* module params */
2933 peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
2934
2935 init_waitqueue_head(&peasycap->wq_video);
2936 init_waitqueue_head(&peasycap->wq_audio);
2937 init_waitqueue_head(&peasycap->wq_trigger);
2938
2939 if (mutex_lock_interruptible(&mutex_dongle)) {
2940 SAY("ERROR: cannot down mutex_dongle\n");
2941 return -ERESTARTSYS;
2942 }
2943
2944 for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
2945 if ((!easycapdc60_dongle[ndong].peasycap) &&
2946 (!mutex_is_locked(&easycapdc60_dongle
2947 [ndong].mutex_video)) &&
2948 (!mutex_is_locked(&easycapdc60_dongle
2949 [ndong].mutex_audio))) {
2950 easycapdc60_dongle[ndong].peasycap = peasycap;
2951 peasycap->isdongle = ndong;
2952 JOM(8, "intf[%i]: peasycap-->easycap"
2953 "_dongle[%i].peasycap\n",
2954 bInterfaceNumber, ndong);
2955 break;
2956 }
2957 }
2958
2959 if (DONGLE_MANY <= ndong) {
2960 SAM("ERROR: too many dongles\n");
2961 mutex_unlock(&mutex_dongle);
2962 return -ENOMEM; 3546 return -ENOMEM;
2963 }
2964 mutex_unlock(&mutex_dongle);
2965
2966 peasycap->allocation_video_struct = sizeof(struct easycap);
2967
2968 /* and further initialize the structure */
2969 peasycap->pusb_device = usbdev;
2970 peasycap->pusb_interface = intf;
2971 3547
2972 peasycap->microphone = false; 3548 /* Perform basic struct initialization */
2973 3549 init_easycap(peasycap, usbdev, intf, bInterfaceNumber);
2974 peasycap->video_interface = -1;
2975 peasycap->video_altsetting_on = -1;
2976 peasycap->video_altsetting_off = -1;
2977 peasycap->video_endpointnumber = -1;
2978 peasycap->video_isoc_maxframesize = -1;
2979 peasycap->video_isoc_buffer_size = -1;
2980
2981 peasycap->audio_interface = -1;
2982 peasycap->audio_altsetting_on = -1;
2983 peasycap->audio_altsetting_off = -1;
2984 peasycap->audio_endpointnumber = -1;
2985 peasycap->audio_isoc_maxframesize = -1;
2986 peasycap->audio_isoc_buffer_size = -1;
2987
2988 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
2989 3550
2990 /* Dynamically fill in the available formats */ 3551 /* Dynamically fill in the available formats */
2991 rc = easycap_video_fillin_formats(); 3552 rc = easycap_video_fillin_formats();
@@ -2996,136 +3557,19 @@ static int easycap_usb_probe(struct usb_interface *intf,
2996 JOM(4, "%i formats available\n", rc); 3557 JOM(4, "%i formats available\n", rc);
2997 3558
2998 /* Populate easycap.inputset[] */ 3559 /* Populate easycap.inputset[] */
2999 inputset = peasycap->inputset; 3560 rc = populate_inputset(peasycap);
3000 fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; 3561 if (rc < 0)
3001 m = 0; 3562 return rc;
3002 mask = 0;
3003 for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) {
3004 if (fmtidx == easycap_standard[i].v4l2_standard.index) {
3005 m++;
3006 for (k = 0; k < INPUT_MANY; k++)
3007 inputset[k].standard_offset = i;
3008
3009 mask = easycap_standard[i].mask;
3010 }
3011 }
3012 if (1 != m) {
3013 SAM("ERROR: "
3014 "inputset->standard_offset unpopulated, %i=m\n", m);
3015 return -ENOENT;
3016 }
3017
3018 peasycap_format = &easycap_format[0];
3019 m = 0;
3020 for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
3021 struct v4l2_pix_format *pix =
3022 &peasycap_format->v4l2_format.fmt.pix;
3023 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) &&
3024 pix->field == V4L2_FIELD_NONE &&
3025 pix->pixelformat == V4L2_PIX_FMT_UYVY &&
3026 pix->width == 640 && pix->height == 480) {
3027 m++;
3028 for (k = 0; k < INPUT_MANY; k++)
3029 inputset[k].format_offset = i;
3030 break;
3031 }
3032 peasycap_format++;
3033 }
3034 if (1 != m) {
3035 SAM("ERROR: inputset[]->format_offset unpopulated\n");
3036 return -ENOENT;
3037 }
3038
3039 m = 0;
3040 for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) {
3041 value = easycap_control[i].default_value;
3042 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
3043 m++;
3044 for (k = 0; k < INPUT_MANY; k++)
3045 inputset[k].brightness = value;
3046 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
3047 m++;
3048 for (k = 0; k < INPUT_MANY; k++)
3049 inputset[k].contrast = value;
3050 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
3051 m++;
3052 for (k = 0; k < INPUT_MANY; k++)
3053 inputset[k].saturation = value;
3054 } else if (V4L2_CID_HUE == easycap_control[i].id) {
3055 m++;
3056 for (k = 0; k < INPUT_MANY; k++)
3057 inputset[k].hue = value;
3058 }
3059 }
3060
3061 if (4 != m) {
3062 SAM("ERROR: inputset[]->brightness underpopulated\n");
3063 return -ENOENT;
3064 }
3065 for (k = 0; k < INPUT_MANY; k++)
3066 inputset[k].input = k;
3067 JOM(4, "populated inputset[]\n");
3068 JOM(4, "finished initialization\n"); 3563 JOM(4, "finished initialization\n");
3069 } else { 3564 } else {
3070 3565 peasycap = get_easycap(usbdev, bInterfaceNumber);
3071 /* 3566 if (!peasycap)
3072 * FIXME: Identify the appropriate pointer
3073 * peasycap for interfaces 1 and 2.
3074 * The address of peasycap->pusb_device
3075 * is reluctantly used for this purpose.
3076 */
3077 for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
3078 if (usbdev == easycapdc60_dongle[ndong].peasycap->
3079 pusb_device) {
3080 peasycap = easycapdc60_dongle[ndong].peasycap;
3081 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
3082 bInterfaceNumber, ndong);
3083 break;
3084 }
3085 }
3086 if (DONGLE_MANY <= ndong) {
3087 SAY("ERROR: peasycap is unknown when probing interface %i\n",
3088 bInterfaceNumber);
3089 return -ENODEV; 3567 return -ENODEV;
3090 }
3091 if (!peasycap) {
3092 SAY("ERROR: peasycap is NULL when probing interface %i\n",
3093 bInterfaceNumber);
3094 return -ENODEV;
3095 }
3096 } 3568 }
3097 3569
3098 if ((USB_CLASS_VIDEO == bInterfaceClass) || 3570 config_easycap(peasycap, bInterfaceNumber,
3099 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { 3571 bInterfaceClass,
3100 if (-1 == peasycap->video_interface) { 3572 bInterfaceSubClass);
3101 peasycap->video_interface = bInterfaceNumber;
3102 JOM(4, "setting peasycap->video_interface=%i\n",
3103 peasycap->video_interface);
3104 } else {
3105 if (peasycap->video_interface != bInterfaceNumber) {
3106 SAM("ERROR: attempting to reset "
3107 "peasycap->video_interface\n");
3108 SAM("...... continuing with "
3109 "%i=peasycap->video_interface\n",
3110 peasycap->video_interface);
3111 }
3112 }
3113 } else if ((USB_CLASS_AUDIO == bInterfaceClass) &&
3114 (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) {
3115 if (-1 == peasycap->audio_interface) {
3116 peasycap->audio_interface = bInterfaceNumber;
3117 JOM(4, "setting peasycap->audio_interface=%i\n",
3118 peasycap->audio_interface);
3119 } else {
3120 if (peasycap->audio_interface != bInterfaceNumber) {
3121 SAM("ERROR: attempting to reset "
3122 "peasycap->audio_interface\n");
3123 SAM("...... continuing with "
3124 "%i=peasycap->audio_interface\n",
3125 peasycap->audio_interface);
3126 }
3127 }
3128 }
3129 3573
3130 /* 3574 /*
3131 * Investigate all altsettings. This is done in detail 3575 * Investigate all altsettings. This is done in detail
@@ -3368,173 +3812,23 @@ static int easycap_usb_probe(struct usb_interface *intf,
3368 */ 3812 */
3369 INIT_LIST_HEAD(&(peasycap->urb_video_head)); 3813 INIT_LIST_HEAD(&(peasycap->urb_video_head));
3370 peasycap->purb_video_head = &(peasycap->urb_video_head); 3814 peasycap->purb_video_head = &(peasycap->urb_video_head);
3371 JOM(4, "allocating %i frame buffers of size %li\n",
3372 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
3373 JOM(4, ".... each scattered over %li pages\n",
3374 FRAME_BUFFER_SIZE/PAGE_SIZE);
3375
3376 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
3377 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
3378 if (peasycap->frame_buffer[k][m].pgo)
3379 SAM("attempting to reallocate frame "
3380 " buffers\n");
3381 else {
3382 pbuf = (void *)__get_free_page(GFP_KERNEL);
3383 if (!pbuf) {
3384 SAM("ERROR: Could not allocate frame "
3385 "buffer %i page %i\n", k, m);
3386 return -ENOMEM;
3387 }
3388
3389 peasycap->allocation_video_page += 1;
3390 peasycap->frame_buffer[k][m].pgo = pbuf;
3391 }
3392 peasycap->frame_buffer[k][m].pto =
3393 peasycap->frame_buffer[k][m].pgo;
3394 }
3395 }
3396
3397 peasycap->frame_fill = 0;
3398 peasycap->frame_read = 0;
3399 JOM(4, "allocation of frame buffers done: %i pages\n", k *
3400 m);
3401 JOM(4, "allocating %i field buffers of size %li\n",
3402 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
3403 JOM(4, ".... each scattered over %li pages\n",
3404 FIELD_BUFFER_SIZE/PAGE_SIZE);
3405
3406 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
3407 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
3408 if (peasycap->field_buffer[k][m].pgo) {
3409 SAM("ERROR: attempting to reallocate "
3410 "field buffers\n");
3411 } else {
3412 pbuf = (void *) __get_free_page(GFP_KERNEL);
3413 if (!pbuf) {
3414 SAM("ERROR: Could not allocate field"
3415 " buffer %i page %i\n", k, m);
3416 return -ENOMEM;
3417 }
3418
3419 peasycap->allocation_video_page += 1;
3420 peasycap->field_buffer[k][m].pgo = pbuf;
3421 }
3422 peasycap->field_buffer[k][m].pto =
3423 peasycap->field_buffer[k][m].pgo;
3424 }
3425 peasycap->field_buffer[k][0].kount = 0x0200;
3426 }
3427 peasycap->field_fill = 0;
3428 peasycap->field_page = 0;
3429 peasycap->field_read = 0;
3430 JOM(4, "allocation of field buffers done: %i pages\n", k *
3431 m);
3432 JOM(4, "allocating %i isoc video buffers of size %i\n",
3433 VIDEO_ISOC_BUFFER_MANY,
3434 peasycap->video_isoc_buffer_size);
3435 JOM(4, ".... each occupying contiguous memory pages\n");
3436
3437 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3438 pbuf = (void *)__get_free_pages(GFP_KERNEL,
3439 VIDEO_ISOC_ORDER);
3440 if (!pbuf) {
3441 SAM("ERROR: Could not allocate isoc video buffer "
3442 "%i\n", k);
3443 return -ENOMEM;
3444 }
3445 peasycap->allocation_video_page +=
3446 BIT(VIDEO_ISOC_ORDER);
3447 3815
3448 peasycap->video_isoc_buffer[k].pgo = pbuf; 3816 rc = alloc_framebuffers(peasycap);
3449 peasycap->video_isoc_buffer[k].pto = 3817 if (rc < 0)
3450 pbuf + peasycap->video_isoc_buffer_size; 3818 return rc;
3451 peasycap->video_isoc_buffer[k].kount = k;
3452 }
3453 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3454 k * (0x01 << VIDEO_ISOC_ORDER));
3455
3456 /* Allocate and initialize multiple struct usb */
3457 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3458 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3459 peasycap->video_isoc_framesperdesc);
3460 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3461 peasycap->video_isoc_maxframesize);
3462 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3463 peasycap->video_isoc_buffer_size);
3464
3465 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3466 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
3467 GFP_KERNEL);
3468 if (!purb) {
3469 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3470 "%i\n", k);
3471 return -ENOMEM;
3472 }
3473 3819
3474 peasycap->allocation_video_urb += 1; 3820 rc = alloc_fieldbuffers(peasycap);
3475 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 3821 if (rc < 0)
3476 if (!pdata_urb) { 3822 return rc;
3477 SAM("ERROR: Could not allocate struct data_urb.\n");
3478 return -ENOMEM;
3479 }
3480 3823
3481 peasycap->allocation_video_struct += 3824 rc = alloc_isocbuffers(peasycap);
3482 sizeof(struct data_urb); 3825 if (rc < 0)
3826 return rc;
3483 3827
3484 pdata_urb->purb = purb; 3828 /* Allocate and initialize video urbs */
3485 pdata_urb->isbuf = k; 3829 rc = create_video_urbs(peasycap);
3486 pdata_urb->length = 0; 3830 if (rc < 0)
3487 list_add_tail(&(pdata_urb->list_head), 3831 return rc;
3488 peasycap->purb_video_head);
3489
3490 /* Initialize allocated urbs */
3491 if (!k) {
3492 JOM(4, "initializing video urbs thus:\n");
3493 JOM(4, " purb->interval = 1;\n");
3494 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3495 JOM(4, " purb->pipe = usb_rcvisocpipe"
3496 "(peasycap->pusb_device,%i);\n",
3497 peasycap->video_endpointnumber);
3498 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3499 JOM(4, " purb->transfer_buffer = peasycap->"
3500 "video_isoc_buffer[.].pgo;\n");
3501 JOM(4, " purb->transfer_buffer_length = %i;\n",
3502 peasycap->video_isoc_buffer_size);
3503 JOM(4, " purb->complete = easycap_complete;\n");
3504 JOM(4, " purb->context = peasycap;\n");
3505 JOM(4, " purb->start_frame = 0;\n");
3506 JOM(4, " purb->number_of_packets = %i;\n",
3507 peasycap->video_isoc_framesperdesc);
3508 JOM(4, " for (j = 0; j < %i; j++)\n",
3509 peasycap->video_isoc_framesperdesc);
3510 JOM(4, " {\n");
3511 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3512 peasycap->video_isoc_maxframesize);
3513 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3514 peasycap->video_isoc_maxframesize);
3515 JOM(4, " }\n");
3516 }
3517
3518 purb->interval = 1;
3519 purb->dev = peasycap->pusb_device;
3520 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3521 peasycap->video_endpointnumber);
3522 purb->transfer_flags = URB_ISO_ASAP;
3523 purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
3524 purb->transfer_buffer_length =
3525 peasycap->video_isoc_buffer_size;
3526 purb->complete = easycap_complete;
3527 purb->context = peasycap;
3528 purb->start_frame = 0;
3529 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3530 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
3531 purb->iso_frame_desc[j].offset = j *
3532 peasycap->video_isoc_maxframesize;
3533 purb->iso_frame_desc[j].length =
3534 peasycap->video_isoc_maxframesize;
3535 }
3536 }
3537 JOM(4, "allocation of %i struct urb done.\n", k);
3538 3832
3539 /* Save pointer peasycap in this interface */ 3833 /* Save pointer peasycap in this interface */
3540 usb_set_intfdata(intf, peasycap); 3834 usb_set_intfdata(intf, peasycap);
@@ -3545,9 +3839,6 @@ static int easycap_usb_probe(struct usb_interface *intf,
3545 * because some udev rules triggers easycap_open() 3839 * because some udev rules triggers easycap_open()
3546 * immediately after registration, causing a clash. 3840 * immediately after registration, causing a clash.
3547 */ 3841 */
3548 peasycap->ntsc = easycap_ntsc;
3549 JOM(8, "defaulting initially to %s\n",
3550 easycap_ntsc ? "NTSC" : "PAL");
3551 rc = reset(peasycap); 3842 rc = reset(peasycap);
3552 if (rc) { 3843 if (rc) {
3553 SAM("ERROR: reset() rc = %i\n", rc); 3844 SAM("ERROR: reset() rc = %i\n", rc);
@@ -3562,33 +3853,12 @@ static int easycap_usb_probe(struct usb_interface *intf,
3562 JOM(4, "registered device instance: %s\n", 3853 JOM(4, "registered device instance: %s\n",
3563 peasycap->v4l2_device.name); 3854 peasycap->v4l2_device.name);
3564 3855
3565 /* 3856 rc = easycap_register_video(peasycap);
3566 * FIXME: This is believed to be harmless, 3857 if (rc < 0) {
3567 * but may well be unnecessary or wrong.
3568 */
3569 peasycap->video_device.v4l2_dev = NULL;
3570
3571
3572 strcpy(&peasycap->video_device.name[0], "easycapdc60");
3573 peasycap->video_device.fops = &v4l2_fops;
3574 peasycap->video_device.minor = -1;
3575 peasycap->video_device.release = (void *)(&videodev_release);
3576
3577 video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
3578
3579 if (0 != (video_register_device(&(peasycap->video_device),
3580 VFL_TYPE_GRABBER, -1))) {
3581 dev_err(&intf->dev, 3858 dev_err(&intf->dev,
3582 "Not able to register with videodev\n"); 3859 "Not able to register with videodev\n");
3583 videodev_release(&(peasycap->video_device));
3584 return -ENODEV; 3860 return -ENODEV;
3585 } 3861 }
3586
3587 peasycap->registered_video++;
3588 SAM("registered with videodev: %i=minor\n",
3589 peasycap->video_device.minor);
3590 peasycap->minor = peasycap->video_device.minor;
3591
3592 break; 3862 break;
3593 } 3863 }
3594 /* 1: Audio control */ 3864 /* 1: Audio control */
@@ -3711,109 +3981,14 @@ static int easycap_usb_probe(struct usb_interface *intf,
3711 INIT_LIST_HEAD(&(peasycap->urb_audio_head)); 3981 INIT_LIST_HEAD(&(peasycap->urb_audio_head));
3712 peasycap->purb_audio_head = &(peasycap->urb_audio_head); 3982 peasycap->purb_audio_head = &(peasycap->urb_audio_head);
3713 3983
3714 JOM(4, "allocating %i isoc audio buffers of size %i\n", 3984 alloc_audio_buffers(peasycap);
3715 AUDIO_ISOC_BUFFER_MANY, 3985 if (rc < 0)
3716 peasycap->audio_isoc_buffer_size); 3986 return rc;
3717 JOM(4, ".... each occupying contiguous memory pages\n");
3718
3719 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3720 pbuf = (void *)__get_free_pages(GFP_KERNEL,
3721 AUDIO_ISOC_ORDER);
3722 if (!pbuf) {
3723 SAM("ERROR: Could not allocate isoc audio buffer "
3724 "%i\n", k);
3725 return -ENOMEM;
3726 }
3727 peasycap->allocation_audio_page +=
3728 BIT(AUDIO_ISOC_ORDER);
3729
3730 peasycap->audio_isoc_buffer[k].pgo = pbuf;
3731 peasycap->audio_isoc_buffer[k].pto = pbuf +
3732 peasycap->audio_isoc_buffer_size;
3733 peasycap->audio_isoc_buffer[k].kount = k;
3734 }
3735 JOM(4, "allocation of isoc audio buffers done.\n");
3736 3987
3737 /* Allocate and initialize urbs */ 3988 /* Allocate and initialize urbs */
3738 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); 3989 rc = create_audio_urbs(peasycap);
3739 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", 3990 if (rc < 0)
3740 peasycap->audio_isoc_framesperdesc); 3991 return rc;
3741 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
3742 peasycap->audio_isoc_maxframesize);
3743 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
3744 peasycap->audio_isoc_buffer_size);
3745
3746 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3747 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
3748 GFP_KERNEL);
3749 if (!purb) {
3750 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3751 "%i\n", k);
3752 return -ENOMEM;
3753 }
3754 peasycap->allocation_audio_urb += 1 ;
3755 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3756 if (!pdata_urb) {
3757 usb_free_urb(purb);
3758 SAM("ERROR: Could not allocate struct data_urb.\n");
3759 return -ENOMEM;
3760 }
3761 peasycap->allocation_audio_struct +=
3762 sizeof(struct data_urb);
3763
3764 pdata_urb->purb = purb;
3765 pdata_urb->isbuf = k;
3766 pdata_urb->length = 0;
3767 list_add_tail(&(pdata_urb->list_head),
3768 peasycap->purb_audio_head);
3769
3770 if (!k) {
3771 JOM(4, "initializing audio urbs thus:\n");
3772 JOM(4, " purb->interval = 1;\n");
3773 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3774 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
3775 "pusb_device,%i);\n",
3776 peasycap->audio_endpointnumber);
3777 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3778 JOM(4, " purb->transfer_buffer = "
3779 "peasycap->audio_isoc_buffer[.].pgo;\n");
3780 JOM(4, " purb->transfer_buffer_length = %i;\n",
3781 peasycap->audio_isoc_buffer_size);
3782 JOM(4, " purb->complete = easycap_alsa_complete;\n");
3783 JOM(4, " purb->context = peasycap;\n");
3784 JOM(4, " purb->start_frame = 0;\n");
3785 JOM(4, " purb->number_of_packets = %i;\n",
3786 peasycap->audio_isoc_framesperdesc);
3787 JOM(4, " for (j = 0; j < %i; j++)\n",
3788 peasycap->audio_isoc_framesperdesc);
3789 JOM(4, " {\n");
3790 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3791 peasycap->audio_isoc_maxframesize);
3792 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3793 peasycap->audio_isoc_maxframesize);
3794 JOM(4, " }\n");
3795 }
3796
3797 purb->interval = 1;
3798 purb->dev = peasycap->pusb_device;
3799 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3800 peasycap->audio_endpointnumber);
3801 purb->transfer_flags = URB_ISO_ASAP;
3802 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
3803 purb->transfer_buffer_length =
3804 peasycap->audio_isoc_buffer_size;
3805 purb->complete = easycap_alsa_complete;
3806 purb->context = peasycap;
3807 purb->start_frame = 0;
3808 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
3809 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
3810 purb->iso_frame_desc[j].offset = j *
3811 peasycap->audio_isoc_maxframesize;
3812 purb->iso_frame_desc[j].length =
3813 peasycap->audio_isoc_maxframesize;
3814 }
3815 }
3816 JOM(4, "allocation of %i struct urb done.\n", k);
3817 3992
3818 /* Save pointer peasycap in this interface */ 3993 /* Save pointer peasycap in this interface */
3819 usb_set_intfdata(intf, peasycap); 3994 usb_set_intfdata(intf, peasycap);
@@ -3843,15 +4018,13 @@ static int easycap_usb_probe(struct usb_interface *intf,
3843 SAM("ends successfully for interface %i\n", bInterfaceNumber); 4018 SAM("ends successfully for interface %i\n", bInterfaceNumber);
3844 return 0; 4019 return 0;
3845} 4020}
3846/*****************************************************************************/ 4021
3847/*---------------------------------------------------------------------------*/
3848/* 4022/*
3849 * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY 4023 * When this function is called the device has already been
3850 * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. 4024 * physically unplugged.
3851 * 4025 * Hence, peasycap->pusb_device is no longer valid.
3852 * THIS FUNCTION AFFECTS ALSA. BEWARE. 4026 * This function affects alsa.
3853 */ 4027 */
3854/*---------------------------------------------------------------------------*/
3855static void easycap_usb_disconnect(struct usb_interface *pusb_interface) 4028static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3856{ 4029{
3857 struct usb_host_interface *pusb_host_interface; 4030 struct usb_host_interface *pusb_host_interface;
@@ -3876,6 +4049,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3876 minor = pusb_interface->minor; 4049 minor = pusb_interface->minor;
3877 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); 4050 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
3878 4051
4052 /* There is nothing to do for Interface Number 1 */
3879 if (1 == bInterfaceNumber) 4053 if (1 == bInterfaceNumber)
3880 return; 4054 return;
3881 4055
@@ -3884,11 +4058,8 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3884 SAY("ERROR: peasycap is NULL\n"); 4058 SAY("ERROR: peasycap is NULL\n");
3885 return; 4059 return;
3886 } 4060 }
3887/*---------------------------------------------------------------------------*/ 4061
3888/* 4062 /* If the waitqueues are not cleared a deadlock is possible */
3889 * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
3890*/
3891/*---------------------------------------------------------------------------*/
3892 peasycap->video_eof = 1; 4063 peasycap->video_eof = 1;
3893 peasycap->audio_eof = 1; 4064 peasycap->audio_eof = 1;
3894 wake_up_interruptible(&(peasycap->wq_video)); 4065 wake_up_interruptible(&(peasycap->wq_video));
@@ -3904,15 +4075,14 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3904 default: 4075 default:
3905 break; 4076 break;
3906 } 4077 }
3907/*--------------------------------------------------------------------------*/ 4078
3908/* 4079 /*
3909 * DEREGISTER 4080 * Deregister
3910 * 4081 * This procedure will block until easycap_poll(),
3911 * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO 4082 * video and audio ioctl are all unlocked.
3912 * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN 4083 * If this is not done an oops can occur when an easycap
3913 * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. 4084 * is unplugged while the urbs are running.
3914 */ 4085 */
3915/*--------------------------------------------------------------------------*/
3916 kd = easycap_isdongle(peasycap); 4086 kd = easycap_isdongle(peasycap);
3917 switch (bInterfaceNumber) { 4087 switch (bInterfaceNumber) {
3918 case 0: { 4088 case 0: {
@@ -3929,7 +4099,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3929 } else { 4099 } else {
3930 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); 4100 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
3931 } 4101 }
3932/*---------------------------------------------------------------------------*/
3933 if (!peasycap->v4l2_device.name[0]) { 4102 if (!peasycap->v4l2_device.name[0]) {
3934 SAM("ERROR: peasycap->v4l2_device.name is empty\n"); 4103 SAM("ERROR: peasycap->v4l2_device.name is empty\n");
3935 if (0 <= kd && DONGLE_MANY > kd) 4104 if (0 <= kd && DONGLE_MANY > kd)
@@ -3945,7 +4114,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3945 JOM(4, "intf[%i]: video_unregister_device() minor=%i\n", 4114 JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
3946 bInterfaceNumber, minor); 4115 bInterfaceNumber, minor);
3947 peasycap->registered_video--; 4116 peasycap->registered_video--;
3948/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3949 4117
3950 if (0 <= kd && DONGLE_MANY > kd) { 4118 if (0 <= kd && DONGLE_MANY > kd) {
3951 mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 4119 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
@@ -3981,12 +4149,12 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
3981 default: 4149 default:
3982 break; 4150 break;
3983 } 4151 }
3984/*---------------------------------------------------------------------------*/ 4152
3985/* 4153 /*
3986 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap 4154 * If no remaining references to peasycap,
3987 * (ALSO WHEN ALSA HAS BEEN IN USE) 4155 * call easycap_delete.
3988 */ 4156 * (Also when alsa has been in use)
3989/*---------------------------------------------------------------------------*/ 4157 */
3990 if (!peasycap->kref.refcount.counter) { 4158 if (!peasycap->kref.refcount.counter) {
3991 SAM("ERROR: peasycap->kref.refcount.counter is zero " 4159 SAM("ERROR: peasycap->kref.refcount.counter is zero "
3992 "so cannot call kref_put()\n"); 4160 "so cannot call kref_put()\n");
@@ -4021,17 +4189,11 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
4021 mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 4189 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
4022 JOT(4, "unlocked dongle[%i].mutex_video\n", kd); 4190 JOT(4, "unlocked dongle[%i].mutex_video\n", kd);
4023 } 4191 }
4024/*---------------------------------------------------------------------------*/
4025 JOM(4, "ends\n"); 4192 JOM(4, "ends\n");
4026 return; 4193 return;
4027} 4194}
4028/*****************************************************************************/
4029 4195
4030/*---------------------------------------------------------------------------*/ 4196/* Devices supported by this driver */
4031/*
4032 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
4033 */
4034/*---------------------------------------------------------------------------*/
4035static struct usb_device_id easycap_usb_device_id_table[] = { 4197static struct usb_device_id easycap_usb_device_id_table[] = {
4036 {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)}, 4198 {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)},
4037 { } 4199 { }
@@ -4066,14 +4228,11 @@ static int __init easycap_module_init(void)
4066 4228
4067 return rc; 4229 return rc;
4068} 4230}
4069/*****************************************************************************/ 4231
4070static void __exit easycap_module_exit(void) 4232static void __exit easycap_module_exit(void)
4071{ 4233{
4072 usb_deregister(&easycap_usb_driver); 4234 usb_deregister(&easycap_usb_driver);
4073} 4235}
4074/*****************************************************************************/
4075 4236
4076module_init(easycap_module_init); 4237module_init(easycap_module_init);
4077module_exit(easycap_module_exit); 4238module_exit(easycap_module_exit);
4078
4079/*****************************************************************************/
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 3ef4cd8b4de3..c184ad30fbd8 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -76,7 +76,6 @@ static void abort_queued(struct go7007 *go)
76 76
77static int go7007_streamoff(struct go7007 *go) 77static int go7007_streamoff(struct go7007 *go)
78{ 78{
79 int retval = -EINVAL;
80 unsigned long flags; 79 unsigned long flags;
81 80
82 mutex_lock(&go->hw_lock); 81 mutex_lock(&go->hw_lock);
@@ -87,7 +86,6 @@ static int go7007_streamoff(struct go7007 *go)
87 abort_queued(go); 86 abort_queued(go);
88 spin_unlock_irqrestore(&go->spinlock, flags); 87 spin_unlock_irqrestore(&go->spinlock, flags);
89 go7007_reset_encoder(go); 88 go7007_reset_encoder(go);
90 retval = 0;
91 } 89 }
92 mutex_unlock(&go->hw_lock); 90 mutex_unlock(&go->hw_lock);
93 return 0; 91 return 0;
diff --git a/drivers/staging/media/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c
index 7c5af4f289b6..f1bd159ac195 100644
--- a/drivers/staging/media/go7007/s2250-loader.c
+++ b/drivers/staging/media/go7007/s2250-loader.c
@@ -165,3 +165,5 @@ module_usb_driver(s2250loader_driver);
165MODULE_AUTHOR(""); 165MODULE_AUTHOR("");
166MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251"); 166MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
167MODULE_LICENSE("GPL v2"); 167MODULE_LICENSE("GPL v2");
168MODULE_FIRMWARE(S2250_LOADER_FIRMWARE);
169MODULE_FIRMWARE(S2250_FIRMWARE);
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index d7cf5ef076a5..2944fde89f44 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -70,10 +70,6 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
70static int ir_open(void *data); 70static int ir_open(void *data);
71static void ir_close(void *data); 71static void ir_close(void *data);
72 72
73/* Driver init/exit prototypes */
74static int __init imon_init(void);
75static void __exit imon_exit(void);
76
77/*** G L O B A L S ***/ 73/*** G L O B A L S ***/
78#define IMON_DATA_BUF_SZ 35 74#define IMON_DATA_BUF_SZ 35
79 75
diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c
index 352a20229ca2..f4e4d9003f38 100644
--- a/drivers/staging/media/lirc/lirc_sasem.c
+++ b/drivers/staging/media/lirc/lirc_sasem.c
@@ -80,10 +80,6 @@ static ssize_t vfd_write(struct file *file, const char *buf,
80static int ir_open(void *data); 80static int ir_open(void *data);
81static void ir_close(void *data); 81static void ir_close(void *data);
82 82
83/* Driver init/exit prototypes */
84static int __init sasem_init(void);
85static void __exit sasem_exit(void);
86
87/*** G L O B A L S ***/ 83/*** G L O B A L S ***/
88#define SASEM_DATA_BUF_SZ 32 84#define SASEM_DATA_BUF_SZ 32
89 85
diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
index 0cdf89d32a15..104ae9c81251 100644
--- a/drivers/usb/gadget/uvc_queue.c
+++ b/drivers/usb/gadget/uvc_queue.c
@@ -543,7 +543,7 @@ done:
543 return ret; 543 return ret;
544} 544}
545 545
546/* called with queue->irqlock held.. */ 546/* called with &queue_irqlock held.. */
547static struct uvc_buffer * 547static struct uvc_buffer *
548uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) 548uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
549{ 549{
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c
index 54d7ca559cb2..2ca9386d655b 100644
--- a/drivers/usb/gadget/uvc_v4l2.c
+++ b/drivers/usb/gadget/uvc_v4l2.c
@@ -296,7 +296,7 @@ uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
296 if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST) 296 if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
297 return -EINVAL; 297 return -EINVAL;
298 298
299 return v4l2_event_subscribe(&handle->vfh, arg, 2); 299 return v4l2_event_subscribe(&handle->vfh, arg, 2, NULL);
300 } 300 }
301 301
302 case VIDIOC_UNSUBSCRIBE_EVENT: 302 case VIDIOC_UNSUBSCRIBE_EVENT:
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 39737839ce29..74af192ef7ae 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -383,6 +383,7 @@ header-y += utime.h
383header-y += utsname.h 383header-y += utsname.h
384header-y += uuid.h 384header-y += uuid.h
385header-y += uvcvideo.h 385header-y += uvcvideo.h
386header-y += v4l2-dv-timings.h
386header-y += v4l2-mediabus.h 387header-y += v4l2-mediabus.h
387header-y += v4l2-subdev.h 388header-y += v4l2-subdev.h
388header-y += veth.h 389header-y += veth.h
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index cb4428ab81ed..f50d4058c5fb 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -320,7 +320,24 @@ struct dvb_frontend_event {
320 320
321#define DTV_ENUM_DELSYS 44 321#define DTV_ENUM_DELSYS 44
322 322
323#define DTV_MAX_COMMAND DTV_ENUM_DELSYS 323/* ATSC-MH */
324#define DTV_ATSCMH_FIC_VER 45
325#define DTV_ATSCMH_PARADE_ID 46
326#define DTV_ATSCMH_NOG 47
327#define DTV_ATSCMH_TNOG 48
328#define DTV_ATSCMH_SGN 49
329#define DTV_ATSCMH_PRC 50
330#define DTV_ATSCMH_RS_FRAME_MODE 51
331#define DTV_ATSCMH_RS_FRAME_ENSEMBLE 52
332#define DTV_ATSCMH_RS_CODE_MODE_PRI 53
333#define DTV_ATSCMH_RS_CODE_MODE_SEC 54
334#define DTV_ATSCMH_SCCC_BLOCK_MODE 55
335#define DTV_ATSCMH_SCCC_CODE_MODE_A 56
336#define DTV_ATSCMH_SCCC_CODE_MODE_B 57
337#define DTV_ATSCMH_SCCC_CODE_MODE_C 58
338#define DTV_ATSCMH_SCCC_CODE_MODE_D 59
339
340#define DTV_MAX_COMMAND DTV_ATSCMH_SCCC_CODE_MODE_D
324 341
325typedef enum fe_pilot { 342typedef enum fe_pilot {
326 PILOT_ON, 343 PILOT_ON,
@@ -360,6 +377,38 @@ typedef enum fe_delivery_system {
360 377
361#define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A 378#define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A
362 379
380/* ATSC-MH */
381
382enum atscmh_sccc_block_mode {
383 ATSCMH_SCCC_BLK_SEP = 0,
384 ATSCMH_SCCC_BLK_COMB = 1,
385 ATSCMH_SCCC_BLK_RES = 2,
386};
387
388enum atscmh_sccc_code_mode {
389 ATSCMH_SCCC_CODE_HLF = 0,
390 ATSCMH_SCCC_CODE_QTR = 1,
391 ATSCMH_SCCC_CODE_RES = 2,
392};
393
394enum atscmh_rs_frame_ensemble {
395 ATSCMH_RSFRAME_ENS_PRI = 0,
396 ATSCMH_RSFRAME_ENS_SEC = 1,
397};
398
399enum atscmh_rs_frame_mode {
400 ATSCMH_RSFRAME_PRI_ONLY = 0,
401 ATSCMH_RSFRAME_PRI_SEC = 1,
402 ATSCMH_RSFRAME_RES = 2,
403};
404
405enum atscmh_rs_code_mode {
406 ATSCMH_RSCODE_211_187 = 0,
407 ATSCMH_RSCODE_223_187 = 1,
408 ATSCMH_RSCODE_235_187 = 2,
409 ATSCMH_RSCODE_RES = 3,
410};
411
363 412
364struct dtv_cmds_h { 413struct dtv_cmds_h {
365 char *name; /* A display name for debugging purposes */ 414 char *name; /* A display name for debugging purposes */
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 0559e2bd38f9..43d9e8d462d4 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
24#define _DVBVERSION_H_ 24#define _DVBVERSION_H_
25 25
26#define DVB_API_VERSION 5 26#define DVB_API_VERSION 5
27#define DVB_API_VERSION_MINOR 5 27#define DVB_API_VERSION_MINOR 6
28 28
29#endif /*_DVBVERSION_H_*/ 29#endif /*_DVBVERSION_H_*/
diff --git a/drivers/input/fixp-arith.h b/include/linux/fixp-arith.h
index 3089d7382325..3089d7382325 100644
--- a/drivers/input/fixp-arith.h
+++ b/include/linux/fixp-arith.h
diff --git a/include/linux/v4l2-dv-timings.h b/include/linux/v4l2-dv-timings.h
new file mode 100644
index 000000000000..9ef8172e5ed0
--- /dev/null
+++ b/include/linux/v4l2-dv-timings.h
@@ -0,0 +1,816 @@
1/*
2 * V4L2 DV timings header.
3 *
4 * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#ifndef _V4L2_DV_TIMINGS_H
22#define _V4L2_DV_TIMINGS_H
23
24#if __GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ < 6))
25/* Sadly gcc versions older than 4.6 have a bug in how they initialize
26 anonymous unions where they require additional curly brackets.
27 This violates the C1x standard. This workaround adds the curly brackets
28 if needed. */
29#define V4L2_INIT_BT_TIMINGS(_width, args...) \
30 { .bt = { _width , ## args } }
31#else
32#define V4L2_INIT_BT_TIMINGS(_width, args...) \
33 .bt = { _width , ## args }
34#endif
35
36/* CEA-861-E timings (i.e. standard HDTV timings) */
37
38#define V4L2_DV_BT_CEA_640X480P59_94 { \
39 .type = V4L2_DV_BT_656_1120, \
40 V4L2_INIT_BT_TIMINGS(640, 480, 0, 0, \
41 25175000, 16, 96, 48, 10, 2, 33, 0, 0, 0, \
42 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, 0) \
43}
44
45#define V4L2_DV_BT_CEA_720X480P59_94 { \
46 .type = V4L2_DV_BT_656_1120, \
47 V4L2_INIT_BT_TIMINGS(720, 480, 0, 0, \
48 27000000, 16, 62, 60, 9, 6, 30, 0, 0, 0, \
49 V4L2_DV_BT_STD_CEA861, 0) \
50}
51
52#define V4L2_DV_BT_CEA_720X576P50 { \
53 .type = V4L2_DV_BT_656_1120, \
54 V4L2_INIT_BT_TIMINGS(720, 576, 0, 0, \
55 27000000, 12, 64, 68, 5, 5, 39, 0, 0, 0, \
56 V4L2_DV_BT_STD_CEA861, 0) \
57}
58
59#define V4L2_DV_BT_CEA_1280X720P24 { \
60 .type = V4L2_DV_BT_656_1120, \
61 V4L2_INIT_BT_TIMINGS(1280, 720, 0, \
62 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
63 59400000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, \
64 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, \
65 V4L2_DV_FL_CAN_REDUCE_FPS) \
66}
67
68#define V4L2_DV_BT_CEA_1280X720P25 { \
69 .type = V4L2_DV_BT_656_1120, \
70 V4L2_INIT_BT_TIMINGS(1280, 720, 0, \
71 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
72 74250000, 2420, 40, 220, 5, 5, 20, 0, 0, 0, \
73 V4L2_DV_BT_STD_CEA861, 0) \
74}
75
76#define V4L2_DV_BT_CEA_1280X720P30 { \
77 .type = V4L2_DV_BT_656_1120, \
78 V4L2_INIT_BT_TIMINGS(1280, 720, 0, \
79 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
80 74250000, 1760, 40, 220, 5, 5, 20, 0, 0, 0, \
81 V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
82}
83
84#define V4L2_DV_BT_CEA_1280X720P50 { \
85 .type = V4L2_DV_BT_656_1120, \
86 V4L2_INIT_BT_TIMINGS(1280, 720, 0, \
87 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
88 74250000, 440, 40, 220, 5, 5, 20, 0, 0, 0, \
89 V4L2_DV_BT_STD_CEA861, 0) \
90}
91
92#define V4L2_DV_BT_CEA_1280X720P60 { \
93 .type = V4L2_DV_BT_656_1120, \
94 V4L2_INIT_BT_TIMINGS(1280, 720, 0, \
95 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
96 74250000, 110, 40, 220, 5, 5, 20, 0, 0, 0, \
97 V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
98}
99
100#define V4L2_DV_BT_CEA_1920X1080P24 { \
101 .type = V4L2_DV_BT_656_1120, \
102 V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
103 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
104 74250000, 638, 44, 148, 4, 5, 36, 0, 0, 0, \
105 V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
106}
107
108#define V4L2_DV_BT_CEA_1920X1080P25 { \
109 .type = V4L2_DV_BT_656_1120, \
110 V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
111 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
112 74250000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \
113 V4L2_DV_BT_STD_CEA861, 0) \
114}
115
116#define V4L2_DV_BT_CEA_1920X1080P30 { \
117 .type = V4L2_DV_BT_656_1120, \
118 V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
119 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
120 74250000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \
121 V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \
122}
123
124#define V4L2_DV_BT_CEA_1920X1080I50 { \
125 .type = V4L2_DV_BT_656_1120, \
126 V4L2_INIT_BT_TIMINGS(1920, 1080, 1, \
127 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
128 74250000, 528, 44, 148, 2, 5, 15, 2, 5, 16, \
129 V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_HALF_LINE) \
130}
131
132#define V4L2_DV_BT_CEA_1920X1080P50 { \
133 .type = V4L2_DV_BT_656_1120, \
134 V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
135 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
136 148500000, 528, 44, 148, 4, 5, 36, 0, 0, 0, \
137 V4L2_DV_BT_STD_CEA861, 0) \
138}
139
140#define V4L2_DV_BT_CEA_1920X1080I60 { \
141 .type = V4L2_DV_BT_656_1120, \
142 V4L2_INIT_BT_TIMINGS(1920, 1080, 1, \
143 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
144 74250000, 88, 44, 148, 2, 5, 15, 2, 5, 16, \
145 V4L2_DV_BT_STD_CEA861, \
146 V4L2_DV_FL_CAN_REDUCE_FPS | V4L2_DV_FL_HALF_LINE) \
147}
148
149#define V4L2_DV_BT_CEA_1920X1080P60 { \
150 .type = V4L2_DV_BT_656_1120, \
151 V4L2_INIT_BT_TIMINGS(1920, 1080, 0, \
152 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
153 148500000, 88, 44, 148, 4, 5, 36, 0, 0, 0, \
154 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CEA861, \
155 V4L2_DV_FL_CAN_REDUCE_FPS) \
156}
157
158
159/* VESA Discrete Monitor Timings as per version 1.0, revision 12 */
160
161#define V4L2_DV_BT_DMT_640X350P85 { \
162 .type = V4L2_DV_BT_656_1120, \
163 V4L2_INIT_BT_TIMINGS(640, 350, 0, V4L2_DV_HSYNC_POS_POL, \
164 31500000, 32, 64, 96, 32, 3, 60, 0, 0, 0, \
165 V4L2_DV_BT_STD_DMT, 0) \
166}
167
168#define V4L2_DV_BT_DMT_640X400P85 { \
169 .type = V4L2_DV_BT_656_1120, \
170 V4L2_INIT_BT_TIMINGS(640, 400, 0, V4L2_DV_VSYNC_POS_POL, \
171 31500000, 32, 64, 96, 1, 3, 41, 0, 0, 0, \
172 V4L2_DV_BT_STD_DMT, 0) \
173}
174
175#define V4L2_DV_BT_DMT_720X400P85 { \
176 .type = V4L2_DV_BT_656_1120, \
177 V4L2_INIT_BT_TIMINGS(720, 400, 0, V4L2_DV_VSYNC_POS_POL, \
178 35500000, 36, 72, 108, 1, 3, 42, 0, 0, 0, \
179 V4L2_DV_BT_STD_DMT, 0) \
180}
181
182/* VGA resolutions */
183#define V4L2_DV_BT_DMT_640X480P60 V4L2_DV_BT_CEA_640X480P59_94
184
185#define V4L2_DV_BT_DMT_640X480P72 { \
186 .type = V4L2_DV_BT_656_1120, \
187 V4L2_INIT_BT_TIMINGS(640, 480, 0, 0, \
188 31500000, 24, 40, 128, 9, 3, 28, 0, 0, 0, \
189 V4L2_DV_BT_STD_DMT, 0) \
190}
191
192#define V4L2_DV_BT_DMT_640X480P75 { \
193 .type = V4L2_DV_BT_656_1120, \
194 V4L2_INIT_BT_TIMINGS(640, 480, 0, 0, \
195 31500000, 16, 64, 120, 1, 3, 16, 0, 0, 0, \
196 V4L2_DV_BT_STD_DMT, 0) \
197}
198
199#define V4L2_DV_BT_DMT_640X480P85 { \
200 .type = V4L2_DV_BT_656_1120, \
201 V4L2_INIT_BT_TIMINGS(640, 480, 0, 0, \
202 36000000, 56, 56, 80, 1, 3, 25, 0, 0, 0, \
203 V4L2_DV_BT_STD_DMT, 0) \
204}
205
206/* SVGA resolutions */
207#define V4L2_DV_BT_DMT_800X600P56 { \
208 .type = V4L2_DV_BT_656_1120, \
209 V4L2_INIT_BT_TIMINGS(800, 600, 0, \
210 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
211 36000000, 24, 72, 128, 1, 2, 22, 0, 0, 0, \
212 V4L2_DV_BT_STD_DMT, 0) \
213}
214
215#define V4L2_DV_BT_DMT_800X600P60 { \
216 .type = V4L2_DV_BT_656_1120, \
217 V4L2_INIT_BT_TIMINGS(800, 600, 0, \
218 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
219 40000000, 40, 128, 88, 1, 4, 23, 0, 0, 0, \
220 V4L2_DV_BT_STD_DMT, 0) \
221}
222
223#define V4L2_DV_BT_DMT_800X600P72 { \
224 .type = V4L2_DV_BT_656_1120, \
225 V4L2_INIT_BT_TIMINGS(800, 600, 0, \
226 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
227 50000000, 56, 120, 64, 37, 6, 23, 0, 0, 0, \
228 V4L2_DV_BT_STD_DMT, 0) \
229}
230
231#define V4L2_DV_BT_DMT_800X600P75 { \
232 .type = V4L2_DV_BT_656_1120, \
233 V4L2_INIT_BT_TIMINGS(800, 600, 0, \
234 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
235 49500000, 16, 80, 160, 1, 3, 21, 0, 0, 0, \
236 V4L2_DV_BT_STD_DMT, 0) \
237}
238
239#define V4L2_DV_BT_DMT_800X600P85 { \
240 .type = V4L2_DV_BT_656_1120, \
241 V4L2_INIT_BT_TIMINGS(800, 600, 0, \
242 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
243 56250000, 32, 64, 152, 1, 3, 27, 0, 0, 0, \
244 V4L2_DV_BT_STD_DMT, 0) \
245}
246
247#define V4L2_DV_BT_DMT_800X600P120_RB { \
248 .type = V4L2_DV_BT_656_1120, \
249 V4L2_INIT_BT_TIMINGS(800, 600, 0, V4L2_DV_HSYNC_POS_POL, \
250 73250000, 48, 32, 80, 3, 4, 29, 0, 0, 0, \
251 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
252 V4L2_DV_FL_REDUCED_BLANKING) \
253}
254
255#define V4L2_DV_BT_DMT_848X480P60 { \
256 .type = V4L2_DV_BT_656_1120, \
257 V4L2_INIT_BT_TIMINGS(848, 480, 0, \
258 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
259 33750000, 16, 112, 112, 6, 8, 23, 0, 0, 0, \
260 V4L2_DV_BT_STD_DMT, 0) \
261}
262
263#define V4L2_DV_BT_DMT_1024X768I43 { \
264 .type = V4L2_DV_BT_656_1120, \
265 V4L2_INIT_BT_TIMINGS(1024, 768, 1, \
266 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
267 44900000, 8, 176, 56, 0, 4, 20, 0, 4, 21, \
268 V4L2_DV_BT_STD_DMT, 0) \
269}
270
271/* XGA resolutions */
272#define V4L2_DV_BT_DMT_1024X768P60 { \
273 .type = V4L2_DV_BT_656_1120, \
274 V4L2_INIT_BT_TIMINGS(1024, 768, 0, 0, \
275 65000000, 24, 136, 160, 3, 6, 29, 0, 0, 0, \
276 V4L2_DV_BT_STD_DMT, 0) \
277}
278
279#define V4L2_DV_BT_DMT_1024X768P70 { \
280 .type = V4L2_DV_BT_656_1120, \
281 V4L2_INIT_BT_TIMINGS(1024, 768, 0, 0, \
282 75000000, 24, 136, 144, 3, 6, 29, 0, 0, 0, \
283 V4L2_DV_BT_STD_DMT, 0) \
284}
285
286#define V4L2_DV_BT_DMT_1024X768P75 { \
287 .type = V4L2_DV_BT_656_1120, \
288 V4L2_INIT_BT_TIMINGS(1024, 768, 0, \
289 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
290 78750000, 16, 96, 176, 1, 3, 28, 0, 0, 0, \
291 V4L2_DV_BT_STD_DMT, 0) \
292}
293
294#define V4L2_DV_BT_DMT_1024X768P85 { \
295 .type = V4L2_DV_BT_656_1120, \
296 V4L2_INIT_BT_TIMINGS(1024, 768, 0, \
297 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
298 94500000, 48, 96, 208, 1, 3, 36, 0, 0, 0, \
299 V4L2_DV_BT_STD_DMT, 0) \
300}
301
302#define V4L2_DV_BT_DMT_1024X768P120_RB { \
303 .type = V4L2_DV_BT_656_1120, \
304 V4L2_INIT_BT_TIMINGS(1024, 768, 0, V4L2_DV_HSYNC_POS_POL, \
305 115500000, 48, 32, 80, 3, 4, 38, 0, 0, 0, \
306 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
307 V4L2_DV_FL_REDUCED_BLANKING) \
308}
309
310/* XGA+ resolution */
311#define V4L2_DV_BT_DMT_1152X864P75 { \
312 .type = V4L2_DV_BT_656_1120, \
313 V4L2_INIT_BT_TIMINGS(1152, 864, 0, \
314 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
315 108000000, 64, 128, 256, 1, 3, 32, 0, 0, 0, \
316 V4L2_DV_BT_STD_DMT, 0) \
317}
318
319#define V4L2_DV_BT_DMT_1280X720P60 V4L2_DV_BT_CEA_1280X720P60
320
321/* WXGA resolutions */
322#define V4L2_DV_BT_DMT_1280X768P60_RB { \
323 .type = V4L2_DV_BT_656_1120, \
324 V4L2_INIT_BT_TIMINGS(1280, 768, 0, V4L2_DV_HSYNC_POS_POL, \
325 68250000, 48, 32, 80, 3, 7, 12, 0, 0, 0, \
326 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
327 V4L2_DV_FL_REDUCED_BLANKING) \
328}
329
330#define V4L2_DV_BT_DMT_1280X768P60 { \
331 .type = V4L2_DV_BT_656_1120, \
332 V4L2_INIT_BT_TIMINGS(1280, 768, 0, V4L2_DV_VSYNC_POS_POL, \
333 79500000, 64, 128, 192, 3, 7, 20, 0, 0, 0, \
334 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
335}
336
337#define V4L2_DV_BT_DMT_1280X768P75 { \
338 .type = V4L2_DV_BT_656_1120, \
339 V4L2_INIT_BT_TIMINGS(1280, 768, 0, V4L2_DV_VSYNC_POS_POL, \
340 102250000, 80, 128, 208, 3, 7, 27, 0, 0, 0, \
341 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
342}
343
344#define V4L2_DV_BT_DMT_1280X768P85 { \
345 .type = V4L2_DV_BT_656_1120, \
346 V4L2_INIT_BT_TIMINGS(1280, 768, 0, V4L2_DV_VSYNC_POS_POL, \
347 117500000, 80, 136, 216, 3, 7, 31, 0, 0, 0, \
348 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
349}
350
351#define V4L2_DV_BT_DMT_1280X768P120_RB { \
352 .type = V4L2_DV_BT_656_1120, \
353 V4L2_INIT_BT_TIMINGS(1280, 768, 0, V4L2_DV_HSYNC_POS_POL, \
354 140250000, 48, 32, 80, 3, 7, 35, 0, 0, 0, \
355 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
356 V4L2_DV_FL_REDUCED_BLANKING) \
357}
358
359#define V4L2_DV_BT_DMT_1280X800P60_RB { \
360 .type = V4L2_DV_BT_656_1120, \
361 V4L2_INIT_BT_TIMINGS(1280, 800, 0, V4L2_DV_HSYNC_POS_POL, \
362 71000000, 48, 32, 80, 3, 6, 14, 0, 0, 0, \
363 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
364 V4L2_DV_FL_REDUCED_BLANKING) \
365}
366
367#define V4L2_DV_BT_DMT_1280X800P60 { \
368 .type = V4L2_DV_BT_656_1120, \
369 V4L2_INIT_BT_TIMINGS(1280, 800, 0, V4L2_DV_VSYNC_POS_POL, \
370 83500000, 72, 128, 200, 3, 6, 22, 0, 0, 0, \
371 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
372}
373
374#define V4L2_DV_BT_DMT_1280X800P75 { \
375 .type = V4L2_DV_BT_656_1120, \
376 V4L2_INIT_BT_TIMINGS(1280, 800, 0, V4L2_DV_VSYNC_POS_POL, \
377 106500000, 80, 128, 208, 3, 6, 29, 0, 0, 0, \
378 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
379}
380
381#define V4L2_DV_BT_DMT_1280X800P85 { \
382 .type = V4L2_DV_BT_656_1120, \
383 V4L2_INIT_BT_TIMINGS(1280, 800, 0, V4L2_DV_VSYNC_POS_POL, \
384 122500000, 80, 136, 216, 3, 6, 34, 0, 0, 0, \
385 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
386}
387
388#define V4L2_DV_BT_DMT_1280X800P120_RB { \
389 .type = V4L2_DV_BT_656_1120, \
390 V4L2_INIT_BT_TIMINGS(1280, 800, 0, V4L2_DV_HSYNC_POS_POL, \
391 146250000, 48, 32, 80, 3, 6, 38, 0, 0, 0, \
392 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
393 V4L2_DV_FL_REDUCED_BLANKING) \
394}
395
396#define V4L2_DV_BT_DMT_1280X960P60 { \
397 .type = V4L2_DV_BT_656_1120, \
398 V4L2_INIT_BT_TIMINGS(1280, 960, 0, \
399 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
400 108000000, 96, 112, 312, 1, 3, 36, 0, 0, 0, \
401 V4L2_DV_BT_STD_DMT, 0) \
402}
403
404#define V4L2_DV_BT_DMT_1280X960P85 { \
405 .type = V4L2_DV_BT_656_1120, \
406 V4L2_INIT_BT_TIMINGS(1280, 960, 0, \
407 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
408 148500000, 64, 160, 224, 1, 3, 47, 0, 0, 0, \
409 V4L2_DV_BT_STD_DMT, 0) \
410}
411
412#define V4L2_DV_BT_DMT_1280X960P120_RB { \
413 .type = V4L2_DV_BT_656_1120, \
414 V4L2_INIT_BT_TIMINGS(1280, 960, 0, V4L2_DV_HSYNC_POS_POL, \
415 175500000, 48, 32, 80, 3, 4, 50, 0, 0, 0, \
416 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
417 V4L2_DV_FL_REDUCED_BLANKING) \
418}
419
420/* SXGA resolutions */
421#define V4L2_DV_BT_DMT_1280X1024P60 { \
422 .type = V4L2_DV_BT_656_1120, \
423 V4L2_INIT_BT_TIMINGS(1280, 1024, 0, \
424 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
425 108000000, 48, 112, 248, 1, 3, 38, 0, 0, 0, \
426 V4L2_DV_BT_STD_DMT, 0) \
427}
428
429#define V4L2_DV_BT_DMT_1280X1024P75 { \
430 .type = V4L2_DV_BT_656_1120, \
431 V4L2_INIT_BT_TIMINGS(1280, 1024, 0, \
432 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
433 135000000, 16, 144, 248, 1, 3, 38, 0, 0, 0, \
434 V4L2_DV_BT_STD_DMT, 0) \
435}
436
437#define V4L2_DV_BT_DMT_1280X1024P85 { \
438 .type = V4L2_DV_BT_656_1120, \
439 V4L2_INIT_BT_TIMINGS(1280, 1024, 0, \
440 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
441 157500000, 64, 160, 224, 1, 3, 44, 0, 0, 0, \
442 V4L2_DV_BT_STD_DMT, 0) \
443}
444
445#define V4L2_DV_BT_DMT_1280X1024P120_RB { \
446 .type = V4L2_DV_BT_656_1120, \
447 V4L2_INIT_BT_TIMINGS(1280, 1024, 0, V4L2_DV_HSYNC_POS_POL, \
448 187250000, 48, 32, 80, 3, 7, 50, 0, 0, 0, \
449 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
450 V4L2_DV_FL_REDUCED_BLANKING) \
451}
452
453#define V4L2_DV_BT_DMT_1360X768P60 { \
454 .type = V4L2_DV_BT_656_1120, \
455 V4L2_INIT_BT_TIMINGS(1360, 768, 0, \
456 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
457 85500000, 64, 112, 256, 3, 6, 18, 0, 0, 0, \
458 V4L2_DV_BT_STD_DMT, 0) \
459}
460
461#define V4L2_DV_BT_DMT_1360X768P120_RB { \
462 .type = V4L2_DV_BT_656_1120, \
463 V4L2_INIT_BT_TIMINGS(1360, 768, 0, V4L2_DV_HSYNC_POS_POL, \
464 148250000, 48, 32, 80, 3, 5, 37, 0, 0, 0, \
465 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
466 V4L2_DV_FL_REDUCED_BLANKING) \
467}
468
469#define V4L2_DV_BT_DMT_1366X768P60 { \
470 .type = V4L2_DV_BT_656_1120, \
471 V4L2_INIT_BT_TIMINGS(1366, 768, 0, \
472 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
473 85500000, 70, 143, 213, 3, 3, 24, 0, 0, 0, \
474 V4L2_DV_BT_STD_DMT, 0) \
475}
476
477#define V4L2_DV_BT_DMT_1366X768P60_RB { \
478 .type = V4L2_DV_BT_656_1120, \
479 V4L2_INIT_BT_TIMINGS(1366, 768, 0, \
480 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
481 72000000, 14, 56, 64, 1, 3, 28, 0, 0, 0, \
482 V4L2_DV_BT_STD_DMT, V4L2_DV_FL_REDUCED_BLANKING) \
483}
484
485/* SXGA+ resolutions */
486#define V4L2_DV_BT_DMT_1400X1050P60_RB { \
487 .type = V4L2_DV_BT_656_1120, \
488 V4L2_INIT_BT_TIMINGS(1400, 1050, 0, V4L2_DV_HSYNC_POS_POL, \
489 101000000, 48, 32, 80, 3, 4, 23, 0, 0, 0, \
490 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
491 V4L2_DV_FL_REDUCED_BLANKING) \
492}
493
494#define V4L2_DV_BT_DMT_1400X1050P60 { \
495 .type = V4L2_DV_BT_656_1120, \
496 V4L2_INIT_BT_TIMINGS(1400, 1050, 0, V4L2_DV_VSYNC_POS_POL, \
497 121750000, 88, 144, 232, 3, 4, 32, 0, 0, 0, \
498 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
499}
500
501#define V4L2_DV_BT_DMT_1400X1050P75 { \
502 .type = V4L2_DV_BT_656_1120, \
503 V4L2_INIT_BT_TIMINGS(1400, 1050, 0, V4L2_DV_VSYNC_POS_POL, \
504 156000000, 104, 144, 248, 3, 4, 42, 0, 0, 0, \
505 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
506}
507
508#define V4L2_DV_BT_DMT_1400X1050P85 { \
509 .type = V4L2_DV_BT_656_1120, \
510 V4L2_INIT_BT_TIMINGS(1400, 1050, 0, V4L2_DV_VSYNC_POS_POL, \
511 179500000, 104, 152, 256, 3, 4, 48, 0, 0, 0, \
512 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
513}
514
515#define V4L2_DV_BT_DMT_1400X1050P120_RB { \
516 .type = V4L2_DV_BT_656_1120, \
517 V4L2_INIT_BT_TIMINGS(1400, 1050, 0, V4L2_DV_HSYNC_POS_POL, \
518 208000000, 48, 32, 80, 3, 4, 55, 0, 0, 0, \
519 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
520 V4L2_DV_FL_REDUCED_BLANKING) \
521}
522
523/* WXGA+ resolutions */
524#define V4L2_DV_BT_DMT_1440X900P60_RB { \
525 .type = V4L2_DV_BT_656_1120, \
526 V4L2_INIT_BT_TIMINGS(1440, 900, 0, V4L2_DV_HSYNC_POS_POL, \
527 88750000, 48, 32, 80, 3, 6, 17, 0, 0, 0, \
528 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
529 V4L2_DV_FL_REDUCED_BLANKING) \
530}
531
532#define V4L2_DV_BT_DMT_1440X900P60 { \
533 .type = V4L2_DV_BT_656_1120, \
534 V4L2_INIT_BT_TIMINGS(1440, 900, 0, V4L2_DV_VSYNC_POS_POL, \
535 106500000, 80, 152, 232, 3, 6, 25, 0, 0, 0, \
536 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
537}
538
539#define V4L2_DV_BT_DMT_1440X900P75 { \
540 .type = V4L2_DV_BT_656_1120, \
541 V4L2_INIT_BT_TIMINGS(1440, 900, 0, V4L2_DV_VSYNC_POS_POL, \
542 136750000, 96, 152, 248, 3, 6, 33, 0, 0, 0, \
543 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
544}
545
546#define V4L2_DV_BT_DMT_1440X900P85 { \
547 .type = V4L2_DV_BT_656_1120, \
548 V4L2_INIT_BT_TIMINGS(1440, 900, 0, V4L2_DV_VSYNC_POS_POL, \
549 157000000, 104, 152, 256, 3, 6, 39, 0, 0, 0, \
550 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
551}
552
553#define V4L2_DV_BT_DMT_1440X900P120_RB { \
554 .type = V4L2_DV_BT_656_1120, \
555 V4L2_INIT_BT_TIMINGS(1440, 900, 0, V4L2_DV_HSYNC_POS_POL, \
556 182750000, 48, 32, 80, 3, 6, 44, 0, 0, 0, \
557 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
558 V4L2_DV_FL_REDUCED_BLANKING) \
559}
560
561#define V4L2_DV_BT_DMT_1600X900P60_RB { \
562 .type = V4L2_DV_BT_656_1120, \
563 V4L2_INIT_BT_TIMINGS(1600, 900, 0, \
564 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
565 108000000, 24, 80, 96, 1, 3, 96, 0, 0, 0, \
566 V4L2_DV_BT_STD_DMT, V4L2_DV_FL_REDUCED_BLANKING) \
567}
568
569/* UXGA resolutions */
570#define V4L2_DV_BT_DMT_1600X1200P60 { \
571 .type = V4L2_DV_BT_656_1120, \
572 V4L2_INIT_BT_TIMINGS(1600, 1200, 0, \
573 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
574 162000000, 64, 192, 304, 1, 3, 46, 0, 0, 0, \
575 V4L2_DV_BT_STD_DMT, 0) \
576}
577
578#define V4L2_DV_BT_DMT_1600X1200P65 { \
579 .type = V4L2_DV_BT_656_1120, \
580 V4L2_INIT_BT_TIMINGS(1600, 1200, 0, \
581 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
582 175500000, 64, 192, 304, 1, 3, 46, 0, 0, 0, \
583 V4L2_DV_BT_STD_DMT, 0) \
584}
585
586#define V4L2_DV_BT_DMT_1600X1200P70 { \
587 .type = V4L2_DV_BT_656_1120, \
588 V4L2_INIT_BT_TIMINGS(1600, 1200, 0, \
589 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
590 189000000, 64, 192, 304, 1, 3, 46, 0, 0, 0, \
591 V4L2_DV_BT_STD_DMT, 0) \
592}
593
594#define V4L2_DV_BT_DMT_1600X1200P75 { \
595 .type = V4L2_DV_BT_656_1120, \
596 V4L2_INIT_BT_TIMINGS(1600, 1200, 0, \
597 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
598 202500000, 64, 192, 304, 1, 3, 46, 0, 0, 0, \
599 V4L2_DV_BT_STD_DMT, 0) \
600}
601
602#define V4L2_DV_BT_DMT_1600X1200P85 { \
603 .type = V4L2_DV_BT_656_1120, \
604 V4L2_INIT_BT_TIMINGS(1600, 1200, 0, \
605 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
606 229500000, 64, 192, 304, 1, 3, 46, 0, 0, 0, \
607 V4L2_DV_BT_STD_DMT, 0) \
608}
609
610#define V4L2_DV_BT_DMT_1600X1200P120_RB { \
611 .type = V4L2_DV_BT_656_1120, \
612 V4L2_INIT_BT_TIMINGS(1600, 1200, 0, V4L2_DV_HSYNC_POS_POL, \
613 268250000, 48, 32, 80, 3, 4, 64, 0, 0, 0, \
614 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
615 V4L2_DV_FL_REDUCED_BLANKING) \
616}
617
618/* WSXGA+ resolutions */
619#define V4L2_DV_BT_DMT_1680X1050P60_RB { \
620 .type = V4L2_DV_BT_656_1120, \
621 V4L2_INIT_BT_TIMINGS(1680, 1050, 0, V4L2_DV_HSYNC_POS_POL, \
622 119000000, 48, 32, 80, 3, 6, 21, 0, 0, 0, \
623 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
624 V4L2_DV_FL_REDUCED_BLANKING) \
625}
626
627#define V4L2_DV_BT_DMT_1680X1050P60 { \
628 .type = V4L2_DV_BT_656_1120, \
629 V4L2_INIT_BT_TIMINGS(1680, 1050, 0, V4L2_DV_VSYNC_POS_POL, \
630 146250000, 104, 176, 280, 3, 6, 30, 0, 0, 0, \
631 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
632}
633
634#define V4L2_DV_BT_DMT_1680X1050P75 { \
635 .type = V4L2_DV_BT_656_1120, \
636 V4L2_INIT_BT_TIMINGS(1680, 1050, 0, V4L2_DV_VSYNC_POS_POL, \
637 187000000, 120, 176, 296, 3, 6, 40, 0, 0, 0, \
638 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
639}
640
641#define V4L2_DV_BT_DMT_1680X1050P85 { \
642 .type = V4L2_DV_BT_656_1120, \
643 V4L2_INIT_BT_TIMINGS(1680, 1050, 0, V4L2_DV_VSYNC_POS_POL, \
644 214750000, 128, 176, 304, 3, 6, 46, 0, 0, 0, \
645 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
646}
647
648#define V4L2_DV_BT_DMT_1680X1050P120_RB { \
649 .type = V4L2_DV_BT_656_1120, \
650 V4L2_INIT_BT_TIMINGS(1680, 1050, 0, V4L2_DV_HSYNC_POS_POL, \
651 245500000, 48, 32, 80, 3, 6, 53, 0, 0, 0, \
652 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
653 V4L2_DV_FL_REDUCED_BLANKING) \
654}
655
656#define V4L2_DV_BT_DMT_1792X1344P60 { \
657 .type = V4L2_DV_BT_656_1120, \
658 V4L2_INIT_BT_TIMINGS(1792, 1344, 0, V4L2_DV_VSYNC_POS_POL, \
659 204750000, 128, 200, 328, 1, 3, 46, 0, 0, 0, \
660 V4L2_DV_BT_STD_DMT, 0) \
661}
662
663#define V4L2_DV_BT_DMT_1792X1344P75 { \
664 .type = V4L2_DV_BT_656_1120, \
665 V4L2_INIT_BT_TIMINGS(1792, 1344, 0, V4L2_DV_VSYNC_POS_POL, \
666 261000000, 96, 216, 352, 1, 3, 69, 0, 0, 0, \
667 V4L2_DV_BT_STD_DMT, 0) \
668}
669
670#define V4L2_DV_BT_DMT_1792X1344P120_RB { \
671 .type = V4L2_DV_BT_656_1120, \
672 V4L2_INIT_BT_TIMINGS(1792, 1344, 0, V4L2_DV_HSYNC_POS_POL, \
673 333250000, 48, 32, 80, 3, 4, 72, 0, 0, 0, \
674 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
675 V4L2_DV_FL_REDUCED_BLANKING) \
676}
677
678#define V4L2_DV_BT_DMT_1856X1392P60 { \
679 .type = V4L2_DV_BT_656_1120, \
680 V4L2_INIT_BT_TIMINGS(1856, 1392, 0, V4L2_DV_VSYNC_POS_POL, \
681 218250000, 96, 224, 352, 1, 3, 43, 0, 0, 0, \
682 V4L2_DV_BT_STD_DMT, 0) \
683}
684
685#define V4L2_DV_BT_DMT_1856X1392P75 { \
686 .type = V4L2_DV_BT_656_1120, \
687 V4L2_INIT_BT_TIMINGS(1856, 1392, 0, V4L2_DV_VSYNC_POS_POL, \
688 288000000, 128, 224, 352, 1, 3, 104, 0, 0, 0, \
689 V4L2_DV_BT_STD_DMT, 0) \
690}
691
692#define V4L2_DV_BT_DMT_1856X1392P120_RB { \
693 .type = V4L2_DV_BT_656_1120, \
694 V4L2_INIT_BT_TIMINGS(1856, 1392, 0, V4L2_DV_HSYNC_POS_POL, \
695 356500000, 48, 32, 80, 3, 4, 75, 0, 0, 0, \
696 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
697 V4L2_DV_FL_REDUCED_BLANKING) \
698}
699
700#define V4L2_DV_BT_DMT_1920X1080P60 V4L2_DV_BT_CEA_1920X1080P60
701
702/* WUXGA resolutions */
703#define V4L2_DV_BT_DMT_1920X1200P60_RB { \
704 .type = V4L2_DV_BT_656_1120, \
705 V4L2_INIT_BT_TIMINGS(1920, 1200, 0, V4L2_DV_HSYNC_POS_POL, \
706 154000000, 48, 32, 80, 3, 6, 26, 0, 0, 0, \
707 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
708 V4L2_DV_FL_REDUCED_BLANKING) \
709}
710
711#define V4L2_DV_BT_DMT_1920X1200P60 { \
712 .type = V4L2_DV_BT_656_1120, \
713 V4L2_INIT_BT_TIMINGS(1920, 1200, 0, V4L2_DV_VSYNC_POS_POL, \
714 193250000, 136, 200, 336, 3, 6, 36, 0, 0, 0, \
715 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
716}
717
718#define V4L2_DV_BT_DMT_1920X1200P75 { \
719 .type = V4L2_DV_BT_656_1120, \
720 V4L2_INIT_BT_TIMINGS(1920, 1200, 0, V4L2_DV_VSYNC_POS_POL, \
721 245250000, 136, 208, 344, 3, 6, 46, 0, 0, 0, \
722 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
723}
724
725#define V4L2_DV_BT_DMT_1920X1200P85 { \
726 .type = V4L2_DV_BT_656_1120, \
727 V4L2_INIT_BT_TIMINGS(1920, 1200, 0, V4L2_DV_VSYNC_POS_POL, \
728 281250000, 144, 208, 352, 3, 6, 53, 0, 0, 0, \
729 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
730}
731
732#define V4L2_DV_BT_DMT_1920X1200P120_RB { \
733 .type = V4L2_DV_BT_656_1120, \
734 V4L2_INIT_BT_TIMINGS(1920, 1200, 0, V4L2_DV_HSYNC_POS_POL, \
735 317000000, 48, 32, 80, 3, 6, 62, 0, 0, 0, \
736 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
737 V4L2_DV_FL_REDUCED_BLANKING) \
738}
739
740#define V4L2_DV_BT_DMT_1920X1440P60 { \
741 .type = V4L2_DV_BT_656_1120, \
742 V4L2_INIT_BT_TIMINGS(1920, 1440, 0, V4L2_DV_VSYNC_POS_POL, \
743 234000000, 128, 208, 344, 1, 3, 56, 0, 0, 0, \
744 V4L2_DV_BT_STD_DMT, 0) \
745}
746
747#define V4L2_DV_BT_DMT_1920X1440P75 { \
748 .type = V4L2_DV_BT_656_1120, \
749 V4L2_INIT_BT_TIMINGS(1920, 1440, 0, V4L2_DV_VSYNC_POS_POL, \
750 297000000, 144, 224, 352, 1, 3, 56, 0, 0, 0, \
751 V4L2_DV_BT_STD_DMT, 0) \
752}
753
754#define V4L2_DV_BT_DMT_1920X1440P120_RB { \
755 .type = V4L2_DV_BT_656_1120, \
756 V4L2_INIT_BT_TIMINGS(1920, 1440, 0, V4L2_DV_HSYNC_POS_POL, \
757 380500000, 48, 32, 80, 3, 4, 78, 0, 0, 0, \
758 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
759 V4L2_DV_FL_REDUCED_BLANKING) \
760}
761
762#define V4L2_DV_BT_DMT_2048X1152P60_RB { \
763 .type = V4L2_DV_BT_656_1120, \
764 V4L2_INIT_BT_TIMINGS(2048, 1152, 0, \
765 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
766 162000000, 26, 80, 96, 1, 3, 44, 0, 0, 0, \
767 V4L2_DV_BT_STD_DMT, V4L2_DV_FL_REDUCED_BLANKING) \
768}
769
770/* WQXGA resolutions */
771#define V4L2_DV_BT_DMT_2560X1600P60_RB { \
772 .type = V4L2_DV_BT_656_1120, \
773 V4L2_INIT_BT_TIMINGS(2560, 1600, 0, V4L2_DV_HSYNC_POS_POL, \
774 268500000, 48, 32, 80, 3, 6, 37, 0, 0, 0, \
775 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
776 V4L2_DV_FL_REDUCED_BLANKING) \
777}
778
779#define V4L2_DV_BT_DMT_2560X1600P60 { \
780 .type = V4L2_DV_BT_656_1120, \
781 V4L2_INIT_BT_TIMINGS(2560, 1600, 0, V4L2_DV_VSYNC_POS_POL, \
782 348500000, 192, 280, 472, 3, 6, 49, 0, 0, 0, \
783 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
784}
785
786#define V4L2_DV_BT_DMT_2560X1600P75 { \
787 .type = V4L2_DV_BT_656_1120, \
788 V4L2_INIT_BT_TIMINGS(2560, 1600, 0, V4L2_DV_VSYNC_POS_POL, \
789 443250000, 208, 280, 488, 3, 6, 63, 0, 0, 0, \
790 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
791}
792
793#define V4L2_DV_BT_DMT_2560X1600P85 { \
794 .type = V4L2_DV_BT_656_1120, \
795 V4L2_INIT_BT_TIMINGS(2560, 1600, 0, V4L2_DV_VSYNC_POS_POL, \
796 505250000, 208, 280, 488, 3, 6, 73, 0, 0, 0, \
797 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, 0) \
798}
799
800#define V4L2_DV_BT_DMT_2560X1600P120_RB { \
801 .type = V4L2_DV_BT_656_1120, \
802 V4L2_INIT_BT_TIMINGS(2560, 1600, 0, V4L2_DV_HSYNC_POS_POL, \
803 552750000, 48, 32, 80, 3, 6, 85, 0, 0, 0, \
804 V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_CVT, \
805 V4L2_DV_FL_REDUCED_BLANKING) \
806}
807
808#define V4L2_DV_BT_DMT_1366X768P60 { \
809 .type = V4L2_DV_BT_656_1120, \
810 V4L2_INIT_BT_TIMINGS(1366, 768, 0, \
811 V4L2_DV_HSYNC_POS_POL | V4L2_DV_VSYNC_POS_POL, \
812 85500000, 70, 143, 213, 3, 3, 24, 0, 0, 0, \
813 V4L2_DV_BT_STD_DMT, 0) \
814}
815
816#endif
diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
index ed29cbbebfef..812019ee1e06 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/linux/v4l2-subdev.h
@@ -123,6 +123,43 @@ struct v4l2_subdev_frame_interval_enum {
123 __u32 reserved[9]; 123 __u32 reserved[9];
124}; 124};
125 125
126#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE (1 << 0)
127#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE (1 << 1)
128#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG (1 << 2)
129
130/* active cropping area */
131#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL 0x0000
132/* cropping bounds */
133#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS 0x0002
134/* current composing area */
135#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL 0x0100
136/* composing bounds */
137#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS 0x0102
138
139
140/**
141 * struct v4l2_subdev_selection - selection info
142 *
143 * @which: either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY
144 * @pad: pad number, as reported by the media API
145 * @target: selection target, used to choose one of possible rectangles
146 * @flags: constraint flags
147 * @r: coordinates of the selection window
148 * @reserved: for future use, set to zero for now
149 *
150 * Hardware may use multiple helper windows to process a video stream.
151 * The structure is used to exchange this selection areas between
152 * an application and a driver.
153 */
154struct v4l2_subdev_selection {
155 __u32 which;
156 __u32 pad;
157 __u32 target;
158 __u32 flags;
159 struct v4l2_rect r;
160 __u32 reserved[8];
161};
162
126#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) 163#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
127#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) 164#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
128#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \ 165#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
@@ -137,5 +174,9 @@ struct v4l2_subdev_frame_interval_enum {
137 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) 174 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
138#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) 175#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop)
139#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) 176#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
177#define VIDIOC_SUBDEV_G_SELECTION \
178 _IOWR('V', 61, struct v4l2_subdev_selection)
179#define VIDIOC_SUBDEV_S_SELECTION \
180 _IOWR('V', 62, struct v4l2_subdev_selection)
140 181
141#endif 182#endif
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index c9c9a4680cc5..370d11106c11 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -292,10 +292,10 @@ struct v4l2_pix_format {
292 __u32 width; 292 __u32 width;
293 __u32 height; 293 __u32 height;
294 __u32 pixelformat; 294 __u32 pixelformat;
295 enum v4l2_field field; 295 __u32 field; /* enum v4l2_field */
296 __u32 bytesperline; /* for padding, zero if unused */ 296 __u32 bytesperline; /* for padding, zero if unused */
297 __u32 sizeimage; 297 __u32 sizeimage;
298 enum v4l2_colorspace colorspace; 298 __u32 colorspace; /* enum v4l2_colorspace */
299 __u32 priv; /* private data, depends on pixelformat */ 299 __u32 priv; /* private data, depends on pixelformat */
300}; 300};
301 301
@@ -378,7 +378,10 @@ struct v4l2_pix_format {
378#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ 378#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */
379#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ 379#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
380 /* 10bit raw bayer DPCM compressed to 8 bits */ 380 /* 10bit raw bayer DPCM compressed to 8 bits */
381#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
382#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
381#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') 383#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
384#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
382 /* 385 /*
383 * 10bit raw bayer, expanded to 16 bits 386 * 10bit raw bayer, expanded to 16 bits
384 * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... 387 * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
@@ -432,7 +435,7 @@ struct v4l2_pix_format {
432 */ 435 */
433struct v4l2_fmtdesc { 436struct v4l2_fmtdesc {
434 __u32 index; /* Format number */ 437 __u32 index; /* Format number */
435 enum v4l2_buf_type type; /* buffer type */ 438 __u32 type; /* enum v4l2_buf_type */
436 __u32 flags; 439 __u32 flags;
437 __u8 description[32]; /* Description string */ 440 __u8 description[32]; /* Description string */
438 __u32 pixelformat; /* Format fourcc */ 441 __u32 pixelformat; /* Format fourcc */
@@ -573,8 +576,8 @@ struct v4l2_jpegcompression {
573 */ 576 */
574struct v4l2_requestbuffers { 577struct v4l2_requestbuffers {
575 __u32 count; 578 __u32 count;
576 enum v4l2_buf_type type; 579 __u32 type; /* enum v4l2_buf_type */
577 enum v4l2_memory memory; 580 __u32 memory; /* enum v4l2_memory */
578 __u32 reserved[2]; 581 __u32 reserved[2];
579}; 582};
580 583
@@ -610,15 +613,17 @@ struct v4l2_plane {
610/** 613/**
611 * struct v4l2_buffer - video buffer info 614 * struct v4l2_buffer - video buffer info
612 * @index: id number of the buffer 615 * @index: id number of the buffer
613 * @type: buffer type (type == *_MPLANE for multiplanar buffers) 616 * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for
617 * multiplanar buffers);
614 * @bytesused: number of bytes occupied by data in the buffer (payload); 618 * @bytesused: number of bytes occupied by data in the buffer (payload);
615 * unused (set to 0) for multiplanar buffers 619 * unused (set to 0) for multiplanar buffers
616 * @flags: buffer informational flags 620 * @flags: buffer informational flags
617 * @field: field order of the image in the buffer 621 * @field: enum v4l2_field; field order of the image in the buffer
618 * @timestamp: frame timestamp 622 * @timestamp: frame timestamp
619 * @timecode: frame timecode 623 * @timecode: frame timecode
620 * @sequence: sequence count of this frame 624 * @sequence: sequence count of this frame
621 * @memory: the method, in which the actual video data is passed 625 * @memory: enum v4l2_memory; the method, in which the actual video data is
626 * passed
622 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; 627 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
623 * offset from the start of the device memory for this plane, 628 * offset from the start of the device memory for this plane,
624 * (or a "cookie" that should be passed to mmap() as offset) 629 * (or a "cookie" that should be passed to mmap() as offset)
@@ -636,16 +641,16 @@ struct v4l2_plane {
636 */ 641 */
637struct v4l2_buffer { 642struct v4l2_buffer {
638 __u32 index; 643 __u32 index;
639 enum v4l2_buf_type type; 644 __u32 type;
640 __u32 bytesused; 645 __u32 bytesused;
641 __u32 flags; 646 __u32 flags;
642 enum v4l2_field field; 647 __u32 field;
643 struct timeval timestamp; 648 struct timeval timestamp;
644 struct v4l2_timecode timecode; 649 struct v4l2_timecode timecode;
645 __u32 sequence; 650 __u32 sequence;
646 651
647 /* memory location */ 652 /* memory location */
648 enum v4l2_memory memory; 653 __u32 memory;
649 union { 654 union {
650 __u32 offset; 655 __u32 offset;
651 unsigned long userptr; 656 unsigned long userptr;
@@ -708,7 +713,7 @@ struct v4l2_clip {
708 713
709struct v4l2_window { 714struct v4l2_window {
710 struct v4l2_rect w; 715 struct v4l2_rect w;
711 enum v4l2_field field; 716 __u32 field; /* enum v4l2_field */
712 __u32 chromakey; 717 __u32 chromakey;
713 struct v4l2_clip __user *clips; 718 struct v4l2_clip __user *clips;
714 __u32 clipcount; 719 __u32 clipcount;
@@ -745,14 +750,14 @@ struct v4l2_outputparm {
745 * I N P U T I M A G E C R O P P I N G 750 * I N P U T I M A G E C R O P P I N G
746 */ 751 */
747struct v4l2_cropcap { 752struct v4l2_cropcap {
748 enum v4l2_buf_type type; 753 __u32 type; /* enum v4l2_buf_type */
749 struct v4l2_rect bounds; 754 struct v4l2_rect bounds;
750 struct v4l2_rect defrect; 755 struct v4l2_rect defrect;
751 struct v4l2_fract pixelaspect; 756 struct v4l2_fract pixelaspect;
752}; 757};
753 758
754struct v4l2_crop { 759struct v4l2_crop {
755 enum v4l2_buf_type type; 760 __u32 type; /* enum v4l2_buf_type */
756 struct v4l2_rect c; 761 struct v4l2_rect c;
757}; 762};
758 763
@@ -939,6 +944,9 @@ struct v4l2_standard {
939 __u32 reserved[4]; 944 __u32 reserved[4];
940}; 945};
941 946
947/* The DV Preset API is deprecated in favor of the DV Timings API.
948 New drivers shouldn't use this anymore! */
949
942/* 950/*
943 * V I D E O T I M I N G S D V P R E S E T 951 * V I D E O T I M I N G S D V P R E S E T
944 */ 952 */
@@ -986,29 +994,56 @@ struct v4l2_dv_enum_preset {
986 * D V B T T I M I N G S 994 * D V B T T I M I N G S
987 */ 995 */
988 996
989/* BT.656/BT.1120 timing data */ 997/** struct v4l2_bt_timings - BT.656/BT.1120 timing data
998 * @width: total width of the active video in pixels
999 * @height: total height of the active video in lines
1000 * @interlaced: Interlaced or progressive
1001 * @polarities: Positive or negative polarities
1002 * @pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
1003 * @hfrontporch:Horizontal front porch in pixels
1004 * @hsync: Horizontal Sync length in pixels
1005 * @hbackporch: Horizontal back porch in pixels
1006 * @vfrontporch:Vertical front porch in lines
1007 * @vsync: Vertical Sync length in lines
1008 * @vbackporch: Vertical back porch in lines
1009 * @il_vfrontporch:Vertical front porch for the even field
1010 * (aka field 2) of interlaced field formats
1011 * @il_vsync: Vertical Sync length for the even field
1012 * (aka field 2) of interlaced field formats
1013 * @il_vbackporch:Vertical back porch for the even field
1014 * (aka field 2) of interlaced field formats
1015 * @standards: Standards the timing belongs to
1016 * @flags: Flags
1017 * @reserved: Reserved fields, must be zeroed.
1018 *
1019 * A note regarding vertical interlaced timings: height refers to the total
1020 * height of the active video frame (= two fields). The blanking timings refer
1021 * to the blanking of each field. So the height of the total frame is
1022 * calculated as follows:
1023 *
1024 * tot_height = height + vfrontporch + vsync + vbackporch +
1025 * il_vfrontporch + il_vsync + il_vbackporch
1026 *
1027 * The active height of each field is height / 2.
1028 */
990struct v4l2_bt_timings { 1029struct v4l2_bt_timings {
991 __u32 width; /* width in pixels */ 1030 __u32 width;
992 __u32 height; /* height in lines */ 1031 __u32 height;
993 __u32 interlaced; /* Interlaced or progressive */ 1032 __u32 interlaced;
994 __u32 polarities; /* Positive or negative polarity */ 1033 __u32 polarities;
995 __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ 1034 __u64 pixelclock;
996 __u32 hfrontporch; /* Horizpontal front porch in pixels */ 1035 __u32 hfrontporch;
997 __u32 hsync; /* Horizontal Sync length in pixels */ 1036 __u32 hsync;
998 __u32 hbackporch; /* Horizontal back porch in pixels */ 1037 __u32 hbackporch;
999 __u32 vfrontporch; /* Vertical front porch in pixels */ 1038 __u32 vfrontporch;
1000 __u32 vsync; /* Vertical Sync length in lines */ 1039 __u32 vsync;
1001 __u32 vbackporch; /* Vertical back porch in lines */ 1040 __u32 vbackporch;
1002 __u32 il_vfrontporch; /* Vertical front porch for bottom field of 1041 __u32 il_vfrontporch;
1003 * interlaced field formats 1042 __u32 il_vsync;
1004 */ 1043 __u32 il_vbackporch;
1005 __u32 il_vsync; /* Vertical sync length for bottom field of 1044 __u32 standards;
1006 * interlaced field formats 1045 __u32 flags;
1007 */ 1046 __u32 reserved[14];
1008 __u32 il_vbackporch; /* Vertical back porch for bottom field of
1009 * interlaced field formats
1010 */
1011 __u32 reserved[16];
1012} __attribute__ ((packed)); 1047} __attribute__ ((packed));
1013 1048
1014/* Interlaced or progressive format */ 1049/* Interlaced or progressive format */
@@ -1019,8 +1054,42 @@ struct v4l2_bt_timings {
1019#define V4L2_DV_VSYNC_POS_POL 0x00000001 1054#define V4L2_DV_VSYNC_POS_POL 0x00000001
1020#define V4L2_DV_HSYNC_POS_POL 0x00000002 1055#define V4L2_DV_HSYNC_POS_POL 0x00000002
1021 1056
1022 1057/* Timings standards */
1023/* DV timings */ 1058#define V4L2_DV_BT_STD_CEA861 (1 << 0) /* CEA-861 Digital TV Profile */
1059#define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */
1060#define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */
1061#define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */
1062
1063/* Flags */
1064
1065/* CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary
1066 GTF' curve (GTF). In both cases the horizontal and/or vertical blanking
1067 intervals are reduced, allowing a higher resolution over the same
1068 bandwidth. This is a read-only flag. */
1069#define V4L2_DV_FL_REDUCED_BLANKING (1 << 0)
1070/* CEA-861 specific: set for CEA-861 formats with a framerate of a multiple
1071 of six. These formats can be optionally played at 1 / 1.001 speed.
1072 This is a read-only flag. */
1073#define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1)
1074/* CEA-861 specific: only valid for video transmitters, the flag is cleared
1075 by receivers.
1076 If the framerate of the format is a multiple of six, then the pixelclock
1077 used to set up the transmitter is divided by 1.001 to make it compatible
1078 with 60 Hz based standards such as NTSC and PAL-M that use a framerate of
1079 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate
1080 such frequencies, then the flag will also be cleared. */
1081#define V4L2_DV_FL_REDUCED_FPS (1 << 2)
1082/* Specific to interlaced formats: if set, then field 1 is really one half-line
1083 longer and field 2 is really one half-line shorter, so each field has
1084 exactly the same number of half-lines. Whether half-lines can be detected
1085 or used depends on the hardware. */
1086#define V4L2_DV_FL_HALF_LINE (1 << 0)
1087
1088
1089/** struct v4l2_dv_timings - DV timings
1090 * @type: the type of the timings
1091 * @bt: BT656/1120 timings
1092 */
1024struct v4l2_dv_timings { 1093struct v4l2_dv_timings {
1025 __u32 type; 1094 __u32 type;
1026 union { 1095 union {
@@ -1032,6 +1101,64 @@ struct v4l2_dv_timings {
1032/* Values for the type field */ 1101/* Values for the type field */
1033#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ 1102#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */
1034 1103
1104
1105/** struct v4l2_enum_dv_timings - DV timings enumeration
1106 * @index: enumeration index
1107 * @reserved: must be zeroed
1108 * @timings: the timings for the given index
1109 */
1110struct v4l2_enum_dv_timings {
1111 __u32 index;
1112 __u32 reserved[3];
1113 struct v4l2_dv_timings timings;
1114};
1115
1116/** struct v4l2_bt_timings_cap - BT.656/BT.1120 timing capabilities
1117 * @min_width: width in pixels
1118 * @max_width: width in pixels
1119 * @min_height: height in lines
1120 * @max_height: height in lines
1121 * @min_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
1122 * @max_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
1123 * @standards: Supported standards
1124 * @capabilities: Supported capabilities
1125 * @reserved: Must be zeroed
1126 */
1127struct v4l2_bt_timings_cap {
1128 __u32 min_width;
1129 __u32 max_width;
1130 __u32 min_height;
1131 __u32 max_height;
1132 __u64 min_pixelclock;
1133 __u64 max_pixelclock;
1134 __u32 standards;
1135 __u32 capabilities;
1136 __u32 reserved[16];
1137} __attribute__ ((packed));
1138
1139/* Supports interlaced formats */
1140#define V4L2_DV_BT_CAP_INTERLACED (1 << 0)
1141/* Supports progressive formats */
1142#define V4L2_DV_BT_CAP_PROGRESSIVE (1 << 1)
1143/* Supports CVT/GTF reduced blanking */
1144#define V4L2_DV_BT_CAP_REDUCED_BLANKING (1 << 2)
1145/* Supports custom formats */
1146#define V4L2_DV_BT_CAP_CUSTOM (1 << 3)
1147
1148/** struct v4l2_dv_timings_cap - DV timings capabilities
1149 * @type: the type of the timings (same as in struct v4l2_dv_timings)
1150 * @bt: the BT656/1120 timings capabilities
1151 */
1152struct v4l2_dv_timings_cap {
1153 __u32 type;
1154 __u32 reserved[3];
1155 union {
1156 struct v4l2_bt_timings_cap bt;
1157 __u32 raw_data[32];
1158 };
1159};
1160
1161
1035/* 1162/*
1036 * V I D E O I N P U T S 1163 * V I D E O I N P U T S
1037 */ 1164 */
@@ -1040,7 +1167,7 @@ struct v4l2_input {
1040 __u8 name[32]; /* Label */ 1167 __u8 name[32]; /* Label */
1041 __u32 type; /* Type of input */ 1168 __u32 type; /* Type of input */
1042 __u32 audioset; /* Associated audios (bitfield) */ 1169 __u32 audioset; /* Associated audios (bitfield) */
1043 __u32 tuner; /* Associated tuner */ 1170 __u32 tuner; /* enum v4l2_tuner_type */
1044 v4l2_std_id std; 1171 v4l2_std_id std;
1045 __u32 status; 1172 __u32 status;
1046 __u32 capabilities; 1173 __u32 capabilities;
@@ -1137,6 +1264,8 @@ struct v4l2_ext_controls {
1137#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ 1264#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
1138#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ 1265#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */
1139#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ 1266#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */
1267#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */
1268#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */
1140 1269
1141#define V4L2_CTRL_ID_MASK (0x0fffffff) 1270#define V4L2_CTRL_ID_MASK (0x0fffffff)
1142#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) 1271#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
@@ -1151,12 +1280,13 @@ enum v4l2_ctrl_type {
1151 V4L2_CTRL_TYPE_CTRL_CLASS = 6, 1280 V4L2_CTRL_TYPE_CTRL_CLASS = 6,
1152 V4L2_CTRL_TYPE_STRING = 7, 1281 V4L2_CTRL_TYPE_STRING = 7,
1153 V4L2_CTRL_TYPE_BITMASK = 8, 1282 V4L2_CTRL_TYPE_BITMASK = 8,
1283 V4L2_CTRL_TYPE_INTEGER_MENU = 9,
1154}; 1284};
1155 1285
1156/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ 1286/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
1157struct v4l2_queryctrl { 1287struct v4l2_queryctrl {
1158 __u32 id; 1288 __u32 id;
1159 enum v4l2_ctrl_type type; 1289 __u32 type; /* enum v4l2_ctrl_type */
1160 __u8 name[32]; /* Whatever */ 1290 __u8 name[32]; /* Whatever */
1161 __s32 minimum; /* Note signedness */ 1291 __s32 minimum; /* Note signedness */
1162 __s32 maximum; 1292 __s32 maximum;
@@ -1170,9 +1300,12 @@ struct v4l2_queryctrl {
1170struct v4l2_querymenu { 1300struct v4l2_querymenu {
1171 __u32 id; 1301 __u32 id;
1172 __u32 index; 1302 __u32 index;
1173 __u8 name[32]; /* Whatever */ 1303 union {
1304 __u8 name[32]; /* Whatever */
1305 __s64 value;
1306 };
1174 __u32 reserved; 1307 __u32 reserved;
1175}; 1308} __attribute__ ((packed));
1176 1309
1177/* Control flags */ 1310/* Control flags */
1178#define V4L2_CTRL_FLAG_DISABLED 0x0001 1311#define V4L2_CTRL_FLAG_DISABLED 0x0001
@@ -1237,16 +1370,22 @@ enum v4l2_power_line_frequency {
1237#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) 1370#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
1238#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) 1371#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
1239enum v4l2_colorfx { 1372enum v4l2_colorfx {
1240 V4L2_COLORFX_NONE = 0, 1373 V4L2_COLORFX_NONE = 0,
1241 V4L2_COLORFX_BW = 1, 1374 V4L2_COLORFX_BW = 1,
1242 V4L2_COLORFX_SEPIA = 2, 1375 V4L2_COLORFX_SEPIA = 2,
1243 V4L2_COLORFX_NEGATIVE = 3, 1376 V4L2_COLORFX_NEGATIVE = 3,
1244 V4L2_COLORFX_EMBOSS = 4, 1377 V4L2_COLORFX_EMBOSS = 4,
1245 V4L2_COLORFX_SKETCH = 5, 1378 V4L2_COLORFX_SKETCH = 5,
1246 V4L2_COLORFX_SKY_BLUE = 6, 1379 V4L2_COLORFX_SKY_BLUE = 6,
1247 V4L2_COLORFX_GRASS_GREEN = 7, 1380 V4L2_COLORFX_GRASS_GREEN = 7,
1248 V4L2_COLORFX_SKIN_WHITEN = 8, 1381 V4L2_COLORFX_SKIN_WHITEN = 8,
1249 V4L2_COLORFX_VIVID = 9, 1382 V4L2_COLORFX_VIVID = 9,
1383 V4L2_COLORFX_AQUA = 10,
1384 V4L2_COLORFX_ART_FREEZE = 11,
1385 V4L2_COLORFX_SILHOUETTE = 12,
1386 V4L2_COLORFX_SOLARIZATION = 13,
1387 V4L2_COLORFX_ANTIQUE = 14,
1388 V4L2_COLORFX_SET_CBCR = 15,
1250}; 1389};
1251#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) 1390#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
1252#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) 1391#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
@@ -1263,9 +1402,10 @@ enum v4l2_colorfx {
1263#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) 1402#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40)
1264 1403
1265#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) 1404#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41)
1405#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
1266 1406
1267/* last CID + 1 */ 1407/* last CID + 1 */
1268#define V4L2_CID_LASTP1 (V4L2_CID_BASE+42) 1408#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43)
1269 1409
1270/* MPEG-class control IDs defined by V4L2 */ 1410/* MPEG-class control IDs defined by V4L2 */
1271#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) 1411#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
@@ -1689,6 +1829,78 @@ enum v4l2_exposure_auto_type {
1689#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) 1829#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17)
1690#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) 1830#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18)
1691 1831
1832#define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19)
1833
1834#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20)
1835enum v4l2_auto_n_preset_white_balance {
1836 V4L2_WHITE_BALANCE_MANUAL = 0,
1837 V4L2_WHITE_BALANCE_AUTO = 1,
1838 V4L2_WHITE_BALANCE_INCANDESCENT = 2,
1839 V4L2_WHITE_BALANCE_FLUORESCENT = 3,
1840 V4L2_WHITE_BALANCE_FLUORESCENT_H = 4,
1841 V4L2_WHITE_BALANCE_HORIZON = 5,
1842 V4L2_WHITE_BALANCE_DAYLIGHT = 6,
1843 V4L2_WHITE_BALANCE_FLASH = 7,
1844 V4L2_WHITE_BALANCE_CLOUDY = 8,
1845 V4L2_WHITE_BALANCE_SHADE = 9,
1846};
1847
1848#define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21)
1849#define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22)
1850
1851#define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23)
1852#define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24)
1853enum v4l2_iso_sensitivity_auto_type {
1854 V4L2_ISO_SENSITIVITY_MANUAL = 0,
1855 V4L2_ISO_SENSITIVITY_AUTO = 1,
1856};
1857
1858#define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25)
1859enum v4l2_exposure_metering {
1860 V4L2_EXPOSURE_METERING_AVERAGE = 0,
1861 V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1,
1862 V4L2_EXPOSURE_METERING_SPOT = 2,
1863};
1864
1865#define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26)
1866enum v4l2_scene_mode {
1867 V4L2_SCENE_MODE_NONE = 0,
1868 V4L2_SCENE_MODE_BACKLIGHT = 1,
1869 V4L2_SCENE_MODE_BEACH_SNOW = 2,
1870 V4L2_SCENE_MODE_CANDLE_LIGHT = 3,
1871 V4L2_SCENE_MODE_DAWN_DUSK = 4,
1872 V4L2_SCENE_MODE_FALL_COLORS = 5,
1873 V4L2_SCENE_MODE_FIREWORKS = 6,
1874 V4L2_SCENE_MODE_LANDSCAPE = 7,
1875 V4L2_SCENE_MODE_NIGHT = 8,
1876 V4L2_SCENE_MODE_PARTY_INDOOR = 9,
1877 V4L2_SCENE_MODE_PORTRAIT = 10,
1878 V4L2_SCENE_MODE_SPORTS = 11,
1879 V4L2_SCENE_MODE_SUNSET = 12,
1880 V4L2_SCENE_MODE_TEXT = 13,
1881};
1882
1883#define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27)
1884#define V4L2_LOCK_EXPOSURE (1 << 0)
1885#define V4L2_LOCK_WHITE_BALANCE (1 << 1)
1886#define V4L2_LOCK_FOCUS (1 << 2)
1887
1888#define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28)
1889#define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29)
1890#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30)
1891#define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0)
1892#define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0)
1893#define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1)
1894#define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2)
1895
1896#define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31)
1897enum v4l2_auto_focus_range {
1898 V4L2_AUTO_FOCUS_RANGE_AUTO = 0,
1899 V4L2_AUTO_FOCUS_RANGE_NORMAL = 1,
1900 V4L2_AUTO_FOCUS_RANGE_MACRO = 2,
1901 V4L2_AUTO_FOCUS_RANGE_INFINITY = 3,
1902};
1903
1692/* FM Modulator class control IDs */ 1904/* FM Modulator class control IDs */
1693#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) 1905#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
1694#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) 1906#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
@@ -1782,13 +1994,28 @@ enum v4l2_jpeg_chroma_subsampling {
1782#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) 1994#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17)
1783#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) 1995#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18)
1784 1996
1997/* Image source controls */
1998#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
1999#define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1)
2000
2001#define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1)
2002#define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
2003#define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
2004
2005/* Image processing controls */
2006#define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900)
2007#define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1)
2008
2009#define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1)
2010#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
2011
1785/* 2012/*
1786 * T U N I N G 2013 * T U N I N G
1787 */ 2014 */
1788struct v4l2_tuner { 2015struct v4l2_tuner {
1789 __u32 index; 2016 __u32 index;
1790 __u8 name[32]; 2017 __u8 name[32];
1791 enum v4l2_tuner_type type; 2018 __u32 type; /* enum v4l2_tuner_type */
1792 __u32 capability; 2019 __u32 capability;
1793 __u32 rangelow; 2020 __u32 rangelow;
1794 __u32 rangehigh; 2021 __u32 rangehigh;
@@ -1838,14 +2065,14 @@ struct v4l2_modulator {
1838 2065
1839struct v4l2_frequency { 2066struct v4l2_frequency {
1840 __u32 tuner; 2067 __u32 tuner;
1841 enum v4l2_tuner_type type; 2068 __u32 type; /* enum v4l2_tuner_type */
1842 __u32 frequency; 2069 __u32 frequency;
1843 __u32 reserved[8]; 2070 __u32 reserved[8];
1844}; 2071};
1845 2072
1846struct v4l2_hw_freq_seek { 2073struct v4l2_hw_freq_seek {
1847 __u32 tuner; 2074 __u32 tuner;
1848 enum v4l2_tuner_type type; 2075 __u32 type; /* enum v4l2_tuner_type */
1849 __u32 seek_upward; 2076 __u32 seek_upward;
1850 __u32 wrap_around; 2077 __u32 wrap_around;
1851 __u32 spacing; 2078 __u32 spacing;
@@ -2056,7 +2283,7 @@ struct v4l2_sliced_vbi_cap {
2056 (equals frame lines 313-336 for 625 line video 2283 (equals frame lines 313-336 for 625 line video
2057 standards, 263-286 for 525 line standards) */ 2284 standards, 263-286 for 525 line standards) */
2058 __u16 service_lines[2][24]; 2285 __u16 service_lines[2][24];
2059 enum v4l2_buf_type type; 2286 __u32 type; /* enum v4l2_buf_type */
2060 __u32 reserved[3]; /* must be 0 */ 2287 __u32 reserved[3]; /* must be 0 */
2061}; 2288};
2062 2289
@@ -2137,8 +2364,8 @@ struct v4l2_plane_pix_format {
2137 * @width: image width in pixels 2364 * @width: image width in pixels
2138 * @height: image height in pixels 2365 * @height: image height in pixels
2139 * @pixelformat: little endian four character code (fourcc) 2366 * @pixelformat: little endian four character code (fourcc)
2140 * @field: field order (for interlaced video) 2367 * @field: enum v4l2_field; field order (for interlaced video)
2141 * @colorspace: supplemental to pixelformat 2368 * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
2142 * @plane_fmt: per-plane information 2369 * @plane_fmt: per-plane information
2143 * @num_planes: number of planes for this format 2370 * @num_planes: number of planes for this format
2144 */ 2371 */
@@ -2146,8 +2373,8 @@ struct v4l2_pix_format_mplane {
2146 __u32 width; 2373 __u32 width;
2147 __u32 height; 2374 __u32 height;
2148 __u32 pixelformat; 2375 __u32 pixelformat;
2149 enum v4l2_field field; 2376 __u32 field;
2150 enum v4l2_colorspace colorspace; 2377 __u32 colorspace;
2151 2378
2152 struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; 2379 struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES];
2153 __u8 num_planes; 2380 __u8 num_planes;
@@ -2156,7 +2383,7 @@ struct v4l2_pix_format_mplane {
2156 2383
2157/** 2384/**
2158 * struct v4l2_format - stream data format 2385 * struct v4l2_format - stream data format
2159 * @type: type of the data stream 2386 * @type: enum v4l2_buf_type; type of the data stream
2160 * @pix: definition of an image format 2387 * @pix: definition of an image format
2161 * @pix_mp: definition of a multiplanar image format 2388 * @pix_mp: definition of a multiplanar image format
2162 * @win: definition of an overlaid image 2389 * @win: definition of an overlaid image
@@ -2165,7 +2392,7 @@ struct v4l2_pix_format_mplane {
2165 * @raw_data: placeholder for future extensions and custom formats 2392 * @raw_data: placeholder for future extensions and custom formats
2166 */ 2393 */
2167struct v4l2_format { 2394struct v4l2_format {
2168 enum v4l2_buf_type type; 2395 __u32 type;
2169 union { 2396 union {
2170 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ 2397 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
2171 struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ 2398 struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
@@ -2179,7 +2406,7 @@ struct v4l2_format {
2179/* Stream type-dependent parameters 2406/* Stream type-dependent parameters
2180 */ 2407 */
2181struct v4l2_streamparm { 2408struct v4l2_streamparm {
2182 enum v4l2_buf_type type; 2409 __u32 type; /* enum v4l2_buf_type */
2183 union { 2410 union {
2184 struct v4l2_captureparm capture; 2411 struct v4l2_captureparm capture;
2185 struct v4l2_outputparm output; 2412 struct v4l2_outputparm output;
@@ -2292,14 +2519,14 @@ struct v4l2_dbg_chip_ident {
2292 * @index: on return, index of the first created buffer 2519 * @index: on return, index of the first created buffer
2293 * @count: entry: number of requested buffers, 2520 * @count: entry: number of requested buffers,
2294 * return: number of created buffers 2521 * return: number of created buffers
2295 * @memory: buffer memory type 2522 * @memory: enum v4l2_memory; buffer memory type
2296 * @format: frame format, for which buffers are requested 2523 * @format: frame format, for which buffers are requested
2297 * @reserved: future extensions 2524 * @reserved: future extensions
2298 */ 2525 */
2299struct v4l2_create_buffers { 2526struct v4l2_create_buffers {
2300 __u32 index; 2527 __u32 index;
2301 __u32 count; 2528 __u32 count;
2302 enum v4l2_memory memory; 2529 __u32 memory;
2303 struct v4l2_format format; 2530 struct v4l2_format format;
2304 __u32 reserved[8]; 2531 __u32 reserved[8];
2305}; 2532};
@@ -2356,8 +2583,8 @@ struct v4l2_create_buffers {
2356#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) 2583#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format)
2357#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) 2584#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio)
2358#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) 2585#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout)
2359#define VIDIOC_G_PRIORITY _IOR('V', 67, enum v4l2_priority) 2586#define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */
2360#define VIDIOC_S_PRIORITY _IOW('V', 68, enum v4l2_priority) 2587#define VIDIOC_S_PRIORITY _IOW('V', 68, __u32) /* enum v4l2_priority */
2361#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) 2588#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap)
2362#define VIDIOC_LOG_STATUS _IO('V', 70) 2589#define VIDIOC_LOG_STATUS _IO('V', 70)
2363#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) 2590#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls)
@@ -2384,6 +2611,9 @@ struct v4l2_create_buffers {
2384#endif 2611#endif
2385 2612
2386#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) 2613#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
2614
2615/* These four DV Preset ioctls are deprecated in favor of the DV Timings
2616 ioctls. */
2387#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) 2617#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset)
2388#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) 2618#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset)
2389#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) 2619#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset)
@@ -2408,6 +2638,12 @@ struct v4l2_create_buffers {
2408#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) 2638#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd)
2409#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) 2639#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd)
2410 2640
2641/* Experimental, these three ioctls may change over the next couple of kernel
2642 versions. */
2643#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 96, struct v4l2_enum_dv_timings)
2644#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 97, struct v4l2_dv_timings)
2645#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 98, struct v4l2_dv_timings_cap)
2646
2411/* Reminder: when adding new ioctls please add support for them to 2647/* Reminder: when adding new ioctls please add support for them to
2412 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 2648 drivers/media/video/v4l2-compat-ioctl32.c as well! */
2413 2649
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 29e7bba78ffe..0c16f518ee09 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -46,6 +46,7 @@ struct media_entity_operations {
46 int (*link_setup)(struct media_entity *entity, 46 int (*link_setup)(struct media_entity *entity,
47 const struct media_pad *local, 47 const struct media_pad *local,
48 const struct media_pad *remote, u32 flags); 48 const struct media_pad *remote, u32 flags);
49 int (*link_validate)(struct media_link *link);
49}; 50};
50 51
51struct media_entity { 52struct media_entity {
@@ -140,8 +141,8 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph,
140 struct media_entity *entity); 141 struct media_entity *entity);
141struct media_entity * 142struct media_entity *
142media_entity_graph_walk_next(struct media_entity_graph *graph); 143media_entity_graph_walk_next(struct media_entity_graph *graph);
143void media_entity_pipeline_start(struct media_entity *entity, 144__must_check int media_entity_pipeline_start(struct media_entity *entity,
144 struct media_pipeline *pipe); 145 struct media_pipeline *pipe);
145void media_entity_pipeline_stop(struct media_entity *entity); 146void media_entity_pipeline_stop(struct media_entity *entity);
146 147
147#define media_entity_call(entity, operation, args...) \ 148#define media_entity_call(entity, operation, args...) \
diff --git a/include/media/mt9p031.h b/include/media/mt9p031.h
index 96448c7a318b..0c97b19af293 100644
--- a/include/media/mt9p031.h
+++ b/include/media/mt9p031.h
@@ -3,17 +3,18 @@
3 3
4struct v4l2_subdev; 4struct v4l2_subdev;
5 5
6enum { 6/*
7 MT9P031_COLOR_VERSION, 7 * struct mt9p031_platform_data - MT9P031 platform data
8 MT9P031_MONOCHROME_VERSION, 8 * @set_xclk: Clock frequency set callback
9}; 9 * @reset: Chip reset GPIO (set to -1 if not used)
10 10 * @ext_freq: Input clock frequency
11 * @target_freq: Pixel clock frequency
12 */
11struct mt9p031_platform_data { 13struct mt9p031_platform_data {
12 int (*set_xclk)(struct v4l2_subdev *subdev, int hz); 14 int (*set_xclk)(struct v4l2_subdev *subdev, int hz);
13 int (*reset)(struct v4l2_subdev *subdev, int active); 15 int reset;
14 int ext_freq; /* input frequency to the mt9p031 for PLL dividers */ 16 int ext_freq;
15 int target_freq; /* frequency target for the PLL */ 17 int target_freq;
16 int version; /* MT9P031_COLOR_VERSION or MT9P031_MONOCHROME_VERSION */
17}; 18};
18 19
19#endif 20#endif
diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h
index 042849a34640..4d94be5226af 100644
--- a/include/media/omap3isp.h
+++ b/include/media/omap3isp.h
@@ -29,6 +29,10 @@
29struct i2c_board_info; 29struct i2c_board_info;
30struct isp_device; 30struct isp_device;
31 31
32#define ISP_XCLK_NONE 0
33#define ISP_XCLK_A 1
34#define ISP_XCLK_B 2
35
32enum isp_interface_type { 36enum isp_interface_type {
33 ISP_INTERFACE_PARALLEL, 37 ISP_INTERFACE_PARALLEL,
34 ISP_INTERFACE_CSI2A_PHY2, 38 ISP_INTERFACE_CSI2A_PHY2,
@@ -87,6 +91,29 @@ enum {
87}; 91};
88 92
89/** 93/**
94 * struct isp_csiphy_lane: CCP2/CSI2 lane position and polarity
95 * @pos: position of the lane
96 * @pol: polarity of the lane
97 */
98struct isp_csiphy_lane {
99 u8 pos;
100 u8 pol;
101};
102
103#define ISP_CSIPHY1_NUM_DATA_LANES 1
104#define ISP_CSIPHY2_NUM_DATA_LANES 2
105
106/**
107 * struct isp_csiphy_lanes_cfg - CCP2/CSI2 lane configuration
108 * @data: Configuration of one or two data lanes
109 * @clk: Clock lane configuration
110 */
111struct isp_csiphy_lanes_cfg {
112 struct isp_csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
113 struct isp_csiphy_lane clk;
114};
115
116/**
90 * struct isp_ccp2_platform_data - CCP2 interface platform data 117 * struct isp_ccp2_platform_data - CCP2 interface platform data
91 * @strobe_clk_pol: Strobe/clock polarity 118 * @strobe_clk_pol: Strobe/clock polarity
92 * 0 - Non Inverted, 1 - Inverted 119 * 0 - Non Inverted, 1 - Inverted
@@ -105,6 +132,7 @@ struct isp_ccp2_platform_data {
105 unsigned int ccp2_mode:1; 132 unsigned int ccp2_mode:1;
106 unsigned int phy_layer:1; 133 unsigned int phy_layer:1;
107 unsigned int vpclk_div:2; 134 unsigned int vpclk_div:2;
135 struct isp_csiphy_lanes_cfg lanecfg;
108}; 136};
109 137
110/** 138/**
@@ -115,6 +143,7 @@ struct isp_ccp2_platform_data {
115struct isp_csi2_platform_data { 143struct isp_csi2_platform_data {
116 unsigned crc:1; 144 unsigned crc:1;
117 unsigned vpclk_div:2; 145 unsigned vpclk_div:2;
146 struct isp_csiphy_lanes_cfg lanecfg;
118}; 147};
119 148
120struct isp_subdev_i2c_board_info { 149struct isp_subdev_i2c_board_info {
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 8db6741c1256..cfd5163ff7f3 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -62,6 +62,7 @@ void rc_map_init(void);
62#define RC_MAP_ANYSEE "rc-anysee" 62#define RC_MAP_ANYSEE "rc-anysee"
63#define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp" 63#define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp"
64#define RC_MAP_ASUS_PC39 "rc-asus-pc39" 64#define RC_MAP_ASUS_PC39 "rc-asus-pc39"
65#define RC_MAP_ASUS_PS3_100 "rc-asus-ps3-100"
65#define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600" 66#define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600"
66#define RC_MAP_ATI_X10 "rc-ati-x10" 67#define RC_MAP_ATI_X10 "rc-ati-x10"
67#define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d" 68#define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d"
@@ -113,6 +114,8 @@ void rc_map_init(void);
113#define RC_MAP_LME2510 "rc-lme2510" 114#define RC_MAP_LME2510 "rc-lme2510"
114#define RC_MAP_MANLI "rc-manli" 115#define RC_MAP_MANLI "rc-manli"
115#define RC_MAP_MEDION_X10 "rc-medion-x10" 116#define RC_MAP_MEDION_X10 "rc-medion-x10"
117#define RC_MAP_MEDION_X10_DIGITAINER "rc-medion-x10-digitainer"
118#define RC_MAP_MEDION_X10_OR2X "rc-medion-x10-or2x"
116#define RC_MAP_MSI_DIGIVOX_II "rc-msi-digivox-ii" 119#define RC_MAP_MSI_DIGIVOX_II "rc-msi-digivox-ii"
117#define RC_MAP_MSI_DIGIVOX_III "rc-msi-digivox-iii" 120#define RC_MAP_MSI_DIGIVOX_III "rc-msi-digivox-iii"
118#define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus" 121#define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus"
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
index 688fb3f1dc35..8587aaf73646 100644
--- a/include/media/s5p_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -64,4 +64,20 @@ struct s5p_platform_fimc {
64 */ 64 */
65#define S5P_FIMC_TX_END_NOTIFY _IO('e', 0) 65#define S5P_FIMC_TX_END_NOTIFY _IO('e', 0)
66 66
67enum fimc_subdev_index {
68 IDX_SENSOR,
69 IDX_CSIS,
70 IDX_FLITE,
71 IDX_FIMC,
72 IDX_MAX,
73};
74
75struct media_pipeline;
76struct v4l2_subdev;
77
78struct fimc_pipeline {
79 struct v4l2_subdev *subdevs[IDX_MAX];
80 struct media_pipeline *m_pipeline;
81};
82
67#endif /* S5P_FIMC_H_ */ 83#endif /* S5P_FIMC_H_ */
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 0f037e8edf9a..773e527deabe 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -13,12 +13,11 @@
13#include <linux/mutex.h> 13#include <linux/mutex.h>
14#include <linux/scatterlist.h> 14#include <linux/scatterlist.h>
15#include <media/v4l2-device.h> 15#include <media/v4l2-device.h>
16#include <media/v4l2-ctrls.h>
16 17
17#include <linux/vmalloc.h> /* for vmalloc() */ 18#include <linux/vmalloc.h> /* for vmalloc() */
18#include <linux/mm.h> /* for vmalloc_to_page() */ 19#include <linux/mm.h> /* for vmalloc_to_page() */
19 20
20#define SAA7146_VERSION_CODE 0x000600 /* 0.6.0 */
21
22#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr))) 21#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr)))
23#define saa7146_read(sxy,adr) readl(sxy->mem+(adr)) 22#define saa7146_read(sxy,adr) readl(sxy->mem+(adr))
24 23
@@ -121,6 +120,7 @@ struct saa7146_dev
121 struct list_head item; 120 struct list_head item;
122 121
123 struct v4l2_device v4l2_dev; 122 struct v4l2_device v4l2_dev;
123 struct v4l2_ctrl_handler ctrl_handler;
124 124
125 /* different device locks */ 125 /* different device locks */
126 spinlock_t slock; 126 spinlock_t slock;
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 4aeff96ff7d8..944ecdf3530f 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -3,6 +3,7 @@
3 3
4#include <media/v4l2-common.h> 4#include <media/v4l2-common.h>
5#include <media/v4l2-ioctl.h> 5#include <media/v4l2-ioctl.h>
6#include <media/v4l2-fh.h>
6#include <media/saa7146.h> 7#include <media/saa7146.h>
7#include <media/videobuf-dma-sg.h> 8#include <media/videobuf-dma-sg.h>
8 9
@@ -84,21 +85,15 @@ struct saa7146_overlay {
84 85
85/* per open data */ 86/* per open data */
86struct saa7146_fh { 87struct saa7146_fh {
88 /* Must be the first field! */
89 struct v4l2_fh fh;
87 struct saa7146_dev *dev; 90 struct saa7146_dev *dev;
88 /* if this is a vbi or capture open */
89 enum v4l2_buf_type type;
90
91 /* video overlay */
92 struct saa7146_overlay ov;
93 91
94 /* video capture */ 92 /* video capture */
95 struct videobuf_queue video_q; 93 struct videobuf_queue video_q;
96 struct v4l2_pix_format video_fmt;
97 94
98 /* vbi capture */ 95 /* vbi capture */
99 struct videobuf_queue vbi_q; 96 struct videobuf_queue vbi_q;
100 struct v4l2_vbi_format vbi_fmt;
101 struct timer_list vbi_read_timeout;
102 97
103 unsigned int resources; /* resource management for device open */ 98 unsigned int resources; /* resource management for device open */
104}; 99};
@@ -109,7 +104,9 @@ struct saa7146_fh {
109struct saa7146_vv 104struct saa7146_vv
110{ 105{
111 /* vbi capture */ 106 /* vbi capture */
112 struct saa7146_dmaqueue vbi_q; 107 struct saa7146_dmaqueue vbi_dmaq;
108 struct v4l2_vbi_format vbi_fmt;
109 struct timer_list vbi_read_timeout;
113 /* vbi workaround interrupt queue */ 110 /* vbi workaround interrupt queue */
114 wait_queue_head_t vbi_wq; 111 wait_queue_head_t vbi_wq;
115 int vbi_fieldcount; 112 int vbi_fieldcount;
@@ -119,13 +116,14 @@ struct saa7146_vv
119 struct saa7146_fh *video_fh; 116 struct saa7146_fh *video_fh;
120 117
121 /* video overlay */ 118 /* video overlay */
119 struct saa7146_overlay ov;
122 struct v4l2_framebuffer ov_fb; 120 struct v4l2_framebuffer ov_fb;
123 struct saa7146_format *ov_fmt; 121 struct saa7146_format *ov_fmt;
124 struct saa7146_overlay *ov_data;
125 struct saa7146_fh *ov_suspend; 122 struct saa7146_fh *ov_suspend;
126 123
127 /* video capture */ 124 /* video capture */
128 struct saa7146_dmaqueue video_q; 125 struct saa7146_dmaqueue video_dmaq;
126 struct v4l2_pix_format video_fmt;
129 enum v4l2_field last_field; 127 enum v4l2_field last_field;
130 128
131 /* common: fixme? shouldn't this be in saa7146_fh? 129 /* common: fixme? shouldn't this be in saa7146_fh?
@@ -163,7 +161,8 @@ struct saa7146_ext_vv
163 int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *); 161 int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *);
164 162
165 /* the extension can override this */ 163 /* the extension can override this */
166 struct v4l2_ioctl_ops ops; 164 struct v4l2_ioctl_ops vid_ops;
165 struct v4l2_ioctl_ops vbi_ops;
167 /* pointer to the saa7146 core ops */ 166 /* pointer to the saa7146 core ops */
168 const struct v4l2_ioctl_ops *core_ops; 167 const struct v4l2_ioctl_ops *core_ops;
169 168
@@ -202,10 +201,12 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
202 201
203/* from saa7146_video.c */ 202/* from saa7146_video.c */
204extern const struct v4l2_ioctl_ops saa7146_video_ioctl_ops; 203extern const struct v4l2_ioctl_ops saa7146_video_ioctl_ops;
204extern const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops;
205extern struct saa7146_use_ops saa7146_video_uops; 205extern struct saa7146_use_ops saa7146_video_uops;
206int saa7146_start_preview(struct saa7146_fh *fh); 206int saa7146_start_preview(struct saa7146_fh *fh);
207int saa7146_stop_preview(struct saa7146_fh *fh); 207int saa7146_stop_preview(struct saa7146_fh *fh);
208long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); 208long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
209int saa7146_s_ctrl(struct v4l2_ctrl *ctrl);
209 210
210/* from saa7146_vbi.c */ 211/* from saa7146_vbi.c */
211extern struct saa7146_use_ops saa7146_vbi_uops; 212extern struct saa7146_use_ops saa7146_vbi_uops;
diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h
index a90a765f18da..6fdb6adf6b2b 100644
--- a/include/media/sh_mobile_ceu.h
+++ b/include/media/sh_mobile_ceu.h
@@ -5,6 +5,7 @@
5#define SH_CEU_FLAG_USE_16BIT_BUS (1 << 1) /* use 16bit bus width */ 5#define SH_CEU_FLAG_USE_16BIT_BUS (1 << 1) /* use 16bit bus width */
6#define SH_CEU_FLAG_HSYNC_LOW (1 << 2) /* default High if possible */ 6#define SH_CEU_FLAG_HSYNC_LOW (1 << 2) /* default High if possible */
7#define SH_CEU_FLAG_VSYNC_LOW (1 << 3) /* default High if possible */ 7#define SH_CEU_FLAG_VSYNC_LOW (1 << 3) /* default High if possible */
8#define SH_CEU_FLAG_LOWER_8BIT (1 << 4) /* default upper 8bit */
8 9
9struct device; 10struct device;
10struct resource; 11struct resource;
diff --git a/include/media/smiapp.h b/include/media/smiapp.h
new file mode 100644
index 000000000000..9ab07fd45d5c
--- /dev/null
+++ b/include/media/smiapp.h
@@ -0,0 +1,84 @@
1/*
2 * include/media/smiapp.h
3 *
4 * Generic driver for SMIA/SMIA++ compliant camera modules
5 *
6 * Copyright (C) 2011--2012 Nokia Corporation
7 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.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
25#ifndef __SMIAPP_H_
26#define __SMIAPP_H_
27
28#include <media/v4l2-subdev.h>
29
30#define SMIAPP_NAME "smiapp"
31
32#define SMIAPP_DFL_I2C_ADDR (0x20 >> 1) /* Default I2C Address */
33#define SMIAPP_ALT_I2C_ADDR (0x6e >> 1) /* Alternate I2C Address */
34
35#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK 0
36#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE 1
37#define SMIAPP_CSI_SIGNALLING_MODE_CSI2 2
38
39#define SMIAPP_NO_XSHUTDOWN -1
40
41/*
42 * Sometimes due to board layout considerations the camera module can be
43 * mounted rotated. The typical rotation used is 180 degrees which can be
44 * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
45 * FIXME: rotation also changes the bayer pattern.
46 */
47enum smiapp_module_board_orient {
48 SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
49 SMIAPP_MODULE_BOARD_ORIENT_180,
50};
51
52struct smiapp_flash_strobe_parms {
53 u8 mode;
54 u32 strobe_width_high_us;
55 u16 strobe_delay;
56 u16 stobe_start_point;
57 u8 trigger;
58};
59
60struct smiapp_platform_data {
61 /*
62 * Change the cci address if i2c_addr_alt is set.
63 * Both default and alternate cci addr need to be present
64 */
65 unsigned short i2c_addr_dfl; /* Default i2c addr */
66 unsigned short i2c_addr_alt; /* Alternate i2c addr */
67
68 unsigned int nvm_size; /* bytes */
69 unsigned int ext_clk; /* sensor external clk */
70
71 unsigned int lanes; /* Number of CSI-2 lanes */
72 u8 csi_signalling_mode; /* SMIAPP_CSI_SIGNALLING_MODE_* */
73 const s64 *op_sys_clock;
74
75 enum smiapp_module_board_orient module_board_orient;
76
77 struct smiapp_flash_strobe_parms *strobe_setup;
78
79 int (*set_xclk)(struct v4l2_subdev *sd, int hz);
80 char *ext_clk_name;
81 int xshutdown; /* gpio or SMIAPP_NO_XSHUTDOWN */
82};
83
84#endif /* __SMIAPP_H_ */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index cad374bdcf4b..d865dcf9879f 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -56,11 +56,15 @@ struct soc_camera_device {
56 }; 56 };
57}; 57};
58 58
59/* Host supports programmable stride */
60#define SOCAM_HOST_CAP_STRIDE (1 << 0)
61
59struct soc_camera_host { 62struct soc_camera_host {
60 struct v4l2_device v4l2_dev; 63 struct v4l2_device v4l2_dev;
61 struct list_head list; 64 struct list_head list;
62 struct mutex host_lock; /* Protect during probing */ 65 struct mutex host_lock; /* Protect during probing */
63 unsigned char nr; /* Host number */ 66 unsigned char nr; /* Host number */
67 u32 capabilities;
64 void *priv; 68 void *priv;
65 const char *drv_name; 69 const char *drv_name;
66 struct soc_camera_host_ops *ops; 70 struct soc_camera_host_ops *ops;
@@ -98,7 +102,7 @@ struct soc_camera_host_ops {
98 int (*set_bus_param)(struct soc_camera_device *); 102 int (*set_bus_param)(struct soc_camera_device *);
99 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 103 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
100 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 104 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
101 int (*enum_fsizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *); 105 int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
102 unsigned int (*poll)(struct file *, poll_table *); 106 unsigned int (*poll)(struct file *, poll_table *);
103}; 107};
104 108
diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h
index 73f1e7eb60f3..0dc6f4625b92 100644
--- a/include/media/soc_mediabus.h
+++ b/include/media/soc_mediabus.h
@@ -47,6 +47,24 @@ enum soc_mbus_order {
47}; 47};
48 48
49/** 49/**
50 * enum soc_mbus_layout - planes layout in memory
51 * @SOC_MBUS_LAYOUT_PACKED: color components packed
52 * @SOC_MBUS_LAYOUT_PLANAR_2Y_U_V: YUV components stored in 3 planes (4:2:2)
53 * @SOC_MBUS_LAYOUT_PLANAR_2Y_C: YUV components stored in a luma and a
54 * chroma plane (C plane is half the size
55 * of Y plane)
56 * @SOC_MBUS_LAYOUT_PLANAR_Y_C: YUV components stored in a luma and a
57 * chroma plane (C plane is the same size
58 * as Y plane)
59 */
60enum soc_mbus_layout {
61 SOC_MBUS_LAYOUT_PACKED = 0,
62 SOC_MBUS_LAYOUT_PLANAR_2Y_U_V,
63 SOC_MBUS_LAYOUT_PLANAR_2Y_C,
64 SOC_MBUS_LAYOUT_PLANAR_Y_C,
65};
66
67/**
50 * struct soc_mbus_pixelfmt - Data format on the media bus 68 * struct soc_mbus_pixelfmt - Data format on the media bus
51 * @name: Name of the format 69 * @name: Name of the format
52 * @fourcc: Fourcc code, that will be obtained if the data is 70 * @fourcc: Fourcc code, that will be obtained if the data is
@@ -60,6 +78,7 @@ struct soc_mbus_pixelfmt {
60 u32 fourcc; 78 u32 fourcc;
61 enum soc_mbus_packing packing; 79 enum soc_mbus_packing packing;
62 enum soc_mbus_order order; 80 enum soc_mbus_order order;
81 enum soc_mbus_layout layout;
63 u8 bits_per_sample; 82 u8 bits_per_sample;
64}; 83};
65 84
@@ -80,6 +99,8 @@ const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
80const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 99const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
81 enum v4l2_mbus_pixelcode code); 100 enum v4l2_mbus_pixelcode code);
82s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); 101s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf);
102s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
103 u32 bytes_per_line, u32 height);
83int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf, 104int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
84 unsigned int *numerator, unsigned int *denominator); 105 unsigned int *numerator, unsigned int *denominator);
85unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg, 106unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 11e67562b3ac..776605f1cbe2 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -25,6 +25,7 @@
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26 26
27/* forward references */ 27/* forward references */
28struct file;
28struct v4l2_ctrl_handler; 29struct v4l2_ctrl_handler;
29struct v4l2_ctrl_helper; 30struct v4l2_ctrl_helper;
30struct v4l2_ctrl; 31struct v4l2_ctrl;
@@ -129,7 +130,10 @@ struct v4l2_ctrl {
129 u32 step; 130 u32 step;
130 u32 menu_skip_mask; 131 u32 menu_skip_mask;
131 }; 132 };
132 const char * const *qmenu; 133 union {
134 const char * const *qmenu;
135 const s64 *qmenu_int;
136 };
133 unsigned long flags; 137 unsigned long flags;
134 union { 138 union {
135 s32 val; 139 s32 val;
@@ -164,7 +168,9 @@ struct v4l2_ctrl_ref {
164/** struct v4l2_ctrl_handler - The control handler keeps track of all the 168/** struct v4l2_ctrl_handler - The control handler keeps track of all the
165 * controls: both the controls owned by the handler and those inherited 169 * controls: both the controls owned by the handler and those inherited
166 * from other handlers. 170 * from other handlers.
171 * @_lock: Default for "lock".
167 * @lock: Lock to control access to this handler and its controls. 172 * @lock: Lock to control access to this handler and its controls.
173 * May be replaced by the user right after init.
168 * @ctrls: The list of controls owned by this handler. 174 * @ctrls: The list of controls owned by this handler.
169 * @ctrl_refs: The list of control references. 175 * @ctrl_refs: The list of control references.
170 * @cached: The last found control reference. It is common that the same 176 * @cached: The last found control reference. It is common that the same
@@ -175,7 +181,8 @@ struct v4l2_ctrl_ref {
175 * @error: The error code of the first failed control addition. 181 * @error: The error code of the first failed control addition.
176 */ 182 */
177struct v4l2_ctrl_handler { 183struct v4l2_ctrl_handler {
178 struct mutex lock; 184 struct mutex _lock;
185 struct mutex *lock;
179 struct list_head ctrls; 186 struct list_head ctrls;
180 struct list_head ctrl_refs; 187 struct list_head ctrl_refs;
181 struct v4l2_ctrl_ref *cached; 188 struct v4l2_ctrl_ref *cached;
@@ -219,6 +226,7 @@ struct v4l2_ctrl_config {
219 u32 flags; 226 u32 flags;
220 u32 menu_skip_mask; 227 u32 menu_skip_mask;
221 const char * const *qmenu; 228 const char * const *qmenu;
229 const s64 *qmenu_int;
222 unsigned int is_private:1; 230 unsigned int is_private:1;
223}; 231};
224 232
@@ -343,6 +351,23 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
343 const struct v4l2_ctrl_ops *ops, 351 const struct v4l2_ctrl_ops *ops,
344 u32 id, s32 max, s32 mask, s32 def); 352 u32 id, s32 max, s32 mask, s32 def);
345 353
354/** v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control.
355 * @hdl: The control handler.
356 * @ops: The control ops.
357 * @id: The control ID.
358 * @max: The control's maximum value.
359 * @def: The control's default value.
360 * @qmenu_int: The control's menu entries.
361 *
362 * Same as v4l2_ctrl_new_std_menu(), but @mask is set to 0 and it additionaly
363 * takes as an argument an array of integers determining the menu items.
364 *
365 * If @id refers to a non-integer-menu control, then this function will return NULL.
366 */
367struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
368 const struct v4l2_ctrl_ops *ops,
369 u32 id, s32 max, s32 def, const s64 *qmenu_int);
370
346/** v4l2_ctrl_add_ctrl() - Add a control from another handler to this handler. 371/** v4l2_ctrl_add_ctrl() - Add a control from another handler to this handler.
347 * @hdl: The control handler. 372 * @hdl: The control handler.
348 * @ctrl: The control to add. 373 * @ctrl: The control to add.
@@ -451,7 +476,7 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
451 */ 476 */
452static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) 477static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
453{ 478{
454 mutex_lock(&ctrl->handler->lock); 479 mutex_lock(ctrl->handler->lock);
455} 480}
456 481
457/** v4l2_ctrl_lock() - Helper function to unlock the handler 482/** v4l2_ctrl_lock() - Helper function to unlock the handler
@@ -460,7 +485,7 @@ static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
460 */ 485 */
461static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl) 486static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
462{ 487{
463 mutex_unlock(&ctrl->handler->lock); 488 mutex_unlock(ctrl->handler->lock);
464} 489}
465 490
466/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. 491/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.
@@ -487,10 +512,9 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
487int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val); 512int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
488 513
489/* Internal helper functions that deal with control events. */ 514/* Internal helper functions that deal with control events. */
490void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl, 515extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
491 struct v4l2_subscribed_event *sev); 516void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);
492void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, 517void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new);
493 struct v4l2_subscribed_event *sev);
494 518
495/* Can be used as a vidioc_log_status function that just dumps all controls 519/* Can be used as a vidioc_log_status function that just dumps all controls
496 associated with the filehandle. */ 520 associated with the filehandle. */
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 96d22215cc88..a056e6ee1b68 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -39,6 +39,9 @@ struct v4l2_ctrl_handler;
39#define V4L2_FL_USES_V4L2_FH (1) 39#define V4L2_FL_USES_V4L2_FH (1)
40/* Use the prio field of v4l2_fh for core priority checking */ 40/* Use the prio field of v4l2_fh for core priority checking */
41#define V4L2_FL_USE_FH_PRIO (2) 41#define V4L2_FL_USE_FH_PRIO (2)
42/* If ioctl core locking is in use, then apply that also to all
43 file operations. Don't use this flag in new drivers! */
44#define V4L2_FL_LOCK_ALL_FOPS (3)
42 45
43/* Priority helper functions */ 46/* Priority helper functions */
44 47
@@ -126,8 +129,10 @@ struct video_device
126 129
127 /* ioctl callbacks */ 130 /* ioctl callbacks */
128 const struct v4l2_ioctl_ops *ioctl_ops; 131 const struct v4l2_ioctl_ops *ioctl_ops;
132 DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
129 133
130 /* serialization lock */ 134 /* serialization lock */
135 DECLARE_BITMAP(disable_locking, BASE_VIDIOC_PRIVATE);
131 struct mutex *lock; 136 struct mutex *lock;
132}; 137};
133 138
@@ -173,6 +178,26 @@ void video_device_release(struct video_device *vdev);
173 a dubious construction at best. */ 178 a dubious construction at best. */
174void video_device_release_empty(struct video_device *vdev); 179void video_device_release_empty(struct video_device *vdev);
175 180
181/* returns true if cmd is a known V4L2 ioctl */
182bool v4l2_is_known_ioctl(unsigned int cmd);
183
184/* mark that this command shouldn't use core locking */
185static inline void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd)
186{
187 if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
188 set_bit(_IOC_NR(cmd), vdev->disable_locking);
189}
190
191/* Mark that this command isn't implemented. This must be called before
192 video_device_register. See also the comments in determine_valid_ioctls().
193 This function allows drivers to provide just one v4l2_ioctl_ops struct, but
194 disable ioctls based on the specific card that is actually found. */
195static inline void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd)
196{
197 if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
198 set_bit(_IOC_NR(cmd), vdev->valid_ioctls);
199}
200
176/* helper functions to access driver private data. */ 201/* helper functions to access driver private data. */
177static inline void *video_get_drvdata(struct video_device *vdev) 202static inline void *video_get_drvdata(struct video_device *vdev)
178{ 203{
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index 5f14e8895ce2..2885a810a128 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -78,6 +78,19 @@ struct v4l2_kevent {
78 struct v4l2_event event; 78 struct v4l2_event event;
79}; 79};
80 80
81/** struct v4l2_subscribed_event_ops - Subscribed event operations.
82 * @add: Optional callback, called when a new listener is added
83 * @del: Optional callback, called when a listener stops listening
84 * @replace: Optional callback that can replace event 'old' with event 'new'.
85 * @merge: Optional callback that can merge event 'old' into event 'new'.
86 */
87struct v4l2_subscribed_event_ops {
88 int (*add)(struct v4l2_subscribed_event *sev, unsigned elems);
89 void (*del)(struct v4l2_subscribed_event *sev);
90 void (*replace)(struct v4l2_event *old, const struct v4l2_event *new);
91 void (*merge)(const struct v4l2_event *old, struct v4l2_event *new);
92};
93
81/** struct v4l2_subscribed_event - Internal struct representing a subscribed event. 94/** struct v4l2_subscribed_event - Internal struct representing a subscribed event.
82 * @list: List node for the v4l2_fh->subscribed list. 95 * @list: List node for the v4l2_fh->subscribed list.
83 * @type: Event type. 96 * @type: Event type.
@@ -85,8 +98,7 @@ struct v4l2_kevent {
85 * @flags: Copy of v4l2_event_subscription->flags. 98 * @flags: Copy of v4l2_event_subscription->flags.
86 * @fh: Filehandle that subscribed to this event. 99 * @fh: Filehandle that subscribed to this event.
87 * @node: List node that hooks into the object's event list (if there is one). 100 * @node: List node that hooks into the object's event list (if there is one).
88 * @replace: Optional callback that can replace event 'old' with event 'new'. 101 * @ops: v4l2_subscribed_event_ops
89 * @merge: Optional callback that can merge event 'old' into event 'new'.
90 * @elems: The number of elements in the events array. 102 * @elems: The number of elements in the events array.
91 * @first: The index of the events containing the oldest available event. 103 * @first: The index of the events containing the oldest available event.
92 * @in_use: The number of queued events. 104 * @in_use: The number of queued events.
@@ -99,10 +111,7 @@ struct v4l2_subscribed_event {
99 u32 flags; 111 u32 flags;
100 struct v4l2_fh *fh; 112 struct v4l2_fh *fh;
101 struct list_head node; 113 struct list_head node;
102 void (*replace)(struct v4l2_event *old, 114 const struct v4l2_subscribed_event_ops *ops;
103 const struct v4l2_event *new);
104 void (*merge)(const struct v4l2_event *old,
105 struct v4l2_event *new);
106 unsigned elems; 115 unsigned elems;
107 unsigned first; 116 unsigned first;
108 unsigned in_use; 117 unsigned in_use;
@@ -115,7 +124,8 @@ void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
115void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev); 124void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev);
116int v4l2_event_pending(struct v4l2_fh *fh); 125int v4l2_event_pending(struct v4l2_fh *fh);
117int v4l2_event_subscribe(struct v4l2_fh *fh, 126int v4l2_event_subscribe(struct v4l2_fh *fh,
118 struct v4l2_event_subscription *sub, unsigned elems); 127 struct v4l2_event_subscription *sub, unsigned elems,
128 const struct v4l2_subscribed_event_ops *ops);
119int v4l2_event_unsubscribe(struct v4l2_fh *fh, 129int v4l2_event_unsubscribe(struct v4l2_fh *fh,
120 struct v4l2_event_subscription *sub); 130 struct v4l2_event_subscription *sub);
121void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); 131void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 3cb939cd03f9..d8b76f7392f8 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -271,6 +271,12 @@ struct v4l2_ioctl_ops {
271 struct v4l2_dv_timings *timings); 271 struct v4l2_dv_timings *timings);
272 int (*vidioc_g_dv_timings) (struct file *file, void *fh, 272 int (*vidioc_g_dv_timings) (struct file *file, void *fh,
273 struct v4l2_dv_timings *timings); 273 struct v4l2_dv_timings *timings);
274 int (*vidioc_query_dv_timings) (struct file *file, void *fh,
275 struct v4l2_dv_timings *timings);
276 int (*vidioc_enum_dv_timings) (struct file *file, void *fh,
277 struct v4l2_enum_dv_timings *timings);
278 int (*vidioc_dv_timings_cap) (struct file *file, void *fh,
279 struct v4l2_dv_timings_cap *cap);
274 280
275 int (*vidioc_subscribe_event) (struct v4l2_fh *fh, 281 int (*vidioc_subscribe_event) (struct v4l2_fh *fh,
276 struct v4l2_event_subscription *sub); 282 struct v4l2_event_subscription *sub);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index f0f3358d1b1b..c35a3545e273 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -307,6 +307,12 @@ struct v4l2_subdev_video_ops {
307 struct v4l2_dv_timings *timings); 307 struct v4l2_dv_timings *timings);
308 int (*g_dv_timings)(struct v4l2_subdev *sd, 308 int (*g_dv_timings)(struct v4l2_subdev *sd,
309 struct v4l2_dv_timings *timings); 309 struct v4l2_dv_timings *timings);
310 int (*enum_dv_timings)(struct v4l2_subdev *sd,
311 struct v4l2_enum_dv_timings *timings);
312 int (*query_dv_timings)(struct v4l2_subdev *sd,
313 struct v4l2_dv_timings *timings);
314 int (*dv_timings_cap)(struct v4l2_subdev *sd,
315 struct v4l2_dv_timings_cap *cap);
310 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, 316 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
311 enum v4l2_mbus_pixelcode *code); 317 enum v4l2_mbus_pixelcode *code);
312 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, 318 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd,
@@ -466,6 +472,15 @@ struct v4l2_subdev_pad_ops {
466 struct v4l2_subdev_crop *crop); 472 struct v4l2_subdev_crop *crop);
467 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 473 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
468 struct v4l2_subdev_crop *crop); 474 struct v4l2_subdev_crop *crop);
475 int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
476 struct v4l2_subdev_selection *sel);
477 int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
478 struct v4l2_subdev_selection *sel);
479#ifdef CONFIG_MEDIA_CONTROLLER
480 int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
481 struct v4l2_subdev_format *source_fmt,
482 struct v4l2_subdev_format *sink_fmt);
483#endif /* CONFIG_MEDIA_CONTROLLER */
469}; 484};
470 485
471struct v4l2_subdev_ops { 486struct v4l2_subdev_ops {
@@ -541,7 +556,7 @@ struct v4l2_subdev {
541#define media_entity_to_v4l2_subdev(ent) \ 556#define media_entity_to_v4l2_subdev(ent) \
542 container_of(ent, struct v4l2_subdev, entity) 557 container_of(ent, struct v4l2_subdev, entity)
543#define vdev_to_v4l2_subdev(vdev) \ 558#define vdev_to_v4l2_subdev(vdev) \
544 video_get_drvdata(vdev) 559 ((struct v4l2_subdev *)video_get_drvdata(vdev))
545 560
546/* 561/*
547 * Used for storing subdev information per file handle 562 * Used for storing subdev information per file handle
@@ -549,8 +564,11 @@ struct v4l2_subdev {
549struct v4l2_subdev_fh { 564struct v4l2_subdev_fh {
550 struct v4l2_fh vfh; 565 struct v4l2_fh vfh;
551#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 566#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
552 struct v4l2_mbus_framefmt *try_fmt; 567 struct {
553 struct v4l2_rect *try_crop; 568 struct v4l2_mbus_framefmt try_fmt;
569 struct v4l2_rect try_crop;
570 struct v4l2_rect try_compose;
571 } *pad;
554#endif 572#endif
555}; 573};
556 574
@@ -558,17 +576,19 @@ struct v4l2_subdev_fh {
558 container_of(fh, struct v4l2_subdev_fh, vfh) 576 container_of(fh, struct v4l2_subdev_fh, vfh)
559 577
560#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 578#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
561static inline struct v4l2_mbus_framefmt * 579#define __V4L2_SUBDEV_MK_GET_TRY(rtype, fun_name, field_name) \
562v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad) 580 static inline struct rtype * \
563{ 581 v4l2_subdev_get_try_##fun_name(struct v4l2_subdev_fh *fh, \
564 return &fh->try_fmt[pad]; 582 unsigned int pad) \
565} 583 { \
566 584 BUG_ON(unlikely(pad >= vdev_to_v4l2_subdev( \
567static inline struct v4l2_rect * 585 fh->vfh.vdev)->entity.num_pads)); \
568v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad) 586 return &fh->pad[pad].field_name; \
569{ 587 }
570 return &fh->try_crop[pad]; 588
571} 589__V4L2_SUBDEV_MK_GET_TRY(v4l2_mbus_framefmt, format, try_fmt)
590__V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, crop, try_compose)
591__V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, compose, try_compose)
572#endif 592#endif
573 593
574extern const struct v4l2_file_operations v4l2_subdev_fops; 594extern const struct v4l2_file_operations v4l2_subdev_fops;
@@ -593,6 +613,13 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
593 return sd->host_priv; 613 return sd->host_priv;
594} 614}
595 615
616#ifdef CONFIG_MEDIA_CONTROLLER
617int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
618 struct media_link *link,
619 struct v4l2_subdev_format *source_fmt,
620 struct v4l2_subdev_format *sink_fmt);
621int v4l2_subdev_link_validate(struct media_link *link);
622#endif /* CONFIG_MEDIA_CONTROLLER */
596void v4l2_subdev_init(struct v4l2_subdev *sd, 623void v4l2_subdev_init(struct v4l2_subdev *sd,
597 const struct v4l2_subdev_ops *ops); 624 const struct v4l2_subdev_ops *ops);
598 625
diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h
index f0ed82543d9f..f473aeb86d3f 100644
--- a/include/media/videobuf-dma-contig.h
+++ b/include/media/videobuf-dma-contig.h
@@ -26,6 +26,16 @@ void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
26 void *priv, 26 void *priv,
27 struct mutex *ext_lock); 27 struct mutex *ext_lock);
28 28
29void videobuf_queue_dma_contig_init_cached(struct videobuf_queue *q,
30 const struct videobuf_queue_ops *ops,
31 struct device *dev,
32 spinlock_t *irqlock,
33 enum v4l2_buf_type type,
34 enum v4l2_field field,
35 unsigned int msize,
36 void *priv,
37 struct mutex *ext_lock);
38
29dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); 39dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
30void videobuf_dma_contig_free(struct videobuf_queue *q, 40void videobuf_dma_contig_free(struct videobuf_queue *q,
31 struct videobuf_buffer *buf); 41 struct videobuf_buffer *buf);
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index c744b88c44e2..59dcf5b81d24 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -402,6 +402,7 @@ unsigned int __kfifo_max_r(unsigned int len, size_t recsize)
402 return max; 402 return max;
403 return len; 403 return len;
404} 404}
405EXPORT_SYMBOL(__kfifo_max_r);
405 406
406#define __KFIFO_PEEK(data, out, mask) \ 407#define __KFIFO_PEEK(data, out, mask) \
407 ((data)[(out) & (mask)]) 408 ((data)[(out) & (mask)])
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index a63faec5e7fd..582aace20ea3 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -375,6 +375,9 @@ int snd_tea575x_init(struct snd_tea575x *tea)
375 tea->vd.v4l2_dev = tea->v4l2_dev; 375 tea->vd.v4l2_dev = tea->v4l2_dev;
376 tea->vd.ctrl_handler = &tea->ctrl_handler; 376 tea->vd.ctrl_handler = &tea->ctrl_handler;
377 set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); 377 set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
378 /* disable hw_freq_seek if we can't use it */
379 if (tea->cannot_read_data)
380 v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
378 381
379 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); 382 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
380 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 383 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);