]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge tag 'media/v4.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Feb 2017 00:58:32 +0000 (16:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Feb 2017 00:58:32 +0000 (16:58 -0800)
Pull media updates from Mauro Carvalho Chehab:

 - new drivers:
       - i.MX6 Video Data Order Adapter's (VDOA)
       - Toshiba et8ek8 5MP sensor
       - STM DELTA multi-format video decoder V4L2 driver
       - SPI connected IR LED
       - Mediatek IR remote receiver
       - ZyDAS ZD1301 DVB USB interface driver

 - new RC keymaps

 - some very old LIRC drivers got removed from staging

 - RC core gained support encoding IR scan codes

 - DVB si2168 gained support for DVBv5 statistics

 - lirc_sir driver ported to rc-core and promoted from staging

 - other bug fixes, board additions and driver improvements

* tag 'media/v4.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (230 commits)
  [media] mtk-vcodec: fix build warnings without DEBUG
  [media] zd1301: fix building interface driver without demodulator
  [media] usbtv: add sharpness control
  [media] cxusb: Use a dma capable buffer also for reading
  [media] ttpci: address stringop overflow warning
  [media] dvb-usb-v2: avoid use-after-free
  [media] add Hama Hybrid DVB-T Stick support
  [media] et8ek8: Fix compiler / Coccinelle warnings
  [media] media: fix semicolon.cocci warnings
  [media] media: exynos4-is: add flags to dummy Exynos IS i2c adapter
  [media] v4l: of: check for unique lanes in data-lanes and clock-lanes
  [media] coda/imx-vdoa: constify structs
  [media] st-delta: debug: trace stream/frame information & summary
  [media] st-delta: add mjpeg support
  [media] st-delta: EOS (End Of Stream) support
  [media] st-delta: rpmsg ipc support
  [media] st-delta: add memory allocator helper functions
  [media] st-delta: STiH4xx multi-format video decoder v4l2 driver
  [media] MAINTAINERS: add st-delta driver
  [media] ARM: multi_v7_defconfig: enable STMicroelectronics DELTA Support
  ...

863 files changed:
Documentation/ABI/testing/sysfs-class-rc
Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/fsl-vdoa.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/gpio-ir-receiver.txt
Documentation/devicetree/bindings/media/hix5hd2-ir.txt
Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/meson-ir.txt
Documentation/devicetree/bindings/media/mtk-cir.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/rc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/st,st-delta.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/sunxi-ir.txt
Documentation/devicetree/bindings/media/ti,da850-vpif.txt [new file with mode: 0644]
Documentation/media/kapi/mc-core.rst
Documentation/media/uapi/gen-errors.rst
Documentation/media/uapi/rc/rc-sysfs-nodes.rst
MAINTAINERS
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/stih407-family.dtsi
arch/arm/configs/multi_v7_defconfig
arch/arm/mach-omap2/pdata-quirks.c
drivers/hid/hid-picolcd_cir.c
drivers/media/cec/cec-core.c
drivers/media/common/b2c2/flexcop-fe-tuner.c
drivers/media/common/b2c2/flexcop.c
drivers/media/common/cx2341x.c
drivers/media/common/siano/sms-cards.c
drivers/media/common/siano/sms-cards.h
drivers/media/common/siano/smscoreapi.c
drivers/media/common/siano/smsir.c
drivers/media/common/tveeprom.c
drivers/media/dvb-core/demux.h
drivers/media/dvb-core/dmxdev.c
drivers/media/dvb-core/dmxdev.h
drivers/media/dvb-core/dvb-usb-ids.h
drivers/media/dvb-core/dvb_ca_en50221.c
drivers/media/dvb-core/dvb_demux.c
drivers/media/dvb-core/dvb_demux.h
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvb_math.c
drivers/media/dvb-core/dvb_math.h
drivers/media/dvb-core/dvb_net.c
drivers/media/dvb-core/dvb_net.h
drivers/media/dvb-core/dvb_ringbuffer.c
drivers/media/dvb-core/dvbdev.c
drivers/media/dvb-core/dvbdev.h
drivers/media/dvb-frontends/Kconfig
drivers/media/dvb-frontends/Makefile
drivers/media/dvb-frontends/af9013.c
drivers/media/dvb-frontends/af9013.h
drivers/media/dvb-frontends/af9013_priv.h
drivers/media/dvb-frontends/af9033.c
drivers/media/dvb-frontends/af9033.h
drivers/media/dvb-frontends/af9033_priv.h
drivers/media/dvb-frontends/atbm8830.c
drivers/media/dvb-frontends/atbm8830.h
drivers/media/dvb-frontends/atbm8830_priv.h
drivers/media/dvb-frontends/au8522_decoder.c
drivers/media/dvb-frontends/bcm3510.h
drivers/media/dvb-frontends/bcm3510_priv.h
drivers/media/dvb-frontends/bsbe1-d01a.h
drivers/media/dvb-frontends/bsbe1.h
drivers/media/dvb-frontends/bsru6.h
drivers/media/dvb-frontends/cx24113.c
drivers/media/dvb-frontends/cx24113.h
drivers/media/dvb-frontends/cx24123.c
drivers/media/dvb-frontends/cxd2820r_core.c
drivers/media/dvb-frontends/dib0070.c
drivers/media/dvb-frontends/dib0090.c
drivers/media/dvb-frontends/dib7000p.c
drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
drivers/media/dvb-frontends/drxd.h
drivers/media/dvb-frontends/drxd_firm.c
drivers/media/dvb-frontends/drxd_firm.h
drivers/media/dvb-frontends/drxd_hard.c
drivers/media/dvb-frontends/drxd_map_firm.h
drivers/media/dvb-frontends/drxk_hard.c
drivers/media/dvb-frontends/dvb-pll.c
drivers/media/dvb-frontends/dvb_dummy_fe.c
drivers/media/dvb-frontends/dvb_dummy_fe.h
drivers/media/dvb-frontends/ec100.c
drivers/media/dvb-frontends/ec100.h
drivers/media/dvb-frontends/hd29l2.c [deleted file]
drivers/media/dvb-frontends/hd29l2.h [deleted file]
drivers/media/dvb-frontends/hd29l2_priv.h [deleted file]
drivers/media/dvb-frontends/isl6405.c
drivers/media/dvb-frontends/isl6405.h
drivers/media/dvb-frontends/isl6421.c
drivers/media/dvb-frontends/isl6421.h
drivers/media/dvb-frontends/itd1000.c
drivers/media/dvb-frontends/itd1000.h
drivers/media/dvb-frontends/itd1000_priv.h
drivers/media/dvb-frontends/ix2505v.c
drivers/media/dvb-frontends/ix2505v.h
drivers/media/dvb-frontends/lg2160.c
drivers/media/dvb-frontends/lg2160.h
drivers/media/dvb-frontends/lgdt3305.c
drivers/media/dvb-frontends/lgdt3305.h
drivers/media/dvb-frontends/lgdt3306a.c
drivers/media/dvb-frontends/lgdt3306a.h
drivers/media/dvb-frontends/lgdt330x.c
drivers/media/dvb-frontends/lgdt330x.h
drivers/media/dvb-frontends/lgdt330x_priv.h
drivers/media/dvb-frontends/lgs8gxx.c
drivers/media/dvb-frontends/lgs8gxx.h
drivers/media/dvb-frontends/lgs8gxx_priv.h
drivers/media/dvb-frontends/lnbh24.h
drivers/media/dvb-frontends/lnbp21.c
drivers/media/dvb-frontends/lnbp21.h
drivers/media/dvb-frontends/lnbp22.c
drivers/media/dvb-frontends/lnbp22.h
drivers/media/dvb-frontends/mn88473.c
drivers/media/dvb-frontends/mt352.c
drivers/media/dvb-frontends/mt352.h
drivers/media/dvb-frontends/mt352_priv.h
drivers/media/dvb-frontends/nxt200x.c
drivers/media/dvb-frontends/nxt200x.h
drivers/media/dvb-frontends/or51132.c
drivers/media/dvb-frontends/or51132.h
drivers/media/dvb-frontends/or51211.c
drivers/media/dvb-frontends/or51211.h
drivers/media/dvb-frontends/rtl2832_sdr.c
drivers/media/dvb-frontends/s5h1420.c
drivers/media/dvb-frontends/s5h1420.h
drivers/media/dvb-frontends/s5h1432.c
drivers/media/dvb-frontends/s5h1432.h
drivers/media/dvb-frontends/si2168.c
drivers/media/dvb-frontends/si2168_priv.h
drivers/media/dvb-frontends/stv0367.c
drivers/media/dvb-frontends/stv0367.h
drivers/media/dvb-frontends/stv0367_priv.h
drivers/media/dvb-frontends/stv0367_regs.h
drivers/media/dvb-frontends/stv0900.h
drivers/media/dvb-frontends/stv0900_core.c
drivers/media/dvb-frontends/stv0900_init.h
drivers/media/dvb-frontends/stv0900_priv.h
drivers/media/dvb-frontends/stv0900_reg.h
drivers/media/dvb-frontends/stv0900_sw.c
drivers/media/dvb-frontends/stv6110.c
drivers/media/dvb-frontends/stv6110.h
drivers/media/dvb-frontends/tda18271c2dd.c
drivers/media/dvb-frontends/tdhd1.h
drivers/media/dvb-frontends/tua6100.c
drivers/media/dvb-frontends/tua6100.h
drivers/media/dvb-frontends/zd1301_demod.c [new file with mode: 0644]
drivers/media/dvb-frontends/zd1301_demod.h [new file with mode: 0644]
drivers/media/dvb-frontends/zl10036.c
drivers/media/dvb-frontends/zl10036.h
drivers/media/dvb-frontends/zl10039.c
drivers/media/dvb-frontends/zl10353.c
drivers/media/dvb-frontends/zl10353.h
drivers/media/dvb-frontends/zl10353_priv.h
drivers/media/i2c/Kconfig
drivers/media/i2c/Makefile
drivers/media/i2c/adp1653.c
drivers/media/i2c/adv7170.c
drivers/media/i2c/adv7175.c
drivers/media/i2c/adv7180.c
drivers/media/i2c/adv7183.c
drivers/media/i2c/adv7183_regs.h
drivers/media/i2c/adv7604.c
drivers/media/i2c/ak881x.c
drivers/media/i2c/aptina-pll.c
drivers/media/i2c/aptina-pll.h
drivers/media/i2c/as3645a.c
drivers/media/i2c/bt819.c
drivers/media/i2c/bt856.c
drivers/media/i2c/cs5345.c
drivers/media/i2c/cs53l32a.c
drivers/media/i2c/cx25840/cx25840-audio.c
drivers/media/i2c/cx25840/cx25840-core.c
drivers/media/i2c/cx25840/cx25840-core.h
drivers/media/i2c/cx25840/cx25840-firmware.c
drivers/media/i2c/cx25840/cx25840-ir.c
drivers/media/i2c/cx25840/cx25840-vbi.c
drivers/media/i2c/et8ek8/Kconfig [new file with mode: 0644]
drivers/media/i2c/et8ek8/Makefile [new file with mode: 0644]
drivers/media/i2c/et8ek8/et8ek8_driver.c [new file with mode: 0644]
drivers/media/i2c/et8ek8/et8ek8_mode.c [new file with mode: 0644]
drivers/media/i2c/et8ek8/et8ek8_reg.h [new file with mode: 0644]
drivers/media/i2c/ir-kbd-i2c.c
drivers/media/i2c/ks0127.c
drivers/media/i2c/ks0127.h
drivers/media/i2c/m52790.c
drivers/media/i2c/m5mols/m5mols_core.c
drivers/media/i2c/ml86v7667.c
drivers/media/i2c/msp3400-driver.c
drivers/media/i2c/msp3400-kthreads.c
drivers/media/i2c/mt9m032.c
drivers/media/i2c/mt9p031.c
drivers/media/i2c/mt9v032.c
drivers/media/i2c/noon010pc30.c
drivers/media/i2c/ov2659.c
drivers/media/i2c/ov7640.c
drivers/media/i2c/ov9650.c
drivers/media/i2c/s5c73m3/s5c73m3-ctrls.c
drivers/media/i2c/s5k6a3.c
drivers/media/i2c/saa7110.c
drivers/media/i2c/saa7115.c
drivers/media/i2c/saa7127.c
drivers/media/i2c/saa717x.c
drivers/media/i2c/saa7185.c
drivers/media/i2c/soc_camera/ov9640.c
drivers/media/i2c/sony-btf-mpx.c
drivers/media/i2c/tc358743.c
drivers/media/i2c/tc358743_regs.h
drivers/media/i2c/tlv320aic23b.c
drivers/media/i2c/tvp514x.c
drivers/media/i2c/tvp514x_regs.h
drivers/media/i2c/tvp7002.c
drivers/media/i2c/tvp7002_reg.h
drivers/media/i2c/tw2804.c
drivers/media/i2c/tw9903.c
drivers/media/i2c/tw9906.c
drivers/media/i2c/uda1342.c
drivers/media/i2c/upd64031a.c
drivers/media/i2c/upd64083.c
drivers/media/i2c/vp27smpx.c
drivers/media/i2c/vpx3220.c
drivers/media/i2c/vs6624.c
drivers/media/i2c/vs6624_regs.h
drivers/media/i2c/wm8739.c
drivers/media/i2c/wm8775.c
drivers/media/media-device.c
drivers/media/media-devnode.c
drivers/media/media-entity.c
drivers/media/pci/b2c2/flexcop-pci.c
drivers/media/pci/bt8xx/bttv-input.c
drivers/media/pci/bt8xx/dst_ca.c
drivers/media/pci/bt8xx/dvb-bt8xx.c
drivers/media/pci/bt8xx/dvb-bt8xx.h
drivers/media/pci/cobalt/cobalt-cpld.c
drivers/media/pci/cx18/cx18-alsa-main.c
drivers/media/pci/cx18/cx18-alsa-mixer.c
drivers/media/pci/cx18/cx18-alsa-mixer.h
drivers/media/pci/cx18/cx18-alsa-pcm.c
drivers/media/pci/cx18/cx18-alsa-pcm.h
drivers/media/pci/cx18/cx18-alsa.h
drivers/media/pci/cx18/cx18-audio.c
drivers/media/pci/cx18/cx18-audio.h
drivers/media/pci/cx18/cx18-av-audio.c
drivers/media/pci/cx18/cx18-av-core.c
drivers/media/pci/cx18/cx18-av-core.h
drivers/media/pci/cx18/cx18-av-firmware.c
drivers/media/pci/cx18/cx18-av-vbi.c
drivers/media/pci/cx18/cx18-cards.c
drivers/media/pci/cx18/cx18-cards.h
drivers/media/pci/cx18/cx18-controls.c
drivers/media/pci/cx18/cx18-driver.c
drivers/media/pci/cx18/cx18-driver.h
drivers/media/pci/cx18/cx18-dvb.c
drivers/media/pci/cx18/cx18-dvb.h
drivers/media/pci/cx18/cx18-fileops.c
drivers/media/pci/cx18/cx18-fileops.h
drivers/media/pci/cx18/cx18-firmware.c
drivers/media/pci/cx18/cx18-firmware.h
drivers/media/pci/cx18/cx18-gpio.c
drivers/media/pci/cx18/cx18-gpio.h
drivers/media/pci/cx18/cx18-i2c.c
drivers/media/pci/cx18/cx18-i2c.h
drivers/media/pci/cx18/cx18-io.c
drivers/media/pci/cx18/cx18-io.h
drivers/media/pci/cx18/cx18-ioctl.c
drivers/media/pci/cx18/cx18-ioctl.h
drivers/media/pci/cx18/cx18-irq.c
drivers/media/pci/cx18/cx18-irq.h
drivers/media/pci/cx18/cx18-mailbox.c
drivers/media/pci/cx18/cx18-mailbox.h
drivers/media/pci/cx18/cx18-queue.c
drivers/media/pci/cx18/cx18-queue.h
drivers/media/pci/cx18/cx18-scb.c
drivers/media/pci/cx18/cx18-scb.h
drivers/media/pci/cx18/cx18-streams.c
drivers/media/pci/cx18/cx18-streams.h
drivers/media/pci/cx18/cx18-vbi.c
drivers/media/pci/cx18/cx18-vbi.h
drivers/media/pci/cx18/cx18-version.h
drivers/media/pci/cx18/cx18-video.c
drivers/media/pci/cx18/cx18-video.h
drivers/media/pci/cx18/cx23418.h
drivers/media/pci/cx23885/cx23885-dvb.c
drivers/media/pci/cx23885/cx23885-input.c
drivers/media/pci/cx25821/cx25821-alsa.c
drivers/media/pci/cx25821/cx25821-audio-upstream.c
drivers/media/pci/cx25821/cx25821-audio-upstream.h
drivers/media/pci/cx25821/cx25821-audio.h
drivers/media/pci/cx25821/cx25821-biffuncs.h
drivers/media/pci/cx25821/cx25821-cards.c
drivers/media/pci/cx25821/cx25821-core.c
drivers/media/pci/cx25821/cx25821-gpio.c
drivers/media/pci/cx25821/cx25821-i2c.c
drivers/media/pci/cx25821/cx25821-medusa-defines.h
drivers/media/pci/cx25821/cx25821-medusa-reg.h
drivers/media/pci/cx25821/cx25821-medusa-video.c
drivers/media/pci/cx25821/cx25821-medusa-video.h
drivers/media/pci/cx25821/cx25821-reg.h
drivers/media/pci/cx25821/cx25821-sram.h
drivers/media/pci/cx25821/cx25821-video-upstream.c
drivers/media/pci/cx25821/cx25821-video-upstream.h
drivers/media/pci/cx25821/cx25821-video.c
drivers/media/pci/cx25821/cx25821-video.h
drivers/media/pci/cx25821/cx25821.h
drivers/media/pci/cx88/cx88-input.c
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/ddbridge/ddbridge-regs.h
drivers/media/pci/ddbridge/ddbridge.h
drivers/media/pci/dm1105/Kconfig
drivers/media/pci/dm1105/dm1105.c
drivers/media/pci/ivtv/Kconfig
drivers/media/pci/ivtv/ivtv-alsa-main.c
drivers/media/pci/ivtv/ivtv-alsa-mixer.c
drivers/media/pci/ivtv/ivtv-alsa-mixer.h
drivers/media/pci/ivtv/ivtv-alsa-pcm.c
drivers/media/pci/ivtv/ivtv-alsa-pcm.h
drivers/media/pci/ivtv/ivtv-alsa.h
drivers/media/pci/ivtv/ivtv-driver.c
drivers/media/pci/ivtv/ivtv-driver.h
drivers/media/pci/ivtv/ivtv-ioctl.c
drivers/media/pci/ivtv/ivtv-mailbox.c
drivers/media/pci/ivtv/ivtvfb.c
drivers/media/pci/mantis/mantis_dvb.c
drivers/media/pci/mantis/mantis_input.c
drivers/media/pci/meye/meye.c
drivers/media/pci/meye/meye.h
drivers/media/pci/ngene/ngene-cards.c
drivers/media/pci/ngene/ngene-core.c
drivers/media/pci/ngene/ngene-dvb.c
drivers/media/pci/ngene/ngene-i2c.c
drivers/media/pci/ngene/ngene.h
drivers/media/pci/pluto2/pluto2.c
drivers/media/pci/pt1/pt1.c
drivers/media/pci/pt1/va1j5jf8007s.c
drivers/media/pci/pt1/va1j5jf8007s.h
drivers/media/pci/pt1/va1j5jf8007t.c
drivers/media/pci/pt1/va1j5jf8007t.h
drivers/media/pci/saa7134/saa7134-alsa.c
drivers/media/pci/saa7134/saa7134-cards.c
drivers/media/pci/saa7134/saa7134-core.c
drivers/media/pci/saa7134/saa7134-dvb.c
drivers/media/pci/saa7134/saa7134-empress.c
drivers/media/pci/saa7134/saa7134-i2c.c
drivers/media/pci/saa7134/saa7134-input.c
drivers/media/pci/saa7134/saa7134-ts.c
drivers/media/pci/saa7134/saa7134-tvaudio.c
drivers/media/pci/saa7134/saa7134-vbi.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/saa7134/saa7134.h
drivers/media/pci/saa7164/saa7164-api.c
drivers/media/pci/saa7164/saa7164-buffer.c
drivers/media/pci/saa7164/saa7164-bus.c
drivers/media/pci/saa7164/saa7164-cards.c
drivers/media/pci/saa7164/saa7164-cmd.c
drivers/media/pci/saa7164/saa7164-core.c
drivers/media/pci/saa7164/saa7164-dvb.c
drivers/media/pci/saa7164/saa7164-encoder.c
drivers/media/pci/saa7164/saa7164-fw.c
drivers/media/pci/saa7164/saa7164-i2c.c
drivers/media/pci/saa7164/saa7164-reg.h
drivers/media/pci/saa7164/saa7164-types.h
drivers/media/pci/saa7164/saa7164-vbi.c
drivers/media/pci/saa7164/saa7164.h
drivers/media/pci/smipcie/smipcie-ir.c
drivers/media/pci/solo6x10/solo6x10-g723.c
drivers/media/pci/sta2x11/sta2x11_vip.c
drivers/media/pci/sta2x11/sta2x11_vip.h
drivers/media/pci/ttpci/av7110.c
drivers/media/pci/ttpci/av7110_av.c
drivers/media/pci/ttpci/av7110_ca.c
drivers/media/pci/ttpci/av7110_hw.c
drivers/media/pci/ttpci/av7110_hw.h
drivers/media/pci/ttpci/av7110_ir.c
drivers/media/pci/ttpci/av7110_v4l.c
drivers/media/pci/ttpci/budget-av.c
drivers/media/pci/ttpci/budget-ci.c
drivers/media/pci/ttpci/budget-core.c
drivers/media/pci/ttpci/budget-patch.c
drivers/media/pci/ttpci/budget.c
drivers/media/pci/ttpci/dvb_filter.h
drivers/media/pci/tw686x/tw686x-core.c
drivers/media/pci/zoran/videocodec.c
drivers/media/pci/zoran/videocodec.h
drivers/media/pci/zoran/zoran.h
drivers/media/pci/zoran/zoran_card.c
drivers/media/pci/zoran/zoran_card.h
drivers/media/pci/zoran/zoran_device.c
drivers/media/pci/zoran/zoran_device.h
drivers/media/pci/zoran/zoran_driver.c
drivers/media/pci/zoran/zoran_procfs.c
drivers/media/pci/zoran/zoran_procfs.h
drivers/media/pci/zoran/zr36016.c
drivers/media/pci/zoran/zr36016.h
drivers/media/pci/zoran/zr36050.c
drivers/media/pci/zoran/zr36050.h
drivers/media/pci/zoran/zr36057.h
drivers/media/pci/zoran/zr36060.c
drivers/media/pci/zoran/zr36060.h
drivers/media/platform/Kconfig
drivers/media/platform/Makefile
drivers/media/platform/am437x/am437x-vpfe.c
drivers/media/platform/blackfin/bfin_capture.c
drivers/media/platform/blackfin/ppi.c
drivers/media/platform/coda/Makefile
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/coda/coda.h
drivers/media/platform/coda/imx-vdoa.c [new file with mode: 0644]
drivers/media/platform/coda/imx-vdoa.h [new file with mode: 0644]
drivers/media/platform/davinci/ccdc_hw_device.h
drivers/media/platform/davinci/dm355_ccdc.c
drivers/media/platform/davinci/dm355_ccdc_regs.h
drivers/media/platform/davinci/dm644x_ccdc.c
drivers/media/platform/davinci/dm644x_ccdc_regs.h
drivers/media/platform/davinci/isif.c
drivers/media/platform/davinci/isif_regs.h
drivers/media/platform/davinci/vpbe.c
drivers/media/platform/davinci/vpbe_osd.c
drivers/media/platform/davinci/vpbe_osd_regs.h
drivers/media/platform/davinci/vpbe_venc.c
drivers/media/platform/davinci/vpbe_venc_regs.h
drivers/media/platform/davinci/vpfe_capture.c
drivers/media/platform/davinci/vpif.c
drivers/media/platform/davinci/vpif_capture.c
drivers/media/platform/davinci/vpif_capture.h
drivers/media/platform/davinci/vpif_display.c
drivers/media/platform/davinci/vpss.c
drivers/media/platform/exynos-gsc/gsc-core.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/exynos4-is/fimc-capture.c
drivers/media/platform/exynos4-is/fimc-is-i2c.c
drivers/media/platform/exynos4-is/fimc-is.c
drivers/media/platform/exynos4-is/fimc-isp-video.c
drivers/media/platform/exynos4-is/fimc-lite.c
drivers/media/platform/exynos4-is/fimc-m2m.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/exynos4-is/media-dev.h
drivers/media/platform/exynos4-is/mipi-csis.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
drivers/media/platform/mtk-vcodec/venc_vpu_if.c
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/rcar_fdp1.c
drivers/media/platform/s3c-camif/camif-capture.c
drivers/media/platform/soc_camera/soc_camera_platform.c
drivers/media/platform/sti/bdisp/bdisp-debug.c
drivers/media/platform/sti/delta/Makefile [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-cfg.h [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-debug.c [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-debug.h [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-ipc.c [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-ipc.h [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-mem.c [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-mem.h [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-mjpeg-dec.c [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-mjpeg-fw.h [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-mjpeg-hdr.c [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-mjpeg.h [new file with mode: 0644]
drivers/media/platform/sti/delta/delta-v4l2.c [new file with mode: 0644]
drivers/media/platform/sti/delta/delta.h [new file with mode: 0644]
drivers/media/platform/sti/hva/Makefile
drivers/media/platform/sti/hva/hva-debugfs.c [new file with mode: 0644]
drivers/media/platform/sti/hva/hva-h264.c
drivers/media/platform/sti/hva/hva-hw.c
drivers/media/platform/sti/hva/hva-hw.h
drivers/media/platform/sti/hva/hva-mem.c
drivers/media/platform/sti/hva/hva-v4l2.c
drivers/media/platform/sti/hva/hva.h
drivers/media/platform/ti-vpe/vpdma.c
drivers/media/platform/vim2m.c
drivers/media/platform/vivid/vivid-vid-cap.c
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/xilinx/xilinx-dma.c
drivers/media/platform/xilinx/xilinx-tpg.c
drivers/media/radio/dsbr100.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-isa.c
drivers/media/radio/radio-isa.h
drivers/media/radio/radio-keene.c
drivers/media/radio/radio-ma901.c
drivers/media/radio/radio-mr800.c
drivers/media/radio/radio-shark.c
drivers/media/radio/radio-shark2.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/radio-tea5777.c
drivers/media/radio/radio-tea5777.h
drivers/media/radio/radio-timb.c
drivers/media/radio/radio-wl1273.c
drivers/media/radio/saa7706h.c
drivers/media/radio/si470x/radio-si470x-common.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/radio/si470x/radio-si470x-usb.c
drivers/media/radio/si470x/radio-si470x.h
drivers/media/radio/si4713/radio-platform-si4713.c
drivers/media/radio/si4713/si4713.c
drivers/media/radio/tef6862.c
drivers/media/radio/wl128x/fmdrv.h
drivers/media/radio/wl128x/fmdrv_common.c
drivers/media/radio/wl128x/fmdrv_common.h
drivers/media/radio/wl128x/fmdrv_rx.c
drivers/media/radio/wl128x/fmdrv_rx.h
drivers/media/radio/wl128x/fmdrv_tx.c
drivers/media/radio/wl128x/fmdrv_tx.h
drivers/media/radio/wl128x/fmdrv_v4l2.c
drivers/media/radio/wl128x/fmdrv_v4l2.h
drivers/media/rc/Kconfig
drivers/media/rc/Makefile
drivers/media/rc/ati_remote.c
drivers/media/rc/ene_ir.c
drivers/media/rc/ene_ir.h
drivers/media/rc/fintek-cir.c
drivers/media/rc/fintek-cir.h
drivers/media/rc/gpio-ir-recv.c
drivers/media/rc/igorplugusb.c
drivers/media/rc/iguanair.c
drivers/media/rc/img-ir/img-ir-hw.c
drivers/media/rc/img-ir/img-ir-nec.c
drivers/media/rc/img-ir/img-ir-raw.c
drivers/media/rc/img-ir/img-ir-sony.c
drivers/media/rc/imon.c
drivers/media/rc/ir-hix5hd2.c
drivers/media/rc/ir-jvc-decoder.c
drivers/media/rc/ir-lirc-codec.c
drivers/media/rc/ir-mce_kbd-decoder.c
drivers/media/rc/ir-nec-decoder.c
drivers/media/rc/ir-rc5-decoder.c
drivers/media/rc/ir-rc6-decoder.c
drivers/media/rc/ir-rx51.c
drivers/media/rc/ir-sanyo-decoder.c
drivers/media/rc/ir-sharp-decoder.c
drivers/media/rc/ir-sony-decoder.c
drivers/media/rc/ir-spi.c [new file with mode: 0644]
drivers/media/rc/ite-cir.c
drivers/media/rc/ite-cir.h
drivers/media/rc/keymaps/Makefile
drivers/media/rc/keymaps/rc-d680-dmb.c [new file with mode: 0644]
drivers/media/rc/keymaps/rc-dvico-mce.c [new file with mode: 0644]
drivers/media/rc/keymaps/rc-dvico-portable.c [new file with mode: 0644]
drivers/media/rc/keymaps/rc-geekbox.c [new file with mode: 0644]
drivers/media/rc/keymaps/rc-rc6-mce.c
drivers/media/rc/keymaps/rc-technisat-usb2.c
drivers/media/rc/keymaps/rc-tivo.c
drivers/media/rc/lirc_dev.c
drivers/media/rc/mceusb.c
drivers/media/rc/meson-ir.c
drivers/media/rc/mtk-cir.c [new file with mode: 0644]
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/nuvoton-cir.h
drivers/media/rc/rc-core-priv.h
drivers/media/rc/rc-ir-raw.c
drivers/media/rc/rc-loopback.c
drivers/media/rc/rc-main.c
drivers/media/rc/redrat3.c
drivers/media/rc/serial_ir.c
drivers/media/rc/st_rc.c
drivers/media/rc/streamzap.c
drivers/media/rc/sunxi-cir.c
drivers/media/rc/ttusbir.c
drivers/media/rc/winbond-cir.c
drivers/media/tuners/fc0011.c
drivers/media/tuners/fc0012-priv.h
drivers/media/tuners/fc0012.c
drivers/media/tuners/fc0012.h
drivers/media/tuners/fc0013-priv.h
drivers/media/tuners/fc0013.c
drivers/media/tuners/fc0013.h
drivers/media/tuners/fc001x-common.h
drivers/media/tuners/it913x.c
drivers/media/tuners/it913x.h
drivers/media/tuners/max2165.c
drivers/media/tuners/max2165.h
drivers/media/tuners/max2165_priv.h
drivers/media/tuners/mc44s803.c
drivers/media/tuners/mc44s803.h
drivers/media/tuners/mc44s803_priv.h
drivers/media/tuners/mt2060.c
drivers/media/tuners/mt2060.h
drivers/media/tuners/mt2060_priv.h
drivers/media/tuners/mt2131.c
drivers/media/tuners/mt2131.h
drivers/media/tuners/mt2131_priv.h
drivers/media/tuners/mxl5007t.c
drivers/media/tuners/mxl5007t.h
drivers/media/tuners/qt1010.c
drivers/media/tuners/qt1010.h
drivers/media/tuners/qt1010_priv.h
drivers/media/tuners/tda18218.c
drivers/media/tuners/tda18218.h
drivers/media/tuners/tda18218_priv.h
drivers/media/tuners/tda827x.c
drivers/media/tuners/xc4000.c
drivers/media/tuners/xc4000.h
drivers/media/tuners/xc5000.c
drivers/media/tuners/xc5000.h
drivers/media/usb/au0828/au0828-cards.c
drivers/media/usb/au0828/au0828-cards.h
drivers/media/usb/au0828/au0828-core.c
drivers/media/usb/au0828/au0828-dvb.c
drivers/media/usb/au0828/au0828-i2c.c
drivers/media/usb/au0828/au0828-input.c
drivers/media/usb/au0828/au0828-reg.h
drivers/media/usb/au0828/au0828-video.c
drivers/media/usb/au0828/au0828.h
drivers/media/usb/cpia2/cpia2.h
drivers/media/usb/cpia2/cpia2_core.c
drivers/media/usb/cpia2/cpia2_registers.h
drivers/media/usb/cpia2/cpia2_usb.c
drivers/media/usb/cpia2/cpia2_v4l.c
drivers/media/usb/cx231xx/Kconfig
drivers/media/usb/cx231xx/cx231xx-417.c
drivers/media/usb/cx231xx/cx231xx-audio.c
drivers/media/usb/cx231xx/cx231xx-cards.c
drivers/media/usb/cx231xx/cx231xx-core.c
drivers/media/usb/cx231xx/cx231xx-dif.h
drivers/media/usb/cx231xx/cx231xx-dvb.c
drivers/media/usb/cx231xx/cx231xx-input.c
drivers/media/usb/cx231xx/cx231xx.h
drivers/media/usb/dvb-usb-v2/Kconfig
drivers/media/usb/dvb-usb-v2/Makefile
drivers/media/usb/dvb-usb-v2/af9015.c
drivers/media/usb/dvb-usb-v2/af9015.h
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/af9035.h
drivers/media/usb/dvb-usb-v2/anysee.c
drivers/media/usb/dvb-usb-v2/anysee.h
drivers/media/usb/dvb-usb-v2/au6610.c
drivers/media/usb/dvb-usb-v2/au6610.h
drivers/media/usb/dvb-usb-v2/ce6230.c
drivers/media/usb/dvb-usb-v2/ce6230.h
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
drivers/media/usb/dvb-usb-v2/dvbsky.c
drivers/media/usb/dvb-usb-v2/ec168.c
drivers/media/usb/dvb-usb-v2/ec168.h
drivers/media/usb/dvb-usb-v2/lmedm04.c
drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/zd1301.c [new file with mode: 0644]
drivers/media/usb/dvb-usb/af9005-fe.c
drivers/media/usb/dvb-usb/af9005-remote.c
drivers/media/usb/dvb-usb/af9005.c
drivers/media/usb/dvb-usb/af9005.h
drivers/media/usb/dvb-usb/cinergyT2-core.c
drivers/media/usb/dvb-usb/cinergyT2-fe.c
drivers/media/usb/dvb-usb/cinergyT2.h
drivers/media/usb/dvb-usb/cxusb.c
drivers/media/usb/dvb-usb/dib0700_devices.c
drivers/media/usb/dvb-usb/dtv5100.c
drivers/media/usb/dvb-usb/dtv5100.h
drivers/media/usb/dvb-usb/dvb-usb-firmware.c
drivers/media/usb/dvb-usb/dvb-usb-remote.c
drivers/media/usb/dvb-usb/gp8psk.c
drivers/media/usb/dvb-usb/technisat-usb2.c
drivers/media/usb/em28xx/em28xx-audio.c
drivers/media/usb/em28xx/em28xx-cards.c
drivers/media/usb/em28xx/em28xx-dvb.c
drivers/media/usb/em28xx/em28xx-input.c
drivers/media/usb/em28xx/em28xx.h
drivers/media/usb/gspca/autogain_functions.c
drivers/media/usb/gspca/benq.c
drivers/media/usb/gspca/conex.c
drivers/media/usb/gspca/cpia1.c
drivers/media/usb/gspca/etoms.c
drivers/media/usb/gspca/finepix.c
drivers/media/usb/gspca/gspca.c
drivers/media/usb/gspca/jeilinj.c
drivers/media/usb/gspca/jl2005bcd.c
drivers/media/usb/gspca/jpeg.h
drivers/media/usb/gspca/kinect.c
drivers/media/usb/gspca/konica.c
drivers/media/usb/gspca/mars.c
drivers/media/usb/gspca/mr97310a.c
drivers/media/usb/gspca/nw80x.c
drivers/media/usb/gspca/ov519.c
drivers/media/usb/gspca/ov534.c
drivers/media/usb/gspca/ov534_9.c
drivers/media/usb/gspca/pac207.c
drivers/media/usb/gspca/pac7302.c
drivers/media/usb/gspca/pac7311.c
drivers/media/usb/gspca/pac_common.h
drivers/media/usb/gspca/se401.c
drivers/media/usb/gspca/se401.h
drivers/media/usb/gspca/sn9c2028.c
drivers/media/usb/gspca/sn9c2028.h
drivers/media/usb/gspca/sn9c20x.c
drivers/media/usb/gspca/sonixb.c
drivers/media/usb/gspca/sonixj.c
drivers/media/usb/gspca/spca1528.c
drivers/media/usb/gspca/spca500.c
drivers/media/usb/gspca/spca501.c
drivers/media/usb/gspca/spca505.c
drivers/media/usb/gspca/spca506.c
drivers/media/usb/gspca/spca508.c
drivers/media/usb/gspca/spca561.c
drivers/media/usb/gspca/sq905.c
drivers/media/usb/gspca/sq905c.c
drivers/media/usb/gspca/sq930x.c
drivers/media/usb/gspca/stk014.c
drivers/media/usb/gspca/stk1135.c
drivers/media/usb/gspca/stk1135.h
drivers/media/usb/gspca/stv0680.c
drivers/media/usb/gspca/stv06xx/stv06xx.c
drivers/media/usb/gspca/stv06xx/stv06xx.h
drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.h
drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.h
drivers/media/usb/gspca/stv06xx/stv06xx_sensor.h
drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
drivers/media/usb/gspca/stv06xx/stv06xx_st6422.h
drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.h
drivers/media/usb/gspca/sunplus.c
drivers/media/usb/gspca/t613.c
drivers/media/usb/gspca/tv8532.c
drivers/media/usb/gspca/vc032x.c
drivers/media/usb/gspca/vicam.c
drivers/media/usb/gspca/w996Xcf.c
drivers/media/usb/gspca/xirlink_cit.c
drivers/media/usb/gspca/zc3xx.c
drivers/media/usb/pvrusb2/pvrusb2-audio.c
drivers/media/usb/pvrusb2/pvrusb2-audio.h
drivers/media/usb/pvrusb2/pvrusb2-context.c
drivers/media/usb/pvrusb2/pvrusb2-context.h
drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c
drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.h
drivers/media/usb/pvrusb2/pvrusb2-ctrl.c
drivers/media/usb/pvrusb2/pvrusb2-ctrl.h
drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.h
drivers/media/usb/pvrusb2/pvrusb2-debug.h
drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
drivers/media/usb/pvrusb2/pvrusb2-debugifc.h
drivers/media/usb/pvrusb2/pvrusb2-devattr.c
drivers/media/usb/pvrusb2/pvrusb2-devattr.h
drivers/media/usb/pvrusb2/pvrusb2-dvb.c
drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
drivers/media/usb/pvrusb2/pvrusb2-eeprom.h
drivers/media/usb/pvrusb2/pvrusb2-encoder.c
drivers/media/usb/pvrusb2/pvrusb2-encoder.h
drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h
drivers/media/usb/pvrusb2/pvrusb2-hdw.c
drivers/media/usb/pvrusb2/pvrusb2-hdw.h
drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
drivers/media/usb/pvrusb2/pvrusb2-i2c-core.h
drivers/media/usb/pvrusb2/pvrusb2-io.c
drivers/media/usb/pvrusb2/pvrusb2-io.h
drivers/media/usb/pvrusb2/pvrusb2-ioread.c
drivers/media/usb/pvrusb2/pvrusb2-ioread.h
drivers/media/usb/pvrusb2/pvrusb2-main.c
drivers/media/usb/pvrusb2/pvrusb2-std.c
drivers/media/usb/pvrusb2/pvrusb2-std.h
drivers/media/usb/pvrusb2/pvrusb2-sysfs.c
drivers/media/usb/pvrusb2/pvrusb2-sysfs.h
drivers/media/usb/pvrusb2/pvrusb2-util.h
drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
drivers/media/usb/pvrusb2/pvrusb2-v4l2.h
drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c
drivers/media/usb/pvrusb2/pvrusb2-video-v4l.h
drivers/media/usb/pvrusb2/pvrusb2-wm8775.c
drivers/media/usb/pvrusb2/pvrusb2-wm8775.h
drivers/media/usb/pvrusb2/pvrusb2.h
drivers/media/usb/s2255/s2255drv.c
drivers/media/usb/stk1160/Kconfig
drivers/media/usb/stk1160/Makefile
drivers/media/usb/stk1160/stk1160-ac97.c
drivers/media/usb/stk1160/stk1160-core.c
drivers/media/usb/stk1160/stk1160-reg.h
drivers/media/usb/stk1160/stk1160.h
drivers/media/usb/stkwebcam/stk-sensor.c
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/stkwebcam/stk-webcam.h
drivers/media/usb/tm6000/tm6000-cards.c
drivers/media/usb/tm6000/tm6000-core.c
drivers/media/usb/tm6000/tm6000-dvb.c
drivers/media/usb/tm6000/tm6000-i2c.c
drivers/media/usb/tm6000/tm6000-input.c
drivers/media/usb/tm6000/tm6000-regs.h
drivers/media/usb/tm6000/tm6000-stds.c
drivers/media/usb/tm6000/tm6000-usb-isoc.h
drivers/media/usb/tm6000/tm6000-video.c
drivers/media/usb/tm6000/tm6000.h
drivers/media/usb/ttusb-dec/ttusb_dec.c
drivers/media/usb/ttusb-dec/ttusbdecfe.c
drivers/media/usb/ttusb-dec/ttusbdecfe.h
drivers/media/usb/usbtv/usbtv-video.c
drivers/media/usb/usbvision/usbvision-cards.c
drivers/media/usb/usbvision/usbvision-core.c
drivers/media/usb/usbvision/usbvision-i2c.c
drivers/media/usb/usbvision/usbvision-video.c
drivers/media/usb/usbvision/usbvision.h
drivers/media/usb/uvc/uvc_debugfs.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/usb/uvc/uvc_video.c
drivers/media/usb/uvc/uvcvideo.h
drivers/media/usb/zr364xx/zr364xx.c
drivers/media/v4l2-core/v4l2-async.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/media/v4l2-core/v4l2-device.c
drivers/media/v4l2-core/v4l2-event.c
drivers/media/v4l2-core/v4l2-fh.c
drivers/media/v4l2-core/v4l2-mc.c
drivers/media/v4l2-core/v4l2-of.c
drivers/media/v4l2-core/v4l2-subdev.c
drivers/staging/media/davinci_vpfe/vpfe_video.c
drivers/staging/media/davinci_vpfe/vpfe_video.h
drivers/staging/media/lirc/Kconfig
drivers/staging/media/lirc/Makefile
drivers/staging/media/lirc/lirc_bt829.c [deleted file]
drivers/staging/media/lirc/lirc_imon.c [deleted file]
drivers/staging/media/lirc/lirc_parallel.c [deleted file]
drivers/staging/media/lirc/lirc_parallel.h [deleted file]
drivers/staging/media/lirc/lirc_sir.c
drivers/staging/media/omap4iss/iss_video.c
drivers/staging/media/s5p-cec/Kconfig
drivers/staging/media/s5p-cec/exynos_hdmi_cec.h
drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
include/linux/platform_data/media/ir-rx51.h
include/media/blackfin/ppi.h
include/media/davinci/ccdc_types.h
include/media/davinci/dm355_ccdc.h
include/media/davinci/dm644x_ccdc.h
include/media/davinci/isif.h
include/media/davinci/vpbe.h
include/media/davinci/vpbe_osd.h
include/media/davinci/vpbe_types.h
include/media/davinci/vpbe_venc.h
include/media/davinci/vpfe_capture.h
include/media/davinci/vpfe_types.h
include/media/davinci/vpif_types.h
include/media/davinci/vpss.h
include/media/drv-intf/tea575x.h
include/media/i2c/adp1653.h
include/media/i2c/adv7183.h
include/media/i2c/as3645a.h
include/media/i2c/lm3560.h
include/media/i2c/mt9m032.h
include/media/i2c/smiapp.h
include/media/i2c/ths7303.h
include/media/i2c/tvp514x.h
include/media/i2c/tvp7002.h
include/media/i2c/upd64031a.h
include/media/i2c/upd64083.h
include/media/media-device.h
include/media/media-devnode.h
include/media/media-entity.h
include/media/rc-core.h
include/media/rc-map.h
include/media/v4l2-event.h
include/media/v4l2-fh.h
include/media/v4l2-subdev.h

index b65674da43bb596b81dd4d29792774e0630bfe9d..8be1fd3760e038738d5a78cf04db330bc9b86b14 100644 (file)
@@ -62,18 +62,18 @@ Description:
                This value may be reset to 0 if the current protocol is altered.
 
 What:          /sys/class/rc/rcN/wakeup_protocols
-Date:          Feb 2014
-KernelVersion: 3.15
+Date:          Feb 2017
+KernelVersion: 4.11
 Contact:       Mauro Carvalho Chehab <m.chehab@samsung.com>
 Description:
                Reading this file returns a list of available protocols to use
                for the wakeup filter, something like:
-                   "rc5 rc6 nec jvc [sony]"
+                   "rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce"
+               Note that protocol variants are listed, so "nec", "sony",
+               "rc-5", "rc-6" have their different bit length encodings
+               listed if available.
                The enabled wakeup protocol is shown in [] brackets.
-               Writing "+proto" will add a protocol to the list of enabled
-               wakeup protocols.
-               Writing "-proto" will remove a protocol from the list of enabled
-               wakeup protocols.
+               Only one protocol can be selected at a time.
                Writing "proto" will use "proto" for wakeup events.
                Writing "none" will disable wakeup.
                Write fails with EINVAL if an invalid protocol combination or
diff --git a/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt b/Documentation/devicetree/bindings/leds/irled/spi-ir-led.txt
new file mode 100644 (file)
index 0000000..896b699
--- /dev/null
@@ -0,0 +1,29 @@
+Device tree bindings for IR LED connected through SPI bus which is used as
+remote controller.
+
+The IR LED switch is connected to the MOSI line of the SPI device and the data
+are delivered thourgh that.
+
+Required properties:
+       - compatible: should be "ir-spi-led".
+
+Optional properties:
+       - duty-cycle: 8 bit balue that represents the percentage of one period
+         in which the signal is active.  It can be 50, 60, 70, 75, 80 or 90.
+       - led-active-low: boolean value that specifies whether the output is
+         negated with a NOT gate.
+       - power-supply: specifies the power source. It can either be a regulator
+         or a gpio which enables a regulator, i.e. a regulator-fixed as
+         described in
+         Documentation/devicetree/bindings/regulator/fixed-regulator.txt
+
+Example:
+
+       irled@0 {
+               compatible = "ir-spi-led";
+               reg = <0x0>;
+               spi-max-frequency = <5000000>;
+               power-supply = <&vdd_led>;
+               led-active-low;
+               duty-cycle = /bits/ 8 <60>;
+       };
diff --git a/Documentation/devicetree/bindings/media/fsl-vdoa.txt b/Documentation/devicetree/bindings/media/fsl-vdoa.txt
new file mode 100644 (file)
index 0000000..6c56285
--- /dev/null
@@ -0,0 +1,21 @@
+Freescale Video Data Order Adapter
+==================================
+
+The Video Data Order Adapter (VDOA) is present on the i.MX6q. Its sole purpose
+is to reorder video data from the macroblock tiled order produced by the CODA
+960 VPU to the conventional raster-scan order for scanout.
+
+Required properties:
+- compatible: must be "fsl,imx6q-vdoa"
+- reg: the register base and size for the device registers
+- interrupts: the VDOA interrupt
+- clocks: the vdoa clock
+
+Example:
+
+vdoa@21e4000 {
+        compatible = "fsl,imx6q-vdoa";
+        reg = <0x021e4000 0x4000>;
+        interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6QDL_CLK_VDOA>;
+};
index 56e726ef4bf26f0faa561e5f5aec663d7def9a1c..58261fb7b408981d709832eadf9c28282a67a822 100644 (file)
@@ -5,7 +5,8 @@ Required properties:
        - gpios: specifies GPIO used for IR signal reception.
 
 Optional properties:
-       - linux,rc-map-name: Linux specific remote control map name.
+       - linux,rc-map-name: see rc.txt file in the same
+         directory.
 
 Example node:
 
index 54e1bede6244f4981b3cdec70ec58dd765cc3e2d..13ebc0fac9ea2faaae8b19b75e494ffa0950ede4 100644 (file)
@@ -10,7 +10,7 @@ Required properties:
        - clocks: clock phandle and specifier pair.
 
 Optional properties:
-       - linux,rc-map-name : Remote control map name.
+       - linux,rc-map-name: see rc.txt file in the same directory.
        - hisilicon,power-syscon: DEPRECATED. Don't use this in new dts files.
                Provide correct clocks instead.
 
diff --git a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
new file mode 100644 (file)
index 0000000..0b7b6a4
--- /dev/null
@@ -0,0 +1,48 @@
+Toshiba et8ek8 5MP sensor
+
+Toshiba et8ek8 5MP sensor is an image sensor found in Nokia N900 device
+
+More detailed documentation can be found in
+Documentation/devicetree/bindings/media/video-interfaces.txt .
+
+
+Mandatory properties
+--------------------
+
+- compatible: "toshiba,et8ek8"
+- reg: I2C address (0x3e, or an alternative address)
+- vana-supply: Analogue voltage supply (VANA), 2.8 volts
+- clocks: External clock to the sensor
+- clock-frequency: Frequency of the external clock to the sensor. Camera
+  driver will set this frequency on the external clock. The clock frequency is
+  a pre-determined frequency known to be suitable to the board.
+- reset-gpios: XSHUTDOWN GPIO. The XSHUTDOWN signal is active low. The sensor
+  is in hardware standby mode when the signal is in the low state.
+
+
+Endpoint node mandatory properties
+----------------------------------
+
+- remote-endpoint: A phandle to the bus receiver's endpoint node.
+
+
+Example
+-------
+
+&i2c3 {
+       clock-frequency = <400000>;
+
+       cam1: camera@3e {
+               compatible = "toshiba,et8ek8";
+               reg = <0x3e>;
+               vana-supply = <&vaux4>;
+               clocks = <&isp 0>;
+               clock-frequency = <9600000>;
+               reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
+               port {
+                       csi_cam1: endpoint {
+                               remote-endpoint = <&csi_out1>;
+                       };
+               };
+       };
+};
index e7e3f3c4fc8f697d9fc5c0b9917cb89cff2198ab..efd9d29a8f103f3003dffd82c84df1eb1d614973 100644 (file)
@@ -8,6 +8,9 @@ Required properties:
  - reg         : physical base address and length of the device registers
  - interrupts  : a single specifier for the interrupt from the device
 
+Optional properties:
+ - linux,rc-map-name:  see rc.txt file in the same directory.
+
 Example:
 
        ir-receiver@c8100480 {
diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt
new file mode 100644 (file)
index 0000000..2be2005
--- /dev/null
@@ -0,0 +1,24 @@
+Device-Tree bindings for Mediatek consumer IR controller
+found in Mediatek SoC family
+
+Required properties:
+- compatible       : "mediatek,mt7623-cir"
+- clocks           : list of clock specifiers, corresponding to
+                     entries in clock-names property;
+- clock-names      : should contain "clk" entries;
+- interrupts       : should contain IR IRQ number;
+- reg              : should contain IO map address for IR.
+
+Optional properties:
+- linux,rc-map-name : see rc.txt file in the same directory.
+
+Example:
+
+cir: cir@10013000 {
+       compatible = "mediatek,mt7623-cir";
+       reg = <0 0x10013000 0 0x1000>;
+       interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
+       clocks = <&infracfg CLK_INFRA_IRRX>;
+       clock-names = "clk";
+       linux,rc-map-name = "rc-rc6-mce";
+};
diff --git a/Documentation/devicetree/bindings/media/rc.txt b/Documentation/devicetree/bindings/media/rc.txt
new file mode 100644 (file)
index 0000000..d3e7a01
--- /dev/null
@@ -0,0 +1,117 @@
+The following properties are common to the infrared remote controllers:
+
+- linux,rc-map-name: string, specifies the scancode/key mapping table
+  defined in-kernel for the remote controller. Support values are:
+  * "rc-adstech-dvb-t-pci"
+  * "rc-alink-dtu-m"
+  * "rc-anysee"
+  * "rc-apac-viewcomp"
+  * "rc-asus-pc39"
+  * "rc-asus-ps3-100"
+  * "rc-ati-tv-wonder-hd-600"
+  * "rc-ati-x10"
+  * "rc-avermedia-a16d"
+  * "rc-avermedia-cardbus"
+  * "rc-avermedia-dvbt"
+  * "rc-avermedia-m135a"
+  * "rc-avermedia-m733a-rm-k6"
+  * "rc-avermedia-rm-ks"
+  * "rc-avermedia"
+  * "rc-avertv-303"
+  * "rc-azurewave-ad-tu700"
+  * "rc-behold-columbus"
+  * "rc-behold"
+  * "rc-budget-ci-old"
+  * "rc-cec"
+  * "rc-cinergy-1400"
+  * "rc-cinergy"
+  * "rc-delock-61959"
+  * "rc-dib0700-nec"
+  * "rc-dib0700-rc5"
+  * "rc-digitalnow-tinytwin"
+  * "rc-digittrade"
+  * "rc-dm1105-nec"
+  * "rc-dntv-live-dvbt-pro"
+  * "rc-dntv-live-dvb-t"
+  * "rc-dtt200u"
+  * "rc-dvbsky"
+  * "rc-empty"
+  * "rc-em-terratec"
+  * "rc-encore-enltv2"
+  * "rc-encore-enltv-fm53"
+  * "rc-encore-enltv"
+  * "rc-evga-indtube"
+  * "rc-eztv"
+  * "rc-flydvb"
+  * "rc-flyvideo"
+  * "rc-fusionhdtv-mce"
+  * "rc-gadmei-rm008z"
+  * "rc-geekbox"
+  * "rc-genius-tvgo-a11mce"
+  * "rc-gotview7135"
+  * "rc-hauppauge"
+  * "rc-imon-mce"
+  * "rc-imon-pad"
+  * "rc-iodata-bctv7e"
+  * "rc-it913x-v1"
+  * "rc-it913x-v2"
+  * "rc-kaiomy"
+  * "rc-kworld-315u"
+  * "rc-kworld-pc150u"
+  * "rc-kworld-plus-tv-analog"
+  * "rc-leadtek-y04g0051"
+  * "rc-lirc"
+  * "rc-lme2510"
+  * "rc-manli"
+  * "rc-medion-x10"
+  * "rc-medion-x10-digitainer"
+  * "rc-medion-x10-or2x"
+  * "rc-msi-digivox-ii"
+  * "rc-msi-digivox-iii"
+  * "rc-msi-tvanywhere-plus"
+  * "rc-msi-tvanywhere"
+  * "rc-nebula"
+  * "rc-nec-terratec-cinergy-xs"
+  * "rc-norwood"
+  * "rc-npgtech"
+  * "rc-pctv-sedna"
+  * "rc-pinnacle-color"
+  * "rc-pinnacle-grey"
+  * "rc-pinnacle-pctv-hd"
+  * "rc-pixelview-new"
+  * "rc-pixelview"
+  * "rc-pixelview-002t"
+  * "rc-pixelview-mk12"
+  * "rc-powercolor-real-angel"
+  * "rc-proteus-2309"
+  * "rc-purpletv"
+  * "rc-pv951"
+  * "rc-hauppauge"
+  * "rc-rc5-tv"
+  * "rc-rc6-mce"
+  * "rc-real-audio-220-32-keys"
+  * "rc-reddo"
+  * "rc-snapstream-firefly"
+  * "rc-streamzap"
+  * "rc-tbs-nec"
+  * "rc-technisat-ts35"
+  * "rc-technisat-usb2"
+  * "rc-terratec-cinergy-c-pci"
+  * "rc-terratec-cinergy-s2-hd"
+  * "rc-terratec-cinergy-xs"
+  * "rc-terratec-slim"
+  * "rc-terratec-slim-2"
+  * "rc-tevii-nec"
+  * "rc-tivo"
+  * "rc-total-media-in-hand"
+  * "rc-total-media-in-hand-02"
+  * "rc-trekstor"
+  * "rc-tt-1500"
+  * "rc-twinhan-dtv-cab-ci"
+  * "rc-twinhan1027"
+  * "rc-videomate-k100"
+  * "rc-videomate-s350"
+  * "rc-videomate-tv-pvr"
+  * "rc-winfast"
+  * "rc-winfast-usbii-deluxe"
+  * "rc-su3000"
diff --git a/Documentation/devicetree/bindings/media/st,st-delta.txt b/Documentation/devicetree/bindings/media/st,st-delta.txt
new file mode 100644 (file)
index 0000000..a538ab3
--- /dev/null
@@ -0,0 +1,17 @@
+* STMicroelectronics DELTA multi-format video decoder
+
+Required properties:
+- compatible: should be "st,st-delta".
+- clocks: from common clock binding: handle hardware IP needed clocks, the
+  number of clocks may depend on the SoC type.
+  See ../clock/clock-bindings.txt for details.
+- clock-names: names of the clocks listed in clocks property in the same order.
+
+Example:
+       delta0 {
+               compatible = "st,st-delta";
+               clock-names = "delta", "delta-st231", "delta-flash-promip";
+               clocks = <&clk_s_c0_flexgen CLK_VID_DMU>,
+                        <&clk_s_c0_flexgen CLK_ST231_DMU>,
+                        <&clk_s_c0_flexgen CLK_FLASH_PROMIP>;
+       };
index 1811a067c72cc8b21267298ec4892dd136ebf7bd..302a0b183cb883245c0804e1effa878cf4d11139 100644 (file)
@@ -9,7 +9,7 @@ Required properties:
 - reg              : should contain IO map address for IR.
 
 Optional properties:
-- linux,rc-map-name : Remote control map name.
+- linux,rc-map-name: see rc.txt file in the same directory.
 - resets : phandle + reset specifier pair
 
 Example:
diff --git a/Documentation/devicetree/bindings/media/ti,da850-vpif.txt b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt
new file mode 100644 (file)
index 0000000..6d25d7f
--- /dev/null
@@ -0,0 +1,83 @@
+Texas Instruments VPIF
+----------------------
+
+The TI Video Port InterFace (VPIF) is the primary component for video
+capture and display on the DA850/AM18x family of TI DaVinci/Sitara
+SoCs.
+
+TI Document reference: SPRUH82C, Chapter 35
+http://www.ti.com/lit/pdf/spruh82
+
+Required properties:
+- compatible: must be "ti,da850-vpif"
+- reg: physical base address and length of the registers set for the device;
+- interrupts: should contain IRQ line for the VPIF
+
+Video Capture:
+
+VPIF has a 16-bit parallel bus input, supporting 2 8-bit channels or a
+single 16-bit channel.  It should contain at least one port child node
+with child 'endpoint' node. Please refer to the bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example using 2 8-bit input channels, one of which is connected to an
+I2C-connected TVP5147 decoder:
+
+       vpif: vpif@217000 {
+               compatible = "ti,da850-vpif";
+               reg = <0x217000 0x1000>;
+               interrupts = <92>;
+
+               port {
+                       vpif_ch0: endpoint@0 {
+                                 reg = <0>;
+                                 bus-width = <8>;
+                                 remote-endpoint = <&composite>;
+                       };
+
+                       vpif_ch1: endpoint@1 {
+                                 reg = <1>;
+                                 bus-width = <8>;
+                                 data-shift = <8>;
+                       };
+               };
+       };
+
+[ ... ]
+
+&i2c0 {
+
+       tvp5147@5d {
+               compatible = "ti,tvp5147";
+               reg = <0x5d>;
+               status = "okay";
+
+               port {
+                       composite: endpoint {
+                               hsync-active = <1>;
+                               vsync-active = <1>;
+                               pclk-sample = <0>;
+
+                               /* VPIF channel 0 (lower 8-bits) */
+                               remote-endpoint = <&vpif_ch0>;
+                               bus-width = <8>;
+                       };
+               };
+       };
+};
+
+
+Alternatively, an example when the bus is configured as a single
+16-bit input (e.g. for raw-capture mode):
+
+       vpif: vpif@217000 {
+               compatible = "ti,da850-vpif";
+               reg = <0x217000 0x1000>;
+               interrupts = <92>;
+
+               port {
+                       vpif_ch0: endpoint {
+                                 bus-width = <16>;
+                       };
+               };
+       };
index 1a738e5f6056cc7ec8225eb31dbd2f99e36301af..0c05503eaf1fa6c7c0a109cfac1460cc0c4afe2b 100644 (file)
@@ -162,13 +162,13 @@ framework provides a depth-first graph traversal API for that purpose.
    currently defined as 16.
 
 Drivers initiate a graph traversal by calling
-:c:func:`media_entity_graph_walk_start()`
+:c:func:`media_graph_walk_start()`
 
 The graph structure, provided by the caller, is initialized to start graph
 traversal at the given entity.
 
 Drivers can then retrieve the next entity by calling
-:c:func:`media_entity_graph_walk_next()`
+:c:func:`media_graph_walk_next()`
 
 When the graph traversal is complete the function will return ``NULL``.
 
@@ -206,7 +206,7 @@ Pipelines and media streams
 
 When starting streaming, drivers must notify all entities in the pipeline to
 prevent link states from being modified during streaming by calling
-:c:func:`media_entity_pipeline_start()`.
+:c:func:`media_pipeline_start()`.
 
 The function will mark all entities connected to the given entity through
 enabled links, either directly or indirectly, as streaming.
@@ -218,17 +218,17 @@ in higher-level pipeline structures and can then access the
 pipeline through the struct :c:type:`media_entity`
 pipe field.
 
-Calls to :c:func:`media_entity_pipeline_start()` can be nested.
+Calls to :c:func:`media_pipeline_start()` can be nested.
 The pipeline pointer must be identical for all nested calls to the function.
 
-:c:func:`media_entity_pipeline_start()` may return an error. In that case,
+:c:func:`media_pipeline_start()` may return an error. In that case,
 it will clean up any of the changes it did by itself.
 
 When stopping the stream, drivers must notify the entities with
-:c:func:`media_entity_pipeline_stop()`.
+:c:func:`media_pipeline_stop()`.
 
-If multiple calls to :c:func:`media_entity_pipeline_start()` have been
-made the same number of :c:func:`media_entity_pipeline_stop()` calls
+If multiple calls to :c:func:`media_pipeline_start()` have been
+made the same number of :c:func:`media_pipeline_stop()` calls
 are required to stop streaming.
 The :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
 nested stop call.
@@ -245,7 +245,7 @@ operation must be done with the media_device graph_mutex held.
 Link validation
 ^^^^^^^^^^^^^^^
 
-Link validation is performed by :c:func:`media_entity_pipeline_start()`
+Link validation is performed by :c:func:`media_pipeline_start()`
 for any entity which has sink pads in the pipeline. The
 :c:type:`media_entity`.\ ``link_validate()`` callback is used for that
 purpose. In ``link_validate()`` callback, entity driver should check
index 6e983b9880fce2df7112e7f3b14365057a6db3da..d39e34d1b19dd09e3e994927341294c52dc688b1 100644 (file)
@@ -94,9 +94,17 @@ Generic Error Codes
        -  Permission denied. Can be returned if the device needs write
          permission, or some special capabilities is needed (e. g. root)
 
+    -  .. row 11
+
+       -  ``EIO``
+
+       -  I/O error. Typically used when there are problems communicating with
+          a hardware device. This could indicate broken or flaky hardware.
+         It's a 'Something is wrong, I give up!' type of error.
+
 .. note::
 
-  #. This list is not exaustive; ioctls may return other error codes.
+  #. This list is not exhaustive; ioctls may return other error codes.
      Since errors may have side effects such as a driver reset,
      applications should abort on unexpected errors, or otherwise
      assume that the device is in a bad state.
index 6fb944fe21fdb49e4c8b72887e759a557f03b749..3476ae29708f7e4068bbb5166c5d6ee66ef29e16 100644 (file)
@@ -92,15 +92,16 @@ This value may be reset to 0 if the current protocol is altered.
 Reading this file returns a list of available protocols to use for the
 wakeup filter, something like:
 
-``rc5 rc6 nec jvc [sony]``
+``rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce``
 
-The enabled wakeup protocol is shown in [] brackets.
+Note that protocol variants are listed, so "nec", "sony", "rc-5", "rc-6"
+have their different bit length encodings listed if available.
 
-Writing "+proto" will add a protocol to the list of enabled wakeup
-protocols.
+Note that all protocol variants are listed.
 
-Writing "-proto" will remove a protocol from the list of enabled wakeup
-protocols.
+The enabled wakeup protocol is shown in [] brackets.
+
+Only one protocol can be selected at a time.
 
 Writing "proto" will use "proto" for wakeup events.
 
index 0e542ed67e0a3eee9b849192c1ff8fd96667f677..2f9f345a15b77f03f0a81c7ef61db9701a7c6bfd 100644 (file)
@@ -2423,6 +2423,14 @@ W:       https://linuxtv.org
 S:     Supported
 F:     drivers/media/platform/sti/bdisp
 
+DELTA ST MEDIA DRIVER
+M:     Hugues Fruchet <hugues.fruchet@st.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+W:     https://linuxtv.org
+S:     Supported
+F:     drivers/media/platform/sti/delta
+
 BEFS FILE SYSTEM
 M:     Luis de Bethencourt <luisbg@osg.samsung.com>
 M:     Salah Triki <salah.triki@gmail.com>
@@ -5738,16 +5746,6 @@ L:       linux-parisc@vger.kernel.org
 S:     Maintained
 F:     sound/parisc/harmony.*
 
-HD29L2 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
-L:     linux-media@vger.kernel.org
-W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
-Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
-S:     Maintained
-F:     drivers/media/dvb-frontends/hd29l2*
-
 HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
 M:     Jimmy Vance <jimmy.vance@hpe.com>
 S:     Supported
@@ -8825,6 +8823,22 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/lftan/nios2.git
 S:     Maintained
 F:     arch/nios2/
 
+NOKIA N900 CAMERA SUPPORT (ET8EK8 SENSOR, AD5820 FOCUS)
+M:     Pavel Machek <pavel@ucw.cz>
+M:     Sakari Ailus <sakari.ailus@iki.fi>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/media/i2c/et8ek8
+F:     drivers/media/i2c/ad5820.c
+
+NOKIA N900 CAMERA SUPPORT (ET8EK8 SENSOR, AD5820 FOCUS)
+M:     Pavel Machek <pavel@ucw.cz>
+M:     Sakari Ailus <sakari.ailus@iki.fi>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/media/i2c/et8ek8
+F:     drivers/media/i2c/ad5820.c
+
 NOKIA N900 POWER SUPPLY DRIVERS
 R:     Pali Rohár <pali.rohar@gmail.com>
 F:     include/linux/power/bq2415x_charger.h
@@ -13660,6 +13674,24 @@ L:     zd1211-devs@lists.sourceforge.net (subscribers-only)
 S:     Maintained
 F:     drivers/net/wireless/zydas/zd1211rw/
 
+ZD1301_DEMOD MEDIA DRIVER
+M:     Antti Palosaari <crope@iki.fi>
+L:     linux-media@vger.kernel.org
+W:     https://linuxtv.org/
+W:     http://palosaari.fi/linux/
+Q:     https://patchwork.linuxtv.org/project/linux-media/list/
+S:     Maintained
+F:     drivers/media/dvb-frontends/zd1301_demod*
+
+ZD1301 MEDIA DRIVER
+M:     Antti Palosaari <crope@iki.fi>
+L:     linux-media@vger.kernel.org
+W:     https://linuxtv.org/
+W:     http://palosaari.fi/linux/
+Q:     https://patchwork.linuxtv.org/project/linux-media/list/
+S:     Maintained
+F:     drivers/media/usb/dvb-usb-v2/zd1301*
+
 ZPOOL COMPRESSED PAGE STORAGE API
 M:     Dan Streetman <ddstreet@ieee.org>
 L:     linux-mm@kvack.org
index e7d30f45b161ebb09f9d904f690638ec46c20ce7..6d37d9af5f1d79f1c972bb4e541626b0d92c6973 100644 (file)
                        };
 
                        vdoa@021e4000 {
+                               compatible = "fsl,imx6q-vdoa";
                                reg = <0x021e4000 0x4000>;
                                interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6QDL_CLK_VDOA>;
                        };
 
                        uart2: serial@021e8000 {
index ace97e8576dbd9ae34d112b4aa8ec991647134e5..4c72dae2aefa00378e4dea9e72bc6004091bf09c 100644 (file)
 
                        status = "disabled";
                };
+
+               delta0 {
+                       compatible = "st,st-delta";
+                       clock-names = "delta",
+                                     "delta-st231",
+                                     "delta-flash-promip";
+                       clocks = <&clk_s_c0_flexgen CLK_VID_DMU>,
+                                <&clk_s_c0_flexgen CLK_ST231_DMU>,
+                                <&clk_s_c0_flexgen CLK_FLASH_PROMIP>;
+               };
        };
 };
index 2e7a63f35bd33fd0e0932b286e7d7a423a25a3e8..affffa7c415b327b6cb6c0930d241b5e742cd133 100644 (file)
@@ -569,6 +569,7 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_VIDEO_STI_BDISP=m
 CONFIG_VIDEO_STI_HVA=m
+CONFIG_VIDEO_STI_DELTA=m
 CONFIG_VIDEO_RENESAS_JPU=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_V4L_TEST_DRIVERS=y
index 70c004794880e0efd567e269eebc0f7484ca5140..67498aad2654f39698c1dbb244a1aded8d321e84 100644 (file)
@@ -484,15 +484,15 @@ static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
 };
 #endif
 
-static struct lirc_rx51_platform_data __maybe_unused rx51_lirc_data = {
+static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
        .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
 };
 
-static struct platform_device __maybe_unused rx51_lirc_device = {
-       .name           = "lirc_rx51",
+static struct platform_device __maybe_unused rx51_ir_device = {
+       .name           = "ir_rx51",
        .id             = -1,
        .dev            = {
-               .platform_data = &rx51_lirc_data,
+               .platform_data = &rx51_ir_data,
        },
 };
 
@@ -533,7 +533,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
                       &omap3_iommu_pdata),
        OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x4809c000, "4809c000.mmc", &mmc_pdata[0]),
        OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x480b4000, "480b4000.mmc", &mmc_pdata[1]),
-       OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_lirc_data),
+       OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_ir_data),
        /* Only on am3517 */
        OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
        OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
index 96286510f42e990eef1a0fd6a03abfd57fd42f57..8ffbb6f65a65a4befda7b2a1257400cab31c6e8b 100644 (file)
@@ -108,13 +108,12 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
        struct rc_dev *rdev;
        int ret = 0;
 
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rdev)
                return -ENOMEM;
 
        rdev->priv             = data;
-       rdev->driver_type      = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rdev->open             = picolcd_cir_open;
        rdev->close            = picolcd_cir_close;
        rdev->input_name       = data->hdev->name;
index aca3ab83a8a142af696443857dcc1a8882689ac6..37217e205040e6748b5b8f7d955063d213ec94e6 100644 (file)
@@ -239,7 +239,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
 
 #if IS_REACHABLE(CONFIG_RC_CORE)
        /* Prepare the RC input device */
-       adap->rc = rc_allocate_device();
+       adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!adap->rc) {
                pr_err("cec-%s: failed to allocate memory for rc_dev\n",
                       name);
@@ -259,7 +259,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
        adap->rc->input_id.vendor = 0;
        adap->rc->input_id.product = 0;
        adap->rc->input_id.version = 1;
-       adap->rc->driver_type = RC_DRIVER_SCANCODE;
        adap->rc->driver_name = CEC_NAME;
        adap->rc->allowed_protocols = RC_BIT_CEC;
        adap->rc->priv = adap;
index f5956402fc69dfcd88c9870abe5ea76e3d6e6d65..5f10151ecec94cf3b3dead5091fb01707998a504 100644 (file)
@@ -24,8 +24,7 @@
 
 /* Can we use the specified front-end?  Remember that if we are compiled
  * into the kernel we can't call code that's in modules.  */
-#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
-       (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
+#define FE_SUPPORTED(fe) IS_REACHABLE(CONFIG_DVB_ ## fe)
 
 #if FE_SUPPORTED(BCM3510) || (FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421))
 static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
index 4338ab0043b4f73f6bb2731a42579a99f84d0094..2e0ab55cd67e1b8381fe7a0d4683a99d6aafac8d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include "flexcop.h"
index 2725702eda7b97bccda06dd3768023a62b3392a7..81dce9a81bd30aa2fbbe83147da8de44630782c5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index ca2f80c7740cd62baa90ff8511a07a02015b55f7..af6b2268db61dadd92a3e3ebd33d1c6c46f99716 100644 (file)
  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  *
  *  See the GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "sms-cards.h"
index bb3d733f092b5b79b0ac69181095fcb3ac689d39..e6264b4797b481b957f97b8ac655448a84a75313 100644 (file)
  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  *
  *  See the GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __SMS_CARDS_H__
index f3a42834d7d61e34f865420befaa63ad639775a2..e7a0d7798d5b249197b9e21cd0ae6f2066162d20 100644 (file)
  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  *
  *  See the GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "smscoreapi.h"
index 41f2a39399792e55fb6217163a6906ad66837229..7c898b06d85c33ddcb92cfce60b22e7208e8b343 100644 (file)
@@ -58,7 +58,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
        struct rc_dev *dev;
 
        pr_debug("Allocating rc device\n");
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!dev)
                return -ENOMEM;
 
@@ -86,8 +86,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
 #endif
 
        dev->priv = coredev;
-       dev->driver_type = RC_DRIVER_IR_RAW;
-       dev->allowed_protocols = RC_BIT_ALL;
+       dev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        dev->map_name = sms_get_board(board_id)->rc_codes;
        dev->driver_name = MODULE_NAME;
 
index 11976031aff8df36763844b4844d7795c06efca0..6e1020227f9fe7d5f4843902509b6b3e845b01f5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index f8adf4506a45134796bb2139e772c599e52454dd..f854309ba8a5a385d9eec0fd9fca5e10f5177b9a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #ifndef __DEMUX_H
index 0c16bb21310109050f461979306408f7ca42866b..45e91add73ba003bafb78584f4c04f708daa4152 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #define pr_fmt(fmt) "dmxdev: " fmt
@@ -151,6 +147,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 
        if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
                void *mem;
+
                if (!dvbdev->readers) {
                        mutex_unlock(&dmxdev->mutex);
                        return -EBUSY;
@@ -202,6 +199,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
                dvbdev->readers++;
                if (dmxdev->dvr_buffer.data) {
                        void *mem = dmxdev->dvr_buffer.data;
+                       /*memory barrier*/
                        mb();
                        spin_lock_irq(&dmxdev->lock);
                        dmxdev->dvr_buffer.data = NULL;
@@ -876,7 +874,7 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
        dvb_dmxdev_filter_stop(dmxdevfilter);
        dvb_dmxdev_filter_reset(dmxdevfilter);
 
-       if ((unsigned)params->pes_type > DMX_PES_OTHER)
+       if ((unsigned int)params->pes_type > DMX_PES_OTHER)
                return -EINVAL;
 
        dmxdevfilter->type = DMXDEV_TYPE_PES;
@@ -1125,7 +1123,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
 
        mutex_lock(&dmxdev->mutex);
        dmxdev->dvbdev->users--;
-       if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
+       if (dmxdev->dvbdev->users == 1 && dmxdev->exit == 1) {
                mutex_unlock(&dmxdev->mutex);
                wake_up(&dmxdev->dvbdev->wait_queue);
        } else
@@ -1263,14 +1261,14 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
 
 void dvb_dmxdev_release(struct dmxdev *dmxdev)
 {
-       dmxdev->exit=1;
+       dmxdev->exit = 1;
        if (dmxdev->dvbdev->users > 1) {
                wait_event(dmxdev->dvbdev->wait_queue,
-                               dmxdev->dvbdev->users==1);
+                               dmxdev->dvbdev->users == 1);
        }
        if (dmxdev->dvr_dvbdev->users > 1) {
                wait_event(dmxdev->dvr_dvbdev->wait_queue,
-                               dmxdev->dvr_dvbdev->users==1);
+                               dmxdev->dvr_dvbdev->users == 1);
        }
 
        dvb_unregister_device(dmxdev->dvbdev);
index 48c6cf92ab994c896d9e0f2d155e532c0aa5c500..054fd4eb6192f6048573f6c6dbd1e7d8fdc2f019 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #ifndef _DMXDEV_H_
index 779f4224b63e4f69b46c93a8db31ae010d6d6001..e200aa6f2d2f30782317d4b6f3ab9e71e3c0c9fd 100644 (file)
 #define USB_VID_GIGABYTE                       0x1044
 #define USB_VID_YUAN                           0x1164
 #define USB_VID_XTENSIONS                      0x1ae7
+#define USB_VID_ZYDAS                          0x0ace
 #define USB_VID_HUMAX_COEX                     0x10b9
 #define USB_VID_774                            0x7a69
 #define USB_VID_EVOLUTEPC                      0x1e59
 #define USB_VID_AZUREWAVE                      0x13d3
 #define USB_VID_TECHNISAT                      0x14f7
+#define USB_VID_HAMA                           0x147f
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD                      0xa333
 #define USB_PID_SVEON_STV27                             0xd3af
 #define USB_PID_TURBOX_DTT_2000                         0xd3a4
 #define USB_PID_WINTV_SOLOHD                            0x0264
-#define USB_PID_EVOLVEO_XTRATV_STICK                   0xa115
+#define USB_PID_EVOLVEO_XTRATV_STICK                   0xa115
+#define USB_PID_HAMA_DVBT_HYBRID                       0x2758
 #endif
index fd893141211c49d699fc0c30da01a7eaaa417ba3..000d737ad8271fcd6596e1206c958d9f3b1dde45 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #define pr_fmt(fmt) "dvb_ca_en50221: " fmt
index bbbff72bbb2af53c2fe255b7e0bc2836558edeed..4eac71e50c5f953a8ee738992b5b0c9de83454e2 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #define pr_fmt(fmt) "dvb_demux: " fmt
index 9235b008ea0ab4db1a539bdce137044a0382a4f7..6f572ca8d3393fd4731a10c5d69ffe66026a2e6e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #ifndef _DVB_DEMUX_H_
index db74cb74d271b23d7566b82ab51e50d819a3d2db..85ae3669aa668baa656ed396ddb4913583e48777 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 /* Enables DVBv3 compatibility bits at the headers */
@@ -2536,9 +2533,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
                fepriv->voltage = -1;
 
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
-               if (fe->dvb->mdev && fe->dvb->mdev->enable_source) {
-                       ret = fe->dvb->mdev->enable_source(dvbdev->entity,
+               if (fe->dvb->mdev) {
+                       mutex_lock(&fe->dvb->mdev->graph_mutex);
+                       if (fe->dvb->mdev->enable_source)
+                               ret = fe->dvb->mdev->enable_source(
+                                                          dvbdev->entity,
                                                           &fepriv->pipe);
+                       mutex_unlock(&fe->dvb->mdev->graph_mutex);
                        if (ret) {
                                dev_err(fe->dvb->device,
                                        "Tuner is busy. Error %d\n", ret);
@@ -2562,8 +2563,12 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
 err3:
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
-       if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
-               fe->dvb->mdev->disable_source(dvbdev->entity);
+       if (fe->dvb->mdev) {
+               mutex_lock(&fe->dvb->mdev->graph_mutex);
+               if (fe->dvb->mdev->disable_source)
+                       fe->dvb->mdev->disable_source(dvbdev->entity);
+               mutex_unlock(&fe->dvb->mdev->graph_mutex);
+       }
 err2:
 #endif
        dvb_generic_release(inode, file);
@@ -2595,8 +2600,12 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
        if (dvbdev->users == -1) {
                wake_up(&fepriv->wait_queue);
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
-               if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
-                       fe->dvb->mdev->disable_source(dvbdev->entity);
+               if (fe->dvb->mdev) {
+                       mutex_lock(&fe->dvb->mdev->graph_mutex);
+                       if (fe->dvb->mdev->disable_source)
+                               fe->dvb->mdev->disable_source(dvbdev->entity);
+                       mutex_unlock(&fe->dvb->mdev->graph_mutex);
+               }
 #endif
                if (fe->exit != DVB_FE_NO_EXIT)
                        wake_up(&dvbdev->wait_queue);
index beb7c93aa6cb3ab8da7bf714ff49aad9983ac1a5..a2e1810dd83a7245c0d121fbb54ed99913a92418 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/bitops.h>
index 4d11d3529c143f5ad33bb93096fc75dd280c3087..8690ec42954d03bae4b2c65871c887bc26a1ee79 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #ifndef __DVB_MATH_H
index 8f11d7e459931bb5a8ed74569781dc83d4bd6422..9947b342633eec756ef64cfcd6b81d643105d5e5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 /*
index ede78e8c8aa8ccf5783fea84663ea48f2c8f25be..e9b18aa03e02e600d1834e9fdc5ea4ee5afc9e72 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #ifndef _DVB_NET_H_
index 5c4b5a1f604f439562385a6f83609edec4579b9d..2322af1b87429aab67454c4ca7f7f486ab9bf211 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
 
index 38c844667789361d1385f6609b30fedade294bcd..41aad0f99d73c43fe1ab997e4fad93df6ba2b9ec 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #define pr_fmt(fmt) "dvbdev: " fmt
index 8c0a7b51555e4e7faa0d2919991592352d086426..49189392cf3b9c22907ff9ff17c610a4b86a4ff3 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  */
 
 #ifndef _DVBDEV_H_
index c841fa1770bec376559d3292f262b41b3a78d5bb..e8c6554a47aa13761ca8016cb0cd7d066e38927a 100644 (file)
@@ -447,13 +447,6 @@ config DVB_EC100
        help
          Say Y when you want to support this frontend.
 
-config DVB_HD29L2
-       tristate "HDIC HD29L2"
-       depends on DVB_CORE && I2C
-       default m if !MEDIA_SUBDRV_AUTOSELECT
-       help
-         Say Y when you want to support this frontend.
-
 config DVB_STV0367
        tristate "ST STV0367 based"
        depends on DVB_CORE && I2C
@@ -513,6 +506,13 @@ config DVB_AS102_FE
        depends on DVB_CORE
        default DVB_AS102
 
+config DVB_ZD1301_DEMOD
+       tristate "ZyDAS ZD1301"
+       depends on DVB_CORE && I2C
+       default m if !MEDIA_SUBDRV_AUTOSELECT
+       help
+         Say Y when you want to support this frontend.
+
 config DVB_GP8PSK_FE
        tristate
        depends on DVB_CORE
@@ -619,7 +619,7 @@ config DVB_LGDT3305
 
 config DVB_LGDT3306A
        tristate "LG Electronics LGDT3306A based"
-       depends on DVB_CORE && I2C
+       depends on DVB_CORE && I2C && I2C_MUX
        default m if !MEDIA_SUBDRV_AUTOSELECT
        help
          An ATSC 8VSB and QAM-B 64/256 demodulator module. Say Y when you want
@@ -852,6 +852,7 @@ config DVB_M88RS2000
 config DVB_AF9033
        tristate "Afatech AF9033 DVB-T demodulator"
        depends on DVB_CORE && I2C
+       select REGMAP_I2C
        default m if !MEDIA_SUBDRV_AUTOSELECT
 
 config DVB_HORUS3A
index 93921a4eaa275997a5ed4178de1acb1a54409430..3fccaf34ef520acf4207710dbf15fd7c08cc62fa 100644 (file)
@@ -99,7 +99,6 @@ obj-$(CONFIG_DVB_MN88472) += mn88472.o
 obj-$(CONFIG_DVB_MN88473) += mn88473.o
 obj-$(CONFIG_DVB_ISL6423) += isl6423.o
 obj-$(CONFIG_DVB_EC100) += ec100.o
-obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
 obj-$(CONFIG_DVB_DS3000) += ds3000.o
 obj-$(CONFIG_DVB_TS2020) += ts2020.o
 obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
@@ -126,3 +125,4 @@ obj-$(CONFIG_DVB_TC90522) += tc90522.o
 obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
 obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
 obj-$(CONFIG_DVB_HELENE) += helene.o
+obj-$(CONFIG_DVB_ZD1301_DEMOD) += zd1301_demod.o
index c6cb3bbc912a5b731d366d561ebff46bb8bfa97d..b978002af4d8afc76563e8e73235595a68a09e48 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "af9013_priv.h"
index dcdd163ace8576e71d98e575959b3332227e6ba8..277112863719ed13d9ac7da4d00500d73b016330 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef AF9013_H
index 8b9392cfc00dd13ddfb6d6834bbe370e6b474438..31d6538abfaeb1e35c19bec40a85303c472e3fb1 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef AF9013_PRIV_H
index f8818028752e126ea53fd7399212a2a1698436f4..aaed7cfe5f6660d608084607c8d5d2afa5f1848e 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include "af9033_priv.h"
 
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  64
-
 struct af9033_dev {
        struct i2c_client *client;
+       struct regmap *regmap;
        struct dvb_frontend fe;
        struct af9033_config cfg;
        bool is_af9035;
@@ -43,146 +37,19 @@ struct af9033_dev {
        u64 total_block_count;
 };
 
-/* write multiple registers */
-static int af9033_wr_regs(struct af9033_dev *dev, u32 reg, const u8 *val,
-               int len)
-{
-       int ret;
-       u8 buf[MAX_XFER_SIZE];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = dev->client->addr,
-                       .flags = 0,
-                       .len = 3 + len,
-                       .buf = buf,
-               }
-       };
-
-       if (3 + len > sizeof(buf)) {
-               dev_warn(&dev->client->dev,
-                               "i2c wr reg=%04x: len=%d is too big!\n",
-                               reg, len);
-               return -EINVAL;
-       }
-
-       buf[0] = (reg >> 16) & 0xff;
-       buf[1] = (reg >>  8) & 0xff;
-       buf[2] = (reg >>  0) & 0xff;
-       memcpy(&buf[3], val, len);
-
-       ret = i2c_transfer(dev->client->adapter, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               dev_warn(&dev->client->dev, "i2c wr failed=%d reg=%06x len=%d\n",
-                               ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* read multiple registers */
-static int af9033_rd_regs(struct af9033_dev *dev, u32 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
-                       (reg >> 0) & 0xff };
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = dev->client->addr,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf
-               }, {
-                       .addr = dev->client->addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val
-               }
-       };
-
-       ret = i2c_transfer(dev->client->adapter, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               dev_warn(&dev->client->dev, "i2c rd failed=%d reg=%06x len=%d\n",
-                               ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-
-/* write single register */
-static int af9033_wr_reg(struct af9033_dev *dev, u32 reg, u8 val)
-{
-       return af9033_wr_regs(dev, reg, &val, 1);
-}
-
-/* read single register */
-static int af9033_rd_reg(struct af9033_dev *dev, u32 reg, u8 *val)
-{
-       return af9033_rd_regs(dev, reg, val, 1);
-}
-
-/* write single register with mask */
-static int af9033_wr_reg_mask(struct af9033_dev *dev, u32 reg, u8 val,
-               u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = af9033_rd_regs(dev, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return af9033_wr_regs(dev, reg, &val, 1);
-}
-
-/* read single register with mask */
-static int af9033_rd_reg_mask(struct af9033_dev *dev, u32 reg, u8 *val,
-               u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = af9033_rd_regs(dev, reg, &tmp, 1);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-/* write reg val table using reg addr auto increment */
+/* Write reg val table using reg addr auto increment */
 static int af9033_wr_reg_val_tab(struct af9033_dev *dev,
-               const struct reg_val *tab, int tab_len)
+                                const struct reg_val *tab, int tab_len)
 {
+       struct i2c_client *client = dev->client;
 #define MAX_TAB_LEN 212
        int ret, i, j;
        u8 buf[1 + MAX_TAB_LEN];
 
-       dev_dbg(&dev->client->dev, "tab_len=%d\n", tab_len);
+       dev_dbg(&client->dev, "tab_len=%d\n", tab_len);
 
        if (tab_len > sizeof(buf)) {
-               dev_warn(&dev->client->dev, "tab len %d is too big\n", tab_len);
+               dev_warn(&client->dev, "tab len %d is too big\n", tab_len);
                return -EINVAL;
        }
 
@@ -190,8 +57,9 @@ static int af9033_wr_reg_val_tab(struct af9033_dev *dev,
                buf[j] = tab[i].val;
 
                if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
-                       ret = af9033_wr_regs(dev, tab[i].reg - j, buf, j + 1);
-                       if (ret < 0)
+                       ret = regmap_bulk_write(dev->regmap, tab[i].reg - j,
+                                               buf, j + 1);
+                       if (ret)
                                goto err;
 
                        j = 0;
@@ -201,47 +69,20 @@ static int af9033_wr_reg_val_tab(struct af9033_dev *dev,
        }
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
-static u32 af9033_div(struct af9033_dev *dev, u32 a, u32 b, u32 x)
-{
-       u32 r = 0, c = 0, i;
-
-       dev_dbg(&dev->client->dev, "a=%d b=%d x=%d\n", a, b, x);
-
-       if (a > b) {
-               c = a / b;
-               a = a - c * b;
-       }
-
-       for (i = 0; i < x; i++) {
-               if (a >= b) {
-                       r += 1;
-                       a -= b;
-               }
-               a <<= 1;
-               r <<= 1;
-       }
-       r = (c << (u32)x) + r;
-
-       dev_dbg(&dev->client->dev, "a=%d b=%d x=%d r=%d r=%x\n", a, b, x, r, r);
-
-       return r;
-}
-
 static int af9033_init(struct dvb_frontend *fe)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        int ret, i, len;
+       unsigned int utmp;
        const struct reg_val *init;
        u8 buf[4];
-       u32 adc_cw, clock_cw;
        struct reg_val_mask tab[] = {
                { 0x80fb24, 0x00, 0x08 },
                { 0x80004c, 0x00, 0xff },
@@ -271,80 +112,76 @@ static int af9033_init(struct dvb_frontend *fe)
                { 0x800045, dev->cfg.adc_multiplier, 0xff },
        };
 
-       /* program clock control */
-       clock_cw = af9033_div(dev, dev->cfg.clock, 1000000ul, 19ul);
-       buf[0] = (clock_cw >>  0) & 0xff;
-       buf[1] = (clock_cw >>  8) & 0xff;
-       buf[2] = (clock_cw >> 16) & 0xff;
-       buf[3] = (clock_cw >> 24) & 0xff;
-
-       dev_dbg(&dev->client->dev, "clock=%d clock_cw=%08x\n",
-                       dev->cfg.clock, clock_cw);
+       dev_dbg(&client->dev, "\n");
 
-       ret = af9033_wr_regs(dev, 0x800025, buf, 4);
-       if (ret < 0)
+       /* Main clk control */
+       utmp = div_u64((u64)dev->cfg.clock * 0x80000, 1000000);
+       buf[0] = (utmp >>  0) & 0xff;
+       buf[1] = (utmp >>  8) & 0xff;
+       buf[2] = (utmp >> 16) & 0xff;
+       buf[3] = (utmp >> 24) & 0xff;
+       ret = regmap_bulk_write(dev->regmap, 0x800025, buf, 4);
+       if (ret)
                goto err;
 
-       /* program ADC control */
+       dev_dbg(&client->dev, "clk=%u clk_cw=%08x\n", dev->cfg.clock, utmp);
+
+       /* ADC clk control */
        for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
                if (clock_adc_lut[i].clock == dev->cfg.clock)
                        break;
        }
        if (i == ARRAY_SIZE(clock_adc_lut)) {
-               dev_err(&dev->client->dev,
-                       "Couldn't find ADC config for clock=%d\n",
+               dev_err(&client->dev, "Couldn't find ADC config for clock %d\n",
                        dev->cfg.clock);
                goto err;
        }
 
-       adc_cw = af9033_div(dev, clock_adc_lut[i].adc, 1000000ul, 19ul);
-       buf[0] = (adc_cw >>  0) & 0xff;
-       buf[1] = (adc_cw >>  8) & 0xff;
-       buf[2] = (adc_cw >> 16) & 0xff;
-
-       dev_dbg(&dev->client->dev, "adc=%d adc_cw=%06x\n",
-                       clock_adc_lut[i].adc, adc_cw);
-
-       ret = af9033_wr_regs(dev, 0x80f1cd, buf, 3);
-       if (ret < 0)
+       utmp = div_u64((u64)clock_adc_lut[i].adc * 0x80000, 1000000);
+       buf[0] = (utmp >>  0) & 0xff;
+       buf[1] = (utmp >>  8) & 0xff;
+       buf[2] = (utmp >> 16) & 0xff;
+       ret = regmap_bulk_write(dev->regmap, 0x80f1cd, buf, 3);
+       if (ret)
                goto err;
 
-       /* program register table */
+       dev_dbg(&client->dev, "adc=%u adc_cw=%06x\n",
+               clock_adc_lut[i].adc, utmp);
+
+       /* Config register table */
        for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = af9033_wr_reg_mask(dev, tab[i].reg, tab[i].val,
-                               tab[i].mask);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, tab[i].reg, tab[i].mask,
+                                        tab[i].val);
+               if (ret)
                        goto err;
        }
 
-       /* clock output */
+       /* Demod clk output */
        if (dev->cfg.dyn0_clk) {
-               ret = af9033_wr_reg(dev, 0x80fba8, 0x00);
-               if (ret < 0)
+               ret = regmap_write(dev->regmap, 0x80fba8, 0x00);
+               if (ret)
                        goto err;
        }
 
-       /* settings for TS interface */
+       /* TS interface */
        if (dev->cfg.ts_mode == AF9033_TS_MODE_USB) {
-               ret = af9033_wr_reg_mask(dev, 0x80f9a5, 0x00, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x80f9a5, 0x01, 0x00);
+               if (ret)
                        goto err;
-
-               ret = af9033_wr_reg_mask(dev, 0x80f9b5, 0x01, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x80f9b5, 0x01, 0x01);
+               if (ret)
                        goto err;
        } else {
-               ret = af9033_wr_reg_mask(dev, 0x80f990, 0x00, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x80f990, 0x01, 0x00);
+               if (ret)
                        goto err;
-
-               ret = af9033_wr_reg_mask(dev, 0x80f9b5, 0x00, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x80f9b5, 0x01, 0x00);
+               if (ret)
                        goto err;
        }
 
-       /* load OFSM settings */
-       dev_dbg(&dev->client->dev, "load ofsm settings\n");
+       /* Demod core settings */
+       dev_dbg(&client->dev, "load ofsm settings\n");
        switch (dev->cfg.tuner) {
        case AF9033_TUNER_IT9135_38:
        case AF9033_TUNER_IT9135_51:
@@ -365,11 +202,11 @@ static int af9033_init(struct dvb_frontend *fe)
        }
 
        ret = af9033_wr_reg_val_tab(dev, init, len);
-       if (ret < 0)
+       if (ret)
                goto err;
 
-       /* load tuner specific settings */
-       dev_dbg(&dev->client->dev, "load tuner specific settings\n");
+       /* Demod tuner specific settings */
+       dev_dbg(&client->dev, "load tuner specific settings\n");
        switch (dev->cfg.tuner) {
        case AF9033_TUNER_TUA9001:
                len = ARRAY_SIZE(tuner_init_tua9001);
@@ -420,27 +257,25 @@ static int af9033_init(struct dvb_frontend *fe)
                init = tuner_init_it9135_62;
                break;
        default:
-               dev_dbg(&dev->client->dev, "unsupported tuner ID=%d\n",
-                               dev->cfg.tuner);
+               dev_dbg(&client->dev, "unsupported tuner ID=%d\n",
+                       dev->cfg.tuner);
                ret = -ENODEV;
                goto err;
        }
 
        ret = af9033_wr_reg_val_tab(dev, init, len);
-       if (ret < 0)
+       if (ret)
                goto err;
 
        if (dev->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
-               ret = af9033_wr_reg_mask(dev, 0x00d91c, 0x01, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x00d91c, 0x01, 0x01);
+               if (ret)
                        goto err;
-
-               ret = af9033_wr_reg_mask(dev, 0x00d917, 0x00, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x00d917, 0x01, 0x00);
+               if (ret)
                        goto err;
-
-               ret = af9033_wr_reg_mask(dev, 0x00d916, 0x00, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x00d916, 0x01, 0x00);
+               if (ret)
                        goto err;
        }
 
@@ -448,13 +283,13 @@ static int af9033_init(struct dvb_frontend *fe)
        case AF9033_TUNER_IT9135_60:
        case AF9033_TUNER_IT9135_61:
        case AF9033_TUNER_IT9135_62:
-               ret = af9033_wr_reg(dev, 0x800000, 0x01);
-               if (ret < 0)
+               ret = regmap_write(dev->regmap, 0x800000, 0x01);
+               if (ret)
                        goto err;
        }
 
-       dev->bandwidth_hz = 0; /* force to program all parameters */
-       /* init stats here in order signal app which stats are supported */
+       dev->bandwidth_hz = 0; /* Force to program all parameters */
+       /* Init stats here in order signal app which stats are supported */
        c->strength.len = 1;
        c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
        c->cnr.len = 1;
@@ -469,68 +304,53 @@ static int af9033_init(struct dvb_frontend *fe)
        c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_sleep(struct dvb_frontend *fe)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
-       int ret, i;
-       u8 tmp;
+       struct i2c_client *client = dev->client;
+       int ret;
+       unsigned int utmp;
 
-       ret = af9033_wr_reg(dev, 0x80004c, 1);
-       if (ret < 0)
-               goto err;
+       dev_dbg(&client->dev, "\n");
 
-       ret = af9033_wr_reg(dev, 0x800000, 0);
-       if (ret < 0)
+       ret = regmap_write(dev->regmap, 0x80004c, 0x01);
+       if (ret)
                goto err;
-
-       for (i = 100, tmp = 1; i && tmp; i--) {
-               ret = af9033_rd_reg(dev, 0x80004c, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               usleep_range(200, 10000);
-       }
-
-       dev_dbg(&dev->client->dev, "loop=%d\n", i);
-
-       if (i == 0) {
-               ret = -ETIMEDOUT;
+       ret = regmap_write(dev->regmap, 0x800000, 0x00);
+       if (ret)
                goto err;
-       }
-
-       ret = af9033_wr_reg_mask(dev, 0x80fb24, 0x08, 0x08);
-       if (ret < 0)
+       ret = regmap_read_poll_timeout(dev->regmap, 0x80004c, utmp, utmp == 0,
+                                      5000, 1000000);
+       if (ret)
+               goto err;
+       ret = regmap_update_bits(dev->regmap, 0x80fb24, 0x08, 0x08);
+       if (ret)
                goto err;
 
-       /* prevent current leak (?) */
+       /* Prevent current leak by setting TS interface to parallel mode */
        if (dev->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
-               /* enable parallel TS */
-               ret = af9033_wr_reg_mask(dev, 0x00d917, 0x00, 0x01);
-               if (ret < 0)
+               /* Enable parallel TS */
+               ret = regmap_update_bits(dev->regmap, 0x00d917, 0x01, 0x00);
+               if (ret)
                        goto err;
-
-               ret = af9033_wr_reg_mask(dev, 0x00d916, 0x01, 0x01);
-               if (ret < 0)
+               ret = regmap_update_bits(dev->regmap, 0x00d916, 0x01, 0x01);
+               if (ret)
                        goto err;
        }
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_get_tune_settings(struct dvb_frontend *fe,
-               struct dvb_frontend_tune_settings *fesettings)
+                                   struct dvb_frontend_tune_settings *fesettings)
 {
        /* 800 => 2000 because IT9135 v2 is slow to gain lock */
        fesettings->min_delay_ms = 2000;
@@ -543,15 +363,17 @@ static int af9033_get_tune_settings(struct dvb_frontend *fe,
 static int af9033_set_frontend(struct dvb_frontend *fe)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, spec_inv, sampling_freq;
+       int ret, i;
+       unsigned int utmp, adc_freq;
        u8 tmp, buf[3], bandwidth_reg_val;
-       u32 if_frequency, freq_cw, adc_freq;
+       u32 if_frequency;
 
-       dev_dbg(&dev->client->dev, "frequency=%d bandwidth_hz=%d\n",
-                       c->frequency, c->bandwidth_hz);
+       dev_dbg(&client->dev, "frequency=%u bandwidth_hz=%u\n",
+               c->frequency, c->bandwidth_hz);
 
-       /* check bandwidth */
+       /* Check bandwidth */
        switch (c->bandwidth_hz) {
        case 6000000:
                bandwidth_reg_val = 0x00;
@@ -563,105 +385,91 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
                bandwidth_reg_val = 0x02;
                break;
        default:
-               dev_dbg(&dev->client->dev, "invalid bandwidth_hz\n");
+               dev_dbg(&client->dev, "invalid bandwidth_hz\n");
                ret = -EINVAL;
                goto err;
        }
 
-       /* program tuner */
+       /* Program tuner */
        if (fe->ops.tuner_ops.set_params)
                fe->ops.tuner_ops.set_params(fe);
 
-       /* program CFOE coefficients */
+       /* Coefficients */
        if (c->bandwidth_hz != dev->bandwidth_hz) {
                for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
                        if (coeff_lut[i].clock == dev->cfg.clock &&
-                               coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
+                           coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
                                break;
                        }
                }
                if (i == ARRAY_SIZE(coeff_lut)) {
-                       dev_err(&dev->client->dev,
-                               "Couldn't find LUT config for clock=%d\n",
+                       dev_err(&client->dev,
+                               "Couldn't find config for clock %u\n",
                                dev->cfg.clock);
                        ret = -EINVAL;
                        goto err;
                }
 
-               ret = af9033_wr_regs(dev, 0x800001,
-                               coeff_lut[i].val, sizeof(coeff_lut[i].val));
+               ret = regmap_bulk_write(dev->regmap, 0x800001, coeff_lut[i].val,
+                                       sizeof(coeff_lut[i].val));
+               if (ret)
+                       goto err;
        }
 
-       /* program frequency control */
+       /* IF frequency control */
        if (c->bandwidth_hz != dev->bandwidth_hz) {
-               spec_inv = dev->cfg.spec_inv ? -1 : 1;
-
                for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
                        if (clock_adc_lut[i].clock == dev->cfg.clock)
                                break;
                }
                if (i == ARRAY_SIZE(clock_adc_lut)) {
-                       dev_err(&dev->client->dev,
-                               "Couldn't find ADC clock for clock=%d\n",
+                       dev_err(&client->dev,
+                               "Couldn't find ADC clock for clock %u\n",
                                dev->cfg.clock);
                        ret = -EINVAL;
                        goto err;
                }
                adc_freq = clock_adc_lut[i].adc;
 
-               /* get used IF frequency */
+               if (dev->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
+                       adc_freq = 2 * adc_freq;
+
+               /* Get used IF frequency */
                if (fe->ops.tuner_ops.get_if_frequency)
                        fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
                else
                        if_frequency = 0;
 
-               sampling_freq = if_frequency;
-
-               while (sampling_freq > (adc_freq / 2))
-                       sampling_freq -= adc_freq;
-
-               if (sampling_freq >= 0)
-                       spec_inv *= -1;
-               else
-                       sampling_freq *= -1;
-
-               freq_cw = af9033_div(dev, sampling_freq, adc_freq, 23ul);
+               utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x800000,
+                                            adc_freq);
 
-               if (spec_inv == -1)
-                       freq_cw = 0x800000 - freq_cw;
+               if (!dev->cfg.spec_inv && if_frequency)
+                       utmp = 0x800000 - utmp;
 
-               if (dev->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
-                       freq_cw /= 2;
-
-               buf[0] = (freq_cw >>  0) & 0xff;
-               buf[1] = (freq_cw >>  8) & 0xff;
-               buf[2] = (freq_cw >> 16) & 0x7f;
-
-               /* FIXME: there seems to be calculation error here... */
-               if (if_frequency == 0)
-                       buf[2] = 0;
-
-               ret = af9033_wr_regs(dev, 0x800029, buf, 3);
-               if (ret < 0)
+               buf[0] = (utmp >>  0) & 0xff;
+               buf[1] = (utmp >>  8) & 0xff;
+               buf[2] = (utmp >> 16) & 0xff;
+               ret = regmap_bulk_write(dev->regmap, 0x800029, buf, 3);
+               if (ret)
                        goto err;
 
+               dev_dbg(&client->dev, "if_frequency_cw=%06x\n", utmp);
+
                dev->bandwidth_hz = c->bandwidth_hz;
        }
 
-       ret = af9033_wr_reg_mask(dev, 0x80f904, bandwidth_reg_val, 0x03);
-       if (ret < 0)
+       ret = regmap_update_bits(dev->regmap, 0x80f904, 0x03,
+                                bandwidth_reg_val);
+       if (ret)
                goto err;
-
-       ret = af9033_wr_reg(dev, 0x800040, 0x00);
-       if (ret < 0)
+       ret = regmap_write(dev->regmap, 0x800040, 0x00);
+       if (ret)
                goto err;
-
-       ret = af9033_wr_reg(dev, 0x800047, 0x00);
-       if (ret < 0)
+       ret = regmap_write(dev->regmap, 0x800047, 0x00);
+       if (ret)
                goto err;
-
-       ret = af9033_wr_reg_mask(dev, 0x80f999, 0x00, 0x01);
-       if (ret < 0)
+       ret = regmap_update_bits(dev->regmap, 0x80f999, 0x01, 0x00);
+       if (ret)
                goto err;
 
        if (c->frequency <= 230000000)
@@ -669,19 +477,17 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
        else
                tmp = 0x01; /* UHF */
 
-       ret = af9033_wr_reg(dev, 0x80004b, tmp);
-       if (ret < 0)
+       ret = regmap_write(dev->regmap, 0x80004b, tmp);
+       if (ret)
                goto err;
-
-       ret = af9033_wr_reg(dev, 0x800000, 0x00);
-       if (ret < 0)
+       /* Reset FSM */
+       ret = regmap_write(dev->regmap, 0x800000, 0x00);
+       if (ret)
                goto err;
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
@@ -689,14 +495,15 @@ static int af9033_get_frontend(struct dvb_frontend *fe,
                               struct dtv_frontend_properties *c)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        int ret;
        u8 buf[8];
 
-       dev_dbg(&dev->client->dev, "\n");
+       dev_dbg(&client->dev, "\n");
 
-       /* read all needed registers */
-       ret = af9033_rd_regs(dev, 0x80f900, buf, sizeof(buf));
-       if (ret < 0)
+       /* Read all needed TPS registers */
+       ret = regmap_bulk_read(dev->regmap, 0x80f900, buf, 8);
+       if (ret)
                goto err;
 
        switch ((buf[0] >> 0) & 3) {
@@ -805,49 +612,49 @@ static int af9033_get_frontend(struct dvb_frontend *fe,
        }
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i, tmp = 0;
-       u8 u8tmp, buf[7];
+       int ret, tmp = 0;
+       u8 buf[7];
+       unsigned int utmp, utmp1;
 
-       dev_dbg(&dev->client->dev, "\n");
+       dev_dbg(&client->dev, "\n");
 
        *status = 0;
 
-       /* radio channel status, 0=no result, 1=has signal, 2=no signal */
-       ret = af9033_rd_reg(dev, 0x800047, &u8tmp);
-       if (ret < 0)
+       /* Radio channel status: 0=no result, 1=has signal, 2=no signal */
+       ret = regmap_read(dev->regmap, 0x800047, &utmp);
+       if (ret)
                goto err;
 
-       /* has signal */
-       if (u8tmp == 0x01)
+       /* Has signal */
+       if (utmp == 0x01)
                *status |= FE_HAS_SIGNAL;
 
-       if (u8tmp != 0x02) {
+       if (utmp != 0x02) {
                /* TPS lock */
-               ret = af9033_rd_reg_mask(dev, 0x80f5a9, &u8tmp, 0x01);
-               if (ret < 0)
+               ret = regmap_read(dev->regmap, 0x80f5a9, &utmp);
+               if (ret)
                        goto err;
 
-               if (u8tmp)
+               if ((utmp >> 0) & 0x01)
                        *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
                                        FE_HAS_VITERBI;
 
-               /* full lock */
-               ret = af9033_rd_reg_mask(dev, 0x80f999, &u8tmp, 0x01);
-               if (ret < 0)
+               /* Full lock */
+               ret = regmap_read(dev->regmap, 0x80f999, &utmp);
+               if (ret)
                        goto err;
 
-               if (u8tmp)
+               if ((utmp >> 0) & 0x01)
                        *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
                                        FE_HAS_VITERBI | FE_HAS_SYNC |
                                        FE_HAS_LOCK;
@@ -855,18 +662,18 @@ static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status)
 
        dev->fe_status = *status;
 
-       /* signal strength */
+       /* Signal strength */
        if (dev->fe_status & FE_HAS_SIGNAL) {
                if (dev->is_af9035) {
-                       ret = af9033_rd_reg(dev, 0x80004a, &u8tmp);
+                       ret = regmap_read(dev->regmap, 0x80004a, &utmp);
                        if (ret)
                                goto err;
-                       tmp = -u8tmp * 1000;
+                       tmp = -utmp * 1000;
                } else {
-                       ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp);
+                       ret = regmap_read(dev->regmap, 0x8000f7, &utmp);
                        if (ret)
                                goto err;
-                       tmp = (u8tmp - 100) * 1000;
+                       tmp = (utmp - 100) * 1000;
                }
 
                c->strength.len = 1;
@@ -879,87 +686,101 @@ static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status)
 
        /* CNR */
        if (dev->fe_status & FE_HAS_VITERBI) {
-               u32 snr_val, snr_lut_size;
-               const struct val_snr *snr_lut = NULL;
-
-               /* read value */
-               ret = af9033_rd_regs(dev, 0x80002c, buf, 3);
+               /* Read raw SNR value */
+               ret = regmap_bulk_read(dev->regmap, 0x80002c, buf, 3);
                if (ret)
                        goto err;
 
-               snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
+               utmp1 = buf[2] << 16 | buf[1] << 8 | buf[0] << 0;
 
-               /* read superframe number */
-               ret = af9033_rd_reg(dev, 0x80f78b, &u8tmp);
+               /* Read superframe number */
+               ret = regmap_read(dev->regmap, 0x80f78b, &utmp);
                if (ret)
                        goto err;
 
-               if (u8tmp)
-                       snr_val /= u8tmp;
+               if (utmp)
+                       utmp1 /= utmp;
 
-               /* read current transmission mode */
-               ret = af9033_rd_reg(dev, 0x80f900, &u8tmp);
+               /* Read current transmission mode */
+               ret = regmap_read(dev->regmap, 0x80f900, &utmp);
                if (ret)
                        goto err;
 
-               switch ((u8tmp >> 0) & 3) {
+               switch ((utmp >> 0) & 3) {
                case 0:
-                       snr_val *= 4;
+                       /* 2k */
+                       utmp1 *= 4;
                        break;
                case 1:
-                       snr_val *= 1;
+                       /* 8k */
+                       utmp1 *= 1;
                        break;
                case 2:
-                       snr_val *= 2;
+                       /* 4k */
+                       utmp1 *= 2;
                        break;
                default:
-                       snr_val *= 0;
+                       utmp1 *= 0;
                        break;
                }
 
-               /* read current modulation */
-               ret = af9033_rd_reg(dev, 0x80f903, &u8tmp);
+               /* Read current modulation */
+               ret = regmap_read(dev->regmap, 0x80f903, &utmp);
                if (ret)
                        goto err;
 
-               switch ((u8tmp >> 0) & 3) {
+               switch ((utmp >> 0) & 3) {
                case 0:
-                       snr_lut_size = ARRAY_SIZE(qpsk_snr_lut);
-                       snr_lut = qpsk_snr_lut;
+                       /*
+                        * QPSK
+                        * CNR[dB] 13 * -log10((1690000 - value) / value) + 2.6
+                        * value [653799, 1689999], 2.6 / 13 = 3355443
+                        */
+                       utmp1 = clamp(utmp1, 653799U, 1689999U);
+                       utmp1 = ((u64)(intlog10(utmp1)
+                                - intlog10(1690000 - utmp1)
+                                + 3355443) * 13 * 1000) >> 24;
                        break;
                case 1:
-                       snr_lut_size = ARRAY_SIZE(qam16_snr_lut);
-                       snr_lut = qam16_snr_lut;
+                       /*
+                        * QAM-16
+                        * CNR[dB] 6 * log10((value - 370000) / (828000 - value)) + 15.7
+                        * value [371105, 827999], 15.7 / 6 = 43900382
+                        */
+                       utmp1 = clamp(utmp1, 371105U, 827999U);
+                       utmp1 = ((u64)(intlog10(utmp1 - 370000)
+                                - intlog10(828000 - utmp1)
+                                + 43900382) * 6 * 1000) >> 24;
                        break;
                case 2:
-                       snr_lut_size = ARRAY_SIZE(qam64_snr_lut);
-                       snr_lut = qam64_snr_lut;
+                       /*
+                        * QAM-64
+                        * CNR[dB] 8 * log10((value - 193000) / (425000 - value)) + 23.8
+                        * value [193246, 424999], 23.8 / 8 = 49912218
+                        */
+                       utmp1 = clamp(utmp1, 193246U, 424999U);
+                       utmp1 = ((u64)(intlog10(utmp1 - 193000)
+                                - intlog10(425000 - utmp1)
+                                + 49912218) * 8 * 1000) >> 24;
                        break;
                default:
-                       snr_lut_size = 0;
-                       tmp = 0;
+                       utmp1 = 0;
                        break;
                }
 
-               for (i = 0; i < snr_lut_size; i++) {
-                       tmp = snr_lut[i].snr * 1000;
-                       if (snr_val < snr_lut[i].val)
-                               break;
-               }
+               dev_dbg(&client->dev, "cnr=%u\n", utmp1);
 
-               c->cnr.len = 1;
                c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
-               c->cnr.stat[0].svalue = tmp;
+               c->cnr.stat[0].svalue = utmp1;
        } else {
-               c->cnr.len = 1;
                c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
        }
 
        /* UCB/PER/BER */
        if (dev->fe_status & FE_HAS_LOCK) {
-               /* outer FEC, 204 byte packets */
+               /* Outer FEC, 204 byte packets */
                u16 abort_packet_count, rsd_packet_count;
-               /* inner FEC, bits */
+               /* Inner FEC, bits */
                u32 rsd_bit_err_count;
 
                /*
@@ -967,7 +788,7 @@ static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status)
                 * (rsd_packet_count). Maybe it should be increased?
                 */
 
-               ret = af9033_rd_regs(dev, 0x800032, buf, 7);
+               ret = regmap_bulk_read(dev->regmap, 0x800032, buf, 7);
                if (ret)
                        goto err;
 
@@ -998,21 +819,22 @@ static int af9033_read_status(struct dvb_frontend *fe, enum fe_status *status)
        }
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
        int ret;
-       u8 u8tmp;
+       unsigned int utmp;
+
+       dev_dbg(&client->dev, "\n");
 
-       /* use DVBv5 CNR */
+       /* Use DVBv5 CNR */
        if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) {
                /* Return 0.1 dB for AF9030 and 0-0xffff for IT9130. */
                if (dev->is_af9035) {
@@ -1022,13 +844,13 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
                        /* 1000x => 1x (1 dB) */
                        *snr = div_s64(c->cnr.stat[0].svalue, 1000);
 
-                       /* read current modulation */
-                       ret = af9033_rd_reg(dev, 0x80f903, &u8tmp);
+                       /* Read current modulation */
+                       ret = regmap_read(dev->regmap, 0x80f903, &utmp);
                        if (ret)
                                goto err;
 
                        /* scale value to 0x0000-0xffff */
-                       switch ((u8tmp >> 0) & 3) {
+                       switch ((utmp >> 0) & 3) {
                        case 0:
                                *snr = *snr * 0xffff / 23;
                                break;
@@ -1047,35 +869,37 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
        }
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
        int ret, tmp, power_real;
-       u8 u8tmp, gain_offset, buf[7];
+       unsigned int utmp;
+       u8 gain_offset, buf[7];
+
+       dev_dbg(&client->dev, "\n");
 
        if (dev->is_af9035) {
-               /* read signal strength of 0-100 scale */
-               ret = af9033_rd_reg(dev, 0x800048, &u8tmp);
-               if (ret < 0)
+               /* Read signal strength of 0-100 scale */
+               ret = regmap_read(dev->regmap, 0x800048, &utmp);
+               if (ret)
                        goto err;
 
-               /* scale value to 0x0000-0xffff */
-               *strength = u8tmp * 0xffff / 100;
+               /* Scale value to 0x0000-0xffff */
+               *strength = utmp * 0xffff / 100;
        } else {
-               ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp);
-               if (ret < 0)
+               ret = regmap_read(dev->regmap, 0x8000f7, &utmp);
+               if (ret)
                        goto err;
 
-               ret = af9033_rd_regs(dev, 0x80f900, buf, 7);
-               if (ret < 0)
+               ret = regmap_bulk_read(dev->regmap, 0x80f900, buf, 7);
+               if (ret)
                        goto err;
 
                if (c->frequency <= 300000000)
@@ -1083,7 +907,7 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
                else
                        gain_offset = 4; /* UHF */
 
-               power_real = (u8tmp - 100 - gain_offset) -
+               power_real = (utmp - 100 - gain_offset) -
                        power_reference[((buf[3] >> 0) & 3)][((buf[6] >> 0) & 7)];
 
                if (power_real < -15)
@@ -1097,15 +921,13 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
                else
                        tmp = 100;
 
-               /* scale value to 0x0000-0xffff */
+               /* Scale value to 0x0000-0xffff */
                *strength = tmp * 0xffff / 100;
        }
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
@@ -1124,82 +946,78 @@ static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
        struct af9033_dev *dev = fe->demodulator_priv;
 
        *ucblocks = dev->error_block_count;
+
        return 0;
 }
 
 static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        int ret;
 
-       dev_dbg(&dev->client->dev, "enable=%d\n", enable);
+       dev_dbg(&client->dev, "enable=%d\n", enable);
 
-       ret = af9033_wr_reg_mask(dev, 0x00fa04, enable, 0x01);
-       if (ret < 0)
+       ret = regmap_update_bits(dev->regmap, 0x00fa04, 0x01, enable);
+       if (ret)
                goto err;
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        int ret;
 
-       dev_dbg(&dev->client->dev, "onoff=%d\n", onoff);
+       dev_dbg(&client->dev, "onoff=%d\n", onoff);
 
-       ret = af9033_wr_reg_mask(dev, 0x80f993, onoff, 0x01);
-       if (ret < 0)
+       ret = regmap_update_bits(dev->regmap, 0x80f993, 0x01, onoff);
+       if (ret)
                goto err;
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
-               int onoff)
+                            int onoff)
 {
        struct af9033_dev *dev = fe->demodulator_priv;
+       struct i2c_client *client = dev->client;
        int ret;
        u8 wbuf[2] = {(pid >> 0) & 0xff, (pid >> 8) & 0xff};
 
-       dev_dbg(&dev->client->dev, "index=%d pid=%04x onoff=%d\n",
-                       index, pid, onoff);
+       dev_dbg(&client->dev, "index=%d pid=%04x onoff=%d\n",
+               index, pid, onoff);
 
        if (pid > 0x1fff)
                return 0;
 
-       ret = af9033_wr_regs(dev, 0x80f996, wbuf, 2);
-       if (ret < 0)
+       ret = regmap_bulk_write(dev->regmap, 0x80f996, wbuf, 2);
+       if (ret)
                goto err;
-
-       ret = af9033_wr_reg(dev, 0x80f994, onoff);
-       if (ret < 0)
+       ret = regmap_write(dev->regmap, 0x80f994, onoff);
+       if (ret)
                goto err;
-
-       ret = af9033_wr_reg(dev, 0x80f995, index);
-       if (ret < 0)
+       ret = regmap_write(dev->regmap, 0x80f995, index);
+       if (ret)
                goto err;
 
        return 0;
-
 err:
-       dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-
+       dev_dbg(&client->dev, "failed=%d\n", ret);
        return ret;
 }
 
 static const struct dvb_frontend_ops af9033_ops = {
-       .delsys = { SYS_DVBT },
+       .delsys = {SYS_DVBT},
        .info = {
                .name = "Afatech AF9033 (DVB-T)",
                .frequency_min = 174000000,
@@ -1240,35 +1058,57 @@ static const struct dvb_frontend_ops af9033_ops = {
 };
 
 static int af9033_probe(struct i2c_client *client,
-               const struct i2c_device_id *id)
+                       const struct i2c_device_id *id)
 {
        struct af9033_config *cfg = client->dev.platform_data;
        struct af9033_dev *dev;
        int ret;
        u8 buf[8];
        u32 reg;
+       static const struct regmap_config regmap_config = {
+               .reg_bits    =  24,
+               .val_bits    =  8,
+       };
 
-       /* allocate memory for the internal state */
-       dev = kzalloc(sizeof(struct af9033_dev), GFP_KERNEL);
-       if (dev == NULL) {
+       /* Allocate memory for the internal state */
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev) {
                ret = -ENOMEM;
-               dev_err(&client->dev, "Could not allocate memory for state\n");
                goto err;
        }
 
-       /* setup the state */
+       /* Setup the state */
        dev->client = client;
-       memcpy(&dev->cfg, cfg, sizeof(struct af9033_config));
+       memcpy(&dev->cfg, cfg, sizeof(dev->cfg));
+       switch (dev->cfg.ts_mode) {
+       case AF9033_TS_MODE_PARALLEL:
+               dev->ts_mode_parallel = true;
+               break;
+       case AF9033_TS_MODE_SERIAL:
+               dev->ts_mode_serial = true;
+               break;
+       case AF9033_TS_MODE_USB:
+               /* USB mode for AF9035 */
+       default:
+               break;
+       }
 
        if (dev->cfg.clock != 12000000) {
                ret = -ENODEV;
-               dev_err(&dev->client->dev,
-                               "unsupported clock %d Hz, only 12000000 Hz is supported currently\n",
-                               dev->cfg.clock);
+               dev_err(&client->dev,
+                       "Unsupported clock %u Hz. Only 12000000 Hz is supported currently\n",
+                       dev->cfg.clock);
+               goto err_kfree;
+       }
+
+       /* Create regmap */
+       dev->regmap = regmap_init_i2c(client, &regmap_config);
+       if (IS_ERR(dev->regmap)) {
+               ret = PTR_ERR(dev->regmap);
                goto err_kfree;
        }
 
-       /* firmware version */
+       /* Firmware version */
        switch (dev->cfg.tuner) {
        case AF9033_TUNER_IT9135_38:
        case AF9033_TUNER_IT9135_51:
@@ -1285,20 +1125,19 @@ static int af9033_probe(struct i2c_client *client,
                break;
        }
 
-       ret = af9033_rd_regs(dev, reg, &buf[0], 4);
-       if (ret < 0)
-               goto err_kfree;
-
-       ret = af9033_rd_regs(dev, 0x804191, &buf[4], 4);
-       if (ret < 0)
-               goto err_kfree;
+       ret = regmap_bulk_read(dev->regmap, reg, &buf[0], 4);
+       if (ret)
+               goto err_regmap_exit;
+       ret = regmap_bulk_read(dev->regmap, 0x804191, &buf[4], 4);
+       if (ret)
+               goto err_regmap_exit;
 
-       dev_info(&dev->client->dev,
-                       "firmware version: LINK %d.%d.%d.%d - OFDM %d.%d.%d.%d\n",
-                       buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
-                       buf[7]);
+       dev_info(&client->dev,
+                "firmware version: LINK %d.%d.%d.%d - OFDM %d.%d.%d.%d\n",
+                buf[0], buf[1], buf[2], buf[3],
+                buf[4], buf[5], buf[6], buf[7]);
 
-       /* sleep */
+       /* Sleep as chip seems to be partly active by default */
        switch (dev->cfg.tuner) {
        case AF9033_TUNER_IT9135_38:
        case AF9033_TUNER_IT9135_51:
@@ -1309,41 +1148,30 @@ static int af9033_probe(struct i2c_client *client,
                /* IT9135 did not like to sleep at that early */
                break;
        default:
-               ret = af9033_wr_reg(dev, 0x80004c, 1);
-               if (ret < 0)
-                       goto err_kfree;
-
-               ret = af9033_wr_reg(dev, 0x800000, 0);
-               if (ret < 0)
-                       goto err_kfree;
-       }
-
-       /* configure internal TS mode */
-       switch (dev->cfg.ts_mode) {
-       case AF9033_TS_MODE_PARALLEL:
-               dev->ts_mode_parallel = true;
-               break;
-       case AF9033_TS_MODE_SERIAL:
-               dev->ts_mode_serial = true;
-               break;
-       case AF9033_TS_MODE_USB:
-               /* usb mode for AF9035 */
-       default:
-               break;
+               ret = regmap_write(dev->regmap, 0x80004c, 0x01);
+               if (ret)
+                       goto err_regmap_exit;
+               ret = regmap_write(dev->regmap, 0x800000, 0x00);
+               if (ret)
+                       goto err_regmap_exit;
        }
 
-       /* create dvb_frontend */
-       memcpy(&dev->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
+       /* Create dvb frontend */
+       memcpy(&dev->fe.ops, &af9033_ops, sizeof(dev->fe.ops));
        dev->fe.demodulator_priv = dev;
        *cfg->fe = &dev->fe;
        if (cfg->ops) {
                cfg->ops->pid_filter = af9033_pid_filter;
                cfg->ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
        }
+       cfg->regmap = dev->regmap;
        i2c_set_clientdata(client, dev);
 
-       dev_info(&dev->client->dev, "Afatech AF9033 successfully attached\n");
+       dev_info(&client->dev, "Afatech AF9033 successfully attached\n");
+
        return 0;
+err_regmap_exit:
+       regmap_exit(dev->regmap);
 err_kfree:
        kfree(dev);
 err:
@@ -1355,10 +1183,9 @@ static int af9033_remove(struct i2c_client *client)
 {
        struct af9033_dev *dev = i2c_get_clientdata(client);
 
-       dev_dbg(&dev->client->dev, "\n");
+       dev_dbg(&client->dev, "\n");
 
-       dev->fe.ops.release = NULL;
-       dev->fe.demodulator_priv = NULL;
+       regmap_exit(dev->regmap);
        kfree(dev);
 
        return 0;
index 5b83e4f96297126ae5b3da337b6dc250645e91e8..8193f9805c4f8c9ce6d238192c453858588e750f 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #ifndef AF9033_H
 #define AF9033_H
 
 /*
- * I2C address (TODO: are these in 8-bit format?)
- * 0x38, 0x3a, 0x3c, 0x3e
+ * I2C address: 0x1c, 0x1d, 0x1e, 0x1f
  */
 struct af9033_config {
        /*
@@ -88,6 +83,12 @@ struct af9033_config {
         * returned by that driver
         */
        struct dvb_frontend **fe;
+
+       /*
+        * regmap for IT913x integrated tuner driver
+        * returned by that driver
+        */
+       struct regmap *regmap;
 };
 
 struct af9033_ops {
index 8e23275148edf80ee7f102dbc9d2ec6485c1afde..8799cda1ae143a8405c96fc0f87f7197a124bb41 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License along
- *    with this program; if not, write to the Free Software Foundation, Inc.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #ifndef AF9033_PRIV_H
@@ -25,6 +21,9 @@
 #include "dvb_frontend.h"
 #include "af9033.h"
 #include <linux/math64.h>
+#include <linux/regmap.h>
+#include <linux/kernel.h>
+#include "dvb_math.h"
 
 struct reg_val {
        u32 reg;
@@ -68,7 +67,7 @@ static const struct clock_adc clock_adc_lut[] = {
        { 12000000, 20250000 },
 };
 
-/* pre-calculated coeff lookup table */
+/* Pre-calculated coeff lookup table */
 static const struct coeff coeff_lut[] = {
        /* 12.000 MHz */
        { 12000000, 8000000, {
@@ -91,102 +90,9 @@ static const struct coeff coeff_lut[] = {
        },
 };
 
-/* QPSK SNR lookup table */
-static const struct val_snr qpsk_snr_lut[] = {
-       { 0x0b4771,  0 },
-       { 0x0c1aed,  1 },
-       { 0x0d0d27,  2 },
-       { 0x0e4d19,  3 },
-       { 0x0e5da8,  4 },
-       { 0x107097,  5 },
-       { 0x116975,  6 },
-       { 0x1252d9,  7 },
-       { 0x131fa4,  8 },
-       { 0x13d5e1,  9 },
-       { 0x148e53, 10 },
-       { 0x15358b, 11 },
-       { 0x15dd29, 12 },
-       { 0x168112, 13 },
-       { 0x170b61, 14 },
-       { 0x17a532, 15 },
-       { 0x180f94, 16 },
-       { 0x186ed2, 17 },
-       { 0x18b271, 18 },
-       { 0x18e118, 19 },
-       { 0x18ff4b, 20 },
-       { 0x190af1, 21 },
-       { 0x191451, 22 },
-       { 0xffffff, 23 },
-};
-
-/* QAM16 SNR lookup table */
-static const struct val_snr qam16_snr_lut[] = {
-       { 0x04f0d5,  0 },
-       { 0x05387a,  1 },
-       { 0x0573a4,  2 },
-       { 0x05a99e,  3 },
-       { 0x05cc80,  4 },
-       { 0x05eb62,  5 },
-       { 0x05fecf,  6 },
-       { 0x060b80,  7 },
-       { 0x062501,  8 },
-       { 0x064865,  9 },
-       { 0x069604, 10 },
-       { 0x06f356, 11 },
-       { 0x07706a, 12 },
-       { 0x0804d3, 13 },
-       { 0x089d1a, 14 },
-       { 0x093e3d, 15 },
-       { 0x09e35d, 16 },
-       { 0x0a7c3c, 17 },
-       { 0x0afaf8, 18 },
-       { 0x0b719d, 19 },
-       { 0x0bda6a, 20 },
-       { 0x0c0c75, 21 },
-       { 0x0c3f7d, 22 },
-       { 0x0c5e62, 23 },
-       { 0x0c6c31, 24 },
-       { 0x0c7925, 25 },
-       { 0xffffff, 26 },
-};
-
-/* QAM64 SNR lookup table */
-static const struct val_snr qam64_snr_lut[] = {
-       { 0x0256d0,  0 },
-       { 0x027a65,  1 },
-       { 0x029873,  2 },
-       { 0x02b7fe,  3 },
-       { 0x02cf1e,  4 },
-       { 0x02e234,  5 },
-       { 0x02f409,  6 },
-       { 0x030046,  7 },
-       { 0x030844,  8 },
-       { 0x030a02,  9 },
-       { 0x030cde, 10 },
-       { 0x031031, 11 },
-       { 0x03144c, 12 },
-       { 0x0315dd, 13 },
-       { 0x031920, 14 },
-       { 0x0322d0, 15 },
-       { 0x0339fc, 16 },
-       { 0x0364a1, 17 },
-       { 0x038bcc, 18 },
-       { 0x03c7d3, 19 },
-       { 0x0408cc, 20 },
-       { 0x043bed, 21 },
-       { 0x048061, 22 },
-       { 0x04be95, 23 },
-       { 0x04fa7d, 24 },
-       { 0x052405, 25 },
-       { 0x05570d, 26 },
-       { 0x059feb, 27 },
-       { 0x05bf38, 28 },
-       { 0x05f78f, 29 },
-       { 0x0612c3, 30 },
-       { 0x0626be, 31 },
-       { 0xffffff, 32 },
-};
-
+/*
+ * Afatech AF9033 demod init
+ */
 static const struct reg_val ofsm_init[] = {
        { 0x800051, 0x01 },
        { 0x800070, 0x0a },
@@ -298,8 +204,10 @@ static const struct reg_val ofsm_init[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* Infineon TUA 9001 tuner init
-   AF9033_TUNER_TUA9001    = 0x27 */
+/*
+ * Infineon TUA 9001 tuner init
+ * AF9033_TUNER_TUA9001    = 0x27
+ */
 static const struct reg_val tuner_init_tua9001[] = {
        { 0x800046, 0x27 },
        { 0x800057, 0x00 },
@@ -340,8 +248,10 @@ static const struct reg_val tuner_init_tua9001[] = {
        { 0x80f1e6, 0x00 },
 };
 
-/* Fitipower fc0011 tuner init
-   AF9033_TUNER_FC0011    = 0x28 */
+/*
+ * Fitipower FC0011 tuner init
+ * AF9033_TUNER_FC0011    = 0x28
+ */
 static const struct reg_val tuner_init_fc0011[] = {
        { 0x800046, 0x28 },
        { 0x800057, 0x00 },
@@ -401,8 +311,10 @@ static const struct reg_val tuner_init_fc0011[] = {
        { 0x80f1e6, 0x00 },
 };
 
-/* Fitipower FC0012 tuner init
-   AF9033_TUNER_FC0012    = 0x2e */
+/*
+ * Fitipower FC0012 tuner init
+ * AF9033_TUNER_FC0012    = 0x2e
+ */
 static const struct reg_val tuner_init_fc0012[] = {
        { 0x800046, 0x2e },
        { 0x800057, 0x00 },
@@ -444,8 +356,10 @@ static const struct reg_val tuner_init_fc0012[] = {
        { 0x80f1e6, 0x00 },
 };
 
-/* MaxLinear MxL5007T tuner init
-   AF9033_TUNER_MXL5007T    = 0xa0 */
+/*
+ * MaxLinear MxL5007T tuner init
+ * AF9033_TUNER_MXL5007T    = 0xa0
+ */
 static const struct reg_val tuner_init_mxl5007t[] = {
        { 0x800046, 0x1b },
        { 0x800057, 0x01 },
@@ -479,8 +393,10 @@ static const struct reg_val tuner_init_mxl5007t[] = {
        { 0x80f1e6, 0x00 },
 };
 
-/* NXP TDA 18218HN tuner init
-   AF9033_TUNER_TDA18218    = 0xa1 */
+/*
+ * NXP TDA18218HN tuner init
+ * AF9033_TUNER_TDA18218    = 0xa1
+ */
 static const struct reg_val tuner_init_tda18218[] = {
        {0x800046, 0xa1},
        {0x800057, 0x01},
@@ -513,7 +429,10 @@ static const struct reg_val tuner_init_tda18218[] = {
        {0x80f1e6, 0x00},
 };
 
-/* FCI FC2580 tuner init */
+/*
+ * FCI FC2580 tuner init
+ * AF9033_TUNER_FC2580      = 0x32
+ */
 static const struct reg_val tuner_init_fc2580[] = {
        { 0x800046, 0x32 },
        { 0x800057, 0x01 },
@@ -551,6 +470,9 @@ static const struct reg_val tuner_init_fc2580[] = {
        { 0x80f1e6, 0x01 },
 };
 
+/*
+ * IT9133 AX demod init
+ */
 static const struct reg_val ofsm_init_it9135_v1[] = {
        { 0x800051, 0x01 },
        { 0x800070, 0x0a },
@@ -662,8 +584,10 @@ static const struct reg_val ofsm_init_it9135_v1[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* ITE Tech IT9135 Omega tuner init
-   AF9033_TUNER_IT9135_38   = 0x38 */
+/*
+ * ITE Tech IT9133 AX Omega tuner init
+ * AF9033_TUNER_IT9135_38   = 0x38
+ */
 static const struct reg_val tuner_init_it9135_38[] = {
        { 0x800043, 0x00 },
        { 0x800046, 0x38 },
@@ -879,8 +803,10 @@ static const struct reg_val tuner_init_it9135_38[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* ITE Tech IT9135 Omega LNA config 1 tuner init
-   AF9033_TUNER_IT9135_51   = 0x51 */
+/*
+ * ITE Tech IT9133 AX Omega LNA config 1 tuner init
+ * AF9033_TUNER_IT9135_51   = 0x51
+ */
 static const struct reg_val tuner_init_it9135_51[] = {
        { 0x800043, 0x00 },
        { 0x800046, 0x51 },
@@ -1096,8 +1022,10 @@ static const struct reg_val tuner_init_it9135_51[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* ITE Tech IT9135 Omega LNA config 2 tuner init
-   AF9033_TUNER_IT9135_52   = 0x52 */
+/*
+ * ITE Tech IT9133 AX Omega LNA config 2 tuner init
+ * AF9033_TUNER_IT9135_52   = 0x52
+ */
 static const struct reg_val tuner_init_it9135_52[] = {
        { 0x800043, 0x00 },
        { 0x800046, 0x52 },
@@ -1313,6 +1241,9 @@ static const struct reg_val tuner_init_it9135_52[] = {
        { 0x80fd8b, 0x00 },
 };
 
+/*
+ * ITE Tech IT9133 BX demod init
+ */
 static const struct reg_val ofsm_init_it9135_v2[] = {
        { 0x800051, 0x01 },
        { 0x800070, 0x0a },
@@ -1411,8 +1342,10 @@ static const struct reg_val ofsm_init_it9135_v2[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* ITE Tech IT9135 Omega v2 tuner init
-   AF9033_TUNER_IT9135_60   = 0x60 */
+/*
+ * ITE Tech IT9133 BX Omega tuner init
+ * AF9033_TUNER_IT9135_60   = 0x60
+ */
 static const struct reg_val tuner_init_it9135_60[] = {
        { 0x800043, 0x00 },
        { 0x800046, 0x60 },
@@ -1625,8 +1558,10 @@ static const struct reg_val tuner_init_it9135_60[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* ITE Tech IT9135 Omega v2 LNA config 1 tuner init
-   AF9033_TUNER_IT9135_61   = 0x61 */
+/*
+ * ITE Tech IT9133 BX Omega LNA config 1 tuner init
+ * AF9033_TUNER_IT9135_61   = 0x61
+ */
 static const struct reg_val tuner_init_it9135_61[] = {
        { 0x800043, 0x00 },
        { 0x800046, 0x61 },
@@ -1839,8 +1774,10 @@ static const struct reg_val tuner_init_it9135_61[] = {
        { 0x80fd8b, 0x00 },
 };
 
-/* ITE Tech IT9135 Omega v2 LNA config 2 tuner init
-   AF9033_TUNER_IT9135_62   = 0x62 */
+/*
+ * ITE Tech IT9133 BX Omega LNA config 2 tuner init
+ * AF9033_TUNER_IT9135_62   = 0x62
+ */
 static const struct reg_val tuner_init_it9135_62[] = {
        { 0x800043, 0x00 },
        { 0x800046, 0x62 },
index 07ce05578278fe6498d9342fc6363428106087e3..05850b32d6c6a81040dcb9aa215f470bd07b0ef1 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <asm/div64.h>
index bb862387080f7f0607493050c06372b5e0bc2cf1..e146d394f4ed06a7c9abcd37fa76ef18ad56f6c2 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __ATBM8830_H__
index d460058d497e7151ebfc2240c230cebd9aec98cf..f1399451d1b0ef546215d3e7b063b41db778dbff 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __ATBM8830_PRIV_H
index add2463828061d4feccc4a8a335c49f4fa81f942..a2e771305008da18292a857ae9f0ad6b2e54f177 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
 
 /* Developer notes:
index 961c2eb87c684a595ede26ac332a6889c8323309..b6a2d62de37950d428beb63f0ba8ab0fb0cf112c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef BCM3510_H
 #define BCM3510_H
index 67f24686c31b9dd3306bc51c5271d9af25a47e11..475e8381bf133c157412bbc88dec1211a17ec14f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef __BCM3510_PRIV_H__
 #define __BCM3510_PRIV_H__
index baaf89e768cf500ea96497d930dbfb1ac6004f30..1d6e8d33cd9204af97f8b577e8855e08ea24be5c 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 4ad7661547415e1a0dc398bc8b59a2f59cb8f425..cb7cb2c5b9777856611a45ab0739960bf313f11a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 275c1782597d91a420939598e35324dab29a15bf..1c203eb27491d357148c4fbb226dd0ce482c8ac1 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index db44ebb7c56123e3e6486f89be229d4d466007a9..0118c2658cf780d4431032e6dd6bd0c510b93b5c 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/slab.h>
index 194c703611b459c9c3da2c89bdb68aa116638c4d..f013aca3a691e064ca1bbf7b1a9c9df06f24ede3 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef CX24113_H
index 8aed8cc9f93dda1f68fd53c005662c16f6c63710..4ae3d922a8e8a962c5c7e3fb34b3e524eee67cb8 100644 (file)
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  *   General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/slab.h>
@@ -653,7 +649,7 @@ static int cx24123_pll_tune(struct dvb_frontend *fe)
        dprintk("frequency=%i\n", p->frequency);
 
        if (cx24123_pll_calculate(fe) != 0) {
-               err("%s: cx24123_pll_calcutate failed\n", __func__);
+               err("%s: cx24123_pll_calculate failed\n", __func__);
                return -EINVAL;
        }
 
index 95267c6edb3a1357c463eabe4352ba40a9cc8319..f6ebbb47b9b2b9eedc62fa8789b969cae97fac04 100644 (file)
@@ -615,6 +615,7 @@ static int cxd2820r_probe(struct i2c_client *client,
        }
 
        priv->client[0] = client;
+       priv->fe.demodulator_priv = priv;
        priv->i2c = client->adapter;
        priv->ts_mode = pdata->ts_mode;
        priv->ts_clk_inv = pdata->ts_clk_inv;
@@ -697,7 +698,6 @@ static int cxd2820r_probe(struct i2c_client *client,
        memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(priv->fe.ops));
        if (!pdata->attach_in_use)
                priv->fe.ops.release = NULL;
-       priv->fe.demodulator_priv = priv;
        i2c_set_clientdata(client, priv);
 
        /* Setup callbacks */
index befc8172159d0309b2e804318674cd289467e301..d7614b8b8782c16caea5d810d6346f870ef533cd 100644 (file)
  *
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *
  * This code is more or less generated from another driver, please
  * excuse some codingstyle oddities.
index fd3b33296b1574718f21d7ce9e4ffc2077195146..33af14df27bde93854afa2516845c8d6f971fe2f 100644 (file)
  *
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *
  * This code is more or less generated from another driver, please
  * excuse some codingstyle oddities.
index a27c0001f2d6dfe4031eacda011c4e790288476f..3815ea515364554b7aa70320f0155d74a8c3de15 100644 (file)
@@ -805,13 +805,19 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
        return 0;
 }
 
-static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
+static int dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
 {
        u32 internal = dib7000p_get_internal_freq(state);
-       s32 unit_khz_dds_val = 67108864 / (internal);   /* 2**26 / Fsampling is the unit 1KHz offset */
+       s32 unit_khz_dds_val;
        u32 abs_offset_khz = ABS(offset_khz);
        u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
        u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
+       if (internal == 0) {
+               pr_warn("DIB7000P: dib7000p_get_internal_freq returned 0\n");
+               return -1;
+       }
+       /* 2**26 / Fsampling is the unit 1KHz offset */
+       unit_khz_dds_val = 67108864 / (internal);
 
        dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d\n", offset_khz, internal, invert);
 
@@ -828,6 +834,7 @@ static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
                dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
                dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
        }
+       return 0;
 }
 
 static int dib7000p_agc_startup(struct dvb_frontend *demod)
@@ -867,7 +874,9 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
                        frequency_offset = (s32)frequency_tuner / 1000 - ch->frequency / 1000;
                }
 
-               dib7000p_set_dds(state, frequency_offset);
+               if (dib7000p_set_dds(state, frequency_offset) < 0)
+                       return -1;
+
                ret = 7;
                (*agc_state)++;
                break;
index 8188062953afac9277c2e30f8649323c9eeb26aa..11e1ddeeef0a0b6493b4337523f756dbffaeb3fb 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef DRX39XXJ_H
index f0507cdbb5034f57d3b942675dcb57b1857a2438..1d4b89488ac49011645c1e03cc843b31803557d2 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef _DRXD_H_
index 5418b0b1dadc6acc7502bc5e70357aba93f3d0a8..4e1d8905e06ad20e7f6c6faccd1afaaedbfd9ad1 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 /* TODO: generate this file with a script from a settings file */
index 41597e89941ce80fbe687577e2b1946ac2f62fe0..7d9f9fa7ab3ce2151cd20fc6a795df2c425c8dad 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef _DRXD_FIRM_H_
index 4143f0326684653041fc09bfb8133531a2dda79e..71910561005f40116de556b9701d8b9ec6d28f78 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/kernel.h>
index 6bc553abf2152354ba5957c7eab8bcdc64c6d46c..8e5bd2e8de4043b90fade7139cbbcd1e870a6c6d 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef __DRX3973D_MAP__H__
index 146edf344dd8cd6b638085e4e8f4ab65dd4ba8e2..15d2cac588b14320b54676ef18e9aa3e0493512b 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index ef976eb233444bc3790eda024e2d8034e515599e..7bec3e028beec10e188fea4d9f53cc40556f8ddf 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index efc3c31a763503d0aeef62d2a02c4e51f21bb213..50b2b666ef6c2e7d8fac5142d22635b2cd801e17 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #include <linux/module.h>
index 50f1af512b626dbc3a22bb26e66a0983ca38eb81..86dd7b9d1e57b849a7ec56b64912e222336d4596 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef DVB_DUMMY_FE_H
index d97ce21e26e1b67c9c41e15b6cca219ebce2022f..fa2a96d5f94ebc0a41dd163cbfe0586a693a9acb 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "dvb_frontend.h"
index e894bdcf35a3a6fa8a4d5f1423a8788dafd91c5d..e43fe26654b2e701fc1d55928cb77fff7ffea3d9 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef EC100_H
diff --git a/drivers/media/dvb-frontends/hd29l2.c b/drivers/media/dvb-frontends/hd29l2.c
deleted file mode 100644 (file)
index 8b53633..0000000
+++ /dev/null
@@ -1,870 +0,0 @@
-/*
- * HDIC HD29L2 DMB-TH demodulator driver
- *
- * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
- *
- * Author: Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "hd29l2_priv.h"
-
-#define HD29L2_MAX_LEN (3)
-
-/* write multiple registers */
-static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[2 + HD29L2_MAX_LEN];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 2 + len,
-                       .buf = buf,
-               }
-       };
-
-       if (len > HD29L2_MAX_LEN)
-               return -EINVAL;
-       buf[0] = 0x00;
-       buf[1] = reg;
-       memcpy(&buf[2], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev,
-                               "%s: i2c wr failed=%d reg=%02x len=%d\n",
-                               KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* read multiple registers */
-static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
-{
-       int ret;
-       u8 buf[2] = { 0x00, reg };
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = 0,
-                       .len = 2,
-                       .buf = buf,
-               }, {
-                       .addr = priv->cfg.i2c_addr,
-                       .flags = I2C_M_RD,
-                       .len = len,
-                       .buf = val,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev,
-                               "%s: i2c rd failed=%d reg=%02x len=%d\n",
-                               KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* write single register */
-static int hd29l2_wr_reg(struct hd29l2_priv *priv, u8 reg, u8 val)
-{
-       return hd29l2_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-static int hd29l2_rd_reg(struct hd29l2_priv *priv, u8 reg, u8 *val)
-{
-       return hd29l2_rd_regs(priv, reg, val, 1);
-}
-
-/* write single register with mask */
-static int hd29l2_wr_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 val, u8 mask)
-{
-       int ret;
-       u8 tmp;
-
-       /* no need for read if whole reg is written */
-       if (mask != 0xff) {
-               ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
-               if (ret)
-                       return ret;
-
-               val &= mask;
-               tmp &= ~mask;
-               val |= tmp;
-       }
-
-       return hd29l2_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register with mask */
-static int hd29l2_rd_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 *val, u8 mask)
-{
-       int ret, i;
-       u8 tmp;
-
-       ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
-       if (ret)
-               return ret;
-
-       tmp &= mask;
-
-       /* find position of the first bit */
-       for (i = 0; i < 8; i++) {
-               if ((mask >> i) & 0x01)
-                       break;
-       }
-       *val = tmp >> i;
-
-       return 0;
-}
-
-static int hd29l2_soft_reset(struct hd29l2_priv *priv)
-{
-       int ret;
-       u8 tmp;
-
-       ret = hd29l2_rd_reg(priv, 0x26, &tmp);
-       if (ret)
-               goto err;
-
-       ret = hd29l2_wr_reg(priv, 0x26, 0x0d);
-       if (ret)
-               goto err;
-
-       usleep_range(10000, 20000);
-
-       ret = hd29l2_wr_reg(priv, 0x26, tmp);
-       if (ret)
-               goto err;
-
-       return 0;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       int ret, i;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 tmp;
-
-       dev_dbg(&priv->i2c->dev, "%s: enable=%d\n", __func__, enable);
-
-       /* set tuner address for demod */
-       if (!priv->tuner_i2c_addr_programmed && enable) {
-               /* no need to set tuner address every time, once is enough */
-               ret = hd29l2_wr_reg(priv, 0x9d, priv->cfg.tuner_i2c_addr << 1);
-               if (ret)
-                       goto err;
-
-               priv->tuner_i2c_addr_programmed = true;
-       }
-
-       /* open / close gate */
-       ret = hd29l2_wr_reg(priv, 0x9f, enable);
-       if (ret)
-               goto err;
-
-       /* wait demod ready */
-       for (i = 10; i; i--) {
-               ret = hd29l2_rd_reg(priv, 0x9e, &tmp);
-               if (ret)
-                       goto err;
-
-               if (tmp == enable)
-                       break;
-
-               usleep_range(5000, 10000);
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-       return ret;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_status(struct dvb_frontend *fe, enum fe_status *status)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-
-       *status = 0;
-
-       ret = hd29l2_rd_reg(priv, 0x05, &buf[0]);
-       if (ret)
-               goto err;
-
-       if (buf[0] & 0x01) {
-               /* full lock */
-               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
-                       FE_HAS_SYNC | FE_HAS_LOCK;
-       } else {
-               ret = hd29l2_rd_reg(priv, 0x0d, &buf[1]);
-               if (ret)
-                       goto err;
-
-               if ((buf[1] & 0xfe) == 0x78)
-                       /* partial lock */
-                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-                               FE_HAS_VITERBI | FE_HAS_SYNC;
-       }
-
-       priv->fe_status = *status;
-
-       return 0;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-       u16 tmp;
-
-       if (!(priv->fe_status & FE_HAS_LOCK)) {
-               *snr = 0;
-               ret = 0;
-               goto err;
-       }
-
-       ret = hd29l2_rd_regs(priv, 0x0b, buf, 2);
-       if (ret)
-               goto err;
-
-       tmp = (buf[0] << 8) | buf[1];
-
-       /* report SNR in dB * 10 */
-       #define LOG10_20736_24 72422627 /* log10(20736) << 24 */
-       if (tmp)
-               *snr = (LOG10_20736_24 - intlog10(tmp)) / ((1 << 24) / 100);
-       else
-               *snr = 0;
-
-       return 0;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-       u16 tmp;
-
-       *strength = 0;
-
-       ret = hd29l2_rd_regs(priv, 0xd5, buf, 2);
-       if (ret)
-               goto err;
-
-       tmp = buf[0] << 8 | buf[1];
-       tmp = ~tmp & 0x0fff;
-
-       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
-       *strength = tmp * 0xffff / 0x0fff;
-
-       return 0;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[2];
-
-       if (!(priv->fe_status & FE_HAS_SYNC)) {
-               *ber = 0;
-               ret = 0;
-               goto err;
-       }
-
-       ret = hd29l2_rd_regs(priv, 0xd9, buf, 2);
-       if (ret) {
-               *ber = 0;
-               goto err;
-       }
-
-       /* LDPC BER */
-       *ber = ((buf[0] & 0x0f) << 8) | buf[1];
-
-       return 0;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       /* no way to read? */
-       *ucblocks = 0;
-       return 0;
-}
-
-static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
-{
-       int ret, i;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u8 tmp, buf[3];
-       u8 modulation, carrier, guard_interval, interleave, code_rate;
-       u64 num64;
-       u32 if_freq, if_ctl;
-       bool auto_mode;
-
-       dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
-                       "bandwidth_hz=%d modulation=%d inversion=%d " \
-                       "fec_inner=%d guard_interval=%d\n", __func__,
-                       c->delivery_system, c->frequency, c->bandwidth_hz,
-                       c->modulation, c->inversion, c->fec_inner,
-                       c->guard_interval);
-
-       /* as for now we detect always params automatically */
-       auto_mode = true;
-
-       /* program tuner */
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-
-       /* get and program IF */
-       if (fe->ops.tuner_ops.get_if_frequency)
-               fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
-       else
-               if_freq = 0;
-
-       if (if_freq) {
-               /* normal IF */
-
-               /* calc IF control value */
-               num64 = if_freq;
-               num64 *= 0x800000;
-               num64 = div_u64(num64, HD29L2_XTAL);
-               num64 -= 0x800000;
-               if_ctl = num64;
-
-               tmp = 0xfc; /* tuner type normal */
-       } else {
-               /* zero IF */
-               if_ctl = 0;
-               tmp = 0xfe; /* tuner type Zero-IF */
-       }
-
-       buf[0] = ((if_ctl >>  0) & 0xff);
-       buf[1] = ((if_ctl >>  8) & 0xff);
-       buf[2] = ((if_ctl >> 16) & 0xff);
-
-       /* program IF control */
-       ret = hd29l2_wr_regs(priv, 0x14, buf, 3);
-       if (ret)
-               goto err;
-
-       /* program tuner type */
-       ret = hd29l2_wr_reg(priv, 0xab, tmp);
-       if (ret)
-               goto err;
-
-       dev_dbg(&priv->i2c->dev, "%s: if_freq=%d if_ctl=%x\n",
-                       __func__, if_freq, if_ctl);
-
-       if (auto_mode) {
-               /*
-                * use auto mode
-                */
-
-               /* disable quick mode */
-               ret = hd29l2_wr_reg_mask(priv, 0xac, 0 << 7, 0x80);
-               if (ret)
-                       goto err;
-
-               ret = hd29l2_wr_reg_mask(priv, 0x82, 1 << 1, 0x02);
-               if (ret)
-                       goto err;
-
-               /* enable auto mode */
-               ret = hd29l2_wr_reg_mask(priv, 0x7d, 1 << 6, 0x40);
-               if (ret)
-                       goto err;
-
-               ret = hd29l2_wr_reg_mask(priv, 0x81, 1 << 3, 0x08);
-               if (ret)
-                       goto err;
-
-               /* soft reset */
-               ret = hd29l2_soft_reset(priv);
-               if (ret)
-                       goto err;
-
-               /* detect modulation */
-               for (i = 30; i; i--) {
-                       msleep(100);
-
-                       ret = hd29l2_rd_reg(priv, 0x0d, &tmp);
-                       if (ret)
-                               goto err;
-
-                       if ((((tmp & 0xf0) >= 0x10) &&
-                               ((tmp & 0x0f) == 0x08)) || (tmp >= 0x2c))
-                               break;
-               }
-
-               dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-               if (i == 0)
-                       /* detection failed */
-                       return DVBFE_ALGO_SEARCH_FAILED;
-
-               /* read modulation */
-               ret = hd29l2_rd_reg_mask(priv, 0x7d, &modulation, 0x07);
-               if (ret)
-                       goto err;
-       } else {
-               /*
-                * use manual mode
-                */
-
-               modulation = HD29L2_QAM64;
-               carrier = HD29L2_CARRIER_MULTI;
-               guard_interval = HD29L2_PN945;
-               interleave = HD29L2_INTERLEAVER_420;
-               code_rate = HD29L2_CODE_RATE_08;
-
-               tmp = (code_rate << 3) | modulation;
-               ret = hd29l2_wr_reg_mask(priv, 0x7d, tmp, 0x5f);
-               if (ret)
-                       goto err;
-
-               tmp = (carrier << 2) | guard_interval;
-               ret = hd29l2_wr_reg_mask(priv, 0x81, tmp, 0x0f);
-               if (ret)
-                       goto err;
-
-               tmp = interleave;
-               ret = hd29l2_wr_reg_mask(priv, 0x82, tmp, 0x03);
-               if (ret)
-                       goto err;
-       }
-
-       /* ensure modulation validy */
-       /* 0=QAM4_NR, 1=QAM4, 2=QAM16, 3=QAM32, 4=QAM64 */
-       if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) {
-               dev_dbg(&priv->i2c->dev, "%s: modulation=%d not valid\n",
-                               __func__, modulation);
-               goto err;
-       }
-
-       /* program registers according to modulation */
-       for (i = 0; i < ARRAY_SIZE(reg_mod_vals_tab); i++) {
-               ret = hd29l2_wr_reg(priv, reg_mod_vals_tab[i].reg,
-                       reg_mod_vals_tab[i].val[modulation]);
-               if (ret)
-                       goto err;
-       }
-
-       /* read guard interval */
-       ret = hd29l2_rd_reg_mask(priv, 0x81, &guard_interval, 0x03);
-       if (ret)
-               goto err;
-
-       /* read carrier mode */
-       ret = hd29l2_rd_reg_mask(priv, 0x81, &carrier, 0x04);
-       if (ret)
-               goto err;
-
-       dev_dbg(&priv->i2c->dev,
-                       "%s: modulation=%d guard_interval=%d carrier=%d\n",
-                       __func__, modulation, guard_interval, carrier);
-
-       if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) &&
-               (guard_interval == HD29L2_PN945)) {
-               dev_dbg(&priv->i2c->dev, "%s: C=3780 && QAM64 && PN945\n",
-                               __func__);
-
-               ret = hd29l2_wr_reg(priv, 0x42, 0x33);
-               if (ret)
-                       goto err;
-
-               ret = hd29l2_wr_reg(priv, 0xdd, 0x01);
-               if (ret)
-                       goto err;
-       }
-
-       usleep_range(10000, 20000);
-
-       /* soft reset */
-       ret = hd29l2_soft_reset(priv);
-       if (ret)
-               goto err;
-
-       /* wait demod lock */
-       for (i = 30; i; i--) {
-               msleep(100);
-
-               /* read lock bit */
-               ret = hd29l2_rd_reg_mask(priv, 0x05, &tmp, 0x01);
-               if (ret)
-                       goto err;
-
-               if (tmp)
-                       break;
-       }
-
-       dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
-       if (i == 0)
-               return DVBFE_ALGO_SEARCH_AGAIN;
-
-       return DVBFE_ALGO_SEARCH_SUCCESS;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return DVBFE_ALGO_SEARCH_ERROR;
-}
-
-static int hd29l2_get_frontend_algo(struct dvb_frontend *fe)
-{
-       return DVBFE_ALGO_CUSTOM;
-}
-
-static int hd29l2_get_frontend(struct dvb_frontend *fe,
-                              struct dtv_frontend_properties *c)
-{
-       int ret;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 buf[3];
-       u32 if_ctl;
-       char *str_constellation, *str_code_rate, *str_constellation_code_rate,
-               *str_guard_interval, *str_carrier, *str_guard_interval_carrier,
-               *str_interleave, *str_interleave_;
-
-       ret = hd29l2_rd_reg(priv, 0x7d, &buf[0]);
-       if (ret)
-               goto err;
-
-       ret = hd29l2_rd_regs(priv, 0x81, &buf[1], 2);
-       if (ret)
-               goto err;
-
-       /* constellation, 0x7d[2:0] */
-       switch ((buf[0] >> 0) & 0x07) {
-       case 0: /* QAM4NR */
-               str_constellation = "QAM4NR";
-               c->modulation = QAM_AUTO; /* FIXME */
-               break;
-       case 1: /* QAM4 */
-               str_constellation = "QAM4";
-               c->modulation = QPSK; /* FIXME */
-               break;
-       case 2:
-               str_constellation = "QAM16";
-               c->modulation = QAM_16;
-               break;
-       case 3:
-               str_constellation = "QAM32";
-               c->modulation = QAM_32;
-               break;
-       case 4:
-               str_constellation = "QAM64";
-               c->modulation = QAM_64;
-               break;
-       default:
-               str_constellation = "?";
-       }
-
-       /* LDPC code rate, 0x7d[4:3] */
-       switch ((buf[0] >> 3) & 0x03) {
-       case 0: /* 0.4 */
-               str_code_rate = "0.4";
-               c->fec_inner = FEC_AUTO; /* FIXME */
-               break;
-       case 1: /* 0.6 */
-               str_code_rate = "0.6";
-               c->fec_inner = FEC_3_5;
-               break;
-       case 2: /* 0.8 */
-               str_code_rate = "0.8";
-               c->fec_inner = FEC_4_5;
-               break;
-       default:
-               str_code_rate = "?";
-       }
-
-       /* constellation & code rate set, 0x7d[6] */
-       switch ((buf[0] >> 6) & 0x01) {
-       case 0:
-               str_constellation_code_rate = "manual";
-               break;
-       case 1:
-               str_constellation_code_rate = "auto";
-               break;
-       default:
-               str_constellation_code_rate = "?";
-       }
-
-       /* frame header, 0x81[1:0] */
-       switch ((buf[1] >> 0) & 0x03) {
-       case 0: /* PN945 */
-               str_guard_interval = "PN945";
-               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
-               break;
-       case 1: /* PN595 */
-               str_guard_interval = "PN595";
-               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
-               break;
-       case 2: /* PN420 */
-               str_guard_interval = "PN420";
-               c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
-               break;
-       default:
-               str_guard_interval = "?";
-       }
-
-       /* carrier, 0x81[2] */
-       switch ((buf[1] >> 2) & 0x01) {
-       case 0:
-               str_carrier = "C=1";
-               break;
-       case 1:
-               str_carrier = "C=3780";
-               break;
-       default:
-               str_carrier = "?";
-       }
-
-       /* frame header & carrier set, 0x81[3] */
-       switch ((buf[1] >> 3) & 0x01) {
-       case 0:
-               str_guard_interval_carrier = "manual";
-               break;
-       case 1:
-               str_guard_interval_carrier = "auto";
-               break;
-       default:
-               str_guard_interval_carrier = "?";
-       }
-
-       /* interleave, 0x82[0] */
-       switch ((buf[2] >> 0) & 0x01) {
-       case 0:
-               str_interleave = "M=720";
-               break;
-       case 1:
-               str_interleave = "M=240";
-               break;
-       default:
-               str_interleave = "?";
-       }
-
-       /* interleave set, 0x82[1] */
-       switch ((buf[2] >> 1) & 0x01) {
-       case 0:
-               str_interleave_ = "manual";
-               break;
-       case 1:
-               str_interleave_ = "auto";
-               break;
-       default:
-               str_interleave_ = "?";
-       }
-
-       /*
-        * We can read out current detected NCO and use that value next
-        * time instead of calculating new value from targed IF.
-        * I think it will not effect receiver sensitivity but gaining lock
-        * after tune could be easier...
-        */
-       ret = hd29l2_rd_regs(priv, 0xb1, &buf[0], 3);
-       if (ret)
-               goto err;
-
-       if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2];
-
-       dev_dbg(&priv->i2c->dev, "%s: %s %s %s | %s %s %s | %s %s | NCO=%06x\n",
-                       __func__, str_constellation, str_code_rate,
-                       str_constellation_code_rate, str_guard_interval,
-                       str_carrier, str_guard_interval_carrier, str_interleave,
-                       str_interleave_, if_ctl);
-       return 0;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static int hd29l2_init(struct dvb_frontend *fe)
-{
-       int ret, i;
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       u8 tmp;
-       static const struct reg_val tab[] = {
-               { 0x3a, 0x06 },
-               { 0x3b, 0x03 },
-               { 0x3c, 0x04 },
-               { 0xaf, 0x06 },
-               { 0xb0, 0x1b },
-               { 0x80, 0x64 },
-               { 0x10, 0x38 },
-       };
-
-       dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
-
-       /* reset demod */
-       /* it is recommended to HW reset chip using RST_N pin */
-       if (fe->callback) {
-               ret = fe->callback(fe, DVB_FRONTEND_COMPONENT_DEMOD, 0, 0);
-               if (ret)
-                       goto err;
-
-               /* reprogramming needed because HW reset clears registers */
-               priv->tuner_i2c_addr_programmed = false;
-       }
-
-       /* init */
-       for (i = 0; i < ARRAY_SIZE(tab); i++) {
-               ret = hd29l2_wr_reg(priv, tab[i].reg, tab[i].val);
-               if (ret)
-                       goto err;
-       }
-
-       /* TS params */
-       ret = hd29l2_rd_reg(priv, 0x36, &tmp);
-       if (ret)
-               goto err;
-
-       tmp &= 0x1b;
-       tmp |= priv->cfg.ts_mode;
-       ret = hd29l2_wr_reg(priv, 0x36, tmp);
-       if (ret)
-               goto err;
-
-       ret = hd29l2_rd_reg(priv, 0x31, &tmp);
-       tmp &= 0xef;
-
-       if (!(priv->cfg.ts_mode >> 7))
-               /* set b4 for serial TS */
-               tmp |= 0x10;
-
-       ret = hd29l2_wr_reg(priv, 0x31, tmp);
-       if (ret)
-               goto err;
-
-       return ret;
-err:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       return ret;
-}
-
-static void hd29l2_release(struct dvb_frontend *fe)
-{
-       struct hd29l2_priv *priv = fe->demodulator_priv;
-       kfree(priv);
-}
-
-static const struct dvb_frontend_ops hd29l2_ops;
-
-struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
-       struct i2c_adapter *i2c)
-{
-       int ret;
-       struct hd29l2_priv *priv = NULL;
-       u8 tmp;
-
-       /* allocate memory for the internal state */
-       priv = kzalloc(sizeof(struct hd29l2_priv), GFP_KERNEL);
-       if (priv == NULL)
-               goto err;
-
-       /* setup the state */
-       priv->i2c = i2c;
-       memcpy(&priv->cfg, config, sizeof(struct hd29l2_config));
-
-
-       /* check if the demod is there */
-       ret = hd29l2_rd_reg(priv, 0x00, &tmp);
-       if (ret)
-               goto err;
-
-       /* create dvb_frontend */
-       memcpy(&priv->fe.ops, &hd29l2_ops, sizeof(struct dvb_frontend_ops));
-       priv->fe.demodulator_priv = priv;
-
-       return &priv->fe;
-err:
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(hd29l2_attach);
-
-static const struct dvb_frontend_ops hd29l2_ops = {
-       .delsys = { SYS_DVBT },
-       .info = {
-               .name = "HDIC HD29L2 DMB-TH",
-               .frequency_min = 474000000,
-               .frequency_max = 858000000,
-               .frequency_stepsize = 10000,
-               .caps = FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_QAM_16 |
-                       FE_CAN_QAM_32 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_BANDWIDTH_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_RECOVER
-       },
-
-       .release = hd29l2_release,
-
-       .init = hd29l2_init,
-
-       .get_frontend_algo = hd29l2_get_frontend_algo,
-       .search = hd29l2_search,
-       .get_frontend = hd29l2_get_frontend,
-
-       .read_status = hd29l2_read_status,
-       .read_snr = hd29l2_read_snr,
-       .read_signal_strength = hd29l2_read_signal_strength,
-       .read_ber = hd29l2_read_ber,
-       .read_ucblocks = hd29l2_read_ucblocks,
-
-       .i2c_gate_ctrl = hd29l2_i2c_gate_ctrl,
-};
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("HDIC HD29L2 DMB-TH demodulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/hd29l2.h b/drivers/media/dvb-frontends/hd29l2.h
deleted file mode 100644 (file)
index a14d6f3..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * HDIC HD29L2 DMB-TH demodulator driver
- *
- * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
- *
- * Author: Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef HD29L2_H
-#define HD29L2_H
-
-#include <linux/dvb/frontend.h>
-
-struct hd29l2_config {
-       /*
-        * demodulator I2C address
-        */
-       u8 i2c_addr;
-
-       /*
-        * tuner I2C address
-        * only needed when tuner is behind demod I2C-gate
-        */
-       u8 tuner_i2c_addr;
-
-       /*
-        * TS settings
-        */
-#define HD29L2_TS_SERIAL            0x00
-#define HD29L2_TS_PARALLEL          0x80
-#define HD29L2_TS_CLK_NORMAL        0x40
-#define HD29L2_TS_CLK_INVERTED      0x00
-#define HD29L2_TS_CLK_GATED         0x20
-#define HD29L2_TS_CLK_FREE          0x00
-       u8 ts_mode;
-};
-
-
-#if IS_REACHABLE(CONFIG_DVB_HD29L2)
-extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
-       struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend *hd29l2_attach(
-const struct hd29l2_config *config, struct i2c_adapter *i2c)
-{
-       pr_warn("%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* HD29L2_H */
diff --git a/drivers/media/dvb-frontends/hd29l2_priv.h b/drivers/media/dvb-frontends/hd29l2_priv.h
deleted file mode 100644 (file)
index 6dc225c..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * HDIC HD29L2 DMB-TH demodulator driver
- *
- * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
- *
- * Author: Antti Palosaari <crope@iki.fi>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef HD29L2_PRIV
-#define HD29L2_PRIV
-
-#include <linux/dvb/version.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
-#include "hd29l2.h"
-
-#define HD29L2_XTAL 30400000 /* Hz */
-
-
-#define HD29L2_QAM4NR 0x00
-#define HD29L2_QAM4   0x01
-#define HD29L2_QAM16  0x02
-#define HD29L2_QAM32  0x03
-#define HD29L2_QAM64  0x04
-
-#define HD29L2_CODE_RATE_04 0x00
-#define HD29L2_CODE_RATE_06 0x08
-#define HD29L2_CODE_RATE_08 0x10
-
-#define HD29L2_PN945 0x00
-#define HD29L2_PN595 0x01
-#define HD29L2_PN420 0x02
-
-#define HD29L2_CARRIER_SINGLE 0x00
-#define HD29L2_CARRIER_MULTI  0x01
-
-#define HD29L2_INTERLEAVER_720 0x00
-#define HD29L2_INTERLEAVER_420 0x01
-
-struct reg_val {
-       u8 reg;
-       u8 val;
-};
-
-struct reg_mod_vals {
-       u8 reg;
-       u8 val[5];
-};
-
-struct hd29l2_priv {
-       struct i2c_adapter *i2c;
-       struct dvb_frontend fe;
-       struct hd29l2_config cfg;
-       u8 tuner_i2c_addr_programmed:1;
-
-       enum fe_status fe_status;
-};
-
-static const struct reg_mod_vals reg_mod_vals_tab[] = {
-       /* REG, QAM4NR, QAM4,QAM16,QAM32,QAM64 */
-       { 0x01, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x02, { 0x07, 0x07, 0x07, 0x07, 0x07 } },
-       { 0x03, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x04, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x05, { 0x61, 0x60, 0x60, 0x61, 0x60 } },
-       { 0x06, { 0xff, 0xff, 0xff, 0xff, 0xff } },
-       { 0x07, { 0xff, 0xff, 0xff, 0xff, 0xff } },
-       { 0x08, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x09, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x0a, { 0x15, 0x15, 0x03, 0x03, 0x03 } },
-       { 0x0d, { 0x78, 0x78, 0x88, 0x78, 0x78 } },
-       { 0x0e, { 0xa0, 0x90, 0xa0, 0xa0, 0xa0 } },
-       { 0x0f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x10, { 0xa0, 0xa0, 0x58, 0x38, 0x38 } },
-       { 0x11, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x12, { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a } },
-       { 0x13, { 0xa2, 0xa2, 0xa2, 0xa2, 0xa2 } },
-       { 0x17, { 0x40, 0x40, 0x40, 0x40, 0x40 } },
-       { 0x18, { 0x21, 0x21, 0x42, 0x52, 0x42 } },
-       { 0x19, { 0x21, 0x21, 0x62, 0x72, 0x62 } },
-       { 0x1a, { 0x32, 0x43, 0xa9, 0xb9, 0xa9 } },
-       { 0x1b, { 0x32, 0x43, 0xb9, 0xd8, 0xb9 } },
-       { 0x1c, { 0x02, 0x02, 0x03, 0x02, 0x03 } },
-       { 0x1d, { 0x0c, 0x0c, 0x01, 0x02, 0x02 } },
-       { 0x1e, { 0x02, 0x02, 0x02, 0x01, 0x02 } },
-       { 0x1f, { 0x02, 0x02, 0x01, 0x02, 0x04 } },
-       { 0x20, { 0x01, 0x02, 0x01, 0x01, 0x01 } },
-       { 0x21, { 0x08, 0x08, 0x0a, 0x0a, 0x0a } },
-       { 0x22, { 0x06, 0x06, 0x04, 0x05, 0x05 } },
-       { 0x23, { 0x06, 0x06, 0x05, 0x03, 0x05 } },
-       { 0x24, { 0x08, 0x08, 0x05, 0x07, 0x07 } },
-       { 0x25, { 0x16, 0x10, 0x10, 0x0a, 0x10 } },
-       { 0x26, { 0x14, 0x14, 0x04, 0x04, 0x04 } },
-       { 0x27, { 0x58, 0x58, 0x58, 0x5c, 0x58 } },
-       { 0x28, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0x29, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0x2a, { 0x08, 0x0a, 0x08, 0x08, 0x08 } },
-       { 0x2b, { 0x08, 0x08, 0x08, 0x08, 0x08 } },
-       { 0x2c, { 0x06, 0x06, 0x06, 0x06, 0x06 } },
-       { 0x2d, { 0x05, 0x06, 0x06, 0x06, 0x06 } },
-       { 0x2e, { 0x21, 0x21, 0x21, 0x21, 0x21 } },
-       { 0x2f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x30, { 0x14, 0x14, 0x14, 0x14, 0x14 } },
-       { 0x33, { 0xb7, 0xb7, 0xb7, 0xb7, 0xb7 } },
-       { 0x34, { 0x81, 0x81, 0x81, 0x81, 0x81 } },
-       { 0x35, { 0x80, 0x80, 0x80, 0x80, 0x80 } },
-       { 0x37, { 0x70, 0x70, 0x70, 0x70, 0x70 } },
-       { 0x38, { 0x04, 0x04, 0x02, 0x02, 0x02 } },
-       { 0x39, { 0x07, 0x07, 0x05, 0x05, 0x05 } },
-       { 0x3a, { 0x06, 0x06, 0x06, 0x06, 0x06 } },
-       { 0x3b, { 0x03, 0x03, 0x03, 0x03, 0x03 } },
-       { 0x3c, { 0x07, 0x06, 0x04, 0x04, 0x04 } },
-       { 0x3d, { 0xf0, 0xf0, 0xf0, 0xf0, 0x80 } },
-       { 0x3e, { 0x60, 0x60, 0x60, 0x60, 0xff } },
-       { 0x3f, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x40, { 0x5b, 0x5b, 0x5b, 0x57, 0x50 } },
-       { 0x41, { 0x30, 0x30, 0x30, 0x30, 0x18 } },
-       { 0x42, { 0x20, 0x20, 0x20, 0x00, 0x30 } },
-       { 0x43, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x44, { 0x3f, 0x3f, 0x3f, 0x3f, 0x3f } },
-       { 0x45, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x46, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0x47, { 0x00, 0x00, 0x95, 0x00, 0x95 } },
-       { 0x48, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } },
-       { 0x49, { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 } },
-       { 0x4a, { 0x40, 0x40, 0x33, 0x11, 0x11 } },
-       { 0x4b, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x4c, { 0x40, 0x40, 0x99, 0x11, 0x11 } },
-       { 0x4d, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x4e, { 0x40, 0x40, 0x66, 0x77, 0x77 } },
-       { 0x4f, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x50, { 0x40, 0x40, 0x88, 0x33, 0x11 } },
-       { 0x51, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x52, { 0x40, 0x40, 0x88, 0x02, 0x02 } },
-       { 0x53, { 0x40, 0x40, 0x00, 0x02, 0x02 } },
-       { 0x54, { 0x00, 0x00, 0x88, 0x33, 0x33 } },
-       { 0x55, { 0x40, 0x40, 0x00, 0x00, 0x00 } },
-       { 0x56, { 0x00, 0x00, 0x00, 0x0b, 0x00 } },
-       { 0x57, { 0x40, 0x40, 0x0a, 0x0b, 0x0a } },
-       { 0x58, { 0xaa, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x59, { 0x7a, 0x40, 0x02, 0x02, 0x02 } },
-       { 0x5a, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5b, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5c, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5d, { 0x18, 0x18, 0x01, 0x01, 0x01 } },
-       { 0x5e, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } },
-       { 0x5f, { 0xc0, 0xc0, 0xc0, 0xff, 0xc0 } },
-       { 0x60, { 0x40, 0x40, 0x00, 0x30, 0x30 } },
-       { 0x61, { 0x40, 0x40, 0x10, 0x30, 0x30 } },
-       { 0x62, { 0x40, 0x40, 0x00, 0x30, 0x30 } },
-       { 0x63, { 0x40, 0x40, 0x05, 0x30, 0x30 } },
-       { 0x64, { 0x40, 0x40, 0x06, 0x00, 0x30 } },
-       { 0x65, { 0x40, 0x40, 0x06, 0x08, 0x30 } },
-       { 0x66, { 0x40, 0x40, 0x00, 0x00, 0x20 } },
-       { 0x67, { 0x40, 0x40, 0x01, 0x04, 0x20 } },
-       { 0x68, { 0x00, 0x00, 0x30, 0x00, 0x20 } },
-       { 0x69, { 0xa0, 0xa0, 0x00, 0x08, 0x20 } },
-       { 0x6a, { 0x00, 0x00, 0x30, 0x00, 0x25 } },
-       { 0x6b, { 0xa0, 0xa0, 0x00, 0x06, 0x25 } },
-       { 0x6c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x6d, { 0xa0, 0x60, 0x0c, 0x03, 0x0c } },
-       { 0x6e, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x6f, { 0xa0, 0x60, 0x04, 0x01, 0x04 } },
-       { 0x70, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } },
-       { 0x71, { 0x58, 0x58, 0xaa, 0xaa, 0xaa } },
-       { 0x72, { 0x58, 0x58, 0xff, 0xff, 0xff } },
-       { 0x73, { 0x58, 0x58, 0xff, 0xff, 0xff } },
-       { 0x74, { 0x06, 0x06, 0x09, 0x05, 0x05 } },
-       { 0x75, { 0x06, 0x06, 0x0a, 0x10, 0x10 } },
-       { 0x76, { 0x10, 0x10, 0x06, 0x0a, 0x0a } },
-       { 0x77, { 0x12, 0x18, 0x28, 0x10, 0x28 } },
-       { 0x78, { 0xf8, 0xf8, 0xf8, 0xf8, 0xf8 } },
-       { 0x79, { 0x15, 0x15, 0x03, 0x03, 0x03 } },
-       { 0x7a, { 0x02, 0x02, 0x01, 0x04, 0x03 } },
-       { 0x7b, { 0x01, 0x02, 0x03, 0x03, 0x03 } },
-       { 0x7c, { 0x28, 0x28, 0x28, 0x28, 0x28 } },
-       { 0x7f, { 0x25, 0x92, 0x5f, 0x17, 0x2d } },
-       { 0x80, { 0x64, 0x64, 0x64, 0x74, 0x64 } },
-       { 0x83, { 0x06, 0x03, 0x04, 0x04, 0x04 } },
-       { 0x84, { 0xff, 0xff, 0xff, 0xff, 0xff } },
-       { 0x85, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
-       { 0x86, { 0x00, 0x00, 0x11, 0x11, 0x11 } },
-       { 0x87, { 0x03, 0x03, 0x03, 0x03, 0x03 } },
-       { 0x88, { 0x09, 0x09, 0x09, 0x09, 0x09 } },
-       { 0x89, { 0x20, 0x20, 0x30, 0x20, 0x20 } },
-       { 0x8a, { 0x03, 0x03, 0x02, 0x03, 0x02 } },
-       { 0x8b, { 0x00, 0x07, 0x09, 0x00, 0x09 } },
-       { 0x8c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x8d, { 0x4f, 0x4f, 0x4f, 0x3f, 0x4f } },
-       { 0x8e, { 0xf0, 0xf0, 0x60, 0xf0, 0xa0 } },
-       { 0x8f, { 0xe8, 0xe8, 0xe8, 0xe8, 0xe8 } },
-       { 0x90, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x91, { 0x40, 0x40, 0x70, 0x70, 0x10 } },
-       { 0x92, { 0x00, 0x00, 0x00, 0x00, 0x04 } },
-       { 0x93, { 0x60, 0x60, 0x60, 0x60, 0x60 } },
-       { 0x94, { 0x00, 0x00, 0x00, 0x00, 0x03 } },
-       { 0x95, { 0x09, 0x09, 0x47, 0x47, 0x47 } },
-       { 0x96, { 0x80, 0xa0, 0xa0, 0x40, 0xa0 } },
-       { 0x97, { 0x60, 0x60, 0x60, 0x60, 0x60 } },
-       { 0x98, { 0x50, 0x50, 0x50, 0x30, 0x50 } },
-       { 0x99, { 0x10, 0x10, 0x10, 0x10, 0x10 } },
-       { 0x9a, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0x9b, { 0x40, 0x40, 0x40, 0x30, 0x40 } },
-       { 0x9c, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa0, { 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 } },
-       { 0xa1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa2, { 0x30, 0x30, 0x00, 0x30, 0x00 } },
-       { 0xa3, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa4, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa5, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xa8, { 0x77, 0x77, 0x77, 0x77, 0x77 } },
-       { 0xa9, { 0x02, 0x02, 0x02, 0x02, 0x02 } },
-       { 0xaa, { 0x40, 0x40, 0x40, 0x40, 0x40 } },
-       { 0xac, { 0x1f, 0x1f, 0x1f, 0x1f, 0x1f } },
-       { 0xad, { 0x14, 0x14, 0x14, 0x14, 0x14 } },
-       { 0xae, { 0x78, 0x78, 0x78, 0x78, 0x78 } },
-       { 0xaf, { 0x06, 0x06, 0x06, 0x06, 0x07 } },
-       { 0xb0, { 0x1b, 0x1b, 0x1b, 0x19, 0x1b } },
-       { 0xb1, { 0x18, 0x17, 0x17, 0x18, 0x17 } },
-       { 0xb2, { 0x35, 0x82, 0x82, 0x38, 0x82 } },
-       { 0xb3, { 0xb6, 0xce, 0xc7, 0x5c, 0xb0 } },
-       { 0xb4, { 0x3f, 0x3e, 0x3e, 0x3f, 0x3e } },
-       { 0xb5, { 0x70, 0x58, 0x50, 0x68, 0x50 } },
-       { 0xb6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xb7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xb8, { 0x03, 0x03, 0x01, 0x01, 0x01 } },
-       { 0xb9, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xba, { 0x06, 0x06, 0x0a, 0x05, 0x0a } },
-       { 0xbb, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbc, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbd, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbe, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xbf, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc3, { 0x00, 0x00, 0x88, 0x66, 0x88 } },
-       { 0xc4, { 0x10, 0x10, 0x00, 0x00, 0x00 } },
-       { 0xc5, { 0x00, 0x00, 0x44, 0x60, 0x44 } },
-       { 0xc6, { 0x10, 0x0a, 0x00, 0x00, 0x00 } },
-       { 0xc7, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc8, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xc9, { 0x90, 0x04, 0x00, 0x00, 0x00 } },
-       { 0xca, { 0x90, 0x08, 0x01, 0x01, 0x01 } },
-       { 0xcb, { 0xa0, 0x04, 0x00, 0x44, 0x00 } },
-       { 0xcc, { 0xa0, 0x10, 0x03, 0x00, 0x03 } },
-       { 0xcd, { 0x06, 0x06, 0x06, 0x05, 0x06 } },
-       { 0xce, { 0x05, 0x05, 0x01, 0x01, 0x01 } },
-       { 0xcf, { 0x40, 0x20, 0x18, 0x18, 0x18 } },
-       { 0xd0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd3, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xd4, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
-       { 0xd5, { 0x05, 0x05, 0x05, 0x03, 0x05 } },
-       { 0xd6, { 0xac, 0x22, 0xca, 0x8f, 0xca } },
-       { 0xd7, { 0x20, 0x20, 0x20, 0x20, 0x20 } },
-       { 0xd8, { 0x01, 0x01, 0x01, 0x01, 0x01 } },
-       { 0xd9, { 0x00, 0x00, 0x0f, 0x00, 0x0f } },
-       { 0xda, { 0x00, 0xff, 0xff, 0x0e, 0xff } },
-       { 0xdb, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xdc, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xdd, { 0x05, 0x05, 0x05, 0x05, 0x05 } },
-       { 0xde, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xdf, { 0x42, 0x42, 0x44, 0x44, 0x04 } },
-       { 0xe0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe1, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe2, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe3, { 0x00, 0x00, 0x26, 0x06, 0x26 } },
-       { 0xe4, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe5, { 0x01, 0x0a, 0x01, 0x01, 0x01 } },
-       { 0xe6, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xe7, { 0x08, 0x08, 0x08, 0x08, 0x08 } },
-       { 0xe8, { 0x63, 0x63, 0x63, 0x63, 0x63 } },
-       { 0xe9, { 0x59, 0x59, 0x59, 0x59, 0x59 } },
-       { 0xea, { 0x80, 0x80, 0x20, 0x80, 0x80 } },
-       { 0xeb, { 0x37, 0x37, 0x78, 0x37, 0x77 } },
-       { 0xec, { 0x1f, 0x1f, 0x25, 0x25, 0x25 } },
-       { 0xed, { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } },
-       { 0xee, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-       { 0xef, { 0x70, 0x70, 0x58, 0x38, 0x58 } },
-       { 0xf0, { 0x00, 0x00, 0x00, 0x00, 0x00 } },
-};
-
-#endif /* HD29L2_PRIV */
index 6913cd687b4d514d8c8063c526492619fd823fda..2fc8d3c72c118ff2fdcd7e326cdfbb10c5e1487a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 4a23d3bdf3e6b6200fb60ded487aa963bcc96c7b..18fe714f9999b27dba6ad7d231b41a298dbcafee 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 0b6d3837d5de52c0ecea33980a4c9f2afd3809ca..838b42771a05812c01e2d9f388e00512240030ca 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 00f9874ca5a28b61f8e2942041066d3456a477d7..4deeddec51403b1458ff345596435ae9f1b8faf3 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 4755251343278928c300e041c00229974d19cd5f..5bb1e73a10b4390c88a123b995e5181cbb04980a 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #include <linux/module.h>
index a691bb6f26de7d89f6b582b77120231a4efc1412..f8a2256a0b36477ac87e47d03399159b49310cc7 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef ITD1000_H
index 08ca851223c9ed92f814b5b98514be3ade4cf4cf..6c99d95d1056b51a3be326b33b4a8f5fbfdfcdeb 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef ITD1000_PRIV_H
index ca371680a69fd9ac5fc2d799d59845e1b4c53088..534b24fa2b95ae021dd4989091c312b8d1f4081e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <linux/module.h>
index 5eab39744b23558f4754a9a46bda197007cbc224..0b0a431c74f61a404c7c3c38dce035bc90a826b6 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef DVB_IX2505V_H
index 3b31e5f20f4668833ad7b7e878d16e5bedc842f0..5798079add1029f7ad4d751336537f06c3b84c2d 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <linux/jiffies.h>
index 8c74ddc6b88a1a138f288d2509bef7cbf40445f2..ba99125deac0f41176da3a61b01d34ab525e8dd2 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _LG2160_H_
index 9f5d9380bf5f1eeb3450982c4fa6c7992a8a476f..0af4d910476135a14be0e52532fbee8e3b8b9b45 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <asm/div64.h>
index e7dceb60e5727a89934afd2fc58cb6a69dbb7e8b..2fb60d91f7b4e81cbda38e5d5b37c017e319765c 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _LGDT3305_H_
index 19dca46b1171c516a6252b08d7153bd9e35e2616..c9b1eb38444e8cc199aeffa2c96244b141663b7d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/dvb/frontend.h>
 #include "dvb_math.h"
 #include "lgdt3306a.h"
+#include <linux/i2c-mux.h>
 
 
 static int debug;
@@ -65,6 +66,8 @@ struct lgdt3306a_state {
        enum fe_modulation current_modulation;
        u32 current_frequency;
        u32 snr;
+
+       struct i2c_mux_core *muxc;
 };
 
 /*
@@ -2131,6 +2134,111 @@ static const struct dvb_frontend_ops lgdt3306a_ops = {
        .search               = lgdt3306a_search,
 };
 
+static int lgdt3306a_select(struct i2c_mux_core *muxc, u32 chan)
+{
+       struct i2c_client *client = i2c_mux_priv(muxc);
+       struct lgdt3306a_state *state = i2c_get_clientdata(client);
+
+       return lgdt3306a_i2c_gate_ctrl(&state->frontend, 1);
+}
+
+static int lgdt3306a_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+       struct i2c_client *client = i2c_mux_priv(muxc);
+       struct lgdt3306a_state *state = i2c_get_clientdata(client);
+
+       return lgdt3306a_i2c_gate_ctrl(&state->frontend, 0);
+}
+
+static int lgdt3306a_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+{
+       struct lgdt3306a_config *config;
+       struct lgdt3306a_state *state;
+       struct dvb_frontend *fe;
+       int ret;
+
+       config = kzalloc(sizeof(struct lgdt3306a_config), GFP_KERNEL);
+       if (config == NULL) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       memcpy(config, client->dev.platform_data,
+                       sizeof(struct lgdt3306a_config));
+
+       config->i2c_addr = client->addr;
+       fe = lgdt3306a_attach(config, client->adapter);
+       if (fe == NULL) {
+               ret = -ENODEV;
+               goto err_fe;
+       }
+
+       i2c_set_clientdata(client, fe->demodulator_priv);
+       state = fe->demodulator_priv;
+
+       /* create mux i2c adapter for tuner */
+       state->muxc = i2c_mux_alloc(client->adapter, &client->dev,
+                                 1, 0, I2C_MUX_LOCKED,
+                                 lgdt3306a_select, lgdt3306a_deselect);
+       if (!state->muxc) {
+               ret = -ENOMEM;
+               goto err_kfree;
+       }
+       state->muxc->priv = client;
+       ret = i2c_mux_add_adapter(state->muxc, 0, 0, 0);
+       if (ret)
+               goto err_kfree;
+
+       /* create dvb_frontend */
+       fe->ops.i2c_gate_ctrl = NULL;
+       *config->i2c_adapter = state->muxc->adapter[0];
+       *config->fe = fe;
+
+       return 0;
+
+err_kfree:
+       kfree(state);
+err_fe:
+       kfree(config);
+fail:
+       dev_dbg(&client->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int lgdt3306a_remove(struct i2c_client *client)
+{
+       struct lgdt3306a_state *state = i2c_get_clientdata(client);
+
+       i2c_mux_del_adapters(state->muxc);
+
+       state->frontend.ops.release = NULL;
+       state->frontend.demodulator_priv = NULL;
+
+       kfree(state->cfg);
+       kfree(state);
+
+       return 0;
+}
+
+static const struct i2c_device_id lgdt3306a_id_table[] = {
+       {"lgdt3306a", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, lgdt3306a_id_table);
+
+static struct i2c_driver lgdt3306a_driver = {
+       .driver = {
+               .name                = "lgdt3306a",
+               .suppress_bind_attrs = true,
+       },
+       .probe          = lgdt3306a_probe,
+       .remove         = lgdt3306a_remove,
+       .id_table       = lgdt3306a_id_table,
+};
+
+module_i2c_driver(lgdt3306a_driver);
+
 MODULE_DESCRIPTION("LG Electronics LGDT3306A ATSC/QAM-B Demodulator Driver");
 MODULE_AUTHOR("Fred Richter <frichter@hauppauge.com>");
 MODULE_LICENSE("GPL");
index 9dbb2dced1fe49e08dc3b6b126d4ae16a38e2be0..6ce337ec5272138469cd2fd1de1713377873a265 100644 (file)
@@ -56,6 +56,10 @@ struct lgdt3306a_config {
 
        /* demod clock freq in MHz; 24 or 25 supported */
        int  xtalMHz;
+
+       /* returned by driver if using i2c bus multiplexing */
+       struct dvb_frontend **fe;
+       struct i2c_adapter **i2c_adapter;
 };
 
 #if IS_REACHABLE(CONFIG_DVB_LGDT3306A)
index 2f4a0316f89c4d6f274d5316994c26816ba4a134..06f47dc8cd3d014c34b026a89f227a7b62224951 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 /*
index c73eeb45e3305cf3ea043df4b119d8183549cc03..61434cbecd2c5519bb83c22b5be9d57df3b7d4d9 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef LGDT330X_H
index 1922f09a02d07d601db33a7241b51cde2a064781..dcb9a317eddc6f5bf6bd7319dce450855be91e15 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _LGDT330X_PRIV_
index 6d2e62469d58fb21276dc2eb10f5ad32bfdac667..e6bf60e1138cc8ce757e4d76d887bbf5b6f64497 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <asm/div64.h>
index 7519c02103995ea818ab542bc98abc70ad586579..aa83ea46807bee262559ef34b8d1e0427a032ad0 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef __LGS8GXX_H__
index 8ef376f1414de30c6d078a47e36d05717767b9ec..42ecbbd14c90a0665ee3006b8716dc6365369572 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef LGS8913_PRIV_H
index 24431dfdce1fa7273b63b1421d3dcadc5bb05fd1..332d639025ba085e8692c93dc4a456a004cc927a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _LNBH24_H
index 6261460d93a7f069e9b2e06a5e6972d413a5ef77..392d7be9377412bf83ad64a2c34ebcb4374e9c20 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 4bb6439068ecca8b77263a21f79bcd94199c6da6..ee9d050ddc0415c450afcb4a6d14469bbff96216 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 5c5fd04fd4a73dfacc3fb867eb32ee0f6a669bdd..39326a2ebab2746ef6df616f2b42e5d09375a80e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 0cb72126c498d9294e33d10d12ed7bd17ae776b7..f4c59ff7b7caa7d496a4c22bb09c7184a084aa09 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index c221c7d2ac3eabc268d91808cbf7e642560997af..15874244fd8b2054cc9a4697f7279b77a84b05b7 100644 (file)
@@ -223,6 +223,13 @@ static int mn88473_set_frontend(struct dvb_frontend *fe)
        if (ret)
                goto err;
 
+       /* PLP */
+       if (c->delivery_system == SYS_DVBT2) {
+               ret = regmap_write(dev->regmap[2], 0x36, c->stream_id);
+               if (ret)
+                       goto err;
+       }
+
        /* Reset FSM */
        ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
        if (ret)
@@ -592,7 +599,8 @@ static const struct dvb_frontend_ops mn88473_ops = {
                        FE_CAN_GUARD_INTERVAL_AUTO     |
                        FE_CAN_HIERARCHY_AUTO          |
                        FE_CAN_MUTE_TS                 |
-                       FE_CAN_2G_MODULATION
+                       FE_CAN_2G_MODULATION           |
+                       FE_CAN_MULTISTREAM
        },
 
        .get_tune_settings = mn88473_get_tune_settings,
index 48ea0408f02adb2397d76d44a3d7502cd967e7a8..e127090f2d228a0a86b4c16121df32bb047978c2 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #include <linux/kernel.h>
index 5873263bd1af16fdaf5c6b9fd9638cc870ba9b82..b4c03b7405fb92a6e4fa0c0725e67de7b30d2770 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef MT352_H
index 44ad0d4c8f12b2a2057cc7fd2fa6e7e2da96e768..79bbb894b2876ab6fcdea06ecd6b909af354b036 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef _MT352_PRIV_
index 2fe40372ca07520ae43c1daf493d529daf54aa17..bf6e5cd572c55f831eb10fdaef0ad927a2688489 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
 */
 
 /*
index 825b928ef54235958e58020f9a4afc0cc4c6f613..36032064591356529613c577a839ed436b92d2b7 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
 */
 
 #ifndef NXT200X_H
index 17bdadd7d0e1a53e2a31a4c8878acb7e242b937d..4b67d7e0116d615116d7e2ac736c09391ef6e793 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
 */
 
 /*
index 9acf8dc87413283be5a55a00f6dc1446d72bf73f..96b70e78e30a281d9311db759fb30bc9188ec14e 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
 */
 
 #ifndef OR51132_H
index 27eb73aa4f6283a49fd1e190c49451836174e38d..d14fa9736ae526c848e785887742db2dac847ab4 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
 */
 
 #define pr_fmt(fmt)    KBUILD_MODNAME ": %s: " fmt, __func__
index cc6adab63249bbb9041a32ac2fd21d1fe21817a7..03b476982ad0860a7a1e5b8b63572003c6c29046 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
 */
 
 #ifndef OR51211_H
index e038e886731b1326d584d2fcc767492f3d0e9f85..c6e78d870ccdc222ce20aac7d30f5a8c223f8988 100644 (file)
@@ -956,7 +956,7 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
        mutex_unlock(&dev->v4l2_lock);
 }
 
-static struct vb2_ops rtl2832_sdr_vb2_ops = {
+static const struct vb2_ops rtl2832_sdr_vb2_ops = {
        .queue_setup            = rtl2832_sdr_queue_setup,
        .buf_prepare            = rtl2832_sdr_buf_prepare,
        .buf_queue              = rtl2832_sdr_buf_queue,
index f9a18fe94d88c5324ddd321e30912dbfb59210c5..cba9bff05b1245d4d02ddb53df4bfacdb4b7e679 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index 142d93e7d02bf27f257bfcea7b5497caba6050b9..43d0de6f3a55f81942e7fad1b4b9437c49bd7130 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef S5H1420_H
 #define S5H1420_H
index a32fd9bc51a93130474e0bde07e1a36e89100118..4de50fe0c638db2a0fb9fb9f6af6b097e53953e7 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index b81c9bd4e422388d3f8c3b94d31c31d37d88ef38..af3a157b5e77f1d81004359e456a330b17457920 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef __S5H1432_H__
index 20b4a659e2e459dd9f536566f60c8fdda300eaa4..680ba06c29fb57610b6804d9b233f7a4458ada23 100644 (file)
@@ -85,7 +85,8 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status)
        struct i2c_client *client = fe->demodulator_priv;
        struct si2168_dev *dev = i2c_get_clientdata(client);
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
+       int ret, i;
+       unsigned int utmp, utmp1, utmp2;
        struct si2168_cmd cmd;
 
        *status = 0;
@@ -144,6 +145,61 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status)
        dev_dbg(&client->dev, "status=%02x args=%*ph\n",
                        *status, cmd.rlen, cmd.args);
 
+       /* BER */
+       if (*status & FE_HAS_VITERBI) {
+               memcpy(cmd.args, "\x82\x00", 2);
+               cmd.wlen = 2;
+               cmd.rlen = 3;
+               ret = si2168_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               /*
+                * Firmware returns [0, 255] mantissa and [0, 8] exponent.
+                * Convert to DVB API: mantissa * 10^(8 - exponent) / 10^8
+                */
+               utmp = clamp(8 - cmd.args[1], 0, 8);
+               for (i = 0, utmp1 = 1; i < utmp; i++)
+                       utmp1 = utmp1 * 10;
+
+               utmp1 = cmd.args[2] * utmp1;
+               utmp2 = 100000000; /* 10^8 */
+
+               dev_dbg(&client->dev,
+                       "post_bit_error=%u post_bit_count=%u ber=%u*10^-%u\n",
+                       utmp1, utmp2, cmd.args[2], cmd.args[1]);
+
+               c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+               c->post_bit_error.stat[0].uvalue += utmp1;
+               c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+               c->post_bit_count.stat[0].uvalue += utmp2;
+       } else {
+               c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+               c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       }
+
+       /* UCB */
+       if (*status & FE_HAS_SYNC) {
+               memcpy(cmd.args, "\x84\x01", 2);
+               cmd.wlen = 2;
+               cmd.rlen = 3;
+               ret = si2168_cmd_execute(client, &cmd);
+               if (ret)
+                       goto err;
+
+               utmp1 = cmd.args[2] << 8 | cmd.args[1] << 0;
+               dev_dbg(&client->dev, "block_error=%u\n", utmp1);
+
+               /* Sometimes firmware returns bogus value */
+               if (utmp1 == 0xffff)
+                       utmp1 = 0;
+
+               c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+               c->block_error.stat[0].uvalue += utmp1;
+       } else {
+               c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       }
+
        return 0;
 err:
        dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -355,6 +411,7 @@ static int si2168_init(struct dvb_frontend *fe)
 {
        struct i2c_client *client = fe->demodulator_priv;
        struct si2168_dev *dev = i2c_get_clientdata(client);
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        int ret, len, remaining;
        const struct firmware *fw;
        struct si2168_cmd cmd;
@@ -493,10 +550,19 @@ static int si2168_init(struct dvb_frontend *fe)
 
        dev->warm = true;
 warm:
+       /* Init stats here to indicate which stats are supported */
+       c->cnr.len = 1;
+       c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       c->post_bit_error.len = 1;
+       c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       c->post_bit_count.len = 1;
+       c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+       c->block_error.len = 1;
+       c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
        dev->active = true;
 
        return 0;
-
 err_release_firmware:
        release_firmware(fw);
 err:
index 7843ccb448a088d097ea1fe95542dc4785a2e28a..2fecac6231ff47dce1cb6c71fd9147fe4d975f24 100644 (file)
@@ -21,6 +21,7 @@
 #include "dvb_frontend.h"
 #include <linux/firmware.h>
 #include <linux/i2c-mux.h>
+#include <linux/kernel.h>
 
 #define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
 #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
index 4ac1ce2831bae9fd13341664a1ad38af6e6d93c9..fd49c436a36d16fc206e43d579414c4db3f817bb 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index b88166a9716faf40c1ffefd14ffc9dbc27209c5a..26c38a0503c8b5990367bf51f8392983e4acc252 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef STV0367_H
index 89bf6f64b078b7d7a6898ec77f5a183fe2f28bd3..8abc451dd5243e11950e47dc7bec81c35d78214e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 /* Common driver error constants */
 
index a96fbdc7e25e79794803784446be86215ba931c1..1d158622123953c7c531eb073ba4d9705498b940 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef STV0367_REGS_H
index 9ca2da90c7d7605f97d5c68537a43b742be1fe36..1571a465e05c4f93593c1dc1635b8940d406eaeb 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef STV0900_H
index 43a0f69b4b1449461a4983885fd49d561ac9f3fb..0b739725e3c0c06c9fb14f42ed09e5322a613968 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index b684df9995d82d5e4baf8574c5ffbc9110215319..411941442086e4d5abc806f6029328ec7ed11652 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef STV0900_INIT_H
index e0ea74c8e09327cf7813650f06144770325be971..7a95f955627b8fdc8882fc7ed6110ec17528227b 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef STV0900_PRIV_H
index 511ed2a2d987da24fef2035a88c813c8b0eb5a2b..59f264c2f8f5909325fd449926e104917b69bf93 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef STV0900_REG_H
index bded82774f4b5405ae1b27c47d6f4965019c49b4..c97a39120ea5eaa77cfe21a264dc915d49954bfd 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "stv0900.h"
index 6a72d0be2ec50516b5603912f9198d40d4ef5877..e4fd9c1b05606dccdd5c32a68f90c27fcb92a69e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/slab.h>
index 4604f793d954d7cdaf3fad52acd85fb0ce60db49..ab73124c0dec2a3eb51863af1eaec6d6318b907f 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __DVB_STV6110_H__
index 6859fa5d5a85b799ad90344f532e0d0be3c2c869..2d2778be2d2fb905e3ab449961b099eed89537b2 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/kernel.h>
index 2b9e8732c8024d30fe263bbe7e82ed1fb1f141cb..68358c0d869fe79c1fdf27fbba1b8ef19725ba6a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * The project's page is at https://linuxtv.org
index 05ee16d29851fe1dcb4cadf42ff8976ed1b74cac..18e6d4c5be21ce75c0d6afbf714cf5d11406b67a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/slab.h>
index 52919e04e25852b35f7e85d6c86425d02dbfe12d..9f15cbdfdeca98b85ec4b28245ca13c1ed557a4c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __DVB_TUA6100_H__
diff --git a/drivers/media/dvb-frontends/zd1301_demod.c b/drivers/media/dvb-frontends/zd1301_demod.c
new file mode 100644 (file)
index 0000000..fcf5f69
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * ZyDAS ZD1301 driver (demodulator)
+ *
+ * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "zd1301_demod.h"
+
+static u8 zd1301_demod_gain = 0x38;
+module_param_named(gain, zd1301_demod_gain, byte, 0644);
+MODULE_PARM_DESC(gain, "gain (value: 0x00 - 0x70, default: 0x38)");
+
+struct zd1301_demod_dev {
+       struct platform_device *pdev;
+       struct dvb_frontend frontend;
+       struct i2c_adapter adapter;
+       u8 gain;
+};
+
+static int zd1301_demod_wreg(struct zd1301_demod_dev *dev, u16 reg, u8 val)
+{
+       struct platform_device *pdev = dev->pdev;
+       struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
+
+       return pdata->reg_write(pdata->reg_priv, reg, val);
+}
+
+static int zd1301_demod_rreg(struct zd1301_demod_dev *dev, u16 reg, u8 *val)
+{
+       struct platform_device *pdev = dev->pdev;
+       struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
+
+       return pdata->reg_read(pdata->reg_priv, reg, val);
+}
+
+static int zd1301_demod_set_frontend(struct dvb_frontend *fe)
+{
+       struct zd1301_demod_dev *dev = fe->demodulator_priv;
+       struct platform_device *pdev = dev->pdev;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+       u32 if_frequency;
+       u8 r6a50_val;
+
+       dev_dbg(&pdev->dev, "frequency=%u bandwidth_hz=%u\n",
+               c->frequency, c->bandwidth_hz);
+
+       /* Program tuner */
+       if (fe->ops.tuner_ops.set_params &&
+           fe->ops.tuner_ops.get_if_frequency) {
+               ret = fe->ops.tuner_ops.set_params(fe);
+               if (ret)
+                       goto err;
+               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+               if (ret)
+                       goto err;
+       } else {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       dev_dbg(&pdev->dev, "if_frequency=%u\n", if_frequency);
+       if (if_frequency != 36150000) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               r6a50_val = 0x78;
+               break;
+       case 7000000:
+               r6a50_val = 0x68;
+               break;
+       case 8000000:
+               r6a50_val = 0x58;
+               break;
+       default:
+               ret = -EINVAL;
+               goto err;
+       }
+
+       ret = zd1301_demod_wreg(dev, 0x6a60, 0x11);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a47, 0x46);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a48, 0x46);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a4a, 0x15);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a4b, 0x63);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a5b, 0x99);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a3b, 0x10);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6806, 0x01);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a41, 0x08);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a42, 0x46);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a44, 0x14);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a45, 0x67);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a38, 0x00);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a4c, 0x52);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a49, 0x2a);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6840, 0x2e);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a50, r6a50_val);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&pdev->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_demod_sleep(struct dvb_frontend *fe)
+{
+       struct zd1301_demod_dev *dev = fe->demodulator_priv;
+       struct platform_device *pdev = dev->pdev;
+       int ret;
+
+       dev_dbg(&pdev->dev, "\n");
+
+       ret = zd1301_demod_wreg(dev, 0x6a43, 0x70);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x684e, 0x00);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6849, 0x00);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x68e2, 0xd7);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x68e0, 0x39);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&pdev->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_demod_init(struct dvb_frontend *fe)
+{
+       struct zd1301_demod_dev *dev = fe->demodulator_priv;
+       struct platform_device *pdev = dev->pdev;
+       int ret;
+
+       dev_dbg(&pdev->dev, "\n");
+
+       ret = zd1301_demod_wreg(dev, 0x6840, 0x26);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x68e0, 0xff);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x68e2, 0xd8);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6849, 0x4e);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x684e, 0x01);
+       if (ret)
+               goto err;
+       ret = zd1301_demod_wreg(dev, 0x6a43, zd1301_demod_gain);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&pdev->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_demod_get_tune_settings(struct dvb_frontend *fe,
+                                         struct dvb_frontend_tune_settings *settings)
+{
+       struct zd1301_demod_dev *dev = fe->demodulator_priv;
+       struct platform_device *pdev = dev->pdev;
+
+       dev_dbg(&pdev->dev, "\n");
+
+       /* ~180ms seems to be enough */
+       settings->min_delay_ms = 400;
+
+       return 0;
+}
+
+static int zd1301_demod_read_status(struct dvb_frontend *fe,
+                                   enum fe_status *status)
+{
+       struct zd1301_demod_dev *dev = fe->demodulator_priv;
+       struct platform_device *pdev = dev->pdev;
+       int ret;
+       u8 u8tmp;
+
+       ret = zd1301_demod_rreg(dev, 0x6a24, &u8tmp);
+       if (ret)
+               goto err;
+       if (u8tmp > 0x00 && u8tmp < 0x20)
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+                         FE_HAS_SYNC | FE_HAS_LOCK;
+       else
+               *status = 0;
+
+       dev_dbg(&pdev->dev, "lock byte=%02x\n", u8tmp);
+
+       /*
+        * Interesting registers here are:
+        * 0x6a05: get some gain value
+        * 0x6a06: get about same gain value than set to 0x6a43
+        * 0x6a07: get some gain value
+        * 0x6a43: set gain value by driver
+        * 0x6a24: get demod lock bits (FSM stage?)
+        *
+        * Driver should implement some kind of algorithm to calculate suitable
+        * value for register 0x6a43, based likely values from register 0x6a05
+        * and 0x6a07. Looks like gain register 0x6a43 value could be from
+        * range 0x00 - 0x70.
+        */
+
+       if (dev->gain != zd1301_demod_gain) {
+               dev->gain = zd1301_demod_gain;
+
+               ret = zd1301_demod_wreg(dev, 0x6a43, dev->gain);
+               if (ret)
+                       goto err;
+       }
+
+       return 0;
+err:
+       dev_dbg(&pdev->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static const struct dvb_frontend_ops zd1301_demod_ops = {
+       .delsys = {SYS_DVBT},
+       .info = {
+               .name = "ZyDAS ZD1301",
+               .caps = FE_CAN_FEC_1_2 |
+                       FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 |
+                       FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK |
+                       FE_CAN_QAM_16 |
+                       FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO |
+                       FE_CAN_MUTE_TS
+       },
+
+       .sleep = zd1301_demod_sleep,
+       .init = zd1301_demod_init,
+       .set_frontend = zd1301_demod_set_frontend,
+       .get_tune_settings = zd1301_demod_get_tune_settings,
+       .read_status = zd1301_demod_read_status,
+};
+
+struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *pdev)
+{
+       struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
+
+       dev_dbg(&pdev->dev, "\n");
+
+       return &dev->frontend;
+}
+EXPORT_SYMBOL(zd1301_demod_get_dvb_frontend);
+
+static int zd1301_demod_i2c_master_xfer(struct i2c_adapter *adapter,
+                                       struct i2c_msg msg[], int num)
+{
+       struct zd1301_demod_dev *dev = i2c_get_adapdata(adapter);
+       struct platform_device *pdev = dev->pdev;
+       int ret, i;
+       unsigned long timeout;
+       u8 u8tmp;
+
+       #define I2C_XFER_TIMEOUT 5
+       #define ZD1301_IS_I2C_XFER_WRITE_READ(_msg, _num) \
+               (_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD))
+       #define ZD1301_IS_I2C_XFER_WRITE(_msg, _num) \
+               (_num == 1 && !(_msg[0].flags & I2C_M_RD))
+       #define ZD1301_IS_I2C_XFER_READ(_msg, _num) \
+               (_num == 1 && (_msg[0].flags & I2C_M_RD))
+       if (ZD1301_IS_I2C_XFER_WRITE_READ(msg, num)) {
+               dev_dbg(&pdev->dev, "write&read msg[0].len=%u msg[1].len=%u\n",
+                       msg[0].len, msg[1].len);
+               if (msg[0].len > 1 || msg[1].len > 8) {
+                       ret = -EOPNOTSUPP;
+                       goto err;
+               }
+
+               ret = zd1301_demod_wreg(dev, 0x6811, 0x80);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6812, 0x05);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6813, msg[1].addr << 1);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6801, msg[0].buf[0]);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6805, 0x00);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6804, msg[1].len);
+               if (ret)
+                       goto err;
+
+               /* Poll xfer ready */
+               timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
+               for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
+                       usleep_range(500, 800);
+
+                       ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
+                       if (ret)
+                               goto err;
+               }
+
+               for (i = 0; i < msg[1].len; i++) {
+                       ret = zd1301_demod_rreg(dev, 0x0600 + i, &msg[1].buf[i]);
+                       if (ret)
+                               goto err;
+               }
+       } else if (ZD1301_IS_I2C_XFER_WRITE(msg, num)) {
+               dev_dbg(&pdev->dev, "write msg[0].len=%u\n", msg[0].len);
+               if (msg[0].len > 1 + 8) {
+                       ret = -EOPNOTSUPP;
+                       goto err;
+               }
+
+               ret = zd1301_demod_wreg(dev, 0x6811, 0x80);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6812, 0x01);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6813, msg[0].addr << 1);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6800, msg[0].buf[0]);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
+               if (ret)
+                       goto err;
+
+               for (i = 0; i < msg[0].len - 1; i++) {
+                       ret = zd1301_demod_wreg(dev, 0x0600 + i, msg[0].buf[1 + i]);
+                       if (ret)
+                               goto err;
+               }
+
+               ret = zd1301_demod_wreg(dev, 0x6805, 0x80);
+               if (ret)
+                       goto err;
+               ret = zd1301_demod_wreg(dev, 0x6804, msg[0].len - 1);
+               if (ret)
+                       goto err;
+
+               /* Poll xfer ready */
+               timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
+               for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
+                       usleep_range(500, 800);
+
+                       ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
+                       if (ret)
+                               goto err;
+               }
+       } else {
+               dev_dbg(&pdev->dev, "unknown msg[0].len=%u\n", msg[0].len);
+               ret = -EOPNOTSUPP;
+               if (ret)
+                       goto err;
+       }
+
+       return num;
+err:
+       dev_dbg(&pdev->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static u32 zd1301_demod_i2c_functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm zd1301_demod_i2c_algorithm = {
+       .master_xfer   = zd1301_demod_i2c_master_xfer,
+       .functionality = zd1301_demod_i2c_functionality,
+};
+
+struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *pdev)
+{
+       struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
+
+       dev_dbg(&pdev->dev, "\n");
+
+       return &dev->adapter;
+}
+EXPORT_SYMBOL(zd1301_demod_get_i2c_adapter);
+
+/* Platform driver interface */
+static int zd1301_demod_probe(struct platform_device *pdev)
+{
+       struct zd1301_demod_dev *dev;
+       struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
+       int ret;
+
+       dev_dbg(&pdev->dev, "\n");
+
+       if (!pdata) {
+               ret = -EINVAL;
+               dev_err(&pdev->dev, "cannot proceed without platform data\n");
+               goto err;
+       }
+       if (!pdev->dev.parent->driver) {
+               ret = -EINVAL;
+               dev_dbg(&pdev->dev, "no parent device\n");
+               goto err;
+       }
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       /* Setup the state */
+       dev->pdev = pdev;
+       dev->gain = zd1301_demod_gain;
+
+       /* Sleep */
+       ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
+       if (ret)
+               goto err_kfree;
+       ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
+       if (ret)
+               goto err_kfree;
+
+       /* Create I2C adapter */
+       strlcpy(dev->adapter.name, "ZyDAS ZD1301 demod", sizeof(dev->adapter.name));
+       dev->adapter.algo = &zd1301_demod_i2c_algorithm;
+       dev->adapter.algo_data = NULL;
+       dev->adapter.dev.parent = pdev->dev.parent;
+       i2c_set_adapdata(&dev->adapter, dev);
+       ret = i2c_add_adapter(&dev->adapter);
+       if (ret) {
+               dev_err(&pdev->dev, "I2C adapter add failed %d\n", ret);
+               goto err_kfree;
+       }
+
+       /* Create dvb frontend */
+       memcpy(&dev->frontend.ops, &zd1301_demod_ops, sizeof(dev->frontend.ops));
+       dev->frontend.demodulator_priv = dev;
+       platform_set_drvdata(pdev, dev);
+       dev_info(&pdev->dev, "ZyDAS ZD1301 demod attached\n");
+
+       return 0;
+err_kfree:
+       kfree(dev);
+err:
+       dev_dbg(&pdev->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_demod_remove(struct platform_device *pdev)
+{
+       struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
+
+       dev_dbg(&pdev->dev, "\n");
+
+       i2c_del_adapter(&dev->adapter);
+       kfree(dev);
+
+       return 0;
+}
+
+static struct platform_driver zd1301_demod_driver = {
+       .driver = {
+               .name                = "zd1301_demod",
+               .suppress_bind_attrs = true,
+       },
+       .probe          = zd1301_demod_probe,
+       .remove         = zd1301_demod_remove,
+};
+module_platform_driver(zd1301_demod_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("ZyDAS ZD1301 demodulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/zd1301_demod.h b/drivers/media/dvb-frontends/zd1301_demod.h
new file mode 100644 (file)
index 0000000..ceb2e05
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * ZyDAS ZD1301 driver (demodulator)
+ *
+ * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef ZD1301_DEMOD_H
+#define ZD1301_DEMOD_H
+
+#include <linux/platform_device.h>
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+/**
+ * struct zd1301_demod_platform_data - Platform data for the zd1301_demod driver
+ * @reg_priv: First argument of reg_read and reg_write callbacks.
+ * @reg_read: Register read callback.
+ * @reg_write: Register write callback.
+ */
+
+struct zd1301_demod_platform_data {
+       void *reg_priv;
+       int (*reg_read)(void *, u16, u8 *);
+       int (*reg_write)(void *, u16, u8);
+};
+
+#if IS_REACHABLE(CONFIG_DVB_ZD1301_DEMOD)
+/**
+ * zd1301_demod_get_dvb_frontend() - Get pointer to DVB frontend
+ * @pdev: Pointer to platform device
+ *
+ * Return: Pointer to DVB frontend which given platform device owns.
+ */
+
+struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *);
+
+/**
+ * zd1301_demod_get_i2c_adapter() - Get pointer to I2C adapter
+ * @pdev: Pointer to platform device
+ *
+ * Return: Pointer to I2C adapter which given platform device owns.
+ */
+
+struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *);
+
+#else
+
+static inline struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *dev)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+
+       return NULL;
+}
+static inline struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *dev)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+
+       return NULL;
+}
+
+#endif
+
+#endif /* ZD1301_DEMOD_H */
index a6d020fe9b8b801814d3a5a3c39b3fb80b7141f0..062282739ce56136f8abd0c2d30d8c4b0a94fcab 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  **
  * The data sheet for this tuner can be found at:
  *    http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
index c568d8d59de30c3f8f57a09e0282054740151dd0..88751adfecf7c6f5d8bf824f9f7ba1b2a7d4b4dc 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef DVB_ZL10036_H
index 60a2954f8ff80cef04ed0fe78edec1eae67169a0..623355fc26661a2124133bb45d97f0e7a692d4b6 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 4f3ff3e853ac65e19bb49d6521f0a54d237846a2..47c0549eb7b273d4901cff2045618b09f168d877 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index 37aa6e8f454a71977795fdb2e2f0b494052013fb..cb6248c00089c03a344e17bf744e5d22b1ffac7d 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef ZL10353_H
index e0dd1d3e09dd85665483afe9bf347d61ea738310..a1d902b2d47a75a09ab6406ea9ac8defd36cd82b 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _ZL10353_PRIV_
index b979ea148251deab48fbfca7a0141aa408010f5e..cee1dae6e0143619d18f5c908bacd6f619afb319 100644 (file)
@@ -668,6 +668,7 @@ config VIDEO_S5K5BAF
          camera sensor with an embedded SoC image signal processor.
 
 source "drivers/media/i2c/smiapp/Kconfig"
+source "drivers/media/i2c/et8ek8/Kconfig"
 
 config VIDEO_S5C73M3
        tristate "Samsung S5C73M3 sensor support"
index 92773b2e62257db49ccced3af7503592492ec78d..5bc7bbeb5499345f28999b11622a0ebbe0920e09 100644 (file)
@@ -2,6 +2,7 @@ msp3400-objs    :=      msp3400-driver.o msp3400-kthreads.o
 obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
 
 obj-$(CONFIG_VIDEO_SMIAPP)     += smiapp/
+obj-$(CONFIG_VIDEO_ET8EK8)     += et8ek8/
 obj-$(CONFIG_VIDEO_CX25840) += cx25840/
 obj-$(CONFIG_VIDEO_M5MOLS)     += m5mols/
 obj-y                          += soc_camera/
index e191e295c95116e311fc226f64dc850b6a4ba196..ba1ec4ab9eba031bf74cd2b363aa8dfaad989a10 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  * TODO:
  * - fault interrupt handling
  * - hardware strobe
index fc9ec0f3679c57f675b9dddbde58ef5d2dd98db1..73933147342947387555c8eb35951262f6c7bc07 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -302,7 +298,6 @@ static int adv7170_set_fmt(struct v4l2_subdev *sd,
 {
        struct v4l2_mbus_framefmt *mf = &format->format;
        u8 val = adv7170_read(sd, 0x7);
-       int ret = 0;
 
        if (format->pad)
                return -EINVAL;
@@ -323,9 +318,9 @@ static int adv7170_set_fmt(struct v4l2_subdev *sd,
        }
 
        if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               ret = adv7170_write(sd, 0x7, val);
+               return adv7170_write(sd, 0x7, val);
 
-       return ret;
+       return 0;
 }
 
 /* ----------------------------------------------------------------------- */
index 72139bdae1ca3280848e96a3e0ed9439fb5de415..e31e8d909bb9958c765077369370376c96935486 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index cbed2bc293255c58cb9c37f7ca0e2237346f6707..bdbbf8cf27e4bf93fffc3dc08507e563bda32a1f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 04eecda74d66af63cb3d0bc2d894742182e2e224..8b00dc854cf87c119a4719258c46544a33f8b3ea 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/delay.h>
index b253d400e8176a8baa3d1ba6928a1911d74bdb9d..843d4998435ef964b3ee806aebde007648459c19 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _ADV7183_REGS_H_
index d0375cac6a058c2d71720022ba283bd55e912bac..d8bf435db86db386a1f48b89c0f181bb505fe99e 100644 (file)
@@ -3133,6 +3133,9 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
        state->pdata.blank_data = 1;
        state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0;
        state->pdata.bus_order = ADV7604_BUS_ORDER_RGB;
+       state->pdata.dr_str_data = ADV76XX_DR_STR_MEDIUM_HIGH;
+       state->pdata.dr_str_clk = ADV76XX_DR_STR_MEDIUM_HIGH;
+       state->pdata.dr_str_sync = ADV76XX_DR_STR_MEDIUM_HIGH;
 
        return 0;
 }
index 3a795dcb7d8e07c76c16720850b6cb99c7d60369..16682c8477d14d378b761bf58e1b1be89912c1ff 100644 (file)
@@ -205,14 +205,14 @@ static int ak881x_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
+static const struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = ak881x_g_register,
        .s_register     = ak881x_s_register,
 #endif
 };
 
-static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = {
+static const struct v4l2_subdev_video_ops ak881x_subdev_video_ops = {
        .s_std_output   = ak881x_s_std_output,
        .s_stream       = ak881x_s_stream,
 };
@@ -224,7 +224,7 @@ static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = {
        .get_fmt        = ak881x_fill_fmt,
 };
 
-static struct v4l2_subdev_ops ak881x_subdev_ops = {
+static const struct v4l2_subdev_ops ak881x_subdev_ops = {
        .core   = &ak881x_subdev_core_ops,
        .video  = &ak881x_subdev_video_ops,
        .pad    = &ak881x_subdev_pad_ops,
index 8153a449846b8f0248a8c9a63c4b5df838c350b3..224ae4e4cf8b16373790de6472c17943cb55d104 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #include <linux/device.h>
index b370e341e75df67a28d02cf61207cf28a96a3a1d..1632f864c44f4aefc9799db9e9ceb03246a211b0 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #ifndef __APTINA_PLL_H
index 2e90e4094b7960777296c0e24a4b3ed74706ac5a..b6aeceea985053163722f3b908e077c8e3df25d1 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  * TODO:
  * - Check hardware FSTROBE control when sensor driver add support for this
  *
index 7907bcfbaed33a020cddf349106b0aba6071a3a7..472e37637c8db54310ef7ca4053739887a91a1b6 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 54c627859c8ea5d24b15374db4896736ec174b20..2c039ae7d0b2446b00074fd1608d3c0368935693 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index c7de9790d4f3fddf3e5bac5a3b6bc60ee337f910..03e80278dc10b03b776ed1334465e84142d74421 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index 59c1a98c5a90307edb117f255517a791ebf4dc9c..fd70fe2130a15c5aaea13d3e64defb60472c2b8a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index baf3d9c8710e3066acc3b75ba4b2660b0b7ebd56..dfe94b84f1fb10be6759b8c169cd97e17bf6f9b9 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 
index 0dcf450052ac458a1d634e4dc51a32e45866f619..b8d3c070bfc1d10eb55b32b199a7b7cca4f09105 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 
index 254ef45ce41a8fb0138a1deafbabed0cd6fa1e7b..55432ed42714ac474483624f0b1bd1c14b42177f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef _CX25840_CORE_H_
index 37e052923a877d0097f23017acbc54824b58204f..a7819c4636740a1087965753a9dda006d4bed29c 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #include <linux/module.h>
index 15fbd9607ceea889e6bb4d3c5543eabd01865a0c..9b65c7d2fa84a56d8f2d23ecc0458b62abe1b9bb 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #include <linux/slab.h>
index 0470bb6128e1f320be078dbc70e303c6f0148a25..8c99a79fb7261a4ec02065d6e3292d8aa28aa262 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 
diff --git a/drivers/media/i2c/et8ek8/Kconfig b/drivers/media/i2c/et8ek8/Kconfig
new file mode 100644 (file)
index 0000000..1439936
--- /dev/null
@@ -0,0 +1,6 @@
+config VIDEO_ET8EK8
+       tristate "ET8EK8 camera sensor support"
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       ---help---
+         This is a driver for the Toshiba ET8EK8 5 MP camera sensor.
+         It is used for example in Nokia N900 (RX-51).
diff --git a/drivers/media/i2c/et8ek8/Makefile b/drivers/media/i2c/et8ek8/Makefile
new file mode 100644 (file)
index 0000000..66d1b7d
--- /dev/null
@@ -0,0 +1,2 @@
+et8ek8-objs                    += et8ek8_mode.o et8ek8_driver.o
+obj-$(CONFIG_VIDEO_ET8EK8)     += et8ek8.o
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
new file mode 100644 (file)
index 0000000..bec4a56
--- /dev/null
@@ -0,0 +1,1514 @@
+/*
+ * et8ek8_driver.c
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *          Tuukka Toivonen <tuukkat76@gmail.com>
+ *          Pavel Machek <pavel@ucw.cz>
+ *
+ * Based on code from Toni Leinonen <toni.leinonen@offcode.fi>.
+ *
+ * This driver is based on the Micron MT9T012 camera imager driver
+ * (C) Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+#include <linux/v4l2-mediabus.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "et8ek8_reg.h"
+
+#define ET8EK8_NAME            "et8ek8"
+#define ET8EK8_PRIV_MEM_SIZE   128
+#define ET8EK8_MAX_MSG         48
+
+struct et8ek8_sensor {
+       struct v4l2_subdev subdev;
+       struct media_pad pad;
+       struct v4l2_mbus_framefmt format;
+       struct gpio_desc *reset;
+       struct regulator *vana;
+       struct clk *ext_clk;
+       u32 xclk_freq;
+
+       u16 version;
+
+       struct v4l2_ctrl_handler ctrl_handler;
+       struct v4l2_ctrl *exposure;
+       struct v4l2_ctrl *pixel_rate;
+       struct et8ek8_reglist *current_reglist;
+
+       u8 priv_mem[ET8EK8_PRIV_MEM_SIZE];
+
+       struct mutex power_lock;
+       int power_count;
+};
+
+#define to_et8ek8_sensor(sd)   container_of(sd, struct et8ek8_sensor, subdev)
+
+enum et8ek8_versions {
+       ET8EK8_REV_1 = 0x0001,
+       ET8EK8_REV_2,
+};
+
+/*
+ * This table describes what should be written to the sensor register
+ * for each gain value. The gain(index in the table) is in terms of
+ * 0.1EV, i.e. 10 indexes in the table give 2 time more gain [0] in
+ * the *analog gain, [1] in the digital gain
+ *
+ * Analog gain [dB] = 20*log10(regvalue/32); 0x20..0x100
+ */
+static struct et8ek8_gain {
+       u16 analog;
+       u16 digital;
+} const et8ek8_gain_table[] = {
+       { 32,    0},  /* x1 */
+       { 34,    0},
+       { 37,    0},
+       { 39,    0},
+       { 42,    0},
+       { 45,    0},
+       { 49,    0},
+       { 52,    0},
+       { 56,    0},
+       { 60,    0},
+       { 64,    0},  /* x2 */
+       { 69,    0},
+       { 74,    0},
+       { 79,    0},
+       { 84,    0},
+       { 91,    0},
+       { 97,    0},
+       {104,    0},
+       {111,    0},
+       {119,    0},
+       {128,    0},  /* x4 */
+       {137,    0},
+       {147,    0},
+       {158,    0},
+       {169,    0},
+       {181,    0},
+       {194,    0},
+       {208,    0},
+       {223,    0},
+       {239,    0},
+       {256,    0},  /* x8 */
+       {256,   73},
+       {256,  152},
+       {256,  236},
+       {256,  327},
+       {256,  424},
+       {256,  528},
+       {256,  639},
+       {256,  758},
+       {256,  886},
+       {256, 1023},  /* x16 */
+};
+
+/* Register definitions */
+#define REG_REVISION_NUMBER_L  0x1200
+#define REG_REVISION_NUMBER_H  0x1201
+
+#define PRIV_MEM_START_REG     0x0008
+#define PRIV_MEM_WIN_SIZE      8
+
+#define ET8EK8_I2C_DELAY       3       /* msec delay b/w accesses */
+
+#define USE_CRC                        1
+
+/*
+ * Register access helpers
+ *
+ * Read a 8/16/32-bit i2c register.  The value is returned in 'val'.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int et8ek8_i2c_read_reg(struct i2c_client *client, u16 data_length,
+                              u16 reg, u32 *val)
+{
+       int r;
+       struct i2c_msg msg;
+       unsigned char data[4];
+
+       if (!client->adapter)
+               return -ENODEV;
+       if (data_length != ET8EK8_REG_8BIT && data_length != ET8EK8_REG_16BIT)
+               return -EINVAL;
+
+       msg.addr = client->addr;
+       msg.flags = 0;
+       msg.len = 2;
+       msg.buf = data;
+
+       /* high byte goes out first */
+       data[0] = (u8) (reg >> 8);
+       data[1] = (u8) (reg & 0xff);
+       r = i2c_transfer(client->adapter, &msg, 1);
+       if (r < 0)
+               goto err;
+
+       msg.len = data_length;
+       msg.flags = I2C_M_RD;
+       r = i2c_transfer(client->adapter, &msg, 1);
+       if (r < 0)
+               goto err;
+
+       *val = 0;
+       /* high byte comes first */
+       if (data_length == ET8EK8_REG_8BIT)
+               *val = data[0];
+       else
+               *val = (data[1] << 8) + data[0];
+
+       return 0;
+
+err:
+       dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r);
+
+       return r;
+}
+
+static void et8ek8_i2c_create_msg(struct i2c_client *client, u16 len, u16 reg,
+                                 u32 val, struct i2c_msg *msg,
+                                 unsigned char *buf)
+{
+       msg->addr = client->addr;
+       msg->flags = 0; /* Write */
+       msg->len = 2 + len;
+       msg->buf = buf;
+
+       /* high byte goes out first */
+       buf[0] = (u8) (reg >> 8);
+       buf[1] = (u8) (reg & 0xff);
+
+       switch (len) {
+       case ET8EK8_REG_8BIT:
+               buf[2] = (u8) (val) & 0xff;
+               break;
+       case ET8EK8_REG_16BIT:
+               buf[2] = (u8) (val) & 0xff;
+               buf[3] = (u8) (val >> 8) & 0xff;
+               break;
+       default:
+               WARN_ONCE(1, ET8EK8_NAME ": %s: invalid message length.\n",
+                         __func__);
+       }
+}
+
+/*
+ * A buffered write method that puts the wanted register write
+ * commands in a message list and passes the list to the i2c framework
+ */
+static int et8ek8_i2c_buffered_write_regs(struct i2c_client *client,
+                                         const struct et8ek8_reg *wnext,
+                                         int cnt)
+{
+       struct i2c_msg msg[ET8EK8_MAX_MSG];
+       unsigned char data[ET8EK8_MAX_MSG][6];
+       int wcnt = 0;
+       u16 reg, data_length;
+       u32 val;
+
+       if (WARN_ONCE(cnt > ET8EK8_MAX_MSG,
+                     ET8EK8_NAME ": %s: too many messages.\n", __func__)) {
+               return -EINVAL;
+       }
+
+       /* Create new write messages for all writes */
+       while (wcnt < cnt) {
+               data_length = wnext->type;
+               reg = wnext->reg;
+               val = wnext->val;
+               wnext++;
+
+               et8ek8_i2c_create_msg(client, data_length, reg,
+                                   val, &msg[wcnt], &data[wcnt][0]);
+
+               /* Update write count */
+               wcnt++;
+       }
+
+       /* Now we send everything ... */
+       return i2c_transfer(client->adapter, msg, wcnt);
+}
+
+/*
+ * Write a list of registers to i2c device.
+ *
+ * The list of registers is terminated by ET8EK8_REG_TERM.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int et8ek8_i2c_write_regs(struct i2c_client *client,
+                                const struct et8ek8_reg *regs)
+{
+       int r, cnt = 0;
+       const struct et8ek8_reg *next;
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       if (!regs)
+               return -EINVAL;
+
+       /* Initialize list pointers to the start of the list */
+       next = regs;
+
+       do {
+               /*
+                * We have to go through the list to figure out how
+                * many regular writes we have in a row
+                */
+               while (next->type != ET8EK8_REG_TERM &&
+                      next->type != ET8EK8_REG_DELAY) {
+                       /*
+                        * Here we check that the actual length fields
+                        * are valid
+                        */
+                       if (WARN(next->type != ET8EK8_REG_8BIT &&
+                                next->type != ET8EK8_REG_16BIT,
+                                "Invalid type = %d", next->type)) {
+                               return -EINVAL;
+                       }
+                       /*
+                        * Increment count of successive writes and
+                        * read pointer
+                        */
+                       cnt++;
+                       next++;
+               }
+
+               /* Now we start writing ... */
+               r = et8ek8_i2c_buffered_write_regs(client, regs, cnt);
+
+               /* ... and then check that everything was OK */
+               if (r < 0) {
+                       dev_err(&client->dev, "i2c transfer error!\n");
+                       return r;
+               }
+
+               /*
+                * If we ran into a sleep statement when going through
+                * the list, this is where we snooze for the required time
+                */
+               if (next->type == ET8EK8_REG_DELAY) {
+                       msleep(next->val);
+                       /*
+                        * ZZZ ...
+                        * Update list pointers and cnt and start over ...
+                        */
+                       next++;
+                       regs = next;
+                       cnt = 0;
+               }
+       } while (next->type != ET8EK8_REG_TERM);
+
+       return 0;
+}
+
+/*
+ * Write to a 8/16-bit register.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int et8ek8_i2c_write_reg(struct i2c_client *client, u16 data_length,
+                               u16 reg, u32 val)
+{
+       int r;
+       struct i2c_msg msg;
+       unsigned char data[6];
+
+       if (!client->adapter)
+               return -ENODEV;
+       if (data_length != ET8EK8_REG_8BIT && data_length != ET8EK8_REG_16BIT)
+               return -EINVAL;
+
+       et8ek8_i2c_create_msg(client, data_length, reg, val, &msg, data);
+
+       r = i2c_transfer(client->adapter, &msg, 1);
+       if (r < 0) {
+               dev_err(&client->dev,
+                       "wrote 0x%x to offset 0x%x error %d\n", val, reg, r);
+               return r;
+       }
+
+       return 0;
+}
+
+static struct et8ek8_reglist *et8ek8_reglist_find_type(
+               struct et8ek8_meta_reglist *meta,
+               u16 type)
+{
+       struct et8ek8_reglist **next = &meta->reglist[0].ptr;
+
+       while (*next) {
+               if ((*next)->type == type)
+                       return *next;
+
+               next++;
+       }
+
+       return NULL;
+}
+
+static int et8ek8_i2c_reglist_find_write(struct i2c_client *client,
+                                        struct et8ek8_meta_reglist *meta,
+                                        u16 type)
+{
+       struct et8ek8_reglist *reglist;
+
+       reglist = et8ek8_reglist_find_type(meta, type);
+       if (!reglist)
+               return -EINVAL;
+
+       return et8ek8_i2c_write_regs(client, reglist->regs);
+}
+
+static struct et8ek8_reglist **et8ek8_reglist_first(
+               struct et8ek8_meta_reglist *meta)
+{
+       return &meta->reglist[0].ptr;
+}
+
+static void et8ek8_reglist_to_mbus(const struct et8ek8_reglist *reglist,
+                                  struct v4l2_mbus_framefmt *fmt)
+{
+       fmt->width = reglist->mode.window_width;
+       fmt->height = reglist->mode.window_height;
+       fmt->code = reglist->mode.bus_format;
+}
+
+static struct et8ek8_reglist *et8ek8_reglist_find_mode_fmt(
+               struct et8ek8_meta_reglist *meta,
+               struct v4l2_mbus_framefmt *fmt)
+{
+       struct et8ek8_reglist **list = et8ek8_reglist_first(meta);
+       struct et8ek8_reglist *best_match = NULL;
+       struct et8ek8_reglist *best_other = NULL;
+       struct v4l2_mbus_framefmt format;
+       unsigned int max_dist_match = (unsigned int)-1;
+       unsigned int max_dist_other = (unsigned int)-1;
+
+       /*
+        * Find the mode with the closest image size. The distance between
+        * image sizes is the size in pixels of the non-overlapping regions
+        * between the requested size and the frame-specified size.
+        *
+        * Store both the closest mode that matches the requested format, and
+        * the closest mode for all other formats. The best match is returned
+        * if found, otherwise the best mode with a non-matching format is
+        * returned.
+        */
+       for (; *list; list++) {
+               unsigned int dist;
+
+               if ((*list)->type != ET8EK8_REGLIST_MODE)
+                       continue;
+
+               et8ek8_reglist_to_mbus(*list, &format);
+
+               dist = min(fmt->width, format.width)
+                    * min(fmt->height, format.height);
+               dist = format.width * format.height
+                    + fmt->width * fmt->height - 2 * dist;
+
+
+               if (fmt->code == format.code) {
+                       if (dist < max_dist_match || !best_match) {
+                               best_match = *list;
+                               max_dist_match = dist;
+                       }
+               } else {
+                       if (dist < max_dist_other || !best_other) {
+                               best_other = *list;
+                               max_dist_other = dist;
+                       }
+               }
+       }
+
+       return best_match ? best_match : best_other;
+}
+
+#define TIMEPERFRAME_AVG_FPS(t)                                                \
+       (((t).denominator + ((t).numerator >> 1)) / (t).numerator)
+
+static struct et8ek8_reglist *et8ek8_reglist_find_mode_ival(
+               struct et8ek8_meta_reglist *meta,
+               struct et8ek8_reglist *current_reglist,
+               struct v4l2_fract *timeperframe)
+{
+       int fps = TIMEPERFRAME_AVG_FPS(*timeperframe);
+       struct et8ek8_reglist **list = et8ek8_reglist_first(meta);
+       struct et8ek8_mode *current_mode = &current_reglist->mode;
+
+       for (; *list; list++) {
+               struct et8ek8_mode *mode = &(*list)->mode;
+
+               if ((*list)->type != ET8EK8_REGLIST_MODE)
+                       continue;
+
+               if (mode->window_width != current_mode->window_width ||
+                   mode->window_height != current_mode->window_height)
+                       continue;
+
+               if (TIMEPERFRAME_AVG_FPS(mode->timeperframe) == fps)
+                       return *list;
+       }
+
+       return NULL;
+}
+
+static int et8ek8_reglist_cmp(const void *a, const void *b)
+{
+       const struct et8ek8_reglist **list1 = (const struct et8ek8_reglist **)a,
+               **list2 = (const struct et8ek8_reglist **)b;
+
+       /* Put real modes in the beginning. */
+       if ((*list1)->type == ET8EK8_REGLIST_MODE &&
+           (*list2)->type != ET8EK8_REGLIST_MODE)
+               return -1;
+       if ((*list1)->type != ET8EK8_REGLIST_MODE &&
+           (*list2)->type == ET8EK8_REGLIST_MODE)
+               return 1;
+
+       /* Descending width. */
+       if ((*list1)->mode.window_width > (*list2)->mode.window_width)
+               return -1;
+       if ((*list1)->mode.window_width < (*list2)->mode.window_width)
+               return 1;
+
+       if ((*list1)->mode.window_height > (*list2)->mode.window_height)
+               return -1;
+       if ((*list1)->mode.window_height < (*list2)->mode.window_height)
+               return 1;
+
+       return 0;
+}
+
+static int et8ek8_reglist_import(struct i2c_client *client,
+                                struct et8ek8_meta_reglist *meta)
+{
+       int nlists = 0, i;
+
+       dev_info(&client->dev, "meta_reglist version %s\n", meta->version);
+
+       while (meta->reglist[nlists].ptr)
+               nlists++;
+
+       if (!nlists)
+               return -EINVAL;
+
+       sort(&meta->reglist[0].ptr, nlists, sizeof(meta->reglist[0].ptr),
+            et8ek8_reglist_cmp, NULL);
+
+       i = nlists;
+       nlists = 0;
+
+       while (i--) {
+               struct et8ek8_reglist *list;
+
+               list = meta->reglist[nlists].ptr;
+
+               dev_dbg(&client->dev,
+                      "%s: type %d\tw %d\th %d\tfmt %x\tival %d/%d\tptr %p\n",
+                      __func__,
+                      list->type,
+                      list->mode.window_width, list->mode.window_height,
+                      list->mode.bus_format,
+                      list->mode.timeperframe.numerator,
+                      list->mode.timeperframe.denominator,
+                      (void *)meta->reglist[nlists].ptr);
+
+               nlists++;
+       }
+
+       return 0;
+}
+
+/* Called to change the V4L2 gain control value. This function
+ * rounds and clamps the given value and updates the V4L2 control value.
+ * If power is on, also updates the sensor analog and digital gains.
+ * gain is in 0.1 EV (exposure value) units.
+ */
+static int et8ek8_set_gain(struct et8ek8_sensor *sensor, s32 gain)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
+       struct et8ek8_gain new;
+       int r;
+
+       new = et8ek8_gain_table[gain];
+
+       /* FIXME: optimise I2C writes! */
+       r = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT,
+                               0x124a, new.analog >> 8);
+       if (r)
+               return r;
+       r = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT,
+                               0x1249, new.analog & 0xff);
+       if (r)
+               return r;
+
+       r = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT,
+                               0x124d, new.digital >> 8);
+       if (r)
+               return r;
+       r = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT,
+                               0x124c, new.digital & 0xff);
+
+       return r;
+}
+
+static int et8ek8_set_test_pattern(struct et8ek8_sensor *sensor, s32 mode)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
+       int cbh_mode, cbv_mode, tp_mode, din_sw, r1420, rval;
+
+       /* Values for normal mode */
+       cbh_mode = 0;
+       cbv_mode = 0;
+       tp_mode  = 0;
+       din_sw   = 0x00;
+       r1420    = 0xF0;
+
+       if (mode) {
+               /* Test pattern mode */
+               if (mode < 5) {
+                       cbh_mode = 1;
+                       cbv_mode = 1;
+                       tp_mode  = mode + 3;
+               } else {
+                       cbh_mode = 0;
+                       cbv_mode = 0;
+                       tp_mode  = mode - 4 + 3;
+               }
+
+               din_sw   = 0x01;
+               r1420    = 0xE0;
+       }
+
+       rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x111B,
+                                   tp_mode << 4);
+       if (rval)
+               return rval;
+
+       rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1121,
+                                   cbh_mode << 7);
+       if (rval)
+               return rval;
+
+       rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1124,
+                                   cbv_mode << 7);
+       if (rval)
+               return rval;
+
+       rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x112C, din_sw);
+       if (rval)
+               return rval;
+
+       return et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1420, r1420);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 controls
+ */
+
+static int et8ek8_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct et8ek8_sensor *sensor =
+               container_of(ctrl->handler, struct et8ek8_sensor, ctrl_handler);
+
+       switch (ctrl->id) {
+       case V4L2_CID_GAIN:
+               return et8ek8_set_gain(sensor, ctrl->val);
+
+       case V4L2_CID_EXPOSURE:
+       {
+               struct i2c_client *client =
+                       v4l2_get_subdevdata(&sensor->subdev);
+
+               return et8ek8_i2c_write_reg(client, ET8EK8_REG_16BIT, 0x1243,
+                                           ctrl->val);
+       }
+
+       case V4L2_CID_TEST_PATTERN:
+               return et8ek8_set_test_pattern(sensor, ctrl->val);
+
+       case V4L2_CID_PIXEL_RATE:
+               return 0;
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct v4l2_ctrl_ops et8ek8_ctrl_ops = {
+       .s_ctrl = et8ek8_set_ctrl,
+};
+
+static const char * const et8ek8_test_pattern_menu[] = {
+       "Normal",
+       "Vertical colorbar",
+       "Horizontal colorbar",
+       "Scale",
+       "Ramp",
+       "Small vertical colorbar",
+       "Small horizontal colorbar",
+       "Small scale",
+       "Small ramp",
+};
+
+static int et8ek8_init_controls(struct et8ek8_sensor *sensor)
+{
+       s32 max_rows;
+
+       v4l2_ctrl_handler_init(&sensor->ctrl_handler, 4);
+
+       /* V4L2_CID_GAIN */
+       v4l2_ctrl_new_std(&sensor->ctrl_handler, &et8ek8_ctrl_ops,
+                         V4L2_CID_GAIN, 0, ARRAY_SIZE(et8ek8_gain_table) - 1,
+                         1, 0);
+
+       max_rows = sensor->current_reglist->mode.max_exp;
+       {
+               u32 min = 1, max = max_rows;
+
+               sensor->exposure =
+                       v4l2_ctrl_new_std(&sensor->ctrl_handler,
+                                         &et8ek8_ctrl_ops, V4L2_CID_EXPOSURE,
+                                         min, max, min, max);
+       }
+
+       /* V4L2_CID_PIXEL_RATE */
+       sensor->pixel_rate =
+               v4l2_ctrl_new_std(&sensor->ctrl_handler, &et8ek8_ctrl_ops,
+               V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
+
+       /* V4L2_CID_TEST_PATTERN */
+       v4l2_ctrl_new_std_menu_items(&sensor->ctrl_handler,
+                                    &et8ek8_ctrl_ops, V4L2_CID_TEST_PATTERN,
+                                    ARRAY_SIZE(et8ek8_test_pattern_menu) - 1,
+                                    0, 0, et8ek8_test_pattern_menu);
+
+       if (sensor->ctrl_handler.error)
+               return sensor->ctrl_handler.error;
+
+       sensor->subdev.ctrl_handler = &sensor->ctrl_handler;
+
+       return 0;
+}
+
+static void et8ek8_update_controls(struct et8ek8_sensor *sensor)
+{
+       struct v4l2_ctrl *ctrl;
+       struct et8ek8_mode *mode = &sensor->current_reglist->mode;
+
+       u32 min, max, pixel_rate;
+       static const int S = 8;
+
+       ctrl = sensor->exposure;
+
+       min = 1;
+       max = mode->max_exp;
+
+       /*
+        * Calculate average pixel clock per line. Assume buffers can spread
+        * the data over horizontal blanking time. Rounding upwards.
+        * Formula taken from stock Nokia N900 kernel.
+        */
+       pixel_rate = ((mode->pixel_clock + (1 << S) - 1) >> S) + mode->width;
+       pixel_rate = mode->window_width * (pixel_rate - 1) / mode->width;
+
+       __v4l2_ctrl_modify_range(ctrl, min, max, min, max);
+       __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate, pixel_rate << S);
+}
+
+static int et8ek8_configure(struct et8ek8_sensor *sensor)
+{
+       struct v4l2_subdev *subdev = &sensor->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       int rval;
+
+       rval = et8ek8_i2c_write_regs(client, sensor->current_reglist->regs);
+       if (rval)
+               goto fail;
+
+       /* Controls set while the power to the sensor is turned off are saved
+        * but not applied to the hardware. Now that we're about to start
+        * streaming apply all the current values to the hardware.
+        */
+       rval = v4l2_ctrl_handler_setup(&sensor->ctrl_handler);
+       if (rval)
+               goto fail;
+
+       return 0;
+
+fail:
+       dev_err(&client->dev, "sensor configuration failed\n");
+
+       return rval;
+}
+
+static int et8ek8_stream_on(struct et8ek8_sensor *sensor)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
+
+       return et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1252, 0xb0);
+}
+
+static int et8ek8_stream_off(struct et8ek8_sensor *sensor)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
+
+       return et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1252, 0x30);
+}
+
+static int et8ek8_s_stream(struct v4l2_subdev *subdev, int streaming)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       int ret;
+
+       if (!streaming)
+               return et8ek8_stream_off(sensor);
+
+       ret = et8ek8_configure(sensor);
+       if (ret < 0)
+               return ret;
+
+       return et8ek8_stream_on(sensor);
+}
+
+/* --------------------------------------------------------------------------
+ * V4L2 subdev operations
+ */
+
+static int et8ek8_power_off(struct et8ek8_sensor *sensor)
+{
+       gpiod_set_value(sensor->reset, 0);
+       udelay(1);
+
+       clk_disable_unprepare(sensor->ext_clk);
+
+       return regulator_disable(sensor->vana);
+}
+
+static int et8ek8_power_on(struct et8ek8_sensor *sensor)
+{
+       struct v4l2_subdev *subdev = &sensor->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       unsigned int xclk_freq;
+       int val, rval;
+
+       rval = regulator_enable(sensor->vana);
+       if (rval) {
+               dev_err(&client->dev, "failed to enable vana regulator\n");
+               return rval;
+       }
+
+       if (sensor->current_reglist)
+               xclk_freq = sensor->current_reglist->mode.ext_clock;
+       else
+               xclk_freq = sensor->xclk_freq;
+
+       rval = clk_set_rate(sensor->ext_clk, xclk_freq);
+       if (rval < 0) {
+               dev_err(&client->dev, "unable to set extclk clock freq to %u\n",
+                       xclk_freq);
+               goto out;
+       }
+       rval = clk_prepare_enable(sensor->ext_clk);
+       if (rval < 0) {
+               dev_err(&client->dev, "failed to enable extclk\n");
+               goto out;
+       }
+
+       if (rval)
+               goto out;
+
+       udelay(10); /* I wish this is a good value */
+
+       gpiod_set_value(sensor->reset, 1);
+
+       msleep(5000 * 1000 / xclk_freq + 1); /* Wait 5000 cycles */
+
+       rval = et8ek8_i2c_reglist_find_write(client, &meta_reglist,
+                                            ET8EK8_REGLIST_POWERON);
+       if (rval)
+               goto out;
+
+#ifdef USE_CRC
+       rval = et8ek8_i2c_read_reg(client, ET8EK8_REG_8BIT, 0x1263, &val);
+       if (rval)
+               goto out;
+#if USE_CRC /* TODO get crc setting from DT */
+       val |= BIT(4);
+#else
+       val &= ~BIT(4);
+#endif
+       rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x1263, val);
+       if (rval)
+               goto out;
+#endif
+
+out:
+       if (rval)
+               et8ek8_power_off(sensor);
+
+       return rval;
+}
+
+/* --------------------------------------------------------------------------
+ * V4L2 subdev video operations
+ */
+#define MAX_FMTS 4
+static int et8ek8_enum_mbus_code(struct v4l2_subdev *subdev,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct et8ek8_reglist **list =
+                       et8ek8_reglist_first(&meta_reglist);
+       u32 pixelformat[MAX_FMTS];
+       int npixelformat = 0;
+
+       if (code->index >= MAX_FMTS)
+               return -EINVAL;
+
+       for (; *list; list++) {
+               struct et8ek8_mode *mode = &(*list)->mode;
+               int i;
+
+               if ((*list)->type != ET8EK8_REGLIST_MODE)
+                       continue;
+
+               for (i = 0; i < npixelformat; i++) {
+                       if (pixelformat[i] == mode->bus_format)
+                               break;
+               }
+               if (i != npixelformat)
+                       continue;
+
+               if (code->index == npixelformat) {
+                       code->code = mode->bus_format;
+                       return 0;
+               }
+
+               pixelformat[npixelformat] = mode->bus_format;
+               npixelformat++;
+       }
+
+       return -EINVAL;
+}
+
+static int et8ek8_enum_frame_size(struct v4l2_subdev *subdev,
+                                 struct v4l2_subdev_pad_config *cfg,
+                                 struct v4l2_subdev_frame_size_enum *fse)
+{
+       struct et8ek8_reglist **list =
+                       et8ek8_reglist_first(&meta_reglist);
+       struct v4l2_mbus_framefmt format;
+       int cmp_width = INT_MAX;
+       int cmp_height = INT_MAX;
+       int index = fse->index;
+
+       for (; *list; list++) {
+               if ((*list)->type != ET8EK8_REGLIST_MODE)
+                       continue;
+
+               et8ek8_reglist_to_mbus(*list, &format);
+               if (fse->code != format.code)
+                       continue;
+
+               /* Assume that the modes are grouped by frame size. */
+               if (format.width == cmp_width && format.height == cmp_height)
+                       continue;
+
+               cmp_width = format.width;
+               cmp_height = format.height;
+
+               if (index-- == 0) {
+                       fse->min_width = format.width;
+                       fse->min_height = format.height;
+                       fse->max_width = format.width;
+                       fse->max_height = format.height;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int et8ek8_enum_frame_ival(struct v4l2_subdev *subdev,
+                                 struct v4l2_subdev_pad_config *cfg,
+                                 struct v4l2_subdev_frame_interval_enum *fie)
+{
+       struct et8ek8_reglist **list =
+                       et8ek8_reglist_first(&meta_reglist);
+       struct v4l2_mbus_framefmt format;
+       int index = fie->index;
+
+       for (; *list; list++) {
+               struct et8ek8_mode *mode = &(*list)->mode;
+
+               if ((*list)->type != ET8EK8_REGLIST_MODE)
+                       continue;
+
+               et8ek8_reglist_to_mbus(*list, &format);
+               if (fie->code != format.code)
+                       continue;
+
+               if (fie->width != format.width || fie->height != format.height)
+                       continue;
+
+               if (index-- == 0) {
+                       fie->interval = mode->timeperframe;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static struct v4l2_mbus_framefmt *
+__et8ek8_get_pad_format(struct et8ek8_sensor *sensor,
+                       struct v4l2_subdev_pad_config *cfg,
+                       unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+       switch (which) {
+       case V4L2_SUBDEV_FORMAT_TRY:
+               return v4l2_subdev_get_try_format(&sensor->subdev, cfg, pad);
+       case V4L2_SUBDEV_FORMAT_ACTIVE:
+               return &sensor->format;
+       default:
+               return NULL;
+       }
+}
+
+static int et8ek8_get_pad_format(struct v4l2_subdev *subdev,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_format *fmt)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       struct v4l2_mbus_framefmt *format;
+
+       format = __et8ek8_get_pad_format(sensor, cfg, fmt->pad, fmt->which);
+       if (!format)
+               return -EINVAL;
+
+       fmt->format = *format;
+
+       return 0;
+}
+
+static int et8ek8_set_pad_format(struct v4l2_subdev *subdev,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_format *fmt)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       struct v4l2_mbus_framefmt *format;
+       struct et8ek8_reglist *reglist;
+
+       format = __et8ek8_get_pad_format(sensor, cfg, fmt->pad, fmt->which);
+       if (!format)
+               return -EINVAL;
+
+       reglist = et8ek8_reglist_find_mode_fmt(&meta_reglist, &fmt->format);
+       et8ek8_reglist_to_mbus(reglist, &fmt->format);
+       *format = fmt->format;
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+               sensor->current_reglist = reglist;
+               et8ek8_update_controls(sensor);
+       }
+
+       return 0;
+}
+
+static int et8ek8_get_frame_interval(struct v4l2_subdev *subdev,
+                                    struct v4l2_subdev_frame_interval *fi)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+
+       memset(fi, 0, sizeof(*fi));
+       fi->interval = sensor->current_reglist->mode.timeperframe;
+
+       return 0;
+}
+
+static int et8ek8_set_frame_interval(struct v4l2_subdev *subdev,
+                                    struct v4l2_subdev_frame_interval *fi)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       struct et8ek8_reglist *reglist;
+
+       reglist = et8ek8_reglist_find_mode_ival(&meta_reglist,
+                                               sensor->current_reglist,
+                                               &fi->interval);
+
+       if (!reglist)
+               return -EINVAL;
+
+       if (sensor->current_reglist->mode.ext_clock != reglist->mode.ext_clock)
+               return -EINVAL;
+
+       sensor->current_reglist = reglist;
+       et8ek8_update_controls(sensor);
+
+       return 0;
+}
+
+static int et8ek8_g_priv_mem(struct v4l2_subdev *subdev)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       unsigned int length = ET8EK8_PRIV_MEM_SIZE;
+       unsigned int offset = 0;
+       u8 *ptr  = sensor->priv_mem;
+       int rval = 0;
+
+       /* Read the EEPROM window-by-window, each window 8 bytes */
+       do {
+               u8 buffer[PRIV_MEM_WIN_SIZE];
+               struct i2c_msg msg;
+               int bytes, i;
+               int ofs;
+
+               /* Set the current window */
+               rval = et8ek8_i2c_write_reg(client, ET8EK8_REG_8BIT, 0x0001,
+                                           0xe0 | (offset >> 3));
+               if (rval < 0)
+                       return rval;
+
+               /* Wait for status bit */
+               for (i = 0; i < 1000; ++i) {
+                       u32 status;
+
+                       rval = et8ek8_i2c_read_reg(client, ET8EK8_REG_8BIT,
+                                                  0x0003, &status);
+                       if (rval < 0)
+                               return rval;
+                       if (!(status & 0x08))
+                               break;
+                       usleep_range(1000, 2000);
+               }
+
+               if (i == 1000)
+                       return -EIO;
+
+               /* Read window, 8 bytes at once, and copy to user space */
+               ofs = offset & 0x07;    /* Offset within this window */
+               bytes = length + ofs > 8 ? 8-ofs : length;
+               msg.addr = client->addr;
+               msg.flags = 0;
+               msg.len = 2;
+               msg.buf = buffer;
+               ofs += PRIV_MEM_START_REG;
+               buffer[0] = (u8)(ofs >> 8);
+               buffer[1] = (u8)(ofs & 0xFF);
+
+               rval = i2c_transfer(client->adapter, &msg, 1);
+               if (rval < 0)
+                       return rval;
+
+               mdelay(ET8EK8_I2C_DELAY);
+               msg.addr = client->addr;
+               msg.len = bytes;
+               msg.flags = I2C_M_RD;
+               msg.buf = buffer;
+               memset(buffer, 0, sizeof(buffer));
+
+               rval = i2c_transfer(client->adapter, &msg, 1);
+               if (rval < 0)
+                       return rval;
+
+               rval = 0;
+               memcpy(ptr, buffer, bytes);
+
+               length -= bytes;
+               offset += bytes;
+               ptr += bytes;
+       } while (length > 0);
+
+       return rval;
+}
+
+static int et8ek8_dev_init(struct v4l2_subdev *subdev)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       int rval, rev_l, rev_h;
+
+       rval = et8ek8_power_on(sensor);
+       if (rval) {
+               dev_err(&client->dev, "could not power on\n");
+               return rval;
+       }
+
+       rval = et8ek8_i2c_read_reg(client, ET8EK8_REG_8BIT,
+                                  REG_REVISION_NUMBER_L, &rev_l);
+       if (!rval)
+               rval = et8ek8_i2c_read_reg(client, ET8EK8_REG_8BIT,
+                                          REG_REVISION_NUMBER_H, &rev_h);
+       if (rval) {
+               dev_err(&client->dev, "no et8ek8 sensor detected\n");
+               goto out_poweroff;
+       }
+
+       sensor->version = (rev_h << 8) + rev_l;
+       if (sensor->version != ET8EK8_REV_1 && sensor->version != ET8EK8_REV_2)
+               dev_info(&client->dev,
+                        "unknown version 0x%x detected, continuing anyway\n",
+                        sensor->version);
+
+       rval = et8ek8_reglist_import(client, &meta_reglist);
+       if (rval) {
+               dev_err(&client->dev,
+                       "invalid register list %s, import failed\n",
+                       ET8EK8_NAME);
+               goto out_poweroff;
+       }
+
+       sensor->current_reglist = et8ek8_reglist_find_type(&meta_reglist,
+                                                          ET8EK8_REGLIST_MODE);
+       if (!sensor->current_reglist) {
+               dev_err(&client->dev,
+                       "invalid register list %s, no mode found\n",
+                       ET8EK8_NAME);
+               rval = -ENODEV;
+               goto out_poweroff;
+       }
+
+       et8ek8_reglist_to_mbus(sensor->current_reglist, &sensor->format);
+
+       rval = et8ek8_i2c_reglist_find_write(client, &meta_reglist,
+                                            ET8EK8_REGLIST_POWERON);
+       if (rval) {
+               dev_err(&client->dev,
+                       "invalid register list %s, no POWERON mode found\n",
+                       ET8EK8_NAME);
+               goto out_poweroff;
+       }
+       rval = et8ek8_stream_on(sensor); /* Needed to be able to read EEPROM */
+       if (rval)
+               goto out_poweroff;
+       rval = et8ek8_g_priv_mem(subdev);
+       if (rval)
+               dev_warn(&client->dev,
+                       "can not read OTP (EEPROM) memory from sensor\n");
+       rval = et8ek8_stream_off(sensor);
+       if (rval)
+               goto out_poweroff;
+
+       rval = et8ek8_power_off(sensor);
+       if (rval)
+               goto out_poweroff;
+
+       return 0;
+
+out_poweroff:
+       et8ek8_power_off(sensor);
+
+       return rval;
+}
+
+/* --------------------------------------------------------------------------
+ * sysfs attributes
+ */
+static ssize_t
+et8ek8_priv_mem_read(struct device *dev, struct device_attribute *attr,
+                    char *buf)
+{
+       struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+
+#if PAGE_SIZE < ET8EK8_PRIV_MEM_SIZE
+#error PAGE_SIZE too small!
+#endif
+
+       memcpy(buf, sensor->priv_mem, ET8EK8_PRIV_MEM_SIZE);
+
+       return ET8EK8_PRIV_MEM_SIZE;
+}
+static DEVICE_ATTR(priv_mem, 0444, et8ek8_priv_mem_read, NULL);
+
+/* --------------------------------------------------------------------------
+ * V4L2 subdev core operations
+ */
+
+static int
+et8ek8_registered(struct v4l2_subdev *subdev)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       int rval;
+
+       dev_dbg(&client->dev, "registered!");
+
+       rval = device_create_file(&client->dev, &dev_attr_priv_mem);
+       if (rval) {
+               dev_err(&client->dev, "could not register sysfs entry\n");
+               return rval;
+       }
+
+       rval = et8ek8_dev_init(subdev);
+       if (rval)
+               goto err_file;
+
+       rval = et8ek8_init_controls(sensor);
+       if (rval) {
+               dev_err(&client->dev, "controls initialization failed\n");
+               goto err_file;
+       }
+
+       __et8ek8_get_pad_format(sensor, NULL, 0, V4L2_SUBDEV_FORMAT_ACTIVE);
+
+       return 0;
+
+err_file:
+       device_remove_file(&client->dev, &dev_attr_priv_mem);
+
+       return rval;
+}
+
+static int __et8ek8_set_power(struct et8ek8_sensor *sensor, bool on)
+{
+       return on ? et8ek8_power_on(sensor) : et8ek8_power_off(sensor);
+}
+
+static int et8ek8_set_power(struct v4l2_subdev *subdev, int on)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+       int ret = 0;
+
+       mutex_lock(&sensor->power_lock);
+
+       /* If the power count is modified from 0 to != 0 or from != 0 to 0,
+        * update the power state.
+        */
+       if (sensor->power_count == !on) {
+               ret = __et8ek8_set_power(sensor, !!on);
+               if (ret < 0)
+                       goto done;
+       }
+
+       /* Update the power count. */
+       sensor->power_count += on ? 1 : -1;
+       WARN_ON(sensor->power_count < 0);
+
+done:
+       mutex_unlock(&sensor->power_lock);
+
+       return ret;
+}
+
+static int et8ek8_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(sd);
+       struct v4l2_mbus_framefmt *format;
+       struct et8ek8_reglist *reglist;
+
+       reglist = et8ek8_reglist_find_type(&meta_reglist, ET8EK8_REGLIST_MODE);
+       format = __et8ek8_get_pad_format(sensor, fh->pad, 0,
+                                        V4L2_SUBDEV_FORMAT_TRY);
+       et8ek8_reglist_to_mbus(reglist, format);
+
+       return et8ek8_set_power(sd, true);
+}
+
+static int et8ek8_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       return et8ek8_set_power(sd, false);
+}
+
+static const struct v4l2_subdev_video_ops et8ek8_video_ops = {
+       .s_stream = et8ek8_s_stream,
+       .g_frame_interval = et8ek8_get_frame_interval,
+       .s_frame_interval = et8ek8_set_frame_interval,
+};
+
+static const struct v4l2_subdev_core_ops et8ek8_core_ops = {
+       .s_power = et8ek8_set_power,
+};
+
+static const struct v4l2_subdev_pad_ops et8ek8_pad_ops = {
+       .enum_mbus_code = et8ek8_enum_mbus_code,
+       .enum_frame_size = et8ek8_enum_frame_size,
+       .enum_frame_interval = et8ek8_enum_frame_ival,
+       .get_fmt = et8ek8_get_pad_format,
+       .set_fmt = et8ek8_set_pad_format,
+};
+
+static const struct v4l2_subdev_ops et8ek8_ops = {
+       .core = &et8ek8_core_ops,
+       .video = &et8ek8_video_ops,
+       .pad = &et8ek8_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops et8ek8_internal_ops = {
+       .registered = et8ek8_registered,
+       .open = et8ek8_open,
+       .close = et8ek8_close,
+};
+
+/* --------------------------------------------------------------------------
+ * I2C driver
+ */
+static int __maybe_unused et8ek8_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+
+       if (!sensor->power_count)
+               return 0;
+
+       return __et8ek8_set_power(sensor, false);
+}
+
+static int __maybe_unused et8ek8_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+
+       if (!sensor->power_count)
+               return 0;
+
+       return __et8ek8_set_power(sensor, true);
+}
+
+static int et8ek8_probe(struct i2c_client *client,
+                       const struct i2c_device_id *devid)
+{
+       struct et8ek8_sensor *sensor;
+       struct device *dev = &client->dev;
+       int ret;
+
+       sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+       if (!sensor)
+               return -ENOMEM;
+
+       sensor->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+       if (IS_ERR(sensor->reset)) {
+               dev_dbg(&client->dev, "could not request reset gpio\n");
+               return PTR_ERR(sensor->reset);
+       }
+
+       sensor->vana = devm_regulator_get(dev, "vana");
+       if (IS_ERR(sensor->vana)) {
+               dev_err(&client->dev, "could not get regulator for vana\n");
+               return PTR_ERR(sensor->vana);
+       }
+
+       sensor->ext_clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(sensor->ext_clk)) {
+               dev_err(&client->dev, "could not get clock\n");
+               return PTR_ERR(sensor->ext_clk);
+       }
+
+       ret = of_property_read_u32(dev->of_node, "clock-frequency",
+                                  &sensor->xclk_freq);
+       if (ret) {
+               dev_warn(dev, "can't get clock-frequency\n");
+               return ret;
+       }
+
+       mutex_init(&sensor->power_lock);
+
+       v4l2_i2c_subdev_init(&sensor->subdev, client, &et8ek8_ops);
+       sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       sensor->subdev.internal_ops = &et8ek8_internal_ops;
+
+       sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad);
+       if (ret < 0) {
+               dev_err(&client->dev, "media entity init failed!\n");
+               goto err_mutex;
+       }
+
+       ret = v4l2_async_register_subdev(&sensor->subdev);
+       if (ret < 0)
+               goto err_entity;
+
+       dev_dbg(dev, "initialized!\n");
+
+       return 0;
+
+err_entity:
+       media_entity_cleanup(&sensor->subdev.entity);
+err_mutex:
+       mutex_destroy(&sensor->power_lock);
+       return ret;
+}
+
+static int __exit et8ek8_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
+
+       if (sensor->power_count) {
+               WARN_ON(1);
+               et8ek8_power_off(sensor);
+               sensor->power_count = 0;
+       }
+
+       v4l2_device_unregister_subdev(&sensor->subdev);
+       device_remove_file(&client->dev, &dev_attr_priv_mem);
+       v4l2_ctrl_handler_free(&sensor->ctrl_handler);
+       v4l2_async_unregister_subdev(&sensor->subdev);
+       media_entity_cleanup(&sensor->subdev.entity);
+       mutex_destroy(&sensor->power_lock);
+
+       return 0;
+}
+
+static const struct of_device_id et8ek8_of_table[] = {
+       { .compatible = "toshiba,et8ek8" },
+       { },
+};
+
+static const struct i2c_device_id et8ek8_id_table[] = {
+       { ET8EK8_NAME, 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, et8ek8_id_table);
+
+static const struct dev_pm_ops et8ek8_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(et8ek8_suspend, et8ek8_resume)
+};
+
+static struct i2c_driver et8ek8_i2c_driver = {
+       .driver         = {
+               .name   = ET8EK8_NAME,
+               .pm     = &et8ek8_pm_ops,
+               .of_match_table = et8ek8_of_table,
+       },
+       .probe          = et8ek8_probe,
+       .remove         = __exit_p(et8ek8_remove),
+       .id_table       = et8ek8_id_table,
+};
+
+module_i2c_driver(et8ek8_i2c_driver);
+
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus@iki.fi>, Pavel Machek <pavel@ucw.cz");
+MODULE_DESCRIPTION("Toshiba ET8EK8 camera sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/et8ek8/et8ek8_mode.c b/drivers/media/i2c/et8ek8/et8ek8_mode.c
new file mode 100644 (file)
index 0000000..a79882a
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * et8ek8_mode.c
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *          Tuukka Toivonen <tuukkat76@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include "et8ek8_reg.h"
+
+/*
+ * Stingray sensor mode settings for Scooby
+ */
+
+/* Mode1_poweron_Mode2_16VGA_2592x1968_12.07fps */
+static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
+/* (without the +1)
+ * SPCK       = 80 MHz
+ * CCP2       = 640 MHz
+ * VCO        = 640 MHz
+ * VCOUNT     = 84 (2016)
+ * HCOUNT     = 137 (3288)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 200
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 7
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 0
+ */
+       .type = ET8EK8_REGLIST_POWERON,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3288,
+               .height = 2016,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 2592,
+               .window_height = 1968,
+               .pixel_clock = 80000000,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 1207
+               },
+               .max_exp = 2012,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .sensitivity = 65536
+       },
+       .regs = {
+               /* Need to set firstly */
+               { ET8EK8_REG_8BIT, 0x126C, 0xCC },
+               /* Strobe and Data of CCP2 delay are minimized. */
+               { ET8EK8_REG_8BIT, 0x1269, 0x00 },
+               /* Refined value of Min H_COUNT  */
+               { ET8EK8_REG_8BIT, 0x1220, 0x89 },
+               /* Frequency of SPCK setting (SPCK=MRCK) */
+               { ET8EK8_REG_8BIT, 0x123A, 0x07 },
+               { ET8EK8_REG_8BIT, 0x1241, 0x94 },
+               { ET8EK8_REG_8BIT, 0x1242, 0x02 },
+               { ET8EK8_REG_8BIT, 0x124B, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1255, 0xFF },
+               { ET8EK8_REG_8BIT, 0x1256, 0x9F },
+               { ET8EK8_REG_8BIT, 0x1258, 0x00 },
+               /* From parallel out to serial out */
+               { ET8EK8_REG_8BIT, 0x125D, 0x88 },
+               /* From w/ embeded data to w/o embeded data */
+               { ET8EK8_REG_8BIT, 0x125E, 0xC0 },
+               /* CCP2 out is from STOP to ACTIVE */
+               { ET8EK8_REG_8BIT, 0x1263, 0x98 },
+               { ET8EK8_REG_8BIT, 0x1268, 0xC6 },
+               { ET8EK8_REG_8BIT, 0x1434, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1163, 0x44 },
+               { ET8EK8_REG_8BIT, 0x1166, 0x29 },
+               { ET8EK8_REG_8BIT, 0x1140, 0x02 },
+               { ET8EK8_REG_8BIT, 0x1011, 0x24 },
+               { ET8EK8_REG_8BIT, 0x1151, 0x80 },
+               { ET8EK8_REG_8BIT, 0x1152, 0x23 },
+               /* Initial setting for improvement2 of lower frequency noise */
+               { ET8EK8_REG_8BIT, 0x1014, 0x05 },
+               { ET8EK8_REG_8BIT, 0x1033, 0x06 },
+               { ET8EK8_REG_8BIT, 0x1034, 0x79 },
+               { ET8EK8_REG_8BIT, 0x1423, 0x3F },
+               { ET8EK8_REG_8BIT, 0x1424, 0x3F },
+               { ET8EK8_REG_8BIT, 0x1426, 0x00 },
+               /* Switch of Preset-White-balance (0d:disable / 1d:enable) */
+               { ET8EK8_REG_8BIT, 0x1439, 0x00 },
+               /* Switch of blemish correction (0d:disable / 1d:enable) */
+               { ET8EK8_REG_8BIT, 0x161F, 0x60 },
+               /* Switch of auto noise correction (0d:disable / 1d:enable) */
+               { ET8EK8_REG_8BIT, 0x1634, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1646, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1648, 0x00 },
+               { ET8EK8_REG_8BIT, 0x113E, 0x01 },
+               { ET8EK8_REG_8BIT, 0x113F, 0x22 },
+               { ET8EK8_REG_8BIT, 0x1239, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x07 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x64 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0x89 },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode1_16VGA_2592x1968_13.12fps_DPCM10-8 */
+static struct et8ek8_reglist mode1_16vga_2592x1968_13_12fps_dpcm10_8 = {
+/* (without the +1)
+ * SPCK       = 80 MHz
+ * CCP2       = 560 MHz
+ * VCO        = 560 MHz
+ * VCOUNT     = 84 (2016)
+ * HCOUNT     = 128 (3072)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 175
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 6
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 0
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3072,
+               .height = 2016,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 2592,
+               .window_height = 1968,
+               .pixel_clock = 80000000,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 1292
+               },
+               .max_exp = 2012,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x57 },
+               { ET8EK8_REG_8BIT, 0x1238, 0x82 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x06 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x64 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0x80 }, /* <-changed to v14 7E->80 */
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x83 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode3_4VGA_1296x984_29.99fps_DPCM10-8 */
+static struct et8ek8_reglist mode3_4vga_1296x984_29_99fps_dpcm10_8 = {
+/* (without the +1)
+ * SPCK       = 96.5333333333333 MHz
+ * CCP2       = 579.2 MHz
+ * VCO        = 579.2 MHz
+ * VCOUNT     = 84 (2016)
+ * HCOUNT     = 133 (3192)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 181
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 5
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 0
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3192,
+               .height = 1008,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 1296,
+               .window_height = 984,
+               .pixel_clock = 96533333,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 3000
+               },
+               .max_exp = 1004,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x5A },
+               { ET8EK8_REG_8BIT, 0x1238, 0x82 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x05 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x63 },
+               { ET8EK8_REG_8BIT, 0x1220, 0x85 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x63 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x83 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode4_SVGA_864x656_29.88fps */
+static struct et8ek8_reglist mode4_svga_864x656_29_88fps = {
+/* (without the +1)
+ * SPCK       = 80 MHz
+ * CCP2       = 320 MHz
+ * VCO        = 640 MHz
+ * VCOUNT     = 84 (2016)
+ * HCOUNT     = 166 (3984)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 200
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 7
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 1
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3984,
+               .height = 672,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 864,
+               .window_height = 656,
+               .pixel_clock = 80000000,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 2988
+               },
+               .max_exp = 668,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x71 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x07 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x62 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x62 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0xA6 },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode5_VGA_648x492_29.93fps */
+static struct et8ek8_reglist mode5_vga_648x492_29_93fps = {
+/* (without the +1)
+ * SPCK       = 80 MHz
+ * CCP2       = 320 MHz
+ * VCO        = 640 MHz
+ * VCOUNT     = 84 (2016)
+ * HCOUNT     = 221 (5304)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 200
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 7
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 1
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 5304,
+               .height = 504,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 648,
+               .window_height = 492,
+               .pixel_clock = 80000000,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 2993
+               },
+               .max_exp = 500,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x71 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x07 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x61 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x61 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0xDD },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode2_16VGA_2592x1968_3.99fps */
+static struct et8ek8_reglist mode2_16vga_2592x1968_3_99fps = {
+/* (without the +1)
+ * SPCK       = 80 MHz
+ * CCP2       = 640 MHz
+ * VCO        = 640 MHz
+ * VCOUNT     = 254 (6096)
+ * HCOUNT     = 137 (3288)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 200
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 7
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 0
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3288,
+               .height = 6096,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 2592,
+               .window_height = 1968,
+               .pixel_clock = 80000000,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 399
+               },
+               .max_exp = 6092,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x07 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x64 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0x89 },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0xFE },
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode_648x492_5fps */
+static struct et8ek8_reglist mode_648x492_5fps = {
+/* (without the +1)
+ * SPCK       = 13.3333333333333 MHz
+ * CCP2       = 53.3333333333333 MHz
+ * VCO        = 640 MHz
+ * VCOUNT     = 84 (2016)
+ * HCOUNT     = 221 (5304)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 200
+ * VCO_DIV    = 5
+ * SPCK_DIV   = 7
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 1
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 5304,
+               .height = 504,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 648,
+               .window_height = 492,
+               .pixel_clock = 13333333,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 499
+               },
+               .max_exp = 500,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x64 },
+               { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x71 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x57 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x61 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x61 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0xDD },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode3_4VGA_1296x984_5fps */
+static struct et8ek8_reglist mode3_4vga_1296x984_5fps = {
+/* (without the +1)
+ * SPCK       = 49.4 MHz
+ * CCP2       = 395.2 MHz
+ * VCO        = 790.4 MHz
+ * VCOUNT     = 250 (6000)
+ * HCOUNT     = 137 (3288)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 247
+ * VCO_DIV    = 1
+ * SPCK_DIV   = 7
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 0
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3288,
+               .height = 3000,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 1296,
+               .window_height = 984,
+               .pixel_clock = 49400000,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 501
+               },
+               .max_exp = 2996,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x7B },
+               { ET8EK8_REG_8BIT, 0x1238, 0x82 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x17 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x63 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x63 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1220, 0x89 },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0xFA },
+               { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/  */
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+/* Mode_4VGA_1296x984_25fps_DPCM10-8 */
+static struct et8ek8_reglist mode_4vga_1296x984_25fps_dpcm10_8 = {
+/* (without the +1)
+ * SPCK       = 84.2666666666667 MHz
+ * CCP2       = 505.6 MHz
+ * VCO        = 505.6 MHz
+ * VCOUNT     = 88 (2112)
+ * HCOUNT     = 133 (3192)
+ * CKREF_DIV  = 2
+ * CKVAR_DIV  = 158
+ * VCO_DIV    = 0
+ * SPCK_DIV   = 5
+ * MRCK_DIV   = 7
+ * LVDSCK_DIV = 0
+ */
+       .type = ET8EK8_REGLIST_MODE,
+       .mode = {
+               .sensor_width = 2592,
+               .sensor_height = 1968,
+               .sensor_window_origin_x = 0,
+               .sensor_window_origin_y = 0,
+               .sensor_window_width = 2592,
+               .sensor_window_height = 1968,
+               .width = 3192,
+               .height = 1056,
+               .window_origin_x = 0,
+               .window_origin_y = 0,
+               .window_width = 1296,
+               .window_height = 984,
+               .pixel_clock = 84266667,
+               .ext_clock = 9600000,
+               .timeperframe = {
+                       .numerator = 100,
+                       .denominator = 2500
+               },
+               .max_exp = 1052,
+               /* .max_gain = 0, */
+               .bus_format = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
+               .sensitivity = 65536
+       },
+       .regs = {
+               { ET8EK8_REG_8BIT, 0x1239, 0x4F },
+               { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+               { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+               { ET8EK8_REG_8BIT, 0x123A, 0x05 },
+               { ET8EK8_REG_8BIT, 0x121B, 0x63 },
+               { ET8EK8_REG_8BIT, 0x1220, 0x85 },
+               { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+               { ET8EK8_REG_8BIT, 0x1222, 0x58 },
+               { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+               { ET8EK8_REG_8BIT, 0x121D, 0x63 },
+               { ET8EK8_REG_8BIT, 0x125D, 0x83 },
+               { ET8EK8_REG_TERM, 0, 0}
+       }
+};
+
+struct et8ek8_meta_reglist meta_reglist = {
+       .version = "V14 03-June-2008",
+       .reglist = {
+               { .ptr = &mode1_poweron_mode2_16vga_2592x1968_12_07fps },
+               { .ptr = &mode1_16vga_2592x1968_13_12fps_dpcm10_8 },
+               { .ptr = &mode3_4vga_1296x984_29_99fps_dpcm10_8 },
+               { .ptr = &mode4_svga_864x656_29_88fps },
+               { .ptr = &mode5_vga_648x492_29_93fps },
+               { .ptr = &mode2_16vga_2592x1968_3_99fps },
+               { .ptr = &mode_648x492_5fps },
+               { .ptr = &mode3_4vga_1296x984_5fps },
+               { .ptr = &mode_4vga_1296x984_25fps_dpcm10_8 },
+               { .ptr = NULL }
+       }
+};
diff --git a/drivers/media/i2c/et8ek8/et8ek8_reg.h b/drivers/media/i2c/et8ek8/et8ek8_reg.h
new file mode 100644 (file)
index 0000000..07f1873
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * et8ek8_reg.h
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *          Tuukka Toivonen <tuukkat76@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef ET8EK8REGS_H
+#define ET8EK8REGS_H
+
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-subdev.h>
+
+struct v4l2_mbus_framefmt;
+struct v4l2_subdev_pad_mbus_code_enum;
+
+struct et8ek8_mode {
+       /* Physical sensor resolution and current image window */
+       u16 sensor_width;
+       u16 sensor_height;
+       u16 sensor_window_origin_x;
+       u16 sensor_window_origin_y;
+       u16 sensor_window_width;
+       u16 sensor_window_height;
+
+       /* Image data coming from sensor (after scaling) */
+       u16 width;
+       u16 height;
+       u16 window_origin_x;
+       u16 window_origin_y;
+       u16 window_width;
+       u16 window_height;
+
+       u32 pixel_clock;                /* in Hz */
+       u32 ext_clock;                  /* in Hz */
+       struct v4l2_fract timeperframe;
+       u32 max_exp;                    /* Maximum exposure value */
+       u32 bus_format;                 /* MEDIA_BUS_FMT_ */
+       u32 sensitivity;                /* 16.16 fixed point */
+};
+
+#define ET8EK8_REG_8BIT                        1
+#define ET8EK8_REG_16BIT               2
+#define ET8EK8_REG_DELAY               100
+#define ET8EK8_REG_TERM                        0xff
+struct et8ek8_reg {
+       u16 type;
+       u16 reg;                        /* 16-bit offset */
+       u32 val;                        /* 8/16/32-bit value */
+};
+
+/* Possible struct smia_reglist types. */
+#define ET8EK8_REGLIST_STANDBY         0
+#define ET8EK8_REGLIST_POWERON         1
+#define ET8EK8_REGLIST_RESUME          2
+#define ET8EK8_REGLIST_STREAMON                3
+#define ET8EK8_REGLIST_STREAMOFF       4
+#define ET8EK8_REGLIST_DISABLED                5
+
+#define ET8EK8_REGLIST_MODE            10
+
+#define ET8EK8_REGLIST_LSC_ENABLE      100
+#define ET8EK8_REGLIST_LSC_DISABLE     101
+#define ET8EK8_REGLIST_ANR_ENABLE      102
+#define ET8EK8_REGLIST_ANR_DISABLE     103
+
+struct et8ek8_reglist {
+       u32 type;
+       struct et8ek8_mode mode;
+       struct et8ek8_reg regs[];
+};
+
+#define ET8EK8_MAX_LEN                 32
+struct et8ek8_meta_reglist {
+       char version[ET8EK8_MAX_LEN];
+       union {
+               struct et8ek8_reglist *ptr;
+       } reglist[];
+};
+
+extern struct et8ek8_meta_reglist meta_reglist;
+
+#endif /* ET8EK8REGS */
index cede3975d04bd90441abcb29e6f169857561f935..cee7fd9cf08b3fe1704902a9959392277d9c04ca 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <asm/unaligned.h>
@@ -428,7 +424,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
                 * If platform_data doesn't specify rc_dev, initialize it
                 * internally
                 */
-               rc = rc_allocate_device();
+               rc = rc_allocate_device(RC_DRIVER_SCANCODE);
                if (!rc)
                        return -ENOMEM;
        }
index 77551baab068bd2358a5abfbbe9aa8b5dfeecca0..ab536c4a711558fb22cf5dd0ab22cb4b770a49f2 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
  *****************************************************************************
  *
  * Modified and extended by
index cb8abd5403b341f12a1243a6e39286a75a2a5d55..636b70a984f757531e6eafb2bc7241ceda4a8af4 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef KS0127_H
index 89c28c36c5bf7e5b6e220da6e34c64c1c801dd51..a7a8f9a4e45cc52d79c321a2f79dca4d66c70a66 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index acb804bceccbc745b06da770ef7eb541d53118e6..9ccb5ee55fa9c845a076ee23bf46220339021df5 100644 (file)
@@ -168,7 +168,7 @@ static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
        msg[1].buf = rbuf;
 
        /* minimum stabilization time */
-       usleep_range(200, 200);
+       usleep_range(200, 300);
 
        ret = i2c_transfer(client->adapter, msg, 2);
 
@@ -268,7 +268,8 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
 
        *buf = m5mols_swap_byte((u8 *)&val, size);
 
-       usleep_range(200, 200);
+       /* minimum stabilization time */
+       usleep_range(200, 300);
 
        ret = i2c_transfer(client->adapter, msg, 1);
        if (ret == 1)
@@ -651,7 +652,7 @@ static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
        return 0;
 }
 
-static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
+static const struct v4l2_subdev_pad_ops m5mols_pad_ops = {
        .enum_mbus_code = m5mols_enum_mbus_code,
        .get_fmt        = m5mols_get_fmt,
        .set_fmt        = m5mols_set_fmt,
index 38a20fe181eef9b09e73cdf266ce4642a074a6f3..57ef901edb06074a90c1f81cbca252d43c21f60f 100644 (file)
@@ -290,7 +290,7 @@ static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
        .s_ctrl = ml86v7667_s_ctrl,
 };
 
-static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
+static const struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
        .g_std = ml86v7667_g_std,
        .s_std = ml86v7667_s_std,
        .querystd = ml86v7667_querystd,
@@ -304,14 +304,14 @@ static const struct v4l2_subdev_pad_ops ml86v7667_subdev_pad_ops = {
        .set_fmt = ml86v7667_fill_fmt,
 };
 
-static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
+static const struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register = ml86v7667_g_register,
        .s_register = ml86v7667_s_register,
 #endif
 };
 
-static struct v4l2_subdev_ops ml86v7667_subdev_ops = {
+static const struct v4l2_subdev_ops ml86v7667_subdev_ops = {
        .core = &ml86v7667_subdev_core_ops,
        .video = &ml86v7667_subdev_video_ops,
        .pad = &ml86v7667_subdev_pad_ops,
index 201a9800ea52a8e8860acec804ac7a989e54b596..3db966db83eb50c6888549c062fefd05ae591da9 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
 
 
index eec7aa4c6f98f6b6a48c36177df93dfc5825b585..11fc593ed908a25db615c5ecec979eb31f3e0ac5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
 
 
index da076796999ee6ee5e3ee9ae17d65856ce744629..6a9e068462fd9484be7a69135af9ed8510311d63 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #include <linux/delay.h>
index 237737fec09c15fdc6b3148c10a602860d3b5bff..91d822fc4443a362d3ee8d2b6538deb84b8e2f91 100644 (file)
@@ -972,15 +972,15 @@ static int mt9p031_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
        return mt9p031_set_power(subdev, 0);
 }
 
-static struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
+static const struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
        .s_power        = mt9p031_set_power,
 };
 
-static struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
+static const struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
        .s_stream       = mt9p031_s_stream,
 };
 
-static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
+static const struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
        .enum_mbus_code = mt9p031_enum_mbus_code,
        .enum_frame_size = mt9p031_enum_frame_size,
        .get_fmt = mt9p031_get_format,
@@ -989,7 +989,7 @@ static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
        .set_selection = mt9p031_set_selection,
 };
 
-static struct v4l2_subdev_ops mt9p031_subdev_ops = {
+static const struct v4l2_subdev_ops mt9p031_subdev_ops = {
        .core   = &mt9p031_subdev_core_ops,
        .video  = &mt9p031_subdev_video_ops,
        .pad    = &mt9p031_subdev_pad_ops,
index 58eb62f1ba214449d72a8f06b09e2f21c1eb47c4..2e7a6e62a358ab637342aafebd8ecc3882b942f9 100644 (file)
@@ -266,8 +266,7 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
        struct regmap *map = mt9v032->regmap;
        int ret;
 
-       if (mt9v032->reset_gpio)
-               gpiod_set_value_cansleep(mt9v032->reset_gpio, 1);
+       gpiod_set_value_cansleep(mt9v032->reset_gpio, 1);
 
        ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
        if (ret < 0)
@@ -936,15 +935,15 @@ static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
        return mt9v032_set_power(subdev, 0);
 }
 
-static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
+static const struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
        .s_power        = mt9v032_set_power,
 };
 
-static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
+static const struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
        .s_stream       = mt9v032_s_stream,
 };
 
-static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
+static const struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
        .enum_mbus_code = mt9v032_enum_mbus_code,
        .enum_frame_size = mt9v032_enum_frame_size,
        .get_fmt = mt9v032_get_format,
@@ -953,7 +952,7 @@ static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
        .set_selection = mt9v032_set_selection,
 };
 
-static struct v4l2_subdev_ops mt9v032_subdev_ops = {
+static const struct v4l2_subdev_ops mt9v032_subdev_ops = {
        .core   = &mt9v032_subdev_core_ops,
        .video  = &mt9v032_subdev_video_ops,
        .pad    = &mt9v032_subdev_pad_ops,
index 30cb90b88d7551515abb601dd578216ee60bc204..88c498ad45dfb01aa089090609307ed3ce29673c 100644 (file)
@@ -664,13 +664,13 @@ static const struct v4l2_subdev_core_ops noon010_core_ops = {
        .log_status     = noon010_log_status,
 };
 
-static struct v4l2_subdev_pad_ops noon010_pad_ops = {
+static const struct v4l2_subdev_pad_ops noon010_pad_ops = {
        .enum_mbus_code = noon010_enum_mbus_code,
        .get_fmt        = noon010_get_fmt,
        .set_fmt        = noon010_set_fmt,
 };
 
-static struct v4l2_subdev_video_ops noon010_video_ops = {
+static const struct v4l2_subdev_video_ops noon010_video_ops = {
        .s_stream       = noon010_s_stream,
 };
 
index 1f999e9c0118e358ac111c17084c21799a677db0..6e6367214d408081f36416a1d8249a75b16fb4fd 100644 (file)
@@ -1121,7 +1121,6 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd,
                return -EINVAL;
 
        mf->colorspace = V4L2_COLORSPACE_SRGB;
-       mf->code = ov2659_formats[index].code;
        mf->field = V4L2_FIELD_NONE;
 
        mutex_lock(&ov2659->lock);
index b8961df5af3350d8497d66bc8cbd9e7f0e0c566c..a03b41a3639ec5a54145afa7bafe04a47a8508f7 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
 #include <linux/init.h>
index 502c72238a4a52440a2fa735686f88ffa00a88bf..2de2fbb13b857ec92cc2766fe06730ed4702ad56 100644 (file)
@@ -522,7 +522,7 @@ static void __ov965x_set_power(struct ov965x *ov965x, int on)
        if (on) {
                ov965x_gpio_set(ov965x->gpios[GPIO_PWDN], 0);
                ov965x_gpio_set(ov965x->gpios[GPIO_RST], 0);
-               usleep_range(25000, 26000);
+               msleep(25);
        } else {
                ov965x_gpio_set(ov965x->gpios[GPIO_RST], 1);
                ov965x_gpio_set(ov965x->gpios[GPIO_PWDN], 1);
@@ -1438,7 +1438,7 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd)
 
        mutex_lock(&ov965x->lock);
        __ov965x_set_power(ov965x, 1);
-       usleep_range(25000, 26000);
+       msleep(25);
 
        /* Check sensor revision */
        ret = ov965x_read(client, REG_PID, &pid);
index 0a060339e51667b4ded02b180bc5d8fa7f0f877a..2e7185030741919095cdef356d7b049921190fac 100644 (file)
@@ -211,7 +211,7 @@ static int s5c73m3_3a_lock(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
        }
 
        if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
-               ret = s5c73m3_af_run(state, ~af_lock);
+               ret = s5c73m3_af_run(state, !af_lock);
 
        return ret;
 }
index 769964057881cd1090c47fee5ac33e8b0fc5e818..67dcca76f981cc5a38a23f6a098cc71dc37622e9 100644 (file)
@@ -165,7 +165,7 @@ static int s5k6a3_get_fmt(struct v4l2_subdev *sd,
        return 0;
 }
 
-static struct v4l2_subdev_pad_ops s5k6a3_pad_ops = {
+static const struct v4l2_subdev_pad_ops s5k6a3_pad_ops = {
        .enum_mbus_code = s5k6a3_enum_mbus_code,
        .get_fmt        = s5k6a3_get_fmt,
        .set_fmt        = s5k6a3_set_fmt,
@@ -266,11 +266,11 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
        return ret;
 }
 
-static struct v4l2_subdev_core_ops s5k6a3_core_ops = {
+static const struct v4l2_subdev_core_ops s5k6a3_core_ops = {
        .s_power = s5k6a3_s_power,
 };
 
-static struct v4l2_subdev_ops s5k6a3_subdev_ops = {
+static const struct v4l2_subdev_ops s5k6a3_subdev_ops = {
        .core = &s5k6a3_core_ops,
        .pad = &s5k6a3_pad_ops,
 };
index ad456ce051f9f6e2e95a7a88c2214b662e965ec2..63fe521752a171c530548a46d2e0d3da0fd26a1a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 58062b41c923e48e1c87fdc421cf195b9bdb3e07..d863b04aa2a891be150fc759a1ca881c32386161 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #include "saa711x_regs.h"
index 8d94dcbf4366466c87067d61c16aa78be7f76470..99c303002e9049f80d0ab2285d2afd583aa876db 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index 1baca37f3eb6056e1d9de35c1b167c0ceda96353..e1f6bc219c6460ed0d905db277590c95679fede6 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 119050e1197a4966c4164868f6da1405391c891d..0e27fafaef2d9ceff5191c31a4f6268a876badb4 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 8c93c57af71cd2c7413b0bdd5564d1f070bf0f66..65085a235128ecd844199b292a549a7d2a8841e2 100644 (file)
@@ -233,7 +233,7 @@ static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
        if (ret) {
                dev_err(&client->dev,
                        "[Read]-Modify-Write of register %02x failed!\n", reg);
-               return val;
+               return ret;
        }
 
        val |= set;
index 6b1a04ffad32e1ede62b95264ef77248383610da..a9c067bcc0acd6ed24ac392fb914a2929c4741e8 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
 #include <linux/module.h>
index 1e3a0dd2238cf4aa1c43705ca3493d3652d79967..f569a05fe10547e4ffc159bbce96d5765ae9e40b 100644 (file)
@@ -96,6 +96,7 @@ struct tc358743_state {
 
        struct v4l2_dv_timings timings;
        u32 mbus_fmt_code;
+       u8 csi_lanes_in_use;
 
        struct gpio_desc *reset_gpio;
 };
@@ -287,11 +288,6 @@ static int get_audio_sampling_rate(struct v4l2_subdev *sd)
        return code_to_rate[i2c_rd8(sd, FS_SET) & MASK_FS];
 }
 
-static unsigned tc358743_num_csi_lanes_in_use(struct v4l2_subdev *sd)
-{
-       return ((i2c_rd32(sd, CSI_CONTROL) & MASK_NOL) >> 1) + 1;
-}
-
 /* --------------- TIMINGS --------------- */
 
 static inline unsigned fps(const struct v4l2_bt_timings *t)
@@ -372,29 +368,21 @@ static void tc358743_set_hdmi_hdcp(struct v4l2_subdev *sd, bool enable)
        v4l2_dbg(2, debug, sd, "%s: %s\n", __func__, enable ?
                                "enable" : "disable");
 
-       i2c_wr8_and_or(sd, HDCP_REG1,
-                       ~(MASK_AUTH_UNAUTH_SEL | MASK_AUTH_UNAUTH),
-                       MASK_AUTH_UNAUTH_SEL_16_FRAMES | MASK_AUTH_UNAUTH_AUTO);
+       if (enable) {
+               i2c_wr8_and_or(sd, HDCP_REG3, ~KEY_RD_CMD, KEY_RD_CMD);
 
-       i2c_wr8_and_or(sd, HDCP_REG2, ~MASK_AUTO_P3_RESET,
-                       SET_AUTO_P3_RESET_FRAMES(0x0f));
+               i2c_wr8_and_or(sd, HDCP_MODE, ~MASK_MANUAL_AUTHENTICATION, 0);
 
-       /* HDCP is disabled by configuring the receiver as HDCP repeater. The
-        * repeater mode require software support to work, so HDCP
-        * authentication will fail.
-        */
-       i2c_wr8_and_or(sd, HDCP_REG3, ~KEY_RD_CMD, enable ? KEY_RD_CMD : 0);
-       i2c_wr8_and_or(sd, HDCP_MODE, ~(MASK_AUTO_CLR | MASK_MODE_RST_TN),
-                       enable ?  (MASK_AUTO_CLR | MASK_MODE_RST_TN) : 0);
+               i2c_wr8_and_or(sd, HDCP_REG1, 0xff,
+                               MASK_AUTH_UNAUTH_SEL_16_FRAMES |
+                               MASK_AUTH_UNAUTH_AUTO);
 
-       /* Apple MacBook Pro gen.8 has a bug that makes it freeze every fifth
-        * second when HDCP is disabled, but the MAX_EXCED bit is handled
-        * correctly and HDCP is disabled on the HDMI output.
-        */
-       i2c_wr8_and_or(sd, BSTATUS1, ~MASK_MAX_EXCED,
-                       enable ? 0 : MASK_MAX_EXCED);
-       i2c_wr8_and_or(sd, BCAPS, ~(MASK_REPEATER | MASK_READY),
-                       enable ? 0 : MASK_REPEATER | MASK_READY);
+               i2c_wr8_and_or(sd, HDCP_REG2, ~MASK_AUTO_P3_RESET,
+                               SET_AUTO_P3_RESET_FRAMES(0x0f));
+       } else {
+               i2c_wr8_and_or(sd, HDCP_MODE, ~MASK_MANUAL_AUTHENTICATION,
+                               MASK_MANUAL_AUTHENTICATION);
+       }
 }
 
 static void tc358743_disable_edid(struct v4l2_subdev *sd)
@@ -416,6 +404,7 @@ static void tc358743_enable_edid(struct v4l2_subdev *sd)
 
        if (state->edid_blocks_written == 0) {
                v4l2_dbg(2, debug, sd, "%s: no EDID -> no hotplug\n", __func__);
+               tc358743_s_ctrl_detect_tx_5v(sd);
                return;
        }
 
@@ -683,6 +672,8 @@ static void tc358743_set_csi(struct v4l2_subdev *sd)
 
        v4l2_dbg(3, debug, sd, "%s:\n", __func__);
 
+       state->csi_lanes_in_use = lanes;
+
        tc358743_reset(sd, MASK_CTXRST);
 
        if (lanes < 1)
@@ -1155,7 +1146,7 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
        v4l2_info(sd, "Lanes needed: %d\n",
                        tc358743_num_csi_lanes_needed(sd));
        v4l2_info(sd, "Lanes in use: %d\n",
-                       tc358743_num_csi_lanes_in_use(sd));
+                       state->csi_lanes_in_use);
        v4l2_info(sd, "Waiting for particular sync signal: %s\n",
                        (i2c_rd16(sd, CSI_STATUS) & MASK_S_WSYNC) ?
                        "yes" : "no");
@@ -1438,12 +1429,14 @@ static int tc358743_dv_timings_cap(struct v4l2_subdev *sd,
 static int tc358743_g_mbus_config(struct v4l2_subdev *sd,
                             struct v4l2_mbus_config *cfg)
 {
+       struct tc358743_state *state = to_state(sd);
+
        cfg->type = V4L2_MBUS_CSI2;
 
        /* Support for non-continuous CSI-2 clock is missing in the driver */
        cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
 
-       switch (tc358743_num_csi_lanes_in_use(sd)) {
+       switch (state->csi_lanes_in_use) {
        case 1:
                cfg->flags |= V4L2_MBUS_CSI2_1_LANE;
                break;
index 81f1db558e7c79f4e0ca1787e8dae8ccd62ac0f2..657ef50f215f5f03ccebc2b734a38b51387be587 100644 (file)
 #define MASK_MODE_RST_TN                      0x20
 #define MASK_LINE_REKEY                       0x10
 #define MASK_AUTO_CLR                         0x04
+#define MASK_MANUAL_AUTHENTICATION            0x02 /* Not in REF_01 */
 
 #define HDCP_REG1                             0x8563 /* Not in REF_01 */
 #define MASK_AUTH_UNAUTH_SEL                  0x70
index cc6104da34ef6f3702b055915b473a4ef0506c0e..6ac26986f6a2194014d321edb0958efa43c9903e 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 0c62899c3667cb4b59a1cb12759dea7cb7a51b24..07853d2252aab2a64d3eb5df195e64a60f798f05 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <linux/i2c.h>
index d23aa2fbb9b1e2f6f540ad7864298a28d4a3b3b4..1e6c0857590e89dbca603757960f7c15d2d9009a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _TVP514X_REGS_H
index 3dc3341c48961907f8c26fa5b2a21b58a014e339..4c1190127c85c90f8d5e88a936373b0d71b2ba02 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
index 0e34ca9bccf3913e6524ba07175d5a45e25e3a6f..933673561fa25d095acc59797874ffd896462858 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /* Naming conventions
index 7347480c0b0c48788e44e6fad150343ccc6941e7..bc8a3ecebffbe4cc24ceaabbbad5dcc7101254c5 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
 #include <linux/module.h>
index bef79cf74364fa2b816b54985886cf8b19c1806b..af32db3d74089a437ddcc7ce0dde46aa9e68e9ec 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
 #include <linux/module.h>
index 316a3113ef27b32befccbde8db222262d51f01fc..5081307b2cdbff6a007cd4359878394bc5111791 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
 #include <linux/module.h>
index 8e17a83920d4355038673410459af1011d69e00e..eb0084ebe35e8bf763ffa87ca6469903afaf3395 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
 #include <linux/module.h>
index c03567e993cd3c7645e010314211354ff170f511..7ad5d51dfbc3d31c2938c0090573f53ea8f00196 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index 77f122f2e3c99af0390a64c30a2cf7c14efa82dd..c7fdd7c163cb9ea8db2af76fedd573a2708e951e 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
 
 #include <linux/module.h>
index ef0d8b8e3df79ccd4c84f26c95ac76c495ff9342..c6611a3f2b3d9e1782666a00289528a889ddd232 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index ce9f09370e22171167c2ea9f1e31780f40268e77..67de79b2d55039704ef589949690d4b60502bcf1 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index be4cb7a8bdebec1c1df3463dba4bd1aa7378f289..f0741ab338df2441180e4066cafe775a8e2c55c2 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/delay.h>
index 6ba2ee25827ea9029b1c49ccfe8f21abbeaa4060..f78e7d1087a48a6d67b1146b0c0eeec3cb2c779c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _VS6624_REGS_H_
index c885def54b15a0a65ec03d2f19621613e0dc4597..23464d0641febbd220d546fa9dd894cd712d7e9a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 45039d7567535e6a3590cd59100a8741c29e5f51..704bccf0d4b23464735baadfa47d87d4e28d0e06 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 8756275e9fc4ee71d99d2b9d15eb592cc8e04e2a..760e3e424e23cc0357e5b316a0a66c01b9063dd7 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /* We need to access legacy defines from linux/media.h */
@@ -130,7 +126,7 @@ static long media_device_enum_entities(struct media_device *mdev,
         * old range.
         */
        if (ent->function < MEDIA_ENT_F_OLD_BASE ||
-           ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) {
+           ent->function > MEDIA_ENT_F_TUNER) {
                if (is_media_entity_v4l2_subdev(ent))
                        entd->type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
                else if (ent->function != MEDIA_ENT_F_IO_V4L)
@@ -601,19 +597,19 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 
        if (mdev->entity_internal_idx_max
            >= mdev->pm_count_walk.ent_enum.idx_max) {
-               struct media_entity_graph new = { .top = 0 };
+               struct media_graph new = { .top = 0 };
 
                /*
                 * Initialise the new graph walk before cleaning up
                 * the old one in order not to spoil the graph walk
                 * object of the media device if graph walk init fails.
                 */
-               ret = media_entity_graph_walk_init(&new, mdev);
+               ret = media_graph_walk_init(&new, mdev);
                if (ret) {
                        mutex_unlock(&mdev->graph_mutex);
                        return ret;
                }
-               media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
+               media_graph_walk_cleanup(&mdev->pm_count_walk);
                mdev->pm_count_walk = new;
        }
        mutex_unlock(&mdev->graph_mutex);
@@ -695,7 +691,7 @@ void media_device_cleanup(struct media_device *mdev)
 {
        ida_destroy(&mdev->entity_internal_idx);
        mdev->entity_internal_idx_max = 0;
-       media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
+       media_graph_walk_cleanup(&mdev->pm_count_walk);
        mutex_destroy(&mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_device_cleanup);
index f2772ba6f61163f59d25c31b9b1b4cf16d824856..ae46753c90cbe96a2bb359eca45fa27d9f576284 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * --
  *
  * Generic media device node infrastructure to register and unregister
index f9f723f5e4f06bdcb1c306e61c597bb187bcfb49..5640ca29da8c9bbc8ea63ce84077c087a0bb9557 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/bitmap.h>
@@ -258,7 +254,7 @@ media_entity_other(struct media_entity *entity, struct media_link *link)
 }
 
 /* push an entity to traversal stack */
-static void stack_push(struct media_entity_graph *graph,
+static void stack_push(struct media_graph *graph,
                       struct media_entity *entity)
 {
        if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) {
@@ -270,7 +266,7 @@ static void stack_push(struct media_entity_graph *graph,
        graph->stack[graph->top].entity = entity;
 }
 
-static struct media_entity *stack_pop(struct media_entity_graph *graph)
+static struct media_entity *stack_pop(struct media_graph *graph)
 {
        struct media_entity *entity;
 
@@ -289,35 +285,35 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph)
 #define MEDIA_ENTITY_MAX_PADS          512
 
 /**
- * media_entity_graph_walk_init - Allocate resources for graph walk
+ * media_graph_walk_init - Allocate resources for graph walk
  * @graph: Media graph structure that will be used to walk the graph
  * @mdev: Media device
  *
  * Reserve resources for graph walk in media device's current
  * state. The memory must be released using
- * media_entity_graph_walk_free().
+ * media_graph_walk_free().
  *
  * Returns error on failure, zero on success.
  */
-__must_check int media_entity_graph_walk_init(
-       struct media_entity_graph *graph, struct media_device *mdev)
+__must_check int media_graph_walk_init(
+       struct media_graph *graph, struct media_device *mdev)
 {
        return media_entity_enum_init(&graph->ent_enum, mdev);
 }
-EXPORT_SYMBOL_GPL(media_entity_graph_walk_init);
+EXPORT_SYMBOL_GPL(media_graph_walk_init);
 
 /**
- * media_entity_graph_walk_cleanup - Release resources related to graph walking
+ * media_graph_walk_cleanup - Release resources related to graph walking
  * @graph: Media graph structure that was used to walk the graph
  */
-void media_entity_graph_walk_cleanup(struct media_entity_graph *graph)
+void media_graph_walk_cleanup(struct media_graph *graph)
 {
        media_entity_enum_cleanup(&graph->ent_enum);
 }
-EXPORT_SYMBOL_GPL(media_entity_graph_walk_cleanup);
+EXPORT_SYMBOL_GPL(media_graph_walk_cleanup);
 
-void media_entity_graph_walk_start(struct media_entity_graph *graph,
-                                  struct media_entity *entity)
+void media_graph_walk_start(struct media_graph *graph,
+                           struct media_entity *entity)
 {
        media_entity_enum_zero(&graph->ent_enum);
        media_entity_enum_set(&graph->ent_enum, entity);
@@ -325,12 +321,52 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph,
        graph->top = 0;
        graph->stack[graph->top].entity = NULL;
        stack_push(graph, entity);
+       dev_dbg(entity->graph_obj.mdev->dev,
+               "begin graph walk at '%s'\n", entity->name);
 }
-EXPORT_SYMBOL_GPL(media_entity_graph_walk_start);
+EXPORT_SYMBOL_GPL(media_graph_walk_start);
 
-struct media_entity *
-media_entity_graph_walk_next(struct media_entity_graph *graph)
+static void media_graph_walk_iter(struct media_graph *graph)
 {
+       struct media_entity *entity = stack_top(graph);
+       struct media_link *link;
+       struct media_entity *next;
+
+       link = list_entry(link_top(graph), typeof(*link), list);
+
+       /* The link is not enabled so we do not follow. */
+       if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
+               link_top(graph) = link_top(graph)->next;
+               dev_dbg(entity->graph_obj.mdev->dev,
+                       "walk: skipping disabled link '%s':%u -> '%s':%u\n",
+                       link->source->entity->name, link->source->index,
+                       link->sink->entity->name, link->sink->index);
+               return;
+       }
+
+       /* Get the entity in the other end of the link . */
+       next = media_entity_other(entity, link);
+
+       /* Has the entity already been visited? */
+       if (media_entity_enum_test_and_set(&graph->ent_enum, next)) {
+               link_top(graph) = link_top(graph)->next;
+               dev_dbg(entity->graph_obj.mdev->dev,
+                       "walk: skipping entity '%s' (already seen)\n",
+                       next->name);
+               return;
+       }
+
+       /* Push the new entity to stack and start over. */
+       link_top(graph) = link_top(graph)->next;
+       stack_push(graph, next);
+       dev_dbg(entity->graph_obj.mdev->dev, "walk: pushing '%s' on stack\n",
+               next->name);
+}
+
+struct media_entity *media_graph_walk_next(struct media_graph *graph)
+{
+       struct media_entity *entity;
+
        if (stack_top(graph) == NULL)
                return NULL;
 
@@ -339,59 +375,39 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
         * top of the stack until no more entities on the level can be
         * found.
         */
-       while (link_top(graph) != &stack_top(graph)->links) {
-               struct media_entity *entity = stack_top(graph);
-               struct media_link *link;
-               struct media_entity *next;
-
-               link = list_entry(link_top(graph), typeof(*link), list);
-
-               /* The link is not enabled so we do not follow. */
-               if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
-                       link_top(graph) = link_top(graph)->next;
-                       continue;
-               }
+       while (link_top(graph) != &stack_top(graph)->links)
+               media_graph_walk_iter(graph);
 
-               /* Get the entity in the other end of the link . */
-               next = media_entity_other(entity, link);
+       entity = stack_pop(graph);
+       dev_dbg(entity->graph_obj.mdev->dev,
+               "walk: returning entity '%s'\n", entity->name);
 
-               /* Has the entity already been visited? */
-               if (media_entity_enum_test_and_set(&graph->ent_enum, next)) {
-                       link_top(graph) = link_top(graph)->next;
-                       continue;
-               }
-
-               /* Push the new entity to stack and start over. */
-               link_top(graph) = link_top(graph)->next;
-               stack_push(graph, next);
-       }
-
-       return stack_pop(graph);
+       return entity;
 }
-EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
+EXPORT_SYMBOL_GPL(media_graph_walk_next);
 
 /* -----------------------------------------------------------------------------
  * Pipeline management
  */
 
-__must_check int __media_entity_pipeline_start(struct media_entity *entity,
-                                              struct media_pipeline *pipe)
+__must_check int __media_pipeline_start(struct media_entity *entity,
+                                       struct media_pipeline *pipe)
 {
        struct media_device *mdev = entity->graph_obj.mdev;
-       struct media_entity_graph *graph = &pipe->graph;
+       struct media_graph *graph = &pipe->graph;
        struct media_entity *entity_err = entity;
        struct media_link *link;
        int ret;
 
        if (!pipe->streaming_count++) {
-               ret = media_entity_graph_walk_init(&pipe->graph, mdev);
+               ret = media_graph_walk_init(&pipe->graph, mdev);
                if (ret)
                        goto error_graph_walk_start;
        }
 
-       media_entity_graph_walk_start(&pipe->graph, entity);
+       media_graph_walk_start(&pipe->graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(graph))) {
+       while ((entity = media_graph_walk_next(graph))) {
                DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
                DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
 
@@ -441,7 +457,7 @@ __must_check int __media_entity_pipeline_start(struct media_entity *entity,
                        ret = entity->ops->link_validate(link);
                        if (ret < 0 && ret != -ENOIOCTLCMD) {
                                dev_dbg(entity->graph_obj.mdev->dev,
-                                       "link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
+                                       "link validation failed for '%s':%u -> '%s':%u, error %d\n",
                                        link->source->entity->name,
                                        link->source->index,
                                        entity->name, link->sink->index, ret);
@@ -455,7 +471,7 @@ __must_check int __media_entity_pipeline_start(struct media_entity *entity,
                if (!bitmap_full(active, entity->num_pads)) {
                        ret = -ENOLINK;
                        dev_dbg(entity->graph_obj.mdev->dev,
-                               "\"%s\":%u must be connected by an enabled link\n",
+                               "'%s':%u must be connected by an enabled link\n",
                                entity->name,
                                (unsigned)find_first_zero_bit(
                                        active, entity->num_pads));
@@ -470,11 +486,11 @@ error:
         * Link validation on graph failed. We revert what we did and
         * return the error.
         */
-       media_entity_graph_walk_start(graph, entity_err);
+       media_graph_walk_start(graph, entity_err);
 
-       while ((entity_err = media_entity_graph_walk_next(graph))) {
-               /* don't let the stream_count go negative */
-               if (entity->stream_count > 0) {
+       while ((entity_err = media_graph_walk_next(graph))) {
+               /* Sanity check for negative stream_count */
+               if (!WARN_ON_ONCE(entity_err->stream_count <= 0)) {
                        entity_err->stream_count--;
                        if (entity_err->stream_count == 0)
                                entity_err->pipe = NULL;
@@ -490,37 +506,37 @@ error:
 
 error_graph_walk_start:
        if (!--pipe->streaming_count)
-               media_entity_graph_walk_cleanup(graph);
+               media_graph_walk_cleanup(graph);
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(__media_entity_pipeline_start);
+EXPORT_SYMBOL_GPL(__media_pipeline_start);
 
-__must_check int media_entity_pipeline_start(struct media_entity *entity,
-                                            struct media_pipeline *pipe)
+__must_check int media_pipeline_start(struct media_entity *entity,
+                                     struct media_pipeline *pipe)
 {
        struct media_device *mdev = entity->graph_obj.mdev;
        int ret;
 
        mutex_lock(&mdev->graph_mutex);
-       ret = __media_entity_pipeline_start(entity, pipe);
+       ret = __media_pipeline_start(entity, pipe);
        mutex_unlock(&mdev->graph_mutex);
        return ret;
 }
-EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
+EXPORT_SYMBOL_GPL(media_pipeline_start);
 
-void __media_entity_pipeline_stop(struct media_entity *entity)
+void __media_pipeline_stop(struct media_entity *entity)
 {
-       struct media_entity_graph *graph = &entity->pipe->graph;
+       struct media_graph *graph = &entity->pipe->graph;
        struct media_pipeline *pipe = entity->pipe;
 
 
        WARN_ON(!pipe->streaming_count);
-       media_entity_graph_walk_start(graph, entity);
+       media_graph_walk_start(graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(graph))) {
-               /* don't let the stream_count go negative */
-               if (entity->stream_count > 0) {
+       while ((entity = media_graph_walk_next(graph))) {
+               /* Sanity check for negative stream_count */
+               if (!WARN_ON_ONCE(entity->stream_count <= 0)) {
                        entity->stream_count--;
                        if (entity->stream_count == 0)
                                entity->pipe = NULL;
@@ -528,20 +544,20 @@ void __media_entity_pipeline_stop(struct media_entity *entity)
        }
 
        if (!--pipe->streaming_count)
-               media_entity_graph_walk_cleanup(graph);
+               media_graph_walk_cleanup(graph);
 
 }
-EXPORT_SYMBOL_GPL(__media_entity_pipeline_stop);
+EXPORT_SYMBOL_GPL(__media_pipeline_stop);
 
-void media_entity_pipeline_stop(struct media_entity *entity)
+void media_pipeline_stop(struct media_entity *entity)
 {
        struct media_device *mdev = entity->graph_obj.mdev;
 
        mutex_lock(&mdev->graph_mutex);
-       __media_entity_pipeline_stop(entity);
+       __media_pipeline_stop(entity);
        mutex_unlock(&mdev->graph_mutex);
 }
-EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
+EXPORT_SYMBOL_GPL(media_pipeline_stop);
 
 /* -----------------------------------------------------------------------------
  * Module use count
index 99ce28442a75b389956bc43b8407f5d71cff690d..6e60decb2198b407bd963fed4925b64f767b489f 100644 (file)
@@ -157,7 +157,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
        if (v.irq_20c.Data_receiver_error)
                deb_chk("data receiver error\n");
        if (v.irq_20c.Continuity_error_flag)
-               deb_chk("Contunuity error flag is set\n");
+               deb_chk("Continuity error flag is set\n");
        if (v.irq_20c.LLC_SNAP_FLAG_set)
                deb_chk("LLC_SNAP_FLAG_set is set\n");
        if (v.irq_20c.Transport_Error)
index 4da720e4867e8d195ca597f2d1b79f5147662ecf..2fd07a8afcd2500d641d72031075f5aebea151e2 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -424,7 +420,7 @@ int bttv_input_init(struct bttv *btv)
                return -ENODEV;
 
        ir = kzalloc(sizeof(*ir),GFP_KERNEL);
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!ir || !rc)
                goto err_out_free;
 
index 8681b9143a3521fd0457095d8d66e6eab776c566..04d06c564602566e442cd427ec7878ed87a22d98 100644 (file)
@@ -475,16 +475,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
 
 static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
 {
-       int i = 0;
-
-       u32 command = 0;
+       int i;
+       u32 command;
        struct ca_msg *hw_buffer;
        int result = 0;
 
-       if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
-               dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
+       hw_buffer = kmalloc(sizeof(*hw_buffer), GFP_KERNEL);
+       if (!hw_buffer)
                return -ENOMEM;
-       }
        dprintk(verbose, DST_CA_DEBUG, 1, " ");
 
        if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) {
@@ -567,7 +565,6 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct
        p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
        p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
        if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) {
-               dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
                result = -ENOMEM;
                goto free_mem_and_exit;
        }
index 6100fa71ece818274964aabf2cf268ea6f8e72a7..ad617871ce9b003940b0e06a275fb2e31aed7ff9 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -683,6 +679,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
                /*      DST is not a frontend, attaching the ASIC       */
                if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
                        pr_err("%s: Could not find a Twinhan DST\n", __func__);
+                       kfree(state);
                        break;
                }
                /*      Attach other DST peripherals if any             */
index 4499ed2ac0ed7339384663dc1b2a5f8f77d82224..0ec538e23b4e18a096e80d45eec8930a4b89761a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef DVB_BT8XX_H
index 23c875fc173efd04f372e9edd4d2e80afc9ce4d0..bfcecef659e3851be0247b1b4bc81230c798337e 100644 (file)
@@ -71,9 +71,9 @@ static void cpld_info_ver3(struct cobalt *cobalt)
        cobalt_info("\t\tMAXII program revision:  0x%04x\n",
                    cpld_read(cobalt, 0x30));
        cobalt_info("CPLD temp and voltage ADT7411 registers (read only)\n");
-       cobalt_info("\t\tBoard temperature:  %u Celcius\n",
+       cobalt_info("\t\tBoard temperature:  %u Celsius\n",
                    cpld_read(cobalt, 0x34) / 4);
-       cobalt_info("\t\tFPGA temperature:   %u Celcius\n",
+       cobalt_info("\t\tFPGA temperature:   %u Celsius\n",
                    cpld_read(cobalt, 0x38) / 4);
        rd = cpld_read(cobalt, 0x3c);
        tmp = (rd * 33 * 1000) / (483 * 10);
index 9fb7f5978c8b5b14bac5854a8d5d024c4933bd60..2531e4b81b60ad9718cd8934fb726926bc8921e4 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include <linux/init.h>
index 284275270f1bb18d2a7b05045ab0c33919c05142..06b066bc9301a8a730ef4efba411f952a075ad5c 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include <linux/init.h>
index ec9238793f6f415fbf660d4b592af1e4431942e7..3aed123955dd992a08e03d181239782dd326f82f 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc);
index 5344510fbea30afb97cb99229b96e1eab67e1599..205a98da877caa9db99ae21f11cf6c0c86434265 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include <linux/init.h>
index e2b2c5b012157feff45ea99176fd8b79ec85fe47..b9e3afe14ee0b1697bcf7026694474e15642de7b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
index 2718be28bf5f541bec384b1dbd2fc629756fc2eb..d88e3bd7944e8f20bbbcd289fe5bf32dcb370c2f 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 struct snd_card;
index 35268923911c94b88bf527bc0734941cd3617b95..61fc485d3d8015af4aaaf5d36370f4446cb1a945 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 2731d29b0ab95078cb856cac4c9fb4067fa9c6c6..f65d71a04c199948cf13221b0579f0ddd920e355 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int cx18_audio_set_io(struct cx18 *cx);
index 4a24ffb17a7d85177d9792a7c5f4eebf51e65a32..8b95e9aae576c33e85b4c83680d9872b401dfba0 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #include "cx18-driver.h"
index 7f7306fd9a7f73adf5254fc41cdef9ccc2bd567c..cf8817e9c8b9b7f10905c7ad1201ac73269da8d7 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #include "cx18-driver.h"
index 4c559e86e340b39f2727794144ca4fd55b1ac2ac..c976ce6e7a78aa2f1bccb41393e0e6bdaaab13df 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #ifndef _CX18_AV_CORE_H_
index 160e2e53383ffa9715f0ee260f9fc72d58d265dc..543ace7a481a4a61661e28f065d542ee1a57f8de 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #include "cx18-driver.h"
index 246982841fece5ac75df67c9beb08604d56f3eba..a002537a387d79864ed05d7f9098e7a685ba90d4 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 
index 5e01ea441dc4d59d77558087bddbce11e024a7d9..11e898e66ce907f2dae812e9f87d620f55bad3da 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index f6b921f3b0acdda222e294592854a1ffbe352915..667e2d7b1d037c5fad4a2012d22084c7e7c40a87 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /* hardware flags */
index 812a2507945ae27fe931453d85f193ef9898e17a..f02df985def0777be920a1f356c26365628fa6ec 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 #include <linux/kernel.h>
 #include <linux/slab.h>
index b8eedbe51c8f65cbebca2cd56d71c72590b9bca6..206db81ef78eb7723192adc4abfe9f6b4d87bd67 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index ef308a10e870c45a73b968a6da3d9b0ea3b4d56f..fef3c736fcba68c21cbb63fc5ade2e646ea13c66 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #ifndef CX18_DRIVER_H
index 03d0478170a7522a5a77d7418ed6de8bc81c417c..d130d65828b0b6d305c529dbc1281bfe960769e8 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx18-version.h"
index bf8d8f6f54558ab3264dd783ad13dc9246632b40..33dfc53e3b4f6cd064da3f999de09b6299b57c7e 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx18-driver.h"
index 78b399b8613e8952d0b517747c85e0750a0d0505..98467b2089fa8e837134d8e73fd0ccc584de4a4e 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index b9e5110ad04368765fbe7be12fe4dd7ea869d6d0..58b00b43370809fa3ba1a2f78bf2bf7ddf5e2f33 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 /* Testing/Debugging */
index c6c83445f8bfb93605990d6726b9d2755d0d4f24..1b34ea1c3730561c5b24d6c6283072c3cb2dafbd 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 38d4c05e8499749bfcb187ecf07c41a6bf65aa09..bdc4b11f74f7c97468a71c48c646d1d5808251ed 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int cx18_firmware_init(struct cx18 *cx);
index 38dc6b8f82546ffdf275a192dba3ff6c38cad6b9..012859e6dc7bdb7ef011011e5984c254a3145592 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 4aea2ef88e8d05794e6a07e3a7ba734dc9be1048..0274a17a88372491898f614e16b6b143a15144e2 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 void cx18_gpio_init(struct cx18 *cx);
index c9329371a3f8ed867b1c1beeb335789122971849..eabdd4c5520ad36e9ed617f56d9bde6614fcaa6c 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 1180fdc8d983b1b861edc635a7e9ed53463d56ee..bf315ecbe5ddf25fbc5d3f990edd57fad66e0d5d 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int cx18_i2c_register(struct cx18 *cx, unsigned idx);
index 49b9dbd06248c53e0e0388e23e1ceb0104a45ec1..7090fdbce28f537c6299f1077a1e709afe558dab 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 18974d886cf729e01d777f10a3f2226a936b397d..a3c96fb5d28d9b94c6651edd1af66dcd923cf052 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #ifndef CX18_IO_H
index 0faeb979ceb94e1ce413fa1c431d6605a96d12bb..80b902b12a78a97880786c0afe3143fb1db62c46 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 43433969d6331271969fc84477161eada3f540e2..413129004a89bbb3978c1cbe931b10232d54fe32 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 u16 cx18_service2vbi(int type);
index 361426485e98837fece026eb4e47a10939bd4c03..ff33ffda0126c21dbffceb89bf0249c7f799592b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 30e7eaf8cb5540007446cb79f0c923caf1d21867..64496746ea46fc6a5eb3198c270d907d5b1e1986 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #define HW2_I2C1_INT                   (1 << 22)
index d3cf3588879f5740aa16fff3f04c487182a21b66..763f960fc918bbc22e230204fd1ffe752458c320 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include <stdarg.h>
index b63fdfaac49ea39c01ee999c6549c303c7f6b539..54b11322bd23fb0864b6b6ea023564e4a4191a85 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #ifndef _CX18_MAILBOX_H_
index 13e96d6055ebf6a4da65a774e901f5dad787d0a9..d212f79fd3aab1b472864f93d71087cf512ff5d6 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 4201ddc16091518b553b0ce0e94282a5e025fb4d..093b04e0189c43dbbd79e3b49be9e0425e5ac43b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #define CX18_DMA_UNMAPPED      ((u32) -1)
index 85cc59637e54f67fa5ef0ad975adbeef4a958b76..83a92629519d74b4e7acf9a2e89fe06bf3cd38d5 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 08877652e321f8579d350effa6b0531be12f2be1..7c3eaea3021fdb2ff3a69a6b068f6663c01bb3b9 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #ifndef CX18_SCB_H
index 7f699f0ee76cbadf3b58045fbeae9b5a30c1b59a..7c93814489667e621f881aa039fedf656939504e 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 27f8af9b11cdbdea0536ecf63655e3ba09b7a441..75c86f1b2e260b151e5d744ffa11b60361b309d7 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 u32 cx18_find_handle(struct cx18 *cx);
index 43360cbcf24b443b2d6ec4d9a73bc2cdb4bc3a69..72c74d60c6fbf6f5b711e32be144d54b7a969aaa 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index b365cf4b46683d7e029eafc69dd7d1406b7a7a0c..8c514ea2d2ba36f1600997a255d8af95fc695236 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
index fed48b6bb67b622b981532be129a5834ecdd8547..50728c68b83551fe82a9562cea590c5e69ead6eb 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #ifndef CX18_VERSION_H
index 6dc84aac8f4421eda5b4c53ac01f3c7e11eb3743..697d01168b63c381e9590f0eb0ad23201746434d 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #include "cx18-driver.h"
index 529006a06e5cf6d95625ac194e3c0c89d6497f6b..f6eca36e72717f13d3f3db8d5fb25589523995bd 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 void cx18_video_set_io(struct cx18 *cx);
index 67ffe65b56a35fdcb64776c417195d806a3603fc..901ed7fac10f00855ab214f80bfa3920561de56b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 #ifndef CX23418_H
index 589a168d1df4581c1481cb5d389d888e1de570b2..979b66627f60faeaef4683eaf2bddd825277d881 100644 (file)
@@ -920,19 +920,6 @@ static const struct m88ds3103_config dvbsky_s950c_m88ds3103_config = {
        .agc = 0x99,
 };
 
-static const struct m88ds3103_config dvbsky_s952_portc_m88ds3103_config = {
-       .i2c_addr = 0x68,
-       .clock = 27000000,
-       .i2c_wr_max = 33,
-       .clock_out = 0,
-       .ts_mode = M88DS3103_TS_SERIAL,
-       .ts_clk = 96000,
-       .ts_clk_pol = 0,
-       .lnb_en_pol = 1,
-       .lnb_hv_pol = 0,
-       .agc = 0x99,
-};
-
 static const struct m88ds3103_config hauppauge_hvr5525_m88ds3103_config = {
        .i2c_addr = 0x69,
        .clock = 27000000,
@@ -1206,11 +1193,11 @@ static int dvb_register(struct cx23885_tsport *port)
        struct si2165_platform_data si2165_pdata;
        struct si2157_config si2157_config;
        struct ts2020_config ts2020_config;
+       struct m88ds3103_platform_data m88ds3103_pdata;
        struct i2c_board_info info;
        struct i2c_adapter *adapter;
        struct i2c_client *client_demod = NULL, *client_tuner = NULL;
        struct i2c_client *client_sec = NULL;
-       const struct m88ds3103_config *p_m88ds3103_config = NULL;
        int (*p_set_voltage)(struct dvb_frontend *fe,
                             enum fe_sec_voltage voltage) = NULL;
        int mfe_shared = 0; /* bus not shared by default */
@@ -2103,27 +2090,50 @@ static int dvb_register(struct cx23885_tsport *port)
                port->i2c_client_tuner = client_tuner;
                break;
        case CX23885_BOARD_DVBSKY_S952:
+               /* attach frontend */
+               memset(&m88ds3103_pdata, 0, sizeof(m88ds3103_pdata));
+               m88ds3103_pdata.clk = 27000000;
+               m88ds3103_pdata.i2c_wr_max = 33;
+               m88ds3103_pdata.agc = 0x99;
+               m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_DISABLED;
+               m88ds3103_pdata.lnb_en_pol = 1;
+
                switch (port->nr) {
                /* port b */
                case 1:
                        i2c_bus = &dev->i2c_bus[1];
-                       p_m88ds3103_config = &dvbsky_t9580_m88ds3103_config;
+                       m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
+                       m88ds3103_pdata.ts_clk = 16000;
+                       m88ds3103_pdata.ts_clk_pol = 1;
                        p_set_voltage = dvbsky_t9580_set_voltage;
                        break;
                /* port c */
                case 2:
                        i2c_bus = &dev->i2c_bus[0];
-                       p_m88ds3103_config = &dvbsky_s952_portc_m88ds3103_config;
+                       m88ds3103_pdata.ts_mode = M88DS3103_TS_SERIAL;
+                       m88ds3103_pdata.ts_clk = 96000;
+                       m88ds3103_pdata.ts_clk_pol = 0;
                        p_set_voltage = dvbsky_s952_portc_set_voltage;
                        break;
+               default:
+                       return 0;
                }
 
-               /* attach frontend */
-               fe0->dvb.frontend = dvb_attach(m88ds3103_attach,
-                               p_m88ds3103_config,
-                               &i2c_bus->i2c_adap, &adapter);
-               if (fe0->dvb.frontend == NULL)
-                       break;
+               memset(&info, 0, sizeof(info));
+               strlcpy(info.type, "m88ds3103", I2C_NAME_SIZE);
+               info.addr = 0x68;
+               info.platform_data = &m88ds3103_pdata;
+               request_module(info.type);
+               client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
+               if (client_demod == NULL || client_demod->dev.driver == NULL)
+                       goto frontend_detach;
+               if (!try_module_get(client_demod->dev.driver->owner)) {
+                       i2c_unregister_device(client_demod);
+                       goto frontend_detach;
+               }
+               port->i2c_client_demod = client_demod;
+               adapter = m88ds3103_pdata.get_i2c_adapter(client_demod);
+               fe0->dvb.frontend = m88ds3103_pdata.get_dvb_frontend(client_demod);
 
                /* attach tuner */
                memset(&ts2020_config, 0, sizeof(ts2020_config));
index 1f092febdbd18fead84f8569787c28d96750f6e3..4367cb3162b659e9018ece20c39ba51979a321d2 100644 (file)
@@ -267,7 +267,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
        struct cx23885_kernel_ir *kernel_ir;
        struct rc_dev *rc;
        char *rc_map;
-       enum rc_driver_type driver_type;
        u64 allowed_protos;
 
        int ret;
@@ -285,37 +284,32 @@ int cx23885_input_init(struct cx23885_dev *dev)
        case CX23885_BOARD_HAUPPAUGE_HVR1290:
        case CX23885_BOARD_HAUPPAUGE_HVR1250:
                /* Integrated CX2388[58] IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                /* The grey Hauppauge RC-5 remote */
                rc_map = RC_MAP_HAUPPAUGE;
                break;
        case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
                /* Integrated CX23885 IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                /* The grey Terratec remote with orange buttons */
                rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
                break;
        case CX23885_BOARD_TEVII_S470:
                /* Integrated CX23885 IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                /* A guess at the remote */
                rc_map = RC_MAP_TEVII_NEC;
                break;
        case CX23885_BOARD_MYGICA_X8507:
                /* Integrated CX23885 IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                /* A guess at the remote */
                rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02;
                break;
        case CX23885_BOARD_TBS_6980:
        case CX23885_BOARD_TBS_6981:
                /* Integrated CX23885 IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                /* A guess at the remote */
                rc_map = RC_MAP_TBS_NEC;
                break;
@@ -326,14 +320,12 @@ int cx23885_input_init(struct cx23885_dev *dev)
        case CX23885_BOARD_DVBSKY_S952:
        case CX23885_BOARD_DVBSKY_T982:
                /* Integrated CX23885 IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                rc_map = RC_MAP_DVBSKY;
                break;
        case CX23885_BOARD_TT_CT2_4500_CI:
                /* Integrated CX23885 IR controller */
-               driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_BIT_ALL;
+               allowed_protos = RC_BIT_ALL_IR_DECODER;
                rc_map = RC_MAP_TT_1500;
                break;
        default:
@@ -352,7 +344,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
                                    pci_name(dev->pci));
 
        /* input device */
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rc) {
                ret = -ENOMEM;
                goto err_out_free;
@@ -371,7 +363,6 @@ int cx23885_input_init(struct cx23885_dev *dev)
                rc->input_id.product = dev->pci->device;
        }
        rc->dev.parent = &dev->pci->dev;
-       rc->driver_type = driver_type;
        rc->allowed_protocols = allowed_protos;
        rc->priv = kernel_ir;
        rc->open = cx23885_input_ir_open;
index 4711583de8fe5325312cfb757f7c624cc27b11e0..519b81c0c8378fd02733b7bd897a00f8a780148e 100644 (file)
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 7c8edb6181ec888d233faa96eb59187d832aa310..b94eb1c0023d810c9ed7fcb50b9c88d4b222b5fe 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index af2ae7c5815a68cba3c79fa9e1aebd22e98578bc..2bc875d1ec9fafe536f500b377512b2cac889c50 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/mutex.h>
index 1fc2d24f5110ac400e80f94ec5112ba4f0bc42c7..55df64091539367aaec3ba231aa8a4ae744e8ab9 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __CX25821_AUDIO_H__
index 937f5a70fb7a8d8d032759a937ca889a45f11f64..7c0ada3e382dc6e99496bb9072f6ca5f8bab2c8e 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _BITFUNCS_H
index f2ebc989b30338b943e1406780a61a219db7c7fc..f3b4d89d90c8543a7da081c34ae26d8d29aa1ae7 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 9a5f912ca859a6951fb78bb3cf125eeeea4dfa4b..fbc0229183bde435df926fb388a4541c6372935f 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 95e8ddf629472afe938177a1be93bebf297d886a..76b8f619e55a5b423d0e31b7ba832ac6f67d6741 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 63ba25b826929ca9b91f7fab99fae849252f47a6..263a1cf36ef1c8370bd33a0b5332ea2f0f812c82 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 7a9e6470ba227db92d2a26fc89c83388fa6c3d89..36977090ec4c10ac0408208d234aea45f75a73b8 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _MEDUSA_DEF_H_
index 2e10643a86b7fb218b97beb274377796915e912a..6ef63b86787962668f9adf5bbad199910cd887d3 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MEDUSA_REGISTERS__
index 43bdfa4dfba11c54ecfdffc98a0ce07c77b070b7..0a9db050b1756d5c0988e5297dbc01aaf1f66ab5 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 8bf602ff27b1049e9bee6f0495ce205a4d753822..176b35333f2b631fe132ac23ed0a0f5a467183e2 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _MEDUSA_VIDEO_H
index a3fc25a4dc0bcfeb5699af9184bd12877851d882..061cdeb9b45b7cef50169e9a0452f2a0ffe7e5cb 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __CX25821_REGISTERS__
index 5f05d153bc4d5dc49d57fb800b5ab5511e5ce164..b94e0d4df6645341126fc9cb9d9bfdaac667cf3b 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __ATHENA_SRAM_H__
index a664997e1958dccdba7fbf6315d1d5b4606ca084..6c838c8a7924f7c067e986b98d264b801426eadc 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 268ec8aa6a6142844bedbb71aededb1be7a4f097..b6cf95f2d11bac6f089b4e1ce4a4fa4edec6404b 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/mutex.h>
index 7ce352a0f2d3af7dedee47239d792b669a986457..dbaf42ec26cd8efd4076a53419262fc0855f12fc 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index ab63b3858acf14b1853078903fc9af91e25444a0..246011c1ba084dd343c81d8424aa270e309a683c 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef CX25821_VIDEO_H_
index ef61dea982e8f864cde03d1ac114ea2879d8b032..0f20e89b0cdeda5aca1917cb6bce67f5aff9dc8a 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef CX25821_H_
index c7b3cb406499b0b7d0319f64cc0891e03bcd485a..01f2e472a2a09c9ba0bfd8b0d5bdb61f218c343f 100644 (file)
@@ -274,7 +274,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
                                 */
 
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!ir || !dev)
                goto err_out_free;
 
@@ -484,7 +484,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        dev->scancode_mask = hardware_mask;
 
        if (ir->sampling) {
-               dev->driver_type = RC_DRIVER_IR_RAW;
                dev->timeout = 10 * 1000 * 1000; /* 10 ms */
        } else {
                dev->driver_type = RC_DRIVER_SCANCODE;
index a6c9fe235974a81dd9f761182a1948d09a95ad1e..340cff02dee250b8c565517f83e7262b4f433cfb 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/module.h>
index a3ccb318b500055b4506707e5b19aed74a511e76..6ae810324b4e6df83d232c6ea29cda50704e3101 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 /* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */
index be87fbd9045646214f61aeda2f573ba1e62b1462..185b423818d38376028d9d0b79a5f6ebf6c21be2 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef _DDBRIDGE_H_
index 173daf0c084703419674b050c1872a077855a1b2..14fa7e40f2a62c744050901d6d8f98e900104d99 100644 (file)
@@ -1,6 +1,6 @@
 config DVB_DM1105
        tristate "SDMC DM1105 based PCI cards"
-       depends on DVB_CORE && PCI && I2C
+       depends on DVB_CORE && PCI && I2C && I2C_ALGOBIT
        select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
        select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
        select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
index a589aa78d1d98deed94e38b98deacb080d8b0e3a..a7724b78fbb463e9be1cef92eb55cd31f96eaba8 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <linux/i2c.h>
@@ -743,7 +739,7 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105)
        struct rc_dev *dev;
        int err = -ENOMEM;
 
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!dev)
                return -ENOMEM;
 
@@ -752,7 +748,6 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105)
 
        dev->driver_name = MODULE_NAME;
        dev->map_name = RC_MAP_DM1105_NEC;
-       dev->driver_type = RC_DRIVER_SCANCODE;
        dev->input_name = "DVB on-card IR receiver";
        dev->input_phys = dm1105->ir.input_phys;
        dev->input_id.bustype = BUS_PCI;
index 6e5867c57305253227096b3e9715bc92b4c761bd..c72cbbd2d40c601024cbef73d5cf4031e968cf70 100644 (file)
@@ -28,6 +28,19 @@ config VIDEO_IVTV
          To compile this driver as a module, choose M here: the
          module will be called ivtv.
 
+config VIDEO_IVTV_DEPRECATED_IOCTLS
+       bool "enable the DVB ioctls abuse on ivtv driver"
+       depends on VIDEO_IVTV
+       default n
+       ---help---
+         Enable the usage of the a DVB set of ioctls that were abused by
+         IVTV driver for a while.
+
+         Those ioctls were not needed for a long time, as IVTV implements
+         the proper V4L2 ioctls since kernel 3.3.
+
+         If unsure, say N.
+
 config VIDEO_IVTV_ALSA
        tristate "Conexant cx23415/cx23416 ALSA interface for PCM audio capture"
        depends on VIDEO_IVTV && SND
index 374f45f81ab300cb9a4ec4bcaf5eb09fe992e515..029f52733f70330bd3316ec7885b789403498012 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/initval.h>
-
 #include "ivtv-driver.h"
 #include "ivtv-version.h"
 #include "ivtv-alsa.h"
 #include "ivtv-alsa-mixer.h"
 #include "ivtv-alsa-pcm.h"
 
+#include <sound/core.h>
+#include <sound/initval.h>
+
 int ivtv_alsa_debug;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 
-#define IVTV_DEBUG_ALSA_INFO(fmt, arg...) \
+#define IVTV_DEBUG_ALSA_INFO(__fmt, __arg...) \
        do { \
                if (ivtv_alsa_debug & 2) \
-                       pr_info("%s: " fmt, "ivtv-alsa", ## arg); \
+                       printk(KERN_INFO pr_fmt("%s: alsa:" __fmt),     \
+                              __func__, ##__arg);                      \
        } while (0)
 
 module_param_named(debug, ivtv_alsa_debug, int, 0644);
@@ -235,8 +222,7 @@ static int ivtv_alsa_load(struct ivtv *itv)
 
        s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
        if (s->vdev.v4l2_dev == NULL) {
-               IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - skipping\n",
-                                    __func__);
+               IVTV_DEBUG_ALSA_INFO("PCM stream for card is disabled - skipping\n");
                return 0;
        }
 
@@ -250,8 +236,7 @@ static int ivtv_alsa_load(struct ivtv *itv)
                IVTV_ALSA_ERR("%s: failed to create struct snd_ivtv_card\n",
                              __func__);
        } else {
-               IVTV_DEBUG_ALSA_INFO("%s: created ivtv ALSA interface instance \n",
-                                    __func__);
+               IVTV_DEBUG_ALSA_INFO("created ivtv ALSA interface instance\n");
        }
        return 0;
 }
index 79b24bde4a39a6527008ca414e8a26c02eebd5c4..ba372a23eb5c0538273a349ba8f75ec9c34e539b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
+#include "ivtv-alsa.h"
+#include "ivtv-alsa-mixer.h"
+#include "ivtv-driver.h"
 
-#include <media/v4l2-device.h>
+#include <linux/videodev2.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/tlv.h>
 
-#include "ivtv-alsa.h"
-#include "ivtv-driver.h"
-
 /*
  * Note the cx25840-core volume scale is funny, due to the alignment of the
  * scale with another chip's range:
index cdde36704d53e1822264caf0637cb15e699a63ab..382bc36bc529534064f9d2e4cb84f45da0868ca1 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int __init snd_ivtv_mixer_create(struct snd_ivtv_card *itvsc);
index a26f9800eca34e55e88436edc0ea93a57e4b2cff..807ead20d212f559072e49673cdeb1c6492c8dcb 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-
-#include <media/v4l2-device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
 #include "ivtv-driver.h"
 #include "ivtv-queue.h"
 #include "ivtv-streams.h"
 #include "ivtv-alsa.h"
 #include "ivtv-alsa-pcm.h"
 
+#include <linux/vmalloc.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+
 static unsigned int pcm_debug;
 module_param(pcm_debug, int, 0644);
 MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
@@ -174,6 +166,7 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
        /* See if the stream is available */
        if (ivtv_claim_stream(&item, item.type)) {
                /* No, it's already in use */
+               v4l2_fh_exit(&item.fh);
                snd_ivtv_unlock(itvsc);
                return -EBUSY;
        }
index 186814e0b2d4d1a19dcebdf0f42d79ca024bd5fb..147586a886fc988b140f87cdbb24a72075f48d16 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
index 4a0d8f2c254deca6e740a599b6af19245bbd32d9..eae6462233674e481960a9fea31e251309860470 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *  02111-1307  USA
  */
 
 struct snd_card;
index 0a3b80a4bd69d69e0b967156d42d3148a2e22729..ab2ae53618e829e926a78162d146aa91766762ef 100644 (file)
@@ -1452,7 +1452,7 @@ static void ivtv_remove(struct pci_dev *pdev)
        for (i = 0; i < IVTV_VBI_FRAMES; i++)
                kfree(itv->vbi.sliced_mpeg_data[i]);
 
-       printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
+       pr_info("Removed %s\n", itv->card_name);
 
        v4l2_device_unregister(&itv->v4l2_dev);
        kfree(itv);
@@ -1468,25 +1468,25 @@ static struct pci_driver ivtv_pci_driver = {
 
 static int __init module_start(void)
 {
-       printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION);
+       pr_info("Start initialization, version %s\n", IVTV_VERSION);
 
        /* Validate parameters */
        if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) {
-               printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n",
+               pr_err("Exiting, ivtv_first_minor must be between 0 and %d\n",
                     IVTV_MAX_CARDS - 1);
                return -1;
        }
 
        if (ivtv_debug < 0 || ivtv_debug > 2047) {
                ivtv_debug = 0;
-               printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 2047\n");
+               pr_info("Debug value must be >= 0 and <= 2047\n");
        }
 
        if (pci_register_driver(&ivtv_pci_driver)) {
-               printk(KERN_ERR "ivtv: Error detecting PCI card\n");
+               pr_err("Error detecting PCI card\n");
                return -ENODEV;
        }
-       printk(KERN_INFO "ivtv: End initialization\n");
+       pr_info("End initialization\n");
        return 0;
 }
 
index 6b09a9514d649925028ed6af3358532f109c5218..cde452e30746793dd781de9c392e42d6e2421973 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef IVTV_DRIVER_H
 #define IVTV_DRIVER_H
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 /* Internal header for ivtv project:
  * Driver for the cx23415/6 chip.
  * Author: Kevin Thayer (nufan_wfk at yahoo.com)
  *                using information provided by Jiun-Kuei Jung @ AVerMedia.
  */
 
-#include <linux/module.h>
-#include <linux/init.h>
+#include <asm/byteorder.h>
 #include <linux/delay.h>
-#include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ivtv.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/list.h>
-#include <linux/unistd.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/pagemap.h>
+#include <linux/pci.h>
 #include <linux/scatterlist.h>
-#include <linux/kthread.h>
-#include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/uaccess.h>
-#include <asm/byteorder.h>
+#include <linux/unistd.h>
 
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
+#include <media/drv-intf/cx2341x.h>
+#include <media/i2c/ir-kbd-i2c.h>
+#include <media/tuner.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fh.h>
-#include <media/tuner.h>
-#include <media/drv-intf/cx2341x.h>
-#include <media/i2c/ir-kbd-i2c.h>
-
-#include <linux/ivtv.h>
+#include <media/v4l2-ioctl.h>
 
 /* Memory layout */
 #define IVTV_ENCODER_OFFSET    0x00000000
index 2dc4b20f3ac0a80773167a6a8ef52d5a042581c5..f956188f7f196699d4279a66a2a0c55b1a683e1b 100644 (file)
 #include <media/i2c/saa7127.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-event.h>
+#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
 #include <linux/dvb/audio.h>
+#include <linux/dvb/video.h>
+#endif
 
 u16 ivtv_service2vbi(int type)
 {
@@ -1620,13 +1623,23 @@ static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder
        return ivtv_video_command(itv, id, dec, true);
 }
 
+#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
+static __inline__ void warn_deprecated_ioctl(const char *name)
+{
+       pr_warn_once("warning: the %s ioctl is deprecated. Don't use it, as it will be removed soon\n",
+                    name);
+}
+#endif
+
 static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 {
        struct ivtv_open_id *id = fh2id(filp->private_data);
        struct ivtv *itv = id->itv;
-       int nonblocking = filp->f_flags & O_NONBLOCK;
        struct ivtv_stream *s = &itv->streams[id->type];
+#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
+       int nonblocking = filp->f_flags & O_NONBLOCK;
        unsigned long iarg = (unsigned long)arg;
+#endif
 
        switch (cmd) {
        case IVTV_IOC_DMA_FRAME: {
@@ -1658,12 +1671,12 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                        return -EINVAL;
                return ivtv_passthrough_mode(itv, *(int *)arg != 0);
-
+#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
        case VIDEO_GET_PTS: {
                s64 *pts = arg;
                s64 frame;
 
-               IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
+               warn_deprecated_ioctl("VIDEO_GET_PTS");
                if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
                        *pts = s->dma_pts;
                        break;
@@ -1677,7 +1690,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                s64 *frame = arg;
                s64 pts;
 
-               IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
+               warn_deprecated_ioctl("VIDEO_GET_FRAME_COUNT");
                if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
                        *frame = 0;
                        break;
@@ -1690,7 +1703,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        case VIDEO_PLAY: {
                struct v4l2_decoder_cmd dc;
 
-               IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
+               warn_deprecated_ioctl("VIDEO_PLAY");
                memset(&dc, 0, sizeof(dc));
                dc.cmd = V4L2_DEC_CMD_START;
                return ivtv_video_command(itv, id, &dc, 0);
@@ -1699,7 +1712,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        case VIDEO_STOP: {
                struct v4l2_decoder_cmd dc;
 
-               IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
+               warn_deprecated_ioctl("VIDEO_STOP");
                memset(&dc, 0, sizeof(dc));
                dc.cmd = V4L2_DEC_CMD_STOP;
                dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
@@ -1709,7 +1722,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        case VIDEO_FREEZE: {
                struct v4l2_decoder_cmd dc;
 
-               IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
+               warn_deprecated_ioctl("VIDEO_FREEZE");
                memset(&dc, 0, sizeof(dc));
                dc.cmd = V4L2_DEC_CMD_PAUSE;
                return ivtv_video_command(itv, id, &dc, 0);
@@ -1718,7 +1731,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        case VIDEO_CONTINUE: {
                struct v4l2_decoder_cmd dc;
 
-               IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
+               warn_deprecated_ioctl("VIDEO_CONTINUE");
                memset(&dc, 0, sizeof(dc));
                dc.cmd = V4L2_DEC_CMD_RESUME;
                return ivtv_video_command(itv, id, &dc, 0);
@@ -1732,9 +1745,9 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                int try = (cmd == VIDEO_TRY_COMMAND);
 
                if (try)
-                       IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
+                       warn_deprecated_ioctl("VIDEO_TRY_COMMAND");
                else
-                       IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
+                       warn_deprecated_ioctl("VIDEO_COMMAND");
                return ivtv_video_command(itv, id, dc, try);
        }
 
@@ -1742,7 +1755,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                struct video_event *ev = arg;
                DEFINE_WAIT(wait);
 
-               IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
+               warn_deprecated_ioctl("VIDEO_GET_EVENT");
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                        return -EINVAL;
                memset(ev, 0, sizeof(*ev));
@@ -1785,28 +1798,28 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        }
 
        case VIDEO_SELECT_SOURCE:
-               IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
+               warn_deprecated_ioctl("VIDEO_SELECT_SOURCE");
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                        return -EINVAL;
                return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
 
        case AUDIO_SET_MUTE:
-               IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
+               warn_deprecated_ioctl("AUDIO_SET_MUTE");
                itv->speed_mute_audio = iarg;
                return 0;
 
        case AUDIO_CHANNEL_SELECT:
-               IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
+               warn_deprecated_ioctl("AUDIO_CHANNEL_SELECT");
                if (iarg > AUDIO_STEREO_SWAPPED)
                        return -EINVAL;
                return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
 
        case AUDIO_BILINGUAL_CHANNEL_SELECT:
-               IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
+               warn_deprecated_ioctl("AUDIO_BILINGUAL_CHANNEL_SELECT");
                if (iarg > AUDIO_STEREO_SWAPPED)
                        return -EINVAL;
                return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
-
+#endif
        default:
                return -EINVAL;
        }
@@ -1821,6 +1834,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
        if (!valid_prio) {
                switch (cmd) {
                case IVTV_IOC_PASSTHROUGH_MODE:
+#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
                case VIDEO_PLAY:
                case VIDEO_STOP:
                case VIDEO_FREEZE:
@@ -1830,6 +1844,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
                case AUDIO_SET_MUTE:
                case AUDIO_CHANNEL_SELECT:
                case AUDIO_BILINGUAL_CHANNEL_SELECT:
+#endif
                        return -EBUSY;
                }
        }
@@ -1847,6 +1862,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
 
        case IVTV_IOC_DMA_FRAME:
        case IVTV_IOC_PASSTHROUGH_MODE:
+#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
        case VIDEO_GET_PTS:
        case VIDEO_GET_FRAME_COUNT:
        case VIDEO_GET_EVENT:
@@ -1860,6 +1876,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
        case AUDIO_SET_MUTE:
        case AUDIO_CHANNEL_SELECT:
        case AUDIO_BILINGUAL_CHANNEL_SELECT:
+#endif
                return ivtv_decoder_ioctls(file, cmd, (void *)arg);
 
        default:
index e3ce967637853d906756009cce321c930c2f82c9..9a2506a5edbebaaa58182ae345462121923ca92a 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <stdarg.h>
-
 #include "ivtv-driver.h"
 #include "ivtv-mailbox.h"
 
+#include <stdarg.h>
+
 /* Firmware mailbox flags*/
 #define IVTV_MBOX_FIRMWARE_DONE 0x00000004
 #define IVTV_MBOX_DRIVER_DONE   0x00000002
index 612a8402cf4d66efe50e6a103a604abd64ad2f8e..621b2f613d818dbc7ae8f9ddf9fa3310010aaabb 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include "ivtv-driver.h"
+#include "ivtv-cards.h"
+#include "ivtv-i2c.h"
+#include "ivtv-udma.h"
+#include "ivtv-mailbox.h"
+#include "ivtv-firmware.h"
 
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/fb.h>
 #include <linux/ivtvfb.h>
-#include <linux/slab.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/pat.h>
 #endif
 
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-i2c.h"
-#include "ivtv-udma.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-firmware.h"
-
 /* card parameters */
 static int ivtvfb_card_id = -1;
 static int ivtvfb_debug = 0;
@@ -1275,7 +1270,7 @@ static int __init ivtvfb_init(void)
 
 
        if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
-               printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
+               pr_err("ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
                     IVTV_MAX_CARDS - 1);
                return -EINVAL;
        }
@@ -1284,7 +1279,7 @@ static int __init ivtvfb_init(void)
        err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
        (void)err;      /* suppress compiler warning */
        if (!registered) {
-               printk(KERN_ERR "ivtvfb:  no cards found\n");
+               pr_err("no cards found\n");
                return -ENODEV;
        }
        return 0;
@@ -1295,7 +1290,7 @@ static void ivtvfb_cleanup(void)
        struct device_driver *drv;
        int err;
 
-       printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
+       pr_info("Unloading framebuffer module\n");
 
        drv = driver_find("ivtv", &pci_bus_type);
        err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
index 5a71e1791cf5a00ab1d198520c380cf7a44c1890..0db4de3a228522089de86ec2a5ce7314fde64b37 100644 (file)
@@ -226,11 +226,12 @@ int mantis_dvb_init(struct mantis_pci *mantis)
                        goto err5;
                } else {
                        if (mantis->fe == NULL) {
+                               result = -ENOMEM;
                                dprintk(MANTIS_ERROR, 1, "FE <NULL>");
                                goto err5;
                        }
-
-                       if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
+                       result = dvb_register_frontend(&mantis->dvb_adapter, mantis->fe);
+                       if (result) {
                                dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
 
                                if (mantis->fe->ops.release)
index 7f7f1d4d7bb1a98984ae03691a20c1d95445bc5e..50d10cb7d49de0fd5222fdf28d55fd3839440f09 100644 (file)
@@ -39,7 +39,7 @@ int mantis_input_init(struct mantis_pci *mantis)
        struct rc_dev *dev;
        int err;
 
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!dev) {
                dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
                err = -ENOMEM;
index 24fba633c21712fa7cc4eec56420dd809a3ea922..9c4a024745de055571c6696daa4f4caf6cdb0c0a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -1663,6 +1659,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
                goto outenabledev;
        }
 
+       ret = -EIO;
        mchip_adr = pci_resource_start(meye.mchip_dev,0);
        if (!mchip_adr) {
                v4l2_err(v4l2_dev, "meye: mchip has no device base address\n");
index 751be5e533c7e12eeff2ff40a78396223b4943b6..c4a8a5fe040c5dba757baf73528b5ab411a7adff 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _MEYE_PRIV_H_
index 423e8c8893109f45bda279a157a8e0f9c69a0b1a..bb49620540c5129f4a3ee05e2484a7e2a7694b12 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/module.h>
@@ -781,12 +777,6 @@ static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
        return PCI_ERS_RESULT_CAN_RECOVER;
 }
 
-static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
-{
-       printk(KERN_INFO DEVICE_NAME ": link reset\n");
-       return 0;
-}
-
 static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
 {
        printk(KERN_INFO DEVICE_NAME ": slot reset\n");
@@ -800,7 +790,6 @@ static void ngene_resume(struct pci_dev *dev)
 
 static const struct pci_error_handlers ngene_errors = {
        .error_detected = ngene_error_detected,
-       .link_reset = ngene_link_reset,
        .slot_reset = ngene_slot_reset,
        .resume = ngene_resume,
 };
index 4e924e2d1638fe2d98d034f90e0263070dab1982..ce69e648b663a934f5ace1c834e8c0b1642d044a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/module.h>
index 59bb2858c8d0127c8779f3323b8f1d1a25b832e2..03fc218a45e95e2e742eb1ba8a55a4bdf3e09f7e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/module.h>
index d28554f8ce9961f1102a9a22e8f28d71f057e7cd..cf39fcf54adfb812ca691caa68e09ddcbb434947 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 /* FIXME - some of these can probably be removed */
index fa30930d70477cc7c0f48644e3a414ca1847504d..10d8f74c4f0a50a4f282b0211b8bb0b616919d5a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef _NGENE_H_
index 65afb71ff79fef1bebb13e7ce29836047251d413..74838109afe554812354984363419243f2c7a5fb 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <linux/i2c.h>
index d5ee82aee9e8518d983f17ac331f87a6f74d9f70..da1eebd2016f5c45ff0615d44b05b31a29f06b10 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index 249273b2e0f22af7792b5a0b3b7eaf633b4d6ff8..f75f69556be7e2fc98dfb2314c9378f152accd99 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index b7d6f05a0e02fc26e20e674081add247977ec082..efbe6ccae8b42ee3093c55c7fa9450b58a04c9e2 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef VA1J5JF8007S_H
index e0766e69a37083e4ca21276b0e01c2072b399922..63fda79a75c0498517c0088fa132283f05ffb9ec 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index 2903be519ef55039a29a308ce4e63b3cf32f99bf..6fb119c6e73ac303bd19afbf7fb74f40a2f7a9c2 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef VA1J5JF8007T_H
index 8a35ecfb75e38d41f2a11d93831d3032cd17cafc..bf358ec7aca57167429de6843825811c15704e00 100644 (file)
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #include "saa7134.h"
index 2b60af493de4330e5a99e9036a01cafd804dc4e6..321253827997a2c163893126e9ef444c355c50d6 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index 7d6bb5c9343f76d651c123429214aeb667e5d8b1..7976c5a12ca85af06235f458bea1e613bf571099 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index 598b8bbfe726413dde7c24b812a7ed2a2a37ec4c..efdece5ab11cb9f855225819af15626c84fe2e26 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index f0fe2524259f0799e1ba9b6986b8310fb02839c2..b1d3648dcba1898502bc84d1f05b11be17d02294 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index dca0592c5f47157bae6d1b85a751bb51f7aee6fe..9d0e69eae036fafe8e2001a330a7139174f8b1f9 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index 823b75ed47e152e00890ddf38a742df83ffb4d3d..78849c19f68a97232c3fb02d549196c77e3937e8 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #include "saa7134.h"
@@ -846,7 +842,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        }
 
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!ir || !rc) {
                err = -ENOMEM;
                goto err_out_free;
index 7eaf36a41db9ea05c415b3836935b0022f628b8d..578e03f8c04157bb24c1346bd1eb870c7292ef31 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index 38f94b742e28354b407f25a002f619685136813d..68d400e1e240e9c785c73256fa1595a419c9d8d8 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index cf9a31e0a390783fbe2b3431b950090ffdf81147..46193370e41a41c872c76de6f25a56c9c586757a 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index cbb173d990853840f7a364494613c0028cb97ede..4b1c4327f1127418ada7260d739070bca3dd3b24 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7134.h"
index 3849083526a7ac24f0a3b3976ae9d38131bd3b28..816b5282d6710639f2869e15e7fda9c4037b38b3 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define SAA7134_VERSION "0, 2, 17"
index e7e586c1ba535af882a2159f5e33ae2f0286ef91..e318ccf81277d26dda436a3e057dd90c8ca0380f 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/wait.h>
index 62c34504199df6f8021bd5f1594688e560a140df..a0d2129c6ca97ff0c464eace88904523cba69ac1 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/slab.h>
index e305c02f9dc9d9a06a54e6bd2ef08664b96c61c5..b2ff82fa7116962b718aebd3213ab7036e8b02ba 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7164.h"
index 15a98c638c5563d48bdb75c6115c42081d507984..0e1cd7e153ca83ba08c13061eabd38f179a58d5c 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
index 45951b3cc251c6ab21f670bd5d8d902f1f60fabf..f55c177fd1e4ac7155abe8eacdc8088d5eaa79f5 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/wait.h>
index 03a1511a92be2c870951f199ec60ba06b441b97a..75eed4cc4823062d1cd53debf9c5d395dbe428a9 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
index cd3eeda5250bf8bf113b0fe82c1139599452b3dd..e76d3bafe2ce246ff8dceaf9c3db09054c0c7d3f 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7164.h"
index 68124ce7ebc39ab7ab158fa2fb26a19fe1fcd1c7..f21c245a54f7243603ec30fcbe7462cb7ffd410e 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7164.h"
index 8568adfd7ece9e1a48f2fa2f8a3ec12b2f9b0591..4ba5eade7ce29bc5863be57de7147e8f22c116d8 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/firmware.h>
@@ -309,7 +305,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
                                        break;
                                }
                                if (err_flags & SAA_DEVICE_NO_IMAGE) {
-                                       printk(KERN_ERR "%s() no first image\n",
+                                       printk(KERN_ERR "%s() no second image\n",
                                                __func__);
                                        break;
                                }
index 024f4e29e8400d192b566966b9b291511907e1af..430f6789f222cc9573695177abd56e4bea99f7f9 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 37521a2ee50453a924478123c7efa7f30532fb11..5cf842112e4345f6cd10439f17bcb2793dbc2462 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /* TODO: Retest the driver with errors expressed as negatives */
index 1efba6c64ebfad0c684f2fa20bcea2688c829003..ae241103b2611633dbeab11695c53c04609c886e 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /* TODO: Cleanup and shorten the namespace */
index e5dcb81029d3be2f74b2637ececf2fc3f5d62c4a..9255d7d23947252299c12a5bf041e1ea2eda4203 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "saa7164.h"
index 97411b0384c15b32a7ada4f41e93fb06ecaa947e..81b3f0e1999370d527422d6890b49d1d387547b4 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
index 826c7c75e64d13cdcea14a8c5c35981fc2085041..d2730c3fdbae5b60ae22a7fc8ac6af1ceb4ecbbc 100644 (file)
@@ -183,7 +183,7 @@ int smi_ir_init(struct smi_dev *dev)
        struct rc_dev *rc_dev;
        struct smi_rc *ir = &dev->ir;
 
-       rc_dev = rc_allocate_device();
+       rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!rc_dev)
                return -ENOMEM;
 
@@ -202,7 +202,6 @@ int smi_ir_init(struct smi_dev *dev)
        rc_dev->input_id.product = dev->pci_dev->subsystem_device;
        rc_dev->dev.parent = &dev->pci_dev->dev;
 
-       rc_dev->driver_type = RC_DRIVER_SCANCODE;
        rc_dev->map_name = dev->info->rc_map;
 
        ir->rc_dev = rc_dev;
index 6a35107aca255b88555297567feb44c8f6eb74bc..36e93540bb49b9384158c50487aeec6aa6295ee2 100644 (file)
@@ -350,7 +350,7 @@ static int solo_snd_pcm_init(struct solo_dev *solo_dev)
 
 int solo_g723_init(struct solo_dev *solo_dev)
 {
-       static struct snd_device_ops ops = { NULL };
+       static struct snd_device_ops ops = { };
        struct snd_card *card;
        struct snd_kcontrol_new kctl;
        char name[32];
index aeb2b4e2db35cf500535586ccc2562f83f557859..6343d24eb1d591510967f7f624430c39410d1f8a 100644 (file)
@@ -377,7 +377,7 @@ static void stop_streaming(struct vb2_queue *vq)
        spin_unlock(&vip->lock);
 }
 
-static struct vb2_ops vip_video_qops = {
+static const struct vb2_ops vip_video_qops = {
        .queue_setup            = queue_setup,
        .buf_init               = buffer_init,
        .buf_prepare            = buffer_prepare,
index 4f81a13666eb22fd37401ee1f8c6216bbe5649ab..61e5c4822b52b2bf26c0ce7b91aef91b6f346419 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  * Author:  Anders Wallin <anders.wallin@windriver.com>
  *
  */
index 6e63949d6ad0b7285d2fcc16e4640dfd54a4b063..df9395c87178c8941c1174a7e673448c4c631080 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 26c5696c193bf244aa098e6c99e205dc4475710b..2aa4ba675194e2eb02e5825ce94147e19270a53d 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 96a130fb4595729b880aab0aba9ab4ab75faddb8..f64723aea56be2c3dc8602eb9ade71ec70648aab 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 520414cbe087b30ca2cb199eb2ba1cd06219eb0b..b2b79bb739176c019aae693cc63de96690d47aad 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  * the project's page is at https://linuxtv.org
  */
    by Nathan Laredo <laredo@gnu.org> */
 
 int av7110_debiwrite(struct av7110 *av7110, u32 config,
-                    int addr, u32 val, int count)
+                    int addr, u32 val, unsigned int count)
 {
        struct saa7146_dev *dev = av7110->dev;
 
-       if (count <= 0 || count > 32764) {
+       if (count > 32764) {
                printk("%s: invalid count %d\n", __func__, count);
                return -1;
        }
@@ -78,12 +75,12 @@ int av7110_debiwrite(struct av7110 *av7110, u32 config,
        return 0;
 }
 
-u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
+u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, unsigned int count)
 {
        struct saa7146_dev *dev = av7110->dev;
        u32 result = 0;
 
-       if (count > 32764 || count <= 0) {
+       if (count > 32764) {
                printk("%s: invalid count %d\n", __func__, count);
                return 0;
        }
index 1634aba5cb84693bfde178dba08f5dc32ab3ab91..ccb1480594068f4058ac8c774cbc888ea16818be 100644 (file)
@@ -377,14 +377,14 @@ extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
 
 /* DEBI (saa7146 data extension bus interface) access */
 extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
-                           int addr, u32 val, int count);
+                           int addr, u32 val, unsigned int count);
 extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
-                          int addr, int count);
+                          int addr, unsigned int count);
 
 
 /* DEBI during interrupt */
 /* single word writes */
-static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, unsigned int count)
 {
        av7110_debiwrite(av7110, config, addr, val, count);
 }
@@ -397,7 +397,7 @@ static inline void mwdebi(struct av7110 *av7110, u32 config, int addr,
        av7110_debiwrite(av7110, config, addr, 0, count);
 }
 
-static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, unsigned int count)
 {
        u32 res;
 
@@ -408,7 +408,7 @@ static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, i
 }
 
 /* DEBI outside interrupts, only for count <= 4! */
-static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, unsigned int count)
 {
        unsigned long flags;
 
@@ -417,7 +417,7 @@ static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, i
        spin_unlock_irqrestore(&av7110->debilock, flags);
 }
 
-static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
+static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, unsigned int count)
 {
        unsigned long flags;
        u32 res;
index 0e763a784e2b44d6d12c78d83cc2be5cbc7918ab..10e28f067b4551fd427c3bdc07a20742b481e2d1 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  */
 
index 479aff02db81b72e93fda83896b2b6c2be19b4d9..397fe146dedd12753aa92ea68e3ab5e1d116f315 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  * the project's page is at https://linuxtv.org
  */
index 896c66d4b3ae74207aebea6da7830e6a4c46614e..19f07d4aba6acc9388b25aa7d8ed1073281a6368 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 20ad93bf0f544568ffe6aed0a3245564e67f699f..68355484ba7d5bd828cd3a8d9ec5f2e51574f90d 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
@@ -177,7 +174,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
        struct rc_dev *dev;
        int error;
 
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!dev) {
                printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
                return -ENOMEM;
index 6d42dcfd4825bd85348260de5ea3b0a85cfec758..97499b2af71442ffd4db39151be5252df0710d63 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index f152eda0123a3bb34cd12acc2b1415ebfe52edbf..44299237200846c30b9ab6dae3316b6a95a9be04 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 3091b480ce222c295c8985b4e75113b432cf0081..5f17e1c9a20745ce6322992ea023ad2360c86e84 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  *
  *
  * the project's page is at https://linuxtv.org
index 375e3be184b1afc54bacb55ad951948e819ed1c9..3d410d02a987f297524a2b7a1d72cc985831eae4 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #ifndef _DVB_FILTER_H_
index 71a0453b1af15dabea389e82fd22111d3f269dce..336e2f9bc1b6363045f4890c662299d8009f5e30 100644 (file)
@@ -74,7 +74,7 @@ static const char *dma_mode_name(unsigned int mode)
 
 static int tw686x_dma_mode_get(char *buffer, struct kernel_param *kp)
 {
-       return sprintf(buffer, dma_mode_name(dma_mode));
+       return sprintf(buffer, "%s", dma_mode_name(dma_mode));
 }
 
 static int tw686x_dma_mode_set(const char *val, struct kernel_param *kp)
index 3c3cbce0f9ccaa83d965e008126ebcc8ebe29403..303289a7fd3f614846ca4252c47c37de519df455 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index def55585ad2321901c19f4c709eb6caa924b6d4f..8ed5a0f7ac018df4d63ab066c53d32852bd960e5 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index 4e7db8939c2be89cf9a7f580f2df92f2b9bad23c..9bb3c21aa2757a8aa1f18ace1c25c4fbe898c9ae 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _BUZ_H_
index 9d2697f5b455d261b0bdc9447cf13e764a398e14..5266755add63de6e9f93876b8ff0e89a4d9416cb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/delay.h>
index 4936fead73e8693cfab4a2ad7ebb9111be92a1e7..81cba177cd9027a5c883d0e1f3d93cf4e329d405 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __ZORAN_CARD_H__
index 35b552c178dae86f3623024a36f81030c940781a..671907a6e6b631d780593fff55a3254ad00020e1 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/types.h>
index 07f2c23ff7401a3b5e6653f0133477939c4ca2a3..a507aaad4ebbb579745682971670623aad8cb744 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __ZORAN_DEVICE_H__
index 94b9b616df989e29d24af197471fb921e3190c73..180f3d7af3e1d1426a9d8a9675e6e71304326679 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
@@ -975,6 +971,7 @@ static int zoran_open(struct file *file)
        return 0;
 
 fail_fh:
+       v4l2_fh_exit(&fh->fh);
        kfree(fh);
 fail_unlock:
        mutex_unlock(&zr->lock);
index 437652761093746e8536ef5ca04e9ca1a9e3df79..78ac8f853748e73e3bd6c7fb18ba86f14fb067c8 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/types.h>
index f2d5b1ba448f4b8c8dc4baa9dbe14bcd56e52eeb..0ac7cb0011f281f27b7f3eda900a652960050633 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __ZORAN_PROCFS_H__
index c12ca9f96bac40a825ac3ce8bede2ffc3c32d6fc..8736b9d8d97eb7d7cfe47225c665c7d61c8d86d5 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index 8c79229f69d1a5e4e85eeb761073e35f5bda9435..784bcf5727b865e36d7852c195d2b9a71c2b6b4c 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index e1985609af4bc416a7ba7d6e42f7dd872461ad9e..5ebfc16672f378e6ae7ec12469e11e868ffd2ce8 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index ea083adda04579e8c8875bbec020da59a935a985..9236486d3c2b56a700e365202bfb306f79cec269 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index 54c9362aa98059879300ab6e7700b041176e688a..c9ffef15532db1f5107779bbc02979bb57632989 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _ZR36057_H_
index f08546fe22347718777c8b330b9ec4ce54bb91d5..2c2e8130fc96c1d8efa07ea8fa39f0ea3e88cc93 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index 914ffa4ad8d3bde7f6219c672ea4382048179f56..82911757ba782c3004a5455707e0a85df0e95597 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * ------------------------------------------------------------------------
  */
 
index d944421e392d7b0af9e1c93b6bd63ea902bc5e60..c9106e105baba8eba37a36e6e27e1e6a28feea17 100644 (file)
@@ -162,6 +162,9 @@ config VIDEO_CODA
           Coda is a range of video codec IPs that supports
           H.264, MPEG-4, and other video formats.
 
+config VIDEO_IMX_VDOA
+       def_tristate VIDEO_CODA if SOC_IMX6Q || COMPILE_TEST
+
 config VIDEO_MEDIATEK_VPU
        tristate "Mediatek Video Processor Unit"
        depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
@@ -298,6 +301,56 @@ config VIDEO_STI_HVA
          To compile this driver as a module, choose M here:
          the module will be called st-hva.
 
+config VIDEO_STI_HVA_DEBUGFS
+       bool "Export STMicroelectronics HVA internals in debugfs"
+       depends on VIDEO_STI_HVA
+       depends on DEBUG_FS
+       help
+         Select this to see information about the internal state and the last
+          operation of STMicroelectronics HVA multi-format video encoder in
+          debugfs.
+
+          Choose N unless you know you need this.
+
+config VIDEO_STI_DELTA
+       tristate "STMicroelectronics DELTA multi-format video decoder V4L2 driver"
+       depends on VIDEO_DEV && VIDEO_V4L2
+       depends on ARCH_STI || COMPILE_TEST
+       depends on HAS_DMA
+       help
+               This V4L2 driver enables DELTA multi-format video decoder
+               of STMicroelectronics STiH4xx SoC series allowing hardware
+               decoding of various compressed video bitstream format in
+               raw uncompressed format.
+
+               Use this option to see the decoders available for such
+               hardware.
+
+               Please notice that the driver will only be built if
+               at least one of the DELTA decoder below is selected.
+
+if VIDEO_STI_DELTA
+
+config VIDEO_STI_DELTA_MJPEG
+       bool "STMicroelectronics DELTA MJPEG support"
+       default y
+       help
+               Enables DELTA MJPEG hardware support.
+
+               To compile this driver as a module, choose M here:
+               the module will be called st-delta.
+
+config VIDEO_STI_DELTA_DRIVER
+       tristate
+       depends on VIDEO_STI_DELTA
+       depends on VIDEO_STI_DELTA_MJPEG
+       default VIDEO_STI_DELTA_MJPEG
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_MEM2MEM_DEV
+       select RPMSG
+
+endif # VIDEO_STI_DELTA
+
 config VIDEO_SH_VEU
        tristate "SuperH VEU mem2mem video processing driver"
        depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
index 5b3cb271d2b8ccf3a2d47a00dcfe90bdb5a95e3c..349ddf6a69da2183b5e36d303add55aa79d68793 100644 (file)
@@ -39,6 +39,8 @@ obj-$(CONFIG_VIDEO_STI_BDISP)         += sti/bdisp/
 obj-$(CONFIG_VIDEO_STI_HVA)            += sti/hva/
 obj-$(CONFIG_DVB_C8SECTPFE)            += sti/c8sectpfe/
 
+obj-$(CONFIG_VIDEO_STI_DELTA)          += sti/delta/
+
 obj-$(CONFIG_BLACKFIN)                  += blackfin/
 
 obj-$(CONFIG_ARCH_DAVINCI)             += davinci/
index b33b9e35e60e4aac658fb370379ff8f11b062c28..05489a401c5c1506efbd7f742ac7ea81e3276ef7 100644 (file)
@@ -1576,7 +1576,7 @@ static int vpfe_s_fmt(struct file *file, void *priv,
                return -EBUSY;
        }
 
-       ret = vpfe_try_fmt(file, priv, &format);
+       ret = __vpfe_get_format(vpfe, &format, &bpp);
        if (ret)
                return ret;
 
index 2e6edc09b58fb0bb755a0bb75cfcc45b44ad84e8..1c5166df46f58dfd07a246672b907815643119db 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/completion.h>
index b8f3d9fa66e907ca54c0e61972c5c2bbacfad2b5..37169054b82888be7923c0d1a83751245a30710b 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 9342ac57b23067823bba23901bb294969bc77219..858284328af9dae700a43b1db3b64fce5a99f398 100644 (file)
@@ -3,3 +3,4 @@ ccflags-y += -I$(src)
 coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o coda-jpeg.o
 
 obj-$(CONFIG_VIDEO_CODA) += coda.o
+obj-$(CONFIG_VIDEO_IMX_VDOA) += imx-vdoa.o
index b6625047250d62c40ca153606aa0227ee4f4de86..466a44e4549e5e611d13a5b3d08f91571524301d 100644 (file)
@@ -30,6 +30,7 @@
 #include <media/videobuf2-vmalloc.h>
 
 #include "coda.h"
+#include "imx-vdoa.h"
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
@@ -758,7 +759,7 @@ static void coda9_set_frame_cache(struct coda_ctx *ctx, u32 fourcc)
                cache_config = 1 << CODA9_CACHE_PAGEMERGE_OFFSET;
        }
        coda_write(ctx->dev, cache_size, CODA9_CMD_SET_FRAME_CACHE_SIZE);
-       if (fourcc == V4L2_PIX_FMT_NV12) {
+       if (fourcc == V4L2_PIX_FMT_NV12 || fourcc == V4L2_PIX_FMT_YUYV) {
                cache_config |= 32 << CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET |
                                16 << CODA9_CACHE_CR_BUFFER_SIZE_OFFSET |
                                0 << CODA9_CACHE_CB_BUFFER_SIZE_OFFSET;
@@ -1517,6 +1518,10 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
        u32 val;
        int ret;
 
+       v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
+                "Video Data Order Adapter: %s\n",
+                ctx->use_vdoa ? "Enabled" : "Disabled");
+
        /* Start decoding */
        q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
        q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
@@ -1532,10 +1537,11 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
 
        ctx->frame_mem_ctrl &= ~(CODA_FRAME_CHROMA_INTERLEAVE | (0x3 << 9) |
                                 CODA9_FRAME_TILED2LINEAR);
-       if (dst_fourcc == V4L2_PIX_FMT_NV12)
+       if (dst_fourcc == V4L2_PIX_FMT_NV12 || dst_fourcc == V4L2_PIX_FMT_YUYV)
                ctx->frame_mem_ctrl |= CODA_FRAME_CHROMA_INTERLEAVE;
        if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP)
-               ctx->frame_mem_ctrl |= (0x3 << 9) | CODA9_FRAME_TILED2LINEAR;
+               ctx->frame_mem_ctrl |= (0x3 << 9) |
+                       ((ctx->use_vdoa) ? 0 : CODA9_FRAME_TILED2LINEAR);
        coda_write(dev, ctx->frame_mem_ctrl, CODA_REG_BIT_FRAME_MEM_CTRL);
 
        ctx->display_idx = -1;
@@ -1618,6 +1624,15 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
                 __func__, ctx->idx, width, height);
 
        ctx->num_internal_frames = coda_read(dev, CODA_RET_DEC_SEQ_FRAME_NEED);
+       /*
+        * If the VDOA is used, the decoder needs one additional frame,
+        * because the frames are freed when the next frame is decoded.
+        * Otherwise there are visible errors in the decoded frames (green
+        * regions in displayed frames) and a broken order of frames (earlier
+        * frames are sporadically displayed after later frames).
+        */
+       if (ctx->use_vdoa)
+               ctx->num_internal_frames += 1;
        if (ctx->num_internal_frames > CODA_MAX_FRAMEBUFFERS) {
                v4l2_err(&dev->v4l2_dev,
                         "not enough framebuffers to decode (%d < %d)\n",
@@ -1724,6 +1739,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
        struct coda_q_data *q_data_dst;
        struct coda_buffer_meta *meta;
        unsigned long flags;
+       u32 rot_mode = 0;
        u32 reg_addr, reg_stride;
 
        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
@@ -1759,27 +1775,40 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
        if (dev->devtype->product == CODA_960)
                coda_set_gdi_regs(ctx);
 
-       if (dev->devtype->product == CODA_960) {
-               /*
-                * The CODA960 seems to have an internal list of buffers with
-                * 64 entries that includes the registered frame buffers as
-                * well as the rotator buffer output.
-                * ROT_INDEX needs to be < 0x40, but > ctx->num_internal_frames.
-                */
-               coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->vb2_buf.index,
-                               CODA9_CMD_DEC_PIC_ROT_INDEX);
-
-               reg_addr = CODA9_CMD_DEC_PIC_ROT_ADDR_Y;
-               reg_stride = CODA9_CMD_DEC_PIC_ROT_STRIDE;
+       if (ctx->use_vdoa &&
+           ctx->display_idx >= 0 &&
+           ctx->display_idx < ctx->num_internal_frames) {
+               vdoa_device_run(ctx->vdoa,
+                               vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0),
+                               ctx->internal_frames[ctx->display_idx].paddr);
        } else {
-               reg_addr = CODA_CMD_DEC_PIC_ROT_ADDR_Y;
-               reg_stride = CODA_CMD_DEC_PIC_ROT_STRIDE;
+               if (dev->devtype->product == CODA_960) {
+                       /*
+                        * The CODA960 seems to have an internal list of
+                        * buffers with 64 entries that includes the
+                        * registered frame buffers as well as the rotator
+                        * buffer output.
+                        *
+                        * ROT_INDEX needs to be < 0x40, but >
+                        * ctx->num_internal_frames.
+                        */
+                       coda_write(dev,
+                                  CODA_MAX_FRAMEBUFFERS + dst_buf->vb2_buf.index,
+                                  CODA9_CMD_DEC_PIC_ROT_INDEX);
+
+                       reg_addr = CODA9_CMD_DEC_PIC_ROT_ADDR_Y;
+                       reg_stride = CODA9_CMD_DEC_PIC_ROT_STRIDE;
+               } else {
+                       reg_addr = CODA_CMD_DEC_PIC_ROT_ADDR_Y;
+                       reg_stride = CODA_CMD_DEC_PIC_ROT_STRIDE;
+               }
+               coda_write_base(ctx, q_data_dst, dst_buf, reg_addr);
+               coda_write(dev, q_data_dst->bytesperline, reg_stride);
+
+               rot_mode = CODA_ROT_MIR_ENABLE | ctx->params.rot_mode;
        }
-       coda_write_base(ctx, q_data_dst, dst_buf, reg_addr);
-       coda_write(dev, q_data_dst->bytesperline, reg_stride);
 
-       coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode,
-                       CODA_CMD_DEC_PIC_ROT_MODE);
+       coda_write(dev, rot_mode, CODA_CMD_DEC_PIC_ROT_MODE);
 
        switch (dev->devtype->product) {
        case CODA_DX6:
@@ -1851,6 +1880,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
        u32 src_fourcc;
        int success;
        u32 err_mb;
+       int err_vdoa = 0;
        u32 val;
 
        /* Update kfifo out pointer from coda bitstream read pointer */
@@ -1934,13 +1964,17 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                }
        }
 
+       /* Wait until the VDOA finished writing the previous display frame */
+       if (ctx->use_vdoa &&
+           ctx->display_idx >= 0 &&
+           ctx->display_idx < ctx->num_internal_frames) {
+               err_vdoa = vdoa_wait_for_completion(ctx->vdoa);
+       }
+
        ctx->frm_dis_flg = coda_read(dev,
                                     CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx));
 
-       /*
-        * The previous display frame was copied out by the rotator,
-        * now it can be overwritten again
-        */
+       /* The previous display frame was copied out and can be overwritten */
        if (ctx->display_idx >= 0 &&
            ctx->display_idx < ctx->num_internal_frames) {
                ctx->frm_dis_flg &= ~(1 << ctx->display_idx);
@@ -2045,6 +2079,9 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                trace_coda_dec_rot_done(ctx, dst_buf, meta);
 
                switch (q_data_dst->fourcc) {
+               case V4L2_PIX_FMT_YUYV:
+                       payload = width * height * 2;
+                       break;
                case V4L2_PIX_FMT_YUV420:
                case V4L2_PIX_FMT_YVU420:
                case V4L2_PIX_FMT_NV12:
@@ -2057,8 +2094,10 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                }
                vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
 
-               coda_m2m_buf_done(ctx, dst_buf, ctx->frame_errors[display_idx] ?
-                                 VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+               if (ctx->frame_errors[ctx->display_idx] || err_vdoa)
+                       coda_m2m_buf_done(ctx, dst_buf, VB2_BUF_STATE_ERROR);
+               else
+                       coda_m2m_buf_done(ctx, dst_buf, VB2_BUF_STATE_DONE);
 
                v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
                        "job finished: decoding frame (%d) (%s)\n",
index 9e6bdafa16f583fc657940824cf9d1236bd9a249..eb6548f46cbac1978056f78d8a5d101a7fbe8a0a 100644 (file)
@@ -41,6 +41,7 @@
 #include <media/videobuf2-vmalloc.h>
 
 #include "coda.h"
+#include "imx-vdoa.h"
 
 #define CODA_NAME              "coda"
 
@@ -66,6 +67,10 @@ static int disable_tiling;
 module_param(disable_tiling, int, 0644);
 MODULE_PARM_DESC(disable_tiling, "Disable tiled frame buffers");
 
+static int disable_vdoa;
+module_param(disable_vdoa, int, 0644);
+MODULE_PARM_DESC(disable_vdoa, "Disable Video Data Order Adapter tiled to raster-scan conversion");
+
 void coda_write(struct coda_dev *dev, u32 data, u32 reg)
 {
        v4l2_dbg(2, coda_debug, &dev->v4l2_dev,
@@ -90,6 +95,8 @@ void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data,
        u32 base_cb, base_cr;
 
        switch (q_data->fourcc) {
+       case V4L2_PIX_FMT_YUYV:
+               /* Fallthrough: IN -H264-> CODA -NV12 MB-> VDOA -YUYV-> OUT */
        case V4L2_PIX_FMT_NV12:
        case V4L2_PIX_FMT_YUV420:
        default:
@@ -196,6 +203,11 @@ static const struct coda_video_device coda_bit_decoder = {
                V4L2_PIX_FMT_NV12,
                V4L2_PIX_FMT_YUV420,
                V4L2_PIX_FMT_YVU420,
+               /*
+                * If V4L2_PIX_FMT_YUYV should be default,
+                * set_default_params() must be adjusted.
+                */
+               V4L2_PIX_FMT_YUYV,
        },
 };
 
@@ -241,6 +253,7 @@ static u32 coda_format_normalize_yuv(u32 fourcc)
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
        case V4L2_PIX_FMT_YUV422P:
+       case V4L2_PIX_FMT_YUYV:
                return V4L2_PIX_FMT_YUV420;
        default:
                return fourcc;
@@ -325,6 +338,31 @@ const char *coda_product_name(int product)
        }
 }
 
+static struct vdoa_data *coda_get_vdoa_data(void)
+{
+       struct device_node *vdoa_node;
+       struct platform_device *vdoa_pdev;
+       struct vdoa_data *vdoa_data = NULL;
+
+       vdoa_node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-vdoa");
+       if (!vdoa_node)
+               return NULL;
+
+       vdoa_pdev = of_find_device_by_node(vdoa_node);
+       if (!vdoa_pdev)
+               goto out;
+
+       vdoa_data = platform_get_drvdata(vdoa_pdev);
+       if (!vdoa_data)
+               vdoa_data = ERR_PTR(-EPROBE_DEFER);
+
+out:
+       if (vdoa_node)
+               of_node_put(vdoa_node);
+
+       return vdoa_data;
+}
+
 /*
  * V4L2 ioctl() operations.
  */
@@ -404,6 +442,11 @@ static int coda_try_pixelformat(struct coda_ctx *ctx, struct v4l2_format *f)
                return -EINVAL;
 
        for (i = 0; i < CODA_MAX_FORMATS; i++) {
+               /* Skip YUYV if the vdoa is not available */
+               if (!ctx->vdoa && f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+                   formats[i] == V4L2_PIX_FMT_YUYV)
+                       continue;
+
                if (formats[i] == f->fmt.pix.pixelformat) {
                        f->fmt.pix.pixelformat = formats[i];
                        return 0;
@@ -417,6 +460,33 @@ static int coda_try_pixelformat(struct coda_ctx *ctx, struct v4l2_format *f)
        return 0;
 }
 
+static int coda_try_fmt_vdoa(struct coda_ctx *ctx, struct v4l2_format *f,
+                            bool *use_vdoa)
+{
+       int err;
+
+       if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (!use_vdoa)
+               return -EINVAL;
+
+       if (!ctx->vdoa) {
+               *use_vdoa = false;
+               return 0;
+       }
+
+       err = vdoa_context_configure(NULL, f->fmt.pix.width, f->fmt.pix.height,
+                                    f->fmt.pix.pixelformat);
+       if (err) {
+               *use_vdoa = false;
+               return 0;
+       }
+
+       *use_vdoa = true;
+       return 0;
+}
+
 static unsigned int coda_estimate_sizeimage(struct coda_ctx *ctx, u32 sizeimage,
                                            u32 width, u32 height)
 {
@@ -463,6 +533,11 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec,
                f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
                                        f->fmt.pix.height * 3 / 2;
                break;
+       case V4L2_PIX_FMT_YUYV:
+               f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16) * 2;
+               f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
+                                       f->fmt.pix.height;
+               break;
        case V4L2_PIX_FMT_YUV422P:
                f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
                f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
@@ -495,6 +570,7 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
        const struct coda_codec *codec;
        struct vb2_queue *src_vq;
        int ret;
+       bool use_vdoa;
 
        ret = coda_try_pixelformat(ctx, f);
        if (ret < 0)
@@ -531,6 +607,19 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
                f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
                f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
                                       f->fmt.pix.height * 3 / 2;
+
+               ret = coda_try_fmt_vdoa(ctx, f, &use_vdoa);
+               if (ret < 0)
+                       return ret;
+
+               if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
+                       if (!use_vdoa)
+                               return -EINVAL;
+
+                       f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16) * 2;
+                       f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
+                               f->fmt.pix.height;
+               }
        }
 
        return 0;
@@ -566,7 +655,8 @@ static int coda_try_fmt_vid_out(struct file *file, void *priv,
        return coda_try_fmt(ctx, codec, f);
 }
 
-static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
+static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
+                     struct v4l2_rect *r)
 {
        struct coda_q_data *q_data;
        struct vb2_queue *vq;
@@ -589,18 +679,23 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
        q_data->height = f->fmt.pix.height;
        q_data->bytesperline = f->fmt.pix.bytesperline;
        q_data->sizeimage = f->fmt.pix.sizeimage;
-       q_data->rect.left = 0;
-       q_data->rect.top = 0;
-       q_data->rect.width = f->fmt.pix.width;
-       q_data->rect.height = f->fmt.pix.height;
+       if (r) {
+               q_data->rect = *r;
+       } else {
+               q_data->rect.left = 0;
+               q_data->rect.top = 0;
+               q_data->rect.width = f->fmt.pix.width;
+               q_data->rect.height = f->fmt.pix.height;
+       }
 
        switch (f->fmt.pix.pixelformat) {
+       case V4L2_PIX_FMT_YUYV:
+               ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
+               break;
        case V4L2_PIX_FMT_NV12:
-               if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-                       ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
-                       if (!disable_tiling)
-                               break;
-               }
+               ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
+               if (!disable_tiling)
+                       break;
                /* else fall through */
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
@@ -610,9 +705,20 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
                break;
        }
 
+       if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP &&
+           !coda_try_fmt_vdoa(ctx, f, &ctx->use_vdoa) &&
+           ctx->use_vdoa)
+               vdoa_context_configure(ctx->vdoa, f->fmt.pix.width,
+                                      f->fmt.pix.height,
+                                      f->fmt.pix.pixelformat);
+       else
+               ctx->use_vdoa = false;
+
        v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
-               "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
-               f->type, q_data->width, q_data->height, q_data->fourcc);
+               "Setting format for type %d, wxh: %dx%d, fmt: %4.4s %c\n",
+               f->type, q_data->width, q_data->height,
+               (char *)&q_data->fourcc,
+               (ctx->tiled_map_type == GDI_LINEAR_FRAME_MAP) ? 'L' : 'T');
 
        return 0;
 }
@@ -621,27 +727,37 @@ static int coda_s_fmt_vid_cap(struct file *file, void *priv,
                              struct v4l2_format *f)
 {
        struct coda_ctx *ctx = fh_to_ctx(priv);
+       struct coda_q_data *q_data_src;
+       struct v4l2_rect r;
        int ret;
 
        ret = coda_try_fmt_vid_cap(file, priv, f);
        if (ret)
                return ret;
 
-       return coda_s_fmt(ctx, f);
+       q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+       r.left = 0;
+       r.top = 0;
+       r.width = q_data_src->width;
+       r.height = q_data_src->height;
+
+       return coda_s_fmt(ctx, f, &r);
 }
 
 static int coda_s_fmt_vid_out(struct file *file, void *priv,
                              struct v4l2_format *f)
 {
        struct coda_ctx *ctx = fh_to_ctx(priv);
+       struct coda_q_data *q_data_src;
        struct v4l2_format f_cap;
+       struct v4l2_rect r;
        int ret;
 
        ret = coda_try_fmt_vid_out(file, priv, f);
        if (ret)
                return ret;
 
-       ret = coda_s_fmt(ctx, f);
+       ret = coda_s_fmt(ctx, f, NULL);
        if (ret)
                return ret;
 
@@ -657,7 +773,13 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv,
        if (ret)
                return ret;
 
-       return coda_s_fmt(ctx, &f_cap);
+       q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+       r.left = 0;
+       r.top = 0;
+       r.width = q_data_src->width;
+       r.height = q_data_src->height;
+
+       return coda_s_fmt(ctx, &f_cap, &r);
 }
 
 static int coda_reqbufs(struct file *file, void *priv,
@@ -1018,6 +1140,16 @@ static int coda_job_ready(void *m2m_priv)
                bool stream_end = ctx->bit_stream_param &
                                  CODA_BIT_STREAM_END_FLAG;
                int num_metas = ctx->num_metas;
+               unsigned int count;
+
+               count = hweight32(ctx->frm_dis_flg);
+               if (ctx->use_vdoa && count >= (ctx->num_internal_frames - 1)) {
+                       v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+                                "%d: not ready: all internal buffers in use: %d/%d (0x%x)",
+                                ctx->idx, count, ctx->num_internal_frames,
+                                ctx->frm_dis_flg);
+                       return 0;
+               }
 
                if (ctx->hold && !src_bufs) {
                        v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
@@ -1708,6 +1840,13 @@ static int coda_open(struct file *file)
        default:
                ctx->reg_idx = idx;
        }
+       if (ctx->dev->vdoa && !disable_vdoa) {
+               ctx->vdoa = vdoa_context_create(dev->vdoa);
+               if (!ctx->vdoa)
+                       v4l2_warn(&dev->v4l2_dev,
+                                 "Failed to create vdoa context: not using vdoa");
+       }
+       ctx->use_vdoa = false;
 
        /* Power up and upload firmware if necessary */
        ret = pm_runtime_get_sync(&dev->plat_dev->dev);
@@ -1789,6 +1928,9 @@ static int coda_release(struct file *file)
        /* If this instance is running, call .job_abort and wait for it to end */
        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 
+       if (ctx->vdoa)
+               vdoa_context_destroy(ctx->vdoa);
+
        /* In case the instance was not running, we still need to call SEQ_END */
        if (ctx->ops->seq_end_work) {
                queue_work(dev->workqueue, &ctx->seq_end_work);
@@ -2079,6 +2221,7 @@ static const struct coda_devtype coda_devdata[] = {
        [CODA_IMX27] = {
                .firmware     = {
                        "vpu_fw_imx27_TO2.bin",
+                       "vpu/vpu_fw_imx27_TO2.bin",
                        "v4l-codadx6-imx27.bin"
                },
                .product      = CODA_DX6,
@@ -2092,6 +2235,7 @@ static const struct coda_devtype coda_devdata[] = {
        [CODA_IMX53] = {
                .firmware     = {
                        "vpu_fw_imx53.bin",
+                       "vpu/vpu_fw_imx53.bin",
                        "v4l-coda7541-imx53.bin"
                },
                .product      = CODA_7541,
@@ -2106,6 +2250,7 @@ static const struct coda_devtype coda_devdata[] = {
        [CODA_IMX6Q] = {
                .firmware     = {
                        "vpu_fw_imx6q.bin",
+                       "vpu/vpu_fw_imx6q.bin",
                        "v4l-coda960-imx6q.bin"
                },
                .product      = CODA_960,
@@ -2120,6 +2265,7 @@ static const struct coda_devtype coda_devdata[] = {
        [CODA_IMX6DL] = {
                .firmware     = {
                        "vpu_fw_imx6d.bin",
+                       "vpu/vpu_fw_imx6d.bin",
                        "v4l-coda960-imx6dl.bin"
                },
                .product      = CODA_960,
@@ -2235,6 +2381,11 @@ static int coda_probe(struct platform_device *pdev)
        }
        dev->iram_pool = pool;
 
+       /* Get vdoa_data if supported by the platform */
+       dev->vdoa = coda_get_vdoa_data();
+       if (PTR_ERR(dev->vdoa) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+
        ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
        if (ret)
                return ret;
index 53f96661683c63c7865967467d96585e48264252..4b831c91ae4aff81f59574811f67ae82f1508eee 100644 (file)
@@ -50,7 +50,7 @@ enum coda_product {
 struct coda_video_device;
 
 struct coda_devtype {
-       char                    *firmware[2];
+       char                    *firmware[3];
        enum coda_product       product;
        const struct coda_codec *codecs;
        unsigned int            num_codecs;
@@ -75,6 +75,7 @@ struct coda_dev {
        struct platform_device  *plat_dev;
        const struct coda_devtype *devtype;
        int                     firmware;
+       struct vdoa_data        *vdoa;
 
        void __iomem            *regs_base;
        struct clk              *clk_per;
@@ -236,6 +237,8 @@ struct coda_ctx {
        int                             display_idx;
        struct dentry                   *debugfs_entry;
        bool                            use_bit;
+       bool                            use_vdoa;
+       struct vdoa_ctx                 *vdoa;
 };
 
 extern int coda_debug;
diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
new file mode 100644 (file)
index 0000000..67fd8ff
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * i.MX6 Video Data Order Adapter (VDOA)
+ *
+ * Copyright (C) 2014 Philipp Zabel
+ * Copyright (C) 2016 Pengutronix, Michael Tretter <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+
+#include "imx-vdoa.h"
+
+#define VDOA_NAME "imx-vdoa"
+
+#define VDOAC          0x00
+#define VDOASRR                0x04
+#define VDOAIE         0x08
+#define VDOAIST                0x0c
+#define VDOAFP         0x10
+#define VDOAIEBA00     0x14
+#define VDOAIEBA01     0x18
+#define VDOAIEBA02     0x1c
+#define VDOAIEBA10     0x20
+#define VDOAIEBA11     0x24
+#define VDOAIEBA12     0x28
+#define VDOASL         0x2c
+#define VDOAIUBO       0x30
+#define VDOAVEBA0      0x34
+#define VDOAVEBA1      0x38
+#define VDOAVEBA2      0x3c
+#define VDOAVUBO       0x40
+#define VDOASR         0x44
+
+#define VDOAC_ISEL             BIT(6)
+#define VDOAC_PFS              BIT(5)
+#define VDOAC_SO               BIT(4)
+#define VDOAC_SYNC             BIT(3)
+#define VDOAC_NF               BIT(2)
+#define VDOAC_BNDM_MASK                0x3
+#define VDOAC_BAND_HEIGHT_8    0x0
+#define VDOAC_BAND_HEIGHT_16   0x1
+#define VDOAC_BAND_HEIGHT_32   0x2
+
+#define VDOASRR_START          BIT(1)
+#define VDOASRR_SWRST          BIT(0)
+
+#define VDOAIE_EITERR          BIT(1)
+#define VDOAIE_EIEOT           BIT(0)
+
+#define VDOAIST_TERR           BIT(1)
+#define VDOAIST_EOT            BIT(0)
+
+#define VDOAFP_FH_MASK         (0x1fff << 16)
+#define VDOAFP_FW_MASK         (0x3fff)
+
+#define VDOASL_VSLY_MASK       (0x3fff << 16)
+#define VDOASL_ISLY_MASK       (0x7fff)
+
+#define VDOASR_ERRW            BIT(4)
+#define VDOASR_EOB             BIT(3)
+#define VDOASR_CURRENT_FRAME   (0x3 << 1)
+#define VDOASR_CURRENT_BUFFER  BIT(1)
+
+enum {
+       V4L2_M2M_SRC = 0,
+       V4L2_M2M_DST = 1,
+};
+
+struct vdoa_data {
+       struct vdoa_ctx         *curr_ctx;
+       struct device           *dev;
+       struct clk              *vdoa_clk;
+       void __iomem            *regs;
+       int                     irq;
+};
+
+struct vdoa_q_data {
+       unsigned int    width;
+       unsigned int    height;
+       unsigned int    bytesperline;
+       unsigned int    sizeimage;
+       u32             pixelformat;
+};
+
+struct vdoa_ctx {
+       struct vdoa_data        *vdoa;
+       struct completion       completion;
+       struct vdoa_q_data      q_data[2];
+};
+
+static irqreturn_t vdoa_irq_handler(int irq, void *data)
+{
+       struct vdoa_data *vdoa = data;
+       struct vdoa_ctx *curr_ctx;
+       u32 val;
+
+       /* Disable interrupts */
+       writel(0, vdoa->regs + VDOAIE);
+
+       curr_ctx = vdoa->curr_ctx;
+       if (!curr_ctx) {
+               dev_dbg(vdoa->dev,
+                       "Instance released before the end of transaction\n");
+               return IRQ_HANDLED;
+       }
+
+       val = readl(vdoa->regs + VDOAIST);
+       writel(val, vdoa->regs + VDOAIST);
+       if (val & VDOAIST_TERR) {
+               val = readl(vdoa->regs + VDOASR) & VDOASR_ERRW;
+               dev_err(vdoa->dev, "AXI %s error\n", val ? "write" : "read");
+       } else if (!(val & VDOAIST_EOT)) {
+               dev_warn(vdoa->dev, "Spurious interrupt\n");
+       }
+       complete(&curr_ctx->completion);
+
+       return IRQ_HANDLED;
+}
+
+void vdoa_device_run(struct vdoa_ctx *ctx, dma_addr_t dst, dma_addr_t src)
+{
+       struct vdoa_q_data *src_q_data, *dst_q_data;
+       struct vdoa_data *vdoa = ctx->vdoa;
+       u32 val;
+
+       vdoa->curr_ctx = ctx;
+
+       src_q_data = &ctx->q_data[V4L2_M2M_SRC];
+       dst_q_data = &ctx->q_data[V4L2_M2M_DST];
+
+       /* Progressive, no sync, 1 frame per run */
+       if (dst_q_data->pixelformat == V4L2_PIX_FMT_YUYV)
+               val = VDOAC_PFS;
+       else
+               val = 0;
+       writel(val, vdoa->regs + VDOAC);
+
+       writel(dst_q_data->height << 16 | dst_q_data->width,
+              vdoa->regs + VDOAFP);
+
+       val = dst;
+       writel(val, vdoa->regs + VDOAIEBA00);
+
+       writel(src_q_data->bytesperline << 16 | dst_q_data->bytesperline,
+              vdoa->regs + VDOASL);
+
+       if (dst_q_data->pixelformat == V4L2_PIX_FMT_NV12 ||
+           dst_q_data->pixelformat == V4L2_PIX_FMT_NV21)
+               val = dst_q_data->bytesperline * dst_q_data->height;
+       else
+               val = 0;
+       writel(val, vdoa->regs + VDOAIUBO);
+
+       val = src;
+       writel(val, vdoa->regs + VDOAVEBA0);
+       val = round_up(src_q_data->bytesperline * src_q_data->height, 4096);
+       writel(val, vdoa->regs + VDOAVUBO);
+
+       /* Enable interrupts and start transfer */
+       writel(VDOAIE_EITERR | VDOAIE_EIEOT, vdoa->regs + VDOAIE);
+       writel(VDOASRR_START, vdoa->regs + VDOASRR);
+}
+EXPORT_SYMBOL(vdoa_device_run);
+
+int vdoa_wait_for_completion(struct vdoa_ctx *ctx)
+{
+       struct vdoa_data *vdoa = ctx->vdoa;
+
+       if (!wait_for_completion_timeout(&ctx->completion,
+                                        msecs_to_jiffies(300))) {
+               dev_err(vdoa->dev,
+                       "Timeout waiting for transfer result\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(vdoa_wait_for_completion);
+
+struct vdoa_ctx *vdoa_context_create(struct vdoa_data *vdoa)
+{
+       struct vdoa_ctx *ctx;
+       int err;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return NULL;
+
+       err = clk_prepare_enable(vdoa->vdoa_clk);
+       if (err) {
+               kfree(ctx);
+               return NULL;
+       }
+
+       init_completion(&ctx->completion);
+       ctx->vdoa = vdoa;
+
+       return ctx;
+}
+EXPORT_SYMBOL(vdoa_context_create);
+
+void vdoa_context_destroy(struct vdoa_ctx *ctx)
+{
+       struct vdoa_data *vdoa = ctx->vdoa;
+
+       clk_disable_unprepare(vdoa->vdoa_clk);
+       kfree(ctx);
+}
+EXPORT_SYMBOL(vdoa_context_destroy);
+
+int vdoa_context_configure(struct vdoa_ctx *ctx,
+                          unsigned int width, unsigned int height,
+                          u32 pixelformat)
+{
+       struct vdoa_q_data *src_q_data;
+       struct vdoa_q_data *dst_q_data;
+
+       if (width < 16 || width  > 8192 || width % 16 != 0 ||
+           height < 16 || height > 4096 || height % 16 != 0)
+               return -EINVAL;
+
+       if (pixelformat != V4L2_PIX_FMT_YUYV &&
+           pixelformat != V4L2_PIX_FMT_NV12)
+               return -EINVAL;
+
+       /* If no context is passed, only check if the format is valid */
+       if (!ctx)
+               return 0;
+
+       src_q_data = &ctx->q_data[V4L2_M2M_SRC];
+       dst_q_data = &ctx->q_data[V4L2_M2M_DST];
+
+       src_q_data->width = width;
+       src_q_data->height = height;
+       src_q_data->bytesperline = width;
+       src_q_data->sizeimage =
+               round_up(src_q_data->bytesperline * height, 4096) +
+               src_q_data->bytesperline * height / 2;
+
+       dst_q_data->width = width;
+       dst_q_data->height = height;
+       dst_q_data->pixelformat = pixelformat;
+       switch (pixelformat) {
+       case V4L2_PIX_FMT_YUYV:
+               dst_q_data->bytesperline = width * 2;
+               dst_q_data->sizeimage = dst_q_data->bytesperline * height;
+               break;
+       case V4L2_PIX_FMT_NV12:
+       default:
+               dst_q_data->bytesperline = width;
+               dst_q_data->sizeimage =
+                       dst_q_data->bytesperline * height * 3 / 2;
+               break;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(vdoa_context_configure);
+
+static int vdoa_probe(struct platform_device *pdev)
+{
+       struct vdoa_data *vdoa;
+       struct resource *res;
+
+       dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+
+       vdoa = devm_kzalloc(&pdev->dev, sizeof(*vdoa), GFP_KERNEL);
+       if (!vdoa)
+               return -ENOMEM;
+
+       vdoa->dev = &pdev->dev;
+
+       vdoa->vdoa_clk = devm_clk_get(vdoa->dev, NULL);
+       if (IS_ERR(vdoa->vdoa_clk)) {
+               dev_err(vdoa->dev, "Failed to get clock\n");
+               return PTR_ERR(vdoa->vdoa_clk);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       vdoa->regs = devm_ioremap_resource(vdoa->dev, res);
+       if (IS_ERR(vdoa->regs))
+               return PTR_ERR(vdoa->regs);
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       vdoa->irq = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
+                                       vdoa_irq_handler, IRQF_ONESHOT,
+                                       "vdoa", vdoa);
+       if (vdoa->irq < 0) {
+               dev_err(vdoa->dev, "Failed to get irq\n");
+               return vdoa->irq;
+       }
+
+       platform_set_drvdata(pdev, vdoa);
+
+       return 0;
+}
+
+static int vdoa_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static const struct of_device_id vdoa_dt_ids[] = {
+       { .compatible = "fsl,imx6q-vdoa" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, vdoa_dt_ids);
+
+static const struct platform_driver vdoa_driver = {
+       .probe          = vdoa_probe,
+       .remove         = vdoa_remove,
+       .driver         = {
+               .name   = VDOA_NAME,
+               .of_match_table = vdoa_dt_ids,
+       },
+};
+
+module_platform_driver(vdoa_driver);
+
+MODULE_DESCRIPTION("Video Data Order Adapter");
+MODULE_AUTHOR("Philipp Zabel <philipp.zabel@gmail.com>");
+MODULE_ALIAS("platform:imx-vdoa");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/coda/imx-vdoa.h b/drivers/media/platform/coda/imx-vdoa.h
new file mode 100644 (file)
index 0000000..967576b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef IMX_VDOA_H
+#define IMX_VDOA_H
+
+struct vdoa_data;
+struct vdoa_ctx;
+
+#if (defined CONFIG_VIDEO_IMX_VDOA || defined CONFIG_VIDEO_IMX_VDOA_MODULE)
+
+struct vdoa_ctx *vdoa_context_create(struct vdoa_data *vdoa);
+int vdoa_context_configure(struct vdoa_ctx *ctx,
+                          unsigned int width, unsigned int height,
+                          u32 pixelformat);
+void vdoa_context_destroy(struct vdoa_ctx *ctx);
+
+void vdoa_device_run(struct vdoa_ctx *ctx, dma_addr_t dst, dma_addr_t src);
+int vdoa_wait_for_completion(struct vdoa_ctx *ctx);
+
+#else
+
+static inline struct vdoa_ctx *vdoa_context_create(struct vdoa_data *vdoa)
+{
+       return NULL;
+}
+
+static inline int vdoa_context_configure(struct vdoa_ctx *ctx,
+                                        unsigned int width,
+                                        unsigned int height,
+                                        u32 pixelformat)
+{
+       return 0;
+}
+
+static inline void vdoa_context_destroy(struct vdoa_ctx *ctx) { };
+
+static inline void vdoa_device_run(struct vdoa_ctx *ctx,
+                                  dma_addr_t dst, dma_addr_t src) { };
+
+static inline int vdoa_wait_for_completion(struct vdoa_ctx *ctx)
+{
+       return 0;
+};
+
+#endif
+
+#endif /* IMX_VDOA_H */
index ae5605de7679565013098282e2e89c837b4e4db2..8f6688a7a111cd0a5dbf9cf7370f9b97a1fcde52 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * ccdc device API
  */
 #ifndef _CCDC_HW_DEVICE_H
index 65c2973167c678b7a1201118d07375b806dedfd4..73db166dc338e5b352e9718950fe1739e42115e7 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * CCDC hardware module for DM355
  * ------------------------------
  *
index 2e1946e0b99f0b2fbc8c15be396cf9ef2715597a..a753ce2625832a65880205e68273e5818334ee60 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifndef _DM355_CCDC_REGS_H
 #define _DM355_CCDC_REGS_H
index c7523a7e05940a59187bf205520abf4ab3f2a4d9..740fbc7a8c149172202c082576fdf159b6ba5bc7 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * CCDC hardware module for DM6446
  * ------------------------------
  *
index 2b0aca5383f0d1fef320b88d2d8b4991fd6ff0fd..bece0bd9c9de6772099949f5f760aad53983c95d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifndef _DM644X_CCDC_REGS_H
 #define _DM644X_CCDC_REGS_H
index 99faea2e84c6b38d78ae9ee5b6337e765f2daf9f..5813b49391edb086b572d05e34bbd608eccf17ab 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * Image Sensor Interface (ISIF) driver
  *
  * This driver is for configuring the ISIF IP available on DM365 or any other
index 3993aece821b92c8498a20f2021f9b7d6381d561..a3564abe08ae27f5c6746f8e10055c5e330ece47 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifndef _ISIF_REGS_H
 #define _ISIF_REGS_H
index 8c8cbeb7d90f0c68312d950bea7be2467d7fc328..3679b1e7b39effe7c5c06ee733f3eabfdc8d2a51 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 7d96a4b13b3235031bb05efdfb5619606a746f23..df042e84a67830d476f0ee4bc2ebc2b197588c70 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
index 584520f3af608165d86c6bff4ecc32ac06d23f77..3db265f87c650bf368b1b71133d679fdf5b7e8de 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPBE_OSD_REGS_H
 #define _VPBE_OSD_REGS_H
index 36ed1466b290ff7b86037439d7aca21a2db96e4f..8bfe90a246812185e32270230ef3b42ac8d5d174 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
index 947cb1510776a03de18c360735bd0cb68095101d..6ad38f7ab0fe97725c2dc4aca013aa136a91ceb6 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPBE_VENC_REGS_H
 #define _VPBE_VENC_REGS_H
index ee1cd79739c8caf6d9ef999738628dc85523078c..e3fe3e0635aa87806abf4b15e4ba83264ec8b557 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  * Driver name : VPFE Capture driver
  *    VPFE Capture driver allows applications to capture and stream video
  *    frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
@@ -523,6 +519,8 @@ static int vpfe_open(struct file *file)
        if (!vpfe_dev->initialized) {
                if (vpfe_initialize_device(vpfe_dev)) {
                        mutex_unlock(&vpfe_dev->lock);
+                       v4l2_fh_exit(&fh->fh);
+                       kfree(fh);
                        return -ENODEV;
                }
        }
index 0380cf2e5775dda31fe7cefa0059c547390bef8d..1b02a6363f7779b664a217ae420a30973b9ac661 100644 (file)
@@ -32,6 +32,9 @@
 MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
 MODULE_LICENSE("GPL");
 
+#define VPIF_DRIVER_NAME       "vpif"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
+
 #define VPIF_CH0_MAX_MODES     22
 #define VPIF_CH1_MAX_MODES     2
 #define VPIF_CH2_MAX_MODES     15
@@ -464,9 +467,18 @@ static const struct dev_pm_ops vpif_pm = {
 #define vpif_pm_ops NULL
 #endif
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id vpif_of_match[] = {
+       { .compatible = "ti,da850-vpif", },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, vpif_of_match);
+#endif
+
 static struct platform_driver vpif_driver = {
        .driver = {
-               .name   = "vpif",
+               .of_match_table = of_match_ptr(vpif_of_match),
+               .name   = VPIF_DRIVER_NAME,
                .pm     = vpif_pm_ops,
        },
        .remove = vpif_remove,
index f791f5c402bf1dc72ed630f0f1a817505ac1e0b9..44f702752d3aae4add9bf85339607c0f6d317de3 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  * TODO : add support for VBI & HBI data service
  *       add static buffer allocation
  */
@@ -45,6 +41,7 @@ module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level 0-1");
 
 #define VPIF_DRIVER_NAME       "vpif_capture"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
 
 /* global variables */
 static struct vpif_device vpif_obj = { {NULL} };
@@ -178,8 +175,6 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        unsigned long addr, flags;
        int ret;
 
-       spin_lock_irqsave(&common->irqlock, flags);
-
        /* Initialize field_id */
        ch->field_id = 0;
 
@@ -210,6 +205,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        vpif_config_addr(ch, ret);
 
        /* Get the next frame from the buffer queue */
+       spin_lock_irqsave(&common->irqlock, flags);
        common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
                                    struct vpif_cap_buffer, list);
        /* Remove buffer from the buffer queue */
@@ -243,6 +239,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        return 0;
 
 err:
+       spin_lock_irqsave(&common->irqlock, flags);
        list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
                list_del(&buf->list);
                vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
@@ -286,7 +283,6 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
                vpif_dbg(1, debug, "stream off failed in subdev\n");
 
        /* release all active buffers */
-       spin_lock_irqsave(&common->irqlock, flags);
        if (common->cur_frm == common->next_frm) {
                vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
                                VB2_BUF_STATE_ERROR);
@@ -299,6 +295,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq)
                                        VB2_BUF_STATE_ERROR);
        }
 
+       spin_lock_irqsave(&common->irqlock, flags);
        while (!list_empty(&common->dma_queue)) {
                common->next_frm = list_entry(common->dma_queue.next,
                                                struct vpif_cap_buffer, list);
@@ -647,6 +644,10 @@ static int vpif_input_to_subdev(
 
        vpif_dbg(2, debug, "vpif_input_to_subdev\n");
 
+       if (!chan_cfg)
+               return -1;
+       if (input_index >= chan_cfg->input_count)
+               return -1;
        subdev_name = chan_cfg->inputs[input_index].subdev_name;
        if (!subdev_name)
                return -1;
@@ -685,6 +686,9 @@ static int vpif_set_input(
        if (sd_index >= 0) {
                sd = vpif_obj.sd[sd_index];
                subdev_info = &vpif_cfg->subdev_info[sd_index];
+       } else {
+               /* no subdevice, no input to setup */
+               return 0;
        }
 
        /* first setup input path from sub device to vpif */
@@ -1430,6 +1434,11 @@ static __init int vpif_probe(struct platform_device *pdev)
        int res_idx = 0;
        int i, err;
 
+       if (!pdev->dev.platform_data) {
+               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
+               return -EINVAL;
+       }
+
        vpif_dev = &pdev->dev;
 
        err = initialize_vpif();
@@ -1466,7 +1475,10 @@ static __init int vpif_probe(struct platform_device *pdev)
        }
 
        if (!vpif_obj.config->asd_sizes) {
-               i2c_adap = i2c_get_adapter(1);
+               int i2c_id = vpif_obj.config->i2c_adapter_id;
+
+               i2c_adap = i2c_get_adapter(i2c_id);
+               WARN_ON(!i2c_adap);
                for (i = 0; i < subdev_count; i++) {
                        subdevdata = &vpif_obj.config->subdev_info[i];
                        vpif_obj.sd[i] =
index 9e35b6771d22a04cc333938be45eb0dafa49b21f..cf494a596a440d03c44b2042a0e4376a609e2403 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifndef VPIF_CAPTURE_H
@@ -67,7 +63,7 @@ struct common_obj {
        struct vb2_queue buffer_queue;
        /* Queue of filled frames */
        struct list_head dma_queue;
-       /* Used in video-buf */
+       /* Protects the dma_queue field */
        spinlock_t irqlock;
        /* lock used to access this structure */
        struct mutex lock;
index e5f18448dbf73e6cc73c9e573f6fa537a8edf60e..50c30731bb78e2ac4029874c0b2bb3ec8352ddbf 100644 (file)
@@ -42,6 +42,7 @@ module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level 0-1");
 
 #define VPIF_DRIVER_NAME       "vpif_display"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
 
 /* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
 static int ycmux_mode;
@@ -1244,6 +1245,11 @@ static __init int vpif_probe(struct platform_device *pdev)
        int res_idx = 0;
        int i, err;
 
+       if (!pdev->dev.platform_data) {
+               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
+               return -EINVAL;
+       }
+
        vpif_dev = &pdev->dev;
        err = initialize_vpif();
 
index 373b796132f20b96a337ba4a5f9213b2bdf416e9..f2d27b9329990a9cfbbaf315448210b0c9dc4ea4 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * common vpss system module platform driver for all video drivers.
  */
 #include <linux/module.h>
index cbf75b6194b431934a45b877617de3e6bb504501..cbb03768f5d73574b4d95939a08d7605e94dd6d7 100644 (file)
@@ -408,7 +408,7 @@ int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f)
        if (pix_mp->field == V4L2_FIELD_ANY)
                pix_mp->field = V4L2_FIELD_NONE;
        else if (pix_mp->field != V4L2_FIELD_NONE) {
-               pr_err("Not supported field order(%d)\n", pix_mp->field);
+               pr_debug("Not supported field order(%d)\n", pix_mp->field);
                return -EINVAL;
        }
 
@@ -1118,6 +1118,7 @@ static int gsc_remove(struct platform_device *pdev)
                clk_disable_unprepare(gsc->clock[i]);
 
        pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
 
        dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
        return 0;
index f49f24b4462abe62992837f95a1ab1724a6fd695..82505025d96c422d3b66ba82a70c70454740bef3 100644 (file)
@@ -675,8 +675,8 @@ static int gsc_m2m_open(struct file *file)
 
 error_ctrls:
        gsc_ctrls_delete(ctx);
-error_fh:
        v4l2_fh_del(&ctx->fh);
+error_fh:
        v4l2_fh_exit(&ctx->fh);
        kfree(ctx);
 unlock:
index 964f4a6819343a4fe1fc375ddde45a052cab3747..8a7cd07dbe281e757904fabe423296751e861012 100644 (file)
@@ -536,7 +536,7 @@ static int fimc_capture_release(struct file *file)
        mutex_lock(&fimc->lock);
 
        if (close && vc->streaming) {
-               media_entity_pipeline_stop(&vc->ve.vdev.entity);
+               media_pipeline_stop(&vc->ve.vdev.entity);
                vc->streaming = false;
        }
 
@@ -1195,7 +1195,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
        if (fimc_capture_active(fimc))
                return -EBUSY;
 
-       ret = media_entity_pipeline_start(entity, &vc->ve.pipe->mp);
+       ret = media_pipeline_start(entity, &vc->ve.pipe->mp);
        if (ret < 0)
                return ret;
 
@@ -1229,7 +1229,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
        }
 
 err_p_stop:
-       media_entity_pipeline_stop(entity);
+       media_pipeline_stop(entity);
        return ret;
 }
 
@@ -1244,7 +1244,7 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
        if (ret < 0)
                return ret;
 
-       media_entity_pipeline_stop(&vc->ve.vdev.entity);
+       media_pipeline_stop(&vc->ve.vdev.entity);
        vc->streaming = false;
        return 0;
 }
@@ -1695,7 +1695,7 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
        return 0;
 }
 
-static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
+static const struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
        .enum_mbus_code = fimc_subdev_enum_mbus_code,
        .get_selection = fimc_subdev_get_selection,
        .set_selection = fimc_subdev_set_selection,
@@ -1703,7 +1703,7 @@ static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
        .set_fmt = fimc_subdev_set_fmt,
 };
 
-static struct v4l2_subdev_ops fimc_subdev_ops = {
+static const struct v4l2_subdev_ops fimc_subdev_ops = {
        .pad = &fimc_subdev_pad_ops,
 };
 
index 6bba4ca022be542e478b32c76286f0a2f11927d3..2f559663e51e5046e58a7be15e95242848d98cf6 100644 (file)
@@ -28,7 +28,14 @@ struct fimc_is_i2c {
  * is implemented in the FIMC-IS subsystem firmware and the host CPU
  * doesn't access the I2C bus controller.
  */
-static const struct i2c_algorithm fimc_is_i2c_algorithm;
+static u32 is_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm fimc_is_i2c_algorithm = {
+       .functionality  = is_i2c_func,
+};
 
 static int fimc_is_i2c_probe(struct platform_device *pdev)
 {
index 518ad34f80d7c4e1d29d7313568d8f4087f7cc5d..7f92144a1de3acd812dde54c70b32bd901a8959c 100644 (file)
@@ -825,12 +825,13 @@ static int fimc_is_probe(struct platform_device *pdev)
        is->irq = irq_of_parse_and_map(dev->of_node, 0);
        if (!is->irq) {
                dev_err(dev, "no irq found\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_iounmap;
        }
 
        ret = fimc_is_get_clocks(is);
        if (ret < 0)
-               return ret;
+               goto err_iounmap;
 
        platform_set_drvdata(pdev, is);
 
@@ -891,6 +892,8 @@ err_irq:
        free_irq(is->irq, is);
 err_clk:
        fimc_is_put_clocks(is);
+err_iounmap:
+       iounmap(is->pmu_regs);
        return ret;
 }
 
@@ -947,6 +950,7 @@ static int fimc_is_remove(struct platform_device *pdev)
        fimc_is_unregister_subdevs(is);
        vb2_dma_contig_clear_max_seg_size(dev);
        fimc_is_put_clocks(is);
+       iounmap(is->pmu_regs);
        fimc_is_debugfs_remove(is);
        release_firmware(is->fw.f_w);
        fimc_is_free_cpu_memory(is);
index 400ce0cb0c0dc97900226d0060c57cb0b3f71711..55ba696b8cf40e13339e42234bfd352e8df90520 100644 (file)
@@ -312,7 +312,7 @@ static int isp_video_release(struct file *file)
        mutex_lock(&isp->video_lock);
 
        if (v4l2_fh_is_singular_file(file) && ivc->streaming) {
-               media_entity_pipeline_stop(entity);
+               media_pipeline_stop(entity);
                ivc->streaming = 0;
        }
 
@@ -489,7 +489,7 @@ static int isp_video_streamon(struct file *file, void *priv,
        struct media_entity *me = &ve->vdev.entity;
        int ret;
 
-       ret = media_entity_pipeline_start(me, &ve->pipe->mp);
+       ret = media_pipeline_start(me, &ve->pipe->mp);
        if (ret < 0)
                return ret;
 
@@ -504,7 +504,7 @@ static int isp_video_streamon(struct file *file, void *priv,
        isp->video_capture.streaming = 1;
        return 0;
 p_stop:
-       media_entity_pipeline_stop(me);
+       media_pipeline_stop(me);
        return ret;
 }
 
@@ -519,7 +519,7 @@ static int isp_video_streamoff(struct file *file, void *priv,
        if (ret < 0)
                return ret;
 
-       media_entity_pipeline_stop(&video->ve.vdev.entity);
+       media_pipeline_stop(&video->ve.vdev.entity);
        video->streaming = 0;
        return 0;
 }
index b91abf1c4d43b6330ae8ff9daa307affdf25d03e..b4c4a33784c4fde9b9a523b1776d9ece24f40afb 100644 (file)
@@ -524,7 +524,7 @@ static int fimc_lite_release(struct file *file)
        if (v4l2_fh_is_singular_file(file) &&
            atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
                if (fimc->streaming) {
-                       media_entity_pipeline_stop(entity);
+                       media_pipeline_stop(entity);
                        fimc->streaming = false;
                }
                fimc_lite_stop_capture(fimc, false);
@@ -832,7 +832,7 @@ static int fimc_lite_streamon(struct file *file, void *priv,
        if (fimc_lite_active(fimc))
                return -EBUSY;
 
-       ret = media_entity_pipeline_start(entity, &fimc->ve.pipe->mp);
+       ret = media_pipeline_start(entity, &fimc->ve.pipe->mp);
        if (ret < 0)
                return ret;
 
@@ -849,7 +849,7 @@ static int fimc_lite_streamon(struct file *file, void *priv,
        }
 
 err_p_stop:
-       media_entity_pipeline_stop(entity);
+       media_pipeline_stop(entity);
        return 0;
 }
 
@@ -863,7 +863,7 @@ static int fimc_lite_streamoff(struct file *file, void *priv,
        if (ret < 0)
                return ret;
 
-       media_entity_pipeline_stop(&fimc->ve.vdev.entity);
+       media_pipeline_stop(&fimc->ve.vdev.entity);
        fimc->streaming = false;
        return 0;
 }
index 6028e4fbaed35f3a7cf49e151ad9145fcaba9def..d8724fe9e9dae7ca7173c31610b62b04e92141ca 100644 (file)
@@ -663,8 +663,8 @@ error_m2m_ctx:
        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 error_c:
        fimc_ctrls_delete(ctx);
-error_fh:
        v4l2_fh_del(&ctx->fh);
+error_fh:
        v4l2_fh_exit(&ctx->fh);
        kfree(ctx);
 unlock:
index e3a8709138fa05bb26da493c23cc74ec2a937189..e82450e90a676db9ba1dafd410d0840d8f209c81 100644 (file)
@@ -402,8 +402,10 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
                return ret;
        }
 
-       if (WARN_ON(endpoint.base.port == 0) || index >= FIMC_MAX_SENSORS)
+       if (WARN_ON(endpoint.base.port == 0) || index >= FIMC_MAX_SENSORS) {
+               of_node_put(ep);
                return -EINVAL;
+       }
 
        pd->mux_id = (endpoint.base.port - 1) & 0x1;
 
@@ -1117,7 +1119,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 
 /* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */
 static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable,
-                                     struct media_entity_graph *graph)
+                                     struct media_graph *graph)
 {
        struct media_entity *entity_err = entity;
        int ret;
@@ -1128,9 +1130,9 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable,
         * through active links. This is needed as we cannot power on/off the
         * subdevs in random order.
         */
-       media_entity_graph_walk_start(graph, entity);
+       media_graph_walk_start(graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(graph))) {
+       while ((entity = media_graph_walk_next(graph))) {
                if (!is_media_entity_v4l2_video_device(entity))
                        continue;
 
@@ -1143,9 +1145,9 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable,
        return 0;
 
 err:
-       media_entity_graph_walk_start(graph, entity_err);
+       media_graph_walk_start(graph, entity_err);
 
-       while ((entity_err = media_entity_graph_walk_next(graph))) {
+       while ((entity_err = media_graph_walk_next(graph))) {
                if (!is_media_entity_v4l2_video_device(entity_err))
                        continue;
 
@@ -1161,7 +1163,7 @@ err:
 static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
                                unsigned int notification)
 {
-       struct media_entity_graph *graph =
+       struct media_graph *graph =
                &container_of(link->graph_obj.mdev, struct fimc_md,
                              media_dev)->link_setup_graph;
        struct media_entity *sink = link->sink->entity;
@@ -1169,7 +1171,7 @@ static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
 
        /* Before link disconnection */
        if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
-               ret = media_entity_graph_walk_init(graph,
+               ret = media_graph_walk_init(graph,
                                                   link->graph_obj.mdev);
                if (ret)
                        return ret;
@@ -1183,7 +1185,7 @@ static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
        } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) {
                if (link->flags & MEDIA_LNK_FL_ENABLED)
                        ret = __fimc_md_modify_pipelines(sink, true, graph);
-               media_entity_graph_walk_cleanup(graph);
+               media_graph_walk_cleanup(graph);
        }
 
        return ret ? -EPIPE : 0;
index ed122cb2dd7416bbc8fd3a6dbda4e7b2e0341b17..957787a2f48002379639ee362e0ba59935ab7062 100644 (file)
@@ -154,7 +154,7 @@ struct fimc_md {
        bool user_subdev_api;
        spinlock_t slock;
        struct list_head pipelines;
-       struct media_entity_graph link_setup_graph;
+       struct media_graph link_setup_graph;
 };
 
 static inline
index befd9fc0adc4aa26c74deee6a9e6ba39d50251c2..f819b29efc384bc573bd3070fda60472ef792ab6 100644 (file)
@@ -649,23 +649,23 @@ static int s5pcsis_log_status(struct v4l2_subdev *sd)
        return 0;
 }
 
-static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
+static const struct v4l2_subdev_core_ops s5pcsis_core_ops = {
        .s_power = s5pcsis_s_power,
        .log_status = s5pcsis_log_status,
 };
 
-static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
+static const struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
        .enum_mbus_code = s5pcsis_enum_mbus_code,
        .get_fmt = s5pcsis_get_fmt,
        .set_fmt = s5pcsis_set_fmt,
 };
 
-static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
+static const struct v4l2_subdev_video_ops s5pcsis_video_ops = {
        .s_rx_buffer = s5pcsis_s_rx_buffer,
        .s_stream = s5pcsis_s_stream,
 };
 
-static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
+static const struct v4l2_subdev_ops s5pcsis_subdev_ops = {
        .core = &s5pcsis_core_ops,
        .pad = &s5pcsis_pad_ops,
        .video = &s5pcsis_video_ops,
index 0746592278645d0a8794bfd4e3286a2bd7396a33..502877a4b1df34a502145d22e57af23889643fd8 100644 (file)
@@ -351,16 +351,6 @@ static void mtk_vdec_worker(struct work_struct *work)
        dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
        dst_buf_info = container_of(dst_vb2_v4l2, struct mtk_video_dec_buf, vb);
 
-       buf.va = vb2_plane_vaddr(src_buf, 0);
-       buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
-       buf.size = (size_t)src_buf->planes[0].bytesused;
-       if (!buf.va) {
-               v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-               mtk_v4l2_err("[%d] id=%d src_addr is NULL!!",
-                               ctx->id, src_buf->index);
-               return;
-       }
-
        pfb = &dst_buf_info->frame_buffer;
        pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
        pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
@@ -371,8 +361,6 @@ static void mtk_vdec_worker(struct work_struct *work)
        pfb->base_c.size = ctx->picinfo.c_bs_sz + ctx->picinfo.c_len_sz;
        pfb->status = 0;
        mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id);
-       mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
-                       ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
 
        mtk_v4l2_debug(3,
                        "id=%d Framebuf  pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx",
@@ -381,24 +369,36 @@ static void mtk_vdec_worker(struct work_struct *work)
                        &pfb->base_c.dma_addr, pfb->base_y.size);
 
        if (src_buf_info->lastframe) {
-               /* update src buf status */
+               mtk_v4l2_debug(1, "Got empty flush input buffer.");
                src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-               src_buf_info->lastframe = false;
-               v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
 
                /* update dst buf status */
                dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+               mutex_lock(&ctx->lock);
                dst_buf_info->used = false;
+               mutex_unlock(&ctx->lock);
 
                vdec_if_decode(ctx, NULL, NULL, &res_chg);
                clean_display_buffer(ctx);
                vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 0, 0);
                vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 1, 0);
+               dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_LAST;
                v4l2_m2m_buf_done(&dst_buf_info->vb, VB2_BUF_STATE_DONE);
                clean_free_buffer(ctx);
                v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
                return;
        }
+       buf.va = vb2_plane_vaddr(src_buf, 0);
+       buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+       buf.size = (size_t)src_buf->planes[0].bytesused;
+       if (!buf.va) {
+               v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+               mtk_v4l2_err("[%d] id=%d src_addr is NULL!!",
+                               ctx->id, src_buf->index);
+               return;
+       }
+       mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
+                       ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
        dst_buf_info->vb.vb2_buf.timestamp
                        = src_buf_info->vb.vb2_buf.timestamp;
        dst_buf_info->vb.timecode
@@ -412,10 +412,9 @@ static void mtk_vdec_worker(struct work_struct *work)
 
        if (ret) {
                mtk_v4l2_err(
-                       " <===[%d], src_buf[%d]%d sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>",
+                       " <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>",
                        ctx->id,
                        src_buf->index,
-                       src_buf_info->lastframe,
                        buf.size,
                        src_buf_info->vb.vb2_buf.timestamp,
                        dst_buf->index,
@@ -456,6 +455,65 @@ static void mtk_vdec_worker(struct work_struct *work)
        v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 }
 
+static int vidioc_try_decoder_cmd(struct file *file, void *priv,
+                               struct v4l2_decoder_cmd *cmd)
+{
+       switch (cmd->cmd) {
+       case V4L2_DEC_CMD_STOP:
+       case V4L2_DEC_CMD_START:
+               if (cmd->flags != 0) {
+                       mtk_v4l2_err("cmd->flags=%u", cmd->flags);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+static int vidioc_decoder_cmd(struct file *file, void *priv,
+                               struct v4l2_decoder_cmd *cmd)
+{
+       struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+       struct vb2_queue *src_vq, *dst_vq;
+       int ret;
+
+       ret = vidioc_try_decoder_cmd(file, priv, cmd);
+       if (ret)
+               return ret;
+
+       mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd);
+       dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+                               V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+       switch (cmd->cmd) {
+       case V4L2_DEC_CMD_STOP:
+               src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+                               V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+               if (!vb2_is_streaming(src_vq)) {
+                       mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
+                       return 0;
+               }
+               if (!vb2_is_streaming(dst_vq)) {
+                       mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
+                       return 0;
+               }
+               v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
+               v4l2_m2m_try_schedule(ctx->m2m_ctx);
+               break;
+
+       case V4L2_DEC_CMD_START:
+               vb2_clear_last_buffer_dequeued(dst_vq);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
 {
        mutex_unlock(&ctx->dev->dec_mutex);
@@ -521,10 +579,6 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv,
                            struct v4l2_buffer *buf)
 {
        struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-       struct vb2_queue *vq;
-       struct vb2_buffer *vb;
-       struct mtk_video_dec_buf *mtkbuf;
-       struct vb2_v4l2_buffer  *vb2_v4l2;
 
        if (ctx->state == MTK_STATE_ABORT) {
                mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
@@ -532,25 +586,6 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv,
                return -EIO;
        }
 
-       vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type);
-       if (buf->index >= vq->num_buffers) {
-               mtk_v4l2_debug(1, "buffer index %d out of range", buf->index);
-               return -EINVAL;
-       }
-       vb = vq->bufs[buf->index];
-       vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
-       mtkbuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
-
-       if ((buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
-           (buf->m.planes[0].bytesused == 0)) {
-               mtkbuf->lastframe = true;
-               mtk_v4l2_debug(1, "[%d] (%d) id=%d lastframe=%d (%d,%d, %d) vb=%p",
-                        ctx->id, buf->type, buf->index,
-                        mtkbuf->lastframe, buf->bytesused,
-                        buf->m.planes[0].bytesused, buf->length,
-                        vb);
-       }
-
        return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
 }
 
@@ -1067,10 +1102,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
        int ret = 0;
        unsigned int dpbsize = 1;
        struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-       struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
-                               struct vb2_v4l2_buffer, vb2_buf);
-       struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
-                               struct mtk_video_dec_buf, vb);
+       struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
+       struct mtk_video_dec_buf *buf = NULL;
 
        mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p",
                        ctx->id, vb->vb2_queue->type,
@@ -1079,10 +1112,11 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
         * check if this buffer is ready to be used after decode
         */
        if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+               buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
                mutex_lock(&ctx->lock);
                if (buf->used == false) {
-                       v4l2_m2m_buf_queue(ctx->m2m_ctx,
-                                       to_vb2_v4l2_buffer(vb));
+                       v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
                        buf->queued_in_vb2 = true;
                        buf->queued_in_v4l2 = true;
                        buf->ready_to_display = false;
@@ -1095,7 +1129,7 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
                return;
        }
 
-       v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
+       v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
 
        if (ctx->state != MTK_STATE_INIT) {
                mtk_v4l2_debug(3, "[%d] already init driver %d",
@@ -1108,6 +1142,14 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
                mtk_v4l2_err("No src buffer");
                return;
        }
+       vb2_v4l2 = to_vb2_v4l2_buffer(src_buf);
+       buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
+       if (buf->lastframe) {
+               /* This shouldn't happen. Just in case. */
+               mtk_v4l2_err("Invalid flush buffer.");
+               v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+               return;
+       }
 
        src_mem.va = vb2_plane_vaddr(src_buf, 0);
        src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
@@ -1126,15 +1168,14 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
                 * if there is no SPS header or picture info
                 * in bs
                 */
-               int log_level = ret ? 0 : 1;
 
                src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
                v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf),
                                        VB2_BUF_STATE_DONE);
-               mtk_v4l2_debug(log_level,
-                               "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d",
-                               ctx->id, src_buf->index,
-                               src_mem.size, ret, res_chg);
+               mtk_v4l2_debug(ret ? 0 : 1,
+                              "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d",
+                              ctx->id, src_buf->index,
+                              src_mem.size, ret, res_chg);
                return;
        }
 
@@ -1224,9 +1265,15 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
                        ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
 
        if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-               while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
-                       v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf),
-                                       VB2_BUF_STATE_ERROR);
+               while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
+                       struct vb2_v4l2_buffer *vb2_v4l2 =
+                                       to_vb2_v4l2_buffer(src_buf);
+                       struct mtk_video_dec_buf *buf_info = container_of(
+                                       vb2_v4l2, struct mtk_video_dec_buf, vb);
+                       if (!buf_info->lastframe)
+                               v4l2_m2m_buf_done(vb2_v4l2,
+                                               VB2_BUF_STATE_ERROR);
+               }
                return;
        }
 
@@ -1406,6 +1453,9 @@ const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
        .vidioc_g_selection             = vidioc_vdec_g_selection,
        .vidioc_s_selection             = vidioc_vdec_s_selection,
+
+       .vidioc_decoder_cmd = vidioc_decoder_cmd,
+       .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
 };
 
 int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
index d48287c727f4f7e418f935bdad91c2f03a7daf73..4334b73948612911f508e7bf6ca29a41d53982f5 100644 (file)
@@ -105,13 +105,21 @@ static int fops_vcodec_open(struct file *file)
 {
        struct mtk_vcodec_dev *dev = video_drvdata(file);
        struct mtk_vcodec_ctx *ctx = NULL;
+       struct mtk_video_dec_buf *mtk_buf = NULL;
        int ret = 0;
+       struct vb2_queue *src_vq;
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
+       mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL);
+       if (!mtk_buf) {
+               kfree(ctx);
+               return -ENOMEM;
+       }
 
        mutex_lock(&dev->dev_mutex);
+       ctx->empty_flush_buf = mtk_buf;
        ctx->id = dev->id_counter++;
        v4l2_fh_init(&ctx->fh, video_devdata(file));
        file->private_data = &ctx->fh;
@@ -135,6 +143,10 @@ static int fops_vcodec_open(struct file *file)
                        ret);
                goto err_m2m_ctx_init;
        }
+       src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+                               V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+       ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
+       ctx->empty_flush_buf->lastframe = true;
        mtk_vcodec_dec_set_default_params(ctx);
 
        if (v4l2_fh_is_singular(&ctx->fh)) {
@@ -173,6 +185,7 @@ err_m2m_ctx_init:
 err_ctrls_setup:
        v4l2_fh_del(&ctx->fh);
        v4l2_fh_exit(&ctx->fh);
+       kfree(ctx->empty_flush_buf);
        kfree(ctx);
        mutex_unlock(&dev->dev_mutex);
 
@@ -203,6 +216,7 @@ static int fops_vcodec_release(struct file *file)
        v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
        list_del_init(&ctx->list);
+       kfree(ctx->empty_flush_buf);
        kfree(ctx);
        mutex_unlock(&dev->dev_mutex);
        return 0;
index d7eb8ef855d25e59d9de3871f42275d271beba0c..3cffb381ac8e280ba9c8fa14d75681e2d4bf8f3d 100644 (file)
@@ -254,6 +254,7 @@ struct vdec_pic_info {
  * @decode_work: worker for the decoding
  * @encode_work: worker for the encoding
  * @last_decoded_picinfo: pic information get from latest decode
+ * @empty_flush_buf: a fake size-0 capture buffer that indicates flush
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -291,6 +292,7 @@ struct mtk_vcodec_ctx {
        struct work_struct decode_work;
        struct work_struct encode_work;
        struct vdec_pic_info last_decoded_picinfo;
+       struct mtk_video_dec_buf *empty_flush_buf;
 
        enum v4l2_colorspace colorspace;
        enum v4l2_ycbcr_encoding ycbcr_enc;
index 5a24c51aebb7dc13f2d4876bccc2bd67f1ff9203..1abd14e79565f4105b9bdbed425f6fe3d2464a30 100644 (file)
@@ -70,9 +70,8 @@ void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
 {
        int err;
-       uint32_t msg_id = *(uint32_t *)msg;
 
-       mtk_vcodec_debug(vpu, "id=%X", msg_id);
+       mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg);
 
        vpu->failure = 0;
        vpu->signaled = 0;
@@ -80,7 +79,7 @@ static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
        err = vpu_ipi_send(vpu->dev, vpu->id, msg, len);
        if (err) {
                mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
-                              vpu->id, msg_id, err);
+                              vpu->id, *(uint32_t *)msg, err);
                return err;
        }
 
index b76c80bdf30b82f8c90aaf5aa3c9ad069261e282..4eb3be37ba143980291f33e0de40835a352f42ad 100644 (file)
@@ -665,10 +665,10 @@ static int h264_enc_deinit(unsigned long handle)
 }
 
 static const struct venc_common_if venc_h264_if = {
-       h264_enc_init,
-       h264_enc_encode,
-       h264_enc_set_param,
-       h264_enc_deinit,
+       .init = h264_enc_init,
+       .encode = h264_enc_encode,
+       .set_param = h264_enc_set_param,
+       .deinit = h264_enc_deinit,
 };
 
 const struct venc_common_if *get_h264_enc_comm_if(void);
index 544f57186243673e76063f82e58a54f6f05651e3..a6fa145f2c54e201937b3bab5e76197294b786cc 100644 (file)
@@ -470,10 +470,10 @@ static int vp8_enc_deinit(unsigned long handle)
 }
 
 static const struct venc_common_if venc_vp8_if = {
-       vp8_enc_init,
-       vp8_enc_encode,
-       vp8_enc_set_param,
-       vp8_enc_deinit,
+       .init = vp8_enc_init,
+       .encode = vp8_enc_encode,
+       .set_param = vp8_enc_set_param,
+       .deinit = vp8_enc_deinit,
 };
 
 const struct venc_common_if *get_vp8_enc_comm_if(void);
index a01c7599b5105704eb8b6d82b98de2e977b21bd4..0d882acf88305c03371ad72595155e8411d0a04a 100644 (file)
@@ -79,10 +79,8 @@ static int vpu_enc_send_msg(struct venc_vpu_inst *vpu, void *msg,
 
        status = vpu_ipi_send(vpu->dev, vpu->id, msg, len);
        if (status) {
-               uint32_t msg_id = *(uint32_t *)msg;
-
                mtk_vcodec_err(vpu, "vpu_ipi_send msg_id %x len %d fail %d",
-                              msg_id, len, status);
+                              *(uint32_t *)msg, len, status);
                return -EINVAL;
        }
        if (vpu->failure)
index 7354469670b79a0e71298411c7b6791a314815d4..218e6d7ae93ae003c7600ea9b1c268cf2305b7ed 100644 (file)
@@ -225,22 +225,22 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 static int isp_video_get_graph_data(struct isp_video *video,
                                    struct isp_pipeline *pipe)
 {
-       struct media_entity_graph graph;
+       struct media_graph graph;
        struct media_entity *entity = &video->video.entity;
        struct media_device *mdev = entity->graph_obj.mdev;
        struct isp_video *far_end = NULL;
        int ret;
 
        mutex_lock(&mdev->graph_mutex);
-       ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
+       ret = media_graph_walk_init(&graph, mdev);
        if (ret) {
                mutex_unlock(&mdev->graph_mutex);
                return ret;
        }
 
-       media_entity_graph_walk_start(&graph, entity);
+       media_graph_walk_start(&graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(&graph))) {
+       while ((entity = media_graph_walk_next(&graph))) {
                struct isp_video *__video;
 
                media_entity_enum_set(&pipe->ent_enum, entity);
@@ -261,7 +261,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 
        mutex_unlock(&mdev->graph_mutex);
 
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
 
        if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
                pipe->input = far_end;
@@ -1112,7 +1112,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
        pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
        pipe->max_rate = pipe->l3_ick;
 
-       ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
+       ret = media_pipeline_start(&video->video.entity, &pipe->pipe);
        if (ret < 0)
                goto err_pipeline_start;
 
@@ -1169,7 +1169,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
        return 0;
 
 err_check_format:
-       media_entity_pipeline_stop(&video->video.entity);
+       media_pipeline_stop(&video->video.entity);
 err_pipeline_start:
        /* TODO: Implement PM QoS */
        /* The DMA queue must be emptied here, otherwise CCDC interrupts that
@@ -1236,7 +1236,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
        video->error = false;
 
        /* TODO: Implement PM QoS */
-       media_entity_pipeline_stop(&video->video.entity);
+       media_pipeline_stop(&video->video.entity);
 
        media_entity_enum_cleanup(&pipe->ent_enum);
 
@@ -1350,6 +1350,7 @@ static int isp_video_open(struct file *file)
 done:
        if (ret < 0) {
                v4l2_fh_del(&handle->vfh);
+               v4l2_fh_exit(&handle->vfh);
                kfree(handle);
        }
 
@@ -1373,6 +1374,7 @@ static int isp_video_release(struct file *file)
 
        /* Release the file handle. */
        v4l2_fh_del(vfh);
+       v4l2_fh_exit(vfh);
        kfree(handle);
        file->private_data = NULL;
 
index 674cc1309b436b963b313e7102e789a4be966316..42f25d241edd7c40548842a2e2fb940002030b68 100644 (file)
@@ -1596,7 +1596,7 @@ static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
        else
                fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp);
 
-       dprintk(ctx->fdp1, "Try %s format: %4s (0x%08x) %ux%u field %u\n",
+       dprintk(ctx->fdp1, "Try %s format: %4.4s (0x%08x) %ux%u field %u\n",
                V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
                (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
                f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
@@ -1671,7 +1671,7 @@ static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
 
        fdp1_set_format(ctx, &f->fmt.pix_mp, f->type);
 
-       dprintk(ctx->fdp1, "Set %s format: %4s (0x%08x) %ux%u field %u\n",
+       dprintk(ctx->fdp1, "Set %s format: %4.4s (0x%08x) %ux%u field %u\n",
                V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
                (char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
                f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
index 0413a861a59a48e4ff76522892905b9e6f97e07d..1b30be72f4f9f1e664fee96b34dbb4b6d150401a 100644 (file)
@@ -856,13 +856,13 @@ static int s3c_camif_streamon(struct file *file, void *priv,
        if (s3c_vp_active(vp))
                return 0;
 
-       ret = media_entity_pipeline_start(sensor, camif->m_pipeline);
+       ret = media_pipeline_start(sensor, camif->m_pipeline);
        if (ret < 0)
                return ret;
 
        ret = camif_pipeline_validate(camif);
        if (ret < 0) {
-               media_entity_pipeline_stop(sensor);
+               media_pipeline_stop(sensor);
                return ret;
        }
 
@@ -886,7 +886,7 @@ static int s3c_camif_streamoff(struct file *file, void *priv,
 
        ret = vb2_streamoff(&vp->vb_queue, type);
        if (ret == 0)
-               media_entity_pipeline_stop(&camif->sensor.sd->entity);
+               media_pipeline_stop(&camif->sensor.sd->entity);
        return ret;
 }
 
@@ -1488,7 +1488,7 @@ static const struct v4l2_subdev_pad_ops s3c_camif_subdev_pad_ops = {
        .set_fmt = s3c_camif_subdev_set_fmt,
 };
 
-static struct v4l2_subdev_ops s3c_camif_subdev_ops = {
+static const struct v4l2_subdev_ops s3c_camif_subdev_ops = {
        .pad = &s3c_camif_subdev_pad_ops,
 };
 
index 534d6c3c6d608865aa7afe0135c31dcdb4b61cfe..cb4986b8f798296ff89851cc0615541c1e688b1e 100644 (file)
@@ -59,7 +59,7 @@ static int soc_camera_platform_s_power(struct v4l2_subdev *sd, int on)
        return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, NULL, on);
 }
 
-static struct v4l2_subdev_core_ops platform_subdev_core_ops = {
+static const struct v4l2_subdev_core_ops platform_subdev_core_ops = {
        .s_power = soc_camera_platform_s_power,
 };
 
@@ -110,7 +110,7 @@ static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd,
        return 0;
 }
 
-static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
+static const struct v4l2_subdev_video_ops platform_subdev_video_ops = {
        .s_stream       = soc_camera_platform_s_stream,
        .g_mbus_config  = soc_camera_platform_g_mbus_config,
 };
@@ -122,7 +122,7 @@ static const struct v4l2_subdev_pad_ops platform_subdev_pad_ops = {
        .set_fmt        = soc_camera_platform_fill_fmt,
 };
 
-static struct v4l2_subdev_ops platform_subdev_ops = {
+static const struct v4l2_subdev_ops platform_subdev_ops = {
        .core   = &platform_subdev_core_ops,
        .video  = &platform_subdev_video_ops,
        .pad    = &platform_subdev_pad_ops,
index 79c56356a7c7aad03ccd4d8fbda5feb126d8be94..7af66860d6240cca3cf44e9b8a2ea8724920481e 100644 (file)
@@ -677,7 +677,7 @@ int bdisp_debugfs_create(struct bdisp_dev *bdisp)
 
 err:
        bdisp_debugfs_remove(bdisp);
-       return 0;
+       return -ENOMEM;
 }
 
 void bdisp_debugfs_remove(struct bdisp_dev *bdisp)
diff --git a/drivers/media/platform/sti/delta/Makefile b/drivers/media/platform/sti/delta/Makefile
new file mode 100644 (file)
index 0000000..8d03250
--- /dev/null
@@ -0,0 +1,6 @@
+obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o
+st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o delta-debug.o
+
+# MJPEG support
+st-delta-$(CONFIG_VIDEO_STI_DELTA_MJPEG) += delta-mjpeg-hdr.o
+st-delta-$(CONFIG_VIDEO_STI_DELTA_MJPEG) += delta-mjpeg-dec.o
diff --git a/drivers/media/platform/sti/delta/delta-cfg.h b/drivers/media/platform/sti/delta/delta-cfg.h
new file mode 100644 (file)
index 0000000..c6388f5
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_CFG_H
+#define DELTA_CFG_H
+
+#define DELTA_FW_VERSION "21.1-3"
+
+#define DELTA_MIN_WIDTH  32
+#define DELTA_MAX_WIDTH  4096
+#define DELTA_MIN_HEIGHT 32
+#define DELTA_MAX_HEIGHT 2400
+
+/* DELTA requires a 32x32 pixels alignment for frames */
+#define DELTA_WIDTH_ALIGNMENT    32
+#define DELTA_HEIGHT_ALIGNMENT   32
+
+#define DELTA_DEFAULT_WIDTH  DELTA_MIN_WIDTH
+#define DELTA_DEFAULT_HEIGHT DELTA_MIN_HEIGHT
+#define DELTA_DEFAULT_FRAMEFORMAT  V4L2_PIX_FMT_NV12
+#define DELTA_DEFAULT_STREAMFORMAT V4L2_PIX_FMT_MJPEG
+
+#define DELTA_MAX_RESO (DELTA_MAX_WIDTH * DELTA_MAX_HEIGHT)
+
+/* guard value for number of access units */
+#define DELTA_MAX_AUS 10
+
+/* IP perf dependent, can be tuned */
+#define DELTA_PEAK_FRAME_SMOOTHING 2
+
+/*
+ * guard output frame count:
+ * - at least 1 frame needed for display
+ * - at worst 21
+ *   ( max h264 dpb (16) +
+ *     decoding peak smoothing (2) +
+ *     user display pipeline (3) )
+ */
+#define DELTA_MIN_FRAME_USER    1
+#define DELTA_MAX_DPB           16
+#define DELTA_MAX_FRAME_USER    3 /* platform/use-case dependent */
+#define DELTA_MAX_FRAMES (DELTA_MAX_DPB + DELTA_PEAK_FRAME_SMOOTHING +\
+                         DELTA_MAX_FRAME_USER)
+
+#if DELTA_MAX_FRAMES > VIDEO_MAX_FRAME
+#undef DELTA_MAX_FRAMES
+#define DELTA_MAX_FRAMES (VIDEO_MAX_FRAME)
+#endif
+
+/* extra space to be allocated to store codec specific data per frame */
+#define DELTA_MAX_FRAME_PRIV_SIZE 100
+
+/* PM runtime auto power-off after 5ms of inactivity */
+#define DELTA_HW_AUTOSUSPEND_DELAY_MS 5
+
+#define DELTA_MAX_DECODERS 10
+#ifdef CONFIG_VIDEO_STI_DELTA_MJPEG
+extern const struct delta_dec mjpegdec;
+#endif
+
+#endif /* DELTA_CFG_H */
diff --git a/drivers/media/platform/sti/delta/delta-debug.c b/drivers/media/platform/sti/delta/delta-debug.c
new file mode 100644 (file)
index 0000000..a7ebf2c
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Authors: Hugues Fruchet <hugues.fruchet@st.com>
+ *          Fabrice Lecoultre <fabrice.lecoultre@st.com>
+ *          for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include "delta.h"
+#include "delta-debug.h"
+
+char *delta_streaminfo_str(struct delta_streaminfo *s, char *str,
+                          unsigned int len)
+{
+       if (!s)
+               return NULL;
+
+       snprintf(str, len,
+                "%4.4s %dx%d %s %s dpb=%d %s %s %s%dx%d@(%d,%d) %s%d/%d",
+                (char *)&s->streamformat, s->width, s->height,
+                s->profile, s->level, s->dpb,
+                (s->field == V4L2_FIELD_NONE) ? "progressive" : "interlaced",
+                s->other,
+                s->flags & DELTA_STREAMINFO_FLAG_CROP ? "crop=" : "",
+                s->crop.width, s->crop.height,
+                s->crop.left, s->crop.top,
+                s->flags & DELTA_STREAMINFO_FLAG_PIXELASPECT ? "par=" : "",
+                s->pixelaspect.numerator,
+                s->pixelaspect.denominator);
+
+       return str;
+}
+
+char *delta_frameinfo_str(struct delta_frameinfo *f, char *str,
+                         unsigned int len)
+{
+       if (!f)
+               return NULL;
+
+       snprintf(str, len,
+                "%4.4s %dx%d aligned %dx%d %s %s%dx%d@(%d,%d) %s%d/%d",
+                (char *)&f->pixelformat, f->width, f->height,
+                f->aligned_width, f->aligned_height,
+                (f->field == V4L2_FIELD_NONE) ? "progressive" : "interlaced",
+                f->flags & DELTA_STREAMINFO_FLAG_CROP ? "crop=" : "",
+                f->crop.width, f->crop.height,
+                f->crop.left, f->crop.top,
+                f->flags & DELTA_STREAMINFO_FLAG_PIXELASPECT ? "par=" : "",
+                f->pixelaspect.numerator,
+                f->pixelaspect.denominator);
+
+       return str;
+}
+
+void delta_trace_summary(struct delta_ctx *ctx)
+{
+       struct delta_dev *delta = ctx->dev;
+       struct delta_streaminfo *s = &ctx->streaminfo;
+       unsigned char str[100] = "";
+
+       if (!(ctx->flags & DELTA_FLAG_STREAMINFO))
+               return;
+
+       dev_dbg(delta->dev, "%s %s, %d frames decoded, %d frames output, %d frames dropped, %d stream errors, %d decode errors",
+               ctx->name,
+               delta_streaminfo_str(s, str, sizeof(str)),
+               ctx->decoded_frames,
+               ctx->output_frames,
+               ctx->dropped_frames,
+               ctx->stream_errors,
+               ctx->decode_errors);
+}
diff --git a/drivers/media/platform/sti/delta/delta-debug.h b/drivers/media/platform/sti/delta/delta-debug.h
new file mode 100644 (file)
index 0000000..955c158
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Authors: Hugues Fruchet <hugues.fruchet@st.com>
+ *          Fabrice Lecoultre <fabrice.lecoultre@st.com>
+ *          for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_DEBUG_H
+#define DELTA_DEBUG_H
+
+char *delta_streaminfo_str(struct delta_streaminfo *s, char *str,
+                          unsigned int len);
+char *delta_frameinfo_str(struct delta_frameinfo *f, char *str,
+                         unsigned int len);
+void delta_trace_summary(struct delta_ctx *ctx);
+
+#endif /* DELTA_DEBUG_H */
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c
new file mode 100644 (file)
index 0000000..41e4a4c
--- /dev/null
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/rpmsg.h>
+
+#include "delta.h"
+#include "delta-ipc.h"
+#include "delta-mem.h"
+
+#define IPC_TIMEOUT 100
+#define IPC_SANITY_TAG 0xDEADBEEF
+
+enum delta_ipc_fw_command {
+       DELTA_IPC_OPEN,
+       DELTA_IPC_SET_STREAM,
+       DELTA_IPC_DECODE,
+       DELTA_IPC_CLOSE
+};
+
+#define to_rpmsg_driver(__drv) container_of(__drv, struct rpmsg_driver, drv)
+#define to_delta(__d) container_of(__d, struct delta_dev, rpmsg_driver)
+
+#define to_ctx(hdl) ((struct delta_ipc_ctx *)hdl)
+#define to_pctx(ctx) container_of(ctx, struct delta_ctx, ipc_ctx)
+
+struct delta_ipc_header_msg {
+       u32 tag;
+       void *host_hdl;
+       u32 copro_hdl;
+       u32 command;
+};
+
+#define to_host_hdl(ctx) ((void *)ctx)
+
+#define msg_to_ctx(msg) ((struct delta_ipc_ctx *)(msg)->header.host_hdl)
+#define msg_to_copro_hdl(msg) ((msg)->header.copro_hdl)
+
+static inline dma_addr_t to_paddr(struct delta_ipc_ctx *ctx, void *vaddr)
+{
+       return (ctx->ipc_buf->paddr + (vaddr - ctx->ipc_buf->vaddr));
+}
+
+static inline bool is_valid_data(struct delta_ipc_ctx *ctx,
+                                void *data, u32 size)
+{
+       return ((data >= ctx->ipc_buf->vaddr) &&
+               ((data + size) <= (ctx->ipc_buf->vaddr + ctx->ipc_buf->size)));
+}
+
+/*
+ * IPC shared memory (@ipc_buf_size, @ipc_buf_paddr) is sent to copro
+ * at each instance opening. This memory is allocated by IPC client
+ * and given through delta_ipc_open(). All messages parameters
+ * (open, set_stream, decode) will have their phy address within
+ * this IPC shared memory, avoiding de-facto recopies inside delta-ipc.
+ * All the below messages structures are used on both host and firmware
+ * side and are packed (use only of 32 bits size fields in messages
+ * structures to ensure packing):
+ * - struct delta_ipc_open_msg
+ * - struct delta_ipc_set_stream_msg
+ * - struct delta_ipc_decode_msg
+ * - struct delta_ipc_close_msg
+ * - struct delta_ipc_cb_msg
+ */
+struct delta_ipc_open_msg {
+       struct delta_ipc_header_msg header;
+       u32 ipc_buf_size;
+       dma_addr_t ipc_buf_paddr;
+       char name[32];
+       u32 param_size;
+       dma_addr_t param_paddr;
+};
+
+struct delta_ipc_set_stream_msg {
+       struct delta_ipc_header_msg header;
+       u32 param_size;
+       dma_addr_t param_paddr;
+};
+
+struct delta_ipc_decode_msg {
+       struct delta_ipc_header_msg header;
+       u32 param_size;
+       dma_addr_t param_paddr;
+       u32 status_size;
+       dma_addr_t status_paddr;
+};
+
+struct delta_ipc_close_msg {
+       struct delta_ipc_header_msg header;
+};
+
+struct delta_ipc_cb_msg {
+       struct delta_ipc_header_msg header;
+       int err;
+};
+
+static void build_msg_header(struct delta_ipc_ctx *ctx,
+                            enum delta_ipc_fw_command command,
+                            struct delta_ipc_header_msg *header)
+{
+       header->tag = IPC_SANITY_TAG;
+       header->host_hdl = to_host_hdl(ctx);
+       header->copro_hdl = ctx->copro_hdl;
+       header->command = command;
+}
+
+int delta_ipc_open(struct delta_ctx *pctx, const char *name,
+                  struct delta_ipc_param *param, u32 ipc_buf_size,
+                  struct delta_buf **ipc_buf, void **hdl)
+{
+       struct delta_dev *delta = pctx->dev;
+       struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
+       struct delta_ipc_ctx *ctx = &pctx->ipc_ctx;
+       struct delta_ipc_open_msg msg;
+       struct delta_buf *buf = &ctx->ipc_buf_struct;
+       int ret;
+
+       if (!rpmsg_device) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, rpmsg is not initialized\n",
+                       pctx->name);
+               pctx->sys_errors++;
+               return -EINVAL;
+       }
+
+       if (!name) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, no name given\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!param || !param->data || !param->size) {
+               dev_err(delta->dev,
+                       "%s  ipc: failed to open, empty parameter\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!ipc_buf_size) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, no size given for ipc buffer\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (param->size > ipc_buf_size) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, too large ipc parameter (%d bytes while max %d expected)\n",
+                       pctx->name,
+                       param->size, ctx->ipc_buf->size);
+               return -EINVAL;
+       }
+
+       /* init */
+       init_completion(&ctx->done);
+
+       /*
+        * allocation of contiguous buffer for
+        * data of commands exchanged between
+        * host and firmware coprocessor
+        */
+       ret = hw_alloc(pctx, ipc_buf_size,
+                      "ipc data buffer", buf);
+       if (ret)
+               return ret;
+       ctx->ipc_buf = buf;
+
+       /* build rpmsg message */
+       build_msg_header(ctx, DELTA_IPC_OPEN, &msg.header);
+
+       msg.ipc_buf_size = ipc_buf_size;
+       msg.ipc_buf_paddr = ctx->ipc_buf->paddr;
+
+       memcpy(msg.name, name, sizeof(msg.name));
+       msg.name[sizeof(msg.name) - 1] = 0;
+
+       msg.param_size = param->size;
+       memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size);
+       msg.param_paddr = ctx->ipc_buf->paddr;
+
+       /* send it */
+       ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
+       if (ret) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, rpmsg_send failed (%d) for DELTA_IPC_OPEN (name=%s, size=%d, data=%p)\n",
+                       pctx->name,
+                       ret, name, param->size, param->data);
+               goto err;
+       }
+
+       /* wait for acknowledge */
+       if (!wait_for_completion_timeout
+           (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, timeout waiting for DELTA_IPC_OPEN callback (name=%s, size=%d, data=%p)\n",
+                       pctx->name,
+                       name, param->size, param->data);
+               ret = -ETIMEDOUT;
+               goto err;
+       }
+
+       /* command completed, check error */
+       if (ctx->cb_err) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to open, DELTA_IPC_OPEN completed but with error (%d) (name=%s, size=%d, data=%p)\n",
+                       pctx->name,
+                       ctx->cb_err, name, param->size, param->data);
+               ret = -EIO;
+               goto err;
+       }
+
+       *ipc_buf = ctx->ipc_buf;
+       *hdl = (void *)ctx;
+
+       return 0;
+
+err:
+       pctx->sys_errors++;
+       if (ctx->ipc_buf) {
+               hw_free(pctx, ctx->ipc_buf);
+               ctx->ipc_buf = NULL;
+       }
+
+       return ret;
+};
+
+int delta_ipc_set_stream(void *hdl, struct delta_ipc_param *param)
+{
+       struct delta_ipc_ctx *ctx = to_ctx(hdl);
+       struct delta_ctx *pctx = to_pctx(ctx);
+       struct delta_dev *delta = pctx->dev;
+       struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
+       struct delta_ipc_set_stream_msg msg;
+       int ret;
+
+       if (!hdl) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, invalid ipc handle\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!rpmsg_device) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, rpmsg is not initialized\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!param || !param->data || !param->size) {
+               dev_err(delta->dev,
+                       "%s  ipc: failed to set stream, empty parameter\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (param->size > ctx->ipc_buf->size) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, too large ipc parameter(%d bytes while max %d expected)\n",
+                       pctx->name,
+                       param->size, ctx->ipc_buf->size);
+               return -EINVAL;
+       }
+
+       if (!is_valid_data(ctx, param->data, param->size)) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, parameter is not in expected address range (size=%d, data=%p not in %p..%p)\n",
+                       pctx->name,
+                       param->size,
+                       param->data,
+                       ctx->ipc_buf->vaddr,
+                       ctx->ipc_buf->vaddr + ctx->ipc_buf->size - 1);
+               return -EINVAL;
+       }
+
+       /* build rpmsg message */
+       build_msg_header(ctx, DELTA_IPC_SET_STREAM, &msg.header);
+
+       msg.param_size = param->size;
+       msg.param_paddr = to_paddr(ctx, param->data);
+
+       /* send it */
+       ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
+       if (ret) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, rpmsg_send failed (%d) for DELTA_IPC_SET_STREAM (size=%d, data=%p)\n",
+                       pctx->name,
+                       ret, param->size, param->data);
+               pctx->sys_errors++;
+               return ret;
+       }
+
+       /* wait for acknowledge */
+       if (!wait_for_completion_timeout
+           (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, timeout waiting for DELTA_IPC_SET_STREAM callback (size=%d, data=%p)\n",
+                       pctx->name,
+                       param->size, param->data);
+               pctx->sys_errors++;
+               return -ETIMEDOUT;
+       }
+
+       /* command completed, check status */
+       if (ctx->cb_err) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to set stream, DELTA_IPC_SET_STREAM completed but with error (%d) (size=%d, data=%p)\n",
+                       pctx->name,
+                       ctx->cb_err, param->size, param->data);
+               pctx->sys_errors++;
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int delta_ipc_decode(void *hdl, struct delta_ipc_param *param,
+                    struct delta_ipc_param *status)
+{
+       struct delta_ipc_ctx *ctx = to_ctx(hdl);
+       struct delta_ctx *pctx = to_pctx(ctx);
+       struct delta_dev *delta = pctx->dev;
+       struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
+       struct delta_ipc_decode_msg msg;
+       int ret;
+
+       if (!hdl) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, invalid ipc handle\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!rpmsg_device) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, rpmsg is not initialized\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!param || !param->data || !param->size) {
+               dev_err(delta->dev,
+                       "%s  ipc: failed to decode, empty parameter\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (!status || !status->data || !status->size) {
+               dev_err(delta->dev,
+                       "%s  ipc: failed to decode, empty status\n",
+                       pctx->name);
+               return -EINVAL;
+       }
+
+       if (param->size + status->size > ctx->ipc_buf->size) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, too large ipc parameter (%d bytes (param) + %d bytes (status) while max %d expected)\n",
+                       pctx->name,
+                       param->size,
+                       status->size,
+                       ctx->ipc_buf->size);
+               return -EINVAL;
+       }
+
+       if (!is_valid_data(ctx, param->data, param->size)) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, parameter is not in expected address range (size=%d, data=%p not in %p..%p)\n",
+                       pctx->name,
+                       param->size,
+                       param->data,
+                       ctx->ipc_buf->vaddr,
+                       ctx->ipc_buf->vaddr + ctx->ipc_buf->size - 1);
+               return -EINVAL;
+       }
+
+       if (!is_valid_data(ctx, status->data, status->size)) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, status is not in expected address range (size=%d, data=%p not in %p..%p)\n",
+                       pctx->name,
+                       status->size,
+                       status->data,
+                       ctx->ipc_buf->vaddr,
+                       ctx->ipc_buf->vaddr + ctx->ipc_buf->size - 1);
+               return -EINVAL;
+       }
+
+       /* build rpmsg message */
+       build_msg_header(ctx, DELTA_IPC_DECODE, &msg.header);
+
+       msg.param_size = param->size;
+       msg.param_paddr = to_paddr(ctx, param->data);
+
+       msg.status_size = status->size;
+       msg.status_paddr = to_paddr(ctx, status->data);
+
+       /* send it */
+       ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
+       if (ret) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, rpmsg_send failed (%d) for DELTA_IPC_DECODE (size=%d, data=%p)\n",
+                       pctx->name,
+                       ret, param->size, param->data);
+               pctx->sys_errors++;
+               return ret;
+       }
+
+       /* wait for acknowledge */
+       if (!wait_for_completion_timeout
+           (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, timeout waiting for DELTA_IPC_DECODE callback (size=%d, data=%p)\n",
+                       pctx->name,
+                       param->size, param->data);
+               pctx->sys_errors++;
+               return -ETIMEDOUT;
+       }
+
+       /* command completed, check status */
+       if (ctx->cb_err) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to decode, DELTA_IPC_DECODE completed but with error (%d) (size=%d, data=%p)\n",
+                       pctx->name,
+                       ctx->cb_err, param->size, param->data);
+               pctx->sys_errors++;
+               return -EIO;
+       }
+
+       return 0;
+};
+
+void delta_ipc_close(void *hdl)
+{
+       struct delta_ipc_ctx *ctx = to_ctx(hdl);
+       struct delta_ctx *pctx = to_pctx(ctx);
+       struct delta_dev *delta = pctx->dev;
+       struct rpmsg_device *rpmsg_device = delta->rpmsg_device;
+       struct delta_ipc_close_msg msg;
+       int ret;
+
+       if (!hdl) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to close, invalid ipc handle\n",
+                       pctx->name);
+               return;
+       }
+
+       if (ctx->ipc_buf) {
+               hw_free(pctx, ctx->ipc_buf);
+               ctx->ipc_buf = NULL;
+       }
+
+       if (!rpmsg_device) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to close, rpmsg is not initialized\n",
+                       pctx->name);
+               return;
+       }
+
+       /* build rpmsg message */
+       build_msg_header(ctx, DELTA_IPC_CLOSE, &msg.header);
+
+       /* send it */
+       ret = rpmsg_send(rpmsg_device->ept, &msg, sizeof(msg));
+       if (ret) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to close, rpmsg_send failed (%d) for DELTA_IPC_CLOSE\n",
+                       pctx->name, ret);
+               pctx->sys_errors++;
+               return;
+       }
+
+       /* wait for acknowledge */
+       if (!wait_for_completion_timeout
+           (&ctx->done, msecs_to_jiffies(IPC_TIMEOUT))) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to close, timeout waiting for DELTA_IPC_CLOSE callback\n",
+                       pctx->name);
+               pctx->sys_errors++;
+               return;
+       }
+
+       /* command completed, check status */
+       if (ctx->cb_err) {
+               dev_err(delta->dev,
+                       "%s   ipc: failed to close, DELTA_IPC_CLOSE completed but with error (%d)\n",
+                       pctx->name, ctx->cb_err);
+               pctx->sys_errors++;
+       }
+};
+
+static int delta_ipc_cb(struct rpmsg_device *rpdev, void *data,
+                       int len, void *priv, u32 src)
+{
+       struct delta_ipc_ctx *ctx;
+       struct delta_ipc_cb_msg *msg;
+
+       /* sanity check */
+       if (!rpdev) {
+               dev_err(NULL, "rpdev is NULL\n");
+               return -EINVAL;
+       }
+
+       if (!data || !len) {
+               dev_err(&rpdev->dev,
+                       "unexpected empty message received from src=%d\n", src);
+               return -EINVAL;
+       }
+
+       if (len != sizeof(*msg)) {
+               dev_err(&rpdev->dev,
+                       "unexpected message length received from src=%d (received %d bytes while %zu bytes expected)\n",
+                       len, src, sizeof(*msg));
+               return -EINVAL;
+       }
+
+       msg = (struct delta_ipc_cb_msg *)data;
+       if (msg->header.tag != IPC_SANITY_TAG) {
+               dev_err(&rpdev->dev,
+                       "unexpected message tag received from src=%d (received %x tag while %x expected)\n",
+                       src, msg->header.tag, IPC_SANITY_TAG);
+               return -EINVAL;
+       }
+
+       ctx = msg_to_ctx(msg);
+       if (!ctx) {
+               dev_err(&rpdev->dev,
+                       "unexpected message with NULL host_hdl received from src=%d\n",
+                       src);
+               return -EINVAL;
+       }
+
+       /*
+        * if not already known, save copro instance context
+        * to ensure re-entrance on copro side
+        */
+       if (!ctx->copro_hdl)
+               ctx->copro_hdl = msg_to_copro_hdl(msg);
+
+       /*
+        * all is fine,
+        * update status & complete command
+        */
+       ctx->cb_err = msg->err;
+       complete(&ctx->done);
+
+       return 0;
+}
+
+static int delta_ipc_probe(struct rpmsg_device *rpmsg_device)
+{
+       struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpmsg_device->dev.driver);
+       struct delta_dev *delta = to_delta(rpdrv);
+
+       delta->rpmsg_device = rpmsg_device;
+
+       return 0;
+}
+
+static void delta_ipc_remove(struct rpmsg_device *rpmsg_device)
+{
+       struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpmsg_device->dev.driver);
+       struct delta_dev *delta = to_delta(rpdrv);
+
+       delta->rpmsg_device = NULL;
+}
+
+static struct rpmsg_device_id delta_ipc_device_id_table[] = {
+       {.name = "rpmsg-delta"},
+       {},
+};
+
+static struct rpmsg_driver delta_rpmsg_driver = {
+       .drv = {.name = KBUILD_MODNAME},
+       .id_table = delta_ipc_device_id_table,
+       .probe = delta_ipc_probe,
+       .callback = delta_ipc_cb,
+       .remove = delta_ipc_remove,
+};
+
+int delta_ipc_init(struct delta_dev *delta)
+{
+       delta->rpmsg_driver = delta_rpmsg_driver;
+
+       return register_rpmsg_driver(&delta->rpmsg_driver);
+}
+
+void delta_ipc_exit(struct delta_dev *delta)
+{
+       unregister_rpmsg_driver(&delta->rpmsg_driver);
+}
diff --git a/drivers/media/platform/sti/delta/delta-ipc.h b/drivers/media/platform/sti/delta/delta-ipc.h
new file mode 100644 (file)
index 0000000..cef2019
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_IPC_H
+#define DELTA_IPC_H
+
+int delta_ipc_init(struct delta_dev *delta);
+void delta_ipc_exit(struct delta_dev *delta);
+
+/*
+ * delta_ipc_open - open a decoding instance on firmware side
+ * @ctx:               (in) delta context
+ * @name:              (in) name of decoder to be used
+ * @param:             (in) open command parameters specific to decoder
+ *  @param.size:               (in) size of parameter
+ *  @param.data:               (in) virtual address of parameter
+ * @ipc_buf_size:      (in) size of IPC shared buffer between host
+ *                          and copro used to share command data.
+ *                          Client have to set here the size of the biggest
+ *                          command parameters (+ status if any).
+ *                          Allocation will be done in this function which
+ *                          will give back to client in @ipc_buf the virtual
+ *                          & physical addresses & size of shared IPC buffer.
+ *                          All the further command data (parameters + status)
+ *                          have to be written in this shared IPC buffer
+ *                          virtual memory. This is done to avoid
+ *                          unnecessary copies of command data.
+ * @ipc_buf:           (out) allocated IPC shared buffer
+ *  @ipc_buf.size:             (out) allocated size
+ *  @ipc_buf.vaddr:            (out) virtual address where to copy
+ *                                   further command data
+ * @hdl:               (out) handle of decoding instance.
+ */
+
+int delta_ipc_open(struct delta_ctx *ctx, const char *name,
+                  struct delta_ipc_param *param, u32 ipc_buf_size,
+                  struct delta_buf **ipc_buf, void **hdl);
+
+/*
+ * delta_ipc_set_stream - set information about stream to decoder
+ * @hdl:               (in) handle of decoding instance.
+ * @param:             (in) set stream command parameters specific to decoder
+ *  @param.size:               (in) size of parameter
+ *  @param.data:               (in) virtual address of parameter. Must be
+ *                                  within IPC shared buffer range
+ */
+int delta_ipc_set_stream(void *hdl, struct delta_ipc_param *param);
+
+/*
+ * delta_ipc_decode - frame decoding synchronous request, returns only
+ *                   after decoding completion on firmware side.
+ * @hdl:               (in) handle of decoding instance.
+ * @param:             (in) decode command parameters specific to decoder
+ *  @param.size:               (in) size of parameter
+ *  @param.data:               (in) virtual address of parameter. Must be
+ *                                  within IPC shared buffer range
+ * @status:            (in/out) decode command status specific to decoder
+ *  @status.size:              (in) size of status
+ *  @status.data:              (in/out) virtual address of status. Must be
+ *                                      within IPC shared buffer range.
+ *                                      Status is filled by decoding instance
+ *                                      after decoding completion.
+ */
+int delta_ipc_decode(void *hdl, struct delta_ipc_param *param,
+                    struct delta_ipc_param *status);
+
+/*
+ * delta_ipc_close - close decoding instance
+ * @hdl:               (in) handle of decoding instance to close.
+ */
+void delta_ipc_close(void *hdl);
+
+#endif /* DELTA_IPC_H */
diff --git a/drivers/media/platform/sti/delta/delta-mem.c b/drivers/media/platform/sti/delta/delta-mem.c
new file mode 100644 (file)
index 0000000..d7b53d3
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include "delta.h"
+#include "delta-mem.h"
+
+int hw_alloc(struct delta_ctx *ctx, u32 size, const char *name,
+            struct delta_buf *buf)
+{
+       struct delta_dev *delta = ctx->dev;
+       dma_addr_t dma_addr;
+       void *addr;
+       unsigned long attrs = DMA_ATTR_WRITE_COMBINE;
+
+       addr = dma_alloc_attrs(delta->dev, size, &dma_addr,
+                              GFP_KERNEL | __GFP_NOWARN, attrs);
+       if (!addr) {
+               dev_err(delta->dev,
+                       "%s hw_alloc:dma_alloc_coherent failed for %s (size=%d)\n",
+                       ctx->name, name, size);
+               ctx->sys_errors++;
+               return -ENOMEM;
+       }
+
+       buf->size = size;
+       buf->paddr = dma_addr;
+       buf->vaddr = addr;
+       buf->name = name;
+       buf->attrs = attrs;
+
+       dev_dbg(delta->dev,
+               "%s allocate %d bytes of HW memory @(virt=0x%p, phy=0x%pad): %s\n",
+               ctx->name, size, buf->vaddr, &buf->paddr, buf->name);
+
+       return 0;
+}
+
+void hw_free(struct delta_ctx *ctx, struct delta_buf *buf)
+{
+       struct delta_dev *delta = ctx->dev;
+
+       dev_dbg(delta->dev,
+               "%s     free %d bytes of HW memory @(virt=0x%p, phy=0x%pad): %s\n",
+               ctx->name, buf->size, buf->vaddr, &buf->paddr, buf->name);
+
+       dma_free_attrs(delta->dev, buf->size,
+                      buf->vaddr, buf->paddr, buf->attrs);
+}
diff --git a/drivers/media/platform/sti/delta/delta-mem.h b/drivers/media/platform/sti/delta/delta-mem.h
new file mode 100644 (file)
index 0000000..f8ca109
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_MEM_H
+#define DELTA_MEM_H
+
+int hw_alloc(struct delta_ctx *ctx, u32 size, const char *name,
+            struct delta_buf *buf);
+void hw_free(struct delta_ctx *ctx, struct delta_buf *buf);
+
+#endif /* DELTA_MEM_H */
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
new file mode 100644 (file)
index 0000000..e79bdc6
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2013
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/slab.h>
+
+#include "delta.h"
+#include "delta-ipc.h"
+#include "delta-mjpeg.h"
+#include "delta-mjpeg-fw.h"
+
+#define DELTA_MJPEG_MAX_RESO DELTA_MAX_RESO
+
+struct delta_mjpeg_ctx {
+       /* jpeg header */
+       struct mjpeg_header header_struct;
+       struct mjpeg_header *header;
+
+       /* ipc */
+       void *ipc_hdl;
+       struct delta_buf *ipc_buf;
+
+       /* decoded output frame */
+       struct delta_frame *out_frame;
+
+       unsigned char str[3000];
+};
+
+#define to_ctx(ctx) ((struct delta_mjpeg_ctx *)(ctx)->priv)
+
+static char *ipc_open_param_str(struct jpeg_video_decode_init_params_t *p,
+                               char *str, unsigned int len)
+{
+       char *b = str;
+
+       if (!p)
+               return "";
+
+       b += snprintf(b, len,
+                     "jpeg_video_decode_init_params_t\n"
+                     "circular_buffer_begin_addr_p 0x%x\n"
+                     "circular_buffer_end_addr_p   0x%x\n",
+                     p->circular_buffer_begin_addr_p,
+                     p->circular_buffer_end_addr_p);
+
+       return str;
+}
+
+static char *ipc_decode_param_str(struct jpeg_decode_params_t *p,
+                                 char *str, unsigned int len)
+{
+       char *b = str;
+
+       if (!p)
+               return "";
+
+       b += snprintf(b, len,
+                     "jpeg_decode_params_t\n"
+                     "picture_start_addr_p                  0x%x\n"
+                     "picture_end_addr_p                    0x%x\n"
+                     "decoding_mode                        %d\n"
+                     "display_buffer_addr.display_decimated_luma_p   0x%x\n"
+                     "display_buffer_addr.display_decimated_chroma_p 0x%x\n"
+                     "main_aux_enable                       %d\n"
+                     "additional_flags                     0x%x\n"
+                     "field_flag                           %x\n"
+                     "is_jpeg_image                        %x\n",
+                     p->picture_start_addr_p,
+                     p->picture_end_addr_p,
+                     p->decoding_mode,
+                     p->display_buffer_addr.display_decimated_luma_p,
+                     p->display_buffer_addr.display_decimated_chroma_p,
+                     p->main_aux_enable, p->additional_flags,
+                     p->field_flag,
+                     p->is_jpeg_image);
+
+       return str;
+}
+
+static inline bool is_stream_error(enum jpeg_decoding_error_t err)
+{
+       switch (err) {
+       case JPEG_DECODER_UNDEFINED_HUFF_TABLE:
+       case JPEG_DECODER_BAD_RESTART_MARKER:
+       case JPEG_DECODER_BAD_SOS_SPECTRAL:
+       case JPEG_DECODER_BAD_SOS_SUCCESSIVE:
+       case JPEG_DECODER_BAD_HEADER_LENGTH:
+       case JPEG_DECODER_BAD_COUNT_VALUE:
+       case JPEG_DECODER_BAD_DHT_MARKER:
+       case JPEG_DECODER_BAD_INDEX_VALUE:
+       case JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES:
+       case JPEG_DECODER_BAD_QUANT_TABLE_LENGTH:
+       case JPEG_DECODER_BAD_NUMBER_QUANT_TABLES:
+       case JPEG_DECODER_BAD_COMPONENT_COUNT:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static inline const char *err_str(enum jpeg_decoding_error_t err)
+{
+       switch (err) {
+       case JPEG_DECODER_NO_ERROR:
+               return "JPEG_DECODER_NO_ERROR";
+       case JPEG_DECODER_UNDEFINED_HUFF_TABLE:
+               return "JPEG_DECODER_UNDEFINED_HUFF_TABLE";
+       case JPEG_DECODER_UNSUPPORTED_MARKER:
+               return "JPEG_DECODER_UNSUPPORTED_MARKER";
+       case JPEG_DECODER_UNABLE_ALLOCATE_MEMORY:
+               return "JPEG_DECODER_UNABLE_ALLOCATE_MEMORY";
+       case JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS:
+               return "JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS";
+       case JPEG_DECODER_BAD_PARAMETER:
+               return "JPEG_DECODER_BAD_PARAMETER";
+       case JPEG_DECODER_DECODE_ERROR:
+               return "JPEG_DECODER_DECODE_ERROR";
+       case JPEG_DECODER_BAD_RESTART_MARKER:
+               return "JPEG_DECODER_BAD_RESTART_MARKER";
+       case JPEG_DECODER_UNSUPPORTED_COLORSPACE:
+               return "JPEG_DECODER_UNSUPPORTED_COLORSPACE";
+       case JPEG_DECODER_BAD_SOS_SPECTRAL:
+               return "JPEG_DECODER_BAD_SOS_SPECTRAL";
+       case JPEG_DECODER_BAD_SOS_SUCCESSIVE:
+               return "JPEG_DECODER_BAD_SOS_SUCCESSIVE";
+       case JPEG_DECODER_BAD_HEADER_LENGTH:
+               return "JPEG_DECODER_BAD_HEADER_LENGTH";
+       case JPEG_DECODER_BAD_COUNT_VALUE:
+               return "JPEG_DECODER_BAD_COUNT_VALUE";
+       case JPEG_DECODER_BAD_DHT_MARKER:
+               return "JPEG_DECODER_BAD_DHT_MARKER";
+       case JPEG_DECODER_BAD_INDEX_VALUE:
+               return "JPEG_DECODER_BAD_INDEX_VALUE";
+       case JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES:
+               return "JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES";
+       case JPEG_DECODER_BAD_QUANT_TABLE_LENGTH:
+               return "JPEG_DECODER_BAD_QUANT_TABLE_LENGTH";
+       case JPEG_DECODER_BAD_NUMBER_QUANT_TABLES:
+               return "JPEG_DECODER_BAD_NUMBER_QUANT_TABLES";
+       case JPEG_DECODER_BAD_COMPONENT_COUNT:
+               return "JPEG_DECODER_BAD_COMPONENT_COUNT";
+       case JPEG_DECODER_DIVIDE_BY_ZERO_ERROR:
+               return "JPEG_DECODER_DIVIDE_BY_ZERO_ERROR";
+       case JPEG_DECODER_NOT_JPG_IMAGE:
+               return "JPEG_DECODER_NOT_JPG_IMAGE";
+       case JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE:
+               return "JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE";
+       case JPEG_DECODER_UNSUPPORTED_SCALING:
+               return "JPEG_DECODER_UNSUPPORTED_SCALING";
+       case JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE:
+               return "JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE";
+       case JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE:
+               return "JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE";
+       case JPEG_DECODER_BAD_VALUE_FROM_RED:
+               return "JPEG_DECODER_BAD_VALUE_FROM_RED";
+       case JPEG_DECODER_BAD_SUBREGION_PARAMETERS:
+               return "JPEG_DECODER_BAD_SUBREGION_PARAMETERS";
+       case JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED:
+               return "JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED";
+       case JPEG_DECODER_ERROR_TASK_TIMEOUT:
+               return "JPEG_DECODER_ERROR_TASK_TIMEOUT";
+       case JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED:
+               return "JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED";
+       default:
+               return "!unknown MJPEG error!";
+       }
+}
+
+static bool delta_mjpeg_check_status(struct delta_ctx *pctx,
+                                    struct jpeg_decode_return_params_t *status)
+{
+       struct delta_dev *delta = pctx->dev;
+       bool dump = false;
+
+       if (status->error_code == JPEG_DECODER_NO_ERROR)
+               goto out;
+
+       if (is_stream_error(status->error_code)) {
+               dev_warn_ratelimited(delta->dev,
+                                    "%s  firmware: stream error @ frame %d (%s)\n",
+                                    pctx->name, pctx->decoded_frames,
+                                    err_str(status->error_code));
+               pctx->stream_errors++;
+       } else {
+               dev_warn_ratelimited(delta->dev,
+                                    "%s  firmware: decode error @ frame %d (%s)\n",
+                                    pctx->name, pctx->decoded_frames,
+                                    err_str(status->error_code));
+               pctx->decode_errors++;
+               dump = true;
+       }
+
+out:
+       dev_dbg(delta->dev,
+               "%s  firmware: decoding time(us)=%d\n", pctx->name,
+               status->decode_time_in_us);
+
+       return dump;
+}
+
+static int delta_mjpeg_ipc_open(struct delta_ctx *pctx)
+{
+       struct delta_dev *delta = pctx->dev;
+       struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
+       int ret = 0;
+       struct jpeg_video_decode_init_params_t params_struct;
+       struct jpeg_video_decode_init_params_t *params = &params_struct;
+       struct delta_buf *ipc_buf;
+       u32 ipc_buf_size;
+       struct delta_ipc_param ipc_param;
+       void *hdl;
+
+       memset(params, 0, sizeof(*params));
+       params->circular_buffer_begin_addr_p = 0x00000000;
+       params->circular_buffer_end_addr_p = 0xffffffff;
+
+       dev_vdbg(delta->dev,
+                "%s  %s\n", pctx->name,
+                ipc_open_param_str(params, ctx->str, sizeof(ctx->str)));
+
+       ipc_param.size = sizeof(*params);
+       ipc_param.data = params;
+       ipc_buf_size = sizeof(struct jpeg_decode_params_t) +
+           sizeof(struct jpeg_decode_return_params_t);
+       ret = delta_ipc_open(pctx, "JPEG_DECODER_HW0", &ipc_param,
+                            ipc_buf_size, &ipc_buf, &hdl);
+       if (ret) {
+               dev_err(delta->dev,
+                       "%s  dumping command %s\n", pctx->name,
+                       ipc_open_param_str(params, ctx->str, sizeof(ctx->str)));
+               return ret;
+       }
+
+       ctx->ipc_buf = ipc_buf;
+       ctx->ipc_hdl = hdl;
+
+       return 0;
+}
+
+static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au)
+{
+       struct delta_dev *delta = pctx->dev;
+       struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
+       int ret = 0;
+       struct jpeg_decode_params_t *params = ctx->ipc_buf->vaddr;
+       struct jpeg_decode_return_params_t *status =
+           ctx->ipc_buf->vaddr + sizeof(*params);
+       struct delta_frame *frame;
+       struct delta_ipc_param ipc_param, ipc_status;
+
+       ret = delta_get_free_frame(pctx, &frame);
+       if (ret)
+               return ret;
+
+       memset(params, 0, sizeof(*params));
+
+       params->picture_start_addr_p = (u32)(au->paddr);
+       params->picture_end_addr_p = (u32)(au->paddr + au->size - 1);
+
+       /*
+        * !WARNING!
+        * the NV12 decoded frame is only available
+        * on decimated output when enabling flag
+        * "JPEG_ADDITIONAL_FLAG_420MB"...
+        * the non decimated output gives YUV422SP
+        */
+       params->main_aux_enable = JPEG_DISP_AUX_EN;
+       params->additional_flags = JPEG_ADDITIONAL_FLAG_420MB;
+       params->horizontal_decimation_factor = JPEG_HDEC_1;
+       params->vertical_decimation_factor = JPEG_VDEC_1;
+       params->decoding_mode = JPEG_NORMAL_DECODE;
+
+       params->display_buffer_addr.struct_size =
+           sizeof(struct jpeg_display_buffer_address_t);
+       params->display_buffer_addr.display_decimated_luma_p =
+           (u32)frame->paddr;
+       params->display_buffer_addr.display_decimated_chroma_p =
+           (u32)(frame->paddr
+                 + frame->info.aligned_width * frame->info.aligned_height);
+
+       dev_vdbg(delta->dev,
+                "%s  %s\n", pctx->name,
+                ipc_decode_param_str(params, ctx->str, sizeof(ctx->str)));
+
+       /* status */
+       memset(status, 0, sizeof(*status));
+       status->error_code = JPEG_DECODER_NO_ERROR;
+
+       ipc_param.size = sizeof(*params);
+       ipc_param.data = params;
+       ipc_status.size = sizeof(*status);
+       ipc_status.data = status;
+       ret = delta_ipc_decode(ctx->ipc_hdl, &ipc_param, &ipc_status);
+       if (ret) {
+               dev_err(delta->dev,
+                       "%s  dumping command %s\n", pctx->name,
+                       ipc_decode_param_str(params, ctx->str,
+                                            sizeof(ctx->str)));
+               return ret;
+       }
+
+       pctx->decoded_frames++;
+
+       /* check firmware decoding status */
+       if (delta_mjpeg_check_status(pctx, status)) {
+               dev_err(delta->dev,
+                       "%s  dumping command %s\n", pctx->name,
+                       ipc_decode_param_str(params, ctx->str,
+                                            sizeof(ctx->str)));
+       }
+
+       frame->field = V4L2_FIELD_NONE;
+       frame->flags = V4L2_BUF_FLAG_KEYFRAME;
+       frame->state |= DELTA_FRAME_DEC;
+
+       ctx->out_frame = frame;
+
+       return 0;
+}
+
+static int delta_mjpeg_open(struct delta_ctx *pctx)
+{
+       struct delta_mjpeg_ctx *ctx;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+       pctx->priv = ctx;
+
+       return 0;
+}
+
+static int delta_mjpeg_close(struct delta_ctx *pctx)
+{
+       struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
+
+       if (ctx->ipc_hdl) {
+               delta_ipc_close(ctx->ipc_hdl);
+               ctx->ipc_hdl = NULL;
+       }
+
+       kfree(ctx);
+
+       return 0;
+}
+
+static int delta_mjpeg_get_streaminfo(struct delta_ctx *pctx,
+                                     struct delta_streaminfo *streaminfo)
+{
+       struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
+
+       if (!ctx->header)
+               goto nodata;
+
+       streaminfo->streamformat = V4L2_PIX_FMT_MJPEG;
+       streaminfo->width = ctx->header->frame_width;
+       streaminfo->height = ctx->header->frame_height;
+
+       /* progressive stream */
+       streaminfo->field = V4L2_FIELD_NONE;
+
+       streaminfo->dpb = 1;
+
+       return 0;
+
+nodata:
+       return -ENODATA;
+}
+
+static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau)
+{
+       struct delta_dev *delta = pctx->dev;
+       struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
+       int ret;
+       struct delta_au au = *pau;
+       unsigned int data_offset;
+       struct mjpeg_header *header = &ctx->header_struct;
+
+       if (!ctx->header) {
+               ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
+                                             header, &data_offset);
+               if (ret) {
+                       pctx->stream_errors++;
+                       goto err;
+               }
+               if (header->frame_width * header->frame_height >
+                   DELTA_MJPEG_MAX_RESO) {
+                       dev_err(delta->dev,
+                               "%s  stream resolution too large: %dx%d > %d pixels budget\n",
+                               pctx->name,
+                               header->frame_width,
+                               header->frame_height, DELTA_MJPEG_MAX_RESO);
+                       ret = -EINVAL;
+                       goto err;
+               }
+               ctx->header = header;
+               goto out;
+       }
+
+       if (!ctx->ipc_hdl) {
+               ret = delta_mjpeg_ipc_open(pctx);
+               if (ret)
+                       goto err;
+       }
+
+       ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
+                                     ctx->header, &data_offset);
+       if (ret) {
+               pctx->stream_errors++;
+               goto err;
+       }
+
+       au.paddr += data_offset;
+       au.vaddr += data_offset;
+
+       ret = delta_mjpeg_ipc_decode(pctx, &au);
+       if (ret)
+               goto err;
+
+out:
+       return 0;
+
+err:
+       return ret;
+}
+
+static int delta_mjpeg_get_frame(struct delta_ctx *pctx,
+                                struct delta_frame **frame)
+{
+       struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
+
+       if (!ctx->out_frame)
+               return -ENODATA;
+
+       *frame = ctx->out_frame;
+
+       ctx->out_frame = NULL;
+
+       return 0;
+}
+
+const struct delta_dec mjpegdec = {
+       .name = "MJPEG",
+       .streamformat = V4L2_PIX_FMT_MJPEG,
+       .pixelformat = V4L2_PIX_FMT_NV12,
+       .open = delta_mjpeg_open,
+       .close = delta_mjpeg_close,
+       .get_streaminfo = delta_mjpeg_get_streaminfo,
+       .get_frameinfo = delta_get_frameinfo_default,
+       .decode = delta_mjpeg_decode,
+       .get_frame = delta_mjpeg_get_frame,
+       .recycle = delta_recycle_default,
+};
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-fw.h b/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
new file mode 100644 (file)
index 0000000..de803d0
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_MJPEG_FW_H
+#define DELTA_MJPEG_FW_H
+
+/*
+ * struct jpeg_decoded_buffer_address_t
+ *
+ * defines the addresses where the decoded picture/additional
+ * info related to the block structures will be stored
+ *
+ * @display_luma_p:            address of the luma buffer
+ * @display_chroma_p:          address of the chroma buffer
+ */
+struct jpeg_decoded_buffer_address_t {
+       u32 luma_p;
+       u32 chroma_p;
+};
+
+/*
+ * struct jpeg_display_buffer_address_t
+ *
+ * defines the addresses (used by the Display Reconstruction block)
+ * where the pictures to be displayed will be stored
+ *
+ * @struct_size:               size of the structure in bytes
+ * @display_luma_p:            address of the luma buffer
+ * @display_chroma_p:          address of the chroma buffer
+ * @display_decimated_luma_p:  address of the decimated luma buffer
+ * @display_decimated_chroma_p:        address of the decimated chroma buffer
+ */
+struct jpeg_display_buffer_address_t {
+       u32 struct_size;
+       u32 display_luma_p;
+       u32 display_chroma_p;
+       u32 display_decimated_luma_p;
+       u32 display_decimated_chroma_p;
+};
+
+/*
+ * used for enabling main/aux outputs for both display &
+ * reference reconstruction blocks
+ */
+enum jpeg_rcn_ref_disp_enable_t {
+       /* enable decimated (for display) reconstruction */
+       JPEG_DISP_AUX_EN = 0x00000010,
+       /* enable main (for display) reconstruction */
+       JPEG_DISP_MAIN_EN = 0x00000020,
+       /* enable both main & decimated (for display) reconstruction */
+       JPEG_DISP_AUX_MAIN_EN = 0x00000030,
+       /* enable only reference output(ex. for trick modes) */
+       JPEG_REF_MAIN_EN = 0x00000100,
+       /*
+        * enable reference output with decimated
+        * (for display) reconstruction
+        */
+       JPEG_REF_MAIN_DISP_AUX_EN = 0x00000110,
+       /*
+        * enable reference output with main
+        * (for display) reconstruction
+        */
+       JPEG_REF_MAIN_DISP_MAIN_EN = 0x00000120,
+       /*
+        * enable reference output with main & decimated
+        * (for display) reconstruction
+        */
+       JPEG_REF_MAIN_DISP_MAIN_AUX_EN = 0x00000130
+};
+
+/* identifies the horizontal decimation factor */
+enum jpeg_horizontal_deci_factor_t {
+       /* no resize */
+       JPEG_HDEC_1 = 0x00000000,
+       /* Advanced H/2 resize using improved 8-tap filters */
+       JPEG_HDEC_ADVANCED_2 = 0x00000101,
+       /* Advanced H/4 resize using improved 8-tap filters */
+       JPEG_HDEC_ADVANCED_4 = 0x00000102
+};
+
+/* identifies the vertical decimation factor */
+enum jpeg_vertical_deci_factor_t {
+       /* no resize */
+       JPEG_VDEC_1 = 0x00000000,
+       /* V/2 , progressive resize */
+       JPEG_VDEC_ADVANCED_2_PROG = 0x00000204,
+       /* V/2 , interlaced resize */
+       JPEG_VDEC_ADVANCED_2_INT = 0x000000208
+};
+
+/* status of the decoding process */
+enum jpeg_decoding_error_t {
+       JPEG_DECODER_NO_ERROR = 0,
+       JPEG_DECODER_UNDEFINED_HUFF_TABLE = 1,
+       JPEG_DECODER_UNSUPPORTED_MARKER = 2,
+       JPEG_DECODER_UNABLE_ALLOCATE_MEMORY = 3,
+       JPEG_DECODER_NON_SUPPORTED_SAMP_FACTORS = 4,
+       JPEG_DECODER_BAD_PARAMETER = 5,
+       JPEG_DECODER_DECODE_ERROR = 6,
+       JPEG_DECODER_BAD_RESTART_MARKER = 7,
+       JPEG_DECODER_UNSUPPORTED_COLORSPACE = 8,
+       JPEG_DECODER_BAD_SOS_SPECTRAL = 9,
+       JPEG_DECODER_BAD_SOS_SUCCESSIVE = 10,
+       JPEG_DECODER_BAD_HEADER_LENGTH = 11,
+       JPEG_DECODER_BAD_COUNT_VALUE = 12,
+       JPEG_DECODER_BAD_DHT_MARKER = 13,
+       JPEG_DECODER_BAD_INDEX_VALUE = 14,
+       JPEG_DECODER_BAD_NUMBER_HUFFMAN_TABLES = 15,
+       JPEG_DECODER_BAD_QUANT_TABLE_LENGTH = 16,
+       JPEG_DECODER_BAD_NUMBER_QUANT_TABLES = 17,
+       JPEG_DECODER_BAD_COMPONENT_COUNT = 18,
+       JPEG_DECODER_DIVIDE_BY_ZERO_ERROR = 19,
+       JPEG_DECODER_NOT_JPG_IMAGE = 20,
+       JPEG_DECODER_UNSUPPORTED_ROTATION_ANGLE = 21,
+       JPEG_DECODER_UNSUPPORTED_SCALING = 22,
+       JPEG_DECODER_INSUFFICIENT_OUTPUTBUFFER_SIZE = 23,
+       JPEG_DECODER_BAD_HWCFG_GP_VERSION_VALUE = 24,
+       JPEG_DECODER_BAD_VALUE_FROM_RED = 25,
+       JPEG_DECODER_BAD_SUBREGION_PARAMETERS = 26,
+       JPEG_DECODER_PROGRESSIVE_DECODE_NOT_SUPPORTED = 27,
+       JPEG_DECODER_ERROR_TASK_TIMEOUT = 28,
+       JPEG_DECODER_ERROR_FEATURE_NOT_SUPPORTED = 29
+};
+
+/* identifies the decoding mode */
+enum jpeg_decoding_mode_t {
+       JPEG_NORMAL_DECODE = 0,
+};
+
+enum jpeg_additional_flags_t {
+       JPEG_ADDITIONAL_FLAG_NONE = 0,
+       /* request firmware to return values of the CEH registers */
+       JPEG_ADDITIONAL_FLAG_CEH = 1,
+       /* output storage of auxiliary reconstruction in Raster format. */
+       JPEG_ADDITIONAL_FLAG_RASTER = 64,
+       /* output storage of auxiliary reconstruction in 420MB format. */
+       JPEG_ADDITIONAL_FLAG_420MB = 128
+};
+
+/*
+ * struct jpeg_video_decode_init_params_t - initialization command parameters
+ *
+ * @circular_buffer_begin_addr_p:      start address of fw circular buffer
+ * @circular_buffer_end_addr_p:                end address of fw circular buffer
+ */
+struct jpeg_video_decode_init_params_t {
+       u32 circular_buffer_begin_addr_p;
+       u32 circular_buffer_end_addr_p;
+       u32 reserved;
+};
+
+/*
+ * struct jpeg_decode_params_t - decode command parameters
+ *
+ * @picture_start_addr_p:      start address of jpeg picture
+ * @picture_end_addr_p:                end address of jpeg picture
+ * @decoded_buffer_addr:       decoded picture buffer
+ * @display_buffer_addr:       display picture buffer
+ * @main_aux_enable:           enable main and/or aux outputs
+ * @horizontal_decimation_factor:horizontal decimation factor
+ * @vertical_decimation_factor:        vertical decimation factor
+ * @xvalue0:                   the x(0) coordinate for subregion decoding
+ * @xvalue1:                   the x(1) coordinate for subregion decoding
+ * @yvalue0:                   the y(0) coordinate for subregion decoding
+ * @yvalue1:                   the y(1) coordinate for subregion decoding
+ * @decoding_mode:             decoding mode
+ * @additional_flags:          additional flags
+ * @field_flag:                        determines frame/field scan
+ * @is_jpeg_image:             1 = still jpeg, 0 = motion jpeg
+ */
+struct jpeg_decode_params_t {
+       u32 picture_start_addr_p;
+       u32 picture_end_addr_p;
+       struct jpeg_decoded_buffer_address_t decoded_buffer_addr;
+       struct jpeg_display_buffer_address_t display_buffer_addr;
+       enum jpeg_rcn_ref_disp_enable_t main_aux_enable;
+       enum jpeg_horizontal_deci_factor_t horizontal_decimation_factor;
+       enum jpeg_vertical_deci_factor_t vertical_decimation_factor;
+       u32 xvalue0;
+       u32 xvalue1;
+       u32 yvalue0;
+       u32 yvalue1;
+       enum jpeg_decoding_mode_t decoding_mode;
+       u32 additional_flags;
+       u32 field_flag;
+       u32 reserved;
+       u32 is_jpeg_image;
+};
+
+/*
+ * struct jpeg_decode_return_params_t
+ *
+ * status returned by firmware after decoding
+ *
+ * @decode_time_in_us: decoding time in microseconds
+ * @pm_cycles:         profiling information
+ * @pm_dmiss:          profiling information
+ * @pm_imiss:          profiling information
+ * @pm_bundles:                profiling information
+ * @pm_pft:            profiling information
+ * @error_code:                status of the decoding process
+ * @ceh_registers:     array where values of the Contrast Enhancement
+ *                     Histogram (CEH) registers will be stored.
+ *                     ceh_registers[0] correspond to register MBE_CEH_0_7,
+ *                     ceh_registers[1] correspond to register MBE_CEH_8_15
+ *                     ceh_registers[2] correspond to register MBE_CEH_16_23
+ *                     Note that elements of this array will be updated only
+ *                     if additional_flags has JPEG_ADDITIONAL_FLAG_CEH set.
+ */
+struct jpeg_decode_return_params_t {
+       /* profiling info */
+       u32 decode_time_in_us;
+       u32 pm_cycles;
+       u32 pm_dmiss;
+       u32 pm_imiss;
+       u32 pm_bundles;
+       u32 pm_pft;
+       enum jpeg_decoding_error_t error_code;
+       u32 ceh_registers[32];
+};
+
+#endif /* DELTA_MJPEG_FW_H */
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c b/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
new file mode 100644 (file)
index 0000000..a8fd8fa
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2013
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include "delta.h"
+#include "delta-mjpeg.h"
+
+#define MJPEG_SOF_0  0xc0
+#define MJPEG_SOF_1  0xc1
+#define MJPEG_SOI    0xd8
+#define MJPEG_MARKER 0xff
+
+static char *header_str(struct mjpeg_header *header,
+                       char *str,
+                       unsigned int len)
+{
+       char *cur = str;
+       unsigned int left = len;
+
+       if (!header)
+               return "";
+
+       snprintf(cur, left, "[MJPEG header]\n"
+                       "|- length     = %d\n"
+                       "|- precision  = %d\n"
+                       "|- width      = %d\n"
+                       "|- height     = %d\n"
+                       "|- components = %d\n",
+                       header->length,
+                       header->sample_precision,
+                       header->frame_width,
+                       header->frame_height,
+                       header->nb_of_components);
+
+       return str;
+}
+
+static int delta_mjpeg_read_sof(struct delta_ctx *pctx,
+                               unsigned char *data, unsigned int size,
+                               struct mjpeg_header *header)
+{
+       struct delta_dev *delta = pctx->dev;
+       unsigned int offset = 0;
+
+       if (size < 64)
+               goto err_no_more;
+
+       memset(header, 0, sizeof(*header));
+       header->length           = be16_to_cpu(*(__be16 *)(data + offset));
+       offset += sizeof(u16);
+       header->sample_precision = *(u8 *)(data + offset);
+       offset += sizeof(u8);
+       header->frame_height     = be16_to_cpu(*(__be16 *)(data + offset));
+       offset += sizeof(u16);
+       header->frame_width      = be16_to_cpu(*(__be16 *)(data + offset));
+       offset += sizeof(u16);
+       header->nb_of_components = *(u8 *)(data + offset);
+       offset += sizeof(u8);
+
+       if (header->nb_of_components >= MJPEG_MAX_COMPONENTS) {
+               dev_err(delta->dev,
+                       "%s   unsupported number of components (%d > %d)\n",
+                       pctx->name, header->nb_of_components,
+                       MJPEG_MAX_COMPONENTS);
+               return -EINVAL;
+       }
+
+       if ((offset + header->nb_of_components *
+            sizeof(header->components[0])) > size)
+               goto err_no_more;
+
+       return 0;
+
+err_no_more:
+       dev_err(delta->dev,
+               "%s   sof: reached end of %d size input stream\n",
+               pctx->name, size);
+       return -ENODATA;
+}
+
+int delta_mjpeg_read_header(struct delta_ctx *pctx,
+                           unsigned char *data, unsigned int size,
+                           struct mjpeg_header *header,
+                           unsigned int *data_offset)
+{
+       struct delta_dev *delta = pctx->dev;
+       unsigned char str[200];
+
+       unsigned int ret = 0;
+       unsigned int offset = 0;
+       unsigned int soi = 0;
+
+       if (size < 2)
+               goto err_no_more;
+
+       offset = 0;
+       while (1) {
+               if (data[offset] == MJPEG_MARKER)
+                       switch (data[offset + 1]) {
+                       case MJPEG_SOI:
+                               soi = 1;
+                               *data_offset = offset;
+                               break;
+
+                       case MJPEG_SOF_0:
+                       case MJPEG_SOF_1:
+                               if (!soi) {
+                                       dev_err(delta->dev,
+                                               "%s   wrong sequence, got SOF while SOI not seen\n",
+                                               pctx->name);
+                                       return -EINVAL;
+                               }
+
+                               ret = delta_mjpeg_read_sof(pctx,
+                                                          &data[offset + 2],
+                                                          size - (offset + 2),
+                                                          header);
+                               if (ret)
+                                       goto err;
+
+                               goto done;
+
+                       default:
+                               break;
+                       }
+
+               offset++;
+               if ((offset + 2) >= size)
+                       goto err_no_more;
+       }
+
+done:
+       dev_dbg(delta->dev,
+               "%s   found header @ offset %d:\n%s", pctx->name,
+               *data_offset,
+               header_str(header, str, sizeof(str)));
+       return 0;
+
+err_no_more:
+       dev_err(delta->dev,
+               "%s   no header found within %d bytes input stream\n",
+               pctx->name, size);
+       return -ENODATA;
+
+err:
+       return ret;
+}
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg.h b/drivers/media/platform/sti/delta/delta-mjpeg.h
new file mode 100644 (file)
index 0000000..18e6b37
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2013
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_MJPEG_H
+#define DELTA_MJPEG_H
+
+#include "delta.h"
+
+struct mjpeg_component {
+       unsigned int id;/* 1=Y, 2=Cb, 3=Cr, 4=L, 5=Q */
+       unsigned int h_sampling_factor;
+       unsigned int v_sampling_factor;
+       unsigned int quant_table_index;
+};
+
+#define MJPEG_MAX_COMPONENTS 5
+
+struct mjpeg_header {
+       unsigned int length;
+       unsigned int sample_precision;
+       unsigned int frame_width;
+       unsigned int frame_height;
+       unsigned int nb_of_components;
+       struct mjpeg_component components[MJPEG_MAX_COMPONENTS];
+};
+
+int delta_mjpeg_read_header(struct delta_ctx *pctx,
+                           unsigned char *data, unsigned int size,
+                           struct mjpeg_header *header,
+                           unsigned int *data_offset);
+
+#endif /* DELTA_MJPEG_H */
diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c
new file mode 100644 (file)
index 0000000..c6f2e24
--- /dev/null
@@ -0,0 +1,1993 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Authors: Hugues Fruchet <hugues.fruchet@st.com>
+ *          Jean-Christophe Trotin <jean-christophe.trotin@st.com>
+ *          for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "delta.h"
+#include "delta-debug.h"
+#include "delta-ipc.h"
+
+#define DELTA_NAME     "st-delta"
+
+#define DELTA_PREFIX "[---:----]"
+
+#define to_ctx(__fh) container_of(__fh, struct delta_ctx, fh)
+#define to_au(__vbuf) container_of(__vbuf, struct delta_au, vbuf)
+#define to_frame(__vbuf) container_of(__vbuf, struct delta_frame, vbuf)
+
+#define call_dec_op(dec, op, args...)\
+               ((dec && (dec)->op) ? (dec)->op(args) : 0)
+
+/* registry of available decoders */
+static const struct delta_dec *delta_decoders[] = {
+#ifdef CONFIG_VIDEO_STI_DELTA_MJPEG
+       &mjpegdec,
+#endif
+};
+
+static inline int frame_size(u32 w, u32 h, u32 fmt)
+{
+       switch (fmt) {
+       case V4L2_PIX_FMT_NV12:
+               return (w * h * 3) / 2;
+       default:
+               return 0;
+       }
+}
+
+static inline int frame_stride(u32 w, u32 fmt)
+{
+       switch (fmt) {
+       case V4L2_PIX_FMT_NV12:
+               return w;
+       default:
+               return 0;
+       }
+}
+
+static void dump_au(struct delta_ctx *ctx, struct delta_au *au)
+{
+       struct delta_dev *delta = ctx->dev;
+       u32 size = 10;  /* dump first & last 10 bytes */
+       u8 *data = (u8 *)(au->vaddr);
+
+       if (au->size <= (size * 2))
+               dev_dbg(delta->dev, "%s dump au[%d] dts=%lld size=%d data=%*ph\n",
+                       ctx->name, au->vbuf.vb2_buf.index, au->dts, au->size,
+                       au->size, data);
+       else
+               dev_dbg(delta->dev, "%s dump au[%d] dts=%lld size=%d data=%*ph..%*ph\n",
+                       ctx->name, au->vbuf.vb2_buf.index, au->dts, au->size,
+                       size, data, size, data + au->size - size);
+}
+
+static void dump_frame(struct delta_ctx *ctx, struct delta_frame *frame)
+{
+       struct delta_dev *delta = ctx->dev;
+       u32 size = 10;  /* dump first 10 bytes */
+       u8 *data = (u8 *)(frame->vaddr);
+
+       dev_dbg(delta->dev, "%s dump frame[%d] dts=%lld type=%s field=%s data=%*ph\n",
+               ctx->name, frame->index, frame->dts,
+               frame_type_str(frame->flags),
+               frame_field_str(frame->field),
+               size, data);
+}
+
+static void delta_au_done(struct delta_ctx *ctx, struct delta_au *au, int err)
+{
+       struct vb2_v4l2_buffer *vbuf;
+
+       vbuf = &au->vbuf;
+       vbuf->sequence = ctx->au_num++;
+       v4l2_m2m_buf_done(vbuf, err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+}
+
+static void delta_frame_done(struct delta_ctx *ctx, struct delta_frame *frame,
+                            int err)
+{
+       struct vb2_v4l2_buffer *vbuf;
+
+       dump_frame(ctx, frame);
+
+       /* decoded frame is now output to user */
+       frame->state |= DELTA_FRAME_OUT;
+
+       vbuf = &frame->vbuf;
+       vbuf->sequence = ctx->frame_num++;
+       v4l2_m2m_buf_done(vbuf, err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+
+       if (frame->info.size) /* ignore EOS */
+               ctx->output_frames++;
+}
+
+static void requeue_free_frames(struct delta_ctx *ctx)
+{
+       struct vb2_v4l2_buffer *vbuf;
+       struct delta_frame *frame;
+       unsigned int i;
+
+       /* requeue all free frames */
+       for (i = 0; i < ctx->nb_of_frames; i++) {
+               frame = ctx->frames[i];
+               if (frame->state == DELTA_FRAME_FREE) {
+                       vbuf = &frame->vbuf;
+                       v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+                       frame->state = DELTA_FRAME_M2M;
+               }
+       }
+}
+
+static int delta_recycle(struct delta_ctx *ctx, struct delta_frame *frame)
+{
+       const struct delta_dec *dec = ctx->dec;
+
+       /* recycle frame on decoder side */
+       call_dec_op(dec, recycle, ctx, frame);
+
+       /* this frame is no more output */
+       frame->state &= ~DELTA_FRAME_OUT;
+
+       /* requeue free frame */
+       if (frame->state == DELTA_FRAME_FREE) {
+               struct vb2_v4l2_buffer *vbuf = &frame->vbuf;
+
+               v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+               frame->state = DELTA_FRAME_M2M;
+       }
+
+       /* reset other frame fields */
+       frame->flags = 0;
+       frame->dts = 0;
+
+       return 0;
+}
+
+static void delta_push_dts(struct delta_ctx *ctx, u64 val)
+{
+       struct delta_dts *dts;
+
+       dts = kzalloc(sizeof(*dts), GFP_KERNEL);
+       if (!dts)
+               return;
+
+       INIT_LIST_HEAD(&dts->list);
+
+       /*
+        * protected by global lock acquired
+        * by V4L2 when calling delta_vb2_au_queue
+        */
+       dts->val = val;
+       list_add_tail(&dts->list, &ctx->dts);
+}
+
+static void delta_pop_dts(struct delta_ctx *ctx, u64 *val)
+{
+       struct delta_dev *delta = ctx->dev;
+       struct delta_dts *dts;
+
+       /*
+        * protected by global lock acquired
+        * by V4L2 when calling delta_vb2_au_queue
+        */
+       if (list_empty(&ctx->dts)) {
+               dev_warn(delta->dev, "%s no dts to pop ... output dts = 0\n",
+                        ctx->name);
+               *val = 0;
+               return;
+       }
+
+       dts = list_first_entry(&ctx->dts, struct delta_dts, list);
+       list_del(&dts->list);
+
+       *val = dts->val;
+
+       kfree(dts);
+}
+
+static void delta_flush_dts(struct delta_ctx *ctx)
+{
+       struct delta_dts *dts;
+       struct delta_dts *next;
+
+       /*
+        * protected by global lock acquired
+        * by V4L2 when calling delta_vb2_au_queue
+        */
+
+       /* free all pending dts */
+       list_for_each_entry_safe(dts, next, &ctx->dts, list)
+               kfree(dts);
+
+       /* reset list */
+       INIT_LIST_HEAD(&ctx->dts);
+}
+
+static inline int frame_alignment(u32 fmt)
+{
+       switch (fmt) {
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV21:
+               /* multiple of 2 */
+               return 2;
+       default:
+               return 1;
+       }
+}
+
+static inline int estimated_au_size(u32 w, u32 h)
+{
+       /*
+        * for a MJPEG stream encoded from YUV422 pixel format,
+        * assuming a compression ratio of 2, the maximum size
+        * of an access unit is (width x height x 2) / 2,
+        * so (width x height)
+        */
+       return (w * h);
+}
+
+static void set_default_params(struct delta_ctx *ctx)
+{
+       struct delta_frameinfo *frameinfo = &ctx->frameinfo;
+       struct delta_streaminfo *streaminfo = &ctx->streaminfo;
+
+       memset(frameinfo, 0, sizeof(*frameinfo));
+       frameinfo->pixelformat = V4L2_PIX_FMT_NV12;
+       frameinfo->width = DELTA_DEFAULT_WIDTH;
+       frameinfo->height = DELTA_DEFAULT_HEIGHT;
+       frameinfo->aligned_width = ALIGN(frameinfo->width,
+                                        DELTA_WIDTH_ALIGNMENT);
+       frameinfo->aligned_height = ALIGN(frameinfo->height,
+                                         DELTA_HEIGHT_ALIGNMENT);
+       frameinfo->size = frame_size(frameinfo->aligned_width,
+                                    frameinfo->aligned_height,
+                                    frameinfo->pixelformat);
+       frameinfo->field = V4L2_FIELD_NONE;
+       frameinfo->colorspace = V4L2_COLORSPACE_REC709;
+       frameinfo->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+       frameinfo->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+       frameinfo->quantization = V4L2_QUANTIZATION_DEFAULT;
+
+       memset(streaminfo, 0, sizeof(*streaminfo));
+       streaminfo->streamformat = DELTA_DEFAULT_STREAMFORMAT;
+       streaminfo->width = DELTA_DEFAULT_WIDTH;
+       streaminfo->height = DELTA_DEFAULT_HEIGHT;
+       streaminfo->field = V4L2_FIELD_NONE;
+       streaminfo->colorspace = V4L2_COLORSPACE_REC709;
+       streaminfo->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+       streaminfo->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+       streaminfo->quantization = V4L2_QUANTIZATION_DEFAULT;
+
+       ctx->max_au_size = estimated_au_size(streaminfo->width,
+                                            streaminfo->height);
+}
+
+static const struct delta_dec *delta_find_decoder(struct delta_ctx *ctx,
+                                                 u32 streamformat,
+                                                 u32 pixelformat)
+{
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec;
+       unsigned int i;
+
+       for (i = 0; i < delta->nb_of_decoders; i++) {
+               dec = delta->decoders[i];
+               if ((dec->pixelformat == pixelformat) &&
+                   (dec->streamformat == streamformat))
+                       return dec;
+       }
+
+       return NULL;
+}
+
+static void register_format(u32 format, u32 formats[], u32 *nb_of_formats)
+{
+       u32 i;
+
+       for (i = 0; i < *nb_of_formats; i++) {
+               if (format == formats[i])
+                       return;
+       }
+
+       formats[(*nb_of_formats)++] = format;
+}
+
+static void register_formats(struct delta_dev *delta)
+{
+       unsigned int i;
+
+       for (i = 0; i < delta->nb_of_decoders; i++) {
+               register_format(delta->decoders[i]->pixelformat,
+                               delta->pixelformats,
+                               &delta->nb_of_pixelformats);
+
+               register_format(delta->decoders[i]->streamformat,
+                               delta->streamformats,
+                               &delta->nb_of_streamformats);
+       }
+}
+
+static void register_decoders(struct delta_dev *delta)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(delta_decoders); i++) {
+               if (delta->nb_of_decoders >= DELTA_MAX_DECODERS) {
+                       dev_dbg(delta->dev,
+                               "%s failed to register %s decoder (%d maximum reached)\n",
+                               DELTA_PREFIX, delta_decoders[i]->name,
+                               DELTA_MAX_DECODERS);
+                       return;
+               }
+
+               delta->decoders[delta->nb_of_decoders++] = delta_decoders[i];
+               dev_info(delta->dev, "%s %s decoder registered\n",
+                        DELTA_PREFIX, delta_decoders[i]->name);
+       }
+}
+
+static void delta_lock(void *priv)
+{
+       struct delta_ctx *ctx = priv;
+       struct delta_dev *delta = ctx->dev;
+
+       mutex_lock(&delta->lock);
+}
+
+static void delta_unlock(void *priv)
+{
+       struct delta_ctx *ctx = priv;
+       struct delta_dev *delta = ctx->dev;
+
+       mutex_unlock(&delta->lock);
+}
+
+static int delta_open_decoder(struct delta_ctx *ctx, u32 streamformat,
+                             u32 pixelformat, const struct delta_dec **pdec)
+{
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec;
+       int ret;
+
+       dec = delta_find_decoder(ctx, streamformat, ctx->frameinfo.pixelformat);
+       if (!dec) {
+               dev_err(delta->dev, "%s no decoder found matching %4.4s => %4.4s\n",
+                       ctx->name, (char *)&streamformat, (char *)&pixelformat);
+               return -EINVAL;
+       }
+
+       dev_dbg(delta->dev, "%s one decoder matching %4.4s => %4.4s\n",
+               ctx->name, (char *)&streamformat, (char *)&pixelformat);
+
+       /* update instance name */
+       snprintf(ctx->name, sizeof(ctx->name), "[%3d:%4.4s]",
+                delta->instance_id, (char *)&streamformat);
+
+       /* open decoder instance */
+       ret = call_dec_op(dec, open, ctx);
+       if (ret) {
+               dev_err(delta->dev, "%s failed to open decoder instance (%d)\n",
+                       ctx->name, ret);
+               return ret;
+       }
+
+       dev_dbg(delta->dev, "%s %s decoder opened\n", ctx->name, dec->name);
+
+       *pdec = dec;
+
+       return ret;
+}
+
+/*
+ * V4L2 ioctl operations
+ */
+
+static int delta_querycap(struct file *file, void *priv,
+                         struct v4l2_capability *cap)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+
+       strlcpy(cap->driver, DELTA_NAME, sizeof(cap->driver));
+       strlcpy(cap->card, delta->vdev->name, sizeof(cap->card));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+                delta->pdev->name);
+
+       return 0;
+}
+
+static int delta_enum_fmt_stream(struct file *file, void *priv,
+                                struct v4l2_fmtdesc *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+
+       if (unlikely(f->index >= delta->nb_of_streamformats))
+               return -EINVAL;
+
+       f->pixelformat = delta->streamformats[f->index];
+
+       return 0;
+}
+
+static int delta_enum_fmt_frame(struct file *file, void *priv,
+                               struct v4l2_fmtdesc *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+
+       if (unlikely(f->index >= delta->nb_of_pixelformats))
+               return -EINVAL;
+
+       f->pixelformat = delta->pixelformats[f->index];
+
+       return 0;
+}
+
+static int delta_g_fmt_stream(struct file *file, void *fh,
+                             struct v4l2_format *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct delta_streaminfo *streaminfo = &ctx->streaminfo;
+       unsigned char str[100] = "";
+
+       if (!(ctx->flags & DELTA_FLAG_STREAMINFO))
+               dev_dbg(delta->dev,
+                       "%s V4L2 GET_FMT (OUTPUT): no stream information available, default to %s\n",
+                       ctx->name,
+                       delta_streaminfo_str(streaminfo, str, sizeof(str)));
+
+       pix->pixelformat = streaminfo->streamformat;
+       pix->width = streaminfo->width;
+       pix->height = streaminfo->height;
+       pix->field = streaminfo->field;
+       pix->bytesperline = 0;
+       pix->sizeimage = ctx->max_au_size;
+       pix->colorspace = streaminfo->colorspace;
+       pix->xfer_func = streaminfo->xfer_func;
+       pix->ycbcr_enc = streaminfo->ycbcr_enc;
+       pix->quantization = streaminfo->quantization;
+
+       return 0;
+}
+
+static int delta_g_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct delta_frameinfo *frameinfo = &ctx->frameinfo;
+       struct delta_streaminfo *streaminfo = &ctx->streaminfo;
+       unsigned char str[100] = "";
+
+       if (!(ctx->flags & DELTA_FLAG_FRAMEINFO))
+               dev_dbg(delta->dev,
+                       "%s V4L2 GET_FMT (CAPTURE): no frame information available, default to %s\n",
+                       ctx->name,
+                       delta_frameinfo_str(frameinfo, str, sizeof(str)));
+
+       pix->pixelformat = frameinfo->pixelformat;
+       pix->width = frameinfo->aligned_width;
+       pix->height = frameinfo->aligned_height;
+       pix->field = frameinfo->field;
+       pix->bytesperline = frame_stride(frameinfo->aligned_width,
+                                              frameinfo->pixelformat);
+       pix->sizeimage = frameinfo->size;
+
+       if (ctx->flags & DELTA_FLAG_STREAMINFO) {
+               /* align colorspace & friends on stream ones if any set */
+               frameinfo->colorspace = streaminfo->colorspace;
+               frameinfo->xfer_func = streaminfo->xfer_func;
+               frameinfo->ycbcr_enc = streaminfo->ycbcr_enc;
+               frameinfo->quantization = streaminfo->quantization;
+       }
+       pix->colorspace = frameinfo->colorspace;
+       pix->xfer_func = frameinfo->xfer_func;
+       pix->ycbcr_enc = frameinfo->ycbcr_enc;
+       pix->quantization = frameinfo->quantization;
+
+       return 0;
+}
+
+static int delta_try_fmt_stream(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       u32 streamformat = pix->pixelformat;
+       const struct delta_dec *dec;
+       u32 width, height;
+       u32 au_size;
+
+       dec = delta_find_decoder(ctx, streamformat, ctx->frameinfo.pixelformat);
+       if (!dec) {
+               dev_dbg(delta->dev,
+                       "%s V4L2 TRY_FMT (OUTPUT): unsupported format %4.4s\n",
+                       ctx->name, (char *)&pix->pixelformat);
+               return -EINVAL;
+       }
+
+       /* adjust width & height */
+       width = pix->width;
+       height = pix->height;
+       v4l_bound_align_image
+               (&pix->width,
+                DELTA_MIN_WIDTH,
+                dec->max_width ? dec->max_width : DELTA_MAX_WIDTH,
+                0,
+                &pix->height,
+                DELTA_MIN_HEIGHT,
+                dec->max_height ? dec->max_height : DELTA_MAX_HEIGHT,
+                0, 0);
+
+       if ((pix->width != width) || (pix->height != height))
+               dev_dbg(delta->dev,
+                       "%s V4L2 TRY_FMT (OUTPUT): resolution updated %dx%d -> %dx%d to fit min/max/alignment\n",
+                       ctx->name, width, height,
+                       pix->width, pix->height);
+
+       au_size = estimated_au_size(pix->width, pix->height);
+       if (pix->sizeimage < au_size) {
+               dev_dbg(delta->dev,
+                       "%s V4L2 TRY_FMT (OUTPUT): size updated %d -> %d to fit estimated size\n",
+                       ctx->name, pix->sizeimage, au_size);
+               pix->sizeimage = au_size;
+       }
+
+       pix->bytesperline = 0;
+
+       if (pix->field == V4L2_FIELD_ANY)
+               pix->field = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int delta_try_fmt_frame(struct file *file, void *priv,
+                              struct v4l2_format *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       u32 pixelformat = pix->pixelformat;
+       const struct delta_dec *dec;
+       u32 width, height;
+
+       dec = delta_find_decoder(ctx, ctx->streaminfo.streamformat,
+                                pixelformat);
+       if (!dec) {
+               dev_dbg(delta->dev,
+                       "%s V4L2 TRY_FMT (CAPTURE): unsupported format %4.4s\n",
+                       ctx->name, (char *)&pixelformat);
+               return -EINVAL;
+       }
+
+       /* adjust width & height */
+       width = pix->width;
+       height = pix->height;
+       v4l_bound_align_image(&pix->width,
+                             DELTA_MIN_WIDTH, DELTA_MAX_WIDTH,
+                             frame_alignment(pixelformat) - 1,
+                             &pix->height,
+                             DELTA_MIN_HEIGHT, DELTA_MAX_HEIGHT,
+                             frame_alignment(pixelformat) - 1, 0);
+
+       if ((pix->width != width) || (pix->height != height))
+               dev_dbg(delta->dev,
+                       "%s V4L2 TRY_FMT (CAPTURE): resolution updated %dx%d -> %dx%d to fit min/max/alignment\n",
+                       ctx->name, width, height, pix->width, pix->height);
+
+       /* default decoder alignment constraint */
+       width = ALIGN(pix->width, DELTA_WIDTH_ALIGNMENT);
+       height = ALIGN(pix->height, DELTA_HEIGHT_ALIGNMENT);
+       if ((pix->width != width) || (pix->height != height))
+               dev_dbg(delta->dev,
+                       "%s V4L2 TRY_FMT (CAPTURE): resolution updated %dx%d -> %dx%d to fit decoder alignment\n",
+                       ctx->name, width, height, pix->width, pix->height);
+
+       if (!pix->colorspace) {
+               pix->colorspace = V4L2_COLORSPACE_REC709;
+               pix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+               pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+               pix->quantization = V4L2_QUANTIZATION_DEFAULT;
+       }
+
+       pix->width = width;
+       pix->height = height;
+       pix->bytesperline = frame_stride(pix->width, pixelformat);
+       pix->sizeimage = frame_size(pix->width, pix->height, pixelformat);
+
+       if (pix->field == V4L2_FIELD_ANY)
+               pix->field = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int delta_s_fmt_stream(struct file *file, void *fh,
+                             struct v4l2_format *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       struct vb2_queue *vq;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       int ret;
+
+       ret = delta_try_fmt_stream(file, fh, f);
+       if (ret) {
+               dev_dbg(delta->dev,
+                       "%s V4L2 S_FMT (OUTPUT): unsupported format %4.4s\n",
+                       ctx->name, (char *)&pix->pixelformat);
+               return ret;
+       }
+
+       vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+       if (vb2_is_streaming(vq)) {
+               dev_dbg(delta->dev, "%s V4L2 S_FMT (OUTPUT): queue busy\n",
+                       ctx->name);
+               return -EBUSY;
+       }
+
+       ctx->max_au_size = pix->sizeimage;
+       ctx->streaminfo.width = pix->width;
+       ctx->streaminfo.height = pix->height;
+       ctx->streaminfo.streamformat = pix->pixelformat;
+       ctx->streaminfo.colorspace = pix->colorspace;
+       ctx->streaminfo.xfer_func = pix->xfer_func;
+       ctx->streaminfo.ycbcr_enc = pix->ycbcr_enc;
+       ctx->streaminfo.quantization = pix->quantization;
+       ctx->flags |= DELTA_FLAG_STREAMINFO;
+
+       return 0;
+}
+
+static int delta_s_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec = ctx->dec;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct delta_frameinfo frameinfo;
+       unsigned char str[100] = "";
+       struct vb2_queue *vq;
+       int ret;
+
+       vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+       if (vb2_is_streaming(vq)) {
+               dev_dbg(delta->dev, "%s V4L2 S_FMT (CAPTURE): queue busy\n",
+                       ctx->name);
+               return -EBUSY;
+       }
+
+       if (ctx->state < DELTA_STATE_READY) {
+               /*
+                * decoder not yet opened and valid stream header not found,
+                * could not negotiate format with decoder, check at least
+                * pixel format & negotiate resolution boundaries
+                * and alignment...
+                */
+               ret = delta_try_fmt_frame(file, fh, f);
+               if (ret) {
+                       dev_dbg(delta->dev,
+                               "%s V4L2 S_FMT (CAPTURE): unsupported format %4.4s\n",
+                               ctx->name, (char *)&pix->pixelformat);
+                       return ret;
+               }
+
+               return 0;
+       }
+
+       /* set frame information to decoder */
+       memset(&frameinfo, 0, sizeof(frameinfo));
+       frameinfo.pixelformat = pix->pixelformat;
+       frameinfo.width = pix->width;
+       frameinfo.height = pix->height;
+       frameinfo.aligned_width = pix->width;
+       frameinfo.aligned_height = pix->height;
+       frameinfo.size = pix->sizeimage;
+       frameinfo.field = pix->field;
+       frameinfo.colorspace = pix->colorspace;
+       frameinfo.xfer_func = pix->xfer_func;
+       frameinfo.ycbcr_enc = pix->ycbcr_enc;
+       frameinfo.quantization = pix->quantization;
+       ret = call_dec_op(dec, set_frameinfo, ctx, &frameinfo);
+       if (ret)
+               return ret;
+
+       /* then get what decoder can really do */
+       ret = call_dec_op(dec, get_frameinfo, ctx, &frameinfo);
+       if (ret)
+               return ret;
+
+       ctx->flags |= DELTA_FLAG_FRAMEINFO;
+       ctx->frameinfo = frameinfo;
+       dev_dbg(delta->dev,
+               "%s V4L2 SET_FMT (CAPTURE): frameinfo updated to %s\n",
+               ctx->name,
+               delta_frameinfo_str(&frameinfo, str, sizeof(str)));
+
+       pix->pixelformat = frameinfo.pixelformat;
+       pix->width = frameinfo.aligned_width;
+       pix->height = frameinfo.aligned_height;
+       pix->bytesperline = frame_stride(pix->width, pix->pixelformat);
+       pix->sizeimage = frameinfo.size;
+       pix->field = frameinfo.field;
+       pix->colorspace = frameinfo.colorspace;
+       pix->xfer_func = frameinfo.xfer_func;
+       pix->ycbcr_enc = frameinfo.ycbcr_enc;
+       pix->quantization = frameinfo.quantization;
+
+       return 0;
+}
+
+static int delta_g_selection(struct file *file, void *fh,
+                            struct v4l2_selection *s)
+{
+       struct delta_ctx *ctx = to_ctx(fh);
+       struct delta_frameinfo *frameinfo = &ctx->frameinfo;
+       struct v4l2_rect crop;
+
+       if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if ((ctx->flags & DELTA_FLAG_FRAMEINFO) &&
+           (frameinfo->flags & DELTA_FRAMEINFO_FLAG_CROP)) {
+               crop = frameinfo->crop;
+       } else {
+               /* default to video dimensions */
+               crop.left = 0;
+               crop.top = 0;
+               crop.width = frameinfo->width;
+               crop.height = frameinfo->height;
+       }
+
+       switch (s->target) {
+       case V4L2_SEL_TGT_COMPOSE:
+       case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+               /* visible area inside video */
+               s->r = crop;
+               break;
+       case V4L2_SEL_TGT_COMPOSE_PADDED:
+       case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+               /* up to aligned dimensions */
+               s->r.left = 0;
+               s->r.top = 0;
+               s->r.width = frameinfo->aligned_width;
+               s->r.height = frameinfo->aligned_height;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void delta_complete_eos(struct delta_ctx *ctx,
+                              struct delta_frame *frame)
+{
+       struct delta_dev *delta = ctx->dev;
+       const struct v4l2_event ev = {.type = V4L2_EVENT_EOS};
+
+       /*
+        * Send EOS to user:
+        * - by returning an empty frame flagged to V4L2_BUF_FLAG_LAST
+        * - and then send EOS event
+        */
+
+       /* empty frame */
+       frame->info.size = 0;
+
+       /* set the last buffer flag */
+       frame->flags |= V4L2_BUF_FLAG_LAST;
+
+       /* release frame to user */
+       delta_frame_done(ctx, frame, 0);
+
+       /* send EOS event */
+       v4l2_event_queue_fh(&ctx->fh, &ev);
+
+       dev_dbg(delta->dev, "%s EOS completed\n", ctx->name);
+}
+
+static int delta_try_decoder_cmd(struct file *file, void *fh,
+                                struct v4l2_decoder_cmd *cmd)
+{
+       if (cmd->cmd != V4L2_DEC_CMD_STOP)
+               return -EINVAL;
+
+       if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
+               return -EINVAL;
+
+       if (!(cmd->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) &&
+           (cmd->stop.pts != 0))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int delta_decoder_stop_cmd(struct delta_ctx *ctx, void *fh)
+{
+       const struct delta_dec *dec = ctx->dec;
+       struct delta_dev *delta = ctx->dev;
+       struct delta_frame *frame = NULL;
+       int ret = 0;
+
+       dev_dbg(delta->dev, "%s EOS received\n", ctx->name);
+
+       if (ctx->state != DELTA_STATE_READY)
+               return 0;
+
+       /* drain the decoder */
+       call_dec_op(dec, drain, ctx);
+
+       /* release to user drained frames */
+       while (1) {
+               frame = NULL;
+               ret = call_dec_op(dec, get_frame, ctx, &frame);
+               if (ret == -ENODATA) {
+                       /* no more decoded frames */
+                       break;
+               }
+               if (frame) {
+                       dev_dbg(delta->dev, "%s drain frame[%d]\n",
+                               ctx->name, frame->index);
+
+                       /* pop timestamp and mark frame with it */
+                       delta_pop_dts(ctx, &frame->dts);
+
+                       /* release decoded frame to user */
+                       delta_frame_done(ctx, frame, 0);
+               }
+       }
+
+       /* try to complete EOS */
+       ret = delta_get_free_frame(ctx, &frame);
+       if (ret)
+               goto delay_eos;
+
+       /* new frame available, EOS can now be completed */
+       delta_complete_eos(ctx, frame);
+
+       ctx->state = DELTA_STATE_EOS;
+
+       return 0;
+
+delay_eos:
+       /*
+        * EOS completion from driver is delayed because
+        * we don't have a free empty frame available.
+        * EOS completion is so delayed till next frame_queue() call
+        * to be sure to have a free empty frame available.
+        */
+       ctx->state = DELTA_STATE_WF_EOS;
+       dev_dbg(delta->dev, "%s EOS delayed\n", ctx->name);
+
+       return 0;
+}
+
+static int delta_decoder_cmd(struct file *file, void *fh,
+                            struct v4l2_decoder_cmd *cmd)
+{
+       struct delta_ctx *ctx = to_ctx(fh);
+       int ret = 0;
+
+       ret = delta_try_decoder_cmd(file, fh, cmd);
+       if (ret)
+               return ret;
+
+       return delta_decoder_stop_cmd(ctx, fh);
+}
+
+static int delta_subscribe_event(struct v4l2_fh *fh,
+                                const struct v4l2_event_subscription *sub)
+{
+       switch (sub->type) {
+       case V4L2_EVENT_EOS:
+               return v4l2_event_subscribe(fh, sub, 2, NULL);
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* v4l2 ioctl ops */
+static const struct v4l2_ioctl_ops delta_ioctl_ops = {
+       .vidioc_querycap = delta_querycap,
+       .vidioc_enum_fmt_vid_cap = delta_enum_fmt_frame,
+       .vidioc_g_fmt_vid_cap = delta_g_fmt_frame,
+       .vidioc_try_fmt_vid_cap = delta_try_fmt_frame,
+       .vidioc_s_fmt_vid_cap = delta_s_fmt_frame,
+       .vidioc_enum_fmt_vid_out = delta_enum_fmt_stream,
+       .vidioc_g_fmt_vid_out = delta_g_fmt_stream,
+       .vidioc_try_fmt_vid_out = delta_try_fmt_stream,
+       .vidioc_s_fmt_vid_out = delta_s_fmt_stream,
+       .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+       .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+       .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+       .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+       .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+       .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+       .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+       .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+       .vidioc_g_selection = delta_g_selection,
+       .vidioc_try_decoder_cmd = delta_try_decoder_cmd,
+       .vidioc_decoder_cmd = delta_decoder_cmd,
+       .vidioc_subscribe_event = delta_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+/*
+ * mem-to-mem operations
+ */
+
+static void delta_run_work(struct work_struct *work)
+{
+       struct delta_ctx *ctx = container_of(work, struct delta_ctx, run_work);
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec = ctx->dec;
+       struct delta_au *au;
+       struct delta_frame *frame = NULL;
+       int ret = 0;
+       bool discard = false;
+       struct vb2_v4l2_buffer *vbuf;
+
+       if (!dec) {
+               dev_err(delta->dev, "%s no decoder opened yet\n", ctx->name);
+               return;
+       }
+
+       /* protect instance against reentrancy */
+       mutex_lock(&ctx->lock);
+
+       vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+       if (!vbuf) {
+               dev_err(delta->dev, "%s no buffer to decode\n", ctx->name);
+               mutex_unlock(&ctx->lock);
+               return;
+       }
+       au = to_au(vbuf);
+       au->size = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
+       au->dts = vbuf->vb2_buf.timestamp;
+
+       /* dump access unit */
+       dump_au(ctx, au);
+
+       /* enable the hardware */
+       if (!dec->pm) {
+               ret = delta_get_sync(ctx);
+               if (ret)
+                       goto err;
+       }
+
+       /* decode this access unit */
+       ret = call_dec_op(dec, decode, ctx, au);
+
+       /*
+        * if the (-ENODATA) value is returned, it refers to the interlaced
+        * stream case for which 2 access units are needed to get 1 frame.
+        * So, this returned value doesn't mean that the decoding fails, but
+        * indicates that the timestamp information of the access unit shall
+        * not be taken into account, and that the V4L2 buffer associated with
+        * the access unit shall be flagged with V4L2_BUF_FLAG_ERROR to inform
+        * the user of this situation
+        */
+       if (ret == -ENODATA) {
+               discard = true;
+       } else if (ret) {
+               dev_err(delta->dev, "%s decoding failed (%d)\n",
+                       ctx->name, ret);
+
+               /* disable the hardware */
+               if (!dec->pm)
+                       delta_put_autosuspend(ctx);
+
+               goto err;
+       }
+
+       /* disable the hardware */
+       if (!dec->pm)
+               delta_put_autosuspend(ctx);
+
+       /* push au timestamp in FIFO */
+       if (!discard)
+               delta_push_dts(ctx, au->dts);
+
+       /* get available decoded frames */
+       while (1) {
+               ret = call_dec_op(dec, get_frame, ctx, &frame);
+               if (ret == -ENODATA) {
+                       /* no more decoded frames */
+                       goto out;
+               }
+               if (ret) {
+                       dev_err(delta->dev, "%s  cannot get decoded frame (%d)\n",
+                               ctx->name, ret);
+                       goto out;
+               }
+               if (!frame) {
+                       dev_err(delta->dev,
+                               "%s  NULL decoded frame\n",
+                               ctx->name);
+                       ret = -EIO;
+                       goto out;
+               }
+
+               /* pop timestamp and mark frame with it */
+               delta_pop_dts(ctx, &frame->dts);
+
+               /* release decoded frame to user */
+               delta_frame_done(ctx, frame, 0);
+       }
+
+out:
+       requeue_free_frames(ctx);
+       delta_au_done(ctx, au, (discard ? -ENODATA : 0));
+       mutex_unlock(&ctx->lock);
+       v4l2_m2m_job_finish(delta->m2m_dev, ctx->fh.m2m_ctx);
+       return;
+
+err:
+       requeue_free_frames(ctx);
+       delta_au_done(ctx, au, ret);
+       mutex_unlock(&ctx->lock);
+       v4l2_m2m_job_finish(delta->m2m_dev, ctx->fh.m2m_ctx);
+}
+
+static void delta_device_run(void *priv)
+{
+       struct delta_ctx *ctx = priv;
+       struct delta_dev *delta = ctx->dev;
+
+       queue_work(delta->work_queue, &ctx->run_work);
+}
+
+static void delta_job_abort(void *priv)
+{
+       struct delta_ctx *ctx = priv;
+       struct delta_dev *delta = ctx->dev;
+
+       dev_dbg(delta->dev, "%s aborting job\n", ctx->name);
+
+       ctx->aborting = true;
+}
+
+static int delta_job_ready(void *priv)
+{
+       struct delta_ctx *ctx = priv;
+       struct delta_dev *delta = ctx->dev;
+       int src_bufs = v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx);
+
+       if (!src_bufs) {
+               dev_dbg(delta->dev, "%s not ready: not enough video buffers.\n",
+                       ctx->name);
+               return 0;
+       }
+
+       if (!v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) {
+               dev_dbg(delta->dev, "%s not ready: not enough video capture buffers.\n",
+                       ctx->name);
+               return 0;
+       }
+
+       if (ctx->aborting) {
+               dev_dbg(delta->dev, "%s job not ready: aborting\n", ctx->name);
+               return 0;
+       }
+
+       dev_dbg(delta->dev, "%s job ready\n", ctx->name);
+
+       return 1;
+}
+
+/* mem-to-mem ops */
+static struct v4l2_m2m_ops delta_m2m_ops = {
+       .device_run     = delta_device_run,
+       .job_ready      = delta_job_ready,
+       .job_abort      = delta_job_abort,
+       .lock           = delta_lock,
+       .unlock         = delta_unlock,
+};
+
+/*
+ * VB2 queue operations
+ */
+
+static int delta_vb2_au_queue_setup(struct vb2_queue *vq,
+                                   unsigned int *num_buffers,
+                                   unsigned int *num_planes,
+                                   unsigned int sizes[],
+                                   struct device *alloc_devs[])
+{
+       struct delta_ctx *ctx = vb2_get_drv_priv(vq);
+       unsigned int size = ctx->max_au_size;
+
+       if (*num_planes)
+               return sizes[0] < size ? -EINVAL : 0;
+
+       *num_planes = 1;
+       if (*num_buffers < 1)
+               *num_buffers = 1;
+       if (*num_buffers > DELTA_MAX_AUS)
+               *num_buffers = DELTA_MAX_AUS;
+
+       sizes[0] = size;
+
+       return 0;
+}
+
+static int delta_vb2_au_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct delta_dev *delta = ctx->dev;
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct delta_au *au = to_au(vbuf);
+
+       if (!au->prepared) {
+               /* get memory addresses */
+               au->vaddr = vb2_plane_vaddr(&au->vbuf.vb2_buf, 0);
+               au->paddr = vb2_dma_contig_plane_dma_addr
+                               (&au->vbuf.vb2_buf, 0);
+               au->prepared = true;
+               dev_dbg(delta->dev, "%s au[%d] prepared; virt=0x%p, phy=0x%pad\n",
+                       ctx->name, vb->index, au->vaddr, &au->paddr);
+       }
+
+       if (vbuf->field == V4L2_FIELD_ANY)
+               vbuf->field = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int delta_setup_frame(struct delta_ctx *ctx,
+                            struct delta_frame *frame)
+{
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec = ctx->dec;
+
+       if (frame->index >= DELTA_MAX_FRAMES) {
+               dev_err(delta->dev,
+                       "%s frame index=%d exceeds output frame count (%d)\n",
+                       ctx->name, frame->index, DELTA_MAX_FRAMES);
+               return -EINVAL;
+       }
+
+       if (ctx->nb_of_frames >= DELTA_MAX_FRAMES) {
+               dev_err(delta->dev,
+                       "%s number of frames exceeds output frame count (%d > %d)\n",
+                       ctx->name, ctx->nb_of_frames, DELTA_MAX_FRAMES);
+               return -EINVAL;
+       }
+
+       if (frame->index != ctx->nb_of_frames) {
+               dev_warn(delta->dev,
+                        "%s frame index discontinuity detected, expected %d, got %d\n",
+                        ctx->name, ctx->nb_of_frames, frame->index);
+       }
+
+       frame->state = DELTA_FRAME_FREE;
+       ctx->frames[ctx->nb_of_frames] = frame;
+       ctx->nb_of_frames++;
+
+       /* setup frame on decoder side */
+       return call_dec_op(dec, setup_frame, ctx, frame);
+}
+
+/*
+ * default implementation of get_frameinfo decoder ops
+ * matching frame information from stream information
+ * & with default pixel format & default alignment.
+ */
+int delta_get_frameinfo_default(struct delta_ctx *ctx,
+                               struct delta_frameinfo *frameinfo)
+{
+       struct delta_streaminfo *streaminfo = &ctx->streaminfo;
+
+       memset(frameinfo, 0, sizeof(*frameinfo));
+       frameinfo->pixelformat = V4L2_PIX_FMT_NV12;
+       frameinfo->width = streaminfo->width;
+       frameinfo->height = streaminfo->height;
+       frameinfo->aligned_width = ALIGN(streaminfo->width,
+                                        DELTA_WIDTH_ALIGNMENT);
+       frameinfo->aligned_height = ALIGN(streaminfo->height,
+                                         DELTA_HEIGHT_ALIGNMENT);
+       frameinfo->size = frame_size(frameinfo->aligned_width,
+                                    frameinfo->aligned_height,
+                                    frameinfo->pixelformat);
+       if (streaminfo->flags & DELTA_STREAMINFO_FLAG_CROP) {
+               frameinfo->flags |= DELTA_FRAMEINFO_FLAG_CROP;
+               frameinfo->crop = streaminfo->crop;
+       }
+       if (streaminfo->flags & DELTA_STREAMINFO_FLAG_PIXELASPECT) {
+               frameinfo->flags |= DELTA_FRAMEINFO_FLAG_PIXELASPECT;
+               frameinfo->pixelaspect = streaminfo->pixelaspect;
+       }
+       frameinfo->field = streaminfo->field;
+
+       return 0;
+}
+
+/*
+ * default implementation of recycle decoder ops
+ * consisting to relax the "decoded" frame state
+ */
+int delta_recycle_default(struct delta_ctx *pctx,
+                         struct delta_frame *frame)
+{
+       frame->state &= ~DELTA_FRAME_DEC;
+
+       return 0;
+}
+
+static void dump_frames_status(struct delta_ctx *ctx)
+{
+       struct delta_dev *delta = ctx->dev;
+       unsigned int i;
+       struct delta_frame *frame;
+       unsigned char str[100] = "";
+
+       dev_info(delta->dev,
+                "%s dumping frames status...\n", ctx->name);
+
+       for (i = 0; i < ctx->nb_of_frames; i++) {
+               frame = ctx->frames[i];
+               dev_info(delta->dev,
+                        "%s frame[%d] %s\n",
+                        ctx->name, frame->index,
+                        frame_state_str(frame->state,
+                                        str, sizeof(str)));
+       }
+}
+
+int delta_get_free_frame(struct delta_ctx *ctx,
+                        struct delta_frame **pframe)
+{
+       struct delta_dev *delta = ctx->dev;
+       struct vb2_v4l2_buffer *vbuf;
+       struct delta_frame *frame;
+
+       *pframe = NULL;
+
+       vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+       if (!vbuf) {
+               dev_err(delta->dev, "%s no frame available",
+                       ctx->name);
+               return -EIO;
+       }
+
+       frame = to_frame(vbuf);
+       frame->state &= ~DELTA_FRAME_M2M;
+       if (frame->state != DELTA_FRAME_FREE) {
+               dev_err(delta->dev,
+                       "%s frame[%d] is not free\n",
+                       ctx->name, frame->index);
+               dump_frames_status(ctx);
+               return -ENODATA;
+       }
+
+       dev_dbg(delta->dev,
+               "%s get free frame[%d]\n", ctx->name, frame->index);
+
+       *pframe = frame;
+       return 0;
+}
+
+int delta_get_sync(struct delta_ctx *ctx)
+{
+       struct delta_dev *delta = ctx->dev;
+       int ret = 0;
+
+       /* enable the hardware */
+       ret = pm_runtime_get_sync(delta->dev);
+       if (ret < 0) {
+               dev_err(delta->dev, "%s pm_runtime_get_sync failed (%d)\n",
+                       __func__, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+void delta_put_autosuspend(struct delta_ctx *ctx)
+{
+       struct delta_dev *delta = ctx->dev;
+
+       pm_runtime_put_autosuspend(delta->dev);
+}
+
+static void delta_vb2_au_queue(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+       v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static int delta_vb2_au_start_streaming(struct vb2_queue *q,
+                                       unsigned int count)
+{
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec = ctx->dec;
+       struct delta_au *au;
+       int ret = 0;
+       struct vb2_v4l2_buffer *vbuf = NULL;
+       struct delta_streaminfo *streaminfo = &ctx->streaminfo;
+       struct delta_frameinfo *frameinfo = &ctx->frameinfo;
+       unsigned char str1[100] = "";
+       unsigned char str2[100] = "";
+
+       if ((ctx->state != DELTA_STATE_WF_FORMAT) &&
+           (ctx->state != DELTA_STATE_WF_STREAMINFO))
+               return 0;
+
+       if (ctx->state == DELTA_STATE_WF_FORMAT) {
+               /* open decoder if not yet done */
+               ret = delta_open_decoder(ctx,
+                                        ctx->streaminfo.streamformat,
+                                        ctx->frameinfo.pixelformat, &dec);
+               if (ret)
+                       goto err;
+               ctx->dec = dec;
+               ctx->state = DELTA_STATE_WF_STREAMINFO;
+       }
+
+       /*
+        * first buffer should contain stream header,
+        * decode it to get the infos related to stream
+        * such as width, height, dpb, ...
+        */
+       vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+       if (!vbuf) {
+               dev_err(delta->dev, "%s failed to start streaming, no stream header buffer enqueued\n",
+                       ctx->name);
+               ret = -EINVAL;
+               goto err;
+       }
+       au = to_au(vbuf);
+       au->size = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
+       au->dts = vbuf->vb2_buf.timestamp;
+
+       delta_push_dts(ctx, au->dts);
+
+       /* dump access unit */
+       dump_au(ctx, au);
+
+       /* decode this access unit */
+       ret = call_dec_op(dec, decode, ctx, au);
+       if (ret) {
+               dev_err(delta->dev, "%s failed to start streaming, header decoding failed (%d)\n",
+                       ctx->name, ret);
+               goto err;
+       }
+
+       ret = call_dec_op(dec, get_streaminfo, ctx, streaminfo);
+       if (ret) {
+               dev_dbg_ratelimited(delta->dev,
+                                   "%s failed to start streaming, valid stream header not yet decoded\n",
+                                   ctx->name);
+               goto err;
+       }
+       ctx->flags |= DELTA_FLAG_STREAMINFO;
+
+       ret = call_dec_op(dec, get_frameinfo, ctx, frameinfo);
+       if (ret)
+               goto err;
+       ctx->flags |= DELTA_FLAG_FRAMEINFO;
+
+       ctx->state = DELTA_STATE_READY;
+
+       dev_dbg(delta->dev, "%s %s => %s\n", ctx->name,
+               delta_streaminfo_str(streaminfo, str1, sizeof(str1)),
+               delta_frameinfo_str(frameinfo, str2, sizeof(str2)));
+
+       delta_au_done(ctx, au, ret);
+       return 0;
+
+err:
+       /*
+        * return all buffers to vb2 in QUEUED state.
+        * This will give ownership back to userspace
+        */
+       if (vbuf)
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_QUEUED);
+
+       while ((vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_QUEUED);
+       return ret;
+}
+
+static void delta_vb2_au_stop_streaming(struct vb2_queue *q)
+{
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct vb2_v4l2_buffer *vbuf;
+
+       delta_flush_dts(ctx);
+
+       /* return all buffers to vb2 in ERROR state */
+       while ((vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+
+       ctx->au_num = 0;
+
+       ctx->aborting = false;
+}
+
+static int delta_vb2_frame_queue_setup(struct vb2_queue *vq,
+                                      unsigned int *num_buffers,
+                                      unsigned int *num_planes,
+                                      unsigned int sizes[],
+                                      struct device *alloc_devs[])
+{
+       struct delta_ctx *ctx = vb2_get_drv_priv(vq);
+       struct delta_dev *delta = ctx->dev;
+       struct delta_streaminfo *streaminfo = &ctx->streaminfo;
+       struct delta_frameinfo *frameinfo = &ctx->frameinfo;
+       unsigned int size = frameinfo->size;
+
+       /*
+        * the number of output buffers needed for decoding =
+        * user need (*num_buffers given, usually for display pipeline) +
+        * stream need (streaminfo->dpb) +
+        * decoding peak smoothing (depends on DELTA IP perf)
+        */
+       if (*num_buffers < DELTA_MIN_FRAME_USER) {
+               dev_dbg(delta->dev,
+                       "%s num_buffers too low (%d), increasing to %d\n",
+                       ctx->name, *num_buffers, DELTA_MIN_FRAME_USER);
+               *num_buffers = DELTA_MIN_FRAME_USER;
+       }
+
+       *num_buffers += streaminfo->dpb + DELTA_PEAK_FRAME_SMOOTHING;
+
+       if (*num_buffers > DELTA_MAX_FRAMES) {
+               dev_dbg(delta->dev,
+                       "%s output frame count too high (%d), cut to %d\n",
+                       ctx->name, *num_buffers, DELTA_MAX_FRAMES);
+               *num_buffers = DELTA_MAX_FRAMES;
+       }
+
+       if (*num_planes)
+               return sizes[0] < size ? -EINVAL : 0;
+
+       /* single plane for Y and CbCr */
+       *num_planes = 1;
+
+       sizes[0] = size;
+
+       ctx->nb_of_frames = 0;
+
+       return 0;
+}
+
+static int delta_vb2_frame_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct delta_dev *delta = ctx->dev;
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct delta_frame *frame = to_frame(vbuf);
+       int ret = 0;
+
+       if (!frame->prepared) {
+               frame->index = vbuf->vb2_buf.index;
+               frame->vaddr = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
+               frame->paddr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
+               frame->info = ctx->frameinfo;
+
+               ret = delta_setup_frame(ctx, frame);
+               if (ret) {
+                       dev_err(delta->dev,
+                               "%s setup_frame() failed (%d)\n",
+                               ctx->name, ret);
+                       return ret;
+               }
+               frame->prepared = true;
+               dev_dbg(delta->dev,
+                       "%s frame[%d] prepared; virt=0x%p, phy=0x%pad\n",
+                       ctx->name, vb->index, frame->vaddr,
+                       &frame->paddr);
+       }
+
+       frame->flags = vbuf->flags;
+
+       return 0;
+}
+
+static void delta_vb2_frame_finish(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct delta_frame *frame = to_frame(vbuf);
+
+       /* update V4L2 fields for user */
+       vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->info.size);
+       vb->timestamp = frame->dts;
+       vbuf->field = frame->field;
+       vbuf->flags = frame->flags;
+}
+
+static void delta_vb2_frame_queue(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct delta_frame *frame = to_frame(vbuf);
+
+       if (ctx->state == DELTA_STATE_WF_EOS) {
+               /* new frame available, EOS can now be completed */
+               delta_complete_eos(ctx, frame);
+
+               ctx->state = DELTA_STATE_EOS;
+
+               /* return, no need to recycle this buffer to decoder */
+               return;
+       }
+
+       /* recycle this frame */
+       delta_recycle(ctx, frame);
+}
+
+static void delta_vb2_frame_stop_streaming(struct vb2_queue *q)
+{
+       struct delta_ctx *ctx = vb2_get_drv_priv(q);
+       struct vb2_v4l2_buffer *vbuf;
+       struct delta_frame *frame;
+       const struct delta_dec *dec = ctx->dec;
+       unsigned int i;
+
+       delta_flush_dts(ctx);
+
+       call_dec_op(dec, flush, ctx);
+
+       /*
+        * return all buffers to vb2 in ERROR state
+        * & reset each frame state to OUT
+        */
+       for (i = 0; i < ctx->nb_of_frames; i++) {
+               frame = ctx->frames[i];
+               if (!(frame->state & DELTA_FRAME_OUT)) {
+                       vbuf = &frame->vbuf;
+                       v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+               }
+               frame->state = DELTA_FRAME_OUT;
+       }
+
+       ctx->frame_num = 0;
+
+       ctx->aborting = false;
+}
+
+/* VB2 queue ops */
+static struct vb2_ops delta_vb2_au_ops = {
+       .queue_setup = delta_vb2_au_queue_setup,
+       .buf_prepare = delta_vb2_au_prepare,
+       .buf_queue = delta_vb2_au_queue,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
+       .start_streaming = delta_vb2_au_start_streaming,
+       .stop_streaming = delta_vb2_au_stop_streaming,
+};
+
+static struct vb2_ops delta_vb2_frame_ops = {
+       .queue_setup = delta_vb2_frame_queue_setup,
+       .buf_prepare = delta_vb2_frame_prepare,
+       .buf_finish = delta_vb2_frame_finish,
+       .buf_queue = delta_vb2_frame_queue,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
+       .stop_streaming = delta_vb2_frame_stop_streaming,
+};
+
+/*
+ * V4L2 file operations
+ */
+
+static int queue_init(void *priv,
+                     struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+{
+       struct vb2_queue *q;
+       struct delta_ctx *ctx = priv;
+       struct delta_dev *delta = ctx->dev;
+       int ret;
+
+       /* setup vb2 queue for stream input */
+       q = src_vq;
+       q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       q->io_modes = VB2_MMAP | VB2_DMABUF;
+       q->drv_priv = ctx;
+       /* overload vb2 buf with private au struct */
+       q->buf_struct_size = sizeof(struct delta_au);
+       q->ops = &delta_vb2_au_ops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       q->lock = &delta->lock;
+       q->dev = delta->dev;
+
+       ret = vb2_queue_init(q);
+       if (ret)
+               return ret;
+
+       /* setup vb2 queue for frame output */
+       q = dst_vq;
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_DMABUF;
+       q->drv_priv = ctx;
+       /* overload vb2 buf with private frame struct */
+       q->buf_struct_size = sizeof(struct delta_frame)
+                            + DELTA_MAX_FRAME_PRIV_SIZE;
+       q->ops = &delta_vb2_frame_ops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       q->lock = &delta->lock;
+       q->dev = delta->dev;
+
+       return vb2_queue_init(q);
+}
+
+static int delta_open(struct file *file)
+{
+       struct delta_dev *delta = video_drvdata(file);
+       struct delta_ctx *ctx = NULL;
+       int ret = 0;
+
+       mutex_lock(&delta->lock);
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx) {
+               ret = -ENOMEM;
+               goto err;
+       }
+       ctx->dev = delta;
+
+       v4l2_fh_init(&ctx->fh, video_devdata(file));
+       file->private_data = &ctx->fh;
+       v4l2_fh_add(&ctx->fh);
+
+       INIT_WORK(&ctx->run_work, delta_run_work);
+       mutex_init(&ctx->lock);
+
+       ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(delta->m2m_dev, ctx,
+                                           queue_init);
+       if (IS_ERR(ctx->fh.m2m_ctx)) {
+               ret = PTR_ERR(ctx->fh.m2m_ctx);
+               dev_err(delta->dev, "%s failed to initialize m2m context (%d)\n",
+                       DELTA_PREFIX, ret);
+               goto err_fh_del;
+       }
+
+       /*
+        * wait stream format to determine which
+        * decoder to open
+        */
+       ctx->state = DELTA_STATE_WF_FORMAT;
+
+       INIT_LIST_HEAD(&ctx->dts);
+
+       /* set the instance name */
+       delta->instance_id++;
+       snprintf(ctx->name, sizeof(ctx->name), "[%3d:----]",
+                delta->instance_id);
+
+       /* default parameters for frame and stream */
+       set_default_params(ctx);
+
+       /* enable ST231 clocks */
+       if (delta->clk_st231)
+               if (clk_prepare_enable(delta->clk_st231))
+                       dev_warn(delta->dev, "failed to enable st231 clk\n");
+
+       /* enable FLASH_PROMIP clock */
+       if (delta->clk_flash_promip)
+               if (clk_prepare_enable(delta->clk_flash_promip))
+                       dev_warn(delta->dev, "failed to enable delta promip clk\n");
+
+       mutex_unlock(&delta->lock);
+
+       dev_dbg(delta->dev, "%s decoder instance created\n", ctx->name);
+
+       return 0;
+
+err_fh_del:
+       v4l2_fh_del(&ctx->fh);
+       v4l2_fh_exit(&ctx->fh);
+       kfree(ctx);
+err:
+       mutex_unlock(&delta->lock);
+
+       return ret;
+}
+
+static int delta_release(struct file *file)
+{
+       struct delta_ctx *ctx = to_ctx(file->private_data);
+       struct delta_dev *delta = ctx->dev;
+       const struct delta_dec *dec = ctx->dec;
+
+       mutex_lock(&delta->lock);
+
+       /* close decoder */
+       call_dec_op(dec, close, ctx);
+
+       /*
+        * trace a summary of instance
+        * before closing (debug purpose)
+        */
+       delta_trace_summary(ctx);
+
+       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+
+       v4l2_fh_del(&ctx->fh);
+       v4l2_fh_exit(&ctx->fh);
+
+       /* disable ST231 clocks */
+       if (delta->clk_st231)
+               clk_disable_unprepare(delta->clk_st231);
+
+       /* disable FLASH_PROMIP clock */
+       if (delta->clk_flash_promip)
+               clk_disable_unprepare(delta->clk_flash_promip);
+
+       dev_dbg(delta->dev, "%s decoder instance released\n", ctx->name);
+
+       kfree(ctx);
+
+       mutex_unlock(&delta->lock);
+       return 0;
+}
+
+/* V4L2 file ops */
+static const struct v4l2_file_operations delta_fops = {
+       .owner = THIS_MODULE,
+       .open = delta_open,
+       .release = delta_release,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap = v4l2_m2m_fop_mmap,
+       .poll = v4l2_m2m_fop_poll,
+};
+
+/*
+ * Platform device operations
+ */
+
+static int delta_register_device(struct delta_dev *delta)
+{
+       int ret;
+       struct video_device *vdev;
+
+       if (!delta)
+               return -ENODEV;
+
+       delta->m2m_dev = v4l2_m2m_init(&delta_m2m_ops);
+       if (IS_ERR(delta->m2m_dev)) {
+               dev_err(delta->dev, "%s failed to initialize v4l2-m2m device\n",
+                       DELTA_PREFIX);
+               ret = PTR_ERR(delta->m2m_dev);
+               goto err;
+       }
+
+       vdev = video_device_alloc();
+       if (!vdev) {
+               dev_err(delta->dev, "%s failed to allocate video device\n",
+                       DELTA_PREFIX);
+               ret = -ENOMEM;
+               goto err_m2m_release;
+       }
+
+       vdev->fops = &delta_fops;
+       vdev->ioctl_ops = &delta_ioctl_ops;
+       vdev->release = video_device_release;
+       vdev->lock = &delta->lock;
+       vdev->vfl_dir = VFL_DIR_M2M;
+       vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
+       vdev->v4l2_dev = &delta->v4l2_dev;
+       snprintf(vdev->name, sizeof(vdev->name), "%s-%s",
+                DELTA_NAME, DELTA_FW_VERSION);
+
+       ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+       if (ret) {
+               dev_err(delta->dev, "%s failed to register video device\n",
+                       DELTA_PREFIX);
+               goto err_vdev_release;
+       }
+
+       delta->vdev = vdev;
+       video_set_drvdata(vdev, delta);
+       return 0;
+
+err_vdev_release:
+       video_device_release(vdev);
+err_m2m_release:
+       v4l2_m2m_release(delta->m2m_dev);
+err:
+       return ret;
+}
+
+static void delta_unregister_device(struct delta_dev *delta)
+{
+       if (!delta)
+               return;
+
+       if (delta->m2m_dev)
+               v4l2_m2m_release(delta->m2m_dev);
+
+       video_unregister_device(delta->vdev);
+}
+
+static int delta_probe(struct platform_device *pdev)
+{
+       struct delta_dev *delta;
+       struct device *dev = &pdev->dev;
+       int ret;
+
+       delta = devm_kzalloc(dev, sizeof(*delta), GFP_KERNEL);
+       if (!delta) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       delta->dev = dev;
+       delta->pdev = pdev;
+       platform_set_drvdata(pdev, delta);
+
+       mutex_init(&delta->lock);
+
+       /* get clock resources */
+       delta->clk_delta = devm_clk_get(dev, "delta");
+       if (IS_ERR(delta->clk_delta)) {
+               dev_dbg(dev, "%s can't get delta clock\n", DELTA_PREFIX);
+               delta->clk_delta = NULL;
+       }
+
+       delta->clk_st231 = devm_clk_get(dev, "delta-st231");
+       if (IS_ERR(delta->clk_st231)) {
+               dev_dbg(dev, "%s can't get delta-st231 clock\n", DELTA_PREFIX);
+               delta->clk_st231 = NULL;
+       }
+
+       delta->clk_flash_promip = devm_clk_get(dev, "delta-flash-promip");
+       if (IS_ERR(delta->clk_flash_promip)) {
+               dev_dbg(dev, "%s can't get delta-flash-promip clock\n",
+                       DELTA_PREFIX);
+               delta->clk_flash_promip = NULL;
+       }
+
+       /* init pm_runtime used for power management */
+       pm_runtime_set_autosuspend_delay(dev, DELTA_HW_AUTOSUSPEND_DELAY_MS);
+       pm_runtime_use_autosuspend(dev);
+       pm_runtime_set_suspended(dev);
+       pm_runtime_enable(dev);
+
+       /* init firmware ipc channel */
+       ret = delta_ipc_init(delta);
+       if (ret) {
+               dev_err(delta->dev, "%s failed to initialize firmware ipc channel\n",
+                       DELTA_PREFIX);
+               goto err;
+       }
+
+       /* register all available decoders */
+       register_decoders(delta);
+
+       /* register all supported formats */
+       register_formats(delta);
+
+       /* register on V4L2 */
+       ret = v4l2_device_register(dev, &delta->v4l2_dev);
+       if (ret) {
+               dev_err(delta->dev, "%s failed to register V4L2 device\n",
+                       DELTA_PREFIX);
+               goto err;
+       }
+
+       delta->work_queue = create_workqueue(DELTA_NAME);
+       if (!delta->work_queue) {
+               dev_err(delta->dev, "%s failed to allocate work queue\n",
+                       DELTA_PREFIX);
+               ret = -ENOMEM;
+               goto err_v4l2;
+       }
+
+       /* register device */
+       ret = delta_register_device(delta);
+       if (ret)
+               goto err_work_queue;
+
+       dev_info(dev, "%s %s registered as /dev/video%d\n",
+                DELTA_PREFIX, delta->vdev->name, delta->vdev->num);
+
+       return 0;
+
+err_work_queue:
+       destroy_workqueue(delta->work_queue);
+err_v4l2:
+       v4l2_device_unregister(&delta->v4l2_dev);
+err:
+       return ret;
+}
+
+static int delta_remove(struct platform_device *pdev)
+{
+       struct delta_dev *delta = platform_get_drvdata(pdev);
+
+       delta_ipc_exit(delta);
+
+       delta_unregister_device(delta);
+
+       destroy_workqueue(delta->work_queue);
+
+       pm_runtime_put_autosuspend(delta->dev);
+       pm_runtime_disable(delta->dev);
+
+       v4l2_device_unregister(&delta->v4l2_dev);
+
+       return 0;
+}
+
+static int delta_runtime_suspend(struct device *dev)
+{
+       struct delta_dev *delta = dev_get_drvdata(dev);
+
+       if (delta->clk_delta)
+               clk_disable_unprepare(delta->clk_delta);
+
+       return 0;
+}
+
+static int delta_runtime_resume(struct device *dev)
+{
+       struct delta_dev *delta = dev_get_drvdata(dev);
+
+       if (delta->clk_delta)
+               if (clk_prepare_enable(delta->clk_delta))
+                       dev_warn(dev, "failed to prepare/enable delta clk\n");
+
+       return 0;
+}
+
+/* PM ops */
+static const struct dev_pm_ops delta_pm_ops = {
+       .runtime_suspend = delta_runtime_suspend,
+       .runtime_resume = delta_runtime_resume,
+};
+
+static const struct of_device_id delta_match_types[] = {
+       {
+        .compatible = "st,st-delta",
+       },
+       {
+        /* end node */
+       }
+};
+
+MODULE_DEVICE_TABLE(of, delta_match_types);
+
+static struct platform_driver delta_driver = {
+       .probe = delta_probe,
+       .remove = delta_remove,
+       .driver = {
+                  .name = DELTA_NAME,
+                  .of_match_table = delta_match_types,
+                  .pm = &delta_pm_ops},
+};
+
+module_platform_driver(delta_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Hugues Fruchet <hugues.fruchet@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics DELTA video decoder V4L2 driver");
diff --git a/drivers/media/platform/sti/delta/delta.h b/drivers/media/platform/sti/delta/delta.h
new file mode 100644 (file)
index 0000000..60c0732
--- /dev/null
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef DELTA_H
+#define DELTA_H
+
+#include <linux/rpmsg.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "delta-cfg.h"
+
+/*
+ * enum delta_state - state of decoding instance
+ *
+ *@DELTA_STATE_WF_FORMAT:
+ *     Wait for compressed format to be set by V4L2 client in order
+ *     to know what is the relevant decoder to open.
+ *
+ *@DELTA_STATE_WF_STREAMINFO:
+ *     Wait for stream information to be available (bitstream
+ *     header parsing is done).
+ *
+ *@DELTA_STATE_READY:
+ *     Decoding instance is ready to decode compressed access unit.
+ *
+ *@DELTA_STATE_WF_EOS:
+ *     Decoding instance is waiting for EOS (End Of Stream) completion.
+ *
+ *@DELTA_STATE_EOS:
+ *     EOS (End Of Stream) is completed (signaled to user). Decoding instance
+ *     should then be closed.
+ */
+enum delta_state {
+       DELTA_STATE_WF_FORMAT,
+       DELTA_STATE_WF_STREAMINFO,
+       DELTA_STATE_READY,
+       DELTA_STATE_WF_EOS,
+       DELTA_STATE_EOS
+};
+
+/*
+ * struct delta_streaminfo - information about stream to decode
+ *
+ * @flags:             validity of fields (crop, pixelaspect, other)
+ * @width:             width of video stream
+ * @height:            height ""
+ * @streamformat:      fourcc compressed format of video (MJPEG, MPEG2, ...)
+ * @dpb:               number of frames needed to decode a single frame
+ *                     (h264 dpb, up to 16)
+ * @crop:              cropping window inside decoded frame (1920x1080@0,0
+ *                     inside 1920x1088 frame for ex.)
+ * @pixelaspect:       pixel aspect ratio of video (4/3, 5/4)
+ * @field:             interlaced or not
+ * @profile:           profile string
+ * @level:             level string
+ * @other:             other string information from codec
+ * @colorspace:                colorspace identifier
+ * @xfer_func:         transfer function identifier
+ * @ycbcr_enc:         Y'CbCr encoding identifier
+ * @quantization:      quantization identifier
+ */
+struct delta_streaminfo {
+       u32 flags;
+       u32 streamformat;
+       u32 width;
+       u32 height;
+       u32 dpb;
+       struct v4l2_rect crop;
+       struct v4l2_fract pixelaspect;
+       enum v4l2_field field;
+       u8 profile[32];
+       u8 level[32];
+       u8 other[32];
+       enum v4l2_colorspace colorspace;
+       enum v4l2_xfer_func xfer_func;
+       enum v4l2_ycbcr_encoding ycbcr_enc;
+       enum v4l2_quantization quantization;
+};
+
+#define DELTA_STREAMINFO_FLAG_CROP             0x0001
+#define DELTA_STREAMINFO_FLAG_PIXELASPECT      0x0002
+#define DELTA_STREAMINFO_FLAG_OTHER            0x0004
+
+/*
+ * struct delta_au - access unit structure.
+ *
+ * @vbuf:      video buffer information for V4L2
+ * @list:      V4L2 m2m list that the frame belongs to
+ * @prepared:  if set vaddr/paddr are resolved
+ * @vaddr:     virtual address (kernel can read/write)
+ * @paddr:     physical address (for hardware)
+ * @flags:     access unit type (V4L2_BUF_FLAG_KEYFRAME/PFRAME/BFRAME)
+ * @dts:       decoding timestamp of this access unit
+ */
+struct delta_au {
+       struct vb2_v4l2_buffer vbuf;    /* keep first */
+       struct list_head list;  /* keep second */
+
+       bool prepared;
+       u32 size;
+       void *vaddr;
+       dma_addr_t paddr;
+       u32 flags;
+       u64 dts;
+};
+
+/*
+ * struct delta_frameinfo - information about decoded frame
+ *
+ * @flags:             validity of fields (crop, pixelaspect)
+ * @pixelformat:       fourcc code for uncompressed video format
+ * @width:             width of frame
+ * @height:            height of frame
+ * @aligned_width:     width of frame (with encoder or decoder alignment
+ *                     constraint)
+ * @aligned_height:    height of frame (with encoder or decoder alignment
+ *                     constraint)
+ * @size:              maximum size in bytes required for data
+ * @crop:              cropping window inside frame (1920x1080@0,0
+ *                     inside 1920x1088 frame for ex.)
+ * @pixelaspect:       pixel aspect ratio of video (4/3, 5/4)
+ * @field:             interlaced mode
+ * @colorspace:                colorspace identifier
+ * @xfer_func:         transfer function identifier
+ * @ycbcr_enc:         Y'CbCr encoding identifier
+ * @quantization:      quantization identifier
+ */
+struct delta_frameinfo {
+       u32 flags;
+       u32 pixelformat;
+       u32 width;
+       u32 height;
+       u32 aligned_width;
+       u32 aligned_height;
+       u32 size;
+       struct v4l2_rect crop;
+       struct v4l2_fract pixelaspect;
+       enum v4l2_field field;
+       enum v4l2_colorspace colorspace;
+       enum v4l2_xfer_func xfer_func;
+       enum v4l2_ycbcr_encoding ycbcr_enc;
+       enum v4l2_quantization quantization;
+};
+
+#define DELTA_FRAMEINFO_FLAG_CROP              0x0001
+#define DELTA_FRAMEINFO_FLAG_PIXELASPECT       0x0002
+
+/*
+ * struct delta_frame - frame structure.
+ *
+ * @vbuf:      video buffer information for V4L2
+ * @list:      V4L2 m2m list that the frame belongs to
+ * @info:      frame information (width, height, format, alignment...)
+ * @prepared:  if set pix/vaddr/paddr are resolved
+ * @index:     frame index, aligned on V4L2 wow
+ * @vaddr:     virtual address (kernel can read/write)
+ * @paddr:     physical address (for hardware)
+ * @state:     frame state for frame lifecycle tracking
+ *             (DELTA_FRAME_FREE/DEC/OUT/REC/...)
+ * @flags:     frame type (V4L2_BUF_FLAG_KEYFRAME/PFRAME/BFRAME)
+ * @dts:       decoding timestamp of this frame
+ * @field:     field order for interlaced frame
+ */
+struct delta_frame {
+       struct vb2_v4l2_buffer vbuf;    /* keep first */
+       struct list_head list;  /* keep second */
+
+       struct delta_frameinfo info;
+       bool prepared;
+       u32 index;
+       void *vaddr;
+       dma_addr_t paddr;
+       u32 state;
+       u32 flags;
+       u64 dts;
+       enum v4l2_field field;
+};
+
+/* frame state for frame lifecycle tracking */
+#define DELTA_FRAME_FREE       0x00 /* is free and can be used for decoding */
+#define DELTA_FRAME_REF                0x01 /* is a reference frame */
+#define DELTA_FRAME_BSY                0x02 /* is owned by decoder and busy */
+#define DELTA_FRAME_DEC                0x04 /* contains decoded content */
+#define DELTA_FRAME_OUT                0x08 /* has been given to user */
+#define DELTA_FRAME_RDY                0x10 /* is ready but still held by decoder */
+#define DELTA_FRAME_M2M                0x20 /* is owned by mem2mem framework */
+
+/*
+ * struct delta_dts - decoding timestamp.
+ *
+ * @list:      list to chain timestamps
+ * @val:       timestamp in microseconds
+ */
+struct delta_dts {
+       struct list_head list;
+       u64 val;
+};
+
+struct delta_buf {
+       u32 size;
+       void *vaddr;
+       dma_addr_t paddr;
+       const char *name;
+       unsigned long attrs;
+};
+
+struct delta_ipc_ctx {
+       int cb_err;
+       u32 copro_hdl;
+       struct completion done;
+       struct delta_buf ipc_buf_struct;
+       struct delta_buf *ipc_buf;
+};
+
+struct delta_ipc_param {
+       u32 size;
+       void *data;
+};
+
+struct delta_ctx;
+
+/*
+ * struct delta_dec - decoder structure.
+ *
+ * @name:              name of this decoder
+ * @streamformat:      input stream format that this decoder support
+ * @pixelformat:       pixel format of decoded frame that this decoder support
+ * @max_width:         (optional) maximum width that can decode this decoder
+ *                     if not set, maximum width is DELTA_MAX_WIDTH
+ * @max_height:                (optional) maximum height that can decode this decoder
+ *                     if not set, maximum height is DELTA_MAX_HEIGHT
+ * @pm:                        (optional) if set, decoder will manage power on its own
+ * @open:              open this decoder
+ * @close:             close this decoder
+ * @setup_frame:       setup frame to be used by decoder, see below
+ * @get_streaminfo:    get stream related infos, see below
+ * @get_frameinfo:     get decoded frame related infos, see below
+ * @set_frameinfo:     (optional) set decoded frame related infos, see below
+ * @setup_frame:       setup frame to be used by decoder, see below
+ * @decode:            decode a single access unit, see below
+ * @get_frame:         get the next decoded frame available, see below
+ * @recycle:           recycle the given frame, see below
+ * @flush:             (optional) flush decoder, see below
+ * @drain:             (optional) drain decoder, see below
+ */
+struct delta_dec {
+       const char *name;
+       u32 streamformat;
+       u32 pixelformat;
+       u32 max_width;
+       u32 max_height;
+       bool pm;
+
+       /*
+        * decoder ops
+        */
+       int (*open)(struct delta_ctx *ctx);
+       int (*close)(struct delta_ctx *ctx);
+
+       /*
+        * setup_frame() - setup frame to be used by decoder
+        * @ctx:        (in) instance
+        * @frame:      (in) frame to use
+        *  @frame.index        (in) identifier of frame
+        *  @frame.vaddr        (in) virtual address (kernel can read/write)
+        *  @frame.paddr        (in) physical address (for hardware)
+        *
+        * Frame is to be allocated by caller, then given
+        * to decoder through this call.
+        * Several frames must be given to decoder (dpb),
+        * each frame is identified using its index.
+        */
+       int (*setup_frame)(struct delta_ctx *ctx, struct delta_frame *frame);
+
+       /*
+        * get_streaminfo() - get stream related infos
+        * @ctx:        (in) instance
+        * @streaminfo: (out) width, height, dpb,...
+        *
+        * Precondition: stream header must have been successfully
+        * parsed to have this call successful & @streaminfo valid.
+        * Header parsing must be done using decode(), giving
+        * explicitly header access unit or first access unit of bitstream.
+        * If no valid header is found, get_streaminfo will return -ENODATA,
+        * in this case the next bistream access unit must be decoded till
+        * get_streaminfo becomes successful.
+        */
+       int (*get_streaminfo)(struct delta_ctx *ctx,
+                             struct delta_streaminfo *streaminfo);
+
+       /*
+        * get_frameinfo() - get decoded frame related infos
+        * @ctx:        (in) instance
+        * @frameinfo:  (out) width, height, alignment, crop, ...
+        *
+        * Precondition: get_streaminfo() must be successful
+        */
+       int (*get_frameinfo)(struct delta_ctx *ctx,
+                            struct delta_frameinfo *frameinfo);
+
+       /*
+        * set_frameinfo() - set decoded frame related infos
+        * @ctx:        (in) instance
+        * @frameinfo:  (out) width, height, alignment, crop, ...
+        *
+        * Optional.
+        * Typically used to negotiate with decoder the output
+        * frame if decoder can do post-processing.
+        */
+       int (*set_frameinfo)(struct delta_ctx *ctx,
+                            struct delta_frameinfo *frameinfo);
+
+       /*
+        * decode() - decode a single access unit
+        * @ctx:        (in) instance
+        * @au:         (in/out) access unit
+        *  @au.size    (in) size of au to decode
+        *  @au.vaddr   (in) virtual address (kernel can read/write)
+        *  @au.paddr   (in) physical address (for hardware)
+        *  @au.flags   (out) au type (V4L2_BUF_FLAG_KEYFRAME/
+        *                      PFRAME/BFRAME)
+        *
+        * Decode the access unit given. Decode is synchronous;
+        * access unit memory is no more needed after this call.
+        * After this call, none, one or several frames could
+        * have been decoded, which can be retrieved using
+        * get_frame().
+        */
+       int (*decode)(struct delta_ctx *ctx, struct delta_au *au);
+
+       /*
+        * get_frame() - get the next decoded frame available
+        * @ctx:        (in) instance
+        * @frame:      (out) frame with decoded data:
+        *  @frame.index        (out) identifier of frame
+        *  @frame.field        (out) field order for interlaced frame
+        *  @frame.state        (out) frame state for frame lifecycle tracking
+        *  @frame.flags        (out) frame type (V4L2_BUF_FLAG_KEYFRAME/
+        *                      PFRAME/BFRAME)
+        *
+        * Get the next available decoded frame.
+        * If no frame is available, -ENODATA is returned.
+        * If a frame is available, frame structure is filled with
+        * relevant data, frame.index identifying this exact frame.
+        * When this frame is no more needed by upper layers,
+        * recycle() must be called giving this frame identifier.
+        */
+       int (*get_frame)(struct delta_ctx *ctx, struct delta_frame **frame);
+
+       /*
+        * recycle() - recycle the given frame
+        * @ctx:        (in) instance
+        * @frame:      (in) frame to recycle:
+        *  @frame.index        (in) identifier of frame
+        *
+        * recycle() is to be called by user when the decoded frame
+        * is no more needed (composition/display done).
+        * This frame will then be reused by decoder to proceed
+        * with next frame decoding.
+        * If not enough frames have been provided through setup_frame(),
+        * or recycle() is not called fast enough, the decoder can run out
+        * of available frames to proceed with decoding (starvation).
+        * This case is guarded by wq_recycle wait queue which ensures that
+        * decoder is called only if at least one frame is available.
+        */
+       int (*recycle)(struct delta_ctx *ctx, struct delta_frame *frame);
+
+       /*
+        * flush() - flush decoder
+        * @ctx:        (in) instance
+        *
+        * Optional.
+        * Reset decoder context and discard all internal buffers.
+        * This allows implementation of seek, which leads to discontinuity
+        * of input bitstream that decoder must know to restart its internal
+        * decoding logic.
+        */
+       int (*flush)(struct delta_ctx *ctx);
+
+       /*
+        * drain() - drain decoder
+        * @ctx:        (in) instance
+        *
+        * Optional.
+        * Mark decoder pending frames (decoded but not yet output) as ready
+        * so that they can be output to client at EOS (End Of Stream).
+        * get_frame() is to be called in a loop right after drain() to
+        * get all those pending frames.
+        */
+       int (*drain)(struct delta_ctx *ctx);
+};
+
+struct delta_dev;
+
+/*
+ * struct delta_ctx - instance structure.
+ *
+ * @flags:             validity of fields (streaminfo)
+ * @fh:                        V4L2 file handle
+ * @dev:               device context
+ * @dec:               selected decoder context for this instance
+ * @ipc_ctx:           context of IPC communication with firmware
+ * @state:             instance state
+ * @frame_num:         frame number
+ * @au_num:            access unit number
+ * @max_au_size:       max size of an access unit
+ * @streaminfo:                stream information (width, height, dpb, interlacing...)
+ * @frameinfo:         frame information (width, height, format, alignment...)
+ * @nb_of_frames:      number of frames available for decoding
+ * @frames:            array of decoding frames to keep track of frame
+ *                     state and manage frame recycling
+ * @decoded_frames:    nb of decoded frames from opening
+ * @output_frames:     nb of output frames from opening
+ * @dropped_frames:    nb of frames dropped (ie access unit not parsed
+ *                     or frame decoded but not output)
+ * @stream_errors:     nb of stream errors (corrupted, not supported, ...)
+ * @decode_errors:     nb of decode errors (firmware error)
+ * @sys_errors:                nb of system errors (memory, ipc, ...)
+ * @dts:               FIFO of decoding timestamp.
+ *                     output frames are timestamped with incoming access
+ *                     unit timestamps using this fifo.
+ * @name:              string naming this instance (debug purpose)
+ * @run_work:          decoding work
+ * @lock:              lock for decoding work serialization
+ * @aborting:          true if current job aborted
+ * @priv:              private decoder context for this instance, allocated
+ *                     by decoder @open time.
+ */
+struct delta_ctx {
+       u32 flags;
+       struct v4l2_fh fh;
+       struct delta_dev *dev;
+       const struct delta_dec *dec;
+       struct delta_ipc_ctx ipc_ctx;
+
+       enum delta_state state;
+       u32 frame_num;
+       u32 au_num;
+       size_t max_au_size;
+       struct delta_streaminfo streaminfo;
+       struct delta_frameinfo frameinfo;
+       u32 nb_of_frames;
+       struct delta_frame *frames[DELTA_MAX_FRAMES];
+       u32 decoded_frames;
+       u32 output_frames;
+       u32 dropped_frames;
+       u32 stream_errors;
+       u32 decode_errors;
+       u32 sys_errors;
+       struct list_head dts;
+       char name[100];
+       struct work_struct run_work;
+       struct mutex lock;
+       bool aborting;
+       void *priv;
+};
+
+#define DELTA_FLAG_STREAMINFO 0x0001
+#define DELTA_FLAG_FRAMEINFO 0x0002
+
+#define DELTA_MAX_FORMATS  DELTA_MAX_DECODERS
+
+/*
+ * struct delta_dev - device struct, 1 per probe (so single one for
+ * all platform life)
+ *
+ * @v4l2_dev:          v4l2 device
+ * @vdev:              v4l2 video device
+ * @pdev:              platform device
+ * @dev:               device
+ * @m2m_dev:           memory-to-memory V4L2 device
+ * @lock:              device lock, for crit section & V4L2 ops serialization.
+ * @clk_delta:         delta main clock
+ * @clk_st231:         st231 coprocessor main clock
+ * @clk_flash_promip:  flash promip clock
+ * @decoders:          list of registered decoders
+ * @nb_of_decoders:    nb of registered decoders
+ * @pixelformats:      supported uncompressed video formats
+ * @nb_of_pixelformats:        number of supported umcompressed video formats
+ * @streamformats:     supported compressed video formats
+ * @nb_of_streamformats:number of supported compressed video formats
+ * @instance_id:       rolling counter identifying an instance (debug purpose)
+ * @work_queue:                decoding job work queue
+ * @rpmsg_driver:      rpmsg IPC driver
+ * @rpmsg_device:      rpmsg IPC device
+ */
+struct delta_dev {
+       struct v4l2_device v4l2_dev;
+       struct video_device *vdev;
+       struct platform_device *pdev;
+       struct device *dev;
+       struct v4l2_m2m_dev *m2m_dev;
+       struct mutex lock;
+       struct clk *clk_delta;
+       struct clk *clk_st231;
+       struct clk *clk_flash_promip;
+       const struct delta_dec *decoders[DELTA_MAX_DECODERS];
+       u32 nb_of_decoders;
+       u32 pixelformats[DELTA_MAX_FORMATS];
+       u32 nb_of_pixelformats;
+       u32 streamformats[DELTA_MAX_FORMATS];
+       u32 nb_of_streamformats;
+       u8 instance_id;
+       struct workqueue_struct *work_queue;
+       struct rpmsg_driver rpmsg_driver;
+       struct rpmsg_device *rpmsg_device;
+};
+
+static inline char *frame_type_str(u32 flags)
+{
+       if (flags & V4L2_BUF_FLAG_KEYFRAME)
+               return "I";
+       if (flags & V4L2_BUF_FLAG_PFRAME)
+               return "P";
+       if (flags & V4L2_BUF_FLAG_BFRAME)
+               return "B";
+       if (flags & V4L2_BUF_FLAG_LAST)
+               return "EOS";
+       return "?";
+}
+
+static inline char *frame_field_str(enum v4l2_field field)
+{
+       if (field == V4L2_FIELD_NONE)
+               return "-";
+       if (field == V4L2_FIELD_TOP)
+               return "T";
+       if (field == V4L2_FIELD_BOTTOM)
+               return "B";
+       if (field == V4L2_FIELD_INTERLACED)
+               return "I";
+       if (field == V4L2_FIELD_INTERLACED_TB)
+               return "TB";
+       if (field == V4L2_FIELD_INTERLACED_BT)
+               return "BT";
+       return "?";
+}
+
+static inline char *frame_state_str(u32 state, char *str, unsigned int len)
+{
+       snprintf(str, len, "%s %s %s %s %s %s",
+                (state & DELTA_FRAME_REF)  ? "ref" : "   ",
+                (state & DELTA_FRAME_BSY)  ? "bsy" : "   ",
+                (state & DELTA_FRAME_DEC)  ? "dec" : "   ",
+                (state & DELTA_FRAME_OUT)  ? "out" : "   ",
+                (state & DELTA_FRAME_M2M)  ? "m2m" : "   ",
+                (state & DELTA_FRAME_RDY)  ? "rdy" : "   ");
+       return str;
+}
+
+int delta_get_frameinfo_default(struct delta_ctx *ctx,
+                               struct delta_frameinfo *frameinfo);
+int delta_recycle_default(struct delta_ctx *pctx,
+                         struct delta_frame *frame);
+
+int delta_get_free_frame(struct delta_ctx *ctx,
+                        struct delta_frame **pframe);
+
+int delta_get_sync(struct delta_ctx *ctx);
+void delta_put_autosuspend(struct delta_ctx *ctx);
+
+#endif /* DELTA_H */
index ffb69cebaef3d782b9388267362a9a40d7ad0cb4..e3ebe968472db99a3e801a2cd9948b49d01b73a4 100644 (file)
@@ -1,2 +1,3 @@
 obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o
 st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o
+st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o
diff --git a/drivers/media/platform/sti/hva/hva-debugfs.c b/drivers/media/platform/sti/hva/hva-debugfs.c
new file mode 100644 (file)
index 0000000..83a6258
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2015
+ * Authors: Yannick Fertre <yannick.fertre@st.com>
+ *          Hugues Fruchet <hugues.fruchet@st.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/debugfs.h>
+
+#include "hva.h"
+#include "hva-hw.h"
+
+static void format_ctx(struct seq_file *s, struct hva_ctx *ctx)
+{
+       struct hva_streaminfo *stream = &ctx->streaminfo;
+       struct hva_frameinfo *frame = &ctx->frameinfo;
+       struct hva_controls *ctrls = &ctx->ctrls;
+       struct hva_ctx_dbg *dbg = &ctx->dbg;
+       u32 bitrate_mode, aspect, entropy, vui_sar, sei_fp;
+
+       seq_printf(s, "|-%s\n  |\n", ctx->name);
+
+       seq_printf(s, "  |-[%sframe info]\n",
+                  ctx->flags & HVA_FLAG_FRAMEINFO ? "" : "default ");
+       seq_printf(s, "  | |- pixel format=%4.4s\n"
+                     "  | |- wxh=%dx%d\n"
+                     "  | |- wxh (w/ encoder alignment constraint)=%dx%d\n"
+                     "  |\n",
+                     (char *)&frame->pixelformat,
+                     frame->width, frame->height,
+                     frame->aligned_width, frame->aligned_height);
+
+       seq_printf(s, "  |-[%sstream info]\n",
+                  ctx->flags & HVA_FLAG_STREAMINFO ? "" : "default ");
+       seq_printf(s, "  | |- stream format=%4.4s\n"
+                     "  | |- wxh=%dx%d\n"
+                     "  | |- %s\n"
+                     "  | |- %s\n"
+                     "  |\n",
+                     (char *)&stream->streamformat,
+                     stream->width, stream->height,
+                     stream->profile, stream->level);
+
+       bitrate_mode = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
+       aspect = V4L2_CID_MPEG_VIDEO_ASPECT;
+       seq_puts(s, "  |-[parameters]\n");
+       seq_printf(s, "  | |- %s\n"
+                     "  | |- bitrate=%d bps\n"
+                     "  | |- GOP size=%d\n"
+                     "  | |- video aspect=%s\n"
+                     "  | |- framerate=%d/%d\n",
+                     v4l2_ctrl_get_menu(bitrate_mode)[ctrls->bitrate_mode],
+                     ctrls->bitrate,
+                     ctrls->gop_size,
+                     v4l2_ctrl_get_menu(aspect)[ctrls->aspect],
+                     ctrls->time_per_frame.denominator,
+                     ctrls->time_per_frame.numerator);
+
+       entropy = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
+       vui_sar = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
+       sei_fp =  V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
+       if (stream->streamformat == V4L2_PIX_FMT_H264) {
+               seq_printf(s, "  | |- %s entropy mode\n"
+                             "  | |- CPB size=%d kB\n"
+                             "  | |- DCT8x8 enable=%s\n"
+                             "  | |- qpmin=%d\n"
+                             "  | |- qpmax=%d\n"
+                             "  | |- PAR enable=%s\n"
+                             "  | |- PAR id=%s\n"
+                             "  | |- SEI frame packing enable=%s\n"
+                             "  | |- SEI frame packing type=%s\n",
+                             v4l2_ctrl_get_menu(entropy)[ctrls->entropy_mode],
+                             ctrls->cpb_size,
+                             ctrls->dct8x8 ? "true" : "false",
+                             ctrls->qpmin,
+                             ctrls->qpmax,
+                             ctrls->vui_sar ? "true" : "false",
+                             v4l2_ctrl_get_menu(vui_sar)[ctrls->vui_sar_idc],
+                             ctrls->sei_fp ? "true" : "false",
+                             v4l2_ctrl_get_menu(sei_fp)[ctrls->sei_fp_type]);
+       }
+
+       if (ctx->sys_errors || ctx->encode_errors || ctx->frame_errors) {
+               seq_puts(s, "  |\n  |-[errors]\n");
+               seq_printf(s, "  | |- system=%d\n"
+                             "  | |- encoding=%d\n"
+                             "  | |- frame=%d\n",
+                             ctx->sys_errors,
+                             ctx->encode_errors,
+                             ctx->frame_errors);
+       }
+
+       seq_puts(s, "  |\n  |-[performances]\n");
+       seq_printf(s, "  | |- frames encoded=%d\n"
+                     "  | |- avg HW processing duration (0.1ms)=%d [min=%d, max=%d]\n"
+                     "  | |- avg encoding period (0.1ms)=%d [min=%d, max=%d]\n"
+                     "  | |- avg fps (0.1Hz)=%d\n"
+                     "  | |- max reachable fps (0.1Hz)=%d\n"
+                     "  | |- avg bitrate (kbps)=%d [min=%d, max=%d]\n"
+                     "  | |- last bitrate (kbps)=%d\n",
+                     dbg->cnt_duration,
+                     dbg->avg_duration,
+                     dbg->min_duration,
+                     dbg->max_duration,
+                     dbg->avg_period,
+                     dbg->min_period,
+                     dbg->max_period,
+                     dbg->avg_fps,
+                     dbg->max_fps,
+                     dbg->avg_bitrate,
+                     dbg->min_bitrate,
+                     dbg->max_bitrate,
+                     dbg->last_bitrate);
+}
+
+/*
+ * performance debug info
+ */
+void hva_dbg_perf_begin(struct hva_ctx *ctx)
+{
+       u64 div;
+       u32 period;
+       u32 bitrate;
+       struct hva_ctx_dbg *dbg = &ctx->dbg;
+       ktime_t prev = dbg->begin;
+
+       dbg->begin = ktime_get();
+
+       if (dbg->is_valid_period) {
+               /* encoding period */
+               div = (u64)ktime_us_delta(dbg->begin, prev);
+               do_div(div, 100);
+               period = (u32)div;
+               dbg->min_period = min(period, dbg->min_period);
+               dbg->max_period = max(period, dbg->max_period);
+               dbg->total_period += period;
+               dbg->cnt_period++;
+
+               /*
+                * minimum and maximum bitrates are based on the
+                * encoding period values upon a window of 32 samples
+                */
+               dbg->window_duration += period;
+               dbg->cnt_window++;
+               if (dbg->cnt_window >= 32) {
+                       /*
+                        * bitrate in kbps = (size * 8 / 1000) /
+                        *                   (duration / 10000)
+                        *                 = size * 80 / duration
+                        */
+                       if (dbg->window_duration > 0) {
+                               div = (u64)dbg->window_stream_size * 80;
+                               do_div(div, dbg->window_duration);
+                               bitrate = (u32)div;
+                               dbg->last_bitrate = bitrate;
+                               dbg->min_bitrate = min(bitrate,
+                                                      dbg->min_bitrate);
+                               dbg->max_bitrate = max(bitrate,
+                                                      dbg->max_bitrate);
+                       }
+                       dbg->window_stream_size = 0;
+                       dbg->window_duration = 0;
+                       dbg->cnt_window = 0;
+               }
+       }
+
+       /*
+        * filter sequences valid for performance:
+        * - begin/begin (no stream available) is an invalid sequence
+        * - begin/end is a valid sequence
+        */
+       dbg->is_valid_period = false;
+}
+
+void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream)
+{
+       struct device *dev = ctx_to_dev(ctx);
+       u64 div;
+       u32 duration;
+       u32 bytesused;
+       u32 timestamp;
+       struct hva_ctx_dbg *dbg = &ctx->dbg;
+       ktime_t end = ktime_get();
+
+       /* stream bytesused and timestamp in us */
+       bytesused = vb2_get_plane_payload(&stream->vbuf.vb2_buf, 0);
+       div = stream->vbuf.vb2_buf.timestamp;
+       do_div(div, 1000);
+       timestamp = (u32)div;
+
+       /* encoding duration */
+       div = (u64)ktime_us_delta(end, dbg->begin);
+
+       dev_dbg(dev,
+               "%s perf stream[%d] dts=%d encoded using %d bytes in %d us",
+               ctx->name,
+               stream->vbuf.sequence,
+               timestamp,
+               bytesused, (u32)div);
+
+       do_div(div, 100);
+       duration = (u32)div;
+
+       dbg->min_duration = min(duration, dbg->min_duration);
+       dbg->max_duration = max(duration, dbg->max_duration);
+       dbg->total_duration += duration;
+       dbg->cnt_duration++;
+
+       /*
+        * the average bitrate is based on the total stream size
+        * and the total encoding periods
+        */
+       dbg->total_stream_size += bytesused;
+       dbg->window_stream_size += bytesused;
+
+       dbg->is_valid_period = true;
+}
+
+static void hva_dbg_perf_compute(struct hva_ctx *ctx)
+{
+       u64 div;
+       struct hva_ctx_dbg *dbg = &ctx->dbg;
+
+       if (dbg->cnt_duration > 0) {
+               div = (u64)dbg->total_duration;
+               do_div(div, dbg->cnt_duration);
+               dbg->avg_duration = (u32)div;
+       } else {
+               dbg->avg_duration = 0;
+       }
+
+       if (dbg->total_duration > 0) {
+               div = (u64)dbg->cnt_duration * 100000;
+               do_div(div, dbg->total_duration);
+               dbg->max_fps = (u32)div;
+       } else {
+               dbg->max_fps = 0;
+       }
+
+       if (dbg->cnt_period > 0) {
+               div = (u64)dbg->total_period;
+               do_div(div, dbg->cnt_period);
+               dbg->avg_period = (u32)div;
+       } else {
+               dbg->avg_period = 0;
+       }
+
+       if (dbg->total_period > 0) {
+               div = (u64)dbg->cnt_period * 100000;
+               do_div(div, dbg->total_period);
+               dbg->avg_fps = (u32)div;
+       } else {
+               dbg->avg_fps = 0;
+       }
+
+       if (dbg->total_period > 0) {
+               /*
+                * bitrate in kbps = (video size * 8 / 1000) /
+                *                   (video duration / 10000)
+                *                 = video size * 80 / video duration
+                */
+               div = (u64)dbg->total_stream_size * 80;
+               do_div(div, dbg->total_period);
+               dbg->avg_bitrate = (u32)div;
+       } else {
+               dbg->avg_bitrate = 0;
+       }
+}
+
+/*
+ * device debug info
+ */
+
+static int hva_dbg_device(struct seq_file *s, void *data)
+{
+       struct hva_dev *hva = s->private;
+
+       seq_printf(s, "[%s]\n", hva->v4l2_dev.name);
+       seq_printf(s, "registered as /dev/video%d\n", hva->vdev->num);
+
+       return 0;
+}
+
+static int hva_dbg_encoders(struct seq_file *s, void *data)
+{
+       struct hva_dev *hva = s->private;
+       unsigned int i = 0;
+
+       seq_printf(s, "[encoders]\n|- %d registered encoders:\n",
+                  hva->nb_of_encoders);
+
+       while (hva->encoders[i]) {
+               seq_printf(s, "|- %s: %4.4s => %4.4s\n", hva->encoders[i]->name,
+                          (char *)&hva->encoders[i]->pixelformat,
+                          (char *)&hva->encoders[i]->streamformat);
+               i++;
+       }
+
+       return 0;
+}
+
+static int hva_dbg_last(struct seq_file *s, void *data)
+{
+       struct hva_dev *hva = s->private;
+       struct hva_ctx *last_ctx = &hva->dbg.last_ctx;
+
+       if (last_ctx->flags & HVA_FLAG_STREAMINFO) {
+               seq_puts(s, "[last encoding]\n");
+
+               hva_dbg_perf_compute(last_ctx);
+               format_ctx(s, last_ctx);
+       } else {
+               seq_puts(s, "[no information recorded about last encoding]\n");
+       }
+
+       return 0;
+}
+
+static int hva_dbg_regs(struct seq_file *s, void *data)
+{
+       struct hva_dev *hva = s->private;
+
+       hva_hw_dump_regs(hva, s);
+
+       return 0;
+}
+
+#define hva_dbg_declare(name)                                            \
+       static int hva_dbg_##name##_open(struct inode *i, struct file *f) \
+       {                                                                 \
+               return single_open(f, hva_dbg_##name, i->i_private);      \
+       }                                                                 \
+       static const struct file_operations hva_dbg_##name##_fops = {     \
+               .open           = hva_dbg_##name##_open,                  \
+               .read           = seq_read,                               \
+               .llseek         = seq_lseek,                              \
+               .release        = single_release,                         \
+       }
+
+#define hva_dbg_create_entry(name)                                      \
+       debugfs_create_file(#name, 0444, hva->dbg.debugfs_entry, hva, \
+                           &hva_dbg_##name##_fops)
+
+hva_dbg_declare(device);
+hva_dbg_declare(encoders);
+hva_dbg_declare(last);
+hva_dbg_declare(regs);
+
+void hva_debugfs_create(struct hva_dev *hva)
+{
+       hva->dbg.debugfs_entry = debugfs_create_dir(HVA_NAME, NULL);
+       if (!hva->dbg.debugfs_entry)
+               goto err;
+
+       if (!hva_dbg_create_entry(device))
+               goto err;
+
+       if (!hva_dbg_create_entry(encoders))
+               goto err;
+
+       if (!hva_dbg_create_entry(last))
+               goto err;
+
+       if (!hva_dbg_create_entry(regs))
+               goto err;
+
+       return;
+
+err:
+       hva_debugfs_remove(hva);
+}
+
+void hva_debugfs_remove(struct hva_dev *hva)
+{
+       debugfs_remove_recursive(hva->dbg.debugfs_entry);
+       hva->dbg.debugfs_entry = NULL;
+}
+
+/*
+ * context (instance) debug info
+ */
+
+static int hva_dbg_ctx(struct seq_file *s, void *data)
+{
+       struct hva_ctx *ctx = s->private;
+
+       seq_printf(s, "[running encoding %d]\n", ctx->id);
+
+       hva_dbg_perf_compute(ctx);
+       format_ctx(s, ctx);
+
+       return 0;
+}
+
+hva_dbg_declare(ctx);
+
+void hva_dbg_ctx_create(struct hva_ctx *ctx)
+{
+       struct hva_dev *hva = ctx->hva_dev;
+       char name[4] = "";
+
+       ctx->dbg.min_duration = UINT_MAX;
+       ctx->dbg.min_period = UINT_MAX;
+       ctx->dbg.min_bitrate = UINT_MAX;
+
+       snprintf(name, sizeof(name), "%d", hva->instance_id);
+
+       ctx->dbg.debugfs_entry = debugfs_create_file(name, 0444,
+                                                    hva->dbg.debugfs_entry,
+                                                    ctx, &hva_dbg_ctx_fops);
+}
+
+void hva_dbg_ctx_remove(struct hva_ctx *ctx)
+{
+       struct hva_dev *hva = ctx->hva_dev;
+
+       if (ctx->flags & HVA_FLAG_STREAMINFO)
+               /* save context before removing */
+               memcpy(&hva->dbg.last_ctx, ctx, sizeof(*ctx));
+
+       debugfs_remove(ctx->dbg.debugfs_entry);
+}
index 8cc8467c0cd3d9a108528303b87a650461c7b7a4..e6f247a983c73bf1e4cc347248af51892f7d1b10 100644 (file)
@@ -607,6 +607,7 @@ static int hva_h264_prepare_task(struct hva_ctx *pctx,
                        "%s   width(%d) or height(%d) exceeds limits (%dx%d)\n",
                        pctx->name, frame_width, frame_height,
                        H264_MAX_SIZE_W, H264_MAX_SIZE_H);
+               pctx->frame_errors++;
                return -EINVAL;
        }
 
@@ -717,6 +718,7 @@ static int hva_h264_prepare_task(struct hva_ctx *pctx,
        default:
                dev_err(dev, "%s   invalid source pixel format\n",
                        pctx->name);
+               pctx->frame_errors++;
                return -EINVAL;
        }
 
@@ -741,6 +743,7 @@ static int hva_h264_prepare_task(struct hva_ctx *pctx,
 
        if (td->framerate_den == 0) {
                dev_err(dev, "%s   invalid framerate\n", pctx->name);
+               pctx->frame_errors++;
                return -EINVAL;
        }
 
@@ -831,6 +834,7 @@ static int hva_h264_prepare_task(struct hva_ctx *pctx,
            (payload > MAX_SPS_PPS_SIZE)) {
                dev_err(dev, "%s   invalid sps/pps size %d\n", pctx->name,
                        payload);
+               pctx->frame_errors++;
                return -EINVAL;
        }
 
@@ -842,6 +846,7 @@ static int hva_h264_prepare_task(struct hva_ctx *pctx,
                                                   (u8 *)stream->vaddr,
                                                   &payload)) {
                dev_err(dev, "%s   fail to get SEI nal\n", pctx->name);
+               pctx->frame_errors++;
                return -EINVAL;
        }
 
@@ -963,6 +968,7 @@ err_seq_info:
 err_ctx:
        devm_kfree(dev, ctx);
 err:
+       pctx->sys_errors++;
        return ret;
 }
 
index 68d625b412b6ce5e3a3c25920d516c3efbdad46e..ec25bdcfa3d1e11c776c2fe96d7671264c27234e 100644 (file)
@@ -9,6 +9,9 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+#include <linux/seq_file.h>
+#endif
 
 #include "hva.h"
 #include "hva-hw.h"
@@ -470,6 +473,7 @@ int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
 
        if (pm_runtime_get_sync(dev) < 0) {
                dev_err(dev, "%s     failed to get pm_runtime\n", ctx->name);
+               ctx->sys_errors++;
                ret = -EFAULT;
                goto out;
        }
@@ -481,6 +485,7 @@ int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
                break;
        default:
                dev_dbg(dev, "%s     unknown command 0x%x\n", ctx->name, cmd);
+               ctx->encode_errors++;
                ret = -EFAULT;
                goto out;
        }
@@ -511,6 +516,7 @@ int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
                                         msecs_to_jiffies(2000))) {
                dev_err(dev, "%s     %s: time out on completion\n", ctx->name,
                        __func__);
+               ctx->encode_errors++;
                ret = -EFAULT;
                goto out;
        }
@@ -518,6 +524,8 @@ int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
        /* get encoding status */
        ret = ctx->hw_err ? -EFAULT : 0;
 
+       ctx->encode_errors += ctx->hw_err ? 1 : 0;
+
 out:
        disable_irq(hva->irq_its);
        disable_irq(hva->irq_err);
@@ -536,3 +544,43 @@ out:
 
        return ret;
 }
+
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+#define DUMP(reg) seq_printf(s, "%-30s: 0x%08X\n",\
+                            #reg, readl_relaxed(hva->regs + reg))
+
+void hva_hw_dump_regs(struct hva_dev *hva, struct seq_file *s)
+{
+       struct device *dev = hva_to_dev(hva);
+
+       mutex_lock(&hva->protect_mutex);
+
+       if (pm_runtime_get_sync(dev) < 0) {
+               seq_puts(s, "Cannot wake up IP\n");
+               mutex_unlock(&hva->protect_mutex);
+               return;
+       }
+
+       seq_printf(s, "Registers:\nReg @ = 0x%p\n", hva->regs);
+
+       DUMP(HVA_HIF_REG_RST);
+       DUMP(HVA_HIF_REG_RST_ACK);
+       DUMP(HVA_HIF_REG_MIF_CFG);
+       DUMP(HVA_HIF_REG_HEC_MIF_CFG);
+       DUMP(HVA_HIF_REG_CFL);
+       DUMP(HVA_HIF_REG_SFL);
+       DUMP(HVA_HIF_REG_LMI_ERR);
+       DUMP(HVA_HIF_REG_EMI_ERR);
+       DUMP(HVA_HIF_REG_HEC_MIF_ERR);
+       DUMP(HVA_HIF_REG_HEC_STS);
+       DUMP(HVA_HIF_REG_HVC_STS);
+       DUMP(HVA_HIF_REG_HJE_STS);
+       DUMP(HVA_HIF_REG_CNT);
+       DUMP(HVA_HIF_REG_HEC_CHKSYN_DIS);
+       DUMP(HVA_HIF_REG_CLK_GATING);
+       DUMP(HVA_HIF_REG_VERSION);
+
+       pm_runtime_put_autosuspend(dev);
+       mutex_unlock(&hva->protect_mutex);
+}
+#endif
index efb45b927524c7ede050454a86814d4cfd2ec787..b46017dcfae95a0a317ea2992f4937a5501edf4c 100644 (file)
@@ -38,5 +38,8 @@ int hva_hw_runtime_suspend(struct device *dev);
 int hva_hw_runtime_resume(struct device *dev);
 int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
                        struct hva_buffer *task);
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+void hva_hw_dump_regs(struct hva_dev *hva, struct seq_file *s);
+#endif
 
 #endif /* HVA_HW_H */
index 649f66007ad666e68380c9fc36988f72d1664001..821c78ed208c0646c24daa2242b7b7254ab4b8b3 100644 (file)
@@ -17,14 +17,17 @@ int hva_mem_alloc(struct hva_ctx *ctx, u32 size, const char *name,
        void *base;
 
        b = devm_kzalloc(dev, sizeof(*b), GFP_KERNEL);
-       if (!b)
+       if (!b) {
+               ctx->sys_errors++;
                return -ENOMEM;
+       }
 
        base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL | GFP_DMA,
                               DMA_ATTR_WRITE_COMBINE);
        if (!base) {
                dev_err(dev, "%s %s : dma_alloc_attrs failed for %s (size=%d)\n",
                        ctx->name, __func__, name, size);
+               ctx->sys_errors++;
                devm_kfree(dev, b);
                return -ENOMEM;
        }
index 6bf3c85882300f9f97c65dd9a2d10bf4c3f68369..1c4fc33cbcb5ac8205b49a03fe2cdfa4fbaec78e 100644 (file)
@@ -15,8 +15,6 @@
 #include "hva.h"
 #include "hva-hw.h"
 
-#define HVA_NAME "st-hva"
-
 #define MIN_FRAMES     1
 #define MIN_STREAMS    1
 
@@ -226,6 +224,28 @@ static int hva_open_encoder(struct hva_ctx *ctx, u32 streamformat,
        return ret;
 }
 
+static void hva_dbg_summary(struct hva_ctx *ctx)
+{
+       struct device *dev = ctx_to_dev(ctx);
+       struct hva_streaminfo *stream = &ctx->streaminfo;
+       struct hva_frameinfo *frame = &ctx->frameinfo;
+
+       if (!(ctx->flags & HVA_FLAG_STREAMINFO))
+               return;
+
+       dev_dbg(dev, "%s %4.4s %dx%d > %4.4s %dx%d %s %s: %d frames encoded, %d system errors, %d encoding errors, %d frame errors\n",
+               ctx->name,
+               (char *)&frame->pixelformat,
+               frame->aligned_width, frame->aligned_height,
+               (char *)&stream->streamformat,
+               stream->width, stream->height,
+               stream->profile, stream->level,
+               ctx->encoded_frames,
+               ctx->sys_errors,
+               ctx->encode_errors,
+               ctx->frame_errors);
+}
+
 /*
  * V4L2 ioctl operations
  */
@@ -614,19 +634,17 @@ static int hva_s_ctrl(struct v4l2_ctrl *ctrl)
                break;
        case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
                ctx->ctrls.profile = ctrl->val;
-               if (ctx->flags & HVA_FLAG_STREAMINFO)
-                       snprintf(ctx->streaminfo.profile,
-                                sizeof(ctx->streaminfo.profile),
-                                "%s profile",
-                                v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
+               snprintf(ctx->streaminfo.profile,
+                        sizeof(ctx->streaminfo.profile),
+                        "%s profile",
+                        v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
                break;
        case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
                ctx->ctrls.level = ctrl->val;
-               if (ctx->flags & HVA_FLAG_STREAMINFO)
-                       snprintf(ctx->streaminfo.level,
-                                sizeof(ctx->streaminfo.level),
-                                "level %s",
-                                v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
+               snprintf(ctx->streaminfo.level,
+                        sizeof(ctx->streaminfo.level),
+                        "level %s",
+                        v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
                break;
        case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
                ctx->ctrls.entropy_mode = ctrl->val;
@@ -793,6 +811,10 @@ static void hva_run_work(struct work_struct *work)
        /* protect instance against reentrancy */
        mutex_lock(&ctx->lock);
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       hva_dbg_perf_begin(ctx);
+#endif
+
        src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
        dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 
@@ -812,6 +834,12 @@ static void hva_run_work(struct work_struct *work)
                dst_buf->field = V4L2_FIELD_NONE;
                dst_buf->sequence = ctx->stream_num - 1;
 
+               ctx->encoded_frames++;
+
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+               hva_dbg_perf_end(ctx, stream);
+#endif
+
                v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
                v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
        }
@@ -1026,6 +1054,8 @@ err:
                        v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_QUEUED);
        }
 
+       ctx->sys_errors++;
+
        return ret;
 }
 
@@ -1150,6 +1180,7 @@ static int hva_open(struct file *file)
        if (ret) {
                dev_err(dev, "%s [x:x] failed to setup controls\n",
                        HVA_PREFIX);
+               ctx->sys_errors++;
                goto err_fh;
        }
        ctx->fh.ctrl_handler = &ctx->ctrl_handler;
@@ -1162,6 +1193,7 @@ static int hva_open(struct file *file)
                ret = PTR_ERR(ctx->fh.m2m_ctx);
                dev_err(dev, "%s failed to initialize m2m context (%d)\n",
                        HVA_PREFIX, ret);
+               ctx->sys_errors++;
                goto err_ctrls;
        }
 
@@ -1175,6 +1207,10 @@ static int hva_open(struct file *file)
        /* default parameters for frame and stream */
        set_default_params(ctx);
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       hva_dbg_ctx_create(ctx);
+#endif
+
        dev_info(dev, "%s encoder instance created\n", ctx->name);
 
        return 0;
@@ -1206,6 +1242,9 @@ static int hva_release(struct file *file)
                hva->nb_of_instances--;
        }
 
+       /* trace a summary of instance before closing (debug purpose) */
+       hva_dbg_summary(ctx);
+
        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 
        v4l2_ctrl_handler_free(&ctx->ctrl_handler);
@@ -1213,6 +1252,10 @@ static int hva_release(struct file *file)
        v4l2_fh_del(&ctx->fh);
        v4l2_fh_exit(&ctx->fh);
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       hva_dbg_ctx_remove(ctx);
+#endif
+
        dev_info(dev, "%s encoder instance released\n", ctx->name);
 
        kfree(ctx);
@@ -1337,6 +1380,10 @@ static int hva_probe(struct platform_device *pdev)
                goto err_hw;
        }
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       hva_debugfs_create(hva);
+#endif
+
        hva->work_queue = create_workqueue(HVA_NAME);
        if (!hva->work_queue) {
                dev_err(dev, "%s %s failed to allocate work queue\n",
@@ -1358,6 +1405,9 @@ static int hva_probe(struct platform_device *pdev)
 err_work_queue:
        destroy_workqueue(hva->work_queue);
 err_v4l2:
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       hva_debugfs_remove(hva);
+#endif
        v4l2_device_unregister(&hva->v4l2_dev);
 err_hw:
        hva_hw_remove(hva);
@@ -1376,6 +1426,10 @@ static int hva_remove(struct platform_device *pdev)
 
        hva_hw_remove(hva);
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       hva_debugfs_remove(hva);
+#endif
+
        v4l2_device_unregister(&hva->v4l2_dev);
 
        dev_info(dev, "%s %s removed\n", HVA_PREFIX, pdev->name);
index caa5808255411464fdf1685a14a5261ab0c186ce..0d749b257a211335bc85908ab30b9b68b7a68a65 100644 (file)
@@ -21,7 +21,8 @@
 
 #define ctx_to_hdev(c)  (c->hva_dev)
 
-#define HVA_PREFIX "[---:----]"
+#define HVA_NAME       "st-hva"
+#define HVA_PREFIX     "[---:----]"
 
 extern const struct hva_enc nv12h264enc;
 extern const struct hva_enc nv21h264enc;
@@ -153,6 +154,61 @@ struct hva_stream {
 #define to_hva_stream(vb) \
        container_of(vb, struct hva_stream, vbuf)
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+/**
+ * struct hva_ctx_dbg - instance context debug info
+ *
+ * @debugfs_entry:      debugfs entry
+ * @is_valid_period:    true if the sequence is valid for performance
+ * @begin:              start time of last HW task
+ * @total_duration:     total HW processing durations in 0.1ms
+ * @cnt_duration:       number of HW processings
+ * @min_duration:       minimum HW processing duration in 0.1ms
+ * @max_duration:       maximum HW processing duration in 0.1ms
+ * @avg_duration:       average HW processing duration in 0.1ms
+ * @max_fps:            maximum frames encoded per second (in 0.1Hz)
+ * @total_period:       total encoding periods in 0.1ms
+ * @cnt_period:         number of periods
+ * @min_period:         minimum encoding period in 0.1ms
+ * @max_period:         maximum encoding period in 0.1ms
+ * @avg_period:         average encoding period in 0.1ms
+ * @total_stream_size:  total number of encoded bytes
+ * @avg_fps:            average frames encoded per second (in 0.1Hz)
+ * @window_duration:    duration of the sampling window in 0.1ms
+ * @cnt_window:         number of samples in the window
+ * @window_stream_size: number of encoded bytes upon the sampling window
+ * @last_bitrate:       bitrate upon the last sampling window
+ * @min_bitrate:        minimum bitrate in kbps
+ * @max_bitrate:        maximum bitrate in kbps
+ * @avg_bitrate:        average bitrate in kbps
+ */
+struct hva_ctx_dbg {
+       struct dentry   *debugfs_entry;
+       bool            is_valid_period;
+       ktime_t         begin;
+       u32             total_duration;
+       u32             cnt_duration;
+       u32             min_duration;
+       u32             max_duration;
+       u32             avg_duration;
+       u32             max_fps;
+       u32             total_period;
+       u32             cnt_period;
+       u32             min_period;
+       u32             max_period;
+       u32             avg_period;
+       u32             total_stream_size;
+       u32             avg_fps;
+       u32             window_duration;
+       u32             cnt_window;
+       u32             window_stream_size;
+       u32             last_bitrate;
+       u32             min_bitrate;
+       u32             max_bitrate;
+       u32             avg_bitrate;
+};
+#endif
+
 struct hva_dev;
 struct hva_enc;
 
@@ -182,6 +238,11 @@ struct hva_enc;
  * @priv:            private codec data for this instance, allocated
  *                   by encoder @open time
  * @hw_err:          true if hardware error detected
+ * @encoded_frames:  number of encoded frames
+ * @sys_errors:      number of system errors (memory, resource, pm...)
+ * @encode_errors:   number of encoding errors (hw/driver errors)
+ * @frame_errors:    number of frame errors (format, size, header...)
+ * @dbg:             context debug info
  */
 struct hva_ctx {
        struct hva_dev                  *hva_dev;
@@ -207,11 +268,31 @@ struct hva_ctx {
        struct hva_enc                  *enc;
        void                            *priv;
        bool                            hw_err;
+       u32                             encoded_frames;
+       u32                             sys_errors;
+       u32                             encode_errors;
+       u32                             frame_errors;
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       struct hva_ctx_dbg              dbg;
+#endif
 };
 
 #define HVA_FLAG_STREAMINFO    0x0001
 #define HVA_FLAG_FRAMEINFO     0x0002
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+/**
+ * struct hva_dev_dbg - device debug info
+ *
+ * @debugfs_entry: debugfs entry
+ * @last_ctx:      debug information about last running instance context
+ */
+struct hva_dev_dbg {
+       struct dentry   *debugfs_entry;
+       struct hva_ctx  last_ctx;
+};
+#endif
+
 #define HVA_MAX_INSTANCES      16
 #define HVA_MAX_ENCODERS       10
 #define HVA_MAX_FORMATS                HVA_MAX_ENCODERS
@@ -250,6 +331,7 @@ struct hva_ctx {
  * @lmi_err_reg:         local memory interface error register value
  * @emi_err_reg:         external memory interface error register value
  * @hec_mif_err_reg:     HEC memory interface error register value
+ * @dbg:                 device debug info
  */
 struct hva_dev {
        struct v4l2_device      v4l2_dev;
@@ -284,6 +366,9 @@ struct hva_dev {
        u32                     lmi_err_reg;
        u32                     emi_err_reg;
        u32                     hec_mif_err_reg;
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+       struct hva_dev_dbg      dbg;
+#endif
 };
 
 /**
@@ -312,4 +397,13 @@ struct hva_enc {
                                  struct hva_stream *stream);
 };
 
+#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
+void hva_debugfs_create(struct hva_dev *hva);
+void hva_debugfs_remove(struct hva_dev *hva);
+void hva_dbg_ctx_create(struct hva_ctx *ctx);
+void hva_dbg_ctx_remove(struct hva_ctx *ctx);
+void hva_dbg_perf_begin(struct hva_ctx *ctx);
+void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream);
+#endif
+
 #endif /* HVA_H */
index 13bfd718416051d912a4a6f5ba529638f2db14c3..23472e3784ff169f0c05c9bcb473cccb6d9af0d0 100644 (file)
@@ -453,7 +453,7 @@ int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
        if (ret)
                return ret;
 
-       while (vpdma_list_busy(vpdma, list_num) && timeout--)
+       while (vpdma_list_busy(vpdma, list_num) && --timeout)
                ;
 
        if (timeout == 0) {
index a98f679bd88d0ba57ec1c8b99afc4174c6e1d88d..970b9b6dab25562200e6a0243b1d50218aafab45 100644 (file)
@@ -907,6 +907,7 @@ static int vim2m_open(struct file *file)
        if (hdl->error) {
                rc = hdl->error;
                v4l2_ctrl_handler_free(hdl);
+               kfree(ctx);
                goto open_unlock;
        }
        ctx->fh.ctrl_handler = hdl;
@@ -928,6 +929,7 @@ static int vim2m_open(struct file *file)
                rc = PTR_ERR(ctx->fh.m2m_ctx);
 
                v4l2_ctrl_handler_free(hdl);
+               v4l2_fh_exit(&ctx->fh);
                kfree(ctx);
                goto open_unlock;
        }
index c52dd87877941943ed8ac5a1adb0d2a42dec6272..a18e6fec219bb5fe7fa381d6076fdccdd18bcc9e 100644 (file)
@@ -63,7 +63,7 @@ static const struct vivid_fmt formats_ovl[] = {
 };
 
 /* The number of discrete webcam framesizes */
-#define VIVID_WEBCAM_SIZES 4
+#define VIVID_WEBCAM_SIZES 5
 /* The number of discrete webcam frameintervals */
 #define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2)
 
@@ -73,6 +73,7 @@ static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = {
        {  640, 360 },
        { 1280, 720 },
        { 1920, 1080 },
+       { 3840, 2160 },
 };
 
 /*
@@ -80,7 +81,9 @@ static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = {
  * elements in this array as there are in webcam_sizes.
  */
 static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
+       {  1, 1 },
        {  1, 2 },
+       {  1, 4 },
        {  1, 5 },
        {  1, 10 },
        {  1, 15 },
index cd209dccff1bd0f8f9679b124f619a59b831a5e3..b4b583f7137a54eb86f8592724603b296afb9347 100644 (file)
@@ -90,7 +90,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
                if (ret == -ETIMEDOUT)
                        dev_err(vsp1->dev, "DRM pipeline stop timeout\n");
 
-               media_entity_pipeline_stop(&pipe->output->entity.subdev.entity);
+               media_pipeline_stop(&pipe->output->entity.subdev.entity);
 
                for (i = 0; i < bru->entity.source_pad; ++i) {
                        vsp1->drm->inputs[i].enabled = false;
@@ -196,7 +196,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
        if (ret < 0)
                return ret;
 
-       ret = media_entity_pipeline_start(&pipe->output->entity.subdev.entity,
+       ret = media_pipeline_start(&pipe->output->entity.subdev.entity,
                                          &pipe->pipe);
        if (ret < 0) {
                dev_dbg(vsp1->dev, "%s: pipeline start failed\n", __func__);
index 41e8b096dab85893191aefea8de5e0265dcc64d3..3eaadbf7a876dd3c5400e7473304a6c7ad8f06cf 100644 (file)
@@ -548,20 +548,20 @@ out:
 static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
                                     struct vsp1_video *video)
 {
-       struct media_entity_graph graph;
+       struct media_graph graph;
        struct media_entity *entity = &video->video.entity;
        struct media_device *mdev = entity->graph_obj.mdev;
        unsigned int i;
        int ret;
 
        /* Walk the graph to locate the entities and video nodes. */
-       ret = media_entity_graph_walk_init(&graph, mdev);
+       ret = media_graph_walk_init(&graph, mdev);
        if (ret)
                return ret;
 
-       media_entity_graph_walk_start(&graph, entity);
+       media_graph_walk_start(&graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(&graph))) {
+       while ((entity = media_graph_walk_next(&graph))) {
                struct v4l2_subdev *subdev;
                struct vsp1_rwpf *rwpf;
                struct vsp1_entity *e;
@@ -590,7 +590,7 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
                }
        }
 
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
 
        /* We need one output and at least one input. */
        if (pipe->num_inputs == 0 || !pipe->output)
@@ -848,7 +848,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
        }
        mutex_unlock(&pipe->lock);
 
-       media_entity_pipeline_stop(&video->video.entity);
+       media_pipeline_stop(&video->video.entity);
        vsp1_video_pipeline_put(pipe);
 
        /* Remove all buffers from the IRQ queue. */
@@ -980,7 +980,7 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
                return PTR_ERR(pipe);
        }
 
-       ret = __media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
+       ret = __media_pipeline_start(&video->video.entity, &pipe->pipe);
        if (ret < 0) {
                mutex_unlock(&mdev->graph_mutex);
                goto err_pipe;
@@ -1003,7 +1003,7 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
        return 0;
 
 err_stop:
-       media_entity_pipeline_stop(&video->video.entity);
+       media_pipeline_stop(&video->video.entity);
 err_pipe:
        vsp1_video_pipeline_put(pipe);
        return ret;
@@ -1021,6 +1021,7 @@ static const struct v4l2_ioctl_ops vsp1_video_ioctl_ops = {
        .vidioc_querybuf                = vb2_ioctl_querybuf,
        .vidioc_qbuf                    = vb2_ioctl_qbuf,
        .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
+       .vidioc_expbuf                  = vb2_ioctl_expbuf,
        .vidioc_create_bufs             = vb2_ioctl_create_bufs,
        .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
        .vidioc_streamon                = vsp1_video_streamon,
index 1d5836c3fb7a8ff0fd0109627836fb3fdae03fb9..522cdfdd334518fd578e8440d451d37a504afc7e 100644 (file)
@@ -177,7 +177,7 @@ done:
 static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
                                  struct xvip_dma *start)
 {
-       struct media_entity_graph graph;
+       struct media_graph graph;
        struct media_entity *entity = &start->video.entity;
        struct media_device *mdev = entity->graph_obj.mdev;
        unsigned int num_inputs = 0;
@@ -187,15 +187,15 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
        mutex_lock(&mdev->graph_mutex);
 
        /* Walk the graph to locate the video nodes. */
-       ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
+       ret = media_graph_walk_init(&graph, mdev);
        if (ret) {
                mutex_unlock(&mdev->graph_mutex);
                return ret;
        }
 
-       media_entity_graph_walk_start(&graph, entity);
+       media_graph_walk_start(&graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(&graph))) {
+       while ((entity = media_graph_walk_next(&graph))) {
                struct xvip_dma *dma;
 
                if (entity->function != MEDIA_ENT_F_IO_V4L)
@@ -213,7 +213,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 
        mutex_unlock(&mdev->graph_mutex);
 
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
 
        /* We need exactly one output and zero or one input. */
        if (num_outputs != 1 || num_inputs > 1)
@@ -409,7 +409,7 @@ static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count)
        pipe = dma->video.entity.pipe
             ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe;
 
-       ret = media_entity_pipeline_start(&dma->video.entity, &pipe->pipe);
+       ret = media_pipeline_start(&dma->video.entity, &pipe->pipe);
        if (ret < 0)
                goto error;
 
@@ -435,7 +435,7 @@ static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count)
        return 0;
 
 error_stop:
-       media_entity_pipeline_stop(&dma->video.entity);
+       media_pipeline_stop(&dma->video.entity);
 
 error:
        /* Give back all queued buffers to videobuf2. */
@@ -463,7 +463,7 @@ static void xvip_dma_stop_streaming(struct vb2_queue *vq)
 
        /* Cleanup the pipeline and mark it as being stopped. */
        xvip_pipeline_cleanup(pipe);
-       media_entity_pipeline_stop(&dma->video.entity);
+       media_pipeline_stop(&dma->video.entity);
 
        /* Give back all queued buffers to videobuf2. */
        spin_lock_irq(&dma->queued_lock);
index 2ec1f6c4b27421d81dae68f62a9221178b579d55..9c49d1d10bee572066e14d35151595a878f124d9 100644 (file)
@@ -460,21 +460,21 @@ static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
        .s_ctrl = xtpg_s_ctrl,
 };
 
-static struct v4l2_subdev_core_ops xtpg_core_ops = {
+static const struct v4l2_subdev_core_ops xtpg_core_ops = {
 };
 
-static struct v4l2_subdev_video_ops xtpg_video_ops = {
+static const struct v4l2_subdev_video_ops xtpg_video_ops = {
        .s_stream = xtpg_s_stream,
 };
 
-static struct v4l2_subdev_pad_ops xtpg_pad_ops = {
+static const struct v4l2_subdev_pad_ops xtpg_pad_ops = {
        .enum_mbus_code         = xvip_enum_mbus_code,
        .enum_frame_size        = xtpg_enum_frame_size,
        .get_fmt                = xtpg_get_format,
        .set_fmt                = xtpg_set_format,
 };
 
-static struct v4l2_subdev_ops xtpg_ops = {
+static const struct v4l2_subdev_ops xtpg_ops = {
        .core   = &xtpg_core_ops,
        .video  = &xtpg_video_ops,
        .pad    = &xtpg_pad_ops,
index 2262b8139ca1e39d779d73fa22927467623f4683..53bc8c0100357c56ee5e4c678c76414c34be20b9 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
 
 #include <linux/kernel.h>
index 82affaedf06778ad73d0d40fa1a87b0e621630cd..cbaf850f47912792c75e8b9fed8de4b9258816ba 100644 (file)
@@ -309,9 +309,7 @@ static void cadet_handler(unsigned long data)
        /*
         * Clean up and exit
         */
-       init_timer(&dev->readtimer);
-       dev->readtimer.function = cadet_handler;
-       dev->readtimer.data = data;
+       setup_timer(&dev->readtimer, cadet_handler, data);
        dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
        add_timer(&dev->readtimer);
 }
@@ -320,9 +318,7 @@ static void cadet_start_rds(struct cadet *dev)
 {
        dev->rdsstat = 1;
        outb(0x80, dev->io);        /* Select RDS fifo */
-       init_timer(&dev->readtimer);
-       dev->readtimer.function = cadet_handler;
-       dev->readtimer.data = (unsigned long)dev;
+       setup_timer(&dev->readtimer, cadet_handler, (unsigned long)dev);
        dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
        add_timer(&dev->readtimer);
 }
index c309ee45a08e1ba3d5a747a35badac7767c15dfa..7312e469e850e8bbb0d3e54f02356de7a96d953e 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #include <linux/module.h>
index ba4c01f1bd0c275213a993d9574fb70e18be8600..bab414919cf0647d53ea4f83116f5cb907c22255 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #ifndef _RADIO_ISA_H_
index 0c5d2db3b8282280cb2bdcb03af790a2f4ceb394..53a7c2e87762ae7eeb9c6cbb12489debe2a5f890 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /* kernel includes */
index b3000ef85ee715d0c500c2ae0bbb7dcc62073448..c2010a905a4727358666b98609f408faf191554a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/kernel.h>
index c2927fd12615d30e7a019db7bb681a95830505db..95c12532e87a2dcd1ea62412d9ece6b33c5cdf18 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /*
index 85667a95f003a053ecfeb9a2ad3254453b543d31..23971f5502a8514d883751f094a9e0ccf3a45775 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
 
 #include <linux/init.h>
index 0e65a85d52c6667dac78d175b365cfff17e9ec11..b50638ec5f09633f268434789faec47e406b4835 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/init.h>
index a1930b300c06d3bf14811b43b161056b14f346ab..9db8331a0c758dd5f4b0e8618b4833d389c8ab3c 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  * History:
  * 2008-12-06   Fabio Belavenuto <belavenuto@gmail.com>
  *              initial code
index 83fe7ab358dfaa6eecc0013f0e3fb1036caeedb8..04ed1a5d117789bcc598e039144bf7168ed09d90 100644 (file)
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #include <linux/delay.h>
index 4bd942526a1bb83a07344074df77e3bfdec8dde5..6b5af3c8457b57852e65b67834fc7442431f0473 100644 (file)
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #include <linux/videodev2.h>
index a82eb9678d6c5379a8d029fff5e85a4f4464f048..fc4d9a73ab17fc6ce41c466a43e761c2d2ea9576 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/io.h>
index 9ce4b12299b4bc8c907db084dbdb94709927c75f..7240223dc15abae5a9dd00cf6662beaec8e2f196 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/delay.h>
index ba8e357ba0a2dc1d856f386e79a24eee0c85a3ef..bf9eced906db4d0185ec1e73e2500adaaf5b5f13 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 1d827adab7ebbbbf2ef9ed873fa55494344e4aa5..cd76facc22f5cffc8de8f450af2b3ce5f2c292fb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 
index 9b81969d76b57df9e0da4bf61f45cd0e04d00263..b3034f80163fb349d50dd7cd8da1b725741cc418 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 
index 1add136d37a32f327f32a3f04f786ea39863b8ad..571f29a34bf81e23f35fedae5a10ec9a6bc50d5d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 
index 6c0ca900702e9762e8ed1ae1e7fc6c3bc8f718c3..7d2defd9d3991e921f55d57cc6bbfc560aa8c6d0 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 
index 6c7597383ca2e0d54f8b71147e449afedb3c75ba..6f93ef1249a6a2ada6989de6dc8bad0743289c03 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/kernel.h>
index bc2a8b5442ae3e7370f9854f55c963c18ba8680d..60f026a58076bb1f28f24fe109fc436d0ddea574 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/completion.h>
index 9f879f0ec0ef2de7e516d5b77830583525259670..ed210f4c476aa1ac3604e087e7fdb5d5c667d2ec 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index dd203de5de9597265178bd3d6d27c87dc6e25c7f..1ff2eec4ed52ec7d269c3bc05afa7ca9b3abf29e 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef _FM_DRV_H
index 4be07656fbc0c4223c90cb51857f758688c550bb..74a1b3ecb30a087955ec0b412df86bbb11e4a2ec 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/module.h>
index d9b9c6cf83b40fe9f9a973ec3de930b784cd5b4d..7f1514eb1c07349720ecb7ae2d380beffdc8b81a 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef _FMDRV_COMMON_H
index e7455f82fadcaa5133c6474f7be51d7cfc083c5f..f689adc831ceb0f2e7e8217cedfa7c525389cb44 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "fmdrv.h"
index 23922188882fb83fa6c0e484b16dc48c8720d83a..f647c9bc796a6e7b9fc893b3acff9b951a225a86 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef _FMDRV_RX_H
index 839970b0f313522a31edfc0430f0d15652f47526..47ac19466ed2c37cb6c3589286c1a77c0a885a85 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/delay.h>
index 11ae2e4c2d033e586bfcda18db1754aa9462fe8b..95e4daf7ba43227ccd54ee329d90f8d99e88e0a1 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef _FMDRV_TX_H
index fb42f0fd0c1f0fbe65cd2b8401854411e387f2ef..71423f45c05c2f2c9eb966f7e1dab03ff5c01df5 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/export.h>
index 0ba79d745e2f42925325035f6d15211fefd92026..9babb4ab2fad44683778672026aed5698d16aa74 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef _FMDRV_V4L2_H
index 629e8ca15ab37ef4f42a3c32cc114269f7f95a07..d1d3fd00ed89664a2dab5d4b4bd8178f028ca913 100644 (file)
@@ -235,6 +235,17 @@ config IR_MESON
           To compile this driver as a module, choose M here: the
           module will be called meson-ir.
 
+config IR_MTK
+       tristate "Mediatek IR remote receiver"
+       depends on RC_CORE
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       ---help---
+          Say Y if you want to use the IR remote receiver available
+          on Mediatek SoCs.
+
+          To compile this driver as a module, choose M here: the
+          module will be called mtk-cir.
+
 config IR_NUVOTON
        tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
        depends on PNP
@@ -261,6 +272,15 @@ config IR_REDRAT3
           To compile this driver as a module, choose M here: the
           module will be called redrat3.
 
+config IR_SPI
+       tristate "SPI connected IR LED"
+       depends on SPI && LIRC
+       ---help---
+         Say Y if you want to use an IR LED connected through SPI bus.
+
+         To compile this driver as a module, choose M here: the module will be
+         called ir-spi.
+
 config IR_STREAMZAP
        tristate "Streamzap PC Remote IR Receiver"
        depends on USB_ARCH_HAS_HCD
@@ -336,7 +356,7 @@ config IR_TTUSBIR
 
 config IR_RX51
        tristate "Nokia N900 IR transmitter diode"
-       depends on OMAP_DM_TIMER && PWM_OMAP_DMTIMER && ARCH_OMAP2PLUS && LIRC
+       depends on (OMAP_DM_TIMER && PWM_OMAP_DMTIMER && ARCH_OMAP2PLUS || COMPILE_TEST) && RC_CORE
        ---help---
           Say Y or M here if you want to enable support for the IR
           transmitter diode built in the Nokia N900 (RX51) device.
index 3a984ee301e256c9e9e38c085980ce5cc8740384..679aa0af85cd65d30d4bba4b1216eafdfeab4d98 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
 obj-$(CONFIG_IR_ENE) += ene_ir.o
 obj-$(CONFIG_IR_REDRAT3) += redrat3.o
 obj-$(CONFIG_IR_RX51) += ir-rx51.o
+obj-$(CONFIG_IR_SPI) += ir-spi.o
 obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
 obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
 obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
@@ -38,3 +39,4 @@ obj-$(CONFIG_RC_ST) += st_rc.o
 obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
 obj-$(CONFIG_IR_IMG) += img-ir/
 obj-$(CONFIG_IR_SERIAL) += serial_ir.o
+obj-$(CONFIG_IR_MTK) += mtk-cir.o
index 0884b7dc0e71314c500172d04f268c78f05015c7..9cf3e69de16a4cde23dcc4c166089223beae5f53 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *
  * Hardware & software notes
@@ -764,7 +760,6 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote)
        struct rc_dev *rdev = ati_remote->rdev;
 
        rdev->priv = ati_remote;
-       rdev->driver_type = RC_DRIVER_SCANCODE;
        rdev->allowed_protocols = RC_BIT_OTHER;
        rdev->driver_name = "ati_remote";
 
@@ -851,7 +846,7 @@ static int ati_remote_probe(struct usb_interface *interface,
        }
 
        ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
-       rc_dev = rc_allocate_device();
+       rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!ati_remote || !rc_dev)
                goto exit_free_dev_rdev;
 
index bd5512e64aeadf08cd4ff9474fedfccb09468038..60da963f40dca448b0cab7269de5e11724fa6a03 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
  * Special thanks to:
  *   Sami R. <maesesami@gmail.com> for lot of help in debugging and therefore
  *    bringing to life support for transmission & learning mode.
@@ -1012,7 +1007,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 
        /* allocate memory */
        dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!dev || !rdev)
                goto exit_free_dev_rdev;
 
@@ -1058,8 +1053,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
        if (!dev->hw_learning_and_tx_capable)
                learning_mode_force = false;
 
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rdev->priv = dev;
        rdev->open = ene_open;
        rdev->close = ene_close;
index a7911e3b9bc07d4e887dadf8a41a76cf6e1275c5..494646b2a2844e0edb5dc3c670de07241c19c73e 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
  */
 #include <linux/spinlock.h>
 
index ecab69ea3d5157d3ef6bce57a742fa7d01d81073..0d3562712f273c968653b95aa5a0dc772a176391 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -492,7 +487,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
                return ret;
 
        /* input device for IR remote (and tx) */
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rdev)
                goto exit_free_dev_rdev;
 
@@ -534,8 +529,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
 
        /* Set up the rc device */
        rdev->priv = fintek;
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rdev->open = fintek_open;
        rdev->close = fintek_close;
        rdev->input_name = FINTEK_DESCRIPTION;
index b698f3d2ced938582a80aa9c8075add338921fb9..ac34a774d018343d16a48c9e3ea1e56b91b0cca6 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
  */
 
 #include <linux/spinlock.h>
index 5b63b1f15cb18b4431c872923b88d1cd2c0bf764..4a4895e4d5993afddf0ef667ced79b055f21035b 100644 (file)
@@ -143,14 +143,13 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
        if (!gpio_dev)
                return -ENOMEM;
 
-       rcdev = rc_allocate_device();
+       rcdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rcdev) {
                rc = -ENOMEM;
                goto err_allocate_device;
        }
 
        rcdev->priv = gpio_dev;
-       rcdev->driver_type = RC_DRIVER_IR_RAW;
        rcdev->input_name = GPIO_IR_DEVICE_NAME;
        rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
        rcdev->input_id.bustype = BUS_HOST;
@@ -165,7 +164,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
        if (pdata->allowed_protos)
                rcdev->allowed_protocols = pdata->allowed_protos;
        else
-               rcdev->allowed_protocols = RC_BIT_ALL;
+               rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
 
        gpio_dev->rcdev = rcdev;
index 5cf983be07a207f896dc11621095e21ebd91c79a..0f0ed4ea4d06bd3e4671d3ee6070eda2d496abbe 100644 (file)
@@ -190,7 +190,7 @@ static int igorplugusb_probe(struct usb_interface *intf,
 
        usb_make_path(udev, ir->phys, sizeof(ir->phys));
 
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rc)
                goto fail;
 
@@ -198,13 +198,12 @@ static int igorplugusb_probe(struct usb_interface *intf,
        rc->input_phys = ir->phys;
        usb_to_input_id(udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
-       rc->driver_type = RC_DRIVER_IR_RAW;
        /*
         * This device can only store 36 pulses + spaces, which is not enough
         * for the NEC protocol and many others.
         */
-       rc->allowed_protocols = RC_BIT_ALL & ~(RC_BIT_NEC | RC_BIT_NECX |
-                       RC_BIT_NEC32 | RC_BIT_RC6_6A_20 |
+       rc->allowed_protocols = RC_BIT_ALL_IR_DECODER & ~(RC_BIT_NEC |
+                       RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_6A_20 |
                        RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE |
                        RC_BIT_SONY20 | RC_BIT_MCE_KBD | RC_BIT_SANYO);
 
index 5f634545ddd81c6e98887ed93a8fc2abb8a29f21..ccf24fd7ec1bbc65b16ece57979b2025182617df 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/device.h>
@@ -431,7 +427,7 @@ static int iguanair_probe(struct usb_interface *intf,
        struct usb_host_interface *idesc;
 
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!ir || !rc) {
                ret = -ENOMEM;
                goto out;
@@ -494,8 +490,7 @@ static int iguanair_probe(struct usb_interface *intf,
        rc->input_phys = ir->phys;
        usb_to_input_id(ir->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
-       rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protocols = RC_BIT_ALL;
+       rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rc->priv = ir;
        rc->open = iguanair_open;
        rc->close = iguanair_close;
@@ -504,7 +499,9 @@ static int iguanair_probe(struct usb_interface *intf,
        rc->tx_ir = iguanair_tx;
        rc->driver_name = DRIVER_NAME;
        rc->map_name = RC_MAP_RC6_MCE;
-       rc->timeout = MS_TO_NS(100);
+       rc->min_timeout = 1;
+       rc->timeout = IR_DEFAULT_TIMEOUT;
+       rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
        rc->rx_resolution = RX_RESOLUTION;
 
        iguanair_set_tx_carrier(rc, 38000);
index 7bb71bc9f534d525d48f9fd97a56e2e749685185..431d33b36fb03d97f1379c45952563be806ffbf4 100644 (file)
@@ -488,7 +488,15 @@ static int img_ir_set_filter(struct rc_dev *dev, enum rc_filter_type type,
        /* convert scancode filter to raw filter */
        filter.minlen = 0;
        filter.maxlen = ~0;
-       ret = hw->decoder->filter(sc_filter, &filter, hw->enabled_protocols);
+       if (type == RC_FILTER_NORMAL) {
+               /* guess scancode from protocol */
+               ret = hw->decoder->filter(sc_filter, &filter,
+                                         dev->enabled_protocols);
+       } else {
+               /* for wakeup user provided exact protocol variant */
+               ret = hw->decoder->filter(sc_filter, &filter,
+                                         1ULL << dev->wakeup_protocol);
+       }
        if (ret)
                goto unlock;
        dev_dbg(priv->dev, "IR raw %sfilter=%016llx & %016llx\n",
@@ -581,6 +589,7 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
        /* clear the wakeup scancode filter */
        rdev->scancode_wakeup_filter.data = 0;
        rdev->scancode_wakeup_filter.mask = 0;
+       rdev->wakeup_protocol = RC_TYPE_UNKNOWN;
 
        /* clear raw filters */
        _img_ir_set_filter(priv, NULL);
@@ -685,7 +694,6 @@ success:
        if (!hw->decoder || !hw->decoder->filter)
                wakeup_protocols = 0;
        rdev->allowed_wakeup_protocols = wakeup_protocols;
-       rdev->enabled_wakeup_protocols = wakeup_protocols;
        return 0;
 }
 
@@ -701,7 +709,6 @@ static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto)
        mutex_lock(&rdev->lock);
        rdev->enabled_protocols = proto;
        rdev->allowed_wakeup_protocols = proto;
-       rdev->enabled_wakeup_protocols = proto;
        mutex_unlock(&rdev->lock);
 }
 
@@ -1071,7 +1078,7 @@ int img_ir_probe_hw(struct img_ir_priv *priv)
        }
 
        /* Allocate hardware decoder */
-       hw->rdev = rdev = rc_allocate_device();
+       hw->rdev = rdev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!rdev) {
                dev_err(priv->dev, "cannot allocate input device\n");
                error = -ENOMEM;
index 09314933ea0871127e027dd45fced708924fb34a..044fd42b22a090b34a5fb64cbd2df0cba50192bb 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "img-ir-hw.h"
 #include <linux/bitrev.h>
+#include <linux/log2.h>
 
 /* Convert NEC data to a scancode */
 static int img_ir_nec_scancode(int len, u64 raw, u64 enabled_protocols,
@@ -62,7 +63,23 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in,
        data       = in->data & 0xff;
        data_m     = in->mask & 0xff;
 
-       if ((in->data | in->mask) & 0xff000000) {
+       protocols &= RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32;
+
+       /*
+        * If only one bit is set, we were requested to do an exact
+        * protocol. This should be the case for wakeup filters; for
+        * normal filters, guess the protocol from the scancode.
+        */
+       if (!is_power_of_2(protocols)) {
+               if ((in->data | in->mask) & 0xff000000)
+                       protocols = RC_BIT_NEC32;
+               else if ((in->data | in->mask) & 0x00ff0000)
+                       protocols = RC_BIT_NECX;
+               else
+                       protocols = RC_BIT_NEC;
+       }
+
+       if (protocols == RC_BIT_NEC32) {
                /* 32-bit NEC (used by Apple and TiVo remotes) */
                /* scan encoding: as transmitted, MSBit = first received bit */
                addr       = bitrev8(in->data >> 24);
@@ -73,7 +90,7 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in,
                data_m     = bitrev8(in->mask >>  8);
                data_inv   = bitrev8(in->data >>  0);
                data_inv_m = bitrev8(in->mask >>  0);
-       } else if ((in->data | in->mask) & 0x00ff0000) {
+       } else if (protocols == RC_BIT_NECX) {
                /* Extended NEC */
                /* scan encoding AAaaDD */
                addr       = (in->data >> 16) & 0xff;
index 33f37ed87ad2909e5b53e1a4083c99e46d70d68d..8d2f8e2006e7bdce9ade9bc9fd3cb144d4d84126 100644 (file)
@@ -110,7 +110,7 @@ int img_ir_probe_raw(struct img_ir_priv *priv)
        setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);
 
        /* Allocate raw decoder */
-       raw->rdev = rdev = rc_allocate_device();
+       raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rdev) {
                dev_err(priv->dev, "cannot allocate raw input device\n");
                return -ENOMEM;
@@ -118,7 +118,6 @@ int img_ir_probe_raw(struct img_ir_priv *priv)
        rdev->priv = priv;
        rdev->map_name = RC_MAP_EMPTY;
        rdev->input_name = "IMG Infrared Decoder Raw";
-       rdev->driver_type = RC_DRIVER_IR_RAW;
 
        /* Register raw decoder */
        error = rc_register_device(rdev);
index 7f7375f82ed60017f0dfe6c0517b7ec93ecd85bb..3fcba271a419f8582ded5ecffa29413c2cb9e89d 100644 (file)
@@ -68,19 +68,29 @@ static int img_ir_sony_filter(const struct rc_scancode_filter *in,
        func     = (in->data >> 0)  & 0x7f;
        func_m   = (in->mask >> 0)  & 0x7f;
 
-       if (subdev & subdev_m) {
+       protocols &= RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20;
+
+       /*
+        * If only one bit is set, we were requested to do an exact
+        * protocol. This should be the case for wakeup filters; for
+        * normal filters, guess the protocol from the scancode.
+        */
+       if (!is_power_of_2(protocols)) {
+               if (subdev & subdev_m)
+                       protocols = RC_BIT_SONY20;
+               else if (dev & dev_m & 0xe0)
+                       protocols = RC_BIT_SONY15;
+               else
+                       protocols = RC_BIT_SONY12;
+       }
+
+       if (protocols == RC_BIT_SONY20) {
                /* can't encode subdev and higher device bits */
                if (dev & dev_m & 0xe0)
                        return -EINVAL;
-               /* subdevice (extended) bits only in 20 bit encoding */
-               if (!(protocols & RC_BIT_SONY20))
-                       return -EINVAL;
                len = 20;
                dev_m &= 0x1f;
-       } else if (dev & dev_m & 0xe0) {
-               /* upper device bits only in 15 bit encoding */
-               if (!(protocols & RC_BIT_SONY15))
-                       return -EINVAL;
+       } else if (protocols == RC_BIT_SONY15) {
                len = 15;
                subdev_m = 0;
        } else {
index 0785a24af8fc4acca86e11b74b372b8d9af29dcd..89823d24a38441cf7e3bcaef11b4f623eb78d01d 100644 (file)
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
@@ -96,6 +92,7 @@ struct imon_usb_dev_descr {
        __u16 flags;
 #define IMON_NO_FLAGS 0
 #define IMON_NEED_20MS_PKT_DELAY 1
+#define IMON_IR_RAW 2
        struct imon_panel_key_table key_table[];
 };
 
@@ -126,6 +123,12 @@ struct imon_context {
        unsigned char usb_tx_buf[8];
        unsigned int send_packet_delay;
 
+       struct rx_data {
+               int count;              /* length of 0 or 1 sequence */
+               int prev_bit;           /* logic level of sequence */
+               int initial_space;      /* initial space flag */
+       } rx;
+
        struct tx_t {
                unsigned char data_buf[35];     /* user data buffer */
                struct completion finished;     /* wait for write to finish */
@@ -328,6 +331,10 @@ static const struct imon_usb_dev_descr imon_DH102 = {
        }
 };
 
+static const struct imon_usb_dev_descr imon_ir_raw = {
+       .flags = IMON_IR_RAW,
+};
+
 /*
  * USB Device ID for iMON USB Control Boards
  *
@@ -411,6 +418,18 @@ static struct usb_device_id imon_usb_id_table[] = {
        /* device specifics unknown */
        { USB_DEVICE(0x15c2, 0x0046),
          .driver_info = (unsigned long)&imon_default_table},
+       /* TriGem iMON (IR only) -- TG_iMON.inf */
+       { USB_DEVICE(0x0aa8, 0x8001),
+         .driver_info = (unsigned long)&imon_ir_raw},
+       /* SoundGraph iMON (IR only) -- sg_imon.inf */
+       { USB_DEVICE(0x04e8, 0xff30),
+         .driver_info = (unsigned long)&imon_ir_raw},
+       /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */
+       { USB_DEVICE(0x0aa8, 0xffda),
+         .driver_info = (unsigned long)&imon_ir_raw},
+       /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */
+       { USB_DEVICE(0x15c2, 0xffda),
+         .driver_info = (unsigned long)&imon_ir_raw},
        {}
 };
 
@@ -1577,8 +1596,91 @@ static int imon_parse_press_type(struct imon_context *ictx,
 /**
  * Process the incoming packet
  */
-static void imon_incoming_packet(struct imon_context *ictx,
+/**
+ * Convert bit count to time duration (in us) and submit
+ * the value to lirc_dev.
+ */
+static void submit_data(struct imon_context *context)
+{
+       DEFINE_IR_RAW_EVENT(ev);
+
+       ev.pulse = context->rx.prev_bit;
+       ev.duration = US_TO_NS(context->rx.count * BIT_DURATION);
+       ir_raw_event_store_with_filter(context->rdev, &ev);
+}
+
+/**
+ * Process the incoming packet
+ */
+static void imon_incoming_ir_raw(struct imon_context *context,
                                 struct urb *urb, int intf)
+{
+       int len = urb->actual_length;
+       unsigned char *buf = urb->transfer_buffer;
+       struct device *dev = context->dev;
+       int octet, bit;
+       unsigned char mask;
+
+       if (len != 8) {
+               dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n",
+                        __func__, len, intf);
+               return;
+       }
+
+       if (debug)
+               dev_info(dev, "raw packet: %*ph\n", len, buf);
+       /*
+        * Translate received data to pulse and space lengths.
+        * Received data is active low, i.e. pulses are 0 and
+        * spaces are 1.
+        *
+        * My original algorithm was essentially similar to
+        * Changwoo Ryu's with the exception that he switched
+        * the incoming bits to active high and also fed an
+        * initial space to LIRC at the start of a new sequence
+        * if the previous bit was a pulse.
+        *
+        * I've decided to adopt his algorithm.
+        */
+
+       if (buf[7] == 1 && context->rx.initial_space) {
+               /* LIRC requires a leading space */
+               context->rx.prev_bit = 0;
+               context->rx.count = 4;
+               submit_data(context);
+               context->rx.count = 0;
+       }
+
+       for (octet = 0; octet < 5; ++octet) {
+               mask = 0x80;
+               for (bit = 0; bit < 8; ++bit) {
+                       int curr_bit = !(buf[octet] & mask);
+
+                       if (curr_bit != context->rx.prev_bit) {
+                               if (context->rx.count) {
+                                       submit_data(context);
+                                       context->rx.count = 0;
+                               }
+                               context->rx.prev_bit = curr_bit;
+                       }
+                       ++context->rx.count;
+                       mask >>= 1;
+               }
+       }
+
+       if (buf[7] == 10) {
+               if (context->rx.count) {
+                       submit_data(context);
+                       context->rx.count = 0;
+               }
+               context->rx.initial_space = context->rx.prev_bit;
+       }
+
+       ir_raw_event_handle(context->rdev);
+}
+
+static void imon_incoming_scancode(struct imon_context *ictx,
+                                  struct urb *urb, int intf)
 {
        int len = urb->actual_length;
        unsigned char *buf = urb->transfer_buffer;
@@ -1761,7 +1863,10 @@ static void usb_rx_callback_intf0(struct urb *urb)
                break;
 
        case 0:
-               imon_incoming_packet(ictx, urb, intfnum);
+               if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW)
+                       imon_incoming_ir_raw(ictx, urb, intfnum);
+               else
+                       imon_incoming_scancode(ictx, urb, intfnum);
                break;
 
        default:
@@ -1802,7 +1907,10 @@ static void usb_rx_callback_intf1(struct urb *urb)
                break;
 
        case 0:
-               imon_incoming_packet(ictx, urb, intfnum);
+               if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW)
+                       imon_incoming_ir_raw(ictx, urb, intfnum);
+               else
+                       imon_incoming_scancode(ictx, urb, intfnum);
                break;
 
        default:
@@ -1910,11 +2018,14 @@ static void imon_set_display_type(struct imon_context *ictx)
                case 0x0041:
                case 0x0042:
                case 0x0043:
+               case 0x8001:
+               case 0xff30:
                        configured_display_type = IMON_DISPLAY_TYPE_NONE;
                        ictx->display_supported = false;
                        break;
                case 0x0036:
                case 0x0044:
+               case 0xffda:
                default:
                        configured_display_type = IMON_DISPLAY_TYPE_VFD;
                        break;
@@ -1939,7 +2050,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
        const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
                                            0x00, 0x00, 0x00, 0x88 };
 
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(ictx->dev_descr->flags & IMON_IR_RAW ?
+                                 RC_DRIVER_IR_RAW : RC_DRIVER_SCANCODE);
        if (!rdev) {
                dev_err(ictx->dev, "remote control dev allocation failed\n");
                goto out;
@@ -1957,8 +2069,11 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
        rdev->dev.parent = ictx->dev;
 
        rdev->priv = ictx;
-       rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
+       if (ictx->dev_descr->flags & IMON_IR_RAW)
+               rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
+       else
+               /* iMON PAD or MCE */
+               rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE;
        rdev->change_protocol = imon_ir_change_protocol;
        rdev->driver_name = MOD_NAME;
 
@@ -1976,7 +2091,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 
        imon_set_display_type(ictx);
 
-       if (ictx->rc_type == RC_BIT_RC6_MCE)
+       if (ictx->rc_type == RC_BIT_RC6_MCE ||
+           ictx->dev_descr->flags & IMON_IR_RAW)
                rdev->map_name = RC_MAP_IMON_MCE;
        else
                rdev->map_name = RC_MAP_IMON_PAD;
index d26907e684dc2ba7bcd1e0af846b573c7c4f055d..50951f68685275985515c49841c5402141db006f 100644 (file)
@@ -229,7 +229,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
                return priv->irq;
        }
 
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rdev)
                return -ENOMEM;
 
@@ -242,8 +242,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
        clk_prepare_enable(priv->clock);
        priv->rate = clk_get_rate(priv->clock);
 
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rdev->priv = priv;
        rdev->open = hix5hd2_ir_open;
        rdev->close = hix5hd2_ir_close;
index 182402f7b4d152ae8befc0255b36e32183d0118b..674bf156edcbd4faaa46a6c4d8032f5b6ce03f7e 100644 (file)
@@ -170,9 +170,48 @@ out:
        return -EINVAL;
 }
 
+static const struct ir_raw_timings_pd ir_jvc_timings = {
+       .header_pulse  = JVC_HEADER_PULSE,
+       .header_space  = JVC_HEADER_SPACE,
+       .bit_pulse     = JVC_BIT_PULSE,
+       .bit_space[0]  = JVC_BIT_0_SPACE,
+       .bit_space[1]  = JVC_BIT_1_SPACE,
+       .trailer_pulse = JVC_TRAILER_PULSE,
+       .trailer_space = JVC_TRAILER_SPACE,
+       .msb_first     = 1,
+};
+
+/**
+ * ir_jvc_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ */
+static int ir_jvc_encode(enum rc_type protocol, u32 scancode,
+                        struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_event *e = events;
+       int ret;
+       u32 raw = (bitrev8((scancode >> 8) & 0xff) << 8) |
+                 (bitrev8((scancode >> 0) & 0xff) << 0);
+
+       ret = ir_raw_gen_pd(&e, max, &ir_jvc_timings, JVC_NBITS, raw);
+       if (ret < 0)
+               return ret;
+
+       return e - events;
+}
+
 static struct ir_raw_handler jvc_handler = {
        .protocols      = RC_BIT_JVC,
        .decode         = ir_jvc_decode,
+       .encode         = ir_jvc_encode,
 };
 
 static int __init ir_jvc_decode_init(void)
index c3277308a70b449acd415f946b984e8c8a00901b..8517d5153fcf211606280e5eb4c83ea4837bc4fc 100644 (file)
@@ -204,11 +204,17 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
 
        /* legacy support */
        case LIRC_GET_SEND_MODE:
-               val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
+               if (!dev->tx_ir)
+                       return -ENOTTY;
+
+               val = LIRC_MODE_PULSE;
                break;
 
        case LIRC_SET_SEND_MODE:
-               if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
+               if (!dev->tx_ir)
+                       return -ENOTTY;
+
+               if (val != LIRC_MODE_PULSE)
                        return -EINVAL;
                return 0;
 
@@ -273,7 +279,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
        case LIRC_GET_MIN_TIMEOUT:
                if (!dev->max_timeout)
                        return -ENOSYS;
-               val = dev->min_timeout / 1000;
+               val = DIV_ROUND_UP(dev->min_timeout, 1000);
                break;
 
        case LIRC_GET_MAX_TIMEOUT:
@@ -341,7 +347,7 @@ static int ir_lirc_register(struct rc_dev *dev)
        struct lirc_driver *drv;
        struct lirc_buffer *rbuf;
        int rc = -ENOMEM;
-       unsigned long features;
+       unsigned long features = 0;
 
        drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
        if (!drv)
@@ -355,7 +361,8 @@ static int ir_lirc_register(struct rc_dev *dev)
        if (rc)
                goto rbuf_init_failed;
 
-       features = LIRC_CAN_REC_MODE2;
+       if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+               features |= LIRC_CAN_REC_MODE2;
        if (dev->tx_ir) {
                features |= LIRC_CAN_SEND_PULSE;
                if (dev->s_tx_mask)
index d80986251ee025490ccd01082dfdf8767b5522c2..5226d510e84779f0dcf0cb47372fd0ddd6cee058 100644 (file)
@@ -71,7 +71,7 @@ static unsigned char kbd_keycodes[256] = {
        KEY_6,          KEY_7,          KEY_8,          KEY_9,          KEY_0,
        KEY_ENTER,      KEY_ESC,        KEY_BACKSPACE,  KEY_TAB,        KEY_SPACE,
        KEY_MINUS,      KEY_EQUAL,      KEY_LEFTBRACE,  KEY_RIGHTBRACE, KEY_BACKSLASH,
-       KEY_RESERVED,   KEY_SEMICOLON,  KEY_APOSTROPHE, KEY_GRAVE,      KEY_COMMA,
+       KEY_BACKSLASH,  KEY_SEMICOLON,  KEY_APOSTROPHE, KEY_GRAVE,      KEY_COMMA,
        KEY_DOT,        KEY_SLASH,      KEY_CAPSLOCK,   KEY_F1,         KEY_F2,
        KEY_F3,         KEY_F4,         KEY_F5,         KEY_F6,         KEY_F7,
        KEY_F8,         KEY_F9,         KEY_F10,        KEY_F11,        KEY_F12,
index 2a9d155548ab3a648ce24062b1e8c5d8f1764a0a..3ce850314dcadb54c1829649244763bcdc06d864 100644 (file)
@@ -170,7 +170,10 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
                if (send_32bits) {
                        /* NEC transport, but modified protocol, used by at
                         * least Apple and TiVo remotes */
-                       scancode = data->bits;
+                       scancode = not_address << 24 |
+                               address     << 16 |
+                               not_command <<  8 |
+                               command;
                        IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
                        rc_type = RC_TYPE_NEC32;
                } else if ((address ^ not_address) != 0xff) {
@@ -201,9 +204,90 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
        return -EINVAL;
 }
 
+/**
+ * ir_nec_scancode_to_raw() - encode an NEC scancode ready for modulation.
+ * @protocol:  specific protocol to use
+ * @scancode:  a single NEC scancode.
+ * @raw:       raw data to be modulated.
+ */
+static u32 ir_nec_scancode_to_raw(enum rc_type protocol, u32 scancode)
+{
+       unsigned int addr, addr_inv, data, data_inv;
+
+       data = scancode & 0xff;
+
+       if (protocol == RC_TYPE_NEC32) {
+               /* 32-bit NEC (used by Apple and TiVo remotes) */
+               /* scan encoding: aaAAddDD */
+               addr_inv   = (scancode >> 24) & 0xff;
+               addr       = (scancode >> 16) & 0xff;
+               data_inv   = (scancode >>  8) & 0xff;
+       } else if (protocol == RC_TYPE_NECX) {
+               /* Extended NEC */
+               /* scan encoding AAaaDD */
+               addr       = (scancode >> 16) & 0xff;
+               addr_inv   = (scancode >>  8) & 0xff;
+               data_inv   = data ^ 0xff;
+       } else {
+               /* Normal NEC */
+               /* scan encoding: AADD */
+               addr       = (scancode >>  8) & 0xff;
+               addr_inv   = addr ^ 0xff;
+               data_inv   = data ^ 0xff;
+       }
+
+       /* raw encoding: ddDDaaAA */
+       return data_inv << 24 |
+              data     << 16 |
+              addr_inv <<  8 |
+              addr;
+}
+
+static const struct ir_raw_timings_pd ir_nec_timings = {
+       .header_pulse   = NEC_HEADER_PULSE,
+       .header_space   = NEC_HEADER_SPACE,
+       .bit_pulse      = NEC_BIT_PULSE,
+       .bit_space[0]   = NEC_BIT_0_SPACE,
+       .bit_space[1]   = NEC_BIT_1_SPACE,
+       .trailer_pulse  = NEC_TRAILER_PULSE,
+       .trailer_space  = NEC_TRAILER_SPACE,
+       .msb_first      = 0,
+};
+
+/**
+ * ir_nec_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ */
+static int ir_nec_encode(enum rc_type protocol, u32 scancode,
+                        struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_event *e = events;
+       int ret;
+       u32 raw;
+
+       /* Convert a NEC scancode to raw NEC data */
+       raw = ir_nec_scancode_to_raw(protocol, scancode);
+
+       /* Modulate the raw data using a pulse distance modulation */
+       ret = ir_raw_gen_pd(&e, max, &ir_nec_timings, NEC_NBITS, raw);
+       if (ret < 0)
+               return ret;
+
+       return e - events;
+}
+
 static struct ir_raw_handler nec_handler = {
        .protocols      = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32,
        .decode         = ir_nec_decode,
+       .encode         = ir_nec_encode,
 };
 
 static int __init ir_nec_decode_init(void)
index a0fd4e6b2155b81e0605e58db2225d70cdf54fc1..fcfedf95def72a3dc9ffdd70d2a025210b8ea26f 100644 (file)
@@ -124,7 +124,7 @@ again:
                if (data->is_rc5x && data->count == RC5X_NBITS) {
                        /* RC5X */
                        u8 xdata, command, system;
-                       if (!(dev->enabled_protocols & RC_BIT_RC5X)) {
+                       if (!(dev->enabled_protocols & RC_BIT_RC5X_20)) {
                                data->state = STATE_INACTIVE;
                                return 0;
                        }
@@ -132,9 +132,9 @@ again:
                        command  = (data->bits & 0x00FC0) >> 6;
                        system   = (data->bits & 0x1F000) >> 12;
                        toggle   = (data->bits & 0x20000) ? 1 : 0;
-                       command += (data->bits & 0x01000) ? 0 : 0x40;
+                       command += (data->bits & 0x40000) ? 0 : 0x40;
                        scancode = system << 16 | command << 8 | xdata;
-                       protocol = RC_TYPE_RC5X;
+                       protocol = RC_TYPE_RC5X_20;
 
                } else if (!data->is_rc5x && data->count == RC5_NBITS) {
                        /* RC5 */
@@ -181,9 +181,106 @@ out:
        return -EINVAL;
 }
 
+static const struct ir_raw_timings_manchester ir_rc5_timings = {
+       .leader                 = RC5_UNIT,
+       .pulse_space_start      = 0,
+       .clock                  = RC5_UNIT,
+       .trailer_space          = RC5_UNIT * 10,
+};
+
+static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
+       {
+               .leader                 = RC5_UNIT,
+               .pulse_space_start      = 0,
+               .clock                  = RC5_UNIT,
+               .trailer_space          = RC5X_SPACE,
+       },
+       {
+               .clock                  = RC5_UNIT,
+               .trailer_space          = RC5_UNIT * 10,
+       },
+};
+
+static const struct ir_raw_timings_manchester ir_rc5_sz_timings = {
+       .leader                         = RC5_UNIT,
+       .pulse_space_start              = 0,
+       .clock                          = RC5_UNIT,
+       .trailer_space                  = RC5_UNIT * 10,
+};
+
+/**
+ * ir_rc5_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol variant to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ *             -EINVAL if the scancode is ambiguous or invalid.
+ */
+static int ir_rc5_encode(enum rc_type protocol, u32 scancode,
+                        struct ir_raw_event *events, unsigned int max)
+{
+       int ret;
+       struct ir_raw_event *e = events;
+       unsigned int data, xdata, command, commandx, system, pre_space_data;
+
+       /* Detect protocol and convert scancode to raw data */
+       if (protocol == RC_TYPE_RC5) {
+               /* decode scancode */
+               command  = (scancode & 0x003f) >> 0;
+               commandx = (scancode & 0x0040) >> 6;
+               system   = (scancode & 0x1f00) >> 8;
+               /* encode data */
+               data = !commandx << 12 | system << 6 | command;
+
+               /* Modulate the data */
+               ret = ir_raw_gen_manchester(&e, max, &ir_rc5_timings,
+                                           RC5_NBITS, data);
+               if (ret < 0)
+                       return ret;
+       } else if (protocol == RC_TYPE_RC5X_20) {
+               /* decode scancode */
+               xdata    = (scancode & 0x00003f) >> 0;
+               command  = (scancode & 0x003f00) >> 8;
+               commandx = !(scancode & 0x004000);
+               system   = (scancode & 0x1f0000) >> 16;
+
+               /* encode data */
+               data = commandx << 18 | system << 12 | command << 6 | xdata;
+
+               /* Modulate the data */
+               pre_space_data = data >> (RC5X_NBITS - CHECK_RC5X_NBITS);
+               ret = ir_raw_gen_manchester(&e, max, &ir_rc5x_timings[0],
+                                           CHECK_RC5X_NBITS, pre_space_data);
+               if (ret < 0)
+                       return ret;
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc5x_timings[1],
+                                           RC5X_NBITS - CHECK_RC5X_NBITS,
+                                           data);
+               if (ret < 0)
+                       return ret;
+       } else if (protocol == RC_TYPE_RC5_SZ) {
+               /* RC5-SZ scancode is raw enough for Manchester as it is */
+               ret = ir_raw_gen_manchester(&e, max, &ir_rc5_sz_timings,
+                                           RC5_SZ_NBITS, scancode & 0x2fff);
+               if (ret < 0)
+                       return ret;
+       } else {
+               return -EINVAL;
+       }
+
+       return e - events;
+}
+
 static struct ir_raw_handler rc5_handler = {
-       .protocols      = RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ,
+       .protocols      = RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ,
        .decode         = ir_rc5_decode,
+       .encode         = ir_rc5_encode,
 };
 
 static int __init ir_rc5_decode_init(void)
index 5cc54c967a80dd8ad29eb3eb50db437568bd073c..6fe2268dada0c938dcd8eaf82ee1edc8ee032a31 100644 (file)
@@ -286,11 +286,128 @@ out:
        return -EINVAL;
 }
 
+static const struct ir_raw_timings_manchester ir_rc6_timings[4] = {
+       {
+               .leader                 = RC6_PREFIX_PULSE,
+               .pulse_space_start      = 0,
+               .clock                  = RC6_UNIT,
+               .invert                 = 1,
+               .trailer_space          = RC6_PREFIX_SPACE,
+       },
+       {
+               .clock                  = RC6_UNIT,
+               .invert                 = 1,
+       },
+       {
+               .clock                  = RC6_UNIT * 2,
+               .invert                 = 1,
+       },
+       {
+               .clock                  = RC6_UNIT,
+               .invert                 = 1,
+               .trailer_space          = RC6_SUFFIX_SPACE,
+       },
+};
+
+/**
+ * ir_rc6_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ *             -EINVAL if the scancode is ambiguous or invalid.
+ */
+static int ir_rc6_encode(enum rc_type protocol, u32 scancode,
+                        struct ir_raw_event *events, unsigned int max)
+{
+       int ret;
+       struct ir_raw_event *e = events;
+
+       if (protocol == RC_TYPE_RC6_0) {
+               /* Modulate the preamble */
+               ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
+               if (ret < 0)
+                       return ret;
+
+               /* Modulate the header (Start Bit & Mode-0) */
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc6_timings[1],
+                                           RC6_HEADER_NBITS, (1 << 3));
+               if (ret < 0)
+                       return ret;
+
+               /* Modulate Trailer Bit */
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc6_timings[2], 1, 0);
+               if (ret < 0)
+                       return ret;
+
+               /* Modulate rest of the data */
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc6_timings[3], RC6_0_NBITS,
+                                           scancode);
+               if (ret < 0)
+                       return ret;
+
+       } else {
+               int bits;
+
+               switch (protocol) {
+               case RC_TYPE_RC6_MCE:
+               case RC_TYPE_RC6_6A_32:
+                       bits = 32;
+                       break;
+               case RC_TYPE_RC6_6A_24:
+                       bits = 24;
+                       break;
+               case RC_TYPE_RC6_6A_20:
+                       bits = 20;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               /* Modulate the preamble */
+               ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
+               if (ret < 0)
+                       return ret;
+
+               /* Modulate the header (Start Bit & Header-version 6 */
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc6_timings[1],
+                                           RC6_HEADER_NBITS, (1 << 3 | 6));
+               if (ret < 0)
+                       return ret;
+
+               /* Modulate Trailer Bit */
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc6_timings[2], 1, 0);
+               if (ret < 0)
+                       return ret;
+
+               /* Modulate rest of the data */
+               ret = ir_raw_gen_manchester(&e, max - (e - events),
+                                           &ir_rc6_timings[3],
+                                           bits,
+                                           scancode);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return e - events;
+}
+
 static struct ir_raw_handler rc6_handler = {
        .protocols      = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 |
                          RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 |
                          RC_BIT_RC6_MCE,
        .decode         = ir_rc6_decode,
+       .encode         = ir_rc6_encode,
 };
 
 static int __init ir_rc6_decode_init(void)
index e6efa8c267a062b0aa28b7912e0999ac57ce7e9a..49265f02e772b471b9c3bbb7b49af03bc2dc21d1 100644 (file)
  */
 #include <linux/clk.h>
 #include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
 #include <linux/platform_device.h>
-#include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/pwm.h>
 #include <linux/of.h>
 #include <linux/hrtimer.h>
 
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
+#include <media/rc-core.h>
 #include <linux/platform_data/media/ir-rx51.h>
 
-#define LIRC_RX51_DRIVER_FEATURES (LIRC_CAN_SET_SEND_DUTY_CYCLE |      \
-                                  LIRC_CAN_SET_SEND_CARRIER |          \
-                                  LIRC_CAN_SEND_PULSE)
-
-#define DRIVER_NAME "lirc_rx51"
-
 #define WBUF_LEN 256
 
-struct lirc_rx51 {
+struct ir_rx51 {
+       struct rc_dev *rcdev;
        struct pwm_device *pwm;
        struct hrtimer timer;
        struct device        *dev;
-       struct lirc_rx51_platform_data *pdata;
+       struct ir_rx51_platform_data *pdata;
        wait_queue_head_t     wqueue;
 
        unsigned int    freq;           /* carrier frequency */
@@ -50,38 +41,37 @@ struct lirc_rx51 {
        unsigned long   device_is_open;
 };
 
-static inline void lirc_rx51_on(struct lirc_rx51 *lirc_rx51)
+static inline void ir_rx51_on(struct ir_rx51 *ir_rx51)
 {
-       pwm_enable(lirc_rx51->pwm);
+       pwm_enable(ir_rx51->pwm);
 }
 
-static inline void lirc_rx51_off(struct lirc_rx51 *lirc_rx51)
+static inline void ir_rx51_off(struct ir_rx51 *ir_rx51)
 {
-       pwm_disable(lirc_rx51->pwm);
+       pwm_disable(ir_rx51->pwm);
 }
 
-static int init_timing_params(struct lirc_rx51 *lirc_rx51)
+static int init_timing_params(struct ir_rx51 *ir_rx51)
 {
-       struct pwm_device *pwm = lirc_rx51->pwm;
-       int duty, period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, lirc_rx51->freq);
+       struct pwm_device *pwm = ir_rx51->pwm;
+       int duty, period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, ir_rx51->freq);
 
-       duty = DIV_ROUND_CLOSEST(lirc_rx51->duty_cycle * period, 100);
+       duty = DIV_ROUND_CLOSEST(ir_rx51->duty_cycle * period, 100);
 
        pwm_config(pwm, duty, period);
 
        return 0;
 }
 
-static enum hrtimer_restart lirc_rx51_timer_cb(struct hrtimer *timer)
+static enum hrtimer_restart ir_rx51_timer_cb(struct hrtimer *timer)
 {
-       struct lirc_rx51 *lirc_rx51 =
-                       container_of(timer, struct lirc_rx51, timer);
+       struct ir_rx51 *ir_rx51 = container_of(timer, struct ir_rx51, timer);
        ktime_t now;
 
-       if (lirc_rx51->wbuf_index < 0) {
-               dev_err_ratelimited(lirc_rx51->dev,
-                               "BUG wbuf_index has value of %i\n",
-                               lirc_rx51->wbuf_index);
+       if (ir_rx51->wbuf_index < 0) {
+               dev_err_ratelimited(ir_rx51->dev,
+                                   "BUG wbuf_index has value of %i\n",
+                                   ir_rx51->wbuf_index);
                goto end;
        }
 
@@ -92,20 +82,20 @@ static enum hrtimer_restart lirc_rx51_timer_cb(struct hrtimer *timer)
        do {
                u64 ns;
 
-               if (lirc_rx51->wbuf_index >= WBUF_LEN)
+               if (ir_rx51->wbuf_index >= WBUF_LEN)
                        goto end;
-               if (lirc_rx51->wbuf[lirc_rx51->wbuf_index] == -1)
+               if (ir_rx51->wbuf[ir_rx51->wbuf_index] == -1)
                        goto end;
 
-               if (lirc_rx51->wbuf_index % 2)
-                       lirc_rx51_off(lirc_rx51);
+               if (ir_rx51->wbuf_index % 2)
+                       ir_rx51_off(ir_rx51);
                else
-                       lirc_rx51_on(lirc_rx51);
+                       ir_rx51_on(ir_rx51);
 
-               ns = 1000 * lirc_rx51->wbuf[lirc_rx51->wbuf_index];
+               ns = US_TO_NS(ir_rx51->wbuf[ir_rx51->wbuf_index]);
                hrtimer_add_expires_ns(timer, ns);
 
-               lirc_rx51->wbuf_index++;
+               ir_rx51->wbuf_index++;
 
                now = timer->base->get_time();
 
@@ -114,203 +104,112 @@ static enum hrtimer_restart lirc_rx51_timer_cb(struct hrtimer *timer)
        return HRTIMER_RESTART;
 end:
        /* Stop TX here */
-       lirc_rx51_off(lirc_rx51);
-       lirc_rx51->wbuf_index = -1;
+       ir_rx51_off(ir_rx51);
+       ir_rx51->wbuf_index = -1;
 
-       wake_up_interruptible(&lirc_rx51->wqueue);
+       wake_up_interruptible(&ir_rx51->wqueue);
 
        return HRTIMER_NORESTART;
 }
 
-static ssize_t lirc_rx51_write(struct file *file, const char *buf,
-                         size_t n, loff_t *ppos)
+static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer,
+                     unsigned int count)
 {
-       int count, i;
-       struct lirc_rx51 *lirc_rx51 = file->private_data;
+       struct ir_rx51 *ir_rx51 = dev->priv;
 
-       if (n % sizeof(int))
+       if (count > WBUF_LEN)
                return -EINVAL;
 
-       count = n / sizeof(int);
-       if ((count > WBUF_LEN) || (count % 2 == 0))
-               return -EINVAL;
+       memcpy(ir_rx51->wbuf, buffer, count * sizeof(unsigned int));
 
        /* Wait any pending transfers to finish */
-       wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);
-
-       if (copy_from_user(lirc_rx51->wbuf, buf, n))
-               return -EFAULT;
-
-       /* Sanity check the input pulses */
-       for (i = 0; i < count; i++)
-               if (lirc_rx51->wbuf[i] < 0)
-                       return -EINVAL;
+       wait_event_interruptible(ir_rx51->wqueue, ir_rx51->wbuf_index < 0);
 
-       init_timing_params(lirc_rx51);
+       init_timing_params(ir_rx51);
        if (count < WBUF_LEN)
-               lirc_rx51->wbuf[count] = -1; /* Insert termination mark */
+               ir_rx51->wbuf[count] = -1; /* Insert termination mark */
 
        /*
         * Adjust latency requirements so the device doesn't go in too
         * deep sleep states
         */
-       lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, 50);
+       ir_rx51->pdata->set_max_mpu_wakeup_lat(ir_rx51->dev, 50);
 
-       lirc_rx51_on(lirc_rx51);
-       lirc_rx51->wbuf_index = 1;
-       hrtimer_start(&lirc_rx51->timer,
-                     ns_to_ktime(1000 * lirc_rx51->wbuf[0]),
+       ir_rx51_on(ir_rx51);
+       ir_rx51->wbuf_index = 1;
+       hrtimer_start(&ir_rx51->timer,
+                     ns_to_ktime(US_TO_NS(ir_rx51->wbuf[0])),
                      HRTIMER_MODE_REL);
        /*
         * Don't return back to the userspace until the transfer has
         * finished
         */
-       wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);
+       wait_event_interruptible(ir_rx51->wqueue, ir_rx51->wbuf_index < 0);
 
        /* We can sleep again */
-       lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, -1);
+       ir_rx51->pdata->set_max_mpu_wakeup_lat(ir_rx51->dev, -1);
 
-       return n;
+       return count;
 }
 
-static long lirc_rx51_ioctl(struct file *filep,
-                       unsigned int cmd, unsigned long arg)
+static int ir_rx51_open(struct rc_dev *dev)
 {
-       int result;
-       unsigned long value;
-       unsigned int ivalue;
-       struct lirc_rx51 *lirc_rx51 = filep->private_data;
-
-       switch (cmd) {
-       case LIRC_GET_SEND_MODE:
-               result = put_user(LIRC_MODE_PULSE, (unsigned long *)arg);
-               if (result)
-                       return result;
-               break;
-
-       case LIRC_SET_SEND_MODE:
-               result = get_user(value, (unsigned long *)arg);
-               if (result)
-                       return result;
-
-               /* only LIRC_MODE_PULSE supported */
-               if (value != LIRC_MODE_PULSE)
-                       return -ENOSYS;
-               break;
-
-       case LIRC_GET_REC_MODE:
-               result = put_user(0, (unsigned long *) arg);
-               if (result)
-                       return result;
-               break;
-
-       case LIRC_GET_LENGTH:
-               return -ENOSYS;
-               break;
-
-       case LIRC_SET_SEND_DUTY_CYCLE:
-               result = get_user(ivalue, (unsigned int *) arg);
-               if (result)
-                       return result;
-
-               if (ivalue <= 0 || ivalue > 100) {
-                       dev_err(lirc_rx51->dev, ": invalid duty cycle %d\n",
-                               ivalue);
-                       return -EINVAL;
-               }
-
-               lirc_rx51->duty_cycle = ivalue;
-               break;
-
-       case LIRC_SET_SEND_CARRIER:
-               result = get_user(ivalue, (unsigned int *) arg);
-               if (result)
-                       return result;
-
-               if (ivalue > 500000 || ivalue < 20000) {
-                       dev_err(lirc_rx51->dev, ": invalid carrier freq %d\n",
-                               ivalue);
-                       return -EINVAL;
-               }
-
-               lirc_rx51->freq = ivalue;
-               break;
-
-       case LIRC_GET_FEATURES:
-               result = put_user(LIRC_RX51_DRIVER_FEATURES,
-                                 (unsigned long *) arg);
-               if (result)
-                       return result;
-               break;
-
-       default:
-               return -ENOIOCTLCMD;
-       }
-
-       return 0;
-}
+       struct ir_rx51 *ir_rx51 = dev->priv;
 
-static int lirc_rx51_open(struct inode *inode, struct file *file)
-{
-       struct lirc_rx51 *lirc_rx51 = lirc_get_pdata(file);
-       BUG_ON(!lirc_rx51);
-
-       file->private_data = lirc_rx51;
-
-       if (test_and_set_bit(1, &lirc_rx51->device_is_open))
+       if (test_and_set_bit(1, &ir_rx51->device_is_open))
                return -EBUSY;
 
-       lirc_rx51->pwm = pwm_get(lirc_rx51->dev, NULL);
-       if (IS_ERR(lirc_rx51->pwm)) {
-               int res = PTR_ERR(lirc_rx51->pwm);
+       ir_rx51->pwm = pwm_get(ir_rx51->dev, NULL);
+       if (IS_ERR(ir_rx51->pwm)) {
+               int res = PTR_ERR(ir_rx51->pwm);
 
-               dev_err(lirc_rx51->dev, "pwm_get failed: %d\n", res);
+               dev_err(ir_rx51->dev, "pwm_get failed: %d\n", res);
                return res;
        }
 
        return 0;
 }
 
-static int lirc_rx51_release(struct inode *inode, struct file *file)
+static void ir_rx51_release(struct rc_dev *dev)
 {
-       struct lirc_rx51 *lirc_rx51 = file->private_data;
-
-       hrtimer_cancel(&lirc_rx51->timer);
-       lirc_rx51_off(lirc_rx51);
-       pwm_put(lirc_rx51->pwm);
+       struct ir_rx51 *ir_rx51 = dev->priv;
 
-       clear_bit(1, &lirc_rx51->device_is_open);
+       hrtimer_cancel(&ir_rx51->timer);
+       ir_rx51_off(ir_rx51);
+       pwm_put(ir_rx51->pwm);
 
-       return 0;
+       clear_bit(1, &ir_rx51->device_is_open);
 }
 
-static struct lirc_rx51 lirc_rx51 = {
+static struct ir_rx51 ir_rx51 = {
        .duty_cycle     = 50,
        .wbuf_index     = -1,
 };
 
-static const struct file_operations lirc_fops = {
-       .owner          = THIS_MODULE,
-       .write          = lirc_rx51_write,
-       .unlocked_ioctl = lirc_rx51_ioctl,
-       .read           = lirc_dev_fop_read,
-       .poll           = lirc_dev_fop_poll,
-       .open           = lirc_rx51_open,
-       .release        = lirc_rx51_release,
-};
+static int ir_rx51_set_duty_cycle(struct rc_dev *dev, u32 duty)
+{
+       struct ir_rx51 *ir_rx51 = dev->priv;
 
-static struct lirc_driver lirc_rx51_driver = {
-       .name           = DRIVER_NAME,
-       .minor          = -1,
-       .code_length    = 1,
-       .data           = &lirc_rx51,
-       .fops           = &lirc_fops,
-       .owner          = THIS_MODULE,
-};
+       ir_rx51->duty_cycle = duty;
+
+       return 0;
+}
+
+static int ir_rx51_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+       struct ir_rx51 *ir_rx51 = dev->priv;
+
+       if (carrier > 500000 || carrier < 20000)
+               return -EINVAL;
+
+       ir_rx51->freq = carrier;
+
+       return 0;
+}
 
 #ifdef CONFIG_PM
 
-static int lirc_rx51_suspend(struct platform_device *dev, pm_message_t state)
+static int ir_rx51_suspend(struct platform_device *dev, pm_message_t state)
 {
        /*
         * In case the device is still open, do not suspend. Normally
@@ -320,34 +219,34 @@ static int lirc_rx51_suspend(struct platform_device *dev, pm_message_t state)
         * were in a middle of a transmit. Thus, we defer any suspend
         * actions until transmit has completed.
         */
-       if (test_and_set_bit(1, &lirc_rx51.device_is_open))
+       if (test_and_set_bit(1, &ir_rx51.device_is_open))
                return -EAGAIN;
 
-       clear_bit(1, &lirc_rx51.device_is_open);
+       clear_bit(1, &ir_rx51.device_is_open);
 
        return 0;
 }
 
-static int lirc_rx51_resume(struct platform_device *dev)
+static int ir_rx51_resume(struct platform_device *dev)
 {
        return 0;
 }
 
 #else
 
-#define lirc_rx51_suspend      NULL
-#define lirc_rx51_resume       NULL
+#define ir_rx51_suspend        NULL
+#define ir_rx51_resume NULL
 
 #endif /* CONFIG_PM */
 
-static int lirc_rx51_probe(struct platform_device *dev)
+static int ir_rx51_probe(struct platform_device *dev)
 {
        struct pwm_device *pwm;
+       struct rc_dev *rcdev;
 
-       lirc_rx51_driver.features = LIRC_RX51_DRIVER_FEATURES;
-       lirc_rx51.pdata = dev->dev.platform_data;
+       ir_rx51.pdata = dev->dev.platform_data;
 
-       if (!lirc_rx51.pdata) {
+       if (!ir_rx51.pdata) {
                dev_err(&dev->dev, "Platform Data is missing\n");
                return -ENXIO;
        }
@@ -362,51 +261,56 @@ static int lirc_rx51_probe(struct platform_device *dev)
        }
 
        /* Use default, in case userspace does not set the carrier */
-       lirc_rx51.freq = DIV_ROUND_CLOSEST(pwm_get_period(pwm), NSEC_PER_SEC);
+       ir_rx51.freq = DIV_ROUND_CLOSEST(pwm_get_period(pwm), NSEC_PER_SEC);
        pwm_put(pwm);
 
-       hrtimer_init(&lirc_rx51.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-       lirc_rx51.timer.function = lirc_rx51_timer_cb;
+       hrtimer_init(&ir_rx51.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       ir_rx51.timer.function = ir_rx51_timer_cb;
 
-       lirc_rx51.dev = &dev->dev;
-       lirc_rx51_driver.dev = &dev->dev;
-       lirc_rx51_driver.minor = lirc_register_driver(&lirc_rx51_driver);
-       init_waitqueue_head(&lirc_rx51.wqueue);
+       ir_rx51.dev = &dev->dev;
 
-       if (lirc_rx51_driver.minor < 0) {
-               dev_err(lirc_rx51.dev, ": lirc_register_driver failed: %d\n",
-                      lirc_rx51_driver.minor);
-               return lirc_rx51_driver.minor;
-       }
+       rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW_TX);
+       if (!rcdev)
+               return -ENOMEM;
 
-       return 0;
+       rcdev->priv = &ir_rx51;
+       rcdev->open = ir_rx51_open;
+       rcdev->close = ir_rx51_release;
+       rcdev->tx_ir = ir_rx51_tx;
+       rcdev->s_tx_duty_cycle = ir_rx51_set_duty_cycle;
+       rcdev->s_tx_carrier = ir_rx51_set_tx_carrier;
+       rcdev->driver_name = KBUILD_MODNAME;
+
+       ir_rx51.rcdev = rcdev;
+
+       return devm_rc_register_device(&dev->dev, ir_rx51.rcdev);
 }
 
-static int lirc_rx51_remove(struct platform_device *dev)
+static int ir_rx51_remove(struct platform_device *dev)
 {
-       return lirc_unregister_driver(lirc_rx51_driver.minor);
+       return 0;
 }
 
-static const struct of_device_id lirc_rx51_match[] = {
+static const struct of_device_id ir_rx51_match[] = {
        {
                .compatible = "nokia,n900-ir",
        },
        {},
 };
-MODULE_DEVICE_TABLE(of, lirc_rx51_match);
+MODULE_DEVICE_TABLE(of, ir_rx51_match);
 
-struct platform_driver lirc_rx51_platform_driver = {
-       .probe          = lirc_rx51_probe,
-       .remove         = lirc_rx51_remove,
-       .suspend        = lirc_rx51_suspend,
-       .resume         = lirc_rx51_resume,
+static struct platform_driver ir_rx51_platform_driver = {
+       .probe          = ir_rx51_probe,
+       .remove         = ir_rx51_remove,
+       .suspend        = ir_rx51_suspend,
+       .resume         = ir_rx51_resume,
        .driver         = {
-               .name   = DRIVER_NAME,
-               .of_match_table = of_match_ptr(lirc_rx51_match),
+               .name   = KBUILD_MODNAME,
+               .of_match_table = of_match_ptr(ir_rx51_match),
        },
 };
-module_platform_driver(lirc_rx51_platform_driver);
+module_platform_driver(ir_rx51_platform_driver);
 
-MODULE_DESCRIPTION("LIRC TX driver for Nokia RX51");
+MODULE_DESCRIPTION("IR TX driver for Nokia RX51");
 MODULE_AUTHOR("Nokia Corporation");
 MODULE_LICENSE("GPL");
index b07d9caebeb1d5c8c515e61f6163686eea54c46c..520bb77dcb62b31ba2915fc4b673365d69113c70 100644 (file)
@@ -176,9 +176,52 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
        return -EINVAL;
 }
 
+static const struct ir_raw_timings_pd ir_sanyo_timings = {
+       .header_pulse  = SANYO_HEADER_PULSE,
+       .header_space  = SANYO_HEADER_SPACE,
+       .bit_pulse     = SANYO_BIT_PULSE,
+       .bit_space[0]  = SANYO_BIT_0_SPACE,
+       .bit_space[1]  = SANYO_BIT_1_SPACE,
+       .trailer_pulse = SANYO_TRAILER_PULSE,
+       .trailer_space = SANYO_TRAILER_SPACE,
+       .msb_first     = 1,
+};
+
+/**
+ * ir_sanyo_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ */
+static int ir_sanyo_encode(enum rc_type protocol, u32 scancode,
+                          struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_event *e = events;
+       int ret;
+       u64 raw;
+
+       raw = ((u64)(bitrev16(scancode >> 8) & 0xfff8) << (8 + 8 + 13 - 3)) |
+             ((u64)(bitrev16(~scancode >> 8) & 0xfff8) << (8 + 8 +  0 - 3)) |
+             ((bitrev8(scancode) & 0xff) << 8) |
+             (bitrev8(~scancode) & 0xff);
+
+       ret = ir_raw_gen_pd(&e, max, &ir_sanyo_timings, SANYO_NBITS, raw);
+       if (ret < 0)
+               return ret;
+
+       return e - events;
+}
+
 static struct ir_raw_handler sanyo_handler = {
        .protocols      = RC_BIT_SANYO,
        .decode         = ir_sanyo_decode,
+       .encode         = ir_sanyo_encode,
 };
 
 static int __init ir_sanyo_decode_init(void)
index 317677f06f2c6e147d380bd3b4705df5e99224fe..b47e89e2c1bd1d6a2d347fd1c17451e798adf50d 100644 (file)
@@ -173,9 +173,59 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev)
        return -EINVAL;
 }
 
+static const struct ir_raw_timings_pd ir_sharp_timings = {
+       .header_pulse  = 0,
+       .header_space  = 0,
+       .bit_pulse     = SHARP_BIT_PULSE,
+       .bit_space[0]  = SHARP_BIT_0_PERIOD,
+       .bit_space[1]  = SHARP_BIT_1_PERIOD,
+       .trailer_pulse = SHARP_BIT_PULSE,
+       .trailer_space = SHARP_ECHO_SPACE,
+       .msb_first     = 1,
+};
+
+/**
+ * ir_sharp_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ */
+static int ir_sharp_encode(enum rc_type protocol, u32 scancode,
+                          struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_event *e = events;
+       int ret;
+       u32 raw;
+
+       raw = (((bitrev8(scancode >> 8) >> 3) << 8) & 0x1f00) |
+               bitrev8(scancode);
+       ret = ir_raw_gen_pd(&e, max, &ir_sharp_timings, SHARP_NBITS,
+                           (raw << 2) | 2);
+       if (ret < 0)
+               return ret;
+
+       max -= ret;
+
+       raw = (((bitrev8(scancode >> 8) >> 3) << 8) & 0x1f00) |
+               bitrev8(~scancode);
+       ret = ir_raw_gen_pd(&e, max, &ir_sharp_timings, SHARP_NBITS,
+                           (raw << 2) | 1);
+       if (ret < 0)
+               return ret;
+
+       return e - events;
+}
+
 static struct ir_raw_handler sharp_handler = {
        .protocols      = RC_BIT_SHARP,
        .decode         = ir_sharp_decode,
+       .encode         = ir_sharp_encode,
 };
 
 static int __init ir_sharp_decode_init(void)
index baa972c76e0e19a5f0b5651310df2c93daf0e8fa..355fa8198f5a12c9534eaba2b48dbd956cd0a5d3 100644 (file)
@@ -169,9 +169,57 @@ finish_state_machine:
        return 0;
 }
 
+static const struct ir_raw_timings_pl ir_sony_timings = {
+       .header_pulse  = SONY_HEADER_PULSE,
+       .bit_space     = SONY_BIT_SPACE,
+       .bit_pulse[0]  = SONY_BIT_0_PULSE,
+       .bit_pulse[1]  = SONY_BIT_1_PULSE,
+       .trailer_space = SONY_TRAILER_SPACE + SONY_BIT_SPACE,
+       .msb_first     = 0,
+};
+
+/**
+ * ir_sony_encode() - Encode a scancode as a stream of raw events
+ *
+ * @protocol:  protocol to encode
+ * @scancode:  scancode to encode
+ * @events:    array of raw ir events to write into
+ * @max:       maximum size of @events
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ */
+static int ir_sony_encode(enum rc_type protocol, u32 scancode,
+                         struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_event *e = events;
+       u32 raw, len;
+       int ret;
+
+       if (protocol == RC_TYPE_SONY12) {
+               raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9);
+               len = 12;
+       } else if (protocol == RC_TYPE_SONY15) {
+               raw = (scancode & 0x7f) | ((scancode & 0xff0000) >> 9);
+               len = 15;
+       } else {
+               raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9) |
+                      ((scancode & 0xff00) << 4);
+               len = 20;
+       }
+
+       ret = ir_raw_gen_pl(&e, max, &ir_sony_timings, len, raw);
+       if (ret < 0)
+               return ret;
+
+       return e - events;
+}
+
 static struct ir_raw_handler sony_handler = {
        .protocols      = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
        .decode         = ir_sony_decode,
+       .encode         = ir_sony_encode,
 };
 
 static int __init ir_sony_decode_init(void)
diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c
new file mode 100644 (file)
index 0000000..c8863f3
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Author: Andi Shyti <andi.shyti@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * SPI driven IR LED device driver
+ */
+
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <media/rc-core.h>
+
+#define IR_SPI_DRIVER_NAME             "ir-spi"
+
+/* pulse value for different duty cycles */
+#define IR_SPI_PULSE_DC_50             0xff00
+#define IR_SPI_PULSE_DC_60             0xfc00
+#define IR_SPI_PULSE_DC_70             0xf800
+#define IR_SPI_PULSE_DC_75             0xf000
+#define IR_SPI_PULSE_DC_80             0xc000
+#define IR_SPI_PULSE_DC_90             0x8000
+
+#define IR_SPI_DEFAULT_FREQUENCY       38000
+#define IR_SPI_BIT_PER_WORD                8
+#define IR_SPI_MAX_BUFSIZE              4096
+
+struct ir_spi_data {
+       u32 freq;
+       u8 duty_cycle;
+       bool negated;
+
+       u16 tx_buf[IR_SPI_MAX_BUFSIZE];
+       u16 pulse;
+       u16 space;
+
+       struct rc_dev *rc;
+       struct spi_device *spi;
+       struct regulator *regulator;
+};
+
+static int ir_spi_tx(struct rc_dev *dev,
+                    unsigned int *buffer, unsigned int count)
+{
+       int i;
+       int ret;
+       unsigned int len = 0;
+       struct ir_spi_data *idata = dev->priv;
+       struct spi_transfer xfer;
+
+       /* convert the pulse/space signal to raw binary signal */
+       for (i = 0; i < count; i++) {
+               int j;
+               u16 val = ((i + 1) % 2) ? idata->pulse : idata->space;
+
+               if (len + buffer[i] >= IR_SPI_MAX_BUFSIZE)
+                       return -EINVAL;
+
+               /*
+                * the first value in buffer is a pulse, so that 0, 2, 4, ...
+                * contain a pulse duration. On the contrary, 1, 3, 5, ...
+                * contain a space duration.
+                */
+               val = (i % 2) ? idata->space : idata->pulse;
+               for (j = 0; j < buffer[i]; j++)
+                       idata->tx_buf[len++] = val;
+       }
+
+       memset(&xfer, 0, sizeof(xfer));
+
+       xfer.speed_hz = idata->freq;
+       xfer.len = len * sizeof(*idata->tx_buf);
+       xfer.tx_buf = idata->tx_buf;
+
+       ret = regulator_enable(idata->regulator);
+       if (ret)
+               return ret;
+
+       ret = spi_sync_transfer(idata->spi, &xfer, 1);
+       if (ret)
+               dev_err(&idata->spi->dev, "unable to deliver the signal\n");
+
+       regulator_disable(idata->regulator);
+
+       return ret ? ret : count;
+}
+
+static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+       struct ir_spi_data *idata = dev->priv;
+
+       if (!carrier)
+               return -EINVAL;
+
+       idata->freq = carrier;
+
+       return 0;
+}
+
+static int ir_spi_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
+{
+       struct ir_spi_data *idata = dev->priv;
+
+       if (duty_cycle >= 90)
+               idata->pulse = IR_SPI_PULSE_DC_90;
+       else if (duty_cycle >= 80)
+               idata->pulse = IR_SPI_PULSE_DC_80;
+       else if (duty_cycle >= 75)
+               idata->pulse = IR_SPI_PULSE_DC_75;
+       else if (duty_cycle >= 70)
+               idata->pulse = IR_SPI_PULSE_DC_70;
+       else if (duty_cycle >= 60)
+               idata->pulse = IR_SPI_PULSE_DC_60;
+       else
+               idata->pulse = IR_SPI_PULSE_DC_50;
+
+       if (idata->negated) {
+               idata->pulse = ~idata->pulse;
+               idata->space = 0xffff;
+       } else {
+               idata->space = 0;
+       }
+
+       return 0;
+}
+
+static int ir_spi_probe(struct spi_device *spi)
+{
+       int ret;
+       u8 dc;
+       struct ir_spi_data *idata;
+
+       idata = devm_kzalloc(&spi->dev, sizeof(*idata), GFP_KERNEL);
+       if (!idata)
+               return -ENOMEM;
+
+       idata->regulator = devm_regulator_get(&spi->dev, "irda_regulator");
+       if (IS_ERR(idata->regulator))
+               return PTR_ERR(idata->regulator);
+
+       idata->rc = devm_rc_allocate_device(&spi->dev, RC_DRIVER_IR_RAW_TX);
+       if (!idata->rc)
+               return -ENOMEM;
+
+       idata->rc->tx_ir           = ir_spi_tx;
+       idata->rc->s_tx_carrier    = ir_spi_set_tx_carrier;
+       idata->rc->s_tx_duty_cycle = ir_spi_set_duty_cycle;
+       idata->rc->driver_name     = IR_SPI_DRIVER_NAME;
+       idata->rc->priv            = idata;
+       idata->spi                 = spi;
+
+       idata->negated = of_property_read_bool(spi->dev.of_node,
+                                                       "led-active-low");
+       ret = of_property_read_u8(spi->dev.of_node, "duty-cycle", &dc);
+       if (ret)
+               dc = 50;
+
+       /* ir_spi_set_duty_cycle cannot fail,
+        * it returns int to be compatible with the
+        * rc->s_tx_duty_cycle function
+        */
+       ir_spi_set_duty_cycle(idata->rc, dc);
+
+       idata->freq = IR_SPI_DEFAULT_FREQUENCY;
+
+       return devm_rc_register_device(&spi->dev, idata->rc);
+}
+
+static int ir_spi_remove(struct spi_device *spi)
+{
+       return 0;
+}
+
+static const struct of_device_id ir_spi_of_match[] = {
+       { .compatible = "ir-spi-led" },
+       {},
+};
+
+static struct spi_driver ir_spi_driver = {
+       .probe = ir_spi_probe,
+       .remove = ir_spi_remove,
+       .driver = {
+               .name = IR_SPI_DRIVER_NAME,
+               .of_match_table = ir_spi_of_match,
+       },
+};
+
+module_spi_driver(ir_spi_driver);
+
+MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
+MODULE_DESCRIPTION("SPI IR LED");
+MODULE_LICENSE("GPL v2");
index 367b28bed627f69025adc554afc830fc20ac72aa..e9e4befbbebb8126220f02e79e9278e69b23fe5a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- *
  * Inspired by the original lirc_it87 and lirc_ite8709 drivers, on top of the
  * skeleton provided by the nuvoton-cir driver.
  *
@@ -1470,7 +1465,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
                return ret;
 
        /* input device for IR remote (and tx) */
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rdev)
                goto exit_free_dev_rdev;
        itdev->rdev = rdev;
@@ -1561,8 +1556,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
 
        /* set up ir-core props */
        rdev->priv = itdev;
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rdev->open = ite_open;
        rdev->close = ite_close;
        rdev->s_idle = ite_s_idle;
index aa899a0b9750770da5ee1a4b8a079d8f6d21bc4a..0e8ebc880d1fcae829f4dad3424c3ec67fd5118d 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
  */
 
 /* platform driver name to register */
index d7b13fae1267533d446483173bcc3617c075fca9..ffe9e612f8d6c63249b810ca612f61db2fb1b4a9 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
                        rc-cec.o \
                        rc-cinergy-1400.o \
                        rc-cinergy.o \
+                       rc-d680-dmb.o \
                        rc-delock-61959.o \
                        rc-dib0700-nec.o \
                        rc-dib0700-rc5.o \
@@ -31,6 +32,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
                        rc-dntv-live-dvbt-pro.o \
                        rc-dtt200u.o \
                        rc-dvbsky.o \
+                       rc-dvico-mce.o \
+                       rc-dvico-portable.o \
                        rc-em-terratec.o \
                        rc-encore-enltv2.o \
                        rc-encore-enltv.o \
@@ -41,6 +44,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
                        rc-flyvideo.o \
                        rc-fusionhdtv-mce.o \
                        rc-gadmei-rm008z.o \
+                       rc-geekbox.o \
                        rc-genius-tvgo-a11mce.o \
                        rc-gotview7135.o \
                        rc-imon-mce.o \
diff --git a/drivers/media/rc/keymaps/rc-d680-dmb.c b/drivers/media/rc/keymaps/rc-d680-dmb.c
new file mode 100644 (file)
index 0000000..bb5745d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * keymap imported from cxusb.c
+ *
+ * Copyright (C) 2016 Sean Young
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table rc_map_d680_dmb_table[] = {
+       { 0x0038, KEY_SWITCHVIDEOMODE },        /* TV/AV */
+       { 0x080c, KEY_ZOOM },
+       { 0x0800, KEY_0 },
+       { 0x0001, KEY_1 },
+       { 0x0802, KEY_2 },
+       { 0x0003, KEY_3 },
+       { 0x0804, KEY_4 },
+       { 0x0005, KEY_5 },
+       { 0x0806, KEY_6 },
+       { 0x0007, KEY_7 },
+       { 0x0808, KEY_8 },
+       { 0x0009, KEY_9 },
+       { 0x000a, KEY_MUTE },
+       { 0x0829, KEY_BACK },
+       { 0x0012, KEY_CHANNELUP },
+       { 0x0813, KEY_CHANNELDOWN },
+       { 0x002b, KEY_VOLUMEUP },
+       { 0x082c, KEY_VOLUMEDOWN },
+       { 0x0020, KEY_UP },
+       { 0x0821, KEY_DOWN },
+       { 0x0011, KEY_LEFT },
+       { 0x0810, KEY_RIGHT },
+       { 0x000d, KEY_OK },
+       { 0x081f, KEY_RECORD },
+       { 0x0017, KEY_PLAYPAUSE },
+       { 0x0816, KEY_PLAYPAUSE },
+       { 0x000b, KEY_STOP },
+       { 0x0827, KEY_FASTFORWARD },
+       { 0x0026, KEY_REWIND },
+       { 0x081e, KEY_UNKNOWN },    /* Time Shift */
+       { 0x000e, KEY_UNKNOWN },    /* Snapshot */
+       { 0x082d, KEY_UNKNOWN },    /* Mouse Cursor */
+       { 0x000f, KEY_UNKNOWN },    /* Minimize/Maximize */
+       { 0x0814, KEY_SHUFFLE },    /* Shuffle */
+       { 0x0025, KEY_POWER },
+};
+
+static struct rc_map_list d680_dmb_map = {
+       .map = {
+               .scan    = rc_map_d680_dmb_table,
+               .size    = ARRAY_SIZE(rc_map_d680_dmb_table),
+               .rc_type = RC_TYPE_UNKNOWN,     /* Legacy IR type */
+               .name    = RC_MAP_D680_DMB,
+       }
+};
+
+static int __init init_rc_map_d680_dmb(void)
+{
+       return rc_map_register(&d680_dmb_map);
+}
+
+static void __exit exit_rc_map_d680_dmb(void)
+{
+       rc_map_unregister(&d680_dmb_map);
+}
+
+module_init(init_rc_map_d680_dmb)
+module_exit(exit_rc_map_d680_dmb)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
diff --git a/drivers/media/rc/keymaps/rc-dvico-mce.c b/drivers/media/rc/keymaps/rc-dvico-mce.c
new file mode 100644 (file)
index 0000000..e5f098c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * keymap imported from cxusb.c
+ *
+ * Copyright (C) 2016 Sean Young
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table rc_map_dvico_mce_table[] = {
+       { 0xfe02, KEY_TV },
+       { 0xfe0e, KEY_MP3 },
+       { 0xfe1a, KEY_DVD },
+       { 0xfe1e, KEY_FAVORITES },
+       { 0xfe16, KEY_SETUP },
+       { 0xfe46, KEY_POWER2 },
+       { 0xfe0a, KEY_EPG },
+       { 0xfe49, KEY_BACK },
+       { 0xfe4d, KEY_MENU },
+       { 0xfe51, KEY_UP },
+       { 0xfe5b, KEY_LEFT },
+       { 0xfe5f, KEY_RIGHT },
+       { 0xfe53, KEY_DOWN },
+       { 0xfe5e, KEY_OK },
+       { 0xfe59, KEY_INFO },
+       { 0xfe55, KEY_TAB },
+       { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
+       { 0xfe12, KEY_NEXTSONG },       /* Skip */
+       { 0xfe42, KEY_ENTER      },     /* Windows/Start */
+       { 0xfe15, KEY_VOLUMEUP },
+       { 0xfe05, KEY_VOLUMEDOWN },
+       { 0xfe11, KEY_CHANNELUP },
+       { 0xfe09, KEY_CHANNELDOWN },
+       { 0xfe52, KEY_CAMERA },
+       { 0xfe5a, KEY_TUNER },  /* Live */
+       { 0xfe19, KEY_OPEN },
+       { 0xfe0b, KEY_1 },
+       { 0xfe17, KEY_2 },
+       { 0xfe1b, KEY_3 },
+       { 0xfe07, KEY_4 },
+       { 0xfe50, KEY_5 },
+       { 0xfe54, KEY_6 },
+       { 0xfe48, KEY_7 },
+       { 0xfe4c, KEY_8 },
+       { 0xfe58, KEY_9 },
+       { 0xfe13, KEY_ANGLE },  /* Aspect */
+       { 0xfe03, KEY_0 },
+       { 0xfe1f, KEY_ZOOM },
+       { 0xfe43, KEY_REWIND },
+       { 0xfe47, KEY_PLAYPAUSE },
+       { 0xfe4f, KEY_FASTFORWARD },
+       { 0xfe57, KEY_MUTE },
+       { 0xfe0d, KEY_STOP },
+       { 0xfe01, KEY_RECORD },
+       { 0xfe4e, KEY_POWER },
+};
+
+static struct rc_map_list dvico_mce_map = {
+       .map = {
+               .scan    = rc_map_dvico_mce_table,
+               .size    = ARRAY_SIZE(rc_map_dvico_mce_table),
+               .rc_type = RC_TYPE_UNKNOWN,     /* Legacy IR type */
+               .name    = RC_MAP_DVICO_MCE,
+       }
+};
+
+static int __init init_rc_map_dvico_mce(void)
+{
+       return rc_map_register(&dvico_mce_map);
+}
+
+static void __exit exit_rc_map_dvico_mce(void)
+{
+       rc_map_unregister(&dvico_mce_map);
+}
+
+module_init(init_rc_map_dvico_mce)
+module_exit(exit_rc_map_dvico_mce)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
diff --git a/drivers/media/rc/keymaps/rc-dvico-portable.c b/drivers/media/rc/keymaps/rc-dvico-portable.c
new file mode 100644 (file)
index 0000000..94ceeee
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * keymap imported from cxusb.c
+ *
+ * Copyright (C) 2016 Sean Young
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table rc_map_dvico_portable_table[] = {
+       { 0xfc02, KEY_SETUP },       /* Profile */
+       { 0xfc43, KEY_POWER2 },
+       { 0xfc06, KEY_EPG },
+       { 0xfc5a, KEY_BACK },
+       { 0xfc05, KEY_MENU },
+       { 0xfc47, KEY_INFO },
+       { 0xfc01, KEY_TAB },
+       { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
+       { 0xfc49, KEY_VOLUMEUP },
+       { 0xfc09, KEY_VOLUMEDOWN },
+       { 0xfc54, KEY_CHANNELUP },
+       { 0xfc0b, KEY_CHANNELDOWN },
+       { 0xfc16, KEY_CAMERA },
+       { 0xfc40, KEY_TUNER },  /* ATV/DTV */
+       { 0xfc45, KEY_OPEN },
+       { 0xfc19, KEY_1 },
+       { 0xfc18, KEY_2 },
+       { 0xfc1b, KEY_3 },
+       { 0xfc1a, KEY_4 },
+       { 0xfc58, KEY_5 },
+       { 0xfc59, KEY_6 },
+       { 0xfc15, KEY_7 },
+       { 0xfc14, KEY_8 },
+       { 0xfc17, KEY_9 },
+       { 0xfc44, KEY_ANGLE },  /* Aspect */
+       { 0xfc55, KEY_0 },
+       { 0xfc07, KEY_ZOOM },
+       { 0xfc0a, KEY_REWIND },
+       { 0xfc08, KEY_PLAYPAUSE },
+       { 0xfc4b, KEY_FASTFORWARD },
+       { 0xfc5b, KEY_MUTE },
+       { 0xfc04, KEY_STOP },
+       { 0xfc56, KEY_RECORD },
+       { 0xfc57, KEY_POWER },
+       { 0xfc41, KEY_UNKNOWN },    /* INPUT */
+       { 0xfc00, KEY_UNKNOWN },    /* HD */
+};
+
+static struct rc_map_list dvico_portable_map = {
+       .map = {
+               .scan    = rc_map_dvico_portable_table,
+               .size    = ARRAY_SIZE(rc_map_dvico_portable_table),
+               .rc_type = RC_TYPE_UNKNOWN,     /* Legacy IR type */
+               .name    = RC_MAP_DVICO_PORTABLE,
+       }
+};
+
+static int __init init_rc_map_dvico_portable(void)
+{
+       return rc_map_register(&dvico_portable_map);
+}
+
+static void __exit exit_rc_map_dvico_portable(void)
+{
+       rc_map_unregister(&dvico_portable_map);
+}
+
+module_init(init_rc_map_dvico_portable)
+module_exit(exit_rc_map_dvico_portable)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
diff --git a/drivers/media/rc/keymaps/rc-geekbox.c b/drivers/media/rc/keymaps/rc-geekbox.c
new file mode 100644 (file)
index 0000000..affc4c4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Keytable for the GeekBox remote controller
+ *
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table geekbox[] = {
+       { 0x01, KEY_BACK },
+       { 0x02, KEY_DOWN },
+       { 0x03, KEY_UP },
+       { 0x07, KEY_OK },
+       { 0x0b, KEY_VOLUMEUP },
+       { 0x0e, KEY_LEFT },
+       { 0x13, KEY_MENU },
+       { 0x14, KEY_POWER },
+       { 0x1a, KEY_RIGHT },
+       { 0x48, KEY_HOME },
+       { 0x58, KEY_VOLUMEDOWN },
+       { 0x5c, KEY_SCREEN },
+};
+
+static struct rc_map_list geekbox_map = {
+       .map = {
+               .scan    = geekbox,
+               .size    = ARRAY_SIZE(geekbox),
+               .rc_type = RC_TYPE_NEC,
+               .name    = RC_MAP_GEEKBOX,
+       }
+};
+
+static int __init init_rc_map_geekbox(void)
+{
+       return rc_map_register(&geekbox_map);
+}
+
+static void __exit exit_rc_map_geekbox(void)
+{
+       rc_map_unregister(&geekbox_map);
+}
+
+module_init(init_rc_map_geekbox)
+module_exit(exit_rc_map_geekbox)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
index ef4006fe4de0a6ca48d7bb3b6fa059bfa5af59fd..5be567506bcd48383933299127bbe87f6ac2102b 100644 (file)
@@ -86,6 +86,7 @@ static struct rc_map_table rc6_mce[] = {
        { 0x800f045e, KEY_BLUE },
 
        { 0x800f0465, KEY_POWER2 },     /* TV Power */
+       { 0x800f0469, KEY_MESSENGER },
        { 0x800f046e, KEY_PLAYPAUSE },
        { 0x800f046f, KEY_PLAYER },     /* Start media application (NEW) */
 
index f9733bb289d63441c7d2f249ebc30f69c960c84c..02c9c243c060b7e414928970f13f7a11595bd3a3 100644 (file)
  * License, or (at your option) any later version.
  *
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
  * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
  * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
index 454e062956925ee6b82ad195f10ca6bca82d4516..5cc1b456e3299893b37e27f92310453cfc0e898f 100644 (file)
  * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle,
  * which also ships with a TiVo-branded IR transceiver, supported by the mceusb
  * driver. Note that the remote uses an NEC-ish protocol, but instead of having
- * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the
+ * a command/not_command pair, it has a vendor ID of 0x3085, but some keys, the
  * NEC extended checksums do pass, so the table presently has the intended
  * values and the checksum-passed versions for those keys.
  */
 static struct rc_map_table tivo[] = {
-       { 0xa10c900f, KEY_MEDIA },      /* TiVo Button */
-       { 0xa10c0807, KEY_POWER2 },     /* TV Power */
-       { 0xa10c8807, KEY_TV },         /* Live TV/Swap */
-       { 0xa10c2c03, KEY_VIDEO_NEXT }, /* TV Input */
-       { 0xa10cc807, KEY_INFO },
-       { 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */
+       { 0x3085f009, KEY_MEDIA },      /* TiVo Button */
+       { 0x3085e010, KEY_POWER2 },     /* TV Power */
+       { 0x3085e011, KEY_TV },         /* Live TV/Swap */
+       { 0x3085c034, KEY_VIDEO_NEXT }, /* TV Input */
+       { 0x3085e013, KEY_INFO },
+       { 0x3085a05f, KEY_CYCLEWINDOWS }, /* Window */
        { 0x0085305f, KEY_CYCLEWINDOWS },
-       { 0xa10c6c03, KEY_EPG },        /* Guide */
+       { 0x3085c036, KEY_EPG },        /* Guide */
 
-       { 0xa10c2807, KEY_UP },
-       { 0xa10c6807, KEY_DOWN },
-       { 0xa10ce807, KEY_LEFT },
-       { 0xa10ca807, KEY_RIGHT },
+       { 0x3085e014, KEY_UP },
+       { 0x3085e016, KEY_DOWN },
+       { 0x3085e017, KEY_LEFT },
+       { 0x3085e015, KEY_RIGHT },
 
-       { 0xa10c1807, KEY_SCROLLDOWN }, /* Red Thumbs Down */
-       { 0xa10c9807, KEY_SELECT },
-       { 0xa10c5807, KEY_SCROLLUP },   /* Green Thumbs Up */
+       { 0x3085e018, KEY_SCROLLDOWN }, /* Red Thumbs Down */
+       { 0x3085e019, KEY_SELECT },
+       { 0x3085e01a, KEY_SCROLLUP },   /* Green Thumbs Up */
 
-       { 0xa10c3807, KEY_VOLUMEUP },
-       { 0xa10cb807, KEY_VOLUMEDOWN },
-       { 0xa10cd807, KEY_MUTE },
-       { 0xa10c040b, KEY_RECORD },
-       { 0xa10c7807, KEY_CHANNELUP },
-       { 0xa10cf807, KEY_CHANNELDOWN },
+       { 0x3085e01c, KEY_VOLUMEUP },
+       { 0x3085e01d, KEY_VOLUMEDOWN },
+       { 0x3085e01b, KEY_MUTE },
+       { 0x3085d020, KEY_RECORD },
+       { 0x3085e01e, KEY_CHANNELUP },
+       { 0x3085e01f, KEY_CHANNELDOWN },
        { 0x0085301f, KEY_CHANNELDOWN },
 
-       { 0xa10c840b, KEY_PLAY },
-       { 0xa10cc40b, KEY_PAUSE },
-       { 0xa10ca40b, KEY_SLOW },
-       { 0xa10c440b, KEY_REWIND },
-       { 0xa10c240b, KEY_FASTFORWARD },
-       { 0xa10c640b, KEY_PREVIOUS },
-       { 0xa10ce40b, KEY_NEXT },       /* ->| */
+       { 0x3085d021, KEY_PLAY },
+       { 0x3085d023, KEY_PAUSE },
+       { 0x3085d025, KEY_SLOW },
+       { 0x3085d022, KEY_REWIND },
+       { 0x3085d024, KEY_FASTFORWARD },
+       { 0x3085d026, KEY_PREVIOUS },
+       { 0x3085d027, KEY_NEXT },       /* ->| */
 
-       { 0xa10c220d, KEY_ZOOM },       /* Aspect */
-       { 0xa10c120d, KEY_STOP },
-       { 0xa10c520d, KEY_DVD },        /* DVD Menu */
+       { 0x3085b044, KEY_ZOOM },       /* Aspect */
+       { 0x3085b048, KEY_STOP },
+       { 0x3085b04a, KEY_DVD },        /* DVD Menu */
 
-       { 0xa10c140b, KEY_NUMERIC_1 },
-       { 0xa10c940b, KEY_NUMERIC_2 },
-       { 0xa10c540b, KEY_NUMERIC_3 },
-       { 0xa10cd40b, KEY_NUMERIC_4 },
-       { 0xa10c340b, KEY_NUMERIC_5 },
-       { 0xa10cb40b, KEY_NUMERIC_6 },
-       { 0xa10c740b, KEY_NUMERIC_7 },
-       { 0xa10cf40b, KEY_NUMERIC_8 },
+       { 0x3085d028, KEY_NUMERIC_1 },
+       { 0x3085d029, KEY_NUMERIC_2 },
+       { 0x3085d02a, KEY_NUMERIC_3 },
+       { 0x3085d02b, KEY_NUMERIC_4 },
+       { 0x3085d02c, KEY_NUMERIC_5 },
+       { 0x3085d02d, KEY_NUMERIC_6 },
+       { 0x3085d02e, KEY_NUMERIC_7 },
+       { 0x3085d02f, KEY_NUMERIC_8 },
        { 0x0085302f, KEY_NUMERIC_8 },
-       { 0xa10c0c03, KEY_NUMERIC_9 },
-       { 0xa10c8c03, KEY_NUMERIC_0 },
-       { 0xa10ccc03, KEY_ENTER },
-       { 0xa10c4c03, KEY_CLEAR },
+       { 0x3085c030, KEY_NUMERIC_9 },
+       { 0x3085c031, KEY_NUMERIC_0 },
+       { 0x3085c033, KEY_ENTER },
+       { 0x3085c032, KEY_CLEAR },
 };
 
 static struct rc_map_list tivo_map = {
index 3854809e853110ea74867d5ecda8f08acb3609b6..a54ca531d8ef85280c8cf9df7b7b19ac226f7032 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -472,7 +468,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
                if (retval) {
                        module_put(cdev->owner);
                        ir->open--;
-               } else {
+               } else if (ir->buf) {
                        lirc_buffer_clear(ir->buf);
                }
                if (ir->task)
@@ -582,7 +578,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                result = put_user(ir->d.features, (__u32 __user *)arg);
                break;
        case LIRC_GET_REC_MODE:
-               if (LIRC_CAN_REC(ir->d.features)) {
+               if (!LIRC_CAN_REC(ir->d.features)) {
                        result = -ENOTTY;
                        break;
                }
@@ -592,7 +588,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                  (__u32 __user *)arg);
                break;
        case LIRC_SET_REC_MODE:
-               if (LIRC_CAN_REC(ir->d.features)) {
+               if (!LIRC_CAN_REC(ir->d.features)) {
                        result = -ENOTTY;
                        break;
                }
@@ -651,6 +647,9 @@ ssize_t lirc_dev_fop_read(struct file *file,
                return -ENODEV;
        }
 
+       if (!LIRC_CAN_REC(ir->d.features))
+               return -EINVAL;
+
        dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
 
        buf = kzalloc(ir->chunk_size, GFP_KERNEL);
index 9bf69179eee0e7b21b11b6e0a4b1e220254f8181..238d8eaf7d94f8e2a1346b4c9889176d8a21e3b0 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #include <linux/device.h>
@@ -890,7 +886,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
                        cmdbuf[3] = MCE_IRDATA_TRAILER;
                        dev_dbg(ir->dev, "disabling carrier modulation");
                        mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
-                       return carrier;
+                       return 0;
                }
 
                for (prescaler = 0; prescaler < 4; ++prescaler) {
@@ -904,7 +900,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
 
                                /* Transmit new carrier to mce device */
                                mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
-                               return carrier;
+                               return 0;
                        }
                }
 
@@ -1181,7 +1177,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
        struct rc_dev *rc;
        int ret;
 
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rc) {
                dev_err(dev, "remote dev allocation failed");
                goto out;
@@ -1201,8 +1197,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
        usb_to_input_id(ir->usbdev, &rc->input_id);
        rc->dev.parent = dev;
        rc->priv = ir;
-       rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protocols = RC_BIT_ALL;
+       rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rc->timeout = MS_TO_NS(100);
        if (!ir->flags.no_tx) {
                rc->s_tx_mask = mceusb_set_tx_mask;
index 7eb3f4f1ddcd670d501432528a2472dc0775d55f..5576dbd6b1a4daa9fb5d96da7ee88e4bc056878c 100644 (file)
@@ -131,7 +131,7 @@ static int meson_ir_probe(struct platform_device *pdev)
                return ir->irq;
        }
 
-       ir->rc = rc_allocate_device();
+       ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!ir->rc) {
                dev_err(dev, "failed to allocate rc device\n");
                return -ENOMEM;
@@ -144,8 +144,7 @@ static int meson_ir_probe(struct platform_device *pdev)
        map_name = of_get_property(node, "linux,rc-map-name", NULL);
        ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
        ir->rc->dev.parent = dev;
-       ir->rc->driver_type = RC_DRIVER_IR_RAW;
-       ir->rc->allowed_protocols = RC_BIT_ALL;
+       ir->rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
        ir->rc->timeout = MS_TO_NS(200);
        ir->rc->driver_name = DRIVER_NAME;
diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
new file mode 100644 (file)
index 0000000..f1e164e
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * Driver for Mediatek IR Receiver Controller
+ *
+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+#include <media/rc-core.h>
+
+#define MTK_IR_DEV KBUILD_MODNAME
+
+/* Register to enable PWM and IR */
+#define MTK_CONFIG_HIGH_REG       0x0c
+/* Enable IR pulse width detection */
+#define MTK_PWM_EN               BIT(13)
+/* Enable IR hardware function */
+#define MTK_IR_EN                BIT(0)
+
+/* Register to setting sample period */
+#define MTK_CONFIG_LOW_REG        0x10
+/* Field to set sample period */
+#define CHK_PERIOD               DIV_ROUND_CLOSEST(MTK_IR_SAMPLE,  \
+                                                   MTK_IR_CLK_PERIOD)
+#define MTK_CHK_PERIOD            (((CHK_PERIOD) << 8) & (GENMASK(20, 8)))
+#define MTK_CHK_PERIOD_MASK      (GENMASK(20, 8))
+
+/* Register to clear state of state machine */
+#define MTK_IRCLR_REG             0x20
+/* Bit to restart IR receiving */
+#define MTK_IRCLR                BIT(0)
+
+/* Register containing pulse width data */
+#define MTK_CHKDATA_REG(i)        (0x88 + 4 * (i))
+#define MTK_WIDTH_MASK           (GENMASK(7, 0))
+
+/* Register to enable IR interrupt */
+#define MTK_IRINT_EN_REG          0xcc
+/* Bit to enable interrupt */
+#define MTK_IRINT_EN             BIT(0)
+
+/* Register to ack IR interrupt */
+#define MTK_IRINT_CLR_REG         0xd0
+/* Bit to clear interrupt status */
+#define MTK_IRINT_CLR            BIT(0)
+
+/* Maximum count of samples */
+#define MTK_MAX_SAMPLES                  0xff
+/* Indicate the end of IR message */
+#define MTK_IR_END(v, p)         ((v) == MTK_MAX_SAMPLES && (p) == 0)
+/* Number of registers to record the pulse width */
+#define MTK_CHKDATA_SZ           17
+/* Source clock frequency */
+#define MTK_IR_BASE_CLK                  273000000
+/* Frequency after IR internal divider */
+#define MTK_IR_CLK_FREQ                  (MTK_IR_BASE_CLK / 4)
+/* Period for MTK_IR_CLK in ns*/
+#define MTK_IR_CLK_PERIOD        DIV_ROUND_CLOSEST(1000000000ul,  \
+                                                   MTK_IR_CLK_FREQ)
+/* Sample period in ns */
+#define MTK_IR_SAMPLE            (MTK_IR_CLK_PERIOD * 0xc00)
+
+/*
+ * struct mtk_ir -     This is the main datasructure for holding the state
+ *                     of the driver
+ * @dev:               The device pointer
+ * @rc:                        The rc instrance
+ * @irq:               The IRQ that we are using
+ * @base:              The mapped register i/o base
+ * @clk:               The clock that we are using
+ */
+struct mtk_ir {
+       struct device   *dev;
+       struct rc_dev   *rc;
+       void __iomem    *base;
+       int             irq;
+       struct clk      *clk;
+};
+
+static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg)
+{
+       u32 tmp;
+
+       tmp = __raw_readl(ir->base + reg);
+       tmp = (tmp & ~mask) | val;
+       __raw_writel(tmp, ir->base + reg);
+}
+
+static void mtk_w32(struct mtk_ir *ir, u32 val, unsigned int reg)
+{
+       __raw_writel(val, ir->base + reg);
+}
+
+static u32 mtk_r32(struct mtk_ir *ir, unsigned int reg)
+{
+       return __raw_readl(ir->base + reg);
+}
+
+static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask)
+{
+       u32 val;
+
+       val = mtk_r32(ir, MTK_IRINT_EN_REG);
+       mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG);
+}
+
+static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask)
+{
+       u32 val;
+
+       val = mtk_r32(ir, MTK_IRINT_EN_REG);
+       mtk_w32(ir, val | mask, MTK_IRINT_EN_REG);
+}
+
+static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
+{
+       struct mtk_ir *ir = dev_id;
+       u8  wid = 0;
+       u32 i, j, val;
+       DEFINE_IR_RAW_EVENT(rawir);
+
+       /*
+        * Reset decoder state machine explicitly is required
+        * because 1) the longest duration for space MTK IR hardware
+        * could record is not safely long. e.g  12ms if rx resolution
+        * is 46us by default. There is still the risk to satisfying
+        * every decoder to reset themselves through long enough
+        * trailing spaces and 2) the IRQ handler guarantees that
+        * start of IR message is always contained in and starting
+        * from register MTK_CHKDATA_REG(0).
+        */
+       ir_raw_event_reset(ir->rc);
+
+       /* First message must be pulse */
+       rawir.pulse = false;
+
+       /* Handle all pulse and space IR controller captures */
+       for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
+               val = mtk_r32(ir, MTK_CHKDATA_REG(i));
+               dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
+
+               for (j = 0 ; j < 4 ; j++) {
+                       wid = (val & (MTK_WIDTH_MASK << j * 8)) >> j * 8;
+                       rawir.pulse = !rawir.pulse;
+                       rawir.duration = wid * (MTK_IR_SAMPLE + 1);
+                       ir_raw_event_store_with_filter(ir->rc, &rawir);
+               }
+       }
+
+       /*
+        * The maximum number of edges the IR controller can
+        * hold is MTK_CHKDATA_SZ * 4. So if received IR messages
+        * is over the limit, the last incomplete IR message would
+        * be appended trailing space and still would be sent into
+        * ir-rc-raw to decode. That helps it is possible that it
+        * has enough information to decode a scancode even if the
+        * trailing end of the message is missing.
+        */
+       if (!MTK_IR_END(wid, rawir.pulse)) {
+               rawir.pulse = false;
+               rawir.duration = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
+               ir_raw_event_store_with_filter(ir->rc, &rawir);
+       }
+
+       ir_raw_event_handle(ir->rc);
+
+       /*
+        * Restart controller for the next receive that would
+        * clear up all CHKDATA registers
+        */
+       mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG);
+
+       /* Clear interrupt status */
+       mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG);
+
+       return IRQ_HANDLED;
+}
+
+static int mtk_ir_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *dn = dev->of_node;
+       struct resource *res;
+       struct mtk_ir *ir;
+       u32 val;
+       int ret = 0;
+       const char *map_name;
+
+       ir = devm_kzalloc(dev, sizeof(struct mtk_ir), GFP_KERNEL);
+       if (!ir)
+               return -ENOMEM;
+
+       ir->dev = dev;
+
+       if (!of_device_is_compatible(dn, "mediatek,mt7623-cir"))
+               return -ENODEV;
+
+       ir->clk = devm_clk_get(dev, "clk");
+       if (IS_ERR(ir->clk)) {
+               dev_err(dev, "failed to get a ir clock.\n");
+               return PTR_ERR(ir->clk);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       ir->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(ir->base)) {
+               dev_err(dev, "failed to map registers\n");
+               return PTR_ERR(ir->base);
+       }
+
+       ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
+       if (!ir->rc) {
+               dev_err(dev, "failed to allocate device\n");
+               return -ENOMEM;
+       }
+
+       ir->rc->priv = ir;
+       ir->rc->input_name = MTK_IR_DEV;
+       ir->rc->input_phys = MTK_IR_DEV "/input0";
+       ir->rc->input_id.bustype = BUS_HOST;
+       ir->rc->input_id.vendor = 0x0001;
+       ir->rc->input_id.product = 0x0001;
+       ir->rc->input_id.version = 0x0001;
+       map_name = of_get_property(dn, "linux,rc-map-name", NULL);
+       ir->rc->map_name = map_name ?: RC_MAP_EMPTY;
+       ir->rc->dev.parent = dev;
+       ir->rc->driver_name = MTK_IR_DEV;
+       ir->rc->allowed_protocols = RC_BIT_ALL;
+       ir->rc->rx_resolution = MTK_IR_SAMPLE;
+       ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
+
+       ret = devm_rc_register_device(dev, ir->rc);
+       if (ret) {
+               dev_err(dev, "failed to register rc device\n");
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, ir);
+
+       ir->irq = platform_get_irq(pdev, 0);
+       if (ir->irq < 0) {
+               dev_err(dev, "no irq resource\n");
+               return -ENODEV;
+       }
+
+       /*
+        * Enable interrupt after proper hardware
+        * setup and IRQ handler registration
+        */
+       if (clk_prepare_enable(ir->clk)) {
+               dev_err(dev, "try to enable ir_clk failed\n");
+               ret = -EINVAL;
+               goto exit_clkdisable_clk;
+       }
+
+       mtk_irq_disable(ir, MTK_IRINT_EN);
+
+       ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir);
+       if (ret) {
+               dev_err(dev, "failed request irq\n");
+               goto exit_clkdisable_clk;
+       }
+
+       /* Enable IR and PWM */
+       val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
+       val |= MTK_PWM_EN | MTK_IR_EN;
+       mtk_w32(ir, val, MTK_CONFIG_HIGH_REG);
+
+       /* Setting sample period */
+       mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK,
+                    MTK_CONFIG_LOW_REG);
+
+       mtk_irq_enable(ir, MTK_IRINT_EN);
+
+       dev_info(dev, "Initialized MT7623 IR driver, sample period = %luus\n",
+                DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000));
+
+       return 0;
+
+exit_clkdisable_clk:
+       clk_disable_unprepare(ir->clk);
+
+       return ret;
+}
+
+static int mtk_ir_remove(struct platform_device *pdev)
+{
+       struct mtk_ir *ir = platform_get_drvdata(pdev);
+
+       /*
+        * Avoid contention between remove handler and
+        * IRQ handler so that disabling IR interrupt and
+        * waiting for pending IRQ handler to complete
+        */
+       mtk_irq_disable(ir, MTK_IRINT_EN);
+       synchronize_irq(ir->irq);
+
+       clk_disable_unprepare(ir->clk);
+
+       return 0;
+}
+
+static const struct of_device_id mtk_ir_match[] = {
+       { .compatible = "mediatek,mt7623-cir" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mtk_ir_match);
+
+static struct platform_driver mtk_ir_driver = {
+       .probe          = mtk_ir_probe,
+       .remove         = mtk_ir_remove,
+       .driver = {
+               .name = MTK_IR_DEV,
+               .of_match_table = mtk_ir_match,
+       },
+};
+
+module_platform_driver(mtk_ir_driver);
+
+MODULE_DESCRIPTION("Mediatek IR Receiver Controller Driver");
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_LICENSE("GPL");
index 4b78c891eb7794935390b7bd60aacb4fb6a0886c..b109f8246b968d99cacde9b6ee73719f554a4bfd 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -176,6 +171,41 @@ static void nvt_set_ioaddr(struct nvt_dev *nvt, unsigned long *ioaddr)
        }
 }
 
+static void nvt_write_wakeup_codes(struct rc_dev *dev,
+                                  const u8 *wbuf, int count)
+{
+       u8 tolerance, config;
+       struct nvt_dev *nvt = dev->priv;
+       int i;
+
+       /* hardcode the tolerance to 10% */
+       tolerance = DIV_ROUND_UP(count, 10);
+
+       spin_lock(&nvt->lock);
+
+       nvt_clear_cir_wake_fifo(nvt);
+       nvt_cir_wake_reg_write(nvt, count, CIR_WAKE_FIFO_CMP_DEEP);
+       nvt_cir_wake_reg_write(nvt, tolerance, CIR_WAKE_FIFO_CMP_TOL);
+
+       config = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON);
+
+       /* enable writes to wake fifo */
+       nvt_cir_wake_reg_write(nvt, config | CIR_WAKE_IRCON_MODE1,
+                              CIR_WAKE_IRCON);
+
+       if (count)
+               pr_info("Wake samples (%d) =", count);
+       else
+               pr_info("Wake sample fifo cleared");
+
+       for (i = 0; i < count; i++)
+               nvt_cir_wake_reg_write(nvt, wbuf[i], CIR_WAKE_WR_FIFO_DATA);
+
+       nvt_cir_wake_reg_write(nvt, config, CIR_WAKE_IRCON);
+
+       spin_unlock(&nvt->lock);
+}
+
 static ssize_t wakeup_data_show(struct device *dev,
                                struct device_attribute *attr,
                                char *buf)
@@ -214,9 +244,7 @@ static ssize_t wakeup_data_store(struct device *dev,
                                 const char *buf, size_t len)
 {
        struct rc_dev *rc_dev = to_rc_dev(dev);
-       struct nvt_dev *nvt = rc_dev->priv;
-       unsigned long flags;
-       u8 tolerance, config, wake_buf[WAKEUP_MAX_SIZE];
+       u8 wake_buf[WAKEUP_MAX_SIZE];
        char **argv;
        int i, count;
        unsigned int val;
@@ -245,27 +273,7 @@ static ssize_t wakeup_data_store(struct device *dev,
                        wake_buf[i] |= BUF_PULSE_BIT;
        }
 
-       /* hardcode the tolerance to 10% */
-       tolerance = DIV_ROUND_UP(count, 10);
-
-       spin_lock_irqsave(&nvt->lock, flags);
-
-       nvt_clear_cir_wake_fifo(nvt);
-       nvt_cir_wake_reg_write(nvt, count, CIR_WAKE_FIFO_CMP_DEEP);
-       nvt_cir_wake_reg_write(nvt, tolerance, CIR_WAKE_FIFO_CMP_TOL);
-
-       config = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON);
-
-       /* enable writes to wake fifo */
-       nvt_cir_wake_reg_write(nvt, config | CIR_WAKE_IRCON_MODE1,
-                              CIR_WAKE_IRCON);
-
-       for (i = 0; i < count; i++)
-               nvt_cir_wake_reg_write(nvt, wake_buf[i], CIR_WAKE_WR_FIFO_DATA);
-
-       nvt_cir_wake_reg_write(nvt, config, CIR_WAKE_IRCON);
-
-       spin_unlock_irqrestore(&nvt->lock, flags);
+       nvt_write_wakeup_codes(rc_dev, wake_buf, count);
 
        ret = len;
 out:
@@ -662,6 +670,62 @@ static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
        return 0;
 }
 
+static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev,
+                                       struct rc_scancode_filter *sc_filter)
+{
+       u8 buf_val;
+       int i, ret, count;
+       unsigned int val;
+       struct ir_raw_event *raw;
+       u8 wake_buf[WAKEUP_MAX_SIZE];
+       bool complete;
+
+       /* Require mask to be set */
+       if (!sc_filter->mask)
+               return 0;
+
+       raw = kmalloc_array(WAKEUP_MAX_SIZE, sizeof(*raw), GFP_KERNEL);
+       if (!raw)
+               return -ENOMEM;
+
+       ret = ir_raw_encode_scancode(dev->wakeup_protocol, sc_filter->data,
+                                    raw, WAKEUP_MAX_SIZE);
+       complete = (ret != -ENOBUFS);
+       if (!complete)
+               ret = WAKEUP_MAX_SIZE;
+       else if (ret < 0)
+               goto out_raw;
+
+       /* Inspect the ir samples */
+       for (i = 0, count = 0; i < ret && count < WAKEUP_MAX_SIZE; ++i) {
+               /* NS to US */
+               val = DIV_ROUND_UP(raw[i].duration, 1000L) / SAMPLE_PERIOD;
+
+               /* Split too large values into several smaller ones */
+               while (val > 0 && count < WAKEUP_MAX_SIZE) {
+                       /* Skip last value for better comparison tolerance */
+                       if (complete && i == ret - 1 && val < BUF_LEN_MASK)
+                               break;
+
+                       /* Clamp values to BUF_LEN_MASK at most */
+                       buf_val = (val > BUF_LEN_MASK) ? BUF_LEN_MASK : val;
+
+                       wake_buf[count] = buf_val;
+                       val -= buf_val;
+                       if ((raw[i]).pulse)
+                               wake_buf[count] |= BUF_PULSE_BIT;
+                       count++;
+               }
+       }
+
+       nvt_write_wakeup_codes(dev, wake_buf, count);
+       ret = 0;
+out_raw:
+       kfree(raw);
+
+       return ret;
+}
+
 /*
  * nvt_tx_ir
  *
@@ -998,7 +1062,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
                return -ENOMEM;
 
        /* input device for IR remote (and tx) */
-       nvt->rdev = devm_rc_allocate_device(&pdev->dev);
+       nvt->rdev = devm_rc_allocate_device(&pdev->dev, RC_DRIVER_IR_RAW);
        if (!nvt->rdev)
                return -ENOMEM;
        rdev = nvt->rdev;
@@ -1061,12 +1125,14 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
 
        /* Set up the rc device */
        rdev->priv = nvt;
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
+       rdev->allowed_wakeup_protocols = RC_BIT_ALL_IR_ENCODER;
+       rdev->encode_wakeup = true;
        rdev->open = nvt_open;
        rdev->close = nvt_close;
        rdev->tx_ir = nvt_tx_ir;
        rdev->s_tx_carrier = nvt_set_tx_carrier;
+       rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter;
        rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
        rdev->input_phys = "nuvoton/cir0";
        rdev->input_id.bustype = BUS_HOST;
index c41c5765e1d21e556bc6cac2bd9832cf27badf89..88a29df38a57f8ffb082df109ea8777605684bc9 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
  */
 
 #include <linux/spinlock.h>
index 585d5e52118d538f7fc764d2793bd98384c72b44..a70a5c55743436979066af1d3cba00e5243fe3a0 100644 (file)
@@ -20,7 +20,6 @@
 #define        MAX_IR_EVENT_SIZE       512
 
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 #include <media/rc-core.h>
 
 struct ir_raw_handler {
@@ -28,6 +27,8 @@ struct ir_raw_handler {
 
        u64 protocols; /* which are handled by this handler */
        int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
+       int (*encode)(enum rc_type protocol, u32 scancode,
+                     struct ir_raw_event *events, unsigned int max);
 
        /* These two should only be used by the lirc decoder */
        int (*raw_register)(struct rc_dev *dev);
@@ -37,7 +38,6 @@ struct ir_raw_handler {
 struct ir_raw_event_ctrl {
        struct list_head                list;           /* to keep track of raw clients */
        struct task_struct              *thread;
-       spinlock_t                      lock;
        /* fifo for the pulse/space durations */
        DECLARE_KFIFO(kfifo, struct ir_raw_event, MAX_IR_EVENT_SIZE);
        ktime_t                         last_event;     /* when last event occurred */
@@ -154,6 +154,111 @@ static inline bool is_timing_event(struct ir_raw_event ev)
 #define TO_US(duration)                        DIV_ROUND_CLOSEST((duration), 1000)
 #define TO_STR(is_pulse)               ((is_pulse) ? "pulse" : "space")
 
+/* functions for IR encoders */
+
+static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,
+                                             unsigned int pulse,
+                                             u32 duration)
+{
+       init_ir_raw_event(ev);
+       ev->duration = duration;
+       ev->pulse = pulse;
+}
+
+/**
+ * struct ir_raw_timings_manchester - Manchester coding timings
+ * @leader:            duration of leader pulse (if any) 0 if continuing
+ *                     existing signal (see @pulse_space_start)
+ * @pulse_space_start: 1 for starting with pulse (0 for starting with space)
+ * @clock:             duration of each pulse/space in ns
+ * @invert:            if set clock logic is inverted
+ *                     (0 = space + pulse, 1 = pulse + space)
+ * @trailer_space:     duration of trailer space in ns
+ */
+struct ir_raw_timings_manchester {
+       unsigned int leader;
+       unsigned int pulse_space_start:1;
+       unsigned int clock;
+       unsigned int invert:1;
+       unsigned int trailer_space;
+};
+
+int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
+                         const struct ir_raw_timings_manchester *timings,
+                         unsigned int n, unsigned int data);
+
+/**
+ * ir_raw_gen_pulse_space() - generate pulse and space raw events.
+ * @ev:                        Pointer to pointer to next free raw event.
+ *                     Will be incremented for each raw event written.
+ * @max:               Pointer to number of raw events available in buffer.
+ *                     Will be decremented for each raw event written.
+ * @pulse_width:       Width of pulse in ns.
+ * @space_width:       Width of space in ns.
+ *
+ * Returns:    0 on success.
+ *             -ENOBUFS if there isn't enough buffer space to write both raw
+ *             events. In this case @max events will have been written.
+ */
+static inline int ir_raw_gen_pulse_space(struct ir_raw_event **ev,
+                                        unsigned int *max,
+                                        unsigned int pulse_width,
+                                        unsigned int space_width)
+{
+       if (!*max)
+               return -ENOBUFS;
+       init_ir_raw_event_duration((*ev)++, 1, pulse_width);
+       if (!--*max)
+               return -ENOBUFS;
+       init_ir_raw_event_duration((*ev)++, 0, space_width);
+       --*max;
+       return 0;
+}
+
+/**
+ * struct ir_raw_timings_pd - pulse-distance modulation timings
+ * @header_pulse:      duration of header pulse in ns (0 for none)
+ * @header_space:      duration of header space in ns
+ * @bit_pulse:         duration of bit pulse in ns
+ * @bit_space:         duration of bit space (for logic 0 and 1) in ns
+ * @trailer_pulse:     duration of trailer pulse in ns
+ * @trailer_space:     duration of trailer space in ns
+ * @msb_first:         1 if most significant bit is sent first
+ */
+struct ir_raw_timings_pd {
+       unsigned int header_pulse;
+       unsigned int header_space;
+       unsigned int bit_pulse;
+       unsigned int bit_space[2];
+       unsigned int trailer_pulse;
+       unsigned int trailer_space;
+       unsigned int msb_first:1;
+};
+
+int ir_raw_gen_pd(struct ir_raw_event **ev, unsigned int max,
+                 const struct ir_raw_timings_pd *timings,
+                 unsigned int n, u64 data);
+
+/**
+ * struct ir_raw_timings_pl - pulse-length modulation timings
+ * @header_pulse:      duration of header pulse in ns (0 for none)
+ * @bit_space:         duration of bit space in ns
+ * @bit_pulse:         duration of bit pulse (for logic 0 and 1) in ns
+ * @trailer_space:     duration of trailer space in ns
+ * @msb_first:         1 if most significant bit is sent first
+ */
+struct ir_raw_timings_pl {
+       unsigned int header_pulse;
+       unsigned int bit_space;
+       unsigned int bit_pulse[2];
+       unsigned int trailer_space;
+       unsigned int msb_first:1;
+};
+
+int ir_raw_gen_pl(struct ir_raw_event **ev, unsigned int max,
+                 const struct ir_raw_timings_pl *timings,
+                 unsigned int n, u64 data);
+
 /*
  * Routines from rc-raw.c to be used internally and by decoders
  */
index 1c42a9f2f2901b417ab7fdd258fdb416546aeeea..7fa84b64a2ae53c71476f83d89b8eb7062c73643 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mutex.h>
 #include <linux/kmod.h>
 #include <linux/sched.h>
-#include <linux/freezer.h>
 #include "rc-core-priv.h"
 
 /* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
@@ -34,32 +33,26 @@ static int ir_raw_event_thread(void *data)
        struct ir_raw_handler *handler;
        struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
 
-       while (!kthread_should_stop()) {
-
-               spin_lock_irq(&raw->lock);
-
-               if (!kfifo_len(&raw->kfifo)) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-
-                       if (kthread_should_stop())
-                               set_current_state(TASK_RUNNING);
-
-                       spin_unlock_irq(&raw->lock);
-                       schedule();
-                       continue;
+       while (1) {
+               mutex_lock(&ir_raw_handler_lock);
+               while (kfifo_out(&raw->kfifo, &ev, 1)) {
+                       list_for_each_entry(handler, &ir_raw_handler_list, list)
+                               if (raw->dev->enabled_protocols &
+                                   handler->protocols || !handler->protocols)
+                                       handler->decode(raw->dev, ev);
+                       raw->prev_ev = ev;
                }
+               mutex_unlock(&ir_raw_handler_lock);
 
-               if(!kfifo_out(&raw->kfifo, &ev, 1))
-                       dev_err(&raw->dev->dev, "IR event FIFO is empty!\n");
-               spin_unlock_irq(&raw->lock);
+               set_current_state(TASK_INTERRUPTIBLE);
 
-               mutex_lock(&ir_raw_handler_lock);
-               list_for_each_entry(handler, &ir_raw_handler_list, list)
-                       if (raw->dev->enabled_protocols & handler->protocols ||
-                           !handler->protocols)
-                               handler->decode(raw->dev, ev);
-               raw->prev_ev = ev;
-               mutex_unlock(&ir_raw_handler_lock);
+               if (kthread_should_stop()) {
+                       __set_current_state(TASK_RUNNING);
+                       break;
+               } else if (!kfifo_is_empty(&raw->kfifo))
+                       set_current_state(TASK_RUNNING);
+
+               schedule();
        }
 
        return 0;
@@ -218,14 +211,10 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
  */
 void ir_raw_event_handle(struct rc_dev *dev)
 {
-       unsigned long flags;
-
        if (!dev->raw)
                return;
 
-       spin_lock_irqsave(&dev->raw->lock, flags);
        wake_up_process(dev->raw->thread);
-       spin_unlock_irqrestore(&dev->raw->lock, flags);
 }
 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 
@@ -246,10 +235,254 @@ static void ir_raw_disable_protocols(struct rc_dev *dev, u64 protocols)
 {
        mutex_lock(&dev->lock);
        dev->enabled_protocols &= ~protocols;
-       dev->enabled_wakeup_protocols &= ~protocols;
        mutex_unlock(&dev->lock);
 }
 
+/**
+ * ir_raw_gen_manchester() - Encode data with Manchester (bi-phase) modulation.
+ * @ev:                Pointer to pointer to next free event. *@ev is incremented for
+ *             each raw event filled.
+ * @max:       Maximum number of raw events to fill.
+ * @timings:   Manchester modulation timings.
+ * @n:         Number of bits of data.
+ * @data:      Data bits to encode.
+ *
+ * Encodes the @n least significant bits of @data using Manchester (bi-phase)
+ * modulation with the timing characteristics described by @timings, writing up
+ * to @max raw IR events using the *@ev pointer.
+ *
+ * Returns:    0 on success.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             full encoded data. In this case all @max events will have been
+ *             written.
+ */
+int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
+                         const struct ir_raw_timings_manchester *timings,
+                         unsigned int n, unsigned int data)
+{
+       bool need_pulse;
+       unsigned int i;
+       int ret = -ENOBUFS;
+
+       i = 1 << (n - 1);
+
+       if (timings->leader) {
+               if (!max--)
+                       return ret;
+               if (timings->pulse_space_start) {
+                       init_ir_raw_event_duration((*ev)++, 1, timings->leader);
+
+                       if (!max--)
+                               return ret;
+                       init_ir_raw_event_duration((*ev), 0, timings->leader);
+               } else {
+                       init_ir_raw_event_duration((*ev), 1, timings->leader);
+               }
+               i >>= 1;
+       } else {
+               /* continue existing signal */
+               --(*ev);
+       }
+       /* from here on *ev will point to the last event rather than the next */
+
+       while (n && i > 0) {
+               need_pulse = !(data & i);
+               if (timings->invert)
+                       need_pulse = !need_pulse;
+               if (need_pulse == !!(*ev)->pulse) {
+                       (*ev)->duration += timings->clock;
+               } else {
+                       if (!max--)
+                               goto nobufs;
+                       init_ir_raw_event_duration(++(*ev), need_pulse,
+                                                  timings->clock);
+               }
+
+               if (!max--)
+                       goto nobufs;
+               init_ir_raw_event_duration(++(*ev), !need_pulse,
+                                          timings->clock);
+               i >>= 1;
+       }
+
+       if (timings->trailer_space) {
+               if (!(*ev)->pulse)
+                       (*ev)->duration += timings->trailer_space;
+               else if (!max--)
+                       goto nobufs;
+               else
+                       init_ir_raw_event_duration(++(*ev), 0,
+                                                  timings->trailer_space);
+       }
+
+       ret = 0;
+nobufs:
+       /* point to the next event rather than last event before returning */
+       ++(*ev);
+       return ret;
+}
+EXPORT_SYMBOL(ir_raw_gen_manchester);
+
+/**
+ * ir_raw_gen_pd() - Encode data to raw events with pulse-distance modulation.
+ * @ev:                Pointer to pointer to next free event. *@ev is incremented for
+ *             each raw event filled.
+ * @max:       Maximum number of raw events to fill.
+ * @timings:   Pulse distance modulation timings.
+ * @n:         Number of bits of data.
+ * @data:      Data bits to encode.
+ *
+ * Encodes the @n least significant bits of @data using pulse-distance
+ * modulation with the timing characteristics described by @timings, writing up
+ * to @max raw IR events using the *@ev pointer.
+ *
+ * Returns:    0 on success.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             full encoded data. In this case all @max events will have been
+ *             written.
+ */
+int ir_raw_gen_pd(struct ir_raw_event **ev, unsigned int max,
+                 const struct ir_raw_timings_pd *timings,
+                 unsigned int n, u64 data)
+{
+       int i;
+       int ret;
+       unsigned int space;
+
+       if (timings->header_pulse) {
+               ret = ir_raw_gen_pulse_space(ev, &max, timings->header_pulse,
+                                            timings->header_space);
+               if (ret)
+                       return ret;
+       }
+
+       if (timings->msb_first) {
+               for (i = n - 1; i >= 0; --i) {
+                       space = timings->bit_space[(data >> i) & 1];
+                       ret = ir_raw_gen_pulse_space(ev, &max,
+                                                    timings->bit_pulse,
+                                                    space);
+                       if (ret)
+                               return ret;
+               }
+       } else {
+               for (i = 0; i < n; ++i, data >>= 1) {
+                       space = timings->bit_space[data & 1];
+                       ret = ir_raw_gen_pulse_space(ev, &max,
+                                                    timings->bit_pulse,
+                                                    space);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       ret = ir_raw_gen_pulse_space(ev, &max, timings->trailer_pulse,
+                                    timings->trailer_space);
+       return ret;
+}
+EXPORT_SYMBOL(ir_raw_gen_pd);
+
+/**
+ * ir_raw_gen_pl() - Encode data to raw events with pulse-length modulation.
+ * @ev:                Pointer to pointer to next free event. *@ev is incremented for
+ *             each raw event filled.
+ * @max:       Maximum number of raw events to fill.
+ * @timings:   Pulse distance modulation timings.
+ * @n:         Number of bits of data.
+ * @data:      Data bits to encode.
+ *
+ * Encodes the @n least significant bits of @data using space-distance
+ * modulation with the timing characteristics described by @timings, writing up
+ * to @max raw IR events using the *@ev pointer.
+ *
+ * Returns:    0 on success.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             full encoded data. In this case all @max events will have been
+ *             written.
+ */
+int ir_raw_gen_pl(struct ir_raw_event **ev, unsigned int max,
+                 const struct ir_raw_timings_pl *timings,
+                 unsigned int n, u64 data)
+{
+       int i;
+       int ret = -ENOBUFS;
+       unsigned int pulse;
+
+       if (!max--)
+               return ret;
+
+       init_ir_raw_event_duration((*ev)++, 1, timings->header_pulse);
+
+       if (timings->msb_first) {
+               for (i = n - 1; i >= 0; --i) {
+                       if (!max--)
+                               return ret;
+                       init_ir_raw_event_duration((*ev)++, 0,
+                                                  timings->bit_space);
+                       if (!max--)
+                               return ret;
+                       pulse = timings->bit_pulse[(data >> i) & 1];
+                       init_ir_raw_event_duration((*ev)++, 1, pulse);
+               }
+       } else {
+               for (i = 0; i < n; ++i, data >>= 1) {
+                       if (!max--)
+                               return ret;
+                       init_ir_raw_event_duration((*ev)++, 0,
+                                                  timings->bit_space);
+                       if (!max--)
+                               return ret;
+                       pulse = timings->bit_pulse[data & 1];
+                       init_ir_raw_event_duration((*ev)++, 1, pulse);
+               }
+       }
+
+       if (!max--)
+               return ret;
+
+       init_ir_raw_event_duration((*ev)++, 0, timings->trailer_space);
+
+       return 0;
+}
+EXPORT_SYMBOL(ir_raw_gen_pl);
+
+/**
+ * ir_raw_encode_scancode() - Encode a scancode as raw events
+ *
+ * @protocol:          protocol
+ * @scancode:          scancode filter describing a single scancode
+ * @events:            array of raw events to write into
+ * @max:               max number of raw events
+ *
+ * Attempts to encode the scancode as raw events.
+ *
+ * Returns:    The number of events written.
+ *             -ENOBUFS if there isn't enough space in the array to fit the
+ *             encoding. In this case all @max events will have been written.
+ *             -EINVAL if the scancode is ambiguous or invalid, or if no
+ *             compatible encoder was found.
+ */
+int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode,
+                          struct ir_raw_event *events, unsigned int max)
+{
+       struct ir_raw_handler *handler;
+       int ret = -EINVAL;
+       u64 mask = 1ULL << protocol;
+
+       mutex_lock(&ir_raw_handler_lock);
+       list_for_each_entry(handler, &ir_raw_handler_list, list) {
+               if (handler->protocols & mask && handler->encode) {
+                       ret = handler->encode(protocol, scancode, events, max);
+                       if (ret >= 0 || ret == -ENOBUFS)
+                               break;
+               }
+       }
+       mutex_unlock(&ir_raw_handler_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL(ir_raw_encode_scancode);
+
 /*
  * Used to (un)register raw event clients
  */
@@ -269,13 +502,18 @@ int ir_raw_event_register(struct rc_dev *dev)
        dev->change_protocol = change_protocol;
        INIT_KFIFO(dev->raw->kfifo);
 
-       spin_lock_init(&dev->raw->lock);
-       dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
-                                      "rc%u", dev->minor);
+       /*
+        * raw transmitters do not need any event registration
+        * because the event is coming from userspace
+        */
+       if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
+               dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
+                                              "rc%u", dev->minor);
 
-       if (IS_ERR(dev->raw->thread)) {
-               rc = PTR_ERR(dev->raw->thread);
-               goto out;
+               if (IS_ERR(dev->raw->thread)) {
+                       rc = PTR_ERR(dev->raw->thread);
+                       goto out;
+               }
        }
 
        mutex_lock(&ir_raw_handler_lock);
index 63dace8198b0b3dbcb116108e238351fe9684a9e..62195af24fbe7769a8d806454a15329eb72fa8da 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <media/rc-core.h>
 
 #define DRIVER_NAME    "rc-loopback"
@@ -176,12 +173,47 @@ static int loop_set_carrier_report(struct rc_dev *dev, int enable)
        return 0;
 }
 
+static int loop_set_wakeup_filter(struct rc_dev *dev,
+                                 struct rc_scancode_filter *sc)
+{
+       static const unsigned int max = 512;
+       struct ir_raw_event *raw;
+       int ret;
+       int i;
+
+       /* fine to disable filter */
+       if (!sc->mask)
+               return 0;
+
+       /* encode the specified filter and loop it back */
+       raw = kmalloc_array(max, sizeof(*raw), GFP_KERNEL);
+       if (!raw)
+               return -ENOMEM;
+
+       ret = ir_raw_encode_scancode(dev->wakeup_protocol, sc->data, raw, max);
+       /* still loop back the partial raw IR even if it's incomplete */
+       if (ret == -ENOBUFS)
+               ret = max;
+       if (ret >= 0) {
+               /* do the loopback */
+               for (i = 0; i < ret; ++i)
+                       ir_raw_event_store(dev, &raw[i]);
+               ir_raw_event_handle(dev);
+
+               ret = 0;
+       }
+
+       kfree(raw);
+
+       return ret;
+}
+
 static int __init loop_init(void)
 {
        struct rc_dev *rc;
        int ret;
 
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rc) {
                printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
                return -ENOMEM;
@@ -194,8 +226,9 @@ static int __init loop_init(void)
        rc->driver_name         = DRIVER_NAME;
        rc->map_name            = RC_MAP_EMPTY;
        rc->priv                = &loopdev;
-       rc->driver_type         = RC_DRIVER_IR_RAW;
-       rc->allowed_protocols   = RC_BIT_ALL;
+       rc->allowed_protocols   = RC_BIT_ALL_IR_DECODER;
+       rc->allowed_wakeup_protocols = RC_BIT_ALL_IR_ENCODER;
+       rc->encode_wakeup       = true;
        rc->timeout             = 100 * 1000 * 1000; /* 100 ms */
        rc->min_timeout         = 1;
        rc->max_timeout         = UINT_MAX;
@@ -209,6 +242,7 @@ static int __init loop_init(void)
        rc->s_idle              = loop_set_idle;
        rc->s_learning_mode     = loop_set_learning_mode;
        rc->s_carrier_report    = loop_set_carrier_report;
+       rc->s_wakeup_filter     = loop_set_wakeup_filter;
 
        loopdev.txmask          = RXMASK_REGULAR;
        loopdev.txcarrier       = 36000;
index dedaf38c5ff6cceee42e29f5871794f1bad23b1d..2424946740e64fb602f55a30d5f158a212cc88ce 100644 (file)
@@ -724,6 +724,72 @@ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol,
 }
 EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
 
+/**
+ * rc_validate_filter() - checks that the scancode and mask are valid and
+ *                       provides sensible defaults
+ * @dev:       the struct rc_dev descriptor of the device
+ * @filter:    the scancode and mask
+ * @return:    0 or -EINVAL if the filter is not valid
+ */
+static int rc_validate_filter(struct rc_dev *dev,
+                             struct rc_scancode_filter *filter)
+{
+       static u32 masks[] = {
+               [RC_TYPE_RC5] = 0x1f7f,
+               [RC_TYPE_RC5X_20] = 0x1f7f3f,
+               [RC_TYPE_RC5_SZ] = 0x2fff,
+               [RC_TYPE_SONY12] = 0x1f007f,
+               [RC_TYPE_SONY15] = 0xff007f,
+               [RC_TYPE_SONY20] = 0x1fff7f,
+               [RC_TYPE_JVC] = 0xffff,
+               [RC_TYPE_NEC] = 0xffff,
+               [RC_TYPE_NECX] = 0xffffff,
+               [RC_TYPE_NEC32] = 0xffffffff,
+               [RC_TYPE_SANYO] = 0x1fffff,
+               [RC_TYPE_RC6_0] = 0xffff,
+               [RC_TYPE_RC6_6A_20] = 0xfffff,
+               [RC_TYPE_RC6_6A_24] = 0xffffff,
+               [RC_TYPE_RC6_6A_32] = 0xffffffff,
+               [RC_TYPE_RC6_MCE] = 0xffff7fff,
+               [RC_TYPE_SHARP] = 0x1fff,
+       };
+       u32 s = filter->data;
+       enum rc_type protocol = dev->wakeup_protocol;
+
+       switch (protocol) {
+       case RC_TYPE_NECX:
+               if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0)
+                       return -EINVAL;
+               break;
+       case RC_TYPE_NEC32:
+               if ((((s >> 24) ^ ~(s >> 16)) & 0xff) == 0)
+                       return -EINVAL;
+               break;
+       case RC_TYPE_RC6_MCE:
+               if ((s & 0xffff0000) != 0x800f0000)
+                       return -EINVAL;
+               break;
+       case RC_TYPE_RC6_6A_32:
+               if ((s & 0xffff0000) == 0x800f0000)
+                       return -EINVAL;
+               break;
+       default:
+               break;
+       }
+
+       filter->data &= masks[protocol];
+       filter->mask &= masks[protocol];
+
+       /*
+        * If we have to raw encode the IR for wakeup, we cannot have a mask
+        */
+       if (dev->encode_wakeup &&
+           filter->mask != 0 && filter->mask != masks[protocol])
+               return -EINVAL;
+
+       return 0;
+}
+
 int rc_open(struct rc_dev *rdev)
 {
        int rval = 0;
@@ -796,7 +862,7 @@ static const struct {
        { RC_BIT_OTHER,         "other",        NULL                    },
        { RC_BIT_UNKNOWN,       "unknown",      NULL                    },
        { RC_BIT_RC5 |
-         RC_BIT_RC5X,          "rc-5",         "ir-rc5-decoder"        },
+         RC_BIT_RC5X_20,       "rc-5",         "ir-rc5-decoder"        },
        { RC_BIT_NEC |
          RC_BIT_NECX |
          RC_BIT_NEC32,         "nec",          "ir-nec-decoder"        },
@@ -830,11 +896,6 @@ struct rc_filter_attribute {
 };
 #define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr)
 
-#define RC_PROTO_ATTR(_name, _mode, _show, _store, _type)              \
-       struct rc_filter_attribute dev_attr_##_name = {                 \
-               .attr = __ATTR(_name, _mode, _show, _store),            \
-               .type = (_type),                                        \
-       }
 #define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask)      \
        struct rc_filter_attribute dev_attr_##_name = {                 \
                .attr = __ATTR(_name, _mode, _show, _store),            \
@@ -860,13 +921,13 @@ static bool lirc_is_present(void)
 }
 
 /**
- * show_protocols() - shows the current/wakeup IR protocol(s)
+ * show_protocols() - shows the current IR protocol(s)
  * @device:    the device descriptor
  * @mattr:     the device attribute struct
  * @buf:       a pointer to the output buffer
  *
  * This routine is a callback routine for input read the IR protocol type(s).
- * it is trigged by reading /sys/class/rc/rc?/[wakeup_]protocols.
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
  * It returns the protocol names of supported protocols.
  * Enabled protocols are printed in brackets.
  *
@@ -877,7 +938,6 @@ static ssize_t show_protocols(struct device *device,
                              struct device_attribute *mattr, char *buf)
 {
        struct rc_dev *dev = to_rc_dev(device);
-       struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
        u64 allowed, enabled;
        char *tmp = buf;
        int i;
@@ -891,15 +951,10 @@ static ssize_t show_protocols(struct device *device,
 
        mutex_lock(&dev->lock);
 
-       if (fattr->type == RC_FILTER_NORMAL) {
-               enabled = dev->enabled_protocols;
-               allowed = dev->allowed_protocols;
-               if (dev->raw && !allowed)
-                       allowed = ir_raw_get_allowed_protocols();
-       } else {
-               enabled = dev->enabled_wakeup_protocols;
-               allowed = dev->allowed_wakeup_protocols;
-       }
+       enabled = dev->enabled_protocols;
+       allowed = dev->allowed_protocols;
+       if (dev->raw && !allowed)
+               allowed = ir_raw_get_allowed_protocols();
 
        mutex_unlock(&dev->lock);
 
@@ -997,7 +1052,6 @@ static int parse_protocol_change(u64 *protocols, const char *buf)
 }
 
 static void ir_raw_load_modules(u64 *protocols)
-
 {
        u64 available;
        int i, ret;
@@ -1030,8 +1084,7 @@ static void ir_raw_load_modules(u64 *protocols)
                if (!(*protocols & proto_names[i].type & ~available))
                        continue;
 
-               pr_err("Loaded IR protocol module %s, \
-                      but protocol %s still not available\n",
+               pr_err("Loaded IR protocol module %s, but protocol %s still not available\n",
                       proto_names[i].module_name,
                       proto_names[i].name);
                *protocols &= ~proto_names[i].type;
@@ -1058,11 +1111,8 @@ static ssize_t store_protocols(struct device *device,
                               const char *buf, size_t len)
 {
        struct rc_dev *dev = to_rc_dev(device);
-       struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
        u64 *current_protocols;
-       int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        struct rc_scancode_filter *filter;
-       int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);
        u64 old_protocols, new_protocols;
        ssize_t rc;
 
@@ -1073,21 +1123,11 @@ static ssize_t store_protocols(struct device *device,
        if (!atomic_read(&dev->initialized))
                return -ERESTARTSYS;
 
-       if (fattr->type == RC_FILTER_NORMAL) {
-               IR_dprintk(1, "Normal protocol change requested\n");
-               current_protocols = &dev->enabled_protocols;
-               change_protocol = dev->change_protocol;
-               filter = &dev->scancode_filter;
-               set_filter = dev->s_filter;
-       } else {
-               IR_dprintk(1, "Wakeup protocol change requested\n");
-               current_protocols = &dev->enabled_wakeup_protocols;
-               change_protocol = dev->change_wakeup_protocol;
-               filter = &dev->scancode_wakeup_filter;
-               set_filter = dev->s_wakeup_filter;
-       }
+       IR_dprintk(1, "Normal protocol change requested\n");
+       current_protocols = &dev->enabled_protocols;
+       filter = &dev->scancode_filter;
 
-       if (!change_protocol) {
+       if (!dev->change_protocol) {
                IR_dprintk(1, "Protocol switching not supported\n");
                return -EINVAL;
        }
@@ -1100,7 +1140,7 @@ static ssize_t store_protocols(struct device *device,
        if (rc < 0)
                goto out;
 
-       rc = change_protocol(dev, &new_protocols);
+       rc = dev->change_protocol(dev, &new_protocols);
        if (rc < 0) {
                IR_dprintk(1, "Error setting protocols to 0x%llx\n",
                           (long long)new_protocols);
@@ -1123,16 +1163,16 @@ static ssize_t store_protocols(struct device *device,
         * Try setting the same filter with the new protocol (if any).
         * Fall back to clearing the filter.
         */
-       if (set_filter && filter->mask) {
+       if (dev->s_filter && filter->mask) {
                if (new_protocols)
-                       rc = set_filter(dev, filter);
+                       rc = dev->s_filter(dev, filter);
                else
                        rc = -1;
 
                if (rc < 0) {
                        filter->data = 0;
                        filter->mask = 0;
-                       set_filter(dev, filter);
+                       dev->s_filter(dev, filter);
                }
        }
 
@@ -1221,7 +1261,6 @@ static ssize_t store_filter(struct device *device,
        int ret;
        unsigned long val;
        int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);
-       u64 *enabled_protocols;
 
        /* Device is being removed */
        if (!dev)
@@ -1236,11 +1275,9 @@ static ssize_t store_filter(struct device *device,
 
        if (fattr->type == RC_FILTER_NORMAL) {
                set_filter = dev->s_filter;
-               enabled_protocols = &dev->enabled_protocols;
                filter = &dev->scancode_filter;
        } else {
                set_filter = dev->s_wakeup_filter;
-               enabled_protocols = &dev->enabled_wakeup_protocols;
                filter = &dev->scancode_wakeup_filter;
        }
 
@@ -1255,7 +1292,22 @@ static ssize_t store_filter(struct device *device,
        else
                new_filter.data = val;
 
-       if (!*enabled_protocols && val) {
+       if (fattr->type == RC_FILTER_WAKEUP) {
+               /*
+                * Refuse to set a filter unless a protocol is enabled
+                * and the filter is valid for that protocol
+                */
+               if (dev->wakeup_protocol != RC_TYPE_UNKNOWN)
+                       ret = rc_validate_filter(dev, &new_filter);
+               else
+                       ret = -EINVAL;
+
+               if (ret != 0)
+                       goto unlock;
+       }
+
+       if (fattr->type == RC_FILTER_NORMAL && !dev->enabled_protocols &&
+           val) {
                /* refuse to set a filter unless a protocol is enabled */
                ret = -EINVAL;
                goto unlock;
@@ -1272,6 +1324,182 @@ unlock:
        return (ret < 0) ? ret : len;
 }
 
+/*
+ * This is the list of all variants of all protocols, which is used by
+ * the wakeup_protocols sysfs entry. In the protocols sysfs entry some
+ * some protocols are grouped together (e.g. nec = nec + necx + nec32).
+ *
+ * For wakeup we need to know the exact protocol variant so the hardware
+ * can be programmed exactly what to expect.
+ */
+static const char * const proto_variant_names[] = {
+       [RC_TYPE_UNKNOWN] = "unknown",
+       [RC_TYPE_OTHER] = "other",
+       [RC_TYPE_RC5] = "rc-5",
+       [RC_TYPE_RC5X_20] = "rc-5x-20",
+       [RC_TYPE_RC5_SZ] = "rc-5-sz",
+       [RC_TYPE_JVC] = "jvc",
+       [RC_TYPE_SONY12] = "sony-12",
+       [RC_TYPE_SONY15] = "sony-15",
+       [RC_TYPE_SONY20] = "sony-20",
+       [RC_TYPE_NEC] = "nec",
+       [RC_TYPE_NECX] = "nec-x",
+       [RC_TYPE_NEC32] = "nec-32",
+       [RC_TYPE_SANYO] = "sanyo",
+       [RC_TYPE_MCE_KBD] = "mce_kbd",
+       [RC_TYPE_RC6_0] = "rc-6-0",
+       [RC_TYPE_RC6_6A_20] = "rc-6-6a-20",
+       [RC_TYPE_RC6_6A_24] = "rc-6-6a-24",
+       [RC_TYPE_RC6_6A_32] = "rc-6-6a-32",
+       [RC_TYPE_RC6_MCE] = "rc-6-mce",
+       [RC_TYPE_SHARP] = "sharp",
+       [RC_TYPE_XMP] = "xmp",
+       [RC_TYPE_CEC] = "cec",
+};
+
+/**
+ * show_wakeup_protocols() - shows the wakeup IR protocol
+ * @device:    the device descriptor
+ * @mattr:     the device attribute struct
+ * @buf:       a pointer to the output buffer
+ *
+ * This routine is a callback routine for input read the IR protocol type(s).
+ * it is trigged by reading /sys/class/rc/rc?/wakeup_protocols.
+ * It returns the protocol names of supported protocols.
+ * The enabled protocols are printed in brackets.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_protocols and show_protocols.
+ */
+static ssize_t show_wakeup_protocols(struct device *device,
+                                    struct device_attribute *mattr,
+                                    char *buf)
+{
+       struct rc_dev *dev = to_rc_dev(device);
+       u64 allowed;
+       enum rc_type enabled;
+       char *tmp = buf;
+       int i;
+
+       /* Device is being removed */
+       if (!dev)
+               return -EINVAL;
+
+       if (!atomic_read(&dev->initialized))
+               return -ERESTARTSYS;
+
+       mutex_lock(&dev->lock);
+
+       allowed = dev->allowed_wakeup_protocols;
+       enabled = dev->wakeup_protocol;
+
+       mutex_unlock(&dev->lock);
+
+       IR_dprintk(1, "%s: allowed - 0x%llx, enabled - %d\n",
+                  __func__, (long long)allowed, enabled);
+
+       for (i = 0; i < ARRAY_SIZE(proto_variant_names); i++) {
+               if (allowed & (1ULL << i)) {
+                       if (i == enabled)
+                               tmp += sprintf(tmp, "[%s] ",
+                                               proto_variant_names[i]);
+                       else
+                               tmp += sprintf(tmp, "%s ",
+                                               proto_variant_names[i]);
+               }
+       }
+
+       if (tmp != buf)
+               tmp--;
+       *tmp = '\n';
+
+       return tmp + 1 - buf;
+}
+
+/**
+ * store_wakeup_protocols() - changes the wakeup IR protocol(s)
+ * @device:    the device descriptor
+ * @mattr:     the device attribute struct
+ * @buf:       a pointer to the input buffer
+ * @len:       length of the input buffer
+ *
+ * This routine is for changing the IR protocol type.
+ * It is trigged by writing to /sys/class/rc/rc?/wakeup_protocols.
+ * Returns @len on success or a negative error code.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_protocols and show_protocols.
+ */
+static ssize_t store_wakeup_protocols(struct device *device,
+                                     struct device_attribute *mattr,
+                                     const char *buf, size_t len)
+{
+       struct rc_dev *dev = to_rc_dev(device);
+       enum rc_type protocol;
+       ssize_t rc;
+       u64 allowed;
+       int i;
+
+       /* Device is being removed */
+       if (!dev)
+               return -EINVAL;
+
+       if (!atomic_read(&dev->initialized))
+               return -ERESTARTSYS;
+
+       mutex_lock(&dev->lock);
+
+       allowed = dev->allowed_wakeup_protocols;
+
+       if (sysfs_streq(buf, "none")) {
+               protocol = RC_TYPE_UNKNOWN;
+       } else {
+               for (i = 0; i < ARRAY_SIZE(proto_variant_names); i++) {
+                       if ((allowed & (1ULL << i)) &&
+                           sysfs_streq(buf, proto_variant_names[i])) {
+                               protocol = i;
+                               break;
+                       }
+               }
+
+               if (i == ARRAY_SIZE(proto_variant_names)) {
+                       rc = -EINVAL;
+                       goto out;
+               }
+
+               if (dev->encode_wakeup) {
+                       u64 mask = 1ULL << protocol;
+
+                       ir_raw_load_modules(&mask);
+                       if (!mask) {
+                               rc = -EINVAL;
+                               goto out;
+                       }
+               }
+       }
+
+       if (dev->wakeup_protocol != protocol) {
+               dev->wakeup_protocol = protocol;
+               IR_dprintk(1, "Wakeup protocol changed to %d\n", protocol);
+
+               if (protocol == RC_TYPE_RC6_MCE)
+                       dev->scancode_wakeup_filter.data = 0x800f0000;
+               else
+                       dev->scancode_wakeup_filter.data = 0;
+               dev->scancode_wakeup_filter.mask = 0;
+
+               rc = dev->s_wakeup_filter(dev, &dev->scancode_wakeup_filter);
+               if (rc == 0)
+                       rc = len;
+       } else {
+               rc = len;
+       }
+
+out:
+       mutex_unlock(&dev->lock);
+       return rc;
+}
+
 static void rc_dev_release(struct device *device)
 {
        struct rc_dev *dev = to_rc_dev(device);
@@ -1301,10 +1529,9 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
 /*
  * Static device attribute struct with the sysfs attributes for IR's
  */
-static RC_PROTO_ATTR(protocols, S_IRUGO | S_IWUSR,
-                    show_protocols, store_protocols, RC_FILTER_NORMAL);
-static RC_PROTO_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR,
-                    show_protocols, store_protocols, RC_FILTER_WAKEUP);
+static DEVICE_ATTR(protocols, 0644, show_protocols, store_protocols);
+static DEVICE_ATTR(wakeup_protocols, 0644, show_wakeup_protocols,
+                  store_wakeup_protocols);
 static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR,
                      show_filter, store_filter, RC_FILTER_NORMAL, false);
 static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR,
@@ -1315,7 +1542,7 @@ static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR,
                      show_filter, store_filter, RC_FILTER_WAKEUP, true);
 
 static struct attribute *rc_dev_protocol_attrs[] = {
-       &dev_attr_protocols.attr.attr,
+       &dev_attr_protocols.attr,
        NULL,
 };
 
@@ -1323,15 +1550,6 @@ static struct attribute_group rc_dev_protocol_attr_grp = {
        .attrs  = rc_dev_protocol_attrs,
 };
 
-static struct attribute *rc_dev_wakeup_protocol_attrs[] = {
-       &dev_attr_wakeup_protocols.attr.attr,
-       NULL,
-};
-
-static struct attribute_group rc_dev_wakeup_protocol_attr_grp = {
-       .attrs  = rc_dev_wakeup_protocol_attrs,
-};
-
 static struct attribute *rc_dev_filter_attrs[] = {
        &dev_attr_filter.attr.attr,
        &dev_attr_filter_mask.attr.attr,
@@ -1345,6 +1563,7 @@ static struct attribute_group rc_dev_filter_attr_grp = {
 static struct attribute *rc_dev_wakeup_filter_attrs[] = {
        &dev_attr_wakeup_filter.attr.attr,
        &dev_attr_wakeup_filter_mask.attr.attr,
+       &dev_attr_wakeup_protocols.attr,
        NULL,
 };
 
@@ -1357,7 +1576,7 @@ static struct device_type rc_dev_type = {
        .uevent         = rc_dev_uevent,
 };
 
-struct rc_dev *rc_allocate_device(void)
+struct rc_dev *rc_allocate_device(enum rc_driver_type type)
 {
        struct rc_dev *dev;
 
@@ -1365,25 +1584,31 @@ struct rc_dev *rc_allocate_device(void)
        if (!dev)
                return NULL;
 
-       dev->input_dev = input_allocate_device();
-       if (!dev->input_dev) {
-               kfree(dev);
-               return NULL;
-       }
+       if (type != RC_DRIVER_IR_RAW_TX) {
+               dev->input_dev = input_allocate_device();
+               if (!dev->input_dev) {
+                       kfree(dev);
+                       return NULL;
+               }
 
-       dev->input_dev->getkeycode = ir_getkeycode;
-       dev->input_dev->setkeycode = ir_setkeycode;
-       input_set_drvdata(dev->input_dev, dev);
+               dev->input_dev->getkeycode = ir_getkeycode;
+               dev->input_dev->setkeycode = ir_setkeycode;
+               input_set_drvdata(dev->input_dev, dev);
 
-       spin_lock_init(&dev->rc_map.lock);
-       spin_lock_init(&dev->keylock);
+               setup_timer(&dev->timer_keyup, ir_timer_keyup,
+                           (unsigned long)dev);
+
+               spin_lock_init(&dev->rc_map.lock);
+               spin_lock_init(&dev->keylock);
+       }
        mutex_init(&dev->lock);
-       setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
 
        dev->dev.type = &rc_dev_type;
        dev->dev.class = &rc_class;
        device_initialize(&dev->dev);
 
+       dev->driver_type = type;
+
        __module_get(THIS_MODULE);
        return dev;
 }
@@ -1410,7 +1635,8 @@ static void devm_rc_alloc_release(struct device *dev, void *res)
        rc_free_device(*(struct rc_dev **)res);
 }
 
-struct rc_dev *devm_rc_allocate_device(struct device *dev)
+struct rc_dev *devm_rc_allocate_device(struct device *dev,
+                                      enum rc_driver_type type)
 {
        struct rc_dev **dr, *rc;
 
@@ -1418,7 +1644,7 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev)
        if (!dr)
                return NULL;
 
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(type);
        if (!rc) {
                devres_free(dr);
                return NULL;
@@ -1433,16 +1659,12 @@ struct rc_dev *devm_rc_allocate_device(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(devm_rc_allocate_device);
 
-int rc_register_device(struct rc_dev *dev)
+static int rc_setup_rx_device(struct rc_dev *dev)
 {
-       static bool raw_init = false; /* raw decoders loaded? */
-       struct rc_map *rc_map;
-       const char *path;
-       int attr = 0;
-       int minor;
        int rc;
+       struct rc_map *rc_map;
 
-       if (!dev || !dev->map_name)
+       if (!dev->map_name)
                return -EINVAL;
 
        rc_map = rc_map_get(dev->map_name);
@@ -1451,6 +1673,19 @@ int rc_register_device(struct rc_dev *dev)
        if (!rc_map || !rc_map->scan || rc_map->size == 0)
                return -EINVAL;
 
+       rc = ir_setkeytable(dev, rc_map);
+       if (rc)
+               return rc;
+
+       if (dev->change_protocol) {
+               u64 rc_type = (1ll << rc_map->rc_type);
+
+               rc = dev->change_protocol(dev, &rc_type);
+               if (rc < 0)
+                       goto out_table;
+               dev->enabled_protocols = rc_type;
+       }
+
        set_bit(EV_KEY, dev->input_dev->evbit);
        set_bit(EV_REP, dev->input_dev->evbit);
        set_bit(EV_MSC, dev->input_dev->evbit);
@@ -1460,6 +1695,61 @@ int rc_register_device(struct rc_dev *dev)
        if (dev->close)
                dev->input_dev->close = ir_close;
 
+       /*
+        * Default delay of 250ms is too short for some protocols, especially
+        * since the timeout is currently set to 250ms. Increase it to 500ms,
+        * to avoid wrong repetition of the keycodes. Note that this must be
+        * set after the call to input_register_device().
+        */
+       dev->input_dev->rep[REP_DELAY] = 500;
+
+       /*
+        * As a repeat event on protocols like RC-5 and NEC take as long as
+        * 110/114ms, using 33ms as a repeat period is not the right thing
+        * to do.
+        */
+       dev->input_dev->rep[REP_PERIOD] = 125;
+
+       dev->input_dev->dev.parent = &dev->dev;
+       memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
+       dev->input_dev->phys = dev->input_phys;
+       dev->input_dev->name = dev->input_name;
+
+       /* rc_open will be called here */
+       rc = input_register_device(dev->input_dev);
+       if (rc)
+               goto out_table;
+
+       return 0;
+
+out_table:
+       ir_free_table(&dev->rc_map);
+
+       return rc;
+}
+
+static void rc_free_rx_device(struct rc_dev *dev)
+{
+       if (!dev || dev->driver_type == RC_DRIVER_IR_RAW_TX)
+               return;
+
+       ir_free_table(&dev->rc_map);
+
+       input_unregister_device(dev->input_dev);
+       dev->input_dev = NULL;
+}
+
+int rc_register_device(struct rc_dev *dev)
+{
+       static bool raw_init; /* 'false' default value, raw decoders loaded? */
+       const char *path;
+       int attr = 0;
+       int minor;
+       int rc;
+
+       if (!dev)
+               return -EINVAL;
+
        minor = ida_simple_get(&rc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
        if (minor < 0)
                return minor;
@@ -1470,89 +1760,51 @@ int rc_register_device(struct rc_dev *dev)
        atomic_set(&dev->initialized, 0);
 
        dev->dev.groups = dev->sysfs_groups;
-       dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
+       if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+               dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
        if (dev->s_filter)
                dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;
        if (dev->s_wakeup_filter)
                dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
-       if (dev->change_wakeup_protocol)
-               dev->sysfs_groups[attr++] = &rc_dev_wakeup_protocol_attr_grp;
        dev->sysfs_groups[attr++] = NULL;
 
        rc = device_add(&dev->dev);
        if (rc)
                goto out_unlock;
 
-       rc = ir_setkeytable(dev, rc_map);
-       if (rc)
-               goto out_dev;
-
-       dev->input_dev->dev.parent = &dev->dev;
-       memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
-       dev->input_dev->phys = dev->input_phys;
-       dev->input_dev->name = dev->input_name;
-
-       rc = input_register_device(dev->input_dev);
-       if (rc)
-               goto out_table;
-
-       /*
-        * Default delay of 250ms is too short for some protocols, especially
-        * since the timeout is currently set to 250ms. Increase it to 500ms,
-        * to avoid wrong repetition of the keycodes. Note that this must be
-        * set after the call to input_register_device().
-        */
-       dev->input_dev->rep[REP_DELAY] = 500;
-
-       /*
-        * As a repeat event on protocols like RC-5 and NEC take as long as
-        * 110/114ms, using 33ms as a repeat period is not the right thing
-        * to do.
-        */
-       dev->input_dev->rep[REP_PERIOD] = 125;
-
        path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
        dev_info(&dev->dev, "%s as %s\n",
                dev->input_name ?: "Unspecified device", path ?: "N/A");
        kfree(path);
 
-       if (dev->driver_type == RC_DRIVER_IR_RAW) {
+       if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
+               rc = rc_setup_rx_device(dev);
+               if (rc)
+                       goto out_dev;
+       }
+
+       if (dev->driver_type == RC_DRIVER_IR_RAW ||
+           dev->driver_type == RC_DRIVER_IR_RAW_TX) {
                if (!raw_init) {
                        request_module_nowait("ir-lirc-codec");
                        raw_init = true;
                }
                rc = ir_raw_event_register(dev);
                if (rc < 0)
-                       goto out_input;
-       }
-
-       if (dev->change_protocol) {
-               u64 rc_type = (1ll << rc_map->rc_type);
-               rc = dev->change_protocol(dev, &rc_type);
-               if (rc < 0)
-                       goto out_raw;
-               dev->enabled_protocols = rc_type;
+                       goto out_rx;
        }
 
        /* Allow the RC sysfs nodes to be accessible */
        atomic_set(&dev->initialized, 1);
 
-       IR_dprintk(1, "Registered rc%u (driver: %s, remote: %s, mode %s)\n",
+       IR_dprintk(1, "Registered rc%u (driver: %s)\n",
                   dev->minor,
-                  dev->driver_name ? dev->driver_name : "unknown",
-                  rc_map->name ? rc_map->name : "unknown",
-                  dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked");
+                  dev->driver_name ? dev->driver_name : "unknown");
 
        return 0;
 
-out_raw:
-       if (dev->driver_type == RC_DRIVER_IR_RAW)
-               ir_raw_event_unregister(dev);
-out_input:
-       input_unregister_device(dev->input_dev);
-       dev->input_dev = NULL;
-out_table:
-       ir_free_table(&dev->rc_map);
+out_rx:
+       rc_free_rx_device(dev);
 out_dev:
        device_del(&dev->dev);
 out_unlock:
@@ -1598,12 +1850,7 @@ void rc_unregister_device(struct rc_dev *dev)
        if (dev->driver_type == RC_DRIVER_IR_RAW)
                ir_raw_event_unregister(dev);
 
-       /* Freeing the table should also call the stop callback */
-       ir_free_table(&dev->rc_map);
-       IR_dprintk(1, "Freed keycode table\n");
-
-       input_unregister_device(dev->input_dev);
-       dev->input_dev = NULL;
+       rc_free_rx_device(dev);
 
        device_del(&dev->dev);
 
index 2784f5dae398ee9483a36cdeec5217a9a1f6fcc7..56d43be2756b8c645e633cd9b03f6729a387a982 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #include <asm/unaligned.h>
@@ -945,7 +941,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
        int ret;
        u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);
 
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rc)
                return NULL;
 
@@ -960,8 +956,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
        usb_to_input_id(rr3->udev, &rc->input_id);
        rc->dev.parent = dev;
        rc->priv = rr3;
-       rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protocols = RC_BIT_ALL;
+       rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
        rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
        rc->timeout = US_TO_NS(redrat3_get_timeout(rr3));
index 436bd58b5f05f252098ec433ac7305feb033034e..923fb2299553cb96c0db87368a322ea875da4652 100644 (file)
@@ -137,6 +137,7 @@ struct serial_ir {
        ktime_t lastkt;
        struct rc_dev *rcdev;
        struct platform_device *pdev;
+       struct timer_list timeout_timer;
 
        unsigned int freq;
        unsigned int duty_cycle;
@@ -395,9 +396,14 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah)
                        frbwrite(data, !(dcd ^ sense));
                        serial_ir.lastkt = kt;
                        last_dcd = dcd;
-                       ir_raw_event_handle(serial_ir.rcdev);
                }
        } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
+
+       mod_timer(&serial_ir.timeout_timer,
+                 jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout));
+
+       ir_raw_event_handle(serial_ir.rcdev);
+
        return IRQ_HANDLED;
 }
 
@@ -471,6 +477,16 @@ static int hardware_init_port(void)
        return 0;
 }
 
+static void serial_ir_timeout(unsigned long arg)
+{
+       DEFINE_IR_RAW_EVENT(ev);
+
+       ev.timeout = true;
+       ev.duration = serial_ir.rcdev->timeout;
+       ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
+       ir_raw_event_handle(serial_ir.rcdev);
+}
+
 static int serial_ir_probe(struct platform_device *dev)
 {
        int i, nlow, nhigh, result;
@@ -500,6 +516,9 @@ static int serial_ir_probe(struct platform_device *dev)
                return -EBUSY;
        }
 
+       setup_timer(&serial_ir.timeout_timer, serial_ir_timeout,
+                   (unsigned long)&serial_ir);
+
        result = hardware_init_port();
        if (result < 0)
                return result;
@@ -738,7 +757,7 @@ static int __init serial_ir_init_module(void)
        if (result)
                return result;
 
-       rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev);
+       rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev, RC_DRIVER_IR_RAW);
        if (!rcdev) {
                result = -ENOMEM;
                goto serial_cleanup;
@@ -777,11 +796,12 @@ static int __init serial_ir_init_module(void)
        rcdev->open = serial_ir_open;
        rcdev->close = serial_ir_close;
        rcdev->dev.parent = &serial_ir.pdev->dev;
-       rcdev->driver_type = RC_DRIVER_IR_RAW;
-       rcdev->allowed_protocols = RC_BIT_ALL;
+       rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rcdev->driver_name = KBUILD_MODNAME;
        rcdev->map_name = RC_MAP_RC6_MCE;
+       rcdev->min_timeout = 1;
        rcdev->timeout = IR_DEFAULT_TIMEOUT;
+       rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
        rcdev->rx_resolution = 250000;
 
        serial_ir.rcdev = rcdev;
@@ -797,6 +817,7 @@ serial_cleanup:
 
 static void __exit serial_ir_exit_module(void)
 {
+       del_timer_sync(&serial_ir.timeout_timer);
        rc_unregister_device(serial_ir.rcdev);
        serial_ir_exit();
 }
index 1fa0c9d1c5083766c53bafe11d5e955bdd6c838a..f0d7190e391952be799b5265d8a78c217bbc9430 100644 (file)
@@ -235,7 +235,7 @@ static int st_rc_probe(struct platform_device *pdev)
        if (!rc_dev)
                return -ENOMEM;
 
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
 
        if (!rdev)
                return -ENOMEM;
@@ -290,8 +290,7 @@ static int st_rc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, rc_dev);
        st_rc_hardware_init(rc_dev);
 
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        /* rx sampling rate is 10Mhz */
        rdev->rx_resolution = 100;
        rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
index 53f9b0af358a463acdaa91e64c679c952f69a3cc..b09c45abb5f3280d2b2c474ea49528bf9333e35f 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/device.h>
@@ -291,7 +287,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
        struct device *dev = sz->dev;
        int ret;
 
-       rdev = rc_allocate_device();
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!rdev) {
                dev_err(dev, "remote dev allocation failed\n");
                goto out;
@@ -308,8 +304,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
        usb_to_input_id(sz->usbdev, &rdev->input_id);
        rdev->dev.parent = dev;
        rdev->priv = sz;
-       rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protocols = RC_BIT_ALL;
+       rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rdev->driver_name = DRIVER_NAME;
        rdev->map_name = RC_MAP_STREAMZAP;
 
index eaadc081760ae1ec21a5a3ff018ad42ee497c5f0..25b006167810221a26181e9128070ea12eb4ee15 100644 (file)
@@ -212,7 +212,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
                goto exit_clkdisable_clk;
        }
 
-       ir->rc = rc_allocate_device();
+       ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!ir->rc) {
                dev_err(dev, "failed to allocate device\n");
                ret = -ENOMEM;
@@ -229,8 +229,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
        ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
        ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
        ir->rc->dev.parent = dev;
-       ir->rc->driver_type = RC_DRIVER_IR_RAW;
-       ir->rc->allowed_protocols = RC_BIT_ALL;
+       ir->rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        ir->rc->rx_resolution = SUNXI_IR_SAMPLE;
        ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT);
        ir->rc->driver_name = SUNXI_IR_DEV;
index bc214e2b3a368941c857d5b176fa28ada8fd7c80..23be7702e2dfbf0ee4989cb968ed81288aef68cd 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/module.h>
@@ -205,7 +201,7 @@ static int ttusbir_probe(struct usb_interface *intf,
        int altsetting = -1;
 
        tt = kzalloc(sizeof(*tt), GFP_KERNEL);
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!tt || !rc) {
                ret = -ENOMEM;
                goto out;
@@ -317,12 +313,14 @@ static int ttusbir_probe(struct usb_interface *intf,
        rc->input_phys = tt->phys;
        usb_to_input_id(tt->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
-       rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protocols = RC_BIT_ALL;
+       rc->allowed_protocols = RC_BIT_ALL_IR_DECODER;
        rc->priv = tt;
        rc->driver_name = DRIVER_NAME;
        rc->map_name = RC_MAP_TT_1500;
-       rc->timeout = MS_TO_NS(100);
+       rc->min_timeout = 1;
+       rc->timeout = IR_DEFAULT_TIMEOUT;
+       rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
+
        /*
         * The precision is NS_PER_BIT, but since every 8th bit can be
         * overwritten with garbage the accuracy is at best 2 * NS_PER_BIT.
index 78491ed48d92eae15fd5b72d6b46462d40e3dde5..dc1c8305ad23572933f63caa1e340592e40c65a4 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -194,7 +190,6 @@ enum wbcir_txstate {
 #define WBCIR_NAME     "Winbond CIR"
 #define WBCIR_ID_FAMILY          0xF1 /* Family ID for the WPCD376I    */
 #define        WBCIR_ID_CHIP            0x04 /* Chip ID for the WPCD376I       */
-#define INVALID_SCANCODE   0x7FFFFFFF /* Invalid with all protos       */
 #define WAKEUP_IOMEM_LEN         0x10 /* Wake-Up I/O Reg Len           */
 #define EHFUNC_IOMEM_LEN         0x10 /* Enhanced Func I/O Reg Len     */
 #define SP_IOMEM_LEN             0x08 /* Serial Port 3 (IR) Reg Len    */
@@ -225,10 +220,6 @@ struct wbcir_data {
        u32 txcarrier;
 };
 
-static enum wbcir_protocol protocol = IR_PROTOCOL_RC6;
-module_param(protocol, uint, 0444);
-MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command (0 = RC5, 1 = NEC, 2 = RC6A, default)");
-
 static bool invert; /* default = 0 */
 module_param(invert, bool, 0444);
 MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver");
@@ -237,15 +228,6 @@ static bool txandrx; /* default = 0 */
 module_param(txandrx, bool, 0444);
 MODULE_PARM_DESC(txandrx, "Allow simultaneous TX and RX");
 
-static unsigned int wake_sc = 0x800F040C;
-module_param(wake_sc, uint, 0644);
-MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command");
-
-static unsigned int wake_rc6mode = 6;
-module_param(wake_rc6mode, uint, 0644);
-MODULE_PARM_DESC(wake_rc6mode, "RC6 mode for the power-on command (0 = 0, 6 = 6A, default)");
-
-
 
 /*****************************************************************************
  *
@@ -696,138 +678,153 @@ wbcir_shutdown(struct pnp_dev *device)
 {
        struct device *dev = &device->dev;
        struct wbcir_data *data = pnp_get_drvdata(device);
+       struct rc_dev *rc = data->dev;
        bool do_wake = true;
        u8 match[11];
        u8 mask[11];
        u8 rc6_csl = 0;
+       u8 proto;
+       u32 wake_sc = rc->scancode_wakeup_filter.data;
+       u32 mask_sc = rc->scancode_wakeup_filter.mask;
        int i;
 
        memset(match, 0, sizeof(match));
        memset(mask, 0, sizeof(mask));
 
-       if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) {
+       if (!mask_sc || !device_may_wakeup(dev)) {
                do_wake = false;
                goto finish;
        }
 
-       switch (protocol) {
-       case IR_PROTOCOL_RC5:
-               if (wake_sc > 0xFFF) {
-                       do_wake = false;
-                       dev_err(dev, "RC5 - Invalid wake scancode\n");
-                       break;
-               }
-
+       switch (rc->wakeup_protocol) {
+       case RC_TYPE_RC5:
                /* Mask = 13 bits, ex toggle */
-               mask[0] = 0xFF;
-               mask[1] = 0x17;
+               mask[0]  = (mask_sc & 0x003f);
+               mask[0] |= (mask_sc & 0x0300) >> 2;
+               mask[1]  = (mask_sc & 0x1c00) >> 10;
+               if (mask_sc & 0x0040)                 /* 2nd start bit  */
+                       match[1] |= 0x10;
 
-               match[0]  = (wake_sc & 0x003F);      /* 6 command bits */
-               match[0] |= (wake_sc & 0x0180) >> 1; /* 2 address bits */
-               match[1]  = (wake_sc & 0x0E00) >> 9; /* 3 address bits */
-               if (!(wake_sc & 0x0040))             /* 2nd start bit  */
+               match[0]  = (wake_sc & 0x003F);       /* 6 command bits */
+               match[0] |= (wake_sc & 0x0300) >> 2;  /* 2 address bits */
+               match[1]  = (wake_sc & 0x1c00) >> 10; /* 3 address bits */
+               if (!(wake_sc & 0x0040))              /* 2nd start bit  */
                        match[1] |= 0x10;
 
+               proto = IR_PROTOCOL_RC5;
                break;
 
-       case IR_PROTOCOL_NEC:
-               if (wake_sc > 0xFFFFFF) {
-                       do_wake = false;
-                       dev_err(dev, "NEC - Invalid wake scancode\n");
-                       break;
-               }
+       case RC_TYPE_NEC:
+               mask[1] = bitrev8(mask_sc);
+               mask[0] = mask[1];
+               mask[3] = bitrev8(mask_sc >> 8);
+               mask[2] = mask[3];
 
-               mask[0] = mask[1] = mask[2] = mask[3] = 0xFF;
-
-               match[1] = bitrev8((wake_sc & 0xFF));
+               match[1] = bitrev8(wake_sc);
                match[0] = ~match[1];
+               match[3] = bitrev8(wake_sc >> 8);
+               match[2] = ~match[3];
 
-               match[3] = bitrev8((wake_sc & 0xFF00) >> 8);
-               if (wake_sc > 0xFFFF)
-                       match[2] = bitrev8((wake_sc & 0xFF0000) >> 16);
-               else
-                       match[2] = ~match[3];
+               proto = IR_PROTOCOL_NEC;
+               break;
+
+       case RC_TYPE_NECX:
+               mask[1] = bitrev8(mask_sc);
+               mask[0] = mask[1];
+               mask[2] = bitrev8(mask_sc >> 8);
+               mask[3] = bitrev8(mask_sc >> 16);
 
+               match[1] = bitrev8(wake_sc);
+               match[0] = ~match[1];
+               match[2] = bitrev8(wake_sc >> 8);
+               match[3] = bitrev8(wake_sc >> 16);
+
+               proto = IR_PROTOCOL_NEC;
                break;
 
-       case IR_PROTOCOL_RC6:
+       case RC_TYPE_NEC32:
+               mask[0] = bitrev8(mask_sc);
+               mask[1] = bitrev8(mask_sc >> 8);
+               mask[2] = bitrev8(mask_sc >> 16);
+               mask[3] = bitrev8(mask_sc >> 24);
 
-               if (wake_rc6mode == 0) {
-                       if (wake_sc > 0xFFFF) {
-                               do_wake = false;
-                               dev_err(dev, "RC6 - Invalid wake scancode\n");
-                               break;
-                       }
+               match[0] = bitrev8(wake_sc);
+               match[1] = bitrev8(wake_sc >> 8);
+               match[2] = bitrev8(wake_sc >> 16);
+               match[3] = bitrev8(wake_sc >> 24);
 
-                       /* Command */
-                       match[0] = wbcir_to_rc6cells(wake_sc >>  0);
-                       mask[0]  = 0xFF;
-                       match[1] = wbcir_to_rc6cells(wake_sc >>  4);
-                       mask[1]  = 0xFF;
-
-                       /* Address */
-                       match[2] = wbcir_to_rc6cells(wake_sc >>  8);
-                       mask[2]  = 0xFF;
-                       match[3] = wbcir_to_rc6cells(wake_sc >> 12);
-                       mask[3]  = 0xFF;
-
-                       /* Header */
-                       match[4] = 0x50; /* mode1 = mode0 = 0, ignore toggle */
-                       mask[4]  = 0xF0;
-                       match[5] = 0x09; /* start bit = 1, mode2 = 0 */
-                       mask[5]  = 0x0F;
-
-                       rc6_csl = 44;
-
-               } else if (wake_rc6mode == 6) {
-                       i = 0;
-
-                       /* Command */
-                       match[i]  = wbcir_to_rc6cells(wake_sc >>  0);
-                       mask[i++] = 0xFF;
-                       match[i]  = wbcir_to_rc6cells(wake_sc >>  4);
-                       mask[i++] = 0xFF;
-
-                       /* Address + Toggle */
-                       match[i]  = wbcir_to_rc6cells(wake_sc >>  8);
-                       mask[i++] = 0xFF;
-                       match[i]  = wbcir_to_rc6cells(wake_sc >> 12);
-                       mask[i++] = 0x3F;
-
-                       /* Customer bits 7 - 0 */
-                       match[i]  = wbcir_to_rc6cells(wake_sc >> 16);
-                       mask[i++] = 0xFF;
+               proto = IR_PROTOCOL_NEC;
+               break;
+
+       case RC_TYPE_RC6_0:
+               /* Command */
+               match[0] = wbcir_to_rc6cells(wake_sc >> 0);
+               mask[0]  = wbcir_to_rc6cells(mask_sc >> 0);
+               match[1] = wbcir_to_rc6cells(wake_sc >> 4);
+               mask[1]  = wbcir_to_rc6cells(mask_sc >> 4);
+
+               /* Address */
+               match[2] = wbcir_to_rc6cells(wake_sc >>  8);
+               mask[2]  = wbcir_to_rc6cells(mask_sc >>  8);
+               match[3] = wbcir_to_rc6cells(wake_sc >> 12);
+               mask[3]  = wbcir_to_rc6cells(mask_sc >> 12);
+
+               /* Header */
+               match[4] = 0x50; /* mode1 = mode0 = 0, ignore toggle */
+               mask[4]  = 0xF0;
+               match[5] = 0x09; /* start bit = 1, mode2 = 0 */
+               mask[5]  = 0x0F;
+
+               rc6_csl = 44;
+               proto = IR_PROTOCOL_RC6;
+               break;
+
+       case RC_TYPE_RC6_6A_24:
+       case RC_TYPE_RC6_6A_32:
+       case RC_TYPE_RC6_MCE:
+               i = 0;
+
+               /* Command */
+               match[i]  = wbcir_to_rc6cells(wake_sc >>  0);
+               mask[i++] = wbcir_to_rc6cells(mask_sc >>  0);
+               match[i]  = wbcir_to_rc6cells(wake_sc >>  4);
+               mask[i++] = wbcir_to_rc6cells(mask_sc >>  4);
+
+               /* Address + Toggle */
+               match[i]  = wbcir_to_rc6cells(wake_sc >>  8);
+               mask[i++] = wbcir_to_rc6cells(mask_sc >>  8);
+               match[i]  = wbcir_to_rc6cells(wake_sc >> 12);
+               mask[i++] = wbcir_to_rc6cells(mask_sc >> 12);
+
+               /* Customer bits 7 - 0 */
+               match[i]  = wbcir_to_rc6cells(wake_sc >> 16);
+               mask[i++] = wbcir_to_rc6cells(mask_sc >> 16);
+
+               if (rc->wakeup_protocol == RC_TYPE_RC6_6A_20) {
+                       rc6_csl = 52;
+               } else {
                        match[i]  = wbcir_to_rc6cells(wake_sc >> 20);
-                       mask[i++] = 0xFF;
+                       mask[i++] = wbcir_to_rc6cells(mask_sc >> 20);
 
-                       if (wake_sc & 0x80000000) {
+                       if (rc->wakeup_protocol == RC_TYPE_RC6_6A_24) {
+                               rc6_csl = 60;
+                       } else {
                                /* Customer range bit and bits 15 - 8 */
                                match[i]  = wbcir_to_rc6cells(wake_sc >> 24);
-                               mask[i++] = 0xFF;
+                               mask[i++] = wbcir_to_rc6cells(mask_sc >> 24);
                                match[i]  = wbcir_to_rc6cells(wake_sc >> 28);
-                               mask[i++] = 0xFF;
+                               mask[i++] = wbcir_to_rc6cells(mask_sc >> 28);
                                rc6_csl = 76;
-                       } else if (wake_sc <= 0x007FFFFF) {
-                               rc6_csl = 60;
-                       } else {
-                               do_wake = false;
-                               dev_err(dev, "RC6 - Invalid wake scancode\n");
-                               break;
                        }
-
-                       /* Header */
-                       match[i]  = 0x93; /* mode1 = mode0 = 1, submode = 0 */
-                       mask[i++] = 0xFF;
-                       match[i]  = 0x0A; /* start bit = 1, mode2 = 1 */
-                       mask[i++] = 0x0F;
-
-               } else {
-                       do_wake = false;
-                       dev_err(dev, "RC6 - Invalid wake mode\n");
                }
 
+               /* Header */
+               match[i]  = 0x93; /* mode1 = mode0 = 1, submode = 0 */
+               mask[i++] = 0xFF;
+               match[i]  = 0x0A; /* start bit = 1, mode2 = 1 */
+               mask[i++] = 0x0F;
+               proto = IR_PROTOCOL_RC6;
                break;
-
        default:
                do_wake = false;
                break;
@@ -855,7 +852,8 @@ finish:
                wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x01, 0x07);
 
                /* Set CEIR_EN */
-               wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x01, 0x01);
+               wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL,
+                              (proto << 4) | 0x01, 0x31);
 
        } else {
                /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */
@@ -875,6 +873,15 @@ finish:
        disable_irq(data->irq);
 }
 
+/*
+ * Wakeup handling is done on shutdown.
+ */
+static int
+wbcir_set_wakeup_filter(struct rc_dev *rc, struct rc_scancode_filter *filter)
+{
+       return 0;
+}
+
 static int
 wbcir_suspend(struct pnp_dev *device, pm_message_t state)
 {
@@ -887,16 +894,11 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state)
 static void
 wbcir_init_hw(struct wbcir_data *data)
 {
-       u8 tmp;
-
        /* Disable interrupts */
        wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
 
-       /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
-       tmp = protocol << 4;
-       if (invert)
-               tmp |= 0x08;
-       outb(tmp, data->wbase + WBCIR_REG_WCEIR_CTL);
+       /* Set RX_INV, Clear CEIR_EN (needed for the led) */
+       wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, invert ? 8 : 0, 0x09);
 
        /* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */
        wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_STS, 0x17, 0x17);
@@ -1059,13 +1061,12 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
        if (err)
                goto exit_free_data;
 
-       data->dev = rc_allocate_device();
+       data->dev = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!data->dev) {
                err = -ENOMEM;
                goto exit_unregister_led;
        }
 
-       data->dev->driver_type = RC_DRIVER_IR_RAW;
        data->dev->driver_name = DRVNAME;
        data->dev->input_name = WBCIR_NAME;
        data->dev->input_phys = "wbcir/cir0";
@@ -1083,7 +1084,15 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
        data->dev->dev.parent = &device->dev;
        data->dev->timeout = MS_TO_NS(100);
        data->dev->rx_resolution = US_TO_NS(2);
-       data->dev->allowed_protocols = RC_BIT_ALL;
+       data->dev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
+       data->dev->allowed_wakeup_protocols = RC_BIT_NEC | RC_BIT_NECX |
+                       RC_BIT_NEC32 | RC_BIT_RC5 | RC_BIT_RC6_0 |
+                       RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 |
+                       RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE;
+       data->dev->wakeup_protocol = RC_TYPE_RC6_MCE;
+       data->dev->scancode_wakeup_filter.data = 0x800f040c;
+       data->dev->scancode_wakeup_filter.mask = 0xffff7fff;
+       data->dev->s_wakeup_filter = wbcir_set_wakeup_filter;
 
        err = rc_register_device(data->dev);
        if (err)
@@ -1199,15 +1208,6 @@ wbcir_init(void)
 {
        int ret;
 
-       switch (protocol) {
-       case IR_PROTOCOL_RC5:
-       case IR_PROTOCOL_NEC:
-       case IR_PROTOCOL_RC6:
-               break;
-       default:
-               pr_err("Invalid power-on protocol\n");
-       }
-
        ret = pnp_register_driver(&wbcir_driver);
        if (ret)
                pr_err("Unable to register driver\n");
index 00489a9df4e4c6e45a450512bb37613995b53bcc..192b1c7740df23f99b77230643a5e4b1ccab34fa 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "fc0011.h"
index 1a86ce1d3fcf03bbc87fcb884eb9621a1b25414c..0fbf0114bdcd437c176f1e5972235af8bb5973e2 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _FC0012_PRIV_H_
index 30508f44e5f934134bbecd7ff74266cfd6f1a6ba..dcc323ffbde75a111b089601b8cd50392ddb20e3 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "fc0012.h"
index 4a23e418daf08495d38335a9fbd49e061e78645c..64d07a2adb2ef4ec133a8dea56ea8f1f6714792f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _FC0012_H_
index bfd49dedea22963da4820afdd0d0211821b16d0c..2eeaca8abae52226a614be8c97a3a69f92cfbb4d 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _FC0013_PRIV_H_
index f7cf0e9e7c99b486c12a0421f6f52b24270b14e5..91dfa770a5cc76ad90424d5d8354786c0296071a 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "fc0013.h"
index 8c34105c938342e29d97898d70943a6da945d075..4431e7ceb43da3f3bd20cd57893d6d6523dd711a 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _FC0013_H_
index 71881815693432c1f87bed233bd1b04701f1067b..3a96ff76c19558815a30694de26dd932febf13e8 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _FC001X_COMMON_H_
index 6c3ef2181fcdc5b6f0a318feb5f1aef7bfb234d1..27e5bc1c3cb5d8b84f5f7cdab041c3cb2b1f5fff 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #include "it913x.h"
+#include <linux/platform_device.h>
 #include <linux/regmap.h>
 
 struct it913x_dev {
-       struct i2c_client *client;
+       struct platform_device *pdev;
        struct regmap *regmap;
        struct dvb_frontend *fe;
        u8 chip_ver:2;
@@ -39,13 +36,14 @@ struct it913x_dev {
 static int it913x_init(struct dvb_frontend *fe)
 {
        struct it913x_dev *dev = fe->tuner_priv;
+       struct platform_device *pdev = dev->pdev;
        int ret;
        unsigned int utmp;
        u8 iqik_m_cal, nv_val, buf[2];
        static const u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
        unsigned long timeout;
 
-       dev_dbg(&dev->client->dev, "role %u\n", dev->role);
+       dev_dbg(&pdev->dev, "role %u\n", dev->role);
 
        ret = regmap_write(dev->regmap, 0x80ec4c, 0x68);
        if (ret)
@@ -73,7 +71,7 @@ static int it913x_init(struct dvb_frontend *fe)
                iqik_m_cal = 6;
                break;
        default:
-               dev_err(&dev->client->dev, "unknown clock identifier %d\n", utmp);
+               dev_err(&pdev->dev, "unknown clock identifier %d\n", utmp);
                goto err;
        }
 
@@ -98,14 +96,14 @@ static int it913x_init(struct dvb_frontend *fe)
                        break;
        }
 
-       dev_dbg(&dev->client->dev, "r_fbc_m_bdry took %u ms, val %u\n",
+       dev_dbg(&pdev->dev, "r_fbc_m_bdry took %u ms, val %u\n",
                        jiffies_to_msecs(jiffies) -
                        (jiffies_to_msecs(timeout) - TIMEOUT), utmp);
 
        dev->fn_min = dev->xtal * utmp;
        dev->fn_min /= (dev->fdiv * nv_val);
        dev->fn_min *= 1000;
-       dev_dbg(&dev->client->dev, "fn_min %u\n", dev->fn_min);
+       dev_dbg(&pdev->dev, "fn_min %u\n", dev->fn_min);
 
        /*
         * Chip version BX never sets that flag so we just wait 50ms in that
@@ -125,7 +123,7 @@ static int it913x_init(struct dvb_frontend *fe)
                                break;
                }
 
-               dev_dbg(&dev->client->dev, "p_tsm_init_mode took %u ms, val %u\n",
+               dev_dbg(&pdev->dev, "p_tsm_init_mode took %u ms, val %u\n",
                                jiffies_to_msecs(jiffies) -
                                (jiffies_to_msecs(timeout) - TIMEOUT), utmp);
        } else {
@@ -152,16 +150,17 @@ static int it913x_init(struct dvb_frontend *fe)
 
        return 0;
 err:
-       dev_dbg(&dev->client->dev, "failed %d\n", ret);
+       dev_dbg(&pdev->dev, "failed %d\n", ret);
        return ret;
 }
 
 static int it913x_sleep(struct dvb_frontend *fe)
 {
        struct it913x_dev *dev = fe->tuner_priv;
+       struct platform_device *pdev = dev->pdev;
        int ret, len;
 
-       dev_dbg(&dev->client->dev, "role %u\n", dev->role);
+       dev_dbg(&pdev->dev, "role %u\n", dev->role);
 
        dev->active = false;
 
@@ -178,7 +177,7 @@ static int it913x_sleep(struct dvb_frontend *fe)
        else
                len = 15;
 
-       dev_dbg(&dev->client->dev, "role %u, len %d\n", dev->role, len);
+       dev_dbg(&pdev->dev, "role %u, len %d\n", dev->role, len);
 
        ret = regmap_bulk_write(dev->regmap, 0x80ec02,
                        "\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
@@ -210,13 +209,14 @@ static int it913x_sleep(struct dvb_frontend *fe)
 
        return 0;
 err:
-       dev_dbg(&dev->client->dev, "failed %d\n", ret);
+       dev_dbg(&pdev->dev, "failed %d\n", ret);
        return ret;
 }
 
 static int it913x_set_params(struct dvb_frontend *fe)
 {
        struct it913x_dev *dev = fe->tuner_priv;
+       struct platform_device *pdev = dev->pdev;
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        int ret;
        unsigned int utmp;
@@ -224,7 +224,7 @@ static int it913x_set_params(struct dvb_frontend *fe)
        u16 iqik_m_cal, n_div;
        u8 u8tmp, n, l_band, lna_band;
 
-       dev_dbg(&dev->client->dev, "role=%u, frequency %u, bandwidth_hz %u\n",
+       dev_dbg(&pdev->dev, "role=%u, frequency %u, bandwidth_hz %u\n",
                        dev->role, c->frequency, c->bandwidth_hz);
 
        if (!dev->active) {
@@ -290,7 +290,7 @@ static int it913x_set_params(struct dvb_frontend *fe)
        pre_lo_freq += (u32) n << 13;
        /* Frequency OMEGA_IQIK_M_CAL_MID*/
        t_cal_freq = pre_lo_freq + (u32)iqik_m_cal;
-       dev_dbg(&dev->client->dev, "t_cal_freq %u, pre_lo_freq %u\n",
+       dev_dbg(&pdev->dev, "t_cal_freq %u, pre_lo_freq %u\n",
                        t_cal_freq, pre_lo_freq);
 
        if (c->frequency <=         440000000) {
@@ -369,7 +369,7 @@ static int it913x_set_params(struct dvb_frontend *fe)
 
        return 0;
 err:
-       dev_dbg(&dev->client->dev, "failed %d\n", ret);
+       dev_dbg(&pdev->dev, "failed %d\n", ret);
        return ret;
 }
 
@@ -385,40 +385,32 @@ static const struct dvb_tuner_ops it913x_tuner_ops = {
        .set_params = it913x_set_params,
 };
 
-static int it913x_probe(struct i2c_client *client,
-               const struct i2c_device_id *id)
+static int it913x_probe(struct platform_device *pdev)
 {
-       struct it913x_config *cfg = client->dev.platform_data;
-       struct dvb_frontend *fe = cfg->fe;
+       struct it913x_platform_data *pdata = pdev->dev.platform_data;
+       struct dvb_frontend *fe = pdata->fe;
        struct it913x_dev *dev;
+       const struct platform_device_id *id = platform_get_device_id(pdev);
        int ret;
        char *chip_ver_str;
-       static const struct regmap_config regmap_config = {
-               .reg_bits = 24,
-               .val_bits = 8,
-       };
 
        dev = kzalloc(sizeof(struct it913x_dev), GFP_KERNEL);
        if (dev == NULL) {
                ret = -ENOMEM;
-               dev_err(&client->dev, "kzalloc() failed\n");
+               dev_err(&pdev->dev, "kzalloc() failed\n");
                goto err;
        }
 
-       dev->client = client;
-       dev->fe = cfg->fe;
-       dev->chip_ver = cfg->chip_ver;
-       dev->role = cfg->role;
-       dev->regmap = regmap_init_i2c(client, &regmap_config);
-       if (IS_ERR(dev->regmap)) {
-               ret = PTR_ERR(dev->regmap);
-               goto err_kfree;
-       }
+       dev->pdev = pdev;
+       dev->regmap = pdata->regmap;
+       dev->fe = pdata->fe;
+       dev->chip_ver = id->driver_data;
+       dev->role = pdata->role;
 
        fe->tuner_priv = dev;
        memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
                        sizeof(struct dvb_tuner_ops));
-       i2c_set_clientdata(client, dev);
+       platform_set_drvdata(pdev, dev);
 
        if (dev->chip_ver == 1)
                chip_ver_str = "AX";
@@ -427,41 +419,37 @@ static int it913x_probe(struct i2c_client *client,
        else
                chip_ver_str = "??";
 
-       dev_info(&dev->client->dev, "ITE IT913X %s successfully attached\n",
-                       chip_ver_str);
-       dev_dbg(&dev->client->dev, "chip_ver %u, role %u\n",
-                       dev->chip_ver, dev->role);
+       dev_info(&pdev->dev, "ITE IT913X %s successfully attached\n",
+                chip_ver_str);
+       dev_dbg(&pdev->dev, "chip_ver %u, role %u\n", dev->chip_ver, dev->role);
        return 0;
-
-err_kfree:
-       kfree(dev);
 err:
-       dev_dbg(&client->dev, "failed %d\n", ret);
+       dev_dbg(&pdev->dev, "failed %d\n", ret);
        return ret;
 }
 
-static int it913x_remove(struct i2c_client *client)
+static int it913x_remove(struct platform_device *pdev)
 {
-       struct it913x_dev *dev = i2c_get_clientdata(client);
+       struct it913x_dev *dev = platform_get_drvdata(pdev);
        struct dvb_frontend *fe = dev->fe;
 
-       dev_dbg(&client->dev, "\n");
+       dev_dbg(&pdev->dev, "\n");
 
        memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
        fe->tuner_priv = NULL;
-       regmap_exit(dev->regmap);
        kfree(dev);
 
        return 0;
 }
 
-static const struct i2c_device_id it913x_id_table[] = {
-       {"it913x", 0},
-       {}
+static const struct platform_device_id it913x_id_table[] = {
+       {"it9133ax-tuner", 1},
+       {"it9133bx-tuner", 2},
+       {},
 };
-MODULE_DEVICE_TABLE(i2c, it913x_id_table);
+MODULE_DEVICE_TABLE(platform, it913x_id_table);
 
-static struct i2c_driver it913x_driver = {
+static struct platform_driver it913x_driver = {
        .driver = {
                .name   = "it913x",
                .suppress_bind_attrs    = true,
@@ -471,7 +459,7 @@ static struct i2c_driver it913x_driver = {
        .id_table       = it913x_id_table,
 };
 
-module_i2c_driver(it913x_driver);
+module_platform_driver(it913x_driver);
 
 MODULE_DESCRIPTION("ITE IT913X silicon tuner driver");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
index 33de53d4a566e1dd63b0de7e6883b7ebb16d7fe7..226f657228fbbd5a0f12166c1ffec6745d17d8c8 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef IT913X_H
 
 #include "dvb_frontend.h"
 
-/*
- * I2C address
- * 0x38, 0x3a, 0x3c, 0x3e
+/**
+ * struct it913x_platform_data - Platform data for the it913x driver
+ * @regmap: af9033 demod driver regmap.
+ * @dvb_frontend: af9033 demod driver DVB frontend.
+ * @role: Chip role, single or dual configuration.
  */
-struct it913x_config {
-       /*
-        * pointer to DVB frontend
-        */
-       struct dvb_frontend *fe;
 
-       /*
-        * chip version
-        * 1 = IT9135 AX
-        * 2 = IT9135 BX
-        */
-       unsigned int chip_ver:2;
-
-       /*
-        * tuner role
-        */
+struct it913x_platform_data {
+       struct regmap *regmap;
+       struct dvb_frontend *fe;
 #define IT913X_ROLE_SINGLE         0
 #define IT913X_ROLE_DUAL_MASTER    1
 #define IT913X_ROLE_DUAL_SLAVE     2
index c3f10925b0d4f99620c0b4fc09604ff0b74cd101..a86c081149154d29df8c7234d6de3b1ecd4149c0 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index aadd9fea59e4fffe062af7f50206be6936493c29..3120c54ec154e469e2095eebd945061478f4a579 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MAX2165_H__
index 91bbe021a08d321aa3233d2209b766986e838722..20d7751881a3345535111c5ac92d319bef8f542f 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MAX2165_PRIV_H__
index aba580b4ac2cd2779e076c61d64cfef98f87042b..12f545ef12430824e402ca19b8db47d57e38432a 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #include <linux/module.h>
index 6b40df33928458be61baf4ac9bb9a8a3fef6337f..f68133fb9760a875863bd5d3cb8ae0da57df2e72 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef MC44S803_H
index 14a92780906d7775cd4093b6b52c299d0900a103..52325395dfe7fb147f7d3b8bee972c676606b166 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef MC44S803_PRIV_H
index 94077ea78dde401b07afb58bff12775e016d029c..2e487f9a2cc3fb678aa173b93a9bb141cc23ba69 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 /* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
@@ -71,13 +67,24 @@ static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
 // Writes a set of consecutive registers
 static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
 {
+       int rem, val_len;
+       u8 xfer_buf[16];
        struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = xfer_buf
        };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
-               return -EREMOTEIO;
+
+       for (rem = len - 1; rem > 0; rem -= priv->i2c_max_regs) {
+               val_len = min_t(int, rem, priv->i2c_max_regs);
+               msg.len = 1 + val_len;
+               xfer_buf[0] = buf[0] + len - 1 - rem;
+               memcpy(&xfer_buf[1], &buf[1 + len - 1 - rem], val_len);
+
+               if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+                       printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n", val_len);
+                       return -EREMOTEIO;
+               }
        }
+
        return 0;
 }
 
@@ -306,9 +313,16 @@ static int mt2060_init(struct dvb_frontend *fe)
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
 
+       if (priv->sleep) {
+               ret = mt2060_writereg(priv, REG_MISC_CTRL, 0x20);
+               if (ret)
+                       goto err_i2c_gate_ctrl;
+       }
+
        ret = mt2060_writereg(priv, REG_VGAG,
                              (priv->cfg->clock_out << 6) | 0x33);
 
+err_i2c_gate_ctrl:
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
 
@@ -325,7 +339,13 @@ static int mt2060_sleep(struct dvb_frontend *fe)
 
        ret = mt2060_writereg(priv, REG_VGAG,
                              (priv->cfg->clock_out << 6) | 0x30);
+       if (ret)
+               goto err_i2c_gate_ctrl;
+
+       if (priv->sleep)
+               ret = mt2060_writereg(priv, REG_MISC_CTRL, 0xe8);
 
+err_i2c_gate_ctrl:
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
 
@@ -369,6 +389,7 @@ struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter
        priv->cfg      = cfg;
        priv->i2c      = i2c;
        priv->if1_freq = if1;
+       priv->i2c_max_regs = ~0;
 
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
@@ -396,6 +417,98 @@ struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter
 }
 EXPORT_SYMBOL(mt2060_attach);
 
+static int mt2060_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       struct mt2060_platform_data *pdata = client->dev.platform_data;
+       struct dvb_frontend *fe;
+       struct mt2060_priv *dev;
+       int ret;
+       u8 chip_id;
+
+       dev_dbg(&client->dev, "\n");
+
+       if (!pdata) {
+               dev_err(&client->dev, "Cannot proceed without platform data\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
+       if (!dev) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       fe = pdata->dvb_frontend;
+       dev->config.i2c_address = client->addr;
+       dev->config.clock_out = pdata->clock_out;
+       dev->cfg = &dev->config;
+       dev->i2c = client->adapter;
+       dev->if1_freq = pdata->if1 ? pdata->if1 : 1220;
+       dev->client = client;
+       dev->i2c_max_regs = pdata->i2c_write_max ? pdata->i2c_write_max - 1 : ~0;
+       dev->sleep = true;
+
+       ret = mt2060_readreg(dev, REG_PART_REV, &chip_id);
+       if (ret) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       dev_dbg(&client->dev, "chip id=%02x\n", chip_id);
+
+       if (chip_id != PART_REV) {
+               ret = -ENODEV;
+               goto err;
+       }
+
+       /* Power on, calibrate, sleep */
+       ret = mt2060_writereg(dev, REG_MISC_CTRL, 0x20);
+       if (ret)
+               goto err;
+       mt2060_calibrate(dev);
+       ret = mt2060_writereg(dev, REG_MISC_CTRL, 0xe8);
+       if (ret)
+               goto err;
+
+       dev_info(&client->dev, "Microtune MT2060 successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(fe->ops.tuner_ops));
+       fe->ops.tuner_ops.release = NULL;
+       fe->tuner_priv = dev;
+       i2c_set_clientdata(client, dev);
+
+       return 0;
+err:
+       dev_dbg(&client->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int mt2060_remove(struct i2c_client *client)
+{
+       dev_dbg(&client->dev, "\n");
+
+       return 0;
+}
+
+static const struct i2c_device_id mt2060_id_table[] = {
+       {"mt2060", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, mt2060_id_table);
+
+static struct i2c_driver mt2060_driver = {
+       .driver = {
+               .name = "mt2060",
+               .suppress_bind_attrs = true,
+       },
+       .probe          = mt2060_probe,
+       .remove         = mt2060_remove,
+       .id_table       = mt2060_id_table,
+};
+
+module_i2c_driver(mt2060_driver);
+
 MODULE_AUTHOR("Olivier DANET");
 MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
 MODULE_LICENSE("GPL");
index 6efed359a24fd2cefadfffaf378294b4a112b535..cc534eb41378ffbeff1982d35cd6d65d92c2c059 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef MT2060_H
 struct dvb_frontend;
 struct i2c_adapter;
 
+/*
+ * I2C address
+ * 0x60, ...
+ */
+
+/**
+ * struct mt2060_platform_data - Platform data for the mt2060 driver
+ * @clock_out: Clock output setting. 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1.
+ * @if1: First IF used [MHz]. 0 defaults to 1220.
+ * @i2c_write_max: Maximum number of bytes I2C adapter can write at once.
+ *  0 defaults to maximum.
+ * @dvb_frontend: DVB frontend.
+ */
+
+struct mt2060_platform_data {
+       u8 clock_out;
+       u16 if1;
+       unsigned int i2c_write_max:5;
+       struct dvb_frontend *dvb_frontend;
+};
+
+
+/* configuration struct for mt2060_attach() */
 struct mt2060_config {
        u8 i2c_address;
        u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
index 2b60de6c707dfd884812376358089fde51600233..a6c931c1a5a7bb831c7ed3631a253c9cce7c8d3d 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  */
 
 #ifndef MT2060_PRIV_H
 struct mt2060_priv {
        struct mt2060_config *cfg;
        struct i2c_adapter   *i2c;
+       struct i2c_client *client;
+       struct mt2060_config config;
 
+       u8 i2c_max_regs;
        u32 frequency;
        u16 if1_freq;
        u8  fmfreq;
+
+       /*
+        * Use REG_MISC_CTRL register for sleep. That drops sleep power usage
+        * about 0.9W (huge!). Register bit meanings are unknown, so let it be
+        * disabled by default to avoid possible regression. Convert driver to
+        * i2c model in order to enable it.
+        */
+       bool sleep;
 };
 
 #endif
index e7790e4afcfec35ec866249b90654d912aa36d21..dd85d58fa8d05b75ccedffff9276e28d387eed09 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 8267a6ae5d848bc12bb1bbb7e2f1fc5ab7ffd561..050da5540b15119b6d5643867568c809e41ebb75 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MT2131_H__
index 91283b599cb3ed7ee3872ac7b74550d7248f40f0..d2b6f29182cc17cc28376e263f5b44a91d100b1d 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MT2131_PRIV_H__
index b16dfa5e85fb0c78a7316a558d742ac9cd10ae2c..4081fd97c3b2cad0b71e0bd53d87c6ad8b2805c6 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/i2c.h>
index e786d1f23ff1b7c0da087361903c576778fdd75c..273f61aeb8be34f6062d81539dbfad259b2f78f9 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MXL5007T_H__
index a2c6cd1c3923a2ff0e02ba27451725940463f758..ee33b7cc7682435c2e39e5145e2e36c3c4dec568 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include "qt1010.h"
 #include "qt1010_priv.h"
index e3198f23437c1af9d70b340415d567e970d24832..276e59e8503261e9d0fdfa1e6bf83a517f3d89d9 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef QT1010_H
index 2c42d3f016366d5f7cb8b11baebee9d1342a3ea3..4cb78ecc89857c064632d75eab98822933639f3a 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef QT1010_PRIV_H
index 8357a3c08a701916b154d89eae50a55e8250196d..c56fcf5d48e335834ea3fe957dfea34c8c6edde1 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "tda18218_priv.h"
index 076b5f2e888d4a4b4ef5e97ef27cc82c0cdc6ea7..9c0e3fd7ed7f86eadcaf3cbf6a80439c276ef12f 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef TDA18218_H
index 285b77366c8d0104c17db0c1a24b5c8cd0ff41d3..9d04781966e769bdee82bf06d8706386a99d193b 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef TDA18218_PRIV_H
index 2137eadf30f192144d1f01b1fa29f5bcca6954fc..8400808f8f7fe1c77822941f0890757131ba219b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 03eef9b87a24e11c2e5a015b3d1037a03fb15b8b..e30948e4ff87eae8070250181f7ea1328d108974 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 40517860cf67ff85b261dc3470c2343da27b1835..8af93b63ff9ed3a797642dd43f34501062ac10d6 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __XC4000_H__
index 796e7638b3b257a03c14d2f4b761631d43efe42a..0345b274eccc0c88aa94f7539401340acf18dfcf 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 336bd49eb09b2d4d59e64b61cfc703deec1227a0..42bbec2409fdf3c6499970f8c8cdb5da96382ddf 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __XC5000_H__
index 6b469e8c4c6e209d0001c0ff8e9150057fee1c43..313f659f0bfb00554d8a7c74b57de6b6432d7903 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "au0828.h"
index 48a1882c2b6bec47464cb48992d3b3af3081a6ea..1f4412ee6da44ba676f3fe5889b135ae4d2ca261 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define AU0828_BOARD_UNKNOWN           0
index bf53553d262449db469ea9461fb763cc61ebfa40..739df61cec4f7049a838d27d6c80b4d7ec682040 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "au0828.h"
@@ -153,9 +149,11 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
        }
 
        /* clear enable_source, disable_source */
+       mutex_lock(&mdev->graph_mutex);
        dev->media_dev->source_priv = NULL;
        dev->media_dev->enable_source = NULL;
        dev->media_dev->disable_source = NULL;
+       mutex_unlock(&mdev->graph_mutex);
 
        media_device_unregister(dev->media_dev);
        media_device_cleanup(dev->media_dev);
@@ -278,6 +276,7 @@ create_link:
        }
 }
 
+/* Callers should hold graph_mutex */
 static int au0828_enable_source(struct media_entity *entity,
                                struct media_pipeline *pipe)
 {
@@ -291,8 +290,6 @@ static int au0828_enable_source(struct media_entity *entity,
        if (!mdev)
                return -ENODEV;
 
-       mutex_lock(&mdev->graph_mutex);
-
        dev = mdev->source_priv;
 
        /*
@@ -397,7 +394,7 @@ static int au0828_enable_source(struct media_entity *entity,
                goto end;
        }
 
-       ret = __media_entity_pipeline_start(entity, pipe);
+       ret = __media_pipeline_start(entity, pipe);
        if (ret) {
                pr_err("Start Pipeline: %s->%s Error %d\n",
                        source->name, entity->name, ret);
@@ -419,12 +416,12 @@ static int au0828_enable_source(struct media_entity *entity,
                 dev->active_source->name, dev->active_sink->name,
                 dev->active_link_owner->name, ret);
 end:
-       mutex_unlock(&mdev->graph_mutex);
        pr_debug("au0828_enable_source() end %s %d %d\n",
                 entity->name, entity->function, ret);
        return ret;
 }
 
+/* Callers should hold graph_mutex */
 static void au0828_disable_source(struct media_entity *entity)
 {
        int ret = 0;
@@ -434,13 +431,10 @@ static void au0828_disable_source(struct media_entity *entity)
        if (!mdev)
                return;
 
-       mutex_lock(&mdev->graph_mutex);
        dev = mdev->source_priv;
 
-       if (!dev->active_link) {
-               ret = -ENODEV;
-               goto end;
-       }
+       if (!dev->active_link)
+               return;
 
        /* link is active - stop pipeline from source (tuner) */
        if (dev->active_link->sink->entity == dev->active_sink &&
@@ -450,8 +444,8 @@ static void au0828_disable_source(struct media_entity *entity)
                 * has active pipeline
                */
                if (dev->active_link_owner != entity)
-                       goto end;
-               __media_entity_pipeline_stop(entity);
+                       return;
+               __media_pipeline_stop(entity);
                ret = __media_entity_setup_link(dev->active_link, 0);
                if (ret)
                        pr_err("Deactivate link Error %d\n", ret);
@@ -465,9 +459,6 @@ static void au0828_disable_source(struct media_entity *entity)
                dev->active_source = NULL;
                dev->active_sink = NULL;
        }
-
-end:
-       mutex_unlock(&mdev->graph_mutex);
 }
 #endif
 
@@ -549,9 +540,11 @@ static int au0828_media_device_register(struct au0828_dev *dev,
                return ret;
        }
        /* set enable_source */
+       mutex_lock(&dev->media_dev->graph_mutex);
        dev->media_dev->source_priv = (void *) dev;
        dev->media_dev->enable_source = au0828_enable_source;
        dev->media_dev->disable_source = au0828_disable_source;
+       mutex_unlock(&dev->media_dev->graph_mutex);
 #endif
        return 0;
 }
index 0e174e86061404d6e01f36d8ff2db5e0f856702b..7e0c9b795e52409dd2449b3b6bbce160a3303df2 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "au0828.h"
index ae7ac6669769f3cdcc2d2ba01db5cc0c73ce5039..42b352bb4f020523f7c3a9e284217d36b411b3ea 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "au0828.h"
index 1e66e7828d8f2921ad954e5568534ebb55dbffde..9ec919c68482df5c5c97e4a41d421f71411422ee 100644 (file)
@@ -298,7 +298,7 @@ int au0828_rc_register(struct au0828_dev *dev)
                return -ENODEV;
 
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_IR_RAW);
        if (!ir || !rc)
                goto error;
 
@@ -343,7 +343,6 @@ int au0828_rc_register(struct au0828_dev *dev)
        rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
        rc->dev.parent = &dev->usbdev->dev;
        rc->driver_name = "au0828-input";
-       rc->driver_type = RC_DRIVER_IR_RAW;
        rc->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 |
                                                                RC_BIT_RC5;
 
index 2140f4cfb645679901e71853a940240a64024029..7aaf10739c8b2cfe14bfc618c631320f758e1da4 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /* We'll start to rename these registers once we have a better
index 7a10eaa38f672e715f237ecb92c76ad97e8e1ea3..16f9125a985a2787687743c95d9911ddcb778029 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
 
 /* Developer Notes:
index dd7b378fe0706111d0473b74bc45cb5a7ee7b134..88e59748ebc27335d4832147cbfde6b0a4f3925f 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index cdef677d57ecf5910d83882df79f6d3a33fe8e8b..81f72c0b561fb7bdd4f0278abef69d8f362aa4a6 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  ****************************************************************************/
 
 #ifndef __CPIA2_H__
index 0310fd6ed1033ced21cf8c509666852b17c128b7..431dd0b4b3323671039fc9b2a71926fcc681dd6f 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *  Stripped of 2.4 stuff ready for main kernel submit by
  *             Alan Cox <alan@lxorguk.ukuu.org.uk>
  *
index 3bbec514a967a86fcc2079718500557d4aa2738a..eebe46ea9c0158b6887bc1d9e092873707ac7f9e 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  ****************************************************************************/
 
 #ifndef CPIA2_REGISTER_HEADER
index 37f9b30b0abc73f5ea024a979d61ba4ff157b401..1c7e16e5d88b53f0258fd2bcd749e10299945ec0 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *  Stripped of 2.4 stuff ready for main kernel submit by
  *             Alan Cox <alan@lxorguk.ukuu.org.uk>
  ****************************************************************************/
@@ -551,12 +547,10 @@ static int write_packet(struct usb_device *udev,
        if (!registers || size <= 0)
                return -EINVAL;
 
-       buf = kmalloc(size, GFP_KERNEL);
+       buf = kmemdup(registers, size, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
-       memcpy(buf, registers, size);
-
        ret = usb_control_msg(udev,
                               usb_sndctrlpipe(udev, 0),
                               request,
index 9caea8344547a790db13b04690d5d5c14aaf9451..7122023e7004995a5cd8912b4b77175b695acb11 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *  Stripped of 2.4 stuff ready for main kernel submit by
  *             Alan Cox <alan@lxorguk.ukuu.org.uk>
  ****************************************************************************/
index 0cced3e5b040bfddc8696d030aa3752003108e9f..58de80bff4c761296d85ae942899e87c1317476e 100644 (file)
@@ -50,6 +50,7 @@ config VIDEO_CX231XX_DVB
        select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
        select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
        select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
+       select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
        select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
 
        ---help---
index 29d450c15f293bed2b59dc92c207fedef5cd67c5..509d9711d590047c4017ceab8b6987a891be6e71 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx231xx.h"
index 8263c4b0610b4e44457f6c867a387e3a9a89d06d..cf80842dfa082f8d14104377f7c61c15bcc25fe6 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx231xx.h"
index 36bc25494319dbf1b48d2414c1e0b3f76965dc64..f730fdbc915670225ff2ca08a9f4cc60340523ed 100644 (file)
@@ -841,6 +841,33 @@ struct cx231xx_board cx231xx_boards[] = {
                        .gpio = NULL,
                } },
        },
+       [CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD] = {
+               .name = "Evromedia USB Full Hybrid Full HD",
+               .tuner_type = TUNER_ABSENT,
+               .demod_addr = 0x64, /* 0xc8 >> 1 */
+               .demod_i2c_master = I2C_1_MUX_3,
+               .has_dvb = 1,
+               .ir_i2c_master = I2C_0,
+               .norm = V4L2_STD_PAL,
+               .output_mode = OUT_MODE_VIP11,
+               .tuner_addr = 0x60, /* 0xc0 >> 1 */
+               .tuner_i2c_master = I2C_2,
+               .input = {{
+                       .type = CX231XX_VMUX_TELEVISION,
+                       .vmux = 0,
+                       .amux = CX231XX_AMUX_VIDEO,
+               }, {
+                       .type = CX231XX_VMUX_COMPOSITE1,
+                       .vmux = CX231XX_VIN_2_1,
+                       .amux = CX231XX_AMUX_LINE_IN,
+               }, {
+                       .type = CX231XX_VMUX_SVIDEO,
+                       .vmux = CX231XX_VIN_1_1 |
+                               (CX231XX_VIN_1_2 << 8) |
+                               CX25840_SVIDEO_ON,
+                       .amux = CX231XX_AMUX_LINE_IN,
+               } },
+       },
 };
 const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
 
@@ -908,6 +935,8 @@ struct usb_device_id cx231xx_id_table[] = {
         .driver_info = CX231XX_BOARD_OTG102},
        {USB_DEVICE(USB_VID_TERRATEC, 0x00a6),
         .driver_info = CX231XX_BOARD_TERRATEC_GRABBY},
+       {USB_DEVICE(0x1b80, 0xd3b2),
+       .driver_info = CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD},
        {},
 };
 
index 550ec932f931950b28e072dd7b918bf33223bf1e..46646ecd2dbcf6a53af13210f28f1368c1e92c10 100644 (file)
@@ -355,7 +355,12 @@ int cx231xx_send_vendor_cmd(struct cx231xx *dev,
         */
        if ((ven_req->wLength > 4) && ((ven_req->bRequest == 0x4) ||
                                        (ven_req->bRequest == 0x5) ||
-                                       (ven_req->bRequest == 0x6))) {
+                                       (ven_req->bRequest == 0x6) ||
+
+                                       /* Internal Master 3 Bus can send
+                                        * and receive only 4 bytes per time
+                                        */
+                                       (ven_req->bRequest == 0x2))) {
                unsend_size = 0;
                pdata = ven_req->pBuff;
 
index 2b63c2f6d3b0644fdf023b37202140806cc7d7b4..2b9eb9fd7c52b64f46d8c7d1efb0f44e504dfc67 100644 (file)
  *  but WITHOUT ANY WARRANTY, without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program, if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _CX231XX_DIF_H
index 2868546999caff703a4a1c2a5ebc7a7af339f24e..46427fd3b220dc211f8a29bcd04a747ead171089 100644 (file)
@@ -33,6 +33,7 @@
 #include "s5h1411.h"
 #include "lgdt3305.h"
 #include "si2165.h"
+#include "si2168.h"
 #include "mb86a20s.h"
 #include "si2157.h"
 #include "lgdt3306a.h"
@@ -949,6 +950,75 @@ static int dvb_init(struct cx231xx *dev)
                           &pv_tda18271_config);
                break;
 
+       case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD:
+       {
+               struct si2157_config si2157_config = {};
+               struct si2168_config si2168_config = {};
+               struct i2c_board_info info = {};
+               struct i2c_client *client;
+               struct i2c_adapter *adapter;
+
+               /* attach demodulator chip */
+               si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */
+               si2168_config.fe = &dev->dvb->frontend;
+               si2168_config.i2c_adapter = &adapter;
+               si2168_config.ts_clock_inv = true;
+
+               strlcpy(info.type, "si2168", sizeof(info.type));
+               info.addr = dev->board.demod_addr;
+               info.platform_data = &si2168_config;
+
+               request_module(info.type);
+               client = i2c_new_device(demod_i2c, &info);
+
+               if (client == NULL || client->dev.driver == NULL) {
+                       result = -ENODEV;
+                       goto out_free;
+               }
+
+               if (!try_module_get(client->dev.driver->owner)) {
+                       i2c_unregister_device(client);
+                       result = -ENODEV;
+                       goto out_free;
+               }
+
+               dvb->i2c_client_demod = client;
+
+               /* attach tuner chip */
+               si2157_config.fe = dev->dvb->frontend;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+               si2157_config.mdev = dev->media_dev;
+#endif
+               si2157_config.if_port = 1;
+               si2157_config.inversion = false;
+
+               memset(&info, 0, sizeof(info));
+               strlcpy(info.type, "si2157", sizeof(info.type));
+               info.addr = dev->board.tuner_addr;
+               info.platform_data = &si2157_config;
+
+               request_module(info.type);
+               client = i2c_new_device(tuner_i2c, &info);
+
+               if (client == NULL || client->dev.driver == NULL) {
+                       module_put(dvb->i2c_client_demod->dev.driver->owner);
+                       i2c_unregister_device(dvb->i2c_client_demod);
+                       result = -ENODEV;
+                       goto out_free;
+               }
+
+               if (!try_module_get(client->dev.driver->owner)) {
+                       i2c_unregister_device(client);
+                       module_put(dvb->i2c_client_demod->dev.driver->owner);
+                       i2c_unregister_device(dvb->i2c_client_demod);
+                       result = -ENODEV;
+                       goto out_free;
+               }
+
+               dev->cx231xx_reset_analog_tuner = NULL;
+               dev->dvb->i2c_client_tuner = client;
+               break;
+       }
        default:
                dev_err(dev->dev,
                        "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
index 15d8d1b5f05ca73feb8817e3b6c1132d45f17f04..6e80f3c573f36a623bf2b30309642cdd9dba25d3 100644 (file)
@@ -72,7 +72,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
 
        memset(&info, 0, sizeof(struct i2c_board_info));
        memset(&dev->init_data, 0, sizeof(dev->init_data));
-       dev->init_data.rc_dev = rc_allocate_device();
+       dev->init_data.rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!dev->init_data.rc_dev)
                return -ENOMEM;
 
index 90c867683076017f818a81d6db15dfb0c97adb95..d9792ea4bbc63ea2882e4b196af0040185d561c3 100644 (file)
@@ -78,6 +78,7 @@
 #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx 20
 #define CX231XX_BOARD_HAUPPAUGE_955Q 21
 #define CX231XX_BOARD_TERRATEC_GRABBY 22
+#define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23
 
 /* Limits minimum and default number of buffers */
 #define CX231XX_MIN_BUF                 4
index 524533d3eb291c7f22b5c131ab7479b134031428..0e4944b2b0f4d3a70eec4a0958f4ecccf1ea3803 100644 (file)
@@ -156,3 +156,11 @@ config DVB_USB_DVBSKY
        select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT
        help
          Say Y here to support the USB receivers from DVBSky.
+
+config DVB_USB_ZD1301
+       tristate "ZyDAS ZD1301"
+       depends on DVB_USB_V2
+       select DVB_ZD1301_DEMOD if MEDIA_SUBDRV_AUTOSELECT
+       select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+       help
+         Say Y here to support the ZyDAS ZD1301 DVB USB receiver.
index f10d4df0eae5c2962e4a20de60de3145a082ea83..969f68e55265e1a20331f11ebfe35755a11ef5a9 100644 (file)
@@ -40,6 +40,9 @@ obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
 dvb-usb-dvbsky-objs := dvbsky.o
 obj-$(CONFIG_DVB_USB_DVBSKY) += dvb-usb-dvbsky.o
 
+dvb-usb-zd1301-objs := zd1301.o
+obj-$(CONFIG_DVB_USB_ZD1301) += zd1301.o
+
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/tuners
index 29011dfabb11047f20318d3f8cf5b3dfc34a5dfc..caa1e6101f5890e08ffc8148938f52f9e945bf4c 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "af9015.h"
index 1db1bb0d57bcd1c858151588693b6fc5b821a85d..2dd9231a8ece878e44e22147edc391e88b94f7f4 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef AF9015_H
index c673726d9b70185080f58f4dd7f7ade81d916cee..4df9486e19b9bb020ca2d0844d2df0f7144179b1 100644 (file)
@@ -335,14 +335,12 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                        /* TODO: correct limits > 40 */
                        ret = -EOPNOTSUPP;
                } else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
-                          (msg[0].addr == state->af9033_i2c_addr[1]) ||
-                          (state->chip_type == 0x9135)) {
+                          (msg[0].addr == state->af9033_i2c_addr[1])) {
                        /* demod access via firmware interface */
                        u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
                                        msg[0].buf[2];
 
-                       if (msg[0].addr == state->af9033_i2c_addr[1] ||
-                           msg[0].addr == (state->af9033_i2c_addr[1] >> 1))
+                       if (msg[0].addr == state->af9033_i2c_addr[1])
                                reg |= 0x100000;
 
                        ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
@@ -396,14 +394,12 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                        /* TODO: correct limits > 40 */
                        ret = -EOPNOTSUPP;
                } else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
-                          (msg[0].addr == state->af9033_i2c_addr[1]) ||
-                          (state->chip_type == 0x9135)) {
+                          (msg[0].addr == state->af9033_i2c_addr[1])) {
                        /* demod access via firmware interface */
                        u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
                                        msg[0].buf[2];
 
-                       if (msg[0].addr == state->af9033_i2c_addr[1] ||
-                           msg[0].addr == (state->af9033_i2c_addr[1] >> 1))
+                       if (msg[0].addr == state->af9033_i2c_addr[1])
                                reg |= 0x100000;
 
                        ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
@@ -496,7 +492,8 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
 {
        struct state *state = d_to_priv(d);
        struct usb_interface *intf = d->intf;
-       int ret, ts_mode_invalid;
+       int ret, i, ts_mode_invalid;
+       unsigned int utmp, eeprom_addr;
        u8 tmp;
        u8 wbuf[1] = { 1 };
        u8 rbuf[4];
@@ -518,25 +515,48 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
                 state->prechip_version, state->chip_version, state->chip_type);
 
        if (state->chip_type == 0x9135) {
-               if (state->chip_version == 0x02)
+               if (state->chip_version == 0x02) {
                        *name = AF9035_FIRMWARE_IT9135_V2;
-               else
+                       utmp = 0x00461d;
+               } else {
                        *name = AF9035_FIRMWARE_IT9135_V1;
-               state->eeprom_addr = EEPROM_BASE_IT9135;
+                       utmp = 0x00461b;
+               }
+
+               /* Check if eeprom exists */
+               ret = af9035_rd_reg(d, utmp, &tmp);
+               if (ret < 0)
+                       goto err;
+
+               if (tmp == 0x00) {
+                       dev_dbg(&intf->dev, "no eeprom\n");
+                       state->no_eeprom = true;
+                       goto check_firmware_status;
+               }
+
+               eeprom_addr = EEPROM_BASE_IT9135;
        } else if (state->chip_type == 0x9306) {
                *name = AF9035_FIRMWARE_IT9303;
-               state->eeprom_addr = EEPROM_BASE_IT9135;
+               state->no_eeprom = true;
+               goto check_firmware_status;
        } else {
                *name = AF9035_FIRMWARE_AF9035;
-               state->eeprom_addr = EEPROM_BASE_AF9035;
+               eeprom_addr = EEPROM_BASE_AF9035;
+       }
+
+       /* Read and store eeprom */
+       for (i = 0; i < 256; i += 32) {
+               ret = af9035_rd_regs(d, eeprom_addr + i, &state->eeprom[i], 32);
+               if (ret < 0)
+                       goto err;
        }
 
+       dev_dbg(&intf->dev, "eeprom dump:\n");
+       for (i = 0; i < 256; i += 16)
+               dev_dbg(&intf->dev, "%*ph\n", 16, &state->eeprom[i]);
 
        /* check for dual tuner mode */
-       ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
-       if (ret < 0)
-               goto err;
-
+       tmp = state->eeprom[EEPROM_TS_MODE];
        ts_mode_invalid = 0;
        switch (tmp) {
        case 0:
@@ -560,7 +580,7 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
        if (ts_mode_invalid)
                dev_info(&intf->dev, "ts mode=%d not supported, defaulting to single tuner mode!", tmp);
 
-
+check_firmware_status:
        ret = af9035_ctrl_msg(d, &req);
        if (ret < 0)
                goto err;
@@ -750,15 +770,11 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
                        goto err;
 
                /* tell the slave I2C address */
-               ret = af9035_rd_reg(d,
-                               state->eeprom_addr + EEPROM_2ND_DEMOD_ADDR,
-                               &tmp);
-               if (ret < 0)
-                       goto err;
+               tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
 
-               /* use default I2C address if eeprom has no address set */
+               /* Use default I2C address if eeprom has no address set */
                if (!tmp)
-                       tmp = 0x3a;
+                       tmp = 0x1d << 1; /* 8-bit format used by chip */
 
                if ((state->chip_type == 0x9135) ||
                                (state->chip_type == 0x9306)) {
@@ -819,11 +835,11 @@ static int af9035_read_config(struct dvb_usb_device *d)
        struct state *state = d_to_priv(d);
        int ret, i;
        u8 tmp;
-       u16 tmp16, addr;
+       u16 tmp16;
 
-       /* demod I2C "address" */
-       state->af9033_i2c_addr[0] = 0x38;
-       state->af9033_i2c_addr[1] = 0x3a;
+       /* Demod I2C address */
+       state->af9033_i2c_addr[0] = 0x1c;
+       state->af9033_i2c_addr[1] = 0x1d;
        state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
        state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
        state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
@@ -837,20 +853,16 @@ static int af9035_read_config(struct dvb_usb_device *d)
                if (state->chip_version == 0x02) {
                        state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60;
                        state->af9033_config[1].tuner = AF9033_TUNER_IT9135_60;
-                       tmp16 = 0x00461d; /* eeprom memory mapped location */
                } else {
                        state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38;
                        state->af9033_config[1].tuner = AF9033_TUNER_IT9135_38;
-                       tmp16 = 0x00461b; /* eeprom memory mapped location */
                }
 
-               /* check if eeprom exists */
-               ret = af9035_rd_reg(d, tmp16, &tmp);
-               if (ret < 0)
-                       goto err;
+               if (state->no_eeprom) {
+                       /* Remote controller to NEC polling by default */
+                       state->ir_mode = 0x05;
+                       state->ir_type = 0x00;
 
-               if (tmp == 0x00) {
-                       dev_dbg(&intf->dev, "no eeprom\n");
                        goto skip_eeprom;
                }
        } else if (state->chip_type == 0x9306) {
@@ -861,29 +873,25 @@ static int af9035_read_config(struct dvb_usb_device *d)
                return 0;
        }
 
+       /* Remote controller */
+       state->ir_mode = state->eeprom[EEPROM_IR_MODE];
+       state->ir_type = state->eeprom[EEPROM_IR_TYPE];
 
        if (state->dual_mode) {
-               /* read 2nd demodulator I2C address */
-               ret = af9035_rd_reg(d,
-                               state->eeprom_addr + EEPROM_2ND_DEMOD_ADDR,
-                               &tmp);
-               if (ret < 0)
-                       goto err;
-
+               /* Read 2nd demodulator I2C address. 8-bit format on eeprom */
+               tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
                if (tmp)
-                       state->af9033_i2c_addr[1] = tmp;
+                       state->af9033_i2c_addr[1] = tmp >> 1;
 
-               dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n", tmp);
+               dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n",
+                       state->af9033_i2c_addr[1]);
        }
 
-       addr = state->eeprom_addr;
-
        for (i = 0; i < state->dual_mode + 1; i++) {
-               /* tuner */
-               ret = af9035_rd_reg(d, addr + EEPROM_1_TUNER_ID, &tmp);
-               if (ret < 0)
-                       goto err;
+               unsigned int eeprom_offset = 0;
 
+               /* tuner */
+               tmp = state->eeprom[EEPROM_1_TUNER_ID + eeprom_offset];
                dev_dbg(&intf->dev, "[%d]tuner=%02x\n", i, tmp);
 
                /* tuner sanity check */
@@ -956,21 +964,13 @@ static int af9035_read_config(struct dvb_usb_device *d)
                }
 
                /* tuner IF frequency */
-               ret = af9035_rd_reg(d, addr + EEPROM_1_IF_L, &tmp);
-               if (ret < 0)
-                       goto err;
-
-               tmp16 = tmp;
-
-               ret = af9035_rd_reg(d, addr + EEPROM_1_IF_H, &tmp);
-               if (ret < 0)
-                       goto err;
-
+               tmp = state->eeprom[EEPROM_1_IF_L + eeprom_offset];
+               tmp16 = tmp << 0;
+               tmp = state->eeprom[EEPROM_1_IF_H + eeprom_offset];
                tmp16 |= tmp << 8;
-
                dev_dbg(&intf->dev, "[%d]IF=%d\n", i, tmp16);
 
-               addr += 0x10; /* shift for the 2nd tuner params */
+               eeprom_offset += 0x10; /* shift for the 2nd tuner params */
        }
 
 skip_eeprom:
@@ -1247,30 +1247,11 @@ static int af9035_frontend_detach(struct dvb_usb_adapter *adap)
        struct state *state = adap_to_priv(adap);
        struct dvb_usb_device *d = adap_to_d(adap);
        struct usb_interface *intf = d->intf;
-       int demod2;
 
        dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
 
-       /*
-        * For dual tuner devices we have to resolve 2nd demod client, as there
-        * is two different kind of tuner drivers; one is using I2C binding
-        * and the other is using DVB attach/detach binding.
-        */
-       switch (state->af9033_config[adap->id].tuner) {
-       case AF9033_TUNER_IT9135_38:
-       case AF9033_TUNER_IT9135_51:
-       case AF9033_TUNER_IT9135_52:
-       case AF9033_TUNER_IT9135_60:
-       case AF9033_TUNER_IT9135_61:
-       case AF9033_TUNER_IT9135_62:
-               demod2 = 2;
-               break;
-       default:
-               demod2 = 1;
-       }
-
        if (adap->id == 1) {
-               if (state->i2c_client[demod2])
+               if (state->i2c_client[1])
                        af9035_del_i2c_dev(d);
        } else if (adap->id == 0) {
                if (state->i2c_client[0])
@@ -1510,50 +1491,58 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
        case AF9033_TUNER_IT9135_38:
        case AF9033_TUNER_IT9135_51:
        case AF9033_TUNER_IT9135_52:
-       {
-               struct it913x_config it913x_config = {
-                       .fe = adap->fe[0],
-                       .chip_ver = 1,
-               };
-
-               if (state->dual_mode) {
-                       if (adap->id == 0)
-                               it913x_config.role = IT913X_ROLE_DUAL_MASTER;
-                       else
-                               it913x_config.role = IT913X_ROLE_DUAL_SLAVE;
-               }
-
-               ret = af9035_add_i2c_dev(d, "it913x",
-                               state->af9033_i2c_addr[adap->id] >> 1,
-                               &it913x_config, &d->i2c_adap);
-               if (ret)
-                       goto err;
-
-               fe = adap->fe[0];
-               break;
-       }
        case AF9033_TUNER_IT9135_60:
        case AF9033_TUNER_IT9135_61:
        case AF9033_TUNER_IT9135_62:
        {
-               struct it913x_config it913x_config = {
+               struct platform_device *pdev;
+               const char *name;
+               struct it913x_platform_data it913x_pdata = {
+                       .regmap = state->af9033_config[adap->id].regmap,
                        .fe = adap->fe[0],
-                       .chip_ver = 2,
                };
 
+               switch (state->af9033_config[adap->id].tuner) {
+               case AF9033_TUNER_IT9135_38:
+               case AF9033_TUNER_IT9135_51:
+               case AF9033_TUNER_IT9135_52:
+                       name = "it9133ax-tuner";
+                       break;
+               case AF9033_TUNER_IT9135_60:
+               case AF9033_TUNER_IT9135_61:
+               case AF9033_TUNER_IT9135_62:
+                       name = "it9133bx-tuner";
+                       break;
+               default:
+                       ret = -ENODEV;
+                       goto err;
+               }
+
                if (state->dual_mode) {
                        if (adap->id == 0)
-                               it913x_config.role = IT913X_ROLE_DUAL_MASTER;
+                               it913x_pdata.role = IT913X_ROLE_DUAL_MASTER;
                        else
-                               it913x_config.role = IT913X_ROLE_DUAL_SLAVE;
+                               it913x_pdata.role = IT913X_ROLE_DUAL_SLAVE;
+               } else {
+                       it913x_pdata.role = IT913X_ROLE_SINGLE;
                }
 
-               ret = af9035_add_i2c_dev(d, "it913x",
-                               state->af9033_i2c_addr[adap->id] >> 1,
-                               &it913x_config, &d->i2c_adap);
-               if (ret)
+               request_module("%s", "it913x");
+               pdev = platform_device_register_data(&d->intf->dev, name,
+                                                    PLATFORM_DEVID_AUTO,
+                                                    &it913x_pdata,
+                                                    sizeof(it913x_pdata));
+               if (IS_ERR(pdev) || !pdev->dev.driver) {
+                       ret = -ENODEV;
+                       goto err;
+               }
+               if (!try_module_get(pdev->dev.driver->owner)) {
+                       platform_device_unregister(pdev);
+                       ret = -ENODEV;
                        goto err;
+               }
 
+               state->platform_device_tuner[adap->id] = pdev;
                fe = adap->fe[0];
                break;
        }
@@ -1675,12 +1664,6 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
        switch (state->af9033_config[adap->id].tuner) {
        case AF9033_TUNER_TUA9001:
        case AF9033_TUNER_FC2580:
-       case AF9033_TUNER_IT9135_38:
-       case AF9033_TUNER_IT9135_51:
-       case AF9033_TUNER_IT9135_52:
-       case AF9033_TUNER_IT9135_60:
-       case AF9033_TUNER_IT9135_61:
-       case AF9033_TUNER_IT9135_62:
                if (adap->id == 1) {
                        if (state->i2c_client[3])
                                af9035_del_i2c_dev(d);
@@ -1688,6 +1671,23 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
                        if (state->i2c_client[1])
                                af9035_del_i2c_dev(d);
                }
+               break;
+       case AF9033_TUNER_IT9135_38:
+       case AF9033_TUNER_IT9135_51:
+       case AF9033_TUNER_IT9135_52:
+       case AF9033_TUNER_IT9135_60:
+       case AF9033_TUNER_IT9135_61:
+       case AF9033_TUNER_IT9135_62:
+       {
+               struct platform_device *pdev;
+
+               pdev = state->platform_device_tuner[adap->id];
+               if (pdev) {
+                       module_put(pdev->dev.driver->owner);
+                       platform_device_unregister(pdev);
+               }
+               break;
+       }
        }
 
        return 0;
@@ -1872,25 +1872,13 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
 {
        struct state *state = d_to_priv(d);
        struct usb_interface *intf = d->intf;
-       int ret;
-       u8 tmp;
-
-       ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_IR_MODE, &tmp);
-       if (ret < 0)
-               goto err;
 
-       dev_dbg(&intf->dev, "ir_mode=%02x\n", tmp);
+       dev_dbg(&intf->dev, "ir_mode=%02x ir_type=%02x\n",
+               state->ir_mode, state->ir_type);
 
        /* don't activate rc if in HID mode or if not available */
-       if (tmp == 5) {
-               ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_IR_TYPE,
-                               &tmp);
-               if (ret < 0)
-                       goto err;
-
-               dev_dbg(&intf->dev, "ir_type=%02x\n", tmp);
-
-               switch (tmp) {
+       if (state->ir_mode == 0x05) {
+               switch (state->ir_type) {
                case 0: /* NEC */
                default:
                        rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX |
@@ -1910,11 +1898,6 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
        }
 
        return 0;
-
-err:
-       dev_dbg(&intf->dev, "failed=%d\n", ret);
-
-       return ret;
 }
 #else
        #define af9035_get_rc_config NULL
index 1f83c9218ad06a54b8d974e4762e6fb8a22e5931..a76e6bf0ab1ee13801241dd3b912994e4e05dab8 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef AF9035_H
 #define AF9035_H
 
+#include <linux/platform_device.h>
 #include "dvb_usb.h"
 #include "af9033.h"
 #include "tua9001.h"
@@ -61,15 +62,19 @@ struct state {
        u8 prechip_version;
        u8 chip_version;
        u16 chip_type;
+       u8 eeprom[256];
+       bool no_eeprom;
+       u8 ir_mode;
+       u8 ir_type;
        u8 dual_mode:1;
        u8 no_read:1;
-       u16 eeprom_addr;
        u8 af9033_i2c_addr[2];
        struct af9033_config af9033_config[2];
        struct af9033_ops ops;
        #define AF9035_I2C_CLIENT_MAX 4
        struct i2c_client *i2c_client[AF9035_I2C_CLIENT_MAX];
        struct i2c_adapter *i2c_adapter_demod;
+       struct platform_device *platform_device_tuner[2];
 };
 
 static const u32 clock_lut_af9035[] = {
index ae917c042a52e7737a74e536328906014dbe34aa..6795c0c609b186dcd7d1a88857918e7796a7eb33 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * TODO:
  * - add smart card reader support for Conditional Access (CA)
  *
index 3ca2bca4ebafacc581bfd3cc3aa17c3d087c209b..393e2fce2aed04a880e5de81344fca359a2ebbde 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * TODO:
  * - add smart card reader support for Conditional Access (CA)
  *
index ae6a671b7fd55dae414501628918d4d00f4a5336..6ee01cb64ca5ac1a45c288678c5c867dc5aa0e9d 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "au6610.h"
index ea337bfc00b111aae5de96e85f370fddefa73cf2..aacfcc6fa0f56a3dce90aac469666a1d7720f4c3 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef AU6610_H
index f67b14bc32e3e653174dbae9e6d64567c657b389..e596031a708d06d69b20af0c2de0a60183b334c2 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "ce6230.h"
index 299e57e3390b8714549b867bf67df3adc02f6b24..b25b3b938e492ffd669031180205b485fd01dcd4 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef CE6230_H
index a8e6624fbe8347fb48055d0048cd4bf84575edc1..955fb0d075070a2ee62b0afa698268049fd90f09 100644 (file)
@@ -147,7 +147,7 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
        if (!d->rc.map_name)
                return 0;
 
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(d->rc.driver_type);
        if (!dev) {
                ret = -ENOMEM;
                goto err;
@@ -162,7 +162,6 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
        /* TODO: likely RC-core should took const char * */
        dev->driver_name = (char *) d->props->driver_name;
        dev->map_name = d->rc.map_name;
-       dev->driver_type = d->rc.driver_type;
        dev->allowed_protocols = d->rc.allowed_protos;
        dev->change_protocol = d->rc.change_protocol;
        dev->priv = d;
@@ -1013,8 +1012,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe);
 void dvb_usbv2_disconnect(struct usb_interface *intf)
 {
        struct dvb_usb_device *d = usb_get_intfdata(intf);
-       const char *name = d->name;
-       struct device dev = d->udev->dev;
+       const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL);
+       const char *drvname = d->name;
 
        dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
                        intf->cur_altsetting->desc.bInterfaceNumber);
@@ -1024,8 +1023,9 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
 
        dvb_usbv2_exit(d);
 
-       dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
-                       KBUILD_MODNAME, name);
+       pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
+               KBUILD_MODNAME, drvname, devname);
+       kfree(devname);
 }
 EXPORT_SYMBOL(dvb_usbv2_disconnect);
 
index 0636eac37bbbf8aa0af02cef377c1f54373ae5a2..5730760e4e93b67ac54a0d2551154be17064bd80 100644 (file)
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "dvb_usb.h"
index 0c2b377704ff18daba836e2af3151a7765982092..1db8aeef36553d67d63ca04fd6013fce883e9471 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "ec168.h"
index 615a6569421f55298a07b4770711f0ef9e895113..704955bcaa102b946ea865c0baea9d00c3005388 100644 (file)
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *    GNU General Public License for more details.
  *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef EC168_H
index 5fea02672685b41cf46f0eb31c67b7fc763c0fde..924adfdb660da3b7dcdc339a06cd8ec921d2bf8d 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *
  * see Documentation/dvb/README.dvb-usb for more information
  *
@@ -99,9 +95,7 @@ static int dvb_usb_lme2510_debug;
 } while (0)
 #define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
 #define debug_data_snipet(level, name, p) \
-        deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
-               *p, *(p+1), *(p+2), *(p+3), *(p+4), \
-                       *(p+5), *(p+6), *(p+7));
+        deb_info(level, name" (%8phN)", p);
 #define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
 
 module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
@@ -315,7 +309,7 @@ static void lme2510_int_response(struct urb *lme_urb)
 {
        struct dvb_usb_adapter *adap = lme_urb->context;
        struct lme2510_state *st = adap_to_priv(adap);
-       static u8 *ibuf, *rbuf;
+       u8 *ibuf, *rbuf;
        int i = 0, offset;
        u32 key;
        u8 signal_lock = 0;
@@ -1002,8 +996,9 @@ static int lme_name(struct dvb_usb_adapter *adap)
        struct dvb_usb_device *d = adap_to_d(adap);
        struct lme2510_state *st = adap_to_priv(adap);
        const char *desc = d->name;
-       char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
-                               " SHARP:BS2F7HZ0194", " RS2000"};
+       static const char * const fe_name[] = {
+               "", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
+               " SHARP:BS2F7HZ0194", " RS2000"};
        char *name = adap->fe[0]->ops.info.name;
 
        strlcpy(name, desc, 128);
@@ -1124,7 +1119,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
 {
        struct dvb_usb_device *d = adap_to_d(adap);
        struct lme2510_state *st = adap_to_priv(adap);
-       char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
+       static const char * const tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
        int ret = 0;
 
        switch (st->tuner_config) {
@@ -1178,10 +1173,7 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
 
        mutex_lock(&d->i2c_mutex);
 
-       if (onoff)
-               ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
-       else
-               ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+       ret = lme2510_usb_talk(d, onoff ? lnb_on : lnb_off, len, rbuf, rlen);
 
        st->i2c_talk_onoff = 1;
 
index 639e156e0c1b0edf7cebb8d62350e1b835021c0a..f0ed37da73d42798fe9e028d1005180022c23742 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "mxl111sf-demod.h"
index e6eae9d88e9f2a36dbead11d6ee615a5ea5518bb..9cb4972ce7a3ef0dc6dc946b82827e26703dcaca 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MXL111SF_DEMOD_H__
index 2180c13a6dcc18497c92fdfc05e49f61cfb7ad94..c66861c9342bfe34200f59ee6af59e84a7a1e7cc 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "mxl111sf-gpio.h"
index 16fa4d4daf88d368e85ab5aecf4e9bf7455a41f6..af2c7bc8f3014dd483d89bfac166d56b063ac171 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _DVB_USB_MXL111SF_GPIO_H_
index 6427137a09ef8abf1075990c4e996e602c3079c0..ffb49c28b15a985a312e69d81989f55377f8c9f2 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "mxl111sf-i2c.h"
index c486fe02f01879e467d5304eb465fa9f6054ee80..28877c7a8175ac067563524e545998db105ff42b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _DVB_USB_MXL111SF_I2C_H_
index 5b0191178f9fc6ce4d219a9aa76894b56de4830e..ffb6e7c72f57492860d7a4fdad80d3544f8db969 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "mxl111sf-phy.h"
index 25aa4a1ea755c0ec767bfe4b135227bf752df6b3..0a61e8a565848891459f51847bd97946395b3d07 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _DVB_USB_MXL111SF_PHY_H_
index 1f4bfbcdbabb34b4c8dc7ee05b71fa6acc44a19d..ad3f806dcc7a9ba10d07ca98fd1d7c0267350229 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _DVB_USB_MXL111SF_REG_H_
index f84bef6034dcb73eee483172ba5b0d4f2da010b8..240d736bf1bb39e2e1f8430aab35c2aa2bd04a8a 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "mxl111sf-tuner.h"
index e96d9a444ed1aae155a439503bf99323d0d493b4..11ea07a7327180cc508a468ce196c74f9c0690c4 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef __MXL111SF_TUNER_H__
index c583c638e4681878ff46d1596f40f54b456b2848..e16ca07acf1db68b337e5adae429aac976e20d6b 100644 (file)
@@ -1778,7 +1778,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
        /* load empty to enable rc */
        if (!rc->map_name)
                rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_BIT_ALL;
+       rc->allowed_protos = RC_BIT_ALL_IR_DECODER;
        rc->driver_type = RC_DRIVER_IR_RAW;
        rc->query = rtl2832u_rc_query;
        rc->interval = 200;
diff --git a/drivers/media/usb/dvb-usb-v2/zd1301.c b/drivers/media/usb/dvb-usb-v2/zd1301.c
new file mode 100644 (file)
index 0000000..d1eb4b7
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * ZyDAS ZD1301 driver (USB interface)
+ *
+ * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "dvb_usb.h"
+#include "zd1301_demod.h"
+#include "mt2060.h"
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct zd1301_dev {
+       #define BUF_LEN 8
+       u8 buf[BUF_LEN]; /* bulk USB control message */
+       struct zd1301_demod_platform_data demod_pdata;
+       struct mt2060_platform_data mt2060_pdata;
+       struct platform_device *platform_device_demod;
+       struct i2c_client *i2c_client_tuner;
+};
+
+static int zd1301_ctrl_msg(struct dvb_usb_device *d, const u8 *wbuf,
+                          unsigned int wlen, u8 *rbuf, unsigned int rlen)
+{
+       struct zd1301_dev *dev = d_to_priv(d);
+       struct usb_interface *intf = d->intf;
+       int ret, actual_length;
+
+       mutex_lock(&d->usb_mutex);
+
+       memcpy(&dev->buf, wbuf, wlen);
+
+       dev_dbg(&intf->dev, ">>> %*ph\n", wlen, dev->buf);
+
+       ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, 0x04), dev->buf,
+                          wlen, &actual_length, 1000);
+       if (ret) {
+               dev_err(&intf->dev, "1st usb_bulk_msg() failed %d\n", ret);
+               goto err_mutex_unlock;
+       }
+
+       if (rlen) {
+               ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 0x83),
+                                  dev->buf, rlen, &actual_length, 1000);
+               if (ret) {
+                       dev_err(&intf->dev,
+                               "2nd usb_bulk_msg() failed %d\n", ret);
+                       goto err_mutex_unlock;
+               }
+
+               dev_dbg(&intf->dev, "<<< %*ph\n", actual_length, dev->buf);
+
+               if (actual_length != rlen) {
+                       /*
+                        * Chip replies often with 3 byte len stub. On that case
+                        * we have to query new reply.
+                        */
+                       dev_dbg(&intf->dev, "repeating reply message\n");
+
+                       ret = usb_bulk_msg(d->udev,
+                                          usb_rcvbulkpipe(d->udev, 0x83),
+                                          dev->buf, rlen, &actual_length,
+                                          1000);
+                       if (ret) {
+                               dev_err(&intf->dev,
+                                       "3rd usb_bulk_msg() failed %d\n", ret);
+                               goto err_mutex_unlock;
+                       }
+
+                       dev_dbg(&intf->dev,
+                               "<<< %*ph\n", actual_length, dev->buf);
+               }
+
+               memcpy(rbuf, dev->buf, rlen);
+       }
+
+err_mutex_unlock:
+       mutex_unlock(&d->usb_mutex);
+       return ret;
+}
+
+static int zd1301_demod_wreg(void *reg_priv, u16 reg, u8 val)
+{
+       struct dvb_usb_device *d = reg_priv;
+       struct usb_interface *intf = d->intf;
+       int ret;
+       u8 buf[7] = {0x07, 0x00, 0x03, 0x01,
+                    (reg >> 0) & 0xff, (reg >> 8) & 0xff, val};
+
+       ret = zd1301_ctrl_msg(d, buf, 7, NULL, 0);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&intf->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_demod_rreg(void *reg_priv, u16 reg, u8 *val)
+{
+       struct dvb_usb_device *d = reg_priv;
+       struct usb_interface *intf = d->intf;
+       int ret;
+       u8 buf[7] = {0x07, 0x00, 0x04, 0x01,
+                    (reg >> 0) & 0xff, (reg >> 8) & 0xff, 0};
+
+       ret = zd1301_ctrl_msg(d, buf, 7, buf, 7);
+       if (ret)
+               goto err;
+
+       *val = buf[6];
+
+       return 0;
+err:
+       dev_dbg(&intf->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct zd1301_dev *dev = adap_to_priv(adap);
+       struct usb_interface *intf = d->intf;
+       struct platform_device *pdev;
+       struct i2c_client *client;
+       struct i2c_board_info board_info;
+       struct i2c_adapter *adapter;
+       struct dvb_frontend *frontend;
+       int ret;
+
+       dev_dbg(&intf->dev, "\n");
+
+       /* Add platform demod */
+       dev->demod_pdata.reg_priv = d;
+       dev->demod_pdata.reg_read = zd1301_demod_rreg;
+       dev->demod_pdata.reg_write = zd1301_demod_wreg;
+       request_module("%s", "zd1301_demod");
+       pdev = platform_device_register_data(&intf->dev,
+                                            "zd1301_demod",
+                                            PLATFORM_DEVID_AUTO,
+                                            &dev->demod_pdata,
+                                            sizeof(dev->demod_pdata));
+       if (IS_ERR(pdev)) {
+               ret = PTR_ERR(pdev);
+               goto err;
+       }
+       if (!pdev->dev.driver) {
+               ret = -ENODEV;
+               goto err;
+       }
+       if (!try_module_get(pdev->dev.driver->owner)) {
+               ret = -ENODEV;
+               goto err_platform_device_unregister;
+       }
+
+       adapter = zd1301_demod_get_i2c_adapter(pdev);
+       frontend = zd1301_demod_get_dvb_frontend(pdev);
+       if (!adapter || !frontend) {
+               ret = -ENODEV;
+               goto err_module_put_demod;
+       }
+
+       /* Add I2C tuner */
+       dev->mt2060_pdata.i2c_write_max = 9;
+       dev->mt2060_pdata.dvb_frontend = frontend;
+       memset(&board_info, 0, sizeof(board_info));
+       strlcpy(board_info.type, "mt2060", I2C_NAME_SIZE);
+       board_info.addr = 0x60;
+       board_info.platform_data = &dev->mt2060_pdata;
+       request_module("%s", "mt2060");
+       client = i2c_new_device(adapter, &board_info);
+       if (!client || !client->dev.driver) {
+               ret = -ENODEV;
+               goto err_module_put_demod;
+       }
+       if (!try_module_get(client->dev.driver->owner)) {
+               ret = -ENODEV;
+               goto err_i2c_unregister_device;
+       }
+
+       dev->platform_device_demod = pdev;
+       dev->i2c_client_tuner = client;
+       adap->fe[0] = frontend;
+
+       return 0;
+err_i2c_unregister_device:
+       i2c_unregister_device(client);
+err_module_put_demod:
+       module_put(pdev->dev.driver->owner);
+err_platform_device_unregister:
+       platform_device_unregister(pdev);
+err:
+       dev_dbg(&intf->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static int zd1301_frontend_detach(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap_to_d(adap);
+       struct zd1301_dev *dev = d_to_priv(d);
+       struct usb_interface *intf = d->intf;
+       struct platform_device *pdev;
+       struct i2c_client *client;
+
+       dev_dbg(&intf->dev, "\n");
+
+       client = dev->i2c_client_tuner;
+       pdev = dev->platform_device_demod;
+
+       /* Remove I2C tuner */
+       if (client) {
+               module_put(client->dev.driver->owner);
+               i2c_unregister_device(client);
+       }
+
+       /* Remove platform demod */
+       if (pdev) {
+               module_put(pdev->dev.driver->owner);
+               platform_device_unregister(pdev);
+       }
+
+       return 0;
+}
+
+static int zd1301_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+       struct dvb_usb_device *d = fe_to_d(fe);
+       struct usb_interface *intf = d->intf;
+       int ret;
+       u8 buf[3] = {0x03, 0x00, onoff ? 0x07 : 0x08};
+
+       dev_dbg(&intf->dev, "onoff=%d\n", onoff);
+
+       ret = zd1301_ctrl_msg(d, buf, 3, NULL, 0);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       dev_dbg(&intf->dev, "failed=%d\n", ret);
+       return ret;
+}
+
+static const struct dvb_usb_device_properties zd1301_props = {
+       .driver_name = KBUILD_MODNAME,
+       .owner = THIS_MODULE,
+       .adapter_nr = adapter_nr,
+       .size_of_priv = sizeof(struct zd1301_dev),
+
+       .frontend_attach = zd1301_frontend_attach,
+       .frontend_detach = zd1301_frontend_detach,
+       .streaming_ctrl  = zd1301_streaming_ctrl,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .stream = DVB_USB_STREAM_BULK(0x81, 6, 21 * 188),
+               },
+       },
+};
+
+static const struct usb_device_id zd1301_id_table[] = {
+       {DVB_USB_DEVICE(USB_VID_ZYDAS, 0x13a1, &zd1301_props,
+                       "ZyDAS ZD1301 reference design", NULL)},
+       {}
+};
+MODULE_DEVICE_TABLE(usb, zd1301_id_table);
+
+/* Usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver zd1301_usb_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = zd1301_id_table,
+       .probe = dvb_usbv2_probe,
+       .disconnect = dvb_usbv2_disconnect,
+       .suspend = dvb_usbv2_suspend,
+       .resume = dvb_usbv2_resume,
+       .reset_resume = dvb_usbv2_reset_resume,
+       .no_dynamic_id = 1,
+       .soft_unbind = 1,
+};
+module_usb_driver(zd1301_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("ZyDAS ZD1301 driver");
+MODULE_LICENSE("GPL");
index 9862d3e6b8e8ff44896f18addaf0cfcb916fa65e..544bdf18fb2fe4d4d41dfa67f5e9eeac5b7cc1a1 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "af9005.h"
index 7e3961d0db6b8c64018596ece3896b77bbaeffe0..9b29ffa9307502431c9c4ce79bb3d759ee1e18bc 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "af9005.h"
index f5f476841aea0ca5103a69b7d979674ef37d03cd..986763b1b2b32a2688a2f9a75db4392bf2bc2d5e 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "af9005.h"
index 6a2bf3de845668c162cf679fdab5eaaf775005c0..a1eae0fa02edda2e70304bf8016a97632e86a65a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #ifndef _DVB_USB_AF9005_H_
index 6404205560eb4d190844688c3111cc19721fd79e..6131aa7914a9a1333be69eb367447b0c411ebdeb 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "cinergyT2.h"
index bbb10fab65bceb82c22bbb5369f40dd72181a229..f9772ad0a2a5c114ebbae1c70f381b84f6525ea5 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "cinergyT2.h"
index 84efe03771eb1da8278cf613fd051f2b58f17b35..c04b819be160d0f762f0d4dfaf5871416a721cc6 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not,  write to the Free Software
- * Foundation,  Inc.,  675 Mass Ave,  Cambridge,  MA 02139,  USA.
- *
  */
 
 #ifndef _DVB_USB_CINERGYT2_H_
index 9b8771eb31d44d87515d82ca7f69fbd04b6efec3..51620e02292f588b6643862c3207aa6d5cd75948 100644 (file)
@@ -59,23 +59,24 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
                          u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
        struct cxusb_state *st = d->priv;
-       int ret, wo;
+       int ret;
 
        if (1 + wlen > MAX_XFER_SIZE) {
                warn("i2c wr: len=%d is too big!\n", wlen);
                return -EOPNOTSUPP;
        }
 
-       wo = (rbuf == NULL || rlen == 0); /* write-only */
+       if (rlen > MAX_XFER_SIZE) {
+               warn("i2c rd: len=%d is too big!\n", rlen);
+               return -EOPNOTSUPP;
+       }
 
        mutex_lock(&d->data_mutex);
        st->data[0] = cmd;
        memcpy(&st->data[1], wbuf, wlen);
-       if (wo)
-               ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
-       else
-               ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
-                                        rbuf, rlen, 0);
+       ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0);
+       if (!ret && rbuf && rlen)
+               memcpy(rbuf, st->data, rlen);
 
        mutex_unlock(&d->data_mutex);
        return ret;
@@ -450,209 +451,46 @@ static int cxusb_d680_dmb_streaming_ctrl(
        }
 }
 
-static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int cxusb_rc_query(struct dvb_usb_device *d)
 {
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
        u8 ircode[4];
-       int i;
 
        cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
 
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               if (rc5_custom(&keymap[i]) == ircode[2] &&
-                   rc5_data(&keymap[i]) == ircode[3]) {
-                       *event = keymap[i].keycode;
-                       *state = REMOTE_KEY_PRESSED;
-
-                       return 0;
-               }
-       }
-
+       if (ircode[2] || ircode[3])
+               rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN,
+                          RC_SCANCODE_RC5(ircode[2], ircode[3]), 0);
        return 0;
 }
 
-static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
-                                   int *state)
+static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d)
 {
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
        u8 ircode[4];
-       int i;
        struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
                               .buf = ircode, .len = 4 };
 
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
-
        if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
                return 0;
 
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               if (rc5_custom(&keymap[i]) == ircode[1] &&
-                   rc5_data(&keymap[i]) == ircode[2]) {
-                       *event = keymap[i].keycode;
-                       *state = REMOTE_KEY_PRESSED;
-
-                       return 0;
-               }
-       }
-
+       if (ircode[1] || ircode[2])
+               rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN,
+                          RC_SCANCODE_RC5(ircode[1], ircode[2]), 0);
        return 0;
 }
 
-static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
-               int *state)
+static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d)
 {
-       struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
        u8 ircode[2];
-       int i;
-
-       *event = 0;
-       *state = REMOTE_NO_KEY_PRESSED;
 
        if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
                return 0;
 
-       for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
-               if (rc5_custom(&keymap[i]) == ircode[0] &&
-                   rc5_data(&keymap[i]) == ircode[1]) {
-                       *event = keymap[i].keycode;
-                       *state = REMOTE_KEY_PRESSED;
-
-                       return 0;
-               }
-       }
-
+       if (ircode[0] || ircode[1])
+               rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN,
+                          RC_SCANCODE_RC5(ircode[0], ircode[1]), 0);
        return 0;
 }
 
-static struct rc_map_table rc_map_dvico_mce_table[] = {
-       { 0xfe02, KEY_TV },
-       { 0xfe0e, KEY_MP3 },
-       { 0xfe1a, KEY_DVD },
-       { 0xfe1e, KEY_FAVORITES },
-       { 0xfe16, KEY_SETUP },
-       { 0xfe46, KEY_POWER2 },
-       { 0xfe0a, KEY_EPG },
-       { 0xfe49, KEY_BACK },
-       { 0xfe4d, KEY_MENU },
-       { 0xfe51, KEY_UP },
-       { 0xfe5b, KEY_LEFT },
-       { 0xfe5f, KEY_RIGHT },
-       { 0xfe53, KEY_DOWN },
-       { 0xfe5e, KEY_OK },
-       { 0xfe59, KEY_INFO },
-       { 0xfe55, KEY_TAB },
-       { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
-       { 0xfe12, KEY_NEXTSONG },       /* Skip */
-       { 0xfe42, KEY_ENTER      },     /* Windows/Start */
-       { 0xfe15, KEY_VOLUMEUP },
-       { 0xfe05, KEY_VOLUMEDOWN },
-       { 0xfe11, KEY_CHANNELUP },
-       { 0xfe09, KEY_CHANNELDOWN },
-       { 0xfe52, KEY_CAMERA },
-       { 0xfe5a, KEY_TUNER },  /* Live */
-       { 0xfe19, KEY_OPEN },
-       { 0xfe0b, KEY_1 },
-       { 0xfe17, KEY_2 },
-       { 0xfe1b, KEY_3 },
-       { 0xfe07, KEY_4 },
-       { 0xfe50, KEY_5 },
-       { 0xfe54, KEY_6 },
-       { 0xfe48, KEY_7 },
-       { 0xfe4c, KEY_8 },
-       { 0xfe58, KEY_9 },
-       { 0xfe13, KEY_ANGLE },  /* Aspect */
-       { 0xfe03, KEY_0 },
-       { 0xfe1f, KEY_ZOOM },
-       { 0xfe43, KEY_REWIND },
-       { 0xfe47, KEY_PLAYPAUSE },
-       { 0xfe4f, KEY_FASTFORWARD },
-       { 0xfe57, KEY_MUTE },
-       { 0xfe0d, KEY_STOP },
-       { 0xfe01, KEY_RECORD },
-       { 0xfe4e, KEY_POWER },
-};
-
-static struct rc_map_table rc_map_dvico_portable_table[] = {
-       { 0xfc02, KEY_SETUP },       /* Profile */
-       { 0xfc43, KEY_POWER2 },
-       { 0xfc06, KEY_EPG },
-       { 0xfc5a, KEY_BACK },
-       { 0xfc05, KEY_MENU },
-       { 0xfc47, KEY_INFO },
-       { 0xfc01, KEY_TAB },
-       { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
-       { 0xfc49, KEY_VOLUMEUP },
-       { 0xfc09, KEY_VOLUMEDOWN },
-       { 0xfc54, KEY_CHANNELUP },
-       { 0xfc0b, KEY_CHANNELDOWN },
-       { 0xfc16, KEY_CAMERA },
-       { 0xfc40, KEY_TUNER },  /* ATV/DTV */
-       { 0xfc45, KEY_OPEN },
-       { 0xfc19, KEY_1 },
-       { 0xfc18, KEY_2 },
-       { 0xfc1b, KEY_3 },
-       { 0xfc1a, KEY_4 },
-       { 0xfc58, KEY_5 },
-       { 0xfc59, KEY_6 },
-       { 0xfc15, KEY_7 },
-       { 0xfc14, KEY_8 },
-       { 0xfc17, KEY_9 },
-       { 0xfc44, KEY_ANGLE },  /* Aspect */
-       { 0xfc55, KEY_0 },
-       { 0xfc07, KEY_ZOOM },
-       { 0xfc0a, KEY_REWIND },
-       { 0xfc08, KEY_PLAYPAUSE },
-       { 0xfc4b, KEY_FASTFORWARD },
-       { 0xfc5b, KEY_MUTE },
-       { 0xfc04, KEY_STOP },
-       { 0xfc56, KEY_RECORD },
-       { 0xfc57, KEY_POWER },
-       { 0xfc41, KEY_UNKNOWN },    /* INPUT */
-       { 0xfc00, KEY_UNKNOWN },    /* HD */
-};
-
-static struct rc_map_table rc_map_d680_dmb_table[] = {
-       { 0x0038, KEY_UNKNOWN },        /* TV/AV */
-       { 0x080c, KEY_ZOOM },
-       { 0x0800, KEY_0 },
-       { 0x0001, KEY_1 },
-       { 0x0802, KEY_2 },
-       { 0x0003, KEY_3 },
-       { 0x0804, KEY_4 },
-       { 0x0005, KEY_5 },
-       { 0x0806, KEY_6 },
-       { 0x0007, KEY_7 },
-       { 0x0808, KEY_8 },
-       { 0x0009, KEY_9 },
-       { 0x000a, KEY_MUTE },
-       { 0x0829, KEY_BACK },
-       { 0x0012, KEY_CHANNELUP },
-       { 0x0813, KEY_CHANNELDOWN },
-       { 0x002b, KEY_VOLUMEUP },
-       { 0x082c, KEY_VOLUMEDOWN },
-       { 0x0020, KEY_UP },
-       { 0x0821, KEY_DOWN },
-       { 0x0011, KEY_LEFT },
-       { 0x0810, KEY_RIGHT },
-       { 0x000d, KEY_OK },
-       { 0x081f, KEY_RECORD },
-       { 0x0017, KEY_PLAYPAUSE },
-       { 0x0816, KEY_PLAYPAUSE },
-       { 0x000b, KEY_STOP },
-       { 0x0827, KEY_FASTFORWARD },
-       { 0x0026, KEY_REWIND },
-       { 0x081e, KEY_UNKNOWN },    /* Time Shift */
-       { 0x000e, KEY_UNKNOWN },    /* Snapshot */
-       { 0x082d, KEY_UNKNOWN },    /* Mouse Cursor */
-       { 0x000f, KEY_UNKNOWN },    /* Minimize/Maximize */
-       { 0x0814, KEY_UNKNOWN },    /* Shuffle */
-       { 0x0025, KEY_POWER },
-};
-
 static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 {
        static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
@@ -1000,7 +838,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
                return -EIO;
 
        /* try to determine if there is no IR decoder on the I2C bus */
-       for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
+       for (i = 0; adap->dev->props.rc.core.rc_codes && i < 5; i++) {
                msleep(20);
                if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
                        goto no_IR;
@@ -1008,7 +846,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
                        continue;
                if (ircode[2] + ircode[3] != 0xff) {
 no_IR:
-                       adap->dev->props.rc.legacy.rc_map_table = NULL;
+                       adap->dev->props.rc.core.rc_codes = NULL;
                        info("No IR receiver detected on this device.");
                        break;
                }
@@ -1720,11 +1558,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
 
        .i2c_algo         = &cxusb_i2c_algo,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_PORTABLE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .generic_bulk_ctrl_endpoint = 0x01,
@@ -1776,11 +1615,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
 
        .i2c_algo         = &cxusb_i2c_algo,
 
-       .rc.legacy = {
-               .rc_interval      = 150,
-               .rc_map_table     = rc_map_dvico_mce_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
-               .rc_query         = cxusb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_MCE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .generic_bulk_ctrl_endpoint = 0x01,
@@ -1840,11 +1680,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
 
        .i2c_algo         = &cxusb_i2c_algo,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_PORTABLE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .generic_bulk_ctrl_endpoint = 0x01,
@@ -1895,11 +1736,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
 
        .i2c_algo         = &cxusb_i2c_algo,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_PORTABLE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .generic_bulk_ctrl_endpoint = 0x01,
@@ -1949,11 +1791,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_mce_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
-               .rc_query         = cxusb_bluebird2_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_MCE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_bluebird2_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
@@ -2002,11 +1845,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_bluebird2_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_PORTABLE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_bluebird2_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
@@ -2057,11 +1901,12 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_portable_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_portable_table),
-               .rc_query         = cxusb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_PORTABLE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
@@ -2155,11 +2000,12 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_dvico_mce_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_dvico_mce_table),
-               .rc_query         = cxusb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_DVICO_MCE,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
@@ -2208,11 +2054,12 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_d680_dmb_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
-               .rc_query         = cxusb_d680_dmb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_D680_DMB,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_d680_dmb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
@@ -2262,11 +2109,12 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_d680_dmb_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
-               .rc_query         = cxusb_d680_dmb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_D680_DMB,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_d680_dmb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
@@ -2315,11 +2163,12 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .rc.legacy = {
-               .rc_interval      = 100,
-               .rc_map_table     = rc_map_d680_dmb_table,
-               .rc_map_size      = ARRAY_SIZE(rc_map_d680_dmb_table),
-               .rc_query         = cxusb_d680_dmb_rc_query,
+       .rc.core = {
+               .rc_interval    = 100,
+               .rc_codes       = RC_MAP_D680_DMB,
+               .module_name    = KBUILD_MODNAME,
+               .rc_query       = cxusb_d680_dmb_rc_query,
+               .allowed_protos = RC_BIT_UNKNOWN,
        },
 
        .num_device_descs = 1,
index b29d4894c2f1ca914088880785e0157c2cdfcff5..81d7fd4f7776ef629ad0ea93d619ce9bc0c4c653 100644 (file)
@@ -3815,6 +3815,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
        { USB_DEVICE(USB_VID_PCTV,      USB_PID_PCTV_2002E_SE) },
        { USB_DEVICE(USB_VID_PCTV,      USB_PID_DIBCOM_STK8096PVR) },
        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK8096PVR) },
+       { USB_DEVICE(USB_VID_HAMA,      USB_PID_HAMA_DVBT_HYBRID) },
        { 0 }           /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -4379,7 +4380,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        },
                },
 
-               .num_device_descs = 9,
+               .num_device_descs = 10,
                .devices = {
                        {   "Terratec Cinergy HT USB XE",
                                { &dib0700_usb_id_table[27], NULL },
@@ -4417,6 +4418,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { &dib0700_usb_id_table[54], NULL },
                                { NULL },
                        },
+                       {   "Hama DVB=T Hybrid USB Stick",
+                               { &dib0700_usb_id_table[85], NULL },
+                               { NULL },
+                       },
                },
 
                .rc.core = {
index c60fb54f445f582357ca949b3e4f6775e0822e12..2fa2abd3e726317b848974cae66f941257db430c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "dtv5100.h"
index 93e96e04a82a10714b641bd94053d8ad49546c49..1ab1eafd31879551ba25eb74f2088595b92d992e 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifndef _DVB_USB_DTV5100_H_
index f0023dbb72761641112ac7b0bfcba51cf154eda2..ab9866024ec7983d597efd157476820222ad8134 100644 (file)
@@ -35,28 +35,33 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 le
 
 int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
 {
-       struct hexline hx;
+       struct hexline *hx;
        u8 reset;
        int ret,pos=0;
 
+       hx = kmalloc(sizeof(*hx), GFP_KERNEL);
+       if (!hx)
+               return -ENOMEM;
+
        /* stop the CPU */
        reset = 1;
        if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
                err("could not stop the USB controller CPU.");
 
-       while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
-               deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
-               ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
+       while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
+               deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk);
+               ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
 
-               if (ret != hx.len) {
+               if (ret != hx->len) {
                        err("error while transferring firmware (transferred size: %d, block size: %d)",
-                               ret,hx.len);
+                               ret, hx->len);
                        ret = -EINVAL;
                        break;
                }
        }
        if (ret < 0) {
                err("firmware download failed at %d with %d",pos,ret);
+               kfree(hx);
                return ret;
        }
 
@@ -70,6 +75,8 @@ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw
        } else
                ret = -EIO;
 
+       kfree(hx);
+
        return ret;
 }
 EXPORT_SYMBOL(usb_cypress_load_firmware);
index c259f9e43542970d87a32ca2e79806d87d193a8e..059ded59208e8af0275b064efd5c5659130ae228 100644 (file)
@@ -265,7 +265,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
        int err, rc_interval;
        struct rc_dev *dev;
 
-       dev = rc_allocate_device();
+       dev = rc_allocate_device(d->props.rc.core.driver_type);
        if (!dev)
                return -ENOMEM;
 
@@ -273,7 +273,6 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
        dev->map_name = d->props.rc.core.rc_codes;
        dev->change_protocol = d->props.rc.core.change_protocol;
        dev->allowed_protocols = d->props.rc.core.allowed_protos;
-       dev->driver_type = d->props.rc.core.driver_type;
        usb_to_input_id(d->udev, &dev->input_id);
        dev->input_name = "IR-receiver inside an USB DVB receiver";
        dev->input_phys = d->rc_phys;
index 2360e7e32b06db333e6c9de0b617191369c64716..37f062225ed213a00f54ed6dc551971a41c8f5c5 100644 (file)
@@ -161,7 +161,7 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
                        goto out_free;
                }
                if (buflen > 64) {
-                       err("firmare chunk size bigger than 64 bytes.");
+                       err("firmware chunk size bigger than 64 bytes.");
                        goto out_free;
                }
 
@@ -278,7 +278,7 @@ static int gp8psk_fe_reload(void *priv)
        return gp8psk_bcm4500_reload(d);
 }
 
-const struct gp8psk_fe_ops gp8psk_fe_ops = {
+static const struct gp8psk_fe_ops gp8psk_fe_ops = {
        .in = gp8psk_fe_in,
        .out = gp8psk_fe_out,
        .reload = gp8psk_fe_reload,
index 02c3bee6f83bdd789af978578254cc85cfe7c62d..9f7dd1afcb15714db883074824d1fe484556b982 100644 (file)
  * License, or (at your option) any later version.
  *
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
  * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
  * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
@@ -753,7 +749,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = {
                .rc_codes    = RC_MAP_TECHNISAT_USB2,
                .module_name = "technisat-usb2",
                .rc_query    = technisat_usb2_rc_query,
-               .allowed_protos = RC_BIT_ALL,
+               .allowed_protos = RC_BIT_ALL_IR_DECODER,
                .driver_type    = RC_DRIVER_IR_RAW,
        }
 };
index 7969ddb9e2dd2858909734bf39ed03a07aa66811..ffad7f1af1667cd7ef4a4c95c8239cfd18795e9f 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "em28xx.h"
index 23c67494762d4d32643bf78446607b3bc24da9b3..5f90d0899a45f5ed8af5b62c5d3e863fcd4ab191 100644 (file)
@@ -509,6 +509,7 @@ static struct em28xx_reg_seq plex_px_bcud[] = {
 
 /*
  * 2040:0265 Hauppauge WinTV-dualHD DVB
+ * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM
  * reg 0x80/0x84:
  * GPIO_0: Yellow LED tuner 1, 0=on, 1=off
  * GPIO_1: Green LED tuner 1, 0=on, 1=off
@@ -2389,6 +2390,21 @@ struct em28xx_board em28xx_boards[] = {
                .ir_codes      = RC_MAP_HAUPPAUGE,
                .leds          = hauppauge_dualhd_leds,
        },
+       /*
+        * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM).
+        * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157
+        */
+       [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = {
+               .name          = "Hauppauge WinTV-dualHD 01595 ATSC/QAM",
+               .def_i2c_bus   = 1,
+               .i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
+                                EM28XX_I2C_FREQ_400_KHZ,
+               .tuner_type    = TUNER_ABSENT,
+               .tuner_gpio    = hauppauge_dualhd_dvb,
+               .has_dvb       = 1,
+               .ir_codes      = RC_MAP_HAUPPAUGE,
+               .leds          = hauppauge_dualhd_leds,
+       },
 };
 EXPORT_SYMBOL_GPL(em28xx_boards);
 
@@ -2514,6 +2530,8 @@ struct usb_device_id em28xx_id_table[] = {
                        .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
        { USB_DEVICE(0x2040, 0x0265),
                        .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
+       { USB_DEVICE(0x2040, 0x026d),
+                       .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 },
        { USB_DEVICE(0x0438, 0xb002),
                        .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
        { USB_DEVICE(0x2001, 0xf112),
@@ -2945,6 +2963,7 @@ static void em28xx_card_setup(struct em28xx *dev)
        case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
        case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
        case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
+       case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
        {
                struct tveeprom tv;
 
index 75a75dab2e8ebddef2e8de22f09fa52a76c44418..82edd37f0d733ddc263b5be4883ac314c133eaa3 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "lgdt330x.h"
 #include "lgdt3305.h"
+#include "lgdt3306a.h"
 #include "zl10353.h"
 #include "s5h1409.h"
 #include "mt2060.h"
@@ -920,6 +921,17 @@ static struct tda18271_config pinnacle_80e_dvb_config = {
        .role    = TDA18271_MASTER,
 };
 
+static struct lgdt3306a_config hauppauge_01595_lgdt3306a_config = {
+       .qam_if_khz         = 4000,
+       .vsb_if_khz         = 3250,
+       .spectral_inversion = 0,
+       .deny_i2c_rptr      = 0,
+       .mpeg_mode          = LGDT3306A_MPEG_SERIAL,
+       .tpclk_edge         = LGDT3306A_TPCLK_RISING_EDGE,
+       .tpvalid_polarity   = LGDT3306A_TP_VALID_HIGH,
+       .xtalMHz            = 25,
+};
+
 /* ------------------------------------------------------------------ */
 
 static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
@@ -1950,6 +1962,68 @@ static int em28xx_dvb_init(struct em28xx *dev)
 
                }
                break;
+       case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
+               {
+                       struct i2c_adapter *adapter;
+                       struct i2c_client *client;
+                       struct i2c_board_info info = {};
+                       struct lgdt3306a_config lgdt3306a_config;
+                       struct si2157_config si2157_config = {};
+
+                       /* attach demod */
+                       lgdt3306a_config = hauppauge_01595_lgdt3306a_config;
+                       lgdt3306a_config.fe = &dvb->fe[0];
+                       lgdt3306a_config.i2c_adapter = &adapter;
+                       strlcpy(info.type, "lgdt3306a", sizeof(info.type));
+                       info.addr = 0x59;
+                       info.platform_data = &lgdt3306a_config;
+                       request_module(info.type);
+                       client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus],
+                                       &info);
+                       if (client == NULL || client->dev.driver == NULL) {
+                               result = -ENODEV;
+                               goto out_free;
+                       }
+
+                       if (!try_module_get(client->dev.driver->owner)) {
+                               i2c_unregister_device(client);
+                               result = -ENODEV;
+                               goto out_free;
+                       }
+
+                       dvb->i2c_client_demod = client;
+
+                       /* attach tuner */
+                       si2157_config.fe = dvb->fe[0];
+                       si2157_config.if_port = 1;
+                       si2157_config.inversion = 1;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+                       si2157_config.mdev = dev->media_dev;
+#endif
+                       memset(&info, 0, sizeof(struct i2c_board_info));
+                       strlcpy(info.type, "si2157", sizeof(info.type));
+                       info.addr = 0x60;
+                       info.platform_data = &si2157_config;
+                       request_module(info.type);
+
+                       client = i2c_new_device(adapter, &info);
+                       if (client == NULL || client->dev.driver == NULL) {
+                               module_put(dvb->i2c_client_demod->dev.driver->owner);
+                               i2c_unregister_device(dvb->i2c_client_demod);
+                               result = -ENODEV;
+                               goto out_free;
+                       }
+                       if (!try_module_get(client->dev.driver->owner)) {
+                               i2c_unregister_device(client);
+                               module_put(dvb->i2c_client_demod->dev.driver->owner);
+                               i2c_unregister_device(dvb->i2c_client_demod);
+                               result = -ENODEV;
+                               goto out_free;
+                       }
+
+                       dvb->i2c_client_tuner = client;
+               }
+               break;
        default:
                dev_err(&dev->intf->dev,
                        "The frontend of your DVB/ATSC card isn't supported yet\n");
index 782ce095c8c511a2c99805fe042cef1b2f911697..eba75736e65406a39c547df442ebbb5835836cf6 100644 (file)
@@ -259,18 +259,21 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
                break;
 
        case RC_BIT_NEC:
-               poll_result->protocol = RC_TYPE_RC5;
                poll_result->scancode = msg[1] << 8 | msg[2];
-               if ((msg[3] ^ msg[4]) != 0xff)          /* 32 bits NEC */
+               if ((msg[3] ^ msg[4]) != 0xff) {        /* 32 bits NEC */
+                       poll_result->protocol = RC_TYPE_NEC32;
                        poll_result->scancode = RC_SCANCODE_NEC32((msg[1] << 24) |
                                                                  (msg[2] << 16) |
                                                                  (msg[3] << 8)  |
                                                                  (msg[4]));
-               else if ((msg[1] ^ msg[2]) != 0xff)     /* 24 bits NEC */
+               } else if ((msg[1] ^ msg[2]) != 0xff) { /* 24 bits NEC */
+                       poll_result->protocol = RC_TYPE_NECX;
                        poll_result->scancode = RC_SCANCODE_NECX(msg[1] << 8 |
                                                                 msg[2], msg[3]);
-               else                                    /* Normal NEC */
+               } else {                                /* Normal NEC */
+                       poll_result->protocol = RC_TYPE_NEC;
                        poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[3]);
+               }
                break;
 
        case RC_BIT_RC6_0:
@@ -719,7 +722,7 @@ static int em28xx_ir_init(struct em28xx *dev)
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
        if (!ir)
                return -ENOMEM;
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!rc)
                goto error;
 
@@ -777,7 +780,7 @@ static int em28xx_ir_init(struct em28xx *dev)
                case CHIP_ID_EM28178:
                        ir->get_key = em2874_polling_getkey;
                        rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC |
-                                            RC_BIT_RC6_0;
+                               RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_0;
                        break;
                default:
                        err = -ENODEV;
index ca59e2d4fccfa4d1729d94f6f9fd7ac58fc0bded..e9f379959fa5e1bfe570973fa464932792a47776 100644 (file)
 #define EM2884_BOARD_ELGATO_EYETV_HYBRID_2008     97
 #define EM28178_BOARD_PLEX_PX_BCUD                98
 #define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB  99
+#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 100
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
index 0e9ee8b50bb7f2ed5839b27c5614a5f1b09423ec..427db745e027436b97ec4a878a5442499809a4be 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "gspca.h"
 
index 5fa67b78ad49b1a1da48bb02144b011f6ef34443..60a728203b3bedfeaff36526a9d34e9d6b2483b6 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 2e15c80d6e3d11b953d210b553cbc6878110427f..bdcdf7999c5644bfa6abe14167c010eff702eee8 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 52b88e9e656b5f87e3573a7a0afb7e49da8cfb95..23d3285f182a5997c498640ae092c90d4ce7596a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 26c9ee1f1045a197ca7624b5dd007396964c3c68..8f84292936e98ce592277fd9f3b72d730669b106 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index ae9a55d7bbbb617aaf94c91477dca6513d8a8a91..7bb469aa61a7363d52ffd18671b784168fa9baec 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index fa2cbb981905a4908d19dd793a1138bc3bcf7ab4..16bc1dde2c8cd5ed341c8356dc0e48598c4dd43d 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 19736e237b37d6a14e50141c8d24104141783f16..34e043b7d1bc38ec6d7f3a10676c841f1d98e4e7 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index b12ecb72df4cf4e0e0980ee95c8704805c886c42..17c7a953564ce1dd0e29087730d49320b3883a28 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define MODULE_NAME "jl2005bcd"
index 0aa2b671faa417120217c9ae960e79013171f213..d5ad7c96d0398ad01f5cdbbc240511d05b449e15 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 /*
index 3cb30a37d6ac90818521dc646b48b9f9bfcabb95..2f28b38c5479c3c4d414a374ae47f449c221eec1 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 40aaaa9c5f30ebd0990d5df3fecebfed4faa123a..71f273377f833b3d6fce5a7770a71bcf1c647eac 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 779a8785f421bbcb67c62840c8a67478ee0a44a2..25df55e840c73026bdffdb76e3fe004942c855b3 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 6dfb364094ec769937515d7d2d086d4a135a5865..8b0e32a649acffb9f8b60ec96163a0994e6a6fc0 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 599f755e75b86513c28228468bc19e15278a414a..5d2d0bcb038d3e86eaab89dec368466228f140f9 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 4dbca54cf2a83de08a743f2c8969ff465b2632ed..f4c41f043cda4da995d1ee52708fc1ffaa57112f 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 9266a5c9abc5db0197b7305530e06dfbbc9dd541..32849ff86b09dfa6b793d94d4435edab776a3f28 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 47085cf2d72365b5fdac410d5394bbdb8a7407b0..b2a92e518118ff055bdfb086a40a06af91fe2022 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 51e11248bbb837a60df723f8310f80f4f53a0fcd..01c185d367e5d413d1c957a79d9c3f4bbb7ca6bb 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index be07a24c4518f10cbb97aee99eb9120139ed13cc..595535e143e647c8b5b232b31a8d20ffc9c112b7 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /*
index 25f86b1e74a80b9c9d6f4d856b8156a216d47102..8bac2d9326bf8f9beee707087d15b4953d9e72d0 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /* Some documentation about various registers as determined by trial and error.
index fbc5e226c3e4855436f0ba9781f8f21e91f2420d..4047bcb6c2b552a2d270361cfb6ee855da751ba4 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 /* We calculate the autogain at the end of the transfer of a frame, at this
index 5102cea504710c5c2aeeba1b0101159f35b0b459..477da0664b7daf1a77537c6314c22bcb7778550d 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 96d8ebf3cf595622d2547344b078586b63c3a19e..7cc0728c1410fce5e375e26c9c5f59d66091be74 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define SE401_REQ_GET_CAMERA_DESCRIPTOR                0x06
index 4f2050a5ec941a036119eba6ad7c6730f6ac713e..5d32dd359d84d49a1ebf63a8f37e8c4d838320d8 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index f85bc106bc52c7566ff9f7153303f26398a6f960..85761aa7c8b249550476efce59246f695aac04f8 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 static const unsigned char sn9c2028_sof_marker[] = {
index e7430b06526ae25030e0f960bbbcc021435448c6..c605f78d618673614eb54f7224398c499f960ded 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 6696b2ec34e969dd631a91ca2dbe6b3ac5fac1fd..5f3f2979540a64b7a868dd2573db3c329a6e08da 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /* Some documentation on known sonixb registers:
index d49d76ec142126c84868dcfd348aaf835ecaaee8..5eeaf16ac5e82a2793d7ca8800d3a5bb28e175da 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index f38fd8949609fd917cee8568a4cba9bdb5e83cb4..327ec901abe149d8be6a4bdf267a5aa53a9e7728 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index f011a309dd65f4d0776e82cb55f4e6c3fb4ccf58..da2d9027914c61a9d33c8cd97f20277cdc9f3a35 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index d92fd17d6701423fa254e98d098b76f53f0d353a..ae5a80987553a2567f31890c3f5c3bbbb4045e32 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 232b330d2dd3717c493e1b9aebd218fff9ad9f58..1553cc766c0422fd97040bdbb1039bc6bf394109 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index ee84863d27d473a752e532f6c507cd5a641d8f93..843c93f5acf3acf8a8a4c864542615337c5730eb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define MODULE_NAME "spca506"
index 75f2beb2ea5aa9d9d341e40342a7cca8aa7b3c26..1e0ba6b24e2180ddf576d2ec11918904fd1845a9 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 403d71cd65d93f32e82982cfdff5f89208c3de1c..4ff704cf9ed6cc2c21f36a384fd2fb6da980a969 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 9424c33f0ddb839023b3bb384374718e0b74e417..f1da34a10ce88af679128cf15dc5f7ea7ed6b413 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /*
index 6c45dcc44eb01fd37fe21a178d20301dfc0e673e..8b4e4948a0cb6d25f1128ede0cd386176d239612 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /*
index e274cf19a3ea22a1448f340f7a779c5a1274d528..aa9a9411b801818f222b668410084a89192981d5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index d324d001e1143890fb5ec171f0fad0f608771c06..daf45db6c4047723765279769860a787aa3891ff 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 48234c9a8b6c3e4b4b927eb654ddb0009aa3d8ba..3ab5ec2ca4bd725f95479c9ff4f1e48880dc09a5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index e1dd92ab49bbf60fcad0ec25d3f8f4833f346497..bd144012f73a9f89a64ee44e574f4f9c8de251d3 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #define STK1135_REG_GCTRL      0x000   /* GPIO control */
index 7f94ec74282e3ea42b0c423130419b038a5e3edd..29a65d05cbb22c416ab09397e2ce8b08315bf410 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index fef7a784b8799eae88e99dad70b8bacf2c3b84c6..e72c3e1ab9ff41f0a39d685d4615a8bd3cb06914 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 34957a4ec1501ec483dcb10167cb2914ea63e956..f9d74e4d7cf95153943c4a94ea683bb7ed881f3a 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 2220b70d47e6663d6200eec0768c4894fe833ef2..28252f6c4afd837435ad153f2ae6fddf17f225c7 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 1ba9158d0102196356ff1e069f166aa4b997f4c9..d2da0de05236e54579ef7411a81bb3e00c17e9e6 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 8d785edcccf2ef040906840f55ea3173e555ecbf..e1ce96e9405f5ed89a23c5c0a59a7b5290b5cd93 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 5071e5353fd339be30bfd914601e0dacd6b63c15..33572d8bb3689a941574d1129c415d200923a5ac 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 3a498c2495c606d8c35d74537addc1f3bd1aadf6..747d07c877fe31d0fe6bc3b8235a01fed821bb00 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 515a9e121653b28bcaf68b0300d955fdcdd7e818..4b76070515b5e8315aed3e11493962e59e1e0e05 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 8f20fbf30f3331d5720249f30794708e57e8de99..87324a69a0bee53da32d733152591ac921da0116 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef STV06XX_ST6422_H_
index f86cec091bf40f0e5700403152221a945d955d14..d265e6b0099477c6251bc03a17e4a42fc4223be1 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
@@ -120,9 +116,6 @@ static int vv6410_init(struct sd *sd)
        for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++)
                stv06xx_write_bridge(sd, stv_bridge_init[i].addr, stv_bridge_init[i].data);
 
-       if (err < 0)
-               return err;
-
        err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
                                         ARRAY_SIZE(vv6410_sensor_init));
        return (err < 0) ? err : 0;
index 53e67b40ca05f23c0d6492ee95aee1ae189676fe..e8598893791efd4915b7d2dea69f7d082d6b737b 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
index 38dc9e7aa313fc028c80f30a0ca68d684937a66f..8c2785aea3cd046a5d60fd824d21579290f3626b 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index bb52fc1fe598c66982a914cbb351fcb46b24d743..42667710af92279dba54b777b9aa4827237f9340 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  *Notes: * t613  + tas5130A
  *     * Focus to light do not balance well as in win.
  *       Quality in win is not good, but its kinda better.
index d497ba38af0da06149ebb95ec91526c21e6a4604..bc2720e9cc4f88065289e27b5b577d7239e92160 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 #define MODULE_NAME "tv8532"
 
index b4efb2fb36fa3b875e96e5a668d2f349289e8bad..b935febf7146856c2bf3ef2f9d89d4c2b6558e9f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 8860510c2f9c73c7afb00d52cadf5edb934bcf45..554b90ef2200bf928686e83bec938d8d4f6588a1 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 896f1b2b91793907a62d751f178c30001da683bc..728d2322c433ad25488737f0ecfbe6f2daee8725 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  */
 
 /* Note this is not a stand alone driver, it gets included in ov519.c, this
index d5ed9d36ce25855cba5b745b1c605fa4b515bc69..b600ea6460d3bc5012435bbb007b5e261e837867 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index d5d8c7e81762310272caad6b60fe0dc5f0d1dd56..e2d486bd8c2806ae82c59f8d4fa92fdb6d33320d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 3bac50a248d479c7aefb5d6891dca3cdabcff24b..356afa250cd6e4a3808e05db37143b89550065db 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "pvrusb2-audio.h"
index 27cefb5cb170ebcdaf80dc107269bd995d8ea9d1..4f3898473165f3ec4a0e775cd0358187680682c3 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_AUDIO_H
index c45f30715dcd019217d9ae51a22f1f8874c96d10..d9e8481e9e286e5f2d6dc7584155e995d7541cc2 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "pvrusb2-context.h"
index 1c1d442d9ea3bba70ea48f451775fa8086895b1f..13e00c529611043a68f925f4faf8ff0a423aee86 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_CONTEXT_H
 #define __PVRUSB2_CONTEXT_H
index 7f29a0464f36a0062d74998bd63d3a3cf292b393..679f3ff3b0a5c073ff8ab589d59331ffdd92653d 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 /*
index 86c17bee56f947227b56feb272a20c137f14a020..90dfb8b3f3e515d72bbbd2b0e9c63f8ae2dfa3e4 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_CS53L32A_H
index 958db170a04832e28361e40dfb0a9d82f9c72f83..5f4ba84e5557788727ba2ca65de50258db982237 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "pvrusb2-ctrl.h"
index c175571868a38a1abf67a6b42b19828ed54ac357..4b9152e36fe4760c85749359dbd5b25d9418fffa 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_CTRL_H
 #define __PVRUSB2_CTRL_H
index 30eef97ef2efa9dc8bff15b0ba7926c60ea48992..242b213b7599abab0acbad522cb46bef6abea4fb 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 /*
index 2eed7b7ee25ec4fcf48b86e6764a7712fb5a4868..dfddc88750d9401f9132f65de4f35e85dbab6194 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_CX2584X_V4L_H
index 4ef2ebcd97a5fd994e1b28765ded57dbd0016846..5cd16292e2fa1ae2de78c6586d24a6c5678f1122 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_DEBUG_H
 #define __PVRUSB2_DEBUG_H
index 58ec706ebdb3f807528d69aa0b3a3db00b41097c..d3f3bd96885f9637cf0f1e27c66ec3c0ee64fead 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/string.h>
index a8dfc55f136f28dd7488661ee4f367b5fe1b7daa..fcaaa8dd68b87cdc738cb71966519801764fd1de 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_DEBUGIFC_H
 #define __PVRUSB2_DEBUGIFC_H
index 06c4c3dabcde35cc487637211516dd812e5cdca2..51b3312eaea13421097053e7955e2c1ac5128464 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 /*
index 5aeefb6a991ff5d441df7047561029a5a3daa345..c1e7d4822cd1d3c398390bf10060be236f17d91c 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_DEVATTR_H
 #define __PVRUSB2_DEVATTR_H
index 8c95793433e79b8d93470e4b9b757dc7ef656dd6..56c750535ee7e6f11ad455800a29d6be6ed28bdb 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/kthread.h>
index 276b17fb9aadecf6fae0cd4cb8c5676d3f69452b..4af2fb5c85d50d2947692fa499af083633f5b6f5 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/slab.h>
index f1e33c807f4648942d97e6992b0eb6ff38e81fcf..1d81cac30f3d7828f44c2f5d6444514e621f2bf8 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_EEPROM_H
index f0483621d2a3aedfc4aca1257579a7083e9bdf90..ca637074fa1ff3e74e7491373998a4b679a5ce8a 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/device.h>   // for linux/firmware.h
index a2bfb48f1ecdfb49b033e2856e6b1ec70a2b9edd..10d7f0b48264ba465419f69f6645b0b6e40396dd 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_ENCODER_H
index 06a15a68bcfdc13ca4ee5d005f0740bf80788950..0a01de4e54db3fa69196eccd853a976981b64439 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef _PVRUSB2_FX2_CMD_H_
index 23473a21319cd4275a663b77e5fef0850602feb2..7a824196d5fa000f0510d23bb612d92f5f8fa462 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_HDW_INTERNAL_H
 #define __PVRUSB2_HDW_INTERNAL_H
index e3ed8ffee9f7a0a5b94903bee0ce4c84451ed56a..ad5b25b896990eab69616ad6e454bb2bd2d9601c 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/errno.h>
index a82a00dd732930694dd6815d25d59bed6ffb1546..25648add77e58c841ebf03672433cfb2e35da34d 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_HDW_H
 #define __PVRUSB2_HDW_H
index cc63e5f4c26c452c214c4f116cf8432bb5fd57fc..f727b54a53c6d94a34476e9d22fca1de544b3ca2 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/i2c.h>
index a10a3e8e9345760f82e0ba0b4ed9aa2bf161e81c..1c44dee7fd69b434aa17a4be3ce9dc2bb03bce58 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_I2C_CORE_H
 #define __PVRUSB2_I2C_CORE_H
index e3103ecd4828c2f89d1bfeedc3067c91d4b7cc23..6d153fc23ec2e14b98d5e1bbb6f88ff94913f178 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "pvrusb2-io.h"
@@ -37,13 +33,13 @@ static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state);
        if ((bp)->signature != BUFFER_SIG) { \
                pvr2_trace(PVR2_TRACE_ERROR_LEGS, \
                "Buffer %p is bad at %s:%d", \
-               (bp),__FILE__,__LINE__); \
-               pvr2_buffer_describe(bp,"BadSig"); \
+               (bp), __FILE__, __LINE__); \
+               pvr2_buffer_describe(bp, "BadSig"); \
                BUG(); \
        } \
 } while (0)
 #else
-#define BUFFER_CHECK(bp) do {} while(0)
+#define BUFFER_CHECK(bp) do {} while (0)
 #endif
 
 struct pvr2_stream {
@@ -110,7 +106,7 @@ static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st)
 }
 
 #ifdef SANITY_CHECK_BUFFERS
-static void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg)
+static void pvr2_buffer_describe(struct pvr2_buffer *bp, const char *msg)
 {
        pvr2_trace(PVR2_TRACE_INFO,
                   "buffer%s%s %p state=%s id=%d status=%d stream=%p purb=%p sig=0x%x",
@@ -156,7 +152,7 @@ static void pvr2_buffer_remove(struct pvr2_buffer *bp)
        (*bcnt) -= ccnt;
        pvr2_trace(PVR2_TRACE_BUF_FLOW,
                   "/*---TRACE_FLOW---*/ bufferPool     %8s dec cap=%07d cnt=%02d",
-                  pvr2_buffer_state_decode(bp->state),*bcnt,*cnt);
+                  pvr2_buffer_state_decode(bp->state), *bcnt, *cnt);
        bp->state = pvr2_buffer_state_none;
 }
 
@@ -171,9 +167,9 @@ static void pvr2_buffer_set_none(struct pvr2_buffer *bp)
                   bp,
                   pvr2_buffer_state_decode(bp->state),
                   pvr2_buffer_state_decode(pvr2_buffer_state_none));
-       spin_lock_irqsave(&sp->list_lock,irq_flags);
+       spin_lock_irqsave(&sp->list_lock, irq_flags);
        pvr2_buffer_remove(bp);
-       spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+       spin_unlock_irqrestore(&sp->list_lock, irq_flags);
 }
 
 static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
@@ -188,18 +184,18 @@ static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
                   bp,
                   pvr2_buffer_state_decode(bp->state),
                   pvr2_buffer_state_decode(pvr2_buffer_state_ready));
-       spin_lock_irqsave(&sp->list_lock,irq_flags);
+       spin_lock_irqsave(&sp->list_lock, irq_flags);
        fl = (sp->r_count == 0);
        pvr2_buffer_remove(bp);
-       list_add_tail(&bp->list_overhead,&sp->ready_list);
+       list_add_tail(&bp->list_overhead, &sp->ready_list);
        bp->state = pvr2_buffer_state_ready;
        (sp->r_count)++;
        sp->r_bcount += bp->used_count;
        pvr2_trace(PVR2_TRACE_BUF_FLOW,
                   "/*---TRACE_FLOW---*/ bufferPool     %8s inc cap=%07d cnt=%02d",
                   pvr2_buffer_state_decode(bp->state),
-                  sp->r_bcount,sp->r_count);
-       spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+                  sp->r_bcount, sp->r_count);
+       spin_unlock_irqrestore(&sp->list_lock, irq_flags);
        return fl;
 }
 
@@ -214,17 +210,17 @@ static void pvr2_buffer_set_idle(struct pvr2_buffer *bp)
                   bp,
                   pvr2_buffer_state_decode(bp->state),
                   pvr2_buffer_state_decode(pvr2_buffer_state_idle));
-       spin_lock_irqsave(&sp->list_lock,irq_flags);
+       spin_lock_irqsave(&sp->list_lock, irq_flags);
        pvr2_buffer_remove(bp);
-       list_add_tail(&bp->list_overhead,&sp->idle_list);
+       list_add_tail(&bp->list_overhead, &sp->idle_list);
        bp->state = pvr2_buffer_state_idle;
        (sp->i_count)++;
        sp->i_bcount += bp->max_count;
        pvr2_trace(PVR2_TRACE_BUF_FLOW,
                   "/*---TRACE_FLOW---*/ bufferPool     %8s inc cap=%07d cnt=%02d",
                   pvr2_buffer_state_decode(bp->state),
-                  sp->i_bcount,sp->i_count);
-       spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+                  sp->i_bcount, sp->i_count);
+       spin_unlock_irqrestore(&sp->list_lock, irq_flags);
 }
 
 static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
@@ -238,17 +234,17 @@ static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
                   bp,
                   pvr2_buffer_state_decode(bp->state),
                   pvr2_buffer_state_decode(pvr2_buffer_state_queued));
-       spin_lock_irqsave(&sp->list_lock,irq_flags);
+       spin_lock_irqsave(&sp->list_lock, irq_flags);
        pvr2_buffer_remove(bp);
-       list_add_tail(&bp->list_overhead,&sp->queued_list);
+       list_add_tail(&bp->list_overhead, &sp->queued_list);
        bp->state = pvr2_buffer_state_queued;
        (sp->q_count)++;
        sp->q_bcount += bp->max_count;
        pvr2_trace(PVR2_TRACE_BUF_FLOW,
                   "/*---TRACE_FLOW---*/ bufferPool     %8s inc cap=%07d cnt=%02d",
                   pvr2_buffer_state_decode(bp->state),
-                  sp->q_bcount,sp->q_count);
-       spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+                  sp->q_bcount, sp->q_count);
+       spin_unlock_irqrestore(&sp->list_lock, irq_flags);
 }
 
 static void pvr2_buffer_wipe(struct pvr2_buffer *bp)
@@ -262,18 +258,18 @@ static int pvr2_buffer_init(struct pvr2_buffer *bp,
                            struct pvr2_stream *sp,
                            unsigned int id)
 {
-       memset(bp,0,sizeof(*bp));
+       memset(bp, 0, sizeof(*bp));
        bp->signature = BUFFER_SIG;
        bp->id = id;
        pvr2_trace(PVR2_TRACE_BUF_POOL,
-                  "/*---TRACE_FLOW---*/ bufferInit     %p stream=%p",bp,sp);
+                  "/*---TRACE_FLOW---*/ bufferInit     %p stream=%p", bp, sp);
        bp->stream = sp;
        bp->state = pvr2_buffer_state_none;
        INIT_LIST_HEAD(&bp->list_overhead);
-       bp->purb = usb_alloc_urb(0,GFP_KERNEL);
+       bp->purb = usb_alloc_urb(0, GFP_KERNEL);
        if (! bp->purb) return -ENOMEM;
 #ifdef SANITY_CHECK_BUFFERS
-       pvr2_buffer_describe(bp,"create");
+       pvr2_buffer_describe(bp, "create");
 #endif
        return 0;
 }
@@ -281,7 +277,7 @@ static int pvr2_buffer_init(struct pvr2_buffer *bp,
 static void pvr2_buffer_done(struct pvr2_buffer *bp)
 {
 #ifdef SANITY_CHECK_BUFFERS
-       pvr2_buffer_describe(bp,"delete");
+       pvr2_buffer_describe(bp, "delete");
 #endif
        pvr2_buffer_wipe(bp);
        pvr2_buffer_set_none(bp);
@@ -292,7 +288,7 @@ static void pvr2_buffer_done(struct pvr2_buffer *bp)
                   bp);
 }
 
-static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
+static int pvr2_stream_buffer_count(struct pvr2_stream *sp, unsigned int cnt)
 {
        int ret;
        unsigned int scnt;
@@ -312,10 +308,11 @@ static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
        if (cnt > sp->buffer_total_count) {
                if (scnt > sp->buffer_slot_count) {
                        struct pvr2_buffer **nb;
-                       nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
+
+                       nb = kmalloc_array(scnt, sizeof(*nb), GFP_KERNEL);
                        if (!nb) return -ENOMEM;
                        if (sp->buffer_slot_count) {
-                               memcpy(nb,sp->buffers,
+                               memcpy(nb, sp->buffers,
                                       sp->buffer_slot_count * sizeof(*nb));
                                kfree(sp->buffers);
                        }
@@ -324,9 +321,9 @@ static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
                }
                while (sp->buffer_total_count < cnt) {
                        struct pvr2_buffer *bp;
-                       bp = kmalloc(sizeof(*bp),GFP_KERNEL);
+                       bp = kmalloc(sizeof(*bp), GFP_KERNEL);
                        if (!bp) return -ENOMEM;
-                       ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count);
+                       ret = pvr2_buffer_init(bp, sp, sp->buffer_total_count);
                        if (ret) {
                                kfree(bp);
                                return -ENOMEM;
@@ -369,10 +366,10 @@ static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
 
        pvr2_trace(PVR2_TRACE_BUF_POOL,
                   "/*---TRACE_FLOW---*/ poolCheck      stream=%p cur=%d tgt=%d",
-                  sp,sp->buffer_total_count,sp->buffer_target_count);
+                  sp, sp->buffer_total_count, sp->buffer_target_count);
 
        if (sp->buffer_total_count < sp->buffer_target_count) {
-               return pvr2_stream_buffer_count(sp,sp->buffer_target_count);
+               return pvr2_stream_buffer_count(sp, sp->buffer_target_count);
        }
 
        cnt = 0;
@@ -382,7 +379,7 @@ static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
                cnt++;
        }
        if (cnt) {
-               pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt);
+               pvr2_stream_buffer_count(sp, sp->buffer_total_count - cnt);
        }
 
        return 0;
@@ -393,7 +390,7 @@ static void pvr2_stream_internal_flush(struct pvr2_stream *sp)
        struct list_head *lp;
        struct pvr2_buffer *bp1;
        while ((lp = sp->queued_list.next) != &sp->queued_list) {
-               bp1 = list_entry(lp,struct pvr2_buffer,list_overhead);
+               bp1 = list_entry(lp, struct pvr2_buffer, list_overhead);
                pvr2_buffer_wipe(bp1);
                /* At this point, we should be guaranteed that no
                   completion callback may happen on this buffer.  But it's
@@ -421,7 +418,7 @@ static void pvr2_stream_done(struct pvr2_stream *sp)
 {
        mutex_lock(&sp->mutex); do {
                pvr2_stream_internal_flush(sp);
-               pvr2_stream_buffer_count(sp,0);
+               pvr2_stream_buffer_count(sp, 0);
        } while (0); mutex_unlock(&sp->mutex);
 }
 
@@ -436,8 +433,8 @@ static void buffer_complete(struct urb *urb)
        bp->status = 0;
        pvr2_trace(PVR2_TRACE_BUF_FLOW,
                   "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d",
-                  bp,urb->status,urb->actual_length);
-       spin_lock_irqsave(&sp->list_lock,irq_flags);
+                  bp, urb->status, urb->actual_length);
+       spin_lock_irqsave(&sp->list_lock, irq_flags);
        if ((!(urb->status)) ||
            (urb->status == -ENOENT) ||
            (urb->status == -ECONNRESET) ||
@@ -458,12 +455,12 @@ static void buffer_complete(struct urb *urb)
                (sp->buffers_failed)++;
                pvr2_trace(PVR2_TRACE_TOLERANCE,
                           "stream %p ignoring error %d - fail count increased to %u",
-                          sp,urb->status,sp->fail_count);
+                          sp, urb->status, sp->fail_count);
        } else {
                (sp->buffers_failed)++;
                bp->status = urb->status;
        }
-       spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+       spin_unlock_irqrestore(&sp->list_lock, irq_flags);
        pvr2_buffer_set_ready(bp);
        if (sp->callback_func) {
                sp->callback_func(sp->callback_data);
@@ -473,9 +470,9 @@ static void buffer_complete(struct urb *urb)
 struct pvr2_stream *pvr2_stream_create(void)
 {
        struct pvr2_stream *sp;
-       sp = kzalloc(sizeof(*sp),GFP_KERNEL);
+       sp = kzalloc(sizeof(*sp), GFP_KERNEL);
        if (!sp) return sp;
-       pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp);
+       pvr2_trace(PVR2_TRACE_INIT, "pvr2_stream_create: sp=%p", sp);
        pvr2_stream_init(sp);
        return sp;
 }
@@ -483,7 +480,7 @@ struct pvr2_stream *pvr2_stream_create(void)
 void pvr2_stream_destroy(struct pvr2_stream *sp)
 {
        if (!sp) return;
-       pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp);
+       pvr2_trace(PVR2_TRACE_INIT, "pvr2_stream_destroy: sp=%p", sp);
        pvr2_stream_done(sp);
        kfree(sp);
 }
@@ -498,7 +495,7 @@ void pvr2_stream_setup(struct pvr2_stream *sp,
                sp->dev = dev;
                sp->endpoint = endpoint;
                sp->fail_tolerance = tolerance;
-       } while(0); mutex_unlock(&sp->mutex);
+       } while (0); mutex_unlock(&sp->mutex);
 }
 
 void pvr2_stream_set_callback(struct pvr2_stream *sp,
@@ -508,11 +505,11 @@ void pvr2_stream_set_callback(struct pvr2_stream *sp,
        unsigned long irq_flags;
        mutex_lock(&sp->mutex);
        do {
-               spin_lock_irqsave(&sp->list_lock,irq_flags);
+               spin_lock_irqsave(&sp->list_lock, irq_flags);
                sp->callback_data = data;
                sp->callback_func = func;
-               spin_unlock_irqrestore(&sp->list_lock,irq_flags);
-       } while(0);
+               spin_unlock_irqrestore(&sp->list_lock, irq_flags);
+       } while (0);
        mutex_unlock(&sp->mutex);
 }
 
@@ -521,7 +518,7 @@ void pvr2_stream_get_stats(struct pvr2_stream *sp,
                           int zero_counts)
 {
        unsigned long irq_flags;
-       spin_lock_irqsave(&sp->list_lock,irq_flags);
+       spin_lock_irqsave(&sp->list_lock, irq_flags);
        if (stats) {
                stats->buffers_in_queue = sp->q_count;
                stats->buffers_in_idle = sp->i_count;
@@ -535,7 +532,7 @@ void pvr2_stream_get_stats(struct pvr2_stream *sp,
                sp->buffers_failed = 0;
                sp->bytes_processed = 0;
        }
-       spin_unlock_irqrestore(&sp->list_lock,irq_flags);
+       spin_unlock_irqrestore(&sp->list_lock, irq_flags);
 }
 
 /* Query / set the nominal buffer count */
@@ -544,7 +541,7 @@ int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
        return sp->buffer_target_count;
 }
 
-int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
+int pvr2_stream_set_buffer_count(struct pvr2_stream *sp, unsigned int cnt)
 {
        int ret;
        if (sp->buffer_target_count == cnt) return 0;
@@ -552,7 +549,7 @@ int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
        do {
                sp->buffer_target_count = cnt;
                ret = pvr2_stream_achieve_buffer_count(sp);
-       } while(0);
+       } while (0);
        mutex_unlock(&sp->mutex);
        return ret;
 }
@@ -561,17 +558,17 @@ struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp)
 {
        struct list_head *lp = sp->idle_list.next;
        if (lp == &sp->idle_list) return NULL;
-       return list_entry(lp,struct pvr2_buffer,list_overhead);
+       return list_entry(lp, struct pvr2_buffer, list_overhead);
 }
 
 struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp)
 {
        struct list_head *lp = sp->ready_list.next;
        if (lp == &sp->ready_list) return NULL;
-       return list_entry(lp,struct pvr2_buffer,list_overhead);
+       return list_entry(lp, struct pvr2_buffer, list_overhead);
 }
 
-struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id)
+struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp, int id)
 {
        if (id < 0) return NULL;
        if (id >= sp->buffer_total_count) return NULL;
@@ -595,7 +592,7 @@ void pvr2_stream_kill(struct pvr2_stream *sp)
                if (sp->buffer_total_count != sp->buffer_target_count) {
                        pvr2_stream_achieve_buffer_count(sp);
                }
-       } while(0);
+       } while (0);
        mutex_unlock(&sp->mutex);
 }
 
@@ -629,18 +626,18 @@ int pvr2_buffer_queue(struct pvr2_buffer *bp)
                usb_fill_bulk_urb(bp->purb,      // struct urb *urb
                                  sp->dev,       // struct usb_device *dev
                                  // endpoint (below)
-                                 usb_rcvbulkpipe(sp->dev,sp->endpoint),
+                                 usb_rcvbulkpipe(sp->dev, sp->endpoint),
                                  bp->ptr,       // void *transfer_buffer
                                  bp->max_count, // int buffer_length
                                  buffer_complete,
                                  bp);
-               usb_submit_urb(bp->purb,GFP_KERNEL);
-       } while(0);
+               usb_submit_urb(bp->purb, GFP_KERNEL);
+       } while (0);
        mutex_unlock(&sp->mutex);
        return ret;
 }
 
-int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
+int pvr2_buffer_set_buffer(struct pvr2_buffer *bp, void *ptr, unsigned int cnt)
 {
        int ret = 0;
        unsigned long irq_flags;
@@ -649,7 +646,7 @@ int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
        sp = bp->stream;
        mutex_lock(&sp->mutex);
        do {
-               spin_lock_irqsave(&sp->list_lock,irq_flags);
+               spin_lock_irqsave(&sp->list_lock, irq_flags);
                if (bp->state != pvr2_buffer_state_idle) {
                        ret = -EPERM;
                } else {
@@ -661,10 +658,10 @@ int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
                                   "/*---TRACE_FLOW---*/ bufferPool     %8s cap cap=%07d cnt=%02d",
                                   pvr2_buffer_state_decode(
                                           pvr2_buffer_state_idle),
-                                  bp->stream->i_bcount,bp->stream->i_count);
+                                  bp->stream->i_bcount, bp->stream->i_count);
                }
-               spin_unlock_irqrestore(&sp->list_lock,irq_flags);
-       } while(0);
+               spin_unlock_irqrestore(&sp->list_lock, irq_flags);
+       } while (0);
        mutex_unlock(&sp->mutex);
        return ret;
 }
index 0c47c6a95ab22651235a42a482d357fc6949bf52..e769aeb9d529595fd8ef5e0f699b6704d4def388 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_IO_H
 #define __PVRUSB2_IO_H
index 3c7ca2c2c108ed41a23469f22c6169adec424e0d..602097bdcf149dcc18f57cdb92f2215df3e2342c 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "pvrusb2-ioread.h"
index 0b1f0fbc34381799417e699b47cd8b29f2a8c666..5827ea09c5e35a7b8d1e59678155180ade970f07 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_IOREAD_H
 #define __PVRUSB2_IOREAD_H
index 86be902a00491ebf5d8a94133ae3637db2b9e116..cbe2c3a2245839005aa05f3bd56eedcc9a853270 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/kernel.h>
index cd7bc18a1ba22e9477bd3ceb6e62489d00610899..21bb20dba82c8df5fbc3ccd42c905c220de602eb 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include "pvrusb2-std.h"
index ed4ec0474429a3c3034e6e07ac9c6fcd1bc38a79..b48304f414723b9b0e52f5b487afcfd693c1abdf 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_STD_H
 #define __PVRUSB2_STD_H
index d977976b8d919ab7a15911e89fdd1be2cffbbc25..7bc6d090358ee707173cbb332667a9a2d41f5077 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/string.h>
index 6f0579e1e07ba318ee65202ea1dee4653d7ad90b..431f4fd1901507f49bac5951c347e58ac76cf1bc 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_SYSFS_H
 #define __PVRUSB2_SYSFS_H
index 5465bf9cd73e692d3616664c20852250daf9e3e5..b03ca3ef1ba03aceaaf686485e396792ac6f1764 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_UTIL_H
 #define __PVRUSB2_UTIL_H
index bbbe18d5275ac038142fffec3c34539fea10b339..8f13c60198ed64d72dc74ebf56eacb28714aba86 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #include <linux/kernel.h>
@@ -1054,7 +1050,7 @@ static int pvr2_v4l2_open(struct file *file)
                pvr2_trace(PVR2_TRACE_STRUCT,
                           "Destroying pvr_v4l2_fh id=%p (input mask error)",
                           fhp);
-
+               v4l2_fh_exit(&fhp->fh);
                kfree(fhp);
                return ret;
        }
@@ -1071,6 +1067,7 @@ static int pvr2_v4l2_open(struct file *file)
                pvr2_trace(PVR2_TRACE_STRUCT,
                           "Destroying pvr_v4l2_fh id=%p (input map failure)",
                           fhp);
+               v4l2_fh_exit(&fhp->fh);
                kfree(fhp);
                return -ENOMEM;
        }
index e455c95158414b5453939dd6d8d0ae56bee32274..ec755ee8f86a5d0be82487e689b88435a4e0e4fa 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef __PVRUSB2_V4L2_H
 #define __PVRUSB2_V4L2_H
index 6fee367139aad54ef963487d9824db3f1ddeb77a..b68aec2124b262dcbea4c23d5a95d38f9e16cb81 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 /*
index dacf3ec7f9e1b8637b3f495e52cb66892e1aab9e..fa33f20655f4c4d07d510a012a91fda6412ca664 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_VIDEO_V4L_H
index 7993983de5a68cb2fae869168ec61ca39f5f56e5..8f357f771ba7cb72bbbd8049327436cbbf465693 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 /*
index a4ee12e28d5c6633c442bfb4552f9a8d495919f8..c4ac7c2701d0dda494e02091fcc787433a35cd26 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_WM8775_H
index 95f98a87abb3c192f94cbb6641170c2083eb21b6..955290ba2d5439b9d6398e2b15870cdd492bbfe3 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
 #ifndef __PVRUSB2_H
index f7bb78c1873c915d9db9574ea024cc77a355c413..a9d4484f7626ad4c92692d6e1853461c2efc695a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 95584c15dc5aa7813444a3d51408142b8032b357..22dff4f3b921c56dbdae5facc486d91c3c8492e6 100644 (file)
@@ -8,17 +8,9 @@ config VIDEO_STK1160_COMMON
          To compile this driver as a module, choose M here: the
          module will be called stk1160
 
-config VIDEO_STK1160_AC97
-       bool "STK1160 AC97 codec support"
-       depends on VIDEO_STK1160_COMMON && SND
-
-       ---help---
-         Enables AC97 codec support for stk1160 driver.
-
 config VIDEO_STK1160
        tristate
-       depends on (!VIDEO_STK1160_AC97 || (SND='n') || SND) && VIDEO_STK1160_COMMON
+       depends on VIDEO_STK1160_COMMON
        default y
        select VIDEOBUF2_VMALLOC
        select VIDEO_SAA711X
-       select SND_AC97_CODEC if SND
index dfe3e90ff392fb3e0e7b17f30dc3bf58180e408e..42d05463b353d5b2b1e3f66dc88bbaa2b00ab0a8 100644 (file)
@@ -1,10 +1,8 @@
-obj-stk1160-ac97-$(CONFIG_VIDEO_STK1160_AC97) := stk1160-ac97.o
-
 stk1160-y :=   stk1160-core.o \
                stk1160-v4l.o \
                stk1160-video.o \
                stk1160-i2c.o \
-               $(obj-stk1160-ac97-y)
+               stk1160-ac97.o
 
 obj-$(CONFIG_VIDEO_STK1160) += stk1160.o
 
index 2dd308f9541f469b719adf7d53f01901f4525b3e..2169be8a71dd29006aed5815213dc4905b3c9deb 100644 (file)
@@ -4,6 +4,9 @@
  * Copyright (C) 2012 Ezequiel Garcia
  * <elezegarcia--a.t--gmail.com>
  *
+ * Copyright (C) 2016 Marcel Hasler
+ * <mahasler--a.t--gmail.com>
+ *
  * Based on Easycap driver by R.M. Thomas
  *     Copyright (C) 2010 R.M. Thomas
  *     <rmthomas--a.t--sciolus.org>
  *
  */
 
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/ac97_codec.h>
+#include <linux/delay.h>
 
 #include "stk1160.h"
 #include "stk1160-reg.h"
 
-static struct snd_ac97 *stk1160_ac97;
-
-static void stk1160_write_ac97(struct snd_ac97 *ac97, u16 reg, u16 value)
+static int stk1160_ac97_wait_transfer_complete(struct stk1160 *dev)
 {
-       struct stk1160 *dev = ac97->private_data;
+       unsigned long timeout = jiffies + msecs_to_jiffies(STK1160_AC97_TIMEOUT);
+       u8 value;
+
+       /* Wait for AC97 transfer to complete */
+       while (time_is_after_jiffies(timeout)) {
+               stk1160_read_reg(dev, STK1160_AC97CTL_0, &value);
+
+               if (!(value & (STK1160_AC97CTL_0_CR | STK1160_AC97CTL_0_CW)))
+                       return 0;
 
+               usleep_range(50, 100);
+       }
+
+       stk1160_err("AC97 transfer took too long, this should never happen!");
+       return -EBUSY;
+}
+
+static void stk1160_write_ac97(struct stk1160 *dev, u16 reg, u16 value)
+{
        /* Set codec register address */
        stk1160_write_reg(dev, STK1160_AC97_ADDR, reg);
 
@@ -41,28 +56,30 @@ static void stk1160_write_ac97(struct snd_ac97 *ac97, u16 reg, u16 value)
        stk1160_write_reg(dev, STK1160_AC97_CMD, value & 0xff);
        stk1160_write_reg(dev, STK1160_AC97_CMD + 1, (value & 0xff00) >> 8);
 
-       /*
-        * Set command write bit to initiate write operation.
-        * The bit will be cleared when transfer is done.
-        */
+       /* Set command write bit to initiate write operation */
        stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8c);
+
+       /* Wait for command write bit to be cleared */
+       stk1160_ac97_wait_transfer_complete(dev);
 }
 
-static u16 stk1160_read_ac97(struct snd_ac97 *ac97, u16 reg)
+#ifdef DEBUG
+static u16 stk1160_read_ac97(struct stk1160 *dev, u16 reg)
 {
-       struct stk1160 *dev = ac97->private_data;
        u8 vall = 0;
        u8 valh = 0;
 
        /* Set codec register address */
        stk1160_write_reg(dev, STK1160_AC97_ADDR, reg);
 
-       /*
-        * Set command read bit to initiate read operation.
-        * The bit will be cleared when transfer is done.
-        */
+       /* Set command read bit to initiate read operation */
        stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8b);
 
+       /* Wait for command read bit to be cleared */
+       if (stk1160_ac97_wait_transfer_complete(dev) < 0)
+               return 0;
+
+
        /* Retrieve register value */
        stk1160_read_reg(dev, STK1160_AC97_CMD, &vall);
        stk1160_read_reg(dev, STK1160_AC97_CMD + 1, &valh);
@@ -70,81 +87,79 @@ static u16 stk1160_read_ac97(struct snd_ac97 *ac97, u16 reg)
        return (valh << 8) | vall;
 }
 
-static void stk1160_reset_ac97(struct snd_ac97 *ac97)
+void stk1160_ac97_dump_regs(struct stk1160 *dev)
 {
-       struct stk1160 *dev = ac97->private_data;
-       /* Two-step reset AC97 interface and hardware codec */
-       stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x94);
-       stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x88);
+       u16 value;
 
-       /* Set 16-bit audio data and choose L&R channel*/
-       stk1160_write_reg(dev, STK1160_AC97CTL_1 + 2, 0x01);
+       value = stk1160_read_ac97(dev, 0x12); /* CD volume */
+       stk1160_dbg("0x12 == 0x%04x", value);
+
+       value = stk1160_read_ac97(dev, 0x10); /* Line-in volume */
+       stk1160_dbg("0x10 == 0x%04x", value);
+
+       value = stk1160_read_ac97(dev, 0x0e); /* MIC volume (mono) */
+       stk1160_dbg("0x0e == 0x%04x", value);
+
+       value = stk1160_read_ac97(dev, 0x16); /* Aux volume */
+       stk1160_dbg("0x16 == 0x%04x", value);
+
+       value = stk1160_read_ac97(dev, 0x1a); /* Record select */
+       stk1160_dbg("0x1a == 0x%04x", value);
+
+       value = stk1160_read_ac97(dev, 0x02); /* Master volume */
+       stk1160_dbg("0x02 == 0x%04x", value);
+
+       value = stk1160_read_ac97(dev, 0x1c); /* Record gain */
+       stk1160_dbg("0x1c == 0x%04x", value);
 }
+#endif
+
+static int stk1160_has_audio(struct stk1160 *dev)
+{
+       u8 value;
 
-static struct snd_ac97_bus_ops stk1160_ac97_ops = {
-       .read   = stk1160_read_ac97,
-       .write  = stk1160_write_ac97,
-       .reset  = stk1160_reset_ac97,
-};
+       stk1160_read_reg(dev, STK1160_POSV_L, &value);
+       return !(value & STK1160_POSV_L_ACDOUT);
+}
 
-int stk1160_ac97_register(struct stk1160 *dev)
+static int stk1160_has_ac97(struct stk1160 *dev)
 {
-       struct snd_card *card = NULL;
-       struct snd_ac97_bus *ac97_bus;
-       struct snd_ac97_template ac97_template;
-       int rc;
-
-       /*
-        * Just want a card to access ac96 controls,
-        * the actual capture interface will be handled by snd-usb-audio
-        */
-       rc = snd_card_new(dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-                         THIS_MODULE, 0, &card);
-       if (rc < 0)
-               return rc;
-
-       /* TODO: I'm not sure where should I get these names :-( */
-       snprintf(card->shortname, sizeof(card->shortname),
-                "stk1160-mixer");
-       snprintf(card->longname, sizeof(card->longname),
-                "stk1160 ac97 codec mixer control");
-       strlcpy(card->driver, dev->dev->driver->name, sizeof(card->driver));
-
-       rc = snd_ac97_bus(card, 0, &stk1160_ac97_ops, NULL, &ac97_bus);
-       if (rc)
-               goto err;
-
-       /* We must set private_data before calling snd_ac97_mixer */
-       memset(&ac97_template, 0, sizeof(ac97_template));
-       ac97_template.private_data = dev;
-       ac97_template.scaps = AC97_SCAP_SKIP_MODEM;
-       rc = snd_ac97_mixer(ac97_bus, &ac97_template, &stk1160_ac97);
-       if (rc)
-               goto err;
-
-       dev->snd_card = card;
-       rc = snd_card_register(card);
-       if (rc)
-               goto err;
-
-       return 0;
-
-err:
-       dev->snd_card = NULL;
-       snd_card_free(card);
-       return rc;
+       u8 value;
+
+       stk1160_read_reg(dev, STK1160_POSV_L, &value);
+       return !(value & STK1160_POSV_L_ACSYNC);
 }
 
-int stk1160_ac97_unregister(struct stk1160 *dev)
+void stk1160_ac97_setup(struct stk1160 *dev)
 {
-       struct snd_card *card = dev->snd_card;
+       if (!stk1160_has_audio(dev)) {
+               stk1160_info("Device doesn't support audio, skipping AC97 setup.");
+               return;
+       }
 
-       /*
-        * We need to check usb_device,
-        * because ac97 release attempts to communicate with codec
-        */
-       if (card && dev->udev)
-               snd_card_free(card);
+       if (!stk1160_has_ac97(dev)) {
+               stk1160_info("Device uses internal 8-bit ADC, skipping AC97 setup.");
+               return;
+       }
 
-       return 0;
+       /* Two-step reset AC97 interface and hardware codec */
+       stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x94);
+       stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8c);
+
+       /* Set 16-bit audio data and choose L&R channel*/
+       stk1160_write_reg(dev, STK1160_AC97CTL_1 + 2, 0x01);
+       stk1160_write_reg(dev, STK1160_AC97CTL_1 + 3, 0x00);
+
+       /* Setup channels */
+       stk1160_write_ac97(dev, 0x12, 0x8808); /* CD volume */
+       stk1160_write_ac97(dev, 0x10, 0x0808); /* Line-in volume */
+       stk1160_write_ac97(dev, 0x0e, 0x0008); /* MIC volume (mono) */
+       stk1160_write_ac97(dev, 0x16, 0x0808); /* Aux volume */
+       stk1160_write_ac97(dev, 0x1a, 0x0404); /* Record select */
+       stk1160_write_ac97(dev, 0x02, 0x0000); /* Master volume */
+       stk1160_write_ac97(dev, 0x1c, 0x0808); /* Record gain */
+
+#ifdef DEBUG
+       stk1160_ac97_dump_regs(dev);
+#endif
 }
index bc029478065a0f9c029dd024fca1ef4c0b6788fe..c86eb61647138b394a3c22c7e62b354f1f1df378 100644 (file)
@@ -20,8 +20,7 @@
  *
  * TODO:
  *
- * 1. (Try to) detect if we must register ac97 mixer
- * 2. Support stream at lower speed: lower frame rate or lower frame size.
+ * 1. Support stream at lower speed: lower frame rate or lower frame size.
  *
  */
 
@@ -373,7 +372,7 @@ static int stk1160_probe(struct usb_interface *interface,
        /* select default input */
        stk1160_select_input(dev);
 
-       stk1160_ac97_register(dev);
+       stk1160_ac97_setup(dev);
 
        rc = stk1160_video_register(dev);
        if (rc < 0)
@@ -411,9 +410,6 @@ static void stk1160_disconnect(struct usb_interface *interface)
        /* Here is the only place where isoc get released */
        stk1160_uninit_isoc(dev);
 
-       /* ac97 unregister needs to be done before usb_device is cleared */
-       stk1160_ac97_unregister(dev);
-
        stk1160_clear_queue(dev);
 
        video_unregister_device(&dev->vdev);
index 81ff3a15d96ee413bef207e6cc42325702578a47..7b08a3cc45047c986af1e74d271232b8cd99787e 100644 (file)
 /* Remote Wakup Control */
 #define STK1160_RMCTL                  0x00c
 
+/* Power-on Strapping Data */
+#define STK1160_POSVA                  0x010
+#define STK1160_POSV_L                 0x010
+#define STK1160_POSV_M                 0x011
+#define STK1160_POSV_H                 0x012
+#define  STK1160_POSV_L_ACDOUT         BIT(3)
+#define  STK1160_POSV_L_ACSYNC         BIT(2)
+
 /*
  * Decoder Control Register:
  * This byte controls capture start/stop
 /* AC97 Audio Control */
 #define STK1160_AC97CTL_0              0x500
 #define STK1160_AC97CTL_1              0x504
+#define  STK1160_AC97CTL_0_CR          BIT(1)
+#define  STK1160_AC97CTL_0_CW          BIT(2)
 
 /* Use [0:6] bits of register 0x504 to set codec command address */
 #define STK1160_AC97_ADDR              0x504
index 1ed1cc43cdb268106fee45fdcb61b63fefe02ae0..acd1c811db08a12a9baa9912b8784ea12bae533f 100644 (file)
@@ -50,6 +50,8 @@
 #define STK1160_MAX_INPUT 4
 #define STK1160_SVIDEO_INPUT 4
 
+#define STK1160_AC97_TIMEOUT 50
+
 #define STK1160_I2C_TIMEOUT 100
 
 /* TODO: Print helpers
@@ -197,11 +199,4 @@ int stk1160_read_reg_req_len(struct stk1160 *dev, u8 req, u16 reg,
 void stk1160_select_input(struct stk1160 *dev);
 
 /* Provided by stk1160-ac97.c */
-#ifdef CONFIG_VIDEO_STK1160_AC97
-int stk1160_ac97_register(struct stk1160 *dev);
-int stk1160_ac97_unregister(struct stk1160 *dev);
-#else
-static inline int stk1160_ac97_register(struct stk1160 *dev) { return 0; }
-static inline int stk1160_ac97_unregister(struct stk1160 *dev) { return 0; }
-#endif
-
+void stk1160_ac97_setup(struct stk1160 *dev);
index fbccbb2eed9f4accaf8644c961573542eda2ece2..985af9933c7e093a1d4017d04cb52861b6212992 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /* Controlling the sensor via the STK1125 vendor specific control interface:
index a212248bc2a3294f8bb915c47b5c12a973587234..6e7fc36b658f9b09786240f98046792c4ebca2a5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/module.h>
index 92bb48e3c74e249a5171938a492eb36aa6b7bf4e..0284120ce246b011cd1d4272091dd9039cc2dbe6 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #ifndef STKWEBCAM_H
index 8902ee36bc942049d019b545a1c876b674111d79..b293dea6554f568f3f46dd1318987f87c06f18cd 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
index 8d104e5c4be3cac6e2095d6a2b76e6577807e579..8c265bd80faa7c7e6f4951ba510cd4924e1cb0e0 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 70dbaec1219e11e739b08467e575b5d6f6846153..097ac321b7e1e35f1d89bd18456ab1d501a20773 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index b01d3ee56e770f8b4d8feca78faf8fa017ca9f88..cbcc1472f1c75d477c4c965f4bdecbadc2e25192 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 26b2ebb62547d24de91e60452491fc582f476325..4afd4655d562883a58c4e1bc2b7fa0dbe58f0b58 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -39,7 +35,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
 
 static unsigned int ir_clock_mhz = 12;
 module_param(ir_clock_mhz, int, 0644);
-MODULE_PARM_DESC(enable_ir, "ir clock, in MHz");
+MODULE_PARM_DESC(ir_clock_mhz, "ir clock, in MHz");
 
 #define URB_SUBMIT_DELAY       100     /* ms - Delay to submit an URB request on retrial and init */
 #define URB_INT_LED_DELAY      100     /* ms - Delay to turn led on again on int mode */
@@ -429,7 +425,7 @@ int tm6000_ir_init(struct tm6000_core *dev)
                return 0;
 
        ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
-       rc = rc_allocate_device();
+       rc = rc_allocate_device(RC_DRIVER_SCANCODE);
        if (!ir || !rc)
                goto out;
 
@@ -456,7 +452,6 @@ int tm6000_ir_init(struct tm6000_core *dev)
                ir->polling = 50;
                INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
        }
-       rc->driver_type = RC_DRIVER_SCANCODE;
 
        snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
                                                dev->name);
index a38c251ed57bbe89443158d851052761cc5eb60e..ab3fb74c476c5d19b8bf5a6cef838ea1e387ad7e 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
index 4064a5e8fae1bf1526632f070156b06e210072f4..aa43810d17f97b04a48c29d75b011600a6d0797b 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 99d15a55aa03ae3049320d2b468b14b7dd0a874d..6a13a27c55d7ec785a1673f6b32cb2caf51b8814 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/videodev2.h>
index d9f3fa5db8dd7c1997c570dcd22ed99080e61dad..c4fdc1fa32ef2df170f10339978dba8ea5f288ee 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -1375,8 +1371,11 @@ static int __tm6000_open(struct file *file)
 
        /* initialize hardware on analog mode */
        rc = tm6000_init_analog_mode(dev);
-       if (rc < 0)
+       if (rc < 0) {
+               v4l2_fh_exit(&fh->fh);
+               kfree(fh);
                return rc;
+       }
 
        dev->mode = TM6000_MODE_ANALOG;
 
index f2127944776fb2a4fc91458599d4738d1804c620..7ec478d75f55e57001e1b4100ac9cd32f670c860 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/videodev2.h>
index fc0219f1b7df76ed2307bf1d0bb3ef40136617a2..01c7e6d4481c54567d77bd966f56d2ea87506b66 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include <linux/list.h>
index 2d9444905fdb381061cf5c856521115cef623133..09693caa15e2c3633449f645bd91e6cab170f88f 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #include "dvb_frontend.h"
index 15ccc3d1a20e3bf332005e03a10c4db6655c348a..5aff58c1b075da0584175bbababa78e79df845b0 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef TTUSBDECFE_H
index d3b6d3dfaa09d2c8a1c76ad7544a6e133b6224e8..8135614f395a93565b21e77a0f9fab46432a00ba 100644 (file)
@@ -757,6 +757,12 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl)
                        data[1] = -ctrl->val & 0xff;
                }
                break;
+       case V4L2_CID_SHARPNESS:
+               index = USBTV_BASE + 0x0239;
+               data[0] = 0;
+               data[1] = ctrl->val;
+               size = 2;
+               break;
        default:
                kfree(data);
                return -EINVAL;
@@ -825,6 +831,8 @@ int usbtv_video_init(struct usbtv *usbtv)
                        V4L2_CID_SATURATION, 0, 0x3ff, 1, 0x200);
        v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,
                        V4L2_CID_HUE, -0xdff, 0xdff, 1, 0x000);
+       v4l2_ctrl_new_std(&usbtv->ctrl, &usbtv_ctrl_ops,
+                       V4L2_CID_SHARPNESS, 0x0, 0xff, 1, 0x60);
        ret = usbtv->ctrl.error;
        if (ret < 0) {
                dev_warn(usbtv->dev, "Could not initialize controls\n");
index 3103d0d020e814e70a82d38a0f9d1b3fa12341c3..fc2418b9f37cf81a35ba159a085bd5bf399bb6e1 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index bf041a9e69dbb65f7149df5050b1c9930fb4cbb4..3f87fbc80be29823e0bae8f9cc9c7107a2c9a49d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
@@ -1417,8 +1413,6 @@ static void usbvision_ctrl_urb_complete(struct urb *urb)
 
        PDEBUG(DBG_IRQ, "");
        usbvision->ctrl_urb_busy = 0;
-       if (waitqueue_active(&usbvision->ctrl_urb_wq))
-               wake_up_interruptible(&usbvision->ctrl_urb_wq);
 }
 
 
index 120de2e020e1f31ae0b8ef2bf3c50bea1de691dd..5a3f788ad033772f13d641a6357b93639721cdf3 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
index a7529196c327f8d8ad016ae7b46d68340cba81b4..f5c635a67d74427707e0f44703d6a75f85de9519 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Let's call the version 0.... until compression decoding is completely
  * implemented.
  *
@@ -1340,7 +1336,6 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
        usbvision->ctrl_urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
        if (usbvision->ctrl_urb == NULL)
                goto err_unreg;
-       init_waitqueue_head(&usbvision->ctrl_urb_wq);
 
        return usbvision;
 
index 4f2e4fde38f24fe2b7b4aec1ba00460b3e658d3a..6ecdcd58248f195cd4a2c7e43b62f93d8857170a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 
@@ -370,7 +366,6 @@ struct usb_usbvision {
        unsigned char ctrl_urb_buffer[8];
        int ctrl_urb_busy;
        struct usb_ctrlrequest ctrl_urb_setup;
-       wait_queue_head_t ctrl_urb_wq;                                  /* Processes waiting */
 
        /* configuration part */
        int have_tuner;
index 14561a5abb793df434e40bbaa29a5db7d43e5e9c..368f8f8dfcb5c5917e63fbf1cf25bb80f1d4ed50 100644 (file)
@@ -75,14 +75,14 @@ static const struct file_operations uvc_debugfs_stats_fops = {
 
 static struct dentry *uvc_debugfs_root_dir;
 
-int uvc_debugfs_init_stream(struct uvc_streaming *stream)
+void uvc_debugfs_init_stream(struct uvc_streaming *stream)
 {
        struct usb_device *udev = stream->dev->udev;
        struct dentry *dent;
        char dir_name[32];
 
        if (uvc_debugfs_root_dir == NULL)
-               return -ENODEV;
+               return;
 
        sprintf(dir_name, "%u-%u", udev->bus->busnum, udev->devnum);
 
@@ -90,7 +90,7 @@ int uvc_debugfs_init_stream(struct uvc_streaming *stream)
        if (IS_ERR_OR_NULL(dent)) {
                uvc_printk(KERN_INFO, "Unable to create debugfs %s "
                           "directory.\n", dir_name);
-               return -ENODEV;
+               return;
        }
 
        stream->debugfs_dir = dent;
@@ -100,10 +100,8 @@ int uvc_debugfs_init_stream(struct uvc_streaming *stream)
        if (IS_ERR_OR_NULL(dent)) {
                uvc_printk(KERN_INFO, "Unable to create debugfs stats file.\n");
                uvc_debugfs_cleanup_stream(stream);
-               return -ENODEV;
+               return;
        }
-
-       return 0;
 }
 
 void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream)
@@ -115,18 +113,17 @@ void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream)
        stream->debugfs_dir = NULL;
 }
 
-int uvc_debugfs_init(void)
+void uvc_debugfs_init(void)
 {
        struct dentry *dir;
 
        dir = debugfs_create_dir("uvcvideo", usb_debug_root);
        if (IS_ERR_OR_NULL(dir)) {
                uvc_printk(KERN_INFO, "Unable to create debugfs directory\n");
-               return -ENODATA;
+               return;
        }
 
        uvc_debugfs_root_dir = dir;
-       return 0;
 }
 
 void uvc_debugfs_cleanup(void)
index 77edd206d3452b71460326e970a62c10b62708df..aa2199775cb8f37061c021ae0ed3198bfc199f43 100644 (file)
@@ -43,6 +43,11 @@ uvc_queue_to_stream(struct uvc_video_queue *queue)
        return container_of(queue, struct uvc_streaming, queue);
 }
 
+static inline struct uvc_buffer *uvc_vbuf_to_buffer(struct vb2_v4l2_buffer *buf)
+{
+       return container_of(buf, struct uvc_buffer, buf);
+}
+
 /*
  * Return all queued buffers to videobuf2 in the requested state.
  *
@@ -89,7 +94,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
 {
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
-       struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
+       struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
 
        if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
            vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
@@ -116,7 +121,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb)
 {
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
-       struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
+       struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
        unsigned long flags;
 
        spin_lock_irqsave(&queue->irqlock, flags);
@@ -138,7 +143,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb)
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
        struct uvc_streaming *stream = uvc_queue_to_stream(queue);
-       struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
+       struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
 
        if (vb->state == VB2_BUF_STATE_DONE)
                uvc_video_clock_update(stream, vbuf, buf);
@@ -412,7 +417,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
                nextbuf = NULL;
        spin_unlock_irqrestore(&queue->irqlock, flags);
 
-       buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
+       buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
        vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
        vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
 
index f3c1c852e401ad3b5e834b971008faa3ed403d69..07a6c833ef7b8bf1920937fb0c508f3a7942b9b9 100644 (file)
@@ -1262,8 +1262,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
                        uvc_video_decode_end(stream, buf, stream->bulk.header,
                                stream->bulk.payload_size);
                        if (buf->state == UVC_BUF_STATE_READY)
-                               buf = uvc_queue_next_buffer(&stream->queue,
-                                                           buf);
+                               uvc_queue_next_buffer(&stream->queue, buf);
                }
 
                stream->bulk.header_size = 0;
index 3d6cc62f3cd2e6ffbec0f0d7d6e15be65d260a5b..4205e7a423f0fed13473559ea503e35dd1a69771 100644 (file)
@@ -757,9 +757,9 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
                struct uvc_buffer *buf);
 
 /* debugfs and statistics */
-int uvc_debugfs_init(void);
+void uvc_debugfs_init(void);
 void uvc_debugfs_cleanup(void);
-int uvc_debugfs_init_stream(struct uvc_streaming *stream);
+void uvc_debugfs_init_stream(struct uvc_streaming *stream);
 void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream);
 
 size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
index 3950708cbb328e1adf648c02c1e967aff8ceae5d..f2d6fc03dda03ef000404fc68dba7d40ec20ab48 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 
index 5bada202b2d38c264cbcd87022278d699e411a40..96cc733f35ef72b0f8280f8ff30e0beaedf6d222 100644 (file)
@@ -42,7 +42,8 @@ static bool match_devname(struct v4l2_subdev *sd,
 
 static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
-       return sd->of_node == asd->match.of.node;
+       return !of_node_cmp(of_node_full_name(sd->of_node),
+                           of_node_full_name(asd->match.of.node));
 }
 
 static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
@@ -99,18 +100,11 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
 {
        int ret;
 
-       /* Remove from the waiting list */
-       list_del(&asd->list);
-       sd->asd = asd;
-       sd->notifier = notifier;
-
        if (notifier->bound) {
                ret = notifier->bound(notifier, sd, asd);
                if (ret < 0)
                        return ret;
        }
-       /* Move from the global subdevice list to notifier's done */
-       list_move(&sd->async_list, &notifier->done);
 
        ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
        if (ret < 0) {
@@ -119,6 +113,14 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
                return ret;
        }
 
+       /* Remove from the waiting list */
+       list_del(&asd->list);
+       sd->asd = asd;
+       sd->notifier = notifier;
+
+       /* Move from the global subdevice list to notifier's done */
+       list_move(&sd->async_list, &notifier->done);
+
        if (list_empty(&notifier->waiting) && notifier->complete)
                return notifier->complete(notifier);
 
@@ -168,9 +170,6 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
 
        mutex_lock(&list_lock);
 
-       /* Keep also completed notifiers on the list */
-       list_add(&notifier->list, &notifier_list);
-
        list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
                int ret;
 
@@ -185,6 +184,9 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
                }
        }
 
+       /* Keep also completed notifiers on the list */
+       list_add(&notifier->list, &notifier_list);
+
        mutex_unlock(&list_lock);
 
        return 0;
@@ -202,7 +204,7 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
        if (!notifier->v4l2_dev)
                return;
 
-       dev = kmalloc(n_subdev * sizeof(*dev), GFP_KERNEL);
+       dev = kmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL);
        if (!dev) {
                dev_err(notifier->v4l2_dev->dev,
                        "Failed to allocate device cache!\n");
index 47001e25fd9eeade8ec028c51f2d2482f633db98..b9e08e3d6e0e7d52deeed2d8d9d2d51f6622659c 100644 (file)
@@ -3367,6 +3367,9 @@ static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
 {
        struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
 
+       if (ctrl == NULL)
+               return;
+
        v4l2_ctrl_lock(ctrl);
        list_del(&sev->node);
        v4l2_ctrl_unlock(ctrl);
index 62bbed76dbbc401bda8413ec94cc5cf4d065f5de..f364cc1b521dcd65919cb8a548e3f3d18acf6880 100644 (file)
@@ -253,6 +253,7 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
                        kfree(vdev);
                        goto clean_up;
                }
+               sd->devnode = vdev;
 #if defined(CONFIG_MEDIA_CONTROLLER)
                sd->entity.info.dev.major = VIDEO_MAJOR;
                sd->entity.info.dev.minor = vdev->minor;
@@ -270,7 +271,6 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
                        }
                }
 #endif
-               sd->devnode = vdev;
        }
        return 0;
 
index 8d3171c6bee8e5be0d5f06d1e104151b4ee06485..a75df6cb141fdf1466baa323507da29d28e78617 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #include <media/v4l2-dev.h>
index c183f0996fa1ce3b394b4bd2cb700574842e7e80..3895999bf8805c3c208a4f042cb59b786a6ec44c 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #include <linux/bitops.h>
index 8bef4331bd511261acacf1b58acbeb56749a90ff..303980b71aae26f2a750c2f1bfe96ebe1046148e 100644 (file)
@@ -198,14 +198,20 @@ EXPORT_SYMBOL_GPL(v4l2_mc_create_media_graph);
 int v4l_enable_media_source(struct video_device *vdev)
 {
        struct media_device *mdev = vdev->entity.graph_obj.mdev;
-       int ret;
+       int ret = 0, err;
 
-       if (!mdev || !mdev->enable_source)
+       if (!mdev)
                return 0;
-       ret = mdev->enable_source(&vdev->entity, &vdev->pipe);
-       if (ret)
-               return -EBUSY;
-       return 0;
+
+       mutex_lock(&mdev->graph_mutex);
+       if (!mdev->enable_source)
+               goto end;
+       err = mdev->enable_source(&vdev->entity, &vdev->pipe);
+       if (err)
+               ret = -EBUSY;
+end:
+       mutex_unlock(&mdev->graph_mutex);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(v4l_enable_media_source);
 
@@ -213,8 +219,12 @@ void v4l_disable_media_source(struct video_device *vdev)
 {
        struct media_device *mdev = vdev->entity.graph_obj.mdev;
 
-       if (mdev && mdev->disable_source)
-               mdev->disable_source(&vdev->entity);
+       if (mdev) {
+               mutex_lock(&mdev->graph_mutex);
+               if (mdev->disable_source)
+                       mdev->disable_source(&vdev->entity);
+               mutex_unlock(&mdev->graph_mutex);
+       }
 }
 EXPORT_SYMBOL_GPL(v4l_disable_media_source);
 
@@ -256,13 +266,13 @@ EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_source);
  * Return the total number of users of all video device nodes in the pipeline.
  */
 static int pipeline_pm_use_count(struct media_entity *entity,
-       struct media_entity_graph *graph)
+       struct media_graph *graph)
 {
        int use = 0;
 
-       media_entity_graph_walk_start(graph, entity);
+       media_graph_walk_start(graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(graph))) {
+       while ((entity = media_graph_walk_next(graph))) {
                if (is_media_entity_v4l2_video_device(entity))
                        use += entity->use_count;
        }
@@ -315,7 +325,7 @@ static int pipeline_pm_power_one(struct media_entity *entity, int change)
  * Return 0 on success or a negative error code on failure.
  */
 static int pipeline_pm_power(struct media_entity *entity, int change,
-       struct media_entity_graph *graph)
+       struct media_graph *graph)
 {
        struct media_entity *first = entity;
        int ret = 0;
@@ -323,18 +333,18 @@ static int pipeline_pm_power(struct media_entity *entity, int change,
        if (!change)
                return 0;
 
-       media_entity_graph_walk_start(graph, entity);
+       media_graph_walk_start(graph, entity);
 
-       while (!ret && (entity = media_entity_graph_walk_next(graph)))
+       while (!ret && (entity = media_graph_walk_next(graph)))
                if (is_media_entity_v4l2_subdev(entity))
                        ret = pipeline_pm_power_one(entity, change);
 
        if (!ret)
                return ret;
 
-       media_entity_graph_walk_start(graph, first);
+       media_graph_walk_start(graph, first);
 
-       while ((first = media_entity_graph_walk_next(graph))
+       while ((first = media_graph_walk_next(graph))
               && first != entity)
                if (is_media_entity_v4l2_subdev(first))
                        pipeline_pm_power_one(first, -change);
@@ -368,7 +378,7 @@ EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_use);
 int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
                              unsigned int notification)
 {
-       struct media_entity_graph *graph = &link->graph_obj.mdev->pm_count_walk;
+       struct media_graph *graph = &link->graph_obj.mdev->pm_count_walk;
        struct media_entity *source = link->source->entity;
        struct media_entity *sink = link->sink->entity;
        int source_use;
index 93b33681776ca427703dee8bbf6616cca95d7938..4f59f442dd0a64c9003873f11c0658d2e258eb6b 100644 (file)
@@ -26,7 +26,7 @@ static int v4l2_of_parse_csi_bus(const struct device_node *node,
        struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2;
        struct property *prop;
        bool have_clk_lane = false;
-       unsigned int flags = 0;
+       unsigned int flags = 0, lanes_used = 0;
        u32 v;
 
        prop = of_find_property(node, "data-lanes", NULL);
@@ -38,6 +38,12 @@ static int v4l2_of_parse_csi_bus(const struct device_node *node,
                        lane = of_prop_next_u32(prop, lane, &v);
                        if (!lane)
                                break;
+
+                       if (lanes_used & BIT(v))
+                               pr_warn("%s: duplicated lane %u in data-lanes\n",
+                                       node->full_name, v);
+                       lanes_used |= BIT(v);
+
                        bus->data_lanes[i] = v;
                }
                bus->num_data_lanes = i;
@@ -63,6 +69,11 @@ static int v4l2_of_parse_csi_bus(const struct device_node *node,
        }
 
        if (!of_property_read_u32(node, "clock-lanes", &v)) {
+               if (lanes_used & BIT(v))
+                       pr_warn("%s: duplicated lane %u in clock-lanes\n",
+                               node->full_name, v);
+               lanes_used |= BIT(v);
+
                bus->clock_lane = v;
                have_clk_lane = true;
        }
index 34a1e7c8b3069e87626dd77db89c659a54c67a56..da78497ae5ed2f0944a20c9992eaa4265917b175 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/ioctl.h>
index c27d7e9a1bdbe84059b484c7971f0f6ff9a16c33..8b2117ee0f602b43826aabd75e532df4606ecc88 100644 (file)
@@ -129,7 +129,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
 /* make a note of pipeline details */
 static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
 {
-       struct media_entity_graph graph;
+       struct media_graph graph;
        struct media_entity *entity = &video->video_dev.entity;
        struct media_device *mdev = entity->graph_obj.mdev;
        struct vpfe_pipeline *pipe = &video->pipe;
@@ -145,13 +145,13 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
                pipe->outputs[pipe->output_num++] = video;
 
        mutex_lock(&mdev->graph_mutex);
-       ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
+       ret = media_graph_walk_init(&graph, mdev);
        if (ret) {
                mutex_unlock(&mdev->graph_mutex);
                return -ENOMEM;
        }
-       media_entity_graph_walk_start(&graph, entity);
-       while ((entity = media_entity_graph_walk_next(&graph))) {
+       media_graph_walk_start(&graph, entity);
+       while ((entity = media_graph_walk_next(&graph))) {
                if (entity == &video->video_dev.entity)
                        continue;
                if (!is_media_entity_v4l2_video_device(entity))
@@ -162,7 +162,7 @@ static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
                else
                        pipe->outputs[pipe->output_num++] = far_end;
        }
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
        mutex_unlock(&mdev->graph_mutex);
 
        return 0;
@@ -300,12 +300,11 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 
        mdev = entity->graph_obj.mdev;
        mutex_lock(&mdev->graph_mutex);
-       ret = media_entity_graph_walk_init(&pipe->graph,
-                                          entity->graph_obj.mdev);
+       ret = media_graph_walk_init(&pipe->graph, mdev);
        if (ret)
                goto out;
-       media_entity_graph_walk_start(&pipe->graph, entity);
-       while ((entity = media_entity_graph_walk_next(&pipe->graph))) {
+       media_graph_walk_start(&pipe->graph, entity);
+       while ((entity = media_graph_walk_next(&pipe->graph))) {
 
                if (!is_media_entity_v4l2_subdev(entity))
                        continue;
@@ -316,7 +315,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
        }
 out:
        if (ret)
-               media_entity_graph_walk_cleanup(&pipe->graph);
+               media_graph_walk_cleanup(&pipe->graph);
        mutex_unlock(&mdev->graph_mutex);
        return ret;
 }
@@ -346,9 +345,9 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 
        mdev = entity->graph_obj.mdev;
        mutex_lock(&mdev->graph_mutex);
-       media_entity_graph_walk_start(&pipe->graph, entity);
+       media_graph_walk_start(&pipe->graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(&pipe->graph))) {
+       while ((entity = media_graph_walk_next(&pipe->graph))) {
 
                if (!is_media_entity_v4l2_subdev(entity))
                        continue;
@@ -359,7 +358,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
        }
        mutex_unlock(&mdev->graph_mutex);
 
-       media_entity_graph_walk_cleanup(&pipe->graph);
+       media_graph_walk_cleanup(&pipe->graph);
        return ret ? -ETIMEDOUT : 0;
 }
 
index aaec4403df3b695b83fca64065dd1b50d4858d30..22136d3dadcbe946b65360372c8c0e5d2b59a1a1 100644 (file)
@@ -52,7 +52,7 @@ enum vpfe_video_state {
 struct vpfe_pipeline {
        /* media pipeline */
        struct media_pipeline           *pipe;
-       struct media_entity_graph       graph;
+       struct media_graph      graph;
        /* state of the pipeline, continuous,
         * single-shot or stopped
         */
index 25b7e7ccf55479ec7a3d83a6e4b8b6aaba207a26..bc67da254262318f43cb81ab58fb2053339f2e73 100644 (file)
@@ -12,26 +12,6 @@ menuconfig LIRC_STAGING
 
 if LIRC_STAGING
 
-config LIRC_BT829
-        tristate "BT829 based hardware"
-       depends on LIRC && PCI
-       help
-         Driver for the IR interface on BT829-based hardware
-
-config LIRC_IMON
-       tristate "Legacy SoundGraph iMON Receiver and Display"
-       depends on LIRC && USB
-       help
-         Driver for the original SoundGraph iMON IR Receiver and Display
-
-         Current generation iMON devices use the input layer imon driver.
-
-config LIRC_PARALLEL
-       tristate "Homebrew Parallel Port Receiver"
-       depends on LIRC && PARPORT
-       help
-         Driver for Homebrew Parallel Port Receivers
-
 config LIRC_SASEM
        tristate "Sasem USB IR Remote"
        depends on LIRC && USB
@@ -40,7 +20,7 @@ config LIRC_SASEM
 
 config LIRC_SIR
        tristate "Built-in SIR IrDA port"
-       depends on LIRC
+       depends on RC_CORE
        help
          Driver for the SIR IrDA port
 
index 7f919eab1989e33f49917f51e9857bc439f51d1f..28740c94349c4e412ee0b77bc800c8fb0705297c 100644 (file)
@@ -3,9 +3,6 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_LIRC_BT829)       += lirc_bt829.o
-obj-$(CONFIG_LIRC_IMON)                += lirc_imon.o
-obj-$(CONFIG_LIRC_PARALLEL)    += lirc_parallel.o
 obj-$(CONFIG_LIRC_SASEM)       += lirc_sasem.o
 obj-$(CONFIG_LIRC_SIR)         += lirc_sir.o
 obj-$(CONFIG_LIRC_ZILOG)       += lirc_zilog.o
diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c
deleted file mode 100644 (file)
index 04d881b..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Remote control driver for the TV-card based on bt829
- *
- *  by Leonid Froenchenko <lfroen@galileo.co.il>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-
-#include <media/lirc_dev.h>
-
-static int poll_main(void);
-static int atir_init_start(void);
-
-static void write_index(unsigned char index, unsigned int value);
-static unsigned int read_index(unsigned char index);
-
-static void do_i2c_start(void);
-static void do_i2c_stop(void);
-
-static void seems_wr_byte(unsigned char al);
-static unsigned char seems_rd_byte(void);
-
-static unsigned int read_index(unsigned char al);
-static void write_index(unsigned char ah, unsigned int edx);
-
-static void cycle_delay(int cycle);
-
-static void do_set_bits(unsigned char bl);
-static unsigned char do_get_bits(void);
-
-#define DATA_PCI_OFF 0x7FFC00
-#define WAIT_CYCLE   20
-
-#define DRIVER_NAME "lirc_bt829"
-
-static bool debug;
-
-static int atir_minor;
-static phys_addr_t pci_addr_phys;
-static unsigned char __iomem *pci_addr_lin;
-
-static struct lirc_driver atir_driver;
-
-static struct pci_dev *do_pci_probe(void)
-{
-       struct pci_dev *my_dev;
-
-       my_dev = pci_get_device(PCI_VENDOR_ID_ATI,
-                               PCI_DEVICE_ID_ATI_264VT, NULL);
-       if (my_dev) {
-               pr_err("Using device: %s\n", pci_name(my_dev));
-               pci_addr_phys = 0;
-               if (my_dev->resource[0].flags & IORESOURCE_MEM) {
-                       pci_addr_phys = my_dev->resource[0].start;
-                       pr_info("memory at %pa\n", &pci_addr_phys);
-               }
-               if (pci_addr_phys == 0) {
-                       pr_err("no memory resource ?\n");
-                       pci_dev_put(my_dev);
-                       return NULL;
-               }
-       } else {
-               pr_err("pci_probe failed\n");
-               return NULL;
-       }
-       return my_dev;
-}
-
-static int atir_add_to_buf(void *data, struct lirc_buffer *buf)
-{
-       unsigned char key;
-       int status;
-
-       status = poll_main();
-       key = (status >> 8) & 0xFF;
-       if (status & 0xFF) {
-               dev_dbg(atir_driver.dev, "reading key %02X\n", key);
-               lirc_buffer_write(buf, &key);
-               return 0;
-       }
-       return -ENODATA;
-}
-
-static int atir_set_use_inc(void *data)
-{
-       dev_dbg(atir_driver.dev, "driver is opened\n");
-       return 0;
-}
-
-static void atir_set_use_dec(void *data)
-{
-       dev_dbg(atir_driver.dev, "driver is closed\n");
-}
-
-int init_module(void)
-{
-       struct pci_dev *pdev;
-       int rc;
-
-       pdev = do_pci_probe();
-       if (!pdev)
-               return -ENODEV;
-
-       rc = pci_enable_device(pdev);
-       if (rc)
-               goto err_put_dev;
-
-       if (!atir_init_start()) {
-               rc = -ENODEV;
-               goto err_disable;
-       }
-
-       strcpy(atir_driver.name, "ATIR");
-       atir_driver.minor       = -1;
-       atir_driver.code_length = 8;
-       atir_driver.sample_rate = 10;
-       atir_driver.data        = NULL;
-       atir_driver.add_to_buf  = atir_add_to_buf;
-       atir_driver.set_use_inc = atir_set_use_inc;
-       atir_driver.set_use_dec = atir_set_use_dec;
-       atir_driver.dev         = &pdev->dev;
-       atir_driver.owner       = THIS_MODULE;
-
-       atir_minor = lirc_register_driver(&atir_driver);
-       if (atir_minor < 0) {
-               pr_err("failed to register driver!\n");
-               rc = atir_minor;
-               goto err_unmap;
-       }
-       dev_dbg(atir_driver.dev, "driver is registered on minor %d\n",
-                               atir_minor);
-
-       return 0;
-
-err_unmap:
-       iounmap(pci_addr_lin);
-err_disable:
-       pci_disable_device(pdev);
-err_put_dev:
-       pci_dev_put(pdev);
-       return rc;
-}
-
-void cleanup_module(void)
-{
-       struct pci_dev *pdev = to_pci_dev(atir_driver.dev);
-
-       lirc_unregister_driver(atir_minor);
-       iounmap(pci_addr_lin);
-       pci_disable_device(pdev);
-       pci_dev_put(pdev);
-}
-
-static int atir_init_start(void)
-{
-       pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
-       if (!pci_addr_lin) {
-               pr_info("pci mem must be mapped\n");
-               return 0;
-       }
-       return 1;
-}
-
-static void cycle_delay(int cycle)
-{
-       udelay(WAIT_CYCLE * cycle);
-}
-
-static int poll_main(void)
-{
-       unsigned char status_high, status_low;
-
-       do_i2c_start();
-
-       seems_wr_byte(0xAA);
-       seems_wr_byte(0x01);
-
-       do_i2c_start();
-
-       seems_wr_byte(0xAB);
-
-       status_low = seems_rd_byte();
-       status_high = seems_rd_byte();
-
-       do_i2c_stop();
-
-       return (status_high << 8) | status_low;
-}
-
-static void do_i2c_start(void)
-{
-       do_set_bits(3);
-       cycle_delay(4);
-
-       do_set_bits(1);
-       cycle_delay(7);
-
-       do_set_bits(0);
-       cycle_delay(2);
-}
-
-static void do_i2c_stop(void)
-{
-       unsigned char bits;
-
-       bits =  do_get_bits() & 0xFD;
-       do_set_bits(bits);
-       cycle_delay(1);
-
-       bits |= 1;
-       do_set_bits(bits);
-       cycle_delay(2);
-
-       bits |= 2;
-       do_set_bits(bits);
-       bits = 3;
-       do_set_bits(bits);
-       cycle_delay(2);
-}
-
-static void seems_wr_byte(unsigned char value)
-{
-       int i;
-       unsigned char reg;
-
-       reg = do_get_bits();
-       for (i = 0; i < 8; i++) {
-               if (value & 0x80)
-                       reg |= 0x02;
-               else
-                       reg &= 0xFD;
-
-               do_set_bits(reg);
-               cycle_delay(1);
-
-               reg |= 1;
-               do_set_bits(reg);
-               cycle_delay(1);
-
-               reg &= 0xFE;
-               do_set_bits(reg);
-               cycle_delay(1);
-               value <<= 1;
-       }
-       cycle_delay(2);
-
-       reg |= 2;
-       do_set_bits(reg);
-
-       reg |= 1;
-       do_set_bits(reg);
-
-       cycle_delay(1);
-       do_get_bits();
-
-       reg &= 0xFE;
-       do_set_bits(reg);
-       cycle_delay(3);
-}
-
-static unsigned char seems_rd_byte(void)
-{
-       int i;
-       int rd_byte;
-       unsigned char bits_2, bits_1;
-
-       bits_1 = do_get_bits() | 2;
-       do_set_bits(bits_1);
-
-       rd_byte = 0;
-       for (i = 0; i < 8; i++) {
-               bits_1 &= 0xFE;
-               do_set_bits(bits_1);
-               cycle_delay(2);
-
-               bits_1 |= 1;
-               do_set_bits(bits_1);
-               cycle_delay(1);
-
-               bits_2 = do_get_bits();
-               if (bits_2 & 2)
-                       rd_byte |= 1;
-
-               rd_byte <<= 1;
-       }
-
-       bits_1 = 0;
-       if (bits_2 == 0)
-               bits_1 |= 2;
-
-       do_set_bits(bits_1);
-       cycle_delay(2);
-
-       bits_1 |= 1;
-       do_set_bits(bits_1);
-       cycle_delay(3);
-
-       bits_1 &= 0xFE;
-       do_set_bits(bits_1);
-       cycle_delay(2);
-
-       rd_byte >>= 1;
-       rd_byte &= 0xFF;
-       return rd_byte;
-}
-
-static void do_set_bits(unsigned char new_bits)
-{
-       int reg_val;
-
-       reg_val = read_index(0x34);
-       if (new_bits & 2) {
-               reg_val &= 0xFFFFFFDF;
-               reg_val |= 1;
-       } else {
-               reg_val &= 0xFFFFFFFE;
-               reg_val |= 0x20;
-       }
-       reg_val |= 0x10;
-       write_index(0x34, reg_val);
-
-       reg_val = read_index(0x31);
-       if (new_bits & 1)
-               reg_val |= 0x1000000;
-       else
-               reg_val &= 0xFEFFFFFF;
-
-       reg_val |= 0x8000000;
-       write_index(0x31, reg_val);
-}
-
-static unsigned char do_get_bits(void)
-{
-       unsigned char bits;
-       int reg_val;
-
-       reg_val = read_index(0x34);
-       reg_val |= 0x10;
-       reg_val &= 0xFFFFFFDF;
-       write_index(0x34, reg_val);
-
-       reg_val = read_index(0x34);
-       bits = 0;
-       if (reg_val & 8)
-               bits |= 2;
-       else
-               bits &= 0xFD;
-
-       reg_val = read_index(0x31);
-       if (reg_val & 0x1000000)
-               bits |= 1;
-       else
-               bits &= 0xFE;
-
-       return bits;
-}
-
-static unsigned int read_index(unsigned char index)
-{
-       unsigned char __iomem *addr;
-       /*  addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */
-       addr = pci_addr_lin + ((index & 0xFF) << 2);
-       return readl(addr);
-}
-
-static void write_index(unsigned char index, unsigned int reg_val)
-{
-       unsigned char __iomem *addr;
-
-       addr = pci_addr_lin + ((index & 0xFF) << 2);
-       writel(reg_val, addr);
-}
-
-MODULE_AUTHOR("Froenchenko Leonid");
-MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards");
-MODULE_LICENSE("GPL");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
deleted file mode 100644 (file)
index 1e650fb..0000000
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- *   lirc_imon.c:  LIRC/VFD/LCD driver for SoundGraph iMON IR/VFD/LCD
- *                including the iMON PAD model
- *
- *   Copyright(C) 2004  Venky Raju(dev@venky.ws)
- *   Copyright(C) 2009  Jarod Wilson <jarod@wilsonet.com>
- *
- *   lirc_imon is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/usb.h>
-
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
-
-#define MOD_AUTHOR     "Venky Raju <dev@venky.ws>"
-#define MOD_DESC       "Driver for SoundGraph iMON MultiMedia IR/Display"
-#define MOD_NAME       "lirc_imon"
-#define MOD_VERSION    "0.8"
-
-#define DISPLAY_MINOR_BASE     144
-#define DEVICE_NAME    "lcd%d"
-
-#define BUF_CHUNK_SIZE 4
-#define BUF_SIZE       128
-
-#define BIT_DURATION   250     /* each bit received is 250us */
-
-/*** P R O T O T Y P E S ***/
-
-/* USB Callback prototypes */
-static int imon_probe(struct usb_interface *interface,
-                     const struct usb_device_id *id);
-static void imon_disconnect(struct usb_interface *interface);
-static void usb_rx_callback(struct urb *urb);
-static void usb_tx_callback(struct urb *urb);
-
-/* suspend/resume support */
-static int imon_resume(struct usb_interface *intf);
-static int imon_suspend(struct usb_interface *intf, pm_message_t message);
-
-/* Display file_operations function prototypes */
-static int display_open(struct inode *inode, struct file *file);
-static int display_close(struct inode *inode, struct file *file);
-
-/* VFD write operation */
-static ssize_t vfd_write(struct file *file, const char __user *buf,
-                        size_t n_bytes, loff_t *pos);
-
-/* LIRC driver function prototypes */
-static int ir_open(void *data);
-static void ir_close(void *data);
-
-/*** G L O B A L S ***/
-#define IMON_DATA_BUF_SZ       35
-
-struct imon_context {
-       struct usb_device *usbdev;
-       /* Newer devices have two interfaces */
-       int display;                    /* not all controllers do */
-       int display_isopen;             /* display port has been opened */
-       int ir_isopen;                  /* IR port open */
-       int dev_present;                /* USB device presence */
-       struct mutex ctx_lock;          /* to lock this object */
-       wait_queue_head_t remove_ok;    /* For unexpected USB disconnects */
-
-       int vfd_proto_6p;               /* some VFD require a 6th packet */
-
-       struct lirc_driver *driver;
-       struct usb_endpoint_descriptor *rx_endpoint;
-       struct usb_endpoint_descriptor *tx_endpoint;
-       struct urb *rx_urb;
-       struct urb *tx_urb;
-       unsigned char usb_rx_buf[8];
-       unsigned char usb_tx_buf[8];
-
-       struct rx_data {
-               int count;              /* length of 0 or 1 sequence */
-               int prev_bit;           /* logic level of sequence */
-               int initial_space;      /* initial space flag */
-       } rx;
-
-       struct tx_t {
-               unsigned char data_buf[IMON_DATA_BUF_SZ]; /* user data buffer */
-               struct completion finished;     /* wait for write to finish */
-               atomic_t busy;                  /* write in progress */
-               int status;                     /* status of tx completion */
-       } tx;
-};
-
-static const struct file_operations display_fops = {
-       .owner          = THIS_MODULE,
-       .open           = &display_open,
-       .write          = &vfd_write,
-       .release        = &display_close,
-       .llseek         = noop_llseek,
-};
-
-/*
- * USB Device ID for iMON USB Control Boards
- *
- * The Windows drivers contain 6 different inf files, more or less one for
- * each new device until the 0x0034-0x0046 devices, which all use the same
- * driver. Some of the devices in the 34-46 range haven't been definitively
- * identified yet. Early devices have either a TriGem Computer, Inc. or a
- * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
- * devices use the SoundGraph vendor ID (0x15c2).
- */
-static struct usb_device_id imon_usb_id_table[] = {
-       /* TriGem iMON (IR only) -- TG_iMON.inf */
-       { USB_DEVICE(0x0aa8, 0x8001) },
-
-       /* SoundGraph iMON (IR only) -- sg_imon.inf */
-       { USB_DEVICE(0x04e8, 0xff30) },
-
-       /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */
-       { USB_DEVICE(0x0aa8, 0xffda) },
-
-       /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */
-       { USB_DEVICE(0x15c2, 0xffda) },
-
-       {}
-};
-
-/* Some iMON VFD models requires a 6th packet for VFD writes */
-static struct usb_device_id vfd_proto_6p_list[] = {
-       { USB_DEVICE(0x15c2, 0xffda) },
-       {}
-};
-
-/* Some iMON devices have no lcd/vfd, don't set one up */
-static struct usb_device_id ir_only_list[] = {
-       { USB_DEVICE(0x0aa8, 0x8001) },
-       { USB_DEVICE(0x04e8, 0xff30) },
-       {}
-};
-
-/* USB Device data */
-static struct usb_driver imon_driver = {
-       .name           = MOD_NAME,
-       .probe          = imon_probe,
-       .disconnect     = imon_disconnect,
-       .suspend        = imon_suspend,
-       .resume         = imon_resume,
-       .id_table       = imon_usb_id_table,
-};
-
-static struct usb_class_driver imon_class = {
-       .name           = DEVICE_NAME,
-       .fops           = &display_fops,
-       .minor_base     = DISPLAY_MINOR_BASE,
-};
-
-/* to prevent races between open() and disconnect(), probing, etc */
-static DEFINE_MUTEX(driver_lock);
-
-static int debug;
-
-/***  M O D U L E   C O D E ***/
-
-MODULE_AUTHOR(MOD_AUTHOR);
-MODULE_DESCRIPTION(MOD_DESC);
-MODULE_VERSION(MOD_VERSION);
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
-
-static void free_imon_context(struct imon_context *context)
-{
-       struct device *dev = context->driver->dev;
-
-       usb_free_urb(context->tx_urb);
-       usb_free_urb(context->rx_urb);
-       lirc_buffer_free(context->driver->rbuf);
-       kfree(context->driver->rbuf);
-       kfree(context->driver);
-       kfree(context);
-
-       dev_dbg(dev, "%s: iMON context freed\n", __func__);
-}
-
-static void deregister_from_lirc(struct imon_context *context)
-{
-       int retval;
-       int minor = context->driver->minor;
-
-       retval = lirc_unregister_driver(minor);
-       if (retval)
-               dev_err(&context->usbdev->dev,
-                       "unable to deregister from lirc(%d)", retval);
-       else
-               dev_info(&context->usbdev->dev,
-                        "Deregistered iMON driver (minor:%d)\n", minor);
-}
-
-/**
- * Called when the Display device (e.g. /dev/lcd0)
- * is opened by the application.
- */
-static int display_open(struct inode *inode, struct file *file)
-{
-       struct usb_interface *interface;
-       struct imon_context *context = NULL;
-       int subminor;
-       int retval = 0;
-
-       /* prevent races with disconnect */
-       mutex_lock(&driver_lock);
-
-       subminor = iminor(inode);
-       interface = usb_find_interface(&imon_driver, subminor);
-       if (!interface) {
-               pr_err("%s: could not find interface for minor %d\n",
-                      __func__, subminor);
-               retval = -ENODEV;
-               goto exit;
-       }
-       context = usb_get_intfdata(interface);
-
-       if (!context) {
-               dev_err(&interface->dev, "no context found for minor %d\n",
-                       subminor);
-               retval = -ENODEV;
-               goto exit;
-       }
-
-       mutex_lock(&context->ctx_lock);
-
-       if (!context->display) {
-               dev_err(&interface->dev,
-                       "%s: display not supported by device\n", __func__);
-               retval = -ENODEV;
-       } else if (context->display_isopen) {
-               dev_err(&interface->dev,
-                       "%s: display port is already open\n", __func__);
-               retval = -EBUSY;
-       } else {
-               context->display_isopen = 1;
-               file->private_data = context;
-               dev_info(context->driver->dev, "display port opened\n");
-       }
-
-       mutex_unlock(&context->ctx_lock);
-
-exit:
-       mutex_unlock(&driver_lock);
-       return retval;
-}
-
-/**
- * Called when the display device (e.g. /dev/lcd0)
- * is closed by the application.
- */
-static int display_close(struct inode *inode, struct file *file)
-{
-       struct imon_context *context = NULL;
-       int retval = 0;
-
-       context = file->private_data;
-
-       if (!context) {
-               pr_err("%s: no context for device\n", __func__);
-               return -ENODEV;
-       }
-
-       mutex_lock(&context->ctx_lock);
-
-       if (!context->display) {
-               dev_err(&context->usbdev->dev,
-                       "%s: display not supported by device\n", __func__);
-               retval = -ENODEV;
-       } else if (!context->display_isopen) {
-               dev_err(&context->usbdev->dev,
-                       "%s: display is not open\n", __func__);
-               retval = -EIO;
-       } else {
-               context->display_isopen = 0;
-               dev_info(context->driver->dev, "display port closed\n");
-               if (!context->dev_present && !context->ir_isopen) {
-                       /*
-                        * Device disconnected before close and IR port is not
-                        * open. If IR port is open, context will be deleted by
-                        * ir_close.
-                        */
-                       mutex_unlock(&context->ctx_lock);
-                       free_imon_context(context);
-                       return retval;
-               }
-       }
-
-       mutex_unlock(&context->ctx_lock);
-       return retval;
-}
-
-/**
- * Sends a packet to the device -- this function must be called
- * with context->ctx_lock held.
- */
-static int send_packet(struct imon_context *context)
-{
-       unsigned int pipe;
-       int interval = 0;
-       int retval = 0;
-
-       /* Check if we need to use control or interrupt urb */
-       pipe = usb_sndintpipe(context->usbdev,
-                             context->tx_endpoint->bEndpointAddress);
-       interval = context->tx_endpoint->bInterval;
-
-       usb_fill_int_urb(context->tx_urb, context->usbdev, pipe,
-                        context->usb_tx_buf,
-                        sizeof(context->usb_tx_buf),
-                        usb_tx_callback, context, interval);
-
-       context->tx_urb->actual_length = 0;
-
-       reinit_completion(&context->tx.finished);
-       atomic_set(&context->tx.busy, 1);
-
-       retval = usb_submit_urb(context->tx_urb, GFP_KERNEL);
-       if (retval) {
-               atomic_set(&context->tx.busy, 0);
-               dev_err(&context->usbdev->dev, "error submitting urb(%d)\n",
-                       retval);
-       } else {
-               /* Wait for transmission to complete (or abort) */
-               mutex_unlock(&context->ctx_lock);
-               retval = wait_for_completion_interruptible(
-                               &context->tx.finished);
-               if (retval)
-                       dev_err(&context->usbdev->dev,
-                               "%s: task interrupted\n", __func__);
-               mutex_lock(&context->ctx_lock);
-
-               retval = context->tx.status;
-               if (retval)
-                       dev_err(&context->usbdev->dev,
-                               "packet tx failed (%d)\n", retval);
-       }
-
-       return retval;
-}
-
-/**
- * Writes data to the VFD.  The iMON VFD is 2x16 characters
- * and requires data in 5 consecutive USB interrupt packets,
- * each packet but the last carrying 7 bytes.
- *
- * I don't know if the VFD board supports features such as
- * scrolling, clearing rows, blanking, etc. so at
- * the caller must provide a full screen of data.  If fewer
- * than 32 bytes are provided spaces will be appended to
- * generate a full screen.
- */
-static ssize_t vfd_write(struct file *file, const char __user *buf,
-                        size_t n_bytes, loff_t *pos)
-{
-       int i;
-       int offset;
-       int seq;
-       int retval = 0;
-       struct imon_context *context;
-       const unsigned char vfd_packet6[] = {
-               0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
-       int *data_buf = NULL;
-
-       context = file->private_data;
-       if (!context) {
-               pr_err("%s: no context for device\n", __func__);
-               return -ENODEV;
-       }
-
-       mutex_lock(&context->ctx_lock);
-
-       if (!context->dev_present) {
-               dev_err(&context->usbdev->dev,
-                       "%s: no iMON device present\n", __func__);
-               retval = -ENODEV;
-               goto exit;
-       }
-
-       if (n_bytes <= 0 || n_bytes > IMON_DATA_BUF_SZ - 3) {
-               dev_err(&context->usbdev->dev,
-                       "%s: invalid payload size\n", __func__);
-               retval = -EINVAL;
-               goto exit;
-       }
-
-       data_buf = memdup_user(buf, n_bytes);
-       if (IS_ERR(data_buf)) {
-               mutex_unlock(&context->ctx_lock);
-               return PTR_ERR(data_buf);
-       }
-
-       memcpy(context->tx.data_buf, data_buf, n_bytes);
-
-       /* Pad with spaces */
-       for (i = n_bytes; i < IMON_DATA_BUF_SZ - 3; ++i)
-               context->tx.data_buf[i] = ' ';
-
-       for (i = IMON_DATA_BUF_SZ - 3; i < IMON_DATA_BUF_SZ; ++i)
-               context->tx.data_buf[i] = 0xFF;
-
-       offset = 0;
-       seq = 0;
-
-       do {
-               memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7);
-               context->usb_tx_buf[7] = (unsigned char)seq;
-
-               retval = send_packet(context);
-               if (retval) {
-                       dev_err(&context->usbdev->dev,
-                               "send packet failed for packet #%d\n",
-                               seq / 2);
-                       goto exit;
-               } else {
-                       seq += 2;
-                       offset += 7;
-               }
-
-       } while (offset < IMON_DATA_BUF_SZ);
-
-       if (context->vfd_proto_6p) {
-               /* Send packet #6 */
-               memcpy(context->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
-               context->usb_tx_buf[7] = (unsigned char)seq;
-               retval = send_packet(context);
-               if (retval)
-                       dev_err(&context->usbdev->dev,
-                               "send packet failed for packet #%d\n",
-                               seq / 2);
-       }
-
-exit:
-       mutex_unlock(&context->ctx_lock);
-       kfree(data_buf);
-
-       return (!retval) ? n_bytes : retval;
-}
-
-/**
- * Callback function for USB core API: transmit data
- */
-static void usb_tx_callback(struct urb *urb)
-{
-       struct imon_context *context;
-
-       if (!urb)
-               return;
-       context = (struct imon_context *)urb->context;
-       if (!context)
-               return;
-
-       context->tx.status = urb->status;
-
-       /* notify waiters that write has finished */
-       atomic_set(&context->tx.busy, 0);
-       complete(&context->tx.finished);
-}
-
-/**
- * Called by lirc_dev when the application opens /dev/lirc
- */
-static int ir_open(void *data)
-{
-       struct imon_context *context;
-
-       /* prevent races with disconnect */
-       mutex_lock(&driver_lock);
-
-       context = data;
-
-       /* initial IR protocol decode variables */
-       context->rx.count = 0;
-       context->rx.initial_space = 1;
-       context->rx.prev_bit = 0;
-
-       init_completion(&context->tx.finished);
-
-       context->ir_isopen = 1;
-       dev_info(context->driver->dev, "IR port opened\n");
-
-       mutex_unlock(&driver_lock);
-       return 0;
-}
-
-/**
- * Called by lirc_dev when the application closes /dev/lirc
- */
-static void ir_close(void *data)
-{
-       struct imon_context *context;
-
-       context = data;
-       if (!context) {
-               pr_err("%s: no context for device\n", __func__);
-               return;
-       }
-
-       mutex_lock(&context->ctx_lock);
-
-       context->ir_isopen = 0;
-       dev_info(context->driver->dev, "IR port closed\n");
-
-       if (!context->dev_present) {
-               /*
-                * Device disconnected while IR port was still open. Driver
-                * was not deregistered at disconnect time, so do it now.
-                */
-               deregister_from_lirc(context);
-
-               if (!context->display_isopen) {
-                       mutex_unlock(&context->ctx_lock);
-                       free_imon_context(context);
-                       return;
-               }
-               /*
-                * If display port is open, context will be deleted by
-                * display_close
-                */
-       }
-
-       mutex_unlock(&context->ctx_lock);
-}
-
-/**
- * Convert bit count to time duration (in us) and submit
- * the value to lirc_dev.
- */
-static void submit_data(struct imon_context *context)
-{
-       unsigned char buf[4];
-       int value = context->rx.count;
-       int i;
-
-       dev_dbg(context->driver->dev, "submitting data to LIRC\n");
-
-       value *= BIT_DURATION;
-       value &= PULSE_MASK;
-       if (context->rx.prev_bit)
-               value |= PULSE_BIT;
-
-       for (i = 0; i < 4; ++i)
-               buf[i] = value >> (i * 8);
-
-       lirc_buffer_write(context->driver->rbuf, buf);
-       wake_up(&context->driver->rbuf->wait_poll);
-}
-
-/**
- * Process the incoming packet
- */
-static void imon_incoming_packet(struct imon_context *context,
-                                struct urb *urb, int intf)
-{
-       int len = urb->actual_length;
-       unsigned char *buf = urb->transfer_buffer;
-       struct device *dev = context->driver->dev;
-       int octet, bit;
-       unsigned char mask;
-
-       /*
-        * just bail out if no listening IR client
-        */
-       if (!context->ir_isopen)
-               return;
-
-       if (len != 8) {
-               dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n",
-                        __func__, len, intf);
-               return;
-       }
-
-       if (debug)
-               dev_info(dev, "raw packet: %*ph\n", len, buf);
-       /*
-        * Translate received data to pulse and space lengths.
-        * Received data is active low, i.e. pulses are 0 and
-        * spaces are 1.
-        *
-        * My original algorithm was essentially similar to
-        * Changwoo Ryu's with the exception that he switched
-        * the incoming bits to active high and also fed an
-        * initial space to LIRC at the start of a new sequence
-        * if the previous bit was a pulse.
-        *
-        * I've decided to adopt his algorithm.
-        */
-
-       if (buf[7] == 1 && context->rx.initial_space) {
-               /* LIRC requires a leading space */
-               context->rx.prev_bit = 0;
-               context->rx.count = 4;
-               submit_data(context);
-               context->rx.count = 0;
-       }
-
-       for (octet = 0; octet < 5; ++octet) {
-               mask = 0x80;
-               for (bit = 0; bit < 8; ++bit) {
-                       int curr_bit = !(buf[octet] & mask);
-
-                       if (curr_bit != context->rx.prev_bit) {
-                               if (context->rx.count) {
-                                       submit_data(context);
-                                       context->rx.count = 0;
-                               }
-                               context->rx.prev_bit = curr_bit;
-                       }
-                       ++context->rx.count;
-                       mask >>= 1;
-               }
-       }
-
-       if (buf[7] == 10) {
-               if (context->rx.count) {
-                       submit_data(context);
-                       context->rx.count = 0;
-               }
-               context->rx.initial_space = context->rx.prev_bit;
-       }
-}
-
-/**
- * Callback function for USB core API: receive data
- */
-static void usb_rx_callback(struct urb *urb)
-{
-       struct imon_context *context;
-       int intfnum = 0;
-
-       if (!urb)
-               return;
-
-       context = (struct imon_context *)urb->context;
-       if (!context)
-               return;
-
-       switch (urb->status) {
-       case -ENOENT:           /* usbcore unlink successful! */
-               return;
-
-       case 0:
-               imon_incoming_packet(context, urb, intfnum);
-               break;
-
-       default:
-               dev_warn(context->driver->dev, "imon %s: status(%d): ignored\n",
-                        __func__, urb->status);
-               break;
-       }
-
-       usb_submit_urb(context->rx_urb, GFP_ATOMIC);
-}
-
-/**
- * Callback function for USB core API: Probe
- */
-static int imon_probe(struct usb_interface *interface,
-                     const struct usb_device_id *id)
-{
-       struct usb_device *usbdev = NULL;
-       struct usb_host_interface *iface_desc = NULL;
-       struct usb_endpoint_descriptor *rx_endpoint = NULL;
-       struct usb_endpoint_descriptor *tx_endpoint = NULL;
-       struct urb *rx_urb = NULL;
-       struct urb *tx_urb = NULL;
-       struct lirc_driver *driver = NULL;
-       struct lirc_buffer *rbuf = NULL;
-       struct device *dev = &interface->dev;
-       int ifnum;
-       int lirc_minor = 0;
-       int num_endpts;
-       int retval = -ENOMEM;
-       int display_ep_found = 0;
-       int ir_ep_found = 0;
-       int vfd_proto_6p = 0;
-       struct imon_context *context = NULL;
-       int i;
-       u16 vendor, product;
-
-       /* prevent races probing devices w/multiple interfaces */
-       mutex_lock(&driver_lock);
-
-       context = kzalloc(sizeof(*context), GFP_KERNEL);
-       if (!context)
-               goto driver_unlock;
-
-       /*
-        * Try to auto-detect the type of display if the user hasn't set
-        * it by hand via the display_type modparam. Default is VFD.
-        */
-       if (usb_match_id(interface, ir_only_list))
-               context->display = 0;
-       else
-               context->display = 1;
-
-       usbdev     = usb_get_dev(interface_to_usbdev(interface));
-       iface_desc = interface->cur_altsetting;
-       num_endpts = iface_desc->desc.bNumEndpoints;
-       ifnum      = iface_desc->desc.bInterfaceNumber;
-       vendor     = le16_to_cpu(usbdev->descriptor.idVendor);
-       product    = le16_to_cpu(usbdev->descriptor.idProduct);
-
-       dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
-               __func__, vendor, product, ifnum);
-
-       /*
-        * Scan the endpoint list and set:
-        *      first input endpoint = IR endpoint
-        *      first output endpoint = display endpoint
-        */
-       for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
-               struct usb_endpoint_descriptor *ep;
-               int ep_dir;
-               int ep_type;
-
-               ep = &iface_desc->endpoint[i].desc;
-               ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
-               ep_type = usb_endpoint_type(ep);
-
-               if (!ir_ep_found &&
-                       ep_dir == USB_DIR_IN &&
-                       ep_type == USB_ENDPOINT_XFER_INT) {
-
-                       rx_endpoint = ep;
-                       ir_ep_found = 1;
-                       dev_dbg(dev, "%s: found IR endpoint\n", __func__);
-
-               } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
-                          ep_type == USB_ENDPOINT_XFER_INT) {
-                       tx_endpoint = ep;
-                       display_ep_found = 1;
-                       dev_dbg(dev, "%s: found display endpoint\n", __func__);
-               }
-       }
-
-       /*
-        * Some iMON receivers have no display. Unfortunately, it seems
-        * that SoundGraph recycles device IDs between devices both with
-        * and without... :\
-        */
-       if (context->display == 0) {
-               display_ep_found = 0;
-               dev_dbg(dev, "%s: device has no display\n", __func__);
-       }
-
-       /* Input endpoint is mandatory */
-       if (!ir_ep_found) {
-               dev_err(dev, "%s: no valid input (IR) endpoint found.\n",
-                       __func__);
-               retval = -ENODEV;
-               goto free_context;
-       }
-
-       /* Determine if display requires 6 packets */
-       if (display_ep_found) {
-               if (usb_match_id(interface, vfd_proto_6p_list))
-                       vfd_proto_6p = 1;
-
-               dev_dbg(dev, "%s: vfd_proto_6p: %d\n",
-                       __func__, vfd_proto_6p);
-       }
-
-       driver = kzalloc(sizeof(*driver), GFP_KERNEL);
-       if (!driver)
-               goto free_context;
-
-       rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL);
-       if (!rbuf)
-               goto free_driver;
-
-       if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
-               dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
-               goto free_rbuf;
-       }
-       rx_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!rx_urb)
-               goto free_lirc_buf;
-       tx_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!tx_urb)
-               goto free_rx_urb;
-
-       mutex_init(&context->ctx_lock);
-       context->vfd_proto_6p = vfd_proto_6p;
-
-       strcpy(driver->name, MOD_NAME);
-       driver->minor = -1;
-       driver->code_length = BUF_CHUNK_SIZE * 8;
-       driver->sample_rate = 0;
-       driver->features = LIRC_CAN_REC_MODE2;
-       driver->data = context;
-       driver->rbuf = rbuf;
-       driver->set_use_inc = ir_open;
-       driver->set_use_dec = ir_close;
-       driver->dev = &interface->dev;
-       driver->owner = THIS_MODULE;
-
-       mutex_lock(&context->ctx_lock);
-
-       context->driver = driver;
-       /* start out in keyboard mode */
-
-       lirc_minor = lirc_register_driver(driver);
-       if (lirc_minor < 0) {
-               dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
-               goto free_tx_urb;
-       }
-
-       dev_info(dev, "Registered iMON driver (lirc minor: %d)\n",
-                lirc_minor);
-
-       /* Needed while unregistering! */
-       driver->minor = lirc_minor;
-
-       context->usbdev = usbdev;
-       context->dev_present = 1;
-       context->rx_endpoint = rx_endpoint;
-       context->rx_urb = rx_urb;
-
-       /*
-        * tx is used to send characters to lcd/vfd, associate RF
-        * remotes, set IR protocol, and maybe more...
-        */
-       context->tx_endpoint = tx_endpoint;
-       context->tx_urb = tx_urb;
-
-       if (display_ep_found)
-               context->display = 1;
-
-       usb_fill_int_urb(context->rx_urb, context->usbdev,
-                        usb_rcvintpipe(context->usbdev,
-                        context->rx_endpoint->bEndpointAddress),
-               context->usb_rx_buf, sizeof(context->usb_rx_buf),
-               usb_rx_callback, context,
-               context->rx_endpoint->bInterval);
-
-       retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
-       if (retval) {
-               dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval);
-               goto unregister_lirc;
-       }
-
-       usb_set_intfdata(interface, context);
-
-       if (context->display && ifnum == 0) {
-               dev_dbg(dev, "%s: Registering iMON display with sysfs\n",
-                       __func__);
-
-               if (usb_register_dev(interface, &imon_class)) {
-                       /* Not a fatal error, so ignore */
-                       dev_info(dev, "%s: could not get a minor number for display\n",
-                                __func__);
-               }
-       }
-
-       dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n",
-                vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
-
-       /* Everything went fine. Just unlock and return retval (with is 0) */
-       mutex_unlock(&context->ctx_lock);
-       goto driver_unlock;
-
-unregister_lirc:
-       lirc_unregister_driver(driver->minor);
-
-free_tx_urb:
-       mutex_unlock(&context->ctx_lock);
-       usb_free_urb(tx_urb);
-
-free_rx_urb:
-       usb_free_urb(rx_urb);
-
-free_lirc_buf:
-       lirc_buffer_free(rbuf);
-
-free_rbuf:
-       kfree(rbuf);
-
-free_driver:
-       kfree(driver);
-free_context:
-       kfree(context);
-       context = NULL;
-
-driver_unlock:
-       mutex_unlock(&driver_lock);
-
-       return retval;
-}
-
-/**
- * Callback function for USB core API: disconnect
- */
-static void imon_disconnect(struct usb_interface *interface)
-{
-       struct imon_context *context;
-       int ifnum;
-
-       /* prevent races with ir_open()/display_open() */
-       mutex_lock(&driver_lock);
-
-       context = usb_get_intfdata(interface);
-       ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
-
-       mutex_lock(&context->ctx_lock);
-
-       usb_set_intfdata(interface, NULL);
-
-       /* Abort ongoing write */
-       if (atomic_read(&context->tx.busy)) {
-               usb_kill_urb(context->tx_urb);
-               complete(&context->tx.finished);
-       }
-
-       context->dev_present = 0;
-       usb_kill_urb(context->rx_urb);
-       if (context->display)
-               usb_deregister_dev(interface, &imon_class);
-
-       if (!context->ir_isopen && !context->dev_present) {
-               deregister_from_lirc(context);
-               mutex_unlock(&context->ctx_lock);
-               if (!context->display_isopen)
-                       free_imon_context(context);
-       } else
-               mutex_unlock(&context->ctx_lock);
-
-       mutex_unlock(&driver_lock);
-
-       dev_info(&interface->dev, "%s: iMON device (intf%d) disconnected\n",
-                __func__, ifnum);
-}
-
-static int imon_suspend(struct usb_interface *intf, pm_message_t message)
-{
-       struct imon_context *context = usb_get_intfdata(intf);
-
-       usb_kill_urb(context->rx_urb);
-
-       return 0;
-}
-
-static int imon_resume(struct usb_interface *intf)
-{
-       struct imon_context *context = usb_get_intfdata(intf);
-
-       usb_fill_int_urb(context->rx_urb, context->usbdev,
-                        usb_rcvintpipe(context->usbdev,
-                        context->rx_endpoint->bEndpointAddress),
-               context->usb_rx_buf, sizeof(context->usb_rx_buf),
-               usb_rx_callback, context,
-               context->rx_endpoint->bInterval);
-
-       return usb_submit_urb(context->rx_urb, GFP_ATOMIC);
-}
-
-module_usb_driver(imon_driver);
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
deleted file mode 100644 (file)
index bfb76a4..0000000
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * lirc_parallel.c
- *
- * lirc_parallel - device driver for infra-red signal receiving and
- *                 transmitting unit built by the author
- *
- * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-/*** Includes ***/
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/ktime.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/uaccess.h>
-#include <asm/div64.h>
-
-#include <linux/poll.h>
-#include <linux/parport.h>
-#include <linux/platform_device.h>
-
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
-
-#include "lirc_parallel.h"
-
-#define LIRC_DRIVER_NAME "lirc_parallel"
-
-#ifndef LIRC_IRQ
-#define LIRC_IRQ 7
-#endif
-#ifndef LIRC_PORT
-#define LIRC_PORT 0x378
-#endif
-#ifndef LIRC_TIMER
-#define LIRC_TIMER 65536
-#endif
-
-/*** Global Variables ***/
-
-static bool debug;
-static bool check_pselecd;
-
-static unsigned int irq = LIRC_IRQ;
-static unsigned int io = LIRC_PORT;
-#ifdef LIRC_TIMER
-static unsigned int timer;
-static unsigned int default_timer = LIRC_TIMER;
-#endif
-
-#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
-
-static int rbuf[RBUF_SIZE];
-
-static DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
-
-static unsigned int rptr;
-static unsigned int wptr;
-static unsigned int lost_irqs;
-static int is_open;
-
-static struct parport *pport;
-static struct pardevice *ppdevice;
-static int is_claimed;
-
-static unsigned int tx_mask = 1;
-
-/*** Internal Functions ***/
-
-static unsigned int in(int offset)
-{
-       switch (offset) {
-       case LIRC_LP_BASE:
-               return parport_read_data(pport);
-       case LIRC_LP_STATUS:
-               return parport_read_status(pport);
-       case LIRC_LP_CONTROL:
-               return parport_read_control(pport);
-       }
-       return 0; /* make compiler happy */
-}
-
-static void out(int offset, int value)
-{
-       switch (offset) {
-       case LIRC_LP_BASE:
-               parport_write_data(pport, value);
-               break;
-       case LIRC_LP_CONTROL:
-               parport_write_control(pport, value);
-               break;
-       case LIRC_LP_STATUS:
-               pr_info("attempt to write to status register\n");
-               break;
-       }
-}
-
-static unsigned int lirc_get_timer(void)
-{
-       return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
-}
-
-static unsigned int lirc_get_signal(void)
-{
-       return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
-}
-
-static void lirc_on(void)
-{
-       out(LIRC_PORT_DATA, tx_mask);
-}
-
-static void lirc_off(void)
-{
-       out(LIRC_PORT_DATA, 0);
-}
-
-static unsigned int init_lirc_timer(void)
-{
-       ktime_t kt, now, timeout;
-       unsigned int level, newlevel, timeelapsed, newtimer;
-       int count = 0;
-
-       kt = ktime_get();
-       /* wait max. 1 sec. */
-       timeout = ktime_add_ns(kt, NSEC_PER_SEC);
-       level = lirc_get_timer();
-       do {
-               newlevel = lirc_get_timer();
-               if (level == 0 && newlevel != 0)
-                       count++;
-               level = newlevel;
-               now = ktime_get();
-       } while (count < 1000 && (ktime_before(now, timeout)));
-       timeelapsed = ktime_us_delta(now, kt);
-       if (count >= 1000 && timeelapsed > 0) {
-               if (default_timer == 0) {
-                       /* autodetect timer */
-                       newtimer = (1000000 * count) / timeelapsed;
-                       pr_info("%u Hz timer detected\n", newtimer);
-                       return newtimer;
-               }
-               newtimer = (1000000 * count) / timeelapsed;
-               if (abs(newtimer - default_timer) > default_timer / 10) {
-                       /* bad timer */
-                       pr_notice("bad timer: %u Hz\n", newtimer);
-                       pr_notice("using default timer: %u Hz\n",
-                                 default_timer);
-                       return default_timer;
-               }
-               pr_info("%u Hz timer detected\n", newtimer);
-               return newtimer; /* use detected value */
-       }
-
-       pr_notice("no timer detected\n");
-       return 0;
-}
-
-static int lirc_claim(void)
-{
-       if (parport_claim(ppdevice) != 0) {
-               pr_warn("could not claim port\n");
-               pr_warn("waiting for port becoming available\n");
-               if (parport_claim_or_block(ppdevice) < 0) {
-                       pr_notice("could not claim port, giving up\n");
-                       return 0;
-               }
-       }
-       out(LIRC_LP_CONTROL, LP_PSELECP | LP_PINITP);
-       is_claimed = 1;
-       return 1;
-}
-
-/*** interrupt handler ***/
-
-static void rbuf_write(int signal)
-{
-       unsigned int nwptr;
-
-       nwptr = (wptr + 1) & (RBUF_SIZE - 1);
-       if (nwptr == rptr) {
-               /* no new signals will be accepted */
-               lost_irqs++;
-               pr_notice("buffer overrun\n");
-               return;
-       }
-       rbuf[wptr] = signal;
-       wptr = nwptr;
-}
-
-static void lirc_lirc_irq_handler(void *blah)
-{
-       ktime_t kt, delkt;
-       static ktime_t lastkt;
-       static int init;
-       long signal;
-       int data;
-       unsigned int level, newlevel;
-       unsigned int timeout;
-
-       if (!is_open)
-               return;
-
-       if (!is_claimed)
-               return;
-
-#if 0
-       /* disable interrupt */
-         disable_irq(irq);
-         out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN));
-#endif
-       if (check_pselecd && (in(1) & LP_PSELECD))
-               return;
-
-#ifdef LIRC_TIMER
-       if (init) {
-               kt = ktime_get();
-
-               delkt = ktime_sub(kt, lastkt);
-               if (ktime_compare(delkt, ktime_set(15, 0)) > 0)
-                       /* really long time */
-                       data = PULSE_MASK;
-               else
-                       data = (int)(ktime_to_us(delkt) + LIRC_SFH506_DELAY);
-
-               rbuf_write(data); /* space */
-       } else {
-               if (timer == 0) {
-                       /*
-                        * wake up; we'll lose this signal, but it will be
-                        * garbage if the device is turned on anyway
-                        */
-                       timer = init_lirc_timer();
-                       /* enable_irq(irq); */
-                       return;
-               }
-               init = 1;
-       }
-
-       timeout = timer / 10;   /* timeout after 1/10 sec. */
-       signal = 1;
-       level = lirc_get_timer();
-       do {
-               newlevel = lirc_get_timer();
-               if (level == 0 && newlevel != 0)
-                       signal++;
-               level = newlevel;
-
-               /* giving up */
-               if (signal > timeout
-                   || (check_pselecd && (in(1) & LP_PSELECD))) {
-                       signal = 0;
-                       pr_notice("timeout\n");
-                       break;
-               }
-       } while (lirc_get_signal());
-
-       if (signal != 0) {
-               /* adjust value to usecs */
-               __u64 helper;
-
-               helper = ((__u64)signal) * 1000000;
-               do_div(helper, timer);
-               signal = (long)helper;
-
-               if (signal > LIRC_SFH506_DELAY)
-                       data = signal - LIRC_SFH506_DELAY;
-               else
-                       data = 1;
-               rbuf_write(PULSE_BIT | data); /* pulse */
-       }
-       lastkt = ktime_get();
-#else
-       /* add your code here */
-#endif
-
-       wake_up_interruptible(&lirc_wait);
-
-       /* enable interrupt */
-       /*
-        * enable_irq(irq);
-        * out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
-        */
-}
-
-/*** file operations ***/
-
-static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
-{
-       return -ESPIPE;
-}
-
-static ssize_t lirc_read(struct file *filep, char __user *buf, size_t n,
-                        loff_t *ppos)
-{
-       int result = 0;
-       int count = 0;
-       DECLARE_WAITQUEUE(wait, current);
-
-       if (n % sizeof(int))
-               return -EINVAL;
-
-       add_wait_queue(&lirc_wait, &wait);
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (count < n) {
-               if (rptr != wptr) {
-                       if (copy_to_user(buf + count, &rbuf[rptr],
-                                        sizeof(int))) {
-                               result = -EFAULT;
-                               break;
-                       }
-                       rptr = (rptr + 1) & (RBUF_SIZE - 1);
-                       count += sizeof(int);
-               } else {
-                       if (filep->f_flags & O_NONBLOCK) {
-                               result = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               result = -ERESTARTSYS;
-                               break;
-                       }
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-               }
-       }
-       remove_wait_queue(&lirc_wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return count ? count : result;
-}
-
-static ssize_t lirc_write(struct file *filep, const char __user *buf, size_t n,
-                         loff_t *ppos)
-{
-       int count;
-       unsigned int i;
-       unsigned int level, newlevel;
-       unsigned long flags;
-       int counttimer;
-       int *wbuf;
-       ssize_t ret;
-
-       if (!is_claimed)
-               return -EBUSY;
-
-       count = n / sizeof(int);
-
-       if (n % sizeof(int) || count % 2 == 0)
-               return -EINVAL;
-
-       wbuf = memdup_user(buf, n);
-       if (IS_ERR(wbuf))
-               return PTR_ERR(wbuf);
-
-#ifdef LIRC_TIMER
-       if (timer == 0) {
-               /* try again if device is ready */
-               timer = init_lirc_timer();
-               if (timer == 0) {
-                       ret = -EIO;
-                       goto out;
-               }
-       }
-
-       /* adjust values from usecs */
-       for (i = 0; i < count; i++) {
-               __u64 helper;
-
-               helper = ((__u64)wbuf[i]) * timer;
-               do_div(helper, 1000000);
-               wbuf[i] = (int)helper;
-       }
-
-       local_irq_save(flags);
-       i = 0;
-       while (i < count) {
-               level = lirc_get_timer();
-               counttimer = 0;
-               lirc_on();
-               do {
-                       newlevel = lirc_get_timer();
-                       if (level == 0 && newlevel != 0)
-                               counttimer++;
-                       level = newlevel;
-                       if (check_pselecd && (in(1) & LP_PSELECD)) {
-                               lirc_off();
-                               local_irq_restore(flags);
-                               ret = -EIO;
-                               goto out;
-                       }
-               } while (counttimer < wbuf[i]);
-               i++;
-
-               lirc_off();
-               if (i == count)
-                       break;
-               counttimer = 0;
-               do {
-                       newlevel = lirc_get_timer();
-                       if (level == 0 && newlevel != 0)
-                               counttimer++;
-                       level = newlevel;
-                       if (check_pselecd && (in(1) & LP_PSELECD)) {
-                               local_irq_restore(flags);
-                               ret = -EIO;
-                               goto out;
-                       }
-               } while (counttimer < wbuf[i]);
-               i++;
-       }
-       local_irq_restore(flags);
-#else
-       /* place code that handles write without external timer here */
-#endif
-       ret = n;
-out:
-       kfree(wbuf);
-
-       return ret;
-}
-
-static unsigned int lirc_poll(struct file *file, poll_table *wait)
-{
-       poll_wait(file, &lirc_wait, wait);
-       if (rptr != wptr)
-               return POLLIN | POLLRDNORM;
-       return 0;
-}
-
-static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-{
-       int result;
-       u32 __user *uptr = (u32 __user *)arg;
-       u32 features = LIRC_CAN_SET_TRANSMITTER_MASK |
-                      LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
-       u32 mode;
-       u32 value;
-
-       switch (cmd) {
-       case LIRC_GET_FEATURES:
-               result = put_user(features, uptr);
-               if (result)
-                       return result;
-               break;
-       case LIRC_GET_SEND_MODE:
-               result = put_user(LIRC_MODE_PULSE, uptr);
-               if (result)
-                       return result;
-               break;
-       case LIRC_GET_REC_MODE:
-               result = put_user(LIRC_MODE_MODE2, uptr);
-               if (result)
-                       return result;
-               break;
-       case LIRC_SET_SEND_MODE:
-               result = get_user(mode, uptr);
-               if (result)
-                       return result;
-               if (mode != LIRC_MODE_PULSE)
-                       return -EINVAL;
-               break;
-       case LIRC_SET_REC_MODE:
-               result = get_user(mode, uptr);
-               if (result)
-                       return result;
-               if (mode != LIRC_MODE_MODE2)
-                       return -ENOSYS;
-               break;
-       case LIRC_SET_TRANSMITTER_MASK:
-               result = get_user(value, uptr);
-               if (result)
-                       return result;
-               if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
-                       return LIRC_PARALLEL_MAX_TRANSMITTERS;
-               tx_mask = value;
-               break;
-       default:
-               return -ENOIOCTLCMD;
-       }
-       return 0;
-}
-
-static int lirc_open(struct inode *node, struct file *filep)
-{
-       if (is_open || !lirc_claim())
-               return -EBUSY;
-
-       parport_enable_irq(pport);
-
-       /* init read ptr */
-       rptr = 0;
-       wptr = 0;
-       lost_irqs = 0;
-
-       is_open = 1;
-       return 0;
-}
-
-static int lirc_close(struct inode *node, struct file *filep)
-{
-       if (is_claimed) {
-               is_claimed = 0;
-               parport_release(ppdevice);
-       }
-       is_open = 0;
-       return 0;
-}
-
-static const struct file_operations lirc_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = lirc_lseek,
-       .read           = lirc_read,
-       .write          = lirc_write,
-       .poll           = lirc_poll,
-       .unlocked_ioctl = lirc_ioctl,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl   = lirc_ioctl,
-#endif
-       .open           = lirc_open,
-       .release        = lirc_close
-};
-
-static int set_use_inc(void *data)
-{
-       return 0;
-}
-
-static void set_use_dec(void *data)
-{
-}
-
-static struct lirc_driver driver = {
-       .name           = LIRC_DRIVER_NAME,
-       .minor          = -1,
-       .code_length    = 1,
-       .sample_rate    = 0,
-       .data           = NULL,
-       .add_to_buf     = NULL,
-       .set_use_inc    = set_use_inc,
-       .set_use_dec    = set_use_dec,
-       .fops           = &lirc_fops,
-       .dev            = NULL,
-       .owner          = THIS_MODULE,
-};
-
-static struct platform_device *lirc_parallel_dev;
-
-static int lirc_parallel_probe(struct platform_device *dev)
-{
-       return 0;
-}
-
-static int lirc_parallel_remove(struct platform_device *dev)
-{
-       return 0;
-}
-
-static int lirc_parallel_suspend(struct platform_device *dev,
-                                       pm_message_t state)
-{
-       return 0;
-}
-
-static int lirc_parallel_resume(struct platform_device *dev)
-{
-       return 0;
-}
-
-static struct platform_driver lirc_parallel_driver = {
-       .probe  = lirc_parallel_probe,
-       .remove = lirc_parallel_remove,
-       .suspend        = lirc_parallel_suspend,
-       .resume = lirc_parallel_resume,
-       .driver = {
-               .name   = LIRC_DRIVER_NAME,
-       },
-};
-
-static int pf(void *handle)
-{
-       parport_disable_irq(pport);
-       is_claimed = 0;
-       return 0;
-}
-
-static void kf(void *handle)
-{
-       if (!is_open)
-               return;
-       if (!lirc_claim())
-               return;
-       parport_enable_irq(pport);
-       lirc_off();
-       /* this is a bit annoying when you actually print...*/
-       /*
-        * printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
-       */
-}
-
-/*** module initialization and cleanup ***/
-
-static int __init lirc_parallel_init(void)
-{
-       int result;
-
-       result = platform_driver_register(&lirc_parallel_driver);
-       if (result) {
-               pr_notice("platform_driver_register returned %d\n", result);
-               return result;
-       }
-
-       lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
-       if (!lirc_parallel_dev) {
-               result = -ENOMEM;
-               goto exit_driver_unregister;
-       }
-
-       result = platform_device_add(lirc_parallel_dev);
-       if (result)
-               goto exit_device_put;
-
-       pport = parport_find_base(io);
-       if (!pport) {
-               pr_notice("no port at %x found\n", io);
-               result = -ENXIO;
-               goto exit_device_del;
-       }
-       ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
-                                          pf, kf, lirc_lirc_irq_handler, 0,
-                                          NULL);
-       parport_put_port(pport);
-       if (!ppdevice) {
-               pr_notice("parport_register_device() failed\n");
-               result = -ENXIO;
-               goto exit_device_del;
-       }
-       if (parport_claim(ppdevice) != 0)
-               goto skip_init;
-       is_claimed = 1;
-       out(LIRC_LP_CONTROL, LP_PSELECP | LP_PINITP);
-
-#ifdef LIRC_TIMER
-       if (debug)
-               out(LIRC_PORT_DATA, tx_mask);
-
-       timer = init_lirc_timer();
-
-#if 0  /* continue even if device is offline */
-       if (timer == 0) {
-               is_claimed = 0;
-               parport_release(pport);
-               parport_unregister_device(ppdevice);
-               result = -EIO;
-               goto exit_device_del;
-       }
-
-#endif
-       if (debug)
-               out(LIRC_PORT_DATA, 0);
-#endif
-
-       is_claimed = 0;
-       parport_release(ppdevice);
- skip_init:
-       driver.dev = &lirc_parallel_dev->dev;
-       driver.minor = lirc_register_driver(&driver);
-       if (driver.minor < 0) {
-               pr_notice("register_chrdev() failed\n");
-               parport_unregister_device(ppdevice);
-               result = -EIO;
-               goto exit_device_del;
-       }
-       pr_info("installed using port 0x%04x irq %d\n", io, irq);
-       return 0;
-
-exit_device_del:
-       platform_device_del(lirc_parallel_dev);
-exit_device_put:
-       platform_device_put(lirc_parallel_dev);
-exit_driver_unregister:
-       platform_driver_unregister(&lirc_parallel_driver);
-       return result;
-}
-
-static void __exit lirc_parallel_exit(void)
-{
-       parport_unregister_device(ppdevice);
-       lirc_unregister_driver(driver.minor);
-
-       platform_device_unregister(lirc_parallel_dev);
-       platform_driver_unregister(&lirc_parallel_driver);
-}
-
-module_init(lirc_parallel_init);
-module_exit(lirc_parallel_exit);
-
-MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
-MODULE_AUTHOR("Christoph Bartelmus");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, S_IRUGO);
-MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
-
-module_param(irq, int, S_IRUGO);
-MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
-
-module_param(tx_mask, int, S_IRUGO);
-MODULE_PARM_DESC(tx_mask, "Transmitter mask (default: 0x01)");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Enable debugging messages");
-
-module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(check_pselecd, "Check for printer (default: 0)");
diff --git a/drivers/staging/media/lirc/lirc_parallel.h b/drivers/staging/media/lirc/lirc_parallel.h
deleted file mode 100644 (file)
index 4bed6af..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* lirc_parallel.h */
-
-#ifndef _LIRC_PARALLEL_H
-#define _LIRC_PARALLEL_H
-
-#include <linux/lp.h>
-
-#define LIRC_PORT_LEN 3
-
-#define LIRC_LP_BASE    0
-#define LIRC_LP_STATUS  1
-#define LIRC_LP_CONTROL 2
-
-#define LIRC_PORT_DATA           LIRC_LP_BASE    /* base */
-#define LIRC_PORT_TIMER        LIRC_LP_STATUS    /* status port */
-#define LIRC_PORT_TIMER_BIT          LP_PBUSY    /* busy signal */
-#define LIRC_PORT_SIGNAL       LIRC_LP_STATUS    /* status port */
-#define LIRC_PORT_SIGNAL_BIT          LP_PACK    /* ack signal */
-#define LIRC_PORT_IRQ         LIRC_LP_CONTROL    /* control port */
-
-#define LIRC_SFH506_DELAY 0             /* delay t_phl in usecs */
-
-#define LIRC_PARALLEL_MAX_TRANSMITTERS 8
-#define LIRC_PARALLEL_TRANSMITTER_MASK ((1<<LIRC_PARALLEL_MAX_TRANSMITTERS) - 1)
-
-#endif
index 4f326e97ad75e9180b9013c0916fe2a2ad1747ab..c75ae43095ba55a7250fe504e579b3dde8016bf2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * LIRC SIR driver, (C) 2000 Milan Pikula <www@fornax.sk>
  *
- * lirc_sir - Device driver for use with SIR (serial infra red)
+ * sir_ir - Device driver for use with SIR (serial infra red)
  * mode of IrDA on many notebooks.
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -58,8 +58,7 @@
 
 #include <linux/timer.h>
 
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
+#include <media/rc-core.h>
 
 /* SECTION: Definitions */
 
@@ -87,11 +86,6 @@ static void init_act200(void);
 static void init_act220(void);
 #endif
 
-#define RBUF_LEN 1024
-#define WBUF_LEN 1024
-
-#define LIRC_DRIVER_NAME "lirc_sir"
-
 #define PULSE '['
 
 #ifndef LIRC_SIR_TEKRAM
@@ -131,28 +125,19 @@ static ktime_t last;
 /* time of last UART data ready interrupt */
 static ktime_t last_intr_time;
 static int last_value;
+static struct rc_dev *rcdev;
 
-static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
+static struct platform_device *sir_ir_dev;
 
 static DEFINE_SPINLOCK(hardware_lock);
 
-static int rx_buf[RBUF_LEN];
-static unsigned int rx_tail, rx_head;
-
 static bool debug;
 
 /* SECTION: Prototypes */
 
 /* Communication with user-space */
-static unsigned int lirc_poll(struct file *file, poll_table *wait);
-static ssize_t lirc_read(struct file *file, char __user *buf, size_t count,
-                        loff_t *ppos);
-static ssize_t lirc_write(struct file *file, const char __user *buf, size_t n,
-                         loff_t *pos);
-static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 static void add_read_queue(int flag, unsigned long val);
 static int init_chrdev(void);
-static void drop_chrdev(void);
 /* Hardware */
 static irqreturn_t sir_interrupt(int irq, void *dev_id);
 static void send_space(unsigned long len);
@@ -189,72 +174,14 @@ static void safe_udelay(unsigned long usecs)
 }
 
 /* SECTION: Communication with user-space */
-
-static unsigned int lirc_poll(struct file *file, poll_table *wait)
-{
-       poll_wait(file, &lirc_read_queue, wait);
-       if (rx_head != rx_tail)
-               return POLLIN | POLLRDNORM;
-       return 0;
-}
-
-static ssize_t lirc_read(struct file *file, char __user *buf, size_t count,
-                        loff_t *ppos)
-{
-       int n = 0;
-       int retval = 0;
-       DECLARE_WAITQUEUE(wait, current);
-
-       if (count % sizeof(int))
-               return -EINVAL;
-
-       add_wait_queue(&lirc_read_queue, &wait);
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (n < count) {
-               if (rx_head != rx_tail) {
-                       if (copy_to_user(buf + n,
-                                        rx_buf + rx_head,
-                                        sizeof(int))) {
-                               retval = -EFAULT;
-                               break;
-                       }
-                       rx_head = (rx_head + 1) & (RBUF_LEN - 1);
-                       n += sizeof(int);
-               } else {
-                       if (file->f_flags & O_NONBLOCK) {
-                               retval = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               retval = -ERESTARTSYS;
-                               break;
-                       }
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-               }
-       }
-       remove_wait_queue(&lirc_read_queue, &wait);
-       set_current_state(TASK_RUNNING);
-       return n ? n : retval;
-}
-static ssize_t lirc_write(struct file *file, const char __user *buf, size_t n,
-                         loff_t *pos)
+static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf,
+                    unsigned int count)
 {
        unsigned long flags;
-       int i, count;
-       int *tx_buf;
-
-       count = n / sizeof(int);
-       if (n % sizeof(int) || count % 2 == 0)
-               return -EINVAL;
-       tx_buf = memdup_user(buf, n);
-       if (IS_ERR(tx_buf))
-               return PTR_ERR(tx_buf);
-       i = 0;
+       int i;
+
        local_irq_save(flags);
-       while (1) {
-               if (i >= count)
-                       break;
+       for (i = 0; i < count;) {
                if (tx_buf[i])
                        send_pulse(tx_buf[i]);
                i++;
@@ -265,138 +192,53 @@ static ssize_t lirc_write(struct file *file, const char __user *buf, size_t n,
                i++;
        }
        local_irq_restore(flags);
-       kfree(tx_buf);
-       return count;
-}
-
-static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-{
-       u32 __user *uptr = (u32 __user *)arg;
-       int retval = 0;
-       u32 value = 0;
-
-       if (cmd == LIRC_GET_FEATURES)
-               value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
-       else if (cmd == LIRC_GET_SEND_MODE)
-               value = LIRC_MODE_PULSE;
-       else if (cmd == LIRC_GET_REC_MODE)
-               value = LIRC_MODE_MODE2;
-
-       switch (cmd) {
-       case LIRC_GET_FEATURES:
-       case LIRC_GET_SEND_MODE:
-       case LIRC_GET_REC_MODE:
-               retval = put_user(value, uptr);
-               break;
-
-       case LIRC_SET_SEND_MODE:
-       case LIRC_SET_REC_MODE:
-               retval = get_user(value, uptr);
-               break;
-       default:
-               retval = -ENOIOCTLCMD;
-
-       }
-
-       if (retval)
-               return retval;
-       if (cmd == LIRC_SET_REC_MODE) {
-               if (value != LIRC_MODE_MODE2)
-                       retval = -ENOSYS;
-       } else if (cmd == LIRC_SET_SEND_MODE) {
-               if (value != LIRC_MODE_PULSE)
-                       retval = -ENOSYS;
-       }
 
-       return retval;
+       return count;
 }
 
 static void add_read_queue(int flag, unsigned long val)
 {
-       unsigned int new_rx_tail;
-       int newval;
+       DEFINE_IR_RAW_EVENT(ev);
 
        pr_debug("add flag %d with val %lu\n", flag, val);
 
-       newval = val & PULSE_MASK;
-
        /*
         * statistically, pulses are ~TIME_CONST/2 too long. we could
         * maybe make this more exact, but this is good enough
         */
        if (flag) {
                /* pulse */
-               if (newval > TIME_CONST/2)
-                       newval -= TIME_CONST/2;
+               if (val > TIME_CONST / 2)
+                       val -= TIME_CONST / 2;
                else /* should not ever happen */
-                       newval = 1;
-               newval |= PULSE_BIT;
+                       val = 1;
+               ev.pulse = true;
        } else {
-               newval += TIME_CONST/2;
+               val += TIME_CONST / 2;
        }
-       new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
-       if (new_rx_tail == rx_head) {
-               pr_debug("Buffer overrun.\n");
-               return;
-       }
-       rx_buf[rx_tail] = newval;
-       rx_tail = new_rx_tail;
-       wake_up_interruptible(&lirc_read_queue);
-}
+       ev.duration = US_TO_NS(val);
 
-static const struct file_operations lirc_fops = {
-       .owner          = THIS_MODULE,
-       .read           = lirc_read,
-       .write          = lirc_write,
-       .poll           = lirc_poll,
-       .unlocked_ioctl = lirc_ioctl,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl   = lirc_ioctl,
-#endif
-       .open           = lirc_dev_fop_open,
-       .release        = lirc_dev_fop_close,
-       .llseek         = no_llseek,
-};
-
-static int set_use_inc(void *data)
-{
-       return 0;
+       ir_raw_event_store_with_filter(rcdev, &ev);
 }
 
-static void set_use_dec(void *data)
-{
-}
-
-static struct lirc_driver driver = {
-       .name           = LIRC_DRIVER_NAME,
-       .minor          = -1,
-       .code_length    = 1,
-       .sample_rate    = 0,
-       .data           = NULL,
-       .add_to_buf     = NULL,
-       .set_use_inc    = set_use_inc,
-       .set_use_dec    = set_use_dec,
-       .fops           = &lirc_fops,
-       .dev            = NULL,
-       .owner          = THIS_MODULE,
-};
-
-static struct platform_device *lirc_sir_dev;
-
 static int init_chrdev(void)
 {
-       driver.dev = &lirc_sir_dev->dev;
-       driver.minor = lirc_register_driver(&driver);
-       if (driver.minor < 0) {
-               pr_err("init_chrdev() failed.\n");
-               return -EIO;
-       }
-       return 0;
-}
-
-static void drop_chrdev(void)
-{
-       lirc_unregister_driver(driver.minor);
+       rcdev = devm_rc_allocate_device(&sir_ir_dev->dev, RC_DRIVER_IR_RAW);
+       if (!rcdev)
+               return -ENOMEM;
+
+       rcdev->input_phys = KBUILD_MODNAME "/input0";
+       rcdev->input_id.bustype = BUS_HOST;
+       rcdev->input_id.vendor = 0x0001;
+       rcdev->input_id.product = 0x0001;
+       rcdev->input_id.version = 0x0100;
+       rcdev->tx_ir = sir_tx_ir;
+       rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
+       rcdev->map_name = RC_MAP_RC6_MCE;
+       rcdev->timeout = IR_DEFAULT_TIMEOUT;
+       rcdev->dev.parent = &sir_ir_dev->dev;
+
+       return devm_rc_register_device(&sir_ir_dev->dev, rcdev);
 }
 
 /* SECTION: Hardware */
@@ -420,14 +262,15 @@ static void sir_timeout(unsigned long data)
                /* determine 'virtual' pulse end: */
                pulse_end = min_t(unsigned long,
                                  ktime_us_delta(last, last_intr_time),
-                                 PULSE_MASK);
-               dev_dbg(driver.dev, "timeout add %d for %lu usec\n",
-                                   last_value, pulse_end);
+                                 IR_MAX_DURATION);
+               dev_dbg(&sir_ir_dev->dev, "timeout add %d for %lu usec\n",
+                       last_value, pulse_end);
                add_read_queue(last_value, pulse_end);
                last_value = 0;
                last = last_intr_time;
        }
        spin_unlock_irqrestore(&timer_lock, flags);
+       ir_raw_event_handle(rcdev);
 }
 
 static irqreturn_t sir_interrupt(int irq, void *dev_id)
@@ -462,20 +305,20 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id)
                                curr_time = ktime_get();
                                delt = min_t(unsigned long,
                                             ktime_us_delta(last, curr_time),
-                                            PULSE_MASK);
+                                            IR_MAX_DURATION);
                                deltintr = min_t(unsigned long,
                                                 ktime_us_delta(last_intr_time,
                                                                curr_time),
-                                                PULSE_MASK);
-                               dev_dbg(driver.dev, "t %lu, d %d\n",
-                                                   deltintr, (int)data);
+                                                IR_MAX_DURATION);
+                               dev_dbg(&sir_ir_dev->dev, "t %lu, d %d\n",
+                                       deltintr, (int)data);
                                /*
                                 * if nothing came in last X cycles,
                                 * it was gap
                                 */
                                if (deltintr > TIME_CONST * threshold) {
                                        if (last_value) {
-                                               dev_dbg(driver.dev, "GAP\n");
+                                               dev_dbg(&sir_ir_dev->dev, "GAP\n");
                                                /* simulate signal change */
                                                add_read_queue(last_value,
                                                               delt -
@@ -517,6 +360,7 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id)
                        break;
                }
        }
+       ir_raw_event_handle(rcdev);
        return IRQ_RETVAL(IRQ_HANDLED);
 }
 
@@ -655,12 +499,12 @@ static int init_port(void)
        int retval;
 
        /* get I/O port access and IRQ line */
-       if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) {
+       if (!request_region(io, 8, KBUILD_MODNAME)) {
                pr_err("i/o port 0x%.4x already in use.\n", io);
                return -EBUSY;
        }
        retval = request_irq(irq, sir_interrupt, 0,
-                            LIRC_DRIVER_NAME, NULL);
+                            KBUILD_MODNAME, NULL);
        if (retval < 0) {
                release_region(io, 8);
                pr_err("IRQ %d already in use.\n", irq);
@@ -882,11 +726,10 @@ void init_act220(void)
 }
 #endif
 
-static int init_lirc_sir(void)
+static int init_sir_ir(void)
 {
        int retval;
 
-       init_waitqueue_head(&lirc_read_queue);
        retval = init_port();
        if (retval < 0)
                return retval;
@@ -895,42 +738,42 @@ static int init_lirc_sir(void)
        return 0;
 }
 
-static int lirc_sir_probe(struct platform_device *dev)
+static int sir_ir_probe(struct platform_device *dev)
 {
        return 0;
 }
 
-static int lirc_sir_remove(struct platform_device *dev)
+static int sir_ir_remove(struct platform_device *dev)
 {
        return 0;
 }
 
-static struct platform_driver lirc_sir_driver = {
-       .probe          = lirc_sir_probe,
-       .remove         = lirc_sir_remove,
+static struct platform_driver sir_ir_driver = {
+       .probe          = sir_ir_probe,
+       .remove         = sir_ir_remove,
        .driver         = {
-               .name   = "lirc_sir",
+               .name   = "sir_ir",
        },
 };
 
-static int __init lirc_sir_init(void)
+static int __init sir_ir_init(void)
 {
        int retval;
 
-       retval = platform_driver_register(&lirc_sir_driver);
+       retval = platform_driver_register(&sir_ir_driver);
        if (retval) {
                pr_err("Platform driver register failed!\n");
                return -ENODEV;
        }
 
-       lirc_sir_dev = platform_device_alloc("lirc_dev", 0);
-       if (!lirc_sir_dev) {
+       sir_ir_dev = platform_device_alloc("sir_ir", 0);
+       if (!sir_ir_dev) {
                pr_err("Platform device alloc failed!\n");
                retval = -ENOMEM;
                goto pdev_alloc_fail;
        }
 
-       retval = platform_device_add(lirc_sir_dev);
+       retval = platform_device_add(sir_ir_dev);
        if (retval) {
                pr_err("Platform device add failed!\n");
                retval = -ENODEV;
@@ -941,35 +784,32 @@ static int __init lirc_sir_init(void)
        if (retval < 0)
                goto fail;
 
-       retval = init_lirc_sir();
-       if (retval) {
-               drop_chrdev();
+       retval = init_sir_ir();
+       if (retval)
                goto fail;
-       }
 
        return 0;
 
 fail:
-       platform_device_del(lirc_sir_dev);
+       platform_device_del(sir_ir_dev);
 pdev_add_fail:
-       platform_device_put(lirc_sir_dev);
+       platform_device_put(sir_ir_dev);
 pdev_alloc_fail:
-       platform_driver_unregister(&lirc_sir_driver);
+       platform_driver_unregister(&sir_ir_driver);
        return retval;
 }
 
-static void __exit lirc_sir_exit(void)
+static void __exit sir_ir_exit(void)
 {
        drop_hardware();
-       drop_chrdev();
        drop_port();
-       platform_device_unregister(lirc_sir_dev);
-       platform_driver_unregister(&lirc_sir_driver);
+       platform_device_unregister(sir_ir_dev);
+       platform_driver_unregister(&sir_ir_driver);
        pr_info("Uninstalled.\n");
 }
 
-module_init(lirc_sir_init);
-module_exit(lirc_sir_exit);
+module_init(sir_ir_init);
+module_exit(sir_ir_exit);
 
 #ifdef LIRC_SIR_TEKRAM
 MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210");
index c16927ac8eb0b259ca1ece37da1043c53ecf279b..bb0e3b4a4558ab6f69da99891c77cadc634681a0 100644 (file)
@@ -205,21 +205,21 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad)
 static struct iss_video *
 iss_video_far_end(struct iss_video *video)
 {
-       struct media_entity_graph graph;
+       struct media_graph graph;
        struct media_entity *entity = &video->video.entity;
        struct media_device *mdev = entity->graph_obj.mdev;
        struct iss_video *far_end = NULL;
 
        mutex_lock(&mdev->graph_mutex);
 
-       if (media_entity_graph_walk_init(&graph, mdev)) {
+       if (media_graph_walk_init(&graph, mdev)) {
                mutex_unlock(&mdev->graph_mutex);
                return NULL;
        }
 
-       media_entity_graph_walk_start(&graph, entity);
+       media_graph_walk_start(&graph, entity);
 
-       while ((entity = media_entity_graph_walk_next(&graph))) {
+       while ((entity = media_graph_walk_next(&graph))) {
                if (entity == &video->video.entity)
                        continue;
 
@@ -235,7 +235,7 @@ iss_video_far_end(struct iss_video *video)
 
        mutex_unlock(&mdev->graph_mutex);
 
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
 
        return far_end;
 }
@@ -854,7 +854,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 {
        struct iss_video_fh *vfh = to_iss_video_fh(fh);
        struct iss_video *video = video_drvdata(file);
-       struct media_entity_graph graph;
+       struct media_graph graph;
        struct media_entity *entity = &video->video.entity;
        enum iss_pipeline_state state;
        struct iss_pipeline *pipe;
@@ -880,19 +880,19 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
        if (ret)
                goto err_graph_walk_init;
 
-       ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
+       ret = media_graph_walk_init(&graph, entity->graph_obj.mdev);
        if (ret)
                goto err_graph_walk_init;
 
        if (video->iss->pdata->set_constraints)
                video->iss->pdata->set_constraints(video->iss, true);
 
-       ret = media_entity_pipeline_start(entity, &pipe->pipe);
+       ret = media_pipeline_start(entity, &pipe->pipe);
        if (ret < 0)
-               goto err_media_entity_pipeline_start;
+               goto err_media_pipeline_start;
 
-       media_entity_graph_walk_start(&graph, entity);
-       while ((entity = media_entity_graph_walk_next(&graph)))
+       media_graph_walk_start(&graph, entity);
+       while ((entity = media_graph_walk_next(&graph)))
                media_entity_enum_set(&pipe->ent_enum, entity);
 
        /* Verify that the currently configured format matches the output of
@@ -963,7 +963,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
                spin_unlock_irqrestore(&video->qlock, flags);
        }
 
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
 
        mutex_unlock(&video->stream_lock);
 
@@ -972,13 +972,13 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 err_omap4iss_set_stream:
        vb2_streamoff(&vfh->queue, type);
 err_iss_video_check_format:
-       media_entity_pipeline_stop(&video->video.entity);
-err_media_entity_pipeline_start:
+       media_pipeline_stop(&video->video.entity);
+err_media_pipeline_start:
        if (video->iss->pdata->set_constraints)
                video->iss->pdata->set_constraints(video->iss, false);
        video->queue = NULL;
 
-       media_entity_graph_walk_cleanup(&graph);
+       media_graph_walk_cleanup(&graph);
 
 err_graph_walk_init:
        media_entity_enum_cleanup(&pipe->ent_enum);
@@ -1026,7 +1026,7 @@ iss_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
 
        if (video->iss->pdata->set_constraints)
                video->iss->pdata->set_constraints(video->iss, false);
-       media_entity_pipeline_stop(&video->video.entity);
+       media_pipeline_stop(&video->video.entity);
 
 done:
        mutex_unlock(&video->stream_lock);
@@ -1141,6 +1141,7 @@ static int iss_video_open(struct file *file)
 done:
        if (ret < 0) {
                v4l2_fh_del(&handle->vfh);
+               v4l2_fh_exit(&handle->vfh);
                kfree(handle);
        }
 
@@ -1162,6 +1163,7 @@ static int iss_video_release(struct file *file)
        vb2_queue_release(&handle->queue);
 
        v4l2_fh_del(vfh);
+       v4l2_fh_exit(vfh);
        kfree(handle);
        file->private_data = NULL;
 
index ddfd955da0d40d48e830fe41395f1a2f37dae2e8..7a3489df3e70c1e3fe1ef9145f2c2f48d9ea4d1b 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_SAMSUNG_S5P_CEC
        tristate "Samsung S5P CEC driver"
-       depends on VIDEO_DEV && MEDIA_CEC_SUPPORT && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST)
+       depends on VIDEO_DEV && MEDIA_CEC_SUPPORT && (ARCH_EXYNOS || COMPILE_TEST)
        ---help---
          This is a driver for Samsung S5P HDMI CEC interface. It uses the
          generic CEC framework interface.
index 3e4fc7b05e83155c4c7adf0dee2baad0f34259ef..7d9453505dcee32e61359d188b80d77043e73a74 100644 (file)
@@ -14,7 +14,6 @@
 #define _EXYNOS_HDMI_CEC_H_ __FILE__
 
 #include <linux/regmap.h>
-#include <linux/miscdevice.h>
 #include "s5p_cec.h"
 
 void s5p_cec_set_divider(struct s5p_cec_dev *cec);
index ce95e0fcd882f20b1009c996269b0cb4eb1d5e62..1edf667d562a4df64a4806e947f192aa2a24357f 100644 (file)
@@ -87,7 +87,6 @@ void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec)
        reg |= S5P_CEC_IRQ_TX_DONE;
        reg |= S5P_CEC_IRQ_TX_ERROR;
        writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
-
 }
 
 void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec)
@@ -186,13 +185,13 @@ u32 s5p_cec_get_status(struct s5p_cec_dev *cec)
 void s5p_clr_pending_tx(struct s5p_cec_dev *cec)
 {
        writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR,
-                                       cec->reg + S5P_CEC_IRQ_CLEAR);
+              cec->reg + S5P_CEC_IRQ_CLEAR);
 }
 
 void s5p_clr_pending_rx(struct s5p_cec_dev *cec)
 {
        writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR,
-                                       cec->reg + S5P_CEC_IRQ_CLEAR);
+              cec->reg + S5P_CEC_IRQ_CLEAR);
 }
 
 void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer)
index 812d8730787735d15dbc273ff4bd922bbe899ca2..2c94ab568bfa52f4e8d2d22197fa11e5869bfccd 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef _LIRC_RX51_H
-#define _LIRC_RX51_H
+#ifndef _IR_RX51_H
+#define _IR_RX51_H
 
-struct lirc_rx51_platform_data {
+struct ir_rx51_platform_data {
        int(*set_max_mpu_wakeup_lat)(struct device *dev, long t);
 };
 
index 4900baedd55af4518fd9d06ac4887f4dd65bf2bd..987e49e8f9c99e73ea3eb3fff2ee47c9cfd45b98 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _PPI_H_
index 5773874bf266f6ffaf737ff7c76b9ec9fd365437..a27defcf972c723ea35af46cc5b502e74d284494 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  **************************************************************************/
 #ifndef _CCDC_TYPES_H
 #define _CCDC_TYPES_H
index c669a9fb75e57504673b3c4c86d7a37c57555a3a..e6bc72f6b60f6415026155c03ee8a9a9e4a7a86e 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifndef _DM355_CCDC_H
 #define _DM355_CCDC_H
index 984fb79031de62274363cde081341daea3688593..7c909da29d435759970b0523cc5ce98ae6493955 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #ifndef _DM644X_CCDC_H
 #define _DM644X_CCDC_H
index 7f3d76a4b9e3f2749db14d48bc0812f9c655cfa2..170a7b9cf8240b7706f71ee9c384d60877be458b 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * isif header file
  */
 #ifndef _ISIF_H
index 4376beeb28c2c9b2db4efe2dbb0a8869bd6ecd93..79a566d7defd00353651c8a06fc0d3a3d62a8615 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPBE_H
 #define _VPBE_H
index de59364d7ed2a98263bddc76e92dd5c6414c0574..32f77bcae6b3e0f852e3b4d67f1324b0936f686f 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 #ifndef _OSD_H
 #define _OSD_H
index 05dbe0ba514c0bc3e657df60d5c15258b7a9dcf5..c10690b15935a46ccca22bff69d045b4303d937f 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPBE_TYPES_H
 #define _VPBE_TYPES_H
index 3dbd200261078bdeaad5c1d8a5fa365d5638a93d..e32617bc7f9d0ffbaa46bc93ae7c67b8bd4a680b 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPBE_VENC_H
 #define _VPBE_VENC_H
index 28bcd71cdd2608f9ad7f19ab124f61679f88b409..8e1a4d88daa024cc2b5df4e687d1d96f3925ae61 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifndef _VPFE_CAPTURE_H
index 76fb74bad08c14b9b75785b5b6d5342a88d20e8d..498a274047617c33380db68d571c4f25e8cade6c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPFE_TYPES_H
 #define _VPFE_TYPES_H
index 3cb1704a0650d2020f3bb67cc055bc4bd695c0d0..c49c306cba6177fc21e5f9765059a98935bddc9a 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #ifndef _VPIF_TYPES_H
 #define _VPIF_TYPES_H
@@ -82,6 +78,7 @@ struct vpif_capture_config {
        struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS];
        struct vpif_subdev_info *subdev_info;
        int subdev_count;
+       int i2c_adapter_id;
        const char *card_name;
        struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */
        int *asd_sizes;         /* 0-terminated array of asd group sizes */
index 153473daaa32fc9d559ef47661692e3668074f05..98e7f41fc387becfee39ead5f48ce31daeff49fe 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * vpss - video processing subsystem module header file.
  *
  * Include this header file if a driver needs to configure vpss system
index fb272d48ba33e34104ca6ed91b4388b48ee2e74c..ba4923844d1dc9d6e3d3fe973a81944d491a5998 100644 (file)
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *   GNU General Public License for more details.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #include <linux/videodev2.h>
index 0b6709335dff77eaf812ee161be46981b3d8917f..8a79f7200f5d64f7e0ca6b5a4d3b900a1623f976 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  */
 
 #ifndef ADP1653_H
index c5c2d377c0a60ed50a3f40d97fa9c75f6b7d30c0..2ad8c3d0b7d2697ebbf7f0df4fd27c2bff1f5530 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _ADV7183_H_
index 0e07484ddc33779ca03a83008cd44d66af4142bf..fffd4b563f5ad608b3566acf23f7f4377b3a32ad 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  */
 
 #ifndef __AS3645A_H__
index 5ed942a8ac326a6f97826418c36d97e1b2ab18b7..a5bd310c9e1ed33e51754f16c319b224dc4e4320 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  */
 
 #ifndef __LM3560_H__
index c3a78114d7a6cac3e23d5d1d5236c36debc5fdee..30d02a1af708bf65401bd15cd7beded3de299b43 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  */
 
 #ifndef MT9M032_H
index 635007e7441a9f5695771683351e85a59b794e5c..525d55b2afeb81ee1c1ae12716343c6b26a13f37 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
  */
 
 #ifndef __SMIAPP_H_
index a7b49297da82ca9792d9d55e1bce8190cc3f9537..834e2f95b630540399f3f7b3cfafeb5265cf51ce 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 #ifndef THS7353_H
index 86ed7e8068304e1c44bc9a59d95c59e655940a82..c4896702f2d022470b535ae3b8fb035b38714eef 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef _TVP514X_H
index fadb6afe9ef0a003ef8db8c5db3733321b55c744..5ee007c1cead8e392a784f725a3960eee049f64b 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef _TVP7002_H_
 #define _TVP7002_H_
index 3ad6a32e1bce20e9043bebffd785b214d2ce28cc..48ec03c4ef23258cf7080259c21d7a437d77f77f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef _UPD64031A_H_
index 59b6f32ba300e84a882cfff87c72c86d0b7efff5..4bed7371fdde9429ef32244ff027553c94227802 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifndef _UPD64083_H_
index c21b4c5f587192ce206689bf083a3552e10060e8..6896266031b9905ff6ba61eb0706e5550e85f616 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifndef _MEDIA_DEVICE_H
@@ -125,6 +121,8 @@ struct media_device_ops {
  *    bridge driver finds the media_device during probe.
  *    Bridge driver sets source_priv with information
  *    necessary to run @enable_source and @disable_source handlers.
+ *    Callers should hold graph_mutex to access and call @enable_source
+ *    and @disable_source handlers.
  */
 struct media_device {
        /* dev->driver_data points to this struct. */
@@ -154,7 +152,7 @@ struct media_device {
 
        /* Serializes graph operations. */
        struct mutex graph_mutex;
-       struct media_entity_graph pm_count_walk;
+       struct media_graph pm_count_walk;
 
        void *source_priv;
        int (*enable_source)(struct media_entity *entity,
index cd23e915764cd00c24881fee879abfb85889ee2b..511615d3bf6f4310726eac73d86662534bdb2479 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  * --
  *
  * Common functions for media-related drivers to register and unregister media
index b2203ee7a4c1020a5d973bf04f1ed4914498f36e..c7c254c5bca1761b5767c093a67078658654920a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #ifndef _MEDIA_ENTITY_H
@@ -86,7 +82,7 @@ struct media_entity_enum {
 };
 
 /**
- * struct media_entity_graph - Media graph traversal state
+ * struct media_graph - Media graph traversal state
  *
  * @stack:             Graph traversal stack; the stack contains information
  *                     on the path the media entities to be walked and the
@@ -94,7 +90,7 @@ struct media_entity_enum {
  * @ent_enum:          Visited entities
  * @top:               The top of the stack
  */
-struct media_entity_graph {
+struct media_graph {
        struct {
                struct media_entity *entity;
                struct list_head *link;
@@ -112,7 +108,7 @@ struct media_entity_graph {
  */
 struct media_pipeline {
        int streaming_count;
-       struct media_entity_graph graph;
+       struct media_graph graph;
 };
 
 /**
@@ -179,7 +175,7 @@ struct media_pad {
  *                     return an error, in which case link setup will be
  *                     cancelled. Optional.
  * @link_validate:     Return whether a link is valid from the entity point of
- *                     view. The media_entity_pipeline_start() function
+ *                     view. The media_pipeline_start() function
  *                     validates all links by calling this operation. Optional.
  *
  * .. note::
@@ -820,20 +816,20 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad);
 struct media_entity *media_entity_get(struct media_entity *entity);
 
 /**
- * media_entity_graph_walk_init - Allocate resources used by graph walk.
+ * media_graph_walk_init - Allocate resources used by graph walk.
  *
  * @graph: Media graph structure that will be used to walk the graph
  * @mdev: Pointer to the &media_device that contains the object
  */
-__must_check int media_entity_graph_walk_init(
-       struct media_entity_graph *graph, struct media_device *mdev);
+__must_check int media_graph_walk_init(
+       struct media_graph *graph, struct media_device *mdev);
 
 /**
- * media_entity_graph_walk_cleanup - Release resources used by graph walk.
+ * media_graph_walk_cleanup - Release resources used by graph walk.
  *
  * @graph: Media graph structure that will be used to walk the graph
  */
-void media_entity_graph_walk_cleanup(struct media_entity_graph *graph);
+void media_graph_walk_cleanup(struct media_graph *graph);
 
 /**
  * media_entity_put - Release the reference to the parent module
@@ -847,40 +843,39 @@ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph);
 void media_entity_put(struct media_entity *entity);
 
 /**
- * media_entity_graph_walk_start - Start walking the media graph at a
+ * media_graph_walk_start - Start walking the media graph at a
  *     given entity
  *
  * @graph: Media graph structure that will be used to walk the graph
  * @entity: Starting entity
  *
- * Before using this function, media_entity_graph_walk_init() must be
+ * Before using this function, media_graph_walk_init() must be
  * used to allocate resources used for walking the graph. This
  * function initializes the graph traversal structure to walk the
  * entities graph starting at the given entity. The traversal
  * structure must not be modified by the caller during graph
  * traversal. After the graph walk, the resources must be released
- * using media_entity_graph_walk_cleanup().
+ * using media_graph_walk_cleanup().
  */
-void media_entity_graph_walk_start(struct media_entity_graph *graph,
-                                  struct media_entity *entity);
+void media_graph_walk_start(struct media_graph *graph,
+                           struct media_entity *entity);
 
 /**
- * media_entity_graph_walk_next - Get the next entity in the graph
+ * media_graph_walk_next - Get the next entity in the graph
  * @graph: Media graph structure
  *
  * Perform a depth-first traversal of the given media entities graph.
  *
  * The graph structure must have been previously initialized with a call to
- * media_entity_graph_walk_start().
+ * media_graph_walk_start().
  *
  * Return: returns the next entity in the graph or %NULL if the whole graph
  * have been traversed.
  */
-struct media_entity *
-media_entity_graph_walk_next(struct media_entity_graph *graph);
+struct media_entity *media_graph_walk_next(struct media_graph *graph);
 
 /**
- * media_entity_pipeline_start - Mark a pipeline as streaming
+ * media_pipeline_start - Mark a pipeline as streaming
  * @entity: Starting entity
  * @pipe: Media pipeline to be assigned to all entities in the pipeline.
  *
@@ -889,45 +884,45 @@ media_entity_graph_walk_next(struct media_entity_graph *graph);
  * to every entity in the pipeline and stored in the media_entity pipe field.
  *
  * Calls to this function can be nested, in which case the same number of
- * media_entity_pipeline_stop() calls will be required to stop streaming. The
+ * media_pipeline_stop() calls will be required to stop streaming. The
  * pipeline pointer must be identical for all nested calls to
- * media_entity_pipeline_start().
+ * media_pipeline_start().
  */
-__must_check int media_entity_pipeline_start(struct media_entity *entity,
-                                            struct media_pipeline *pipe);
+__must_check int media_pipeline_start(struct media_entity *entity,
+                                     struct media_pipeline *pipe);
 /**
- * __media_entity_pipeline_start - Mark a pipeline as streaming
+ * __media_pipeline_start - Mark a pipeline as streaming
  *
  * @entity: Starting entity
  * @pipe: Media pipeline to be assigned to all entities in the pipeline.
  *
- * ..note:: This is the non-locking version of media_entity_pipeline_start()
+ * ..note:: This is the non-locking version of media_pipeline_start()
  */
-__must_check int __media_entity_pipeline_start(struct media_entity *entity,
-                                              struct media_pipeline *pipe);
+__must_check int __media_pipeline_start(struct media_entity *entity,
+                                       struct media_pipeline *pipe);
 
 /**
- * media_entity_pipeline_stop - Mark a pipeline as not streaming
+ * media_pipeline_stop - Mark a pipeline as not streaming
  * @entity: Starting entity
  *
  * Mark all entities connected to a given entity through enabled links, either
  * directly or indirectly, as not streaming. The media_entity pipe field is
  * reset to %NULL.
  *
- * If multiple calls to media_entity_pipeline_start() have been made, the same
+ * If multiple calls to media_pipeline_start() have been made, the same
  * number of calls to this function are required to mark the pipeline as not
  * streaming.
  */
-void media_entity_pipeline_stop(struct media_entity *entity);
+void media_pipeline_stop(struct media_entity *entity);
 
 /**
- * __media_entity_pipeline_stop - Mark a pipeline as not streaming
+ * __media_pipeline_stop - Mark a pipeline as not streaming
  *
  * @entity: Starting entity
  *
- * .. note:: This is the non-locking version of media_entity_pipeline_stop()
+ * .. note:: This is the non-locking version of media_pipeline_stop()
  */
-void __media_entity_pipeline_stop(struct media_entity *entity);
+void __media_pipeline_stop(struct media_entity *entity);
 
 /**
  * media_devnode_create() - creates and initializes a device node interface
index 55281b92105a3ebd0d2e899028c3781e298738ea..73ddd721d7bafe03c2eabef4263b54f4c1ff6984 100644 (file)
@@ -32,13 +32,16 @@ do {                                                                \
 /**
  * enum rc_driver_type - type of the RC output
  *
- * @RC_DRIVER_SCANCODE:        Driver or hardware generates a scancode
- * @RC_DRIVER_IR_RAW:  Driver or hardware generates pulse/space sequences.
- *                     It needs a Infra-Red pulse/space decoder
+ * @RC_DRIVER_SCANCODE:         Driver or hardware generates a scancode
+ * @RC_DRIVER_IR_RAW:   Driver or hardware generates pulse/space sequences.
+ *                      It needs a Infra-Red pulse/space decoder
+ * @RC_DRIVER_IR_RAW_TX: Device transmitter only,
+ *                      driver requires pulse/space data sequence.
  */
 enum rc_driver_type {
        RC_DRIVER_SCANCODE = 0,
        RC_DRIVER_IR_RAW,
+       RC_DRIVER_IR_RAW_TX,
 };
 
 /**
@@ -83,10 +86,13 @@ enum rc_filter_type {
  * @input_dev: the input child device used to communicate events to userspace
  * @driver_type: specifies if protocol decoding is done in hardware or software
  * @idle: used to keep track of RX state
+ * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed
+ *     wakeup protocols is the set of all raw encoders
  * @allowed_protocols: bitmask with the supported RC_BIT_* protocols
  * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols
  * @allowed_wakeup_protocols: bitmask with the supported RC_BIT_* wakeup protocols
- * @enabled_wakeup_protocols: bitmask with the enabled RC_BIT_* wakeup protocols
+ * @wakeup_protocol: the enabled RC_TYPE_* wakeup protocol or
+ *     RC_TYPE_UNKNOWN if disabled.
  * @scancode_filter: scancode filter
  * @scancode_wakeup_filter: scancode wakeup filters
  * @scancode_mask: some hardware decoders are not capable of providing the full
@@ -110,8 +116,6 @@ enum rc_filter_type {
  * @rx_resolution : resolution (in ns) of input sampler
  * @tx_resolution: resolution (in ns) of output sampler
  * @change_protocol: allow changing the protocol used on hardware decoders
- * @change_wakeup_protocol: allow changing the protocol used for wakeup
- *     filtering
  * @open: callback to allow drivers to enable polling/irq when IR input device
  *     is opened.
  * @close: callback to allow drivers to disable polling/irq when IR input device
@@ -126,7 +130,9 @@ enum rc_filter_type {
  * @s_learning_mode: enable wide band receiver used for learning
  * @s_carrier_report: enable carrier reports
  * @s_filter: set the scancode filter
- * @s_wakeup_filter: set the wakeup scancode filter
+ * @s_wakeup_filter: set the wakeup scancode filter. If the mask is zero
+ *     then wakeup should be disabled. wakeup_protocol will be set to
+ *     a valid protocol if mask is nonzero.
  * @s_timeout: set hardware timeout in ns
  */
 struct rc_dev {
@@ -146,10 +152,11 @@ struct rc_dev {
        struct input_dev                *input_dev;
        enum rc_driver_type             driver_type;
        bool                            idle;
+       bool                            encode_wakeup;
        u64                             allowed_protocols;
        u64                             enabled_protocols;
        u64                             allowed_wakeup_protocols;
-       u64                             enabled_wakeup_protocols;
+       enum rc_type                    wakeup_protocol;
        struct rc_scancode_filter       scancode_filter;
        struct rc_scancode_filter       scancode_wakeup_filter;
        u32                             scancode_mask;
@@ -169,7 +176,6 @@ struct rc_dev {
        u32                             rx_resolution;
        u32                             tx_resolution;
        int                             (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
-       int                             (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type);
        int                             (*open)(struct rc_dev *dev);
        void                            (*close)(struct rc_dev *dev);
        int                             (*s_tx_mask)(struct rc_dev *dev, u32 mask);
@@ -200,17 +206,19 @@ struct rc_dev {
 /**
  * rc_allocate_device - Allocates a RC device
  *
+ * @rc_driver_type: specifies the type of the RC output to be allocated
  * returns a pointer to struct rc_dev.
  */
-struct rc_dev *rc_allocate_device(void);
+struct rc_dev *rc_allocate_device(enum rc_driver_type);
 
 /**
  * devm_rc_allocate_device - Managed RC device allocation
  *
  * @dev: pointer to struct device
+ * @rc_driver_type: specifies the type of the RC output to be allocated
  * returns a pointer to struct rc_dev.
  */
-struct rc_dev *devm_rc_allocate_device(struct device *dev);
+struct rc_dev *devm_rc_allocate_device(struct device *dev, enum rc_driver_type);
 
 /**
  * rc_free_device - Frees a RC device
@@ -306,6 +314,8 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type);
 int ir_raw_event_store_with_filter(struct rc_dev *dev,
                                struct ir_raw_event *ev);
 void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
+int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode,
+                          struct ir_raw_event *events, unsigned int max);
 
 static inline void ir_raw_event_reset(struct rc_dev *dev)
 {
index e1cc14cba3914f86aec8c5c9c5d90103f6f80fbc..a704749280d2342d10f64fbd01b2b9a90604a045 100644 (file)
@@ -17,7 +17,7 @@
  * @RC_TYPE_UNKNOWN: Protocol not known
  * @RC_TYPE_OTHER: Protocol known but proprietary
  * @RC_TYPE_RC5: Philips RC5 protocol
- * @RC_TYPE_RC5X: Philips RC5x protocol
+ * @RC_TYPE_RC5X_20: Philips RC5x 20 bit protocol
  * @RC_TYPE_RC5_SZ: StreamZap variant of RC5
  * @RC_TYPE_JVC: JVC protocol
  * @RC_TYPE_SONY12: Sony 12 bit protocol
@@ -41,7 +41,7 @@ enum rc_type {
        RC_TYPE_UNKNOWN         = 0,
        RC_TYPE_OTHER           = 1,
        RC_TYPE_RC5             = 2,
-       RC_TYPE_RC5X            = 3,
+       RC_TYPE_RC5X_20         = 3,
        RC_TYPE_RC5_SZ          = 4,
        RC_TYPE_JVC             = 5,
        RC_TYPE_SONY12          = 6,
@@ -66,7 +66,7 @@ enum rc_type {
 #define RC_BIT_UNKNOWN         (1ULL << RC_TYPE_UNKNOWN)
 #define RC_BIT_OTHER           (1ULL << RC_TYPE_OTHER)
 #define RC_BIT_RC5             (1ULL << RC_TYPE_RC5)
-#define RC_BIT_RC5X            (1ULL << RC_TYPE_RC5X)
+#define RC_BIT_RC5X_20         (1ULL << RC_TYPE_RC5X_20)
 #define RC_BIT_RC5_SZ          (1ULL << RC_TYPE_RC5_SZ)
 #define RC_BIT_JVC             (1ULL << RC_TYPE_JVC)
 #define RC_BIT_SONY12          (1ULL << RC_TYPE_SONY12)
@@ -87,7 +87,7 @@ enum rc_type {
 #define RC_BIT_CEC             (1ULL << RC_TYPE_CEC)
 
 #define RC_BIT_ALL     (RC_BIT_UNKNOWN | RC_BIT_OTHER | \
-                        RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \
+                        RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \
                         RC_BIT_JVC | \
                         RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \
                         RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \
@@ -95,7 +95,26 @@ enum rc_type {
                         RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
                         RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \
                         RC_BIT_XMP | RC_BIT_CEC)
+/* All rc protocols for which we have decoders */
+#define RC_BIT_ALL_IR_DECODER \
+                       (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \
+                        RC_BIT_JVC | \
+                        RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \
+                        RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \
+                        RC_BIT_SANYO | RC_BIT_MCE_KBD | RC_BIT_RC6_0 | \
+                        RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
+                        RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \
+                        RC_BIT_XMP)
 
+#define RC_BIT_ALL_IR_ENCODER \
+                       (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \
+                        RC_BIT_JVC | \
+                        RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \
+                        RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \
+                        RC_BIT_SANYO | \
+                        RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
+                        RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | \
+                        RC_BIT_SHARP)
 
 #define RC_SCANCODE_UNKNOWN(x)                 (x)
 #define RC_SCANCODE_OTHER(x)                   (x)
@@ -198,6 +217,7 @@ struct rc_map *rc_map_get(const char *name);
 #define RC_MAP_CEC                       "rc-cec"
 #define RC_MAP_CINERGY_1400              "rc-cinergy-1400"
 #define RC_MAP_CINERGY                   "rc-cinergy"
+#define RC_MAP_D680_DMB                  "rc-d680-dmb"
 #define RC_MAP_DELOCK_61959              "rc-delock-61959"
 #define RC_MAP_DIB0700_NEC_TABLE         "rc-dib0700-nec"
 #define RC_MAP_DIB0700_RC5_TABLE         "rc-dib0700-rc5"
@@ -208,6 +228,8 @@ struct rc_map *rc_map_get(const char *name);
 #define RC_MAP_DNTV_LIVE_DVB_T           "rc-dntv-live-dvb-t"
 #define RC_MAP_DTT200U                   "rc-dtt200u"
 #define RC_MAP_DVBSKY                    "rc-dvbsky"
+#define RC_MAP_DVICO_MCE                "rc-dvico-mce"
+#define RC_MAP_DVICO_PORTABLE           "rc-dvico-portable"
 #define RC_MAP_EMPTY                     "rc-empty"
 #define RC_MAP_EM_TERRATEC               "rc-em-terratec"
 #define RC_MAP_ENCORE_ENLTV2             "rc-encore-enltv2"
@@ -219,6 +241,7 @@ struct rc_map *rc_map_get(const char *name);
 #define RC_MAP_FLYVIDEO                  "rc-flyvideo"
 #define RC_MAP_FUSIONHDTV_MCE            "rc-fusionhdtv-mce"
 #define RC_MAP_GADMEI_RM008Z             "rc-gadmei-rm008z"
+#define RC_MAP_GEEKBOX                   "rc-geekbox"
 #define RC_MAP_GENIUS_TVGO_A11MCE        "rc-genius-tvgo-a11mce"
 #define RC_MAP_GOTVIEW7135               "rc-gotview7135"
 #define RC_MAP_HAUPPAUGE_NEW             "rc-hauppauge"
index a700285c64a93de046cd5277f8cae66cc133fd4a..6741910c3a18978cfd7fd2dc295a4a11ea680538 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #ifndef V4L2_EVENT_H
index e19e6246e21c85dc78fa545b95e0f62b011026bb..62633e7d2630ce590311ed908558e582595c8900 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
  */
 
 #ifndef V4L2_FH_H
index cf778c5dca1806e2877d24044c857b31c4705549..0ab1c5df6fac87f94d2752be0624be3d333fecf4 100644 (file)
@@ -592,9 +592,9 @@ struct v4l2_subdev_ir_ops {
 /**
  * struct v4l2_subdev_pad_config - Used for storing subdev pad information.
  *
- * @try_fmt: pointer to &struct v4l2_mbus_framefmt
- * @try_crop: pointer to &struct v4l2_rect to be used for crop
- * @try_compose: pointer to &struct v4l2_rect to be used for compose
+ * @try_fmt: &struct v4l2_mbus_framefmt
+ * @try_crop: &struct v4l2_rect to be used for crop
+ * @try_compose: &struct v4l2_rect to be used for compose
  *
  * This structure only needs to be passed to the pad op if the 'which' field
  * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For