aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-20 12:37:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-20 12:37:45 -0400
commitfb091be08d1acf184e8801dfdcace6e0cb19b1fe (patch)
treecbd0c4200fd8628d592167589ca790e36fc4ae26
parentbd7fc2f2d807fdb254f7efc542f8eec3f23e289e (diff)
parente8d0416796d43a950ec7b65629e53419b2e22453 (diff)
Merge branch 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (534 commits) V4L/DVB (13554a): v4l: Use the video_drvdata function in drivers V4L/DVB: vivi and mem2mem_testdev need slab.h to build V4L/DVB: tm6000: bugfix image position V4L/DVB: IR/imon: remove dead IMON_KEY_RELEASE_OFFSET V4L/DVB: tm6000: README - add vbi V4L/DVB: Fix unlock logic at medusa_video_init V4L/DVB: fix dvb frontend lockup V4L/DVB: s2255drv: remove dead code V4L/DVB: s2255drv: return if vdev not found V4L/DVB: ov511: cleanup: remove unneeded null check V4L/DVB: media/mem2mem: dereferencing free memory V4L/DVB: media/IR: Add missing include file to rc-map.c V4L/DVB: dvb/stv6110x: cleanup error handling V4L/DVB: ngene: Add lgdt3303 and mt2131 deps to Kconfig V4L/DVB: ngene: start separating out DVB functions into separate file V4L/DVB: ngene: split out card specific code into a separate file V4L/DVB: ngene: split out i2c code into a separate file V4L/DVB: ngene: add initial support for digital side of Avermedia m780 V4L/DVB: ngene: properly support boards where channel 0 isn't a TS input V4L-DVB: ngene: make sure that tuner headers are included ...
-rw-r--r--Documentation/DocBook/media-entities.tmpl11
-rw-r--r--Documentation/DocBook/v4l/compat.xml126
-rw-r--r--Documentation/DocBook/v4l/controls.xml36
-rw-r--r--Documentation/DocBook/v4l/dev-event.xml31
-rw-r--r--Documentation/DocBook/v4l/io.xml18
-rw-r--r--Documentation/DocBook/v4l/pixfmt.xml12
-rw-r--r--Documentation/DocBook/v4l/v4l2.xml3
-rw-r--r--Documentation/DocBook/v4l/videodev2.h.xml10
-rw-r--r--Documentation/DocBook/v4l/vidioc-dqevent.xml131
-rw-r--r--Documentation/DocBook/v4l/vidioc-enuminput.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-qbuf.xml14
-rw-r--r--Documentation/DocBook/v4l/vidioc-queryctrl.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-reqbufs.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-subscribe-event.xml133
-rw-r--r--Documentation/video4linux/CARDLIST.bttv2
-rw-r--r--Documentation/video4linux/CARDLIST.cx881
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx4
-rw-r--r--Documentation/video4linux/CARDLIST.saa71343
-rw-r--r--Documentation/video4linux/extract_xc3028.pl817
-rw-r--r--Documentation/video4linux/gspca.txt5
-rw-r--r--Documentation/video4linux/sh_mobile_ceu_camera.txt80
-rw-r--r--Documentation/video4linux/v4l2-framework.txt143
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/media/IR/Kconfig59
-rw-r--r--drivers/media/IR/Makefile14
-rw-r--r--drivers/media/IR/imon.c2396
-rw-r--r--drivers/media/IR/ir-core-priv.h126
-rw-r--r--drivers/media/IR/ir-functions.c1
-rw-r--r--drivers/media/IR/ir-jvc-decoder.c320
-rw-r--r--drivers/media/IR/ir-keymaps.c3494
-rw-r--r--drivers/media/IR/ir-keytable.c687
-rw-r--r--drivers/media/IR/ir-nec-decoder.c328
-rw-r--r--drivers/media/IR/ir-raw-event.c251
-rw-r--r--drivers/media/IR/ir-rc5-decoder.c324
-rw-r--r--drivers/media/IR/ir-rc6-decoder.c419
-rw-r--r--drivers/media/IR/ir-sony-decoder.c312
-rw-r--r--drivers/media/IR/ir-sysfs.c202
-rw-r--r--drivers/media/IR/keymaps/Kconfig15
-rw-r--r--drivers/media/IR/keymaps/Makefile67
-rw-r--r--drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c89
-rw-r--r--drivers/media/IR/keymaps/rc-apac-viewcomp.c80
-rw-r--r--drivers/media/IR/keymaps/rc-asus-pc39.c91
-rw-r--r--drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c69
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-a16d.c75
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-cardbus.c97
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-dvbt.c78
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c90
-rw-r--r--drivers/media/IR/keymaps/rc-avermedia.c86
-rw-r--r--drivers/media/IR/keymaps/rc-avertv-303.c85
-rw-r--r--drivers/media/IR/keymaps/rc-behold-columbus.c108
-rw-r--r--drivers/media/IR/keymaps/rc-behold.c141
-rw-r--r--drivers/media/IR/keymaps/rc-budget-ci-old.c92
-rw-r--r--drivers/media/IR/keymaps/rc-cinergy-1400.c84
-rw-r--r--drivers/media/IR/keymaps/rc-cinergy.c78
-rw-r--r--drivers/media/IR/keymaps/rc-dm1105-nec.c76
-rw-r--r--drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c78
-rw-r--r--drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c97
-rw-r--r--drivers/media/IR/keymaps/rc-em-terratec.c69
-rw-r--r--drivers/media/IR/keymaps/rc-empty.c44
-rw-r--r--drivers/media/IR/keymaps/rc-encore-enltv-fm53.c81
-rw-r--r--drivers/media/IR/keymaps/rc-encore-enltv.c112
-rw-r--r--drivers/media/IR/keymaps/rc-encore-enltv2.c90
-rw-r--r--drivers/media/IR/keymaps/rc-evga-indtube.c61
-rw-r--r--drivers/media/IR/keymaps/rc-eztv.c96
-rw-r--r--drivers/media/IR/keymaps/rc-flydvb.c77
-rw-r--r--drivers/media/IR/keymaps/rc-flyvideo.c70
-rw-r--r--drivers/media/IR/keymaps/rc-fusionhdtv-mce.c98
-rw-r--r--drivers/media/IR/keymaps/rc-gadmei-rm008z.c81
-rw-r--r--drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c84
-rw-r--r--drivers/media/IR/keymaps/rc-gotview7135.c79
-rw-r--r--drivers/media/IR/keymaps/rc-hauppauge-new.c100
-rw-r--r--drivers/media/IR/keymaps/rc-imon-mce.c142
-rw-r--r--drivers/media/IR/keymaps/rc-imon-pad.c156
-rw-r--r--drivers/media/IR/keymaps/rc-iodata-bctv7e.c88
-rw-r--r--drivers/media/IR/keymaps/rc-kaiomy.c87
-rw-r--r--drivers/media/IR/keymaps/rc-kworld-315u.c83
-rw-r--r--drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c99
-rw-r--r--drivers/media/IR/keymaps/rc-manli.c135
-rw-r--r--drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c123
-rw-r--r--drivers/media/IR/keymaps/rc-msi-tvanywhere.c69
-rw-r--r--drivers/media/IR/keymaps/rc-nebula.c96
-rw-r--r--drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c105
-rw-r--r--drivers/media/IR/keymaps/rc-norwood.c85
-rw-r--r--drivers/media/IR/keymaps/rc-npgtech.c80
-rw-r--r--drivers/media/IR/keymaps/rc-pctv-sedna.c80
-rw-r--r--drivers/media/IR/keymaps/rc-pinnacle-color.c94
-rw-r--r--drivers/media/IR/keymaps/rc-pinnacle-grey.c89
-rw-r--r--drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c73
-rw-r--r--drivers/media/IR/keymaps/rc-pixelview-mk12.c83
-rw-r--r--drivers/media/IR/keymaps/rc-pixelview-new.c83
-rw-r--r--drivers/media/IR/keymaps/rc-pixelview.c82
-rw-r--r--drivers/media/IR/keymaps/rc-powercolor-real-angel.c81
-rw-r--r--drivers/media/IR/keymaps/rc-proteus-2309.c69
-rw-r--r--drivers/media/IR/keymaps/rc-purpletv.c81
-rw-r--r--drivers/media/IR/keymaps/rc-pv951.c78
-rw-r--r--drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c103
-rw-r--r--drivers/media/IR/keymaps/rc-rc5-tv.c81
-rw-r--r--drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c78
-rw-r--r--drivers/media/IR/keymaps/rc-tbs-nec.c73
-rw-r--r--drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c92
-rw-r--r--drivers/media/IR/keymaps/rc-tevii-nec.c88
-rw-r--r--drivers/media/IR/keymaps/rc-tt-1500.c82
-rw-r--r--drivers/media/IR/keymaps/rc-videomate-s350.c85
-rw-r--r--drivers/media/IR/keymaps/rc-videomate-tv-pvr.c87
-rw-r--r--drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c82
-rw-r--r--drivers/media/IR/keymaps/rc-winfast.c102
-rw-r--r--drivers/media/IR/rc-map.c84
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c25
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.h2
-rw-r--r--drivers/media/dvb/bt8xx/dst.c2
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c25
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c11
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c25
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c6
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-remote.c16
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.c8
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.h4
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c43
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h18
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c6
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.c114
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c6
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c51
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c100
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c6
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h9
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h7
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c44
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c4
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c18
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c18
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c16
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c12
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c12
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c2
-rw-r--r--drivers/media/dvb/frontends/atbm8830_priv.h2
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c7
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c26
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h5
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c35
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c36
-rw-r--r--drivers/media/dvb/frontends/dib8000.h1
-rw-r--r--drivers/media/dvb/frontends/ds3000.c2
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c16
-rw-r--r--drivers/media/dvb/frontends/stv090x.c94
-rw-r--r--drivers/media/dvb/frontends/stv090x.h1
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c34
-rw-r--r--drivers/media/dvb/frontends/stv6110x.h1
-rw-r--r--drivers/media/dvb/mantis/mantis_input.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1041.c10
-rw-r--r--drivers/media/dvb/ngene/Kconfig2
-rw-r--r--drivers/media/dvb/ngene/Makefile4
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c328
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c518
-rw-r--r--drivers/media/dvb/ngene/ngene-dvb.c172
-rw-r--r--drivers/media/dvb/ngene/ngene-i2c.c179
-rw-r--r--drivers/media/dvb/ngene/ngene.h30
-rw-r--r--drivers/media/dvb/pt1/pt1.c271
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.c32
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.h8
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.c31
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.h8
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c52
-rw-r--r--drivers/media/dvb/ttpci/budget.c47
-rw-r--r--drivers/media/radio/radio-mr800.c19
-rw-r--r--drivers/media/video/Kconfig52
-rw-r--r--drivers/media/video/Makefile14
-rw-r--r--drivers/media/video/ak881x.c368
-rw-r--r--drivers/media/video/arv.c524
-rw-r--r--drivers/media/video/au0828/au0828-video.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c27
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c30
-rw-r--r--drivers/media/video/bw-qcam.c452
-rw-r--r--drivers/media/video/c-qcam.c483
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c4
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c54
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h24
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c42
-rw-r--r--drivers/media/video/cx18/cx18-cards.c4
-rw-r--r--drivers/media/video/cx18/cx18-cards.h4
-rw-r--r--drivers/media/video/cx18/cx18-controls.c2
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c22
-rw-r--r--drivers/media/video/cx18/cx18-streams.c5
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-audio.c2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c13
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c52
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c9
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/video/cx2341x.c14
-rw-r--r--drivers/media/video/cx23885/cimax2.c12
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c16
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c8
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c4
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c17
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h5
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c40
-rw-r--r--drivers/media/video/cx88/cx88-core.c3
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-input.c149
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c11
-rw-r--r--drivers/media/video/cx88/cx88-video.c20
-rw-r--r--drivers/media/video/cx88/cx88.h8
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c131
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc_regs.h10
-rw-r--r--drivers/media/video/davinci/isif_regs.h2
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c83
-rw-r--r--drivers/media/video/davinci/vpif_capture.c8
-rw-r--r--drivers/media/video/davinci/vpif_display.c6
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c56
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c25
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c11
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c29
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c66
-rw-r--r--drivers/media/video/em28xx/em28xx.h7
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c6
-rw-r--r--drivers/media/video/font.h407
-rw-r--r--drivers/media/video/gspca/Kconfig6
-rw-r--r--drivers/media/video/gspca/cpia1.c36
-rw-r--r--drivers/media/video/gspca/gspca.c124
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/ov534.c563
-rw-r--r--drivers/media/video/gspca/pac207.c4
-rw-r--r--drivers/media/video/gspca/sn9c2028.c2
-rw-r--r--drivers/media/video/gspca/sn9c20x.c359
-rw-r--r--drivers/media/video/gspca/sonixj.c585
-rw-r--r--drivers/media/video/gspca/spca561.c58
-rw-r--r--drivers/media/video/gspca/t613.c172
-rw-r--r--drivers/media/video/gspca/vc032x.c747
-rw-r--r--drivers/media/video/gspca/zc3xx.c95
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c33
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c18
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h5
-rw-r--r--drivers/media/video/ir-kbd-i2c.c28
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h10
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c55
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c119
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c23
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c17
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c18
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c2
-rw-r--r--drivers/media/video/mem2mem_testdev.c1052
-rw-r--r--drivers/media/video/meye.c78
-rw-r--r--drivers/media/video/meye.h10
-rw-r--r--drivers/media/video/mt9t031.c66
-rw-r--r--drivers/media/video/mt9v022.c2
-rw-r--r--drivers/media/video/mx1_camera.c4
-rw-r--r--drivers/media/video/mx3_camera.c4
-rw-r--r--drivers/media/video/omap/Kconfig11
-rw-r--r--drivers/media/video/omap/Makefile7
-rw-r--r--drivers/media/video/omap/omap_vout.c2643
-rw-r--r--drivers/media/video/omap/omap_voutdef.h147
-rw-r--r--drivers/media/video/omap/omap_voutlib.c293
-rw-r--r--drivers/media/video/omap/omap_voutlib.h34
-rw-r--r--drivers/media/video/omap24xxcam.c4
-rw-r--r--drivers/media/video/ov511.c11
-rw-r--r--drivers/media/video/ov7670.c286
-rw-r--r--drivers/media/video/ov9640.c6
-rw-r--r--drivers/media/video/pms.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c28
-rw-r--r--drivers/media/video/pwc/Kconfig2
-rw-r--r--drivers/media/video/pxa_camera.c4
-rw-r--r--drivers/media/video/rj54n1cb0c.c18
-rw-r--r--drivers/media/video/s2255drv.c1161
-rw-r--r--drivers/media/video/saa7115.c74
-rw-r--r--drivers/media/video/saa7127.c31
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c111
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c22
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c9
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c283
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h24
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c25
-rw-r--r--drivers/media/video/saa7134/saa7134.h7
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c613
-rw-r--r--drivers/media/video/sh_vou.c1476
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c6
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h18
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131d.c2
-rw-r--r--drivers/media/video/soc_camera.c21
-rw-r--r--drivers/media/video/tlg2300/pd-dvb.c6
-rw-r--r--drivers/media/video/tlg2300/pd-main.c7
-rw-r--r--drivers/media/video/tlg2300/pd-radio.c21
-rw-r--r--drivers/media/video/tlg2300/pd-video.c18
-rw-r--r--drivers/media/video/tvp514x.c13
-rw-r--r--drivers/media/video/tvp5150.c67
-rw-r--r--drivers/media/video/tvp7002.c53
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c3
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c3
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c82
-rw-r--r--drivers/media/video/usbvision/usbvision.h6
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c50
-rw-r--r--drivers/media/video/uvc/uvc_driver.c25
-rw-r--r--drivers/media/video/uvc/uvc_queue.c8
-rw-r--r--drivers/media/video/uvc/uvcvideo.h4
-rw-r--r--drivers/media/video/v4l2-common.c101
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c3
-rw-r--r--drivers/media/video/v4l2-dev.c6
-rw-r--r--drivers/media/video/v4l2-device.c11
-rw-r--r--drivers/media/video/v4l2-event.c292
-rw-r--r--drivers/media/video/v4l2-fh.c79
-rw-r--r--drivers/media/video/v4l2-ioctl.c103
-rw-r--r--drivers/media/video/v4l2-mem2mem.c633
-rw-r--r--drivers/media/video/videobuf-core.c244
-rw-r--r--drivers/media/video/videobuf-dma-contig.c115
-rw-r--r--drivers/media/video/videobuf-dma-sg.c383
-rw-r--r--drivers/media/video/videobuf-dvb.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c183
-rw-r--r--drivers/media/video/vivi.c806
-rw-r--r--drivers/media/video/w9966.c1149
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c6
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h2
-rw-r--r--drivers/media/video/zoran/zoran.h24
-rw-r--r--drivers/media/video/zoran/zoran_driver.c16
-rw-r--r--drivers/media/video/zr364xx.c4
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c103
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c146
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c84
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c4
-rw-r--r--drivers/staging/cx25821/cx25821-core.c160
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.c25
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c14
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c260
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c145
-rw-r--r--drivers/staging/cx25821/cx25821-video.c145
-rw-r--r--drivers/staging/cx25821/cx25821-video.h78
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c88
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c88
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c84
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c84
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c84
-rw-r--r--drivers/staging/tm6000/Kconfig32
-rw-r--r--drivers/staging/tm6000/Makefile17
-rw-r--r--drivers/staging/tm6000/README22
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c414
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c973
-rw-r--r--drivers/staging/tm6000/tm6000-core.c602
-rw-r--r--drivers/staging/tm6000/tm6000-dvb.c346
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c370
-rw-r--r--drivers/staging/tm6000/tm6000-regs.h541
-rw-r--r--drivers/staging/tm6000/tm6000-stds.c873
-rw-r--r--drivers/staging/tm6000/tm6000-usb-isoc.h53
-rw-r--r--drivers/staging/tm6000/tm6000-video.c1557
-rw-r--r--drivers/staging/tm6000/tm6000.h301
-rw-r--r--include/linux/meye.h12
-rw-r--r--include/linux/videodev2.h75
-rw-r--r--include/media/ak881x.h25
-rw-r--r--include/media/davinci/vpfe_capture.h2
-rw-r--r--include/media/ir-common.h74
-rw-r--r--include/media/ir-core.h142
-rw-r--r--include/media/ir-kbd-i2c.h6
-rw-r--r--include/media/rc-map.h121
-rw-r--r--include/media/sh_vou.h34
-rw-r--r--include/media/soc_camera.h12
-rw-r--r--include/media/v4l2-chip-ident.h127
-rw-r--r--include/media/v4l2-common.h27
-rw-r--r--include/media/v4l2-dev.h5
-rw-r--r--include/media/v4l2-event.h67
-rw-r--r--include/media/v4l2-fh.h65
-rw-r--r--include/media/v4l2-ioctl.h7
-rw-r--r--include/media/v4l2-mem2mem.h201
-rw-r--r--include/media/v4l2-subdev.h70
-rw-r--r--include/media/videobuf-core.h35
-rw-r--r--include/media/videobuf-dma-sg.h26
-rw-r--r--include/media/videobuf-vmalloc.h12
387 files changed, 36270 insertions, 11937 deletions
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index c725cb852c54..5d4d40f429a5 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -17,6 +17,7 @@
17<!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>"> 17<!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>">
18<!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>"> 18<!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>">
19<!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>"> 19<!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>">
20<!ENTITY VIDIOC-DQEVENT "<link linkend='vidioc-dqevent'><constant>VIDIOC_DQEVENT</constant></link>">
20<!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>"> 21<!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>">
21<!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>"> 22<!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>">
22<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>"> 23<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
@@ -60,6 +61,7 @@
60<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>"> 61<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
61<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>"> 62<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
62<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>"> 63<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
64<!ENTITY VIDIOC-SUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_SUBSCRIBE_EVENT</constant></link>">
63<!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>"> 65<!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>">
64<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>"> 66<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
65<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>"> 67<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
@@ -83,6 +85,7 @@
83<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>"> 85<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
84<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>"> 86<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
85<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>"> 87<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
88<!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>">
86 89
87<!-- Types --> 90<!-- Types -->
88<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>"> 91<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
@@ -141,6 +144,9 @@
141<!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>"> 144<!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
142<!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>"> 145<!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
143<!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>"> 146<!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
147<!ENTITY v4l2-event "struct&nbsp;<link linkend='v4l2-event'>v4l2_event</link>">
148<!ENTITY v4l2-event-subscription "struct&nbsp;<link linkend='v4l2-event-subscription'>v4l2_event_subscription</link>">
149<!ENTITY v4l2-event-vsync "struct&nbsp;<link linkend='v4l2-event-vsync'>v4l2_event_vsync</link>">
144<!ENTITY v4l2-ext-control "struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link>"> 150<!ENTITY v4l2-ext-control "struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link>">
145<!ENTITY v4l2-ext-controls "struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>"> 151<!ENTITY v4l2-ext-controls "struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>">
146<!ENTITY v4l2-fmtdesc "struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>"> 152<!ENTITY v4l2-fmtdesc "struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
@@ -200,6 +206,7 @@
200<!ENTITY sub-controls SYSTEM "v4l/controls.xml"> 206<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
201<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml"> 207<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
202<!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml"> 208<!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml">
209<!ENTITY sub-dev-event SYSTEM "v4l/dev-event.xml">
203<!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml"> 210<!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml">
204<!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml"> 211<!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml">
205<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml"> 212<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
@@ -292,6 +299,8 @@
292<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> 299<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
293<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml"> 300<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml">
294<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml"> 301<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
302<!ENTITY sub-dqevent SYSTEM "v4l/vidioc-dqevent.xml">
303<!ENTITY sub-subscribe-event SYSTEM "v4l/vidioc-subscribe-event.xml">
295<!ENTITY sub-intro SYSTEM "dvb/intro.xml"> 304<!ENTITY sub-intro SYSTEM "dvb/intro.xml">
296<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml"> 305<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
297<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml"> 306<!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
@@ -381,3 +390,5 @@
381<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> 390<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
382<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> 391<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
383<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml"> 392<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml">
393<!ENTITY dqevent SYSTEM "v4l/vidioc-dqevent.xml">
394<!ENTITY subscribe_event SYSTEM "v4l/vidioc-subscribe-event.xml">
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml
index b9dbdf9e6d29..b42b935913cd 100644
--- a/Documentation/DocBook/v4l/compat.xml
+++ b/Documentation/DocBook/v4l/compat.xml
@@ -2332,15 +2332,26 @@ more information.</para>
2332 </listitem> 2332 </listitem>
2333 </orderedlist> 2333 </orderedlist>
2334 </section> 2334 </section>
2335 </section> 2335 <section>
2336 <title>V4L2 in Linux 2.6.34</title>
2337 <orderedlist>
2338 <listitem>
2339 <para>Added
2340<constant>V4L2_CID_IRIS_ABSOLUTE</constant> and
2341<constant>V4L2_CID_IRIS_RELATIVE</constant> controls to the
2342 <link linkend="camera-controls">Camera controls class</link>.
2343 </para>
2344 </listitem>
2345 </orderedlist>
2346 </section>
2336 2347
2337 <section id="other"> 2348 <section id="other">
2338 <title>Relation of V4L2 to other Linux multimedia APIs</title> 2349 <title>Relation of V4L2 to other Linux multimedia APIs</title>
2339 2350
2340 <section id="xvideo"> 2351 <section id="xvideo">
2341 <title>X Video Extension</title> 2352 <title>X Video Extension</title>
2342 2353
2343 <para>The X Video Extension (abbreviated XVideo or just Xv) is 2354 <para>The X Video Extension (abbreviated XVideo or just Xv) is
2344an extension of the X Window system, implemented for example by the 2355an extension of the X Window system, implemented for example by the
2345XFree86 project. Its scope is similar to V4L2, an API to video capture 2356XFree86 project. Its scope is similar to V4L2, an API to video capture
2346and output devices for X clients. Xv allows applications to display 2357and output devices for X clients. Xv allows applications to display
@@ -2351,7 +2362,7 @@ capture or output still images in XPixmaps<footnote>
2351extension available across many operating systems and 2362extension available across many operating systems and
2352architectures.</para> 2363architectures.</para>
2353 2364
2354 <para>Because the driver is embedded into the X server Xv has a 2365 <para>Because the driver is embedded into the X server Xv has a
2355number of advantages over the V4L2 <link linkend="overlay">video 2366number of advantages over the V4L2 <link linkend="overlay">video
2356overlay interface</link>. The driver can easily determine the overlay 2367overlay interface</link>. The driver can easily determine the overlay
2357target, &ie; visible graphics memory or off-screen buffers for a 2368target, &ie; visible graphics memory or off-screen buffers for a
@@ -2360,16 +2371,16 @@ overlay, scaling or color-keying, or the clipping functions of the
2360video capture hardware, always in sync with drawing operations or 2371video capture hardware, always in sync with drawing operations or
2361windows moving or changing their stacking order.</para> 2372windows moving or changing their stacking order.</para>
2362 2373
2363 <para>To combine the advantages of Xv and V4L a special Xv 2374 <para>To combine the advantages of Xv and V4L a special Xv
2364driver exists in XFree86 and XOrg, just programming any overlay capable 2375driver exists in XFree86 and XOrg, just programming any overlay capable
2365Video4Linux device it finds. To enable it 2376Video4Linux device it finds. To enable it
2366<filename>/etc/X11/XF86Config</filename> must contain these lines:</para> 2377<filename>/etc/X11/XF86Config</filename> must contain these lines:</para>
2367 <para><screen> 2378 <para><screen>
2368Section "Module" 2379Section "Module"
2369 Load "v4l" 2380 Load "v4l"
2370EndSection</screen></para> 2381EndSection</screen></para>
2371 2382
2372 <para>As of XFree86 4.2 this driver still supports only V4L 2383 <para>As of XFree86 4.2 this driver still supports only V4L
2373ioctls, however it should work just fine with all V4L2 devices through 2384ioctls, however it should work just fine with all V4L2 devices through
2374the V4L2 backward-compatibility layer. Since V4L2 permits multiple 2385the V4L2 backward-compatibility layer. Since V4L2 permits multiple
2375opens it is possible (if supported by the V4L2 driver) to capture 2386opens it is possible (if supported by the V4L2 driver) to capture
@@ -2377,83 +2388,84 @@ video while an X client requested video overlay. Restrictions of
2377simultaneous capturing and overlay are discussed in <xref 2388simultaneous capturing and overlay are discussed in <xref
2378 linkend="overlay" /> apply.</para> 2389 linkend="overlay" /> apply.</para>
2379 2390
2380 <para>Only marginally related to V4L2, XFree86 extended Xv to 2391 <para>Only marginally related to V4L2, XFree86 extended Xv to
2381support hardware YUV to RGB conversion and scaling for faster video 2392support hardware YUV to RGB conversion and scaling for faster video
2382playback, and added an interface to MPEG-2 decoding hardware. This API 2393playback, and added an interface to MPEG-2 decoding hardware. This API
2383is useful to display images captured with V4L2 devices.</para> 2394is useful to display images captured with V4L2 devices.</para>
2384 </section> 2395 </section>
2385 2396
2386 <section> 2397 <section>
2387 <title>Digital Video</title> 2398 <title>Digital Video</title>
2388 2399
2389 <para>V4L2 does not support digital terrestrial, cable or 2400 <para>V4L2 does not support digital terrestrial, cable or
2390satellite broadcast. A separate project aiming at digital receivers 2401satellite broadcast. A separate project aiming at digital receivers
2391exists. You can find its homepage at <ulink 2402exists. You can find its homepage at <ulink
2392url="http://linuxtv.org">http://linuxtv.org</ulink>. The Linux DVB API 2403url="http://linuxtv.org">http://linuxtv.org</ulink>. The Linux DVB API
2393has no connection to the V4L2 API except that drivers for hybrid 2404has no connection to the V4L2 API except that drivers for hybrid
2394hardware may support both.</para> 2405hardware may support both.</para>
2395 </section> 2406 </section>
2396 2407
2397 <section> 2408 <section>
2398 <title>Audio Interfaces</title> 2409 <title>Audio Interfaces</title>
2399 2410
2400 <para>[to do - OSS/ALSA]</para> 2411 <para>[to do - OSS/ALSA]</para>
2412 </section>
2401 </section> 2413 </section>
2402 </section>
2403 2414
2404 <section id="experimental"> 2415 <section id="experimental">
2405 <title>Experimental API Elements</title> 2416 <title>Experimental API Elements</title>
2406 2417
2407 <para>The following V4L2 API elements are currently experimental 2418 <para>The following V4L2 API elements are currently experimental
2408and may change in the future.</para> 2419and may change in the future.</para>
2409 2420
2410 <itemizedlist> 2421 <itemizedlist>
2411 <listitem> 2422 <listitem>
2412 <para>Video Output Overlay (OSD) Interface, <xref 2423 <para>Video Output Overlay (OSD) Interface, <xref
2413 linkend="osd" />.</para> 2424 linkend="osd" />.</para>
2414 </listitem> 2425 </listitem>
2415 <listitem> 2426 <listitem>
2416 <para><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>, 2427 <para><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>,
2417 &v4l2-buf-type;, <xref linkend="v4l2-buf-type" />.</para> 2428 &v4l2-buf-type;, <xref linkend="v4l2-buf-type" />.</para>
2418 </listitem> 2429 </listitem>
2419 <listitem> 2430 <listitem>
2420 <para><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant>, 2431 <para><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant>,
2421&VIDIOC-QUERYCAP; ioctl, <xref linkend="device-capabilities" />.</para> 2432&VIDIOC-QUERYCAP; ioctl, <xref linkend="device-capabilities" />.</para>
2422 </listitem> 2433 </listitem>
2423 <listitem> 2434 <listitem>
2424 <para>&VIDIOC-ENUM-FRAMESIZES; and 2435 <para>&VIDIOC-ENUM-FRAMESIZES; and
2425&VIDIOC-ENUM-FRAMEINTERVALS; ioctls.</para> 2436&VIDIOC-ENUM-FRAMEINTERVALS; ioctls.</para>
2426 </listitem> 2437 </listitem>
2427 <listitem> 2438 <listitem>
2428 <para>&VIDIOC-G-ENC-INDEX; ioctl.</para> 2439 <para>&VIDIOC-G-ENC-INDEX; ioctl.</para>
2429 </listitem> 2440 </listitem>
2430 <listitem> 2441 <listitem>
2431 <para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD; 2442 <para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD;
2432ioctls.</para> 2443ioctls.</para>
2433 </listitem> 2444 </listitem>
2434 <listitem> 2445 <listitem>
2435 <para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER; 2446 <para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER;
2436ioctls.</para> 2447ioctls.</para>
2437 </listitem> 2448 </listitem>
2438 <listitem> 2449 <listitem>
2439 <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para> 2450 <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
2440 </listitem> 2451 </listitem>
2441 </itemizedlist> 2452 </itemizedlist>
2442 </section> 2453 </section>
2443 2454
2444 <section id="obsolete"> 2455 <section id="obsolete">
2445 <title>Obsolete API Elements</title> 2456 <title>Obsolete API Elements</title>
2446 2457
2447 <para>The following V4L2 API elements were superseded by new 2458 <para>The following V4L2 API elements were superseded by new
2448interfaces and should not be implemented in new drivers.</para> 2459interfaces and should not be implemented in new drivers.</para>
2449 2460
2450 <itemizedlist> 2461 <itemizedlist>
2451 <listitem> 2462 <listitem>
2452 <para><constant>VIDIOC_G_MPEGCOMP</constant> and 2463 <para><constant>VIDIOC_G_MPEGCOMP</constant> and
2453<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls, 2464<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
2454<xref linkend="extended-controls" />.</para> 2465<xref linkend="extended-controls" />.</para>
2455 </listitem> 2466 </listitem>
2456 </itemizedlist> 2467 </itemizedlist>
2468 </section>
2457 </section> 2469 </section>
2458 2470
2459 <!-- 2471 <!--
diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml
index f46450610412..8408caaee276 100644
--- a/Documentation/DocBook/v4l/controls.xml
+++ b/Documentation/DocBook/v4l/controls.xml
@@ -267,6 +267,12 @@ minimum value disables backlight compensation.</entry>
267 <entry>Chroma automatic gain control.</entry> 267 <entry>Chroma automatic gain control.</entry>
268 </row> 268 </row>
269 <row> 269 <row>
270 <entry><constant>V4L2_CID_CHROMA_GAIN</constant></entry>
271 <entry>integer</entry>
272 <entry>Adjusts the Chroma gain control (for use when chroma AGC
273 is disabled).</entry>
274 </row>
275 <row>
270 <entry><constant>V4L2_CID_COLOR_KILLER</constant></entry> 276 <entry><constant>V4L2_CID_COLOR_KILLER</constant></entry>
271 <entry>boolean</entry> 277 <entry>boolean</entry>
272 <entry>Enable the color killer (&ie; force a black &amp; white image in case of a weak video signal).</entry> 278 <entry>Enable the color killer (&ie; force a black &amp; white image in case of a weak video signal).</entry>
@@ -277,8 +283,15 @@ minimum value disables backlight compensation.</entry>
277 <entry>Selects a color effect. Possible values for 283 <entry>Selects a color effect. Possible values for
278<constant>enum v4l2_colorfx</constant> are: 284<constant>enum v4l2_colorfx</constant> are:
279<constant>V4L2_COLORFX_NONE</constant> (0), 285<constant>V4L2_COLORFX_NONE</constant> (0),
280<constant>V4L2_COLORFX_BW</constant> (1) and 286<constant>V4L2_COLORFX_BW</constant> (1),
281<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry> 287<constant>V4L2_COLORFX_SEPIA</constant> (2),
288<constant>V4L2_COLORFX_NEGATIVE</constant> (3),
289<constant>V4L2_COLORFX_EMBOSS</constant> (4),
290<constant>V4L2_COLORFX_SKETCH</constant> (5),
291<constant>V4L2_COLORFX_SKY_BLUE</constant> (6),
292<constant>V4L2_COLORFX_GRASS_GREEN</constant> (7),
293<constant>V4L2_COLORFX_SKIN_WHITEN</constant> (8) and
294<constant>V4L2_COLORFX_VIVID</constant> (9).</entry>
282 </row> 295 </row>
283 <row> 296 <row>
284 <entry><constant>V4L2_CID_ROTATE</constant></entry> 297 <entry><constant>V4L2_CID_ROTATE</constant></entry>
@@ -1825,6 +1838,25 @@ wide-angle direction. The zoom speed unit is driver-specific.</entry>
1825 <row><entry></entry></row> 1838 <row><entry></entry></row>
1826 1839
1827 <row> 1840 <row>
1841 <entry spanname="id"><constant>V4L2_CID_IRIS_ABSOLUTE</constant>&nbsp;</entry>
1842 <entry>integer</entry>
1843 </row><row><entry spanname="descr">This control sets the
1844camera's aperture to the specified value. The unit is undefined.
1845Larger values open the iris wider, smaller values close it.</entry>
1846 </row>
1847 <row><entry></entry></row>
1848
1849 <row>
1850 <entry spanname="id"><constant>V4L2_CID_IRIS_RELATIVE</constant>&nbsp;</entry>
1851 <entry>integer</entry>
1852 </row><row><entry spanname="descr">This control modifies the
1853camera's aperture by the specified amount. The unit is undefined.
1854Positive values open the iris one step further, negative values close
1855it one step further. This is a write-only control.</entry>
1856 </row>
1857 <row><entry></entry></row>
1858
1859 <row>
1828 <entry spanname="id"><constant>V4L2_CID_PRIVACY</constant>&nbsp;</entry> 1860 <entry spanname="id"><constant>V4L2_CID_PRIVACY</constant>&nbsp;</entry>
1829 <entry>boolean</entry> 1861 <entry>boolean</entry>
1830 </row><row><entry spanname="descr">Prevent video from being acquired 1862 </row><row><entry spanname="descr">Prevent video from being acquired
diff --git a/Documentation/DocBook/v4l/dev-event.xml b/Documentation/DocBook/v4l/dev-event.xml
new file mode 100644
index 000000000000..be5a98fb4fab
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-event.xml
@@ -0,0 +1,31 @@
1 <title>Event Interface</title>
2
3 <para>The V4L2 event interface provides means for user to get
4 immediately notified on certain conditions taking place on a device.
5 This might include start of frame or loss of signal events, for
6 example.
7 </para>
8
9 <para>To receive events, the events the user is interested in first must
10 be subscribed using the &VIDIOC-SUBSCRIBE-EVENT; ioctl. Once an event is
11 subscribed, the events of subscribed types are dequeueable using the
12 &VIDIOC-DQEVENT; ioctl. Events may be unsubscribed using
13 VIDIOC_UNSUBSCRIBE_EVENT ioctl. The special event type V4L2_EVENT_ALL may
14 be used to unsubscribe all the events the driver supports.</para>
15
16 <para>The event subscriptions and event queues are specific to file
17 handles. Subscribing an event on one file handle does not affect
18 other file handles.
19 </para>
20
21 <para>The information on dequeueable events is obtained by using select or
22 poll system calls on video devices. The V4L2 events use POLLPRI events on
23 poll system call and exceptions on select system call. </para>
24
25 <!--
26Local Variables:
27mode: sgml
28sgml-parent-document: "v4l2.sgml"
29indent-tabs-mode: nil
30End:
31 -->
diff --git a/Documentation/DocBook/v4l/io.xml b/Documentation/DocBook/v4l/io.xml
index e870330cbf77..d424886beda0 100644
--- a/Documentation/DocBook/v4l/io.xml
+++ b/Documentation/DocBook/v4l/io.xml
@@ -702,6 +702,16 @@ They can be both cleared however, then the buffer is in "dequeued"
702state, in the application domain to say so.</entry> 702state, in the application domain to say so.</entry>
703 </row> 703 </row>
704 <row> 704 <row>
705 <entry><constant>V4L2_BUF_FLAG_ERROR</constant></entry>
706 <entry>0x0040</entry>
707 <entry>When this flag is set, the buffer has been dequeued
708 successfully, although the data might have been corrupted.
709 This is recoverable, streaming may continue as normal and
710 the buffer may be reused normally.
711 Drivers set this flag when the <constant>VIDIOC_DQBUF</constant>
712 ioctl is called.</entry>
713 </row>
714 <row>
705 <entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry> 715 <entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
706 <entry>0x0008</entry> 716 <entry>0x0008</entry>
707 <entry>Drivers set or clear this flag when calling the 717 <entry>Drivers set or clear this flag when calling the
@@ -918,8 +928,8 @@ order</emphasis>.</para>
918 928
919 <para>When the driver provides or accepts images field by field 929 <para>When the driver provides or accepts images field by field
920rather than interleaved, it is also important applications understand 930rather than interleaved, it is also important applications understand
921how the fields combine to frames. We distinguish between top and 931how the fields combine to frames. We distinguish between top (aka odd) and
922bottom fields, the <emphasis>spatial order</emphasis>: The first line 932bottom (aka even) fields, the <emphasis>spatial order</emphasis>: The first line
923of the top field is the first line of an interlaced frame, the first 933of the top field is the first line of an interlaced frame, the first
924line of the bottom field is the second line of that frame.</para> 934line of the bottom field is the second line of that frame.</para>
925 935
@@ -972,12 +982,12 @@ between <constant>V4L2_FIELD_TOP</constant> and
972 <row> 982 <row>
973 <entry><constant>V4L2_FIELD_TOP</constant></entry> 983 <entry><constant>V4L2_FIELD_TOP</constant></entry>
974 <entry>2</entry> 984 <entry>2</entry>
975 <entry>Images consist of the top field only.</entry> 985 <entry>Images consist of the top (aka odd) field only.</entry>
976 </row> 986 </row>
977 <row> 987 <row>
978 <entry><constant>V4L2_FIELD_BOTTOM</constant></entry> 988 <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
979 <entry>3</entry> 989 <entry>3</entry>
980 <entry>Images consist of the bottom field only. 990 <entry>Images consist of the bottom (aka even) field only.
981Applications may wish to prevent a device from capturing interlaced 991Applications may wish to prevent a device from capturing interlaced
982images because they will have "comb" or "feathering" artefacts around 992images because they will have "comb" or "feathering" artefacts around
983moving objects.</entry> 993moving objects.</entry>
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index 885968d6a2fc..c4ad0a8e42dc 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -792,6 +792,18 @@ http://www.thedirks.org/winnov/</ulink></para></entry>
792 <entry>'YYUV'</entry> 792 <entry>'YYUV'</entry>
793 <entry>unknown</entry> 793 <entry>unknown</entry>
794 </row> 794 </row>
795 <row id="V4L2-PIX-FMT-Y4">
796 <entry><constant>V4L2_PIX_FMT_Y4</constant></entry>
797 <entry>'Y04 '</entry>
798 <entry>Old 4-bit greyscale format. Only the least significant 4 bits of each byte are used,
799the other bits are set to 0.</entry>
800 </row>
801 <row id="V4L2-PIX-FMT-Y6">
802 <entry><constant>V4L2_PIX_FMT_Y6</constant></entry>
803 <entry>'Y06 '</entry>
804 <entry>Old 6-bit greyscale format. Only the least significant 6 bits of each byte are used,
805the other bits are set to 0.</entry>
806 </row>
795 </tbody> 807 </tbody>
796 </tgroup> 808 </tgroup>
797 </table> 809 </table>
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
index 060105af49e5..9737243377a3 100644
--- a/Documentation/DocBook/v4l/v4l2.xml
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -401,6 +401,7 @@ and discussions on the V4L mailing list.</revremark>
401 <section id="ttx"> &sub-dev-teletext; </section> 401 <section id="ttx"> &sub-dev-teletext; </section>
402 <section id="radio"> &sub-dev-radio; </section> 402 <section id="radio"> &sub-dev-radio; </section>
403 <section id="rds"> &sub-dev-rds; </section> 403 <section id="rds"> &sub-dev-rds; </section>
404 <section id="event"> &sub-dev-event; </section>
404 </chapter> 405 </chapter>
405 406
406 <chapter id="driver"> 407 <chapter id="driver">
@@ -426,6 +427,7 @@ and discussions on the V4L mailing list.</revremark>
426 &sub-cropcap; 427 &sub-cropcap;
427 &sub-dbg-g-chip-ident; 428 &sub-dbg-g-chip-ident;
428 &sub-dbg-g-register; 429 &sub-dbg-g-register;
430 &sub-dqevent;
429 &sub-encoder-cmd; 431 &sub-encoder-cmd;
430 &sub-enumaudio; 432 &sub-enumaudio;
431 &sub-enumaudioout; 433 &sub-enumaudioout;
@@ -467,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
467 &sub-reqbufs; 469 &sub-reqbufs;
468 &sub-s-hw-freq-seek; 470 &sub-s-hw-freq-seek;
469 &sub-streamon; 471 &sub-streamon;
472 &sub-subscribe-event;
470 <!-- End of ioctls. --> 473 <!-- End of ioctls. -->
471 &sub-mmap; 474 &sub-mmap;
472 &sub-munmap; 475 &sub-munmap;
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
index 068325940658..865b06d9e679 100644
--- a/Documentation/DocBook/v4l/videodev2.h.xml
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -1018,6 +1018,13 @@ enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> {
1018 V4L2_COLORFX_NONE = 0, 1018 V4L2_COLORFX_NONE = 0,
1019 V4L2_COLORFX_BW = 1, 1019 V4L2_COLORFX_BW = 1,
1020 V4L2_COLORFX_SEPIA = 2, 1020 V4L2_COLORFX_SEPIA = 2,
1021 V4L2_COLORFX_NEGATIVE = 3,
1022 V4L2_COLORFX_EMBOSS = 4,
1023 V4L2_COLORFX_SKETCH = 5,
1024 V4L2_COLORFX_SKY_BLUE = 6,
1025 V4L2_COLORFX_GRASS_GREEN = 7,
1026 V4L2_COLORFX_SKIN_WHITEN = 8,
1027 V4L2_COLORFX_VIVID = 9.
1021}; 1028};
1022#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) 1029#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
1023#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) 1030#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
@@ -1271,6 +1278,9 @@ enum <link linkend="v4l2-exposure-auto-type">v4l2_exposure_auto_type</link> {
1271 1278
1272#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) 1279#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
1273 1280
1281#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17)
1282#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18)
1283
1274/* FM Modulator class control IDs */ 1284/* FM Modulator class control IDs */
1275#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) 1285#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
1276#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) 1286#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
diff --git a/Documentation/DocBook/v4l/vidioc-dqevent.xml b/Documentation/DocBook/v4l/vidioc-dqevent.xml
new file mode 100644
index 000000000000..4e0a7cc30812
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-dqevent.xml
@@ -0,0 +1,131 @@
1<refentry id="vidioc-dqevent">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_DQEVENT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_DQEVENT</refname>
9 <refpurpose>Dequeue event</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_event
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_DQEVENT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>Dequeue an event from a video device. No input is required
53 for this ioctl. All the fields of the &v4l2-event; structure are
54 filled by the driver. The file handle will also receive exceptions
55 which the application may get by e.g. using the select system
56 call.</para>
57
58 <table frame="none" pgwide="1" id="v4l2-event">
59 <title>struct <structname>v4l2_event</structname></title>
60 <tgroup cols="4">
61 &cs-str;
62 <tbody valign="top">
63 <row>
64 <entry>__u32</entry>
65 <entry><structfield>type</structfield></entry>
66 <entry></entry>
67 <entry>Type of the event.</entry>
68 </row>
69 <row>
70 <entry>union</entry>
71 <entry><structfield>u</structfield></entry>
72 <entry></entry>
73 <entry></entry>
74 </row>
75 <row>
76 <entry></entry>
77 <entry>&v4l2-event-vsync;</entry>
78 <entry><structfield>vsync</structfield></entry>
79 <entry>Event data for event V4L2_EVENT_VSYNC.
80 </entry>
81 </row>
82 <row>
83 <entry></entry>
84 <entry>__u8</entry>
85 <entry><structfield>data</structfield>[64]</entry>
86 <entry>Event data. Defined by the event type. The union
87 should be used to define easily accessible type for
88 events.</entry>
89 </row>
90 <row>
91 <entry>__u32</entry>
92 <entry><structfield>pending</structfield></entry>
93 <entry></entry>
94 <entry>Number of pending events excluding this one.</entry>
95 </row>
96 <row>
97 <entry>__u32</entry>
98 <entry><structfield>sequence</structfield></entry>
99 <entry></entry>
100 <entry>Event sequence number. The sequence number is
101 incremented for every subscribed event that takes place.
102 If sequence numbers are not contiguous it means that
103 events have been lost.
104 </entry>
105 </row>
106 <row>
107 <entry>struct timespec</entry>
108 <entry><structfield>timestamp</structfield></entry>
109 <entry></entry>
110 <entry>Event timestamp.</entry>
111 </row>
112 <row>
113 <entry>__u32</entry>
114 <entry><structfield>reserved</structfield>[9]</entry>
115 <entry></entry>
116 <entry>Reserved for future extensions. Drivers must set
117 the array to zero.</entry>
118 </row>
119 </tbody>
120 </tgroup>
121 </table>
122
123 </refsect1>
124</refentry>
125<!--
126Local Variables:
127mode: sgml
128sgml-parent-document: "v4l2.sgml"
129indent-tabs-mode: nil
130End:
131-->
diff --git a/Documentation/DocBook/v4l/vidioc-enuminput.xml b/Documentation/DocBook/v4l/vidioc-enuminput.xml
index 71b868e2fb8f..476fe1d2bba0 100644
--- a/Documentation/DocBook/v4l/vidioc-enuminput.xml
+++ b/Documentation/DocBook/v4l/vidioc-enuminput.xml
@@ -283,7 +283,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
283 <entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry> 283 <entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
284 </row> 284 </row>
285 <row> 285 <row>
286 <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry> 286 <entry><constant>V4L2_IN_CAP_CUSTOM_TIMINGS</constant></entry>
287 <entry>0x00000002</entry> 287 <entry>0x00000002</entry>
288 <entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry> 288 <entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
289 </row> 289 </row>
diff --git a/Documentation/DocBook/v4l/vidioc-qbuf.xml b/Documentation/DocBook/v4l/vidioc-qbuf.xml
index b843bd7b3897..ab691ebf3b93 100644
--- a/Documentation/DocBook/v4l/vidioc-qbuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-qbuf.xml
@@ -111,7 +111,11 @@ from the driver's outgoing queue. They just set the
111and <structfield>reserved</structfield> 111and <structfield>reserved</structfield>
112fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant> 112fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
113is called with a pointer to this structure the driver fills the 113is called with a pointer to this structure the driver fills the
114remaining fields or returns an error code.</para> 114remaining fields or returns an error code. The driver may also set
115<constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield>
116field. It indicates a non-critical (recoverable) streaming error. In such case
117the application may continue as normal, but should be aware that data in the
118dequeued buffer might be corrupted.</para>
115 119
116 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no 120 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
117buffer is in the outgoing queue. When the 121buffer is in the outgoing queue. When the
@@ -158,7 +162,13 @@ enqueue a user pointer buffer.</para>
158 <para><constant>VIDIOC_DQBUF</constant> failed due to an 162 <para><constant>VIDIOC_DQBUF</constant> failed due to an
159internal error. Can also indicate temporary problems like signal 163internal error. Can also indicate temporary problems like signal
160loss. Note the driver might dequeue an (empty) buffer despite 164loss. Note the driver might dequeue an (empty) buffer despite
161returning an error, or even stop capturing.</para> 165returning an error, or even stop capturing. Reusing such buffer may be unsafe
166though and its details (e.g. <structfield>index</structfield>) may not be
167returned either. It is recommended that drivers indicate recoverable errors
168by setting the <constant>V4L2_BUF_FLAG_ERROR</constant> and returning 0 instead.
169In that case the application should be able to safely reuse the buffer and
170continue streaming.
171 </para>
162 </listitem> 172 </listitem>
163 </varlistentry> 173 </varlistentry>
164 </variablelist> 174 </variablelist>
diff --git a/Documentation/DocBook/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/v4l/vidioc-queryctrl.xml
index 4876ff1a1a04..8e0e055ac934 100644
--- a/Documentation/DocBook/v4l/vidioc-queryctrl.xml
+++ b/Documentation/DocBook/v4l/vidioc-queryctrl.xml
@@ -325,7 +325,7 @@ should be part of the control documentation.</entry>
325 <entry>n/a</entry> 325 <entry>n/a</entry>
326 <entry>This is not a control. When 326 <entry>This is not a control. When
327<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID 327<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID
328equal to a control class code (see <xref linkend="ctrl-class" />), the 328equal to a control class code (see <xref linkend="ctrl-class" />) + 1, the
329ioctl returns the name of the control class and this control type. 329ioctl returns the name of the control class and this control type.
330Older drivers which do not support this feature return an 330Older drivers which do not support this feature return an
331&EINVAL;.</entry> 331&EINVAL;.</entry>
diff --git a/Documentation/DocBook/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/v4l/vidioc-reqbufs.xml
index 1c0816372074..69800ae23348 100644
--- a/Documentation/DocBook/v4l/vidioc-reqbufs.xml
+++ b/Documentation/DocBook/v4l/vidioc-reqbufs.xml
@@ -61,7 +61,7 @@ fields of the <structname>v4l2_requestbuffers</structname> structure.
61They set the <structfield>type</structfield> field to the respective 61They set the <structfield>type</structfield> field to the respective
62stream or buffer type, the <structfield>count</structfield> field to 62stream or buffer type, the <structfield>count</structfield> field to
63the desired number of buffers, <structfield>memory</structfield> 63the desired number of buffers, <structfield>memory</structfield>
64must be set to the requested I/O method and the reserved array 64must be set to the requested I/O method and the <structfield>reserved</structfield> array
65must be zeroed. When the ioctl 65must be zeroed. When the ioctl
66is called with a pointer to this structure the driver will attempt to allocate 66is called with a pointer to this structure the driver will attempt to allocate
67the requested number of buffers and it stores the actual number 67the requested number of buffers and it stores the actual number
diff --git a/Documentation/DocBook/v4l/vidioc-subscribe-event.xml b/Documentation/DocBook/v4l/vidioc-subscribe-event.xml
new file mode 100644
index 000000000000..8b501791aa68
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subscribe-event.xml
@@ -0,0 +1,133 @@
1<refentry id="vidioc-subscribe-event">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</refname>
9 <refpurpose>Subscribe or unsubscribe event</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_event_subscription
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>Subscribe or unsubscribe V4L2 event. Subscribed events are
53 dequeued by using the &VIDIOC-DQEVENT; ioctl.</para>
54
55 <table frame="none" pgwide="1" id="v4l2-event-subscription">
56 <title>struct <structname>v4l2_event_subscription</structname></title>
57 <tgroup cols="3">
58 &cs-str;
59 <tbody valign="top">
60 <row>
61 <entry>__u32</entry>
62 <entry><structfield>type</structfield></entry>
63 <entry>Type of the event.</entry>
64 </row>
65 <row>
66 <entry>__u32</entry>
67 <entry><structfield>reserved</structfield>[7]</entry>
68 <entry>Reserved for future extensions. Drivers and applications
69 must set the array to zero.</entry>
70 </row>
71 </tbody>
72 </tgroup>
73 </table>
74
75 <table frame="none" pgwide="1" id="event-type">
76 <title>Event Types</title>
77 <tgroup cols="3">
78 &cs-def;
79 <tbody valign="top">
80 <row>
81 <entry><constant>V4L2_EVENT_ALL</constant></entry>
82 <entry>0</entry>
83 <entry>All events. V4L2_EVENT_ALL is valid only for
84 VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
85 </entry>
86 </row>
87 <row>
88 <entry><constant>V4L2_EVENT_VSYNC</constant></entry>
89 <entry>1</entry>
90 <entry>This event is triggered on the vertical sync.
91 This event has &v4l2-event-vsync; associated with it.
92 </entry>
93 </row>
94 <row>
95 <entry><constant>V4L2_EVENT_EOS</constant></entry>
96 <entry>2</entry>
97 <entry>This event is triggered when the end of a stream is reached.
98 This is typically used with MPEG decoders to report to the application
99 when the last of the MPEG stream has been decoded.
100 </entry>
101 </row>
102 <row>
103 <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
104 <entry>0x08000000</entry>
105 <entry>Base event number for driver-private events.</entry>
106 </row>
107 </tbody>
108 </tgroup>
109 </table>
110
111 <table frame="none" pgwide="1" id="v4l2-event-vsync">
112 <title>struct <structname>v4l2_event_vsync</structname></title>
113 <tgroup cols="3">
114 &cs-str;
115 <tbody valign="top">
116 <row>
117 <entry>__u8</entry>
118 <entry><structfield>field</structfield></entry>
119 <entry>The upcoming field. See &v4l2-field;.</entry>
120 </row>
121 </tbody>
122 </tgroup>
123 </table>
124
125 </refsect1>
126</refentry>
127<!--
128Local Variables:
129mode: sgml
130sgml-parent-document: "v4l2.sgml"
131indent-tabs-mode: nil
132End:
133-->
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index f11c583295e9..4739d5684305 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -100,7 +100,7 @@
100 99 -> AD-TVK503 100 99 -> AD-TVK503
101100 -> Hercules Smart TV Stereo 101100 -> Hercules Smart TV Stereo
102101 -> Pace TV & Radio Card 102101 -> Pace TV & Radio Card
103102 -> IVC-200 [0000:a155,0001:a155,0002:a155,0003:a155,0100:a155,0101:a155,0102:a155,0103:a155] 103102 -> IVC-200 [0000:a155,0001:a155,0002:a155,0003:a155,0100:a155,0101:a155,0102:a155,0103:a155,0800:a155,0801:a155,0802:a155,0803:a155]
104103 -> Grand X-Guard / Trust 814PCI [0304:0102] 104103 -> Grand X-Guard / Trust 814PCI [0304:0102]
105104 -> Nebula Electronics DigiTV [0071:0101] 105104 -> Nebula Electronics DigiTV [0071:0101]
106105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433] 106105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 7ec3c4e4b60f..f2510541373b 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -82,3 +82,4 @@
82 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654] 82 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654]
83 82 -> WinFast DTV2000 H rev. J [107d:6f2b] 83 82 -> WinFast DTV2000 H rev. J [107d:6f2b]
84 83 -> Prof 7301 DVB-S/S2 [b034:3034] 84 83 -> Prof 7301 DVB-S/S2 [b034:3034]
85 84 -> Samsung SMT 7020 DVB-S [18ac:dc00,18ac:dccd]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 0c166ff003a0..3a623aaeae5f 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,5 +1,5 @@
1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] 1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868] 2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2862,eb1a:2863,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] 5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
@@ -27,6 +27,7 @@
27 26 -> Hercules Smart TV USB 2.0 (em2820/em2840) 27 26 -> Hercules Smart TV USB 2.0 (em2820/em2840)
28 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840) 28 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840)
29 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840) 29 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840)
30 29 -> EM2860/TVP5150 Reference Design (em2860)
30 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) 31 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
31 31 -> Usbgear VD204v9 (em2821) 32 31 -> Usbgear VD204v9 (em2821)
32 32 -> Supercomp USB 2.0 TV (em2821) 33 32 -> Supercomp USB 2.0 TV (em2821)
@@ -70,3 +71,4 @@
70 72 -> Gadmei UTV330+ (em2861) 71 72 -> Gadmei UTV330+ (em2861)
71 73 -> Reddo DVB-C USB TV Box (em2870) 72 73 -> Reddo DVB-C USB TV Box (em2870)
72 74 -> Actionmaster/LinXcel/Digitus VC211A (em2800) 73 74 -> Actionmaster/LinXcel/Digitus VC211A (em2800)
74 75 -> Dikom DK300 (em2882)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index b4a767060ed7..070f2576707e 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -175,3 +175,6 @@
175174 -> Asus Europa Hybrid OEM [1043:4847] 175174 -> Asus Europa Hybrid OEM [1043:4847]
176175 -> Leadtek Winfast DTV1000S [107d:6655] 176175 -> Leadtek Winfast DTV1000S [107d:6655]
177176 -> Beholder BeholdTV 505 RDS [0000:5051] 177176 -> Beholder BeholdTV 505 RDS [0000:5051]
178177 -> Hawell HW-404M7
179179 -> Beholder BeholdTV H7 [5ace:7190]
180180 -> Beholder BeholdTV A7 [5ace:7090]
diff --git a/Documentation/video4linux/extract_xc3028.pl b/Documentation/video4linux/extract_xc3028.pl
index 2cb816047fc1..47877deae6d7 100644
--- a/Documentation/video4linux/extract_xc3028.pl
+++ b/Documentation/video4linux/extract_xc3028.pl
@@ -5,12 +5,18 @@
5# 5#
6# In order to use, you need to: 6# In order to use, you need to:
7# 1) Download the windows driver with something like: 7# 1) Download the windows driver with something like:
8# Version 2.4
9# wget http://www.twinhan.com/files/AW/BDA T/20080303_V1.0.6.7.zip
10# or wget http://www.stefanringel.de/pub/20080303_V1.0.6.7.zip
11# Version 2.7
8# wget http://www.steventoth.net/linux/xc5000/HVR-12x0-14x0-17x0_1_25_25271_WHQL.zip 12# wget http://www.steventoth.net/linux/xc5000/HVR-12x0-14x0-17x0_1_25_25271_WHQL.zip
9# 2) Extract the file hcw85bda.sys from the zip into the current dir: 13# 2) Extract the files from the zip into the current dir:
14# unzip -j 20080303_V1.0.6.7.zip 20080303_v1.0.6.7/UDXTTM6000.sys
10# unzip -j HVR-12x0-14x0-17x0_1_25_25271_WHQL.zip Driver85/hcw85bda.sys 15# unzip -j HVR-12x0-14x0-17x0_1_25_25271_WHQL.zip Driver85/hcw85bda.sys
11# 3) run the script: 16# 3) run the script:
12# ./extract_xc3028.pl 17# ./extract_xc3028.pl
13# 4) copy the generated file: 18# 4) copy the generated files:
19# cp xc3028-v24.fw /lib/firmware
14# cp xc3028-v27.fw /lib/firmware 20# cp xc3028-v27.fw /lib/firmware
15 21
16#use strict; 22#use strict;
@@ -135,7 +141,7 @@ sub write_hunk_fix_endian($$)
135 } 141 }
136} 142}
137 143
138sub main_firmware($$$$) 144sub main_firmware_24($$$$)
139{ 145{
140 my $out; 146 my $out;
141 my $j=0; 147 my $j=0;
@@ -146,8 +152,774 @@ sub main_firmware($$$$)
146 152
147 for ($j = length($name); $j <32; $j++) { 153 for ($j = length($name); $j <32; $j++) {
148 $name = $name.chr(0); 154 $name = $name.chr(0);
155 }
156
157 open OUTFILE, ">$outfile";
158 syswrite(OUTFILE, $name);
159 write_le16($version);
160 write_le16($nr_desc);
161
162 #
163 # Firmware 0, type: BASE FW F8MHZ (0x00000003), id: (0000000000000000), size: 6635
164 #
165
166 write_le32(0x00000003); # Type
167 write_le64(0x00000000, 0x00000000); # ID
168 write_le32(6635); # Size
169 write_hunk_fix_endian(257752, 6635);
170
171 #
172 # Firmware 1, type: BASE FW F8MHZ MTS (0x00000007), id: (0000000000000000), size: 6635
173 #
174
175 write_le32(0x00000007); # Type
176 write_le64(0x00000000, 0x00000000); # ID
177 write_le32(6635); # Size
178 write_hunk_fix_endian(264392, 6635);
179
180 #
181 # Firmware 2, type: BASE FW FM (0x00000401), id: (0000000000000000), size: 6525
182 #
183
184 write_le32(0x00000401); # Type
185 write_le64(0x00000000, 0x00000000); # ID
186 write_le32(6525); # Size
187 write_hunk_fix_endian(271040, 6525);
188
189 #
190 # Firmware 3, type: BASE FW FM INPUT1 (0x00000c01), id: (0000000000000000), size: 6539
191 #
192
193 write_le32(0x00000c01); # Type
194 write_le64(0x00000000, 0x00000000); # ID
195 write_le32(6539); # Size
196 write_hunk_fix_endian(277568, 6539);
197
198 #
199 # Firmware 4, type: BASE FW (0x00000001), id: (0000000000000000), size: 6633
200 #
201
202 write_le32(0x00000001); # Type
203 write_le64(0x00000000, 0x00000000); # ID
204 write_le32(6633); # Size
205 write_hunk_fix_endian(284120, 6633);
206
207 #
208 # Firmware 5, type: BASE FW MTS (0x00000005), id: (0000000000000000), size: 6617
209 #
210
211 write_le32(0x00000005); # Type
212 write_le64(0x00000000, 0x00000000); # ID
213 write_le32(6617); # Size
214 write_hunk_fix_endian(290760, 6617);
215
216 #
217 # Firmware 6, type: STD FW (0x00000000), id: PAL/BG A2/A (0000000100000007), size: 161
218 #
219
220 write_le32(0x00000000); # Type
221 write_le64(0x00000001, 0x00000007); # ID
222 write_le32(161); # Size
223 write_hunk_fix_endian(297384, 161);
224
225 #
226 # Firmware 7, type: STD FW MTS (0x00000004), id: PAL/BG A2/A (0000000100000007), size: 169
227 #
228
229 write_le32(0x00000004); # Type
230 write_le64(0x00000001, 0x00000007); # ID
231 write_le32(169); # Size
232 write_hunk_fix_endian(297552, 169);
233
234 #
235 # Firmware 8, type: STD FW (0x00000000), id: PAL/BG A2/B (0000000200000007), size: 161
236 #
237
238 write_le32(0x00000000); # Type
239 write_le64(0x00000002, 0x00000007); # ID
240 write_le32(161); # Size
241 write_hunk_fix_endian(297728, 161);
242
243 #
244 # Firmware 9, type: STD FW MTS (0x00000004), id: PAL/BG A2/B (0000000200000007), size: 169
245 #
246
247 write_le32(0x00000004); # Type
248 write_le64(0x00000002, 0x00000007); # ID
249 write_le32(169); # Size
250 write_hunk_fix_endian(297896, 169);
251
252 #
253 # Firmware 10, type: STD FW (0x00000000), id: PAL/BG NICAM/A (0000000400000007), size: 161
254 #
255
256 write_le32(0x00000000); # Type
257 write_le64(0x00000004, 0x00000007); # ID
258 write_le32(161); # Size
259 write_hunk_fix_endian(298072, 161);
260
261 #
262 # Firmware 11, type: STD FW MTS (0x00000004), id: PAL/BG NICAM/A (0000000400000007), size: 169
263 #
264
265 write_le32(0x00000004); # Type
266 write_le64(0x00000004, 0x00000007); # ID
267 write_le32(169); # Size
268 write_hunk_fix_endian(298240, 169);
269
270 #
271 # Firmware 12, type: STD FW (0x00000000), id: PAL/BG NICAM/B (0000000800000007), size: 161
272 #
273
274 write_le32(0x00000000); # Type
275 write_le64(0x00000008, 0x00000007); # ID
276 write_le32(161); # Size
277 write_hunk_fix_endian(298416, 161);
278
279 #
280 # Firmware 13, type: STD FW MTS (0x00000004), id: PAL/BG NICAM/B (0000000800000007), size: 169
281 #
282
283 write_le32(0x00000004); # Type
284 write_le64(0x00000008, 0x00000007); # ID
285 write_le32(169); # Size
286 write_hunk_fix_endian(298584, 169);
287
288 #
289 # Firmware 14, type: STD FW (0x00000000), id: PAL/DK A2 (00000003000000e0), size: 161
290 #
291
292 write_le32(0x00000000); # Type
293 write_le64(0x00000003, 0x000000e0); # ID
294 write_le32(161); # Size
295 write_hunk_fix_endian(298760, 161);
296
297 #
298 # Firmware 15, type: STD FW MTS (0x00000004), id: PAL/DK A2 (00000003000000e0), size: 169
299 #
300
301 write_le32(0x00000004); # Type
302 write_le64(0x00000003, 0x000000e0); # ID
303 write_le32(169); # Size
304 write_hunk_fix_endian(298928, 169);
305
306 #
307 # Firmware 16, type: STD FW (0x00000000), id: PAL/DK NICAM (0000000c000000e0), size: 161
308 #
309
310 write_le32(0x00000000); # Type
311 write_le64(0x0000000c, 0x000000e0); # ID
312 write_le32(161); # Size
313 write_hunk_fix_endian(299104, 161);
314
315 #
316 # Firmware 17, type: STD FW MTS (0x00000004), id: PAL/DK NICAM (0000000c000000e0), size: 169
317 #
318
319 write_le32(0x00000004); # Type
320 write_le64(0x0000000c, 0x000000e0); # ID
321 write_le32(169); # Size
322 write_hunk_fix_endian(299272, 169);
323
324 #
325 # Firmware 18, type: STD FW (0x00000000), id: SECAM/K1 (0000000000200000), size: 161
326 #
327
328 write_le32(0x00000000); # Type
329 write_le64(0x00000000, 0x00200000); # ID
330 write_le32(161); # Size
331 write_hunk_fix_endian(299448, 161);
332
333 #
334 # Firmware 19, type: STD FW MTS (0x00000004), id: SECAM/K1 (0000000000200000), size: 169
335 #
336
337 write_le32(0x00000004); # Type
338 write_le64(0x00000000, 0x00200000); # ID
339 write_le32(169); # Size
340 write_hunk_fix_endian(299616, 169);
341
342 #
343 # Firmware 20, type: STD FW (0x00000000), id: SECAM/K3 (0000000004000000), size: 161
344 #
345
346 write_le32(0x00000000); # Type
347 write_le64(0x00000000, 0x04000000); # ID
348 write_le32(161); # Size
349 write_hunk_fix_endian(299792, 161);
350
351 #
352 # Firmware 21, type: STD FW MTS (0x00000004), id: SECAM/K3 (0000000004000000), size: 169
353 #
354
355 write_le32(0x00000004); # Type
356 write_le64(0x00000000, 0x04000000); # ID
357 write_le32(169); # Size
358 write_hunk_fix_endian(299960, 169);
359
360 #
361 # Firmware 22, type: STD FW D2633 DTV6 ATSC (0x00010030), id: (0000000000000000), size: 149
362 #
363
364 write_le32(0x00010030); # Type
365 write_le64(0x00000000, 0x00000000); # ID
366 write_le32(149); # Size
367 write_hunk_fix_endian(300136, 149);
368
369 #
370 # Firmware 23, type: STD FW D2620 DTV6 QAM (0x00000068), id: (0000000000000000), size: 149
371 #
372
373 write_le32(0x00000068); # Type
374 write_le64(0x00000000, 0x00000000); # ID
375 write_le32(149); # Size
376 write_hunk_fix_endian(300296, 149);
377
378 #
379 # Firmware 24, type: STD FW D2633 DTV6 QAM (0x00000070), id: (0000000000000000), size: 149
380 #
381
382 write_le32(0x00000070); # Type
383 write_le64(0x00000000, 0x00000000); # ID
384 write_le32(149); # Size
385 write_hunk_fix_endian(300448, 149);
386
387 #
388 # Firmware 25, type: STD FW D2620 DTV7 (0x00000088), id: (0000000000000000), size: 149
389 #
390
391 write_le32(0x00000088); # Type
392 write_le64(0x00000000, 0x00000000); # ID
393 write_le32(149); # Size
394 write_hunk_fix_endian(300608, 149);
395
396 #
397 # Firmware 26, type: STD FW D2633 DTV7 (0x00000090), id: (0000000000000000), size: 149
398 #
399
400 write_le32(0x00000090); # Type
401 write_le64(0x00000000, 0x00000000); # ID
402 write_le32(149); # Size
403 write_hunk_fix_endian(300760, 149);
404
405 #
406 # Firmware 27, type: STD FW D2620 DTV78 (0x00000108), id: (0000000000000000), size: 149
407 #
408
409 write_le32(0x00000108); # Type
410 write_le64(0x00000000, 0x00000000); # ID
411 write_le32(149); # Size
412 write_hunk_fix_endian(300920, 149);
413
414 #
415 # Firmware 28, type: STD FW D2633 DTV78 (0x00000110), id: (0000000000000000), size: 149
416 #
417
418 write_le32(0x00000110); # Type
419 write_le64(0x00000000, 0x00000000); # ID
420 write_le32(149); # Size
421 write_hunk_fix_endian(301072, 149);
422
423 #
424 # Firmware 29, type: STD FW D2620 DTV8 (0x00000208), id: (0000000000000000), size: 149
425 #
426
427 write_le32(0x00000208); # Type
428 write_le64(0x00000000, 0x00000000); # ID
429 write_le32(149); # Size
430 write_hunk_fix_endian(301232, 149);
431
432 #
433 # Firmware 30, type: STD FW D2633 DTV8 (0x00000210), id: (0000000000000000), size: 149
434 #
435
436 write_le32(0x00000210); # Type
437 write_le64(0x00000000, 0x00000000); # ID
438 write_le32(149); # Size
439 write_hunk_fix_endian(301384, 149);
440
441 #
442 # Firmware 31, type: STD FW FM (0x00000400), id: (0000000000000000), size: 135
443 #
444
445 write_le32(0x00000400); # Type
446 write_le64(0x00000000, 0x00000000); # ID
447 write_le32(135); # Size
448 write_hunk_fix_endian(301554, 135);
449
450 #
451 # Firmware 32, type: STD FW (0x00000000), id: PAL/I (0000000000000010), size: 161
452 #
453
454 write_le32(0x00000000); # Type
455 write_le64(0x00000000, 0x00000010); # ID
456 write_le32(161); # Size
457 write_hunk_fix_endian(301688, 161);
458
459 #
460 # Firmware 33, type: STD FW MTS (0x00000004), id: PAL/I (0000000000000010), size: 169
461 #
462
463 write_le32(0x00000004); # Type
464 write_le64(0x00000000, 0x00000010); # ID
465 write_le32(169); # Size
466 write_hunk_fix_endian(301856, 169);
467
468 #
469 # Firmware 34, type: STD FW (0x00000000), id: SECAM/L AM (0000001000400000), size: 169
470 #
471
472 #
473 # Firmware 35, type: STD FW (0x00000000), id: SECAM/L NICAM (0000000c00400000), size: 161
474 #
475
476 write_le32(0x00000000); # Type
477 write_le64(0x0000000c, 0x00400000); # ID
478 write_le32(161); # Size
479 write_hunk_fix_endian(302032, 161);
480
481 #
482 # Firmware 36, type: STD FW (0x00000000), id: SECAM/Lc (0000000000800000), size: 161
483 #
484
485 write_le32(0x00000000); # Type
486 write_le64(0x00000000, 0x00800000); # ID
487 write_le32(161); # Size
488 write_hunk_fix_endian(302200, 161);
489
490 #
491 # Firmware 37, type: STD FW (0x00000000), id: NTSC/M Kr (0000000000008000), size: 161
492 #
493
494 write_le32(0x00000000); # Type
495 write_le64(0x00000000, 0x00008000); # ID
496 write_le32(161); # Size
497 write_hunk_fix_endian(302368, 161);
498
499 #
500 # Firmware 38, type: STD FW LCD (0x00001000), id: NTSC/M Kr (0000000000008000), size: 161
501 #
502
503 write_le32(0x00001000); # Type
504 write_le64(0x00000000, 0x00008000); # ID
505 write_le32(161); # Size
506 write_hunk_fix_endian(302536, 161);
507
508 #
509 # Firmware 39, type: STD FW LCD NOGD (0x00003000), id: NTSC/M Kr (0000000000008000), size: 161
510 #
511
512 write_le32(0x00003000); # Type
513 write_le64(0x00000000, 0x00008000); # ID
514 write_le32(161); # Size
515 write_hunk_fix_endian(302704, 161);
516
517 #
518 # Firmware 40, type: STD FW MTS (0x00000004), id: NTSC/M Kr (0000000000008000), size: 169
519 #
520
521 write_le32(0x00000004); # Type
522 write_le64(0x00000000, 0x00008000); # ID
523 write_le32(169); # Size
524 write_hunk_fix_endian(302872, 169);
525
526 #
527 # Firmware 41, type: STD FW (0x00000000), id: NTSC PAL/M PAL/N (000000000000b700), size: 161
528 #
529
530 write_le32(0x00000000); # Type
531 write_le64(0x00000000, 0x0000b700); # ID
532 write_le32(161); # Size
533 write_hunk_fix_endian(303048, 161);
534
535 #
536 # Firmware 42, type: STD FW LCD (0x00001000), id: NTSC PAL/M PAL/N (000000000000b700), size: 161
537 #
538
539 write_le32(0x00001000); # Type
540 write_le64(0x00000000, 0x0000b700); # ID
541 write_le32(161); # Size
542 write_hunk_fix_endian(303216, 161);
543
544 #
545 # Firmware 43, type: STD FW LCD NOGD (0x00003000), id: NTSC PAL/M PAL/N (000000000000b700), size: 161
546 #
547
548 write_le32(0x00003000); # Type
549 write_le64(0x00000000, 0x0000b700); # ID
550 write_le32(161); # Size
551 write_hunk_fix_endian(303384, 161);
552
553 #
554 # Firmware 44, type: STD FW (0x00000000), id: NTSC/M Jp (0000000000002000), size: 161
555 #
556
557 write_le32(0x00000000); # Type
558 write_le64(0x00000000, 0x00002000); # ID
559 write_le32(161); # Size
560 write_hunk_fix_endian(303552, 161);
561
562 #
563 # Firmware 45, type: STD FW MTS (0x00000004), id: NTSC PAL/M PAL/N (000000000000b700), size: 169
564 #
565
566 write_le32(0x00000004); # Type
567 write_le64(0x00000000, 0x0000b700); # ID
568 write_le32(169); # Size
569 write_hunk_fix_endian(303720, 169);
570
571 #
572 # Firmware 46, type: STD FW MTS LCD (0x00001004), id: NTSC PAL/M PAL/N (000000000000b700), size: 169
573 #
574
575 write_le32(0x00001004); # Type
576 write_le64(0x00000000, 0x0000b700); # ID
577 write_le32(169); # Size
578 write_hunk_fix_endian(303896, 169);
579
580 #
581 # Firmware 47, type: STD FW MTS LCD NOGD (0x00003004), id: NTSC PAL/M PAL/N (000000000000b700), size: 169
582 #
583
584 write_le32(0x00003004); # Type
585 write_le64(0x00000000, 0x0000b700); # ID
586 write_le32(169); # Size
587 write_hunk_fix_endian(304072, 169);
588
589 #
590 # Firmware 48, type: SCODE FW HAS IF (0x60000000), IF = 3.28 MHz id: (0000000000000000), size: 192
591 #
592
593 write_le32(0x60000000); # Type
594 write_le64(0x00000000, 0x00000000); # ID
595 write_le16(3280); # IF
596 write_le32(192); # Size
597 write_hunk(309048, 192);
598
599 #
600 # Firmware 49, type: SCODE FW HAS IF (0x60000000), IF = 3.30 MHz id: (0000000000000000), size: 192
601 #
602
603# write_le32(0x60000000); # Type
604# write_le64(0x00000000, 0x00000000); # ID
605# write_le16(3300); # IF
606# write_le32(192); # Size
607# write_hunk(304440, 192);
608
609 #
610 # Firmware 50, type: SCODE FW HAS IF (0x60000000), IF = 3.44 MHz id: (0000000000000000), size: 192
611 #
612
613 write_le32(0x60000000); # Type
614 write_le64(0x00000000, 0x00000000); # ID
615 write_le16(3440); # IF
616 write_le32(192); # Size
617 write_hunk(309432, 192);
618
619 #
620 # Firmware 51, type: SCODE FW HAS IF (0x60000000), IF = 3.46 MHz id: (0000000000000000), size: 192
621 #
622
623 write_le32(0x60000000); # Type
624 write_le64(0x00000000, 0x00000000); # ID
625 write_le16(3460); # IF
626 write_le32(192); # Size
627 write_hunk(309624, 192);
628
629 #
630 # Firmware 52, type: SCODE FW DTV6 ATSC OREN36 HAS IF (0x60210020), IF = 3.80 MHz id: (0000000000000000), size: 192
631 #
632
633 write_le32(0x60210020); # Type
634 write_le64(0x00000000, 0x00000000); # ID
635 write_le16(3800); # IF
636 write_le32(192); # Size
637 write_hunk(306936, 192);
638
639 #
640 # Firmware 53, type: SCODE FW HAS IF (0x60000000), IF = 4.00 MHz id: (0000000000000000), size: 192
641 #
642
643 write_le32(0x60000000); # Type
644 write_le64(0x00000000, 0x00000000); # ID
645 write_le16(4000); # IF
646 write_le32(192); # Size
647 write_hunk(309240, 192);
648
649 #
650 # Firmware 54, type: SCODE FW DTV6 ATSC TOYOTA388 HAS IF (0x60410020), IF = 4.08 MHz id: (0000000000000000), size: 192
651 #
652
653 write_le32(0x60410020); # Type
654 write_le64(0x00000000, 0x00000000); # ID
655 write_le16(4080); # IF
656 write_le32(192); # Size
657 write_hunk(307128, 192);
658
659 #
660 # Firmware 55, type: SCODE FW HAS IF (0x60000000), IF = 4.20 MHz id: (0000000000000000), size: 192
661 #
662
663 write_le32(0x60000000); # Type
664 write_le64(0x00000000, 0x00000000); # ID
665 write_le16(4200); # IF
666 write_le32(192); # Size
667 write_hunk(308856, 192);
668
669 #
670 # Firmware 56, type: SCODE FW MONO HAS IF (0x60008000), IF = 4.32 MHz id: NTSC/M Kr (0000000000008000), size: 192
671 #
672
673 write_le32(0x60008000); # Type
674 write_le64(0x00000000, 0x00008000); # ID
675 write_le16(4320); # IF
676 write_le32(192); # Size
677 write_hunk(305208, 192);
678
679 #
680 # Firmware 57, type: SCODE FW HAS IF (0x60000000), IF = 4.45 MHz id: (0000000000000000), size: 192
681 #
682
683 write_le32(0x60000000); # Type
684 write_le64(0x00000000, 0x00000000); # ID
685 write_le16(4450); # IF
686 write_le32(192); # Size
687 write_hunk(309816, 192);
688
689 #
690 # Firmware 58, type: SCODE FW MTS LCD NOGD MONO IF HAS IF (0x6002b004), IF = 4.50 MHz id: NTSC PAL/M PAL/N (000000000000b700), size: 192
691 #
692
693 write_le32(0x6002b004); # Type
694 write_le64(0x00000000, 0x0000b700); # ID
695 write_le16(4500); # IF
696 write_le32(192); # Size
697 write_hunk(304824, 192);
698
699 #
700 # Firmware 59, type: SCODE FW LCD NOGD IF HAS IF (0x60023000), IF = 4.60 MHz id: NTSC/M Kr (0000000000008000), size: 192
701 #
702
703 write_le32(0x60023000); # Type
704 write_le64(0x00000000, 0x00008000); # ID
705 write_le16(4600); # IF
706 write_le32(192); # Size
707 write_hunk(305016, 192);
708
709 #
710 # Firmware 60, type: SCODE FW DTV6 QAM DTV7 DTV78 DTV8 ZARLINK456 HAS IF (0x620003e0), IF = 4.76 MHz id: (0000000000000000), size: 192
711 #
712
713 write_le32(0x620003e0); # Type
714 write_le64(0x00000000, 0x00000000); # ID
715 write_le16(4760); # IF
716 write_le32(192); # Size
717 write_hunk(304440, 192);
718
719 #
720 # Firmware 61, type: SCODE FW HAS IF (0x60000000), IF = 4.94 MHz id: (0000000000000000), size: 192
721 #
722
723 write_le32(0x60000000); # Type
724 write_le64(0x00000000, 0x00000000); # ID
725 write_le16(4940); # IF
726 write_le32(192); # Size
727 write_hunk(308664, 192);
728
729 #
730 # Firmware 62, type: SCODE FW HAS IF (0x60000000), IF = 5.26 MHz id: (0000000000000000), size: 192
731 #
732
733 write_le32(0x60000000); # Type
734 write_le64(0x00000000, 0x00000000); # ID
735 write_le16(5260); # IF
736 write_le32(192); # Size
737 write_hunk(307704, 192);
738
739 #
740 # Firmware 63, type: SCODE FW MONO HAS IF (0x60008000), IF = 5.32 MHz id: PAL/BG A2 NICAM (0000000f00000007), size: 192
741 #
742
743 write_le32(0x60008000); # Type
744 write_le64(0x0000000f, 0x00000007); # ID
745 write_le16(5320); # IF
746 write_le32(192); # Size
747 write_hunk(307896, 192);
748
749 #
750 # Firmware 64, type: SCODE FW DTV7 DTV78 DTV8 DIBCOM52 CHINA HAS IF (0x65000380), IF = 5.40 MHz id: (0000000000000000), size: 192
751 #
752
753 write_le32(0x65000380); # Type
754 write_le64(0x00000000, 0x00000000); # ID
755 write_le16(5400); # IF
756 write_le32(192); # Size
757 write_hunk(304248, 192);
758
759 #
760 # Firmware 65, type: SCODE FW DTV6 ATSC OREN538 HAS IF (0x60110020), IF = 5.58 MHz id: (0000000000000000), size: 192
761 #
762
763 write_le32(0x60110020); # Type
764 write_le64(0x00000000, 0x00000000); # ID
765 write_le16(5580); # IF
766 write_le32(192); # Size
767 write_hunk(306744, 192);
768
769 #
770 # Firmware 66, type: SCODE FW HAS IF (0x60000000), IF = 5.64 MHz id: PAL/BG A2 (0000000300000007), size: 192
771 #
772
773 write_le32(0x60000000); # Type
774 write_le64(0x00000003, 0x00000007); # ID
775 write_le16(5640); # IF
776 write_le32(192); # Size
777 write_hunk(305592, 192);
778
779 #
780 # Firmware 67, type: SCODE FW HAS IF (0x60000000), IF = 5.74 MHz id: PAL/BG NICAM (0000000c00000007), size: 192
781 #
782
783 write_le32(0x60000000); # Type
784 write_le64(0x0000000c, 0x00000007); # ID
785 write_le16(5740); # IF
786 write_le32(192); # Size
787 write_hunk(305784, 192);
788
789 #
790 # Firmware 68, type: SCODE FW HAS IF (0x60000000), IF = 5.90 MHz id: (0000000000000000), size: 192
791 #
792
793 write_le32(0x60000000); # Type
794 write_le64(0x00000000, 0x00000000); # ID
795 write_le16(5900); # IF
796 write_le32(192); # Size
797 write_hunk(307512, 192);
798
799 #
800 # Firmware 69, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.00 MHz id: PAL/DK PAL/I SECAM/K3 SECAM/L SECAM/Lc NICAM (0000000c04c000f0), size: 192
801 #
802
803 write_le32(0x60008000); # Type
804 write_le64(0x0000000c, 0x04c000f0); # ID
805 write_le16(6000); # IF
806 write_le32(192); # Size
807 write_hunk(305576, 192);
808
809 #
810 # Firmware 70, type: SCODE FW DTV6 QAM ATSC LG60 F6MHZ HAS IF (0x68050060), IF = 6.20 MHz id: (0000000000000000), size: 192
811 #
812
813 write_le32(0x68050060); # Type
814 write_le64(0x00000000, 0x00000000); # ID
815 write_le16(6200); # IF
816 write_le32(192); # Size
817 write_hunk(306552, 192);
818
819 #
820 # Firmware 71, type: SCODE FW HAS IF (0x60000000), IF = 6.24 MHz id: PAL/I (0000000000000010), size: 192
821 #
822
823 write_le32(0x60000000); # Type
824 write_le64(0x00000000, 0x00000010); # ID
825 write_le16(6240); # IF
826 write_le32(192); # Size
827 write_hunk(305400, 192);
828
829 #
830 # Firmware 72, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.32 MHz id: SECAM/K1 (0000000000200000), size: 192
831 #
832
833 write_le32(0x60008000); # Type
834 write_le64(0x00000000, 0x00200000); # ID
835 write_le16(6320); # IF
836 write_le32(192); # Size
837 write_hunk(308472, 192);
838
839 #
840 # Firmware 73, type: SCODE FW HAS IF (0x60000000), IF = 6.34 MHz id: SECAM/K1 (0000000000200000), size: 192
841 #
842
843 write_le32(0x60000000); # Type
844 write_le64(0x00000000, 0x00200000); # ID
845 write_le16(6340); # IF
846 write_le32(192); # Size
847 write_hunk(306360, 192);
848
849 #
850 # Firmware 74, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.50 MHz id: PAL/DK SECAM/K3 SECAM/L NICAM (0000000c044000e0), size: 192
851 #
852
853 write_le32(0x60008000); # Type
854 write_le64(0x0000000c, 0x044000e0); # ID
855 write_le16(6500); # IF
856 write_le32(192); # Size
857 write_hunk(308280, 192);
858
859 #
860 # Firmware 75, type: SCODE FW DTV6 ATSC ATI638 HAS IF (0x60090020), IF = 6.58 MHz id: (0000000000000000), size: 192
861 #
862
863 write_le32(0x60090020); # Type
864 write_le64(0x00000000, 0x00000000); # ID
865 write_le16(6580); # IF
866 write_le32(192); # Size
867 write_hunk(304632, 192);
868
869 #
870 # Firmware 76, type: SCODE FW HAS IF (0x60000000), IF = 6.60 MHz id: PAL/DK A2 (00000003000000e0), size: 192
871 #
872
873 write_le32(0x60000000); # Type
874 write_le64(0x00000003, 0x000000e0); # ID
875 write_le16(6600); # IF
876 write_le32(192); # Size
877 write_hunk(306168, 192);
878
879 #
880 # Firmware 77, type: SCODE FW MONO HAS IF (0x60008000), IF = 6.68 MHz id: PAL/DK A2 (00000003000000e0), size: 192
881 #
882
883 write_le32(0x60008000); # Type
884 write_le64(0x00000003, 0x000000e0); # ID
885 write_le16(6680); # IF
886 write_le32(192); # Size
887 write_hunk(308088, 192);
888
889 #
890 # Firmware 78, type: SCODE FW DTV6 ATSC TOYOTA794 HAS IF (0x60810020), IF = 8.14 MHz id: (0000000000000000), size: 192
891 #
892
893 write_le32(0x60810020); # Type
894 write_le64(0x00000000, 0x00000000); # ID
895 write_le16(8140); # IF
896 write_le32(192); # Size
897 write_hunk(307320, 192);
898
899 #
900 # Firmware 79, type: SCODE FW HAS IF (0x60000000), IF = 8.20 MHz id: (0000000000000000), size: 192
901 #
902
903# write_le32(0x60000000); # Type
904# write_le64(0x00000000, 0x00000000); # ID
905# write_le16(8200); # IF
906# write_le32(192); # Size
907# write_hunk(308088, 192);
149} 908}
150 909
910sub main_firmware_27($$$$)
911{
912 my $out;
913 my $j=0;
914 my $outfile = shift;
915 my $name = shift;
916 my $version = shift;
917 my $nr_desc = shift;
918
919 for ($j = length($name); $j <32; $j++) {
920 $name = $name.chr(0);
921 }
922
151 open OUTFILE, ">$outfile"; 923 open OUTFILE, ">$outfile";
152 syswrite(OUTFILE, $name); 924 syswrite(OUTFILE, $name);
153 write_le16($version); 925 write_le16($version);
@@ -906,20 +1678,39 @@ sub main_firmware($$$$)
906 write_hunk(812856, 192); 1678 write_hunk(812856, 192);
907} 1679}
908 1680
1681
909sub extract_firmware { 1682sub extract_firmware {
910 my $sourcefile = "hcw85bda.sys"; 1683 my $sourcefile_24 = "UDXTTM6000.sys";
911 my $hash = "0e44dbf63bb0169d57446aec21881ff2"; 1684 my $hash_24 = "cb9deb5508a5e150af2880f5b0066d78";
912 my $outfile = "xc3028-v27.fw"; 1685 my $outfile_24 = "xc3028-v24.fw";
913 my $name = "xc2028 firmware"; 1686 my $name_24 = "xc2028 firmware";
914 my $version = 519; 1687 my $version_24 = 516;
915 my $nr_desc = 80; 1688 my $nr_desc_24 = 77;
1689 my $out;
1690
1691 my $sourcefile_27 = "hcw85bda.sys";
1692 my $hash_27 = "0e44dbf63bb0169d57446aec21881ff2";
1693 my $outfile_27 = "xc3028-v27.fw";
1694 my $name_27 = "xc2028 firmware";
1695 my $version_27 = 519;
1696 my $nr_desc_27 = 80;
916 my $out; 1697 my $out;
917 1698
918 verify($sourcefile, $hash); 1699 if (-e $sourcefile_24) {
1700 verify($sourcefile_24, $hash_24);
1701
1702 open INFILE, "<$sourcefile_24";
1703 main_firmware_24($outfile_24, $name_24, $version_24, $nr_desc_24);
1704 close INFILE;
1705 }
919 1706
920 open INFILE, "<$sourcefile"; 1707 if (-e $sourcefile_27) {
921 main_firmware($outfile, $name, $version, $nr_desc); 1708 verify($sourcefile_27, $hash_27);
922 close INFILE; 1709
1710 open INFILE, "<$sourcefile_27";
1711 main_firmware_27($outfile_27, $name_27, $version_27, $nr_desc_27);
1712 close INFILE;
1713 }
923} 1714}
924 1715
925extract_firmware; 1716extract_firmware;
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 181b9e6fd984..8f3f5d33327c 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -50,6 +50,8 @@ zc3xx 0458:700f Genius VideoCam Web V2
50sonixj 0458:7025 Genius Eye 311Q 50sonixj 0458:7025 Genius Eye 311Q
51sn9c20x 0458:7029 Genius Look 320s 51sn9c20x 0458:7029 Genius Look 320s
52sonixj 0458:702e Genius Slim 310 NB 52sonixj 0458:702e Genius Slim 310 NB
53sn9c20x 0458:704a Genius Slim 1320
54sn9c20x 0458:704c Genius i-Look 1321
53sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) 55sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650)
54sonixj 045e:00f5 MicroSoft VX3000 56sonixj 045e:00f5 MicroSoft VX3000
55sonixj 045e:00f7 MicroSoft VX1000 57sonixj 045e:00f7 MicroSoft VX1000
@@ -305,12 +307,14 @@ sonixj 0c45:6138 Sn9c120 Mo4000
305sonixj 0c45:613a Microdia Sonix PC Camera 307sonixj 0c45:613a Microdia Sonix PC Camera
306sonixj 0c45:613b Surfer SN-206 308sonixj 0c45:613b Surfer SN-206
307sonixj 0c45:613c Sonix Pccam168 309sonixj 0c45:613c Sonix Pccam168
310sonixj 0c45:6142 Hama PC-Webcam AC-150
308sonixj 0c45:6143 Sonix Pccam168 311sonixj 0c45:6143 Sonix Pccam168
309sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia 312sonixj 0c45:6148 Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
310sonixj 0c45:614a Frontech E-Ccam (JIL-2225) 313sonixj 0c45:614a Frontech E-Ccam (JIL-2225)
311sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001) 314sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001)
312sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111) 315sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111)
313sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655) 316sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655)
317sn9c20x 0c45:624c PC Camera (SN9C201 + MT9M112)
314sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968) 318sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968)
315sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650) 319sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650)
316sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650) 320sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650)
@@ -323,6 +327,7 @@ sn9c20x 0c45:627f PC Camera (SN9C201 + OV9650)
323sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001) 327sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001)
324sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111) 328sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111)
325sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655) 329sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655)
330sn9c20x 0c45:628c PC Camera (SN9C201 + MT9M112)
326sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968) 331sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968)
327sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650) 332sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650)
328sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670) 333sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670)
diff --git a/Documentation/video4linux/sh_mobile_ceu_camera.txt b/Documentation/video4linux/sh_mobile_ceu_camera.txt
index 2ae16349a78d..cb47e723af74 100644
--- a/Documentation/video4linux/sh_mobile_ceu_camera.txt
+++ b/Documentation/video4linux/sh_mobile_ceu_camera.txt
@@ -17,18 +17,18 @@ Generic scaling / cropping scheme
17-2-- -\ 17-2-- -\
18| --\ 18| --\
19| --\ 19| --\
20+-5-- -\ -- -3-- 20+-5-- . -- -3-- -\
21| ---\ 21| `... -\
22| --- -4-- -\ 22| `... -4-- . - -7..
23| -\ 23| `.
24| - -6-- 24| `. .6--
25| 25|
26| - -6'- 26| . .6'-
27| -/ 27| .´
28| --- -4'- -/ 28| ... -4'- .´
29| ---/ 29| ...´ - -7'.
30+-5'- -/ 30+-5'- .´ -/
31| -- -3'- 31| -- -3'- -/
32| --/ 32| --/
33| --/ 33| --/
34-2'- -/ 34-2'- -/
@@ -36,7 +36,11 @@ Generic scaling / cropping scheme
36| 36|
37-1'- 37-1'-
38 38
39Produced by user requests: 39In the above chart minuses and slashes represent "real" data amounts, points and
40accents represent "useful" data, basically, CEU scaled amd cropped output,
41mapped back onto the client's source plane.
42
43Such a configuration can be produced by user requests:
40 44
41S_CROP(left / top = (5) - (1), width / height = (5') - (5)) 45S_CROP(left / top = (5) - (1), width / height = (5') - (5))
42S_FMT(width / height = (6') - (6)) 46S_FMT(width / height = (6') - (6))
@@ -106,52 +110,30 @@ window:
106S_CROP 110S_CROP
107------ 111------
108 112
109If old scale applied to new crop is invalid produce nearest new scale possible 113The API at http://v4l2spec.bytesex.org/spec/x1904.htm says:
110
1111. Calculate current combined scales.
112
113 scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
114
1152. Apply iterative sensor S_CROP for new input window.
116
1173. If old combined scales applied to new crop produce an impossible user window,
118adjust scales to produce nearest possible window.
119
120 width_u_out = ((5') - (5)) / scale_comb
121 114
122 if (width_u_out > max) 115"...specification does not define an origin or units. However by convention
123 scale_comb = ((5') - (5)) / max; 116drivers should horizontally count unscaled samples relative to 0H."
124 else if (width_u_out < min)
125 scale_comb = ((5') - (5)) / min;
126 117
1274. Issue G_CROP to retrieve actual input window. 118We choose to follow the advise and interpret cropping units as client input
119pixels.
128 120
1295. Using actual input window and calculated combined scales calculate sensor 121Cropping is performed in the following 6 steps:
130target output window.
131
132 width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
133
1346. Apply iterative S_FMT for new sensor target output window.
135
1367. Issue G_FMT to retrieve the actual sensor output window.
137
1388. Calculate sensor scales.
139
140 scale_s = ((3') - (3)) / ((2') - (2))
141 122
1429. Calculate sensor output subwindow to be cropped on CEU by applying sensor 1231. Request exactly user rectangle from the sensor.
143scales to the requested window.
144 124
145 width_ceu = ((5') - (5)) / scale_s 1252. If smaller - iterate until a larger one is obtained. Result: sensor cropped
126 to 2 : 2', target crop 5 : 5', current output format 6' - 6.
146 127
14710. Use CEU cropping for above calculated window. 1283. In the previous step the sensor has tried to preserve its output frame as
129 good as possible, but it could have changed. Retrieve it again.
148 130
14911. Calculate CEU scales from sensor scales from results of (10) and user window 1314. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
150from (3) 132 intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
151 133
152 scale_ceu = calc_scale(((5') - (5)), &width_u_out) 1345. Calculate and apply host scale = (6' - 6) / (4' - 4)
153 135
15412. Apply CEU scales. 1366. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
155 137
156-- 138--
157Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> 139Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 5155700c206b..e831aaca66f8 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -545,12 +545,11 @@ unregister them:
545This will remove the device nodes from sysfs (causing udev to remove them 545This will remove the device nodes from sysfs (causing udev to remove them
546from /dev). 546from /dev).
547 547
548After video_unregister_device() returns no new opens can be done. 548After video_unregister_device() returns no new opens can be done. However,
549 549in the case of USB devices some application might still have one of these
550However, in the case of USB devices some application might still have one 550device nodes open. So after the unregister all file operations will return
551of these device nodes open. You should block all new accesses to read, 551an error as well, except for the ioctl and unlocked_ioctl file operations:
552write, poll, etc. except possibly for certain ioctl operations like 552those will still be passed on since some buffer ioctls may still be needed.
553queueing buffers.
554 553
555When the last user of the video device node exits, then the vdev->release() 554When the last user of the video device node exits, then the vdev->release()
556callback is called and you can do the final cleanup there. 555callback is called and you can do the final cleanup there.
@@ -609,3 +608,135 @@ scatter/gather method (videobuf-dma-sg), DMA with linear access
609 608
610Please see Documentation/video4linux/videobuf for more information on how 609Please see Documentation/video4linux/videobuf for more information on how
611to use the videobuf layer. 610to use the videobuf layer.
611
612struct v4l2_fh
613--------------
614
615struct v4l2_fh provides a way to easily keep file handle specific data
616that is used by the V4L2 framework. Using v4l2_fh is optional for
617drivers.
618
619The users of v4l2_fh (in the V4L2 framework, not the driver) know
620whether a driver uses v4l2_fh as its file->private_data pointer by
621testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags.
622
623Useful functions:
624
625- v4l2_fh_init()
626
627 Initialise the file handle. This *MUST* be performed in the driver's
628 v4l2_file_operations->open() handler.
629
630- v4l2_fh_add()
631
632 Add a v4l2_fh to video_device file handle list. May be called after
633 initialising the file handle.
634
635- v4l2_fh_del()
636
637 Unassociate the file handle from video_device(). The file handle
638 exit function may now be called.
639
640- v4l2_fh_exit()
641
642 Uninitialise the file handle. After uninitialisation the v4l2_fh
643 memory can be freed.
644
645struct v4l2_fh is allocated as a part of the driver's own file handle
646structure and is set to file->private_data in the driver's open
647function by the driver. Drivers can extract their own file handle
648structure by using the container_of macro. Example:
649
650struct my_fh {
651 int blah;
652 struct v4l2_fh fh;
653};
654
655...
656
657int my_open(struct file *file)
658{
659 struct my_fh *my_fh;
660 struct video_device *vfd;
661 int ret;
662
663 ...
664
665 ret = v4l2_fh_init(&my_fh->fh, vfd);
666 if (ret)
667 return ret;
668
669 v4l2_fh_add(&my_fh->fh);
670
671 file->private_data = &my_fh->fh;
672
673 ...
674}
675
676int my_release(struct file *file)
677{
678 struct v4l2_fh *fh = file->private_data;
679 struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
680
681 ...
682}
683
684V4L2 events
685-----------
686
687The V4L2 events provide a generic way to pass events to user space.
688The driver must use v4l2_fh to be able to support V4L2 events.
689
690Useful functions:
691
692- v4l2_event_alloc()
693
694 To use events, the driver must allocate events for the file handle. By
695 calling the function more than once, the driver may assure that at least n
696 events in total have been allocated. The function may not be called in
697 atomic context.
698
699- v4l2_event_queue()
700
701 Queue events to video device. The driver's only responsibility is to fill
702 in the type and the data fields. The other fields will be filled in by
703 V4L2.
704
705- v4l2_event_subscribe()
706
707 The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
708 is able to produce events with specified event id. Then it calls
709 v4l2_event_subscribe() to subscribe the event.
710
711- v4l2_event_unsubscribe()
712
713 vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
714 v4l2_event_unsubscribe() directly unless it wants to be involved in
715 unsubscription process.
716
717 The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
718 drivers may want to handle this in a special way.
719
720- v4l2_event_pending()
721
722 Returns the number of pending events. Useful when implementing poll.
723
724Drivers do not initialise events directly. The events are initialised
725through v4l2_fh_init() if video_device->ioctl_ops->vidioc_subscribe_event is
726non-NULL. This *MUST* be performed in the driver's
727v4l2_file_operations->open() handler.
728
729Events are delivered to user space through the poll system call. The driver
730can use v4l2_fh->events->wait wait_queue_head_t as the argument for
731poll_wait().
732
733There are standard and private events. New standard events must use the
734smallest available event type. The drivers must allocate their events from
735their own class starting from class base. Class base is
736V4L2_EVENT_PRIVATE_START + n * 1000 where n is the lowest available number.
737The first event type in the class is reserved for future use, so the first
738available event type is 'class base + 1'.
739
740An example on how the V4L2 events may be used can be found in the OMAP
7413 ISP driver available at <URL:http://gitorious.org/omap3camera> as of
742writing this.
diff --git a/MAINTAINERS b/MAINTAINERS
index 2f5510cc142d..f860e2ec1b71 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5963,7 +5963,7 @@ M: Laurent Pinchart <laurent.pinchart@skynet.be>
5963L: linux-uvc-devel@lists.berlios.de (subscribers-only) 5963L: linux-uvc-devel@lists.berlios.de (subscribers-only)
5964L: linux-media@vger.kernel.org 5964L: linux-media@vger.kernel.org
5965T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git 5965T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
5966W: http://linux-uvc.berlios.de 5966W: http://www.ideasonboard.org/uvc/
5967S: Maintained 5967S: Maintained
5968F: drivers/media/video/uvc/ 5968F: drivers/media/video/uvc/
5969 5969
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index 4dde7d180a32..195c6cf359f6 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -7,3 +7,62 @@ config VIDEO_IR
7 tristate 7 tristate
8 depends on IR_CORE 8 depends on IR_CORE
9 default IR_CORE 9 default IR_CORE
10
11source "drivers/media/IR/keymaps/Kconfig"
12
13config IR_NEC_DECODER
14 tristate "Enable IR raw decoder for the NEC protocol"
15 depends on IR_CORE
16 default y
17
18 ---help---
19 Enable this option if you have IR with NEC protocol, and
20 if the IR is decoded in software
21
22config IR_RC5_DECODER
23 tristate "Enable IR raw decoder for the RC-5 protocol"
24 depends on IR_CORE
25 default y
26
27 ---help---
28 Enable this option if you have IR with RC-5 protocol, and
29 if the IR is decoded in software
30
31config IR_RC6_DECODER
32 tristate "Enable IR raw decoder for the RC6 protocol"
33 depends on IR_CORE
34 default y
35
36 ---help---
37 Enable this option if you have an infrared remote control which
38 uses the RC6 protocol, and you need software decoding support.
39
40config IR_JVC_DECODER
41 tristate "Enable IR raw decoder for the JVC protocol"
42 depends on IR_CORE
43 default y
44
45 ---help---
46 Enable this option if you have an infrared remote control which
47 uses the JVC protocol, and you need software decoding support.
48
49config IR_SONY_DECODER
50 tristate "Enable IR raw decoder for the Sony protocol"
51 depends on IR_CORE
52 default y
53
54 ---help---
55 Enable this option if you have an infrared remote control which
56 uses the Sony protocol, and you need software decoding support.
57
58config IR_IMON
59 tristate "SoundGraph iMON Receiver and Display"
60 depends on USB_ARCH_HAS_HCD
61 depends on IR_CORE
62 select USB
63 ---help---
64 Say Y here if you want to use a SoundGraph iMON (aka Antec Veris)
65 IR Receiver and/or LCD/VFD/VGA display.
66
67 To compile this driver as a module, choose M here: the
68 module will be called imon.
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index 171890e7a41d..b998fcced2e4 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -1,5 +1,15 @@
1ir-common-objs := ir-functions.o ir-keymaps.o 1ir-common-objs := ir-functions.o
2ir-core-objs := ir-keytable.o ir-sysfs.o 2ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o rc-map.o
3
4obj-y += keymaps/
3 5
4obj-$(CONFIG_IR_CORE) += ir-core.o 6obj-$(CONFIG_IR_CORE) += ir-core.o
5obj-$(CONFIG_VIDEO_IR) += ir-common.o 7obj-$(CONFIG_VIDEO_IR) += ir-common.o
8obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
9obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
10obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
11obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
12obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
13
14# stand-alone IR receivers/transmitters
15obj-$(CONFIG_IR_IMON) += imon.o
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
new file mode 100644
index 000000000000..5e2045670004
--- /dev/null
+++ b/drivers/media/IR/imon.c
@@ -0,0 +1,2396 @@
1/*
2 * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD
3 *
4 * Copyright(C) 2009 Jarod Wilson <jarod@wilsonet.com>
5 * Portions based on the original lirc_imon driver,
6 * Copyright(C) 2004 Venky Raju(dev@venky.ws)
7 *
8 * Huge thanks to R. Geoff Newbury for invaluable debugging on the
9 * 0xffdc iMON devices, and for sending me one to hack on, without
10 * which the support for them wouldn't be nearly as good. Thanks
11 * also to the numerous 0xffdc device owners that tested auto-config
12 * support for me and provided debug dumps from their devices.
13 *
14 * imon is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <linux/uaccess.h>
35
36#include <linux/input.h>
37#include <linux/usb.h>
38#include <linux/usb/input.h>
39#include <media/ir-core.h>
40
41#include <linux/time.h>
42#include <linux/timer.h>
43
44#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
45#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
46#define MOD_NAME "imon"
47#define MOD_VERSION "0.9.1"
48
49#define DISPLAY_MINOR_BASE 144
50#define DEVICE_NAME "lcd%d"
51
52#define BUF_CHUNK_SIZE 8
53#define BUF_SIZE 128
54
55#define BIT_DURATION 250 /* each bit received is 250us */
56
57#define IMON_CLOCK_ENABLE_PACKETS 2
58
59/*** P R O T O T Y P E S ***/
60
61/* USB Callback prototypes */
62static int imon_probe(struct usb_interface *interface,
63 const struct usb_device_id *id);
64static void imon_disconnect(struct usb_interface *interface);
65static void usb_rx_callback_intf0(struct urb *urb);
66static void usb_rx_callback_intf1(struct urb *urb);
67static void usb_tx_callback(struct urb *urb);
68
69/* suspend/resume support */
70static int imon_resume(struct usb_interface *intf);
71static int imon_suspend(struct usb_interface *intf, pm_message_t message);
72
73/* Display file_operations function prototypes */
74static int display_open(struct inode *inode, struct file *file);
75static int display_close(struct inode *inode, struct file *file);
76
77/* VFD write operation */
78static ssize_t vfd_write(struct file *file, const char *buf,
79 size_t n_bytes, loff_t *pos);
80
81/* LCD file_operations override function prototypes */
82static ssize_t lcd_write(struct file *file, const char *buf,
83 size_t n_bytes, loff_t *pos);
84
85/*** G L O B A L S ***/
86
87struct imon_context {
88 struct device *dev;
89 struct ir_dev_props *props;
90 struct ir_input_dev *ir;
91 /* Newer devices have two interfaces */
92 struct usb_device *usbdev_intf0;
93 struct usb_device *usbdev_intf1;
94
95 bool display_supported; /* not all controllers do */
96 bool display_isopen; /* display port has been opened */
97 bool rf_isassociating; /* RF remote associating */
98 bool dev_present_intf0; /* USB device presence, interface 0 */
99 bool dev_present_intf1; /* USB device presence, interface 1 */
100
101 struct mutex lock; /* to lock this object */
102 wait_queue_head_t remove_ok; /* For unexpected USB disconnects */
103
104 struct usb_endpoint_descriptor *rx_endpoint_intf0;
105 struct usb_endpoint_descriptor *rx_endpoint_intf1;
106 struct usb_endpoint_descriptor *tx_endpoint;
107 struct urb *rx_urb_intf0;
108 struct urb *rx_urb_intf1;
109 struct urb *tx_urb;
110 bool tx_control;
111 unsigned char usb_rx_buf[8];
112 unsigned char usb_tx_buf[8];
113
114 struct tx_t {
115 unsigned char data_buf[35]; /* user data buffer */
116 struct completion finished; /* wait for write to finish */
117 bool busy; /* write in progress */
118 int status; /* status of tx completion */
119 } tx;
120
121 u16 vendor; /* usb vendor ID */
122 u16 product; /* usb product ID */
123
124 struct input_dev *idev; /* input device for remote */
125 struct input_dev *touch; /* input device for touchscreen */
126
127 u32 kc; /* current input keycode */
128 u32 last_keycode; /* last reported input keycode */
129 u64 ir_type; /* iMON or MCE (RC6) IR protocol? */
130 u8 mce_toggle_bit; /* last mce toggle bit */
131 bool release_code; /* some keys send a release code */
132
133 u8 display_type; /* store the display type */
134 bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */
135
136 char name_idev[128]; /* input device name */
137 char phys_idev[64]; /* input device phys path */
138 struct timer_list itimer; /* input device timer, need for rc6 */
139
140 char name_touch[128]; /* touch screen name */
141 char phys_touch[64]; /* touch screen phys path */
142 struct timer_list ttimer; /* touch screen timer */
143 int touch_x; /* x coordinate on touchscreen */
144 int touch_y; /* y coordinate on touchscreen */
145};
146
147#define TOUCH_TIMEOUT (HZ/30)
148
149/* vfd character device file operations */
150static const struct file_operations vfd_fops = {
151 .owner = THIS_MODULE,
152 .open = &display_open,
153 .write = &vfd_write,
154 .release = &display_close
155};
156
157/* lcd character device file operations */
158static const struct file_operations lcd_fops = {
159 .owner = THIS_MODULE,
160 .open = &display_open,
161 .write = &lcd_write,
162 .release = &display_close
163};
164
165enum {
166 IMON_DISPLAY_TYPE_AUTO = 0,
167 IMON_DISPLAY_TYPE_VFD = 1,
168 IMON_DISPLAY_TYPE_LCD = 2,
169 IMON_DISPLAY_TYPE_VGA = 3,
170 IMON_DISPLAY_TYPE_NONE = 4,
171};
172
173enum {
174 IMON_KEY_IMON = 0,
175 IMON_KEY_MCE = 1,
176 IMON_KEY_PANEL = 2,
177};
178
179/*
180 * USB Device ID for iMON USB Control Boards
181 *
182 * The Windows drivers contain 6 different inf files, more or less one for
183 * each new device until the 0x0034-0x0046 devices, which all use the same
184 * driver. Some of the devices in the 34-46 range haven't been definitively
185 * identified yet. Early devices have either a TriGem Computer, Inc. or a
186 * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
187 * devices use the SoundGraph vendor ID (0x15c2). This driver only supports
188 * the ffdc and later devices, which do onboard decoding.
189 */
190static struct usb_device_id imon_usb_id_table[] = {
191 /*
192 * Several devices with this same device ID, all use iMON_PAD.inf
193 * SoundGraph iMON PAD (IR & VFD)
194 * SoundGraph iMON PAD (IR & LCD)
195 * SoundGraph iMON Knob (IR only)
196 */
197 { USB_DEVICE(0x15c2, 0xffdc) },
198
199 /*
200 * Newer devices, all driven by the latest iMON Windows driver, full
201 * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2'
202 * Need user input to fill in details on unknown devices.
203 */
204 /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
205 { USB_DEVICE(0x15c2, 0x0034) },
206 /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
207 { USB_DEVICE(0x15c2, 0x0035) },
208 /* SoundGraph iMON OEM VFD (IR & VFD) */
209 { USB_DEVICE(0x15c2, 0x0036) },
210 /* device specifics unknown */
211 { USB_DEVICE(0x15c2, 0x0037) },
212 /* SoundGraph iMON OEM LCD (IR & LCD) */
213 { USB_DEVICE(0x15c2, 0x0038) },
214 /* SoundGraph iMON UltraBay (IR & LCD) */
215 { USB_DEVICE(0x15c2, 0x0039) },
216 /* device specifics unknown */
217 { USB_DEVICE(0x15c2, 0x003a) },
218 /* device specifics unknown */
219 { USB_DEVICE(0x15c2, 0x003b) },
220 /* SoundGraph iMON OEM Inside (IR only) */
221 { USB_DEVICE(0x15c2, 0x003c) },
222 /* device specifics unknown */
223 { USB_DEVICE(0x15c2, 0x003d) },
224 /* device specifics unknown */
225 { USB_DEVICE(0x15c2, 0x003e) },
226 /* device specifics unknown */
227 { USB_DEVICE(0x15c2, 0x003f) },
228 /* device specifics unknown */
229 { USB_DEVICE(0x15c2, 0x0040) },
230 /* SoundGraph iMON MINI (IR only) */
231 { USB_DEVICE(0x15c2, 0x0041) },
232 /* Antec Veris Multimedia Station EZ External (IR only) */
233 { USB_DEVICE(0x15c2, 0x0042) },
234 /* Antec Veris Multimedia Station Basic Internal (IR only) */
235 { USB_DEVICE(0x15c2, 0x0043) },
236 /* Antec Veris Multimedia Station Elite (IR & VFD) */
237 { USB_DEVICE(0x15c2, 0x0044) },
238 /* Antec Veris Multimedia Station Premiere (IR & LCD) */
239 { USB_DEVICE(0x15c2, 0x0045) },
240 /* device specifics unknown */
241 { USB_DEVICE(0x15c2, 0x0046) },
242 {}
243};
244
245/* USB Device data */
246static struct usb_driver imon_driver = {
247 .name = MOD_NAME,
248 .probe = imon_probe,
249 .disconnect = imon_disconnect,
250 .suspend = imon_suspend,
251 .resume = imon_resume,
252 .id_table = imon_usb_id_table,
253};
254
255static struct usb_class_driver imon_vfd_class = {
256 .name = DEVICE_NAME,
257 .fops = &vfd_fops,
258 .minor_base = DISPLAY_MINOR_BASE,
259};
260
261static struct usb_class_driver imon_lcd_class = {
262 .name = DEVICE_NAME,
263 .fops = &lcd_fops,
264 .minor_base = DISPLAY_MINOR_BASE,
265};
266
267/* imon receiver front panel/knob key table */
268static const struct {
269 u64 hw_code;
270 u32 keycode;
271} imon_panel_key_table[] = {
272 { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */
273 { 0x000000001f00ffeell, KEY_AUDIO },
274 { 0x000000002000ffeell, KEY_VIDEO },
275 { 0x000000002100ffeell, KEY_CAMERA },
276 { 0x000000002700ffeell, KEY_DVD },
277 { 0x000000002300ffeell, KEY_TV },
278 { 0x000000000500ffeell, KEY_PREVIOUS },
279 { 0x000000000700ffeell, KEY_REWIND },
280 { 0x000000000400ffeell, KEY_STOP },
281 { 0x000000003c00ffeell, KEY_PLAYPAUSE },
282 { 0x000000000800ffeell, KEY_FASTFORWARD },
283 { 0x000000000600ffeell, KEY_NEXT },
284 { 0x000000010000ffeell, KEY_RIGHT },
285 { 0x000001000000ffeell, KEY_LEFT },
286 { 0x000000003d00ffeell, KEY_SELECT },
287 { 0x000100000000ffeell, KEY_VOLUMEUP },
288 { 0x010000000000ffeell, KEY_VOLUMEDOWN },
289 { 0x000000000100ffeell, KEY_MUTE },
290 /* iMON Knob values */
291 { 0x000100ffffffffeell, KEY_VOLUMEUP },
292 { 0x010000ffffffffeell, KEY_VOLUMEDOWN },
293 { 0x000008ffffffffeell, KEY_MUTE },
294};
295
296/* to prevent races between open() and disconnect(), probing, etc */
297static DEFINE_MUTEX(driver_lock);
298
299/* Module bookkeeping bits */
300MODULE_AUTHOR(MOD_AUTHOR);
301MODULE_DESCRIPTION(MOD_DESC);
302MODULE_VERSION(MOD_VERSION);
303MODULE_LICENSE("GPL");
304MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
305
306static bool debug;
307module_param(debug, bool, S_IRUGO | S_IWUSR);
308MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
309
310/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */
311static int display_type;
312module_param(display_type, int, S_IRUGO);
313MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, "
314 "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");
315
316static int pad_stabilize = 1;
317module_param(pad_stabilize, int, S_IRUGO | S_IWUSR);
318MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD "
319 "presses in arrow key mode. 0=disable, 1=enable (default).");
320
321/*
322 * In certain use cases, mouse mode isn't really helpful, and could actually
323 * cause confusion, so allow disabling it when the IR device is open.
324 */
325static bool nomouse;
326module_param(nomouse, bool, S_IRUGO | S_IWUSR);
327MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is "
328 "open. 0=don't disable, 1=disable. (default: don't disable)");
329
330/* threshold at which a pad push registers as an arrow key in kbd mode */
331static int pad_thresh;
332module_param(pad_thresh, int, S_IRUGO | S_IWUSR);
333MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an "
334 "arrow key in kbd mode (default: 28)");
335
336
337static void free_imon_context(struct imon_context *ictx)
338{
339 struct device *dev = ictx->dev;
340
341 usb_free_urb(ictx->tx_urb);
342 usb_free_urb(ictx->rx_urb_intf0);
343 usb_free_urb(ictx->rx_urb_intf1);
344 kfree(ictx);
345
346 dev_dbg(dev, "%s: iMON context freed\n", __func__);
347}
348
349/**
350 * Called when the Display device (e.g. /dev/lcd0)
351 * is opened by the application.
352 */
353static int display_open(struct inode *inode, struct file *file)
354{
355 struct usb_interface *interface;
356 struct imon_context *ictx = NULL;
357 int subminor;
358 int retval = 0;
359
360 /* prevent races with disconnect */
361 mutex_lock(&driver_lock);
362
363 subminor = iminor(inode);
364 interface = usb_find_interface(&imon_driver, subminor);
365 if (!interface) {
366 err("%s: could not find interface for minor %d",
367 __func__, subminor);
368 retval = -ENODEV;
369 goto exit;
370 }
371 ictx = usb_get_intfdata(interface);
372
373 if (!ictx) {
374 err("%s: no context found for minor %d", __func__, subminor);
375 retval = -ENODEV;
376 goto exit;
377 }
378
379 mutex_lock(&ictx->lock);
380
381 if (!ictx->display_supported) {
382 err("%s: display not supported by device", __func__);
383 retval = -ENODEV;
384 } else if (ictx->display_isopen) {
385 err("%s: display port is already open", __func__);
386 retval = -EBUSY;
387 } else {
388 ictx->display_isopen = 1;
389 file->private_data = ictx;
390 dev_dbg(ictx->dev, "display port opened\n");
391 }
392
393 mutex_unlock(&ictx->lock);
394
395exit:
396 mutex_unlock(&driver_lock);
397 return retval;
398}
399
400/**
401 * Called when the display device (e.g. /dev/lcd0)
402 * is closed by the application.
403 */
404static int display_close(struct inode *inode, struct file *file)
405{
406 struct imon_context *ictx = NULL;
407 int retval = 0;
408
409 ictx = (struct imon_context *)file->private_data;
410
411 if (!ictx) {
412 err("%s: no context for device", __func__);
413 return -ENODEV;
414 }
415
416 mutex_lock(&ictx->lock);
417
418 if (!ictx->display_supported) {
419 err("%s: display not supported by device", __func__);
420 retval = -ENODEV;
421 } else if (!ictx->display_isopen) {
422 err("%s: display is not open", __func__);
423 retval = -EIO;
424 } else {
425 ictx->display_isopen = 0;
426 dev_dbg(ictx->dev, "display port closed\n");
427 if (!ictx->dev_present_intf0) {
428 /*
429 * Device disconnected before close and IR port is not
430 * open. If IR port is open, context will be deleted by
431 * ir_close.
432 */
433 mutex_unlock(&ictx->lock);
434 free_imon_context(ictx);
435 return retval;
436 }
437 }
438
439 mutex_unlock(&ictx->lock);
440 return retval;
441}
442
443/**
444 * Sends a packet to the device -- this function must be called
445 * with ictx->lock held.
446 */
447static int send_packet(struct imon_context *ictx)
448{
449 unsigned int pipe;
450 unsigned long timeout;
451 int interval = 0;
452 int retval = 0;
453 struct usb_ctrlrequest *control_req = NULL;
454
455 /* Check if we need to use control or interrupt urb */
456 if (!ictx->tx_control) {
457 pipe = usb_sndintpipe(ictx->usbdev_intf0,
458 ictx->tx_endpoint->bEndpointAddress);
459 interval = ictx->tx_endpoint->bInterval;
460
461 usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe,
462 ictx->usb_tx_buf,
463 sizeof(ictx->usb_tx_buf),
464 usb_tx_callback, ictx, interval);
465
466 ictx->tx_urb->actual_length = 0;
467 } else {
468 /* fill request into kmalloc'ed space: */
469 control_req = kmalloc(sizeof(struct usb_ctrlrequest),
470 GFP_KERNEL);
471 if (control_req == NULL)
472 return -ENOMEM;
473
474 /* setup packet is '21 09 0200 0001 0008' */
475 control_req->bRequestType = 0x21;
476 control_req->bRequest = 0x09;
477 control_req->wValue = cpu_to_le16(0x0200);
478 control_req->wIndex = cpu_to_le16(0x0001);
479 control_req->wLength = cpu_to_le16(0x0008);
480
481 /* control pipe is endpoint 0x00 */
482 pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0);
483
484 /* build the control urb */
485 usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0,
486 pipe, (unsigned char *)control_req,
487 ictx->usb_tx_buf,
488 sizeof(ictx->usb_tx_buf),
489 usb_tx_callback, ictx);
490 ictx->tx_urb->actual_length = 0;
491 }
492
493 init_completion(&ictx->tx.finished);
494 ictx->tx.busy = 1;
495 smp_rmb(); /* ensure later readers know we're busy */
496
497 retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
498 if (retval) {
499 ictx->tx.busy = 0;
500 smp_rmb(); /* ensure later readers know we're not busy */
501 err("%s: error submitting urb(%d)", __func__, retval);
502 } else {
503 /* Wait for transmission to complete (or abort) */
504 mutex_unlock(&ictx->lock);
505 retval = wait_for_completion_interruptible(
506 &ictx->tx.finished);
507 if (retval)
508 err("%s: task interrupted", __func__);
509 mutex_lock(&ictx->lock);
510
511 retval = ictx->tx.status;
512 if (retval)
513 err("%s: packet tx failed (%d)", __func__, retval);
514 }
515
516 kfree(control_req);
517
518 /*
519 * Induce a mandatory 5ms delay before returning, as otherwise,
520 * send_packet can get called so rapidly as to overwhelm the device,
521 * particularly on faster systems and/or those with quirky usb.
522 */
523 timeout = msecs_to_jiffies(5);
524 set_current_state(TASK_UNINTERRUPTIBLE);
525 schedule_timeout(timeout);
526
527 return retval;
528}
529
530/**
531 * Sends an associate packet to the iMON 2.4G.
532 *
533 * This might not be such a good idea, since it has an id collision with
534 * some versions of the "IR & VFD" combo. The only way to determine if it
535 * is an RF version is to look at the product description string. (Which
536 * we currently do not fetch).
537 */
538static int send_associate_24g(struct imon_context *ictx)
539{
540 int retval;
541 const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x20 };
543
544 if (!ictx) {
545 err("%s: no context for device", __func__);
546 return -ENODEV;
547 }
548
549 if (!ictx->dev_present_intf0) {
550 err("%s: no iMON device present", __func__);
551 return -ENODEV;
552 }
553
554 memcpy(ictx->usb_tx_buf, packet, sizeof(packet));
555 retval = send_packet(ictx);
556
557 return retval;
558}
559
560/**
561 * Sends packets to setup and show clock on iMON display
562 *
563 * Arguments: year - last 2 digits of year, month - 1..12,
564 * day - 1..31, dow - day of the week (0-Sun...6-Sat),
565 * hour - 0..23, minute - 0..59, second - 0..59
566 */
567static int send_set_imon_clock(struct imon_context *ictx,
568 unsigned int year, unsigned int month,
569 unsigned int day, unsigned int dow,
570 unsigned int hour, unsigned int minute,
571 unsigned int second)
572{
573 unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8];
574 int retval = 0;
575 int i;
576
577 if (!ictx) {
578 err("%s: no context for device", __func__);
579 return -ENODEV;
580 }
581
582 switch (ictx->display_type) {
583 case IMON_DISPLAY_TYPE_LCD:
584 clock_enable_pkt[0][0] = 0x80;
585 clock_enable_pkt[0][1] = year;
586 clock_enable_pkt[0][2] = month-1;
587 clock_enable_pkt[0][3] = day;
588 clock_enable_pkt[0][4] = hour;
589 clock_enable_pkt[0][5] = minute;
590 clock_enable_pkt[0][6] = second;
591
592 clock_enable_pkt[1][0] = 0x80;
593 clock_enable_pkt[1][1] = 0;
594 clock_enable_pkt[1][2] = 0;
595 clock_enable_pkt[1][3] = 0;
596 clock_enable_pkt[1][4] = 0;
597 clock_enable_pkt[1][5] = 0;
598 clock_enable_pkt[1][6] = 0;
599
600 if (ictx->product == 0xffdc) {
601 clock_enable_pkt[0][7] = 0x50;
602 clock_enable_pkt[1][7] = 0x51;
603 } else {
604 clock_enable_pkt[0][7] = 0x88;
605 clock_enable_pkt[1][7] = 0x8a;
606 }
607
608 break;
609
610 case IMON_DISPLAY_TYPE_VFD:
611 clock_enable_pkt[0][0] = year;
612 clock_enable_pkt[0][1] = month-1;
613 clock_enable_pkt[0][2] = day;
614 clock_enable_pkt[0][3] = dow;
615 clock_enable_pkt[0][4] = hour;
616 clock_enable_pkt[0][5] = minute;
617 clock_enable_pkt[0][6] = second;
618 clock_enable_pkt[0][7] = 0x40;
619
620 clock_enable_pkt[1][0] = 0;
621 clock_enable_pkt[1][1] = 0;
622 clock_enable_pkt[1][2] = 1;
623 clock_enable_pkt[1][3] = 0;
624 clock_enable_pkt[1][4] = 0;
625 clock_enable_pkt[1][5] = 0;
626 clock_enable_pkt[1][6] = 0;
627 clock_enable_pkt[1][7] = 0x42;
628
629 break;
630
631 default:
632 return -ENODEV;
633 }
634
635 for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) {
636 memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8);
637 retval = send_packet(ictx);
638 if (retval) {
639 err("%s: send_packet failed for packet %d",
640 __func__, i);
641 break;
642 }
643 }
644
645 return retval;
646}
647
648/**
649 * These are the sysfs functions to handle the association on the iMON 2.4G LT.
650 */
651static ssize_t show_associate_remote(struct device *d,
652 struct device_attribute *attr,
653 char *buf)
654{
655 struct imon_context *ictx = dev_get_drvdata(d);
656
657 if (!ictx)
658 return -ENODEV;
659
660 mutex_lock(&ictx->lock);
661 if (ictx->rf_isassociating)
662 strcpy(buf, "associating\n");
663 else
664 strcpy(buf, "closed\n");
665
666 dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for "
667 "instructions on how to associate your iMON 2.4G DT/LT "
668 "remote\n");
669 mutex_unlock(&ictx->lock);
670 return strlen(buf);
671}
672
673static ssize_t store_associate_remote(struct device *d,
674 struct device_attribute *attr,
675 const char *buf, size_t count)
676{
677 struct imon_context *ictx;
678
679 ictx = dev_get_drvdata(d);
680
681 if (!ictx)
682 return -ENODEV;
683
684 mutex_lock(&ictx->lock);
685 ictx->rf_isassociating = 1;
686 send_associate_24g(ictx);
687 mutex_unlock(&ictx->lock);
688
689 return count;
690}
691
692/**
693 * sysfs functions to control internal imon clock
694 */
695static ssize_t show_imon_clock(struct device *d,
696 struct device_attribute *attr, char *buf)
697{
698 struct imon_context *ictx = dev_get_drvdata(d);
699 size_t len;
700
701 if (!ictx)
702 return -ENODEV;
703
704 mutex_lock(&ictx->lock);
705
706 if (!ictx->display_supported) {
707 len = snprintf(buf, PAGE_SIZE, "Not supported.");
708 } else {
709 len = snprintf(buf, PAGE_SIZE,
710 "To set the clock on your iMON display:\n"
711 "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n"
712 "%s", ictx->display_isopen ?
713 "\nNOTE: imon device must be closed\n" : "");
714 }
715
716 mutex_unlock(&ictx->lock);
717
718 return len;
719}
720
721static ssize_t store_imon_clock(struct device *d,
722 struct device_attribute *attr,
723 const char *buf, size_t count)
724{
725 struct imon_context *ictx = dev_get_drvdata(d);
726 ssize_t retval;
727 unsigned int year, month, day, dow, hour, minute, second;
728
729 if (!ictx)
730 return -ENODEV;
731
732 mutex_lock(&ictx->lock);
733
734 if (!ictx->display_supported) {
735 retval = -ENODEV;
736 goto exit;
737 } else if (ictx->display_isopen) {
738 retval = -EBUSY;
739 goto exit;
740 }
741
742 if (sscanf(buf, "%u %u %u %u %u %u %u", &year, &month, &day, &dow,
743 &hour, &minute, &second) != 7) {
744 retval = -EINVAL;
745 goto exit;
746 }
747
748 if ((month < 1 || month > 12) ||
749 (day < 1 || day > 31) || (dow > 6) ||
750 (hour > 23) || (minute > 59) || (second > 59)) {
751 retval = -EINVAL;
752 goto exit;
753 }
754
755 retval = send_set_imon_clock(ictx, year, month, day, dow,
756 hour, minute, second);
757 if (retval)
758 goto exit;
759
760 retval = count;
761exit:
762 mutex_unlock(&ictx->lock);
763
764 return retval;
765}
766
767
768static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock,
769 store_imon_clock);
770
771static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote,
772 store_associate_remote);
773
774static struct attribute *imon_display_sysfs_entries[] = {
775 &dev_attr_imon_clock.attr,
776 NULL
777};
778
779static struct attribute_group imon_display_attribute_group = {
780 .attrs = imon_display_sysfs_entries
781};
782
783static struct attribute *imon_rf_sysfs_entries[] = {
784 &dev_attr_associate_remote.attr,
785 NULL
786};
787
788static struct attribute_group imon_rf_attribute_group = {
789 .attrs = imon_rf_sysfs_entries
790};
791
792/**
793 * Writes data to the VFD. The iMON VFD is 2x16 characters
794 * and requires data in 5 consecutive USB interrupt packets,
795 * each packet but the last carrying 7 bytes.
796 *
797 * I don't know if the VFD board supports features such as
798 * scrolling, clearing rows, blanking, etc. so at
799 * the caller must provide a full screen of data. If fewer
800 * than 32 bytes are provided spaces will be appended to
801 * generate a full screen.
802 */
803static ssize_t vfd_write(struct file *file, const char *buf,
804 size_t n_bytes, loff_t *pos)
805{
806 int i;
807 int offset;
808 int seq;
809 int retval = 0;
810 struct imon_context *ictx;
811 const unsigned char vfd_packet6[] = {
812 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
813
814 ictx = (struct imon_context *)file->private_data;
815 if (!ictx) {
816 err("%s: no context for device", __func__);
817 return -ENODEV;
818 }
819
820 mutex_lock(&ictx->lock);
821
822 if (!ictx->dev_present_intf0) {
823 err("%s: no iMON device present", __func__);
824 retval = -ENODEV;
825 goto exit;
826 }
827
828 if (n_bytes <= 0 || n_bytes > 32) {
829 err("%s: invalid payload size", __func__);
830 retval = -EINVAL;
831 goto exit;
832 }
833
834 if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) {
835 retval = -EFAULT;
836 goto exit;
837 }
838
839 /* Pad with spaces */
840 for (i = n_bytes; i < 32; ++i)
841 ictx->tx.data_buf[i] = ' ';
842
843 for (i = 32; i < 35; ++i)
844 ictx->tx.data_buf[i] = 0xFF;
845
846 offset = 0;
847 seq = 0;
848
849 do {
850 memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7);
851 ictx->usb_tx_buf[7] = (unsigned char) seq;
852
853 retval = send_packet(ictx);
854 if (retval) {
855 err("%s: send packet failed for packet #%d",
856 __func__, seq/2);
857 goto exit;
858 } else {
859 seq += 2;
860 offset += 7;
861 }
862
863 } while (offset < 35);
864
865 /* Send packet #6 */
866 memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
867 ictx->usb_tx_buf[7] = (unsigned char) seq;
868 retval = send_packet(ictx);
869 if (retval)
870 err("%s: send packet failed for packet #%d",
871 __func__, seq / 2);
872
873exit:
874 mutex_unlock(&ictx->lock);
875
876 return (!retval) ? n_bytes : retval;
877}
878
879/**
880 * Writes data to the LCD. The iMON OEM LCD screen expects 8-byte
881 * packets. We accept data as 16 hexadecimal digits, followed by a
882 * newline (to make it easy to drive the device from a command-line
883 * -- even though the actual binary data is a bit complicated).
884 *
885 * The device itself is not a "traditional" text-mode display. It's
886 * actually a 16x96 pixel bitmap display. That means if you want to
887 * display text, you've got to have your own "font" and translate the
888 * text into bitmaps for display. This is really flexible (you can
889 * display whatever diacritics you need, and so on), but it's also
890 * a lot more complicated than most LCDs...
891 */
892static ssize_t lcd_write(struct file *file, const char *buf,
893 size_t n_bytes, loff_t *pos)
894{
895 int retval = 0;
896 struct imon_context *ictx;
897
898 ictx = (struct imon_context *)file->private_data;
899 if (!ictx) {
900 err("%s: no context for device", __func__);
901 return -ENODEV;
902 }
903
904 mutex_lock(&ictx->lock);
905
906 if (!ictx->display_supported) {
907 err("%s: no iMON display present", __func__);
908 retval = -ENODEV;
909 goto exit;
910 }
911
912 if (n_bytes != 8) {
913 err("%s: invalid payload size: %d (expecting 8)",
914 __func__, (int) n_bytes);
915 retval = -EINVAL;
916 goto exit;
917 }
918
919 if (copy_from_user(ictx->usb_tx_buf, buf, 8)) {
920 retval = -EFAULT;
921 goto exit;
922 }
923
924 retval = send_packet(ictx);
925 if (retval) {
926 err("%s: send packet failed!", __func__);
927 goto exit;
928 } else {
929 dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n",
930 __func__, (int) n_bytes);
931 }
932exit:
933 mutex_unlock(&ictx->lock);
934 return (!retval) ? n_bytes : retval;
935}
936
937/**
938 * Callback function for USB core API: transmit data
939 */
940static void usb_tx_callback(struct urb *urb)
941{
942 struct imon_context *ictx;
943
944 if (!urb)
945 return;
946 ictx = (struct imon_context *)urb->context;
947 if (!ictx)
948 return;
949
950 ictx->tx.status = urb->status;
951
952 /* notify waiters that write has finished */
953 ictx->tx.busy = 0;
954 smp_rmb(); /* ensure later readers know we're not busy */
955 complete(&ictx->tx.finished);
956}
957
958/**
959 * mce/rc6 keypresses have no distinct release code, use timer
960 */
961static void imon_mce_timeout(unsigned long data)
962{
963 struct imon_context *ictx = (struct imon_context *)data;
964
965 input_report_key(ictx->idev, ictx->last_keycode, 0);
966 input_sync(ictx->idev);
967}
968
969/**
970 * report touchscreen input
971 */
972static void imon_touch_display_timeout(unsigned long data)
973{
974 struct imon_context *ictx = (struct imon_context *)data;
975
976 if (ictx->display_type != IMON_DISPLAY_TYPE_VGA)
977 return;
978
979 input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
980 input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
981 input_report_key(ictx->touch, BTN_TOUCH, 0x00);
982 input_sync(ictx->touch);
983}
984
985/**
986 * iMON IR receivers support two different signal sets -- those used by
987 * the iMON remotes, and those used by the Windows MCE remotes (which is
988 * really just RC-6), but only one or the other at a time, as the signals
989 * are decoded onboard the receiver.
990 */
991int imon_ir_change_protocol(void *priv, u64 ir_type)
992{
993 int retval;
994 struct imon_context *ictx = priv;
995 struct device *dev = ictx->dev;
996 bool pad_mouse;
997 unsigned char ir_proto_packet[] = {
998 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
999
1000 if (ir_type && !(ir_type & ictx->props->allowed_protos))
1001 dev_warn(dev, "Looks like you're trying to use an IR protocol "
1002 "this device does not support\n");
1003
1004 switch (ir_type) {
1005 case IR_TYPE_RC6:
1006 dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
1007 ir_proto_packet[0] = 0x01;
1008 pad_mouse = false;
1009 init_timer(&ictx->itimer);
1010 ictx->itimer.data = (unsigned long)ictx;
1011 ictx->itimer.function = imon_mce_timeout;
1012 break;
1013 case IR_TYPE_UNKNOWN:
1014 case IR_TYPE_OTHER:
1015 dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
1016 if (pad_stabilize)
1017 pad_mouse = true;
1018 else {
1019 dev_dbg(dev, "PAD stabilize functionality disabled\n");
1020 pad_mouse = false;
1021 }
1022 /* ir_proto_packet[0] = 0x00; // already the default */
1023 ir_type = IR_TYPE_OTHER;
1024 break;
1025 default:
1026 dev_warn(dev, "Unsupported IR protocol specified, overriding "
1027 "to iMON IR protocol\n");
1028 if (pad_stabilize)
1029 pad_mouse = true;
1030 else {
1031 dev_dbg(dev, "PAD stabilize functionality disabled\n");
1032 pad_mouse = false;
1033 }
1034 /* ir_proto_packet[0] = 0x00; // already the default */
1035 ir_type = IR_TYPE_OTHER;
1036 break;
1037 }
1038
1039 memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
1040
1041 retval = send_packet(ictx);
1042 if (retval)
1043 goto out;
1044
1045 ictx->ir_type = ir_type;
1046 ictx->pad_mouse = pad_mouse;
1047
1048out:
1049 return retval;
1050}
1051
1052static inline int tv2int(const struct timeval *a, const struct timeval *b)
1053{
1054 int usecs = 0;
1055 int sec = 0;
1056
1057 if (b->tv_usec > a->tv_usec) {
1058 usecs = 1000000;
1059 sec--;
1060 }
1061
1062 usecs += a->tv_usec - b->tv_usec;
1063
1064 sec += a->tv_sec - b->tv_sec;
1065 sec *= 1000;
1066 usecs /= 1000;
1067 sec += usecs;
1068
1069 if (sec < 0)
1070 sec = 1000;
1071
1072 return sec;
1073}
1074
1075/**
1076 * The directional pad behaves a bit differently, depending on whether this is
1077 * one of the older ffdc devices or a newer device. Newer devices appear to
1078 * have a higher resolution matrix for more precise mouse movement, but it
1079 * makes things overly sensitive in keyboard mode, so we do some interesting
1080 * contortions to make it less touchy. Older devices run through the same
1081 * routine with shorter timeout and a smaller threshold.
1082 */
1083static int stabilize(int a, int b, u16 timeout, u16 threshold)
1084{
1085 struct timeval ct;
1086 static struct timeval prev_time = {0, 0};
1087 static struct timeval hit_time = {0, 0};
1088 static int x, y, prev_result, hits;
1089 int result = 0;
1090 int msec, msec_hit;
1091
1092 do_gettimeofday(&ct);
1093 msec = tv2int(&ct, &prev_time);
1094 msec_hit = tv2int(&ct, &hit_time);
1095
1096 if (msec > 100) {
1097 x = 0;
1098 y = 0;
1099 hits = 0;
1100 }
1101
1102 x += a;
1103 y += b;
1104
1105 prev_time = ct;
1106
1107 if (abs(x) > threshold || abs(y) > threshold) {
1108 if (abs(y) > abs(x))
1109 result = (y > 0) ? 0x7F : 0x80;
1110 else
1111 result = (x > 0) ? 0x7F00 : 0x8000;
1112
1113 x = 0;
1114 y = 0;
1115
1116 if (result == prev_result) {
1117 hits++;
1118
1119 if (hits > 3) {
1120 switch (result) {
1121 case 0x7F:
1122 y = 17 * threshold / 30;
1123 break;
1124 case 0x80:
1125 y -= 17 * threshold / 30;
1126 break;
1127 case 0x7F00:
1128 x = 17 * threshold / 30;
1129 break;
1130 case 0x8000:
1131 x -= 17 * threshold / 30;
1132 break;
1133 }
1134 }
1135
1136 if (hits == 2 && msec_hit < timeout) {
1137 result = 0;
1138 hits = 1;
1139 }
1140 } else {
1141 prev_result = result;
1142 hits = 1;
1143 hit_time = ct;
1144 }
1145 }
1146
1147 return result;
1148}
1149
1150static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code)
1151{
1152 u32 scancode = be32_to_cpu(hw_code);
1153 u32 keycode;
1154 u32 release;
1155 bool is_release_code = false;
1156
1157 /* Look for the initial press of a button */
1158 keycode = ir_g_keycode_from_table(ictx->idev, scancode);
1159
1160 /* Look for the release of a button */
1161 if (keycode == KEY_RESERVED) {
1162 release = scancode & ~0x4000;
1163 keycode = ir_g_keycode_from_table(ictx->idev, release);
1164 if (keycode != KEY_RESERVED)
1165 is_release_code = true;
1166 }
1167
1168 ictx->release_code = is_release_code;
1169
1170 return keycode;
1171}
1172
1173static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code)
1174{
1175 u32 scancode = be32_to_cpu(hw_code);
1176 u32 keycode;
1177
1178#define MCE_KEY_MASK 0x7000
1179#define MCE_TOGGLE_BIT 0x8000
1180
1181 /*
1182 * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx
1183 * (the toggle bit flipping between alternating key presses), while
1184 * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep
1185 * the table trim, we always or in the bits to look up 0x8000ff4xx,
1186 * but we can't or them into all codes, as some keys are decoded in
1187 * a different way w/o the same use of the toggle bit...
1188 */
1189 if ((scancode >> 24) & 0x80)
1190 scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
1191
1192 keycode = ir_g_keycode_from_table(ictx->idev, scancode);
1193
1194 return keycode;
1195}
1196
1197static u32 imon_panel_key_lookup(u64 hw_code)
1198{
1199 int i;
1200 u64 code = be64_to_cpu(hw_code);
1201 u32 keycode = KEY_RESERVED;
1202
1203 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
1204 if (imon_panel_key_table[i].hw_code == (code | 0xffee)) {
1205 keycode = imon_panel_key_table[i].keycode;
1206 break;
1207 }
1208 }
1209
1210 return keycode;
1211}
1212
1213static bool imon_mouse_event(struct imon_context *ictx,
1214 unsigned char *buf, int len)
1215{
1216 char rel_x = 0x00, rel_y = 0x00;
1217 u8 right_shift = 1;
1218 bool mouse_input = 1;
1219 int dir = 0;
1220
1221 /* newer iMON device PAD or mouse button */
1222 if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) {
1223 rel_x = buf[2];
1224 rel_y = buf[3];
1225 right_shift = 1;
1226 /* 0xffdc iMON PAD or mouse button input */
1227 } else if (ictx->product == 0xffdc && (buf[0] & 0x40) &&
1228 !((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) {
1229 rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1230 (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1231 if (buf[0] & 0x02)
1232 rel_x |= ~0x0f;
1233 rel_x = rel_x + rel_x / 2;
1234 rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1235 (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1236 if (buf[0] & 0x01)
1237 rel_y |= ~0x0f;
1238 rel_y = rel_y + rel_y / 2;
1239 right_shift = 2;
1240 /* some ffdc devices decode mouse buttons differently... */
1241 } else if (ictx->product == 0xffdc && (buf[0] == 0x68)) {
1242 right_shift = 2;
1243 /* ch+/- buttons, which we use for an emulated scroll wheel */
1244 } else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) {
1245 dir = 1;
1246 } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
1247 dir = -1;
1248 } else
1249 mouse_input = 0;
1250
1251 if (mouse_input) {
1252 dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");
1253
1254 if (dir) {
1255 input_report_rel(ictx->idev, REL_WHEEL, dir);
1256 } else if (rel_x || rel_y) {
1257 input_report_rel(ictx->idev, REL_X, rel_x);
1258 input_report_rel(ictx->idev, REL_Y, rel_y);
1259 } else {
1260 input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1);
1261 input_report_key(ictx->idev, BTN_RIGHT,
1262 buf[1] >> right_shift & 0x1);
1263 }
1264 input_sync(ictx->idev);
1265 ictx->last_keycode = ictx->kc;
1266 }
1267
1268 return mouse_input;
1269}
1270
1271static void imon_touch_event(struct imon_context *ictx, unsigned char *buf)
1272{
1273 mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT);
1274 ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4);
1275 ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf));
1276 input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
1277 input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
1278 input_report_key(ictx->touch, BTN_TOUCH, 0x01);
1279 input_sync(ictx->touch);
1280}
1281
1282static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1283{
1284 int dir = 0;
1285 char rel_x = 0x00, rel_y = 0x00;
1286 u16 timeout, threshold;
1287 u64 temp_key;
1288 u32 remote_key;
1289
1290 /*
1291 * The imon directional pad functions more like a touchpad. Bytes 3 & 4
1292 * contain a position coordinate (x,y), with each component ranging
1293 * from -14 to 14. We want to down-sample this to only 4 discrete values
1294 * for up/down/left/right arrow keys. Also, when you get too close to
1295 * diagonals, it has a tendancy to jump back and forth, so lets try to
1296 * ignore when they get too close.
1297 */
1298 if (ictx->product != 0xffdc) {
1299 /* first, pad to 8 bytes so it conforms with everything else */
1300 buf[5] = buf[6] = buf[7] = 0;
1301 timeout = 500; /* in msecs */
1302 /* (2*threshold) x (2*threshold) square */
1303 threshold = pad_thresh ? pad_thresh : 28;
1304 rel_x = buf[2];
1305 rel_y = buf[3];
1306
1307 if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
1308 if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
1309 dir = stabilize((int)rel_x, (int)rel_y,
1310 timeout, threshold);
1311 if (!dir) {
1312 ictx->kc = KEY_UNKNOWN;
1313 return;
1314 }
1315 buf[2] = dir & 0xFF;
1316 buf[3] = (dir >> 8) & 0xFF;
1317 memcpy(&temp_key, buf, sizeof(temp_key));
1318 remote_key = (u32) (le64_to_cpu(temp_key)
1319 & 0xffffffff);
1320 ictx->kc = imon_remote_key_lookup(ictx,
1321 remote_key);
1322 }
1323 } else {
1324 if (abs(rel_y) > abs(rel_x)) {
1325 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1326 buf[3] = 0;
1327 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP;
1328 } else {
1329 buf[2] = 0;
1330 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1331 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT;
1332 }
1333 }
1334
1335 /*
1336 * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad
1337 * device (15c2:ffdc). The remote generates various codes from
1338 * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
1339 * 0x688301b7 and the right one 0x688481b7. All other keys generate
1340 * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
1341 * reversed endianess. Extract direction from buffer, rotate endianess,
1342 * adjust sign and feed the values into stabilize(). The resulting codes
1343 * will be 0x01008000, 0x01007F00, which match the newer devices.
1344 */
1345 } else {
1346 timeout = 10; /* in msecs */
1347 /* (2*threshold) x (2*threshold) square */
1348 threshold = pad_thresh ? pad_thresh : 15;
1349
1350 /* buf[1] is x */
1351 rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1352 (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1353 if (buf[0] & 0x02)
1354 rel_x |= ~0x10+1;
1355 /* buf[2] is y */
1356 rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1357 (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1358 if (buf[0] & 0x01)
1359 rel_y |= ~0x10+1;
1360
1361 buf[0] = 0x01;
1362 buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
1363
1364 if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
1365 dir = stabilize((int)rel_x, (int)rel_y,
1366 timeout, threshold);
1367 if (!dir) {
1368 ictx->kc = KEY_UNKNOWN;
1369 return;
1370 }
1371 buf[2] = dir & 0xFF;
1372 buf[3] = (dir >> 8) & 0xFF;
1373 memcpy(&temp_key, buf, sizeof(temp_key));
1374 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1375 ictx->kc = imon_remote_key_lookup(ictx, remote_key);
1376 } else {
1377 if (abs(rel_y) > abs(rel_x)) {
1378 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1379 buf[3] = 0;
1380 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP;
1381 } else {
1382 buf[2] = 0;
1383 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1384 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT;
1385 }
1386 }
1387 }
1388}
1389
1390static int imon_parse_press_type(struct imon_context *ictx,
1391 unsigned char *buf, u8 ktype)
1392{
1393 int press_type = 0;
1394 int rep_delay = ictx->idev->rep[REP_DELAY];
1395 int rep_period = ictx->idev->rep[REP_PERIOD];
1396
1397 /* key release of 0x02XXXXXX key */
1398 if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
1399 ictx->kc = ictx->last_keycode;
1400
1401 /* mouse button release on (some) 0xffdc devices */
1402 else if (ictx->kc == KEY_RESERVED && buf[0] == 0x68 && buf[1] == 0x82 &&
1403 buf[2] == 0x81 && buf[3] == 0xb7)
1404 ictx->kc = ictx->last_keycode;
1405
1406 /* mouse button release on (some other) 0xffdc devices */
1407 else if (ictx->kc == KEY_RESERVED && buf[0] == 0x01 && buf[1] == 0x00 &&
1408 buf[2] == 0x81 && buf[3] == 0xb7)
1409 ictx->kc = ictx->last_keycode;
1410
1411 /* mce-specific button handling */
1412 else if (ktype == IMON_KEY_MCE) {
1413 /* initial press */
1414 if (ictx->kc != ictx->last_keycode
1415 || buf[2] != ictx->mce_toggle_bit) {
1416 ictx->last_keycode = ictx->kc;
1417 ictx->mce_toggle_bit = buf[2];
1418 press_type = 1;
1419 mod_timer(&ictx->itimer,
1420 jiffies + msecs_to_jiffies(rep_delay));
1421 /* repeat */
1422 } else {
1423 press_type = 2;
1424 mod_timer(&ictx->itimer,
1425 jiffies + msecs_to_jiffies(rep_period));
1426 }
1427
1428 /* incoherent or irrelevant data */
1429 } else if (ictx->kc == KEY_RESERVED)
1430 press_type = -EINVAL;
1431
1432 /* key release of 0xXXXXXXb7 key */
1433 else if (ictx->release_code)
1434 press_type = 0;
1435
1436 /* this is a button press */
1437 else
1438 press_type = 1;
1439
1440 return press_type;
1441}
1442
1443/**
1444 * Process the incoming packet
1445 */
1446static void imon_incoming_packet(struct imon_context *ictx,
1447 struct urb *urb, int intf)
1448{
1449 int len = urb->actual_length;
1450 unsigned char *buf = urb->transfer_buffer;
1451 struct device *dev = ictx->dev;
1452 u32 kc;
1453 bool norelease = 0;
1454 int i;
1455 u64 temp_key;
1456 u64 panel_key = 0;
1457 u32 remote_key = 0;
1458 struct input_dev *idev = NULL;
1459 int press_type = 0;
1460 int msec;
1461 struct timeval t;
1462 static struct timeval prev_time = { 0, 0 };
1463 u8 ktype = IMON_KEY_IMON;
1464
1465 idev = ictx->idev;
1466
1467 /* filter out junk data on the older 0xffdc imon devices */
1468 if ((buf[0] == 0xff) && (buf[7] == 0xff))
1469 return;
1470
1471 /* Figure out what key was pressed */
1472 memcpy(&temp_key, buf, sizeof(temp_key));
1473 if (len == 8 && buf[7] == 0xee) {
1474 ktype = IMON_KEY_PANEL;
1475 panel_key = le64_to_cpu(temp_key);
1476 kc = imon_panel_key_lookup(panel_key);
1477 } else {
1478 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1479 if (ictx->ir_type == IR_TYPE_RC6) {
1480 if (buf[0] == 0x80)
1481 ktype = IMON_KEY_MCE;
1482 kc = imon_mce_key_lookup(ictx, remote_key);
1483 } else
1484 kc = imon_remote_key_lookup(ictx, remote_key);
1485 }
1486
1487 /* keyboard/mouse mode toggle button */
1488 if (kc == KEY_KEYBOARD && !ictx->release_code) {
1489 ictx->last_keycode = kc;
1490 if (!nomouse) {
1491 ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
1492 dev_dbg(dev, "toggling to %s mode\n",
1493 ictx->pad_mouse ? "mouse" : "keyboard");
1494 return;
1495 } else {
1496 ictx->pad_mouse = 0;
1497 dev_dbg(dev, "mouse mode disabled, passing key value\n");
1498 }
1499 }
1500
1501 ictx->kc = kc;
1502
1503 /* send touchscreen events through input subsystem if touchpad data */
1504 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
1505 buf[7] == 0x86) {
1506 imon_touch_event(ictx, buf);
1507
1508 /* look for mouse events with pad in mouse mode */
1509 } else if (ictx->pad_mouse) {
1510 if (imon_mouse_event(ictx, buf, len))
1511 return;
1512 }
1513
1514 /* Now for some special handling to convert pad input to arrow keys */
1515 if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) ||
1516 ((len == 8) && (buf[0] & 0x40) &&
1517 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
1518 len = 8;
1519 imon_pad_to_keys(ictx, buf);
1520 norelease = 1;
1521 }
1522
1523 if (debug) {
1524 printk(KERN_INFO "intf%d decoded packet: ", intf);
1525 for (i = 0; i < len; ++i)
1526 printk("%02x ", buf[i]);
1527 printk("\n");
1528 }
1529
1530 press_type = imon_parse_press_type(ictx, buf, ktype);
1531 if (press_type < 0)
1532 goto not_input_data;
1533
1534 if (ictx->kc == KEY_UNKNOWN)
1535 goto unknown_key;
1536
1537 /* KEY_MUTE repeats from MCE and knob need to be suppressed */
1538 if ((ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode)
1539 && (buf[7] == 0xee || ktype == IMON_KEY_MCE)) {
1540 do_gettimeofday(&t);
1541 msec = tv2int(&t, &prev_time);
1542 prev_time = t;
1543 if (msec < idev->rep[REP_DELAY])
1544 return;
1545 }
1546
1547 input_report_key(idev, ictx->kc, press_type);
1548 input_sync(idev);
1549
1550 /* panel keys and some remote keys don't generate a release */
1551 if (panel_key || norelease) {
1552 input_report_key(idev, ictx->kc, 0);
1553 input_sync(idev);
1554 }
1555
1556 ictx->last_keycode = ictx->kc;
1557
1558 return;
1559
1560unknown_key:
1561 dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__,
1562 (panel_key ? be64_to_cpu(panel_key) :
1563 be32_to_cpu(remote_key)));
1564 return;
1565
1566not_input_data:
1567 if (len != 8) {
1568 dev_warn(dev, "imon %s: invalid incoming packet "
1569 "size (len = %d, intf%d)\n", __func__, len, intf);
1570 return;
1571 }
1572
1573 /* iMON 2.4G associate frame */
1574 if (buf[0] == 0x00 &&
1575 buf[2] == 0xFF && /* REFID */
1576 buf[3] == 0xFF &&
1577 buf[4] == 0xFF &&
1578 buf[5] == 0xFF && /* iMON 2.4G */
1579 ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */
1580 (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */
1581 dev_warn(dev, "%s: remote associated refid=%02X\n",
1582 __func__, buf[1]);
1583 ictx->rf_isassociating = 0;
1584 }
1585}
1586
1587/**
1588 * Callback function for USB core API: receive data
1589 */
1590static void usb_rx_callback_intf0(struct urb *urb)
1591{
1592 struct imon_context *ictx;
1593 int intfnum = 0;
1594
1595 if (!urb)
1596 return;
1597
1598 ictx = (struct imon_context *)urb->context;
1599 if (!ictx)
1600 return;
1601
1602 switch (urb->status) {
1603 case -ENOENT: /* usbcore unlink successful! */
1604 return;
1605
1606 case -ESHUTDOWN: /* transport endpoint was shut down */
1607 break;
1608
1609 case 0:
1610 imon_incoming_packet(ictx, urb, intfnum);
1611 break;
1612
1613 default:
1614 dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1615 __func__, urb->status);
1616 break;
1617 }
1618
1619 usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
1620}
1621
1622static void usb_rx_callback_intf1(struct urb *urb)
1623{
1624 struct imon_context *ictx;
1625 int intfnum = 1;
1626
1627 if (!urb)
1628 return;
1629
1630 ictx = (struct imon_context *)urb->context;
1631 if (!ictx)
1632 return;
1633
1634 switch (urb->status) {
1635 case -ENOENT: /* usbcore unlink successful! */
1636 return;
1637
1638 case -ESHUTDOWN: /* transport endpoint was shut down */
1639 break;
1640
1641 case 0:
1642 imon_incoming_packet(ictx, urb, intfnum);
1643 break;
1644
1645 default:
1646 dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1647 __func__, urb->status);
1648 break;
1649 }
1650
1651 usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
1652}
1653
1654static struct input_dev *imon_init_idev(struct imon_context *ictx)
1655{
1656 struct input_dev *idev;
1657 struct ir_dev_props *props;
1658 struct ir_input_dev *ir;
1659 int ret, i;
1660
1661 idev = input_allocate_device();
1662 if (!idev) {
1663 dev_err(ictx->dev, "remote input dev allocation failed\n");
1664 goto idev_alloc_failed;
1665 }
1666
1667 props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
1668 if (!props) {
1669 dev_err(ictx->dev, "remote ir dev props allocation failed\n");
1670 goto props_alloc_failed;
1671 }
1672
1673 ir = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
1674 if (!ir) {
1675 dev_err(ictx->dev, "remote ir input dev allocation failed\n");
1676 goto ir_dev_alloc_failed;
1677 }
1678
1679 snprintf(ictx->name_idev, sizeof(ictx->name_idev),
1680 "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product);
1681 idev->name = ictx->name_idev;
1682
1683 usb_make_path(ictx->usbdev_intf0, ictx->phys_idev,
1684 sizeof(ictx->phys_idev));
1685 strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev));
1686 idev->phys = ictx->phys_idev;
1687
1688 idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
1689
1690 idev->keybit[BIT_WORD(BTN_MOUSE)] =
1691 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
1692 idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
1693 BIT_MASK(REL_WHEEL);
1694
1695 /* panel and/or knob code support */
1696 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
1697 u32 kc = imon_panel_key_table[i].keycode;
1698 __set_bit(kc, idev->keybit);
1699 }
1700
1701 props->priv = ictx;
1702 props->driver_type = RC_DRIVER_SCANCODE;
1703 /* IR_TYPE_OTHER maps to iMON PAD remote, IR_TYPE_RC6 to MCE remote */
1704 props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6;
1705 props->change_protocol = imon_ir_change_protocol;
1706 ictx->props = props;
1707
1708 ictx->ir = ir;
1709 memcpy(&ir->dev, ictx->dev, sizeof(struct device));
1710
1711 usb_to_input_id(ictx->usbdev_intf0, &idev->id);
1712 idev->dev.parent = ictx->dev;
1713
1714 input_set_drvdata(idev, ir);
1715
1716 ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME);
1717 if (ret < 0) {
1718 dev_err(ictx->dev, "remote input dev register failed\n");
1719 goto idev_register_failed;
1720 }
1721
1722 return idev;
1723
1724idev_register_failed:
1725 kfree(ir);
1726ir_dev_alloc_failed:
1727 kfree(props);
1728props_alloc_failed:
1729 input_free_device(idev);
1730idev_alloc_failed:
1731
1732 return NULL;
1733}
1734
1735static struct input_dev *imon_init_touch(struct imon_context *ictx)
1736{
1737 struct input_dev *touch;
1738 int ret;
1739
1740 touch = input_allocate_device();
1741 if (!touch) {
1742 dev_err(ictx->dev, "touchscreen input dev allocation failed\n");
1743 goto touch_alloc_failed;
1744 }
1745
1746 snprintf(ictx->name_touch, sizeof(ictx->name_touch),
1747 "iMON USB Touchscreen (%04x:%04x)",
1748 ictx->vendor, ictx->product);
1749 touch->name = ictx->name_touch;
1750
1751 usb_make_path(ictx->usbdev_intf1, ictx->phys_touch,
1752 sizeof(ictx->phys_touch));
1753 strlcat(ictx->phys_touch, "/input1", sizeof(ictx->phys_touch));
1754 touch->phys = ictx->phys_touch;
1755
1756 touch->evbit[0] =
1757 BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1758 touch->keybit[BIT_WORD(BTN_TOUCH)] =
1759 BIT_MASK(BTN_TOUCH);
1760 input_set_abs_params(touch, ABS_X,
1761 0x00, 0xfff, 0, 0);
1762 input_set_abs_params(touch, ABS_Y,
1763 0x00, 0xfff, 0, 0);
1764
1765 input_set_drvdata(touch, ictx);
1766
1767 usb_to_input_id(ictx->usbdev_intf1, &touch->id);
1768 touch->dev.parent = ictx->dev;
1769 ret = input_register_device(touch);
1770 if (ret < 0) {
1771 dev_info(ictx->dev, "touchscreen input dev register failed\n");
1772 goto touch_register_failed;
1773 }
1774
1775 return touch;
1776
1777touch_register_failed:
1778 input_free_device(ictx->touch);
1779
1780touch_alloc_failed:
1781 return NULL;
1782}
1783
1784static bool imon_find_endpoints(struct imon_context *ictx,
1785 struct usb_host_interface *iface_desc)
1786{
1787 struct usb_endpoint_descriptor *ep;
1788 struct usb_endpoint_descriptor *rx_endpoint = NULL;
1789 struct usb_endpoint_descriptor *tx_endpoint = NULL;
1790 int ifnum = iface_desc->desc.bInterfaceNumber;
1791 int num_endpts = iface_desc->desc.bNumEndpoints;
1792 int i, ep_dir, ep_type;
1793 bool ir_ep_found = 0;
1794 bool display_ep_found = 0;
1795 bool tx_control = 0;
1796
1797 /*
1798 * Scan the endpoint list and set:
1799 * first input endpoint = IR endpoint
1800 * first output endpoint = display endpoint
1801 */
1802 for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
1803 ep = &iface_desc->endpoint[i].desc;
1804 ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
1805 ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
1806
1807 if (!ir_ep_found && ep_dir == USB_DIR_IN &&
1808 ep_type == USB_ENDPOINT_XFER_INT) {
1809
1810 rx_endpoint = ep;
1811 ir_ep_found = 1;
1812 dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__);
1813
1814 } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
1815 ep_type == USB_ENDPOINT_XFER_INT) {
1816 tx_endpoint = ep;
1817 display_ep_found = 1;
1818 dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__);
1819 }
1820 }
1821
1822 if (ifnum == 0) {
1823 ictx->rx_endpoint_intf0 = rx_endpoint;
1824 /*
1825 * tx is used to send characters to lcd/vfd, associate RF
1826 * remotes, set IR protocol, and maybe more...
1827 */
1828 ictx->tx_endpoint = tx_endpoint;
1829 } else {
1830 ictx->rx_endpoint_intf1 = rx_endpoint;
1831 }
1832
1833 /*
1834 * If we didn't find a display endpoint, this is probably one of the
1835 * newer iMON devices that use control urb instead of interrupt
1836 */
1837 if (!display_ep_found) {
1838 tx_control = 1;
1839 display_ep_found = 1;
1840 dev_dbg(ictx->dev, "%s: device uses control endpoint, not "
1841 "interface OUT endpoint\n", __func__);
1842 }
1843
1844 /*
1845 * Some iMON receivers have no display. Unfortunately, it seems
1846 * that SoundGraph recycles device IDs between devices both with
1847 * and without... :\
1848 */
1849 if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) {
1850 display_ep_found = 0;
1851 dev_dbg(ictx->dev, "%s: device has no display\n", __func__);
1852 }
1853
1854 /*
1855 * iMON Touch devices have a VGA touchscreen, but no "display", as
1856 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
1857 */
1858 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1859 display_ep_found = 0;
1860 dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__);
1861 }
1862
1863 /* Input endpoint is mandatory */
1864 if (!ir_ep_found)
1865 err("%s: no valid input (IR) endpoint found.", __func__);
1866
1867 ictx->tx_control = tx_control;
1868
1869 if (display_ep_found)
1870 ictx->display_supported = true;
1871
1872 return ir_ep_found;
1873
1874}
1875
1876static struct imon_context *imon_init_intf0(struct usb_interface *intf)
1877{
1878 struct imon_context *ictx;
1879 struct urb *rx_urb;
1880 struct urb *tx_urb;
1881 struct device *dev = &intf->dev;
1882 struct usb_host_interface *iface_desc;
1883 int ret = -ENOMEM;
1884
1885 ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
1886 if (!ictx) {
1887 dev_err(dev, "%s: kzalloc failed for context", __func__);
1888 goto exit;
1889 }
1890 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1891 if (!rx_urb) {
1892 dev_err(dev, "%s: usb_alloc_urb failed for IR urb", __func__);
1893 goto rx_urb_alloc_failed;
1894 }
1895 tx_urb = usb_alloc_urb(0, GFP_KERNEL);
1896 if (!tx_urb) {
1897 dev_err(dev, "%s: usb_alloc_urb failed for display urb",
1898 __func__);
1899 goto tx_urb_alloc_failed;
1900 }
1901
1902 mutex_init(&ictx->lock);
1903
1904 mutex_lock(&ictx->lock);
1905
1906 ictx->dev = dev;
1907 ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf));
1908 ictx->dev_present_intf0 = 1;
1909 ictx->rx_urb_intf0 = rx_urb;
1910 ictx->tx_urb = tx_urb;
1911
1912 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
1913 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);
1914
1915 ret = -ENODEV;
1916 iface_desc = intf->cur_altsetting;
1917 if (!imon_find_endpoints(ictx, iface_desc)) {
1918 goto find_endpoint_failed;
1919 }
1920
1921 ictx->idev = imon_init_idev(ictx);
1922 if (!ictx->idev) {
1923 dev_err(dev, "%s: input device setup failed\n", __func__);
1924 goto idev_setup_failed;
1925 }
1926
1927 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
1928 usb_rcvintpipe(ictx->usbdev_intf0,
1929 ictx->rx_endpoint_intf0->bEndpointAddress),
1930 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
1931 usb_rx_callback_intf0, ictx,
1932 ictx->rx_endpoint_intf0->bInterval);
1933
1934 ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL);
1935 if (ret) {
1936 err("%s: usb_submit_urb failed for intf0 (%d)",
1937 __func__, ret);
1938 goto urb_submit_failed;
1939 }
1940
1941 return ictx;
1942
1943urb_submit_failed:
1944 input_unregister_device(ictx->idev);
1945 input_free_device(ictx->idev);
1946idev_setup_failed:
1947find_endpoint_failed:
1948 mutex_unlock(&ictx->lock);
1949 usb_free_urb(tx_urb);
1950tx_urb_alloc_failed:
1951 usb_free_urb(rx_urb);
1952rx_urb_alloc_failed:
1953 kfree(ictx);
1954exit:
1955 dev_err(dev, "unable to initialize intf0, err %d\n", ret);
1956
1957 return NULL;
1958}
1959
1960static struct imon_context *imon_init_intf1(struct usb_interface *intf,
1961 struct imon_context *ictx)
1962{
1963 struct urb *rx_urb;
1964 struct usb_host_interface *iface_desc;
1965 int ret = -ENOMEM;
1966
1967 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1968 if (!rx_urb) {
1969 err("%s: usb_alloc_urb failed for IR urb", __func__);
1970 goto rx_urb_alloc_failed;
1971 }
1972
1973 mutex_lock(&ictx->lock);
1974
1975 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1976 init_timer(&ictx->ttimer);
1977 ictx->ttimer.data = (unsigned long)ictx;
1978 ictx->ttimer.function = imon_touch_display_timeout;
1979 }
1980
1981 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
1982 ictx->dev_present_intf1 = 1;
1983 ictx->rx_urb_intf1 = rx_urb;
1984
1985 ret = -ENODEV;
1986 iface_desc = intf->cur_altsetting;
1987 if (!imon_find_endpoints(ictx, iface_desc))
1988 goto find_endpoint_failed;
1989
1990 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1991 ictx->touch = imon_init_touch(ictx);
1992 if (!ictx->touch)
1993 goto touch_setup_failed;
1994 } else
1995 ictx->touch = NULL;
1996
1997 usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
1998 usb_rcvintpipe(ictx->usbdev_intf1,
1999 ictx->rx_endpoint_intf1->bEndpointAddress),
2000 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2001 usb_rx_callback_intf1, ictx,
2002 ictx->rx_endpoint_intf1->bInterval);
2003
2004 ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL);
2005
2006 if (ret) {
2007 err("%s: usb_submit_urb failed for intf1 (%d)",
2008 __func__, ret);
2009 goto urb_submit_failed;
2010 }
2011
2012 return ictx;
2013
2014urb_submit_failed:
2015 if (ictx->touch) {
2016 input_unregister_device(ictx->touch);
2017 input_free_device(ictx->touch);
2018 }
2019touch_setup_failed:
2020find_endpoint_failed:
2021 mutex_unlock(&ictx->lock);
2022 usb_free_urb(rx_urb);
2023rx_urb_alloc_failed:
2024 dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret);
2025
2026 return NULL;
2027}
2028
2029/*
2030 * The 0x15c2:0xffdc device ID was used for umpteen different imon
2031 * devices, and all of them constantly spew interrupts, even when there
2032 * is no actual data to report. However, byte 6 of this buffer looks like
2033 * its unique across device variants, so we're trying to key off that to
2034 * figure out which display type (if any) and what IR protocol the device
2035 * actually supports. These devices have their IR protocol hard-coded into
2036 * their firmware, they can't be changed on the fly like the newer hardware.
2037 */
2038static void imon_get_ffdc_type(struct imon_context *ictx)
2039{
2040 u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
2041 u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
2042 u64 allowed_protos = IR_TYPE_OTHER;
2043
2044 switch (ffdc_cfg_byte) {
2045 /* iMON Knob, no display, iMON IR + vol knob */
2046 case 0x21:
2047 dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
2048 ictx->display_supported = false;
2049 break;
2050 /* iMON VFD, no IR (does have vol knob tho) */
2051 case 0x35:
2052 dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
2053 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2054 break;
2055 /* iMON VFD, iMON IR */
2056 case 0x24:
2057 case 0x85:
2058 dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
2059 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2060 break;
2061 /* iMON LCD, MCE IR */
2062 case 0x9f:
2063 dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
2064 detected_display_type = IMON_DISPLAY_TYPE_LCD;
2065 allowed_protos = IR_TYPE_RC6;
2066 break;
2067 default:
2068 dev_info(ictx->dev, "Unknown 0xffdc device, "
2069 "defaulting to VFD and iMON IR");
2070 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2071 break;
2072 }
2073
2074 printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
2075
2076 ictx->display_type = detected_display_type;
2077 ictx->props->allowed_protos = allowed_protos;
2078 ictx->ir_type = allowed_protos;
2079}
2080
2081static void imon_set_display_type(struct imon_context *ictx,
2082 struct usb_interface *intf)
2083{
2084 u8 configured_display_type = IMON_DISPLAY_TYPE_VFD;
2085
2086 /*
2087 * Try to auto-detect the type of display if the user hasn't set
2088 * it by hand via the display_type modparam. Default is VFD.
2089 */
2090
2091 if (display_type == IMON_DISPLAY_TYPE_AUTO) {
2092 switch (ictx->product) {
2093 case 0xffdc:
2094 /* set in imon_get_ffdc_type() */
2095 configured_display_type = ictx->display_type;
2096 break;
2097 case 0x0034:
2098 case 0x0035:
2099 configured_display_type = IMON_DISPLAY_TYPE_VGA;
2100 break;
2101 case 0x0038:
2102 case 0x0039:
2103 case 0x0045:
2104 configured_display_type = IMON_DISPLAY_TYPE_LCD;
2105 break;
2106 case 0x003c:
2107 case 0x0041:
2108 case 0x0042:
2109 case 0x0043:
2110 configured_display_type = IMON_DISPLAY_TYPE_NONE;
2111 ictx->display_supported = false;
2112 break;
2113 case 0x0036:
2114 case 0x0044:
2115 default:
2116 configured_display_type = IMON_DISPLAY_TYPE_VFD;
2117 break;
2118 }
2119 } else {
2120 configured_display_type = display_type;
2121 if (display_type == IMON_DISPLAY_TYPE_NONE)
2122 ictx->display_supported = false;
2123 else
2124 ictx->display_supported = true;
2125 dev_info(ictx->dev, "%s: overriding display type to %d via "
2126 "modparam\n", __func__, display_type);
2127 }
2128
2129 ictx->display_type = configured_display_type;
2130}
2131
2132static void imon_init_display(struct imon_context *ictx,
2133 struct usb_interface *intf)
2134{
2135 int ret;
2136
2137 dev_dbg(ictx->dev, "Registering iMON display with sysfs\n");
2138
2139 /* set up sysfs entry for built-in clock */
2140 ret = sysfs_create_group(&intf->dev.kobj,
2141 &imon_display_attribute_group);
2142 if (ret)
2143 dev_err(ictx->dev, "Could not create display sysfs "
2144 "entries(%d)", ret);
2145
2146 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2147 ret = usb_register_dev(intf, &imon_lcd_class);
2148 else
2149 ret = usb_register_dev(intf, &imon_vfd_class);
2150 if (ret)
2151 /* Not a fatal error, so ignore */
2152 dev_info(ictx->dev, "could not get a minor number for "
2153 "display\n");
2154
2155}
2156
2157/**
2158 * Callback function for USB core API: Probe
2159 */
2160static int __devinit imon_probe(struct usb_interface *interface,
2161 const struct usb_device_id *id)
2162{
2163 struct usb_device *usbdev = NULL;
2164 struct usb_host_interface *iface_desc = NULL;
2165 struct usb_interface *first_if;
2166 struct device *dev = &interface->dev;
2167 int ifnum, code_length, sysfs_err;
2168 int ret = 0;
2169 struct imon_context *ictx = NULL;
2170 struct imon_context *first_if_ctx = NULL;
2171 u16 vendor, product;
2172 const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
2173 0x00, 0x00, 0x00, 0x88 };
2174
2175 code_length = BUF_CHUNK_SIZE * 8;
2176
2177 usbdev = usb_get_dev(interface_to_usbdev(interface));
2178 iface_desc = interface->cur_altsetting;
2179 ifnum = iface_desc->desc.bInterfaceNumber;
2180 vendor = le16_to_cpu(usbdev->descriptor.idVendor);
2181 product = le16_to_cpu(usbdev->descriptor.idProduct);
2182
2183 dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
2184 __func__, vendor, product, ifnum);
2185
2186 /* prevent races probing devices w/multiple interfaces */
2187 mutex_lock(&driver_lock);
2188
2189 first_if = usb_ifnum_to_if(usbdev, 0);
2190 first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if);
2191
2192 if (ifnum == 0) {
2193 ictx = imon_init_intf0(interface);
2194 if (!ictx) {
2195 err("%s: failed to initialize context!\n", __func__);
2196 ret = -ENODEV;
2197 goto fail;
2198 }
2199
2200 if (product == 0xffdc) {
2201 /* RF products *also* use 0xffdc... sigh... */
2202 sysfs_err = sysfs_create_group(&interface->dev.kobj,
2203 &imon_rf_attribute_group);
2204 if (sysfs_err)
2205 err("%s: Could not create RF sysfs entries(%d)",
2206 __func__, sysfs_err);
2207 }
2208
2209 } else {
2210 /* this is the secondary interface on the device */
2211 ictx = imon_init_intf1(interface, first_if_ctx);
2212 if (!ictx) {
2213 err("%s: failed to attach to context!\n", __func__);
2214 ret = -ENODEV;
2215 goto fail;
2216 }
2217
2218 }
2219
2220 usb_set_intfdata(interface, ictx);
2221
2222 if (ifnum == 0) {
2223 /* Enable front-panel buttons and/or knobs */
2224 memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
2225 ret = send_packet(ictx);
2226 /* Not fatal, but warn about it */
2227 if (ret)
2228 dev_info(dev, "failed to enable panel buttons "
2229 "and/or knobs\n");
2230
2231 if (product == 0xffdc)
2232 imon_get_ffdc_type(ictx);
2233
2234 imon_set_display_type(ictx, interface);
2235
2236 if (ictx->display_supported)
2237 imon_init_display(ictx, interface);
2238 }
2239
2240 /* set IR protocol/remote type */
2241 ret = imon_ir_change_protocol(ictx, ictx->ir_type);
2242 if (ret) {
2243 dev_warn(dev, "%s: failed to set IR protocol, falling back "
2244 "to standard iMON protocol mode\n", __func__);
2245 ictx->ir_type = IR_TYPE_OTHER;
2246 }
2247
2248 dev_info(dev, "iMON device (%04x:%04x, intf%d) on "
2249 "usb<%d:%d> initialized\n", vendor, product, ifnum,
2250 usbdev->bus->busnum, usbdev->devnum);
2251
2252 mutex_unlock(&ictx->lock);
2253 mutex_unlock(&driver_lock);
2254
2255 return 0;
2256
2257fail:
2258 mutex_unlock(&driver_lock);
2259 dev_err(dev, "unable to register, err %d\n", ret);
2260
2261 return ret;
2262}
2263
2264/**
2265 * Callback function for USB core API: disconnect
2266 */
2267static void __devexit imon_disconnect(struct usb_interface *interface)
2268{
2269 struct imon_context *ictx;
2270 struct device *dev;
2271 int ifnum;
2272
2273 /* prevent races with multi-interface device probing and display_open */
2274 mutex_lock(&driver_lock);
2275
2276 ictx = usb_get_intfdata(interface);
2277 dev = ictx->dev;
2278 ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
2279
2280 mutex_lock(&ictx->lock);
2281
2282 /*
2283 * sysfs_remove_group is safe to call even if sysfs_create_group
2284 * hasn't been called
2285 */
2286 sysfs_remove_group(&interface->dev.kobj,
2287 &imon_display_attribute_group);
2288 sysfs_remove_group(&interface->dev.kobj,
2289 &imon_rf_attribute_group);
2290
2291 usb_set_intfdata(interface, NULL);
2292
2293 /* Abort ongoing write */
2294 if (ictx->tx.busy) {
2295 usb_kill_urb(ictx->tx_urb);
2296 complete_all(&ictx->tx.finished);
2297 }
2298
2299 if (ifnum == 0) {
2300 ictx->dev_present_intf0 = 0;
2301 usb_kill_urb(ictx->rx_urb_intf0);
2302 input_unregister_device(ictx->idev);
2303 if (ictx->display_supported) {
2304 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2305 usb_deregister_dev(interface, &imon_lcd_class);
2306 else
2307 usb_deregister_dev(interface, &imon_vfd_class);
2308 }
2309 } else {
2310 ictx->dev_present_intf1 = 0;
2311 usb_kill_urb(ictx->rx_urb_intf1);
2312 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2313 input_unregister_device(ictx->touch);
2314 }
2315
2316 if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) {
2317 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2318 del_timer_sync(&ictx->ttimer);
2319 mutex_unlock(&ictx->lock);
2320 if (!ictx->display_isopen)
2321 free_imon_context(ictx);
2322 } else {
2323 if (ictx->ir_type == IR_TYPE_RC6)
2324 del_timer_sync(&ictx->itimer);
2325 mutex_unlock(&ictx->lock);
2326 }
2327
2328 mutex_unlock(&driver_lock);
2329
2330 dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n",
2331 __func__, ifnum);
2332}
2333
2334static int imon_suspend(struct usb_interface *intf, pm_message_t message)
2335{
2336 struct imon_context *ictx = usb_get_intfdata(intf);
2337 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
2338
2339 if (ifnum == 0)
2340 usb_kill_urb(ictx->rx_urb_intf0);
2341 else
2342 usb_kill_urb(ictx->rx_urb_intf1);
2343
2344 return 0;
2345}
2346
2347static int imon_resume(struct usb_interface *intf)
2348{
2349 int rc = 0;
2350 struct imon_context *ictx = usb_get_intfdata(intf);
2351 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
2352
2353 if (ifnum == 0) {
2354 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
2355 usb_rcvintpipe(ictx->usbdev_intf0,
2356 ictx->rx_endpoint_intf0->bEndpointAddress),
2357 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2358 usb_rx_callback_intf0, ictx,
2359 ictx->rx_endpoint_intf0->bInterval);
2360
2361 rc = usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
2362
2363 } else {
2364 usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
2365 usb_rcvintpipe(ictx->usbdev_intf1,
2366 ictx->rx_endpoint_intf1->bEndpointAddress),
2367 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2368 usb_rx_callback_intf1, ictx,
2369 ictx->rx_endpoint_intf1->bInterval);
2370
2371 rc = usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
2372 }
2373
2374 return rc;
2375}
2376
2377static int __init imon_init(void)
2378{
2379 int rc;
2380
2381 rc = usb_register(&imon_driver);
2382 if (rc) {
2383 err("%s: usb register failed(%d)", __func__, rc);
2384 rc = -ENODEV;
2385 }
2386
2387 return rc;
2388}
2389
2390static void __exit imon_exit(void)
2391{
2392 usb_deregister(&imon_driver);
2393}
2394
2395module_init(imon_init);
2396module_exit(imon_exit);
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
new file mode 100644
index 000000000000..9a5e65a471a5
--- /dev/null
+++ b/drivers/media/IR/ir-core-priv.h
@@ -0,0 +1,126 @@
1/*
2 * Remote Controller core raw events header
3 *
4 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _IR_RAW_EVENT
17#define _IR_RAW_EVENT
18
19#include <linux/slab.h>
20#include <media/ir-core.h>
21
22struct ir_raw_handler {
23 struct list_head list;
24
25 int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
26 int (*raw_register)(struct input_dev *input_dev);
27 int (*raw_unregister)(struct input_dev *input_dev);
28};
29
30struct ir_raw_event_ctrl {
31 struct work_struct rx_work; /* for the rx decoding workqueue */
32 struct kfifo kfifo; /* fifo for the pulse/space durations */
33 ktime_t last_event; /* when last event occurred */
34 enum raw_event_type last_type; /* last event type */
35 struct input_dev *input_dev; /* pointer to the parent input_dev */
36};
37
38/* macros for IR decoders */
39static inline bool geq_margin(unsigned d1, unsigned d2, unsigned margin)
40{
41 return d1 > (d2 - margin);
42}
43
44static inline bool eq_margin(unsigned d1, unsigned d2, unsigned margin)
45{
46 return ((d1 > (d2 - margin)) && (d1 < (d2 + margin)));
47}
48
49static inline bool is_transition(struct ir_raw_event *x, struct ir_raw_event *y)
50{
51 return x->pulse != y->pulse;
52}
53
54static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration)
55{
56 if (duration > ev->duration)
57 ev->duration = 0;
58 else
59 ev->duration -= duration;
60}
61
62#define TO_US(duration) (((duration) + 500) / 1000)
63#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
64#define IS_RESET(ev) (ev.duration == 0)
65
66/*
67 * Routines from ir-sysfs.c - Meant to be called only internally inside
68 * ir-core
69 */
70
71int ir_register_class(struct input_dev *input_dev);
72void ir_unregister_class(struct input_dev *input_dev);
73
74/*
75 * Routines from ir-raw-event.c to be used internally and by decoders
76 */
77int ir_raw_event_register(struct input_dev *input_dev);
78void ir_raw_event_unregister(struct input_dev *input_dev);
79int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
80void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
81void ir_raw_init(void);
82
83
84/*
85 * Decoder initialization code
86 *
87 * Those load logic are called during ir-core init, and automatically
88 * loads the compiled decoders for their usage with IR raw events
89 */
90
91/* from ir-nec-decoder.c */
92#ifdef CONFIG_IR_NEC_DECODER_MODULE
93#define load_nec_decode() request_module("ir-nec-decoder")
94#else
95#define load_nec_decode() 0
96#endif
97
98/* from ir-rc5-decoder.c */
99#ifdef CONFIG_IR_RC5_DECODER_MODULE
100#define load_rc5_decode() request_module("ir-rc5-decoder")
101#else
102#define load_rc5_decode() 0
103#endif
104
105/* from ir-rc6-decoder.c */
106#ifdef CONFIG_IR_RC6_DECODER_MODULE
107#define load_rc6_decode() request_module("ir-rc6-decoder")
108#else
109#define load_rc6_decode() 0
110#endif
111
112/* from ir-jvc-decoder.c */
113#ifdef CONFIG_IR_JVC_DECODER_MODULE
114#define load_jvc_decode() request_module("ir-jvc-decoder")
115#else
116#define load_jvc_decode() 0
117#endif
118
119/* from ir-sony-decoder.c */
120#ifdef CONFIG_IR_SONY_DECODER_MODULE
121#define load_sony_decode() request_module("ir-sony-decoder")
122#else
123#define load_sony_decode() 0
124#endif
125
126#endif /* _IR_RAW_EVENT */
diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
index ab06919ad5fc..db591e421887 100644
--- a/drivers/media/IR/ir-functions.c
+++ b/drivers/media/IR/ir-functions.c
@@ -24,6 +24,7 @@
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/jiffies.h> 25#include <linux/jiffies.h>
26#include <media/ir-common.h> 26#include <media/ir-common.h>
27#include "ir-core-priv.h"
27 28
28/* -------------------------------------------------------------------------- */ 29/* -------------------------------------------------------------------------- */
29 30
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
new file mode 100644
index 000000000000..0b804944cbb0
--- /dev/null
+++ b/drivers/media/IR/ir-jvc-decoder.c
@@ -0,0 +1,320 @@
1/* ir-jvc-decoder.c - handle JVC IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/bitrev.h>
16#include "ir-core-priv.h"
17
18#define JVC_NBITS 16 /* dev(8) + func(8) */
19#define JVC_UNIT 525000 /* ns */
20#define JVC_HEADER_PULSE (16 * JVC_UNIT) /* lack of header -> repeat */
21#define JVC_HEADER_SPACE (8 * JVC_UNIT)
22#define JVC_BIT_PULSE (1 * JVC_UNIT)
23#define JVC_BIT_0_SPACE (1 * JVC_UNIT)
24#define JVC_BIT_1_SPACE (3 * JVC_UNIT)
25#define JVC_TRAILER_PULSE (1 * JVC_UNIT)
26#define JVC_TRAILER_SPACE (35 * JVC_UNIT)
27
28/* Used to register jvc_decoder clients */
29static LIST_HEAD(decoder_list);
30DEFINE_SPINLOCK(decoder_lock);
31
32enum jvc_state {
33 STATE_INACTIVE,
34 STATE_HEADER_SPACE,
35 STATE_BIT_PULSE,
36 STATE_BIT_SPACE,
37 STATE_TRAILER_PULSE,
38 STATE_TRAILER_SPACE,
39};
40
41struct decoder_data {
42 struct list_head list;
43 struct ir_input_dev *ir_dev;
44 int enabled:1;
45
46 /* State machine control */
47 enum jvc_state state;
48 u16 jvc_bits;
49 u16 jvc_old_bits;
50 unsigned count;
51 bool first;
52 bool toggle;
53};
54
55
56/**
57 * get_decoder_data() - gets decoder data
58 * @input_dev: input device
59 *
60 * Returns the struct decoder_data that corresponds to a device
61 */
62static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
63{
64 struct decoder_data *data = NULL;
65
66 spin_lock(&decoder_lock);
67 list_for_each_entry(data, &decoder_list, list) {
68 if (data->ir_dev == ir_dev)
69 break;
70 }
71 spin_unlock(&decoder_lock);
72 return data;
73}
74
75static ssize_t store_enabled(struct device *d,
76 struct device_attribute *mattr,
77 const char *buf,
78 size_t len)
79{
80 unsigned long value;
81 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
82 struct decoder_data *data = get_decoder_data(ir_dev);
83
84 if (!data)
85 return -EINVAL;
86
87 if (strict_strtoul(buf, 10, &value) || value > 1)
88 return -EINVAL;
89
90 data->enabled = value;
91
92 return len;
93}
94
95static ssize_t show_enabled(struct device *d,
96 struct device_attribute *mattr, char *buf)
97{
98 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
99 struct decoder_data *data = get_decoder_data(ir_dev);
100
101 if (!data)
102 return -EINVAL;
103
104 if (data->enabled)
105 return sprintf(buf, "1\n");
106 else
107 return sprintf(buf, "0\n");
108}
109
110static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
111
112static struct attribute *decoder_attributes[] = {
113 &dev_attr_enabled.attr,
114 NULL
115};
116
117static struct attribute_group decoder_attribute_group = {
118 .name = "jvc_decoder",
119 .attrs = decoder_attributes,
120};
121
122/**
123 * ir_jvc_decode() - Decode one JVC pulse or space
124 * @input_dev: the struct input_dev descriptor of the device
125 * @duration: the struct ir_raw_event descriptor of the pulse/space
126 *
127 * This function returns -EINVAL if the pulse violates the state machine
128 */
129static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
130{
131 struct decoder_data *data;
132 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
133
134 data = get_decoder_data(ir_dev);
135 if (!data)
136 return -EINVAL;
137
138 if (!data->enabled)
139 return 0;
140
141 if (IS_RESET(ev)) {
142 data->state = STATE_INACTIVE;
143 return 0;
144 }
145
146 if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2))
147 goto out;
148
149 IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n",
150 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
151
152 switch (data->state) {
153
154 case STATE_INACTIVE:
155 if (!ev.pulse)
156 break;
157
158 if (!eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
159 break;
160
161 data->count = 0;
162 data->first = true;
163 data->toggle = !data->toggle;
164 data->state = STATE_HEADER_SPACE;
165 return 0;
166
167 case STATE_HEADER_SPACE:
168 if (ev.pulse)
169 break;
170
171 if (!eq_margin(ev.duration, JVC_HEADER_SPACE, JVC_UNIT / 2))
172 break;
173
174 data->state = STATE_BIT_PULSE;
175 return 0;
176
177 case STATE_BIT_PULSE:
178 if (!ev.pulse)
179 break;
180
181 if (!eq_margin(ev.duration, JVC_BIT_PULSE, JVC_UNIT / 2))
182 break;
183
184 data->state = STATE_BIT_SPACE;
185 return 0;
186
187 case STATE_BIT_SPACE:
188 if (ev.pulse)
189 break;
190
191 data->jvc_bits <<= 1;
192 if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
193 data->jvc_bits |= 1;
194 decrease_duration(&ev, JVC_BIT_1_SPACE);
195 } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
196 decrease_duration(&ev, JVC_BIT_0_SPACE);
197 else
198 break;
199 data->count++;
200
201 if (data->count == JVC_NBITS)
202 data->state = STATE_TRAILER_PULSE;
203 else
204 data->state = STATE_BIT_PULSE;
205 return 0;
206
207 case STATE_TRAILER_PULSE:
208 if (!ev.pulse)
209 break;
210
211 if (!eq_margin(ev.duration, JVC_TRAILER_PULSE, JVC_UNIT / 2))
212 break;
213
214 data->state = STATE_TRAILER_SPACE;
215 return 0;
216
217 case STATE_TRAILER_SPACE:
218 if (ev.pulse)
219 break;
220
221 if (!geq_margin(ev.duration, JVC_TRAILER_SPACE, JVC_UNIT / 2))
222 break;
223
224 if (data->first) {
225 u32 scancode;
226 scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
227 (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
228 IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
229 ir_keydown(input_dev, scancode, data->toggle);
230 data->first = false;
231 data->jvc_old_bits = data->jvc_bits;
232 } else if (data->jvc_bits == data->jvc_old_bits) {
233 IR_dprintk(1, "JVC repeat\n");
234 ir_repeat(input_dev);
235 } else {
236 IR_dprintk(1, "JVC invalid repeat msg\n");
237 break;
238 }
239
240 data->count = 0;
241 data->state = STATE_BIT_PULSE;
242 return 0;
243 }
244
245out:
246 IR_dprintk(1, "JVC decode failed at state %d (%uus %s)\n",
247 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
248 data->state = STATE_INACTIVE;
249 return -EINVAL;
250}
251
252static int ir_jvc_register(struct input_dev *input_dev)
253{
254 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
255 struct decoder_data *data;
256 int rc;
257
258 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
259 if (rc < 0)
260 return rc;
261
262 data = kzalloc(sizeof(*data), GFP_KERNEL);
263 if (!data) {
264 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
265 return -ENOMEM;
266 }
267
268 data->ir_dev = ir_dev;
269 data->enabled = 1;
270
271 spin_lock(&decoder_lock);
272 list_add_tail(&data->list, &decoder_list);
273 spin_unlock(&decoder_lock);
274
275 return 0;
276}
277
278static int ir_jvc_unregister(struct input_dev *input_dev)
279{
280 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
281 static struct decoder_data *data;
282
283 data = get_decoder_data(ir_dev);
284 if (!data)
285 return 0;
286
287 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
288
289 spin_lock(&decoder_lock);
290 list_del(&data->list);
291 spin_unlock(&decoder_lock);
292
293 return 0;
294}
295
296static struct ir_raw_handler jvc_handler = {
297 .decode = ir_jvc_decode,
298 .raw_register = ir_jvc_register,
299 .raw_unregister = ir_jvc_unregister,
300};
301
302static int __init ir_jvc_decode_init(void)
303{
304 ir_raw_handler_register(&jvc_handler);
305
306 printk(KERN_INFO "IR JVC protocol handler initialized\n");
307 return 0;
308}
309
310static void __exit ir_jvc_decode_exit(void)
311{
312 ir_raw_handler_unregister(&jvc_handler);
313}
314
315module_init(ir_jvc_decode_init);
316module_exit(ir_jvc_decode_exit);
317
318MODULE_LICENSE("GPL");
319MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
320MODULE_DESCRIPTION("JVC IR protocol decoder");
diff --git a/drivers/media/IR/ir-keymaps.c b/drivers/media/IR/ir-keymaps.c
deleted file mode 100644
index 0efdefe75f32..000000000000
--- a/drivers/media/IR/ir-keymaps.c
+++ /dev/null
@@ -1,3494 +0,0 @@
1/*
2 Keytables for supported remote controls, used on drivers/media
3 devices.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20/*
21 * NOTICE FOR DEVELOPERS:
22 * The IR mappings should be as close as possible to what's
23 * specified at:
24 * http://linuxtv.org/wiki/index.php/Remote_Controllers
25 */
26#include <linux/module.h>
27
28#include <linux/input.h>
29#include <media/ir-common.h>
30
31/* empty keytable, can be used as placeholder for not-yet created keytables */
32static struct ir_scancode ir_codes_empty[] = {
33 { 0x2a, KEY_COFFEE },
34};
35
36struct ir_scancode_table ir_codes_empty_table = {
37 .scan = ir_codes_empty,
38 .size = ARRAY_SIZE(ir_codes_empty),
39};
40EXPORT_SYMBOL_GPL(ir_codes_empty_table);
41
42/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
43static struct ir_scancode ir_codes_proteus_2309[] = {
44 /* numeric */
45 { 0x00, KEY_0 },
46 { 0x01, KEY_1 },
47 { 0x02, KEY_2 },
48 { 0x03, KEY_3 },
49 { 0x04, KEY_4 },
50 { 0x05, KEY_5 },
51 { 0x06, KEY_6 },
52 { 0x07, KEY_7 },
53 { 0x08, KEY_8 },
54 { 0x09, KEY_9 },
55
56 { 0x5c, KEY_POWER }, /* power */
57 { 0x20, KEY_ZOOM }, /* full screen */
58 { 0x0f, KEY_BACKSPACE }, /* recall */
59 { 0x1b, KEY_ENTER }, /* mute */
60 { 0x41, KEY_RECORD }, /* record */
61 { 0x43, KEY_STOP }, /* stop */
62 { 0x16, KEY_S },
63 { 0x1a, KEY_POWER2 }, /* off */
64 { 0x2e, KEY_RED },
65 { 0x1f, KEY_CHANNELDOWN }, /* channel - */
66 { 0x1c, KEY_CHANNELUP }, /* channel + */
67 { 0x10, KEY_VOLUMEDOWN }, /* volume - */
68 { 0x1e, KEY_VOLUMEUP }, /* volume + */
69 { 0x14, KEY_F1 },
70};
71
72struct ir_scancode_table ir_codes_proteus_2309_table = {
73 .scan = ir_codes_proteus_2309,
74 .size = ARRAY_SIZE(ir_codes_proteus_2309),
75};
76EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
77
78/* Matt Jesson <dvb@jesson.eclipse.co.uk */
79static struct ir_scancode ir_codes_avermedia_dvbt[] = {
80 { 0x28, KEY_0 }, /* '0' / 'enter' */
81 { 0x22, KEY_1 }, /* '1' */
82 { 0x12, KEY_2 }, /* '2' / 'up arrow' */
83 { 0x32, KEY_3 }, /* '3' */
84 { 0x24, KEY_4 }, /* '4' / 'left arrow' */
85 { 0x14, KEY_5 }, /* '5' */
86 { 0x34, KEY_6 }, /* '6' / 'right arrow' */
87 { 0x26, KEY_7 }, /* '7' */
88 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
89 { 0x36, KEY_9 }, /* '9' */
90
91 { 0x20, KEY_LIST }, /* 'source' */
92 { 0x10, KEY_TEXT }, /* 'teletext' */
93 { 0x00, KEY_POWER }, /* 'power' */
94 { 0x04, KEY_AUDIO }, /* 'audio' */
95 { 0x06, KEY_ZOOM }, /* 'full screen' */
96 { 0x18, KEY_VIDEO }, /* 'display' */
97 { 0x38, KEY_SEARCH }, /* 'loop' */
98 { 0x08, KEY_INFO }, /* 'preview' */
99 { 0x2a, KEY_REWIND }, /* 'backward <<' */
100 { 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
101 { 0x3a, KEY_RECORD }, /* 'capture' */
102 { 0x0a, KEY_MUTE }, /* 'mute' */
103 { 0x2c, KEY_RECORD }, /* 'record' */
104 { 0x1c, KEY_PAUSE }, /* 'pause' */
105 { 0x3c, KEY_STOP }, /* 'stop' */
106 { 0x0c, KEY_PLAY }, /* 'play' */
107 { 0x2e, KEY_RED }, /* 'red' */
108 { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
109 { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
110 { 0x21, KEY_GREEN }, /* 'green' */
111 { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
112 { 0x31, KEY_CHANNELUP }, /* 'channel +' */
113 { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
114 { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
115};
116
117struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
118 .scan = ir_codes_avermedia_dvbt,
119 .size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
120};
121EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
122
123/* Mauro Carvalho Chehab <mchehab@infradead.org> */
124static struct ir_scancode ir_codes_avermedia_m135a[] = {
125 { 0x00, KEY_POWER2 },
126 { 0x2e, KEY_DOT }, /* '.' */
127 { 0x01, KEY_MODE }, /* TV/FM */
128
129 { 0x05, KEY_1 },
130 { 0x06, KEY_2 },
131 { 0x07, KEY_3 },
132 { 0x09, KEY_4 },
133 { 0x0a, KEY_5 },
134 { 0x0b, KEY_6 },
135 { 0x0d, KEY_7 },
136 { 0x0e, KEY_8 },
137 { 0x0f, KEY_9 },
138 { 0x11, KEY_0 },
139
140 { 0x13, KEY_RIGHT }, /* -> */
141 { 0x12, KEY_LEFT }, /* <- */
142
143 { 0x17, KEY_SLEEP }, /* Capturar Imagem */
144 { 0x10, KEY_SHUFFLE }, /* Amostra */
145
146 /* FIXME: The keys bellow aren't ok */
147
148 { 0x43, KEY_CHANNELUP },
149 { 0x42, KEY_CHANNELDOWN },
150 { 0x1f, KEY_VOLUMEUP },
151 { 0x1e, KEY_VOLUMEDOWN },
152 { 0x0c, KEY_ENTER },
153
154 { 0x14, KEY_MUTE },
155 { 0x08, KEY_AUDIO },
156
157 { 0x03, KEY_TEXT },
158 { 0x04, KEY_EPG },
159 { 0x2b, KEY_TV2 }, /* TV2 */
160
161 { 0x1d, KEY_RED },
162 { 0x1c, KEY_YELLOW },
163 { 0x41, KEY_GREEN },
164 { 0x40, KEY_BLUE },
165
166 { 0x1a, KEY_PLAYPAUSE },
167 { 0x19, KEY_RECORD },
168 { 0x18, KEY_PLAY },
169 { 0x1b, KEY_STOP },
170};
171
172struct ir_scancode_table ir_codes_avermedia_m135a_table = {
173 .scan = ir_codes_avermedia_m135a,
174 .size = ARRAY_SIZE(ir_codes_avermedia_m135a),
175};
176EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
177
178/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
179static struct ir_scancode ir_codes_avermedia_cardbus[] = {
180 { 0x00, KEY_POWER },
181 { 0x01, KEY_TUNER }, /* TV/FM */
182 { 0x03, KEY_TEXT }, /* Teletext */
183 { 0x04, KEY_EPG },
184 { 0x05, KEY_1 },
185 { 0x06, KEY_2 },
186 { 0x07, KEY_3 },
187 { 0x08, KEY_AUDIO },
188 { 0x09, KEY_4 },
189 { 0x0a, KEY_5 },
190 { 0x0b, KEY_6 },
191 { 0x0c, KEY_ZOOM }, /* Full screen */
192 { 0x0d, KEY_7 },
193 { 0x0e, KEY_8 },
194 { 0x0f, KEY_9 },
195 { 0x10, KEY_PAGEUP }, /* 16-CH PREV */
196 { 0x11, KEY_0 },
197 { 0x12, KEY_INFO },
198 { 0x13, KEY_AGAIN }, /* CH RTN - channel return */
199 { 0x14, KEY_MUTE },
200 { 0x15, KEY_EDIT }, /* Autoscan */
201 { 0x17, KEY_SAVE }, /* Screenshot */
202 { 0x18, KEY_PLAYPAUSE },
203 { 0x19, KEY_RECORD },
204 { 0x1a, KEY_PLAY },
205 { 0x1b, KEY_STOP },
206 { 0x1c, KEY_FASTFORWARD },
207 { 0x1d, KEY_REWIND },
208 { 0x1e, KEY_VOLUMEDOWN },
209 { 0x1f, KEY_VOLUMEUP },
210 { 0x22, KEY_SLEEP }, /* Sleep */
211 { 0x23, KEY_ZOOM }, /* Aspect */
212 { 0x26, KEY_SCREEN }, /* Pos */
213 { 0x27, KEY_ANGLE }, /* Size */
214 { 0x28, KEY_SELECT }, /* Select */
215 { 0x29, KEY_BLUE }, /* Blue/Picture */
216 { 0x2a, KEY_BACKSPACE }, /* Back */
217 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
218 { 0x2c, KEY_DOWN },
219 { 0x2e, KEY_DOT },
220 { 0x2f, KEY_TV }, /* Live TV */
221 { 0x32, KEY_LEFT },
222 { 0x33, KEY_CLEAR }, /* Clear */
223 { 0x35, KEY_RED }, /* Red/TV */
224 { 0x36, KEY_UP },
225 { 0x37, KEY_HOME }, /* Home */
226 { 0x39, KEY_GREEN }, /* Green/Video */
227 { 0x3d, KEY_YELLOW }, /* Yellow/Music */
228 { 0x3e, KEY_OK }, /* Ok */
229 { 0x3f, KEY_RIGHT },
230 { 0x40, KEY_NEXT }, /* Next */
231 { 0x41, KEY_PREVIOUS }, /* Previous */
232 { 0x42, KEY_CHANNELDOWN }, /* Channel down */
233 { 0x43, KEY_CHANNELUP }, /* Channel up */
234};
235
236struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
237 .scan = ir_codes_avermedia_cardbus,
238 .size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
239};
240EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
241
242/* Attila Kondoros <attila.kondoros@chello.hu> */
243static struct ir_scancode ir_codes_apac_viewcomp[] = {
244
245 { 0x01, KEY_1 },
246 { 0x02, KEY_2 },
247 { 0x03, KEY_3 },
248 { 0x04, KEY_4 },
249 { 0x05, KEY_5 },
250 { 0x06, KEY_6 },
251 { 0x07, KEY_7 },
252 { 0x08, KEY_8 },
253 { 0x09, KEY_9 },
254 { 0x00, KEY_0 },
255 { 0x17, KEY_LAST }, /* +100 */
256 { 0x0a, KEY_LIST }, /* recall */
257
258
259 { 0x1c, KEY_TUNER }, /* TV/FM */
260 { 0x15, KEY_SEARCH }, /* scan */
261 { 0x12, KEY_POWER }, /* power */
262 { 0x1f, KEY_VOLUMEDOWN }, /* vol up */
263 { 0x1b, KEY_VOLUMEUP }, /* vol down */
264 { 0x1e, KEY_CHANNELDOWN }, /* chn up */
265 { 0x1a, KEY_CHANNELUP }, /* chn down */
266
267 { 0x11, KEY_VIDEO }, /* video */
268 { 0x0f, KEY_ZOOM }, /* full screen */
269 { 0x13, KEY_MUTE }, /* mute/unmute */
270 { 0x10, KEY_TEXT }, /* min */
271
272 { 0x0d, KEY_STOP }, /* freeze */
273 { 0x0e, KEY_RECORD }, /* record */
274 { 0x1d, KEY_PLAYPAUSE }, /* stop */
275 { 0x19, KEY_PLAY }, /* play */
276
277 { 0x16, KEY_GOTO }, /* osd */
278 { 0x14, KEY_REFRESH }, /* default */
279 { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
280 { 0x18, KEY_KPMINUS }, /* fine tune <<<< */
281};
282
283struct ir_scancode_table ir_codes_apac_viewcomp_table = {
284 .scan = ir_codes_apac_viewcomp,
285 .size = ARRAY_SIZE(ir_codes_apac_viewcomp),
286};
287EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
288
289/* ---------------------------------------------------------------------- */
290
291static struct ir_scancode ir_codes_pixelview[] = {
292
293 { 0x1e, KEY_POWER }, /* power */
294 { 0x07, KEY_MEDIA }, /* source */
295 { 0x1c, KEY_SEARCH }, /* scan */
296
297
298 { 0x03, KEY_TUNER }, /* TV/FM */
299
300 { 0x00, KEY_RECORD },
301 { 0x08, KEY_STOP },
302 { 0x11, KEY_PLAY },
303
304 { 0x1a, KEY_PLAYPAUSE }, /* freeze */
305 { 0x19, KEY_ZOOM }, /* zoom */
306 { 0x0f, KEY_TEXT }, /* min */
307
308 { 0x01, KEY_1 },
309 { 0x0b, KEY_2 },
310 { 0x1b, KEY_3 },
311 { 0x05, KEY_4 },
312 { 0x09, KEY_5 },
313 { 0x15, KEY_6 },
314 { 0x06, KEY_7 },
315 { 0x0a, KEY_8 },
316 { 0x12, KEY_9 },
317 { 0x02, KEY_0 },
318 { 0x10, KEY_LAST }, /* +100 */
319 { 0x13, KEY_LIST }, /* recall */
320
321 { 0x1f, KEY_CHANNELUP }, /* chn down */
322 { 0x17, KEY_CHANNELDOWN }, /* chn up */
323 { 0x16, KEY_VOLUMEUP }, /* vol down */
324 { 0x14, KEY_VOLUMEDOWN }, /* vol up */
325
326 { 0x04, KEY_KPMINUS }, /* <<< */
327 { 0x0e, KEY_SETUP }, /* function */
328 { 0x0c, KEY_KPPLUS }, /* >>> */
329
330 { 0x0d, KEY_GOTO }, /* mts */
331 { 0x1d, KEY_REFRESH }, /* reset */
332 { 0x18, KEY_MUTE }, /* mute/unmute */
333};
334
335struct ir_scancode_table ir_codes_pixelview_table = {
336 .scan = ir_codes_pixelview,
337 .size = ARRAY_SIZE(ir_codes_pixelview),
338};
339EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
340
341/*
342 Mauro Carvalho Chehab <mchehab@infradead.org>
343 present on PV MPEG 8000GT
344 */
345static struct ir_scancode ir_codes_pixelview_new[] = {
346 { 0x3c, KEY_TIME }, /* Timeshift */
347 { 0x12, KEY_POWER },
348
349 { 0x3d, KEY_1 },
350 { 0x38, KEY_2 },
351 { 0x18, KEY_3 },
352 { 0x35, KEY_4 },
353 { 0x39, KEY_5 },
354 { 0x15, KEY_6 },
355 { 0x36, KEY_7 },
356 { 0x3a, KEY_8 },
357 { 0x1e, KEY_9 },
358 { 0x3e, KEY_0 },
359
360 { 0x1c, KEY_AGAIN }, /* LOOP */
361 { 0x3f, KEY_MEDIA }, /* Source */
362 { 0x1f, KEY_LAST }, /* +100 */
363 { 0x1b, KEY_MUTE },
364
365 { 0x17, KEY_CHANNELDOWN },
366 { 0x16, KEY_CHANNELUP },
367 { 0x10, KEY_VOLUMEUP },
368 { 0x14, KEY_VOLUMEDOWN },
369 { 0x13, KEY_ZOOM },
370
371 { 0x19, KEY_CAMERA }, /* SNAPSHOT */
372 { 0x1a, KEY_SEARCH }, /* scan */
373
374 { 0x37, KEY_REWIND }, /* << */
375 { 0x32, KEY_RECORD }, /* o (red) */
376 { 0x33, KEY_FORWARD }, /* >> */
377 { 0x11, KEY_STOP }, /* square */
378 { 0x3b, KEY_PLAY }, /* > */
379 { 0x30, KEY_PLAYPAUSE }, /* || */
380
381 { 0x31, KEY_TV },
382 { 0x34, KEY_RADIO },
383};
384
385struct ir_scancode_table ir_codes_pixelview_new_table = {
386 .scan = ir_codes_pixelview_new,
387 .size = ARRAY_SIZE(ir_codes_pixelview_new),
388};
389EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
390
391static struct ir_scancode ir_codes_nebula[] = {
392 { 0x00, KEY_0 },
393 { 0x01, KEY_1 },
394 { 0x02, KEY_2 },
395 { 0x03, KEY_3 },
396 { 0x04, KEY_4 },
397 { 0x05, KEY_5 },
398 { 0x06, KEY_6 },
399 { 0x07, KEY_7 },
400 { 0x08, KEY_8 },
401 { 0x09, KEY_9 },
402 { 0x0a, KEY_TV },
403 { 0x0b, KEY_AUX },
404 { 0x0c, KEY_DVD },
405 { 0x0d, KEY_POWER },
406 { 0x0e, KEY_MHP }, /* labelled 'Picture' */
407 { 0x0f, KEY_AUDIO },
408 { 0x10, KEY_INFO },
409 { 0x11, KEY_F13 }, /* 16:9 */
410 { 0x12, KEY_F14 }, /* 14:9 */
411 { 0x13, KEY_EPG },
412 { 0x14, KEY_EXIT },
413 { 0x15, KEY_MENU },
414 { 0x16, KEY_UP },
415 { 0x17, KEY_DOWN },
416 { 0x18, KEY_LEFT },
417 { 0x19, KEY_RIGHT },
418 { 0x1a, KEY_ENTER },
419 { 0x1b, KEY_CHANNELUP },
420 { 0x1c, KEY_CHANNELDOWN },
421 { 0x1d, KEY_VOLUMEUP },
422 { 0x1e, KEY_VOLUMEDOWN },
423 { 0x1f, KEY_RED },
424 { 0x20, KEY_GREEN },
425 { 0x21, KEY_YELLOW },
426 { 0x22, KEY_BLUE },
427 { 0x23, KEY_SUBTITLE },
428 { 0x24, KEY_F15 }, /* AD */
429 { 0x25, KEY_TEXT },
430 { 0x26, KEY_MUTE },
431 { 0x27, KEY_REWIND },
432 { 0x28, KEY_STOP },
433 { 0x29, KEY_PLAY },
434 { 0x2a, KEY_FASTFORWARD },
435 { 0x2b, KEY_F16 }, /* chapter */
436 { 0x2c, KEY_PAUSE },
437 { 0x2d, KEY_PLAY },
438 { 0x2e, KEY_RECORD },
439 { 0x2f, KEY_F17 }, /* picture in picture */
440 { 0x30, KEY_KPPLUS }, /* zoom in */
441 { 0x31, KEY_KPMINUS }, /* zoom out */
442 { 0x32, KEY_F18 }, /* capture */
443 { 0x33, KEY_F19 }, /* web */
444 { 0x34, KEY_EMAIL },
445 { 0x35, KEY_PHONE },
446 { 0x36, KEY_PC },
447};
448
449struct ir_scancode_table ir_codes_nebula_table = {
450 .scan = ir_codes_nebula,
451 .size = ARRAY_SIZE(ir_codes_nebula),
452};
453EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
454
455/* DigitalNow DNTV Live DVB-T Remote */
456static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
457 { 0x00, KEY_ESC }, /* 'go up a level?' */
458 /* Keys 0 to 9 */
459 { 0x0a, KEY_0 },
460 { 0x01, KEY_1 },
461 { 0x02, KEY_2 },
462 { 0x03, KEY_3 },
463 { 0x04, KEY_4 },
464 { 0x05, KEY_5 },
465 { 0x06, KEY_6 },
466 { 0x07, KEY_7 },
467 { 0x08, KEY_8 },
468 { 0x09, KEY_9 },
469
470 { 0x0b, KEY_TUNER }, /* tv/fm */
471 { 0x0c, KEY_SEARCH }, /* scan */
472 { 0x0d, KEY_STOP },
473 { 0x0e, KEY_PAUSE },
474 { 0x0f, KEY_LIST }, /* source */
475
476 { 0x10, KEY_MUTE },
477 { 0x11, KEY_REWIND }, /* backward << */
478 { 0x12, KEY_POWER },
479 { 0x13, KEY_CAMERA }, /* snap */
480 { 0x14, KEY_AUDIO }, /* stereo */
481 { 0x15, KEY_CLEAR }, /* reset */
482 { 0x16, KEY_PLAY },
483 { 0x17, KEY_ENTER },
484 { 0x18, KEY_ZOOM }, /* full screen */
485 { 0x19, KEY_FASTFORWARD }, /* forward >> */
486 { 0x1a, KEY_CHANNELUP },
487 { 0x1b, KEY_VOLUMEUP },
488 { 0x1c, KEY_INFO }, /* preview */
489 { 0x1d, KEY_RECORD }, /* record */
490 { 0x1e, KEY_CHANNELDOWN },
491 { 0x1f, KEY_VOLUMEDOWN },
492};
493
494struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
495 .scan = ir_codes_dntv_live_dvb_t,
496 .size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
497};
498EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
499
500/* ---------------------------------------------------------------------- */
501
502/* IO-DATA BCTV7E Remote */
503static struct ir_scancode ir_codes_iodata_bctv7e[] = {
504 { 0x40, KEY_TV },
505 { 0x20, KEY_RADIO }, /* FM */
506 { 0x60, KEY_EPG },
507 { 0x00, KEY_POWER },
508
509 /* Keys 0 to 9 */
510 { 0x44, KEY_0 }, /* 10 */
511 { 0x50, KEY_1 },
512 { 0x30, KEY_2 },
513 { 0x70, KEY_3 },
514 { 0x48, KEY_4 },
515 { 0x28, KEY_5 },
516 { 0x68, KEY_6 },
517 { 0x58, KEY_7 },
518 { 0x38, KEY_8 },
519 { 0x78, KEY_9 },
520
521 { 0x10, KEY_L }, /* Live */
522 { 0x08, KEY_TIME }, /* Time Shift */
523
524 { 0x18, KEY_PLAYPAUSE }, /* Play */
525
526 { 0x24, KEY_ENTER }, /* 11 */
527 { 0x64, KEY_ESC }, /* 12 */
528 { 0x04, KEY_M }, /* Multi */
529
530 { 0x54, KEY_VIDEO },
531 { 0x34, KEY_CHANNELUP },
532 { 0x74, KEY_VOLUMEUP },
533 { 0x14, KEY_MUTE },
534
535 { 0x4c, KEY_VCR }, /* SVIDEO */
536 { 0x2c, KEY_CHANNELDOWN },
537 { 0x6c, KEY_VOLUMEDOWN },
538 { 0x0c, KEY_ZOOM },
539
540 { 0x5c, KEY_PAUSE },
541 { 0x3c, KEY_RED }, /* || (red) */
542 { 0x7c, KEY_RECORD }, /* recording */
543 { 0x1c, KEY_STOP },
544
545 { 0x41, KEY_REWIND }, /* backward << */
546 { 0x21, KEY_PLAY },
547 { 0x61, KEY_FASTFORWARD }, /* forward >> */
548 { 0x01, KEY_NEXT }, /* skip >| */
549};
550
551struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
552 .scan = ir_codes_iodata_bctv7e,
553 .size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
554};
555EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
556
557/* ---------------------------------------------------------------------- */
558
559/* ADS Tech Instant TV DVB-T PCI Remote */
560static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
561 /* Keys 0 to 9 */
562 { 0x4d, KEY_0 },
563 { 0x57, KEY_1 },
564 { 0x4f, KEY_2 },
565 { 0x53, KEY_3 },
566 { 0x56, KEY_4 },
567 { 0x4e, KEY_5 },
568 { 0x5e, KEY_6 },
569 { 0x54, KEY_7 },
570 { 0x4c, KEY_8 },
571 { 0x5c, KEY_9 },
572
573 { 0x5b, KEY_POWER },
574 { 0x5f, KEY_MUTE },
575 { 0x55, KEY_GOTO },
576 { 0x5d, KEY_SEARCH },
577 { 0x17, KEY_EPG }, /* Guide */
578 { 0x1f, KEY_MENU },
579 { 0x0f, KEY_UP },
580 { 0x46, KEY_DOWN },
581 { 0x16, KEY_LEFT },
582 { 0x1e, KEY_RIGHT },
583 { 0x0e, KEY_SELECT }, /* Enter */
584 { 0x5a, KEY_INFO },
585 { 0x52, KEY_EXIT },
586 { 0x59, KEY_PREVIOUS },
587 { 0x51, KEY_NEXT },
588 { 0x58, KEY_REWIND },
589 { 0x50, KEY_FORWARD },
590 { 0x44, KEY_PLAYPAUSE },
591 { 0x07, KEY_STOP },
592 { 0x1b, KEY_RECORD },
593 { 0x13, KEY_TUNER }, /* Live */
594 { 0x0a, KEY_A },
595 { 0x12, KEY_B },
596 { 0x03, KEY_PROG1 }, /* 1 */
597 { 0x01, KEY_PROG2 }, /* 2 */
598 { 0x00, KEY_PROG3 }, /* 3 */
599 { 0x06, KEY_DVD },
600 { 0x48, KEY_AUX }, /* Photo */
601 { 0x40, KEY_VIDEO },
602 { 0x19, KEY_AUDIO }, /* Music */
603 { 0x0b, KEY_CHANNELUP },
604 { 0x08, KEY_CHANNELDOWN },
605 { 0x15, KEY_VOLUMEUP },
606 { 0x1c, KEY_VOLUMEDOWN },
607};
608
609struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
610 .scan = ir_codes_adstech_dvb_t_pci,
611 .size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
612};
613EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
614
615/* ---------------------------------------------------------------------- */
616
617/* MSI TV@nywhere MASTER remote */
618
619static struct ir_scancode ir_codes_msi_tvanywhere[] = {
620 /* Keys 0 to 9 */
621 { 0x00, KEY_0 },
622 { 0x01, KEY_1 },
623 { 0x02, KEY_2 },
624 { 0x03, KEY_3 },
625 { 0x04, KEY_4 },
626 { 0x05, KEY_5 },
627 { 0x06, KEY_6 },
628 { 0x07, KEY_7 },
629 { 0x08, KEY_8 },
630 { 0x09, KEY_9 },
631
632 { 0x0c, KEY_MUTE },
633 { 0x0f, KEY_SCREEN }, /* Full Screen */
634 { 0x10, KEY_FN }, /* Funtion */
635 { 0x11, KEY_TIME }, /* Time shift */
636 { 0x12, KEY_POWER },
637 { 0x13, KEY_MEDIA }, /* MTS */
638 { 0x14, KEY_SLOW },
639 { 0x16, KEY_REWIND }, /* backward << */
640 { 0x17, KEY_ENTER }, /* Return */
641 { 0x18, KEY_FASTFORWARD }, /* forward >> */
642 { 0x1a, KEY_CHANNELUP },
643 { 0x1b, KEY_VOLUMEUP },
644 { 0x1e, KEY_CHANNELDOWN },
645 { 0x1f, KEY_VOLUMEDOWN },
646};
647
648struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
649 .scan = ir_codes_msi_tvanywhere,
650 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
651};
652EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
653
654/* ---------------------------------------------------------------------- */
655
656/*
657 Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
658 is marked "KS003". The controller is I2C at address 0x30, but does not seem
659 to respond to probes until a read is performed from a valid device.
660 I don't know why...
661
662 Note: This remote may be of similar or identical design to the
663 Pixelview remote (?). The raw codes and duplicate button codes
664 appear to be the same.
665
666 Henry Wong <henry@stuffedcow.net>
667 Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
668
669*/
670
671static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
672
673/* ---- Remote Button Layout ----
674
675 POWER SOURCE SCAN MUTE
676 TV/FM 1 2 3
677 |> 4 5 6
678 <| 7 8 9
679 ^^UP 0 + RECALL
680 vvDN RECORD STOP PLAY
681
682 MINIMIZE ZOOM
683
684 CH+
685 VOL- VOL+
686 CH-
687
688 SNAPSHOT MTS
689
690 << FUNC >> RESET
691*/
692
693 { 0x01, KEY_1 }, /* 1 */
694 { 0x0b, KEY_2 }, /* 2 */
695 { 0x1b, KEY_3 }, /* 3 */
696 { 0x05, KEY_4 }, /* 4 */
697 { 0x09, KEY_5 }, /* 5 */
698 { 0x15, KEY_6 }, /* 6 */
699 { 0x06, KEY_7 }, /* 7 */
700 { 0x0a, KEY_8 }, /* 8 */
701 { 0x12, KEY_9 }, /* 9 */
702 { 0x02, KEY_0 }, /* 0 */
703 { 0x10, KEY_KPPLUS }, /* + */
704 { 0x13, KEY_AGAIN }, /* Recall */
705
706 { 0x1e, KEY_POWER }, /* Power */
707 { 0x07, KEY_TUNER }, /* Source */
708 { 0x1c, KEY_SEARCH }, /* Scan */
709 { 0x18, KEY_MUTE }, /* Mute */
710
711 { 0x03, KEY_RADIO }, /* TV/FM */
712 /* The next four keys are duplicates that appear to send the
713 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
714 to them is the actual code + 0x20 - they will never be
715 detected as such unless some way is discovered to distinguish
716 these buttons from those that have the same code. */
717 { 0x3f, KEY_RIGHT }, /* |> and Ch+ */
718 { 0x37, KEY_LEFT }, /* <| and Ch- */
719 { 0x2c, KEY_UP }, /* ^^Up and >> */
720 { 0x24, KEY_DOWN }, /* vvDn and << */
721
722 { 0x00, KEY_RECORD }, /* Record */
723 { 0x08, KEY_STOP }, /* Stop */
724 { 0x11, KEY_PLAY }, /* Play */
725
726 { 0x0f, KEY_CLOSE }, /* Minimize */
727 { 0x19, KEY_ZOOM }, /* Zoom */
728 { 0x1a, KEY_CAMERA }, /* Snapshot */
729 { 0x0d, KEY_LANGUAGE }, /* MTS */
730
731 { 0x14, KEY_VOLUMEDOWN }, /* Vol- */
732 { 0x16, KEY_VOLUMEUP }, /* Vol+ */
733 { 0x17, KEY_CHANNELDOWN }, /* Ch- */
734 { 0x1f, KEY_CHANNELUP }, /* Ch+ */
735
736 { 0x04, KEY_REWIND }, /* << */
737 { 0x0e, KEY_MENU }, /* Function */
738 { 0x0c, KEY_FASTFORWARD }, /* >> */
739 { 0x1d, KEY_RESTART }, /* Reset */
740};
741
742struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
743 .scan = ir_codes_msi_tvanywhere_plus,
744 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
745};
746EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
747
748/* ---------------------------------------------------------------------- */
749
750/* Cinergy 1400 DVB-T */
751static struct ir_scancode ir_codes_cinergy_1400[] = {
752 { 0x01, KEY_POWER },
753 { 0x02, KEY_1 },
754 { 0x03, KEY_2 },
755 { 0x04, KEY_3 },
756 { 0x05, KEY_4 },
757 { 0x06, KEY_5 },
758 { 0x07, KEY_6 },
759 { 0x08, KEY_7 },
760 { 0x09, KEY_8 },
761 { 0x0a, KEY_9 },
762 { 0x0c, KEY_0 },
763
764 { 0x0b, KEY_VIDEO },
765 { 0x0d, KEY_REFRESH },
766 { 0x0e, KEY_SELECT },
767 { 0x0f, KEY_EPG },
768 { 0x10, KEY_UP },
769 { 0x11, KEY_LEFT },
770 { 0x12, KEY_OK },
771 { 0x13, KEY_RIGHT },
772 { 0x14, KEY_DOWN },
773 { 0x15, KEY_TEXT },
774 { 0x16, KEY_INFO },
775
776 { 0x17, KEY_RED },
777 { 0x18, KEY_GREEN },
778 { 0x19, KEY_YELLOW },
779 { 0x1a, KEY_BLUE },
780
781 { 0x1b, KEY_CHANNELUP },
782 { 0x1c, KEY_VOLUMEUP },
783 { 0x1d, KEY_MUTE },
784 { 0x1e, KEY_VOLUMEDOWN },
785 { 0x1f, KEY_CHANNELDOWN },
786
787 { 0x40, KEY_PAUSE },
788 { 0x4c, KEY_PLAY },
789 { 0x58, KEY_RECORD },
790 { 0x54, KEY_PREVIOUS },
791 { 0x48, KEY_STOP },
792 { 0x5c, KEY_NEXT },
793};
794
795struct ir_scancode_table ir_codes_cinergy_1400_table = {
796 .scan = ir_codes_cinergy_1400,
797 .size = ARRAY_SIZE(ir_codes_cinergy_1400),
798};
799EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
800
801/* ---------------------------------------------------------------------- */
802
803/* AVERTV STUDIO 303 Remote */
804static struct ir_scancode ir_codes_avertv_303[] = {
805 { 0x2a, KEY_1 },
806 { 0x32, KEY_2 },
807 { 0x3a, KEY_3 },
808 { 0x4a, KEY_4 },
809 { 0x52, KEY_5 },
810 { 0x5a, KEY_6 },
811 { 0x6a, KEY_7 },
812 { 0x72, KEY_8 },
813 { 0x7a, KEY_9 },
814 { 0x0e, KEY_0 },
815
816 { 0x02, KEY_POWER },
817 { 0x22, KEY_VIDEO },
818 { 0x42, KEY_AUDIO },
819 { 0x62, KEY_ZOOM },
820 { 0x0a, KEY_TV },
821 { 0x12, KEY_CD },
822 { 0x1a, KEY_TEXT },
823
824 { 0x16, KEY_SUBTITLE },
825 { 0x1e, KEY_REWIND },
826 { 0x06, KEY_PRINT },
827
828 { 0x2e, KEY_SEARCH },
829 { 0x36, KEY_SLEEP },
830 { 0x3e, KEY_SHUFFLE },
831 { 0x26, KEY_MUTE },
832
833 { 0x4e, KEY_RECORD },
834 { 0x56, KEY_PAUSE },
835 { 0x5e, KEY_STOP },
836 { 0x46, KEY_PLAY },
837
838 { 0x6e, KEY_RED },
839 { 0x0b, KEY_GREEN },
840 { 0x66, KEY_YELLOW },
841 { 0x03, KEY_BLUE },
842
843 { 0x76, KEY_LEFT },
844 { 0x7e, KEY_RIGHT },
845 { 0x13, KEY_DOWN },
846 { 0x1b, KEY_UP },
847};
848
849struct ir_scancode_table ir_codes_avertv_303_table = {
850 .scan = ir_codes_avertv_303,
851 .size = ARRAY_SIZE(ir_codes_avertv_303),
852};
853EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
854
855/* ---------------------------------------------------------------------- */
856
857/* DigitalNow DNTV Live! DVB-T Pro Remote */
858static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
859 { 0x16, KEY_POWER },
860 { 0x5b, KEY_HOME },
861
862 { 0x55, KEY_TV }, /* live tv */
863 { 0x58, KEY_TUNER }, /* digital Radio */
864 { 0x5a, KEY_RADIO }, /* FM radio */
865 { 0x59, KEY_DVD }, /* dvd menu */
866 { 0x03, KEY_1 },
867 { 0x01, KEY_2 },
868 { 0x06, KEY_3 },
869 { 0x09, KEY_4 },
870 { 0x1d, KEY_5 },
871 { 0x1f, KEY_6 },
872 { 0x0d, KEY_7 },
873 { 0x19, KEY_8 },
874 { 0x1b, KEY_9 },
875 { 0x0c, KEY_CANCEL },
876 { 0x15, KEY_0 },
877 { 0x4a, KEY_CLEAR },
878 { 0x13, KEY_BACK },
879 { 0x00, KEY_TAB },
880 { 0x4b, KEY_UP },
881 { 0x4e, KEY_LEFT },
882 { 0x4f, KEY_OK },
883 { 0x52, KEY_RIGHT },
884 { 0x51, KEY_DOWN },
885 { 0x1e, KEY_VOLUMEUP },
886 { 0x0a, KEY_VOLUMEDOWN },
887 { 0x02, KEY_CHANNELDOWN },
888 { 0x05, KEY_CHANNELUP },
889 { 0x11, KEY_RECORD },
890 { 0x14, KEY_PLAY },
891 { 0x4c, KEY_PAUSE },
892 { 0x1a, KEY_STOP },
893 { 0x40, KEY_REWIND },
894 { 0x12, KEY_FASTFORWARD },
895 { 0x41, KEY_PREVIOUSSONG }, /* replay |< */
896 { 0x42, KEY_NEXTSONG }, /* skip >| */
897 { 0x54, KEY_CAMERA }, /* capture */
898 { 0x50, KEY_LANGUAGE }, /* sap */
899 { 0x47, KEY_TV2 }, /* pip */
900 { 0x4d, KEY_SCREEN },
901 { 0x43, KEY_SUBTITLE },
902 { 0x10, KEY_MUTE },
903 { 0x49, KEY_AUDIO }, /* l/r */
904 { 0x07, KEY_SLEEP },
905 { 0x08, KEY_VIDEO }, /* a/v */
906 { 0x0e, KEY_PREVIOUS }, /* recall */
907 { 0x45, KEY_ZOOM }, /* zoom + */
908 { 0x46, KEY_ANGLE }, /* zoom - */
909 { 0x56, KEY_RED },
910 { 0x57, KEY_GREEN },
911 { 0x5c, KEY_YELLOW },
912 { 0x5d, KEY_BLUE },
913};
914
915struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
916 .scan = ir_codes_dntv_live_dvbt_pro,
917 .size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
918};
919EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
920
921static struct ir_scancode ir_codes_em_terratec[] = {
922 { 0x01, KEY_CHANNEL },
923 { 0x02, KEY_SELECT },
924 { 0x03, KEY_MUTE },
925 { 0x04, KEY_POWER },
926 { 0x05, KEY_1 },
927 { 0x06, KEY_2 },
928 { 0x07, KEY_3 },
929 { 0x08, KEY_CHANNELUP },
930 { 0x09, KEY_4 },
931 { 0x0a, KEY_5 },
932 { 0x0b, KEY_6 },
933 { 0x0c, KEY_CHANNELDOWN },
934 { 0x0d, KEY_7 },
935 { 0x0e, KEY_8 },
936 { 0x0f, KEY_9 },
937 { 0x10, KEY_VOLUMEUP },
938 { 0x11, KEY_0 },
939 { 0x12, KEY_MENU },
940 { 0x13, KEY_PRINT },
941 { 0x14, KEY_VOLUMEDOWN },
942 { 0x16, KEY_PAUSE },
943 { 0x18, KEY_RECORD },
944 { 0x19, KEY_REWIND },
945 { 0x1a, KEY_PLAY },
946 { 0x1b, KEY_FORWARD },
947 { 0x1c, KEY_BACKSPACE },
948 { 0x1e, KEY_STOP },
949 { 0x40, KEY_ZOOM },
950};
951
952struct ir_scancode_table ir_codes_em_terratec_table = {
953 .scan = ir_codes_em_terratec,
954 .size = ARRAY_SIZE(ir_codes_em_terratec),
955};
956EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
957
958static struct ir_scancode ir_codes_pinnacle_grey[] = {
959 { 0x3a, KEY_0 },
960 { 0x31, KEY_1 },
961 { 0x32, KEY_2 },
962 { 0x33, KEY_3 },
963 { 0x34, KEY_4 },
964 { 0x35, KEY_5 },
965 { 0x36, KEY_6 },
966 { 0x37, KEY_7 },
967 { 0x38, KEY_8 },
968 { 0x39, KEY_9 },
969
970 { 0x2f, KEY_POWER },
971
972 { 0x2e, KEY_P },
973 { 0x1f, KEY_L },
974 { 0x2b, KEY_I },
975
976 { 0x2d, KEY_SCREEN },
977 { 0x1e, KEY_ZOOM },
978 { 0x1b, KEY_VOLUMEUP },
979 { 0x0f, KEY_VOLUMEDOWN },
980 { 0x17, KEY_CHANNELUP },
981 { 0x1c, KEY_CHANNELDOWN },
982 { 0x25, KEY_INFO },
983
984 { 0x3c, KEY_MUTE },
985
986 { 0x3d, KEY_LEFT },
987 { 0x3b, KEY_RIGHT },
988
989 { 0x3f, KEY_UP },
990 { 0x3e, KEY_DOWN },
991 { 0x1a, KEY_ENTER },
992
993 { 0x1d, KEY_MENU },
994 { 0x19, KEY_AGAIN },
995 { 0x16, KEY_PREVIOUSSONG },
996 { 0x13, KEY_NEXTSONG },
997 { 0x15, KEY_PAUSE },
998 { 0x0e, KEY_REWIND },
999 { 0x0d, KEY_PLAY },
1000 { 0x0b, KEY_STOP },
1001 { 0x07, KEY_FORWARD },
1002 { 0x27, KEY_RECORD },
1003 { 0x26, KEY_TUNER },
1004 { 0x29, KEY_TEXT },
1005 { 0x2a, KEY_MEDIA },
1006 { 0x18, KEY_EPG },
1007};
1008
1009struct ir_scancode_table ir_codes_pinnacle_grey_table = {
1010 .scan = ir_codes_pinnacle_grey,
1011 .size = ARRAY_SIZE(ir_codes_pinnacle_grey),
1012};
1013EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
1014
1015static struct ir_scancode ir_codes_flyvideo[] = {
1016 { 0x0f, KEY_0 },
1017 { 0x03, KEY_1 },
1018 { 0x04, KEY_2 },
1019 { 0x05, KEY_3 },
1020 { 0x07, KEY_4 },
1021 { 0x08, KEY_5 },
1022 { 0x09, KEY_6 },
1023 { 0x0b, KEY_7 },
1024 { 0x0c, KEY_8 },
1025 { 0x0d, KEY_9 },
1026
1027 { 0x0e, KEY_MODE }, /* Air/Cable */
1028 { 0x11, KEY_VIDEO }, /* Video */
1029 { 0x15, KEY_AUDIO }, /* Audio */
1030 { 0x00, KEY_POWER }, /* Power */
1031 { 0x18, KEY_TUNER }, /* AV Source */
1032 { 0x02, KEY_ZOOM }, /* Fullscreen */
1033 { 0x1a, KEY_LANGUAGE }, /* Stereo */
1034 { 0x1b, KEY_MUTE }, /* Mute */
1035 { 0x14, KEY_VOLUMEUP }, /* Volume + */
1036 { 0x17, KEY_VOLUMEDOWN },/* Volume - */
1037 { 0x12, KEY_CHANNELUP },/* Channel + */
1038 { 0x13, KEY_CHANNELDOWN },/* Channel - */
1039 { 0x06, KEY_AGAIN }, /* Recall */
1040 { 0x10, KEY_ENTER }, /* Enter */
1041
1042 { 0x19, KEY_BACK }, /* Rewind ( <<< ) */
1043 { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
1044 { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
1045};
1046
1047struct ir_scancode_table ir_codes_flyvideo_table = {
1048 .scan = ir_codes_flyvideo,
1049 .size = ARRAY_SIZE(ir_codes_flyvideo),
1050};
1051EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
1052
1053static struct ir_scancode ir_codes_flydvb[] = {
1054 { 0x01, KEY_ZOOM }, /* Full Screen */
1055 { 0x00, KEY_POWER }, /* Power */
1056
1057 { 0x03, KEY_1 },
1058 { 0x04, KEY_2 },
1059 { 0x05, KEY_3 },
1060 { 0x07, KEY_4 },
1061 { 0x08, KEY_5 },
1062 { 0x09, KEY_6 },
1063 { 0x0b, KEY_7 },
1064 { 0x0c, KEY_8 },
1065 { 0x0d, KEY_9 },
1066 { 0x06, KEY_AGAIN }, /* Recall */
1067 { 0x0f, KEY_0 },
1068 { 0x10, KEY_MUTE }, /* Mute */
1069 { 0x02, KEY_RADIO }, /* TV/Radio */
1070 { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
1071
1072 { 0x14, KEY_VOLUMEUP }, /* VOL+ */
1073 { 0x17, KEY_VOLUMEDOWN }, /* VOL- */
1074 { 0x12, KEY_CHANNELUP }, /* CH+ */
1075 { 0x13, KEY_CHANNELDOWN }, /* CH- */
1076 { 0x1d, KEY_ENTER }, /* Enter */
1077
1078 { 0x1a, KEY_MODE }, /* PIP */
1079 { 0x18, KEY_TUNER }, /* Source */
1080
1081 { 0x1e, KEY_RECORD }, /* Record/Pause */
1082 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
1083 { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
1084 { 0x19, KEY_BACK }, /* Rewind << */
1085 { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
1086 { 0x1f, KEY_FORWARD }, /* Forward >> */
1087 { 0x16, KEY_PREVIOUS }, /* Back |<< */
1088 { 0x11, KEY_STOP }, /* Stop */
1089 { 0x0e, KEY_NEXT }, /* End >>| */
1090};
1091
1092struct ir_scancode_table ir_codes_flydvb_table = {
1093 .scan = ir_codes_flydvb,
1094 .size = ARRAY_SIZE(ir_codes_flydvb),
1095};
1096EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
1097
1098static struct ir_scancode ir_codes_cinergy[] = {
1099 { 0x00, KEY_0 },
1100 { 0x01, KEY_1 },
1101 { 0x02, KEY_2 },
1102 { 0x03, KEY_3 },
1103 { 0x04, KEY_4 },
1104 { 0x05, KEY_5 },
1105 { 0x06, KEY_6 },
1106 { 0x07, KEY_7 },
1107 { 0x08, KEY_8 },
1108 { 0x09, KEY_9 },
1109
1110 { 0x0a, KEY_POWER },
1111 { 0x0b, KEY_PROG1 }, /* app */
1112 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
1113 { 0x0d, KEY_CHANNELUP }, /* channel */
1114 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
1115 { 0x0f, KEY_VOLUMEUP },
1116 { 0x10, KEY_VOLUMEDOWN },
1117 { 0x11, KEY_TUNER }, /* AV */
1118 { 0x12, KEY_NUMLOCK }, /* -/-- */
1119 { 0x13, KEY_AUDIO }, /* audio */
1120 { 0x14, KEY_MUTE },
1121 { 0x15, KEY_UP },
1122 { 0x16, KEY_DOWN },
1123 { 0x17, KEY_LEFT },
1124 { 0x18, KEY_RIGHT },
1125 { 0x19, BTN_LEFT, },
1126 { 0x1a, BTN_RIGHT, },
1127 { 0x1b, KEY_WWW }, /* text */
1128 { 0x1c, KEY_REWIND },
1129 { 0x1d, KEY_FORWARD },
1130 { 0x1e, KEY_RECORD },
1131 { 0x1f, KEY_PLAY },
1132 { 0x20, KEY_PREVIOUSSONG },
1133 { 0x21, KEY_NEXTSONG },
1134 { 0x22, KEY_PAUSE },
1135 { 0x23, KEY_STOP },
1136};
1137
1138struct ir_scancode_table ir_codes_cinergy_table = {
1139 .scan = ir_codes_cinergy,
1140 .size = ARRAY_SIZE(ir_codes_cinergy),
1141};
1142EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
1143
1144/* Alfons Geser <a.geser@cox.net>
1145 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
1146static struct ir_scancode ir_codes_eztv[] = {
1147 { 0x12, KEY_POWER },
1148 { 0x01, KEY_TV }, /* DVR */
1149 { 0x15, KEY_DVD }, /* DVD */
1150 { 0x17, KEY_AUDIO }, /* music */
1151 /* DVR mode / DVD mode / music mode */
1152
1153 { 0x1b, KEY_MUTE }, /* mute */
1154 { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
1155 { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
1156 { 0x16, KEY_ZOOM }, /* full screen */
1157 { 0x1c, KEY_VIDEO }, /* video source / eject / delall */
1158 { 0x1d, KEY_RESTART }, /* playback / angle / del */
1159 { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
1160 { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
1161
1162 { 0x31, KEY_HELP }, /* help */
1163 { 0x32, KEY_MODE }, /* num/memo */
1164 { 0x33, KEY_ESC }, /* cancel */
1165
1166 { 0x0c, KEY_UP }, /* up */
1167 { 0x10, KEY_DOWN }, /* down */
1168 { 0x08, KEY_LEFT }, /* left */
1169 { 0x04, KEY_RIGHT }, /* right */
1170 { 0x03, KEY_SELECT }, /* select */
1171
1172 { 0x1f, KEY_REWIND }, /* rewind */
1173 { 0x20, KEY_PLAYPAUSE },/* play/pause */
1174 { 0x29, KEY_FORWARD }, /* forward */
1175 { 0x14, KEY_AGAIN }, /* repeat */
1176 { 0x2b, KEY_RECORD }, /* recording */
1177 { 0x2c, KEY_STOP }, /* stop */
1178 { 0x2d, KEY_PLAY }, /* play */
1179 { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
1180
1181 { 0x00, KEY_0 },
1182 { 0x05, KEY_1 },
1183 { 0x06, KEY_2 },
1184 { 0x07, KEY_3 },
1185 { 0x09, KEY_4 },
1186 { 0x0a, KEY_5 },
1187 { 0x0b, KEY_6 },
1188 { 0x0d, KEY_7 },
1189 { 0x0e, KEY_8 },
1190 { 0x0f, KEY_9 },
1191
1192 { 0x2a, KEY_VOLUMEUP },
1193 { 0x11, KEY_VOLUMEDOWN },
1194 { 0x18, KEY_CHANNELUP },/* CH.tracking up */
1195 { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
1196
1197 { 0x13, KEY_ENTER }, /* enter */
1198 { 0x21, KEY_DOT }, /* . (decimal dot) */
1199};
1200
1201struct ir_scancode_table ir_codes_eztv_table = {
1202 .scan = ir_codes_eztv,
1203 .size = ARRAY_SIZE(ir_codes_eztv),
1204};
1205EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
1206
1207/* Alex Hermann <gaaf@gmx.net> */
1208static struct ir_scancode ir_codes_avermedia[] = {
1209 { 0x28, KEY_1 },
1210 { 0x18, KEY_2 },
1211 { 0x38, KEY_3 },
1212 { 0x24, KEY_4 },
1213 { 0x14, KEY_5 },
1214 { 0x34, KEY_6 },
1215 { 0x2c, KEY_7 },
1216 { 0x1c, KEY_8 },
1217 { 0x3c, KEY_9 },
1218 { 0x22, KEY_0 },
1219
1220 { 0x20, KEY_TV }, /* TV/FM */
1221 { 0x10, KEY_CD }, /* CD */
1222 { 0x30, KEY_TEXT }, /* TELETEXT */
1223 { 0x00, KEY_POWER }, /* POWER */
1224
1225 { 0x08, KEY_VIDEO }, /* VIDEO */
1226 { 0x04, KEY_AUDIO }, /* AUDIO */
1227 { 0x0c, KEY_ZOOM }, /* FULL SCREEN */
1228
1229 { 0x12, KEY_SUBTITLE }, /* DISPLAY */
1230 { 0x32, KEY_REWIND }, /* LOOP */
1231 { 0x02, KEY_PRINT }, /* PREVIEW */
1232
1233 { 0x2a, KEY_SEARCH }, /* AUTOSCAN */
1234 { 0x1a, KEY_SLEEP }, /* FREEZE */
1235 { 0x3a, KEY_CAMERA }, /* SNAPSHOT */
1236 { 0x0a, KEY_MUTE }, /* MUTE */
1237
1238 { 0x26, KEY_RECORD }, /* RECORD */
1239 { 0x16, KEY_PAUSE }, /* PAUSE */
1240 { 0x36, KEY_STOP }, /* STOP */
1241 { 0x06, KEY_PLAY }, /* PLAY */
1242
1243 { 0x2e, KEY_RED }, /* RED */
1244 { 0x21, KEY_GREEN }, /* GREEN */
1245 { 0x0e, KEY_YELLOW }, /* YELLOW */
1246 { 0x01, KEY_BLUE }, /* BLUE */
1247
1248 { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
1249 { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
1250 { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
1251 { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
1252};
1253
1254struct ir_scancode_table ir_codes_avermedia_table = {
1255 .scan = ir_codes_avermedia,
1256 .size = ARRAY_SIZE(ir_codes_avermedia),
1257};
1258EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
1259
1260static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
1261 { 0x14, KEY_MUTE },
1262 { 0x24, KEY_ZOOM },
1263
1264 { 0x01, KEY_DVD },
1265 { 0x23, KEY_RADIO },
1266 { 0x00, KEY_TV },
1267
1268 { 0x0a, KEY_REWIND },
1269 { 0x08, KEY_PLAYPAUSE },
1270 { 0x0f, KEY_FORWARD },
1271
1272 { 0x02, KEY_PREVIOUS },
1273 { 0x07, KEY_STOP },
1274 { 0x06, KEY_NEXT },
1275
1276 { 0x0c, KEY_UP },
1277 { 0x0e, KEY_DOWN },
1278 { 0x0b, KEY_LEFT },
1279 { 0x0d, KEY_RIGHT },
1280 { 0x11, KEY_OK },
1281
1282 { 0x03, KEY_MENU },
1283 { 0x09, KEY_SETUP },
1284 { 0x05, KEY_VIDEO },
1285 { 0x22, KEY_CHANNEL },
1286
1287 { 0x12, KEY_VOLUMEUP },
1288 { 0x15, KEY_VOLUMEDOWN },
1289 { 0x10, KEY_CHANNELUP },
1290 { 0x13, KEY_CHANNELDOWN },
1291
1292 { 0x04, KEY_RECORD },
1293
1294 { 0x16, KEY_1 },
1295 { 0x17, KEY_2 },
1296 { 0x18, KEY_3 },
1297 { 0x19, KEY_4 },
1298 { 0x1a, KEY_5 },
1299 { 0x1b, KEY_6 },
1300 { 0x1c, KEY_7 },
1301 { 0x1d, KEY_8 },
1302 { 0x1e, KEY_9 },
1303 { 0x1f, KEY_0 },
1304
1305 { 0x20, KEY_LANGUAGE },
1306 { 0x21, KEY_SLEEP },
1307};
1308
1309struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
1310 .scan = ir_codes_videomate_tv_pvr,
1311 .size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
1312};
1313EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
1314
1315/* Michael Tokarev <mjt@tls.msk.ru>
1316 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
1317 keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
1318 least, and probably other cards too.
1319 The "ascii-art picture" below (in comments, first row
1320 is the keycode in hex, and subsequent row(s) shows
1321 the button labels (several variants when appropriate)
1322 helps to descide which keycodes to assign to the buttons.
1323 */
1324static struct ir_scancode ir_codes_manli[] = {
1325
1326 /* 0x1c 0x12 *
1327 * FUNCTION POWER *
1328 * FM (|) *
1329 * */
1330 { 0x1c, KEY_RADIO }, /*XXX*/
1331 { 0x12, KEY_POWER },
1332
1333 /* 0x01 0x02 0x03 *
1334 * 1 2 3 *
1335 * *
1336 * 0x04 0x05 0x06 *
1337 * 4 5 6 *
1338 * *
1339 * 0x07 0x08 0x09 *
1340 * 7 8 9 *
1341 * */
1342 { 0x01, KEY_1 },
1343 { 0x02, KEY_2 },
1344 { 0x03, KEY_3 },
1345 { 0x04, KEY_4 },
1346 { 0x05, KEY_5 },
1347 { 0x06, KEY_6 },
1348 { 0x07, KEY_7 },
1349 { 0x08, KEY_8 },
1350 { 0x09, KEY_9 },
1351
1352 /* 0x0a 0x00 0x17 *
1353 * RECALL 0 +100 *
1354 * PLUS *
1355 * */
1356 { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
1357 { 0x00, KEY_0 },
1358 { 0x17, KEY_DIGITS }, /*XXX*/
1359
1360 /* 0x14 0x10 *
1361 * MENU INFO *
1362 * OSD */
1363 { 0x14, KEY_MENU },
1364 { 0x10, KEY_INFO },
1365
1366 /* 0x0b *
1367 * Up *
1368 * *
1369 * 0x18 0x16 0x0c *
1370 * Left Ok Right *
1371 * *
1372 * 0x015 *
1373 * Down *
1374 * */
1375 { 0x0b, KEY_UP },
1376 { 0x18, KEY_LEFT },
1377 { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
1378 { 0x0c, KEY_RIGHT },
1379 { 0x15, KEY_DOWN },
1380
1381 /* 0x11 0x0d *
1382 * TV/AV MODE *
1383 * SOURCE STEREO *
1384 * */
1385 { 0x11, KEY_TV }, /*XXX*/
1386 { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
1387
1388 /* 0x0f 0x1b 0x1a *
1389 * AUDIO Vol+ Chan+ *
1390 * TIMESHIFT??? *
1391 * *
1392 * 0x0e 0x1f 0x1e *
1393 * SLEEP Vol- Chan- *
1394 * */
1395 { 0x0f, KEY_AUDIO },
1396 { 0x1b, KEY_VOLUMEUP },
1397 { 0x1a, KEY_CHANNELUP },
1398 { 0x0e, KEY_TIME },
1399 { 0x1f, KEY_VOLUMEDOWN },
1400 { 0x1e, KEY_CHANNELDOWN },
1401
1402 /* 0x13 0x19 *
1403 * MUTE SNAPSHOT*
1404 * */
1405 { 0x13, KEY_MUTE },
1406 { 0x19, KEY_CAMERA },
1407
1408 /* 0x1d unused ? */
1409};
1410
1411struct ir_scancode_table ir_codes_manli_table = {
1412 .scan = ir_codes_manli,
1413 .size = ARRAY_SIZE(ir_codes_manli),
1414};
1415EXPORT_SYMBOL_GPL(ir_codes_manli_table);
1416
1417/* Mike Baikov <mike@baikov.com> */
1418static struct ir_scancode ir_codes_gotview7135[] = {
1419
1420 { 0x11, KEY_POWER },
1421 { 0x35, KEY_TV },
1422 { 0x1b, KEY_0 },
1423 { 0x29, KEY_1 },
1424 { 0x19, KEY_2 },
1425 { 0x39, KEY_3 },
1426 { 0x1f, KEY_4 },
1427 { 0x2c, KEY_5 },
1428 { 0x21, KEY_6 },
1429 { 0x24, KEY_7 },
1430 { 0x18, KEY_8 },
1431 { 0x2b, KEY_9 },
1432 { 0x3b, KEY_AGAIN }, /* LOOP */
1433 { 0x06, KEY_AUDIO },
1434 { 0x31, KEY_PRINT }, /* PREVIEW */
1435 { 0x3e, KEY_VIDEO },
1436 { 0x10, KEY_CHANNELUP },
1437 { 0x20, KEY_CHANNELDOWN },
1438 { 0x0c, KEY_VOLUMEDOWN },
1439 { 0x28, KEY_VOLUMEUP },
1440 { 0x08, KEY_MUTE },
1441 { 0x26, KEY_SEARCH }, /* SCAN */
1442 { 0x3f, KEY_CAMERA }, /* SNAPSHOT */
1443 { 0x12, KEY_RECORD },
1444 { 0x32, KEY_STOP },
1445 { 0x3c, KEY_PLAY },
1446 { 0x1d, KEY_REWIND },
1447 { 0x2d, KEY_PAUSE },
1448 { 0x0d, KEY_FORWARD },
1449 { 0x05, KEY_ZOOM }, /*FULL*/
1450
1451 { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
1452 { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
1453 { 0x1e, KEY_TIME }, /* TIMESHIFT */
1454 { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
1455};
1456
1457struct ir_scancode_table ir_codes_gotview7135_table = {
1458 .scan = ir_codes_gotview7135,
1459 .size = ARRAY_SIZE(ir_codes_gotview7135),
1460};
1461EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
1462
1463static struct ir_scancode ir_codes_purpletv[] = {
1464 { 0x03, KEY_POWER },
1465 { 0x6f, KEY_MUTE },
1466 { 0x10, KEY_BACKSPACE }, /* Recall */
1467
1468 { 0x11, KEY_0 },
1469 { 0x04, KEY_1 },
1470 { 0x05, KEY_2 },
1471 { 0x06, KEY_3 },
1472 { 0x08, KEY_4 },
1473 { 0x09, KEY_5 },
1474 { 0x0a, KEY_6 },
1475 { 0x0c, KEY_7 },
1476 { 0x0d, KEY_8 },
1477 { 0x0e, KEY_9 },
1478 { 0x12, KEY_DOT }, /* 100+ */
1479
1480 { 0x07, KEY_VOLUMEUP },
1481 { 0x0b, KEY_VOLUMEDOWN },
1482 { 0x1a, KEY_KPPLUS },
1483 { 0x18, KEY_KPMINUS },
1484 { 0x15, KEY_UP },
1485 { 0x1d, KEY_DOWN },
1486 { 0x0f, KEY_CHANNELUP },
1487 { 0x13, KEY_CHANNELDOWN },
1488 { 0x48, KEY_ZOOM },
1489
1490 { 0x1b, KEY_VIDEO }, /* Video source */
1491 { 0x1f, KEY_CAMERA }, /* Snapshot */
1492 { 0x49, KEY_LANGUAGE }, /* MTS Select */
1493 { 0x19, KEY_SEARCH }, /* Auto Scan */
1494
1495 { 0x4b, KEY_RECORD },
1496 { 0x46, KEY_PLAY },
1497 { 0x45, KEY_PAUSE }, /* Pause */
1498 { 0x44, KEY_STOP },
1499 { 0x43, KEY_TIME }, /* Time Shift */
1500 { 0x17, KEY_CHANNEL }, /* SURF CH */
1501 { 0x40, KEY_FORWARD }, /* Forward ? */
1502 { 0x42, KEY_REWIND }, /* Backward ? */
1503
1504};
1505
1506struct ir_scancode_table ir_codes_purpletv_table = {
1507 .scan = ir_codes_purpletv,
1508 .size = ARRAY_SIZE(ir_codes_purpletv),
1509};
1510EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
1511
1512/* Mapping for the 28 key remote control as seen at
1513 http://www.sednacomputer.com/photo/cardbus-tv.jpg
1514 Pavel Mihaylov <bin@bash.info>
1515 Also for the remote bundled with Kozumi KTV-01C card */
1516static struct ir_scancode ir_codes_pctv_sedna[] = {
1517 { 0x00, KEY_0 },
1518 { 0x01, KEY_1 },
1519 { 0x02, KEY_2 },
1520 { 0x03, KEY_3 },
1521 { 0x04, KEY_4 },
1522 { 0x05, KEY_5 },
1523 { 0x06, KEY_6 },
1524 { 0x07, KEY_7 },
1525 { 0x08, KEY_8 },
1526 { 0x09, KEY_9 },
1527
1528 { 0x0a, KEY_AGAIN }, /* Recall */
1529 { 0x0b, KEY_CHANNELUP },
1530 { 0x0c, KEY_VOLUMEUP },
1531 { 0x0d, KEY_MODE }, /* Stereo */
1532 { 0x0e, KEY_STOP },
1533 { 0x0f, KEY_PREVIOUSSONG },
1534 { 0x10, KEY_ZOOM },
1535 { 0x11, KEY_TUNER }, /* Source */
1536 { 0x12, KEY_POWER },
1537 { 0x13, KEY_MUTE },
1538 { 0x15, KEY_CHANNELDOWN },
1539 { 0x18, KEY_VOLUMEDOWN },
1540 { 0x19, KEY_CAMERA }, /* Snapshot */
1541 { 0x1a, KEY_NEXTSONG },
1542 { 0x1b, KEY_TIME }, /* Time Shift */
1543 { 0x1c, KEY_RADIO }, /* FM Radio */
1544 { 0x1d, KEY_RECORD },
1545 { 0x1e, KEY_PAUSE },
1546 /* additional codes for Kozumi's remote */
1547 { 0x14, KEY_INFO }, /* OSD */
1548 { 0x16, KEY_OK }, /* OK */
1549 { 0x17, KEY_DIGITS }, /* Plus */
1550 { 0x1f, KEY_PLAY }, /* Play */
1551};
1552
1553struct ir_scancode_table ir_codes_pctv_sedna_table = {
1554 .scan = ir_codes_pctv_sedna,
1555 .size = ARRAY_SIZE(ir_codes_pctv_sedna),
1556};
1557EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
1558
1559/* Mark Phalan <phalanm@o2.ie> */
1560static struct ir_scancode ir_codes_pv951[] = {
1561 { 0x00, KEY_0 },
1562 { 0x01, KEY_1 },
1563 { 0x02, KEY_2 },
1564 { 0x03, KEY_3 },
1565 { 0x04, KEY_4 },
1566 { 0x05, KEY_5 },
1567 { 0x06, KEY_6 },
1568 { 0x07, KEY_7 },
1569 { 0x08, KEY_8 },
1570 { 0x09, KEY_9 },
1571
1572 { 0x12, KEY_POWER },
1573 { 0x10, KEY_MUTE },
1574 { 0x1f, KEY_VOLUMEDOWN },
1575 { 0x1b, KEY_VOLUMEUP },
1576 { 0x1a, KEY_CHANNELUP },
1577 { 0x1e, KEY_CHANNELDOWN },
1578 { 0x0e, KEY_PAGEUP },
1579 { 0x1d, KEY_PAGEDOWN },
1580 { 0x13, KEY_SOUND },
1581
1582 { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */
1583 { 0x16, KEY_SUBTITLE }, /* CC */
1584 { 0x0d, KEY_TEXT }, /* TTX */
1585 { 0x0b, KEY_TV }, /* AIR/CBL */
1586 { 0x11, KEY_PC }, /* PC/TV */
1587 { 0x17, KEY_OK }, /* CH RTN */
1588 { 0x19, KEY_MODE }, /* FUNC */
1589 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
1590
1591 /* Not sure what to do with these ones! */
1592 { 0x0f, KEY_SELECT }, /* SOURCE */
1593 { 0x0a, KEY_KPPLUS }, /* +100 */
1594 { 0x14, KEY_EQUAL }, /* SYNC */
1595 { 0x1c, KEY_MEDIA }, /* PC/TV */
1596};
1597
1598struct ir_scancode_table ir_codes_pv951_table = {
1599 .scan = ir_codes_pv951,
1600 .size = ARRAY_SIZE(ir_codes_pv951),
1601};
1602EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
1603
1604/* generic RC5 keytable */
1605/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
1606/* used by old (black) Hauppauge remotes */
1607static struct ir_scancode ir_codes_rc5_tv[] = {
1608 /* Keys 0 to 9 */
1609 { 0x00, KEY_0 },
1610 { 0x01, KEY_1 },
1611 { 0x02, KEY_2 },
1612 { 0x03, KEY_3 },
1613 { 0x04, KEY_4 },
1614 { 0x05, KEY_5 },
1615 { 0x06, KEY_6 },
1616 { 0x07, KEY_7 },
1617 { 0x08, KEY_8 },
1618 { 0x09, KEY_9 },
1619
1620 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
1621 { 0x0c, KEY_POWER }, /* standby */
1622 { 0x0d, KEY_MUTE }, /* mute / demute */
1623 { 0x0f, KEY_TV }, /* display */
1624 { 0x10, KEY_VOLUMEUP },
1625 { 0x11, KEY_VOLUMEDOWN },
1626 { 0x12, KEY_BRIGHTNESSUP },
1627 { 0x13, KEY_BRIGHTNESSDOWN },
1628 { 0x1e, KEY_SEARCH }, /* search + */
1629 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1630 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1631 { 0x22, KEY_CHANNEL }, /* alt / channel */
1632 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
1633 { 0x26, KEY_SLEEP }, /* sleeptimer */
1634 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
1635 { 0x30, KEY_PAUSE },
1636 { 0x32, KEY_REWIND },
1637 { 0x33, KEY_GOTO },
1638 { 0x35, KEY_PLAY },
1639 { 0x36, KEY_STOP },
1640 { 0x37, KEY_RECORD }, /* recording */
1641 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
1642 { 0x3d, KEY_SUSPEND }, /* system standby */
1643
1644};
1645
1646struct ir_scancode_table ir_codes_rc5_tv_table = {
1647 .scan = ir_codes_rc5_tv,
1648 .size = ARRAY_SIZE(ir_codes_rc5_tv),
1649};
1650EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
1651
1652/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
1653static struct ir_scancode ir_codes_winfast[] = {
1654 /* Keys 0 to 9 */
1655 { 0x12, KEY_0 },
1656 { 0x05, KEY_1 },
1657 { 0x06, KEY_2 },
1658 { 0x07, KEY_3 },
1659 { 0x09, KEY_4 },
1660 { 0x0a, KEY_5 },
1661 { 0x0b, KEY_6 },
1662 { 0x0d, KEY_7 },
1663 { 0x0e, KEY_8 },
1664 { 0x0f, KEY_9 },
1665
1666 { 0x00, KEY_POWER },
1667 { 0x1b, KEY_AUDIO }, /* Audio Source */
1668 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
1669 { 0x1e, KEY_VIDEO }, /* Video Source */
1670 { 0x16, KEY_INFO }, /* Display information */
1671 { 0x04, KEY_VOLUMEUP },
1672 { 0x08, KEY_VOLUMEDOWN },
1673 { 0x0c, KEY_CHANNELUP },
1674 { 0x10, KEY_CHANNELDOWN },
1675 { 0x03, KEY_ZOOM }, /* fullscreen */
1676 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
1677 { 0x20, KEY_SLEEP },
1678 { 0x29, KEY_CLEAR }, /* boss key */
1679 { 0x14, KEY_MUTE },
1680 { 0x2b, KEY_RED },
1681 { 0x2c, KEY_GREEN },
1682 { 0x2d, KEY_YELLOW },
1683 { 0x2e, KEY_BLUE },
1684 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
1685 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
1686 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
1687 { 0x21, KEY_DOT },
1688 { 0x13, KEY_ENTER },
1689 { 0x11, KEY_LAST }, /* Recall (last channel */
1690 { 0x22, KEY_PREVIOUS },
1691 { 0x23, KEY_PLAYPAUSE },
1692 { 0x24, KEY_NEXT },
1693 { 0x25, KEY_TIME }, /* Time Shifting */
1694 { 0x26, KEY_STOP },
1695 { 0x27, KEY_RECORD },
1696 { 0x28, KEY_SAVE }, /* Screenshot */
1697 { 0x2f, KEY_MENU },
1698 { 0x30, KEY_CANCEL },
1699 { 0x31, KEY_CHANNEL }, /* Channel Surf */
1700 { 0x32, KEY_SUBTITLE },
1701 { 0x33, KEY_LANGUAGE },
1702 { 0x34, KEY_REWIND },
1703 { 0x35, KEY_FASTFORWARD },
1704 { 0x36, KEY_TV },
1705 { 0x37, KEY_RADIO }, /* FM */
1706 { 0x38, KEY_DVD },
1707
1708 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
1709 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
1710 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
1711 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
1712 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
1713};
1714
1715struct ir_scancode_table ir_codes_winfast_table = {
1716 .scan = ir_codes_winfast,
1717 .size = ARRAY_SIZE(ir_codes_winfast),
1718};
1719EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
1720
1721static struct ir_scancode ir_codes_pinnacle_color[] = {
1722 { 0x59, KEY_MUTE },
1723 { 0x4a, KEY_POWER },
1724
1725 { 0x18, KEY_TEXT },
1726 { 0x26, KEY_TV },
1727 { 0x3d, KEY_PRINT },
1728
1729 { 0x48, KEY_RED },
1730 { 0x04, KEY_GREEN },
1731 { 0x11, KEY_YELLOW },
1732 { 0x00, KEY_BLUE },
1733
1734 { 0x2d, KEY_VOLUMEUP },
1735 { 0x1e, KEY_VOLUMEDOWN },
1736
1737 { 0x49, KEY_MENU },
1738
1739 { 0x16, KEY_CHANNELUP },
1740 { 0x17, KEY_CHANNELDOWN },
1741
1742 { 0x20, KEY_UP },
1743 { 0x21, KEY_DOWN },
1744 { 0x22, KEY_LEFT },
1745 { 0x23, KEY_RIGHT },
1746 { 0x0d, KEY_SELECT },
1747
1748 { 0x08, KEY_BACK },
1749 { 0x07, KEY_REFRESH },
1750
1751 { 0x2f, KEY_ZOOM },
1752 { 0x29, KEY_RECORD },
1753
1754 { 0x4b, KEY_PAUSE },
1755 { 0x4d, KEY_REWIND },
1756 { 0x2e, KEY_PLAY },
1757 { 0x4e, KEY_FORWARD },
1758 { 0x53, KEY_PREVIOUS },
1759 { 0x4c, KEY_STOP },
1760 { 0x54, KEY_NEXT },
1761
1762 { 0x69, KEY_0 },
1763 { 0x6a, KEY_1 },
1764 { 0x6b, KEY_2 },
1765 { 0x6c, KEY_3 },
1766 { 0x6d, KEY_4 },
1767 { 0x6e, KEY_5 },
1768 { 0x6f, KEY_6 },
1769 { 0x70, KEY_7 },
1770 { 0x71, KEY_8 },
1771 { 0x72, KEY_9 },
1772
1773 { 0x74, KEY_CHANNEL },
1774 { 0x0a, KEY_BACKSPACE },
1775};
1776
1777struct ir_scancode_table ir_codes_pinnacle_color_table = {
1778 .scan = ir_codes_pinnacle_color,
1779 .size = ARRAY_SIZE(ir_codes_pinnacle_color),
1780};
1781EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
1782
1783/* Hauppauge: the newer, gray remotes (seems there are multiple
1784 * slightly different versions), shipped with cx88+ivtv cards.
1785 * almost rc5 coding, but some non-standard keys */
1786static struct ir_scancode ir_codes_hauppauge_new[] = {
1787 /* Keys 0 to 9 */
1788 { 0x00, KEY_0 },
1789 { 0x01, KEY_1 },
1790 { 0x02, KEY_2 },
1791 { 0x03, KEY_3 },
1792 { 0x04, KEY_4 },
1793 { 0x05, KEY_5 },
1794 { 0x06, KEY_6 },
1795 { 0x07, KEY_7 },
1796 { 0x08, KEY_8 },
1797 { 0x09, KEY_9 },
1798
1799 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
1800 { 0x0b, KEY_RED }, /* red button */
1801 { 0x0c, KEY_RADIO },
1802 { 0x0d, KEY_MENU },
1803 { 0x0e, KEY_SUBTITLE }, /* also the # key */
1804 { 0x0f, KEY_MUTE },
1805 { 0x10, KEY_VOLUMEUP },
1806 { 0x11, KEY_VOLUMEDOWN },
1807 { 0x12, KEY_PREVIOUS }, /* previous channel */
1808 { 0x14, KEY_UP },
1809 { 0x15, KEY_DOWN },
1810 { 0x16, KEY_LEFT },
1811 { 0x17, KEY_RIGHT },
1812 { 0x18, KEY_VIDEO }, /* Videos */
1813 { 0x19, KEY_AUDIO }, /* Music */
1814 /* 0x1a: Pictures - presume this means
1815 "Multimedia Home Platform" -
1816 no "PICTURES" key in input.h
1817 */
1818 { 0x1a, KEY_MHP },
1819
1820 { 0x1b, KEY_EPG }, /* Guide */
1821 { 0x1c, KEY_TV },
1822 { 0x1e, KEY_NEXTSONG }, /* skip >| */
1823 { 0x1f, KEY_EXIT }, /* back/exit */
1824 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1825 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1826 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
1827 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
1828 { 0x25, KEY_ENTER }, /* OK */
1829 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
1830 { 0x29, KEY_BLUE }, /* blue key */
1831 { 0x2e, KEY_GREEN }, /* green button */
1832 { 0x30, KEY_PAUSE }, /* pause */
1833 { 0x32, KEY_REWIND }, /* backward << */
1834 { 0x34, KEY_FASTFORWARD }, /* forward >> */
1835 { 0x35, KEY_PLAY },
1836 { 0x36, KEY_STOP },
1837 { 0x37, KEY_RECORD }, /* recording */
1838 { 0x38, KEY_YELLOW }, /* yellow key */
1839 { 0x3b, KEY_SELECT }, /* top right button */
1840 { 0x3c, KEY_ZOOM }, /* full */
1841 { 0x3d, KEY_POWER }, /* system power (green button) */
1842};
1843
1844struct ir_scancode_table ir_codes_hauppauge_new_table = {
1845 .scan = ir_codes_hauppauge_new,
1846 .size = ARRAY_SIZE(ir_codes_hauppauge_new),
1847};
1848EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
1849
1850static struct ir_scancode ir_codes_npgtech[] = {
1851 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
1852 { 0x2a, KEY_FRONT },
1853
1854 { 0x3e, KEY_1 },
1855 { 0x02, KEY_2 },
1856 { 0x06, KEY_3 },
1857 { 0x0a, KEY_4 },
1858 { 0x0e, KEY_5 },
1859 { 0x12, KEY_6 },
1860 { 0x16, KEY_7 },
1861 { 0x1a, KEY_8 },
1862 { 0x1e, KEY_9 },
1863 { 0x3a, KEY_0 },
1864 { 0x22, KEY_NUMLOCK }, /* -/-- */
1865 { 0x20, KEY_REFRESH },
1866
1867 { 0x03, KEY_BRIGHTNESSDOWN },
1868 { 0x28, KEY_AUDIO },
1869 { 0x3c, KEY_CHANNELUP },
1870 { 0x3f, KEY_VOLUMEDOWN },
1871 { 0x2e, KEY_MUTE },
1872 { 0x3b, KEY_VOLUMEUP },
1873 { 0x00, KEY_CHANNELDOWN },
1874 { 0x07, KEY_BRIGHTNESSUP },
1875 { 0x2c, KEY_TEXT },
1876
1877 { 0x37, KEY_RECORD },
1878 { 0x17, KEY_PLAY },
1879 { 0x13, KEY_PAUSE },
1880 { 0x26, KEY_STOP },
1881 { 0x18, KEY_FASTFORWARD },
1882 { 0x14, KEY_REWIND },
1883 { 0x33, KEY_ZOOM },
1884 { 0x32, KEY_KEYBOARD },
1885 { 0x30, KEY_GOTO }, /* Pointing arrow */
1886 { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */
1887 { 0x0b, KEY_RADIO },
1888 { 0x10, KEY_POWER },
1889
1890};
1891
1892struct ir_scancode_table ir_codes_npgtech_table = {
1893 .scan = ir_codes_npgtech,
1894 .size = ARRAY_SIZE(ir_codes_npgtech),
1895};
1896EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
1897
1898/* Norwood Micro (non-Pro) TV Tuner
1899 By Peter Naulls <peter@chocky.org>
1900 Key comments are the functions given in the manual */
1901static struct ir_scancode ir_codes_norwood[] = {
1902 /* Keys 0 to 9 */
1903 { 0x20, KEY_0 },
1904 { 0x21, KEY_1 },
1905 { 0x22, KEY_2 },
1906 { 0x23, KEY_3 },
1907 { 0x24, KEY_4 },
1908 { 0x25, KEY_5 },
1909 { 0x26, KEY_6 },
1910 { 0x27, KEY_7 },
1911 { 0x28, KEY_8 },
1912 { 0x29, KEY_9 },
1913
1914 { 0x78, KEY_TUNER }, /* Video Source */
1915 { 0x2c, KEY_EXIT }, /* Open/Close software */
1916 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
1917 { 0x69, KEY_AGAIN }, /* Recall */
1918
1919 { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */
1920 { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */
1921 { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */
1922 { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */
1923
1924 { 0x2d, KEY_MUTE }, /* Mute */
1925 { 0x30, KEY_VOLUMEUP }, /* Volume up */
1926 { 0x31, KEY_VOLUMEDOWN }, /* Volume down */
1927 { 0x60, KEY_CHANNELUP }, /* Channel up */
1928 { 0x61, KEY_CHANNELDOWN }, /* Channel down */
1929
1930 { 0x3f, KEY_RECORD }, /* Record */
1931 { 0x37, KEY_PLAY }, /* Play */
1932 { 0x36, KEY_PAUSE }, /* Pause */
1933 { 0x2b, KEY_STOP }, /* Stop */
1934 { 0x67, KEY_FASTFORWARD }, /* Foward */
1935 { 0x66, KEY_REWIND }, /* Rewind */
1936 { 0x3e, KEY_SEARCH }, /* Auto Scan */
1937 { 0x2e, KEY_CAMERA }, /* Capture Video */
1938 { 0x6d, KEY_MENU }, /* Show/Hide Control */
1939 { 0x2f, KEY_ZOOM }, /* Full Screen */
1940 { 0x34, KEY_RADIO }, /* FM */
1941 { 0x65, KEY_POWER }, /* Computer power */
1942};
1943
1944struct ir_scancode_table ir_codes_norwood_table = {
1945 .scan = ir_codes_norwood,
1946 .size = ARRAY_SIZE(ir_codes_norwood),
1947};
1948EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
1949
1950/* From reading the following remotes:
1951 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
1952 * Hauppauge (from NOVA-CI-s box product)
1953 * This is a "middle of the road" approach, differences are noted
1954 */
1955static struct ir_scancode ir_codes_budget_ci_old[] = {
1956 { 0x00, KEY_0 },
1957 { 0x01, KEY_1 },
1958 { 0x02, KEY_2 },
1959 { 0x03, KEY_3 },
1960 { 0x04, KEY_4 },
1961 { 0x05, KEY_5 },
1962 { 0x06, KEY_6 },
1963 { 0x07, KEY_7 },
1964 { 0x08, KEY_8 },
1965 { 0x09, KEY_9 },
1966 { 0x0a, KEY_ENTER },
1967 { 0x0b, KEY_RED },
1968 { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
1969 { 0x0d, KEY_MUTE },
1970 { 0x0f, KEY_A }, /* TV on Hauppauge */
1971 { 0x10, KEY_VOLUMEUP },
1972 { 0x11, KEY_VOLUMEDOWN },
1973 { 0x14, KEY_B },
1974 { 0x1c, KEY_UP },
1975 { 0x1d, KEY_DOWN },
1976 { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
1977 { 0x1f, KEY_BREAK },
1978 { 0x20, KEY_CHANNELUP },
1979 { 0x21, KEY_CHANNELDOWN },
1980 { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
1981 { 0x24, KEY_RESTART },
1982 { 0x25, KEY_OK },
1983 { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
1984 { 0x28, KEY_ENTER }, /* VCR mode on Zenith */
1985 { 0x29, KEY_PAUSE },
1986 { 0x2b, KEY_RIGHT },
1987 { 0x2c, KEY_LEFT },
1988 { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
1989 { 0x30, KEY_SLOW },
1990 { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
1991 { 0x32, KEY_REWIND },
1992 { 0x34, KEY_FASTFORWARD },
1993 { 0x35, KEY_PLAY },
1994 { 0x36, KEY_STOP },
1995 { 0x37, KEY_RECORD },
1996 { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
1997 { 0x3a, KEY_C },
1998 { 0x3c, KEY_EXIT },
1999 { 0x3d, KEY_POWER2 },
2000 { 0x3e, KEY_TUNER },
2001};
2002
2003struct ir_scancode_table ir_codes_budget_ci_old_table = {
2004 .scan = ir_codes_budget_ci_old,
2005 .size = ARRAY_SIZE(ir_codes_budget_ci_old),
2006};
2007EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
2008
2009/*
2010 * Marc Fargas <telenieko@telenieko.com>
2011 * this is the remote control that comes with the asus p7131
2012 * which has a label saying is "Model PC-39"
2013 */
2014static struct ir_scancode ir_codes_asus_pc39[] = {
2015 /* Keys 0 to 9 */
2016 { 0x15, KEY_0 },
2017 { 0x29, KEY_1 },
2018 { 0x2d, KEY_2 },
2019 { 0x2b, KEY_3 },
2020 { 0x09, KEY_4 },
2021 { 0x0d, KEY_5 },
2022 { 0x0b, KEY_6 },
2023 { 0x31, KEY_7 },
2024 { 0x35, KEY_8 },
2025 { 0x33, KEY_9 },
2026
2027 { 0x3e, KEY_RADIO }, /* radio */
2028 { 0x03, KEY_MENU }, /* dvd/menu */
2029 { 0x2a, KEY_VOLUMEUP },
2030 { 0x19, KEY_VOLUMEDOWN },
2031 { 0x37, KEY_UP },
2032 { 0x3b, KEY_DOWN },
2033 { 0x27, KEY_LEFT },
2034 { 0x2f, KEY_RIGHT },
2035 { 0x25, KEY_VIDEO }, /* video */
2036 { 0x39, KEY_AUDIO }, /* music */
2037
2038 { 0x21, KEY_TV }, /* tv */
2039 { 0x1d, KEY_EXIT }, /* back */
2040 { 0x0a, KEY_CHANNELUP }, /* channel / program + */
2041 { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
2042 { 0x1a, KEY_ENTER }, /* enter */
2043
2044 { 0x06, KEY_PAUSE }, /* play/pause */
2045 { 0x1e, KEY_PREVIOUS }, /* rew */
2046 { 0x26, KEY_NEXT }, /* forward */
2047 { 0x0e, KEY_REWIND }, /* backward << */
2048 { 0x3a, KEY_FASTFORWARD }, /* forward >> */
2049 { 0x36, KEY_STOP },
2050 { 0x2e, KEY_RECORD }, /* recording */
2051 { 0x16, KEY_POWER }, /* the button that reads "close" */
2052
2053 { 0x11, KEY_ZOOM }, /* full screen */
2054 { 0x13, KEY_MACRO }, /* recall */
2055 { 0x23, KEY_HOME }, /* home */
2056 { 0x05, KEY_PVR }, /* picture */
2057 { 0x3d, KEY_MUTE }, /* mute */
2058 { 0x01, KEY_DVD }, /* dvd */
2059};
2060
2061struct ir_scancode_table ir_codes_asus_pc39_table = {
2062 .scan = ir_codes_asus_pc39,
2063 .size = ARRAY_SIZE(ir_codes_asus_pc39),
2064};
2065EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
2066
2067
2068/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
2069 Juan Pablo Sormani <sorman@gmail.com> */
2070static struct ir_scancode ir_codes_encore_enltv[] = {
2071
2072 /* Power button does nothing, neither in Windows app,
2073 although it sends data (used for BIOS wakeup?) */
2074 { 0x0d, KEY_MUTE },
2075
2076 { 0x1e, KEY_TV },
2077 { 0x00, KEY_VIDEO },
2078 { 0x01, KEY_AUDIO }, /* music */
2079 { 0x02, KEY_MHP }, /* picture */
2080
2081 { 0x1f, KEY_1 },
2082 { 0x03, KEY_2 },
2083 { 0x04, KEY_3 },
2084 { 0x05, KEY_4 },
2085 { 0x1c, KEY_5 },
2086 { 0x06, KEY_6 },
2087 { 0x07, KEY_7 },
2088 { 0x08, KEY_8 },
2089 { 0x1d, KEY_9 },
2090 { 0x0a, KEY_0 },
2091
2092 { 0x09, KEY_LIST }, /* -/-- */
2093 { 0x0b, KEY_LAST }, /* recall */
2094
2095 { 0x14, KEY_HOME }, /* win start menu */
2096 { 0x15, KEY_EXIT }, /* exit */
2097 { 0x16, KEY_CHANNELUP }, /* UP */
2098 { 0x12, KEY_CHANNELDOWN }, /* DOWN */
2099 { 0x0c, KEY_VOLUMEUP }, /* RIGHT */
2100 { 0x17, KEY_VOLUMEDOWN }, /* LEFT */
2101
2102 { 0x18, KEY_ENTER }, /* OK */
2103
2104 { 0x0e, KEY_ESC },
2105 { 0x13, KEY_CYCLEWINDOWS }, /* desktop */
2106 { 0x11, KEY_TAB },
2107 { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
2108
2109 { 0x1a, KEY_MENU },
2110 { 0x1b, KEY_ZOOM }, /* fullscreen */
2111 { 0x44, KEY_TIME }, /* time shift */
2112 { 0x40, KEY_MODE }, /* source */
2113
2114 { 0x5a, KEY_RECORD },
2115 { 0x42, KEY_PLAY }, /* play/pause */
2116 { 0x45, KEY_STOP },
2117 { 0x43, KEY_CAMERA }, /* camera icon */
2118
2119 { 0x48, KEY_REWIND },
2120 { 0x4a, KEY_FASTFORWARD },
2121 { 0x49, KEY_PREVIOUS },
2122 { 0x4b, KEY_NEXT },
2123
2124 { 0x4c, KEY_FAVORITES }, /* tv wall */
2125 { 0x4d, KEY_SOUND }, /* DVD sound */
2126 { 0x4e, KEY_LANGUAGE }, /* DVD lang */
2127 { 0x4f, KEY_TEXT }, /* DVD text */
2128
2129 { 0x50, KEY_SLEEP }, /* shutdown */
2130 { 0x51, KEY_MODE }, /* stereo > main */
2131 { 0x52, KEY_SELECT }, /* stereo > sap */
2132 { 0x53, KEY_PROG1 }, /* teletext */
2133
2134
2135 { 0x59, KEY_RED }, /* AP1 */
2136 { 0x41, KEY_GREEN }, /* AP2 */
2137 { 0x47, KEY_YELLOW }, /* AP3 */
2138 { 0x57, KEY_BLUE }, /* AP4 */
2139};
2140
2141struct ir_scancode_table ir_codes_encore_enltv_table = {
2142 .scan = ir_codes_encore_enltv,
2143 .size = ARRAY_SIZE(ir_codes_encore_enltv),
2144};
2145EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
2146
2147/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
2148 Mauro Carvalho Chehab <mchehab@infradead.org> */
2149static struct ir_scancode ir_codes_encore_enltv2[] = {
2150 { 0x4c, KEY_POWER2 },
2151 { 0x4a, KEY_TUNER },
2152 { 0x40, KEY_1 },
2153 { 0x60, KEY_2 },
2154 { 0x50, KEY_3 },
2155 { 0x70, KEY_4 },
2156 { 0x48, KEY_5 },
2157 { 0x68, KEY_6 },
2158 { 0x58, KEY_7 },
2159 { 0x78, KEY_8 },
2160 { 0x44, KEY_9 },
2161 { 0x54, KEY_0 },
2162
2163 { 0x64, KEY_LAST }, /* +100 */
2164 { 0x4e, KEY_AGAIN }, /* Recall */
2165
2166 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
2167 { 0x5e, KEY_MENU },
2168 { 0x56, KEY_SCREEN },
2169 { 0x7a, KEY_SETUP },
2170
2171 { 0x46, KEY_MUTE },
2172 { 0x5c, KEY_MODE }, /* Stereo */
2173 { 0x74, KEY_INFO },
2174 { 0x7c, KEY_CLEAR },
2175
2176 { 0x55, KEY_UP },
2177 { 0x49, KEY_DOWN },
2178 { 0x7e, KEY_LEFT },
2179 { 0x59, KEY_RIGHT },
2180 { 0x6a, KEY_ENTER },
2181
2182 { 0x42, KEY_VOLUMEUP },
2183 { 0x62, KEY_VOLUMEDOWN },
2184 { 0x52, KEY_CHANNELUP },
2185 { 0x72, KEY_CHANNELDOWN },
2186
2187 { 0x41, KEY_RECORD },
2188 { 0x51, KEY_CAMERA }, /* Snapshot */
2189 { 0x75, KEY_TIME }, /* Timeshift */
2190 { 0x71, KEY_TV2 }, /* PIP */
2191
2192 { 0x45, KEY_REWIND },
2193 { 0x6f, KEY_PAUSE },
2194 { 0x7d, KEY_FORWARD },
2195 { 0x79, KEY_STOP },
2196};
2197
2198struct ir_scancode_table ir_codes_encore_enltv2_table = {
2199 .scan = ir_codes_encore_enltv2,
2200 .size = ARRAY_SIZE(ir_codes_encore_enltv2),
2201};
2202EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
2203
2204/* for the Technotrend 1500 bundled remotes (grey and black): */
2205static struct ir_scancode ir_codes_tt_1500[] = {
2206 { 0x01, KEY_POWER },
2207 { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
2208 { 0x03, KEY_1 },
2209 { 0x04, KEY_2 },
2210 { 0x05, KEY_3 },
2211 { 0x06, KEY_4 },
2212 { 0x07, KEY_5 },
2213 { 0x08, KEY_6 },
2214 { 0x09, KEY_7 },
2215 { 0x0a, KEY_8 },
2216 { 0x0b, KEY_9 },
2217 { 0x0c, KEY_0 },
2218 { 0x0d, KEY_UP },
2219 { 0x0e, KEY_LEFT },
2220 { 0x0f, KEY_OK },
2221 { 0x10, KEY_RIGHT },
2222 { 0x11, KEY_DOWN },
2223 { 0x12, KEY_INFO },
2224 { 0x13, KEY_EXIT },
2225 { 0x14, KEY_RED },
2226 { 0x15, KEY_GREEN },
2227 { 0x16, KEY_YELLOW },
2228 { 0x17, KEY_BLUE },
2229 { 0x18, KEY_MUTE },
2230 { 0x19, KEY_TEXT },
2231 { 0x1a, KEY_MODE }, /* ? TV/Radio */
2232 { 0x21, KEY_OPTION },
2233 { 0x22, KEY_EPG },
2234 { 0x23, KEY_CHANNELUP },
2235 { 0x24, KEY_CHANNELDOWN },
2236 { 0x25, KEY_VOLUMEUP },
2237 { 0x26, KEY_VOLUMEDOWN },
2238 { 0x27, KEY_SETUP },
2239 { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
2240 { 0x3b, KEY_PLAY },
2241 { 0x3c, KEY_STOP },
2242 { 0x3d, KEY_REWIND },
2243 { 0x3e, KEY_PAUSE },
2244 { 0x3f, KEY_FORWARD },
2245};
2246
2247struct ir_scancode_table ir_codes_tt_1500_table = {
2248 .scan = ir_codes_tt_1500,
2249 .size = ARRAY_SIZE(ir_codes_tt_1500),
2250};
2251EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
2252
2253/* DViCO FUSION HDTV MCE remote */
2254static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
2255
2256 { 0x0b, KEY_1 },
2257 { 0x17, KEY_2 },
2258 { 0x1b, KEY_3 },
2259 { 0x07, KEY_4 },
2260 { 0x50, KEY_5 },
2261 { 0x54, KEY_6 },
2262 { 0x48, KEY_7 },
2263 { 0x4c, KEY_8 },
2264 { 0x58, KEY_9 },
2265 { 0x03, KEY_0 },
2266
2267 { 0x5e, KEY_OK },
2268 { 0x51, KEY_UP },
2269 { 0x53, KEY_DOWN },
2270 { 0x5b, KEY_LEFT },
2271 { 0x5f, KEY_RIGHT },
2272
2273 { 0x02, KEY_TV }, /* Labeled DTV on remote */
2274 { 0x0e, KEY_MP3 },
2275 { 0x1a, KEY_DVD },
2276 { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
2277 { 0x16, KEY_SETUP },
2278 { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
2279 { 0x0a, KEY_EPG }, /* Labeled Guide on remote */
2280
2281 { 0x49, KEY_BACK },
2282 { 0x59, KEY_INFO }, /* Labeled MORE on remote */
2283 { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
2284 { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
2285
2286 { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
2287 { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
2288 { 0x42, KEY_ENTER }, /* Labeled START with a green
2289 MS windows logo on remote */
2290
2291 { 0x15, KEY_VOLUMEUP },
2292 { 0x05, KEY_VOLUMEDOWN },
2293 { 0x11, KEY_CHANNELUP },
2294 { 0x09, KEY_CHANNELDOWN },
2295
2296 { 0x52, KEY_CAMERA },
2297 { 0x5a, KEY_TUNER },
2298 { 0x19, KEY_OPEN },
2299
2300 { 0x13, KEY_MODE }, /* 4:3 16:9 select */
2301 { 0x1f, KEY_ZOOM },
2302
2303 { 0x43, KEY_REWIND },
2304 { 0x47, KEY_PLAYPAUSE },
2305 { 0x4f, KEY_FASTFORWARD },
2306 { 0x57, KEY_MUTE },
2307 { 0x0d, KEY_STOP },
2308 { 0x01, KEY_RECORD },
2309 { 0x4e, KEY_POWER },
2310};
2311
2312struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
2313 .scan = ir_codes_fusionhdtv_mce,
2314 .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
2315};
2316EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
2317
2318/* Pinnacle PCTV HD 800i mini remote */
2319static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
2320
2321 { 0x0f, KEY_1 },
2322 { 0x15, KEY_2 },
2323 { 0x10, KEY_3 },
2324 { 0x18, KEY_4 },
2325 { 0x1b, KEY_5 },
2326 { 0x1e, KEY_6 },
2327 { 0x11, KEY_7 },
2328 { 0x21, KEY_8 },
2329 { 0x12, KEY_9 },
2330 { 0x27, KEY_0 },
2331
2332 { 0x24, KEY_ZOOM },
2333 { 0x2a, KEY_SUBTITLE },
2334
2335 { 0x00, KEY_MUTE },
2336 { 0x01, KEY_ENTER }, /* Pinnacle Logo */
2337 { 0x39, KEY_POWER },
2338
2339 { 0x03, KEY_VOLUMEUP },
2340 { 0x09, KEY_VOLUMEDOWN },
2341 { 0x06, KEY_CHANNELUP },
2342 { 0x0c, KEY_CHANNELDOWN },
2343
2344 { 0x2d, KEY_REWIND },
2345 { 0x30, KEY_PLAYPAUSE },
2346 { 0x33, KEY_FASTFORWARD },
2347 { 0x3c, KEY_STOP },
2348 { 0x36, KEY_RECORD },
2349 { 0x3f, KEY_EPG }, /* Labeled "?" */
2350};
2351
2352struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
2353 .scan = ir_codes_pinnacle_pctv_hd,
2354 .size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
2355};
2356EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
2357
2358/*
2359 * Igor Kuznetsov <igk72@ya.ru>
2360 * Andrey J. Melnikov <temnota@kmv.ru>
2361 *
2362 * Keytable is used by BeholdTV 60x series, M6 series at
2363 * least, and probably other cards too.
2364 * The "ascii-art picture" below (in comments, first row
2365 * is the keycode in hex, and subsequent row(s) shows
2366 * the button labels (several variants when appropriate)
2367 * helps to descide which keycodes to assign to the buttons.
2368 */
2369static struct ir_scancode ir_codes_behold[] = {
2370
2371 /* 0x1c 0x12 *
2372 * TV/FM POWER *
2373 * */
2374 { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
2375 { 0x12, KEY_POWER },
2376
2377 /* 0x01 0x02 0x03 *
2378 * 1 2 3 *
2379 * *
2380 * 0x04 0x05 0x06 *
2381 * 4 5 6 *
2382 * *
2383 * 0x07 0x08 0x09 *
2384 * 7 8 9 *
2385 * */
2386 { 0x01, KEY_1 },
2387 { 0x02, KEY_2 },
2388 { 0x03, KEY_3 },
2389 { 0x04, KEY_4 },
2390 { 0x05, KEY_5 },
2391 { 0x06, KEY_6 },
2392 { 0x07, KEY_7 },
2393 { 0x08, KEY_8 },
2394 { 0x09, KEY_9 },
2395
2396 /* 0x0a 0x00 0x17 *
2397 * RECALL 0 MODE *
2398 * */
2399 { 0x0a, KEY_AGAIN },
2400 { 0x00, KEY_0 },
2401 { 0x17, KEY_MODE },
2402
2403 /* 0x14 0x10 *
2404 * ASPECT FULLSCREEN *
2405 * */
2406 { 0x14, KEY_SCREEN },
2407 { 0x10, KEY_ZOOM },
2408
2409 /* 0x0b *
2410 * Up *
2411 * *
2412 * 0x18 0x16 0x0c *
2413 * Left Ok Right *
2414 * *
2415 * 0x015 *
2416 * Down *
2417 * */
2418 { 0x0b, KEY_CHANNELUP },
2419 { 0x18, KEY_VOLUMEDOWN },
2420 { 0x16, KEY_OK }, /* XXX KEY_ENTER */
2421 { 0x0c, KEY_VOLUMEUP },
2422 { 0x15, KEY_CHANNELDOWN },
2423
2424 /* 0x11 0x0d *
2425 * MUTE INFO *
2426 * */
2427 { 0x11, KEY_MUTE },
2428 { 0x0d, KEY_INFO },
2429
2430 /* 0x0f 0x1b 0x1a *
2431 * RECORD PLAY/PAUSE STOP *
2432 * *
2433 * 0x0e 0x1f 0x1e *
2434 *TELETEXT AUDIO SOURCE *
2435 * RED YELLOW *
2436 * */
2437 { 0x0f, KEY_RECORD },
2438 { 0x1b, KEY_PLAYPAUSE },
2439 { 0x1a, KEY_STOP },
2440 { 0x0e, KEY_TEXT },
2441 { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
2442 { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
2443
2444 /* 0x1d 0x13 0x19 *
2445 * SLEEP PREVIEW DVB *
2446 * GREEN BLUE *
2447 * */
2448 { 0x1d, KEY_SLEEP },
2449 { 0x13, KEY_GREEN },
2450 { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
2451
2452 /* 0x58 0x5c *
2453 * FREEZE SNAPSHOT *
2454 * */
2455 { 0x58, KEY_SLOW },
2456 { 0x5c, KEY_CAMERA },
2457
2458};
2459
2460struct ir_scancode_table ir_codes_behold_table = {
2461 .scan = ir_codes_behold,
2462 .size = ARRAY_SIZE(ir_codes_behold),
2463};
2464EXPORT_SYMBOL_GPL(ir_codes_behold_table);
2465
2466/* Beholder Intl. Ltd. 2008
2467 * Dmitry Belimov d.belimov@google.com
2468 * Keytable is used by BeholdTV Columbus
2469 * The "ascii-art picture" below (in comments, first row
2470 * is the keycode in hex, and subsequent row(s) shows
2471 * the button labels (several variants when appropriate)
2472 * helps to descide which keycodes to assign to the buttons.
2473 */
2474static struct ir_scancode ir_codes_behold_columbus[] = {
2475
2476 /* 0x13 0x11 0x1C 0x12 *
2477 * Mute Source TV/FM Power *
2478 * */
2479
2480 { 0x13, KEY_MUTE },
2481 { 0x11, KEY_PROPS },
2482 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
2483 { 0x12, KEY_POWER },
2484
2485 /* 0x01 0x02 0x03 0x0D *
2486 * 1 2 3 Stereo *
2487 * *
2488 * 0x04 0x05 0x06 0x19 *
2489 * 4 5 6 Snapshot *
2490 * *
2491 * 0x07 0x08 0x09 0x10 *
2492 * 7 8 9 Zoom *
2493 * */
2494 { 0x01, KEY_1 },
2495 { 0x02, KEY_2 },
2496 { 0x03, KEY_3 },
2497 { 0x0D, KEY_SETUP }, /* Setup key */
2498 { 0x04, KEY_4 },
2499 { 0x05, KEY_5 },
2500 { 0x06, KEY_6 },
2501 { 0x19, KEY_CAMERA }, /* Snapshot key */
2502 { 0x07, KEY_7 },
2503 { 0x08, KEY_8 },
2504 { 0x09, KEY_9 },
2505 { 0x10, KEY_ZOOM },
2506
2507 /* 0x0A 0x00 0x0B 0x0C *
2508 * RECALL 0 ChannelUp VolumeUp *
2509 * */
2510 { 0x0A, KEY_AGAIN },
2511 { 0x00, KEY_0 },
2512 { 0x0B, KEY_CHANNELUP },
2513 { 0x0C, KEY_VOLUMEUP },
2514
2515 /* 0x1B 0x1D 0x15 0x18 *
2516 * Timeshift Record ChannelDown VolumeDown *
2517 * */
2518
2519 { 0x1B, KEY_TIME },
2520 { 0x1D, KEY_RECORD },
2521 { 0x15, KEY_CHANNELDOWN },
2522 { 0x18, KEY_VOLUMEDOWN },
2523
2524 /* 0x0E 0x1E 0x0F 0x1A *
2525 * Stop Pause Previouse Next *
2526 * */
2527
2528 { 0x0E, KEY_STOP },
2529 { 0x1E, KEY_PAUSE },
2530 { 0x0F, KEY_PREVIOUS },
2531 { 0x1A, KEY_NEXT },
2532
2533};
2534
2535struct ir_scancode_table ir_codes_behold_columbus_table = {
2536 .scan = ir_codes_behold_columbus,
2537 .size = ARRAY_SIZE(ir_codes_behold_columbus),
2538};
2539EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
2540
2541/*
2542 * Remote control for the Genius TVGO A11MCE
2543 * Adrian Pardini <pardo.bsso@gmail.com>
2544 */
2545static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
2546 /* Keys 0 to 9 */
2547 { 0x48, KEY_0 },
2548 { 0x09, KEY_1 },
2549 { 0x1d, KEY_2 },
2550 { 0x1f, KEY_3 },
2551 { 0x19, KEY_4 },
2552 { 0x1b, KEY_5 },
2553 { 0x11, KEY_6 },
2554 { 0x17, KEY_7 },
2555 { 0x12, KEY_8 },
2556 { 0x16, KEY_9 },
2557
2558 { 0x54, KEY_RECORD }, /* recording */
2559 { 0x06, KEY_MUTE }, /* mute */
2560 { 0x10, KEY_POWER },
2561 { 0x40, KEY_LAST }, /* recall */
2562 { 0x4c, KEY_CHANNELUP }, /* channel / program + */
2563 { 0x00, KEY_CHANNELDOWN }, /* channel / program - */
2564 { 0x0d, KEY_VOLUMEUP },
2565 { 0x15, KEY_VOLUMEDOWN },
2566 { 0x4d, KEY_OK }, /* also labeled as Pause */
2567 { 0x1c, KEY_ZOOM }, /* full screen and Stop*/
2568 { 0x02, KEY_MODE }, /* AV Source or Rewind*/
2569 { 0x04, KEY_LIST }, /* -/-- */
2570 /* small arrows above numbers */
2571 { 0x1a, KEY_NEXT }, /* also Fast Forward */
2572 { 0x0e, KEY_PREVIOUS }, /* also Rewind */
2573 /* these are in a rather non standard layout and have
2574 an alternate name written */
2575 { 0x1e, KEY_UP }, /* Video Setting */
2576 { 0x0a, KEY_DOWN }, /* Video Default */
2577 { 0x05, KEY_CAMERA }, /* Snapshot */
2578 { 0x0c, KEY_RIGHT }, /* Hide Panel */
2579 /* Four buttons without label */
2580 { 0x49, KEY_RED },
2581 { 0x0b, KEY_GREEN },
2582 { 0x13, KEY_YELLOW },
2583 { 0x50, KEY_BLUE },
2584};
2585
2586struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
2587 .scan = ir_codes_genius_tvgo_a11mce,
2588 .size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
2589};
2590EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
2591
2592/*
2593 * Remote control for Powercolor Real Angel 330
2594 * Daniel Fraga <fragabr@gmail.com>
2595 */
2596static struct ir_scancode ir_codes_powercolor_real_angel[] = {
2597 { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
2598 { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
2599 { 0x00, KEY_0 },
2600 { 0x01, KEY_1 },
2601 { 0x02, KEY_2 },
2602 { 0x03, KEY_3 },
2603 { 0x04, KEY_4 },
2604 { 0x05, KEY_5 },
2605 { 0x06, KEY_6 },
2606 { 0x07, KEY_7 },
2607 { 0x08, KEY_8 },
2608 { 0x09, KEY_9 },
2609 { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */
2610 { 0x29, KEY_PREVIOUS }, /* previous channel */
2611 { 0x12, KEY_BRIGHTNESSUP },
2612 { 0x13, KEY_BRIGHTNESSDOWN },
2613 { 0x2b, KEY_MODE }, /* stereo/mono */
2614 { 0x2c, KEY_TEXT }, /* teletext */
2615 { 0x20, KEY_CHANNELUP }, /* channel up */
2616 { 0x21, KEY_CHANNELDOWN }, /* channel down */
2617 { 0x10, KEY_VOLUMEUP }, /* volume up */
2618 { 0x11, KEY_VOLUMEDOWN }, /* volume down */
2619 { 0x0d, KEY_MUTE },
2620 { 0x1f, KEY_RECORD },
2621 { 0x17, KEY_PLAY },
2622 { 0x16, KEY_PAUSE },
2623 { 0x0b, KEY_STOP },
2624 { 0x27, KEY_FASTFORWARD },
2625 { 0x26, KEY_REWIND },
2626 { 0x1e, KEY_SEARCH }, /* autoscan */
2627 { 0x0e, KEY_CAMERA }, /* snapshot */
2628 { 0x2d, KEY_SETUP },
2629 { 0x0f, KEY_SCREEN }, /* full screen */
2630 { 0x14, KEY_RADIO }, /* FM radio */
2631 { 0x25, KEY_POWER }, /* power */
2632};
2633
2634struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
2635 .scan = ir_codes_powercolor_real_angel,
2636 .size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
2637};
2638EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
2639
2640/* Kworld Plus TV Analog Lite PCI IR
2641 Mauro Carvalho Chehab <mchehab@infradead.org>
2642 */
2643static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
2644 { 0x0c, KEY_PROG1 }, /* Kworld key */
2645 { 0x16, KEY_CLOSECD }, /* -> ) */
2646 { 0x1d, KEY_POWER2 },
2647
2648 { 0x00, KEY_1 },
2649 { 0x01, KEY_2 },
2650 { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
2651 { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
2652 { 0x04, KEY_5 },
2653 { 0x05, KEY_6 },
2654 { 0x06, KEY_7 },
2655 { 0x07, KEY_8 },
2656 { 0x08, KEY_9 },
2657 { 0x0a, KEY_0 },
2658
2659 { 0x09, KEY_AGAIN },
2660 { 0x14, KEY_MUTE },
2661
2662 { 0x20, KEY_UP },
2663 { 0x21, KEY_DOWN },
2664 { 0x0b, KEY_ENTER },
2665
2666 { 0x10, KEY_CHANNELUP },
2667 { 0x11, KEY_CHANNELDOWN },
2668
2669 /* Couldn't map key left/key right since those
2670 conflict with '3' and '4' scancodes
2671 I dunno what the original driver does
2672 */
2673
2674 { 0x13, KEY_VOLUMEUP },
2675 { 0x12, KEY_VOLUMEDOWN },
2676
2677 /* The lower part of the IR
2678 There are several duplicated keycodes there.
2679 Most of them conflict with digits.
2680 Add mappings just to the unused scancodes.
2681 Somehow, the original driver has a way to know,
2682 but this doesn't seem to be on some GPIO.
2683 Also, it is not related to the time between keyup
2684 and keydown.
2685 */
2686 { 0x19, KEY_TIME}, /* Timeshift */
2687 { 0x1a, KEY_STOP},
2688 { 0x1b, KEY_RECORD},
2689
2690 { 0x22, KEY_TEXT},
2691
2692 { 0x15, KEY_AUDIO}, /* ((*)) */
2693 { 0x0f, KEY_ZOOM},
2694 { 0x1c, KEY_CAMERA}, /* snapshot */
2695
2696 { 0x18, KEY_RED}, /* B */
2697 { 0x23, KEY_GREEN}, /* C */
2698};
2699struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
2700 .scan = ir_codes_kworld_plus_tv_analog,
2701 .size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
2702};
2703EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
2704
2705/* Kaiomy TVnPC U2
2706 Mauro Carvalho Chehab <mchehab@infradead.org>
2707 */
2708static struct ir_scancode ir_codes_kaiomy[] = {
2709 { 0x43, KEY_POWER2},
2710 { 0x01, KEY_LIST},
2711 { 0x0b, KEY_ZOOM},
2712 { 0x03, KEY_POWER},
2713
2714 { 0x04, KEY_1},
2715 { 0x08, KEY_2},
2716 { 0x02, KEY_3},
2717
2718 { 0x0f, KEY_4},
2719 { 0x05, KEY_5},
2720 { 0x06, KEY_6},
2721
2722 { 0x0c, KEY_7},
2723 { 0x0d, KEY_8},
2724 { 0x0a, KEY_9},
2725
2726 { 0x11, KEY_0},
2727
2728 { 0x09, KEY_CHANNELUP},
2729 { 0x07, KEY_CHANNELDOWN},
2730
2731 { 0x0e, KEY_VOLUMEUP},
2732 { 0x13, KEY_VOLUMEDOWN},
2733
2734 { 0x10, KEY_HOME},
2735 { 0x12, KEY_ENTER},
2736
2737 { 0x14, KEY_RECORD},
2738 { 0x15, KEY_STOP},
2739 { 0x16, KEY_PLAY},
2740 { 0x17, KEY_MUTE},
2741
2742 { 0x18, KEY_UP},
2743 { 0x19, KEY_DOWN},
2744 { 0x1a, KEY_LEFT},
2745 { 0x1b, KEY_RIGHT},
2746
2747 { 0x1c, KEY_RED},
2748 { 0x1d, KEY_GREEN},
2749 { 0x1e, KEY_YELLOW},
2750 { 0x1f, KEY_BLUE},
2751};
2752struct ir_scancode_table ir_codes_kaiomy_table = {
2753 .scan = ir_codes_kaiomy,
2754 .size = ARRAY_SIZE(ir_codes_kaiomy),
2755};
2756EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
2757
2758static struct ir_scancode ir_codes_avermedia_a16d[] = {
2759 { 0x20, KEY_LIST},
2760 { 0x00, KEY_POWER},
2761 { 0x28, KEY_1},
2762 { 0x18, KEY_2},
2763 { 0x38, KEY_3},
2764 { 0x24, KEY_4},
2765 { 0x14, KEY_5},
2766 { 0x34, KEY_6},
2767 { 0x2c, KEY_7},
2768 { 0x1c, KEY_8},
2769 { 0x3c, KEY_9},
2770 { 0x12, KEY_SUBTITLE},
2771 { 0x22, KEY_0},
2772 { 0x32, KEY_REWIND},
2773 { 0x3a, KEY_SHUFFLE},
2774 { 0x02, KEY_PRINT},
2775 { 0x11, KEY_CHANNELDOWN},
2776 { 0x31, KEY_CHANNELUP},
2777 { 0x0c, KEY_ZOOM},
2778 { 0x1e, KEY_VOLUMEDOWN},
2779 { 0x3e, KEY_VOLUMEUP},
2780 { 0x0a, KEY_MUTE},
2781 { 0x04, KEY_AUDIO},
2782 { 0x26, KEY_RECORD},
2783 { 0x06, KEY_PLAY},
2784 { 0x36, KEY_STOP},
2785 { 0x16, KEY_PAUSE},
2786 { 0x2e, KEY_REWIND},
2787 { 0x0e, KEY_FASTFORWARD},
2788 { 0x30, KEY_TEXT},
2789 { 0x21, KEY_GREEN},
2790 { 0x01, KEY_BLUE},
2791 { 0x08, KEY_EPG},
2792 { 0x2a, KEY_MENU},
2793};
2794struct ir_scancode_table ir_codes_avermedia_a16d_table = {
2795 .scan = ir_codes_avermedia_a16d,
2796 .size = ARRAY_SIZE(ir_codes_avermedia_a16d),
2797};
2798EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
2799
2800/* Encore ENLTV-FM v5.3
2801 Mauro Carvalho Chehab <mchehab@infradead.org>
2802 */
2803static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
2804 { 0x10, KEY_POWER2},
2805 { 0x06, KEY_MUTE},
2806
2807 { 0x09, KEY_1},
2808 { 0x1d, KEY_2},
2809 { 0x1f, KEY_3},
2810 { 0x19, KEY_4},
2811 { 0x1b, KEY_5},
2812 { 0x11, KEY_6},
2813 { 0x17, KEY_7},
2814 { 0x12, KEY_8},
2815 { 0x16, KEY_9},
2816 { 0x48, KEY_0},
2817
2818 { 0x04, KEY_LIST}, /* -/-- */
2819 { 0x40, KEY_LAST}, /* recall */
2820
2821 { 0x02, KEY_MODE}, /* TV/AV */
2822 { 0x05, KEY_CAMERA}, /* SNAPSHOT */
2823
2824 { 0x4c, KEY_CHANNELUP}, /* UP */
2825 { 0x00, KEY_CHANNELDOWN}, /* DOWN */
2826 { 0x0d, KEY_VOLUMEUP}, /* RIGHT */
2827 { 0x15, KEY_VOLUMEDOWN}, /* LEFT */
2828 { 0x49, KEY_ENTER}, /* OK */
2829
2830 { 0x54, KEY_RECORD},
2831 { 0x4d, KEY_PLAY}, /* pause */
2832
2833 { 0x1e, KEY_MENU}, /* video setting */
2834 { 0x0e, KEY_RIGHT}, /* <- */
2835 { 0x1a, KEY_LEFT}, /* -> */
2836
2837 { 0x0a, KEY_CLEAR}, /* video default */
2838 { 0x0c, KEY_ZOOM}, /* hide pannel */
2839 { 0x47, KEY_SLEEP}, /* shutdown */
2840};
2841struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
2842 .scan = ir_codes_encore_enltv_fm53,
2843 .size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
2844};
2845EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
2846
2847/* Zogis Real Audio 220 - 32 keys IR */
2848static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
2849 { 0x1c, KEY_RADIO},
2850 { 0x12, KEY_POWER2},
2851
2852 { 0x01, KEY_1},
2853 { 0x02, KEY_2},
2854 { 0x03, KEY_3},
2855 { 0x04, KEY_4},
2856 { 0x05, KEY_5},
2857 { 0x06, KEY_6},
2858 { 0x07, KEY_7},
2859 { 0x08, KEY_8},
2860 { 0x09, KEY_9},
2861 { 0x00, KEY_0},
2862
2863 { 0x0c, KEY_VOLUMEUP},
2864 { 0x18, KEY_VOLUMEDOWN},
2865 { 0x0b, KEY_CHANNELUP},
2866 { 0x15, KEY_CHANNELDOWN},
2867 { 0x16, KEY_ENTER},
2868
2869 { 0x11, KEY_LIST}, /* Source */
2870 { 0x0d, KEY_AUDIO}, /* stereo */
2871
2872 { 0x0f, KEY_PREVIOUS}, /* Prev */
2873 { 0x1b, KEY_TIME}, /* Timeshift */
2874 { 0x1a, KEY_NEXT}, /* Next */
2875
2876 { 0x0e, KEY_STOP},
2877 { 0x1f, KEY_PLAY},
2878 { 0x1e, KEY_PLAYPAUSE}, /* Pause */
2879
2880 { 0x1d, KEY_RECORD},
2881 { 0x13, KEY_MUTE},
2882 { 0x19, KEY_CAMERA}, /* Snapshot */
2883
2884};
2885struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
2886 .scan = ir_codes_real_audio_220_32_keys,
2887 .size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
2888};
2889EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
2890
2891/* ATI TV Wonder HD 600 USB
2892 Devin Heitmueller <devin.heitmueller@gmail.com>
2893 */
2894static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
2895 { 0x00, KEY_RECORD}, /* Row 1 */
2896 { 0x01, KEY_PLAYPAUSE},
2897 { 0x02, KEY_STOP},
2898 { 0x03, KEY_POWER},
2899 { 0x04, KEY_PREVIOUS}, /* Row 2 */
2900 { 0x05, KEY_REWIND},
2901 { 0x06, KEY_FORWARD},
2902 { 0x07, KEY_NEXT},
2903 { 0x08, KEY_EPG}, /* Row 3 */
2904 { 0x09, KEY_HOME},
2905 { 0x0a, KEY_MENU},
2906 { 0x0b, KEY_CHANNELUP},
2907 { 0x0c, KEY_BACK}, /* Row 4 */
2908 { 0x0d, KEY_UP},
2909 { 0x0e, KEY_INFO},
2910 { 0x0f, KEY_CHANNELDOWN},
2911 { 0x10, KEY_LEFT}, /* Row 5 */
2912 { 0x11, KEY_SELECT},
2913 { 0x12, KEY_RIGHT},
2914 { 0x13, KEY_VOLUMEUP},
2915 { 0x14, KEY_LAST}, /* Row 6 */
2916 { 0x15, KEY_DOWN},
2917 { 0x16, KEY_MUTE},
2918 { 0x17, KEY_VOLUMEDOWN},
2919};
2920struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
2921 .scan = ir_codes_ati_tv_wonder_hd_600,
2922 .size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
2923};
2924EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
2925
2926/* DVBWorld remotes
2927 Igor M. Liplianin <liplianin@me.by>
2928 */
2929static struct ir_scancode ir_codes_dm1105_nec[] = {
2930 { 0x0a, KEY_POWER2}, /* power */
2931 { 0x0c, KEY_MUTE}, /* mute */
2932 { 0x11, KEY_1},
2933 { 0x12, KEY_2},
2934 { 0x13, KEY_3},
2935 { 0x14, KEY_4},
2936 { 0x15, KEY_5},
2937 { 0x16, KEY_6},
2938 { 0x17, KEY_7},
2939 { 0x18, KEY_8},
2940 { 0x19, KEY_9},
2941 { 0x10, KEY_0},
2942 { 0x1c, KEY_CHANNELUP}, /* ch+ */
2943 { 0x0f, KEY_CHANNELDOWN}, /* ch- */
2944 { 0x1a, KEY_VOLUMEUP}, /* vol+ */
2945 { 0x0e, KEY_VOLUMEDOWN}, /* vol- */
2946 { 0x04, KEY_RECORD}, /* rec */
2947 { 0x09, KEY_CHANNEL}, /* fav */
2948 { 0x08, KEY_BACKSPACE}, /* rewind */
2949 { 0x07, KEY_FASTFORWARD}, /* fast */
2950 { 0x0b, KEY_PAUSE}, /* pause */
2951 { 0x02, KEY_ESC}, /* cancel */
2952 { 0x03, KEY_TAB}, /* tab */
2953 { 0x00, KEY_UP}, /* up */
2954 { 0x1f, KEY_ENTER}, /* ok */
2955 { 0x01, KEY_DOWN}, /* down */
2956 { 0x05, KEY_RECORD}, /* cap */
2957 { 0x06, KEY_STOP}, /* stop */
2958 { 0x40, KEY_ZOOM}, /* full */
2959 { 0x1e, KEY_TV}, /* tvmode */
2960 { 0x1b, KEY_B}, /* recall */
2961};
2962struct ir_scancode_table ir_codes_dm1105_nec_table = {
2963 .scan = ir_codes_dm1105_nec,
2964 .size = ARRAY_SIZE(ir_codes_dm1105_nec),
2965};
2966EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
2967
2968static struct ir_scancode ir_codes_tevii_nec[] = {
2969 { 0x0a, KEY_POWER2},
2970 { 0x0c, KEY_MUTE},
2971 { 0x11, KEY_1},
2972 { 0x12, KEY_2},
2973 { 0x13, KEY_3},
2974 { 0x14, KEY_4},
2975 { 0x15, KEY_5},
2976 { 0x16, KEY_6},
2977 { 0x17, KEY_7},
2978 { 0x18, KEY_8},
2979 { 0x19, KEY_9},
2980 { 0x10, KEY_0},
2981 { 0x1c, KEY_MENU},
2982 { 0x0f, KEY_VOLUMEDOWN},
2983 { 0x1a, KEY_LAST},
2984 { 0x0e, KEY_OPEN},
2985 { 0x04, KEY_RECORD},
2986 { 0x09, KEY_VOLUMEUP},
2987 { 0x08, KEY_CHANNELUP},
2988 { 0x07, KEY_PVR},
2989 { 0x0b, KEY_TIME},
2990 { 0x02, KEY_RIGHT},
2991 { 0x03, KEY_LEFT},
2992 { 0x00, KEY_UP},
2993 { 0x1f, KEY_OK},
2994 { 0x01, KEY_DOWN},
2995 { 0x05, KEY_TUNER},
2996 { 0x06, KEY_CHANNELDOWN},
2997 { 0x40, KEY_PLAYPAUSE},
2998 { 0x1e, KEY_REWIND},
2999 { 0x1b, KEY_FAVORITES},
3000 { 0x1d, KEY_BACK},
3001 { 0x4d, KEY_FASTFORWARD},
3002 { 0x44, KEY_EPG},
3003 { 0x4c, KEY_INFO},
3004 { 0x41, KEY_AB},
3005 { 0x43, KEY_AUDIO},
3006 { 0x45, KEY_SUBTITLE},
3007 { 0x4a, KEY_LIST},
3008 { 0x46, KEY_F1},
3009 { 0x47, KEY_F2},
3010 { 0x5e, KEY_F3},
3011 { 0x5c, KEY_F4},
3012 { 0x52, KEY_F5},
3013 { 0x5a, KEY_F6},
3014 { 0x56, KEY_MODE},
3015 { 0x58, KEY_SWITCHVIDEOMODE},
3016};
3017struct ir_scancode_table ir_codes_tevii_nec_table = {
3018 .scan = ir_codes_tevii_nec,
3019 .size = ARRAY_SIZE(ir_codes_tevii_nec),
3020};
3021EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
3022
3023static struct ir_scancode ir_codes_tbs_nec[] = {
3024 { 0x04, KEY_POWER2}, /*power*/
3025 { 0x14, KEY_MUTE}, /*mute*/
3026 { 0x07, KEY_1},
3027 { 0x06, KEY_2},
3028 { 0x05, KEY_3},
3029 { 0x0b, KEY_4},
3030 { 0x0a, KEY_5},
3031 { 0x09, KEY_6},
3032 { 0x0f, KEY_7},
3033 { 0x0e, KEY_8},
3034 { 0x0d, KEY_9},
3035 { 0x12, KEY_0},
3036 { 0x16, KEY_CHANNELUP}, /*ch+*/
3037 { 0x11, KEY_CHANNELDOWN},/*ch-*/
3038 { 0x13, KEY_VOLUMEUP}, /*vol+*/
3039 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
3040 { 0x03, KEY_RECORD}, /*rec*/
3041 { 0x18, KEY_PAUSE}, /*pause*/
3042 { 0x19, KEY_OK}, /*ok*/
3043 { 0x1a, KEY_CAMERA}, /* snapshot */
3044 { 0x01, KEY_UP},
3045 { 0x10, KEY_LEFT},
3046 { 0x02, KEY_RIGHT},
3047 { 0x08, KEY_DOWN},
3048 { 0x15, KEY_FAVORITES},
3049 { 0x17, KEY_SUBTITLE},
3050 { 0x1d, KEY_ZOOM},
3051 { 0x1f, KEY_EXIT},
3052 { 0x1e, KEY_MENU},
3053 { 0x1c, KEY_EPG},
3054 { 0x00, KEY_PREVIOUS},
3055 { 0x1b, KEY_MODE},
3056};
3057struct ir_scancode_table ir_codes_tbs_nec_table = {
3058 .scan = ir_codes_tbs_nec,
3059 .size = ARRAY_SIZE(ir_codes_tbs_nec),
3060};
3061EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
3062
3063/* Terratec Cinergy Hybrid T USB XS
3064 Devin Heitmueller <dheitmueller@linuxtv.org>
3065 */
3066static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
3067 { 0x41, KEY_HOME},
3068 { 0x01, KEY_POWER},
3069 { 0x42, KEY_MENU},
3070 { 0x02, KEY_1},
3071 { 0x03, KEY_2},
3072 { 0x04, KEY_3},
3073 { 0x43, KEY_SUBTITLE},
3074 { 0x05, KEY_4},
3075 { 0x06, KEY_5},
3076 { 0x07, KEY_6},
3077 { 0x44, KEY_TEXT},
3078 { 0x08, KEY_7},
3079 { 0x09, KEY_8},
3080 { 0x0a, KEY_9},
3081 { 0x45, KEY_DELETE},
3082 { 0x0b, KEY_TUNER},
3083 { 0x0c, KEY_0},
3084 { 0x0d, KEY_MODE},
3085 { 0x46, KEY_TV},
3086 { 0x47, KEY_DVD},
3087 { 0x49, KEY_VIDEO},
3088 { 0x4b, KEY_AUX},
3089 { 0x10, KEY_UP},
3090 { 0x11, KEY_LEFT},
3091 { 0x12, KEY_OK},
3092 { 0x13, KEY_RIGHT},
3093 { 0x14, KEY_DOWN},
3094 { 0x0f, KEY_EPG},
3095 { 0x16, KEY_INFO},
3096 { 0x4d, KEY_BACKSPACE},
3097 { 0x1c, KEY_VOLUMEUP},
3098 { 0x4c, KEY_PLAY},
3099 { 0x1b, KEY_CHANNELUP},
3100 { 0x1e, KEY_VOLUMEDOWN},
3101 { 0x1d, KEY_MUTE},
3102 { 0x1f, KEY_CHANNELDOWN},
3103 { 0x17, KEY_RED},
3104 { 0x18, KEY_GREEN},
3105 { 0x19, KEY_YELLOW},
3106 { 0x1a, KEY_BLUE},
3107 { 0x58, KEY_RECORD},
3108 { 0x48, KEY_STOP},
3109 { 0x40, KEY_PAUSE},
3110 { 0x54, KEY_LAST},
3111 { 0x4e, KEY_REWIND},
3112 { 0x4f, KEY_FASTFORWARD},
3113 { 0x5c, KEY_NEXT},
3114};
3115struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
3116 .scan = ir_codes_terratec_cinergy_xs,
3117 .size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
3118};
3119EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
3120
3121/* EVGA inDtube
3122 Devin Heitmueller <devin.heitmueller@gmail.com>
3123 */
3124static struct ir_scancode ir_codes_evga_indtube[] = {
3125 { 0x12, KEY_POWER},
3126 { 0x02, KEY_MODE}, /* TV */
3127 { 0x14, KEY_MUTE},
3128 { 0x1a, KEY_CHANNELUP},
3129 { 0x16, KEY_TV2}, /* PIP */
3130 { 0x1d, KEY_VOLUMEUP},
3131 { 0x05, KEY_CHANNELDOWN},
3132 { 0x0f, KEY_PLAYPAUSE},
3133 { 0x19, KEY_VOLUMEDOWN},
3134 { 0x1c, KEY_REWIND},
3135 { 0x0d, KEY_RECORD},
3136 { 0x18, KEY_FORWARD},
3137 { 0x1e, KEY_PREVIOUS},
3138 { 0x1b, KEY_STOP},
3139 { 0x1f, KEY_NEXT},
3140 { 0x13, KEY_CAMERA},
3141};
3142struct ir_scancode_table ir_codes_evga_indtube_table = {
3143 .scan = ir_codes_evga_indtube,
3144 .size = ARRAY_SIZE(ir_codes_evga_indtube),
3145};
3146EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
3147
3148static struct ir_scancode ir_codes_videomate_s350[] = {
3149 { 0x00, KEY_TV},
3150 { 0x01, KEY_DVD},
3151 { 0x04, KEY_RECORD},
3152 { 0x05, KEY_VIDEO}, /* TV/Video */
3153 { 0x07, KEY_STOP},
3154 { 0x08, KEY_PLAYPAUSE},
3155 { 0x0a, KEY_REWIND},
3156 { 0x0f, KEY_FASTFORWARD},
3157 { 0x10, KEY_CHANNELUP},
3158 { 0x12, KEY_VOLUMEUP},
3159 { 0x13, KEY_CHANNELDOWN},
3160 { 0x14, KEY_MUTE},
3161 { 0x15, KEY_VOLUMEDOWN},
3162 { 0x16, KEY_1},
3163 { 0x17, KEY_2},
3164 { 0x18, KEY_3},
3165 { 0x19, KEY_4},
3166 { 0x1a, KEY_5},
3167 { 0x1b, KEY_6},
3168 { 0x1c, KEY_7},
3169 { 0x1d, KEY_8},
3170 { 0x1e, KEY_9},
3171 { 0x1f, KEY_0},
3172 { 0x21, KEY_SLEEP},
3173 { 0x24, KEY_ZOOM},
3174 { 0x25, KEY_LAST}, /* Recall */
3175 { 0x26, KEY_SUBTITLE}, /* CC */
3176 { 0x27, KEY_LANGUAGE}, /* MTS */
3177 { 0x29, KEY_CHANNEL}, /* SURF */
3178 { 0x2b, KEY_A},
3179 { 0x2c, KEY_B},
3180 { 0x2f, KEY_CAMERA}, /* Snapshot */
3181 { 0x23, KEY_RADIO},
3182 { 0x02, KEY_PREVIOUSSONG},
3183 { 0x06, KEY_NEXTSONG},
3184 { 0x03, KEY_EPG},
3185 { 0x09, KEY_SETUP},
3186 { 0x22, KEY_BACKSPACE},
3187 { 0x0c, KEY_UP},
3188 { 0x0e, KEY_DOWN},
3189 { 0x0b, KEY_LEFT},
3190 { 0x0d, KEY_RIGHT},
3191 { 0x11, KEY_ENTER},
3192 { 0x20, KEY_TEXT},
3193};
3194struct ir_scancode_table ir_codes_videomate_s350_table = {
3195 .scan = ir_codes_videomate_s350,
3196 .size = ARRAY_SIZE(ir_codes_videomate_s350),
3197};
3198EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
3199
3200/* GADMEI UTV330+ RM008Z remote
3201 Shine Liu <shinel@foxmail.com>
3202 */
3203static struct ir_scancode ir_codes_gadmei_rm008z[] = {
3204 { 0x14, KEY_POWER2}, /* POWER OFF */
3205 { 0x0c, KEY_MUTE}, /* MUTE */
3206
3207 { 0x18, KEY_TV}, /* TV */
3208 { 0x0e, KEY_VIDEO}, /* AV */
3209 { 0x0b, KEY_AUDIO}, /* SV */
3210 { 0x0f, KEY_RADIO}, /* FM */
3211
3212 { 0x00, KEY_1},
3213 { 0x01, KEY_2},
3214 { 0x02, KEY_3},
3215 { 0x03, KEY_4},
3216 { 0x04, KEY_5},
3217 { 0x05, KEY_6},
3218 { 0x06, KEY_7},
3219 { 0x07, KEY_8},
3220 { 0x08, KEY_9},
3221 { 0x09, KEY_0},
3222 { 0x0a, KEY_INFO}, /* OSD */
3223 { 0x1c, KEY_BACKSPACE}, /* LAST */
3224
3225 { 0x0d, KEY_PLAY}, /* PLAY */
3226 { 0x1e, KEY_CAMERA}, /* SNAPSHOT */
3227 { 0x1a, KEY_RECORD}, /* RECORD */
3228 { 0x17, KEY_STOP}, /* STOP */
3229
3230 { 0x1f, KEY_UP}, /* UP */
3231 { 0x44, KEY_DOWN}, /* DOWN */
3232 { 0x46, KEY_TAB}, /* BACK */
3233 { 0x4a, KEY_ZOOM}, /* FULLSECREEN */
3234
3235 { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
3236 { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3237 { 0x12, KEY_CHANNELUP}, /* CHANNELUP */
3238 { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3239 { 0x15, KEY_ENTER}, /* OK */
3240};
3241struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
3242 .scan = ir_codes_gadmei_rm008z,
3243 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
3244};
3245EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
3246
3247/*************************************************************
3248 * COMPLETE SCANCODE TABLES
3249 * Instead of just a partial scancode, the tables bellow
3250 * contains the complete scancode and the receiver protocol
3251 *************************************************************/
3252
3253/*
3254 * Hauppauge:the newer, gray remotes (seems there are multiple
3255 * slightly different versions), shipped with cx88+ivtv cards.
3256 *
3257 * This table contains the complete RC5 code, instead of just the data part
3258 */
3259static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
3260 /* Keys 0 to 9 */
3261 { 0x1e00, KEY_0 },
3262 { 0x1e01, KEY_1 },
3263 { 0x1e02, KEY_2 },
3264 { 0x1e03, KEY_3 },
3265 { 0x1e04, KEY_4 },
3266 { 0x1e05, KEY_5 },
3267 { 0x1e06, KEY_6 },
3268 { 0x1e07, KEY_7 },
3269 { 0x1e08, KEY_8 },
3270 { 0x1e09, KEY_9 },
3271
3272 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
3273 { 0x1e0b, KEY_RED }, /* red button */
3274 { 0x1e0c, KEY_RADIO },
3275 { 0x1e0d, KEY_MENU },
3276 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
3277 { 0x1e0f, KEY_MUTE },
3278 { 0x1e10, KEY_VOLUMEUP },
3279 { 0x1e11, KEY_VOLUMEDOWN },
3280 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
3281 { 0x1e14, KEY_UP },
3282 { 0x1e15, KEY_DOWN },
3283 { 0x1e16, KEY_LEFT },
3284 { 0x1e17, KEY_RIGHT },
3285 { 0x1e18, KEY_VIDEO }, /* Videos */
3286 { 0x1e19, KEY_AUDIO }, /* Music */
3287 /* 0x1e1a: Pictures - presume this means
3288 "Multimedia Home Platform" -
3289 no "PICTURES" key in input.h
3290 */
3291 { 0x1e1a, KEY_MHP },
3292
3293 { 0x1e1b, KEY_EPG }, /* Guide */
3294 { 0x1e1c, KEY_TV },
3295 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
3296 { 0x1e1f, KEY_EXIT }, /* back/exit */
3297 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
3298 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
3299 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
3300 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
3301 { 0x1e25, KEY_ENTER }, /* OK */
3302 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
3303 { 0x1e29, KEY_BLUE }, /* blue key */
3304 { 0x1e2e, KEY_GREEN }, /* green button */
3305 { 0x1e30, KEY_PAUSE }, /* pause */
3306 { 0x1e32, KEY_REWIND }, /* backward << */
3307 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
3308 { 0x1e35, KEY_PLAY },
3309 { 0x1e36, KEY_STOP },
3310 { 0x1e37, KEY_RECORD }, /* recording */
3311 { 0x1e38, KEY_YELLOW }, /* yellow key */
3312 { 0x1e3b, KEY_SELECT }, /* top right button */
3313 { 0x1e3c, KEY_ZOOM }, /* full */
3314 { 0x1e3d, KEY_POWER }, /* system power (green button) */
3315};
3316
3317struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
3318 .scan = ir_codes_rc5_hauppauge_new,
3319 .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
3320 .ir_type = IR_TYPE_RC5,
3321};
3322EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
3323
3324/* Terratec Cinergy Hybrid T USB XS FM
3325 Mauro Carvalho Chehab <mchehab@redhat.com>
3326 */
3327static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
3328 { 0x1441, KEY_HOME},
3329 { 0x1401, KEY_POWER2},
3330
3331 { 0x1442, KEY_MENU}, /* DVD menu */
3332 { 0x1443, KEY_SUBTITLE},
3333 { 0x1444, KEY_TEXT}, /* Teletext */
3334 { 0x1445, KEY_DELETE},
3335
3336 { 0x1402, KEY_1},
3337 { 0x1403, KEY_2},
3338 { 0x1404, KEY_3},
3339 { 0x1405, KEY_4},
3340 { 0x1406, KEY_5},
3341 { 0x1407, KEY_6},
3342 { 0x1408, KEY_7},
3343 { 0x1409, KEY_8},
3344 { 0x140a, KEY_9},
3345 { 0x140c, KEY_0},
3346
3347 { 0x140b, KEY_TUNER}, /* AV */
3348 { 0x140d, KEY_MODE}, /* A.B */
3349
3350 { 0x1446, KEY_TV},
3351 { 0x1447, KEY_DVD},
3352 { 0x1449, KEY_VIDEO},
3353 { 0x144a, KEY_RADIO}, /* Music */
3354 { 0x144b, KEY_CAMERA}, /* PIC */
3355
3356 { 0x1410, KEY_UP},
3357 { 0x1411, KEY_LEFT},
3358 { 0x1412, KEY_OK},
3359 { 0x1413, KEY_RIGHT},
3360 { 0x1414, KEY_DOWN},
3361
3362 { 0x140f, KEY_EPG},
3363 { 0x1416, KEY_INFO},
3364 { 0x144d, KEY_BACKSPACE},
3365
3366 { 0x141c, KEY_VOLUMEUP},
3367 { 0x141e, KEY_VOLUMEDOWN},
3368
3369 { 0x144c, KEY_PLAY},
3370 { 0x141d, KEY_MUTE},
3371
3372 { 0x141b, KEY_CHANNELUP},
3373 { 0x141f, KEY_CHANNELDOWN},
3374
3375 { 0x1417, KEY_RED},
3376 { 0x1418, KEY_GREEN},
3377 { 0x1419, KEY_YELLOW},
3378 { 0x141a, KEY_BLUE},
3379
3380 { 0x1458, KEY_RECORD},
3381 { 0x1448, KEY_STOP},
3382 { 0x1440, KEY_PAUSE},
3383
3384 { 0x1454, KEY_LAST},
3385 { 0x144e, KEY_REWIND},
3386 { 0x144f, KEY_FASTFORWARD},
3387 { 0x145c, KEY_NEXT},
3388};
3389struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
3390 .scan = ir_codes_nec_terratec_cinergy_xs,
3391 .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
3392 .ir_type = IR_TYPE_NEC,
3393};
3394EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
3395
3396
3397/* Leadtek Winfast TV USB II Deluxe remote
3398 Magnus Alm <magnus.alm@gmail.com>
3399 */
3400static struct ir_scancode ir_codes_winfast_usbii_deluxe[] = {
3401 { 0x62, KEY_0},
3402 { 0x75, KEY_1},
3403 { 0x76, KEY_2},
3404 { 0x77, KEY_3},
3405 { 0x79, KEY_4},
3406 { 0x7a, KEY_5},
3407 { 0x7b, KEY_6},
3408 { 0x7d, KEY_7},
3409 { 0x7e, KEY_8},
3410 { 0x7f, KEY_9},
3411
3412 { 0x38, KEY_CAMERA}, /* SNAPSHOT */
3413 { 0x37, KEY_RECORD}, /* RECORD */
3414 { 0x35, KEY_TIME}, /* TIMESHIFT */
3415
3416 { 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */
3417 { 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3418 { 0x64, KEY_MUTE}, /* MUTE */
3419
3420 { 0x21, KEY_CHANNEL}, /* SURF */
3421 { 0x7c, KEY_CHANNELUP}, /* CHANNELUP */
3422 { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3423 { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
3424
3425 { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
3426
3427 { 0x70, KEY_POWER2}, /* TV ON/OFF */
3428
3429 { 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */
3430 { 0x3a, KEY_NEW}, /* PIP */
3431 { 0x73, KEY_ZOOM}, /* FULLSECREEN */
3432
3433 { 0x66, KEY_INFO}, /* OSD (DISPLAY) */
3434
3435 { 0x31, KEY_DOT}, /* '.' */
3436 { 0x63, KEY_ENTER}, /* ENTER */
3437
3438};
3439struct ir_scancode_table ir_codes_winfast_usbii_deluxe_table = {
3440 .scan = ir_codes_winfast_usbii_deluxe,
3441 .size = ARRAY_SIZE(ir_codes_winfast_usbii_deluxe),
3442};
3443EXPORT_SYMBOL_GPL(ir_codes_winfast_usbii_deluxe_table);
3444
3445/* Kworld 315U
3446 */
3447static struct ir_scancode ir_codes_kworld_315u[] = {
3448 { 0x6143, KEY_POWER },
3449 { 0x6101, KEY_TUNER }, /* source */
3450 { 0x610b, KEY_ZOOM },
3451 { 0x6103, KEY_POWER2 }, /* shutdown */
3452
3453 { 0x6104, KEY_1 },
3454 { 0x6108, KEY_2 },
3455 { 0x6102, KEY_3 },
3456 { 0x6109, KEY_CHANNELUP },
3457
3458 { 0x610f, KEY_4 },
3459 { 0x6105, KEY_5 },
3460 { 0x6106, KEY_6 },
3461 { 0x6107, KEY_CHANNELDOWN },
3462
3463 { 0x610c, KEY_7 },
3464 { 0x610d, KEY_8 },
3465 { 0x610a, KEY_9 },
3466 { 0x610e, KEY_VOLUMEUP },
3467
3468 { 0x6110, KEY_LAST },
3469 { 0x6111, KEY_0 },
3470 { 0x6112, KEY_ENTER },
3471 { 0x6113, KEY_VOLUMEDOWN },
3472
3473 { 0x6114, KEY_RECORD },
3474 { 0x6115, KEY_STOP },
3475 { 0x6116, KEY_PLAY },
3476 { 0x6117, KEY_MUTE },
3477
3478 { 0x6118, KEY_UP },
3479 { 0x6119, KEY_DOWN },
3480 { 0x611a, KEY_LEFT },
3481 { 0x611b, KEY_RIGHT },
3482
3483 { 0x611c, KEY_RED },
3484 { 0x611d, KEY_GREEN },
3485 { 0x611e, KEY_YELLOW },
3486 { 0x611f, KEY_BLUE },
3487};
3488
3489struct ir_scancode_table ir_codes_kworld_315u_table = {
3490 .scan = ir_codes_kworld_315u,
3491 .size = ARRAY_SIZE(ir_codes_kworld_315u),
3492 .ir_type = IR_TYPE_NEC,
3493};
3494EXPORT_SYMBOL_GPL(ir_codes_kworld_315u_table);
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
index bfca26d51827..9374a006f43d 100644
--- a/drivers/media/IR/ir-keytable.c
+++ b/drivers/media/IR/ir-keytable.c
@@ -1,4 +1,4 @@
1/* ir-register.c - handle IR scancode->keycode tables 1/* ir-keytable.c - handle IR scancode->keycode tables
2 * 2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> 3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 * 4 *
@@ -15,384 +15,408 @@
15 15
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <media/ir-common.h> 18#include "ir-core-priv.h"
19 19
20#define IR_TAB_MIN_SIZE 32 20/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
21#define IR_TAB_MAX_SIZE 1024 21#define IR_TAB_MIN_SIZE 256
22#define IR_TAB_MAX_SIZE 8192
23
24/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
25#define IR_KEYPRESS_TIMEOUT 250
22 26
23/** 27/**
24 * ir_seek_table() - returns the element order on the table 28 * ir_resize_table() - resizes a scancode table if necessary
25 * @rc_tab: the ir_scancode_table with the keymap to be used 29 * @rc_tab: the ir_scancode_table to resize
26 * @scancode: the scancode that we're seeking 30 * @return: zero on success or a negative error code
27 * 31 *
28 * This routine is used by the input routines when a key is pressed at the 32 * This routine will shrink the ir_scancode_table if it has lots of
29 * IR. The scancode is received and needs to be converted into a keycode. 33 * unused entries and grow it if it is full.
30 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
31 * corresponding keycode from the table.
32 */ 34 */
33static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode) 35static int ir_resize_table(struct ir_scancode_table *rc_tab)
34{ 36{
35 int rc; 37 unsigned int oldalloc = rc_tab->alloc;
36 unsigned long flags; 38 unsigned int newalloc = oldalloc;
37 struct ir_scancode *keymap = rc_tab->scan; 39 struct ir_scancode *oldscan = rc_tab->scan;
40 struct ir_scancode *newscan;
41
42 if (rc_tab->size == rc_tab->len) {
43 /* All entries in use -> grow keytable */
44 if (rc_tab->alloc >= IR_TAB_MAX_SIZE)
45 return -ENOMEM;
38 46
39 spin_lock_irqsave(&rc_tab->lock, flags); 47 newalloc *= 2;
48 IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
49 }
40 50
41 /* FIXME: replace it by a binary search */ 51 if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
52 /* Less than 1/3 of entries in use -> shrink keytable */
53 newalloc /= 2;
54 IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
55 }
42 56
43 for (rc = 0; rc < rc_tab->size; rc++) 57 if (newalloc == oldalloc)
44 if (keymap[rc].scancode == scancode) 58 return 0;
45 goto exit;
46 59
47 /* Not found */ 60 newscan = kmalloc(newalloc, GFP_ATOMIC);
48 rc = -EINVAL; 61 if (!newscan) {
62 IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
63 return -ENOMEM;
64 }
49 65
50exit: 66 memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode));
51 spin_unlock_irqrestore(&rc_tab->lock, flags); 67 rc_tab->scan = newscan;
52 return rc; 68 rc_tab->alloc = newalloc;
69 rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
70 kfree(oldscan);
71 return 0;
53} 72}
54 73
55/** 74/**
56 * ir_roundup_tablesize() - gets an optimum value for the table size 75 * ir_do_setkeycode() - internal function to set a keycode in the
57 * @n_elems: minimum number of entries to store keycodes 76 * scancode->keycode table
58 * 77 * @dev: the struct input_dev device descriptor
59 * This routine is used to choose the keycode table size. 78 * @rc_tab: the struct ir_scancode_table to set the keycode in
79 * @scancode: the scancode for the ir command
80 * @keycode: the keycode for the ir command
81 * @resize: whether the keytable may be shrunk
82 * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
60 * 83 *
61 * In order to have some empty space for new keycodes, 84 * This routine is used internally to manipulate the scancode->keycode table.
62 * and knowing in advance that kmalloc allocates only power of two 85 * The caller has to hold @rc_tab->lock.
63 * segments, it optimizes the allocated space to have some spare space
64 * for those new keycodes by using the maximum number of entries that
65 * will be effectively be allocated by kmalloc.
66 * In order to reduce the quantity of table resizes, it has a minimum
67 * table size of IR_TAB_MIN_SIZE.
68 */ 86 */
69static int ir_roundup_tablesize(int n_elems) 87static int ir_do_setkeycode(struct input_dev *dev,
88 struct ir_scancode_table *rc_tab,
89 unsigned scancode, unsigned keycode,
90 bool resize)
70{ 91{
71 size_t size; 92 unsigned int i;
72 93 int old_keycode = KEY_RESERVED;
73 if (n_elems < IR_TAB_MIN_SIZE) 94 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
74 n_elems = IR_TAB_MIN_SIZE;
75 95
76 /* 96 /*
77 * As kmalloc only allocates sizes of power of two, get as 97 * Unfortunately, some hardware-based IR decoders don't provide
78 * much entries as possible for the allocated memory segment 98 * all bits for the complete IR code. In general, they provide only
99 * the command part of the IR code. Yet, as it is possible to replace
100 * the provided IR with another one, it is needed to allow loading
101 * IR tables from other remotes. So,
79 */ 102 */
80 size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode)); 103 if (ir_dev->props && ir_dev->props->scanmask) {
81 n_elems = size / sizeof(struct ir_scancode); 104 scancode &= ir_dev->props->scanmask;
105 }
82 106
83 return n_elems; 107 /* First check if we already have a mapping for this ir command */
108 for (i = 0; i < rc_tab->len; i++) {
109 /* Keytable is sorted from lowest to highest scancode */
110 if (rc_tab->scan[i].scancode > scancode)
111 break;
112 else if (rc_tab->scan[i].scancode < scancode)
113 continue;
114
115 old_keycode = rc_tab->scan[i].keycode;
116 rc_tab->scan[i].keycode = keycode;
117
118 /* Did the user wish to remove the mapping? */
119 if (keycode == KEY_RESERVED || keycode == KEY_UNKNOWN) {
120 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
121 i, scancode);
122 rc_tab->len--;
123 memmove(&rc_tab->scan[i], &rc_tab->scan[i + 1],
124 (rc_tab->len - i) * sizeof(struct ir_scancode));
125 }
126
127 /* Possibly shrink the keytable, failure is not a problem */
128 ir_resize_table(rc_tab);
129 break;
130 }
131
132 if (old_keycode == KEY_RESERVED && keycode != KEY_RESERVED) {
133 /* No previous mapping found, we might need to grow the table */
134 if (resize && ir_resize_table(rc_tab))
135 return -ENOMEM;
136
137 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
138 i, scancode, keycode);
139
140 /* i is the proper index to insert our new keycode */
141 memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
142 (rc_tab->len - i) * sizeof(struct ir_scancode));
143 rc_tab->scan[i].scancode = scancode;
144 rc_tab->scan[i].keycode = keycode;
145 rc_tab->len++;
146 set_bit(keycode, dev->keybit);
147 } else {
148 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
149 i, scancode, keycode);
150 /* A previous mapping was updated... */
151 clear_bit(old_keycode, dev->keybit);
152 /* ...but another scancode might use the same keycode */
153 for (i = 0; i < rc_tab->len; i++) {
154 if (rc_tab->scan[i].keycode == old_keycode) {
155 set_bit(old_keycode, dev->keybit);
156 break;
157 }
158 }
159 }
160
161 return 0;
84} 162}
85 163
86/** 164/**
87 * ir_copy_table() - copies a keytable, discarding the unused entries 165 * ir_setkeycode() - set a keycode in the scancode->keycode table
88 * @destin: destin table 166 * @dev: the struct input_dev device descriptor
89 * @origin: origin table 167 * @scancode: the desired scancode
168 * @keycode: result
169 * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
90 * 170 *
91 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED 171 * This routine is used to handle evdev EVIOCSKEY ioctl.
92 * Also copies table size and table protocol.
93 * NOTE: It shouldn't copy the lock field
94 */ 172 */
95 173static int ir_setkeycode(struct input_dev *dev,
96static int ir_copy_table(struct ir_scancode_table *destin, 174 unsigned int scancode, unsigned int keycode)
97 const struct ir_scancode_table *origin)
98{ 175{
99 int i, j = 0; 176 int rc;
100 177 unsigned long flags;
101 for (i = 0; i < origin->size; i++) { 178 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
102 if (origin->scan[i].keycode == KEY_UNKNOWN || 179 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
103 origin->scan[i].keycode == KEY_RESERVED)
104 continue;
105 180
106 memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode)); 181 spin_lock_irqsave(&rc_tab->lock, flags);
107 j++; 182 rc = ir_do_setkeycode(dev, rc_tab, scancode, keycode, true);
108 } 183 spin_unlock_irqrestore(&rc_tab->lock, flags);
109 destin->size = j; 184 return rc;
110 destin->ir_type = origin->ir_type; 185}
111 186
112 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size); 187/**
188 * ir_setkeytable() - sets several entries in the scancode->keycode table
189 * @dev: the struct input_dev device descriptor
190 * @to: the struct ir_scancode_table to copy entries to
191 * @from: the struct ir_scancode_table to copy entries from
192 * @return: -EINVAL if all keycodes could not be inserted, otherwise zero.
193 *
194 * This routine is used to handle table initialization.
195 */
196static int ir_setkeytable(struct input_dev *dev,
197 struct ir_scancode_table *to,
198 const struct ir_scancode_table *from)
199{
200 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
201 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
202 unsigned long flags;
203 unsigned int i;
204 int rc = 0;
113 205
114 return 0; 206 spin_lock_irqsave(&rc_tab->lock, flags);
207 for (i = 0; i < from->size; i++) {
208 rc = ir_do_setkeycode(dev, to, from->scan[i].scancode,
209 from->scan[i].keycode, false);
210 if (rc)
211 break;
212 }
213 spin_unlock_irqrestore(&rc_tab->lock, flags);
214 return rc;
115} 215}
116 216
117/** 217/**
118 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table 218 * ir_getkeycode() - get a keycode from the scancode->keycode table
119 * @dev: the struct input_dev device descriptor 219 * @dev: the struct input_dev device descriptor
120 * @scancode: the desired scancode 220 * @scancode: the desired scancode
121 * @keycode: the keycode to be retorned. 221 * @keycode: used to return the keycode, if found, or KEY_RESERVED
222 * @return: always returns zero.
122 * 223 *
123 * This routine is used to handle evdev EVIOCGKEY ioctl. 224 * This routine is used to handle evdev EVIOCGKEY ioctl.
124 * If the key is not found, returns -EINVAL, otherwise, returns 0.
125 */ 225 */
126static int ir_getkeycode(struct input_dev *dev, 226static int ir_getkeycode(struct input_dev *dev,
127 unsigned int scancode, unsigned int *keycode) 227 unsigned int scancode, unsigned int *keycode)
128{ 228{
129 int elem; 229 int start, end, mid;
230 unsigned long flags;
231 int key = KEY_RESERVED;
130 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 232 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
131 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; 233 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
132 234
133 elem = ir_seek_table(rc_tab, scancode); 235 spin_lock_irqsave(&rc_tab->lock, flags);
134 if (elem >= 0) { 236 start = 0;
135 *keycode = rc_tab->scan[elem].keycode; 237 end = rc_tab->len - 1;
136 return 0; 238 while (start <= end) {
239 mid = (start + end) / 2;
240 if (rc_tab->scan[mid].scancode < scancode)
241 start = mid + 1;
242 else if (rc_tab->scan[mid].scancode > scancode)
243 end = mid - 1;
244 else {
245 key = rc_tab->scan[mid].keycode;
246 break;
247 }
137 } 248 }
249 spin_unlock_irqrestore(&rc_tab->lock, flags);
138 250
139 /* 251 if (key == KEY_RESERVED)
140 * Scancode not found and table can't be expanded 252 IR_dprintk(1, "unknown key for scancode 0x%04x\n",
141 */ 253 scancode);
142 if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
143 return -EINVAL;
144 254
145 /* 255 *keycode = key;
146 * If is there extra space, returns KEY_RESERVED,
147 * otherwise, input core won't let ir_setkeycode to work
148 */
149 *keycode = KEY_RESERVED;
150 return 0; 256 return 0;
151} 257}
152 258
153/** 259/**
154 * ir_is_resize_needed() - Check if the table needs rezise 260 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
155 * @table: keycode table that may need to resize 261 * @input_dev: the struct input_dev descriptor of the device
156 * @n_elems: minimum number of entries to store keycodes 262 * @scancode: the scancode that we're seeking
157 *
158 * Considering that kmalloc uses power of two storage areas, this
159 * routine detects if the real alloced size will change. If not, it
160 * just returns without doing nothing. Otherwise, it will extend or
161 * reduce the table size to meet the new needs.
162 * 263 *
163 * It returns 0 if no resize is needed, 1 otherwise. 264 * This routine is used by the input routines when a key is pressed at the
265 * IR. The scancode is received and needs to be converted into a keycode.
266 * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the
267 * corresponding keycode from the table.
164 */ 268 */
165static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems) 269u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
166{ 270{
167 int cur_size = ir_roundup_tablesize(table->size); 271 int keycode;
168 int new_size = ir_roundup_tablesize(n_elems);
169
170 if (cur_size == new_size)
171 return 0;
172 272
173 /* Resize is needed */ 273 ir_getkeycode(dev, scancode, &keycode);
174 return 1; 274 if (keycode != KEY_RESERVED)
275 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
276 dev->name, scancode, keycode);
277 return keycode;
175} 278}
279EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
176 280
177/** 281/**
178 * ir_delete_key() - remove a keycode from the table 282 * ir_keyup() - generates input event to cleanup a key press
179 * @rc_tab: keycode table 283 * @ir: the struct ir_input_dev descriptor of the device
180 * @elem: element to be removed
181 * 284 *
285 * This routine is used to signal that a key has been released on the
286 * remote control. It reports a keyup input event via input_report_key().
182 */ 287 */
183static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem) 288static void ir_keyup(struct ir_input_dev *ir)
184{ 289{
185 unsigned long flags = 0; 290 if (!ir->keypressed)
186 int newsize = rc_tab->size - 1; 291 return;
187 int resize = ir_is_resize_needed(rc_tab, newsize);
188 struct ir_scancode *oldkeymap = rc_tab->scan;
189 struct ir_scancode *newkeymap = NULL;
190
191 if (resize)
192 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
193 sizeof(*newkeymap), GFP_ATOMIC);
194
195 /* There's no memory for resize. Keep the old table */
196 if (!resize || !newkeymap) {
197 newkeymap = oldkeymap;
198
199 /* We'll modify the live table. Lock it */
200 spin_lock_irqsave(&rc_tab->lock, flags);
201 }
202 292
203 /* 293 IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode);
204 * Copy the elements before the one that will be deleted 294 input_report_key(ir->input_dev, ir->last_keycode, 0);
205 * if (!resize), both oldkeymap and newkeymap points 295 input_sync(ir->input_dev);
206 * to the same place, so, there's no need to copy 296 ir->keypressed = false;
207 */ 297}
208 if (resize && elem > 0) 298
209 memcpy(newkeymap, oldkeymap, 299/**
210 elem * sizeof(*newkeymap)); 300 * ir_timer_keyup() - generates a keyup event after a timeout
301 * @cookie: a pointer to struct ir_input_dev passed to setup_timer()
302 *
303 * This routine will generate a keyup event some time after a keydown event
304 * is generated when no further activity has been detected.
305 */
306static void ir_timer_keyup(unsigned long cookie)
307{
308 struct ir_input_dev *ir = (struct ir_input_dev *)cookie;
309 unsigned long flags;
211 310
212 /* 311 /*
213 * Copy the other elements overwriting the element to be removed 312 * ir->keyup_jiffies is used to prevent a race condition if a
214 * This operation applies to both resize and non-resize case 313 * hardware interrupt occurs at this point and the keyup timer
314 * event is moved further into the future as a result.
315 *
316 * The timer will then be reactivated and this function called
317 * again in the future. We need to exit gracefully in that case
318 * to allow the input subsystem to do its auto-repeat magic or
319 * a keyup event might follow immediately after the keydown.
215 */ 320 */
216 if (elem < newsize) 321 spin_lock_irqsave(&ir->keylock, flags);
217 memcpy(&newkeymap[elem], &oldkeymap[elem + 1], 322 if (time_is_after_eq_jiffies(ir->keyup_jiffies))
218 (newsize - elem) * sizeof(*newkeymap)); 323 ir_keyup(ir);
219 324 spin_unlock_irqrestore(&ir->keylock, flags);
220 if (resize) {
221 /*
222 * As the copy happened to a temporary table, only here
223 * it needs to lock while replacing the table pointers
224 * to use the new table
225 */
226 spin_lock_irqsave(&rc_tab->lock, flags);
227 rc_tab->size = newsize;
228 rc_tab->scan = newkeymap;
229 spin_unlock_irqrestore(&rc_tab->lock, flags);
230
231 /* Frees the old keytable */
232 kfree(oldkeymap);
233 } else {
234 rc_tab->size = newsize;
235 spin_unlock_irqrestore(&rc_tab->lock, flags);
236 }
237} 325}
238 326
239/** 327/**
240 * ir_insert_key() - insert a keycode at the table 328 * ir_repeat() - notifies the IR core that a key is still pressed
241 * @rc_tab: keycode table 329 * @dev: the struct input_dev descriptor of the device
242 * @scancode: the desired scancode
243 * @keycode: the keycode to be retorned.
244 * 330 *
331 * This routine is used by IR decoders when a repeat message which does
332 * not include the necessary bits to reproduce the scancode has been
333 * received.
245 */ 334 */
246static int ir_insert_key(struct ir_scancode_table *rc_tab, 335void ir_repeat(struct input_dev *dev)
247 int scancode, int keycode)
248{ 336{
249 unsigned long flags; 337 unsigned long flags;
250 int elem = rc_tab->size; 338 struct ir_input_dev *ir = input_get_drvdata(dev);
251 int newsize = rc_tab->size + 1;
252 int resize = ir_is_resize_needed(rc_tab, newsize);
253 struct ir_scancode *oldkeymap = rc_tab->scan;
254 struct ir_scancode *newkeymap;
255
256 if (resize) {
257 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
258 sizeof(*newkeymap), GFP_ATOMIC);
259 if (!newkeymap)
260 return -ENOMEM;
261 339
262 memcpy(newkeymap, oldkeymap, 340 spin_lock_irqsave(&ir->keylock, flags);
263 rc_tab->size * sizeof(*newkeymap));
264 } else
265 newkeymap = oldkeymap;
266 341
267 /* Stores the new code at the table */ 342 if (!ir->keypressed)
268 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n", 343 goto out;
269 rc_tab->size, scancode, keycode);
270 344
271 spin_lock_irqsave(&rc_tab->lock, flags); 345 ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
272 rc_tab->size = newsize; 346 mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
273 if (resize) {
274 rc_tab->scan = newkeymap;
275 kfree(oldkeymap);
276 }
277 newkeymap[elem].scancode = scancode;
278 newkeymap[elem].keycode = keycode;
279 spin_unlock_irqrestore(&rc_tab->lock, flags);
280 347
281 return 0; 348out:
349 spin_unlock_irqrestore(&ir->keylock, flags);
282} 350}
351EXPORT_SYMBOL_GPL(ir_repeat);
283 352
284/** 353/**
285 * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table 354 * ir_keydown() - generates input event for a key press
286 * @dev: the struct input_dev device descriptor 355 * @dev: the struct input_dev descriptor of the device
287 * @scancode: the desired scancode 356 * @scancode: the scancode that we're seeking
288 * @keycode: the keycode to be retorned. 357 * @toggle: the toggle value (protocol dependent, if the protocol doesn't
358 * support toggle values, this should be set to zero)
289 * 359 *
290 * This routine is used to handle evdev EVIOCSKEY ioctl. 360 * This routine is used by the input routines when a key is pressed at the
291 * There's one caveat here: how can we increase the size of the table? 361 * IR. It gets the keycode for a scancode and reports an input event via
292 * If the key is not found, returns -EINVAL, otherwise, returns 0. 362 * input_report_key().
293 */ 363 */
294static int ir_setkeycode(struct input_dev *dev, 364void ir_keydown(struct input_dev *dev, int scancode, u8 toggle)
295 unsigned int scancode, unsigned int keycode)
296{ 365{
297 int rc = 0;
298 struct ir_input_dev *ir_dev = input_get_drvdata(dev);
299 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
300 struct ir_scancode *keymap = rc_tab->scan;
301 unsigned long flags; 366 unsigned long flags;
367 struct ir_input_dev *ir = input_get_drvdata(dev);
302 368
303 /* 369 u32 keycode = ir_g_keycode_from_table(dev, scancode);
304 * Handle keycode table deletions
305 *
306 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
307 * deal as a trial to remove an existing scancode attribution
308 * if table become too big, reduce it to save space
309 */
310 if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
311 rc = ir_seek_table(rc_tab, scancode);
312 if (rc < 0)
313 return 0;
314
315 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
316 clear_bit(keymap[rc].keycode, dev->keybit);
317 ir_delete_key(rc_tab, rc);
318
319 return 0;
320 }
321 370
322 /* 371 spin_lock_irqsave(&ir->keylock, flags);
323 * Handle keycode replacements
324 *
325 * If the scancode exists, just replace by the new value
326 */
327 rc = ir_seek_table(rc_tab, scancode);
328 if (rc >= 0) {
329 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
330 rc, scancode, keycode);
331 372
332 clear_bit(keymap[rc].keycode, dev->keybit); 373 /* Repeat event? */
374 if (ir->keypressed &&
375 ir->last_scancode == scancode &&
376 ir->last_toggle == toggle)
377 goto set_timer;
333 378
334 spin_lock_irqsave(&rc_tab->lock, flags); 379 /* Release old keypress */
335 keymap[rc].keycode = keycode; 380 ir_keyup(ir);
336 spin_unlock_irqrestore(&rc_tab->lock, flags);
337 381
338 set_bit(keycode, dev->keybit); 382 ir->last_scancode = scancode;
383 ir->last_toggle = toggle;
384 ir->last_keycode = keycode;
339 385
340 return 0; 386 if (keycode == KEY_RESERVED)
341 } 387 goto out;
342 388
343 /* 389 /* Register a keypress */
344 * Handle new scancode inserts 390 ir->keypressed = true;
345 * 391 IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
346 * reallocate table if needed and insert a new keycode 392 dev->name, keycode, scancode);
347 */ 393 input_report_key(dev, ir->last_keycode, 1);
394 input_sync(dev);
348 395
349 /* Avoid growing the table indefinitely */ 396set_timer:
350 if (rc_tab->size + 1 > IR_TAB_MAX_SIZE) 397 ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
351 return -EINVAL; 398 mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
352 399out:
353 rc = ir_insert_key(rc_tab, scancode, keycode); 400 spin_unlock_irqrestore(&ir->keylock, flags);
354 if (rc < 0)
355 return rc;
356 set_bit(keycode, dev->keybit);
357
358 return 0;
359} 401}
402EXPORT_SYMBOL_GPL(ir_keydown);
360 403
361/** 404static int ir_open(struct input_dev *input_dev)
362 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
363 * @input_dev: the struct input_dev descriptor of the device
364 * @scancode: the scancode that we're seeking
365 *
366 * This routine is used by the input routines when a key is pressed at the
367 * IR. The scancode is received and needs to be converted into a keycode.
368 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
369 * corresponding keycode from the table.
370 */
371u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
372{ 405{
373 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 406 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
374 struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
375 struct ir_scancode *keymap = rc_tab->scan;
376 int elem;
377 407
378 elem = ir_seek_table(rc_tab, scancode); 408 return ir_dev->props->open(ir_dev->props->priv);
379 if (elem >= 0) { 409}
380 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
381 dev->name, scancode, keymap[elem].keycode);
382
383 return rc_tab->scan[elem].keycode;
384 }
385 410
386 printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n", 411static void ir_close(struct input_dev *input_dev)
387 dev->name, scancode); 412{
413 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
388 414
389 /* Reports userspace that an unknown keycode were got */ 415 ir_dev->props->close(ir_dev->props->priv);
390 return KEY_RESERVED;
391} 416}
392EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
393 417
394/** 418/**
395 * ir_input_register() - sets the IR keycode table and add the handlers 419 * __ir_input_register() - sets the IR keycode table and add the handlers
396 * for keymap table get/set 420 * for keymap table get/set
397 * @input_dev: the struct input_dev descriptor of the device 421 * @input_dev: the struct input_dev descriptor of the device
398 * @rc_tab: the struct ir_scancode_table table of scancode/keymap 422 * @rc_tab: the struct ir_scancode_table table of scancode/keymap
@@ -402,13 +426,13 @@ EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
402 * It will register the input/evdev interface for the device and 426 * It will register the input/evdev interface for the device and
403 * register the syfs code for IR class 427 * register the syfs code for IR class
404 */ 428 */
405int ir_input_register(struct input_dev *input_dev, 429int __ir_input_register(struct input_dev *input_dev,
406 const struct ir_scancode_table *rc_tab, 430 const struct ir_scancode_table *rc_tab,
407 const struct ir_dev_props *props) 431 const struct ir_dev_props *props,
432 const char *driver_name)
408{ 433{
409 struct ir_input_dev *ir_dev; 434 struct ir_input_dev *ir_dev;
410 struct ir_scancode *keymap = rc_tab->scan; 435 int rc;
411 int i, rc;
412 436
413 if (rc_tab->scan == NULL || !rc_tab->size) 437 if (rc_tab->scan == NULL || !rc_tab->size)
414 return -EINVAL; 438 return -EINVAL;
@@ -417,57 +441,77 @@ int ir_input_register(struct input_dev *input_dev,
417 if (!ir_dev) 441 if (!ir_dev)
418 return -ENOMEM; 442 return -ENOMEM;
419 443
420 spin_lock_init(&ir_dev->rc_tab.lock); 444 ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name);
421 445 if (!ir_dev->driver_name) {
422 ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size); 446 rc = -ENOMEM;
423 ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size * 447 goto out_dev;
424 sizeof(struct ir_scancode), GFP_KERNEL);
425 if (!ir_dev->rc_tab.scan) {
426 kfree(ir_dev);
427 return -ENOMEM;
428 } 448 }
429 449
430 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", 450 input_dev->getkeycode = ir_getkeycode;
431 ir_dev->rc_tab.size, 451 input_dev->setkeycode = ir_setkeycode;
432 ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan)); 452 input_set_drvdata(input_dev, ir_dev);
453 ir_dev->input_dev = input_dev;
433 454
434 ir_copy_table(&ir_dev->rc_tab, rc_tab); 455 spin_lock_init(&ir_dev->rc_tab.lock);
435 ir_dev->props = props; 456 spin_lock_init(&ir_dev->keylock);
457 setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev);
458
459 ir_dev->rc_tab.name = rc_tab->name;
460 ir_dev->rc_tab.ir_type = rc_tab->ir_type;
461 ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size *
462 sizeof(struct ir_scancode));
463 ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL);
464 ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode);
465 if (props) {
466 ir_dev->props = props;
467 if (props->open)
468 input_dev->open = ir_open;
469 if (props->close)
470 input_dev->close = ir_close;
471 }
436 472
437 /* set the bits for the keys */ 473 if (!ir_dev->rc_tab.scan) {
438 IR_dprintk(1, "key map size: %d\n", rc_tab->size); 474 rc = -ENOMEM;
439 for (i = 0; i < rc_tab->size; i++) { 475 goto out_name;
440 IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
441 i, keymap[i].keycode);
442 set_bit(keymap[i].keycode, input_dev->keybit);
443 } 476 }
444 clear_bit(0, input_dev->keybit); 477
478 IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
479 ir_dev->rc_tab.size, ir_dev->rc_tab.alloc);
445 480
446 set_bit(EV_KEY, input_dev->evbit); 481 set_bit(EV_KEY, input_dev->evbit);
482 set_bit(EV_REP, input_dev->evbit);
447 483
448 input_dev->getkeycode = ir_getkeycode; 484 if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) {
449 input_dev->setkeycode = ir_setkeycode; 485 rc = -ENOMEM;
450 input_set_drvdata(input_dev, ir_dev); 486 goto out_table;
487 }
451 488
452 rc = input_register_device(input_dev); 489 rc = ir_register_class(input_dev);
453 if (rc < 0) 490 if (rc < 0)
454 goto err; 491 goto out_table;
455 492
456 rc = ir_register_class(input_dev); 493 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
457 if (rc < 0) { 494 rc = ir_raw_event_register(input_dev);
458 input_unregister_device(input_dev); 495 if (rc < 0)
459 goto err; 496 goto out_event;
460 } 497 }
461 498
499 IR_dprintk(1, "Registered input device on %s for %s remote.\n",
500 driver_name, rc_tab->name);
501
462 return 0; 502 return 0;
463 503
464err: 504out_event:
465 kfree(rc_tab->scan); 505 ir_unregister_class(input_dev);
506out_table:
507 kfree(ir_dev->rc_tab.scan);
508out_name:
509 kfree(ir_dev->driver_name);
510out_dev:
466 kfree(ir_dev); 511 kfree(ir_dev);
467 input_set_drvdata(input_dev, NULL);
468 return rc; 512 return rc;
469} 513}
470EXPORT_SYMBOL_GPL(ir_input_register); 514EXPORT_SYMBOL_GPL(__ir_input_register);
471 515
472/** 516/**
473 * ir_input_unregister() - unregisters IR and frees resources 517 * ir_input_unregister() - unregisters IR and frees resources
@@ -475,9 +519,9 @@ EXPORT_SYMBOL_GPL(ir_input_register);
475 519
476 * This routine is used to free memory and de-register interfaces. 520 * This routine is used to free memory and de-register interfaces.
477 */ 521 */
478void ir_input_unregister(struct input_dev *dev) 522void ir_input_unregister(struct input_dev *input_dev)
479{ 523{
480 struct ir_input_dev *ir_dev = input_get_drvdata(dev); 524 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
481 struct ir_scancode_table *rc_tab; 525 struct ir_scancode_table *rc_tab;
482 526
483 if (!ir_dev) 527 if (!ir_dev)
@@ -485,15 +529,18 @@ void ir_input_unregister(struct input_dev *dev)
485 529
486 IR_dprintk(1, "Freed keycode table\n"); 530 IR_dprintk(1, "Freed keycode table\n");
487 531
532 del_timer_sync(&ir_dev->timer_keyup);
533 if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
534 ir_raw_event_unregister(input_dev);
488 rc_tab = &ir_dev->rc_tab; 535 rc_tab = &ir_dev->rc_tab;
489 rc_tab->size = 0; 536 rc_tab->size = 0;
490 kfree(rc_tab->scan); 537 kfree(rc_tab->scan);
491 rc_tab->scan = NULL; 538 rc_tab->scan = NULL;
492 539
493 ir_unregister_class(dev); 540 ir_unregister_class(input_dev);
494 541
542 kfree(ir_dev->driver_name);
495 kfree(ir_dev); 543 kfree(ir_dev);
496 input_unregister_device(dev);
497} 544}
498EXPORT_SYMBOL_GPL(ir_input_unregister); 545EXPORT_SYMBOL_GPL(ir_input_unregister);
499 546
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
new file mode 100644
index 000000000000..ba79233112ef
--- /dev/null
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -0,0 +1,328 @@
1/* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/bitrev.h>
16#include "ir-core-priv.h"
17
18#define NEC_NBITS 32
19#define NEC_UNIT 562500 /* ns */
20#define NEC_HEADER_PULSE (16 * NEC_UNIT)
21#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
22#define NEC_HEADER_SPACE (8 * NEC_UNIT)
23#define NEC_REPEAT_SPACE (8 * NEC_UNIT)
24#define NEC_BIT_PULSE (1 * NEC_UNIT)
25#define NEC_BIT_0_SPACE (1 * NEC_UNIT)
26#define NEC_BIT_1_SPACE (3 * NEC_UNIT)
27#define NEC_TRAILER_PULSE (1 * NEC_UNIT)
28#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
29
30/* Used to register nec_decoder clients */
31static LIST_HEAD(decoder_list);
32static DEFINE_SPINLOCK(decoder_lock);
33
34enum nec_state {
35 STATE_INACTIVE,
36 STATE_HEADER_SPACE,
37 STATE_BIT_PULSE,
38 STATE_BIT_SPACE,
39 STATE_TRAILER_PULSE,
40 STATE_TRAILER_SPACE,
41};
42
43struct decoder_data {
44 struct list_head list;
45 struct ir_input_dev *ir_dev;
46 int enabled:1;
47
48 /* State machine control */
49 enum nec_state state;
50 u32 nec_bits;
51 unsigned count;
52};
53
54
55/**
56 * get_decoder_data() - gets decoder data
57 * @input_dev: input device
58 *
59 * Returns the struct decoder_data that corresponds to a device
60 */
61static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
62{
63 struct decoder_data *data = NULL;
64
65 spin_lock(&decoder_lock);
66 list_for_each_entry(data, &decoder_list, list) {
67 if (data->ir_dev == ir_dev)
68 break;
69 }
70 spin_unlock(&decoder_lock);
71 return data;
72}
73
74static ssize_t store_enabled(struct device *d,
75 struct device_attribute *mattr,
76 const char *buf,
77 size_t len)
78{
79 unsigned long value;
80 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
81 struct decoder_data *data = get_decoder_data(ir_dev);
82
83 if (!data)
84 return -EINVAL;
85
86 if (strict_strtoul(buf, 10, &value) || value > 1)
87 return -EINVAL;
88
89 data->enabled = value;
90
91 return len;
92}
93
94static ssize_t show_enabled(struct device *d,
95 struct device_attribute *mattr, char *buf)
96{
97 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
98 struct decoder_data *data = get_decoder_data(ir_dev);
99
100 if (!data)
101 return -EINVAL;
102
103 if (data->enabled)
104 return sprintf(buf, "1\n");
105 else
106 return sprintf(buf, "0\n");
107}
108
109static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
110
111static struct attribute *decoder_attributes[] = {
112 &dev_attr_enabled.attr,
113 NULL
114};
115
116static struct attribute_group decoder_attribute_group = {
117 .name = "nec_decoder",
118 .attrs = decoder_attributes,
119};
120
121/**
122 * ir_nec_decode() - Decode one NEC pulse or space
123 * @input_dev: the struct input_dev descriptor of the device
124 * @duration: the struct ir_raw_event descriptor of the pulse/space
125 *
126 * This function returns -EINVAL if the pulse violates the state machine
127 */
128static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
129{
130 struct decoder_data *data;
131 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
132 u32 scancode;
133 u8 address, not_address, command, not_command;
134
135 data = get_decoder_data(ir_dev);
136 if (!data)
137 return -EINVAL;
138
139 if (!data->enabled)
140 return 0;
141
142 if (IS_RESET(ev)) {
143 data->state = STATE_INACTIVE;
144 return 0;
145 }
146
147 IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
148 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
149
150 switch (data->state) {
151
152 case STATE_INACTIVE:
153 if (!ev.pulse)
154 break;
155
156 if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
157 !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
158 break;
159
160 data->count = 0;
161 data->state = STATE_HEADER_SPACE;
162 return 0;
163
164 case STATE_HEADER_SPACE:
165 if (ev.pulse)
166 break;
167
168 if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
169 data->state = STATE_BIT_PULSE;
170 return 0;
171 } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
172 ir_repeat(input_dev);
173 IR_dprintk(1, "Repeat last key\n");
174 data->state = STATE_TRAILER_PULSE;
175 return 0;
176 }
177
178 break;
179
180 case STATE_BIT_PULSE:
181 if (!ev.pulse)
182 break;
183
184 if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
185 break;
186
187 data->state = STATE_BIT_SPACE;
188 return 0;
189
190 case STATE_BIT_SPACE:
191 if (ev.pulse)
192 break;
193
194 data->nec_bits <<= 1;
195 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
196 data->nec_bits |= 1;
197 else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
198 break;
199 data->count++;
200
201 if (data->count == NEC_NBITS)
202 data->state = STATE_TRAILER_PULSE;
203 else
204 data->state = STATE_BIT_PULSE;
205
206 return 0;
207
208 case STATE_TRAILER_PULSE:
209 if (!ev.pulse)
210 break;
211
212 if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
213 break;
214
215 data->state = STATE_TRAILER_SPACE;
216 return 0;
217
218 case STATE_TRAILER_SPACE:
219 if (ev.pulse)
220 break;
221
222 if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
223 break;
224
225 address = bitrev8((data->nec_bits >> 24) & 0xff);
226 not_address = bitrev8((data->nec_bits >> 16) & 0xff);
227 command = bitrev8((data->nec_bits >> 8) & 0xff);
228 not_command = bitrev8((data->nec_bits >> 0) & 0xff);
229
230 if ((command ^ not_command) != 0xff) {
231 IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
232 data->nec_bits);
233 break;
234 }
235
236 if ((address ^ not_address) != 0xff) {
237 /* Extended NEC */
238 scancode = address << 16 |
239 not_address << 8 |
240 command;
241 IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
242 } else {
243 /* Normal NEC */
244 scancode = address << 8 | command;
245 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
246 }
247
248 ir_keydown(input_dev, scancode, 0);
249 data->state = STATE_INACTIVE;
250 return 0;
251 }
252
253 IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
254 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
255 data->state = STATE_INACTIVE;
256 return -EINVAL;
257}
258
259static int ir_nec_register(struct input_dev *input_dev)
260{
261 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
262 struct decoder_data *data;
263 int rc;
264
265 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
266 if (rc < 0)
267 return rc;
268
269 data = kzalloc(sizeof(*data), GFP_KERNEL);
270 if (!data) {
271 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
272 return -ENOMEM;
273 }
274
275 data->ir_dev = ir_dev;
276 data->enabled = 1;
277
278 spin_lock(&decoder_lock);
279 list_add_tail(&data->list, &decoder_list);
280 spin_unlock(&decoder_lock);
281
282 return 0;
283}
284
285static int ir_nec_unregister(struct input_dev *input_dev)
286{
287 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
288 static struct decoder_data *data;
289
290 data = get_decoder_data(ir_dev);
291 if (!data)
292 return 0;
293
294 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
295
296 spin_lock(&decoder_lock);
297 list_del(&data->list);
298 spin_unlock(&decoder_lock);
299
300 return 0;
301}
302
303static struct ir_raw_handler nec_handler = {
304 .decode = ir_nec_decode,
305 .raw_register = ir_nec_register,
306 .raw_unregister = ir_nec_unregister,
307};
308
309static int __init ir_nec_decode_init(void)
310{
311 ir_raw_handler_register(&nec_handler);
312
313 printk(KERN_INFO "IR NEC protocol handler initialized\n");
314 return 0;
315}
316
317static void __exit ir_nec_decode_exit(void)
318{
319 ir_raw_handler_unregister(&nec_handler);
320}
321
322module_init(ir_nec_decode_init);
323module_exit(ir_nec_decode_exit);
324
325MODULE_LICENSE("GPL");
326MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
327MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
328MODULE_DESCRIPTION("NEC IR protocol decoder");
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
new file mode 100644
index 000000000000..ea68a3f2effa
--- /dev/null
+++ b/drivers/media/IR/ir-raw-event.c
@@ -0,0 +1,251 @@
1/* ir-raw-event.c - handle IR Pulse/Space event
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/workqueue.h>
16#include <linux/spinlock.h>
17#include <linux/sched.h>
18#include "ir-core-priv.h"
19
20/* Define the max number of pulse/space transitions to buffer */
21#define MAX_IR_EVENT_SIZE 512
22
23/* Used to handle IR raw handler extensions */
24static LIST_HEAD(ir_raw_handler_list);
25static DEFINE_SPINLOCK(ir_raw_handler_lock);
26
27/**
28 * RUN_DECODER() - runs an operation on all IR decoders
29 * @ops: IR raw handler operation to be called
30 * @arg: arguments to be passed to the callback
31 *
32 * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
33 * new decode addition/removal while running, by locking ir_raw_handler_lock
34 * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
35 * of the return codes.
36 */
37#define RUN_DECODER(ops, ...) ({ \
38 struct ir_raw_handler *_ir_raw_handler; \
39 int _sumrc = 0, _rc; \
40 spin_lock(&ir_raw_handler_lock); \
41 list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) { \
42 if (_ir_raw_handler->ops) { \
43 _rc = _ir_raw_handler->ops(__VA_ARGS__); \
44 if (_rc < 0) \
45 break; \
46 _sumrc += _rc; \
47 } \
48 } \
49 spin_unlock(&ir_raw_handler_lock); \
50 _sumrc; \
51})
52
53#ifdef MODULE
54/* Used to load the decoders */
55static struct work_struct wq_load;
56#endif
57
58static void ir_raw_event_work(struct work_struct *work)
59{
60 struct ir_raw_event ev;
61 struct ir_raw_event_ctrl *raw =
62 container_of(work, struct ir_raw_event_ctrl, rx_work);
63
64 while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
65 RUN_DECODER(decode, raw->input_dev, ev);
66}
67
68int ir_raw_event_register(struct input_dev *input_dev)
69{
70 struct ir_input_dev *ir = input_get_drvdata(input_dev);
71 int rc;
72
73 ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
74 if (!ir->raw)
75 return -ENOMEM;
76
77 ir->raw->input_dev = input_dev;
78 INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
79
80 rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
81 GFP_KERNEL);
82 if (rc < 0) {
83 kfree(ir->raw);
84 ir->raw = NULL;
85 return rc;
86 }
87
88 rc = RUN_DECODER(raw_register, input_dev);
89 if (rc < 0) {
90 kfifo_free(&ir->raw->kfifo);
91 kfree(ir->raw);
92 ir->raw = NULL;
93 return rc;
94 }
95
96 return rc;
97}
98
99void ir_raw_event_unregister(struct input_dev *input_dev)
100{
101 struct ir_input_dev *ir = input_get_drvdata(input_dev);
102
103 if (!ir->raw)
104 return;
105
106 cancel_work_sync(&ir->raw->rx_work);
107 RUN_DECODER(raw_unregister, input_dev);
108
109 kfifo_free(&ir->raw->kfifo);
110 kfree(ir->raw);
111 ir->raw = NULL;
112}
113
114/**
115 * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
116 * @input_dev: the struct input_dev device descriptor
117 * @ev: the struct ir_raw_event descriptor of the pulse/space
118 *
119 * This routine (which may be called from an interrupt context) stores a
120 * pulse/space duration for the raw ir decoding state machines. Pulses are
121 * signalled as positive values and spaces as negative values. A zero value
122 * will reset the decoding state machines.
123 */
124int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
125{
126 struct ir_input_dev *ir = input_get_drvdata(input_dev);
127
128 if (!ir->raw)
129 return -EINVAL;
130
131 if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
132 return -ENOMEM;
133
134 return 0;
135}
136EXPORT_SYMBOL_GPL(ir_raw_event_store);
137
138/**
139 * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
140 * @input_dev: the struct input_dev device descriptor
141 * @type: the type of the event that has occurred
142 *
143 * This routine (which may be called from an interrupt context) is used to
144 * store the beginning of an ir pulse or space (or the start/end of ir
145 * reception) for the raw ir decoding state machines. This is used by
146 * hardware which does not provide durations directly but only interrupts
147 * (or similar events) on state change.
148 */
149int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
150{
151 struct ir_input_dev *ir = input_get_drvdata(input_dev);
152 ktime_t now;
153 s64 delta; /* ns */
154 struct ir_raw_event ev;
155 int rc = 0;
156
157 if (!ir->raw)
158 return -EINVAL;
159
160 now = ktime_get();
161 delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
162
163 /* Check for a long duration since last event or if we're
164 * being called for the first time, note that delta can't
165 * possibly be negative.
166 */
167 ev.duration = 0;
168 if (delta > IR_MAX_DURATION || !ir->raw->last_type)
169 type |= IR_START_EVENT;
170 else
171 ev.duration = delta;
172
173 if (type & IR_START_EVENT)
174 ir_raw_event_reset(input_dev);
175 else if (ir->raw->last_type & IR_SPACE) {
176 ev.pulse = false;
177 rc = ir_raw_event_store(input_dev, &ev);
178 } else if (ir->raw->last_type & IR_PULSE) {
179 ev.pulse = true;
180 rc = ir_raw_event_store(input_dev, &ev);
181 } else
182 return 0;
183
184 ir->raw->last_event = now;
185 ir->raw->last_type = type;
186 return rc;
187}
188EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
189
190/**
191 * ir_raw_event_handle() - schedules the decoding of stored ir data
192 * @input_dev: the struct input_dev device descriptor
193 *
194 * This routine will signal the workqueue to start decoding stored ir data.
195 */
196void ir_raw_event_handle(struct input_dev *input_dev)
197{
198 struct ir_input_dev *ir = input_get_drvdata(input_dev);
199
200 if (!ir->raw)
201 return;
202
203 schedule_work(&ir->raw->rx_work);
204}
205EXPORT_SYMBOL_GPL(ir_raw_event_handle);
206
207/*
208 * Extension interface - used to register the IR decoders
209 */
210
211int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
212{
213 spin_lock(&ir_raw_handler_lock);
214 list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
215 spin_unlock(&ir_raw_handler_lock);
216 return 0;
217}
218EXPORT_SYMBOL(ir_raw_handler_register);
219
220void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
221{
222 spin_lock(&ir_raw_handler_lock);
223 list_del(&ir_raw_handler->list);
224 spin_unlock(&ir_raw_handler_lock);
225}
226EXPORT_SYMBOL(ir_raw_handler_unregister);
227
228#ifdef MODULE
229static void init_decoders(struct work_struct *work)
230{
231 /* Load the decoder modules */
232
233 load_nec_decode();
234 load_rc5_decode();
235 load_rc6_decode();
236 load_jvc_decode();
237 load_sony_decode();
238
239 /* If needed, we may later add some init code. In this case,
240 it is needed to change the CONFIG_MODULE test at ir-core.h
241 */
242}
243#endif
244
245void ir_raw_init(void)
246{
247#ifdef MODULE
248 INIT_WORK(&wq_load, init_decoders);
249 schedule_work(&wq_load);
250#endif
251}
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
new file mode 100644
index 000000000000..23cdb1b1a3bc
--- /dev/null
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -0,0 +1,324 @@
1/* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15/*
16 * This code handles 14 bits RC5 protocols and 20 bits RC5x protocols.
17 * There are other variants that use a different number of bits.
18 * This is currently unsupported.
19 * It considers a carrier of 36 kHz, with a total of 14/20 bits, where
20 * the first two bits are start bits, and a third one is a filing bit
21 */
22
23#include "ir-core-priv.h"
24
25#define RC5_NBITS 14
26#define RC5X_NBITS 20
27#define CHECK_RC5X_NBITS 8
28#define RC5_UNIT 888888 /* ns */
29#define RC5_BIT_START (1 * RC5_UNIT)
30#define RC5_BIT_END (1 * RC5_UNIT)
31#define RC5X_SPACE (4 * RC5_UNIT)
32
33/* Used to register rc5_decoder clients */
34static LIST_HEAD(decoder_list);
35static DEFINE_SPINLOCK(decoder_lock);
36
37enum rc5_state {
38 STATE_INACTIVE,
39 STATE_BIT_START,
40 STATE_BIT_END,
41 STATE_CHECK_RC5X,
42 STATE_FINISHED,
43};
44
45struct decoder_data {
46 struct list_head list;
47 struct ir_input_dev *ir_dev;
48 int enabled:1;
49
50 /* State machine control */
51 enum rc5_state state;
52 u32 rc5_bits;
53 struct ir_raw_event prev_ev;
54 unsigned count;
55 unsigned wanted_bits;
56};
57
58
59/**
60 * get_decoder_data() - gets decoder data
61 * @input_dev: input device
62 *
63 * Returns the struct decoder_data that corresponds to a device
64 */
65
66static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
67{
68 struct decoder_data *data = NULL;
69
70 spin_lock(&decoder_lock);
71 list_for_each_entry(data, &decoder_list, list) {
72 if (data->ir_dev == ir_dev)
73 break;
74 }
75 spin_unlock(&decoder_lock);
76 return data;
77}
78
79static ssize_t store_enabled(struct device *d,
80 struct device_attribute *mattr,
81 const char *buf,
82 size_t len)
83{
84 unsigned long value;
85 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
86 struct decoder_data *data = get_decoder_data(ir_dev);
87
88 if (!data)
89 return -EINVAL;
90
91 if (strict_strtoul(buf, 10, &value) || value > 1)
92 return -EINVAL;
93
94 data->enabled = value;
95
96 return len;
97}
98
99static ssize_t show_enabled(struct device *d,
100 struct device_attribute *mattr, char *buf)
101{
102 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
103 struct decoder_data *data = get_decoder_data(ir_dev);
104
105 if (!data)
106 return -EINVAL;
107
108 if (data->enabled)
109 return sprintf(buf, "1\n");
110 else
111 return sprintf(buf, "0\n");
112}
113
114static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
115
116static struct attribute *decoder_attributes[] = {
117 &dev_attr_enabled.attr,
118 NULL
119};
120
121static struct attribute_group decoder_attribute_group = {
122 .name = "rc5_decoder",
123 .attrs = decoder_attributes,
124};
125
126/**
127 * ir_rc5_decode() - Decode one RC-5 pulse or space
128 * @input_dev: the struct input_dev descriptor of the device
129 * @ev: the struct ir_raw_event descriptor of the pulse/space
130 *
131 * This function returns -EINVAL if the pulse violates the state machine
132 */
133static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
134{
135 struct decoder_data *data;
136 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
137 u8 toggle;
138 u32 scancode;
139
140 data = get_decoder_data(ir_dev);
141 if (!data)
142 return -EINVAL;
143
144 if (!data->enabled)
145 return 0;
146
147 if (IS_RESET(ev)) {
148 data->state = STATE_INACTIVE;
149 return 0;
150 }
151
152 if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
153 goto out;
154
155again:
156 IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
157 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
158
159 if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
160 return 0;
161
162 switch (data->state) {
163
164 case STATE_INACTIVE:
165 if (!ev.pulse)
166 break;
167
168 data->state = STATE_BIT_START;
169 data->count = 1;
170 /* We just need enough bits to get to STATE_CHECK_RC5X */
171 data->wanted_bits = RC5X_NBITS;
172 decrease_duration(&ev, RC5_BIT_START);
173 goto again;
174
175 case STATE_BIT_START:
176 if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
177 break;
178
179 data->rc5_bits <<= 1;
180 if (!ev.pulse)
181 data->rc5_bits |= 1;
182 data->count++;
183 data->prev_ev = ev;
184 data->state = STATE_BIT_END;
185 return 0;
186
187 case STATE_BIT_END:
188 if (!is_transition(&ev, &data->prev_ev))
189 break;
190
191 if (data->count == data->wanted_bits)
192 data->state = STATE_FINISHED;
193 else if (data->count == CHECK_RC5X_NBITS)
194 data->state = STATE_CHECK_RC5X;
195 else
196 data->state = STATE_BIT_START;
197
198 decrease_duration(&ev, RC5_BIT_END);
199 goto again;
200
201 case STATE_CHECK_RC5X:
202 if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
203 /* RC5X */
204 data->wanted_bits = RC5X_NBITS;
205 decrease_duration(&ev, RC5X_SPACE);
206 } else {
207 /* RC5 */
208 data->wanted_bits = RC5_NBITS;
209 }
210 data->state = STATE_BIT_START;
211 goto again;
212
213 case STATE_FINISHED:
214 if (ev.pulse)
215 break;
216
217 if (data->wanted_bits == RC5X_NBITS) {
218 /* RC5X */
219 u8 xdata, command, system;
220 xdata = (data->rc5_bits & 0x0003F) >> 0;
221 command = (data->rc5_bits & 0x00FC0) >> 6;
222 system = (data->rc5_bits & 0x1F000) >> 12;
223 toggle = (data->rc5_bits & 0x20000) ? 1 : 0;
224 command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
225 scancode = system << 16 | command << 8 | xdata;
226
227 IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
228 scancode, toggle);
229
230 } else {
231 /* RC5 */
232 u8 command, system;
233 command = (data->rc5_bits & 0x0003F) >> 0;
234 system = (data->rc5_bits & 0x007C0) >> 6;
235 toggle = (data->rc5_bits & 0x00800) ? 1 : 0;
236 command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
237 scancode = system << 8 | command;
238
239 IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
240 scancode, toggle);
241 }
242
243 ir_keydown(input_dev, scancode, toggle);
244 data->state = STATE_INACTIVE;
245 return 0;
246 }
247
248out:
249 IR_dprintk(1, "RC5(x) decode failed at state %i (%uus %s)\n",
250 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
251 data->state = STATE_INACTIVE;
252 return -EINVAL;
253}
254
255static int ir_rc5_register(struct input_dev *input_dev)
256{
257 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
258 struct decoder_data *data;
259 int rc;
260
261 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
262 if (rc < 0)
263 return rc;
264
265 data = kzalloc(sizeof(*data), GFP_KERNEL);
266 if (!data) {
267 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
268 return -ENOMEM;
269 }
270
271 data->ir_dev = ir_dev;
272 data->enabled = 1;
273
274 spin_lock(&decoder_lock);
275 list_add_tail(&data->list, &decoder_list);
276 spin_unlock(&decoder_lock);
277
278 return 0;
279}
280
281static int ir_rc5_unregister(struct input_dev *input_dev)
282{
283 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
284 static struct decoder_data *data;
285
286 data = get_decoder_data(ir_dev);
287 if (!data)
288 return 0;
289
290 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
291
292 spin_lock(&decoder_lock);
293 list_del(&data->list);
294 spin_unlock(&decoder_lock);
295
296 return 0;
297}
298
299static struct ir_raw_handler rc5_handler = {
300 .decode = ir_rc5_decode,
301 .raw_register = ir_rc5_register,
302 .raw_unregister = ir_rc5_unregister,
303};
304
305static int __init ir_rc5_decode_init(void)
306{
307 ir_raw_handler_register(&rc5_handler);
308
309 printk(KERN_INFO "IR RC5(x) protocol handler initialized\n");
310 return 0;
311}
312
313static void __exit ir_rc5_decode_exit(void)
314{
315 ir_raw_handler_unregister(&rc5_handler);
316}
317
318module_init(ir_rc5_decode_init);
319module_exit(ir_rc5_decode_exit);
320
321MODULE_LICENSE("GPL");
322MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
323MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
324MODULE_DESCRIPTION("RC5(x) IR protocol decoder");
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
new file mode 100644
index 000000000000..2bf479f4f1bc
--- /dev/null
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -0,0 +1,419 @@
1/* ir-rc6-decoder.c - A decoder for the RC6 IR protocol
2 *
3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include "ir-core-priv.h"
16
17/*
18 * This decoder currently supports:
19 * RC6-0-16 (standard toggle bit in header)
20 * RC6-6A-24 (no toggle bit)
21 * RC6-6A-32 (MCE version with toggle bit in body)
22 */
23
24#define RC6_UNIT 444444 /* us */
25#define RC6_HEADER_NBITS 4 /* not including toggle bit */
26#define RC6_0_NBITS 16
27#define RC6_6A_SMALL_NBITS 24
28#define RC6_6A_LARGE_NBITS 32
29#define RC6_PREFIX_PULSE (6 * RC6_UNIT)
30#define RC6_PREFIX_SPACE (2 * RC6_UNIT)
31#define RC6_BIT_START (1 * RC6_UNIT)
32#define RC6_BIT_END (1 * RC6_UNIT)
33#define RC6_TOGGLE_START (2 * RC6_UNIT)
34#define RC6_TOGGLE_END (2 * RC6_UNIT)
35#define RC6_MODE_MASK 0x07 /* for the header bits */
36#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
37#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
38
39/* Used to register rc6_decoder clients */
40static LIST_HEAD(decoder_list);
41static DEFINE_SPINLOCK(decoder_lock);
42
43enum rc6_mode {
44 RC6_MODE_0,
45 RC6_MODE_6A,
46 RC6_MODE_UNKNOWN,
47};
48
49enum rc6_state {
50 STATE_INACTIVE,
51 STATE_PREFIX_SPACE,
52 STATE_HEADER_BIT_START,
53 STATE_HEADER_BIT_END,
54 STATE_TOGGLE_START,
55 STATE_TOGGLE_END,
56 STATE_BODY_BIT_START,
57 STATE_BODY_BIT_END,
58 STATE_FINISHED,
59};
60
61struct decoder_data {
62 struct list_head list;
63 struct ir_input_dev *ir_dev;
64 int enabled:1;
65
66 /* State machine control */
67 enum rc6_state state;
68 u8 header;
69 u32 body;
70 struct ir_raw_event prev_ev;
71 bool toggle;
72 unsigned count;
73 unsigned wanted_bits;
74};
75
76
77/**
78 * get_decoder_data() - gets decoder data
79 * @input_dev: input device
80 *
81 * Returns the struct decoder_data that corresponds to a device
82 */
83static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
84{
85 struct decoder_data *data = NULL;
86
87 spin_lock(&decoder_lock);
88 list_for_each_entry(data, &decoder_list, list) {
89 if (data->ir_dev == ir_dev)
90 break;
91 }
92 spin_unlock(&decoder_lock);
93 return data;
94}
95
96static ssize_t store_enabled(struct device *d,
97 struct device_attribute *mattr,
98 const char *buf,
99 size_t len)
100{
101 unsigned long value;
102 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
103 struct decoder_data *data = get_decoder_data(ir_dev);
104
105 if (!data)
106 return -EINVAL;
107
108 if (strict_strtoul(buf, 10, &value) || value > 1)
109 return -EINVAL;
110
111 data->enabled = value;
112
113 return len;
114}
115
116static ssize_t show_enabled(struct device *d,
117 struct device_attribute *mattr, char *buf)
118{
119 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
120 struct decoder_data *data = get_decoder_data(ir_dev);
121
122 if (!data)
123 return -EINVAL;
124
125 if (data->enabled)
126 return sprintf(buf, "1\n");
127 else
128 return sprintf(buf, "0\n");
129}
130
131static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
132
133static struct attribute *decoder_attributes[] = {
134 &dev_attr_enabled.attr,
135 NULL
136};
137
138static struct attribute_group decoder_attribute_group = {
139 .name = "rc6_decoder",
140 .attrs = decoder_attributes,
141};
142
143static enum rc6_mode rc6_mode(struct decoder_data *data) {
144 switch (data->header & RC6_MODE_MASK) {
145 case 0:
146 return RC6_MODE_0;
147 case 6:
148 if (!data->toggle)
149 return RC6_MODE_6A;
150 /* fall through */
151 default:
152 return RC6_MODE_UNKNOWN;
153 }
154}
155
156/**
157 * ir_rc6_decode() - Decode one RC6 pulse or space
158 * @input_dev: the struct input_dev descriptor of the device
159 * @ev: the struct ir_raw_event descriptor of the pulse/space
160 *
161 * This function returns -EINVAL if the pulse violates the state machine
162 */
163static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
164{
165 struct decoder_data *data;
166 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
167 u32 scancode;
168 u8 toggle;
169
170 data = get_decoder_data(ir_dev);
171 if (!data)
172 return -EINVAL;
173
174 if (!data->enabled)
175 return 0;
176
177 if (IS_RESET(ev)) {
178 data->state = STATE_INACTIVE;
179 return 0;
180 }
181
182 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
183 goto out;
184
185again:
186 IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
187 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
188
189 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
190 return 0;
191
192 switch (data->state) {
193
194 case STATE_INACTIVE:
195 if (!ev.pulse)
196 break;
197
198 /* Note: larger margin on first pulse since each RC6_UNIT
199 is quite short and some hardware takes some time to
200 adjust to the signal */
201 if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
202 break;
203
204 data->state = STATE_PREFIX_SPACE;
205 data->count = 0;
206 return 0;
207
208 case STATE_PREFIX_SPACE:
209 if (ev.pulse)
210 break;
211
212 if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
213 break;
214
215 data->state = STATE_HEADER_BIT_START;
216 return 0;
217
218 case STATE_HEADER_BIT_START:
219 if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
220 break;
221
222 data->header <<= 1;
223 if (ev.pulse)
224 data->header |= 1;
225 data->count++;
226 data->prev_ev = ev;
227 data->state = STATE_HEADER_BIT_END;
228 return 0;
229
230 case STATE_HEADER_BIT_END:
231 if (!is_transition(&ev, &data->prev_ev))
232 break;
233
234 if (data->count == RC6_HEADER_NBITS)
235 data->state = STATE_TOGGLE_START;
236 else
237 data->state = STATE_HEADER_BIT_START;
238
239 decrease_duration(&ev, RC6_BIT_END);
240 goto again;
241
242 case STATE_TOGGLE_START:
243 if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
244 break;
245
246 data->toggle = ev.pulse;
247 data->prev_ev = ev;
248 data->state = STATE_TOGGLE_END;
249 return 0;
250
251 case STATE_TOGGLE_END:
252 if (!is_transition(&ev, &data->prev_ev) ||
253 !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
254 break;
255
256 if (!(data->header & RC6_STARTBIT_MASK)) {
257 IR_dprintk(1, "RC6 invalid start bit\n");
258 break;
259 }
260
261 data->state = STATE_BODY_BIT_START;
262 data->prev_ev = ev;
263 decrease_duration(&ev, RC6_TOGGLE_END);
264 data->count = 0;
265
266 switch (rc6_mode(data)) {
267 case RC6_MODE_0:
268 data->wanted_bits = RC6_0_NBITS;
269 break;
270 case RC6_MODE_6A:
271 /* This might look weird, but we basically
272 check the value of the first body bit to
273 determine the number of bits in mode 6A */
274 if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
275 geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
276 data->wanted_bits = RC6_6A_LARGE_NBITS;
277 else
278 data->wanted_bits = RC6_6A_SMALL_NBITS;
279 break;
280 default:
281 IR_dprintk(1, "RC6 unknown mode\n");
282 goto out;
283 }
284 goto again;
285
286 case STATE_BODY_BIT_START:
287 if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
288 break;
289
290 data->body <<= 1;
291 if (ev.pulse)
292 data->body |= 1;
293 data->count++;
294 data->prev_ev = ev;
295
296 data->state = STATE_BODY_BIT_END;
297 return 0;
298
299 case STATE_BODY_BIT_END:
300 if (!is_transition(&ev, &data->prev_ev))
301 break;
302
303 if (data->count == data->wanted_bits)
304 data->state = STATE_FINISHED;
305 else
306 data->state = STATE_BODY_BIT_START;
307
308 decrease_duration(&ev, RC6_BIT_END);
309 goto again;
310
311 case STATE_FINISHED:
312 if (ev.pulse)
313 break;
314
315 switch (rc6_mode(data)) {
316 case RC6_MODE_0:
317 scancode = data->body & 0xffff;
318 toggle = data->toggle;
319 IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
320 scancode, toggle);
321 break;
322 case RC6_MODE_6A:
323 if (data->wanted_bits == RC6_6A_LARGE_NBITS) {
324 toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0;
325 scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK;
326 } else {
327 toggle = 0;
328 scancode = data->body & 0xffffff;
329 }
330
331 IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
332 scancode, toggle);
333 break;
334 default:
335 IR_dprintk(1, "RC6 unknown mode\n");
336 goto out;
337 }
338
339 ir_keydown(input_dev, scancode, toggle);
340 data->state = STATE_INACTIVE;
341 return 0;
342 }
343
344out:
345 IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
346 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
347 data->state = STATE_INACTIVE;
348 return -EINVAL;
349}
350
351static int ir_rc6_register(struct input_dev *input_dev)
352{
353 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
354 struct decoder_data *data;
355 int rc;
356
357 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
358 if (rc < 0)
359 return rc;
360
361 data = kzalloc(sizeof(*data), GFP_KERNEL);
362 if (!data) {
363 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
364 return -ENOMEM;
365 }
366
367 data->ir_dev = ir_dev;
368 data->enabled = 1;
369
370 spin_lock(&decoder_lock);
371 list_add_tail(&data->list, &decoder_list);
372 spin_unlock(&decoder_lock);
373
374 return 0;
375}
376
377static int ir_rc6_unregister(struct input_dev *input_dev)
378{
379 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
380 static struct decoder_data *data;
381
382 data = get_decoder_data(ir_dev);
383 if (!data)
384 return 0;
385
386 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
387
388 spin_lock(&decoder_lock);
389 list_del(&data->list);
390 spin_unlock(&decoder_lock);
391
392 return 0;
393}
394
395static struct ir_raw_handler rc6_handler = {
396 .decode = ir_rc6_decode,
397 .raw_register = ir_rc6_register,
398 .raw_unregister = ir_rc6_unregister,
399};
400
401static int __init ir_rc6_decode_init(void)
402{
403 ir_raw_handler_register(&rc6_handler);
404
405 printk(KERN_INFO "IR RC6 protocol handler initialized\n");
406 return 0;
407}
408
409static void __exit ir_rc6_decode_exit(void)
410{
411 ir_raw_handler_unregister(&rc6_handler);
412}
413
414module_init(ir_rc6_decode_init);
415module_exit(ir_rc6_decode_exit);
416
417MODULE_LICENSE("GPL");
418MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
419MODULE_DESCRIPTION("RC6 IR protocol decoder");
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
new file mode 100644
index 000000000000..9f440c5c060d
--- /dev/null
+++ b/drivers/media/IR/ir-sony-decoder.c
@@ -0,0 +1,312 @@
1/* ir-sony-decoder.c - handle Sony IR Pulse/Space protocol
2 *
3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/bitrev.h>
16#include "ir-core-priv.h"
17
18#define SONY_UNIT 600000 /* ns */
19#define SONY_HEADER_PULSE (4 * SONY_UNIT)
20#define SONY_HEADER_SPACE (1 * SONY_UNIT)
21#define SONY_BIT_0_PULSE (1 * SONY_UNIT)
22#define SONY_BIT_1_PULSE (2 * SONY_UNIT)
23#define SONY_BIT_SPACE (1 * SONY_UNIT)
24#define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */
25
26/* Used to register sony_decoder clients */
27static LIST_HEAD(decoder_list);
28static DEFINE_SPINLOCK(decoder_lock);
29
30enum sony_state {
31 STATE_INACTIVE,
32 STATE_HEADER_SPACE,
33 STATE_BIT_PULSE,
34 STATE_BIT_SPACE,
35 STATE_FINISHED,
36};
37
38struct decoder_data {
39 struct list_head list;
40 struct ir_input_dev *ir_dev;
41 int enabled:1;
42
43 /* State machine control */
44 enum sony_state state;
45 u32 sony_bits;
46 unsigned count;
47};
48
49
50/**
51 * get_decoder_data() - gets decoder data
52 * @input_dev: input device
53 *
54 * Returns the struct decoder_data that corresponds to a device
55 */
56static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
57{
58 struct decoder_data *data = NULL;
59
60 spin_lock(&decoder_lock);
61 list_for_each_entry(data, &decoder_list, list) {
62 if (data->ir_dev == ir_dev)
63 break;
64 }
65 spin_unlock(&decoder_lock);
66 return data;
67}
68
69static ssize_t store_enabled(struct device *d,
70 struct device_attribute *mattr,
71 const char *buf,
72 size_t len)
73{
74 unsigned long value;
75 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
76 struct decoder_data *data = get_decoder_data(ir_dev);
77
78 if (!data)
79 return -EINVAL;
80
81 if (strict_strtoul(buf, 10, &value) || value > 1)
82 return -EINVAL;
83
84 data->enabled = value;
85
86 return len;
87}
88
89static ssize_t show_enabled(struct device *d,
90 struct device_attribute *mattr, char *buf)
91{
92 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
93 struct decoder_data *data = get_decoder_data(ir_dev);
94
95 if (!data)
96 return -EINVAL;
97
98 if (data->enabled)
99 return sprintf(buf, "1\n");
100 else
101 return sprintf(buf, "0\n");
102}
103
104static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
105
106static struct attribute *decoder_attributes[] = {
107 &dev_attr_enabled.attr,
108 NULL
109};
110
111static struct attribute_group decoder_attribute_group = {
112 .name = "sony_decoder",
113 .attrs = decoder_attributes,
114};
115
116/**
117 * ir_sony_decode() - Decode one Sony pulse or space
118 * @input_dev: the struct input_dev descriptor of the device
119 * @ev: the struct ir_raw_event descriptor of the pulse/space
120 *
121 * This function returns -EINVAL if the pulse violates the state machine
122 */
123static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
124{
125 struct decoder_data *data;
126 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
127 u32 scancode;
128 u8 device, subdevice, function;
129
130 data = get_decoder_data(ir_dev);
131 if (!data)
132 return -EINVAL;
133
134 if (!data->enabled)
135 return 0;
136
137 if (IS_RESET(ev)) {
138 data->state = STATE_INACTIVE;
139 return 0;
140 }
141
142 if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2))
143 goto out;
144
145 IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n",
146 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
147
148 switch (data->state) {
149
150 case STATE_INACTIVE:
151 if (!ev.pulse)
152 break;
153
154 if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2))
155 break;
156
157 data->count = 0;
158 data->state = STATE_HEADER_SPACE;
159 return 0;
160
161 case STATE_HEADER_SPACE:
162 if (ev.pulse)
163 break;
164
165 if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2))
166 break;
167
168 data->state = STATE_BIT_PULSE;
169 return 0;
170
171 case STATE_BIT_PULSE:
172 if (!ev.pulse)
173 break;
174
175 data->sony_bits <<= 1;
176 if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
177 data->sony_bits |= 1;
178 else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
179 break;
180
181 data->count++;
182 data->state = STATE_BIT_SPACE;
183 return 0;
184
185 case STATE_BIT_SPACE:
186 if (ev.pulse)
187 break;
188
189 if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2))
190 break;
191
192 decrease_duration(&ev, SONY_BIT_SPACE);
193
194 if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) {
195 data->state = STATE_BIT_PULSE;
196 return 0;
197 }
198
199 data->state = STATE_FINISHED;
200 /* Fall through */
201
202 case STATE_FINISHED:
203 if (ev.pulse)
204 break;
205
206 if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2))
207 break;
208
209 switch (data->count) {
210 case 12:
211 device = bitrev8((data->sony_bits << 3) & 0xF8);
212 subdevice = 0;
213 function = bitrev8((data->sony_bits >> 4) & 0xFE);
214 break;
215 case 15:
216 device = bitrev8((data->sony_bits >> 0) & 0xFF);
217 subdevice = 0;
218 function = bitrev8((data->sony_bits >> 7) & 0xFD);
219 break;
220 case 20:
221 device = bitrev8((data->sony_bits >> 5) & 0xF8);
222 subdevice = bitrev8((data->sony_bits >> 0) & 0xFF);
223 function = bitrev8((data->sony_bits >> 12) & 0xFE);
224 break;
225 default:
226 IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
227 goto out;
228 }
229
230 scancode = device << 16 | subdevice << 8 | function;
231 IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
232 ir_keydown(input_dev, scancode, 0);
233 data->state = STATE_INACTIVE;
234 return 0;
235 }
236
237out:
238 IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n",
239 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
240 data->state = STATE_INACTIVE;
241 return -EINVAL;
242}
243
244static int ir_sony_register(struct input_dev *input_dev)
245{
246 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
247 struct decoder_data *data;
248 int rc;
249
250 rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
251 if (rc < 0)
252 return rc;
253
254 data = kzalloc(sizeof(*data), GFP_KERNEL);
255 if (!data) {
256 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
257 return -ENOMEM;
258 }
259
260 data->ir_dev = ir_dev;
261 data->enabled = 1;
262
263 spin_lock(&decoder_lock);
264 list_add_tail(&data->list, &decoder_list);
265 spin_unlock(&decoder_lock);
266
267 return 0;
268}
269
270static int ir_sony_unregister(struct input_dev *input_dev)
271{
272 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
273 static struct decoder_data *data;
274
275 data = get_decoder_data(ir_dev);
276 if (!data)
277 return 0;
278
279 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
280
281 spin_lock(&decoder_lock);
282 list_del(&data->list);
283 spin_unlock(&decoder_lock);
284
285 return 0;
286}
287
288static struct ir_raw_handler sony_handler = {
289 .decode = ir_sony_decode,
290 .raw_register = ir_sony_register,
291 .raw_unregister = ir_sony_unregister,
292};
293
294static int __init ir_sony_decode_init(void)
295{
296 ir_raw_handler_register(&sony_handler);
297
298 printk(KERN_INFO "IR Sony protocol handler initialized\n");
299 return 0;
300}
301
302static void __exit ir_sony_decode_exit(void)
303{
304 ir_raw_handler_unregister(&sony_handler);
305}
306
307module_init(ir_sony_decode_init);
308module_exit(ir_sony_decode_exit);
309
310MODULE_LICENSE("GPL");
311MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
312MODULE_DESCRIPTION("Sony IR protocol decoder");
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index e14e6c486b52..d7da63e16c92 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -1,6 +1,6 @@
1/* ir-register.c - handle IR scancode->keycode tables 1/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
2 * 2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> 3 * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -15,15 +15,23 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <media/ir-core.h> 18#include "ir-core-priv.h"
19 19
20#define IRRCV_NUM_DEVICES 256 20#define IRRCV_NUM_DEVICES 256
21 21
22/* bit array to represent IR sysfs device number */ 22/* bit array to represent IR sysfs device number */
23static unsigned long ir_core_dev_number; 23static unsigned long ir_core_dev_number;
24 24
25/* class for /sys/class/irrcv */ 25/* class for /sys/class/rc */
26static struct class *ir_input_class; 26static char *ir_devnode(struct device *dev, mode_t *mode)
27{
28 return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
29}
30
31static struct class ir_input_class = {
32 .name = "rc",
33 .devnode = ir_devnode,
34};
27 35
28/** 36/**
29 * show_protocol() - shows the current IR protocol 37 * show_protocol() - shows the current IR protocol
@@ -32,7 +40,7 @@ static struct class *ir_input_class;
32 * @buf: a pointer to the output buffer 40 * @buf: a pointer to the output buffer
33 * 41 *
34 * This routine is a callback routine for input read the IR protocol type. 42 * This routine is a callback routine for input read the IR protocol type.
35 * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol. 43 * it is trigged by reading /sys/class/rc/rc?/current_protocol.
36 * It returns the protocol name, as understood by the driver. 44 * It returns the protocol name, as understood by the driver.
37 */ 45 */
38static ssize_t show_protocol(struct device *d, 46static ssize_t show_protocol(struct device *d,
@@ -48,13 +56,17 @@ static ssize_t show_protocol(struct device *d,
48 if (ir_type == IR_TYPE_UNKNOWN) 56 if (ir_type == IR_TYPE_UNKNOWN)
49 s = "Unknown"; 57 s = "Unknown";
50 else if (ir_type == IR_TYPE_RC5) 58 else if (ir_type == IR_TYPE_RC5)
51 s = "RC-5"; 59 s = "rc-5";
52 else if (ir_type == IR_TYPE_PD)
53 s = "Pulse/distance";
54 else if (ir_type == IR_TYPE_NEC) 60 else if (ir_type == IR_TYPE_NEC)
55 s = "NEC"; 61 s = "nec";
62 else if (ir_type == IR_TYPE_RC6)
63 s = "rc6";
64 else if (ir_type == IR_TYPE_JVC)
65 s = "jvc";
66 else if (ir_type == IR_TYPE_SONY)
67 s = "sony";
56 else 68 else
57 s = "Other"; 69 s = "other";
58 70
59 return sprintf(buf, "%s\n", s); 71 return sprintf(buf, "%s\n", s);
60} 72}
@@ -67,7 +79,7 @@ static ssize_t show_protocol(struct device *d,
67 * @len: length of the input buffer 79 * @len: length of the input buffer
68 * 80 *
69 * This routine is a callback routine for changing the IR protocol type. 81 * This routine is a callback routine for changing the IR protocol type.
70 * it is trigged by reading /sys/class/irrcv/irrcv?/current_protocol. 82 * it is trigged by reading /sys/class/rc/rc?/current_protocol.
71 * It changes the IR the protocol name, if the IR type is recognized 83 * It changes the IR the protocol name, if the IR type is recognized
72 * by the driver. 84 * by the driver.
73 * If an unknown protocol name is used, returns -EINVAL. 85 * If an unknown protocol name is used, returns -EINVAL.
@@ -78,23 +90,24 @@ static ssize_t store_protocol(struct device *d,
78 size_t len) 90 size_t len)
79{ 91{
80 struct ir_input_dev *ir_dev = dev_get_drvdata(d); 92 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
81 u64 ir_type = IR_TYPE_UNKNOWN; 93 u64 ir_type = 0;
82 int rc = -EINVAL; 94 int rc = -EINVAL;
83 unsigned long flags; 95 unsigned long flags;
84 char *buf; 96 char *buf;
85 97
86 buf = strsep((char **) &data, "\n"); 98 while ((buf = strsep((char **) &data, " \n")) != NULL) {
87 99 if (!strcasecmp(buf, "rc-5") || !strcasecmp(buf, "rc5"))
88 if (!strcasecmp(buf, "rc-5")) 100 ir_type |= IR_TYPE_RC5;
89 ir_type = IR_TYPE_RC5; 101 if (!strcasecmp(buf, "nec"))
90 else if (!strcasecmp(buf, "pd")) 102 ir_type |= IR_TYPE_NEC;
91 ir_type = IR_TYPE_PD; 103 if (!strcasecmp(buf, "jvc"))
92 else if (!strcasecmp(buf, "nec")) 104 ir_type |= IR_TYPE_JVC;
93 ir_type = IR_TYPE_NEC; 105 if (!strcasecmp(buf, "sony"))
106 ir_type |= IR_TYPE_SONY;
107 }
94 108
95 if (ir_type == IR_TYPE_UNKNOWN) { 109 if (!ir_type) {
96 IR_dprintk(1, "Error setting protocol to %lld\n", 110 IR_dprintk(1, "Unknown protocol\n");
97 (long long)ir_type);
98 return -EINVAL; 111 return -EINVAL;
99 } 112 }
100 113
@@ -112,25 +125,87 @@ static ssize_t store_protocol(struct device *d,
112 ir_dev->rc_tab.ir_type = ir_type; 125 ir_dev->rc_tab.ir_type = ir_type;
113 spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); 126 spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
114 127
115 IR_dprintk(1, "Current protocol is %lld\n", 128 IR_dprintk(1, "Current protocol(s) is(are) %lld\n",
116 (long long)ir_type); 129 (long long)ir_type);
117 130
118 return len; 131 return len;
119} 132}
120 133
134static ssize_t show_supported_protocols(struct device *d,
135 struct device_attribute *mattr, char *buf)
136{
137 char *orgbuf = buf;
138 struct ir_input_dev *ir_dev = dev_get_drvdata(d);
139
140 /* FIXME: doesn't support multiple protocols at the same time */
141 if (ir_dev->props->allowed_protos == IR_TYPE_UNKNOWN)
142 buf += sprintf(buf, "unknown ");
143 if (ir_dev->props->allowed_protos & IR_TYPE_RC5)
144 buf += sprintf(buf, "rc-5 ");
145 if (ir_dev->props->allowed_protos & IR_TYPE_NEC)
146 buf += sprintf(buf, "nec ");
147 if (buf == orgbuf)
148 buf += sprintf(buf, "other ");
149
150 buf += sprintf(buf - 1, "\n");
151
152 return buf - orgbuf;
153}
154
155#define ADD_HOTPLUG_VAR(fmt, val...) \
156 do { \
157 int err = add_uevent_var(env, fmt, val); \
158 if (err) \
159 return err; \
160 } while (0)
161
162static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
163{
164 struct ir_input_dev *ir_dev = dev_get_drvdata(device);
165
166 if (ir_dev->rc_tab.name)
167 ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
168 if (ir_dev->driver_name)
169 ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
170
171 return 0;
172}
173
121/* 174/*
122 * Static device attribute struct with the sysfs attributes for IR's 175 * Static device attribute struct with the sysfs attributes for IR's
123 */ 176 */
124static DEVICE_ATTR(current_protocol, S_IRUGO | S_IWUSR, 177static DEVICE_ATTR(protocol, S_IRUGO | S_IWUSR,
125 show_protocol, store_protocol); 178 show_protocol, store_protocol);
126 179
127static struct attribute *ir_dev_attrs[] = { 180static DEVICE_ATTR(supported_protocols, S_IRUGO | S_IWUSR,
128 &dev_attr_current_protocol.attr, 181 show_supported_protocols, NULL);
182
183static struct attribute *ir_hw_dev_attrs[] = {
184 &dev_attr_protocol.attr,
185 &dev_attr_supported_protocols.attr,
129 NULL, 186 NULL,
130}; 187};
131 188
189static struct attribute_group ir_hw_dev_attr_grp = {
190 .attrs = ir_hw_dev_attrs,
191};
192
193static const struct attribute_group *ir_hw_dev_attr_groups[] = {
194 &ir_hw_dev_attr_grp,
195 NULL
196};
197
198static struct device_type rc_dev_type = {
199 .groups = ir_hw_dev_attr_groups,
200 .uevent = ir_dev_uevent,
201};
202
203static struct device_type ir_raw_dev_type = {
204 .uevent = ir_dev_uevent,
205};
206
132/** 207/**
133 * ir_register_class() - creates the sysfs for /sys/class/irrcv/irrcv? 208 * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
134 * @input_dev: the struct input_dev descriptor of the device 209 * @input_dev: the struct input_dev descriptor of the device
135 * 210 *
136 * This routine is used to register the syfs code for IR class 211 * This routine is used to register the syfs code for IR class
@@ -138,8 +213,7 @@ static struct attribute *ir_dev_attrs[] = {
138int ir_register_class(struct input_dev *input_dev) 213int ir_register_class(struct input_dev *input_dev)
139{ 214{
140 int rc; 215 int rc;
141 struct kobject *kobj; 216 const char *path;
142
143 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 217 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
144 int devno = find_first_zero_bit(&ir_core_dev_number, 218 int devno = find_first_zero_bit(&ir_core_dev_number,
145 IRRCV_NUM_DEVICES); 219 IRRCV_NUM_DEVICES);
@@ -147,19 +221,36 @@ int ir_register_class(struct input_dev *input_dev)
147 if (unlikely(devno < 0)) 221 if (unlikely(devno < 0))
148 return devno; 222 return devno;
149 223
150 ir_dev->attr.attrs = ir_dev_attrs; 224 if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
151 ir_dev->class_dev = device_create(ir_input_class, NULL, 225 ir_dev->dev.type = &rc_dev_type;
152 input_dev->dev.devt, ir_dev, 226 else
153 "irrcv%d", devno); 227 ir_dev->dev.type = &ir_raw_dev_type;
154 kobj = &ir_dev->class_dev->kobj; 228
155 229 ir_dev->dev.class = &ir_input_class;
156 printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj)); 230 ir_dev->dev.parent = input_dev->dev.parent;
157 rc = sysfs_create_group(kobj, &ir_dev->attr); 231 dev_set_name(&ir_dev->dev, "rc%d", devno);
158 if (unlikely(rc < 0)) { 232 dev_set_drvdata(&ir_dev->dev, ir_dev);
159 device_destroy(ir_input_class, input_dev->dev.devt); 233 rc = device_register(&ir_dev->dev);
160 return -ENOMEM; 234 if (rc)
235 return rc;
236
237
238 input_dev->dev.parent = &ir_dev->dev;
239 rc = input_register_device(input_dev);
240 if (rc < 0) {
241 device_del(&ir_dev->dev);
242 return rc;
161 } 243 }
162 244
245 __module_get(THIS_MODULE);
246
247 path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
248 printk(KERN_INFO "%s: %s as %s\n",
249 dev_name(&ir_dev->dev),
250 input_dev->name ? input_dev->name : "Unspecified device",
251 path ? path : "N/A");
252 kfree(path);
253
163 ir_dev->devno = devno; 254 ir_dev->devno = devno;
164 set_bit(devno, &ir_core_dev_number); 255 set_bit(devno, &ir_core_dev_number);
165 256
@@ -168,7 +259,7 @@ int ir_register_class(struct input_dev *input_dev)
168 259
169/** 260/**
170 * ir_unregister_class() - removes the sysfs for sysfs for 261 * ir_unregister_class() - removes the sysfs for sysfs for
171 * /sys/class/irrcv/irrcv? 262 * /sys/class/rc/rc?
172 * @input_dev: the struct input_dev descriptor of the device 263 * @input_dev: the struct input_dev descriptor of the device
173 * 264 *
174 * This routine is used to unregister the syfs code for IR class 265 * This routine is used to unregister the syfs code for IR class
@@ -176,36 +267,35 @@ int ir_register_class(struct input_dev *input_dev)
176void ir_unregister_class(struct input_dev *input_dev) 267void ir_unregister_class(struct input_dev *input_dev)
177{ 268{
178 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 269 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
179 struct kobject *kobj;
180 270
181 clear_bit(ir_dev->devno, &ir_core_dev_number); 271 clear_bit(ir_dev->devno, &ir_core_dev_number);
272 input_unregister_device(input_dev);
273 device_del(&ir_dev->dev);
182 274
183 kobj = &ir_dev->class_dev->kobj; 275 module_put(THIS_MODULE);
184
185 sysfs_remove_group(kobj, &ir_dev->attr);
186 device_destroy(ir_input_class, input_dev->dev.devt);
187
188 kfree(ir_dev->attr.name);
189} 276}
190 277
191/* 278/*
192 * Init/exit code for the module. Basically, creates/removes /sys/class/irrcv 279 * Init/exit code for the module. Basically, creates/removes /sys/class/rc
193 */ 280 */
194 281
195static int __init ir_core_init(void) 282static int __init ir_core_init(void)
196{ 283{
197 ir_input_class = class_create(THIS_MODULE, "irrcv"); 284 int rc = class_register(&ir_input_class);
198 if (IS_ERR(ir_input_class)) { 285 if (rc) {
199 printk(KERN_ERR "ir_core: unable to register irrcv class\n"); 286 printk(KERN_ERR "ir_core: unable to register rc class\n");
200 return PTR_ERR(ir_input_class); 287 return rc;
201 } 288 }
202 289
290 /* Initialize/load the decoders/keymap code that will be used */
291 ir_raw_init();
292
203 return 0; 293 return 0;
204} 294}
205 295
206static void __exit ir_core_exit(void) 296static void __exit ir_core_exit(void)
207{ 297{
208 class_destroy(ir_input_class); 298 class_unregister(&ir_input_class);
209} 299}
210 300
211module_init(ir_core_init); 301module_init(ir_core_init);
diff --git a/drivers/media/IR/keymaps/Kconfig b/drivers/media/IR/keymaps/Kconfig
new file mode 100644
index 000000000000..14b22f58f823
--- /dev/null
+++ b/drivers/media/IR/keymaps/Kconfig
@@ -0,0 +1,15 @@
1config RC_MAP
2 tristate "Compile Remote Controller keymap modules"
3 depends on IR_CORE
4 default y
5
6 ---help---
7 This option enables the compilation of lots of Remote
8 Controller tables. They are short tables, but if you
9 don't use a remote controller, or prefer to load the
10 tables on userspace, you should disable it.
11
12 The ir-keytable program, available at v4l-utils package
13 provide the tool and the same RC maps for load from
14 userspace. Its available at
15 http://git.linuxtv.org/v4l-utils
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
new file mode 100644
index 000000000000..ec25258a955f
--- /dev/null
+++ b/drivers/media/IR/keymaps/Makefile
@@ -0,0 +1,67 @@
1obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
2 rc-apac-viewcomp.o \
3 rc-asus-pc39.o \
4 rc-ati-tv-wonder-hd-600.o \
5 rc-avermedia-a16d.o \
6 rc-avermedia.o \
7 rc-avermedia-cardbus.o \
8 rc-avermedia-dvbt.o \
9 rc-avermedia-m135a-rm-jx.o \
10 rc-avertv-303.o \
11 rc-behold.o \
12 rc-behold-columbus.o \
13 rc-budget-ci-old.o \
14 rc-cinergy-1400.o \
15 rc-cinergy.o \
16 rc-dm1105-nec.o \
17 rc-dntv-live-dvb-t.o \
18 rc-dntv-live-dvbt-pro.o \
19 rc-empty.o \
20 rc-em-terratec.o \
21 rc-encore-enltv2.o \
22 rc-encore-enltv.o \
23 rc-encore-enltv-fm53.o \
24 rc-evga-indtube.o \
25 rc-eztv.o \
26 rc-flydvb.o \
27 rc-flyvideo.o \
28 rc-fusionhdtv-mce.o \
29 rc-gadmei-rm008z.o \
30 rc-genius-tvgo-a11mce.o \
31 rc-gotview7135.o \
32 rc-hauppauge-new.o \
33 rc-imon-mce.o \
34 rc-imon-pad.o \
35 rc-iodata-bctv7e.o \
36 rc-kaiomy.o \
37 rc-kworld-315u.o \
38 rc-kworld-plus-tv-analog.o \
39 rc-manli.o \
40 rc-msi-tvanywhere.o \
41 rc-msi-tvanywhere-plus.o \
42 rc-nebula.o \
43 rc-nec-terratec-cinergy-xs.o \
44 rc-norwood.o \
45 rc-npgtech.o \
46 rc-pctv-sedna.o \
47 rc-pinnacle-color.o \
48 rc-pinnacle-grey.o \
49 rc-pinnacle-pctv-hd.o \
50 rc-pixelview.o \
51 rc-pixelview-mk12.o \
52 rc-pixelview-new.o \
53 rc-powercolor-real-angel.o \
54 rc-proteus-2309.o \
55 rc-purpletv.o \
56 rc-pv951.o \
57 rc-rc5-hauppauge-new.o \
58 rc-rc5-tv.o \
59 rc-real-audio-220-32-keys.o \
60 rc-tbs-nec.o \
61 rc-terratec-cinergy-xs.o \
62 rc-tevii-nec.o \
63 rc-tt-1500.o \
64 rc-videomate-s350.o \
65 rc-videomate-tv-pvr.o \
66 rc-winfast.o \
67 rc-winfast-usbii-deluxe.o
diff --git a/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c
new file mode 100644
index 000000000000..b17283176ecd
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c
@@ -0,0 +1,89 @@
1/* adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* ADS Tech Instant TV DVB-T PCI Remote */
16
17static struct ir_scancode adstech_dvb_t_pci[] = {
18 /* Keys 0 to 9 */
19 { 0x4d, KEY_0 },
20 { 0x57, KEY_1 },
21 { 0x4f, KEY_2 },
22 { 0x53, KEY_3 },
23 { 0x56, KEY_4 },
24 { 0x4e, KEY_5 },
25 { 0x5e, KEY_6 },
26 { 0x54, KEY_7 },
27 { 0x4c, KEY_8 },
28 { 0x5c, KEY_9 },
29
30 { 0x5b, KEY_POWER },
31 { 0x5f, KEY_MUTE },
32 { 0x55, KEY_GOTO },
33 { 0x5d, KEY_SEARCH },
34 { 0x17, KEY_EPG }, /* Guide */
35 { 0x1f, KEY_MENU },
36 { 0x0f, KEY_UP },
37 { 0x46, KEY_DOWN },
38 { 0x16, KEY_LEFT },
39 { 0x1e, KEY_RIGHT },
40 { 0x0e, KEY_SELECT }, /* Enter */
41 { 0x5a, KEY_INFO },
42 { 0x52, KEY_EXIT },
43 { 0x59, KEY_PREVIOUS },
44 { 0x51, KEY_NEXT },
45 { 0x58, KEY_REWIND },
46 { 0x50, KEY_FORWARD },
47 { 0x44, KEY_PLAYPAUSE },
48 { 0x07, KEY_STOP },
49 { 0x1b, KEY_RECORD },
50 { 0x13, KEY_TUNER }, /* Live */
51 { 0x0a, KEY_A },
52 { 0x12, KEY_B },
53 { 0x03, KEY_PROG1 }, /* 1 */
54 { 0x01, KEY_PROG2 }, /* 2 */
55 { 0x00, KEY_PROG3 }, /* 3 */
56 { 0x06, KEY_DVD },
57 { 0x48, KEY_AUX }, /* Photo */
58 { 0x40, KEY_VIDEO },
59 { 0x19, KEY_AUDIO }, /* Music */
60 { 0x0b, KEY_CHANNELUP },
61 { 0x08, KEY_CHANNELDOWN },
62 { 0x15, KEY_VOLUMEUP },
63 { 0x1c, KEY_VOLUMEDOWN },
64};
65
66static struct rc_keymap adstech_dvb_t_pci_map = {
67 .map = {
68 .scan = adstech_dvb_t_pci,
69 .size = ARRAY_SIZE(adstech_dvb_t_pci),
70 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
71 .name = RC_MAP_ADSTECH_DVB_T_PCI,
72 }
73};
74
75static int __init init_rc_map_adstech_dvb_t_pci(void)
76{
77 return ir_register_map(&adstech_dvb_t_pci_map);
78}
79
80static void __exit exit_rc_map_adstech_dvb_t_pci(void)
81{
82 ir_unregister_map(&adstech_dvb_t_pci_map);
83}
84
85module_init(init_rc_map_adstech_dvb_t_pci)
86module_exit(exit_rc_map_adstech_dvb_t_pci)
87
88MODULE_LICENSE("GPL");
89MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-apac-viewcomp.c b/drivers/media/IR/keymaps/rc-apac-viewcomp.c
new file mode 100644
index 000000000000..0ef2b562baf0
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-apac-viewcomp.c
@@ -0,0 +1,80 @@
1/* apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Attila Kondoros <attila.kondoros@chello.hu> */
16
17static struct ir_scancode apac_viewcomp[] = {
18
19 { 0x01, KEY_1 },
20 { 0x02, KEY_2 },
21 { 0x03, KEY_3 },
22 { 0x04, KEY_4 },
23 { 0x05, KEY_5 },
24 { 0x06, KEY_6 },
25 { 0x07, KEY_7 },
26 { 0x08, KEY_8 },
27 { 0x09, KEY_9 },
28 { 0x00, KEY_0 },
29 { 0x17, KEY_LAST }, /* +100 */
30 { 0x0a, KEY_LIST }, /* recall */
31
32
33 { 0x1c, KEY_TUNER }, /* TV/FM */
34 { 0x15, KEY_SEARCH }, /* scan */
35 { 0x12, KEY_POWER }, /* power */
36 { 0x1f, KEY_VOLUMEDOWN }, /* vol up */
37 { 0x1b, KEY_VOLUMEUP }, /* vol down */
38 { 0x1e, KEY_CHANNELDOWN }, /* chn up */
39 { 0x1a, KEY_CHANNELUP }, /* chn down */
40
41 { 0x11, KEY_VIDEO }, /* video */
42 { 0x0f, KEY_ZOOM }, /* full screen */
43 { 0x13, KEY_MUTE }, /* mute/unmute */
44 { 0x10, KEY_TEXT }, /* min */
45
46 { 0x0d, KEY_STOP }, /* freeze */
47 { 0x0e, KEY_RECORD }, /* record */
48 { 0x1d, KEY_PLAYPAUSE }, /* stop */
49 { 0x19, KEY_PLAY }, /* play */
50
51 { 0x16, KEY_GOTO }, /* osd */
52 { 0x14, KEY_REFRESH }, /* default */
53 { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
54 { 0x18, KEY_KPMINUS }, /* fine tune <<<< */
55};
56
57static struct rc_keymap apac_viewcomp_map = {
58 .map = {
59 .scan = apac_viewcomp,
60 .size = ARRAY_SIZE(apac_viewcomp),
61 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
62 .name = RC_MAP_APAC_VIEWCOMP,
63 }
64};
65
66static int __init init_rc_map_apac_viewcomp(void)
67{
68 return ir_register_map(&apac_viewcomp_map);
69}
70
71static void __exit exit_rc_map_apac_viewcomp(void)
72{
73 ir_unregister_map(&apac_viewcomp_map);
74}
75
76module_init(init_rc_map_apac_viewcomp)
77module_exit(exit_rc_map_apac_viewcomp)
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-asus-pc39.c b/drivers/media/IR/keymaps/rc-asus-pc39.c
new file mode 100644
index 000000000000..2aa068cd6c75
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-asus-pc39.c
@@ -0,0 +1,91 @@
1/* asus-pc39.h - Keytable for asus_pc39 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Marc Fargas <telenieko@telenieko.com>
17 * this is the remote control that comes with the asus p7131
18 * which has a label saying is "Model PC-39"
19 */
20
21static struct ir_scancode asus_pc39[] = {
22 /* Keys 0 to 9 */
23 { 0x15, KEY_0 },
24 { 0x29, KEY_1 },
25 { 0x2d, KEY_2 },
26 { 0x2b, KEY_3 },
27 { 0x09, KEY_4 },
28 { 0x0d, KEY_5 },
29 { 0x0b, KEY_6 },
30 { 0x31, KEY_7 },
31 { 0x35, KEY_8 },
32 { 0x33, KEY_9 },
33
34 { 0x3e, KEY_RADIO }, /* radio */
35 { 0x03, KEY_MENU }, /* dvd/menu */
36 { 0x2a, KEY_VOLUMEUP },
37 { 0x19, KEY_VOLUMEDOWN },
38 { 0x37, KEY_UP },
39 { 0x3b, KEY_DOWN },
40 { 0x27, KEY_LEFT },
41 { 0x2f, KEY_RIGHT },
42 { 0x25, KEY_VIDEO }, /* video */
43 { 0x39, KEY_AUDIO }, /* music */
44
45 { 0x21, KEY_TV }, /* tv */
46 { 0x1d, KEY_EXIT }, /* back */
47 { 0x0a, KEY_CHANNELUP }, /* channel / program + */
48 { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
49 { 0x1a, KEY_ENTER }, /* enter */
50
51 { 0x06, KEY_PAUSE }, /* play/pause */
52 { 0x1e, KEY_PREVIOUS }, /* rew */
53 { 0x26, KEY_NEXT }, /* forward */
54 { 0x0e, KEY_REWIND }, /* backward << */
55 { 0x3a, KEY_FASTFORWARD }, /* forward >> */
56 { 0x36, KEY_STOP },
57 { 0x2e, KEY_RECORD }, /* recording */
58 { 0x16, KEY_POWER }, /* the button that reads "close" */
59
60 { 0x11, KEY_ZOOM }, /* full screen */
61 { 0x13, KEY_MACRO }, /* recall */
62 { 0x23, KEY_HOME }, /* home */
63 { 0x05, KEY_PVR }, /* picture */
64 { 0x3d, KEY_MUTE }, /* mute */
65 { 0x01, KEY_DVD }, /* dvd */
66};
67
68static struct rc_keymap asus_pc39_map = {
69 .map = {
70 .scan = asus_pc39,
71 .size = ARRAY_SIZE(asus_pc39),
72 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
73 .name = RC_MAP_ASUS_PC39,
74 }
75};
76
77static int __init init_rc_map_asus_pc39(void)
78{
79 return ir_register_map(&asus_pc39_map);
80}
81
82static void __exit exit_rc_map_asus_pc39(void)
83{
84 ir_unregister_map(&asus_pc39_map);
85}
86
87module_init(init_rc_map_asus_pc39)
88module_exit(exit_rc_map_asus_pc39)
89
90MODULE_LICENSE("GPL");
91MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c
new file mode 100644
index 000000000000..8edfd293d010
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c
@@ -0,0 +1,69 @@
1/* ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* ATI TV Wonder HD 600 USB
16 Devin Heitmueller <devin.heitmueller@gmail.com>
17 */
18
19static struct ir_scancode ati_tv_wonder_hd_600[] = {
20 { 0x00, KEY_RECORD}, /* Row 1 */
21 { 0x01, KEY_PLAYPAUSE},
22 { 0x02, KEY_STOP},
23 { 0x03, KEY_POWER},
24 { 0x04, KEY_PREVIOUS}, /* Row 2 */
25 { 0x05, KEY_REWIND},
26 { 0x06, KEY_FORWARD},
27 { 0x07, KEY_NEXT},
28 { 0x08, KEY_EPG}, /* Row 3 */
29 { 0x09, KEY_HOME},
30 { 0x0a, KEY_MENU},
31 { 0x0b, KEY_CHANNELUP},
32 { 0x0c, KEY_BACK}, /* Row 4 */
33 { 0x0d, KEY_UP},
34 { 0x0e, KEY_INFO},
35 { 0x0f, KEY_CHANNELDOWN},
36 { 0x10, KEY_LEFT}, /* Row 5 */
37 { 0x11, KEY_SELECT},
38 { 0x12, KEY_RIGHT},
39 { 0x13, KEY_VOLUMEUP},
40 { 0x14, KEY_LAST}, /* Row 6 */
41 { 0x15, KEY_DOWN},
42 { 0x16, KEY_MUTE},
43 { 0x17, KEY_VOLUMEDOWN},
44};
45
46static struct rc_keymap ati_tv_wonder_hd_600_map = {
47 .map = {
48 .scan = ati_tv_wonder_hd_600,
49 .size = ARRAY_SIZE(ati_tv_wonder_hd_600),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_ATI_TV_WONDER_HD_600,
52 }
53};
54
55static int __init init_rc_map_ati_tv_wonder_hd_600(void)
56{
57 return ir_register_map(&ati_tv_wonder_hd_600_map);
58}
59
60static void __exit exit_rc_map_ati_tv_wonder_hd_600(void)
61{
62 ir_unregister_map(&ati_tv_wonder_hd_600_map);
63}
64
65module_init(init_rc_map_ati_tv_wonder_hd_600)
66module_exit(exit_rc_map_ati_tv_wonder_hd_600)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-a16d.c b/drivers/media/IR/keymaps/rc-avermedia-a16d.c
new file mode 100644
index 000000000000..12f043587f2e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-a16d.c
@@ -0,0 +1,75 @@
1/* avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode avermedia_a16d[] = {
16 { 0x20, KEY_LIST},
17 { 0x00, KEY_POWER},
18 { 0x28, KEY_1},
19 { 0x18, KEY_2},
20 { 0x38, KEY_3},
21 { 0x24, KEY_4},
22 { 0x14, KEY_5},
23 { 0x34, KEY_6},
24 { 0x2c, KEY_7},
25 { 0x1c, KEY_8},
26 { 0x3c, KEY_9},
27 { 0x12, KEY_SUBTITLE},
28 { 0x22, KEY_0},
29 { 0x32, KEY_REWIND},
30 { 0x3a, KEY_SHUFFLE},
31 { 0x02, KEY_PRINT},
32 { 0x11, KEY_CHANNELDOWN},
33 { 0x31, KEY_CHANNELUP},
34 { 0x0c, KEY_ZOOM},
35 { 0x1e, KEY_VOLUMEDOWN},
36 { 0x3e, KEY_VOLUMEUP},
37 { 0x0a, KEY_MUTE},
38 { 0x04, KEY_AUDIO},
39 { 0x26, KEY_RECORD},
40 { 0x06, KEY_PLAY},
41 { 0x36, KEY_STOP},
42 { 0x16, KEY_PAUSE},
43 { 0x2e, KEY_REWIND},
44 { 0x0e, KEY_FASTFORWARD},
45 { 0x30, KEY_TEXT},
46 { 0x21, KEY_GREEN},
47 { 0x01, KEY_BLUE},
48 { 0x08, KEY_EPG},
49 { 0x2a, KEY_MENU},
50};
51
52static struct rc_keymap avermedia_a16d_map = {
53 .map = {
54 .scan = avermedia_a16d,
55 .size = ARRAY_SIZE(avermedia_a16d),
56 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
57 .name = RC_MAP_AVERMEDIA_A16D,
58 }
59};
60
61static int __init init_rc_map_avermedia_a16d(void)
62{
63 return ir_register_map(&avermedia_a16d_map);
64}
65
66static void __exit exit_rc_map_avermedia_a16d(void)
67{
68 ir_unregister_map(&avermedia_a16d_map);
69}
70
71module_init(init_rc_map_avermedia_a16d)
72module_exit(exit_rc_map_avermedia_a16d)
73
74MODULE_LICENSE("GPL");
75MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-cardbus.c b/drivers/media/IR/keymaps/rc-avermedia-cardbus.c
new file mode 100644
index 000000000000..2a945b02e8ca
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-cardbus.c
@@ -0,0 +1,97 @@
1/* avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
16
17static struct ir_scancode avermedia_cardbus[] = {
18 { 0x00, KEY_POWER },
19 { 0x01, KEY_TUNER }, /* TV/FM */
20 { 0x03, KEY_TEXT }, /* Teletext */
21 { 0x04, KEY_EPG },
22 { 0x05, KEY_1 },
23 { 0x06, KEY_2 },
24 { 0x07, KEY_3 },
25 { 0x08, KEY_AUDIO },
26 { 0x09, KEY_4 },
27 { 0x0a, KEY_5 },
28 { 0x0b, KEY_6 },
29 { 0x0c, KEY_ZOOM }, /* Full screen */
30 { 0x0d, KEY_7 },
31 { 0x0e, KEY_8 },
32 { 0x0f, KEY_9 },
33 { 0x10, KEY_PAGEUP }, /* 16-CH PREV */
34 { 0x11, KEY_0 },
35 { 0x12, KEY_INFO },
36 { 0x13, KEY_AGAIN }, /* CH RTN - channel return */
37 { 0x14, KEY_MUTE },
38 { 0x15, KEY_EDIT }, /* Autoscan */
39 { 0x17, KEY_SAVE }, /* Screenshot */
40 { 0x18, KEY_PLAYPAUSE },
41 { 0x19, KEY_RECORD },
42 { 0x1a, KEY_PLAY },
43 { 0x1b, KEY_STOP },
44 { 0x1c, KEY_FASTFORWARD },
45 { 0x1d, KEY_REWIND },
46 { 0x1e, KEY_VOLUMEDOWN },
47 { 0x1f, KEY_VOLUMEUP },
48 { 0x22, KEY_SLEEP }, /* Sleep */
49 { 0x23, KEY_ZOOM }, /* Aspect */
50 { 0x26, KEY_SCREEN }, /* Pos */
51 { 0x27, KEY_ANGLE }, /* Size */
52 { 0x28, KEY_SELECT }, /* Select */
53 { 0x29, KEY_BLUE }, /* Blue/Picture */
54 { 0x2a, KEY_BACKSPACE }, /* Back */
55 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
56 { 0x2c, KEY_DOWN },
57 { 0x2e, KEY_DOT },
58 { 0x2f, KEY_TV }, /* Live TV */
59 { 0x32, KEY_LEFT },
60 { 0x33, KEY_CLEAR }, /* Clear */
61 { 0x35, KEY_RED }, /* Red/TV */
62 { 0x36, KEY_UP },
63 { 0x37, KEY_HOME }, /* Home */
64 { 0x39, KEY_GREEN }, /* Green/Video */
65 { 0x3d, KEY_YELLOW }, /* Yellow/Music */
66 { 0x3e, KEY_OK }, /* Ok */
67 { 0x3f, KEY_RIGHT },
68 { 0x40, KEY_NEXT }, /* Next */
69 { 0x41, KEY_PREVIOUS }, /* Previous */
70 { 0x42, KEY_CHANNELDOWN }, /* Channel down */
71 { 0x43, KEY_CHANNELUP }, /* Channel up */
72};
73
74static struct rc_keymap avermedia_cardbus_map = {
75 .map = {
76 .scan = avermedia_cardbus,
77 .size = ARRAY_SIZE(avermedia_cardbus),
78 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
79 .name = RC_MAP_AVERMEDIA_CARDBUS,
80 }
81};
82
83static int __init init_rc_map_avermedia_cardbus(void)
84{
85 return ir_register_map(&avermedia_cardbus_map);
86}
87
88static void __exit exit_rc_map_avermedia_cardbus(void)
89{
90 ir_unregister_map(&avermedia_cardbus_map);
91}
92
93module_init(init_rc_map_avermedia_cardbus)
94module_exit(exit_rc_map_avermedia_cardbus)
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-dvbt.c b/drivers/media/IR/keymaps/rc-avermedia-dvbt.c
new file mode 100644
index 000000000000..39dde6222875
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-dvbt.c
@@ -0,0 +1,78 @@
1/* avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Matt Jesson <dvb@jesson.eclipse.co.uk */
16
17static struct ir_scancode avermedia_dvbt[] = {
18 { 0x28, KEY_0 }, /* '0' / 'enter' */
19 { 0x22, KEY_1 }, /* '1' */
20 { 0x12, KEY_2 }, /* '2' / 'up arrow' */
21 { 0x32, KEY_3 }, /* '3' */
22 { 0x24, KEY_4 }, /* '4' / 'left arrow' */
23 { 0x14, KEY_5 }, /* '5' */
24 { 0x34, KEY_6 }, /* '6' / 'right arrow' */
25 { 0x26, KEY_7 }, /* '7' */
26 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
27 { 0x36, KEY_9 }, /* '9' */
28
29 { 0x20, KEY_LIST }, /* 'source' */
30 { 0x10, KEY_TEXT }, /* 'teletext' */
31 { 0x00, KEY_POWER }, /* 'power' */
32 { 0x04, KEY_AUDIO }, /* 'audio' */
33 { 0x06, KEY_ZOOM }, /* 'full screen' */
34 { 0x18, KEY_VIDEO }, /* 'display' */
35 { 0x38, KEY_SEARCH }, /* 'loop' */
36 { 0x08, KEY_INFO }, /* 'preview' */
37 { 0x2a, KEY_REWIND }, /* 'backward <<' */
38 { 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
39 { 0x3a, KEY_RECORD }, /* 'capture' */
40 { 0x0a, KEY_MUTE }, /* 'mute' */
41 { 0x2c, KEY_RECORD }, /* 'record' */
42 { 0x1c, KEY_PAUSE }, /* 'pause' */
43 { 0x3c, KEY_STOP }, /* 'stop' */
44 { 0x0c, KEY_PLAY }, /* 'play' */
45 { 0x2e, KEY_RED }, /* 'red' */
46 { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
47 { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
48 { 0x21, KEY_GREEN }, /* 'green' */
49 { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
50 { 0x31, KEY_CHANNELUP }, /* 'channel +' */
51 { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
52 { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
53};
54
55static struct rc_keymap avermedia_dvbt_map = {
56 .map = {
57 .scan = avermedia_dvbt,
58 .size = ARRAY_SIZE(avermedia_dvbt),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_AVERMEDIA_DVBT,
61 }
62};
63
64static int __init init_rc_map_avermedia_dvbt(void)
65{
66 return ir_register_map(&avermedia_dvbt_map);
67}
68
69static void __exit exit_rc_map_avermedia_dvbt(void)
70{
71 ir_unregister_map(&avermedia_dvbt_map);
72}
73
74module_init(init_rc_map_avermedia_dvbt)
75module_exit(exit_rc_map_avermedia_dvbt)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c b/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c
new file mode 100644
index 000000000000..101e7ea85941
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c
@@ -0,0 +1,90 @@
1/* avermedia-m135a-rm-jx.h - Keytable for avermedia_m135a_rm_jx Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Avermedia M135A with IR model RM-JX
17 * The same codes exist on both Positivo (BR) and original IR
18 * Mauro Carvalho Chehab <mchehab@infradead.org>
19 */
20
21static struct ir_scancode avermedia_m135a_rm_jx[] = {
22 { 0x0200, KEY_POWER2 },
23 { 0x022e, KEY_DOT }, /* '.' */
24 { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
25
26 { 0x0205, KEY_1 },
27 { 0x0206, KEY_2 },
28 { 0x0207, KEY_3 },
29 { 0x0209, KEY_4 },
30 { 0x020a, KEY_5 },
31 { 0x020b, KEY_6 },
32 { 0x020d, KEY_7 },
33 { 0x020e, KEY_8 },
34 { 0x020f, KEY_9 },
35 { 0x0211, KEY_0 },
36
37 { 0x0213, KEY_RIGHT }, /* -> or L */
38 { 0x0212, KEY_LEFT }, /* <- or R */
39
40 { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
41 { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
42
43 { 0x0303, KEY_CHANNELUP },
44 { 0x0302, KEY_CHANNELDOWN },
45 { 0x021f, KEY_VOLUMEUP },
46 { 0x021e, KEY_VOLUMEDOWN },
47 { 0x020c, KEY_ENTER }, /* Full Screen */
48
49 { 0x0214, KEY_MUTE },
50 { 0x0208, KEY_AUDIO },
51
52 { 0x0203, KEY_TEXT }, /* Teletext */
53 { 0x0204, KEY_EPG },
54 { 0x022b, KEY_TV2 }, /* TV2 or PIP */
55
56 { 0x021d, KEY_RED },
57 { 0x021c, KEY_YELLOW },
58 { 0x0301, KEY_GREEN },
59 { 0x0300, KEY_BLUE },
60
61 { 0x021a, KEY_PLAYPAUSE },
62 { 0x0219, KEY_RECORD },
63 { 0x0218, KEY_PLAY },
64 { 0x021b, KEY_STOP },
65};
66
67static struct rc_keymap avermedia_m135a_rm_jx_map = {
68 .map = {
69 .scan = avermedia_m135a_rm_jx,
70 .size = ARRAY_SIZE(avermedia_m135a_rm_jx),
71 .ir_type = IR_TYPE_NEC,
72 .name = RC_MAP_AVERMEDIA_M135A_RM_JX,
73 }
74};
75
76static int __init init_rc_map_avermedia_m135a_rm_jx(void)
77{
78 return ir_register_map(&avermedia_m135a_rm_jx_map);
79}
80
81static void __exit exit_rc_map_avermedia_m135a_rm_jx(void)
82{
83 ir_unregister_map(&avermedia_m135a_rm_jx_map);
84}
85
86module_init(init_rc_map_avermedia_m135a_rm_jx)
87module_exit(exit_rc_map_avermedia_m135a_rm_jx)
88
89MODULE_LICENSE("GPL");
90MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avermedia.c b/drivers/media/IR/keymaps/rc-avermedia.c
new file mode 100644
index 000000000000..21effd5bfb0d
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avermedia.c
@@ -0,0 +1,86 @@
1/* avermedia.h - Keytable for avermedia Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Alex Hermann <gaaf@gmx.net> */
16
17static struct ir_scancode avermedia[] = {
18 { 0x28, KEY_1 },
19 { 0x18, KEY_2 },
20 { 0x38, KEY_3 },
21 { 0x24, KEY_4 },
22 { 0x14, KEY_5 },
23 { 0x34, KEY_6 },
24 { 0x2c, KEY_7 },
25 { 0x1c, KEY_8 },
26 { 0x3c, KEY_9 },
27 { 0x22, KEY_0 },
28
29 { 0x20, KEY_TV }, /* TV/FM */
30 { 0x10, KEY_CD }, /* CD */
31 { 0x30, KEY_TEXT }, /* TELETEXT */
32 { 0x00, KEY_POWER }, /* POWER */
33
34 { 0x08, KEY_VIDEO }, /* VIDEO */
35 { 0x04, KEY_AUDIO }, /* AUDIO */
36 { 0x0c, KEY_ZOOM }, /* FULL SCREEN */
37
38 { 0x12, KEY_SUBTITLE }, /* DISPLAY */
39 { 0x32, KEY_REWIND }, /* LOOP */
40 { 0x02, KEY_PRINT }, /* PREVIEW */
41
42 { 0x2a, KEY_SEARCH }, /* AUTOSCAN */
43 { 0x1a, KEY_SLEEP }, /* FREEZE */
44 { 0x3a, KEY_CAMERA }, /* SNAPSHOT */
45 { 0x0a, KEY_MUTE }, /* MUTE */
46
47 { 0x26, KEY_RECORD }, /* RECORD */
48 { 0x16, KEY_PAUSE }, /* PAUSE */
49 { 0x36, KEY_STOP }, /* STOP */
50 { 0x06, KEY_PLAY }, /* PLAY */
51
52 { 0x2e, KEY_RED }, /* RED */
53 { 0x21, KEY_GREEN }, /* GREEN */
54 { 0x0e, KEY_YELLOW }, /* YELLOW */
55 { 0x01, KEY_BLUE }, /* BLUE */
56
57 { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
58 { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
59 { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
60 { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
61};
62
63static struct rc_keymap avermedia_map = {
64 .map = {
65 .scan = avermedia,
66 .size = ARRAY_SIZE(avermedia),
67 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
68 .name = RC_MAP_AVERMEDIA,
69 }
70};
71
72static int __init init_rc_map_avermedia(void)
73{
74 return ir_register_map(&avermedia_map);
75}
76
77static void __exit exit_rc_map_avermedia(void)
78{
79 ir_unregister_map(&avermedia_map);
80}
81
82module_init(init_rc_map_avermedia)
83module_exit(exit_rc_map_avermedia)
84
85MODULE_LICENSE("GPL");
86MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-avertv-303.c b/drivers/media/IR/keymaps/rc-avertv-303.c
new file mode 100644
index 000000000000..971c59d6f9d6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-avertv-303.c
@@ -0,0 +1,85 @@
1/* avertv-303.h - Keytable for avertv_303 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* AVERTV STUDIO 303 Remote */
16
17static struct ir_scancode avertv_303[] = {
18 { 0x2a, KEY_1 },
19 { 0x32, KEY_2 },
20 { 0x3a, KEY_3 },
21 { 0x4a, KEY_4 },
22 { 0x52, KEY_5 },
23 { 0x5a, KEY_6 },
24 { 0x6a, KEY_7 },
25 { 0x72, KEY_8 },
26 { 0x7a, KEY_9 },
27 { 0x0e, KEY_0 },
28
29 { 0x02, KEY_POWER },
30 { 0x22, KEY_VIDEO },
31 { 0x42, KEY_AUDIO },
32 { 0x62, KEY_ZOOM },
33 { 0x0a, KEY_TV },
34 { 0x12, KEY_CD },
35 { 0x1a, KEY_TEXT },
36
37 { 0x16, KEY_SUBTITLE },
38 { 0x1e, KEY_REWIND },
39 { 0x06, KEY_PRINT },
40
41 { 0x2e, KEY_SEARCH },
42 { 0x36, KEY_SLEEP },
43 { 0x3e, KEY_SHUFFLE },
44 { 0x26, KEY_MUTE },
45
46 { 0x4e, KEY_RECORD },
47 { 0x56, KEY_PAUSE },
48 { 0x5e, KEY_STOP },
49 { 0x46, KEY_PLAY },
50
51 { 0x6e, KEY_RED },
52 { 0x0b, KEY_GREEN },
53 { 0x66, KEY_YELLOW },
54 { 0x03, KEY_BLUE },
55
56 { 0x76, KEY_LEFT },
57 { 0x7e, KEY_RIGHT },
58 { 0x13, KEY_DOWN },
59 { 0x1b, KEY_UP },
60};
61
62static struct rc_keymap avertv_303_map = {
63 .map = {
64 .scan = avertv_303,
65 .size = ARRAY_SIZE(avertv_303),
66 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
67 .name = RC_MAP_AVERTV_303,
68 }
69};
70
71static int __init init_rc_map_avertv_303(void)
72{
73 return ir_register_map(&avertv_303_map);
74}
75
76static void __exit exit_rc_map_avertv_303(void)
77{
78 ir_unregister_map(&avertv_303_map);
79}
80
81module_init(init_rc_map_avertv_303)
82module_exit(exit_rc_map_avertv_303)
83
84MODULE_LICENSE("GPL");
85MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-behold-columbus.c b/drivers/media/IR/keymaps/rc-behold-columbus.c
new file mode 100644
index 000000000000..9f56c98fef5b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-behold-columbus.c
@@ -0,0 +1,108 @@
1/* behold-columbus.h - Keytable for behold_columbus Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Beholder Intl. Ltd. 2008
16 * Dmitry Belimov d.belimov@google.com
17 * Keytable is used by BeholdTV Columbus
18 * The "ascii-art picture" below (in comments, first row
19 * is the keycode in hex, and subsequent row(s) shows
20 * the button labels (several variants when appropriate)
21 * helps to descide which keycodes to assign to the buttons.
22 */
23
24static struct ir_scancode behold_columbus[] = {
25
26 /* 0x13 0x11 0x1C 0x12 *
27 * Mute Source TV/FM Power *
28 * */
29
30 { 0x13, KEY_MUTE },
31 { 0x11, KEY_PROPS },
32 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
33 { 0x12, KEY_POWER },
34
35 /* 0x01 0x02 0x03 0x0D *
36 * 1 2 3 Stereo *
37 * *
38 * 0x04 0x05 0x06 0x19 *
39 * 4 5 6 Snapshot *
40 * *
41 * 0x07 0x08 0x09 0x10 *
42 * 7 8 9 Zoom *
43 * */
44 { 0x01, KEY_1 },
45 { 0x02, KEY_2 },
46 { 0x03, KEY_3 },
47 { 0x0D, KEY_SETUP }, /* Setup key */
48 { 0x04, KEY_4 },
49 { 0x05, KEY_5 },
50 { 0x06, KEY_6 },
51 { 0x19, KEY_CAMERA }, /* Snapshot key */
52 { 0x07, KEY_7 },
53 { 0x08, KEY_8 },
54 { 0x09, KEY_9 },
55 { 0x10, KEY_ZOOM },
56
57 /* 0x0A 0x00 0x0B 0x0C *
58 * RECALL 0 ChannelUp VolumeUp *
59 * */
60 { 0x0A, KEY_AGAIN },
61 { 0x00, KEY_0 },
62 { 0x0B, KEY_CHANNELUP },
63 { 0x0C, KEY_VOLUMEUP },
64
65 /* 0x1B 0x1D 0x15 0x18 *
66 * Timeshift Record ChannelDown VolumeDown *
67 * */
68
69 { 0x1B, KEY_TIME },
70 { 0x1D, KEY_RECORD },
71 { 0x15, KEY_CHANNELDOWN },
72 { 0x18, KEY_VOLUMEDOWN },
73
74 /* 0x0E 0x1E 0x0F 0x1A *
75 * Stop Pause Previouse Next *
76 * */
77
78 { 0x0E, KEY_STOP },
79 { 0x1E, KEY_PAUSE },
80 { 0x0F, KEY_PREVIOUS },
81 { 0x1A, KEY_NEXT },
82
83};
84
85static struct rc_keymap behold_columbus_map = {
86 .map = {
87 .scan = behold_columbus,
88 .size = ARRAY_SIZE(behold_columbus),
89 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
90 .name = RC_MAP_BEHOLD_COLUMBUS,
91 }
92};
93
94static int __init init_rc_map_behold_columbus(void)
95{
96 return ir_register_map(&behold_columbus_map);
97}
98
99static void __exit exit_rc_map_behold_columbus(void)
100{
101 ir_unregister_map(&behold_columbus_map);
102}
103
104module_init(init_rc_map_behold_columbus)
105module_exit(exit_rc_map_behold_columbus)
106
107MODULE_LICENSE("GPL");
108MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-behold.c b/drivers/media/IR/keymaps/rc-behold.c
new file mode 100644
index 000000000000..abc140b2098b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-behold.c
@@ -0,0 +1,141 @@
1/* behold.h - Keytable for behold Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Igor Kuznetsov <igk72@ya.ru>
17 * Andrey J. Melnikov <temnota@kmv.ru>
18 *
19 * Keytable is used by BeholdTV 60x series, M6 series at
20 * least, and probably other cards too.
21 * The "ascii-art picture" below (in comments, first row
22 * is the keycode in hex, and subsequent row(s) shows
23 * the button labels (several variants when appropriate)
24 * helps to descide which keycodes to assign to the buttons.
25 */
26
27static struct ir_scancode behold[] = {
28
29 /* 0x1c 0x12 *
30 * TV/FM POWER *
31 * */
32 { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
33 { 0x12, KEY_POWER },
34
35 /* 0x01 0x02 0x03 *
36 * 1 2 3 *
37 * *
38 * 0x04 0x05 0x06 *
39 * 4 5 6 *
40 * *
41 * 0x07 0x08 0x09 *
42 * 7 8 9 *
43 * */
44 { 0x01, KEY_1 },
45 { 0x02, KEY_2 },
46 { 0x03, KEY_3 },
47 { 0x04, KEY_4 },
48 { 0x05, KEY_5 },
49 { 0x06, KEY_6 },
50 { 0x07, KEY_7 },
51 { 0x08, KEY_8 },
52 { 0x09, KEY_9 },
53
54 /* 0x0a 0x00 0x17 *
55 * RECALL 0 MODE *
56 * */
57 { 0x0a, KEY_AGAIN },
58 { 0x00, KEY_0 },
59 { 0x17, KEY_MODE },
60
61 /* 0x14 0x10 *
62 * ASPECT FULLSCREEN *
63 * */
64 { 0x14, KEY_SCREEN },
65 { 0x10, KEY_ZOOM },
66
67 /* 0x0b *
68 * Up *
69 * *
70 * 0x18 0x16 0x0c *
71 * Left Ok Right *
72 * *
73 * 0x015 *
74 * Down *
75 * */
76 { 0x0b, KEY_CHANNELUP },
77 { 0x18, KEY_VOLUMEDOWN },
78 { 0x16, KEY_OK }, /* XXX KEY_ENTER */
79 { 0x0c, KEY_VOLUMEUP },
80 { 0x15, KEY_CHANNELDOWN },
81
82 /* 0x11 0x0d *
83 * MUTE INFO *
84 * */
85 { 0x11, KEY_MUTE },
86 { 0x0d, KEY_INFO },
87
88 /* 0x0f 0x1b 0x1a *
89 * RECORD PLAY/PAUSE STOP *
90 * *
91 * 0x0e 0x1f 0x1e *
92 *TELETEXT AUDIO SOURCE *
93 * RED YELLOW *
94 * */
95 { 0x0f, KEY_RECORD },
96 { 0x1b, KEY_PLAYPAUSE },
97 { 0x1a, KEY_STOP },
98 { 0x0e, KEY_TEXT },
99 { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
100 { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
101
102 /* 0x1d 0x13 0x19 *
103 * SLEEP PREVIEW DVB *
104 * GREEN BLUE *
105 * */
106 { 0x1d, KEY_SLEEP },
107 { 0x13, KEY_GREEN },
108 { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
109
110 /* 0x58 0x5c *
111 * FREEZE SNAPSHOT *
112 * */
113 { 0x58, KEY_SLOW },
114 { 0x5c, KEY_CAMERA },
115
116};
117
118static struct rc_keymap behold_map = {
119 .map = {
120 .scan = behold,
121 .size = ARRAY_SIZE(behold),
122 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
123 .name = RC_MAP_BEHOLD,
124 }
125};
126
127static int __init init_rc_map_behold(void)
128{
129 return ir_register_map(&behold_map);
130}
131
132static void __exit exit_rc_map_behold(void)
133{
134 ir_unregister_map(&behold_map);
135}
136
137module_init(init_rc_map_behold)
138module_exit(exit_rc_map_behold)
139
140MODULE_LICENSE("GPL");
141MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-budget-ci-old.c b/drivers/media/IR/keymaps/rc-budget-ci-old.c
new file mode 100644
index 000000000000..64c2ac913338
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-budget-ci-old.c
@@ -0,0 +1,92 @@
1/* budget-ci-old.h - Keytable for budget_ci_old Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* From reading the following remotes:
16 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
17 * Hauppauge (from NOVA-CI-s box product)
18 * This is a "middle of the road" approach, differences are noted
19 */
20
21static struct ir_scancode budget_ci_old[] = {
22 { 0x00, KEY_0 },
23 { 0x01, KEY_1 },
24 { 0x02, KEY_2 },
25 { 0x03, KEY_3 },
26 { 0x04, KEY_4 },
27 { 0x05, KEY_5 },
28 { 0x06, KEY_6 },
29 { 0x07, KEY_7 },
30 { 0x08, KEY_8 },
31 { 0x09, KEY_9 },
32 { 0x0a, KEY_ENTER },
33 { 0x0b, KEY_RED },
34 { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
35 { 0x0d, KEY_MUTE },
36 { 0x0f, KEY_A }, /* TV on Hauppauge */
37 { 0x10, KEY_VOLUMEUP },
38 { 0x11, KEY_VOLUMEDOWN },
39 { 0x14, KEY_B },
40 { 0x1c, KEY_UP },
41 { 0x1d, KEY_DOWN },
42 { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
43 { 0x1f, KEY_BREAK },
44 { 0x20, KEY_CHANNELUP },
45 { 0x21, KEY_CHANNELDOWN },
46 { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
47 { 0x24, KEY_RESTART },
48 { 0x25, KEY_OK },
49 { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
50 { 0x28, KEY_ENTER }, /* VCR mode on Zenith */
51 { 0x29, KEY_PAUSE },
52 { 0x2b, KEY_RIGHT },
53 { 0x2c, KEY_LEFT },
54 { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
55 { 0x30, KEY_SLOW },
56 { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
57 { 0x32, KEY_REWIND },
58 { 0x34, KEY_FASTFORWARD },
59 { 0x35, KEY_PLAY },
60 { 0x36, KEY_STOP },
61 { 0x37, KEY_RECORD },
62 { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
63 { 0x3a, KEY_C },
64 { 0x3c, KEY_EXIT },
65 { 0x3d, KEY_POWER2 },
66 { 0x3e, KEY_TUNER },
67};
68
69static struct rc_keymap budget_ci_old_map = {
70 .map = {
71 .scan = budget_ci_old,
72 .size = ARRAY_SIZE(budget_ci_old),
73 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
74 .name = RC_MAP_BUDGET_CI_OLD,
75 }
76};
77
78static int __init init_rc_map_budget_ci_old(void)
79{
80 return ir_register_map(&budget_ci_old_map);
81}
82
83static void __exit exit_rc_map_budget_ci_old(void)
84{
85 ir_unregister_map(&budget_ci_old_map);
86}
87
88module_init(init_rc_map_budget_ci_old)
89module_exit(exit_rc_map_budget_ci_old)
90
91MODULE_LICENSE("GPL");
92MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-cinergy-1400.c b/drivers/media/IR/keymaps/rc-cinergy-1400.c
new file mode 100644
index 000000000000..074f2c2c2c61
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-cinergy-1400.c
@@ -0,0 +1,84 @@
1/* cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Cinergy 1400 DVB-T */
16
17static struct ir_scancode cinergy_1400[] = {
18 { 0x01, KEY_POWER },
19 { 0x02, KEY_1 },
20 { 0x03, KEY_2 },
21 { 0x04, KEY_3 },
22 { 0x05, KEY_4 },
23 { 0x06, KEY_5 },
24 { 0x07, KEY_6 },
25 { 0x08, KEY_7 },
26 { 0x09, KEY_8 },
27 { 0x0a, KEY_9 },
28 { 0x0c, KEY_0 },
29
30 { 0x0b, KEY_VIDEO },
31 { 0x0d, KEY_REFRESH },
32 { 0x0e, KEY_SELECT },
33 { 0x0f, KEY_EPG },
34 { 0x10, KEY_UP },
35 { 0x11, KEY_LEFT },
36 { 0x12, KEY_OK },
37 { 0x13, KEY_RIGHT },
38 { 0x14, KEY_DOWN },
39 { 0x15, KEY_TEXT },
40 { 0x16, KEY_INFO },
41
42 { 0x17, KEY_RED },
43 { 0x18, KEY_GREEN },
44 { 0x19, KEY_YELLOW },
45 { 0x1a, KEY_BLUE },
46
47 { 0x1b, KEY_CHANNELUP },
48 { 0x1c, KEY_VOLUMEUP },
49 { 0x1d, KEY_MUTE },
50 { 0x1e, KEY_VOLUMEDOWN },
51 { 0x1f, KEY_CHANNELDOWN },
52
53 { 0x40, KEY_PAUSE },
54 { 0x4c, KEY_PLAY },
55 { 0x58, KEY_RECORD },
56 { 0x54, KEY_PREVIOUS },
57 { 0x48, KEY_STOP },
58 { 0x5c, KEY_NEXT },
59};
60
61static struct rc_keymap cinergy_1400_map = {
62 .map = {
63 .scan = cinergy_1400,
64 .size = ARRAY_SIZE(cinergy_1400),
65 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
66 .name = RC_MAP_CINERGY_1400,
67 }
68};
69
70static int __init init_rc_map_cinergy_1400(void)
71{
72 return ir_register_map(&cinergy_1400_map);
73}
74
75static void __exit exit_rc_map_cinergy_1400(void)
76{
77 ir_unregister_map(&cinergy_1400_map);
78}
79
80module_init(init_rc_map_cinergy_1400)
81module_exit(exit_rc_map_cinergy_1400)
82
83MODULE_LICENSE("GPL");
84MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-cinergy.c b/drivers/media/IR/keymaps/rc-cinergy.c
new file mode 100644
index 000000000000..cf84c3dba742
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-cinergy.c
@@ -0,0 +1,78 @@
1/* cinergy.h - Keytable for cinergy Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode cinergy[] = {
16 { 0x00, KEY_0 },
17 { 0x01, KEY_1 },
18 { 0x02, KEY_2 },
19 { 0x03, KEY_3 },
20 { 0x04, KEY_4 },
21 { 0x05, KEY_5 },
22 { 0x06, KEY_6 },
23 { 0x07, KEY_7 },
24 { 0x08, KEY_8 },
25 { 0x09, KEY_9 },
26
27 { 0x0a, KEY_POWER },
28 { 0x0b, KEY_PROG1 }, /* app */
29 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
30 { 0x0d, KEY_CHANNELUP }, /* channel */
31 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
32 { 0x0f, KEY_VOLUMEUP },
33 { 0x10, KEY_VOLUMEDOWN },
34 { 0x11, KEY_TUNER }, /* AV */
35 { 0x12, KEY_NUMLOCK }, /* -/-- */
36 { 0x13, KEY_AUDIO }, /* audio */
37 { 0x14, KEY_MUTE },
38 { 0x15, KEY_UP },
39 { 0x16, KEY_DOWN },
40 { 0x17, KEY_LEFT },
41 { 0x18, KEY_RIGHT },
42 { 0x19, BTN_LEFT, },
43 { 0x1a, BTN_RIGHT, },
44 { 0x1b, KEY_WWW }, /* text */
45 { 0x1c, KEY_REWIND },
46 { 0x1d, KEY_FORWARD },
47 { 0x1e, KEY_RECORD },
48 { 0x1f, KEY_PLAY },
49 { 0x20, KEY_PREVIOUSSONG },
50 { 0x21, KEY_NEXTSONG },
51 { 0x22, KEY_PAUSE },
52 { 0x23, KEY_STOP },
53};
54
55static struct rc_keymap cinergy_map = {
56 .map = {
57 .scan = cinergy,
58 .size = ARRAY_SIZE(cinergy),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_CINERGY,
61 }
62};
63
64static int __init init_rc_map_cinergy(void)
65{
66 return ir_register_map(&cinergy_map);
67}
68
69static void __exit exit_rc_map_cinergy(void)
70{
71 ir_unregister_map(&cinergy_map);
72}
73
74module_init(init_rc_map_cinergy)
75module_exit(exit_rc_map_cinergy)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-dm1105-nec.c b/drivers/media/IR/keymaps/rc-dm1105-nec.c
new file mode 100644
index 000000000000..90684d0efea3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-dm1105-nec.c
@@ -0,0 +1,76 @@
1/* dm1105-nec.h - Keytable for dm1105_nec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DVBWorld remotes
16 Igor M. Liplianin <liplianin@me.by>
17 */
18
19static struct ir_scancode dm1105_nec[] = {
20 { 0x0a, KEY_POWER2}, /* power */
21 { 0x0c, KEY_MUTE}, /* mute */
22 { 0x11, KEY_1},
23 { 0x12, KEY_2},
24 { 0x13, KEY_3},
25 { 0x14, KEY_4},
26 { 0x15, KEY_5},
27 { 0x16, KEY_6},
28 { 0x17, KEY_7},
29 { 0x18, KEY_8},
30 { 0x19, KEY_9},
31 { 0x10, KEY_0},
32 { 0x1c, KEY_CHANNELUP}, /* ch+ */
33 { 0x0f, KEY_CHANNELDOWN}, /* ch- */
34 { 0x1a, KEY_VOLUMEUP}, /* vol+ */
35 { 0x0e, KEY_VOLUMEDOWN}, /* vol- */
36 { 0x04, KEY_RECORD}, /* rec */
37 { 0x09, KEY_CHANNEL}, /* fav */
38 { 0x08, KEY_BACKSPACE}, /* rewind */
39 { 0x07, KEY_FASTFORWARD}, /* fast */
40 { 0x0b, KEY_PAUSE}, /* pause */
41 { 0x02, KEY_ESC}, /* cancel */
42 { 0x03, KEY_TAB}, /* tab */
43 { 0x00, KEY_UP}, /* up */
44 { 0x1f, KEY_ENTER}, /* ok */
45 { 0x01, KEY_DOWN}, /* down */
46 { 0x05, KEY_RECORD}, /* cap */
47 { 0x06, KEY_STOP}, /* stop */
48 { 0x40, KEY_ZOOM}, /* full */
49 { 0x1e, KEY_TV}, /* tvmode */
50 { 0x1b, KEY_B}, /* recall */
51};
52
53static struct rc_keymap dm1105_nec_map = {
54 .map = {
55 .scan = dm1105_nec,
56 .size = ARRAY_SIZE(dm1105_nec),
57 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
58 .name = RC_MAP_DM1105_NEC,
59 }
60};
61
62static int __init init_rc_map_dm1105_nec(void)
63{
64 return ir_register_map(&dm1105_nec_map);
65}
66
67static void __exit exit_rc_map_dm1105_nec(void)
68{
69 ir_unregister_map(&dm1105_nec_map);
70}
71
72module_init(init_rc_map_dm1105_nec)
73module_exit(exit_rc_map_dm1105_nec)
74
75MODULE_LICENSE("GPL");
76MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c
new file mode 100644
index 000000000000..8a4027af964a
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c
@@ -0,0 +1,78 @@
1/* dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DigitalNow DNTV Live DVB-T Remote */
16
17static struct ir_scancode dntv_live_dvb_t[] = {
18 { 0x00, KEY_ESC }, /* 'go up a level?' */
19 /* Keys 0 to 9 */
20 { 0x0a, KEY_0 },
21 { 0x01, KEY_1 },
22 { 0x02, KEY_2 },
23 { 0x03, KEY_3 },
24 { 0x04, KEY_4 },
25 { 0x05, KEY_5 },
26 { 0x06, KEY_6 },
27 { 0x07, KEY_7 },
28 { 0x08, KEY_8 },
29 { 0x09, KEY_9 },
30
31 { 0x0b, KEY_TUNER }, /* tv/fm */
32 { 0x0c, KEY_SEARCH }, /* scan */
33 { 0x0d, KEY_STOP },
34 { 0x0e, KEY_PAUSE },
35 { 0x0f, KEY_LIST }, /* source */
36
37 { 0x10, KEY_MUTE },
38 { 0x11, KEY_REWIND }, /* backward << */
39 { 0x12, KEY_POWER },
40 { 0x13, KEY_CAMERA }, /* snap */
41 { 0x14, KEY_AUDIO }, /* stereo */
42 { 0x15, KEY_CLEAR }, /* reset */
43 { 0x16, KEY_PLAY },
44 { 0x17, KEY_ENTER },
45 { 0x18, KEY_ZOOM }, /* full screen */
46 { 0x19, KEY_FASTFORWARD }, /* forward >> */
47 { 0x1a, KEY_CHANNELUP },
48 { 0x1b, KEY_VOLUMEUP },
49 { 0x1c, KEY_INFO }, /* preview */
50 { 0x1d, KEY_RECORD }, /* record */
51 { 0x1e, KEY_CHANNELDOWN },
52 { 0x1f, KEY_VOLUMEDOWN },
53};
54
55static struct rc_keymap dntv_live_dvb_t_map = {
56 .map = {
57 .scan = dntv_live_dvb_t,
58 .size = ARRAY_SIZE(dntv_live_dvb_t),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_DNTV_LIVE_DVB_T,
61 }
62};
63
64static int __init init_rc_map_dntv_live_dvb_t(void)
65{
66 return ir_register_map(&dntv_live_dvb_t_map);
67}
68
69static void __exit exit_rc_map_dntv_live_dvb_t(void)
70{
71 ir_unregister_map(&dntv_live_dvb_t_map);
72}
73
74module_init(init_rc_map_dntv_live_dvb_t)
75module_exit(exit_rc_map_dntv_live_dvb_t)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c
new file mode 100644
index 000000000000..6f4d60764d59
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c
@@ -0,0 +1,97 @@
1/* dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DigitalNow DNTV Live! DVB-T Pro Remote */
16
17static struct ir_scancode dntv_live_dvbt_pro[] = {
18 { 0x16, KEY_POWER },
19 { 0x5b, KEY_HOME },
20
21 { 0x55, KEY_TV }, /* live tv */
22 { 0x58, KEY_TUNER }, /* digital Radio */
23 { 0x5a, KEY_RADIO }, /* FM radio */
24 { 0x59, KEY_DVD }, /* dvd menu */
25 { 0x03, KEY_1 },
26 { 0x01, KEY_2 },
27 { 0x06, KEY_3 },
28 { 0x09, KEY_4 },
29 { 0x1d, KEY_5 },
30 { 0x1f, KEY_6 },
31 { 0x0d, KEY_7 },
32 { 0x19, KEY_8 },
33 { 0x1b, KEY_9 },
34 { 0x0c, KEY_CANCEL },
35 { 0x15, KEY_0 },
36 { 0x4a, KEY_CLEAR },
37 { 0x13, KEY_BACK },
38 { 0x00, KEY_TAB },
39 { 0x4b, KEY_UP },
40 { 0x4e, KEY_LEFT },
41 { 0x4f, KEY_OK },
42 { 0x52, KEY_RIGHT },
43 { 0x51, KEY_DOWN },
44 { 0x1e, KEY_VOLUMEUP },
45 { 0x0a, KEY_VOLUMEDOWN },
46 { 0x02, KEY_CHANNELDOWN },
47 { 0x05, KEY_CHANNELUP },
48 { 0x11, KEY_RECORD },
49 { 0x14, KEY_PLAY },
50 { 0x4c, KEY_PAUSE },
51 { 0x1a, KEY_STOP },
52 { 0x40, KEY_REWIND },
53 { 0x12, KEY_FASTFORWARD },
54 { 0x41, KEY_PREVIOUSSONG }, /* replay |< */
55 { 0x42, KEY_NEXTSONG }, /* skip >| */
56 { 0x54, KEY_CAMERA }, /* capture */
57 { 0x50, KEY_LANGUAGE }, /* sap */
58 { 0x47, KEY_TV2 }, /* pip */
59 { 0x4d, KEY_SCREEN },
60 { 0x43, KEY_SUBTITLE },
61 { 0x10, KEY_MUTE },
62 { 0x49, KEY_AUDIO }, /* l/r */
63 { 0x07, KEY_SLEEP },
64 { 0x08, KEY_VIDEO }, /* a/v */
65 { 0x0e, KEY_PREVIOUS }, /* recall */
66 { 0x45, KEY_ZOOM }, /* zoom + */
67 { 0x46, KEY_ANGLE }, /* zoom - */
68 { 0x56, KEY_RED },
69 { 0x57, KEY_GREEN },
70 { 0x5c, KEY_YELLOW },
71 { 0x5d, KEY_BLUE },
72};
73
74static struct rc_keymap dntv_live_dvbt_pro_map = {
75 .map = {
76 .scan = dntv_live_dvbt_pro,
77 .size = ARRAY_SIZE(dntv_live_dvbt_pro),
78 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
79 .name = RC_MAP_DNTV_LIVE_DVBT_PRO,
80 }
81};
82
83static int __init init_rc_map_dntv_live_dvbt_pro(void)
84{
85 return ir_register_map(&dntv_live_dvbt_pro_map);
86}
87
88static void __exit exit_rc_map_dntv_live_dvbt_pro(void)
89{
90 ir_unregister_map(&dntv_live_dvbt_pro_map);
91}
92
93module_init(init_rc_map_dntv_live_dvbt_pro)
94module_exit(exit_rc_map_dntv_live_dvbt_pro)
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-em-terratec.c b/drivers/media/IR/keymaps/rc-em-terratec.c
new file mode 100644
index 000000000000..3130c9c29e6b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-em-terratec.c
@@ -0,0 +1,69 @@
1/* em-terratec.h - Keytable for em_terratec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode em_terratec[] = {
16 { 0x01, KEY_CHANNEL },
17 { 0x02, KEY_SELECT },
18 { 0x03, KEY_MUTE },
19 { 0x04, KEY_POWER },
20 { 0x05, KEY_1 },
21 { 0x06, KEY_2 },
22 { 0x07, KEY_3 },
23 { 0x08, KEY_CHANNELUP },
24 { 0x09, KEY_4 },
25 { 0x0a, KEY_5 },
26 { 0x0b, KEY_6 },
27 { 0x0c, KEY_CHANNELDOWN },
28 { 0x0d, KEY_7 },
29 { 0x0e, KEY_8 },
30 { 0x0f, KEY_9 },
31 { 0x10, KEY_VOLUMEUP },
32 { 0x11, KEY_0 },
33 { 0x12, KEY_MENU },
34 { 0x13, KEY_PRINT },
35 { 0x14, KEY_VOLUMEDOWN },
36 { 0x16, KEY_PAUSE },
37 { 0x18, KEY_RECORD },
38 { 0x19, KEY_REWIND },
39 { 0x1a, KEY_PLAY },
40 { 0x1b, KEY_FORWARD },
41 { 0x1c, KEY_BACKSPACE },
42 { 0x1e, KEY_STOP },
43 { 0x40, KEY_ZOOM },
44};
45
46static struct rc_keymap em_terratec_map = {
47 .map = {
48 .scan = em_terratec,
49 .size = ARRAY_SIZE(em_terratec),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_EM_TERRATEC,
52 }
53};
54
55static int __init init_rc_map_em_terratec(void)
56{
57 return ir_register_map(&em_terratec_map);
58}
59
60static void __exit exit_rc_map_em_terratec(void)
61{
62 ir_unregister_map(&em_terratec_map);
63}
64
65module_init(init_rc_map_em_terratec)
66module_exit(exit_rc_map_em_terratec)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-empty.c b/drivers/media/IR/keymaps/rc-empty.c
new file mode 100644
index 000000000000..3b338d84b476
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-empty.c
@@ -0,0 +1,44 @@
1/* empty.h - Keytable for empty Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* empty keytable, can be used as placeholder for not-yet created keytables */
16
17static struct ir_scancode empty[] = {
18 { 0x2a, KEY_COFFEE },
19};
20
21static struct rc_keymap empty_map = {
22 .map = {
23 .scan = empty,
24 .size = ARRAY_SIZE(empty),
25 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
26 .name = RC_MAP_EMPTY,
27 }
28};
29
30static int __init init_rc_map_empty(void)
31{
32 return ir_register_map(&empty_map);
33}
34
35static void __exit exit_rc_map_empty(void)
36{
37 ir_unregister_map(&empty_map);
38}
39
40module_init(init_rc_map_empty)
41module_exit(exit_rc_map_empty)
42
43MODULE_LICENSE("GPL");
44MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c b/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c
new file mode 100644
index 000000000000..4b816967877e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c
@@ -0,0 +1,81 @@
1/* encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Encore ENLTV-FM v5.3
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 */
18
19static struct ir_scancode encore_enltv_fm53[] = {
20 { 0x10, KEY_POWER2},
21 { 0x06, KEY_MUTE},
22
23 { 0x09, KEY_1},
24 { 0x1d, KEY_2},
25 { 0x1f, KEY_3},
26 { 0x19, KEY_4},
27 { 0x1b, KEY_5},
28 { 0x11, KEY_6},
29 { 0x17, KEY_7},
30 { 0x12, KEY_8},
31 { 0x16, KEY_9},
32 { 0x48, KEY_0},
33
34 { 0x04, KEY_LIST}, /* -/-- */
35 { 0x40, KEY_LAST}, /* recall */
36
37 { 0x02, KEY_MODE}, /* TV/AV */
38 { 0x05, KEY_CAMERA}, /* SNAPSHOT */
39
40 { 0x4c, KEY_CHANNELUP}, /* UP */
41 { 0x00, KEY_CHANNELDOWN}, /* DOWN */
42 { 0x0d, KEY_VOLUMEUP}, /* RIGHT */
43 { 0x15, KEY_VOLUMEDOWN}, /* LEFT */
44 { 0x49, KEY_ENTER}, /* OK */
45
46 { 0x54, KEY_RECORD},
47 { 0x4d, KEY_PLAY}, /* pause */
48
49 { 0x1e, KEY_MENU}, /* video setting */
50 { 0x0e, KEY_RIGHT}, /* <- */
51 { 0x1a, KEY_LEFT}, /* -> */
52
53 { 0x0a, KEY_CLEAR}, /* video default */
54 { 0x0c, KEY_ZOOM}, /* hide pannel */
55 { 0x47, KEY_SLEEP}, /* shutdown */
56};
57
58static struct rc_keymap encore_enltv_fm53_map = {
59 .map = {
60 .scan = encore_enltv_fm53,
61 .size = ARRAY_SIZE(encore_enltv_fm53),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_ENCORE_ENLTV_FM53,
64 }
65};
66
67static int __init init_rc_map_encore_enltv_fm53(void)
68{
69 return ir_register_map(&encore_enltv_fm53_map);
70}
71
72static void __exit exit_rc_map_encore_enltv_fm53(void)
73{
74 ir_unregister_map(&encore_enltv_fm53_map);
75}
76
77module_init(init_rc_map_encore_enltv_fm53)
78module_exit(exit_rc_map_encore_enltv_fm53)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv.c b/drivers/media/IR/keymaps/rc-encore-enltv.c
new file mode 100644
index 000000000000..9fabffd28cc9
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-encore-enltv.c
@@ -0,0 +1,112 @@
1/* encore-enltv.h - Keytable for encore_enltv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
16 Juan Pablo Sormani <sorman@gmail.com> */
17
18static struct ir_scancode encore_enltv[] = {
19
20 /* Power button does nothing, neither in Windows app,
21 although it sends data (used for BIOS wakeup?) */
22 { 0x0d, KEY_MUTE },
23
24 { 0x1e, KEY_TV },
25 { 0x00, KEY_VIDEO },
26 { 0x01, KEY_AUDIO }, /* music */
27 { 0x02, KEY_MHP }, /* picture */
28
29 { 0x1f, KEY_1 },
30 { 0x03, KEY_2 },
31 { 0x04, KEY_3 },
32 { 0x05, KEY_4 },
33 { 0x1c, KEY_5 },
34 { 0x06, KEY_6 },
35 { 0x07, KEY_7 },
36 { 0x08, KEY_8 },
37 { 0x1d, KEY_9 },
38 { 0x0a, KEY_0 },
39
40 { 0x09, KEY_LIST }, /* -/-- */
41 { 0x0b, KEY_LAST }, /* recall */
42
43 { 0x14, KEY_HOME }, /* win start menu */
44 { 0x15, KEY_EXIT }, /* exit */
45 { 0x16, KEY_CHANNELUP }, /* UP */
46 { 0x12, KEY_CHANNELDOWN }, /* DOWN */
47 { 0x0c, KEY_VOLUMEUP }, /* RIGHT */
48 { 0x17, KEY_VOLUMEDOWN }, /* LEFT */
49
50 { 0x18, KEY_ENTER }, /* OK */
51
52 { 0x0e, KEY_ESC },
53 { 0x13, KEY_CYCLEWINDOWS }, /* desktop */
54 { 0x11, KEY_TAB },
55 { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
56
57 { 0x1a, KEY_MENU },
58 { 0x1b, KEY_ZOOM }, /* fullscreen */
59 { 0x44, KEY_TIME }, /* time shift */
60 { 0x40, KEY_MODE }, /* source */
61
62 { 0x5a, KEY_RECORD },
63 { 0x42, KEY_PLAY }, /* play/pause */
64 { 0x45, KEY_STOP },
65 { 0x43, KEY_CAMERA }, /* camera icon */
66
67 { 0x48, KEY_REWIND },
68 { 0x4a, KEY_FASTFORWARD },
69 { 0x49, KEY_PREVIOUS },
70 { 0x4b, KEY_NEXT },
71
72 { 0x4c, KEY_FAVORITES }, /* tv wall */
73 { 0x4d, KEY_SOUND }, /* DVD sound */
74 { 0x4e, KEY_LANGUAGE }, /* DVD lang */
75 { 0x4f, KEY_TEXT }, /* DVD text */
76
77 { 0x50, KEY_SLEEP }, /* shutdown */
78 { 0x51, KEY_MODE }, /* stereo > main */
79 { 0x52, KEY_SELECT }, /* stereo > sap */
80 { 0x53, KEY_PROG1 }, /* teletext */
81
82
83 { 0x59, KEY_RED }, /* AP1 */
84 { 0x41, KEY_GREEN }, /* AP2 */
85 { 0x47, KEY_YELLOW }, /* AP3 */
86 { 0x57, KEY_BLUE }, /* AP4 */
87};
88
89static struct rc_keymap encore_enltv_map = {
90 .map = {
91 .scan = encore_enltv,
92 .size = ARRAY_SIZE(encore_enltv),
93 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
94 .name = RC_MAP_ENCORE_ENLTV,
95 }
96};
97
98static int __init init_rc_map_encore_enltv(void)
99{
100 return ir_register_map(&encore_enltv_map);
101}
102
103static void __exit exit_rc_map_encore_enltv(void)
104{
105 ir_unregister_map(&encore_enltv_map);
106}
107
108module_init(init_rc_map_encore_enltv)
109module_exit(exit_rc_map_encore_enltv)
110
111MODULE_LICENSE("GPL");
112MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv2.c b/drivers/media/IR/keymaps/rc-encore-enltv2.c
new file mode 100644
index 000000000000..efefd5166618
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-encore-enltv2.c
@@ -0,0 +1,90 @@
1/* encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
16 Mauro Carvalho Chehab <mchehab@infradead.org> */
17
18static struct ir_scancode encore_enltv2[] = {
19 { 0x4c, KEY_POWER2 },
20 { 0x4a, KEY_TUNER },
21 { 0x40, KEY_1 },
22 { 0x60, KEY_2 },
23 { 0x50, KEY_3 },
24 { 0x70, KEY_4 },
25 { 0x48, KEY_5 },
26 { 0x68, KEY_6 },
27 { 0x58, KEY_7 },
28 { 0x78, KEY_8 },
29 { 0x44, KEY_9 },
30 { 0x54, KEY_0 },
31
32 { 0x64, KEY_LAST }, /* +100 */
33 { 0x4e, KEY_AGAIN }, /* Recall */
34
35 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
36 { 0x5e, KEY_MENU },
37 { 0x56, KEY_SCREEN },
38 { 0x7a, KEY_SETUP },
39
40 { 0x46, KEY_MUTE },
41 { 0x5c, KEY_MODE }, /* Stereo */
42 { 0x74, KEY_INFO },
43 { 0x7c, KEY_CLEAR },
44
45 { 0x55, KEY_UP },
46 { 0x49, KEY_DOWN },
47 { 0x7e, KEY_LEFT },
48 { 0x59, KEY_RIGHT },
49 { 0x6a, KEY_ENTER },
50
51 { 0x42, KEY_VOLUMEUP },
52 { 0x62, KEY_VOLUMEDOWN },
53 { 0x52, KEY_CHANNELUP },
54 { 0x72, KEY_CHANNELDOWN },
55
56 { 0x41, KEY_RECORD },
57 { 0x51, KEY_CAMERA }, /* Snapshot */
58 { 0x75, KEY_TIME }, /* Timeshift */
59 { 0x71, KEY_TV2 }, /* PIP */
60
61 { 0x45, KEY_REWIND },
62 { 0x6f, KEY_PAUSE },
63 { 0x7d, KEY_FORWARD },
64 { 0x79, KEY_STOP },
65};
66
67static struct rc_keymap encore_enltv2_map = {
68 .map = {
69 .scan = encore_enltv2,
70 .size = ARRAY_SIZE(encore_enltv2),
71 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
72 .name = RC_MAP_ENCORE_ENLTV2,
73 }
74};
75
76static int __init init_rc_map_encore_enltv2(void)
77{
78 return ir_register_map(&encore_enltv2_map);
79}
80
81static void __exit exit_rc_map_encore_enltv2(void)
82{
83 ir_unregister_map(&encore_enltv2_map);
84}
85
86module_init(init_rc_map_encore_enltv2)
87module_exit(exit_rc_map_encore_enltv2)
88
89MODULE_LICENSE("GPL");
90MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-evga-indtube.c b/drivers/media/IR/keymaps/rc-evga-indtube.c
new file mode 100644
index 000000000000..3f3fb13813b3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-evga-indtube.c
@@ -0,0 +1,61 @@
1/* evga-indtube.h - Keytable for evga_indtube Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* EVGA inDtube
16 Devin Heitmueller <devin.heitmueller@gmail.com>
17 */
18
19static struct ir_scancode evga_indtube[] = {
20 { 0x12, KEY_POWER},
21 { 0x02, KEY_MODE}, /* TV */
22 { 0x14, KEY_MUTE},
23 { 0x1a, KEY_CHANNELUP},
24 { 0x16, KEY_TV2}, /* PIP */
25 { 0x1d, KEY_VOLUMEUP},
26 { 0x05, KEY_CHANNELDOWN},
27 { 0x0f, KEY_PLAYPAUSE},
28 { 0x19, KEY_VOLUMEDOWN},
29 { 0x1c, KEY_REWIND},
30 { 0x0d, KEY_RECORD},
31 { 0x18, KEY_FORWARD},
32 { 0x1e, KEY_PREVIOUS},
33 { 0x1b, KEY_STOP},
34 { 0x1f, KEY_NEXT},
35 { 0x13, KEY_CAMERA},
36};
37
38static struct rc_keymap evga_indtube_map = {
39 .map = {
40 .scan = evga_indtube,
41 .size = ARRAY_SIZE(evga_indtube),
42 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
43 .name = RC_MAP_EVGA_INDTUBE,
44 }
45};
46
47static int __init init_rc_map_evga_indtube(void)
48{
49 return ir_register_map(&evga_indtube_map);
50}
51
52static void __exit exit_rc_map_evga_indtube(void)
53{
54 ir_unregister_map(&evga_indtube_map);
55}
56
57module_init(init_rc_map_evga_indtube)
58module_exit(exit_rc_map_evga_indtube)
59
60MODULE_LICENSE("GPL");
61MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-eztv.c b/drivers/media/IR/keymaps/rc-eztv.c
new file mode 100644
index 000000000000..660907a78db9
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-eztv.c
@@ -0,0 +1,96 @@
1/* eztv.h - Keytable for eztv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Alfons Geser <a.geser@cox.net>
16 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
17
18static struct ir_scancode eztv[] = {
19 { 0x12, KEY_POWER },
20 { 0x01, KEY_TV }, /* DVR */
21 { 0x15, KEY_DVD }, /* DVD */
22 { 0x17, KEY_AUDIO }, /* music */
23 /* DVR mode / DVD mode / music mode */
24
25 { 0x1b, KEY_MUTE }, /* mute */
26 { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
27 { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
28 { 0x16, KEY_ZOOM }, /* full screen */
29 { 0x1c, KEY_VIDEO }, /* video source / eject / delall */
30 { 0x1d, KEY_RESTART }, /* playback / angle / del */
31 { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
32 { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
33
34 { 0x31, KEY_HELP }, /* help */
35 { 0x32, KEY_MODE }, /* num/memo */
36 { 0x33, KEY_ESC }, /* cancel */
37
38 { 0x0c, KEY_UP }, /* up */
39 { 0x10, KEY_DOWN }, /* down */
40 { 0x08, KEY_LEFT }, /* left */
41 { 0x04, KEY_RIGHT }, /* right */
42 { 0x03, KEY_SELECT }, /* select */
43
44 { 0x1f, KEY_REWIND }, /* rewind */
45 { 0x20, KEY_PLAYPAUSE },/* play/pause */
46 { 0x29, KEY_FORWARD }, /* forward */
47 { 0x14, KEY_AGAIN }, /* repeat */
48 { 0x2b, KEY_RECORD }, /* recording */
49 { 0x2c, KEY_STOP }, /* stop */
50 { 0x2d, KEY_PLAY }, /* play */
51 { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
52
53 { 0x00, KEY_0 },
54 { 0x05, KEY_1 },
55 { 0x06, KEY_2 },
56 { 0x07, KEY_3 },
57 { 0x09, KEY_4 },
58 { 0x0a, KEY_5 },
59 { 0x0b, KEY_6 },
60 { 0x0d, KEY_7 },
61 { 0x0e, KEY_8 },
62 { 0x0f, KEY_9 },
63
64 { 0x2a, KEY_VOLUMEUP },
65 { 0x11, KEY_VOLUMEDOWN },
66 { 0x18, KEY_CHANNELUP },/* CH.tracking up */
67 { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
68
69 { 0x13, KEY_ENTER }, /* enter */
70 { 0x21, KEY_DOT }, /* . (decimal dot) */
71};
72
73static struct rc_keymap eztv_map = {
74 .map = {
75 .scan = eztv,
76 .size = ARRAY_SIZE(eztv),
77 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
78 .name = RC_MAP_EZTV,
79 }
80};
81
82static int __init init_rc_map_eztv(void)
83{
84 return ir_register_map(&eztv_map);
85}
86
87static void __exit exit_rc_map_eztv(void)
88{
89 ir_unregister_map(&eztv_map);
90}
91
92module_init(init_rc_map_eztv)
93module_exit(exit_rc_map_eztv)
94
95MODULE_LICENSE("GPL");
96MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-flydvb.c b/drivers/media/IR/keymaps/rc-flydvb.c
new file mode 100644
index 000000000000..a173c81035f4
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-flydvb.c
@@ -0,0 +1,77 @@
1/* flydvb.h - Keytable for flydvb Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode flydvb[] = {
16 { 0x01, KEY_ZOOM }, /* Full Screen */
17 { 0x00, KEY_POWER }, /* Power */
18
19 { 0x03, KEY_1 },
20 { 0x04, KEY_2 },
21 { 0x05, KEY_3 },
22 { 0x07, KEY_4 },
23 { 0x08, KEY_5 },
24 { 0x09, KEY_6 },
25 { 0x0b, KEY_7 },
26 { 0x0c, KEY_8 },
27 { 0x0d, KEY_9 },
28 { 0x06, KEY_AGAIN }, /* Recall */
29 { 0x0f, KEY_0 },
30 { 0x10, KEY_MUTE }, /* Mute */
31 { 0x02, KEY_RADIO }, /* TV/Radio */
32 { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
33
34 { 0x14, KEY_VOLUMEUP }, /* VOL+ */
35 { 0x17, KEY_VOLUMEDOWN }, /* VOL- */
36 { 0x12, KEY_CHANNELUP }, /* CH+ */
37 { 0x13, KEY_CHANNELDOWN }, /* CH- */
38 { 0x1d, KEY_ENTER }, /* Enter */
39
40 { 0x1a, KEY_MODE }, /* PIP */
41 { 0x18, KEY_TUNER }, /* Source */
42
43 { 0x1e, KEY_RECORD }, /* Record/Pause */
44 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
45 { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
46 { 0x19, KEY_BACK }, /* Rewind << */
47 { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
48 { 0x1f, KEY_FORWARD }, /* Forward >> */
49 { 0x16, KEY_PREVIOUS }, /* Back |<< */
50 { 0x11, KEY_STOP }, /* Stop */
51 { 0x0e, KEY_NEXT }, /* End >>| */
52};
53
54static struct rc_keymap flydvb_map = {
55 .map = {
56 .scan = flydvb,
57 .size = ARRAY_SIZE(flydvb),
58 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
59 .name = RC_MAP_FLYDVB,
60 }
61};
62
63static int __init init_rc_map_flydvb(void)
64{
65 return ir_register_map(&flydvb_map);
66}
67
68static void __exit exit_rc_map_flydvb(void)
69{
70 ir_unregister_map(&flydvb_map);
71}
72
73module_init(init_rc_map_flydvb)
74module_exit(exit_rc_map_flydvb)
75
76MODULE_LICENSE("GPL");
77MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-flyvideo.c b/drivers/media/IR/keymaps/rc-flyvideo.c
new file mode 100644
index 000000000000..9c73043cbdba
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-flyvideo.c
@@ -0,0 +1,70 @@
1/* flyvideo.h - Keytable for flyvideo Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode flyvideo[] = {
16 { 0x0f, KEY_0 },
17 { 0x03, KEY_1 },
18 { 0x04, KEY_2 },
19 { 0x05, KEY_3 },
20 { 0x07, KEY_4 },
21 { 0x08, KEY_5 },
22 { 0x09, KEY_6 },
23 { 0x0b, KEY_7 },
24 { 0x0c, KEY_8 },
25 { 0x0d, KEY_9 },
26
27 { 0x0e, KEY_MODE }, /* Air/Cable */
28 { 0x11, KEY_VIDEO }, /* Video */
29 { 0x15, KEY_AUDIO }, /* Audio */
30 { 0x00, KEY_POWER }, /* Power */
31 { 0x18, KEY_TUNER }, /* AV Source */
32 { 0x02, KEY_ZOOM }, /* Fullscreen */
33 { 0x1a, KEY_LANGUAGE }, /* Stereo */
34 { 0x1b, KEY_MUTE }, /* Mute */
35 { 0x14, KEY_VOLUMEUP }, /* Volume + */
36 { 0x17, KEY_VOLUMEDOWN },/* Volume - */
37 { 0x12, KEY_CHANNELUP },/* Channel + */
38 { 0x13, KEY_CHANNELDOWN },/* Channel - */
39 { 0x06, KEY_AGAIN }, /* Recall */
40 { 0x10, KEY_ENTER }, /* Enter */
41
42 { 0x19, KEY_BACK }, /* Rewind ( <<< ) */
43 { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
44 { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
45};
46
47static struct rc_keymap flyvideo_map = {
48 .map = {
49 .scan = flyvideo,
50 .size = ARRAY_SIZE(flyvideo),
51 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
52 .name = RC_MAP_FLYVIDEO,
53 }
54};
55
56static int __init init_rc_map_flyvideo(void)
57{
58 return ir_register_map(&flyvideo_map);
59}
60
61static void __exit exit_rc_map_flyvideo(void)
62{
63 ir_unregister_map(&flyvideo_map);
64}
65
66module_init(init_rc_map_flyvideo)
67module_exit(exit_rc_map_flyvideo)
68
69MODULE_LICENSE("GPL");
70MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c b/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c
new file mode 100644
index 000000000000..cdb10389b10e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c
@@ -0,0 +1,98 @@
1/* fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* DViCO FUSION HDTV MCE remote */
16
17static struct ir_scancode fusionhdtv_mce[] = {
18
19 { 0x0b, KEY_1 },
20 { 0x17, KEY_2 },
21 { 0x1b, KEY_3 },
22 { 0x07, KEY_4 },
23 { 0x50, KEY_5 },
24 { 0x54, KEY_6 },
25 { 0x48, KEY_7 },
26 { 0x4c, KEY_8 },
27 { 0x58, KEY_9 },
28 { 0x03, KEY_0 },
29
30 { 0x5e, KEY_OK },
31 { 0x51, KEY_UP },
32 { 0x53, KEY_DOWN },
33 { 0x5b, KEY_LEFT },
34 { 0x5f, KEY_RIGHT },
35
36 { 0x02, KEY_TV }, /* Labeled DTV on remote */
37 { 0x0e, KEY_MP3 },
38 { 0x1a, KEY_DVD },
39 { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
40 { 0x16, KEY_SETUP },
41 { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
42 { 0x0a, KEY_EPG }, /* Labeled Guide on remote */
43
44 { 0x49, KEY_BACK },
45 { 0x59, KEY_INFO }, /* Labeled MORE on remote */
46 { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
47 { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
48
49 { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
50 { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
51 { 0x42, KEY_ENTER }, /* Labeled START with a green
52 MS windows logo on remote */
53
54 { 0x15, KEY_VOLUMEUP },
55 { 0x05, KEY_VOLUMEDOWN },
56 { 0x11, KEY_CHANNELUP },
57 { 0x09, KEY_CHANNELDOWN },
58
59 { 0x52, KEY_CAMERA },
60 { 0x5a, KEY_TUNER },
61 { 0x19, KEY_OPEN },
62
63 { 0x13, KEY_MODE }, /* 4:3 16:9 select */
64 { 0x1f, KEY_ZOOM },
65
66 { 0x43, KEY_REWIND },
67 { 0x47, KEY_PLAYPAUSE },
68 { 0x4f, KEY_FASTFORWARD },
69 { 0x57, KEY_MUTE },
70 { 0x0d, KEY_STOP },
71 { 0x01, KEY_RECORD },
72 { 0x4e, KEY_POWER },
73};
74
75static struct rc_keymap fusionhdtv_mce_map = {
76 .map = {
77 .scan = fusionhdtv_mce,
78 .size = ARRAY_SIZE(fusionhdtv_mce),
79 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
80 .name = RC_MAP_FUSIONHDTV_MCE,
81 }
82};
83
84static int __init init_rc_map_fusionhdtv_mce(void)
85{
86 return ir_register_map(&fusionhdtv_mce_map);
87}
88
89static void __exit exit_rc_map_fusionhdtv_mce(void)
90{
91 ir_unregister_map(&fusionhdtv_mce_map);
92}
93
94module_init(init_rc_map_fusionhdtv_mce)
95module_exit(exit_rc_map_fusionhdtv_mce)
96
97MODULE_LICENSE("GPL");
98MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-gadmei-rm008z.c b/drivers/media/IR/keymaps/rc-gadmei-rm008z.c
new file mode 100644
index 000000000000..c16c0d1263ac
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-gadmei-rm008z.c
@@ -0,0 +1,81 @@
1/* gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* GADMEI UTV330+ RM008Z remote
16 Shine Liu <shinel@foxmail.com>
17 */
18
19static struct ir_scancode gadmei_rm008z[] = {
20 { 0x14, KEY_POWER2}, /* POWER OFF */
21 { 0x0c, KEY_MUTE}, /* MUTE */
22
23 { 0x18, KEY_TV}, /* TV */
24 { 0x0e, KEY_VIDEO}, /* AV */
25 { 0x0b, KEY_AUDIO}, /* SV */
26 { 0x0f, KEY_RADIO}, /* FM */
27
28 { 0x00, KEY_1},
29 { 0x01, KEY_2},
30 { 0x02, KEY_3},
31 { 0x03, KEY_4},
32 { 0x04, KEY_5},
33 { 0x05, KEY_6},
34 { 0x06, KEY_7},
35 { 0x07, KEY_8},
36 { 0x08, KEY_9},
37 { 0x09, KEY_0},
38 { 0x0a, KEY_INFO}, /* OSD */
39 { 0x1c, KEY_BACKSPACE}, /* LAST */
40
41 { 0x0d, KEY_PLAY}, /* PLAY */
42 { 0x1e, KEY_CAMERA}, /* SNAPSHOT */
43 { 0x1a, KEY_RECORD}, /* RECORD */
44 { 0x17, KEY_STOP}, /* STOP */
45
46 { 0x1f, KEY_UP}, /* UP */
47 { 0x44, KEY_DOWN}, /* DOWN */
48 { 0x46, KEY_TAB}, /* BACK */
49 { 0x4a, KEY_ZOOM}, /* FULLSECREEN */
50
51 { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
52 { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
53 { 0x12, KEY_CHANNELUP}, /* CHANNELUP */
54 { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
55 { 0x15, KEY_ENTER}, /* OK */
56};
57
58static struct rc_keymap gadmei_rm008z_map = {
59 .map = {
60 .scan = gadmei_rm008z,
61 .size = ARRAY_SIZE(gadmei_rm008z),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_GADMEI_RM008Z,
64 }
65};
66
67static int __init init_rc_map_gadmei_rm008z(void)
68{
69 return ir_register_map(&gadmei_rm008z_map);
70}
71
72static void __exit exit_rc_map_gadmei_rm008z(void)
73{
74 ir_unregister_map(&gadmei_rm008z_map);
75}
76
77module_init(init_rc_map_gadmei_rm008z)
78module_exit(exit_rc_map_gadmei_rm008z)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c
new file mode 100644
index 000000000000..89f8e384e52a
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c
@@ -0,0 +1,84 @@
1/* genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Remote control for the Genius TVGO A11MCE
17 * Adrian Pardini <pardo.bsso@gmail.com>
18 */
19
20static struct ir_scancode genius_tvgo_a11mce[] = {
21 /* Keys 0 to 9 */
22 { 0x48, KEY_0 },
23 { 0x09, KEY_1 },
24 { 0x1d, KEY_2 },
25 { 0x1f, KEY_3 },
26 { 0x19, KEY_4 },
27 { 0x1b, KEY_5 },
28 { 0x11, KEY_6 },
29 { 0x17, KEY_7 },
30 { 0x12, KEY_8 },
31 { 0x16, KEY_9 },
32
33 { 0x54, KEY_RECORD }, /* recording */
34 { 0x06, KEY_MUTE }, /* mute */
35 { 0x10, KEY_POWER },
36 { 0x40, KEY_LAST }, /* recall */
37 { 0x4c, KEY_CHANNELUP }, /* channel / program + */
38 { 0x00, KEY_CHANNELDOWN }, /* channel / program - */
39 { 0x0d, KEY_VOLUMEUP },
40 { 0x15, KEY_VOLUMEDOWN },
41 { 0x4d, KEY_OK }, /* also labeled as Pause */
42 { 0x1c, KEY_ZOOM }, /* full screen and Stop*/
43 { 0x02, KEY_MODE }, /* AV Source or Rewind*/
44 { 0x04, KEY_LIST }, /* -/-- */
45 /* small arrows above numbers */
46 { 0x1a, KEY_NEXT }, /* also Fast Forward */
47 { 0x0e, KEY_PREVIOUS }, /* also Rewind */
48 /* these are in a rather non standard layout and have
49 an alternate name written */
50 { 0x1e, KEY_UP }, /* Video Setting */
51 { 0x0a, KEY_DOWN }, /* Video Default */
52 { 0x05, KEY_CAMERA }, /* Snapshot */
53 { 0x0c, KEY_RIGHT }, /* Hide Panel */
54 /* Four buttons without label */
55 { 0x49, KEY_RED },
56 { 0x0b, KEY_GREEN },
57 { 0x13, KEY_YELLOW },
58 { 0x50, KEY_BLUE },
59};
60
61static struct rc_keymap genius_tvgo_a11mce_map = {
62 .map = {
63 .scan = genius_tvgo_a11mce,
64 .size = ARRAY_SIZE(genius_tvgo_a11mce),
65 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
66 .name = RC_MAP_GENIUS_TVGO_A11MCE,
67 }
68};
69
70static int __init init_rc_map_genius_tvgo_a11mce(void)
71{
72 return ir_register_map(&genius_tvgo_a11mce_map);
73}
74
75static void __exit exit_rc_map_genius_tvgo_a11mce(void)
76{
77 ir_unregister_map(&genius_tvgo_a11mce_map);
78}
79
80module_init(init_rc_map_genius_tvgo_a11mce)
81module_exit(exit_rc_map_genius_tvgo_a11mce)
82
83MODULE_LICENSE("GPL");
84MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-gotview7135.c b/drivers/media/IR/keymaps/rc-gotview7135.c
new file mode 100644
index 000000000000..52f025bb35f6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-gotview7135.c
@@ -0,0 +1,79 @@
1/* gotview7135.h - Keytable for gotview7135 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Mike Baikov <mike@baikov.com> */
16
17static struct ir_scancode gotview7135[] = {
18
19 { 0x11, KEY_POWER },
20 { 0x35, KEY_TV },
21 { 0x1b, KEY_0 },
22 { 0x29, KEY_1 },
23 { 0x19, KEY_2 },
24 { 0x39, KEY_3 },
25 { 0x1f, KEY_4 },
26 { 0x2c, KEY_5 },
27 { 0x21, KEY_6 },
28 { 0x24, KEY_7 },
29 { 0x18, KEY_8 },
30 { 0x2b, KEY_9 },
31 { 0x3b, KEY_AGAIN }, /* LOOP */
32 { 0x06, KEY_AUDIO },
33 { 0x31, KEY_PRINT }, /* PREVIEW */
34 { 0x3e, KEY_VIDEO },
35 { 0x10, KEY_CHANNELUP },
36 { 0x20, KEY_CHANNELDOWN },
37 { 0x0c, KEY_VOLUMEDOWN },
38 { 0x28, KEY_VOLUMEUP },
39 { 0x08, KEY_MUTE },
40 { 0x26, KEY_SEARCH }, /* SCAN */
41 { 0x3f, KEY_CAMERA }, /* SNAPSHOT */
42 { 0x12, KEY_RECORD },
43 { 0x32, KEY_STOP },
44 { 0x3c, KEY_PLAY },
45 { 0x1d, KEY_REWIND },
46 { 0x2d, KEY_PAUSE },
47 { 0x0d, KEY_FORWARD },
48 { 0x05, KEY_ZOOM }, /*FULL*/
49
50 { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
51 { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
52 { 0x1e, KEY_TIME }, /* TIMESHIFT */
53 { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
54};
55
56static struct rc_keymap gotview7135_map = {
57 .map = {
58 .scan = gotview7135,
59 .size = ARRAY_SIZE(gotview7135),
60 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
61 .name = RC_MAP_GOTVIEW7135,
62 }
63};
64
65static int __init init_rc_map_gotview7135(void)
66{
67 return ir_register_map(&gotview7135_map);
68}
69
70static void __exit exit_rc_map_gotview7135(void)
71{
72 ir_unregister_map(&gotview7135_map);
73}
74
75module_init(init_rc_map_gotview7135)
76module_exit(exit_rc_map_gotview7135)
77
78MODULE_LICENSE("GPL");
79MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-hauppauge-new.c b/drivers/media/IR/keymaps/rc-hauppauge-new.c
new file mode 100644
index 000000000000..c6f8cd7c5186
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-hauppauge-new.c
@@ -0,0 +1,100 @@
1/* hauppauge-new.h - Keytable for hauppauge_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Hauppauge: the newer, gray remotes (seems there are multiple
16 * slightly different versions), shipped with cx88+ivtv cards.
17 * almost rc5 coding, but some non-standard keys */
18
19static struct ir_scancode hauppauge_new[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
33 { 0x0b, KEY_RED }, /* red button */
34 { 0x0c, KEY_RADIO },
35 { 0x0d, KEY_MENU },
36 { 0x0e, KEY_SUBTITLE }, /* also the # key */
37 { 0x0f, KEY_MUTE },
38 { 0x10, KEY_VOLUMEUP },
39 { 0x11, KEY_VOLUMEDOWN },
40 { 0x12, KEY_PREVIOUS }, /* previous channel */
41 { 0x14, KEY_UP },
42 { 0x15, KEY_DOWN },
43 { 0x16, KEY_LEFT },
44 { 0x17, KEY_RIGHT },
45 { 0x18, KEY_VIDEO }, /* Videos */
46 { 0x19, KEY_AUDIO }, /* Music */
47 /* 0x1a: Pictures - presume this means
48 "Multimedia Home Platform" -
49 no "PICTURES" key in input.h
50 */
51 { 0x1a, KEY_MHP },
52
53 { 0x1b, KEY_EPG }, /* Guide */
54 { 0x1c, KEY_TV },
55 { 0x1e, KEY_NEXTSONG }, /* skip >| */
56 { 0x1f, KEY_EXIT }, /* back/exit */
57 { 0x20, KEY_CHANNELUP }, /* channel / program + */
58 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
59 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
60 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
61 { 0x25, KEY_ENTER }, /* OK */
62 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
63 { 0x29, KEY_BLUE }, /* blue key */
64 { 0x2e, KEY_GREEN }, /* green button */
65 { 0x30, KEY_PAUSE }, /* pause */
66 { 0x32, KEY_REWIND }, /* backward << */
67 { 0x34, KEY_FASTFORWARD }, /* forward >> */
68 { 0x35, KEY_PLAY },
69 { 0x36, KEY_STOP },
70 { 0x37, KEY_RECORD }, /* recording */
71 { 0x38, KEY_YELLOW }, /* yellow key */
72 { 0x3b, KEY_SELECT }, /* top right button */
73 { 0x3c, KEY_ZOOM }, /* full */
74 { 0x3d, KEY_POWER }, /* system power (green button) */
75};
76
77static struct rc_keymap hauppauge_new_map = {
78 .map = {
79 .scan = hauppauge_new,
80 .size = ARRAY_SIZE(hauppauge_new),
81 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
82 .name = RC_MAP_HAUPPAUGE_NEW,
83 }
84};
85
86static int __init init_rc_map_hauppauge_new(void)
87{
88 return ir_register_map(&hauppauge_new_map);
89}
90
91static void __exit exit_rc_map_hauppauge_new(void)
92{
93 ir_unregister_map(&hauppauge_new_map);
94}
95
96module_init(init_rc_map_hauppauge_new)
97module_exit(exit_rc_map_hauppauge_new)
98
99MODULE_LICENSE("GPL");
100MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-imon-mce.c b/drivers/media/IR/keymaps/rc-imon-mce.c
new file mode 100644
index 000000000000..e49f350e3a0d
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-imon-mce.c
@@ -0,0 +1,142 @@
1/* rc5-imon-mce.c - Keytable for Windows Media Center RC-6 remotes for use
2 * with the SoundGraph iMON/Antec Veris hardware IR decoder
3 *
4 * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <media/rc-map.h>
13
14/* mce-mode imon mce remote key table */
15static struct ir_scancode imon_mce[] = {
16 /* keys sorted mostly by frequency of use to optimize lookups */
17 { 0x800ff415, KEY_REWIND },
18 { 0x800ff414, KEY_FASTFORWARD },
19 { 0x800ff41b, KEY_PREVIOUS },
20 { 0x800ff41a, KEY_NEXT },
21
22 { 0x800ff416, KEY_PLAY },
23 { 0x800ff418, KEY_PAUSE },
24 { 0x800ff419, KEY_STOP },
25 { 0x800ff417, KEY_RECORD },
26
27 { 0x02000052, KEY_UP },
28 { 0x02000051, KEY_DOWN },
29 { 0x02000050, KEY_LEFT },
30 { 0x0200004f, KEY_RIGHT },
31
32 { 0x800ff41e, KEY_UP },
33 { 0x800ff41f, KEY_DOWN },
34 { 0x800ff420, KEY_LEFT },
35 { 0x800ff421, KEY_RIGHT },
36
37 /* 0x800ff40b also KEY_NUMERIC_POUND on some receivers */
38 { 0x800ff40b, KEY_ENTER },
39 { 0x02000028, KEY_ENTER },
40/* the OK and Enter buttons decode to the same value on some remotes
41 { 0x02000028, KEY_OK }, */
42 { 0x800ff422, KEY_OK },
43 { 0x0200002a, KEY_EXIT },
44 { 0x800ff423, KEY_EXIT },
45 { 0x02000029, KEY_DELETE },
46 /* 0x800ff40a also KEY_NUMERIC_STAR on some receivers */
47 { 0x800ff40a, KEY_DELETE },
48
49 { 0x800ff40e, KEY_MUTE },
50 { 0x800ff410, KEY_VOLUMEUP },
51 { 0x800ff411, KEY_VOLUMEDOWN },
52 { 0x800ff412, KEY_CHANNELUP },
53 { 0x800ff413, KEY_CHANNELDOWN },
54
55 { 0x0200001e, KEY_NUMERIC_1 },
56 { 0x0200001f, KEY_NUMERIC_2 },
57 { 0x02000020, KEY_NUMERIC_3 },
58 { 0x02000021, KEY_NUMERIC_4 },
59 { 0x02000022, KEY_NUMERIC_5 },
60 { 0x02000023, KEY_NUMERIC_6 },
61 { 0x02000024, KEY_NUMERIC_7 },
62 { 0x02000025, KEY_NUMERIC_8 },
63 { 0x02000026, KEY_NUMERIC_9 },
64 { 0x02000027, KEY_NUMERIC_0 },
65
66 { 0x800ff401, KEY_NUMERIC_1 },
67 { 0x800ff402, KEY_NUMERIC_2 },
68 { 0x800ff403, KEY_NUMERIC_3 },
69 { 0x800ff404, KEY_NUMERIC_4 },
70 { 0x800ff405, KEY_NUMERIC_5 },
71 { 0x800ff406, KEY_NUMERIC_6 },
72 { 0x800ff407, KEY_NUMERIC_7 },
73 { 0x800ff408, KEY_NUMERIC_8 },
74 { 0x800ff409, KEY_NUMERIC_9 },
75 { 0x800ff400, KEY_NUMERIC_0 },
76
77 { 0x02200025, KEY_NUMERIC_STAR },
78 { 0x02200020, KEY_NUMERIC_POUND },
79 /* 0x800ff41d also KEY_BLUE on some receivers */
80 { 0x800ff41d, KEY_NUMERIC_STAR },
81 /* 0x800ff41c also KEY_PREVIOUS on some receivers */
82 { 0x800ff41c, KEY_NUMERIC_POUND },
83
84 { 0x800ff446, KEY_TV },
85 { 0x800ff447, KEY_AUDIO }, /* My Music */
86 { 0x800ff448, KEY_PVR }, /* RecordedTV */
87 { 0x800ff449, KEY_CAMERA },
88 { 0x800ff44a, KEY_VIDEO },
89 /* 0x800ff424 also KEY_MENU on some receivers */
90 { 0x800ff424, KEY_DVD },
91 /* 0x800ff425 also KEY_GREEN on some receivers */
92 { 0x800ff425, KEY_TUNER }, /* LiveTV */
93 { 0x800ff450, KEY_RADIO },
94
95 { 0x800ff44c, KEY_LANGUAGE },
96 { 0x800ff427, KEY_ZOOM }, /* Aspect */
97
98 { 0x800ff45b, KEY_RED },
99 { 0x800ff45c, KEY_GREEN },
100 { 0x800ff45d, KEY_YELLOW },
101 { 0x800ff45e, KEY_BLUE },
102
103 { 0x800ff466, KEY_RED },
104 /* { 0x800ff425, KEY_GREEN }, */
105 { 0x800ff468, KEY_YELLOW },
106 /* { 0x800ff41d, KEY_BLUE }, */
107
108 { 0x800ff40f, KEY_INFO },
109 { 0x800ff426, KEY_EPG }, /* Guide */
110 { 0x800ff45a, KEY_SUBTITLE }, /* Caption/Teletext */
111 { 0x800ff44d, KEY_TITLE },
112
113 { 0x800ff40c, KEY_POWER },
114 { 0x800ff40d, KEY_PROG1 }, /* Windows MCE button */
115
116};
117
118static struct rc_keymap imon_mce_map = {
119 .map = {
120 .scan = imon_mce,
121 .size = ARRAY_SIZE(imon_mce),
122 /* its RC6, but w/a hardware decoder */
123 .ir_type = IR_TYPE_RC6,
124 .name = RC_MAP_IMON_MCE,
125 }
126};
127
128static int __init init_rc_map_imon_mce(void)
129{
130 return ir_register_map(&imon_mce_map);
131}
132
133static void __exit exit_rc_map_imon_mce(void)
134{
135 ir_unregister_map(&imon_mce_map);
136}
137
138module_init(init_rc_map_imon_mce)
139module_exit(exit_rc_map_imon_mce)
140
141MODULE_LICENSE("GPL");
142MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-imon-pad.c b/drivers/media/IR/keymaps/rc-imon-pad.c
new file mode 100644
index 000000000000..bc4db72f02e6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-imon-pad.c
@@ -0,0 +1,156 @@
1/* rc5-imon-pad.c - Keytable for SoundGraph iMON PAD and Antec Veris
2 * RM-200 Remote Control
3 *
4 * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <media/rc-map.h>
13
14/*
15 * standard imon remote key table, which isn't really entirely
16 * "standard", as different receivers decode the same key on the
17 * same remote to different hex codes, and the silkscreened names
18 * vary a bit between the SoundGraph and Antec remotes... ugh.
19 */
20static struct ir_scancode imon_pad[] = {
21 /* keys sorted mostly by frequency of use to optimize lookups */
22 { 0x2a8195b7, KEY_REWIND },
23 { 0x298315b7, KEY_REWIND },
24 { 0x2b8115b7, KEY_FASTFORWARD },
25 { 0x2b8315b7, KEY_FASTFORWARD },
26 { 0x2b9115b7, KEY_PREVIOUS },
27 { 0x298195b7, KEY_NEXT },
28
29 { 0x2a8115b7, KEY_PLAY },
30 { 0x2a8315b7, KEY_PLAY },
31 { 0x2a9115b7, KEY_PAUSE },
32 { 0x2b9715b7, KEY_STOP },
33 { 0x298115b7, KEY_RECORD },
34
35 { 0x01008000, KEY_UP },
36 { 0x01007f00, KEY_DOWN },
37 { 0x01000080, KEY_LEFT },
38 { 0x0100007f, KEY_RIGHT },
39
40 { 0x2aa515b7, KEY_UP },
41 { 0x289515b7, KEY_DOWN },
42 { 0x29a515b7, KEY_LEFT },
43 { 0x2ba515b7, KEY_RIGHT },
44
45 { 0x0200002c, KEY_SPACE }, /* Select/Space */
46 { 0x2a9315b7, KEY_SPACE }, /* Select/Space */
47 { 0x02000028, KEY_ENTER },
48 { 0x28a195b7, KEY_ENTER },
49 { 0x288195b7, KEY_EXIT },
50 { 0x02000029, KEY_ESC },
51 { 0x2bb715b7, KEY_ESC },
52 { 0x0200002a, KEY_BACKSPACE },
53 { 0x28a115b7, KEY_BACKSPACE },
54
55 { 0x2b9595b7, KEY_MUTE },
56 { 0x28a395b7, KEY_VOLUMEUP },
57 { 0x28a595b7, KEY_VOLUMEDOWN },
58 { 0x289395b7, KEY_CHANNELUP },
59 { 0x288795b7, KEY_CHANNELDOWN },
60
61 { 0x0200001e, KEY_NUMERIC_1 },
62 { 0x0200001f, KEY_NUMERIC_2 },
63 { 0x02000020, KEY_NUMERIC_3 },
64 { 0x02000021, KEY_NUMERIC_4 },
65 { 0x02000022, KEY_NUMERIC_5 },
66 { 0x02000023, KEY_NUMERIC_6 },
67 { 0x02000024, KEY_NUMERIC_7 },
68 { 0x02000025, KEY_NUMERIC_8 },
69 { 0x02000026, KEY_NUMERIC_9 },
70 { 0x02000027, KEY_NUMERIC_0 },
71
72 { 0x28b595b7, KEY_NUMERIC_1 },
73 { 0x2bb195b7, KEY_NUMERIC_2 },
74 { 0x28b195b7, KEY_NUMERIC_3 },
75 { 0x2a8595b7, KEY_NUMERIC_4 },
76 { 0x299595b7, KEY_NUMERIC_5 },
77 { 0x2aa595b7, KEY_NUMERIC_6 },
78 { 0x2b9395b7, KEY_NUMERIC_7 },
79 { 0x2a8515b7, KEY_NUMERIC_8 },
80 { 0x2aa115b7, KEY_NUMERIC_9 },
81 { 0x2ba595b7, KEY_NUMERIC_0 },
82
83 { 0x02200025, KEY_NUMERIC_STAR },
84 { 0x28b515b7, KEY_NUMERIC_STAR },
85 { 0x02200020, KEY_NUMERIC_POUND },
86 { 0x29a115b7, KEY_NUMERIC_POUND },
87
88 { 0x2b8515b7, KEY_VIDEO },
89 { 0x299195b7, KEY_AUDIO },
90 { 0x2ba115b7, KEY_CAMERA },
91 { 0x28a515b7, KEY_TV },
92 { 0x29a395b7, KEY_DVD },
93 { 0x29a295b7, KEY_DVD },
94
95 /* the Menu key between DVD and Subtitle on the RM-200... */
96 { 0x2ba385b7, KEY_MENU },
97 { 0x2ba395b7, KEY_MENU },
98
99 { 0x288515b7, KEY_BOOKMARKS },
100 { 0x2ab715b7, KEY_MEDIA }, /* Thumbnail */
101 { 0x298595b7, KEY_SUBTITLE },
102 { 0x2b8595b7, KEY_LANGUAGE },
103
104 { 0x29a595b7, KEY_ZOOM },
105 { 0x2aa395b7, KEY_SCREEN }, /* FullScreen */
106
107 { 0x299115b7, KEY_KEYBOARD },
108 { 0x299135b7, KEY_KEYBOARD },
109
110 { 0x01010000, BTN_LEFT },
111 { 0x01020000, BTN_RIGHT },
112 { 0x01010080, BTN_LEFT },
113 { 0x01020080, BTN_RIGHT },
114 { 0x688301b7, BTN_LEFT },
115 { 0x688481b7, BTN_RIGHT },
116
117 { 0x2a9395b7, KEY_CYCLEWINDOWS }, /* TaskSwitcher */
118 { 0x2b8395b7, KEY_TIME }, /* Timer */
119
120 { 0x289115b7, KEY_POWER },
121 { 0x29b195b7, KEY_EJECTCD }, /* the one next to play */
122 { 0x299395b7, KEY_EJECTCLOSECD }, /* eject (by TaskSw) */
123
124 { 0x02800000, KEY_CONTEXT_MENU }, /* Left Menu */
125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */
127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
128 { 0x2ab195b7, KEY_PROG1 }, /* Go or MultiMon */
129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
130};
131
132static struct rc_keymap imon_pad_map = {
133 .map = {
134 .scan = imon_pad,
135 .size = ARRAY_SIZE(imon_pad),
136 /* actual protocol details unknown, hardware decoder */
137 .ir_type = IR_TYPE_OTHER,
138 .name = RC_MAP_IMON_PAD,
139 }
140};
141
142static int __init init_rc_map_imon_pad(void)
143{
144 return ir_register_map(&imon_pad_map);
145}
146
147static void __exit exit_rc_map_imon_pad(void)
148{
149 ir_unregister_map(&imon_pad_map);
150}
151
152module_init(init_rc_map_imon_pad)
153module_exit(exit_rc_map_imon_pad)
154
155MODULE_LICENSE("GPL");
156MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-iodata-bctv7e.c b/drivers/media/IR/keymaps/rc-iodata-bctv7e.c
new file mode 100644
index 000000000000..ef6600259fc0
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-iodata-bctv7e.c
@@ -0,0 +1,88 @@
1/* iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* IO-DATA BCTV7E Remote */
16
17static struct ir_scancode iodata_bctv7e[] = {
18 { 0x40, KEY_TV },
19 { 0x20, KEY_RADIO }, /* FM */
20 { 0x60, KEY_EPG },
21 { 0x00, KEY_POWER },
22
23 /* Keys 0 to 9 */
24 { 0x44, KEY_0 }, /* 10 */
25 { 0x50, KEY_1 },
26 { 0x30, KEY_2 },
27 { 0x70, KEY_3 },
28 { 0x48, KEY_4 },
29 { 0x28, KEY_5 },
30 { 0x68, KEY_6 },
31 { 0x58, KEY_7 },
32 { 0x38, KEY_8 },
33 { 0x78, KEY_9 },
34
35 { 0x10, KEY_L }, /* Live */
36 { 0x08, KEY_TIME }, /* Time Shift */
37
38 { 0x18, KEY_PLAYPAUSE }, /* Play */
39
40 { 0x24, KEY_ENTER }, /* 11 */
41 { 0x64, KEY_ESC }, /* 12 */
42 { 0x04, KEY_M }, /* Multi */
43
44 { 0x54, KEY_VIDEO },
45 { 0x34, KEY_CHANNELUP },
46 { 0x74, KEY_VOLUMEUP },
47 { 0x14, KEY_MUTE },
48
49 { 0x4c, KEY_VCR }, /* SVIDEO */
50 { 0x2c, KEY_CHANNELDOWN },
51 { 0x6c, KEY_VOLUMEDOWN },
52 { 0x0c, KEY_ZOOM },
53
54 { 0x5c, KEY_PAUSE },
55 { 0x3c, KEY_RED }, /* || (red) */
56 { 0x7c, KEY_RECORD }, /* recording */
57 { 0x1c, KEY_STOP },
58
59 { 0x41, KEY_REWIND }, /* backward << */
60 { 0x21, KEY_PLAY },
61 { 0x61, KEY_FASTFORWARD }, /* forward >> */
62 { 0x01, KEY_NEXT }, /* skip >| */
63};
64
65static struct rc_keymap iodata_bctv7e_map = {
66 .map = {
67 .scan = iodata_bctv7e,
68 .size = ARRAY_SIZE(iodata_bctv7e),
69 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
70 .name = RC_MAP_IODATA_BCTV7E,
71 }
72};
73
74static int __init init_rc_map_iodata_bctv7e(void)
75{
76 return ir_register_map(&iodata_bctv7e_map);
77}
78
79static void __exit exit_rc_map_iodata_bctv7e(void)
80{
81 ir_unregister_map(&iodata_bctv7e_map);
82}
83
84module_init(init_rc_map_iodata_bctv7e)
85module_exit(exit_rc_map_iodata_bctv7e)
86
87MODULE_LICENSE("GPL");
88MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-kaiomy.c b/drivers/media/IR/keymaps/rc-kaiomy.c
new file mode 100644
index 000000000000..4c7883ba0f15
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-kaiomy.c
@@ -0,0 +1,87 @@
1/* kaiomy.h - Keytable for kaiomy Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Kaiomy TVnPC U2
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 */
18
19static struct ir_scancode kaiomy[] = {
20 { 0x43, KEY_POWER2},
21 { 0x01, KEY_LIST},
22 { 0x0b, KEY_ZOOM},
23 { 0x03, KEY_POWER},
24
25 { 0x04, KEY_1},
26 { 0x08, KEY_2},
27 { 0x02, KEY_3},
28
29 { 0x0f, KEY_4},
30 { 0x05, KEY_5},
31 { 0x06, KEY_6},
32
33 { 0x0c, KEY_7},
34 { 0x0d, KEY_8},
35 { 0x0a, KEY_9},
36
37 { 0x11, KEY_0},
38
39 { 0x09, KEY_CHANNELUP},
40 { 0x07, KEY_CHANNELDOWN},
41
42 { 0x0e, KEY_VOLUMEUP},
43 { 0x13, KEY_VOLUMEDOWN},
44
45 { 0x10, KEY_HOME},
46 { 0x12, KEY_ENTER},
47
48 { 0x14, KEY_RECORD},
49 { 0x15, KEY_STOP},
50 { 0x16, KEY_PLAY},
51 { 0x17, KEY_MUTE},
52
53 { 0x18, KEY_UP},
54 { 0x19, KEY_DOWN},
55 { 0x1a, KEY_LEFT},
56 { 0x1b, KEY_RIGHT},
57
58 { 0x1c, KEY_RED},
59 { 0x1d, KEY_GREEN},
60 { 0x1e, KEY_YELLOW},
61 { 0x1f, KEY_BLUE},
62};
63
64static struct rc_keymap kaiomy_map = {
65 .map = {
66 .scan = kaiomy,
67 .size = ARRAY_SIZE(kaiomy),
68 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
69 .name = RC_MAP_KAIOMY,
70 }
71};
72
73static int __init init_rc_map_kaiomy(void)
74{
75 return ir_register_map(&kaiomy_map);
76}
77
78static void __exit exit_rc_map_kaiomy(void)
79{
80 ir_unregister_map(&kaiomy_map);
81}
82
83module_init(init_rc_map_kaiomy)
84module_exit(exit_rc_map_kaiomy)
85
86MODULE_LICENSE("GPL");
87MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-kworld-315u.c b/drivers/media/IR/keymaps/rc-kworld-315u.c
new file mode 100644
index 000000000000..618c817374e6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-kworld-315u.c
@@ -0,0 +1,83 @@
1/* kworld-315u.h - Keytable for kworld_315u Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Kworld 315U
16 */
17
18static struct ir_scancode kworld_315u[] = {
19 { 0x6143, KEY_POWER },
20 { 0x6101, KEY_TUNER }, /* source */
21 { 0x610b, KEY_ZOOM },
22 { 0x6103, KEY_POWER2 }, /* shutdown */
23
24 { 0x6104, KEY_1 },
25 { 0x6108, KEY_2 },
26 { 0x6102, KEY_3 },
27 { 0x6109, KEY_CHANNELUP },
28
29 { 0x610f, KEY_4 },
30 { 0x6105, KEY_5 },
31 { 0x6106, KEY_6 },
32 { 0x6107, KEY_CHANNELDOWN },
33
34 { 0x610c, KEY_7 },
35 { 0x610d, KEY_8 },
36 { 0x610a, KEY_9 },
37 { 0x610e, KEY_VOLUMEUP },
38
39 { 0x6110, KEY_LAST },
40 { 0x6111, KEY_0 },
41 { 0x6112, KEY_ENTER },
42 { 0x6113, KEY_VOLUMEDOWN },
43
44 { 0x6114, KEY_RECORD },
45 { 0x6115, KEY_STOP },
46 { 0x6116, KEY_PLAY },
47 { 0x6117, KEY_MUTE },
48
49 { 0x6118, KEY_UP },
50 { 0x6119, KEY_DOWN },
51 { 0x611a, KEY_LEFT },
52 { 0x611b, KEY_RIGHT },
53
54 { 0x611c, KEY_RED },
55 { 0x611d, KEY_GREEN },
56 { 0x611e, KEY_YELLOW },
57 { 0x611f, KEY_BLUE },
58};
59
60static struct rc_keymap kworld_315u_map = {
61 .map = {
62 .scan = kworld_315u,
63 .size = ARRAY_SIZE(kworld_315u),
64 .ir_type = IR_TYPE_NEC,
65 .name = RC_MAP_KWORLD_315U,
66 }
67};
68
69static int __init init_rc_map_kworld_315u(void)
70{
71 return ir_register_map(&kworld_315u_map);
72}
73
74static void __exit exit_rc_map_kworld_315u(void)
75{
76 ir_unregister_map(&kworld_315u_map);
77}
78
79module_init(init_rc_map_kworld_315u)
80module_exit(exit_rc_map_kworld_315u)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c
new file mode 100644
index 000000000000..366732f1f7b7
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c
@@ -0,0 +1,99 @@
1/* kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Kworld Plus TV Analog Lite PCI IR
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 */
18
19static struct ir_scancode kworld_plus_tv_analog[] = {
20 { 0x0c, KEY_PROG1 }, /* Kworld key */
21 { 0x16, KEY_CLOSECD }, /* -> ) */
22 { 0x1d, KEY_POWER2 },
23
24 { 0x00, KEY_1 },
25 { 0x01, KEY_2 },
26 { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
27 { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
28 { 0x04, KEY_5 },
29 { 0x05, KEY_6 },
30 { 0x06, KEY_7 },
31 { 0x07, KEY_8 },
32 { 0x08, KEY_9 },
33 { 0x0a, KEY_0 },
34
35 { 0x09, KEY_AGAIN },
36 { 0x14, KEY_MUTE },
37
38 { 0x20, KEY_UP },
39 { 0x21, KEY_DOWN },
40 { 0x0b, KEY_ENTER },
41
42 { 0x10, KEY_CHANNELUP },
43 { 0x11, KEY_CHANNELDOWN },
44
45 /* Couldn't map key left/key right since those
46 conflict with '3' and '4' scancodes
47 I dunno what the original driver does
48 */
49
50 { 0x13, KEY_VOLUMEUP },
51 { 0x12, KEY_VOLUMEDOWN },
52
53 /* The lower part of the IR
54 There are several duplicated keycodes there.
55 Most of them conflict with digits.
56 Add mappings just to the unused scancodes.
57 Somehow, the original driver has a way to know,
58 but this doesn't seem to be on some GPIO.
59 Also, it is not related to the time between keyup
60 and keydown.
61 */
62 { 0x19, KEY_TIME}, /* Timeshift */
63 { 0x1a, KEY_STOP},
64 { 0x1b, KEY_RECORD},
65
66 { 0x22, KEY_TEXT},
67
68 { 0x15, KEY_AUDIO}, /* ((*)) */
69 { 0x0f, KEY_ZOOM},
70 { 0x1c, KEY_CAMERA}, /* snapshot */
71
72 { 0x18, KEY_RED}, /* B */
73 { 0x23, KEY_GREEN}, /* C */
74};
75
76static struct rc_keymap kworld_plus_tv_analog_map = {
77 .map = {
78 .scan = kworld_plus_tv_analog,
79 .size = ARRAY_SIZE(kworld_plus_tv_analog),
80 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
81 .name = RC_MAP_KWORLD_PLUS_TV_ANALOG,
82 }
83};
84
85static int __init init_rc_map_kworld_plus_tv_analog(void)
86{
87 return ir_register_map(&kworld_plus_tv_analog_map);
88}
89
90static void __exit exit_rc_map_kworld_plus_tv_analog(void)
91{
92 ir_unregister_map(&kworld_plus_tv_analog_map);
93}
94
95module_init(init_rc_map_kworld_plus_tv_analog)
96module_exit(exit_rc_map_kworld_plus_tv_analog)
97
98MODULE_LICENSE("GPL");
99MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-manli.c b/drivers/media/IR/keymaps/rc-manli.c
new file mode 100644
index 000000000000..1e9fbfa90a1e
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-manli.c
@@ -0,0 +1,135 @@
1/* manli.h - Keytable for manli Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Michael Tokarev <mjt@tls.msk.ru>
16 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
17 keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
18 least, and probably other cards too.
19 The "ascii-art picture" below (in comments, first row
20 is the keycode in hex, and subsequent row(s) shows
21 the button labels (several variants when appropriate)
22 helps to descide which keycodes to assign to the buttons.
23 */
24
25static struct ir_scancode manli[] = {
26
27 /* 0x1c 0x12 *
28 * FUNCTION POWER *
29 * FM (|) *
30 * */
31 { 0x1c, KEY_RADIO }, /*XXX*/
32 { 0x12, KEY_POWER },
33
34 /* 0x01 0x02 0x03 *
35 * 1 2 3 *
36 * *
37 * 0x04 0x05 0x06 *
38 * 4 5 6 *
39 * *
40 * 0x07 0x08 0x09 *
41 * 7 8 9 *
42 * */
43 { 0x01, KEY_1 },
44 { 0x02, KEY_2 },
45 { 0x03, KEY_3 },
46 { 0x04, KEY_4 },
47 { 0x05, KEY_5 },
48 { 0x06, KEY_6 },
49 { 0x07, KEY_7 },
50 { 0x08, KEY_8 },
51 { 0x09, KEY_9 },
52
53 /* 0x0a 0x00 0x17 *
54 * RECALL 0 +100 *
55 * PLUS *
56 * */
57 { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
58 { 0x00, KEY_0 },
59 { 0x17, KEY_DIGITS }, /*XXX*/
60
61 /* 0x14 0x10 *
62 * MENU INFO *
63 * OSD */
64 { 0x14, KEY_MENU },
65 { 0x10, KEY_INFO },
66
67 /* 0x0b *
68 * Up *
69 * *
70 * 0x18 0x16 0x0c *
71 * Left Ok Right *
72 * *
73 * 0x015 *
74 * Down *
75 * */
76 { 0x0b, KEY_UP },
77 { 0x18, KEY_LEFT },
78 { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
79 { 0x0c, KEY_RIGHT },
80 { 0x15, KEY_DOWN },
81
82 /* 0x11 0x0d *
83 * TV/AV MODE *
84 * SOURCE STEREO *
85 * */
86 { 0x11, KEY_TV }, /*XXX*/
87 { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
88
89 /* 0x0f 0x1b 0x1a *
90 * AUDIO Vol+ Chan+ *
91 * TIMESHIFT??? *
92 * *
93 * 0x0e 0x1f 0x1e *
94 * SLEEP Vol- Chan- *
95 * */
96 { 0x0f, KEY_AUDIO },
97 { 0x1b, KEY_VOLUMEUP },
98 { 0x1a, KEY_CHANNELUP },
99 { 0x0e, KEY_TIME },
100 { 0x1f, KEY_VOLUMEDOWN },
101 { 0x1e, KEY_CHANNELDOWN },
102
103 /* 0x13 0x19 *
104 * MUTE SNAPSHOT*
105 * */
106 { 0x13, KEY_MUTE },
107 { 0x19, KEY_CAMERA },
108
109 /* 0x1d unused ? */
110};
111
112static struct rc_keymap manli_map = {
113 .map = {
114 .scan = manli,
115 .size = ARRAY_SIZE(manli),
116 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
117 .name = RC_MAP_MANLI,
118 }
119};
120
121static int __init init_rc_map_manli(void)
122{
123 return ir_register_map(&manli_map);
124}
125
126static void __exit exit_rc_map_manli(void)
127{
128 ir_unregister_map(&manli_map);
129}
130
131module_init(init_rc_map_manli)
132module_exit(exit_rc_map_manli)
133
134MODULE_LICENSE("GPL");
135MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c
new file mode 100644
index 000000000000..eb8e42c18ff9
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c
@@ -0,0 +1,123 @@
1/* msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
17 is marked "KS003". The controller is I2C at address 0x30, but does not seem
18 to respond to probes until a read is performed from a valid device.
19 I don't know why...
20
21 Note: This remote may be of similar or identical design to the
22 Pixelview remote (?). The raw codes and duplicate button codes
23 appear to be the same.
24
25 Henry Wong <henry@stuffedcow.net>
26 Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
27*/
28
29static struct ir_scancode msi_tvanywhere_plus[] = {
30
31/* ---- Remote Button Layout ----
32
33 POWER SOURCE SCAN MUTE
34 TV/FM 1 2 3
35 |> 4 5 6
36 <| 7 8 9
37 ^^UP 0 + RECALL
38 vvDN RECORD STOP PLAY
39
40 MINIMIZE ZOOM
41
42 CH+
43 VOL- VOL+
44 CH-
45
46 SNAPSHOT MTS
47
48 << FUNC >> RESET
49*/
50
51 { 0x01, KEY_1 }, /* 1 */
52 { 0x0b, KEY_2 }, /* 2 */
53 { 0x1b, KEY_3 }, /* 3 */
54 { 0x05, KEY_4 }, /* 4 */
55 { 0x09, KEY_5 }, /* 5 */
56 { 0x15, KEY_6 }, /* 6 */
57 { 0x06, KEY_7 }, /* 7 */
58 { 0x0a, KEY_8 }, /* 8 */
59 { 0x12, KEY_9 }, /* 9 */
60 { 0x02, KEY_0 }, /* 0 */
61 { 0x10, KEY_KPPLUS }, /* + */
62 { 0x13, KEY_AGAIN }, /* Recall */
63
64 { 0x1e, KEY_POWER }, /* Power */
65 { 0x07, KEY_TUNER }, /* Source */
66 { 0x1c, KEY_SEARCH }, /* Scan */
67 { 0x18, KEY_MUTE }, /* Mute */
68
69 { 0x03, KEY_RADIO }, /* TV/FM */
70 /* The next four keys are duplicates that appear to send the
71 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
72 to them is the actual code + 0x20 - they will never be
73 detected as such unless some way is discovered to distinguish
74 these buttons from those that have the same code. */
75 { 0x3f, KEY_RIGHT }, /* |> and Ch+ */
76 { 0x37, KEY_LEFT }, /* <| and Ch- */
77 { 0x2c, KEY_UP }, /* ^^Up and >> */
78 { 0x24, KEY_DOWN }, /* vvDn and << */
79
80 { 0x00, KEY_RECORD }, /* Record */
81 { 0x08, KEY_STOP }, /* Stop */
82 { 0x11, KEY_PLAY }, /* Play */
83
84 { 0x0f, KEY_CLOSE }, /* Minimize */
85 { 0x19, KEY_ZOOM }, /* Zoom */
86 { 0x1a, KEY_CAMERA }, /* Snapshot */
87 { 0x0d, KEY_LANGUAGE }, /* MTS */
88
89 { 0x14, KEY_VOLUMEDOWN }, /* Vol- */
90 { 0x16, KEY_VOLUMEUP }, /* Vol+ */
91 { 0x17, KEY_CHANNELDOWN }, /* Ch- */
92 { 0x1f, KEY_CHANNELUP }, /* Ch+ */
93
94 { 0x04, KEY_REWIND }, /* << */
95 { 0x0e, KEY_MENU }, /* Function */
96 { 0x0c, KEY_FASTFORWARD }, /* >> */
97 { 0x1d, KEY_RESTART }, /* Reset */
98};
99
100static struct rc_keymap msi_tvanywhere_plus_map = {
101 .map = {
102 .scan = msi_tvanywhere_plus,
103 .size = ARRAY_SIZE(msi_tvanywhere_plus),
104 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
105 .name = RC_MAP_MSI_TVANYWHERE_PLUS,
106 }
107};
108
109static int __init init_rc_map_msi_tvanywhere_plus(void)
110{
111 return ir_register_map(&msi_tvanywhere_plus_map);
112}
113
114static void __exit exit_rc_map_msi_tvanywhere_plus(void)
115{
116 ir_unregister_map(&msi_tvanywhere_plus_map);
117}
118
119module_init(init_rc_map_msi_tvanywhere_plus)
120module_exit(exit_rc_map_msi_tvanywhere_plus)
121
122MODULE_LICENSE("GPL");
123MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere.c b/drivers/media/IR/keymaps/rc-msi-tvanywhere.c
new file mode 100644
index 000000000000..ef411854f067
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-msi-tvanywhere.c
@@ -0,0 +1,69 @@
1/* msi-tvanywhere.h - Keytable for msi_tvanywhere Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* MSI TV@nywhere MASTER remote */
16
17static struct ir_scancode msi_tvanywhere[] = {
18 /* Keys 0 to 9 */
19 { 0x00, KEY_0 },
20 { 0x01, KEY_1 },
21 { 0x02, KEY_2 },
22 { 0x03, KEY_3 },
23 { 0x04, KEY_4 },
24 { 0x05, KEY_5 },
25 { 0x06, KEY_6 },
26 { 0x07, KEY_7 },
27 { 0x08, KEY_8 },
28 { 0x09, KEY_9 },
29
30 { 0x0c, KEY_MUTE },
31 { 0x0f, KEY_SCREEN }, /* Full Screen */
32 { 0x10, KEY_FN }, /* Funtion */
33 { 0x11, KEY_TIME }, /* Time shift */
34 { 0x12, KEY_POWER },
35 { 0x13, KEY_MEDIA }, /* MTS */
36 { 0x14, KEY_SLOW },
37 { 0x16, KEY_REWIND }, /* backward << */
38 { 0x17, KEY_ENTER }, /* Return */
39 { 0x18, KEY_FASTFORWARD }, /* forward >> */
40 { 0x1a, KEY_CHANNELUP },
41 { 0x1b, KEY_VOLUMEUP },
42 { 0x1e, KEY_CHANNELDOWN },
43 { 0x1f, KEY_VOLUMEDOWN },
44};
45
46static struct rc_keymap msi_tvanywhere_map = {
47 .map = {
48 .scan = msi_tvanywhere,
49 .size = ARRAY_SIZE(msi_tvanywhere),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_MSI_TVANYWHERE,
52 }
53};
54
55static int __init init_rc_map_msi_tvanywhere(void)
56{
57 return ir_register_map(&msi_tvanywhere_map);
58}
59
60static void __exit exit_rc_map_msi_tvanywhere(void)
61{
62 ir_unregister_map(&msi_tvanywhere_map);
63}
64
65module_init(init_rc_map_msi_tvanywhere)
66module_exit(exit_rc_map_msi_tvanywhere)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-nebula.c b/drivers/media/IR/keymaps/rc-nebula.c
new file mode 100644
index 000000000000..ccc50eb402ec
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-nebula.c
@@ -0,0 +1,96 @@
1/* nebula.h - Keytable for nebula Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode nebula[] = {
16 { 0x00, KEY_0 },
17 { 0x01, KEY_1 },
18 { 0x02, KEY_2 },
19 { 0x03, KEY_3 },
20 { 0x04, KEY_4 },
21 { 0x05, KEY_5 },
22 { 0x06, KEY_6 },
23 { 0x07, KEY_7 },
24 { 0x08, KEY_8 },
25 { 0x09, KEY_9 },
26 { 0x0a, KEY_TV },
27 { 0x0b, KEY_AUX },
28 { 0x0c, KEY_DVD },
29 { 0x0d, KEY_POWER },
30 { 0x0e, KEY_MHP }, /* labelled 'Picture' */
31 { 0x0f, KEY_AUDIO },
32 { 0x10, KEY_INFO },
33 { 0x11, KEY_F13 }, /* 16:9 */
34 { 0x12, KEY_F14 }, /* 14:9 */
35 { 0x13, KEY_EPG },
36 { 0x14, KEY_EXIT },
37 { 0x15, KEY_MENU },
38 { 0x16, KEY_UP },
39 { 0x17, KEY_DOWN },
40 { 0x18, KEY_LEFT },
41 { 0x19, KEY_RIGHT },
42 { 0x1a, KEY_ENTER },
43 { 0x1b, KEY_CHANNELUP },
44 { 0x1c, KEY_CHANNELDOWN },
45 { 0x1d, KEY_VOLUMEUP },
46 { 0x1e, KEY_VOLUMEDOWN },
47 { 0x1f, KEY_RED },
48 { 0x20, KEY_GREEN },
49 { 0x21, KEY_YELLOW },
50 { 0x22, KEY_BLUE },
51 { 0x23, KEY_SUBTITLE },
52 { 0x24, KEY_F15 }, /* AD */
53 { 0x25, KEY_TEXT },
54 { 0x26, KEY_MUTE },
55 { 0x27, KEY_REWIND },
56 { 0x28, KEY_STOP },
57 { 0x29, KEY_PLAY },
58 { 0x2a, KEY_FASTFORWARD },
59 { 0x2b, KEY_F16 }, /* chapter */
60 { 0x2c, KEY_PAUSE },
61 { 0x2d, KEY_PLAY },
62 { 0x2e, KEY_RECORD },
63 { 0x2f, KEY_F17 }, /* picture in picture */
64 { 0x30, KEY_KPPLUS }, /* zoom in */
65 { 0x31, KEY_KPMINUS }, /* zoom out */
66 { 0x32, KEY_F18 }, /* capture */
67 { 0x33, KEY_F19 }, /* web */
68 { 0x34, KEY_EMAIL },
69 { 0x35, KEY_PHONE },
70 { 0x36, KEY_PC },
71};
72
73static struct rc_keymap nebula_map = {
74 .map = {
75 .scan = nebula,
76 .size = ARRAY_SIZE(nebula),
77 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
78 .name = RC_MAP_NEBULA,
79 }
80};
81
82static int __init init_rc_map_nebula(void)
83{
84 return ir_register_map(&nebula_map);
85}
86
87static void __exit exit_rc_map_nebula(void)
88{
89 ir_unregister_map(&nebula_map);
90}
91
92module_init(init_rc_map_nebula)
93module_exit(exit_rc_map_nebula)
94
95MODULE_LICENSE("GPL");
96MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c
new file mode 100644
index 000000000000..e1b54d20db60
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -0,0 +1,105 @@
1/* nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Terratec Cinergy Hybrid T USB XS FM
16 Mauro Carvalho Chehab <mchehab@redhat.com>
17 */
18
19static struct ir_scancode nec_terratec_cinergy_xs[] = {
20 { 0x1441, KEY_HOME},
21 { 0x1401, KEY_POWER2},
22
23 { 0x1442, KEY_MENU}, /* DVD menu */
24 { 0x1443, KEY_SUBTITLE},
25 { 0x1444, KEY_TEXT}, /* Teletext */
26 { 0x1445, KEY_DELETE},
27
28 { 0x1402, KEY_1},
29 { 0x1403, KEY_2},
30 { 0x1404, KEY_3},
31 { 0x1405, KEY_4},
32 { 0x1406, KEY_5},
33 { 0x1407, KEY_6},
34 { 0x1408, KEY_7},
35 { 0x1409, KEY_8},
36 { 0x140a, KEY_9},
37 { 0x140c, KEY_0},
38
39 { 0x140b, KEY_TUNER}, /* AV */
40 { 0x140d, KEY_MODE}, /* A.B */
41
42 { 0x1446, KEY_TV},
43 { 0x1447, KEY_DVD},
44 { 0x1449, KEY_VIDEO},
45 { 0x144a, KEY_RADIO}, /* Music */
46 { 0x144b, KEY_CAMERA}, /* PIC */
47
48 { 0x1410, KEY_UP},
49 { 0x1411, KEY_LEFT},
50 { 0x1412, KEY_OK},
51 { 0x1413, KEY_RIGHT},
52 { 0x1414, KEY_DOWN},
53
54 { 0x140f, KEY_EPG},
55 { 0x1416, KEY_INFO},
56 { 0x144d, KEY_BACKSPACE},
57
58 { 0x141c, KEY_VOLUMEUP},
59 { 0x141e, KEY_VOLUMEDOWN},
60
61 { 0x144c, KEY_PLAY},
62 { 0x141d, KEY_MUTE},
63
64 { 0x141b, KEY_CHANNELUP},
65 { 0x141f, KEY_CHANNELDOWN},
66
67 { 0x1417, KEY_RED},
68 { 0x1418, KEY_GREEN},
69 { 0x1419, KEY_YELLOW},
70 { 0x141a, KEY_BLUE},
71
72 { 0x1458, KEY_RECORD},
73 { 0x1448, KEY_STOP},
74 { 0x1440, KEY_PAUSE},
75
76 { 0x1454, KEY_LAST},
77 { 0x144e, KEY_REWIND},
78 { 0x144f, KEY_FASTFORWARD},
79 { 0x145c, KEY_NEXT},
80};
81
82static struct rc_keymap nec_terratec_cinergy_xs_map = {
83 .map = {
84 .scan = nec_terratec_cinergy_xs,
85 .size = ARRAY_SIZE(nec_terratec_cinergy_xs),
86 .ir_type = IR_TYPE_NEC,
87 .name = RC_MAP_NEC_TERRATEC_CINERGY_XS,
88 }
89};
90
91static int __init init_rc_map_nec_terratec_cinergy_xs(void)
92{
93 return ir_register_map(&nec_terratec_cinergy_xs_map);
94}
95
96static void __exit exit_rc_map_nec_terratec_cinergy_xs(void)
97{
98 ir_unregister_map(&nec_terratec_cinergy_xs_map);
99}
100
101module_init(init_rc_map_nec_terratec_cinergy_xs)
102module_exit(exit_rc_map_nec_terratec_cinergy_xs)
103
104MODULE_LICENSE("GPL");
105MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-norwood.c b/drivers/media/IR/keymaps/rc-norwood.c
new file mode 100644
index 000000000000..e5849a6b3f05
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-norwood.c
@@ -0,0 +1,85 @@
1/* norwood.h - Keytable for norwood Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Norwood Micro (non-Pro) TV Tuner
16 By Peter Naulls <peter@chocky.org>
17 Key comments are the functions given in the manual */
18
19static struct ir_scancode norwood[] = {
20 /* Keys 0 to 9 */
21 { 0x20, KEY_0 },
22 { 0x21, KEY_1 },
23 { 0x22, KEY_2 },
24 { 0x23, KEY_3 },
25 { 0x24, KEY_4 },
26 { 0x25, KEY_5 },
27 { 0x26, KEY_6 },
28 { 0x27, KEY_7 },
29 { 0x28, KEY_8 },
30 { 0x29, KEY_9 },
31
32 { 0x78, KEY_TUNER }, /* Video Source */
33 { 0x2c, KEY_EXIT }, /* Open/Close software */
34 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
35 { 0x69, KEY_AGAIN }, /* Recall */
36
37 { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */
38 { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */
39 { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */
40 { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */
41
42 { 0x2d, KEY_MUTE }, /* Mute */
43 { 0x30, KEY_VOLUMEUP }, /* Volume up */
44 { 0x31, KEY_VOLUMEDOWN }, /* Volume down */
45 { 0x60, KEY_CHANNELUP }, /* Channel up */
46 { 0x61, KEY_CHANNELDOWN }, /* Channel down */
47
48 { 0x3f, KEY_RECORD }, /* Record */
49 { 0x37, KEY_PLAY }, /* Play */
50 { 0x36, KEY_PAUSE }, /* Pause */
51 { 0x2b, KEY_STOP }, /* Stop */
52 { 0x67, KEY_FASTFORWARD }, /* Foward */
53 { 0x66, KEY_REWIND }, /* Rewind */
54 { 0x3e, KEY_SEARCH }, /* Auto Scan */
55 { 0x2e, KEY_CAMERA }, /* Capture Video */
56 { 0x6d, KEY_MENU }, /* Show/Hide Control */
57 { 0x2f, KEY_ZOOM }, /* Full Screen */
58 { 0x34, KEY_RADIO }, /* FM */
59 { 0x65, KEY_POWER }, /* Computer power */
60};
61
62static struct rc_keymap norwood_map = {
63 .map = {
64 .scan = norwood,
65 .size = ARRAY_SIZE(norwood),
66 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
67 .name = RC_MAP_NORWOOD,
68 }
69};
70
71static int __init init_rc_map_norwood(void)
72{
73 return ir_register_map(&norwood_map);
74}
75
76static void __exit exit_rc_map_norwood(void)
77{
78 ir_unregister_map(&norwood_map);
79}
80
81module_init(init_rc_map_norwood)
82module_exit(exit_rc_map_norwood)
83
84MODULE_LICENSE("GPL");
85MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-npgtech.c b/drivers/media/IR/keymaps/rc-npgtech.c
new file mode 100644
index 000000000000..b9ece1e90296
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-npgtech.c
@@ -0,0 +1,80 @@
1/* npgtech.h - Keytable for npgtech Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode npgtech[] = {
16 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
17 { 0x2a, KEY_FRONT },
18
19 { 0x3e, KEY_1 },
20 { 0x02, KEY_2 },
21 { 0x06, KEY_3 },
22 { 0x0a, KEY_4 },
23 { 0x0e, KEY_5 },
24 { 0x12, KEY_6 },
25 { 0x16, KEY_7 },
26 { 0x1a, KEY_8 },
27 { 0x1e, KEY_9 },
28 { 0x3a, KEY_0 },
29 { 0x22, KEY_NUMLOCK }, /* -/-- */
30 { 0x20, KEY_REFRESH },
31
32 { 0x03, KEY_BRIGHTNESSDOWN },
33 { 0x28, KEY_AUDIO },
34 { 0x3c, KEY_CHANNELUP },
35 { 0x3f, KEY_VOLUMEDOWN },
36 { 0x2e, KEY_MUTE },
37 { 0x3b, KEY_VOLUMEUP },
38 { 0x00, KEY_CHANNELDOWN },
39 { 0x07, KEY_BRIGHTNESSUP },
40 { 0x2c, KEY_TEXT },
41
42 { 0x37, KEY_RECORD },
43 { 0x17, KEY_PLAY },
44 { 0x13, KEY_PAUSE },
45 { 0x26, KEY_STOP },
46 { 0x18, KEY_FASTFORWARD },
47 { 0x14, KEY_REWIND },
48 { 0x33, KEY_ZOOM },
49 { 0x32, KEY_KEYBOARD },
50 { 0x30, KEY_GOTO }, /* Pointing arrow */
51 { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */
52 { 0x0b, KEY_RADIO },
53 { 0x10, KEY_POWER },
54
55};
56
57static struct rc_keymap npgtech_map = {
58 .map = {
59 .scan = npgtech,
60 .size = ARRAY_SIZE(npgtech),
61 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
62 .name = RC_MAP_NPGTECH,
63 }
64};
65
66static int __init init_rc_map_npgtech(void)
67{
68 return ir_register_map(&npgtech_map);
69}
70
71static void __exit exit_rc_map_npgtech(void)
72{
73 ir_unregister_map(&npgtech_map);
74}
75
76module_init(init_rc_map_npgtech)
77module_exit(exit_rc_map_npgtech)
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pctv-sedna.c b/drivers/media/IR/keymaps/rc-pctv-sedna.c
new file mode 100644
index 000000000000..4129bb44a25b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pctv-sedna.c
@@ -0,0 +1,80 @@
1/* pctv-sedna.h - Keytable for pctv_sedna Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Mapping for the 28 key remote control as seen at
16 http://www.sednacomputer.com/photo/cardbus-tv.jpg
17 Pavel Mihaylov <bin@bash.info>
18 Also for the remote bundled with Kozumi KTV-01C card */
19
20static struct ir_scancode pctv_sedna[] = {
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0a, KEY_AGAIN }, /* Recall */
33 { 0x0b, KEY_CHANNELUP },
34 { 0x0c, KEY_VOLUMEUP },
35 { 0x0d, KEY_MODE }, /* Stereo */
36 { 0x0e, KEY_STOP },
37 { 0x0f, KEY_PREVIOUSSONG },
38 { 0x10, KEY_ZOOM },
39 { 0x11, KEY_TUNER }, /* Source */
40 { 0x12, KEY_POWER },
41 { 0x13, KEY_MUTE },
42 { 0x15, KEY_CHANNELDOWN },
43 { 0x18, KEY_VOLUMEDOWN },
44 { 0x19, KEY_CAMERA }, /* Snapshot */
45 { 0x1a, KEY_NEXTSONG },
46 { 0x1b, KEY_TIME }, /* Time Shift */
47 { 0x1c, KEY_RADIO }, /* FM Radio */
48 { 0x1d, KEY_RECORD },
49 { 0x1e, KEY_PAUSE },
50 /* additional codes for Kozumi's remote */
51 { 0x14, KEY_INFO }, /* OSD */
52 { 0x16, KEY_OK }, /* OK */
53 { 0x17, KEY_DIGITS }, /* Plus */
54 { 0x1f, KEY_PLAY }, /* Play */
55};
56
57static struct rc_keymap pctv_sedna_map = {
58 .map = {
59 .scan = pctv_sedna,
60 .size = ARRAY_SIZE(pctv_sedna),
61 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
62 .name = RC_MAP_PCTV_SEDNA,
63 }
64};
65
66static int __init init_rc_map_pctv_sedna(void)
67{
68 return ir_register_map(&pctv_sedna_map);
69}
70
71static void __exit exit_rc_map_pctv_sedna(void)
72{
73 ir_unregister_map(&pctv_sedna_map);
74}
75
76module_init(init_rc_map_pctv_sedna)
77module_exit(exit_rc_map_pctv_sedna)
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-color.c b/drivers/media/IR/keymaps/rc-pinnacle-color.c
new file mode 100644
index 000000000000..326e023ce126
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pinnacle-color.c
@@ -0,0 +1,94 @@
1/* pinnacle-color.h - Keytable for pinnacle_color Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode pinnacle_color[] = {
16 { 0x59, KEY_MUTE },
17 { 0x4a, KEY_POWER },
18
19 { 0x18, KEY_TEXT },
20 { 0x26, KEY_TV },
21 { 0x3d, KEY_PRINT },
22
23 { 0x48, KEY_RED },
24 { 0x04, KEY_GREEN },
25 { 0x11, KEY_YELLOW },
26 { 0x00, KEY_BLUE },
27
28 { 0x2d, KEY_VOLUMEUP },
29 { 0x1e, KEY_VOLUMEDOWN },
30
31 { 0x49, KEY_MENU },
32
33 { 0x16, KEY_CHANNELUP },
34 { 0x17, KEY_CHANNELDOWN },
35
36 { 0x20, KEY_UP },
37 { 0x21, KEY_DOWN },
38 { 0x22, KEY_LEFT },
39 { 0x23, KEY_RIGHT },
40 { 0x0d, KEY_SELECT },
41
42 { 0x08, KEY_BACK },
43 { 0x07, KEY_REFRESH },
44
45 { 0x2f, KEY_ZOOM },
46 { 0x29, KEY_RECORD },
47
48 { 0x4b, KEY_PAUSE },
49 { 0x4d, KEY_REWIND },
50 { 0x2e, KEY_PLAY },
51 { 0x4e, KEY_FORWARD },
52 { 0x53, KEY_PREVIOUS },
53 { 0x4c, KEY_STOP },
54 { 0x54, KEY_NEXT },
55
56 { 0x69, KEY_0 },
57 { 0x6a, KEY_1 },
58 { 0x6b, KEY_2 },
59 { 0x6c, KEY_3 },
60 { 0x6d, KEY_4 },
61 { 0x6e, KEY_5 },
62 { 0x6f, KEY_6 },
63 { 0x70, KEY_7 },
64 { 0x71, KEY_8 },
65 { 0x72, KEY_9 },
66
67 { 0x74, KEY_CHANNEL },
68 { 0x0a, KEY_BACKSPACE },
69};
70
71static struct rc_keymap pinnacle_color_map = {
72 .map = {
73 .scan = pinnacle_color,
74 .size = ARRAY_SIZE(pinnacle_color),
75 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
76 .name = RC_MAP_PINNACLE_COLOR,
77 }
78};
79
80static int __init init_rc_map_pinnacle_color(void)
81{
82 return ir_register_map(&pinnacle_color_map);
83}
84
85static void __exit exit_rc_map_pinnacle_color(void)
86{
87 ir_unregister_map(&pinnacle_color_map);
88}
89
90module_init(init_rc_map_pinnacle_color)
91module_exit(exit_rc_map_pinnacle_color)
92
93MODULE_LICENSE("GPL");
94MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-grey.c b/drivers/media/IR/keymaps/rc-pinnacle-grey.c
new file mode 100644
index 000000000000..14cb772515c6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pinnacle-grey.c
@@ -0,0 +1,89 @@
1/* pinnacle-grey.h - Keytable for pinnacle_grey Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode pinnacle_grey[] = {
16 { 0x3a, KEY_0 },
17 { 0x31, KEY_1 },
18 { 0x32, KEY_2 },
19 { 0x33, KEY_3 },
20 { 0x34, KEY_4 },
21 { 0x35, KEY_5 },
22 { 0x36, KEY_6 },
23 { 0x37, KEY_7 },
24 { 0x38, KEY_8 },
25 { 0x39, KEY_9 },
26
27 { 0x2f, KEY_POWER },
28
29 { 0x2e, KEY_P },
30 { 0x1f, KEY_L },
31 { 0x2b, KEY_I },
32
33 { 0x2d, KEY_SCREEN },
34 { 0x1e, KEY_ZOOM },
35 { 0x1b, KEY_VOLUMEUP },
36 { 0x0f, KEY_VOLUMEDOWN },
37 { 0x17, KEY_CHANNELUP },
38 { 0x1c, KEY_CHANNELDOWN },
39 { 0x25, KEY_INFO },
40
41 { 0x3c, KEY_MUTE },
42
43 { 0x3d, KEY_LEFT },
44 { 0x3b, KEY_RIGHT },
45
46 { 0x3f, KEY_UP },
47 { 0x3e, KEY_DOWN },
48 { 0x1a, KEY_ENTER },
49
50 { 0x1d, KEY_MENU },
51 { 0x19, KEY_AGAIN },
52 { 0x16, KEY_PREVIOUSSONG },
53 { 0x13, KEY_NEXTSONG },
54 { 0x15, KEY_PAUSE },
55 { 0x0e, KEY_REWIND },
56 { 0x0d, KEY_PLAY },
57 { 0x0b, KEY_STOP },
58 { 0x07, KEY_FORWARD },
59 { 0x27, KEY_RECORD },
60 { 0x26, KEY_TUNER },
61 { 0x29, KEY_TEXT },
62 { 0x2a, KEY_MEDIA },
63 { 0x18, KEY_EPG },
64};
65
66static struct rc_keymap pinnacle_grey_map = {
67 .map = {
68 .scan = pinnacle_grey,
69 .size = ARRAY_SIZE(pinnacle_grey),
70 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
71 .name = RC_MAP_PINNACLE_GREY,
72 }
73};
74
75static int __init init_rc_map_pinnacle_grey(void)
76{
77 return ir_register_map(&pinnacle_grey_map);
78}
79
80static void __exit exit_rc_map_pinnacle_grey(void)
81{
82 ir_unregister_map(&pinnacle_grey_map);
83}
84
85module_init(init_rc_map_pinnacle_grey)
86module_exit(exit_rc_map_pinnacle_grey)
87
88MODULE_LICENSE("GPL");
89MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c
new file mode 100644
index 000000000000..835bf4ef8de7
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c
@@ -0,0 +1,73 @@
1/* pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Pinnacle PCTV HD 800i mini remote */
16
17static struct ir_scancode pinnacle_pctv_hd[] = {
18
19 { 0x0f, KEY_1 },
20 { 0x15, KEY_2 },
21 { 0x10, KEY_3 },
22 { 0x18, KEY_4 },
23 { 0x1b, KEY_5 },
24 { 0x1e, KEY_6 },
25 { 0x11, KEY_7 },
26 { 0x21, KEY_8 },
27 { 0x12, KEY_9 },
28 { 0x27, KEY_0 },
29
30 { 0x24, KEY_ZOOM },
31 { 0x2a, KEY_SUBTITLE },
32
33 { 0x00, KEY_MUTE },
34 { 0x01, KEY_ENTER }, /* Pinnacle Logo */
35 { 0x39, KEY_POWER },
36
37 { 0x03, KEY_VOLUMEUP },
38 { 0x09, KEY_VOLUMEDOWN },
39 { 0x06, KEY_CHANNELUP },
40 { 0x0c, KEY_CHANNELDOWN },
41
42 { 0x2d, KEY_REWIND },
43 { 0x30, KEY_PLAYPAUSE },
44 { 0x33, KEY_FASTFORWARD },
45 { 0x3c, KEY_STOP },
46 { 0x36, KEY_RECORD },
47 { 0x3f, KEY_EPG }, /* Labeled "?" */
48};
49
50static struct rc_keymap pinnacle_pctv_hd_map = {
51 .map = {
52 .scan = pinnacle_pctv_hd,
53 .size = ARRAY_SIZE(pinnacle_pctv_hd),
54 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
55 .name = RC_MAP_PINNACLE_PCTV_HD,
56 }
57};
58
59static int __init init_rc_map_pinnacle_pctv_hd(void)
60{
61 return ir_register_map(&pinnacle_pctv_hd_map);
62}
63
64static void __exit exit_rc_map_pinnacle_pctv_hd(void)
65{
66 ir_unregister_map(&pinnacle_pctv_hd_map);
67}
68
69module_init(init_rc_map_pinnacle_pctv_hd)
70module_exit(exit_rc_map_pinnacle_pctv_hd)
71
72MODULE_LICENSE("GPL");
73MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview-mk12.c b/drivers/media/IR/keymaps/rc-pixelview-mk12.c
new file mode 100644
index 000000000000..5a735d569a8b
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pixelview-mk12.c
@@ -0,0 +1,83 @@
1/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Keytable for MK-F12 IR remote provided together with Pixelview
17 * Ultra Pro Remote Controller. Uses NEC extended format.
18 */
19static struct ir_scancode pixelview_mk12[] = {
20 { 0x866b03, KEY_TUNER }, /* Timeshift */
21 { 0x866b1e, KEY_POWER2 }, /* power */
22
23 { 0x866b01, KEY_1 },
24 { 0x866b0b, KEY_2 },
25 { 0x866b1b, KEY_3 },
26 { 0x866b05, KEY_4 },
27 { 0x866b09, KEY_5 },
28 { 0x866b15, KEY_6 },
29 { 0x866b06, KEY_7 },
30 { 0x866b0a, KEY_8 },
31 { 0x866b12, KEY_9 },
32 { 0x866b02, KEY_0 },
33
34 { 0x866b13, KEY_AGAIN }, /* loop */
35 { 0x866b10, KEY_DIGITS }, /* +100 */
36
37 { 0x866b00, KEY_MEDIA }, /* source */
38 { 0x866b18, KEY_MUTE }, /* mute */
39 { 0x866b19, KEY_CAMERA }, /* snapshot */
40 { 0x866b1a, KEY_SEARCH }, /* scan */
41
42 { 0x866b16, KEY_CHANNELUP }, /* chn + */
43 { 0x866b14, KEY_CHANNELDOWN }, /* chn - */
44 { 0x866b1f, KEY_VOLUMEUP }, /* vol + */
45 { 0x866b17, KEY_VOLUMEDOWN }, /* vol - */
46 { 0x866b1c, KEY_ZOOM }, /* zoom */
47
48 { 0x866b04, KEY_REWIND },
49 { 0x866b0e, KEY_RECORD },
50 { 0x866b0c, KEY_FORWARD },
51
52 { 0x866b1d, KEY_STOP },
53 { 0x866b08, KEY_PLAY },
54 { 0x866b0f, KEY_PAUSE },
55
56 { 0x866b0d, KEY_TV },
57 { 0x866b07, KEY_RADIO }, /* FM */
58};
59
60static struct rc_keymap pixelview_map = {
61 .map = {
62 .scan = pixelview_mk12,
63 .size = ARRAY_SIZE(pixelview_mk12),
64 .ir_type = IR_TYPE_NEC,
65 .name = RC_MAP_PIXELVIEW_MK12,
66 }
67};
68
69static int __init init_rc_map_pixelview(void)
70{
71 return ir_register_map(&pixelview_map);
72}
73
74static void __exit exit_rc_map_pixelview(void)
75{
76 ir_unregister_map(&pixelview_map);
77}
78
79module_init(init_rc_map_pixelview)
80module_exit(exit_rc_map_pixelview)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview-new.c b/drivers/media/IR/keymaps/rc-pixelview-new.c
new file mode 100644
index 000000000000..7bbbbf5735e6
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pixelview-new.c
@@ -0,0 +1,83 @@
1/* pixelview-new.h - Keytable for pixelview_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 Mauro Carvalho Chehab <mchehab@infradead.org>
17 present on PV MPEG 8000GT
18 */
19
20static struct ir_scancode pixelview_new[] = {
21 { 0x3c, KEY_TIME }, /* Timeshift */
22 { 0x12, KEY_POWER },
23
24 { 0x3d, KEY_1 },
25 { 0x38, KEY_2 },
26 { 0x18, KEY_3 },
27 { 0x35, KEY_4 },
28 { 0x39, KEY_5 },
29 { 0x15, KEY_6 },
30 { 0x36, KEY_7 },
31 { 0x3a, KEY_8 },
32 { 0x1e, KEY_9 },
33 { 0x3e, KEY_0 },
34
35 { 0x1c, KEY_AGAIN }, /* LOOP */
36 { 0x3f, KEY_MEDIA }, /* Source */
37 { 0x1f, KEY_LAST }, /* +100 */
38 { 0x1b, KEY_MUTE },
39
40 { 0x17, KEY_CHANNELDOWN },
41 { 0x16, KEY_CHANNELUP },
42 { 0x10, KEY_VOLUMEUP },
43 { 0x14, KEY_VOLUMEDOWN },
44 { 0x13, KEY_ZOOM },
45
46 { 0x19, KEY_CAMERA }, /* SNAPSHOT */
47 { 0x1a, KEY_SEARCH }, /* scan */
48
49 { 0x37, KEY_REWIND }, /* << */
50 { 0x32, KEY_RECORD }, /* o (red) */
51 { 0x33, KEY_FORWARD }, /* >> */
52 { 0x11, KEY_STOP }, /* square */
53 { 0x3b, KEY_PLAY }, /* > */
54 { 0x30, KEY_PLAYPAUSE }, /* || */
55
56 { 0x31, KEY_TV },
57 { 0x34, KEY_RADIO },
58};
59
60static struct rc_keymap pixelview_new_map = {
61 .map = {
62 .scan = pixelview_new,
63 .size = ARRAY_SIZE(pixelview_new),
64 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
65 .name = RC_MAP_PIXELVIEW_NEW,
66 }
67};
68
69static int __init init_rc_map_pixelview_new(void)
70{
71 return ir_register_map(&pixelview_new_map);
72}
73
74static void __exit exit_rc_map_pixelview_new(void)
75{
76 ir_unregister_map(&pixelview_new_map);
77}
78
79module_init(init_rc_map_pixelview_new)
80module_exit(exit_rc_map_pixelview_new)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pixelview.c b/drivers/media/IR/keymaps/rc-pixelview.c
new file mode 100644
index 000000000000..82ff12e182a0
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pixelview.c
@@ -0,0 +1,82 @@
1/* pixelview.h - Keytable for pixelview Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode pixelview[] = {
16
17 { 0x1e, KEY_POWER }, /* power */
18 { 0x07, KEY_MEDIA }, /* source */
19 { 0x1c, KEY_SEARCH }, /* scan */
20
21
22 { 0x03, KEY_TUNER }, /* TV/FM */
23
24 { 0x00, KEY_RECORD },
25 { 0x08, KEY_STOP },
26 { 0x11, KEY_PLAY },
27
28 { 0x1a, KEY_PLAYPAUSE }, /* freeze */
29 { 0x19, KEY_ZOOM }, /* zoom */
30 { 0x0f, KEY_TEXT }, /* min */
31
32 { 0x01, KEY_1 },
33 { 0x0b, KEY_2 },
34 { 0x1b, KEY_3 },
35 { 0x05, KEY_4 },
36 { 0x09, KEY_5 },
37 { 0x15, KEY_6 },
38 { 0x06, KEY_7 },
39 { 0x0a, KEY_8 },
40 { 0x12, KEY_9 },
41 { 0x02, KEY_0 },
42 { 0x10, KEY_LAST }, /* +100 */
43 { 0x13, KEY_LIST }, /* recall */
44
45 { 0x1f, KEY_CHANNELUP }, /* chn down */
46 { 0x17, KEY_CHANNELDOWN }, /* chn up */
47 { 0x16, KEY_VOLUMEUP }, /* vol down */
48 { 0x14, KEY_VOLUMEDOWN }, /* vol up */
49
50 { 0x04, KEY_KPMINUS }, /* <<< */
51 { 0x0e, KEY_SETUP }, /* function */
52 { 0x0c, KEY_KPPLUS }, /* >>> */
53
54 { 0x0d, KEY_GOTO }, /* mts */
55 { 0x1d, KEY_REFRESH }, /* reset */
56 { 0x18, KEY_MUTE }, /* mute/unmute */
57};
58
59static struct rc_keymap pixelview_map = {
60 .map = {
61 .scan = pixelview,
62 .size = ARRAY_SIZE(pixelview),
63 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
64 .name = RC_MAP_PIXELVIEW,
65 }
66};
67
68static int __init init_rc_map_pixelview(void)
69{
70 return ir_register_map(&pixelview_map);
71}
72
73static void __exit exit_rc_map_pixelview(void)
74{
75 ir_unregister_map(&pixelview_map);
76}
77
78module_init(init_rc_map_pixelview)
79module_exit(exit_rc_map_pixelview)
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-powercolor-real-angel.c b/drivers/media/IR/keymaps/rc-powercolor-real-angel.c
new file mode 100644
index 000000000000..7cef8190a224
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-powercolor-real-angel.c
@@ -0,0 +1,81 @@
1/* powercolor-real-angel.h - Keytable for powercolor_real_angel Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Remote control for Powercolor Real Angel 330
17 * Daniel Fraga <fragabr@gmail.com>
18 */
19
20static struct ir_scancode powercolor_real_angel[] = {
21 { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
22 { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
23 { 0x00, KEY_0 },
24 { 0x01, KEY_1 },
25 { 0x02, KEY_2 },
26 { 0x03, KEY_3 },
27 { 0x04, KEY_4 },
28 { 0x05, KEY_5 },
29 { 0x06, KEY_6 },
30 { 0x07, KEY_7 },
31 { 0x08, KEY_8 },
32 { 0x09, KEY_9 },
33 { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */
34 { 0x29, KEY_PREVIOUS }, /* previous channel */
35 { 0x12, KEY_BRIGHTNESSUP },
36 { 0x13, KEY_BRIGHTNESSDOWN },
37 { 0x2b, KEY_MODE }, /* stereo/mono */
38 { 0x2c, KEY_TEXT }, /* teletext */
39 { 0x20, KEY_CHANNELUP }, /* channel up */
40 { 0x21, KEY_CHANNELDOWN }, /* channel down */
41 { 0x10, KEY_VOLUMEUP }, /* volume up */
42 { 0x11, KEY_VOLUMEDOWN }, /* volume down */
43 { 0x0d, KEY_MUTE },
44 { 0x1f, KEY_RECORD },
45 { 0x17, KEY_PLAY },
46 { 0x16, KEY_PAUSE },
47 { 0x0b, KEY_STOP },
48 { 0x27, KEY_FASTFORWARD },
49 { 0x26, KEY_REWIND },
50 { 0x1e, KEY_SEARCH }, /* autoscan */
51 { 0x0e, KEY_CAMERA }, /* snapshot */
52 { 0x2d, KEY_SETUP },
53 { 0x0f, KEY_SCREEN }, /* full screen */
54 { 0x14, KEY_RADIO }, /* FM radio */
55 { 0x25, KEY_POWER }, /* power */
56};
57
58static struct rc_keymap powercolor_real_angel_map = {
59 .map = {
60 .scan = powercolor_real_angel,
61 .size = ARRAY_SIZE(powercolor_real_angel),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_POWERCOLOR_REAL_ANGEL,
64 }
65};
66
67static int __init init_rc_map_powercolor_real_angel(void)
68{
69 return ir_register_map(&powercolor_real_angel_map);
70}
71
72static void __exit exit_rc_map_powercolor_real_angel(void)
73{
74 ir_unregister_map(&powercolor_real_angel_map);
75}
76
77module_init(init_rc_map_powercolor_real_angel)
78module_exit(exit_rc_map_powercolor_real_angel)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-proteus-2309.c b/drivers/media/IR/keymaps/rc-proteus-2309.c
new file mode 100644
index 000000000000..22e92d39dee5
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-proteus-2309.c
@@ -0,0 +1,69 @@
1/* proteus-2309.h - Keytable for proteus_2309 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
16
17static struct ir_scancode proteus_2309[] = {
18 /* numeric */
19 { 0x00, KEY_0 },
20 { 0x01, KEY_1 },
21 { 0x02, KEY_2 },
22 { 0x03, KEY_3 },
23 { 0x04, KEY_4 },
24 { 0x05, KEY_5 },
25 { 0x06, KEY_6 },
26 { 0x07, KEY_7 },
27 { 0x08, KEY_8 },
28 { 0x09, KEY_9 },
29
30 { 0x5c, KEY_POWER }, /* power */
31 { 0x20, KEY_ZOOM }, /* full screen */
32 { 0x0f, KEY_BACKSPACE }, /* recall */
33 { 0x1b, KEY_ENTER }, /* mute */
34 { 0x41, KEY_RECORD }, /* record */
35 { 0x43, KEY_STOP }, /* stop */
36 { 0x16, KEY_S },
37 { 0x1a, KEY_POWER2 }, /* off */
38 { 0x2e, KEY_RED },
39 { 0x1f, KEY_CHANNELDOWN }, /* channel - */
40 { 0x1c, KEY_CHANNELUP }, /* channel + */
41 { 0x10, KEY_VOLUMEDOWN }, /* volume - */
42 { 0x1e, KEY_VOLUMEUP }, /* volume + */
43 { 0x14, KEY_F1 },
44};
45
46static struct rc_keymap proteus_2309_map = {
47 .map = {
48 .scan = proteus_2309,
49 .size = ARRAY_SIZE(proteus_2309),
50 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
51 .name = RC_MAP_PROTEUS_2309,
52 }
53};
54
55static int __init init_rc_map_proteus_2309(void)
56{
57 return ir_register_map(&proteus_2309_map);
58}
59
60static void __exit exit_rc_map_proteus_2309(void)
61{
62 ir_unregister_map(&proteus_2309_map);
63}
64
65module_init(init_rc_map_proteus_2309)
66module_exit(exit_rc_map_proteus_2309)
67
68MODULE_LICENSE("GPL");
69MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-purpletv.c b/drivers/media/IR/keymaps/rc-purpletv.c
new file mode 100644
index 000000000000..4e20fc2269f7
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-purpletv.c
@@ -0,0 +1,81 @@
1/* purpletv.h - Keytable for purpletv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode purpletv[] = {
16 { 0x03, KEY_POWER },
17 { 0x6f, KEY_MUTE },
18 { 0x10, KEY_BACKSPACE }, /* Recall */
19
20 { 0x11, KEY_0 },
21 { 0x04, KEY_1 },
22 { 0x05, KEY_2 },
23 { 0x06, KEY_3 },
24 { 0x08, KEY_4 },
25 { 0x09, KEY_5 },
26 { 0x0a, KEY_6 },
27 { 0x0c, KEY_7 },
28 { 0x0d, KEY_8 },
29 { 0x0e, KEY_9 },
30 { 0x12, KEY_DOT }, /* 100+ */
31
32 { 0x07, KEY_VOLUMEUP },
33 { 0x0b, KEY_VOLUMEDOWN },
34 { 0x1a, KEY_KPPLUS },
35 { 0x18, KEY_KPMINUS },
36 { 0x15, KEY_UP },
37 { 0x1d, KEY_DOWN },
38 { 0x0f, KEY_CHANNELUP },
39 { 0x13, KEY_CHANNELDOWN },
40 { 0x48, KEY_ZOOM },
41
42 { 0x1b, KEY_VIDEO }, /* Video source */
43 { 0x1f, KEY_CAMERA }, /* Snapshot */
44 { 0x49, KEY_LANGUAGE }, /* MTS Select */
45 { 0x19, KEY_SEARCH }, /* Auto Scan */
46
47 { 0x4b, KEY_RECORD },
48 { 0x46, KEY_PLAY },
49 { 0x45, KEY_PAUSE }, /* Pause */
50 { 0x44, KEY_STOP },
51 { 0x43, KEY_TIME }, /* Time Shift */
52 { 0x17, KEY_CHANNEL }, /* SURF CH */
53 { 0x40, KEY_FORWARD }, /* Forward ? */
54 { 0x42, KEY_REWIND }, /* Backward ? */
55
56};
57
58static struct rc_keymap purpletv_map = {
59 .map = {
60 .scan = purpletv,
61 .size = ARRAY_SIZE(purpletv),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_PURPLETV,
64 }
65};
66
67static int __init init_rc_map_purpletv(void)
68{
69 return ir_register_map(&purpletv_map);
70}
71
72static void __exit exit_rc_map_purpletv(void)
73{
74 ir_unregister_map(&purpletv_map);
75}
76
77module_init(init_rc_map_purpletv)
78module_exit(exit_rc_map_purpletv)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-pv951.c b/drivers/media/IR/keymaps/rc-pv951.c
new file mode 100644
index 000000000000..36679e706cf3
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-pv951.c
@@ -0,0 +1,78 @@
1/* pv951.h - Keytable for pv951 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Mark Phalan <phalanm@o2.ie> */
16
17static struct ir_scancode pv951[] = {
18 { 0x00, KEY_0 },
19 { 0x01, KEY_1 },
20 { 0x02, KEY_2 },
21 { 0x03, KEY_3 },
22 { 0x04, KEY_4 },
23 { 0x05, KEY_5 },
24 { 0x06, KEY_6 },
25 { 0x07, KEY_7 },
26 { 0x08, KEY_8 },
27 { 0x09, KEY_9 },
28
29 { 0x12, KEY_POWER },
30 { 0x10, KEY_MUTE },
31 { 0x1f, KEY_VOLUMEDOWN },
32 { 0x1b, KEY_VOLUMEUP },
33 { 0x1a, KEY_CHANNELUP },
34 { 0x1e, KEY_CHANNELDOWN },
35 { 0x0e, KEY_PAGEUP },
36 { 0x1d, KEY_PAGEDOWN },
37 { 0x13, KEY_SOUND },
38
39 { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */
40 { 0x16, KEY_SUBTITLE }, /* CC */
41 { 0x0d, KEY_TEXT }, /* TTX */
42 { 0x0b, KEY_TV }, /* AIR/CBL */
43 { 0x11, KEY_PC }, /* PC/TV */
44 { 0x17, KEY_OK }, /* CH RTN */
45 { 0x19, KEY_MODE }, /* FUNC */
46 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
47
48 /* Not sure what to do with these ones! */
49 { 0x0f, KEY_SELECT }, /* SOURCE */
50 { 0x0a, KEY_KPPLUS }, /* +100 */
51 { 0x14, KEY_EQUAL }, /* SYNC */
52 { 0x1c, KEY_MEDIA }, /* PC/TV */
53};
54
55static struct rc_keymap pv951_map = {
56 .map = {
57 .scan = pv951,
58 .size = ARRAY_SIZE(pv951),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_PV951,
61 }
62};
63
64static int __init init_rc_map_pv951(void)
65{
66 return ir_register_map(&pv951_map);
67}
68
69static void __exit exit_rc_map_pv951(void)
70{
71 ir_unregister_map(&pv951_map);
72}
73
74module_init(init_rc_map_pv951)
75module_exit(exit_rc_map_pv951)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c
new file mode 100644
index 000000000000..cc6b8f548747
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c
@@ -0,0 +1,103 @@
1/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/*
16 * Hauppauge:the newer, gray remotes (seems there are multiple
17 * slightly different versions), shipped with cx88+ivtv cards.
18 *
19 * This table contains the complete RC5 code, instead of just the data part
20 */
21
22static struct ir_scancode rc5_hauppauge_new[] = {
23 /* Keys 0 to 9 */
24 { 0x1e00, KEY_0 },
25 { 0x1e01, KEY_1 },
26 { 0x1e02, KEY_2 },
27 { 0x1e03, KEY_3 },
28 { 0x1e04, KEY_4 },
29 { 0x1e05, KEY_5 },
30 { 0x1e06, KEY_6 },
31 { 0x1e07, KEY_7 },
32 { 0x1e08, KEY_8 },
33 { 0x1e09, KEY_9 },
34
35 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
36 { 0x1e0b, KEY_RED }, /* red button */
37 { 0x1e0c, KEY_RADIO },
38 { 0x1e0d, KEY_MENU },
39 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
40 { 0x1e0f, KEY_MUTE },
41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
44 { 0x1e14, KEY_UP },
45 { 0x1e15, KEY_DOWN },
46 { 0x1e16, KEY_LEFT },
47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO }, /* Videos */
49 { 0x1e19, KEY_AUDIO }, /* Music */
50 /* 0x1e1a: Pictures - presume this means
51 "Multimedia Home Platform" -
52 no "PICTURES" key in input.h
53 */
54 { 0x1e1a, KEY_MHP },
55
56 { 0x1e1b, KEY_EPG }, /* Guide */
57 { 0x1e1c, KEY_TV },
58 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
59 { 0x1e1f, KEY_EXIT }, /* back/exit */
60 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
61 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
62 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
63 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
64 { 0x1e25, KEY_ENTER }, /* OK */
65 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
66 { 0x1e29, KEY_BLUE }, /* blue key */
67 { 0x1e2e, KEY_GREEN }, /* green button */
68 { 0x1e30, KEY_PAUSE }, /* pause */
69 { 0x1e32, KEY_REWIND }, /* backward << */
70 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
71 { 0x1e35, KEY_PLAY },
72 { 0x1e36, KEY_STOP },
73 { 0x1e37, KEY_RECORD }, /* recording */
74 { 0x1e38, KEY_YELLOW }, /* yellow key */
75 { 0x1e3b, KEY_SELECT }, /* top right button */
76 { 0x1e3c, KEY_ZOOM }, /* full */
77 { 0x1e3d, KEY_POWER }, /* system power (green button) */
78};
79
80static struct rc_keymap rc5_hauppauge_new_map = {
81 .map = {
82 .scan = rc5_hauppauge_new,
83 .size = ARRAY_SIZE(rc5_hauppauge_new),
84 .ir_type = IR_TYPE_RC5,
85 .name = RC_MAP_RC5_HAUPPAUGE_NEW,
86 }
87};
88
89static int __init init_rc_map_rc5_hauppauge_new(void)
90{
91 return ir_register_map(&rc5_hauppauge_new_map);
92}
93
94static void __exit exit_rc_map_rc5_hauppauge_new(void)
95{
96 ir_unregister_map(&rc5_hauppauge_new_map);
97}
98
99module_init(init_rc_map_rc5_hauppauge_new)
100module_exit(exit_rc_map_rc5_hauppauge_new)
101
102MODULE_LICENSE("GPL");
103MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-rc5-tv.c b/drivers/media/IR/keymaps/rc-rc5-tv.c
new file mode 100644
index 000000000000..73cce2f8ddfb
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-rc5-tv.c
@@ -0,0 +1,81 @@
1/* rc5-tv.h - Keytable for rc5_tv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* generic RC5 keytable */
16/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
17/* used by old (black) Hauppauge remotes */
18
19static struct ir_scancode rc5_tv[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
33 { 0x0c, KEY_POWER }, /* standby */
34 { 0x0d, KEY_MUTE }, /* mute / demute */
35 { 0x0f, KEY_TV }, /* display */
36 { 0x10, KEY_VOLUMEUP },
37 { 0x11, KEY_VOLUMEDOWN },
38 { 0x12, KEY_BRIGHTNESSUP },
39 { 0x13, KEY_BRIGHTNESSDOWN },
40 { 0x1e, KEY_SEARCH }, /* search + */
41 { 0x20, KEY_CHANNELUP }, /* channel / program + */
42 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
43 { 0x22, KEY_CHANNEL }, /* alt / channel */
44 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
45 { 0x26, KEY_SLEEP }, /* sleeptimer */
46 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
47 { 0x30, KEY_PAUSE },
48 { 0x32, KEY_REWIND },
49 { 0x33, KEY_GOTO },
50 { 0x35, KEY_PLAY },
51 { 0x36, KEY_STOP },
52 { 0x37, KEY_RECORD }, /* recording */
53 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
54 { 0x3d, KEY_SUSPEND }, /* system standby */
55
56};
57
58static struct rc_keymap rc5_tv_map = {
59 .map = {
60 .scan = rc5_tv,
61 .size = ARRAY_SIZE(rc5_tv),
62 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_RC5_TV,
64 }
65};
66
67static int __init init_rc_map_rc5_tv(void)
68{
69 return ir_register_map(&rc5_tv_map);
70}
71
72static void __exit exit_rc_map_rc5_tv(void)
73{
74 ir_unregister_map(&rc5_tv_map);
75}
76
77module_init(init_rc_map_rc5_tv)
78module_exit(exit_rc_map_rc5_tv)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c
new file mode 100644
index 000000000000..ab1a6d2baf72
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c
@@ -0,0 +1,78 @@
1/* real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Zogis Real Audio 220 - 32 keys IR */
16
17static struct ir_scancode real_audio_220_32_keys[] = {
18 { 0x1c, KEY_RADIO},
19 { 0x12, KEY_POWER2},
20
21 { 0x01, KEY_1},
22 { 0x02, KEY_2},
23 { 0x03, KEY_3},
24 { 0x04, KEY_4},
25 { 0x05, KEY_5},
26 { 0x06, KEY_6},
27 { 0x07, KEY_7},
28 { 0x08, KEY_8},
29 { 0x09, KEY_9},
30 { 0x00, KEY_0},
31
32 { 0x0c, KEY_VOLUMEUP},
33 { 0x18, KEY_VOLUMEDOWN},
34 { 0x0b, KEY_CHANNELUP},
35 { 0x15, KEY_CHANNELDOWN},
36 { 0x16, KEY_ENTER},
37
38 { 0x11, KEY_LIST}, /* Source */
39 { 0x0d, KEY_AUDIO}, /* stereo */
40
41 { 0x0f, KEY_PREVIOUS}, /* Prev */
42 { 0x1b, KEY_TIME}, /* Timeshift */
43 { 0x1a, KEY_NEXT}, /* Next */
44
45 { 0x0e, KEY_STOP},
46 { 0x1f, KEY_PLAY},
47 { 0x1e, KEY_PLAYPAUSE}, /* Pause */
48
49 { 0x1d, KEY_RECORD},
50 { 0x13, KEY_MUTE},
51 { 0x19, KEY_CAMERA}, /* Snapshot */
52
53};
54
55static struct rc_keymap real_audio_220_32_keys_map = {
56 .map = {
57 .scan = real_audio_220_32_keys,
58 .size = ARRAY_SIZE(real_audio_220_32_keys),
59 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
60 .name = RC_MAP_REAL_AUDIO_220_32_KEYS,
61 }
62};
63
64static int __init init_rc_map_real_audio_220_32_keys(void)
65{
66 return ir_register_map(&real_audio_220_32_keys_map);
67}
68
69static void __exit exit_rc_map_real_audio_220_32_keys(void)
70{
71 ir_unregister_map(&real_audio_220_32_keys_map);
72}
73
74module_init(init_rc_map_real_audio_220_32_keys)
75module_exit(exit_rc_map_real_audio_220_32_keys)
76
77MODULE_LICENSE("GPL");
78MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tbs-nec.c b/drivers/media/IR/keymaps/rc-tbs-nec.c
new file mode 100644
index 000000000000..3309631e6f80
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-tbs-nec.c
@@ -0,0 +1,73 @@
1/* tbs-nec.h - Keytable for tbs_nec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode tbs_nec[] = {
16 { 0x04, KEY_POWER2}, /*power*/
17 { 0x14, KEY_MUTE}, /*mute*/
18 { 0x07, KEY_1},
19 { 0x06, KEY_2},
20 { 0x05, KEY_3},
21 { 0x0b, KEY_4},
22 { 0x0a, KEY_5},
23 { 0x09, KEY_6},
24 { 0x0f, KEY_7},
25 { 0x0e, KEY_8},
26 { 0x0d, KEY_9},
27 { 0x12, KEY_0},
28 { 0x16, KEY_CHANNELUP}, /*ch+*/
29 { 0x11, KEY_CHANNELDOWN},/*ch-*/
30 { 0x13, KEY_VOLUMEUP}, /*vol+*/
31 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
32 { 0x03, KEY_RECORD}, /*rec*/
33 { 0x18, KEY_PAUSE}, /*pause*/
34 { 0x19, KEY_OK}, /*ok*/
35 { 0x1a, KEY_CAMERA}, /* snapshot */
36 { 0x01, KEY_UP},
37 { 0x10, KEY_LEFT},
38 { 0x02, KEY_RIGHT},
39 { 0x08, KEY_DOWN},
40 { 0x15, KEY_FAVORITES},
41 { 0x17, KEY_SUBTITLE},
42 { 0x1d, KEY_ZOOM},
43 { 0x1f, KEY_EXIT},
44 { 0x1e, KEY_MENU},
45 { 0x1c, KEY_EPG},
46 { 0x00, KEY_PREVIOUS},
47 { 0x1b, KEY_MODE},
48};
49
50static struct rc_keymap tbs_nec_map = {
51 .map = {
52 .scan = tbs_nec,
53 .size = ARRAY_SIZE(tbs_nec),
54 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
55 .name = RC_MAP_TBS_NEC,
56 }
57};
58
59static int __init init_rc_map_tbs_nec(void)
60{
61 return ir_register_map(&tbs_nec_map);
62}
63
64static void __exit exit_rc_map_tbs_nec(void)
65{
66 ir_unregister_map(&tbs_nec_map);
67}
68
69module_init(init_rc_map_tbs_nec)
70module_exit(exit_rc_map_tbs_nec)
71
72MODULE_LICENSE("GPL");
73MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c
new file mode 100644
index 000000000000..5326a0b444c1
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c
@@ -0,0 +1,92 @@
1/* terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Terratec Cinergy Hybrid T USB XS
16 Devin Heitmueller <dheitmueller@linuxtv.org>
17 */
18
19static struct ir_scancode terratec_cinergy_xs[] = {
20 { 0x41, KEY_HOME},
21 { 0x01, KEY_POWER},
22 { 0x42, KEY_MENU},
23 { 0x02, KEY_1},
24 { 0x03, KEY_2},
25 { 0x04, KEY_3},
26 { 0x43, KEY_SUBTITLE},
27 { 0x05, KEY_4},
28 { 0x06, KEY_5},
29 { 0x07, KEY_6},
30 { 0x44, KEY_TEXT},
31 { 0x08, KEY_7},
32 { 0x09, KEY_8},
33 { 0x0a, KEY_9},
34 { 0x45, KEY_DELETE},
35 { 0x0b, KEY_TUNER},
36 { 0x0c, KEY_0},
37 { 0x0d, KEY_MODE},
38 { 0x46, KEY_TV},
39 { 0x47, KEY_DVD},
40 { 0x49, KEY_VIDEO},
41 { 0x4b, KEY_AUX},
42 { 0x10, KEY_UP},
43 { 0x11, KEY_LEFT},
44 { 0x12, KEY_OK},
45 { 0x13, KEY_RIGHT},
46 { 0x14, KEY_DOWN},
47 { 0x0f, KEY_EPG},
48 { 0x16, KEY_INFO},
49 { 0x4d, KEY_BACKSPACE},
50 { 0x1c, KEY_VOLUMEUP},
51 { 0x4c, KEY_PLAY},
52 { 0x1b, KEY_CHANNELUP},
53 { 0x1e, KEY_VOLUMEDOWN},
54 { 0x1d, KEY_MUTE},
55 { 0x1f, KEY_CHANNELDOWN},
56 { 0x17, KEY_RED},
57 { 0x18, KEY_GREEN},
58 { 0x19, KEY_YELLOW},
59 { 0x1a, KEY_BLUE},
60 { 0x58, KEY_RECORD},
61 { 0x48, KEY_STOP},
62 { 0x40, KEY_PAUSE},
63 { 0x54, KEY_LAST},
64 { 0x4e, KEY_REWIND},
65 { 0x4f, KEY_FASTFORWARD},
66 { 0x5c, KEY_NEXT},
67};
68
69static struct rc_keymap terratec_cinergy_xs_map = {
70 .map = {
71 .scan = terratec_cinergy_xs,
72 .size = ARRAY_SIZE(terratec_cinergy_xs),
73 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
74 .name = RC_MAP_TERRATEC_CINERGY_XS,
75 }
76};
77
78static int __init init_rc_map_terratec_cinergy_xs(void)
79{
80 return ir_register_map(&terratec_cinergy_xs_map);
81}
82
83static void __exit exit_rc_map_terratec_cinergy_xs(void)
84{
85 ir_unregister_map(&terratec_cinergy_xs_map);
86}
87
88module_init(init_rc_map_terratec_cinergy_xs)
89module_exit(exit_rc_map_terratec_cinergy_xs)
90
91MODULE_LICENSE("GPL");
92MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tevii-nec.c b/drivers/media/IR/keymaps/rc-tevii-nec.c
new file mode 100644
index 000000000000..e30d411c07bb
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-tevii-nec.c
@@ -0,0 +1,88 @@
1/* tevii-nec.h - Keytable for tevii_nec Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode tevii_nec[] = {
16 { 0x0a, KEY_POWER2},
17 { 0x0c, KEY_MUTE},
18 { 0x11, KEY_1},
19 { 0x12, KEY_2},
20 { 0x13, KEY_3},
21 { 0x14, KEY_4},
22 { 0x15, KEY_5},
23 { 0x16, KEY_6},
24 { 0x17, KEY_7},
25 { 0x18, KEY_8},
26 { 0x19, KEY_9},
27 { 0x10, KEY_0},
28 { 0x1c, KEY_MENU},
29 { 0x0f, KEY_VOLUMEDOWN},
30 { 0x1a, KEY_LAST},
31 { 0x0e, KEY_OPEN},
32 { 0x04, KEY_RECORD},
33 { 0x09, KEY_VOLUMEUP},
34 { 0x08, KEY_CHANNELUP},
35 { 0x07, KEY_PVR},
36 { 0x0b, KEY_TIME},
37 { 0x02, KEY_RIGHT},
38 { 0x03, KEY_LEFT},
39 { 0x00, KEY_UP},
40 { 0x1f, KEY_OK},
41 { 0x01, KEY_DOWN},
42 { 0x05, KEY_TUNER},
43 { 0x06, KEY_CHANNELDOWN},
44 { 0x40, KEY_PLAYPAUSE},
45 { 0x1e, KEY_REWIND},
46 { 0x1b, KEY_FAVORITES},
47 { 0x1d, KEY_BACK},
48 { 0x4d, KEY_FASTFORWARD},
49 { 0x44, KEY_EPG},
50 { 0x4c, KEY_INFO},
51 { 0x41, KEY_AB},
52 { 0x43, KEY_AUDIO},
53 { 0x45, KEY_SUBTITLE},
54 { 0x4a, KEY_LIST},
55 { 0x46, KEY_F1},
56 { 0x47, KEY_F2},
57 { 0x5e, KEY_F3},
58 { 0x5c, KEY_F4},
59 { 0x52, KEY_F5},
60 { 0x5a, KEY_F6},
61 { 0x56, KEY_MODE},
62 { 0x58, KEY_SWITCHVIDEOMODE},
63};
64
65static struct rc_keymap tevii_nec_map = {
66 .map = {
67 .scan = tevii_nec,
68 .size = ARRAY_SIZE(tevii_nec),
69 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
70 .name = RC_MAP_TEVII_NEC,
71 }
72};
73
74static int __init init_rc_map_tevii_nec(void)
75{
76 return ir_register_map(&tevii_nec_map);
77}
78
79static void __exit exit_rc_map_tevii_nec(void)
80{
81 ir_unregister_map(&tevii_nec_map);
82}
83
84module_init(init_rc_map_tevii_nec)
85module_exit(exit_rc_map_tevii_nec)
86
87MODULE_LICENSE("GPL");
88MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-tt-1500.c b/drivers/media/IR/keymaps/rc-tt-1500.c
new file mode 100644
index 000000000000..bc88de011d5d
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-tt-1500.c
@@ -0,0 +1,82 @@
1/* tt-1500.h - Keytable for tt_1500 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* for the Technotrend 1500 bundled remotes (grey and black): */
16
17static struct ir_scancode tt_1500[] = {
18 { 0x01, KEY_POWER },
19 { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
20 { 0x03, KEY_1 },
21 { 0x04, KEY_2 },
22 { 0x05, KEY_3 },
23 { 0x06, KEY_4 },
24 { 0x07, KEY_5 },
25 { 0x08, KEY_6 },
26 { 0x09, KEY_7 },
27 { 0x0a, KEY_8 },
28 { 0x0b, KEY_9 },
29 { 0x0c, KEY_0 },
30 { 0x0d, KEY_UP },
31 { 0x0e, KEY_LEFT },
32 { 0x0f, KEY_OK },
33 { 0x10, KEY_RIGHT },
34 { 0x11, KEY_DOWN },
35 { 0x12, KEY_INFO },
36 { 0x13, KEY_EXIT },
37 { 0x14, KEY_RED },
38 { 0x15, KEY_GREEN },
39 { 0x16, KEY_YELLOW },
40 { 0x17, KEY_BLUE },
41 { 0x18, KEY_MUTE },
42 { 0x19, KEY_TEXT },
43 { 0x1a, KEY_MODE }, /* ? TV/Radio */
44 { 0x21, KEY_OPTION },
45 { 0x22, KEY_EPG },
46 { 0x23, KEY_CHANNELUP },
47 { 0x24, KEY_CHANNELDOWN },
48 { 0x25, KEY_VOLUMEUP },
49 { 0x26, KEY_VOLUMEDOWN },
50 { 0x27, KEY_SETUP },
51 { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
52 { 0x3b, KEY_PLAY },
53 { 0x3c, KEY_STOP },
54 { 0x3d, KEY_REWIND },
55 { 0x3e, KEY_PAUSE },
56 { 0x3f, KEY_FORWARD },
57};
58
59static struct rc_keymap tt_1500_map = {
60 .map = {
61 .scan = tt_1500,
62 .size = ARRAY_SIZE(tt_1500),
63 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
64 .name = RC_MAP_TT_1500,
65 }
66};
67
68static int __init init_rc_map_tt_1500(void)
69{
70 return ir_register_map(&tt_1500_map);
71}
72
73static void __exit exit_rc_map_tt_1500(void)
74{
75 ir_unregister_map(&tt_1500_map);
76}
77
78module_init(init_rc_map_tt_1500)
79module_exit(exit_rc_map_tt_1500)
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-videomate-s350.c b/drivers/media/IR/keymaps/rc-videomate-s350.c
new file mode 100644
index 000000000000..4df7fcd1d2fc
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-videomate-s350.c
@@ -0,0 +1,85 @@
1/* videomate-s350.h - Keytable for videomate_s350 Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode videomate_s350[] = {
16 { 0x00, KEY_TV},
17 { 0x01, KEY_DVD},
18 { 0x04, KEY_RECORD},
19 { 0x05, KEY_VIDEO}, /* TV/Video */
20 { 0x07, KEY_STOP},
21 { 0x08, KEY_PLAYPAUSE},
22 { 0x0a, KEY_REWIND},
23 { 0x0f, KEY_FASTFORWARD},
24 { 0x10, KEY_CHANNELUP},
25 { 0x12, KEY_VOLUMEUP},
26 { 0x13, KEY_CHANNELDOWN},
27 { 0x14, KEY_MUTE},
28 { 0x15, KEY_VOLUMEDOWN},
29 { 0x16, KEY_1},
30 { 0x17, KEY_2},
31 { 0x18, KEY_3},
32 { 0x19, KEY_4},
33 { 0x1a, KEY_5},
34 { 0x1b, KEY_6},
35 { 0x1c, KEY_7},
36 { 0x1d, KEY_8},
37 { 0x1e, KEY_9},
38 { 0x1f, KEY_0},
39 { 0x21, KEY_SLEEP},
40 { 0x24, KEY_ZOOM},
41 { 0x25, KEY_LAST}, /* Recall */
42 { 0x26, KEY_SUBTITLE}, /* CC */
43 { 0x27, KEY_LANGUAGE}, /* MTS */
44 { 0x29, KEY_CHANNEL}, /* SURF */
45 { 0x2b, KEY_A},
46 { 0x2c, KEY_B},
47 { 0x2f, KEY_CAMERA}, /* Snapshot */
48 { 0x23, KEY_RADIO},
49 { 0x02, KEY_PREVIOUSSONG},
50 { 0x06, KEY_NEXTSONG},
51 { 0x03, KEY_EPG},
52 { 0x09, KEY_SETUP},
53 { 0x22, KEY_BACKSPACE},
54 { 0x0c, KEY_UP},
55 { 0x0e, KEY_DOWN},
56 { 0x0b, KEY_LEFT},
57 { 0x0d, KEY_RIGHT},
58 { 0x11, KEY_ENTER},
59 { 0x20, KEY_TEXT},
60};
61
62static struct rc_keymap videomate_s350_map = {
63 .map = {
64 .scan = videomate_s350,
65 .size = ARRAY_SIZE(videomate_s350),
66 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
67 .name = RC_MAP_VIDEOMATE_S350,
68 }
69};
70
71static int __init init_rc_map_videomate_s350(void)
72{
73 return ir_register_map(&videomate_s350_map);
74}
75
76static void __exit exit_rc_map_videomate_s350(void)
77{
78 ir_unregister_map(&videomate_s350_map);
79}
80
81module_init(init_rc_map_videomate_s350)
82module_exit(exit_rc_map_videomate_s350)
83
84MODULE_LICENSE("GPL");
85MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c b/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c
new file mode 100644
index 000000000000..776b0a638d87
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c
@@ -0,0 +1,87 @@
1/* videomate-tv-pvr.h - Keytable for videomate_tv_pvr Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15static struct ir_scancode videomate_tv_pvr[] = {
16 { 0x14, KEY_MUTE },
17 { 0x24, KEY_ZOOM },
18
19 { 0x01, KEY_DVD },
20 { 0x23, KEY_RADIO },
21 { 0x00, KEY_TV },
22
23 { 0x0a, KEY_REWIND },
24 { 0x08, KEY_PLAYPAUSE },
25 { 0x0f, KEY_FORWARD },
26
27 { 0x02, KEY_PREVIOUS },
28 { 0x07, KEY_STOP },
29 { 0x06, KEY_NEXT },
30
31 { 0x0c, KEY_UP },
32 { 0x0e, KEY_DOWN },
33 { 0x0b, KEY_LEFT },
34 { 0x0d, KEY_RIGHT },
35 { 0x11, KEY_OK },
36
37 { 0x03, KEY_MENU },
38 { 0x09, KEY_SETUP },
39 { 0x05, KEY_VIDEO },
40 { 0x22, KEY_CHANNEL },
41
42 { 0x12, KEY_VOLUMEUP },
43 { 0x15, KEY_VOLUMEDOWN },
44 { 0x10, KEY_CHANNELUP },
45 { 0x13, KEY_CHANNELDOWN },
46
47 { 0x04, KEY_RECORD },
48
49 { 0x16, KEY_1 },
50 { 0x17, KEY_2 },
51 { 0x18, KEY_3 },
52 { 0x19, KEY_4 },
53 { 0x1a, KEY_5 },
54 { 0x1b, KEY_6 },
55 { 0x1c, KEY_7 },
56 { 0x1d, KEY_8 },
57 { 0x1e, KEY_9 },
58 { 0x1f, KEY_0 },
59
60 { 0x20, KEY_LANGUAGE },
61 { 0x21, KEY_SLEEP },
62};
63
64static struct rc_keymap videomate_tv_pvr_map = {
65 .map = {
66 .scan = videomate_tv_pvr,
67 .size = ARRAY_SIZE(videomate_tv_pvr),
68 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
69 .name = RC_MAP_VIDEOMATE_TV_PVR,
70 }
71};
72
73static int __init init_rc_map_videomate_tv_pvr(void)
74{
75 return ir_register_map(&videomate_tv_pvr_map);
76}
77
78static void __exit exit_rc_map_videomate_tv_pvr(void)
79{
80 ir_unregister_map(&videomate_tv_pvr_map);
81}
82
83module_init(init_rc_map_videomate_tv_pvr)
84module_exit(exit_rc_map_videomate_tv_pvr)
85
86MODULE_LICENSE("GPL");
87MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c
new file mode 100644
index 000000000000..9d2d550aaa90
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c
@@ -0,0 +1,82 @@
1/* winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Leadtek Winfast TV USB II Deluxe remote
16 Magnus Alm <magnus.alm@gmail.com>
17 */
18
19static struct ir_scancode winfast_usbii_deluxe[] = {
20 { 0x62, KEY_0},
21 { 0x75, KEY_1},
22 { 0x76, KEY_2},
23 { 0x77, KEY_3},
24 { 0x79, KEY_4},
25 { 0x7a, KEY_5},
26 { 0x7b, KEY_6},
27 { 0x7d, KEY_7},
28 { 0x7e, KEY_8},
29 { 0x7f, KEY_9},
30
31 { 0x38, KEY_CAMERA}, /* SNAPSHOT */
32 { 0x37, KEY_RECORD}, /* RECORD */
33 { 0x35, KEY_TIME}, /* TIMESHIFT */
34
35 { 0x74, KEY_VOLUMEUP}, /* VOLUMEUP */
36 { 0x78, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
37 { 0x64, KEY_MUTE}, /* MUTE */
38
39 { 0x21, KEY_CHANNEL}, /* SURF */
40 { 0x7c, KEY_CHANNELUP}, /* CHANNELUP */
41 { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
42 { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
43
44 { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
45
46 { 0x70, KEY_POWER2}, /* TV ON/OFF */
47
48 { 0x39, KEY_CYCLEWINDOWS}, /* MINIMIZE (BOSS) */
49 { 0x3a, KEY_NEW}, /* PIP */
50 { 0x73, KEY_ZOOM}, /* FULLSECREEN */
51
52 { 0x66, KEY_INFO}, /* OSD (DISPLAY) */
53
54 { 0x31, KEY_DOT}, /* '.' */
55 { 0x63, KEY_ENTER}, /* ENTER */
56
57};
58
59static struct rc_keymap winfast_usbii_deluxe_map = {
60 .map = {
61 .scan = winfast_usbii_deluxe,
62 .size = ARRAY_SIZE(winfast_usbii_deluxe),
63 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
64 .name = RC_MAP_WINFAST_USBII_DELUXE,
65 }
66};
67
68static int __init init_rc_map_winfast_usbii_deluxe(void)
69{
70 return ir_register_map(&winfast_usbii_deluxe_map);
71}
72
73static void __exit exit_rc_map_winfast_usbii_deluxe(void)
74{
75 ir_unregister_map(&winfast_usbii_deluxe_map);
76}
77
78module_init(init_rc_map_winfast_usbii_deluxe)
79module_exit(exit_rc_map_winfast_usbii_deluxe)
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-winfast.c b/drivers/media/IR/keymaps/rc-winfast.c
new file mode 100644
index 000000000000..0e90a3bd9499
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-winfast.c
@@ -0,0 +1,102 @@
1/* winfast.h - Keytable for winfast Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <media/rc-map.h>
14
15/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
16
17static struct ir_scancode winfast[] = {
18 /* Keys 0 to 9 */
19 { 0x12, KEY_0 },
20 { 0x05, KEY_1 },
21 { 0x06, KEY_2 },
22 { 0x07, KEY_3 },
23 { 0x09, KEY_4 },
24 { 0x0a, KEY_5 },
25 { 0x0b, KEY_6 },
26 { 0x0d, KEY_7 },
27 { 0x0e, KEY_8 },
28 { 0x0f, KEY_9 },
29
30 { 0x00, KEY_POWER },
31 { 0x1b, KEY_AUDIO }, /* Audio Source */
32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
33 { 0x1e, KEY_VIDEO }, /* Video Source */
34 { 0x16, KEY_INFO }, /* Display information */
35 { 0x04, KEY_VOLUMEUP },
36 { 0x08, KEY_VOLUMEDOWN },
37 { 0x0c, KEY_CHANNELUP },
38 { 0x10, KEY_CHANNELDOWN },
39 { 0x03, KEY_ZOOM }, /* fullscreen */
40 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
41 { 0x20, KEY_SLEEP },
42 { 0x29, KEY_CLEAR }, /* boss key */
43 { 0x14, KEY_MUTE },
44 { 0x2b, KEY_RED },
45 { 0x2c, KEY_GREEN },
46 { 0x2d, KEY_YELLOW },
47 { 0x2e, KEY_BLUE },
48 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
49 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
50 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
51 { 0x21, KEY_DOT },
52 { 0x13, KEY_ENTER },
53 { 0x11, KEY_LAST }, /* Recall (last channel */
54 { 0x22, KEY_PREVIOUS },
55 { 0x23, KEY_PLAYPAUSE },
56 { 0x24, KEY_NEXT },
57 { 0x25, KEY_TIME }, /* Time Shifting */
58 { 0x26, KEY_STOP },
59 { 0x27, KEY_RECORD },
60 { 0x28, KEY_SAVE }, /* Screenshot */
61 { 0x2f, KEY_MENU },
62 { 0x30, KEY_CANCEL },
63 { 0x31, KEY_CHANNEL }, /* Channel Surf */
64 { 0x32, KEY_SUBTITLE },
65 { 0x33, KEY_LANGUAGE },
66 { 0x34, KEY_REWIND },
67 { 0x35, KEY_FASTFORWARD },
68 { 0x36, KEY_TV },
69 { 0x37, KEY_RADIO }, /* FM */
70 { 0x38, KEY_DVD },
71
72 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
73 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
74 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
75 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
76 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
77};
78
79static struct rc_keymap winfast_map = {
80 .map = {
81 .scan = winfast,
82 .size = ARRAY_SIZE(winfast),
83 .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
84 .name = RC_MAP_WINFAST,
85 }
86};
87
88static int __init init_rc_map_winfast(void)
89{
90 return ir_register_map(&winfast_map);
91}
92
93static void __exit exit_rc_map_winfast(void)
94{
95 ir_unregister_map(&winfast_map);
96}
97
98module_init(init_rc_map_winfast)
99module_exit(exit_rc_map_winfast)
100
101MODULE_LICENSE("GPL");
102MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c
new file mode 100644
index 000000000000..46a8f1524b5b
--- /dev/null
+++ b/drivers/media/IR/rc-map.c
@@ -0,0 +1,84 @@
1/* ir-raw-event.c - handle IR Pulse/Space event
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <media/ir-core.h>
16#include <linux/spinlock.h>
17#include <linux/delay.h>
18
19/* Used to handle IR raw handler extensions */
20static LIST_HEAD(rc_map_list);
21static DEFINE_SPINLOCK(rc_map_lock);
22
23static struct rc_keymap *seek_rc_map(const char *name)
24{
25 struct rc_keymap *map = NULL;
26
27 spin_lock(&rc_map_lock);
28 list_for_each_entry(map, &rc_map_list, list) {
29 if (!strcmp(name, map->map.name)) {
30 spin_unlock(&rc_map_lock);
31 return map;
32 }
33 }
34 spin_unlock(&rc_map_lock);
35
36 return NULL;
37}
38
39struct ir_scancode_table *get_rc_map(const char *name)
40{
41
42 struct rc_keymap *map;
43
44 map = seek_rc_map(name);
45#ifdef MODULE
46 if (!map) {
47 int rc = request_module(name);
48 if (rc < 0) {
49 printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
50 return NULL;
51 }
52 msleep(20); /* Give some time for IR to register */
53
54 map = seek_rc_map(name);
55 }
56#endif
57 if (!map) {
58 printk(KERN_ERR "IR keymap %s not found\n", name);
59 return NULL;
60 }
61
62 printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
63
64 return &map->map;
65}
66EXPORT_SYMBOL_GPL(get_rc_map);
67
68int ir_register_map(struct rc_keymap *map)
69{
70 spin_lock(&rc_map_lock);
71 list_add_tail(&map->list, &rc_map_list);
72 spin_unlock(&rc_map_lock);
73 return 0;
74}
75EXPORT_SYMBOL_GPL(ir_register_map);
76
77void ir_unregister_map(struct rc_keymap *map)
78{
79 spin_lock(&rc_map_lock);
80 list_del(&map->list);
81 spin_unlock(&rc_map_lock);
82}
83EXPORT_SYMBOL_GPL(ir_unregister_map);
84
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 96d61707f501..b6ce528e1889 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -100,6 +100,8 @@ struct xc2028_data {
100 if (size != _rc) \ 100 if (size != _rc) \
101 tuner_info("i2c output error: rc = %d (should be %d)\n",\ 101 tuner_info("i2c output error: rc = %d (should be %d)\n",\
102 _rc, (int)size); \ 102 _rc, (int)size); \
103 if (priv->ctrl.msleep) \
104 msleep(priv->ctrl.msleep); \
103 _rc; \ 105 _rc; \
104}) 106})
105 107
@@ -119,6 +121,8 @@ struct xc2028_data {
119 if (isize != _rc) \ 121 if (isize != _rc) \
120 tuner_err("i2c input error: rc = %d (should be %d)\n", \ 122 tuner_err("i2c input error: rc = %d (should be %d)\n", \
121 _rc, (int)isize); \ 123 _rc, (int)isize); \
124 if (priv->ctrl.msleep) \
125 msleep(priv->ctrl.msleep); \
122 _rc; \ 126 _rc; \
123}) 127})
124 128
@@ -129,8 +133,8 @@ struct xc2028_data {
129 (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \ 133 (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \
130 _val, sizeof(_val)))) { \ 134 _val, sizeof(_val)))) { \
131 tuner_err("Error on line %d: %d\n", __LINE__, _rc); \ 135 tuner_err("Error on line %d: %d\n", __LINE__, _rc); \
132 } else \ 136 } else if (priv->ctrl.msleep) \
133 msleep(10); \ 137 msleep(priv->ctrl.msleep); \
134 _rc; \ 138 _rc; \
135}) 139})
136 140
@@ -809,10 +813,20 @@ check_device:
809 hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, 813 hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
810 (version & 0xf0) >> 4, version & 0xf); 814 (version & 0xf0) >> 4, version & 0xf);
811 815
816
817 if (priv->ctrl.read_not_reliable)
818 goto read_not_reliable;
819
812 /* Check firmware version against what we downloaded. */ 820 /* Check firmware version against what we downloaded. */
813 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) { 821 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
814 tuner_err("Incorrect readback of firmware version.\n"); 822 if (!priv->ctrl.read_not_reliable) {
815 goto fail; 823 tuner_err("Incorrect readback of firmware version.\n");
824 goto fail;
825 } else {
826 tuner_err("Returned an incorrect version. However, "
827 "read is not reliable enough. Ignoring it.\n");
828 hwmodel = 3028;
829 }
816 } 830 }
817 831
818 /* Check that the tuner hardware model remains consistent over time. */ 832 /* Check that the tuner hardware model remains consistent over time. */
@@ -826,6 +840,7 @@ check_device:
826 goto fail; 840 goto fail;
827 } 841 }
828 842
843read_not_reliable:
829 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw)); 844 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
830 845
831 /* 846 /*
@@ -996,6 +1011,8 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
996 The reset CLK is needed only with tm6000. 1011 The reset CLK is needed only with tm6000.
997 Driver should work fine even if this fails. 1012 Driver should work fine even if this fails.
998 */ 1013 */
1014 if (priv->ctrl.msleep)
1015 msleep(priv->ctrl.msleep);
999 do_tuner_callback(fe, XC2028_RESET_CLK, 1); 1016 do_tuner_callback(fe, XC2028_RESET_CLK, 1);
1000 1017
1001 msleep(10); 1018 msleep(10);
diff --git a/drivers/media/common/tuners/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h
index a90c35d50add..9778c96a5006 100644
--- a/drivers/media/common/tuners/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -33,12 +33,14 @@ enum firmware_type {
33struct xc2028_ctrl { 33struct xc2028_ctrl {
34 char *fname; 34 char *fname;
35 int max_len; 35 int max_len;
36 int msleep;
36 unsigned int scode_table; 37 unsigned int scode_table;
37 unsigned int mts :1; 38 unsigned int mts :1;
38 unsigned int input1:1; 39 unsigned int input1:1;
39 unsigned int vhfbw7:1; 40 unsigned int vhfbw7:1;
40 unsigned int uhfbw8:1; 41 unsigned int uhfbw8:1;
41 unsigned int disable_power_mgmt:1; 42 unsigned int disable_power_mgmt:1;
43 unsigned int read_not_reliable:1;
42 unsigned int demod; 44 unsigned int demod;
43 enum firmware_type type:2; 45 enum firmware_type type:2;
44}; 46};
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 8b0cde38984d..248a2a9d8416 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -930,7 +930,6 @@ static int dst_fw_ver(struct dst_state *state)
930 dprintk(verbose, DST_INFO, 1, "Unsupported Command"); 930 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
931 return -1; 931 return -1;
932 } 932 }
933 memset(&state->fw_version, '\0', 8);
934 memcpy(&state->fw_version, &state->rxbuffer, 8); 933 memcpy(&state->fw_version, &state->rxbuffer, 8);
935 dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x", 934 dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
936 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f, 935 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
@@ -1053,7 +1052,6 @@ static int dst_get_tuner_info(struct dst_state *state)
1053 goto force; 1052 goto force;
1054 } 1053 }
1055 } 1054 }
1056 memset(&state->board_info, '\0', 8);
1057 memcpy(&state->board_info, &state->rxbuffer, 8); 1055 memcpy(&state->board_info, &state->rxbuffer, 8);
1058 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { 1056 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
1059 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); 1057 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index b6d46961a99e..b762e561a6d5 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -28,7 +28,7 @@
28#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <media/ir-common.h> 31#include <media/ir-core.h>
32 32
33#include "demux.h" 33#include "demux.h"
34#include "dmxdev.h" 34#include "dmxdev.h"
@@ -46,6 +46,8 @@
46#include "z0194a.h" 46#include "z0194a.h"
47#include "ds3000.h" 47#include "ds3000.h"
48 48
49#define MODULE_NAME "dm1105"
50
49#define UNSET (-1U) 51#define UNSET (-1U)
50 52
51#define DM1105_BOARD_NOAUTO UNSET 53#define DM1105_BOARD_NOAUTO UNSET
@@ -265,7 +267,6 @@ static void dm1105_card_list(struct pci_dev *pci)
265/* infrared remote control */ 267/* infrared remote control */
266struct infrared { 268struct infrared {
267 struct input_dev *input_dev; 269 struct input_dev *input_dev;
268 struct ir_input_state ir;
269 char input_phys[32]; 270 char input_phys[32];
270 struct work_struct work; 271 struct work_struct work;
271 u32 ir_command; 272 u32 ir_command;
@@ -531,8 +532,7 @@ static void dm1105_emit_key(struct work_struct *work)
531 532
532 data = (ircom >> 8) & 0x7f; 533 data = (ircom >> 8) & 0x7f;
533 534
534 ir_input_keydown(ir->input_dev, &ir->ir, data); 535 ir_keydown(ir->input_dev, data, 0);
535 ir_input_nokey(ir->input_dev, &ir->ir);
536} 536}
537 537
538/* work handler */ 538/* work handler */
@@ -594,8 +594,7 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
594int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) 594int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
595{ 595{
596 struct input_dev *input_dev; 596 struct input_dev *input_dev;
597 struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table; 597 char *ir_codes = NULL;
598 u64 ir_type = IR_TYPE_OTHER;
599 int err = -ENOMEM; 598 int err = -ENOMEM;
600 599
601 input_dev = input_allocate_device(); 600 input_dev = input_allocate_device();
@@ -606,12 +605,6 @@ int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
606 snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), 605 snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
607 "pci-%s/ir0", pci_name(dm1105->pdev)); 606 "pci-%s/ir0", pci_name(dm1105->pdev));
608 607
609 err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
610 if (err < 0) {
611 input_free_device(input_dev);
612 return err;
613 }
614
615 input_dev->name = "DVB on-card IR receiver"; 608 input_dev->name = "DVB on-card IR receiver";
616 input_dev->phys = dm1105->ir.input_phys; 609 input_dev->phys = dm1105->ir.input_phys;
617 input_dev->id.bustype = BUS_PCI; 610 input_dev->id.bustype = BUS_PCI;
@@ -628,9 +621,13 @@ int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
628 621
629 INIT_WORK(&dm1105->ir.work, dm1105_emit_key); 622 INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
630 623
631 err = ir_input_register(input_dev, ir_codes, NULL); 624 err = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
625 if (err < 0) {
626 input_free_device(input_dev);
627 return err;
628 }
632 629
633 return err; 630 return 0;
634} 631}
635 632
636void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105) 633void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 67f189b7aa1f..977ddba3e235 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -426,7 +426,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
426 }; 426 };
427 }; 427 };
428 428
429 if (demux->cnt_storage) { 429 if (demux->cnt_storage && dvb_demux_tscheck) {
430 /* check pkt counter */ 430 /* check pkt counter */
431 if (pid < MAX_PID) { 431 if (pid < MAX_PID) {
432 if (buf[1] & 0x80) 432 if (buf[1] & 0x80)
@@ -1248,12 +1248,9 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
1248 dvbdemux->feed[i].index = i; 1248 dvbdemux->feed[i].index = i;
1249 } 1249 }
1250 1250
1251 if (dvb_demux_tscheck) { 1251 dvbdemux->cnt_storage = vmalloc(MAX_PID + 1);
1252 dvbdemux->cnt_storage = vmalloc(MAX_PID + 1); 1252 if (!dvbdemux->cnt_storage)
1253 1253 printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
1254 if (!dvbdemux->cnt_storage)
1255 printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n");
1256 }
1257 1254
1258 INIT_LIST_HEAD(&dvbdemux->frontend_list); 1255 INIT_LIST_HEAD(&dvbdemux->frontend_list);
1259 1256
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 55ea260572bf..6932def4d266 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -95,6 +95,10 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
95 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. 95 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
96 */ 96 */
97 97
98#define DVB_FE_NO_EXIT 0
99#define DVB_FE_NORMAL_EXIT 1
100#define DVB_FE_DEVICE_REMOVED 2
101
98static DEFINE_MUTEX(frontend_mutex); 102static DEFINE_MUTEX(frontend_mutex);
99 103
100struct dvb_frontend_private { 104struct dvb_frontend_private {
@@ -497,7 +501,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
497{ 501{
498 struct dvb_frontend_private *fepriv = fe->frontend_priv; 502 struct dvb_frontend_private *fepriv = fe->frontend_priv;
499 503
500 if (fepriv->exit) 504 if (fepriv->exit != DVB_FE_NO_EXIT)
501 return 1; 505 return 1;
502 506
503 if (fepriv->dvbdev->writers == 1) 507 if (fepriv->dvbdev->writers == 1)
@@ -559,7 +563,7 @@ restart:
559 563
560 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { 564 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
561 /* got signal or quitting */ 565 /* got signal or quitting */
562 fepriv->exit = 1; 566 fepriv->exit = DVB_FE_NORMAL_EXIT;
563 break; 567 break;
564 } 568 }
565 569
@@ -673,7 +677,10 @@ restart:
673 } 677 }
674 678
675 fepriv->thread = NULL; 679 fepriv->thread = NULL;
676 fepriv->exit = 0; 680 if (kthread_should_stop())
681 fepriv->exit = DVB_FE_DEVICE_REMOVED;
682 else
683 fepriv->exit = DVB_FE_NO_EXIT;
677 mb(); 684 mb();
678 685
679 dvb_frontend_wakeup(fe); 686 dvb_frontend_wakeup(fe);
@@ -686,7 +693,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
686 693
687 dprintk ("%s\n", __func__); 694 dprintk ("%s\n", __func__);
688 695
689 fepriv->exit = 1; 696 fepriv->exit = DVB_FE_NORMAL_EXIT;
690 mb(); 697 mb();
691 698
692 if (!fepriv->thread) 699 if (!fepriv->thread)
@@ -755,7 +762,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
755 dprintk ("%s\n", __func__); 762 dprintk ("%s\n", __func__);
756 763
757 if (fepriv->thread) { 764 if (fepriv->thread) {
758 if (!fepriv->exit) 765 if (fepriv->exit == DVB_FE_NO_EXIT)
759 return 0; 766 return 0;
760 else 767 else
761 dvb_frontend_stop (fe); 768 dvb_frontend_stop (fe);
@@ -767,7 +774,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
767 return -EINTR; 774 return -EINTR;
768 775
769 fepriv->state = FESTATE_IDLE; 776 fepriv->state = FESTATE_IDLE;
770 fepriv->exit = 0; 777 fepriv->exit = DVB_FE_NO_EXIT;
771 fepriv->thread = NULL; 778 fepriv->thread = NULL;
772 mb(); 779 mb();
773 780
@@ -1490,7 +1497,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1490 1497
1491 dprintk("%s (%d)\n", __func__, _IOC_NR(cmd)); 1498 dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
1492 1499
1493 if (fepriv->exit) 1500 if (fepriv->exit != DVB_FE_NO_EXIT)
1494 return -ENODEV; 1501 return -ENODEV;
1495 1502
1496 if ((file->f_flags & O_ACCMODE) == O_RDONLY && 1503 if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
@@ -1916,6 +1923,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
1916 int ret; 1923 int ret;
1917 1924
1918 dprintk ("%s\n", __func__); 1925 dprintk ("%s\n", __func__);
1926 if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
1927 return -ENODEV;
1919 1928
1920 if (adapter->mfe_shared) { 1929 if (adapter->mfe_shared) {
1921 mutex_lock (&adapter->mfe_lock); 1930 mutex_lock (&adapter->mfe_lock);
@@ -2008,7 +2017,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
2008 ret = dvb_generic_release (inode, file); 2017 ret = dvb_generic_release (inode, file);
2009 2018
2010 if (dvbdev->users == -1) { 2019 if (dvbdev->users == -1) {
2011 if (fepriv->exit == 1) { 2020 if (fepriv->exit != DVB_FE_NO_EXIT) {
2012 fops_put(file->f_op); 2021 fops_put(file->f_op);
2013 file->f_op = NULL; 2022 file->f_op = NULL;
2014 wake_up(&dvbdev->wait_queue); 2023 wake_up(&dvbdev->wait_queue);
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index 6247239982e9..b6cbb1dfc5f1 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -37,7 +37,7 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
37 return 0; 37 return 0;
38} 38}
39 39
40static struct dvb_usb_rc_key a800_rc_keys[] = { 40static struct dvb_usb_rc_key ir_codes_a800_table[] = {
41 { 0x0201, KEY_PROG1 }, /* SOURCE */ 41 { 0x0201, KEY_PROG1 }, /* SOURCE */
42 { 0x0200, KEY_POWER }, /* POWER */ 42 { 0x0200, KEY_POWER }, /* POWER */
43 { 0x0205, KEY_1 }, /* 1 */ 43 { 0x0205, KEY_1 }, /* 1 */
@@ -147,8 +147,8 @@ static struct dvb_usb_device_properties a800_properties = {
147 .identify_state = a800_identify_state, 147 .identify_state = a800_identify_state,
148 148
149 .rc_interval = DEFAULT_RC_INTERVAL, 149 .rc_interval = DEFAULT_RC_INTERVAL,
150 .rc_key_map = a800_rc_keys, 150 .rc_key_map = ir_codes_a800_table,
151 .rc_key_map_size = ARRAY_SIZE(a800_rc_keys), 151 .rc_key_map_size = ARRAY_SIZE(ir_codes_a800_table),
152 .rc_query = a800_rc_query, 152 .rc_query = a800_rc_query,
153 153
154 .i2c_algo = &dibusb_i2c_algo, 154 .i2c_algo = &dibusb_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index f4379c650a19..b41fa873b04d 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -33,7 +33,7 @@ MODULE_PARM_DESC(debug,
33 33
34#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args) 34#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args)
35 35
36struct dvb_usb_rc_key af9005_rc_keys[] = { 36struct dvb_usb_rc_key ir_codes_af9005_table[] = {
37 37
38 {0x01b7, KEY_POWER}, 38 {0x01b7, KEY_POWER},
39 {0x01a7, KEY_VOLUMEUP}, 39 {0x01a7, KEY_VOLUMEUP},
@@ -74,7 +74,7 @@ struct dvb_usb_rc_key af9005_rc_keys[] = {
74 {0x00d5, KEY_GOTO}, /* marked jump on the remote */ 74 {0x00d5, KEY_GOTO}, /* marked jump on the remote */
75}; 75};
76 76
77int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys); 77int ir_codes_af9005_table_size = ARRAY_SIZE(ir_codes_af9005_table);
78 78
79static int repeatable_keys[] = { 79static int repeatable_keys[] = {
80 KEY_VOLUMEUP, 80 KEY_VOLUMEUP,
@@ -130,10 +130,10 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
130 deb_decode("code != inverted code\n"); 130 deb_decode("code != inverted code\n");
131 return 0; 131 return 0;
132 } 132 }
133 for (i = 0; i < af9005_rc_keys_size; i++) { 133 for (i = 0; i < ir_codes_af9005_table_size; i++) {
134 if (rc5_custom(&af9005_rc_keys[i]) == cust 134 if (rc5_custom(&ir_codes_af9005_table[i]) == cust
135 && rc5_data(&af9005_rc_keys[i]) == dat) { 135 && rc5_data(&ir_codes_af9005_table[i]) == dat) {
136 *event = af9005_rc_keys[i].event; 136 *event = ir_codes_af9005_table[i].event;
137 *state = REMOTE_KEY_PRESSED; 137 *state = REMOTE_KEY_PRESSED;
138 deb_decode 138 deb_decode
139 ("key pressed, event %x\n", *event); 139 ("key pressed, event %x\n", *event);
@@ -146,8 +146,8 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
146 return 0; 146 return 0;
147} 147}
148 148
149EXPORT_SYMBOL(af9005_rc_keys); 149EXPORT_SYMBOL(ir_codes_af9005_table);
150EXPORT_SYMBOL(af9005_rc_keys_size); 150EXPORT_SYMBOL(ir_codes_af9005_table_size);
151EXPORT_SYMBOL(af9005_rc_decode); 151EXPORT_SYMBOL(af9005_rc_decode);
152 152
153MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); 153MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
index ca5a0a4d2a47..cfd6107d5349 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -1109,8 +1109,8 @@ static int __init af9005_usb_module_init(void)
1109 return result; 1109 return result;
1110 } 1110 }
1111 rc_decode = symbol_request(af9005_rc_decode); 1111 rc_decode = symbol_request(af9005_rc_decode);
1112 rc_keys = symbol_request(af9005_rc_keys); 1112 rc_keys = symbol_request(ir_codes_af9005_table);
1113 rc_keys_size = symbol_request(af9005_rc_keys_size); 1113 rc_keys_size = symbol_request(ir_codes_af9005_table_size);
1114 if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { 1114 if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
1115 err("af9005_rc_decode function not found, disabling remote"); 1115 err("af9005_rc_decode function not found, disabling remote");
1116 af9005_properties.rc_query = NULL; 1116 af9005_properties.rc_query = NULL;
@@ -1128,9 +1128,9 @@ static void __exit af9005_usb_module_exit(void)
1128 if (rc_decode != NULL) 1128 if (rc_decode != NULL)
1129 symbol_put(af9005_rc_decode); 1129 symbol_put(af9005_rc_decode);
1130 if (rc_keys != NULL) 1130 if (rc_keys != NULL)
1131 symbol_put(af9005_rc_keys); 1131 symbol_put(ir_codes_af9005_table);
1132 if (rc_keys_size != NULL) 1132 if (rc_keys_size != NULL)
1133 symbol_put(af9005_rc_keys_size); 1133 symbol_put(ir_codes_af9005_table_size);
1134 /* deregister this driver from the USB subsystem */ 1134 /* deregister this driver from the USB subsystem */
1135 usb_deregister(&af9005_usb_driver); 1135 usb_deregister(&af9005_usb_driver);
1136} 1136}
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h
index 0bc48a012187..088e7083a39b 100644
--- a/drivers/media/dvb/dvb-usb/af9005.h
+++ b/drivers/media/dvb/dvb-usb/af9005.h
@@ -3490,7 +3490,7 @@ extern u8 regmask[8];
3490/* remote control decoder */ 3490/* remote control decoder */
3491extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, 3491extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
3492 u32 * event, int *state); 3492 u32 * event, int *state);
3493extern struct dvb_usb_rc_key af9005_rc_keys[]; 3493extern struct dvb_usb_rc_key ir_codes_af9005_table[];
3494extern int af9005_rc_keys_size; 3494extern int ir_codes_af9005_table_size;
3495 3495
3496#endif 3496#endif
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 74d94e45324d..66c7c3ea7990 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -752,19 +752,19 @@ static const struct af9015_setup *af9015_setup_match(unsigned int id,
752 752
753static const struct af9015_setup af9015_setup_modparam[] = { 753static const struct af9015_setup af9015_setup_modparam[] = {
754 { AF9015_REMOTE_A_LINK_DTU_M, 754 { AF9015_REMOTE_A_LINK_DTU_M,
755 af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link), 755 ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
756 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, 756 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
757 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, 757 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
758 af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi), 758 ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
759 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, 759 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
760 { AF9015_REMOTE_MYGICTV_U718, 760 { AF9015_REMOTE_MYGICTV_U718,
761 af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv), 761 ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
762 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, 762 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
763 { AF9015_REMOTE_DIGITTRADE_DVB_T, 763 { AF9015_REMOTE_DIGITTRADE_DVB_T,
764 af9015_rc_keys_digittrade, ARRAY_SIZE(af9015_rc_keys_digittrade), 764 ir_codes_af9015_table_digittrade, ARRAY_SIZE(ir_codes_af9015_table_digittrade),
765 af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) }, 765 af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) },
766 { AF9015_REMOTE_AVERMEDIA_KS, 766 { AF9015_REMOTE_AVERMEDIA_KS,
767 af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia), 767 ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
768 af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) }, 768 af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) },
769 { } 769 { }
770}; 770};
@@ -772,32 +772,32 @@ static const struct af9015_setup af9015_setup_modparam[] = {
772/* don't add new entries here anymore, use hashes instead */ 772/* don't add new entries here anymore, use hashes instead */
773static const struct af9015_setup af9015_setup_usbids[] = { 773static const struct af9015_setup af9015_setup_usbids[] = {
774 { USB_VID_LEADTEK, 774 { USB_VID_LEADTEK,
775 af9015_rc_keys_leadtek, ARRAY_SIZE(af9015_rc_keys_leadtek), 775 ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek),
776 af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) }, 776 af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) },
777 { USB_VID_VISIONPLUS, 777 { USB_VID_VISIONPLUS,
778 af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan), 778 ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
779 af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) }, 779 af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) },
780 { USB_VID_KWORLD_2, /* TODO: use correct rc keys */ 780 { USB_VID_KWORLD_2, /* TODO: use correct rc keys */
781 af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan), 781 ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
782 af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) }, 782 af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) },
783 { USB_VID_AVERMEDIA, 783 { USB_VID_AVERMEDIA,
784 af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia), 784 ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
785 af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) }, 785 af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) },
786 { USB_VID_MSI_2, 786 { USB_VID_MSI_2,
787 af9015_rc_keys_msi_digivox_iii, ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii), 787 ir_codes_af9015_table_msi_digivox_iii, ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii),
788 af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) }, 788 af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) },
789 { } 789 { }
790}; 790};
791 791
792static const struct af9015_setup af9015_setup_hashes[] = { 792static const struct af9015_setup af9015_setup_hashes[] = {
793 { 0xb8feb708, 793 { 0xb8feb708,
794 af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi), 794 ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
795 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, 795 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
796 { 0xa3703d00, 796 { 0xa3703d00,
797 af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link), 797 ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
798 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, 798 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
799 { 0x9b7dc64e, 799 { 0x9b7dc64e,
800 af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv), 800 ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
801 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, 801 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
802 { } 802 { }
803}; 803};
@@ -836,8 +836,8 @@ static void af9015_set_remote_config(struct usb_device *udev,
836 } else if (udev->descriptor.idProduct == 836 } else if (udev->descriptor.idProduct ==
837 cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { 837 cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
838 table = &(const struct af9015_setup){ 0, 838 table = &(const struct af9015_setup){ 0,
839 af9015_rc_keys_trekstor, 839 ir_codes_af9015_table_trekstor,
840 ARRAY_SIZE(af9015_rc_keys_trekstor), 840 ARRAY_SIZE(ir_codes_af9015_table_trekstor),
841 af9015_ir_table_trekstor, 841 af9015_ir_table_trekstor,
842 ARRAY_SIZE(af9015_ir_table_trekstor) 842 ARRAY_SIZE(af9015_ir_table_trekstor)
843 }; 843 };
@@ -1297,6 +1297,8 @@ static struct usb_device_id af9015_usb_table[] = {
1297 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, 1297 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
1298 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, 1298 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
1299 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, 1299 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
1300/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
1301 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
1300 {0}, 1302 {0},
1301}; 1303};
1302MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1304MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1500,7 +1502,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1500 "(VS-DVB-T 395U)", 1502 "(VS-DVB-T 395U)",
1501 .cold_ids = {&af9015_usb_table[16], 1503 .cold_ids = {&af9015_usb_table[16],
1502 &af9015_usb_table[17], 1504 &af9015_usb_table[17],
1503 &af9015_usb_table[18], NULL}, 1505 &af9015_usb_table[18],
1506 &af9015_usb_table[31], NULL},
1504 .warm_ids = {NULL}, 1507 .warm_ids = {NULL},
1505 }, 1508 },
1506 { 1509 {
@@ -1569,7 +1572,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1569 1572
1570 .i2c_algo = &af9015_i2c_algo, 1573 .i2c_algo = &af9015_i2c_algo,
1571 1574
1572 .num_device_descs = 7, /* max 9 */ 1575 .num_device_descs = 8, /* max 9 */
1573 .devices = { 1576 .devices = {
1574 { 1577 {
1575 .name = "AverMedia AVerTV Volar GPS 805 (A805)", 1578 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
@@ -1608,6 +1611,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1608 .cold_ids = {&af9015_usb_table[29], NULL}, 1611 .cold_ids = {&af9015_usb_table[29], NULL},
1609 .warm_ids = {NULL}, 1612 .warm_ids = {NULL},
1610 }, 1613 },
1614 {
1615 .name = "KWorld USB DVB-T Stick Mobile " \
1616 "(UB383-T)",
1617 .cold_ids = {&af9015_usb_table[30], NULL},
1618 .warm_ids = {NULL},
1619 },
1611 } 1620 }
1612 }, 1621 },
1613}; 1622};
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index ef36b1831490..63b2a4907b7e 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -123,7 +123,7 @@ enum af9015_remote {
123 123
124/* LeadTek - Y04G0051 */ 124/* LeadTek - Y04G0051 */
125/* Leadtek WinFast DTV Dongle Gold */ 125/* Leadtek WinFast DTV Dongle Gold */
126static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { 126static struct dvb_usb_rc_key ir_codes_af9015_table_leadtek[] = {
127 { 0x001e, KEY_1 }, 127 { 0x001e, KEY_1 },
128 { 0x001f, KEY_2 }, 128 { 0x001f, KEY_2 },
129 { 0x0020, KEY_3 }, 129 { 0x0020, KEY_3 },
@@ -227,7 +227,7 @@ static u8 af9015_ir_table_leadtek[] = {
227}; 227};
228 228
229/* TwinHan AzureWave AD-TU700(704J) */ 229/* TwinHan AzureWave AD-TU700(704J) */
230static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = { 230static struct dvb_usb_rc_key ir_codes_af9015_table_twinhan[] = {
231 { 0x053f, KEY_POWER }, 231 { 0x053f, KEY_POWER },
232 { 0x0019, KEY_FAVORITES }, /* Favorite List */ 232 { 0x0019, KEY_FAVORITES }, /* Favorite List */
233 { 0x0004, KEY_TEXT }, /* Teletext */ 233 { 0x0004, KEY_TEXT }, /* Teletext */
@@ -338,7 +338,7 @@ static u8 af9015_ir_table_twinhan[] = {
338}; 338};
339 339
340/* A-Link DTU(m) */ 340/* A-Link DTU(m) */
341static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = { 341static struct dvb_usb_rc_key ir_codes_af9015_table_a_link[] = {
342 { 0x001e, KEY_1 }, 342 { 0x001e, KEY_1 },
343 { 0x001f, KEY_2 }, 343 { 0x001f, KEY_2 },
344 { 0x0020, KEY_3 }, 344 { 0x0020, KEY_3 },
@@ -381,7 +381,7 @@ static u8 af9015_ir_table_a_link[] = {
381}; 381};
382 382
383/* MSI DIGIVOX mini II V3.0 */ 383/* MSI DIGIVOX mini II V3.0 */
384static struct dvb_usb_rc_key af9015_rc_keys_msi[] = { 384static struct dvb_usb_rc_key ir_codes_af9015_table_msi[] = {
385 { 0x001e, KEY_1 }, 385 { 0x001e, KEY_1 },
386 { 0x001f, KEY_2 }, 386 { 0x001f, KEY_2 },
387 { 0x0020, KEY_3 }, 387 { 0x0020, KEY_3 },
@@ -424,7 +424,7 @@ static u8 af9015_ir_table_msi[] = {
424}; 424};
425 425
426/* MYGICTV U718 */ 426/* MYGICTV U718 */
427static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = { 427static struct dvb_usb_rc_key ir_codes_af9015_table_mygictv[] = {
428 { 0x003d, KEY_SWITCHVIDEOMODE }, 428 { 0x003d, KEY_SWITCHVIDEOMODE },
429 /* TV / AV */ 429 /* TV / AV */
430 { 0x0545, KEY_POWER }, 430 { 0x0545, KEY_POWER },
@@ -550,7 +550,7 @@ static u8 af9015_ir_table_kworld[] = {
550}; 550};
551 551
552/* AverMedia Volar X */ 552/* AverMedia Volar X */
553static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = { 553static struct dvb_usb_rc_key ir_codes_af9015_table_avermedia[] = {
554 { 0x053d, KEY_PROG1 }, /* SOURCE */ 554 { 0x053d, KEY_PROG1 }, /* SOURCE */
555 { 0x0512, KEY_POWER }, /* POWER */ 555 { 0x0512, KEY_POWER }, /* POWER */
556 { 0x051e, KEY_1 }, /* 1 */ 556 { 0x051e, KEY_1 }, /* 1 */
@@ -656,7 +656,7 @@ static u8 af9015_ir_table_avermedia_ks[] = {
656}; 656};
657 657
658/* Digittrade DVB-T USB Stick */ 658/* Digittrade DVB-T USB Stick */
659static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = { 659static struct dvb_usb_rc_key ir_codes_af9015_table_digittrade[] = {
660 { 0x010f, KEY_LAST }, /* RETURN */ 660 { 0x010f, KEY_LAST }, /* RETURN */
661 { 0x0517, KEY_TEXT }, /* TELETEXT */ 661 { 0x0517, KEY_TEXT }, /* TELETEXT */
662 { 0x0108, KEY_EPG }, /* EPG */ 662 { 0x0108, KEY_EPG }, /* EPG */
@@ -719,7 +719,7 @@ static u8 af9015_ir_table_digittrade[] = {
719}; 719};
720 720
721/* TREKSTOR DVB-T USB Stick */ 721/* TREKSTOR DVB-T USB Stick */
722static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = { 722static struct dvb_usb_rc_key ir_codes_af9015_table_trekstor[] = {
723 { 0x0704, KEY_AGAIN }, /* Home */ 723 { 0x0704, KEY_AGAIN }, /* Home */
724 { 0x0705, KEY_MUTE }, /* Mute */ 724 { 0x0705, KEY_MUTE }, /* Mute */
725 { 0x0706, KEY_UP }, /* Up */ 725 { 0x0706, KEY_UP }, /* Up */
@@ -782,7 +782,7 @@ static u8 af9015_ir_table_trekstor[] = {
782}; 782};
783 783
784/* MSI DIGIVOX mini III */ 784/* MSI DIGIVOX mini III */
785static struct dvb_usb_rc_key af9015_rc_keys_msi_digivox_iii[] = { 785static struct dvb_usb_rc_key ir_codes_af9015_table_msi_digivox_iii[] = {
786 { 0x0713, KEY_POWER }, /* [red power button] */ 786 { 0x0713, KEY_POWER }, /* [red power button] */
787 { 0x073b, KEY_VIDEO }, /* Source */ 787 { 0x073b, KEY_VIDEO }, /* Source */
788 { 0x073e, KEY_ZOOM }, /* Zoom */ 788 { 0x073e, KEY_ZOOM }, /* Zoom */
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index bb69f3719f9a..faca1ad88a67 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -399,7 +399,7 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
399 return 0; 399 return 0;
400} 400}
401 401
402static struct dvb_usb_rc_key anysee_rc_keys[] = { 402static struct dvb_usb_rc_key ir_codes_anysee_table[] = {
403 { 0x0100, KEY_0 }, 403 { 0x0100, KEY_0 },
404 { 0x0101, KEY_1 }, 404 { 0x0101, KEY_1 },
405 { 0x0102, KEY_2 }, 405 { 0x0102, KEY_2 },
@@ -518,8 +518,8 @@ static struct dvb_usb_device_properties anysee_properties = {
518 } 518 }
519 }, 519 },
520 520
521 .rc_key_map = anysee_rc_keys, 521 .rc_key_map = ir_codes_anysee_table,
522 .rc_key_map_size = ARRAY_SIZE(anysee_rc_keys), 522 .rc_key_map_size = ARRAY_SIZE(ir_codes_anysee_table),
523 .rc_query = anysee_rc_query, 523 .rc_query = anysee_rc_query,
524 .rc_interval = 200, /* windows driver uses 500ms */ 524 .rc_interval = 200, /* windows driver uses 500ms */
525 525
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c
index d7290b2c0913..6681ac1c56e3 100644
--- a/drivers/media/dvb/dvb-usb/az6027.c
+++ b/drivers/media/dvb/dvb-usb/az6027.c
@@ -125,12 +125,12 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
125 { STB0899_RCOMPC , 0xc9 }, 125 { STB0899_RCOMPC , 0xc9 },
126 { STB0899_AGC1CN , 0x01 }, 126 { STB0899_AGC1CN , 0x01 },
127 { STB0899_AGC1REF , 0x10 }, 127 { STB0899_AGC1REF , 0x10 },
128 { STB0899_RTC , 0x23 }, 128 { STB0899_RTC , 0x23 },
129 { STB0899_TMGCFG , 0x4e }, 129 { STB0899_TMGCFG , 0x4e },
130 { STB0899_AGC2REF , 0x34 }, 130 { STB0899_AGC2REF , 0x34 },
131 { STB0899_TLSR , 0x84 }, 131 { STB0899_TLSR , 0x84 },
132 { STB0899_CFD , 0xf7 }, 132 { STB0899_CFD , 0xf7 },
133 { STB0899_ACLC , 0x87 }, 133 { STB0899_ACLC , 0x87 },
134 { STB0899_BCLC , 0x94 }, 134 { STB0899_BCLC , 0x94 },
135 { STB0899_EQON , 0x41 }, 135 { STB0899_EQON , 0x41 },
136 { STB0899_LDT , 0xf1 }, 136 { STB0899_LDT , 0xf1 },
@@ -183,10 +183,10 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
183 { STB0899_ECNT3M , 0x0a }, 183 { STB0899_ECNT3M , 0x0a },
184 { STB0899_ECNT3L , 0xad }, 184 { STB0899_ECNT3L , 0xad },
185 { STB0899_FECAUTO1 , 0x06 }, 185 { STB0899_FECAUTO1 , 0x06 },
186 { STB0899_FECM , 0x01 }, 186 { STB0899_FECM , 0x01 },
187 { STB0899_VTH12 , 0xb0 }, 187 { STB0899_VTH12 , 0xb0 },
188 { STB0899_VTH23 , 0x7a }, 188 { STB0899_VTH23 , 0x7a },
189 { STB0899_VTH34 , 0x58 }, 189 { STB0899_VTH34 , 0x58 },
190 { STB0899_VTH56 , 0x38 }, 190 { STB0899_VTH56 , 0x38 },
191 { STB0899_VTH67 , 0x34 }, 191 { STB0899_VTH67 , 0x34 },
192 { STB0899_VTH78 , 0x24 }, 192 { STB0899_VTH78 , 0x24 },
@@ -195,7 +195,7 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
195 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ 195 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
196 { STB0899_TSULC , 0x42 }, 196 { STB0899_TSULC , 0x42 },
197 { STB0899_RSLLC , 0x41 }, 197 { STB0899_RSLLC , 0x41 },
198 { STB0899_TSLPL , 0x12 }, 198 { STB0899_TSLPL , 0x12 },
199 { STB0899_TSCFGH , 0x0c }, 199 { STB0899_TSCFGH , 0x0c },
200 { STB0899_TSCFGM , 0x00 }, 200 { STB0899_TSCFGM , 0x00 },
201 { STB0899_TSCFGL , 0x00 }, 201 { STB0899_TSCFGL , 0x00 },
@@ -386,7 +386,7 @@ static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
386} 386}
387 387
388/* keys for the enclosed remote control */ 388/* keys for the enclosed remote control */
389static struct dvb_usb_rc_key az6027_rc_keys[] = { 389static struct dvb_usb_rc_key ir_codes_az6027_table[] = {
390 { 0x01, KEY_1 }, 390 { 0x01, KEY_1 },
391 { 0x02, KEY_2 }, 391 { 0x02, KEY_2 },
392}; 392};
@@ -417,11 +417,15 @@ static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
417 u16 value; 417 u16 value;
418 u16 index; 418 u16 index;
419 int blen; 419 int blen;
420 u8 b[12]; 420 u8 *b;
421 421
422 if (slot != 0) 422 if (slot != 0)
423 return -EINVAL; 423 return -EINVAL;
424 424
425 b = kmalloc(12, GFP_KERNEL);
426 if (!b)
427 return -ENOMEM;
428
425 mutex_lock(&state->ca_mutex); 429 mutex_lock(&state->ca_mutex);
426 430
427 req = 0xC1; 431 req = 0xC1;
@@ -438,6 +442,7 @@ static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
438 } 442 }
439 443
440 mutex_unlock(&state->ca_mutex); 444 mutex_unlock(&state->ca_mutex);
445 kfree(b);
441 return ret; 446 return ret;
442} 447}
443 448
@@ -485,11 +490,15 @@ static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
485 u16 value; 490 u16 value;
486 u16 index; 491 u16 index;
487 int blen; 492 int blen;
488 u8 b[12]; 493 u8 *b;
489 494
490 if (slot != 0) 495 if (slot != 0)
491 return -EINVAL; 496 return -EINVAL;
492 497
498 b = kmalloc(12, GFP_KERNEL);
499 if (!b)
500 return -ENOMEM;
501
493 mutex_lock(&state->ca_mutex); 502 mutex_lock(&state->ca_mutex);
494 503
495 req = 0xC3; 504 req = 0xC3;
@@ -510,6 +519,7 @@ static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
510 } 519 }
511 520
512 mutex_unlock(&state->ca_mutex); 521 mutex_unlock(&state->ca_mutex);
522 kfree(b);
513 return ret; 523 return ret;
514} 524}
515 525
@@ -556,7 +566,11 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
556 u16 value; 566 u16 value;
557 u16 index; 567 u16 index;
558 int blen; 568 int blen;
559 u8 b[12]; 569 u8 *b;
570
571 b = kmalloc(12, GFP_KERNEL);
572 if (!b)
573 return -ENOMEM;
560 574
561 req = 0xC8; 575 req = 0xC8;
562 value = 0; 576 value = 0;
@@ -570,6 +584,7 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
570 } else{ 584 } else{
571 ret = b[0]; 585 ret = b[0];
572 } 586 }
587 kfree(b);
573 return ret; 588 return ret;
574} 589}
575 590
@@ -667,8 +682,11 @@ static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int o
667 u16 value; 682 u16 value;
668 u16 index; 683 u16 index;
669 int blen; 684 int blen;
670 u8 b[12]; 685 u8 *b;
671 686
687 b = kmalloc(12, GFP_KERNEL);
688 if (!b)
689 return -ENOMEM;
672 mutex_lock(&state->ca_mutex); 690 mutex_lock(&state->ca_mutex);
673 691
674 req = 0xC5; 692 req = 0xC5;
@@ -683,15 +701,13 @@ static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int o
683 } else 701 } else
684 ret = 0; 702 ret = 0;
685 703
686 if (b[0] == 0) { 704 if (!ret && b[0] == 1) {
687 ret = 0;
688
689 } else if (b[0] == 1) {
690 ret = DVB_CA_EN50221_POLL_CAM_PRESENT | 705 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
691 DVB_CA_EN50221_POLL_CAM_READY; 706 DVB_CA_EN50221_POLL_CAM_READY;
692 } 707 }
693 708
694 mutex_unlock(&state->ca_mutex); 709 mutex_unlock(&state->ca_mutex);
710 kfree(b);
695 return ret; 711 return ret;
696} 712}
697 713
@@ -943,10 +959,16 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
943 u16 value; 959 u16 value;
944 int length; 960 int length;
945 u8 req; 961 u8 req;
946 u8 data[256]; 962 u8 *data;
947 963
948 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 964 data = kmalloc(256, GFP_KERNEL);
965 if (!data)
966 return -ENOMEM;
967
968 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
969 kfree(data);
949 return -EAGAIN; 970 return -EAGAIN;
971 }
950 972
951 if (num > 2) 973 if (num > 2)
952 warn("more than 2 i2c messages at a time is not handled yet. TODO."); 974 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
@@ -976,17 +998,14 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
976 i++; 998 i++;
977 } else { 999 } else {
978 1000
979 if (msg[i].addr == 0xd0) { 1001 /* demod 16bit addr */
980 /* demod 16bit addr */ 1002 req = 0xBD;
981 req = 0xBD; 1003 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
982 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); 1004 value = msg[i].addr + (2 << 8);
983 value = msg[i].addr + (2 << 8); 1005 length = msg[i].len - 2;
984 length = msg[i].len - 2; 1006 len = msg[i].len - 2;
985 len = msg[i].len - 2; 1007 for (j = 0; j < len; j++)
986 for (j = 0; j < len; j++) 1008 data[j] = msg[i].buf[j + 2];
987 data[j] = msg[i].buf[j + 2];
988
989 }
990 az6027_usb_out_op(d, req, value, index, data, length); 1009 az6027_usb_out_op(d, req, value, index, data, length);
991 } 1010 }
992 } 1011 }
@@ -1019,6 +1038,7 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
1019 } 1038 }
1020 } 1039 }
1021 mutex_unlock(&d->i2c_mutex); 1040 mutex_unlock(&d->i2c_mutex);
1041 kfree(data);
1022 1042
1023 return i; 1043 return i;
1024} 1044}
@@ -1039,8 +1059,14 @@ int az6027_identify_state(struct usb_device *udev,
1039 struct dvb_usb_device_description **desc, 1059 struct dvb_usb_device_description **desc,
1040 int *cold) 1060 int *cold)
1041{ 1061{
1042 u8 b[16]; 1062 u8 *b;
1043 s16 ret = usb_control_msg(udev, 1063 s16 ret;
1064
1065 b = kmalloc(16, GFP_KERNEL);
1066 if (!b)
1067 return -ENOMEM;
1068
1069 ret = usb_control_msg(udev,
1044 usb_rcvctrlpipe(udev, 0), 1070 usb_rcvctrlpipe(udev, 0),
1045 0xb7, 1071 0xb7,
1046 USB_TYPE_VENDOR | USB_DIR_IN, 1072 USB_TYPE_VENDOR | USB_DIR_IN,
@@ -1051,7 +1077,7 @@ int az6027_identify_state(struct usb_device *udev,
1051 USB_CTRL_GET_TIMEOUT); 1077 USB_CTRL_GET_TIMEOUT);
1052 1078
1053 *cold = ret <= 0; 1079 *cold = ret <= 0;
1054 1080 kfree(b);
1055 deb_info("cold: %d\n", *cold); 1081 deb_info("cold: %d\n", *cold);
1056 return 0; 1082 return 0;
1057} 1083}
@@ -1059,8 +1085,10 @@ int az6027_identify_state(struct usb_device *udev,
1059 1085
1060static struct usb_device_id az6027_usb_table[] = { 1086static struct usb_device_id az6027_usb_table[] = {
1061 { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) }, 1087 { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
1062 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI) }, 1088 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V1) },
1063 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI) }, 1089 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V2) },
1090 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
1091 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
1064 { }, 1092 { },
1065}; 1093};
1066 1094
@@ -1097,18 +1125,34 @@ static struct dvb_usb_device_properties az6027_properties = {
1097 .power_ctrl = az6027_power_ctrl, 1125 .power_ctrl = az6027_power_ctrl,
1098 .read_mac_address = az6027_read_mac_addr, 1126 .read_mac_address = az6027_read_mac_addr,
1099 */ 1127 */
1100 .rc_key_map = az6027_rc_keys, 1128 .rc_key_map = ir_codes_az6027_table,
1101 .rc_key_map_size = ARRAY_SIZE(az6027_rc_keys), 1129 .rc_key_map_size = ARRAY_SIZE(ir_codes_az6027_table),
1102 .rc_interval = 400, 1130 .rc_interval = 400,
1103 .rc_query = az6027_rc_query, 1131 .rc_query = az6027_rc_query,
1104 .i2c_algo = &az6027_i2c_algo, 1132 .i2c_algo = &az6027_i2c_algo,
1105 1133
1106 .num_device_descs = 1, 1134 .num_device_descs = 5,
1107 .devices = { 1135 .devices = {
1108 { 1136 {
1109 .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)", 1137 .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
1110 .cold_ids = { &az6027_usb_table[0], NULL }, 1138 .cold_ids = { &az6027_usb_table[0], NULL },
1111 .warm_ids = { NULL }, 1139 .warm_ids = { NULL },
1140 }, {
1141 .name = "TERRATEC S7",
1142 .cold_ids = { &az6027_usb_table[1], NULL },
1143 .warm_ids = { NULL },
1144 }, {
1145 .name = "TERRATEC S7 MKII",
1146 .cold_ids = { &az6027_usb_table[2], NULL },
1147 .warm_ids = { NULL },
1148 }, {
1149 .name = "Technisat SkyStar USB 2 HD CI",
1150 .cold_ids = { &az6027_usb_table[3], NULL },
1151 .warm_ids = { NULL },
1152 }, {
1153 .name = "Technisat SkyStar USB 2 HD CI",
1154 .cold_ids = { &az6027_usb_table[4], NULL },
1155 .warm_ids = { NULL },
1112 }, 1156 },
1113 { NULL }, 1157 { NULL },
1114 } 1158 }
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
index e37ac4d48602..5a9c14bdc980 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -84,7 +84,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
84 return 0; 84 return 0;
85} 85}
86 86
87static struct dvb_usb_rc_key cinergyt2_rc_keys[] = { 87static struct dvb_usb_rc_key ir_codes_cinergyt2_table[] = {
88 { 0x0401, KEY_POWER }, 88 { 0x0401, KEY_POWER },
89 { 0x0402, KEY_1 }, 89 { 0x0402, KEY_1 },
90 { 0x0403, KEY_2 }, 90 { 0x0403, KEY_2 },
@@ -218,8 +218,8 @@ static struct dvb_usb_device_properties cinergyt2_properties = {
218 .power_ctrl = cinergyt2_power_ctrl, 218 .power_ctrl = cinergyt2_power_ctrl,
219 219
220 .rc_interval = 50, 220 .rc_interval = 50,
221 .rc_key_map = cinergyt2_rc_keys, 221 .rc_key_map = ir_codes_cinergyt2_table,
222 .rc_key_map_size = ARRAY_SIZE(cinergyt2_rc_keys), 222 .rc_key_map_size = ARRAY_SIZE(ir_codes_cinergyt2_table),
223 .rc_query = cinergyt2_rc_query, 223 .rc_query = cinergyt2_rc_query,
224 224
225 .generic_bulk_ctrl_endpoint = 1, 225 .generic_bulk_ctrl_endpoint = 1,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 960376da7d59..0eb490889162 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -461,7 +461,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
461 return 0; 461 return 0;
462} 462}
463 463
464static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { 464static struct dvb_usb_rc_key ir_codes_dvico_mce_table[] = {
465 { 0xfe02, KEY_TV }, 465 { 0xfe02, KEY_TV },
466 { 0xfe0e, KEY_MP3 }, 466 { 0xfe0e, KEY_MP3 },
467 { 0xfe1a, KEY_DVD }, 467 { 0xfe1a, KEY_DVD },
@@ -509,7 +509,7 @@ static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
509 { 0xfe4e, KEY_POWER }, 509 { 0xfe4e, KEY_POWER },
510}; 510};
511 511
512static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { 512static struct dvb_usb_rc_key ir_codes_dvico_portable_table[] = {
513 { 0xfc02, KEY_SETUP }, /* Profile */ 513 { 0xfc02, KEY_SETUP }, /* Profile */
514 { 0xfc43, KEY_POWER2 }, 514 { 0xfc43, KEY_POWER2 },
515 { 0xfc06, KEY_EPG }, 515 { 0xfc06, KEY_EPG },
@@ -548,7 +548,7 @@ static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
548 { 0xfc00, KEY_UNKNOWN }, /* HD */ 548 { 0xfc00, KEY_UNKNOWN }, /* HD */
549}; 549};
550 550
551static struct dvb_usb_rc_key d680_dmb_rc_keys[] = { 551static struct dvb_usb_rc_key ir_codes_d680_dmb_table[] = {
552 { 0x0038, KEY_UNKNOWN }, /* TV/AV */ 552 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
553 { 0x080c, KEY_ZOOM }, 553 { 0x080c, KEY_ZOOM },
554 { 0x0800, KEY_0 }, 554 { 0x0800, KEY_0 },
@@ -1025,8 +1025,9 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1025 1025
1026 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); 1026 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1027 1027
1028 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 1028 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1029 &cxusb_dualdig4_rev2_config); 1029 &cxusb_dualdig4_rev2_config) < 0)
1030 return -ENODEV;
1030 1031
1031 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, 1032 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1032 &cxusb_dualdig4_rev2_config); 1033 &cxusb_dualdig4_rev2_config);
@@ -1449,8 +1450,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
1449 .i2c_algo = &cxusb_i2c_algo, 1450 .i2c_algo = &cxusb_i2c_algo,
1450 1451
1451 .rc_interval = 100, 1452 .rc_interval = 100,
1452 .rc_key_map = dvico_portable_rc_keys, 1453 .rc_key_map = ir_codes_dvico_portable_table,
1453 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), 1454 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
1454 .rc_query = cxusb_rc_query, 1455 .rc_query = cxusb_rc_query,
1455 1456
1456 .generic_bulk_ctrl_endpoint = 0x01, 1457 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1500,8 +1501,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
1500 .i2c_algo = &cxusb_i2c_algo, 1501 .i2c_algo = &cxusb_i2c_algo,
1501 1502
1502 .rc_interval = 150, 1503 .rc_interval = 150,
1503 .rc_key_map = dvico_mce_rc_keys, 1504 .rc_key_map = ir_codes_dvico_mce_table,
1504 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), 1505 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
1505 .rc_query = cxusb_rc_query, 1506 .rc_query = cxusb_rc_query,
1506 1507
1507 .generic_bulk_ctrl_endpoint = 0x01, 1508 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1559,8 +1560,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1559 .i2c_algo = &cxusb_i2c_algo, 1560 .i2c_algo = &cxusb_i2c_algo,
1560 1561
1561 .rc_interval = 100, 1562 .rc_interval = 100,
1562 .rc_key_map = dvico_portable_rc_keys, 1563 .rc_key_map = ir_codes_dvico_portable_table,
1563 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), 1564 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
1564 .rc_query = cxusb_rc_query, 1565 .rc_query = cxusb_rc_query,
1565 1566
1566 .generic_bulk_ctrl_endpoint = 0x01, 1567 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1609,8 +1610,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1609 .i2c_algo = &cxusb_i2c_algo, 1610 .i2c_algo = &cxusb_i2c_algo,
1610 1611
1611 .rc_interval = 100, 1612 .rc_interval = 100,
1612 .rc_key_map = dvico_portable_rc_keys, 1613 .rc_key_map = ir_codes_dvico_portable_table,
1613 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), 1614 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
1614 .rc_query = cxusb_rc_query, 1615 .rc_query = cxusb_rc_query,
1615 1616
1616 .generic_bulk_ctrl_endpoint = 0x01, 1617 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1658,8 +1659,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1658 .generic_bulk_ctrl_endpoint = 0x01, 1659 .generic_bulk_ctrl_endpoint = 0x01,
1659 1660
1660 .rc_interval = 100, 1661 .rc_interval = 100,
1661 .rc_key_map = dvico_mce_rc_keys, 1662 .rc_key_map = ir_codes_dvico_mce_table,
1662 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), 1663 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
1663 .rc_query = cxusb_bluebird2_rc_query, 1664 .rc_query = cxusb_bluebird2_rc_query,
1664 1665
1665 .num_device_descs = 1, 1666 .num_device_descs = 1,
@@ -1706,8 +1707,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1706 .generic_bulk_ctrl_endpoint = 0x01, 1707 .generic_bulk_ctrl_endpoint = 0x01,
1707 1708
1708 .rc_interval = 100, 1709 .rc_interval = 100,
1709 .rc_key_map = dvico_portable_rc_keys, 1710 .rc_key_map = ir_codes_dvico_portable_table,
1710 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), 1711 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
1711 .rc_query = cxusb_bluebird2_rc_query, 1712 .rc_query = cxusb_bluebird2_rc_query,
1712 1713
1713 .num_device_descs = 1, 1714 .num_device_descs = 1,
@@ -1756,8 +1757,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
1756 .generic_bulk_ctrl_endpoint = 0x01, 1757 .generic_bulk_ctrl_endpoint = 0x01,
1757 1758
1758 .rc_interval = 100, 1759 .rc_interval = 100,
1759 .rc_key_map = dvico_portable_rc_keys, 1760 .rc_key_map = ir_codes_dvico_portable_table,
1760 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), 1761 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
1761 .rc_query = cxusb_rc_query, 1762 .rc_query = cxusb_rc_query,
1762 1763
1763 .num_device_descs = 1, 1764 .num_device_descs = 1,
@@ -1847,8 +1848,8 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1847 .generic_bulk_ctrl_endpoint = 0x01, 1848 .generic_bulk_ctrl_endpoint = 0x01,
1848 1849
1849 .rc_interval = 100, 1850 .rc_interval = 100,
1850 .rc_key_map = dvico_mce_rc_keys, 1851 .rc_key_map = ir_codes_dvico_mce_table,
1851 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), 1852 .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
1852 .rc_query = cxusb_rc_query, 1853 .rc_query = cxusb_rc_query,
1853 1854
1854 .num_device_descs = 1, 1855 .num_device_descs = 1,
@@ -1895,8 +1896,8 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1895 .generic_bulk_ctrl_endpoint = 0x01, 1896 .generic_bulk_ctrl_endpoint = 0x01,
1896 1897
1897 .rc_interval = 100, 1898 .rc_interval = 100,
1898 .rc_key_map = d680_dmb_rc_keys, 1899 .rc_key_map = ir_codes_d680_dmb_table,
1899 .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys), 1900 .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
1900 .rc_query = cxusb_d680_dmb_rc_query, 1901 .rc_query = cxusb_d680_dmb_rc_query,
1901 1902
1902 .num_device_descs = 1, 1903 .num_device_descs = 1,
@@ -1944,8 +1945,8 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
1944 .generic_bulk_ctrl_endpoint = 0x01, 1945 .generic_bulk_ctrl_endpoint = 0x01,
1945 1946
1946 .rc_interval = 100, 1947 .rc_interval = 100,
1947 .rc_key_map = d680_dmb_rc_keys, 1948 .rc_key_map = ir_codes_d680_dmb_table,
1948 .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys), 1949 .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
1949 .rc_query = cxusb_d680_dmb_rc_query, 1950 .rc_query = cxusb_d680_dmb_rc_query,
1950 1951
1951 .num_device_descs = 1, 1952 .num_device_descs = 1,
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 34eab05afc6c..800800a9649e 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -562,7 +562,7 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
562 return 0; 562 return 0;
563} 563}
564 564
565static struct dvb_usb_rc_key dib0700_rc_keys[] = { 565static struct dvb_usb_rc_key ir_codes_dib0700_table[] = {
566 /* Key codes for the tiny Pinnacle remote*/ 566 /* Key codes for the tiny Pinnacle remote*/
567 { 0x0700, KEY_MUTE }, 567 { 0x0700, KEY_MUTE },
568 { 0x0701, KEY_MENU }, /* Pinnacle logo */ 568 { 0x0701, KEY_MENU }, /* Pinnacle logo */
@@ -794,6 +794,43 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
794 { 0x7a13, KEY_VOLUMEDOWN }, 794 { 0x7a13, KEY_VOLUMEDOWN },
795 { 0x7a40, KEY_POWER }, 795 { 0x7a40, KEY_POWER },
796 { 0x7a41, KEY_MUTE }, 796 { 0x7a41, KEY_MUTE },
797
798 /* Key codes for the Elgato EyeTV Diversity silver remote,
799 set dvb_usb_dib0700_ir_proto=0 */
800 { 0x4501, KEY_POWER },
801 { 0x4502, KEY_MUTE },
802 { 0x4503, KEY_1 },
803 { 0x4504, KEY_2 },
804 { 0x4505, KEY_3 },
805 { 0x4506, KEY_4 },
806 { 0x4507, KEY_5 },
807 { 0x4508, KEY_6 },
808 { 0x4509, KEY_7 },
809 { 0x450a, KEY_8 },
810 { 0x450b, KEY_9 },
811 { 0x450c, KEY_LAST },
812 { 0x450d, KEY_0 },
813 { 0x450e, KEY_ENTER },
814 { 0x450f, KEY_RED },
815 { 0x4510, KEY_CHANNELUP },
816 { 0x4511, KEY_GREEN },
817 { 0x4512, KEY_VOLUMEDOWN },
818 { 0x4513, KEY_OK },
819 { 0x4514, KEY_VOLUMEUP },
820 { 0x4515, KEY_YELLOW },
821 { 0x4516, KEY_CHANNELDOWN },
822 { 0x4517, KEY_BLUE },
823 { 0x4518, KEY_LEFT }, /* Skip backwards */
824 { 0x4519, KEY_PLAYPAUSE },
825 { 0x451a, KEY_RIGHT }, /* Skip forward */
826 { 0x451b, KEY_REWIND },
827 { 0x451c, KEY_L }, /* Live */
828 { 0x451d, KEY_FASTFORWARD },
829 { 0x451e, KEY_STOP }, /* 'Reveal' for Teletext */
830 { 0x451f, KEY_MENU }, /* KEY_TEXT for Teletext */
831 { 0x4540, KEY_RECORD }, /* Font 'Size' for Teletext */
832 { 0x4541, KEY_SCREEN }, /* Full screen toggle, 'Hold' for Teletext */
833 { 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */
797}; 834};
798 835
799/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ 836/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -2049,6 +2086,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
2049/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, 2086/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
2050 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, 2087 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
2051 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, 2088 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
2089 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
2052 { 0 } /* Terminating entry */ 2090 { 0 } /* Terminating entry */
2053}; 2091};
2054MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 2092MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -2131,8 +2169,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2131 }, 2169 },
2132 2170
2133 .rc_interval = DEFAULT_RC_INTERVAL, 2171 .rc_interval = DEFAULT_RC_INTERVAL,
2134 .rc_key_map = dib0700_rc_keys, 2172 .rc_key_map = ir_codes_dib0700_table,
2135 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2173 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2136 .rc_query = dib0700_rc_query 2174 .rc_query = dib0700_rc_query
2137 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2175 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2138 2176
@@ -2160,8 +2198,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2160 }, 2198 },
2161 2199
2162 .rc_interval = DEFAULT_RC_INTERVAL, 2200 .rc_interval = DEFAULT_RC_INTERVAL,
2163 .rc_key_map = dib0700_rc_keys, 2201 .rc_key_map = ir_codes_dib0700_table,
2164 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2202 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2165 .rc_query = dib0700_rc_query 2203 .rc_query = dib0700_rc_query
2166 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2204 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2167 2205
@@ -2214,8 +2252,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2214 }, 2252 },
2215 2253
2216 .rc_interval = DEFAULT_RC_INTERVAL, 2254 .rc_interval = DEFAULT_RC_INTERVAL,
2217 .rc_key_map = dib0700_rc_keys, 2255 .rc_key_map = ir_codes_dib0700_table,
2218 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2256 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2219 .rc_query = dib0700_rc_query 2257 .rc_query = dib0700_rc_query
2220 2258
2221 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2259 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2251,8 +2289,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2251 }, 2289 },
2252 2290
2253 .rc_interval = DEFAULT_RC_INTERVAL, 2291 .rc_interval = DEFAULT_RC_INTERVAL,
2254 .rc_key_map = dib0700_rc_keys, 2292 .rc_key_map = ir_codes_dib0700_table,
2255 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2293 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2256 .rc_query = dib0700_rc_query 2294 .rc_query = dib0700_rc_query
2257 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2295 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2258 2296
@@ -2321,8 +2359,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2321 }, 2359 },
2322 2360
2323 .rc_interval = DEFAULT_RC_INTERVAL, 2361 .rc_interval = DEFAULT_RC_INTERVAL,
2324 .rc_key_map = dib0700_rc_keys, 2362 .rc_key_map = ir_codes_dib0700_table,
2325 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2363 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2326 .rc_query = dib0700_rc_query 2364 .rc_query = dib0700_rc_query
2327 2365
2328 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2366 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2360,8 +2398,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2360 }, 2398 },
2361 2399
2362 .rc_interval = DEFAULT_RC_INTERVAL, 2400 .rc_interval = DEFAULT_RC_INTERVAL,
2363 .rc_key_map = dib0700_rc_keys, 2401 .rc_key_map = ir_codes_dib0700_table,
2364 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2402 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2365 .rc_query = dib0700_rc_query 2403 .rc_query = dib0700_rc_query
2366 2404
2367 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2405 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2393,7 +2431,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2393 } 2431 }
2394 }, 2432 },
2395 2433
2396 .num_device_descs = 6, 2434 .num_device_descs = 7,
2397 .devices = { 2435 .devices = {
2398 { "DiBcom STK7070PD reference design", 2436 { "DiBcom STK7070PD reference design",
2399 { &dib0700_usb_id_table[17], NULL }, 2437 { &dib0700_usb_id_table[17], NULL },
@@ -2419,11 +2457,15 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2419 { "Sony PlayTV", 2457 { "Sony PlayTV",
2420 { &dib0700_usb_id_table[44], NULL }, 2458 { &dib0700_usb_id_table[44], NULL },
2421 { NULL }, 2459 { NULL },
2422 } 2460 },
2461 { "Elgato EyeTV Diversity",
2462 { &dib0700_usb_id_table[68], NULL },
2463 { NULL },
2464 },
2423 }, 2465 },
2424 .rc_interval = DEFAULT_RC_INTERVAL, 2466 .rc_interval = DEFAULT_RC_INTERVAL,
2425 .rc_key_map = dib0700_rc_keys, 2467 .rc_key_map = ir_codes_dib0700_table,
2426 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2468 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2427 .rc_query = dib0700_rc_query 2469 .rc_query = dib0700_rc_query
2428 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2470 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2429 2471
@@ -2484,8 +2526,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2484 }, 2526 },
2485 }, 2527 },
2486 .rc_interval = DEFAULT_RC_INTERVAL, 2528 .rc_interval = DEFAULT_RC_INTERVAL,
2487 .rc_key_map = dib0700_rc_keys, 2529 .rc_key_map = ir_codes_dib0700_table,
2488 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2530 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2489 .rc_query = dib0700_rc_query 2531 .rc_query = dib0700_rc_query
2490 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2532 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2491 .num_adapters = 1, 2533 .num_adapters = 1,
@@ -2513,8 +2555,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2513 }, 2555 },
2514 }, 2556 },
2515 .rc_interval = DEFAULT_RC_INTERVAL, 2557 .rc_interval = DEFAULT_RC_INTERVAL,
2516 .rc_key_map = dib0700_rc_keys, 2558 .rc_key_map = ir_codes_dib0700_table,
2517 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2559 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2518 .rc_query = dib0700_rc_query 2560 .rc_query = dib0700_rc_query
2519 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2561 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2520 .num_adapters = 1, 2562 .num_adapters = 1,
@@ -2574,8 +2616,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2574 }, 2616 },
2575 }, 2617 },
2576 .rc_interval = DEFAULT_RC_INTERVAL, 2618 .rc_interval = DEFAULT_RC_INTERVAL,
2577 .rc_key_map = dib0700_rc_keys, 2619 .rc_key_map = ir_codes_dib0700_table,
2578 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2620 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2579 .rc_query = dib0700_rc_query 2621 .rc_query = dib0700_rc_query
2580 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2622 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2581 .num_adapters = 1, 2623 .num_adapters = 1,
@@ -2612,8 +2654,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2612 }, 2654 },
2613 2655
2614 .rc_interval = DEFAULT_RC_INTERVAL, 2656 .rc_interval = DEFAULT_RC_INTERVAL,
2615 .rc_key_map = dib0700_rc_keys, 2657 .rc_key_map = ir_codes_dib0700_table,
2616 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2658 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2617 .rc_query = dib0700_rc_query 2659 .rc_query = dib0700_rc_query
2618 2660
2619 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2661 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2656,8 +2698,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2656 }, 2698 },
2657 2699
2658 .rc_interval = DEFAULT_RC_INTERVAL, 2700 .rc_interval = DEFAULT_RC_INTERVAL,
2659 .rc_key_map = dib0700_rc_keys, 2701 .rc_key_map = ir_codes_dib0700_table,
2660 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2702 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2661 .rc_query = dib0700_rc_query 2703 .rc_query = dib0700_rc_query
2662 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2704 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2663 .num_adapters = 1, 2705 .num_adapters = 1,
@@ -2687,8 +2729,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2687 }, 2729 },
2688 2730
2689 .rc_interval = DEFAULT_RC_INTERVAL, 2731 .rc_interval = DEFAULT_RC_INTERVAL,
2690 .rc_key_map = dib0700_rc_keys, 2732 .rc_key_map = ir_codes_dib0700_table,
2691 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), 2733 .rc_key_map_size = ARRAY_SIZE(ir_codes_dib0700_table),
2692 .rc_query = dib0700_rc_query 2734 .rc_query = dib0700_rc_query
2693 }, 2735 },
2694}; 2736};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 9143b5631e88..bc08bc0b723c 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -327,7 +327,7 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
327/* 327/*
328 * common remote control stuff 328 * common remote control stuff
329 */ 329 */
330struct dvb_usb_rc_key dibusb_rc_keys[] = { 330struct dvb_usb_rc_key ir_codes_dibusb_table[] = {
331 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ 331 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
332 { 0x0016, KEY_POWER }, 332 { 0x0016, KEY_POWER },
333 { 0x0010, KEY_MUTE }, 333 { 0x0010, KEY_MUTE },
@@ -456,7 +456,7 @@ struct dvb_usb_rc_key dibusb_rc_keys[] = {
456 { 0x804e, KEY_ENTER }, 456 { 0x804e, KEY_ENTER },
457 { 0x804f, KEY_VOLUMEDOWN }, 457 { 0x804f, KEY_VOLUMEDOWN },
458}; 458};
459EXPORT_SYMBOL(dibusb_rc_keys); 459EXPORT_SYMBOL(ir_codes_dibusb_table);
460 460
461int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 461int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
462{ 462{
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 5c0126dc1ff9..eb2e6f050fbe 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -212,7 +212,7 @@ static struct dvb_usb_device_properties dibusb1_1_properties = {
212 .power_ctrl = dibusb_power_ctrl, 212 .power_ctrl = dibusb_power_ctrl,
213 213
214 .rc_interval = DEFAULT_RC_INTERVAL, 214 .rc_interval = DEFAULT_RC_INTERVAL,
215 .rc_key_map = dibusb_rc_keys, 215 .rc_key_map = ir_codes_dibusb_table,
216 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 216 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
217 .rc_query = dibusb_rc_query, 217 .rc_query = dibusb_rc_query,
218 218
@@ -296,7 +296,7 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
296 .power_ctrl = dibusb_power_ctrl, 296 .power_ctrl = dibusb_power_ctrl,
297 297
298 .rc_interval = DEFAULT_RC_INTERVAL, 298 .rc_interval = DEFAULT_RC_INTERVAL,
299 .rc_key_map = dibusb_rc_keys, 299 .rc_key_map = ir_codes_dibusb_table,
300 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 300 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
301 .rc_query = dibusb_rc_query, 301 .rc_query = dibusb_rc_query,
302 302
@@ -360,7 +360,7 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = {
360 .power_ctrl = dibusb2_0_power_ctrl, 360 .power_ctrl = dibusb2_0_power_ctrl,
361 361
362 .rc_interval = DEFAULT_RC_INTERVAL, 362 .rc_interval = DEFAULT_RC_INTERVAL,
363 .rc_key_map = dibusb_rc_keys, 363 .rc_key_map = ir_codes_dibusb_table,
364 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 364 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
365 .rc_query = dibusb_rc_query, 365 .rc_query = dibusb_rc_query,
366 366
@@ -417,7 +417,7 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = {
417 .power_ctrl = dibusb2_0_power_ctrl, 417 .power_ctrl = dibusb2_0_power_ctrl,
418 418
419 .rc_interval = DEFAULT_RC_INTERVAL, 419 .rc_interval = DEFAULT_RC_INTERVAL,
420 .rc_key_map = dibusb_rc_keys, 420 .rc_key_map = ir_codes_dibusb_table,
421 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 421 .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
422 .rc_query = dibusb_rc_query, 422 .rc_query = dibusb_rc_query,
423 423
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index a05b9f875663..588308eb6638 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -82,7 +82,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
82 .power_ctrl = dibusb2_0_power_ctrl, 82 .power_ctrl = dibusb2_0_power_ctrl,
83 83
84 .rc_interval = DEFAULT_RC_INTERVAL, 84 .rc_interval = DEFAULT_RC_INTERVAL,
85 .rc_key_map = dibusb_rc_keys, 85 .rc_key_map = ir_codes_dibusb_table,
86 .rc_key_map_size = 111, /* FIXME */ 86 .rc_key_map_size = 111, /* FIXME */
87 .rc_query = dibusb_rc_query, 87 .rc_query = dibusb_rc_query,
88 88
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 8e847aa73ba1..3d50ac59088f 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -124,7 +124,7 @@ extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
124#define DEFAULT_RC_INTERVAL 150 124#define DEFAULT_RC_INTERVAL 150
125//#define DEFAULT_RC_INTERVAL 100000 125//#define DEFAULT_RC_INTERVAL 100000
126 126
127extern struct dvb_usb_rc_key dibusb_rc_keys[]; 127extern struct dvb_usb_rc_key ir_codes_dibusb_table[];
128extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *); 128extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
129extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *); 129extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
130 130
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 955147d00756..e826077094fa 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -161,7 +161,7 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
161 return 0; 161 return 0;
162} 162}
163 163
164static struct dvb_usb_rc_key digitv_rc_keys[] = { 164static struct dvb_usb_rc_key ir_codes_digitv_table[] = {
165 { 0x5f55, KEY_0 }, 165 { 0x5f55, KEY_0 },
166 { 0x6f55, KEY_1 }, 166 { 0x6f55, KEY_1 },
167 { 0x9f55, KEY_2 }, 167 { 0x9f55, KEY_2 },
@@ -311,8 +311,8 @@ static struct dvb_usb_device_properties digitv_properties = {
311 .identify_state = digitv_identify_state, 311 .identify_state = digitv_identify_state,
312 312
313 .rc_interval = 1000, 313 .rc_interval = 1000,
314 .rc_key_map = digitv_rc_keys, 314 .rc_key_map = ir_codes_digitv_table,
315 .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys), 315 .rc_key_map_size = ARRAY_SIZE(ir_codes_digitv_table),
316 .rc_query = digitv_rc_query, 316 .rc_query = digitv_rc_query,
317 317
318 .i2c_algo = &digitv_i2c_algo, 318 .i2c_algo = &digitv_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index a1b12b01cbe4..f57e59044d4d 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -57,7 +57,7 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
57 57
58/* remote control */ 58/* remote control */
59/* key list for the tiny remote control (Yakumo, don't know about the others) */ 59/* key list for the tiny remote control (Yakumo, don't know about the others) */
60static struct dvb_usb_rc_key dtt200u_rc_keys[] = { 60static struct dvb_usb_rc_key ir_codes_dtt200u_table[] = {
61 { 0x8001, KEY_MUTE }, 61 { 0x8001, KEY_MUTE },
62 { 0x8002, KEY_CHANNELDOWN }, 62 { 0x8002, KEY_CHANNELDOWN },
63 { 0x8003, KEY_VOLUMEDOWN }, 63 { 0x8003, KEY_VOLUMEDOWN },
@@ -162,8 +162,8 @@ static struct dvb_usb_device_properties dtt200u_properties = {
162 .power_ctrl = dtt200u_power_ctrl, 162 .power_ctrl = dtt200u_power_ctrl,
163 163
164 .rc_interval = 300, 164 .rc_interval = 300,
165 .rc_key_map = dtt200u_rc_keys, 165 .rc_key_map = ir_codes_dtt200u_table,
166 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 166 .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
167 .rc_query = dtt200u_rc_query, 167 .rc_query = dtt200u_rc_query,
168 168
169 .generic_bulk_ctrl_endpoint = 0x01, 169 .generic_bulk_ctrl_endpoint = 0x01,
@@ -207,8 +207,8 @@ static struct dvb_usb_device_properties wt220u_properties = {
207 .power_ctrl = dtt200u_power_ctrl, 207 .power_ctrl = dtt200u_power_ctrl,
208 208
209 .rc_interval = 300, 209 .rc_interval = 300,
210 .rc_key_map = dtt200u_rc_keys, 210 .rc_key_map = ir_codes_dtt200u_table,
211 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 211 .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
212 .rc_query = dtt200u_rc_query, 212 .rc_query = dtt200u_rc_query,
213 213
214 .generic_bulk_ctrl_endpoint = 0x01, 214 .generic_bulk_ctrl_endpoint = 0x01,
@@ -252,8 +252,8 @@ static struct dvb_usb_device_properties wt220u_fc_properties = {
252 .power_ctrl = dtt200u_power_ctrl, 252 .power_ctrl = dtt200u_power_ctrl,
253 253
254 .rc_interval = 300, 254 .rc_interval = 300,
255 .rc_key_map = dtt200u_rc_keys, 255 .rc_key_map = ir_codes_dtt200u_table,
256 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 256 .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
257 .rc_query = dtt200u_rc_query, 257 .rc_query = dtt200u_rc_query,
258 258
259 .generic_bulk_ctrl_endpoint = 0x01, 259 .generic_bulk_ctrl_endpoint = 0x01,
@@ -297,8 +297,8 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
297 .power_ctrl = dtt200u_power_ctrl, 297 .power_ctrl = dtt200u_power_ctrl,
298 298
299 .rc_interval = 300, 299 .rc_interval = 300,
300 .rc_key_map = dtt200u_rc_keys, 300 .rc_key_map = ir_codes_dtt200u_table,
301 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 301 .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
302 .rc_query = dtt200u_rc_query, 302 .rc_query = dtt200u_rc_query,
303 303
304 .generic_bulk_ctrl_endpoint = 0x01, 304 .generic_bulk_ctrl_endpoint = 0x01,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index ae8b57acfe05..085c4e457e0e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -124,9 +124,11 @@
124#define USB_PID_KWORLD_395U 0xe396 124#define USB_PID_KWORLD_395U 0xe396
125#define USB_PID_KWORLD_395U_2 0xe39b 125#define USB_PID_KWORLD_395U_2 0xe39b
126#define USB_PID_KWORLD_395U_3 0xe395 126#define USB_PID_KWORLD_395U_3 0xe395
127#define USB_PID_KWORLD_395U_4 0xe39a
127#define USB_PID_KWORLD_MC810 0xc810 128#define USB_PID_KWORLD_MC810 0xc810
128#define USB_PID_KWORLD_PC160_2T 0xc160 129#define USB_PID_KWORLD_PC160_2T 0xc160
129#define USB_PID_KWORLD_PC160_T 0xc161 130#define USB_PID_KWORLD_PC160_T 0xc161
131#define USB_PID_KWORLD_UB383_T 0xe383
130#define USB_PID_KWORLD_VSTREAM_COLD 0x17de 132#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
131#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 133#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
132#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 134#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
@@ -288,6 +290,7 @@
288#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 290#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
289#define USB_PID_SONY_PLAYTV 0x0003 291#define USB_PID_SONY_PLAYTV 0x0003
290#define USB_PID_MYGICA_D689 0xd811 292#define USB_PID_MYGICA_D689 0xd811
293#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
291#define USB_PID_ELGATO_EYETV_DTT 0x0021 294#define USB_PID_ELGATO_EYETV_DTT 0x0021
292#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 295#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
293#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 296#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
@@ -296,6 +299,8 @@
296#define USB_PID_TVWAY_PLUS 0x0002 299#define USB_PID_TVWAY_PLUS 0x0002
297#define USB_PID_SVEON_STV20 0xe39d 300#define USB_PID_SVEON_STV20 0xe39d
298#define USB_PID_AZUREWAVE_AZ6027 0x3275 301#define USB_PID_AZUREWAVE_AZ6027 0x3275
299#define USB_PID_TERRATEC_DVBS2CI 0x3275 302#define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4
300#define USB_PID_TECHNISAT_USB2_HDCI 0x0002 303#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac
304#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001
305#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
301#endif 306#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index 6fe71c6745eb..bb46ba6a3573 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -42,6 +42,8 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
42 msleep(delay_ms); 42 msleep(delay_ms);
43 43
44 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev, 44 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
45 d->props.generic_bulk_ctrl_endpoint_response ?
46 d->props.generic_bulk_ctrl_endpoint_response :
45 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen, 47 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
46 2000); 48 2000);
47 49
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 0143aef19ecd..4a9f676087bf 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -198,6 +198,12 @@ struct dvb_usb_adapter_properties {
198 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write- 198 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
199 * helper functions. 199 * helper functions.
200 * 200 *
201 * @generic_bulk_ctrl_endpoint_response: some DVB USB devices use a separate
202 * endpoint for responses to control messages sent with bulk transfers via
203 * the generic_bulk_ctrl_endpoint. When this is non-zero, this will be used
204 * instead of the generic_bulk_ctrl_endpoint when reading usb responses in
205 * the dvb_usb_generic_rw helper function.
206 *
201 * @num_device_descs: number of struct dvb_usb_device_description in @devices 207 * @num_device_descs: number of struct dvb_usb_device_description in @devices
202 * @devices: array of struct dvb_usb_device_description compatibles with these 208 * @devices: array of struct dvb_usb_device_description compatibles with these
203 * properties. 209 * properties.
@@ -239,6 +245,7 @@ struct dvb_usb_device_properties {
239 struct i2c_algorithm *i2c_algo; 245 struct i2c_algorithm *i2c_algo;
240 246
241 int generic_bulk_ctrl_endpoint; 247 int generic_bulk_ctrl_endpoint;
248 int generic_bulk_ctrl_endpoint_response;
242 249
243 int num_device_descs; 250 int num_device_descs;
244 struct dvb_usb_device_description devices[12]; 251 struct dvb_usb_device_description devices[12];
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index accc65509b07..e8fb85380672 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -73,7 +73,7 @@
73 "Please see linux/Documentation/dvb/ for more details " \ 73 "Please see linux/Documentation/dvb/ for more details " \
74 "on firmware-problems." 74 "on firmware-problems."
75 75
76struct dvb_usb_rc_keys_table { 76struct ir_codes_dvb_usb_table_table {
77 struct dvb_usb_rc_key *rc_keys; 77 struct dvb_usb_rc_key *rc_keys;
78 int rc_keys_size; 78 int rc_keys_size;
79}; 79};
@@ -948,7 +948,7 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
948 return 0; 948 return 0;
949} 949}
950 950
951static struct dvb_usb_rc_key dw210x_rc_keys[] = { 951static struct dvb_usb_rc_key ir_codes_dw210x_table[] = {
952 { 0xf80a, KEY_Q }, /*power*/ 952 { 0xf80a, KEY_Q }, /*power*/
953 { 0xf80c, KEY_M }, /*mute*/ 953 { 0xf80c, KEY_M }, /*mute*/
954 { 0xf811, KEY_1 }, 954 { 0xf811, KEY_1 },
@@ -982,7 +982,7 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = {
982 { 0xf81b, KEY_B }, /*recall*/ 982 { 0xf81b, KEY_B }, /*recall*/
983}; 983};
984 984
985static struct dvb_usb_rc_key tevii_rc_keys[] = { 985static struct dvb_usb_rc_key ir_codes_tevii_table[] = {
986 { 0xf80a, KEY_POWER }, 986 { 0xf80a, KEY_POWER },
987 { 0xf80c, KEY_MUTE }, 987 { 0xf80c, KEY_MUTE },
988 { 0xf811, KEY_1 }, 988 { 0xf811, KEY_1 },
@@ -1032,7 +1032,7 @@ static struct dvb_usb_rc_key tevii_rc_keys[] = {
1032 { 0xf858, KEY_SWITCHVIDEOMODE }, 1032 { 0xf858, KEY_SWITCHVIDEOMODE },
1033}; 1033};
1034 1034
1035static struct dvb_usb_rc_key tbs_rc_keys[] = { 1035static struct dvb_usb_rc_key ir_codes_tbs_table[] = {
1036 { 0xf884, KEY_POWER }, 1036 { 0xf884, KEY_POWER },
1037 { 0xf894, KEY_MUTE }, 1037 { 0xf894, KEY_MUTE },
1038 { 0xf887, KEY_1 }, 1038 { 0xf887, KEY_1 },
@@ -1067,10 +1067,10 @@ static struct dvb_usb_rc_key tbs_rc_keys[] = {
1067 { 0xf89b, KEY_MODE } 1067 { 0xf89b, KEY_MODE }
1068}; 1068};
1069 1069
1070static struct dvb_usb_rc_keys_table keys_tables[] = { 1070static struct ir_codes_dvb_usb_table_table keys_tables[] = {
1071 { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) }, 1071 { ir_codes_dw210x_table, ARRAY_SIZE(ir_codes_dw210x_table) },
1072 { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) }, 1072 { ir_codes_tevii_table, ARRAY_SIZE(ir_codes_tevii_table) },
1073 { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) }, 1073 { ir_codes_tbs_table, ARRAY_SIZE(ir_codes_tbs_table) },
1074}; 1074};
1075 1075
1076static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 1076static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -1185,14 +1185,14 @@ static int dw2102_load_firmware(struct usb_device *dev,
1185 /* init registers */ 1185 /* init registers */
1186 switch (dev->descriptor.idProduct) { 1186 switch (dev->descriptor.idProduct) {
1187 case USB_PID_PROF_1100: 1187 case USB_PID_PROF_1100:
1188 s6x0_properties.rc_key_map = tbs_rc_keys; 1188 s6x0_properties.rc_key_map = ir_codes_tbs_table;
1189 s6x0_properties.rc_key_map_size = 1189 s6x0_properties.rc_key_map_size =
1190 ARRAY_SIZE(tbs_rc_keys); 1190 ARRAY_SIZE(ir_codes_tbs_table);
1191 break; 1191 break;
1192 case USB_PID_TEVII_S650: 1192 case USB_PID_TEVII_S650:
1193 dw2104_properties.rc_key_map = tevii_rc_keys; 1193 dw2104_properties.rc_key_map = ir_codes_tevii_table;
1194 dw2104_properties.rc_key_map_size = 1194 dw2104_properties.rc_key_map_size =
1195 ARRAY_SIZE(tevii_rc_keys); 1195 ARRAY_SIZE(ir_codes_tevii_table);
1196 case USB_PID_DW2104: 1196 case USB_PID_DW2104:
1197 reset = 1; 1197 reset = 1;
1198 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, 1198 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
@@ -1255,8 +1255,8 @@ static struct dvb_usb_device_properties dw2102_properties = {
1255 .no_reconnect = 1, 1255 .no_reconnect = 1,
1256 1256
1257 .i2c_algo = &dw2102_serit_i2c_algo, 1257 .i2c_algo = &dw2102_serit_i2c_algo,
1258 .rc_key_map = dw210x_rc_keys, 1258 .rc_key_map = ir_codes_dw210x_table,
1259 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), 1259 .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
1260 .rc_interval = 150, 1260 .rc_interval = 150,
1261 .rc_query = dw2102_rc_query, 1261 .rc_query = dw2102_rc_query,
1262 1262
@@ -1306,8 +1306,8 @@ static struct dvb_usb_device_properties dw2104_properties = {
1306 .no_reconnect = 1, 1306 .no_reconnect = 1,
1307 1307
1308 .i2c_algo = &dw2104_i2c_algo, 1308 .i2c_algo = &dw2104_i2c_algo,
1309 .rc_key_map = dw210x_rc_keys, 1309 .rc_key_map = ir_codes_dw210x_table,
1310 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), 1310 .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
1311 .rc_interval = 150, 1311 .rc_interval = 150,
1312 .rc_query = dw2102_rc_query, 1312 .rc_query = dw2102_rc_query,
1313 1313
@@ -1353,8 +1353,8 @@ static struct dvb_usb_device_properties dw3101_properties = {
1353 .no_reconnect = 1, 1353 .no_reconnect = 1,
1354 1354
1355 .i2c_algo = &dw3101_i2c_algo, 1355 .i2c_algo = &dw3101_i2c_algo,
1356 .rc_key_map = dw210x_rc_keys, 1356 .rc_key_map = ir_codes_dw210x_table,
1357 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), 1357 .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
1358 .rc_interval = 150, 1358 .rc_interval = 150,
1359 .rc_query = dw2102_rc_query, 1359 .rc_query = dw2102_rc_query,
1360 1360
@@ -1396,8 +1396,8 @@ static struct dvb_usb_device_properties s6x0_properties = {
1396 .no_reconnect = 1, 1396 .no_reconnect = 1,
1397 1397
1398 .i2c_algo = &s6x0_i2c_algo, 1398 .i2c_algo = &s6x0_i2c_algo,
1399 .rc_key_map = tevii_rc_keys, 1399 .rc_key_map = ir_codes_tevii_table,
1400 .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys), 1400 .rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table),
1401 .rc_interval = 150, 1401 .rc_interval = 150,
1402 .rc_query = dw2102_rc_query, 1402 .rc_query = dw2102_rc_query,
1403 1403
@@ -1459,8 +1459,8 @@ static int dw2102_probe(struct usb_interface *intf,
1459 /* fill only different fields */ 1459 /* fill only different fields */
1460 p7500->firmware = "dvb-usb-p7500.fw"; 1460 p7500->firmware = "dvb-usb-p7500.fw";
1461 p7500->devices[0] = d7500; 1461 p7500->devices[0] = d7500;
1462 p7500->rc_key_map = tbs_rc_keys; 1462 p7500->rc_key_map = ir_codes_tbs_table;
1463 p7500->rc_key_map_size = ARRAY_SIZE(tbs_rc_keys); 1463 p7500->rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table);
1464 p7500->adapter->frontend_attach = prof_7500_frontend_attach; 1464 p7500->adapter->frontend_attach = prof_7500_frontend_attach;
1465 1465
1466 if (0 == dvb_usb_device_init(intf, &dw2102_properties, 1466 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
index afb444db43ad..45106ac49674 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -105,6 +105,10 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
105 105
106 ptr = fw->data; 106 ptr = fw->data;
107 buf = kmalloc(64, GFP_KERNEL | GFP_DMA); 107 buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
108 if (!buf) {
109 ret = -ENOMEM;
110 goto out_rel_fw;
111 }
108 112
109 while (ptr[0] != 0xff) { 113 while (ptr[0] != 0xff) {
110 u16 buflen = ptr[0] + 4; 114 u16 buflen = ptr[0] + 4;
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index 737ffa36ac9c..c211fef45fc3 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -589,7 +589,7 @@ static struct m920x_inits pinnacle310e_init[] = {
589}; 589};
590 590
591/* ir keymaps */ 591/* ir keymaps */
592static struct dvb_usb_rc_key megasky_rc_keys [] = { 592static struct dvb_usb_rc_key ir_codes_megasky_table [] = {
593 { 0x0012, KEY_POWER }, 593 { 0x0012, KEY_POWER },
594 { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */ 594 { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
595 { 0x0002, KEY_CHANNELUP }, 595 { 0x0002, KEY_CHANNELUP },
@@ -608,7 +608,7 @@ static struct dvb_usb_rc_key megasky_rc_keys [] = {
608 { 0x000e, KEY_COFFEE }, /* "MTS" */ 608 { 0x000e, KEY_COFFEE }, /* "MTS" */
609}; 609};
610 610
611static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = { 611static struct dvb_usb_rc_key ir_codes_tvwalkertwin_table [] = {
612 { 0x0001, KEY_ZOOM }, /* Full Screen */ 612 { 0x0001, KEY_ZOOM }, /* Full Screen */
613 { 0x0002, KEY_CAMERA }, /* snapshot */ 613 { 0x0002, KEY_CAMERA }, /* snapshot */
614 { 0x0003, KEY_MUTE }, 614 { 0x0003, KEY_MUTE },
@@ -628,7 +628,7 @@ static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
628 { 0x001e, KEY_VOLUMEUP }, 628 { 0x001e, KEY_VOLUMEUP },
629}; 629};
630 630
631static struct dvb_usb_rc_key pinnacle310e_rc_keys[] = { 631static struct dvb_usb_rc_key ir_codes_pinnacle310e_table[] = {
632 { 0x16, KEY_POWER }, 632 { 0x16, KEY_POWER },
633 { 0x17, KEY_FAVORITES }, 633 { 0x17, KEY_FAVORITES },
634 { 0x0f, KEY_TEXT }, 634 { 0x0f, KEY_TEXT },
@@ -785,8 +785,8 @@ static struct dvb_usb_device_properties megasky_properties = {
785 .download_firmware = m920x_firmware_download, 785 .download_firmware = m920x_firmware_download,
786 786
787 .rc_interval = 100, 787 .rc_interval = 100,
788 .rc_key_map = megasky_rc_keys, 788 .rc_key_map = ir_codes_megasky_table,
789 .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), 789 .rc_key_map_size = ARRAY_SIZE(ir_codes_megasky_table),
790 .rc_query = m920x_rc_query, 790 .rc_query = m920x_rc_query,
791 791
792 .size_of_priv = sizeof(struct m920x_state), 792 .size_of_priv = sizeof(struct m920x_state),
@@ -886,8 +886,8 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = {
886 .download_firmware = m920x_firmware_download, 886 .download_firmware = m920x_firmware_download,
887 887
888 .rc_interval = 100, 888 .rc_interval = 100,
889 .rc_key_map = tvwalkertwin_rc_keys, 889 .rc_key_map = ir_codes_tvwalkertwin_table,
890 .rc_key_map_size = ARRAY_SIZE(tvwalkertwin_rc_keys), 890 .rc_key_map_size = ARRAY_SIZE(ir_codes_tvwalkertwin_table),
891 .rc_query = m920x_rc_query, 891 .rc_query = m920x_rc_query,
892 892
893 .size_of_priv = sizeof(struct m920x_state), 893 .size_of_priv = sizeof(struct m920x_state),
@@ -993,8 +993,8 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
993 .download_firmware = NULL, 993 .download_firmware = NULL,
994 994
995 .rc_interval = 100, 995 .rc_interval = 100,
996 .rc_key_map = pinnacle310e_rc_keys, 996 .rc_key_map = ir_codes_pinnacle310e_table,
997 .rc_key_map_size = ARRAY_SIZE(pinnacle310e_rc_keys), 997 .rc_key_map_size = ARRAY_SIZE(ir_codes_pinnacle310e_table),
998 .rc_query = m920x_rc_query, 998 .rc_query = m920x_rc_query,
999 999
1000 .size_of_priv = sizeof(struct m920x_state), 1000 .size_of_priv = sizeof(struct m920x_state),
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index b41d66ef8325..d195a587cc65 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -21,7 +21,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
21#define deb_ee(args...) dprintk(debug,0x02,args) 21#define deb_ee(args...) dprintk(debug,0x02,args)
22 22
23/* Hauppauge NOVA-T USB2 keys */ 23/* Hauppauge NOVA-T USB2 keys */
24static struct dvb_usb_rc_key haupp_rc_keys [] = { 24static struct dvb_usb_rc_key ir_codes_haupp_table [] = {
25 { 0x1e00, KEY_0 }, 25 { 0x1e00, KEY_0 },
26 { 0x1e01, KEY_1 }, 26 { 0x1e01, KEY_1 },
27 { 0x1e02, KEY_2 }, 27 { 0x1e02, KEY_2 },
@@ -91,14 +91,14 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
91 91
92 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle); 92 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
93 93
94 for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) { 94 for (i = 0; i < ARRAY_SIZE(ir_codes_haupp_table); i++) {
95 if (rc5_data(&haupp_rc_keys[i]) == data && 95 if (rc5_data(&ir_codes_haupp_table[i]) == data &&
96 rc5_custom(&haupp_rc_keys[i]) == custom) { 96 rc5_custom(&ir_codes_haupp_table[i]) == custom) {
97 97
98 deb_rc("c: %x, d: %x\n", rc5_data(&haupp_rc_keys[i]), 98 deb_rc("c: %x, d: %x\n", rc5_data(&ir_codes_haupp_table[i]),
99 rc5_custom(&haupp_rc_keys[i])); 99 rc5_custom(&ir_codes_haupp_table[i]));
100 100
101 *event = haupp_rc_keys[i].event; 101 *event = ir_codes_haupp_table[i].event;
102 *state = REMOTE_KEY_PRESSED; 102 *state = REMOTE_KEY_PRESSED;
103 if (st->old_toggle == toggle) { 103 if (st->old_toggle == toggle) {
104 if (st->last_repeat_count++ < 2) 104 if (st->last_repeat_count++ < 2)
@@ -196,8 +196,8 @@ static struct dvb_usb_device_properties nova_t_properties = {
196 .read_mac_address = nova_t_read_mac_address, 196 .read_mac_address = nova_t_read_mac_address,
197 197
198 .rc_interval = 100, 198 .rc_interval = 100,
199 .rc_key_map = haupp_rc_keys, 199 .rc_key_map = ir_codes_haupp_table,
200 .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys), 200 .rc_key_map_size = ARRAY_SIZE(ir_codes_haupp_table),
201 .rc_query = nova_t_rc_query, 201 .rc_query = nova_t_rc_query,
202 202
203 .i2c_algo = &dibusb_i2c_algo, 203 .i2c_algo = &dibusb_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 830557696ae6..dfb81ff1d9a7 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -35,7 +35,7 @@
35struct opera1_state { 35struct opera1_state {
36 u32 last_key_pressed; 36 u32 last_key_pressed;
37}; 37};
38struct opera_rc_keys { 38struct ir_codes_opera_table {
39 u32 keycode; 39 u32 keycode;
40 u32 event; 40 u32 event;
41}; 41};
@@ -331,7 +331,7 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
331 return 0; 331 return 0;
332} 332}
333 333
334static struct dvb_usb_rc_key opera1_rc_keys[] = { 334static struct dvb_usb_rc_key ir_codes_opera1_table[] = {
335 {0x5fa0, KEY_1}, 335 {0x5fa0, KEY_1},
336 {0x51af, KEY_2}, 336 {0x51af, KEY_2},
337 {0x5da2, KEY_3}, 337 {0x5da2, KEY_3},
@@ -404,12 +404,12 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
404 404
405 send_key = (send_key & 0xffff) | 0x0100; 405 send_key = (send_key & 0xffff) | 0x0100;
406 406
407 for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) { 407 for (i = 0; i < ARRAY_SIZE(ir_codes_opera1_table); i++) {
408 if (rc5_scan(&opera1_rc_keys[i]) == (send_key & 0xffff)) { 408 if (rc5_scan(&ir_codes_opera1_table[i]) == (send_key & 0xffff)) {
409 *state = REMOTE_KEY_PRESSED; 409 *state = REMOTE_KEY_PRESSED;
410 *event = opera1_rc_keys[i].event; 410 *event = ir_codes_opera1_table[i].event;
411 opst->last_key_pressed = 411 opst->last_key_pressed =
412 opera1_rc_keys[i].event; 412 ir_codes_opera1_table[i].event;
413 break; 413 break;
414 } 414 }
415 opst->last_key_pressed = 0; 415 opst->last_key_pressed = 0;
@@ -498,8 +498,8 @@ static struct dvb_usb_device_properties opera1_properties = {
498 .power_ctrl = opera1_power_ctrl, 498 .power_ctrl = opera1_power_ctrl,
499 .i2c_algo = &opera1_i2c_algo, 499 .i2c_algo = &opera1_i2c_algo,
500 500
501 .rc_key_map = opera1_rc_keys, 501 .rc_key_map = ir_codes_opera1_table,
502 .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys), 502 .rc_key_map_size = ARRAY_SIZE(ir_codes_opera1_table),
503 .rc_interval = 200, 503 .rc_interval = 200,
504 .rc_query = opera1_rc_query, 504 .rc_query = opera1_rc_query,
505 .read_mac_address = opera1_read_mac_address, 505 .read_mac_address = opera1_read_mac_address,
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index ef4e37d9c5ff..4d332451653b 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -174,7 +174,7 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
174} 174}
175 175
176/* keys for the enclosed remote control */ 176/* keys for the enclosed remote control */
177static struct dvb_usb_rc_key vp702x_rc_keys[] = { 177static struct dvb_usb_rc_key ir_codes_vp702x_table[] = {
178 { 0x0001, KEY_1 }, 178 { 0x0001, KEY_1 },
179 { 0x0002, KEY_2 }, 179 { 0x0002, KEY_2 },
180}; 180};
@@ -197,10 +197,10 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
197 return 0; 197 return 0;
198 } 198 }
199 199
200 for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++) 200 for (i = 0; i < ARRAY_SIZE(ir_codes_vp702x_table); i++)
201 if (rc5_custom(&vp702x_rc_keys[i]) == key[1]) { 201 if (rc5_custom(&ir_codes_vp702x_table[i]) == key[1]) {
202 *state = REMOTE_KEY_PRESSED; 202 *state = REMOTE_KEY_PRESSED;
203 *event = vp702x_rc_keys[i].event; 203 *event = ir_codes_vp702x_table[i].event;
204 break; 204 break;
205 } 205 }
206 return 0; 206 return 0;
@@ -283,8 +283,8 @@ static struct dvb_usb_device_properties vp702x_properties = {
283 }, 283 },
284 .read_mac_address = vp702x_read_mac_addr, 284 .read_mac_address = vp702x_read_mac_addr,
285 285
286 .rc_key_map = vp702x_rc_keys, 286 .rc_key_map = ir_codes_vp702x_table,
287 .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys), 287 .rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table),
288 .rc_interval = 400, 288 .rc_interval = 400,
289 .rc_query = vp702x_rc_query, 289 .rc_query = vp702x_rc_query,
290 290
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index a59faa27912a..036893fa4480 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -99,7 +99,7 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
99 99
100/* The keymapping struct. Somehow this should be loaded to the driver, but 100/* The keymapping struct. Somehow this should be loaded to the driver, but
101 * currently it is hardcoded. */ 101 * currently it is hardcoded. */
102static struct dvb_usb_rc_key vp7045_rc_keys[] = { 102static struct dvb_usb_rc_key ir_codes_vp7045_table[] = {
103 { 0x0016, KEY_POWER }, 103 { 0x0016, KEY_POWER },
104 { 0x0010, KEY_MUTE }, 104 { 0x0010, KEY_MUTE },
105 { 0x0003, KEY_1 }, 105 { 0x0003, KEY_1 },
@@ -165,10 +165,10 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
165 return 0; 165 return 0;
166 } 166 }
167 167
168 for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++) 168 for (i = 0; i < ARRAY_SIZE(ir_codes_vp7045_table); i++)
169 if (rc5_data(&vp7045_rc_keys[i]) == key) { 169 if (rc5_data(&ir_codes_vp7045_table[i]) == key) {
170 *state = REMOTE_KEY_PRESSED; 170 *state = REMOTE_KEY_PRESSED;
171 *event = vp7045_rc_keys[i].event; 171 *event = ir_codes_vp7045_table[i].event;
172 break; 172 break;
173 } 173 }
174 return 0; 174 return 0;
@@ -260,8 +260,8 @@ static struct dvb_usb_device_properties vp7045_properties = {
260 .read_mac_address = vp7045_read_mac_addr, 260 .read_mac_address = vp7045_read_mac_addr,
261 261
262 .rc_interval = 400, 262 .rc_interval = 400,
263 .rc_key_map = vp7045_rc_keys, 263 .rc_key_map = ir_codes_vp7045_table,
264 .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys), 264 .rc_key_map_size = ARRAY_SIZE(ir_codes_vp7045_table),
265 .rc_query = vp7045_rc_query, 265 .rc_query = vp7045_rc_query,
266 266
267 .num_device_descs = 2, 267 .num_device_descs = 2,
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 1b31bebc27d6..28294af752db 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -1096,7 +1096,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
1096 1096
1097 c->operand[15] = msg[1]; /* Program number */ 1097 c->operand[15] = msg[1]; /* Program number */
1098 c->operand[16] = msg[2]; 1098 c->operand[16] = msg[2];
1099 c->operand[17] = 0x01; /* Version number=0 + current/next=1 */ 1099 c->operand[17] = msg[3]; /* Version number and current/next */
1100 c->operand[18] = 0x00; /* Section number=0 */ 1100 c->operand[18] = 0x00; /* Section number=0 */
1101 c->operand[19] = 0x00; /* Last section number=0 */ 1101 c->operand[19] = 0x00; /* Last section number=0 */
1102 c->operand[20] = 0x1f; /* PCR_PID=1FFF */ 1102 c->operand[20] = 0x1f; /* PCR_PID=1FFF */
diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb/frontends/atbm8830_priv.h
index ce960f76092a..d460058d497e 100644
--- a/drivers/media/dvb/frontends/atbm8830_priv.h
+++ b/drivers/media/dvb/frontends/atbm8830_priv.h
@@ -18,7 +18,7 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22#ifndef __ATBM8830_PRIV_H 22#ifndef __ATBM8830_PRIV_H
23#define __ATBM8830_PRIV_H 23#define __ATBM8830_PRIV_H
24 24
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 24268ef2753d..68dba3a4b4da 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -664,6 +664,13 @@ static int au8522_reset(struct v4l2_subdev *sd, u32 val)
664{ 664{
665 struct au8522_state *state = to_state(sd); 665 struct au8522_state *state = to_state(sd);
666 666
667 state->operational_mode = AU8522_ANALOG_MODE;
668
669 /* Clear out any state associated with the digital side of the
670 chip, so that when it gets powered back up it won't think
671 that it is already tuned */
672 state->current_frequency = 0;
673
667 au8522_writereg(state, 0xa4, 1 << 5); 674 au8522_writereg(state, 0xa4, 1 << 5);
668 675
669 return 0; 676 return 0;
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index a1fed0fa8ed4..65f6a36dfb21 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -84,6 +84,14 @@ static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
84 84
85 dprintk("%s(%d)\n", __func__, enable); 85 dprintk("%s(%d)\n", __func__, enable);
86 86
87 if (state->operational_mode == AU8522_ANALOG_MODE) {
88 /* We're being asked to manage the gate even though we're
89 not in digital mode. This can occur if we get switched
90 over to analog mode before the dvb_frontend kernel thread
91 has completely shutdown */
92 return 0;
93 }
94
87 if (enable) 95 if (enable)
88 return au8522_writereg(state, 0x106, 1); 96 return au8522_writereg(state, 0x106, 1);
89 else 97 else
@@ -608,6 +616,13 @@ int au8522_init(struct dvb_frontend *fe)
608 struct au8522_state *state = fe->demodulator_priv; 616 struct au8522_state *state = fe->demodulator_priv;
609 dprintk("%s()\n", __func__); 617 dprintk("%s()\n", __func__);
610 618
619 state->operational_mode = AU8522_DIGITAL_MODE;
620
621 /* Clear out any state associated with the digital side of the
622 chip, so that when it gets powered back up it won't think
623 that it is already tuned */
624 state->current_frequency = 0;
625
611 au8522_writereg(state, 0xa4, 1 << 5); 626 au8522_writereg(state, 0xa4, 1 << 5);
612 627
613 au8522_i2c_gate_ctrl(fe, 1); 628 au8522_i2c_gate_ctrl(fe, 1);
@@ -704,6 +719,15 @@ int au8522_sleep(struct dvb_frontend *fe)
704 struct au8522_state *state = fe->demodulator_priv; 719 struct au8522_state *state = fe->demodulator_priv;
705 dprintk("%s()\n", __func__); 720 dprintk("%s()\n", __func__);
706 721
722 /* Only power down if the digital side is currently using the chip */
723 if (state->operational_mode == AU8522_ANALOG_MODE) {
724 /* We're not in one of the expected power modes, which means
725 that the DVB thread is probably telling us to go to sleep
726 even though the analog frontend has already started using
727 the chip. So ignore the request */
728 return 0;
729 }
730
707 /* turn off led */ 731 /* turn off led */
708 au8522_led_ctrl(state, 0); 732 au8522_led_ctrl(state, 0);
709 733
@@ -932,6 +956,8 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
932 /* setup the state */ 956 /* setup the state */
933 state->config = config; 957 state->config = config;
934 state->i2c = i2c; 958 state->i2c = i2c;
959 state->operational_mode = AU8522_DIGITAL_MODE;
960
935 /* create dvb_frontend */ 961 /* create dvb_frontend */
936 memcpy(&state->frontend.ops, &au8522_ops, 962 memcpy(&state->frontend.ops, &au8522_ops,
937 sizeof(struct dvb_frontend_ops)); 963 sizeof(struct dvb_frontend_ops));
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index c74c4e72fe91..609cf04bc312 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -34,10 +34,15 @@
34#include "au8522.h" 34#include "au8522.h"
35#include "tuner-i2c.h" 35#include "tuner-i2c.h"
36 36
37#define AU8522_ANALOG_MODE 0
38#define AU8522_DIGITAL_MODE 1
39
37struct au8522_state { 40struct au8522_state {
38 struct i2c_client *c; 41 struct i2c_client *c;
39 struct i2c_adapter *i2c; 42 struct i2c_adapter *i2c;
40 43
44 u8 operational_mode;
45
41 /* Used for sharing of the state between analog and digital mode */ 46 /* Used for sharing of the state between analog and digital mode */
42 struct tuner_i2c_props i2c_props; 47 struct tuner_i2c_props i2c_props;
43 struct list_head hybrid_tuner_instance_list; 48 struct list_head hybrid_tuner_instance_list;
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 40a099810279..afad252abf41 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -814,42 +814,51 @@ EXPORT_SYMBOL(dib3000mc_set_config);
814 814
815int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]) 815int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
816{ 816{
817 struct dib3000mc_state st = { .i2c_adap = i2c }; 817 struct dib3000mc_state *dmcst;
818 int k; 818 int k;
819 u8 new_addr; 819 u8 new_addr;
820 820
821 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26}; 821 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
822 822
823 dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
824 if (dmcst == NULL)
825 return -ENODEV;
826
827 dmcst->i2c_adap = i2c;
828
823 for (k = no_of_demods-1; k >= 0; k--) { 829 for (k = no_of_demods-1; k >= 0; k--) {
824 st.cfg = &cfg[k]; 830 dmcst->cfg = &cfg[k];
825 831
826 /* designated i2c address */ 832 /* designated i2c address */
827 new_addr = DIB3000MC_I2C_ADDRESS[k]; 833 new_addr = DIB3000MC_I2C_ADDRESS[k];
828 st.i2c_addr = new_addr; 834 dmcst->i2c_addr = new_addr;
829 if (dib3000mc_identify(&st) != 0) { 835 if (dib3000mc_identify(dmcst) != 0) {
830 st.i2c_addr = default_addr; 836 dmcst->i2c_addr = default_addr;
831 if (dib3000mc_identify(&st) != 0) { 837 if (dib3000mc_identify(dmcst) != 0) {
832 dprintk("-E- DiB3000P/MC #%d: not identified\n", k); 838 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
839 kfree(dmcst);
833 return -ENODEV; 840 return -ENODEV;
834 } 841 }
835 } 842 }
836 843
837 dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK); 844 dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
838 845
839 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0) 846 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
840 dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1); 847 dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
841 st.i2c_addr = new_addr; 848 dmcst->i2c_addr = new_addr;
842 } 849 }
843 850
844 for (k = 0; k < no_of_demods; k++) { 851 for (k = 0; k < no_of_demods; k++) {
845 st.cfg = &cfg[k]; 852 dmcst->cfg = &cfg[k];
846 st.i2c_addr = DIB3000MC_I2C_ADDRESS[k]; 853 dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
847 854
848 dib3000mc_write_word(&st, 1024, st.i2c_addr << 3); 855 dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
849 856
850 /* turn off data output */ 857 /* turn off data output */
851 dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z); 858 dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
852 } 859 }
860
861 kfree(dmcst);
853 return 0; 862 return 0;
854} 863}
855EXPORT_SYMBOL(dib3000mc_i2c_enumeration); 864EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 85468a45c344..2e28b973dfd3 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -1324,46 +1324,54 @@ EXPORT_SYMBOL(dib7000p_pid_filter);
1324 1324
1325int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) 1325int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1326{ 1326{
1327 struct dib7000p_state st = { .i2c_adap = i2c }; 1327 struct dib7000p_state *dpst;
1328 int k = 0; 1328 int k = 0;
1329 u8 new_addr = 0; 1329 u8 new_addr = 0;
1330 1330
1331 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1332 if (!dpst)
1333 return -ENOMEM;
1334
1335 dpst->i2c_adap = i2c;
1336
1331 for (k = no_of_demods-1; k >= 0; k--) { 1337 for (k = no_of_demods-1; k >= 0; k--) {
1332 st.cfg = cfg[k]; 1338 dpst->cfg = cfg[k];
1333 1339
1334 /* designated i2c address */ 1340 /* designated i2c address */
1335 new_addr = (0x40 + k) << 1; 1341 new_addr = (0x40 + k) << 1;
1336 st.i2c_addr = new_addr; 1342 dpst->i2c_addr = new_addr;
1337 dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */ 1343 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1338 if (dib7000p_identify(&st) != 0) { 1344 if (dib7000p_identify(dpst) != 0) {
1339 st.i2c_addr = default_addr; 1345 dpst->i2c_addr = default_addr;
1340 dib7000p_write_word(&st, 1287, 0x0003); /* sram lead in, rdy */ 1346 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1341 if (dib7000p_identify(&st) != 0) { 1347 if (dib7000p_identify(dpst) != 0) {
1342 dprintk("DiB7000P #%d: not identified\n", k); 1348 dprintk("DiB7000P #%d: not identified\n", k);
1349 kfree(dpst);
1343 return -EIO; 1350 return -EIO;
1344 } 1351 }
1345 } 1352 }
1346 1353
1347 /* start diversity to pull_down div_str - just for i2c-enumeration */ 1354 /* start diversity to pull_down div_str - just for i2c-enumeration */
1348 dib7000p_set_output_mode(&st, OUTMODE_DIVERSITY); 1355 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1349 1356
1350 /* set new i2c address and force divstart */ 1357 /* set new i2c address and force divstart */
1351 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2); 1358 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1352 1359
1353 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); 1360 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1354 } 1361 }
1355 1362
1356 for (k = 0; k < no_of_demods; k++) { 1363 for (k = 0; k < no_of_demods; k++) {
1357 st.cfg = cfg[k]; 1364 dpst->cfg = cfg[k];
1358 st.i2c_addr = (0x40 + k) << 1; 1365 dpst->i2c_addr = (0x40 + k) << 1;
1359 1366
1360 // unforce divstr 1367 // unforce divstr
1361 dib7000p_write_word(&st, 1285, st.i2c_addr << 2); 1368 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1362 1369
1363 /* deactivate div - it was just for i2c-enumeration */ 1370 /* deactivate div - it was just for i2c-enumeration */
1364 dib7000p_set_output_mode(&st, OUTMODE_HIGH_Z); 1371 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1365 } 1372 }
1366 1373
1374 kfree(dpst);
1367 return 0; 1375 return 0;
1368} 1376}
1369EXPORT_SYMBOL(dib7000p_i2c_enumeration); 1377EXPORT_SYMBOL(dib7000p_i2c_enumeration);
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
index b1ee20799639..e0a9ded11df4 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -109,6 +109,7 @@ static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
109static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) 109static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
110{ 110{
111 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 111 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
112 return 0;
112} 113}
113#endif 114#endif
114 115
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
index cff3535566fe..78001e8bcdb7 100644
--- a/drivers/media/dvb/frontends/ds3000.c
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -719,7 +719,7 @@ static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
719 (ds3000_readreg(state, 0x8d) << 4); 719 (ds3000_readreg(state, 0x8d) << 4);
720 dvbs2_signal_reading = ds3000_readreg(state, 0x8e); 720 dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
721 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1; 721 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
722 if (dvbs2_signal_reading == 0) { 722 if (tmp == 0) {
723 *snr = 0x0000; 723 *snr = 0x0000;
724 return 0; 724 return 0;
725 } 725 }
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 01f8f1f802fd..4f5e7d3a0e61 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -1583,7 +1583,7 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1583 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1583 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1584 1584
1585 struct stv0900_search_params p_search; 1585 struct stv0900_search_params p_search;
1586 struct stv0900_signal_info p_result; 1586 struct stv0900_signal_info p_result = intp->result[demod];
1587 1587
1588 enum fe_stv0900_error error = STV0900_NO_ERROR; 1588 enum fe_stv0900_error error = STV0900_NO_ERROR;
1589 1589
@@ -1842,6 +1842,19 @@ static void stv0900_release(struct dvb_frontend *fe)
1842 kfree(state); 1842 kfree(state);
1843} 1843}
1844 1844
1845static int stv0900_get_frontend(struct dvb_frontend *fe,
1846 struct dvb_frontend_parameters *p)
1847{
1848 struct stv0900_state *state = fe->demodulator_priv;
1849 struct stv0900_internal *intp = state->internal;
1850 enum fe_stv0900_demod_num demod = state->demod;
1851 struct stv0900_signal_info p_result = intp->result[demod];
1852
1853 p->frequency = p_result.locked ? p_result.frequency : 0;
1854 p->u.qpsk.symbol_rate = p_result.locked ? p_result.symbol_rate : 0;
1855 return 0;
1856}
1857
1845static struct dvb_frontend_ops stv0900_ops = { 1858static struct dvb_frontend_ops stv0900_ops = {
1846 1859
1847 .info = { 1860 .info = {
@@ -1862,6 +1875,7 @@ static struct dvb_frontend_ops stv0900_ops = {
1862 }, 1875 },
1863 .release = stv0900_release, 1876 .release = stv0900_release,
1864 .init = stv0900_init, 1877 .init = stv0900_init,
1878 .get_frontend = stv0900_get_frontend,
1865 .get_frontend_algo = stv0900_frontend_algo, 1879 .get_frontend_algo = stv0900_frontend_algo,
1866 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, 1880 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
1867 .diseqc_send_master_cmd = stv0900_send_master_cmd, 1881 .diseqc_send_master_cmd = stv0900_send_master_cmd,
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 96972804f4ad..425e7a43ae19 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -754,11 +754,19 @@ static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 d
754 return stv090x_write_regs(state, reg, &data, 1); 754 return stv090x_write_regs(state, reg, &data, 1);
755} 755}
756 756
757static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 757static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
758{ 758{
759 struct stv090x_state *state = fe->demodulator_priv;
760 u32 reg; 759 u32 reg;
761 760
761 /*
762 * NOTE! A lock is used as a FSM to control the state in which
763 * access is serialized between two tuners on the same demod.
764 * This has nothing to do with a lock to protect a critical section
765 * which may in some other cases be confused with protecting I/O
766 * access to the demodulator gate.
767 * In case of any error, the lock is unlocked and exit within the
768 * relevant operations themselves.
769 */
762 if (enable) 770 if (enable)
763 mutex_lock(&state->internal->tuner_lock); 771 mutex_lock(&state->internal->tuner_lock);
764 772
@@ -1778,7 +1786,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1778 freq -= cur_step * car_step; 1786 freq -= cur_step * car_step;
1779 1787
1780 /* Setup tuner */ 1788 /* Setup tuner */
1781 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 1789 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
1782 goto err; 1790 goto err;
1783 1791
1784 if (state->config->tuner_set_frequency) { 1792 if (state->config->tuner_set_frequency) {
@@ -1791,12 +1799,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1791 goto err_gateoff; 1799 goto err_gateoff;
1792 } 1800 }
1793 1801
1794 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 1802 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
1795 goto err; 1803 goto err;
1796 1804
1797 msleep(50); 1805 msleep(50);
1798 1806
1799 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 1807 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
1800 goto err; 1808 goto err;
1801 1809
1802 if (state->config->tuner_get_status) { 1810 if (state->config->tuner_get_status) {
@@ -1809,7 +1817,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1809 else 1817 else
1810 dprintk(FE_DEBUG, 1, "Tuner unlocked"); 1818 dprintk(FE_DEBUG, 1, "Tuner unlocked");
1811 1819
1812 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 1820 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
1813 goto err; 1821 goto err;
1814 1822
1815 } 1823 }
@@ -1822,7 +1830,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1822 return srate_coarse; 1830 return srate_coarse;
1823 1831
1824err_gateoff: 1832err_gateoff:
1825 stv090x_i2c_gate_ctrl(fe, 0); 1833 stv090x_i2c_gate_ctrl(state, 0);
1826err: 1834err:
1827 dprintk(FE_ERROR, 1, "I/O error"); 1835 dprintk(FE_ERROR, 1, "I/O error");
1828 return -1; 1836 return -1;
@@ -2167,7 +2175,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2167 freq -= cur_step * car_step; 2175 freq -= cur_step * car_step;
2168 2176
2169 /* Setup tuner */ 2177 /* Setup tuner */
2170 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 2178 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2171 goto err; 2179 goto err;
2172 2180
2173 if (state->config->tuner_set_frequency) { 2181 if (state->config->tuner_set_frequency) {
@@ -2180,12 +2188,12 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2180 goto err_gateoff; 2188 goto err_gateoff;
2181 } 2189 }
2182 2190
2183 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2191 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2184 goto err; 2192 goto err;
2185 2193
2186 msleep(50); 2194 msleep(50);
2187 2195
2188 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 2196 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2189 goto err; 2197 goto err;
2190 2198
2191 if (state->config->tuner_get_status) { 2199 if (state->config->tuner_get_status) {
@@ -2198,7 +2206,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2198 else 2206 else
2199 dprintk(FE_DEBUG, 1, "Tuner unlocked"); 2207 dprintk(FE_DEBUG, 1, "Tuner unlocked");
2200 2208
2201 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2209 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2202 goto err; 2210 goto err;
2203 2211
2204 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); 2212 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
@@ -2222,7 +2230,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2222 return lock; 2230 return lock;
2223 2231
2224err_gateoff: 2232err_gateoff:
2225 stv090x_i2c_gate_ctrl(fe, 0); 2233 stv090x_i2c_gate_ctrl(state, 0);
2226err: 2234err:
2227 dprintk(FE_ERROR, 1, "I/O error"); 2235 dprintk(FE_ERROR, 1, "I/O error");
2228 return -1; 2236 return -1;
@@ -2591,7 +2599,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2591 } 2599 }
2592 state->delsys = stv090x_get_std(state); 2600 state->delsys = stv090x_get_std(state);
2593 2601
2594 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 2602 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2595 goto err; 2603 goto err;
2596 2604
2597 if (state->config->tuner_get_frequency) { 2605 if (state->config->tuner_get_frequency) {
@@ -2599,7 +2607,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2599 goto err_gateoff; 2607 goto err_gateoff;
2600 } 2608 }
2601 2609
2602 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2610 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2603 goto err; 2611 goto err;
2604 2612
2605 offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000; 2613 offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;
@@ -2619,7 +2627,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2619 2627
2620 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { 2628 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {
2621 2629
2622 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 2630 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2623 goto err; 2631 goto err;
2624 2632
2625 if (state->config->tuner_get_frequency) { 2633 if (state->config->tuner_get_frequency) {
@@ -2627,7 +2635,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2627 goto err_gateoff; 2635 goto err_gateoff;
2628 } 2636 }
2629 2637
2630 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 2638 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2631 goto err; 2639 goto err;
2632 2640
2633 if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) 2641 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
@@ -2646,7 +2654,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
2646 return STV090x_OUTOFRANGE; 2654 return STV090x_OUTOFRANGE;
2647 2655
2648err_gateoff: 2656err_gateoff:
2649 stv090x_i2c_gate_ctrl(fe, 0); 2657 stv090x_i2c_gate_ctrl(state, 0);
2650err: 2658err:
2651 dprintk(FE_ERROR, 1, "I/O error"); 2659 dprintk(FE_ERROR, 1, "I/O error");
2652 return -1; 2660 return -1;
@@ -3000,7 +3008,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
3000 3008
3001 if (state->algo != STV090x_WARM_SEARCH) { 3009 if (state->algo != STV090x_WARM_SEARCH) {
3002 3010
3003 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 3011 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3004 goto err; 3012 goto err;
3005 3013
3006 if (state->config->tuner_set_bandwidth) { 3014 if (state->config->tuner_set_bandwidth) {
@@ -3008,7 +3016,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
3008 goto err_gateoff; 3016 goto err_gateoff;
3009 } 3017 }
3010 3018
3011 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 3019 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3012 goto err; 3020 goto err;
3013 3021
3014 } 3022 }
@@ -3059,7 +3067,7 @@ static int stv090x_optimize_track(struct stv090x_state *state)
3059 return 0; 3067 return 0;
3060 3068
3061err_gateoff: 3069err_gateoff:
3062 stv090x_i2c_gate_ctrl(fe, 0); 3070 stv090x_i2c_gate_ctrl(state, 0);
3063err: 3071err:
3064 dprintk(FE_ERROR, 1, "I/O error"); 3072 dprintk(FE_ERROR, 1, "I/O error");
3065 return -1; 3073 return -1;
@@ -3235,7 +3243,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3235 } 3243 }
3236 3244
3237 /* Setup tuner */ 3245 /* Setup tuner */
3238 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 3246 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3239 goto err; 3247 goto err;
3240 3248
3241 if (state->config->tuner_set_bbgain) { 3249 if (state->config->tuner_set_bbgain) {
@@ -3256,17 +3264,17 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3256 goto err_gateoff; 3264 goto err_gateoff;
3257 } 3265 }
3258 3266
3259 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 3267 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3260 goto err; 3268 goto err;
3261 3269
3262 msleep(50); 3270 msleep(50);
3263 3271
3264 if (state->config->tuner_get_status) { 3272 if (state->config->tuner_get_status) {
3265 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 3273 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3266 goto err; 3274 goto err;
3267 if (state->config->tuner_get_status(fe, &reg) < 0) 3275 if (state->config->tuner_get_status(fe, &reg) < 0)
3268 goto err_gateoff; 3276 goto err_gateoff;
3269 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 3277 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3270 goto err; 3278 goto err;
3271 3279
3272 if (reg) 3280 if (reg)
@@ -3400,7 +3408,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3400 return signal_state; 3408 return signal_state;
3401 3409
3402err_gateoff: 3410err_gateoff:
3403 stv090x_i2c_gate_ctrl(fe, 0); 3411 stv090x_i2c_gate_ctrl(state, 0);
3404err: 3412err:
3405 dprintk(FE_ERROR, 1, "I/O error"); 3413 dprintk(FE_ERROR, 1, "I/O error");
3406 return -1; 3414 return -1;
@@ -3839,6 +3847,17 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3839 struct stv090x_state *state = fe->demodulator_priv; 3847 struct stv090x_state *state = fe->demodulator_priv;
3840 u32 reg; 3848 u32 reg;
3841 3849
3850 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3851 goto err;
3852
3853 if (state->config->tuner_sleep) {
3854 if (state->config->tuner_sleep(fe) < 0)
3855 goto err_gateoff;
3856 }
3857
3858 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3859 goto err;
3860
3842 dprintk(FE_DEBUG, 1, "Set %s to sleep", 3861 dprintk(FE_DEBUG, 1, "Set %s to sleep",
3843 state->device == STV0900 ? "STV0900" : "STV0903"); 3862 state->device == STV0900 ? "STV0900" : "STV0903");
3844 3863
@@ -3853,6 +3872,9 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3853 goto err; 3872 goto err;
3854 3873
3855 return 0; 3874 return 0;
3875
3876err_gateoff:
3877 stv090x_i2c_gate_ctrl(state, 0);
3856err: 3878err:
3857 dprintk(FE_ERROR, 1, "I/O error"); 3879 dprintk(FE_ERROR, 1, "I/O error");
3858 return -1; 3880 return -1;
@@ -4311,6 +4333,20 @@ static int stv090x_init(struct dvb_frontend *fe)
4311 u32 reg; 4333 u32 reg;
4312 4334
4313 if (state->internal->mclk == 0) { 4335 if (state->internal->mclk == 0) {
4336 /* call tuner init to configure the tuner's clock output
4337 divider directly before setting up the master clock of
4338 the stv090x. */
4339 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
4340 goto err;
4341
4342 if (config->tuner_init) {
4343 if (config->tuner_init(fe) < 0)
4344 goto err_gateoff;
4345 }
4346
4347 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
4348 goto err;
4349
4314 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ 4350 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
4315 msleep(5); 4351 msleep(5);
4316 if (stv090x_write_reg(state, STV090x_SYNTCTRL, 4352 if (stv090x_write_reg(state, STV090x_SYNTCTRL,
@@ -4336,7 +4372,7 @@ static int stv090x_init(struct dvb_frontend *fe)
4336 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 4372 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
4337 goto err; 4373 goto err;
4338 4374
4339 if (stv090x_i2c_gate_ctrl(fe, 1) < 0) 4375 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
4340 goto err; 4376 goto err;
4341 4377
4342 if (config->tuner_set_mode) { 4378 if (config->tuner_set_mode) {
@@ -4349,7 +4385,7 @@ static int stv090x_init(struct dvb_frontend *fe)
4349 goto err_gateoff; 4385 goto err_gateoff;
4350 } 4386 }
4351 4387
4352 if (stv090x_i2c_gate_ctrl(fe, 0) < 0) 4388 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
4353 goto err; 4389 goto err;
4354 4390
4355 if (stv090x_set_tspath(state) < 0) 4391 if (stv090x_set_tspath(state) < 0)
@@ -4358,7 +4394,7 @@ static int stv090x_init(struct dvb_frontend *fe)
4358 return 0; 4394 return 0;
4359 4395
4360err_gateoff: 4396err_gateoff:
4361 stv090x_i2c_gate_ctrl(fe, 0); 4397 stv090x_i2c_gate_ctrl(state, 0);
4362err: 4398err:
4363 dprintk(FE_ERROR, 1, "I/O error"); 4399 dprintk(FE_ERROR, 1, "I/O error");
4364 return -1; 4400 return -1;
@@ -4503,8 +4539,6 @@ static struct dvb_frontend_ops stv090x_ops = {
4503 .sleep = stv090x_sleep, 4539 .sleep = stv090x_sleep,
4504 .get_frontend_algo = stv090x_frontend_algo, 4540 .get_frontend_algo = stv090x_frontend_algo,
4505 4541
4506 .i2c_gate_ctrl = stv090x_i2c_gate_ctrl,
4507
4508 .diseqc_send_master_cmd = stv090x_send_diseqc_msg, 4542 .diseqc_send_master_cmd = stv090x_send_diseqc_msg,
4509 .diseqc_send_burst = stv090x_send_diseqc_burst, 4543 .diseqc_send_burst = stv090x_send_diseqc_burst,
4510 .diseqc_recv_slave_reply = stv090x_recv_slave_reply, 4544 .diseqc_recv_slave_reply = stv090x_recv_slave_reply,
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
index 30f01a6902ac..dd1b93ae4e9d 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -87,6 +87,7 @@ struct stv090x_config {
87 bool diseqc_envelope_mode; 87 bool diseqc_envelope_mode;
88 88
89 int (*tuner_init) (struct dvb_frontend *fe); 89 int (*tuner_init) (struct dvb_frontend *fe);
90 int (*tuner_sleep) (struct dvb_frontend *fe);
90 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); 91 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
91 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); 92 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
92 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); 93 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
index dea4245f077c..42591ce1aaad 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -338,14 +338,12 @@ static struct dvb_tuner_ops stv6110x_ops = {
338 .frequency_max = 2150000, 338 .frequency_max = 2150000,
339 .frequency_step = 0, 339 .frequency_step = 0,
340 }, 340 },
341
342 .init = stv6110x_init,
343 .sleep = stv6110x_sleep,
344 .release = stv6110x_release 341 .release = stv6110x_release
345}; 342};
346 343
347static struct stv6110x_devctl stv6110x_ctl = { 344static struct stv6110x_devctl stv6110x_ctl = {
348 .tuner_init = stv6110x_init, 345 .tuner_init = stv6110x_init,
346 .tuner_sleep = stv6110x_sleep,
349 .tuner_set_mode = stv6110x_set_mode, 347 .tuner_set_mode = stv6110x_set_mode,
350 .tuner_set_frequency = stv6110x_set_frequency, 348 .tuner_set_frequency = stv6110x_set_frequency,
351 .tuner_get_frequency = stv6110x_get_frequency, 349 .tuner_get_frequency = stv6110x_get_frequency,
@@ -363,11 +361,10 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
363{ 361{
364 struct stv6110x_state *stv6110x; 362 struct stv6110x_state *stv6110x;
365 u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; 363 u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
366 int ret;
367 364
368 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); 365 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
369 if (stv6110x == NULL) 366 if (!stv6110x)
370 goto error; 367 return NULL;
371 368
372 stv6110x->i2c = i2c; 369 stv6110x->i2c = i2c;
373 stv6110x->config = config; 370 stv6110x->config = config;
@@ -392,34 +389,11 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
392 break; 389 break;
393 } 390 }
394 391
395 if (fe->ops.i2c_gate_ctrl) {
396 ret = fe->ops.i2c_gate_ctrl(fe, 1);
397 if (ret < 0)
398 goto error;
399 }
400
401 ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
402 ARRAY_SIZE(stv6110x->regs));
403 if (ret < 0) {
404 dprintk(FE_ERROR, 1, "Initialization failed");
405 goto error;
406 }
407
408 if (fe->ops.i2c_gate_ctrl) {
409 ret = fe->ops.i2c_gate_ctrl(fe, 0);
410 if (ret < 0)
411 goto error;
412 }
413
414 fe->tuner_priv = stv6110x; 392 fe->tuner_priv = stv6110x;
415 fe->ops.tuner_ops = stv6110x_ops; 393 fe->ops.tuner_ops = stv6110x_ops;
416 394
417 printk("%s: Attaching STV6110x \n", __func__); 395 printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
418 return stv6110x->devctl; 396 return stv6110x->devctl;
419
420error:
421 kfree(stv6110x);
422 return NULL;
423} 397}
424EXPORT_SYMBOL(stv6110x_attach); 398EXPORT_SYMBOL(stv6110x_attach);
425 399
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
index 2429ae6d7847..47516753929a 100644
--- a/drivers/media/dvb/frontends/stv6110x.h
+++ b/drivers/media/dvb/frontends/stv6110x.h
@@ -40,6 +40,7 @@ enum tuner_status {
40 40
41struct stv6110x_devctl { 41struct stv6110x_devctl {
42 int (*tuner_init) (struct dvb_frontend *fe); 42 int (*tuner_init) (struct dvb_frontend *fe);
43 int (*tuner_sleep) (struct dvb_frontend *fe);
43 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); 44 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
44 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); 45 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
45 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); 46 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index 4675a3b53c7d..3d4e4663220c 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -32,6 +32,8 @@
32#include "mantis_reg.h" 32#include "mantis_reg.h"
33#include "mantis_uart.h" 33#include "mantis_uart.h"
34 34
35#define MODULE_NAME "mantis_core"
36
35static struct ir_scancode mantis_ir_table[] = { 37static struct ir_scancode mantis_ir_table[] = {
36 { 0x29, KEY_POWER }, 38 { 0x29, KEY_POWER },
37 { 0x28, KEY_FAVORITES }, 39 { 0x28, KEY_FAVORITES },
@@ -126,7 +128,7 @@ int mantis_input_init(struct mantis_pci *mantis)
126 rc->id.version = 1; 128 rc->id.version = 1;
127 rc->dev = mantis->pdev->dev; 129 rc->dev = mantis->pdev->dev;
128 130
129 err = ir_input_register(rc, &ir_mantis, NULL); 131 err = __ir_input_register(rc, &ir_mantis, NULL, MODULE_NAME);
130 if (err) { 132 if (err) {
131 dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); 133 dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
132 input_free_device(rc); 134 input_free_device(rc);
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c
index 515346dd31d0..d1aa2bc0c155 100644
--- a/drivers/media/dvb/mantis/mantis_vp1041.c
+++ b/drivers/media/dvb/mantis/mantis_vp1041.c
@@ -136,12 +136,12 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
136 { STB0899_RCOMPC , 0xc9 }, 136 { STB0899_RCOMPC , 0xc9 },
137 { STB0899_AGC1CN , 0x01 }, 137 { STB0899_AGC1CN , 0x01 },
138 { STB0899_AGC1REF , 0x10 }, 138 { STB0899_AGC1REF , 0x10 },
139 { STB0899_RTC , 0x23 }, 139 { STB0899_RTC , 0x23 },
140 { STB0899_TMGCFG , 0x4e }, 140 { STB0899_TMGCFG , 0x4e },
141 { STB0899_AGC2REF , 0x34 }, 141 { STB0899_AGC2REF , 0x34 },
142 { STB0899_TLSR , 0x84 }, 142 { STB0899_TLSR , 0x84 },
143 { STB0899_CFD , 0xf7 }, 143 { STB0899_CFD , 0xf7 },
144 { STB0899_ACLC , 0x87 }, 144 { STB0899_ACLC , 0x87 },
145 { STB0899_BCLC , 0x94 }, 145 { STB0899_BCLC , 0x94 },
146 { STB0899_EQON , 0x41 }, 146 { STB0899_EQON , 0x41 },
147 { STB0899_LDT , 0xf1 }, 147 { STB0899_LDT , 0xf1 },
@@ -194,10 +194,10 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
194 { STB0899_ECNT3M , 0x0a }, 194 { STB0899_ECNT3M , 0x0a },
195 { STB0899_ECNT3L , 0xad }, 195 { STB0899_ECNT3L , 0xad },
196 { STB0899_FECAUTO1 , 0x06 }, 196 { STB0899_FECAUTO1 , 0x06 },
197 { STB0899_FECM , 0x01 }, 197 { STB0899_FECM , 0x01 },
198 { STB0899_VTH12 , 0xb0 }, 198 { STB0899_VTH12 , 0xb0 },
199 { STB0899_VTH23 , 0x7a }, 199 { STB0899_VTH23 , 0x7a },
200 { STB0899_VTH34 , 0x58 }, 200 { STB0899_VTH34 , 0x58 },
201 { STB0899_VTH56 , 0x38 }, 201 { STB0899_VTH56 , 0x38 },
202 { STB0899_VTH67 , 0x34 }, 202 { STB0899_VTH67 , 0x34 },
203 { STB0899_VTH78 , 0x24 }, 203 { STB0899_VTH78 , 0x24 },
@@ -206,7 +206,7 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
206 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ 206 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
207 { STB0899_TSULC , 0x42 }, 207 { STB0899_TSULC , 0x42 },
208 { STB0899_RSLLC , 0x41 }, 208 { STB0899_RSLLC , 0x41 },
209 { STB0899_TSLPL , 0x12 }, 209 { STB0899_TSLPL , 0x12 },
210 { STB0899_TSCFGH , 0x0c }, 210 { STB0899_TSCFGH , 0x0c },
211 { STB0899_TSCFGM , 0x00 }, 211 { STB0899_TSCFGM , 0x00 },
212 { STB0899_TSCFGL , 0x00 }, 212 { STB0899_TSCFGL , 0x00 },
diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig
index 3ec8e6fcbb1d..cec242b7c00d 100644
--- a/drivers/media/dvb/ngene/Kconfig
+++ b/drivers/media/dvb/ngene/Kconfig
@@ -4,6 +4,8 @@ config DVB_NGENE
4 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 4 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
5 select DVB_STV6110x if !DVB_FE_CUSTOMISE 5 select DVB_STV6110x if !DVB_FE_CUSTOMISE
6 select DVB_STV090x if !DVB_FE_CUSTOMISE 6 select DVB_STV090x if !DVB_FE_CUSTOMISE
7 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
8 select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
7 ---help--- 9 ---help---
8 Support for Micronas PCI express cards with nGene bridge. 10 Support for Micronas PCI express cards with nGene bridge.
9 11
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
index 40435cad4819..0608aabb14ee 100644
--- a/drivers/media/dvb/ngene/Makefile
+++ b/drivers/media/dvb/ngene/Makefile
@@ -2,10 +2,10 @@
2# Makefile for the nGene device driver 2# Makefile for the nGene device driver
3# 3#
4 4
5ngene-objs := ngene-core.o 5ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o
6 6
7obj-$(CONFIG_DVB_NGENE) += ngene.o 7obj-$(CONFIG_DVB_NGENE) += ngene.o
8 8
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ 10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
11 11EXTRA_CFLAGS += -Idrivers/media/common/tuners/
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
new file mode 100644
index 000000000000..692c3e226e83
--- /dev/null
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -0,0 +1,328 @@
1/*
2 * ngene-cards.c: nGene PCIe bridge driver - card specific info
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
7 * Modifications for new nGene firmware,
8 * support for EEPROM-copying,
9 * support for new dual DVB-S2 card prototype
10 *
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 only, as published by the Free Software Foundation.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * 02110-1301, USA
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/pci.h>
33#include <linux/pci_ids.h>
34
35#include "ngene.h"
36
37/* demods/tuners */
38#include "stv6110x.h"
39#include "stv090x.h"
40#include "lnbh24.h"
41#include "lgdt330x.h"
42#include "mt2131.h"
43
44
45/****************************************************************************/
46/* Demod/tuner attachment ***************************************************/
47/****************************************************************************/
48
49static int tuner_attach_stv6110(struct ngene_channel *chan)
50{
51 struct stv090x_config *feconf = (struct stv090x_config *)
52 chan->dev->card_info->fe_config[chan->number];
53 struct stv6110x_config *tunerconf = (struct stv6110x_config *)
54 chan->dev->card_info->tuner_config[chan->number];
55 struct stv6110x_devctl *ctl;
56
57 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf,
58 &chan->i2c_adapter);
59 if (ctl == NULL) {
60 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
61 return -ENODEV;
62 }
63
64 feconf->tuner_init = ctl->tuner_init;
65 feconf->tuner_set_mode = ctl->tuner_set_mode;
66 feconf->tuner_set_frequency = ctl->tuner_set_frequency;
67 feconf->tuner_get_frequency = ctl->tuner_get_frequency;
68 feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
69 feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
70 feconf->tuner_set_bbgain = ctl->tuner_set_bbgain;
71 feconf->tuner_get_bbgain = ctl->tuner_get_bbgain;
72 feconf->tuner_set_refclk = ctl->tuner_set_refclk;
73 feconf->tuner_get_status = ctl->tuner_get_status;
74
75 return 0;
76}
77
78
79static int demod_attach_stv0900(struct ngene_channel *chan)
80{
81 struct stv090x_config *feconf = (struct stv090x_config *)
82 chan->dev->card_info->fe_config[chan->number];
83
84 chan->fe = dvb_attach(stv090x_attach,
85 feconf,
86 &chan->i2c_adapter,
87 chan->number == 0 ? STV090x_DEMODULATOR_0 :
88 STV090x_DEMODULATOR_1);
89 if (chan->fe == NULL) {
90 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
91 return -ENODEV;
92 }
93
94 if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0,
95 0, chan->dev->card_info->lnb[chan->number])) {
96 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
97 dvb_frontend_detach(chan->fe);
98 return -ENODEV;
99 }
100
101 return 0;
102}
103
104static struct lgdt330x_config aver_m780 = {
105 .demod_address = 0xb2 >> 1,
106 .demod_chip = LGDT3303,
107 .serial_mpeg = 0x00, /* PARALLEL */
108 .clock_polarity_flip = 1,
109};
110
111static struct mt2131_config m780_tunerconfig = {
112 0xc0 >> 1
113};
114
115/* A single func to attach the demo and tuner, rather than
116 * use two sep funcs like the current design mandates.
117 */
118static int demod_attach_lg330x(struct ngene_channel *chan)
119{
120 chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter);
121 if (chan->fe == NULL) {
122 printk(KERN_ERR DEVICE_NAME ": No LGDT330x found!\n");
123 return -ENODEV;
124 }
125
126 dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter,
127 &m780_tunerconfig, 0);
128
129 return (chan->fe) ? 0 : -ENODEV;
130}
131
132/****************************************************************************/
133/* Switch control (I2C gates, etc.) *****************************************/
134/****************************************************************************/
135
136
137static struct stv090x_config fe_cineS2 = {
138 .device = STV0900,
139 .demod_mode = STV090x_DUAL,
140 .clk_mode = STV090x_CLK_EXT,
141
142 .xtal = 27000000,
143 .address = 0x68,
144
145 .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
146 .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
147
148 .repeater_level = STV090x_RPTLEVEL_16,
149
150 .adc1_range = STV090x_ADC_1Vpp,
151 .adc2_range = STV090x_ADC_1Vpp,
152
153 .diseqc_envelope_mode = true,
154};
155
156static struct stv6110x_config tuner_cineS2_0 = {
157 .addr = 0x60,
158 .refclk = 27000000,
159 .clk_div = 1,
160};
161
162static struct stv6110x_config tuner_cineS2_1 = {
163 .addr = 0x63,
164 .refclk = 27000000,
165 .clk_div = 1,
166};
167
168static struct ngene_info ngene_info_cineS2 = {
169 .type = NGENE_SIDEWINDER,
170 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner",
171 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
172 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
173 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
174 .fe_config = {&fe_cineS2, &fe_cineS2},
175 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
176 .lnb = {0x0b, 0x08},
177 .tsf = {3, 3},
178 .fw_version = 15,
179};
180
181static struct ngene_info ngene_info_satixS2 = {
182 .type = NGENE_SIDEWINDER,
183 .name = "Mystique SaTiX-S2 Dual",
184 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
185 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
186 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
187 .fe_config = {&fe_cineS2, &fe_cineS2},
188 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
189 .lnb = {0x0b, 0x08},
190 .tsf = {3, 3},
191 .fw_version = 15,
192};
193
194static struct ngene_info ngene_info_satixS2v2 = {
195 .type = NGENE_SIDEWINDER,
196 .name = "Mystique SaTiX-S2 Dual (v2)",
197 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
198 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
199 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
200 .fe_config = {&fe_cineS2, &fe_cineS2},
201 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
202 .lnb = {0x0a, 0x08},
203 .tsf = {3, 3},
204 .fw_version = 15,
205};
206
207static struct ngene_info ngene_info_cineS2v5 = {
208 .type = NGENE_SIDEWINDER,
209 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
210 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
211 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
212 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
213 .fe_config = {&fe_cineS2, &fe_cineS2},
214 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
215 .lnb = {0x0a, 0x08},
216 .tsf = {3, 3},
217 .fw_version = 15,
218};
219
220static struct ngene_info ngene_info_m780 = {
221 .type = NGENE_APP,
222 .name = "Aver M780 ATSC/QAM-B",
223
224 /* Channel 0 is analog, which is currently unsupported */
225 .io_type = { NGENE_IO_NONE, NGENE_IO_TSIN },
226 .demod_attach = { NULL, demod_attach_lg330x },
227
228 /* Ensure these are NULL else the frame will call them (as funcs) */
229 .tuner_attach = { 0, 0, 0, 0 },
230 .fe_config = { NULL, &aver_m780 },
231 .avf = { 0 },
232
233 /* A custom electrical interface config for the demod to bridge */
234 .tsf = { 4, 4 },
235 .fw_version = 15,
236};
237
238/****************************************************************************/
239
240
241
242/****************************************************************************/
243/* PCI Subsystem ID *********************************************************/
244/****************************************************************************/
245
246#define NGENE_ID(_subvend, _subdev, _driverdata) { \
247 .vendor = NGENE_VID, .device = NGENE_PID, \
248 .subvendor = _subvend, .subdevice = _subdev, \
249 .driver_data = (unsigned long) &_driverdata }
250
251/****************************************************************************/
252
253static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
254 NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
255 NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
256 NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
257 NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
258 NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
259 NGENE_ID(0x1461, 0x062e, ngene_info_m780),
260 {0}
261};
262MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
263
264/****************************************************************************/
265/* Init/Exit ****************************************************************/
266/****************************************************************************/
267
268static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
269 enum pci_channel_state state)
270{
271 printk(KERN_ERR DEVICE_NAME ": PCI error\n");
272 if (state == pci_channel_io_perm_failure)
273 return PCI_ERS_RESULT_DISCONNECT;
274 if (state == pci_channel_io_frozen)
275 return PCI_ERS_RESULT_NEED_RESET;
276 return PCI_ERS_RESULT_CAN_RECOVER;
277}
278
279static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
280{
281 printk(KERN_INFO DEVICE_NAME ": link reset\n");
282 return 0;
283}
284
285static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
286{
287 printk(KERN_INFO DEVICE_NAME ": slot reset\n");
288 return 0;
289}
290
291static void ngene_resume(struct pci_dev *dev)
292{
293 printk(KERN_INFO DEVICE_NAME ": resume\n");
294}
295
296static struct pci_error_handlers ngene_errors = {
297 .error_detected = ngene_error_detected,
298 .link_reset = ngene_link_reset,
299 .slot_reset = ngene_slot_reset,
300 .resume = ngene_resume,
301};
302
303static struct pci_driver ngene_pci_driver = {
304 .name = "ngene",
305 .id_table = ngene_id_tbl,
306 .probe = ngene_probe,
307 .remove = __devexit_p(ngene_remove),
308 .err_handler = &ngene_errors,
309};
310
311static __init int module_init_ngene(void)
312{
313 printk(KERN_INFO
314 "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
315 return pci_register_driver(&ngene_pci_driver);
316}
317
318static __exit void module_exit_ngene(void)
319{
320 pci_unregister_driver(&ngene_pci_driver);
321}
322
323module_init(module_init_ngene);
324module_exit(module_exit_ngene);
325
326MODULE_DESCRIPTION("nGene");
327MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
328MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index 645e8b8a7137..c8b4dfa0ab5f 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -34,20 +34,14 @@
34#include <linux/io.h> 34#include <linux/io.h>
35#include <asm/div64.h> 35#include <asm/div64.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <linux/pci_ids.h>
38#include <linux/smp_lock.h> 37#include <linux/smp_lock.h>
39#include <linux/timer.h> 38#include <linux/timer.h>
40#include <linux/version.h>
41#include <linux/byteorder/generic.h> 39#include <linux/byteorder/generic.h>
42#include <linux/firmware.h> 40#include <linux/firmware.h>
43#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
44 42
45#include "ngene.h" 43#include "ngene.h"
46 44
47#include "stv6110x.h"
48#include "stv090x.h"
49#include "lnbh24.h"
50
51static int one_adapter = 1; 45static int one_adapter = 1;
52module_param(one_adapter, int, 0444); 46module_param(one_adapter, int, 0444);
53MODULE_PARM_DESC(one_adapter, "Use only one adapter."); 47MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
@@ -63,8 +57,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
63 57
64#define dprintk if (debug) printk 58#define dprintk if (debug) printk
65 59
66#define DEVICE_NAME "ngene"
67
68#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) 60#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
69#define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr))) 61#define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr)))
70#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) 62#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
@@ -352,7 +344,7 @@ static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com)
352 return 0; 344 return 0;
353} 345}
354 346
355static int ngene_command(struct ngene *dev, struct ngene_command *com) 347int ngene_command(struct ngene *dev, struct ngene_command *com)
356{ 348{
357 int result; 349 int result;
358 350
@@ -363,55 +355,6 @@ static int ngene_command(struct ngene *dev, struct ngene_command *com)
363} 355}
364 356
365 357
366static int ngene_command_i2c_read(struct ngene *dev, u8 adr,
367 u8 *out, u8 outlen, u8 *in, u8 inlen, int flag)
368{
369 struct ngene_command com;
370
371 com.cmd.hdr.Opcode = CMD_I2C_READ;
372 com.cmd.hdr.Length = outlen + 3;
373 com.cmd.I2CRead.Device = adr << 1;
374 memcpy(com.cmd.I2CRead.Data, out, outlen);
375 com.cmd.I2CRead.Data[outlen] = inlen;
376 com.cmd.I2CRead.Data[outlen + 1] = 0;
377 com.in_len = outlen + 3;
378 com.out_len = inlen + 1;
379
380 if (ngene_command(dev, &com) < 0)
381 return -EIO;
382
383 if ((com.cmd.raw8[0] >> 1) != adr)
384 return -EIO;
385
386 if (flag)
387 memcpy(in, com.cmd.raw8, inlen + 1);
388 else
389 memcpy(in, com.cmd.raw8 + 1, inlen);
390 return 0;
391}
392
393static int ngene_command_i2c_write(struct ngene *dev, u8 adr,
394 u8 *out, u8 outlen)
395{
396 struct ngene_command com;
397
398
399 com.cmd.hdr.Opcode = CMD_I2C_WRITE;
400 com.cmd.hdr.Length = outlen + 1;
401 com.cmd.I2CRead.Device = adr << 1;
402 memcpy(com.cmd.I2CRead.Data, out, outlen);
403 com.in_len = outlen + 1;
404 com.out_len = 1;
405
406 if (ngene_command(dev, &com) < 0)
407 return -EIO;
408
409 if (com.cmd.raw8[0] == 1)
410 return -EIO;
411
412 return 0;
413}
414
415static int ngene_command_load_firmware(struct ngene *dev, 358static int ngene_command_load_firmware(struct ngene *dev,
416 u8 *ngene_fw, u32 size) 359 u8 *ngene_fw, u32 size)
417{ 360{
@@ -477,7 +420,7 @@ static int ngene_command_config_free_buf(struct ngene *dev, u8 *config)
477 return 0; 420 return 0;
478} 421}
479 422
480static int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level) 423int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level)
481{ 424{
482 struct ngene_command com; 425 struct ngene_command com;
483 426
@@ -514,11 +457,12 @@ static int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level)
514 457
515/****************************************************************************/ 458/****************************************************************************/
516 459
517static u8 TSFeatureDecoderSetup[8 * 4] = { 460static u8 TSFeatureDecoderSetup[8 * 5] = {
518 0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, 461 0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00,
519 0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */ 462 0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */
520 0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */ 463 0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */
521 0x72, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */ 464 0x72, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */
465 0x40, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* LGDT3303 */
522}; 466};
523 467
524/* Set NGENE I2S Config to 16 bit packed */ 468/* Set NGENE I2S Config to 16 bit packed */
@@ -559,7 +503,7 @@ static u8 ITUFeatureDecoderSetup[8] = {
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00 503 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00
560}; 504};
561 505
562static void FillTSBuffer(void *Buffer, int Length, u32 Flags) 506void FillTSBuffer(void *Buffer, int Length, u32 Flags)
563{ 507{
564 u32 *ptr = Buffer; 508 u32 *ptr = Buffer;
565 509
@@ -772,144 +716,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
772 return 0; 716 return 0;
773} 717}
774 718
775 719void set_transfer(struct ngene_channel *chan, int state)
776/****************************************************************************/
777/* I2C **********************************************************************/
778/****************************************************************************/
779
780static void ngene_i2c_set_bus(struct ngene *dev, int bus)
781{
782 if (!(dev->card_info->i2c_access & 2))
783 return;
784 if (dev->i2c_current_bus == bus)
785 return;
786
787 switch (bus) {
788 case 0:
789 ngene_command_gpio_set(dev, 3, 0);
790 ngene_command_gpio_set(dev, 2, 1);
791 break;
792
793 case 1:
794 ngene_command_gpio_set(dev, 2, 0);
795 ngene_command_gpio_set(dev, 3, 1);
796 break;
797 }
798 dev->i2c_current_bus = bus;
799}
800
801static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
802 struct i2c_msg msg[], int num)
803{
804 struct ngene_channel *chan =
805 (struct ngene_channel *)i2c_get_adapdata(adapter);
806 struct ngene *dev = chan->dev;
807
808 down(&dev->i2c_switch_mutex);
809 ngene_i2c_set_bus(dev, chan->number);
810
811 if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
812 if (!ngene_command_i2c_read(dev, msg[0].addr,
813 msg[0].buf, msg[0].len,
814 msg[1].buf, msg[1].len, 0))
815 goto done;
816
817 if (num == 1 && !(msg[0].flags & I2C_M_RD))
818 if (!ngene_command_i2c_write(dev, msg[0].addr,
819 msg[0].buf, msg[0].len))
820 goto done;
821 if (num == 1 && (msg[0].flags & I2C_M_RD))
822 if (!ngene_command_i2c_read(dev, msg[0].addr, 0, 0,
823 msg[0].buf, msg[0].len, 0))
824 goto done;
825
826 up(&dev->i2c_switch_mutex);
827 return -EIO;
828
829done:
830 up(&dev->i2c_switch_mutex);
831 return num;
832}
833
834
835static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
836{
837 return I2C_FUNC_SMBUS_EMUL;
838}
839
840static struct i2c_algorithm ngene_i2c_algo = {
841 .master_xfer = ngene_i2c_master_xfer,
842 .functionality = ngene_i2c_functionality,
843};
844
845static int ngene_i2c_init(struct ngene *dev, int dev_nr)
846{
847 struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
848
849 i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
850 adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
851
852 strcpy(adap->name, "nGene");
853
854 adap->algo = &ngene_i2c_algo;
855 adap->algo_data = (void *)&(dev->channel[dev_nr]);
856 adap->dev.parent = &dev->pci_dev->dev;
857
858 return i2c_add_adapter(adap);
859}
860
861
862/****************************************************************************/
863/* DVB functions and API interface ******************************************/
864/****************************************************************************/
865
866static void swap_buffer(u32 *p, u32 len)
867{
868 while (len) {
869 *p = swab32(*p);
870 p++;
871 len -= 4;
872 }
873}
874
875
876static void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
877{
878 struct ngene_channel *chan = priv;
879
880
881#ifdef COMMAND_TIMEOUT_WORKAROUND
882 if (chan->users > 0)
883#endif
884 dvb_dmx_swfilter(&chan->demux, buf, len);
885 return 0;
886}
887
888u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 };
889
890static void *tsout_exchange(void *priv, void *buf, u32 len,
891 u32 clock, u32 flags)
892{
893 struct ngene_channel *chan = priv;
894 struct ngene *dev = chan->dev;
895 u32 alen;
896
897 alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
898 alen -= alen % 188;
899
900 if (alen < len)
901 FillTSBuffer(buf + alen, len - alen, flags);
902 else
903 alen = len;
904 dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
905 if (flags & DF_SWAP32)
906 swap_buffer((u32 *)buf, alen);
907 wake_up_interruptible(&dev->tsout_rbuf.queue);
908 return buf;
909}
910
911
912static void set_transfer(struct ngene_channel *chan, int state)
913{ 720{
914 u8 control = 0, mode = 0, flags = 0; 721 u8 control = 0, mode = 0, flags = 0;
915 struct ngene *dev = chan->dev; 722 struct ngene *dev = chan->dev;
@@ -970,85 +777,12 @@ static void set_transfer(struct ngene_channel *chan, int state)
970 state); 777 state);
971 if (!state) { 778 if (!state) {
972 spin_lock_irq(&chan->state_lock); 779 spin_lock_irq(&chan->state_lock);
973 chan->pBufferExchange = 0; 780 chan->pBufferExchange = NULL;
974 dvb_ringbuffer_flush(&dev->tsout_rbuf); 781 dvb_ringbuffer_flush(&dev->tsout_rbuf);
975 spin_unlock_irq(&chan->state_lock); 782 spin_unlock_irq(&chan->state_lock);
976 } 783 }
977} 784}
978 785
979static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
980{
981 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
982 struct ngene_channel *chan = dvbdmx->priv;
983
984 if (chan->users == 0) {
985#ifdef COMMAND_TIMEOUT_WORKAROUND
986 if (!chan->running)
987#endif
988 set_transfer(chan, 1);
989 /* msleep(10); */
990 }
991
992 return ++chan->users;
993}
994
995static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
996{
997 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
998 struct ngene_channel *chan = dvbdmx->priv;
999
1000 if (--chan->users)
1001 return chan->users;
1002
1003#ifndef COMMAND_TIMEOUT_WORKAROUND
1004 set_transfer(chan, 0);
1005#endif
1006
1007 return 0;
1008}
1009
1010
1011
1012static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
1013 int (*start_feed)(struct dvb_demux_feed *),
1014 int (*stop_feed)(struct dvb_demux_feed *),
1015 void *priv)
1016{
1017 dvbdemux->priv = priv;
1018
1019 dvbdemux->filternum = 256;
1020 dvbdemux->feednum = 256;
1021 dvbdemux->start_feed = start_feed;
1022 dvbdemux->stop_feed = stop_feed;
1023 dvbdemux->write_to_decoder = 0;
1024 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
1025 DMX_SECTION_FILTERING |
1026 DMX_MEMORY_BASED_FILTERING);
1027 return dvb_dmx_init(dvbdemux);
1028}
1029
1030static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
1031 struct dvb_demux *dvbdemux,
1032 struct dmx_frontend *hw_frontend,
1033 struct dmx_frontend *mem_frontend,
1034 struct dvb_adapter *dvb_adapter)
1035{
1036 int ret;
1037
1038 dmxdev->filternum = 256;
1039 dmxdev->demux = &dvbdemux->dmx;
1040 dmxdev->capabilities = 0;
1041 ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
1042 if (ret < 0)
1043 return ret;
1044
1045 hw_frontend->source = DMX_FRONTEND_0;
1046 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
1047 mem_frontend->source = DMX_MEMORY_FE;
1048 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
1049 return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
1050}
1051
1052 786
1053/****************************************************************************/ 787/****************************************************************************/
1054/* nGene hardware init and release functions ********************************/ 788/* nGene hardware init and release functions ********************************/
@@ -1094,8 +828,8 @@ static void free_idlebuffer(struct ngene *dev,
1094 return; 828 return;
1095 free_ringbuffer(dev, rb); 829 free_ringbuffer(dev, rb);
1096 for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) { 830 for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) {
1097 Cur->Buffer2 = 0; 831 Cur->Buffer2 = NULL;
1098 Cur->scList2 = 0; 832 Cur->scList2 = NULL;
1099 Cur->ngeneBuffer.Address_of_first_entry_2 = 0; 833 Cur->ngeneBuffer.Address_of_first_entry_2 = 0;
1100 Cur->ngeneBuffer.Number_of_entries_2 = 0; 834 Cur->ngeneBuffer.Number_of_entries_2 = 0;
1101 } 835 }
@@ -1141,7 +875,7 @@ static int create_ring_buffer(struct pci_dev *pci_dev,
1141 u64 PARingBufferNext; 875 u64 PARingBufferNext;
1142 struct SBufferHeader *Cur, *Next; 876 struct SBufferHeader *Cur, *Next;
1143 877
1144 descr->Head = 0; 878 descr->Head = NULL;
1145 descr->MemSize = 0; 879 descr->MemSize = 0;
1146 descr->PAHead = 0; 880 descr->PAHead = 0;
1147 descr->NumBuffers = 0; 881 descr->NumBuffers = 0;
@@ -1633,69 +1367,6 @@ fail:
1633 1367
1634 1368
1635 1369
1636/****************************************************************************/
1637/* Switch control (I2C gates, etc.) *****************************************/
1638/****************************************************************************/
1639
1640
1641/****************************************************************************/
1642/* Demod/tuner attachment ***************************************************/
1643/****************************************************************************/
1644
1645static int tuner_attach_stv6110(struct ngene_channel *chan)
1646{
1647 struct stv090x_config *feconf = (struct stv090x_config *)
1648 chan->dev->card_info->fe_config[chan->number];
1649 struct stv6110x_config *tunerconf = (struct stv6110x_config *)
1650 chan->dev->card_info->tuner_config[chan->number];
1651 struct stv6110x_devctl *ctl;
1652
1653 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf,
1654 &chan->i2c_adapter);
1655 if (ctl == NULL) {
1656 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
1657 return -ENODEV;
1658 }
1659
1660 feconf->tuner_init = ctl->tuner_init;
1661 feconf->tuner_set_mode = ctl->tuner_set_mode;
1662 feconf->tuner_set_frequency = ctl->tuner_set_frequency;
1663 feconf->tuner_get_frequency = ctl->tuner_get_frequency;
1664 feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
1665 feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
1666 feconf->tuner_set_bbgain = ctl->tuner_set_bbgain;
1667 feconf->tuner_get_bbgain = ctl->tuner_get_bbgain;
1668 feconf->tuner_set_refclk = ctl->tuner_set_refclk;
1669 feconf->tuner_get_status = ctl->tuner_get_status;
1670
1671 return 0;
1672}
1673
1674
1675static int demod_attach_stv0900(struct ngene_channel *chan)
1676{
1677 struct stv090x_config *feconf = (struct stv090x_config *)
1678 chan->dev->card_info->fe_config[chan->number];
1679
1680 chan->fe = dvb_attach(stv090x_attach,
1681 feconf,
1682 &chan->i2c_adapter,
1683 chan->number == 0 ? STV090x_DEMODULATOR_0 :
1684 STV090x_DEMODULATOR_1);
1685 if (chan->fe == NULL) {
1686 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
1687 return -ENODEV;
1688 }
1689
1690 if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0,
1691 0, chan->dev->card_info->lnb[chan->number])) {
1692 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
1693 dvb_frontend_detach(chan->fe);
1694 return -ENODEV;
1695 }
1696
1697 return 0;
1698}
1699 1370
1700/****************************************************************************/ 1371/****************************************************************************/
1701/****************************************************************************/ 1372/****************************************************************************/
@@ -1719,7 +1390,7 @@ static void release_channel(struct ngene_channel *chan)
1719 if (chan->fe) { 1390 if (chan->fe) {
1720 dvb_unregister_frontend(chan->fe); 1391 dvb_unregister_frontend(chan->fe);
1721 dvb_frontend_detach(chan->fe); 1392 dvb_frontend_detach(chan->fe);
1722 chan->fe = 0; 1393 chan->fe = NULL;
1723 } 1394 }
1724 dvbdemux->dmx.close(&dvbdemux->dmx); 1395 dvbdemux->dmx.close(&dvbdemux->dmx);
1725 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, 1396 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
@@ -1751,7 +1422,7 @@ static int init_channel(struct ngene_channel *chan)
1751 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { 1422 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
1752 if (nr >= STREAM_AUDIOIN1) 1423 if (nr >= STREAM_AUDIOIN1)
1753 chan->DataFormatFlags = DF_SWAP32; 1424 chan->DataFormatFlags = DF_SWAP32;
1754 if (nr == 0 || !one_adapter) { 1425 if (nr == 0 || !one_adapter || dev->first_adapter == NULL) {
1755 adapter = &dev->adapter[nr]; 1426 adapter = &dev->adapter[nr];
1756 ret = dvb_register_adapter(adapter, "nGene", 1427 ret = dvb_register_adapter(adapter, "nGene",
1757 THIS_MODULE, 1428 THIS_MODULE,
@@ -1759,8 +1430,10 @@ static int init_channel(struct ngene_channel *chan)
1759 adapter_nr); 1430 adapter_nr);
1760 if (ret < 0) 1431 if (ret < 0)
1761 return ret; 1432 return ret;
1433 if (dev->first_adapter == NULL)
1434 dev->first_adapter = adapter;
1762 } else { 1435 } else {
1763 adapter = &dev->adapter[0]; 1436 adapter = dev->first_adapter;
1764 } 1437 }
1765 1438
1766 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", 1439 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
@@ -1797,6 +1470,7 @@ static int init_channels(struct ngene *dev)
1797 int i, j; 1470 int i, j;
1798 1471
1799 for (i = 0; i < MAX_STREAM; i++) { 1472 for (i = 0; i < MAX_STREAM; i++) {
1473 dev->channel[i].number = i;
1800 if (init_channel(&dev->channel[i]) < 0) { 1474 if (init_channel(&dev->channel[i]) < 0) {
1801 for (j = i - 1; j >= 0; j--) 1475 for (j = i - 1; j >= 0; j--)
1802 release_channel(&dev->channel[j]); 1476 release_channel(&dev->channel[j]);
@@ -1810,7 +1484,7 @@ static int init_channels(struct ngene *dev)
1810/* device probe/remove calls ************************************************/ 1484/* device probe/remove calls ************************************************/
1811/****************************************************************************/ 1485/****************************************************************************/
1812 1486
1813static void __devexit ngene_remove(struct pci_dev *pdev) 1487void __devexit ngene_remove(struct pci_dev *pdev)
1814{ 1488{
1815 struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); 1489 struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
1816 int i; 1490 int i;
@@ -1820,12 +1494,12 @@ static void __devexit ngene_remove(struct pci_dev *pdev)
1820 release_channel(&dev->channel[i]); 1494 release_channel(&dev->channel[i]);
1821 ngene_stop(dev); 1495 ngene_stop(dev);
1822 ngene_release_buffers(dev); 1496 ngene_release_buffers(dev);
1823 pci_set_drvdata(pdev, 0); 1497 pci_set_drvdata(pdev, NULL);
1824 pci_disable_device(pdev); 1498 pci_disable_device(pdev);
1825} 1499}
1826 1500
1827static int __devinit ngene_probe(struct pci_dev *pci_dev, 1501int __devinit ngene_probe(struct pci_dev *pci_dev,
1828 const struct pci_device_id *id) 1502 const struct pci_device_id *id)
1829{ 1503{
1830 struct ngene *dev; 1504 struct ngene *dev;
1831 int stat = 0; 1505 int stat = 0;
@@ -1868,156 +1542,6 @@ fail1:
1868 ngene_release_buffers(dev); 1542 ngene_release_buffers(dev);
1869fail0: 1543fail0:
1870 pci_disable_device(pci_dev); 1544 pci_disable_device(pci_dev);
1871 pci_set_drvdata(pci_dev, 0); 1545 pci_set_drvdata(pci_dev, NULL);
1872 return stat; 1546 return stat;
1873} 1547}
1874
1875/****************************************************************************/
1876/* Card configs *************************************************************/
1877/****************************************************************************/
1878
1879static struct stv090x_config fe_cineS2 = {
1880 .device = STV0900,
1881 .demod_mode = STV090x_DUAL,
1882 .clk_mode = STV090x_CLK_EXT,
1883
1884 .xtal = 27000000,
1885 .address = 0x68,
1886
1887 .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
1888 .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
1889
1890 .repeater_level = STV090x_RPTLEVEL_16,
1891
1892 .adc1_range = STV090x_ADC_1Vpp,
1893 .adc2_range = STV090x_ADC_1Vpp,
1894
1895 .diseqc_envelope_mode = true,
1896};
1897
1898static struct stv6110x_config tuner_cineS2_0 = {
1899 .addr = 0x60,
1900 .refclk = 27000000,
1901 .clk_div = 1,
1902};
1903
1904static struct stv6110x_config tuner_cineS2_1 = {
1905 .addr = 0x63,
1906 .refclk = 27000000,
1907 .clk_div = 1,
1908};
1909
1910static struct ngene_info ngene_info_cineS2 = {
1911 .type = NGENE_SIDEWINDER,
1912 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner",
1913 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
1914 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
1915 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
1916 .fe_config = {&fe_cineS2, &fe_cineS2},
1917 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
1918 .lnb = {0x0b, 0x08},
1919 .tsf = {3, 3},
1920 .fw_version = 15,
1921};
1922
1923static struct ngene_info ngene_info_satixs2 = {
1924 .type = NGENE_SIDEWINDER,
1925 .name = "Mystique SaTiX-S2 Dual",
1926 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
1927 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
1928 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
1929 .fe_config = {&fe_cineS2, &fe_cineS2},
1930 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
1931 .lnb = {0x0b, 0x08},
1932 .tsf = {3, 3},
1933 .fw_version = 15,
1934};
1935
1936/****************************************************************************/
1937
1938
1939
1940/****************************************************************************/
1941/* PCI Subsystem ID *********************************************************/
1942/****************************************************************************/
1943
1944#define NGENE_ID(_subvend, _subdev, _driverdata) { \
1945 .vendor = NGENE_VID, .device = NGENE_PID, \
1946 .subvendor = _subvend, .subdevice = _subdev, \
1947 .driver_data = (unsigned long) &_driverdata }
1948
1949/****************************************************************************/
1950
1951static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
1952 NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
1953 NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
1954 NGENE_ID(0x18c3, 0xdb01, ngene_info_satixs2),
1955 {0}
1956};
1957MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
1958
1959/****************************************************************************/
1960/* Init/Exit ****************************************************************/
1961/****************************************************************************/
1962
1963static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
1964 enum pci_channel_state state)
1965{
1966 printk(KERN_ERR DEVICE_NAME ": PCI error\n");
1967 if (state == pci_channel_io_perm_failure)
1968 return PCI_ERS_RESULT_DISCONNECT;
1969 if (state == pci_channel_io_frozen)
1970 return PCI_ERS_RESULT_NEED_RESET;
1971 return PCI_ERS_RESULT_CAN_RECOVER;
1972}
1973
1974static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
1975{
1976 printk(KERN_INFO DEVICE_NAME ": link reset\n");
1977 return 0;
1978}
1979
1980static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
1981{
1982 printk(KERN_INFO DEVICE_NAME ": slot reset\n");
1983 return 0;
1984}
1985
1986static void ngene_resume(struct pci_dev *dev)
1987{
1988 printk(KERN_INFO DEVICE_NAME ": resume\n");
1989}
1990
1991static struct pci_error_handlers ngene_errors = {
1992 .error_detected = ngene_error_detected,
1993 .link_reset = ngene_link_reset,
1994 .slot_reset = ngene_slot_reset,
1995 .resume = ngene_resume,
1996};
1997
1998static struct pci_driver ngene_pci_driver = {
1999 .name = "ngene",
2000 .id_table = ngene_id_tbl,
2001 .probe = ngene_probe,
2002 .remove = __devexit_p(ngene_remove),
2003 .err_handler = &ngene_errors,
2004};
2005
2006static __init int module_init_ngene(void)
2007{
2008 printk(KERN_INFO
2009 "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
2010 return pci_register_driver(&ngene_pci_driver);
2011}
2012
2013static __exit void module_exit_ngene(void)
2014{
2015 pci_unregister_driver(&ngene_pci_driver);
2016}
2017
2018module_init(module_init_ngene);
2019module_exit(module_exit_ngene);
2020
2021MODULE_DESCRIPTION("nGene");
2022MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
2023MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c
new file mode 100644
index 000000000000..96013eb353cd
--- /dev/null
+++ b/drivers/media/dvb/ngene/ngene-dvb.c
@@ -0,0 +1,172 @@
1/*
2 * ngene-dvb.c: nGene PCIe bridge driver - DVB functions
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
7 * Modifications for new nGene firmware,
8 * support for EEPROM-copying,
9 * support for new dual DVB-S2 card prototype
10 *
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 only, as published by the Free Software Foundation.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * 02110-1301, USA
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/slab.h>
34#include <linux/poll.h>
35#include <linux/io.h>
36#include <asm/div64.h>
37#include <linux/pci.h>
38#include <linux/smp_lock.h>
39#include <linux/timer.h>
40#include <linux/version.h>
41#include <linux/byteorder/generic.h>
42#include <linux/firmware.h>
43#include <linux/vmalloc.h>
44
45#include "ngene.h"
46
47#define COMMAND_TIMEOUT_WORKAROUND
48
49
50/****************************************************************************/
51/* COMMAND API interface ****************************************************/
52/****************************************************************************/
53
54/****************************************************************************/
55/* DVB functions and API interface ******************************************/
56/****************************************************************************/
57
58static void swap_buffer(u32 *p, u32 len)
59{
60 while (len) {
61 *p = swab32(*p);
62 p++;
63 len -= 4;
64 }
65}
66
67void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
68{
69 struct ngene_channel *chan = priv;
70
71
72#ifdef COMMAND_TIMEOUT_WORKAROUND
73 if (chan->users > 0)
74#endif
75 dvb_dmx_swfilter(&chan->demux, buf, len);
76 return NULL;
77}
78
79u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 };
80
81void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
82{
83 struct ngene_channel *chan = priv;
84 struct ngene *dev = chan->dev;
85 u32 alen;
86
87 alen = dvb_ringbuffer_avail(&dev->tsout_rbuf);
88 alen -= alen % 188;
89
90 if (alen < len)
91 FillTSBuffer(buf + alen, len - alen, flags);
92 else
93 alen = len;
94 dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen);
95 if (flags & DF_SWAP32)
96 swap_buffer((u32 *)buf, alen);
97 wake_up_interruptible(&dev->tsout_rbuf.queue);
98 return buf;
99}
100
101
102
103int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
104{
105 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
106 struct ngene_channel *chan = dvbdmx->priv;
107
108 if (chan->users == 0) {
109#ifdef COMMAND_TIMEOUT_WORKAROUND
110 if (!chan->running)
111#endif
112 set_transfer(chan, 1);
113 /* msleep(10); */
114 }
115
116 return ++chan->users;
117}
118
119int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
120{
121 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
122 struct ngene_channel *chan = dvbdmx->priv;
123
124 if (--chan->users)
125 return chan->users;
126
127#ifndef COMMAND_TIMEOUT_WORKAROUND
128 set_transfer(chan, 0);
129#endif
130
131 return 0;
132}
133
134int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
135 int (*start_feed)(struct dvb_demux_feed *),
136 int (*stop_feed)(struct dvb_demux_feed *),
137 void *priv)
138{
139 dvbdemux->priv = priv;
140
141 dvbdemux->filternum = 256;
142 dvbdemux->feednum = 256;
143 dvbdemux->start_feed = start_feed;
144 dvbdemux->stop_feed = stop_feed;
145 dvbdemux->write_to_decoder = NULL;
146 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
147 DMX_SECTION_FILTERING |
148 DMX_MEMORY_BASED_FILTERING);
149 return dvb_dmx_init(dvbdemux);
150}
151
152int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
153 struct dvb_demux *dvbdemux,
154 struct dmx_frontend *hw_frontend,
155 struct dmx_frontend *mem_frontend,
156 struct dvb_adapter *dvb_adapter)
157{
158 int ret;
159
160 dmxdev->filternum = 256;
161 dmxdev->demux = &dvbdemux->dmx;
162 dmxdev->capabilities = 0;
163 ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
164 if (ret < 0)
165 return ret;
166
167 hw_frontend->source = DMX_FRONTEND_0;
168 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
169 mem_frontend->source = DMX_MEMORY_FE;
170 dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
171 return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
172}
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c
new file mode 100644
index 000000000000..2ef54ca6badd
--- /dev/null
+++ b/drivers/media/dvb/ngene/ngene-i2c.c
@@ -0,0 +1,179 @@
1/*
2 * ngene-i2c.c: nGene PCIe bridge driver i2c functions
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
7 * Modifications for new nGene firmware,
8 * support for EEPROM-copying,
9 * support for new dual DVB-S2 card prototype
10 *
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 only, as published by the Free Software Foundation.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * 02110-1301, USA
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 */
29
30/* FIXME - some of these can probably be removed */
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/io.h>
37#include <asm/div64.h>
38#include <linux/pci.h>
39#include <linux/pci_ids.h>
40#include <linux/smp_lock.h>
41#include <linux/timer.h>
42#include <linux/version.h>
43#include <linux/byteorder/generic.h>
44#include <linux/firmware.h>
45#include <linux/vmalloc.h>
46
47#include "ngene.h"
48
49/* Firmware command for i2c operations */
50static int ngene_command_i2c_read(struct ngene *dev, u8 adr,
51 u8 *out, u8 outlen, u8 *in, u8 inlen, int flag)
52{
53 struct ngene_command com;
54
55 com.cmd.hdr.Opcode = CMD_I2C_READ;
56 com.cmd.hdr.Length = outlen + 3;
57 com.cmd.I2CRead.Device = adr << 1;
58 memcpy(com.cmd.I2CRead.Data, out, outlen);
59 com.cmd.I2CRead.Data[outlen] = inlen;
60 com.cmd.I2CRead.Data[outlen + 1] = 0;
61 com.in_len = outlen + 3;
62 com.out_len = inlen + 1;
63
64 if (ngene_command(dev, &com) < 0)
65 return -EIO;
66
67 if ((com.cmd.raw8[0] >> 1) != adr)
68 return -EIO;
69
70 if (flag)
71 memcpy(in, com.cmd.raw8, inlen + 1);
72 else
73 memcpy(in, com.cmd.raw8 + 1, inlen);
74 return 0;
75}
76
77static int ngene_command_i2c_write(struct ngene *dev, u8 adr,
78 u8 *out, u8 outlen)
79{
80 struct ngene_command com;
81
82
83 com.cmd.hdr.Opcode = CMD_I2C_WRITE;
84 com.cmd.hdr.Length = outlen + 1;
85 com.cmd.I2CRead.Device = adr << 1;
86 memcpy(com.cmd.I2CRead.Data, out, outlen);
87 com.in_len = outlen + 1;
88 com.out_len = 1;
89
90 if (ngene_command(dev, &com) < 0)
91 return -EIO;
92
93 if (com.cmd.raw8[0] == 1)
94 return -EIO;
95
96 return 0;
97}
98
99static void ngene_i2c_set_bus(struct ngene *dev, int bus)
100{
101 if (!(dev->card_info->i2c_access & 2))
102 return;
103 if (dev->i2c_current_bus == bus)
104 return;
105
106 switch (bus) {
107 case 0:
108 ngene_command_gpio_set(dev, 3, 0);
109 ngene_command_gpio_set(dev, 2, 1);
110 break;
111
112 case 1:
113 ngene_command_gpio_set(dev, 2, 0);
114 ngene_command_gpio_set(dev, 3, 1);
115 break;
116 }
117 dev->i2c_current_bus = bus;
118}
119
120static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
121 struct i2c_msg msg[], int num)
122{
123 struct ngene_channel *chan =
124 (struct ngene_channel *)i2c_get_adapdata(adapter);
125 struct ngene *dev = chan->dev;
126
127 down(&dev->i2c_switch_mutex);
128 ngene_i2c_set_bus(dev, chan->number);
129
130 if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
131 if (!ngene_command_i2c_read(dev, msg[0].addr,
132 msg[0].buf, msg[0].len,
133 msg[1].buf, msg[1].len, 0))
134 goto done;
135
136 if (num == 1 && !(msg[0].flags & I2C_M_RD))
137 if (!ngene_command_i2c_write(dev, msg[0].addr,
138 msg[0].buf, msg[0].len))
139 goto done;
140 if (num == 1 && (msg[0].flags & I2C_M_RD))
141 if (!ngene_command_i2c_read(dev, msg[0].addr, NULL, 0,
142 msg[0].buf, msg[0].len, 0))
143 goto done;
144
145 up(&dev->i2c_switch_mutex);
146 return -EIO;
147
148done:
149 up(&dev->i2c_switch_mutex);
150 return num;
151}
152
153
154static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
155{
156 return I2C_FUNC_SMBUS_EMUL;
157}
158
159static struct i2c_algorithm ngene_i2c_algo = {
160 .master_xfer = ngene_i2c_master_xfer,
161 .functionality = ngene_i2c_functionality,
162};
163
164int ngene_i2c_init(struct ngene *dev, int dev_nr)
165{
166 struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
167
168 i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
169 adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
170
171 strcpy(adap->name, "nGene");
172
173 adap->algo = &ngene_i2c_algo;
174 adap->algo_data = (void *)&(dev->channel[dev_nr]);
175 adap->dev.parent = &dev->pci_dev->dev;
176
177 return i2c_add_adapter(adap);
178}
179
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h
index a7eb29846310..676fcbb79026 100644
--- a/drivers/media/dvb/ngene/ngene.h
+++ b/drivers/media/dvb/ngene/ngene.h
@@ -39,6 +39,8 @@
39#include "dvb_frontend.h" 39#include "dvb_frontend.h"
40#include "dvb_ringbuffer.h" 40#include "dvb_ringbuffer.h"
41 41
42#define DEVICE_NAME "ngene"
43
42#define NGENE_VID 0x18c3 44#define NGENE_VID 0x18c3
43#define NGENE_PID 0x0720 45#define NGENE_PID 0x0720
44 46
@@ -752,6 +754,7 @@ struct ngene {
752 spinlock_t cmd_lock; 754 spinlock_t cmd_lock;
753 755
754 struct dvb_adapter adapter[MAX_STREAM]; 756 struct dvb_adapter adapter[MAX_STREAM];
757 struct dvb_adapter *first_adapter; /* "one_adapter" modprobe opt */
755 struct ngene_channel channel[MAX_STREAM]; 758 struct ngene_channel channel[MAX_STREAM];
756 759
757 struct ngene_info *card_info; 760 struct ngene_info *card_info;
@@ -853,6 +856,33 @@ struct ngene_buffer {
853#endif 856#endif
854 857
855 858
859/* Provided by ngene-core.c */
860int __devinit ngene_probe(struct pci_dev *pci_dev,
861 const struct pci_device_id *id);
862void __devexit ngene_remove(struct pci_dev *pdev);
863int ngene_command(struct ngene *dev, struct ngene_command *com);
864int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level);
865void set_transfer(struct ngene_channel *chan, int state);
866void FillTSBuffer(void *Buffer, int Length, u32 Flags);
867
868/* Provided by ngene-i2c.c */
869int ngene_i2c_init(struct ngene *dev, int dev_nr);
870
871/* Provided by ngene-dvb.c */
872void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
873void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
874int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed);
875int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
876int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
877 int (*start_feed)(struct dvb_demux_feed *),
878 int (*stop_feed)(struct dvb_demux_feed *),
879 void *priv);
880int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
881 struct dvb_demux *dvbdemux,
882 struct dmx_frontend *hw_frontend,
883 struct dmx_frontend *mem_frontend,
884 struct dvb_adapter *dvb_adapter);
885
856#endif 886#endif
857 887
858/* LocalWords: Endif 888/* LocalWords: Endif
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 6aded234aa61..69ad94934ec2 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * driver for Earthsoft PT1 2 * driver for Earthsoft PT1/PT2
3 * 3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> 4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 * 5 *
@@ -77,6 +77,10 @@ struct pt1 {
77 struct pt1_adapter *adaps[PT1_NR_ADAPS]; 77 struct pt1_adapter *adaps[PT1_NR_ADAPS];
78 struct pt1_table *tables; 78 struct pt1_table *tables;
79 struct task_struct *kthread; 79 struct task_struct *kthread;
80
81 struct mutex lock;
82 int power;
83 int reset;
80}; 84};
81 85
82struct pt1_adapter { 86struct pt1_adapter {
@@ -95,6 +99,11 @@ struct pt1_adapter {
95 struct dvb_frontend *fe; 99 struct dvb_frontend *fe;
96 int (*orig_set_voltage)(struct dvb_frontend *fe, 100 int (*orig_set_voltage)(struct dvb_frontend *fe,
97 fe_sec_voltage_t voltage); 101 fe_sec_voltage_t voltage);
102 int (*orig_sleep)(struct dvb_frontend *fe);
103 int (*orig_init)(struct dvb_frontend *fe);
104
105 fe_sec_voltage_t voltage;
106 int sleep;
98}; 107};
99 108
100#define pt1_printk(level, pt1, format, arg...) \ 109#define pt1_printk(level, pt1, format, arg...) \
@@ -219,8 +228,10 @@ static int pt1_do_enable_ram(struct pt1 *pt1)
219static int pt1_enable_ram(struct pt1 *pt1) 228static int pt1_enable_ram(struct pt1 *pt1)
220{ 229{
221 int i, ret; 230 int i, ret;
231 int phase;
222 schedule_timeout_uninterruptible((HZ + 999) / 1000); 232 schedule_timeout_uninterruptible((HZ + 999) / 1000);
223 for (i = 0; i < 10; i++) { 233 phase = pt1->pdev->device == 0x211a ? 128 : 166;
234 for (i = 0; i < phase; i++) {
224 ret = pt1_do_enable_ram(pt1); 235 ret = pt1_do_enable_ram(pt1);
225 if (ret < 0) 236 if (ret < 0)
226 return ret; 237 return ret;
@@ -485,33 +496,47 @@ static int pt1_stop_feed(struct dvb_demux_feed *feed)
485} 496}
486 497
487static void 498static void
488pt1_set_power(struct pt1 *pt1, int power, int lnb, int reset) 499pt1_update_power(struct pt1 *pt1)
489{ 500{
490 pt1_write_reg(pt1, 1, power | lnb << 1 | !reset << 3); 501 int bits;
502 int i;
503 struct pt1_adapter *adap;
504 static const int sleep_bits[] = {
505 1 << 4,
506 1 << 6 | 1 << 7,
507 1 << 5,
508 1 << 6 | 1 << 8,
509 };
510
511 bits = pt1->power | !pt1->reset << 3;
512 mutex_lock(&pt1->lock);
513 for (i = 0; i < PT1_NR_ADAPS; i++) {
514 adap = pt1->adaps[i];
515 switch (adap->voltage) {
516 case SEC_VOLTAGE_13: /* actually 11V */
517 bits |= 1 << 1;
518 break;
519 case SEC_VOLTAGE_18: /* actually 15V */
520 bits |= 1 << 1 | 1 << 2;
521 break;
522 default:
523 break;
524 }
525
526 /* XXX: The bits should be changed depending on adap->sleep. */
527 bits |= sleep_bits[i];
528 }
529 pt1_write_reg(pt1, 1, bits);
530 mutex_unlock(&pt1->lock);
491} 531}
492 532
493static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 533static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
494{ 534{
495 struct pt1_adapter *adap; 535 struct pt1_adapter *adap;
496 int lnb;
497 536
498 adap = container_of(fe->dvb, struct pt1_adapter, adap); 537 adap = container_of(fe->dvb, struct pt1_adapter, adap);
499 538 adap->voltage = voltage;
500 switch (voltage) { 539 pt1_update_power(adap->pt1);
501 case SEC_VOLTAGE_13: /* actually 11V */
502 lnb = 2;
503 break;
504 case SEC_VOLTAGE_18: /* actually 15V */
505 lnb = 3;
506 break;
507 case SEC_VOLTAGE_OFF:
508 lnb = 0;
509 break;
510 default:
511 return -EINVAL;
512 }
513
514 pt1_set_power(adap->pt1, 1, lnb, 0);
515 540
516 if (adap->orig_set_voltage) 541 if (adap->orig_set_voltage)
517 return adap->orig_set_voltage(fe, voltage); 542 return adap->orig_set_voltage(fe, voltage);
@@ -519,9 +544,37 @@ static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
519 return 0; 544 return 0;
520} 545}
521 546
547static int pt1_sleep(struct dvb_frontend *fe)
548{
549 struct pt1_adapter *adap;
550
551 adap = container_of(fe->dvb, struct pt1_adapter, adap);
552 adap->sleep = 1;
553 pt1_update_power(adap->pt1);
554
555 if (adap->orig_sleep)
556 return adap->orig_sleep(fe);
557 else
558 return 0;
559}
560
561static int pt1_wakeup(struct dvb_frontend *fe)
562{
563 struct pt1_adapter *adap;
564
565 adap = container_of(fe->dvb, struct pt1_adapter, adap);
566 adap->sleep = 0;
567 pt1_update_power(adap->pt1);
568 schedule_timeout_uninterruptible((HZ + 999) / 1000);
569
570 if (adap->orig_init)
571 return adap->orig_init(fe);
572 else
573 return 0;
574}
575
522static void pt1_free_adapter(struct pt1_adapter *adap) 576static void pt1_free_adapter(struct pt1_adapter *adap)
523{ 577{
524 dvb_unregister_frontend(adap->fe);
525 dvb_net_release(&adap->net); 578 dvb_net_release(&adap->net);
526 adap->demux.dmx.close(&adap->demux.dmx); 579 adap->demux.dmx.close(&adap->demux.dmx);
527 dvb_dmxdev_release(&adap->dmxdev); 580 dvb_dmxdev_release(&adap->dmxdev);
@@ -534,7 +587,7 @@ static void pt1_free_adapter(struct pt1_adapter *adap)
534DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 587DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
535 588
536static struct pt1_adapter * 589static struct pt1_adapter *
537pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe) 590pt1_alloc_adapter(struct pt1 *pt1)
538{ 591{
539 struct pt1_adapter *adap; 592 struct pt1_adapter *adap;
540 void *buf; 593 void *buf;
@@ -551,8 +604,8 @@ pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe)
551 604
552 adap->pt1 = pt1; 605 adap->pt1 = pt1;
553 606
554 adap->orig_set_voltage = fe->ops.set_voltage; 607 adap->voltage = SEC_VOLTAGE_OFF;
555 fe->ops.set_voltage = pt1_set_voltage; 608 adap->sleep = 1;
556 609
557 buf = (u8 *)__get_free_page(GFP_KERNEL); 610 buf = (u8 *)__get_free_page(GFP_KERNEL);
558 if (!buf) { 611 if (!buf) {
@@ -593,17 +646,8 @@ pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe)
593 646
594 dvb_net_init(dvb_adap, &adap->net, &demux->dmx); 647 dvb_net_init(dvb_adap, &adap->net, &demux->dmx);
595 648
596 ret = dvb_register_frontend(dvb_adap, fe);
597 if (ret < 0)
598 goto err_net_release;
599 adap->fe = fe;
600
601 return adap; 649 return adap;
602 650
603err_net_release:
604 dvb_net_release(&adap->net);
605 adap->demux.dmx.close(&adap->demux.dmx);
606 dvb_dmxdev_release(&adap->dmxdev);
607err_dmx_release: 651err_dmx_release:
608 dvb_dmx_release(demux); 652 dvb_dmx_release(demux);
609err_unregister_adapter: 653err_unregister_adapter:
@@ -623,6 +667,62 @@ static void pt1_cleanup_adapters(struct pt1 *pt1)
623 pt1_free_adapter(pt1->adaps[i]); 667 pt1_free_adapter(pt1->adaps[i]);
624} 668}
625 669
670static int pt1_init_adapters(struct pt1 *pt1)
671{
672 int i;
673 struct pt1_adapter *adap;
674 int ret;
675
676 for (i = 0; i < PT1_NR_ADAPS; i++) {
677 adap = pt1_alloc_adapter(pt1);
678 if (IS_ERR(adap)) {
679 ret = PTR_ERR(adap);
680 goto err;
681 }
682
683 adap->index = i;
684 pt1->adaps[i] = adap;
685 }
686 return 0;
687
688err:
689 while (i--)
690 pt1_free_adapter(pt1->adaps[i]);
691
692 return ret;
693}
694
695static void pt1_cleanup_frontend(struct pt1_adapter *adap)
696{
697 dvb_unregister_frontend(adap->fe);
698}
699
700static int pt1_init_frontend(struct pt1_adapter *adap, struct dvb_frontend *fe)
701{
702 int ret;
703
704 adap->orig_set_voltage = fe->ops.set_voltage;
705 adap->orig_sleep = fe->ops.sleep;
706 adap->orig_init = fe->ops.init;
707 fe->ops.set_voltage = pt1_set_voltage;
708 fe->ops.sleep = pt1_sleep;
709 fe->ops.init = pt1_wakeup;
710
711 ret = dvb_register_frontend(&adap->adap, fe);
712 if (ret < 0)
713 return ret;
714
715 adap->fe = fe;
716 return 0;
717}
718
719static void pt1_cleanup_frontends(struct pt1 *pt1)
720{
721 int i;
722 for (i = 0; i < PT1_NR_ADAPS; i++)
723 pt1_cleanup_frontend(pt1->adaps[i]);
724}
725
626struct pt1_config { 726struct pt1_config {
627 struct va1j5jf8007s_config va1j5jf8007s_config; 727 struct va1j5jf8007s_config va1j5jf8007s_config;
628 struct va1j5jf8007t_config va1j5jf8007t_config; 728 struct va1j5jf8007t_config va1j5jf8007t_config;
@@ -630,29 +730,63 @@ struct pt1_config {
630 730
631static const struct pt1_config pt1_configs[2] = { 731static const struct pt1_config pt1_configs[2] = {
632 { 732 {
633 { .demod_address = 0x1b }, 733 {
634 { .demod_address = 0x1a }, 734 .demod_address = 0x1b,
735 .frequency = VA1J5JF8007S_20MHZ,
736 },
737 {
738 .demod_address = 0x1a,
739 .frequency = VA1J5JF8007T_20MHZ,
740 },
635 }, { 741 }, {
636 { .demod_address = 0x19 }, 742 {
637 { .demod_address = 0x18 }, 743 .demod_address = 0x19,
744 .frequency = VA1J5JF8007S_20MHZ,
745 },
746 {
747 .demod_address = 0x18,
748 .frequency = VA1J5JF8007T_20MHZ,
749 },
638 }, 750 },
639}; 751};
640 752
641static int pt1_init_adapters(struct pt1 *pt1) 753static const struct pt1_config pt2_configs[2] = {
754 {
755 {
756 .demod_address = 0x1b,
757 .frequency = VA1J5JF8007S_25MHZ,
758 },
759 {
760 .demod_address = 0x1a,
761 .frequency = VA1J5JF8007T_25MHZ,
762 },
763 }, {
764 {
765 .demod_address = 0x19,
766 .frequency = VA1J5JF8007S_25MHZ,
767 },
768 {
769 .demod_address = 0x18,
770 .frequency = VA1J5JF8007T_25MHZ,
771 },
772 },
773};
774
775static int pt1_init_frontends(struct pt1 *pt1)
642{ 776{
643 int i, j; 777 int i, j;
644 struct i2c_adapter *i2c_adap; 778 struct i2c_adapter *i2c_adap;
645 const struct pt1_config *config; 779 const struct pt1_config *configs, *config;
646 struct dvb_frontend *fe[4]; 780 struct dvb_frontend *fe[4];
647 struct pt1_adapter *adap;
648 int ret; 781 int ret;
649 782
650 i = 0; 783 i = 0;
651 j = 0; 784 j = 0;
652 785
653 i2c_adap = &pt1->i2c_adap; 786 i2c_adap = &pt1->i2c_adap;
787 configs = pt1->pdev->device == 0x211a ? pt1_configs : pt2_configs;
654 do { 788 do {
655 config = &pt1_configs[i / 2]; 789 config = &configs[i / 2];
656 790
657 fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config, 791 fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config,
658 i2c_adap); 792 i2c_adap);
@@ -681,11 +815,9 @@ static int pt1_init_adapters(struct pt1 *pt1)
681 } while (i < 4); 815 } while (i < 4);
682 816
683 do { 817 do {
684 adap = pt1_alloc_adapter(pt1, fe[j]); 818 ret = pt1_init_frontend(pt1->adaps[j], fe[j]);
685 if (IS_ERR(adap)) 819 if (ret < 0)
686 goto err; 820 goto err;
687 adap->index = j;
688 pt1->adaps[j] = adap;
689 } while (++j < 4); 821 } while (++j < 4);
690 822
691 return 0; 823 return 0;
@@ -695,7 +827,7 @@ err:
695 fe[i]->ops.release(fe[i]); 827 fe[i]->ops.release(fe[i]);
696 828
697 while (j--) 829 while (j--)
698 pt1_free_adapter(pt1->adaps[j]); 830 dvb_unregister_frontend(fe[j]);
699 831
700 return ret; 832 return ret;
701} 833}
@@ -890,9 +1022,12 @@ static void __devexit pt1_remove(struct pci_dev *pdev)
890 1022
891 kthread_stop(pt1->kthread); 1023 kthread_stop(pt1->kthread);
892 pt1_cleanup_tables(pt1); 1024 pt1_cleanup_tables(pt1);
893 pt1_cleanup_adapters(pt1); 1025 pt1_cleanup_frontends(pt1);
894 pt1_disable_ram(pt1); 1026 pt1_disable_ram(pt1);
895 pt1_set_power(pt1, 0, 0, 1); 1027 pt1->power = 0;
1028 pt1->reset = 1;
1029 pt1_update_power(pt1);
1030 pt1_cleanup_adapters(pt1);
896 i2c_del_adapter(&pt1->i2c_adap); 1031 i2c_del_adapter(&pt1->i2c_adap);
897 pci_set_drvdata(pdev, NULL); 1032 pci_set_drvdata(pdev, NULL);
898 kfree(pt1); 1033 kfree(pt1);
@@ -936,10 +1071,21 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
936 goto err_pci_iounmap; 1071 goto err_pci_iounmap;
937 } 1072 }
938 1073
1074 mutex_init(&pt1->lock);
939 pt1->pdev = pdev; 1075 pt1->pdev = pdev;
940 pt1->regs = regs; 1076 pt1->regs = regs;
941 pci_set_drvdata(pdev, pt1); 1077 pci_set_drvdata(pdev, pt1);
942 1078
1079 ret = pt1_init_adapters(pt1);
1080 if (ret < 0)
1081 goto err_kfree;
1082
1083 mutex_init(&pt1->lock);
1084
1085 pt1->power = 0;
1086 pt1->reset = 1;
1087 pt1_update_power(pt1);
1088
943 i2c_adap = &pt1->i2c_adap; 1089 i2c_adap = &pt1->i2c_adap;
944 i2c_adap->class = I2C_CLASS_TV_DIGITAL; 1090 i2c_adap->class = I2C_CLASS_TV_DIGITAL;
945 i2c_adap->algo = &pt1_i2c_algo; 1091 i2c_adap->algo = &pt1_i2c_algo;
@@ -948,9 +1094,7 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
948 i2c_set_adapdata(i2c_adap, pt1); 1094 i2c_set_adapdata(i2c_adap, pt1);
949 ret = i2c_add_adapter(i2c_adap); 1095 ret = i2c_add_adapter(i2c_adap);
950 if (ret < 0) 1096 if (ret < 0)
951 goto err_kfree; 1097 goto err_pt1_cleanup_adapters;
952
953 pt1_set_power(pt1, 0, 0, 1);
954 1098
955 pt1_i2c_init(pt1); 1099 pt1_i2c_init(pt1);
956 pt1_i2c_wait(pt1); 1100 pt1_i2c_wait(pt1);
@@ -979,19 +1123,21 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
979 1123
980 pt1_init_streams(pt1); 1124 pt1_init_streams(pt1);
981 1125
982 pt1_set_power(pt1, 1, 0, 1); 1126 pt1->power = 1;
1127 pt1_update_power(pt1);
983 schedule_timeout_uninterruptible((HZ + 49) / 50); 1128 schedule_timeout_uninterruptible((HZ + 49) / 50);
984 1129
985 pt1_set_power(pt1, 1, 0, 0); 1130 pt1->reset = 0;
1131 pt1_update_power(pt1);
986 schedule_timeout_uninterruptible((HZ + 999) / 1000); 1132 schedule_timeout_uninterruptible((HZ + 999) / 1000);
987 1133
988 ret = pt1_init_adapters(pt1); 1134 ret = pt1_init_frontends(pt1);
989 if (ret < 0) 1135 if (ret < 0)
990 goto err_pt1_disable_ram; 1136 goto err_pt1_disable_ram;
991 1137
992 ret = pt1_init_tables(pt1); 1138 ret = pt1_init_tables(pt1);
993 if (ret < 0) 1139 if (ret < 0)
994 goto err_pt1_cleanup_adapters; 1140 goto err_pt1_cleanup_frontends;
995 1141
996 kthread = kthread_run(pt1_thread, pt1, "pt1"); 1142 kthread = kthread_run(pt1_thread, pt1, "pt1");
997 if (IS_ERR(kthread)) { 1143 if (IS_ERR(kthread)) {
@@ -1004,11 +1150,15 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1004 1150
1005err_pt1_cleanup_tables: 1151err_pt1_cleanup_tables:
1006 pt1_cleanup_tables(pt1); 1152 pt1_cleanup_tables(pt1);
1007err_pt1_cleanup_adapters: 1153err_pt1_cleanup_frontends:
1008 pt1_cleanup_adapters(pt1); 1154 pt1_cleanup_frontends(pt1);
1009err_pt1_disable_ram: 1155err_pt1_disable_ram:
1010 pt1_disable_ram(pt1); 1156 pt1_disable_ram(pt1);
1011 pt1_set_power(pt1, 0, 0, 1); 1157 pt1->power = 0;
1158 pt1->reset = 1;
1159 pt1_update_power(pt1);
1160err_pt1_cleanup_adapters:
1161 pt1_cleanup_adapters(pt1);
1012err_i2c_del_adapter: 1162err_i2c_del_adapter:
1013 i2c_del_adapter(i2c_adap); 1163 i2c_del_adapter(i2c_adap);
1014err_kfree: 1164err_kfree:
@@ -1027,6 +1177,7 @@ err:
1027 1177
1028static struct pci_device_id pt1_id_table[] = { 1178static struct pci_device_id pt1_id_table[] = {
1029 { PCI_DEVICE(0x10ee, 0x211a) }, 1179 { PCI_DEVICE(0x10ee, 0x211a) },
1180 { PCI_DEVICE(0x10ee, 0x222a) },
1030 { }, 1181 { },
1031}; 1182};
1032MODULE_DEVICE_TABLE(pci, pt1_id_table); 1183MODULE_DEVICE_TABLE(pci, pt1_id_table);
@@ -1054,5 +1205,5 @@ module_init(pt1_init);
1054module_exit(pt1_cleanup); 1205module_exit(pt1_cleanup);
1055 1206
1056MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>"); 1207MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
1057MODULE_DESCRIPTION("Earthsoft PT1 Driver"); 1208MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver");
1058MODULE_LICENSE("GPL"); 1209MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
index fc6594996e79..451641c0c1d2 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007s.c
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ISDB-S driver for VA1J5JF8007 2 * ISDB-S driver for VA1J5JF8007/VA1J5JF8011
3 * 3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> 4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 * 5 *
@@ -580,7 +580,7 @@ static void va1j5jf8007s_release(struct dvb_frontend *fe)
580 580
581static struct dvb_frontend_ops va1j5jf8007s_ops = { 581static struct dvb_frontend_ops va1j5jf8007s_ops = {
582 .info = { 582 .info = {
583 .name = "VA1J5JF8007 ISDB-S", 583 .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S",
584 .type = FE_QPSK, 584 .type = FE_QPSK,
585 .frequency_min = 950000, 585 .frequency_min = 950000,
586 .frequency_max = 2150000, 586 .frequency_max = 2150000,
@@ -628,28 +628,50 @@ static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
628 return 0; 628 return 0;
629} 629}
630 630
631static const u8 va1j5jf8007s_prepare_bufs[][2] = { 631static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = {
632 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, 632 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
633 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, 633 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
634 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, 634 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
635 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0}, 635 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
636}; 636};
637 637
638static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = {
639 {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
640 {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
641 {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
642 {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
643};
644
638static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state) 645static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
639{ 646{
647 const u8 (*bufs)[2];
648 int size;
640 u8 addr; 649 u8 addr;
641 u8 buf[2]; 650 u8 buf[2];
642 struct i2c_msg msg; 651 struct i2c_msg msg;
643 int i; 652 int i;
644 653
654 switch (state->config->frequency) {
655 case VA1J5JF8007S_20MHZ:
656 bufs = va1j5jf8007s_20mhz_prepare_bufs;
657 size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs);
658 break;
659 case VA1J5JF8007S_25MHZ:
660 bufs = va1j5jf8007s_25mhz_prepare_bufs;
661 size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs);
662 break;
663 default:
664 return -EINVAL;
665 }
666
645 addr = state->config->demod_address; 667 addr = state->config->demod_address;
646 668
647 msg.addr = addr; 669 msg.addr = addr;
648 msg.flags = 0; 670 msg.flags = 0;
649 msg.len = 2; 671 msg.len = 2;
650 msg.buf = buf; 672 msg.buf = buf;
651 for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_prepare_bufs); i++) { 673 for (i = 0; i < size; i++) {
652 memcpy(buf, va1j5jf8007s_prepare_bufs[i], sizeof(buf)); 674 memcpy(buf, bufs[i], sizeof(buf));
653 if (i2c_transfer(state->adap, &msg, 1) != 1) 675 if (i2c_transfer(state->adap, &msg, 1) != 1)
654 return -EREMOTEIO; 676 return -EREMOTEIO;
655 } 677 }
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h
index aa228a816353..b7d6f05a0e02 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007s.h
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * ISDB-S driver for VA1J5JF8007 2 * ISDB-S driver for VA1J5JF8007/VA1J5JF8011
3 * 3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> 4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 * 5 *
@@ -24,8 +24,14 @@
24#ifndef VA1J5JF8007S_H 24#ifndef VA1J5JF8007S_H
25#define VA1J5JF8007S_H 25#define VA1J5JF8007S_H
26 26
27enum va1j5jf8007s_frequency {
28 VA1J5JF8007S_20MHZ,
29 VA1J5JF8007S_25MHZ,
30};
31
27struct va1j5jf8007s_config { 32struct va1j5jf8007s_config {
28 u8 demod_address; 33 u8 demod_address;
34 enum va1j5jf8007s_frequency frequency;
29}; 35};
30 36
31struct i2c_adapter; 37struct i2c_adapter;
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
index 3db4f3e34e8f..0f085c3e571b 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007t.c
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ISDB-T driver for VA1J5JF8007 2 * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
3 * 3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> 4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 * 5 *
@@ -429,7 +429,7 @@ static void va1j5jf8007t_release(struct dvb_frontend *fe)
429 429
430static struct dvb_frontend_ops va1j5jf8007t_ops = { 430static struct dvb_frontend_ops va1j5jf8007t_ops = {
431 .info = { 431 .info = {
432 .name = "VA1J5JF8007 ISDB-T", 432 .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T",
433 .type = FE_OFDM, 433 .type = FE_OFDM,
434 .frequency_min = 90000000, 434 .frequency_min = 90000000,
435 .frequency_max = 770000000, 435 .frequency_max = 770000000,
@@ -448,29 +448,50 @@ static struct dvb_frontend_ops va1j5jf8007t_ops = {
448 .release = va1j5jf8007t_release, 448 .release = va1j5jf8007t_release,
449}; 449};
450 450
451static const u8 va1j5jf8007t_prepare_bufs[][2] = { 451static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = {
452 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, 452 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
453 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00}, 453 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
454 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03}, 454 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
455 {0xef, 0x01} 455 {0xef, 0x01}
456}; 456};
457 457
458static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = {
459 {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83},
460 {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c},
461 {0x77, 0x03}, {0xef, 0x01}
462};
463
458int va1j5jf8007t_prepare(struct dvb_frontend *fe) 464int va1j5jf8007t_prepare(struct dvb_frontend *fe)
459{ 465{
460 struct va1j5jf8007t_state *state; 466 struct va1j5jf8007t_state *state;
467 const u8 (*bufs)[2];
468 int size;
461 u8 buf[2]; 469 u8 buf[2];
462 struct i2c_msg msg; 470 struct i2c_msg msg;
463 int i; 471 int i;
464 472
465 state = fe->demodulator_priv; 473 state = fe->demodulator_priv;
466 474
475 switch (state->config->frequency) {
476 case VA1J5JF8007T_20MHZ:
477 bufs = va1j5jf8007t_20mhz_prepare_bufs;
478 size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs);
479 break;
480 case VA1J5JF8007T_25MHZ:
481 bufs = va1j5jf8007t_25mhz_prepare_bufs;
482 size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs);
483 break;
484 default:
485 return -EINVAL;
486 }
487
467 msg.addr = state->config->demod_address; 488 msg.addr = state->config->demod_address;
468 msg.flags = 0; 489 msg.flags = 0;
469 msg.len = sizeof(buf); 490 msg.len = sizeof(buf);
470 msg.buf = buf; 491 msg.buf = buf;
471 492
472 for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_prepare_bufs); i++) { 493 for (i = 0; i < size; i++) {
473 memcpy(buf, va1j5jf8007t_prepare_bufs[i], sizeof(buf)); 494 memcpy(buf, bufs[i], sizeof(buf));
474 if (i2c_transfer(state->adap, &msg, 1) != 1) 495 if (i2c_transfer(state->adap, &msg, 1) != 1)
475 return -EREMOTEIO; 496 return -EREMOTEIO;
476 } 497 }
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h
index ed49906f7769..2903be519ef5 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007t.h
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * ISDB-T driver for VA1J5JF8007 2 * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
3 * 3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> 4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 * 5 *
@@ -24,8 +24,14 @@
24#ifndef VA1J5JF8007T_H 24#ifndef VA1J5JF8007T_H
25#define VA1J5JF8007T_H 25#define VA1J5JF8007T_H
26 26
27enum va1j5jf8007t_frequency {
28 VA1J5JF8007T_20MHZ,
29 VA1J5JF8007T_25MHZ,
30};
31
27struct va1j5jf8007t_config { 32struct va1j5jf8007t_config {
28 u8 demod_address; 33 u8 demod_address;
34 enum va1j5jf8007t_frequency frequency;
29}; 35};
30 36
31struct i2c_adapter; 37struct i2c_adapter;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 49c2a817a06f..461714396331 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -35,7 +35,7 @@
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/input.h> 36#include <linux/input.h>
37#include <linux/spinlock.h> 37#include <linux/spinlock.h>
38#include <media/ir-common.h> 38#include <media/ir-core.h>
39 39
40#include "budget.h" 40#include "budget.h"
41 41
@@ -54,6 +54,8 @@
54#include "tda1002x.h" 54#include "tda1002x.h"
55#include "tda827x.h" 55#include "tda827x.h"
56 56
57#define MODULE_NAME "budget_ci"
58
57/* 59/*
58 * Regarding DEBIADDR_IR: 60 * Regarding DEBIADDR_IR:
59 * Some CI modules hang if random addresses are read. 61 * Some CI modules hang if random addresses are read.
@@ -80,12 +82,6 @@
80#define SLOTSTATUS_READY 8 82#define SLOTSTATUS_READY 8
81#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) 83#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
82 84
83/*
84 * Milliseconds during which a key is regarded as pressed.
85 * If an identical command arrives within this time, the timer will start over.
86 */
87#define IR_KEYPRESS_TIMEOUT 250
88
89/* RC5 device wildcard */ 85/* RC5 device wildcard */
90#define IR_DEVICE_ANY 255 86#define IR_DEVICE_ANY 255
91 87
@@ -102,12 +98,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
102struct budget_ci_ir { 98struct budget_ci_ir {
103 struct input_dev *dev; 99 struct input_dev *dev;
104 struct tasklet_struct msp430_irq_tasklet; 100 struct tasklet_struct msp430_irq_tasklet;
105 struct timer_list timer_keyup;
106 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ 101 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
107 char phys[32]; 102 char phys[32];
108 struct ir_input_state state;
109 int rc5_device; 103 int rc5_device;
110 u32 last_raw;
111 u32 ir_key; 104 u32 ir_key;
112 bool have_command; 105 bool have_command;
113}; 106};
@@ -122,18 +115,11 @@ struct budget_ci {
122 u8 tuner_pll_address; /* used for philips_tdm1316l configs */ 115 u8 tuner_pll_address; /* used for philips_tdm1316l configs */
123}; 116};
124 117
125static void msp430_ir_keyup(unsigned long data)
126{
127 struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
128 ir_input_nokey(ir->dev, &ir->state);
129}
130
131static void msp430_ir_interrupt(unsigned long data) 118static void msp430_ir_interrupt(unsigned long data)
132{ 119{
133 struct budget_ci *budget_ci = (struct budget_ci *) data; 120 struct budget_ci *budget_ci = (struct budget_ci *) data;
134 struct input_dev *dev = budget_ci->ir.dev; 121 struct input_dev *dev = budget_ci->ir.dev;
135 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; 122 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
136 u32 raw;
137 123
138 /* 124 /*
139 * The msp430 chip can generate two different bytes, command and device 125 * The msp430 chip can generate two different bytes, command and device
@@ -169,20 +155,12 @@ static void msp430_ir_interrupt(unsigned long data)
169 return; 155 return;
170 budget_ci->ir.have_command = false; 156 budget_ci->ir.have_command = false;
171 157
158 /* FIXME: We should generate complete scancodes with device info */
172 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && 159 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
173 budget_ci->ir.rc5_device != (command & 0x1f)) 160 budget_ci->ir.rc5_device != (command & 0x1f))
174 return; 161 return;
175 162
176 /* Is this a repeated key sequence? (same device, command, toggle) */ 163 ir_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
177 raw = budget_ci->ir.ir_key | (command << 8);
178 if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
179 ir_input_nokey(dev, &budget_ci->ir.state);
180 ir_input_keydown(dev, &budget_ci->ir.state,
181 budget_ci->ir.ir_key);
182 budget_ci->ir.last_raw = raw;
183 }
184
185 mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
186} 164}
187 165
188static int msp430_ir_init(struct budget_ci *budget_ci) 166static int msp430_ir_init(struct budget_ci *budget_ci)
@@ -190,7 +168,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
190 struct saa7146_dev *saa = budget_ci->budget.dev; 168 struct saa7146_dev *saa = budget_ci->budget.dev;
191 struct input_dev *input_dev = budget_ci->ir.dev; 169 struct input_dev *input_dev = budget_ci->ir.dev;
192 int error; 170 int error;
193 struct ir_scancode_table *ir_codes; 171 char *ir_codes = NULL;
194 172
195 173
196 budget_ci->ir.dev = input_dev = input_allocate_device(); 174 budget_ci->ir.dev = input_dev = input_allocate_device();
@@ -230,7 +208,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
230 case 0x1011: 208 case 0x1011:
231 case 0x1012: 209 case 0x1012:
232 /* The hauppauge keymap is a superset of these remotes */ 210 /* The hauppauge keymap is a superset of these remotes */
233 ir_codes = &ir_codes_hauppauge_new_table; 211 ir_codes = RC_MAP_HAUPPAUGE_NEW;
234 212
235 if (rc5_device < 0) 213 if (rc5_device < 0)
236 budget_ci->ir.rc5_device = 0x1f; 214 budget_ci->ir.rc5_device = 0x1f;
@@ -239,22 +217,15 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
239 case 0x1017: 217 case 0x1017:
240 case 0x101a: 218 case 0x101a:
241 /* for the Technotrend 1500 bundled remote */ 219 /* for the Technotrend 1500 bundled remote */
242 ir_codes = &ir_codes_tt_1500_table; 220 ir_codes = RC_MAP_TT_1500;
243 break; 221 break;
244 default: 222 default:
245 /* unknown remote */ 223 /* unknown remote */
246 ir_codes = &ir_codes_budget_ci_old_table; 224 ir_codes = RC_MAP_BUDGET_CI_OLD;
247 break; 225 break;
248 } 226 }
249 227
250 ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5); 228 error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
251
252 /* initialise the key-up timeout handler */
253 init_timer(&budget_ci->ir.timer_keyup);
254 budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
255 budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
256 budget_ci->ir.last_raw = 0xffff; /* An impossible value */
257 error = ir_input_register(input_dev, ir_codes, NULL);
258 if (error) { 229 if (error) {
259 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); 230 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
260 return error; 231 return error;
@@ -282,9 +253,6 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
282 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 253 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
283 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); 254 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
284 255
285 del_timer_sync(&dev->timer);
286 ir_input_nokey(dev, &budget_ci->ir.state);
287
288 ir_input_unregister(dev); 256 ir_input_unregister(dev);
289} 257}
290 258
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 1500210c06cf..874a10a9d493 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -442,6 +442,7 @@ static struct stv090x_config tt1600_stv090x_config = {
442 .repeater_level = STV090x_RPTLEVEL_16, 442 .repeater_level = STV090x_RPTLEVEL_16,
443 443
444 .tuner_init = NULL, 444 .tuner_init = NULL,
445 .tuner_sleep = NULL,
445 .tuner_set_mode = NULL, 446 .tuner_set_mode = NULL,
446 .tuner_set_frequency = NULL, 447 .tuner_set_frequency = NULL,
447 .tuner_get_frequency = NULL, 448 .tuner_get_frequency = NULL,
@@ -627,22 +628,36 @@ static void frontend_init(struct budget *budget)
627 &tt1600_stv6110x_config, 628 &tt1600_stv6110x_config,
628 &budget->i2c_adap); 629 &budget->i2c_adap);
629 630
630 tt1600_stv090x_config.tuner_init = ctl->tuner_init; 631 if (ctl) {
631 tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; 632 tt1600_stv090x_config.tuner_init = ctl->tuner_init;
632 tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; 633 tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep;
633 tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; 634 tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
634 tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; 635 tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
635 tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; 636 tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
636 tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; 637 tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
637 tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; 638 tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
638 tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; 639 tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
639 tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; 640 tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
640 641 tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
641 dvb_attach(isl6423_attach, 642 tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status;
642 budget->dvb_frontend, 643
643 &budget->i2c_adap, 644 /* call the init function once to initialize
644 &tt1600_isl6423_config); 645 tuner's clock output divider and demod's
645 646 master clock */
647 if (budget->dvb_frontend->ops.init)
648 budget->dvb_frontend->ops.init(budget->dvb_frontend);
649
650 if (dvb_attach(isl6423_attach,
651 budget->dvb_frontend,
652 &budget->i2c_adap,
653 &tt1600_isl6423_config) == NULL) {
654 printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__);
655 goto error_out;
656 }
657 } else {
658 printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
659 goto error_out;
660 }
646 } 661 }
647 } 662 }
648 break; 663 break;
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 02a9cefc9a00..353b82855949 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -144,7 +144,10 @@ struct amradio_device {
144 int initialized; 144 int initialized;
145}; 145};
146 146
147#define vdev_to_amradio(r) container_of(r, struct amradio_device, videodev) 147static inline struct amradio_device *to_amradio_dev(struct v4l2_device *v4l2_dev)
148{
149 return container_of(v4l2_dev, struct amradio_device, v4l2_dev);
150}
148 151
149/* USB Device ID List */ 152/* USB Device ID List */
150static struct usb_device_id usb_amradio_device_table[] = { 153static struct usb_device_id usb_amradio_device_table[] = {
@@ -284,13 +287,12 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument)
284 */ 287 */
285static void usb_amradio_disconnect(struct usb_interface *intf) 288static void usb_amradio_disconnect(struct usb_interface *intf)
286{ 289{
287 struct amradio_device *radio = usb_get_intfdata(intf); 290 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
288 291
289 mutex_lock(&radio->lock); 292 mutex_lock(&radio->lock);
290 radio->usbdev = NULL; 293 radio->usbdev = NULL;
291 mutex_unlock(&radio->lock); 294 mutex_unlock(&radio->lock);
292 295
293 usb_set_intfdata(intf, NULL);
294 v4l2_device_disconnect(&radio->v4l2_dev); 296 v4l2_device_disconnect(&radio->v4l2_dev);
295 video_unregister_device(&radio->videodev); 297 video_unregister_device(&radio->videodev);
296} 298}
@@ -500,7 +502,7 @@ out:
500/* open device - amradio_start() and amradio_setfreq() */ 502/* open device - amradio_start() and amradio_setfreq() */
501static int usb_amradio_open(struct file *file) 503static int usb_amradio_open(struct file *file)
502{ 504{
503 struct amradio_device *radio = vdev_to_amradio(video_devdata(file)); 505 struct amradio_device *radio = video_drvdata(file);
504 int retval = 0; 506 int retval = 0;
505 507
506 mutex_lock(&radio->lock); 508 mutex_lock(&radio->lock);
@@ -566,7 +568,7 @@ unlock:
566/* Suspend device - stop device. Need to be checked and fixed */ 568/* Suspend device - stop device. Need to be checked and fixed */
567static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) 569static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
568{ 570{
569 struct amradio_device *radio = usb_get_intfdata(intf); 571 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
570 572
571 mutex_lock(&radio->lock); 573 mutex_lock(&radio->lock);
572 574
@@ -584,7 +586,7 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
584/* Resume device - start device. Need to be checked and fixed */ 586/* Resume device - start device. Need to be checked and fixed */
585static int usb_amradio_resume(struct usb_interface *intf) 587static int usb_amradio_resume(struct usb_interface *intf)
586{ 588{
587 struct amradio_device *radio = usb_get_intfdata(intf); 589 struct amradio_device *radio = to_amradio_dev(usb_get_intfdata(intf));
588 590
589 mutex_lock(&radio->lock); 591 mutex_lock(&radio->lock);
590 592
@@ -633,9 +635,7 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
633 635
634static void usb_amradio_video_device_release(struct video_device *videodev) 636static void usb_amradio_video_device_release(struct video_device *videodev)
635{ 637{
636 struct amradio_device *radio = vdev_to_amradio(videodev); 638 struct amradio_device *radio = video_get_drvdata(videodev);
637
638 v4l2_device_unregister(&radio->v4l2_dev);
639 639
640 /* free rest memory */ 640 /* free rest memory */
641 kfree(radio->buffer); 641 kfree(radio->buffer);
@@ -693,7 +693,6 @@ static int usb_amradio_probe(struct usb_interface *intf,
693 goto err_vdev; 693 goto err_vdev;
694 } 694 }
695 695
696 usb_set_intfdata(intf, radio);
697 return 0; 696 return 0;
698 697
699err_vdev: 698err_vdev:
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9644cf760aaa..ad9e6f9c22e9 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -45,6 +45,10 @@ config VIDEO_TUNER
45 tristate 45 tristate
46 depends on MEDIA_TUNER 46 depends on MEDIA_TUNER
47 47
48config V4L2_MEM2MEM_DEV
49 tristate
50 depends on VIDEOBUF_GEN
51
48# 52#
49# Multimedia Video device configuration 53# Multimedia Video device configuration
50# 54#
@@ -480,6 +484,12 @@ config VIDEO_ADV7343
480 To compile this driver as a module, choose M here: the 484 To compile this driver as a module, choose M here: the
481 module will be called adv7343. 485 module will be called adv7343.
482 486
487config VIDEO_AK881X
488 tristate "AK8813/AK8814 video encoders"
489 depends on I2C
490 help
491 Video output driver for AKM AK8813 and AK8814 TV encoders
492
483comment "Video improvement chips" 493comment "Video improvement chips"
484 494
485config VIDEO_UPD64031A 495config VIDEO_UPD64031A
@@ -520,6 +530,13 @@ config DISPLAY_DAVINCI_DM646X_EVM
520 To compile this driver as a module, choose M here: the 530 To compile this driver as a module, choose M here: the
521 module will be called vpif_display. 531 module will be called vpif_display.
522 532
533config VIDEO_SH_VOU
534 tristate "SuperH VOU video output driver"
535 depends on VIDEO_DEV && ARCH_SHMOBILE
536 select VIDEOBUF_DMA_CONTIG
537 help
538 Support for the Video Output Unit (VOU) on SuperH SoCs.
539
523config CAPTURE_DAVINCI_DM646X_EVM 540config CAPTURE_DAVINCI_DM646X_EVM
524 tristate "DM646x EVM Video Capture" 541 tristate "DM646x EVM Video Capture"
525 depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM 542 depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
@@ -542,7 +559,8 @@ config VIDEO_DAVINCI_VPIF
542 559
543config VIDEO_VIVI 560config VIDEO_VIVI
544 tristate "Virtual Video Driver" 561 tristate "Virtual Video Driver"
545 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 562 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FONTS
563 select FONT_8x16
546 select VIDEOBUF_VMALLOC 564 select VIDEOBUF_VMALLOC
547 default n 565 default n
548 ---help--- 566 ---help---
@@ -613,6 +631,8 @@ config VIDEO_ISIF
613 To compile this driver as a module, choose M here: the 631 To compile this driver as a module, choose M here: the
614 module will be called vpfe. 632 module will be called vpfe.
615 633
634source "drivers/media/video/omap/Kconfig"
635
616source "drivers/media/video/bt8xx/Kconfig" 636source "drivers/media/video/bt8xx/Kconfig"
617 637
618config VIDEO_PMS 638config VIDEO_PMS
@@ -647,7 +667,7 @@ config VIDEO_CQCAM
647 667
648config VIDEO_W9966 668config VIDEO_W9966
649 tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux" 669 tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
650 depends on PARPORT_1284 && PARPORT && VIDEO_V4L1 670 depends on PARPORT_1284 && PARPORT && VIDEO_V4L2
651 help 671 help
652 Video4linux driver for Winbond's w9966 based Webcams. 672 Video4linux driver for Winbond's w9966 based Webcams.
653 Currently tested with the LifeView FlyCam Supra. 673 Currently tested with the LifeView FlyCam Supra.
@@ -740,7 +760,7 @@ source "drivers/media/video/zoran/Kconfig"
740 760
741config VIDEO_MEYE 761config VIDEO_MEYE
742 tristate "Sony Vaio Picturebook Motion Eye Video For Linux" 762 tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
743 depends on PCI && SONY_LAPTOP && VIDEO_V4L1 763 depends on PCI && SONY_LAPTOP && VIDEO_V4L2
744 ---help--- 764 ---help---
745 This is the video4linux driver for the Motion Eye camera found 765 This is the video4linux driver for the Motion Eye camera found
746 in the Vaio Picturebook laptops. Please read the material in 766 in the Vaio Picturebook laptops. Please read the material in
@@ -807,7 +827,7 @@ source "drivers/media/video/saa7164/Kconfig"
807 827
808config VIDEO_M32R_AR 828config VIDEO_M32R_AR
809 tristate "AR devices" 829 tristate "AR devices"
810 depends on M32R && VIDEO_V4L1 830 depends on M32R && VIDEO_V4L2
811 ---help--- 831 ---help---
812 This is a video4linux driver for the Renesas AR (Artificial Retina) 832 This is a video4linux driver for the Renesas AR (Artificial Retina)
813 camera module. 833 camera module.
@@ -1107,3 +1127,27 @@ config USB_S2255
1107 1127
1108endif # V4L_USB_DRIVERS 1128endif # V4L_USB_DRIVERS
1109endif # VIDEO_CAPTURE_DRIVERS 1129endif # VIDEO_CAPTURE_DRIVERS
1130
1131menuconfig V4L_MEM2MEM_DRIVERS
1132 bool "Memory-to-memory multimedia devices"
1133 depends on VIDEO_V4L2
1134 default n
1135 ---help---
1136 Say Y here to enable selecting drivers for V4L devices that
1137 use system memory for both source and destination buffers, as opposed
1138 to capture and output drivers, which use memory buffers for just
1139 one of those.
1140
1141if V4L_MEM2MEM_DRIVERS
1142
1143config VIDEO_MEM2MEM_TESTDEV
1144 tristate "Virtual test device for mem2mem framework"
1145 depends on VIDEO_DEV && VIDEO_V4L2
1146 select VIDEOBUF_VMALLOC
1147 select V4L2_MEM2MEM_DEV
1148 default n
1149 ---help---
1150 This is a virtual test device for the memory-to-memory driver
1151 framework.
1152
1153endif # V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index c51c386559f2..cc93859d3164 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,7 +10,8 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o
10 10
11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o 11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
12 12
13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o 13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
14 v4l2-event.o
14 15
15# V4L2 core modules 16# V4L2 core modules
16 17
@@ -117,6 +118,8 @@ obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
117obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o 118obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
118obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o 119obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
119 120
121obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
122
120obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o 123obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
121 124
122obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o 125obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
@@ -149,8 +152,11 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv/
149obj-$(CONFIG_VIDEO_CX18) += cx18/ 152obj-$(CONFIG_VIDEO_CX18) += cx18/
150 153
151obj-$(CONFIG_VIDEO_VIVI) += vivi.o 154obj-$(CONFIG_VIDEO_VIVI) += vivi.o
155obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
152obj-$(CONFIG_VIDEO_CX23885) += cx23885/ 156obj-$(CONFIG_VIDEO_CX23885) += cx23885/
153 157
158obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
159
154obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o 160obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
155obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o 161obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
156obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o 162obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
@@ -160,6 +166,10 @@ obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
160obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 166obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
161obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 167obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
162 168
169obj-$(CONFIG_ARCH_DAVINCI) += davinci/
170
171obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
172
163obj-$(CONFIG_VIDEO_AU0828) += au0828/ 173obj-$(CONFIG_VIDEO_AU0828) += au0828/
164 174
165obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ 175obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
@@ -169,6 +179,8 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
169 179
170obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 180obj-$(CONFIG_ARCH_DAVINCI) += davinci/
171 181
182obj-$(CONFIG_ARCH_OMAP) += omap/
183
172EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 184EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
173EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 185EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
174EXTRA_CFLAGS += -Idrivers/media/common/tuners 186EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/ak881x.c b/drivers/media/video/ak881x.c
new file mode 100644
index 000000000000..35390d4717b9
--- /dev/null
+++ b/drivers/media/video/ak881x.c
@@ -0,0 +1,368 @@
1/*
2 * Driver for AK8813 / AK8814 TV-ecoders from Asahi Kasei Microsystems Co., Ltd. (AKM)
3 *
4 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/i2c.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/videodev2.h>
15
16#include <media/ak881x.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/v4l2-common.h>
19#include <media/v4l2-device.h>
20
21#define AK881X_INTERFACE_MODE 0
22#define AK881X_VIDEO_PROCESS1 1
23#define AK881X_VIDEO_PROCESS2 2
24#define AK881X_VIDEO_PROCESS3 3
25#define AK881X_DAC_MODE 5
26#define AK881X_STATUS 0x24
27#define AK881X_DEVICE_ID 0x25
28#define AK881X_DEVICE_REVISION 0x26
29
30struct ak881x {
31 struct v4l2_subdev subdev;
32 struct ak881x_pdata *pdata;
33 unsigned int lines;
34 int id; /* DEVICE_ID code V4L2_IDENT_AK881X code from v4l2-chip-ident.h */
35 char revision; /* DEVICE_REVISION content */
36};
37
38static int reg_read(struct i2c_client *client, const u8 reg)
39{
40 return i2c_smbus_read_byte_data(client, reg);
41}
42
43static int reg_write(struct i2c_client *client, const u8 reg,
44 const u8 data)
45{
46 return i2c_smbus_write_byte_data(client, reg, data);
47}
48
49static int reg_set(struct i2c_client *client, const u8 reg,
50 const u8 data, u8 mask)
51{
52 int ret = reg_read(client, reg);
53 if (ret < 0)
54 return ret;
55 return reg_write(client, reg, (ret & ~mask) | (data & mask));
56}
57
58static struct ak881x *to_ak881x(const struct i2c_client *client)
59{
60 return container_of(i2c_get_clientdata(client), struct ak881x, subdev);
61}
62
63static int ak881x_g_chip_ident(struct v4l2_subdev *sd,
64 struct v4l2_dbg_chip_ident *id)
65{
66 struct i2c_client *client = v4l2_get_subdevdata(sd);
67 struct ak881x *ak881x = to_ak881x(client);
68
69 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
70 return -EINVAL;
71
72 if (id->match.addr != client->addr)
73 return -ENODEV;
74
75 id->ident = ak881x->id;
76 id->revision = ak881x->revision;
77
78 return 0;
79}
80
81#ifdef CONFIG_VIDEO_ADV_DEBUG
82static int ak881x_g_register(struct v4l2_subdev *sd,
83 struct v4l2_dbg_register *reg)
84{
85 struct i2c_client *client = v4l2_get_subdevdata(sd);
86
87 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
88 return -EINVAL;
89
90 if (reg->match.addr != client->addr)
91 return -ENODEV;
92
93 reg->val = reg_read(client, reg->reg);
94
95 if (reg->val > 0xffff)
96 return -EIO;
97
98 return 0;
99}
100
101static int ak881x_s_register(struct v4l2_subdev *sd,
102 struct v4l2_dbg_register *reg)
103{
104 struct i2c_client *client = v4l2_get_subdevdata(sd);
105
106 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
107 return -EINVAL;
108
109 if (reg->match.addr != client->addr)
110 return -ENODEV;
111
112 if (reg_write(client, reg->reg, reg->val) < 0)
113 return -EIO;
114
115 return 0;
116}
117#endif
118
119static int ak881x_try_g_mbus_fmt(struct v4l2_subdev *sd,
120 struct v4l2_mbus_framefmt *mf)
121{
122 struct i2c_client *client = v4l2_get_subdevdata(sd);
123 struct ak881x *ak881x = to_ak881x(client);
124
125 v4l_bound_align_image(&mf->width, 0, 720, 2,
126 &mf->height, 0, ak881x->lines, 1, 0);
127 mf->field = V4L2_FIELD_INTERLACED;
128 mf->code = V4L2_MBUS_FMT_YUYV8_2X8_LE;
129 mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
130
131 return 0;
132}
133
134static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd,
135 struct v4l2_mbus_framefmt *mf)
136{
137 if (mf->field != V4L2_FIELD_INTERLACED ||
138 mf->code != V4L2_MBUS_FMT_YUYV8_2X8_LE)
139 return -EINVAL;
140
141 return ak881x_try_g_mbus_fmt(sd, mf);
142}
143
144static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, int index,
145 enum v4l2_mbus_pixelcode *code)
146{
147 if (index)
148 return -EINVAL;
149
150 *code = V4L2_MBUS_FMT_YUYV8_2X8_LE;
151 return 0;
152}
153
154static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
155{
156 struct i2c_client *client = v4l2_get_subdevdata(sd);
157 struct ak881x *ak881x = to_ak881x(client);
158
159 a->bounds.left = 0;
160 a->bounds.top = 0;
161 a->bounds.width = 720;
162 a->bounds.height = ak881x->lines;
163 a->defrect = a->bounds;
164 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
165 a->pixelaspect.numerator = 1;
166 a->pixelaspect.denominator = 1;
167
168 return 0;
169}
170
171static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
172{
173 struct i2c_client *client = v4l2_get_subdevdata(sd);
174 struct ak881x *ak881x = to_ak881x(client);
175 u8 vp1;
176
177 if (std == V4L2_STD_NTSC_443) {
178 vp1 = 3;
179 ak881x->lines = 480;
180 } else if (std == V4L2_STD_PAL_M) {
181 vp1 = 5;
182 ak881x->lines = 480;
183 } else if (std == V4L2_STD_PAL_60) {
184 vp1 = 7;
185 ak881x->lines = 480;
186 } else if (std && !(std & ~V4L2_STD_PAL)) {
187 vp1 = 0xf;
188 ak881x->lines = 576;
189 } else if (std && !(std & ~V4L2_STD_NTSC)) {
190 vp1 = 0;
191 ak881x->lines = 480;
192 } else {
193 /* No SECAM or PAL_N/Nc supported */
194 return -EINVAL;
195 }
196
197 reg_set(client, AK881X_VIDEO_PROCESS1, vp1, 0xf);
198
199 return 0;
200}
201
202static int ak881x_s_stream(struct v4l2_subdev *sd, int enable)
203{
204 struct i2c_client *client = v4l2_get_subdevdata(sd);
205 struct ak881x *ak881x = to_ak881x(client);
206
207 if (enable) {
208 u8 dac;
209 /* For colour-bar testing set bit 6 of AK881X_VIDEO_PROCESS1 */
210 /* Default: composite output */
211 if (ak881x->pdata->flags & AK881X_COMPONENT)
212 dac = 3;
213 else
214 dac = 4;
215 /* Turn on the DAC(s) */
216 reg_write(client, AK881X_DAC_MODE, dac);
217 dev_dbg(&client->dev, "chip status 0x%x\n",
218 reg_read(client, AK881X_STATUS));
219 } else {
220 /* ...and clear bit 6 of AK881X_VIDEO_PROCESS1 here */
221 reg_write(client, AK881X_DAC_MODE, 0);
222 dev_dbg(&client->dev, "chip status 0x%x\n",
223 reg_read(client, AK881X_STATUS));
224 }
225
226 return 0;
227}
228
229static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
230 .g_chip_ident = ak881x_g_chip_ident,
231#ifdef CONFIG_VIDEO_ADV_DEBUG
232 .g_register = ak881x_g_register,
233 .s_register = ak881x_s_register,
234#endif
235};
236
237static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = {
238 .s_mbus_fmt = ak881x_s_mbus_fmt,
239 .g_mbus_fmt = ak881x_try_g_mbus_fmt,
240 .try_mbus_fmt = ak881x_try_g_mbus_fmt,
241 .cropcap = ak881x_cropcap,
242 .enum_mbus_fmt = ak881x_enum_mbus_fmt,
243 .s_std_output = ak881x_s_std_output,
244 .s_stream = ak881x_s_stream,
245};
246
247static struct v4l2_subdev_ops ak881x_subdev_ops = {
248 .core = &ak881x_subdev_core_ops,
249 .video = &ak881x_subdev_video_ops,
250};
251
252static int ak881x_probe(struct i2c_client *client,
253 const struct i2c_device_id *did)
254{
255 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
256 struct ak881x *ak881x;
257 u8 ifmode, data;
258
259 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
260 dev_warn(&adapter->dev,
261 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
262 return -EIO;
263 }
264
265 ak881x = kzalloc(sizeof(struct ak881x), GFP_KERNEL);
266 if (!ak881x)
267 return -ENOMEM;
268
269 v4l2_i2c_subdev_init(&ak881x->subdev, client, &ak881x_subdev_ops);
270
271 data = reg_read(client, AK881X_DEVICE_ID);
272
273 switch (data) {
274 case 0x13:
275 ak881x->id = V4L2_IDENT_AK8813;
276 break;
277 case 0x14:
278 ak881x->id = V4L2_IDENT_AK8814;
279 break;
280 default:
281 dev_err(&client->dev,
282 "No ak881x chip detected, register read %x\n", data);
283 kfree(ak881x);
284 return -ENODEV;
285 }
286
287 ak881x->revision = reg_read(client, AK881X_DEVICE_REVISION);
288 ak881x->pdata = client->dev.platform_data;
289
290 if (ak881x->pdata) {
291 if (ak881x->pdata->flags & AK881X_FIELD)
292 ifmode = 4;
293 else
294 ifmode = 0;
295
296 switch (ak881x->pdata->flags & AK881X_IF_MODE_MASK) {
297 case AK881X_IF_MODE_BT656:
298 ifmode |= 1;
299 break;
300 case AK881X_IF_MODE_MASTER:
301 ifmode |= 2;
302 break;
303 case AK881X_IF_MODE_SLAVE:
304 default:
305 break;
306 }
307
308 dev_dbg(&client->dev, "IF mode %x\n", ifmode);
309
310 /*
311 * "Line Blanking No." seems to be the same as the number of
312 * "black" lines on, e.g., SuperH VOU, whose default value of 20
313 * "incidentally" matches ak881x' default
314 */
315 reg_write(client, AK881X_INTERFACE_MODE, ifmode | (20 << 3));
316 }
317
318 /* Hardware default: NTSC-M */
319 ak881x->lines = 480;
320
321 dev_info(&client->dev, "Detected an ak881x chip ID %x, revision %x\n",
322 data, ak881x->revision);
323
324 return 0;
325}
326
327static int ak881x_remove(struct i2c_client *client)
328{
329 struct ak881x *ak881x = to_ak881x(client);
330
331 v4l2_device_unregister_subdev(&ak881x->subdev);
332 kfree(ak881x);
333
334 return 0;
335}
336
337static const struct i2c_device_id ak881x_id[] = {
338 { "ak8813", 0 },
339 { "ak8814", 0 },
340 { }
341};
342MODULE_DEVICE_TABLE(i2c, ak881x_id);
343
344static struct i2c_driver ak881x_i2c_driver = {
345 .driver = {
346 .name = "ak881x",
347 },
348 .probe = ak881x_probe,
349 .remove = ak881x_remove,
350 .id_table = ak881x_id,
351};
352
353static int __init ak881x_module_init(void)
354{
355 return i2c_add_driver(&ak881x_i2c_driver);
356}
357
358static void __exit ak881x_module_exit(void)
359{
360 i2c_del_driver(&ak881x_i2c_driver);
361}
362
363module_init(ak881x_module_init);
364module_exit(ak881x_module_exit);
365
366MODULE_DESCRIPTION("TV-output driver for ak8813/ak8814");
367MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
368MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index a356d6bd3131..31e7a123d19a 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -27,8 +27,10 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/videodev.h> 30#include <linux/version.h>
31#include <linux/videodev2.h>
31#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
33#include <media/v4l2-device.h>
32#include <media/v4l2-ioctl.h> 34#include <media/v4l2-ioctl.h>
33#include <linux/mutex.h> 35#include <linux/mutex.h>
34 36
@@ -39,7 +41,7 @@
39#include <asm/byteorder.h> 41#include <asm/byteorder.h>
40 42
41#if 0 43#if 0
42#define DEBUG(n, args...) printk(args) 44#define DEBUG(n, args...) printk(KERN_INFO args)
43#define CHECK_LOST 1 45#define CHECK_LOST 1
44#else 46#else
45#define DEBUG(n, args...) 47#define DEBUG(n, args...)
@@ -52,10 +54,10 @@
52 */ 54 */
53#define USE_INT 0 /* Don't modify */ 55#define USE_INT 0 /* Don't modify */
54 56
55#define VERSION "0.03" 57#define VERSION "0.04"
56 58
57#define ar_inl(addr) inl((unsigned long)(addr)) 59#define ar_inl(addr) inl((unsigned long)(addr))
58#define ar_outl(val, addr) outl((unsigned long)(val),(unsigned long)(addr)) 60#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr))
59 61
60extern struct cpuinfo_m32r boot_cpu_data; 62extern struct cpuinfo_m32r boot_cpu_data;
61 63
@@ -79,7 +81,7 @@ extern struct cpuinfo_m32r boot_cpu_data;
79 81
80/* bits & bytes per pixel */ 82/* bits & bytes per pixel */
81#define AR_BITS_PER_PIXEL 16 83#define AR_BITS_PER_PIXEL 16
82#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL/8) 84#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8)
83 85
84/* line buffer size */ 86/* line buffer size */
85#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL) 87#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
@@ -104,8 +106,9 @@ extern struct cpuinfo_m32r boot_cpu_data;
104#define AR_MODE_INTERLACE 0 106#define AR_MODE_INTERLACE 0
105#define AR_MODE_NORMAL 1 107#define AR_MODE_NORMAL 1
106 108
107struct ar_device { 109struct ar {
108 struct video_device *vdev; 110 struct v4l2_device v4l2_dev;
111 struct video_device vdev;
109 unsigned int start_capture; /* duaring capture in INT. mode. */ 112 unsigned int start_capture; /* duaring capture in INT. mode. */
110#if USE_INT 113#if USE_INT
111 unsigned char *line_buff; /* DMA line buffer */ 114 unsigned char *line_buff; /* DMA line buffer */
@@ -116,12 +119,13 @@ struct ar_device {
116 int width, height; 119 int width, height;
117 int frame_bytes, line_bytes; 120 int frame_bytes, line_bytes;
118 wait_queue_head_t wait; 121 wait_queue_head_t wait;
119 unsigned long in_use;
120 struct mutex lock; 122 struct mutex lock;
121}; 123};
122 124
125static struct ar ardev;
126
123static int video_nr = -1; /* video device number (first free) */ 127static int video_nr = -1; /* video device number (first free) */
124static unsigned char yuv[MAX_AR_FRAME_BYTES]; 128static unsigned char yuv[MAX_AR_FRAME_BYTES];
125 129
126/* module parameters */ 130/* module parameters */
127/* default frequency */ 131/* default frequency */
@@ -133,9 +137,7 @@ module_param(freq, int, 0);
133module_param(vga, int, 0); 137module_param(vga, int, 0);
134module_param(vga_interlace, int, 0); 138module_param(vga_interlace, int, 0);
135 139
136static int ar_initialize(struct video_device *dev); 140static void wait_for_vsync(void)
137
138static inline void wait_for_vsync(void)
139{ 141{
140 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */ 142 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
141 cpu_relax(); 143 cpu_relax();
@@ -143,7 +145,7 @@ static inline void wait_for_vsync(void)
143 cpu_relax(); 145 cpu_relax();
144} 146}
145 147
146static inline void wait_acknowledge(void) 148static void wait_acknowledge(void)
147{ 149{
148 int i; 150 int i;
149 151
@@ -156,7 +158,7 @@ static inline void wait_acknowledge(void)
156/******************************************************************* 158/*******************************************************************
157 * I2C functions 159 * I2C functions
158 *******************************************************************/ 160 *******************************************************************/
159void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2, 161static void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
160 unsigned long data3) 162 unsigned long data3)
161{ 163{
162 int i; 164 int i;
@@ -200,7 +202,7 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
200} 202}
201 203
202 204
203void init_iic(void) 205static void init_iic(void)
204{ 206{
205 DEBUG(1, "init_iic:\n"); 207 DEBUG(1, "init_iic:\n");
206 208
@@ -214,13 +216,12 @@ void init_iic(void)
214 216
215 /* I2C CLK */ 217 /* I2C CLK */
216 /* 50MH-100k */ 218 /* 50MH-100k */
217 if (freq == 75) { 219 if (freq == 75)
218 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */ 220 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
219 } else if (freq == 50) { 221 else if (freq == 50)
220 ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */ 222 ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
221 } else { 223 else
222 ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */ 224 ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
223 }
224 ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ 225 ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
225} 226}
226 227
@@ -245,7 +246,7 @@ static inline void clear_dma_status(void)
245 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */ 246 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
246} 247}
247 248
248static inline void wait_for_vertical_sync(int exp_line) 249static void wait_for_vertical_sync(struct ar *ar, int exp_line)
249{ 250{
250#if CHECK_LOST 251#if CHECK_LOST
251 int tmout = 10000; /* FIXME */ 252 int tmout = 10000; /* FIXME */
@@ -260,7 +261,7 @@ static inline void wait_for_vertical_sync(int exp_line)
260 break; 261 break;
261 } 262 }
262 if (tmout < 0) 263 if (tmout < 0)
263 printk("arv: lost %d -> %d\n", exp_line, l); 264 v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l);
264#else 265#else
265 while (ar_inl(ARVHCOUNT) != exp_line) 266 while (ar_inl(ARVHCOUNT) != exp_line)
266 cpu_relax(); 267 cpu_relax();
@@ -269,15 +270,14 @@ static inline void wait_for_vertical_sync(int exp_line)
269 270
270static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) 271static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
271{ 272{
272 struct video_device *v = video_devdata(file); 273 struct ar *ar = video_drvdata(file);
273 struct ar_device *ar = video_get_drvdata(v);
274 long ret = ar->frame_bytes; /* return read bytes */ 274 long ret = ar->frame_bytes; /* return read bytes */
275 unsigned long arvcr1 = 0; 275 unsigned long arvcr1 = 0;
276 unsigned long flags; 276 unsigned long flags;
277 unsigned char *p; 277 unsigned char *p;
278 int h, w; 278 int h, w;
279 unsigned char *py, *pu, *pv; 279 unsigned char *py, *pu, *pv;
280#if ! USE_INT 280#if !USE_INT
281 int l; 281 int l;
282#endif 282#endif
283 283
@@ -305,7 +305,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
305 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ 305 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
306 306
307 /* 307 /*
308 * Okey , kicks AR LSI to invoke an interrupt 308 * Okay, kick AR LSI to invoke an interrupt
309 */ 309 */
310 ar->start_capture = 0; 310 ar->start_capture = 0;
311 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1); 311 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
@@ -313,7 +313,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
313 /* .... AR interrupts .... */ 313 /* .... AR interrupts .... */
314 interruptible_sleep_on(&ar->wait); 314 interruptible_sleep_on(&ar->wait);
315 if (signal_pending(current)) { 315 if (signal_pending(current)) {
316 printk("arv: interrupted while get frame data.\n"); 316 printk(KERN_ERR "arv: interrupted while get frame data.\n");
317 ret = -EINTR; 317 ret = -EINTR;
318 goto out_up; 318 goto out_up;
319 } 319 }
@@ -334,7 +334,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
334 cpu_relax(); 334 cpu_relax();
335 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 335 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
336 for (h = 0; h < ar->height; h++) { 336 for (h = 0; h < ar->height; h++) {
337 wait_for_vertical_sync(h); 337 wait_for_vertical_sync(ar, h);
338 if (h < (AR_HEIGHT_VGA/2)) 338 if (h < (AR_HEIGHT_VGA/2))
339 l = h << 1; 339 l = h << 1;
340 else 340 else
@@ -349,7 +349,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
349 } 349 }
350 } else { 350 } else {
351 for (h = 0; h < ar->height; h++) { 351 for (h = 0; h < ar->height; h++) {
352 wait_for_vertical_sync(h); 352 wait_for_vertical_sync(ar, h);
353 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL); 353 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
354 enable_dma(); 354 enable_dma();
355 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000)) 355 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
@@ -386,7 +386,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
386 } 386 }
387 } 387 }
388 if (copy_to_user(buf, yuv, ar->frame_bytes)) { 388 if (copy_to_user(buf, yuv, ar->frame_bytes)) {
389 printk("arv: failed while copy_to_user yuv.\n"); 389 v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n");
390 ret = -EFAULT; 390 ret = -EFAULT;
391 goto out_up; 391 goto out_up;
392 } 392 }
@@ -396,153 +396,127 @@ out_up:
396 return ret; 396 return ret;
397} 397}
398 398
399static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg) 399static int ar_querycap(struct file *file, void *priv,
400 struct v4l2_capability *vcap)
400{ 401{
401 struct video_device *dev = video_devdata(file); 402 struct ar *ar = video_drvdata(file);
402 struct ar_device *ar = video_get_drvdata(dev); 403
403 404 strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver));
404 DEBUG(1, "ar_ioctl()\n"); 405 strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card));
405 switch(cmd) { 406 strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info));
406 case VIDIOCGCAP: 407 vcap->version = KERNEL_VERSION(0, 0, 4);
407 { 408 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
408 struct video_capability *b = arg; 409 return 0;
409 DEBUG(1, "VIDIOCGCAP:\n"); 410}
410 strcpy(b->name, ar->vdev->name); 411
411 b->type = VID_TYPE_CAPTURE; 412static int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
412 b->channels = 0; 413{
413 b->audios = 0; 414 if (vin->index > 0)
414 b->maxwidth = MAX_AR_WIDTH;
415 b->maxheight = MAX_AR_HEIGHT;
416 b->minwidth = MIN_AR_WIDTH;
417 b->minheight = MIN_AR_HEIGHT;
418 return 0;
419 }
420 case VIDIOCGCHAN:
421 DEBUG(1, "VIDIOCGCHAN:\n");
422 return 0;
423 case VIDIOCSCHAN:
424 DEBUG(1, "VIDIOCSCHAN:\n");
425 return 0;
426 case VIDIOCGTUNER:
427 DEBUG(1, "VIDIOCGTUNER:\n");
428 return 0;
429 case VIDIOCSTUNER:
430 DEBUG(1, "VIDIOCSTUNER:\n");
431 return 0;
432 case VIDIOCGPICT:
433 DEBUG(1, "VIDIOCGPICT:\n");
434 return 0;
435 case VIDIOCSPICT:
436 DEBUG(1, "VIDIOCSPICT:\n");
437 return 0;
438 case VIDIOCCAPTURE:
439 DEBUG(1, "VIDIOCCAPTURE:\n");
440 return -EINVAL; 415 return -EINVAL;
441 case VIDIOCGWIN: 416 strlcpy(vin->name, "Camera", sizeof(vin->name));
442 { 417 vin->type = V4L2_INPUT_TYPE_CAMERA;
443 struct video_window *w = arg; 418 vin->audioset = 0;
444 DEBUG(1, "VIDIOCGWIN:\n"); 419 vin->tuner = 0;
445 memset(w, 0, sizeof(*w)); 420 vin->std = V4L2_STD_ALL;
446 w->width = ar->width; 421 vin->status = 0;
447 w->height = ar->height; 422 return 0;
448 return 0; 423}
424
425static int ar_g_input(struct file *file, void *fh, unsigned int *inp)
426{
427 *inp = 0;
428 return 0;
429}
430
431static int ar_s_input(struct file *file, void *fh, unsigned int inp)
432{
433 return inp ? -EINVAL : 0;
434}
435
436static int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
437{
438 struct ar *ar = video_drvdata(file);
439 struct v4l2_pix_format *pix = &fmt->fmt.pix;
440
441 pix->width = ar->width;
442 pix->height = ar->height;
443 pix->pixelformat = V4L2_PIX_FMT_YUV422P;
444 pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
445 pix->bytesperline = ar->width;
446 pix->sizeimage = 2 * ar->width * ar->height;
447 /* Just a guess */
448 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
449 return 0;
450}
451
452static int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
453{
454 struct ar *ar = video_drvdata(file);
455 struct v4l2_pix_format *pix = &fmt->fmt.pix;
456
457 if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) {
458 pix->height = AR_HEIGHT_QVGA;
459 pix->width = AR_WIDTH_QVGA;
460 pix->field = V4L2_FIELD_INTERLACED;
461 } else {
462 pix->height = AR_HEIGHT_VGA;
463 pix->width = AR_WIDTH_VGA;
464 pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
449 } 465 }
450 case VIDIOCSWIN: 466 pix->pixelformat = V4L2_PIX_FMT_YUV422P;
451 { 467 pix->bytesperline = ar->width;
452 struct video_window *w = arg; 468 pix->sizeimage = 2 * ar->width * ar->height;
453 DEBUG(1, "VIDIOCSWIN:\n"); 469 /* Just a guess */
454 if ((w->width != AR_WIDTH_VGA || w->height != AR_HEIGHT_VGA) && 470 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
455 (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA)) 471 return 0;
456 return -EINVAL; 472}
457 473
458 mutex_lock(&ar->lock); 474static int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
459 ar->width = w->width; 475{
460 ar->height = w->height; 476 struct ar *ar = video_drvdata(file);
461 if (ar->width == AR_WIDTH_VGA) { 477 struct v4l2_pix_format *pix = &fmt->fmt.pix;
462 ar->size = AR_SIZE_VGA; 478 int ret = ar_try_fmt_vid_cap(file, fh, fmt);
463 ar->frame_bytes = AR_FRAME_BYTES_VGA; 479
464 ar->line_bytes = AR_LINE_BYTES_VGA; 480 if (ret)
465 if (vga_interlace) 481 return ret;
466 ar->mode = AR_MODE_INTERLACE; 482 mutex_lock(&ar->lock);
467 else 483 ar->width = pix->width;
468 ar->mode = AR_MODE_NORMAL; 484 ar->height = pix->height;
469 } else { 485 if (ar->width == AR_WIDTH_VGA) {
470 ar->size = AR_SIZE_QVGA; 486 ar->size = AR_SIZE_VGA;
471 ar->frame_bytes = AR_FRAME_BYTES_QVGA; 487 ar->frame_bytes = AR_FRAME_BYTES_VGA;
472 ar->line_bytes = AR_LINE_BYTES_QVGA; 488 ar->line_bytes = AR_LINE_BYTES_VGA;
489 if (vga_interlace)
473 ar->mode = AR_MODE_INTERLACE; 490 ar->mode = AR_MODE_INTERLACE;
474 } 491 else
475 mutex_unlock(&ar->lock); 492 ar->mode = AR_MODE_NORMAL;
476 return 0; 493 } else {
477 } 494 ar->size = AR_SIZE_QVGA;
478 case VIDIOCGFBUF: 495 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
479 DEBUG(1, "VIDIOCGFBUF:\n"); 496 ar->line_bytes = AR_LINE_BYTES_QVGA;
480 return -EINVAL; 497 ar->mode = AR_MODE_INTERLACE;
481 case VIDIOCSFBUF:
482 DEBUG(1, "VIDIOCSFBUF:\n");
483 return -EINVAL;
484 case VIDIOCKEY:
485 DEBUG(1, "VIDIOCKEY:\n");
486 return 0;
487 case VIDIOCGFREQ:
488 DEBUG(1, "VIDIOCGFREQ:\n");
489 return -EINVAL;
490 case VIDIOCSFREQ:
491 DEBUG(1, "VIDIOCSFREQ:\n");
492 return -EINVAL;
493 case VIDIOCGAUDIO:
494 DEBUG(1, "VIDIOCGAUDIO:\n");
495 return -EINVAL;
496 case VIDIOCSAUDIO:
497 DEBUG(1, "VIDIOCSAUDIO:\n");
498 return -EINVAL;
499 case VIDIOCSYNC:
500 DEBUG(1, "VIDIOCSYNC:\n");
501 return -EINVAL;
502 case VIDIOCMCAPTURE:
503 DEBUG(1, "VIDIOCMCAPTURE:\n");
504 return -EINVAL;
505 case VIDIOCGMBUF:
506 DEBUG(1, "VIDIOCGMBUF:\n");
507 return -EINVAL;
508 case VIDIOCGUNIT:
509 DEBUG(1, "VIDIOCGUNIT:\n");
510 return -EINVAL;
511 case VIDIOCGCAPTURE:
512 DEBUG(1, "VIDIOCGCAPTURE:\n");
513 return -EINVAL;
514 case VIDIOCSCAPTURE:
515 DEBUG(1, "VIDIOCSCAPTURE:\n");
516 return -EINVAL;
517 case VIDIOCSPLAYMODE:
518 DEBUG(1, "VIDIOCSPLAYMODE:\n");
519 return -EINVAL;
520 case VIDIOCSWRITEMODE:
521 DEBUG(1, "VIDIOCSWRITEMODE:\n");
522 return -EINVAL;
523 case VIDIOCGPLAYINFO:
524 DEBUG(1, "VIDIOCGPLAYINFO:\n");
525 return -EINVAL;
526 case VIDIOCSMICROCODE:
527 DEBUG(1, "VIDIOCSMICROCODE:\n");
528 return -EINVAL;
529 case VIDIOCGVBIFMT:
530 DEBUG(1, "VIDIOCGVBIFMT:\n");
531 return -EINVAL;
532 case VIDIOCSVBIFMT:
533 DEBUG(1, "VIDIOCSVBIFMT:\n");
534 return -EINVAL;
535 default:
536 DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);
537 return -ENOIOCTLCMD;
538 } 498 }
499 /* Ok we figured out what to use from our wide choice */
500 mutex_unlock(&ar->lock);
539 return 0; 501 return 0;
540} 502}
541 503
542static long ar_ioctl(struct file *file, unsigned int cmd, 504static int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
543 unsigned long arg)
544{ 505{
545 return video_usercopy(file, cmd, arg, ar_do_ioctl); 506 static struct v4l2_fmtdesc formats[] = {
507 { 0, 0, 0,
508 "YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P,
509 { 0, 0, 0, 0 }
510 },
511 };
512 enum v4l2_buf_type type = fmt->type;
513
514 if (fmt->index > 0)
515 return -EINVAL;
516
517 *fmt = formats[fmt->index];
518 fmt->type = type;
519 return 0;
546} 520}
547 521
548#if USE_INT 522#if USE_INT
@@ -551,7 +525,7 @@ static long ar_ioctl(struct file *file, unsigned int cmd,
551 */ 525 */
552static void ar_interrupt(int irq, void *dev) 526static void ar_interrupt(int irq, void *dev)
553{ 527{
554 struct ar_device *ar = dev; 528 struct ar *ar = dev;
555 unsigned int line_count; 529 unsigned int line_count;
556 unsigned int line_number; 530 unsigned int line_number;
557 unsigned int arvcr1; 531 unsigned int arvcr1;
@@ -559,11 +533,11 @@ static void ar_interrupt(int irq, void *dev)
559 line_count = ar_inl(ARVHCOUNT); /* line number */ 533 line_count = ar_inl(ARVHCOUNT); /* line number */
560 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { 534 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
561 /* operations for interlace mode */ 535 /* operations for interlace mode */
562 if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */ 536 if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */
563 line_number = (line_count << 1); 537 line_number = (line_count << 1);
564 else /* odd line */ 538 else /* odd line */
565 line_number = 539 line_number =
566 (((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1); 540 (((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1);
567 } else { 541 } else {
568 line_number = line_count; 542 line_number = line_count;
569 } 543 }
@@ -623,11 +597,10 @@ static void ar_interrupt(int irq, void *dev)
623 * 0 is returned in success. 597 * 0 is returned in success.
624 * 598 *
625 */ 599 */
626static int ar_initialize(struct video_device *dev) 600static int ar_initialize(struct ar *ar)
627{ 601{
628 struct ar_device *ar = video_get_drvdata(dev);
629 unsigned long cr = 0; 602 unsigned long cr = 0;
630 int i,found=0; 603 int i, found = 0;
631 604
632 DEBUG(1, "ar_initialize:\n"); 605 DEBUG(1, "ar_initialize:\n");
633 606
@@ -666,129 +639,119 @@ static int ar_initialize(struct video_device *dev)
666 if (found == 0) 639 if (found == 0)
667 return -ENODEV; 640 return -ENODEV;
668 641
669 printk("arv: Initializing "); 642 v4l2_info(&ar->v4l2_dev, "Initializing ");
670 643
671 iic(2,0x78,0x11,0x01,0x00); /* start */ 644 iic(2, 0x78, 0x11, 0x01, 0x00); /* start */
672 iic(3,0x78,0x12,0x00,0x06); 645 iic(3, 0x78, 0x12, 0x00, 0x06);
673 iic(3,0x78,0x12,0x12,0x30); 646 iic(3, 0x78, 0x12, 0x12, 0x30);
674 iic(3,0x78,0x12,0x15,0x58); 647 iic(3, 0x78, 0x12, 0x15, 0x58);
675 iic(3,0x78,0x12,0x17,0x30); 648 iic(3, 0x78, 0x12, 0x17, 0x30);
676 printk("."); 649 printk(KERN_CONT ".");
677 iic(3,0x78,0x12,0x1a,0x97); 650 iic(3, 0x78, 0x12, 0x1a, 0x97);
678 iic(3,0x78,0x12,0x1b,0xff); 651 iic(3, 0x78, 0x12, 0x1b, 0xff);
679 iic(3,0x78,0x12,0x1c,0xff); 652 iic(3, 0x78, 0x12, 0x1c, 0xff);
680 iic(3,0x78,0x12,0x26,0x10); 653 iic(3, 0x78, 0x12, 0x26, 0x10);
681 iic(3,0x78,0x12,0x27,0x00); 654 iic(3, 0x78, 0x12, 0x27, 0x00);
682 printk("."); 655 printk(KERN_CONT ".");
683 iic(2,0x78,0x34,0x02,0x00); 656 iic(2, 0x78, 0x34, 0x02, 0x00);
684 iic(2,0x78,0x7a,0x10,0x00); 657 iic(2, 0x78, 0x7a, 0x10, 0x00);
685 iic(2,0x78,0x80,0x39,0x00); 658 iic(2, 0x78, 0x80, 0x39, 0x00);
686 iic(2,0x78,0x81,0xe6,0x00); 659 iic(2, 0x78, 0x81, 0xe6, 0x00);
687 iic(2,0x78,0x8d,0x00,0x00); 660 iic(2, 0x78, 0x8d, 0x00, 0x00);
688 printk("."); 661 printk(KERN_CONT ".");
689 iic(2,0x78,0x8e,0x0c,0x00); 662 iic(2, 0x78, 0x8e, 0x0c, 0x00);
690 iic(2,0x78,0x8f,0x00,0x00); 663 iic(2, 0x78, 0x8f, 0x00, 0x00);
691#if 0 664#if 0
692 iic(2,0x78,0x90,0x00,0x00); /* AWB on=1 off=0 */ 665 iic(2, 0x78, 0x90, 0x00, 0x00); /* AWB on=1 off=0 */
693#endif 666#endif
694 iic(2,0x78,0x93,0x01,0x00); 667 iic(2, 0x78, 0x93, 0x01, 0x00);
695 iic(2,0x78,0x94,0xcd,0x00); 668 iic(2, 0x78, 0x94, 0xcd, 0x00);
696 iic(2,0x78,0x95,0x00,0x00); 669 iic(2, 0x78, 0x95, 0x00, 0x00);
697 printk("."); 670 printk(KERN_CONT ".");
698 iic(2,0x78,0x96,0xa0,0x00); 671 iic(2, 0x78, 0x96, 0xa0, 0x00);
699 iic(2,0x78,0x97,0x00,0x00); 672 iic(2, 0x78, 0x97, 0x00, 0x00);
700 iic(2,0x78,0x98,0x60,0x00); 673 iic(2, 0x78, 0x98, 0x60, 0x00);
701 iic(2,0x78,0x99,0x01,0x00); 674 iic(2, 0x78, 0x99, 0x01, 0x00);
702 iic(2,0x78,0x9a,0x19,0x00); 675 iic(2, 0x78, 0x9a, 0x19, 0x00);
703 printk("."); 676 printk(KERN_CONT ".");
704 iic(2,0x78,0x9b,0x02,0x00); 677 iic(2, 0x78, 0x9b, 0x02, 0x00);
705 iic(2,0x78,0x9c,0xe8,0x00); 678 iic(2, 0x78, 0x9c, 0xe8, 0x00);
706 iic(2,0x78,0x9d,0x02,0x00); 679 iic(2, 0x78, 0x9d, 0x02, 0x00);
707 iic(2,0x78,0x9e,0x2e,0x00); 680 iic(2, 0x78, 0x9e, 0x2e, 0x00);
708 iic(2,0x78,0xb8,0x78,0x00); 681 iic(2, 0x78, 0xb8, 0x78, 0x00);
709 iic(2,0x78,0xba,0x05,0x00); 682 iic(2, 0x78, 0xba, 0x05, 0x00);
710#if 0 683#if 0
711 iic(2,0x78,0x83,0x8c,0x00); /* brightness */ 684 iic(2, 0x78, 0x83, 0x8c, 0x00); /* brightness */
712#endif 685#endif
713 printk("."); 686 printk(KERN_CONT ".");
714 687
715 /* color correction */ 688 /* color correction */
716 iic(3,0x78,0x49,0x00,0x95); /* a */ 689 iic(3, 0x78, 0x49, 0x00, 0x95); /* a */
717 iic(3,0x78,0x49,0x01,0x96); /* b */ 690 iic(3, 0x78, 0x49, 0x01, 0x96); /* b */
718 iic(3,0x78,0x49,0x03,0x85); /* c */ 691 iic(3, 0x78, 0x49, 0x03, 0x85); /* c */
719 iic(3,0x78,0x49,0x04,0x97); /* d */ 692 iic(3, 0x78, 0x49, 0x04, 0x97); /* d */
720 iic(3,0x78,0x49,0x02,0x7e); /* e(Lo) */ 693 iic(3, 0x78, 0x49, 0x02, 0x7e); /* e(Lo) */
721 iic(3,0x78,0x49,0x05,0xa4); /* f(Lo) */ 694 iic(3, 0x78, 0x49, 0x05, 0xa4); /* f(Lo) */
722 iic(3,0x78,0x49,0x06,0x04); /* e(Hi) */ 695 iic(3, 0x78, 0x49, 0x06, 0x04); /* e(Hi) */
723 iic(3,0x78,0x49,0x07,0x04); /* e(Hi) */ 696 iic(3, 0x78, 0x49, 0x07, 0x04); /* e(Hi) */
724 iic(2,0x78,0x48,0x01,0x00); /* on=1 off=0 */ 697 iic(2, 0x78, 0x48, 0x01, 0x00); /* on=1 off=0 */
725 698
726 printk("."); 699 printk(KERN_CONT ".");
727 iic(2,0x78,0x11,0x00,0x00); /* end */ 700 iic(2, 0x78, 0x11, 0x00, 0x00); /* end */
728 printk(" done\n"); 701 printk(KERN_CONT " done\n");
729 return 0; 702 return 0;
730} 703}
731 704
732 705
733void ar_release(struct video_device *vfd)
734{
735 struct ar_device *ar = video_get_drvdata(vfd);
736 mutex_lock(&ar->lock);
737 video_device_release(vfd);
738}
739
740/**************************************************************************** 706/****************************************************************************
741 * 707 *
742 * Video4Linux Module functions 708 * Video4Linux Module functions
743 * 709 *
744 ****************************************************************************/ 710 ****************************************************************************/
745static struct ar_device ardev;
746
747static int ar_exclusive_open(struct file *file)
748{
749 return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;
750}
751
752static int ar_exclusive_release(struct file *file)
753{
754 clear_bit(0, &ardev.in_use);
755 return 0;
756}
757 711
758static const struct v4l2_file_operations ar_fops = { 712static const struct v4l2_file_operations ar_fops = {
759 .owner = THIS_MODULE, 713 .owner = THIS_MODULE,
760 .open = ar_exclusive_open,
761 .release = ar_exclusive_release,
762 .read = ar_read, 714 .read = ar_read,
763 .ioctl = ar_ioctl, 715 .ioctl = video_ioctl2,
764}; 716};
765 717
766static struct video_device ar_template = { 718static const struct v4l2_ioctl_ops ar_ioctl_ops = {
767 .name = "Colour AR VGA", 719 .vidioc_querycap = ar_querycap,
768 .fops = &ar_fops, 720 .vidioc_g_input = ar_g_input,
769 .release = ar_release, 721 .vidioc_s_input = ar_s_input,
722 .vidioc_enum_input = ar_enum_input,
723 .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
724 .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
725 .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
726 .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
770}; 727};
771 728
772#define ALIGN4(x) ((((int)(x)) & 0x3) == 0) 729#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
773 730
774static int __init ar_init(void) 731static int __init ar_init(void)
775{ 732{
776 struct ar_device *ar; 733 struct ar *ar;
734 struct v4l2_device *v4l2_dev;
777 int ret; 735 int ret;
778 int i; 736 int i;
779 737
780 DEBUG(1, "ar_init:\n");
781 ret = -EIO;
782 printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);
783
784 ar = &ardev; 738 ar = &ardev;
785 memset(ar, 0, sizeof(struct ar_device)); 739 v4l2_dev = &ar->v4l2_dev;
740 strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name));
741 v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION);
742
743 ret = v4l2_device_register(NULL, v4l2_dev);
744 if (ret < 0) {
745 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
746 return ret;
747 }
748 ret = -EIO;
786 749
787#if USE_INT 750#if USE_INT
788 /* allocate a DMA buffer for 1 line. */ 751 /* allocate a DMA buffer for 1 line. */
789 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA); 752 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
790 if (ar->line_buff == NULL || ! ALIGN4(ar->line_buff)) { 753 if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) {
791 printk("arv: buffer allocation failed for DMA.\n"); 754 v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n");
792 ret = -ENOMEM; 755 ret = -ENOMEM;
793 goto out_end; 756 goto out_end;
794 } 757 }
@@ -796,20 +759,19 @@ static int __init ar_init(void)
796 /* allocate buffers for a frame */ 759 /* allocate buffers for a frame */
797 for (i = 0; i < MAX_AR_HEIGHT; i++) { 760 for (i = 0; i < MAX_AR_HEIGHT; i++) {
798 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL); 761 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
799 if (ar->frame[i] == NULL || ! ALIGN4(ar->frame[i])) { 762 if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) {
800 printk("arv: buffer allocation failed for frame.\n"); 763 v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n");
801 ret = -ENOMEM; 764 ret = -ENOMEM;
802 goto out_line_buff; 765 goto out_line_buff;
803 } 766 }
804 } 767 }
805 768
806 ar->vdev = video_device_alloc(); 769 strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name));
807 if (!ar->vdev) { 770 ar->vdev.v4l2_dev = v4l2_dev;
808 printk(KERN_ERR "arv: video_device_alloc() failed\n"); 771 ar->vdev.fops = &ar_fops;
809 return -ENOMEM; 772 ar->vdev.ioctl_ops = &ar_ioctl_ops;
810 } 773 ar->vdev.release = video_device_release_empty;
811 memcpy(ar->vdev, &ar_template, sizeof(ar_template)); 774 video_set_drvdata(&ar->vdev, ar);
812 video_set_drvdata(ar->vdev, ar);
813 775
814 if (vga) { 776 if (vga) {
815 ar->width = AR_WIDTH_VGA; 777 ar->width = AR_WIDTH_VGA;
@@ -834,14 +796,14 @@ static int __init ar_init(void)
834 796
835#if USE_INT 797#if USE_INT
836 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) { 798 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
837 printk("arv: request_irq(%d) failed.\n", M32R_IRQ_INT3); 799 v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3);
838 ret = -EIO; 800 ret = -EIO;
839 goto out_irq; 801 goto out_irq;
840 } 802 }
841#endif 803#endif
842 804
843 if (ar_initialize(ar->vdev) != 0) { 805 if (ar_initialize(ar) != 0) {
844 printk("arv: M64278 not found.\n"); 806 v4l2_err(v4l2_dev, "M64278 not found.\n");
845 ret = -ENODEV; 807 ret = -ENODEV;
846 goto out_dev; 808 goto out_dev;
847 } 809 }
@@ -852,15 +814,15 @@ static int __init ar_init(void)
852 * device is named "video[0-64]". 814 * device is named "video[0-64]".
853 * video_register_device() initializes h/w using ar_initialize(). 815 * video_register_device() initializes h/w using ar_initialize().
854 */ 816 */
855 if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { 817 if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
856 /* return -1, -ENFILE(full) or others */ 818 /* return -1, -ENFILE(full) or others */
857 printk("arv: register video (Colour AR) failed.\n"); 819 v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n");
858 ret = -ENODEV; 820 ret = -ENODEV;
859 goto out_dev; 821 goto out_dev;
860 } 822 }
861 823
862 printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", 824 v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
863 video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq); 825 video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq);
864 826
865 return 0; 827 return 0;
866 828
@@ -879,6 +841,7 @@ out_line_buff:
879 841
880out_end: 842out_end:
881#endif 843#endif
844 v4l2_device_unregister(&ar->v4l2_dev);
882 return ret; 845 return ret;
883} 846}
884 847
@@ -886,7 +849,7 @@ out_end:
886static int __init ar_init_module(void) 849static int __init ar_init_module(void)
887{ 850{
888 freq = (boot_cpu_data.bus_clock / 1000000); 851 freq = (boot_cpu_data.bus_clock / 1000000);
889 printk("arv: Bus clock %d\n", freq); 852 printk(KERN_INFO "arv: Bus clock %d\n", freq);
890 if (freq != 50 && freq != 75) 853 if (freq != 50 && freq != 75)
891 freq = DEFAULT_FREQ; 854 freq = DEFAULT_FREQ;
892 return ar_init(); 855 return ar_init();
@@ -894,11 +857,11 @@ static int __init ar_init_module(void)
894 857
895static void __exit ar_cleanup_module(void) 858static void __exit ar_cleanup_module(void)
896{ 859{
897 struct ar_device *ar; 860 struct ar *ar;
898 int i; 861 int i;
899 862
900 ar = &ardev; 863 ar = &ardev;
901 video_unregister_device(ar->vdev); 864 video_unregister_device(&ar->vdev);
902#if USE_INT 865#if USE_INT
903 free_irq(M32R_IRQ_INT3, ar); 866 free_irq(M32R_IRQ_INT3, ar);
904#endif 867#endif
@@ -907,6 +870,7 @@ static void __exit ar_cleanup_module(void)
907#if USE_INT 870#if USE_INT
908 kfree(ar->line_buff); 871 kfree(ar->line_buff);
909#endif 872#endif
873 v4l2_device_unregister(&ar->v4l2_dev);
910} 874}
911 875
912module_init(ar_init_module); 876module_init(ar_init_module);
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 8c140c01c5e6..66150216f976 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -1105,7 +1105,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
1105 1105
1106 tmp = input->index; 1106 tmp = input->index;
1107 1107
1108 if (tmp > AU0828_MAX_INPUT) 1108 if (tmp >= AU0828_MAX_INPUT)
1109 return -EINVAL; 1109 return -EINVAL;
1110 if (AUVI_INPUT(tmp).type == 0) 1110 if (AUVI_INPUT(tmp).type == 0)
1111 return -EINVAL; 1111 return -EINVAL;
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 716870ae85d5..7af56cde0c79 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -241,6 +241,10 @@ static struct CARD {
241 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" }, 241 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
242 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" }, 242 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
243 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" }, 243 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
244 { 0xa1550800, BTTV_BOARD_IVC200, "IVC-200" },
245 { 0xa1550801, BTTV_BOARD_IVC200, "IVC-200" },
246 { 0xa1550802, BTTV_BOARD_IVC200, "IVC-200" },
247 { 0xa1550803, BTTV_BOARD_IVC200, "IVC-200" },
244 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" }, 248 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
245 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" }, 249 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
246 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" }, 250 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index f4860f03dfc3..38c7f78ad9cf 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -1525,7 +1525,7 @@ static int bttv_s_ctrl(struct file *file, void *f,
1525 struct bttv_fh *fh = f; 1525 struct bttv_fh *fh = f;
1526 struct bttv *btv = fh->btv; 1526 struct bttv *btv = fh->btv;
1527 1527
1528 err = v4l2_prio_check(&btv->prio, &fh->prio); 1528 err = v4l2_prio_check(&btv->prio, fh->prio);
1529 if (0 != err) 1529 if (0 != err)
1530 return err; 1530 return err;
1531 1531
@@ -1806,8 +1806,8 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1806 *size = fh->fmt->depth*fh->width*fh->height >> 3; 1806 *size = fh->fmt->depth*fh->width*fh->height >> 3;
1807 if (0 == *count) 1807 if (0 == *count)
1808 *count = gbuffers; 1808 *count = gbuffers;
1809 while (*size * *count > gbuffers * gbufsize) 1809 if (*size * *count > gbuffers * gbufsize)
1810 (*count)--; 1810 *count = (gbuffers * gbufsize) / *size;
1811 return 0; 1811 return 0;
1812} 1812}
1813 1813
@@ -1859,7 +1859,7 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
1859 unsigned int i; 1859 unsigned int i;
1860 int err; 1860 int err;
1861 1861
1862 err = v4l2_prio_check(&btv->prio, &fh->prio); 1862 err = v4l2_prio_check(&btv->prio, fh->prio);
1863 if (0 != err) 1863 if (0 != err)
1864 return err; 1864 return err;
1865 1865
@@ -1941,7 +1941,7 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
1941 1941
1942 int err; 1942 int err;
1943 1943
1944 err = v4l2_prio_check(&btv->prio, &fh->prio); 1944 err = v4l2_prio_check(&btv->prio, fh->prio);
1945 if (0 != err) 1945 if (0 != err)
1946 return err; 1946 return err;
1947 1947
@@ -1961,7 +1961,7 @@ static int bttv_s_tuner(struct file *file, void *priv,
1961 struct bttv *btv = fh->btv; 1961 struct bttv *btv = fh->btv;
1962 int err; 1962 int err;
1963 1963
1964 err = v4l2_prio_check(&btv->prio, &fh->prio); 1964 err = v4l2_prio_check(&btv->prio, fh->prio);
1965 if (0 != err) 1965 if (0 != err)
1966 return err; 1966 return err;
1967 1967
@@ -1987,11 +1987,6 @@ static int bttv_g_frequency(struct file *file, void *priv,
1987{ 1987{
1988 struct bttv_fh *fh = priv; 1988 struct bttv_fh *fh = priv;
1989 struct bttv *btv = fh->btv; 1989 struct bttv *btv = fh->btv;
1990 int err;
1991
1992 err = v4l2_prio_check(&btv->prio, &fh->prio);
1993 if (0 != err)
1994 return err;
1995 1990
1996 f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1991 f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1997 f->frequency = btv->freq; 1992 f->frequency = btv->freq;
@@ -2006,7 +2001,7 @@ static int bttv_s_frequency(struct file *file, void *priv,
2006 struct bttv *btv = fh->btv; 2001 struct bttv *btv = fh->btv;
2007 int err; 2002 int err;
2008 2003
2009 err = v4l2_prio_check(&btv->prio, &fh->prio); 2004 err = v4l2_prio_check(&btv->prio, fh->prio);
2010 if (0 != err) 2005 if (0 != err)
2011 return err; 2006 return err;
2012 2007
@@ -3029,7 +3024,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
3029 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) 3024 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
3030 return -EINVAL; 3025 return -EINVAL;
3031 3026
3032 retval = v4l2_prio_check(&btv->prio, &fh->prio); 3027 retval = v4l2_prio_check(&btv->prio, fh->prio);
3033 if (0 != retval) 3028 if (0 != retval)
3034 return retval; 3029 return retval;
3035 3030
@@ -3241,7 +3236,7 @@ static int bttv_open(struct file *file)
3241 *fh = btv->init; 3236 *fh = btv->init;
3242 fh->type = type; 3237 fh->type = type;
3243 fh->ov.setup_ok = 0; 3238 fh->ov.setup_ok = 0;
3244 v4l2_prio_open(&btv->prio,&fh->prio); 3239 v4l2_prio_open(&btv->prio, &fh->prio);
3245 3240
3246 videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, 3241 videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
3247 &btv->c.pci->dev, &btv->s_lock, 3242 &btv->c.pci->dev, &btv->s_lock,
@@ -3312,7 +3307,7 @@ static int bttv_release(struct file *file)
3312 /* free stuff */ 3307 /* free stuff */
3313 videobuf_mmap_free(&fh->cap); 3308 videobuf_mmap_free(&fh->cap);
3314 videobuf_mmap_free(&fh->vbi); 3309 videobuf_mmap_free(&fh->vbi);
3315 v4l2_prio_close(&btv->prio,&fh->prio); 3310 v4l2_prio_close(&btv->prio, fh->prio);
3316 file->private_data = NULL; 3311 file->private_data = NULL;
3317 kfree(fh); 3312 kfree(fh);
3318 3313
@@ -3449,7 +3444,7 @@ static int radio_release(struct file *file)
3449 struct bttv *btv = fh->btv; 3444 struct bttv *btv = fh->btv;
3450 struct rds_command cmd; 3445 struct rds_command cmd;
3451 3446
3452 v4l2_prio_close(&btv->prio,&fh->prio); 3447 v4l2_prio_close(&btv->prio, fh->prio);
3453 file->private_data = NULL; 3448 file->private_data = NULL;
3454 kfree(fh); 3449 kfree(fh);
3455 3450
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index aa153a986ade..f68717a4bdec 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -49,6 +49,8 @@ module_param(ir_rc5_key_timeout, int, 0644);
49 49
50#define DEVNAME "bttv-input" 50#define DEVNAME "bttv-input"
51 51
52#define MODULE_NAME "bttv"
53
52/* ---------------------------------------------------------------------- */ 54/* ---------------------------------------------------------------------- */
53 55
54static void ir_handle_key(struct bttv *btv) 56static void ir_handle_key(struct bttv *btv)
@@ -246,7 +248,7 @@ static void bttv_ir_stop(struct bttv *btv)
246int bttv_input_init(struct bttv *btv) 248int bttv_input_init(struct bttv *btv)
247{ 249{
248 struct card_ir *ir; 250 struct card_ir *ir;
249 struct ir_scancode_table *ir_codes = NULL; 251 char *ir_codes = NULL;
250 struct input_dev *input_dev; 252 struct input_dev *input_dev;
251 u64 ir_type = IR_TYPE_OTHER; 253 u64 ir_type = IR_TYPE_OTHER;
252 int err = -ENOMEM; 254 int err = -ENOMEM;
@@ -264,7 +266,7 @@ int bttv_input_init(struct bttv *btv)
264 case BTTV_BOARD_AVERMEDIA: 266 case BTTV_BOARD_AVERMEDIA:
265 case BTTV_BOARD_AVPHONE98: 267 case BTTV_BOARD_AVPHONE98:
266 case BTTV_BOARD_AVERMEDIA98: 268 case BTTV_BOARD_AVERMEDIA98:
267 ir_codes = &ir_codes_avermedia_table; 269 ir_codes = RC_MAP_AVERMEDIA;
268 ir->mask_keycode = 0xf88000; 270 ir->mask_keycode = 0xf88000;
269 ir->mask_keydown = 0x010000; 271 ir->mask_keydown = 0x010000;
270 ir->polling = 50; // ms 272 ir->polling = 50; // ms
@@ -272,14 +274,14 @@ int bttv_input_init(struct bttv *btv)
272 274
273 case BTTV_BOARD_AVDVBT_761: 275 case BTTV_BOARD_AVDVBT_761:
274 case BTTV_BOARD_AVDVBT_771: 276 case BTTV_BOARD_AVDVBT_771:
275 ir_codes = &ir_codes_avermedia_dvbt_table; 277 ir_codes = RC_MAP_AVERMEDIA_DVBT;
276 ir->mask_keycode = 0x0f00c0; 278 ir->mask_keycode = 0x0f00c0;
277 ir->mask_keydown = 0x000020; 279 ir->mask_keydown = 0x000020;
278 ir->polling = 50; // ms 280 ir->polling = 50; // ms
279 break; 281 break;
280 282
281 case BTTV_BOARD_PXELVWPLTVPAK: 283 case BTTV_BOARD_PXELVWPLTVPAK:
282 ir_codes = &ir_codes_pixelview_table; 284 ir_codes = RC_MAP_PIXELVIEW;
283 ir->mask_keycode = 0x003e00; 285 ir->mask_keycode = 0x003e00;
284 ir->mask_keyup = 0x010000; 286 ir->mask_keyup = 0x010000;
285 ir->polling = 50; // ms 287 ir->polling = 50; // ms
@@ -287,24 +289,24 @@ int bttv_input_init(struct bttv *btv)
287 case BTTV_BOARD_PV_M4900: 289 case BTTV_BOARD_PV_M4900:
288 case BTTV_BOARD_PV_BT878P_9B: 290 case BTTV_BOARD_PV_BT878P_9B:
289 case BTTV_BOARD_PV_BT878P_PLUS: 291 case BTTV_BOARD_PV_BT878P_PLUS:
290 ir_codes = &ir_codes_pixelview_table; 292 ir_codes = RC_MAP_PIXELVIEW;
291 ir->mask_keycode = 0x001f00; 293 ir->mask_keycode = 0x001f00;
292 ir->mask_keyup = 0x008000; 294 ir->mask_keyup = 0x008000;
293 ir->polling = 50; // ms 295 ir->polling = 50; // ms
294 break; 296 break;
295 297
296 case BTTV_BOARD_WINFAST2000: 298 case BTTV_BOARD_WINFAST2000:
297 ir_codes = &ir_codes_winfast_table; 299 ir_codes = RC_MAP_WINFAST;
298 ir->mask_keycode = 0x1f8; 300 ir->mask_keycode = 0x1f8;
299 break; 301 break;
300 case BTTV_BOARD_MAGICTVIEW061: 302 case BTTV_BOARD_MAGICTVIEW061:
301 case BTTV_BOARD_MAGICTVIEW063: 303 case BTTV_BOARD_MAGICTVIEW063:
302 ir_codes = &ir_codes_winfast_table; 304 ir_codes = RC_MAP_WINFAST;
303 ir->mask_keycode = 0x0008e000; 305 ir->mask_keycode = 0x0008e000;
304 ir->mask_keydown = 0x00200000; 306 ir->mask_keydown = 0x00200000;
305 break; 307 break;
306 case BTTV_BOARD_APAC_VIEWCOMP: 308 case BTTV_BOARD_APAC_VIEWCOMP:
307 ir_codes = &ir_codes_apac_viewcomp_table; 309 ir_codes = RC_MAP_APAC_VIEWCOMP;
308 ir->mask_keycode = 0x001f00; 310 ir->mask_keycode = 0x001f00;
309 ir->mask_keyup = 0x008000; 311 ir->mask_keyup = 0x008000;
310 ir->polling = 50; // ms 312 ir->polling = 50; // ms
@@ -312,30 +314,30 @@ int bttv_input_init(struct bttv *btv)
312 case BTTV_BOARD_ASKEY_CPH03X: 314 case BTTV_BOARD_ASKEY_CPH03X:
313 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: 315 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
314 case BTTV_BOARD_CONTVFMI: 316 case BTTV_BOARD_CONTVFMI:
315 ir_codes = &ir_codes_pixelview_table; 317 ir_codes = RC_MAP_PIXELVIEW;
316 ir->mask_keycode = 0x001F00; 318 ir->mask_keycode = 0x001F00;
317 ir->mask_keyup = 0x006000; 319 ir->mask_keyup = 0x006000;
318 ir->polling = 50; // ms 320 ir->polling = 50; // ms
319 break; 321 break;
320 case BTTV_BOARD_NEBULA_DIGITV: 322 case BTTV_BOARD_NEBULA_DIGITV:
321 ir_codes = &ir_codes_nebula_table; 323 ir_codes = RC_MAP_NEBULA;
322 btv->custom_irq = bttv_rc5_irq; 324 btv->custom_irq = bttv_rc5_irq;
323 ir->rc5_gpio = 1; 325 ir->rc5_gpio = 1;
324 break; 326 break;
325 case BTTV_BOARD_MACHTV_MAGICTV: 327 case BTTV_BOARD_MACHTV_MAGICTV:
326 ir_codes = &ir_codes_apac_viewcomp_table; 328 ir_codes = RC_MAP_APAC_VIEWCOMP;
327 ir->mask_keycode = 0x001F00; 329 ir->mask_keycode = 0x001F00;
328 ir->mask_keyup = 0x004000; 330 ir->mask_keyup = 0x004000;
329 ir->polling = 50; /* ms */ 331 ir->polling = 50; /* ms */
330 break; 332 break;
331 case BTTV_BOARD_KOZUMI_KTV_01C: 333 case BTTV_BOARD_KOZUMI_KTV_01C:
332 ir_codes = &ir_codes_pctv_sedna_table; 334 ir_codes = RC_MAP_PCTV_SEDNA;
333 ir->mask_keycode = 0x001f00; 335 ir->mask_keycode = 0x001f00;
334 ir->mask_keyup = 0x006000; 336 ir->mask_keyup = 0x006000;
335 ir->polling = 50; /* ms */ 337 ir->polling = 50; /* ms */
336 break; 338 break;
337 case BTTV_BOARD_ENLTV_FM_2: 339 case BTTV_BOARD_ENLTV_FM_2:
338 ir_codes = &ir_codes_encore_enltv2_table; 340 ir_codes = RC_MAP_ENCORE_ENLTV2;
339 ir->mask_keycode = 0x00fd00; 341 ir->mask_keycode = 0x00fd00;
340 ir->mask_keyup = 0x000080; 342 ir->mask_keyup = 0x000080;
341 ir->polling = 1; /* ms */ 343 ir->polling = 1; /* ms */
@@ -390,7 +392,7 @@ int bttv_input_init(struct bttv *btv)
390 bttv_ir_start(btv, ir); 392 bttv_ir_start(btv, ir);
391 393
392 /* all done */ 394 /* all done */
393 err = ir_input_register(btv->remote->dev, ir_codes, NULL); 395 err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME);
394 if (err) 396 if (err)
395 goto err_out_stop; 397 goto err_out_stop;
396 398
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 9e39bc5f7b00..3c9e754d73a0 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -80,8 +80,8 @@ OTHER DEALINGS IN THE SOFTWARE.
80 80
81#include "bw-qcam.h" 81#include "bw-qcam.h"
82 82
83static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */ 83static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
84static unsigned int yieldlines=4; /* Yield after this many during capture */ 84static unsigned int yieldlines = 4; /* Yield after this many during capture */
85static int video_nr = -1; 85static int video_nr = -1;
86static unsigned int force_init; /* Whether to probe aggressively */ 86static unsigned int force_init; /* Whether to probe aggressively */
87 87
@@ -156,7 +156,7 @@ static int qc_calibrate(struct qcam_device *q)
156 mdelay(1); 156 mdelay(1);
157 schedule(); 157 schedule();
158 count++; 158 count++;
159 } while (value == 0xff && count<2048); 159 } while (value == 0xff && count < 2048);
160 160
161 q->whitebal = value; 161 q->whitebal = value;
162 return value; 162 return value;
@@ -170,16 +170,15 @@ static struct qcam_device *qcam_init(struct parport *port)
170 struct qcam_device *q; 170 struct qcam_device *q;
171 171
172 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); 172 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
173 if(q==NULL) 173 if (q == NULL)
174 return NULL; 174 return NULL;
175 175
176 q->pport = port; 176 q->pport = port;
177 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, 177 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
178 NULL, 0, NULL); 178 NULL, 0, NULL);
179 if (q->pdev == NULL) 179 if (q->pdev == NULL) {
180 {
181 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n", 180 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
182 port->name); 181 port->name);
183 kfree(q); 182 kfree(q);
184 return NULL; 183 return NULL;
185 } 184 }
@@ -247,12 +246,10 @@ static int qc_readparam(struct qcam_device *q)
247static int qc_waithand(struct qcam_device *q, int val) 246static int qc_waithand(struct qcam_device *q, int val)
248{ 247{
249 int status; 248 int status;
250 int runs=0; 249 int runs = 0;
251 250
252 if (val) 251 if (val) {
253 { 252 while (!((status = read_lpstatus(q)) & 8)) {
254 while (!((status = read_lpstatus(q)) & 8))
255 {
256 /* 1000 is enough spins on the I/O for all normal 253 /* 1000 is enough spins on the I/O for all normal
257 cases, at that point we start to poll slowly 254 cases, at that point we start to poll slowly
258 until the camera wakes up. However, we are 255 until the camera wakes up. However, we are
@@ -260,18 +257,13 @@ static int qc_waithand(struct qcam_device *q, int val)
260 setting it lower is much better for interactive 257 setting it lower is much better for interactive
261 response. */ 258 response. */
262 259
263 if(runs++>maxpoll) 260 if (runs++ > maxpoll)
264 {
265 msleep_interruptible(5); 261 msleep_interruptible(5);
266 } 262 if (runs > (maxpoll + 1000)) /* 5 seconds */
267 if(runs>(maxpoll+1000)) /* 5 seconds */
268 return -1; 263 return -1;
269 } 264 }
270 } 265 } else {
271 else 266 while (((status = read_lpstatus(q)) & 8)) {
272 {
273 while (((status = read_lpstatus(q)) & 8))
274 {
275 /* 1000 is enough spins on the I/O for all normal 267 /* 1000 is enough spins on the I/O for all normal
276 cases, at that point we start to poll slowly 268 cases, at that point we start to poll slowly
277 until the camera wakes up. However, we are 269 until the camera wakes up. However, we are
@@ -279,11 +271,9 @@ static int qc_waithand(struct qcam_device *q, int val)
279 setting it lower is much better for interactive 271 setting it lower is much better for interactive
280 response. */ 272 response. */
281 273
282 if(runs++>maxpoll) 274 if (runs++ > maxpoll)
283 {
284 msleep_interruptible(5); 275 msleep_interruptible(5);
285 } 276 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
286 if(runs++>(maxpoll+1000)) /* 5 seconds */
287 return -1; 277 return -1;
288 } 278 }
289 } 279 }
@@ -299,10 +289,9 @@ static int qc_waithand(struct qcam_device *q, int val)
299static unsigned int qc_waithand2(struct qcam_device *q, int val) 289static unsigned int qc_waithand2(struct qcam_device *q, int val)
300{ 290{
301 unsigned int status; 291 unsigned int status;
302 int runs=0; 292 int runs = 0;
303 293
304 do 294 do {
305 {
306 status = read_lpdata(q); 295 status = read_lpdata(q);
307 /* 1000 is enough spins on the I/O for all normal 296 /* 1000 is enough spins on the I/O for all normal
308 cases, at that point we start to poll slowly 297 cases, at that point we start to poll slowly
@@ -311,14 +300,11 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
311 setting it lower is much better for interactive 300 setting it lower is much better for interactive
312 response. */ 301 response. */
313 302
314 if(runs++>maxpoll) 303 if (runs++ > maxpoll)
315 {
316 msleep_interruptible(5); 304 msleep_interruptible(5);
317 } 305 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
318 if(runs++>(maxpoll+1000)) /* 5 seconds */
319 return 0; 306 return 0;
320 } 307 } while ((status & 1) != val);
321 while ((status & 1) != val);
322 308
323 return status; 309 return status;
324} 310}
@@ -342,8 +328,7 @@ static int qc_detect(struct qcam_device *q)
342 328
343 lastreg = reg = read_lpstatus(q) & 0xf0; 329 lastreg = reg = read_lpstatus(q) & 0xf0;
344 330
345 for (i = 0; i < 500; i++) 331 for (i = 0; i < 500; i++) {
346 {
347 reg = read_lpstatus(q) & 0xf0; 332 reg = read_lpstatus(q) & 0xf0;
348 if (reg != lastreg) 333 if (reg != lastreg)
349 count++; 334 count++;
@@ -357,7 +342,7 @@ static int qc_detect(struct qcam_device *q)
357 won't be flashing these bits. Possibly unloading the module 342 won't be flashing these bits. Possibly unloading the module
358 in the middle of a grab? Or some timeout condition? 343 in the middle of a grab? Or some timeout condition?
359 I've seen this parameter as low as 19 on my 450Mhz box - mpc */ 344 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
360 printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count); 345 printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
361 return 1; 346 return 1;
362#endif 347#endif
363 348
@@ -367,7 +352,7 @@ static int qc_detect(struct qcam_device *q)
367 return 1; /* found */ 352 return 1; /* found */
368 } else { 353 } else {
369 printk(KERN_ERR "No Quickcam found on port %s\n", 354 printk(KERN_ERR "No Quickcam found on port %s\n",
370 q->pport->name); 355 q->pport->name);
371 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count); 356 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
372 return 0; /* not found */ 357 return 0; /* not found */
373 } 358 }
@@ -381,26 +366,24 @@ static int qc_detect(struct qcam_device *q)
381 366
382static void qc_reset(struct qcam_device *q) 367static void qc_reset(struct qcam_device *q)
383{ 368{
384 switch (q->port_mode & QC_FORCE_MASK) 369 switch (q->port_mode & QC_FORCE_MASK) {
385 { 370 case QC_FORCE_UNIDIR:
386 case QC_FORCE_UNIDIR: 371 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
387 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; 372 break;
388 break;
389 373
390 case QC_FORCE_BIDIR: 374 case QC_FORCE_BIDIR:
391 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; 375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
392 break; 376 break;
393 377
394 case QC_ANY: 378 case QC_ANY:
395 write_lpcontrol(q, 0x20); 379 write_lpcontrol(q, 0x20);
396 write_lpdata(q, 0x75); 380 write_lpdata(q, 0x75);
397 381
398 if (read_lpdata(q) != 0x75) { 382 if (read_lpdata(q) != 0x75)
399 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; 383 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
400 } else { 384 else
401 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; 385 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
402 } 386 break;
403 break;
404 } 387 }
405 388
406 write_lpcontrol(q, 0xb); 389 write_lpcontrol(q, 0xb);
@@ -423,36 +406,33 @@ static int qc_setscanmode(struct qcam_device *q)
423{ 406{
424 int old_mode = q->mode; 407 int old_mode = q->mode;
425 408
426 switch (q->transfer_scale) 409 switch (q->transfer_scale) {
427 { 410 case 1:
428 case 1: 411 q->mode = 0;
429 q->mode = 0; 412 break;
430 break; 413 case 2:
431 case 2: 414 q->mode = 4;
432 q->mode = 4; 415 break;
433 break; 416 case 4:
434 case 4: 417 q->mode = 8;
435 q->mode = 8; 418 break;
436 break;
437 } 419 }
438 420
439 switch (q->bpp) 421 switch (q->bpp) {
440 { 422 case 4:
441 case 4: 423 break;
442 break; 424 case 6:
443 case 6: 425 q->mode += 2;
444 q->mode += 2; 426 break;
445 break;
446 } 427 }
447 428
448 switch (q->port_mode & QC_MODE_MASK) 429 switch (q->port_mode & QC_MODE_MASK) {
449 { 430 case QC_BIDIR:
450 case QC_BIDIR: 431 q->mode += 1;
451 q->mode += 1; 432 break;
452 break; 433 case QC_NOTSET:
453 case QC_NOTSET: 434 case QC_UNIDIR:
454 case QC_UNIDIR: 435 break;
455 break;
456 } 436 }
457 437
458 if (q->mode != old_mode) 438 if (q->mode != old_mode)
@@ -493,7 +473,7 @@ static void qc_set(struct qcam_device *q)
493 } else { 473 } else {
494 val = q->width * q->bpp; 474 val = q->width * q->bpp;
495 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * 475 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
496 q->transfer_scale; 476 q->transfer_scale;
497 } 477 }
498 val = DIV_ROUND_UP(val, val2); 478 val = DIV_ROUND_UP(val, val2);
499 qc_command(q, 0x13); 479 qc_command(q, 0x13);
@@ -521,85 +501,80 @@ static void qc_set(struct qcam_device *q)
521 501
522static inline int qc_readbytes(struct qcam_device *q, char buffer[]) 502static inline int qc_readbytes(struct qcam_device *q, char buffer[])
523{ 503{
524 int ret=1; 504 int ret = 1;
525 unsigned int hi, lo; 505 unsigned int hi, lo;
526 unsigned int hi2, lo2; 506 unsigned int hi2, lo2;
527 static int state; 507 static int state;
528 508
529 if (buffer == NULL) 509 if (buffer == NULL) {
530 {
531 state = 0; 510 state = 0;
532 return 0; 511 return 0;
533 } 512 }
534 513
535 switch (q->port_mode & QC_MODE_MASK) 514 switch (q->port_mode & QC_MODE_MASK) {
536 { 515 case QC_BIDIR: /* Bi-directional Port */
537 case QC_BIDIR: /* Bi-directional Port */ 516 write_lpcontrol(q, 0x26);
538 write_lpcontrol(q, 0x26); 517 lo = (qc_waithand2(q, 1) >> 1);
539 lo = (qc_waithand2(q, 1) >> 1); 518 hi = (read_lpstatus(q) >> 3) & 0x1f;
540 hi = (read_lpstatus(q) >> 3) & 0x1f; 519 write_lpcontrol(q, 0x2e);
541 write_lpcontrol(q, 0x2e); 520 lo2 = (qc_waithand2(q, 0) >> 1);
542 lo2 = (qc_waithand2(q, 0) >> 1); 521 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
543 hi2 = (read_lpstatus(q) >> 3) & 0x1f; 522 switch (q->bpp) {
544 switch (q->bpp) 523 case 4:
545 { 524 buffer[0] = lo & 0xf;
546 case 4: 525 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
547 buffer[0] = lo & 0xf; 526 buffer[2] = (hi & 0x1e) >> 1;
548 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3); 527 buffer[3] = lo2 & 0xf;
549 buffer[2] = (hi & 0x1e) >> 1; 528 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
550 buffer[3] = lo2 & 0xf; 529 buffer[5] = (hi2 & 0x1e) >> 1;
551 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3); 530 ret = 6;
552 buffer[5] = (hi2 & 0x1e) >> 1; 531 break;
553 ret = 6; 532 case 6:
554 break; 533 buffer[0] = lo & 0x3f;
555 case 6: 534 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
556 buffer[0] = lo & 0x3f; 535 buffer[2] = lo2 & 0x3f;
557 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1); 536 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
558 buffer[2] = lo2 & 0x3f; 537 ret = 4;
559 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
560 ret = 4;
561 break;
562 }
563 break; 538 break;
539 }
540 break;
541
542 case QC_UNIDIR: /* Unidirectional Port */
543 write_lpcontrol(q, 6);
544 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
545 write_lpcontrol(q, 0xe);
546 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
564 547
565 case QC_UNIDIR: /* Unidirectional Port */ 548 switch (q->bpp) {
566 write_lpcontrol(q, 6); 549 case 4:
567 lo = (qc_waithand(q, 1) & 0xf0) >> 4; 550 buffer[0] = lo;
568 write_lpcontrol(q, 0xe); 551 buffer[1] = hi;
569 hi = (qc_waithand(q, 0) & 0xf0) >> 4; 552 ret = 2;
570 553 break;
571 switch (q->bpp) 554 case 6:
572 { 555 switch (state) {
573 case 4: 556 case 0:
574 buffer[0] = lo; 557 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
575 buffer[1] = hi; 558 q->saved_bits = (hi & 3) << 4;
576 ret = 2; 559 state = 1;
577 break; 560 ret = 1;
578 case 6: 561 break;
579 switch (state) 562 case 1:
580 { 563 buffer[0] = lo | q->saved_bits;
581 case 0: 564 q->saved_bits = hi << 2;
582 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2); 565 state = 2;
583 q->saved_bits = (hi & 3) << 4; 566 ret = 1;
584 state = 1; 567 break;
585 ret = 1; 568 case 2:
586 break; 569 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
587 case 1: 570 buffer[1] = ((lo & 3) << 4) | hi;
588 buffer[0] = lo | q->saved_bits; 571 state = 0;
589 q->saved_bits = hi << 2; 572 ret = 2;
590 state = 2; 573 break;
591 ret = 1;
592 break;
593 case 2:
594 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
595 buffer[1] = ((lo & 3) << 4) | hi;
596 state = 0;
597 ret = 2;
598 break;
599 }
600 break;
601 } 574 }
602 break; 575 break;
576 }
577 break;
603 } 578 }
604 return ret; 579 return ret;
605} 580}
@@ -615,7 +590,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
615 * n=2^(bit depth)-1. Ask me for more details if you don't understand 590 * n=2^(bit depth)-1. Ask me for more details if you don't understand
616 * this. */ 591 * this. */
617 592
618static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len) 593static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
619{ 594{
620 int i, j, k, yield; 595 int i, j, k, yield;
621 int bytes; 596 int bytes;
@@ -623,9 +598,9 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
623 int divisor; 598 int divisor;
624 int pixels_per_line; 599 int pixels_per_line;
625 int pixels_read = 0; 600 int pixels_read = 0;
626 int got=0; 601 int got = 0;
627 char buffer[6]; 602 char buffer[6];
628 int shift=8-q->bpp; 603 int shift = 8 - q->bpp;
629 char invert; 604 char invert;
630 605
631 if (q->mode == -1) 606 if (q->mode == -1)
@@ -634,13 +609,12 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
634 qc_command(q, 0x7); 609 qc_command(q, 0x7);
635 qc_command(q, q->mode); 610 qc_command(q, q->mode);
636 611
637 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) 612 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
638 {
639 write_lpcontrol(q, 0x2e); /* turn port around */ 613 write_lpcontrol(q, 0x2e); /* turn port around */
640 write_lpcontrol(q, 0x26); 614 write_lpcontrol(q, 0x26);
641 (void) qc_waithand(q, 1); 615 qc_waithand(q, 1);
642 write_lpcontrol(q, 0x2e); 616 write_lpcontrol(q, 0x2e);
643 (void) qc_waithand(q, 0); 617 qc_waithand(q, 0);
644 } 618 }
645 619
646 /* strange -- should be 15:63 below, but 4bpp is odd */ 620 /* strange -- should be 15:63 below, but 4bpp is odd */
@@ -650,33 +624,28 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
650 pixels_per_line = q->width / q->transfer_scale; 624 pixels_per_line = q->width / q->transfer_scale;
651 transperline = q->width * q->bpp; 625 transperline = q->width * q->bpp;
652 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * 626 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
653 q->transfer_scale; 627 q->transfer_scale;
654 transperline = DIV_ROUND_UP(transperline, divisor); 628 transperline = DIV_ROUND_UP(transperline, divisor);
655 629
656 for (i = 0, yield = yieldlines; i < linestotrans; i++) 630 for (i = 0, yield = yieldlines; i < linestotrans; i++) {
657 { 631 for (pixels_read = j = 0; j < transperline; j++) {
658 for (pixels_read = j = 0; j < transperline; j++)
659 {
660 bytes = qc_readbytes(q, buffer); 632 bytes = qc_readbytes(q, buffer);
661 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) 633 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
662 {
663 int o; 634 int o;
664 if (buffer[k] == 0 && invert == 16) 635 if (buffer[k] == 0 && invert == 16) {
665 {
666 /* 4bpp is odd (again) -- inverter is 16, not 15, but output 636 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
667 must be 0-15 -- bls */ 637 must be 0-15 -- bls */
668 buffer[k] = 16; 638 buffer[k] = 16;
669 } 639 }
670 o=i*pixels_per_line + pixels_read + k; 640 o = i * pixels_per_line + pixels_read + k;
671 if(o<len) 641 if (o < len) {
672 {
673 got++; 642 got++;
674 put_user((invert - buffer[k])<<shift, buf+o); 643 put_user((invert - buffer[k]) << shift, buf + o);
675 } 644 }
676 } 645 }
677 pixels_read += bytes; 646 pixels_read += bytes;
678 } 647 }
679 (void) qc_readbytes(q, NULL); /* reset state machine */ 648 qc_readbytes(q, NULL); /* reset state machine */
680 649
681 /* Grabbing an entire frame from the quickcam is a lengthy 650 /* Grabbing an entire frame from the quickcam is a lengthy
682 process. We don't (usually) want to busy-block the 651 process. We don't (usually) want to busy-block the
@@ -690,14 +659,13 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
690 } 659 }
691 } 660 }
692 661
693 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) 662 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
694 {
695 write_lpcontrol(q, 2); 663 write_lpcontrol(q, 2);
696 write_lpcontrol(q, 6); 664 write_lpcontrol(q, 6);
697 udelay(3); 665 udelay(3);
698 write_lpcontrol(q, 0xe); 666 write_lpcontrol(q, 0xe);
699 } 667 }
700 if(got<len) 668 if (got < len)
701 return got; 669 return got;
702 return len; 670 return len;
703} 671}
@@ -709,11 +677,10 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
709static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) 677static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
710{ 678{
711 struct video_device *dev = video_devdata(file); 679 struct video_device *dev = video_devdata(file);
712 struct qcam_device *qcam=(struct qcam_device *)dev; 680 struct qcam_device *qcam = (struct qcam_device *)dev;
713 681
714 switch(cmd) 682 switch (cmd) {
715 { 683 case VIDIOCGCAP:
716 case VIDIOCGCAP:
717 { 684 {
718 struct video_capability *b = arg; 685 struct video_capability *b = arg;
719 strcpy(b->name, "Quickcam"); 686 strcpy(b->name, "Quickcam");
@@ -726,73 +693,73 @@ static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
726 b->minheight = 60; 693 b->minheight = 60;
727 return 0; 694 return 0;
728 } 695 }
729 case VIDIOCGCHAN: 696 case VIDIOCGCHAN:
730 { 697 {
731 struct video_channel *v = arg; 698 struct video_channel *v = arg;
732 if(v->channel!=0) 699 if (v->channel != 0)
733 return -EINVAL; 700 return -EINVAL;
734 v->flags=0; 701 v->flags = 0;
735 v->tuners=0; 702 v->tuners = 0;
736 /* Good question.. its composite or SVHS so.. */ 703 /* Good question.. its composite or SVHS so.. */
737 v->type = VIDEO_TYPE_CAMERA; 704 v->type = VIDEO_TYPE_CAMERA;
738 strcpy(v->name, "Camera"); 705 strcpy(v->name, "Camera");
739 return 0; 706 return 0;
740 } 707 }
741 case VIDIOCSCHAN: 708 case VIDIOCSCHAN:
742 { 709 {
743 struct video_channel *v = arg; 710 struct video_channel *v = arg;
744 if(v->channel!=0) 711 if (v->channel != 0)
745 return -EINVAL; 712 return -EINVAL;
746 return 0; 713 return 0;
747 } 714 }
748 case VIDIOCGTUNER: 715 case VIDIOCGTUNER:
749 { 716 {
750 struct video_tuner *v = arg; 717 struct video_tuner *v = arg;
751 if(v->tuner) 718 if (v->tuner)
752 return -EINVAL; 719 return -EINVAL;
753 strcpy(v->name, "Format"); 720 strcpy(v->name, "Format");
754 v->rangelow=0; 721 v->rangelow = 0;
755 v->rangehigh=0; 722 v->rangehigh = 0;
756 v->flags= 0; 723 v->flags = 0;
757 v->mode = VIDEO_MODE_AUTO; 724 v->mode = VIDEO_MODE_AUTO;
758 return 0; 725 return 0;
759 } 726 }
760 case VIDIOCSTUNER: 727 case VIDIOCSTUNER:
761 { 728 {
762 struct video_tuner *v = arg; 729 struct video_tuner *v = arg;
763 if(v->tuner) 730 if (v->tuner)
764 return -EINVAL; 731 return -EINVAL;
765 if(v->mode!=VIDEO_MODE_AUTO) 732 if (v->mode != VIDEO_MODE_AUTO)
766 return -EINVAL; 733 return -EINVAL;
767 return 0; 734 return 0;
768 } 735 }
769 case VIDIOCGPICT: 736 case VIDIOCGPICT:
770 { 737 {
771 struct video_picture *p = arg; 738 struct video_picture *p = arg;
772 p->colour=0x8000; 739 p->colour = 0x8000;
773 p->hue=0x8000; 740 p->hue = 0x8000;
774 p->brightness=qcam->brightness<<8; 741 p->brightness = qcam->brightness << 8;
775 p->contrast=qcam->contrast<<8; 742 p->contrast = qcam->contrast << 8;
776 p->whiteness=qcam->whitebal<<8; 743 p->whiteness = qcam->whitebal << 8;
777 p->depth=qcam->bpp; 744 p->depth = qcam->bpp;
778 p->palette=VIDEO_PALETTE_GREY; 745 p->palette = VIDEO_PALETTE_GREY;
779 return 0; 746 return 0;
780 } 747 }
781 case VIDIOCSPICT: 748 case VIDIOCSPICT:
782 { 749 {
783 struct video_picture *p = arg; 750 struct video_picture *p = arg;
784 if(p->palette!=VIDEO_PALETTE_GREY) 751 if (p->palette != VIDEO_PALETTE_GREY)
785 return -EINVAL; 752 return -EINVAL;
786 if(p->depth!=4 && p->depth!=6) 753 if (p->depth != 4 && p->depth != 6)
787 return -EINVAL; 754 return -EINVAL;
788 755
789 /* 756 /*
790 * Now load the camera. 757 * Now load the camera.
791 */ 758 */
792 759
793 qcam->brightness = p->brightness>>8; 760 qcam->brightness = p->brightness >> 8;
794 qcam->contrast = p->contrast>>8; 761 qcam->contrast = p->contrast >> 8;
795 qcam->whitebal = p->whiteness>>8; 762 qcam->whitebal = p->whiteness >> 8;
796 qcam->bpp = p->depth; 763 qcam->bpp = p->depth;
797 764
798 mutex_lock(&qcam->lock); 765 mutex_lock(&qcam->lock);
@@ -802,28 +769,25 @@ static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
802 769
803 return 0; 770 return 0;
804 } 771 }
805 case VIDIOCSWIN: 772 case VIDIOCSWIN:
806 { 773 {
807 struct video_window *vw = arg; 774 struct video_window *vw = arg;
808 if(vw->flags) 775 if (vw->flags)
809 return -EINVAL; 776 return -EINVAL;
810 if(vw->clipcount) 777 if (vw->clipcount)
811 return -EINVAL; 778 return -EINVAL;
812 if(vw->height<60||vw->height>240) 779 if (vw->height < 60 || vw->height > 240)
813 return -EINVAL; 780 return -EINVAL;
814 if(vw->width<80||vw->width>320) 781 if (vw->width < 80 || vw->width > 320)
815 return -EINVAL; 782 return -EINVAL;
816 783
817 qcam->width = 320; 784 qcam->width = 320;
818 qcam->height = 240; 785 qcam->height = 240;
819 qcam->transfer_scale = 4; 786 qcam->transfer_scale = 4;
820 787
821 if(vw->width>=160 && vw->height>=120) 788 if (vw->width >= 160 && vw->height >= 120)
822 {
823 qcam->transfer_scale = 2; 789 qcam->transfer_scale = 2;
824 } 790 if (vw->width >= 320 && vw->height >= 240) {
825 if(vw->width>=320 && vw->height>=240)
826 {
827 qcam->width = 320; 791 qcam->width = 320;
828 qcam->height = 240; 792 qcam->height = 240;
829 qcam->transfer_scale = 1; 793 qcam->transfer_scale = 1;
@@ -839,41 +803,42 @@ static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
839 /* Ok we figured out what to use from our wide choice */ 803 /* Ok we figured out what to use from our wide choice */
840 return 0; 804 return 0;
841 } 805 }
842 case VIDIOCGWIN: 806 case VIDIOCGWIN:
843 { 807 {
844 struct video_window *vw = arg; 808 struct video_window *vw = arg;
809
845 memset(vw, 0, sizeof(*vw)); 810 memset(vw, 0, sizeof(*vw));
846 vw->width=qcam->width/qcam->transfer_scale; 811 vw->width = qcam->width / qcam->transfer_scale;
847 vw->height=qcam->height/qcam->transfer_scale; 812 vw->height = qcam->height / qcam->transfer_scale;
848 return 0; 813 return 0;
849 } 814 }
850 case VIDIOCKEY: 815 case VIDIOCKEY:
851 return 0; 816 return 0;
852 case VIDIOCCAPTURE: 817 case VIDIOCCAPTURE:
853 case VIDIOCGFBUF: 818 case VIDIOCGFBUF:
854 case VIDIOCSFBUF: 819 case VIDIOCSFBUF:
855 case VIDIOCGFREQ: 820 case VIDIOCGFREQ:
856 case VIDIOCSFREQ: 821 case VIDIOCSFREQ:
857 case VIDIOCGAUDIO: 822 case VIDIOCGAUDIO:
858 case VIDIOCSAUDIO: 823 case VIDIOCSAUDIO:
859 return -EINVAL; 824 return -EINVAL;
860 default: 825 default:
861 return -ENOIOCTLCMD; 826 return -ENOIOCTLCMD;
862 } 827 }
863 return 0; 828 return 0;
864} 829}
865 830
866static long qcam_ioctl(struct file *file, 831static long qcam_ioctl(struct file *file,
867 unsigned int cmd, unsigned long arg) 832 unsigned int cmd, unsigned long arg)
868{ 833{
869 return video_usercopy(file, cmd, arg, qcam_do_ioctl); 834 return video_usercopy(file, cmd, arg, qcam_do_ioctl);
870} 835}
871 836
872static ssize_t qcam_read(struct file *file, char __user *buf, 837static ssize_t qcam_read(struct file *file, char __user *buf,
873 size_t count, loff_t *ppos) 838 size_t count, loff_t *ppos)
874{ 839{
875 struct video_device *v = video_devdata(file); 840 struct video_device *v = video_devdata(file);
876 struct qcam_device *qcam=(struct qcam_device *)v; 841 struct qcam_device *qcam = (struct qcam_device *)v;
877 int len; 842 int len;
878 parport_claim_or_block(qcam->pdev); 843 parport_claim_or_block(qcam->pdev);
879 844
@@ -885,7 +850,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
885 if (qcam->status & QC_PARAM_CHANGE) 850 if (qcam->status & QC_PARAM_CHANGE)
886 qc_set(qcam); 851 qc_set(qcam);
887 852
888 len=qc_capture(qcam, buf,count); 853 len = qc_capture(qcam, buf, count);
889 854
890 mutex_unlock(&qcam->lock); 855 mutex_unlock(&qcam->lock);
891 856
@@ -917,8 +882,7 @@ static const struct v4l2_file_operations qcam_fops = {
917 .ioctl = qcam_ioctl, 882 .ioctl = qcam_ioctl,
918 .read = qcam_read, 883 .read = qcam_read,
919}; 884};
920static struct video_device qcam_template= 885static struct video_device qcam_template = {
921{
922 .name = "Connectix Quickcam", 886 .name = "Connectix Quickcam",
923 .fops = &qcam_fops, 887 .fops = &qcam_fops,
924 .release = video_device_release_empty, 888 .release = video_device_release_empty,
@@ -932,22 +896,20 @@ static int init_bwqcam(struct parport *port)
932{ 896{
933 struct qcam_device *qcam; 897 struct qcam_device *qcam;
934 898
935 if (num_cams == MAX_CAMS) 899 if (num_cams == MAX_CAMS) {
936 {
937 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); 900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
938 return -ENOSPC; 901 return -ENOSPC;
939 } 902 }
940 903
941 qcam=qcam_init(port); 904 qcam = qcam_init(port);
942 if(qcam==NULL) 905 if (qcam == NULL)
943 return -ENODEV; 906 return -ENODEV;
944 907
945 parport_claim_or_block(qcam->pdev); 908 parport_claim_or_block(qcam->pdev);
946 909
947 qc_reset(qcam); 910 qc_reset(qcam);
948 911
949 if(qc_detect(qcam)==0) 912 if (qc_detect(qcam) == 0) {
950 {
951 parport_release(qcam->pdev); 913 parport_release(qcam->pdev);
952 parport_unregister_device(qcam->pdev); 914 parport_unregister_device(qcam->pdev);
953 kfree(qcam); 915 kfree(qcam);
@@ -1045,12 +1007,12 @@ static int __init init_bw_qcams(void)
1045#ifdef MODULE 1007#ifdef MODULE
1046 /* Do some sanity checks on the module parameters. */ 1008 /* Do some sanity checks on the module parameters. */
1047 if (maxpoll > 5000) { 1009 if (maxpoll > 5000) {
1048 printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n"); 1010 printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
1049 maxpoll = 5000; 1011 maxpoll = 5000;
1050 } 1012 }
1051 1013
1052 if (yieldlines < 1) { 1014 if (yieldlines < 1) {
1053 printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n"); 1015 printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
1054 yieldlines = 1; 1016 yieldlines = 1;
1055 } 1017 }
1056#endif 1018#endif
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index e2cbebab959b..8f1dd88b32a6 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -79,17 +79,17 @@ static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
79{ 79{
80 /* note: the QC specs refer to the PCAck pin by voltage, not 80 /* note: the QC specs refer to the PCAck pin by voltage, not
81 software level. PC ports have builtin inverters. */ 81 software level. PC ports have builtin inverters. */
82 parport_frob_control(qcam->pport, 8, i?8:0); 82 parport_frob_control(qcam->pport, 8, i ? 8 : 0);
83} 83}
84 84
85static inline unsigned int qcam_ready1(struct qcam_device *qcam) 85static inline unsigned int qcam_ready1(struct qcam_device *qcam)
86{ 86{
87 return (parport_read_status(qcam->pport) & 0x8)?1:0; 87 return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0;
88} 88}
89 89
90static inline unsigned int qcam_ready2(struct qcam_device *qcam) 90static inline unsigned int qcam_ready2(struct qcam_device *qcam)
91{ 91{
92 return (parport_read_data(qcam->pport) & 0x1)?1:0; 92 return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0;
93} 93}
94 94
95static unsigned int qcam_await_ready1(struct qcam_device *qcam, 95static unsigned int qcam_await_ready1(struct qcam_device *qcam,
@@ -99,14 +99,13 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam,
99 unsigned int i; 99 unsigned int i;
100 100
101 for (oldjiffies = jiffies; 101 for (oldjiffies = jiffies;
102 time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); ) 102 time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
103 if (qcam_ready1(qcam) == value) 103 if (qcam_ready1(qcam) == value)
104 return 0; 104 return 0;
105 105
106 /* If the camera didn't respond within 1/25 second, poll slowly 106 /* If the camera didn't respond within 1/25 second, poll slowly
107 for a while. */ 107 for a while. */
108 for (i = 0; i < 50; i++) 108 for (i = 0; i < 50; i++) {
109 {
110 if (qcam_ready1(qcam) == value) 109 if (qcam_ready1(qcam) == value)
111 return 0; 110 return 0;
112 msleep_interruptible(100); 111 msleep_interruptible(100);
@@ -125,14 +124,13 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
125 unsigned int i; 124 unsigned int i;
126 125
127 for (oldjiffies = jiffies; 126 for (oldjiffies = jiffies;
128 time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); ) 127 time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
129 if (qcam_ready2(qcam) == value) 128 if (qcam_ready2(qcam) == value)
130 return 0; 129 return 0;
131 130
132 /* If the camera didn't respond within 1/25 second, poll slowly 131 /* If the camera didn't respond within 1/25 second, poll slowly
133 for a while. */ 132 for a while. */
134 for (i = 0; i < 50; i++) 133 for (i = 0; i < 50; i++) {
135 {
136 if (qcam_ready2(qcam) == value) 134 if (qcam_ready2(qcam) == value)
137 return 0; 135 return 0;
138 msleep_interruptible(100); 136 msleep_interruptible(100);
@@ -149,22 +147,25 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
149static int qcam_read_data(struct qcam_device *qcam) 147static int qcam_read_data(struct qcam_device *qcam)
150{ 148{
151 unsigned int idata; 149 unsigned int idata;
150
152 qcam_set_ack(qcam, 0); 151 qcam_set_ack(qcam, 0);
153 if (qcam_await_ready1(qcam, 1)) return -1; 152 if (qcam_await_ready1(qcam, 1))
153 return -1;
154 idata = parport_read_status(qcam->pport) & 0xf0; 154 idata = parport_read_status(qcam->pport) & 0xf0;
155 qcam_set_ack(qcam, 1); 155 qcam_set_ack(qcam, 1);
156 if (qcam_await_ready1(qcam, 0)) return -1; 156 if (qcam_await_ready1(qcam, 0))
157 idata |= (parport_read_status(qcam->pport) >> 4); 157 return -1;
158 idata |= parport_read_status(qcam->pport) >> 4;
158 return idata; 159 return idata;
159} 160}
160 161
161static int qcam_write_data(struct qcam_device *qcam, unsigned int data) 162static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
162{ 163{
163 unsigned int idata; 164 unsigned int idata;
165
164 parport_write_data(qcam->pport, data); 166 parport_write_data(qcam->pport, data);
165 idata = qcam_read_data(qcam); 167 idata = qcam_read_data(qcam);
166 if (data != idata) 168 if (data != idata) {
167 {
168 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, 169 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
169 idata); 170 idata);
170 return 1; 171 return 1;
@@ -212,13 +213,12 @@ static int qc_detect(struct qcam_device *qcam)
212 213
213 /* look for a heartbeat */ 214 /* look for a heartbeat */
214 ostat = stat = parport_read_status(qcam->pport); 215 ostat = stat = parport_read_status(qcam->pport);
215 for (i=0; i<250; i++) 216 for (i = 0; i < 250; i++) {
216 {
217 mdelay(1); 217 mdelay(1);
218 stat = parport_read_status(qcam->pport); 218 stat = parport_read_status(qcam->pport);
219 if (ostat != stat) 219 if (ostat != stat) {
220 { 220 if (++count >= 3)
221 if (++count >= 3) return 1; 221 return 1;
222 ostat = stat; 222 ostat = stat;
223 } 223 }
224 } 224 }
@@ -232,13 +232,12 @@ static int qc_detect(struct qcam_device *qcam)
232 count = 0; 232 count = 0;
233 233
234 ostat = stat = parport_read_status(qcam->pport); 234 ostat = stat = parport_read_status(qcam->pport);
235 for (i=0; i<250; i++) 235 for (i = 0; i < 250; i++) {
236 {
237 mdelay(1); 236 mdelay(1);
238 stat = parport_read_status(qcam->pport); 237 stat = parport_read_status(qcam->pport);
239 if (ostat != stat) 238 if (ostat != stat) {
240 { 239 if (++count >= 3)
241 if (++count >= 3) return 1; 240 return 1;
242 ostat = stat; 241 ostat = stat;
243 } 242 }
244 } 243 }
@@ -263,7 +262,7 @@ static void qc_setup(struct qcam_device *q)
263{ 262{
264 qc_reset(q); 263 qc_reset(q);
265 264
266 /* Set the brightness. */ 265 /* Set the brightness. */
267 qcam_set(q, 11, q->brightness); 266 qcam_set(q, 11, q->brightness);
268 267
269 /* Set the height and width. These refer to the actual 268 /* Set the height and width. These refer to the actual
@@ -292,25 +291,25 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
292 unsigned int bytes = 0; 291 unsigned int bytes = 0;
293 292
294 qcam_set_ack(q, 0); 293 qcam_set_ack(q, 0);
295 if (q->bidirectional) 294 if (q->bidirectional) {
296 {
297 /* It's a bidirectional port */ 295 /* It's a bidirectional port */
298 while (bytes < nbytes) 296 while (bytes < nbytes) {
299 {
300 unsigned int lo1, hi1, lo2, hi2; 297 unsigned int lo1, hi1, lo2, hi2;
301 unsigned char r, g, b; 298 unsigned char r, g, b;
302 299
303 if (qcam_await_ready2(q, 1)) return bytes; 300 if (qcam_await_ready2(q, 1))
301 return bytes;
304 lo1 = parport_read_data(q->pport) >> 1; 302 lo1 = parport_read_data(q->pport) >> 1;
305 hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; 303 hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
306 qcam_set_ack(q, 1); 304 qcam_set_ack(q, 1);
307 if (qcam_await_ready2(q, 0)) return bytes; 305 if (qcam_await_ready2(q, 0))
306 return bytes;
308 lo2 = parport_read_data(q->pport) >> 1; 307 lo2 = parport_read_data(q->pport) >> 1;
309 hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; 308 hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
310 qcam_set_ack(q, 0); 309 qcam_set_ack(q, 0);
311 r = (lo1 | ((hi1 & 1)<<7)); 310 r = lo1 | ((hi1 & 1) << 7);
312 g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1); 311 g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1);
313 b = (lo2 | ((hi2 & 1)<<7)); 312 b = lo2 | ((hi2 & 1) << 7);
314 if (force_rgb) { 313 if (force_rgb) {
315 buf[bytes++] = r; 314 buf[bytes++] = r;
316 buf[bytes++] = g; 315 buf[bytes++] = g;
@@ -321,21 +320,20 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
321 buf[bytes++] = r; 320 buf[bytes++] = r;
322 } 321 }
323 } 322 }
324 } 323 } else {
325 else
326 {
327 /* It's a unidirectional port */ 324 /* It's a unidirectional port */
328 int i = 0, n = bytes; 325 int i = 0, n = bytes;
329 unsigned char rgb[3]; 326 unsigned char rgb[3];
330 327
331 while (bytes < nbytes) 328 while (bytes < nbytes) {
332 {
333 unsigned int hi, lo; 329 unsigned int hi, lo;
334 330
335 if (qcam_await_ready1(q, 1)) return bytes; 331 if (qcam_await_ready1(q, 1))
332 return bytes;
336 hi = (parport_read_status(q->pport) & 0xf0); 333 hi = (parport_read_status(q->pport) & 0xf0);
337 qcam_set_ack(q, 1); 334 qcam_set_ack(q, 1);
338 if (qcam_await_ready1(q, 0)) return bytes; 335 if (qcam_await_ready1(q, 0))
336 return bytes;
339 lo = (parport_read_status(q->pport) & 0xf0); 337 lo = (parport_read_status(q->pport) & 0xf0);
340 qcam_set_ack(q, 0); 338 qcam_set_ack(q, 0);
341 /* flip some bits */ 339 /* flip some bits */
@@ -374,28 +372,26 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
374 return -EFAULT; 372 return -EFAULT;
375 373
376 /* Wait for camera to become ready */ 374 /* Wait for camera to become ready */
377 for (;;) 375 for (;;) {
378 {
379 int i = qcam_get(q, 41); 376 int i = qcam_get(q, 41);
377
380 if (i == -1) { 378 if (i == -1) {
381 qc_setup(q); 379 qc_setup(q);
382 return -EIO; 380 return -EIO;
383 } 381 }
384 if ((i & 0x80) == 0) 382 if ((i & 0x80) == 0)
385 break; 383 break;
386 else 384 schedule();
387 schedule();
388 } 385 }
389 386
390 if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1)) 387 if (qcam_set(q, 7, (q->mode | (is_bi_dir ? 1 : 0)) + 1))
391 return -EIO; 388 return -EIO;
392 389
393 lines = q->height; 390 lines = q->height;
394 pixelsperline = q->width; 391 pixelsperline = q->width;
395 bitsperxfer = (is_bi_dir) ? 24 : 8; 392 bitsperxfer = (is_bi_dir) ? 24 : 8;
396 393
397 if (is_bi_dir) 394 if (is_bi_dir) {
398 {
399 /* Turn the port around */ 395 /* Turn the port around */
400 parport_data_reverse(q->pport); 396 parport_data_reverse(q->pport);
401 mdelay(3); 397 mdelay(3);
@@ -413,16 +409,17 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
413 409
414 wantlen = lines * pixelsperline * 24 / 8; 410 wantlen = lines * pixelsperline * 24 / 8;
415 411
416 while (wantlen) 412 while (wantlen) {
417 {
418 size_t t, s; 413 size_t t, s;
419 s = (wantlen > BUFSZ)?BUFSZ:wantlen; 414
415 s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
420 t = qcam_read_bytes(q, tmpbuf, s); 416 t = qcam_read_bytes(q, tmpbuf, s);
421 if (outptr < len) 417 if (outptr < len) {
422 {
423 size_t sz = len - outptr; 418 size_t sz = len - outptr;
424 if (sz > t) sz = t; 419
425 if (__copy_to_user(buf+outptr, tmpbuf, sz)) 420 if (sz > t)
421 sz = t;
422 if (__copy_to_user(buf + outptr, tmpbuf, sz))
426 break; 423 break;
427 outptr += sz; 424 outptr += sz;
428 } 425 }
@@ -434,33 +431,31 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
434 431
435 len = outptr; 432 len = outptr;
436 433
437 if (wantlen) 434 if (wantlen) {
438 { 435 printk(KERN_ERR "qcam: short read.\n");
439 printk("qcam: short read.\n");
440 if (is_bi_dir) 436 if (is_bi_dir)
441 parport_data_forward(q->pport); 437 parport_data_forward(q->pport);
442 qc_setup(q); 438 qc_setup(q);
443 return len; 439 return len;
444 } 440 }
445 441
446 if (is_bi_dir) 442 if (is_bi_dir) {
447 {
448 int l; 443 int l;
444
449 do { 445 do {
450 l = qcam_read_bytes(q, tmpbuf, 3); 446 l = qcam_read_bytes(q, tmpbuf, 3);
451 cond_resched(); 447 cond_resched();
452 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e)); 448 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
453 if (force_rgb) { 449 if (force_rgb) {
454 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) 450 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
455 printk("qcam: bad EOF\n"); 451 printk(KERN_ERR "qcam: bad EOF\n");
456 } else { 452 } else {
457 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) 453 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
458 printk("qcam: bad EOF\n"); 454 printk(KERN_ERR "qcam: bad EOF\n");
459 } 455 }
460 qcam_set_ack(q, 0); 456 qcam_set_ack(q, 0);
461 if (qcam_await_ready1(q, 1)) 457 if (qcam_await_ready1(q, 1)) {
462 { 458 printk(KERN_ERR "qcam: no ack after EOF\n");
463 printk("qcam: no ack after EOF\n");
464 parport_data_forward(q->pport); 459 parport_data_forward(q->pport);
465 qc_setup(q); 460 qc_setup(q);
466 return len; 461 return len;
@@ -468,27 +463,25 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
468 parport_data_forward(q->pport); 463 parport_data_forward(q->pport);
469 mdelay(3); 464 mdelay(3);
470 qcam_set_ack(q, 1); 465 qcam_set_ack(q, 1);
471 if (qcam_await_ready1(q, 0)) 466 if (qcam_await_ready1(q, 0)) {
472 { 467 printk(KERN_ERR "qcam: no ack to port turnaround\n");
473 printk("qcam: no ack to port turnaround\n");
474 qc_setup(q); 468 qc_setup(q);
475 return len; 469 return len;
476 } 470 }
477 } 471 } else {
478 else
479 {
480 int l; 472 int l;
473
481 do { 474 do {
482 l = qcam_read_bytes(q, tmpbuf, 1); 475 l = qcam_read_bytes(q, tmpbuf, 1);
483 cond_resched(); 476 cond_resched();
484 } while (l && tmpbuf[0] == 0x7e); 477 } while (l && tmpbuf[0] == 0x7e);
485 l = qcam_read_bytes(q, tmpbuf+1, 2); 478 l = qcam_read_bytes(q, tmpbuf + 1, 2);
486 if (force_rgb) { 479 if (force_rgb) {
487 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) 480 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
488 printk("qcam: bad EOF\n"); 481 printk(KERN_ERR "qcam: bad EOF\n");
489 } else { 482 } else {
490 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) 483 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
491 printk("qcam: bad EOF\n"); 484 printk(KERN_ERR "qcam: bad EOF\n");
492 } 485 }
493 } 486 }
494 487
@@ -503,164 +496,166 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
503static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) 496static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
504{ 497{
505 struct video_device *dev = video_devdata(file); 498 struct video_device *dev = video_devdata(file);
506 struct qcam_device *qcam=(struct qcam_device *)dev; 499 struct qcam_device *qcam = (struct qcam_device *)dev;
507 500
508 switch(cmd) 501 switch (cmd) {
502 case VIDIOCGCAP:
509 { 503 {
510 case VIDIOCGCAP: 504 struct video_capability *b = arg;
511 { 505
512 struct video_capability *b = arg; 506 strcpy(b->name, "Quickcam");
513 strcpy(b->name, "Quickcam"); 507 b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
514 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES; 508 b->channels = 1;
515 b->channels = 1; 509 b->audios = 0;
516 b->audios = 0; 510 b->maxwidth = 320;
517 b->maxwidth = 320; 511 b->maxheight = 240;
518 b->maxheight = 240; 512 b->minwidth = 80;
519 b->minwidth = 80; 513 b->minheight = 60;
520 b->minheight = 60; 514 return 0;
521 return 0; 515 }
522 } 516 case VIDIOCGCHAN:
523 case VIDIOCGCHAN: 517 {
524 { 518 struct video_channel *v = arg;
525 struct video_channel *v = arg; 519
526 if(v->channel!=0) 520 if (v->channel != 0)
527 return -EINVAL; 521 return -EINVAL;
528 v->flags=0; 522 v->flags = 0;
529 v->tuners=0; 523 v->tuners = 0;
530 /* Good question.. its composite or SVHS so.. */ 524 /* Good question.. its composite or SVHS so.. */
531 v->type = VIDEO_TYPE_CAMERA; 525 v->type = VIDEO_TYPE_CAMERA;
532 strcpy(v->name, "Camera"); 526 strcpy(v->name, "Camera");
533 return 0; 527 return 0;
534 } 528 }
535 case VIDIOCSCHAN: 529 case VIDIOCSCHAN:
536 { 530 {
537 struct video_channel *v = arg; 531 struct video_channel *v = arg;
538 if(v->channel!=0) 532
539 return -EINVAL; 533 if (v->channel != 0)
540 return 0; 534 return -EINVAL;
541 } 535 return 0;
542 case VIDIOCGTUNER: 536 }
543 { 537 case VIDIOCGTUNER:
544 struct video_tuner *v = arg; 538 {
545 if(v->tuner) 539 struct video_tuner *v = arg;
546 return -EINVAL; 540
547 memset(v,0,sizeof(*v)); 541 if (v->tuner)
548 strcpy(v->name, "Format"); 542 return -EINVAL;
549 v->mode = VIDEO_MODE_AUTO; 543 memset(v, 0, sizeof(*v));
550 return 0; 544 strcpy(v->name, "Format");
551 } 545 v->mode = VIDEO_MODE_AUTO;
552 case VIDIOCSTUNER: 546 return 0;
553 { 547 }
554 struct video_tuner *v = arg; 548 case VIDIOCSTUNER:
555 if(v->tuner) 549 {
556 return -EINVAL; 550 struct video_tuner *v = arg;
557 if(v->mode!=VIDEO_MODE_AUTO) 551
558 return -EINVAL; 552 if (v->tuner)
559 return 0; 553 return -EINVAL;
560 } 554 if (v->mode != VIDEO_MODE_AUTO)
561 case VIDIOCGPICT: 555 return -EINVAL;
562 { 556 return 0;
563 struct video_picture *p = arg; 557 }
564 p->colour=0x8000; 558 case VIDIOCGPICT:
565 p->hue=0x8000; 559 {
566 p->brightness=qcam->brightness<<8; 560 struct video_picture *p = arg;
567 p->contrast=qcam->contrast<<8; 561
568 p->whiteness=qcam->whitebal<<8; 562 p->colour = 0x8000;
569 p->depth=24; 563 p->hue = 0x8000;
570 p->palette=VIDEO_PALETTE_RGB24; 564 p->brightness = qcam->brightness << 8;
571 return 0; 565 p->contrast = qcam->contrast << 8;
566 p->whiteness = qcam->whitebal << 8;
567 p->depth = 24;
568 p->palette = VIDEO_PALETTE_RGB24;
569 return 0;
570 }
571 case VIDIOCSPICT:
572 {
573 struct video_picture *p = arg;
574
575 /*
576 * Sanity check args
577 */
578 if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
579 return -EINVAL;
580
581 /*
582 * Now load the camera.
583 */
584 qcam->brightness = p->brightness >> 8;
585 qcam->contrast = p->contrast >> 8;
586 qcam->whitebal = p->whiteness >> 8;
587
588 mutex_lock(&qcam->lock);
589 parport_claim_or_block(qcam->pdev);
590 qc_setup(qcam);
591 parport_release(qcam->pdev);
592 mutex_unlock(&qcam->lock);
593 return 0;
594 }
595 case VIDIOCSWIN:
596 {
597 struct video_window *vw = arg;
598
599 if (vw->flags)
600 return -EINVAL;
601 if (vw->clipcount)
602 return -EINVAL;
603 if (vw->height < 60 || vw->height > 240)
604 return -EINVAL;
605 if (vw->width < 80 || vw->width > 320)
606 return -EINVAL;
607
608 qcam->width = 80;
609 qcam->height = 60;
610 qcam->mode = QC_DECIMATION_4;
611
612 if (vw->width >= 160 && vw->height >= 120) {
613 qcam->width = 160;
614 qcam->height = 120;
615 qcam->mode = QC_DECIMATION_2;
572 } 616 }
573 case VIDIOCSPICT: 617 if (vw->width >= 320 && vw->height >= 240) {
574 { 618 qcam->width = 320;
575 struct video_picture *p = arg; 619 qcam->height = 240;
576 620 qcam->mode = QC_DECIMATION_1;
577 /*
578 * Sanity check args
579 */
580 if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
581 return -EINVAL;
582
583 /*
584 * Now load the camera.
585 */
586 qcam->brightness = p->brightness>>8;
587 qcam->contrast = p->contrast>>8;
588 qcam->whitebal = p->whiteness>>8;
589
590 mutex_lock(&qcam->lock);
591 parport_claim_or_block(qcam->pdev);
592 qc_setup(qcam);
593 parport_release(qcam->pdev);
594 mutex_unlock(&qcam->lock);
595 return 0;
596 } 621 }
597 case VIDIOCSWIN: 622 qcam->mode |= QC_MILLIONS;
598 {
599 struct video_window *vw = arg;
600
601 if(vw->flags)
602 return -EINVAL;
603 if(vw->clipcount)
604 return -EINVAL;
605 if(vw->height<60||vw->height>240)
606 return -EINVAL;
607 if(vw->width<80||vw->width>320)
608 return -EINVAL;
609
610 qcam->width = 80;
611 qcam->height = 60;
612 qcam->mode = QC_DECIMATION_4;
613
614 if(vw->width>=160 && vw->height>=120)
615 {
616 qcam->width = 160;
617 qcam->height = 120;
618 qcam->mode = QC_DECIMATION_2;
619 }
620 if(vw->width>=320 && vw->height>=240)
621 {
622 qcam->width = 320;
623 qcam->height = 240;
624 qcam->mode = QC_DECIMATION_1;
625 }
626 qcam->mode |= QC_MILLIONS;
627#if 0 623#if 0
628 if(vw->width>=640 && vw->height>=480) 624 if (vw->width >= 640 && vw->height >= 480) {
629 { 625 qcam->width = 640;
630 qcam->width = 640; 626 qcam->height = 480;
631 qcam->height = 480; 627 qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
632 qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
633 }
634#endif
635 /* Ok we figured out what to use from our
636 wide choice */
637 mutex_lock(&qcam->lock);
638 parport_claim_or_block(qcam->pdev);
639 qc_setup(qcam);
640 parport_release(qcam->pdev);
641 mutex_unlock(&qcam->lock);
642 return 0;
643 }
644 case VIDIOCGWIN:
645 {
646 struct video_window *vw = arg;
647 memset(vw, 0, sizeof(*vw));
648 vw->width=qcam->width;
649 vw->height=qcam->height;
650 return 0;
651 } 628 }
652 case VIDIOCKEY: 629#endif
653 return 0; 630 /* Ok we figured out what to use from our
654 case VIDIOCCAPTURE: 631 wide choice */
655 case VIDIOCGFBUF: 632 mutex_lock(&qcam->lock);
656 case VIDIOCSFBUF: 633 parport_claim_or_block(qcam->pdev);
657 case VIDIOCGFREQ: 634 qc_setup(qcam);
658 case VIDIOCSFREQ: 635 parport_release(qcam->pdev);
659 case VIDIOCGAUDIO: 636 mutex_unlock(&qcam->lock);
660 case VIDIOCSAUDIO: 637 return 0;
661 return -EINVAL; 638 }
662 default: 639 case VIDIOCGWIN:
663 return -ENOIOCTLCMD; 640 {
641 struct video_window *vw = arg;
642 memset(vw, 0, sizeof(*vw));
643 vw->width = qcam->width;
644 vw->height = qcam->height;
645 return 0;
646 }
647 case VIDIOCKEY:
648 return 0;
649 case VIDIOCCAPTURE:
650 case VIDIOCGFBUF:
651 case VIDIOCSFBUF:
652 case VIDIOCGFREQ:
653 case VIDIOCSFREQ:
654 case VIDIOCGAUDIO:
655 case VIDIOCSAUDIO:
656 return -EINVAL;
657 default:
658 return -ENOIOCTLCMD;
664 } 659 }
665 return 0; 660 return 0;
666} 661}
@@ -675,13 +670,13 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
675 size_t count, loff_t *ppos) 670 size_t count, loff_t *ppos)
676{ 671{
677 struct video_device *v = video_devdata(file); 672 struct video_device *v = video_devdata(file);
678 struct qcam_device *qcam=(struct qcam_device *)v; 673 struct qcam_device *qcam = (struct qcam_device *)v;
679 int len; 674 int len;
680 675
681 mutex_lock(&qcam->lock); 676 mutex_lock(&qcam->lock);
682 parport_claim_or_block(qcam->pdev); 677 parport_claim_or_block(qcam->pdev);
683 /* Probably should have a semaphore against multiple users */ 678 /* Probably should have a semaphore against multiple users */
684 len = qc_capture(qcam, buf,count); 679 len = qc_capture(qcam, buf, count);
685 parport_release(qcam->pdev); 680 parport_release(qcam->pdev);
686 mutex_unlock(&qcam->lock); 681 mutex_unlock(&qcam->lock);
687 return len; 682 return len;
@@ -713,8 +708,7 @@ static const struct v4l2_file_operations qcam_fops = {
713 .read = qcam_read, 708 .read = qcam_read,
714}; 709};
715 710
716static struct video_device qcam_template= 711static struct video_device qcam_template = {
717{
718 .name = "Colour QuickCam", 712 .name = "Colour QuickCam",
719 .fops = &qcam_fops, 713 .fops = &qcam_fops,
720 .release = video_device_release_empty, 714 .release = video_device_release_empty,
@@ -727,17 +721,16 @@ static struct qcam_device *qcam_init(struct parport *port)
727 struct qcam_device *q; 721 struct qcam_device *q;
728 722
729 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); 723 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
730 if(q==NULL) 724 if (q == NULL)
731 return NULL; 725 return NULL;
732 726
733 q->pport = port; 727 q->pport = port;
734 q->pdev = parport_register_device(port, "c-qcam", NULL, NULL, 728 q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
735 NULL, 0, NULL); 729 NULL, 0, NULL);
736 730
737 q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0; 731 q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
738 732
739 if (q->pdev == NULL) 733 if (q->pdev == NULL) {
740 {
741 printk(KERN_ERR "c-qcam: couldn't register for %s.\n", 734 printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
742 port->name); 735 port->name);
743 kfree(q); 736 kfree(q);
@@ -765,12 +758,11 @@ static int init_cqcam(struct parport *port)
765{ 758{
766 struct qcam_device *qcam; 759 struct qcam_device *qcam;
767 760
768 if (parport[0] != -1) 761 if (parport[0] != -1) {
769 {
770 /* The user gave specific instructions */ 762 /* The user gave specific instructions */
771 int i, found = 0; 763 int i, found = 0;
772 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) 764
773 { 765 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) {
774 if (parport[0] == port->number) 766 if (parport[0] == port->number)
775 found = 1; 767 found = 1;
776 } 768 }
@@ -782,15 +774,14 @@ static int init_cqcam(struct parport *port)
782 return -ENOSPC; 774 return -ENOSPC;
783 775
784 qcam = qcam_init(port); 776 qcam = qcam_init(port);
785 if (qcam==NULL) 777 if (qcam == NULL)
786 return -ENODEV; 778 return -ENODEV;
787 779
788 parport_claim_or_block(qcam->pdev); 780 parport_claim_or_block(qcam->pdev);
789 781
790 qc_reset(qcam); 782 qc_reset(qcam);
791 783
792 if (probe && qc_detect(qcam)==0) 784 if (probe && qc_detect(qcam) == 0) {
793 {
794 parport_release(qcam->pdev); 785 parport_release(qcam->pdev);
795 parport_unregister_device(qcam->pdev); 786 parport_unregister_device(qcam->pdev);
796 kfree(qcam); 787 kfree(qcam);
@@ -840,14 +831,14 @@ static struct parport_driver cqcam_driver = {
840 .detach = cq_detach, 831 .detach = cq_detach,
841}; 832};
842 833
843static int __init cqcam_init (void) 834static int __init cqcam_init(void)
844{ 835{
845 printk(BANNER "\n"); 836 printk(BANNER "\n");
846 837
847 return parport_register_driver(&cqcam_driver); 838 return parport_register_driver(&cqcam_driver);
848} 839}
849 840
850static void __exit cqcam_cleanup (void) 841static void __exit cqcam_cleanup(void)
851{ 842{
852 unsigned int i; 843 unsigned int i;
853 844
@@ -862,9 +853,9 @@ MODULE_DESCRIPTION(BANNER);
862MODULE_LICENSE("GPL"); 853MODULE_LICENSE("GPL");
863 854
864/* FIXME: parport=auto would never have worked, surely? --RR */ 855/* FIXME: parport=auto would never have worked, surely? --RR */
865MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\ 856MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
866probe=<0|1|2> for camera detection method\n\ 857 "probe=<0|1|2> for camera detection method\n"
867force_rgb=<0|1> for RGB data format (default BGR)"); 858 "force_rgb=<0|1> for RGB data format (default BGR)");
868module_param_array(parport, int, NULL, 0); 859module_param_array(parport, int, NULL, 0);
869module_param(probe, int, 0); 860module_param(probe, int, 0);
870module_param(force_rgb, bool, 0); 861module_param(force_rgb, bool, 0);
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 6f91415eb7b4..5520789854da 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -324,7 +324,7 @@ static int cpia2_close(struct file *file)
324 { 324 {
325 if(fh->mmapped) 325 if(fh->mmapped)
326 cam->mmapped = 0; 326 cam->mmapped = 0;
327 v4l2_prio_close(&cam->prio,&fh->prio); 327 v4l2_prio_close(&cam->prio, fh->prio);
328 file->private_data = NULL; 328 file->private_data = NULL;
329 kfree(fh); 329 kfree(fh);
330 } 330 }
@@ -1592,7 +1592,7 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1592 case VIDIOC_S_FMT: 1592 case VIDIOC_S_FMT:
1593 { 1593 {
1594 struct cpia2_fh *fh = file->private_data; 1594 struct cpia2_fh *fh = file->private_data;
1595 retval = v4l2_prio_check(&cam->prio, &fh->prio); 1595 retval = v4l2_prio_check(&cam->prio, fh->prio);
1596 if(retval) { 1596 if(retval) {
1597 mutex_unlock(&cam->busy_lock); 1597 mutex_unlock(&cam->busy_lock);
1598 return retval; 1598 return retval;
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 4392c76af5df..0e5006b14279 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -579,6 +579,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
579 579
580 u8 afe_mux_cfg; 580 u8 afe_mux_cfg;
581 u8 adc2_cfg; 581 u8 adc2_cfg;
582 u8 input_mode;
582 u32 afe_cfg; 583 u32 afe_cfg;
583 int i; 584 int i;
584 585
@@ -589,6 +590,30 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
589 vid_input <= CX18_AV_COMPOSITE8) { 590 vid_input <= CX18_AV_COMPOSITE8) {
590 afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); 591 afe_mux_cfg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
591 ch[0] = CVBS; 592 ch[0] = CVBS;
593 input_mode = 0x0;
594 } else if (vid_input >= CX18_AV_COMPONENT_LUMA1) {
595 int luma = vid_input & 0xf000;
596 int r_chroma = vid_input & 0xf0000;
597 int b_chroma = vid_input & 0xf00000;
598
599 if ((vid_input & ~0xfff000) ||
600 luma < CX18_AV_COMPONENT_LUMA1 ||
601 luma > CX18_AV_COMPONENT_LUMA8 ||
602 r_chroma < CX18_AV_COMPONENT_R_CHROMA4 ||
603 r_chroma > CX18_AV_COMPONENT_R_CHROMA6 ||
604 b_chroma < CX18_AV_COMPONENT_B_CHROMA7 ||
605 b_chroma > CX18_AV_COMPONENT_B_CHROMA8) {
606 CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
607 vid_input);
608 return -EINVAL;
609 }
610 afe_mux_cfg = (luma - CX18_AV_COMPONENT_LUMA1) >> 12;
611 ch[0] = Y;
612 afe_mux_cfg |= (r_chroma - CX18_AV_COMPONENT_R_CHROMA4) >> 12;
613 ch[1] = Pr;
614 afe_mux_cfg |= (b_chroma - CX18_AV_COMPONENT_B_CHROMA7) >> 14;
615 ch[2] = Pb;
616 input_mode = 0x6;
592 } else { 617 } else {
593 int luma = vid_input & 0xf0; 618 int luma = vid_input & 0xf0;
594 int chroma = vid_input & 0xf00; 619 int chroma = vid_input & 0xf00;
@@ -598,7 +623,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
598 luma > CX18_AV_SVIDEO_LUMA8 || 623 luma > CX18_AV_SVIDEO_LUMA8 ||
599 chroma < CX18_AV_SVIDEO_CHROMA4 || 624 chroma < CX18_AV_SVIDEO_CHROMA4 ||
600 chroma > CX18_AV_SVIDEO_CHROMA8) { 625 chroma > CX18_AV_SVIDEO_CHROMA8) {
601 CX18_ERR_DEV(sd, "0x%04x is not a valid video input!\n", 626 CX18_ERR_DEV(sd, "0x%06x is not a valid video input!\n",
602 vid_input); 627 vid_input);
603 return -EINVAL; 628 return -EINVAL;
604 } 629 }
@@ -613,8 +638,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
613 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; 638 afe_mux_cfg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
614 ch[1] = C; 639 ch[1] = C;
615 } 640 }
641 input_mode = 0x2;
616 } 642 }
617 /* TODO: LeadTek WinFast DVR3100 H & WinFast PVR2100 can do Y/Pb/Pr */
618 643
619 switch (aud_input) { 644 switch (aud_input) {
620 case CX18_AV_AUDIO_SERIAL1: 645 case CX18_AV_AUDIO_SERIAL1:
@@ -650,8 +675,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
650 675
651 /* Set up analog front end multiplexers */ 676 /* Set up analog front end multiplexers */
652 cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7); 677 cx18_av_write_expect(cx, 0x103, afe_mux_cfg, afe_mux_cfg, 0xf7);
653 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 678 /* Set INPUT_MODE to Composite, S-Video, or Component */
654 cx18_av_and_or(cx, 0x401, ~0x6, ch[0] == CVBS ? 0 : 0x02); 679 cx18_av_and_or(cx, 0x401, ~0x6, input_mode);
655 680
656 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 681 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
657 adc2_cfg = cx18_av_read(cx, 0x102); 682 adc2_cfg = cx18_av_read(cx, 0x102);
@@ -998,9 +1023,9 @@ static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
998 1023
999static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1024static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1000{ 1025{
1001 struct cx18 *cx = v4l2_get_subdevdata(sd); 1026 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1002 1027 return -EINVAL;
1003 return cx18_av_vbi_g_fmt(cx, fmt); 1028 return cx18_av_g_sliced_fmt(sd, &fmt->fmt.sliced);
1004} 1029}
1005 1030
1006static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1031static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
@@ -1073,12 +1098,6 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1073 cx18_av_write(cx, 0x41e, 0x8 | filter); 1098 cx18_av_write(cx, 0x41e, 0x8 | filter);
1074 break; 1099 break;
1075 1100
1076 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1077 return cx18_av_vbi_s_fmt(cx, fmt);
1078
1079 case V4L2_BUF_TYPE_VBI_CAPTURE:
1080 return cx18_av_vbi_s_fmt(cx, fmt);
1081
1082 default: 1101 default:
1083 return -EINVAL; 1102 return -EINVAL;
1084 } 1103 }
@@ -1378,17 +1397,24 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
1378 1397
1379static const struct v4l2_subdev_video_ops cx18_av_video_ops = { 1398static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
1380 .s_routing = cx18_av_s_video_routing, 1399 .s_routing = cx18_av_s_video_routing,
1381 .decode_vbi_line = cx18_av_decode_vbi_line,
1382 .s_stream = cx18_av_s_stream, 1400 .s_stream = cx18_av_s_stream,
1383 .g_fmt = cx18_av_g_fmt, 1401 .g_fmt = cx18_av_g_fmt,
1384 .s_fmt = cx18_av_s_fmt, 1402 .s_fmt = cx18_av_s_fmt,
1385}; 1403};
1386 1404
1405static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {
1406 .decode_vbi_line = cx18_av_decode_vbi_line,
1407 .g_sliced_fmt = cx18_av_g_sliced_fmt,
1408 .s_sliced_fmt = cx18_av_s_sliced_fmt,
1409 .s_raw_fmt = cx18_av_s_raw_fmt,
1410};
1411
1387static const struct v4l2_subdev_ops cx18_av_ops = { 1412static const struct v4l2_subdev_ops cx18_av_ops = {
1388 .core = &cx18_av_general_ops, 1413 .core = &cx18_av_general_ops,
1389 .tuner = &cx18_av_tuner_ops, 1414 .tuner = &cx18_av_tuner_ops,
1390 .audio = &cx18_av_audio_ops, 1415 .audio = &cx18_av_audio_ops,
1391 .video = &cx18_av_video_ops, 1416 .video = &cx18_av_video_ops,
1417 .vbi = &cx18_av_vbi_ops,
1392}; 1418};
1393 1419
1394int cx18_av_probe(struct cx18 *cx) 1420int cx18_av_probe(struct cx18 *cx)
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index cafb7e99b9a0..c106967bdcc3 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -61,6 +61,25 @@ enum cx18_av_video_input {
61 CX18_AV_SVIDEO2 = 0x620, 61 CX18_AV_SVIDEO2 = 0x620,
62 CX18_AV_SVIDEO3 = 0x730, 62 CX18_AV_SVIDEO3 = 0x730,
63 CX18_AV_SVIDEO4 = 0x840, 63 CX18_AV_SVIDEO4 = 0x840,
64
65 /* Component Video inputs consist of one luma input (In1-In8) ORed
66 with a red chroma (In4-In6) and blue chroma input (In7-In8) */
67 CX18_AV_COMPONENT_LUMA1 = 0x1000,
68 CX18_AV_COMPONENT_LUMA2 = 0x2000,
69 CX18_AV_COMPONENT_LUMA3 = 0x3000,
70 CX18_AV_COMPONENT_LUMA4 = 0x4000,
71 CX18_AV_COMPONENT_LUMA5 = 0x5000,
72 CX18_AV_COMPONENT_LUMA6 = 0x6000,
73 CX18_AV_COMPONENT_LUMA7 = 0x7000,
74 CX18_AV_COMPONENT_LUMA8 = 0x8000,
75 CX18_AV_COMPONENT_R_CHROMA4 = 0x40000,
76 CX18_AV_COMPONENT_R_CHROMA5 = 0x50000,
77 CX18_AV_COMPONENT_R_CHROMA6 = 0x60000,
78 CX18_AV_COMPONENT_B_CHROMA7 = 0x700000,
79 CX18_AV_COMPONENT_B_CHROMA8 = 0x800000,
80
81 /* Component Video aliases for common combinations */
82 CX18_AV_COMPONENT1 = 0x861000,
64}; 83};
65 84
66enum cx18_av_audio_input { 85enum cx18_av_audio_input {
@@ -359,7 +378,8 @@ void cx18_av_audio_set_path(struct cx18 *cx);
359/* cx18_av-vbi.c */ 378/* cx18_av-vbi.c */
360int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, 379int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
361 struct v4l2_decode_vbi_line *vbi); 380 struct v4l2_decode_vbi_line *vbi);
362int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt); 381int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
363int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt); 382int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
383int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
364 384
365#endif 385#endif
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index a51732bcca4b..baa36fbcd4d4 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -129,10 +129,10 @@ static int decode_vps(u8 *dst, u8 *p)
129 return err & 0xf0; 129 return err & 0xf0;
130} 130}
131 131
132int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt) 132int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
133{ 133{
134 struct cx18 *cx = v4l2_get_subdevdata(sd);
134 struct cx18_av_state *state = &cx->av_state; 135 struct cx18_av_state *state = &cx->av_state;
135 struct v4l2_sliced_vbi_format *svbi;
136 static const u16 lcr2vbi[] = { 136 static const u16 lcr2vbi[] = {
137 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 137 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
138 0, V4L2_SLICED_WSS_625, 0, /* 4 */ 138 0, V4L2_SLICED_WSS_625, 0, /* 4 */
@@ -143,9 +143,6 @@ int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
143 int is_pal = !(state->std & V4L2_STD_525_60); 143 int is_pal = !(state->std & V4L2_STD_525_60);
144 int i; 144 int i;
145 145
146 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
147 return -EINVAL;
148 svbi = &fmt->fmt.sliced;
149 memset(svbi, 0, sizeof(*svbi)); 146 memset(svbi, 0, sizeof(*svbi));
150 /* we're done if raw VBI is active */ 147 /* we're done if raw VBI is active */
151 if ((cx18_av_read(cx, 0x404) & 0x10) == 0) 148 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
@@ -173,30 +170,27 @@ int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
173 return 0; 170 return 0;
174} 171}
175 172
176int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt) 173int cx18_av_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
177{ 174{
175 struct cx18 *cx = v4l2_get_subdevdata(sd);
178 struct cx18_av_state *state = &cx->av_state; 176 struct cx18_av_state *state = &cx->av_state;
179 struct v4l2_sliced_vbi_format *svbi;
180 int is_pal = !(state->std & V4L2_STD_525_60);
181 int i, x;
182 u8 lcr[24];
183 177
184 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && 178 /* Setup standard */
185 fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) 179 cx18_av_std_setup(cx);
186 return -EINVAL;
187 svbi = &fmt->fmt.sliced;
188 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
189 /* raw VBI */
190 memset(svbi, 0, sizeof(*svbi));
191 180
192 /* Setup standard */ 181 /* VBI Offset */
193 cx18_av_std_setup(cx); 182 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
183 cx18_av_write(cx, 0x404, 0x2e);
184 return 0;
185}
194 186
195 /* VBI Offset */ 187int cx18_av_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
196 cx18_av_write(cx, 0x47f, state->slicer_line_delay); 188{
197 cx18_av_write(cx, 0x404, 0x2e); 189 struct cx18 *cx = v4l2_get_subdevdata(sd);
198 return 0; 190 struct cx18_av_state *state = &cx->av_state;
199 } 191 int is_pal = !(state->std & V4L2_STD_525_60);
192 int i, x;
193 u8 lcr[24];
200 194
201 for (x = 0; x <= 23; x++) 195 for (x = 0; x <= 23; x++)
202 lcr[x] = 0x00; 196 lcr[x] = 0x00;
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index f808fb6fc1c1..74e122b5fc49 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -370,6 +370,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
370 { CX18_CARD_INPUT_SVIDEO1, 1, 370 { CX18_CARD_INPUT_SVIDEO1, 1,
371 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, 371 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
372 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 }, 372 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
373 { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
373 }, 374 },
374 .audio_inputs = { 375 .audio_inputs = {
375 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, 376 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
@@ -422,6 +423,7 @@ static const struct cx18_card cx18_card_leadtek_dvr3100h = {
422 { CX18_CARD_INPUT_SVIDEO1, 1, 423 { CX18_CARD_INPUT_SVIDEO1, 1,
423 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, 424 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
424 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 }, 425 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
426 { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
425 }, 427 },
426 .audio_inputs = { 428 .audio_inputs = {
427 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, 429 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
@@ -480,7 +482,7 @@ int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
480 "S-Video 2", 482 "S-Video 2",
481 "Composite 1", 483 "Composite 1",
482 "Composite 2", 484 "Composite 2",
483 "Composite 3" 485 "Component 1"
484 }; 486 };
485 487
486 memset(input, 0, sizeof(*input)); 488 memset(input, 0, sizeof(*input));
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index af3d71607dc9..796e517300ac 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -43,7 +43,7 @@
43#define CX18_CARD_INPUT_SVIDEO2 3 43#define CX18_CARD_INPUT_SVIDEO2 3
44#define CX18_CARD_INPUT_COMPOSITE1 4 44#define CX18_CARD_INPUT_COMPOSITE1 4
45#define CX18_CARD_INPUT_COMPOSITE2 5 45#define CX18_CARD_INPUT_COMPOSITE2 5
46#define CX18_CARD_INPUT_COMPOSITE3 6 46#define CX18_CARD_INPUT_COMPONENT1 6
47 47
48/* audio inputs */ 48/* audio inputs */
49#define CX18_CARD_INPUT_AUD_TUNER 1 49#define CX18_CARD_INPUT_AUD_TUNER 1
@@ -62,7 +62,7 @@
62struct cx18_card_video_input { 62struct cx18_card_video_input {
63 u8 video_type; /* video input type */ 63 u8 video_type; /* video input type */
64 u8 audio_index; /* index in cx18_card_audio_input array */ 64 u8 audio_index; /* index in cx18_card_audio_input array */
65 u16 video_input; /* hardware video input */ 65 u32 video_input; /* hardware video input */
66}; 66};
67 67
68struct cx18_card_audio_input { 68struct cx18_card_audio_input {
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 7fa589240ff2..4b4b46544d5a 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -263,7 +263,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
263 int ret; 263 int ret;
264 struct v4l2_control ctrl; 264 struct v4l2_control ctrl;
265 265
266 ret = v4l2_prio_check(&cx->prio, &id->prio); 266 ret = v4l2_prio_check(&cx->prio, id->prio);
267 if (ret) 267 if (ret)
268 return ret; 268 return ret;
269 269
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 863ce7758239..e12a15020cda 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -700,7 +700,7 @@ int cx18_v4l2_close(struct file *filp)
700 700
701 CX18_DEBUG_IOCTL("close() of %s\n", s->name); 701 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
702 702
703 v4l2_prio_close(&cx->prio, &id->prio); 703 v4l2_prio_close(&cx->prio, id->prio);
704 704
705 /* Easy case first: this stream was never claimed by us */ 705 /* Easy case first: this stream was never claimed by us */
706 if (s->id != id->open_id) { 706 if (s->id != id->open_id) {
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index eecf29af916c..cfa1f289b0f5 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -109,7 +109,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
109 /* Our default information for ir-kbd-i2c.c to use */ 109 /* Our default information for ir-kbd-i2c.c to use */
110 switch (hw) { 110 switch (hw) {
111 case CX18_HW_Z8F0811_IR_RX_HAUP: 111 case CX18_HW_Z8F0811_IR_RX_HAUP:
112 init_data->ir_codes = &ir_codes_hauppauge_new_table; 112 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
113 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 113 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
114 init_data->type = IR_TYPE_RC5; 114 init_data->type = IR_TYPE_RC5;
115 init_data->name = cx->card_name; 115 init_data->name = cx->card_name;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index b81dd0ea8eb9..2530fc54daaf 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -208,7 +208,7 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
208 * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in 208 * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
209 * fmt->fmt.sliced under valid calling conditions 209 * fmt->fmt.sliced under valid calling conditions
210 */ 210 */
211 if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt)) 211 if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
212 return -EINVAL; 212 return -EINVAL;
213 213
214 /* Ensure V4L2 spec compliant output */ 214 /* Ensure V4L2 spec compliant output */
@@ -277,7 +277,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
277 int ret; 277 int ret;
278 int w, h; 278 int w, h;
279 279
280 ret = v4l2_prio_check(&cx->prio, &id->prio); 280 ret = v4l2_prio_check(&cx->prio, id->prio);
281 if (ret) 281 if (ret)
282 return ret; 282 return ret;
283 283
@@ -306,7 +306,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
306 struct cx18 *cx = id->cx; 306 struct cx18 *cx = id->cx;
307 int ret; 307 int ret;
308 308
309 ret = v4l2_prio_check(&cx->prio, &id->prio); 309 ret = v4l2_prio_check(&cx->prio, id->prio);
310 if (ret) 310 if (ret)
311 return ret; 311 return ret;
312 312
@@ -322,7 +322,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
322 * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid 322 * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
323 * calling conditions 323 * calling conditions
324 */ 324 */
325 ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); 325 ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
326 if (ret) 326 if (ret)
327 return ret; 327 return ret;
328 328
@@ -341,7 +341,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
341 int ret; 341 int ret;
342 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 342 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
343 343
344 ret = v4l2_prio_check(&cx->prio, &id->prio); 344 ret = v4l2_prio_check(&cx->prio, id->prio);
345 if (ret) 345 if (ret)
346 return ret; 346 return ret;
347 347
@@ -359,7 +359,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
359 * Note, cx18_av_vbi() wipes some "impossible" service lines in the 359 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
360 * passed in fmt->fmt.sliced under valid calling conditions 360 * passed in fmt->fmt.sliced under valid calling conditions
361 */ 361 */
362 ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); 362 ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
363 if (ret) 363 if (ret)
364 return ret; 364 return ret;
365 /* Store our current v4l2 sliced VBI settings */ 365 /* Store our current v4l2 sliced VBI settings */
@@ -549,7 +549,7 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
549 struct cx18 *cx = id->cx; 549 struct cx18 *cx = id->cx;
550 int ret; 550 int ret;
551 551
552 ret = v4l2_prio_check(&cx->prio, &id->prio); 552 ret = v4l2_prio_check(&cx->prio, id->prio);
553 if (ret) 553 if (ret)
554 return ret; 554 return ret;
555 555
@@ -601,7 +601,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
601 struct cx18 *cx = id->cx; 601 struct cx18 *cx = id->cx;
602 int ret; 602 int ret;
603 603
604 ret = v4l2_prio_check(&cx->prio, &id->prio); 604 ret = v4l2_prio_check(&cx->prio, id->prio);
605 if (ret) 605 if (ret)
606 return ret; 606 return ret;
607 607
@@ -647,7 +647,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
647 struct cx18 *cx = id->cx; 647 struct cx18 *cx = id->cx;
648 int ret; 648 int ret;
649 649
650 ret = v4l2_prio_check(&cx->prio, &id->prio); 650 ret = v4l2_prio_check(&cx->prio, id->prio);
651 if (ret) 651 if (ret)
652 return ret; 652 return ret;
653 653
@@ -675,7 +675,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
675 struct cx18 *cx = id->cx; 675 struct cx18 *cx = id->cx;
676 int ret; 676 int ret;
677 677
678 ret = v4l2_prio_check(&cx->prio, &id->prio); 678 ret = v4l2_prio_check(&cx->prio, id->prio);
679 if (ret) 679 if (ret)
680 return ret; 680 return ret;
681 681
@@ -715,7 +715,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
715 struct cx18 *cx = id->cx; 715 struct cx18 *cx = id->cx;
716 int ret; 716 int ret;
717 717
718 ret = v4l2_prio_check(&cx->prio, &id->prio); 718 ret = v4l2_prio_check(&cx->prio, id->prio);
719 if (ret) 719 if (ret)
720 return ret; 720 return ret;
721 721
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 054450f65a60..f5c91261b2db 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -374,7 +374,10 @@ static void cx18_vbi_setup(struct cx18_stream *s)
374 } 374 }
375 375
376 /* setup VBI registers */ 376 /* setup VBI registers */
377 v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in); 377 if (raw)
378 v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &cx->vbi.in.fmt.vbi);
379 else
380 v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &cx->vbi.in.fmt.sliced);
378 381
379 /* 382 /*
380 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw 383 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index 574c1c6974f8..582227522cf0 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -174,7 +174,7 @@ static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
174 p[3] != sliced_vbi_eav_rp[1])) 174 p[3] != sliced_vbi_eav_rp[1]))
175 continue; 175 continue;
176 vbi.p = p + 4; 176 vbi.p = p + 4;
177 v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi); 177 v4l2_subdev_call(cx->sd_av, vbi, decode_vbi_line, &vbi);
178 if (vbi.type) { 178 if (vbi.type) {
179 cx->vbi.sliced_data[line].id = vbi.type; 179 cx->vbi.sliced_data[line].id = vbi.type;
180 cx->vbi.sliced_data[line].field = vbi.is_second_field; 180 cx->vbi.sliced_data[line].field = vbi.is_second_field;
diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c
index 7793d60966db..7cae95a2245e 100644
--- a/drivers/media/video/cx231xx/cx231xx-audio.c
+++ b/drivers/media/video/cx231xx/cx231xx-audio.c
@@ -495,7 +495,7 @@ static int cx231xx_audio_init(struct cx231xx *dev)
495 pcm->info_flags = 0; 495 pcm->info_flags = 0;
496 pcm->private_data = dev; 496 pcm->private_data = dev;
497 strcpy(pcm->name, "Conexant cx231xx Capture"); 497 strcpy(pcm->name, "Conexant cx231xx Capture");
498 strcpy(card->driver, "Conexant cx231xx Audio"); 498 strcpy(card->driver, "Cx231xx-Audio");
499 strcpy(card->shortname, "Cx231xx Audio"); 499 strcpy(card->shortname, "Cx231xx Audio");
500 strcpy(card->longname, "Conexant cx231xx Audio"); 500 strcpy(card->longname, "Conexant cx231xx Audio");
501 501
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index b24eee115e7e..f5e1a2315fcc 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -96,10 +96,9 @@ int cx231xx_register_extension(struct cx231xx_ops *ops)
96 mutex_lock(&cx231xx_devlist_mutex); 96 mutex_lock(&cx231xx_devlist_mutex);
97 mutex_lock(&cx231xx_extension_devlist_lock); 97 mutex_lock(&cx231xx_extension_devlist_lock);
98 list_add_tail(&ops->next, &cx231xx_extension_devlist); 98 list_add_tail(&ops->next, &cx231xx_extension_devlist);
99 list_for_each_entry(dev, &cx231xx_devlist, devlist) { 99 list_for_each_entry(dev, &cx231xx_devlist, devlist)
100 if (dev) 100 ops->init(dev);
101 ops->init(dev); 101
102 }
103 printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name); 102 printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
104 mutex_unlock(&cx231xx_extension_devlist_lock); 103 mutex_unlock(&cx231xx_extension_devlist_lock);
105 mutex_unlock(&cx231xx_devlist_mutex); 104 mutex_unlock(&cx231xx_devlist_mutex);
@@ -112,10 +111,8 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops)
112 struct cx231xx *dev = NULL; 111 struct cx231xx *dev = NULL;
113 112
114 mutex_lock(&cx231xx_devlist_mutex); 113 mutex_lock(&cx231xx_devlist_mutex);
115 list_for_each_entry(dev, &cx231xx_devlist, devlist) { 114 list_for_each_entry(dev, &cx231xx_devlist, devlist)
116 if (dev) 115 ops->fini(dev);
117 ops->fini(dev);
118 }
119 116
120 mutex_lock(&cx231xx_extension_devlist_lock); 117 mutex_lock(&cx231xx_extension_devlist_lock);
121 printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name); 118 printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
index b473cd8367f5..fd099153b746 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -35,6 +35,8 @@ static unsigned int ir_debug;
35module_param(ir_debug, int, 0644); 35module_param(ir_debug, int, 0644);
36MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); 36MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
37 37
38#define MODULE_NAME "cx231xx"
39
38#define i2cdprintk(fmt, arg...) \ 40#define i2cdprintk(fmt, arg...) \
39 if (ir_debug) { \ 41 if (ir_debug) { \
40 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ 42 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
@@ -59,7 +61,6 @@ struct cx231xx_ir_poll_result {
59struct cx231xx_IR { 61struct cx231xx_IR {
60 struct cx231xx *dev; 62 struct cx231xx *dev;
61 struct input_dev *input; 63 struct input_dev *input;
62 struct ir_input_state ir;
63 char name[32]; 64 char name[32];
64 char phys[32]; 65 char phys[32];
65 66
@@ -67,9 +68,7 @@ struct cx231xx_IR {
67 int polling; 68 int polling;
68 struct work_struct work; 69 struct work_struct work;
69 struct timer_list timer; 70 struct timer_list timer;
70 unsigned int last_toggle:1;
71 unsigned int last_readcount; 71 unsigned int last_readcount;
72 unsigned int repeat_interval;
73 72
74 int (*get_key) (struct cx231xx_IR *, struct cx231xx_ir_poll_result *); 73 int (*get_key) (struct cx231xx_IR *, struct cx231xx_ir_poll_result *);
75}; 74};
@@ -81,7 +80,6 @@ struct cx231xx_IR {
81static void cx231xx_ir_handle_key(struct cx231xx_IR *ir) 80static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
82{ 81{
83 int result; 82 int result;
84 int do_sendkey = 0;
85 struct cx231xx_ir_poll_result poll_result; 83 struct cx231xx_ir_poll_result poll_result;
86 84
87 /* read the registers containing the IR status */ 85 /* read the registers containing the IR status */
@@ -95,44 +93,23 @@ static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
95 poll_result.toggle_bit, poll_result.read_count, 93 poll_result.toggle_bit, poll_result.read_count,
96 ir->last_readcount, poll_result.rc_data[0]); 94 ir->last_readcount, poll_result.rc_data[0]);
97 95
98 if (ir->dev->chip_id == CHIP_ID_EM2874) { 96 if (poll_result.read_count > 0 &&
97 poll_result.read_count != ir->last_readcount)
98 ir_keydown(ir->input,
99 poll_result.rc_data[0],
100 poll_result.toggle_bit);
101
102 if (ir->dev->chip_id == CHIP_ID_EM2874)
99 /* The em2874 clears the readcount field every time the 103 /* The em2874 clears the readcount field every time the
100 register is read. The em2860/2880 datasheet says that it 104 register is read. The em2860/2880 datasheet says that it
101 is supposed to clear the readcount, but it doesn't. So with 105 is supposed to clear the readcount, but it doesn't. So with
102 the em2874, we are looking for a non-zero read count as 106 the em2874, we are looking for a non-zero read count as
103 opposed to a readcount that is incrementing */ 107 opposed to a readcount that is incrementing */
104 ir->last_readcount = 0; 108 ir->last_readcount = 0;
105 } 109 else
106 110 ir->last_readcount = poll_result.read_count;
107 if (poll_result.read_count == 0) {
108 /* The button has not been pressed since the last read */
109 } else if (ir->last_toggle != poll_result.toggle_bit) {
110 /* A button has been pressed */
111 dprintk("button has been pressed\n");
112 ir->last_toggle = poll_result.toggle_bit;
113 ir->repeat_interval = 0;
114 do_sendkey = 1;
115 } else if (poll_result.toggle_bit == ir->last_toggle &&
116 poll_result.read_count > 0 &&
117 poll_result.read_count != ir->last_readcount) {
118 /* The button is still being held down */
119 dprintk("button being held down\n");
120
121 /* Debouncer for first keypress */
122 if (ir->repeat_interval++ > 9) {
123 /* Start repeating after 1 second */
124 do_sendkey = 1;
125 }
126 }
127 111
128 if (do_sendkey) {
129 dprintk("sending keypress\n");
130 ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0]);
131 ir_input_nokey(ir->input, &ir->ir);
132 } 112 }
133
134 ir->last_readcount = poll_result.read_count;
135 return;
136} 113}
137 114
138static void ir_timer(unsigned long data) 115static void ir_timer(unsigned long data)
@@ -198,10 +175,6 @@ int cx231xx_ir_init(struct cx231xx *dev)
198 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); 175 usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
199 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 176 strlcat(ir->phys, "/input0", sizeof(ir->phys));
200 177
201 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
202 if (err < 0)
203 goto err_out_free;
204
205 input_dev->name = ir->name; 178 input_dev->name = ir->name;
206 input_dev->phys = ir->phys; 179 input_dev->phys = ir->phys;
207 input_dev->id.bustype = BUS_USB; 180 input_dev->id.bustype = BUS_USB;
@@ -217,7 +190,8 @@ int cx231xx_ir_init(struct cx231xx *dev)
217 cx231xx_ir_start(ir); 190 cx231xx_ir_start(ir);
218 191
219 /* all done */ 192 /* all done */
220 err = ir_input_register(ir->input, dev->board.ir_codes, NULL); 193 err = __ir_input_register(ir->input, dev->board.ir_codes,
194 NULL, MODULE_NAME);
221 if (err) 195 if (err)
222 goto err_out_stop; 196 goto err_out_stop;
223 197
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 16a73eab6726..2782709b263f 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -1669,7 +1669,7 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
1669 1669
1670 f->fmt.sliced.service_set = 0; 1670 f->fmt.sliced.service_set = 0;
1671 1671
1672 call_all(dev, video, g_fmt, f); 1672 call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);
1673 1673
1674 if (f->fmt.sliced.service_set == 0) 1674 if (f->fmt.sliced.service_set == 0)
1675 rc = -EINVAL; 1675 rc = -EINVAL;
@@ -1690,7 +1690,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
1690 return rc; 1690 return rc;
1691 1691
1692 mutex_lock(&dev->lock); 1692 mutex_lock(&dev->lock);
1693 call_all(dev, video, g_fmt, f); 1693 call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);
1694 mutex_unlock(&dev->lock); 1694 mutex_unlock(&dev->lock);
1695 1695
1696 if (f->fmt.sliced.service_set == 0) 1696 if (f->fmt.sliced.service_set == 0)
@@ -1902,9 +1902,12 @@ static int radio_queryctrl(struct file *file, void *priv,
1902 if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1) 1902 if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
1903 return -EINVAL; 1903 return -EINVAL;
1904 if (c->id == V4L2_CID_AUDIO_MUTE) { 1904 if (c->id == V4L2_CID_AUDIO_MUTE) {
1905 for (i = 0; i < CX231XX_CTLS; i++) 1905 for (i = 0; i < CX231XX_CTLS; i++) {
1906 if (cx231xx_ctls[i].v.id == c->id) 1906 if (cx231xx_ctls[i].v.id == c->id)
1907 break; 1907 break;
1908 }
1909 if (i == CX231XX_CTLS)
1910 return -EINVAL;
1908 *c = cx231xx_ctls[i].v; 1911 *c = cx231xx_ctls[i].v;
1909 } else 1912 } else
1910 *c = no_ctl; 1913 *c = no_ctl;
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index 17d4d1a800ce..38d417191a65 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -32,7 +32,7 @@
32 32
33#include <media/videobuf-vmalloc.h> 33#include <media/videobuf-vmalloc.h>
34#include <media/v4l2-device.h> 34#include <media/v4l2-device.h>
35#include <media/ir-kbd-i2c.h> 35#include <media/ir-core.h>
36#if defined(CONFIG_VIDEO_CX231XX_DVB) || \ 36#if defined(CONFIG_VIDEO_CX231XX_DVB) || \
37 defined(CONFIG_VIDEO_CX231XX_DVB_MODULE) 37 defined(CONFIG_VIDEO_CX231XX_DVB_MODULE)
38#include <media/videobuf-dvb.h> 38#include <media/videobuf-dvb.h>
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 4c8e95853fa3..022b480918cd 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -1000,20 +1000,6 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
1000 h, w); 1000 h, w);
1001 if (err) return err; 1001 if (err) return err;
1002 } 1002 }
1003
1004 if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
1005 /* Adjust temporal filter if necessary. The problem with the
1006 temporal filter is that it works well with full resolution
1007 capturing, but not when the capture window is scaled (the
1008 filter introduces a ghosting effect). So if the capture
1009 window is scaled, then force the filter to 0.
1010
1011 For full resolution the filter really improves the video
1012 quality, especially if the original video quality is
1013 suboptimal. */
1014 temporal = 0;
1015 }
1016
1017 if (force || NEQ(stream_type)) { 1003 if (force || NEQ(stream_type)) {
1018 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, 1004 err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
1019 mpeg_stream_type[new->stream_type]); 1005 mpeg_stream_type[new->stream_type]);
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index d4a9d2c5947c..c95e7bc14745 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -60,12 +60,18 @@ static unsigned int ci_dbg;
60module_param(ci_dbg, int, 0644); 60module_param(ci_dbg, int, 0644);
61MODULE_PARM_DESC(ci_dbg, "Enable CI debugging"); 61MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
62 62
63static unsigned int ci_irq_enable;
64module_param(ci_irq_enable, int, 0644);
65MODULE_PARM_DESC(ci_irq_enable, "Enable IRQ from CAM");
66
63#define ci_dbg_print(args...) \ 67#define ci_dbg_print(args...) \
64 do { \ 68 do { \
65 if (ci_dbg) \ 69 if (ci_dbg) \
66 printk(KERN_DEBUG args); \ 70 printk(KERN_DEBUG args); \
67 } while (0) 71 } while (0)
68 72
73#define ci_irq_flags() (ci_irq_enable ? NETUP_IRQ_IRQAM : 0)
74
69/* stores all private variables for communication with CI */ 75/* stores all private variables for communication with CI */
70struct netup_ci_state { 76struct netup_ci_state {
71 struct dvb_ca_en50221 ca; 77 struct dvb_ca_en50221 ca;
@@ -392,7 +398,7 @@ int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open
392 if (0 != slot) 398 if (0 != slot)
393 return -EINVAL; 399 return -EINVAL;
394 400
395 netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | NETUP_IRQ_IRQAM) 401 netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | ci_irq_flags())
396 : NETUP_IRQ_DETAM); 402 : NETUP_IRQ_DETAM);
397 403
398 return state->status; 404 return state->status;
@@ -429,7 +435,7 @@ int netup_ci_init(struct cx23885_tsport *port)
429 0x01, /* power on (use it like store place) */ 435 0x01, /* power on (use it like store place) */
430 0x00, /* RFU */ 436 0x00, /* RFU */
431 0x00, /* int status read only */ 437 0x00, /* int status read only */
432 NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */ 438 ci_irq_flags() | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */
433 0x05, /* EXTINT=active-high, INT=push-pull */ 439 0x05, /* EXTINT=active-high, INT=push-pull */
434 0x00, /* USCG1 */ 440 0x00, /* USCG1 */
435 0x04, /* ack active low */ 441 0x04, /* ack active low */
@@ -470,7 +476,7 @@ int netup_ci_init(struct cx23885_tsport *port)
470 state->ca.poll_slot_status = netup_poll_ci_slot_status; 476 state->ca.poll_slot_status = netup_poll_ci_slot_status;
471 state->ca.data = state; 477 state->ca.data = state;
472 state->priv = port; 478 state->priv = port;
473 state->current_irq_mode = NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM; 479 state->current_irq_mode = ci_irq_flags() | NETUP_IRQ_DETAM;
474 480
475 ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, 481 ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
476 0, &cimax_init[0], 34); 482 0, &cimax_init[0], 34);
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index a8ddc227cf86..abd64e89f60f 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1356,7 +1356,7 @@ static int vidioc_querycap(struct file *file, void *priv,
1356 struct cx23885_dev *dev = fh->dev; 1356 struct cx23885_dev *dev = fh->dev;
1357 struct cx23885_tsport *tsport = &dev->ts1; 1357 struct cx23885_tsport *tsport = &dev->ts1;
1358 1358
1359 strcpy(cap->driver, dev->name); 1359 strlcpy(cap->driver, dev->name, sizeof(cap->driver));
1360 strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, 1360 strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
1361 sizeof(cap->card)); 1361 sizeof(cap->card));
1362 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); 1362 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 939079d7bbb9..9e1460828b2f 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -1006,6 +1006,22 @@ static int dvb_register(struct cx23885_tsport *port)
1006 netup_ci_init(port); 1006 netup_ci_init(port);
1007 break; 1007 break;
1008 } 1008 }
1009 case CX23885_BOARD_TEVII_S470: {
1010 u8 eeprom[256]; /* 24C02 i2c eeprom */
1011
1012 if (port->nr != 1)
1013 break;
1014
1015 /* Read entire EEPROM */
1016 dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
1017 tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom));
1018 printk(KERN_INFO "TeVii S470 MAC= "
1019 "%02X:%02X:%02X:%02X:%02X:%02X\n",
1020 eeprom[0xa0], eeprom[0xa1], eeprom[0xa2],
1021 eeprom[0xa3], eeprom[0xa4], eeprom[0xa5]);
1022 memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6);
1023 break;
1024 }
1009 } 1025 }
1010 1026
1011 return ret; 1027 return ret;
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 8e9d990dbe93..8d306d8bb61c 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -51,6 +51,8 @@
51 51
52#define RC5_EXTENDED_COMMAND_OFFSET 64 52#define RC5_EXTENDED_COMMAND_OFFSET 64
53 53
54#define MODULE_NAME "cx23885"
55
54static inline unsigned int rc5_command(u32 rc5_baseband) 56static inline unsigned int rc5_command(u32 rc5_baseband)
55{ 57{
56 return RC5_INSTR(rc5_baseband) + 58 return RC5_INSTR(rc5_baseband) +
@@ -338,7 +340,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
338{ 340{
339 struct card_ir *ir; 341 struct card_ir *ir;
340 struct input_dev *input_dev; 342 struct input_dev *input_dev;
341 struct ir_scancode_table *ir_codes = NULL; 343 char *ir_codes = NULL;
342 int ir_type, ir_addr, ir_start; 344 int ir_type, ir_addr, ir_start;
343 int ret; 345 int ret;
344 346
@@ -353,7 +355,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
353 case CX23885_BOARD_HAUPPAUGE_HVR1850: 355 case CX23885_BOARD_HAUPPAUGE_HVR1850:
354 case CX23885_BOARD_HAUPPAUGE_HVR1290: 356 case CX23885_BOARD_HAUPPAUGE_HVR1290:
355 /* Parameters for the grey Hauppauge remote for the HVR-1850 */ 357 /* Parameters for the grey Hauppauge remote for the HVR-1850 */
356 ir_codes = &ir_codes_hauppauge_new_table; 358 ir_codes = RC_MAP_HAUPPAUGE_NEW;
357 ir_type = IR_TYPE_RC5; 359 ir_type = IR_TYPE_RC5;
358 ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */ 360 ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
359 ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */ 361 ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
@@ -398,7 +400,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
398 dev->ir_input = ir; 400 dev->ir_input = ir;
399 cx23885_input_ir_start(dev); 401 cx23885_input_ir_start(dev);
400 402
401 ret = ir_input_register(ir->dev, ir_codes, NULL); 403 ret = ir_input_register(ir->dev, ir_codes, NULL, MODULE_NAME);
402 if (ret) 404 if (ret)
403 goto err_out_stop; 405 goto err_out_stop;
404 406
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 2d3ac8b83dc3..543b854f6a62 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -514,8 +514,8 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
514 *size = fh->fmt->depth*fh->width*fh->height >> 3; 514 *size = fh->fmt->depth*fh->width*fh->height >> 3;
515 if (0 == *count) 515 if (0 == *count)
516 *count = 32; 516 *count = 32;
517 while (*size * *count > vid_limit * 1024 * 1024) 517 if (*size * *count > vid_limit * 1024 * 1024)
518 (*count)--; 518 *count = (vid_limit * 1024 * 1024) / *size;
519 return 0; 519 return 0;
520} 520}
521 521
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index f2461cd3de5a..8b6fb3544376 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1018,7 +1018,7 @@ static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1018{ 1018{
1019 switch (fmt->type) { 1019 switch (fmt->type) {
1020 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 1020 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1021 return cx25840_vbi_g_fmt(sd, fmt); 1021 return cx25840_g_sliced_fmt(sd, &fmt->fmt.sliced);
1022 default: 1022 default:
1023 return -EINVAL; 1023 return -EINVAL;
1024 } 1024 }
@@ -1079,12 +1079,6 @@ static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1079 cx25840_write(client, 0x41e, 0x8 | filter); 1079 cx25840_write(client, 0x41e, 0x8 | filter);
1080 break; 1080 break;
1081 1081
1082 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1083 return cx25840_vbi_s_fmt(sd, fmt);
1084
1085 case V4L2_BUF_TYPE_VBI_CAPTURE:
1086 return cx25840_vbi_s_fmt(sd, fmt);
1087
1088 default: 1082 default:
1089 return -EINVAL; 1083 return -EINVAL;
1090 } 1084 }
@@ -1635,15 +1629,22 @@ static const struct v4l2_subdev_video_ops cx25840_video_ops = {
1635 .s_routing = cx25840_s_video_routing, 1629 .s_routing = cx25840_s_video_routing,
1636 .g_fmt = cx25840_g_fmt, 1630 .g_fmt = cx25840_g_fmt,
1637 .s_fmt = cx25840_s_fmt, 1631 .s_fmt = cx25840_s_fmt,
1638 .decode_vbi_line = cx25840_decode_vbi_line,
1639 .s_stream = cx25840_s_stream, 1632 .s_stream = cx25840_s_stream,
1640}; 1633};
1641 1634
1635static const struct v4l2_subdev_vbi_ops cx25840_vbi_ops = {
1636 .decode_vbi_line = cx25840_decode_vbi_line,
1637 .s_raw_fmt = cx25840_s_raw_fmt,
1638 .s_sliced_fmt = cx25840_s_sliced_fmt,
1639 .g_sliced_fmt = cx25840_g_sliced_fmt,
1640};
1641
1642static const struct v4l2_subdev_ops cx25840_ops = { 1642static const struct v4l2_subdev_ops cx25840_ops = {
1643 .core = &cx25840_core_ops, 1643 .core = &cx25840_core_ops,
1644 .tuner = &cx25840_tuner_ops, 1644 .tuner = &cx25840_tuner_ops,
1645 .audio = &cx25840_audio_ops, 1645 .audio = &cx25840_audio_ops,
1646 .video = &cx25840_video_ops, 1646 .video = &cx25840_video_ops,
1647 .vbi = &cx25840_vbi_ops,
1647}; 1648};
1648 1649
1649/* ----------------------------------------------------------------------- */ 1650/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 55345444417f..04393b971567 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -99,8 +99,9 @@ int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
99 99
100/* ----------------------------------------------------------------------- */ 100/* ----------------------------------------------------------------------- */
101/* cx25850-vbi.c */ 101/* cx25850-vbi.c */
102int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt); 102int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
103int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt); 103int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
104int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
104int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi); 105int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
105 106
106#endif 107#endif
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 35f6592f6c47..64a4004f8a97 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -82,11 +82,10 @@ static int decode_vps(u8 * dst, u8 * p)
82 return err & 0xf0; 82 return err & 0xf0;
83} 83}
84 84
85int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 85int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
86{ 86{
87 struct i2c_client *client = v4l2_get_subdevdata(sd); 87 struct i2c_client *client = v4l2_get_subdevdata(sd);
88 struct cx25840_state *state = to_state(sd); 88 struct cx25840_state *state = to_state(sd);
89 struct v4l2_sliced_vbi_format *svbi;
90 static const u16 lcr2vbi[] = { 89 static const u16 lcr2vbi[] = {
91 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 90 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
92 0, V4L2_SLICED_WSS_625, 0, /* 4 */ 91 0, V4L2_SLICED_WSS_625, 0, /* 4 */
@@ -97,9 +96,6 @@ int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
97 int is_pal = !(state->std & V4L2_STD_525_60); 96 int is_pal = !(state->std & V4L2_STD_525_60);
98 int i; 97 int i;
99 98
100 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
101 return -EINVAL;
102 svbi = &fmt->fmt.sliced;
103 memset(svbi, 0, sizeof(*svbi)); 99 memset(svbi, 0, sizeof(*svbi));
104 /* we're done if raw VBI is active */ 100 /* we're done if raw VBI is active */
105 if ((cx25840_read(client, 0x404) & 0x10) == 0) 101 if ((cx25840_read(client, 0x404) & 0x10) == 0)
@@ -127,32 +123,30 @@ int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
127 return 0; 123 return 0;
128} 124}
129 125
130int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 126int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
131{ 127{
132 struct i2c_client *client = v4l2_get_subdevdata(sd); 128 struct i2c_client *client = v4l2_get_subdevdata(sd);
133 struct cx25840_state *state = to_state(sd); 129 struct cx25840_state *state = to_state(sd);
134 struct v4l2_sliced_vbi_format *svbi;
135 int is_pal = !(state->std & V4L2_STD_525_60); 130 int is_pal = !(state->std & V4L2_STD_525_60);
136 int vbi_offset = is_pal ? 1 : 0; 131 int vbi_offset = is_pal ? 1 : 0;
137 int i, x;
138 u8 lcr[24];
139 132
140 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && 133 /* Setup standard */
141 fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) 134 cx25840_std_setup(client);
142 return -EINVAL;
143 svbi = &fmt->fmt.sliced;
144 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
145 /* raw VBI */
146 memset(svbi, 0, sizeof(*svbi));
147 135
148 /* Setup standard */ 136 /* VBI Offset */
149 cx25840_std_setup(client); 137 cx25840_write(client, 0x47f, vbi_offset);
138 cx25840_write(client, 0x404, 0x2e);
139 return 0;
140}
150 141
151 /* VBI Offset */ 142int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
152 cx25840_write(client, 0x47f, vbi_offset); 143{
153 cx25840_write(client, 0x404, 0x2e); 144 struct i2c_client *client = v4l2_get_subdevdata(sd);
154 return 0; 145 struct cx25840_state *state = to_state(sd);
155 } 146 int is_pal = !(state->std & V4L2_STD_525_60);
147 int vbi_offset = is_pal ? 1 : 0;
148 int i, x;
149 u8 lcr[24];
156 150
157 for (x = 0; x <= 23; x++) 151 for (x = 0; x <= 23; x++)
158 lcr[x] = 0x00; 152 lcr[x] = 0x00;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index b35411160f04..8b21457111b1 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -847,7 +847,8 @@ static int set_tvaudio(struct cx88_core *core)
847{ 847{
848 v4l2_std_id norm = core->tvnorm; 848 v4l2_std_id norm = core->tvnorm;
849 849
850 if (CX88_VMUX_TELEVISION != INPUT(core->input).type) 850 if (CX88_VMUX_TELEVISION != INPUT(core->input).type &&
851 CX88_VMUX_CABLE != INPUT(core->input).type)
851 return 0; 852 return 0;
852 853
853 if (V4L2_STD_PAL_BG & norm) { 854 if (V4L2_STD_PAL_BG & norm) {
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 94ab862f0219..faa8e8163a4a 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1231,7 +1231,7 @@ static int dvb_register(struct cx8802_dev *dev)
1231 fe->ops.tuner_ops.set_config(fe, &ctl); 1231 fe->ops.tuner_ops.set_config(fe, &ctl);
1232 } 1232 }
1233 break; 1233 break;
1234 case CX88_BOARD_PINNACLE_HYBRID_PCTV: 1234 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1235 case CX88_BOARD_WINFAST_DTV1800H: 1235 case CX88_BOARD_WINFAST_DTV1800H:
1236 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1236 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1237 &cx88_pinnacle_hybrid_pctv, 1237 &cx88_pinnacle_hybrid_pctv,
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 6b6abf062c21..e185289e446c 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -32,12 +32,18 @@
32#include "cx88.h" 32#include "cx88.h"
33#include <media/ir-common.h> 33#include <media/ir-common.h>
34 34
35#define MODULE_NAME "cx88xx"
36
35/* ---------------------------------------------------------------------- */ 37/* ---------------------------------------------------------------------- */
36 38
37struct cx88_IR { 39struct cx88_IR {
38 struct cx88_core *core; 40 struct cx88_core *core;
39 struct input_dev *input; 41 struct input_dev *input;
40 struct ir_input_state ir; 42 struct ir_input_state ir;
43 struct ir_dev_props props;
44
45 int users;
46
41 char name[32]; 47 char name[32];
42 char phys[32]; 48 char phys[32];
43 49
@@ -159,8 +165,16 @@ static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer)
159 return HRTIMER_RESTART; 165 return HRTIMER_RESTART;
160} 166}
161 167
162void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) 168static int __cx88_ir_start(void *priv)
163{ 169{
170 struct cx88_core *core = priv;
171 struct cx88_IR *ir;
172
173 if (!core || !core->ir)
174 return -EINVAL;
175
176 ir = core->ir;
177
164 if (ir->polling) { 178 if (ir->polling) {
165 hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 179 hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
166 ir->timer.function = cx88_ir_work; 180 ir->timer.function = cx88_ir_work;
@@ -173,10 +187,18 @@ void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
173 cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ 187 cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */
174 cx_write(MO_DDSCFG_IO, 0x5); /* enable */ 188 cx_write(MO_DDSCFG_IO, 0x5); /* enable */
175 } 189 }
190 return 0;
176} 191}
177 192
178void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) 193static void __cx88_ir_stop(void *priv)
179{ 194{
195 struct cx88_core *core = priv;
196 struct cx88_IR *ir;
197
198 if (!core || !core->ir)
199 return;
200
201 ir = core->ir;
180 if (ir->sampling) { 202 if (ir->sampling) {
181 cx_write(MO_DDSCFG_IO, 0x0); 203 cx_write(MO_DDSCFG_IO, 0x0);
182 core->pci_irqmask &= ~PCI_INT_IR_SMPINT; 204 core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
@@ -186,15 +208,49 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
186 hrtimer_cancel(&ir->timer); 208 hrtimer_cancel(&ir->timer);
187} 209}
188 210
211int cx88_ir_start(struct cx88_core *core)
212{
213 if (core->ir->users)
214 return __cx88_ir_start(core);
215
216 return 0;
217}
218
219void cx88_ir_stop(struct cx88_core *core)
220{
221 if (core->ir->users)
222 __cx88_ir_stop(core);
223}
224
225static int cx88_ir_open(void *priv)
226{
227 struct cx88_core *core = priv;
228
229 core->ir->users++;
230 return __cx88_ir_start(core);
231}
232
233static void cx88_ir_close(void *priv)
234{
235 struct cx88_core *core = priv;
236
237 core->ir->users--;
238 if (!core->ir->users)
239 __cx88_ir_stop(core);
240}
241
189/* ---------------------------------------------------------------------- */ 242/* ---------------------------------------------------------------------- */
190 243
191int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) 244int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
192{ 245{
193 struct cx88_IR *ir; 246 struct cx88_IR *ir;
194 struct input_dev *input_dev; 247 struct input_dev *input_dev;
195 struct ir_scancode_table *ir_codes = NULL; 248 char *ir_codes = NULL;
196 u64 ir_type = IR_TYPE_OTHER; 249 u64 ir_type = IR_TYPE_OTHER;
197 int err = -ENOMEM; 250 int err = -ENOMEM;
251 u32 hardware_mask = 0; /* For devices with a hardware mask, when
252 * used with a full-code IR table
253 */
198 254
199 ir = kzalloc(sizeof(*ir), GFP_KERNEL); 255 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
200 input_dev = input_allocate_device(); 256 input_dev = input_allocate_device();
@@ -208,15 +264,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
208 case CX88_BOARD_DNTV_LIVE_DVB_T: 264 case CX88_BOARD_DNTV_LIVE_DVB_T:
209 case CX88_BOARD_KWORLD_DVB_T: 265 case CX88_BOARD_KWORLD_DVB_T:
210 case CX88_BOARD_KWORLD_DVB_T_CX22702: 266 case CX88_BOARD_KWORLD_DVB_T_CX22702:
211 ir_codes = &ir_codes_dntv_live_dvb_t_table; 267 ir_codes = RC_MAP_DNTV_LIVE_DVB_T;
212 ir->gpio_addr = MO_GP1_IO; 268 ir->gpio_addr = MO_GP1_IO;
213 ir->mask_keycode = 0x1f; 269 ir->mask_keycode = 0x1f;
214 ir->mask_keyup = 0x60; 270 ir->mask_keyup = 0x60;
215 ir->polling = 50; /* ms */ 271 ir->polling = 50; /* ms */
216 break; 272 break;
217 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 273 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
218 ir_codes = &ir_codes_cinergy_1400_table; 274 ir_codes = RC_MAP_CINERGY_1400;
219 ir_type = IR_TYPE_PD; 275 ir_type = IR_TYPE_NEC;
220 ir->sampling = 0xeb04; /* address */ 276 ir->sampling = 0xeb04; /* address */
221 break; 277 break;
222 case CX88_BOARD_HAUPPAUGE: 278 case CX88_BOARD_HAUPPAUGE:
@@ -230,14 +286,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
230 case CX88_BOARD_PCHDTV_HD3000: 286 case CX88_BOARD_PCHDTV_HD3000:
231 case CX88_BOARD_PCHDTV_HD5500: 287 case CX88_BOARD_PCHDTV_HD5500:
232 case CX88_BOARD_HAUPPAUGE_IRONLY: 288 case CX88_BOARD_HAUPPAUGE_IRONLY:
233 ir_codes = &ir_codes_hauppauge_new_table; 289 ir_codes = RC_MAP_HAUPPAUGE_NEW;
234 ir_type = IR_TYPE_RC5; 290 ir_type = IR_TYPE_RC5;
235 ir->sampling = 1; 291 ir->sampling = 1;
236 break; 292 break;
237 case CX88_BOARD_WINFAST_DTV2000H: 293 case CX88_BOARD_WINFAST_DTV2000H:
238 case CX88_BOARD_WINFAST_DTV2000H_J: 294 case CX88_BOARD_WINFAST_DTV2000H_J:
239 case CX88_BOARD_WINFAST_DTV1800H: 295 case CX88_BOARD_WINFAST_DTV1800H:
240 ir_codes = &ir_codes_winfast_table; 296 ir_codes = RC_MAP_WINFAST;
241 ir->gpio_addr = MO_GP0_IO; 297 ir->gpio_addr = MO_GP0_IO;
242 ir->mask_keycode = 0x8f8; 298 ir->mask_keycode = 0x8f8;
243 ir->mask_keyup = 0x100; 299 ir->mask_keyup = 0x100;
@@ -246,14 +302,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
246 case CX88_BOARD_WINFAST2000XP_EXPERT: 302 case CX88_BOARD_WINFAST2000XP_EXPERT:
247 case CX88_BOARD_WINFAST_DTV1000: 303 case CX88_BOARD_WINFAST_DTV1000:
248 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: 304 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
249 ir_codes = &ir_codes_winfast_table; 305 ir_codes = RC_MAP_WINFAST;
250 ir->gpio_addr = MO_GP0_IO; 306 ir->gpio_addr = MO_GP0_IO;
251 ir->mask_keycode = 0x8f8; 307 ir->mask_keycode = 0x8f8;
252 ir->mask_keyup = 0x100; 308 ir->mask_keyup = 0x100;
253 ir->polling = 1; /* ms */ 309 ir->polling = 1; /* ms */
254 break; 310 break;
255 case CX88_BOARD_IODATA_GVBCTV7E: 311 case CX88_BOARD_IODATA_GVBCTV7E:
256 ir_codes = &ir_codes_iodata_bctv7e_table; 312 ir_codes = RC_MAP_IODATA_BCTV7E;
257 ir->gpio_addr = MO_GP0_IO; 313 ir->gpio_addr = MO_GP0_IO;
258 ir->mask_keycode = 0xfd; 314 ir->mask_keycode = 0xfd;
259 ir->mask_keydown = 0x02; 315 ir->mask_keydown = 0x02;
@@ -261,36 +317,43 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
261 break; 317 break;
262 case CX88_BOARD_PROLINK_PLAYTVPVR: 318 case CX88_BOARD_PROLINK_PLAYTVPVR:
263 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: 319 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
264 ir_codes = &ir_codes_pixelview_table; 320 /*
321 * It seems that this hardware is paired with NEC extended
322 * address 0x866b. So, unfortunately, its usage with other
323 * IR's with different address won't work. Still, there are
324 * other IR's from the same manufacturer that works, like the
325 * 002-T mini RC, provided with newer PV hardware
326 */
327 ir_codes = RC_MAP_PIXELVIEW_MK12;
265 ir->gpio_addr = MO_GP1_IO; 328 ir->gpio_addr = MO_GP1_IO;
266 ir->mask_keycode = 0x1f;
267 ir->mask_keyup = 0x80; 329 ir->mask_keyup = 0x80;
268 ir->polling = 1; /* ms */ 330 ir->polling = 10; /* ms */
331 hardware_mask = 0x3f; /* Hardware returns only 6 bits from command part */
269 break; 332 break;
270 case CX88_BOARD_PROLINK_PV_8000GT: 333 case CX88_BOARD_PROLINK_PV_8000GT:
271 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: 334 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
272 ir_codes = &ir_codes_pixelview_new_table; 335 ir_codes = RC_MAP_PIXELVIEW_NEW;
273 ir->gpio_addr = MO_GP1_IO; 336 ir->gpio_addr = MO_GP1_IO;
274 ir->mask_keycode = 0x3f; 337 ir->mask_keycode = 0x3f;
275 ir->mask_keyup = 0x80; 338 ir->mask_keyup = 0x80;
276 ir->polling = 1; /* ms */ 339 ir->polling = 1; /* ms */
277 break; 340 break;
278 case CX88_BOARD_KWORLD_LTV883: 341 case CX88_BOARD_KWORLD_LTV883:
279 ir_codes = &ir_codes_pixelview_table; 342 ir_codes = RC_MAP_PIXELVIEW;
280 ir->gpio_addr = MO_GP1_IO; 343 ir->gpio_addr = MO_GP1_IO;
281 ir->mask_keycode = 0x1f; 344 ir->mask_keycode = 0x1f;
282 ir->mask_keyup = 0x60; 345 ir->mask_keyup = 0x60;
283 ir->polling = 1; /* ms */ 346 ir->polling = 1; /* ms */
284 break; 347 break;
285 case CX88_BOARD_ADSTECH_DVB_T_PCI: 348 case CX88_BOARD_ADSTECH_DVB_T_PCI:
286 ir_codes = &ir_codes_adstech_dvb_t_pci_table; 349 ir_codes = RC_MAP_ADSTECH_DVB_T_PCI;
287 ir->gpio_addr = MO_GP1_IO; 350 ir->gpio_addr = MO_GP1_IO;
288 ir->mask_keycode = 0xbf; 351 ir->mask_keycode = 0xbf;
289 ir->mask_keyup = 0x40; 352 ir->mask_keyup = 0x40;
290 ir->polling = 50; /* ms */ 353 ir->polling = 50; /* ms */
291 break; 354 break;
292 case CX88_BOARD_MSI_TVANYWHERE_MASTER: 355 case CX88_BOARD_MSI_TVANYWHERE_MASTER:
293 ir_codes = &ir_codes_msi_tvanywhere_table; 356 ir_codes = RC_MAP_MSI_TVANYWHERE;
294 ir->gpio_addr = MO_GP1_IO; 357 ir->gpio_addr = MO_GP1_IO;
295 ir->mask_keycode = 0x1f; 358 ir->mask_keycode = 0x1f;
296 ir->mask_keyup = 0x40; 359 ir->mask_keyup = 0x40;
@@ -298,7 +361,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
298 break; 361 break;
299 case CX88_BOARD_AVERTV_303: 362 case CX88_BOARD_AVERTV_303:
300 case CX88_BOARD_AVERTV_STUDIO_303: 363 case CX88_BOARD_AVERTV_STUDIO_303:
301 ir_codes = &ir_codes_avertv_303_table; 364 ir_codes = RC_MAP_AVERTV_303;
302 ir->gpio_addr = MO_GP2_IO; 365 ir->gpio_addr = MO_GP2_IO;
303 ir->mask_keycode = 0xfb; 366 ir->mask_keycode = 0xfb;
304 ir->mask_keydown = 0x02; 367 ir->mask_keydown = 0x02;
@@ -311,41 +374,41 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
311 case CX88_BOARD_PROF_7300: 374 case CX88_BOARD_PROF_7300:
312 case CX88_BOARD_PROF_7301: 375 case CX88_BOARD_PROF_7301:
313 case CX88_BOARD_PROF_6200: 376 case CX88_BOARD_PROF_6200:
314 ir_codes = &ir_codes_tbs_nec_table; 377 ir_codes = RC_MAP_TBS_NEC;
315 ir_type = IR_TYPE_PD; 378 ir_type = IR_TYPE_NEC;
316 ir->sampling = 0xff00; /* address */ 379 ir->sampling = 0xff00; /* address */
317 break; 380 break;
318 case CX88_BOARD_TEVII_S460: 381 case CX88_BOARD_TEVII_S460:
319 case CX88_BOARD_TEVII_S420: 382 case CX88_BOARD_TEVII_S420:
320 ir_codes = &ir_codes_tevii_nec_table; 383 ir_codes = RC_MAP_TEVII_NEC;
321 ir_type = IR_TYPE_PD; 384 ir_type = IR_TYPE_NEC;
322 ir->sampling = 0xff00; /* address */ 385 ir->sampling = 0xff00; /* address */
323 break; 386 break;
324 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 387 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
325 ir_codes = &ir_codes_dntv_live_dvbt_pro_table; 388 ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO;
326 ir_type = IR_TYPE_PD; 389 ir_type = IR_TYPE_NEC;
327 ir->sampling = 0xff00; /* address */ 390 ir->sampling = 0xff00; /* address */
328 break; 391 break;
329 case CX88_BOARD_NORWOOD_MICRO: 392 case CX88_BOARD_NORWOOD_MICRO:
330 ir_codes = &ir_codes_norwood_table; 393 ir_codes = RC_MAP_NORWOOD;
331 ir->gpio_addr = MO_GP1_IO; 394 ir->gpio_addr = MO_GP1_IO;
332 ir->mask_keycode = 0x0e; 395 ir->mask_keycode = 0x0e;
333 ir->mask_keyup = 0x80; 396 ir->mask_keyup = 0x80;
334 ir->polling = 50; /* ms */ 397 ir->polling = 50; /* ms */
335 break; 398 break;
336 case CX88_BOARD_NPGTECH_REALTV_TOP10FM: 399 case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
337 ir_codes = &ir_codes_npgtech_table; 400 ir_codes = RC_MAP_NPGTECH;
338 ir->gpio_addr = MO_GP0_IO; 401 ir->gpio_addr = MO_GP0_IO;
339 ir->mask_keycode = 0xfa; 402 ir->mask_keycode = 0xfa;
340 ir->polling = 50; /* ms */ 403 ir->polling = 50; /* ms */
341 break; 404 break;
342 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 405 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
343 ir_codes = &ir_codes_pinnacle_pctv_hd_table; 406 ir_codes = RC_MAP_PINNACLE_PCTV_HD;
344 ir_type = IR_TYPE_RC5; 407 ir_type = IR_TYPE_RC5;
345 ir->sampling = 1; 408 ir->sampling = 1;
346 break; 409 break;
347 case CX88_BOARD_POWERCOLOR_REAL_ANGEL: 410 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
348 ir_codes = &ir_codes_powercolor_real_angel_table; 411 ir_codes = RC_MAP_POWERCOLOR_REAL_ANGEL;
349 ir->gpio_addr = MO_GP2_IO; 412 ir->gpio_addr = MO_GP2_IO;
350 ir->mask_keycode = 0x7e; 413 ir->mask_keycode = 0x7e;
351 ir->polling = 100; /* ms */ 414 ir->polling = 100; /* ms */
@@ -357,6 +420,21 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
357 goto err_out_free; 420 goto err_out_free;
358 } 421 }
359 422
423 /*
424 * The usage of mask_keycode were very convenient, due to several
425 * reasons. Among others, the scancode tables were using the scancode
426 * as the index elements. So, the less bits it was used, the smaller
427 * the table were stored. After the input changes, the better is to use
428 * the full scancodes, since it allows replacing the IR remote by
429 * another one. Unfortunately, there are still some hardware, like
430 * Pixelview Ultra Pro, where only part of the scancode is sent via
431 * GPIO. So, there's no way to get the full scancode. Due to that,
432 * hardware_mask were introduced here: it represents those hardware
433 * that has such limits.
434 */
435 if (hardware_mask && !ir->mask_keycode)
436 ir->mask_keycode = hardware_mask;
437
360 /* init input device */ 438 /* init input device */
361 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); 439 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
362 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); 440 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
@@ -381,19 +459,20 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
381 ir->core = core; 459 ir->core = core;
382 core->ir = ir; 460 core->ir = ir;
383 461
384 cx88_ir_start(core, ir); 462 ir->props.priv = core;
463 ir->props.open = cx88_ir_open;
464 ir->props.close = cx88_ir_close;
465 ir->props.scanmask = hardware_mask;
385 466
386 /* all done */ 467 /* all done */
387 err = ir_input_register(ir->input, ir_codes, NULL); 468 err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
388 if (err) 469 if (err)
389 goto err_out_stop; 470 goto err_out_free;
390 471
391 return 0; 472 return 0;
392 473
393 err_out_stop:
394 cx88_ir_stop(core, ir);
395 core->ir = NULL;
396 err_out_free: 474 err_out_free:
475 core->ir = NULL;
397 kfree(ir); 476 kfree(ir);
398 return err; 477 return err;
399} 478}
@@ -406,7 +485,7 @@ int cx88_ir_fini(struct cx88_core *core)
406 if (NULL == ir) 485 if (NULL == ir)
407 return 0; 486 return 0;
408 487
409 cx88_ir_stop(core, ir); 488 cx88_ir_stop(core);
410 ir_input_unregister(ir->input); 489 ir_input_unregister(ir->input);
411 kfree(ir); 490 kfree(ir);
412 491
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 6aba7af9160a..499f8d512ad6 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -599,13 +599,22 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
599static int cx8802_request_acquire(struct cx8802_driver *drv) 599static int cx8802_request_acquire(struct cx8802_driver *drv)
600{ 600{
601 struct cx88_core *core = drv->core; 601 struct cx88_core *core = drv->core;
602 unsigned int i;
602 603
603 /* Fail a request for hardware if the device is busy. */ 604 /* Fail a request for hardware if the device is busy. */
604 if (core->active_type_id != CX88_BOARD_NONE && 605 if (core->active_type_id != CX88_BOARD_NONE &&
605 core->active_type_id != drv->type_id) 606 core->active_type_id != drv->type_id)
606 return -EBUSY; 607 return -EBUSY;
607 608
608 core->input = CX88_VMUX_DVB; 609 core->input = 0;
610 for (i = 0;
611 i < (sizeof(core->board.input) / sizeof(struct cx88_input));
612 i++) {
613 if (core->board.input[i].type == CX88_VMUX_DVB) {
614 core->input = i;
615 break;
616 }
617 }
609 618
610 if (drv->advise_acquire) 619 if (drv->advise_acquire)
611 { 620 {
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 48c450f4a85a..0fab65c3ab39 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -426,12 +426,13 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
426 if (core->board.audio_chip && 426 if (core->board.audio_chip &&
427 core->board.audio_chip == V4L2_IDENT_WM8775) { 427 core->board.audio_chip == V4L2_IDENT_WM8775) {
428 call_all(core, audio, s_routing, 428 call_all(core, audio, s_routing,
429 INPUT(input).audioroute, 0, 0); 429 INPUT(input).audioroute, 0, 0);
430 } 430 }
431 /* cx2388's C-ADC is connected to the tuner only. 431 /* cx2388's C-ADC is connected to the tuner only.
432 When used with S-Video, that ADC is busy dealing with 432 When used with S-Video, that ADC is busy dealing with
433 chroma, so an external must be used for baseband audio */ 433 chroma, so an external must be used for baseband audio */
434 if (INPUT(input).type != CX88_VMUX_TELEVISION ) { 434 if (INPUT(input).type != CX88_VMUX_TELEVISION &&
435 INPUT(input).type != CX88_VMUX_CABLE) {
435 /* "I2S ADC mode" */ 436 /* "I2S ADC mode" */
436 core->tvaudio = WW_I2SADC; 437 core->tvaudio = WW_I2SADC;
437 cx88_set_tvaudio(core); 438 cx88_set_tvaudio(core);
@@ -561,8 +562,8 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
561 *size = fh->fmt->depth*fh->width*fh->height >> 3; 562 *size = fh->fmt->depth*fh->width*fh->height >> 3;
562 if (0 == *count) 563 if (0 == *count)
563 *count = 32; 564 *count = 32;
564 while (*size * *count > vid_limit * 1024 * 1024) 565 if (*size * *count > vid_limit * 1024 * 1024)
565 (*count)--; 566 *count = (vid_limit * 1024 * 1024) / *size;
566 return 0; 567 return 0;
567} 568}
568 569
@@ -1537,9 +1538,12 @@ static int radio_queryctrl (struct file *file, void *priv,
1537 c->id >= V4L2_CID_LASTP1) 1538 c->id >= V4L2_CID_LASTP1)
1538 return -EINVAL; 1539 return -EINVAL;
1539 if (c->id == V4L2_CID_AUDIO_MUTE) { 1540 if (c->id == V4L2_CID_AUDIO_MUTE) {
1540 for (i = 0; i < CX8800_CTLS; i++) 1541 for (i = 0; i < CX8800_CTLS; i++) {
1541 if (cx8800_ctls[i].v.id == c->id) 1542 if (cx8800_ctls[i].v.id == c->id)
1542 break; 1543 break;
1544 }
1545 if (i == CX8800_CTLS)
1546 return -EINVAL;
1543 *c = cx8800_ctls[i].v; 1547 *c = cx8800_ctls[i].v;
1544 } else 1548 } else
1545 *c = no_ctl; 1549 *c = no_ctl;
@@ -1977,7 +1981,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1977 } 1981 }
1978 1982
1979 if (core->ir) 1983 if (core->ir)
1980 cx88_ir_stop(core, core->ir); 1984 cx88_ir_stop(core);
1981 1985
1982 cx88_shutdown(core); /* FIXME */ 1986 cx88_shutdown(core); /* FIXME */
1983 pci_disable_device(pci_dev); 1987 pci_disable_device(pci_dev);
@@ -2015,7 +2019,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
2015 spin_unlock(&dev->slock); 2019 spin_unlock(&dev->slock);
2016 2020
2017 if (core->ir) 2021 if (core->ir)
2018 cx88_ir_stop(core, core->ir); 2022 cx88_ir_stop(core);
2019 /* FIXME -- shutdown device */ 2023 /* FIXME -- shutdown device */
2020 cx88_shutdown(core); 2024 cx88_shutdown(core);
2021 2025
@@ -2056,7 +2060,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
2056 /* FIXME: re-initialize hardware */ 2060 /* FIXME: re-initialize hardware */
2057 cx88_reset(core); 2061 cx88_reset(core);
2058 if (core->ir) 2062 if (core->ir)
2059 cx88_ir_start(core, core->ir); 2063 cx88_ir_start(core);
2060 2064
2061 cx_set(MO_PCI_INTMSK, core->pci_irqmask); 2065 cx_set(MO_PCI_INTMSK, core->pci_irqmask);
2062 2066
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 48b6c04fb497..bdb03d336536 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -41,7 +41,7 @@
41 41
42#include <linux/version.h> 42#include <linux/version.h>
43#include <linux/mutex.h> 43#include <linux/mutex.h>
44#define CX88_VERSION_CODE KERNEL_VERSION(0,0,7) 44#define CX88_VERSION_CODE KERNEL_VERSION(0, 0, 8)
45 45
46#define UNSET (-1U) 46#define UNSET (-1U)
47 47
@@ -290,7 +290,7 @@ struct cx88_subid {
290#define RESOURCE_VIDEO 2 290#define RESOURCE_VIDEO 2
291#define RESOURCE_VBI 4 291#define RESOURCE_VBI 4
292 292
293#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ 293#define BUFFER_TIMEOUT msecs_to_jiffies(2000)
294 294
295/* buffer for one video frame */ 295/* buffer for one video frame */
296struct cx88_buffer { 296struct cx88_buffer {
@@ -683,8 +683,8 @@ s32 cx88_dsp_detect_stereo_sap(struct cx88_core *core);
683int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci); 683int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
684int cx88_ir_fini(struct cx88_core *core); 684int cx88_ir_fini(struct cx88_core *core);
685void cx88_ir_irq(struct cx88_core *core); 685void cx88_ir_irq(struct cx88_core *core);
686void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir); 686int cx88_ir_start(struct cx88_core *core);
687void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir); 687void cx88_ir_stop(struct cx88_core *core);
688 688
689/* ----------------------------------------------------------- */ 689/* ----------------------------------------------------------- */
690/* cx88-mpeg.c */ 690/* cx88-mpeg.c */
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
index b4cc96dc99ef..490aafb34e2f 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -101,6 +101,9 @@ static u32 ccdc_raw_bayer_pix_formats[] =
101static u32 ccdc_raw_yuv_pix_formats[] = 101static u32 ccdc_raw_yuv_pix_formats[] =
102 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV}; 102 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
103 103
104/* CCDC Save/Restore context */
105static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)];
106
104/* register access routines */ 107/* register access routines */
105static inline u32 regr(u32 offset) 108static inline u32 regr(u32 offset)
106{ 109{
@@ -400,7 +403,11 @@ void ccdc_config_ycbcr(void)
400 * configure the FID, VD, HD pin polarity, 403 * configure the FID, VD, HD pin polarity,
401 * fld,hd pol positive, vd negative, 8-bit data 404 * fld,hd pol positive, vd negative, 8-bit data
402 */ 405 */
403 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE | CCDC_SYN_MODE_8BITS; 406 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE;
407 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
408 syn_mode |= CCDC_SYN_MODE_10BITS;
409 else
410 syn_mode |= CCDC_SYN_MODE_8BITS;
404 } else { 411 } else {
405 /* y/c external sync mode */ 412 /* y/c external sync mode */
406 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) << 413 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
@@ -419,8 +426,13 @@ void ccdc_config_ycbcr(void)
419 * configure the order of y cb cr in SDRAM, and disable latch 426 * configure the order of y cb cr in SDRAM, and disable latch
420 * internal register on vsync 427 * internal register on vsync
421 */ 428 */
422 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) | 429 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
423 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG); 430 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
431 CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_BW656_10BIT,
432 CCDC_CCDCFG);
433 else
434 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
435 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
424 436
425 /* 437 /*
426 * configure the horizontal line offset. This should be a 438 * configure the horizontal line offset. This should be a
@@ -435,7 +447,6 @@ void ccdc_config_ycbcr(void)
435 447
436 ccdc_sbl_reset(); 448 ccdc_sbl_reset();
437 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n"); 449 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
438 ccdc_readregs();
439} 450}
440 451
441static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp) 452static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
@@ -827,6 +838,7 @@ static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
827 case VPFE_BT656: 838 case VPFE_BT656:
828 case VPFE_YCBCR_SYNC_16: 839 case VPFE_YCBCR_SYNC_16:
829 case VPFE_YCBCR_SYNC_8: 840 case VPFE_YCBCR_SYNC_8:
841 case VPFE_BT656_10BIT:
830 ccdc_cfg.ycbcr.vd_pol = params->vdpol; 842 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
831 ccdc_cfg.ycbcr.hd_pol = params->hdpol; 843 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
832 break; 844 break;
@@ -837,6 +849,87 @@ static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
837 return 0; 849 return 0;
838} 850}
839 851
852static void ccdc_save_context(void)
853{
854 ccdc_ctx[CCDC_PCR >> 2] = regr(CCDC_PCR);
855 ccdc_ctx[CCDC_SYN_MODE >> 2] = regr(CCDC_SYN_MODE);
856 ccdc_ctx[CCDC_HD_VD_WID >> 2] = regr(CCDC_HD_VD_WID);
857 ccdc_ctx[CCDC_PIX_LINES >> 2] = regr(CCDC_PIX_LINES);
858 ccdc_ctx[CCDC_HORZ_INFO >> 2] = regr(CCDC_HORZ_INFO);
859 ccdc_ctx[CCDC_VERT_START >> 2] = regr(CCDC_VERT_START);
860 ccdc_ctx[CCDC_VERT_LINES >> 2] = regr(CCDC_VERT_LINES);
861 ccdc_ctx[CCDC_CULLING >> 2] = regr(CCDC_CULLING);
862 ccdc_ctx[CCDC_HSIZE_OFF >> 2] = regr(CCDC_HSIZE_OFF);
863 ccdc_ctx[CCDC_SDOFST >> 2] = regr(CCDC_SDOFST);
864 ccdc_ctx[CCDC_SDR_ADDR >> 2] = regr(CCDC_SDR_ADDR);
865 ccdc_ctx[CCDC_CLAMP >> 2] = regr(CCDC_CLAMP);
866 ccdc_ctx[CCDC_DCSUB >> 2] = regr(CCDC_DCSUB);
867 ccdc_ctx[CCDC_COLPTN >> 2] = regr(CCDC_COLPTN);
868 ccdc_ctx[CCDC_BLKCMP >> 2] = regr(CCDC_BLKCMP);
869 ccdc_ctx[CCDC_FPC >> 2] = regr(CCDC_FPC);
870 ccdc_ctx[CCDC_FPC_ADDR >> 2] = regr(CCDC_FPC_ADDR);
871 ccdc_ctx[CCDC_VDINT >> 2] = regr(CCDC_VDINT);
872 ccdc_ctx[CCDC_ALAW >> 2] = regr(CCDC_ALAW);
873 ccdc_ctx[CCDC_REC656IF >> 2] = regr(CCDC_REC656IF);
874 ccdc_ctx[CCDC_CCDCFG >> 2] = regr(CCDC_CCDCFG);
875 ccdc_ctx[CCDC_FMTCFG >> 2] = regr(CCDC_FMTCFG);
876 ccdc_ctx[CCDC_FMT_HORZ >> 2] = regr(CCDC_FMT_HORZ);
877 ccdc_ctx[CCDC_FMT_VERT >> 2] = regr(CCDC_FMT_VERT);
878 ccdc_ctx[CCDC_FMT_ADDR0 >> 2] = regr(CCDC_FMT_ADDR0);
879 ccdc_ctx[CCDC_FMT_ADDR1 >> 2] = regr(CCDC_FMT_ADDR1);
880 ccdc_ctx[CCDC_FMT_ADDR2 >> 2] = regr(CCDC_FMT_ADDR2);
881 ccdc_ctx[CCDC_FMT_ADDR3 >> 2] = regr(CCDC_FMT_ADDR3);
882 ccdc_ctx[CCDC_FMT_ADDR4 >> 2] = regr(CCDC_FMT_ADDR4);
883 ccdc_ctx[CCDC_FMT_ADDR5 >> 2] = regr(CCDC_FMT_ADDR5);
884 ccdc_ctx[CCDC_FMT_ADDR6 >> 2] = regr(CCDC_FMT_ADDR6);
885 ccdc_ctx[CCDC_FMT_ADDR7 >> 2] = regr(CCDC_FMT_ADDR7);
886 ccdc_ctx[CCDC_PRGEVEN_0 >> 2] = regr(CCDC_PRGEVEN_0);
887 ccdc_ctx[CCDC_PRGEVEN_1 >> 2] = regr(CCDC_PRGEVEN_1);
888 ccdc_ctx[CCDC_PRGODD_0 >> 2] = regr(CCDC_PRGODD_0);
889 ccdc_ctx[CCDC_PRGODD_1 >> 2] = regr(CCDC_PRGODD_1);
890 ccdc_ctx[CCDC_VP_OUT >> 2] = regr(CCDC_VP_OUT);
891}
892
893static void ccdc_restore_context(void)
894{
895 regw(ccdc_ctx[CCDC_SYN_MODE >> 2], CCDC_SYN_MODE);
896 regw(ccdc_ctx[CCDC_HD_VD_WID >> 2], CCDC_HD_VD_WID);
897 regw(ccdc_ctx[CCDC_PIX_LINES >> 2], CCDC_PIX_LINES);
898 regw(ccdc_ctx[CCDC_HORZ_INFO >> 2], CCDC_HORZ_INFO);
899 regw(ccdc_ctx[CCDC_VERT_START >> 2], CCDC_VERT_START);
900 regw(ccdc_ctx[CCDC_VERT_LINES >> 2], CCDC_VERT_LINES);
901 regw(ccdc_ctx[CCDC_CULLING >> 2], CCDC_CULLING);
902 regw(ccdc_ctx[CCDC_HSIZE_OFF >> 2], CCDC_HSIZE_OFF);
903 regw(ccdc_ctx[CCDC_SDOFST >> 2], CCDC_SDOFST);
904 regw(ccdc_ctx[CCDC_SDR_ADDR >> 2], CCDC_SDR_ADDR);
905 regw(ccdc_ctx[CCDC_CLAMP >> 2], CCDC_CLAMP);
906 regw(ccdc_ctx[CCDC_DCSUB >> 2], CCDC_DCSUB);
907 regw(ccdc_ctx[CCDC_COLPTN >> 2], CCDC_COLPTN);
908 regw(ccdc_ctx[CCDC_BLKCMP >> 2], CCDC_BLKCMP);
909 regw(ccdc_ctx[CCDC_FPC >> 2], CCDC_FPC);
910 regw(ccdc_ctx[CCDC_FPC_ADDR >> 2], CCDC_FPC_ADDR);
911 regw(ccdc_ctx[CCDC_VDINT >> 2], CCDC_VDINT);
912 regw(ccdc_ctx[CCDC_ALAW >> 2], CCDC_ALAW);
913 regw(ccdc_ctx[CCDC_REC656IF >> 2], CCDC_REC656IF);
914 regw(ccdc_ctx[CCDC_CCDCFG >> 2], CCDC_CCDCFG);
915 regw(ccdc_ctx[CCDC_FMTCFG >> 2], CCDC_FMTCFG);
916 regw(ccdc_ctx[CCDC_FMT_HORZ >> 2], CCDC_FMT_HORZ);
917 regw(ccdc_ctx[CCDC_FMT_VERT >> 2], CCDC_FMT_VERT);
918 regw(ccdc_ctx[CCDC_FMT_ADDR0 >> 2], CCDC_FMT_ADDR0);
919 regw(ccdc_ctx[CCDC_FMT_ADDR1 >> 2], CCDC_FMT_ADDR1);
920 regw(ccdc_ctx[CCDC_FMT_ADDR2 >> 2], CCDC_FMT_ADDR2);
921 regw(ccdc_ctx[CCDC_FMT_ADDR3 >> 2], CCDC_FMT_ADDR3);
922 regw(ccdc_ctx[CCDC_FMT_ADDR4 >> 2], CCDC_FMT_ADDR4);
923 regw(ccdc_ctx[CCDC_FMT_ADDR5 >> 2], CCDC_FMT_ADDR5);
924 regw(ccdc_ctx[CCDC_FMT_ADDR6 >> 2], CCDC_FMT_ADDR6);
925 regw(ccdc_ctx[CCDC_FMT_ADDR7 >> 2], CCDC_FMT_ADDR7);
926 regw(ccdc_ctx[CCDC_PRGEVEN_0 >> 2], CCDC_PRGEVEN_0);
927 regw(ccdc_ctx[CCDC_PRGEVEN_1 >> 2], CCDC_PRGEVEN_1);
928 regw(ccdc_ctx[CCDC_PRGODD_0 >> 2], CCDC_PRGODD_0);
929 regw(ccdc_ctx[CCDC_PRGODD_1 >> 2], CCDC_PRGODD_1);
930 regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
931 regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
932}
840static struct ccdc_hw_device ccdc_hw_dev = { 933static struct ccdc_hw_device ccdc_hw_dev = {
841 .name = "DM6446 CCDC", 934 .name = "DM6446 CCDC",
842 .owner = THIS_MODULE, 935 .owner = THIS_MODULE,
@@ -945,10 +1038,40 @@ static int dm644x_ccdc_remove(struct platform_device *pdev)
945 return 0; 1038 return 0;
946} 1039}
947 1040
1041static int dm644x_ccdc_suspend(struct device *dev)
1042{
1043 /* Save CCDC context */
1044 ccdc_save_context();
1045 /* Disable CCDC */
1046 ccdc_enable(0);
1047 /* Disable both master and slave clock */
1048 clk_disable(ccdc_cfg.mclk);
1049 clk_disable(ccdc_cfg.sclk);
1050
1051 return 0;
1052}
1053
1054static int dm644x_ccdc_resume(struct device *dev)
1055{
1056 /* Enable both master and slave clock */
1057 clk_enable(ccdc_cfg.mclk);
1058 clk_enable(ccdc_cfg.sclk);
1059 /* Restore CCDC context */
1060 ccdc_restore_context();
1061
1062 return 0;
1063}
1064
1065static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
1066 .suspend = dm644x_ccdc_suspend,
1067 .resume = dm644x_ccdc_resume,
1068};
1069
948static struct platform_driver dm644x_ccdc_driver = { 1070static struct platform_driver dm644x_ccdc_driver = {
949 .driver = { 1071 .driver = {
950 .name = "dm644x_ccdc", 1072 .name = "dm644x_ccdc",
951 .owner = THIS_MODULE, 1073 .owner = THIS_MODULE,
1074 .pm = &dm644x_ccdc_pm_ops,
952 }, 1075 },
953 .remove = __devexit_p(dm644x_ccdc_remove), 1076 .remove = __devexit_p(dm644x_ccdc_remove),
954 .probe = dm644x_ccdc_probe, 1077 .probe = dm644x_ccdc_probe,
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h
index 6e5d05324466..90370e414e2c 100644
--- a/drivers/media/video/davinci/dm644x_ccdc_regs.h
+++ b/drivers/media/video/davinci/dm644x_ccdc_regs.h
@@ -59,7 +59,7 @@
59#define CCDC_PRGODD_0 0x8c 59#define CCDC_PRGODD_0 0x8c
60#define CCDC_PRGODD_1 0x90 60#define CCDC_PRGODD_1 0x90
61#define CCDC_VP_OUT 0x94 61#define CCDC_VP_OUT 0x94
62 62#define CCDC_REG_END 0x98
63 63
64/*************************************************************** 64/***************************************************************
65* Define for various register bit mask and shifts for CCDC 65* Define for various register bit mask and shifts for CCDC
@@ -135,11 +135,19 @@
135#define CCDC_SYN_MODE_INPMOD_SHIFT 12 135#define CCDC_SYN_MODE_INPMOD_SHIFT 12
136#define CCDC_SYN_MODE_INPMOD_MASK 3 136#define CCDC_SYN_MODE_INPMOD_MASK 3
137#define CCDC_SYN_MODE_8BITS (7 << 8) 137#define CCDC_SYN_MODE_8BITS (7 << 8)
138#define CCDC_SYN_MODE_10BITS (6 << 8)
139#define CCDC_SYN_MODE_11BITS (5 << 8)
140#define CCDC_SYN_MODE_12BITS (4 << 8)
141#define CCDC_SYN_MODE_13BITS (3 << 8)
142#define CCDC_SYN_MODE_14BITS (2 << 8)
143#define CCDC_SYN_MODE_15BITS (1 << 8)
144#define CCDC_SYN_MODE_16BITS (0 << 8)
138#define CCDC_SYN_FLDMODE_MASK 1 145#define CCDC_SYN_FLDMODE_MASK 1
139#define CCDC_SYN_FLDMODE_SHIFT 7 146#define CCDC_SYN_FLDMODE_SHIFT 7
140#define CCDC_REC656IF_BT656_EN 3 147#define CCDC_REC656IF_BT656_EN 3
141#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2) 148#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2)
142#define CCDC_CCDCFG_Y8POS_SHIFT 11 149#define CCDC_CCDCFG_Y8POS_SHIFT 11
150#define CCDC_CCDCFG_BW656_10BIT (1 << 5)
143#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249 151#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
144#define CCDC_NO_CULLING 0xffff00ff 152#define CCDC_NO_CULLING 0xffff00ff
145#endif 153#endif
diff --git a/drivers/media/video/davinci/isif_regs.h b/drivers/media/video/davinci/isif_regs.h
index f7b8893a2957..aa69a463c122 100644
--- a/drivers/media/video/davinci/isif_regs.h
+++ b/drivers/media/video/davinci/isif_regs.h
@@ -158,7 +158,7 @@
158 158
159/* gain - offset masks */ 159/* gain - offset masks */
160#define GAIN_INTEGER_SHIFT 9 160#define GAIN_INTEGER_SHIFT 9
161#define OFFSET_MASK 0xFFF 161#define OFFSET_MASK 0xFFF
162#define GAIN_SDRAM_EN_SHIFT 12 162#define GAIN_SDRAM_EN_SHIFT 12
163#define GAIN_IPIPE_EN_SHIFT 13 163#define GAIN_IPIPE_EN_SHIFT 13
164#define GAIN_H3A_EN_SHIFT 14 164#define GAIN_H3A_EN_SHIFT 14
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 398dbe71cb82..1c2588247289 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -475,6 +475,11 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
475 ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev); 475 ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
476 if (!ret) 476 if (!ret)
477 vpfe_dev->initialized = 1; 477 vpfe_dev->initialized = 1;
478
479 /* Clear all VPFE/CCDC interrupts */
480 if (vpfe_dev->cfg->clr_intr)
481 vpfe_dev->cfg->clr_intr(-1);
482
478unlock: 483unlock:
479 mutex_unlock(&ccdc_lock); 484 mutex_unlock(&ccdc_lock);
480 return ret; 485 return ret;
@@ -534,6 +539,16 @@ static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
534 list_del(&vpfe_dev->next_frm->queue); 539 list_del(&vpfe_dev->next_frm->queue);
535 vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE; 540 vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
536 addr = videobuf_to_dma_contig(vpfe_dev->next_frm); 541 addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
542
543 ccdc_dev->hw_ops.setfbaddr(addr);
544}
545
546static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
547{
548 unsigned long addr;
549
550 addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
551 addr += vpfe_dev->field_off;
537 ccdc_dev->hw_ops.setfbaddr(addr); 552 ccdc_dev->hw_ops.setfbaddr(addr);
538} 553}
539 554
@@ -554,7 +569,6 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
554{ 569{
555 struct vpfe_device *vpfe_dev = dev_id; 570 struct vpfe_device *vpfe_dev = dev_id;
556 enum v4l2_field field; 571 enum v4l2_field field;
557 unsigned long addr;
558 int fid; 572 int fid;
559 573
560 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n"); 574 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
@@ -562,7 +576,7 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
562 576
563 /* if streaming not started, don't do anything */ 577 /* if streaming not started, don't do anything */
564 if (!vpfe_dev->started) 578 if (!vpfe_dev->started)
565 return IRQ_HANDLED; 579 goto clear_intr;
566 580
567 /* only for 6446 this will be applicable */ 581 /* only for 6446 this will be applicable */
568 if (NULL != ccdc_dev->hw_ops.reset) 582 if (NULL != ccdc_dev->hw_ops.reset)
@@ -574,7 +588,7 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
574 "frame format is progressive...\n"); 588 "frame format is progressive...\n");
575 if (vpfe_dev->cur_frm != vpfe_dev->next_frm) 589 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
576 vpfe_process_buffer_complete(vpfe_dev); 590 vpfe_process_buffer_complete(vpfe_dev);
577 return IRQ_HANDLED; 591 goto clear_intr;
578 } 592 }
579 593
580 /* interlaced or TB capture check which field we are in hardware */ 594 /* interlaced or TB capture check which field we are in hardware */
@@ -599,12 +613,9 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
599 * the CCDC memory address 613 * the CCDC memory address
600 */ 614 */
601 if (field == V4L2_FIELD_SEQ_TB) { 615 if (field == V4L2_FIELD_SEQ_TB) {
602 addr = 616 vpfe_schedule_bottom_field(vpfe_dev);
603 videobuf_to_dma_contig(vpfe_dev->cur_frm);
604 addr += vpfe_dev->field_off;
605 ccdc_dev->hw_ops.setfbaddr(addr);
606 } 617 }
607 return IRQ_HANDLED; 618 goto clear_intr;
608 } 619 }
609 /* 620 /*
610 * if one field is just being captured configure 621 * if one field is just being captured configure
@@ -624,6 +635,10 @@ static irqreturn_t vpfe_isr(int irq, void *dev_id)
624 */ 635 */
625 vpfe_dev->field_id = fid; 636 vpfe_dev->field_id = fid;
626 } 637 }
638clear_intr:
639 if (vpfe_dev->cfg->clr_intr)
640 vpfe_dev->cfg->clr_intr(irq);
641
627 return IRQ_HANDLED; 642 return IRQ_HANDLED;
628} 643}
629 644
@@ -635,8 +650,11 @@ static irqreturn_t vdint1_isr(int irq, void *dev_id)
635 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n"); 650 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
636 651
637 /* if streaming not started, don't do anything */ 652 /* if streaming not started, don't do anything */
638 if (!vpfe_dev->started) 653 if (!vpfe_dev->started) {
654 if (vpfe_dev->cfg->clr_intr)
655 vpfe_dev->cfg->clr_intr(irq);
639 return IRQ_HANDLED; 656 return IRQ_HANDLED;
657 }
640 658
641 spin_lock(&vpfe_dev->dma_queue_lock); 659 spin_lock(&vpfe_dev->dma_queue_lock);
642 if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) && 660 if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
@@ -644,6 +662,10 @@ static irqreturn_t vdint1_isr(int irq, void *dev_id)
644 vpfe_dev->cur_frm == vpfe_dev->next_frm) 662 vpfe_dev->cur_frm == vpfe_dev->next_frm)
645 vpfe_schedule_next_buffer(vpfe_dev); 663 vpfe_schedule_next_buffer(vpfe_dev);
646 spin_unlock(&vpfe_dev->dma_queue_lock); 664 spin_unlock(&vpfe_dev->dma_queue_lock);
665
666 if (vpfe_dev->cfg->clr_intr)
667 vpfe_dev->cfg->clr_intr(irq);
668
647 return IRQ_HANDLED; 669 return IRQ_HANDLED;
648} 670}
649 671
@@ -714,7 +736,7 @@ static int vpfe_release(struct file *file)
714 /* Decrement device usrs counter */ 736 /* Decrement device usrs counter */
715 vpfe_dev->usrs--; 737 vpfe_dev->usrs--;
716 /* Close the priority */ 738 /* Close the priority */
717 v4l2_prio_close(&vpfe_dev->prio, &fh->prio); 739 v4l2_prio_close(&vpfe_dev->prio, fh->prio);
718 /* If this is the last file handle */ 740 /* If this is the last file handle */
719 if (!vpfe_dev->usrs) { 741 if (!vpfe_dev->usrs) {
720 vpfe_dev->initialized = 0; 742 vpfe_dev->initialized = 0;
@@ -1218,7 +1240,10 @@ static int vpfe_videobuf_setup(struct videobuf_queue *vq,
1218 struct vpfe_device *vpfe_dev = fh->vpfe_dev; 1240 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1219 1241
1220 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n"); 1242 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
1221 *size = config_params.device_bufsize; 1243 *size = vpfe_dev->fmt.fmt.pix.sizeimage;
1244 if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
1245 vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
1246 *size = config_params.device_bufsize;
1222 1247
1223 if (*count < config_params.min_numbuffers) 1248 if (*count < config_params.min_numbuffers)
1224 *count = config_params.min_numbuffers; 1249 *count = config_params.min_numbuffers;
@@ -1233,6 +1258,8 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
1233{ 1258{
1234 struct vpfe_fh *fh = vq->priv_data; 1259 struct vpfe_fh *fh = vq->priv_data;
1235 struct vpfe_device *vpfe_dev = fh->vpfe_dev; 1260 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1261 unsigned long addr;
1262 int ret;
1236 1263
1237 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n"); 1264 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
1238 1265
@@ -1242,8 +1269,18 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
1242 vb->height = vpfe_dev->fmt.fmt.pix.height; 1269 vb->height = vpfe_dev->fmt.fmt.pix.height;
1243 vb->size = vpfe_dev->fmt.fmt.pix.sizeimage; 1270 vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
1244 vb->field = field; 1271 vb->field = field;
1272
1273 ret = videobuf_iolock(vq, vb, NULL);;
1274 if (ret < 0)
1275 return ret;
1276
1277 addr = videobuf_to_dma_contig(vb);
1278 /* Make sure user addresses are aligned to 32 bytes */
1279 if (!ALIGN(addr, 32))
1280 return -EINVAL;
1281
1282 vb->state = VIDEOBUF_PREPARED;
1245 } 1283 }
1246 vb->state = VIDEOBUF_PREPARED;
1247 return 0; 1284 return 0;
1248} 1285}
1249 1286
@@ -1311,13 +1348,6 @@ static int vpfe_reqbufs(struct file *file, void *priv,
1311 return -EINVAL; 1348 return -EINVAL;
1312 } 1349 }
1313 1350
1314 if (V4L2_MEMORY_USERPTR == req_buf->memory) {
1315 /* we don't support user ptr IO */
1316 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:"
1317 " USERPTR IO not supported\n");
1318 return -EINVAL;
1319 }
1320
1321 ret = mutex_lock_interruptible(&vpfe_dev->lock); 1351 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1322 if (ret) 1352 if (ret)
1323 return ret; 1353 return ret;
@@ -1831,7 +1861,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
1831 goto probe_free_dev_mem; 1861 goto probe_free_dev_mem;
1832 } 1862 }
1833 1863
1834 mutex_lock(&ccdc_lock);
1835 /* Allocate memory for ccdc configuration */ 1864 /* Allocate memory for ccdc configuration */
1836 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL); 1865 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
1837 if (NULL == ccdc_cfg) { 1866 if (NULL == ccdc_cfg) {
@@ -1840,6 +1869,8 @@ static __init int vpfe_probe(struct platform_device *pdev)
1840 goto probe_free_lock; 1869 goto probe_free_lock;
1841 } 1870 }
1842 1871
1872 mutex_lock(&ccdc_lock);
1873
1843 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); 1874 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
1844 /* Get VINT0 irq resource */ 1875 /* Get VINT0 irq resource */
1845 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1876 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -2015,18 +2046,14 @@ static int __devexit vpfe_remove(struct platform_device *pdev)
2015 return 0; 2046 return 0;
2016} 2047}
2017 2048
2018static int 2049static int vpfe_suspend(struct device *dev)
2019vpfe_suspend(struct device *dev)
2020{ 2050{
2021 /* add suspend code here later */ 2051 return 0;
2022 return -1;
2023} 2052}
2024 2053
2025static int 2054static int vpfe_resume(struct device *dev)
2026vpfe_resume(struct device *dev)
2027{ 2055{
2028 /* add resume code here later */ 2056 return 0;
2029 return -1;
2030} 2057}
2031 2058
2032static const struct dev_pm_ops vpfe_dev_pm_ops = { 2059static const struct dev_pm_ops vpfe_dev_pm_ops = {
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index 2e5a7fb2d0c9..a7f48b53d3fc 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -869,7 +869,7 @@ static int vpif_release(struct file *filep)
869 mutex_unlock(&common->lock); 869 mutex_unlock(&common->lock);
870 870
871 /* Close the priority */ 871 /* Close the priority */
872 v4l2_prio_close(&ch->prio, &fh->prio); 872 v4l2_prio_close(&ch->prio, fh->prio);
873 873
874 if (fh->initialized) 874 if (fh->initialized)
875 ch->initialized = 0; 875 ch->initialized = 0;
@@ -1444,7 +1444,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1444 } 1444 }
1445 } 1445 }
1446 1446
1447 ret = v4l2_prio_check(&ch->prio, &fh->prio); 1447 ret = v4l2_prio_check(&ch->prio, fh->prio);
1448 if (0 != ret) 1448 if (0 != ret)
1449 return ret; 1449 return ret;
1450 1450
@@ -1554,7 +1554,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1554 } 1554 }
1555 } 1555 }
1556 1556
1557 ret = v4l2_prio_check(&ch->prio, &fh->prio); 1557 ret = v4l2_prio_check(&ch->prio, fh->prio);
1558 if (0 != ret) 1558 if (0 != ret)
1559 return ret; 1559 return ret;
1560 1560
@@ -1710,7 +1710,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
1710 } 1710 }
1711 } 1711 }
1712 1712
1713 ret = v4l2_prio_check(&ch->prio, &fh->prio); 1713 ret = v4l2_prio_check(&ch->prio, fh->prio);
1714 if (0 != ret) 1714 if (0 != ret)
1715 return ret; 1715 return ret;
1716 1716
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 13c3a1b97760..da07607cbc55 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -384,7 +384,7 @@ static int vpif_get_std_info(struct channel_obj *ch)
384 int index; 384 int index;
385 385
386 std_info->stdid = vid_ch->stdid; 386 std_info->stdid = vid_ch->stdid;
387 if (!std_info) 387 if (!std_info->stdid)
388 return -1; 388 return -1;
389 389
390 for (index = 0; index < ARRAY_SIZE(ch_params); index++) { 390 for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
@@ -671,7 +671,7 @@ static int vpif_release(struct file *filep)
671 ch->initialized = 0; 671 ch->initialized = 0;
672 672
673 /* Close the priority */ 673 /* Close the priority */
674 v4l2_prio_close(&ch->prio, &fh->prio); 674 v4l2_prio_close(&ch->prio, fh->prio);
675 filep->private_data = NULL; 675 filep->private_data = NULL;
676 fh->initialized = 0; 676 fh->initialized = 0;
677 kfree(fh); 677 kfree(fh);
@@ -753,7 +753,7 @@ static int vpif_s_fmt_vid_out(struct file *file, void *priv,
753 } 753 }
754 754
755 /* Check for the priority */ 755 /* Check for the priority */
756 ret = v4l2_prio_check(&ch->prio, &fh->prio); 756 ret = v4l2_prio_check(&ch->prio, fh->prio);
757 if (0 != ret) 757 if (0 != ret)
758 return ret; 758 return ret;
759 fh->initialized = 1; 759 fh->initialized = 1;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index bd783387b37d..e182abf476c9 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -491,7 +491,7 @@ static int em28xx_audio_init(struct em28xx *dev)
491 strcpy(pcm->name, "Empia 28xx Capture"); 491 strcpy(pcm->name, "Empia 28xx Capture");
492 492
493 snd_card_set_dev(card, &dev->udev->dev); 493 snd_card_set_dev(card, &dev->udev->dev);
494 strcpy(card->driver, "Empia Em28xx Audio"); 494 strcpy(card->driver, "Em28xx-Audio");
495 strcpy(card->shortname, "Em28xx Audio"); 495 strcpy(card->shortname, "Em28xx Audio");
496 strcpy(card->longname, "Empia Em28xx Audio"); 496 strcpy(card->longname, "Empia Em28xx Audio");
497 497
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index b0fb08337710..3a4fd8514511 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -602,7 +602,7 @@ struct em28xx_board em28xx_boards[] = {
602 .name = "Gadmei UTV330+", 602 .name = "Gadmei UTV330+",
603 .tuner_type = TUNER_TNF_5335MF, 603 .tuner_type = TUNER_TNF_5335MF,
604 .tda9887_conf = TDA9887_PRESENT, 604 .tda9887_conf = TDA9887_PRESENT,
605 .ir_codes = &ir_codes_gadmei_rm008z_table, 605 .ir_codes = RC_MAP_GADMEI_RM008Z,
606 .decoder = EM28XX_SAA711X, 606 .decoder = EM28XX_SAA711X,
607 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, 607 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
608 .input = { { 608 .input = { {
@@ -681,6 +681,20 @@ struct em28xx_board em28xx_boards[] = {
681 .amux = EM28XX_AMUX_LINE_IN, 681 .amux = EM28XX_AMUX_LINE_IN,
682 } }, 682 } },
683 }, 683 },
684 [EM2860_BOARD_TVP5150_REFERENCE_DESIGN] = {
685 .name = "EM2860/TVP5150 Reference Design",
686 .tuner_type = TUNER_ABSENT, /* Capture only device */
687 .decoder = EM28XX_TVP5150,
688 .input = { {
689 .type = EM28XX_VMUX_COMPOSITE1,
690 .vmux = TVP5150_COMPOSITE1,
691 .amux = EM28XX_AMUX_LINE_IN,
692 }, {
693 .type = EM28XX_VMUX_SVIDEO,
694 .vmux = TVP5150_SVIDEO,
695 .amux = EM28XX_AMUX_LINE_IN,
696 } },
697 },
684 [EM2861_BOARD_PLEXTOR_PX_TV100U] = { 698 [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
685 .name = "Plextor ConvertX PX-TV100U", 699 .name = "Plextor ConvertX PX-TV100U",
686 .tuner_type = TUNER_TNF_5335MF, 700 .tuner_type = TUNER_TNF_5335MF,
@@ -777,7 +791,7 @@ struct em28xx_board em28xx_boards[] = {
777 .mts_firmware = 1, 791 .mts_firmware = 1,
778 .has_dvb = 1, 792 .has_dvb = 1,
779 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 793 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
780 .ir_codes = &ir_codes_hauppauge_new_table, 794 .ir_codes = RC_MAP_HAUPPAUGE_NEW,
781 .decoder = EM28XX_TVP5150, 795 .decoder = EM28XX_TVP5150,
782 .input = { { 796 .input = { {
783 .type = EM28XX_VMUX_TELEVISION, 797 .type = EM28XX_VMUX_TELEVISION,
@@ -802,7 +816,7 @@ struct em28xx_board em28xx_boards[] = {
802 .tuner_type = TUNER_XC2028, 816 .tuner_type = TUNER_XC2028,
803 .tuner_gpio = default_tuner_gpio, 817 .tuner_gpio = default_tuner_gpio,
804 .mts_firmware = 1, 818 .mts_firmware = 1,
805 .ir_codes = &ir_codes_hauppauge_new_table, 819 .ir_codes = RC_MAP_HAUPPAUGE_NEW,
806 .decoder = EM28XX_TVP5150, 820 .decoder = EM28XX_TVP5150,
807 .input = { { 821 .input = { {
808 .type = EM28XX_VMUX_TELEVISION, 822 .type = EM28XX_VMUX_TELEVISION,
@@ -828,7 +842,7 @@ struct em28xx_board em28xx_boards[] = {
828 .mts_firmware = 1, 842 .mts_firmware = 1,
829 .has_dvb = 1, 843 .has_dvb = 1,
830 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 844 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
831 .ir_codes = &ir_codes_hauppauge_new_table, 845 .ir_codes = RC_MAP_HAUPPAUGE_NEW,
832 .decoder = EM28XX_TVP5150, 846 .decoder = EM28XX_TVP5150,
833 .input = { { 847 .input = { {
834 .type = EM28XX_VMUX_TELEVISION, 848 .type = EM28XX_VMUX_TELEVISION,
@@ -854,7 +868,7 @@ struct em28xx_board em28xx_boards[] = {
854 .mts_firmware = 1, 868 .mts_firmware = 1,
855 .has_dvb = 1, 869 .has_dvb = 1,
856 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 870 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
857 .ir_codes = &ir_codes_rc5_hauppauge_new_table, 871 .ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW,
858 .decoder = EM28XX_TVP5150, 872 .decoder = EM28XX_TVP5150,
859 .input = { { 873 .input = { {
860 .type = EM28XX_VMUX_TELEVISION, 874 .type = EM28XX_VMUX_TELEVISION,
@@ -880,7 +894,7 @@ struct em28xx_board em28xx_boards[] = {
880 .mts_firmware = 1, 894 .mts_firmware = 1,
881 .has_dvb = 1, 895 .has_dvb = 1,
882 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 896 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
883 .ir_codes = &ir_codes_pinnacle_pctv_hd_table, 897 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
884 .decoder = EM28XX_TVP5150, 898 .decoder = EM28XX_TVP5150,
885 .input = { { 899 .input = { {
886 .type = EM28XX_VMUX_TELEVISION, 900 .type = EM28XX_VMUX_TELEVISION,
@@ -906,7 +920,7 @@ struct em28xx_board em28xx_boards[] = {
906 .mts_firmware = 1, 920 .mts_firmware = 1,
907 .has_dvb = 1, 921 .has_dvb = 1,
908 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 922 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
909 .ir_codes = &ir_codes_ati_tv_wonder_hd_600_table, 923 .ir_codes = RC_MAP_ATI_TV_WONDER_HD_600,
910 .decoder = EM28XX_TVP5150, 924 .decoder = EM28XX_TVP5150,
911 .input = { { 925 .input = { {
912 .type = EM28XX_VMUX_TELEVISION, 926 .type = EM28XX_VMUX_TELEVISION,
@@ -932,7 +946,7 @@ struct em28xx_board em28xx_boards[] = {
932 .decoder = EM28XX_TVP5150, 946 .decoder = EM28XX_TVP5150,
933 .has_dvb = 1, 947 .has_dvb = 1,
934 .dvb_gpio = default_digital, 948 .dvb_gpio = default_digital,
935 .ir_codes = &ir_codes_terratec_cinergy_xs_table, 949 .ir_codes = RC_MAP_TERRATEC_CINERGY_XS,
936 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ 950 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
937 .input = { { 951 .input = { {
938 .type = EM28XX_VMUX_TELEVISION, 952 .type = EM28XX_VMUX_TELEVISION,
@@ -1282,7 +1296,7 @@ struct em28xx_board em28xx_boards[] = {
1282 .decoder = EM28XX_SAA711X, 1296 .decoder = EM28XX_SAA711X,
1283 .has_dvb = 1, 1297 .has_dvb = 1,
1284 .dvb_gpio = em2882_kworld_315u_digital, 1298 .dvb_gpio = em2882_kworld_315u_digital,
1285 .ir_codes = &ir_codes_kworld_315u_table, 1299 .ir_codes = RC_MAP_KWORLD_315U,
1286 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, 1300 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1287 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, 1301 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE,
1288 /* Analog mode - still not ready */ 1302 /* Analog mode - still not ready */
@@ -1404,10 +1418,14 @@ struct em28xx_board em28xx_boards[] = {
1404 }, 1418 },
1405 [EM2882_BOARD_KWORLD_VS_DVBT] = { 1419 [EM2882_BOARD_KWORLD_VS_DVBT] = {
1406 .name = "Kworld VS-DVB-T 323UR", 1420 .name = "Kworld VS-DVB-T 323UR",
1407 .valid = EM28XX_BOARD_NOT_VALIDATED,
1408 .tuner_type = TUNER_XC2028, 1421 .tuner_type = TUNER_XC2028,
1409 .tuner_gpio = default_tuner_gpio, 1422 .tuner_gpio = default_tuner_gpio,
1410 .decoder = EM28XX_TVP5150, 1423 .decoder = EM28XX_TVP5150,
1424 .mts_firmware = 1,
1425 .has_dvb = 1,
1426 .dvb_gpio = kworld_330u_digital,
1427 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
1428 .ir_codes = RC_MAP_KWORLD_315U,
1411 .input = { { 1429 .input = { {
1412 .type = EM28XX_VMUX_TELEVISION, 1430 .type = EM28XX_VMUX_TELEVISION,
1413 .vmux = TVP5150_COMPOSITE0, 1431 .vmux = TVP5150_COMPOSITE0,
@@ -1430,7 +1448,7 @@ struct em28xx_board em28xx_boards[] = {
1430 .decoder = EM28XX_TVP5150, 1448 .decoder = EM28XX_TVP5150,
1431 .has_dvb = 1, 1449 .has_dvb = 1,
1432 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 1450 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
1433 .ir_codes = &ir_codes_terratec_cinergy_xs_table, 1451 .ir_codes = RC_MAP_TERRATEC_CINERGY_XS,
1434 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, 1452 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
1435 .input = { { 1453 .input = { {
1436 .type = EM28XX_VMUX_TELEVISION, 1454 .type = EM28XX_VMUX_TELEVISION,
@@ -1523,7 +1541,7 @@ struct em28xx_board em28xx_boards[] = {
1523 .mts_firmware = 1, 1541 .mts_firmware = 1,
1524 .decoder = EM28XX_TVP5150, 1542 .decoder = EM28XX_TVP5150,
1525 .tuner_gpio = default_tuner_gpio, 1543 .tuner_gpio = default_tuner_gpio,
1526 .ir_codes = &ir_codes_kaiomy_table, 1544 .ir_codes = RC_MAP_KAIOMY,
1527 .input = { { 1545 .input = { {
1528 .type = EM28XX_VMUX_TELEVISION, 1546 .type = EM28XX_VMUX_TELEVISION,
1529 .vmux = TVP5150_COMPOSITE0, 1547 .vmux = TVP5150_COMPOSITE0,
@@ -1623,7 +1641,7 @@ struct em28xx_board em28xx_boards[] = {
1623 .mts_firmware = 1, 1641 .mts_firmware = 1,
1624 .has_dvb = 1, 1642 .has_dvb = 1,
1625 .dvb_gpio = evga_indtube_digital, 1643 .dvb_gpio = evga_indtube_digital,
1626 .ir_codes = &ir_codes_evga_indtube_table, 1644 .ir_codes = RC_MAP_EVGA_INDTUBE,
1627 .input = { { 1645 .input = { {
1628 .type = EM28XX_VMUX_TELEVISION, 1646 .type = EM28XX_VMUX_TELEVISION,
1629 .vmux = TVP5150_COMPOSITE0, 1647 .vmux = TVP5150_COMPOSITE0,
@@ -1672,6 +1690,8 @@ struct usb_device_id em28xx_id_table[] = {
1672 .driver_info = EM2820_BOARD_UNKNOWN }, 1690 .driver_info = EM2820_BOARD_UNKNOWN },
1673 { USB_DEVICE(0xeb1a, 0x2862), 1691 { USB_DEVICE(0xeb1a, 0x2862),
1674 .driver_info = EM2820_BOARD_UNKNOWN }, 1692 .driver_info = EM2820_BOARD_UNKNOWN },
1693 { USB_DEVICE(0xeb1a, 0x2863),
1694 .driver_info = EM2820_BOARD_UNKNOWN },
1675 { USB_DEVICE(0xeb1a, 0x2870), 1695 { USB_DEVICE(0xeb1a, 0x2870),
1676 .driver_info = EM2820_BOARD_UNKNOWN }, 1696 .driver_info = EM2820_BOARD_UNKNOWN },
1677 { USB_DEVICE(0xeb1a, 0x2881), 1697 { USB_DEVICE(0xeb1a, 0x2881),
@@ -1792,6 +1812,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
1792 {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, 1812 {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
1793 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, 1813 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
1794 {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, 1814 {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
1815 {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
1795 {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, 1816 {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
1796 {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, 1817 {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
1797}; 1818};
@@ -2138,6 +2159,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
2138 break; 2159 break;
2139 case EM2883_BOARD_KWORLD_HYBRID_330U: 2160 case EM2883_BOARD_KWORLD_HYBRID_330U:
2140 case EM2882_BOARD_DIKOM_DK300: 2161 case EM2882_BOARD_DIKOM_DK300:
2162 case EM2882_BOARD_KWORLD_VS_DVBT:
2141 ctl->demod = XC3028_FE_CHINA; 2163 ctl->demod = XC3028_FE_CHINA;
2142 ctl->fname = XC2028_DEFAULT_FIRMWARE; 2164 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2143 break; 2165 break;
@@ -2313,21 +2335,21 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2313 switch (dev->model) { 2335 switch (dev->model) {
2314 case EM2800_BOARD_TERRATEC_CINERGY_200: 2336 case EM2800_BOARD_TERRATEC_CINERGY_200:
2315 case EM2820_BOARD_TERRATEC_CINERGY_250: 2337 case EM2820_BOARD_TERRATEC_CINERGY_250:
2316 dev->init_data.ir_codes = &ir_codes_em_terratec_table; 2338 dev->init_data.ir_codes = RC_MAP_EM_TERRATEC;
2317 dev->init_data.get_key = em28xx_get_key_terratec; 2339 dev->init_data.get_key = em28xx_get_key_terratec;
2318 dev->init_data.name = "i2c IR (EM28XX Terratec)"; 2340 dev->init_data.name = "i2c IR (EM28XX Terratec)";
2319 break; 2341 break;
2320 case EM2820_BOARD_PINNACLE_USB_2: 2342 case EM2820_BOARD_PINNACLE_USB_2:
2321 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table; 2343 dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
2322 dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey; 2344 dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
2323 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; 2345 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
2324 break; 2346 break;
2325 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: 2347 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
2326 dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table; 2348 dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW;
2327 dev->init_data.get_key = em28xx_get_key_em_haup; 2349 dev->init_data.get_key = em28xx_get_key_em_haup;
2328 dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; 2350 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2329 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: 2351 case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
2330 dev->init_data.ir_codes = &ir_codes_winfast_usbii_deluxe_table;; 2352 dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;;
2331 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; 2353 dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
2332 dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)"; 2354 dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
2333 break; 2355 break;
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index a41cc5566778..d3813ed789d9 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -782,11 +782,15 @@ int em28xx_resolution_set(struct em28xx *dev)
782 782
783 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); 783 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
784 784
785 /* If we don't set the start position to 4 in VBI mode, we end up 785 /* If we don't set the start position to 2 in VBI mode, we end up
786 with line 21 being YUYV encoded instead of being in 8-bit 786 with line 20/21 being YUYV encoded instead of being in 8-bit
787 greyscale */ 787 greyscale. The core of the issue is that line 21 (and line 23 for
788 PAL WSS) are inside of active video region, and as a result they
789 get the pixelformatting associated with that area. So by cropping
790 it out, we end up with the same format as the rest of the VBI
791 region */
788 if (em28xx_vbi_supported(dev) == 1) 792 if (em28xx_vbi_supported(dev) == 1)
789 em28xx_capture_area_set(dev, 0, 4, width >> 2, height >> 2); 793 em28xx_capture_area_set(dev, 0, 2, width >> 2, height >> 2);
790 else 794 else
791 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); 795 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
792 796
@@ -1174,21 +1178,18 @@ void em28xx_add_into_devlist(struct em28xx *dev)
1174 */ 1178 */
1175 1179
1176static LIST_HEAD(em28xx_extension_devlist); 1180static LIST_HEAD(em28xx_extension_devlist);
1177static DEFINE_MUTEX(em28xx_extension_devlist_lock);
1178 1181
1179int em28xx_register_extension(struct em28xx_ops *ops) 1182int em28xx_register_extension(struct em28xx_ops *ops)
1180{ 1183{
1181 struct em28xx *dev = NULL; 1184 struct em28xx *dev = NULL;
1182 1185
1183 mutex_lock(&em28xx_devlist_mutex); 1186 mutex_lock(&em28xx_devlist_mutex);
1184 mutex_lock(&em28xx_extension_devlist_lock);
1185 list_add_tail(&ops->next, &em28xx_extension_devlist); 1187 list_add_tail(&ops->next, &em28xx_extension_devlist);
1186 list_for_each_entry(dev, &em28xx_devlist, devlist) { 1188 list_for_each_entry(dev, &em28xx_devlist, devlist) {
1187 if (dev) 1189 if (dev)
1188 ops->init(dev); 1190 ops->init(dev);
1189 } 1191 }
1190 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); 1192 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
1191 mutex_unlock(&em28xx_extension_devlist_lock);
1192 mutex_unlock(&em28xx_devlist_mutex); 1193 mutex_unlock(&em28xx_devlist_mutex);
1193 return 0; 1194 return 0;
1194} 1195}
@@ -1204,10 +1205,8 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
1204 ops->fini(dev); 1205 ops->fini(dev);
1205 } 1206 }
1206 1207
1207 mutex_lock(&em28xx_extension_devlist_lock);
1208 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); 1208 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
1209 list_del(&ops->next); 1209 list_del(&ops->next);
1210 mutex_unlock(&em28xx_extension_devlist_lock);
1211 mutex_unlock(&em28xx_devlist_mutex); 1210 mutex_unlock(&em28xx_devlist_mutex);
1212} 1211}
1213EXPORT_SYMBOL(em28xx_unregister_extension); 1212EXPORT_SYMBOL(em28xx_unregister_extension);
@@ -1216,26 +1215,26 @@ void em28xx_init_extension(struct em28xx *dev)
1216{ 1215{
1217 struct em28xx_ops *ops = NULL; 1216 struct em28xx_ops *ops = NULL;
1218 1217
1219 mutex_lock(&em28xx_extension_devlist_lock); 1218 mutex_lock(&em28xx_devlist_mutex);
1220 if (!list_empty(&em28xx_extension_devlist)) { 1219 if (!list_empty(&em28xx_extension_devlist)) {
1221 list_for_each_entry(ops, &em28xx_extension_devlist, next) { 1220 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
1222 if (ops->init) 1221 if (ops->init)
1223 ops->init(dev); 1222 ops->init(dev);
1224 } 1223 }
1225 } 1224 }
1226 mutex_unlock(&em28xx_extension_devlist_lock); 1225 mutex_unlock(&em28xx_devlist_mutex);
1227} 1226}
1228 1227
1229void em28xx_close_extension(struct em28xx *dev) 1228void em28xx_close_extension(struct em28xx *dev)
1230{ 1229{
1231 struct em28xx_ops *ops = NULL; 1230 struct em28xx_ops *ops = NULL;
1232 1231
1233 mutex_lock(&em28xx_extension_devlist_lock); 1232 mutex_lock(&em28xx_devlist_mutex);
1234 if (!list_empty(&em28xx_extension_devlist)) { 1233 if (!list_empty(&em28xx_extension_devlist)) {
1235 list_for_each_entry(ops, &em28xx_extension_devlist, next) { 1234 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
1236 if (ops->fini) 1235 if (ops->fini)
1237 ops->fini(dev); 1236 ops->fini(dev);
1238 } 1237 }
1239 } 1238 }
1240 mutex_unlock(&em28xx_extension_devlist_lock); 1239 mutex_unlock(&em28xx_devlist_mutex);
1241} 1240}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index bcd3c371009b..cf1d8c3655fc 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -467,6 +467,7 @@ static int dvb_init(struct em28xx *dev)
467 } 467 }
468 dev->dvb = dvb; 468 dev->dvb = dvb;
469 469
470 mutex_lock(&dev->lock);
470 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 471 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
471 /* init frontend */ 472 /* init frontend */
472 switch (dev->model) { 473 switch (dev->model) {
@@ -506,6 +507,7 @@ static int dvb_init(struct em28xx *dev)
506 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: 507 case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
507 case EM2881_BOARD_PINNACLE_HYBRID_PRO: 508 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
508 case EM2882_BOARD_DIKOM_DK300: 509 case EM2882_BOARD_DIKOM_DK300:
510 case EM2882_BOARD_KWORLD_VS_DVBT:
509 dvb->frontend = dvb_attach(zl10353_attach, 511 dvb->frontend = dvb_attach(zl10353_attach,
510 &em28xx_zl10353_xc3028_no_i2c_gate, 512 &em28xx_zl10353_xc3028_no_i2c_gate,
511 &dev->i2c_adap); 513 &dev->i2c_adap);
@@ -589,15 +591,16 @@ static int dvb_init(struct em28xx *dev)
589 if (result < 0) 591 if (result < 0)
590 goto out_free; 592 goto out_free;
591 593
592 em28xx_set_mode(dev, EM28XX_SUSPEND);
593 em28xx_info("Successfully loaded em28xx-dvb\n"); 594 em28xx_info("Successfully loaded em28xx-dvb\n");
594 return 0; 595ret:
596 em28xx_set_mode(dev, EM28XX_SUSPEND);
597 mutex_unlock(&dev->lock);
598 return result;
595 599
596out_free: 600out_free:
597 em28xx_set_mode(dev, EM28XX_SUSPEND);
598 kfree(dvb); 601 kfree(dvb);
599 dev->dvb = NULL; 602 dev->dvb = NULL;
600 return result; 603 goto ret;
601} 604}
602 605
603static int dvb_fini(struct em28xx *dev) 606static int dvb_fini(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 20a0001e8885..5c3fd9411b1f 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -39,6 +39,8 @@ static unsigned int ir_debug;
39module_param(ir_debug, int, 0644); 39module_param(ir_debug, int, 0644);
40MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); 40MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
41 41
42#define MODULE_NAME "em28xx"
43
42#define i2cdprintk(fmt, arg...) \ 44#define i2cdprintk(fmt, arg...) \
43 if (ir_debug) { \ 45 if (ir_debug) { \
44 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ 46 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
@@ -360,14 +362,20 @@ static void em28xx_ir_work(struct work_struct *work)
360 schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); 362 schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
361} 363}
362 364
363static void em28xx_ir_start(struct em28xx_IR *ir) 365static int em28xx_ir_start(void *priv)
364{ 366{
367 struct em28xx_IR *ir = priv;
368
365 INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); 369 INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
366 schedule_delayed_work(&ir->work, 0); 370 schedule_delayed_work(&ir->work, 0);
371
372 return 0;
367} 373}
368 374
369static void em28xx_ir_stop(struct em28xx_IR *ir) 375static void em28xx_ir_stop(void *priv)
370{ 376{
377 struct em28xx_IR *ir = priv;
378
371 cancel_delayed_work_sync(&ir->work); 379 cancel_delayed_work_sync(&ir->work);
372} 380}
373 381
@@ -380,7 +388,6 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type)
380 388
381 /* Adjust xclk based o IR table for RC5/NEC tables */ 389 /* Adjust xclk based o IR table for RC5/NEC tables */
382 390
383 dev->board.ir_codes->ir_type = IR_TYPE_OTHER;
384 if (ir_type == IR_TYPE_RC5) { 391 if (ir_type == IR_TYPE_RC5) {
385 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; 392 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
386 ir->full_code = 1; 393 ir->full_code = 1;
@@ -388,11 +395,9 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type)
388 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; 395 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
389 ir_config = EM2874_IR_NEC; 396 ir_config = EM2874_IR_NEC;
390 ir->full_code = 1; 397 ir->full_code = 1;
391 } else 398 } else if (ir_type != IR_TYPE_UNKNOWN)
392 rc = -EINVAL; 399 rc = -EINVAL;
393 400
394 dev->board.ir_codes->ir_type = ir_type;
395
396 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, 401 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
397 EM28XX_XCLK_IR_RC5_MODE); 402 EM28XX_XCLK_IR_RC5_MODE);
398 403
@@ -443,6 +448,13 @@ int em28xx_ir_init(struct em28xx *dev)
443 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; 448 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
444 ir->props.priv = ir; 449 ir->props.priv = ir;
445 ir->props.change_protocol = em28xx_ir_change_protocol; 450 ir->props.change_protocol = em28xx_ir_change_protocol;
451 ir->props.open = em28xx_ir_start;
452 ir->props.close = em28xx_ir_stop;
453
454 /* By default, keep protocol field untouched */
455 err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
456 if (err)
457 goto err_out_free;
446 458
447 /* This is how often we ask the chip for IR information */ 459 /* This is how often we ask the chip for IR information */
448 ir->polling = 100; /* ms */ 460 ir->polling = 100; /* ms */
@@ -455,7 +467,6 @@ int em28xx_ir_init(struct em28xx *dev)
455 strlcat(ir->phys, "/input0", sizeof(ir->phys)); 467 strlcat(ir->phys, "/input0", sizeof(ir->phys));
456 468
457 /* Set IR protocol */ 469 /* Set IR protocol */
458 em28xx_ir_change_protocol(ir, dev->board.ir_codes->ir_type);
459 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); 470 err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
460 if (err < 0) 471 if (err < 0)
461 goto err_out_free; 472 goto err_out_free;
@@ -470,17 +481,15 @@ int em28xx_ir_init(struct em28xx *dev)
470 input_dev->dev.parent = &dev->udev->dev; 481 input_dev->dev.parent = &dev->udev->dev;
471 482
472 483
473 em28xx_ir_start(ir);
474 484
475 /* all done */ 485 /* all done */
476 err = ir_input_register(ir->input, dev->board.ir_codes, 486 err = ir_input_register(ir->input, dev->board.ir_codes,
477 &ir->props); 487 &ir->props, MODULE_NAME);
478 if (err) 488 if (err)
479 goto err_out_stop; 489 goto err_out_stop;
480 490
481 return 0; 491 return 0;
482 err_out_stop: 492 err_out_stop:
483 em28xx_ir_stop(ir);
484 dev->ir = NULL; 493 dev->ir = NULL;
485 err_out_free: 494 err_out_free:
486 kfree(ir); 495 kfree(ir);
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 0fe20110bfd6..20090e34173a 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -203,12 +203,6 @@ static void em28xx_copy_video(struct em28xx *dev,
203 if (dma_q->pos + len > buf->vb.size) 203 if (dma_q->pos + len > buf->vb.size)
204 len = buf->vb.size - dma_q->pos; 204 len = buf->vb.size - dma_q->pos;
205 205
206 if (p[0] != 0x88 && p[0] != 0x22) {
207 em28xx_isocdbg("frame is not complete\n");
208 len += 4;
209 } else
210 p += 4;
211
212 startread = p; 206 startread = p;
213 remain = len; 207 remain = len;
214 208
@@ -309,14 +303,6 @@ static void em28xx_copy_vbi(struct em28xx *dev,
309 if (dma_q->pos + len > buf->vb.size) 303 if (dma_q->pos + len > buf->vb.size)
310 len = buf->vb.size - dma_q->pos; 304 len = buf->vb.size - dma_q->pos;
311 305
312 if ((p[0] == 0x33 && p[1] == 0x95) ||
313 (p[0] == 0x88 && p[1] == 0x88)) {
314 /* Header field, advance past it */
315 p += 4;
316 } else {
317 len += 4;
318 }
319
320 startread = p; 306 startread = p;
321 307
322 startwrite = outp + dma_q->pos; 308 startwrite = outp + dma_q->pos;
@@ -507,8 +493,15 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
507 493
508 dma_q->pos = 0; 494 dma_q->pos = 0;
509 } 495 }
510 if (buf != NULL) 496 if (buf != NULL) {
497 if (p[0] != 0x88 && p[0] != 0x22) {
498 em28xx_isocdbg("frame is not complete\n");
499 len += 4;
500 } else {
501 p += 4;
502 }
511 em28xx_copy_video(dev, dma_q, buf, p, outp, len); 503 em28xx_copy_video(dev, dma_q, buf, p, outp, len);
504 }
512 } 505 }
513 return rc; 506 return rc;
514} 507}
@@ -555,8 +548,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
555 continue; 548 continue;
556 } 549 }
557 550
558 len = urb->iso_frame_desc[i].actual_length - 4; 551 len = urb->iso_frame_desc[i].actual_length;
559
560 if (urb->iso_frame_desc[i].actual_length <= 0) { 552 if (urb->iso_frame_desc[i].actual_length <= 0) {
561 /* em28xx_isocdbg("packet %d is empty",i); - spammy */ 553 /* em28xx_isocdbg("packet %d is empty",i); - spammy */
562 continue; 554 continue;
@@ -577,6 +569,17 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
577 dev->vbi_read = 0; 569 dev->vbi_read = 0;
578 em28xx_isocdbg("VBI START HEADER!!!\n"); 570 em28xx_isocdbg("VBI START HEADER!!!\n");
579 dev->cur_field = p[2]; 571 dev->cur_field = p[2];
572 p += 4;
573 len -= 4;
574 } else if (p[0] == 0x88 && p[1] == 0x88 &&
575 p[2] == 0x88 && p[3] == 0x88) {
576 /* continuation */
577 p += 4;
578 len -= 4;
579 } else if (p[0] == 0x22 && p[1] == 0x5a) {
580 /* start video */
581 p += 4;
582 len -= 4;
580 } 583 }
581 584
582 vbi_size = dev->vbi_width * dev->vbi_height; 585 vbi_size = dev->vbi_width * dev->vbi_height;
@@ -631,9 +634,6 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
631 634
632 if (dev->capture_type == 1) { 635 if (dev->capture_type == 1) {
633 dev->capture_type = 2; 636 dev->capture_type = 2;
634 em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
635 len, (p[2] & 1) ? "odd" : "even");
636
637 if (dev->progressive || !(dev->cur_field & 1)) { 637 if (dev->progressive || !(dev->cur_field & 1)) {
638 if (buf != NULL) 638 if (buf != NULL)
639 buffer_filled(dev, dma_q, buf); 639 buffer_filled(dev, dma_q, buf);
@@ -652,8 +652,25 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
652 652
653 dma_q->pos = 0; 653 dma_q->pos = 0;
654 } 654 }
655 if (buf != NULL && dev->capture_type == 2) 655
656 em28xx_copy_video(dev, dma_q, buf, p, outp, len); 656 if (buf != NULL && dev->capture_type == 2) {
657 if (len > 4 && p[0] == 0x88 && p[1] == 0x88 &&
658 p[2] == 0x88 && p[3] == 0x88) {
659 p += 4;
660 len -= 4;
661 }
662 if (len > 4 && p[0] == 0x22 && p[1] == 0x5a) {
663 em28xx_isocdbg("Video frame %d, len=%i, %s\n",
664 p[2], len, (p[2] & 1) ?
665 "odd" : "even");
666 p += 4;
667 len -= 4;
668 }
669
670 if (len > 0)
671 em28xx_copy_video(dev, dma_q, buf, p, outp,
672 len);
673 }
657 } 674 }
658 return rc; 675 return rc;
659} 676}
@@ -1483,6 +1500,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
1483 return -EINVAL; 1500 return -EINVAL;
1484 1501
1485 strcpy(t->name, "Tuner"); 1502 strcpy(t->name, "Tuner");
1503 t->type = V4L2_TUNER_ANALOG_TV;
1486 1504
1487 mutex_lock(&dev->lock); 1505 mutex_lock(&dev->lock);
1488 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); 1506 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
@@ -1814,7 +1832,7 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
1814 mutex_lock(&dev->lock); 1832 mutex_lock(&dev->lock);
1815 1833
1816 f->fmt.sliced.service_set = 0; 1834 f->fmt.sliced.service_set = 0;
1817 v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f); 1835 v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced);
1818 1836
1819 if (f->fmt.sliced.service_set == 0) 1837 if (f->fmt.sliced.service_set == 0)
1820 rc = -EINVAL; 1838 rc = -EINVAL;
@@ -1836,7 +1854,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
1836 return rc; 1854 return rc;
1837 1855
1838 mutex_lock(&dev->lock); 1856 mutex_lock(&dev->lock);
1839 v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f); 1857 v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced);
1840 mutex_unlock(&dev->lock); 1858 mutex_unlock(&dev->lock);
1841 1859
1842 if (f->fmt.sliced.service_set == 0) 1860 if (f->fmt.sliced.service_set == 0)
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index ba6fe5daff84..b252d1b1b2a7 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -68,6 +68,7 @@
68#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 68#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26
69#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 69#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27
70#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 70#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
71#define EM2860_BOARD_TVP5150_REFERENCE_DESIGN 29
71#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 72#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
72#define EM2821_BOARD_USBGEAR_VD204 31 73#define EM2821_BOARD_USBGEAR_VD204 31
73#define EM2821_BOARD_SUPERCOMP_USB_2 32 74#define EM2821_BOARD_SUPERCOMP_USB_2 32
@@ -140,10 +141,10 @@
140#define EM28XX_NUM_BUFS 5 141#define EM28XX_NUM_BUFS 5
141 142
142/* number of packets for each buffer 143/* number of packets for each buffer
143 windows requests only 40 packets .. so we better do the same 144 windows requests only 64 packets .. so we better do the same
144 this is what I found out for all alternate numbers there! 145 this is what I found out for all alternate numbers there!
145 */ 146 */
146#define EM28XX_NUM_PACKETS 40 147#define EM28XX_NUM_PACKETS 64
147 148
148#define EM28XX_INTERLACED_DEFAULT 1 149#define EM28XX_INTERLACED_DEFAULT 1
149 150
@@ -411,7 +412,7 @@ struct em28xx_board {
411 412
412 struct em28xx_input input[MAX_EM28XX_INPUT]; 413 struct em28xx_input input[MAX_EM28XX_INPUT];
413 struct em28xx_input radio; 414 struct em28xx_input radio;
414 struct ir_scancode_table *ir_codes; 415 char *ir_codes;
415}; 416};
416 417
417struct em28xx_eeprom { 418struct em28xx_eeprom {
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index e6c23d509862..a5cfc76b40b7 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1713,7 +1713,7 @@ et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg)
1713 if (copy_from_user(&ctrl, arg, sizeof(ctrl))) 1713 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1714 return -EFAULT; 1714 return -EFAULT;
1715 1715
1716 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 1716 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
1717 if (ctrl.id == s->qctrl[i].id) { 1717 if (ctrl.id == s->qctrl[i].id) {
1718 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) 1718 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
1719 return -EINVAL; 1719 return -EINVAL;
@@ -1723,7 +1723,9 @@ et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg)
1723 ctrl.value -= ctrl.value % s->qctrl[i].step; 1723 ctrl.value -= ctrl.value % s->qctrl[i].step;
1724 break; 1724 break;
1725 } 1725 }
1726 1726 }
1727 if (i == ARRAY_SIZE(s->qctrl))
1728 return -EINVAL;
1727 if ((err = s->set_ctrl(cam, &ctrl))) 1729 if ((err = s->set_ctrl(cam, &ctrl)))
1728 return err; 1730 return err;
1729 1731
diff --git a/drivers/media/video/font.h b/drivers/media/video/font.h
deleted file mode 100644
index 8b1fecc37599..000000000000
--- a/drivers/media/video/font.h
+++ /dev/null
@@ -1,407 +0,0 @@
1static unsigned char rom8x16_bits[] = {
2/* Character 0 (0x30):
3 ht=16, width=8
4 +--------+
5 | |
6 | |
7 | ***** |
8 |** ** |
9 |** ** |
10 |** *** |
11 |** **** |
12 |**** ** |
13 |*** ** |
14 |** ** |
15 |** ** |
16 | ***** |
17 | |
18 | |
19 | |
20 | |
21 +--------+ */
220x00,
230x00,
240x7c,
250xc6,
260xc6,
270xce,
280xde,
290xf6,
300xe6,
310xc6,
320xc6,
330x7c,
340x00,
350x00,
360x00,
370x00,
38
39/* Character 1 (0x31):
40 ht=16, width=8
41 +--------+
42 | |
43 | |
44 | ** |
45 | **** |
46 | ** |
47 | ** |
48 | ** |
49 | ** |
50 | ** |
51 | ** |
52 | ** |
53 | ****** |
54 | |
55 | |
56 | |
57 | |
58 +--------+ */
590x00,
600x00,
610x18,
620x78,
630x18,
640x18,
650x18,
660x18,
670x18,
680x18,
690x18,
700x7e,
710x00,
720x00,
730x00,
740x00,
75
76/* Character 2 (0x32):
77 ht=16, width=8
78 +--------+
79 | |
80 | |
81 | ***** |
82 |** ** |
83 |** ** |
84 | ** |
85 | ** |
86 | ** |
87 | ** |
88 | ** |
89 |** ** |
90 |******* |
91 | |
92 | |
93 | |
94 | |
95 +--------+ */
960x00,
970x00,
980x7c,
990xc6,
1000xc6,
1010x06,
1020x0c,
1030x18,
1040x30,
1050x60,
1060xc6,
1070xfe,
1080x00,
1090x00,
1100x00,
1110x00,
112
113/* Character 3 (0x33):
114 ht=16, width=8
115 +--------+
116 | |
117 | |
118 | ***** |
119 |** ** |
120 | ** |
121 | ** |
122 | **** |
123 | ** |
124 | ** |
125 | ** |
126 |** ** |
127 | ***** |
128 | |
129 | |
130 | |
131 | |
132 +--------+ */
1330x00,
1340x00,
1350x7c,
1360xc6,
1370x06,
1380x06,
1390x3c,
1400x06,
1410x06,
1420x06,
1430xc6,
1440x7c,
1450x00,
1460x00,
1470x00,
1480x00,
149
150/* Character 4 (0x34):
151 ht=16, width=8
152 +--------+
153 | |
154 | |
155 | ** |
156 | *** |
157 | **** |
158 | ** ** |
159 |** ** |
160 |** ** |
161 |******* |
162 | ** |
163 | ** |
164 | **** |
165 | |
166 | |
167 | |
168 | |
169 +--------+ */
1700x00,
1710x00,
1720x0c,
1730x1c,
1740x3c,
1750x6c,
1760xcc,
1770xcc,
1780xfe,
1790x0c,
1800x0c,
1810x1e,
1820x00,
1830x00,
1840x00,
1850x00,
186
187/* Character 5 (0x35):
188 ht=16, width=8
189 +--------+
190 | |
191 | |
192 |******* |
193 |** |
194 |** |
195 |** |
196 |****** |
197 | ** |
198 | ** |
199 | ** |
200 |** ** |
201 | ***** |
202 | |
203 | |
204 | |
205 | |
206 +--------+ */
2070x00,
2080x00,
2090xfe,
2100xc0,
2110xc0,
2120xc0,
2130xfc,
2140x06,
2150x06,
2160x06,
2170xc6,
2180x7c,
2190x00,
2200x00,
2210x00,
2220x00,
223
224/* Character 6 (0x36):
225 ht=16, width=8
226 +--------+
227 | |
228 | |
229 | ***** |
230 |** ** |
231 |** |
232 |** |
233 |****** |
234 |** ** |
235 |** ** |
236 |** ** |
237 |** ** |
238 | ***** |
239 | |
240 | |
241 | |
242 | |
243 +--------+ */
2440x00,
2450x00,
2460x7c,
2470xc6,
2480xc0,
2490xc0,
2500xfc,
2510xc6,
2520xc6,
2530xc6,
2540xc6,
2550x7c,
2560x00,
2570x00,
2580x00,
2590x00,
260
261/* Character 7 (0x37):
262 ht=16, width=8
263 +--------+
264 | |
265 | |
266 |******* |
267 |** ** |
268 | ** |
269 | ** |
270 | ** |
271 | ** |
272 | ** |
273 | ** |
274 | ** |
275 | ** |
276 | |
277 | |
278 | |
279 | |
280 +--------+ */
2810x00,
2820x00,
2830xfe,
2840xc6,
2850x06,
2860x0c,
2870x18,
2880x30,
2890x30,
2900x30,
2910x30,
2920x30,
2930x00,
2940x00,
2950x00,
2960x00,
297
298/* Character 8 (0x38):
299 ht=16, width=8
300 +--------+
301 | |
302 | |
303 | ***** |
304 |** ** |
305 |** ** |
306 |** ** |
307 | ***** |
308 |** ** |
309 |** ** |
310 |** ** |
311 |** ** |
312 | ***** |
313 | |
314 | |
315 | |
316 | |
317 +--------+ */
3180x00,
3190x00,
3200x7c,
3210xc6,
3220xc6,
3230xc6,
3240x7c,
3250xc6,
3260xc6,
3270xc6,
3280xc6,
3290x7c,
3300x00,
3310x00,
3320x00,
3330x00,
334
335/* Character 9 (0x39):
336 ht=16, width=8
337 +--------+
338 | |
339 | |
340 | ***** |
341 |** ** |
342 |** ** |
343 |** ** |
344 |** ** |
345 | ****** |
346 | ** |
347 | ** |
348 |** ** |
349 | ***** |
350 | |
351 | |
352 | |
353 | |
354 +--------+ */
3550x00,
3560x00,
3570x7c,
3580xc6,
3590xc6,
3600xc6,
3610xc6,
3620x7e,
3630x06,
3640x06,
3650xc6,
3660x7c,
3670x00,
3680x00,
3690x00,
3700x00,
371/* Character : (0x3a):
372 ht=16, width=8
373 +--------+
374 | |
375 | |
376 | |
377 | |
378 | |
379 | ** |
380 | ** |
381 | |
382 | |
383 | ** |
384 | ** |
385 | |
386 | |
387 | |
388 | |
389 | |
390 +--------+ */
3910x00,
3920x00,
3930x00,
3940x00,
3950x00,
3960x0c,
3970x0c,
3980x00,
3990x00,
4000x0c,
4010x0c,
4020x00,
4030x00,
4040x00,
4050x00,
4060x00,
407};
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index e0060c1f0544..5d920e584de7 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -172,12 +172,6 @@ config USB_GSPCA_SN9C20X
172 To compile this driver as a module, choose M here: the 172 To compile this driver as a module, choose M here: the
173 module will be called gspca_sn9c20x. 173 module will be called gspca_sn9c20x.
174 174
175config USB_GSPCA_SN9C20X_EVDEV
176 bool "Enable evdev support"
177 depends on USB_GSPCA_SN9C20X && INPUT
178 ---help---
179 Say Y here in order to enable evdev support for sn9c20x webcam button.
180
181config USB_GSPCA_SONIXB 175config USB_GSPCA_SONIXB
182 tristate "SONIX Bayer USB Camera Driver" 176 tristate "SONIX Bayer USB Camera Driver"
183 depends on VIDEO_V4L2 && USB_GSPCA 177 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 82945ed5cbe5..58b696f455be 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -374,7 +374,7 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
374static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val); 374static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val);
375static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val); 375static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val);
376 376
377static struct ctrl sd_ctrls[] = { 377static const struct ctrl sd_ctrls[] = {
378 { 378 {
379 { 379 {
380 .id = V4L2_CID_BRIGHTNESS, 380 .id = V4L2_CID_BRIGHTNESS,
@@ -861,7 +861,7 @@ static int save_camera_state(struct gspca_dev *gspca_dev)
861 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); 861 return do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
862} 862}
863 863
864int command_setformat(struct gspca_dev *gspca_dev) 864static int command_setformat(struct gspca_dev *gspca_dev)
865{ 865{
866 struct sd *sd = (struct sd *) gspca_dev; 866 struct sd *sd = (struct sd *) gspca_dev;
867 int ret; 867 int ret;
@@ -878,7 +878,7 @@ int command_setformat(struct gspca_dev *gspca_dev)
878 sd->params.roi.rowStart, sd->params.roi.rowEnd); 878 sd->params.roi.rowStart, sd->params.roi.rowEnd);
879} 879}
880 880
881int command_setcolourparams(struct gspca_dev *gspca_dev) 881static int command_setcolourparams(struct gspca_dev *gspca_dev)
882{ 882{
883 struct sd *sd = (struct sd *) gspca_dev; 883 struct sd *sd = (struct sd *) gspca_dev;
884 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams, 884 return do_command(gspca_dev, CPIA_COMMAND_SetColourParams,
@@ -887,7 +887,7 @@ int command_setcolourparams(struct gspca_dev *gspca_dev)
887 sd->params.colourParams.saturation, 0); 887 sd->params.colourParams.saturation, 0);
888} 888}
889 889
890int command_setapcor(struct gspca_dev *gspca_dev) 890static int command_setapcor(struct gspca_dev *gspca_dev)
891{ 891{
892 struct sd *sd = (struct sd *) gspca_dev; 892 struct sd *sd = (struct sd *) gspca_dev;
893 return do_command(gspca_dev, CPIA_COMMAND_SetApcor, 893 return do_command(gspca_dev, CPIA_COMMAND_SetApcor,
@@ -897,7 +897,7 @@ int command_setapcor(struct gspca_dev *gspca_dev)
897 sd->params.apcor.gain8); 897 sd->params.apcor.gain8);
898} 898}
899 899
900int command_setvloffset(struct gspca_dev *gspca_dev) 900static int command_setvloffset(struct gspca_dev *gspca_dev)
901{ 901{
902 struct sd *sd = (struct sd *) gspca_dev; 902 struct sd *sd = (struct sd *) gspca_dev;
903 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset, 903 return do_command(gspca_dev, CPIA_COMMAND_SetVLOffset,
@@ -907,7 +907,7 @@ int command_setvloffset(struct gspca_dev *gspca_dev)
907 sd->params.vlOffset.gain8); 907 sd->params.vlOffset.gain8);
908} 908}
909 909
910int command_setexposure(struct gspca_dev *gspca_dev) 910static int command_setexposure(struct gspca_dev *gspca_dev)
911{ 911{
912 struct sd *sd = (struct sd *) gspca_dev; 912 struct sd *sd = (struct sd *) gspca_dev;
913 int ret; 913 int ret;
@@ -943,7 +943,7 @@ int command_setexposure(struct gspca_dev *gspca_dev)
943 return ret; 943 return ret;
944} 944}
945 945
946int command_setcolourbalance(struct gspca_dev *gspca_dev) 946static int command_setcolourbalance(struct gspca_dev *gspca_dev)
947{ 947{
948 struct sd *sd = (struct sd *) gspca_dev; 948 struct sd *sd = (struct sd *) gspca_dev;
949 949
@@ -973,7 +973,7 @@ int command_setcolourbalance(struct gspca_dev *gspca_dev)
973 return -EINVAL; 973 return -EINVAL;
974} 974}
975 975
976int command_setcompressiontarget(struct gspca_dev *gspca_dev) 976static int command_setcompressiontarget(struct gspca_dev *gspca_dev)
977{ 977{
978 struct sd *sd = (struct sd *) gspca_dev; 978 struct sd *sd = (struct sd *) gspca_dev;
979 979
@@ -983,7 +983,7 @@ int command_setcompressiontarget(struct gspca_dev *gspca_dev)
983 sd->params.compressionTarget.targetQ, 0); 983 sd->params.compressionTarget.targetQ, 0);
984} 984}
985 985
986int command_setyuvtresh(struct gspca_dev *gspca_dev) 986static int command_setyuvtresh(struct gspca_dev *gspca_dev)
987{ 987{
988 struct sd *sd = (struct sd *) gspca_dev; 988 struct sd *sd = (struct sd *) gspca_dev;
989 989
@@ -992,7 +992,7 @@ int command_setyuvtresh(struct gspca_dev *gspca_dev)
992 sd->params.yuvThreshold.uvThreshold, 0, 0); 992 sd->params.yuvThreshold.uvThreshold, 0, 0);
993} 993}
994 994
995int command_setcompressionparams(struct gspca_dev *gspca_dev) 995static int command_setcompressionparams(struct gspca_dev *gspca_dev)
996{ 996{
997 struct sd *sd = (struct sd *) gspca_dev; 997 struct sd *sd = (struct sd *) gspca_dev;
998 998
@@ -1009,7 +1009,7 @@ int command_setcompressionparams(struct gspca_dev *gspca_dev)
1009 sd->params.compressionParams.decimationThreshMod); 1009 sd->params.compressionParams.decimationThreshMod);
1010} 1010}
1011 1011
1012int command_setcompression(struct gspca_dev *gspca_dev) 1012static int command_setcompression(struct gspca_dev *gspca_dev)
1013{ 1013{
1014 struct sd *sd = (struct sd *) gspca_dev; 1014 struct sd *sd = (struct sd *) gspca_dev;
1015 1015
@@ -1018,7 +1018,7 @@ int command_setcompression(struct gspca_dev *gspca_dev)
1018 sd->params.compression.decimation, 0, 0); 1018 sd->params.compression.decimation, 0, 0);
1019} 1019}
1020 1020
1021int command_setsensorfps(struct gspca_dev *gspca_dev) 1021static int command_setsensorfps(struct gspca_dev *gspca_dev)
1022{ 1022{
1023 struct sd *sd = (struct sd *) gspca_dev; 1023 struct sd *sd = (struct sd *) gspca_dev;
1024 1024
@@ -1027,7 +1027,7 @@ int command_setsensorfps(struct gspca_dev *gspca_dev)
1027 sd->params.sensorFps.baserate, 0, 0); 1027 sd->params.sensorFps.baserate, 0, 0);
1028} 1028}
1029 1029
1030int command_setflickerctrl(struct gspca_dev *gspca_dev) 1030static int command_setflickerctrl(struct gspca_dev *gspca_dev)
1031{ 1031{
1032 struct sd *sd = (struct sd *) gspca_dev; 1032 struct sd *sd = (struct sd *) gspca_dev;
1033 1033
@@ -1038,7 +1038,7 @@ int command_setflickerctrl(struct gspca_dev *gspca_dev)
1038 0); 1038 0);
1039} 1039}
1040 1040
1041int command_setecptiming(struct gspca_dev *gspca_dev) 1041static int command_setecptiming(struct gspca_dev *gspca_dev)
1042{ 1042{
1043 struct sd *sd = (struct sd *) gspca_dev; 1043 struct sd *sd = (struct sd *) gspca_dev;
1044 1044
@@ -1046,12 +1046,12 @@ int command_setecptiming(struct gspca_dev *gspca_dev)
1046 sd->params.ecpTiming, 0, 0, 0); 1046 sd->params.ecpTiming, 0, 0, 0);
1047} 1047}
1048 1048
1049int command_pause(struct gspca_dev *gspca_dev) 1049static int command_pause(struct gspca_dev *gspca_dev)
1050{ 1050{
1051 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0); 1051 return do_command(gspca_dev, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
1052} 1052}
1053 1053
1054int command_resume(struct gspca_dev *gspca_dev) 1054static int command_resume(struct gspca_dev *gspca_dev)
1055{ 1055{
1056 struct sd *sd = (struct sd *) gspca_dev; 1056 struct sd *sd = (struct sd *) gspca_dev;
1057 1057
@@ -1059,7 +1059,8 @@ int command_resume(struct gspca_dev *gspca_dev)
1059 0, sd->params.streamStartLine, 0, 0); 1059 0, sd->params.streamStartLine, 0, 0);
1060} 1060}
1061 1061
1062int command_setlights(struct gspca_dev *gspca_dev) 1062#if 0 /* Currently unused */
1063static int command_setlights(struct gspca_dev *gspca_dev)
1063{ 1064{
1064 struct sd *sd = (struct sd *) gspca_dev; 1065 struct sd *sd = (struct sd *) gspca_dev;
1065 int ret, p1, p2; 1066 int ret, p1, p2;
@@ -1078,6 +1079,7 @@ int command_setlights(struct gspca_dev *gspca_dev)
1078 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0, 1079 return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
1079 p1 | p2 | 0xE0, 0); 1080 p1 | p2 | 0xE0, 0);
1080} 1081}
1082#endif
1081 1083
1082static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) 1084static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
1083{ 1085{
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 222af479150b..efe615938783 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Main USB camera driver 2 * Main USB camera driver
3 * 3 *
4 * Copyright (C) 2008-2009 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008-2010 Jean-François Moine <http://moinejf.free.fr>
5 * 5 *
6 * Camera button input handling by Márton Németh 6 * Camera button input handling by Márton Németh
7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> 7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
@@ -35,12 +35,12 @@
35#include <linux/io.h> 35#include <linux/io.h>
36#include <asm/page.h> 36#include <asm/page.h>
37#include <linux/uaccess.h> 37#include <linux/uaccess.h>
38#include <linux/jiffies.h> 38#include <linux/ktime.h>
39#include <media/v4l2-ioctl.h> 39#include <media/v4l2-ioctl.h>
40 40
41#include "gspca.h" 41#include "gspca.h"
42 42
43#ifdef CONFIG_INPUT 43#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
44#include <linux/input.h> 44#include <linux/input.h>
45#include <linux/usb/input.h> 45#include <linux/usb/input.h>
46#endif 46#endif
@@ -51,7 +51,7 @@
51#error "DEF_NURBS too big" 51#error "DEF_NURBS too big"
52#endif 52#endif
53 53
54MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 54MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
55MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 55MODULE_DESCRIPTION("GSPCA USB Camera Driver");
56MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
57 57
@@ -115,7 +115,7 @@ static const struct vm_operations_struct gspca_vm_ops = {
115/* 115/*
116 * Input and interrupt endpoint handling functions 116 * Input and interrupt endpoint handling functions
117 */ 117 */
118#ifdef CONFIG_INPUT 118#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
119static void int_irq(struct urb *urb) 119static void int_irq(struct urb *urb)
120{ 120{
121 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; 121 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
@@ -199,7 +199,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
199 void *buffer = NULL; 199 void *buffer = NULL;
200 int ret = -EINVAL; 200 int ret = -EINVAL;
201 201
202 buffer_len = ep->wMaxPacketSize; 202 buffer_len = le16_to_cpu(ep->wMaxPacketSize);
203 interval = ep->bInterval; 203 interval = ep->bInterval;
204 PDEBUG(D_PROBE, "found int in endpoint: 0x%x, " 204 PDEBUG(D_PROBE, "found int in endpoint: 0x%x, "
205 "buffer_len=%u, interval=%u", 205 "buffer_len=%u, interval=%u",
@@ -213,7 +213,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
213 goto error; 213 goto error;
214 } 214 }
215 215
216 buffer = usb_buffer_alloc(dev, ep->wMaxPacketSize, 216 buffer = usb_buffer_alloc(dev, buffer_len,
217 GFP_KERNEL, &urb->transfer_dma); 217 GFP_KERNEL, &urb->transfer_dma);
218 if (!buffer) { 218 if (!buffer) {
219 ret = -ENOMEM; 219 ret = -ENOMEM;
@@ -280,9 +280,18 @@ static void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
280 } 280 }
281} 281}
282#else 282#else
283#define gspca_input_connect(gspca_dev) 0 283static inline void gspca_input_destroy_urb(struct gspca_dev *gspca_dev)
284#define gspca_input_create_urb(gspca_dev) 284{
285#define gspca_input_destroy_urb(gspca_dev) 285}
286
287static inline void gspca_input_create_urb(struct gspca_dev *gspca_dev)
288{
289}
290
291static inline int gspca_input_connect(struct gspca_dev *dev)
292{
293 return 0;
294}
286#endif 295#endif
287 296
288/* get the current input frame buffer */ 297/* get the current input frame buffer */
@@ -442,8 +451,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
442 * is not queued, discard the whole frame */ 451 * is not queued, discard the whole frame */
443 if (packet_type == FIRST_PACKET) { 452 if (packet_type == FIRST_PACKET) {
444 frame->data_end = frame->data; 453 frame->data_end = frame->data;
445 jiffies_to_timeval(get_jiffies_64(), 454 frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
446 &frame->v4l2_buf.timestamp);
447 frame->v4l2_buf.sequence = ++gspca_dev->sequence; 455 frame->v4l2_buf.sequence = ++gspca_dev->sequence;
448 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { 456 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
449 if (packet_type == LAST_PACKET) 457 if (packet_type == LAST_PACKET)
@@ -605,6 +613,37 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
605 } 613 }
606} 614}
607 615
616static int gspca_set_alt0(struct gspca_dev *gspca_dev)
617{
618 int ret;
619
620 if (gspca_dev->alt == 0)
621 return 0;
622 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
623 if (ret < 0)
624 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
625 return ret;
626}
627
628/* Note: both the queue and the usb locks should be held when calling this */
629static void gspca_stream_off(struct gspca_dev *gspca_dev)
630{
631 gspca_dev->streaming = 0;
632 if (gspca_dev->present) {
633 if (gspca_dev->sd_desc->stopN)
634 gspca_dev->sd_desc->stopN(gspca_dev);
635 destroy_urbs(gspca_dev);
636 gspca_input_destroy_urb(gspca_dev);
637 gspca_set_alt0(gspca_dev);
638 gspca_input_create_urb(gspca_dev);
639 }
640
641 /* always call stop0 to free the subdriver's resources */
642 if (gspca_dev->sd_desc->stop0)
643 gspca_dev->sd_desc->stop0(gspca_dev);
644 PDEBUG(D_STREAM, "stream off OK");
645}
646
608/* 647/*
609 * look for an input transfer endpoint in an alternate setting 648 * look for an input transfer endpoint in an alternate setting
610 */ 649 */
@@ -830,8 +869,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
830 } 869 }
831 if (ret >= 0) 870 if (ret >= 0)
832 break; 871 break;
833 gspca_dev->streaming = 0; 872 gspca_stream_off(gspca_dev);
834 destroy_urbs(gspca_dev);
835 if (ret != -ENOSPC) { 873 if (ret != -ENOSPC) {
836 PDEBUG(D_ERR|D_STREAM, 874 PDEBUG(D_ERR|D_STREAM,
837 "usb_submit_urb alt %d err %d", 875 "usb_submit_urb alt %d err %d",
@@ -861,37 +899,6 @@ out:
861 return ret; 899 return ret;
862} 900}
863 901
864static int gspca_set_alt0(struct gspca_dev *gspca_dev)
865{
866 int ret;
867
868 if (gspca_dev->alt == 0)
869 return 0;
870 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
871 if (ret < 0)
872 PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
873 return ret;
874}
875
876/* Note: both the queue and the usb locks should be held when calling this */
877static void gspca_stream_off(struct gspca_dev *gspca_dev)
878{
879 gspca_dev->streaming = 0;
880 if (gspca_dev->present) {
881 if (gspca_dev->sd_desc->stopN)
882 gspca_dev->sd_desc->stopN(gspca_dev);
883 destroy_urbs(gspca_dev);
884 gspca_input_destroy_urb(gspca_dev);
885 gspca_set_alt0(gspca_dev);
886 gspca_input_create_urb(gspca_dev);
887 }
888
889 /* always call stop0 to free the subdriver's resources */
890 if (gspca_dev->sd_desc->stop0)
891 gspca_dev->sd_desc->stop0(gspca_dev);
892 PDEBUG(D_STREAM, "stream off OK");
893}
894
895static void gspca_set_default_mode(struct gspca_dev *gspca_dev) 902static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
896{ 903{
897 int i; 904 int i;
@@ -1495,7 +1502,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1495 struct v4l2_requestbuffers *rb) 1502 struct v4l2_requestbuffers *rb)
1496{ 1503{
1497 struct gspca_dev *gspca_dev = priv; 1504 struct gspca_dev *gspca_dev = priv;
1498 int i, ret = 0; 1505 int i, ret = 0, streaming;
1499 1506
1500 switch (rb->memory) { 1507 switch (rb->memory) {
1501 case GSPCA_MEMORY_READ: /* (internal call) */ 1508 case GSPCA_MEMORY_READ: /* (internal call) */
@@ -1530,7 +1537,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1530 } 1537 }
1531 1538
1532 /* stop streaming */ 1539 /* stop streaming */
1533 if (gspca_dev->streaming) { 1540 streaming = gspca_dev->streaming;
1541 if (streaming) {
1534 mutex_lock(&gspca_dev->usb_lock); 1542 mutex_lock(&gspca_dev->usb_lock);
1535 gspca_dev->usb_err = 0; 1543 gspca_dev->usb_err = 0;
1536 gspca_stream_off(gspca_dev); 1544 gspca_stream_off(gspca_dev);
@@ -1549,6 +1557,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1549 if (ret == 0) { 1557 if (ret == 0) {
1550 rb->count = gspca_dev->nframes; 1558 rb->count = gspca_dev->nframes;
1551 gspca_dev->capt_file = file; 1559 gspca_dev->capt_file = file;
1560 if (streaming)
1561 ret = gspca_init_transfer(gspca_dev);
1552 } 1562 }
1553out: 1563out:
1554 mutex_unlock(&gspca_dev->queue_lock); 1564 mutex_unlock(&gspca_dev->queue_lock);
@@ -1582,6 +1592,12 @@ static int vidioc_streamon(struct file *file, void *priv,
1582 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1592 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1583 return -ERESTARTSYS; 1593 return -ERESTARTSYS;
1584 1594
1595 /* check the capture file */
1596 if (gspca_dev->capt_file != file) {
1597 ret = -EBUSY;
1598 goto out;
1599 }
1600
1585 if (gspca_dev->nframes == 0 1601 if (gspca_dev->nframes == 0
1586 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { 1602 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
1587 ret = -EINVAL; 1603 ret = -EINVAL;
@@ -1619,6 +1635,12 @@ static int vidioc_streamoff(struct file *file, void *priv,
1619 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1635 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1620 return -ERESTARTSYS; 1636 return -ERESTARTSYS;
1621 1637
1638 /* check the capture file */
1639 if (gspca_dev->capt_file != file) {
1640 ret = -EBUSY;
1641 goto out;
1642 }
1643
1622 /* stop streaming */ 1644 /* stop streaming */
1623 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { 1645 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
1624 ret = -ERESTARTSYS; 1646 ret = -ERESTARTSYS;
@@ -2124,7 +2146,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
2124 } 2146 }
2125 2147
2126 /* get a frame */ 2148 /* get a frame */
2127 jiffies_to_timeval(get_jiffies_64(), &timestamp); 2149 timestamp = ktime_to_timeval(ktime_get());
2128 timestamp.tv_sec--; 2150 timestamp.tv_sec--;
2129 n = 2; 2151 n = 2;
2130 for (;;) { 2152 for (;;) {
@@ -2315,7 +2337,7 @@ int gspca_dev_probe(struct usb_interface *intf,
2315 2337
2316 return 0; 2338 return 0;
2317out: 2339out:
2318#ifdef CONFIG_INPUT 2340#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2319 if (gspca_dev->input_dev) 2341 if (gspca_dev->input_dev)
2320 input_unregister_device(gspca_dev->input_dev); 2342 input_unregister_device(gspca_dev->input_dev);
2321#endif 2343#endif
@@ -2334,7 +2356,7 @@ EXPORT_SYMBOL(gspca_dev_probe);
2334void gspca_disconnect(struct usb_interface *intf) 2356void gspca_disconnect(struct usb_interface *intf)
2335{ 2357{
2336 struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2358 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2337#ifdef CONFIG_INPUT 2359#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2338 struct input_dev *input_dev; 2360 struct input_dev *input_dev;
2339#endif 2361#endif
2340 2362
@@ -2348,7 +2370,7 @@ void gspca_disconnect(struct usb_interface *intf)
2348 wake_up_interruptible(&gspca_dev->wq); 2370 wake_up_interruptible(&gspca_dev->wq);
2349 } 2371 }
2350 2372
2351#ifdef CONFIG_INPUT 2373#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2352 gspca_input_destroy_urb(gspca_dev); 2374 gspca_input_destroy_urb(gspca_dev);
2353 input_dev = gspca_dev->input_dev; 2375 input_dev = gspca_dev->input_dev;
2354 if (input_dev) { 2376 if (input_dev) {
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 8bb242fb79de..8b963dfae861 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -130,7 +130,7 @@ struct sd_desc {
130 cam_reg_op get_register; 130 cam_reg_op get_register;
131#endif 131#endif
132 cam_ident_op get_chip_ident; 132 cam_ident_op get_chip_ident;
133#ifdef CONFIG_INPUT 133#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
134 cam_int_pkt_op int_pkt_scan; 134 cam_int_pkt_op int_pkt_scan;
135 /* other_input makes the gspca core create gspca_dev->input even when 135 /* other_input makes the gspca core create gspca_dev->input even when
136 int_pkt_scan is NULL, for cams with non interrupt driven buttons */ 136 int_pkt_scan is NULL, for cams with non interrupt driven buttons */
@@ -158,7 +158,7 @@ struct gspca_dev {
158 struct module *module; /* subdriver handling the device */ 158 struct module *module; /* subdriver handling the device */
159 struct usb_device *dev; 159 struct usb_device *dev;
160 struct file *capt_file; /* file doing video capture */ 160 struct file *capt_file; /* file doing video capture */
161#ifdef CONFIG_INPUT 161#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
162 struct input_dev *input_dev; 162 struct input_dev *input_dev;
163 char phys[64]; /* physical device path */ 163 char phys[64]; /* physical device path */
164#endif 164#endif
@@ -171,7 +171,7 @@ struct gspca_dev {
171#define USB_BUF_SZ 64 171#define USB_BUF_SZ 64
172 __u8 *usb_buf; /* buffer for USB exchanges */ 172 __u8 *usb_buf; /* buffer for USB exchanges */
173 struct urb *urb[MAX_NURBS]; 173 struct urb *urb[MAX_NURBS];
174#ifdef CONFIG_INPUT 174#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
175 struct urb *int_urb; 175 struct urb *int_urb;
176#endif 176#endif
177 177
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 957e05e2d08f..dc1e4efe30fb 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -10,8 +10,8 @@
10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
11 * 11 *
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr 12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 * PS3 Eye camera, brightness, contrast, hue, AWB control added 13 * PS3 Eye camera - brightness, contrast, awb, agc, aec controls
14 * by Max Thrun <bear24rw@gmail.com> 14 * added by Max Thrun <bear24rw@gmail.com>
15 * 15 *
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -60,15 +60,13 @@ struct sd {
60 u8 contrast; 60 u8 contrast;
61 u8 gain; 61 u8 gain;
62 u8 exposure; 62 u8 exposure;
63 u8 redblc; 63 u8 agc;
64 u8 blueblc;
65 u8 hue;
66 u8 autogain;
67 u8 awb; 64 u8 awb;
65 u8 aec;
68 s8 sharpness; 66 s8 sharpness;
69 u8 hflip; 67 u8 hflip;
70 u8 vflip; 68 u8 vflip;
71 69 u8 freqfltr;
72}; 70};
73 71
74/* V4L2 controls supported by the driver */ 72/* V4L2 controls supported by the driver */
@@ -76,197 +74,183 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 74static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 75static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 76static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val); 77static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val); 78static int sd_getagc(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 79static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 80static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 81static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 82static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); 85static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); 86static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setaec(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getaec(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 90static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 91static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 92static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setfreqfltr(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getfreqfltr(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_querymenu(struct gspca_dev *gspca_dev,
96 struct v4l2_querymenu *menu);
99 97
100static const struct ctrl sd_ctrls[] = { 98static const struct ctrl sd_ctrls[] = {
101 { /* 0 */ 99 { /* 0 */
102 { 100 {
103 .id = V4L2_CID_BRIGHTNESS, 101 .id = V4L2_CID_BRIGHTNESS,
104 .type = V4L2_CTRL_TYPE_INTEGER, 102 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Brightness", 103 .name = "Brightness",
106 .minimum = 0, 104 .minimum = 0,
107 .maximum = 255, 105 .maximum = 255,
108 .step = 1, 106 .step = 1,
109#define BRIGHTNESS_DEF 20 107#define BRIGHTNESS_DEF 0
110 .default_value = BRIGHTNESS_DEF, 108 .default_value = BRIGHTNESS_DEF,
109 },
110 .set = sd_setbrightness,
111 .get = sd_getbrightness,
111 }, 112 },
112 .set = sd_setbrightness, 113 { /* 1 */
113 .get = sd_getbrightness, 114 {
114 }, 115 .id = V4L2_CID_CONTRAST,
115 { /* 1 */ 116 .type = V4L2_CTRL_TYPE_INTEGER,
116 { 117 .name = "Contrast",
117 .id = V4L2_CID_CONTRAST, 118 .minimum = 0,
118 .type = V4L2_CTRL_TYPE_INTEGER, 119 .maximum = 255,
119 .name = "Contrast", 120 .step = 1,
120 .minimum = 0, 121#define CONTRAST_DEF 32
121 .maximum = 255, 122 .default_value = CONTRAST_DEF,
122 .step = 1, 123 },
123#define CONTRAST_DEF 37 124 .set = sd_setcontrast,
124 .default_value = CONTRAST_DEF, 125 .get = sd_getcontrast,
125 }, 126 },
126 .set = sd_setcontrast, 127 { /* 2 */
127 .get = sd_getcontrast, 128 {
128 }, 129 .id = V4L2_CID_GAIN,
129 { /* 2 */ 130 .type = V4L2_CTRL_TYPE_INTEGER,
130 { 131 .name = "Main Gain",
131 .id = V4L2_CID_GAIN, 132 .minimum = 0,
132 .type = V4L2_CTRL_TYPE_INTEGER, 133 .maximum = 63,
133 .name = "Main Gain", 134 .step = 1,
134 .minimum = 0,
135 .maximum = 63,
136 .step = 1,
137#define GAIN_DEF 20 135#define GAIN_DEF 20
138 .default_value = GAIN_DEF, 136 .default_value = GAIN_DEF,
137 },
138 .set = sd_setgain,
139 .get = sd_getgain,
139 }, 140 },
140 .set = sd_setgain, 141 { /* 3 */
141 .get = sd_getgain, 142 {
142 }, 143 .id = V4L2_CID_EXPOSURE,
143 { /* 3 */ 144 .type = V4L2_CTRL_TYPE_INTEGER,
144 { 145 .name = "Exposure",
145 .id = V4L2_CID_EXPOSURE, 146 .minimum = 0,
146 .type = V4L2_CTRL_TYPE_INTEGER, 147 .maximum = 255,
147 .name = "Exposure", 148 .step = 1,
148 .minimum = 0,
149 .maximum = 255,
150 .step = 1,
151#define EXPO_DEF 120 149#define EXPO_DEF 120
152 .default_value = EXPO_DEF, 150 .default_value = EXPO_DEF,
153 }, 151 },
154 .set = sd_setexposure, 152 .set = sd_setexposure,
155 .get = sd_getexposure, 153 .get = sd_getexposure,
156 },
157 { /* 4 */
158 {
159 .id = V4L2_CID_RED_BALANCE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Red Balance",
162 .minimum = 0,
163 .maximum = 255,
164 .step = 1,
165#define RED_BALANCE_DEF 128
166 .default_value = RED_BALANCE_DEF,
167 }, 154 },
168 .set = sd_setredblc, 155 { /* 4 */
169 .get = sd_getredblc, 156 {
170 }, 157 .id = V4L2_CID_AUTOGAIN,
171 { /* 5 */ 158 .type = V4L2_CTRL_TYPE_BOOLEAN,
172 { 159 .name = "Auto Gain",
173 .id = V4L2_CID_BLUE_BALANCE, 160 .minimum = 0,
174 .type = V4L2_CTRL_TYPE_INTEGER, 161 .maximum = 1,
175 .name = "Blue Balance", 162 .step = 1,
176 .minimum = 0, 163#define AGC_DEF 1
177 .maximum = 255, 164 .default_value = AGC_DEF,
178 .step = 1, 165 },
179#define BLUE_BALANCE_DEF 128 166 .set = sd_setagc,
180 .default_value = BLUE_BALANCE_DEF, 167 .get = sd_getagc,
181 }, 168 },
182 .set = sd_setblueblc, 169#define AWB_IDX 5
183 .get = sd_getblueblc, 170 { /* 5 */
184 }, 171 {
185 { /* 6 */ 172 .id = V4L2_CID_AUTO_WHITE_BALANCE,
186 { 173 .type = V4L2_CTRL_TYPE_BOOLEAN,
187 .id = V4L2_CID_HUE, 174 .name = "Auto White Balance",
188 .type = V4L2_CTRL_TYPE_INTEGER, 175 .minimum = 0,
189 .name = "Hue", 176 .maximum = 1,
190 .minimum = 0, 177 .step = 1,
191 .maximum = 255, 178#define AWB_DEF 1
192 .step = 1, 179 .default_value = AWB_DEF,
193#define HUE_DEF 143 180 },
194 .default_value = HUE_DEF, 181 .set = sd_setawb,
182 .get = sd_getawb,
195 }, 183 },
196 .set = sd_sethue, 184 { /* 6 */
197 .get = sd_gethue, 185 {
198 }, 186 .id = V4L2_CID_EXPOSURE_AUTO,
199 { /* 7 */ 187 .type = V4L2_CTRL_TYPE_BOOLEAN,
200 { 188 .name = "Auto Exposure",
201 .id = V4L2_CID_AUTOGAIN, 189 .minimum = 0,
202 .type = V4L2_CTRL_TYPE_BOOLEAN, 190 .maximum = 1,
203 .name = "Autogain", 191 .step = 1,
204 .minimum = 0, 192#define AEC_DEF 1
205 .maximum = 1, 193 .default_value = AEC_DEF,
206 .step = 1, 194 },
207#define AUTOGAIN_DEF 0 195 .set = sd_setaec,
208 .default_value = AUTOGAIN_DEF, 196 .get = sd_getaec,
209 }, 197 },
210 .set = sd_setautogain, 198 { /* 7 */
211 .get = sd_getautogain, 199 {
212 }, 200 .id = V4L2_CID_SHARPNESS,
213#define AWB_IDX 8 201 .type = V4L2_CTRL_TYPE_INTEGER,
214 { /* 8 */ 202 .name = "Sharpness",
215 { 203 .minimum = 0,
216 .id = V4L2_CID_AUTO_WHITE_BALANCE, 204 .maximum = 63,
217 .type = V4L2_CTRL_TYPE_BOOLEAN, 205 .step = 1,
218 .name = "Auto White Balance",
219 .minimum = 0,
220 .maximum = 1,
221 .step = 1,
222#define AWB_DEF 0
223 .default_value = AWB_DEF,
224 },
225 .set = sd_setawb,
226 .get = sd_getawb,
227 },
228 { /* 9 */
229 {
230 .id = V4L2_CID_SHARPNESS,
231 .type = V4L2_CTRL_TYPE_INTEGER,
232 .name = "Sharpness",
233 .minimum = 0,
234 .maximum = 63,
235 .step = 1,
236#define SHARPNESS_DEF 0 206#define SHARPNESS_DEF 0
237 .default_value = SHARPNESS_DEF, 207 .default_value = SHARPNESS_DEF,
208 },
209 .set = sd_setsharpness,
210 .get = sd_getsharpness,
238 }, 211 },
239 .set = sd_setsharpness, 212 { /* 8 */
240 .get = sd_getsharpness, 213 {
241 }, 214 .id = V4L2_CID_HFLIP,
242 { /* 10 */ 215 .type = V4L2_CTRL_TYPE_BOOLEAN,
243 { 216 .name = "HFlip",
244 .id = V4L2_CID_HFLIP, 217 .minimum = 0,
245 .type = V4L2_CTRL_TYPE_BOOLEAN, 218 .maximum = 1,
246 .name = "HFlip", 219 .step = 1,
247 .minimum = 0,
248 .maximum = 1,
249 .step = 1,
250#define HFLIP_DEF 0 220#define HFLIP_DEF 0
251 .default_value = HFLIP_DEF, 221 .default_value = HFLIP_DEF,
222 },
223 .set = sd_sethflip,
224 .get = sd_gethflip,
252 }, 225 },
253 .set = sd_sethflip, 226 { /* 9 */
254 .get = sd_gethflip, 227 {
255 }, 228 .id = V4L2_CID_VFLIP,
256 { /* 11 */ 229 .type = V4L2_CTRL_TYPE_BOOLEAN,
257 { 230 .name = "VFlip",
258 .id = V4L2_CID_VFLIP, 231 .minimum = 0,
259 .type = V4L2_CTRL_TYPE_BOOLEAN, 232 .maximum = 1,
260 .name = "VFlip", 233 .step = 1,
261 .minimum = 0,
262 .maximum = 1,
263 .step = 1,
264#define VFLIP_DEF 0 234#define VFLIP_DEF 0
265 .default_value = VFLIP_DEF, 235 .default_value = VFLIP_DEF,
236 },
237 .set = sd_setvflip,
238 .get = sd_getvflip,
239 },
240 { /* 10 */
241 {
242 .id = V4L2_CID_POWER_LINE_FREQUENCY,
243 .type = V4L2_CTRL_TYPE_MENU,
244 .name = "Light Frequency Filter",
245 .minimum = 0,
246 .maximum = 1,
247 .step = 1,
248#define FREQFLTR_DEF 0
249 .default_value = FREQFLTR_DEF,
250 },
251 .set = sd_setfreqfltr,
252 .get = sd_getfreqfltr,
266 }, 253 },
267 .set = sd_setvflip,
268 .get = sd_getvflip,
269 },
270}; 254};
271 255
272static const struct v4l2_pix_format ov772x_mode[] = { 256static const struct v4l2_pix_format ov772x_mode[] = {
@@ -675,14 +659,14 @@ static void setbrightness(struct gspca_dev *gspca_dev)
675{ 659{
676 struct sd *sd = (struct sd *) gspca_dev; 660 struct sd *sd = (struct sd *) gspca_dev;
677 661
678 sccb_reg_write(gspca_dev, 0x9B, sd->brightness); 662 sccb_reg_write(gspca_dev, 0x9b, sd->brightness);
679} 663}
680 664
681static void setcontrast(struct gspca_dev *gspca_dev) 665static void setcontrast(struct gspca_dev *gspca_dev)
682{ 666{
683 struct sd *sd = (struct sd *) gspca_dev; 667 struct sd *sd = (struct sd *) gspca_dev;
684 668
685 sccb_reg_write(gspca_dev, 0x9C, sd->contrast); 669 sccb_reg_write(gspca_dev, 0x9c, sd->contrast);
686} 670}
687 671
688static void setgain(struct gspca_dev *gspca_dev) 672static void setgain(struct gspca_dev *gspca_dev)
@@ -690,6 +674,9 @@ static void setgain(struct gspca_dev *gspca_dev)
690 struct sd *sd = (struct sd *) gspca_dev; 674 struct sd *sd = (struct sd *) gspca_dev;
691 u8 val; 675 u8 val;
692 676
677 if (sd->agc)
678 return;
679
693 val = sd->gain; 680 val = sd->gain;
694 switch (val & 0x30) { 681 switch (val & 0x30) {
695 case 0x00: 682 case 0x00:
@@ -717,55 +704,68 @@ static void setexposure(struct gspca_dev *gspca_dev)
717 struct sd *sd = (struct sd *) gspca_dev; 704 struct sd *sd = (struct sd *) gspca_dev;
718 u8 val; 705 u8 val;
719 706
707 if (sd->aec)
708 return;
709
710 /* 'val' is one byte and represents half of the exposure value we are
711 * going to set into registers, a two bytes value:
712 *
713 * MSB: ((u16) val << 1) >> 8 == val >> 7
714 * LSB: ((u16) val << 1) & 0xff == val << 1
715 */
720 val = sd->exposure; 716 val = sd->exposure;
721 sccb_reg_write(gspca_dev, 0x08, val >> 7); 717 sccb_reg_write(gspca_dev, 0x08, val >> 7);
722 sccb_reg_write(gspca_dev, 0x10, val << 1); 718 sccb_reg_write(gspca_dev, 0x10, val << 1);
723} 719}
724 720
725static void setredblc(struct gspca_dev *gspca_dev) 721static void setagc(struct gspca_dev *gspca_dev)
726{ 722{
727 struct sd *sd = (struct sd *) gspca_dev; 723 struct sd *sd = (struct sd *) gspca_dev;
728 724
729 sccb_reg_write(gspca_dev, 0x43, sd->redblc); 725 if (sd->agc) {
730} 726 sccb_reg_write(gspca_dev, 0x13,
731 727 sccb_reg_read(gspca_dev, 0x13) | 0x04);
732static void setblueblc(struct gspca_dev *gspca_dev) 728 sccb_reg_write(gspca_dev, 0x64,
733{ 729 sccb_reg_read(gspca_dev, 0x64) | 0x03);
734 struct sd *sd = (struct sd *) gspca_dev; 730 } else {
735 731 sccb_reg_write(gspca_dev, 0x13,
736 sccb_reg_write(gspca_dev, 0x42, sd->blueblc); 732 sccb_reg_read(gspca_dev, 0x13) & ~0x04);
737} 733 sccb_reg_write(gspca_dev, 0x64,
738 734 sccb_reg_read(gspca_dev, 0x64) & ~0x03);
739static void sethue(struct gspca_dev *gspca_dev)
740{
741 struct sd *sd = (struct sd *) gspca_dev;
742 735
743 sccb_reg_write(gspca_dev, 0x01, sd->hue); 736 setgain(gspca_dev);
737 }
744} 738}
745 739
746static void setautogain(struct gspca_dev *gspca_dev) 740static void setawb(struct gspca_dev *gspca_dev)
747{ 741{
748 struct sd *sd = (struct sd *) gspca_dev; 742 struct sd *sd = (struct sd *) gspca_dev;
749 743
750 if (sd->autogain) { 744 if (sd->awb) {
751 sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */ 745 sccb_reg_write(gspca_dev, 0x13,
752 sccb_reg_write(gspca_dev, 0x64, 746 sccb_reg_read(gspca_dev, 0x13) | 0x02);
753 sccb_reg_read(gspca_dev, 0x64) | 0x03); 747 sccb_reg_write(gspca_dev, 0x63,
748 sccb_reg_read(gspca_dev, 0x63) | 0xc0);
754 } else { 749 } else {
755 sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */ 750 sccb_reg_write(gspca_dev, 0x13,
756 sccb_reg_write(gspca_dev, 0x64, 751 sccb_reg_read(gspca_dev, 0x13) & ~0x02);
757 sccb_reg_read(gspca_dev, 0x64) & 0xfc); 752 sccb_reg_write(gspca_dev, 0x63,
753 sccb_reg_read(gspca_dev, 0x63) & ~0xc0);
758 } 754 }
759} 755}
760 756
761static void setawb(struct gspca_dev *gspca_dev) 757static void setaec(struct gspca_dev *gspca_dev)
762{ 758{
763 struct sd *sd = (struct sd *) gspca_dev; 759 struct sd *sd = (struct sd *) gspca_dev;
764 760
765 if (sd->awb) 761 if (sd->aec)
766 sccb_reg_write(gspca_dev, 0x63, 0xe0); /* AWB on */ 762 sccb_reg_write(gspca_dev, 0x13,
767 else 763 sccb_reg_read(gspca_dev, 0x13) | 0x01);
768 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ 764 else {
765 sccb_reg_write(gspca_dev, 0x13,
766 sccb_reg_read(gspca_dev, 0x13) & ~0x01);
767 setexposure(gspca_dev);
768 }
769} 769}
770 770
771static void setsharpness(struct gspca_dev *gspca_dev) 771static void setsharpness(struct gspca_dev *gspca_dev)
@@ -774,8 +774,8 @@ static void setsharpness(struct gspca_dev *gspca_dev)
774 u8 val; 774 u8 val;
775 775
776 val = sd->sharpness; 776 val = sd->sharpness;
777 sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */ 777 sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */
778 sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */ 778 sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */
779} 779}
780 780
781static void sethflip(struct gspca_dev *gspca_dev) 781static void sethflip(struct gspca_dev *gspca_dev)
@@ -787,7 +787,7 @@ static void sethflip(struct gspca_dev *gspca_dev)
787 sccb_reg_read(gspca_dev, 0x0c) | 0x40); 787 sccb_reg_read(gspca_dev, 0x0c) | 0x40);
788 else 788 else
789 sccb_reg_write(gspca_dev, 0x0c, 789 sccb_reg_write(gspca_dev, 0x0c,
790 sccb_reg_read(gspca_dev, 0x0c) & 0xbf); 790 sccb_reg_read(gspca_dev, 0x0c) & ~0x40);
791} 791}
792 792
793static void setvflip(struct gspca_dev *gspca_dev) 793static void setvflip(struct gspca_dev *gspca_dev)
@@ -799,9 +799,20 @@ static void setvflip(struct gspca_dev *gspca_dev)
799 sccb_reg_read(gspca_dev, 0x0c) | 0x80); 799 sccb_reg_read(gspca_dev, 0x0c) | 0x80);
800 else 800 else
801 sccb_reg_write(gspca_dev, 0x0c, 801 sccb_reg_write(gspca_dev, 0x0c,
802 sccb_reg_read(gspca_dev, 0x0c) & 0x7f); 802 sccb_reg_read(gspca_dev, 0x0c) & ~0x80);
803} 803}
804 804
805static void setfreqfltr(struct gspca_dev *gspca_dev)
806{
807 struct sd *sd = (struct sd *) gspca_dev;
808
809 if (sd->freqfltr == 0)
810 sccb_reg_write(gspca_dev, 0x2b, 0x00);
811 else
812 sccb_reg_write(gspca_dev, 0x2b, 0x9e);
813}
814
815
805/* this function is called at probe time */ 816/* this function is called at probe time */
806static int sd_config(struct gspca_dev *gspca_dev, 817static int sd_config(struct gspca_dev *gspca_dev,
807 const struct usb_device_id *id) 818 const struct usb_device_id *id)
@@ -825,26 +836,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
825 sd->contrast = CONTRAST_DEF; 836 sd->contrast = CONTRAST_DEF;
826 sd->gain = GAIN_DEF; 837 sd->gain = GAIN_DEF;
827 sd->exposure = EXPO_DEF; 838 sd->exposure = EXPO_DEF;
828 sd->redblc = RED_BALANCE_DEF; 839#if AGC_DEF != 0
829 sd->blueblc = BLUE_BALANCE_DEF; 840 sd->agc = AGC_DEF;
830 sd->hue = HUE_DEF;
831#if AUTOGAIN_DEF != 0
832 sd->autogain = AUTOGAIN_DEF;
833#else 841#else
834 gspca_dev->ctrl_inac |= (1 << AWB_IDX); 842 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
835#endif 843#endif
836#if AWB_DEF != 0 844 sd->awb = AWB_DEF;
837 sd->awb = AWB_DEF 845 sd->aec = AEC_DEF;
838#endif
839#if SHARPNESS_DEF != 0
840 sd->sharpness = SHARPNESS_DEF; 846 sd->sharpness = SHARPNESS_DEF;
841#endif
842#if HFLIP_DEF != 0
843 sd->hflip = HFLIP_DEF; 847 sd->hflip = HFLIP_DEF;
844#endif
845#if VFLIP_DEF != 0
846 sd->vflip = VFLIP_DEF; 848 sd->vflip = VFLIP_DEF;
847#endif 849 sd->freqfltr = FREQFLTR_DEF;
848 850
849 return 0; 851 return 0;
850} 852}
@@ -904,18 +906,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
904 } 906 }
905 set_frame_rate(gspca_dev); 907 set_frame_rate(gspca_dev);
906 908
907 setautogain(gspca_dev); 909 setagc(gspca_dev);
908 setawb(gspca_dev); 910 setawb(gspca_dev);
911 setaec(gspca_dev);
909 setgain(gspca_dev); 912 setgain(gspca_dev);
910 setredblc(gspca_dev);
911 setblueblc(gspca_dev);
912 sethue(gspca_dev);
913 setexposure(gspca_dev); 913 setexposure(gspca_dev);
914 setbrightness(gspca_dev); 914 setbrightness(gspca_dev);
915 setcontrast(gspca_dev); 915 setcontrast(gspca_dev);
916 setsharpness(gspca_dev); 916 setsharpness(gspca_dev);
917 setvflip(gspca_dev); 917 setvflip(gspca_dev);
918 sethflip(gspca_dev); 918 sethflip(gspca_dev);
919 setfreqfltr(gspca_dev);
919 920
920 ov534_set_led(gspca_dev, 1); 921 ov534_set_led(gspca_dev, 1);
921 ov534_reg_write(gspca_dev, 0xe0, 0x00); 922 ov534_reg_write(gspca_dev, 0xe0, 0x00);
@@ -1092,65 +1093,11 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1092 return 0; 1093 return 0;
1093} 1094}
1094 1095
1095static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) 1096static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val)
1096{
1097 struct sd *sd = (struct sd *) gspca_dev;
1098
1099 sd->redblc = val;
1100 if (gspca_dev->streaming)
1101 setredblc(gspca_dev);
1102 return 0;
1103}
1104
1105static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
1106{
1107 struct sd *sd = (struct sd *) gspca_dev;
1108
1109 *val = sd->redblc;
1110 return 0;
1111}
1112
1113static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
1114{
1115 struct sd *sd = (struct sd *) gspca_dev;
1116
1117 sd->blueblc = val;
1118 if (gspca_dev->streaming)
1119 setblueblc(gspca_dev);
1120 return 0;
1121}
1122
1123static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
1124{ 1097{
1125 struct sd *sd = (struct sd *) gspca_dev; 1098 struct sd *sd = (struct sd *) gspca_dev;
1126 1099
1127 *val = sd->blueblc; 1100 sd->agc = val;
1128 return 0;
1129}
1130
1131static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
1132{
1133 struct sd *sd = (struct sd *) gspca_dev;
1134
1135 sd->hue = val;
1136 if (gspca_dev->streaming)
1137 sethue(gspca_dev);
1138 return 0;
1139}
1140
1141static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
1142{
1143 struct sd *sd = (struct sd *) gspca_dev;
1144
1145 *val = sd->hue;
1146 return 0;
1147}
1148
1149static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1150{
1151 struct sd *sd = (struct sd *) gspca_dev;
1152
1153 sd->autogain = val;
1154 1101
1155 if (gspca_dev->streaming) { 1102 if (gspca_dev->streaming) {
1156 1103
@@ -1160,16 +1107,16 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1160 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX); 1107 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX);
1161 else 1108 else
1162 gspca_dev->ctrl_inac |= (1 << AWB_IDX); 1109 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
1163 setautogain(gspca_dev); 1110 setagc(gspca_dev);
1164 } 1111 }
1165 return 0; 1112 return 0;
1166} 1113}
1167 1114
1168static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1115static int sd_getagc(struct gspca_dev *gspca_dev, __s32 *val)
1169{ 1116{
1170 struct sd *sd = (struct sd *) gspca_dev; 1117 struct sd *sd = (struct sd *) gspca_dev;
1171 1118
1172 *val = sd->autogain; 1119 *val = sd->agc;
1173 return 0; 1120 return 0;
1174} 1121}
1175 1122
@@ -1191,6 +1138,24 @@ static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
1191 return 0; 1138 return 0;
1192} 1139}
1193 1140
1141static int sd_setaec(struct gspca_dev *gspca_dev, __s32 val)
1142{
1143 struct sd *sd = (struct sd *) gspca_dev;
1144
1145 sd->aec = val;
1146 if (gspca_dev->streaming)
1147 setaec(gspca_dev);
1148 return 0;
1149}
1150
1151static int sd_getaec(struct gspca_dev *gspca_dev, __s32 *val)
1152{
1153 struct sd *sd = (struct sd *) gspca_dev;
1154
1155 *val = sd->aec;
1156 return 0;
1157}
1158
1194static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) 1159static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1195{ 1160{
1196 struct sd *sd = (struct sd *) gspca_dev; 1161 struct sd *sd = (struct sd *) gspca_dev;
@@ -1245,6 +1210,43 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1245 return 0; 1210 return 0;
1246} 1211}
1247 1212
1213static int sd_setfreqfltr(struct gspca_dev *gspca_dev, __s32 val)
1214{
1215 struct sd *sd = (struct sd *) gspca_dev;
1216
1217 sd->freqfltr = val;
1218 if (gspca_dev->streaming)
1219 setfreqfltr(gspca_dev);
1220 return 0;
1221}
1222
1223static int sd_getfreqfltr(struct gspca_dev *gspca_dev, __s32 *val)
1224{
1225 struct sd *sd = (struct sd *) gspca_dev;
1226
1227 *val = sd->freqfltr;
1228 return 0;
1229}
1230
1231static int sd_querymenu(struct gspca_dev *gspca_dev,
1232 struct v4l2_querymenu *menu)
1233{
1234 switch (menu->id) {
1235 case V4L2_CID_POWER_LINE_FREQUENCY:
1236 switch (menu->index) {
1237 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1238 strcpy((char *) menu->name, "Disabled");
1239 return 0;
1240 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1241 strcpy((char *) menu->name, "50 Hz");
1242 return 0;
1243 }
1244 break;
1245 }
1246
1247 return -EINVAL;
1248}
1249
1248/* get stream parameters (framerate) */ 1250/* get stream parameters (framerate) */
1249static int sd_get_streamparm(struct gspca_dev *gspca_dev, 1251static int sd_get_streamparm(struct gspca_dev *gspca_dev,
1250 struct v4l2_streamparm *parm) 1252 struct v4l2_streamparm *parm)
@@ -1296,6 +1298,7 @@ static const struct sd_desc sd_desc = {
1296 .start = sd_start, 1298 .start = sd_start,
1297 .stopN = sd_stopN, 1299 .stopN = sd_stopN,
1298 .pkt_scan = sd_pkt_scan, 1300 .pkt_scan = sd_pkt_scan,
1301 .querymenu = sd_querymenu,
1299 .get_streamparm = sd_get_streamparm, 1302 .get_streamparm = sd_get_streamparm,
1300 .set_streamparm = sd_set_streamparm, 1303 .set_streamparm = sd_set_streamparm,
1301}; 1304};
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 0c87c3490b1e..a40f8893310d 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -99,7 +99,7 @@ static const struct ctrl sd_ctrls[] = {
99 { 99 {
100 .id = V4L2_CID_EXPOSURE, 100 .id = V4L2_CID_EXPOSURE,
101 .type = V4L2_CTRL_TYPE_INTEGER, 101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "exposure", 102 .name = "Exposure",
103 .minimum = PAC207_EXPOSURE_MIN, 103 .minimum = PAC207_EXPOSURE_MIN,
104 .maximum = PAC207_EXPOSURE_MAX, 104 .maximum = PAC207_EXPOSURE_MAX,
105 .step = 1, 105 .step = 1,
@@ -130,7 +130,7 @@ static const struct ctrl sd_ctrls[] = {
130 { 130 {
131 .id = V4L2_CID_GAIN, 131 .id = V4L2_CID_GAIN,
132 .type = V4L2_CTRL_TYPE_INTEGER, 132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "gain", 133 .name = "Gain",
134 .minimum = PAC207_GAIN_MIN, 134 .minimum = PAC207_GAIN_MIN,
135 .maximum = PAC207_GAIN_MAX, 135 .maximum = PAC207_GAIN_MAX,
136 .step = 1, 136 .step = 1,
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c
index dda5fd4aa69e..71d9447a7986 100644
--- a/drivers/media/video/gspca/sn9c2028.c
+++ b/drivers/media/video/gspca/sn9c2028.c
@@ -39,7 +39,7 @@ struct init_command {
39}; 39};
40 40
41/* V4L2 controls supported by the driver */ 41/* V4L2 controls supported by the driver */
42static struct ctrl sd_ctrls[] = { 42static const struct ctrl sd_ctrls[] = {
43}; 43};
44 44
45/* How to change the resolution of any of the VGA cams is unknown */ 45/* How to change the resolution of any of the VGA cams is unknown */
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 3dee3e5844b6..644a7fd4701a 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -18,10 +18,7 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 21#ifdef CONFIG_INPUT
22#include <linux/kthread.h>
23#include <linux/freezer.h>
24#include <linux/usb/input.h>
25#include <linux/input.h> 22#include <linux/input.h>
26#include <linux/slab.h> 23#include <linux/slab.h>
27#endif 24#endif
@@ -30,6 +27,7 @@
30#include "jpeg.h" 27#include "jpeg.h"
31 28
32#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
30#include <linux/dmi.h>
33 31
34MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " 32MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
35 "microdia project <microdia@googlegroups.com>"); 33 "microdia project <microdia@googlegroups.com>");
@@ -52,9 +50,15 @@ MODULE_LICENSE("GPL");
52#define SENSOR_MT9V112 7 50#define SENSOR_MT9V112 7
53#define SENSOR_MT9M001 8 51#define SENSOR_MT9M001 8
54#define SENSOR_MT9M111 9 52#define SENSOR_MT9M111 9
55#define SENSOR_HV7131R 10 53#define SENSOR_MT9M112 10
54#define SENSOR_HV7131R 11
56#define SENSOR_MT9VPRB 20 55#define SENSOR_MT9VPRB 20
57 56
57/* camera flags */
58#define HAS_NO_BUTTON 0x1
59#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
60#define FLIP_DETECT 0x4
61
58/* specific webcam descriptor */ 62/* specific webcam descriptor */
59struct sd { 63struct sd {
60 struct gspca_dev gspca_dev; 64 struct gspca_dev gspca_dev;
@@ -88,11 +92,7 @@ struct sd {
88 u8 *jpeg_hdr; 92 u8 *jpeg_hdr;
89 u8 quality; 93 u8 quality;
90 94
91#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 95 u8 flags;
92 struct input_dev *input_dev;
93 u8 input_gpio;
94 struct task_struct *input_task;
95#endif
96}; 96};
97 97
98struct i2c_reg_u8 { 98struct i2c_reg_u8 {
@@ -130,6 +130,39 @@ static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
130static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); 130static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
131static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); 131static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
132 132
133static const struct dmi_system_id flip_dmi_table[] = {
134 {
135 .ident = "MSI MS-1034",
136 .matches = {
137 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
138 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
139 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
140 }
141 },
142 {
143 .ident = "MSI MS-1632",
144 .matches = {
145 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
146 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
147 }
148 },
149 {
150 .ident = "MSI MS-1635X",
151 .matches = {
152 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
153 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
154 }
155 },
156 {
157 .ident = "ASUSTeK W7J",
158 .matches = {
159 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
160 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
161 }
162 },
163 {}
164};
165
133static const struct ctrl sd_ctrls[] = { 166static const struct ctrl sd_ctrls[] = {
134 { 167 {
135#define BRIGHTNESS_IDX 0 168#define BRIGHTNESS_IDX 0
@@ -713,6 +746,7 @@ static u16 i2c_ident[] = {
713 V4L2_IDENT_MT9V112, 746 V4L2_IDENT_MT9V112,
714 V4L2_IDENT_MT9M001C12ST, 747 V4L2_IDENT_MT9M001C12ST,
715 V4L2_IDENT_MT9M111, 748 V4L2_IDENT_MT9M111,
749 V4L2_IDENT_MT9M112,
716 V4L2_IDENT_HV7131R, 750 V4L2_IDENT_HV7131R,
717}; 751};
718 752
@@ -735,7 +769,8 @@ static u16 bridge_init[][2] = {
735 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f}, 769 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
736 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f}, 770 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
737 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01}, 771 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
738 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80} 772 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
773 {0x1007, 0x00}
739}; 774};
740 775
741/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ 776/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
@@ -914,40 +949,30 @@ static struct i2c_reg_u8 ov9650_init[] = {
914}; 949};
915 950
916static struct i2c_reg_u8 ov9655_init[] = { 951static struct i2c_reg_u8 ov9655_init[] = {
917 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61}, 952 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
918 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24}, 953 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
919 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08}, 954 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
920 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf}, 955 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
921 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12}, 956 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
922 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, 957 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
923 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, 958 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
924 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, 959 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
925 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, 960 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
926 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04}, 961 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
927 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02}, 962 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
928 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c}, 963 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
929 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60}, 964 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
930 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04}, 965 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
931 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80}, 966 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
932 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf}, 967 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
933 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
934 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
935 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0}, 968 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
936 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61}, 969 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
970 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
937 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a}, 971 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
938 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01}, 972 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
939 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10}, 973 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
940 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04}, 974 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
941 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00}, 975 {0x04, 0x03}, {0x00, 0x13},
942 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
943 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
944 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
945 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
946 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
947 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
948 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
949 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
950 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
951}; 976};
952 977
953static struct i2c_reg_u16 mt9v112_init[] = { 978static struct i2c_reg_u16 mt9v112_init[] = {
@@ -971,29 +996,12 @@ static struct i2c_reg_u16 mt9v112_init[] = {
971 996
972static struct i2c_reg_u16 mt9v111_init[] = { 997static struct i2c_reg_u16 mt9v111_init[] = {
973 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, 998 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
974 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1}, 999 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
975 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002}, 1000 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
976 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03}, 1001 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
977 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c}, 1002 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
978 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064}, 1003 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
979 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480}, 1004 {0x0e, 0x0008}, {0x20, 0x0000}
980 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
981 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
982 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
983 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
984 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
985 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
986 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
987 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
988 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
989 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
990 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
991 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
992 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
993 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
994 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
995 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
996 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
997}; 1005};
998 1006
999static struct i2c_reg_u16 mt9v011_init[] = { 1007static struct i2c_reg_u16 mt9v011_init[] = {
@@ -1043,6 +1051,13 @@ static struct i2c_reg_u16 mt9m111_init[] = {
1043 {0xf0, 0x0000}, 1051 {0xf0, 0x0000},
1044}; 1052};
1045 1053
1054static struct i2c_reg_u16 mt9m112_init[] = {
1055 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1056 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1057 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1058 {0xf0, 0x0000},
1059};
1060
1046static struct i2c_reg_u8 hv7131r_init[] = { 1061static struct i2c_reg_u8 hv7131r_init[] = {
1047 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, 1062 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1048 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, 1063 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
@@ -1240,8 +1255,8 @@ static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1240 } 1255 }
1241 /* disable hflip and vflip */ 1256 /* disable hflip and vflip */
1242 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1257 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1243 sd->hstart = 0; 1258 sd->hstart = 1;
1244 sd->vstart = 7; 1259 sd->vstart = 2;
1245 return 0; 1260 return 0;
1246} 1261}
1247 1262
@@ -1337,6 +1352,7 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1337 return -ENODEV; 1352 return -ENODEV;
1338 } 1353 }
1339 } 1354 }
1355 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1340 sd->hstart = 2; 1356 sd->hstart = 2;
1341 sd->vstart = 2; 1357 sd->vstart = 2;
1342 sd->sensor = SENSOR_MT9V111; 1358 sd->sensor = SENSOR_MT9V111;
@@ -1369,6 +1385,23 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1369 return -ENODEV; 1385 return -ENODEV;
1370} 1386}
1371 1387
1388static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1389{
1390 struct sd *sd = (struct sd *) gspca_dev;
1391 int i;
1392 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1393 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1394 mt9m112_init[i].val) < 0) {
1395 err("MT9M112 sensor initialization failed");
1396 return -ENODEV;
1397 }
1398 }
1399 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1400 sd->hstart = 0;
1401 sd->vstart = 2;
1402 return 0;
1403}
1404
1372static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) 1405static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1373{ 1406{
1374 struct sd *sd = (struct sd *) gspca_dev; 1407 struct sd *sd = (struct sd *) gspca_dev;
@@ -1421,87 +1454,6 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1421 return 0; 1454 return 0;
1422} 1455}
1423 1456
1424#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1425static int input_kthread(void *data)
1426{
1427 struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
1428 struct sd *sd = (struct sd *) gspca_dev;
1429
1430 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait);
1431 set_freezable();
1432 for (;;) {
1433 if (kthread_should_stop())
1434 break;
1435
1436 if (reg_r(gspca_dev, 0x1005, 1) < 0)
1437 continue;
1438
1439 input_report_key(sd->input_dev,
1440 KEY_CAMERA,
1441 gspca_dev->usb_buf[0] & sd->input_gpio);
1442 input_sync(sd->input_dev);
1443
1444 wait_event_freezable_timeout(wait,
1445 kthread_should_stop(),
1446 msecs_to_jiffies(100));
1447 }
1448 return 0;
1449}
1450
1451
1452static int sn9c20x_input_init(struct gspca_dev *gspca_dev)
1453{
1454 struct sd *sd = (struct sd *) gspca_dev;
1455 if (sd->input_gpio == 0)
1456 return 0;
1457
1458 sd->input_dev = input_allocate_device();
1459 if (!sd->input_dev)
1460 return -ENOMEM;
1461
1462 sd->input_dev->name = "SN9C20X Webcam";
1463
1464 sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s",
1465 gspca_dev->dev->bus->bus_name,
1466 gspca_dev->dev->devpath);
1467
1468 if (!sd->input_dev->phys)
1469 return -ENOMEM;
1470
1471 usb_to_input_id(gspca_dev->dev, &sd->input_dev->id);
1472 sd->input_dev->dev.parent = &gspca_dev->dev->dev;
1473
1474 set_bit(EV_KEY, sd->input_dev->evbit);
1475 set_bit(KEY_CAMERA, sd->input_dev->keybit);
1476
1477 if (input_register_device(sd->input_dev))
1478 return -EINVAL;
1479
1480 sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s",
1481 gspca_dev->dev->bus->bus_name,
1482 gspca_dev->dev->devpath);
1483
1484 if (IS_ERR(sd->input_task))
1485 return -EINVAL;
1486
1487 return 0;
1488}
1489
1490static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev)
1491{
1492 struct sd *sd = (struct sd *) gspca_dev;
1493 if (sd->input_task != NULL && !IS_ERR(sd->input_task))
1494 kthread_stop(sd->input_task);
1495
1496 if (sd->input_dev != NULL) {
1497 input_unregister_device(sd->input_dev);
1498 kfree(sd->input_dev->phys);
1499 input_free_device(sd->input_dev);
1500 sd->input_dev = NULL;
1501 }
1502}
1503#endif
1504
1505static int set_cmatrix(struct gspca_dev *gspca_dev) 1457static int set_cmatrix(struct gspca_dev *gspca_dev)
1506{ 1458{
1507 struct sd *sd = (struct sd *) gspca_dev; 1459 struct sd *sd = (struct sd *) gspca_dev;
@@ -1579,17 +1531,26 @@ static int set_redblue(struct gspca_dev *gspca_dev)
1579 1531
1580static int set_hvflip(struct gspca_dev *gspca_dev) 1532static int set_hvflip(struct gspca_dev *gspca_dev)
1581{ 1533{
1582 u8 value, tslb; 1534 u8 value, tslb, hflip, vflip;
1583 u16 value2; 1535 u16 value2;
1584 struct sd *sd = (struct sd *) gspca_dev; 1536 struct sd *sd = (struct sd *) gspca_dev;
1537
1538 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1539 hflip = !sd->hflip;
1540 vflip = !sd->vflip;
1541 } else {
1542 hflip = sd->hflip;
1543 vflip = sd->vflip;
1544 }
1545
1585 switch (sd->sensor) { 1546 switch (sd->sensor) {
1586 case SENSOR_OV9650: 1547 case SENSOR_OV9650:
1587 i2c_r1(gspca_dev, 0x1e, &value); 1548 i2c_r1(gspca_dev, 0x1e, &value);
1588 value &= ~0x30; 1549 value &= ~0x30;
1589 tslb = 0x01; 1550 tslb = 0x01;
1590 if (sd->hflip) 1551 if (hflip)
1591 value |= 0x20; 1552 value |= 0x20;
1592 if (sd->vflip) { 1553 if (vflip) {
1593 value |= 0x10; 1554 value |= 0x10;
1594 tslb = 0x49; 1555 tslb = 0x49;
1595 } 1556 }
@@ -1600,28 +1561,29 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1600 case SENSOR_MT9V011: 1561 case SENSOR_MT9V011:
1601 i2c_r2(gspca_dev, 0x20, &value2); 1562 i2c_r2(gspca_dev, 0x20, &value2);
1602 value2 &= ~0xc0a0; 1563 value2 &= ~0xc0a0;
1603 if (sd->hflip) 1564 if (hflip)
1604 value2 |= 0x8080; 1565 value2 |= 0x8080;
1605 if (sd->vflip) 1566 if (vflip)
1606 value2 |= 0x4020; 1567 value2 |= 0x4020;
1607 i2c_w2(gspca_dev, 0x20, value2); 1568 i2c_w2(gspca_dev, 0x20, value2);
1608 break; 1569 break;
1570 case SENSOR_MT9M112:
1609 case SENSOR_MT9M111: 1571 case SENSOR_MT9M111:
1610 case SENSOR_MT9V112: 1572 case SENSOR_MT9V112:
1611 i2c_r2(gspca_dev, 0x20, &value2); 1573 i2c_r2(gspca_dev, 0x20, &value2);
1612 value2 &= ~0x0003; 1574 value2 &= ~0x0003;
1613 if (sd->hflip) 1575 if (hflip)
1614 value2 |= 0x0002; 1576 value2 |= 0x0002;
1615 if (sd->vflip) 1577 if (vflip)
1616 value2 |= 0x0001; 1578 value2 |= 0x0001;
1617 i2c_w2(gspca_dev, 0x20, value2); 1579 i2c_w2(gspca_dev, 0x20, value2);
1618 break; 1580 break;
1619 case SENSOR_HV7131R: 1581 case SENSOR_HV7131R:
1620 i2c_r1(gspca_dev, 0x01, &value); 1582 i2c_r1(gspca_dev, 0x01, &value);
1621 value &= ~0x03; 1583 value &= ~0x03;
1622 if (sd->vflip) 1584 if (vflip)
1623 value |= 0x01; 1585 value |= 0x01;
1624 if (sd->hflip) 1586 if (hflip)
1625 value |= 0x02; 1587 value |= 0x02;
1626 i2c_w1(gspca_dev, 0x01, value); 1588 i2c_w1(gspca_dev, 0x01, value);
1627 break; 1589 break;
@@ -1645,7 +1607,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1645 break; 1607 break;
1646 case SENSOR_MT9M001: 1608 case SENSOR_MT9M001:
1647 case SENSOR_MT9V112: 1609 case SENSOR_MT9V112:
1648 case SENSOR_MT9V111:
1649 case SENSOR_MT9V011: 1610 case SENSOR_MT9V011:
1650 exp[0] |= (3 << 4); 1611 exp[0] |= (3 << 4);
1651 exp[2] = 0x09; 1612 exp[2] = 0x09;
@@ -1655,9 +1616,9 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1655 case SENSOR_HV7131R: 1616 case SENSOR_HV7131R:
1656 exp[0] |= (4 << 4); 1617 exp[0] |= (4 << 4);
1657 exp[2] = 0x25; 1618 exp[2] = 0x25;
1658 exp[3] = ((sd->exposure * 0xffffff) / 0xffff) >> 16; 1619 exp[3] = (sd->exposure >> 5) & 0xff;
1659 exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8; 1620 exp[4] = (sd->exposure << 3) & 0xff;
1660 exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff; 1621 exp[5] = 0;
1661 break; 1622 break;
1662 default: 1623 default:
1663 return 0; 1624 return 0;
@@ -1680,7 +1641,6 @@ static int set_gain(struct gspca_dev *gspca_dev)
1680 gain[3] = ov_gain[sd->gain]; 1641 gain[3] = ov_gain[sd->gain];
1681 break; 1642 break;
1682 case SENSOR_MT9V011: 1643 case SENSOR_MT9V011:
1683 case SENSOR_MT9V111:
1684 gain[0] |= (3 << 4); 1644 gain[0] |= (3 << 4);
1685 gain[2] = 0x35; 1645 gain[2] = 0x35;
1686 gain[3] = micron1_gain[sd->gain] >> 8; 1646 gain[3] = micron1_gain[sd->gain] >> 8;
@@ -1931,7 +1891,7 @@ static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1931 if (reg->match.addr != sd->i2c_addr) 1891 if (reg->match.addr != sd->i2c_addr)
1932 return -EINVAL; 1892 return -EINVAL;
1933 if (sd->sensor >= SENSOR_MT9V011 && 1893 if (sd->sensor >= SENSOR_MT9V011 &&
1934 sd->sensor <= SENSOR_MT9M111) { 1894 sd->sensor <= SENSOR_MT9M112) {
1935 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0) 1895 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0)
1936 return -EINVAL; 1896 return -EINVAL;
1937 } else { 1897 } else {
@@ -1960,7 +1920,7 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1960 if (reg->match.addr != sd->i2c_addr) 1920 if (reg->match.addr != sd->i2c_addr)
1961 return -EINVAL; 1921 return -EINVAL;
1962 if (sd->sensor >= SENSOR_MT9V011 && 1922 if (sd->sensor >= SENSOR_MT9V011 &&
1963 sd->sensor <= SENSOR_MT9M111) { 1923 sd->sensor <= SENSOR_MT9M112) {
1964 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0) 1924 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1965 return -EINVAL; 1925 return -EINVAL;
1966 } else { 1926 } else {
@@ -2005,8 +1965,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
2005 1965
2006 sd->sensor = (id->driver_info >> 8) & 0xff; 1966 sd->sensor = (id->driver_info >> 8) & 0xff;
2007 sd->i2c_addr = id->driver_info & 0xff; 1967 sd->i2c_addr = id->driver_info & 0xff;
1968 sd->flags = (id->driver_info >> 16) & 0xff;
2008 1969
2009 switch (sd->sensor) { 1970 switch (sd->sensor) {
1971 case SENSOR_MT9M112:
2010 case SENSOR_MT9M111: 1972 case SENSOR_MT9M111:
2011 case SENSOR_OV9650: 1973 case SENSOR_OV9650:
2012 case SENSOR_SOI968: 1974 case SENSOR_SOI968:
@@ -2039,11 +2001,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
2039 2001
2040 sd->quality = 95; 2002 sd->quality = 95;
2041 2003
2042#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2043 sd->input_gpio = (id->driver_info >> 16) & 0xff;
2044 if (sn9c20x_input_init(gspca_dev) < 0)
2045 return -ENODEV;
2046#endif
2047 return 0; 2004 return 0;
2048} 2005}
2049 2006
@@ -2063,6 +2020,11 @@ static int sd_init(struct gspca_dev *gspca_dev)
2063 } 2020 }
2064 } 2021 }
2065 2022
2023 if (sd->flags & LED_REVERSE)
2024 reg_w1(gspca_dev, 0x1006, 0x00);
2025 else
2026 reg_w1(gspca_dev, 0x1006, 0x20);
2027
2066 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) { 2028 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2067 err("Device initialization failed"); 2029 err("Device initialization failed");
2068 return -ENODEV; 2030 return -ENODEV;
@@ -2103,6 +2065,11 @@ static int sd_init(struct gspca_dev *gspca_dev)
2103 return -ENODEV; 2065 return -ENODEV;
2104 info("MT9M111 sensor detected"); 2066 info("MT9M111 sensor detected");
2105 break; 2067 break;
2068 case SENSOR_MT9M112:
2069 if (mt9m112_init_sensor(gspca_dev) < 0)
2070 return -ENODEV;
2071 info("MT9M112 sensor detected");
2072 break;
2106 case SENSOR_MT9M001: 2073 case SENSOR_MT9M001:
2107 if (mt9m001_init_sensor(gspca_dev) < 0) 2074 if (mt9m001_init_sensor(gspca_dev) < 0)
2108 return -ENODEV; 2075 return -ENODEV;
@@ -2162,6 +2129,7 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2162 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); 2129 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2163 } 2130 }
2164 break; 2131 break;
2132 case SENSOR_MT9M112:
2165 case SENSOR_MT9M111: 2133 case SENSOR_MT9M111:
2166 if (mode & MODE_SXGA) { 2134 if (mode & MODE_SXGA) {
2167 i2c_w2(gspca_dev, 0xf0, 0x0002); 2135 i2c_w2(gspca_dev, 0xf0, 0x0002);
@@ -2243,6 +2211,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
2243 set_exposure(gspca_dev); 2211 set_exposure(gspca_dev);
2244 set_hvflip(gspca_dev); 2212 set_hvflip(gspca_dev);
2245 2213
2214 reg_w1(gspca_dev, 0x1007, 0x20);
2215
2246 reg_r(gspca_dev, 0x1061, 1); 2216 reg_r(gspca_dev, 0x1061, 1);
2247 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02); 2217 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2248 return 0; 2218 return 0;
@@ -2250,6 +2220,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
2250 2220
2251static void sd_stopN(struct gspca_dev *gspca_dev) 2221static void sd_stopN(struct gspca_dev *gspca_dev)
2252{ 2222{
2223 reg_w1(gspca_dev, 0x1007, 0x00);
2224
2253 reg_r(gspca_dev, 0x1061, 1); 2225 reg_r(gspca_dev, 0x1061, 1);
2254 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02); 2226 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2255} 2227}
@@ -2343,6 +2315,24 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2343 do_autoexposure(gspca_dev, avg_lum); 2315 do_autoexposure(gspca_dev, avg_lum);
2344} 2316}
2345 2317
2318#ifdef CONFIG_INPUT
2319static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2320 u8 *data, /* interrupt packet */
2321 int len) /* interrupt packet length */
2322{
2323 struct sd *sd = (struct sd *) gspca_dev;
2324 int ret = -EINVAL;
2325 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2326 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2327 input_sync(gspca_dev->input_dev);
2328 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2329 input_sync(gspca_dev->input_dev);
2330 ret = 0;
2331 }
2332 return ret;
2333}
2334#endif
2335
2346static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2336static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2347 u8 *data, /* isoc packet */ 2337 u8 *data, /* isoc packet */
2348 int len) /* iso packet length */ 2338 int len) /* iso packet length */
@@ -2409,6 +2399,9 @@ static const struct sd_desc sd_desc = {
2409 .stopN = sd_stopN, 2399 .stopN = sd_stopN,
2410 .stop0 = sd_stop0, 2400 .stop0 = sd_stop0,
2411 .pkt_scan = sd_pkt_scan, 2401 .pkt_scan = sd_pkt_scan,
2402#ifdef CONFIG_INPUT
2403 .int_pkt_scan = sd_int_pkt_scan,
2404#endif
2412 .dq_callback = sd_dqcallback, 2405 .dq_callback = sd_dqcallback,
2413#ifdef CONFIG_VIDEO_ADV_DEBUG 2406#ifdef CONFIG_VIDEO_ADV_DEBUG
2414 .set_register = sd_dbg_s_register, 2407 .set_register = sd_dbg_s_register,
@@ -2417,8 +2410,8 @@ static const struct sd_desc sd_desc = {
2417 .get_chip_ident = sd_chip_ident, 2410 .get_chip_ident = sd_chip_ident,
2418}; 2411};
2419 2412
2420#define SN9C20X(sensor, i2c_addr, button_mask) \ 2413#define SN9C20X(sensor, i2c_addr, flags) \
2421 .driver_info = (button_mask << 16) \ 2414 .driver_info = ((flags & 0xff) << 16) \
2422 | (SENSOR_ ## sensor << 8) \ 2415 | (SENSOR_ ## sensor << 8) \
2423 | (i2c_addr) 2416 | (i2c_addr)
2424 2417
@@ -2426,8 +2419,10 @@ static const __devinitdata struct usb_device_id device_table[] = {
2426 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, 2419 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2427 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, 2420 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2428 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, 2421 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2429 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)}, 2422 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2430 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, 2423 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2424 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2425 (FLIP_DETECT | HAS_NO_BUTTON))},
2431 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, 2426 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2432 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2427 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2433 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2428 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
@@ -2438,6 +2433,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2438 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2433 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2439 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, 2434 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2440 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, 2435 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2436 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2441 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, 2437 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2442 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, 2438 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2443 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2439 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
@@ -2448,6 +2444,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
2448 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2444 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2449 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2445 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2450 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, 2446 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2447 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2448 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2451 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, 2449 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2452 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, 2450 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2453 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, 2451 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
@@ -2467,22 +2465,11 @@ static int sd_probe(struct usb_interface *intf,
2467 THIS_MODULE); 2465 THIS_MODULE);
2468} 2466}
2469 2467
2470static void sd_disconnect(struct usb_interface *intf)
2471{
2472#ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2473 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2474
2475 sn9c20x_input_cleanup(gspca_dev);
2476#endif
2477
2478 gspca_disconnect(intf);
2479}
2480
2481static struct usb_driver sd_driver = { 2468static struct usb_driver sd_driver = {
2482 .name = MODULE_NAME, 2469 .name = MODULE_NAME,
2483 .id_table = device_table, 2470 .id_table = device_table,
2484 .probe = sd_probe, 2471 .probe = sd_probe,
2485 .disconnect = sd_disconnect, 2472 .disconnect = gspca_disconnect,
2486#ifdef CONFIG_PM 2473#ifdef CONFIG_PM
2487 .suspend = gspca_suspend, 2474 .suspend = gspca_suspend,
2488 .resume = gspca_resume, 2475 .resume = gspca_resume,
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 1d61b92f6bfc..bb923efb75bd 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver 2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3 * 3 *
4 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr 5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,7 @@
28 28
29#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) 29#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
30 30
31MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 31MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
32MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 32MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
33MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
34 34
@@ -67,20 +67,25 @@ struct sd {
67#define BRIDGE_SN9C110 2 67#define BRIDGE_SN9C110 2
68#define BRIDGE_SN9C120 3 68#define BRIDGE_SN9C120 3
69 u8 sensor; /* Type of image sensor chip */ 69 u8 sensor; /* Type of image sensor chip */
70#define SENSOR_ADCM1700 0 70enum {
71#define SENSOR_HV7131R 1 71 SENSOR_ADCM1700,
72#define SENSOR_MI0360 2 72 SENSOR_GC0307,
73#define SENSOR_MO4000 3 73 SENSOR_HV7131R,
74#define SENSOR_MT9V111 4 74 SENSOR_MI0360,
75#define SENSOR_OM6802 5 75 SENSOR_MO4000,
76#define SENSOR_OV7630 6 76 SENSOR_MT9V111,
77#define SENSOR_OV7648 7 77 SENSOR_OM6802,
78#define SENSOR_OV7660 8 78 SENSOR_OV7630,
79#define SENSOR_PO1030 9 79 SENSOR_OV7648,
80#define SENSOR_SP80708 10 80 SENSOR_OV7660,
81 SENSOR_PO1030,
82 SENSOR_PO2030N,
83 SENSOR_SOI768,
84 SENSOR_SP80708,
85} sensors;
81 u8 i2c_addr; 86 u8 i2c_addr;
82 87
83 u8 *jpeg_hdr; 88 u8 jpeg_hdr[JPEG_HDR_SZ];
84}; 89};
85 90
86/* V4L2 controls supported by the driver */ 91/* V4L2 controls supported by the driver */
@@ -281,29 +286,60 @@ static const struct ctrl sd_ctrls[] = {
281}; 286};
282 287
283/* table of the disabled controls */ 288/* table of the disabled controls */
284static __u32 ctrl_dis[] = { 289static const __u32 ctrl_dis[] = {
285 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) | 290[SENSOR_ADCM1700] = (1 << AUTOGAIN_IDX) |
286 (1 << AUTOGAIN_IDX), /* SENSOR_ADCM1700 0 */ 291 (1 << INFRARED_IDX) |
287 (1 << INFRARED_IDX) | (1 << FREQ_IDX), 292 (1 << VFLIP_IDX) |
288 /* SENSOR_HV7131R 1 */ 293 (1 << FREQ_IDX),
289 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 294
290 /* SENSOR_MI0360 2 */ 295[SENSOR_GC0307] = (1 << INFRARED_IDX) |
291 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 296 (1 << VFLIP_IDX) |
292 /* SENSOR_MO4000 3 */ 297 (1 << FREQ_IDX),
293 (1 << VFLIP_IDX) | (1 << FREQ_IDX), 298
294 /* SENSOR_MT9V111 4 */ 299[SENSOR_HV7131R] = (1 << INFRARED_IDX) |
295 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), 300 (1 << FREQ_IDX),
296 /* SENSOR_OM6802 5 */ 301
297 (1 << INFRARED_IDX), 302[SENSOR_MI0360] = (1 << INFRARED_IDX) |
298 /* SENSOR_OV7630 6 */ 303 (1 << VFLIP_IDX) |
299 (1 << INFRARED_IDX), 304 (1 << FREQ_IDX),
300 /* SENSOR_OV7648 7 */ 305
301 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), 306[SENSOR_MO4000] = (1 << INFRARED_IDX) |
302 /* SENSOR_OV7660 8 */ 307 (1 << VFLIP_IDX) |
303 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 308 (1 << FREQ_IDX),
304 (1 << FREQ_IDX), /* SENSOR_PO1030 9 */ 309
305 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | 310[SENSOR_MT9V111] = (1 << VFLIP_IDX) |
306 (1 << FREQ_IDX), /* SENSOR_SP80708 10 */ 311 (1 << FREQ_IDX),
312
313[SENSOR_OM6802] = (1 << INFRARED_IDX) |
314 (1 << VFLIP_IDX) |
315 (1 << FREQ_IDX),
316
317[SENSOR_OV7630] = (1 << INFRARED_IDX),
318
319[SENSOR_OV7648] = (1 << INFRARED_IDX),
320
321[SENSOR_OV7660] = (1 << AUTOGAIN_IDX) |
322 (1 << INFRARED_IDX) |
323 (1 << VFLIP_IDX),
324
325[SENSOR_PO1030] = (1 << AUTOGAIN_IDX) |
326 (1 << INFRARED_IDX) |
327 (1 << VFLIP_IDX) |
328 (1 << FREQ_IDX),
329
330[SENSOR_PO2030N] = (1 << AUTOGAIN_IDX) |
331 (1 << INFRARED_IDX) |
332 (1 << VFLIP_IDX) |
333 (1 << FREQ_IDX),
334[SENSOR_SOI768] = (1 << AUTOGAIN_IDX) |
335 (1 << INFRARED_IDX) |
336 (1 << VFLIP_IDX) |
337 (1 << FREQ_IDX),
338
339[SENSOR_SP80708] = (1 << AUTOGAIN_IDX) |
340 (1 << INFRARED_IDX) |
341 (1 << VFLIP_IDX) |
342 (1 << FREQ_IDX),
307}; 343};
308 344
309static const struct v4l2_pix_format cif_mode[] = { 345static const struct v4l2_pix_format cif_mode[] = {
@@ -343,7 +379,17 @@ static const u8 sn_adcm1700[0x1c] = {
343 0x06, 0x00, 0x00, 0x00 379 0x06, 0x00, 0x00, 0x00
344}; 380};
345 381
346/*Data from sn9c102p+hv7131r */ 382static const u8 sn_gc0307[0x1c] = {
383/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
384 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
385/* reg8 reg9 rega regb regc regd rege regf */
386 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
388 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
389/* reg18 reg19 reg1a reg1b */
390 0x06, 0x00, 0x00, 0x00
391};
392
347static const u8 sn_hv7131[0x1c] = { 393static const u8 sn_hv7131[0x1c] = {
348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 394/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, 395 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -401,7 +447,7 @@ static const u8 sn_om6802[0x1c] = {
401 447
402static const u8 sn_ov7630[0x1c] = { 448static const u8 sn_ov7630[0x1c] = {
403/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 449/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
404 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, 450 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
405/* reg8 reg9 rega regb regc regd rege regf */ 451/* reg8 reg9 rega regb regc regd rege regf */
406 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 452 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 453/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
@@ -443,6 +489,28 @@ static const u8 sn_po1030[0x1c] = {
443 0x07, 0x00, 0x00, 0x00 489 0x07, 0x00, 0x00, 0x00
444}; 490};
445 491
492static const u8 sn_po2030n[0x1c] = {
493/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
494 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
495/* reg8 reg9 rega regb regc regd rege regf */
496 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
498 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
499/* reg18 reg19 reg1a reg1b */
500 0x07, 0x00, 0x00, 0x00
501};
502
503static const u8 sn_soi768[0x1c] = {
504/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
505 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
506/* reg8 reg9 rega regb regc regd rege regf */
507 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
509 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
510/* reg18 reg19 reg1a reg1b */
511 0x07, 0x00, 0x00, 0x00
512};
513
446static const u8 sn_sp80708[0x1c] = { 514static const u8 sn_sp80708[0x1c] = {
447/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 515/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
448 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, 516 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -456,17 +524,20 @@ static const u8 sn_sp80708[0x1c] = {
456 524
457/* sequence specific to the sensors - !! index = SENSOR_xxx */ 525/* sequence specific to the sensors - !! index = SENSOR_xxx */
458static const u8 *sn_tb[] = { 526static const u8 *sn_tb[] = {
459 sn_adcm1700, 527[SENSOR_ADCM1700] = sn_adcm1700,
460 sn_hv7131, 528[SENSOR_GC0307] = sn_gc0307,
461 sn_mi0360, 529[SENSOR_HV7131R] = sn_hv7131,
462 sn_mo4000, 530[SENSOR_MI0360] = sn_mi0360,
463 sn_mt9v111, 531[SENSOR_MO4000] = sn_mo4000,
464 sn_om6802, 532[SENSOR_MT9V111] = sn_mt9v111,
465 sn_ov7630, 533[SENSOR_OM6802] = sn_om6802,
466 sn_ov7648, 534[SENSOR_OV7630] = sn_ov7630,
467 sn_ov7660, 535[SENSOR_OV7648] = sn_ov7648,
468 sn_po1030, 536[SENSOR_OV7660] = sn_ov7660,
469 sn_sp80708 537[SENSOR_PO1030] = sn_po1030,
538[SENSOR_PO2030N] = sn_po2030n,
539[SENSOR_SOI768] = sn_soi768,
540[SENSOR_SP80708] = sn_sp80708,
470}; 541};
471 542
472/* default gamma table */ 543/* default gamma table */
@@ -484,8 +555,13 @@ static const u8 gamma_spec_1[17] = {
484 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, 555 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
485 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 556 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
486}; 557};
487/* gamma for sensor SP80708 */ 558/* gamma for sensor GC0307 */
488static const u8 gamma_spec_2[17] = { 559static const u8 gamma_spec_2[17] = {
560 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
561 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
562};
563/* gamma for sensor SP80708 */
564static const u8 gamma_spec_3[17] = {
489 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab, 565 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
490 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6 566 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
491}; 567};
@@ -533,6 +609,58 @@ static const u8 adcm1700_sensor_param1[][8] = {
533 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10}, 609 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
534 {} 610 {}
535}; 611};
612static const u8 gc0307_sensor_init[][8] = {
613 {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
614 {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
615 {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
616 {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
617 {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
618 {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
619 {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
620 {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
621 {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
622 {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
623 {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
624 {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
625 {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
626 {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
627 {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
628 {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
629 {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
630 {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
631 {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
632 {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
633 {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
634 {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
636 {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
637 {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
638 {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
639 {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
640 {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
641 {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
642 {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
643 {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
644 {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
645 {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
646 {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
647 {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
648 {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
649 {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
650 {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
651 {}
652};
653static const u8 gc0307_sensor_param1[][8] = {
654 {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
655 {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
656 {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
657 {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
658/*param3*/
659 {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
660 {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
661 {}
662};
663
536static const u8 hv7131r_sensor_init[][8] = { 664static const u8 hv7131r_sensor_init[][8] = {
537 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 665 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
538 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, 666 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
@@ -767,7 +895,9 @@ static const u8 ov7630_sensor_init[][8] = {
767 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10}, 895 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
768 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, 896 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
769 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, 897 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
770/* */ 898 {}
899};
900static const u8 ov7630_sensor_param1[][8] = {
771 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 901 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 902 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
773/*fixme: + 0x12, 0x04*/ 903/*fixme: + 0x12, 0x04*/
@@ -984,6 +1114,113 @@ static const u8 po1030_sensor_param1[][8] = {
984 {} 1114 {}
985}; 1115};
986 1116
1117static const u8 po2030n_sensor_init[][8] = {
1118 {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1119 {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1120 {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1121 {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1122 {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1123 {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1124 {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1125 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1126 {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1127 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1128 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1129 {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1130 {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1131 {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1132 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1133 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1134 {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1135 {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1136 {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1137 {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1138 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1139 {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1140 {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1141 {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1142 {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1143 {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1144 {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1145 {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1146 {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1147 {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1148 {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1149 {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1150 {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1151 {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1152 {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1153 {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1154 {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1155 {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1156 {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1157 {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1158 {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1159 {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1160 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1161 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1162 {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1163 {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1164 {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1165 {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1166 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1167 {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1168 {}
1169};
1170static const u8 po2030n_sensor_param1[][8] = {
1171 {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1172 {0xdd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1173 {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1174 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1175 {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1176/*param2*/
1177 {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1178 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1179 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1180 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1181 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1182 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1183 {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1184/*after start*/
1185 {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1186 {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1187 {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1188 {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1189 {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1190 {}
1191};
1192
1193static const u8 soi768_sensor_init[][8] = {
1194 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1195 {0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1196 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1197 {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1198 {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1199 {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1200 {}
1201};
1202static const u8 soi768_sensor_param1[][8] = {
1203 {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1204 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1205 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1206 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1207 {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1208/* */
1209/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1210/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1211 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1212/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1213 {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1214/* the next sequence should be used for auto gain */
1215 {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1216 /* global gain ? : 07 - change with 0x15 at the end */
1217 {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1218 {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1219 {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1220 /* exposure ? : 0200 - change with 0x1e at the end */
1221 {}
1222};
1223
987static const u8 sp80708_sensor_init[][8] = { 1224static const u8 sp80708_sensor_init[][8] = {
988 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, 1225 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
989 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, 1226 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
@@ -1069,18 +1306,21 @@ static const u8 sp80708_sensor_param1[][8] = {
1069 {} 1306 {}
1070}; 1307};
1071 1308
1072static const u8 (*sensor_init[11])[8] = { 1309static const u8 (*sensor_init[])[8] = {
1073 adcm1700_sensor_init, /* ADCM1700 0 */ 1310[SENSOR_ADCM1700] = adcm1700_sensor_init,
1074 hv7131r_sensor_init, /* HV7131R 1 */ 1311[SENSOR_GC0307] = gc0307_sensor_init,
1075 mi0360_sensor_init, /* MI0360 2 */ 1312[SENSOR_HV7131R] = hv7131r_sensor_init,
1076 mo4000_sensor_init, /* MO4000 3 */ 1313[SENSOR_MI0360] = mi0360_sensor_init,
1077 mt9v111_sensor_init, /* MT9V111 4 */ 1314[SENSOR_MO4000] = mo4000_sensor_init,
1078 om6802_sensor_init, /* OM6802 5 */ 1315[SENSOR_MT9V111] = mt9v111_sensor_init,
1079 ov7630_sensor_init, /* OV7630 6 */ 1316[SENSOR_OM6802] = om6802_sensor_init,
1080 ov7648_sensor_init, /* OV7648 7 */ 1317[SENSOR_OV7630] = ov7630_sensor_init,
1081 ov7660_sensor_init, /* OV7660 8 */ 1318[SENSOR_OV7648] = ov7648_sensor_init,
1082 po1030_sensor_init, /* PO1030 9 */ 1319[SENSOR_OV7660] = ov7660_sensor_init,
1083 sp80708_sensor_init, /* SP80708 10 */ 1320[SENSOR_PO1030] = po1030_sensor_init,
1321[SENSOR_PO2030N] = po2030n_sensor_init,
1322[SENSOR_SOI768] = soi768_sensor_init,
1323[SENSOR_SP80708] = sp80708_sensor_init,
1084}; 1324};
1085 1325
1086/* read <len> bytes to gspca_dev->usb_buf */ 1326/* read <len> bytes to gspca_dev->usb_buf */
@@ -1146,10 +1386,11 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1146{ 1386{
1147 struct sd *sd = (struct sd *) gspca_dev; 1387 struct sd *sd = (struct sd *) gspca_dev;
1148 1388
1149 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); 1389 PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
1150 switch (sd->sensor) { 1390 switch (sd->sensor) {
1151 case SENSOR_ADCM1700: 1391 case SENSOR_ADCM1700:
1152 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */ 1392 case SENSOR_OM6802:
1393 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
1153 gspca_dev->usb_buf[0] = 0x80 | (2 << 4); 1394 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1154 break; 1395 break;
1155 default: /* i2c command = a1 (400 kHz) */ 1396 default: /* i2c command = a1 (400 kHz) */
@@ -1177,6 +1418,8 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1177static void i2c_w8(struct gspca_dev *gspca_dev, 1418static void i2c_w8(struct gspca_dev *gspca_dev,
1178 const u8 *buffer) 1419 const u8 *buffer)
1179{ 1420{
1421 PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1422 buffer[2], buffer[3]);
1180 memcpy(gspca_dev->usb_buf, buffer, 8); 1423 memcpy(gspca_dev->usb_buf, buffer, 8);
1181 usb_control_msg(gspca_dev->dev, 1424 usb_control_msg(gspca_dev->dev,
1182 usb_sndctrlpipe(gspca_dev->dev, 0), 1425 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -1196,7 +1439,8 @@ static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1196 1439
1197 switch (sd->sensor) { 1440 switch (sd->sensor) {
1198 case SENSOR_ADCM1700: 1441 case SENSOR_ADCM1700:
1199 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */ 1442 case SENSOR_OM6802:
1443 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
1200 mode[0] = 0x80 | 0x10; 1444 mode[0] = 0x80 | 0x10;
1201 break; 1445 break;
1202 default: /* i2c command = 91 (400 kHz) */ 1446 default: /* i2c command = 91 (400 kHz) */
@@ -1300,39 +1544,100 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
1300 } 1544 }
1301} 1545}
1302 1546
1303static void ov7648_probe(struct gspca_dev *gspca_dev) 1547static void ov7630_probe(struct gspca_dev *gspca_dev)
1304{ 1548{
1305 struct sd *sd = (struct sd *) gspca_dev; 1549 struct sd *sd = (struct sd *) gspca_dev;
1550 u16 val;
1306 1551
1307 /* check ov76xx */ 1552 /* check ov76xx */
1308 reg_w1(gspca_dev, 0x17, 0x62); 1553 reg_w1(gspca_dev, 0x17, 0x62);
1309 reg_w1(gspca_dev, 0x01, 0x08); 1554 reg_w1(gspca_dev, 0x01, 0x08);
1310 sd->i2c_addr = 0x21; 1555 sd->i2c_addr = 0x21;
1311 i2c_r(gspca_dev, 0x0a, 2); 1556 i2c_r(gspca_dev, 0x0a, 2);
1312 if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */ 1557 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1313 PDEBUG(D_PROBE, "Sensor ov%02x%02x", 1558 reg_w1(gspca_dev, 0x01, 0x29);
1314 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]); 1559 reg_w1(gspca_dev, 0x17, 0x42);
1560 if (val == 0x7628) { /* soi768 */
1561 sd->sensor = SENSOR_SOI768;
1562/*fixme: only valid for 0c45:613e?*/
1563 gspca_dev->cam.input_flags =
1564 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1565 PDEBUG(D_PROBE, "Sensor soi768");
1315 return; 1566 return;
1316 } 1567 }
1568 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1569}
1317 1570
1318 /* reset */ 1571static void ov7648_probe(struct gspca_dev *gspca_dev)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 u16 val;
1575
1576 /* check ov76xx */
1577 reg_w1(gspca_dev, 0x17, 0x62);
1578 reg_w1(gspca_dev, 0x01, 0x08);
1579 sd->i2c_addr = 0x21;
1580 i2c_r(gspca_dev, 0x0a, 2);
1581 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1319 reg_w1(gspca_dev, 0x01, 0x29); 1582 reg_w1(gspca_dev, 0x01, 0x29);
1320 reg_w1(gspca_dev, 0x17, 0x42); 1583 reg_w1(gspca_dev, 0x17, 0x42);
1584 if ((val & 0xff00) == 0x7600) { /* ov76xx */
1585 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1586 return;
1587 }
1321 1588
1322 /* check po1030 */ 1589 /* check po1030 */
1323 reg_w1(gspca_dev, 0x17, 0x62); 1590 reg_w1(gspca_dev, 0x17, 0x62);
1324 reg_w1(gspca_dev, 0x01, 0x08); 1591 reg_w1(gspca_dev, 0x01, 0x08);
1325 sd->i2c_addr = 0x6e; 1592 sd->i2c_addr = 0x6e;
1326 i2c_r(gspca_dev, 0x00, 2); 1593 i2c_r(gspca_dev, 0x00, 2);
1327 if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */ 1594 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1328 && gspca_dev->usb_buf[4] == 0x30) { 1595 reg_w1(gspca_dev, 0x01, 0x29);
1596 reg_w1(gspca_dev, 0x17, 0x42);
1597 if (val == 0x1030) { /* po1030 */
1329 PDEBUG(D_PROBE, "Sensor po1030"); 1598 PDEBUG(D_PROBE, "Sensor po1030");
1330 sd->sensor = SENSOR_PO1030; 1599 sd->sensor = SENSOR_PO1030;
1331 return; 1600 return;
1332 } 1601 }
1333 1602
1334 PDEBUG(D_PROBE, "Unknown sensor %02x%02x", 1603 PDEBUG(D_PROBE, "Unknown sensor %04x", val);
1335 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]); 1604}
1605
1606/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1607static void po2030n_probe(struct gspca_dev *gspca_dev)
1608{
1609 struct sd *sd = (struct sd *) gspca_dev;
1610 u16 val;
1611
1612 /* check gc0307 */
1613 reg_w1(gspca_dev, 0x17, 0x62);
1614 reg_w1(gspca_dev, 0x01, 0x08);
1615 reg_w1(gspca_dev, 0x02, 0x22);
1616 sd->i2c_addr = 0x21;
1617 i2c_r(gspca_dev, 0x00, 1);
1618 val = gspca_dev->usb_buf[4];
1619 reg_w1(gspca_dev, 0x01, 0x29); /* reset */
1620 reg_w1(gspca_dev, 0x17, 0x42);
1621 if (val == 0x99) { /* gc0307 (?) */
1622 PDEBUG(D_PROBE, "Sensor gc0307");
1623 sd->sensor = SENSOR_GC0307;
1624 return;
1625 }
1626
1627 /* check po2030n */
1628 reg_w1(gspca_dev, 0x17, 0x62);
1629 reg_w1(gspca_dev, 0x01, 0x0a);
1630 sd->i2c_addr = 0x6e;
1631 i2c_r(gspca_dev, 0x00, 2);
1632 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1633 reg_w1(gspca_dev, 0x01, 0x29);
1634 reg_w1(gspca_dev, 0x17, 0x42);
1635 if (val == 0x2030) {
1636 PDEBUG(D_PROBE, "Sensor po2030n");
1637/* sd->sensor = SENSOR_PO2030N; */
1638 } else {
1639 PDEBUG(D_PROBE, "Unknown sensor ID %04x", val);
1640 }
1336} 1641}
1337 1642
1338static void bridge_init(struct gspca_dev *gspca_dev, 1643static void bridge_init(struct gspca_dev *gspca_dev,
@@ -1355,8 +1660,11 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1355 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); 1660 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1356 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); 1661 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
1357 switch (sd->sensor) { 1662 switch (sd->sensor) {
1663 case SENSOR_GC0307:
1358 case SENSOR_OV7660: 1664 case SENSOR_OV7660:
1359 case SENSOR_PO1030: 1665 case SENSOR_PO1030:
1666 case SENSOR_PO2030N:
1667 case SENSOR_SOI768:
1360 case SENSOR_SP80708: 1668 case SENSOR_SP80708:
1361 reg9a = reg9a_spec; 1669 reg9a = reg9a_spec;
1362 break; 1670 break;
@@ -1377,6 +1685,14 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1377 reg_w1(gspca_dev, 0x01, 0x42); 1685 reg_w1(gspca_dev, 0x01, 0x42);
1378 reg_w1(gspca_dev, 0x01, 0x42); 1686 reg_w1(gspca_dev, 0x01, 0x42);
1379 break; 1687 break;
1688 case SENSOR_GC0307:
1689 msleep(50);
1690 reg_w1(gspca_dev, 0x01, 0x61);
1691 reg_w1(gspca_dev, 0x17, 0x22);
1692 reg_w1(gspca_dev, 0x01, 0x60);
1693 reg_w1(gspca_dev, 0x01, 0x40);
1694 msleep(50);
1695 break;
1380 case SENSOR_MT9V111: 1696 case SENSOR_MT9V111:
1381 reg_w1(gspca_dev, 0x01, 0x61); 1697 reg_w1(gspca_dev, 0x01, 0x61);
1382 reg_w1(gspca_dev, 0x17, 0x61); 1698 reg_w1(gspca_dev, 0x17, 0x61);
@@ -1414,11 +1730,18 @@ static void bridge_init(struct gspca_dev *gspca_dev,
1414 reg_w1(gspca_dev, 0x01, 0x42); 1730 reg_w1(gspca_dev, 0x01, 0x42);
1415 break; 1731 break;
1416 case SENSOR_PO1030: 1732 case SENSOR_PO1030:
1733 case SENSOR_SOI768:
1417 reg_w1(gspca_dev, 0x01, 0x61); 1734 reg_w1(gspca_dev, 0x01, 0x61);
1418 reg_w1(gspca_dev, 0x17, 0x20); 1735 reg_w1(gspca_dev, 0x17, 0x20);
1419 reg_w1(gspca_dev, 0x01, 0x60); 1736 reg_w1(gspca_dev, 0x01, 0x60);
1420 reg_w1(gspca_dev, 0x01, 0x40); 1737 reg_w1(gspca_dev, 0x01, 0x40);
1421 break; 1738 break;
1739 case SENSOR_PO2030N:
1740 reg_w1(gspca_dev, 0x01, 0x63);
1741 reg_w1(gspca_dev, 0x17, 0x20);
1742 reg_w1(gspca_dev, 0x01, 0x62);
1743 reg_w1(gspca_dev, 0x01, 0x42);
1744 break;
1422 case SENSOR_OV7660: 1745 case SENSOR_OV7660:
1423 /* fall thru */ 1746 /* fall thru */
1424 case SENSOR_SP80708: 1747 case SENSOR_SP80708:
@@ -1523,9 +1846,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
1523 case SENSOR_MI0360: 1846 case SENSOR_MI0360:
1524 mi0360_probe(gspca_dev); 1847 mi0360_probe(gspca_dev);
1525 break; 1848 break;
1849 case SENSOR_OV7630:
1850 ov7630_probe(gspca_dev);
1851 break;
1526 case SENSOR_OV7648: 1852 case SENSOR_OV7648:
1527 ov7648_probe(gspca_dev); 1853 ov7648_probe(gspca_dev);
1528 break; 1854 break;
1855 case SENSOR_PO2030N:
1856 po2030n_probe(gspca_dev);
1857 break;
1529 } 1858 }
1530 regGpio[1] = 0x70; 1859 regGpio[1] = 0x70;
1531 reg_w(gspca_dev, 0x01, regGpio, 2); 1860 reg_w(gspca_dev, 0x01, regGpio, 2);
@@ -1558,6 +1887,18 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1558 struct sd *sd = (struct sd *) gspca_dev; 1887 struct sd *sd = (struct sd *) gspca_dev;
1559 1888
1560 switch (sd->sensor) { 1889 switch (sd->sensor) {
1890 case SENSOR_GC0307: {
1891 int a, b;
1892
1893 /* expo = 0..255 -> a = 19..43 */
1894 a = 19 + expo * 25 / 256;
1895 i2c_w1(gspca_dev, 0x68, a);
1896 a -= 12;
1897 b = a * a * 4; /* heuristic */
1898 i2c_w1(gspca_dev, 0x03, b >> 8);
1899 i2c_w1(gspca_dev, 0x04, b);
1900 break;
1901 }
1561 case SENSOR_HV7131R: { 1902 case SENSOR_HV7131R: {
1562 u8 Expodoit[] = 1903 u8 Expodoit[] =
1563 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 }; 1904 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
@@ -1668,6 +2009,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1668 expo = sd->brightness >> 4; 2009 expo = sd->brightness >> 4;
1669 sd->exposure = setexposure(gspca_dev, expo); 2010 sd->exposure = setexposure(gspca_dev, expo);
1670 break; 2011 break;
2012 case SENSOR_GC0307:
1671 case SENSOR_MT9V111: 2013 case SENSOR_MT9V111:
1672 expo = sd->brightness >> 8; 2014 expo = sd->brightness >> 8;
1673 sd->exposure = setexposure(gspca_dev, expo); 2015 sd->exposure = setexposure(gspca_dev, expo);
@@ -1703,7 +2045,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
1703 struct sd *sd = (struct sd *) gspca_dev; 2045 struct sd *sd = (struct sd *) gspca_dev;
1704 int i, v; 2046 int i, v;
1705 u8 reg8a[12]; /* U & V gains */ 2047 u8 reg8a[12]; /* U & V gains */
1706 static s16 uv[6] = { /* same as reg84 in signed decimal */ 2048 static const s16 uv[6] = { /* same as reg84 in signed decimal */
1707 -24, -38, 64, /* UR UG UB */ 2049 -24, -38, 64, /* UR UG UB */
1708 62, -51, -9 /* VR VG VB */ 2050 62, -51, -9 /* VR VG VB */
1709 }; 2051 };
@@ -1744,9 +2086,12 @@ static void setgamma(struct gspca_dev *gspca_dev)
1744 case SENSOR_MT9V111: 2086 case SENSOR_MT9V111:
1745 gamma_base = gamma_spec_1; 2087 gamma_base = gamma_spec_1;
1746 break; 2088 break;
1747 case SENSOR_SP80708: 2089 case SENSOR_GC0307:
1748 gamma_base = gamma_spec_2; 2090 gamma_base = gamma_spec_2;
1749 break; 2091 break;
2092 case SENSOR_SP80708:
2093 gamma_base = gamma_spec_3;
2094 break;
1750 default: 2095 default:
1751 gamma_base = gamma_def; 2096 gamma_base = gamma_def;
1752 break; 2097 break;
@@ -1937,14 +2282,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
1937 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 2282 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1938 static const u8 CA_adcm1700[] = 2283 static const u8 CA_adcm1700[] =
1939 { 0x14, 0xec, 0x0a, 0xf6 }; 2284 { 0x14, 0xec, 0x0a, 0xf6 };
2285 static const u8 CA_po2030n[] =
2286 { 0x1e, 0xe2, 0x14, 0xec };
1940 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 2287 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
2288 static const u8 CE_gc0307[] =
2289 { 0x32, 0xce, 0x2d, 0xd3 };
1941 static const u8 CE_ov76xx[] = 2290 static const u8 CE_ov76xx[] =
1942 { 0x32, 0xdd, 0x32, 0xdd }; 2291 { 0x32, 0xdd, 0x32, 0xdd };
2292 static const u8 CE_po2030n[] =
2293 { 0x14, 0xe7, 0x1e, 0xdd };
1943 2294
1944 /* create the JPEG header */ 2295 /* create the JPEG header */
1945 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
1946 if (!sd->jpeg_hdr)
1947 return -ENOMEM;
1948 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 2296 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1949 0x21); /* JPEG 422 */ 2297 0x21); /* JPEG 422 */
1950 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2298 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -1996,6 +2344,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
1996 } 2344 }
1997 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 2345 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1998 switch (sd->sensor) { 2346 switch (sd->sensor) {
2347 case SENSOR_GC0307:
2348 reg17 = 0xa2;
2349 break;
1999 case SENSOR_MT9V111: 2350 case SENSOR_MT9V111:
2000 reg17 = 0xe0; 2351 reg17 = 0xe0;
2001 break; 2352 break;
@@ -2007,9 +2358,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
2007 reg17 = 0x20; 2358 reg17 = 0x20;
2008 break; 2359 break;
2009 case SENSOR_OV7660: 2360 case SENSOR_OV7660:
2361 case SENSOR_SOI768:
2010 reg17 = 0xa0; 2362 reg17 = 0xa0;
2011 break; 2363 break;
2012 case SENSOR_PO1030: 2364 case SENSOR_PO1030:
2365 case SENSOR_PO2030N:
2013 reg17 = 0xa0; 2366 reg17 = 0xa0;
2014 break; 2367 break;
2015 default: 2368 default:
@@ -2034,12 +2387,18 @@ static int sd_start(struct gspca_dev *gspca_dev)
2034 case SENSOR_SP80708: 2387 case SENSOR_SP80708:
2035 reg_w1(gspca_dev, 0x9a, 0x05); 2388 reg_w1(gspca_dev, 0x9a, 0x05);
2036 break; 2389 break;
2390 case SENSOR_GC0307:
2037 case SENSOR_MT9V111: 2391 case SENSOR_MT9V111:
2038 reg_w1(gspca_dev, 0x9a, 0x07); 2392 reg_w1(gspca_dev, 0x9a, 0x07);
2039 break; 2393 break;
2394 case SENSOR_OV7630:
2040 case SENSOR_OV7648: 2395 case SENSOR_OV7648:
2041 reg_w1(gspca_dev, 0x9a, 0x0a); 2396 reg_w1(gspca_dev, 0x9a, 0x0a);
2042 break; 2397 break;
2398 case SENSOR_PO2030N:
2399 case SENSOR_SOI768:
2400 reg_w1(gspca_dev, 0x9a, 0x06);
2401 break;
2043 default: 2402 default:
2044 reg_w1(gspca_dev, 0x9a, 0x08); 2403 reg_w1(gspca_dev, 0x9a, 0x08);
2045 break; 2404 break;
@@ -2064,6 +2423,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
2064 reg1 = 0x46; 2423 reg1 = 0x46;
2065 reg17 = 0xe2; 2424 reg17 = 0xe2;
2066 break; 2425 break;
2426 case SENSOR_GC0307:
2427 init = gc0307_sensor_param1;
2428 reg17 = 0xa2;
2429 reg1 = 0x44;
2430 break;
2067 case SENSOR_MO4000: 2431 case SENSOR_MO4000:
2068 if (mode) { 2432 if (mode) {
2069/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ 2433/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
@@ -2087,6 +2451,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2087 reg17 = 0x64; /* 640 MCKSIZE */ 2451 reg17 = 0x64; /* 640 MCKSIZE */
2088 break; 2452 break;
2089 case SENSOR_OV7630: 2453 case SENSOR_OV7630:
2454 init = ov7630_sensor_param1;
2090 reg17 = 0xe2; 2455 reg17 = 0xe2;
2091 reg1 = 0x44; 2456 reg1 = 0x44;
2092 break; 2457 break;
@@ -2113,6 +2478,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
2113 reg17 = 0xa2; 2478 reg17 = 0xa2;
2114 reg1 = 0x44; 2479 reg1 = 0x44;
2115 break; 2480 break;
2481 case SENSOR_PO2030N:
2482 init = po2030n_sensor_param1;
2483 reg1 = 0x46;
2484 reg17 = 0xa2;
2485 break;
2486 case SENSOR_SOI768:
2487 init = soi768_sensor_param1;
2488 reg1 = 0x44;
2489 reg17 = 0xa2;
2490 break;
2116 default: 2491 default:
2117/* case SENSOR_SP80708: */ 2492/* case SENSOR_SP80708: */
2118 init = sp80708_sensor_param1; 2493 init = sp80708_sensor_param1;
@@ -2132,17 +2507,33 @@ static int sd_start(struct gspca_dev *gspca_dev)
2132 } 2507 }
2133 2508
2134 reg_w(gspca_dev, 0xc0, C0, 6); 2509 reg_w(gspca_dev, 0xc0, C0, 6);
2135 if (sd->sensor == SENSOR_ADCM1700) 2510 switch (sd->sensor) {
2511 case SENSOR_ADCM1700:
2512 case SENSOR_GC0307:
2513 case SENSOR_SOI768:
2136 reg_w(gspca_dev, 0xca, CA_adcm1700, 4); 2514 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2137 else 2515 break;
2516 case SENSOR_PO2030N:
2517 reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2518 break;
2519 default:
2138 reg_w(gspca_dev, 0xca, CA, 4); 2520 reg_w(gspca_dev, 0xca, CA, 4);
2521 break;
2522 }
2139 switch (sd->sensor) { 2523 switch (sd->sensor) {
2140 case SENSOR_ADCM1700: 2524 case SENSOR_ADCM1700:
2141 case SENSOR_OV7630: 2525 case SENSOR_OV7630:
2142 case SENSOR_OV7648: 2526 case SENSOR_OV7648:
2143 case SENSOR_OV7660: 2527 case SENSOR_OV7660:
2528 case SENSOR_SOI768:
2144 reg_w(gspca_dev, 0xce, CE_ov76xx, 4); 2529 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2145 break; 2530 break;
2531 case SENSOR_GC0307:
2532 reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2533 break;
2534 case SENSOR_PO2030N:
2535 reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2536 break;
2146 default: 2537 default:
2147 reg_w(gspca_dev, 0xce, CE, 4); 2538 reg_w(gspca_dev, 0xce, CE, 4);
2148 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ 2539 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
@@ -2161,6 +2552,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2161 setvflip(sd); 2552 setvflip(sd);
2162 setbrightness(gspca_dev); 2553 setbrightness(gspca_dev);
2163 setcontrast(gspca_dev); 2554 setcontrast(gspca_dev);
2555 setcolors(gspca_dev);
2164 setautogain(gspca_dev); 2556 setautogain(gspca_dev);
2165 setfreq(gspca_dev); 2557 setfreq(gspca_dev);
2166 return 0; 2558 return 0;
@@ -2175,11 +2567,16 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2175 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; 2567 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2176 static const u8 stopov7648[] = 2568 static const u8 stopov7648[] =
2177 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; 2569 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2570 static const u8 stopsoi768[] =
2571 { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2178 u8 data; 2572 u8 data;
2179 const u8 *sn9c1xx; 2573 const u8 *sn9c1xx;
2180 2574
2181 data = 0x0b; 2575 data = 0x0b;
2182 switch (sd->sensor) { 2576 switch (sd->sensor) {
2577 case SENSOR_GC0307:
2578 data = 0x29;
2579 break;
2183 case SENSOR_HV7131R: 2580 case SENSOR_HV7131R:
2184 i2c_w8(gspca_dev, stophv7131); 2581 i2c_w8(gspca_dev, stophv7131);
2185 data = 0x2b; 2582 data = 0x2b;
@@ -2196,6 +2593,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2196 case SENSOR_PO1030: 2593 case SENSOR_PO1030:
2197 data = 0x29; 2594 data = 0x29;
2198 break; 2595 break;
2596 case SENSOR_SOI768:
2597 i2c_w8(gspca_dev, stopsoi768);
2598 data = 0x29;
2599 break;
2199 } 2600 }
2200 sn9c1xx = sn_tb[sd->sensor]; 2601 sn9c1xx = sn_tb[sd->sensor];
2201 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 2602 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -2206,13 +2607,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2206 /* reg_w1(gspca_dev, 0xf1, 0x01); */ 2607 /* reg_w1(gspca_dev, 0xf1, 0x01); */
2207} 2608}
2208 2609
2209static void sd_stop0(struct gspca_dev *gspca_dev)
2210{
2211 struct sd *sd = (struct sd *) gspca_dev;
2212
2213 kfree(sd->jpeg_hdr);
2214}
2215
2216static void do_autogain(struct gspca_dev *gspca_dev) 2610static void do_autogain(struct gspca_dev *gspca_dev)
2217{ 2611{
2218 struct sd *sd = (struct sd *) gspca_dev; 2612 struct sd *sd = (struct sd *) gspca_dev;
@@ -2233,6 +2627,14 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2233 if (delta < luma_mean - luma_delta || 2627 if (delta < luma_mean - luma_delta ||
2234 delta > luma_mean + luma_delta) { 2628 delta > luma_mean + luma_delta) {
2235 switch (sd->sensor) { 2629 switch (sd->sensor) {
2630 case SENSOR_GC0307:
2631 expotimes = sd->exposure;
2632 expotimes += (luma_mean - delta) >> 6;
2633 if (expotimes < 0)
2634 expotimes = 0;
2635 sd->exposure = setexposure(gspca_dev,
2636 (unsigned int) expotimes);
2637 break;
2236 case SENSOR_HV7131R: 2638 case SENSOR_HV7131R:
2237 expotimes = sd->exposure >> 8; 2639 expotimes = sd->exposure >> 8;
2238 expotimes += (luma_mean - delta) >> 4; 2640 expotimes += (luma_mean - delta) >> 4;
@@ -2584,7 +2986,6 @@ static const struct sd_desc sd_desc = {
2584 .init = sd_init, 2986 .init = sd_init,
2585 .start = sd_start, 2987 .start = sd_start,
2586 .stopN = sd_stopN, 2988 .stopN = sd_stopN,
2587 .stop0 = sd_stop0,
2588 .pkt_scan = sd_pkt_scan, 2989 .pkt_scan = sd_pkt_scan,
2589 .dq_callback = do_autogain, 2990 .dq_callback = do_autogain,
2590 .get_jcomp = sd_get_jcomp, 2991 .get_jcomp = sd_get_jcomp,
@@ -2656,7 +3057,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2656#endif 3057#endif
2657 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, 3058 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2658 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, 3059 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
2659/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/ 3060 {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
2660 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ 3061 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2661 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ 3062 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
2662 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ 3063 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index b9c80e2103b9..7bb2355005dc 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -22,6 +22,7 @@
22 22
23#define MODULE_NAME "spca561" 23#define MODULE_NAME "spca561"
24 24
25#include <linux/input.h>
25#include "gspca.h" 26#include "gspca.h"
26 27
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -249,9 +250,9 @@ static const __u16 Pb100_2map8300[][2] = {
249}; 250};
250 251
251static const __u16 spca561_161rev12A_data1[][2] = { 252static const __u16 spca561_161rev12A_data1[][2] = {
252 {0x29, 0x8118}, /* white balance - was 21 */ 253 {0x29, 0x8118}, /* Control register (various enable bits) */
253 {0x08, 0x8114}, /* white balance - was 01 */ 254 {0x08, 0x8114}, /* GPIO: Led off */
254 {0x0e, 0x8112}, /* white balance - was 00 */ 255 {0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */
255 {0x00, 0x8102}, /* white balance - new */ 256 {0x00, 0x8102}, /* white balance - new */
256 {0x92, 0x8804}, 257 {0x92, 0x8804},
257 {0x04, 0x8802}, /* windows uses 08 */ 258 {0x04, 0x8802}, /* windows uses 08 */
@@ -263,15 +264,11 @@ static const __u16 spca561_161rev12A_data2[][2] = {
263 {0x07, 0x8601}, 264 {0x07, 0x8601},
264 {0x07, 0x8602}, 265 {0x07, 0x8602},
265 {0x04, 0x8501}, 266 {0x04, 0x8501},
266 {0x21, 0x8118},
267 267
268 {0x07, 0x8201}, /* windows uses 02 */ 268 {0x07, 0x8201}, /* windows uses 02 */
269 {0x08, 0x8200}, 269 {0x08, 0x8200},
270 {0x01, 0x8200}, 270 {0x01, 0x8200},
271 271
272 {0x00, 0x8114},
273 {0x01, 0x8114}, /* windows uses 00 */
274
275 {0x90, 0x8604}, 272 {0x90, 0x8604},
276 {0x00, 0x8605}, 273 {0x00, 0x8605},
277 {0xb0, 0x8603}, 274 {0xb0, 0x8603},
@@ -302,6 +299,9 @@ static const __u16 spca561_161rev12A_data2[][2] = {
302 {0xf0, 0x8505}, 299 {0xf0, 0x8505},
303 {0x32, 0x850a}, 300 {0x32, 0x850a},
304/* {0x99, 0x8700}, * - white balance - new (removed) */ 301/* {0x99, 0x8700}, * - white balance - new (removed) */
302 /* HDG we used to do this in stop0, making the init state and the state
303 after a start / stop different, so do this here instead. */
304 {0x29, 0x8118},
305 {} 305 {}
306}; 306};
307 307
@@ -645,6 +645,9 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
645 setwhite(gspca_dev); 645 setwhite(gspca_dev);
646 setgain(gspca_dev); 646 setgain(gspca_dev);
647 setexposure(gspca_dev); 647 setexposure(gspca_dev);
648
649 /* Led ON (bit 3 -> 0 */
650 reg_w_val(gspca_dev->dev, 0x8114, 0x00);
648 return 0; 651 return 0;
649} 652}
650static int sd_start_72a(struct gspca_dev *gspca_dev) 653static int sd_start_72a(struct gspca_dev *gspca_dev)
@@ -691,26 +694,14 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
691 694
692 if (sd->chip_revision == Rev012A) { 695 if (sd->chip_revision == Rev012A) {
693 reg_w_val(gspca_dev->dev, 0x8112, 0x0e); 696 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
697 /* Led Off (bit 3 -> 1 */
698 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
694 } else { 699 } else {
695 reg_w_val(gspca_dev->dev, 0x8112, 0x20); 700 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
696/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */ 701/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
697 } 702 }
698} 703}
699 704
700/* called on streamoff with alt 0 and on disconnect */
701static void sd_stop0(struct gspca_dev *gspca_dev)
702{
703 struct sd *sd = (struct sd *) gspca_dev;
704
705 if (!gspca_dev->present)
706 return;
707 if (sd->chip_revision == Rev012A) {
708 reg_w_val(gspca_dev->dev, 0x8118, 0x29);
709 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
710 }
711/* reg_w_val(gspca_dev->dev, 0x8114, 0); */
712}
713
714static void do_autogain(struct gspca_dev *gspca_dev) 705static void do_autogain(struct gspca_dev *gspca_dev)
715{ 706{
716 struct sd *sd = (struct sd *) gspca_dev; 707 struct sd *sd = (struct sd *) gspca_dev;
@@ -788,6 +779,23 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
788 switch (*data++) { /* sequence number */ 779 switch (*data++) { /* sequence number */
789 case 0: /* start of frame */ 780 case 0: /* start of frame */
790 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 781 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
782
783 /* This should never happen */
784 if (len < 2) {
785 PDEBUG(D_ERR, "Short SOF packet, ignoring");
786 gspca_dev->last_packet_type = DISCARD_PACKET;
787 return;
788 }
789
790#ifdef CONFIG_INPUT
791 if (data[0] & 0x20) {
792 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
793 input_sync(gspca_dev->input_dev);
794 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
795 input_sync(gspca_dev->input_dev);
796 }
797#endif
798
791 if (data[1] & 0x10) { 799 if (data[1] & 0x10) {
792 /* compressed bayer */ 800 /* compressed bayer */
793 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 801 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
@@ -1028,8 +1036,10 @@ static const struct sd_desc sd_desc_12a = {
1028 .init = sd_init_12a, 1036 .init = sd_init_12a,
1029 .start = sd_start_12a, 1037 .start = sd_start_12a,
1030 .stopN = sd_stopN, 1038 .stopN = sd_stopN,
1031 .stop0 = sd_stop0,
1032 .pkt_scan = sd_pkt_scan, 1039 .pkt_scan = sd_pkt_scan,
1040#ifdef CONFIG_INPUT
1041 .other_input = 1,
1042#endif
1033}; 1043};
1034static const struct sd_desc sd_desc_72a = { 1044static const struct sd_desc sd_desc_72a = {
1035 .name = MODULE_NAME, 1045 .name = MODULE_NAME,
@@ -1039,9 +1049,11 @@ static const struct sd_desc sd_desc_72a = {
1039 .init = sd_init_72a, 1049 .init = sd_init_72a,
1040 .start = sd_start_72a, 1050 .start = sd_start_72a,
1041 .stopN = sd_stopN, 1051 .stopN = sd_stopN,
1042 .stop0 = sd_stop0,
1043 .pkt_scan = sd_pkt_scan, 1052 .pkt_scan = sd_pkt_scan,
1044 .dq_callback = do_autogain, 1053 .dq_callback = do_autogain,
1054#ifdef CONFIG_INPUT
1055 .other_input = 1,
1056#endif
1045}; 1057};
1046static const struct sd_desc *sd_desc[2] = { 1058static const struct sd_desc *sd_desc[2] = {
1047 &sd_desc_12a, 1059 &sd_desc_12a,
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 668a7536af90..63014372adbc 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -44,7 +44,10 @@ struct sd {
44 u8 gamma; 44 u8 gamma;
45 u8 sharpness; 45 u8 sharpness;
46 u8 freq; 46 u8 freq;
47 u8 whitebalance; 47 u8 red_balance; /* split balance */
48 u8 blue_balance;
49 u8 global_gain; /* aka gain */
50 u8 whitebalance; /* set default r/g/b and activate */
48 u8 mirror; 51 u8 mirror;
49 u8 effect; 52 u8 effect;
50 53
@@ -70,8 +73,17 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
71static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 74static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 75static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
76
77
73static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val);
86
75static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); 87static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); 88static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
@@ -79,6 +91,7 @@ static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_querymenu(struct gspca_dev *gspca_dev, 91static int sd_querymenu(struct gspca_dev *gspca_dev,
80 struct v4l2_querymenu *menu); 92 struct v4l2_querymenu *menu);
81 93
94
82static const struct ctrl sd_ctrls[] = { 95static const struct ctrl sd_ctrls[] = {
83 { 96 {
84 { 97 {
@@ -139,7 +152,7 @@ static const struct ctrl sd_ctrls[] = {
139 }, 152 },
140 { 153 {
141 { 154 {
142 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, 155 .id = V4L2_CID_BACKLIGHT_COMPENSATION, /* Activa lowlight,
143 * some apps dont bring up the 156 * some apps dont bring up the
144 * backligth_compensation control) */ 157 * backligth_compensation control) */
145 .type = V4L2_CTRL_TYPE_INTEGER, 158 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -183,7 +196,7 @@ static const struct ctrl sd_ctrls[] = {
183 196
184 { 197 {
185 { 198 {
186 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 199 .id = V4L2_CID_AUTO_WHITE_BALANCE,
187 .type = V4L2_CTRL_TYPE_INTEGER, 200 .type = V4L2_CTRL_TYPE_INTEGER,
188 .name = "White Balance", 201 .name = "White Balance",
189 .minimum = 0, 202 .minimum = 0,
@@ -223,6 +236,48 @@ static const struct ctrl sd_ctrls[] = {
223 .set = sd_seteffect, 236 .set = sd_seteffect,
224 .get = sd_geteffect 237 .get = sd_geteffect
225 }, 238 },
239 {
240 {
241 .id = V4L2_CID_BLUE_BALANCE,
242 .type = V4L2_CTRL_TYPE_INTEGER,
243 .name = "Blue Balance",
244 .minimum = 0x10,
245 .maximum = 0x40,
246 .step = 1,
247#define BLUE_BALANCE_DEF 0x20
248 .default_value = BLUE_BALANCE_DEF,
249 },
250 .set = sd_setblue_balance,
251 .get = sd_getblue_balance,
252 },
253 {
254 {
255 .id = V4L2_CID_RED_BALANCE,
256 .type = V4L2_CTRL_TYPE_INTEGER,
257 .name = "Red Balance",
258 .minimum = 0x10,
259 .maximum = 0x40,
260 .step = 1,
261#define RED_BALANCE_DEF 0x20
262 .default_value = RED_BALANCE_DEF,
263 },
264 .set = sd_setred_balance,
265 .get = sd_getred_balance,
266 },
267 {
268 {
269 .id = V4L2_CID_GAIN,
270 .type = V4L2_CTRL_TYPE_INTEGER,
271 .name = "Gain",
272 .minimum = 0x10,
273 .maximum = 0x40,
274 .step = 1,
275#define global_gain_DEF 0x20
276 .default_value = global_gain_DEF,
277 },
278 .set = sd_setglobal_gain,
279 .get = sd_getglobal_gain,
280 },
226}; 281};
227 282
228static char *effects_control[] = { 283static char *effects_control[] = {
@@ -523,6 +578,10 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
523 u8 *tmpbuf; 578 u8 *tmpbuf;
524 579
525 tmpbuf = kmalloc(len, GFP_KERNEL); 580 tmpbuf = kmalloc(len, GFP_KERNEL);
581 if (!tmpbuf) {
582 err("Out of memory");
583 return;
584 }
526 memcpy(tmpbuf, buffer, len); 585 memcpy(tmpbuf, buffer, len);
527 usb_control_msg(gspca_dev->dev, 586 usb_control_msg(gspca_dev->dev,
528 usb_sndctrlpipe(gspca_dev->dev, 0), 587 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -542,10 +601,15 @@ static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
542 int i; 601 int i;
543 u8 *p, *tmpbuf; 602 u8 *p, *tmpbuf;
544 603
545 if (len * 2 <= USB_BUF_SZ) 604 if (len * 2 <= USB_BUF_SZ) {
546 p = tmpbuf = gspca_dev->usb_buf; 605 p = tmpbuf = gspca_dev->usb_buf;
547 else 606 } else {
548 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); 607 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
608 if (!tmpbuf) {
609 err("Out of memory");
610 return;
611 }
612 }
549 i = len; 613 i = len;
550 while (--i >= 0) { 614 while (--i >= 0) {
551 *p++ = reg++; 615 *p++ = reg++;
@@ -642,6 +706,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
642 sd->whitebalance = WHITE_BALANCE_DEF; 706 sd->whitebalance = WHITE_BALANCE_DEF;
643 sd->sharpness = SHARPNESS_DEF; 707 sd->sharpness = SHARPNESS_DEF;
644 sd->effect = EFFECTS_DEF; 708 sd->effect = EFFECTS_DEF;
709 sd->red_balance = RED_BALANCE_DEF;
710 sd->blue_balance = BLUE_BALANCE_DEF;
711 sd->global_gain = global_gain_DEF;
712
645 return 0; 713 return 0;
646} 714}
647 715
@@ -693,18 +761,40 @@ static void setgamma(struct gspca_dev *gspca_dev)
693 reg_w_ixbuf(gspca_dev, 0x90, 761 reg_w_ixbuf(gspca_dev, 0x90,
694 gamma_table[sd->gamma], sizeof gamma_table[0]); 762 gamma_table[sd->gamma], sizeof gamma_table[0]);
695} 763}
764static void setglobalgain(struct gspca_dev *gspca_dev)
765{
696 766
697static void setwhitebalance(struct gspca_dev *gspca_dev) 767 struct sd *sd = (struct sd *) gspca_dev;
768 reg_w(gspca_dev, (sd->red_balance << 8) + 0x87);
769 reg_w(gspca_dev, (sd->blue_balance << 8) + 0x88);
770 reg_w(gspca_dev, (sd->global_gain << 8) + 0x89);
771}
772
773/* Generic fnc for r/b balance, exposure and whitebalance */
774static void setbalance(struct gspca_dev *gspca_dev)
698{ 775{
699 struct sd *sd = (struct sd *) gspca_dev; 776 struct sd *sd = (struct sd *) gspca_dev;
700 777
701 u8 white_balance[8] = 778 /* on whitebalance leave defaults values */
702 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; 779 if (sd->whitebalance) {
780 reg_w(gspca_dev, 0x3c80);
781 } else {
782 reg_w(gspca_dev, 0x3880);
783 /* shoud we wait here.. */
784 /* update and reset 'global gain' with webcam parameters */
785 sd->red_balance = reg_r(gspca_dev, 0x0087);
786 sd->blue_balance = reg_r(gspca_dev, 0x0088);
787 sd->global_gain = reg_r(gspca_dev, 0x0089);
788 setglobalgain(gspca_dev);
789 }
790
791}
792
703 793
704 if (sd->whitebalance)
705 white_balance[7] = 0x3c;
706 794
707 reg_w_buf(gspca_dev, white_balance, sizeof white_balance); 795static void setwhitebalance(struct gspca_dev *gspca_dev)
796{
797 setbalance(gspca_dev);
708} 798}
709 799
710static void setsharpness(struct gspca_dev *gspca_dev) 800static void setsharpness(struct gspca_dev *gspca_dev)
@@ -1018,6 +1108,66 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1018 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 1108 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1019} 1109}
1020 1110
1111
1112static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1113{
1114 struct sd *sd = (struct sd *) gspca_dev;
1115
1116 sd->blue_balance = val;
1117 if (gspca_dev->streaming)
1118 reg_w(gspca_dev, (val << 8) + 0x88);
1119 return 0;
1120}
1121
1122static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1123{
1124 struct sd *sd = (struct sd *) gspca_dev;
1125
1126 *val = sd->blue_balance;
1127 return 0;
1128}
1129
1130static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1131{
1132 struct sd *sd = (struct sd *) gspca_dev;
1133
1134 sd->red_balance = val;
1135 if (gspca_dev->streaming)
1136 reg_w(gspca_dev, (val << 8) + 0x87);
1137
1138 return 0;
1139}
1140
1141static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1142{
1143 struct sd *sd = (struct sd *) gspca_dev;
1144
1145 *val = sd->red_balance;
1146 return 0;
1147}
1148
1149
1150
1151static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val)
1152{
1153 struct sd *sd = (struct sd *) gspca_dev;
1154
1155 sd->global_gain = val;
1156 if (gspca_dev->streaming)
1157 setglobalgain(gspca_dev);
1158
1159 return 0;
1160}
1161
1162static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val)
1163{
1164 struct sd *sd = (struct sd *) gspca_dev;
1165
1166 *val = sd->global_gain;
1167 return 0;
1168}
1169
1170
1021static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1171static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1022{ 1172{
1023 struct sd *sd = (struct sd *) gspca_dev; 1173 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 4989f9afb46e..732c3dfe46ff 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Z-star vc0321 library 2 * Z-star vc0321 library
3 * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl
4 * Copyright (C) 2006 Michel Xhaard
5 * 3 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
5 * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl
6 * Copyright (C) 2006 Michel Xhaard
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
24 24
25#include "gspca.h" 25#include "gspca.h"
26 26
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 27MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
28MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); 28MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver");
29MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
30 30
@@ -1971,268 +1971,489 @@ static const u8 ov7660_NoFliker[][4] = {
1971 {} 1971 {}
1972}; 1972};
1973 1973
1974static const u8 ov7670_initVGA_JPG[][4] = { 1974static const u8 ov7670_InitVGA[][4] = {
1975 {0xb3, 0x01, 0x05, 0xcc}, 1975 {0xb3, 0x01, 0x05, 0xcc},
1976 {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, 1976 {0x00, 0x00, 0x30, 0xdd},
1977 {0xb0, 0x03, 0x19, 0xcc},
1978 {0x00, 0x00, 0x10, 0xdd},
1979 {0xb0, 0x04, 0x02, 0xcc},
1977 {0x00, 0x00, 0x10, 0xdd}, 1980 {0x00, 0x00, 0x10, 0xdd},
1978 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 1981 {0xb3, 0x00, 0x66, 0xcc},
1979 {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, 1982 {0xb3, 0x00, 0x67, 0xcc},
1983 {0xb0, 0x16, 0x01, 0xcc},
1980 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */ 1984 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
1981 {0xb3, 0x34, 0x01, 0xcc}, 1985 {0xb3, 0x34, 0x01, 0xcc},
1982 {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, 1986 {0xb3, 0x05, 0x01, 0xcc},
1983 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, 1987 {0xb3, 0x06, 0x01, 0xcc},
1984 {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, 1988 {0xb3, 0x08, 0x01, 0xcc},
1985 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, 1989 {0xb3, 0x09, 0x0c, 0xcc},
1986 {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, 1990 {0xb3, 0x02, 0x02, 0xcc},
1987 {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, 1991 {0xb3, 0x03, 0x1f, 0xcc},
1988 {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, 1992 {0xb3, 0x14, 0x00, 0xcc},
1989 {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0x41, 0xcc}, 1993 {0xb3, 0x15, 0x00, 0xcc},
1990 {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, 1994 {0xb3, 0x16, 0x02, 0xcc},
1991 {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, 1995 {0xb3, 0x17, 0x7f, 0xcc},
1992 {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, 1996 {0xb3, 0x04, 0x05, 0xcc},
1993 {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, 1997 {0xb3, 0x20, 0x00, 0xcc},
1994 {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, 1998 {0xb3, 0x21, 0x00, 0xcc},
1995 {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, 1999 {0xb3, 0x22, 0x01, 0xcc},
1996 {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, 2000 {0xb3, 0x23, 0xe0, 0xcc},
1997 {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, 2001 {0xbc, 0x00, 0x41, 0xcc},
1998 {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, 2002 {0xbc, 0x01, 0x01, 0xcc},
1999 {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, 2003 {0x00, 0x12, 0x80, 0xaa},
2000 {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, 2004 {0x00, 0x00, 0x20, 0xdd},
2001 {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, 2005 {0x00, 0x12, 0x00, 0xaa},
2002 {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, 2006 {0x00, 0x11, 0x40, 0xaa},
2003 {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, 2007 {0x00, 0x6b, 0x0a, 0xaa},
2004 {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, 2008 {0x00, 0x3a, 0x04, 0xaa},
2005 {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, 2009 {0x00, 0x40, 0xc0, 0xaa},
2006 {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, 2010 {0x00, 0x8c, 0x00, 0xaa},
2007 {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, 2011 {0x00, 0x7a, 0x29, 0xaa},
2008 {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, 2012 {0x00, 0x7b, 0x0e, 0xaa},
2009 {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, 2013 {0x00, 0x7c, 0x1a, 0xaa},
2010 {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, 2014 {0x00, 0x7d, 0x31, 0xaa},
2011 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 2015 {0x00, 0x7e, 0x53, 0xaa},
2012 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, 2016 {0x00, 0x7f, 0x60, 0xaa},
2013 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 2017 {0x00, 0x80, 0x6b, 0xaa},
2018 {0x00, 0x81, 0x73, 0xaa},
2019 {0x00, 0x82, 0x7b, 0xaa},
2020 {0x00, 0x83, 0x82, 0xaa},
2021 {0x00, 0x84, 0x89, 0xaa},
2022 {0x00, 0x85, 0x96, 0xaa},
2023 {0x00, 0x86, 0xa1, 0xaa},
2024 {0x00, 0x87, 0xb7, 0xaa},
2025 {0x00, 0x88, 0xcc, 0xaa},
2026 {0x00, 0x89, 0xe1, 0xaa},
2027 {0x00, 0x13, 0xe0, 0xaa},
2028 {0x00, 0x00, 0x00, 0xaa},
2029 {0x00, 0x10, 0x00, 0xaa},
2030 {0x00, 0x0d, 0x40, 0xaa},
2031 {0x00, 0x14, 0x28, 0xaa},
2032 {0x00, 0xa5, 0x05, 0xaa},
2033 {0x00, 0xab, 0x07, 0xaa},
2034 {0x00, 0x24, 0x95, 0xaa},
2035 {0x00, 0x25, 0x33, 0xaa},
2036 {0x00, 0x26, 0xe3, 0xaa},
2037 {0x00, 0x9f, 0x88, 0xaa},
2038 {0x00, 0xa0, 0x78, 0xaa},
2039 {0x00, 0x55, 0x90, 0xaa},
2040 {0x00, 0xa1, 0x03, 0xaa},
2041 {0x00, 0xa6, 0xe0, 0xaa},
2042 {0x00, 0xa7, 0xd8, 0xaa},
2043 {0x00, 0xa8, 0xf0, 0xaa},
2044 {0x00, 0xa9, 0x90, 0xaa},
2045 {0x00, 0xaa, 0x14, 0xaa},
2046 {0x00, 0x13, 0xe5, 0xaa},
2047 {0x00, 0x0e, 0x61, 0xaa},
2048 {0x00, 0x0f, 0x4b, 0xaa},
2049 {0x00, 0x16, 0x02, 0xaa},
2014 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */ 2050 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
2015 {0x00, 0x21, 0x02, 0xaa}, 2051 {0x00, 0x21, 0x02, 0xaa},
2016 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, 2052 {0x00, 0x22, 0x91, 0xaa},
2017 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, 2053 {0x00, 0x29, 0x07, 0xaa},
2018 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, 2054 {0x00, 0x33, 0x0b, 0xaa},
2019 {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, 2055 {0x00, 0x35, 0x0b, 0xaa},
2020 {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, 2056 {0x00, 0x37, 0x1d, 0xaa},
2021 {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, 2057 {0x00, 0x38, 0x71, 0xaa},
2022 {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, 2058 {0x00, 0x39, 0x2a, 0xaa},
2023 {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, 2059 {0x00, 0x3c, 0x78, 0xaa},
2024 {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, 2060 {0x00, 0x4d, 0x40, 0xaa},
2025 {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 2061 {0x00, 0x4e, 0x20, 0xaa},
2026 {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, 2062 {0x00, 0x74, 0x19, 0xaa},
2027 {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, 2063 {0x00, 0x8d, 0x4f, 0xaa},
2028 {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, 2064 {0x00, 0x8e, 0x00, 0xaa},
2029 {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, 2065 {0x00, 0x8f, 0x00, 0xaa},
2030 {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, 2066 {0x00, 0x90, 0x00, 0xaa},
2031 {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, 2067 {0x00, 0x91, 0x00, 0xaa},
2032 {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, 2068 {0x00, 0x96, 0x00, 0xaa},
2033 {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, 2069 {0x00, 0x9a, 0x80, 0xaa},
2034 {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, 2070 {0x00, 0xb0, 0x84, 0xaa},
2035 {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, 2071 {0x00, 0xb1, 0x0c, 0xaa},
2036 {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, 2072 {0x00, 0xb2, 0x0e, 0xaa},
2037 {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, 2073 {0x00, 0xb3, 0x82, 0xaa},
2038 {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, 2074 {0x00, 0xb8, 0x0a, 0xaa},
2039 {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, 2075 {0x00, 0x43, 0x14, 0xaa},
2040 {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, 2076 {0x00, 0x44, 0xf0, 0xaa},
2041 {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, 2077 {0x00, 0x45, 0x45, 0xaa},
2042 {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, 2078 {0x00, 0x46, 0x63, 0xaa},
2043 {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, 2079 {0x00, 0x47, 0x2d, 0xaa},
2044 {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, 2080 {0x00, 0x48, 0x46, 0xaa},
2045 {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, 2081 {0x00, 0x59, 0x88, 0xaa},
2046 {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, 2082 {0x00, 0x5a, 0xa0, 0xaa},
2047 {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, 2083 {0x00, 0x5b, 0xc6, 0xaa},
2048 {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, 2084 {0x00, 0x5c, 0x7d, 0xaa},
2049 {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, 2085 {0x00, 0x5d, 0x5f, 0xaa},
2050 {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, 2086 {0x00, 0x5e, 0x19, 0xaa},
2051 {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, 2087 {0x00, 0x6c, 0x0a, 0xaa},
2052 {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, 2088 {0x00, 0x6d, 0x55, 0xaa},
2053 {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, 2089 {0x00, 0x6e, 0x11, 0xaa},
2054 {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, 2090 {0x00, 0x6f, 0x9e, 0xaa},
2055 {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, 2091 {0x00, 0x69, 0x00, 0xaa},
2056 {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, 2092 {0x00, 0x6a, 0x40, 0xaa},
2057 {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, 2093 {0x00, 0x01, 0x40, 0xaa},
2058 {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, 2094 {0x00, 0x02, 0x40, 0xaa},
2059 {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, 2095 {0x00, 0x13, 0xe7, 0xaa},
2060 {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, 2096 {0x00, 0x5f, 0xf0, 0xaa},
2061 {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, 2097 {0x00, 0x60, 0xf0, 0xaa},
2062 {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, 2098 {0x00, 0x61, 0xf0, 0xaa},
2063 {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, 2099 {0x00, 0x27, 0xa0, 0xaa},
2064 {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, 2100 {0x00, 0x28, 0x80, 0xaa},
2065 {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, 2101 {0x00, 0x2c, 0x90, 0xaa},
2066 {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, 2102 {0x00, 0x4f, 0x66, 0xaa},
2067 {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, 2103 {0x00, 0x50, 0x66, 0xaa},
2068 {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, 2104 {0x00, 0x51, 0x00, 0xaa},
2069 {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, 2105 {0x00, 0x52, 0x22, 0xaa},
2070 {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, 2106 {0x00, 0x53, 0x5e, 0xaa},
2071 {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, 2107 {0x00, 0x54, 0x80, 0xaa},
2072 {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, 2108 {0x00, 0x58, 0x9e, 0xaa},
2073 {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, 2109 {0x00, 0x41, 0x08, 0xaa},
2074 {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, 2110 {0x00, 0x3f, 0x00, 0xaa},
2075 {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, 2111 {0x00, 0x75, 0x85, 0xaa},
2076 {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, 2112 {0x00, 0x76, 0xe1, 0xaa},
2077 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, 2113 {0x00, 0x4c, 0x00, 0xaa},
2078 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, 2114 {0x00, 0x77, 0x0a, 0xaa},
2079 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 2115 {0x00, 0x3d, 0x88, 0xaa},
2116 {0x00, 0x4b, 0x09, 0xaa},
2117 {0x00, 0xc9, 0x60, 0xaa},
2118 {0x00, 0x41, 0x38, 0xaa},
2119 {0x00, 0x62, 0x30, 0xaa},
2120 {0x00, 0x63, 0x30, 0xaa},
2121 {0x00, 0x64, 0x08, 0xaa},
2122 {0x00, 0x94, 0x07, 0xaa},
2123 {0x00, 0x95, 0x0b, 0xaa},
2124 {0x00, 0x65, 0x00, 0xaa},
2125 {0x00, 0x66, 0x05, 0xaa},
2126 {0x00, 0x56, 0x50, 0xaa},
2127 {0x00, 0x34, 0x11, 0xaa},
2128 {0x00, 0xa4, 0x88, 0xaa},
2129 {0x00, 0x96, 0x00, 0xaa},
2130 {0x00, 0x97, 0x30, 0xaa},
2131 {0x00, 0x98, 0x20, 0xaa},
2132 {0x00, 0x99, 0x30, 0xaa},
2133 {0x00, 0x9a, 0x84, 0xaa},
2134 {0x00, 0x9b, 0x29, 0xaa},
2135 {0x00, 0x9c, 0x03, 0xaa},
2136 {0x00, 0x78, 0x04, 0xaa},
2137 {0x00, 0x79, 0x01, 0xaa},
2138 {0x00, 0xc8, 0xf0, 0xaa},
2139 {0x00, 0x79, 0x0f, 0xaa},
2140 {0x00, 0xc8, 0x00, 0xaa},
2141 {0x00, 0x79, 0x10, 0xaa},
2142 {0x00, 0xc8, 0x7e, 0xaa},
2143 {0x00, 0x79, 0x0a, 0xaa},
2144 {0x00, 0xc8, 0x80, 0xaa},
2145 {0x00, 0x79, 0x0b, 0xaa},
2146 {0x00, 0xc8, 0x01, 0xaa},
2147 {0x00, 0x79, 0x0c, 0xaa},
2148 {0x00, 0xc8, 0x0f, 0xaa},
2149 {0x00, 0x79, 0x0d, 0xaa},
2150 {0x00, 0xc8, 0x20, 0xaa},
2151 {0x00, 0x79, 0x09, 0xaa},
2152 {0x00, 0xc8, 0x80, 0xaa},
2153 {0x00, 0x79, 0x02, 0xaa},
2154 {0x00, 0xc8, 0xc0, 0xaa},
2155 {0x00, 0x79, 0x03, 0xaa},
2156 {0x00, 0xc8, 0x40, 0xaa},
2157 {0x00, 0x79, 0x05, 0xaa},
2158 {0x00, 0xc8, 0x30, 0xaa},
2159 {0x00, 0x79, 0x26, 0xaa},
2160 {0x00, 0x11, 0x40, 0xaa},
2161 {0x00, 0x3a, 0x04, 0xaa},
2162 {0x00, 0x12, 0x00, 0xaa},
2163 {0x00, 0x40, 0xc0, 0xaa},
2164 {0x00, 0x8c, 0x00, 0xaa},
2165 {0x00, 0x17, 0x14, 0xaa},
2166 {0x00, 0x18, 0x02, 0xaa},
2167 {0x00, 0x32, 0x92, 0xaa},
2168 {0x00, 0x19, 0x02, 0xaa},
2169 {0x00, 0x1a, 0x7a, 0xaa},
2170 {0x00, 0x03, 0x0a, 0xaa},
2171 {0x00, 0x0c, 0x00, 0xaa},
2172 {0x00, 0x3e, 0x00, 0xaa},
2173 {0x00, 0x70, 0x3a, 0xaa},
2174 {0x00, 0x71, 0x35, 0xaa},
2175 {0x00, 0x72, 0x11, 0xaa},
2176 {0x00, 0x73, 0xf0, 0xaa},
2177 {0x00, 0xa2, 0x02, 0xaa},
2178 {0x00, 0xb1, 0x00, 0xaa},
2179 {0x00, 0xb1, 0x0c, 0xaa},
2080 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */ 2180 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
2081 {0x00, 0xaa, 0x14, 0xaa}, 2181 {0x00, 0xaa, 0x14, 0xaa},
2082 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, 2182 {0x00, 0x24, 0x80, 0xaa},
2083 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, 2183 {0x00, 0x25, 0x74, 0xaa},
2084 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, 2184 {0x00, 0x26, 0xd3, 0xaa},
2085 {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, 2185 {0x00, 0x0d, 0x00, 0xaa},
2086 {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, 2186 {0x00, 0x14, 0x18, 0xaa},
2087 {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, 2187 {0x00, 0x9d, 0x99, 0xaa},
2088 {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, 2188 {0x00, 0x9e, 0x7f, 0xaa},
2089 {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, 2189 {0x00, 0x64, 0x08, 0xaa},
2090 {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, 2190 {0x00, 0x94, 0x07, 0xaa},
2091 {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, 2191 {0x00, 0x95, 0x06, 0xaa},
2092 {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, 2192 {0x00, 0x66, 0x05, 0xaa},
2093 {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc}, 2193 {0x00, 0x41, 0x08, 0xaa},
2094 {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc}, 2194 {0x00, 0x3f, 0x00, 0xaa},
2095 {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x13, 0xcc}, 2195 {0x00, 0x75, 0x07, 0xaa},
2096 {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc}, 2196 {0x00, 0x76, 0xe1, 0xaa},
2097 {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, 2197 {0x00, 0x4c, 0x00, 0xaa},
2098 {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, 2198 {0x00, 0x77, 0x00, 0xaa},
2099 {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, 2199 {0x00, 0x3d, 0xc2, 0xaa},
2100 {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, 2200 {0x00, 0x4b, 0x09, 0xaa},
2201 {0x00, 0xc9, 0x60, 0xaa},
2202 {0x00, 0x41, 0x38, 0xaa},
2203 {0xbf, 0xc0, 0x26, 0xcc},
2204 {0xbf, 0xc1, 0x02, 0xcc},
2205 {0xbf, 0xcc, 0x04, 0xcc},
2206 {0xb3, 0x5c, 0x01, 0xcc},
2207 {0xb3, 0x01, 0x45, 0xcc},
2101 {0x00, 0x77, 0x05, 0xaa}, 2208 {0x00, 0x77, 0x05, 0xaa},
2102 {}, 2209 {},
2103}; 2210};
2104 2211
2105static const u8 ov7670_initQVGA_JPG[][4] = { 2212static const u8 ov7670_InitQVGA[][4] = {
2106 {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, 2213 {0xb3, 0x01, 0x05, 0xcc},
2107 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 2214 {0x00, 0x00, 0x30, 0xdd},
2108 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 2215 {0xb0, 0x03, 0x19, 0xcc},
2109 {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, 2216 {0x00, 0x00, 0x10, 0xdd},
2110 {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, 2217 {0xb0, 0x04, 0x02, 0xcc},
2111 {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, 2218 {0x00, 0x00, 0x10, 0xdd},
2112 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, 2219 {0xb3, 0x00, 0x66, 0xcc},
2113 {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, 2220 {0xb3, 0x00, 0x67, 0xcc},
2114 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, 2221 {0xb0, 0x16, 0x01, 0xcc},
2115 {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, 2222 {0xb3, 0x35, 0xa1, 0xcc}, /* i2c add: 21 */
2116 {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, 2223 {0xb3, 0x34, 0x01, 0xcc},
2117 {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, 2224 {0xb3, 0x05, 0x01, 0xcc},
2118 {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, 2225 {0xb3, 0x06, 0x01, 0xcc},
2119 {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, 2226 {0xb3, 0x08, 0x01, 0xcc},
2120 {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, 2227 {0xb3, 0x09, 0x0c, 0xcc},
2121 {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, 2228 {0xb3, 0x02, 0x02, 0xcc},
2122 {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, 2229 {0xb3, 0x03, 0x1f, 0xcc},
2123 {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, 2230 {0xb3, 0x14, 0x00, 0xcc},
2124 {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, 2231 {0xb3, 0x15, 0x00, 0xcc},
2125 {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, 2232 {0xb3, 0x16, 0x02, 0xcc},
2126 {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, 2233 {0xb3, 0x17, 0x7f, 0xcc},
2127 {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, 2234 {0xb3, 0x04, 0x05, 0xcc},
2128 {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, 2235 {0xb3, 0x20, 0x00, 0xcc},
2129 {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, 2236 {0xb3, 0x21, 0x00, 0xcc},
2130 {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, 2237 {0xb3, 0x22, 0x01, 0xcc},
2131 {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, 2238 {0xb3, 0x23, 0xe0, 0xcc},
2132 {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, 2239 {0xbc, 0x00, 0xd1, 0xcc},
2133 {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, 2240 {0xbc, 0x01, 0x01, 0xcc},
2134 {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, 2241 {0x00, 0x12, 0x80, 0xaa},
2135 {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, 2242 {0x00, 0x00, 0x20, 0xdd},
2136 {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, 2243 {0x00, 0x12, 0x00, 0xaa},
2137 {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, 2244 {0x00, 0x11, 0x40, 0xaa},
2138 {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, 2245 {0x00, 0x6b, 0x0a, 0xaa},
2139 {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, 2246 {0x00, 0x3a, 0x04, 0xaa},
2140 {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, 2247 {0x00, 0x40, 0xc0, 0xaa},
2141 {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, 2248 {0x00, 0x8c, 0x00, 0xaa},
2142 {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 2249 {0x00, 0x7a, 0x29, 0xaa},
2250 {0x00, 0x7b, 0x0e, 0xaa},
2251 {0x00, 0x7c, 0x1a, 0xaa},
2252 {0x00, 0x7d, 0x31, 0xaa},
2253 {0x00, 0x7e, 0x53, 0xaa},
2254 {0x00, 0x7f, 0x60, 0xaa},
2255 {0x00, 0x80, 0x6b, 0xaa},
2256 {0x00, 0x81, 0x73, 0xaa},
2257 {0x00, 0x82, 0x7b, 0xaa},
2258 {0x00, 0x83, 0x82, 0xaa},
2259 {0x00, 0x84, 0x89, 0xaa},
2260 {0x00, 0x85, 0x96, 0xaa},
2261 {0x00, 0x86, 0xa1, 0xaa},
2262 {0x00, 0x87, 0xb7, 0xaa},
2263 {0x00, 0x88, 0xcc, 0xaa},
2264 {0x00, 0x89, 0xe1, 0xaa},
2265 {0x00, 0x13, 0xe0, 0xaa},
2266 {0x00, 0x00, 0x00, 0xaa},
2267 {0x00, 0x10, 0x00, 0xaa},
2268 {0x00, 0x0d, 0x40, 0xaa},
2269 {0x00, 0x14, 0x28, 0xaa},
2270 {0x00, 0xa5, 0x05, 0xaa},
2271 {0x00, 0xab, 0x07, 0xaa},
2272 {0x00, 0x24, 0x95, 0xaa},
2273 {0x00, 0x25, 0x33, 0xaa},
2274 {0x00, 0x26, 0xe3, 0xaa},
2275 {0x00, 0x9f, 0x88, 0xaa},
2276 {0x00, 0xa0, 0x78, 0xaa},
2277 {0x00, 0x55, 0x90, 0xaa},
2278 {0x00, 0xa1, 0x03, 0xaa},
2279 {0x00, 0xa6, 0xe0, 0xaa},
2280 {0x00, 0xa7, 0xd8, 0xaa},
2281 {0x00, 0xa8, 0xf0, 0xaa},
2282 {0x00, 0xa9, 0x90, 0xaa},
2283 {0x00, 0xaa, 0x14, 0xaa},
2284 {0x00, 0x13, 0xe5, 0xaa},
2285 {0x00, 0x0e, 0x61, 0xaa},
2286 {0x00, 0x0f, 0x4b, 0xaa},
2287 {0x00, 0x16, 0x02, 0xaa},
2143 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */ 2288 {0x00, 0x1e, 0x07, 0xaa}, /* MVFP */
2144 {0x00, 0x21, 0x02, 0xaa}, 2289 {0x00, 0x21, 0x02, 0xaa},
2145 {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, 2290 {0x00, 0x22, 0x91, 0xaa},
2146 {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, 2291 {0x00, 0x29, 0x07, 0xaa},
2147 {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, 2292 {0x00, 0x33, 0x0b, 0xaa},
2148 {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, 2293 {0x00, 0x35, 0x0b, 0xaa},
2149 {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, 2294 {0x00, 0x37, 0x1d, 0xaa},
2150 {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, 2295 {0x00, 0x38, 0x71, 0xaa},
2151 {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, 2296 {0x00, 0x39, 0x2a, 0xaa},
2152 {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, 2297 {0x00, 0x3c, 0x78, 0xaa},
2153 {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, 2298 {0x00, 0x4d, 0x40, 0xaa},
2154 {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 2299 {0x00, 0x4e, 0x20, 0xaa},
2155 {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, 2300 {0x00, 0x74, 0x19, 0xaa},
2156 {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, 2301 {0x00, 0x8d, 0x4f, 0xaa},
2157 {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, 2302 {0x00, 0x8e, 0x00, 0xaa},
2158 {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, 2303 {0x00, 0x8f, 0x00, 0xaa},
2159 {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, 2304 {0x00, 0x90, 0x00, 0xaa},
2160 {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, 2305 {0x00, 0x91, 0x00, 0xaa},
2161 {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, 2306 {0x00, 0x96, 0x00, 0xaa},
2162 {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, 2307 {0x00, 0x9a, 0x80, 0xaa},
2163 {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, 2308 {0x00, 0xb0, 0x84, 0xaa},
2164 {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, 2309 {0x00, 0xb1, 0x0c, 0xaa},
2165 {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, 2310 {0x00, 0xb2, 0x0e, 0xaa},
2166 {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, 2311 {0x00, 0xb3, 0x82, 0xaa},
2167 {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, 2312 {0x00, 0xb8, 0x0a, 0xaa},
2168 {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, 2313 {0x00, 0x43, 0x14, 0xaa},
2169 {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, 2314 {0x00, 0x44, 0xf0, 0xaa},
2170 {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, 2315 {0x00, 0x45, 0x45, 0xaa},
2171 {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, 2316 {0x00, 0x46, 0x63, 0xaa},
2172 {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, 2317 {0x00, 0x47, 0x2d, 0xaa},
2173 {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, 2318 {0x00, 0x48, 0x46, 0xaa},
2174 {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, 2319 {0x00, 0x59, 0x88, 0xaa},
2175 {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, 2320 {0x00, 0x5a, 0xa0, 0xaa},
2176 {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, 2321 {0x00, 0x5b, 0xc6, 0xaa},
2177 {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, 2322 {0x00, 0x5c, 0x7d, 0xaa},
2178 {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, 2323 {0x00, 0x5d, 0x5f, 0xaa},
2179 {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, 2324 {0x00, 0x5e, 0x19, 0xaa},
2180 {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, 2325 {0x00, 0x6c, 0x0a, 0xaa},
2181 {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, 2326 {0x00, 0x6d, 0x55, 0xaa},
2182 {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, 2327 {0x00, 0x6e, 0x11, 0xaa},
2183 {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, 2328 {0x00, 0x6f, 0x9e, 0xaa},
2184 {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, 2329 {0x00, 0x69, 0x00, 0xaa},
2185 {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, 2330 {0x00, 0x6a, 0x40, 0xaa},
2186 {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, 2331 {0x00, 0x01, 0x40, 0xaa},
2187 {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, 2332 {0x00, 0x02, 0x40, 0xaa},
2188 {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, 2333 {0x00, 0x13, 0xe7, 0xaa},
2189 {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, 2334 {0x00, 0x5f, 0xf0, 0xaa},
2190 {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, 2335 {0x00, 0x60, 0xf0, 0xaa},
2191 {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, 2336 {0x00, 0x61, 0xf0, 0xaa},
2192 {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, 2337 {0x00, 0x27, 0xa0, 0xaa},
2193 {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, 2338 {0x00, 0x28, 0x80, 0xaa},
2194 {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, 2339 {0x00, 0x2c, 0x90, 0xaa},
2195 {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, 2340 {0x00, 0x4f, 0x66, 0xaa},
2196 {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, 2341 {0x00, 0x50, 0x66, 0xaa},
2197 {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, 2342 {0x00, 0x51, 0x00, 0xaa},
2198 {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, 2343 {0x00, 0x52, 0x22, 0xaa},
2199 {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, 2344 {0x00, 0x53, 0x5e, 0xaa},
2200 {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, 2345 {0x00, 0x54, 0x80, 0xaa},
2201 {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, 2346 {0x00, 0x58, 0x9e, 0xaa},
2202 {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, 2347 {0x00, 0x41, 0x08, 0xaa},
2203 {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, 2348 {0x00, 0x3f, 0x00, 0xaa},
2204 {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, 2349 {0x00, 0x75, 0x85, 0xaa},
2205 {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, 2350 {0x00, 0x76, 0xe1, 0xaa},
2206 {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, 2351 {0x00, 0x4c, 0x00, 0xaa},
2207 {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, 2352 {0x00, 0x77, 0x0a, 0xaa},
2208 {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, 2353 {0x00, 0x3d, 0x88, 0xaa},
2354 {0x00, 0x4b, 0x09, 0xaa},
2355 {0x00, 0xc9, 0x60, 0xaa},
2356 {0x00, 0x41, 0x38, 0xaa},
2357 {0x00, 0x62, 0x30, 0xaa},
2358 {0x00, 0x63, 0x30, 0xaa},
2359 {0x00, 0x64, 0x08, 0xaa},
2360 {0x00, 0x94, 0x07, 0xaa},
2361 {0x00, 0x95, 0x0b, 0xaa},
2362 {0x00, 0x65, 0x00, 0xaa},
2363 {0x00, 0x66, 0x05, 0xaa},
2364 {0x00, 0x56, 0x50, 0xaa},
2365 {0x00, 0x34, 0x11, 0xaa},
2366 {0x00, 0xa4, 0x88, 0xaa},
2367 {0x00, 0x96, 0x00, 0xaa},
2368 {0x00, 0x97, 0x30, 0xaa},
2369 {0x00, 0x98, 0x20, 0xaa},
2370 {0x00, 0x99, 0x30, 0xaa},
2371 {0x00, 0x9a, 0x84, 0xaa},
2372 {0x00, 0x9b, 0x29, 0xaa},
2373 {0x00, 0x9c, 0x03, 0xaa},
2374 {0x00, 0x78, 0x04, 0xaa},
2375 {0x00, 0x79, 0x01, 0xaa},
2376 {0x00, 0xc8, 0xf0, 0xaa},
2377 {0x00, 0x79, 0x0f, 0xaa},
2378 {0x00, 0xc8, 0x00, 0xaa},
2379 {0x00, 0x79, 0x10, 0xaa},
2380 {0x00, 0xc8, 0x7e, 0xaa},
2381 {0x00, 0x79, 0x0a, 0xaa},
2382 {0x00, 0xc8, 0x80, 0xaa},
2383 {0x00, 0x79, 0x0b, 0xaa},
2384 {0x00, 0xc8, 0x01, 0xaa},
2385 {0x00, 0x79, 0x0c, 0xaa},
2386 {0x00, 0xc8, 0x0f, 0xaa},
2387 {0x00, 0x79, 0x0d, 0xaa},
2388 {0x00, 0xc8, 0x20, 0xaa},
2389 {0x00, 0x79, 0x09, 0xaa},
2390 {0x00, 0xc8, 0x80, 0xaa},
2391 {0x00, 0x79, 0x02, 0xaa},
2392 {0x00, 0xc8, 0xc0, 0xaa},
2393 {0x00, 0x79, 0x03, 0xaa},
2394 {0x00, 0xc8, 0x40, 0xaa},
2395 {0x00, 0x79, 0x05, 0xaa},
2396 {0x00, 0xc8, 0x30, 0xaa},
2397 {0x00, 0x79, 0x26, 0xaa},
2398 {0x00, 0x11, 0x40, 0xaa},
2399 {0x00, 0x3a, 0x04, 0xaa},
2400 {0x00, 0x12, 0x00, 0xaa},
2401 {0x00, 0x40, 0xc0, 0xaa},
2402 {0x00, 0x8c, 0x00, 0xaa},
2403 {0x00, 0x17, 0x14, 0xaa},
2404 {0x00, 0x18, 0x02, 0xaa},
2405 {0x00, 0x32, 0x92, 0xaa},
2406 {0x00, 0x19, 0x02, 0xaa},
2407 {0x00, 0x1a, 0x7a, 0xaa},
2408 {0x00, 0x03, 0x0a, 0xaa},
2409 {0x00, 0x0c, 0x00, 0xaa},
2410 {0x00, 0x3e, 0x00, 0xaa},
2411 {0x00, 0x70, 0x3a, 0xaa},
2412 {0x00, 0x71, 0x35, 0xaa},
2413 {0x00, 0x72, 0x11, 0xaa},
2414 {0x00, 0x73, 0xf0, 0xaa},
2415 {0x00, 0xa2, 0x02, 0xaa},
2416 {0x00, 0xb1, 0x00, 0xaa},
2417 {0x00, 0xb1, 0x0c, 0xaa},
2209 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */ 2418 {0x00, 0x1e, 0x37, 0xaa}, /* MVFP */
2210 {0x00, 0xaa, 0x14, 0xaa}, 2419 {0x00, 0xaa, 0x14, 0xaa},
2211 {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, 2420 {0x00, 0x24, 0x80, 0xaa},
2212 {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, 2421 {0x00, 0x25, 0x74, 0xaa},
2213 {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, 2422 {0x00, 0x26, 0xd3, 0xaa},
2214 {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, 2423 {0x00, 0x0d, 0x00, 0xaa},
2215 {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, 2424 {0x00, 0x14, 0x18, 0xaa},
2216 {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, 2425 {0x00, 0x9d, 0x99, 0xaa},
2217 {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, 2426 {0x00, 0x9e, 0x7f, 0xaa},
2218 {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, 2427 {0x00, 0x64, 0x08, 0xaa},
2219 {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, 2428 {0x00, 0x94, 0x07, 0xaa},
2220 {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, 2429 {0x00, 0x95, 0x06, 0xaa},
2221 {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, 2430 {0x00, 0x66, 0x05, 0xaa},
2222 {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, 2431 {0x00, 0x41, 0x08, 0xaa},
2223 {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, 2432 {0x00, 0x3f, 0x00, 0xaa},
2224 {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x21, 0xcc}, 2433 {0x00, 0x75, 0x07, 0xaa},
2225 {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, 2434 {0x00, 0x76, 0xe1, 0xaa},
2226 {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, 2435 {0x00, 0x4c, 0x00, 0xaa},
2227 {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, 2436 {0x00, 0x77, 0x00, 0xaa},
2228 {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, 2437 {0x00, 0x3d, 0xc2, 0xaa},
2229 {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, 2438 {0x00, 0x4b, 0x09, 0xaa},
2230 {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, 2439 {0x00, 0xc9, 0x60, 0xaa},
2231 {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, 2440 {0x00, 0x41, 0x38, 0xaa},
2232 {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, 2441 {0xbc, 0x02, 0x18, 0xcc},
2233 {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, 2442 {0xbc, 0x03, 0x50, 0xcc},
2234 {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, 2443 {0xbc, 0x04, 0x18, 0xcc},
2235 {0x00, 0x77, 0x05, 0xaa }, 2444 {0xbc, 0x05, 0x00, 0xcc},
2445 {0xbc, 0x06, 0x00, 0xcc},
2446 {0xbc, 0x08, 0x30, 0xcc},
2447 {0xbc, 0x09, 0x40, 0xcc},
2448 {0xbc, 0x0a, 0x10, 0xcc},
2449 {0xbc, 0x0b, 0x00, 0xcc},
2450 {0xbc, 0x0c, 0x00, 0xcc},
2451 {0xbf, 0xc0, 0x26, 0xcc},
2452 {0xbf, 0xc1, 0x02, 0xcc},
2453 {0xbf, 0xcc, 0x04, 0xcc},
2454 {0xb3, 0x5c, 0x01, 0xcc},
2455 {0xb3, 0x01, 0x45, 0xcc},
2456 {0x00, 0x77, 0x05, 0xaa},
2236 {}, 2457 {},
2237}; 2458};
2238 2459
@@ -3117,6 +3338,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
3117 cam->cam_mode = bi_mode; 3338 cam->cam_mode = bi_mode;
3118 cam->nmodes = ARRAY_SIZE(bi_mode); 3339 cam->nmodes = ARRAY_SIZE(bi_mode);
3119 break; 3340 break;
3341 case SENSOR_OV7670:
3342 cam->cam_mode = bi_mode;
3343 cam->nmodes = ARRAY_SIZE(bi_mode) - 1;
3344 break;
3120 default: 3345 default:
3121 cam->cam_mode = vc0323_mode; 3346 cam->cam_mode = vc0323_mode;
3122 cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1; 3347 cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
@@ -3329,14 +3554,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
3329 else 3554 else
3330 init = ov7660_initVGA_data; /* 640x480 */ 3555 init = ov7660_initVGA_data; /* 640x480 */
3331 break; 3556 break;
3332 case SENSOR_OV7670:
3333 /*GammaT = ov7660_gamma; */
3334 /*MatrixT = ov7660_matrix; */
3335 if (mode)
3336 init = ov7670_initQVGA_JPG; /* 320x240 */
3337 else
3338 init = ov7670_initVGA_JPG; /* 640x480 */
3339 break;
3340 case SENSOR_MI0360: 3557 case SENSOR_MI0360:
3341 GammaT = mi1320_gamma; 3558 GammaT = mi1320_gamma;
3342 MatrixT = mi0360_matrix; 3559 MatrixT = mi0360_matrix;
@@ -3373,6 +3590,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
3373 MatrixT = mi1320_matrix; 3590 MatrixT = mi1320_matrix;
3374 init = mi1320_soc_init[mode]; 3591 init = mi1320_soc_init[mode];
3375 break; 3592 break;
3593 case SENSOR_OV7670:
3594 init = mode == 1 ? ov7670_InitVGA : ov7670_InitQVGA;
3595 break;
3376 case SENSOR_PO3130NC: 3596 case SENSOR_PO3130NC:
3377 GammaT = po3130_gamma; 3597 GammaT = po3130_gamma;
3378 MatrixT = po3130_matrix; 3598 MatrixT = po3130_matrix;
@@ -3426,7 +3646,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
3426 sethvflip(gspca_dev); 3646 sethvflip(gspca_dev);
3427 setlightfreq(gspca_dev); 3647 setlightfreq(gspca_dev);
3428 } 3648 }
3429 if (sd->sensor == SENSOR_POxxxx) { 3649 switch (sd->sensor) {
3650 case SENSOR_OV7670:
3651 reg_w(gspca_dev->dev, 0x87, 0xffff, 0xffff);
3652 reg_w(gspca_dev->dev, 0x88, 0xff00, 0xf0f1);
3653 reg_w(gspca_dev->dev, 0xa0, 0x0000, 0xbfff);
3654 break;
3655 case SENSOR_POxxxx:
3430 setcolors(gspca_dev); 3656 setcolors(gspca_dev);
3431 setbrightness(gspca_dev); 3657 setbrightness(gspca_dev);
3432 setcontrast(gspca_dev); 3658 setcontrast(gspca_dev);
@@ -3435,6 +3661,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
3435 msleep(80); 3661 msleep(80);
3436 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); 3662 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
3437 usb_exchange(gspca_dev, poxxxx_init_end_2); 3663 usb_exchange(gspca_dev, poxxxx_init_end_2);
3664 break;
3438 } 3665 }
3439 return 0; 3666 return 0;
3440} 3667}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 7d7814c43f92..d02aa5c8472a 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -40,7 +40,6 @@ static int force_sensor = -1;
40struct sd { 40struct sd {
41 struct gspca_dev gspca_dev; /* !! must be the first item */ 41 struct gspca_dev gspca_dev; /* !! must be the first item */
42 42
43 u8 brightness;
44 u8 contrast; 43 u8 contrast;
45 u8 gamma; 44 u8 gamma;
46 u8 autogain; 45 u8 autogain;
@@ -80,8 +79,6 @@ struct sd {
80}; 79};
81 80
82/* V4L2 controls supported by the driver */ 81/* V4L2 controls supported by the driver */
83static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 82static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 83static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 84static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
@@ -94,21 +91,6 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 91static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
95 92
96static const struct ctrl sd_ctrls[] = { 93static const struct ctrl sd_ctrls[] = {
97#define BRIGHTNESS_IDX 0
98 {
99 {
100 .id = V4L2_CID_BRIGHTNESS,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Brightness",
103 .minimum = 0,
104 .maximum = 255,
105 .step = 1,
106#define BRIGHTNESS_DEF 128
107 .default_value = BRIGHTNESS_DEF,
108 },
109 .set = sd_setbrightness,
110 .get = sd_getbrightness,
111 },
112 { 94 {
113 { 95 {
114 .id = V4L2_CID_CONTRAST, 96 .id = V4L2_CID_CONTRAST,
@@ -150,7 +132,7 @@ static const struct ctrl sd_ctrls[] = {
150 .set = sd_setautogain, 132 .set = sd_setautogain,
151 .get = sd_getautogain, 133 .get = sd_getautogain,
152 }, 134 },
153#define LIGHTFREQ_IDX 4 135#define LIGHTFREQ_IDX 3
154 { 136 {
155 { 137 {
156 .id = V4L2_CID_POWER_LINE_FREQUENCY, 138 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -6004,33 +5986,6 @@ static void setmatrix(struct gspca_dev *gspca_dev)
6004 reg_w(gspca_dev->dev, matrix[i], 0x010a + i); 5986 reg_w(gspca_dev->dev, matrix[i], 0x010a + i);
6005} 5987}
6006 5988
6007static void setbrightness(struct gspca_dev *gspca_dev)
6008{
6009 struct sd *sd = (struct sd *) gspca_dev;
6010 u8 brightness;
6011
6012 switch (sd->sensor) {
6013 case SENSOR_GC0305:
6014 case SENSOR_OV7620:
6015 case SENSOR_PAS202B:
6016 case SENSOR_PO2030:
6017 return;
6018 }
6019/*fixme: is it really write to 011d and 018d for all other sensors? */
6020 brightness = sd->brightness;
6021 reg_w(gspca_dev->dev, brightness, 0x011d);
6022 switch (sd->sensor) {
6023 case SENSOR_ADCM2700:
6024 case SENSOR_HV7131B:
6025 return;
6026 }
6027 if (brightness < 0x70)
6028 brightness += 0x10;
6029 else
6030 brightness = 0x80;
6031 reg_w(gspca_dev->dev, brightness, 0x018d);
6032}
6033
6034static void setsharpness(struct gspca_dev *gspca_dev) 5989static void setsharpness(struct gspca_dev *gspca_dev)
6035{ 5990{
6036 struct sd *sd = (struct sd *) gspca_dev; 5991 struct sd *sd = (struct sd *) gspca_dev;
@@ -6059,8 +6014,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6059 int g, i, k, adj, gp; 6014 int g, i, k, adj, gp;
6060 u8 gr[16]; 6015 u8 gr[16];
6061 static const u8 delta_tb[16] = /* delta for contrast */ 6016 static const u8 delta_tb[16] = /* delta for contrast */
6062 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 6017 {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06,
6063 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; 6018 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02};
6064 static const u8 gamma_tb[6][16] = { 6019 static const u8 gamma_tb[6][16] = {
6065 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, 6020 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
6066 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}, 6021 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff},
@@ -6082,11 +6037,11 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6082 adj = 0; 6037 adj = 0;
6083 gp = 0; 6038 gp = 0;
6084 for (i = 0; i < 16; i++) { 6039 for (i = 0; i < 16; i++) {
6085 g = Tgamma[i] - delta_tb[i] * k / 128 - adj / 2; 6040 g = Tgamma[i] - delta_tb[i] * k / 256 - adj / 2;
6086 if (g > 0xff) 6041 if (g > 0xff)
6087 g = 0xff; 6042 g = 0xff;
6088 else if (g <= 0) 6043 else if (g < 0)
6089 g = 1; 6044 g = 0;
6090 reg_w(dev, g, 0x0120 + i); /* gamma */ 6045 reg_w(dev, g, 0x0120 + i); /* gamma */
6091 if (k > 0) 6046 if (k > 0)
6092 adj--; 6047 adj--;
@@ -6203,13 +6158,13 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
6203 pas106b_50HZ, pas106b_50HZ, 6158 pas106b_50HZ, pas106b_50HZ,
6204 pas106b_60HZ, pas106b_60HZ}, 6159 pas106b_60HZ, pas106b_60HZ},
6205/* SENSOR_PAS202B 13 */ 6160/* SENSOR_PAS202B 13 */
6206 {pas202b_NoFlikerScale, pas202b_NoFliker, 6161 {pas202b_NoFliker, pas202b_NoFlikerScale,
6207 pas202b_50HZScale, pas202b_50HZ, 6162 pas202b_50HZ, pas202b_50HZScale,
6208 pas202b_60HZScale, pas202b_60HZ}, 6163 pas202b_60HZ, pas202b_60HZScale},
6209/* SENSOR_PB0330 14 */ 6164/* SENSOR_PB0330 14 */
6210 {pb0330_NoFlikerScale, pb0330_NoFliker, 6165 {pb0330_NoFliker, pb0330_NoFlikerScale,
6211 pb0330_50HZScale, pb0330_50HZ, 6166 pb0330_50HZ, pb0330_50HZScale,
6212 pb0330_60HZScale, pb0330_60HZ}, 6167 pb0330_60HZ, pb0330_60HZScale},
6213/* SENSOR_PO2030 15 */ 6168/* SENSOR_PO2030 15 */
6214 {po2030_NoFliker, po2030_NoFliker, 6169 {po2030_NoFliker, po2030_NoFliker,
6215 po2030_50HZ, po2030_50HZ, 6170 po2030_50HZ, po2030_50HZ,
@@ -6789,7 +6744,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
6789 cam->nmodes = ARRAY_SIZE(broken_vga_mode); 6744 cam->nmodes = ARRAY_SIZE(broken_vga_mode);
6790 break; 6745 break;
6791 } 6746 }
6792 sd->brightness = BRIGHTNESS_DEF;
6793 sd->contrast = CONTRAST_DEF; 6747 sd->contrast = CONTRAST_DEF;
6794 sd->gamma = gamma[sd->sensor]; 6748 sd->gamma = gamma[sd->sensor];
6795 sd->autogain = AUTOGAIN_DEF; 6749 sd->autogain = AUTOGAIN_DEF;
@@ -6797,12 +6751,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
6797 sd->quality = QUALITY_DEF; 6751 sd->quality = QUALITY_DEF;
6798 6752
6799 switch (sd->sensor) { 6753 switch (sd->sensor) {
6800 case SENSOR_GC0305:
6801 case SENSOR_OV7620:
6802 case SENSOR_PAS202B:
6803 case SENSOR_PO2030:
6804 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
6805 break;
6806 case SENSOR_HV7131B: 6754 case SENSOR_HV7131B:
6807 case SENSOR_HV7131C: 6755 case SENSOR_HV7131C:
6808 case SENSOR_OV7630C: 6756 case SENSOR_OV7630C:
@@ -6893,7 +6841,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
6893 } 6841 }
6894 6842
6895 setmatrix(gspca_dev); 6843 setmatrix(gspca_dev);
6896 setbrightness(gspca_dev);
6897 switch (sd->sensor) { 6844 switch (sd->sensor) {
6898 case SENSOR_ADCM2700: 6845 case SENSOR_ADCM2700:
6899 case SENSOR_OV7620: 6846 case SENSOR_OV7620:
@@ -7015,24 +6962,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7015 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 6962 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
7016} 6963}
7017 6964
7018static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
7019{
7020 struct sd *sd = (struct sd *) gspca_dev;
7021
7022 sd->brightness = val;
7023 if (gspca_dev->streaming)
7024 setbrightness(gspca_dev);
7025 return 0;
7026}
7027
7028static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
7029{
7030 struct sd *sd = (struct sd *) gspca_dev;
7031
7032 *val = sd->brightness;
7033 return 0;
7034}
7035
7036static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 6965static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
7037{ 6966{
7038 struct sd *sd = (struct sd *) gspca_dev; 6967 struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 2fc9865fd486..830d47b05e1d 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -373,9 +373,6 @@ static int hdpvr_probe(struct usb_interface *interface,
373 } 373 }
374#endif /* CONFIG_I2C */ 374#endif /* CONFIG_I2C */
375 375
376 /* save our data pointer in this interface device */
377 usb_set_intfdata(interface, dev);
378
379 /* let the user know what node this device is now attached to */ 376 /* let the user know what node this device is now attached to */
380 v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", 377 v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
381 video_device_node_name(dev->video_dev)); 378 video_device_node_name(dev->video_dev));
@@ -391,44 +388,24 @@ error:
391 388
392static void hdpvr_disconnect(struct usb_interface *interface) 389static void hdpvr_disconnect(struct usb_interface *interface)
393{ 390{
394 struct hdpvr_device *dev; 391 struct hdpvr_device *dev = to_hdpvr_dev(usb_get_intfdata(interface));
395
396 dev = usb_get_intfdata(interface);
397 usb_set_intfdata(interface, NULL);
398 392
393 v4l2_info(&dev->v4l2_dev, "device %s disconnected\n",
394 video_device_node_name(dev->video_dev));
399 /* prevent more I/O from starting and stop any ongoing */ 395 /* prevent more I/O from starting and stop any ongoing */
400 mutex_lock(&dev->io_mutex); 396 mutex_lock(&dev->io_mutex);
401 dev->status = STATUS_DISCONNECTED; 397 dev->status = STATUS_DISCONNECTED;
402 v4l2_device_disconnect(&dev->v4l2_dev);
403 video_unregister_device(dev->video_dev);
404 wake_up_interruptible(&dev->wait_data); 398 wake_up_interruptible(&dev->wait_data);
405 wake_up_interruptible(&dev->wait_buffer); 399 wake_up_interruptible(&dev->wait_buffer);
406 mutex_unlock(&dev->io_mutex); 400 mutex_unlock(&dev->io_mutex);
401 v4l2_device_disconnect(&dev->v4l2_dev);
407 msleep(100); 402 msleep(100);
408 flush_workqueue(dev->workqueue); 403 flush_workqueue(dev->workqueue);
409 mutex_lock(&dev->io_mutex); 404 mutex_lock(&dev->io_mutex);
410 hdpvr_cancel_queue(dev); 405 hdpvr_cancel_queue(dev);
411 destroy_workqueue(dev->workqueue);
412 mutex_unlock(&dev->io_mutex); 406 mutex_unlock(&dev->io_mutex);
413 407 video_unregister_device(dev->video_dev);
414 /* deregister I2C adapter */
415#ifdef CONFIG_I2C
416 mutex_lock(&dev->i2c_mutex);
417 if (dev->i2c_adapter)
418 i2c_del_adapter(dev->i2c_adapter);
419 kfree(dev->i2c_adapter);
420 dev->i2c_adapter = NULL;
421 mutex_unlock(&dev->i2c_mutex);
422#endif /* CONFIG_I2C */
423
424 atomic_dec(&dev_nr); 408 atomic_dec(&dev_nr);
425
426 v4l2_info(&dev->v4l2_dev, "device %s disconnected\n",
427 video_device_node_name(dev->video_dev));
428
429 v4l2_device_unregister(&dev->v4l2_dev);
430 kfree(dev->usbc_buf);
431 kfree(dev);
432} 409}
433 410
434 411
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 196f82de48f0..d2f0ee29737f 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -1214,6 +1214,24 @@ static void hdpvr_device_release(struct video_device *vdev)
1214 struct hdpvr_device *dev = video_get_drvdata(vdev); 1214 struct hdpvr_device *dev = video_get_drvdata(vdev);
1215 1215
1216 hdpvr_delete(dev); 1216 hdpvr_delete(dev);
1217 mutex_lock(&dev->io_mutex);
1218 destroy_workqueue(dev->workqueue);
1219 mutex_unlock(&dev->io_mutex);
1220
1221 v4l2_device_unregister(&dev->v4l2_dev);
1222
1223 /* deregister I2C adapter */
1224#ifdef CONFIG_I2C
1225 mutex_lock(&dev->i2c_mutex);
1226 if (dev->i2c_adapter)
1227 i2c_del_adapter(dev->i2c_adapter);
1228 kfree(dev->i2c_adapter);
1229 dev->i2c_adapter = NULL;
1230 mutex_unlock(&dev->i2c_mutex);
1231#endif /* CONFIG_I2C */
1232
1233 kfree(dev->usbc_buf);
1234 kfree(dev);
1217} 1235}
1218 1236
1219static const struct video_device hdpvr_video_template = { 1237static const struct video_device hdpvr_video_template = {
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index 49ae25d83d10..b0f046df3cd8 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -111,6 +111,11 @@ struct hdpvr_device {
111 u8 *usbc_buf; 111 u8 *usbc_buf;
112}; 112};
113 113
114static inline struct hdpvr_device *to_hdpvr_dev(struct v4l2_device *v4l2_dev)
115{
116 return container_of(v4l2_dev, struct hdpvr_device, v4l2_dev);
117}
118
114 119
115/* buffer one bulk urb of data */ 120/* buffer one bulk urb of data */
116struct hdpvr_buffer { 121struct hdpvr_buffer {
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index da18d698e7f2..29d439742653 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -61,9 +61,9 @@ module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */
61MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)"); 61MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)");
62 62
63 63
64#define DEVNAME "ir-kbd-i2c" 64#define MODULE_NAME "ir-kbd-i2c"
65#define dprintk(level, fmt, arg...) if (debug >= level) \ 65#define dprintk(level, fmt, arg...) if (debug >= level) \
66 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) 66 printk(KERN_DEBUG MODULE_NAME ": " fmt , ## arg)
67 67
68/* ----------------------------------------------------------------------- */ 68/* ----------------------------------------------------------------------- */
69 69
@@ -297,7 +297,7 @@ static void ir_work(struct work_struct *work)
297 297
298static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) 298static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
299{ 299{
300 struct ir_scancode_table *ir_codes = NULL; 300 char *ir_codes = NULL;
301 const char *name = NULL; 301 const char *name = NULL;
302 u64 ir_type = 0; 302 u64 ir_type = 0;
303 struct IR_i2c *ir; 303 struct IR_i2c *ir;
@@ -322,13 +322,13 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
322 name = "Pixelview"; 322 name = "Pixelview";
323 ir->get_key = get_key_pixelview; 323 ir->get_key = get_key_pixelview;
324 ir_type = IR_TYPE_OTHER; 324 ir_type = IR_TYPE_OTHER;
325 ir_codes = &ir_codes_empty_table; 325 ir_codes = RC_MAP_EMPTY;
326 break; 326 break;
327 case 0x4b: 327 case 0x4b:
328 name = "PV951"; 328 name = "PV951";
329 ir->get_key = get_key_pv951; 329 ir->get_key = get_key_pv951;
330 ir_type = IR_TYPE_OTHER; 330 ir_type = IR_TYPE_OTHER;
331 ir_codes = &ir_codes_pv951_table; 331 ir_codes = RC_MAP_PV951;
332 break; 332 break;
333 case 0x18: 333 case 0x18:
334 case 0x1f: 334 case 0x1f:
@@ -337,22 +337,22 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
337 ir->get_key = get_key_haup; 337 ir->get_key = get_key_haup;
338 ir_type = IR_TYPE_RC5; 338 ir_type = IR_TYPE_RC5;
339 if (hauppauge == 1) { 339 if (hauppauge == 1) {
340 ir_codes = &ir_codes_hauppauge_new_table; 340 ir_codes = RC_MAP_HAUPPAUGE_NEW;
341 } else { 341 } else {
342 ir_codes = &ir_codes_rc5_tv_table; 342 ir_codes = RC_MAP_RC5_TV;
343 } 343 }
344 break; 344 break;
345 case 0x30: 345 case 0x30:
346 name = "KNC One"; 346 name = "KNC One";
347 ir->get_key = get_key_knc1; 347 ir->get_key = get_key_knc1;
348 ir_type = IR_TYPE_OTHER; 348 ir_type = IR_TYPE_OTHER;
349 ir_codes = &ir_codes_empty_table; 349 ir_codes = RC_MAP_EMPTY;
350 break; 350 break;
351 case 0x6b: 351 case 0x6b:
352 name = "FusionHDTV"; 352 name = "FusionHDTV";
353 ir->get_key = get_key_fusionhdtv; 353 ir->get_key = get_key_fusionhdtv;
354 ir_type = IR_TYPE_RC5; 354 ir_type = IR_TYPE_RC5;
355 ir_codes = &ir_codes_fusionhdtv_mce_table; 355 ir_codes = RC_MAP_FUSIONHDTV_MCE;
356 break; 356 break;
357 case 0x0b: 357 case 0x0b:
358 case 0x47: 358 case 0x47:
@@ -365,9 +365,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
365 ir_type = IR_TYPE_RC5; 365 ir_type = IR_TYPE_RC5;
366 ir->get_key = get_key_haup_xvr; 366 ir->get_key = get_key_haup_xvr;
367 if (hauppauge == 1) { 367 if (hauppauge == 1) {
368 ir_codes = &ir_codes_hauppauge_new_table; 368 ir_codes = RC_MAP_HAUPPAUGE_NEW;
369 } else { 369 } else {
370 ir_codes = &ir_codes_rc5_tv_table; 370 ir_codes = RC_MAP_RC5_TV;
371 } 371 }
372 } else { 372 } else {
373 /* Handled by saa7134-input */ 373 /* Handled by saa7134-input */
@@ -379,7 +379,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
379 name = "AVerMedia Cardbus remote"; 379 name = "AVerMedia Cardbus remote";
380 ir->get_key = get_key_avermedia_cardbus; 380 ir->get_key = get_key_avermedia_cardbus;
381 ir_type = IR_TYPE_OTHER; 381 ir_type = IR_TYPE_OTHER;
382 ir_codes = &ir_codes_avermedia_cardbus_table; 382 ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
383 break; 383 break;
384 } 384 }
385 385
@@ -447,11 +447,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
447 input_dev->name = ir->name; 447 input_dev->name = ir->name;
448 input_dev->phys = ir->phys; 448 input_dev->phys = ir->phys;
449 449
450 err = ir_input_register(ir->input, ir->ir_codes, NULL); 450 err = ir_input_register(ir->input, ir->ir_codes, NULL, MODULE_NAME);
451 if (err) 451 if (err)
452 goto err_out_free; 452 goto err_out_free;
453 453
454 printk(DEVNAME ": %s detected at %s [%s]\n", 454 printk(MODULE_NAME ": %s detected at %s [%s]\n",
455 ir->input->name, ir->input->phys, adap->name); 455 ir->input->name, ir->input->phys, adap->name);
456 456
457 /* start polling via eventd */ 457 /* start polling via eventd */
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 9a250548be4d..1b79475ca134 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1293,7 +1293,6 @@ int ivtv_init_on_first_open(struct ivtv *itv)
1293 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); 1293 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
1294 ivtv_init_mpeg_decoder(itv); 1294 ivtv_init_mpeg_decoder(itv);
1295 } 1295 }
1296 ivtv_s_std(NULL, &fh, &itv->tuner_std);
1297 1296
1298 /* On a cx23416 this seems to be able to enable DMA to the chip? */ 1297 /* On a cx23416 this seems to be able to enable DMA to the chip? */
1299 if (!itv->has_cx23415) 1298 if (!itv->has_cx23415)
@@ -1310,6 +1309,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
1310 } 1309 }
1311 else 1310 else
1312 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); 1311 ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
1312
1313 /* For cards with video out, this call needs interrupts enabled */
1314 ivtv_s_std(NULL, &fh, &itv->tuner_std);
1315
1313 return 0; 1316 return 0;
1314} 1317}
1315 1318
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 5028e31c564a..5b45fd2b2645 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -63,6 +63,7 @@
63#include <media/v4l2-common.h> 63#include <media/v4l2-common.h>
64#include <media/v4l2-ioctl.h> 64#include <media/v4l2-ioctl.h>
65#include <media/v4l2-device.h> 65#include <media/v4l2-device.h>
66#include <media/v4l2-fh.h>
66#include <media/tuner.h> 67#include <media/tuner.h>
67#include <media/cx2341x.h> 68#include <media/cx2341x.h>
68#include <media/ir-kbd-i2c.h> 69#include <media/ir-kbd-i2c.h>
@@ -116,6 +117,9 @@
116#define IVTV_REG_VPU (0x9058) 117#define IVTV_REG_VPU (0x9058)
117#define IVTV_REG_APU (0xA064) 118#define IVTV_REG_APU (0xA064)
118 119
120/* Other registers */
121#define IVTV_REG_DEC_LINE_FIELD (0x28C0)
122
119/* debugging */ 123/* debugging */
120extern int ivtv_debug; 124extern int ivtv_debug;
121 125
@@ -372,6 +376,7 @@ struct ivtv_stream {
372}; 376};
373 377
374struct ivtv_open_id { 378struct ivtv_open_id {
379 struct v4l2_fh fh;
375 u32 open_id; /* unique ID for this file descriptor */ 380 u32 open_id; /* unique ID for this file descriptor */
376 int type; /* stream type */ 381 int type; /* stream type */
377 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ 382 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
@@ -379,6 +384,11 @@ struct ivtv_open_id {
379 struct ivtv *itv; 384 struct ivtv *itv;
380}; 385};
381 386
387static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh)
388{
389 return container_of(fh, struct ivtv_open_id, fh);
390}
391
382struct yuv_frame_info 392struct yuv_frame_info
383{ 393{
384 u32 update; 394 u32 update;
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index babcabd73c08..abf410943cc9 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -32,6 +32,7 @@
32#include "ivtv-yuv.h" 32#include "ivtv-yuv.h"
33#include "ivtv-ioctl.h" 33#include "ivtv-ioctl.h"
34#include "ivtv-cards.h" 34#include "ivtv-cards.h"
35#include <media/v4l2-event.h>
35#include <media/saa7115.h> 36#include <media/saa7115.h>
36 37
37/* This function tries to claim the stream for a specific file descriptor. 38/* This function tries to claim the stream for a specific file descriptor.
@@ -506,7 +507,7 @@ int ivtv_start_capture(struct ivtv_open_id *id)
506 507
507ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos) 508ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
508{ 509{
509 struct ivtv_open_id *id = filp->private_data; 510 struct ivtv_open_id *id = fh2id(filp->private_data);
510 struct ivtv *itv = id->itv; 511 struct ivtv *itv = id->itv;
511 struct ivtv_stream *s = &itv->streams[id->type]; 512 struct ivtv_stream *s = &itv->streams[id->type];
512 int rc; 513 int rc;
@@ -541,7 +542,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
541 542
542ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) 543ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
543{ 544{
544 struct ivtv_open_id *id = filp->private_data; 545 struct ivtv_open_id *id = fh2id(filp->private_data);
545 struct ivtv *itv = id->itv; 546 struct ivtv *itv = id->itv;
546 struct ivtv_stream *s = &itv->streams[id->type]; 547 struct ivtv_stream *s = &itv->streams[id->type];
547 struct yuv_playback_info *yi = &itv->yuv_info; 548 struct yuv_playback_info *yi = &itv->yuv_info;
@@ -711,19 +712,31 @@ retry:
711 712
712unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) 713unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
713{ 714{
714 struct ivtv_open_id *id = filp->private_data; 715 struct ivtv_open_id *id = fh2id(filp->private_data);
715 struct ivtv *itv = id->itv; 716 struct ivtv *itv = id->itv;
716 struct ivtv_stream *s = &itv->streams[id->type]; 717 struct ivtv_stream *s = &itv->streams[id->type];
717 int res = 0; 718 int res = 0;
718 719
719 /* add stream's waitq to the poll list */ 720 /* add stream's waitq to the poll list */
720 IVTV_DEBUG_HI_FILE("Decoder poll\n"); 721 IVTV_DEBUG_HI_FILE("Decoder poll\n");
721 poll_wait(filp, &s->waitq, wait);
722 722
723 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); 723 /* If there are subscribed events, then only use the new event
724 if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) || 724 API instead of the old video.h based API. */
725 test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) 725 if (!list_empty(&id->fh.events->subscribed)) {
726 res = POLLPRI; 726 poll_wait(filp, &id->fh.events->wait, wait);
727 /* Turn off the old-style vsync events */
728 clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
729 if (v4l2_event_pending(&id->fh))
730 res = POLLPRI;
731 } else {
732 /* This is the old-style API which is here only for backwards
733 compatibility. */
734 poll_wait(filp, &s->waitq, wait);
735 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
736 if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
737 test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
738 res = POLLPRI;
739 }
727 740
728 /* Allow write if buffers are available for writing */ 741 /* Allow write if buffers are available for writing */
729 if (s->q_free.buffers) 742 if (s->q_free.buffers)
@@ -733,7 +746,7 @@ unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
733 746
734unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) 747unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
735{ 748{
736 struct ivtv_open_id *id = filp->private_data; 749 struct ivtv_open_id *id = fh2id(filp->private_data);
737 struct ivtv *itv = id->itv; 750 struct ivtv *itv = id->itv;
738 struct ivtv_stream *s = &itv->streams[id->type]; 751 struct ivtv_stream *s = &itv->streams[id->type];
739 int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 752 int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
@@ -833,13 +846,16 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
833 846
834int ivtv_v4l2_close(struct file *filp) 847int ivtv_v4l2_close(struct file *filp)
835{ 848{
836 struct ivtv_open_id *id = filp->private_data; 849 struct v4l2_fh *fh = filp->private_data;
850 struct ivtv_open_id *id = fh2id(fh);
837 struct ivtv *itv = id->itv; 851 struct ivtv *itv = id->itv;
838 struct ivtv_stream *s = &itv->streams[id->type]; 852 struct ivtv_stream *s = &itv->streams[id->type];
839 853
840 IVTV_DEBUG_FILE("close %s\n", s->name); 854 IVTV_DEBUG_FILE("close %s\n", s->name);
841 855
842 v4l2_prio_close(&itv->prio, &id->prio); 856 v4l2_prio_close(&itv->prio, id->prio);
857 v4l2_fh_del(fh);
858 v4l2_fh_exit(fh);
843 859
844 /* Easy case first: this stream was never claimed by us */ 860 /* Easy case first: this stream was never claimed by us */
845 if (s->id != id->open_id) { 861 if (s->id != id->open_id) {
@@ -895,6 +911,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
895{ 911{
896 struct ivtv *itv = s->itv; 912 struct ivtv *itv = s->itv;
897 struct ivtv_open_id *item; 913 struct ivtv_open_id *item;
914 int res = 0;
898 915
899 IVTV_DEBUG_FILE("open %s\n", s->name); 916 IVTV_DEBUG_FILE("open %s\n", s->name);
900 917
@@ -915,17 +932,27 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
915 } 932 }
916 933
917 /* Allocate memory */ 934 /* Allocate memory */
918 item = kmalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); 935 item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
919 if (NULL == item) { 936 if (NULL == item) {
920 IVTV_DEBUG_WARN("nomem on v4l2 open\n"); 937 IVTV_DEBUG_WARN("nomem on v4l2 open\n");
921 return -ENOMEM; 938 return -ENOMEM;
922 } 939 }
940 v4l2_fh_init(&item->fh, s->vdev);
941 if (s->type == IVTV_DEC_STREAM_TYPE_YUV ||
942 s->type == IVTV_DEC_STREAM_TYPE_MPG) {
943 res = v4l2_event_alloc(&item->fh, 60);
944 }
945 if (res < 0) {
946 v4l2_fh_exit(&item->fh);
947 kfree(item);
948 return res;
949 }
923 item->itv = itv; 950 item->itv = itv;
924 item->type = s->type; 951 item->type = s->type;
925 v4l2_prio_open(&itv->prio, &item->prio); 952 v4l2_prio_open(&itv->prio, &item->prio);
926 953
927 item->open_id = itv->open_id++; 954 item->open_id = itv->open_id++;
928 filp->private_data = item; 955 filp->private_data = &item->fh;
929 956
930 if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { 957 if (item->type == IVTV_ENC_STREAM_TYPE_RAD) {
931 /* Try to claim this stream */ 958 /* Try to claim this stream */
@@ -940,6 +967,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
940 /* switching to radio while capture is 967 /* switching to radio while capture is
941 in progress is not polite */ 968 in progress is not polite */
942 ivtv_release_stream(s); 969 ivtv_release_stream(s);
970 v4l2_fh_exit(&item->fh);
943 kfree(item); 971 kfree(item);
944 return -EBUSY; 972 return -EBUSY;
945 } 973 }
@@ -970,6 +998,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
970 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 998 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
971 itv->yuv_info.stream_size = 0; 999 itv->yuv_info.stream_size = 0;
972 } 1000 }
1001 v4l2_fh_add(&item->fh);
973 return 0; 1002 return 0;
974} 1003}
975 1004
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 2ee03c2a1b58..a5b92d109c6c 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -193,7 +193,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
193 /* Our default information for ir-kbd-i2c.c to use */ 193 /* Our default information for ir-kbd-i2c.c to use */
194 switch (hw) { 194 switch (hw) {
195 case IVTV_HW_I2C_IR_RX_AVER: 195 case IVTV_HW_I2C_IR_RX_AVER:
196 init_data->ir_codes = &ir_codes_avermedia_cardbus_table; 196 init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
197 init_data->internal_get_key_func = 197 init_data->internal_get_key_func =
198 IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; 198 IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
199 init_data->type = IR_TYPE_OTHER; 199 init_data->type = IR_TYPE_OTHER;
@@ -202,14 +202,14 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
202 case IVTV_HW_I2C_IR_RX_HAUP_EXT: 202 case IVTV_HW_I2C_IR_RX_HAUP_EXT:
203 case IVTV_HW_I2C_IR_RX_HAUP_INT: 203 case IVTV_HW_I2C_IR_RX_HAUP_INT:
204 /* Default to old black remote */ 204 /* Default to old black remote */
205 init_data->ir_codes = &ir_codes_rc5_tv_table; 205 init_data->ir_codes = RC_MAP_RC5_TV;
206 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; 206 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
207 init_data->type = IR_TYPE_RC5; 207 init_data->type = IR_TYPE_RC5;
208 init_data->name = itv->card_name; 208 init_data->name = itv->card_name;
209 break; 209 break;
210 case IVTV_HW_Z8F0811_IR_RX_HAUP: 210 case IVTV_HW_Z8F0811_IR_RX_HAUP:
211 /* Default to grey remote */ 211 /* Default to grey remote */
212 init_data->ir_codes = &ir_codes_hauppauge_new_table; 212 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
213 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 213 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
214 init_data->type = IR_TYPE_RC5; 214 init_data->type = IR_TYPE_RC5;
215 init_data->name = itv->card_name; 215 init_data->name = itv->card_name;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 99f3c39a118b..fa9f0d958f96 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -35,6 +35,7 @@
35#include <media/saa7127.h> 35#include <media/saa7127.h>
36#include <media/tveeprom.h> 36#include <media/tveeprom.h>
37#include <media/v4l2-chip-ident.h> 37#include <media/v4l2-chip-ident.h>
38#include <media/v4l2-event.h>
38#include <linux/dvb/audio.h> 39#include <linux/dvb/audio.h>
39#include <linux/i2c-id.h> 40#include <linux/i2c-id.h>
40 41
@@ -391,7 +392,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
391 return 0; 392 return 0;
392 } 393 }
393 394
394 v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); 395 v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
395 vbifmt->service_set = ivtv_get_service_set(vbifmt); 396 vbifmt->service_set = ivtv_get_service_set(vbifmt);
396 return 0; 397 return 0;
397} 398}
@@ -597,7 +598,7 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
597 return -EBUSY; 598 return -EBUSY;
598 itv->vbi.sliced_in->service_set = 0; 599 itv->vbi.sliced_in->service_set = 0;
599 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; 600 itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
600 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); 601 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
601 return ivtv_g_fmt_vbi_cap(file, fh, fmt); 602 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
602} 603}
603 604
@@ -615,7 +616,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
615 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) 616 if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
616 return -EBUSY; 617 return -EBUSY;
617 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 618 itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
618 v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); 619 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
619 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); 620 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
620 return 0; 621 return 0;
621} 622}
@@ -1087,8 +1088,10 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1087 1088
1088int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) 1089int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1089{ 1090{
1091 DEFINE_WAIT(wait);
1090 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1092 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1091 struct yuv_playback_info *yi = &itv->yuv_info; 1093 struct yuv_playback_info *yi = &itv->yuv_info;
1094 int f;
1092 1095
1093 if ((*std & V4L2_STD_ALL) == 0) 1096 if ((*std & V4L2_STD_ALL) == 0)
1094 return -EINVAL; 1097 return -EINVAL;
@@ -1128,6 +1131,25 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1128 itv->is_out_60hz = itv->is_60hz; 1131 itv->is_out_60hz = itv->is_60hz;
1129 itv->is_out_50hz = itv->is_50hz; 1132 itv->is_out_50hz = itv->is_50hz;
1130 ivtv_call_all(itv, video, s_std_output, itv->std_out); 1133 ivtv_call_all(itv, video, s_std_output, itv->std_out);
1134
1135 /*
1136 * The next firmware call is time sensitive. Time it to
1137 * avoid risk of a hard lock, by trying to ensure the call
1138 * happens within the first 100 lines of the top field.
1139 * Make 4 attempts to sync to the decoder before giving up.
1140 */
1141 for (f = 0; f < 4; f++) {
1142 prepare_to_wait(&itv->vsync_waitq, &wait,
1143 TASK_UNINTERRUPTIBLE);
1144 if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
1145 break;
1146 schedule_timeout(msecs_to_jiffies(25));
1147 }
1148 finish_wait(&itv->vsync_waitq, &wait);
1149
1150 if (f == 4)
1151 IVTV_WARN("Mode change failed to sync to decoder\n");
1152
1131 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); 1153 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1132 itv->main_rect.left = itv->main_rect.top = 0; 1154 itv->main_rect.left = itv->main_rect.top = 0;
1133 itv->main_rect.width = 720; 1155 itv->main_rect.width = 720;
@@ -1431,6 +1453,18 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1431 return 0; 1453 return 0;
1432} 1454}
1433 1455
1456static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
1457{
1458 switch (sub->type) {
1459 case V4L2_EVENT_VSYNC:
1460 case V4L2_EVENT_EOS:
1461 break;
1462 default:
1463 return -EINVAL;
1464 }
1465 return v4l2_event_subscribe(fh, sub);
1466}
1467
1434static int ivtv_log_status(struct file *file, void *fh) 1468static int ivtv_log_status(struct file *file, void *fh)
1435{ 1469{
1436 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1470 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
@@ -1539,10 +1573,11 @@ static int ivtv_log_status(struct file *file, void *fh)
1539 1573
1540static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) 1574static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1541{ 1575{
1542 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1576 struct ivtv_open_id *id = fh2id(filp->private_data);
1543 struct ivtv *itv = id->itv; 1577 struct ivtv *itv = id->itv;
1544 int nonblocking = filp->f_flags & O_NONBLOCK; 1578 int nonblocking = filp->f_flags & O_NONBLOCK;
1545 struct ivtv_stream *s = &itv->streams[id->type]; 1579 struct ivtv_stream *s = &itv->streams[id->type];
1580 unsigned long iarg = (unsigned long)arg;
1546 1581
1547 switch (cmd) { 1582 switch (cmd) {
1548 case IVTV_IOC_DMA_FRAME: { 1583 case IVTV_IOC_DMA_FRAME: {
@@ -1724,6 +1759,33 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1724 break; 1759 break;
1725 } 1760 }
1726 1761
1762 case VIDEO_SELECT_SOURCE:
1763 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1764 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1765 return -EINVAL;
1766 return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
1767
1768 case AUDIO_SET_MUTE:
1769 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1770 itv->speed_mute_audio = iarg;
1771 return 0;
1772
1773 case AUDIO_CHANNEL_SELECT:
1774 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1775 if (iarg > AUDIO_STEREO_SWAPPED)
1776 return -EINVAL;
1777 itv->audio_stereo_mode = iarg;
1778 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1779 return 0;
1780
1781 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1782 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1783 if (iarg > AUDIO_STEREO_SWAPPED)
1784 return -EINVAL;
1785 itv->audio_bilingual_mode = iarg;
1786 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1787 return 0;
1788
1727 default: 1789 default:
1728 return -EINVAL; 1790 return -EINVAL;
1729 } 1791 }
@@ -1755,6 +1817,10 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
1755 case VIDEO_CONTINUE: 1817 case VIDEO_CONTINUE:
1756 case VIDEO_COMMAND: 1818 case VIDEO_COMMAND:
1757 case VIDEO_TRY_COMMAND: 1819 case VIDEO_TRY_COMMAND:
1820 case VIDEO_SELECT_SOURCE:
1821 case AUDIO_SET_MUTE:
1822 case AUDIO_CHANNEL_SELECT:
1823 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1758 return ivtv_decoder_ioctls(file, cmd, (void *)arg); 1824 return ivtv_decoder_ioctls(file, cmd, (void *)arg);
1759 1825
1760 default: 1826 default:
@@ -1767,42 +1833,9 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1767 unsigned int cmd, unsigned long arg) 1833 unsigned int cmd, unsigned long arg)
1768{ 1834{
1769 struct video_device *vfd = video_devdata(filp); 1835 struct video_device *vfd = video_devdata(filp);
1770 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1836 struct ivtv_open_id *id = fh2id(filp->private_data);
1771 long ret; 1837 long ret;
1772 1838
1773 /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */
1774 switch (cmd) {
1775 case VIDEO_SELECT_SOURCE:
1776 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1777 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1778 return -EINVAL;
1779 return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);
1780
1781 case AUDIO_SET_MUTE:
1782 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1783 itv->speed_mute_audio = arg;
1784 return 0;
1785
1786 case AUDIO_CHANNEL_SELECT:
1787 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1788 if (arg > AUDIO_STEREO_SWAPPED)
1789 return -EINVAL;
1790 itv->audio_stereo_mode = arg;
1791 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1792 return 0;
1793
1794 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1795 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1796 if (arg > AUDIO_STEREO_SWAPPED)
1797 return -EINVAL;
1798 itv->audio_bilingual_mode = arg;
1799 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1800 return 0;
1801
1802 default:
1803 break;
1804 }
1805
1806 /* check priority */ 1839 /* check priority */
1807 switch (cmd) { 1840 switch (cmd) {
1808 case VIDIOC_S_CTRL: 1841 case VIDIOC_S_CTRL:
@@ -1817,8 +1850,9 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1817 case VIDIOC_S_AUDOUT: 1850 case VIDIOC_S_AUDOUT:
1818 case VIDIOC_S_EXT_CTRLS: 1851 case VIDIOC_S_EXT_CTRLS:
1819 case VIDIOC_S_FBUF: 1852 case VIDIOC_S_FBUF:
1853 case VIDIOC_S_PRIORITY:
1820 case VIDIOC_OVERLAY: 1854 case VIDIOC_OVERLAY:
1821 ret = v4l2_prio_check(&itv->prio, &id->prio); 1855 ret = v4l2_prio_check(&itv->prio, id->prio);
1822 if (ret) 1856 if (ret)
1823 return ret; 1857 return ret;
1824 } 1858 }
@@ -1832,10 +1866,13 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1832 1866
1833long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 1867long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1834{ 1868{
1835 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1869 struct ivtv_open_id *id = fh2id(filp->private_data);
1836 struct ivtv *itv = id->itv; 1870 struct ivtv *itv = id->itv;
1837 long res; 1871 long res;
1838 1872
1873 /* DQEVENT can block, so this should not run with the serialize lock */
1874 if (cmd == VIDIOC_DQEVENT)
1875 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
1839 mutex_lock(&itv->serialize_lock); 1876 mutex_lock(&itv->serialize_lock);
1840 res = ivtv_serialized_ioctl(itv, filp, cmd, arg); 1877 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
1841 mutex_unlock(&itv->serialize_lock); 1878 mutex_unlock(&itv->serialize_lock);
@@ -1906,6 +1943,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1906 .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, 1943 .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls,
1907 .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, 1944 .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls,
1908 .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, 1945 .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls,
1946 .vidioc_subscribe_event = ivtv_subscribe_event,
1947 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1909}; 1948};
1910 1949
1911void ivtv_set_funcs(struct video_device *vdev) 1950void ivtv_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index 12d36ca91d53..fea1ec33b0df 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -25,6 +25,7 @@
25#include "ivtv-mailbox.h" 25#include "ivtv-mailbox.h"
26#include "ivtv-vbi.h" 26#include "ivtv-vbi.h"
27#include "ivtv-yuv.h" 27#include "ivtv-yuv.h"
28#include <media/v4l2-event.h>
28 29
29#define DMA_MAGIC_COOKIE 0x000001fe 30#define DMA_MAGIC_COOKIE 0x000001fe
30 31
@@ -752,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
752 * to determine the line being displayed and ensure we handle 753 * to determine the line being displayed and ensure we handle
753 * one vsync per frame. 754 * one vsync per frame.
754 */ 755 */
755 unsigned int frame = read_reg(0x28c0) & 1; 756 unsigned int frame = read_reg(IVTV_REG_DEC_LINE_FIELD) & 1;
756 struct yuv_playback_info *yi = &itv->yuv_info; 757 struct yuv_playback_info *yi = &itv->yuv_info;
757 int last_dma_frame = atomic_read(&yi->next_dma_frame); 758 int last_dma_frame = atomic_read(&yi->next_dma_frame);
758 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; 759 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
@@ -778,6 +779,14 @@ static void ivtv_irq_vsync(struct ivtv *itv)
778 } 779 }
779 } 780 }
780 if (frame != (itv->last_vsync_field & 1)) { 781 if (frame != (itv->last_vsync_field & 1)) {
782 static const struct v4l2_event evtop = {
783 .type = V4L2_EVENT_VSYNC,
784 .u.vsync.field = V4L2_FIELD_TOP,
785 };
786 static const struct v4l2_event evbottom = {
787 .type = V4L2_EVENT_VSYNC,
788 .u.vsync.field = V4L2_FIELD_BOTTOM,
789 };
781 struct ivtv_stream *s = ivtv_get_output_stream(itv); 790 struct ivtv_stream *s = ivtv_get_output_stream(itv);
782 791
783 itv->last_vsync_field += 1; 792 itv->last_vsync_field += 1;
@@ -791,10 +800,12 @@ static void ivtv_irq_vsync(struct ivtv *itv)
791 if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) { 800 if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
792 set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags); 801 set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
793 wake_up(&itv->event_waitq); 802 wake_up(&itv->event_waitq);
803 if (s)
804 wake_up(&s->waitq);
794 } 805 }
806 if (s && s->vdev)
807 v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom);
795 wake_up(&itv->vsync_waitq); 808 wake_up(&itv->vsync_waitq);
796 if (s)
797 wake_up(&s->waitq);
798 809
799 /* Send VBI to saa7127 */ 810 /* Send VBI to saa7127 */
800 if (frame && (itv->output_mode == OUT_PASSTHROUGH || 811 if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
@@ -852,9 +863,11 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
852 */ 863 */
853 if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) { 864 if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
854 /* vsync is enabled, see if we're in a new field */ 865 /* vsync is enabled, see if we're in a new field */
855 if ((itv->last_vsync_field & 1) != (read_reg(0x28c0) & 1)) { 866 if ((itv->last_vsync_field & 1) !=
867 (read_reg(IVTV_REG_DEC_LINE_FIELD) & 1)) {
856 /* New field, looks like we missed it */ 868 /* New field, looks like we missed it */
857 IVTV_DEBUG_YUV("VSync interrupt missed %d\n",read_reg(0x28c0)>>16); 869 IVTV_DEBUG_YUV("VSync interrupt missed %d\n",
870 read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16);
858 vsync_force = 1; 871 vsync_force = 1;
859 } 872 }
860 } 873 }
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 1f9387f6ca24..de4288cc1889 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -42,6 +42,7 @@
42#include "ivtv-yuv.h" 42#include "ivtv-yuv.h"
43#include "ivtv-cards.h" 43#include "ivtv-cards.h"
44#include "ivtv-streams.h" 44#include "ivtv-streams.h"
45#include <media/v4l2-event.h>
45 46
46static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { 47static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
47 .owner = THIS_MODULE, 48 .owner = THIS_MODULE,
@@ -343,7 +344,10 @@ static void ivtv_vbi_setup(struct ivtv *itv)
343 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0); 344 ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0);
344 345
345 /* setup VBI registers */ 346 /* setup VBI registers */
346 v4l2_subdev_call(itv->sd_video, video, s_fmt, &itv->vbi.in); 347 if (raw)
348 v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &itv->vbi.in.fmt.vbi);
349 else
350 v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, &itv->vbi.in.fmt.sliced);
347 351
348 /* determine number of lines and total number of VBI bytes. 352 /* determine number of lines and total number of VBI bytes.
349 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1 353 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
@@ -581,10 +585,9 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
581 v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1); 585 v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
582 /* Avoid unpredictable PCI bus hang - disable video clocks */ 586 /* Avoid unpredictable PCI bus hang - disable video clocks */
583 v4l2_subdev_call(itv->sd_video, video, s_stream, 0); 587 v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
584 ivtv_msleep_timeout(150, 1); 588 ivtv_msleep_timeout(300, 1);
585 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); 589 ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
586 v4l2_subdev_call(itv->sd_video, video, s_stream, 1); 590 v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
587 ivtv_msleep_timeout(150, 1);
588 } 591 }
589 592
590 /* begin_capture */ 593 /* begin_capture */
@@ -830,6 +833,10 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
830 ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); 833 ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
831 } 834 }
832 835
836 /* Raw-passthrough is implied on start. Make sure it's stopped so
837 the encoder will re-initialize when next started */
838 ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 7);
839
833 wake_up(&s->waitq); 840 wake_up(&s->waitq);
834 841
835 return 0; 842 return 0;
@@ -837,6 +844,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
837 844
838int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) 845int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
839{ 846{
847 static const struct v4l2_event ev = {
848 .type = V4L2_EVENT_EOS,
849 };
840 struct ivtv *itv = s->itv; 850 struct ivtv *itv = s->itv;
841 851
842 if (s->vdev == NULL) 852 if (s->vdev == NULL)
@@ -888,6 +898,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
888 898
889 set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); 899 set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags);
890 wake_up(&itv->event_waitq); 900 wake_up(&itv->event_waitq);
901 v4l2_event_queue(s->vdev, &ev);
891 902
892 /* wake up wait queues */ 903 /* wake up wait queues */
893 wake_up(&s->waitq); 904 wake_up(&s->waitq);
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index f420d31b937d..e1c347e5ebd8 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -38,7 +38,7 @@ static void ivtv_set_vps(struct ivtv *itv, int enabled)
38 data.data[9] = itv->vbi.vps_payload.data[2]; 38 data.data[9] = itv->vbi.vps_payload.data[2];
39 data.data[10] = itv->vbi.vps_payload.data[3]; 39 data.data[10] = itv->vbi.vps_payload.data[3];
40 data.data[11] = itv->vbi.vps_payload.data[4]; 40 data.data[11] = itv->vbi.vps_payload.data[4];
41 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); 41 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
42} 42}
43 43
44static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc) 44static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
@@ -52,12 +52,12 @@ static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
52 data.line = (mode & 1) ? 21 : 0; 52 data.line = (mode & 1) ? 21 : 0;
53 data.data[0] = cc->odd[0]; 53 data.data[0] = cc->odd[0];
54 data.data[1] = cc->odd[1]; 54 data.data[1] = cc->odd[1];
55 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); 55 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
56 data.field = 1; 56 data.field = 1;
57 data.line = (mode & 2) ? 21 : 0; 57 data.line = (mode & 2) ? 21 : 0;
58 data.data[0] = cc->even[0]; 58 data.data[0] = cc->even[0];
59 data.data[1] = cc->even[1]; 59 data.data[1] = cc->even[1];
60 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); 60 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
61} 61}
62 62
63static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode) 63static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
@@ -80,7 +80,7 @@ static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
80 data.line = enabled ? 23 : 0; 80 data.line = enabled ? 23 : 0;
81 data.data[0] = mode & 0xff; 81 data.data[0] = mode & 0xff;
82 data.data[1] = (mode >> 8) & 0xff; 82 data.data[1] = (mode >> 8) & 0xff;
83 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); 83 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
84} 84}
85 85
86static int odd_parity(u8 c) 86static int odd_parity(u8 c)
@@ -134,7 +134,7 @@ void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced,
134 } 134 }
135 } 135 }
136 } 136 }
137 if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) { 137 if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
138 vi->cc_payload[vi->cc_payload_idx++] = cc; 138 vi->cc_payload[vi->cc_payload_idx++] = cc;
139 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); 139 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
140 } 140 }
@@ -316,7 +316,7 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
316 continue; 316 continue;
317 } 317 }
318 vbi.p = p + 4; 318 vbi.p = p + 4;
319 v4l2_subdev_call(itv->sd_video, video, decode_vbi_line, &vbi); 319 v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi);
320 if (vbi.type && !(lines & (1 << vbi.line))) { 320 if (vbi.type && !(lines & (1 << vbi.line))) {
321 lines |= 1 << vbi.line; 321 lines |= 1 << vbi.line;
322 itv->vbi.sliced_data[line].id = vbi.type; 322 itv->vbi.sliced_data[line].id = vbi.type;
@@ -440,7 +440,7 @@ void ivtv_vbi_work_handler(struct ivtv *itv)
440 data.id = V4L2_SLICED_WSS_625; 440 data.id = V4L2_SLICED_WSS_625;
441 data.field = 0; 441 data.field = 0;
442 442
443 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) { 443 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
444 ivtv_set_wss(itv, 1, data.data[0] & 0xf); 444 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
445 vi->wss_missing_cnt = 0; 445 vi->wss_missing_cnt = 0;
446 } else if (vi->wss_missing_cnt == 4) { 446 } else if (vi->wss_missing_cnt == 4) {
@@ -454,13 +454,13 @@ void ivtv_vbi_work_handler(struct ivtv *itv)
454 454
455 data.id = V4L2_SLICED_CAPTION_525; 455 data.id = V4L2_SLICED_CAPTION_525;
456 data.field = 0; 456 data.field = 0;
457 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) { 457 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
458 mode |= 1; 458 mode |= 1;
459 cc.odd[0] = data.data[0]; 459 cc.odd[0] = data.data[0];
460 cc.odd[1] = data.data[1]; 460 cc.odd[1] = data.data[1];
461 } 461 }
462 data.field = 1; 462 data.field = 1;
463 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) { 463 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
464 mode |= 2; 464 mode |= 2;
465 cc.even[0] = data.data[0]; 465 cc.even[0] = data.data[0];
466 cc.even[1] = data.data[1]; 466 cc.even[1] = data.data[1];
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index de2ff1c6ac34..49e1a283ed36 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -460,7 +460,7 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
460 460
461 vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | 461 vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
462 FB_VBLANK_HAVE_VSYNC; 462 FB_VBLANK_HAVE_VSYNC;
463 trace = read_reg(0x028c0) >> 16; 463 trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
464 if (itv->is_50hz && trace > 312) 464 if (itv->is_50hz && trace > 312)
465 trace -= 312; 465 trace -= 312;
466 else if (itv->is_60hz && trace > 262) 466 else if (itv->is_60hz && trace > 262)
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
new file mode 100644
index 000000000000..554eaf140128
--- /dev/null
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -0,0 +1,1052 @@
1/*
2 * A virtual v4l2-mem2mem example device.
3 *
4 * This is a virtual device driver for testing mem-to-mem videobuf framework.
5 * It simulates a device that uses memory buffers for both source and
6 * destination, processes the data and issues an "irq" (simulated by a timer).
7 * The device is capable of multi-instance, multi-buffer-per-transaction
8 * operation (via the mem2mem framework).
9 *
10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
11 * Pawel Osciak, <p.osciak@samsung.com>
12 * Marek Szyprowski, <m.szyprowski@samsung.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version
18 */
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22#include <linux/version.h>
23#include <linux/timer.h>
24#include <linux/sched.h>
25#include <linux/slab.h>
26
27#include <linux/platform_device.h>
28#include <media/v4l2-mem2mem.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-ioctl.h>
31#include <media/videobuf-vmalloc.h>
32
33#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev"
34
35MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
36MODULE_AUTHOR("Pawel Osciak, <p.osciak@samsung.com>");
37MODULE_LICENSE("GPL");
38
39
40#define MIN_W 32
41#define MIN_H 32
42#define MAX_W 640
43#define MAX_H 480
44#define DIM_ALIGN_MASK 0x08 /* 8-alignment for dimensions */
45
46/* Flags that indicate a format can be used for capture/output */
47#define MEM2MEM_CAPTURE (1 << 0)
48#define MEM2MEM_OUTPUT (1 << 1)
49
50#define MEM2MEM_NAME "m2m-testdev"
51
52/* Per queue */
53#define MEM2MEM_DEF_NUM_BUFS VIDEO_MAX_FRAME
54/* In bytes, per queue */
55#define MEM2MEM_VID_MEM_LIMIT (16 * 1024 * 1024)
56
57/* Default transaction time in msec */
58#define MEM2MEM_DEF_TRANSTIME 1000
59/* Default number of buffers per transaction */
60#define MEM2MEM_DEF_TRANSLEN 1
61#define MEM2MEM_COLOR_STEP (0xff >> 4)
62#define MEM2MEM_NUM_TILES 8
63
64#define dprintk(dev, fmt, arg...) \
65 v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
66
67
68void m2mtest_dev_release(struct device *dev)
69{}
70
71static struct platform_device m2mtest_pdev = {
72 .name = MEM2MEM_NAME,
73 .dev.release = m2mtest_dev_release,
74};
75
76struct m2mtest_fmt {
77 char *name;
78 u32 fourcc;
79 int depth;
80 /* Types the format can be used for */
81 u32 types;
82};
83
84static struct m2mtest_fmt formats[] = {
85 {
86 .name = "RGB565 (BE)",
87 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
88 .depth = 16,
89 /* Both capture and output format */
90 .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
91 },
92 {
93 .name = "4:2:2, packed, YUYV",
94 .fourcc = V4L2_PIX_FMT_YUYV,
95 .depth = 16,
96 /* Output-only format */
97 .types = MEM2MEM_OUTPUT,
98 },
99};
100
101/* Per-queue, driver-specific private data */
102struct m2mtest_q_data {
103 unsigned int width;
104 unsigned int height;
105 unsigned int sizeimage;
106 struct m2mtest_fmt *fmt;
107};
108
109enum {
110 V4L2_M2M_SRC = 0,
111 V4L2_M2M_DST = 1,
112};
113
114/* Source and destination queue data */
115static struct m2mtest_q_data q_data[2];
116
117static struct m2mtest_q_data *get_q_data(enum v4l2_buf_type type)
118{
119 switch (type) {
120 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
121 return &q_data[V4L2_M2M_SRC];
122 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
123 return &q_data[V4L2_M2M_DST];
124 default:
125 BUG();
126 }
127 return NULL;
128}
129
130#define V4L2_CID_TRANS_TIME_MSEC V4L2_CID_PRIVATE_BASE
131#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE + 1)
132
133static struct v4l2_queryctrl m2mtest_ctrls[] = {
134 {
135 .id = V4L2_CID_TRANS_TIME_MSEC,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Transaction time (msec)",
138 .minimum = 1,
139 .maximum = 10000,
140 .step = 100,
141 .default_value = 1000,
142 .flags = 0,
143 }, {
144 .id = V4L2_CID_TRANS_NUM_BUFS,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Buffers per transaction",
147 .minimum = 1,
148 .maximum = MEM2MEM_DEF_NUM_BUFS,
149 .step = 1,
150 .default_value = 1,
151 .flags = 0,
152 },
153};
154
155#define NUM_FORMATS ARRAY_SIZE(formats)
156
157static struct m2mtest_fmt *find_format(struct v4l2_format *f)
158{
159 struct m2mtest_fmt *fmt;
160 unsigned int k;
161
162 for (k = 0; k < NUM_FORMATS; k++) {
163 fmt = &formats[k];
164 if (fmt->fourcc == f->fmt.pix.pixelformat)
165 break;
166 }
167
168 if (k == NUM_FORMATS)
169 return NULL;
170
171 return &formats[k];
172}
173
174struct m2mtest_dev {
175 struct v4l2_device v4l2_dev;
176 struct video_device *vfd;
177
178 atomic_t num_inst;
179 struct mutex dev_mutex;
180 spinlock_t irqlock;
181
182 struct timer_list timer;
183
184 struct v4l2_m2m_dev *m2m_dev;
185};
186
187struct m2mtest_ctx {
188 struct m2mtest_dev *dev;
189
190 /* Processed buffers in this transaction */
191 u8 num_processed;
192
193 /* Transaction length (i.e. how many buffers per transaction) */
194 u32 translen;
195 /* Transaction time (i.e. simulated processing time) in milliseconds */
196 u32 transtime;
197
198 /* Abort requested by m2m */
199 int aborting;
200
201 struct v4l2_m2m_ctx *m2m_ctx;
202};
203
204struct m2mtest_buffer {
205 /* vb must be first! */
206 struct videobuf_buffer vb;
207};
208
209static struct v4l2_queryctrl *get_ctrl(int id)
210{
211 int i;
212
213 for (i = 0; i < ARRAY_SIZE(m2mtest_ctrls); ++i) {
214 if (id == m2mtest_ctrls[i].id)
215 return &m2mtest_ctrls[i];
216 }
217
218 return NULL;
219}
220
221static int device_process(struct m2mtest_ctx *ctx,
222 struct m2mtest_buffer *in_buf,
223 struct m2mtest_buffer *out_buf)
224{
225 struct m2mtest_dev *dev = ctx->dev;
226 u8 *p_in, *p_out;
227 int x, y, t, w;
228 int tile_w, bytes_left;
229 struct videobuf_queue *src_q;
230 struct videobuf_queue *dst_q;
231
232 src_q = v4l2_m2m_get_src_vq(ctx->m2m_ctx);
233 dst_q = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
234 p_in = videobuf_queue_to_vaddr(src_q, &in_buf->vb);
235 p_out = videobuf_queue_to_vaddr(dst_q, &out_buf->vb);
236 if (!p_in || !p_out) {
237 v4l2_err(&dev->v4l2_dev,
238 "Acquiring kernel pointers to buffers failed\n");
239 return -EFAULT;
240 }
241
242 if (in_buf->vb.size < out_buf->vb.size) {
243 v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
244 return -EINVAL;
245 }
246
247 tile_w = (in_buf->vb.width * (q_data[V4L2_M2M_DST].fmt->depth >> 3))
248 / MEM2MEM_NUM_TILES;
249 bytes_left = in_buf->vb.bytesperline - tile_w * MEM2MEM_NUM_TILES;
250 w = 0;
251
252 for (y = 0; y < in_buf->vb.height; ++y) {
253 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
254 if (w & 0x1) {
255 for (x = 0; x < tile_w; ++x)
256 *p_out++ = *p_in++ + MEM2MEM_COLOR_STEP;
257 } else {
258 for (x = 0; x < tile_w; ++x)
259 *p_out++ = *p_in++ - MEM2MEM_COLOR_STEP;
260 }
261 ++w;
262 }
263 p_in += bytes_left;
264 p_out += bytes_left;
265 }
266
267 return 0;
268}
269
270static void schedule_irq(struct m2mtest_dev *dev, int msec_timeout)
271{
272 dprintk(dev, "Scheduling a simulated irq\n");
273 mod_timer(&dev->timer, jiffies + msecs_to_jiffies(msec_timeout));
274}
275
276/*
277 * mem2mem callbacks
278 */
279
280/**
281 * job_ready() - check whether an instance is ready to be scheduled to run
282 */
283static int job_ready(void *priv)
284{
285 struct m2mtest_ctx *ctx = priv;
286
287 if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) < ctx->translen
288 || v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < ctx->translen) {
289 dprintk(ctx->dev, "Not enough buffers available\n");
290 return 0;
291 }
292
293 return 1;
294}
295
296static void job_abort(void *priv)
297{
298 struct m2mtest_ctx *ctx = priv;
299
300 /* Will cancel the transaction in the next interrupt handler */
301 ctx->aborting = 1;
302}
303
304/* device_run() - prepares and starts the device
305 *
306 * This simulates all the immediate preparations required before starting
307 * a device. This will be called by the framework when it decides to schedule
308 * a particular instance.
309 */
310static void device_run(void *priv)
311{
312 struct m2mtest_ctx *ctx = priv;
313 struct m2mtest_dev *dev = ctx->dev;
314 struct m2mtest_buffer *src_buf, *dst_buf;
315
316 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
317 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
318
319 device_process(ctx, src_buf, dst_buf);
320
321 /* Run a timer, which simulates a hardware irq */
322 schedule_irq(dev, ctx->transtime);
323}
324
325
326static void device_isr(unsigned long priv)
327{
328 struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv;
329 struct m2mtest_ctx *curr_ctx;
330 struct m2mtest_buffer *src_buf, *dst_buf;
331 unsigned long flags;
332
333 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
334
335 if (NULL == curr_ctx) {
336 printk(KERN_ERR
337 "Instance released before the end of transaction\n");
338 return;
339 }
340
341 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
342 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
343 curr_ctx->num_processed++;
344
345 if (curr_ctx->num_processed == curr_ctx->translen
346 || curr_ctx->aborting) {
347 dprintk(curr_ctx->dev, "Finishing transaction\n");
348 curr_ctx->num_processed = 0;
349 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
350 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
351 wake_up(&src_buf->vb.done);
352 wake_up(&dst_buf->vb.done);
353 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
354 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx);
355 } else {
356 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
357 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
358 wake_up(&src_buf->vb.done);
359 wake_up(&dst_buf->vb.done);
360 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
361 device_run(curr_ctx);
362 }
363}
364
365
366/*
367 * video ioctls
368 */
369static int vidioc_querycap(struct file *file, void *priv,
370 struct v4l2_capability *cap)
371{
372 strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
373 strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
374 cap->bus_info[0] = 0;
375 cap->version = KERNEL_VERSION(0, 1, 0);
376 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
377 | V4L2_CAP_STREAMING;
378
379 return 0;
380}
381
382static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
383{
384 int i, num;
385 struct m2mtest_fmt *fmt;
386
387 num = 0;
388
389 for (i = 0; i < NUM_FORMATS; ++i) {
390 if (formats[i].types & type) {
391 /* index-th format of type type found ? */
392 if (num == f->index)
393 break;
394 /* Correct type but haven't reached our index yet,
395 * just increment per-type index */
396 ++num;
397 }
398 }
399
400 if (i < NUM_FORMATS) {
401 /* Format found */
402 fmt = &formats[i];
403 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
404 f->pixelformat = fmt->fourcc;
405 return 0;
406 }
407
408 /* Format not found */
409 return -EINVAL;
410}
411
412static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
413 struct v4l2_fmtdesc *f)
414{
415 return enum_fmt(f, MEM2MEM_CAPTURE);
416}
417
418static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
419 struct v4l2_fmtdesc *f)
420{
421 return enum_fmt(f, MEM2MEM_OUTPUT);
422}
423
424static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
425{
426 struct videobuf_queue *vq;
427 struct m2mtest_q_data *q_data;
428
429 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
430 if (!vq)
431 return -EINVAL;
432
433 q_data = get_q_data(f->type);
434
435 f->fmt.pix.width = q_data->width;
436 f->fmt.pix.height = q_data->height;
437 f->fmt.pix.field = vq->field;
438 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
439 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
440 f->fmt.pix.sizeimage = q_data->sizeimage;
441
442 return 0;
443}
444
445static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
446 struct v4l2_format *f)
447{
448 return vidioc_g_fmt(priv, f);
449}
450
451static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
452 struct v4l2_format *f)
453{
454 return vidioc_g_fmt(priv, f);
455}
456
457static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
458{
459 enum v4l2_field field;
460
461 field = f->fmt.pix.field;
462
463 if (field == V4L2_FIELD_ANY)
464 field = V4L2_FIELD_NONE;
465 else if (V4L2_FIELD_NONE != field)
466 return -EINVAL;
467
468 /* V4L2 specification suggests the driver corrects the format struct
469 * if any of the dimensions is unsupported */
470 f->fmt.pix.field = field;
471
472 if (f->fmt.pix.height < MIN_H)
473 f->fmt.pix.height = MIN_H;
474 else if (f->fmt.pix.height > MAX_H)
475 f->fmt.pix.height = MAX_H;
476
477 if (f->fmt.pix.width < MIN_W)
478 f->fmt.pix.width = MIN_W;
479 else if (f->fmt.pix.width > MAX_W)
480 f->fmt.pix.width = MAX_W;
481
482 f->fmt.pix.width &= ~DIM_ALIGN_MASK;
483 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
484 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
485
486 return 0;
487}
488
489static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
490 struct v4l2_format *f)
491{
492 struct m2mtest_fmt *fmt;
493 struct m2mtest_ctx *ctx = priv;
494
495 fmt = find_format(f);
496 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
497 v4l2_err(&ctx->dev->v4l2_dev,
498 "Fourcc format (0x%08x) invalid.\n",
499 f->fmt.pix.pixelformat);
500 return -EINVAL;
501 }
502
503 return vidioc_try_fmt(f, fmt);
504}
505
506static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
507 struct v4l2_format *f)
508{
509 struct m2mtest_fmt *fmt;
510 struct m2mtest_ctx *ctx = priv;
511
512 fmt = find_format(f);
513 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
514 v4l2_err(&ctx->dev->v4l2_dev,
515 "Fourcc format (0x%08x) invalid.\n",
516 f->fmt.pix.pixelformat);
517 return -EINVAL;
518 }
519
520 return vidioc_try_fmt(f, fmt);
521}
522
523static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
524{
525 struct m2mtest_q_data *q_data;
526 struct videobuf_queue *vq;
527 int ret = 0;
528
529 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
530 if (!vq)
531 return -EINVAL;
532
533 q_data = get_q_data(f->type);
534 if (!q_data)
535 return -EINVAL;
536
537 mutex_lock(&vq->vb_lock);
538
539 if (videobuf_queue_is_busy(vq)) {
540 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
541 ret = -EBUSY;
542 goto out;
543 }
544
545 q_data->fmt = find_format(f);
546 q_data->width = f->fmt.pix.width;
547 q_data->height = f->fmt.pix.height;
548 q_data->sizeimage = q_data->width * q_data->height
549 * q_data->fmt->depth >> 3;
550 vq->field = f->fmt.pix.field;
551
552 dprintk(ctx->dev,
553 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
554 f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
555
556out:
557 mutex_unlock(&vq->vb_lock);
558 return ret;
559}
560
561static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
562 struct v4l2_format *f)
563{
564 int ret;
565
566 ret = vidioc_try_fmt_vid_cap(file, priv, f);
567 if (ret)
568 return ret;
569
570 return vidioc_s_fmt(priv, f);
571}
572
573static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
574 struct v4l2_format *f)
575{
576 int ret;
577
578 ret = vidioc_try_fmt_vid_out(file, priv, f);
579 if (ret)
580 return ret;
581
582 return vidioc_s_fmt(priv, f);
583}
584
585static int vidioc_reqbufs(struct file *file, void *priv,
586 struct v4l2_requestbuffers *reqbufs)
587{
588 struct m2mtest_ctx *ctx = priv;
589
590 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
591}
592
593static int vidioc_querybuf(struct file *file, void *priv,
594 struct v4l2_buffer *buf)
595{
596 struct m2mtest_ctx *ctx = priv;
597
598 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
599}
600
601static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
602{
603 struct m2mtest_ctx *ctx = priv;
604
605 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
606}
607
608static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
609{
610 struct m2mtest_ctx *ctx = priv;
611
612 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
613}
614
615static int vidioc_streamon(struct file *file, void *priv,
616 enum v4l2_buf_type type)
617{
618 struct m2mtest_ctx *ctx = priv;
619
620 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
621}
622
623static int vidioc_streamoff(struct file *file, void *priv,
624 enum v4l2_buf_type type)
625{
626 struct m2mtest_ctx *ctx = priv;
627
628 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
629}
630
631static int vidioc_queryctrl(struct file *file, void *priv,
632 struct v4l2_queryctrl *qc)
633{
634 struct v4l2_queryctrl *c;
635
636 c = get_ctrl(qc->id);
637 if (!c)
638 return -EINVAL;
639
640 *qc = *c;
641 return 0;
642}
643
644static int vidioc_g_ctrl(struct file *file, void *priv,
645 struct v4l2_control *ctrl)
646{
647 struct m2mtest_ctx *ctx = priv;
648
649 switch (ctrl->id) {
650 case V4L2_CID_TRANS_TIME_MSEC:
651 ctrl->value = ctx->transtime;
652 break;
653
654 case V4L2_CID_TRANS_NUM_BUFS:
655 ctrl->value = ctx->translen;
656 break;
657
658 default:
659 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
660 return -EINVAL;
661 }
662
663 return 0;
664}
665
666static int check_ctrl_val(struct m2mtest_ctx *ctx, struct v4l2_control *ctrl)
667{
668 struct v4l2_queryctrl *c;
669
670 c = get_ctrl(ctrl->id);
671 if (!c)
672 return -EINVAL;
673
674 if (ctrl->value < c->minimum || ctrl->value > c->maximum) {
675 v4l2_err(&ctx->dev->v4l2_dev, "Value out of range\n");
676 return -ERANGE;
677 }
678
679 return 0;
680}
681
682static int vidioc_s_ctrl(struct file *file, void *priv,
683 struct v4l2_control *ctrl)
684{
685 struct m2mtest_ctx *ctx = priv;
686 int ret = 0;
687
688 ret = check_ctrl_val(ctx, ctrl);
689 if (ret != 0)
690 return ret;
691
692 switch (ctrl->id) {
693 case V4L2_CID_TRANS_TIME_MSEC:
694 ctx->transtime = ctrl->value;
695 break;
696
697 case V4L2_CID_TRANS_NUM_BUFS:
698 ctx->translen = ctrl->value;
699 break;
700
701 default:
702 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
703 return -EINVAL;
704 }
705
706 return 0;
707}
708
709
710static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
711 .vidioc_querycap = vidioc_querycap,
712
713 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
714 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
715 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
716 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
717
718 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
719 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
720 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
721 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
722
723 .vidioc_reqbufs = vidioc_reqbufs,
724 .vidioc_querybuf = vidioc_querybuf,
725
726 .vidioc_qbuf = vidioc_qbuf,
727 .vidioc_dqbuf = vidioc_dqbuf,
728
729 .vidioc_streamon = vidioc_streamon,
730 .vidioc_streamoff = vidioc_streamoff,
731
732 .vidioc_queryctrl = vidioc_queryctrl,
733 .vidioc_g_ctrl = vidioc_g_ctrl,
734 .vidioc_s_ctrl = vidioc_s_ctrl,
735};
736
737
738/*
739 * Queue operations
740 */
741
742static void m2mtest_buf_release(struct videobuf_queue *vq,
743 struct videobuf_buffer *vb)
744{
745 struct m2mtest_ctx *ctx = vq->priv_data;
746
747 dprintk(ctx->dev, "type: %d, index: %d, state: %d\n",
748 vq->type, vb->i, vb->state);
749
750 videobuf_vmalloc_free(vb);
751 vb->state = VIDEOBUF_NEEDS_INIT;
752}
753
754static int m2mtest_buf_setup(struct videobuf_queue *vq, unsigned int *count,
755 unsigned int *size)
756{
757 struct m2mtest_ctx *ctx = vq->priv_data;
758 struct m2mtest_q_data *q_data;
759
760 q_data = get_q_data(vq->type);
761
762 *size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
763 dprintk(ctx->dev, "size:%d, w/h %d/%d, depth: %d\n",
764 *size, q_data->width, q_data->height, q_data->fmt->depth);
765
766 if (0 == *count)
767 *count = MEM2MEM_DEF_NUM_BUFS;
768
769 while (*size * *count > MEM2MEM_VID_MEM_LIMIT)
770 (*count)--;
771
772 v4l2_info(&ctx->dev->v4l2_dev,
773 "%d buffers of size %d set up.\n", *count, *size);
774
775 return 0;
776}
777
778static int m2mtest_buf_prepare(struct videobuf_queue *vq,
779 struct videobuf_buffer *vb,
780 enum v4l2_field field)
781{
782 struct m2mtest_ctx *ctx = vq->priv_data;
783 struct m2mtest_q_data *q_data;
784 int ret;
785
786 dprintk(ctx->dev, "type: %d, index: %d, state: %d\n",
787 vq->type, vb->i, vb->state);
788
789 q_data = get_q_data(vq->type);
790
791 if (vb->baddr) {
792 /* User-provided buffer */
793 if (vb->bsize < q_data->sizeimage) {
794 /* Buffer too small to fit a frame */
795 v4l2_err(&ctx->dev->v4l2_dev,
796 "User-provided buffer too small\n");
797 return -EINVAL;
798 }
799 } else if (vb->state != VIDEOBUF_NEEDS_INIT
800 && vb->bsize < q_data->sizeimage) {
801 /* We provide the buffer, but it's already been initialized
802 * and is too small */
803 return -EINVAL;
804 }
805
806 vb->width = q_data->width;
807 vb->height = q_data->height;
808 vb->bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
809 vb->size = q_data->sizeimage;
810 vb->field = field;
811
812 if (VIDEOBUF_NEEDS_INIT == vb->state) {
813 ret = videobuf_iolock(vq, vb, NULL);
814 if (ret) {
815 v4l2_err(&ctx->dev->v4l2_dev,
816 "Iolock failed\n");
817 goto fail;
818 }
819 }
820
821 vb->state = VIDEOBUF_PREPARED;
822
823 return 0;
824fail:
825 m2mtest_buf_release(vq, vb);
826 return ret;
827}
828
829static void m2mtest_buf_queue(struct videobuf_queue *vq,
830 struct videobuf_buffer *vb)
831{
832 struct m2mtest_ctx *ctx = vq->priv_data;
833
834 v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb);
835}
836
837static struct videobuf_queue_ops m2mtest_qops = {
838 .buf_setup = m2mtest_buf_setup,
839 .buf_prepare = m2mtest_buf_prepare,
840 .buf_queue = m2mtest_buf_queue,
841 .buf_release = m2mtest_buf_release,
842};
843
844static void queue_init(void *priv, struct videobuf_queue *vq,
845 enum v4l2_buf_type type)
846{
847 struct m2mtest_ctx *ctx = priv;
848
849 videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev,
850 &ctx->dev->irqlock, type, V4L2_FIELD_NONE,
851 sizeof(struct m2mtest_buffer), priv);
852}
853
854
855/*
856 * File operations
857 */
858static int m2mtest_open(struct file *file)
859{
860 struct m2mtest_dev *dev = video_drvdata(file);
861 struct m2mtest_ctx *ctx = NULL;
862
863 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
864 if (!ctx)
865 return -ENOMEM;
866
867 file->private_data = ctx;
868 ctx->dev = dev;
869 ctx->translen = MEM2MEM_DEF_TRANSLEN;
870 ctx->transtime = MEM2MEM_DEF_TRANSTIME;
871 ctx->num_processed = 0;
872
873 ctx->m2m_ctx = v4l2_m2m_ctx_init(ctx, dev->m2m_dev, queue_init);
874 if (IS_ERR(ctx->m2m_ctx)) {
875 int ret = PTR_ERR(ctx->m2m_ctx);
876
877 kfree(ctx);
878 return ret;
879 }
880
881 atomic_inc(&dev->num_inst);
882
883 dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
884
885 return 0;
886}
887
888static int m2mtest_release(struct file *file)
889{
890 struct m2mtest_dev *dev = video_drvdata(file);
891 struct m2mtest_ctx *ctx = file->private_data;
892
893 dprintk(dev, "Releasing instance %p\n", ctx);
894
895 v4l2_m2m_ctx_release(ctx->m2m_ctx);
896 kfree(ctx);
897
898 atomic_dec(&dev->num_inst);
899
900 return 0;
901}
902
903static unsigned int m2mtest_poll(struct file *file,
904 struct poll_table_struct *wait)
905{
906 struct m2mtest_ctx *ctx = (struct m2mtest_ctx *)file->private_data;
907
908 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
909}
910
911static int m2mtest_mmap(struct file *file, struct vm_area_struct *vma)
912{
913 struct m2mtest_ctx *ctx = (struct m2mtest_ctx *)file->private_data;
914
915 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
916}
917
918static const struct v4l2_file_operations m2mtest_fops = {
919 .owner = THIS_MODULE,
920 .open = m2mtest_open,
921 .release = m2mtest_release,
922 .poll = m2mtest_poll,
923 .ioctl = video_ioctl2,
924 .mmap = m2mtest_mmap,
925};
926
927static struct video_device m2mtest_videodev = {
928 .name = MEM2MEM_NAME,
929 .fops = &m2mtest_fops,
930 .ioctl_ops = &m2mtest_ioctl_ops,
931 .minor = -1,
932 .release = video_device_release,
933};
934
935static struct v4l2_m2m_ops m2m_ops = {
936 .device_run = device_run,
937 .job_ready = job_ready,
938 .job_abort = job_abort,
939};
940
941static int m2mtest_probe(struct platform_device *pdev)
942{
943 struct m2mtest_dev *dev;
944 struct video_device *vfd;
945 int ret;
946
947 dev = kzalloc(sizeof *dev, GFP_KERNEL);
948 if (!dev)
949 return -ENOMEM;
950
951 spin_lock_init(&dev->irqlock);
952
953 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
954 if (ret)
955 goto free_dev;
956
957 atomic_set(&dev->num_inst, 0);
958 mutex_init(&dev->dev_mutex);
959
960 vfd = video_device_alloc();
961 if (!vfd) {
962 v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
963 ret = -ENOMEM;
964 goto unreg_dev;
965 }
966
967 *vfd = m2mtest_videodev;
968
969 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
970 if (ret) {
971 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
972 goto rel_vdev;
973 }
974
975 video_set_drvdata(vfd, dev);
976 snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
977 dev->vfd = vfd;
978 v4l2_info(&dev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
979 "Device registered as /dev/video%d\n", vfd->num);
980
981 setup_timer(&dev->timer, device_isr, (long)dev);
982 platform_set_drvdata(pdev, dev);
983
984 dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
985 if (IS_ERR(dev->m2m_dev)) {
986 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
987 ret = PTR_ERR(dev->m2m_dev);
988 goto err_m2m;
989 }
990
991 return 0;
992
993err_m2m:
994 video_unregister_device(dev->vfd);
995rel_vdev:
996 video_device_release(vfd);
997unreg_dev:
998 v4l2_device_unregister(&dev->v4l2_dev);
999free_dev:
1000 kfree(dev);
1001
1002 return ret;
1003}
1004
1005static int m2mtest_remove(struct platform_device *pdev)
1006{
1007 struct m2mtest_dev *dev =
1008 (struct m2mtest_dev *)platform_get_drvdata(pdev);
1009
1010 v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
1011 v4l2_m2m_release(dev->m2m_dev);
1012 del_timer_sync(&dev->timer);
1013 video_unregister_device(dev->vfd);
1014 v4l2_device_unregister(&dev->v4l2_dev);
1015 kfree(dev);
1016
1017 return 0;
1018}
1019
1020static struct platform_driver m2mtest_pdrv = {
1021 .probe = m2mtest_probe,
1022 .remove = m2mtest_remove,
1023 .driver = {
1024 .name = MEM2MEM_NAME,
1025 .owner = THIS_MODULE,
1026 },
1027};
1028
1029static void __exit m2mtest_exit(void)
1030{
1031 platform_driver_unregister(&m2mtest_pdrv);
1032 platform_device_unregister(&m2mtest_pdev);
1033}
1034
1035static int __init m2mtest_init(void)
1036{
1037 int ret;
1038
1039 ret = platform_device_register(&m2mtest_pdev);
1040 if (ret)
1041 return ret;
1042
1043 ret = platform_driver_register(&m2mtest_pdrv);
1044 if (ret)
1045 platform_device_unregister(&m2mtest_pdev);
1046
1047 return 0;
1048}
1049
1050module_init(m2mtest_init);
1051module_exit(m2mtest_exit);
1052
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 4404e5ef818f..2be23bccd3c8 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -30,9 +30,10 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/videodev.h>
34#include <linux/gfp.h> 33#include <linux/gfp.h>
34#include <linux/videodev2.h>
35#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
36#include <media/v4l2-device.h>
36#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38#include <asm/io.h> 39#include <asm/io.h>
@@ -1168,22 +1169,22 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
1168 case V4L2_CID_BRIGHTNESS: 1169 case V4L2_CID_BRIGHTNESS:
1169 sony_pic_camera_command( 1170 sony_pic_camera_command(
1170 SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value); 1171 SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value);
1171 meye.picture.brightness = c->value << 10; 1172 meye.brightness = c->value << 10;
1172 break; 1173 break;
1173 case V4L2_CID_HUE: 1174 case V4L2_CID_HUE:
1174 sony_pic_camera_command( 1175 sony_pic_camera_command(
1175 SONY_PIC_COMMAND_SETCAMERAHUE, c->value); 1176 SONY_PIC_COMMAND_SETCAMERAHUE, c->value);
1176 meye.picture.hue = c->value << 10; 1177 meye.hue = c->value << 10;
1177 break; 1178 break;
1178 case V4L2_CID_CONTRAST: 1179 case V4L2_CID_CONTRAST:
1179 sony_pic_camera_command( 1180 sony_pic_camera_command(
1180 SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value); 1181 SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value);
1181 meye.picture.contrast = c->value << 10; 1182 meye.contrast = c->value << 10;
1182 break; 1183 break;
1183 case V4L2_CID_SATURATION: 1184 case V4L2_CID_SATURATION:
1184 sony_pic_camera_command( 1185 sony_pic_camera_command(
1185 SONY_PIC_COMMAND_SETCAMERACOLOR, c->value); 1186 SONY_PIC_COMMAND_SETCAMERACOLOR, c->value);
1186 meye.picture.colour = c->value << 10; 1187 meye.colour = c->value << 10;
1187 break; 1188 break;
1188 case V4L2_CID_AGC: 1189 case V4L2_CID_AGC:
1189 sony_pic_camera_command( 1190 sony_pic_camera_command(
@@ -1221,16 +1222,16 @@ static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
1221 mutex_lock(&meye.lock); 1222 mutex_lock(&meye.lock);
1222 switch (c->id) { 1223 switch (c->id) {
1223 case V4L2_CID_BRIGHTNESS: 1224 case V4L2_CID_BRIGHTNESS:
1224 c->value = meye.picture.brightness >> 10; 1225 c->value = meye.brightness >> 10;
1225 break; 1226 break;
1226 case V4L2_CID_HUE: 1227 case V4L2_CID_HUE:
1227 c->value = meye.picture.hue >> 10; 1228 c->value = meye.hue >> 10;
1228 break; 1229 break;
1229 case V4L2_CID_CONTRAST: 1230 case V4L2_CID_CONTRAST:
1230 c->value = meye.picture.contrast >> 10; 1231 c->value = meye.contrast >> 10;
1231 break; 1232 break;
1232 case V4L2_CID_SATURATION: 1233 case V4L2_CID_SATURATION:
1233 c->value = meye.picture.colour >> 10; 1234 c->value = meye.colour >> 10;
1234 break; 1235 break;
1235 case V4L2_CID_AGC: 1236 case V4L2_CID_AGC:
1236 c->value = meye.params.agc; 1237 c->value = meye.params.agc;
@@ -1729,6 +1730,7 @@ static int meye_resume(struct pci_dev *pdev)
1729static int __devinit meye_probe(struct pci_dev *pcidev, 1730static int __devinit meye_probe(struct pci_dev *pcidev,
1730 const struct pci_device_id *ent) 1731 const struct pci_device_id *ent)
1731{ 1732{
1733 struct v4l2_device *v4l2_dev = &meye.v4l2_dev;
1732 int ret = -EBUSY; 1734 int ret = -EBUSY;
1733 unsigned long mchip_adr; 1735 unsigned long mchip_adr;
1734 1736
@@ -1737,70 +1739,75 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
1737 goto outnotdev; 1739 goto outnotdev;
1738 } 1740 }
1739 1741
1742 ret = v4l2_device_register(&pcidev->dev, v4l2_dev);
1743 if (ret < 0) {
1744 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
1745 return ret;
1746 }
1740 ret = -ENOMEM; 1747 ret = -ENOMEM;
1741 meye.mchip_dev = pcidev; 1748 meye.mchip_dev = pcidev;
1742 meye.video_dev = video_device_alloc(); 1749 meye.vdev = video_device_alloc();
1743 if (!meye.video_dev) { 1750 if (!meye.vdev) {
1744 printk(KERN_ERR "meye: video_device_alloc() failed!\n"); 1751 v4l2_err(v4l2_dev, "video_device_alloc() failed!\n");
1745 goto outnotdev; 1752 goto outnotdev;
1746 } 1753 }
1747 1754
1748 meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); 1755 meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
1749 if (!meye.grab_temp) { 1756 if (!meye.grab_temp) {
1750 printk(KERN_ERR "meye: grab buffer allocation failed\n"); 1757 v4l2_err(v4l2_dev, "grab buffer allocation failed\n");
1751 goto outvmalloc; 1758 goto outvmalloc;
1752 } 1759 }
1753 1760
1754 spin_lock_init(&meye.grabq_lock); 1761 spin_lock_init(&meye.grabq_lock);
1755 if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, 1762 if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
1756 GFP_KERNEL)) { 1763 GFP_KERNEL)) {
1757 printk(KERN_ERR "meye: fifo allocation failed\n"); 1764 v4l2_err(v4l2_dev, "fifo allocation failed\n");
1758 goto outkfifoalloc1; 1765 goto outkfifoalloc1;
1759 } 1766 }
1760 spin_lock_init(&meye.doneq_lock); 1767 spin_lock_init(&meye.doneq_lock);
1761 if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, 1768 if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
1762 GFP_KERNEL)) { 1769 GFP_KERNEL)) {
1763 printk(KERN_ERR "meye: fifo allocation failed\n"); 1770 v4l2_err(v4l2_dev, "fifo allocation failed\n");
1764 goto outkfifoalloc2; 1771 goto outkfifoalloc2;
1765 } 1772 }
1766 1773
1767 memcpy(meye.video_dev, &meye_template, sizeof(meye_template)); 1774 memcpy(meye.vdev, &meye_template, sizeof(meye_template));
1768 meye.video_dev->parent = &meye.mchip_dev->dev; 1775 meye.vdev->v4l2_dev = &meye.v4l2_dev;
1769 1776
1770 ret = -EIO; 1777 ret = -EIO;
1771 if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { 1778 if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
1772 printk(KERN_ERR "meye: unable to power on the camera\n"); 1779 v4l2_err(v4l2_dev, "meye: unable to power on the camera\n");
1773 printk(KERN_ERR "meye: did you enable the camera in " 1780 v4l2_err(v4l2_dev, "meye: did you enable the camera in "
1774 "sonypi using the module options ?\n"); 1781 "sonypi using the module options ?\n");
1775 goto outsonypienable; 1782 goto outsonypienable;
1776 } 1783 }
1777 1784
1778 if ((ret = pci_enable_device(meye.mchip_dev))) { 1785 if ((ret = pci_enable_device(meye.mchip_dev))) {
1779 printk(KERN_ERR "meye: pci_enable_device failed\n"); 1786 v4l2_err(v4l2_dev, "meye: pci_enable_device failed\n");
1780 goto outenabledev; 1787 goto outenabledev;
1781 } 1788 }
1782 1789
1783 mchip_adr = pci_resource_start(meye.mchip_dev,0); 1790 mchip_adr = pci_resource_start(meye.mchip_dev,0);
1784 if (!mchip_adr) { 1791 if (!mchip_adr) {
1785 printk(KERN_ERR "meye: mchip has no device base address\n"); 1792 v4l2_err(v4l2_dev, "meye: mchip has no device base address\n");
1786 goto outregions; 1793 goto outregions;
1787 } 1794 }
1788 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0), 1795 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
1789 pci_resource_len(meye.mchip_dev, 0), 1796 pci_resource_len(meye.mchip_dev, 0),
1790 "meye")) { 1797 "meye")) {
1791 printk(KERN_ERR "meye: request_mem_region failed\n"); 1798 v4l2_err(v4l2_dev, "meye: request_mem_region failed\n");
1792 goto outregions; 1799 goto outregions;
1793 } 1800 }
1794 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS); 1801 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
1795 if (!meye.mchip_mmregs) { 1802 if (!meye.mchip_mmregs) {
1796 printk(KERN_ERR "meye: ioremap failed\n"); 1803 v4l2_err(v4l2_dev, "meye: ioremap failed\n");
1797 goto outremap; 1804 goto outremap;
1798 } 1805 }
1799 1806
1800 meye.mchip_irq = pcidev->irq; 1807 meye.mchip_irq = pcidev->irq;
1801 if (request_irq(meye.mchip_irq, meye_irq, 1808 if (request_irq(meye.mchip_irq, meye_irq,
1802 IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) { 1809 IRQF_DISABLED | IRQF_SHARED, "meye", meye_irq)) {
1803 printk(KERN_ERR "meye: request_irq failed\n"); 1810 v4l2_err(v4l2_dev, "request_irq failed\n");
1804 goto outreqirq; 1811 goto outreqirq;
1805 } 1812 }
1806 1813
@@ -1824,21 +1831,18 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
1824 msleep(1); 1831 msleep(1);
1825 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); 1832 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1826 1833
1827 if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER, 1834 if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
1828 video_nr) < 0) { 1835 video_nr) < 0) {
1829 printk(KERN_ERR "meye: video_register_device failed\n"); 1836 v4l2_err(v4l2_dev, "video_register_device failed\n");
1830 goto outvideoreg; 1837 goto outvideoreg;
1831 } 1838 }
1832 1839
1833 mutex_init(&meye.lock); 1840 mutex_init(&meye.lock);
1834 init_waitqueue_head(&meye.proc_list); 1841 init_waitqueue_head(&meye.proc_list);
1835 meye.picture.depth = 16; 1842 meye.brightness = 32 << 10;
1836 meye.picture.palette = VIDEO_PALETTE_YUV422; 1843 meye.hue = 32 << 10;
1837 meye.picture.brightness = 32 << 10; 1844 meye.colour = 32 << 10;
1838 meye.picture.hue = 32 << 10; 1845 meye.contrast = 32 << 10;
1839 meye.picture.colour = 32 << 10;
1840 meye.picture.contrast = 32 << 10;
1841 meye.picture.whiteness = 0;
1842 meye.params.subsample = 0; 1846 meye.params.subsample = 0;
1843 meye.params.quality = 8; 1847 meye.params.quality = 8;
1844 meye.params.sharpness = 32; 1848 meye.params.sharpness = 32;
@@ -1854,9 +1858,9 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
1854 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); 1858 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
1855 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); 1859 sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
1856 1860
1857 printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n", 1861 v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n",
1858 MEYE_DRIVER_VERSION); 1862 MEYE_DRIVER_VERSION);
1859 printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n", 1863 v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n",
1860 meye.mchip_dev->revision, mchip_adr, meye.mchip_irq); 1864 meye.mchip_dev->revision, mchip_adr, meye.mchip_irq);
1861 1865
1862 return 0; 1866 return 0;
@@ -1879,14 +1883,14 @@ outkfifoalloc2:
1879outkfifoalloc1: 1883outkfifoalloc1:
1880 vfree(meye.grab_temp); 1884 vfree(meye.grab_temp);
1881outvmalloc: 1885outvmalloc:
1882 video_device_release(meye.video_dev); 1886 video_device_release(meye.vdev);
1883outnotdev: 1887outnotdev:
1884 return ret; 1888 return ret;
1885} 1889}
1886 1890
1887static void __devexit meye_remove(struct pci_dev *pcidev) 1891static void __devexit meye_remove(struct pci_dev *pcidev)
1888{ 1892{
1889 video_unregister_device(meye.video_dev); 1893 video_unregister_device(meye.vdev);
1890 1894
1891 mchip_hic_stop(); 1895 mchip_hic_stop();
1892 1896
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
index 1321ad5d6597..4bdeb03f1644 100644
--- a/drivers/media/video/meye.h
+++ b/drivers/media/video/meye.h
@@ -31,7 +31,7 @@
31#define _MEYE_PRIV_H_ 31#define _MEYE_PRIV_H_
32 32
33#define MEYE_DRIVER_MAJORVERSION 1 33#define MEYE_DRIVER_MAJORVERSION 1
34#define MEYE_DRIVER_MINORVERSION 13 34#define MEYE_DRIVER_MINORVERSION 14
35 35
36#define MEYE_DRIVER_VERSION __stringify(MEYE_DRIVER_MAJORVERSION) "." \ 36#define MEYE_DRIVER_VERSION __stringify(MEYE_DRIVER_MAJORVERSION) "." \
37 __stringify(MEYE_DRIVER_MINORVERSION) 37 __stringify(MEYE_DRIVER_MINORVERSION)
@@ -289,6 +289,7 @@ struct meye_grab_buffer {
289 289
290/* Motion Eye device structure */ 290/* Motion Eye device structure */
291struct meye { 291struct meye {
292 struct v4l2_device v4l2_dev; /* Main v4l2_device struct */
292 struct pci_dev *mchip_dev; /* pci device */ 293 struct pci_dev *mchip_dev; /* pci device */
293 u8 mchip_irq; /* irq */ 294 u8 mchip_irq; /* irq */
294 u8 mchip_mode; /* actual mchip mode: HIC_MODE... */ 295 u8 mchip_mode; /* actual mchip mode: HIC_MODE... */
@@ -308,8 +309,11 @@ struct meye {
308 struct kfifo doneq; /* queue for grabbed buffers */ 309 struct kfifo doneq; /* queue for grabbed buffers */
309 spinlock_t doneq_lock; /* lock protecting the queue */ 310 spinlock_t doneq_lock; /* lock protecting the queue */
310 wait_queue_head_t proc_list; /* wait queue */ 311 wait_queue_head_t proc_list; /* wait queue */
311 struct video_device *video_dev; /* video device parameters */ 312 struct video_device *vdev; /* video device parameters */
312 struct video_picture picture; /* video picture parameters */ 313 u16 brightness;
314 u16 hue;
315 u16 contrast;
316 u16 colour;
313 struct meye_params params; /* additional parameters */ 317 struct meye_params params; /* additional parameters */
314 unsigned long in_use; /* set to 1 if the device is in use */ 318 unsigned long in_use; /* set to 1 if the device is in use */
315#ifdef CONFIG_PM 319#ifdef CONFIG_PM
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index a9061bff79b2..78b4e091d2d5 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -8,14 +8,16 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/videodev2.h> 11#include <linux/device.h>
12#include <linux/slab.h>
13#include <linux/i2c.h> 12#include <linux/i2c.h>
14#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/pm.h>
15#include <linux/slab.h>
16#include <linux/videodev2.h>
15 17
16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19#include <media/v4l2-chip-ident.h>
20#include <media/v4l2-subdev.h>
19 21
20/* 22/*
21 * mt9t031 i2c address 0x5d 23 * mt9t031 i2c address 0x5d
@@ -681,12 +683,66 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
681} 683}
682 684
683/* 685/*
686 * Power Management:
687 * This function does nothing for now but must be present for pm to work
688 */
689static int mt9t031_runtime_suspend(struct device *dev)
690{
691 return 0;
692}
693
694/*
695 * Power Management:
696 * COLUMN_ADDRESS_MODE and ROW_ADDRESS_MODE are not rewritten if unchanged
697 * they are however changed at reset if the platform hook is present
698 * thus we rewrite them with the values stored by the driver
699 */
700static int mt9t031_runtime_resume(struct device *dev)
701{
702 struct video_device *vdev = to_video_device(dev);
703 struct soc_camera_device *icd = container_of(vdev->parent,
704 struct soc_camera_device, dev);
705 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
706 struct i2c_client *client = sd->priv;
707 struct mt9t031 *mt9t031 = to_mt9t031(client);
708
709 int ret;
710 u16 xbin, ybin;
711
712 xbin = min(mt9t031->xskip, (u16)3);
713 ybin = min(mt9t031->yskip, (u16)3);
714
715 ret = reg_write(client, MT9T031_COLUMN_ADDRESS_MODE,
716 ((xbin - 1) << 4) | (mt9t031->xskip - 1));
717 if (ret < 0)
718 return ret;
719
720 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
721 ((ybin - 1) << 4) | (mt9t031->yskip - 1));
722 if (ret < 0)
723 return ret;
724
725 return 0;
726}
727
728static struct dev_pm_ops mt9t031_dev_pm_ops = {
729 .runtime_suspend = mt9t031_runtime_suspend,
730 .runtime_resume = mt9t031_runtime_resume,
731};
732
733static struct device_type mt9t031_dev_type = {
734 .name = "MT9T031",
735 .pm = &mt9t031_dev_pm_ops,
736};
737
738/*
684 * Interface active, can use i2c. If it fails, it can indeed mean, that 739 * Interface active, can use i2c. If it fails, it can indeed mean, that
685 * this wasn't our capture interface, so, we wait for the right one 740 * this wasn't our capture interface, so, we wait for the right one
686 */ 741 */
687static int mt9t031_video_probe(struct i2c_client *client) 742static int mt9t031_video_probe(struct i2c_client *client)
688{ 743{
689 struct mt9t031 *mt9t031 = to_mt9t031(client); 744 struct mt9t031 *mt9t031 = to_mt9t031(client);
745 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
690 s32 data; 746 s32 data;
691 int ret; 747 int ret;
692 748
@@ -712,6 +768,8 @@ static int mt9t031_video_probe(struct i2c_client *client)
712 ret = mt9t031_idle(client); 768 ret = mt9t031_idle(client);
713 if (ret < 0) 769 if (ret < 0)
714 dev_err(&client->dev, "Failed to initialise the camera\n"); 770 dev_err(&client->dev, "Failed to initialise the camera\n");
771 else
772 vdev->dev.type = &mt9t031_dev_type;
715 773
716 /* mt9t031_idle() has reset the chip to default. */ 774 /* mt9t031_idle() has reset the chip to default. */
717 mt9t031->exposure = 255; 775 mt9t031->exposure = 255;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 1a34d2993e94..e5bae4c9393b 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -325,7 +325,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
325 if (ret < 0) 325 if (ret < 0)
326 return ret; 326 return ret;
327 327
328 dev_dbg(&client->dev, "Frame %ux%u pixel\n", rect.width, rect.height); 328 dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height);
329 329
330 mt9v022->rect = rect; 330 mt9v022->rect = rect;
331 331
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 34a66019190e..5c17f9ec3d7c 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -139,8 +139,8 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
139 if (!*count) 139 if (!*count)
140 *count = 32; 140 *count = 32;
141 141
142 while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 142 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
143 (*count)--; 143 *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
144 144
145 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); 145 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
146 146
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index bd297f567dc7..d477e3058002 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -796,7 +796,7 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
796 * FIXME: learn to use stride != width, then we can keep stride properly aligned 796 * FIXME: learn to use stride != width, then we can keep stride properly aligned
797 * and support arbitrary (even) widths. 797 * and support arbitrary (even) widths.
798 */ 798 */
799static inline void stride_align(__s32 *width) 799static inline void stride_align(__u32 *width)
800{ 800{
801 if (((*width + 7) & ~7) < 4096) 801 if (((*width + 7) & ~7) < 4096)
802 *width = (*width + 7) & ~7; 802 *width = (*width + 7) & ~7;
@@ -844,7 +844,7 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
844 * So far only direct camera-to-memory is supported 844 * So far only direct camera-to-memory is supported
845 */ 845 */
846 if (channel_change_requested(icd, rect)) { 846 if (channel_change_requested(icd, rect)) {
847 int ret = acquire_dma_channel(mx3_cam); 847 ret = acquire_dma_channel(mx3_cam);
848 if (ret < 0) 848 if (ret < 0)
849 return ret; 849 return ret;
850 } 850 }
diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/video/omap/Kconfig
new file mode 100644
index 000000000000..97c53949ca89
--- /dev/null
+++ b/drivers/media/video/omap/Kconfig
@@ -0,0 +1,11 @@
1config VIDEO_OMAP2_VOUT
2 tristate "OMAP2/OMAP3 V4L2-Display driver"
3 depends on ARCH_OMAP24XX || ARCH_OMAP34XX
4 select VIDEOBUF_GEN
5 select VIDEOBUF_DMA_SG
6 select OMAP2_DSS
7 select OMAP2_VRAM
8 select OMAP2_VRFB
9 default n
10 ---help---
11 V4L2 Display driver support for OMAP2/3 based boards.
diff --git a/drivers/media/video/omap/Makefile b/drivers/media/video/omap/Makefile
new file mode 100644
index 000000000000..b8bab00ad010
--- /dev/null
+++ b/drivers/media/video/omap/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the omap video device drivers.
3#
4
5# OMAP2/3 Display driver
6omap-vout-mod-objs := omap_vout.o omap_voutlib.o
7obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout-mod.o
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
new file mode 100644
index 000000000000..4c0ab499228b
--- /dev/null
+++ b/drivers/media/video/omap/omap_vout.c
@@ -0,0 +1,2643 @@
1/*
2 * omap_vout.c
3 *
4 * Copyright (C) 2005-2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 * Leveraged code from the OMAP2 camera driver
11 * Video-for-Linux (Version 2) camera capture driver for
12 * the OMAP24xx camera controller.
13 *
14 * Author: Andy Lowe (source@mvista.com)
15 *
16 * Copyright (C) 2004 MontaVista Software, Inc.
17 * Copyright (C) 2010 Texas Instruments.
18 *
19 * History:
20 * 20-APR-2006 Khasim Modified VRFB based Rotation,
21 * The image data is always read from 0 degree
22 * view and written
23 * to the virtual space of desired rotation angle
24 * 4-DEC-2006 Jian Changed to support better memory management
25 *
26 * 17-Nov-2008 Hardik Changed driver to use video_ioctl2
27 *
28 * 23-Feb-2010 Vaibhav H Modified to use new DSS2 interface
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35#include <linux/sched.h>
36#include <linux/types.h>
37#include <linux/platform_device.h>
38#include <linux/dma-mapping.h>
39#include <linux/irq.h>
40#include <linux/videodev2.h>
41
42#include <media/videobuf-dma-sg.h>
43#include <media/v4l2-device.h>
44#include <media/v4l2-ioctl.h>
45
46#include <plat/dma.h>
47#include <plat/vram.h>
48#include <plat/vrfb.h>
49#include <plat/display.h>
50
51#include "omap_voutlib.h"
52#include "omap_voutdef.h"
53
54MODULE_AUTHOR("Texas Instruments");
55MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
56MODULE_LICENSE("GPL");
57
58
59/* Driver Configuration macros */
60#define VOUT_NAME "omap_vout"
61
62enum omap_vout_channels {
63 OMAP_VIDEO1,
64 OMAP_VIDEO2,
65};
66
67enum dma_channel_state {
68 DMA_CHAN_NOT_ALLOTED,
69 DMA_CHAN_ALLOTED,
70};
71
72#define QQVGA_WIDTH 160
73#define QQVGA_HEIGHT 120
74
75/* Max Resolution supported by the driver */
76#define VID_MAX_WIDTH 1280 /* Largest width */
77#define VID_MAX_HEIGHT 720 /* Largest height */
78
79/* Mimimum requirement is 2x2 for DSS */
80#define VID_MIN_WIDTH 2
81#define VID_MIN_HEIGHT 2
82
83/* 2048 x 2048 is max res supported by OMAP display controller */
84#define MAX_PIXELS_PER_LINE 2048
85
86#define VRFB_TX_TIMEOUT 1000
87#define VRFB_NUM_BUFS 4
88
89/* Max buffer size tobe allocated during init */
90#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
91
92static struct videobuf_queue_ops video_vbq_ops;
93/* Variables configurable through module params*/
94static u32 video1_numbuffers = 3;
95static u32 video2_numbuffers = 3;
96static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
97static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
98static u32 vid1_static_vrfb_alloc;
99static u32 vid2_static_vrfb_alloc;
100static int debug;
101
102/* Module parameters */
103module_param(video1_numbuffers, uint, S_IRUGO);
104MODULE_PARM_DESC(video1_numbuffers,
105 "Number of buffers to be allocated at init time for Video1 device.");
106
107module_param(video2_numbuffers, uint, S_IRUGO);
108MODULE_PARM_DESC(video2_numbuffers,
109 "Number of buffers to be allocated at init time for Video2 device.");
110
111module_param(video1_bufsize, uint, S_IRUGO);
112MODULE_PARM_DESC(video1_bufsize,
113 "Size of the buffer to be allocated for video1 device");
114
115module_param(video2_bufsize, uint, S_IRUGO);
116MODULE_PARM_DESC(video2_bufsize,
117 "Size of the buffer to be allocated for video2 device");
118
119module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
120MODULE_PARM_DESC(vid1_static_vrfb_alloc,
121 "Static allocation of the VRFB buffer for video1 device");
122
123module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
124MODULE_PARM_DESC(vid2_static_vrfb_alloc,
125 "Static allocation of the VRFB buffer for video2 device");
126
127module_param(debug, bool, S_IRUGO);
128MODULE_PARM_DESC(debug, "Debug level (0-1)");
129
130/* list of image formats supported by OMAP2 video pipelines */
131const static struct v4l2_fmtdesc omap_formats[] = {
132 {
133 /* Note: V4L2 defines RGB565 as:
134 *
135 * Byte 0 Byte 1
136 * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3
137 *
138 * We interpret RGB565 as:
139 *
140 * Byte 0 Byte 1
141 * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
142 */
143 .description = "RGB565, le",
144 .pixelformat = V4L2_PIX_FMT_RGB565,
145 },
146 {
147 /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
148 * this for RGB24 unpack mode, the last 8 bits are ignored
149 * */
150 .description = "RGB32, le",
151 .pixelformat = V4L2_PIX_FMT_RGB32,
152 },
153 {
154 /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
155 * this for RGB24 packed mode
156 *
157 */
158 .description = "RGB24, le",
159 .pixelformat = V4L2_PIX_FMT_RGB24,
160 },
161 {
162 .description = "YUYV (YUV 4:2:2), packed",
163 .pixelformat = V4L2_PIX_FMT_YUYV,
164 },
165 {
166 .description = "UYVY, packed",
167 .pixelformat = V4L2_PIX_FMT_UYVY,
168 },
169};
170
171#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
172
173/*
174 * Allocate buffers
175 */
176static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)
177{
178 u32 order, size;
179 unsigned long virt_addr, addr;
180
181 size = PAGE_ALIGN(buf_size);
182 order = get_order(size);
183 virt_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, order);
184 addr = virt_addr;
185
186 if (virt_addr) {
187 while (size > 0) {
188 SetPageReserved(virt_to_page(addr));
189 addr += PAGE_SIZE;
190 size -= PAGE_SIZE;
191 }
192 }
193 *phys_addr = (u32) virt_to_phys((void *) virt_addr);
194 return virt_addr;
195}
196
197/*
198 * Free buffers
199 */
200static void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
201{
202 u32 order, size;
203 unsigned long addr = virtaddr;
204
205 size = PAGE_ALIGN(buf_size);
206 order = get_order(size);
207
208 while (size > 0) {
209 ClearPageReserved(virt_to_page(addr));
210 addr += PAGE_SIZE;
211 size -= PAGE_SIZE;
212 }
213 free_pages((unsigned long) virtaddr, order);
214}
215
216/*
217 * Function for allocating video buffers
218 */
219static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
220 unsigned int *count, int startindex)
221{
222 int i, j;
223
224 for (i = 0; i < *count; i++) {
225 if (!vout->smsshado_virt_addr[i]) {
226 vout->smsshado_virt_addr[i] =
227 omap_vout_alloc_buffer(vout->smsshado_size,
228 &vout->smsshado_phy_addr[i]);
229 }
230 if (!vout->smsshado_virt_addr[i] && startindex != -1) {
231 if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex)
232 break;
233 }
234 if (!vout->smsshado_virt_addr[i]) {
235 for (j = 0; j < i; j++) {
236 omap_vout_free_buffer(
237 vout->smsshado_virt_addr[j],
238 vout->smsshado_size);
239 vout->smsshado_virt_addr[j] = 0;
240 vout->smsshado_phy_addr[j] = 0;
241 }
242 *count = 0;
243 return -ENOMEM;
244 }
245 memset((void *) vout->smsshado_virt_addr[i], 0,
246 vout->smsshado_size);
247 }
248 return 0;
249}
250
251/*
252 * Try format
253 */
254static int omap_vout_try_format(struct v4l2_pix_format *pix)
255{
256 int ifmt, bpp = 0;
257
258 pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
259 (u32)VID_MAX_HEIGHT);
260 pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
261
262 for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
263 if (pix->pixelformat == omap_formats[ifmt].pixelformat)
264 break;
265 }
266
267 if (ifmt == NUM_OUTPUT_FORMATS)
268 ifmt = 0;
269
270 pix->pixelformat = omap_formats[ifmt].pixelformat;
271 pix->field = V4L2_FIELD_ANY;
272 pix->priv = 0;
273
274 switch (pix->pixelformat) {
275 case V4L2_PIX_FMT_YUYV:
276 case V4L2_PIX_FMT_UYVY:
277 default:
278 pix->colorspace = V4L2_COLORSPACE_JPEG;
279 bpp = YUYV_BPP;
280 break;
281 case V4L2_PIX_FMT_RGB565:
282 case V4L2_PIX_FMT_RGB565X:
283 pix->colorspace = V4L2_COLORSPACE_SRGB;
284 bpp = RGB565_BPP;
285 break;
286 case V4L2_PIX_FMT_RGB24:
287 pix->colorspace = V4L2_COLORSPACE_SRGB;
288 bpp = RGB24_BPP;
289 break;
290 case V4L2_PIX_FMT_RGB32:
291 case V4L2_PIX_FMT_BGR32:
292 pix->colorspace = V4L2_COLORSPACE_SRGB;
293 bpp = RGB32_BPP;
294 break;
295 }
296 pix->bytesperline = pix->width * bpp;
297 pix->sizeimage = pix->bytesperline * pix->height;
298
299 return bpp;
300}
301
302/*
303 * omap_vout_uservirt_to_phys: This inline function is used to convert user
304 * space virtual address to physical address.
305 */
306static u32 omap_vout_uservirt_to_phys(u32 virtp)
307{
308 unsigned long physp = 0;
309 struct vm_area_struct *vma;
310 struct mm_struct *mm = current->mm;
311
312 vma = find_vma(mm, virtp);
313 /* For kernel direct-mapped memory, take the easy way */
314 if (virtp >= PAGE_OFFSET) {
315 physp = virt_to_phys((void *) virtp);
316 } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
317 /* this will catch, kernel-allocated, mmaped-to-usermode
318 addresses */
319 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
320 } else {
321 /* otherwise, use get_user_pages() for general userland pages */
322 int res, nr_pages = 1;
323 struct page *pages;
324 down_read(&current->mm->mmap_sem);
325
326 res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
327 0, &pages, NULL);
328 up_read(&current->mm->mmap_sem);
329
330 if (res == nr_pages) {
331 physp = __pa(page_address(&pages[0]) +
332 (virtp & ~PAGE_MASK));
333 } else {
334 printk(KERN_WARNING VOUT_NAME
335 "get_user_pages failed\n");
336 return 0;
337 }
338 }
339
340 return physp;
341}
342
343/*
344 * Wakes up the application once the DMA transfer to VRFB space is completed.
345 */
346static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
347{
348 struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
349
350 t->tx_status = 1;
351 wake_up_interruptible(&t->wait);
352}
353
354/*
355 * Release the VRFB context once the module exits
356 */
357static void omap_vout_release_vrfb(struct omap_vout_device *vout)
358{
359 int i;
360
361 for (i = 0; i < VRFB_NUM_BUFS; i++)
362 omap_vrfb_release_ctx(&vout->vrfb_context[i]);
363
364 if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
365 vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
366 omap_free_dma(vout->vrfb_dma_tx.dma_ch);
367 }
368}
369
370/*
371 * Return true if rotation is 90 or 270
372 */
373static inline int rotate_90_or_270(const struct omap_vout_device *vout)
374{
375 return (vout->rotation == dss_rotation_90_degree ||
376 vout->rotation == dss_rotation_270_degree);
377}
378
379/*
380 * Return true if rotation is enabled
381 */
382static inline int rotation_enabled(const struct omap_vout_device *vout)
383{
384 return vout->rotation || vout->mirror;
385}
386
387/*
388 * Reverse the rotation degree if mirroring is enabled
389 */
390static inline int calc_rotation(const struct omap_vout_device *vout)
391{
392 if (!vout->mirror)
393 return vout->rotation;
394
395 switch (vout->rotation) {
396 case dss_rotation_90_degree:
397 return dss_rotation_270_degree;
398 case dss_rotation_270_degree:
399 return dss_rotation_90_degree;
400 case dss_rotation_180_degree:
401 return dss_rotation_0_degree;
402 default:
403 return dss_rotation_180_degree;
404 }
405}
406
407/*
408 * Free the V4L2 buffers
409 */
410static void omap_vout_free_buffers(struct omap_vout_device *vout)
411{
412 int i, numbuffers;
413
414 /* Allocate memory for the buffers */
415 numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers;
416 vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
417
418 for (i = 0; i < numbuffers; i++) {
419 omap_vout_free_buffer(vout->buf_virt_addr[i],
420 vout->buffer_size);
421 vout->buf_phy_addr[i] = 0;
422 vout->buf_virt_addr[i] = 0;
423 }
424}
425
426/*
427 * Free VRFB buffers
428 */
429static void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
430{
431 int j;
432
433 for (j = 0; j < VRFB_NUM_BUFS; j++) {
434 omap_vout_free_buffer(vout->smsshado_virt_addr[j],
435 vout->smsshado_size);
436 vout->smsshado_virt_addr[j] = 0;
437 vout->smsshado_phy_addr[j] = 0;
438 }
439}
440
441/*
442 * Allocate the buffers for the VRFB space. Data is copied from V4L2
443 * buffers to the VRFB buffers using the DMA engine.
444 */
445static int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
446 unsigned int *count, unsigned int startindex)
447{
448 int i;
449 bool yuv_mode;
450
451 /* Allocate the VRFB buffers only if the buffers are not
452 * allocated during init time.
453 */
454 if ((rotation_enabled(vout)) && !vout->vrfb_static_allocation)
455 if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
456 return -ENOMEM;
457
458 if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
459 vout->dss_mode == OMAP_DSS_COLOR_UYVY)
460 yuv_mode = true;
461 else
462 yuv_mode = false;
463
464 for (i = 0; i < *count; i++)
465 omap_vrfb_setup(&vout->vrfb_context[i],
466 vout->smsshado_phy_addr[i], vout->pix.width,
467 vout->pix.height, vout->bpp, yuv_mode);
468
469 return 0;
470}
471
472/*
473 * Convert V4L2 rotation to DSS rotation
474 * V4L2 understand 0, 90, 180, 270.
475 * Convert to 0, 1, 2 and 3 repsectively for DSS
476 */
477static int v4l2_rot_to_dss_rot(int v4l2_rotation,
478 enum dss_rotation *rotation, bool mirror)
479{
480 int ret = 0;
481
482 switch (v4l2_rotation) {
483 case 90:
484 *rotation = dss_rotation_90_degree;
485 break;
486 case 180:
487 *rotation = dss_rotation_180_degree;
488 break;
489 case 270:
490 *rotation = dss_rotation_270_degree;
491 break;
492 case 0:
493 *rotation = dss_rotation_0_degree;
494 break;
495 default:
496 ret = -EINVAL;
497 }
498 return ret;
499}
500
501/*
502 * Calculate the buffer offsets from which the streaming should
503 * start. This offset calculation is mainly required because of
504 * the VRFB 32 pixels alignment with rotation.
505 */
506static int omap_vout_calculate_offset(struct omap_vout_device *vout)
507{
508 struct omap_overlay *ovl;
509 enum dss_rotation rotation;
510 struct omapvideo_info *ovid;
511 bool mirroring = vout->mirror;
512 struct omap_dss_device *cur_display;
513 struct v4l2_rect *crop = &vout->crop;
514 struct v4l2_pix_format *pix = &vout->pix;
515 int *cropped_offset = &vout->cropped_offset;
516 int vr_ps = 1, ps = 2, temp_ps = 2;
517 int offset = 0, ctop = 0, cleft = 0, line_length = 0;
518
519 ovid = &vout->vid_info;
520 ovl = ovid->overlays[0];
521 /* get the display device attached to the overlay */
522 if (!ovl->manager || !ovl->manager->device)
523 return -1;
524
525 cur_display = ovl->manager->device;
526 rotation = calc_rotation(vout);
527
528 if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
529 V4L2_PIX_FMT_UYVY == pix->pixelformat) {
530 if (rotation_enabled(vout)) {
531 /*
532 * ps - Actual pixel size for YUYV/UYVY for
533 * VRFB/Mirroring is 4 bytes
534 * vr_ps - Virtually pixel size for YUYV/UYVY is
535 * 2 bytes
536 */
537 ps = 4;
538 vr_ps = 2;
539 } else {
540 ps = 2; /* otherwise the pixel size is 2 byte */
541 }
542 } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) {
543 ps = 4;
544 } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) {
545 ps = 3;
546 }
547 vout->ps = ps;
548 vout->vr_ps = vr_ps;
549
550 if (rotation_enabled(vout)) {
551 line_length = MAX_PIXELS_PER_LINE;
552 ctop = (pix->height - crop->height) - crop->top;
553 cleft = (pix->width - crop->width) - crop->left;
554 } else {
555 line_length = pix->width;
556 }
557 vout->line_length = line_length;
558 switch (rotation) {
559 case dss_rotation_90_degree:
560 offset = vout->vrfb_context[0].yoffset *
561 vout->vrfb_context[0].bytespp;
562 temp_ps = ps / vr_ps;
563 if (mirroring == 0) {
564 *cropped_offset = offset + line_length *
565 temp_ps * cleft + crop->top * temp_ps;
566 } else {
567 *cropped_offset = offset + line_length * temp_ps *
568 cleft + crop->top * temp_ps + (line_length *
569 ((crop->width / (vr_ps)) - 1) * ps);
570 }
571 break;
572 case dss_rotation_180_degree:
573 offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset *
574 vout->vrfb_context[0].bytespp) +
575 (vout->vrfb_context[0].xoffset *
576 vout->vrfb_context[0].bytespp));
577 if (mirroring == 0) {
578 *cropped_offset = offset + (line_length * ps * ctop) +
579 (cleft / vr_ps) * ps;
580
581 } else {
582 *cropped_offset = offset + (line_length * ps * ctop) +
583 (cleft / vr_ps) * ps + (line_length *
584 (crop->height - 1) * ps);
585 }
586 break;
587 case dss_rotation_270_degree:
588 offset = MAX_PIXELS_PER_LINE * vout->vrfb_context[0].xoffset *
589 vout->vrfb_context[0].bytespp;
590 temp_ps = ps / vr_ps;
591 if (mirroring == 0) {
592 *cropped_offset = offset + line_length *
593 temp_ps * crop->left + ctop * ps;
594 } else {
595 *cropped_offset = offset + line_length *
596 temp_ps * crop->left + ctop * ps +
597 (line_length * ((crop->width / vr_ps) - 1) *
598 ps);
599 }
600 break;
601 case dss_rotation_0_degree:
602 if (mirroring == 0) {
603 *cropped_offset = (line_length * ps) *
604 crop->top + (crop->left / vr_ps) * ps;
605 } else {
606 *cropped_offset = (line_length * ps) *
607 crop->top + (crop->left / vr_ps) * ps +
608 (line_length * (crop->height - 1) * ps);
609 }
610 break;
611 default:
612 *cropped_offset = (line_length * ps * crop->top) /
613 vr_ps + (crop->left * ps) / vr_ps +
614 ((crop->width / vr_ps) - 1) * ps;
615 break;
616 }
617 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
618 __func__, *cropped_offset);
619 return 0;
620}
621
622/*
623 * Convert V4L2 pixel format to DSS pixel format
624 */
625static int video_mode_to_dss_mode(struct omap_vout_device *vout)
626{
627 struct omap_overlay *ovl;
628 struct omapvideo_info *ovid;
629 struct v4l2_pix_format *pix = &vout->pix;
630 enum omap_color_mode mode;
631
632 ovid = &vout->vid_info;
633 ovl = ovid->overlays[0];
634
635 switch (pix->pixelformat) {
636 case 0:
637 break;
638 case V4L2_PIX_FMT_YUYV:
639 mode = OMAP_DSS_COLOR_YUV2;
640 break;
641 case V4L2_PIX_FMT_UYVY:
642 mode = OMAP_DSS_COLOR_UYVY;
643 break;
644 case V4L2_PIX_FMT_RGB565:
645 mode = OMAP_DSS_COLOR_RGB16;
646 break;
647 case V4L2_PIX_FMT_RGB24:
648 mode = OMAP_DSS_COLOR_RGB24P;
649 break;
650 case V4L2_PIX_FMT_RGB32:
651 mode = (ovl->id == OMAP_DSS_VIDEO1) ?
652 OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
653 break;
654 case V4L2_PIX_FMT_BGR32:
655 mode = OMAP_DSS_COLOR_RGBX32;
656 break;
657 default:
658 mode = -EINVAL;
659 }
660 return mode;
661}
662
663/*
664 * Setup the overlay
665 */
666int omapvid_setup_overlay(struct omap_vout_device *vout,
667 struct omap_overlay *ovl, int posx, int posy, int outw,
668 int outh, u32 addr)
669{
670 int ret = 0;
671 struct omap_overlay_info info;
672 int cropheight, cropwidth, pixheight, pixwidth;
673
674 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
675 (outw != vout->pix.width || outh != vout->pix.height)) {
676 ret = -EINVAL;
677 goto setup_ovl_err;
678 }
679
680 vout->dss_mode = video_mode_to_dss_mode(vout);
681 if (vout->dss_mode == -EINVAL) {
682 ret = -EINVAL;
683 goto setup_ovl_err;
684 }
685
686 /* Setup the input plane parameters according to
687 * rotation value selected.
688 */
689 if (rotate_90_or_270(vout)) {
690 cropheight = vout->crop.width;
691 cropwidth = vout->crop.height;
692 pixheight = vout->pix.width;
693 pixwidth = vout->pix.height;
694 } else {
695 cropheight = vout->crop.height;
696 cropwidth = vout->crop.width;
697 pixheight = vout->pix.height;
698 pixwidth = vout->pix.width;
699 }
700
701 ovl->get_overlay_info(ovl, &info);
702 info.paddr = addr;
703 info.vaddr = NULL;
704 info.width = cropwidth;
705 info.height = cropheight;
706 info.color_mode = vout->dss_mode;
707 info.mirror = vout->mirror;
708 info.pos_x = posx;
709 info.pos_y = posy;
710 info.out_width = outw;
711 info.out_height = outh;
712 info.global_alpha = vout->win.global_alpha;
713 if (!rotation_enabled(vout)) {
714 info.rotation = 0;
715 info.rotation_type = OMAP_DSS_ROT_DMA;
716 info.screen_width = pixwidth;
717 } else {
718 info.rotation = vout->rotation;
719 info.rotation_type = OMAP_DSS_ROT_VRFB;
720 info.screen_width = 2048;
721 }
722
723 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
724 "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
725 "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
726 "out_height=%d rotation_type=%d screen_width=%d\n",
727 __func__, info.enabled, info.paddr, info.width, info.height,
728 info.color_mode, info.rotation, info.mirror, info.pos_x,
729 info.pos_y, info.out_width, info.out_height, info.rotation_type,
730 info.screen_width);
731
732 ret = ovl->set_overlay_info(ovl, &info);
733 if (ret)
734 goto setup_ovl_err;
735
736 return 0;
737
738setup_ovl_err:
739 v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n");
740 return ret;
741}
742
743/*
744 * Initialize the overlay structure
745 */
746int omapvid_init(struct omap_vout_device *vout, u32 addr)
747{
748 int ret = 0, i;
749 struct v4l2_window *win;
750 struct omap_overlay *ovl;
751 int posx, posy, outw, outh, temp;
752 struct omap_video_timings *timing;
753 struct omapvideo_info *ovid = &vout->vid_info;
754
755 win = &vout->win;
756 for (i = 0; i < ovid->num_overlays; i++) {
757 ovl = ovid->overlays[i];
758 if (!ovl->manager || !ovl->manager->device)
759 return -EINVAL;
760
761 timing = &ovl->manager->device->panel.timings;
762
763 outw = win->w.width;
764 outh = win->w.height;
765 switch (vout->rotation) {
766 case dss_rotation_90_degree:
767 /* Invert the height and width for 90
768 * and 270 degree rotation
769 */
770 temp = outw;
771 outw = outh;
772 outh = temp;
773 posy = (timing->y_res - win->w.width) - win->w.left;
774 posx = win->w.top;
775 break;
776
777 case dss_rotation_180_degree:
778 posx = (timing->x_res - win->w.width) - win->w.left;
779 posy = (timing->y_res - win->w.height) - win->w.top;
780 break;
781
782 case dss_rotation_270_degree:
783 temp = outw;
784 outw = outh;
785 outh = temp;
786 posy = win->w.left;
787 posx = (timing->x_res - win->w.height) - win->w.top;
788 break;
789
790 default:
791 posx = win->w.left;
792 posy = win->w.top;
793 break;
794 }
795
796 ret = omapvid_setup_overlay(vout, ovl, posx, posy,
797 outw, outh, addr);
798 if (ret)
799 goto omapvid_init_err;
800 }
801 return 0;
802
803omapvid_init_err:
804 v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
805 return ret;
806}
807
808/*
809 * Apply the changes set the go bit of DSS
810 */
811int omapvid_apply_changes(struct omap_vout_device *vout)
812{
813 int i;
814 struct omap_overlay *ovl;
815 struct omapvideo_info *ovid = &vout->vid_info;
816
817 for (i = 0; i < ovid->num_overlays; i++) {
818 ovl = ovid->overlays[i];
819 if (!ovl->manager || !ovl->manager->device)
820 return -EINVAL;
821 ovl->manager->apply(ovl->manager);
822 }
823
824 return 0;
825}
826
827void omap_vout_isr(void *arg, unsigned int irqstatus)
828{
829 int ret;
830 u32 addr, fid;
831 struct omap_overlay *ovl;
832 struct timeval timevalue;
833 struct omapvideo_info *ovid;
834 struct omap_dss_device *cur_display;
835 struct omap_vout_device *vout = (struct omap_vout_device *)arg;
836
837 if (!vout->streaming)
838 return;
839
840 ovid = &vout->vid_info;
841 ovl = ovid->overlays[0];
842 /* get the display device attached to the overlay */
843 if (!ovl->manager || !ovl->manager->device)
844 return;
845
846 cur_display = ovl->manager->device;
847
848 spin_lock(&vout->vbq_lock);
849 do_gettimeofday(&timevalue);
850 if (cur_display->type == OMAP_DISPLAY_TYPE_DPI) {
851 if (!(irqstatus & DISPC_IRQ_VSYNC))
852 goto vout_isr_err;
853
854 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
855 vout->cur_frm->ts = timevalue;
856 vout->cur_frm->state = VIDEOBUF_DONE;
857 wake_up_interruptible(&vout->cur_frm->done);
858 vout->cur_frm = vout->next_frm;
859 }
860 vout->first_int = 0;
861 if (list_empty(&vout->dma_queue))
862 goto vout_isr_err;
863
864 vout->next_frm = list_entry(vout->dma_queue.next,
865 struct videobuf_buffer, queue);
866 list_del(&vout->next_frm->queue);
867
868 vout->next_frm->state = VIDEOBUF_ACTIVE;
869
870 addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
871 + vout->cropped_offset;
872
873 /* First save the configuration in ovelray structure */
874 ret = omapvid_init(vout, addr);
875 if (ret)
876 printk(KERN_ERR VOUT_NAME
877 "failed to set overlay info\n");
878 /* Enable the pipeline and set the Go bit */
879 ret = omapvid_apply_changes(vout);
880 if (ret)
881 printk(KERN_ERR VOUT_NAME "failed to change mode\n");
882 } else {
883
884 if (vout->first_int) {
885 vout->first_int = 0;
886 goto vout_isr_err;
887 }
888 if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
889 fid = 1;
890 else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
891 fid = 0;
892 else
893 goto vout_isr_err;
894
895 vout->field_id ^= 1;
896 if (fid != vout->field_id) {
897 if (0 == fid)
898 vout->field_id = fid;
899
900 goto vout_isr_err;
901 }
902 if (0 == fid) {
903 if (vout->cur_frm == vout->next_frm)
904 goto vout_isr_err;
905
906 vout->cur_frm->ts = timevalue;
907 vout->cur_frm->state = VIDEOBUF_DONE;
908 wake_up_interruptible(&vout->cur_frm->done);
909 vout->cur_frm = vout->next_frm;
910 } else if (1 == fid) {
911 if (list_empty(&vout->dma_queue) ||
912 (vout->cur_frm != vout->next_frm))
913 goto vout_isr_err;
914
915 vout->next_frm = list_entry(vout->dma_queue.next,
916 struct videobuf_buffer, queue);
917 list_del(&vout->next_frm->queue);
918
919 vout->next_frm->state = VIDEOBUF_ACTIVE;
920 addr = (unsigned long)
921 vout->queued_buf_addr[vout->next_frm->i] +
922 vout->cropped_offset;
923 /* First save the configuration in ovelray structure */
924 ret = omapvid_init(vout, addr);
925 if (ret)
926 printk(KERN_ERR VOUT_NAME
927 "failed to set overlay info\n");
928 /* Enable the pipeline and set the Go bit */
929 ret = omapvid_apply_changes(vout);
930 if (ret)
931 printk(KERN_ERR VOUT_NAME
932 "failed to change mode\n");
933 }
934
935 }
936
937vout_isr_err:
938 spin_unlock(&vout->vbq_lock);
939}
940
941
942/* Video buffer call backs */
943
944/*
945 * Buffer setup function is called by videobuf layer when REQBUF ioctl is
946 * called. This is used to setup buffers and return size and count of
947 * buffers allocated. After the call to this buffer, videobuf layer will
948 * setup buffer queue depending on the size and count of buffers
949 */
950static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
951 unsigned int *size)
952{
953 int startindex = 0, i, j;
954 u32 phy_addr = 0, virt_addr = 0;
955 struct omap_vout_device *vout = q->priv_data;
956
957 if (!vout)
958 return -EINVAL;
959
960 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
961 return -EINVAL;
962
963 startindex = (vout->vid == OMAP_VIDEO1) ?
964 video1_numbuffers : video2_numbuffers;
965 if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
966 *count = startindex;
967
968 if ((rotation_enabled(vout)) && *count > VRFB_NUM_BUFS)
969 *count = VRFB_NUM_BUFS;
970
971 /* If rotation is enabled, allocate memory for VRFB space also */
972 if (rotation_enabled(vout))
973 if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
974 return -ENOMEM;
975
976 if (V4L2_MEMORY_MMAP != vout->memory)
977 return 0;
978
979 /* Now allocated the V4L2 buffers */
980 *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
981 startindex = (vout->vid == OMAP_VIDEO1) ?
982 video1_numbuffers : video2_numbuffers;
983
984 for (i = startindex; i < *count; i++) {
985 vout->buffer_size = *size;
986
987 virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
988 &phy_addr);
989 if (!virt_addr) {
990 if (!rotation_enabled(vout))
991 break;
992 /* Free the VRFB buffers if no space for V4L2 buffers */
993 for (j = i; j < *count; j++) {
994 omap_vout_free_buffer(
995 vout->smsshado_virt_addr[j],
996 vout->smsshado_size);
997 vout->smsshado_virt_addr[j] = 0;
998 vout->smsshado_phy_addr[j] = 0;
999 }
1000 }
1001 vout->buf_virt_addr[i] = virt_addr;
1002 vout->buf_phy_addr[i] = phy_addr;
1003 }
1004 *count = vout->buffer_allocated = i;
1005
1006 return 0;
1007}
1008
1009/*
1010 * Free the V4L2 buffers additionally allocated than default
1011 * number of buffers and free all the VRFB buffers
1012 */
1013static void omap_vout_free_allbuffers(struct omap_vout_device *vout)
1014{
1015 int num_buffers = 0, i;
1016
1017 num_buffers = (vout->vid == OMAP_VIDEO1) ?
1018 video1_numbuffers : video2_numbuffers;
1019
1020 for (i = num_buffers; i < vout->buffer_allocated; i++) {
1021 if (vout->buf_virt_addr[i])
1022 omap_vout_free_buffer(vout->buf_virt_addr[i],
1023 vout->buffer_size);
1024
1025 vout->buf_virt_addr[i] = 0;
1026 vout->buf_phy_addr[i] = 0;
1027 }
1028 /* Free the VRFB buffers only if they are allocated
1029 * during reqbufs. Don't free if init time allocated
1030 */
1031 if (!vout->vrfb_static_allocation) {
1032 for (i = 0; i < VRFB_NUM_BUFS; i++) {
1033 if (vout->smsshado_virt_addr[i]) {
1034 omap_vout_free_buffer(
1035 vout->smsshado_virt_addr[i],
1036 vout->smsshado_size);
1037 vout->smsshado_virt_addr[i] = 0;
1038 vout->smsshado_phy_addr[i] = 0;
1039 }
1040 }
1041 }
1042 vout->buffer_allocated = num_buffers;
1043}
1044
1045/*
1046 * This function will be called when VIDIOC_QBUF ioctl is called.
1047 * It prepare buffers before give out for the display. This function
1048 * converts user space virtual address into physical address if userptr memory
1049 * exchange mechanism is used. If rotation is enabled, it copies entire
1050 * buffer into VRFB memory space before giving it to the DSS.
1051 */
1052static int omap_vout_buffer_prepare(struct videobuf_queue *q,
1053 struct videobuf_buffer *vb,
1054 enum v4l2_field field)
1055{
1056 struct vid_vrfb_dma *tx;
1057 enum dss_rotation rotation;
1058 struct videobuf_dmabuf *dmabuf = NULL;
1059 struct omap_vout_device *vout = q->priv_data;
1060 u32 dest_frame_index = 0, src_element_index = 0;
1061 u32 dest_element_index = 0, src_frame_index = 0;
1062 u32 elem_count = 0, frame_count = 0, pixsize = 2;
1063
1064 if (VIDEOBUF_NEEDS_INIT == vb->state) {
1065 vb->width = vout->pix.width;
1066 vb->height = vout->pix.height;
1067 vb->size = vb->width * vb->height * vout->bpp;
1068 vb->field = field;
1069 }
1070 vb->state = VIDEOBUF_PREPARED;
1071 /* if user pointer memory mechanism is used, get the physical
1072 * address of the buffer
1073 */
1074 if (V4L2_MEMORY_USERPTR == vb->memory) {
1075 if (0 == vb->baddr)
1076 return -EINVAL;
1077 /* Virtual address */
1078 /* priv points to struct videobuf_pci_sg_memory. But we went
1079 * pointer to videobuf_dmabuf, which is member of
1080 * videobuf_pci_sg_memory */
1081 dmabuf = videobuf_to_dma(q->bufs[vb->i]);
1082 dmabuf->vmalloc = (void *) vb->baddr;
1083
1084 /* Physical address */
1085 dmabuf->bus_addr =
1086 (dma_addr_t) omap_vout_uservirt_to_phys(vb->baddr);
1087 }
1088
1089 if (!rotation_enabled(vout)) {
1090 dmabuf = videobuf_to_dma(q->bufs[vb->i]);
1091 vout->queued_buf_addr[vb->i] = (u8 *) dmabuf->bus_addr;
1092 return 0;
1093 }
1094 dmabuf = videobuf_to_dma(q->bufs[vb->i]);
1095 /* If rotation is enabled, copy input buffer into VRFB
1096 * memory space using DMA. We are copying input buffer
1097 * into VRFB memory space of desired angle and DSS will
1098 * read image VRFB memory for 0 degree angle
1099 */
1100 pixsize = vout->bpp * vout->vrfb_bpp;
1101 /*
1102 * DMA transfer in double index mode
1103 */
1104
1105 /* Frame index */
1106 dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
1107 (vout->pix.width * vout->bpp)) + 1;
1108
1109 /* Source and destination parameters */
1110 src_element_index = 0;
1111 src_frame_index = 0;
1112 dest_element_index = 1;
1113 /* Number of elements per frame */
1114 elem_count = vout->pix.width * vout->bpp;
1115 frame_count = vout->pix.height;
1116 tx = &vout->vrfb_dma_tx;
1117 tx->tx_status = 0;
1118 omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
1119 (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
1120 tx->dev_id, 0x0);
1121 /* src_port required only for OMAP1 */
1122 omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
1123 dmabuf->bus_addr, src_element_index, src_frame_index);
1124 /*set dma source burst mode for VRFB */
1125 omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
1126 rotation = calc_rotation(vout);
1127
1128 /* dest_port required only for OMAP1 */
1129 omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
1130 vout->vrfb_context[vb->i].paddr[0], dest_element_index,
1131 dest_frame_index);
1132 /*set dma dest burst mode for VRFB */
1133 omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
1134 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
1135
1136 omap_start_dma(tx->dma_ch);
1137 interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
1138
1139 if (tx->tx_status == 0) {
1140 omap_stop_dma(tx->dma_ch);
1141 return -EINVAL;
1142 }
1143 /* Store buffers physical address into an array. Addresses
1144 * from this array will be used to configure DSS */
1145 vout->queued_buf_addr[vb->i] = (u8 *)
1146 vout->vrfb_context[vb->i].paddr[rotation];
1147 return 0;
1148}
1149
1150/*
1151 * Buffer queue funtion will be called from the videobuf layer when _QBUF
1152 * ioctl is called. It is used to enqueue buffer, which is ready to be
1153 * displayed.
1154 */
1155static void omap_vout_buffer_queue(struct videobuf_queue *q,
1156 struct videobuf_buffer *vb)
1157{
1158 struct omap_vout_device *vout = q->priv_data;
1159
1160 /* Driver is also maintainig a queue. So enqueue buffer in the driver
1161 * queue */
1162 list_add_tail(&vb->queue, &vout->dma_queue);
1163
1164 vb->state = VIDEOBUF_QUEUED;
1165}
1166
1167/*
1168 * Buffer release function is called from videobuf layer to release buffer
1169 * which are already allocated
1170 */
1171static void omap_vout_buffer_release(struct videobuf_queue *q,
1172 struct videobuf_buffer *vb)
1173{
1174 struct omap_vout_device *vout = q->priv_data;
1175
1176 vb->state = VIDEOBUF_NEEDS_INIT;
1177
1178 if (V4L2_MEMORY_MMAP != vout->memory)
1179 return;
1180}
1181
1182/*
1183 * File operations
1184 */
1185static void omap_vout_vm_open(struct vm_area_struct *vma)
1186{
1187 struct omap_vout_device *vout = vma->vm_private_data;
1188
1189 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1190 "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
1191 vout->mmap_count++;
1192}
1193
1194static void omap_vout_vm_close(struct vm_area_struct *vma)
1195{
1196 struct omap_vout_device *vout = vma->vm_private_data;
1197
1198 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1199 "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
1200 vout->mmap_count--;
1201}
1202
1203static struct vm_operations_struct omap_vout_vm_ops = {
1204 .open = omap_vout_vm_open,
1205 .close = omap_vout_vm_close,
1206};
1207
1208static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
1209{
1210 int i;
1211 void *pos;
1212 unsigned long start = vma->vm_start;
1213 unsigned long size = (vma->vm_end - vma->vm_start);
1214 struct videobuf_dmabuf *dmabuf = NULL;
1215 struct omap_vout_device *vout = file->private_data;
1216 struct videobuf_queue *q = &vout->vbq;
1217
1218 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1219 " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
1220 vma->vm_pgoff, vma->vm_start, vma->vm_end);
1221
1222 /* look for the buffer to map */
1223 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1224 if (NULL == q->bufs[i])
1225 continue;
1226 if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
1227 continue;
1228 if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
1229 break;
1230 }
1231
1232 if (VIDEO_MAX_FRAME == i) {
1233 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1234 "offset invalid [offset=0x%lx]\n",
1235 (vma->vm_pgoff << PAGE_SHIFT));
1236 return -EINVAL;
1237 }
1238 q->bufs[i]->baddr = vma->vm_start;
1239
1240 vma->vm_flags |= VM_RESERVED;
1241 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1242 vma->vm_ops = &omap_vout_vm_ops;
1243 vma->vm_private_data = (void *) vout;
1244 dmabuf = videobuf_to_dma(q->bufs[i]);
1245 pos = dmabuf->vmalloc;
1246 vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
1247 while (size > 0) {
1248 unsigned long pfn;
1249 pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
1250 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
1251 return -EAGAIN;
1252 start += PAGE_SIZE;
1253 pos += PAGE_SIZE;
1254 size -= PAGE_SIZE;
1255 }
1256 vout->mmap_count++;
1257 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1258
1259 return 0;
1260}
1261
1262static int omap_vout_release(struct file *file)
1263{
1264 unsigned int ret, i;
1265 struct videobuf_queue *q;
1266 struct omapvideo_info *ovid;
1267 struct omap_vout_device *vout = file->private_data;
1268
1269 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1270 ovid = &vout->vid_info;
1271
1272 if (!vout)
1273 return 0;
1274
1275 q = &vout->vbq;
1276 /* Disable all the overlay managers connected with this interface */
1277 for (i = 0; i < ovid->num_overlays; i++) {
1278 struct omap_overlay *ovl = ovid->overlays[i];
1279 if (ovl->manager && ovl->manager->device) {
1280 struct omap_overlay_info info;
1281 ovl->get_overlay_info(ovl, &info);
1282 info.enabled = 0;
1283 ovl->set_overlay_info(ovl, &info);
1284 }
1285 }
1286 /* Turn off the pipeline */
1287 ret = omapvid_apply_changes(vout);
1288 if (ret)
1289 v4l2_warn(&vout->vid_dev->v4l2_dev,
1290 "Unable to apply changes\n");
1291
1292 /* Free all buffers */
1293 omap_vout_free_allbuffers(vout);
1294 videobuf_mmap_free(q);
1295
1296 /* Even if apply changes fails we should continue
1297 freeing allocated memeory */
1298 if (vout->streaming) {
1299 u32 mask = 0;
1300
1301 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
1302 DISPC_IRQ_EVSYNC_ODD;
1303 omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1304 vout->streaming = 0;
1305
1306 videobuf_streamoff(q);
1307 videobuf_queue_cancel(q);
1308 }
1309
1310 if (vout->mmap_count != 0)
1311 vout->mmap_count = 0;
1312
1313 vout->opened -= 1;
1314 file->private_data = NULL;
1315
1316 if (vout->buffer_allocated)
1317 videobuf_mmap_free(q);
1318
1319 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1320 return ret;
1321}
1322
1323static int omap_vout_open(struct file *file)
1324{
1325 struct videobuf_queue *q;
1326 struct omap_vout_device *vout = NULL;
1327
1328 vout = video_drvdata(file);
1329 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1330
1331 if (vout == NULL)
1332 return -ENODEV;
1333
1334 /* for now, we only support single open */
1335 if (vout->opened)
1336 return -EBUSY;
1337
1338 vout->opened += 1;
1339
1340 file->private_data = vout;
1341 vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1342
1343 q = &vout->vbq;
1344 video_vbq_ops.buf_setup = omap_vout_buffer_setup;
1345 video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
1346 video_vbq_ops.buf_release = omap_vout_buffer_release;
1347 video_vbq_ops.buf_queue = omap_vout_buffer_queue;
1348 spin_lock_init(&vout->vbq_lock);
1349
1350 videobuf_queue_sg_init(q, &video_vbq_ops, NULL, &vout->vbq_lock,
1351 vout->type, V4L2_FIELD_NONE,
1352 sizeof(struct videobuf_buffer), vout);
1353
1354 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1355 return 0;
1356}
1357
1358/*
1359 * V4L2 ioctls
1360 */
1361static int vidioc_querycap(struct file *file, void *fh,
1362 struct v4l2_capability *cap)
1363{
1364 struct omap_vout_device *vout = fh;
1365
1366 strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
1367 strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
1368 cap->bus_info[0] = '\0';
1369 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
1370
1371 return 0;
1372}
1373
1374static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
1375 struct v4l2_fmtdesc *fmt)
1376{
1377 int index = fmt->index;
1378 enum v4l2_buf_type type = fmt->type;
1379
1380 fmt->index = index;
1381 fmt->type = type;
1382 if (index >= NUM_OUTPUT_FORMATS)
1383 return -EINVAL;
1384
1385 fmt->flags = omap_formats[index].flags;
1386 strlcpy(fmt->description, omap_formats[index].description,
1387 sizeof(fmt->description));
1388 fmt->pixelformat = omap_formats[index].pixelformat;
1389
1390 return 0;
1391}
1392
1393static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
1394 struct v4l2_format *f)
1395{
1396 struct omap_vout_device *vout = fh;
1397
1398 f->fmt.pix = vout->pix;
1399 return 0;
1400
1401}
1402
1403static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
1404 struct v4l2_format *f)
1405{
1406 struct omap_overlay *ovl;
1407 struct omapvideo_info *ovid;
1408 struct omap_video_timings *timing;
1409 struct omap_vout_device *vout = fh;
1410
1411 ovid = &vout->vid_info;
1412 ovl = ovid->overlays[0];
1413
1414 if (!ovl->manager || !ovl->manager->device)
1415 return -EINVAL;
1416 /* get the display device attached to the overlay */
1417 timing = &ovl->manager->device->panel.timings;
1418
1419 vout->fbuf.fmt.height = timing->y_res;
1420 vout->fbuf.fmt.width = timing->x_res;
1421
1422 omap_vout_try_format(&f->fmt.pix);
1423 return 0;
1424}
1425
1426static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1427 struct v4l2_format *f)
1428{
1429 int ret, bpp;
1430 struct omap_overlay *ovl;
1431 struct omapvideo_info *ovid;
1432 struct omap_video_timings *timing;
1433 struct omap_vout_device *vout = fh;
1434
1435 if (vout->streaming)
1436 return -EBUSY;
1437
1438 mutex_lock(&vout->lock);
1439
1440 ovid = &vout->vid_info;
1441 ovl = ovid->overlays[0];
1442
1443 /* get the display device attached to the overlay */
1444 if (!ovl->manager || !ovl->manager->device) {
1445 ret = -EINVAL;
1446 goto s_fmt_vid_out_exit;
1447 }
1448 timing = &ovl->manager->device->panel.timings;
1449
1450 /* We dont support RGB24-packed mode if vrfb rotation
1451 * is enabled*/
1452 if ((rotation_enabled(vout)) &&
1453 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1454 ret = -EINVAL;
1455 goto s_fmt_vid_out_exit;
1456 }
1457
1458 /* get the framebuffer parameters */
1459
1460 if (rotate_90_or_270(vout)) {
1461 vout->fbuf.fmt.height = timing->x_res;
1462 vout->fbuf.fmt.width = timing->y_res;
1463 } else {
1464 vout->fbuf.fmt.height = timing->y_res;
1465 vout->fbuf.fmt.width = timing->x_res;
1466 }
1467
1468 /* change to samller size is OK */
1469
1470 bpp = omap_vout_try_format(&f->fmt.pix);
1471 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
1472
1473 /* try & set the new output format */
1474 vout->bpp = bpp;
1475 vout->pix = f->fmt.pix;
1476 vout->vrfb_bpp = 1;
1477
1478 /* If YUYV then vrfb bpp is 2, for others its 1 */
1479 if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
1480 V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
1481 vout->vrfb_bpp = 2;
1482
1483 /* set default crop and win */
1484 omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
1485
1486 /* Save the changes in the overlay strcuture */
1487 ret = omapvid_init(vout, 0);
1488 if (ret) {
1489 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1490 goto s_fmt_vid_out_exit;
1491 }
1492
1493 ret = 0;
1494
1495s_fmt_vid_out_exit:
1496 mutex_unlock(&vout->lock);
1497 return ret;
1498}
1499
1500static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
1501 struct v4l2_format *f)
1502{
1503 int ret = 0;
1504 struct omap_vout_device *vout = fh;
1505 struct v4l2_window *win = &f->fmt.win;
1506
1507 ret = omap_vout_try_window(&vout->fbuf, win);
1508
1509 if (!ret) {
1510 if (vout->vid == OMAP_VIDEO1)
1511 win->global_alpha = 255;
1512 else
1513 win->global_alpha = f->fmt.win.global_alpha;
1514 }
1515
1516 return ret;
1517}
1518
1519static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
1520 struct v4l2_format *f)
1521{
1522 int ret = 0;
1523 struct omap_overlay *ovl;
1524 struct omapvideo_info *ovid;
1525 struct omap_vout_device *vout = fh;
1526 struct v4l2_window *win = &f->fmt.win;
1527
1528 mutex_lock(&vout->lock);
1529 ovid = &vout->vid_info;
1530 ovl = ovid->overlays[0];
1531
1532 ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
1533 if (!ret) {
1534 /* Video1 plane does not support global alpha */
1535 if (ovl->id == OMAP_DSS_VIDEO1)
1536 vout->win.global_alpha = 255;
1537 else
1538 vout->win.global_alpha = f->fmt.win.global_alpha;
1539
1540 vout->win.chromakey = f->fmt.win.chromakey;
1541 }
1542 mutex_unlock(&vout->lock);
1543 return ret;
1544}
1545
1546static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh,
1547 struct v4l2_fmtdesc *fmt)
1548{
1549 int index = fmt->index;
1550 enum v4l2_buf_type type = fmt->type;
1551
1552 fmt->index = index;
1553 fmt->type = type;
1554 if (index >= NUM_OUTPUT_FORMATS)
1555 return -EINVAL;
1556
1557 fmt->flags = omap_formats[index].flags;
1558 strlcpy(fmt->description, omap_formats[index].description,
1559 sizeof(fmt->description));
1560 fmt->pixelformat = omap_formats[index].pixelformat;
1561 return 0;
1562}
1563
1564static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
1565 struct v4l2_format *f)
1566{
1567 u32 key_value = 0;
1568 struct omap_overlay *ovl;
1569 struct omapvideo_info *ovid;
1570 struct omap_vout_device *vout = fh;
1571 struct omap_overlay_manager_info info;
1572 struct v4l2_window *win = &f->fmt.win;
1573
1574 ovid = &vout->vid_info;
1575 ovl = ovid->overlays[0];
1576
1577 win->w = vout->win.w;
1578 win->field = vout->win.field;
1579 win->global_alpha = vout->win.global_alpha;
1580
1581 if (ovl->manager && ovl->manager->get_manager_info) {
1582 ovl->manager->get_manager_info(ovl->manager, &info);
1583 key_value = info.trans_key;
1584 }
1585 win->chromakey = key_value;
1586 return 0;
1587}
1588
1589static int vidioc_cropcap(struct file *file, void *fh,
1590 struct v4l2_cropcap *cropcap)
1591{
1592 struct omap_vout_device *vout = fh;
1593 struct v4l2_pix_format *pix = &vout->pix;
1594
1595 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1596 return -EINVAL;
1597
1598 /* Width and height are always even */
1599 cropcap->bounds.width = pix->width & ~1;
1600 cropcap->bounds.height = pix->height & ~1;
1601
1602 omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect);
1603 cropcap->pixelaspect.numerator = 1;
1604 cropcap->pixelaspect.denominator = 1;
1605 return 0;
1606}
1607
1608static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1609{
1610 struct omap_vout_device *vout = fh;
1611
1612 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1613 return -EINVAL;
1614 crop->c = vout->crop;
1615 return 0;
1616}
1617
1618static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1619{
1620 int ret = -EINVAL;
1621 struct omap_vout_device *vout = fh;
1622 struct omapvideo_info *ovid;
1623 struct omap_overlay *ovl;
1624 struct omap_video_timings *timing;
1625
1626 if (vout->streaming)
1627 return -EBUSY;
1628
1629 mutex_lock(&vout->lock);
1630 ovid = &vout->vid_info;
1631 ovl = ovid->overlays[0];
1632
1633 if (!ovl->manager || !ovl->manager->device) {
1634 ret = -EINVAL;
1635 goto s_crop_err;
1636 }
1637 /* get the display device attached to the overlay */
1638 timing = &ovl->manager->device->panel.timings;
1639
1640 if (rotate_90_or_270(vout)) {
1641 vout->fbuf.fmt.height = timing->x_res;
1642 vout->fbuf.fmt.width = timing->y_res;
1643 } else {
1644 vout->fbuf.fmt.height = timing->y_res;
1645 vout->fbuf.fmt.width = timing->x_res;
1646 }
1647
1648 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1649 ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
1650 &vout->fbuf, &crop->c);
1651
1652s_crop_err:
1653 mutex_unlock(&vout->lock);
1654 return ret;
1655}
1656
1657static int vidioc_queryctrl(struct file *file, void *fh,
1658 struct v4l2_queryctrl *ctrl)
1659{
1660 int ret = 0;
1661
1662 switch (ctrl->id) {
1663 case V4L2_CID_ROTATE:
1664 ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
1665 break;
1666 case V4L2_CID_BG_COLOR:
1667 ret = v4l2_ctrl_query_fill(ctrl, 0, 0xFFFFFF, 1, 0);
1668 break;
1669 case V4L2_CID_VFLIP:
1670 ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
1671 break;
1672 default:
1673 ctrl->name[0] = '\0';
1674 ret = -EINVAL;
1675 }
1676 return ret;
1677}
1678
1679static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
1680{
1681 int ret = 0;
1682 struct omap_vout_device *vout = fh;
1683
1684 switch (ctrl->id) {
1685 case V4L2_CID_ROTATE:
1686 ctrl->value = vout->control[0].value;
1687 break;
1688 case V4L2_CID_BG_COLOR:
1689 {
1690 struct omap_overlay_manager_info info;
1691 struct omap_overlay *ovl;
1692
1693 ovl = vout->vid_info.overlays[0];
1694 if (!ovl->manager || !ovl->manager->get_manager_info) {
1695 ret = -EINVAL;
1696 break;
1697 }
1698
1699 ovl->manager->get_manager_info(ovl->manager, &info);
1700 ctrl->value = info.default_color;
1701 break;
1702 }
1703 case V4L2_CID_VFLIP:
1704 ctrl->value = vout->control[2].value;
1705 break;
1706 default:
1707 ret = -EINVAL;
1708 }
1709 return ret;
1710}
1711
1712static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
1713{
1714 int ret = 0;
1715 struct omap_vout_device *vout = fh;
1716
1717 switch (a->id) {
1718 case V4L2_CID_ROTATE:
1719 {
1720 int rotation = a->value;
1721
1722 mutex_lock(&vout->lock);
1723
1724 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1725 mutex_unlock(&vout->lock);
1726 ret = -EINVAL;
1727 break;
1728 }
1729
1730 if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
1731 vout->mirror)) {
1732 mutex_unlock(&vout->lock);
1733 ret = -EINVAL;
1734 break;
1735 }
1736
1737 vout->control[0].value = rotation;
1738 mutex_unlock(&vout->lock);
1739 break;
1740 }
1741 case V4L2_CID_BG_COLOR:
1742 {
1743 struct omap_overlay *ovl;
1744 unsigned int color = a->value;
1745 struct omap_overlay_manager_info info;
1746
1747 ovl = vout->vid_info.overlays[0];
1748
1749 mutex_lock(&vout->lock);
1750 if (!ovl->manager || !ovl->manager->get_manager_info) {
1751 mutex_unlock(&vout->lock);
1752 ret = -EINVAL;
1753 break;
1754 }
1755
1756 ovl->manager->get_manager_info(ovl->manager, &info);
1757 info.default_color = color;
1758 if (ovl->manager->set_manager_info(ovl->manager, &info)) {
1759 mutex_unlock(&vout->lock);
1760 ret = -EINVAL;
1761 break;
1762 }
1763
1764 vout->control[1].value = color;
1765 mutex_unlock(&vout->lock);
1766 break;
1767 }
1768 case V4L2_CID_VFLIP:
1769 {
1770 struct omap_overlay *ovl;
1771 struct omapvideo_info *ovid;
1772 unsigned int mirror = a->value;
1773
1774 ovid = &vout->vid_info;
1775 ovl = ovid->overlays[0];
1776
1777 mutex_lock(&vout->lock);
1778
1779 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1780 mutex_unlock(&vout->lock);
1781 ret = -EINVAL;
1782 break;
1783 }
1784 vout->mirror = mirror;
1785 vout->control[2].value = mirror;
1786 mutex_unlock(&vout->lock);
1787 break;
1788 }
1789 default:
1790 ret = -EINVAL;
1791 }
1792 return ret;
1793}
1794
1795static int vidioc_reqbufs(struct file *file, void *fh,
1796 struct v4l2_requestbuffers *req)
1797{
1798 int ret = 0;
1799 unsigned int i, num_buffers = 0;
1800 struct omap_vout_device *vout = fh;
1801 struct videobuf_queue *q = &vout->vbq;
1802 struct videobuf_dmabuf *dmabuf = NULL;
1803
1804 if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0))
1805 return -EINVAL;
1806 /* if memory is not mmp or userptr
1807 return error */
1808 if ((V4L2_MEMORY_MMAP != req->memory) &&
1809 (V4L2_MEMORY_USERPTR != req->memory))
1810 return -EINVAL;
1811
1812 mutex_lock(&vout->lock);
1813 /* Cannot be requested when streaming is on */
1814 if (vout->streaming) {
1815 ret = -EBUSY;
1816 goto reqbuf_err;
1817 }
1818
1819 /* If buffers are already allocated free them */
1820 if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
1821 if (vout->mmap_count) {
1822 ret = -EBUSY;
1823 goto reqbuf_err;
1824 }
1825 num_buffers = (vout->vid == OMAP_VIDEO1) ?
1826 video1_numbuffers : video2_numbuffers;
1827 for (i = num_buffers; i < vout->buffer_allocated; i++) {
1828 dmabuf = videobuf_to_dma(q->bufs[i]);
1829 omap_vout_free_buffer((u32)dmabuf->vmalloc,
1830 vout->buffer_size);
1831 vout->buf_virt_addr[i] = 0;
1832 vout->buf_phy_addr[i] = 0;
1833 }
1834 vout->buffer_allocated = num_buffers;
1835 videobuf_mmap_free(q);
1836 } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
1837 if (vout->buffer_allocated) {
1838 videobuf_mmap_free(q);
1839 for (i = 0; i < vout->buffer_allocated; i++) {
1840 kfree(q->bufs[i]);
1841 q->bufs[i] = NULL;
1842 }
1843 vout->buffer_allocated = 0;
1844 }
1845 }
1846
1847 /*store the memory type in data structure */
1848 vout->memory = req->memory;
1849
1850 INIT_LIST_HEAD(&vout->dma_queue);
1851
1852 /* call videobuf_reqbufs api */
1853 ret = videobuf_reqbufs(q, req);
1854 if (ret < 0)
1855 goto reqbuf_err;
1856
1857 vout->buffer_allocated = req->count;
1858 for (i = 0; i < req->count; i++) {
1859 dmabuf = videobuf_to_dma(q->bufs[i]);
1860 dmabuf->vmalloc = (void *) vout->buf_virt_addr[i];
1861 dmabuf->bus_addr = (dma_addr_t) vout->buf_phy_addr[i];
1862 dmabuf->sglen = 1;
1863 }
1864reqbuf_err:
1865 mutex_unlock(&vout->lock);
1866 return ret;
1867}
1868
1869static int vidioc_querybuf(struct file *file, void *fh,
1870 struct v4l2_buffer *b)
1871{
1872 struct omap_vout_device *vout = fh;
1873
1874 return videobuf_querybuf(&vout->vbq, b);
1875}
1876
1877static int vidioc_qbuf(struct file *file, void *fh,
1878 struct v4l2_buffer *buffer)
1879{
1880 struct omap_vout_device *vout = fh;
1881 struct videobuf_queue *q = &vout->vbq;
1882
1883 if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
1884 (buffer->index >= vout->buffer_allocated) ||
1885 (q->bufs[buffer->index]->memory != buffer->memory)) {
1886 return -EINVAL;
1887 }
1888 if (V4L2_MEMORY_USERPTR == buffer->memory) {
1889 if ((buffer->length < vout->pix.sizeimage) ||
1890 (0 == buffer->m.userptr)) {
1891 return -EINVAL;
1892 }
1893 }
1894
1895 if ((rotation_enabled(vout)) &&
1896 vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
1897 v4l2_warn(&vout->vid_dev->v4l2_dev,
1898 "DMA Channel not allocated for Rotation\n");
1899 return -EINVAL;
1900 }
1901
1902 return videobuf_qbuf(q, buffer);
1903}
1904
1905static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1906{
1907 struct omap_vout_device *vout = fh;
1908 struct videobuf_queue *q = &vout->vbq;
1909
1910 if (!vout->streaming)
1911 return -EINVAL;
1912
1913 if (file->f_flags & O_NONBLOCK)
1914 /* Call videobuf_dqbuf for non blocking mode */
1915 return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
1916 else
1917 /* Call videobuf_dqbuf for blocking mode */
1918 return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
1919}
1920
1921static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1922{
1923 int ret = 0, j;
1924 u32 addr = 0, mask = 0;
1925 struct omap_vout_device *vout = fh;
1926 struct videobuf_queue *q = &vout->vbq;
1927 struct omapvideo_info *ovid = &vout->vid_info;
1928
1929 mutex_lock(&vout->lock);
1930
1931 if (vout->streaming) {
1932 ret = -EBUSY;
1933 goto streamon_err;
1934 }
1935
1936 ret = videobuf_streamon(q);
1937 if (ret)
1938 goto streamon_err;
1939
1940 if (list_empty(&vout->dma_queue)) {
1941 ret = -EIO;
1942 goto streamon_err1;
1943 }
1944
1945 /* Get the next frame from the buffer queue */
1946 vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
1947 struct videobuf_buffer, queue);
1948 /* Remove buffer from the buffer queue */
1949 list_del(&vout->cur_frm->queue);
1950 /* Mark state of the current frame to active */
1951 vout->cur_frm->state = VIDEOBUF_ACTIVE;
1952 /* Initialize field_id and started member */
1953 vout->field_id = 0;
1954
1955 /* set flag here. Next QBUF will start DMA */
1956 vout->streaming = 1;
1957
1958 vout->first_int = 1;
1959
1960 if (omap_vout_calculate_offset(vout)) {
1961 ret = -EINVAL;
1962 goto streamon_err1;
1963 }
1964 addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
1965 + vout->cropped_offset;
1966
1967 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
1968
1969 omap_dispc_register_isr(omap_vout_isr, vout, mask);
1970
1971 for (j = 0; j < ovid->num_overlays; j++) {
1972 struct omap_overlay *ovl = ovid->overlays[j];
1973
1974 if (ovl->manager && ovl->manager->device) {
1975 struct omap_overlay_info info;
1976 ovl->get_overlay_info(ovl, &info);
1977 info.enabled = 1;
1978 info.paddr = addr;
1979 if (ovl->set_overlay_info(ovl, &info)) {
1980 ret = -EINVAL;
1981 goto streamon_err1;
1982 }
1983 }
1984 }
1985
1986 /* First save the configuration in ovelray structure */
1987 ret = omapvid_init(vout, addr);
1988 if (ret)
1989 v4l2_err(&vout->vid_dev->v4l2_dev,
1990 "failed to set overlay info\n");
1991 /* Enable the pipeline and set the Go bit */
1992 ret = omapvid_apply_changes(vout);
1993 if (ret)
1994 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1995
1996 ret = 0;
1997
1998streamon_err1:
1999 if (ret)
2000 ret = videobuf_streamoff(q);
2001streamon_err:
2002 mutex_unlock(&vout->lock);
2003 return ret;
2004}
2005
2006static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
2007{
2008 u32 mask = 0;
2009 int ret = 0, j;
2010 struct omap_vout_device *vout = fh;
2011 struct omapvideo_info *ovid = &vout->vid_info;
2012
2013 if (!vout->streaming)
2014 return -EINVAL;
2015
2016 vout->streaming = 0;
2017 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
2018
2019 omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
2020
2021 for (j = 0; j < ovid->num_overlays; j++) {
2022 struct omap_overlay *ovl = ovid->overlays[j];
2023
2024 if (ovl->manager && ovl->manager->device) {
2025 struct omap_overlay_info info;
2026
2027 ovl->get_overlay_info(ovl, &info);
2028 info.enabled = 0;
2029 ret = ovl->set_overlay_info(ovl, &info);
2030 if (ret)
2031 v4l2_err(&vout->vid_dev->v4l2_dev,
2032 "failed to update overlay info in streamoff\n");
2033 }
2034 }
2035
2036 /* Turn of the pipeline */
2037 ret = omapvid_apply_changes(vout);
2038 if (ret)
2039 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in"
2040 " streamoff\n");
2041
2042 INIT_LIST_HEAD(&vout->dma_queue);
2043 ret = videobuf_streamoff(&vout->vbq);
2044
2045 return ret;
2046}
2047
2048static int vidioc_s_fbuf(struct file *file, void *fh,
2049 struct v4l2_framebuffer *a)
2050{
2051 int enable = 0;
2052 struct omap_overlay *ovl;
2053 struct omapvideo_info *ovid;
2054 struct omap_vout_device *vout = fh;
2055 struct omap_overlay_manager_info info;
2056 enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
2057
2058 ovid = &vout->vid_info;
2059 ovl = ovid->overlays[0];
2060
2061 /* OMAP DSS doesn't support Source and Destination color
2062 key together */
2063 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
2064 (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
2065 return -EINVAL;
2066 /* OMAP DSS Doesn't support the Destination color key
2067 and alpha blending together */
2068 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
2069 (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
2070 return -EINVAL;
2071
2072 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
2073 vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
2074 key_type = OMAP_DSS_COLOR_KEY_VID_SRC;
2075 } else
2076 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
2077
2078 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
2079 vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
2080 key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
2081 } else
2082 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
2083
2084 if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
2085 V4L2_FBUF_FLAG_SRC_CHROMAKEY))
2086 enable = 1;
2087 else
2088 enable = 0;
2089 if (ovl->manager && ovl->manager->get_manager_info &&
2090 ovl->manager->set_manager_info) {
2091
2092 ovl->manager->get_manager_info(ovl->manager, &info);
2093 info.trans_enabled = enable;
2094 info.trans_key_type = key_type;
2095 info.trans_key = vout->win.chromakey;
2096
2097 if (ovl->manager->set_manager_info(ovl->manager, &info))
2098 return -EINVAL;
2099 }
2100 if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
2101 vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
2102 enable = 1;
2103 } else {
2104 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
2105 enable = 0;
2106 }
2107 if (ovl->manager && ovl->manager->get_manager_info &&
2108 ovl->manager->set_manager_info) {
2109 ovl->manager->get_manager_info(ovl->manager, &info);
2110 info.alpha_enabled = enable;
2111 if (ovl->manager->set_manager_info(ovl->manager, &info))
2112 return -EINVAL;
2113 }
2114
2115 return 0;
2116}
2117
2118static int vidioc_g_fbuf(struct file *file, void *fh,
2119 struct v4l2_framebuffer *a)
2120{
2121 struct omap_overlay *ovl;
2122 struct omapvideo_info *ovid;
2123 struct omap_vout_device *vout = fh;
2124 struct omap_overlay_manager_info info;
2125
2126 ovid = &vout->vid_info;
2127 ovl = ovid->overlays[0];
2128
2129 a->flags = 0x0;
2130 a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
2131 | V4L2_FBUF_CAP_SRC_CHROMAKEY;
2132
2133 if (ovl->manager && ovl->manager->get_manager_info) {
2134 ovl->manager->get_manager_info(ovl->manager, &info);
2135 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
2136 a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
2137 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
2138 a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
2139 }
2140 if (ovl->manager && ovl->manager->get_manager_info) {
2141 ovl->manager->get_manager_info(ovl->manager, &info);
2142 if (info.alpha_enabled)
2143 a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
2144 }
2145
2146 return 0;
2147}
2148
2149static const struct v4l2_ioctl_ops vout_ioctl_ops = {
2150 .vidioc_querycap = vidioc_querycap,
2151 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
2152 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
2153 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
2154 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
2155 .vidioc_queryctrl = vidioc_queryctrl,
2156 .vidioc_g_ctrl = vidioc_g_ctrl,
2157 .vidioc_s_fbuf = vidioc_s_fbuf,
2158 .vidioc_g_fbuf = vidioc_g_fbuf,
2159 .vidioc_s_ctrl = vidioc_s_ctrl,
2160 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
2161 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
2162 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
2163 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
2164 .vidioc_cropcap = vidioc_cropcap,
2165 .vidioc_g_crop = vidioc_g_crop,
2166 .vidioc_s_crop = vidioc_s_crop,
2167 .vidioc_reqbufs = vidioc_reqbufs,
2168 .vidioc_querybuf = vidioc_querybuf,
2169 .vidioc_qbuf = vidioc_qbuf,
2170 .vidioc_dqbuf = vidioc_dqbuf,
2171 .vidioc_streamon = vidioc_streamon,
2172 .vidioc_streamoff = vidioc_streamoff,
2173};
2174
2175static const struct v4l2_file_operations omap_vout_fops = {
2176 .owner = THIS_MODULE,
2177 .unlocked_ioctl = video_ioctl2,
2178 .mmap = omap_vout_mmap,
2179 .open = omap_vout_open,
2180 .release = omap_vout_release,
2181};
2182
2183/* Init functions used during driver initialization */
2184/* Initial setup of video_data */
2185static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
2186{
2187 struct video_device *vfd;
2188 struct v4l2_pix_format *pix;
2189 struct v4l2_control *control;
2190 struct omap_dss_device *display =
2191 vout->vid_info.overlays[0]->manager->device;
2192
2193 /* set the default pix */
2194 pix = &vout->pix;
2195
2196 /* Set the default picture of QVGA */
2197 pix->width = QQVGA_WIDTH;
2198 pix->height = QQVGA_HEIGHT;
2199
2200 /* Default pixel format is RGB 5-6-5 */
2201 pix->pixelformat = V4L2_PIX_FMT_RGB565;
2202 pix->field = V4L2_FIELD_ANY;
2203 pix->bytesperline = pix->width * 2;
2204 pix->sizeimage = pix->bytesperline * pix->height;
2205 pix->priv = 0;
2206 pix->colorspace = V4L2_COLORSPACE_JPEG;
2207
2208 vout->bpp = RGB565_BPP;
2209 vout->fbuf.fmt.width = display->panel.timings.x_res;
2210 vout->fbuf.fmt.height = display->panel.timings.y_res;
2211
2212 /* Set the data structures for the overlay parameters*/
2213 vout->win.global_alpha = 255;
2214 vout->fbuf.flags = 0;
2215 vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
2216 V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
2217 vout->win.chromakey = 0;
2218
2219 omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
2220
2221 /*Initialize the control variables for
2222 rotation, flipping and background color. */
2223 control = vout->control;
2224 control[0].id = V4L2_CID_ROTATE;
2225 control[0].value = 0;
2226 vout->rotation = 0;
2227 vout->mirror = 0;
2228 vout->control[2].id = V4L2_CID_HFLIP;
2229 vout->control[2].value = 0;
2230 vout->vrfb_bpp = 2;
2231
2232 control[1].id = V4L2_CID_BG_COLOR;
2233 control[1].value = 0;
2234
2235 /* initialize the video_device struct */
2236 vfd = vout->vfd = video_device_alloc();
2237
2238 if (!vfd) {
2239 printk(KERN_ERR VOUT_NAME ": could not allocate"
2240 " video device struct\n");
2241 return -ENOMEM;
2242 }
2243 vfd->release = video_device_release;
2244 vfd->ioctl_ops = &vout_ioctl_ops;
2245
2246 strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
2247
2248 /* need to register for a VID_HARDWARE_* ID in videodev.h */
2249 vfd->fops = &omap_vout_fops;
2250 vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
2251 mutex_init(&vout->lock);
2252
2253 vfd->minor = -1;
2254 return 0;
2255
2256}
2257
2258/* Setup video buffers */
2259static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
2260 int vid_num)
2261{
2262 u32 numbuffers;
2263 int ret = 0, i, j;
2264 int image_width, image_height;
2265 struct video_device *vfd;
2266 struct omap_vout_device *vout;
2267 int static_vrfb_allocation = 0, vrfb_num_bufs = VRFB_NUM_BUFS;
2268 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2269 struct omap2video_device *vid_dev =
2270 container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
2271
2272 vout = vid_dev->vouts[vid_num];
2273 vfd = vout->vfd;
2274
2275 numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
2276 vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
2277 dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
2278
2279 for (i = 0; i < numbuffers; i++) {
2280 vout->buf_virt_addr[i] =
2281 omap_vout_alloc_buffer(vout->buffer_size,
2282 (u32 *) &vout->buf_phy_addr[i]);
2283 if (!vout->buf_virt_addr[i]) {
2284 numbuffers = i;
2285 ret = -ENOMEM;
2286 goto free_buffers;
2287 }
2288 }
2289
2290 for (i = 0; i < VRFB_NUM_BUFS; i++) {
2291 if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
2292 dev_info(&pdev->dev, ": VRFB allocation failed\n");
2293 for (j = 0; j < i; j++)
2294 omap_vrfb_release_ctx(&vout->vrfb_context[j]);
2295 ret = -ENOMEM;
2296 goto free_buffers;
2297 }
2298 }
2299 vout->cropped_offset = 0;
2300
2301 /* Calculate VRFB memory size */
2302 /* allocate for worst case size */
2303 image_width = VID_MAX_WIDTH / TILE_SIZE;
2304 if (VID_MAX_WIDTH % TILE_SIZE)
2305 image_width++;
2306
2307 image_width = image_width * TILE_SIZE;
2308 image_height = VID_MAX_HEIGHT / TILE_SIZE;
2309
2310 if (VID_MAX_HEIGHT % TILE_SIZE)
2311 image_height++;
2312
2313 image_height = image_height * TILE_SIZE;
2314 vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);
2315
2316 /*
2317 * Request and Initialize DMA, for DMA based VRFB transfer
2318 */
2319 vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
2320 vout->vrfb_dma_tx.dma_ch = -1;
2321 vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
2322 ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
2323 omap_vout_vrfb_dma_tx_callback,
2324 (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
2325 if (ret < 0) {
2326 vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
2327 dev_info(&pdev->dev, ": failed to allocate DMA Channel for"
2328 " video%d\n", vfd->minor);
2329 }
2330 init_waitqueue_head(&vout->vrfb_dma_tx.wait);
2331
2332 /* Allocate VRFB buffers if selected through bootargs */
2333 static_vrfb_allocation = (vid_num == 0) ?
2334 vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
2335
2336 /* statically allocated the VRFB buffer is done through
2337 commands line aruments */
2338 if (static_vrfb_allocation) {
2339 if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
2340 ret = -ENOMEM;
2341 goto release_vrfb_ctx;
2342 }
2343 vout->vrfb_static_allocation = 1;
2344 }
2345 return 0;
2346
2347release_vrfb_ctx:
2348 for (j = 0; j < VRFB_NUM_BUFS; j++)
2349 omap_vrfb_release_ctx(&vout->vrfb_context[j]);
2350
2351free_buffers:
2352 for (i = 0; i < numbuffers; i++) {
2353 omap_vout_free_buffer(vout->buf_virt_addr[i],
2354 vout->buffer_size);
2355 vout->buf_virt_addr[i] = 0;
2356 vout->buf_phy_addr[i] = 0;
2357 }
2358 return ret;
2359
2360}
2361
2362/* Create video out devices */
2363static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2364{
2365 int ret = 0, k;
2366 struct omap_vout_device *vout;
2367 struct video_device *vfd = NULL;
2368 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2369 struct omap2video_device *vid_dev = container_of(v4l2_dev,
2370 struct omap2video_device, v4l2_dev);
2371
2372 for (k = 0; k < pdev->num_resources; k++) {
2373
2374 vout = kmalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
2375 if (!vout) {
2376 dev_err(&pdev->dev, ": could not allocate memory\n");
2377 return -ENOMEM;
2378 }
2379 memset(vout, 0, sizeof(struct omap_vout_device));
2380
2381 vout->vid = k;
2382 vid_dev->vouts[k] = vout;
2383 vout->vid_dev = vid_dev;
2384 /* Select video2 if only 1 overlay is controlled by V4L2 */
2385 if (pdev->num_resources == 1)
2386 vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
2387 else
2388 /* Else select video1 and video2 one by one. */
2389 vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
2390 vout->vid_info.num_overlays = 1;
2391 vout->vid_info.id = k + 1;
2392
2393 /* Setup the default configuration for the video devices
2394 */
2395 if (omap_vout_setup_video_data(vout) != 0) {
2396 ret = -ENOMEM;
2397 goto error;
2398 }
2399
2400 /* Allocate default number of buffers for the video streaming
2401 * and reserve the VRFB space for rotation
2402 */
2403 if (omap_vout_setup_video_bufs(pdev, k) != 0) {
2404 ret = -ENOMEM;
2405 goto error1;
2406 }
2407
2408 /* Register the Video device with V4L2
2409 */
2410 vfd = vout->vfd;
2411 if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) {
2412 dev_err(&pdev->dev, ": Could not register "
2413 "Video for Linux device\n");
2414 vfd->minor = -1;
2415 ret = -ENODEV;
2416 goto error2;
2417 }
2418 video_set_drvdata(vfd, vout);
2419
2420 /* Configure the overlay structure */
2421 ret = omapvid_init(vid_dev->vouts[k], 0);
2422 if (!ret)
2423 goto success;
2424
2425error2:
2426 omap_vout_release_vrfb(vout);
2427 omap_vout_free_buffers(vout);
2428error1:
2429 video_device_release(vfd);
2430error:
2431 kfree(vout);
2432 return ret;
2433
2434success:
2435 dev_info(&pdev->dev, ": registered and initialized"
2436 " video device %d\n", vfd->minor);
2437 if (k == (pdev->num_resources - 1))
2438 return 0;
2439 }
2440
2441 return -ENODEV;
2442}
2443/* Driver functions */
2444static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2445{
2446 struct video_device *vfd;
2447
2448 if (!vout)
2449 return;
2450
2451 vfd = vout->vfd;
2452 if (vfd) {
2453 if (!video_is_registered(vfd)) {
2454 /*
2455 * The device was never registered, so release the
2456 * video_device struct directly.
2457 */
2458 video_device_release(vfd);
2459 } else {
2460 /*
2461 * The unregister function will release the video_device
2462 * struct as well as unregistering it.
2463 */
2464 video_unregister_device(vfd);
2465 }
2466 }
2467
2468 omap_vout_release_vrfb(vout);
2469 omap_vout_free_buffers(vout);
2470 /* Free the VRFB buffer if allocated
2471 * init time
2472 */
2473 if (vout->vrfb_static_allocation)
2474 omap_vout_free_vrfb_buffers(vout);
2475
2476 kfree(vout);
2477}
2478
2479static int omap_vout_remove(struct platform_device *pdev)
2480{
2481 int k;
2482 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2483 struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
2484 omap2video_device, v4l2_dev);
2485
2486 v4l2_device_unregister(v4l2_dev);
2487 for (k = 0; k < pdev->num_resources; k++)
2488 omap_vout_cleanup_device(vid_dev->vouts[k]);
2489
2490 for (k = 0; k < vid_dev->num_displays; k++) {
2491 if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
2492 vid_dev->displays[k]->disable(vid_dev->displays[k]);
2493
2494 omap_dss_put_device(vid_dev->displays[k]);
2495 }
2496 kfree(vid_dev);
2497 return 0;
2498}
2499
2500static int __init omap_vout_probe(struct platform_device *pdev)
2501{
2502 int ret = 0, i;
2503 struct omap_overlay *ovl;
2504 struct omap_dss_device *dssdev = NULL;
2505 struct omap_dss_device *def_display;
2506 struct omap2video_device *vid_dev = NULL;
2507
2508 if (pdev->num_resources == 0) {
2509 dev_err(&pdev->dev, "probed for an unknown device\n");
2510 return -ENODEV;
2511 }
2512
2513 vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
2514 if (vid_dev == NULL)
2515 return -ENOMEM;
2516
2517 vid_dev->num_displays = 0;
2518 for_each_dss_dev(dssdev) {
2519 omap_dss_get_device(dssdev);
2520 vid_dev->displays[vid_dev->num_displays++] = dssdev;
2521 }
2522
2523 if (vid_dev->num_displays == 0) {
2524 dev_err(&pdev->dev, "no displays\n");
2525 ret = -EINVAL;
2526 goto probe_err0;
2527 }
2528
2529 vid_dev->num_overlays = omap_dss_get_num_overlays();
2530 for (i = 0; i < vid_dev->num_overlays; i++)
2531 vid_dev->overlays[i] = omap_dss_get_overlay(i);
2532
2533 vid_dev->num_managers = omap_dss_get_num_overlay_managers();
2534 for (i = 0; i < vid_dev->num_managers; i++)
2535 vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
2536
2537 /* Get the Video1 overlay and video2 overlay.
2538 * Setup the Display attached to that overlays
2539 */
2540 for (i = 1; i < vid_dev->num_overlays; i++) {
2541 ovl = omap_dss_get_overlay(i);
2542 if (ovl->manager && ovl->manager->device) {
2543 def_display = ovl->manager->device;
2544 } else {
2545 dev_warn(&pdev->dev, "cannot find display\n");
2546 def_display = NULL;
2547 }
2548 if (def_display) {
2549 ret = def_display->enable(def_display);
2550 if (ret) {
2551 /* Here we are not considering a error
2552 * as display may be enabled by frame
2553 * buffer driver
2554 */
2555 dev_warn(&pdev->dev,
2556 "'%s' Display already enabled\n",
2557 def_display->name);
2558 }
2559 /* set the update mode */
2560 if (def_display->caps &
2561 OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2562#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
2563 if (def_display->enable_te)
2564 def_display->enable_te(def_display, 1);
2565 if (def_display->set_update_mode)
2566 def_display->set_update_mode(def_display,
2567 OMAP_DSS_UPDATE_AUTO);
2568#else /* MANUAL_UPDATE */
2569 if (def_display->enable_te)
2570 def_display->enable_te(def_display, 0);
2571 if (def_display->set_update_mode)
2572 def_display->set_update_mode(def_display,
2573 OMAP_DSS_UPDATE_MANUAL);
2574#endif
2575 } else {
2576 if (def_display->set_update_mode)
2577 def_display->set_update_mode(def_display,
2578 OMAP_DSS_UPDATE_AUTO);
2579 }
2580 }
2581 }
2582
2583 if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
2584 dev_err(&pdev->dev, "v4l2_device_register failed\n");
2585 ret = -ENODEV;
2586 goto probe_err1;
2587 }
2588
2589 ret = omap_vout_create_video_devices(pdev);
2590 if (ret)
2591 goto probe_err2;
2592
2593 for (i = 0; i < vid_dev->num_displays; i++) {
2594 struct omap_dss_device *display = vid_dev->displays[i];
2595
2596 if (display->update)
2597 display->update(display, 0, 0,
2598 display->panel.timings.x_res,
2599 display->panel.timings.y_res);
2600 }
2601 return 0;
2602
2603probe_err2:
2604 v4l2_device_unregister(&vid_dev->v4l2_dev);
2605probe_err1:
2606 for (i = 1; i < vid_dev->num_overlays; i++) {
2607 def_display = NULL;
2608 ovl = omap_dss_get_overlay(i);
2609 if (ovl->manager && ovl->manager->device)
2610 def_display = ovl->manager->device;
2611
2612 if (def_display)
2613 def_display->disable(def_display);
2614 }
2615probe_err0:
2616 kfree(vid_dev);
2617 return ret;
2618}
2619
2620static struct platform_driver omap_vout_driver = {
2621 .driver = {
2622 .name = VOUT_NAME,
2623 },
2624 .probe = omap_vout_probe,
2625 .remove = omap_vout_remove,
2626};
2627
2628static int __init omap_vout_init(void)
2629{
2630 if (platform_driver_register(&omap_vout_driver) != 0) {
2631 printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
2632 return -EINVAL;
2633 }
2634 return 0;
2635}
2636
2637static void omap_vout_cleanup(void)
2638{
2639 platform_driver_unregister(&omap_vout_driver);
2640}
2641
2642late_initcall(omap_vout_init);
2643module_exit(omap_vout_cleanup);
diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h
new file mode 100644
index 000000000000..ea3a047f8bca
--- /dev/null
+++ b/drivers/media/video/omap/omap_voutdef.h
@@ -0,0 +1,147 @@
1/*
2 * omap_voutdef.h
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#ifndef OMAP_VOUTDEF_H
12#define OMAP_VOUTDEF_H
13
14#include <plat/display.h>
15
16#define YUYV_BPP 2
17#define RGB565_BPP 2
18#define RGB24_BPP 3
19#define RGB32_BPP 4
20#define TILE_SIZE 32
21#define YUYV_VRFB_BPP 2
22#define RGB_VRFB_BPP 1
23#define MAX_CID 3
24#define MAC_VRFB_CTXS 4
25#define MAX_VOUT_DEV 2
26#define MAX_OVLS 3
27#define MAX_DISPLAYS 3
28#define MAX_MANAGERS 3
29
30/* Enum for Rotation
31 * DSS understands rotation in 0, 1, 2, 3 context
32 * while V4L2 driver understands it as 0, 90, 180, 270
33 */
34enum dss_rotation {
35 dss_rotation_0_degree = 0,
36 dss_rotation_90_degree = 1,
37 dss_rotation_180_degree = 2,
38 dss_rotation_270_degree = 3,
39};
40/*
41 * This structure is used to store the DMA transfer parameters
42 * for VRFB hidden buffer
43 */
44struct vid_vrfb_dma {
45 int dev_id;
46 int dma_ch;
47 int req_status;
48 int tx_status;
49 wait_queue_head_t wait;
50};
51
52struct omapvideo_info {
53 int id;
54 int num_overlays;
55 struct omap_overlay *overlays[MAX_OVLS];
56};
57
58struct omap2video_device {
59 struct mutex mtx;
60
61 int state;
62
63 struct v4l2_device v4l2_dev;
64 struct omap_vout_device *vouts[MAX_VOUT_DEV];
65
66 int num_displays;
67 struct omap_dss_device *displays[MAX_DISPLAYS];
68 int num_overlays;
69 struct omap_overlay *overlays[MAX_OVLS];
70 int num_managers;
71 struct omap_overlay_manager *managers[MAX_MANAGERS];
72};
73
74/* per-device data structure */
75struct omap_vout_device {
76
77 struct omapvideo_info vid_info;
78 struct video_device *vfd;
79 struct omap2video_device *vid_dev;
80 int vid;
81 int opened;
82
83 /* we don't allow to change image fmt/size once buffer has
84 * been allocated
85 */
86 int buffer_allocated;
87 /* allow to reuse previously allocated buffer which is big enough */
88 int buffer_size;
89 /* keep buffer info across opens */
90 unsigned long buf_virt_addr[VIDEO_MAX_FRAME];
91 unsigned long buf_phy_addr[VIDEO_MAX_FRAME];
92 enum omap_color_mode dss_mode;
93
94 /* we don't allow to request new buffer when old buffers are
95 * still mmaped
96 */
97 int mmap_count;
98
99 spinlock_t vbq_lock; /* spinlock for videobuf queues */
100 unsigned long field_count; /* field counter for videobuf_buffer */
101
102 /* non-NULL means streaming is in progress. */
103 bool streaming;
104
105 struct v4l2_pix_format pix;
106 struct v4l2_rect crop;
107 struct v4l2_window win;
108 struct v4l2_framebuffer fbuf;
109
110 /* Lock to protect the shared data structures in ioctl */
111 struct mutex lock;
112
113 /* V4L2 control structure for different control id */
114 struct v4l2_control control[MAX_CID];
115 enum dss_rotation rotation;
116 bool mirror;
117 int flicker_filter;
118 /* V4L2 control structure for different control id */
119
120 int bpp; /* bytes per pixel */
121 int vrfb_bpp; /* bytes per pixel with respect to VRFB */
122
123 struct vid_vrfb_dma vrfb_dma_tx;
124 unsigned int smsshado_phy_addr[MAC_VRFB_CTXS];
125 unsigned int smsshado_virt_addr[MAC_VRFB_CTXS];
126 struct vrfb vrfb_context[MAC_VRFB_CTXS];
127 bool vrfb_static_allocation;
128 unsigned int smsshado_size;
129 unsigned char pos;
130
131 int ps, vr_ps, line_length, first_int, field_id;
132 enum v4l2_memory memory;
133 struct videobuf_buffer *cur_frm, *next_frm;
134 struct list_head dma_queue;
135 u8 *queued_buf_addr[VIDEO_MAX_FRAME];
136 u32 cropped_offset;
137 s32 tv_field1_offset;
138 void *isr_handle;
139
140 /* Buffer queue variables */
141 struct omap_vout_device *vout;
142 enum v4l2_buf_type type;
143 struct videobuf_queue vbq;
144 int io_allowed;
145
146};
147#endif /* ifndef OMAP_VOUTDEF_H */
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c
new file mode 100644
index 000000000000..b941c761eef9
--- /dev/null
+++ b/drivers/media/video/omap/omap_voutlib.c
@@ -0,0 +1,293 @@
1/*
2 * omap_voutlib.c
3 *
4 * Copyright (C) 2005-2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 * Based on the OMAP2 camera driver
11 * Video-for-Linux (Version 2) camera capture driver for
12 * the OMAP24xx camera controller.
13 *
14 * Author: Andy Lowe (source@mvista.com)
15 *
16 * Copyright (C) 2004 MontaVista Software, Inc.
17 * Copyright (C) 2010 Texas Instruments.
18 *
19 */
20
21#include <linux/module.h>
22#include <linux/errno.h>
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <linux/videodev2.h>
26
27#include <plat/cpu.h>
28
29MODULE_AUTHOR("Texas Instruments");
30MODULE_DESCRIPTION("OMAP Video library");
31MODULE_LICENSE("GPL");
32
33/* Return the default overlay cropping rectangle in crop given the image
34 * size in pix and the video display size in fbuf. The default
35 * cropping rectangle is the largest rectangle no larger than the capture size
36 * that will fit on the display. The default cropping rectangle is centered in
37 * the image. All dimensions and offsets are rounded down to even numbers.
38 */
39void omap_vout_default_crop(struct v4l2_pix_format *pix,
40 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop)
41{
42 crop->width = (pix->width < fbuf->fmt.width) ?
43 pix->width : fbuf->fmt.width;
44 crop->height = (pix->height < fbuf->fmt.height) ?
45 pix->height : fbuf->fmt.height;
46 crop->width &= ~1;
47 crop->height &= ~1;
48 crop->left = ((pix->width - crop->width) >> 1) & ~1;
49 crop->top = ((pix->height - crop->height) >> 1) & ~1;
50}
51EXPORT_SYMBOL_GPL(omap_vout_default_crop);
52
53/* Given a new render window in new_win, adjust the window to the
54 * nearest supported configuration. The adjusted window parameters are
55 * returned in new_win.
56 * Returns zero if succesful, or -EINVAL if the requested window is
57 * impossible and cannot reasonably be adjusted.
58 */
59int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
60 struct v4l2_window *new_win)
61{
62 struct v4l2_rect try_win;
63
64 /* make a working copy of the new_win rectangle */
65 try_win = new_win->w;
66
67 /* adjust the preview window so it fits on the display by clipping any
68 * offscreen areas
69 */
70 if (try_win.left < 0) {
71 try_win.width += try_win.left;
72 try_win.left = 0;
73 }
74 if (try_win.top < 0) {
75 try_win.height += try_win.top;
76 try_win.top = 0;
77 }
78 try_win.width = (try_win.width < fbuf->fmt.width) ?
79 try_win.width : fbuf->fmt.width;
80 try_win.height = (try_win.height < fbuf->fmt.height) ?
81 try_win.height : fbuf->fmt.height;
82 if (try_win.left + try_win.width > fbuf->fmt.width)
83 try_win.width = fbuf->fmt.width - try_win.left;
84 if (try_win.top + try_win.height > fbuf->fmt.height)
85 try_win.height = fbuf->fmt.height - try_win.top;
86 try_win.width &= ~1;
87 try_win.height &= ~1;
88
89 if (try_win.width <= 0 || try_win.height <= 0)
90 return -EINVAL;
91
92 /* We now have a valid preview window, so go with it */
93 new_win->w = try_win;
94 new_win->field = V4L2_FIELD_ANY;
95 return 0;
96}
97EXPORT_SYMBOL_GPL(omap_vout_try_window);
98
99/* Given a new render window in new_win, adjust the window to the
100 * nearest supported configuration. The image cropping window in crop
101 * will also be adjusted if necessary. Preference is given to keeping the
102 * the window as close to the requested configuration as possible. If
103 * successful, new_win, vout->win, and crop are updated.
104 * Returns zero if succesful, or -EINVAL if the requested preview window is
105 * impossible and cannot reasonably be adjusted.
106 */
107int omap_vout_new_window(struct v4l2_rect *crop,
108 struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
109 struct v4l2_window *new_win)
110{
111 int err;
112
113 err = omap_vout_try_window(fbuf, new_win);
114 if (err)
115 return err;
116
117 /* update our preview window */
118 win->w = new_win->w;
119 win->field = new_win->field;
120 win->chromakey = new_win->chromakey;
121
122 /* Adjust the cropping window to allow for resizing limitation */
123 if (cpu_is_omap24xx()) {
124 /* For 24xx limit is 8x to 1/2x scaling. */
125 if ((crop->height/win->w.height) >= 2)
126 crop->height = win->w.height * 2;
127
128 if ((crop->width/win->w.width) >= 2)
129 crop->width = win->w.width * 2;
130
131 if (crop->width > 768) {
132 /* The OMAP2420 vertical resizing line buffer is 768
133 * pixels wide. If the cropped image is wider than
134 * 768 pixels then it cannot be vertically resized.
135 */
136 if (crop->height != win->w.height)
137 crop->width = 768;
138 }
139 } else if (cpu_is_omap34xx()) {
140 /* For 34xx limit is 8x to 1/4x scaling. */
141 if ((crop->height/win->w.height) >= 4)
142 crop->height = win->w.height * 4;
143
144 if ((crop->width/win->w.width) >= 4)
145 crop->width = win->w.width * 4;
146 }
147 return 0;
148}
149EXPORT_SYMBOL_GPL(omap_vout_new_window);
150
151/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to
152 * the nearest supported configuration. The image render window in win will
153 * also be adjusted if necessary. The preview window is adjusted such that the
154 * horizontal and vertical rescaling ratios stay constant. If the render
155 * window would fall outside the display boundaries, the cropping rectangle
156 * will also be adjusted to maintain the rescaling ratios. If successful, crop
157 * and win are updated.
158 * Returns zero if succesful, or -EINVAL if the requested cropping rectangle is
159 * impossible and cannot reasonably be adjusted.
160 */
161int omap_vout_new_crop(struct v4l2_pix_format *pix,
162 struct v4l2_rect *crop, struct v4l2_window *win,
163 struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop)
164{
165 struct v4l2_rect try_crop;
166 unsigned long vresize, hresize;
167
168 /* make a working copy of the new_crop rectangle */
169 try_crop = *new_crop;
170
171 /* adjust the cropping rectangle so it fits in the image */
172 if (try_crop.left < 0) {
173 try_crop.width += try_crop.left;
174 try_crop.left = 0;
175 }
176 if (try_crop.top < 0) {
177 try_crop.height += try_crop.top;
178 try_crop.top = 0;
179 }
180 try_crop.width = (try_crop.width < pix->width) ?
181 try_crop.width : pix->width;
182 try_crop.height = (try_crop.height < pix->height) ?
183 try_crop.height : pix->height;
184 if (try_crop.left + try_crop.width > pix->width)
185 try_crop.width = pix->width - try_crop.left;
186 if (try_crop.top + try_crop.height > pix->height)
187 try_crop.height = pix->height - try_crop.top;
188
189 try_crop.width &= ~1;
190 try_crop.height &= ~1;
191
192 if (try_crop.width <= 0 || try_crop.height <= 0)
193 return -EINVAL;
194
195 if (cpu_is_omap24xx()) {
196 if (crop->height != win->w.height) {
197 /* If we're resizing vertically, we can't support a
198 * crop width wider than 768 pixels.
199 */
200 if (try_crop.width > 768)
201 try_crop.width = 768;
202 }
203 }
204 /* vertical resizing */
205 vresize = (1024 * crop->height) / win->w.height;
206 if (cpu_is_omap24xx() && (vresize > 2048))
207 vresize = 2048;
208 else if (cpu_is_omap34xx() && (vresize > 4096))
209 vresize = 4096;
210
211 win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
212 if (win->w.height == 0)
213 win->w.height = 2;
214 if (win->w.height + win->w.top > fbuf->fmt.height) {
215 /* We made the preview window extend below the bottom of the
216 * display, so clip it to the display boundary and resize the
217 * cropping height to maintain the vertical resizing ratio.
218 */
219 win->w.height = (fbuf->fmt.height - win->w.top) & ~1;
220 if (try_crop.height == 0)
221 try_crop.height = 2;
222 }
223 /* horizontal resizing */
224 hresize = (1024 * crop->width) / win->w.width;
225 if (cpu_is_omap24xx() && (hresize > 2048))
226 hresize = 2048;
227 else if (cpu_is_omap34xx() && (hresize > 4096))
228 hresize = 4096;
229
230 win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
231 if (win->w.width == 0)
232 win->w.width = 2;
233 if (win->w.width + win->w.left > fbuf->fmt.width) {
234 /* We made the preview window extend past the right side of the
235 * display, so clip it to the display boundary and resize the
236 * cropping width to maintain the horizontal resizing ratio.
237 */
238 win->w.width = (fbuf->fmt.width - win->w.left) & ~1;
239 if (try_crop.width == 0)
240 try_crop.width = 2;
241 }
242 if (cpu_is_omap24xx()) {
243 if ((try_crop.height/win->w.height) >= 2)
244 try_crop.height = win->w.height * 2;
245
246 if ((try_crop.width/win->w.width) >= 2)
247 try_crop.width = win->w.width * 2;
248
249 if (try_crop.width > 768) {
250 /* The OMAP2420 vertical resizing line buffer is
251 * 768 pixels wide. If the cropped image is wider
252 * than 768 pixels then it cannot be vertically resized.
253 */
254 if (try_crop.height != win->w.height)
255 try_crop.width = 768;
256 }
257 } else if (cpu_is_omap34xx()) {
258 if ((try_crop.height/win->w.height) >= 4)
259 try_crop.height = win->w.height * 4;
260
261 if ((try_crop.width/win->w.width) >= 4)
262 try_crop.width = win->w.width * 4;
263 }
264 /* update our cropping rectangle and we're done */
265 *crop = try_crop;
266 return 0;
267}
268EXPORT_SYMBOL_GPL(omap_vout_new_crop);
269
270/* Given a new format in pix and fbuf, crop and win
271 * structures are initialized to default values. crop
272 * is initialized to the largest window size that will fit on the display. The
273 * crop window is centered in the image. win is initialized to
274 * the same size as crop and is centered on the display.
275 * All sizes and offsets are constrained to be even numbers.
276 */
277void omap_vout_new_format(struct v4l2_pix_format *pix,
278 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
279 struct v4l2_window *win)
280{
281 /* crop defines the preview source window in the image capture
282 * buffer
283 */
284 omap_vout_default_crop(pix, fbuf, crop);
285
286 /* win defines the preview target window on the display */
287 win->w.width = crop->width;
288 win->w.height = crop->height;
289 win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1;
290 win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1;
291}
292EXPORT_SYMBOL_GPL(omap_vout_new_format);
293
diff --git a/drivers/media/video/omap/omap_voutlib.h b/drivers/media/video/omap/omap_voutlib.h
new file mode 100644
index 000000000000..a60b16e8bfc3
--- /dev/null
+++ b/drivers/media/video/omap/omap_voutlib.h
@@ -0,0 +1,34 @@
1/*
2 * omap_voutlib.h
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 */
11
12#ifndef OMAP_VOUTLIB_H
13#define OMAP_VOUTLIB_H
14
15extern void omap_vout_default_crop(struct v4l2_pix_format *pix,
16 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop);
17
18extern int omap_vout_new_crop(struct v4l2_pix_format *pix,
19 struct v4l2_rect *crop, struct v4l2_window *win,
20 struct v4l2_framebuffer *fbuf,
21 const struct v4l2_rect *new_crop);
22
23extern int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
24 struct v4l2_window *new_win);
25
26extern int omap_vout_new_window(struct v4l2_rect *crop,
27 struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
28 struct v4l2_window *new_win);
29
30extern void omap_vout_new_format(struct v4l2_pix_format *pix,
31 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
32 struct v4l2_window *win);
33#endif /* #ifndef OMAP_VOUTLIB_H */
34
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index ce76d952e161..f85b2ed8a2d8 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -452,8 +452,8 @@ static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt,
452 *size = fh->pix.sizeimage; 452 *size = fh->pix.sizeimage;
453 453
454 /* accessing fh->cam->capture_mem is ok, it's constant */ 454 /* accessing fh->cam->capture_mem is ok, it's constant */
455 while (*size * *cnt > fh->cam->capture_mem) 455 if (*size * *cnt > fh->cam->capture_mem)
456 (*cnt)--; 456 *cnt = fh->cam->capture_mem / *size;
457 457
458 return 0; 458 return 0;
459} 459}
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index e0bce8dc74bf..a10912097b7a 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -57,8 +57,8 @@
57#define DRIVER_VERSION "v1.64 for Linux 2.5" 57#define DRIVER_VERSION "v1.64 for Linux 2.5"
58#define EMAIL "mark@alpha.dyndns.org" 58#define EMAIL "mark@alpha.dyndns.org"
59#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \ 59#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
60 & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \ 60& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
61 <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>" 61<cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
62#define DRIVER_DESC "ov511 USB Camera Driver" 62#define DRIVER_DESC "ov511 USB Camera Driver"
63 63
64#define OV511_I2C_RETRIES 3 64#define OV511_I2C_RETRIES 3
@@ -5916,11 +5916,6 @@ ov51x_disconnect(struct usb_interface *intf)
5916 mutex_lock(&ov->lock); 5916 mutex_lock(&ov->lock);
5917 usb_set_intfdata (intf, NULL); 5917 usb_set_intfdata (intf, NULL);
5918 5918
5919 if (!ov) {
5920 mutex_unlock(&ov->lock);
5921 return;
5922 }
5923
5924 /* Free device number */ 5919 /* Free device number */
5925 ov511_devused &= ~(1 << ov->nr); 5920 ov511_devused &= ~(1 << ov->nr);
5926 5921
@@ -5945,7 +5940,7 @@ ov51x_disconnect(struct usb_interface *intf)
5945 ov->dev = NULL; 5940 ov->dev = NULL;
5946 5941
5947 /* Free the memory */ 5942 /* Free the memory */
5948 if (ov && !ov->user) { 5943 if (!ov->user) {
5949 mutex_lock(&ov->cbuf_lock); 5944 mutex_lock(&ov->cbuf_lock);
5950 kfree(ov->cbuf); 5945 kfree(ov->cbuf);
5951 ov->cbuf = NULL; 5946 ov->cbuf = NULL;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index aaa50f9b8e78..91c886ab15c6 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -198,6 +198,7 @@ struct ov7670_info {
198 struct ov7670_format_struct *fmt; /* Current format */ 198 struct ov7670_format_struct *fmt; /* Current format */
199 unsigned char sat; /* Saturation value */ 199 unsigned char sat; /* Saturation value */
200 int hue; /* Hue value */ 200 int hue; /* Hue value */
201 u8 clkrc; /* Clock divider value */
201}; 202};
202 203
203static inline struct ov7670_info *to_state(struct v4l2_subdev *sd) 204static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
@@ -351,7 +352,7 @@ static struct regval_list ov7670_default_regs[] = {
351static struct regval_list ov7670_fmt_yuv422[] = { 352static struct regval_list ov7670_fmt_yuv422[] = {
352 { REG_COM7, 0x0 }, /* Selects YUV mode */ 353 { REG_COM7, 0x0 }, /* Selects YUV mode */
353 { REG_RGB444, 0 }, /* No RGB444 please */ 354 { REG_RGB444, 0 }, /* No RGB444 please */
354 { REG_COM1, 0 }, 355 { REG_COM1, 0 }, /* CCIR601 */
355 { REG_COM15, COM15_R00FF }, 356 { REG_COM15, COM15_R00FF },
356 { REG_COM9, 0x18 }, /* 4x gain ceiling; 0x8 is reserved bit */ 357 { REG_COM9, 0x18 }, /* 4x gain ceiling; 0x8 is reserved bit */
357 { 0x4f, 0x80 }, /* "matrix coefficient 1" */ 358 { 0x4f, 0x80 }, /* "matrix coefficient 1" */
@@ -367,7 +368,7 @@ static struct regval_list ov7670_fmt_yuv422[] = {
367static struct regval_list ov7670_fmt_rgb565[] = { 368static struct regval_list ov7670_fmt_rgb565[] = {
368 { REG_COM7, COM7_RGB }, /* Selects RGB mode */ 369 { REG_COM7, COM7_RGB }, /* Selects RGB mode */
369 { REG_RGB444, 0 }, /* No RGB444 please */ 370 { REG_RGB444, 0 }, /* No RGB444 please */
370 { REG_COM1, 0x0 }, 371 { REG_COM1, 0x0 }, /* CCIR601 */
371 { REG_COM15, COM15_RGB565 }, 372 { REG_COM15, COM15_RGB565 },
372 { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ 373 { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
373 { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ 374 { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
@@ -383,7 +384,7 @@ static struct regval_list ov7670_fmt_rgb565[] = {
383static struct regval_list ov7670_fmt_rgb444[] = { 384static struct regval_list ov7670_fmt_rgb444[] = {
384 { REG_COM7, COM7_RGB }, /* Selects RGB mode */ 385 { REG_COM7, COM7_RGB }, /* Selects RGB mode */
385 { REG_RGB444, R444_ENABLE }, /* Enable xxxxrrrr ggggbbbb */ 386 { REG_RGB444, R444_ENABLE }, /* Enable xxxxrrrr ggggbbbb */
386 { REG_COM1, 0x40 }, /* Magic reserved bit */ 387 { REG_COM1, 0x0 }, /* CCIR601 */
387 { REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */ 388 { REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */
388 { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ 389 { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
389 { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ 390 { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
@@ -408,8 +409,13 @@ static struct regval_list ov7670_fmt_raw[] = {
408 409
409/* 410/*
410 * Low-level register I/O. 411 * Low-level register I/O.
412 *
413 * Note that there are two versions of these. On the XO 1, the
414 * i2c controller only does SMBUS, so that's what we use. The
415 * ov7670 is not really an SMBUS device, though, so the communication
416 * is not always entirely reliable.
411 */ 417 */
412 418#ifdef CONFIG_OLPC_XO_1
413static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, 419static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
414 unsigned char *value) 420 unsigned char *value)
415{ 421{
@@ -432,9 +438,67 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
432 int ret = i2c_smbus_write_byte_data(client, reg, value); 438 int ret = i2c_smbus_write_byte_data(client, reg, value);
433 439
434 if (reg == REG_COM7 && (value & COM7_RESET)) 440 if (reg == REG_COM7 && (value & COM7_RESET))
435 msleep(2); /* Wait for reset to run */ 441 msleep(5); /* Wait for reset to run */
442 return ret;
443}
444
445#else /* ! CONFIG_OLPC_XO_1 */
446/*
447 * On most platforms, we'd rather do straight i2c I/O.
448 */
449static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
450 unsigned char *value)
451{
452 struct i2c_client *client = v4l2_get_subdevdata(sd);
453 u8 data = reg;
454 struct i2c_msg msg;
455 int ret;
456
457 /*
458 * Send out the register address...
459 */
460 msg.addr = client->addr;
461 msg.flags = 0;
462 msg.len = 1;
463 msg.buf = &data;
464 ret = i2c_transfer(client->adapter, &msg, 1);
465 if (ret < 0) {
466 printk(KERN_ERR "Error %d on register write\n", ret);
467 return ret;
468 }
469 /*
470 * ...then read back the result.
471 */
472 msg.flags = I2C_M_RD;
473 ret = i2c_transfer(client->adapter, &msg, 1);
474 if (ret >= 0) {
475 *value = data;
476 ret = 0;
477 }
478 return ret;
479}
480
481
482static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
483 unsigned char value)
484{
485 struct i2c_client *client = v4l2_get_subdevdata(sd);
486 struct i2c_msg msg;
487 unsigned char data[2] = { reg, value };
488 int ret;
489
490 msg.addr = client->addr;
491 msg.flags = 0;
492 msg.len = 2;
493 msg.buf = data;
494 ret = i2c_transfer(client->adapter, &msg, 1);
495 if (ret > 0)
496 ret = 0;
497 if (reg == REG_COM7 && (value & COM7_RESET))
498 msleep(5); /* Wait for reset to run */
436 return ret; 499 return ret;
437} 500}
501#endif /* CONFIG_OLPC_XO_1 */
438 502
439 503
440/* 504/*
@@ -744,22 +808,12 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
744 struct ov7670_format_struct *ovfmt; 808 struct ov7670_format_struct *ovfmt;
745 struct ov7670_win_size *wsize; 809 struct ov7670_win_size *wsize;
746 struct ov7670_info *info = to_state(sd); 810 struct ov7670_info *info = to_state(sd);
747 unsigned char com7, clkrc = 0; 811 unsigned char com7;
748 812
749 ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); 813 ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize);
750 if (ret) 814 if (ret)
751 return ret; 815 return ret;
752 /* 816 /*
753 * HACK: if we're running rgb565 we need to grab then rewrite
754 * CLKRC. If we're *not*, however, then rewriting clkrc hoses
755 * the colors.
756 */
757 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
758 ret = ov7670_read(sd, REG_CLKRC, &clkrc);
759 if (ret)
760 return ret;
761 }
762 /*
763 * COM7 is a pain in the ass, it doesn't like to be read then 817 * COM7 is a pain in the ass, it doesn't like to be read then
764 * quickly written afterward. But we have everything we need 818 * quickly written afterward. But we have everything we need
765 * to set it absolutely here, as long as the format-specific 819 * to set it absolutely here, as long as the format-specific
@@ -779,8 +833,18 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
779 ret = ov7670_write_array(sd, wsize->regs); 833 ret = ov7670_write_array(sd, wsize->regs);
780 info->fmt = ovfmt; 834 info->fmt = ovfmt;
781 835
782 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0) 836 /*
783 ret = ov7670_write(sd, REG_CLKRC, clkrc); 837 * If we're running RGB565, we must rewrite clkrc after setting
838 * the other parameters or the image looks poor. If we're *not*
839 * doing RGB565, we must not rewrite clkrc or the image looks
840 * *really* poor.
841 *
842 * (Update) Now that we retain clkrc state, we should be able
843 * to write it unconditionally, and that will make the frame
844 * rate persistent too.
845 */
846 if (ret == 0)
847 ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
784 return ret; 848 return ret;
785} 849}
786 850
@@ -791,20 +855,17 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
791static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 855static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
792{ 856{
793 struct v4l2_captureparm *cp = &parms->parm.capture; 857 struct v4l2_captureparm *cp = &parms->parm.capture;
794 unsigned char clkrc; 858 struct ov7670_info *info = to_state(sd);
795 int ret;
796 859
797 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 860 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
798 return -EINVAL; 861 return -EINVAL;
799 ret = ov7670_read(sd, REG_CLKRC, &clkrc); 862
800 if (ret < 0)
801 return ret;
802 memset(cp, 0, sizeof(struct v4l2_captureparm)); 863 memset(cp, 0, sizeof(struct v4l2_captureparm));
803 cp->capability = V4L2_CAP_TIMEPERFRAME; 864 cp->capability = V4L2_CAP_TIMEPERFRAME;
804 cp->timeperframe.numerator = 1; 865 cp->timeperframe.numerator = 1;
805 cp->timeperframe.denominator = OV7670_FRAME_RATE; 866 cp->timeperframe.denominator = OV7670_FRAME_RATE;
806 if ((clkrc & CLK_EXT) == 0 && (clkrc & CLK_SCALE) > 1) 867 if ((info->clkrc & CLK_EXT) == 0 && (info->clkrc & CLK_SCALE) > 1)
807 cp->timeperframe.denominator /= (clkrc & CLK_SCALE); 868 cp->timeperframe.denominator /= (info->clkrc & CLK_SCALE);
808 return 0; 869 return 0;
809} 870}
810 871
@@ -812,19 +873,14 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
812{ 873{
813 struct v4l2_captureparm *cp = &parms->parm.capture; 874 struct v4l2_captureparm *cp = &parms->parm.capture;
814 struct v4l2_fract *tpf = &cp->timeperframe; 875 struct v4l2_fract *tpf = &cp->timeperframe;
815 unsigned char clkrc; 876 struct ov7670_info *info = to_state(sd);
816 int ret, div; 877 int div;
817 878
818 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 879 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
819 return -EINVAL; 880 return -EINVAL;
820 if (cp->extendedmode != 0) 881 if (cp->extendedmode != 0)
821 return -EINVAL; 882 return -EINVAL;
822 /* 883
823 * CLKRC has a reserved bit, so let's preserve it.
824 */
825 ret = ov7670_read(sd, REG_CLKRC, &clkrc);
826 if (ret < 0)
827 return ret;
828 if (tpf->numerator == 0 || tpf->denominator == 0) 884 if (tpf->numerator == 0 || tpf->denominator == 0)
829 div = 1; /* Reset to full rate */ 885 div = 1; /* Reset to full rate */
830 else 886 else
@@ -833,10 +889,10 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
833 div = 1; 889 div = 1;
834 else if (div > CLK_SCALE) 890 else if (div > CLK_SCALE)
835 div = CLK_SCALE; 891 div = CLK_SCALE;
836 clkrc = (clkrc & 0x80) | div; 892 info->clkrc = (info->clkrc & 0x80) | div;
837 tpf->numerator = 1; 893 tpf->numerator = 1;
838 tpf->denominator = OV7670_FRAME_RATE/div; 894 tpf->denominator = OV7670_FRAME_RATE/div;
839 return ov7670_write(sd, REG_CLKRC, clkrc); 895 return ov7670_write(sd, REG_CLKRC, info->clkrc);
840} 896}
841 897
842 898
@@ -1115,6 +1171,140 @@ static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
1115 return ret; 1171 return ret;
1116} 1172}
1117 1173
1174/*
1175 * GAIN is split between REG_GAIN and REG_VREF[7:6]. If one believes
1176 * the data sheet, the VREF parts should be the most significant, but
1177 * experience shows otherwise. There seems to be little value in
1178 * messing with the VREF bits, so we leave them alone.
1179 */
1180static int ov7670_g_gain(struct v4l2_subdev *sd, __s32 *value)
1181{
1182 int ret;
1183 unsigned char gain;
1184
1185 ret = ov7670_read(sd, REG_GAIN, &gain);
1186 *value = gain;
1187 return ret;
1188}
1189
1190static int ov7670_s_gain(struct v4l2_subdev *sd, int value)
1191{
1192 int ret;
1193 unsigned char com8;
1194
1195 ret = ov7670_write(sd, REG_GAIN, value & 0xff);
1196 /* Have to turn off AGC as well */
1197 if (ret == 0) {
1198 ret = ov7670_read(sd, REG_COM8, &com8);
1199 ret = ov7670_write(sd, REG_COM8, com8 & ~COM8_AGC);
1200 }
1201 return ret;
1202}
1203
1204/*
1205 * Tweak autogain.
1206 */
1207static int ov7670_g_autogain(struct v4l2_subdev *sd, __s32 *value)
1208{
1209 int ret;
1210 unsigned char com8;
1211
1212 ret = ov7670_read(sd, REG_COM8, &com8);
1213 *value = (com8 & COM8_AGC) != 0;
1214 return ret;
1215}
1216
1217static int ov7670_s_autogain(struct v4l2_subdev *sd, int value)
1218{
1219 int ret;
1220 unsigned char com8;
1221
1222 ret = ov7670_read(sd, REG_COM8, &com8);
1223 if (ret == 0) {
1224 if (value)
1225 com8 |= COM8_AGC;
1226 else
1227 com8 &= ~COM8_AGC;
1228 ret = ov7670_write(sd, REG_COM8, com8);
1229 }
1230 return ret;
1231}
1232
1233/*
1234 * Exposure is spread all over the place: top 6 bits in AECHH, middle
1235 * 8 in AECH, and two stashed in COM1 just for the hell of it.
1236 */
1237static int ov7670_g_exp(struct v4l2_subdev *sd, __s32 *value)
1238{
1239 int ret;
1240 unsigned char com1, aech, aechh;
1241
1242 ret = ov7670_read(sd, REG_COM1, &com1) +
1243 ov7670_read(sd, REG_AECH, &aech) +
1244 ov7670_read(sd, REG_AECHH, &aechh);
1245 *value = ((aechh & 0x3f) << 10) | (aech << 2) | (com1 & 0x03);
1246 return ret;
1247}
1248
1249static int ov7670_s_exp(struct v4l2_subdev *sd, int value)
1250{
1251 int ret;
1252 unsigned char com1, com8, aech, aechh;
1253
1254 ret = ov7670_read(sd, REG_COM1, &com1) +
1255 ov7670_read(sd, REG_COM8, &com8);
1256 ov7670_read(sd, REG_AECHH, &aechh);
1257 if (ret)
1258 return ret;
1259
1260 com1 = (com1 & 0xfc) | (value & 0x03);
1261 aech = (value >> 2) & 0xff;
1262 aechh = (aechh & 0xc0) | ((value >> 10) & 0x3f);
1263 ret = ov7670_write(sd, REG_COM1, com1) +
1264 ov7670_write(sd, REG_AECH, aech) +
1265 ov7670_write(sd, REG_AECHH, aechh);
1266 /* Have to turn off AEC as well */
1267 if (ret == 0)
1268 ret = ov7670_write(sd, REG_COM8, com8 & ~COM8_AEC);
1269 return ret;
1270}
1271
1272/*
1273 * Tweak autoexposure.
1274 */
1275static int ov7670_g_autoexp(struct v4l2_subdev *sd, __s32 *value)
1276{
1277 int ret;
1278 unsigned char com8;
1279 enum v4l2_exposure_auto_type *atype = (enum v4l2_exposure_auto_type *) value;
1280
1281 ret = ov7670_read(sd, REG_COM8, &com8);
1282 if (com8 & COM8_AEC)
1283 *atype = V4L2_EXPOSURE_AUTO;
1284 else
1285 *atype = V4L2_EXPOSURE_MANUAL;
1286 return ret;
1287}
1288
1289static int ov7670_s_autoexp(struct v4l2_subdev *sd,
1290 enum v4l2_exposure_auto_type value)
1291{
1292 int ret;
1293 unsigned char com8;
1294
1295 ret = ov7670_read(sd, REG_COM8, &com8);
1296 if (ret == 0) {
1297 if (value == V4L2_EXPOSURE_AUTO)
1298 com8 |= COM8_AEC;
1299 else
1300 com8 &= ~COM8_AEC;
1301 ret = ov7670_write(sd, REG_COM8, com8);
1302 }
1303 return ret;
1304}
1305
1306
1307
1118static int ov7670_queryctrl(struct v4l2_subdev *sd, 1308static int ov7670_queryctrl(struct v4l2_subdev *sd,
1119 struct v4l2_queryctrl *qc) 1309 struct v4l2_queryctrl *qc)
1120{ 1310{
@@ -1131,6 +1321,14 @@ static int ov7670_queryctrl(struct v4l2_subdev *sd,
1131 return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128); 1321 return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128);
1132 case V4L2_CID_HUE: 1322 case V4L2_CID_HUE:
1133 return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); 1323 return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0);
1324 case V4L2_CID_GAIN:
1325 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
1326 case V4L2_CID_AUTOGAIN:
1327 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1328 case V4L2_CID_EXPOSURE:
1329 return v4l2_ctrl_query_fill(qc, 0, 65535, 1, 500);
1330 case V4L2_CID_EXPOSURE_AUTO:
1331 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
1134 } 1332 }
1135 return -EINVAL; 1333 return -EINVAL;
1136} 1334}
@@ -1150,6 +1348,14 @@ static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1150 return ov7670_g_vflip(sd, &ctrl->value); 1348 return ov7670_g_vflip(sd, &ctrl->value);
1151 case V4L2_CID_HFLIP: 1349 case V4L2_CID_HFLIP:
1152 return ov7670_g_hflip(sd, &ctrl->value); 1350 return ov7670_g_hflip(sd, &ctrl->value);
1351 case V4L2_CID_GAIN:
1352 return ov7670_g_gain(sd, &ctrl->value);
1353 case V4L2_CID_AUTOGAIN:
1354 return ov7670_g_autogain(sd, &ctrl->value);
1355 case V4L2_CID_EXPOSURE:
1356 return ov7670_g_exp(sd, &ctrl->value);
1357 case V4L2_CID_EXPOSURE_AUTO:
1358 return ov7670_g_autoexp(sd, &ctrl->value);
1153 } 1359 }
1154 return -EINVAL; 1360 return -EINVAL;
1155} 1361}
@@ -1169,6 +1375,15 @@ static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1169 return ov7670_s_vflip(sd, ctrl->value); 1375 return ov7670_s_vflip(sd, ctrl->value);
1170 case V4L2_CID_HFLIP: 1376 case V4L2_CID_HFLIP:
1171 return ov7670_s_hflip(sd, ctrl->value); 1377 return ov7670_s_hflip(sd, ctrl->value);
1378 case V4L2_CID_GAIN:
1379 return ov7670_s_gain(sd, ctrl->value);
1380 case V4L2_CID_AUTOGAIN:
1381 return ov7670_s_autogain(sd, ctrl->value);
1382 case V4L2_CID_EXPOSURE:
1383 return ov7670_s_exp(sd, ctrl->value);
1384 case V4L2_CID_EXPOSURE_AUTO:
1385 return ov7670_s_autoexp(sd,
1386 (enum v4l2_exposure_auto_type) ctrl->value);
1172 } 1387 }
1173 return -EINVAL; 1388 return -EINVAL;
1174} 1389}
@@ -1268,6 +1483,7 @@ static int ov7670_probe(struct i2c_client *client,
1268 1483
1269 info->fmt = &ov7670_formats[0]; 1484 info->fmt = &ov7670_formats[0];
1270 info->sat = 128; /* Review this */ 1485 info->sat = 128; /* Review this */
1486 info->clkrc = 1; /* 30fps */
1271 1487
1272 return 0; 1488 return 0;
1273} 1489}
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index 47bf60ceb7a2..36599a65f548 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -59,9 +59,9 @@ static const struct ov9640_reg ov9640_regs_dflt[] = {
59 * COM12 |= OV9640_COM12_YUV_AVG 59 * COM12 |= OV9640_COM12_YUV_AVG
60 * 60 *
61 * for RGB, alter the following registers: 61 * for RGB, alter the following registers:
62 * COM7 |= OV9640_COM7_RGB 62 * COM7 |= OV9640_COM7_RGB
63 * COM13 |= OV9640_COM13_RGB_AVG 63 * COM13 |= OV9640_COM13_RGB_AVG
64 * COM15 |= proper RGB color encoding mode 64 * COM15 |= proper RGB color encoding mode
65 */ 65 */
66static const struct ov9640_reg ov9640_regs_qqcif[] = { 66static const struct ov9640_reg ov9640_regs_qqcif[] = {
67 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) }, 67 { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 0598bbd3f368..7129b50757db 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -61,7 +61,6 @@ struct pms {
61 int depth; 61 int depth;
62 int input; 62 int input;
63 s32 brightness, saturation, hue, contrast; 63 s32 brightness, saturation, hue, contrast;
64 unsigned long in_use;
65 struct mutex lock; 64 struct mutex lock;
66 int i2c_count; 65 int i2c_count;
67 struct i2c_info i2cinfo[64]; 66 struct i2c_info i2cinfo[64];
@@ -931,25 +930,8 @@ static ssize_t pms_read(struct file *file, char __user *buf,
931 return len; 930 return len;
932} 931}
933 932
934static int pms_exclusive_open(struct file *file)
935{
936 struct pms *dev = video_drvdata(file);
937
938 return test_and_set_bit(0, &dev->in_use) ? -EBUSY : 0;
939}
940
941static int pms_exclusive_release(struct file *file)
942{
943 struct pms *dev = video_drvdata(file);
944
945 clear_bit(0, &dev->in_use);
946 return 0;
947}
948
949static const struct v4l2_file_operations pms_fops = { 933static const struct v4l2_file_operations pms_fops = {
950 .owner = THIS_MODULE, 934 .owner = THIS_MODULE,
951 .open = pms_exclusive_open,
952 .release = pms_exclusive_release,
953 .ioctl = video_ioctl2, 935 .ioctl = video_ioctl2,
954 .read = pms_read, 936 .read = pms_read,
955}; 937};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 712b300f723f..301ef197d038 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2028,7 +2028,7 @@ static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
2028 memset(&fmt, 0, sizeof(fmt)); 2028 memset(&fmt, 0, sizeof(fmt));
2029 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 2029 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
2030 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, 2030 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
2031 video, s_fmt, &fmt); 2031 vbi, s_sliced_fmt, &fmt.fmt.sliced);
2032} 2032}
2033 2033
2034 2034
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index bf1e0fe9f4d2..5ffa0d2b0b0d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -49,7 +49,7 @@ struct pvr2_v4l2_dev {
49 49
50struct pvr2_v4l2_fh { 50struct pvr2_v4l2_fh {
51 struct pvr2_channel channel; 51 struct pvr2_channel channel;
52 struct pvr2_v4l2_dev *dev_info; 52 struct pvr2_v4l2_dev *pdi;
53 enum v4l2_priority prio; 53 enum v4l2_priority prio;
54 struct pvr2_ioread *rhp; 54 struct pvr2_ioread *rhp;
55 struct file *file; 55 struct file *file;
@@ -162,7 +162,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
162{ 162{
163 struct pvr2_v4l2_fh *fh = file->private_data; 163 struct pvr2_v4l2_fh *fh = file->private_data;
164 struct pvr2_v4l2 *vp = fh->vhead; 164 struct pvr2_v4l2 *vp = fh->vhead;
165 struct pvr2_v4l2_dev *dev_info = fh->dev_info; 165 struct pvr2_v4l2_dev *pdi = fh->pdi;
166 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; 166 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
167 long ret = -EINVAL; 167 long ret = -EINVAL;
168 168
@@ -183,7 +183,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
183 case VIDIOC_S_INPUT: 183 case VIDIOC_S_INPUT:
184 case VIDIOC_S_TUNER: 184 case VIDIOC_S_TUNER:
185 case VIDIOC_S_FREQUENCY: 185 case VIDIOC_S_FREQUENCY:
186 ret = v4l2_prio_check(&vp->prio, &fh->prio); 186 ret = v4l2_prio_check(&vp->prio, fh->prio);
187 if (ret) 187 if (ret)
188 return ret; 188 return ret;
189 } 189 }
@@ -564,14 +564,14 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
564 564
565 case VIDIOC_STREAMON: 565 case VIDIOC_STREAMON:
566 { 566 {
567 if (!fh->dev_info->stream) { 567 if (!fh->pdi->stream) {
568 /* No stream defined for this node. This means 568 /* No stream defined for this node. This means
569 that we're not currently allowed to stream from 569 that we're not currently allowed to stream from
570 this node. */ 570 this node. */
571 ret = -EPERM; 571 ret = -EPERM;
572 break; 572 break;
573 } 573 }
574 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config); 574 ret = pvr2_hdw_set_stream_type(hdw,pdi->config);
575 if (ret < 0) return ret; 575 if (ret < 0) return ret;
576 ret = pvr2_hdw_set_streaming(hdw,!0); 576 ret = pvr2_hdw_set_streaming(hdw,!0);
577 break; 577 break;
@@ -579,7 +579,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
579 579
580 case VIDIOC_STREAMOFF: 580 case VIDIOC_STREAMOFF:
581 { 581 {
582 if (!fh->dev_info->stream) { 582 if (!fh->pdi->stream) {
583 /* No stream defined for this node. This means 583 /* No stream defined for this node. This means
584 that we're not currently allowed to stream from 584 that we're not currently allowed to stream from
585 this node. */ 585 this node. */
@@ -972,7 +972,7 @@ static int pvr2_v4l2_release(struct file *file)
972 fhp->rhp = NULL; 972 fhp->rhp = NULL;
973 } 973 }
974 974
975 v4l2_prio_close(&vp->prio, &fhp->prio); 975 v4l2_prio_close(&vp->prio, fhp->prio);
976 file->private_data = NULL; 976 file->private_data = NULL;
977 977
978 if (fhp->vnext) { 978 if (fhp->vnext) {
@@ -1032,7 +1032,7 @@ static int pvr2_v4l2_open(struct file *file)
1032 } 1032 }
1033 1033
1034 init_waitqueue_head(&fhp->wait_data); 1034 init_waitqueue_head(&fhp->wait_data);
1035 fhp->dev_info = dip; 1035 fhp->pdi = dip;
1036 1036
1037 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); 1037 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
1038 pvr2_channel_init(&fhp->channel,vp->channel.mc_head); 1038 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
@@ -1093,7 +1093,7 @@ static int pvr2_v4l2_open(struct file *file)
1093 1093
1094 fhp->file = file; 1094 fhp->file = file;
1095 file->private_data = fhp; 1095 file->private_data = fhp;
1096 v4l2_prio_open(&vp->prio,&fhp->prio); 1096 v4l2_prio_open(&vp->prio, &fhp->prio);
1097 1097
1098 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); 1098 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1099 1099
@@ -1113,7 +1113,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1113 struct pvr2_hdw *hdw; 1113 struct pvr2_hdw *hdw;
1114 if (fh->rhp) return 0; 1114 if (fh->rhp) return 0;
1115 1115
1116 if (!fh->dev_info->stream) { 1116 if (!fh->pdi->stream) {
1117 /* No stream defined for this node. This means that we're 1117 /* No stream defined for this node. This means that we're
1118 not currently allowed to stream from this node. */ 1118 not currently allowed to stream from this node. */
1119 return -EPERM; 1119 return -EPERM;
@@ -1122,21 +1122,21 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1122 /* First read() attempt. Try to claim the stream and start 1122 /* First read() attempt. Try to claim the stream and start
1123 it... */ 1123 it... */
1124 if ((ret = pvr2_channel_claim_stream(&fh->channel, 1124 if ((ret = pvr2_channel_claim_stream(&fh->channel,
1125 fh->dev_info->stream)) != 0) { 1125 fh->pdi->stream)) != 0) {
1126 /* Someone else must already have it */ 1126 /* Someone else must already have it */
1127 return ret; 1127 return ret;
1128 } 1128 }
1129 1129
1130 fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream); 1130 fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream);
1131 if (!fh->rhp) { 1131 if (!fh->rhp) {
1132 pvr2_channel_claim_stream(&fh->channel,NULL); 1132 pvr2_channel_claim_stream(&fh->channel,NULL);
1133 return -ENOMEM; 1133 return -ENOMEM;
1134 } 1134 }
1135 1135
1136 hdw = fh->channel.mc_head->hdw; 1136 hdw = fh->channel.mc_head->hdw;
1137 sp = fh->dev_info->stream->stream; 1137 sp = fh->pdi->stream->stream;
1138 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); 1138 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
1139 pvr2_hdw_set_stream_type(hdw,fh->dev_info->config); 1139 pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
1140 if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret; 1140 if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
1141 return pvr2_ioread_set_enabled(fh->rhp,!0); 1141 return pvr2_ioread_set_enabled(fh->rhp,!0);
1142} 1142}
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 340f954aba34..11980db22d31 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -39,7 +39,7 @@ config USB_PWC_DEBUG
39config USB_PWC_INPUT_EVDEV 39config USB_PWC_INPUT_EVDEV
40 bool "USB Philips Cameras input events device support" 40 bool "USB Philips Cameras input events device support"
41 default y 41 default y
42 depends on USB_PWC=INPUT || INPUT=y 42 depends on USB_PWC && (USB_PWC=INPUT || INPUT=y)
43 ---help--- 43 ---help---
44 This option makes USB Philips cameras register the snapshot button as 44 This option makes USB Philips cameras register the snapshot button as
45 an input device to report button events. 45 an input device to report button events.
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 04bf5c11308d..7fe70e718656 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -253,8 +253,8 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
253 253
254 if (0 == *count) 254 if (0 == *count)
255 *count = 32; 255 *count = 32;
256 while (*size * *count > vid_limit * 1024 * 1024) 256 if (*size * *count > vid_limit * 1024 * 1024)
257 (*count)--; 257 *count = (vid_limit * 1024 * 1024) / *size;
258 258
259 return 0; 259 return 0;
260} 260}
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index 9277194cd821..bbd9c11e2c5a 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -555,15 +555,15 @@ static int rj54n1_commit(struct i2c_client *client)
555 return ret; 555 return ret;
556} 556}
557 557
558static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, 558static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
559 u32 *out_w, u32 *out_h); 559 s32 *out_w, s32 *out_h);
560 560
561static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 561static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
562{ 562{
563 struct i2c_client *client = sd->priv; 563 struct i2c_client *client = sd->priv;
564 struct rj54n1 *rj54n1 = to_rj54n1(client); 564 struct rj54n1 *rj54n1 = to_rj54n1(client);
565 struct v4l2_rect *rect = &a->c; 565 struct v4l2_rect *rect = &a->c;
566 unsigned int dummy = 0, output_w, output_h, 566 int dummy = 0, output_w, output_h,
567 input_w = rect->width, input_h = rect->height; 567 input_w = rect->width, input_h = rect->height;
568 int ret; 568 int ret;
569 569
@@ -577,7 +577,7 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
577 output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize; 577 output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize;
578 output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize; 578 output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize;
579 579
580 dev_dbg(&client->dev, "Scaling for %ux%u : %u = %ux%u\n", 580 dev_dbg(&client->dev, "Scaling for %dx%d : %u = %dx%d\n",
581 input_w, input_h, rj54n1->resize, output_w, output_h); 581 input_w, input_h, rj54n1->resize, output_w, output_h);
582 582
583 ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); 583 ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
@@ -638,8 +638,8 @@ static int rj54n1_g_fmt(struct v4l2_subdev *sd,
638 * the output one, updates the window sizes and returns an error or the resize 638 * the output one, updates the window sizes and returns an error or the resize
639 * coefficient on success. Note: we only use the "Fixed Scaling" on this camera. 639 * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
640 */ 640 */
641static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, 641static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
642 u32 *out_w, u32 *out_h) 642 s32 *out_w, s32 *out_h)
643{ 643{
644 struct i2c_client *client = sd->priv; 644 struct i2c_client *client = sd->priv;
645 struct rj54n1 *rj54n1 = to_rj54n1(client); 645 struct rj54n1 *rj54n1 = to_rj54n1(client);
@@ -749,7 +749,7 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
749 * improve the image quality or stability for larger frames (see comment 749 * improve the image quality or stability for larger frames (see comment
750 * above), but I didn't check the framerate. 750 * above), but I didn't check the framerate.
751 */ 751 */
752 skip = min(resize / 1024, (unsigned)15); 752 skip = min(resize / 1024, 15U);
753 753
754 inc_sel = 1 << skip; 754 inc_sel = 1 << skip;
755 755
@@ -819,7 +819,7 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h,
819 *out_w = output_w; 819 *out_w = output_w;
820 *out_h = output_h; 820 *out_h = output_h;
821 821
822 dev_dbg(&client->dev, "Scaled for %ux%u : %u = %ux%u, skip %u\n", 822 dev_dbg(&client->dev, "Scaled for %dx%d : %u = %ux%u, skip %u\n",
823 *in_w, *in_h, resize, output_w, output_h, skip); 823 *in_w, *in_h, resize, output_w, output_h, skip);
824 824
825 return resize; 825 return resize;
@@ -1017,7 +1017,7 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd,
1017 struct i2c_client *client = sd->priv; 1017 struct i2c_client *client = sd->priv;
1018 struct rj54n1 *rj54n1 = to_rj54n1(client); 1018 struct rj54n1 *rj54n1 = to_rj54n1(client);
1019 const struct rj54n1_datafmt *fmt; 1019 const struct rj54n1_datafmt *fmt;
1020 unsigned int output_w, output_h, max_w, max_h, 1020 int output_w, output_h, max_w, max_h,
1021 input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; 1021 input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
1022 int ret; 1022 int ret;
1023 1023
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 3de914deb8ee..3c7a79f3812a 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device 2 * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
3 * 3 *
4 * Copyright (C) 2007-2008 by Sensoray Company Inc. 4 * Copyright (C) 2007-2010 by Sensoray Company Inc.
5 * Dean Anderson 5 * Dean Anderson
6 * 6 *
7 * Some video buffer code based on vivi driver: 7 * Some video buffer code based on vivi driver:
@@ -52,14 +52,19 @@
52#include <linux/smp_lock.h> 52#include <linux/smp_lock.h>
53#include <media/videobuf-vmalloc.h> 53#include <media/videobuf-vmalloc.h>
54#include <media/v4l2-common.h> 54#include <media/v4l2-common.h>
55#include <media/v4l2-device.h>
55#include <media/v4l2-ioctl.h> 56#include <media/v4l2-ioctl.h>
56#include <linux/vmalloc.h> 57#include <linux/vmalloc.h>
57#include <linux/usb.h> 58#include <linux/usb.h>
58 59
60#define S2255_MAJOR_VERSION 1
61#define S2255_MINOR_VERSION 20
62#define S2255_RELEASE 0
63#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
64 S2255_MINOR_VERSION, \
65 S2255_RELEASE)
59#define FIRMWARE_FILE_NAME "f2255usb.bin" 66#define FIRMWARE_FILE_NAME "f2255usb.bin"
60 67
61
62
63/* default JPEG quality */ 68/* default JPEG quality */
64#define S2255_DEF_JPEG_QUAL 50 69#define S2255_DEF_JPEG_QUAL 50
65/* vendor request in */ 70/* vendor request in */
@@ -76,14 +81,14 @@
76#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) 81#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
77#define S2255_DEF_BUFS 16 82#define S2255_DEF_BUFS 16
78#define S2255_SETMODE_TIMEOUT 500 83#define S2255_SETMODE_TIMEOUT 500
79#define MAX_CHANNELS 4 84#define S2255_VIDSTATUS_TIMEOUT 350
80#define S2255_MARKER_FRAME 0x2255DA4AL 85#define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
81#define S2255_MARKER_RESPONSE 0x2255ACACL 86#define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
82#define S2255_RESPONSE_SETMODE 0x01 87#define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
83#define S2255_RESPONSE_FW 0x10 88#define S2255_RESPONSE_FW cpu_to_le32(0x10)
89#define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
84#define S2255_USB_XFER_SIZE (16 * 1024) 90#define S2255_USB_XFER_SIZE (16 * 1024)
85#define MAX_CHANNELS 4 91#define MAX_CHANNELS 4
86#define MAX_PIPE_BUFFERS 1
87#define SYS_FRAMES 4 92#define SYS_FRAMES 4
88/* maximum size is PAL full size plus room for the marker header(s) */ 93/* maximum size is PAL full size plus room for the marker header(s) */
89#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) 94#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
@@ -118,9 +123,10 @@
118#define COLOR_YUVPK 2 /* YUV packed */ 123#define COLOR_YUVPK 2 /* YUV packed */
119#define COLOR_Y8 4 /* monochrome */ 124#define COLOR_Y8 4 /* monochrome */
120#define COLOR_JPG 5 /* JPEG */ 125#define COLOR_JPG 5 /* JPEG */
121#define MASK_COLOR 0xff
122#define MASK_JPG_QUALITY 0xff00
123 126
127#define MASK_COLOR 0x000000ff
128#define MASK_JPG_QUALITY 0x0000ff00
129#define MASK_INPUT_TYPE 0x000f0000
124/* frame decimation. Not implemented by V4L yet(experimental in V4L) */ 130/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
125#define FDEC_1 1 /* capture every frame. default */ 131#define FDEC_1 1 /* capture every frame. default */
126#define FDEC_2 2 /* capture every 2nd frame */ 132#define FDEC_2 2 /* capture every 2nd frame */
@@ -139,12 +145,12 @@
139#define DEF_HUE 0 145#define DEF_HUE 0
140 146
141/* usb config commands */ 147/* usb config commands */
142#define IN_DATA_TOKEN 0x2255c0de 148#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
143#define CMD_2255 0xc2255000 149#define CMD_2255 cpu_to_le32(0xc2255000)
144#define CMD_SET_MODE (CMD_2255 | 0x10) 150#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
145#define CMD_START (CMD_2255 | 0x20) 151#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
146#define CMD_STOP (CMD_2255 | 0x30) 152#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
147#define CMD_STATUS (CMD_2255 | 0x40) 153#define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
148 154
149struct s2255_mode { 155struct s2255_mode {
150 u32 format; /* input video format (NTSC, PAL) */ 156 u32 format; /* input video format (NTSC, PAL) */
@@ -194,7 +200,6 @@ struct s2255_dmaqueue {
194#define S2255_FW_SUCCESS 2 200#define S2255_FW_SUCCESS 2
195#define S2255_FW_FAILED 3 201#define S2255_FW_FAILED 3
196#define S2255_FW_DISCONNECTING 4 202#define S2255_FW_DISCONNECTING 4
197
198#define S2255_FW_MARKER cpu_to_le32(0x22552f2f) 203#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
199/* 2255 read states */ 204/* 2255 read states */
200#define S2255_READ_IDLE 0 205#define S2255_READ_IDLE 0
@@ -223,8 +228,10 @@ struct s2255_pipeinfo {
223struct s2255_fmt; /*forward declaration */ 228struct s2255_fmt; /*forward declaration */
224 229
225struct s2255_dev { 230struct s2255_dev {
231 struct video_device vdev[MAX_CHANNELS];
232 struct v4l2_device v4l2_dev;
233 atomic_t channels; /* number of channels registered */
226 int frames; 234 int frames;
227 int users[MAX_CHANNELS];
228 struct mutex lock; 235 struct mutex lock;
229 struct mutex open_lock; 236 struct mutex open_lock;
230 int resources[MAX_CHANNELS]; 237 int resources[MAX_CHANNELS];
@@ -233,11 +240,10 @@ struct s2255_dev {
233 u8 read_endpoint; 240 u8 read_endpoint;
234 241
235 struct s2255_dmaqueue vidq[MAX_CHANNELS]; 242 struct s2255_dmaqueue vidq[MAX_CHANNELS];
236 struct video_device *vdev[MAX_CHANNELS];
237 struct timer_list timer; 243 struct timer_list timer;
238 struct s2255_fw *fw_data; 244 struct s2255_fw *fw_data;
239 struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; 245 struct s2255_pipeinfo pipe;
240 struct s2255_bufferi buffer[MAX_CHANNELS]; 246 struct s2255_bufferi buffer[MAX_CHANNELS];
241 struct s2255_mode mode[MAX_CHANNELS]; 247 struct s2255_mode mode[MAX_CHANNELS];
242 /* jpeg compression */ 248 /* jpeg compression */
243 struct v4l2_jpegcompression jc[MAX_CHANNELS]; 249 struct v4l2_jpegcompression jc[MAX_CHANNELS];
@@ -261,11 +267,21 @@ struct s2255_dev {
261 int chn_configured[MAX_CHANNELS]; 267 int chn_configured[MAX_CHANNELS];
262 wait_queue_head_t wait_setmode[MAX_CHANNELS]; 268 wait_queue_head_t wait_setmode[MAX_CHANNELS];
263 int setmode_ready[MAX_CHANNELS]; 269 int setmode_ready[MAX_CHANNELS];
270 /* video status items */
271 int vidstatus[MAX_CHANNELS];
272 wait_queue_head_t wait_vidstatus[MAX_CHANNELS];
273 int vidstatus_ready[MAX_CHANNELS];
264 int chn_ready; 274 int chn_ready;
265 struct kref kref;
266 spinlock_t slock; 275 spinlock_t slock;
276 /* dsp firmware version (f2255usb.bin) */
277 int dsp_fw_ver;
278 u16 pid; /* product id */
267}; 279};
268#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref) 280
281static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
282{
283 return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
284}
269 285
270struct s2255_fmt { 286struct s2255_fmt {
271 char *name; 287 char *name;
@@ -296,17 +312,43 @@ struct s2255_fh {
296 312
297/* current cypress EEPROM firmware version */ 313/* current cypress EEPROM firmware version */
298#define S2255_CUR_USB_FWVER ((3 << 8) | 6) 314#define S2255_CUR_USB_FWVER ((3 << 8) | 6)
299#define S2255_MAJOR_VERSION 1 315/* current DSP FW version */
300#define S2255_MINOR_VERSION 14 316#define S2255_CUR_DSP_FWVER 8
301#define S2255_RELEASE 0 317/* Need DSP version 5+ for video status feature */
302#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ 318#define S2255_MIN_DSP_STATUS 5
303 S2255_MINOR_VERSION, \ 319#define S2255_MIN_DSP_COLORFILTER 8
304 S2255_RELEASE)
305
306/* vendor ids */
307#define USB_S2255_VENDOR_ID 0x1943
308#define USB_S2255_PRODUCT_ID 0x2255
309#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) 320#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
321
322/* private V4L2 controls */
323
324/*
325 * The following chart displays how COLORFILTER should be set
326 * =========================================================
327 * = fourcc = COLORFILTER =
328 * = ===============================
329 * = = 0 = 1 =
330 * =========================================================
331 * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
332 * = = s-video or = composite =
333 * = = B/W camera = input =
334 * =========================================================
335 * = other = color, svideo = color, =
336 * = = = composite =
337 * =========================================================
338 *
339 * Notes:
340 * channels 0-3 on 2255 are composite
341 * channels 0-1 on 2257 are composite, 2-3 are s-video
342 * If COLORFILTER is 0 with a composite color camera connected,
343 * the output will appear monochrome but hatching
344 * will occur.
345 * COLORFILTER is different from "color killer" and "color effects"
346 * for reasons above.
347 */
348#define S2255_V4L2_YC_ON 1
349#define S2255_V4L2_YC_OFF 0
350#define V4L2_CID_PRIVATE_COLORFILTER (V4L2_CID_PRIVATE_BASE + 0)
351
310/* frame prefix size (sent once every frame) */ 352/* frame prefix size (sent once every frame) */
311#define PREFIX_SIZE 512 353#define PREFIX_SIZE 512
312 354
@@ -325,9 +367,8 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
325static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, 367static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
326 struct s2255_mode *mode); 368 struct s2255_mode *mode);
327static int s2255_board_shutdown(struct s2255_dev *dev); 369static int s2255_board_shutdown(struct s2255_dev *dev);
328static void s2255_exit_v4l(struct s2255_dev *dev);
329static void s2255_fwload_start(struct s2255_dev *dev, int reset); 370static void s2255_fwload_start(struct s2255_dev *dev, int reset);
330static void s2255_destroy(struct kref *kref); 371static void s2255_destroy(struct s2255_dev *dev);
331static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, 372static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
332 u16 index, u16 value, void *buf, 373 u16 index, u16 value, void *buf,
333 s32 buf_len, int bOut); 374 s32 buf_len, int bOut);
@@ -347,7 +388,6 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
347 388
348static struct usb_driver s2255_driver; 389static struct usb_driver s2255_driver;
349 390
350
351/* Declare static vars that will be used as parameters */ 391/* Declare static vars that will be used as parameters */
352static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 392static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
353 393
@@ -362,58 +402,16 @@ module_param(video_nr, int, 0644);
362MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); 402MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
363 403
364/* USB device table */ 404/* USB device table */
405#define USB_SENSORAY_VID 0x1943
365static struct usb_device_id s2255_table[] = { 406static struct usb_device_id s2255_table[] = {
366 {USB_DEVICE(USB_S2255_VENDOR_ID, USB_S2255_PRODUCT_ID)}, 407 {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
408 {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
367 { } /* Terminating entry */ 409 { } /* Terminating entry */
368}; 410};
369MODULE_DEVICE_TABLE(usb, s2255_table); 411MODULE_DEVICE_TABLE(usb, s2255_table);
370 412
371
372#define BUFFER_TIMEOUT msecs_to_jiffies(400) 413#define BUFFER_TIMEOUT msecs_to_jiffies(400)
373 414
374/* supported controls */
375static struct v4l2_queryctrl s2255_qctrl[] = {
376 {
377 .id = V4L2_CID_BRIGHTNESS,
378 .type = V4L2_CTRL_TYPE_INTEGER,
379 .name = "Brightness",
380 .minimum = -127,
381 .maximum = 128,
382 .step = 1,
383 .default_value = 0,
384 .flags = 0,
385 }, {
386 .id = V4L2_CID_CONTRAST,
387 .type = V4L2_CTRL_TYPE_INTEGER,
388 .name = "Contrast",
389 .minimum = 0,
390 .maximum = 255,
391 .step = 0x1,
392 .default_value = DEF_CONTRAST,
393 .flags = 0,
394 }, {
395 .id = V4L2_CID_SATURATION,
396 .type = V4L2_CTRL_TYPE_INTEGER,
397 .name = "Saturation",
398 .minimum = 0,
399 .maximum = 255,
400 .step = 0x1,
401 .default_value = DEF_SATURATION,
402 .flags = 0,
403 }, {
404 .id = V4L2_CID_HUE,
405 .type = V4L2_CTRL_TYPE_INTEGER,
406 .name = "Hue",
407 .minimum = 0,
408 .maximum = 255,
409 .step = 0x1,
410 .default_value = DEF_HUE,
411 .flags = 0,
412 }
413};
414
415static int qctl_regs[ARRAY_SIZE(s2255_qctrl)];
416
417/* image formats. */ 415/* image formats. */
418static const struct s2255_fmt formats[] = { 416static const struct s2255_fmt formats[] = {
419 { 417 {
@@ -505,7 +503,7 @@ static void s2255_reset_dsppower(struct s2255_dev *dev)
505static void s2255_timer(unsigned long user_data) 503static void s2255_timer(unsigned long user_data)
506{ 504{
507 struct s2255_fw *data = (struct s2255_fw *)user_data; 505 struct s2255_fw *data = (struct s2255_fw *)user_data;
508 dprintk(100, "s2255 timer\n"); 506 dprintk(100, "%s\n", __func__);
509 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { 507 if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
510 printk(KERN_ERR "s2255: can't submit urb\n"); 508 printk(KERN_ERR "s2255: can't submit urb\n");
511 atomic_set(&data->fw_state, S2255_FW_FAILED); 509 atomic_set(&data->fw_state, S2255_FW_FAILED);
@@ -527,7 +525,7 @@ static void s2255_fwchunk_complete(struct urb *urb)
527 struct s2255_fw *data = urb->context; 525 struct s2255_fw *data = urb->context;
528 struct usb_device *udev = urb->dev; 526 struct usb_device *udev = urb->dev;
529 int len; 527 int len;
530 dprintk(100, "udev %p urb %p", udev, urb); 528 dprintk(100, "%s: udev %p urb %p", __func__, udev, urb);
531 if (urb->status) { 529 if (urb->status) {
532 dev_err(&udev->dev, "URB failed with status %d\n", urb->status); 530 dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
533 atomic_set(&data->fw_state, S2255_FW_FAILED); 531 atomic_set(&data->fw_state, S2255_FW_FAILED);
@@ -573,8 +571,8 @@ static void s2255_fwchunk_complete(struct urb *urb)
573 data->fw_loaded += len; 571 data->fw_loaded += len;
574 } else { 572 } else {
575 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); 573 atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
574 dprintk(100, "%s: firmware upload complete\n", __func__);
576 } 575 }
577 dprintk(100, "2255 complete done\n");
578 return; 576 return;
579 577
580} 578}
@@ -585,9 +583,7 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
585 struct s2255_buffer *buf; 583 struct s2255_buffer *buf;
586 unsigned long flags = 0; 584 unsigned long flags = 0;
587 int rc = 0; 585 int rc = 0;
588 dprintk(2, "wakeup: %p channel: %d\n", &dma_q, chn);
589 spin_lock_irqsave(&dev->slock, flags); 586 spin_lock_irqsave(&dev->slock, flags);
590
591 if (list_empty(&dma_q->active)) { 587 if (list_empty(&dma_q->active)) {
592 dprintk(1, "No active queue to serve\n"); 588 dprintk(1, "No active queue to serve\n");
593 rc = -1; 589 rc = -1;
@@ -595,23 +591,19 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
595 } 591 }
596 buf = list_entry(dma_q->active.next, 592 buf = list_entry(dma_q->active.next,
597 struct s2255_buffer, vb.queue); 593 struct s2255_buffer, vb.queue);
598
599 list_del(&buf->vb.queue); 594 list_del(&buf->vb.queue);
600 do_gettimeofday(&buf->vb.ts); 595 do_gettimeofday(&buf->vb.ts);
601 dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i);
602 s2255_fillbuff(dev, buf, dma_q->channel, jpgsize); 596 s2255_fillbuff(dev, buf, dma_q->channel, jpgsize);
603 wake_up(&buf->vb.done); 597 wake_up(&buf->vb.done);
604 dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); 598 dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
605unlock: 599unlock:
606 spin_unlock_irqrestore(&dev->slock, flags); 600 spin_unlock_irqrestore(&dev->slock, flags);
607 return 0; 601 return 0;
608} 602}
609 603
610
611static const struct s2255_fmt *format_by_fourcc(int fourcc) 604static const struct s2255_fmt *format_by_fourcc(int fourcc)
612{ 605{
613 unsigned int i; 606 unsigned int i;
614
615 for (i = 0; i < ARRAY_SIZE(formats); i++) { 607 for (i = 0; i < ARRAY_SIZE(formats); i++) {
616 if (-1 == formats[i].fourcc) 608 if (-1 == formats[i].fourcc)
617 continue; 609 continue;
@@ -621,9 +613,6 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)
621 return NULL; 613 return NULL;
622} 614}
623 615
624
625
626
627/* video buffer vmalloc implementation based partly on VIVI driver which is 616/* video buffer vmalloc implementation based partly on VIVI driver which is
628 * Copyright (c) 2006 by 617 * Copyright (c) 2006 by
629 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org> 618 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
@@ -703,8 +692,8 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
703 if (0 == *count) 692 if (0 == *count)
704 *count = S2255_DEF_BUFS; 693 *count = S2255_DEF_BUFS;
705 694
706 while (*size * (*count) > vid_limit * 1024 * 1024) 695 if (*size * *count > vid_limit * 1024 * 1024)
707 (*count)--; 696 *count = (vid_limit * 1024 * 1024) / *size;
708 697
709 return 0; 698 return 0;
710} 699}
@@ -727,10 +716,10 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
727 if (fh->fmt == NULL) 716 if (fh->fmt == NULL)
728 return -EINVAL; 717 return -EINVAL;
729 718
730 if ((fh->width < norm_minw(fh->dev->vdev[fh->channel])) || 719 if ((fh->width < norm_minw(&fh->dev->vdev[fh->channel])) ||
731 (fh->width > norm_maxw(fh->dev->vdev[fh->channel])) || 720 (fh->width > norm_maxw(&fh->dev->vdev[fh->channel])) ||
732 (fh->height < norm_minh(fh->dev->vdev[fh->channel])) || 721 (fh->height < norm_minh(&fh->dev->vdev[fh->channel])) ||
733 (fh->height > norm_maxh(fh->dev->vdev[fh->channel]))) { 722 (fh->height > norm_maxh(&fh->dev->vdev[fh->channel]))) {
734 dprintk(4, "invalid buffer prepare\n"); 723 dprintk(4, "invalid buffer prepare\n");
735 return -EINVAL; 724 return -EINVAL;
736 } 725 }
@@ -747,7 +736,6 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
747 buf->vb.height = fh->height; 736 buf->vb.height = fh->height;
748 buf->vb.field = field; 737 buf->vb.field = field;
749 738
750
751 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 739 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
752 rc = videobuf_iolock(vq, &buf->vb, NULL); 740 rc = videobuf_iolock(vq, &buf->vb, NULL);
753 if (rc < 0) 741 if (rc < 0)
@@ -767,9 +755,7 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
767 struct s2255_fh *fh = vq->priv_data; 755 struct s2255_fh *fh = vq->priv_data;
768 struct s2255_dev *dev = fh->dev; 756 struct s2255_dev *dev = fh->dev;
769 struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel]; 757 struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel];
770
771 dprintk(1, "%s\n", __func__); 758 dprintk(1, "%s\n", __func__);
772
773 buf->vb.state = VIDEOBUF_QUEUED; 759 buf->vb.state = VIDEOBUF_QUEUED;
774 list_add_tail(&buf->vb.queue, &vidq->active); 760 list_add_tail(&buf->vb.queue, &vidq->active);
775} 761}
@@ -828,6 +814,27 @@ static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
828 dprintk(1, "res: put\n"); 814 dprintk(1, "res: put\n");
829} 815}
830 816
817static int vidioc_querymenu(struct file *file, void *priv,
818 struct v4l2_querymenu *qmenu)
819{
820 static const char *colorfilter[] = {
821 "Off",
822 "On",
823 NULL
824 };
825 if (qmenu->id == V4L2_CID_PRIVATE_COLORFILTER) {
826 int i;
827 const char **menu_items = colorfilter;
828 for (i = 0; i < qmenu->index && menu_items[i]; i++)
829 ; /* do nothing (from v4l2-common.c) */
830 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
831 return -EINVAL;
832 strlcpy(qmenu->name, menu_items[qmenu->index],
833 sizeof(qmenu->name));
834 return 0;
835 }
836 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
837}
831 838
832static int vidioc_querycap(struct file *file, void *priv, 839static int vidioc_querycap(struct file *file, void *priv,
833 struct v4l2_capability *cap) 840 struct v4l2_capability *cap)
@@ -883,7 +890,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
883 int is_ntsc; 890 int is_ntsc;
884 891
885 is_ntsc = 892 is_ntsc =
886 (dev->vdev[fh->channel]->current_norm & V4L2_STD_NTSC) ? 1 : 0; 893 (dev->vdev[fh->channel].current_norm & V4L2_STD_NTSC) ? 1 : 0;
887 894
888 fmt = format_by_fourcc(f->fmt.pix.pixelformat); 895 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
889 896
@@ -894,10 +901,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
894 if (field == V4L2_FIELD_ANY) 901 if (field == V4L2_FIELD_ANY)
895 b_any_field = 1; 902 b_any_field = 1;
896 903
897 dprintk(4, "try format %d \n", is_ntsc); 904 dprintk(50, "%s NTSC: %d suggested width: %d, height: %d\n",
898 /* supports 3 sizes. see s2255drv.h */ 905 __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
899 dprintk(50, "width test %d, height %d\n",
900 f->fmt.pix.width, f->fmt.pix.height);
901 if (is_ntsc) { 906 if (is_ntsc) {
902 /* NTSC */ 907 /* NTSC */
903 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) { 908 if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
@@ -952,29 +957,24 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
952 } 957 }
953 } 958 }
954 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) { 959 if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
955 dprintk(50, "pal 704\n");
956 f->fmt.pix.width = LINE_SZ_4CIFS_PAL; 960 f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
957 field = V4L2_FIELD_SEQ_TB; 961 field = V4L2_FIELD_SEQ_TB;
958 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) { 962 } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
959 dprintk(50, "pal 352A\n");
960 f->fmt.pix.width = LINE_SZ_2CIFS_PAL; 963 f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
961 field = V4L2_FIELD_TOP; 964 field = V4L2_FIELD_TOP;
962 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) { 965 } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
963 dprintk(50, "pal 352B\n");
964 f->fmt.pix.width = LINE_SZ_1CIFS_PAL; 966 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
965 field = V4L2_FIELD_TOP; 967 field = V4L2_FIELD_TOP;
966 } else { 968 } else {
967 dprintk(50, "pal 352C\n");
968 f->fmt.pix.width = LINE_SZ_1CIFS_PAL; 969 f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
969 field = V4L2_FIELD_TOP; 970 field = V4L2_FIELD_TOP;
970 } 971 }
971 } 972 }
972
973 dprintk(50, "width %d height %d field %d \n", f->fmt.pix.width,
974 f->fmt.pix.height, f->fmt.pix.field);
975 f->fmt.pix.field = field; 973 f->fmt.pix.field = field;
976 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; 974 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
977 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 975 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
976 dprintk(50, "%s: set width %d height %d field %d\n", __func__,
977 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
978 return 0; 978 return 0;
979} 979}
980 980
@@ -1006,7 +1006,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1006 } 1006 }
1007 1007
1008 if (res_locked(fh->dev, fh)) { 1008 if (res_locked(fh->dev, fh)) {
1009 dprintk(1, "can't change format after started\n"); 1009 dprintk(1, "%s: channel busy\n", __func__);
1010 ret = -EBUSY; 1010 ret = -EBUSY;
1011 goto out_s_fmt; 1011 goto out_s_fmt;
1012 } 1012 }
@@ -1016,17 +1016,14 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1016 fh->height = f->fmt.pix.height; 1016 fh->height = f->fmt.pix.height;
1017 fh->vb_vidq.field = f->fmt.pix.field; 1017 fh->vb_vidq.field = f->fmt.pix.field;
1018 fh->type = f->type; 1018 fh->type = f->type;
1019 norm = norm_minw(fh->dev->vdev[fh->channel]); 1019 norm = norm_minw(&fh->dev->vdev[fh->channel]);
1020 if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { 1020 if (fh->width > norm_minw(&fh->dev->vdev[fh->channel])) {
1021 if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) { 1021 if (fh->height > norm_minh(&fh->dev->vdev[fh->channel])) {
1022 if (fh->dev->cap_parm[fh->channel].capturemode & 1022 if (fh->dev->cap_parm[fh->channel].capturemode &
1023 V4L2_MODE_HIGHQUALITY) { 1023 V4L2_MODE_HIGHQUALITY)
1024 fh->mode.scale = SCALE_4CIFSI; 1024 fh->mode.scale = SCALE_4CIFSI;
1025 dprintk(2, "scale 4CIFSI\n"); 1025 else
1026 } else {
1027 fh->mode.scale = SCALE_4CIFS; 1026 fh->mode.scale = SCALE_4CIFS;
1028 dprintk(2, "scale 4CIFS\n");
1029 }
1030 } else 1027 } else
1031 fh->mode.scale = SCALE_2CIFS; 1028 fh->mode.scale = SCALE_2CIFS;
1032 1029
@@ -1037,19 +1034,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1037 /* color mode */ 1034 /* color mode */
1038 switch (fh->fmt->fourcc) { 1035 switch (fh->fmt->fourcc) {
1039 case V4L2_PIX_FMT_GREY: 1036 case V4L2_PIX_FMT_GREY:
1040 fh->mode.color = COLOR_Y8; 1037 fh->mode.color &= ~MASK_COLOR;
1038 fh->mode.color |= COLOR_Y8;
1041 break; 1039 break;
1042 case V4L2_PIX_FMT_JPEG: 1040 case V4L2_PIX_FMT_JPEG:
1043 fh->mode.color = COLOR_JPG | 1041 fh->mode.color &= ~MASK_COLOR;
1044 (fh->dev->jc[fh->channel].quality << 8); 1042 fh->mode.color |= COLOR_JPG;
1043 fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8);
1045 break; 1044 break;
1046 case V4L2_PIX_FMT_YUV422P: 1045 case V4L2_PIX_FMT_YUV422P:
1047 fh->mode.color = COLOR_YUVPL; 1046 fh->mode.color &= ~MASK_COLOR;
1047 fh->mode.color |= COLOR_YUVPL;
1048 break; 1048 break;
1049 case V4L2_PIX_FMT_YUYV: 1049 case V4L2_PIX_FMT_YUYV:
1050 case V4L2_PIX_FMT_UYVY: 1050 case V4L2_PIX_FMT_UYVY:
1051 default: 1051 default:
1052 fh->mode.color = COLOR_YUVPK; 1052 fh->mode.color &= ~MASK_COLOR;
1053 fh->mode.color |= COLOR_YUVPK;
1053 break; 1054 break;
1054 } 1055 }
1055 ret = 0; 1056 ret = 0;
@@ -1178,19 +1179,13 @@ static u32 get_transfer_size(struct s2255_mode *mode)
1178 return usbInSize; 1179 return usbInSize;
1179} 1180}
1180 1181
1181static void dump_verify_mode(struct s2255_dev *sdev, struct s2255_mode *mode) 1182static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
1182{ 1183{
1183 struct device *dev = &sdev->udev->dev; 1184 struct device *dev = &sdev->udev->dev;
1184 dev_info(dev, "------------------------------------------------\n"); 1185 dev_info(dev, "------------------------------------------------\n");
1185 dev_info(dev, "verify mode\n"); 1186 dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
1186 dev_info(dev, "format: %d\n", mode->format); 1187 dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
1187 dev_info(dev, "scale: %d\n", mode->scale);
1188 dev_info(dev, "fdec: %d\n", mode->fdec);
1189 dev_info(dev, "color: %d\n", mode->color);
1190 dev_info(dev, "bright: 0x%x\n", mode->bright); 1188 dev_info(dev, "bright: 0x%x\n", mode->bright);
1191 dev_info(dev, "restart: 0x%x\n", mode->restart);
1192 dev_info(dev, "usb_block: 0x%x\n", mode->usb_block);
1193 dev_info(dev, "single: 0x%x\n", mode->single);
1194 dev_info(dev, "------------------------------------------------\n"); 1189 dev_info(dev, "------------------------------------------------\n");
1195} 1190}
1196 1191
@@ -1206,44 +1201,38 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
1206 struct s2255_mode *mode) 1201 struct s2255_mode *mode)
1207{ 1202{
1208 int res; 1203 int res;
1209 u32 *buffer; 1204 __le32 *buffer;
1210 unsigned long chn_rev; 1205 unsigned long chn_rev;
1211
1212 mutex_lock(&dev->lock); 1206 mutex_lock(&dev->lock);
1213 chn_rev = G_chnmap[chn]; 1207 chn_rev = G_chnmap[chn];
1214 dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale); 1208 dprintk(3, "%s channel %lu\n", __func__, chn);
1215 dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn],
1216 dev->mode[chn].scale);
1217 dprintk(2, "mode contrast %x\n", mode->contrast);
1218
1219 /* if JPEG, set the quality */ 1209 /* if JPEG, set the quality */
1220 if ((mode->color & MASK_COLOR) == COLOR_JPG) 1210 if ((mode->color & MASK_COLOR) == COLOR_JPG) {
1221 mode->color = (dev->jc[chn].quality << 8) | COLOR_JPG; 1211 mode->color &= ~MASK_COLOR;
1222 1212 mode->color |= COLOR_JPG;
1213 mode->color &= ~MASK_JPG_QUALITY;
1214 mode->color |= (dev->jc[chn].quality << 8);
1215 }
1223 /* save the mode */ 1216 /* save the mode */
1224 dev->mode[chn] = *mode; 1217 dev->mode[chn] = *mode;
1225 dev->req_image_size[chn] = get_transfer_size(mode); 1218 dev->req_image_size[chn] = get_transfer_size(mode);
1226 dprintk(1, "transfer size %ld\n", dev->req_image_size[chn]); 1219 dprintk(1, "%s: reqsize %ld\n", __func__, dev->req_image_size[chn]);
1227
1228 buffer = kzalloc(512, GFP_KERNEL); 1220 buffer = kzalloc(512, GFP_KERNEL);
1229 if (buffer == NULL) { 1221 if (buffer == NULL) {
1230 dev_err(&dev->udev->dev, "out of mem\n"); 1222 dev_err(&dev->udev->dev, "out of mem\n");
1231 mutex_unlock(&dev->lock); 1223 mutex_unlock(&dev->lock);
1232 return -ENOMEM; 1224 return -ENOMEM;
1233 } 1225 }
1234
1235 /* set the mode */ 1226 /* set the mode */
1236 buffer[0] = IN_DATA_TOKEN; 1227 buffer[0] = IN_DATA_TOKEN;
1237 buffer[1] = (u32) chn_rev; 1228 buffer[1] = (__le32) cpu_to_le32(chn_rev);
1238 buffer[2] = CMD_SET_MODE; 1229 buffer[2] = CMD_SET_MODE;
1239 memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode)); 1230 memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
1240 dev->setmode_ready[chn] = 0; 1231 dev->setmode_ready[chn] = 0;
1241 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); 1232 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1242 if (debug) 1233 if (debug)
1243 dump_verify_mode(dev, mode); 1234 s2255_print_cfg(dev, mode);
1244 kfree(buffer); 1235 kfree(buffer);
1245 dprintk(1, "set mode done chn %lu, %d\n", chn, res);
1246
1247 /* wait at least 3 frames before continuing */ 1236 /* wait at least 3 frames before continuing */
1248 if (mode->restart) { 1237 if (mode->restart) {
1249 wait_event_timeout(dev->wait_setmode[chn], 1238 wait_event_timeout(dev->wait_setmode[chn],
@@ -1254,10 +1243,46 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
1254 res = -EFAULT; 1243 res = -EFAULT;
1255 } 1244 }
1256 } 1245 }
1257
1258 /* clear the restart flag */ 1246 /* clear the restart flag */
1259 dev->mode[chn].restart = 0; 1247 dev->mode[chn].restart = 0;
1260 mutex_unlock(&dev->lock); 1248 mutex_unlock(&dev->lock);
1249 dprintk(1, "%s chn %lu, result: %d\n", __func__, chn, res);
1250 return res;
1251}
1252
1253static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
1254 u32 *pstatus)
1255{
1256 int res;
1257 __le32 *buffer;
1258 u32 chn_rev;
1259 mutex_lock(&dev->lock);
1260 chn_rev = G_chnmap[chn];
1261 dprintk(4, "%s chan %lu\n", __func__, chn);
1262 buffer = kzalloc(512, GFP_KERNEL);
1263 if (buffer == NULL) {
1264 dev_err(&dev->udev->dev, "out of mem\n");
1265 mutex_unlock(&dev->lock);
1266 return -ENOMEM;
1267 }
1268 /* form the get vid status command */
1269 buffer[0] = IN_DATA_TOKEN;
1270 buffer[1] = (__le32) cpu_to_le32(chn_rev);
1271 buffer[2] = CMD_STATUS;
1272 *pstatus = 0;
1273 dev->vidstatus_ready[chn] = 0;
1274 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
1275 kfree(buffer);
1276 wait_event_timeout(dev->wait_vidstatus[chn],
1277 (dev->vidstatus_ready[chn] != 0),
1278 msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
1279 if (dev->vidstatus_ready[chn] != 1) {
1280 printk(KERN_DEBUG "s2255: no vidstatus response\n");
1281 res = -EFAULT;
1282 }
1283 *pstatus = dev->vidstatus[chn];
1284 dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
1285 mutex_unlock(&dev->lock);
1261 return res; 1286 return res;
1262} 1287}
1263 1288
@@ -1291,7 +1316,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1291 new_mode = &fh->mode; 1316 new_mode = &fh->mode;
1292 old_mode = &fh->dev->mode[chn]; 1317 old_mode = &fh->dev->mode[chn];
1293 1318
1294 if (new_mode->color != old_mode->color) 1319 if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR))
1295 new_mode->restart = 1; 1320 new_mode->restart = 1;
1296 else if (new_mode->scale != old_mode->scale) 1321 else if (new_mode->scale != old_mode->scale)
1297 new_mode->restart = 1; 1322 new_mode->restart = 1;
@@ -1302,7 +1327,6 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1302 new_mode->restart = 0; 1327 new_mode->restart = 0;
1303 *old_mode = *new_mode; 1328 *old_mode = *new_mode;
1304 dev->cur_fmt[chn] = fh->fmt; 1329 dev->cur_fmt[chn] = fh->fmt;
1305 dprintk(1, "%s[%d]\n", __func__, chn);
1306 dev->last_frame[chn] = -1; 1330 dev->last_frame[chn] = -1;
1307 dev->bad_payload[chn] = 0; 1331 dev->bad_payload[chn] = 0;
1308 dev->cur_frame[chn] = 0; 1332 dev->cur_frame[chn] = 0;
@@ -1325,7 +1349,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1325{ 1349{
1326 struct s2255_fh *fh = priv; 1350 struct s2255_fh *fh = priv;
1327 struct s2255_dev *dev = fh->dev; 1351 struct s2255_dev *dev = fh->dev;
1328
1329 dprintk(4, "%s\n, channel: %d", __func__, fh->channel); 1352 dprintk(4, "%s\n, channel: %d", __func__, fh->channel);
1330 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1353 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1331 printk(KERN_ERR "invalid fh type0\n"); 1354 printk(KERN_ERR "invalid fh type0\n");
@@ -1347,27 +1370,32 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1347 struct s2255_mode *mode; 1370 struct s2255_mode *mode;
1348 struct videobuf_queue *q = &fh->vb_vidq; 1371 struct videobuf_queue *q = &fh->vb_vidq;
1349 int ret = 0; 1372 int ret = 0;
1350
1351 mutex_lock(&q->vb_lock); 1373 mutex_lock(&q->vb_lock);
1352 if (videobuf_queue_is_busy(q)) { 1374 if (videobuf_queue_is_busy(q)) {
1353 dprintk(1, "queue busy\n"); 1375 dprintk(1, "queue busy\n");
1354 ret = -EBUSY; 1376 ret = -EBUSY;
1355 goto out_s_std; 1377 goto out_s_std;
1356 } 1378 }
1357
1358 if (res_locked(fh->dev, fh)) { 1379 if (res_locked(fh->dev, fh)) {
1359 dprintk(1, "can't change standard after started\n"); 1380 dprintk(1, "can't change standard after started\n");
1360 ret = -EBUSY; 1381 ret = -EBUSY;
1361 goto out_s_std; 1382 goto out_s_std;
1362 } 1383 }
1363 mode = &fh->mode; 1384 mode = &fh->mode;
1364
1365 if (*i & V4L2_STD_NTSC) { 1385 if (*i & V4L2_STD_NTSC) {
1366 dprintk(4, "vidioc_s_std NTSC\n"); 1386 dprintk(4, "%s NTSC\n", __func__);
1367 mode->format = FORMAT_NTSC; 1387 /* if changing format, reset frame decimation/intervals */
1388 if (mode->format != FORMAT_NTSC) {
1389 mode->format = FORMAT_NTSC;
1390 mode->fdec = FDEC_1;
1391 }
1368 } else if (*i & V4L2_STD_PAL) { 1392 } else if (*i & V4L2_STD_PAL) {
1369 dprintk(4, "vidioc_s_std PAL\n"); 1393 dprintk(4, "%s PAL\n", __func__);
1370 mode->format = FORMAT_PAL; 1394 mode->format = FORMAT_PAL;
1395 if (mode->format != FORMAT_PAL) {
1396 mode->format = FORMAT_PAL;
1397 mode->fdec = FDEC_1;
1398 }
1371 } else { 1399 } else {
1372 ret = -EINVAL; 1400 ret = -EINVAL;
1373 } 1401 }
@@ -1386,12 +1414,32 @@ out_s_std:
1386static int vidioc_enum_input(struct file *file, void *priv, 1414static int vidioc_enum_input(struct file *file, void *priv,
1387 struct v4l2_input *inp) 1415 struct v4l2_input *inp)
1388{ 1416{
1417 struct s2255_fh *fh = priv;
1418 struct s2255_dev *dev = fh->dev;
1419 u32 status = 0;
1389 if (inp->index != 0) 1420 if (inp->index != 0)
1390 return -EINVAL; 1421 return -EINVAL;
1391
1392 inp->type = V4L2_INPUT_TYPE_CAMERA; 1422 inp->type = V4L2_INPUT_TYPE_CAMERA;
1393 inp->std = S2255_NORMS; 1423 inp->std = S2255_NORMS;
1394 strlcpy(inp->name, "Camera", sizeof(inp->name)); 1424 inp->status = 0;
1425 if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
1426 int rc;
1427 rc = s2255_cmd_status(dev, fh->channel, &status);
1428 dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
1429 if (rc == 0)
1430 inp->status = (status & 0x01) ? 0
1431 : V4L2_IN_ST_NO_SIGNAL;
1432 }
1433 switch (dev->pid) {
1434 case 0x2255:
1435 default:
1436 strlcpy(inp->name, "Composite", sizeof(inp->name));
1437 break;
1438 case 0x2257:
1439 strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video",
1440 sizeof(inp->name));
1441 break;
1442 }
1395 return 0; 1443 return 0;
1396} 1444}
1397 1445
@@ -1411,74 +1459,113 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1411static int vidioc_queryctrl(struct file *file, void *priv, 1459static int vidioc_queryctrl(struct file *file, void *priv,
1412 struct v4l2_queryctrl *qc) 1460 struct v4l2_queryctrl *qc)
1413{ 1461{
1414 int i; 1462 struct s2255_fh *fh = priv;
1415 1463 struct s2255_dev *dev = fh->dev;
1416 for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) 1464 switch (qc->id) {
1417 if (qc->id && qc->id == s2255_qctrl[i].id) { 1465 case V4L2_CID_BRIGHTNESS:
1418 memcpy(qc, &(s2255_qctrl[i]), sizeof(*qc)); 1466 v4l2_ctrl_query_fill(qc, -127, 127, 1, DEF_BRIGHT);
1419 return 0; 1467 break;
1420 } 1468 case V4L2_CID_CONTRAST:
1421 1469 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_CONTRAST);
1422 dprintk(4, "query_ctrl -EINVAL %d\n", qc->id); 1470 break;
1423 return -EINVAL; 1471 case V4L2_CID_SATURATION:
1472 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_SATURATION);
1473 break;
1474 case V4L2_CID_HUE:
1475 v4l2_ctrl_query_fill(qc, 0, 255, 1, DEF_HUE);
1476 break;
1477 case V4L2_CID_PRIVATE_COLORFILTER:
1478 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1479 return -EINVAL;
1480 if ((dev->pid == 0x2257) && (fh->channel > 1))
1481 return -EINVAL;
1482 strlcpy(qc->name, "Color Filter", sizeof(qc->name));
1483 qc->type = V4L2_CTRL_TYPE_MENU;
1484 qc->minimum = 0;
1485 qc->maximum = 1;
1486 qc->step = 1;
1487 qc->default_value = 1;
1488 qc->flags = 0;
1489 break;
1490 default:
1491 return -EINVAL;
1492 }
1493 dprintk(4, "%s, id %d\n", __func__, qc->id);
1494 return 0;
1424} 1495}
1425 1496
1426static int vidioc_g_ctrl(struct file *file, void *priv, 1497static int vidioc_g_ctrl(struct file *file, void *priv,
1427 struct v4l2_control *ctrl) 1498 struct v4l2_control *ctrl)
1428{ 1499{
1429 int i; 1500 struct s2255_fh *fh = priv;
1430 1501 struct s2255_dev *dev = fh->dev;
1431 for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) 1502 switch (ctrl->id) {
1432 if (ctrl->id == s2255_qctrl[i].id) { 1503 case V4L2_CID_BRIGHTNESS:
1433 ctrl->value = qctl_regs[i]; 1504 ctrl->value = fh->mode.bright;
1434 return 0; 1505 break;
1435 } 1506 case V4L2_CID_CONTRAST:
1436 dprintk(4, "g_ctrl -EINVAL\n"); 1507 ctrl->value = fh->mode.contrast;
1437 1508 break;
1438 return -EINVAL; 1509 case V4L2_CID_SATURATION:
1510 ctrl->value = fh->mode.saturation;
1511 break;
1512 case V4L2_CID_HUE:
1513 ctrl->value = fh->mode.hue;
1514 break;
1515 case V4L2_CID_PRIVATE_COLORFILTER:
1516 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1517 return -EINVAL;
1518 if ((dev->pid == 0x2257) && (fh->channel > 1))
1519 return -EINVAL;
1520 ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16);
1521 break;
1522 default:
1523 return -EINVAL;
1524 }
1525 dprintk(4, "%s, id %d val %d\n", __func__, ctrl->id, ctrl->value);
1526 return 0;
1439} 1527}
1440 1528
1441static int vidioc_s_ctrl(struct file *file, void *priv, 1529static int vidioc_s_ctrl(struct file *file, void *priv,
1442 struct v4l2_control *ctrl) 1530 struct v4l2_control *ctrl)
1443{ 1531{
1444 int i;
1445 struct s2255_fh *fh = priv; 1532 struct s2255_fh *fh = priv;
1446 struct s2255_dev *dev = fh->dev; 1533 struct s2255_dev *dev = fh->dev;
1447 struct s2255_mode *mode; 1534 struct s2255_mode *mode;
1448 mode = &fh->mode; 1535 mode = &fh->mode;
1449 dprintk(4, "vidioc_s_ctrl\n"); 1536 dprintk(4, "%s\n", __func__);
1450 for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) { 1537 /* update the mode to the corresponding value */
1451 if (ctrl->id == s2255_qctrl[i].id) { 1538 switch (ctrl->id) {
1452 if (ctrl->value < s2255_qctrl[i].minimum || 1539 case V4L2_CID_BRIGHTNESS:
1453 ctrl->value > s2255_qctrl[i].maximum) 1540 mode->bright = ctrl->value;
1454 return -ERANGE; 1541 break;
1455 1542 case V4L2_CID_CONTRAST:
1456 qctl_regs[i] = ctrl->value; 1543 mode->contrast = ctrl->value;
1457 /* update the mode to the corresponding value */ 1544 break;
1458 switch (ctrl->id) { 1545 case V4L2_CID_HUE:
1459 case V4L2_CID_BRIGHTNESS: 1546 mode->hue = ctrl->value;
1460 mode->bright = ctrl->value; 1547 break;
1461 break; 1548 case V4L2_CID_SATURATION:
1462 case V4L2_CID_CONTRAST: 1549 mode->saturation = ctrl->value;
1463 mode->contrast = ctrl->value; 1550 break;
1464 break; 1551 case V4L2_CID_PRIVATE_COLORFILTER:
1465 case V4L2_CID_HUE: 1552 if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
1466 mode->hue = ctrl->value; 1553 return -EINVAL;
1467 break; 1554 if ((dev->pid == 0x2257) && (fh->channel > 1))
1468 case V4L2_CID_SATURATION: 1555 return -EINVAL;
1469 mode->saturation = ctrl->value; 1556 mode->color &= ~MASK_INPUT_TYPE;
1470 break; 1557 mode->color |= ((ctrl->value ? 0 : 1) << 16);
1471 } 1558 break;
1472 mode->restart = 0; 1559 default:
1473 /* set mode here. Note: stream does not need restarted. 1560 return -EINVAL;
1474 some V4L programs restart stream unnecessarily
1475 after a s_crtl.
1476 */
1477 s2255_set_mode(dev, fh->channel, mode);
1478 return 0;
1479 }
1480 } 1561 }
1481 return -EINVAL; 1562 mode->restart = 0;
1563 /* set mode here. Note: stream does not need restarted.
1564 some V4L programs restart stream unnecessarily
1565 after a s_crtl.
1566 */
1567 s2255_set_mode(dev, fh->channel, mode);
1568 return 0;
1482} 1569}
1483 1570
1484static int vidioc_g_jpegcomp(struct file *file, void *priv, 1571static int vidioc_g_jpegcomp(struct file *file, void *priv,
@@ -1487,7 +1574,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
1487 struct s2255_fh *fh = priv; 1574 struct s2255_fh *fh = priv;
1488 struct s2255_dev *dev = fh->dev; 1575 struct s2255_dev *dev = fh->dev;
1489 *jc = dev->jc[fh->channel]; 1576 *jc = dev->jc[fh->channel];
1490 dprintk(2, "getting jpegcompression, quality %d\n", jc->quality); 1577 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
1491 return 0; 1578 return 0;
1492} 1579}
1493 1580
@@ -1499,7 +1586,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
1499 if (jc->quality < 0 || jc->quality > 100) 1586 if (jc->quality < 0 || jc->quality > 100)
1500 return -EINVAL; 1587 return -EINVAL;
1501 dev->jc[fh->channel].quality = jc->quality; 1588 dev->jc[fh->channel].quality = jc->quality;
1502 dprintk(2, "setting jpeg quality %d\n", jc->quality); 1589 dprintk(2, "%s: quality %d\n", __func__, jc->quality);
1503 return 0; 1590 return 0;
1504} 1591}
1505 1592
@@ -1508,10 +1595,34 @@ static int vidioc_g_parm(struct file *file, void *priv,
1508{ 1595{
1509 struct s2255_fh *fh = priv; 1596 struct s2255_fh *fh = priv;
1510 struct s2255_dev *dev = fh->dev; 1597 struct s2255_dev *dev = fh->dev;
1598 __u32 def_num, def_dem;
1511 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1599 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1512 return -EINVAL; 1600 return -EINVAL;
1601 memset(sp, 0, sizeof(struct v4l2_streamparm));
1602 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1513 sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; 1603 sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
1514 dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode); 1604 def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1605 def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
1606 sp->parm.capture.timeperframe.denominator = def_dem;
1607 switch (fh->mode.fdec) {
1608 default:
1609 case FDEC_1:
1610 sp->parm.capture.timeperframe.numerator = def_num;
1611 break;
1612 case FDEC_2:
1613 sp->parm.capture.timeperframe.numerator = def_num * 2;
1614 break;
1615 case FDEC_3:
1616 sp->parm.capture.timeperframe.numerator = def_num * 3;
1617 break;
1618 case FDEC_5:
1619 sp->parm.capture.timeperframe.numerator = def_num * 5;
1620 break;
1621 }
1622 dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__,
1623 sp->parm.capture.capturemode,
1624 sp->parm.capture.timeperframe.numerator,
1625 sp->parm.capture.timeperframe.denominator);
1515 return 0; 1626 return 0;
1516} 1627}
1517 1628
@@ -1520,15 +1631,79 @@ static int vidioc_s_parm(struct file *file, void *priv,
1520{ 1631{
1521 struct s2255_fh *fh = priv; 1632 struct s2255_fh *fh = priv;
1522 struct s2255_dev *dev = fh->dev; 1633 struct s2255_dev *dev = fh->dev;
1523 1634 int fdec = FDEC_1;
1635 __u32 def_num, def_dem;
1524 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1636 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1525 return -EINVAL; 1637 return -EINVAL;
1638 /* high quality capture mode requires a stream restart */
1639 if (dev->cap_parm[fh->channel].capturemode
1640 != sp->parm.capture.capturemode && res_locked(fh->dev, fh))
1641 return -EBUSY;
1642 def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
1643 def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
1644 if (def_dem != sp->parm.capture.timeperframe.denominator)
1645 sp->parm.capture.timeperframe.numerator = def_num;
1646 else if (sp->parm.capture.timeperframe.numerator <= def_num)
1647 sp->parm.capture.timeperframe.numerator = def_num;
1648 else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
1649 sp->parm.capture.timeperframe.numerator = def_num * 2;
1650 fdec = FDEC_2;
1651 } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
1652 sp->parm.capture.timeperframe.numerator = def_num * 3;
1653 fdec = FDEC_3;
1654 } else {
1655 sp->parm.capture.timeperframe.numerator = def_num * 5;
1656 fdec = FDEC_5;
1657 }
1658 fh->mode.fdec = fdec;
1659 sp->parm.capture.timeperframe.denominator = def_dem;
1660 s2255_set_mode(dev, fh->channel, &fh->mode);
1661 dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
1662 __func__,
1663 sp->parm.capture.capturemode,
1664 sp->parm.capture.timeperframe.numerator,
1665 sp->parm.capture.timeperframe.denominator, fdec);
1666 return 0;
1667}
1526 1668
1527 dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode; 1669static int vidioc_enum_frameintervals(struct file *file, void *priv,
1528 dprintk(2, "setting param capture mode %d\n", 1670 struct v4l2_frmivalenum *fe)
1529 sp->parm.capture.capturemode); 1671{
1672 int is_ntsc = 0;
1673#define NUM_FRAME_ENUMS 4
1674 int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
1675 if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
1676 return -EINVAL;
1677 switch (fe->width) {
1678 case 640:
1679 if (fe->height != 240 && fe->height != 480)
1680 return -EINVAL;
1681 is_ntsc = 1;
1682 break;
1683 case 320:
1684 if (fe->height != 240)
1685 return -EINVAL;
1686 is_ntsc = 1;
1687 break;
1688 case 704:
1689 if (fe->height != 288 && fe->height != 576)
1690 return -EINVAL;
1691 break;
1692 case 352:
1693 if (fe->height != 288)
1694 return -EINVAL;
1695 break;
1696 default:
1697 return -EINVAL;
1698 }
1699 fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1700 fe->discrete.denominator = is_ntsc ? 30000 : 25000;
1701 fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
1702 dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator,
1703 fe->discrete.denominator);
1530 return 0; 1704 return 0;
1531} 1705}
1706
1532static int s2255_open(struct file *file) 1707static int s2255_open(struct file *file)
1533{ 1708{
1534 struct video_device *vdev = video_devdata(file); 1709 struct video_device *vdev = video_devdata(file);
@@ -1538,31 +1713,29 @@ static int s2255_open(struct file *file)
1538 int i = 0; 1713 int i = 0;
1539 int cur_channel = -1; 1714 int cur_channel = -1;
1540 int state; 1715 int state;
1541
1542 dprintk(1, "s2255: open called (dev=%s)\n", 1716 dprintk(1, "s2255: open called (dev=%s)\n",
1543 video_device_node_name(vdev)); 1717 video_device_node_name(vdev));
1544 1718
1545 lock_kernel();
1546
1547 for (i = 0; i < MAX_CHANNELS; i++) { 1719 for (i = 0; i < MAX_CHANNELS; i++) {
1548 if (dev->vdev[i] == vdev) { 1720 if (&dev->vdev[i] == vdev) {
1549 cur_channel = i; 1721 cur_channel = i;
1550 break; 1722 break;
1551 } 1723 }
1552 } 1724 }
1553 1725 if (i == MAX_CHANNELS)
1554 if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) {
1555 unlock_kernel();
1556 printk(KERN_INFO "disconnecting\n");
1557 return -ENODEV; 1726 return -ENODEV;
1558 }
1559 kref_get(&dev->kref);
1560 mutex_lock(&dev->open_lock);
1561
1562 dev->users[cur_channel]++;
1563 dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]);
1564 1727
1565 switch (atomic_read(&dev->fw_data->fw_state)) { 1728 /*
1729 * open lock necessary to prevent multiple instances
1730 * of v4l-conf (or other programs) from simultaneously
1731 * reloading firmware.
1732 */
1733 mutex_lock(&dev->open_lock);
1734 state = atomic_read(&dev->fw_data->fw_state);
1735 switch (state) {
1736 case S2255_FW_DISCONNECTING:
1737 mutex_unlock(&dev->open_lock);
1738 return -ENODEV;
1566 case S2255_FW_FAILED: 1739 case S2255_FW_FAILED:
1567 s2255_dev_err(&dev->udev->dev, 1740 s2255_dev_err(&dev->udev->dev,
1568 "firmware load failed. retrying.\n"); 1741 "firmware load failed. retrying.\n");
@@ -1573,6 +1746,8 @@ static int s2255_open(struct file *file)
1573 (atomic_read(&dev->fw_data->fw_state) 1746 (atomic_read(&dev->fw_data->fw_state)
1574 == S2255_FW_DISCONNECTING)), 1747 == S2255_FW_DISCONNECTING)),
1575 msecs_to_jiffies(S2255_LOAD_TIMEOUT)); 1748 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
1749 /* state may have changed, re-read */
1750 state = atomic_read(&dev->fw_data->fw_state);
1576 break; 1751 break;
1577 case S2255_FW_NOTLOADED: 1752 case S2255_FW_NOTLOADED:
1578 case S2255_FW_LOADED_DSPWAIT: 1753 case S2255_FW_LOADED_DSPWAIT:
@@ -1584,53 +1759,50 @@ static int s2255_open(struct file *file)
1584 == S2255_FW_SUCCESS) || 1759 == S2255_FW_SUCCESS) ||
1585 (atomic_read(&dev->fw_data->fw_state) 1760 (atomic_read(&dev->fw_data->fw_state)
1586 == S2255_FW_DISCONNECTING)), 1761 == S2255_FW_DISCONNECTING)),
1587 msecs_to_jiffies(S2255_LOAD_TIMEOUT)); 1762 msecs_to_jiffies(S2255_LOAD_TIMEOUT));
1763 /* state may have changed, re-read */
1764 state = atomic_read(&dev->fw_data->fw_state);
1588 break; 1765 break;
1589 case S2255_FW_SUCCESS: 1766 case S2255_FW_SUCCESS:
1590 default: 1767 default:
1591 break; 1768 break;
1592 } 1769 }
1593 state = atomic_read(&dev->fw_data->fw_state); 1770 /* state may have changed in above switch statement */
1594 if (state != S2255_FW_SUCCESS) { 1771 switch (state) {
1595 int rc; 1772 case S2255_FW_SUCCESS:
1596 switch (state) { 1773 break;
1597 case S2255_FW_FAILED: 1774 case S2255_FW_FAILED:
1598 printk(KERN_INFO "2255 FW load failed. %d\n", state); 1775 printk(KERN_INFO "2255 firmware load failed.\n");
1599 rc = -ENODEV; 1776 mutex_unlock(&dev->open_lock);
1600 break; 1777 return -ENODEV;
1601 case S2255_FW_DISCONNECTING: 1778 case S2255_FW_DISCONNECTING:
1602 printk(KERN_INFO "%s: disconnecting\n", __func__); 1779 printk(KERN_INFO "%s: disconnecting\n", __func__);
1603 rc = -ENODEV;
1604 break;
1605 case S2255_FW_LOADED_DSPWAIT:
1606 case S2255_FW_NOTLOADED:
1607 printk(KERN_INFO "%s: firmware not loaded yet"
1608 "please try again later\n",
1609 __func__);
1610 rc = -EAGAIN;
1611 break;
1612 default:
1613 printk(KERN_INFO "%s: unknown state\n", __func__);
1614 rc = -EFAULT;
1615 break;
1616 }
1617 dev->users[cur_channel]--;
1618 mutex_unlock(&dev->open_lock); 1780 mutex_unlock(&dev->open_lock);
1619 kref_put(&dev->kref, s2255_destroy); 1781 return -ENODEV;
1620 unlock_kernel(); 1782 case S2255_FW_LOADED_DSPWAIT:
1621 return rc; 1783 case S2255_FW_NOTLOADED:
1784 printk(KERN_INFO "%s: firmware not loaded yet"
1785 "please try again later\n",
1786 __func__);
1787 /*
1788 * Timeout on firmware load means device unusable.
1789 * Set firmware failure state.
1790 * On next s2255_open the firmware will be reloaded.
1791 */
1792 atomic_set(&dev->fw_data->fw_state,
1793 S2255_FW_FAILED);
1794 mutex_unlock(&dev->open_lock);
1795 return -EAGAIN;
1796 default:
1797 printk(KERN_INFO "%s: unknown state\n", __func__);
1798 mutex_unlock(&dev->open_lock);
1799 return -EFAULT;
1622 } 1800 }
1623 1801 mutex_unlock(&dev->open_lock);
1624 /* allocate + initialize per filehandle data */ 1802 /* allocate + initialize per filehandle data */
1625 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 1803 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1626 if (NULL == fh) { 1804 if (NULL == fh)
1627 dev->users[cur_channel]--;
1628 mutex_unlock(&dev->open_lock);
1629 kref_put(&dev->kref, s2255_destroy);
1630 unlock_kernel();
1631 return -ENOMEM; 1805 return -ENOMEM;
1632 }
1633
1634 file->private_data = fh; 1806 file->private_data = fh;
1635 fh->dev = dev; 1807 fh->dev = dev;
1636 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1808 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1640,35 +1812,23 @@ static int s2255_open(struct file *file)
1640 fh->width = LINE_SZ_4CIFS_NTSC; 1812 fh->width = LINE_SZ_4CIFS_NTSC;
1641 fh->height = NUM_LINES_4CIFS_NTSC * 2; 1813 fh->height = NUM_LINES_4CIFS_NTSC * 2;
1642 fh->channel = cur_channel; 1814 fh->channel = cur_channel;
1643
1644 /* configure channel to default state */ 1815 /* configure channel to default state */
1645 if (!dev->chn_configured[cur_channel]) { 1816 if (!dev->chn_configured[cur_channel]) {
1646 s2255_set_mode(dev, cur_channel, &fh->mode); 1817 s2255_set_mode(dev, cur_channel, &fh->mode);
1647 dev->chn_configured[cur_channel] = 1; 1818 dev->chn_configured[cur_channel] = 1;
1648 } 1819 }
1649 1820 dprintk(1, "%s: dev=%s type=%s\n", __func__,
1650 1821 video_device_node_name(vdev), v4l2_type_names[type]);
1651 /* Put all controls at a sane state */ 1822 dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
1652 for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++)
1653 qctl_regs[i] = s2255_qctrl[i].default_value;
1654
1655 dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n",
1656 video_device_node_name(vdev), v4l2_type_names[type],
1657 dev->users[cur_channel]);
1658 dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n",
1659 (unsigned long)fh, (unsigned long)dev, 1823 (unsigned long)fh, (unsigned long)dev,
1660 (unsigned long)&dev->vidq[cur_channel]); 1824 (unsigned long)&dev->vidq[cur_channel]);
1661 dprintk(4, "s2255drv: open: list_empty active=%d\n", 1825 dprintk(4, "%s: list_empty active=%d\n", __func__,
1662 list_empty(&dev->vidq[cur_channel].active)); 1826 list_empty(&dev->vidq[cur_channel].active));
1663
1664 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops, 1827 videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
1665 NULL, &dev->slock, 1828 NULL, &dev->slock,
1666 fh->type, 1829 fh->type,
1667 V4L2_FIELD_INTERLACED, 1830 V4L2_FIELD_INTERLACED,
1668 sizeof(struct s2255_buffer), fh); 1831 sizeof(struct s2255_buffer), fh);
1669
1670 mutex_unlock(&dev->open_lock);
1671 unlock_kernel();
1672 return 0; 1832 return 0;
1673} 1833}
1674 1834
@@ -1679,39 +1839,19 @@ static unsigned int s2255_poll(struct file *file,
1679 struct s2255_fh *fh = file->private_data; 1839 struct s2255_fh *fh = file->private_data;
1680 int rc; 1840 int rc;
1681 dprintk(100, "%s\n", __func__); 1841 dprintk(100, "%s\n", __func__);
1682
1683 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 1842 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1684 return POLLERR; 1843 return POLLERR;
1685
1686 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); 1844 rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
1687 return rc; 1845 return rc;
1688} 1846}
1689 1847
1690static void s2255_destroy(struct kref *kref) 1848static void s2255_destroy(struct s2255_dev *dev)
1691{ 1849{
1692 struct s2255_dev *dev = to_s2255_dev(kref);
1693 int i;
1694 if (!dev) {
1695 printk(KERN_ERR "s2255drv: kref problem\n");
1696 return;
1697 }
1698 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
1699 wake_up(&dev->fw_data->wait_fw);
1700 for (i = 0; i < MAX_CHANNELS; i++) {
1701 dev->setmode_ready[i] = 1;
1702 wake_up(&dev->wait_setmode[i]);
1703 }
1704 mutex_lock(&dev->open_lock);
1705 /* reset the DSP so firmware can be reload next time */
1706 s2255_reset_dsppower(dev);
1707 s2255_exit_v4l(dev);
1708 /* board shutdown stops the read pipe if it is running */ 1850 /* board shutdown stops the read pipe if it is running */
1709 s2255_board_shutdown(dev); 1851 s2255_board_shutdown(dev);
1710 /* make sure firmware still not trying to load */ 1852 /* make sure firmware still not trying to load */
1711 del_timer(&dev->timer); /* only started in .probe and .open */ 1853 del_timer(&dev->timer); /* only started in .probe and .open */
1712
1713 if (dev->fw_data->fw_urb) { 1854 if (dev->fw_data->fw_urb) {
1714 dprintk(2, "kill fw_urb\n");
1715 usb_kill_urb(dev->fw_data->fw_urb); 1855 usb_kill_urb(dev->fw_data->fw_urb);
1716 usb_free_urb(dev->fw_data->fw_urb); 1856 usb_free_urb(dev->fw_data->fw_urb);
1717 dev->fw_data->fw_urb = NULL; 1857 dev->fw_data->fw_urb = NULL;
@@ -1720,24 +1860,22 @@ static void s2255_destroy(struct kref *kref)
1720 release_firmware(dev->fw_data->fw); 1860 release_firmware(dev->fw_data->fw);
1721 kfree(dev->fw_data->pfw_data); 1861 kfree(dev->fw_data->pfw_data);
1722 kfree(dev->fw_data); 1862 kfree(dev->fw_data);
1863 /* reset the DSP so firmware can be reloaded next time */
1864 s2255_reset_dsppower(dev);
1865 mutex_destroy(&dev->open_lock);
1866 mutex_destroy(&dev->lock);
1723 usb_put_dev(dev->udev); 1867 usb_put_dev(dev->udev);
1724 dprintk(1, "%s", __func__); 1868 dprintk(1, "%s", __func__);
1725
1726 mutex_unlock(&dev->open_lock);
1727 kfree(dev); 1869 kfree(dev);
1728} 1870}
1729 1871
1730static int s2255_close(struct file *file) 1872static int s2255_release(struct file *file)
1731{ 1873{
1732 struct s2255_fh *fh = file->private_data; 1874 struct s2255_fh *fh = file->private_data;
1733 struct s2255_dev *dev = fh->dev; 1875 struct s2255_dev *dev = fh->dev;
1734 struct video_device *vdev = video_devdata(file); 1876 struct video_device *vdev = video_devdata(file);
1735
1736 if (!dev) 1877 if (!dev)
1737 return -ENODEV; 1878 return -ENODEV;
1738
1739 mutex_lock(&dev->open_lock);
1740
1741 /* turn off stream */ 1879 /* turn off stream */
1742 if (res_check(fh)) { 1880 if (res_check(fh)) {
1743 if (dev->b_acquire[fh->channel]) 1881 if (dev->b_acquire[fh->channel])
@@ -1745,15 +1883,8 @@ static int s2255_close(struct file *file)
1745 videobuf_streamoff(&fh->vb_vidq); 1883 videobuf_streamoff(&fh->vb_vidq);
1746 res_free(dev, fh); 1884 res_free(dev, fh);
1747 } 1885 }
1748
1749 videobuf_mmap_free(&fh->vb_vidq); 1886 videobuf_mmap_free(&fh->vb_vidq);
1750 dev->users[fh->channel]--; 1887 dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
1751
1752 mutex_unlock(&dev->open_lock);
1753
1754 kref_put(&dev->kref, s2255_destroy);
1755 dprintk(1, "s2255: close called (dev=%s, users=%d)\n",
1756 video_device_node_name(vdev), dev->users[fh->channel]);
1757 kfree(fh); 1888 kfree(fh);
1758 return 0; 1889 return 0;
1759} 1890}
@@ -1765,27 +1896,25 @@ static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
1765 1896
1766 if (!fh) 1897 if (!fh)
1767 return -ENODEV; 1898 return -ENODEV;
1768 dprintk(4, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 1899 dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
1769
1770 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); 1900 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1771 1901 dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
1772 dprintk(4, "vma start=0x%08lx, size=%ld, ret=%d\n",
1773 (unsigned long)vma->vm_start, 1902 (unsigned long)vma->vm_start,
1774 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); 1903 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
1775
1776 return ret; 1904 return ret;
1777} 1905}
1778 1906
1779static const struct v4l2_file_operations s2255_fops_v4l = { 1907static const struct v4l2_file_operations s2255_fops_v4l = {
1780 .owner = THIS_MODULE, 1908 .owner = THIS_MODULE,
1781 .open = s2255_open, 1909 .open = s2255_open,
1782 .release = s2255_close, 1910 .release = s2255_release,
1783 .poll = s2255_poll, 1911 .poll = s2255_poll,
1784 .ioctl = video_ioctl2, /* V4L2 ioctl handler */ 1912 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
1785 .mmap = s2255_mmap_v4l, 1913 .mmap = s2255_mmap_v4l,
1786}; 1914};
1787 1915
1788static const struct v4l2_ioctl_ops s2255_ioctl_ops = { 1916static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
1917 .vidioc_querymenu = vidioc_querymenu,
1789 .vidioc_querycap = vidioc_querycap, 1918 .vidioc_querycap = vidioc_querycap,
1790 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1919 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1791 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1920 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1811,13 +1940,23 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
1811 .vidioc_g_jpegcomp = vidioc_g_jpegcomp, 1940 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1812 .vidioc_s_parm = vidioc_s_parm, 1941 .vidioc_s_parm = vidioc_s_parm,
1813 .vidioc_g_parm = vidioc_g_parm, 1942 .vidioc_g_parm = vidioc_g_parm,
1943 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1814}; 1944};
1815 1945
1946static void s2255_video_device_release(struct video_device *vdev)
1947{
1948 struct s2255_dev *dev = video_get_drvdata(vdev);
1949 dprintk(4, "%s, chnls: %d \n", __func__, atomic_read(&dev->channels));
1950 if (atomic_dec_and_test(&dev->channels))
1951 s2255_destroy(dev);
1952 return;
1953}
1954
1816static struct video_device template = { 1955static struct video_device template = {
1817 .name = "s2255v", 1956 .name = "s2255v",
1818 .fops = &s2255_fops_v4l, 1957 .fops = &s2255_fops_v4l,
1819 .ioctl_ops = &s2255_ioctl_ops, 1958 .ioctl_ops = &s2255_ioctl_ops,
1820 .release = video_device_release, 1959 .release = s2255_video_device_release,
1821 .tvnorms = S2255_NORMS, 1960 .tvnorms = S2255_NORMS,
1822 .current_norm = V4L2_STD_NTSC_M, 1961 .current_norm = V4L2_STD_NTSC_M,
1823}; 1962};
@@ -1827,7 +1966,9 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
1827 int ret; 1966 int ret;
1828 int i; 1967 int i;
1829 int cur_nr = video_nr; 1968 int cur_nr = video_nr;
1830 1969 ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
1970 if (ret)
1971 return ret;
1831 /* initialize all video 4 linux */ 1972 /* initialize all video 4 linux */
1832 /* register 4 video devices */ 1973 /* register 4 video devices */
1833 for (i = 0; i < MAX_CHANNELS; i++) { 1974 for (i = 0; i < MAX_CHANNELS; i++) {
@@ -1835,45 +1976,39 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
1835 dev->vidq[i].dev = dev; 1976 dev->vidq[i].dev = dev;
1836 dev->vidq[i].channel = i; 1977 dev->vidq[i].channel = i;
1837 /* register 4 video devices */ 1978 /* register 4 video devices */
1838 dev->vdev[i] = video_device_alloc(); 1979 memcpy(&dev->vdev[i], &template, sizeof(struct video_device));
1839 memcpy(dev->vdev[i], &template, sizeof(struct video_device)); 1980 dev->vdev[i].v4l2_dev = &dev->v4l2_dev;
1840 dev->vdev[i]->parent = &dev->interface->dev; 1981 video_set_drvdata(&dev->vdev[i], dev);
1841 video_set_drvdata(dev->vdev[i], dev);
1842 if (video_nr == -1) 1982 if (video_nr == -1)
1843 ret = video_register_device(dev->vdev[i], 1983 ret = video_register_device(&dev->vdev[i],
1844 VFL_TYPE_GRABBER, 1984 VFL_TYPE_GRABBER,
1845 video_nr); 1985 video_nr);
1846 else 1986 else
1847 ret = video_register_device(dev->vdev[i], 1987 ret = video_register_device(&dev->vdev[i],
1848 VFL_TYPE_GRABBER, 1988 VFL_TYPE_GRABBER,
1849 cur_nr + i); 1989 cur_nr + i);
1850 video_set_drvdata(dev->vdev[i], dev); 1990 if (ret) {
1851
1852 if (ret != 0) {
1853 dev_err(&dev->udev->dev, 1991 dev_err(&dev->udev->dev,
1854 "failed to register video device!\n"); 1992 "failed to register video device!\n");
1855 return ret; 1993 break;
1856 } 1994 }
1995 atomic_inc(&dev->channels);
1996 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
1997 video_device_node_name(&dev->vdev[i]));
1998
1857 } 1999 }
2000
1858 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n", 2001 printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
1859 S2255_MAJOR_VERSION, 2002 S2255_MAJOR_VERSION,
1860 S2255_MINOR_VERSION); 2003 S2255_MINOR_VERSION);
1861 return ret; 2004 /* if no channels registered, return error and probe will fail*/
1862} 2005 if (atomic_read(&dev->channels) == 0) {
1863 2006 v4l2_device_unregister(&dev->v4l2_dev);
1864static void s2255_exit_v4l(struct s2255_dev *dev) 2007 return ret;
1865{
1866
1867 int i;
1868 for (i = 0; i < MAX_CHANNELS; i++) {
1869 if (video_is_registered(dev->vdev[i])) {
1870 video_unregister_device(dev->vdev[i]);
1871 printk(KERN_INFO "s2255 unregistered\n");
1872 } else {
1873 video_device_release(dev->vdev[i]);
1874 printk(KERN_INFO "s2255 released\n");
1875 }
1876 } 2008 }
2009 if (atomic_read(&dev->channels) != MAX_CHANNELS)
2010 printk(KERN_WARNING "s2255: Not all channels available.\n");
2011 return 0;
1877} 2012}
1878 2013
1879/* this function moves the usb stream read pipe data 2014/* this function moves the usb stream read pipe data
@@ -1907,14 +2042,14 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1907 if (frm->ulState == S2255_READ_IDLE) { 2042 if (frm->ulState == S2255_READ_IDLE) {
1908 int jj; 2043 int jj;
1909 unsigned int cc; 2044 unsigned int cc;
1910 s32 *pdword; 2045 __le32 *pdword; /*data from dsp is little endian */
1911 int payload; 2046 int payload;
1912 /* search for marker codes */ 2047 /* search for marker codes */
1913 pdata = (unsigned char *)pipe_info->transfer_buffer; 2048 pdata = (unsigned char *)pipe_info->transfer_buffer;
2049 pdword = (__le32 *)pdata;
1914 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { 2050 for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
1915 switch (*(s32 *) pdata) { 2051 switch (*pdword) {
1916 case S2255_MARKER_FRAME: 2052 case S2255_MARKER_FRAME:
1917 pdword = (s32 *)pdata;
1918 dprintk(4, "found frame marker at offset:" 2053 dprintk(4, "found frame marker at offset:"
1919 " %d [%x %x]\n", jj, pdata[0], 2054 " %d [%x %x]\n", jj, pdata[0],
1920 pdata[1]); 2055 pdata[1]);
@@ -1938,7 +2073,6 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1938 dev->jpg_size[dev->cc] = pdword[4]; 2073 dev->jpg_size[dev->cc] = pdword[4];
1939 break; 2074 break;
1940 case S2255_MARKER_RESPONSE: 2075 case S2255_MARKER_RESPONSE:
1941 pdword = (s32 *)pdata;
1942 pdata += DEF_USB_BLOCK; 2076 pdata += DEF_USB_BLOCK;
1943 jj += DEF_USB_BLOCK; 2077 jj += DEF_USB_BLOCK;
1944 if (pdword[1] >= MAX_CHANNELS) 2078 if (pdword[1] >= MAX_CHANNELS)
@@ -1955,7 +2089,6 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1955 dprintk(5, "setmode ready %d\n", cc); 2089 dprintk(5, "setmode ready %d\n", cc);
1956 break; 2090 break;
1957 case S2255_RESPONSE_FW: 2091 case S2255_RESPONSE_FW:
1958
1959 dev->chn_ready |= (1 << cc); 2092 dev->chn_ready |= (1 << cc);
1960 if ((dev->chn_ready & 0x0f) != 0x0f) 2093 if ((dev->chn_ready & 0x0f) != 0x0f)
1961 break; 2094 break;
@@ -1965,6 +2098,13 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
1965 S2255_FW_SUCCESS); 2098 S2255_FW_SUCCESS);
1966 wake_up(&dev->fw_data->wait_fw); 2099 wake_up(&dev->fw_data->wait_fw);
1967 break; 2100 break;
2101 case S2255_RESPONSE_STATUS:
2102 dev->vidstatus[cc] = pdword[3];
2103 dev->vidstatus_ready[cc] = 1;
2104 wake_up(&dev->wait_vidstatus[cc]);
2105 dprintk(5, "got vidstatus %x chan %d\n",
2106 pdword[3], cc);
2107 break;
1968 default: 2108 default:
1969 printk(KERN_INFO "s2255 unknown resp\n"); 2109 printk(KERN_INFO "s2255 unknown resp\n");
1970 } 2110 }
@@ -2165,28 +2305,22 @@ static int s2255_release_sys_buffers(struct s2255_dev *dev,
2165 2305
2166static int s2255_board_init(struct s2255_dev *dev) 2306static int s2255_board_init(struct s2255_dev *dev)
2167{ 2307{
2168 int j;
2169 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT; 2308 struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
2170 int fw_ver; 2309 int fw_ver;
2310 int j;
2311 struct s2255_pipeinfo *pipe = &dev->pipe;
2171 dprintk(4, "board init: %p", dev); 2312 dprintk(4, "board init: %p", dev);
2172 2313 memset(pipe, 0, sizeof(*pipe));
2173 for (j = 0; j < MAX_PIPE_BUFFERS; j++) { 2314 pipe->dev = dev;
2174 struct s2255_pipeinfo *pipe = &dev->pipes[j]; 2315 pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
2175 2316 pipe->max_transfer_size = S2255_USB_XFER_SIZE;
2176 memset(pipe, 0, sizeof(*pipe)); 2317
2177 pipe->dev = dev; 2318 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
2178 pipe->cur_transfer_size = S2255_USB_XFER_SIZE; 2319 GFP_KERNEL);
2179 pipe->max_transfer_size = S2255_USB_XFER_SIZE; 2320 if (pipe->transfer_buffer == NULL) {
2180 2321 dprintk(1, "out of memory!\n");
2181 pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, 2322 return -ENOMEM;
2182 GFP_KERNEL);
2183 if (pipe->transfer_buffer == NULL) {
2184 dprintk(1, "out of memory!\n");
2185 return -ENOMEM;
2186 }
2187
2188 } 2323 }
2189
2190 /* query the firmware */ 2324 /* query the firmware */
2191 fw_ver = s2255_get_fx2fw(dev); 2325 fw_ver = s2255_get_fx2fw(dev);
2192 2326
@@ -2203,6 +2337,8 @@ static int s2255_board_init(struct s2255_dev *dev)
2203 for (j = 0; j < MAX_CHANNELS; j++) { 2337 for (j = 0; j < MAX_CHANNELS; j++) {
2204 dev->b_acquire[j] = 0; 2338 dev->b_acquire[j] = 0;
2205 dev->mode[j] = mode_def; 2339 dev->mode[j] = mode_def;
2340 if (dev->pid == 0x2257 && j > 1)
2341 dev->mode[j].color |= (1 << 16);
2206 dev->jc[j].quality = S2255_DEF_JPEG_QUAL; 2342 dev->jc[j].quality = S2255_DEF_JPEG_QUAL;
2207 dev->cur_fmt[j] = &formats[0]; 2343 dev->cur_fmt[j] = &formats[0];
2208 dev->mode[j].restart = 1; 2344 dev->mode[j].restart = 1;
@@ -2213,16 +2349,14 @@ static int s2255_board_init(struct s2255_dev *dev)
2213 } 2349 }
2214 /* start read pipe */ 2350 /* start read pipe */
2215 s2255_start_readpipe(dev); 2351 s2255_start_readpipe(dev);
2216 2352 dprintk(1, "%s: success\n", __func__);
2217 dprintk(1, "S2255: board initialized\n");
2218 return 0; 2353 return 0;
2219} 2354}
2220 2355
2221static int s2255_board_shutdown(struct s2255_dev *dev) 2356static int s2255_board_shutdown(struct s2255_dev *dev)
2222{ 2357{
2223 u32 i; 2358 u32 i;
2224 2359 dprintk(1, "%s: dev: %p", __func__, dev);
2225 dprintk(1, "S2255: board shutdown: %p", dev);
2226 2360
2227 for (i = 0; i < MAX_CHANNELS; i++) { 2361 for (i = 0; i < MAX_CHANNELS; i++) {
2228 if (dev->b_acquire[i]) 2362 if (dev->b_acquire[i])
@@ -2233,12 +2367,8 @@ static int s2255_board_shutdown(struct s2255_dev *dev)
2233 2367
2234 for (i = 0; i < MAX_CHANNELS; i++) 2368 for (i = 0; i < MAX_CHANNELS; i++)
2235 s2255_release_sys_buffers(dev, i); 2369 s2255_release_sys_buffers(dev, i);
2236 2370 /* release transfer buffer */
2237 /* release transfer buffers */ 2371 kfree(dev->pipe.transfer_buffer);
2238 for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
2239 struct s2255_pipeinfo *pipe = &dev->pipes[i];
2240 kfree(pipe->transfer_buffer);
2241 }
2242 return 0; 2372 return 0;
2243} 2373}
2244 2374
@@ -2248,9 +2378,8 @@ static void read_pipe_completion(struct urb *purb)
2248 struct s2255_dev *dev; 2378 struct s2255_dev *dev;
2249 int status; 2379 int status;
2250 int pipe; 2380 int pipe;
2251
2252 pipe_info = purb->context; 2381 pipe_info = purb->context;
2253 dprintk(100, "read pipe completion %p, status %d\n", purb, 2382 dprintk(100, "%s: urb:%p, status %d\n", __func__, purb,
2254 purb->status); 2383 purb->status);
2255 if (pipe_info == NULL) { 2384 if (pipe_info == NULL) {
2256 dev_err(&purb->dev->dev, "no context!\n"); 2385 dev_err(&purb->dev->dev, "no context!\n");
@@ -2265,13 +2394,13 @@ static void read_pipe_completion(struct urb *purb)
2265 status = purb->status; 2394 status = purb->status;
2266 /* if shutting down, do not resubmit, exit immediately */ 2395 /* if shutting down, do not resubmit, exit immediately */
2267 if (status == -ESHUTDOWN) { 2396 if (status == -ESHUTDOWN) {
2268 dprintk(2, "read_pipe_completion: err shutdown\n"); 2397 dprintk(2, "%s: err shutdown\n", __func__);
2269 pipe_info->err_count++; 2398 pipe_info->err_count++;
2270 return; 2399 return;
2271 } 2400 }
2272 2401
2273 if (pipe_info->state == 0) { 2402 if (pipe_info->state == 0) {
2274 dprintk(2, "exiting USB pipe"); 2403 dprintk(2, "%s: exiting USB pipe", __func__);
2275 return; 2404 return;
2276 } 2405 }
2277 2406
@@ -2279,7 +2408,7 @@ static void read_pipe_completion(struct urb *purb)
2279 s2255_read_video_callback(dev, pipe_info); 2408 s2255_read_video_callback(dev, pipe_info);
2280 else { 2409 else {
2281 pipe_info->err_count++; 2410 pipe_info->err_count++;
2282 dprintk(1, "s2255drv: failed URB %d\n", status); 2411 dprintk(1, "%s: failed URB %d\n", __func__, status);
2283 } 2412 }
2284 2413
2285 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); 2414 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
@@ -2295,7 +2424,7 @@ static void read_pipe_completion(struct urb *purb)
2295 dev_err(&dev->udev->dev, "error submitting urb\n"); 2424 dev_err(&dev->udev->dev, "error submitting urb\n");
2296 } 2425 }
2297 } else { 2426 } else {
2298 dprintk(2, "read pipe complete state 0\n"); 2427 dprintk(2, "%s :complete state 0\n", __func__);
2299 } 2428 }
2300 return; 2429 return;
2301} 2430}
@@ -2304,35 +2433,28 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
2304{ 2433{
2305 int pipe; 2434 int pipe;
2306 int retval; 2435 int retval;
2307 int i; 2436 struct s2255_pipeinfo *pipe_info = &dev->pipe;
2308 struct s2255_pipeinfo *pipe_info = dev->pipes;
2309 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); 2437 pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
2310 dprintk(2, "start pipe IN %d\n", dev->read_endpoint); 2438 dprintk(2, "%s: IN %d\n", __func__, dev->read_endpoint);
2311 2439 pipe_info->state = 1;
2312 for (i = 0; i < MAX_PIPE_BUFFERS; i++) { 2440 pipe_info->err_count = 0;
2313 pipe_info->state = 1; 2441 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
2314 pipe_info->err_count = 0; 2442 if (!pipe_info->stream_urb) {
2315 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); 2443 dev_err(&dev->udev->dev,
2316 if (!pipe_info->stream_urb) { 2444 "ReadStream: Unable to alloc URB\n");
2317 dev_err(&dev->udev->dev, 2445 return -ENOMEM;
2318 "ReadStream: Unable to alloc URB\n"); 2446 }
2319 return -ENOMEM; 2447 /* transfer buffer allocated in board_init */
2320 } 2448 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
2321 /* transfer buffer allocated in board_init */ 2449 pipe,
2322 usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, 2450 pipe_info->transfer_buffer,
2323 pipe, 2451 pipe_info->cur_transfer_size,
2324 pipe_info->transfer_buffer, 2452 read_pipe_completion, pipe_info);
2325 pipe_info->cur_transfer_size, 2453 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2326 read_pipe_completion, pipe_info); 2454 if (retval) {
2327 2455 printk(KERN_ERR "s2255: start read pipe failed\n");
2328 dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); 2456 return retval;
2329 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
2330 if (retval) {
2331 printk(KERN_ERR "s2255: start read pipe failed\n");
2332 return retval;
2333 }
2334 } 2457 }
2335
2336 return 0; 2458 return 0;
2337} 2459}
2338 2460
@@ -2347,10 +2469,7 @@ static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
2347 dprintk(2, "start acquire failed, bad channel %lu\n", chn); 2469 dprintk(2, "start acquire failed, bad channel %lu\n", chn);
2348 return -1; 2470 return -1;
2349 } 2471 }
2350
2351 chn_rev = G_chnmap[chn]; 2472 chn_rev = G_chnmap[chn];
2352 dprintk(1, "S2255: start acquire %lu \n", chn);
2353
2354 buffer = kzalloc(512, GFP_KERNEL); 2473 buffer = kzalloc(512, GFP_KERNEL);
2355 if (buffer == NULL) { 2474 if (buffer == NULL) {
2356 dev_err(&dev->udev->dev, "out of mem\n"); 2475 dev_err(&dev->udev->dev, "out of mem\n");
@@ -2366,9 +2485,9 @@ static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
2366 } 2485 }
2367 2486
2368 /* send the start command */ 2487 /* send the start command */
2369 *(u32 *) buffer = IN_DATA_TOKEN; 2488 *(__le32 *) buffer = IN_DATA_TOKEN;
2370 *((u32 *) buffer + 1) = (u32) chn_rev; 2489 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2371 *((u32 *) buffer + 2) = (u32) CMD_START; 2490 *((__le32 *) buffer + 2) = CMD_START;
2372 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); 2491 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2373 if (res != 0) 2492 if (res != 0)
2374 dev_err(&dev->udev->dev, "CMD_START error\n"); 2493 dev_err(&dev->udev->dev, "CMD_START error\n");
@@ -2383,65 +2502,41 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
2383 unsigned char *buffer; 2502 unsigned char *buffer;
2384 int res; 2503 int res;
2385 unsigned long chn_rev; 2504 unsigned long chn_rev;
2386
2387 if (chn >= MAX_CHANNELS) { 2505 if (chn >= MAX_CHANNELS) {
2388 dprintk(2, "stop acquire failed, bad channel %lu\n", chn); 2506 dprintk(2, "stop acquire failed, bad channel %lu\n", chn);
2389 return -1; 2507 return -1;
2390 } 2508 }
2391 chn_rev = G_chnmap[chn]; 2509 chn_rev = G_chnmap[chn];
2392
2393 buffer = kzalloc(512, GFP_KERNEL); 2510 buffer = kzalloc(512, GFP_KERNEL);
2394 if (buffer == NULL) { 2511 if (buffer == NULL) {
2395 dev_err(&dev->udev->dev, "out of mem\n"); 2512 dev_err(&dev->udev->dev, "out of mem\n");
2396 return -ENOMEM; 2513 return -ENOMEM;
2397 } 2514 }
2398
2399 /* send the stop command */ 2515 /* send the stop command */
2400 dprintk(4, "stop acquire %lu\n", chn); 2516 *(__le32 *) buffer = IN_DATA_TOKEN;
2401 *(u32 *) buffer = IN_DATA_TOKEN; 2517 *((__le32 *) buffer + 1) = (__le32) cpu_to_le32(chn_rev);
2402 *((u32 *) buffer + 1) = (u32) chn_rev; 2518 *((__le32 *) buffer + 2) = CMD_STOP;
2403 *((u32 *) buffer + 2) = CMD_STOP;
2404 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); 2519 res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
2405
2406 if (res != 0) 2520 if (res != 0)
2407 dev_err(&dev->udev->dev, "CMD_STOP error\n"); 2521 dev_err(&dev->udev->dev, "CMD_STOP error\n");
2408
2409 dprintk(4, "stop acquire: releasing states \n");
2410
2411 kfree(buffer); 2522 kfree(buffer);
2412 dev->b_acquire[chn] = 0; 2523 dev->b_acquire[chn] = 0;
2413 2524 dprintk(4, "%s: chn %lu, res %d\n", __func__, chn, res);
2414 return res; 2525 return res;
2415} 2526}
2416 2527
2417static void s2255_stop_readpipe(struct s2255_dev *dev) 2528static void s2255_stop_readpipe(struct s2255_dev *dev)
2418{ 2529{
2419 int j; 2530 struct s2255_pipeinfo *pipe = &dev->pipe;
2420
2421 if (dev == NULL) {
2422 s2255_dev_err(&dev->udev->dev, "invalid device\n");
2423 return;
2424 }
2425 dprintk(4, "stop read pipe\n");
2426 for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
2427 struct s2255_pipeinfo *pipe_info = &dev->pipes[j];
2428 if (pipe_info) {
2429 if (pipe_info->state == 0)
2430 continue;
2431 pipe_info->state = 0;
2432 }
2433 }
2434 2531
2435 for (j = 0; j < MAX_PIPE_BUFFERS; j++) { 2532 pipe->state = 0;
2436 struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; 2533 if (pipe->stream_urb) {
2437 if (pipe_info->stream_urb) { 2534 /* cancel urb */
2438 /* cancel urb */ 2535 usb_kill_urb(pipe->stream_urb);
2439 usb_kill_urb(pipe_info->stream_urb); 2536 usb_free_urb(pipe->stream_urb);
2440 usb_free_urb(pipe_info->stream_urb); 2537 pipe->stream_urb = NULL;
2441 pipe_info->stream_urb = NULL;
2442 }
2443 } 2538 }
2444 dprintk(2, "s2255 stop read pipe: %d\n", j); 2539 dprintk(4, "%s", __func__);
2445 return; 2540 return;
2446} 2541}
2447 2542
@@ -2473,32 +2568,28 @@ static int s2255_probe(struct usb_interface *interface,
2473 int retval = -ENOMEM; 2568 int retval = -ENOMEM;
2474 __le32 *pdata; 2569 __le32 *pdata;
2475 int fw_size; 2570 int fw_size;
2476 2571 dprintk(2, "%s\n", __func__);
2477 dprintk(2, "s2255: probe\n");
2478
2479 /* allocate memory for our device state and initialize it to zero */ 2572 /* allocate memory for our device state and initialize it to zero */
2480 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); 2573 dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
2481 if (dev == NULL) { 2574 if (dev == NULL) {
2482 s2255_dev_err(&interface->dev, "out of memory\n"); 2575 s2255_dev_err(&interface->dev, "out of memory\n");
2483 goto error; 2576 return -ENOMEM;
2484 } 2577 }
2485 2578 atomic_set(&dev->channels, 0);
2579 dev->pid = id->idProduct;
2486 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); 2580 dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
2487 if (!dev->fw_data) 2581 if (!dev->fw_data)
2488 goto error; 2582 goto errorFWDATA1;
2489
2490 mutex_init(&dev->lock); 2583 mutex_init(&dev->lock);
2491 mutex_init(&dev->open_lock); 2584 mutex_init(&dev->open_lock);
2492
2493 /* grab usb_device and save it */ 2585 /* grab usb_device and save it */
2494 dev->udev = usb_get_dev(interface_to_usbdev(interface)); 2586 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2495 if (dev->udev == NULL) { 2587 if (dev->udev == NULL) {
2496 dev_err(&interface->dev, "null usb device\n"); 2588 dev_err(&interface->dev, "null usb device\n");
2497 retval = -ENODEV; 2589 retval = -ENODEV;
2498 goto error; 2590 goto errorUDEV;
2499 } 2591 }
2500 kref_init(&dev->kref); 2592 dprintk(1, "dev: %p, udev %p interface %p\n", dev,
2501 dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref,
2502 dev->udev, interface); 2593 dev->udev, interface);
2503 dev->interface = interface; 2594 dev->interface = interface;
2504 /* set up the endpoint information */ 2595 /* set up the endpoint information */
@@ -2514,39 +2605,33 @@ static int s2255_probe(struct usb_interface *interface,
2514 2605
2515 if (!dev->read_endpoint) { 2606 if (!dev->read_endpoint) {
2516 dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); 2607 dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
2517 goto error; 2608 goto errorEP;
2518 } 2609 }
2519
2520 /* set intfdata */
2521 usb_set_intfdata(interface, dev);
2522
2523 dprintk(100, "after intfdata %p\n", dev);
2524
2525 init_timer(&dev->timer); 2610 init_timer(&dev->timer);
2526 dev->timer.function = s2255_timer; 2611 dev->timer.function = s2255_timer;
2527 dev->timer.data = (unsigned long)dev->fw_data; 2612 dev->timer.data = (unsigned long)dev->fw_data;
2528
2529 init_waitqueue_head(&dev->fw_data->wait_fw); 2613 init_waitqueue_head(&dev->fw_data->wait_fw);
2530 for (i = 0; i < MAX_CHANNELS; i++) 2614 for (i = 0; i < MAX_CHANNELS; i++) {
2531 init_waitqueue_head(&dev->wait_setmode[i]); 2615 init_waitqueue_head(&dev->wait_setmode[i]);
2532 2616 init_waitqueue_head(&dev->wait_vidstatus[i]);
2617 }
2533 2618
2534 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); 2619 dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
2535
2536 if (!dev->fw_data->fw_urb) { 2620 if (!dev->fw_data->fw_urb) {
2537 dev_err(&interface->dev, "out of memory!\n"); 2621 dev_err(&interface->dev, "out of memory!\n");
2538 goto error; 2622 goto errorFWURB;
2539 } 2623 }
2624
2540 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); 2625 dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
2541 if (!dev->fw_data->pfw_data) { 2626 if (!dev->fw_data->pfw_data) {
2542 dev_err(&interface->dev, "out of memory!\n"); 2627 dev_err(&interface->dev, "out of memory!\n");
2543 goto error; 2628 goto errorFWDATA2;
2544 } 2629 }
2545 /* load the first chunk */ 2630 /* load the first chunk */
2546 if (request_firmware(&dev->fw_data->fw, 2631 if (request_firmware(&dev->fw_data->fw,
2547 FIRMWARE_FILE_NAME, &dev->udev->dev)) { 2632 FIRMWARE_FILE_NAME, &dev->udev->dev)) {
2548 printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); 2633 printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
2549 goto error; 2634 goto errorREQFW;
2550 } 2635 }
2551 /* check the firmware is valid */ 2636 /* check the firmware is valid */
2552 fw_size = dev->fw_data->fw->size; 2637 fw_size = dev->fw_data->fw->size;
@@ -2555,59 +2640,80 @@ static int s2255_probe(struct usb_interface *interface,
2555 if (*pdata != S2255_FW_MARKER) { 2640 if (*pdata != S2255_FW_MARKER) {
2556 printk(KERN_INFO "Firmware invalid.\n"); 2641 printk(KERN_INFO "Firmware invalid.\n");
2557 retval = -ENODEV; 2642 retval = -ENODEV;
2558 goto error; 2643 goto errorFWMARKER;
2559 } else { 2644 } else {
2560 /* make sure firmware is the latest */ 2645 /* make sure firmware is the latest */
2561 __le32 *pRel; 2646 __le32 *pRel;
2562 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; 2647 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2563 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); 2648 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
2649 dev->dsp_fw_ver = *pRel;
2650 if (*pRel < S2255_CUR_DSP_FWVER)
2651 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
2652 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
2653 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
2654 "or above.\n", S2255_MIN_DSP_COLORFILTER);
2564 } 2655 }
2565 /* loads v4l specific */
2566 s2255_probe_v4l(dev);
2567 usb_reset_device(dev->udev); 2656 usb_reset_device(dev->udev);
2568 /* load 2255 board specific */ 2657 /* load 2255 board specific */
2569 retval = s2255_board_init(dev); 2658 retval = s2255_board_init(dev);
2570 if (retval) 2659 if (retval)
2571 goto error; 2660 goto errorBOARDINIT;
2572
2573 dprintk(4, "before probe done %p\n", dev);
2574 spin_lock_init(&dev->slock); 2661 spin_lock_init(&dev->slock);
2575
2576 s2255_fwload_start(dev, 0); 2662 s2255_fwload_start(dev, 0);
2663 /* loads v4l specific */
2664 retval = s2255_probe_v4l(dev);
2665 if (retval)
2666 goto errorBOARDINIT;
2577 dev_info(&interface->dev, "Sensoray 2255 detected\n"); 2667 dev_info(&interface->dev, "Sensoray 2255 detected\n");
2578 return 0; 2668 return 0;
2579error: 2669errorBOARDINIT:
2670 s2255_board_shutdown(dev);
2671errorFWMARKER:
2672 release_firmware(dev->fw_data->fw);
2673errorREQFW:
2674 kfree(dev->fw_data->pfw_data);
2675errorFWDATA2:
2676 usb_free_urb(dev->fw_data->fw_urb);
2677errorFWURB:
2678 del_timer(&dev->timer);
2679errorEP:
2680 usb_put_dev(dev->udev);
2681errorUDEV:
2682 kfree(dev->fw_data);
2683 mutex_destroy(&dev->open_lock);
2684 mutex_destroy(&dev->lock);
2685errorFWDATA1:
2686 kfree(dev);
2687 printk(KERN_WARNING "Sensoray 2255 driver load failed: 0x%x\n", retval);
2580 return retval; 2688 return retval;
2581} 2689}
2582 2690
2583/* disconnect routine. when board is removed physically or with rmmod */ 2691/* disconnect routine. when board is removed physically or with rmmod */
2584static void s2255_disconnect(struct usb_interface *interface) 2692static void s2255_disconnect(struct usb_interface *interface)
2585{ 2693{
2586 struct s2255_dev *dev = NULL; 2694 struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
2587 int i; 2695 int i;
2588 dprintk(1, "s2255: disconnect interface %p\n", interface); 2696 int channels = atomic_read(&dev->channels);
2589 dev = usb_get_intfdata(interface); 2697 v4l2_device_unregister(&dev->v4l2_dev);
2590 2698 /*see comments in the uvc_driver.c usb disconnect function */
2591 /* 2699 atomic_inc(&dev->channels);
2592 * wake up any of the timers to allow open_lock to be 2700 /* unregister each video device. */
2593 * acquired sooner 2701 for (i = 0; i < channels; i++) {
2594 */ 2702 if (video_is_registered(&dev->vdev[i]))
2703 video_unregister_device(&dev->vdev[i]);
2704 }
2705 /* wake up any of our timers */
2595 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); 2706 atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
2596 wake_up(&dev->fw_data->wait_fw); 2707 wake_up(&dev->fw_data->wait_fw);
2597 for (i = 0; i < MAX_CHANNELS; i++) { 2708 for (i = 0; i < MAX_CHANNELS; i++) {
2598 dev->setmode_ready[i] = 1; 2709 dev->setmode_ready[i] = 1;
2599 wake_up(&dev->wait_setmode[i]); 2710 wake_up(&dev->wait_setmode[i]);
2711 dev->vidstatus_ready[i] = 1;
2712 wake_up(&dev->wait_vidstatus[i]);
2600 } 2713 }
2601 2714 if (atomic_dec_and_test(&dev->channels))
2602 mutex_lock(&dev->open_lock); 2715 s2255_destroy(dev);
2603 usb_set_intfdata(interface, NULL); 2716 dev_info(&interface->dev, "%s\n", __func__);
2604 mutex_unlock(&dev->open_lock);
2605
2606 if (dev) {
2607 kref_put(&dev->kref, s2255_destroy);
2608 dprintk(1, "s2255drv: disconnect\n");
2609 dev_info(&interface->dev, "s2255usb now disconnected\n");
2610 }
2611} 2717}
2612 2718
2613static struct usb_driver s2255_driver = { 2719static struct usb_driver s2255_driver = {
@@ -2620,15 +2726,12 @@ static struct usb_driver s2255_driver = {
2620static int __init usb_s2255_init(void) 2726static int __init usb_s2255_init(void)
2621{ 2727{
2622 int result; 2728 int result;
2623
2624 /* register this driver with the USB subsystem */ 2729 /* register this driver with the USB subsystem */
2625 result = usb_register(&s2255_driver); 2730 result = usb_register(&s2255_driver);
2626
2627 if (result) 2731 if (result)
2628 pr_err(KBUILD_MODNAME 2732 pr_err(KBUILD_MODNAME
2629 ": usb_register failed. Error number %d\n", result); 2733 ": usb_register failed. Error number %d\n", result);
2630 2734 dprintk(2, "%s\n", __func__);
2631 dprintk(2, "s2255_init: done\n");
2632 return result; 2735 return result;
2633} 2736}
2634 2737
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index c0a7f8a369f4..53b6fcde3800 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -74,6 +74,7 @@ struct saa711x_state {
74 int contrast; 74 int contrast;
75 int hue; 75 int hue;
76 int sat; 76 int sat;
77 int chroma_agc;
77 int width; 78 int width;
78 int height; 79 int height;
79 u32 ident; 80 u32 ident;
@@ -592,7 +593,7 @@ static const unsigned char saa7115_init_misc[] = {
592 R_5D_DID, 0xbd, 593 R_5D_DID, 0xbd,
593 R_5E_SDID, 0x35, 594 R_5E_SDID, 0x35,
594 595
595 R_02_INPUT_CNTL_1, 0x84, /* input tuner -> input 4, amplifier active */ 596 R_02_INPUT_CNTL_1, 0xc4, /* input tuner -> input 4, amplifier active */
596 597
597 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */ 598 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
598 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, 599 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
@@ -743,6 +744,7 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
743static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 744static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
744{ 745{
745 struct saa711x_state *state = to_state(sd); 746 struct saa711x_state *state = to_state(sd);
747 u8 val;
746 748
747 switch (ctrl->id) { 749 switch (ctrl->id) {
748 case V4L2_CID_BRIGHTNESS: 750 case V4L2_CID_BRIGHTNESS:
@@ -784,7 +786,21 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
784 state->hue = ctrl->value; 786 state->hue = ctrl->value;
785 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue); 787 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue);
786 break; 788 break;
787 789 case V4L2_CID_CHROMA_AGC:
790 val = saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL);
791 state->chroma_agc = ctrl->value;
792 if (ctrl->value)
793 val &= 0x7f;
794 else
795 val |= 0x80;
796 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, val);
797 break;
798 case V4L2_CID_CHROMA_GAIN:
799 /* Chroma gain cannot be set when AGC is enabled */
800 if (state->chroma_agc == 1)
801 return -EINVAL;
802 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, ctrl->value | 0x80);
803 break;
788 default: 804 default:
789 return -EINVAL; 805 return -EINVAL;
790 } 806 }
@@ -809,6 +825,12 @@ static int saa711x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
809 case V4L2_CID_HUE: 825 case V4L2_CID_HUE:
810 ctrl->value = state->hue; 826 ctrl->value = state->hue;
811 break; 827 break;
828 case V4L2_CID_CHROMA_AGC:
829 ctrl->value = state->chroma_agc;
830 break;
831 case V4L2_CID_CHROMA_GAIN:
832 ctrl->value = saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
833 break;
812 default: 834 default:
813 return -EINVAL; 835 return -EINVAL;
814 } 836 }
@@ -1069,7 +1091,7 @@ static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_forma
1069 saa7115_cfg_vbi_off); 1091 saa7115_cfg_vbi_off);
1070} 1092}
1071 1093
1072static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1094static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
1073{ 1095{
1074 static u16 lcr2vbi[] = { 1096 static u16 lcr2vbi[] = {
1075 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 1097 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
@@ -1078,11 +1100,8 @@ static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1078 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ 1100 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
1079 0, 0, 0, 0 1101 0, 0, 0, 0
1080 }; 1102 };
1081 struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
1082 int i; 1103 int i;
1083 1104
1084 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1085 return -EINVAL;
1086 memset(sliced, 0, sizeof(*sliced)); 1105 memset(sliced, 0, sizeof(*sliced));
1087 /* done if using raw VBI */ 1106 /* done if using raw VBI */
1088 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10) 1107 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
@@ -1098,16 +1117,27 @@ static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1098 return 0; 1117 return 0;
1099} 1118}
1100 1119
1120static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1121{
1122 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
1123 return -EINVAL;
1124 return saa711x_g_sliced_fmt(sd, &fmt->fmt.sliced);
1125}
1126
1127static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
1128{
1129 saa711x_set_lcr(sd, NULL);
1130 return 0;
1131}
1132
1133static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1134{
1135 saa711x_set_lcr(sd, fmt);
1136 return 0;
1137}
1138
1101static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 1139static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1102{ 1140{
1103 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1104 saa711x_set_lcr(sd, &fmt->fmt.sliced);
1105 return 0;
1106 }
1107 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1108 saa711x_set_lcr(sd, NULL);
1109 return 0;
1110 }
1111 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1141 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1112 return -EINVAL; 1142 return -EINVAL;
1113 1143
@@ -1209,6 +1239,10 @@ static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1209 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); 1239 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
1210 case V4L2_CID_HUE: 1240 case V4L2_CID_HUE:
1211 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); 1241 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
1242 case V4L2_CID_CHROMA_AGC:
1243 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1244 case V4L2_CID_CHROMA_GAIN:
1245 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 48);
1212 default: 1246 default:
1213 return -EINVAL; 1247 return -EINVAL;
1214 } 1248 }
@@ -1524,18 +1558,25 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1524 .s_crystal_freq = saa711x_s_crystal_freq, 1558 .s_crystal_freq = saa711x_s_crystal_freq,
1525 .g_fmt = saa711x_g_fmt, 1559 .g_fmt = saa711x_g_fmt,
1526 .s_fmt = saa711x_s_fmt, 1560 .s_fmt = saa711x_s_fmt,
1527 .g_vbi_data = saa711x_g_vbi_data,
1528 .decode_vbi_line = saa711x_decode_vbi_line,
1529 .s_stream = saa711x_s_stream, 1561 .s_stream = saa711x_s_stream,
1530 .querystd = saa711x_querystd, 1562 .querystd = saa711x_querystd,
1531 .g_input_status = saa711x_g_input_status, 1563 .g_input_status = saa711x_g_input_status,
1532}; 1564};
1533 1565
1566static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
1567 .g_vbi_data = saa711x_g_vbi_data,
1568 .decode_vbi_line = saa711x_decode_vbi_line,
1569 .g_sliced_fmt = saa711x_g_sliced_fmt,
1570 .s_sliced_fmt = saa711x_s_sliced_fmt,
1571 .s_raw_fmt = saa711x_s_raw_fmt,
1572};
1573
1534static const struct v4l2_subdev_ops saa711x_ops = { 1574static const struct v4l2_subdev_ops saa711x_ops = {
1535 .core = &saa711x_core_ops, 1575 .core = &saa711x_core_ops,
1536 .tuner = &saa711x_tuner_ops, 1576 .tuner = &saa711x_tuner_ops,
1537 .audio = &saa711x_audio_ops, 1577 .audio = &saa711x_audio_ops,
1538 .video = &saa711x_video_ops, 1578 .video = &saa711x_video_ops,
1579 .vbi = &saa711x_vbi_ops,
1539}; 1580};
1540 1581
1541/* ----------------------------------------------------------------------- */ 1582/* ----------------------------------------------------------------------- */
@@ -1593,6 +1634,7 @@ static int saa711x_probe(struct i2c_client *client,
1593 state->contrast = 64; 1634 state->contrast = 64;
1594 state->hue = 0; 1635 state->hue = 0;
1595 state->sat = 64; 1636 state->sat = 64;
1637 state->chroma_agc = 1;
1596 switch (chip_id) { 1638 switch (chip_id) {
1597 case '1': 1639 case '1':
1598 state->ident = V4L2_IDENT_SAA7111; 1640 state->ident = V4L2_IDENT_SAA7111;
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 250ef84cf5ca..87986ad62f86 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -625,29 +625,33 @@ static int saa7127_s_stream(struct v4l2_subdev *sd, int enable)
625 return saa7127_set_video_enable(sd, enable); 625 return saa7127_set_video_enable(sd, enable);
626} 626}
627 627
628static int saa7127_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 628static int saa7127_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
629{ 629{
630 struct saa7127_state *state = to_state(sd); 630 struct saa7127_state *state = to_state(sd);
631 631
632 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) 632 memset(fmt, 0, sizeof(*fmt));
633 return -EINVAL;
634
635 memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
636 if (state->vps_enable) 633 if (state->vps_enable)
637 fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS; 634 fmt->service_lines[0][16] = V4L2_SLICED_VPS;
638 if (state->wss_enable) 635 if (state->wss_enable)
639 fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; 636 fmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
640 if (state->cc_enable) { 637 if (state->cc_enable) {
641 fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525; 638 fmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
642 fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525; 639 fmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
643 } 640 }
644 fmt->fmt.sliced.service_set = 641 fmt->service_set =
645 (state->vps_enable ? V4L2_SLICED_VPS : 0) | 642 (state->vps_enable ? V4L2_SLICED_VPS : 0) |
646 (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) | 643 (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
647 (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0); 644 (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
648 return 0; 645 return 0;
649} 646}
650 647
648static int saa7127_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
649{
650 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
651 return -EINVAL;
652 return saa7127_g_sliced_fmt(sd, &fmt->fmt.sliced);
653}
654
651static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data) 655static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data)
652{ 656{
653 switch (data->id) { 657 switch (data->id) {
@@ -727,16 +731,21 @@ static const struct v4l2_subdev_core_ops saa7127_core_ops = {
727}; 731};
728 732
729static const struct v4l2_subdev_video_ops saa7127_video_ops = { 733static const struct v4l2_subdev_video_ops saa7127_video_ops = {
730 .s_vbi_data = saa7127_s_vbi_data,
731 .g_fmt = saa7127_g_fmt, 734 .g_fmt = saa7127_g_fmt,
732 .s_std_output = saa7127_s_std_output, 735 .s_std_output = saa7127_s_std_output,
733 .s_routing = saa7127_s_routing, 736 .s_routing = saa7127_s_routing,
734 .s_stream = saa7127_s_stream, 737 .s_stream = saa7127_s_stream,
735}; 738};
736 739
740static const struct v4l2_subdev_vbi_ops saa7127_vbi_ops = {
741 .s_vbi_data = saa7127_s_vbi_data,
742 .g_sliced_fmt = saa7127_g_sliced_fmt,
743};
744
737static const struct v4l2_subdev_ops saa7127_ops = { 745static const struct v4l2_subdev_ops saa7127_ops = {
738 .core = &saa7127_core_ops, 746 .core = &saa7127_core_ops,
739 .video = &saa7127_video_ops, 747 .video = &saa7127_video_ops,
748 .vbi = &saa7127_vbi_ops,
740}; 749};
741 750
742/* ----------------------------------------------------------------------- */ 751/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index d48c450ed77c..d3bd82ad010a 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -1011,8 +1011,6 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
1011 unsigned int idx; 1011 unsigned int idx;
1012 int err, addr; 1012 int err, addr;
1013 1013
1014 if (snd_BUG_ON(!chip))
1015 return -EINVAL;
1016 strcpy(card->mixername, "SAA7134 Mixer"); 1014 strcpy(card->mixername, "SAA7134 Mixer");
1017 1015
1018 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) { 1016 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 297833fb3b4a..72700d4e3941 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5355,6 +5355,79 @@ struct saa7134_board saa7134_boards[] = {
5355 .amux = LINE2, 5355 .amux = LINE2,
5356 }, 5356 },
5357 }, 5357 },
5358 [SAA7134_BOARD_HAWELL_HW_404M7] = {
5359 /* Hawell HW-404M7 & Hawell HW-808M7 */
5360 /* Bogoslovskiy Viktor <bogovic@bk.ru> */
5361 .name = "Hawell HW-404M7",
5362 .audio_clock = 0x00200000,
5363 .tuner_type = UNSET,
5364 .radio_type = UNSET,
5365 .tuner_addr = ADDR_UNSET,
5366 .radio_addr = ADDR_UNSET,
5367 .gpiomask = 0x389c00,
5368 .inputs = {{
5369 .name = name_comp1,
5370 .vmux = 3,
5371 .amux = LINE1,
5372 .gpio = 0x01fc00,
5373 } },
5374 },
5375 [SAA7134_BOARD_BEHOLD_H7] = {
5376 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
5377 .name = "Beholder BeholdTV H7",
5378 .audio_clock = 0x00187de7,
5379 .tuner_type = TUNER_XC5000,
5380 .radio_type = UNSET,
5381 .tuner_addr = ADDR_UNSET,
5382 .radio_addr = ADDR_UNSET,
5383 .mpeg = SAA7134_MPEG_DVB,
5384 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5385 .inputs = { {
5386 .name = name_tv,
5387 .vmux = 2,
5388 .amux = TV,
5389 .tv = 1,
5390 }, {
5391 .name = name_comp1,
5392 .vmux = 0,
5393 .amux = LINE1,
5394 }, {
5395 .name = name_svideo,
5396 .vmux = 9,
5397 .amux = LINE1,
5398 } },
5399 .radio = {
5400 .name = name_radio,
5401 .amux = TV,
5402 },
5403 },
5404 [SAA7134_BOARD_BEHOLD_A7] = {
5405 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
5406 .name = "Beholder BeholdTV A7",
5407 .audio_clock = 0x00187de7,
5408 .tuner_type = TUNER_XC5000,
5409 .radio_type = UNSET,
5410 .tuner_addr = ADDR_UNSET,
5411 .radio_addr = ADDR_UNSET,
5412 .inputs = { {
5413 .name = name_tv,
5414 .vmux = 2,
5415 .amux = TV,
5416 .tv = 1,
5417 }, {
5418 .name = name_comp1,
5419 .vmux = 0,
5420 .amux = LINE1,
5421 }, {
5422 .name = name_svideo,
5423 .vmux = 9,
5424 .amux = LINE1,
5425 } },
5426 .radio = {
5427 .name = name_radio,
5428 .amux = TV,
5429 },
5430 },
5358 5431
5359}; 5432};
5360 5433
@@ -6549,6 +6622,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
6549 .subvendor = PCI_ANY_ID, 6622 .subvendor = PCI_ANY_ID,
6550 .subdevice = PCI_ANY_ID, 6623 .subdevice = PCI_ANY_ID,
6551 .driver_data = SAA7134_BOARD_UNKNOWN, 6624 .driver_data = SAA7134_BOARD_UNKNOWN,
6625 }, {
6626 .vendor = PCI_VENDOR_ID_PHILIPS,
6627 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6628 .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
6629 .subdevice = 0x7190,
6630 .driver_data = SAA7134_BOARD_BEHOLD_H7,
6631 }, {
6632 .vendor = PCI_VENDOR_ID_PHILIPS,
6633 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6634 .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
6635 .subdevice = 0x7090,
6636 .driver_data = SAA7134_BOARD_BEHOLD_A7,
6552 },{ 6637 },{
6553 /* --- end of list --- */ 6638 /* --- end of list --- */
6554 } 6639 }
@@ -6602,6 +6687,8 @@ static int saa7134_xc5000_callback(struct saa7134_dev *dev,
6602{ 6687{
6603 switch (dev->board) { 6688 switch (dev->board) {
6604 case SAA7134_BOARD_BEHOLD_X7: 6689 case SAA7134_BOARD_BEHOLD_X7:
6690 case SAA7134_BOARD_BEHOLD_H7:
6691 case SAA7134_BOARD_BEHOLD_A7:
6605 if (command == XC5000_TUNER_RESET) { 6692 if (command == XC5000_TUNER_RESET) {
6606 /* Down and UP pheripherial RESET pin for reset all chips */ 6693 /* Down and UP pheripherial RESET pin for reset all chips */
6607 saa_writeb(SAA7134_SPECIAL_MODE, 0x00); 6694 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
@@ -6973,6 +7060,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6973 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 7060 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
6974 case SAA7134_BOARD_BEHOLD_H6: 7061 case SAA7134_BOARD_BEHOLD_H6:
6975 case SAA7134_BOARD_BEHOLD_X7: 7062 case SAA7134_BOARD_BEHOLD_X7:
7063 case SAA7134_BOARD_BEHOLD_H7:
7064 case SAA7134_BOARD_BEHOLD_A7:
6976 dev->has_remote = SAA7134_REMOTE_I2C; 7065 dev->has_remote = SAA7134_REMOTE_I2C;
6977 break; 7066 break;
6978 case SAA7134_BOARD_AVERMEDIA_A169_B: 7067 case SAA7134_BOARD_AVERMEDIA_A169_B:
@@ -7215,6 +7304,11 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7215 printk(KERN_INFO "%s: P7131 analog only, using " 7304 printk(KERN_INFO "%s: P7131 analog only, using "
7216 "entry of %s\n", 7305 "entry of %s\n",
7217 dev->name, saa7134_boards[dev->board].name); 7306 dev->name, saa7134_boards[dev->board].name);
7307
7308 /* IR init has already happened for other cards, so
7309 * we have to catch up. */
7310 dev->has_remote = SAA7134_REMOTE_GPIO;
7311 saa7134_input_init1(dev);
7218 } 7312 }
7219 break; 7313 break;
7220 case SAA7134_BOARD_HAUPPAUGE_HVR1150: 7314 case SAA7134_BOARD_HAUPPAUGE_HVR1150:
@@ -7344,6 +7438,23 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7344 } 7438 }
7345 break; 7439 break;
7346 } 7440 }
7441 case SAA7134_BOARD_BEHOLD_H6:
7442 {
7443 u8 data[] = { 0x09, 0x9f, 0x86, 0x11};
7444 struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = data,
7445 .len = sizeof(data)};
7446
7447 /* The tuner TUNER_PHILIPS_FMD1216MEX_MK3 after hardware */
7448 /* start has disabled IF and enabled DVB-T. When saa7134 */
7449 /* scan I2C devices it not detect IF tda9887 and can`t */
7450 /* watch TV without software reboot. For solve this problem */
7451 /* switch the tuner to analog TV mode manually. */
7452 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
7453 printk(KERN_WARNING
7454 "%s: Unable to enable IF of the tuner.\n",
7455 dev->name);
7456 break;
7457 }
7347 } /* switch() */ 7458 } /* switch() */
7348 7459
7349 /* initialize tuner */ 7460 /* initialize tuner */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index a7ad7810fddc..90f231881297 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -471,7 +471,7 @@ static char *irqbits[] = {
471 "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3", 471 "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
472 "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC", 472 "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
473 "TRIG_ERR", "CONF_ERR", "LOAD_ERR", 473 "TRIG_ERR", "CONF_ERR", "LOAD_ERR",
474 "GPIO16?", "GPIO18", "GPIO22", "GPIO23" 474 "GPIO16", "GPIO18", "GPIO22", "GPIO23"
475}; 475};
476#define IRQBITS ARRAY_SIZE(irqbits) 476#define IRQBITS ARRAY_SIZE(irqbits)
477 477
@@ -601,12 +601,14 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
601 /* disable gpio16 IRQ */ 601 /* disable gpio16 IRQ */
602 printk(KERN_WARNING "%s/irq: looping -- " 602 printk(KERN_WARNING "%s/irq: looping -- "
603 "clearing GPIO16 enable bit\n",dev->name); 603 "clearing GPIO16 enable bit\n",dev->name);
604 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16); 604 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_P);
605 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16_N);
605 } else if (report & SAA7134_IRQ_REPORT_GPIO18) { 606 } else if (report & SAA7134_IRQ_REPORT_GPIO18) {
606 /* disable gpio18 IRQs */ 607 /* disable gpio18 IRQs */
607 printk(KERN_WARNING "%s/irq: looping -- " 608 printk(KERN_WARNING "%s/irq: looping -- "
608 "clearing GPIO18 enable bit\n",dev->name); 609 "clearing GPIO18 enable bit\n",dev->name);
609 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); 610 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
611 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_N);
610 } else { 612 } else {
611 /* disable all irqs */ 613 /* disable all irqs */
612 printk(KERN_WARNING "%s/irq: looping -- " 614 printk(KERN_WARNING "%s/irq: looping -- "
@@ -698,11 +700,13 @@ static int saa7134_hw_enable2(struct saa7134_dev *dev)
698 700
699 if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) { 701 if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) {
700 if (dev->remote->mask_keydown & 0x10000) 702 if (dev->remote->mask_keydown & 0x10000)
701 irq2_mask |= SAA7134_IRQ2_INTE_GPIO16; 703 irq2_mask |= SAA7134_IRQ2_INTE_GPIO16_N;
702 else if (dev->remote->mask_keydown & 0x40000) 704 else { /* Allow enabling both IRQ edge triggers */
703 irq2_mask |= SAA7134_IRQ2_INTE_GPIO18; 705 if (dev->remote->mask_keydown & 0x40000)
704 else if (dev->remote->mask_keyup & 0x40000) 706 irq2_mask |= SAA7134_IRQ2_INTE_GPIO18_P;
705 irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A; 707 if (dev->remote->mask_keyup & 0x40000)
708 irq2_mask |= SAA7134_IRQ2_INTE_GPIO18_N;
709 }
706 } 710 }
707 711
708 if (dev->has_remote == SAA7134_REMOTE_I2C) { 712 if (dev->has_remote == SAA7134_REMOTE_I2C) {
@@ -1227,7 +1231,7 @@ static int saa7134_resume(struct pci_dev *pci_dev)
1227 if (card_has_mpeg(dev)) 1231 if (card_has_mpeg(dev))
1228 saa7134_ts_init_hw(dev); 1232 saa7134_ts_init_hw(dev);
1229 if (dev->remote) 1233 if (dev->remote)
1230 saa7134_ir_start(dev, dev->remote); 1234 saa7134_ir_start(dev);
1231 saa7134_hw_enable1(dev); 1235 saa7134_hw_enable1(dev);
1232 1236
1233 msleep(100); 1237 msleep(100);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 4ab4a987c9b9..31e82be1b7e7 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1532,6 +1532,15 @@ static int dvb_init(struct saa7134_dev *dev)
1532 &dev->i2c_adap, &behold_x7_tunerconfig); 1532 &dev->i2c_adap, &behold_x7_tunerconfig);
1533 } 1533 }
1534 break; 1534 break;
1535 case SAA7134_BOARD_BEHOLD_H7:
1536 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1537 &behold_x7_config,
1538 &dev->i2c_adap);
1539 if (fe0->dvb.frontend) {
1540 dvb_attach(xc5000_attach, fe0->dvb.frontend,
1541 &dev->i2c_adap, &behold_x7_tunerconfig);
1542 }
1543 break;
1535 case SAA7134_BOARD_AVERMEDIA_A700_PRO: 1544 case SAA7134_BOARD_AVERMEDIA_A700_PRO:
1536 case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: 1545 case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
1537 /* Zarlink ZL10313 */ 1546 /* Zarlink ZL10313 */
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 58a0cdc8414a..e5565e2fd426 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -28,6 +28,8 @@
28#include "saa7134-reg.h" 28#include "saa7134-reg.h"
29#include "saa7134.h" 29#include "saa7134.h"
30 30
31#define MODULE_NAME "saa7134"
32
31static unsigned int disable_ir; 33static unsigned int disable_ir;
32module_param(disable_ir, int, 0444); 34module_param(disable_ir, int, 0444);
33MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); 35MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
@@ -66,6 +68,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
66/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ 68/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
67static int saa7134_rc5_irq(struct saa7134_dev *dev); 69static int saa7134_rc5_irq(struct saa7134_dev *dev);
68static int saa7134_nec_irq(struct saa7134_dev *dev); 70static int saa7134_nec_irq(struct saa7134_dev *dev);
71static int saa7134_raw_decode_irq(struct saa7134_dev *dev);
69static void nec_task(unsigned long data); 72static void nec_task(unsigned long data);
70static void saa7134_nec_timer(unsigned long data); 73static void saa7134_nec_timer(unsigned long data);
71 74
@@ -397,14 +400,23 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
397 400
398void saa7134_input_irq(struct saa7134_dev *dev) 401void saa7134_input_irq(struct saa7134_dev *dev)
399{ 402{
400 struct card_ir *ir = dev->remote; 403 struct card_ir *ir;
404
405 if (!dev || !dev->remote)
406 return;
407
408 ir = dev->remote;
409 if (!ir->running)
410 return;
401 411
402 if (ir->nec_gpio) { 412 if (ir->nec_gpio) {
403 saa7134_nec_irq(dev); 413 saa7134_nec_irq(dev);
404 } else if (!ir->polling && !ir->rc5_gpio) { 414 } else if (!ir->polling && !ir->rc5_gpio && !ir->raw_decode) {
405 build_key(dev); 415 build_key(dev);
406 } else if (ir->rc5_gpio) { 416 } else if (ir->rc5_gpio) {
407 saa7134_rc5_irq(dev); 417 saa7134_rc5_irq(dev);
418 } else if (ir->raw_decode) {
419 saa7134_raw_decode_irq(dev);
408 } 420 }
409} 421}
410 422
@@ -417,8 +429,32 @@ static void saa7134_input_timer(unsigned long data)
417 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); 429 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
418} 430}
419 431
420void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) 432void ir_raw_decode_timer_end(unsigned long data)
433{
434 struct saa7134_dev *dev = (struct saa7134_dev *)data;
435 struct card_ir *ir = dev->remote;
436
437 ir_raw_event_handle(dev->remote->dev);
438
439 ir->active = 0;
440}
441
442static int __saa7134_ir_start(void *priv)
421{ 443{
444 struct saa7134_dev *dev = priv;
445 struct card_ir *ir;
446
447 if (!dev)
448 return -EINVAL;
449
450 ir = dev->remote;
451 if (!ir)
452 return -EINVAL;
453
454 if (ir->running)
455 return 0;
456
457 ir->running = 1;
422 if (ir->polling) { 458 if (ir->polling) {
423 setup_timer(&ir->timer, saa7134_input_timer, 459 setup_timer(&ir->timer, saa7134_input_timer,
424 (unsigned long)dev); 460 (unsigned long)dev);
@@ -441,26 +477,125 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
441 setup_timer(&ir->timer_keyup, saa7134_nec_timer, 477 setup_timer(&ir->timer_keyup, saa7134_nec_timer,
442 (unsigned long)dev); 478 (unsigned long)dev);
443 tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); 479 tasklet_init(&ir->tlet, nec_task, (unsigned long)dev);
480 } else if (ir->raw_decode) {
481 /* set timer_end for code completion */
482 init_timer(&ir->timer_end);
483 ir->timer_end.function = ir_raw_decode_timer_end;
484 ir->timer_end.data = (unsigned long)dev;
485 ir->active = 0;
444 } 486 }
487
488 return 0;
445} 489}
446 490
447void saa7134_ir_stop(struct saa7134_dev *dev) 491static void __saa7134_ir_stop(void *priv)
448{ 492{
493 struct saa7134_dev *dev = priv;
494 struct card_ir *ir;
495
496 if (!dev)
497 return;
498
499 ir = dev->remote;
500 if (!ir)
501 return;
502
503 if (!ir->running)
504 return;
449 if (dev->remote->polling) 505 if (dev->remote->polling)
450 del_timer_sync(&dev->remote->timer); 506 del_timer_sync(&dev->remote->timer);
507 else if (ir->rc5_gpio)
508 del_timer_sync(&ir->timer_end);
509 else if (ir->nec_gpio)
510 tasklet_kill(&ir->tlet);
511 else if (ir->raw_decode) {
512 del_timer_sync(&ir->timer_end);
513 ir->active = 0;
514 }
515
516 ir->running = 0;
517
518 return;
519}
520
521int saa7134_ir_start(struct saa7134_dev *dev)
522{
523 if (dev->remote->users)
524 return __saa7134_ir_start(dev);
525
526 return 0;
527}
528
529void saa7134_ir_stop(struct saa7134_dev *dev)
530{
531 if (dev->remote->users)
532 __saa7134_ir_stop(dev);
533}
534
535static int saa7134_ir_open(void *priv)
536{
537 struct saa7134_dev *dev = priv;
538
539 dev->remote->users++;
540 return __saa7134_ir_start(dev);
541}
542
543static void saa7134_ir_close(void *priv)
544{
545 struct saa7134_dev *dev = priv;
546
547 dev->remote->users--;
548 if (!dev->remote->users)
549 __saa7134_ir_stop(dev);
550}
551
552
553int saa7134_ir_change_protocol(void *priv, u64 ir_type)
554{
555 struct saa7134_dev *dev = priv;
556 struct card_ir *ir = dev->remote;
557 u32 nec_gpio, rc5_gpio;
558
559 if (ir_type == IR_TYPE_RC5) {
560 dprintk("Changing protocol to RC5\n");
561 nec_gpio = 0;
562 rc5_gpio = 1;
563 } else if (ir_type == IR_TYPE_NEC) {
564 dprintk("Changing protocol to NEC\n");
565 nec_gpio = 1;
566 rc5_gpio = 0;
567 } else {
568 dprintk("IR protocol type %ud is not supported\n",
569 (unsigned)ir_type);
570 return -EINVAL;
571 }
572
573 if (ir->running) {
574 saa7134_ir_stop(dev);
575 ir->nec_gpio = nec_gpio;
576 ir->rc5_gpio = rc5_gpio;
577 saa7134_ir_start(dev);
578 } else {
579 ir->nec_gpio = nec_gpio;
580 ir->rc5_gpio = rc5_gpio;
581 }
582
583 return 0;
451} 584}
452 585
453int saa7134_input_init1(struct saa7134_dev *dev) 586int saa7134_input_init1(struct saa7134_dev *dev)
454{ 587{
455 struct card_ir *ir; 588 struct card_ir *ir;
456 struct input_dev *input_dev; 589 struct input_dev *input_dev;
457 struct ir_scancode_table *ir_codes = NULL; 590 char *ir_codes = NULL;
458 u32 mask_keycode = 0; 591 u32 mask_keycode = 0;
459 u32 mask_keydown = 0; 592 u32 mask_keydown = 0;
460 u32 mask_keyup = 0; 593 u32 mask_keyup = 0;
461 int polling = 0; 594 int polling = 0;
462 int rc5_gpio = 0; 595 int rc5_gpio = 0;
463 int nec_gpio = 0; 596 int nec_gpio = 0;
597 int raw_decode = 0;
598 int allow_protocol_change = 0;
464 u64 ir_type = IR_TYPE_OTHER; 599 u64 ir_type = IR_TYPE_OTHER;
465 int err; 600 int err;
466 601
@@ -476,27 +611,27 @@ int saa7134_input_init1(struct saa7134_dev *dev)
476 case SAA7134_BOARD_FLYTVPLATINUM_FM: 611 case SAA7134_BOARD_FLYTVPLATINUM_FM:
477 case SAA7134_BOARD_FLYTVPLATINUM_MINI2: 612 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
478 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM: 613 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
479 ir_codes = &ir_codes_flyvideo_table; 614 ir_codes = RC_MAP_FLYVIDEO;
480 mask_keycode = 0xEC00000; 615 mask_keycode = 0xEC00000;
481 mask_keydown = 0x0040000; 616 mask_keydown = 0x0040000;
482 break; 617 break;
483 case SAA7134_BOARD_CINERGY400: 618 case SAA7134_BOARD_CINERGY400:
484 case SAA7134_BOARD_CINERGY600: 619 case SAA7134_BOARD_CINERGY600:
485 case SAA7134_BOARD_CINERGY600_MK3: 620 case SAA7134_BOARD_CINERGY600_MK3:
486 ir_codes = &ir_codes_cinergy_table; 621 ir_codes = RC_MAP_CINERGY;
487 mask_keycode = 0x00003f; 622 mask_keycode = 0x00003f;
488 mask_keyup = 0x040000; 623 mask_keyup = 0x040000;
489 break; 624 break;
490 case SAA7134_BOARD_ECS_TVP3XP: 625 case SAA7134_BOARD_ECS_TVP3XP:
491 case SAA7134_BOARD_ECS_TVP3XP_4CB5: 626 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
492 ir_codes = &ir_codes_eztv_table; 627 ir_codes = RC_MAP_EZTV;
493 mask_keycode = 0x00017c; 628 mask_keycode = 0x00017c;
494 mask_keyup = 0x000002; 629 mask_keyup = 0x000002;
495 polling = 50; // ms 630 polling = 50; // ms
496 break; 631 break;
497 case SAA7134_BOARD_KWORLD_XPERT: 632 case SAA7134_BOARD_KWORLD_XPERT:
498 case SAA7134_BOARD_AVACSSMARTTV: 633 case SAA7134_BOARD_AVACSSMARTTV:
499 ir_codes = &ir_codes_pixelview_table; 634 ir_codes = RC_MAP_PIXELVIEW;
500 mask_keycode = 0x00001F; 635 mask_keycode = 0x00001F;
501 mask_keyup = 0x000020; 636 mask_keyup = 0x000020;
502 polling = 50; // ms 637 polling = 50; // ms
@@ -513,7 +648,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
513 case SAA7134_BOARD_AVERMEDIA_GO_007_FM: 648 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
514 case SAA7134_BOARD_AVERMEDIA_M102: 649 case SAA7134_BOARD_AVERMEDIA_M102:
515 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: 650 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
516 ir_codes = &ir_codes_avermedia_table; 651 ir_codes = RC_MAP_AVERMEDIA;
517 mask_keycode = 0x0007C8; 652 mask_keycode = 0x0007C8;
518 mask_keydown = 0x000010; 653 mask_keydown = 0x000010;
519 polling = 50; // ms 654 polling = 50; // ms
@@ -522,14 +657,15 @@ int saa7134_input_init1(struct saa7134_dev *dev)
522 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 657 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
523 break; 658 break;
524 case SAA7134_BOARD_AVERMEDIA_M135A: 659 case SAA7134_BOARD_AVERMEDIA_M135A:
525 ir_codes = &ir_codes_avermedia_m135a_table; 660 ir_codes = RC_MAP_AVERMEDIA_M135A_RM_JX;
526 mask_keydown = 0x0040000; 661 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
527 mask_keycode = 0x00013f; 662 mask_keyup = 0x0040000;
528 nec_gpio = 1; 663 mask_keycode = 0xffff;
664 raw_decode = 1;
529 break; 665 break;
530 case SAA7134_BOARD_AVERMEDIA_777: 666 case SAA7134_BOARD_AVERMEDIA_777:
531 case SAA7134_BOARD_AVERMEDIA_A16AR: 667 case SAA7134_BOARD_AVERMEDIA_A16AR:
532 ir_codes = &ir_codes_avermedia_table; 668 ir_codes = RC_MAP_AVERMEDIA;
533 mask_keycode = 0x02F200; 669 mask_keycode = 0x02F200;
534 mask_keydown = 0x000400; 670 mask_keydown = 0x000400;
535 polling = 50; // ms 671 polling = 50; // ms
@@ -538,7 +674,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
538 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); 674 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
539 break; 675 break;
540 case SAA7134_BOARD_AVERMEDIA_A16D: 676 case SAA7134_BOARD_AVERMEDIA_A16D:
541 ir_codes = &ir_codes_avermedia_a16d_table; 677 ir_codes = RC_MAP_AVERMEDIA_A16D;
542 mask_keycode = 0x02F200; 678 mask_keycode = 0x02F200;
543 mask_keydown = 0x000400; 679 mask_keydown = 0x000400;
544 polling = 50; /* ms */ 680 polling = 50; /* ms */
@@ -547,14 +683,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
547 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); 683 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
548 break; 684 break;
549 case SAA7134_BOARD_KWORLD_TERMINATOR: 685 case SAA7134_BOARD_KWORLD_TERMINATOR:
550 ir_codes = &ir_codes_pixelview_table; 686 ir_codes = RC_MAP_PIXELVIEW;
551 mask_keycode = 0x00001f; 687 mask_keycode = 0x00001f;
552 mask_keyup = 0x000060; 688 mask_keyup = 0x000060;
553 polling = 50; // ms 689 polling = 50; // ms
554 break; 690 break;
555 case SAA7134_BOARD_MANLI_MTV001: 691 case SAA7134_BOARD_MANLI_MTV001:
556 case SAA7134_BOARD_MANLI_MTV002: 692 case SAA7134_BOARD_MANLI_MTV002:
557 ir_codes = &ir_codes_manli_table; 693 ir_codes = RC_MAP_MANLI;
558 mask_keycode = 0x001f00; 694 mask_keycode = 0x001f00;
559 mask_keyup = 0x004000; 695 mask_keyup = 0x004000;
560 polling = 50; /* ms */ 696 polling = 50; /* ms */
@@ -574,25 +710,25 @@ int saa7134_input_init1(struct saa7134_dev *dev)
574 case SAA7134_BOARD_BEHOLD_507_9FM: 710 case SAA7134_BOARD_BEHOLD_507_9FM:
575 case SAA7134_BOARD_BEHOLD_507RDS_MK3: 711 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
576 case SAA7134_BOARD_BEHOLD_507RDS_MK5: 712 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
577 ir_codes = &ir_codes_manli_table; 713 ir_codes = RC_MAP_MANLI;
578 mask_keycode = 0x003f00; 714 mask_keycode = 0x003f00;
579 mask_keyup = 0x004000; 715 mask_keyup = 0x004000;
580 polling = 50; /* ms */ 716 polling = 50; /* ms */
581 break; 717 break;
582 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: 718 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
583 ir_codes = &ir_codes_behold_columbus_table; 719 ir_codes = RC_MAP_BEHOLD_COLUMBUS;
584 mask_keycode = 0x003f00; 720 mask_keycode = 0x003f00;
585 mask_keyup = 0x004000; 721 mask_keyup = 0x004000;
586 polling = 50; // ms 722 polling = 50; // ms
587 break; 723 break;
588 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: 724 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
589 ir_codes = &ir_codes_pctv_sedna_table; 725 ir_codes = RC_MAP_PCTV_SEDNA;
590 mask_keycode = 0x001f00; 726 mask_keycode = 0x001f00;
591 mask_keyup = 0x004000; 727 mask_keyup = 0x004000;
592 polling = 50; // ms 728 polling = 50; // ms
593 break; 729 break;
594 case SAA7134_BOARD_GOTVIEW_7135: 730 case SAA7134_BOARD_GOTVIEW_7135:
595 ir_codes = &ir_codes_gotview7135_table; 731 ir_codes = RC_MAP_GOTVIEW7135;
596 mask_keycode = 0x0003CC; 732 mask_keycode = 0x0003CC;
597 mask_keydown = 0x000010; 733 mask_keydown = 0x000010;
598 polling = 5; /* ms */ 734 polling = 5; /* ms */
@@ -601,80 +737,80 @@ int saa7134_input_init1(struct saa7134_dev *dev)
601 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 737 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
602 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: 738 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
603 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 739 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
604 ir_codes = &ir_codes_videomate_tv_pvr_table; 740 ir_codes = RC_MAP_VIDEOMATE_TV_PVR;
605 mask_keycode = 0x00003F; 741 mask_keycode = 0x00003F;
606 mask_keyup = 0x400000; 742 mask_keyup = 0x400000;
607 polling = 50; // ms 743 polling = 50; // ms
608 break; 744 break;
609 case SAA7134_BOARD_PROTEUS_2309: 745 case SAA7134_BOARD_PROTEUS_2309:
610 ir_codes = &ir_codes_proteus_2309_table; 746 ir_codes = RC_MAP_PROTEUS_2309;
611 mask_keycode = 0x00007F; 747 mask_keycode = 0x00007F;
612 mask_keyup = 0x000080; 748 mask_keyup = 0x000080;
613 polling = 50; // ms 749 polling = 50; // ms
614 break; 750 break;
615 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 751 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
616 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 752 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
617 ir_codes = &ir_codes_videomate_tv_pvr_table; 753 ir_codes = RC_MAP_VIDEOMATE_TV_PVR;
618 mask_keycode = 0x003F00; 754 mask_keycode = 0x003F00;
619 mask_keyup = 0x040000; 755 mask_keyup = 0x040000;
620 break; 756 break;
621 case SAA7134_BOARD_FLYDVBS_LR300: 757 case SAA7134_BOARD_FLYDVBS_LR300:
622 case SAA7134_BOARD_FLYDVBT_LR301: 758 case SAA7134_BOARD_FLYDVBT_LR301:
623 case SAA7134_BOARD_FLYDVBTDUO: 759 case SAA7134_BOARD_FLYDVBTDUO:
624 ir_codes = &ir_codes_flydvb_table; 760 ir_codes = RC_MAP_FLYDVB;
625 mask_keycode = 0x0001F00; 761 mask_keycode = 0x0001F00;
626 mask_keydown = 0x0040000; 762 mask_keydown = 0x0040000;
627 break; 763 break;
628 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 764 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
629 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: 765 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
630 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: 766 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
631 ir_codes = &ir_codes_asus_pc39_table; 767 ir_codes = RC_MAP_ASUS_PC39;
632 mask_keydown = 0x0040000; 768 mask_keydown = 0x0040000;
633 rc5_gpio = 1; 769 rc5_gpio = 1;
634 break; 770 break;
635 case SAA7134_BOARD_ENCORE_ENLTV: 771 case SAA7134_BOARD_ENCORE_ENLTV:
636 case SAA7134_BOARD_ENCORE_ENLTV_FM: 772 case SAA7134_BOARD_ENCORE_ENLTV_FM:
637 ir_codes = &ir_codes_encore_enltv_table; 773 ir_codes = RC_MAP_ENCORE_ENLTV;
638 mask_keycode = 0x00007f; 774 mask_keycode = 0x00007f;
639 mask_keyup = 0x040000; 775 mask_keyup = 0x040000;
640 polling = 50; // ms 776 polling = 50; // ms
641 break; 777 break;
642 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 778 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
643 ir_codes = &ir_codes_encore_enltv_fm53_table; 779 ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
644 mask_keydown = 0x0040000; 780 mask_keydown = 0x0040000;
645 mask_keycode = 0x00007f; 781 mask_keycode = 0x00007f;
646 nec_gpio = 1; 782 nec_gpio = 1;
647 break; 783 break;
648 case SAA7134_BOARD_10MOONSTVMASTER3: 784 case SAA7134_BOARD_10MOONSTVMASTER3:
649 ir_codes = &ir_codes_encore_enltv_table; 785 ir_codes = RC_MAP_ENCORE_ENLTV;
650 mask_keycode = 0x5f80000; 786 mask_keycode = 0x5f80000;
651 mask_keyup = 0x8000000; 787 mask_keyup = 0x8000000;
652 polling = 50; //ms 788 polling = 50; //ms
653 break; 789 break;
654 case SAA7134_BOARD_GENIUS_TVGO_A11MCE: 790 case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
655 ir_codes = &ir_codes_genius_tvgo_a11mce_table; 791 ir_codes = RC_MAP_GENIUS_TVGO_A11MCE;
656 mask_keycode = 0xff; 792 mask_keycode = 0xff;
657 mask_keydown = 0xf00000; 793 mask_keydown = 0xf00000;
658 polling = 50; /* ms */ 794 polling = 50; /* ms */
659 break; 795 break;
660 case SAA7134_BOARD_REAL_ANGEL_220: 796 case SAA7134_BOARD_REAL_ANGEL_220:
661 ir_codes = &ir_codes_real_audio_220_32_keys_table; 797 ir_codes = RC_MAP_REAL_AUDIO_220_32_KEYS;
662 mask_keycode = 0x3f00; 798 mask_keycode = 0x3f00;
663 mask_keyup = 0x4000; 799 mask_keyup = 0x4000;
664 polling = 50; /* ms */ 800 polling = 50; /* ms */
665 break; 801 break;
666 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: 802 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
667 ir_codes = &ir_codes_kworld_plus_tv_analog_table; 803 ir_codes = RC_MAP_KWORLD_PLUS_TV_ANALOG;
668 mask_keycode = 0x7f; 804 mask_keycode = 0x7f;
669 polling = 40; /* ms */ 805 polling = 40; /* ms */
670 break; 806 break;
671 case SAA7134_BOARD_VIDEOMATE_S350: 807 case SAA7134_BOARD_VIDEOMATE_S350:
672 ir_codes = &ir_codes_videomate_s350_table; 808 ir_codes = RC_MAP_VIDEOMATE_S350;
673 mask_keycode = 0x003f00; 809 mask_keycode = 0x003f00;
674 mask_keydown = 0x040000; 810 mask_keydown = 0x040000;
675 break; 811 break;
676 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S: 812 case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
677 ir_codes = &ir_codes_winfast_table; 813 ir_codes = RC_MAP_WINFAST;
678 mask_keycode = 0x5f00; 814 mask_keycode = 0x5f00;
679 mask_keyup = 0x020000; 815 mask_keyup = 0x020000;
680 polling = 50; /* ms */ 816 polling = 50; /* ms */
@@ -695,6 +831,9 @@ int saa7134_input_init1(struct saa7134_dev *dev)
695 } 831 }
696 832
697 ir->dev = input_dev; 833 ir->dev = input_dev;
834 dev->remote = ir;
835
836 ir->running = 0;
698 837
699 /* init hardware-specific stuff */ 838 /* init hardware-specific stuff */
700 ir->mask_keycode = mask_keycode; 839 ir->mask_keycode = mask_keycode;
@@ -703,6 +842,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
703 ir->polling = polling; 842 ir->polling = polling;
704 ir->rc5_gpio = rc5_gpio; 843 ir->rc5_gpio = rc5_gpio;
705 ir->nec_gpio = nec_gpio; 844 ir->nec_gpio = nec_gpio;
845 ir->raw_decode = raw_decode;
706 846
707 /* init input device */ 847 /* init input device */
708 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", 848 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -710,6 +850,19 @@ int saa7134_input_init1(struct saa7134_dev *dev)
710 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", 850 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
711 pci_name(dev->pci)); 851 pci_name(dev->pci));
712 852
853
854 ir->props.priv = dev;
855 ir->props.open = saa7134_ir_open;
856 ir->props.close = saa7134_ir_close;
857
858 if (raw_decode)
859 ir->props.driver_type = RC_DRIVER_IR_RAW;
860
861 if (!raw_decode && allow_protocol_change) {
862 ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
863 ir->props.change_protocol = saa7134_ir_change_protocol;
864 }
865
713 err = ir_input_init(input_dev, &ir->ir, ir_type); 866 err = ir_input_init(input_dev, &ir->ir, ir_type);
714 if (err < 0) 867 if (err < 0)
715 goto err_out_free; 868 goto err_out_free;
@@ -727,12 +880,9 @@ int saa7134_input_init1(struct saa7134_dev *dev)
727 } 880 }
728 input_dev->dev.parent = &dev->pci->dev; 881 input_dev->dev.parent = &dev->pci->dev;
729 882
730 dev->remote = ir; 883 err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME);
731 saa7134_ir_start(dev, ir);
732
733 err = ir_input_register(ir->dev, ir_codes, NULL);
734 if (err) 884 if (err)
735 goto err_out_stop; 885 goto err_out_free;
736 886
737 /* the remote isn't as bouncy as a keyboard */ 887 /* the remote isn't as bouncy as a keyboard */
738 ir->dev->rep[REP_DELAY] = repeat_delay; 888 ir->dev->rep[REP_DELAY] = repeat_delay;
@@ -740,10 +890,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
740 890
741 return 0; 891 return 0;
742 892
743 err_out_stop: 893err_out_free:
744 saa7134_ir_stop(dev);
745 dev->remote = NULL; 894 dev->remote = NULL;
746 err_out_free:
747 kfree(ir); 895 kfree(ir);
748 return err; 896 return err;
749} 897}
@@ -787,24 +935,24 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
787 dev->init_data.name = "Pinnacle PCTV"; 935 dev->init_data.name = "Pinnacle PCTV";
788 if (pinnacle_remote == 0) { 936 if (pinnacle_remote == 0) {
789 dev->init_data.get_key = get_key_pinnacle_color; 937 dev->init_data.get_key = get_key_pinnacle_color;
790 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table; 938 dev->init_data.ir_codes = RC_MAP_PINNACLE_COLOR;
791 info.addr = 0x47; 939 info.addr = 0x47;
792 } else { 940 } else {
793 dev->init_data.get_key = get_key_pinnacle_grey; 941 dev->init_data.get_key = get_key_pinnacle_grey;
794 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table; 942 dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY;
795 info.addr = 0x47; 943 info.addr = 0x47;
796 } 944 }
797 break; 945 break;
798 case SAA7134_BOARD_UPMOST_PURPLE_TV: 946 case SAA7134_BOARD_UPMOST_PURPLE_TV:
799 dev->init_data.name = "Purple TV"; 947 dev->init_data.name = "Purple TV";
800 dev->init_data.get_key = get_key_purpletv; 948 dev->init_data.get_key = get_key_purpletv;
801 dev->init_data.ir_codes = &ir_codes_purpletv_table; 949 dev->init_data.ir_codes = RC_MAP_PURPLETV;
802 info.addr = 0x7a; 950 info.addr = 0x7a;
803 break; 951 break;
804 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 952 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
805 dev->init_data.name = "MSI TV@nywhere Plus"; 953 dev->init_data.name = "MSI TV@nywhere Plus";
806 dev->init_data.get_key = get_key_msi_tvanywhere_plus; 954 dev->init_data.get_key = get_key_msi_tvanywhere_plus;
807 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table; 955 dev->init_data.ir_codes = RC_MAP_MSI_TVANYWHERE_PLUS;
808 info.addr = 0x30; 956 info.addr = 0x30;
809 /* MSI TV@nywhere Plus controller doesn't seem to 957 /* MSI TV@nywhere Plus controller doesn't seem to
810 respond to probes unless we read something from 958 respond to probes unless we read something from
@@ -818,7 +966,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
818 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 966 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
819 dev->init_data.name = "HVR 1110"; 967 dev->init_data.name = "HVR 1110";
820 dev->init_data.get_key = get_key_hvr1110; 968 dev->init_data.get_key = get_key_hvr1110;
821 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table; 969 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW;
822 info.addr = 0x71; 970 info.addr = 0x71;
823 break; 971 break;
824 case SAA7134_BOARD_BEHOLD_607FM_MK3: 972 case SAA7134_BOARD_BEHOLD_607FM_MK3:
@@ -834,9 +982,12 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
834 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 982 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
835 case SAA7134_BOARD_BEHOLD_H6: 983 case SAA7134_BOARD_BEHOLD_H6:
836 case SAA7134_BOARD_BEHOLD_X7: 984 case SAA7134_BOARD_BEHOLD_X7:
985 case SAA7134_BOARD_BEHOLD_H7:
986 case SAA7134_BOARD_BEHOLD_A7:
837 dev->init_data.name = "BeholdTV"; 987 dev->init_data.name = "BeholdTV";
838 dev->init_data.get_key = get_key_beholdm6xx; 988 dev->init_data.get_key = get_key_beholdm6xx;
839 dev->init_data.ir_codes = &ir_codes_behold_table; 989 dev->init_data.ir_codes = RC_MAP_BEHOLD;
990 dev->init_data.type = IR_TYPE_NEC;
840 info.addr = 0x2d; 991 info.addr = 0x2d;
841 break; 992 break;
842 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: 993 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
@@ -846,7 +997,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
846 case SAA7134_BOARD_FLYDVB_TRIO: 997 case SAA7134_BOARD_FLYDVB_TRIO:
847 dev->init_data.name = "FlyDVB Trio"; 998 dev->init_data.name = "FlyDVB Trio";
848 dev->init_data.get_key = get_key_flydvb_trio; 999 dev->init_data.get_key = get_key_flydvb_trio;
849 dev->init_data.ir_codes = &ir_codes_flydvb_table; 1000 dev->init_data.ir_codes = RC_MAP_FLYDVB;
850 info.addr = 0x0b; 1001 info.addr = 0x0b;
851 break; 1002 break;
852 default: 1003 default:
@@ -859,6 +1010,33 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
859 i2c_new_device(&dev->i2c_adap, &info); 1010 i2c_new_device(&dev->i2c_adap, &info);
860} 1011}
861 1012
1013static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
1014{
1015 struct card_ir *ir = dev->remote;
1016 unsigned long timeout;
1017 int space;
1018
1019 /* Generate initial event */
1020 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1021 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1022 space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
1023 ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);
1024
1025
1026 /*
1027 * Wait 15 ms from the start of the first IR event before processing
1028 * the event. This time is enough for NEC protocol. May need adjustments
1029 * to work with other protocols.
1030 */
1031 if (!ir->active) {
1032 timeout = jiffies + jiffies_to_msecs(15);
1033 mod_timer(&ir->timer_end, timeout);
1034 ir->active = 1;
1035 }
1036
1037 return 1;
1038}
1039
862static int saa7134_rc5_irq(struct saa7134_dev *dev) 1040static int saa7134_rc5_irq(struct saa7134_dev *dev)
863{ 1041{
864 struct card_ir *ir = dev->remote; 1042 struct card_ir *ir = dev->remote;
@@ -901,7 +1079,6 @@ static int saa7134_rc5_irq(struct saa7134_dev *dev)
901 return 1; 1079 return 1;
902} 1080}
903 1081
904
905/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms 1082/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms
906 The first pulse (start) has 9 + 4.5 ms 1083 The first pulse (start) has 9 + 4.5 ms
907 */ 1084 */
@@ -1011,14 +1188,14 @@ static void nec_task(unsigned long data)
1011 /* Keep repeating the last key */ 1188 /* Keep repeating the last key */
1012 mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150)); 1189 mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150));
1013 1190
1014 saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); 1191 saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
1015} 1192}
1016 1193
1017static int saa7134_nec_irq(struct saa7134_dev *dev) 1194static int saa7134_nec_irq(struct saa7134_dev *dev)
1018{ 1195{
1019 struct card_ir *ir = dev->remote; 1196 struct card_ir *ir = dev->remote;
1020 1197
1021 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); 1198 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
1022 tasklet_schedule(&ir->tlet); 1199 tasklet_schedule(&ir->tlet);
1023 1200
1024 return 1; 1201 return 1;
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index cf89d96d7295..e7e0af101fa7 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -112,17 +112,17 @@
112#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0) 112#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0)
113 113
114#define SAA7134_IRQ2 (0x2c8 >> 2) 114#define SAA7134_IRQ2 (0x2c8 >> 2)
115#define SAA7134_IRQ2_INTE_GPIO23A (1 << 17) 115#define SAA7134_IRQ2_INTE_GPIO23_N (1 << 17) /* negative edge */
116#define SAA7134_IRQ2_INTE_GPIO23 (1 << 16) 116#define SAA7134_IRQ2_INTE_GPIO23_P (1 << 16) /* positive edge */
117#define SAA7134_IRQ2_INTE_GPIO22A (1 << 15) 117#define SAA7134_IRQ2_INTE_GPIO22_N (1 << 15) /* negative edge */
118#define SAA7134_IRQ2_INTE_GPIO22 (1 << 14) 118#define SAA7134_IRQ2_INTE_GPIO22_P (1 << 14) /* positive edge */
119#define SAA7134_IRQ2_INTE_GPIO18A (1 << 13) 119#define SAA7134_IRQ2_INTE_GPIO18_N (1 << 13) /* negative edge */
120#define SAA7134_IRQ2_INTE_GPIO18 (1 << 12) 120#define SAA7134_IRQ2_INTE_GPIO18_P (1 << 12) /* positive edge */
121#define SAA7134_IRQ2_INTE_GPIO16 (1 << 11) /* not certain */ 121#define SAA7134_IRQ2_INTE_GPIO16_N (1 << 11) /* negative edge */
122#define SAA7134_IRQ2_INTE_SC2 (1 << 10) 122#define SAA7134_IRQ2_INTE_GPIO16_P (1 << 10) /* positive edge */
123#define SAA7134_IRQ2_INTE_SC1 (1 << 9) 123#define SAA7134_IRQ2_INTE_SC2 (1 << 9)
124#define SAA7134_IRQ2_INTE_SC0 (1 << 8) 124#define SAA7134_IRQ2_INTE_SC1 (1 << 8)
125#define SAA7134_IRQ2_INTE_DEC5 (1 << 7) 125#define SAA7134_IRQ2_INTE_SC0 (1 << 7)
126#define SAA7134_IRQ2_INTE_DEC4 (1 << 6) 126#define SAA7134_IRQ2_INTE_DEC4 (1 << 6)
127#define SAA7134_IRQ2_INTE_DEC3 (1 << 5) 127#define SAA7134_IRQ2_INTE_DEC3 (1 << 5)
128#define SAA7134_IRQ2_INTE_DEC2 (1 << 4) 128#define SAA7134_IRQ2_INTE_DEC2 (1 << 4)
@@ -135,7 +135,7 @@
135#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17) 135#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17)
136#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16) 136#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16)
137#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15) 137#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15)
138#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14) /* not certain */ 138#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14)
139#define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13) 139#define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13)
140#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12) 140#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12)
141#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11) 141#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11)
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 31138d3e51bb..45f0ac8f3c0f 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1180,7 +1180,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
1180 That needs to be fixed somehow, but for now this is 1180 That needs to be fixed somehow, but for now this is
1181 good enough. */ 1181 good enough. */
1182 if (fh) { 1182 if (fh) {
1183 err = v4l2_prio_check(&dev->prio, &fh->prio); 1183 err = v4l2_prio_check(&dev->prio, fh->prio);
1184 if (0 != err) 1184 if (0 != err)
1185 return err; 1185 return err;
1186 } 1186 }
@@ -1359,7 +1359,7 @@ static int video_open(struct file *file)
1359 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); 1359 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1360 fh->width = 720; 1360 fh->width = 720;
1361 fh->height = 576; 1361 fh->height = 576;
1362 v4l2_prio_open(&dev->prio,&fh->prio); 1362 v4l2_prio_open(&dev->prio, &fh->prio);
1363 1363
1364 videobuf_queue_sg_init(&fh->cap, &video_qops, 1364 videobuf_queue_sg_init(&fh->cap, &video_qops,
1365 &dev->pci->dev, &dev->slock, 1365 &dev->pci->dev, &dev->slock,
@@ -1502,7 +1502,7 @@ static int video_release(struct file *file)
1502 saa7134_pgtable_free(dev->pci,&fh->pt_cap); 1502 saa7134_pgtable_free(dev->pci,&fh->pt_cap);
1503 saa7134_pgtable_free(dev->pci,&fh->pt_vbi); 1503 saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
1504 1504
1505 v4l2_prio_close(&dev->prio,&fh->prio); 1505 v4l2_prio_close(&dev->prio, fh->prio);
1506 file->private_data = NULL; 1506 file->private_data = NULL;
1507 kfree(fh); 1507 kfree(fh);
1508 return 0; 1508 return 0;
@@ -1632,8 +1632,15 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
1632 } 1632 }
1633 1633
1634 f->fmt.pix.field = field; 1634 f->fmt.pix.field = field;
1635 v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, 1635 if (f->fmt.pix.width < 48)
1636 &f->fmt.pix.height, 32, maxh, 0, 0); 1636 f->fmt.pix.width = 48;
1637 if (f->fmt.pix.height < 32)
1638 f->fmt.pix.height = 32;
1639 if (f->fmt.pix.width > maxw)
1640 f->fmt.pix.width = maxw;
1641 if (f->fmt.pix.height > maxh)
1642 f->fmt.pix.height = maxh;
1643 f->fmt.pix.width &= ~0x03;
1637 f->fmt.pix.bytesperline = 1644 f->fmt.pix.bytesperline =
1638 (f->fmt.pix.width * fmt->depth) >> 3; 1645 (f->fmt.pix.width * fmt->depth) >> 3;
1639 f->fmt.pix.sizeimage = 1646 f->fmt.pix.sizeimage =
@@ -1778,7 +1785,7 @@ static int saa7134_s_input(struct file *file, void *priv, unsigned int i)
1778 struct saa7134_dev *dev = fh->dev; 1785 struct saa7134_dev *dev = fh->dev;
1779 int err; 1786 int err;
1780 1787
1781 err = v4l2_prio_check(&dev->prio, &fh->prio); 1788 err = v4l2_prio_check(&dev->prio, fh->prio);
1782 if (0 != err) 1789 if (0 != err)
1783 return err; 1790 return err;
1784 1791
@@ -1832,7 +1839,7 @@ int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_
1832 That needs to be fixed somehow, but for now this is 1839 That needs to be fixed somehow, but for now this is
1833 good enough. */ 1840 good enough. */
1834 if (fh) { 1841 if (fh) {
1835 err = v4l2_prio_check(&dev->prio, &fh->prio); 1842 err = v4l2_prio_check(&dev->prio, fh->prio);
1836 if (0 != err) 1843 if (0 != err)
1837 return err; 1844 return err;
1838 } else if (res_locked(dev, RESOURCE_OVERLAY)) { 1845 } else if (res_locked(dev, RESOURCE_OVERLAY)) {
@@ -2016,7 +2023,7 @@ static int saa7134_s_tuner(struct file *file, void *priv,
2016 struct saa7134_dev *dev = fh->dev; 2023 struct saa7134_dev *dev = fh->dev;
2017 int rx, mode, err; 2024 int rx, mode, err;
2018 2025
2019 err = v4l2_prio_check(&dev->prio, &fh->prio); 2026 err = v4l2_prio_check(&dev->prio, fh->prio);
2020 if (0 != err) 2027 if (0 != err)
2021 return err; 2028 return err;
2022 2029
@@ -2050,7 +2057,7 @@ static int saa7134_s_frequency(struct file *file, void *priv,
2050 struct saa7134_dev *dev = fh->dev; 2057 struct saa7134_dev *dev = fh->dev;
2051 int err; 2058 int err;
2052 2059
2053 err = v4l2_prio_check(&dev->prio, &fh->prio); 2060 err = v4l2_prio_check(&dev->prio, fh->prio);
2054 if (0 != err) 2061 if (0 != err)
2055 return err; 2062 return err;
2056 2063
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index bf130967ed17..3962534267be 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -20,7 +20,7 @@
20 */ 20 */
21 21
22#include <linux/version.h> 22#include <linux/version.h>
23#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,15) 23#define SAA7134_VERSION_CODE KERNEL_VERSION(0, 2, 16)
24 24
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
@@ -300,6 +300,9 @@ struct saa7134_format {
300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174 300#define SAA7134_BOARD_ASUS_EUROPA_HYBRID 174
301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175 301#define SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S 175
302#define SAA7134_BOARD_BEHOLD_505RDS_MK3 176 302#define SAA7134_BOARD_BEHOLD_505RDS_MK3 176
303#define SAA7134_BOARD_HAWELL_HW_404M7 177
304#define SAA7134_BOARD_BEHOLD_H7 178
305#define SAA7134_BOARD_BEHOLD_A7 179
303 306
304#define SAA7134_MAXBOARDS 32 307#define SAA7134_MAXBOARDS 32
305#define SAA7134_INPUT_MAX 8 308#define SAA7134_INPUT_MAX 8
@@ -809,7 +812,7 @@ int saa7134_input_init1(struct saa7134_dev *dev);
809void saa7134_input_fini(struct saa7134_dev *dev); 812void saa7134_input_fini(struct saa7134_dev *dev);
810void saa7134_input_irq(struct saa7134_dev *dev); 813void saa7134_input_irq(struct saa7134_dev *dev);
811void saa7134_probe_i2c_ir(struct saa7134_dev *dev); 814void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
812void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); 815int saa7134_ir_start(struct saa7134_dev *dev);
813void saa7134_ir_stop(struct saa7134_dev *dev); 816void saa7134_ir_stop(struct saa7134_dev *dev);
814 817
815 818
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 1ad980f8e770..4ac3b482fbb4 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -115,9 +115,20 @@ struct sh_mobile_ceu_dev {
115}; 115};
116 116
117struct sh_mobile_ceu_cam { 117struct sh_mobile_ceu_cam {
118 struct v4l2_rect ceu_rect; 118 /* CEU offsets within scaled by the CEU camera output */
119 unsigned int cam_width; 119 unsigned int ceu_left;
120 unsigned int cam_height; 120 unsigned int ceu_top;
121 /* Client output, as seen by the CEU */
122 unsigned int width;
123 unsigned int height;
124 /*
125 * User window from S_CROP / G_CROP, produced by client cropping and
126 * scaling, CEU scaling and CEU cropping, mapped back onto the client
127 * input window
128 */
129 struct v4l2_rect subrect;
130 /* Camera cropping rectangle */
131 struct v4l2_rect rect;
121 const struct soc_mbus_pixelfmt *extra_fmt; 132 const struct soc_mbus_pixelfmt *extra_fmt;
122 enum v4l2_mbus_pixelcode code; 133 enum v4l2_mbus_pixelcode code;
123}; 134};
@@ -213,8 +224,8 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
213 *count = 2; 224 *count = 2;
214 225
215 if (pcdev->video_limit) { 226 if (pcdev->video_limit) {
216 while (PAGE_ALIGN(*size) * *count > pcdev->video_limit) 227 if (PAGE_ALIGN(*size) * *count > pcdev->video_limit)
217 (*count)--; 228 *count = pcdev->video_limit / PAGE_ALIGN(*size);
218 } 229 }
219 230
220 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); 231 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
@@ -565,38 +576,36 @@ static u16 calc_scale(unsigned int src, unsigned int *dst)
565} 576}
566 577
567/* rect is guaranteed to not exceed the scaled camera rectangle */ 578/* rect is guaranteed to not exceed the scaled camera rectangle */
568static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd, 579static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
569 unsigned int out_width,
570 unsigned int out_height)
571{ 580{
572 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 581 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
573 struct sh_mobile_ceu_cam *cam = icd->host_priv; 582 struct sh_mobile_ceu_cam *cam = icd->host_priv;
574 struct v4l2_rect *rect = &cam->ceu_rect;
575 struct sh_mobile_ceu_dev *pcdev = ici->priv; 583 struct sh_mobile_ceu_dev *pcdev = ici->priv;
576 unsigned int height, width, cdwdr_width, in_width, in_height; 584 unsigned int height, width, cdwdr_width, in_width, in_height;
577 unsigned int left_offset, top_offset; 585 unsigned int left_offset, top_offset;
578 u32 camor; 586 u32 camor;
579 587
580 dev_dbg(icd->dev.parent, "Crop %ux%u@%u:%u\n", 588 dev_geo(icd->dev.parent, "Crop %ux%u@%u:%u\n",
581 rect->width, rect->height, rect->left, rect->top); 589 icd->user_width, icd->user_height, cam->ceu_left, cam->ceu_top);
582 590
583 left_offset = rect->left; 591 left_offset = cam->ceu_left;
584 top_offset = rect->top; 592 top_offset = cam->ceu_top;
585 593
594 /* CEU cropping (CFSZR) is applied _after_ the scaling filter (CFLCR) */
586 if (pcdev->image_mode) { 595 if (pcdev->image_mode) {
587 in_width = rect->width; 596 in_width = cam->width;
588 if (!pcdev->is_16bit) { 597 if (!pcdev->is_16bit) {
589 in_width *= 2; 598 in_width *= 2;
590 left_offset *= 2; 599 left_offset *= 2;
591 } 600 }
592 width = out_width; 601 width = icd->user_width;
593 cdwdr_width = out_width; 602 cdwdr_width = icd->user_width;
594 } else { 603 } else {
595 int bytes_per_line = soc_mbus_bytes_per_line(out_width, 604 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
596 icd->current_fmt->host_fmt); 605 icd->current_fmt->host_fmt);
597 unsigned int w_factor; 606 unsigned int w_factor;
598 607
599 width = out_width; 608 width = icd->user_width;
600 609
601 switch (icd->current_fmt->host_fmt->packing) { 610 switch (icd->current_fmt->host_fmt->packing) {
602 case SOC_MBUS_PACKING_2X8_PADHI: 611 case SOC_MBUS_PACKING_2X8_PADHI:
@@ -606,17 +615,17 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd,
606 w_factor = 1; 615 w_factor = 1;
607 } 616 }
608 617
609 in_width = rect->width * w_factor; 618 in_width = cam->width * w_factor;
610 left_offset = left_offset * w_factor; 619 left_offset = left_offset * w_factor;
611 620
612 if (bytes_per_line < 0) 621 if (bytes_per_line < 0)
613 cdwdr_width = out_width; 622 cdwdr_width = icd->user_width;
614 else 623 else
615 cdwdr_width = bytes_per_line; 624 cdwdr_width = bytes_per_line;
616 } 625 }
617 626
618 height = out_height; 627 height = icd->user_height;
619 in_height = rect->height; 628 in_height = cam->height;
620 if (V4L2_FIELD_NONE != pcdev->field) { 629 if (V4L2_FIELD_NONE != pcdev->field) {
621 height /= 2; 630 height /= 2;
622 in_height /= 2; 631 in_height /= 2;
@@ -775,9 +784,10 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
775 } 784 }
776 ceu_write(pcdev, CAIFR, value); 785 ceu_write(pcdev, CAIFR, value);
777 786
778 sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height); 787 sh_mobile_ceu_set_rect(icd);
779 mdelay(1); 788 mdelay(1);
780 789
790 dev_geo(icd->dev.parent, "CFLCR 0x%x\n", pcdev->cflcr);
781 ceu_write(pcdev, CFLCR, pcdev->cflcr); 791 ceu_write(pcdev, CFLCR, pcdev->cflcr);
782 792
783 /* 793 /*
@@ -866,6 +876,8 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
866 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 876 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
867} 877}
868 878
879static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
880
869static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, 881static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
870 struct soc_camera_format_xlate *xlate) 882 struct soc_camera_format_xlate *xlate)
871{ 883{
@@ -894,10 +906,55 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
894 return 0; 906 return 0;
895 907
896 if (!icd->host_priv) { 908 if (!icd->host_priv) {
909 struct v4l2_mbus_framefmt mf;
910 struct v4l2_rect rect;
911 struct device *dev = icd->dev.parent;
912 int shift = 0;
913
914 /* FIXME: subwindow is lost between close / open */
915
916 /* Cache current client geometry */
917 ret = client_g_rect(sd, &rect);
918 if (ret < 0)
919 return ret;
920
921 /* First time */
922 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
923 if (ret < 0)
924 return ret;
925
926 while ((mf.width > 2560 || mf.height > 1920) && shift < 4) {
927 /* Try 2560x1920, 1280x960, 640x480, 320x240 */
928 mf.width = 2560 >> shift;
929 mf.height = 1920 >> shift;
930 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
931 if (ret < 0)
932 return ret;
933 shift++;
934 }
935
936 if (shift == 4) {
937 dev_err(dev, "Failed to configure the client below %ux%x\n",
938 mf.width, mf.height);
939 return -EIO;
940 }
941
942 dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);
943
897 cam = kzalloc(sizeof(*cam), GFP_KERNEL); 944 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
898 if (!cam) 945 if (!cam)
899 return -ENOMEM; 946 return -ENOMEM;
900 947
948 /* We are called with current camera crop, initialise subrect with it */
949 cam->rect = rect;
950 cam->subrect = rect;
951
952 cam->width = mf.width;
953 cam->height = mf.height;
954
955 cam->width = mf.width;
956 cam->height = mf.height;
957
901 icd->host_priv = cam; 958 icd->host_priv = cam;
902 } else { 959 } else {
903 cam = icd->host_priv; 960 cam = icd->host_priv;
@@ -979,16 +1036,12 @@ static unsigned int scale_down(unsigned int size, unsigned int scale)
979 return (size * 4096 + scale / 2) / scale; 1036 return (size * 4096 + scale / 2) / scale;
980} 1037}
981 1038
982static unsigned int scale_up(unsigned int size, unsigned int scale)
983{
984 return (size * scale + 2048) / 4096;
985}
986
987static unsigned int calc_generic_scale(unsigned int input, unsigned int output) 1039static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
988{ 1040{
989 return (input * 4096 + output / 2) / output; 1041 return (input * 4096 + output / 2) / output;
990} 1042}
991 1043
1044/* Get and store current client crop */
992static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) 1045static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
993{ 1046{
994 struct v4l2_crop crop; 1047 struct v4l2_crop crop;
@@ -1007,25 +1060,51 @@ static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
1007 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1060 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1008 1061
1009 ret = v4l2_subdev_call(sd, video, cropcap, &cap); 1062 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1010 if (ret < 0) 1063 if (!ret)
1011 return ret; 1064 *rect = cap.defrect;
1012
1013 *rect = cap.defrect;
1014 1065
1015 return ret; 1066 return ret;
1016} 1067}
1017 1068
1069/* Client crop has changed, update our sub-rectangle to remain within the area */
1070static void update_subrect(struct sh_mobile_ceu_cam *cam)
1071{
1072 struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;
1073
1074 if (rect->width < subrect->width)
1075 subrect->width = rect->width;
1076
1077 if (rect->height < subrect->height)
1078 subrect->height = rect->height;
1079
1080 if (rect->left > subrect->left)
1081 subrect->left = rect->left;
1082 else if (rect->left + rect->width >
1083 subrect->left + subrect->width)
1084 subrect->left = rect->left + rect->width -
1085 subrect->width;
1086
1087 if (rect->top > subrect->top)
1088 subrect->top = rect->top;
1089 else if (rect->top + rect->height >
1090 subrect->top + subrect->height)
1091 subrect->top = rect->top + rect->height -
1092 subrect->height;
1093}
1094
1018/* 1095/*
1019 * The common for both scaling and cropping iterative approach is: 1096 * The common for both scaling and cropping iterative approach is:
1020 * 1. try if the client can produce exactly what requested by the user 1097 * 1. try if the client can produce exactly what requested by the user
1021 * 2. if (1) failed, try to double the client image until we get one big enough 1098 * 2. if (1) failed, try to double the client image until we get one big enough
1022 * 3. if (2) failed, try to request the maximum image 1099 * 3. if (2) failed, try to request the maximum image
1023 */ 1100 */
1024static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop, 1101static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
1025 struct v4l2_crop *cam_crop) 1102 struct v4l2_crop *cam_crop)
1026{ 1103{
1104 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1027 struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c; 1105 struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
1028 struct device *dev = sd->v4l2_dev->dev; 1106 struct device *dev = sd->v4l2_dev->dev;
1107 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1029 struct v4l2_cropcap cap; 1108 struct v4l2_cropcap cap;
1030 int ret; 1109 int ret;
1031 unsigned int width, height; 1110 unsigned int width, height;
@@ -1041,13 +1120,14 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
1041 */ 1120 */
1042 if (!memcmp(rect, cam_rect, sizeof(*rect))) { 1121 if (!memcmp(rect, cam_rect, sizeof(*rect))) {
1043 /* Even if camera S_CROP failed, but camera rectangle matches */ 1122 /* Even if camera S_CROP failed, but camera rectangle matches */
1044 dev_dbg(dev, "Camera S_CROP successful for %ux%u@%u:%u\n", 1123 dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
1045 rect->width, rect->height, rect->left, rect->top); 1124 rect->width, rect->height, rect->left, rect->top);
1125 cam->rect = *cam_rect;
1046 return 0; 1126 return 0;
1047 } 1127 }
1048 1128
1049 /* Try to fix cropping, that camera hasn't managed to set */ 1129 /* Try to fix cropping, that camera hasn't managed to set */
1050 dev_geo(dev, "Fix camera S_CROP for %ux%u@%u:%u to %ux%u@%u:%u\n", 1130 dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
1051 cam_rect->width, cam_rect->height, 1131 cam_rect->width, cam_rect->height,
1052 cam_rect->left, cam_rect->top, 1132 cam_rect->left, cam_rect->top,
1053 rect->width, rect->height, rect->left, rect->top); 1133 rect->width, rect->height, rect->left, rect->top);
@@ -1057,6 +1137,7 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
1057 if (ret < 0) 1137 if (ret < 0)
1058 return ret; 1138 return ret;
1059 1139
1140 /* Put user requested rectangle within sensor bounds */
1060 soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2, 1141 soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
1061 cap.bounds.width); 1142 cap.bounds.width);
1062 soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4, 1143 soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
@@ -1069,6 +1150,10 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
1069 width = max(cam_rect->width, 2); 1150 width = max(cam_rect->width, 2);
1070 height = max(cam_rect->height, 2); 1151 height = max(cam_rect->height, 2);
1071 1152
1153 /*
1154 * Loop as long as sensor is not covering the requested rectangle and
1155 * is still within its bounds
1156 */
1072 while (!ret && (is_smaller(cam_rect, rect) || 1157 while (!ret && (is_smaller(cam_rect, rect) ||
1073 is_inside(cam_rect, rect)) && 1158 is_inside(cam_rect, rect)) &&
1074 (cap.bounds.width > width || cap.bounds.height > height)) { 1159 (cap.bounds.width > width || cap.bounds.height > height)) {
@@ -1086,6 +1171,7 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
1086 * target left, set it to the middle point between the current 1171 * target left, set it to the middle point between the current
1087 * left and minimum left. But that would add too much 1172 * left and minimum left. But that would add too much
1088 * complexity: we would have to iterate each border separately. 1173 * complexity: we would have to iterate each border separately.
1174 * Instead we just drop to the left and top bounds.
1089 */ 1175 */
1090 if (cam_rect->left > rect->left) 1176 if (cam_rect->left > rect->left)
1091 cam_rect->left = cap.bounds.left; 1177 cam_rect->left = cap.bounds.left;
@@ -1103,7 +1189,7 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
1103 1189
1104 v4l2_subdev_call(sd, video, s_crop, cam_crop); 1190 v4l2_subdev_call(sd, video, s_crop, cam_crop);
1105 ret = client_g_rect(sd, cam_rect); 1191 ret = client_g_rect(sd, cam_rect);
1106 dev_geo(dev, "Camera S_CROP %d for %ux%u@%u:%u\n", ret, 1192 dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
1107 cam_rect->width, cam_rect->height, 1193 cam_rect->width, cam_rect->height,
1108 cam_rect->left, cam_rect->top); 1194 cam_rect->left, cam_rect->top);
1109 } 1195 }
@@ -1117,82 +1203,24 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
1117 *cam_rect = cap.bounds; 1203 *cam_rect = cap.bounds;
1118 v4l2_subdev_call(sd, video, s_crop, cam_crop); 1204 v4l2_subdev_call(sd, video, s_crop, cam_crop);
1119 ret = client_g_rect(sd, cam_rect); 1205 ret = client_g_rect(sd, cam_rect);
1120 dev_geo(dev, "Camera S_CROP %d for max %ux%u@%u:%u\n", ret, 1206 dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
1121 cam_rect->width, cam_rect->height, 1207 cam_rect->width, cam_rect->height,
1122 cam_rect->left, cam_rect->top); 1208 cam_rect->left, cam_rect->top);
1123 } 1209 }
1124 1210
1125 return ret; 1211 if (!ret) {
1126} 1212 cam->rect = *cam_rect;
1127 1213 update_subrect(cam);
1128static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect,
1129 unsigned int *scale_h, unsigned int *scale_v)
1130{
1131 struct v4l2_mbus_framefmt mf;
1132 int ret;
1133
1134 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1135 if (ret < 0)
1136 return ret;
1137
1138 *scale_h = calc_generic_scale(rect->width, mf.width);
1139 *scale_v = calc_generic_scale(rect->height, mf.height);
1140
1141 return 0;
1142}
1143
1144static int get_camera_subwin(struct soc_camera_device *icd,
1145 struct v4l2_rect *cam_subrect,
1146 unsigned int cam_hscale, unsigned int cam_vscale)
1147{
1148 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1149 struct v4l2_rect *ceu_rect = &cam->ceu_rect;
1150
1151 if (!ceu_rect->width) {
1152 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1153 struct device *dev = icd->dev.parent;
1154 struct v4l2_mbus_framefmt mf;
1155 int ret;
1156 /* First time */
1157
1158 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1159 if (ret < 0)
1160 return ret;
1161
1162 dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);
1163
1164 if (mf.width > 2560) {
1165 ceu_rect->width = 2560;
1166 ceu_rect->left = (mf.width - 2560) / 2;
1167 } else {
1168 ceu_rect->width = mf.width;
1169 ceu_rect->left = 0;
1170 }
1171
1172 if (mf.height > 1920) {
1173 ceu_rect->height = 1920;
1174 ceu_rect->top = (mf.height - 1920) / 2;
1175 } else {
1176 ceu_rect->height = mf.height;
1177 ceu_rect->top = 0;
1178 }
1179
1180 dev_geo(dev, "initialised CEU rect %ux%u@%u:%u\n",
1181 ceu_rect->width, ceu_rect->height,
1182 ceu_rect->left, ceu_rect->top);
1183 } 1214 }
1184 1215
1185 cam_subrect->width = scale_up(ceu_rect->width, cam_hscale); 1216 return ret;
1186 cam_subrect->left = scale_up(ceu_rect->left, cam_hscale);
1187 cam_subrect->height = scale_up(ceu_rect->height, cam_vscale);
1188 cam_subrect->top = scale_up(ceu_rect->top, cam_vscale);
1189
1190 return 0;
1191} 1217}
1192 1218
1219/* Iterative s_mbus_fmt, also updates cached client crop on success */
1193static int client_s_fmt(struct soc_camera_device *icd, 1220static int client_s_fmt(struct soc_camera_device *icd,
1194 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1221 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
1195{ 1222{
1223 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1196 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1224 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1197 struct device *dev = icd->dev.parent; 1225 struct device *dev = icd->dev.parent;
1198 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; 1226 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
@@ -1200,6 +1228,15 @@ static int client_s_fmt(struct soc_camera_device *icd,
1200 struct v4l2_cropcap cap; 1228 struct v4l2_cropcap cap;
1201 int ret; 1229 int ret;
1202 1230
1231 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf);
1232 if (ret < 0)
1233 return ret;
1234
1235 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
1236
1237 if ((width == mf->width && height == mf->height) || !ceu_can_scale)
1238 goto update_cache;
1239
1203 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1240 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1204 1241
1205 ret = v4l2_subdev_call(sd, video, cropcap, &cap); 1242 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
@@ -1209,15 +1246,6 @@ static int client_s_fmt(struct soc_camera_device *icd,
1209 max_width = min(cap.bounds.width, 2560); 1246 max_width = min(cap.bounds.width, 2560);
1210 max_height = min(cap.bounds.height, 1920); 1247 max_height = min(cap.bounds.height, 1920);
1211 1248
1212 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf);
1213 if (ret < 0)
1214 return ret;
1215
1216 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
1217
1218 if ((width == mf->width && height == mf->height) || !ceu_can_scale)
1219 return 0;
1220
1221 /* Camera set a format, but geometry is not precise, try to improve */ 1249 /* Camera set a format, but geometry is not precise, try to improve */
1222 tmp_w = mf->width; 1250 tmp_w = mf->width;
1223 tmp_h = mf->height; 1251 tmp_h = mf->height;
@@ -1239,26 +1267,37 @@ static int client_s_fmt(struct soc_camera_device *icd,
1239 } 1267 }
1240 } 1268 }
1241 1269
1270update_cache:
1271 /* Update cache */
1272 ret = client_g_rect(sd, &cam->rect);
1273 if (ret < 0)
1274 return ret;
1275
1276 update_subrect(cam);
1277
1242 return 0; 1278 return 0;
1243} 1279}
1244 1280
1245/** 1281/**
1246 * @rect - camera cropped rectangle 1282 * @width - on output: user width, mapped back to input
1247 * @sub_rect - CEU cropped rectangle, mapped back to camera input area 1283 * @height - on output: user height, mapped back to input
1248 * @ceu_rect - on output calculated CEU crop rectangle 1284 * @mf - in- / output camera output window
1249 */ 1285 */
1250static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, 1286static int client_scale(struct soc_camera_device *icd,
1251 struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect, 1287 struct v4l2_mbus_framefmt *mf,
1252 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1288 unsigned int *width, unsigned int *height,
1289 bool ceu_can_scale)
1253{ 1290{
1254 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1255 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1291 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1256 struct device *dev = icd->dev.parent; 1292 struct device *dev = icd->dev.parent;
1257 struct v4l2_mbus_framefmt mf_tmp = *mf; 1293 struct v4l2_mbus_framefmt mf_tmp = *mf;
1258 unsigned int scale_h, scale_v; 1294 unsigned int scale_h, scale_v;
1259 int ret; 1295 int ret;
1260 1296
1261 /* 5. Apply iterative camera S_FMT for camera user window. */ 1297 /*
1298 * 5. Apply iterative camera S_FMT for camera user window (also updates
1299 * client crop cache and the imaginary sub-rectangle).
1300 */
1262 ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale); 1301 ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
1263 if (ret < 0) 1302 if (ret < 0)
1264 return ret; 1303 return ret;
@@ -1270,60 +1309,22 @@ static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
1270 1309
1271 /* unneeded - it is already in "mf_tmp" */ 1310 /* unneeded - it is already in "mf_tmp" */
1272 1311
1273 /* 7. Calculate new camera scales. */ 1312 /* 7. Calculate new client scales. */
1274 ret = get_camera_scales(sd, rect, &scale_h, &scale_v); 1313 scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
1275 if (ret < 0) 1314 scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
1276 return ret;
1277
1278 dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v);
1279 1315
1280 cam->cam_width = mf_tmp.width;
1281 cam->cam_height = mf_tmp.height;
1282 mf->width = mf_tmp.width; 1316 mf->width = mf_tmp.width;
1283 mf->height = mf_tmp.height; 1317 mf->height = mf_tmp.height;
1284 mf->colorspace = mf_tmp.colorspace; 1318 mf->colorspace = mf_tmp.colorspace;
1285 1319
1286 /* 1320 /*
1287 * 8. Calculate new CEU crop - apply camera scales to previously 1321 * 8. Calculate new CEU crop - apply camera scales to previously
1288 * calculated "effective" crop. 1322 * updated "effective" crop.
1289 */ 1323 */
1290 ceu_rect->left = scale_down(sub_rect->left, scale_h); 1324 *width = scale_down(cam->subrect.width, scale_h);
1291 ceu_rect->width = scale_down(sub_rect->width, scale_h); 1325 *height = scale_down(cam->subrect.height, scale_v);
1292 ceu_rect->top = scale_down(sub_rect->top, scale_v);
1293 ceu_rect->height = scale_down(sub_rect->height, scale_v);
1294 1326
1295 dev_geo(dev, "8: new CEU rect %ux%u@%u:%u\n", 1327 dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
1296 ceu_rect->width, ceu_rect->height,
1297 ceu_rect->left, ceu_rect->top);
1298
1299 return 0;
1300}
1301
1302/* Get combined scales */
1303static int get_scales(struct soc_camera_device *icd,
1304 unsigned int *scale_h, unsigned int *scale_v)
1305{
1306 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1307 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1308 struct v4l2_crop cam_crop;
1309 unsigned int width_in, height_in;
1310 int ret;
1311
1312 cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1313
1314 ret = client_g_rect(sd, &cam_crop.c);
1315 if (ret < 0)
1316 return ret;
1317
1318 ret = get_camera_scales(sd, &cam_crop.c, scale_h, scale_v);
1319 if (ret < 0)
1320 return ret;
1321
1322 width_in = scale_up(cam->ceu_rect.width, *scale_h);
1323 height_in = scale_up(cam->ceu_rect.height, *scale_v);
1324
1325 *scale_h = calc_generic_scale(width_in, icd->user_width);
1326 *scale_v = calc_generic_scale(height_in, icd->user_height);
1327 1328
1328 return 0; 1329 return 0;
1329} 1330}
@@ -1342,115 +1343,165 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1342 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1343 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1343 struct v4l2_crop cam_crop; 1344 struct v4l2_crop cam_crop;
1344 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1345 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1345 struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect; 1346 struct v4l2_rect *cam_rect = &cam_crop.c;
1346 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1347 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1347 struct device *dev = icd->dev.parent; 1348 struct device *dev = icd->dev.parent;
1348 struct v4l2_mbus_framefmt mf; 1349 struct v4l2_mbus_framefmt mf;
1349 unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v, 1350 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
1350 out_width, out_height; 1351 out_width, out_height, scale_h, scale_v;
1352 int interm_width, interm_height;
1351 u32 capsr, cflcr; 1353 u32 capsr, cflcr;
1352 int ret; 1354 int ret;
1353 1355
1354 /* 1. Calculate current combined scales. */ 1356 dev_geo(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1355 ret = get_scales(icd, &scale_comb_h, &scale_comb_v); 1357 rect->left, rect->top);
1356 if (ret < 0)
1357 return ret;
1358 1358
1359 dev_geo(dev, "1: combined scales %u:%u\n", scale_comb_h, scale_comb_v); 1359 /* During camera cropping its output window can change too, stop CEU */
1360 capsr = capture_save_reset(pcdev);
1361 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1360 1362
1361 /* 2. Apply iterative camera S_CROP for new input window. */ 1363 /* 1. - 2. Apply iterative camera S_CROP for new input window. */
1362 ret = client_s_crop(sd, a, &cam_crop); 1364 ret = client_s_crop(icd, a, &cam_crop);
1363 if (ret < 0) 1365 if (ret < 0)
1364 return ret; 1366 return ret;
1365 1367
1366 dev_geo(dev, "2: camera cropped to %ux%u@%u:%u\n", 1368 dev_geo(dev, "1-2: camera cropped to %ux%u@%u:%u\n",
1367 cam_rect->width, cam_rect->height, 1369 cam_rect->width, cam_rect->height,
1368 cam_rect->left, cam_rect->top); 1370 cam_rect->left, cam_rect->top);
1369 1371
1370 /* On success cam_crop contains current camera crop */ 1372 /* On success cam_crop contains current camera crop */
1371 1373
1372 /* 1374 /* 3. Retrieve camera output window */
1373 * 3. If old combined scales applied to new crop produce an impossible 1375 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1374 * user window, adjust scales to produce nearest possible window. 1376 if (ret < 0)
1375 */ 1377 return ret;
1376 out_width = scale_down(rect->width, scale_comb_h);
1377 out_height = scale_down(rect->height, scale_comb_v);
1378
1379 if (out_width > 2560)
1380 out_width = 2560;
1381 else if (out_width < 2)
1382 out_width = 2;
1383
1384 if (out_height > 1920)
1385 out_height = 1920;
1386 else if (out_height < 4)
1387 out_height = 4;
1388
1389 dev_geo(dev, "3: Adjusted output %ux%u\n", out_width, out_height);
1390
1391 /* 4. Use G_CROP to retrieve actual input window: already in cam_crop */
1392
1393 /*
1394 * 5. Using actual input window and calculated combined scales calculate
1395 * camera target output window.
1396 */
1397 mf.width = scale_down(cam_rect->width, scale_comb_h);
1398 mf.height = scale_down(cam_rect->height, scale_comb_v);
1399
1400 dev_geo(dev, "5: camera target %ux%u\n", mf.width, mf.height);
1401
1402 /* 6. - 9. */
1403 mf.code = cam->code;
1404 mf.field = pcdev->field;
1405
1406 capsr = capture_save_reset(pcdev);
1407 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1408 1378
1409 /* Make relative to camera rectangle */ 1379 if (mf.width > 2560 || mf.height > 1920)
1410 rect->left -= cam_rect->left; 1380 return -EINVAL;
1411 rect->top -= cam_rect->top;
1412 1381
1413 ret = client_scale(icd, cam_rect, rect, ceu_rect, &mf, 1382 /* Cache camera output window */
1414 pcdev->image_mode && 1383 cam->width = mf.width;
1415 V4L2_FIELD_NONE == pcdev->field); 1384 cam->height = mf.height;
1416 1385
1417 dev_geo(dev, "6-9: %d\n", ret); 1386 /* 4. Calculate camera scales */
1387 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1388 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
1418 1389
1419 /* 10. Use CEU cropping to crop to the new window. */ 1390 /* Calculate intermediate window */
1420 sh_mobile_ceu_set_rect(icd, out_width, out_height); 1391 interm_width = scale_down(rect->width, scale_cam_h);
1392 interm_height = scale_down(rect->height, scale_cam_v);
1421 1393
1422 dev_geo(dev, "10: CEU cropped to %ux%u@%u:%u\n", 1394 if (pcdev->image_mode) {
1423 ceu_rect->width, ceu_rect->height, 1395 out_width = min(interm_width, icd->user_width);
1424 ceu_rect->left, ceu_rect->top); 1396 out_height = min(interm_height, icd->user_height);
1397 } else {
1398 out_width = interm_width;
1399 out_height = interm_height;
1400 }
1425 1401
1426 /* 1402 /*
1427 * 11. Calculate CEU scales from camera scales from results of (10) and 1403 * 5. Calculate CEU scales from camera scales from results of (5) and
1428 * user window from (3) 1404 * the user window
1429 */ 1405 */
1430 scale_ceu_h = calc_scale(ceu_rect->width, &out_width); 1406 scale_ceu_h = calc_scale(interm_width, &out_width);
1431 scale_ceu_v = calc_scale(ceu_rect->height, &out_height); 1407 scale_ceu_v = calc_scale(interm_height, &out_height);
1432 1408
1433 dev_geo(dev, "11: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v); 1409 /* Calculate camera scales */
1410 scale_h = calc_generic_scale(cam_rect->width, out_width);
1411 scale_v = calc_generic_scale(cam_rect->height, out_height);
1434 1412
1435 /* 12. Apply CEU scales. */ 1413 dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
1414
1415 /* Apply CEU scales. */
1436 cflcr = scale_ceu_h | (scale_ceu_v << 16); 1416 cflcr = scale_ceu_h | (scale_ceu_v << 16);
1437 if (cflcr != pcdev->cflcr) { 1417 if (cflcr != pcdev->cflcr) {
1438 pcdev->cflcr = cflcr; 1418 pcdev->cflcr = cflcr;
1439 ceu_write(pcdev, CFLCR, cflcr); 1419 ceu_write(pcdev, CFLCR, cflcr);
1440 } 1420 }
1441 1421
1422 icd->user_width = out_width;
1423 icd->user_height = out_height;
1424 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_h) & ~1;
1425 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_v) & ~1;
1426
1427 /* 6. Use CEU cropping to crop to the new window. */
1428 sh_mobile_ceu_set_rect(icd);
1429
1430 cam->subrect = *rect;
1431
1432 dev_geo(dev, "6: CEU cropped to %ux%u@%u:%u\n",
1433 icd->user_width, icd->user_height,
1434 cam->ceu_left, cam->ceu_top);
1435
1442 /* Restore capture */ 1436 /* Restore capture */
1443 if (pcdev->active) 1437 if (pcdev->active)
1444 capsr |= 1; 1438 capsr |= 1;
1445 capture_restore(pcdev, capsr); 1439 capture_restore(pcdev, capsr);
1446 1440
1447 icd->user_width = out_width;
1448 icd->user_height = out_height;
1449
1450 /* Even if only camera cropping succeeded */ 1441 /* Even if only camera cropping succeeded */
1451 return ret; 1442 return ret;
1452} 1443}
1453 1444
1445static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
1446 struct v4l2_crop *a)
1447{
1448 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1449
1450 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1451 a->c = cam->subrect;
1452
1453 return 0;
1454}
1455
1456/*
1457 * Calculate real client output window by applying new scales to the current
1458 * client crop. New scales are calculated from the requested output format and
1459 * CEU crop, mapped backed onto the client input (subrect).
1460 */
1461static void calculate_client_output(struct soc_camera_device *icd,
1462 struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
1463{
1464 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1465 struct device *dev = icd->dev.parent;
1466 struct v4l2_rect *cam_subrect = &cam->subrect;
1467 unsigned int scale_v, scale_h;
1468
1469 if (cam_subrect->width == cam->rect.width &&
1470 cam_subrect->height == cam->rect.height) {
1471 /* No sub-cropping */
1472 mf->width = pix->width;
1473 mf->height = pix->height;
1474 return;
1475 }
1476
1477 /* 1.-2. Current camera scales and subwin - cached. */
1478
1479 dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
1480 cam_subrect->width, cam_subrect->height,
1481 cam_subrect->left, cam_subrect->top);
1482
1483 /*
1484 * 3. Calculate new combined scales from input sub-window to requested
1485 * user window.
1486 */
1487
1488 /*
1489 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
1490 * (128x96) or larger than VGA
1491 */
1492 scale_h = calc_generic_scale(cam_subrect->width, pix->width);
1493 scale_v = calc_generic_scale(cam_subrect->height, pix->height);
1494
1495 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1496
1497 /*
1498 * 4. Calculate client output window by applying combined scales to real
1499 * input window.
1500 */
1501 mf->width = scale_down(cam->rect.width, scale_h);
1502 mf->height = scale_down(cam->rect.height, scale_v);
1503}
1504
1454/* Similar to set_crop multistage iterative algorithm */ 1505/* Similar to set_crop multistage iterative algorithm */
1455static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, 1506static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1456 struct v4l2_format *f) 1507 struct v4l2_format *f)
@@ -1460,18 +1511,17 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1460 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1511 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1461 struct v4l2_pix_format *pix = &f->fmt.pix; 1512 struct v4l2_pix_format *pix = &f->fmt.pix;
1462 struct v4l2_mbus_framefmt mf; 1513 struct v4l2_mbus_framefmt mf;
1463 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1464 struct device *dev = icd->dev.parent; 1514 struct device *dev = icd->dev.parent;
1465 __u32 pixfmt = pix->pixelformat; 1515 __u32 pixfmt = pix->pixelformat;
1466 const struct soc_camera_format_xlate *xlate; 1516 const struct soc_camera_format_xlate *xlate;
1467 struct v4l2_crop cam_crop; 1517 unsigned int ceu_sub_width, ceu_sub_height;
1468 struct v4l2_rect *cam_rect = &cam_crop.c, cam_subrect, ceu_rect;
1469 unsigned int scale_cam_h, scale_cam_v;
1470 u16 scale_v, scale_h; 1518 u16 scale_v, scale_h;
1471 int ret; 1519 int ret;
1472 bool image_mode; 1520 bool image_mode;
1473 enum v4l2_field field; 1521 enum v4l2_field field;
1474 1522
1523 dev_geo(dev, "S_FMT(pix=0x%x, %ux%u)\n", pixfmt, pix->width, pix->height);
1524
1475 switch (pix->field) { 1525 switch (pix->field) {
1476 default: 1526 default:
1477 pix->field = V4L2_FIELD_NONE; 1527 pix->field = V4L2_FIELD_NONE;
@@ -1492,46 +1542,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1492 return -EINVAL; 1542 return -EINVAL;
1493 } 1543 }
1494 1544
1495 /* 1. Calculate current camera scales. */ 1545 /* 1.-4. Calculate client output geometry */
1496 cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1546 calculate_client_output(icd, &f->fmt.pix, &mf);
1497
1498 ret = client_g_rect(sd, cam_rect);
1499 if (ret < 0)
1500 return ret;
1501
1502 ret = get_camera_scales(sd, cam_rect, &scale_cam_h, &scale_cam_v);
1503 if (ret < 0)
1504 return ret;
1505
1506 dev_geo(dev, "1: camera scales %u:%u\n", scale_cam_h, scale_cam_v);
1507
1508 /*
1509 * 2. Calculate "effective" input crop (sensor subwindow) - CEU crop
1510 * scaled back at current camera scales onto input window.
1511 */
1512 ret = get_camera_subwin(icd, &cam_subrect, scale_cam_h, scale_cam_v);
1513 if (ret < 0)
1514 return ret;
1515
1516 dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
1517 cam_subrect.width, cam_subrect.height,
1518 cam_subrect.left, cam_subrect.top);
1519
1520 /*
1521 * 3. Calculate new combined scales from "effective" input window to
1522 * requested user window.
1523 */
1524 scale_h = calc_generic_scale(cam_subrect.width, pix->width);
1525 scale_v = calc_generic_scale(cam_subrect.height, pix->height);
1526
1527 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1528
1529 /*
1530 * 4. Calculate camera output window by applying combined scales to real
1531 * input window.
1532 */
1533 mf.width = scale_down(cam_rect->width, scale_h);
1534 mf.height = scale_down(cam_rect->height, scale_v);
1535 mf.field = pix->field; 1547 mf.field = pix->field;
1536 mf.colorspace = pix->colorspace; 1548 mf.colorspace = pix->colorspace;
1537 mf.code = xlate->code; 1549 mf.code = xlate->code;
@@ -1547,17 +1559,17 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1547 image_mode = false; 1559 image_mode = false;
1548 } 1560 }
1549 1561
1550 dev_geo(dev, "4: camera output %ux%u\n", mf.width, mf.height); 1562 dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
1551 1563
1552 /* 5. - 9. */ 1564 /* 5. - 9. */
1553 ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &mf, 1565 ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
1554 image_mode && V4L2_FIELD_NONE == field); 1566 image_mode && V4L2_FIELD_NONE == field);
1555 1567
1556 dev_geo(dev, "5-9: client scale %d\n", ret); 1568 dev_geo(dev, "5-9: client scale return %d\n", ret);
1557 1569
1558 /* Done with the camera. Now see if we can improve the result */ 1570 /* Done with the camera. Now see if we can improve the result */
1559 1571
1560 dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n", 1572 dev_geo(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1561 ret, mf.width, mf.height, pix->width, pix->height); 1573 ret, mf.width, mf.height, pix->width, pix->height);
1562 if (ret < 0) 1574 if (ret < 0)
1563 return ret; 1575 return ret;
@@ -1565,40 +1577,44 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1565 if (mf.code != xlate->code) 1577 if (mf.code != xlate->code)
1566 return -EINVAL; 1578 return -EINVAL;
1567 1579
1580 /* 9. Prepare CEU crop */
1581 cam->width = mf.width;
1582 cam->height = mf.height;
1583
1568 /* 10. Use CEU scaling to scale to the requested user window. */ 1584 /* 10. Use CEU scaling to scale to the requested user window. */
1569 1585
1570 /* We cannot scale up */ 1586 /* We cannot scale up */
1571 if (pix->width > mf.width) 1587 if (pix->width > ceu_sub_width)
1572 pix->width = mf.width; 1588 ceu_sub_width = pix->width;
1573 if (pix->width > ceu_rect.width)
1574 pix->width = ceu_rect.width;
1575 1589
1576 if (pix->height > mf.height) 1590 if (pix->height > ceu_sub_height)
1577 pix->height = mf.height; 1591 ceu_sub_height = pix->height;
1578 if (pix->height > ceu_rect.height)
1579 pix->height = ceu_rect.height;
1580 1592
1581 pix->colorspace = mf.colorspace; 1593 pix->colorspace = mf.colorspace;
1582 1594
1583 if (image_mode) { 1595 if (image_mode) {
1584 /* Scale pix->{width x height} down to width x height */ 1596 /* Scale pix->{width x height} down to width x height */
1585 scale_h = calc_scale(ceu_rect.width, &pix->width); 1597 scale_h = calc_scale(ceu_sub_width, &pix->width);
1586 scale_v = calc_scale(ceu_rect.height, &pix->height); 1598 scale_v = calc_scale(ceu_sub_height, &pix->height);
1587
1588 pcdev->cflcr = scale_h | (scale_v << 16);
1589 } else { 1599 } else {
1590 pix->width = ceu_rect.width; 1600 pix->width = ceu_sub_width;
1591 pix->height = ceu_rect.height; 1601 pix->height = ceu_sub_height;
1592 scale_h = scale_v = 0; 1602 scale_h = 0;
1593 pcdev->cflcr = 0; 1603 scale_v = 0;
1594 } 1604 }
1595 1605
1606 pcdev->cflcr = scale_h | (scale_v << 16);
1607
1608 /*
1609 * We have calculated CFLCR, the actual configuration will be performed
1610 * in sh_mobile_ceu_set_bus_param()
1611 */
1612
1596 dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n", 1613 dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
1597 ceu_rect.width, scale_h, pix->width, 1614 ceu_sub_width, scale_h, pix->width,
1598 ceu_rect.height, scale_v, pix->height); 1615 ceu_sub_height, scale_v, pix->height);
1599 1616
1600 cam->code = xlate->code; 1617 cam->code = xlate->code;
1601 cam->ceu_rect = ceu_rect;
1602 icd->current_fmt = xlate; 1618 icd->current_fmt = xlate;
1603 1619
1604 pcdev->field = field; 1620 pcdev->field = field;
@@ -1820,6 +1836,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1820 .remove = sh_mobile_ceu_remove_device, 1836 .remove = sh_mobile_ceu_remove_device,
1821 .get_formats = sh_mobile_ceu_get_formats, 1837 .get_formats = sh_mobile_ceu_get_formats,
1822 .put_formats = sh_mobile_ceu_put_formats, 1838 .put_formats = sh_mobile_ceu_put_formats,
1839 .get_crop = sh_mobile_ceu_get_crop,
1823 .set_crop = sh_mobile_ceu_set_crop, 1840 .set_crop = sh_mobile_ceu_set_crop,
1824 .set_fmt = sh_mobile_ceu_set_fmt, 1841 .set_fmt = sh_mobile_ceu_set_fmt,
1825 .try_fmt = sh_mobile_ceu_try_fmt, 1842 .try_fmt = sh_mobile_ceu_try_fmt,
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
new file mode 100644
index 000000000000..f5b892a2a8ee
--- /dev/null
+++ b/drivers/media/video/sh_vou.c
@@ -0,0 +1,1476 @@
1/*
2 * SuperH Video Output Unit (VOU) driver
3 *
4 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/dma-mapping.h>
12#include <linux/delay.h>
13#include <linux/errno.h>
14#include <linux/fs.h>
15#include <linux/i2c.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/platform_device.h>
20#include <linux/pm_runtime.h>
21#include <linux/version.h>
22#include <linux/videodev2.h>
23
24#include <media/sh_vou.h>
25#include <media/v4l2-common.h>
26#include <media/v4l2-device.h>
27#include <media/v4l2-ioctl.h>
28#include <media/v4l2-mediabus.h>
29#include <media/videobuf-dma-contig.h>
30
31/* Mirror addresses are not available for all registers */
32#define VOUER 0
33#define VOUCR 4
34#define VOUSTR 8
35#define VOUVCR 0xc
36#define VOUISR 0x10
37#define VOUBCR 0x14
38#define VOUDPR 0x18
39#define VOUDSR 0x1c
40#define VOUVPR 0x20
41#define VOUIR 0x24
42#define VOUSRR 0x28
43#define VOUMSR 0x2c
44#define VOUHIR 0x30
45#define VOUDFR 0x34
46#define VOUAD1R 0x38
47#define VOUAD2R 0x3c
48#define VOUAIR 0x40
49#define VOUSWR 0x44
50#define VOURCR 0x48
51#define VOURPR 0x50
52
53enum sh_vou_status {
54 SH_VOU_IDLE,
55 SH_VOU_INITIALISING,
56 SH_VOU_RUNNING,
57};
58
59#define VOU_MAX_IMAGE_WIDTH 720
60#define VOU_MAX_IMAGE_HEIGHT 480
61
62struct sh_vou_device {
63 struct v4l2_device v4l2_dev;
64 struct video_device *vdev;
65 atomic_t use_count;
66 struct sh_vou_pdata *pdata;
67 spinlock_t lock;
68 void __iomem *base;
69 /* State information */
70 struct v4l2_pix_format pix;
71 struct v4l2_rect rect;
72 struct list_head queue;
73 v4l2_std_id std;
74 int pix_idx;
75 struct videobuf_buffer *active;
76 enum sh_vou_status status;
77};
78
79struct sh_vou_file {
80 struct videobuf_queue vbq;
81};
82
83/* Register access routines for sides A, B and mirror addresses */
84static void sh_vou_reg_a_write(struct sh_vou_device *vou_dev, unsigned int reg,
85 u32 value)
86{
87 __raw_writel(value, vou_dev->base + reg);
88}
89
90static void sh_vou_reg_ab_write(struct sh_vou_device *vou_dev, unsigned int reg,
91 u32 value)
92{
93 __raw_writel(value, vou_dev->base + reg);
94 __raw_writel(value, vou_dev->base + reg + 0x1000);
95}
96
97static void sh_vou_reg_m_write(struct sh_vou_device *vou_dev, unsigned int reg,
98 u32 value)
99{
100 __raw_writel(value, vou_dev->base + reg + 0x2000);
101}
102
103static u32 sh_vou_reg_a_read(struct sh_vou_device *vou_dev, unsigned int reg)
104{
105 return __raw_readl(vou_dev->base + reg);
106}
107
108static void sh_vou_reg_a_set(struct sh_vou_device *vou_dev, unsigned int reg,
109 u32 value, u32 mask)
110{
111 u32 old = __raw_readl(vou_dev->base + reg);
112
113 value = (value & mask) | (old & ~mask);
114 __raw_writel(value, vou_dev->base + reg);
115}
116
117static void sh_vou_reg_b_set(struct sh_vou_device *vou_dev, unsigned int reg,
118 u32 value, u32 mask)
119{
120 sh_vou_reg_a_set(vou_dev, reg + 0x1000, value, mask);
121}
122
123static void sh_vou_reg_ab_set(struct sh_vou_device *vou_dev, unsigned int reg,
124 u32 value, u32 mask)
125{
126 sh_vou_reg_a_set(vou_dev, reg, value, mask);
127 sh_vou_reg_b_set(vou_dev, reg, value, mask);
128}
129
130struct sh_vou_fmt {
131 u32 pfmt;
132 char *desc;
133 unsigned char bpp;
134 unsigned char rgb;
135 unsigned char yf;
136 unsigned char pkf;
137};
138
139/* Further pixel formats can be added */
140static struct sh_vou_fmt vou_fmt[] = {
141 {
142 .pfmt = V4L2_PIX_FMT_NV12,
143 .bpp = 12,
144 .desc = "YVU420 planar",
145 .yf = 0,
146 .rgb = 0,
147 },
148 {
149 .pfmt = V4L2_PIX_FMT_NV16,
150 .bpp = 16,
151 .desc = "YVYU planar",
152 .yf = 1,
153 .rgb = 0,
154 },
155 {
156 .pfmt = V4L2_PIX_FMT_RGB24,
157 .bpp = 24,
158 .desc = "RGB24",
159 .pkf = 2,
160 .rgb = 1,
161 },
162 {
163 .pfmt = V4L2_PIX_FMT_RGB565,
164 .bpp = 16,
165 .desc = "RGB565",
166 .pkf = 3,
167 .rgb = 1,
168 },
169 {
170 .pfmt = V4L2_PIX_FMT_RGB565X,
171 .bpp = 16,
172 .desc = "RGB565 byteswapped",
173 .pkf = 3,
174 .rgb = 1,
175 },
176};
177
178static void sh_vou_schedule_next(struct sh_vou_device *vou_dev,
179 struct videobuf_buffer *vb)
180{
181 dma_addr_t addr1, addr2;
182
183 addr1 = videobuf_to_dma_contig(vb);
184 switch (vou_dev->pix.pixelformat) {
185 case V4L2_PIX_FMT_NV12:
186 case V4L2_PIX_FMT_NV16:
187 addr2 = addr1 + vou_dev->pix.width * vou_dev->pix.height;
188 break;
189 default:
190 addr2 = 0;
191 }
192
193 sh_vou_reg_m_write(vou_dev, VOUAD1R, addr1);
194 sh_vou_reg_m_write(vou_dev, VOUAD2R, addr2);
195}
196
197static void sh_vou_stream_start(struct sh_vou_device *vou_dev,
198 struct videobuf_buffer *vb)
199{
200 unsigned int row_coeff;
201#ifdef __LITTLE_ENDIAN
202 u32 dataswap = 7;
203#else
204 u32 dataswap = 0;
205#endif
206
207 switch (vou_dev->pix.pixelformat) {
208 case V4L2_PIX_FMT_NV12:
209 case V4L2_PIX_FMT_NV16:
210 row_coeff = 1;
211 break;
212 case V4L2_PIX_FMT_RGB565:
213 dataswap ^= 1;
214 case V4L2_PIX_FMT_RGB565X:
215 row_coeff = 2;
216 break;
217 case V4L2_PIX_FMT_RGB24:
218 row_coeff = 3;
219 break;
220 }
221
222 sh_vou_reg_a_write(vou_dev, VOUSWR, dataswap);
223 sh_vou_reg_ab_write(vou_dev, VOUAIR, vou_dev->pix.width * row_coeff);
224 sh_vou_schedule_next(vou_dev, vb);
225}
226
227static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
228{
229 BUG_ON(in_interrupt());
230
231 /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */
232 videobuf_waiton(vb, 0, 0);
233 videobuf_dma_contig_free(vq, vb);
234 vb->state = VIDEOBUF_NEEDS_INIT;
235}
236
237/* Locking: caller holds vq->vb_lock mutex */
238static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
239 unsigned int *size)
240{
241 struct video_device *vdev = vq->priv_data;
242 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
243
244 *size = vou_fmt[vou_dev->pix_idx].bpp * vou_dev->pix.width *
245 vou_dev->pix.height / 8;
246
247 if (*count < 2)
248 *count = 2;
249
250 /* Taking into account maximum frame size, *count will stay >= 2 */
251 if (PAGE_ALIGN(*size) * *count > 4 * 1024 * 1024)
252 *count = 4 * 1024 * 1024 / PAGE_ALIGN(*size);
253
254 dev_dbg(vq->dev, "%s(): count=%d, size=%d\n", __func__, *count, *size);
255
256 return 0;
257}
258
259/* Locking: caller holds vq->vb_lock mutex */
260static int sh_vou_buf_prepare(struct videobuf_queue *vq,
261 struct videobuf_buffer *vb,
262 enum v4l2_field field)
263{
264 struct video_device *vdev = vq->priv_data;
265 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
266 struct v4l2_pix_format *pix = &vou_dev->pix;
267 int bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
268 int ret;
269
270 dev_dbg(vq->dev, "%s()\n", __func__);
271
272 if (vb->width != pix->width ||
273 vb->height != pix->height ||
274 vb->field != pix->field) {
275 vb->width = pix->width;
276 vb->height = pix->height;
277 vb->field = field;
278 if (vb->state != VIDEOBUF_NEEDS_INIT)
279 free_buffer(vq, vb);
280 }
281
282 vb->size = vb->height * bytes_per_line;
283 if (vb->baddr && vb->bsize < vb->size) {
284 /* User buffer too small */
285 dev_warn(vq->dev, "User buffer too small: [%u] @ %lx\n",
286 vb->bsize, vb->baddr);
287 return -EINVAL;
288 }
289
290 if (vb->state == VIDEOBUF_NEEDS_INIT) {
291 ret = videobuf_iolock(vq, vb, NULL);
292 if (ret < 0) {
293 dev_warn(vq->dev, "IOLOCK buf-type %d: %d\n",
294 vb->memory, ret);
295 return ret;
296 }
297 vb->state = VIDEOBUF_PREPARED;
298 }
299
300 dev_dbg(vq->dev,
301 "%s(): fmt #%d, %u bytes per line, phys 0x%x, type %d, state %d\n",
302 __func__, vou_dev->pix_idx, bytes_per_line,
303 videobuf_to_dma_contig(vb), vb->memory, vb->state);
304
305 return 0;
306}
307
308/* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */
309static void sh_vou_buf_queue(struct videobuf_queue *vq,
310 struct videobuf_buffer *vb)
311{
312 struct video_device *vdev = vq->priv_data;
313 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
314
315 dev_dbg(vq->dev, "%s()\n", __func__);
316
317 vb->state = VIDEOBUF_QUEUED;
318 list_add_tail(&vb->queue, &vou_dev->queue);
319
320 if (vou_dev->status == SH_VOU_RUNNING) {
321 return;
322 } else if (!vou_dev->active) {
323 vou_dev->active = vb;
324 /* Start from side A: we use mirror addresses, so, set B */
325 sh_vou_reg_a_write(vou_dev, VOURPR, 1);
326 dev_dbg(vq->dev, "%s: first buffer status 0x%x\n", __func__,
327 sh_vou_reg_a_read(vou_dev, VOUSTR));
328 sh_vou_schedule_next(vou_dev, vb);
329 /* Only activate VOU after the second buffer */
330 } else if (vou_dev->active->queue.next == &vb->queue) {
331 /* Second buffer - initialise register side B */
332 sh_vou_reg_a_write(vou_dev, VOURPR, 0);
333 sh_vou_stream_start(vou_dev, vb);
334
335 /* Register side switching with frame VSYNC */
336 sh_vou_reg_a_write(vou_dev, VOURCR, 5);
337 dev_dbg(vq->dev, "%s: second buffer status 0x%x\n", __func__,
338 sh_vou_reg_a_read(vou_dev, VOUSTR));
339
340 /* Enable End-of-Frame (VSYNC) interrupts */
341 sh_vou_reg_a_write(vou_dev, VOUIR, 0x10004);
342 /* Two buffers on the queue - activate the hardware */
343
344 vou_dev->status = SH_VOU_RUNNING;
345 sh_vou_reg_a_write(vou_dev, VOUER, 0x107);
346 }
347}
348
349static void sh_vou_buf_release(struct videobuf_queue *vq,
350 struct videobuf_buffer *vb)
351{
352 struct video_device *vdev = vq->priv_data;
353 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
354 unsigned long flags;
355
356 dev_dbg(vq->dev, "%s()\n", __func__);
357
358 spin_lock_irqsave(&vou_dev->lock, flags);
359
360 if (vou_dev->active == vb) {
361 /* disable output */
362 sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
363 /* ...but the current frame will complete */
364 sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
365 vou_dev->active = NULL;
366 }
367
368 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED)) {
369 vb->state = VIDEOBUF_ERROR;
370 list_del(&vb->queue);
371 }
372
373 spin_unlock_irqrestore(&vou_dev->lock, flags);
374
375 free_buffer(vq, vb);
376}
377
378static struct videobuf_queue_ops sh_vou_video_qops = {
379 .buf_setup = sh_vou_buf_setup,
380 .buf_prepare = sh_vou_buf_prepare,
381 .buf_queue = sh_vou_buf_queue,
382 .buf_release = sh_vou_buf_release,
383};
384
385/* Video IOCTLs */
386static int sh_vou_querycap(struct file *file, void *priv,
387 struct v4l2_capability *cap)
388{
389 struct sh_vou_file *vou_file = priv;
390
391 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
392
393 strlcpy(cap->card, "SuperH VOU", sizeof(cap->card));
394 cap->version = KERNEL_VERSION(0, 1, 0);
395 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
396 return 0;
397}
398
399/* Enumerate formats, that the device can accept from the user */
400static int sh_vou_enum_fmt_vid_out(struct file *file, void *priv,
401 struct v4l2_fmtdesc *fmt)
402{
403 struct sh_vou_file *vou_file = priv;
404
405 if (fmt->index >= ARRAY_SIZE(vou_fmt))
406 return -EINVAL;
407
408 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
409
410 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
411 strlcpy(fmt->description, vou_fmt[fmt->index].desc,
412 sizeof(fmt->description));
413 fmt->pixelformat = vou_fmt[fmt->index].pfmt;
414
415 return 0;
416}
417
418static int sh_vou_g_fmt_vid_out(struct file *file, void *priv,
419 struct v4l2_format *fmt)
420{
421 struct video_device *vdev = video_devdata(file);
422 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
423
424 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
425
426 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
427 fmt->fmt.pix = vou_dev->pix;
428
429 return 0;
430}
431
432static const unsigned char vou_scale_h_num[] = {1, 9, 2, 9, 4};
433static const unsigned char vou_scale_h_den[] = {1, 8, 1, 4, 1};
434static const unsigned char vou_scale_h_fld[] = {0, 2, 1, 3};
435static const unsigned char vou_scale_v_num[] = {1, 2, 4};
436static const unsigned char vou_scale_v_den[] = {1, 1, 1};
437static const unsigned char vou_scale_v_fld[] = {0, 1};
438
439static void sh_vou_configure_geometry(struct sh_vou_device *vou_dev,
440 int pix_idx, int w_idx, int h_idx)
441{
442 struct sh_vou_fmt *fmt = vou_fmt + pix_idx;
443 unsigned int black_left, black_top, width_max, height_max,
444 frame_in_height, frame_out_height, frame_out_top;
445 struct v4l2_rect *rect = &vou_dev->rect;
446 struct v4l2_pix_format *pix = &vou_dev->pix;
447 u32 vouvcr = 0, dsr_h, dsr_v;
448
449 if (vou_dev->std & V4L2_STD_525_60) {
450 width_max = 858;
451 height_max = 262;
452 } else {
453 width_max = 864;
454 height_max = 312;
455 }
456
457 frame_in_height = pix->height / 2;
458 frame_out_height = rect->height / 2;
459 frame_out_top = rect->top / 2;
460
461 /*
462 * Cropping scheme: max useful image is 720x480, and the total video
463 * area is 858x525 (NTSC) or 864x625 (PAL). AK8813 / 8814 starts
464 * sampling data beginning with fixed 276th (NTSC) / 288th (PAL) clock,
465 * of which the first 33 / 25 clocks HSYNC must be held active. This
466 * has to be configured in CR[HW]. 1 pixel equals 2 clock periods.
467 * This gives CR[HW] = 16 / 12, VPR[HVP] = 138 / 144, which gives
468 * exactly 858 - 138 = 864 - 144 = 720! We call the out-of-display area,
469 * beyond DSR, specified on the left and top by the VPR register "black
470 * pixels" and out-of-image area (DPR) "background pixels." We fix VPR
471 * at 138 / 144 : 20, because that's the HSYNC timing, that our first
472 * client requires, and that's exactly what leaves us 720 pixels for the
473 * image; we leave VPR[VVP] at default 20 for now, because the client
474 * doesn't seem to have any special requirements for it. Otherwise we
475 * could also set it to max - 240 = 22 / 72. Thus VPR depends only on
476 * the selected standard, and DPR and DSR are selected according to
477 * cropping. Q: how does the client detect the first valid line? Does
478 * HSYNC stay inactive during invalid (black) lines?
479 */
480 black_left = width_max - VOU_MAX_IMAGE_WIDTH;
481 black_top = 20;
482
483 dsr_h = rect->width + rect->left;
484 dsr_v = frame_out_height + frame_out_top;
485
486 dev_dbg(vou_dev->v4l2_dev.dev,
487 "image %ux%u, black %u:%u, offset %u:%u, display %ux%u\n",
488 pix->width, frame_in_height, black_left, black_top,
489 rect->left, frame_out_top, dsr_h, dsr_v);
490
491 /* VOUISR height - half of a frame height in frame mode */
492 sh_vou_reg_ab_write(vou_dev, VOUISR, (pix->width << 16) | frame_in_height);
493 sh_vou_reg_ab_write(vou_dev, VOUVPR, (black_left << 16) | black_top);
494 sh_vou_reg_ab_write(vou_dev, VOUDPR, (rect->left << 16) | frame_out_top);
495 sh_vou_reg_ab_write(vou_dev, VOUDSR, (dsr_h << 16) | dsr_v);
496
497 /*
498 * if necessary, we could set VOUHIR to
499 * max(black_left + dsr_h, width_max) here
500 */
501
502 if (w_idx)
503 vouvcr |= (1 << 15) | (vou_scale_h_fld[w_idx - 1] << 4);
504 if (h_idx)
505 vouvcr |= (1 << 14) | vou_scale_v_fld[h_idx - 1];
506
507 dev_dbg(vou_dev->v4l2_dev.dev, "%s: scaling 0x%x\n", fmt->desc, vouvcr);
508
509 /* To produce a colour bar for testing set bit 23 of VOUVCR */
510 sh_vou_reg_ab_write(vou_dev, VOUVCR, vouvcr);
511 sh_vou_reg_ab_write(vou_dev, VOUDFR,
512 fmt->pkf | (fmt->yf << 8) | (fmt->rgb << 16));
513}
514
515struct sh_vou_geometry {
516 struct v4l2_rect output;
517 unsigned int in_width;
518 unsigned int in_height;
519 int scale_idx_h;
520 int scale_idx_v;
521};
522
523/*
524 * Find input geometry, that we can use to produce output, closest to the
525 * requested rectangle, using VOU scaling
526 */
527static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
528{
529 /* The compiler cannot know, that best and idx will indeed be set */
530 unsigned int best_err = UINT_MAX, best = 0, width_max, height_max;
531 int i, idx = 0;
532
533 if (std & V4L2_STD_525_60) {
534 width_max = 858;
535 height_max = 262;
536 } else {
537 width_max = 864;
538 height_max = 312;
539 }
540
541 /* Image width must be a multiple of 4 */
542 v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2,
543 &geo->in_height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
544
545 /* Select scales to come as close as possible to the output image */
546 for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) {
547 unsigned int err;
548 unsigned int found = geo->output.width * vou_scale_h_den[i] /
549 vou_scale_h_num[i];
550
551 if (found > VOU_MAX_IMAGE_WIDTH)
552 /* scales increase */
553 break;
554
555 err = abs(found - geo->in_width);
556 if (err < best_err) {
557 best_err = err;
558 idx = i;
559 best = found;
560 }
561 if (!err)
562 break;
563 }
564
565 geo->in_width = best;
566 geo->scale_idx_h = idx;
567
568 best_err = UINT_MAX;
569
570 /* This loop can be replaced with one division */
571 for (i = ARRAY_SIZE(vou_scale_v_num) - 1; i >= 0; i--) {
572 unsigned int err;
573 unsigned int found = geo->output.height * vou_scale_v_den[i] /
574 vou_scale_v_num[i];
575
576 if (found > VOU_MAX_IMAGE_HEIGHT)
577 /* scales increase */
578 break;
579
580 err = abs(found - geo->in_height);
581 if (err < best_err) {
582 best_err = err;
583 idx = i;
584 best = found;
585 }
586 if (!err)
587 break;
588 }
589
590 geo->in_height = best;
591 geo->scale_idx_v = idx;
592}
593
594/*
595 * Find output geometry, that we can produce, using VOU scaling, closest to
596 * the requested rectangle
597 */
598static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std)
599{
600 unsigned int best_err = UINT_MAX, best, width_max, height_max;
601 int i, idx;
602
603 if (std & V4L2_STD_525_60) {
604 width_max = 858;
605 height_max = 262 * 2;
606 } else {
607 width_max = 864;
608 height_max = 312 * 2;
609 }
610
611 /* Select scales to come as close as possible to the output image */
612 for (i = 0; i < ARRAY_SIZE(vou_scale_h_num); i++) {
613 unsigned int err;
614 unsigned int found = geo->in_width * vou_scale_h_num[i] /
615 vou_scale_h_den[i];
616
617 if (found > VOU_MAX_IMAGE_WIDTH)
618 /* scales increase */
619 break;
620
621 err = abs(found - geo->output.width);
622 if (err < best_err) {
623 best_err = err;
624 idx = i;
625 best = found;
626 }
627 if (!err)
628 break;
629 }
630
631 geo->output.width = best;
632 geo->scale_idx_h = idx;
633 if (geo->output.left + best > width_max)
634 geo->output.left = width_max - best;
635
636 pr_debug("%s(): W %u * %u/%u = %u\n", __func__, geo->in_width,
637 vou_scale_h_num[idx], vou_scale_h_den[idx], best);
638
639 best_err = UINT_MAX;
640
641 /* This loop can be replaced with one division */
642 for (i = 0; i < ARRAY_SIZE(vou_scale_v_num); i++) {
643 unsigned int err;
644 unsigned int found = geo->in_height * vou_scale_v_num[i] /
645 vou_scale_v_den[i];
646
647 if (found > VOU_MAX_IMAGE_HEIGHT)
648 /* scales increase */
649 break;
650
651 err = abs(found - geo->output.height);
652 if (err < best_err) {
653 best_err = err;
654 idx = i;
655 best = found;
656 }
657 if (!err)
658 break;
659 }
660
661 geo->output.height = best;
662 geo->scale_idx_v = idx;
663 if (geo->output.top + best > height_max)
664 geo->output.top = height_max - best;
665
666 pr_debug("%s(): H %u * %u/%u = %u\n", __func__, geo->in_height,
667 vou_scale_v_num[idx], vou_scale_v_den[idx], best);
668}
669
670static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
671 struct v4l2_format *fmt)
672{
673 struct video_device *vdev = video_devdata(file);
674 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
675 struct v4l2_pix_format *pix = &fmt->fmt.pix;
676 int pix_idx;
677 struct sh_vou_geometry geo;
678 struct v4l2_mbus_framefmt mbfmt = {
679 /* Revisit: is this the correct code? */
680 .code = V4L2_MBUS_FMT_YUYV8_2X8_LE,
681 .field = V4L2_FIELD_INTERLACED,
682 .colorspace = V4L2_COLORSPACE_SMPTE170M,
683 };
684 int ret;
685
686 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
687 vou_dev->rect.width, vou_dev->rect.height,
688 pix->width, pix->height);
689
690 if (pix->field == V4L2_FIELD_ANY)
691 pix->field = V4L2_FIELD_NONE;
692
693 if (fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
694 pix->field != V4L2_FIELD_NONE)
695 return -EINVAL;
696
697 for (pix_idx = 0; pix_idx < ARRAY_SIZE(vou_fmt); pix_idx++)
698 if (vou_fmt[pix_idx].pfmt == pix->pixelformat)
699 break;
700
701 if (pix_idx == ARRAY_SIZE(vou_fmt))
702 return -EINVAL;
703
704 /* Image width must be a multiple of 4 */
705 v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
706 &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
707
708 geo.in_width = pix->width;
709 geo.in_height = pix->height;
710 geo.output = vou_dev->rect;
711
712 vou_adjust_output(&geo, vou_dev->std);
713
714 mbfmt.width = geo.output.width;
715 mbfmt.height = geo.output.height;
716 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
717 s_mbus_fmt, &mbfmt);
718 /* Must be implemented, so, don't check for -ENOIOCTLCMD */
719 if (ret < 0)
720 return ret;
721
722 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
723 geo.output.width, geo.output.height, mbfmt.width, mbfmt.height);
724
725 /* Sanity checks */
726 if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
727 (unsigned)mbfmt.height > VOU_MAX_IMAGE_HEIGHT ||
728 mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8_LE)
729 return -EIO;
730
731 if (mbfmt.width != geo.output.width ||
732 mbfmt.height != geo.output.height) {
733 geo.output.width = mbfmt.width;
734 geo.output.height = mbfmt.height;
735
736 vou_adjust_input(&geo, vou_dev->std);
737 }
738
739 /* We tried to preserve output rectangle, but it could have changed */
740 vou_dev->rect = geo.output;
741 pix->width = geo.in_width;
742 pix->height = geo.in_height;
743
744 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u\n", __func__,
745 pix->width, pix->height);
746
747 vou_dev->pix_idx = pix_idx;
748
749 vou_dev->pix = *pix;
750
751 sh_vou_configure_geometry(vou_dev, pix_idx,
752 geo.scale_idx_h, geo.scale_idx_v);
753
754 return 0;
755}
756
757static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
758 struct v4l2_format *fmt)
759{
760 struct sh_vou_file *vou_file = priv;
761 struct v4l2_pix_format *pix = &fmt->fmt.pix;
762 int i;
763
764 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
765
766 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
767 pix->field = V4L2_FIELD_NONE;
768
769 v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
770 &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
771
772 for (i = 0; ARRAY_SIZE(vou_fmt); i++)
773 if (vou_fmt[i].pfmt == pix->pixelformat)
774 return 0;
775
776 pix->pixelformat = vou_fmt[0].pfmt;
777
778 return 0;
779}
780
781static int sh_vou_reqbufs(struct file *file, void *priv,
782 struct v4l2_requestbuffers *req)
783{
784 struct sh_vou_file *vou_file = priv;
785
786 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
787
788 if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
789 return -EINVAL;
790
791 return videobuf_reqbufs(&vou_file->vbq, req);
792}
793
794static int sh_vou_querybuf(struct file *file, void *priv,
795 struct v4l2_buffer *b)
796{
797 struct sh_vou_file *vou_file = priv;
798
799 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
800
801 return videobuf_querybuf(&vou_file->vbq, b);
802}
803
804static int sh_vou_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
805{
806 struct sh_vou_file *vou_file = priv;
807
808 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
809
810 return videobuf_qbuf(&vou_file->vbq, b);
811}
812
813static int sh_vou_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
814{
815 struct sh_vou_file *vou_file = priv;
816
817 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
818
819 return videobuf_dqbuf(&vou_file->vbq, b, file->f_flags & O_NONBLOCK);
820}
821
822static int sh_vou_streamon(struct file *file, void *priv,
823 enum v4l2_buf_type buftype)
824{
825 struct video_device *vdev = video_devdata(file);
826 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
827 struct sh_vou_file *vou_file = priv;
828 int ret;
829
830 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
831
832 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0,
833 video, s_stream, 1);
834 if (ret < 0 && ret != -ENOIOCTLCMD)
835 return ret;
836
837 /* This calls our .buf_queue() (== sh_vou_buf_queue) */
838 return videobuf_streamon(&vou_file->vbq);
839}
840
841static int sh_vou_streamoff(struct file *file, void *priv,
842 enum v4l2_buf_type buftype)
843{
844 struct video_device *vdev = video_devdata(file);
845 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
846 struct sh_vou_file *vou_file = priv;
847
848 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
849
850 /*
851 * This calls buf_release from host driver's videobuf_queue_ops for all
852 * remaining buffers. When the last buffer is freed, stop streaming
853 */
854 videobuf_streamoff(&vou_file->vbq);
855 v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, s_stream, 0);
856
857 return 0;
858}
859
860static u32 sh_vou_ntsc_mode(enum sh_vou_bus_fmt bus_fmt)
861{
862 switch (bus_fmt) {
863 default:
864 pr_warning("%s(): Invalid bus-format code %d, using default 8-bit\n",
865 __func__, bus_fmt);
866 case SH_VOU_BUS_8BIT:
867 return 1;
868 case SH_VOU_BUS_16BIT:
869 return 0;
870 case SH_VOU_BUS_BT656:
871 return 3;
872 }
873}
874
875static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
876{
877 struct video_device *vdev = video_devdata(file);
878 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
879 int ret;
880
881 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, *std_id);
882
883 if (*std_id & ~vdev->tvnorms)
884 return -EINVAL;
885
886 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
887 s_std_output, *std_id);
888 /* Shall we continue, if the subdev doesn't support .s_std_output()? */
889 if (ret < 0 && ret != -ENOIOCTLCMD)
890 return ret;
891
892 if (*std_id & V4L2_STD_525_60)
893 sh_vou_reg_ab_set(vou_dev, VOUCR,
894 sh_vou_ntsc_mode(vou_dev->pdata->bus_fmt) << 29, 7 << 29);
895 else
896 sh_vou_reg_ab_set(vou_dev, VOUCR, 5 << 29, 7 << 29);
897
898 vou_dev->std = *std_id;
899
900 return 0;
901}
902
903static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
904{
905 struct video_device *vdev = video_devdata(file);
906 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
907
908 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
909
910 *std = vou_dev->std;
911
912 return 0;
913}
914
915static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
916{
917 struct video_device *vdev = video_devdata(file);
918 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
919
920 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
921
922 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
923 a->c = vou_dev->rect;
924
925 return 0;
926}
927
928/* Assume a dull encoder, do all the work ourselves. */
929static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
930{
931 struct video_device *vdev = video_devdata(file);
932 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
933 struct v4l2_rect *rect = &a->c;
934 struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
935 struct v4l2_pix_format *pix = &vou_dev->pix;
936 struct sh_vou_geometry geo;
937 struct v4l2_mbus_framefmt mbfmt = {
938 /* Revisit: is this the correct code? */
939 .code = V4L2_MBUS_FMT_YUYV8_2X8_LE,
940 .field = V4L2_FIELD_INTERLACED,
941 .colorspace = V4L2_COLORSPACE_SMPTE170M,
942 };
943 int ret;
944
945 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__,
946 rect->width, rect->height, rect->left, rect->top);
947
948 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
949 return -EINVAL;
950
951 v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
952 &rect->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
953
954 if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH)
955 rect->left = VOU_MAX_IMAGE_WIDTH - rect->width;
956
957 if (rect->height + rect->top > VOU_MAX_IMAGE_HEIGHT)
958 rect->top = VOU_MAX_IMAGE_HEIGHT - rect->height;
959
960 geo.output = *rect;
961 geo.in_width = pix->width;
962 geo.in_height = pix->height;
963
964 /* Configure the encoder one-to-one, position at 0, ignore errors */
965 sd_crop.c.width = geo.output.width;
966 sd_crop.c.height = geo.output.height;
967 /*
968 * We first issue a S_CROP, so that the subsequent S_FMT delivers the
969 * final encoder configuration.
970 */
971 v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
972 s_crop, &sd_crop);
973 mbfmt.width = geo.output.width;
974 mbfmt.height = geo.output.height;
975 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
976 s_mbus_fmt, &mbfmt);
977 /* Must be implemented, so, don't check for -ENOIOCTLCMD */
978 if (ret < 0)
979 return ret;
980
981 /* Sanity checks */
982 if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
983 (unsigned)mbfmt.height > VOU_MAX_IMAGE_HEIGHT ||
984 mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8_LE)
985 return -EIO;
986
987 geo.output.width = mbfmt.width;
988 geo.output.height = mbfmt.height;
989
990 /*
991 * No down-scaling. According to the API, current call has precedence:
992 * http://v4l2spec.bytesex.org/spec/x1904.htm#AEN1954 paragraph two.
993 */
994 vou_adjust_input(&geo, vou_dev->std);
995
996 /* We tried to preserve output rectangle, but it could have changed */
997 vou_dev->rect = geo.output;
998 pix->width = geo.in_width;
999 pix->height = geo.in_height;
1000
1001 sh_vou_configure_geometry(vou_dev, vou_dev->pix_idx,
1002 geo.scale_idx_h, geo.scale_idx_v);
1003
1004 return 0;
1005}
1006
1007/*
1008 * Total field: NTSC 858 x 2 * 262/263, PAL 864 x 2 * 312/313, default rectangle
1009 * is the initial register values, height takes the interlaced format into
1010 * account. The actual image can only go up to 720 x 2 * 240, So, VOUVPR can
1011 * actually only meaningfully contain values <= 720 and <= 240 respectively, and
1012 * not <= 864 and <= 312.
1013 */
1014static int sh_vou_cropcap(struct file *file, void *priv,
1015 struct v4l2_cropcap *a)
1016{
1017 struct sh_vou_file *vou_file = priv;
1018
1019 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1020
1021 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1022 a->bounds.left = 0;
1023 a->bounds.top = 0;
1024 a->bounds.width = VOU_MAX_IMAGE_WIDTH;
1025 a->bounds.height = VOU_MAX_IMAGE_HEIGHT;
1026 /* Default = max, set VOUDPR = 0, which is not hardware default */
1027 a->defrect.left = 0;
1028 a->defrect.top = 0;
1029 a->defrect.width = VOU_MAX_IMAGE_WIDTH;
1030 a->defrect.height = VOU_MAX_IMAGE_HEIGHT;
1031 a->pixelaspect.numerator = 1;
1032 a->pixelaspect.denominator = 1;
1033
1034 return 0;
1035}
1036
1037static irqreturn_t sh_vou_isr(int irq, void *dev_id)
1038{
1039 struct sh_vou_device *vou_dev = dev_id;
1040 static unsigned long j;
1041 struct videobuf_buffer *vb;
1042 static int cnt;
1043 static int side;
1044 u32 irq_status = sh_vou_reg_a_read(vou_dev, VOUIR), masked;
1045 u32 vou_status = sh_vou_reg_a_read(vou_dev, VOUSTR);
1046
1047 if (!(irq_status & 0x300)) {
1048 if (printk_timed_ratelimit(&j, 500))
1049 dev_warn(vou_dev->v4l2_dev.dev, "IRQ status 0x%x!\n",
1050 irq_status);
1051 return IRQ_NONE;
1052 }
1053
1054 spin_lock(&vou_dev->lock);
1055 if (!vou_dev->active || list_empty(&vou_dev->queue)) {
1056 if (printk_timed_ratelimit(&j, 500))
1057 dev_warn(vou_dev->v4l2_dev.dev,
1058 "IRQ without active buffer: %x!\n", irq_status);
1059 /* Just ack: buf_release will disable further interrupts */
1060 sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x300);
1061 spin_unlock(&vou_dev->lock);
1062 return IRQ_HANDLED;
1063 }
1064
1065 masked = ~(0x300 & irq_status) & irq_status & 0x30304;
1066 dev_dbg(vou_dev->v4l2_dev.dev,
1067 "IRQ status 0x%x -> 0x%x, VOU status 0x%x, cnt %d\n",
1068 irq_status, masked, vou_status, cnt);
1069
1070 cnt++;
1071 side = vou_status & 0x10000;
1072
1073 /* Clear only set interrupts */
1074 sh_vou_reg_a_write(vou_dev, VOUIR, masked);
1075
1076 vb = vou_dev->active;
1077 list_del(&vb->queue);
1078
1079 vb->state = VIDEOBUF_DONE;
1080 do_gettimeofday(&vb->ts);
1081 vb->field_count++;
1082 wake_up(&vb->done);
1083
1084 if (list_empty(&vou_dev->queue)) {
1085 /* Stop VOU */
1086 dev_dbg(vou_dev->v4l2_dev.dev, "%s: queue empty after %d\n",
1087 __func__, cnt);
1088 sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
1089 vou_dev->active = NULL;
1090 vou_dev->status = SH_VOU_INITIALISING;
1091 /* Disable End-of-Frame (VSYNC) interrupts */
1092 sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
1093 spin_unlock(&vou_dev->lock);
1094 return IRQ_HANDLED;
1095 }
1096
1097 vou_dev->active = list_entry(vou_dev->queue.next,
1098 struct videobuf_buffer, queue);
1099
1100 if (vou_dev->active->queue.next != &vou_dev->queue) {
1101 struct videobuf_buffer *new = list_entry(vou_dev->active->queue.next,
1102 struct videobuf_buffer, queue);
1103 sh_vou_schedule_next(vou_dev, new);
1104 }
1105
1106 spin_unlock(&vou_dev->lock);
1107
1108 return IRQ_HANDLED;
1109}
1110
1111static int sh_vou_hw_init(struct sh_vou_device *vou_dev)
1112{
1113 struct sh_vou_pdata *pdata = vou_dev->pdata;
1114 u32 voucr = sh_vou_ntsc_mode(pdata->bus_fmt) << 29;
1115 int i = 100;
1116
1117 /* Disable all IRQs */
1118 sh_vou_reg_a_write(vou_dev, VOUIR, 0);
1119
1120 /* Reset VOU interfaces - registers unaffected */
1121 sh_vou_reg_a_write(vou_dev, VOUSRR, 0x101);
1122 while (--i && (sh_vou_reg_a_read(vou_dev, VOUSRR) & 0x101))
1123 udelay(1);
1124
1125 if (!i)
1126 return -ETIMEDOUT;
1127
1128 dev_dbg(vou_dev->v4l2_dev.dev, "Reset took %dus\n", 100 - i);
1129
1130 if (pdata->flags & SH_VOU_PCLK_FALLING)
1131 voucr |= 1 << 28;
1132 if (pdata->flags & SH_VOU_HSYNC_LOW)
1133 voucr |= 1 << 27;
1134 if (pdata->flags & SH_VOU_VSYNC_LOW)
1135 voucr |= 1 << 26;
1136 sh_vou_reg_ab_set(vou_dev, VOUCR, voucr, 0xfc000000);
1137
1138 /* Manual register side switching at first */
1139 sh_vou_reg_a_write(vou_dev, VOURCR, 4);
1140 /* Default - fixed HSYNC length, can be made configurable is required */
1141 sh_vou_reg_ab_write(vou_dev, VOUMSR, 0x800000);
1142
1143 return 0;
1144}
1145
1146/* File operations */
1147static int sh_vou_open(struct file *file)
1148{
1149 struct video_device *vdev = video_devdata(file);
1150 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1151 struct sh_vou_file *vou_file = kzalloc(sizeof(struct sh_vou_file),
1152 GFP_KERNEL);
1153
1154 if (!vou_file)
1155 return -ENOMEM;
1156
1157 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
1158
1159 file->private_data = vou_file;
1160
1161 if (atomic_inc_return(&vou_dev->use_count) == 1) {
1162 int ret;
1163 /* First open */
1164 vou_dev->status = SH_VOU_INITIALISING;
1165 pm_runtime_get_sync(vdev->v4l2_dev->dev);
1166 ret = sh_vou_hw_init(vou_dev);
1167 if (ret < 0) {
1168 atomic_dec(&vou_dev->use_count);
1169 pm_runtime_put(vdev->v4l2_dev->dev);
1170 vou_dev->status = SH_VOU_IDLE;
1171 return ret;
1172 }
1173 }
1174
1175 videobuf_queue_dma_contig_init(&vou_file->vbq, &sh_vou_video_qops,
1176 vou_dev->v4l2_dev.dev, &vou_dev->lock,
1177 V4L2_BUF_TYPE_VIDEO_OUTPUT,
1178 V4L2_FIELD_NONE,
1179 sizeof(struct videobuf_buffer), vdev);
1180
1181 return 0;
1182}
1183
1184static int sh_vou_release(struct file *file)
1185{
1186 struct video_device *vdev = video_devdata(file);
1187 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1188 struct sh_vou_file *vou_file = file->private_data;
1189
1190 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1191
1192 if (!atomic_dec_return(&vou_dev->use_count)) {
1193 /* Last close */
1194 vou_dev->status = SH_VOU_IDLE;
1195 sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101);
1196 pm_runtime_put(vdev->v4l2_dev->dev);
1197 }
1198
1199 file->private_data = NULL;
1200 kfree(vou_file);
1201
1202 return 0;
1203}
1204
1205static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma)
1206{
1207 struct sh_vou_file *vou_file = file->private_data;
1208
1209 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1210
1211 return videobuf_mmap_mapper(&vou_file->vbq, vma);
1212}
1213
1214static unsigned int sh_vou_poll(struct file *file, poll_table *wait)
1215{
1216 struct sh_vou_file *vou_file = file->private_data;
1217
1218 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1219
1220 return videobuf_poll_stream(file, &vou_file->vbq, wait);
1221}
1222
1223static int sh_vou_g_chip_ident(struct file *file, void *fh,
1224 struct v4l2_dbg_chip_ident *id)
1225{
1226 struct video_device *vdev = video_devdata(file);
1227 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1228
1229 return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_chip_ident, id);
1230}
1231
1232#ifdef CONFIG_VIDEO_ADV_DEBUG
1233static int sh_vou_g_register(struct file *file, void *fh,
1234 struct v4l2_dbg_register *reg)
1235{
1236 struct video_device *vdev = video_devdata(file);
1237 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1238
1239 return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_register, reg);
1240}
1241
1242static int sh_vou_s_register(struct file *file, void *fh,
1243 struct v4l2_dbg_register *reg)
1244{
1245 struct video_device *vdev = video_devdata(file);
1246 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1247
1248 return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, s_register, reg);
1249}
1250#endif
1251
1252/* sh_vou display ioctl operations */
1253static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
1254 .vidioc_querycap = sh_vou_querycap,
1255 .vidioc_enum_fmt_vid_out = sh_vou_enum_fmt_vid_out,
1256 .vidioc_g_fmt_vid_out = sh_vou_g_fmt_vid_out,
1257 .vidioc_s_fmt_vid_out = sh_vou_s_fmt_vid_out,
1258 .vidioc_try_fmt_vid_out = sh_vou_try_fmt_vid_out,
1259 .vidioc_reqbufs = sh_vou_reqbufs,
1260 .vidioc_querybuf = sh_vou_querybuf,
1261 .vidioc_qbuf = sh_vou_qbuf,
1262 .vidioc_dqbuf = sh_vou_dqbuf,
1263 .vidioc_streamon = sh_vou_streamon,
1264 .vidioc_streamoff = sh_vou_streamoff,
1265 .vidioc_s_std = sh_vou_s_std,
1266 .vidioc_g_std = sh_vou_g_std,
1267 .vidioc_cropcap = sh_vou_cropcap,
1268 .vidioc_g_crop = sh_vou_g_crop,
1269 .vidioc_s_crop = sh_vou_s_crop,
1270 .vidioc_g_chip_ident = sh_vou_g_chip_ident,
1271#ifdef CONFIG_VIDEO_ADV_DEBUG
1272 .vidioc_g_register = sh_vou_g_register,
1273 .vidioc_s_register = sh_vou_s_register,
1274#endif
1275};
1276
1277static const struct v4l2_file_operations sh_vou_fops = {
1278 .owner = THIS_MODULE,
1279 .open = sh_vou_open,
1280 .release = sh_vou_release,
1281 .ioctl = video_ioctl2,
1282 .mmap = sh_vou_mmap,
1283 .poll = sh_vou_poll,
1284};
1285
1286static const struct video_device sh_vou_video_template = {
1287 .name = "sh_vou",
1288 .fops = &sh_vou_fops,
1289 .ioctl_ops = &sh_vou_ioctl_ops,
1290 .tvnorms = V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
1291 .current_norm = V4L2_STD_NTSC_M,
1292};
1293
1294static int __devinit sh_vou_probe(struct platform_device *pdev)
1295{
1296 struct sh_vou_pdata *vou_pdata = pdev->dev.platform_data;
1297 struct v4l2_rect *rect;
1298 struct v4l2_pix_format *pix;
1299 struct i2c_adapter *i2c_adap;
1300 struct video_device *vdev;
1301 struct sh_vou_device *vou_dev;
1302 struct resource *reg_res, *region;
1303 struct v4l2_subdev *subdev;
1304 int irq, ret;
1305
1306 reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1307 irq = platform_get_irq(pdev, 0);
1308
1309 if (!vou_pdata || !reg_res || irq <= 0) {
1310 dev_err(&pdev->dev, "Insufficient VOU platform information.\n");
1311 return -ENODEV;
1312 }
1313
1314 vou_dev = kzalloc(sizeof(*vou_dev), GFP_KERNEL);
1315 if (!vou_dev)
1316 return -ENOMEM;
1317
1318 INIT_LIST_HEAD(&vou_dev->queue);
1319 spin_lock_init(&vou_dev->lock);
1320 atomic_set(&vou_dev->use_count, 0);
1321 vou_dev->pdata = vou_pdata;
1322 vou_dev->status = SH_VOU_IDLE;
1323
1324 rect = &vou_dev->rect;
1325 pix = &vou_dev->pix;
1326
1327 /* Fill in defaults */
1328 vou_dev->std = sh_vou_video_template.current_norm;
1329 rect->left = 0;
1330 rect->top = 0;
1331 rect->width = VOU_MAX_IMAGE_WIDTH;
1332 rect->height = VOU_MAX_IMAGE_HEIGHT;
1333 pix->width = VOU_MAX_IMAGE_WIDTH;
1334 pix->height = VOU_MAX_IMAGE_HEIGHT;
1335 pix->pixelformat = V4L2_PIX_FMT_YVYU;
1336 pix->field = V4L2_FIELD_NONE;
1337 pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2;
1338 pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * VOU_MAX_IMAGE_HEIGHT;
1339 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1340
1341 region = request_mem_region(reg_res->start, resource_size(reg_res),
1342 pdev->name);
1343 if (!region) {
1344 dev_err(&pdev->dev, "VOU region already claimed\n");
1345 ret = -EBUSY;
1346 goto ereqmemreg;
1347 }
1348
1349 vou_dev->base = ioremap(reg_res->start, resource_size(reg_res));
1350 if (!vou_dev->base) {
1351 ret = -ENOMEM;
1352 goto emap;
1353 }
1354
1355 ret = request_irq(irq, sh_vou_isr, 0, "vou", vou_dev);
1356 if (ret < 0)
1357 goto ereqirq;
1358
1359 ret = v4l2_device_register(&pdev->dev, &vou_dev->v4l2_dev);
1360 if (ret < 0) {
1361 dev_err(&pdev->dev, "Error registering v4l2 device\n");
1362 goto ev4l2devreg;
1363 }
1364
1365 /* Allocate memory for video device */
1366 vdev = video_device_alloc();
1367 if (vdev == NULL) {
1368 ret = -ENOMEM;
1369 goto evdevalloc;
1370 }
1371
1372 *vdev = sh_vou_video_template;
1373 if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT)
1374 vdev->tvnorms |= V4L2_STD_PAL;
1375 vdev->v4l2_dev = &vou_dev->v4l2_dev;
1376 vdev->release = video_device_release;
1377
1378 vou_dev->vdev = vdev;
1379 video_set_drvdata(vdev, vou_dev);
1380
1381 pm_runtime_enable(&pdev->dev);
1382 pm_runtime_resume(&pdev->dev);
1383
1384 i2c_adap = i2c_get_adapter(vou_pdata->i2c_adap);
1385 if (!i2c_adap) {
1386 ret = -ENODEV;
1387 goto ei2cgadap;
1388 }
1389
1390 ret = sh_vou_hw_init(vou_dev);
1391 if (ret < 0)
1392 goto ereset;
1393
1394 subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
1395 vou_pdata->module_name, vou_pdata->board_info, NULL);
1396 if (!subdev) {
1397 ret = -ENOMEM;
1398 goto ei2cnd;
1399 }
1400
1401 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1402 if (ret < 0)
1403 goto evregdev;
1404
1405 return 0;
1406
1407evregdev:
1408ei2cnd:
1409ereset:
1410 i2c_put_adapter(i2c_adap);
1411ei2cgadap:
1412 video_device_release(vdev);
1413 pm_runtime_disable(&pdev->dev);
1414evdevalloc:
1415 v4l2_device_unregister(&vou_dev->v4l2_dev);
1416ev4l2devreg:
1417 free_irq(irq, vou_dev);
1418ereqirq:
1419 iounmap(vou_dev->base);
1420emap:
1421 release_mem_region(reg_res->start, resource_size(reg_res));
1422ereqmemreg:
1423 kfree(vou_dev);
1424 return ret;
1425}
1426
1427static int __devexit sh_vou_remove(struct platform_device *pdev)
1428{
1429 int irq = platform_get_irq(pdev, 0);
1430 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1431 struct sh_vou_device *vou_dev = container_of(v4l2_dev,
1432 struct sh_vou_device, v4l2_dev);
1433 struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next,
1434 struct v4l2_subdev, list);
1435 struct i2c_client *client = v4l2_get_subdevdata(sd);
1436 struct resource *reg_res;
1437
1438 if (irq > 0)
1439 free_irq(irq, vou_dev);
1440 pm_runtime_disable(&pdev->dev);
1441 video_unregister_device(vou_dev->vdev);
1442 i2c_put_adapter(client->adapter);
1443 v4l2_device_unregister(&vou_dev->v4l2_dev);
1444 iounmap(vou_dev->base);
1445 reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1446 if (reg_res)
1447 release_mem_region(reg_res->start, resource_size(reg_res));
1448 kfree(vou_dev);
1449 return 0;
1450}
1451
1452static struct platform_driver __refdata sh_vou = {
1453 .remove = __devexit_p(sh_vou_remove),
1454 .driver = {
1455 .name = "sh-vou",
1456 .owner = THIS_MODULE,
1457 },
1458};
1459
1460static int __init sh_vou_init(void)
1461{
1462 return platform_driver_probe(&sh_vou, sh_vou_probe);
1463}
1464
1465static void __exit sh_vou_exit(void)
1466{
1467 platform_driver_unregister(&sh_vou);
1468}
1469
1470module_init(sh_vou_init);
1471module_exit(sh_vou_exit);
1472
1473MODULE_DESCRIPTION("SuperH VOU driver");
1474MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1475MODULE_LICENSE("GPL v2");
1476MODULE_ALIAS("platform:sh-vou");
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index cbf8087b286f..28e19daadec9 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -2295,7 +2295,7 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
2295 if (copy_from_user(&ctrl, arg, sizeof(ctrl))) 2295 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
2296 return -EFAULT; 2296 return -EFAULT;
2297 2297
2298 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 2298 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
2299 if (ctrl.id == s->qctrl[i].id) { 2299 if (ctrl.id == s->qctrl[i].id) {
2300 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) 2300 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
2301 return -EINVAL; 2301 return -EINVAL;
@@ -2305,7 +2305,9 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
2305 ctrl.value -= ctrl.value % s->qctrl[i].step; 2305 ctrl.value -= ctrl.value % s->qctrl[i].step;
2306 break; 2306 break;
2307 } 2307 }
2308 2308 }
2309 if (i == ARRAY_SIZE(s->qctrl))
2310 return -EINVAL;
2309 if ((err = s->set_ctrl(cam, &ctrl))) 2311 if ((err = s->set_ctrl(cam, &ctrl)))
2310 return err; 2312 return err;
2311 2313
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index cc40d6ba9f22..522ba3f4c285 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -40,12 +40,12 @@ struct sn9c102_device;
40 40
41static const struct usb_device_id sn9c102_id_table[] = { 41static const struct usb_device_id sn9c102_id_table[] = {
42 /* SN9C101 and SN9C102 */ 42 /* SN9C101 and SN9C102 */
43#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 43#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
44 { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), }, 44 { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, 45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
46#endif 46#endif
47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, 47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
48#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 48#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
49 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, 49 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
50 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, 50 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
51/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ 51/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
@@ -53,13 +53,13 @@ static const struct usb_device_id sn9c102_id_table[] = {
53 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, 53 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
54 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, 54 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
55 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, 55 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
56#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 56#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
57 { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), }, 57 { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
58 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, 58 { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
59#endif 59#endif
60 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, 60 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
61 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, 61 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
62#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 62#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
63 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, 63 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
64/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ 64/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
65#endif 65#endif
@@ -74,7 +74,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
74 { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, 74 { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), },
75 { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), }, 75 { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), },
76/* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */ 76/* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */
77#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 77#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
78 { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), }, 78 { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), },
79#endif 79#endif
80 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, 80 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), },
@@ -86,7 +86,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
86 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, 86 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), },
87 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, 87 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), },
88 { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), }, 88 { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), },
89#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 89#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
90 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), }, 90 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), },
91#endif 91#endif
92 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, 92 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), },
@@ -97,7 +97,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
97 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, 97 { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
98 { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, 98 { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
99 /* SN9C105 */ 99 /* SN9C105 */
100#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 100#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE
101 { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), }, 101 { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
102 { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), }, 102 { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
103 { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, 103 { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
@@ -121,11 +121,11 @@ static const struct usb_device_id sn9c102_id_table[] = {
121 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, 121 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
122 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, 122 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
123/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */ 123/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
124#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 124#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE
125 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, 125 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
126#endif 126#endif
127 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, 127 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
128#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 128#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE
129 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, 129 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
130 { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), }, 130 { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
131#endif 131#endif
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
index db2434948939..2dce5c908c8e 100644
--- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
@@ -255,7 +255,7 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
255 if (err || r0 < 0 || r1 < 0) 255 if (err || r0 < 0 || r1 < 0)
256 return -EIO; 256 return -EIO;
257 257
258 if (r0 != 0x00 || r1 != 0x04) 258 if ((r0 != 0x00 && r0 != 0x01) || r1 != 0x04)
259 return -ENODEV; 259 return -ENODEV;
260 260
261 sn9c102_attach_sensor(cam, &hv7131d); 261 sn9c102_attach_sensor(cam, &hv7131d);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a24174ddec46..db1ca0e90d76 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -25,6 +25,7 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/pm_runtime.h>
28#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
29 30
30#include <media/soc_camera.h> 31#include <media/soc_camera.h>
@@ -388,6 +389,11 @@ static int soc_camera_open(struct file *file)
388 goto eiciadd; 389 goto eiciadd;
389 } 390 }
390 391
392 pm_runtime_enable(&icd->vdev->dev);
393 ret = pm_runtime_resume(&icd->vdev->dev);
394 if (ret < 0 && ret != -ENOSYS)
395 goto eresume;
396
391 /* 397 /*
392 * Try to configure with default parameters. Notice: this is the 398 * Try to configure with default parameters. Notice: this is the
393 * very first open, so, we cannot race against other calls, 399 * very first open, so, we cannot race against other calls,
@@ -409,10 +415,12 @@ static int soc_camera_open(struct file *file)
409 return 0; 415 return 0;
410 416
411 /* 417 /*
412 * First five errors are entered with the .video_lock held 418 * First four errors are entered with the .video_lock held
413 * and use_count == 1 419 * and use_count == 1
414 */ 420 */
415esfmt: 421esfmt:
422 pm_runtime_disable(&icd->vdev->dev);
423eresume:
416 ici->ops->remove(icd); 424 ici->ops->remove(icd);
417eiciadd: 425eiciadd:
418 if (icl->power) 426 if (icl->power)
@@ -437,7 +445,11 @@ static int soc_camera_close(struct file *file)
437 if (!icd->use_count) { 445 if (!icd->use_count) {
438 struct soc_camera_link *icl = to_soc_camera_link(icd); 446 struct soc_camera_link *icl = to_soc_camera_link(icd);
439 447
448 pm_runtime_suspend(&icd->vdev->dev);
449 pm_runtime_disable(&icd->vdev->dev);
450
440 ici->ops->remove(icd); 451 ici->ops->remove(icd);
452
441 if (icl->power) 453 if (icl->power)
442 icl->power(icd->pdev, 0); 454 icl->power(icd->pdev, 0);
443 } 455 }
@@ -741,8 +753,7 @@ static int soc_camera_g_crop(struct file *file, void *fh,
741/* 753/*
742 * According to the V4L2 API, drivers shall not update the struct v4l2_crop 754 * According to the V4L2 API, drivers shall not update the struct v4l2_crop
743 * argument with the actual geometry, instead, the user shall use G_CROP to 755 * argument with the actual geometry, instead, the user shall use G_CROP to
744 * retrieve it. However, we expect camera host and client drivers to update 756 * retrieve it.
745 * the argument, which we then use internally, but do not return to the user.
746 */ 757 */
747static int soc_camera_s_crop(struct file *file, void *fh, 758static int soc_camera_s_crop(struct file *file, void *fh,
748 struct v4l2_crop *a) 759 struct v4l2_crop *a)
@@ -1319,6 +1330,7 @@ static int video_dev_create(struct soc_camera_device *icd)
1319 */ 1330 */
1320static int soc_camera_video_start(struct soc_camera_device *icd) 1331static int soc_camera_video_start(struct soc_camera_device *icd)
1321{ 1332{
1333 struct device_type *type = icd->vdev->dev.type;
1322 int ret; 1334 int ret;
1323 1335
1324 if (!icd->dev.parent) 1336 if (!icd->dev.parent)
@@ -1335,6 +1347,9 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
1335 return ret; 1347 return ret;
1336 } 1348 }
1337 1349
1350 /* Restore device type, possibly set by the subdevice driver */
1351 icd->vdev->dev.type = type;
1352
1338 return 0; 1353 return 0;
1339} 1354}
1340 1355
diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/video/tlg2300/pd-dvb.c
index ebd9cb5bec74..edd78f8b1baa 100644
--- a/drivers/media/video/tlg2300/pd-dvb.c
+++ b/drivers/media/video/tlg2300/pd-dvb.c
@@ -97,15 +97,17 @@ open_out:
97 return ret; 97 return ret;
98} 98}
99 99
100#ifdef CONFIG_PM
100static void poseidon_fe_release(struct dvb_frontend *fe) 101static void poseidon_fe_release(struct dvb_frontend *fe)
101{ 102{
102 struct poseidon *pd = fe->demodulator_priv; 103 struct poseidon *pd = fe->demodulator_priv;
103 104
104#ifdef CONFIG_PM
105 pd->pm_suspend = NULL; 105 pd->pm_suspend = NULL;
106 pd->pm_resume = NULL; 106 pd->pm_resume = NULL;
107#endif
108} 107}
108#else
109#define poseidon_fe_release NULL
110#endif
109 111
110static s32 poseidon_fe_sleep(struct dvb_frontend *fe) 112static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
111{ 113{
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c
index 2cf0ebf9f28b..c267e0cfb54b 100644
--- a/drivers/media/video/tlg2300/pd-main.c
+++ b/drivers/media/video/tlg2300/pd-main.c
@@ -24,7 +24,6 @@
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */ 25 */
26 26
27#include <linux/version.h>
28#include <linux/kernel.h> 27#include <linux/kernel.h>
29#include <linux/errno.h> 28#include <linux/errno.h>
30#include <linux/init.h> 29#include <linux/init.h>
@@ -55,8 +54,8 @@ int debug_mode;
55module_param(debug_mode, int, 0644); 54module_param(debug_mode, int, 0644);
56MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose"); 55MODULE_PARM_DESC(debug_mode, "0 = disable, 1 = enable, 2 = verbose");
57 56
58const char *firmware_name = "tlg2300_firmware.bin"; 57static const char *firmware_name = "tlg2300_firmware.bin";
59struct usb_driver poseidon_driver; 58static struct usb_driver poseidon_driver;
60static LIST_HEAD(pd_device_list); 59static LIST_HEAD(pd_device_list);
61 60
62/* 61/*
@@ -501,7 +500,7 @@ static void poseidon_disconnect(struct usb_interface *interface)
501 kref_put(&pd->kref, poseidon_delete); 500 kref_put(&pd->kref, poseidon_delete);
502} 501}
503 502
504struct usb_driver poseidon_driver = { 503static struct usb_driver poseidon_driver = {
505 .name = "poseidon", 504 .name = "poseidon",
506 .probe = poseidon_probe, 505 .probe = poseidon_probe,
507 .disconnect = poseidon_disconnect, 506 .disconnect = poseidon_disconnect,
diff --git a/drivers/media/video/tlg2300/pd-radio.c b/drivers/media/video/tlg2300/pd-radio.c
index 755766b15157..fae84c2a0c39 100644
--- a/drivers/media/video/tlg2300/pd-radio.c
+++ b/drivers/media/video/tlg2300/pd-radio.c
@@ -161,7 +161,8 @@ static const struct v4l2_file_operations poseidon_fm_fops = {
161 .ioctl = video_ioctl2, 161 .ioctl = video_ioctl2,
162}; 162};
163 163
164int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) 164static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv,
165 struct v4l2_tuner *vt)
165{ 166{
166 struct tuner_fm_sig_stat_s fm_stat = {}; 167 struct tuner_fm_sig_stat_s fm_stat = {};
167 int ret, status, count = 5; 168 int ret, status, count = 5;
@@ -203,7 +204,8 @@ int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
203 return 0; 204 return 0;
204} 205}
205 206
206int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp) 207static int fm_get_freq(struct file *file, void *priv,
208 struct v4l2_frequency *argp)
207{ 209{
208 struct poseidon *p = file->private_data; 210 struct poseidon *p = file->private_data;
209 211
@@ -246,7 +248,8 @@ error:
246 return ret; 248 return ret;
247} 249}
248 250
249int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp) 251static int fm_set_freq(struct file *file, void *priv,
252 struct v4l2_frequency *argp)
250{ 253{
251 struct poseidon *p = file->private_data; 254 struct poseidon *p = file->private_data;
252 255
@@ -258,13 +261,13 @@ int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
258 return set_frequency(p, argp->frequency); 261 return set_frequency(p, argp->frequency);
259} 262}
260 263
261int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv, 264static int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
262 struct v4l2_control *arg) 265 struct v4l2_control *arg)
263{ 266{
264 return 0; 267 return 0;
265} 268}
266 269
267int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh, 270static int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
268 struct v4l2_ext_controls *ctrls) 271 struct v4l2_ext_controls *ctrls)
269{ 272{
270 struct poseidon *p = file->private_data; 273 struct poseidon *p = file->private_data;
@@ -285,7 +288,7 @@ int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
285 return 0; 288 return 0;
286} 289}
287 290
288int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh, 291static int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
289 struct v4l2_ext_controls *ctrls) 292 struct v4l2_ext_controls *ctrls)
290{ 293{
291 int i; 294 int i;
@@ -312,13 +315,13 @@ int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
312 return 0; 315 return 0;
313} 316}
314 317
315int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv, 318static int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
316 struct v4l2_control *ctrl) 319 struct v4l2_control *ctrl)
317{ 320{
318 return 0; 321 return 0;
319} 322}
320 323
321int tlg_fm_vidioc_queryctrl(struct file *file, void *priv, 324static int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
322 struct v4l2_queryctrl *ctrl) 325 struct v4l2_queryctrl *ctrl)
323{ 326{
324 if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)) 327 if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
@@ -337,7 +340,7 @@ int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
337 return -EINVAL; 340 return -EINVAL;
338} 341}
339 342
340int tlg_fm_vidioc_querymenu(struct file *file, void *fh, 343static int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
341 struct v4l2_querymenu *qmenu) 344 struct v4l2_querymenu *qmenu)
342{ 345{
343 return v4l2_ctrl_query_menu(qmenu, NULL, NULL); 346 return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index cf8f18c007e6..c750fd115ec4 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -12,11 +12,13 @@
12#include "pd-common.h" 12#include "pd-common.h"
13#include "vendorcmds.h" 13#include "vendorcmds.h"
14 14
15#ifdef CONFIG_PM
15static int pm_video_suspend(struct poseidon *pd); 16static int pm_video_suspend(struct poseidon *pd);
16static int pm_video_resume(struct poseidon *pd); 17static int pm_video_resume(struct poseidon *pd);
18#endif
17static void iso_bubble_handler(struct work_struct *w); 19static void iso_bubble_handler(struct work_struct *w);
18 20
19int usb_transfer_mode; 21static int usb_transfer_mode;
20module_param(usb_transfer_mode, int, 0644); 22module_param(usb_transfer_mode, int, 0644);
21MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous"); 23MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous");
22 24
@@ -617,7 +619,7 @@ static int pd_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
617 return 0; 619 return 0;
618} 620}
619 621
620int fire_all_urb(struct video_data *video) 622static int fire_all_urb(struct video_data *video)
621{ 623{
622 int i, ret; 624 int i, ret;
623 625
@@ -877,7 +879,7 @@ out:
877 return ret; 879 return ret;
878} 880}
879 881
880int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm) 882static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *norm)
881{ 883{
882 struct front_face *front = fh; 884 struct front_face *front = fh;
883 logs(front); 885 logs(front);
@@ -1020,7 +1022,7 @@ static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
1020 return 0; 1022 return 0;
1021} 1023}
1022 1024
1023int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 1025static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
1024{ 1026{
1025 a->index = 0; 1027 a->index = 0;
1026 a->capability = V4L2_AUDCAP_STEREO; 1028 a->capability = V4L2_AUDCAP_STEREO;
@@ -1029,7 +1031,7 @@ int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
1029 return 0; 1031 return 0;
1030} 1032}
1031 1033
1032int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) 1034static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
1033{ 1035{
1034 return (0 == a->index) ? 0 : -EINVAL; 1036 return (0 == a->index) ? 0 : -EINVAL;
1035} 1037}
@@ -1189,7 +1191,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1189} 1191}
1190 1192
1191/* Just stop the URBs, do not free the URBs */ 1193/* Just stop the URBs, do not free the URBs */
1192int usb_transfer_stop(struct video_data *video) 1194static int usb_transfer_stop(struct video_data *video)
1193{ 1195{
1194 if (video->is_streaming) { 1196 if (video->is_streaming) {
1195 int i; 1197 int i;
@@ -1518,13 +1520,13 @@ static int pd_video_mmap(struct file *file, struct vm_area_struct *vma)
1518 return videobuf_mmap_mapper(&front->q, vma); 1520 return videobuf_mmap_mapper(&front->q, vma);
1519} 1521}
1520 1522
1521unsigned int pd_video_poll(struct file *file, poll_table *table) 1523static unsigned int pd_video_poll(struct file *file, poll_table *table)
1522{ 1524{
1523 struct front_face *front = file->private_data; 1525 struct front_face *front = file->private_data;
1524 return videobuf_poll_stream(file, &front->q, table); 1526 return videobuf_poll_stream(file, &front->q, table);
1525} 1527}
1526 1528
1527ssize_t pd_video_read(struct file *file, char __user *buffer, 1529static ssize_t pd_video_read(struct file *file, char __user *buffer,
1528 size_t count, loff_t *ppos) 1530 size_t count, loff_t *ppos)
1529{ 1531{
1530 struct front_face *front = file->private_data; 1532 struct front_face *front = file->private_data;
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index e4815a1806e3..e826114b7fb8 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -79,6 +79,8 @@ struct tvp514x_std_info {
79}; 79};
80 80
81static struct tvp514x_reg tvp514x_reg_list_default[0x40]; 81static struct tvp514x_reg tvp514x_reg_list_default[0x40];
82
83static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
82/** 84/**
83 * struct tvp514x_decoder - TVP5146/47 decoder object 85 * struct tvp514x_decoder - TVP5146/47 decoder object
84 * @sd: Subdevice Slave handle 86 * @sd: Subdevice Slave handle
@@ -644,6 +646,17 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
644 /* Index out of bound */ 646 /* Index out of bound */
645 return -EINVAL; 647 return -EINVAL;
646 648
649 /*
650 * For the sequence streamon -> streamoff and again s_input
651 * it fails to lock the signal, since streamoff puts TVP514x
652 * into power off state which leads to failure in sub-sequent s_input.
653 *
654 * So power up the TVP514x device here, since it is important to lock
655 * the signal at this stage.
656 */
657 if (!decoder->streaming)
658 tvp514x_s_stream(sd, 1);
659
647 input_sel = input; 660 input_sel = input;
648 output_sel = output; 661 output_sel = output;
649 662
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 908ffb68e926..47f0582d50a5 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -891,29 +891,26 @@ static int tvp5150_s_routing(struct v4l2_subdev *sd,
891 return 0; 891 return 0;
892} 892}
893 893
894static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 894static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
895{
896 /* this is for capturing 36 raw vbi lines
897 if there's a way to cut off the beginning 2 vbi lines
898 with the tvp5150 then the vbi line count could be lowered
899 to 17 lines/field again, although I couldn't find a register
900 which could do that cropping */
901 if (fmt->sample_format == V4L2_PIX_FMT_GREY)
902 tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70);
903 if (fmt->count[0] == 18 && fmt->count[1] == 18) {
904 tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00);
905 tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01);
906 }
907 return 0;
908}
909
910static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
895{ 911{
896 struct v4l2_sliced_vbi_format *svbi;
897 int i; 912 int i;
898 913
899 /* raw vbi */
900 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
901 /* this is for capturing 36 raw vbi lines
902 if there's a way to cut off the beginning 2 vbi lines
903 with the tvp5150 then the vbi line count could be lowered
904 to 17 lines/field again, although I couldn't find a register
905 which could do that cropping */
906 if (fmt->fmt.vbi.sample_format == V4L2_PIX_FMT_GREY)
907 tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70);
908 if (fmt->fmt.vbi.count[0] == 18 && fmt->fmt.vbi.count[1] == 18) {
909 tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00);
910 tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01);
911 }
912 return 0;
913 }
914 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
915 return -EINVAL;
916 svbi = &fmt->fmt.sliced;
917 if (svbi->service_set != 0) { 914 if (svbi->service_set != 0) {
918 for (i = 0; i <= 23; i++) { 915 for (i = 0; i <= 23; i++) {
919 svbi->service_lines[1][i] = 0; 916 svbi->service_lines[1][i] = 0;
@@ -937,14 +934,21 @@ static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
937 return 0; 934 return 0;
938} 935}
939 936
940static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) 937static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
941{ 938{
942 struct v4l2_sliced_vbi_format *svbi; 939 switch (fmt->type) {
943 int i, mask = 0; 940 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
941 return tvp5150_s_sliced_fmt(sd, &fmt->fmt.sliced);
944 942
945 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) 943 default:
946 return -EINVAL; 944 return -EINVAL;
947 svbi = &fmt->fmt.sliced; 945 }
946}
947
948static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
949{
950 int i, mask = 0;
951
948 memset(svbi, 0, sizeof(*svbi)); 952 memset(svbi, 0, sizeof(*svbi));
949 953
950 for (i = 0; i <= 23; i++) { 954 for (i = 0; i <= 23; i++) {
@@ -956,6 +960,12 @@ static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
956 return 0; 960 return 0;
957} 961}
958 962
963static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
964{
965 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
966 return -EINVAL;
967 return tvp5150_g_sliced_fmt(sd, &fmt->fmt.sliced);
968}
959 969
960static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, 970static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
961 struct v4l2_dbg_chip_ident *chip) 971 struct v4l2_dbg_chip_ident *chip)
@@ -1046,13 +1056,20 @@ static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
1046 .s_routing = tvp5150_s_routing, 1056 .s_routing = tvp5150_s_routing,
1047 .g_fmt = tvp5150_g_fmt, 1057 .g_fmt = tvp5150_g_fmt,
1048 .s_fmt = tvp5150_s_fmt, 1058 .s_fmt = tvp5150_s_fmt,
1059};
1060
1061static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
1049 .g_sliced_vbi_cap = tvp5150_g_sliced_vbi_cap, 1062 .g_sliced_vbi_cap = tvp5150_g_sliced_vbi_cap,
1063 .g_sliced_fmt = tvp5150_g_sliced_fmt,
1064 .s_sliced_fmt = tvp5150_s_sliced_fmt,
1065 .s_raw_fmt = tvp5150_s_raw_fmt,
1050}; 1066};
1051 1067
1052static const struct v4l2_subdev_ops tvp5150_ops = { 1068static const struct v4l2_subdev_ops tvp5150_ops = {
1053 .core = &tvp5150_core_ops, 1069 .core = &tvp5150_core_ops,
1054 .tuner = &tvp5150_tuner_ops, 1070 .tuner = &tvp5150_tuner_ops,
1055 .video = &tvp5150_video_ops, 1071 .video = &tvp5150_video_ops,
1072 .vbi = &tvp5150_vbi_ops,
1056}; 1073};
1057 1074
1058 1075
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index 4a69bcc738f3..8085ac392446 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -458,7 +458,7 @@ static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
458/* 458/*
459 * tvp7002_read - Read a value from a register in an TVP7002 459 * tvp7002_read - Read a value from a register in an TVP7002
460 * @sd: ptr to v4l2_subdev struct 460 * @sd: ptr to v4l2_subdev struct
461 * @reg: TVP7002 register address 461 * @addr: TVP7002 register address
462 * @dst: pointer to 8-bit destination 462 * @dst: pointer to 8-bit destination
463 * 463 *
464 * Returns value read if successful, or non-zero (-1) otherwise. 464 * Returns value read if successful, or non-zero (-1) otherwise.
@@ -488,7 +488,7 @@ static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
488 * @sd: pointer to standard V4L2 sub-device structure 488 * @sd: pointer to standard V4L2 sub-device structure
489 * @reg: destination register 489 * @reg: destination register
490 * @val: value to be read 490 * @val: value to be read
491 * @error: pointer to error value 491 * @err: pointer to error value
492 * 492 *
493 * Read a value in a register and save error value in pointer. 493 * Read a value in a register and save error value in pointer.
494 * Also update the register table if successful 494 * Also update the register table if successful
@@ -535,7 +535,7 @@ static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
535 * @sd: pointer to standard V4L2 sub-device structure 535 * @sd: pointer to standard V4L2 sub-device structure
536 * @reg: destination register 536 * @reg: destination register
537 * @val: value to be written 537 * @val: value to be written
538 * @error: pointer to error value 538 * @err: pointer to error value
539 * 539 *
540 * Write a value in a register and save error value in pointer. 540 * Write a value in a register and save error value in pointer.
541 * Also update the register table if successful 541 * Also update the register table if successful
@@ -596,7 +596,7 @@ static int tvp7002_write_inittab(struct v4l2_subdev *sd,
596/* 596/*
597 * tvp7002_s_dv_preset() - Set digital video preset 597 * tvp7002_s_dv_preset() - Set digital video preset
598 * @sd: ptr to v4l2_subdev struct 598 * @sd: ptr to v4l2_subdev struct
599 * @std: ptr to v4l2_dv_preset struct 599 * @dv_preset: ptr to v4l2_dv_preset struct
600 * 600 *
601 * Set the digital video preset for a TVP7002 decoder device. 601 * Set the digital video preset for a TVP7002 decoder device.
602 * Returns zero when successful or -EINVAL if register access fails. 602 * Returns zero when successful or -EINVAL if register access fails.
@@ -676,7 +676,7 @@ static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
676/* 676/*
677 * tvp7002_queryctrl() - Query a control 677 * tvp7002_queryctrl() - Query a control
678 * @sd: ptr to v4l2_subdev struct 678 * @sd: ptr to v4l2_subdev struct
679 * @ctrl: ptr to v4l2_queryctrl struct 679 * @qc: ptr to v4l2_queryctrl struct
680 * 680 *
681 * Query a control of a TVP7002 decoder device. 681 * Query a control of a TVP7002 decoder device.
682 * Returns zero when successful or -EINVAL if register read fails. 682 * Returns zero when successful or -EINVAL if register read fails.
@@ -776,7 +776,7 @@ static int tvp7002_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
776/* 776/*
777 * tvp7002_query_dv_preset() - query DV preset 777 * tvp7002_query_dv_preset() - query DV preset
778 * @sd: pointer to standard V4L2 sub-device structure 778 * @sd: pointer to standard V4L2 sub-device structure
779 * @std_id: standard V4L2 v4l2_dv_preset 779 * @qpreset: standard V4L2 v4l2_dv_preset structure
780 * 780 *
781 * Returns the current DV preset by TVP7002. If no active input is 781 * Returns the current DV preset by TVP7002. If no active input is
782 * detected, returns -EINVAL 782 * detected, returns -EINVAL
@@ -785,7 +785,6 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
785 struct v4l2_dv_preset *qpreset) 785 struct v4l2_dv_preset *qpreset)
786{ 786{
787 const struct tvp7002_preset_definition *presets = tvp7002_presets; 787 const struct tvp7002_preset_definition *presets = tvp7002_presets;
788 struct v4l2_dv_enum_preset e_preset;
789 struct tvp7002 *device; 788 struct tvp7002 *device;
790 u8 progressive; 789 u8 progressive;
791 u32 lpfr; 790 u32 lpfr;
@@ -828,20 +827,18 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
828 } 827 }
829 828
830 if (index == NUM_PRESETS) { 829 if (index == NUM_PRESETS) {
831 v4l2_err(sd, "querystd error, lpf = %x, cpl = %x\n", 830 v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n",
832 lpfr, cpln); 831 lpfr, cpln);
833 return -EINVAL; 832 /* Could not detect a signal, so return the 'invalid' preset */
833 qpreset->preset = V4L2_DV_INVALID;
834 return 0;
834 } 835 }
835 836
836 if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
837 return -EINVAL;
838
839 /* Set values in found preset */ 837 /* Set values in found preset */
840 qpreset->preset = presets->preset; 838 qpreset->preset = presets->preset;
841 839
842 /* Update lines per frame and clocks per line info */ 840 /* Update lines per frame and clocks per line info */
843 v4l2_dbg(1, debug, sd, "Current preset: %d %d", 841 v4l2_dbg(1, debug, sd, "detected preset: %d\n", presets->preset);
844 e_preset.width, e_preset.height);
845 return 0; 842 return 0;
846} 843}
847 844
@@ -849,7 +846,7 @@ static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
849/* 846/*
850 * tvp7002_g_register() - Get the value of a register 847 * tvp7002_g_register() - Get the value of a register
851 * @sd: ptr to v4l2_subdev struct 848 * @sd: ptr to v4l2_subdev struct
852 * @vreg: ptr to v4l2_dbg_register struct 849 * @reg: ptr to v4l2_dbg_register struct
853 * 850 *
854 * Get the value of a TVP7002 decoder device register. 851 * Get the value of a TVP7002 decoder device register.
855 * Returns zero when successful, -EINVAL if register read fails or 852 * Returns zero when successful, -EINVAL if register read fails or
@@ -876,7 +873,7 @@ static int tvp7002_g_register(struct v4l2_subdev *sd,
876/* 873/*
877 * tvp7002_s_register() - set a control 874 * tvp7002_s_register() - set a control
878 * @sd: ptr to v4l2_subdev struct 875 * @sd: ptr to v4l2_subdev struct
879 * @ctrl: ptr to v4l2_control struct 876 * @reg: ptr to v4l2_dbg_register struct
880 * 877 *
881 * Get the value of a TVP7002 decoder device register. 878 * Get the value of a TVP7002 decoder device register.
882 * Returns zero when successful, -EINVAL if register read fails or 879 * Returns zero when successful, -EINVAL if register read fails or
@@ -899,7 +896,7 @@ static int tvp7002_s_register(struct v4l2_subdev *sd,
899/* 896/*
900 * tvp7002_enum_fmt() - Enum supported formats 897 * tvp7002_enum_fmt() - Enum supported formats
901 * @sd: pointer to standard V4L2 sub-device structure 898 * @sd: pointer to standard V4L2 sub-device structure
902 * @enable: pointer to format struct 899 * @fmtdesc: pointer to format struct
903 * 900 *
904 * Enumerate supported formats. 901 * Enumerate supported formats.
905 */ 902 */
@@ -994,6 +991,23 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
994 return 0; 991 return 0;
995} 992}
996 993
994/*
995 * tvp7002_enum_dv_presets() - Enum supported digital video formats
996 * @sd: pointer to standard V4L2 sub-device structure
997 * @preset: pointer to format struct
998 *
999 * Enumerate supported digital video formats.
1000 */
1001static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
1002 struct v4l2_dv_enum_preset *preset)
1003{
1004 /* Check requested format index is within range */
1005 if (preset->index >= NUM_PRESETS)
1006 return -EINVAL;
1007
1008 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
1009}
1010
997/* V4L2 core operation handlers */ 1011/* V4L2 core operation handlers */
998static const struct v4l2_subdev_core_ops tvp7002_core_ops = { 1012static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
999 .g_chip_ident = tvp7002_g_chip_ident, 1013 .g_chip_ident = tvp7002_g_chip_ident,
@@ -1009,6 +1023,7 @@ static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
1009 1023
1010/* Specific video subsystem operation handlers */ 1024/* Specific video subsystem operation handlers */
1011static const struct v4l2_subdev_video_ops tvp7002_video_ops = { 1025static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
1026 .enum_dv_presets = tvp7002_enum_dv_presets,
1012 .s_dv_preset = tvp7002_s_dv_preset, 1027 .s_dv_preset = tvp7002_s_dv_preset,
1013 .query_dv_preset = tvp7002_query_dv_preset, 1028 .query_dv_preset = tvp7002_query_dv_preset,
1014 .s_stream = tvp7002_s_stream, 1029 .s_stream = tvp7002_s_stream,
@@ -1042,8 +1057,8 @@ static struct tvp7002 tvp7002_dev = {
1042 1057
1043/* 1058/*
1044 * tvp7002_probe - Probe a TVP7002 device 1059 * tvp7002_probe - Probe a TVP7002 device
1045 * @sd: ptr to v4l2_subdev struct 1060 * @c: ptr to i2c_client struct
1046 * @ctrl: ptr to i2c_device_id struct 1061 * @id: ptr to i2c_device_id struct
1047 * 1062 *
1048 * Initialize the TVP7002 device 1063 * Initialize the TVP7002 device
1049 * Returns zero when successful, -EINVAL if register read fails or 1064 * Returns zero when successful, -EINVAL if register read fails or
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index fab48ec6c0ea..fbd665fa1979 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -693,12 +693,13 @@ static int qcm_start_data(struct uvd *uvd)
693 693
694static void qcm_stop_data(struct uvd *uvd) 694static void qcm_stop_data(struct uvd *uvd)
695{ 695{
696 struct qcm *cam = (struct qcm *) uvd->user_data; 696 struct qcm *cam;
697 int i, j; 697 int i, j;
698 int ret; 698 int ret;
699 699
700 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL)) 700 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
701 return; 701 return;
702 cam = (struct qcm *) uvd->user_data;
702 703
703 ret = qcm_camera_off(uvd); 704 ret = qcm_camera_off(uvd);
704 if (ret) 705 if (ret)
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 083765238a6a..42ba28785750 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -244,6 +244,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
244 switch (usbvision_device_data[usbvision->DevModel].Codec) { 244 switch (usbvision_device_data[usbvision->DevModel].Codec) {
245 case CODEC_SAA7113: 245 case CODEC_SAA7113:
246 case CODEC_SAA7111: 246 case CODEC_SAA7111:
247 /* Without this delay the detection of the saa711x is
248 hit-and-miss. */
249 mdelay(10);
247 v4l2_i2c_new_subdev(&usbvision->v4l2_dev, 250 v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
248 &usbvision->i2c_adap, "saa7115", 251 &usbvision->i2c_adap, "saa7115",
249 "saa7115_auto", 0, saa711x_addrs); 252 "saa7115_auto", 0, saa711x_addrs);
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 7c17ec63c5da..6248a639ba2d 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -137,8 +137,6 @@ static int PowerOnAtOpen = 1;
137static int video_nr = -1; 137static int video_nr = -1;
138/* Sequential Number of Radio Device */ 138/* Sequential Number of Radio Device */
139static int radio_nr = -1; 139static int radio_nr = -1;
140/* Sequential Number of VBI Device */
141static int vbi_nr = -1;
142 140
143/* Grab parameters for the device driver */ 141/* Grab parameters for the device driver */
144 142
@@ -148,14 +146,12 @@ module_param(video_debug, int, 0444);
148module_param(PowerOnAtOpen, int, 0444); 146module_param(PowerOnAtOpen, int, 0444);
149module_param(video_nr, int, 0444); 147module_param(video_nr, int, 0444);
150module_param(radio_nr, int, 0444); 148module_param(radio_nr, int, 0444);
151module_param(vbi_nr, int, 0444);
152 149
153MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)"); 150MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
154MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)"); 151MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");
155MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened. Default: 1 (On)"); 152MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened. Default: 1 (On)");
156MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)"); 153MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
157MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)"); 154MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
158MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)");
159 155
160 156
161// Misc stuff 157// Misc stuff
@@ -1244,36 +1240,6 @@ static int usbvision_radio_close(struct file *file)
1244 return errCode; 1240 return errCode;
1245} 1241}
1246 1242
1247/*
1248 * Here comes the stuff for vbi on usbvision based devices
1249 *
1250 */
1251static int usbvision_vbi_open(struct file *file)
1252{
1253 /* TODO */
1254 return -ENODEV;
1255}
1256
1257static int usbvision_vbi_close(struct file *file)
1258{
1259 /* TODO */
1260 return -ENODEV;
1261}
1262
1263static long usbvision_do_vbi_ioctl(struct file *file,
1264 unsigned int cmd, void *arg)
1265{
1266 /* TODO */
1267 return -ENOIOCTLCMD;
1268}
1269
1270static long usbvision_vbi_ioctl(struct file *file,
1271 unsigned int cmd, unsigned long arg)
1272{
1273 return video_usercopy(file, cmd, arg, usbvision_do_vbi_ioctl);
1274}
1275
1276
1277// 1243//
1278// Video registration stuff 1244// Video registration stuff
1279// 1245//
@@ -1367,21 +1333,6 @@ static struct video_device usbvision_radio_template = {
1367 .current_norm = V4L2_STD_PAL 1333 .current_norm = V4L2_STD_PAL
1368}; 1334};
1369 1335
1370// vbi template
1371static const struct v4l2_file_operations usbvision_vbi_fops = {
1372 .owner = THIS_MODULE,
1373 .open = usbvision_vbi_open,
1374 .release = usbvision_vbi_close,
1375 .ioctl = usbvision_vbi_ioctl,
1376};
1377
1378static struct video_device usbvision_vbi_template=
1379{
1380 .fops = &usbvision_vbi_fops,
1381 .release = video_device_release,
1382 .name = "usbvision-vbi",
1383};
1384
1385 1336
1386static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, 1337static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
1387 struct video_device *vdev_template, 1338 struct video_device *vdev_template,
@@ -1410,18 +1361,6 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
1410// unregister video4linux devices 1361// unregister video4linux devices
1411static void usbvision_unregister_video(struct usb_usbvision *usbvision) 1362static void usbvision_unregister_video(struct usb_usbvision *usbvision)
1412{ 1363{
1413 // vbi Device:
1414 if (usbvision->vbi) {
1415 PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
1416 video_device_node_name(usbvision->vbi));
1417 if (video_is_registered(usbvision->vbi)) {
1418 video_unregister_device(usbvision->vbi);
1419 } else {
1420 video_device_release(usbvision->vbi);
1421 }
1422 usbvision->vbi = NULL;
1423 }
1424
1425 // Radio Device: 1364 // Radio Device:
1426 if (usbvision->rdev) { 1365 if (usbvision->rdev) {
1427 PDEBUG(DBG_PROBE, "unregister %s [v4l2]", 1366 PDEBUG(DBG_PROBE, "unregister %s [v4l2]",
@@ -1482,22 +1421,6 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
1482 printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", 1421 printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n",
1483 usbvision->nr, video_device_node_name(usbvision->rdev)); 1422 usbvision->nr, video_device_node_name(usbvision->rdev));
1484 } 1423 }
1485 // vbi Device:
1486 if (usbvision_device_data[usbvision->DevModel].vbi) {
1487 usbvision->vbi = usbvision_vdev_init(usbvision,
1488 &usbvision_vbi_template,
1489 "USBVision VBI");
1490 if (usbvision->vbi == NULL) {
1491 goto err_exit;
1492 }
1493 if (video_register_device(usbvision->vbi,
1494 VFL_TYPE_VBI,
1495 vbi_nr)<0) {
1496 goto err_exit;
1497 }
1498 printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device %s [v4l2] (Not Working Yet!)\n",
1499 usbvision->nr, video_device_node_name(usbvision->vbi));
1500 }
1501 // all done 1424 // all done
1502 return 0; 1425 return 0;
1503 1426
@@ -1726,8 +1649,6 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
1726 usbvision_configure_video(usbvision); 1649 usbvision_configure_video(usbvision);
1727 mutex_unlock(&usbvision->lock); 1650 mutex_unlock(&usbvision->lock);
1728 1651
1729
1730 usb_set_intfdata (intf, usbvision);
1731 usbvision_create_sysfs(usbvision->vdev); 1652 usbvision_create_sysfs(usbvision->vdev);
1732 1653
1733 PDEBUG(DBG_PROBE, "success"); 1654 PDEBUG(DBG_PROBE, "success");
@@ -1745,7 +1666,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
1745 */ 1666 */
1746static void __devexit usbvision_disconnect(struct usb_interface *intf) 1667static void __devexit usbvision_disconnect(struct usb_interface *intf)
1747{ 1668{
1748 struct usb_usbvision *usbvision = usb_get_intfdata(intf); 1669 struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf));
1749 1670
1750 PDEBUG(DBG_PROBE, ""); 1671 PDEBUG(DBG_PROBE, "");
1751 1672
@@ -1754,7 +1675,6 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
1754 "%s: usb_get_intfdata() failed\n", __func__); 1675 "%s: usb_get_intfdata() failed\n", __func__);
1755 return; 1676 return;
1756 } 1677 }
1757 usb_set_intfdata (intf, NULL);
1758 1678
1759 mutex_lock(&usbvision->lock); 1679 mutex_lock(&usbvision->lock);
1760 1680
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index f8d7458daf3e..d1b3cc0cd87f 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -360,7 +360,6 @@ struct usb_usbvision {
360 struct v4l2_device v4l2_dev; 360 struct v4l2_device v4l2_dev;
361 struct video_device *vdev; /* Video Device */ 361 struct video_device *vdev; /* Video Device */
362 struct video_device *rdev; /* Radio Device */ 362 struct video_device *rdev; /* Radio Device */
363 struct video_device *vbi; /* VBI Device */
364 363
365 /* i2c Declaration Section*/ 364 /* i2c Declaration Section*/
366 struct i2c_adapter i2c_adap; 365 struct i2c_adapter i2c_adap;
@@ -463,6 +462,11 @@ struct usb_usbvision {
463 int ComprBlockTypes[4]; 462 int ComprBlockTypes[4];
464}; 463};
465 464
465static inline struct usb_usbvision *to_usbvision(struct v4l2_device *v4l2_dev)
466{
467 return container_of(v4l2_dev, struct usb_usbvision, v4l2_dev);
468}
469
466#define call_all(usbvision, o, f, args...) \ 470#define call_all(usbvision, o, f, args...) \
467 v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args) 471 v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args)
468 472
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 6d3850b37161..aa0720af07a0 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -217,8 +217,7 @@ static struct uvc_control_info uvc_ctrls[] = {
217 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL, 217 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
218 .index = 4, 218 .index = 4,
219 .size = 1, 219 .size = 1,
220 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 220 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_RESTORE,
221 | UVC_CONTROL_RESTORE,
222 }, 221 },
223 { 222 {
224 .entity = UVC_GUID_UVC_CAMERA, 223 .entity = UVC_GUID_UVC_CAMERA,
@@ -233,8 +232,9 @@ static struct uvc_control_info uvc_ctrls[] = {
233 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL, 232 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
234 .index = 6, 233 .index = 6,
235 .size = 2, 234 .size = 2,
236 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 235 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
237 | UVC_CONTROL_AUTO_UPDATE, 236 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
237 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
238 }, 238 },
239 { 239 {
240 .entity = UVC_GUID_UVC_CAMERA, 240 .entity = UVC_GUID_UVC_CAMERA,
@@ -249,8 +249,7 @@ static struct uvc_control_info uvc_ctrls[] = {
249 .selector = UVC_CT_IRIS_RELATIVE_CONTROL, 249 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
250 .index = 8, 250 .index = 8,
251 .size = 1, 251 .size = 1,
252 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 252 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_AUTO_UPDATE,
253 | UVC_CONTROL_AUTO_UPDATE,
254 }, 253 },
255 { 254 {
256 .entity = UVC_GUID_UVC_CAMERA, 255 .entity = UVC_GUID_UVC_CAMERA,
@@ -265,8 +264,9 @@ static struct uvc_control_info uvc_ctrls[] = {
265 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL, 264 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
266 .index = 10, 265 .index = 10,
267 .size = 3, 266 .size = 3,
268 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 267 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
269 | UVC_CONTROL_AUTO_UPDATE, 268 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
269 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
270 }, 270 },
271 { 271 {
272 .entity = UVC_GUID_UVC_CAMERA, 272 .entity = UVC_GUID_UVC_CAMERA,
@@ -281,8 +281,9 @@ static struct uvc_control_info uvc_ctrls[] = {
281 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL, 281 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
282 .index = 12, 282 .index = 12,
283 .size = 4, 283 .size = 4,
284 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 284 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
285 | UVC_CONTROL_AUTO_UPDATE, 285 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
286 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
286 }, 287 },
287 { 288 {
288 .entity = UVC_GUID_UVC_CAMERA, 289 .entity = UVC_GUID_UVC_CAMERA,
@@ -297,8 +298,9 @@ static struct uvc_control_info uvc_ctrls[] = {
297 .selector = UVC_CT_ROLL_RELATIVE_CONTROL, 298 .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
298 .index = 14, 299 .index = 14,
299 .size = 2, 300 .size = 2,
300 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 301 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
301 | UVC_CONTROL_AUTO_UPDATE, 302 | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
303 | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
302 }, 304 },
303 { 305 {
304 .entity = UVC_GUID_UVC_CAMERA, 306 .entity = UVC_GUID_UVC_CAMERA,
@@ -562,6 +564,26 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
562 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, 564 .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN,
563 }, 565 },
564 { 566 {
567 .id = V4L2_CID_IRIS_ABSOLUTE,
568 .name = "Iris, Absolute",
569 .entity = UVC_GUID_UVC_CAMERA,
570 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
571 .size = 16,
572 .offset = 0,
573 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
574 .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
575 },
576 {
577 .id = V4L2_CID_IRIS_RELATIVE,
578 .name = "Iris, Relative",
579 .entity = UVC_GUID_UVC_CAMERA,
580 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
581 .size = 8,
582 .offset = 0,
583 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
584 .data_type = UVC_CTRL_DATA_TYPE_SIGNED,
585 },
586 {
565 .id = V4L2_CID_ZOOM_ABSOLUTE, 587 .id = V4L2_CID_ZOOM_ABSOLUTE,
566 .name = "Zoom, Absolute", 588 .name = "Zoom, Absolute",
567 .entity = UVC_GUID_UVC_CAMERA, 589 .entity = UVC_GUID_UVC_CAMERA,
@@ -822,6 +844,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
822 strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); 844 strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
823 v4l2_ctrl->flags = 0; 845 v4l2_ctrl->flags = 0;
824 846
847 if (!(ctrl->info->flags & UVC_CONTROL_GET_CUR))
848 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
825 if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) 849 if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
826 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 850 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
827 851
@@ -1047,6 +1071,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1047 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); 1071 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
1048 step = mapping->get(mapping, UVC_GET_RES, 1072 step = mapping->get(mapping, UVC_GET_RES,
1049 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); 1073 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
1074 if (step == 0)
1075 step = 1;
1050 1076
1051 xctrl->value = min + (xctrl->value - min + step/2) / step * step; 1077 xctrl->value = min + (xctrl->value - min + step/2) / step * step;
1052 xctrl->value = clamp(xctrl->value, min, max); 1078 xctrl->value = clamp(xctrl->value, min, max);
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 86ff8c12ea58..838b56f097cf 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -91,11 +91,16 @@ static struct uvc_format_desc uvc_fmts[] = {
91 .fcc = V4L2_PIX_FMT_UYVY, 91 .fcc = V4L2_PIX_FMT_UYVY,
92 }, 92 },
93 { 93 {
94 .name = "Greyscale", 94 .name = "Greyscale (8-bit)",
95 .guid = UVC_GUID_FORMAT_Y800, 95 .guid = UVC_GUID_FORMAT_Y800,
96 .fcc = V4L2_PIX_FMT_GREY, 96 .fcc = V4L2_PIX_FMT_GREY,
97 }, 97 },
98 { 98 {
99 .name = "Greyscale (16-bit)",
100 .guid = UVC_GUID_FORMAT_Y16,
101 .fcc = V4L2_PIX_FMT_Y16,
102 },
103 {
99 .name = "RGB Bayer", 104 .name = "RGB Bayer",
100 .guid = UVC_GUID_FORMAT_BY8, 105 .guid = UVC_GUID_FORMAT_BY8,
101 .fcc = V4L2_PIX_FMT_SBGGR8, 106 .fcc = V4L2_PIX_FMT_SBGGR8,
@@ -2105,6 +2110,15 @@ static struct usb_device_id uvc_ids[] = {
2105 .bInterfaceSubClass = 1, 2110 .bInterfaceSubClass = 1,
2106 .bInterfaceProtocol = 0, 2111 .bInterfaceProtocol = 0,
2107 .driver_info = UVC_QUIRK_STREAM_NO_FID }, 2112 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2113 /* Syntek (Packard Bell EasyNote MX52 */
2114 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2115 | USB_DEVICE_ID_MATCH_INT_INFO,
2116 .idVendor = 0x174f,
2117 .idProduct = 0x8a12,
2118 .bInterfaceClass = USB_CLASS_VIDEO,
2119 .bInterfaceSubClass = 1,
2120 .bInterfaceProtocol = 0,
2121 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2108 /* Syntek (Asus F9SG) */ 2122 /* Syntek (Asus F9SG) */
2109 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2123 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2110 | USB_DEVICE_ID_MATCH_INT_INFO, 2124 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2169,6 +2183,15 @@ static struct usb_device_id uvc_ids[] = {
2169 .bInterfaceSubClass = 1, 2183 .bInterfaceSubClass = 1,
2170 .bInterfaceProtocol = 0, 2184 .bInterfaceProtocol = 0,
2171 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 2185 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2186 /* Arkmicro unbranded */
2187 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2188 | USB_DEVICE_ID_MATCH_INT_INFO,
2189 .idVendor = 0x18ec,
2190 .idProduct = 0x3290,
2191 .bInterfaceClass = USB_CLASS_VIDEO,
2192 .bInterfaceSubClass = 1,
2193 .bInterfaceProtocol = 0,
2194 .driver_info = UVC_QUIRK_PROBE_DEF },
2172 /* Bodelin ProScopeHR */ 2195 /* Bodelin ProScopeHR */
2173 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2196 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2174 | USB_DEVICE_ID_MATCH_DEV_HI 2197 | USB_DEVICE_ID_MATCH_DEV_HI
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 4a925a31b0e0..133c78d113ac 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -388,8 +388,12 @@ unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
388 388
389 poll_wait(file, &buf->wait, wait); 389 poll_wait(file, &buf->wait, wait);
390 if (buf->state == UVC_BUF_STATE_DONE || 390 if (buf->state == UVC_BUF_STATE_DONE ||
391 buf->state == UVC_BUF_STATE_ERROR) 391 buf->state == UVC_BUF_STATE_ERROR) {
392 mask |= POLLIN | POLLRDNORM; 392 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
393 mask |= POLLIN | POLLRDNORM;
394 else
395 mask |= POLLOUT | POLLWRNORM;
396 }
393 397
394done: 398done:
395 mutex_unlock(&queue->mutex); 399 mutex_unlock(&queue->mutex);
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 2bba059259e6..d1f88406a5e7 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -131,11 +131,13 @@ struct uvc_xu_control {
131#define UVC_GUID_FORMAT_Y800 \ 131#define UVC_GUID_FORMAT_Y800 \
132 { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ 132 { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
133 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 133 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
134#define UVC_GUID_FORMAT_Y16 \
135 { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
136 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
134#define UVC_GUID_FORMAT_BY8 \ 137#define UVC_GUID_FORMAT_BY8 \
135 { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 138 { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
136 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 139 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
137 140
138
139/* ------------------------------------------------------------------------ 141/* ------------------------------------------------------------------------
140 * Driver specific constants. 142 * Driver specific constants.
141 */ 143 */
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 36b5cb86fb57..4e53b0b3339c 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -51,6 +51,9 @@
51#include <linux/string.h> 51#include <linux/string.h>
52#include <linux/errno.h> 52#include <linux/errno.h>
53#include <linux/i2c.h> 53#include <linux/i2c.h>
54#if defined(CONFIG_SPI)
55#include <linux/spi/spi.h>
56#endif
54#include <asm/uaccess.h> 57#include <asm/uaccess.h>
55#include <asm/system.h> 58#include <asm/system.h>
56#include <asm/pgtable.h> 59#include <asm/pgtable.h>
@@ -85,10 +88,9 @@ MODULE_LICENSE("GPL");
85 val == V4L2_PRIORITY_INTERACTIVE || \ 88 val == V4L2_PRIORITY_INTERACTIVE || \
86 val == V4L2_PRIORITY_RECORD) 89 val == V4L2_PRIORITY_RECORD)
87 90
88int v4l2_prio_init(struct v4l2_prio_state *global) 91void v4l2_prio_init(struct v4l2_prio_state *global)
89{ 92{
90 memset(global,0,sizeof(*global)); 93 memset(global, 0, sizeof(*global));
91 return 0;
92} 94}
93EXPORT_SYMBOL(v4l2_prio_init); 95EXPORT_SYMBOL(v4l2_prio_init);
94 96
@@ -108,17 +110,16 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
108} 110}
109EXPORT_SYMBOL(v4l2_prio_change); 111EXPORT_SYMBOL(v4l2_prio_change);
110 112
111int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local) 113void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
112{ 114{
113 return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT); 115 v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
114} 116}
115EXPORT_SYMBOL(v4l2_prio_open); 117EXPORT_SYMBOL(v4l2_prio_open);
116 118
117int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local) 119void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
118{ 120{
119 if (V4L2_PRIO_VALID(*local)) 121 if (V4L2_PRIO_VALID(local))
120 atomic_dec(&global->prios[*local]); 122 atomic_dec(&global->prios[local]);
121 return 0;
122} 123}
123EXPORT_SYMBOL(v4l2_prio_close); 124EXPORT_SYMBOL(v4l2_prio_close);
124 125
@@ -134,11 +135,9 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
134} 135}
135EXPORT_SYMBOL(v4l2_prio_max); 136EXPORT_SYMBOL(v4l2_prio_max);
136 137
137int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) 138int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
138{ 139{
139 if (*local < v4l2_prio_max(global)) 140 return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
140 return -EBUSY;
141 return 0;
142} 141}
143EXPORT_SYMBOL(v4l2_prio_check); 142EXPORT_SYMBOL(v4l2_prio_check);
144 143
@@ -340,6 +339,13 @@ const char **v4l2_ctrl_get_menu(u32 id)
340 "None", 339 "None",
341 "Black & White", 340 "Black & White",
342 "Sepia", 341 "Sepia",
342 "Negative",
343 "Emboss",
344 "Sketch",
345 "Sky blue",
346 "Grass green",
347 "Skin whiten",
348 "Vivid",
343 NULL 349 NULL
344 }; 350 };
345 static const char *tune_preemphasis[] = { 351 static const char *tune_preemphasis[] = {
@@ -429,10 +435,13 @@ const char *v4l2_ctrl_get_name(u32 id)
429 case V4L2_CID_SHARPNESS: return "Sharpness"; 435 case V4L2_CID_SHARPNESS: return "Sharpness";
430 case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; 436 case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
431 case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; 437 case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
438 case V4L2_CID_CHROMA_GAIN: return "Chroma Gain";
432 case V4L2_CID_COLOR_KILLER: return "Color Killer"; 439 case V4L2_CID_COLOR_KILLER: return "Color Killer";
433 case V4L2_CID_COLORFX: return "Color Effects"; 440 case V4L2_CID_COLORFX: return "Color Effects";
441 case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic";
442 case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter";
434 case V4L2_CID_ROTATE: return "Rotate"; 443 case V4L2_CID_ROTATE: return "Rotate";
435 case V4L2_CID_BG_COLOR: return "Background color"; 444 case V4L2_CID_BG_COLOR: return "Background Color";
436 445
437 /* MPEG controls */ 446 /* MPEG controls */
438 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; 447 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
@@ -483,6 +492,8 @@ const char *v4l2_ctrl_get_name(u32 id)
483 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute"; 492 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute";
484 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative"; 493 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative";
485 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic"; 494 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic";
495 case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute";
496 case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative";
486 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute"; 497 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute";
487 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative"; 498 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative";
488 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; 499 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
@@ -620,6 +631,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
620 case V4L2_CID_BLUE_BALANCE: 631 case V4L2_CID_BLUE_BALANCE:
621 case V4L2_CID_GAMMA: 632 case V4L2_CID_GAMMA:
622 case V4L2_CID_SHARPNESS: 633 case V4L2_CID_SHARPNESS:
634 case V4L2_CID_CHROMA_GAIN:
623 case V4L2_CID_RDS_TX_DEVIATION: 635 case V4L2_CID_RDS_TX_DEVIATION:
624 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: 636 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
625 case V4L2_CID_AUDIO_LIMITER_DEVIATION: 637 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
@@ -636,6 +648,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
636 case V4L2_CID_PAN_RELATIVE: 648 case V4L2_CID_PAN_RELATIVE:
637 case V4L2_CID_TILT_RELATIVE: 649 case V4L2_CID_TILT_RELATIVE:
638 case V4L2_CID_FOCUS_RELATIVE: 650 case V4L2_CID_FOCUS_RELATIVE:
651 case V4L2_CID_IRIS_RELATIVE:
639 case V4L2_CID_ZOOM_RELATIVE: 652 case V4L2_CID_ZOOM_RELATIVE:
640 qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; 653 qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
641 break; 654 break;
@@ -951,6 +964,66 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
951 964
952#endif /* defined(CONFIG_I2C) */ 965#endif /* defined(CONFIG_I2C) */
953 966
967#if defined(CONFIG_SPI)
968
969/* Load a spi sub-device. */
970
971void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
972 const struct v4l2_subdev_ops *ops)
973{
974 v4l2_subdev_init(sd, ops);
975 sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
976 /* the owner is the same as the spi_device's driver owner */
977 sd->owner = spi->dev.driver->owner;
978 /* spi_device and v4l2_subdev point to one another */
979 v4l2_set_subdevdata(sd, spi);
980 spi_set_drvdata(spi, sd);
981 /* initialize name */
982 strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name));
983}
984EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
985
986struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
987 struct spi_master *master, struct spi_board_info *info)
988{
989 struct v4l2_subdev *sd = NULL;
990 struct spi_device *spi = NULL;
991
992 BUG_ON(!v4l2_dev);
993
994 if (info->modalias)
995 request_module(info->modalias);
996
997 spi = spi_new_device(master, info);
998
999 if (spi == NULL || spi->dev.driver == NULL)
1000 goto error;
1001
1002 if (!try_module_get(spi->dev.driver->owner))
1003 goto error;
1004
1005 sd = spi_get_drvdata(spi);
1006
1007 /* Register with the v4l2_device which increases the module's
1008 use count as well. */
1009 if (v4l2_device_register_subdev(v4l2_dev, sd))
1010 sd = NULL;
1011
1012 /* Decrease the module use count to match the first try_module_get. */
1013 module_put(spi->dev.driver->owner);
1014
1015error:
1016 /* If we have a client but no subdev, then something went wrong and
1017 we must unregister the client. */
1018 if (spi && sd == NULL)
1019 spi_unregister_device(spi);
1020
1021 return sd;
1022}
1023EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
1024
1025#endif /* defined(CONFIG_SPI) */
1026
954/* Clamp x to be between min and max, aligned to a multiple of 2^align. min 1027/* Clamp x to be between min and max, aligned to a multiple of 2^align. min
955 * and max don't have to be aligned, but there must be at least one valid 1028 * and max don't have to be aligned, but there must be at least one valid
956 * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples 1029 * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index f77f84bfe714..9004a5fe7643 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -1086,6 +1086,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1086 case VIDIOC_QUERY_DV_PRESET: 1086 case VIDIOC_QUERY_DV_PRESET:
1087 case VIDIOC_S_DV_TIMINGS: 1087 case VIDIOC_S_DV_TIMINGS:
1088 case VIDIOC_G_DV_TIMINGS: 1088 case VIDIOC_G_DV_TIMINGS:
1089 case VIDIOC_DQEVENT:
1090 case VIDIOC_SUBSCRIBE_EVENT:
1091 case VIDIOC_UNSUBSCRIBE_EVENT:
1089 ret = do_video_ioctl(file, cmd, arg); 1092 ret = do_video_ioctl(file, cmd, arg);
1090 break; 1093 break;
1091 1094
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 709069916068..0ca7ec9ca902 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -421,6 +421,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
421 if (!vdev->release) 421 if (!vdev->release)
422 return -EINVAL; 422 return -EINVAL;
423 423
424 /* v4l2_fh support */
425 spin_lock_init(&vdev->fh_lock);
426 INIT_LIST_HEAD(&vdev->fh_list);
427
424 /* Part 1: check device type */ 428 /* Part 1: check device type */
425 switch (type) { 429 switch (type) {
426 case VFL_TYPE_GRABBER: 430 case VFL_TYPE_GRABBER:
@@ -596,9 +600,7 @@ void video_unregister_device(struct video_device *vdev)
596 if (!vdev || !video_is_registered(vdev)) 600 if (!vdev || !video_is_registered(vdev))
597 return; 601 return;
598 602
599 mutex_lock(&videodev_lock);
600 clear_bit(V4L2_FL_REGISTERED, &vdev->flags); 603 clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
601 mutex_unlock(&videodev_lock);
602 device_unregister(&vdev->dev); 604 device_unregister(&vdev->dev);
603} 605}
604EXPORT_SYMBOL(video_unregister_device); 606EXPORT_SYMBOL(video_unregister_device);
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 0d06e7cbd5b3..5a7dc4afe92a 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -21,6 +21,9 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/ioctl.h> 22#include <linux/ioctl.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#if defined(CONFIG_SPI)
25#include <linux/spi/spi.h>
26#endif
24#include <linux/videodev2.h> 27#include <linux/videodev2.h>
25#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
26 29
@@ -97,6 +100,14 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
97 i2c_unregister_device(client); 100 i2c_unregister_device(client);
98 } 101 }
99#endif 102#endif
103#if defined(CONFIG_SPI)
104 if (sd->flags & V4L2_SUBDEV_FL_IS_SPI) {
105 struct spi_device *spi = v4l2_get_subdevdata(sd);
106
107 if (spi)
108 spi_unregister_device(spi);
109 }
110#endif
100 } 111 }
101} 112}
102EXPORT_SYMBOL_GPL(v4l2_device_unregister); 113EXPORT_SYMBOL_GPL(v4l2_device_unregister);
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c
new file mode 100644
index 000000000000..de74ce07b5e2
--- /dev/null
+++ b/drivers/media/video/v4l2-event.c
@@ -0,0 +1,292 @@
1/*
2 * v4l2-event.c
3 *
4 * V4L2 events.
5 *
6 * Copyright (C) 2009--2010 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include <media/v4l2-dev.h>
26#include <media/v4l2-fh.h>
27#include <media/v4l2-event.h>
28
29#include <linux/sched.h>
30#include <linux/slab.h>
31
32int v4l2_event_init(struct v4l2_fh *fh)
33{
34 fh->events = kzalloc(sizeof(*fh->events), GFP_KERNEL);
35 if (fh->events == NULL)
36 return -ENOMEM;
37
38 init_waitqueue_head(&fh->events->wait);
39
40 INIT_LIST_HEAD(&fh->events->free);
41 INIT_LIST_HEAD(&fh->events->available);
42 INIT_LIST_HEAD(&fh->events->subscribed);
43
44 fh->events->sequence = -1;
45
46 return 0;
47}
48EXPORT_SYMBOL_GPL(v4l2_event_init);
49
50int v4l2_event_alloc(struct v4l2_fh *fh, unsigned int n)
51{
52 struct v4l2_events *events = fh->events;
53 unsigned long flags;
54
55 if (!events) {
56 WARN_ON(1);
57 return -ENOMEM;
58 }
59
60 while (events->nallocated < n) {
61 struct v4l2_kevent *kev;
62
63 kev = kzalloc(sizeof(*kev), GFP_KERNEL);
64 if (kev == NULL)
65 return -ENOMEM;
66
67 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
68 list_add_tail(&kev->list, &events->free);
69 events->nallocated++;
70 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
71 }
72
73 return 0;
74}
75EXPORT_SYMBOL_GPL(v4l2_event_alloc);
76
77#define list_kfree(list, type, member) \
78 while (!list_empty(list)) { \
79 type *hi; \
80 hi = list_first_entry(list, type, member); \
81 list_del(&hi->member); \
82 kfree(hi); \
83 }
84
85void v4l2_event_free(struct v4l2_fh *fh)
86{
87 struct v4l2_events *events = fh->events;
88
89 if (!events)
90 return;
91
92 list_kfree(&events->free, struct v4l2_kevent, list);
93 list_kfree(&events->available, struct v4l2_kevent, list);
94 list_kfree(&events->subscribed, struct v4l2_subscribed_event, list);
95
96 kfree(events);
97 fh->events = NULL;
98}
99EXPORT_SYMBOL_GPL(v4l2_event_free);
100
101static int __v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event)
102{
103 struct v4l2_events *events = fh->events;
104 struct v4l2_kevent *kev;
105 unsigned long flags;
106
107 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
108
109 if (list_empty(&events->available)) {
110 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
111 return -ENOENT;
112 }
113
114 WARN_ON(events->navailable == 0);
115
116 kev = list_first_entry(&events->available, struct v4l2_kevent, list);
117 list_move(&kev->list, &events->free);
118 events->navailable--;
119
120 kev->event.pending = events->navailable;
121 *event = kev->event;
122
123 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
124
125 return 0;
126}
127
128int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
129 int nonblocking)
130{
131 struct v4l2_events *events = fh->events;
132 int ret;
133
134 if (nonblocking)
135 return __v4l2_event_dequeue(fh, event);
136
137 do {
138 ret = wait_event_interruptible(events->wait,
139 events->navailable != 0);
140 if (ret < 0)
141 return ret;
142
143 ret = __v4l2_event_dequeue(fh, event);
144 } while (ret == -ENOENT);
145
146 return ret;
147}
148EXPORT_SYMBOL_GPL(v4l2_event_dequeue);
149
150/* Caller must hold fh->event->lock! */
151static struct v4l2_subscribed_event *v4l2_event_subscribed(
152 struct v4l2_fh *fh, u32 type)
153{
154 struct v4l2_events *events = fh->events;
155 struct v4l2_subscribed_event *sev;
156
157 assert_spin_locked(&fh->vdev->fh_lock);
158
159 list_for_each_entry(sev, &events->subscribed, list) {
160 if (sev->type == type)
161 return sev;
162 }
163
164 return NULL;
165}
166
167void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
168{
169 struct v4l2_fh *fh;
170 unsigned long flags;
171 struct timespec timestamp;
172
173 ktime_get_ts(&timestamp);
174
175 spin_lock_irqsave(&vdev->fh_lock, flags);
176
177 list_for_each_entry(fh, &vdev->fh_list, list) {
178 struct v4l2_events *events = fh->events;
179 struct v4l2_kevent *kev;
180
181 /* Are we subscribed? */
182 if (!v4l2_event_subscribed(fh, ev->type))
183 continue;
184
185 /* Increase event sequence number on fh. */
186 events->sequence++;
187
188 /* Do we have any free events? */
189 if (list_empty(&events->free))
190 continue;
191
192 /* Take one and fill it. */
193 kev = list_first_entry(&events->free, struct v4l2_kevent, list);
194 kev->event.type = ev->type;
195 kev->event.u = ev->u;
196 kev->event.timestamp = timestamp;
197 kev->event.sequence = events->sequence;
198 list_move_tail(&kev->list, &events->available);
199
200 events->navailable++;
201
202 wake_up_all(&events->wait);
203 }
204
205 spin_unlock_irqrestore(&vdev->fh_lock, flags);
206}
207EXPORT_SYMBOL_GPL(v4l2_event_queue);
208
209int v4l2_event_pending(struct v4l2_fh *fh)
210{
211 return fh->events->navailable;
212}
213EXPORT_SYMBOL_GPL(v4l2_event_pending);
214
215int v4l2_event_subscribe(struct v4l2_fh *fh,
216 struct v4l2_event_subscription *sub)
217{
218 struct v4l2_events *events = fh->events;
219 struct v4l2_subscribed_event *sev;
220 unsigned long flags;
221
222 if (fh->events == NULL) {
223 WARN_ON(1);
224 return -ENOMEM;
225 }
226
227 sev = kmalloc(sizeof(*sev), GFP_KERNEL);
228 if (!sev)
229 return -ENOMEM;
230
231 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
232
233 if (v4l2_event_subscribed(fh, sub->type) == NULL) {
234 INIT_LIST_HEAD(&sev->list);
235 sev->type = sub->type;
236
237 list_add(&sev->list, &events->subscribed);
238 sev = NULL;
239 }
240
241 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
242
243 kfree(sev);
244
245 return 0;
246}
247EXPORT_SYMBOL_GPL(v4l2_event_subscribe);
248
249static void v4l2_event_unsubscribe_all(struct v4l2_fh *fh)
250{
251 struct v4l2_events *events = fh->events;
252 struct v4l2_subscribed_event *sev;
253 unsigned long flags;
254
255 do {
256 sev = NULL;
257
258 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
259 if (!list_empty(&events->subscribed)) {
260 sev = list_first_entry(&events->subscribed,
261 struct v4l2_subscribed_event, list);
262 list_del(&sev->list);
263 }
264 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
265 kfree(sev);
266 } while (sev);
267}
268
269int v4l2_event_unsubscribe(struct v4l2_fh *fh,
270 struct v4l2_event_subscription *sub)
271{
272 struct v4l2_subscribed_event *sev;
273 unsigned long flags;
274
275 if (sub->type == V4L2_EVENT_ALL) {
276 v4l2_event_unsubscribe_all(fh);
277 return 0;
278 }
279
280 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
281
282 sev = v4l2_event_subscribed(fh, sub->type);
283 if (sev != NULL)
284 list_del(&sev->list);
285
286 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
287
288 kfree(sev);
289
290 return 0;
291}
292EXPORT_SYMBOL_GPL(v4l2_event_unsubscribe);
diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/video/v4l2-fh.c
new file mode 100644
index 000000000000..d78f184f40c5
--- /dev/null
+++ b/drivers/media/video/v4l2-fh.c
@@ -0,0 +1,79 @@
1/*
2 * v4l2-fh.c
3 *
4 * V4L2 file handles.
5 *
6 * Copyright (C) 2009--2010 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include <linux/bitops.h>
26#include <media/v4l2-dev.h>
27#include <media/v4l2-fh.h>
28#include <media/v4l2-event.h>
29#include <media/v4l2-ioctl.h>
30
31int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
32{
33 fh->vdev = vdev;
34 INIT_LIST_HEAD(&fh->list);
35 set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
36
37 /*
38 * fh->events only needs to be initialized if the driver
39 * supports the VIDIOC_SUBSCRIBE_EVENT ioctl.
40 */
41 if (vdev->ioctl_ops && vdev->ioctl_ops->vidioc_subscribe_event)
42 return v4l2_event_init(fh);
43
44 fh->events = NULL;
45
46 return 0;
47}
48EXPORT_SYMBOL_GPL(v4l2_fh_init);
49
50void v4l2_fh_add(struct v4l2_fh *fh)
51{
52 unsigned long flags;
53
54 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
55 list_add(&fh->list, &fh->vdev->fh_list);
56 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
57}
58EXPORT_SYMBOL_GPL(v4l2_fh_add);
59
60void v4l2_fh_del(struct v4l2_fh *fh)
61{
62 unsigned long flags;
63
64 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
65 list_del_init(&fh->list);
66 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
67}
68EXPORT_SYMBOL_GPL(v4l2_fh_del);
69
70void v4l2_fh_exit(struct v4l2_fh *fh)
71{
72 if (fh->vdev == NULL)
73 return;
74
75 fh->vdev = NULL;
76
77 v4l2_event_free(fh);
78}
79EXPORT_SYMBOL_GPL(v4l2_fh_exit);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 7d59c107f13b..0eeceae50329 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -26,6 +26,8 @@
26#endif 26#endif
27#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
28#include <media/v4l2-ioctl.h> 28#include <media/v4l2-ioctl.h>
29#include <media/v4l2-fh.h>
30#include <media/v4l2-event.h>
29#include <media/v4l2-chip-ident.h> 31#include <media/v4l2-chip-ident.h>
30 32
31#define dbgarg(cmd, fmt, arg...) \ 33#define dbgarg(cmd, fmt, arg...) \
@@ -291,6 +293,9 @@ static const char *v4l2_ioctls[] = {
291 [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", 293 [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET",
292 [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", 294 [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS",
293 [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", 295 [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS",
296 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
297 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
298 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
294}; 299};
295#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 300#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
296 301
@@ -610,17 +615,33 @@ static long __video_do_ioctl(struct file *file,
610 void *fh = file->private_data; 615 void *fh = file->private_data;
611 long ret = -EINVAL; 616 long ret = -EINVAL;
612 617
618 if (ops == NULL) {
619 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
620 vfd->name);
621 return -EINVAL;
622 }
623
624#ifdef CONFIG_VIDEO_V4L1_COMPAT
625 /********************************************************
626 All other V4L1 calls are handled by v4l1_compat module.
627 Those calls will be translated into V4L2 calls, and
628 __video_do_ioctl will be called again, with one or more
629 V4L2 ioctls.
630 ********************************************************/
631 if (_IOC_TYPE(cmd) == 'v' && cmd != VIDIOCGMBUF &&
632 _IOC_NR(cmd) < BASE_VIDIOCPRIVATE) {
633 return v4l_compat_translate_ioctl(file, cmd, arg,
634 __video_do_ioctl);
635 }
636#endif
637
613 if ((vfd->debug & V4L2_DEBUG_IOCTL) && 638 if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
614 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { 639 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
615 v4l_print_ioctl(vfd->name, cmd); 640 v4l_print_ioctl(vfd->name, cmd);
616 printk(KERN_CONT "\n"); 641 printk(KERN_CONT "\n");
617 } 642 }
618 643
619 if (ops == NULL) { 644 switch (cmd) {
620 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
621 vfd->name);
622 return -EINVAL;
623 }
624 645
625#ifdef CONFIG_VIDEO_V4L1_COMPAT 646#ifdef CONFIG_VIDEO_V4L1_COMPAT
626 /*********************************************************** 647 /***********************************************************
@@ -630,31 +651,21 @@ static long __video_do_ioctl(struct file *file,
630 ***********************************************************/ 651 ***********************************************************/
631 652
632 /* --- streaming capture ------------------------------------- */ 653 /* --- streaming capture ------------------------------------- */
633 if (cmd == VIDIOCGMBUF) { 654 case VIDIOCGMBUF:
655 {
634 struct video_mbuf *p = arg; 656 struct video_mbuf *p = arg;
635 657
636 if (!ops->vidiocgmbuf) 658 if (!ops->vidiocgmbuf)
637 return ret; 659 break;
638 ret = ops->vidiocgmbuf(file, fh, p); 660 ret = ops->vidiocgmbuf(file, fh, p);
639 if (!ret) 661 if (!ret)
640 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n", 662 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
641 p->size, p->frames, 663 p->size, p->frames,
642 (unsigned long)p->offsets); 664 (unsigned long)p->offsets);
643 return ret; 665 break;
644 } 666 }
645
646 /********************************************************
647 All other V4L1 calls are handled by v4l1_compat module.
648 Those calls will be translated into V4L2 calls, and
649 __video_do_ioctl will be called again, with one or more
650 V4L2 ioctls.
651 ********************************************************/
652 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
653 return v4l_compat_translate_ioctl(file, cmd, arg,
654 __video_do_ioctl);
655#endif 667#endif
656 668
657 switch (cmd) {
658 /* --- capabilities ------------------------------------------ */ 669 /* --- capabilities ------------------------------------------ */
659 case VIDIOC_QUERYCAP: 670 case VIDIOC_QUERYCAP:
660 { 671 {
@@ -1072,7 +1083,7 @@ static long __video_do_ioctl(struct file *file,
1072 id &= ~curr_id; 1083 id &= ~curr_id;
1073 } 1084 }
1074 if (i <= index) 1085 if (i <= index)
1075 return -EINVAL; 1086 break;
1076 1087
1077 v4l2_video_std_construct(p, curr_id, descr); 1088 v4l2_video_std_construct(p, curr_id, descr);
1078 1089
@@ -1597,7 +1608,7 @@ static long __video_do_ioctl(struct file *file,
1597 v4l2_std_id std = vfd->current_norm; 1608 v4l2_std_id std = vfd->current_norm;
1598 1609
1599 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1610 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1600 return -EINVAL; 1611 break;
1601 1612
1602 ret = 0; 1613 ret = 0;
1603 if (ops->vidioc_g_std) 1614 if (ops->vidioc_g_std)
@@ -1942,7 +1953,55 @@ static long __video_do_ioctl(struct file *file,
1942 } 1953 }
1943 break; 1954 break;
1944 } 1955 }
1956 case VIDIOC_DQEVENT:
1957 {
1958 struct v4l2_event *ev = arg;
1959
1960 if (!ops->vidioc_subscribe_event)
1961 break;
1945 1962
1963 ret = v4l2_event_dequeue(fh, ev, file->f_flags & O_NONBLOCK);
1964 if (ret < 0) {
1965 dbgarg(cmd, "no pending events?");
1966 break;
1967 }
1968 dbgarg(cmd,
1969 "pending=%d, type=0x%8.8x, sequence=%d, "
1970 "timestamp=%lu.%9.9lu ",
1971 ev->pending, ev->type, ev->sequence,
1972 ev->timestamp.tv_sec, ev->timestamp.tv_nsec);
1973 break;
1974 }
1975 case VIDIOC_SUBSCRIBE_EVENT:
1976 {
1977 struct v4l2_event_subscription *sub = arg;
1978
1979 if (!ops->vidioc_subscribe_event)
1980 break;
1981
1982 ret = ops->vidioc_subscribe_event(fh, sub);
1983 if (ret < 0) {
1984 dbgarg(cmd, "failed, ret=%ld", ret);
1985 break;
1986 }
1987 dbgarg(cmd, "type=0x%8.8x", sub->type);
1988 break;
1989 }
1990 case VIDIOC_UNSUBSCRIBE_EVENT:
1991 {
1992 struct v4l2_event_subscription *sub = arg;
1993
1994 if (!ops->vidioc_unsubscribe_event)
1995 break;
1996
1997 ret = ops->vidioc_unsubscribe_event(fh, sub);
1998 if (ret < 0) {
1999 dbgarg(cmd, "failed, ret=%ld", ret);
2000 break;
2001 }
2002 dbgarg(cmd, "type=0x%8.8x", sub->type);
2003 break;
2004 }
1946 default: 2005 default:
1947 { 2006 {
1948 if (!ops->vidioc_default) 2007 if (!ops->vidioc_default)
@@ -2006,7 +2065,7 @@ long video_ioctl2(struct file *file,
2006{ 2065{
2007 char sbuf[128]; 2066 char sbuf[128];
2008 void *mbuf = NULL; 2067 void *mbuf = NULL;
2009 void *parg = NULL; 2068 void *parg = (void *)arg;
2010 long err = -EINVAL; 2069 long err = -EINVAL;
2011 int is_ext_ctrl; 2070 int is_ext_ctrl;
2012 size_t ctrls_size = 0; 2071 size_t ctrls_size = 0;
diff --git a/drivers/media/video/v4l2-mem2mem.c b/drivers/media/video/v4l2-mem2mem.c
new file mode 100644
index 000000000000..f45f9405ea39
--- /dev/null
+++ b/drivers/media/video/v4l2-mem2mem.c
@@ -0,0 +1,633 @@
1/*
2 * Memory-to-memory device framework for Video for Linux 2 and videobuf.
3 *
4 * Helper functions for devices that use videobuf buffers for both their
5 * source and destination.
6 *
7 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
8 * Pawel Osciak, <p.osciak@samsung.com>
9 * Marek Szyprowski, <m.szyprowski@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/module.h>
17#include <linux/sched.h>
18#include <linux/slab.h>
19
20#include <media/videobuf-core.h>
21#include <media/v4l2-mem2mem.h>
22
23MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
24MODULE_AUTHOR("Pawel Osciak, <p.osciak@samsung.com>");
25MODULE_LICENSE("GPL");
26
27static bool debug;
28module_param(debug, bool, 0644);
29
30#define dprintk(fmt, arg...) \
31 do { \
32 if (debug) \
33 printk(KERN_DEBUG "%s: " fmt, __func__, ## arg);\
34 } while (0)
35
36
37/* Instance is already queued on the job_queue */
38#define TRANS_QUEUED (1 << 0)
39/* Instance is currently running in hardware */
40#define TRANS_RUNNING (1 << 1)
41
42
43/* Offset base for buffers on the destination queue - used to distinguish
44 * between source and destination buffers when mmapping - they receive the same
45 * offsets but for different queues */
46#define DST_QUEUE_OFF_BASE (1 << 30)
47
48
49/**
50 * struct v4l2_m2m_dev - per-device context
51 * @curr_ctx: currently running instance
52 * @job_queue: instances queued to run
53 * @job_spinlock: protects job_queue
54 * @m2m_ops: driver callbacks
55 */
56struct v4l2_m2m_dev {
57 struct v4l2_m2m_ctx *curr_ctx;
58
59 struct list_head job_queue;
60 spinlock_t job_spinlock;
61
62 struct v4l2_m2m_ops *m2m_ops;
63};
64
65static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx,
66 enum v4l2_buf_type type)
67{
68 switch (type) {
69 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
70 return &m2m_ctx->cap_q_ctx;
71 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
72 return &m2m_ctx->out_q_ctx;
73 default:
74 printk(KERN_ERR "Invalid buffer type\n");
75 return NULL;
76 }
77}
78
79/**
80 * v4l2_m2m_get_vq() - return videobuf_queue for the given type
81 */
82struct videobuf_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
83 enum v4l2_buf_type type)
84{
85 struct v4l2_m2m_queue_ctx *q_ctx;
86
87 q_ctx = get_queue_ctx(m2m_ctx, type);
88 if (!q_ctx)
89 return NULL;
90
91 return &q_ctx->q;
92}
93EXPORT_SYMBOL(v4l2_m2m_get_vq);
94
95/**
96 * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers
97 */
98void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type)
99{
100 struct v4l2_m2m_queue_ctx *q_ctx;
101 struct videobuf_buffer *vb = NULL;
102 unsigned long flags;
103
104 q_ctx = get_queue_ctx(m2m_ctx, type);
105 if (!q_ctx)
106 return NULL;
107
108 spin_lock_irqsave(q_ctx->q.irqlock, flags);
109
110 if (list_empty(&q_ctx->rdy_queue))
111 goto end;
112
113 vb = list_entry(q_ctx->rdy_queue.next, struct videobuf_buffer, queue);
114 vb->state = VIDEOBUF_ACTIVE;
115
116end:
117 spin_unlock_irqrestore(q_ctx->q.irqlock, flags);
118 return vb;
119}
120EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf);
121
122/**
123 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
124 * return it
125 */
126void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type)
127{
128 struct v4l2_m2m_queue_ctx *q_ctx;
129 struct videobuf_buffer *vb = NULL;
130 unsigned long flags;
131
132 q_ctx = get_queue_ctx(m2m_ctx, type);
133 if (!q_ctx)
134 return NULL;
135
136 spin_lock_irqsave(q_ctx->q.irqlock, flags);
137 if (!list_empty(&q_ctx->rdy_queue)) {
138 vb = list_entry(q_ctx->rdy_queue.next, struct videobuf_buffer,
139 queue);
140 list_del(&vb->queue);
141 q_ctx->num_rdy--;
142 }
143 spin_unlock_irqrestore(q_ctx->q.irqlock, flags);
144
145 return vb;
146}
147EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
148
149/*
150 * Scheduling handlers
151 */
152
153/**
154 * v4l2_m2m_get_curr_priv() - return driver private data for the currently
155 * running instance or NULL if no instance is running
156 */
157void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev)
158{
159 unsigned long flags;
160 void *ret = NULL;
161
162 spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
163 if (m2m_dev->curr_ctx)
164 ret = m2m_dev->curr_ctx->priv;
165 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
166
167 return ret;
168}
169EXPORT_SYMBOL(v4l2_m2m_get_curr_priv);
170
171/**
172 * v4l2_m2m_try_run() - select next job to perform and run it if possible
173 *
174 * Get next transaction (if present) from the waiting jobs list and run it.
175 */
176static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
177{
178 unsigned long flags;
179
180 spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
181 if (NULL != m2m_dev->curr_ctx) {
182 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
183 dprintk("Another instance is running, won't run now\n");
184 return;
185 }
186
187 if (list_empty(&m2m_dev->job_queue)) {
188 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
189 dprintk("No job pending\n");
190 return;
191 }
192
193 m2m_dev->curr_ctx = list_entry(m2m_dev->job_queue.next,
194 struct v4l2_m2m_ctx, queue);
195 m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING;
196 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
197
198 m2m_dev->m2m_ops->device_run(m2m_dev->curr_ctx->priv);
199}
200
201/**
202 * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to
203 * the pending job queue and add it if so.
204 * @m2m_ctx: m2m context assigned to the instance to be checked
205 *
206 * There are three basic requirements an instance has to meet to be able to run:
207 * 1) at least one source buffer has to be queued,
208 * 2) at least one destination buffer has to be queued,
209 * 3) streaming has to be on.
210 *
211 * There may also be additional, custom requirements. In such case the driver
212 * should supply a custom callback (job_ready in v4l2_m2m_ops) that should
213 * return 1 if the instance is ready.
214 * An example of the above could be an instance that requires more than one
215 * src/dst buffer per transaction.
216 */
217static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
218{
219 struct v4l2_m2m_dev *m2m_dev;
220 unsigned long flags_job, flags;
221
222 m2m_dev = m2m_ctx->m2m_dev;
223 dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
224
225 if (!m2m_ctx->out_q_ctx.q.streaming
226 || !m2m_ctx->cap_q_ctx.q.streaming) {
227 dprintk("Streaming needs to be on for both queues\n");
228 return;
229 }
230
231 spin_lock_irqsave(&m2m_dev->job_spinlock, flags_job);
232 if (m2m_ctx->job_flags & TRANS_QUEUED) {
233 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
234 dprintk("On job queue already\n");
235 return;
236 }
237
238 spin_lock_irqsave(m2m_ctx->out_q_ctx.q.irqlock, flags);
239 if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) {
240 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags);
241 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
242 dprintk("No input buffers available\n");
243 return;
244 }
245 if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) {
246 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags);
247 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
248 dprintk("No output buffers available\n");
249 return;
250 }
251 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags);
252
253 if (m2m_dev->m2m_ops->job_ready
254 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
255 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
256 dprintk("Driver not ready\n");
257 return;
258 }
259
260 list_add_tail(&m2m_ctx->queue, &m2m_dev->job_queue);
261 m2m_ctx->job_flags |= TRANS_QUEUED;
262
263 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
264
265 v4l2_m2m_try_run(m2m_dev);
266}
267
268/**
269 * v4l2_m2m_job_finish() - inform the framework that a job has been finished
270 * and have it clean up
271 *
272 * Called by a driver to yield back the device after it has finished with it.
273 * Should be called as soon as possible after reaching a state which allows
274 * other instances to take control of the device.
275 *
276 * This function has to be called only after device_run() callback has been
277 * called on the driver. To prevent recursion, it should not be called directly
278 * from the device_run() callback though.
279 */
280void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
281 struct v4l2_m2m_ctx *m2m_ctx)
282{
283 unsigned long flags;
284
285 spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
286 if (!m2m_dev->curr_ctx || m2m_dev->curr_ctx != m2m_ctx) {
287 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
288 dprintk("Called by an instance not currently running\n");
289 return;
290 }
291
292 list_del(&m2m_dev->curr_ctx->queue);
293 m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
294 m2m_dev->curr_ctx = NULL;
295
296 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
297
298 /* This instance might have more buffers ready, but since we do not
299 * allow more than one job on the job_queue per instance, each has
300 * to be scheduled separately after the previous one finishes. */
301 v4l2_m2m_try_schedule(m2m_ctx);
302 v4l2_m2m_try_run(m2m_dev);
303}
304EXPORT_SYMBOL(v4l2_m2m_job_finish);
305
306/**
307 * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer
308 */
309int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
310 struct v4l2_requestbuffers *reqbufs)
311{
312 struct videobuf_queue *vq;
313
314 vq = v4l2_m2m_get_vq(m2m_ctx, reqbufs->type);
315 return videobuf_reqbufs(vq, reqbufs);
316}
317EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
318
319/**
320 * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer
321 *
322 * See v4l2_m2m_mmap() documentation for details.
323 */
324int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
325 struct v4l2_buffer *buf)
326{
327 struct videobuf_queue *vq;
328 int ret;
329
330 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
331 ret = videobuf_querybuf(vq, buf);
332
333 if (buf->memory == V4L2_MEMORY_MMAP
334 && vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
335 buf->m.offset += DST_QUEUE_OFF_BASE;
336 }
337
338 return ret;
339}
340EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
341
342/**
343 * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on
344 * the type
345 */
346int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
347 struct v4l2_buffer *buf)
348{
349 struct videobuf_queue *vq;
350 int ret;
351
352 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
353 ret = videobuf_qbuf(vq, buf);
354 if (!ret)
355 v4l2_m2m_try_schedule(m2m_ctx);
356
357 return ret;
358}
359EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);
360
361/**
362 * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on
363 * the type
364 */
365int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
366 struct v4l2_buffer *buf)
367{
368 struct videobuf_queue *vq;
369
370 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
371 return videobuf_dqbuf(vq, buf, file->f_flags & O_NONBLOCK);
372}
373EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
374
375/**
376 * v4l2_m2m_streamon() - turn on streaming for a video queue
377 */
378int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
379 enum v4l2_buf_type type)
380{
381 struct videobuf_queue *vq;
382 int ret;
383
384 vq = v4l2_m2m_get_vq(m2m_ctx, type);
385 ret = videobuf_streamon(vq);
386 if (!ret)
387 v4l2_m2m_try_schedule(m2m_ctx);
388
389 return ret;
390}
391EXPORT_SYMBOL_GPL(v4l2_m2m_streamon);
392
393/**
394 * v4l2_m2m_streamoff() - turn off streaming for a video queue
395 */
396int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
397 enum v4l2_buf_type type)
398{
399 struct videobuf_queue *vq;
400
401 vq = v4l2_m2m_get_vq(m2m_ctx, type);
402 return videobuf_streamoff(vq);
403}
404EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
405
406/**
407 * v4l2_m2m_poll() - poll replacement, for destination buffers only
408 *
409 * Call from the driver's poll() function. Will poll both queues. If a buffer
410 * is available to dequeue (with dqbuf) from the source queue, this will
411 * indicate that a non-blocking write can be performed, while read will be
412 * returned in case of the destination queue.
413 */
414unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
415 struct poll_table_struct *wait)
416{
417 struct videobuf_queue *src_q, *dst_q;
418 struct videobuf_buffer *src_vb = NULL, *dst_vb = NULL;
419 unsigned int rc = 0;
420
421 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
422 dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
423
424 mutex_lock(&src_q->vb_lock);
425 mutex_lock(&dst_q->vb_lock);
426
427 if (src_q->streaming && !list_empty(&src_q->stream))
428 src_vb = list_first_entry(&src_q->stream,
429 struct videobuf_buffer, stream);
430 if (dst_q->streaming && !list_empty(&dst_q->stream))
431 dst_vb = list_first_entry(&dst_q->stream,
432 struct videobuf_buffer, stream);
433
434 if (!src_vb && !dst_vb) {
435 rc = POLLERR;
436 goto end;
437 }
438
439 if (src_vb) {
440 poll_wait(file, &src_vb->done, wait);
441 if (src_vb->state == VIDEOBUF_DONE
442 || src_vb->state == VIDEOBUF_ERROR)
443 rc |= POLLOUT | POLLWRNORM;
444 }
445 if (dst_vb) {
446 poll_wait(file, &dst_vb->done, wait);
447 if (dst_vb->state == VIDEOBUF_DONE
448 || dst_vb->state == VIDEOBUF_ERROR)
449 rc |= POLLIN | POLLRDNORM;
450 }
451
452end:
453 mutex_unlock(&dst_q->vb_lock);
454 mutex_unlock(&src_q->vb_lock);
455 return rc;
456}
457EXPORT_SYMBOL_GPL(v4l2_m2m_poll);
458
459/**
460 * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer
461 *
462 * Call from driver's mmap() function. Will handle mmap() for both queues
463 * seamlessly for videobuffer, which will receive normal per-queue offsets and
464 * proper videobuf queue pointers. The differentiation is made outside videobuf
465 * by adding a predefined offset to buffers from one of the queues and
466 * subtracting it before passing it back to videobuf. Only drivers (and
467 * thus applications) receive modified offsets.
468 */
469int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
470 struct vm_area_struct *vma)
471{
472 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
473 struct videobuf_queue *vq;
474
475 if (offset < DST_QUEUE_OFF_BASE) {
476 vq = v4l2_m2m_get_src_vq(m2m_ctx);
477 } else {
478 vq = v4l2_m2m_get_dst_vq(m2m_ctx);
479 vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
480 }
481
482 return videobuf_mmap_mapper(vq, vma);
483}
484EXPORT_SYMBOL(v4l2_m2m_mmap);
485
486/**
487 * v4l2_m2m_init() - initialize per-driver m2m data
488 *
489 * Usually called from driver's probe() function.
490 */
491struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops)
492{
493 struct v4l2_m2m_dev *m2m_dev;
494
495 if (!m2m_ops)
496 return ERR_PTR(-EINVAL);
497
498 BUG_ON(!m2m_ops->device_run);
499 BUG_ON(!m2m_ops->job_abort);
500
501 m2m_dev = kzalloc(sizeof *m2m_dev, GFP_KERNEL);
502 if (!m2m_dev)
503 return ERR_PTR(-ENOMEM);
504
505 m2m_dev->curr_ctx = NULL;
506 m2m_dev->m2m_ops = m2m_ops;
507 INIT_LIST_HEAD(&m2m_dev->job_queue);
508 spin_lock_init(&m2m_dev->job_spinlock);
509
510 return m2m_dev;
511}
512EXPORT_SYMBOL_GPL(v4l2_m2m_init);
513
514/**
515 * v4l2_m2m_release() - cleans up and frees a m2m_dev structure
516 *
517 * Usually called from driver's remove() function.
518 */
519void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev)
520{
521 kfree(m2m_dev);
522}
523EXPORT_SYMBOL_GPL(v4l2_m2m_release);
524
525/**
526 * v4l2_m2m_ctx_init() - allocate and initialize a m2m context
527 * @priv - driver's instance private data
528 * @m2m_dev - a previously initialized m2m_dev struct
529 * @vq_init - a callback for queue type-specific initialization function to be
530 * used for initializing videobuf_queues
531 *
532 * Usually called from driver's open() function.
533 */
534struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(void *priv, struct v4l2_m2m_dev *m2m_dev,
535 void (*vq_init)(void *priv, struct videobuf_queue *,
536 enum v4l2_buf_type))
537{
538 struct v4l2_m2m_ctx *m2m_ctx;
539 struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx;
540
541 if (!vq_init)
542 return ERR_PTR(-EINVAL);
543
544 m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL);
545 if (!m2m_ctx)
546 return ERR_PTR(-ENOMEM);
547
548 m2m_ctx->priv = priv;
549 m2m_ctx->m2m_dev = m2m_dev;
550
551 out_q_ctx = get_queue_ctx(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
552 cap_q_ctx = get_queue_ctx(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
553
554 INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
555 INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
556
557 INIT_LIST_HEAD(&m2m_ctx->queue);
558
559 vq_init(priv, &out_q_ctx->q, V4L2_BUF_TYPE_VIDEO_OUTPUT);
560 vq_init(priv, &cap_q_ctx->q, V4L2_BUF_TYPE_VIDEO_CAPTURE);
561 out_q_ctx->q.priv_data = cap_q_ctx->q.priv_data = priv;
562
563 return m2m_ctx;
564}
565EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
566
567/**
568 * v4l2_m2m_ctx_release() - release m2m context
569 *
570 * Usually called from driver's release() function.
571 */
572void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
573{
574 struct v4l2_m2m_dev *m2m_dev;
575 struct videobuf_buffer *vb;
576 unsigned long flags;
577
578 m2m_dev = m2m_ctx->m2m_dev;
579
580 spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
581 if (m2m_ctx->job_flags & TRANS_RUNNING) {
582 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
583 m2m_dev->m2m_ops->job_abort(m2m_ctx->priv);
584 dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx);
585 vb = v4l2_m2m_next_dst_buf(m2m_ctx);
586 BUG_ON(NULL == vb);
587 wait_event(vb->done, vb->state != VIDEOBUF_ACTIVE
588 && vb->state != VIDEOBUF_QUEUED);
589 } else if (m2m_ctx->job_flags & TRANS_QUEUED) {
590 list_del(&m2m_ctx->queue);
591 m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
592 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
593 dprintk("m2m_ctx: %p had been on queue and was removed\n",
594 m2m_ctx);
595 } else {
596 /* Do nothing, was not on queue/running */
597 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
598 }
599
600 videobuf_stop(&m2m_ctx->cap_q_ctx.q);
601 videobuf_stop(&m2m_ctx->out_q_ctx.q);
602
603 videobuf_mmap_free(&m2m_ctx->cap_q_ctx.q);
604 videobuf_mmap_free(&m2m_ctx->out_q_ctx.q);
605
606 kfree(m2m_ctx);
607}
608EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_release);
609
610/**
611 * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list.
612 *
613 * Call from buf_queue(), videobuf_queue_ops callback.
614 *
615 * Locking: Caller holds q->irqlock (taken by videobuf before calling buf_queue
616 * callback in the driver).
617 */
618void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct videobuf_queue *vq,
619 struct videobuf_buffer *vb)
620{
621 struct v4l2_m2m_queue_ctx *q_ctx;
622
623 q_ctx = get_queue_ctx(m2m_ctx, vq->type);
624 if (!q_ctx)
625 return;
626
627 list_add_tail(&vb->queue, &q_ctx->rdy_queue);
628 q_ctx->num_rdy++;
629
630 vb->state = VIDEOBUF_QUEUED;
631}
632EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
633
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index bb0a1c8de414..7d3378437ded 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -24,10 +24,15 @@
24#include <media/videobuf-core.h> 24#include <media/videobuf-core.h>
25 25
26#define MAGIC_BUFFER 0x20070728 26#define MAGIC_BUFFER 0x20070728
27#define MAGIC_CHECK(is, should) do { \ 27#define MAGIC_CHECK(is, should) \
28 if (unlikely((is) != (should))) { \ 28 do { \
29 printk(KERN_ERR "magic mismatch: %x (expected %x)\n", is, should); \ 29 if (unlikely((is) != (should))) { \
30 BUG(); } } while (0) 30 printk(KERN_ERR \
31 "magic mismatch: %x (expected %x)\n", \
32 is, should); \
33 BUG(); \
34 } \
35 } while (0)
31 36
32static int debug; 37static int debug;
33module_param(debug, int, 0644); 38module_param(debug, int, 0644);
@@ -36,16 +41,18 @@ MODULE_DESCRIPTION("helper module to manage video4linux buffers");
36MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 41MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
37MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
38 43
39#define dprintk(level, fmt, arg...) do { \ 44#define dprintk(level, fmt, arg...) \
40 if (debug >= level) \ 45 do { \
41 printk(KERN_DEBUG "vbuf: " fmt , ## arg); } while (0) 46 if (debug >= level) \
47 printk(KERN_DEBUG "vbuf: " fmt, ## arg); \
48 } while (0)
42 49
43/* --------------------------------------------------------------------- */ 50/* --------------------------------------------------------------------- */
44 51
45#define CALL(q, f, arg...) \ 52#define CALL(q, f, arg...) \
46 ((q->int_ops->f) ? q->int_ops->f(arg) : 0) 53 ((q->int_ops->f) ? q->int_ops->f(arg) : 0)
47 54
48void *videobuf_alloc(struct videobuf_queue *q) 55struct videobuf_buffer *videobuf_alloc(struct videobuf_queue *q)
49{ 56{
50 struct videobuf_buffer *vb; 57 struct videobuf_buffer *vb;
51 58
@@ -57,14 +64,14 @@ void *videobuf_alloc(struct videobuf_queue *q)
57 } 64 }
58 65
59 vb = q->int_ops->alloc(q->msize); 66 vb = q->int_ops->alloc(q->msize);
60
61 if (NULL != vb) { 67 if (NULL != vb) {
62 init_waitqueue_head(&vb->done); 68 init_waitqueue_head(&vb->done);
63 vb->magic = MAGIC_BUFFER; 69 vb->magic = MAGIC_BUFFER;
64 } 70 }
65 71
66 return vb; 72 return vb;
67} 73}
74EXPORT_SYMBOL_GPL(videobuf_alloc);
68 75
69#define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\ 76#define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\
70 vb->state != VIDEOBUF_QUEUED) 77 vb->state != VIDEOBUF_QUEUED)
@@ -86,6 +93,7 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
86 93
87 return 0; 94 return 0;
88} 95}
96EXPORT_SYMBOL_GPL(videobuf_waiton);
89 97
90int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, 98int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
91 struct v4l2_framebuffer *fbuf) 99 struct v4l2_framebuffer *fbuf)
@@ -95,16 +103,16 @@ int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
95 103
96 return CALL(q, iolock, q, vb, fbuf); 104 return CALL(q, iolock, q, vb, fbuf);
97} 105}
106EXPORT_SYMBOL_GPL(videobuf_iolock);
98 107
99void *videobuf_queue_to_vmalloc (struct videobuf_queue *q, 108void *videobuf_queue_to_vaddr(struct videobuf_queue *q,
100 struct videobuf_buffer *buf) 109 struct videobuf_buffer *buf)
101{ 110{
102 if (q->int_ops->vmalloc) 111 if (q->int_ops->vaddr)
103 return q->int_ops->vmalloc(buf); 112 return q->int_ops->vaddr(buf);
104 else 113 return NULL;
105 return NULL;
106} 114}
107EXPORT_SYMBOL_GPL(videobuf_queue_to_vmalloc); 115EXPORT_SYMBOL_GPL(videobuf_queue_to_vaddr);
108 116
109/* --------------------------------------------------------------------- */ 117/* --------------------------------------------------------------------- */
110 118
@@ -146,6 +154,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q,
146 init_waitqueue_head(&q->wait); 154 init_waitqueue_head(&q->wait);
147 INIT_LIST_HEAD(&q->stream); 155 INIT_LIST_HEAD(&q->stream);
148} 156}
157EXPORT_SYMBOL_GPL(videobuf_queue_core_init);
149 158
150/* Locking: Only usage in bttv unsafe find way to remove */ 159/* Locking: Only usage in bttv unsafe find way to remove */
151int videobuf_queue_is_busy(struct videobuf_queue *q) 160int videobuf_queue_is_busy(struct videobuf_queue *q)
@@ -184,6 +193,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
184 } 193 }
185 return 0; 194 return 0;
186} 195}
196EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
187 197
188/* Locking: Caller holds q->vb_lock */ 198/* Locking: Caller holds q->vb_lock */
189void videobuf_queue_cancel(struct videobuf_queue *q) 199void videobuf_queue_cancel(struct videobuf_queue *q)
@@ -216,6 +226,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
216 } 226 }
217 INIT_LIST_HEAD(&q->stream); 227 INIT_LIST_HEAD(&q->stream);
218} 228}
229EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
219 230
220/* --------------------------------------------------------------------- */ 231/* --------------------------------------------------------------------- */
221 232
@@ -237,6 +248,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
237 } 248 }
238 return field; 249 return field;
239} 250}
251EXPORT_SYMBOL_GPL(videobuf_next_field);
240 252
241/* Locking: Caller holds q->vb_lock */ 253/* Locking: Caller holds q->vb_lock */
242static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, 254static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
@@ -273,8 +285,10 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
273 case VIDEOBUF_ACTIVE: 285 case VIDEOBUF_ACTIVE:
274 b->flags |= V4L2_BUF_FLAG_QUEUED; 286 b->flags |= V4L2_BUF_FLAG_QUEUED;
275 break; 287 break;
276 case VIDEOBUF_DONE:
277 case VIDEOBUF_ERROR: 288 case VIDEOBUF_ERROR:
289 b->flags |= V4L2_BUF_FLAG_ERROR;
290 /* fall through */
291 case VIDEOBUF_DONE:
278 b->flags |= V4L2_BUF_FLAG_DONE; 292 b->flags |= V4L2_BUF_FLAG_DONE;
279 break; 293 break;
280 case VIDEOBUF_NEEDS_INIT: 294 case VIDEOBUF_NEEDS_INIT:
@@ -298,20 +312,15 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
298static int __videobuf_mmap_free(struct videobuf_queue *q) 312static int __videobuf_mmap_free(struct videobuf_queue *q)
299{ 313{
300 int i; 314 int i;
301 int rc;
302 315
303 if (!q) 316 if (!q)
304 return 0; 317 return 0;
305 318
306 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); 319 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
307 320
308 321 for (i = 0; i < VIDEO_MAX_FRAME; i++)
309 rc = CALL(q, mmap_free, q); 322 if (q->bufs[i] && q->bufs[i]->map)
310 323 return -EBUSY;
311 q->is_mmapped = 0;
312
313 if (rc < 0)
314 return rc;
315 324
316 for (i = 0; i < VIDEO_MAX_FRAME; i++) { 325 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
317 if (NULL == q->bufs[i]) 326 if (NULL == q->bufs[i])
@@ -321,7 +330,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q)
321 q->bufs[i] = NULL; 330 q->bufs[i] = NULL;
322 } 331 }
323 332
324 return rc; 333 return 0;
325} 334}
326 335
327int videobuf_mmap_free(struct videobuf_queue *q) 336int videobuf_mmap_free(struct videobuf_queue *q)
@@ -332,6 +341,7 @@ int videobuf_mmap_free(struct videobuf_queue *q)
332 mutex_unlock(&q->vb_lock); 341 mutex_unlock(&q->vb_lock);
333 return ret; 342 return ret;
334} 343}
344EXPORT_SYMBOL_GPL(videobuf_mmap_free);
335 345
336/* Locking: Caller holds q->vb_lock */ 346/* Locking: Caller holds q->vb_lock */
337int __videobuf_mmap_setup(struct videobuf_queue *q, 347int __videobuf_mmap_setup(struct videobuf_queue *q,
@@ -351,7 +361,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
351 for (i = 0; i < bcount; i++) { 361 for (i = 0; i < bcount; i++) {
352 q->bufs[i] = videobuf_alloc(q); 362 q->bufs[i] = videobuf_alloc(q);
353 363
354 if (q->bufs[i] == NULL) 364 if (NULL == q->bufs[i])
355 break; 365 break;
356 366
357 q->bufs[i]->i = i; 367 q->bufs[i]->i = i;
@@ -372,11 +382,11 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
372 if (!i) 382 if (!i)
373 return -ENOMEM; 383 return -ENOMEM;
374 384
375 dprintk(1, "mmap setup: %d buffers, %d bytes each\n", 385 dprintk(1, "mmap setup: %d buffers, %d bytes each\n", i, bsize);
376 i, bsize);
377 386
378 return i; 387 return i;
379} 388}
389EXPORT_SYMBOL_GPL(__videobuf_mmap_setup);
380 390
381int videobuf_mmap_setup(struct videobuf_queue *q, 391int videobuf_mmap_setup(struct videobuf_queue *q,
382 unsigned int bcount, unsigned int bsize, 392 unsigned int bcount, unsigned int bsize,
@@ -388,6 +398,7 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
388 mutex_unlock(&q->vb_lock); 398 mutex_unlock(&q->vb_lock);
389 return ret; 399 return ret;
390} 400}
401EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
391 402
392int videobuf_reqbufs(struct videobuf_queue *q, 403int videobuf_reqbufs(struct videobuf_queue *q,
393 struct v4l2_requestbuffers *req) 404 struct v4l2_requestbuffers *req)
@@ -432,7 +443,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
432 q->ops->buf_setup(q, &count, &size); 443 q->ops->buf_setup(q, &count, &size);
433 dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n", 444 dprintk(1, "reqbufs: bufs=%d, size=0x%x [%u pages total]\n",
434 count, size, 445 count, size,
435 (unsigned int)((count*PAGE_ALIGN(size))>>PAGE_SHIFT) ); 446 (unsigned int)((count * PAGE_ALIGN(size)) >> PAGE_SHIFT));
436 447
437 retval = __videobuf_mmap_setup(q, count, size, req->memory); 448 retval = __videobuf_mmap_setup(q, count, size, req->memory);
438 if (retval < 0) { 449 if (retval < 0) {
@@ -447,6 +458,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
447 mutex_unlock(&q->vb_lock); 458 mutex_unlock(&q->vb_lock);
448 return retval; 459 return retval;
449} 460}
461EXPORT_SYMBOL_GPL(videobuf_reqbufs);
450 462
451int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) 463int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
452{ 464{
@@ -473,9 +485,9 @@ done:
473 mutex_unlock(&q->vb_lock); 485 mutex_unlock(&q->vb_lock);
474 return ret; 486 return ret;
475} 487}
488EXPORT_SYMBOL_GPL(videobuf_querybuf);
476 489
477int videobuf_qbuf(struct videobuf_queue *q, 490int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
478 struct v4l2_buffer *b)
479{ 491{
480 struct videobuf_buffer *buf; 492 struct videobuf_buffer *buf;
481 enum v4l2_field field; 493 enum v4l2_field field;
@@ -534,6 +546,13 @@ int videobuf_qbuf(struct videobuf_queue *q,
534 "but buffer addr is zero!\n"); 546 "but buffer addr is zero!\n");
535 goto done; 547 goto done;
536 } 548 }
549 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
550 || q->type == V4L2_BUF_TYPE_VBI_OUTPUT
551 || q->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
552 buf->size = b->bytesused;
553 buf->field = b->field;
554 buf->ts = b->timestamp;
555 }
537 break; 556 break;
538 case V4L2_MEMORY_USERPTR: 557 case V4L2_MEMORY_USERPTR:
539 if (b->length < buf->bsize) { 558 if (b->length < buf->bsize) {
@@ -567,11 +586,11 @@ int videobuf_qbuf(struct videobuf_queue *q,
567 q->ops->buf_queue(q, buf); 586 q->ops->buf_queue(q, buf);
568 spin_unlock_irqrestore(q->irqlock, flags); 587 spin_unlock_irqrestore(q->irqlock, flags);
569 } 588 }
570 dprintk(1, "qbuf: succeded\n"); 589 dprintk(1, "qbuf: succeeded\n");
571 retval = 0; 590 retval = 0;
572 wake_up_interruptible_sync(&q->wait); 591 wake_up_interruptible_sync(&q->wait);
573 592
574 done: 593done:
575 mutex_unlock(&q->vb_lock); 594 mutex_unlock(&q->vb_lock);
576 595
577 if (b->memory == V4L2_MEMORY_MMAP) 596 if (b->memory == V4L2_MEMORY_MMAP)
@@ -579,7 +598,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
579 598
580 return retval; 599 return retval;
581} 600}
582 601EXPORT_SYMBOL_GPL(videobuf_qbuf);
583 602
584/* Locking: Caller holds q->vb_lock */ 603/* Locking: Caller holds q->vb_lock */
585static int stream_next_buffer_check_queue(struct videobuf_queue *q, int noblock) 604static int stream_next_buffer_check_queue(struct videobuf_queue *q, int noblock)
@@ -624,7 +643,6 @@ done:
624 return retval; 643 return retval;
625} 644}
626 645
627
628/* Locking: Caller holds q->vb_lock */ 646/* Locking: Caller holds q->vb_lock */
629static int stream_next_buffer(struct videobuf_queue *q, 647static int stream_next_buffer(struct videobuf_queue *q,
630 struct videobuf_buffer **vb, int nonblocking) 648 struct videobuf_buffer **vb, int nonblocking)
@@ -647,13 +665,14 @@ done:
647} 665}
648 666
649int videobuf_dqbuf(struct videobuf_queue *q, 667int videobuf_dqbuf(struct videobuf_queue *q,
650 struct v4l2_buffer *b, int nonblocking) 668 struct v4l2_buffer *b, int nonblocking)
651{ 669{
652 struct videobuf_buffer *buf = NULL; 670 struct videobuf_buffer *buf = NULL;
653 int retval; 671 int retval;
654 672
655 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); 673 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
656 674
675 memset(b, 0, sizeof(*b));
657 mutex_lock(&q->vb_lock); 676 mutex_lock(&q->vb_lock);
658 677
659 retval = stream_next_buffer(q, &buf, nonblocking); 678 retval = stream_next_buffer(q, &buf, nonblocking);
@@ -665,28 +684,25 @@ int videobuf_dqbuf(struct videobuf_queue *q,
665 switch (buf->state) { 684 switch (buf->state) {
666 case VIDEOBUF_ERROR: 685 case VIDEOBUF_ERROR:
667 dprintk(1, "dqbuf: state is error\n"); 686 dprintk(1, "dqbuf: state is error\n");
668 retval = -EIO;
669 CALL(q, sync, q, buf);
670 buf->state = VIDEOBUF_IDLE;
671 break; 687 break;
672 case VIDEOBUF_DONE: 688 case VIDEOBUF_DONE:
673 dprintk(1, "dqbuf: state is done\n"); 689 dprintk(1, "dqbuf: state is done\n");
674 CALL(q, sync, q, buf);
675 buf->state = VIDEOBUF_IDLE;
676 break; 690 break;
677 default: 691 default:
678 dprintk(1, "dqbuf: state invalid\n"); 692 dprintk(1, "dqbuf: state invalid\n");
679 retval = -EINVAL; 693 retval = -EINVAL;
680 goto done; 694 goto done;
681 } 695 }
682 list_del(&buf->stream); 696 CALL(q, sync, q, buf);
683 memset(b, 0, sizeof(*b));
684 videobuf_status(q, b, buf, q->type); 697 videobuf_status(q, b, buf, q->type);
685 698 list_del(&buf->stream);
686 done: 699 buf->state = VIDEOBUF_IDLE;
700 b->flags &= ~V4L2_BUF_FLAG_DONE;
701done:
687 mutex_unlock(&q->vb_lock); 702 mutex_unlock(&q->vb_lock);
688 return retval; 703 return retval;
689} 704}
705EXPORT_SYMBOL_GPL(videobuf_dqbuf);
690 706
691int videobuf_streamon(struct videobuf_queue *q) 707int videobuf_streamon(struct videobuf_queue *q)
692{ 708{
@@ -709,10 +725,11 @@ int videobuf_streamon(struct videobuf_queue *q)
709 spin_unlock_irqrestore(q->irqlock, flags); 725 spin_unlock_irqrestore(q->irqlock, flags);
710 726
711 wake_up_interruptible_sync(&q->wait); 727 wake_up_interruptible_sync(&q->wait);
712 done: 728done:
713 mutex_unlock(&q->vb_lock); 729 mutex_unlock(&q->vb_lock);
714 return retval; 730 return retval;
715} 731}
732EXPORT_SYMBOL_GPL(videobuf_streamon);
716 733
717/* Locking: Caller holds q->vb_lock */ 734/* Locking: Caller holds q->vb_lock */
718static int __videobuf_streamoff(struct videobuf_queue *q) 735static int __videobuf_streamoff(struct videobuf_queue *q)
@@ -735,6 +752,7 @@ int videobuf_streamoff(struct videobuf_queue *q)
735 752
736 return retval; 753 return retval;
737} 754}
755EXPORT_SYMBOL_GPL(videobuf_streamoff);
738 756
739/* Locking: Caller holds q->vb_lock */ 757/* Locking: Caller holds q->vb_lock */
740static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, 758static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
@@ -774,7 +792,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
774 retval = q->read_buf->size; 792 retval = q->read_buf->size;
775 } 793 }
776 794
777 done: 795done:
778 /* cleanup */ 796 /* cleanup */
779 q->ops->buf_release(q, q->read_buf); 797 q->ops->buf_release(q, q->read_buf);
780 kfree(q->read_buf); 798 kfree(q->read_buf);
@@ -782,6 +800,49 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
782 return retval; 800 return retval;
783} 801}
784 802
803static int __videobuf_copy_to_user(struct videobuf_queue *q,
804 struct videobuf_buffer *buf,
805 char __user *data, size_t count,
806 int nonblocking)
807{
808 void *vaddr = CALL(q, vaddr, buf);
809
810 /* copy to userspace */
811 if (count > buf->size - q->read_off)
812 count = buf->size - q->read_off;
813
814 if (copy_to_user(data, vaddr + q->read_off, count))
815 return -EFAULT;
816
817 return count;
818}
819
820static int __videobuf_copy_stream(struct videobuf_queue *q,
821 struct videobuf_buffer *buf,
822 char __user *data, size_t count, size_t pos,
823 int vbihack, int nonblocking)
824{
825 unsigned int *fc = CALL(q, vaddr, buf);
826
827 if (vbihack) {
828 /* dirty, undocumented hack -- pass the frame counter
829 * within the last four bytes of each vbi data block.
830 * We need that one to maintain backward compatibility
831 * to all vbi decoding software out there ... */
832 fc += (buf->size >> 2) - 1;
833 *fc = buf->field_count >> 1;
834 dprintk(1, "vbihack: %d\n", *fc);
835 }
836
837 /* copy stuff using the common method */
838 count = __videobuf_copy_to_user(q, buf, data, count, nonblocking);
839
840 if ((count == -EFAULT) && (pos == 0))
841 return -EFAULT;
842
843 return count;
844}
845
785ssize_t videobuf_read_one(struct videobuf_queue *q, 846ssize_t videobuf_read_one(struct videobuf_queue *q,
786 char __user *data, size_t count, loff_t *ppos, 847 char __user *data, size_t count, loff_t *ppos,
787 int nonblocking) 848 int nonblocking)
@@ -850,7 +911,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
850 } 911 }
851 912
852 /* Copy to userspace */ 913 /* Copy to userspace */
853 retval = CALL(q, video_copy_to_user, q, data, count, nonblocking); 914 retval = __videobuf_copy_to_user(q, q->read_buf, data, count, nonblocking);
854 if (retval < 0) 915 if (retval < 0)
855 goto done; 916 goto done;
856 917
@@ -862,10 +923,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
862 q->read_buf = NULL; 923 q->read_buf = NULL;
863 } 924 }
864 925
865 done: 926done:
866 mutex_unlock(&q->vb_lock); 927 mutex_unlock(&q->vb_lock);
867 return retval; 928 return retval;
868} 929}
930EXPORT_SYMBOL_GPL(videobuf_read_one);
869 931
870/* Locking: Caller holds q->vb_lock */ 932/* Locking: Caller holds q->vb_lock */
871static int __videobuf_read_start(struct videobuf_queue *q) 933static int __videobuf_read_start(struct videobuf_queue *q)
@@ -917,7 +979,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q)
917 q->bufs[i] = NULL; 979 q->bufs[i] = NULL;
918 } 980 }
919 q->read_buf = NULL; 981 q->read_buf = NULL;
920
921} 982}
922 983
923int videobuf_read_start(struct videobuf_queue *q) 984int videobuf_read_start(struct videobuf_queue *q)
@@ -930,6 +991,7 @@ int videobuf_read_start(struct videobuf_queue *q)
930 991
931 return rc; 992 return rc;
932} 993}
994EXPORT_SYMBOL_GPL(videobuf_read_start);
933 995
934void videobuf_read_stop(struct videobuf_queue *q) 996void videobuf_read_stop(struct videobuf_queue *q)
935{ 997{
@@ -937,6 +999,7 @@ void videobuf_read_stop(struct videobuf_queue *q)
937 __videobuf_read_stop(q); 999 __videobuf_read_stop(q);
938 mutex_unlock(&q->vb_lock); 1000 mutex_unlock(&q->vb_lock);
939} 1001}
1002EXPORT_SYMBOL_GPL(videobuf_read_stop);
940 1003
941void videobuf_stop(struct videobuf_queue *q) 1004void videobuf_stop(struct videobuf_queue *q)
942{ 1005{
@@ -950,7 +1013,7 @@ void videobuf_stop(struct videobuf_queue *q)
950 1013
951 mutex_unlock(&q->vb_lock); 1014 mutex_unlock(&q->vb_lock);
952} 1015}
953 1016EXPORT_SYMBOL_GPL(videobuf_stop);
954 1017
955ssize_t videobuf_read_stream(struct videobuf_queue *q, 1018ssize_t videobuf_read_stream(struct videobuf_queue *q,
956 char __user *data, size_t count, loff_t *ppos, 1019 char __user *data, size_t count, loff_t *ppos,
@@ -990,7 +1053,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
990 } 1053 }
991 1054
992 if (q->read_buf->state == VIDEOBUF_DONE) { 1055 if (q->read_buf->state == VIDEOBUF_DONE) {
993 rc = CALL(q, copy_stream, q, data + retval, count, 1056 rc = __videobuf_copy_stream(q, q->read_buf, data + retval, count,
994 retval, vbihack, nonblocking); 1057 retval, vbihack, nonblocking);
995 if (rc < 0) { 1058 if (rc < 0) {
996 retval = rc; 1059 retval = rc;
@@ -1019,10 +1082,11 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
1019 break; 1082 break;
1020 } 1083 }
1021 1084
1022 done: 1085done:
1023 mutex_unlock(&q->vb_lock); 1086 mutex_unlock(&q->vb_lock);
1024 return retval; 1087 return retval;
1025} 1088}
1089EXPORT_SYMBOL_GPL(videobuf_read_stream);
1026 1090
1027unsigned int videobuf_poll_stream(struct file *file, 1091unsigned int videobuf_poll_stream(struct file *file,
1028 struct videobuf_queue *q, 1092 struct videobuf_queue *q,
@@ -1056,27 +1120,51 @@ unsigned int videobuf_poll_stream(struct file *file,
1056 if (0 == rc) { 1120 if (0 == rc) {
1057 poll_wait(file, &buf->done, wait); 1121 poll_wait(file, &buf->done, wait);
1058 if (buf->state == VIDEOBUF_DONE || 1122 if (buf->state == VIDEOBUF_DONE ||
1059 buf->state == VIDEOBUF_ERROR) 1123 buf->state == VIDEOBUF_ERROR) {
1060 rc = POLLIN|POLLRDNORM; 1124 switch (q->type) {
1125 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1126 case V4L2_BUF_TYPE_VBI_OUTPUT:
1127 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1128 rc = POLLOUT | POLLWRNORM;
1129 break;
1130 default:
1131 rc = POLLIN | POLLRDNORM;
1132 break;
1133 }
1134 }
1061 } 1135 }
1062 mutex_unlock(&q->vb_lock); 1136 mutex_unlock(&q->vb_lock);
1063 return rc; 1137 return rc;
1064} 1138}
1139EXPORT_SYMBOL_GPL(videobuf_poll_stream);
1065 1140
1066int videobuf_mmap_mapper(struct videobuf_queue *q, 1141int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
1067 struct vm_area_struct *vma)
1068{ 1142{
1069 int retval; 1143 int rc = -EINVAL;
1144 int i;
1070 1145
1071 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); 1146 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
1072 1147
1148 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
1149 dprintk(1, "mmap appl bug: PROT_WRITE and MAP_SHARED are required\n");
1150 return -EINVAL;
1151 }
1152
1073 mutex_lock(&q->vb_lock); 1153 mutex_lock(&q->vb_lock);
1074 retval = CALL(q, mmap_mapper, q, vma); 1154 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1075 q->is_mmapped = 1; 1155 struct videobuf_buffer *buf = q->bufs[i];
1156
1157 if (buf && buf->memory == V4L2_MEMORY_MMAP &&
1158 buf->boff == (vma->vm_pgoff << PAGE_SHIFT)) {
1159 rc = CALL(q, mmap_mapper, q, buf, vma);
1160 break;
1161 }
1162 }
1076 mutex_unlock(&q->vb_lock); 1163 mutex_unlock(&q->vb_lock);
1077 1164
1078 return retval; 1165 return rc;
1079} 1166}
1167EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
1080 1168
1081#ifdef CONFIG_VIDEO_V4L1_COMPAT 1169#ifdef CONFIG_VIDEO_V4L1_COMPAT
1082int videobuf_cgmbuf(struct videobuf_queue *q, 1170int videobuf_cgmbuf(struct videobuf_queue *q,
@@ -1107,33 +1195,3 @@ int videobuf_cgmbuf(struct videobuf_queue *q,
1107EXPORT_SYMBOL_GPL(videobuf_cgmbuf); 1195EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
1108#endif 1196#endif
1109 1197
1110/* --------------------------------------------------------------------- */
1111
1112EXPORT_SYMBOL_GPL(videobuf_waiton);
1113EXPORT_SYMBOL_GPL(videobuf_iolock);
1114
1115EXPORT_SYMBOL_GPL(videobuf_alloc);
1116
1117EXPORT_SYMBOL_GPL(videobuf_queue_core_init);
1118EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
1119EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
1120
1121EXPORT_SYMBOL_GPL(videobuf_next_field);
1122EXPORT_SYMBOL_GPL(videobuf_reqbufs);
1123EXPORT_SYMBOL_GPL(videobuf_querybuf);
1124EXPORT_SYMBOL_GPL(videobuf_qbuf);
1125EXPORT_SYMBOL_GPL(videobuf_dqbuf);
1126EXPORT_SYMBOL_GPL(videobuf_streamon);
1127EXPORT_SYMBOL_GPL(videobuf_streamoff);
1128
1129EXPORT_SYMBOL_GPL(videobuf_read_start);
1130EXPORT_SYMBOL_GPL(videobuf_read_stop);
1131EXPORT_SYMBOL_GPL(videobuf_stop);
1132EXPORT_SYMBOL_GPL(videobuf_read_stream);
1133EXPORT_SYMBOL_GPL(videobuf_read_one);
1134EXPORT_SYMBOL_GPL(videobuf_poll_stream);
1135
1136EXPORT_SYMBOL_GPL(__videobuf_mmap_setup);
1137EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
1138EXPORT_SYMBOL_GPL(videobuf_mmap_free);
1139EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index dce4f3aa4af1..74730c624cfc 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -55,14 +55,14 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
55 struct videobuf_queue *q = map->q; 55 struct videobuf_queue *q = map->q;
56 int i; 56 int i;
57 57
58 dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", 58 dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
59 map, map->count, vma->vm_start, vma->vm_end); 59 map, map->count, vma->vm_start, vma->vm_end);
60 60
61 map->count--; 61 map->count--;
62 if (0 == map->count) { 62 if (0 == map->count) {
63 struct videobuf_dma_contig_memory *mem; 63 struct videobuf_dma_contig_memory *mem;
64 64
65 dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q); 65 dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
66 mutex_lock(&q->vb_lock); 66 mutex_lock(&q->vb_lock);
67 67
68 /* We need first to cancel streams, before unmapping */ 68 /* We need first to cancel streams, before unmapping */
@@ -89,7 +89,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
89 /* vfree is not atomic - can't be 89 /* vfree is not atomic - can't be
90 called with IRQ's disabled 90 called with IRQ's disabled
91 */ 91 */
92 dev_dbg(map->q->dev, "buf[%d] freeing %p\n", 92 dev_dbg(q->dev, "buf[%d] freeing %p\n",
93 i, mem->vaddr); 93 i, mem->vaddr);
94 94
95 dma_free_coherent(q->dev, mem->size, 95 dma_free_coherent(q->dev, mem->size,
@@ -190,7 +190,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
190 return ret; 190 return ret;
191} 191}
192 192
193static void *__videobuf_alloc(size_t size) 193static struct videobuf_buffer *__videobuf_alloc(size_t size)
194{ 194{
195 struct videobuf_dma_contig_memory *mem; 195 struct videobuf_dma_contig_memory *mem;
196 struct videobuf_buffer *vb; 196 struct videobuf_buffer *vb;
@@ -204,7 +204,7 @@ static void *__videobuf_alloc(size_t size)
204 return vb; 204 return vb;
205} 205}
206 206
207static void *__videobuf_to_vmalloc(struct videobuf_buffer *buf) 207static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
208{ 208{
209 struct videobuf_dma_contig_memory *mem = buf->priv; 209 struct videobuf_dma_contig_memory *mem = buf->priv;
210 210
@@ -263,65 +263,34 @@ static int __videobuf_iolock(struct videobuf_queue *q,
263 return 0; 263 return 0;
264} 264}
265 265
266static int __videobuf_mmap_free(struct videobuf_queue *q)
267{
268 unsigned int i;
269
270 dev_dbg(q->dev, "%s\n", __func__);
271 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
272 if (q->bufs[i] && q->bufs[i]->map)
273 return -EBUSY;
274 }
275
276 return 0;
277}
278
279static int __videobuf_mmap_mapper(struct videobuf_queue *q, 266static int __videobuf_mmap_mapper(struct videobuf_queue *q,
267 struct videobuf_buffer *buf,
280 struct vm_area_struct *vma) 268 struct vm_area_struct *vma)
281{ 269{
282 struct videobuf_dma_contig_memory *mem; 270 struct videobuf_dma_contig_memory *mem;
283 struct videobuf_mapping *map; 271 struct videobuf_mapping *map;
284 unsigned int first;
285 int retval; 272 int retval;
286 unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT; 273 unsigned long size;
287 274
288 dev_dbg(q->dev, "%s\n", __func__); 275 dev_dbg(q->dev, "%s\n", __func__);
289 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
290 return -EINVAL;
291
292 /* look for first buffer to map */
293 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
294 if (!q->bufs[first])
295 continue;
296
297 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
298 continue;
299 if (q->bufs[first]->boff == offset)
300 break;
301 }
302 if (VIDEO_MAX_FRAME == first) {
303 dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
304 offset);
305 return -EINVAL;
306 }
307 276
308 /* create mapping + update buffer list */ 277 /* create mapping + update buffer list */
309 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); 278 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
310 if (!map) 279 if (!map)
311 return -ENOMEM; 280 return -ENOMEM;
312 281
313 q->bufs[first]->map = map; 282 buf->map = map;
314 map->start = vma->vm_start; 283 map->start = vma->vm_start;
315 map->end = vma->vm_end; 284 map->end = vma->vm_end;
316 map->q = q; 285 map->q = q;
317 286
318 q->bufs[first]->baddr = vma->vm_start; 287 buf->baddr = vma->vm_start;
319 288
320 mem = q->bufs[first]->priv; 289 mem = buf->priv;
321 BUG_ON(!mem); 290 BUG_ON(!mem);
322 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); 291 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
323 292
324 mem->size = PAGE_ALIGN(q->bufs[first]->bsize); 293 mem->size = PAGE_ALIGN(buf->bsize);
325 mem->vaddr = dma_alloc_coherent(q->dev, mem->size, 294 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
326 &mem->dma_handle, GFP_KERNEL); 295 &mem->dma_handle, GFP_KERNEL);
327 if (!mem->vaddr) { 296 if (!mem->vaddr) {
@@ -354,8 +323,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
354 323
355 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", 324 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
356 map, q, vma->vm_start, vma->vm_end, 325 map, q, vma->vm_start, vma->vm_end,
357 (long int) q->bufs[first]->bsize, 326 (long int)buf->bsize,
358 vma->vm_pgoff, first); 327 vma->vm_pgoff, buf->i);
359 328
360 videobuf_vm_open(vma); 329 videobuf_vm_open(vma);
361 330
@@ -366,69 +335,13 @@ error:
366 return -ENOMEM; 335 return -ENOMEM;
367} 336}
368 337
369static int __videobuf_copy_to_user(struct videobuf_queue *q,
370 char __user *data, size_t count,
371 int nonblocking)
372{
373 struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
374 void *vaddr;
375
376 BUG_ON(!mem);
377 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
378 BUG_ON(!mem->vaddr);
379
380 /* copy to userspace */
381 if (count > q->read_buf->size - q->read_off)
382 count = q->read_buf->size - q->read_off;
383
384 vaddr = mem->vaddr;
385
386 if (copy_to_user(data, vaddr + q->read_off, count))
387 return -EFAULT;
388
389 return count;
390}
391
392static int __videobuf_copy_stream(struct videobuf_queue *q,
393 char __user *data, size_t count, size_t pos,
394 int vbihack, int nonblocking)
395{
396 unsigned int *fc;
397 struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
398
399 BUG_ON(!mem);
400 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
401
402 if (vbihack) {
403 /* dirty, undocumented hack -- pass the frame counter
404 * within the last four bytes of each vbi data block.
405 * We need that one to maintain backward compatibility
406 * to all vbi decoding software out there ... */
407 fc = (unsigned int *)mem->vaddr;
408 fc += (q->read_buf->size >> 2) - 1;
409 *fc = q->read_buf->field_count >> 1;
410 dev_dbg(q->dev, "vbihack: %d\n", *fc);
411 }
412
413 /* copy stuff using the common method */
414 count = __videobuf_copy_to_user(q, data, count, nonblocking);
415
416 if ((count == -EFAULT) && (pos == 0))
417 return -EFAULT;
418
419 return count;
420}
421
422static struct videobuf_qtype_ops qops = { 338static struct videobuf_qtype_ops qops = {
423 .magic = MAGIC_QTYPE_OPS, 339 .magic = MAGIC_QTYPE_OPS,
424 340
425 .alloc = __videobuf_alloc, 341 .alloc = __videobuf_alloc,
426 .iolock = __videobuf_iolock, 342 .iolock = __videobuf_iolock,
427 .mmap_free = __videobuf_mmap_free,
428 .mmap_mapper = __videobuf_mmap_mapper, 343 .mmap_mapper = __videobuf_mmap_mapper,
429 .video_copy_to_user = __videobuf_copy_to_user, 344 .vaddr = __videobuf_to_vaddr,
430 .copy_stream = __videobuf_copy_stream,
431 .vmalloc = __videobuf_to_vmalloc,
432}; 345};
433 346
434void videobuf_queue_dma_contig_init(struct videobuf_queue *q, 347void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index fcd045e7a1c1..8359e6badd36 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -37,8 +37,12 @@
37#define MAGIC_DMABUF 0x19721112 37#define MAGIC_DMABUF 0x19721112
38#define MAGIC_SG_MEM 0x17890714 38#define MAGIC_SG_MEM 0x17890714
39 39
40#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ 40#define MAGIC_CHECK(is, should) \
41 { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } 41 if (unlikely((is) != (should))) { \
42 printk(KERN_ERR "magic mismatch: %x (expected %x)\n", \
43 is, should); \
44 BUG(); \
45 }
42 46
43static int debug; 47static int debug;
44module_param(debug, int, 0644); 48module_param(debug, int, 0644);
@@ -47,13 +51,13 @@ MODULE_DESCRIPTION("helper module to manage video4linux dma sg buffers");
47MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 51MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
48MODULE_LICENSE("GPL"); 52MODULE_LICENSE("GPL");
49 53
50#define dprintk(level, fmt, arg...) if (debug >= level) \ 54#define dprintk(level, fmt, arg...) \
51 printk(KERN_DEBUG "vbuf-sg: " fmt , ## arg) 55 if (debug >= level) \
56 printk(KERN_DEBUG "vbuf-sg: " fmt , ## arg)
52 57
53/* --------------------------------------------------------------------- */ 58/* --------------------------------------------------------------------- */
54 59
55struct scatterlist* 60struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
56videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
57{ 61{
58 struct scatterlist *sglist; 62 struct scatterlist *sglist;
59 struct page *pg; 63 struct page *pg;
@@ -73,13 +77,14 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
73 } 77 }
74 return sglist; 78 return sglist;
75 79
76 err: 80err:
77 vfree(sglist); 81 vfree(sglist);
78 return NULL; 82 return NULL;
79} 83}
84EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
80 85
81struct scatterlist* 86struct scatterlist *videobuf_pages_to_sg(struct page **pages, int nr_pages,
82videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) 87 int offset)
83{ 88{
84 struct scatterlist *sglist; 89 struct scatterlist *sglist;
85 int i; 90 int i;
@@ -104,20 +109,20 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
104 } 109 }
105 return sglist; 110 return sglist;
106 111
107 nopage: 112nopage:
108 dprintk(2,"sgl: oops - no page\n"); 113 dprintk(2, "sgl: oops - no page\n");
109 vfree(sglist); 114 vfree(sglist);
110 return NULL; 115 return NULL;
111 116
112 highmem: 117highmem:
113 dprintk(2,"sgl: oops - highmem page\n"); 118 dprintk(2, "sgl: oops - highmem page\n");
114 vfree(sglist); 119 vfree(sglist);
115 return NULL; 120 return NULL;
116} 121}
117 122
118/* --------------------------------------------------------------------- */ 123/* --------------------------------------------------------------------- */
119 124
120struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf) 125struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf)
121{ 126{
122 struct videobuf_dma_sg_memory *mem = buf->priv; 127 struct videobuf_dma_sg_memory *mem = buf->priv;
123 BUG_ON(!mem); 128 BUG_ON(!mem);
@@ -126,17 +131,19 @@ struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf)
126 131
127 return &mem->dma; 132 return &mem->dma;
128} 133}
134EXPORT_SYMBOL_GPL(videobuf_to_dma);
129 135
130void videobuf_dma_init(struct videobuf_dmabuf *dma) 136void videobuf_dma_init(struct videobuf_dmabuf *dma)
131{ 137{
132 memset(dma,0,sizeof(*dma)); 138 memset(dma, 0, sizeof(*dma));
133 dma->magic = MAGIC_DMABUF; 139 dma->magic = MAGIC_DMABUF;
134} 140}
141EXPORT_SYMBOL_GPL(videobuf_dma_init);
135 142
136static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, 143static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
137 int direction, unsigned long data, unsigned long size) 144 int direction, unsigned long data, unsigned long size)
138{ 145{
139 unsigned long first,last; 146 unsigned long first, last;
140 int err, rw = 0; 147 int err, rw = 0;
141 148
142 dma->direction = direction; 149 dma->direction = direction;
@@ -155,21 +162,21 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
155 last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; 162 last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
156 dma->offset = data & ~PAGE_MASK; 163 dma->offset = data & ~PAGE_MASK;
157 dma->nr_pages = last-first+1; 164 dma->nr_pages = last-first+1;
158 dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*), 165 dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL);
159 GFP_KERNEL);
160 if (NULL == dma->pages) 166 if (NULL == dma->pages)
161 return -ENOMEM; 167 return -ENOMEM;
162 dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
163 data,size,dma->nr_pages);
164 168
165 err = get_user_pages(current,current->mm, 169 dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
170 data, size, dma->nr_pages);
171
172 err = get_user_pages(current, current->mm,
166 data & PAGE_MASK, dma->nr_pages, 173 data & PAGE_MASK, dma->nr_pages,
167 rw == READ, 1, /* force */ 174 rw == READ, 1, /* force */
168 dma->pages, NULL); 175 dma->pages, NULL);
169 176
170 if (err != dma->nr_pages) { 177 if (err != dma->nr_pages) {
171 dma->nr_pages = (err >= 0) ? err : 0; 178 dma->nr_pages = (err >= 0) ? err : 0;
172 dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages); 179 dprintk(1, "get_user_pages: err=%d [%d]\n", err, dma->nr_pages);
173 return err < 0 ? err : -EINVAL; 180 return err < 0 ? err : -EINVAL;
174 } 181 }
175 return 0; 182 return 0;
@@ -179,48 +186,58 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
179 unsigned long data, unsigned long size) 186 unsigned long data, unsigned long size)
180{ 187{
181 int ret; 188 int ret;
189
182 down_read(&current->mm->mmap_sem); 190 down_read(&current->mm->mmap_sem);
183 ret = videobuf_dma_init_user_locked(dma, direction, data, size); 191 ret = videobuf_dma_init_user_locked(dma, direction, data, size);
184 up_read(&current->mm->mmap_sem); 192 up_read(&current->mm->mmap_sem);
185 193
186 return ret; 194 return ret;
187} 195}
196EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
188 197
189int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, 198int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
190 int nr_pages) 199 int nr_pages)
191{ 200{
192 dprintk(1,"init kernel [%d pages]\n",nr_pages); 201 dprintk(1, "init kernel [%d pages]\n", nr_pages);
202
193 dma->direction = direction; 203 dma->direction = direction;
194 dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT); 204 dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
195 if (NULL == dma->vmalloc) { 205 if (NULL == dma->vmalloc) {
196 dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages); 206 dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
197 return -ENOMEM; 207 return -ENOMEM;
198 } 208 }
199 dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n", 209
210 dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
200 (unsigned long)dma->vmalloc, 211 (unsigned long)dma->vmalloc,
201 nr_pages << PAGE_SHIFT); 212 nr_pages << PAGE_SHIFT);
202 memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT); 213
214 memset(dma->vmalloc, 0, nr_pages << PAGE_SHIFT);
203 dma->nr_pages = nr_pages; 215 dma->nr_pages = nr_pages;
216
204 return 0; 217 return 0;
205} 218}
219EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
206 220
207int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, 221int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
208 dma_addr_t addr, int nr_pages) 222 dma_addr_t addr, int nr_pages)
209{ 223{
210 dprintk(1,"init overlay [%d pages @ bus 0x%lx]\n", 224 dprintk(1, "init overlay [%d pages @ bus 0x%lx]\n",
211 nr_pages,(unsigned long)addr); 225 nr_pages, (unsigned long)addr);
212 dma->direction = direction; 226 dma->direction = direction;
227
213 if (0 == addr) 228 if (0 == addr)
214 return -EINVAL; 229 return -EINVAL;
215 230
216 dma->bus_addr = addr; 231 dma->bus_addr = addr;
217 dma->nr_pages = nr_pages; 232 dma->nr_pages = nr_pages;
233
218 return 0; 234 return 0;
219} 235}
236EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
220 237
221int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) 238int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
222{ 239{
223 MAGIC_CHECK(dma->magic,MAGIC_DMABUF); 240 MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
224 BUG_ON(0 == dma->nr_pages); 241 BUG_ON(0 == dma->nr_pages);
225 242
226 if (dma->pages) { 243 if (dma->pages) {
@@ -228,20 +245,21 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
228 dma->offset); 245 dma->offset);
229 } 246 }
230 if (dma->vmalloc) { 247 if (dma->vmalloc) {
231 dma->sglist = videobuf_vmalloc_to_sg 248 dma->sglist = videobuf_vmalloc_to_sg(dma->vmalloc,
232 (dma->vmalloc,dma->nr_pages); 249 dma->nr_pages);
233 } 250 }
234 if (dma->bus_addr) { 251 if (dma->bus_addr) {
235 dma->sglist = vmalloc(sizeof(*dma->sglist)); 252 dma->sglist = vmalloc(sizeof(*dma->sglist));
236 if (NULL != dma->sglist) { 253 if (NULL != dma->sglist) {
237 dma->sglen = 1; 254 dma->sglen = 1;
238 sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK; 255 sg_dma_address(&dma->sglist[0]) = dma->bus_addr
239 dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK; 256 & PAGE_MASK;
240 sg_dma_len(&dma->sglist[0]) = dma->nr_pages * PAGE_SIZE; 257 dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK;
258 sg_dma_len(&dma->sglist[0]) = dma->nr_pages * PAGE_SIZE;
241 } 259 }
242 } 260 }
243 if (NULL == dma->sglist) { 261 if (NULL == dma->sglist) {
244 dprintk(1,"scatterlist is NULL\n"); 262 dprintk(1, "scatterlist is NULL\n");
245 return -ENOMEM; 263 return -ENOMEM;
246 } 264 }
247 if (!dma->bus_addr) { 265 if (!dma->bus_addr) {
@@ -249,47 +267,43 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
249 dma->nr_pages, dma->direction); 267 dma->nr_pages, dma->direction);
250 if (0 == dma->sglen) { 268 if (0 == dma->sglen) {
251 printk(KERN_WARNING 269 printk(KERN_WARNING
252 "%s: videobuf_map_sg failed\n",__func__); 270 "%s: videobuf_map_sg failed\n", __func__);
253 vfree(dma->sglist); 271 vfree(dma->sglist);
254 dma->sglist = NULL; 272 dma->sglist = NULL;
255 dma->sglen = 0; 273 dma->sglen = 0;
256 return -ENOMEM; 274 return -ENOMEM;
257 } 275 }
258 } 276 }
259 return 0;
260}
261
262int videobuf_dma_sync(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
263{
264 MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
265 BUG_ON(!dma->sglen);
266 277
267 dma_sync_sg_for_cpu(q->dev, dma->sglist, dma->nr_pages, dma->direction);
268 return 0; 278 return 0;
269} 279}
280EXPORT_SYMBOL_GPL(videobuf_dma_map);
270 281
271int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma) 282int videobuf_dma_unmap(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
272{ 283{
273 MAGIC_CHECK(dma->magic, MAGIC_DMABUF); 284 MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
285
274 if (!dma->sglen) 286 if (!dma->sglen)
275 return 0; 287 return 0;
276 288
277 dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction); 289 dma_unmap_sg(q->dev, dma->sglist, dma->sglen, dma->direction);
278 290
279 vfree(dma->sglist); 291 vfree(dma->sglist);
280 dma->sglist = NULL; 292 dma->sglist = NULL;
281 dma->sglen = 0; 293 dma->sglen = 0;
294
282 return 0; 295 return 0;
283} 296}
297EXPORT_SYMBOL_GPL(videobuf_dma_unmap);
284 298
285int videobuf_dma_free(struct videobuf_dmabuf *dma) 299int videobuf_dma_free(struct videobuf_dmabuf *dma)
286{ 300{
287 MAGIC_CHECK(dma->magic,MAGIC_DMABUF); 301 int i;
302 MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
288 BUG_ON(dma->sglen); 303 BUG_ON(dma->sglen);
289 304
290 if (dma->pages) { 305 if (dma->pages) {
291 int i; 306 for (i = 0; i < dma->nr_pages; i++)
292 for (i=0; i < dma->nr_pages; i++)
293 page_cache_release(dma->pages[i]); 307 page_cache_release(dma->pages[i]);
294 kfree(dma->pages); 308 kfree(dma->pages);
295 dma->pages = NULL; 309 dma->pages = NULL;
@@ -298,12 +312,13 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
298 vfree(dma->vmalloc); 312 vfree(dma->vmalloc);
299 dma->vmalloc = NULL; 313 dma->vmalloc = NULL;
300 314
301 if (dma->bus_addr) { 315 if (dma->bus_addr)
302 dma->bus_addr = 0; 316 dma->bus_addr = 0;
303 }
304 dma->direction = DMA_NONE; 317 dma->direction = DMA_NONE;
318
305 return 0; 319 return 0;
306} 320}
321EXPORT_SYMBOL_GPL(videobuf_dma_free);
307 322
308/* --------------------------------------------------------------------- */ 323/* --------------------------------------------------------------------- */
309 324
@@ -315,6 +330,7 @@ int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma)
315 330
316 return videobuf_dma_map(&q, dma); 331 return videobuf_dma_map(&q, dma);
317} 332}
333EXPORT_SYMBOL_GPL(videobuf_sg_dma_map);
318 334
319int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma) 335int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma)
320{ 336{
@@ -324,49 +340,48 @@ int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma)
324 340
325 return videobuf_dma_unmap(&q, dma); 341 return videobuf_dma_unmap(&q, dma);
326} 342}
343EXPORT_SYMBOL_GPL(videobuf_sg_dma_unmap);
327 344
328/* --------------------------------------------------------------------- */ 345/* --------------------------------------------------------------------- */
329 346
330static void 347static void videobuf_vm_open(struct vm_area_struct *vma)
331videobuf_vm_open(struct vm_area_struct *vma)
332{ 348{
333 struct videobuf_mapping *map = vma->vm_private_data; 349 struct videobuf_mapping *map = vma->vm_private_data;
334 350
335 dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map, 351 dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map,
336 map->count,vma->vm_start,vma->vm_end); 352 map->count, vma->vm_start, vma->vm_end);
353
337 map->count++; 354 map->count++;
338} 355}
339 356
340static void 357static void videobuf_vm_close(struct vm_area_struct *vma)
341videobuf_vm_close(struct vm_area_struct *vma)
342{ 358{
343 struct videobuf_mapping *map = vma->vm_private_data; 359 struct videobuf_mapping *map = vma->vm_private_data;
344 struct videobuf_queue *q = map->q; 360 struct videobuf_queue *q = map->q;
345 struct videobuf_dma_sg_memory *mem; 361 struct videobuf_dma_sg_memory *mem;
346 int i; 362 int i;
347 363
348 dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map, 364 dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map,
349 map->count,vma->vm_start,vma->vm_end); 365 map->count, vma->vm_start, vma->vm_end);
350 366
351 map->count--; 367 map->count--;
352 if (0 == map->count) { 368 if (0 == map->count) {
353 dprintk(1,"munmap %p q=%p\n",map,q); 369 dprintk(1, "munmap %p q=%p\n", map, q);
354 mutex_lock(&q->vb_lock); 370 mutex_lock(&q->vb_lock);
355 for (i = 0; i < VIDEO_MAX_FRAME; i++) { 371 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
356 if (NULL == q->bufs[i]) 372 if (NULL == q->bufs[i])
357 continue; 373 continue;
358 mem=q->bufs[i]->priv; 374 mem = q->bufs[i]->priv;
359
360 if (!mem) 375 if (!mem)
361 continue; 376 continue;
362 377
363 MAGIC_CHECK(mem->magic,MAGIC_SG_MEM); 378 MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
364 379
365 if (q->bufs[i]->map != map) 380 if (q->bufs[i]->map != map)
366 continue; 381 continue;
367 q->bufs[i]->map = NULL; 382 q->bufs[i]->map = NULL;
368 q->bufs[i]->baddr = 0; 383 q->bufs[i]->baddr = 0;
369 q->ops->buf_release(q,q->bufs[i]); 384 q->ops->buf_release(q, q->bufs[i]);
370 } 385 }
371 mutex_unlock(&q->vb_lock); 386 mutex_unlock(&q->vb_lock);
372 kfree(map); 387 kfree(map);
@@ -380,26 +395,27 @@ videobuf_vm_close(struct vm_area_struct *vma)
380 * now ...). Bounce buffers don't work very well for the data rates 395 * now ...). Bounce buffers don't work very well for the data rates
381 * video capture has. 396 * video capture has.
382 */ 397 */
383static int 398static int videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
384videobuf_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
385{ 399{
386 struct page *page; 400 struct page *page;
387 401
388 dprintk(3,"fault: fault @ %08lx [vma %08lx-%08lx]\n", 402 dprintk(3, "fault: fault @ %08lx [vma %08lx-%08lx]\n",
389 (unsigned long)vmf->virtual_address,vma->vm_start,vma->vm_end); 403 (unsigned long)vmf->virtual_address,
404 vma->vm_start, vma->vm_end);
405
390 page = alloc_page(GFP_USER | __GFP_DMA32); 406 page = alloc_page(GFP_USER | __GFP_DMA32);
391 if (!page) 407 if (!page)
392 return VM_FAULT_OOM; 408 return VM_FAULT_OOM;
393 clear_user_highpage(page, (unsigned long)vmf->virtual_address); 409 clear_user_highpage(page, (unsigned long)vmf->virtual_address);
394 vmf->page = page; 410 vmf->page = page;
411
395 return 0; 412 return 0;
396} 413}
397 414
398static const struct vm_operations_struct videobuf_vm_ops = 415static const struct vm_operations_struct videobuf_vm_ops = {
399{ 416 .open = videobuf_vm_open,
400 .open = videobuf_vm_open, 417 .close = videobuf_vm_close,
401 .close = videobuf_vm_close, 418 .fault = videobuf_vm_fault,
402 .fault = videobuf_vm_fault,
403}; 419};
404 420
405/* --------------------------------------------------------------------- 421/* ---------------------------------------------------------------------
@@ -412,28 +428,28 @@ static const struct vm_operations_struct videobuf_vm_ops =
412 struct videobuf_dma_sg_memory 428 struct videobuf_dma_sg_memory
413 */ 429 */
414 430
415static void *__videobuf_alloc(size_t size) 431static struct videobuf_buffer *__videobuf_alloc(size_t size)
416{ 432{
417 struct videobuf_dma_sg_memory *mem; 433 struct videobuf_dma_sg_memory *mem;
418 struct videobuf_buffer *vb; 434 struct videobuf_buffer *vb;
419 435
420 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); 436 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
421 if (!vb) 437 if (!vb)
422 return vb; 438 return vb;
423 439
424 mem = vb->priv = ((char *)vb)+size; 440 mem = vb->priv = ((char *)vb) + size;
425 mem->magic=MAGIC_SG_MEM; 441 mem->magic = MAGIC_SG_MEM;
426 442
427 videobuf_dma_init(&mem->dma); 443 videobuf_dma_init(&mem->dma);
428 444
429 dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", 445 dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
430 __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), 446 __func__, vb, (long)sizeof(*vb), (long)size - sizeof(*vb),
431 mem,(long)sizeof(*mem)); 447 mem, (long)sizeof(*mem));
432 448
433 return vb; 449 return vb;
434} 450}
435 451
436static void *__videobuf_to_vmalloc (struct videobuf_buffer *buf) 452static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
437{ 453{
438 struct videobuf_dma_sg_memory *mem = buf->priv; 454 struct videobuf_dma_sg_memory *mem = buf->priv;
439 BUG_ON(!mem); 455 BUG_ON(!mem);
@@ -443,11 +459,11 @@ static void *__videobuf_to_vmalloc (struct videobuf_buffer *buf)
443 return mem->dma.vmalloc; 459 return mem->dma.vmalloc;
444} 460}
445 461
446static int __videobuf_iolock (struct videobuf_queue* q, 462static int __videobuf_iolock(struct videobuf_queue *q,
447 struct videobuf_buffer *vb, 463 struct videobuf_buffer *vb,
448 struct v4l2_framebuffer *fbuf) 464 struct v4l2_framebuffer *fbuf)
449{ 465{
450 int err,pages; 466 int err, pages;
451 dma_addr_t bus; 467 dma_addr_t bus;
452 struct videobuf_dma_sg_memory *mem = vb->priv; 468 struct videobuf_dma_sg_memory *mem = vb->priv;
453 BUG_ON(!mem); 469 BUG_ON(!mem);
@@ -460,16 +476,16 @@ static int __videobuf_iolock (struct videobuf_queue* q,
460 if (0 == vb->baddr) { 476 if (0 == vb->baddr) {
461 /* no userspace addr -- kernel bounce buffer */ 477 /* no userspace addr -- kernel bounce buffer */
462 pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; 478 pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
463 err = videobuf_dma_init_kernel( &mem->dma, 479 err = videobuf_dma_init_kernel(&mem->dma,
464 DMA_FROM_DEVICE, 480 DMA_FROM_DEVICE,
465 pages ); 481 pages);
466 if (0 != err) 482 if (0 != err)
467 return err; 483 return err;
468 } else if (vb->memory == V4L2_MEMORY_USERPTR) { 484 } else if (vb->memory == V4L2_MEMORY_USERPTR) {
469 /* dma directly to userspace */ 485 /* dma directly to userspace */
470 err = videobuf_dma_init_user( &mem->dma, 486 err = videobuf_dma_init_user(&mem->dma,
471 DMA_FROM_DEVICE, 487 DMA_FROM_DEVICE,
472 vb->baddr,vb->bsize ); 488 vb->baddr, vb->bsize);
473 if (0 != err) 489 if (0 != err)
474 return err; 490 return err;
475 } else { 491 } else {
@@ -515,43 +531,27 @@ static int __videobuf_sync(struct videobuf_queue *q,
515 struct videobuf_buffer *buf) 531 struct videobuf_buffer *buf)
516{ 532{
517 struct videobuf_dma_sg_memory *mem = buf->priv; 533 struct videobuf_dma_sg_memory *mem = buf->priv;
518 BUG_ON(!mem); 534 BUG_ON(!mem || !mem->dma.sglen);
519 MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
520 535
521 return videobuf_dma_sync(q,&mem->dma); 536 MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
522} 537 MAGIC_CHECK(mem->dma.magic, MAGIC_DMABUF);
523
524static int __videobuf_mmap_free(struct videobuf_queue *q)
525{
526 int i;
527 538
528 for (i = 0; i < VIDEO_MAX_FRAME; i++) { 539 dma_sync_sg_for_cpu(q->dev, mem->dma.sglist,
529 if (q->bufs[i]) { 540 mem->dma.sglen, mem->dma.direction);
530 if (q->bufs[i]->map)
531 return -EBUSY;
532 }
533 }
534 541
535 return 0; 542 return 0;
536} 543}
537 544
538static int __videobuf_mmap_mapper(struct videobuf_queue *q, 545static int __videobuf_mmap_mapper(struct videobuf_queue *q,
539 struct vm_area_struct *vma) 546 struct videobuf_buffer *buf,
547 struct vm_area_struct *vma)
540{ 548{
541 struct videobuf_dma_sg_memory *mem; 549 struct videobuf_dma_sg_memory *mem = buf->priv;
542 struct videobuf_mapping *map; 550 struct videobuf_mapping *map;
543 unsigned int first,last,size,i; 551 unsigned int first, last, size = 0, i;
544 int retval; 552 int retval;
545 553
546 retval = -EINVAL; 554 retval = -EINVAL;
547 if (!(vma->vm_flags & VM_WRITE)) {
548 dprintk(1,"mmap app bug: PROT_WRITE please\n");
549 goto done;
550 }
551 if (!(vma->vm_flags & VM_SHARED)) {
552 dprintk(1,"mmap app bug: MAP_SHARED please\n");
553 goto done;
554 }
555 555
556 /* This function maintains backwards compatibility with V4L1 and will 556 /* This function maintains backwards compatibility with V4L1 and will
557 * map more than one buffer if the vma length is equal to the combined 557 * map more than one buffer if the vma length is equal to the combined
@@ -561,48 +561,52 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
561 * TODO: Allow drivers to specify if they support this mode 561 * TODO: Allow drivers to specify if they support this mode
562 */ 562 */
563 563
564 BUG_ON(!mem);
565 MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
566
564 /* look for first buffer to map */ 567 /* look for first buffer to map */
565 for (first = 0; first < VIDEO_MAX_FRAME; first++) { 568 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
566 if (NULL == q->bufs[first]) 569 if (buf == q->bufs[first]) {
567 continue; 570 size = PAGE_ALIGN(q->bufs[first]->bsize);
568 mem=q->bufs[first]->priv;
569 BUG_ON(!mem);
570 MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
571
572 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
573 continue;
574 if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
575 break; 571 break;
572 }
576 } 573 }
577 if (VIDEO_MAX_FRAME == first) { 574
578 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n", 575 /* paranoia, should never happen since buf is always valid. */
579 (vma->vm_pgoff << PAGE_SHIFT)); 576 if (!size) {
577 dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n",
578 (vma->vm_pgoff << PAGE_SHIFT));
580 goto done; 579 goto done;
581 } 580 }
582 581
583 /* look for last buffer to map */ 582 last = first;
584 for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) { 583#ifdef CONFIG_VIDEO_V4L1_COMPAT
585 if (NULL == q->bufs[last]) 584 if (size != (vma->vm_end - vma->vm_start)) {
586 continue; 585 /* look for last buffer to map */
587 if (V4L2_MEMORY_MMAP != q->bufs[last]->memory) 586 for (last = first + 1; last < VIDEO_MAX_FRAME; last++) {
588 continue; 587 if (NULL == q->bufs[last])
589 if (q->bufs[last]->map) { 588 continue;
590 retval = -EBUSY; 589 if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
590 continue;
591 if (q->bufs[last]->map) {
592 retval = -EBUSY;
593 goto done;
594 }
595 size += PAGE_ALIGN(q->bufs[last]->bsize);
596 if (size == (vma->vm_end - vma->vm_start))
597 break;
598 }
599 if (VIDEO_MAX_FRAME == last) {
600 dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n",
601 (vma->vm_end - vma->vm_start));
591 goto done; 602 goto done;
592 } 603 }
593 size += PAGE_ALIGN(q->bufs[last]->bsize);
594 if (size == (vma->vm_end - vma->vm_start))
595 break;
596 }
597 if (VIDEO_MAX_FRAME == last) {
598 dprintk(1,"mmap app bug: size invalid [size=0x%lx]\n",
599 (vma->vm_end - vma->vm_start));
600 goto done;
601 } 604 }
605#endif
602 606
603 /* create mapping + update buffer list */ 607 /* create mapping + update buffer list */
604 retval = -ENOMEM; 608 retval = -ENOMEM;
605 map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL); 609 map = kmalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
606 if (NULL == map) 610 if (NULL == map)
607 goto done; 611 goto done;
608 612
@@ -623,72 +627,22 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
623 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; 627 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
624 vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */ 628 vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
625 vma->vm_private_data = map; 629 vma->vm_private_data = map;
626 dprintk(1,"mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n", 630 dprintk(1, "mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
627 map,q,vma->vm_start,vma->vm_end,vma->vm_pgoff,first,last); 631 map, q, vma->vm_start, vma->vm_end, vma->vm_pgoff, first, last);
628 retval = 0; 632 retval = 0;
629 633
630 done: 634done:
631 return retval; 635 return retval;
632} 636}
633 637
634static int __videobuf_copy_to_user ( struct videobuf_queue *q,
635 char __user *data, size_t count,
636 int nonblocking )
637{
638 struct videobuf_dma_sg_memory *mem = q->read_buf->priv;
639 BUG_ON(!mem);
640 MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
641
642 /* copy to userspace */
643 if (count > q->read_buf->size - q->read_off)
644 count = q->read_buf->size - q->read_off;
645
646 if (copy_to_user(data, mem->dma.vmalloc+q->read_off, count))
647 return -EFAULT;
648
649 return count;
650}
651
652static int __videobuf_copy_stream ( struct videobuf_queue *q,
653 char __user *data, size_t count, size_t pos,
654 int vbihack, int nonblocking )
655{
656 unsigned int *fc;
657 struct videobuf_dma_sg_memory *mem = q->read_buf->priv;
658 BUG_ON(!mem);
659 MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
660
661 if (vbihack) {
662 /* dirty, undocumented hack -- pass the frame counter
663 * within the last four bytes of each vbi data block.
664 * We need that one to maintain backward compatibility
665 * to all vbi decoding software out there ... */
666 fc = (unsigned int*)mem->dma.vmalloc;
667 fc += (q->read_buf->size>>2) -1;
668 *fc = q->read_buf->field_count >> 1;
669 dprintk(1,"vbihack: %d\n",*fc);
670 }
671
672 /* copy stuff using the common method */
673 count = __videobuf_copy_to_user (q,data,count,nonblocking);
674
675 if ( (count==-EFAULT) && (0 == pos) )
676 return -EFAULT;
677
678 return count;
679}
680
681static struct videobuf_qtype_ops sg_ops = { 638static struct videobuf_qtype_ops sg_ops = {
682 .magic = MAGIC_QTYPE_OPS, 639 .magic = MAGIC_QTYPE_OPS,
683 640
684 .alloc = __videobuf_alloc, 641 .alloc = __videobuf_alloc,
685 .iolock = __videobuf_iolock, 642 .iolock = __videobuf_iolock,
686 .sync = __videobuf_sync, 643 .sync = __videobuf_sync,
687 .mmap_free = __videobuf_mmap_free,
688 .mmap_mapper = __videobuf_mmap_mapper, 644 .mmap_mapper = __videobuf_mmap_mapper,
689 .video_copy_to_user = __videobuf_copy_to_user, 645 .vaddr = __videobuf_to_vaddr,
690 .copy_stream = __videobuf_copy_stream,
691 .vmalloc = __videobuf_to_vmalloc,
692}; 646};
693 647
694void *videobuf_sg_alloc(size_t size) 648void *videobuf_sg_alloc(size_t size)
@@ -702,8 +656,9 @@ void *videobuf_sg_alloc(size_t size)
702 656
703 return videobuf_alloc(&q); 657 return videobuf_alloc(&q);
704} 658}
659EXPORT_SYMBOL_GPL(videobuf_sg_alloc);
705 660
706void videobuf_queue_sg_init(struct videobuf_queue* q, 661void videobuf_queue_sg_init(struct videobuf_queue *q,
707 const struct videobuf_queue_ops *ops, 662 const struct videobuf_queue_ops *ops,
708 struct device *dev, 663 struct device *dev,
709 spinlock_t *irqlock, 664 spinlock_t *irqlock,
@@ -715,29 +670,5 @@ void videobuf_queue_sg_init(struct videobuf_queue* q,
715 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, 670 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
716 priv, &sg_ops); 671 priv, &sg_ops);
717} 672}
718
719/* --------------------------------------------------------------------- */
720
721EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
722
723EXPORT_SYMBOL_GPL(videobuf_to_dma);
724EXPORT_SYMBOL_GPL(videobuf_dma_init);
725EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
726EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
727EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
728EXPORT_SYMBOL_GPL(videobuf_dma_map);
729EXPORT_SYMBOL_GPL(videobuf_dma_sync);
730EXPORT_SYMBOL_GPL(videobuf_dma_unmap);
731EXPORT_SYMBOL_GPL(videobuf_dma_free);
732
733EXPORT_SYMBOL_GPL(videobuf_sg_dma_map);
734EXPORT_SYMBOL_GPL(videobuf_sg_dma_unmap);
735EXPORT_SYMBOL_GPL(videobuf_sg_alloc);
736
737EXPORT_SYMBOL_GPL(videobuf_queue_sg_init); 673EXPORT_SYMBOL_GPL(videobuf_queue_sg_init);
738 674
739/*
740 * Local variables:
741 * c-basic-offset: 8
742 * End:
743 */
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 0afb62e63d99..3f76398968b8 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -67,7 +67,7 @@ static int videobuf_dvb_thread(void *data)
67 try_to_freeze(); 67 try_to_freeze();
68 68
69 /* feed buffer data to demux */ 69 /* feed buffer data to demux */
70 outp = videobuf_queue_to_vmalloc (&dvb->dvbq, buf); 70 outp = videobuf_queue_to_vaddr(&dvb->dvbq, buf);
71 71
72 if (buf->state == VIDEOBUF_DONE) 72 if (buf->state == VIDEOBUF_DONE)
73 dvb_dmx_swfilter(&dvb->demux, outp, 73 dvb_dmx_swfilter(&dvb->demux, outp,
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 136e09383c06..583728f4c221 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -30,8 +30,12 @@
30#define MAGIC_DMABUF 0x17760309 30#define MAGIC_DMABUF 0x17760309
31#define MAGIC_VMAL_MEM 0x18221223 31#define MAGIC_VMAL_MEM 0x18221223
32 32
33#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \ 33#define MAGIC_CHECK(is, should) \
34 { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); } 34 if (unlikely((is) != (should))) { \
35 printk(KERN_ERR "magic mismatch: %x (expected %x)\n", \
36 is, should); \
37 BUG(); \
38 }
35 39
36static int debug; 40static int debug;
37module_param(debug, int, 0644); 41module_param(debug, int, 0644);
@@ -40,19 +44,19 @@ MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
40MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 44MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
41MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
42 46
43#define dprintk(level, fmt, arg...) if (debug >= level) \ 47#define dprintk(level, fmt, arg...) \
44 printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg) 48 if (debug >= level) \
49 printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg)
45 50
46 51
47/***************************************************************************/ 52/***************************************************************************/
48 53
49static void 54static void videobuf_vm_open(struct vm_area_struct *vma)
50videobuf_vm_open(struct vm_area_struct *vma)
51{ 55{
52 struct videobuf_mapping *map = vma->vm_private_data; 56 struct videobuf_mapping *map = vma->vm_private_data;
53 57
54 dprintk(2,"vm_open %p [count=%u,vma=%08lx-%08lx]\n",map, 58 dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map,
55 map->count,vma->vm_start,vma->vm_end); 59 map->count, vma->vm_start, vma->vm_end);
56 60
57 map->count++; 61 map->count++;
58} 62}
@@ -63,7 +67,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
63 struct videobuf_queue *q = map->q; 67 struct videobuf_queue *q = map->q;
64 int i; 68 int i;
65 69
66 dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, 70 dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
67 map->count, vma->vm_start, vma->vm_end); 71 map->count, vma->vm_start, vma->vm_end);
68 72
69 map->count--; 73 map->count--;
@@ -116,8 +120,7 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
116 return; 120 return;
117} 121}
118 122
119static const struct vm_operations_struct videobuf_vm_ops = 123static const struct vm_operations_struct videobuf_vm_ops = {
120{
121 .open = videobuf_vm_open, 124 .open = videobuf_vm_open,
122 .close = videobuf_vm_close, 125 .close = videobuf_vm_close,
123}; 126};
@@ -132,28 +135,28 @@ static const struct vm_operations_struct videobuf_vm_ops =
132 struct videobuf_dma_sg_memory 135 struct videobuf_dma_sg_memory
133 */ 136 */
134 137
135static void *__videobuf_alloc(size_t size) 138static struct videobuf_buffer *__videobuf_alloc(size_t size)
136{ 139{
137 struct videobuf_vmalloc_memory *mem; 140 struct videobuf_vmalloc_memory *mem;
138 struct videobuf_buffer *vb; 141 struct videobuf_buffer *vb;
139 142
140 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); 143 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
141 if (!vb) 144 if (!vb)
142 return vb; 145 return vb;
143 146
144 mem = vb->priv = ((char *)vb)+size; 147 mem = vb->priv = ((char *)vb) + size;
145 mem->magic=MAGIC_VMAL_MEM; 148 mem->magic = MAGIC_VMAL_MEM;
146 149
147 dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", 150 dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
148 __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), 151 __func__, vb, (long)sizeof(*vb), (long)size - sizeof(*vb),
149 mem,(long)sizeof(*mem)); 152 mem, (long)sizeof(*mem));
150 153
151 return vb; 154 return vb;
152} 155}
153 156
154static int __videobuf_iolock (struct videobuf_queue* q, 157static int __videobuf_iolock(struct videobuf_queue *q,
155 struct videobuf_buffer *vb, 158 struct videobuf_buffer *vb,
156 struct v4l2_framebuffer *fbuf) 159 struct v4l2_framebuffer *fbuf)
157{ 160{
158 struct videobuf_vmalloc_memory *mem = vb->priv; 161 struct videobuf_vmalloc_memory *mem = vb->priv;
159 int pages; 162 int pages;
@@ -177,15 +180,13 @@ static int __videobuf_iolock (struct videobuf_queue* q,
177 180
178 dprintk(1, "%s memory method USERPTR\n", __func__); 181 dprintk(1, "%s memory method USERPTR\n", __func__);
179 182
180#if 1
181 if (vb->baddr) { 183 if (vb->baddr) {
182 printk(KERN_ERR "USERPTR is currently not supported\n"); 184 printk(KERN_ERR "USERPTR is currently not supported\n");
183 return -EINVAL; 185 return -EINVAL;
184 } 186 }
185#endif
186 187
187 /* The only USERPTR currently supported is the one needed for 188 /* The only USERPTR currently supported is the one needed for
188 read() method. 189 * read() method.
189 */ 190 */
190 191
191 mem->vmalloc = vmalloc_user(pages); 192 mem->vmalloc = vmalloc_user(pages);
@@ -210,7 +211,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
210 /* Try to remap memory */ 211 /* Try to remap memory */
211 rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0); 212 rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0);
212 if (rc < 0) { 213 if (rc < 0) {
213 printk(KERN_ERR "mmap: remap failed with error %d. ", rc); 214 printk(KERN_ERR "mmap: remap failed with error %d", rc);
214 return -ENOMEM; 215 return -ENOMEM;
215 } 216 }
216#endif 217#endif
@@ -228,69 +229,29 @@ static int __videobuf_iolock (struct videobuf_queue* q,
228 return 0; 229 return 0;
229} 230}
230 231
231static int __videobuf_sync(struct videobuf_queue *q,
232 struct videobuf_buffer *buf)
233{
234 return 0;
235}
236
237static int __videobuf_mmap_free(struct videobuf_queue *q)
238{
239 unsigned int i;
240
241 dprintk(1, "%s\n", __func__);
242 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
243 if (q->bufs[i]) {
244 if (q->bufs[i]->map)
245 return -EBUSY;
246 }
247 }
248
249 return 0;
250}
251
252static int __videobuf_mmap_mapper(struct videobuf_queue *q, 232static int __videobuf_mmap_mapper(struct videobuf_queue *q,
253 struct vm_area_struct *vma) 233 struct videobuf_buffer *buf,
234 struct vm_area_struct *vma)
254{ 235{
255 struct videobuf_vmalloc_memory *mem; 236 struct videobuf_vmalloc_memory *mem;
256 struct videobuf_mapping *map; 237 struct videobuf_mapping *map;
257 unsigned int first;
258 int retval, pages; 238 int retval, pages;
259 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
260 239
261 dprintk(1, "%s\n", __func__); 240 dprintk(1, "%s\n", __func__);
262 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
263 return -EINVAL;
264
265 /* look for first buffer to map */
266 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
267 if (NULL == q->bufs[first])
268 continue;
269
270 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
271 continue;
272 if (q->bufs[first]->boff == offset)
273 break;
274 }
275 if (VIDEO_MAX_FRAME == first) {
276 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
277 (vma->vm_pgoff << PAGE_SHIFT));
278 return -EINVAL;
279 }
280 241
281 /* create mapping + update buffer list */ 242 /* create mapping + update buffer list */
282 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); 243 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
283 if (NULL == map) 244 if (NULL == map)
284 return -ENOMEM; 245 return -ENOMEM;
285 246
286 q->bufs[first]->map = map; 247 buf->map = map;
287 map->start = vma->vm_start; 248 map->start = vma->vm_start;
288 map->end = vma->vm_end; 249 map->end = vma->vm_end;
289 map->q = q; 250 map->q = q;
290 251
291 q->bufs[first]->baddr = vma->vm_start; 252 buf->baddr = vma->vm_start;
292 253
293 mem = q->bufs[first]->priv; 254 mem = buf->priv;
294 BUG_ON(!mem); 255 BUG_ON(!mem);
295 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 256 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
296 257
@@ -300,8 +261,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
300 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); 261 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
301 goto error; 262 goto error;
302 } 263 }
303 dprintk(1, "vmalloc is at addr %p (%d pages)\n", 264 dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vmalloc, pages);
304 mem->vmalloc, pages);
305 265
306 /* Try to remap memory */ 266 /* Try to remap memory */
307 retval = remap_vmalloc_range(vma, mem->vmalloc, 0); 267 retval = remap_vmalloc_range(vma, mem->vmalloc, 0);
@@ -315,10 +275,10 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
315 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; 275 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
316 vma->vm_private_data = map; 276 vma->vm_private_data = map;
317 277
318 dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", 278 dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
319 map, q, vma->vm_start, vma->vm_end, 279 map, q, vma->vm_start, vma->vm_end,
320 (long int) q->bufs[first]->bsize, 280 (long int)buf->bsize,
321 vma->vm_pgoff, first); 281 vma->vm_pgoff, buf->i);
322 282
323 videobuf_vm_open(vma); 283 videobuf_vm_open(vma);
324 284
@@ -330,69 +290,16 @@ error:
330 return -ENOMEM; 290 return -ENOMEM;
331} 291}
332 292
333static int __videobuf_copy_to_user ( struct videobuf_queue *q,
334 char __user *data, size_t count,
335 int nonblocking )
336{
337 struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
338 BUG_ON (!mem);
339 MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
340
341 BUG_ON (!mem->vmalloc);
342
343 /* copy to userspace */
344 if (count > q->read_buf->size - q->read_off)
345 count = q->read_buf->size - q->read_off;
346
347 if (copy_to_user(data, mem->vmalloc+q->read_off, count))
348 return -EFAULT;
349
350 return count;
351}
352
353static int __videobuf_copy_stream ( struct videobuf_queue *q,
354 char __user *data, size_t count, size_t pos,
355 int vbihack, int nonblocking )
356{
357 unsigned int *fc;
358 struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
359 BUG_ON (!mem);
360 MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
361
362 if (vbihack) {
363 /* dirty, undocumented hack -- pass the frame counter
364 * within the last four bytes of each vbi data block.
365 * We need that one to maintain backward compatibility
366 * to all vbi decoding software out there ... */
367 fc = (unsigned int*)mem->vmalloc;
368 fc += (q->read_buf->size>>2) -1;
369 *fc = q->read_buf->field_count >> 1;
370 dprintk(1,"vbihack: %d\n",*fc);
371 }
372
373 /* copy stuff using the common method */
374 count = __videobuf_copy_to_user (q,data,count,nonblocking);
375
376 if ( (count==-EFAULT) && (0 == pos) )
377 return -EFAULT;
378
379 return count;
380}
381
382static struct videobuf_qtype_ops qops = { 293static struct videobuf_qtype_ops qops = {
383 .magic = MAGIC_QTYPE_OPS, 294 .magic = MAGIC_QTYPE_OPS,
384 295
385 .alloc = __videobuf_alloc, 296 .alloc = __videobuf_alloc,
386 .iolock = __videobuf_iolock, 297 .iolock = __videobuf_iolock,
387 .sync = __videobuf_sync,
388 .mmap_free = __videobuf_mmap_free,
389 .mmap_mapper = __videobuf_mmap_mapper, 298 .mmap_mapper = __videobuf_mmap_mapper,
390 .video_copy_to_user = __videobuf_copy_to_user, 299 .vaddr = videobuf_to_vmalloc,
391 .copy_stream = __videobuf_copy_stream,
392 .vmalloc = videobuf_to_vmalloc,
393}; 300};
394 301
395void videobuf_queue_vmalloc_init(struct videobuf_queue* q, 302void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
396 const struct videobuf_queue_ops *ops, 303 const struct videobuf_queue_ops *ops,
397 struct device *dev, 304 struct device *dev,
398 spinlock_t *irqlock, 305 spinlock_t *irqlock,
@@ -404,20 +311,19 @@ void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
404 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, 311 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
405 priv, &qops); 312 priv, &qops);
406} 313}
407
408EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init); 314EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
409 315
410void *videobuf_to_vmalloc (struct videobuf_buffer *buf) 316void *videobuf_to_vmalloc(struct videobuf_buffer *buf)
411{ 317{
412 struct videobuf_vmalloc_memory *mem=buf->priv; 318 struct videobuf_vmalloc_memory *mem = buf->priv;
413 BUG_ON (!mem); 319 BUG_ON(!mem);
414 MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); 320 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
415 321
416 return mem->vmalloc; 322 return mem->vmalloc;
417} 323}
418EXPORT_SYMBOL_GPL(videobuf_to_vmalloc); 324EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
419 325
420void videobuf_vmalloc_free (struct videobuf_buffer *buf) 326void videobuf_vmalloc_free(struct videobuf_buffer *buf)
421{ 327{
422 struct videobuf_vmalloc_memory *mem = buf->priv; 328 struct videobuf_vmalloc_memory *mem = buf->priv;
423 329
@@ -442,8 +348,3 @@ void videobuf_vmalloc_free (struct videobuf_buffer *buf)
442} 348}
443EXPORT_SYMBOL_GPL(videobuf_vmalloc_free); 349EXPORT_SYMBOL_GPL(videobuf_vmalloc_free);
444 350
445/*
446 * Local variables:
447 * c-basic-offset: 8
448 * End:
449 */
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index cdbe70385c12..e17b6fee046b 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -13,29 +13,23 @@
13 * License, or (at your option) any later version 13 * License, or (at your option) any later version
14 */ 14 */
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/delay.h>
17#include <linux/errno.h> 16#include <linux/errno.h>
18#include <linux/fs.h>
19#include <linux/kernel.h> 17#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/mm.h>
22#include <linux/ioport.h>
23#include <linux/init.h> 18#include <linux/init.h>
24#include <linux/sched.h> 19#include <linux/sched.h>
25#include <linux/pci.h> 20#include <linux/slab.h>
26#include <linux/random.h> 21#include <linux/font.h>
27#include <linux/version.h> 22#include <linux/version.h>
28#include <linux/mutex.h> 23#include <linux/mutex.h>
29#include <linux/videodev2.h> 24#include <linux/videodev2.h>
30#include <linux/dma-mapping.h>
31#include <linux/interrupt.h>
32#include <linux/kthread.h> 25#include <linux/kthread.h>
33#include <linux/highmem.h> 26#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
34#include <linux/freezer.h> 27#include <linux/freezer.h>
28#endif
35#include <media/videobuf-vmalloc.h> 29#include <media/videobuf-vmalloc.h>
36#include <media/v4l2-device.h> 30#include <media/v4l2-device.h>
37#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
38#include "font.h" 32#include <media/v4l2-common.h>
39 33
40#define VIVI_MODULE_NAME "vivi" 34#define VIVI_MODULE_NAME "vivi"
41 35
@@ -44,8 +38,11 @@
44#define WAKE_DENOMINATOR 1001 38#define WAKE_DENOMINATOR 1001
45#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ 39#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
46 40
41#define MAX_WIDTH 1920
42#define MAX_HEIGHT 1200
43
47#define VIVI_MAJOR_VERSION 0 44#define VIVI_MAJOR_VERSION 0
48#define VIVI_MINOR_VERSION 6 45#define VIVI_MINOR_VERSION 7
49#define VIVI_RELEASE 0 46#define VIVI_RELEASE 0
50#define VIVI_VERSION \ 47#define VIVI_VERSION \
51 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) 48 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
@@ -70,56 +67,8 @@ static unsigned int vid_limit = 16;
70module_param(vid_limit, uint, 0644); 67module_param(vid_limit, uint, 0644);
71MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); 68MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
72 69
73 70/* Global font descriptor */
74/* supported controls */ 71static const u8 *font8x16;
75static struct v4l2_queryctrl vivi_qctrl[] = {
76 {
77 .id = V4L2_CID_AUDIO_VOLUME,
78 .name = "Volume",
79 .minimum = 0,
80 .maximum = 65535,
81 .step = 65535/100,
82 .default_value = 65535,
83 .flags = V4L2_CTRL_FLAG_SLIDER,
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 }, {
86 .id = V4L2_CID_BRIGHTNESS,
87 .type = V4L2_CTRL_TYPE_INTEGER,
88 .name = "Brightness",
89 .minimum = 0,
90 .maximum = 255,
91 .step = 1,
92 .default_value = 127,
93 .flags = V4L2_CTRL_FLAG_SLIDER,
94 }, {
95 .id = V4L2_CID_CONTRAST,
96 .type = V4L2_CTRL_TYPE_INTEGER,
97 .name = "Contrast",
98 .minimum = 0,
99 .maximum = 255,
100 .step = 0x1,
101 .default_value = 0x10,
102 .flags = V4L2_CTRL_FLAG_SLIDER,
103 }, {
104 .id = V4L2_CID_SATURATION,
105 .type = V4L2_CTRL_TYPE_INTEGER,
106 .name = "Saturation",
107 .minimum = 0,
108 .maximum = 255,
109 .step = 0x1,
110 .default_value = 127,
111 .flags = V4L2_CTRL_FLAG_SLIDER,
112 }, {
113 .id = V4L2_CID_HUE,
114 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Hue",
116 .minimum = -128,
117 .maximum = 127,
118 .step = 0x1,
119 .default_value = 0,
120 .flags = V4L2_CTRL_FLAG_SLIDER,
121 }
122};
123 72
124#define dprintk(dev, level, fmt, arg...) \ 73#define dprintk(dev, level, fmt, arg...) \
125 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) 74 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
@@ -214,41 +163,38 @@ struct vivi_dev {
214 struct list_head vivi_devlist; 163 struct list_head vivi_devlist;
215 struct v4l2_device v4l2_dev; 164 struct v4l2_device v4l2_dev;
216 165
166 /* controls */
167 int brightness;
168 int contrast;
169 int saturation;
170 int hue;
171 int volume;
172
217 spinlock_t slock; 173 spinlock_t slock;
218 struct mutex mutex; 174 struct mutex mutex;
219 175
220 int users;
221
222 /* various device info */ 176 /* various device info */
223 struct video_device *vfd; 177 struct video_device *vfd;
224 178
225 struct vivi_dmaqueue vidq; 179 struct vivi_dmaqueue vidq;
226 180
227 /* Several counters */ 181 /* Several counters */
228 int h, m, s, ms; 182 unsigned ms;
229 unsigned long jiffies; 183 unsigned long jiffies;
230 char timestr[13];
231 184
232 int mv_count; /* Controls bars movement */ 185 int mv_count; /* Controls bars movement */
233 186
234 /* Input Number */ 187 /* Input Number */
235 int input; 188 int input;
236 189
237 /* Control 'registers' */
238 int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
239};
240
241struct vivi_fh {
242 struct vivi_dev *dev;
243
244 /* video capture */ 190 /* video capture */
245 struct vivi_fmt *fmt; 191 struct vivi_fmt *fmt;
246 unsigned int width, height; 192 unsigned int width, height;
247 struct videobuf_queue vb_vidq; 193 struct videobuf_queue vb_vidq;
248 194
249 enum v4l2_buf_type type; 195 unsigned long generating;
250 unsigned char bars[8][3]; 196 u8 bars[9][3];
251 int input; /* Input Number on bars */ 197 u8 line[MAX_WIDTH * 4];
252}; 198};
253 199
254/* ------------------------------------------------------------------ 200/* ------------------------------------------------------------------
@@ -259,19 +205,20 @@ struct vivi_fh {
259 205
260enum colors { 206enum colors {
261 WHITE, 207 WHITE,
262 AMBAR, 208 AMBER,
263 CYAN, 209 CYAN,
264 GREEN, 210 GREEN,
265 MAGENTA, 211 MAGENTA,
266 RED, 212 RED,
267 BLUE, 213 BLUE,
268 BLACK, 214 BLACK,
215 TEXT_BLACK,
269}; 216};
270 217
271 /* R G B */ 218/* R G B */
272#define COLOR_WHITE {204, 204, 204} 219#define COLOR_WHITE {204, 204, 204}
273#define COLOR_AMBAR {208, 208, 0} 220#define COLOR_AMBER {208, 208, 0}
274#define COLOR_CIAN { 0, 206, 206} 221#define COLOR_CYAN { 0, 206, 206}
275#define COLOR_GREEN { 0, 239, 0} 222#define COLOR_GREEN { 0, 239, 0}
276#define COLOR_MAGENTA {239, 0, 239} 223#define COLOR_MAGENTA {239, 0, 239}
277#define COLOR_RED {205, 0, 0} 224#define COLOR_RED {205, 0, 0}
@@ -279,56 +226,24 @@ enum colors {
279#define COLOR_BLACK { 0, 0, 0} 226#define COLOR_BLACK { 0, 0, 0}
280 227
281struct bar_std { 228struct bar_std {
282 u8 bar[8][3]; 229 u8 bar[9][3];
283}; 230};
284 231
285/* Maximum number of bars are 10 - otherwise, the input print code 232/* Maximum number of bars are 10 - otherwise, the input print code
286 should be modified */ 233 should be modified */
287static struct bar_std bars[] = { 234static struct bar_std bars[] = {
288 { /* Standard ITU-R color bar sequence */ 235 { /* Standard ITU-R color bar sequence */
289 { 236 { COLOR_WHITE, COLOR_AMBER, COLOR_CYAN, COLOR_GREEN,
290 COLOR_WHITE, 237 COLOR_MAGENTA, COLOR_RED, COLOR_BLUE, COLOR_BLACK, COLOR_BLACK }
291 COLOR_AMBAR,
292 COLOR_CIAN,
293 COLOR_GREEN,
294 COLOR_MAGENTA,
295 COLOR_RED,
296 COLOR_BLUE,
297 COLOR_BLACK,
298 }
299 }, { 238 }, {
300 { 239 { COLOR_WHITE, COLOR_AMBER, COLOR_BLACK, COLOR_WHITE,
301 COLOR_WHITE, 240 COLOR_AMBER, COLOR_BLACK, COLOR_WHITE, COLOR_AMBER, COLOR_BLACK }
302 COLOR_AMBAR,
303 COLOR_BLACK,
304 COLOR_WHITE,
305 COLOR_AMBAR,
306 COLOR_BLACK,
307 COLOR_WHITE,
308 COLOR_AMBAR,
309 }
310 }, { 241 }, {
311 { 242 { COLOR_WHITE, COLOR_CYAN, COLOR_BLACK, COLOR_WHITE,
312 COLOR_WHITE, 243 COLOR_CYAN, COLOR_BLACK, COLOR_WHITE, COLOR_CYAN, COLOR_BLACK }
313 COLOR_CIAN,
314 COLOR_BLACK,
315 COLOR_WHITE,
316 COLOR_CIAN,
317 COLOR_BLACK,
318 COLOR_WHITE,
319 COLOR_CIAN,
320 }
321 }, { 244 }, {
322 { 245 { COLOR_WHITE, COLOR_GREEN, COLOR_BLACK, COLOR_WHITE,
323 COLOR_WHITE, 246 COLOR_GREEN, COLOR_BLACK, COLOR_WHITE, COLOR_GREEN, COLOR_BLACK }
324 COLOR_GREEN,
325 COLOR_BLACK,
326 COLOR_WHITE,
327 COLOR_GREEN,
328 COLOR_BLACK,
329 COLOR_WHITE,
330 COLOR_GREEN,
331 }
332 }, 247 },
333}; 248};
334 249
@@ -344,21 +259,18 @@ static struct bar_std bars[] = {
344 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) 259 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
345 260
346/* precalculate color bar values to speed up rendering */ 261/* precalculate color bar values to speed up rendering */
347static void precalculate_bars(struct vivi_fh *fh) 262static void precalculate_bars(struct vivi_dev *dev)
348{ 263{
349 struct vivi_dev *dev = fh->dev; 264 u8 r, g, b;
350 unsigned char r, g, b;
351 int k, is_yuv; 265 int k, is_yuv;
352 266
353 fh->input = dev->input; 267 for (k = 0; k < 9; k++) {
354 268 r = bars[dev->input].bar[k][0];
355 for (k = 0; k < 8; k++) { 269 g = bars[dev->input].bar[k][1];
356 r = bars[fh->input].bar[k][0]; 270 b = bars[dev->input].bar[k][2];
357 g = bars[fh->input].bar[k][1];
358 b = bars[fh->input].bar[k][2];
359 is_yuv = 0; 271 is_yuv = 0;
360 272
361 switch (fh->fmt->fourcc) { 273 switch (dev->fmt->fourcc) {
362 case V4L2_PIX_FMT_YUYV: 274 case V4L2_PIX_FMT_YUYV:
363 case V4L2_PIX_FMT_UYVY: 275 case V4L2_PIX_FMT_UYVY:
364 is_yuv = 1; 276 is_yuv = 1;
@@ -378,16 +290,15 @@ static void precalculate_bars(struct vivi_fh *fh)
378 } 290 }
379 291
380 if (is_yuv) { 292 if (is_yuv) {
381 fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ 293 dev->bars[k][0] = TO_Y(r, g, b); /* Luma */
382 fh->bars[k][1] = TO_U(r, g, b); /* Cb */ 294 dev->bars[k][1] = TO_U(r, g, b); /* Cb */
383 fh->bars[k][2] = TO_V(r, g, b); /* Cr */ 295 dev->bars[k][2] = TO_V(r, g, b); /* Cr */
384 } else { 296 } else {
385 fh->bars[k][0] = r; 297 dev->bars[k][0] = r;
386 fh->bars[k][1] = g; 298 dev->bars[k][1] = g;
387 fh->bars[k][2] = b; 299 dev->bars[k][2] = b;
388 } 300 }
389 } 301 }
390
391} 302}
392 303
393#define TSTAMP_MIN_Y 24 304#define TSTAMP_MIN_Y 24
@@ -395,20 +306,20 @@ static void precalculate_bars(struct vivi_fh *fh)
395#define TSTAMP_INPUT_X 10 306#define TSTAMP_INPUT_X 10
396#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) 307#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
397 308
398static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) 309static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
399{ 310{
400 unsigned char r_y, g_u, b_v; 311 u8 r_y, g_u, b_v;
401 unsigned char *p;
402 int color; 312 int color;
313 u8 *p;
403 314
404 r_y = fh->bars[colorpos][0]; /* R or precalculated Y */ 315 r_y = dev->bars[colorpos][0]; /* R or precalculated Y */
405 g_u = fh->bars[colorpos][1]; /* G or precalculated U */ 316 g_u = dev->bars[colorpos][1]; /* G or precalculated U */
406 b_v = fh->bars[colorpos][2]; /* B or precalculated V */ 317 b_v = dev->bars[colorpos][2]; /* B or precalculated V */
407 318
408 for (color = 0; color < 4; color++) { 319 for (color = 0; color < 4; color++) {
409 p = buf + color; 320 p = buf + color;
410 321
411 switch (fh->fmt->fourcc) { 322 switch (dev->fmt->fourcc) {
412 case V4L2_PIX_FMT_YUYV: 323 case V4L2_PIX_FMT_YUYV:
413 switch (color) { 324 switch (color) {
414 case 0: 325 case 0:
@@ -489,123 +400,88 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
489 } 400 }
490} 401}
491 402
492static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, 403static void precalculate_line(struct vivi_dev *dev)
493 int hmax, int line, int count, char *timestr)
494{ 404{
495 int w, i, j; 405 int w;
496 int pos = inipos;
497 char *s;
498 u8 chr;
499
500 /* We will just duplicate the second pixel at the packet */
501 wmax /= 2;
502 406
503 /* Generate a standard color bar pattern */ 407 for (w = 0; w < dev->width * 2; w += 2) {
504 for (w = 0; w < wmax; w++) { 408 int colorpos = (w / (dev->width / 8) % 8);
505 int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
506 409
507 gen_twopix(fh, basep + pos, colorpos); 410 gen_twopix(dev, dev->line + w * 2, colorpos);
508 pos += 4; /* only 16 bpp supported for now */
509 } 411 }
412}
510 413
511 /* Prints input entry number */ 414static void gen_text(struct vivi_dev *dev, char *basep,
512 415 int y, int x, char *text)
513 /* Checks if it is possible to input number */ 416{
514 if (TSTAMP_MAX_Y >= hmax) 417 int line;
515 goto end;
516
517 if (TSTAMP_INPUT_X + strlen(timestr) >= wmax)
518 goto end;
519
520 if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
521 chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y];
522 pos = TSTAMP_INPUT_X;
523 for (i = 0; i < 7; i++) {
524 /* Draw white font on black background */
525 if (chr & 1 << (7 - i))
526 gen_twopix(fh, basep + pos, WHITE);
527 else
528 gen_twopix(fh, basep + pos, BLACK);
529 pos += 2;
530 }
531 }
532 418
533 /* Checks if it is possible to show timestamp */ 419 /* Checks if it is possible to show string */
534 if (TSTAMP_MIN_X + strlen(timestr) >= wmax) 420 if (y + 16 >= dev->height || x + strlen(text) * 8 >= dev->width)
535 goto end; 421 return;
536 422
537 /* Print stream time */ 423 /* Print stream time */
538 if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) { 424 for (line = y; line < y + 16; line++) {
539 j = TSTAMP_MIN_X; 425 int j = 0;
540 for (s = timestr; *s; s++) { 426 char *pos = basep + line * dev->width * 2 + x * 2;
541 chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; 427 char *s;
542 for (i = 0; i < 7; i++) { 428
543 pos = inipos + j * 2; 429 for (s = text; *s; s++) {
430 u8 chr = font8x16[*s * 16 + line - y];
431 int i;
432
433 for (i = 0; i < 7; i++, j++) {
544 /* Draw white font on black background */ 434 /* Draw white font on black background */
545 if (chr & 1 << (7 - i)) 435 if (chr & (1 << (7 - i)))
546 gen_twopix(fh, basep + pos, WHITE); 436 gen_twopix(dev, pos + j * 2, WHITE);
547 else 437 else
548 gen_twopix(fh, basep + pos, BLACK); 438 gen_twopix(dev, pos + j * 2, TEXT_BLACK);
549 j++;
550 } 439 }
551 } 440 }
552 } 441 }
553
554end:
555 return;
556} 442}
557 443
558static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf) 444static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
559{ 445{
560 struct vivi_dev *dev = fh->dev; 446 int hmax = buf->vb.height;
561 int h , pos = 0; 447 int wmax = buf->vb.width;
562 int hmax = buf->vb.height;
563 int wmax = buf->vb.width;
564 struct timeval ts; 448 struct timeval ts;
565 char *tmpbuf;
566 void *vbuf = videobuf_to_vmalloc(&buf->vb); 449 void *vbuf = videobuf_to_vmalloc(&buf->vb);
450 unsigned ms;
451 char str[100];
452 int h, line = 1;
567 453
568 if (!vbuf) 454 if (!vbuf)
569 return; 455 return;
570 456
571 tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); 457 for (h = 0; h < hmax; h++)
572 if (!tmpbuf) 458 memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2);
573 return;
574
575 for (h = 0; h < hmax; h++) {
576 gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count,
577 dev->timestr);
578 memcpy(vbuf + pos, tmpbuf, wmax * 2);
579 pos += wmax*2;
580 }
581
582 dev->mv_count++;
583
584 kfree(tmpbuf);
585 459
586 /* Updates stream time */ 460 /* Updates stream time */
587 461
588 dev->ms += jiffies_to_msecs(jiffies-dev->jiffies); 462 dev->ms += jiffies_to_msecs(jiffies - dev->jiffies);
589 dev->jiffies = jiffies; 463 dev->jiffies = jiffies;
590 if (dev->ms >= 1000) { 464 ms = dev->ms;
591 dev->ms -= 1000; 465 snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d ",
592 dev->s++; 466 (ms / (60 * 60 * 1000)) % 24,
593 if (dev->s >= 60) { 467 (ms / (60 * 1000)) % 60,
594 dev->s -= 60; 468 (ms / 1000) % 60,
595 dev->m++; 469 ms % 1000);
596 if (dev->m > 60) { 470 gen_text(dev, vbuf, line++ * 16, 16, str);
597 dev->m -= 60; 471 snprintf(str, sizeof(str), " %dx%d, input %d ",
598 dev->h++; 472 dev->width, dev->height, dev->input);
599 if (dev->h > 24) 473 gen_text(dev, vbuf, line++ * 16, 16, str);
600 dev->h -= 24; 474
601 } 475 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
602 } 476 dev->brightness,
603 } 477 dev->contrast,
604 sprintf(dev->timestr, "%02d:%02d:%02d:%03d", 478 dev->saturation,
605 dev->h, dev->m, dev->s, dev->ms); 479 dev->hue);
606 480 gen_text(dev, vbuf, line++ * 16, 16, str);
607 dprintk(dev, 2, "vivifill at %s: Buffer 0x%08lx size= %d\n", 481 snprintf(str, sizeof(str), " volume %3d ", dev->volume);
608 dev->timestr, (unsigned long)tmpbuf, pos); 482 gen_text(dev, vbuf, line++ * 16, 16, str);
483
484 dev->mv_count += 2;
609 485
610 /* Advice that buffer was filled */ 486 /* Advice that buffer was filled */
611 buf->vb.field_count++; 487 buf->vb.field_count++;
@@ -614,12 +490,10 @@ static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf)
614 buf->vb.state = VIDEOBUF_DONE; 490 buf->vb.state = VIDEOBUF_DONE;
615} 491}
616 492
617static void vivi_thread_tick(struct vivi_fh *fh) 493static void vivi_thread_tick(struct vivi_dev *dev)
618{ 494{
619 struct vivi_buffer *buf;
620 struct vivi_dev *dev = fh->dev;
621 struct vivi_dmaqueue *dma_q = &dev->vidq; 495 struct vivi_dmaqueue *dma_q = &dev->vidq;
622 496 struct vivi_buffer *buf;
623 unsigned long flags = 0; 497 unsigned long flags = 0;
624 498
625 dprintk(dev, 1, "Thread tick\n"); 499 dprintk(dev, 1, "Thread tick\n");
@@ -642,22 +516,20 @@ static void vivi_thread_tick(struct vivi_fh *fh)
642 do_gettimeofday(&buf->vb.ts); 516 do_gettimeofday(&buf->vb.ts);
643 517
644 /* Fill buffer */ 518 /* Fill buffer */
645 vivi_fillbuff(fh, buf); 519 vivi_fillbuff(dev, buf);
646 dprintk(dev, 1, "filled buffer %p\n", buf); 520 dprintk(dev, 1, "filled buffer %p\n", buf);
647 521
648 wake_up(&buf->vb.done); 522 wake_up(&buf->vb.done);
649 dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); 523 dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i);
650unlock: 524unlock:
651 spin_unlock_irqrestore(&dev->slock, flags); 525 spin_unlock_irqrestore(&dev->slock, flags);
652 return;
653} 526}
654 527
655#define frames_to_ms(frames) \ 528#define frames_to_ms(frames) \
656 ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) 529 ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
657 530
658static void vivi_sleep(struct vivi_fh *fh) 531static void vivi_sleep(struct vivi_dev *dev)
659{ 532{
660 struct vivi_dev *dev = fh->dev;
661 struct vivi_dmaqueue *dma_q = &dev->vidq; 533 struct vivi_dmaqueue *dma_q = &dev->vidq;
662 int timeout; 534 int timeout;
663 DECLARE_WAITQUEUE(wait, current); 535 DECLARE_WAITQUEUE(wait, current);
@@ -672,7 +544,7 @@ static void vivi_sleep(struct vivi_fh *fh)
672 /* Calculate time to wake up */ 544 /* Calculate time to wake up */
673 timeout = msecs_to_jiffies(frames_to_ms(1)); 545 timeout = msecs_to_jiffies(frames_to_ms(1));
674 546
675 vivi_thread_tick(fh); 547 vivi_thread_tick(dev);
676 548
677 schedule_timeout_interruptible(timeout); 549 schedule_timeout_interruptible(timeout);
678 550
@@ -683,15 +555,14 @@ stop_task:
683 555
684static int vivi_thread(void *data) 556static int vivi_thread(void *data)
685{ 557{
686 struct vivi_fh *fh = data; 558 struct vivi_dev *dev = data;
687 struct vivi_dev *dev = fh->dev;
688 559
689 dprintk(dev, 1, "thread started\n"); 560 dprintk(dev, 1, "thread started\n");
690 561
691 set_freezable(); 562 set_freezable();
692 563
693 for (;;) { 564 for (;;) {
694 vivi_sleep(fh); 565 vivi_sleep(dev);
695 566
696 if (kthread_should_stop()) 567 if (kthread_should_stop())
697 break; 568 break;
@@ -700,39 +571,61 @@ static int vivi_thread(void *data)
700 return 0; 571 return 0;
701} 572}
702 573
703static int vivi_start_thread(struct vivi_fh *fh) 574static void vivi_start_generating(struct file *file)
704{ 575{
705 struct vivi_dev *dev = fh->dev; 576 struct vivi_dev *dev = video_drvdata(file);
706 struct vivi_dmaqueue *dma_q = &dev->vidq; 577 struct vivi_dmaqueue *dma_q = &dev->vidq;
707 578
708 dma_q->frame = 0;
709 dma_q->ini_jiffies = jiffies;
710
711 dprintk(dev, 1, "%s\n", __func__); 579 dprintk(dev, 1, "%s\n", __func__);
712 580
713 dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); 581 if (test_and_set_bit(0, &dev->generating))
582 return;
583 file->private_data = dev;
584
585 /* Resets frame counters */
586 dev->ms = 0;
587 dev->mv_count = 0;
588 dev->jiffies = jiffies;
589
590 dma_q->frame = 0;
591 dma_q->ini_jiffies = jiffies;
592 dma_q->kthread = kthread_run(vivi_thread, dev, dev->v4l2_dev.name);
714 593
715 if (IS_ERR(dma_q->kthread)) { 594 if (IS_ERR(dma_q->kthread)) {
716 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); 595 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
717 return PTR_ERR(dma_q->kthread); 596 clear_bit(0, &dev->generating);
597 return;
718 } 598 }
719 /* Wakes thread */ 599 /* Wakes thread */
720 wake_up_interruptible(&dma_q->wq); 600 wake_up_interruptible(&dma_q->wq);
721 601
722 dprintk(dev, 1, "returning from %s\n", __func__); 602 dprintk(dev, 1, "returning from %s\n", __func__);
723 return 0;
724} 603}
725 604
726static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) 605static void vivi_stop_generating(struct file *file)
727{ 606{
728 struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); 607 struct vivi_dev *dev = video_drvdata(file);
608 struct vivi_dmaqueue *dma_q = &dev->vidq;
729 609
730 dprintk(dev, 1, "%s\n", __func__); 610 dprintk(dev, 1, "%s\n", __func__);
611
612 if (!file->private_data)
613 return;
614 if (!test_and_clear_bit(0, &dev->generating))
615 return;
616
731 /* shutdown control thread */ 617 /* shutdown control thread */
732 if (dma_q->kthread) { 618 if (dma_q->kthread) {
733 kthread_stop(dma_q->kthread); 619 kthread_stop(dma_q->kthread);
734 dma_q->kthread = NULL; 620 dma_q->kthread = NULL;
735 } 621 }
622 videobuf_stop(&dev->vb_vidq);
623 videobuf_mmap_free(&dev->vb_vidq);
624}
625
626static int vivi_is_generating(struct vivi_dev *dev)
627{
628 return test_bit(0, &dev->generating);
736} 629}
737 630
738/* ------------------------------------------------------------------ 631/* ------------------------------------------------------------------
@@ -741,10 +634,9 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q)
741static int 634static int
742buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) 635buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
743{ 636{
744 struct vivi_fh *fh = vq->priv_data; 637 struct vivi_dev *dev = vq->priv_data;
745 struct vivi_dev *dev = fh->dev;
746 638
747 *size = fh->width*fh->height*2; 639 *size = dev->width * dev->height * 2;
748 640
749 if (0 == *count) 641 if (0 == *count)
750 *count = 32; 642 *count = 32;
@@ -760,49 +652,43 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
760 652
761static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) 653static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
762{ 654{
763 struct vivi_fh *fh = vq->priv_data; 655 struct vivi_dev *dev = vq->priv_data;
764 struct vivi_dev *dev = fh->dev;
765 656
766 dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); 657 dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state);
767 658
768 if (in_interrupt())
769 BUG();
770
771 videobuf_vmalloc_free(&buf->vb); 659 videobuf_vmalloc_free(&buf->vb);
772 dprintk(dev, 1, "free_buffer: freed\n"); 660 dprintk(dev, 1, "free_buffer: freed\n");
773 buf->vb.state = VIDEOBUF_NEEDS_INIT; 661 buf->vb.state = VIDEOBUF_NEEDS_INIT;
774} 662}
775 663
776#define norm_maxw() 1024
777#define norm_maxh() 768
778static int 664static int
779buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, 665buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
780 enum v4l2_field field) 666 enum v4l2_field field)
781{ 667{
782 struct vivi_fh *fh = vq->priv_data; 668 struct vivi_dev *dev = vq->priv_data;
783 struct vivi_dev *dev = fh->dev;
784 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 669 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
785 int rc; 670 int rc;
786 671
787 dprintk(dev, 1, "%s, field=%d\n", __func__, field); 672 dprintk(dev, 1, "%s, field=%d\n", __func__, field);
788 673
789 BUG_ON(NULL == fh->fmt); 674 BUG_ON(NULL == dev->fmt);
790 675
791 if (fh->width < 48 || fh->width > norm_maxw() || 676 if (dev->width < 48 || dev->width > MAX_WIDTH ||
792 fh->height < 32 || fh->height > norm_maxh()) 677 dev->height < 32 || dev->height > MAX_HEIGHT)
793 return -EINVAL; 678 return -EINVAL;
794 679
795 buf->vb.size = fh->width*fh->height*2; 680 buf->vb.size = dev->width * dev->height * 2;
796 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 681 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
797 return -EINVAL; 682 return -EINVAL;
798 683
799 /* These properties only change when queue is idle, see s_fmt */ 684 /* These properties only change when queue is idle, see s_fmt */
800 buf->fmt = fh->fmt; 685 buf->fmt = dev->fmt;
801 buf->vb.width = fh->width; 686 buf->vb.width = dev->width;
802 buf->vb.height = fh->height; 687 buf->vb.height = dev->height;
803 buf->vb.field = field; 688 buf->vb.field = field;
804 689
805 precalculate_bars(fh); 690 precalculate_bars(dev);
691 precalculate_line(dev);
806 692
807 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 693 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
808 rc = videobuf_iolock(vq, &buf->vb, NULL); 694 rc = videobuf_iolock(vq, &buf->vb, NULL);
@@ -811,7 +697,6 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
811 } 697 }
812 698
813 buf->vb.state = VIDEOBUF_PREPARED; 699 buf->vb.state = VIDEOBUF_PREPARED;
814
815 return 0; 700 return 0;
816 701
817fail: 702fail:
@@ -822,9 +707,8 @@ fail:
822static void 707static void
823buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) 708buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
824{ 709{
825 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 710 struct vivi_dev *dev = vq->priv_data;
826 struct vivi_fh *fh = vq->priv_data; 711 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
827 struct vivi_dev *dev = fh->dev;
828 struct vivi_dmaqueue *vidq = &dev->vidq; 712 struct vivi_dmaqueue *vidq = &dev->vidq;
829 713
830 dprintk(dev, 1, "%s\n", __func__); 714 dprintk(dev, 1, "%s\n", __func__);
@@ -836,9 +720,8 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
836static void buffer_release(struct videobuf_queue *vq, 720static void buffer_release(struct videobuf_queue *vq,
837 struct videobuf_buffer *vb) 721 struct videobuf_buffer *vb)
838{ 722{
839 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 723 struct vivi_dev *dev = vq->priv_data;
840 struct vivi_fh *fh = vq->priv_data; 724 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
841 struct vivi_dev *dev = (struct vivi_dev *)fh->dev;
842 725
843 dprintk(dev, 1, "%s\n", __func__); 726 dprintk(dev, 1, "%s\n", __func__);
844 727
@@ -858,16 +741,14 @@ static struct videobuf_queue_ops vivi_video_qops = {
858static int vidioc_querycap(struct file *file, void *priv, 741static int vidioc_querycap(struct file *file, void *priv,
859 struct v4l2_capability *cap) 742 struct v4l2_capability *cap)
860{ 743{
861 struct vivi_fh *fh = priv; 744 struct vivi_dev *dev = video_drvdata(file);
862 struct vivi_dev *dev = fh->dev;
863 745
864 strcpy(cap->driver, "vivi"); 746 strcpy(cap->driver, "vivi");
865 strcpy(cap->card, "vivi"); 747 strcpy(cap->card, "vivi");
866 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); 748 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
867 cap->version = VIVI_VERSION; 749 cap->version = VIVI_VERSION;
868 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 750 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
869 V4L2_CAP_STREAMING | 751 V4L2_CAP_READWRITE;
870 V4L2_CAP_READWRITE;
871 return 0; 752 return 0;
872} 753}
873 754
@@ -889,28 +770,25 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
889static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 770static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
890 struct v4l2_format *f) 771 struct v4l2_format *f)
891{ 772{
892 struct vivi_fh *fh = priv; 773 struct vivi_dev *dev = video_drvdata(file);
893 774
894 f->fmt.pix.width = fh->width; 775 f->fmt.pix.width = dev->width;
895 f->fmt.pix.height = fh->height; 776 f->fmt.pix.height = dev->height;
896 f->fmt.pix.field = fh->vb_vidq.field; 777 f->fmt.pix.field = dev->vb_vidq.field;
897 f->fmt.pix.pixelformat = fh->fmt->fourcc; 778 f->fmt.pix.pixelformat = dev->fmt->fourcc;
898 f->fmt.pix.bytesperline = 779 f->fmt.pix.bytesperline =
899 (f->fmt.pix.width * fh->fmt->depth) >> 3; 780 (f->fmt.pix.width * dev->fmt->depth) >> 3;
900 f->fmt.pix.sizeimage = 781 f->fmt.pix.sizeimage =
901 f->fmt.pix.height * f->fmt.pix.bytesperline; 782 f->fmt.pix.height * f->fmt.pix.bytesperline;
902 783 return 0;
903 return (0);
904} 784}
905 785
906static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 786static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
907 struct v4l2_format *f) 787 struct v4l2_format *f)
908{ 788{
909 struct vivi_fh *fh = priv; 789 struct vivi_dev *dev = video_drvdata(file);
910 struct vivi_dev *dev = fh->dev;
911 struct vivi_fmt *fmt; 790 struct vivi_fmt *fmt;
912 enum v4l2_field field; 791 enum v4l2_field field;
913 unsigned int maxw, maxh;
914 792
915 fmt = get_format(f); 793 fmt = get_format(f);
916 if (!fmt) { 794 if (!fmt) {
@@ -928,113 +806,109 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
928 return -EINVAL; 806 return -EINVAL;
929 } 807 }
930 808
931 maxw = norm_maxw();
932 maxh = norm_maxh();
933
934 f->fmt.pix.field = field; 809 f->fmt.pix.field = field;
935 v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, 810 v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2,
936 &f->fmt.pix.height, 32, maxh, 0, 0); 811 &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0);
937 f->fmt.pix.bytesperline = 812 f->fmt.pix.bytesperline =
938 (f->fmt.pix.width * fmt->depth) >> 3; 813 (f->fmt.pix.width * fmt->depth) >> 3;
939 f->fmt.pix.sizeimage = 814 f->fmt.pix.sizeimage =
940 f->fmt.pix.height * f->fmt.pix.bytesperline; 815 f->fmt.pix.height * f->fmt.pix.bytesperline;
941
942 return 0; 816 return 0;
943} 817}
944 818
945/*FIXME: This seems to be generic enough to be at videodev2 */
946static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 819static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
947 struct v4l2_format *f) 820 struct v4l2_format *f)
948{ 821{
949 struct vivi_fh *fh = priv; 822 struct vivi_dev *dev = video_drvdata(file);
950 struct videobuf_queue *q = &fh->vb_vidq; 823 struct videobuf_queue *q = &dev->vb_vidq;
951 824
952 int ret = vidioc_try_fmt_vid_cap(file, fh, f); 825 int ret = vidioc_try_fmt_vid_cap(file, priv, f);
953 if (ret < 0) 826 if (ret < 0)
954 return ret; 827 return ret;
955 828
956 mutex_lock(&q->vb_lock); 829 mutex_lock(&q->vb_lock);
957 830
958 if (videobuf_queue_is_busy(&fh->vb_vidq)) { 831 if (vivi_is_generating(dev)) {
959 dprintk(fh->dev, 1, "%s queue busy\n", __func__); 832 dprintk(dev, 1, "%s device busy\n", __func__);
960 ret = -EBUSY; 833 ret = -EBUSY;
961 goto out; 834 goto out;
962 } 835 }
963 836
964 fh->fmt = get_format(f); 837 dev->fmt = get_format(f);
965 fh->width = f->fmt.pix.width; 838 dev->width = f->fmt.pix.width;
966 fh->height = f->fmt.pix.height; 839 dev->height = f->fmt.pix.height;
967 fh->vb_vidq.field = f->fmt.pix.field; 840 dev->vb_vidq.field = f->fmt.pix.field;
968 fh->type = f->type;
969
970 ret = 0; 841 ret = 0;
971out: 842out:
972 mutex_unlock(&q->vb_lock); 843 mutex_unlock(&q->vb_lock);
973
974 return ret; 844 return ret;
975} 845}
976 846
977static int vidioc_reqbufs(struct file *file, void *priv, 847static int vidioc_reqbufs(struct file *file, void *priv,
978 struct v4l2_requestbuffers *p) 848 struct v4l2_requestbuffers *p)
979{ 849{
980 struct vivi_fh *fh = priv; 850 struct vivi_dev *dev = video_drvdata(file);
981 851
982 return (videobuf_reqbufs(&fh->vb_vidq, p)); 852 return videobuf_reqbufs(&dev->vb_vidq, p);
983} 853}
984 854
985static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) 855static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
986{ 856{
987 struct vivi_fh *fh = priv; 857 struct vivi_dev *dev = video_drvdata(file);
988 858
989 return (videobuf_querybuf(&fh->vb_vidq, p)); 859 return videobuf_querybuf(&dev->vb_vidq, p);
990} 860}
991 861
992static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) 862static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
993{ 863{
994 struct vivi_fh *fh = priv; 864 struct vivi_dev *dev = video_drvdata(file);
995 865
996 return (videobuf_qbuf(&fh->vb_vidq, p)); 866 return videobuf_qbuf(&dev->vb_vidq, p);
997} 867}
998 868
999static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) 869static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1000{ 870{
1001 struct vivi_fh *fh = priv; 871 struct vivi_dev *dev = video_drvdata(file);
1002 872
1003 return (videobuf_dqbuf(&fh->vb_vidq, p, 873 return videobuf_dqbuf(&dev->vb_vidq, p,
1004 file->f_flags & O_NONBLOCK)); 874 file->f_flags & O_NONBLOCK);
1005} 875}
1006 876
1007#ifdef CONFIG_VIDEO_V4L1_COMPAT 877#ifdef CONFIG_VIDEO_V4L1_COMPAT
1008static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) 878static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1009{ 879{
1010 struct vivi_fh *fh = priv; 880 struct vivi_dev *dev = video_drvdata(file);
1011 881
1012 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); 882 return videobuf_cgmbuf(&dev->vb_vidq, mbuf, 8);
1013} 883}
1014#endif 884#endif
1015 885
1016static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) 886static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1017{ 887{
1018 struct vivi_fh *fh = priv; 888 struct vivi_dev *dev = video_drvdata(file);
889 int ret;
1019 890
1020 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 891 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1021 return -EINVAL;
1022 if (i != fh->type)
1023 return -EINVAL; 892 return -EINVAL;
893 ret = videobuf_streamon(&dev->vb_vidq);
894 if (ret)
895 return ret;
1024 896
1025 return videobuf_streamon(&fh->vb_vidq); 897 vivi_start_generating(file);
898 return 0;
1026} 899}
1027 900
1028static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) 901static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1029{ 902{
1030 struct vivi_fh *fh = priv; 903 struct vivi_dev *dev = video_drvdata(file);
904 int ret;
1031 905
1032 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 906 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1033 return -EINVAL;
1034 if (i != fh->type)
1035 return -EINVAL; 907 return -EINVAL;
1036 908 ret = videobuf_streamoff(&dev->vb_vidq);
1037 return videobuf_streamoff(&fh->vb_vidq); 909 if (!ret)
910 vivi_stop_generating(file);
911 return ret;
1038} 912}
1039 913
1040static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) 914static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
@@ -1052,80 +926,104 @@ static int vidioc_enum_input(struct file *file, void *priv,
1052 inp->type = V4L2_INPUT_TYPE_CAMERA; 926 inp->type = V4L2_INPUT_TYPE_CAMERA;
1053 inp->std = V4L2_STD_525_60; 927 inp->std = V4L2_STD_525_60;
1054 sprintf(inp->name, "Camera %u", inp->index); 928 sprintf(inp->name, "Camera %u", inp->index);
1055 929 return 0;
1056 return (0);
1057} 930}
1058 931
1059static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) 932static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1060{ 933{
1061 struct vivi_fh *fh = priv; 934 struct vivi_dev *dev = video_drvdata(file);
1062 struct vivi_dev *dev = fh->dev;
1063 935
1064 *i = dev->input; 936 *i = dev->input;
1065 937 return 0;
1066 return (0);
1067} 938}
939
1068static int vidioc_s_input(struct file *file, void *priv, unsigned int i) 940static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1069{ 941{
1070 struct vivi_fh *fh = priv; 942 struct vivi_dev *dev = video_drvdata(file);
1071 struct vivi_dev *dev = fh->dev;
1072 943
1073 if (i >= NUM_INPUTS) 944 if (i >= NUM_INPUTS)
1074 return -EINVAL; 945 return -EINVAL;
1075 946
1076 dev->input = i; 947 dev->input = i;
1077 precalculate_bars(fh); 948 precalculate_bars(dev);
1078 949 precalculate_line(dev);
1079 return (0); 950 return 0;
1080} 951}
1081 952
1082 /* --- controls ---------------------------------------------- */ 953/* --- controls ---------------------------------------------- */
1083static int vidioc_queryctrl(struct file *file, void *priv, 954static int vidioc_queryctrl(struct file *file, void *priv,
1084 struct v4l2_queryctrl *qc) 955 struct v4l2_queryctrl *qc)
1085{ 956{
1086 int i; 957 switch (qc->id) {
1087 958 case V4L2_CID_AUDIO_VOLUME:
1088 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) 959 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 200);
1089 if (qc->id && qc->id == vivi_qctrl[i].id) { 960 case V4L2_CID_BRIGHTNESS:
1090 memcpy(qc, &(vivi_qctrl[i]), 961 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
1091 sizeof(*qc)); 962 case V4L2_CID_CONTRAST:
1092 return (0); 963 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 16);
1093 } 964 case V4L2_CID_SATURATION:
1094 965 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
966 case V4L2_CID_HUE:
967 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
968 }
1095 return -EINVAL; 969 return -EINVAL;
1096} 970}
1097 971
1098static int vidioc_g_ctrl(struct file *file, void *priv, 972static int vidioc_g_ctrl(struct file *file, void *priv,
1099 struct v4l2_control *ctrl) 973 struct v4l2_control *ctrl)
1100{ 974{
1101 struct vivi_fh *fh = priv; 975 struct vivi_dev *dev = video_drvdata(file);
1102 struct vivi_dev *dev = fh->dev;
1103 int i;
1104
1105 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1106 if (ctrl->id == vivi_qctrl[i].id) {
1107 ctrl->value = dev->qctl_regs[i];
1108 return 0;
1109 }
1110 976
977 switch (ctrl->id) {
978 case V4L2_CID_AUDIO_VOLUME:
979 ctrl->value = dev->volume;
980 return 0;
981 case V4L2_CID_BRIGHTNESS:
982 ctrl->value = dev->brightness;
983 return 0;
984 case V4L2_CID_CONTRAST:
985 ctrl->value = dev->contrast;
986 return 0;
987 case V4L2_CID_SATURATION:
988 ctrl->value = dev->saturation;
989 return 0;
990 case V4L2_CID_HUE:
991 ctrl->value = dev->hue;
992 return 0;
993 }
1111 return -EINVAL; 994 return -EINVAL;
1112} 995}
996
1113static int vidioc_s_ctrl(struct file *file, void *priv, 997static int vidioc_s_ctrl(struct file *file, void *priv,
1114 struct v4l2_control *ctrl) 998 struct v4l2_control *ctrl)
1115{ 999{
1116 struct vivi_fh *fh = priv; 1000 struct vivi_dev *dev = video_drvdata(file);
1117 struct vivi_dev *dev = fh->dev; 1001 struct v4l2_queryctrl qc;
1118 int i; 1002 int err;
1119 1003
1120 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) 1004 qc.id = ctrl->id;
1121 if (ctrl->id == vivi_qctrl[i].id) { 1005 err = vidioc_queryctrl(file, priv, &qc);
1122 if (ctrl->value < vivi_qctrl[i].minimum || 1006 if (err < 0)
1123 ctrl->value > vivi_qctrl[i].maximum) { 1007 return err;
1124 return -ERANGE; 1008 if (ctrl->value < qc.minimum || ctrl->value > qc.maximum)
1125 } 1009 return -ERANGE;
1126 dev->qctl_regs[i] = ctrl->value; 1010 switch (ctrl->id) {
1127 return 0; 1011 case V4L2_CID_AUDIO_VOLUME:
1128 } 1012 dev->volume = ctrl->value;
1013 return 0;
1014 case V4L2_CID_BRIGHTNESS:
1015 dev->brightness = ctrl->value;
1016 return 0;
1017 case V4L2_CID_CONTRAST:
1018 dev->contrast = ctrl->value;
1019 return 0;
1020 case V4L2_CID_SATURATION:
1021 dev->saturation = ctrl->value;
1022 return 0;
1023 case V4L2_CID_HUE:
1024 dev->hue = ctrl->value;
1025 return 0;
1026 }
1129 return -EINVAL; 1027 return -EINVAL;
1130} 1028}
1131 1029
@@ -1133,134 +1031,58 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1133 File operations for the device 1031 File operations for the device
1134 ------------------------------------------------------------------*/ 1032 ------------------------------------------------------------------*/
1135 1033
1136static int vivi_open(struct file *file)
1137{
1138 struct vivi_dev *dev = video_drvdata(file);
1139 struct vivi_fh *fh = NULL;
1140 int retval = 0;
1141
1142 mutex_lock(&dev->mutex);
1143 dev->users++;
1144
1145 if (dev->users > 1) {
1146 dev->users--;
1147 mutex_unlock(&dev->mutex);
1148 return -EBUSY;
1149 }
1150
1151 dprintk(dev, 1, "open %s type=%s users=%d\n",
1152 video_device_node_name(dev->vfd),
1153 v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
1154
1155 /* allocate + initialize per filehandle data */
1156 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1157 if (NULL == fh) {
1158 dev->users--;
1159 retval = -ENOMEM;
1160 }
1161 mutex_unlock(&dev->mutex);
1162
1163 if (retval)
1164 return retval;
1165
1166 file->private_data = fh;
1167 fh->dev = dev;
1168
1169 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1170 fh->fmt = &formats[0];
1171 fh->width = 640;
1172 fh->height = 480;
1173
1174 /* Resets frame counters */
1175 dev->h = 0;
1176 dev->m = 0;
1177 dev->s = 0;
1178 dev->ms = 0;
1179 dev->mv_count = 0;
1180 dev->jiffies = jiffies;
1181 sprintf(dev->timestr, "%02d:%02d:%02d:%03d",
1182 dev->h, dev->m, dev->s, dev->ms);
1183
1184 videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops,
1185 NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED,
1186 sizeof(struct vivi_buffer), fh);
1187
1188 vivi_start_thread(fh);
1189
1190 return 0;
1191}
1192
1193static ssize_t 1034static ssize_t
1194vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1035vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1195{ 1036{
1196 struct vivi_fh *fh = file->private_data; 1037 struct vivi_dev *dev = video_drvdata(file);
1197 1038
1198 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1039 vivi_start_generating(file);
1199 return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0, 1040 return videobuf_read_stream(&dev->vb_vidq, data, count, ppos, 0,
1200 file->f_flags & O_NONBLOCK); 1041 file->f_flags & O_NONBLOCK);
1201 }
1202 return 0;
1203} 1042}
1204 1043
1205static unsigned int 1044static unsigned int
1206vivi_poll(struct file *file, struct poll_table_struct *wait) 1045vivi_poll(struct file *file, struct poll_table_struct *wait)
1207{ 1046{
1208 struct vivi_fh *fh = file->private_data; 1047 struct vivi_dev *dev = video_drvdata(file);
1209 struct vivi_dev *dev = fh->dev; 1048 struct videobuf_queue *q = &dev->vb_vidq;
1210 struct videobuf_queue *q = &fh->vb_vidq;
1211 1049
1212 dprintk(dev, 1, "%s\n", __func__); 1050 dprintk(dev, 1, "%s\n", __func__);
1213 1051
1214 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 1052 vivi_start_generating(file);
1215 return POLLERR;
1216
1217 return videobuf_poll_stream(file, q, wait); 1053 return videobuf_poll_stream(file, q, wait);
1218} 1054}
1219 1055
1220static int vivi_close(struct file *file) 1056static int vivi_close(struct file *file)
1221{ 1057{
1222 struct vivi_fh *fh = file->private_data;
1223 struct vivi_dev *dev = fh->dev;
1224 struct vivi_dmaqueue *vidq = &dev->vidq;
1225 struct video_device *vdev = video_devdata(file); 1058 struct video_device *vdev = video_devdata(file);
1059 struct vivi_dev *dev = video_drvdata(file);
1226 1060
1227 vivi_stop_thread(vidq); 1061 vivi_stop_generating(file);
1228 videobuf_stop(&fh->vb_vidq);
1229 videobuf_mmap_free(&fh->vb_vidq);
1230
1231 kfree(fh);
1232
1233 mutex_lock(&dev->mutex);
1234 dev->users--;
1235 mutex_unlock(&dev->mutex);
1236
1237 dprintk(dev, 1, "close called (dev=%s, users=%d)\n",
1238 video_device_node_name(vdev), dev->users);
1239 1062
1063 dprintk(dev, 1, "close called (dev=%s)\n",
1064 video_device_node_name(vdev));
1240 return 0; 1065 return 0;
1241} 1066}
1242 1067
1243static int vivi_mmap(struct file *file, struct vm_area_struct *vma) 1068static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1244{ 1069{
1245 struct vivi_fh *fh = file->private_data; 1070 struct vivi_dev *dev = video_drvdata(file);
1246 struct vivi_dev *dev = fh->dev;
1247 int ret; 1071 int ret;
1248 1072
1249 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 1073 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1250 1074
1251 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); 1075 ret = videobuf_mmap_mapper(&dev->vb_vidq, vma);
1252 1076
1253 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", 1077 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n",
1254 (unsigned long)vma->vm_start, 1078 (unsigned long)vma->vm_start,
1255 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, 1079 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
1256 ret); 1080 ret);
1257
1258 return ret; 1081 return ret;
1259} 1082}
1260 1083
1261static const struct v4l2_file_operations vivi_fops = { 1084static const struct v4l2_file_operations vivi_fops = {
1262 .owner = THIS_MODULE, 1085 .owner = THIS_MODULE,
1263 .open = vivi_open,
1264 .release = vivi_close, 1086 .release = vivi_close,
1265 .read = vivi_read, 1087 .read = vivi_read,
1266 .poll = vivi_poll, 1088 .poll = vivi_poll,
@@ -1282,11 +1104,11 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
1282 .vidioc_enum_input = vidioc_enum_input, 1104 .vidioc_enum_input = vidioc_enum_input,
1283 .vidioc_g_input = vidioc_g_input, 1105 .vidioc_g_input = vidioc_g_input,
1284 .vidioc_s_input = vidioc_s_input, 1106 .vidioc_s_input = vidioc_s_input,
1107 .vidioc_streamon = vidioc_streamon,
1108 .vidioc_streamoff = vidioc_streamoff,
1285 .vidioc_queryctrl = vidioc_queryctrl, 1109 .vidioc_queryctrl = vidioc_queryctrl,
1286 .vidioc_g_ctrl = vidioc_g_ctrl, 1110 .vidioc_g_ctrl = vidioc_g_ctrl,
1287 .vidioc_s_ctrl = vidioc_s_ctrl, 1111 .vidioc_s_ctrl = vidioc_s_ctrl,
1288 .vidioc_streamon = vidioc_streamon,
1289 .vidioc_streamoff = vidioc_streamoff,
1290#ifdef CONFIG_VIDEO_V4L1_COMPAT 1112#ifdef CONFIG_VIDEO_V4L1_COMPAT
1291 .vidiocgmbuf = vidiocgmbuf, 1113 .vidiocgmbuf = vidiocgmbuf,
1292#endif 1114#endif
@@ -1330,7 +1152,7 @@ static int __init vivi_create_instance(int inst)
1330{ 1152{
1331 struct vivi_dev *dev; 1153 struct vivi_dev *dev;
1332 struct video_device *vfd; 1154 struct video_device *vfd;
1333 int ret, i; 1155 int ret;
1334 1156
1335 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1157 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1336 if (!dev) 1158 if (!dev)
@@ -1342,6 +1164,20 @@ static int __init vivi_create_instance(int inst)
1342 if (ret) 1164 if (ret)
1343 goto free_dev; 1165 goto free_dev;
1344 1166
1167 dev->fmt = &formats[0];
1168 dev->width = 640;
1169 dev->height = 480;
1170 dev->volume = 200;
1171 dev->brightness = 127;
1172 dev->contrast = 16;
1173 dev->saturation = 127;
1174 dev->hue = 0;
1175
1176 videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops,
1177 NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
1178 V4L2_FIELD_INTERLACED,
1179 sizeof(struct vivi_buffer), dev);
1180
1345 /* init video dma queues */ 1181 /* init video dma queues */
1346 INIT_LIST_HEAD(&dev->vidq.active); 1182 INIT_LIST_HEAD(&dev->vidq.active);
1347 init_waitqueue_head(&dev->vidq.wq); 1183 init_waitqueue_head(&dev->vidq.wq);
@@ -1357,6 +1193,7 @@ static int __init vivi_create_instance(int inst)
1357 1193
1358 *vfd = vivi_template; 1194 *vfd = vivi_template;
1359 vfd->debug = debug; 1195 vfd->debug = debug;
1196 vfd->v4l2_dev = &dev->v4l2_dev;
1360 1197
1361 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); 1198 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1362 if (ret < 0) 1199 if (ret < 0)
@@ -1364,10 +1201,6 @@ static int __init vivi_create_instance(int inst)
1364 1201
1365 video_set_drvdata(vfd, dev); 1202 video_set_drvdata(vfd, dev);
1366 1203
1367 /* Set all controls to their default value. */
1368 for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
1369 dev->qctl_regs[i] = vivi_qctrl[i].default_value;
1370
1371 /* Now that everything is fine, let's add it to device list */ 1204 /* Now that everything is fine, let's add it to device list */
1372 list_add_tail(&dev->vivi_devlist, &vivi_devlist); 1205 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1373 1206
@@ -1396,8 +1229,15 @@ free_dev:
1396 */ 1229 */
1397static int __init vivi_init(void) 1230static int __init vivi_init(void)
1398{ 1231{
1232 const struct font_desc *font = find_font("VGA8x16");
1399 int ret = 0, i; 1233 int ret = 0, i;
1400 1234
1235 if (font == NULL) {
1236 printk(KERN_ERR "vivi: could not find font\n");
1237 return -ENODEV;
1238 }
1239 font8x16 = font->data;
1240
1401 if (n_devs <= 0) 1241 if (n_devs <= 0)
1402 n_devs = 1; 1242 n_devs = 1;
1403 1243
@@ -1412,7 +1252,7 @@ static int __init vivi_init(void)
1412 } 1252 }
1413 1253
1414 if (ret < 0) { 1254 if (ret < 0) {
1415 printk(KERN_INFO "Error %d while loading vivi driver\n", ret); 1255 printk(KERN_ERR "vivi: error %d while loading driver\n", ret);
1416 return ret; 1256 return ret;
1417 } 1257 }
1418 1258
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index bf9bf650a317..635420d8d84a 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Winbond w9966cf Webcam parport driver. 2 Winbond w9966cf Webcam parport driver.
3 3
4 Version 0.32 4 Version 0.33
5 5
6 Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se> 6 Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
7 7
@@ -57,10 +57,12 @@
57#include <linux/module.h> 57#include <linux/module.h>
58#include <linux/init.h> 58#include <linux/init.h>
59#include <linux/delay.h> 59#include <linux/delay.h>
60#include <linux/videodev.h> 60#include <linux/version.h>
61#include <linux/videodev2.h>
61#include <linux/slab.h> 62#include <linux/slab.h>
62#include <media/v4l2-common.h> 63#include <media/v4l2-common.h>
63#include <media/v4l2-ioctl.h> 64#include <media/v4l2-ioctl.h>
65#include <media/v4l2-device.h>
64#include <linux/parport.h> 66#include <linux/parport.h>
65 67
66/*#define DEBUG*/ /* Undef me for production */ 68/*#define DEBUG*/ /* Undef me for production */
@@ -76,12 +78,12 @@
76 */ 78 */
77 79
78#define W9966_DRIVERNAME "W9966CF Webcam" 80#define W9966_DRIVERNAME "W9966CF Webcam"
79#define W9966_MAXCAMS 4 // Maximum number of cameras 81#define W9966_MAXCAMS 4 /* Maximum number of cameras */
80#define W9966_RBUFFER 2048 // Read buffer (must be an even number) 82#define W9966_RBUFFER 2048 /* Read buffer (must be an even number) */
81#define W9966_SRAMSIZE 131072 // 128kb 83#define W9966_SRAMSIZE 131072 /* 128kb */
82#define W9966_SRAMID 0x02 // check w9966cf.pdf 84#define W9966_SRAMID 0x02 /* check w9966cf.pdf */
83 85
84// Empirically determined window limits 86/* Empirically determined window limits */
85#define W9966_WND_MIN_X 16 87#define W9966_WND_MIN_X 16
86#define W9966_WND_MIN_Y 14 88#define W9966_WND_MIN_Y 14
87#define W9966_WND_MAX_X 705 89#define W9966_WND_MAX_X 705
@@ -89,7 +91,7 @@
89#define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X) 91#define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
90#define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y) 92#define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
91 93
92// Keep track of our current state 94/* Keep track of our current state */
93#define W9966_STATE_PDEV 0x01 95#define W9966_STATE_PDEV 0x01
94#define W9966_STATE_CLAIMED 0x02 96#define W9966_STATE_CLAIMED 0x02
95#define W9966_STATE_VDEV 0x04 97#define W9966_STATE_VDEV 0x04
@@ -101,12 +103,13 @@
101#define W9966_I2C_W_DATA 0x02 103#define W9966_I2C_W_DATA 0x02
102#define W9966_I2C_W_CLOCK 0x01 104#define W9966_I2C_W_CLOCK 0x01
103 105
104struct w9966_dev { 106struct w9966 {
107 struct v4l2_device v4l2_dev;
105 unsigned char dev_state; 108 unsigned char dev_state;
106 unsigned char i2c_state; 109 unsigned char i2c_state;
107 unsigned short ppmode; 110 unsigned short ppmode;
108 struct parport* pport; 111 struct parport *pport;
109 struct pardevice* pdev; 112 struct pardevice *pdev;
110 struct video_device vdev; 113 struct video_device vdev;
111 unsigned short width; 114 unsigned short width;
112 unsigned short height; 115 unsigned short height;
@@ -114,7 +117,7 @@ struct w9966_dev {
114 signed char contrast; 117 signed char contrast;
115 signed char color; 118 signed char color;
116 signed char hue; 119 signed char hue;
117 unsigned long in_use; 120 struct mutex lock;
118}; 121};
119 122
120/* 123/*
@@ -127,15 +130,15 @@ MODULE_LICENSE("GPL");
127 130
128 131
129#ifdef MODULE 132#ifdef MODULE
130static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""}; 133static const char *pardev[] = {[0 ... W9966_MAXCAMS] = ""};
131#else 134#else
132static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"}; 135static const char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
133#endif 136#endif
134module_param_array(pardev, charp, NULL, 0); 137module_param_array(pardev, charp, NULL, 0);
135MODULE_PARM_DESC(pardev, "pardev: where to search for\n\ 138MODULE_PARM_DESC(pardev, "pardev: where to search for\n"
136\teach camera. 'aggressive' means brute-force search.\n\ 139 "\teach camera. 'aggressive' means brute-force search.\n"
137\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\ 140 "\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n"
138\tcam 1 to parport3 and search every parport for cam 2 etc..."); 141 "\tcam 1 to parport3 and search every parport for cam 2 etc...");
139 142
140static int parmode; 143static int parmode;
141module_param(parmode, int, 0); 144module_param(parmode, int, 0);
@@ -144,117 +147,49 @@ MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
144static int video_nr = -1; 147static int video_nr = -1;
145module_param(video_nr, int, 0); 148module_param(video_nr, int, 0);
146 149
147/* 150static struct w9966 w9966_cams[W9966_MAXCAMS];
148 * Private data
149 */
150
151static struct w9966_dev w9966_cams[W9966_MAXCAMS];
152
153/*
154 * Private function declares
155 */
156
157static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
158static inline int w9966_getState(struct w9966_dev* cam, int mask, int val);
159static inline void w9966_pdev_claim(struct w9966_dev *vdev);
160static inline void w9966_pdev_release(struct w9966_dev *vdev);
161
162static int w9966_rReg(struct w9966_dev* cam, int reg);
163static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
164#if 0
165static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
166#endif
167static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
168static int w9966_findlen(int near, int size, int maxlen);
169static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
170static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
171
172static int w9966_init(struct w9966_dev* cam, struct parport* port);
173static void w9966_term(struct w9966_dev* cam);
174
175static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
176static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state);
177static inline int w9966_i2c_getsda(struct w9966_dev* cam);
178static inline int w9966_i2c_getscl(struct w9966_dev* cam);
179static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
180#if 0
181static int w9966_i2c_rbyte(struct w9966_dev* cam);
182#endif
183
184static long w9966_v4l_ioctl(struct file *file,
185 unsigned int cmd, unsigned long arg);
186static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
187 size_t count, loff_t *ppos);
188
189static int w9966_exclusive_open(struct file *file)
190{
191 struct w9966_dev *cam = video_drvdata(file);
192
193 return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0;
194}
195
196static int w9966_exclusive_release(struct file *file)
197{
198 struct w9966_dev *cam = video_drvdata(file);
199
200 clear_bit(0, &cam->in_use);
201 return 0;
202}
203
204static const struct v4l2_file_operations w9966_fops = {
205 .owner = THIS_MODULE,
206 .open = w9966_exclusive_open,
207 .release = w9966_exclusive_release,
208 .ioctl = w9966_v4l_ioctl,
209 .read = w9966_v4l_read,
210};
211static struct video_device w9966_template = {
212 .name = W9966_DRIVERNAME,
213 .fops = &w9966_fops,
214 .release = video_device_release_empty,
215};
216 151
217/* 152/*
218 * Private function defines 153 * Private function defines
219 */ 154 */
220 155
221 156
222// Set camera phase flags, so we know what to uninit when terminating 157/* Set camera phase flags, so we know what to uninit when terminating */
223static inline void w9966_setState(struct w9966_dev* cam, int mask, int val) 158static inline void w9966_set_state(struct w9966 *cam, int mask, int val)
224{ 159{
225 cam->dev_state = (cam->dev_state & ~mask) ^ val; 160 cam->dev_state = (cam->dev_state & ~mask) ^ val;
226} 161}
227 162
228// Get camera phase flags 163/* Get camera phase flags */
229static inline int w9966_getState(struct w9966_dev* cam, int mask, int val) 164static inline int w9966_get_state(struct w9966 *cam, int mask, int val)
230{ 165{
231 return ((cam->dev_state & mask) == val); 166 return ((cam->dev_state & mask) == val);
232} 167}
233 168
234// Claim parport for ourself 169/* Claim parport for ourself */
235static inline void w9966_pdev_claim(struct w9966_dev* cam) 170static void w9966_pdev_claim(struct w9966 *cam)
236{ 171{
237 if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED)) 172 if (w9966_get_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
238 return; 173 return;
239 parport_claim_or_block(cam->pdev); 174 parport_claim_or_block(cam->pdev);
240 w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED); 175 w9966_set_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
241} 176}
242 177
243// Release parport for others to use 178/* Release parport for others to use */
244static inline void w9966_pdev_release(struct w9966_dev* cam) 179static void w9966_pdev_release(struct w9966 *cam)
245{ 180{
246 if (w9966_getState(cam, W9966_STATE_CLAIMED, 0)) 181 if (w9966_get_state(cam, W9966_STATE_CLAIMED, 0))
247 return; 182 return;
248 parport_release(cam->pdev); 183 parport_release(cam->pdev);
249 w9966_setState(cam, W9966_STATE_CLAIMED, 0); 184 w9966_set_state(cam, W9966_STATE_CLAIMED, 0);
250} 185}
251 186
252// Read register from W9966 interface-chip 187/* Read register from W9966 interface-chip
253// Expects a claimed pdev 188 Expects a claimed pdev
254// -1 on error, else register data (byte) 189 -1 on error, else register data (byte) */
255static int w9966_rReg(struct w9966_dev* cam, int reg) 190static int w9966_read_reg(struct w9966 *cam, int reg)
256{ 191{
257 // ECP, read, regtransfer, REG, REG, REG, REG, REG 192 /* ECP, read, regtransfer, REG, REG, REG, REG, REG */
258 const unsigned char addr = 0x80 | (reg & 0x1f); 193 const unsigned char addr = 0x80 | (reg & 0x1f);
259 unsigned char val; 194 unsigned char val;
260 195
@@ -270,12 +205,12 @@ static int w9966_rReg(struct w9966_dev* cam, int reg)
270 return val; 205 return val;
271} 206}
272 207
273// Write register to W9966 interface-chip 208/* Write register to W9966 interface-chip
274// Expects a claimed pdev 209 Expects a claimed pdev
275// -1 on error 210 -1 on error */
276static int w9966_wReg(struct w9966_dev* cam, int reg, int data) 211static int w9966_write_reg(struct w9966 *cam, int reg, int data)
277{ 212{
278 // ECP, write, regtransfer, REG, REG, REG, REG, REG 213 /* ECP, write, regtransfer, REG, REG, REG, REG, REG */
279 const unsigned char addr = 0xc0 | (reg & 0x1f); 214 const unsigned char addr = 0xc0 | (reg & 0x1f);
280 const unsigned char val = data; 215 const unsigned char val = data;
281 216
@@ -291,119 +226,186 @@ static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
291 return 0; 226 return 0;
292} 227}
293 228
294// Initialize camera device. Setup all internal flags, set a 229/*
295// default video mode, setup ccd-chip, register v4l device etc.. 230 * Ugly and primitive i2c protocol functions
296// Also used for 'probing' of hardware. 231 */
297// -1 on error 232
298static int w9966_init(struct w9966_dev* cam, struct parport* port) 233/* Sets the data line on the i2c bus.
234 Expects a claimed pdev. */
235static void w9966_i2c_setsda(struct w9966 *cam, int state)
299{ 236{
300 if (cam->dev_state != 0) 237 if (state)
301 return -1; 238 cam->i2c_state |= W9966_I2C_W_DATA;
239 else
240 cam->i2c_state &= ~W9966_I2C_W_DATA;
302 241
303 cam->pport = port; 242 w9966_write_reg(cam, 0x18, cam->i2c_state);
304 cam->brightness = 128; 243 udelay(5);
305 cam->contrast = 64; 244}
306 cam->color = 64;
307 cam->hue = 0;
308 245
309// Select requested transfer mode 246/* Get peripheral clock line
310 switch(parmode) 247 Expects a claimed pdev. */
311 { 248static int w9966_i2c_getscl(struct w9966 *cam)
312 default: // Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) 249{
313 case 0: 250 const unsigned char state = w9966_read_reg(cam, 0x18);
314 if (port->modes & PARPORT_MODE_ECP) 251 return ((state & W9966_I2C_R_CLOCK) > 0);
315 cam->ppmode = IEEE1284_MODE_ECP; 252}
316 else if (port->modes & PARPORT_MODE_EPP) 253
317 cam->ppmode = IEEE1284_MODE_EPP; 254/* Sets the clock line on the i2c bus.
318 else 255 Expects a claimed pdev. -1 on error */
319 cam->ppmode = IEEE1284_MODE_ECP; 256static int w9966_i2c_setscl(struct w9966 *cam, int state)
320 break; 257{
321 case 1: // hw- or sw-ecp 258 unsigned long timeout;
322 cam->ppmode = IEEE1284_MODE_ECP; 259
323 break; 260 if (state)
324 case 2: // hw- or sw-epp 261 cam->i2c_state |= W9966_I2C_W_CLOCK;
325 cam->ppmode = IEEE1284_MODE_EPP; 262 else
326 break; 263 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
264
265 w9966_write_reg(cam, 0x18, cam->i2c_state);
266 udelay(5);
267
268 /* we go to high, we also expect the peripheral to ack. */
269 if (state) {
270 timeout = jiffies + 100;
271 while (!w9966_i2c_getscl(cam)) {
272 if (time_after(jiffies, timeout))
273 return -1;
274 }
327 } 275 }
276 return 0;
277}
328 278
329// Tell the parport driver that we exists 279#if 0
330 cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL); 280/* Get peripheral data line
331 if (cam->pdev == NULL) { 281 Expects a claimed pdev. */
332 DPRINTF("parport_register_device() failed\n"); 282static int w9966_i2c_getsda(struct w9966 *cam)
333 return -1; 283{
284 const unsigned char state = w9966_read_reg(cam, 0x18);
285 return ((state & W9966_I2C_R_DATA) > 0);
286}
287#endif
288
289/* Write a byte with ack to the i2c bus.
290 Expects a claimed pdev. -1 on error */
291static int w9966_i2c_wbyte(struct w9966 *cam, int data)
292{
293 int i;
294
295 for (i = 7; i >= 0; i--) {
296 w9966_i2c_setsda(cam, (data >> i) & 0x01);
297
298 if (w9966_i2c_setscl(cam, 1) == -1)
299 return -1;
300 w9966_i2c_setscl(cam, 0);
334 } 301 }
335 w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
336 302
337 w9966_pdev_claim(cam); 303 w9966_i2c_setsda(cam, 1);
338 304
339// Setup a default capture mode 305 if (w9966_i2c_setscl(cam, 1) == -1)
340 if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
341 DPRINTF("w9966_setup() failed.\n");
342 return -1; 306 return -1;
307 w9966_i2c_setscl(cam, 0);
308
309 return 0;
310}
311
312/* Read a data byte with ack from the i2c-bus
313 Expects a claimed pdev. -1 on error */
314#if 0
315static int w9966_i2c_rbyte(struct w9966 *cam)
316{
317 unsigned char data = 0x00;
318 int i;
319
320 w9966_i2c_setsda(cam, 1);
321
322 for (i = 0; i < 8; i++) {
323 if (w9966_i2c_setscl(cam, 1) == -1)
324 return -1;
325 data = data << 1;
326 if (w9966_i2c_getsda(cam))
327 data |= 0x01;
328
329 w9966_i2c_setscl(cam, 0);
343 } 330 }
331 return data;
332}
333#endif
344 334
345 w9966_pdev_release(cam); 335/* Read a register from the i2c device.
336 Expects claimed pdev. -1 on error */
337#if 0
338static int w9966_read_reg_i2c(struct w9966 *cam, int reg)
339{
340 int data;
346 341
347// Fill in the video_device struct and register us to v4l 342 w9966_i2c_setsda(cam, 0);
348 memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device)); 343 w9966_i2c_setscl(cam, 0);
349 video_set_drvdata(&cam->vdev, cam);
350 344
351 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) 345 if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
346 w9966_i2c_wbyte(cam, reg) == -1)
347 return -1;
348
349 w9966_i2c_setsda(cam, 1);
350 if (w9966_i2c_setscl(cam, 1) == -1)
352 return -1; 351 return -1;
352 w9966_i2c_setsda(cam, 0);
353 w9966_i2c_setscl(cam, 0);
353 354
354 w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); 355 if (w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1)
356 return -1;
357 data = w9966_i2c_rbyte(cam);
358 if (data == -1)
359 return -1;
355 360
356 // All ok 361 w9966_i2c_setsda(cam, 0);
357 printk(
358 "w9966cf: Found and initialized a webcam on %s.\n",
359 cam->pport->name
360 );
361 return 0;
362}
363 362
363 if (w9966_i2c_setscl(cam, 1) == -1)
364 return -1;
365 w9966_i2c_setsda(cam, 1);
364 366
365// Terminate everything gracefully 367 return data;
366static void w9966_term(struct w9966_dev* cam) 368}
369#endif
370
371/* Write a register to the i2c device.
372 Expects claimed pdev. -1 on error */
373static int w9966_write_reg_i2c(struct w9966 *cam, int reg, int data)
367{ 374{
368// Unregister from v4l 375 w9966_i2c_setsda(cam, 0);
369 if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) { 376 w9966_i2c_setscl(cam, 0);
370 video_unregister_device(&cam->vdev);
371 w9966_setState(cam, W9966_STATE_VDEV, 0);
372 }
373 377
374// Terminate from IEEE1284 mode and release pdev block 378 if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
375 if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { 379 w9966_i2c_wbyte(cam, reg) == -1 ||
376 w9966_pdev_claim(cam); 380 w9966_i2c_wbyte(cam, data) == -1)
377 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT); 381 return -1;
378 w9966_pdev_release(cam);
379 }
380 382
381// Unregister from parport 383 w9966_i2c_setsda(cam, 0);
382 if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { 384 if (w9966_i2c_setscl(cam, 1) == -1)
383 parport_unregister_device(cam->pdev); 385 return -1;
384 w9966_setState(cam, W9966_STATE_PDEV, 0); 386
385 } 387 w9966_i2c_setsda(cam, 1);
386}
387 388
389 return 0;
390}
388 391
389// Find a good length for capture window (used both for W and H) 392/* Find a good length for capture window (used both for W and H)
390// A bit ugly but pretty functional. The capture length 393 A bit ugly but pretty functional. The capture length
391// have to match the downscale 394 have to match the downscale */
392static int w9966_findlen(int near, int size, int maxlen) 395static int w9966_findlen(int near, int size, int maxlen)
393{ 396{
394 int bestlen = size; 397 int bestlen = size;
395 int besterr = abs(near - bestlen); 398 int besterr = abs(near - bestlen);
396 int len; 399 int len;
397 400
398 for(len = size+1;len < maxlen;len++) 401 for (len = size + 1; len < maxlen; len++) {
399 {
400 int err; 402 int err;
401 if ( ((64*size) %len) != 0) 403 if (((64 * size) % len) != 0)
402 continue; 404 continue;
403 405
404 err = abs(near - len); 406 err = abs(near - len);
405 407
406 // Only continue as long as we keep getting better values 408 /* Only continue as long as we keep getting better values */
407 if (err > besterr) 409 if (err > besterr)
408 break; 410 break;
409 411
@@ -414,32 +416,32 @@ static int w9966_findlen(int near, int size, int maxlen)
414 return bestlen; 416 return bestlen;
415} 417}
416 418
417// Modify capture window (if necessary) 419/* Modify capture window (if necessary)
418// and calculate downscaling 420 and calculate downscaling
419// Return -1 on error 421 Return -1 on error */
420static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor) 422static int w9966_calcscale(int size, int min, int max, int *beg, int *end, unsigned char *factor)
421{ 423{
422 int maxlen = max - min; 424 int maxlen = max - min;
423 int len = *end - *beg + 1; 425 int len = *end - *beg + 1;
424 int newlen = w9966_findlen(len, size, maxlen); 426 int newlen = w9966_findlen(len, size, maxlen);
425 int err = newlen - len; 427 int err = newlen - len;
426 428
427 // Check for bad format 429 /* Check for bad format */
428 if (newlen > maxlen || newlen < size) 430 if (newlen > maxlen || newlen < size)
429 return -1; 431 return -1;
430 432
431 // Set factor (6 bit fixed) 433 /* Set factor (6 bit fixed) */
432 *factor = (64*size) / newlen; 434 *factor = (64 * size) / newlen;
433 if (*factor == 64) 435 if (*factor == 64)
434 *factor = 0x00; // downscale is disabled 436 *factor = 0x00; /* downscale is disabled */
435 else 437 else
436 *factor |= 0x80; // set downscale-enable bit 438 *factor |= 0x80; /* set downscale-enable bit */
437 439
438 // Modify old beginning and end 440 /* Modify old beginning and end */
439 *beg -= err / 2; 441 *beg -= err / 2;
440 *end += err - (err / 2); 442 *end += err - (err / 2);
441 443
442 // Move window if outside borders 444 /* Move window if outside borders */
443 if (*beg < min) { 445 if (*beg < min) {
444 *end += min - *beg; 446 *end += min - *beg;
445 *beg += min - *beg; 447 *beg += min - *beg;
@@ -452,10 +454,10 @@ static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsig
452 return 0; 454 return 0;
453} 455}
454 456
455// Setup the cameras capture window etc. 457/* Setup the cameras capture window etc.
456// Expects a claimed pdev 458 Expects a claimed pdev
457// return -1 on error 459 return -1 on error */
458static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h) 460static int w9966_setup(struct w9966 *cam, int x1, int y1, int x2, int y2, int w, int h)
459{ 461{
460 unsigned int i; 462 unsigned int i;
461 unsigned int enh_s, enh_e; 463 unsigned int enh_s, enh_e;
@@ -469,443 +471,314 @@ static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, in
469 }; 471 };
470 472
471 473
472 if (w*h*2 > W9966_SRAMSIZE) 474 if (w * h * 2 > W9966_SRAMSIZE) {
473 {
474 DPRINTF("capture window exceeds SRAM size!.\n"); 475 DPRINTF("capture window exceeds SRAM size!.\n");
475 w = 200; h = 160; // Pick default values 476 w = 200; h = 160; /* Pick default values */
476 } 477 }
477 478
478 w &= ~0x1; 479 w &= ~0x1;
479 if (w < 2) w = 2; 480 if (w < 2)
480 if (h < 1) h = 1; 481 w = 2;
481 if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W; 482 if (h < 1)
482 if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H; 483 h = 1;
484 if (w > W9966_WND_MAX_W)
485 w = W9966_WND_MAX_W;
486 if (h > W9966_WND_MAX_H)
487 h = W9966_WND_MAX_H;
483 488
484 cam->width = w; 489 cam->width = w;
485 cam->height = h; 490 cam->height = h;
486 491
487 enh_s = 0; 492 enh_s = 0;
488 enh_e = w*h*2; 493 enh_e = w * h * 2;
489 494
490// Modify capture window if necessary and calculate downscaling 495 /* Modify capture window if necessary and calculate downscaling */
491 if ( 496 if (w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
492 w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 || 497 w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0)
493 w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0 498 return -1;
494 ) return -1; 499
495 500 DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
496 DPRINTF( 501 w, h, x1, x2, y1, y2, scale_x & ~0x80, scale_y & ~0x80);
497 "%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n", 502
498 w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80 503 /* Setup registers */
499 ); 504 regs[0x00] = 0x00; /* Set normal operation */
500 505 regs[0x01] = 0x18; /* Capture mode */
501// Setup registers 506 regs[0x02] = scale_y; /* V-scaling */
502 regs[0x00] = 0x00; // Set normal operation 507 regs[0x03] = scale_x; /* H-scaling */
503 regs[0x01] = 0x18; // Capture mode 508
504 regs[0x02] = scale_y; // V-scaling 509 /* Capture window */
505 regs[0x03] = scale_x; // H-scaling 510 regs[0x04] = (x1 & 0x0ff); /* X-start (8 low bits) */
506 511 regs[0x05] = (x1 & 0x300)>>8; /* X-start (2 high bits) */
507 // Capture window 512 regs[0x06] = (y1 & 0x0ff); /* Y-start (8 low bits) */
508 regs[0x04] = (x1 & 0x0ff); // X-start (8 low bits) 513 regs[0x07] = (y1 & 0x300)>>8; /* Y-start (2 high bits) */
509 regs[0x05] = (x1 & 0x300)>>8; // X-start (2 high bits) 514 regs[0x08] = (x2 & 0x0ff); /* X-end (8 low bits) */
510 regs[0x06] = (y1 & 0x0ff); // Y-start (8 low bits) 515 regs[0x09] = (x2 & 0x300)>>8; /* X-end (2 high bits) */
511 regs[0x07] = (y1 & 0x300)>>8; // Y-start (2 high bits) 516 regs[0x0a] = (y2 & 0x0ff); /* Y-end (8 low bits) */
512 regs[0x08] = (x2 & 0x0ff); // X-end (8 low bits) 517
513 regs[0x09] = (x2 & 0x300)>>8; // X-end (2 high bits) 518 regs[0x0c] = W9966_SRAMID; /* SRAM-banks (1x 128kb) */
514 regs[0x0a] = (y2 & 0x0ff); // Y-end (8 low bits) 519
515 520 /* Enhancement layer */
516 regs[0x0c] = W9966_SRAMID; // SRAM-banks (1x 128kb) 521 regs[0x0d] = (enh_s & 0x000ff); /* Enh. start (0-7) */
517 522 regs[0x0e] = (enh_s & 0x0ff00) >> 8; /* Enh. start (8-15) */
518 // Enhancement layer 523 regs[0x0f] = (enh_s & 0x70000) >> 16; /* Enh. start (16-17/18??) */
519 regs[0x0d] = (enh_s& 0x000ff); // Enh. start (0-7) 524 regs[0x10] = (enh_e & 0x000ff); /* Enh. end (0-7) */
520 regs[0x0e] = (enh_s& 0x0ff00)>>8; // Enh. start (8-15) 525 regs[0x11] = (enh_e & 0x0ff00) >> 8; /* Enh. end (8-15) */
521 regs[0x0f] = (enh_s& 0x70000)>>16; // Enh. start (16-17/18??) 526 regs[0x12] = (enh_e & 0x70000) >> 16; /* Enh. end (16-17/18??) */
522 regs[0x10] = (enh_e& 0x000ff); // Enh. end (0-7) 527
523 regs[0x11] = (enh_e& 0x0ff00)>>8; // Enh. end (8-15) 528 /* Misc */
524 regs[0x12] = (enh_e& 0x70000)>>16; // Enh. end (16-17/18??) 529 regs[0x13] = 0x40; /* VEE control (raw 4:2:2) */
525 530 regs[0x17] = 0x00; /* ??? */
526 // Misc 531 regs[0x18] = cam->i2c_state = 0x00; /* Serial bus */
527 regs[0x13] = 0x40; // VEE control (raw 4:2:2) 532 regs[0x19] = 0xff; /* I/O port direction control */
528 regs[0x17] = 0x00; // ??? 533 regs[0x1a] = 0xff; /* I/O port data register */
529 regs[0x18] = cam->i2c_state = 0x00; // Serial bus 534 regs[0x1b] = 0x10; /* ??? */
530 regs[0x19] = 0xff; // I/O port direction control 535
531 regs[0x1a] = 0xff; // I/O port data register 536 /* SAA7111 chip settings */
532 regs[0x1b] = 0x10; // ???
533
534 // SAA7111 chip settings
535 saa7111_regs[0x0a] = cam->brightness; 537 saa7111_regs[0x0a] = cam->brightness;
536 saa7111_regs[0x0b] = cam->contrast; 538 saa7111_regs[0x0b] = cam->contrast;
537 saa7111_regs[0x0c] = cam->color; 539 saa7111_regs[0x0c] = cam->color;
538 saa7111_regs[0x0d] = cam->hue; 540 saa7111_regs[0x0d] = cam->hue;
539 541
540// Reset (ECP-fifo & serial-bus) 542 /* Reset (ECP-fifo & serial-bus) */
541 if (w9966_wReg(cam, 0x00, 0x03) == -1) 543 if (w9966_write_reg(cam, 0x00, 0x03) == -1)
542 return -1; 544 return -1;
543 545
544// Write regs to w9966cf chip 546 /* Write regs to w9966cf chip */
545 for (i = 0; i < 0x1c; i++) 547 for (i = 0; i < 0x1c; i++)
546 if (w9966_wReg(cam, i, regs[i]) == -1) 548 if (w9966_write_reg(cam, i, regs[i]) == -1)
547 return -1; 549 return -1;
548 550
549// Write regs to saa7111 chip 551 /* Write regs to saa7111 chip */
550 for (i = 0; i < 0x20; i++) 552 for (i = 0; i < 0x20; i++)
551 if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1) 553 if (w9966_write_reg_i2c(cam, i, saa7111_regs[i]) == -1)
552 return -1; 554 return -1;
553 555
554 return 0; 556 return 0;
555} 557}
556 558
557/* 559/*
558 * Ugly and primitive i2c protocol functions 560 * Video4linux interfacing
559 */ 561 */
560 562
561// Sets the data line on the i2c bus. 563static int cam_querycap(struct file *file, void *priv,
562// Expects a claimed pdev. 564 struct v4l2_capability *vcap)
563static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
564{ 565{
565 if (state) 566 struct w9966 *cam = video_drvdata(file);
566 cam->i2c_state |= W9966_I2C_W_DATA;
567 else
568 cam->i2c_state &= ~W9966_I2C_W_DATA;
569 567
570 w9966_wReg(cam, 0x18, cam->i2c_state); 568 strlcpy(vcap->driver, cam->v4l2_dev.name, sizeof(vcap->driver));
571 udelay(5); 569 strlcpy(vcap->card, W9966_DRIVERNAME, sizeof(vcap->card));
570 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
571 vcap->version = KERNEL_VERSION(0, 33, 0);
572 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
573 return 0;
572} 574}
573 575
574// Get peripheral clock line 576static int cam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
575// Expects a claimed pdev.
576static inline int w9966_i2c_getscl(struct w9966_dev* cam)
577{ 577{
578 const unsigned char state = w9966_rReg(cam, 0x18); 578 if (vin->index > 0)
579 return ((state & W9966_I2C_R_CLOCK) > 0); 579 return -EINVAL;
580 strlcpy(vin->name, "Camera", sizeof(vin->name));
581 vin->type = V4L2_INPUT_TYPE_CAMERA;
582 vin->audioset = 0;
583 vin->tuner = 0;
584 vin->std = 0;
585 vin->status = 0;
586 return 0;
580} 587}
581 588
582// Sets the clock line on the i2c bus. 589static int cam_g_input(struct file *file, void *fh, unsigned int *inp)
583// Expects a claimed pdev. -1 on error
584static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
585{ 590{
586 unsigned long timeout; 591 *inp = 0;
587
588 if (state)
589 cam->i2c_state |= W9966_I2C_W_CLOCK;
590 else
591 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
592
593 w9966_wReg(cam, 0x18, cam->i2c_state);
594 udelay(5);
595
596 // we go to high, we also expect the peripheral to ack.
597 if (state) {
598 timeout = jiffies + 100;
599 while (!w9966_i2c_getscl(cam)) {
600 if (time_after(jiffies, timeout))
601 return -1;
602 }
603 }
604 return 0; 592 return 0;
605} 593}
606 594
607// Get peripheral data line 595static int cam_s_input(struct file *file, void *fh, unsigned int inp)
608// Expects a claimed pdev.
609static inline int w9966_i2c_getsda(struct w9966_dev* cam)
610{ 596{
611 const unsigned char state = w9966_rReg(cam, 0x18); 597 return (inp > 0) ? -EINVAL : 0;
612 return ((state & W9966_I2C_R_DATA) > 0);
613} 598}
614 599
615// Write a byte with ack to the i2c bus. 600static int cam_queryctrl(struct file *file, void *priv,
616// Expects a claimed pdev. -1 on error 601 struct v4l2_queryctrl *qc)
617static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
618{ 602{
619 int i; 603 switch (qc->id) {
620 for (i = 7; i >= 0; i--) 604 case V4L2_CID_BRIGHTNESS:
621 { 605 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
622 w9966_i2c_setsda(cam, (data >> i) & 0x01); 606 case V4L2_CID_CONTRAST:
623 607 return v4l2_ctrl_query_fill(qc, -64, 64, 1, 64);
624 if (w9966_i2c_setscl(cam, 1) == -1) 608 case V4L2_CID_SATURATION:
625 return -1; 609 return v4l2_ctrl_query_fill(qc, -64, 64, 1, 64);
626 w9966_i2c_setscl(cam, 0); 610 case V4L2_CID_HUE:
611 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
627 } 612 }
628 613 return -EINVAL;
629 w9966_i2c_setsda(cam, 1);
630
631 if (w9966_i2c_setscl(cam, 1) == -1)
632 return -1;
633 w9966_i2c_setscl(cam, 0);
634
635 return 0;
636} 614}
637 615
638// Read a data byte with ack from the i2c-bus 616static int cam_g_ctrl(struct file *file, void *priv,
639// Expects a claimed pdev. -1 on error 617 struct v4l2_control *ctrl)
640#if 0
641static int w9966_i2c_rbyte(struct w9966_dev* cam)
642{ 618{
643 unsigned char data = 0x00; 619 struct w9966 *cam = video_drvdata(file);
644 int i; 620 int ret = 0;
645
646 w9966_i2c_setsda(cam, 1);
647 621
648 for (i = 0; i < 8; i++) 622 switch (ctrl->id) {
649 { 623 case V4L2_CID_BRIGHTNESS:
650 if (w9966_i2c_setscl(cam, 1) == -1) 624 ctrl->value = cam->brightness;
651 return -1; 625 break;
652 data = data << 1; 626 case V4L2_CID_CONTRAST:
653 if (w9966_i2c_getsda(cam)) 627 ctrl->value = cam->contrast;
654 data |= 0x01; 628 break;
655 629 case V4L2_CID_SATURATION:
656 w9966_i2c_setscl(cam, 0); 630 ctrl->value = cam->color;
631 break;
632 case V4L2_CID_HUE:
633 ctrl->value = cam->hue;
634 break;
635 default:
636 ret = -EINVAL;
637 break;
657 } 638 }
658 return data; 639 return ret;
659} 640}
660#endif
661 641
662// Read a register from the i2c device. 642static int cam_s_ctrl(struct file *file, void *priv,
663// Expects claimed pdev. -1 on error 643 struct v4l2_control *ctrl)
664#if 0
665static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
666{ 644{
667 int data; 645 struct w9966 *cam = video_drvdata(file);
668 646 int ret = 0;
669 w9966_i2c_setsda(cam, 0);
670 w9966_i2c_setscl(cam, 0);
671
672 if (
673 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
674 w9966_i2c_wbyte(cam, reg) == -1
675 )
676 return -1;
677
678 w9966_i2c_setsda(cam, 1);
679 if (w9966_i2c_setscl(cam, 1) == -1)
680 return -1;
681 w9966_i2c_setsda(cam, 0);
682 w9966_i2c_setscl(cam, 0);
683 647
684 if ( 648 mutex_lock(&cam->lock);
685 w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 || 649 switch (ctrl->id) {
686 (data = w9966_i2c_rbyte(cam)) == -1 650 case V4L2_CID_BRIGHTNESS:
687 ) 651 cam->brightness = ctrl->value;
688 return -1; 652 break;
653 case V4L2_CID_CONTRAST:
654 cam->contrast = ctrl->value;
655 break;
656 case V4L2_CID_SATURATION:
657 cam->color = ctrl->value;
658 break;
659 case V4L2_CID_HUE:
660 cam->hue = ctrl->value;
661 break;
662 default:
663 ret = -EINVAL;
664 break;
665 }
689 666
690 w9966_i2c_setsda(cam, 0); 667 if (ret == 0) {
668 w9966_pdev_claim(cam);
691 669
692 if (w9966_i2c_setscl(cam, 1) == -1) 670 if (w9966_write_reg_i2c(cam, 0x0a, cam->brightness) == -1 ||
693 return -1; 671 w9966_write_reg_i2c(cam, 0x0b, cam->contrast) == -1 ||
694 w9966_i2c_setsda(cam, 1); 672 w9966_write_reg_i2c(cam, 0x0c, cam->color) == -1 ||
673 w9966_write_reg_i2c(cam, 0x0d, cam->hue) == -1) {
674 ret = -EIO;
675 }
695 676
696 return data; 677 w9966_pdev_release(cam);
678 }
679 mutex_unlock(&cam->lock);
680 return ret;
697} 681}
698#endif
699 682
700// Write a register to the i2c device. 683static int cam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
701// Expects claimed pdev. -1 on error
702static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
703{ 684{
704 w9966_i2c_setsda(cam, 0); 685 struct w9966 *cam = video_drvdata(file);
705 w9966_i2c_setscl(cam, 0); 686 struct v4l2_pix_format *pix = &fmt->fmt.pix;
706 687
707 if ( 688 pix->width = cam->width;
708 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 || 689 pix->height = cam->height;
709 w9966_i2c_wbyte(cam, reg) == -1 || 690 pix->pixelformat = V4L2_PIX_FMT_YUYV;
710 w9966_i2c_wbyte(cam, data) == -1 691 pix->field = V4L2_FIELD_NONE;
711 ) 692 pix->bytesperline = 2 * cam->width;
712 return -1; 693 pix->sizeimage = 2 * cam->width * cam->height;
713 694 /* Just a guess */
714 w9966_i2c_setsda(cam, 0); 695 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
715 if (w9966_i2c_setscl(cam, 1) == -1)
716 return -1;
717
718 w9966_i2c_setsda(cam, 1);
719
720 return 0; 696 return 0;
721} 697}
722 698
723/* 699static int cam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
724 * Video4linux interfacing 700{
725 */ 701 struct v4l2_pix_format *pix = &fmt->fmt.pix;
726 702
727static long w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg) 703 if (pix->width < 2)
728{ 704 pix->width = 2;
729 struct w9966_dev *cam = video_drvdata(file); 705 if (pix->height < 1)
730 706 pix->height = 1;
731 switch(cmd) 707 if (pix->width > W9966_WND_MAX_W)
732 { 708 pix->width = W9966_WND_MAX_W;
733 case VIDIOCGCAP: 709 if (pix->height > W9966_WND_MAX_H)
734 { 710 pix->height = W9966_WND_MAX_H;
735 static struct video_capability vcap = { 711 pix->pixelformat = V4L2_PIX_FMT_YUYV;
736 .name = W9966_DRIVERNAME, 712 pix->field = V4L2_FIELD_NONE;
737 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, 713 pix->bytesperline = 2 * pix->width;
738 .channels = 1, 714 pix->sizeimage = 2 * pix->width * pix->height;
739 .maxwidth = W9966_WND_MAX_W, 715 /* Just a guess */
740 .maxheight = W9966_WND_MAX_H, 716 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
741 .minwidth = 2, 717 return 0;
742 .minheight = 1, 718}
743 };
744 struct video_capability *cap = arg;
745 *cap = vcap;
746 return 0;
747 }
748 case VIDIOCGCHAN:
749 {
750 struct video_channel *vch = arg;
751 if(vch->channel != 0) // We only support one channel (#0)
752 return -EINVAL;
753 memset(vch,0,sizeof(*vch));
754 strcpy(vch->name, "CCD-input");
755 vch->type = VIDEO_TYPE_CAMERA;
756 return 0;
757 }
758 case VIDIOCSCHAN:
759 {
760 struct video_channel *vch = arg;
761 if(vch->channel != 0)
762 return -EINVAL;
763 return 0;
764 }
765 case VIDIOCGTUNER:
766 {
767 struct video_tuner *vtune = arg;
768 if(vtune->tuner != 0)
769 return -EINVAL;
770 strcpy(vtune->name, "no tuner");
771 vtune->rangelow = 0;
772 vtune->rangehigh = 0;
773 vtune->flags = VIDEO_TUNER_NORM;
774 vtune->mode = VIDEO_MODE_AUTO;
775 vtune->signal = 0xffff;
776 return 0;
777 }
778 case VIDIOCSTUNER:
779 {
780 struct video_tuner *vtune = arg;
781 if (vtune->tuner != 0)
782 return -EINVAL;
783 if (vtune->mode != VIDEO_MODE_AUTO)
784 return -EINVAL;
785 return 0;
786 }
787 case VIDIOCGPICT:
788 {
789 struct video_picture vpic = {
790 cam->brightness << 8, // brightness
791 (cam->hue + 128) << 8, // hue
792 cam->color << 9, // color
793 cam->contrast << 9, // contrast
794 0x8000, // whiteness
795 16, VIDEO_PALETTE_YUV422// bpp, palette format
796 };
797 struct video_picture *pic = arg;
798 *pic = vpic;
799 return 0;
800 }
801 case VIDIOCSPICT:
802 {
803 struct video_picture *vpic = arg;
804 if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV))
805 return -EINVAL;
806
807 cam->brightness = vpic->brightness >> 8;
808 cam->hue = (vpic->hue >> 8) - 128;
809 cam->color = vpic->colour >> 9;
810 cam->contrast = vpic->contrast >> 9;
811 719
812 w9966_pdev_claim(cam); 720static int cam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
721{
722 struct w9966 *cam = video_drvdata(file);
723 struct v4l2_pix_format *pix = &fmt->fmt.pix;
724 int ret = cam_try_fmt_vid_cap(file, fh, fmt);
813 725
814 if ( 726 if (ret)
815 w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 || 727 return ret;
816 w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
817 w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
818 w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
819 ) {
820 w9966_pdev_release(cam);
821 return -EIO;
822 }
823 728
824 w9966_pdev_release(cam); 729 mutex_lock(&cam->lock);
825 return 0; 730 /* Update camera regs */
826 } 731 w9966_pdev_claim(cam);
827 case VIDIOCSWIN: 732 ret = w9966_setup(cam, 0, 0, 1023, 1023, pix->width, pix->height);
828 { 733 w9966_pdev_release(cam);
829 int ret; 734 mutex_unlock(&cam->lock);
830 struct video_window *vwin = arg; 735 return ret;
831 736}
832 if (vwin->flags != 0)
833 return -EINVAL;
834 if (vwin->clipcount != 0)
835 return -EINVAL;
836 if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
837 return -EINVAL;
838 if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
839 return -EINVAL;
840
841 // Update camera regs
842 w9966_pdev_claim(cam);
843 ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
844 w9966_pdev_release(cam);
845 737
846 if (ret != 0) { 738static int cam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
847 DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n"); 739{
848 return -EIO; 740 static struct v4l2_fmtdesc formats[] = {
849 } 741 { 0, 0, 0,
742 "YUV 4:2:2", V4L2_PIX_FMT_YUYV,
743 { 0, 0, 0, 0 }
744 },
745 };
746 enum v4l2_buf_type type = fmt->type;
850 747
851 return 0; 748 if (fmt->index > 0)
852 }
853 case VIDIOCGWIN:
854 {
855 struct video_window *vwin = arg;
856 memset(vwin, 0, sizeof(*vwin));
857 vwin->width = cam->width;
858 vwin->height = cam->height;
859 return 0;
860 }
861 // Unimplemented
862 case VIDIOCCAPTURE:
863 case VIDIOCGFBUF:
864 case VIDIOCSFBUF:
865 case VIDIOCKEY:
866 case VIDIOCGFREQ:
867 case VIDIOCSFREQ:
868 case VIDIOCGAUDIO:
869 case VIDIOCSAUDIO:
870 return -EINVAL; 749 return -EINVAL;
871 default:
872 return -ENOIOCTLCMD;
873 }
874 return 0;
875}
876 750
877static long w9966_v4l_ioctl(struct file *file, 751 *fmt = formats[fmt->index];
878 unsigned int cmd, unsigned long arg) 752 fmt->type = type;
879{ 753 return 0;
880 return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl);
881} 754}
882 755
883// Capture data 756/* Capture data */
884static ssize_t w9966_v4l_read(struct file *file, char __user *buf, 757static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
885 size_t count, loff_t *ppos) 758 size_t count, loff_t *ppos)
886{ 759{
887 struct w9966_dev *cam = video_drvdata(file); 760 struct w9966 *cam = video_drvdata(file);
888 unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000 761 unsigned char addr = 0xa0; /* ECP, read, CCD-transfer, 00000 */
889 unsigned char __user *dest = (unsigned char __user *)buf; 762 unsigned char __user *dest = (unsigned char __user *)buf;
890 unsigned long dleft = count; 763 unsigned long dleft = count;
891 unsigned char *tbuf; 764 unsigned char *tbuf;
892 765
893 // Why would anyone want more than this?? 766 /* Why would anyone want more than this?? */
894 if (count > cam->width * cam->height * 2) 767 if (count > cam->width * cam->height * 2)
895 return -EINVAL; 768 return -EINVAL;
896 769
770 mutex_lock(&cam->lock);
897 w9966_pdev_claim(cam); 771 w9966_pdev_claim(cam);
898 w9966_wReg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer 772 w9966_write_reg(cam, 0x00, 0x02); /* Reset ECP-FIFO buffer */
899 w9966_wReg(cam, 0x00, 0x00); // Return to normal operation 773 w9966_write_reg(cam, 0x00, 0x00); /* Return to normal operation */
900 w9966_wReg(cam, 0x01, 0x98); // Enable capture 774 w9966_write_reg(cam, 0x01, 0x98); /* Enable capture */
901 775
902 // write special capture-addr and negotiate into data transfer 776 /* write special capture-addr and negotiate into data transfer */
903 if ( 777 if ((parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0) ||
904 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 )|| 778 (parport_write(cam->pport, &addr, 1) != 1) ||
905 (parport_write(cam->pport, &addr, 1) != 1 )|| 779 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0)) {
906 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0 )
907 ) {
908 w9966_pdev_release(cam); 780 w9966_pdev_release(cam);
781 mutex_unlock(&cam->lock);
909 return -EFAULT; 782 return -EFAULT;
910 } 783 }
911 784
@@ -915,8 +788,7 @@ static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
915 goto out; 788 goto out;
916 } 789 }
917 790
918 while(dleft > 0) 791 while (dleft > 0) {
919 {
920 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft; 792 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
921 793
922 if (parport_read(cam->pport, tbuf, tsize) < tsize) { 794 if (parport_read(cam->pport, tbuf, tsize) < tsize) {
@@ -931,43 +803,167 @@ static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
931 dleft -= tsize; 803 dleft -= tsize;
932 } 804 }
933 805
934 w9966_wReg(cam, 0x01, 0x18); // Disable capture 806 w9966_write_reg(cam, 0x01, 0x18); /* Disable capture */
935 807
936out: 808out:
937 kfree(tbuf); 809 kfree(tbuf);
938 w9966_pdev_release(cam); 810 w9966_pdev_release(cam);
811 mutex_unlock(&cam->lock);
939 812
940 return count; 813 return count;
941} 814}
942 815
816static const struct v4l2_file_operations w9966_fops = {
817 .owner = THIS_MODULE,
818 .ioctl = video_ioctl2,
819 .read = w9966_v4l_read,
820};
821
822static const struct v4l2_ioctl_ops w9966_ioctl_ops = {
823 .vidioc_querycap = cam_querycap,
824 .vidioc_g_input = cam_g_input,
825 .vidioc_s_input = cam_s_input,
826 .vidioc_enum_input = cam_enum_input,
827 .vidioc_queryctrl = cam_queryctrl,
828 .vidioc_g_ctrl = cam_g_ctrl,
829 .vidioc_s_ctrl = cam_s_ctrl,
830 .vidioc_enum_fmt_vid_cap = cam_enum_fmt_vid_cap,
831 .vidioc_g_fmt_vid_cap = cam_g_fmt_vid_cap,
832 .vidioc_s_fmt_vid_cap = cam_s_fmt_vid_cap,
833 .vidioc_try_fmt_vid_cap = cam_try_fmt_vid_cap,
834};
835
943 836
944// Called once for every parport on init 837/* Initialize camera device. Setup all internal flags, set a
838 default video mode, setup ccd-chip, register v4l device etc..
839 Also used for 'probing' of hardware.
840 -1 on error */
841static int w9966_init(struct w9966 *cam, struct parport *port)
842{
843 struct v4l2_device *v4l2_dev = &cam->v4l2_dev;
844
845 if (cam->dev_state != 0)
846 return -1;
847
848 strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name));
849
850 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
851 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
852 return -1;
853 }
854 cam->pport = port;
855 cam->brightness = 128;
856 cam->contrast = 64;
857 cam->color = 64;
858 cam->hue = 0;
859
860 /* Select requested transfer mode */
861 switch (parmode) {
862 default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */
863 case 0:
864 if (port->modes & PARPORT_MODE_ECP)
865 cam->ppmode = IEEE1284_MODE_ECP;
866 else if (port->modes & PARPORT_MODE_EPP)
867 cam->ppmode = IEEE1284_MODE_EPP;
868 else
869 cam->ppmode = IEEE1284_MODE_ECP;
870 break;
871 case 1: /* hw- or sw-ecp */
872 cam->ppmode = IEEE1284_MODE_ECP;
873 break;
874 case 2: /* hw- or sw-epp */
875 cam->ppmode = IEEE1284_MODE_EPP;
876 break;
877 }
878
879 /* Tell the parport driver that we exists */
880 cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
881 if (cam->pdev == NULL) {
882 DPRINTF("parport_register_device() failed\n");
883 return -1;
884 }
885 w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
886
887 w9966_pdev_claim(cam);
888
889 /* Setup a default capture mode */
890 if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
891 DPRINTF("w9966_setup() failed.\n");
892 return -1;
893 }
894
895 w9966_pdev_release(cam);
896
897 /* Fill in the video_device struct and register us to v4l */
898 strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name));
899 cam->vdev.v4l2_dev = v4l2_dev;
900 cam->vdev.fops = &w9966_fops;
901 cam->vdev.ioctl_ops = &w9966_ioctl_ops;
902 cam->vdev.release = video_device_release_empty;
903 video_set_drvdata(&cam->vdev, cam);
904
905 mutex_init(&cam->lock);
906
907 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
908 return -1;
909
910 w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
911
912 /* All ok */
913 v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n",
914 cam->pport->name);
915 return 0;
916}
917
918
919/* Terminate everything gracefully */
920static void w9966_term(struct w9966 *cam)
921{
922 /* Unregister from v4l */
923 if (w9966_get_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
924 video_unregister_device(&cam->vdev);
925 w9966_set_state(cam, W9966_STATE_VDEV, 0);
926 }
927
928 /* Terminate from IEEE1284 mode and release pdev block */
929 if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
930 w9966_pdev_claim(cam);
931 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
932 w9966_pdev_release(cam);
933 }
934
935 /* Unregister from parport */
936 if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
937 parport_unregister_device(cam->pdev);
938 w9966_set_state(cam, W9966_STATE_PDEV, 0);
939 }
940}
941
942
943/* Called once for every parport on init */
945static void w9966_attach(struct parport *port) 944static void w9966_attach(struct parport *port)
946{ 945{
947 int i; 946 int i;
948 947
949 for (i = 0; i < W9966_MAXCAMS; i++) 948 for (i = 0; i < W9966_MAXCAMS; i++) {
950 { 949 if (w9966_cams[i].dev_state != 0) /* Cam is already assigned */
951 if (w9966_cams[i].dev_state != 0) // Cam is already assigned
952 continue; 950 continue;
953 if ( 951 if (strcmp(pardev[i], "aggressive") == 0 || strcmp(pardev[i], port->name) == 0) {
954 strcmp(pardev[i], "aggressive") == 0 ||
955 strcmp(pardev[i], port->name) == 0
956 ) {
957 if (w9966_init(&w9966_cams[i], port) != 0) 952 if (w9966_init(&w9966_cams[i], port) != 0)
958 w9966_term(&w9966_cams[i]); 953 w9966_term(&w9966_cams[i]);
959 break; // return 954 break; /* return */
960 } 955 }
961 } 956 }
962} 957}
963 958
964// Called once for every parport on termination 959/* Called once for every parport on termination */
965static void w9966_detach(struct parport *port) 960static void w9966_detach(struct parport *port)
966{ 961{
967 int i; 962 int i;
963
968 for (i = 0; i < W9966_MAXCAMS; i++) 964 for (i = 0; i < W9966_MAXCAMS; i++)
969 if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port) 965 if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
970 w9966_term(&w9966_cams[i]); 966 w9966_term(&w9966_cams[i]);
971} 967}
972 968
973 969
@@ -977,17 +973,18 @@ static struct parport_driver w9966_ppd = {
977 .detach = w9966_detach, 973 .detach = w9966_detach,
978}; 974};
979 975
980// Module entry point 976/* Module entry point */
981static int __init w9966_mod_init(void) 977static int __init w9966_mod_init(void)
982{ 978{
983 int i; 979 int i;
980
984 for (i = 0; i < W9966_MAXCAMS; i++) 981 for (i = 0; i < W9966_MAXCAMS; i++)
985 w9966_cams[i].dev_state = 0; 982 w9966_cams[i].dev_state = 0;
986 983
987 return parport_register_driver(&w9966_ppd); 984 return parport_register_driver(&w9966_ppd);
988} 985}
989 986
990// Module cleanup 987/* Module cleanup */
991static void __exit w9966_mod_term(void) 988static void __exit w9966_mod_term(void)
992{ 989{
993 parport_unregister_driver(&w9966_ppd); 990 parport_unregister_driver(&w9966_ppd);
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index e44e4b5f3e50..bb51cfb0c647 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1153,7 +1153,7 @@ zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
1153 if (copy_from_user(&ctrl, arg, sizeof(ctrl))) 1153 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
1154 return -EFAULT; 1154 return -EFAULT;
1155 1155
1156 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) 1156 for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
1157 if (ctrl.id == s->qctrl[i].id) { 1157 if (ctrl.id == s->qctrl[i].id) {
1158 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED) 1158 if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
1159 return -EINVAL; 1159 return -EINVAL;
@@ -1163,7 +1163,9 @@ zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
1163 ctrl.value -= ctrl.value % s->qctrl[i].step; 1163 ctrl.value -= ctrl.value % s->qctrl[i].step;
1164 break; 1164 break;
1165 } 1165 }
1166 1166 }
1167 if (i == ARRAY_SIZE(s->qctrl))
1168 return -EINVAL;
1167 if ((err = s->set_ctrl(cam, &ctrl))) 1169 if ((err = s->set_ctrl(cam, &ctrl)))
1168 return err; 1170 return err;
1169 1171
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index 3a408de91b9c..0be783c203f7 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -58,7 +58,7 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
58 .idProduct = (prod), \ 58 .idProduct = (prod), \
59 .bInterfaceClass = (intclass) 59 .bInterfaceClass = (intclass)
60 60
61#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 61#if !defined CONFIG_USB_GSPCA_ZC3XX && !defined CONFIG_USB_GSPCA_ZC3XX_MODULE
62#define ZC0301_ID_TABLE \ 62#define ZC0301_ID_TABLE \
63static const struct usb_device_id zc0301_id_table[] = { \ 63static const struct usb_device_id zc0301_id_table[] = { \
64 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ 64 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index cb1de7ea197a..8997add1248e 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -33,6 +33,10 @@
33 33
34#include <media/v4l2-device.h> 34#include <media/v4l2-device.h>
35 35
36#define ZORAN_VIDMODE_PAL 0
37#define ZORAN_VIDMODE_NTSC 1
38#define ZORAN_VIDMODE_SECAM 2
39
36struct zoran_requestbuffers { 40struct zoran_requestbuffers {
37 unsigned long count; /* Number of buffers for MJPEG grabbing */ 41 unsigned long count; /* Number of buffers for MJPEG grabbing */
38 unsigned long size; /* Size PER BUFFER in bytes */ 42 unsigned long size; /* Size PER BUFFER in bytes */
@@ -48,7 +52,7 @@ struct zoran_sync {
48struct zoran_status { 52struct zoran_status {
49 int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */ 53 int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */
50 int signal; /* Returned: 1 if valid video signal detected */ 54 int signal; /* Returned: 1 if valid video signal detected */
51 int norm; /* Returned: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */ 55 int norm; /* Returned: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */
52 int color; /* Returned: 1 if color signal detected */ 56 int color; /* Returned: 1 if color signal detected */
53}; 57};
54 58
@@ -62,7 +66,7 @@ struct zoran_params {
62 /* Main control parameters */ 66 /* Main control parameters */
63 67
64 int input; /* Input channel: 0 = Composite, 1 = S-VHS */ 68 int input; /* Input channel: 0 = Composite, 1 = S-VHS */
65 int norm; /* Norm: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */ 69 int norm; /* Norm: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */
66 int decimation; /* decimation of captured video, 70 int decimation; /* decimation of captured video,
67 * enlargement of video played back. 71 * enlargement of video played back.
68 * Valid values are 1, 2, 4 or 0. 72 * Valid values are 1, 2, 4 or 0.
@@ -131,13 +135,13 @@ struct zoran_params {
131/* 135/*
132Private IOCTL to set up for displaying MJPEG 136Private IOCTL to set up for displaying MJPEG
133*/ 137*/
134#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOCPRIVATE+0, struct zoran_params) 138#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOC_PRIVATE+0, struct zoran_params)
135#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOCPRIVATE+1, struct zoran_params) 139#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOC_PRIVATE+1, struct zoran_params)
136#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOCPRIVATE+2, struct zoran_requestbuffers) 140#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOC_PRIVATE+2, struct zoran_requestbuffers)
137#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOCPRIVATE+3, int) 141#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOC_PRIVATE+3, int)
138#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOCPRIVATE+4, int) 142#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOC_PRIVATE+4, int)
139#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOCPRIVATE+5, struct zoran_sync) 143#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOC_PRIVATE+5, struct zoran_sync)
140#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOCPRIVATE+6, struct zoran_status) 144#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOC_PRIVATE+6, struct zoran_status)
141 145
142 146
143#ifdef __KERNEL__ 147#ifdef __KERNEL__
@@ -401,7 +405,7 @@ struct zoran {
401 spinlock_t spinlock; /* Spinlock */ 405 spinlock_t spinlock; /* Spinlock */
402 406
403 /* Video for Linux parameters */ 407 /* Video for Linux parameters */
404 int input; /* card's norm and input - norm=VIDEO_MODE_* */ 408 int input; /* card's norm and input */
405 v4l2_std_id norm; 409 v4l2_std_id norm;
406 410
407 /* Current buffer params */ 411 /* Current buffer params */
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index ec41303544e5..6f89d0a096ea 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -60,7 +60,7 @@
60 60
61#include <linux/spinlock.h> 61#include <linux/spinlock.h>
62 62
63#include <linux/videodev.h> 63#include <linux/videodev2.h>
64#include <media/v4l2-common.h> 64#include <media/v4l2-common.h>
65#include <media/v4l2-ioctl.h> 65#include <media/v4l2-ioctl.h>
66#include "videocodec.h" 66#include "videocodec.h"
@@ -1549,11 +1549,11 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
1549 mutex_lock(&zr->resource_lock); 1549 mutex_lock(&zr->resource_lock);
1550 1550
1551 if (zr->norm & V4L2_STD_NTSC) 1551 if (zr->norm & V4L2_STD_NTSC)
1552 bparams->norm = VIDEO_MODE_NTSC; 1552 bparams->norm = ZORAN_VIDMODE_NTSC;
1553 else if (zr->norm & V4L2_STD_PAL) 1553 else if (zr->norm & V4L2_STD_SECAM)
1554 bparams->norm = VIDEO_MODE_PAL; 1554 bparams->norm = ZORAN_VIDMODE_SECAM;
1555 else 1555 else
1556 bparams->norm = VIDEO_MODE_SECAM; 1556 bparams->norm = ZORAN_VIDMODE_PAL;
1557 1557
1558 bparams->input = zr->input; 1558 bparams->input = zr->input;
1559 1559
@@ -1789,11 +1789,11 @@ gstat_unlock_and_return:
1789 bstat->signal = 1789 bstat->signal =
1790 (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1; 1790 (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
1791 if (norm & V4L2_STD_NTSC) 1791 if (norm & V4L2_STD_NTSC)
1792 bstat->norm = VIDEO_MODE_NTSC; 1792 bstat->norm = ZORAN_VIDMODE_NTSC;
1793 else if (norm & V4L2_STD_SECAM) 1793 else if (norm & V4L2_STD_SECAM)
1794 bstat->norm = VIDEO_MODE_SECAM; 1794 bstat->norm = ZORAN_VIDMODE_SECAM;
1795 else 1795 else
1796 bstat->norm = VIDEO_MODE_PAL; 1796 bstat->norm = ZORAN_VIDMODE_PAL;
1797 1797
1798 bstat->color = 1798 bstat->color =
1799 (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1; 1799 (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 3d4bac252902..a82b5bd18d26 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -376,8 +376,8 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
376 if (*count == 0) 376 if (*count == 0)
377 *count = ZR364XX_DEF_BUFS; 377 *count = ZR364XX_DEF_BUFS;
378 378
379 while (*size * (*count) > ZR364XX_DEF_BUFS * 1024 * 1024) 379 if (*size * *count > ZR364XX_DEF_BUFS * 1024 * 1024)
380 (*count)--; 380 *count = (ZR364XX_DEF_BUFS * 1024 * 1024) / *size;
381 381
382 return 0; 382 return 0;
383} 383}
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 7696a664f8a5..5589616082e7 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -49,6 +49,8 @@ source "drivers/staging/go7007/Kconfig"
49 49
50source "drivers/staging/cx25821/Kconfig" 50source "drivers/staging/cx25821/Kconfig"
51 51
52source "drivers/staging/tm6000/Kconfig"
53
52source "drivers/staging/usbip/Kconfig" 54source "drivers/staging/usbip/Kconfig"
53 55
54source "drivers/staging/winbond/Kconfig" 56source "drivers/staging/winbond/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index ea2e70e2fed4..ec45d4bb8c11 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_ET131X) += et131x/
7obj-$(CONFIG_SLICOSS) += slicoss/ 7obj-$(CONFIG_SLICOSS) += slicoss/
8obj-$(CONFIG_VIDEO_GO7007) += go7007/ 8obj-$(CONFIG_VIDEO_GO7007) += go7007/
9obj-$(CONFIG_VIDEO_CX25821) += cx25821/ 9obj-$(CONFIG_VIDEO_CX25821) += cx25821/
10obj-$(CONFIG_VIDEO_TM6000) += tm6000/
10obj-$(CONFIG_USB_IP_COMMON) += usbip/ 11obj-$(CONFIG_USB_IP_COMMON) += usbip/
11obj-$(CONFIG_W35UND) += winbond/ 12obj-$(CONFIG_W35UND) += winbond/
12obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 13obj-$(CONFIG_PRISM2_USB) += wlan-ng/
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index 061add30ba8a..1798975a69bd 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -29,7 +29,7 @@
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31 31
32#include <asm/delay.h> 32#include <linux/delay.h>
33#include <sound/core.h> 33#include <sound/core.h>
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
@@ -42,10 +42,10 @@
42 42
43#define AUDIO_SRAM_CHANNEL SRAM_CH08 43#define AUDIO_SRAM_CHANNEL SRAM_CH08
44 44
45#define dprintk(level,fmt, arg...) if (debug >= level) \ 45#define dprintk(level, fmt, arg...) if (debug >= level) \
46 printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg) 46 printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
47 47
48#define dprintk_core(level,fmt, arg...) if (debug >= level) \ 48#define dprintk_core(level, fmt, arg...) if (debug >= level) \
49 printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg) 49 printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
50 50
51/**************************************************************************** 51/****************************************************************************
@@ -81,7 +81,6 @@ struct cx25821_audio_dev {
81 81
82 struct snd_pcm_substream *substream; 82 struct snd_pcm_substream *substream;
83}; 83};
84typedef struct cx25821_audio_dev snd_cx25821_card_t;
85 84
86 85
87/**************************************************************************** 86/****************************************************************************
@@ -90,7 +89,7 @@ typedef struct cx25821_audio_dev snd_cx25821_card_t;
90 89
91static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 90static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
92static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 91static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
93static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 1 }; 92static int enable[SNDRV_CARDS] = { 1, [1 ... (SNDRV_CARDS - 1)] = 1 };
94 93
95module_param_array(enable, bool, NULL, 0444); 94module_param_array(enable, bool, NULL, 0444);
96MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled."); 95MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
@@ -105,7 +104,7 @@ MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
105MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards"); 104MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
106MODULE_AUTHOR("Hiep Huynh"); 105MODULE_AUTHOR("Hiep Huynh");
107MODULE_LICENSE("GPL"); 106MODULE_LICENSE("GPL");
108MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); //"{{Conexant,23881}," 107MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); /* "{{Conexant,23881}," */
109 108
110static unsigned int debug; 109static unsigned int debug;
111module_param(debug, int, 0644); 110module_param(debug, int, 0644);
@@ -135,7 +134,7 @@ MODULE_PARM_DESC(debug, "enable debug messages");
135 * BOARD Specific: Sets audio DMA 134 * BOARD Specific: Sets audio DMA
136 */ 135 */
137 136
138static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip) 137static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip)
139{ 138{
140 struct cx25821_buffer *buf = chip->buf; 139 struct cx25821_buffer *buf = chip->buf;
141 struct cx25821_dev *dev = chip->dev; 140 struct cx25821_dev *dev = chip->dev;
@@ -143,7 +142,7 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
143 &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]; 142 &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
144 u32 tmp = 0; 143 u32 tmp = 0;
145 144
146 // enable output on the GPIO 0 for the MCLK ADC (Audio) 145 /* enable output on the GPIO 0 for the MCLK ADC (Audio) */
147 cx25821_set_gpiopin_direction(chip->dev, 0, 0); 146 cx25821_set_gpiopin_direction(chip->dev, 0, 0);
148 147
149 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ 148 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
@@ -158,18 +157,23 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
158 cx_write(AUD_A_LNGTH, buf->bpl); 157 cx_write(AUD_A_LNGTH, buf->bpl);
159 158
160 /* reset counter */ 159 /* reset counter */
161 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); //GP_COUNT_CONTROL_RESET = 0x3 160 /* GP_COUNT_CONTROL_RESET = 0x3 */
161 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
162 atomic_set(&chip->count, 0); 162 atomic_set(&chip->count, 0);
163 163
164 //Set the input mode to 16-bit 164 /* Set the input mode to 16-bit */
165 tmp = cx_read(AUD_A_CFG); 165 tmp = cx_read(AUD_A_CFG);
166 cx_write(AUD_A_CFG, 166 cx_write(AUD_A_CFG,
167 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | 167 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
168 FLD_AUD_CLK_ENABLE); 168 FLD_AUD_CLK_ENABLE);
169 169
170 //printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d " 170 /* printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line,"
171 // "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1, 171 "cmds_start(0x%x)= %d lines/FIFO, %d periods, "
172 // chip->num_periods, buf->bpl * chip->num_periods); 172 "%d byte buffer\n", buf->bpl,
173 audio_ch->cmds_start,
174 cx_read(audio_ch->cmds_start + 12)>>1,
175 chip->num_periods, buf->bpl *chip->num_periods);
176 */
173 177
174 /* Enables corresponding bits at AUD_INT_STAT */ 178 /* Enables corresponding bits at AUD_INT_STAT */
175 cx_write(AUD_A_INT_MSK, 179 cx_write(AUD_A_INT_MSK,
@@ -182,7 +186,7 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
182 /* enable audio irqs */ 186 /* enable audio irqs */
183 cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT); 187 cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
184 188
185 // Turn on audio downstream fifo and risc enable 0x101 189 /* Turn on audio downstream fifo and risc enable 0x101 */
186 tmp = cx_read(AUD_INT_DMA_CTL); 190 tmp = cx_read(AUD_INT_DMA_CTL);
187 cx_set(AUD_INT_DMA_CTL, 191 cx_set(AUD_INT_DMA_CTL,
188 tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); 192 tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
@@ -194,7 +198,7 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
194/* 198/*
195 * BOARD Specific: Resets audio DMA 199 * BOARD Specific: Resets audio DMA
196 */ 200 */
197static int _cx25821_stop_audio_dma(snd_cx25821_card_t * chip) 201static int _cx25821_stop_audio_dma(struct cx25821_audio_dev *chip)
198{ 202{
199 struct cx25821_dev *dev = chip->dev; 203 struct cx25821_dev *dev = chip->dev;
200 204
@@ -232,13 +236,13 @@ static char *cx25821_aud_irqs[32] = {
232/* 236/*
233 * BOARD Specific: Threats IRQ audio specific calls 237 * BOARD Specific: Threats IRQ audio specific calls
234 */ 238 */
235static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask) 239static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status,
240 u32 mask)
236{ 241{
237 struct cx25821_dev *dev = chip->dev; 242 struct cx25821_dev *dev = chip->dev;
238 243
239 if (0 == (status & mask)) { 244 if (0 == (status & mask))
240 return; 245 return;
241 }
242 246
243 cx_write(AUD_A_INT_STAT, status); 247 cx_write(AUD_A_INT_STAT, status);
244 if (debug > 1 || (status & mask & ~0xff)) 248 if (debug > 1 || (status & mask & ~0xff))
@@ -277,7 +281,7 @@ static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask)
277 */ 281 */
278static irqreturn_t cx25821_irq(int irq, void *dev_id) 282static irqreturn_t cx25821_irq(int irq, void *dev_id)
279{ 283{
280 snd_cx25821_card_t *chip = dev_id; 284 struct cx25821_audio_dev *chip = dev_id;
281 struct cx25821_dev *dev = chip->dev; 285 struct cx25821_dev *dev = chip->dev;
282 u32 status, pci_status; 286 u32 status, pci_status;
283 u32 audint_status, audint_mask; 287 u32 audint_status, audint_mask;
@@ -318,11 +322,11 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id)
318 if (handled) 322 if (handled)
319 cx_write(PCI_INT_STAT, pci_status); 323 cx_write(PCI_INT_STAT, pci_status);
320 324
321 out: 325out:
322 return IRQ_RETVAL(handled); 326 return IRQ_RETVAL(handled);
323} 327}
324 328
325static int dsp_buffer_free(snd_cx25821_card_t * chip) 329static int dsp_buffer_free(struct cx25821_audio_dev *chip)
326{ 330{
327 BUG_ON(!chip->dma_size); 331 BUG_ON(!chip->dma_size);
328 332
@@ -363,7 +367,8 @@ static struct snd_pcm_hardware snd_cx25821_digital_hw = {
363 .period_bytes_max = DEFAULT_FIFO_SIZE / 3, 367 .period_bytes_max = DEFAULT_FIFO_SIZE / 3,
364 .periods_min = 1, 368 .periods_min = 1,
365 .periods_max = AUDIO_LINE_SIZE, 369 .periods_max = AUDIO_LINE_SIZE,
366 .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), //128*128 = 16384 = 1024 * 16 370 /* 128 * 128 = 16384 = 1024 * 16 */
371 .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE),
367}; 372};
368 373
369/* 374/*
@@ -371,7 +376,7 @@ static struct snd_pcm_hardware snd_cx25821_digital_hw = {
371 */ 376 */
372static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream) 377static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
373{ 378{
374 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream); 379 struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
375 struct snd_pcm_runtime *runtime = substream->runtime; 380 struct snd_pcm_runtime *runtime = substream->runtime;
376 int err; 381 int err;
377 unsigned int bpl = 0; 382 unsigned int bpl = 0;
@@ -393,18 +398,19 @@ static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
393 398
394 if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size != 399 if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size !=
395 DEFAULT_FIFO_SIZE) { 400 DEFAULT_FIFO_SIZE) {
396 bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; //since there are 3 audio Clusters 401 /* since there are 3 audio Clusters */
402 bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3;
397 bpl &= ~7; /* must be multiple of 8 */ 403 bpl &= ~7; /* must be multiple of 8 */
398 404
399 if (bpl > AUDIO_LINE_SIZE) { 405 if (bpl > AUDIO_LINE_SIZE)
400 bpl = AUDIO_LINE_SIZE; 406 bpl = AUDIO_LINE_SIZE;
401 } 407
402 runtime->hw.period_bytes_min = bpl; 408 runtime->hw.period_bytes_min = bpl;
403 runtime->hw.period_bytes_max = bpl; 409 runtime->hw.period_bytes_max = bpl;
404 } 410 }
405 411
406 return 0; 412 return 0;
407 _error: 413_error:
408 dprintk(1, "Error opening PCM!\n"); 414 dprintk(1, "Error opening PCM!\n");
409 return err; 415 return err;
410} 416}
@@ -423,7 +429,7 @@ static int snd_cx25821_close(struct snd_pcm_substream *substream)
423static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, 429static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
424 struct snd_pcm_hw_params *hw_params) 430 struct snd_pcm_hw_params *hw_params)
425{ 431{
426 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream); 432 struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
427 struct videobuf_dmabuf *dma; 433 struct videobuf_dmabuf *dma;
428 434
429 struct cx25821_buffer *buf; 435 struct cx25821_buffer *buf;
@@ -445,9 +451,8 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
445 if (NULL == buf) 451 if (NULL == buf)
446 return -ENOMEM; 452 return -ENOMEM;
447 453
448 if (chip->period_size > AUDIO_LINE_SIZE) { 454 if (chip->period_size > AUDIO_LINE_SIZE)
449 chip->period_size = AUDIO_LINE_SIZE; 455 chip->period_size = AUDIO_LINE_SIZE;
450 }
451 456
452 buf->vb.memory = V4L2_MEMORY_MMAP; 457 buf->vb.memory = V4L2_MEMORY_MMAP;
453 buf->vb.field = V4L2_FIELD_NONE; 458 buf->vb.field = V4L2_FIELD_NONE;
@@ -474,7 +479,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
474 buf->vb.width, buf->vb.height, 1); 479 buf->vb.width, buf->vb.height, 1);
475 if (ret < 0) { 480 if (ret < 0) {
476 printk(KERN_INFO 481 printk(KERN_INFO
477 "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n"); 482 "DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
478 goto error; 483 goto error;
479 } 484 }
480 485
@@ -494,7 +499,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
494 499
495 return 0; 500 return 0;
496 501
497 error: 502error:
498 kfree(buf); 503 kfree(buf);
499 return ret; 504 return ret;
500} 505}
@@ -504,7 +509,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
504 */ 509 */
505static int snd_cx25821_hw_free(struct snd_pcm_substream *substream) 510static int snd_cx25821_hw_free(struct snd_pcm_substream *substream)
506{ 511{
507 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream); 512 struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
508 513
509 if (substream->runtime->dma_area) { 514 if (substream->runtime->dma_area) {
510 dsp_buffer_free(chip); 515 dsp_buffer_free(chip);
@@ -528,7 +533,7 @@ static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
528static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream, 533static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
529 int cmd) 534 int cmd)
530{ 535{
531 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream); 536 struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
532 int err = 0; 537 int err = 0;
533 538
534 /* Local interrupts are already disabled by ALSA */ 539 /* Local interrupts are already disabled by ALSA */
@@ -557,7 +562,7 @@ static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
557static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream 562static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream
558 *substream) 563 *substream)
559{ 564{
560 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream); 565 struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
561 struct snd_pcm_runtime *runtime = substream->runtime; 566 struct snd_pcm_runtime *runtime = substream->runtime;
562 u16 count; 567 u16 count;
563 568
@@ -593,10 +598,11 @@ static struct snd_pcm_ops snd_cx25821_pcm_ops = {
593}; 598};
594 599
595/* 600/*
596 * ALSA create a PCM device: Called when initializing the board. Sets up the name and hooks up 601 * ALSA create a PCM device: Called when initializing the board.
597 * the callbacks 602 * Sets up the name and hooks up the callbacks
598 */ 603 */
599static int snd_cx25821_pcm(snd_cx25821_card_t * chip, int device, char *name) 604static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
605 char *name)
600{ 606{
601 struct snd_pcm *pcm; 607 struct snd_pcm *pcm;
602 int err; 608 int err;
@@ -636,7 +642,7 @@ MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
636 * from the file. 642 * from the file.
637 */ 643 */
638/* 644/*
639static int snd_cx25821_free(snd_cx25821_card_t *chip) 645static int snd_cx25821_free(struct cx25821_audio_dev *chip)
640{ 646{
641 if (chip->irq >= 0) 647 if (chip->irq >= 0)
642 free_irq(chip->irq, chip); 648 free_irq(chip->irq, chip);
@@ -653,9 +659,9 @@ static int snd_cx25821_free(snd_cx25821_card_t *chip)
653 */ 659 */
654static void snd_cx25821_dev_free(struct snd_card *card) 660static void snd_cx25821_dev_free(struct snd_card *card)
655{ 661{
656 snd_cx25821_card_t *chip = card->private_data; 662 struct cx25821_audio_dev *chip = card->private_data;
657 663
658 //snd_cx25821_free(chip); 664 /* snd_cx25821_free(chip); */
659 snd_card_free(chip->card); 665 snd_card_free(chip->card);
660} 666}
661 667
@@ -665,23 +671,23 @@ static void snd_cx25821_dev_free(struct snd_card *card)
665static int cx25821_audio_initdev(struct cx25821_dev *dev) 671static int cx25821_audio_initdev(struct cx25821_dev *dev)
666{ 672{
667 struct snd_card *card; 673 struct snd_card *card;
668 snd_cx25821_card_t *chip; 674 struct cx25821_audio_dev *chip;
669 int err; 675 int err;
670 676
671 if (devno >= SNDRV_CARDS) { 677 if (devno >= SNDRV_CARDS) {
672 printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n", 678 printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
673 __func__); 679 __func__);
674 return (-ENODEV); 680 return -ENODEV;
675 } 681 }
676 682
677 if (!enable[devno]) { 683 if (!enable[devno]) {
678 ++devno; 684 ++devno;
679 printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__); 685 printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
680 return (-ENOENT); 686 return -ENOENT;
681 } 687 }
682 688
683 err = snd_card_create(index[devno], id[devno], THIS_MODULE, 689 err = snd_card_create(index[devno], id[devno], THIS_MODULE,
684 sizeof(snd_cx25821_card_t), &card); 690 sizeof(struct cx25821_audio_dev), &card);
685 if (err < 0) { 691 if (err < 0) {
686 printk(KERN_INFO 692 printk(KERN_INFO
687 "DEBUG ERROR: cannot create snd_card_new in %s\n", 693 "DEBUG ERROR: cannot create snd_card_new in %s\n",
@@ -693,7 +699,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
693 699
694 /* Card "creation" */ 700 /* Card "creation" */
695 card->private_free = snd_cx25821_dev_free; 701 card->private_free = snd_cx25821_dev_free;
696 chip = (snd_cx25821_card_t *) card->private_data; 702 chip = (struct cx25821_audio_dev *) card->private_data;
697 spin_lock_init(&chip->reg_lock); 703 spin_lock_init(&chip->reg_lock);
698 704
699 chip->dev = dev; 705 chip->dev = dev;
@@ -712,7 +718,8 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
712 goto error; 718 goto error;
713 } 719 }
714 720
715 if ((err = snd_cx25821_pcm(chip, 0, "cx25821 Digital")) < 0) { 721 err = snd_cx25821_pcm(chip, 0, "cx25821 Digital");
722 if (err < 0) {
716 printk(KERN_INFO 723 printk(KERN_INFO
717 "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n", 724 "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
718 __func__); 725 __func__);
@@ -741,7 +748,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
741 devno++; 748 devno++;
742 return 0; 749 return 0;
743 750
744 error: 751error:
745 snd_card_free(card); 752 snd_card_free(card);
746 return err; 753 return err;
747} 754}
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
index 11c56bdb0ceb..6a4e8720b478 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -33,7 +33,7 @@
33#include <linux/fcntl.h> 33#include <linux/fcntl.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <asm/uaccess.h> 36#include <linux/uaccess.h>
37 37
38MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); 38MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
39MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); 39MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
@@ -62,9 +62,8 @@ int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
62 cdt = ch->cdt; 62 cdt = ch->cdt;
63 lines = ch->fifo_size / bpl; 63 lines = ch->fifo_size / bpl;
64 64
65 if (lines > 3) { 65 if (lines > 3)
66 lines = 3; 66 lines = 3;
67 }
68 67
69 BUG_ON(lines < 2); 68 BUG_ON(lines < 2);
70 69
@@ -84,7 +83,7 @@ int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
84 cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW); 83 cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
85 cx_write(ch->cmds_start + 16, ch->ctrl_start); 84 cx_write(ch->cmds_start + 16, ch->ctrl_start);
86 85
87 //IQ size 86 /* IQ size */
88 cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW); 87 cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
89 88
90 for (i = 24; i < 80; i += 4) 89 for (i = 24; i < 80; i += 4)
@@ -100,7 +99,7 @@ int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
100} 99}
101 100
102static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev, 101static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
103 __le32 * rp, 102 __le32 *rp,
104 dma_addr_t databuf_phys_addr, 103 dma_addr_t databuf_phys_addr,
105 unsigned int bpl, 104 unsigned int bpl,
106 int fifo_enable) 105 int fifo_enable)
@@ -116,8 +115,10 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
116 *(rp++) = cpu_to_le32(databuf_phys_addr + offset); 115 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
117 *(rp++) = cpu_to_le32(0); /* bits 63-32 */ 116 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
118 117
119 // Check if we need to enable the FIFO after the first 3 lines 118 /* Check if we need to enable the FIFO
120 // For the upstream audio channel, the risc engine will enable the FIFO. 119 * after the first 3 lines.
120 * For the upstream audio channel,
121 * the risc engine will enable the FIFO */
121 if (fifo_enable && line == 2) { 122 if (fifo_enable && line == 2) {
122 *(rp++) = RISC_WRITECR; 123 *(rp++) = RISC_WRITECR;
123 *(rp++) = sram_ch->dma_ctl; 124 *(rp++) = sram_ch->dma_ctl;
@@ -160,7 +161,7 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
160 risc_flag = RISC_CNT_INC; 161 risc_flag = RISC_CNT_INC;
161 } 162 }
162 163
163 //Calculate physical jump address 164 /* Calculate physical jump address */
164 if ((frame + 1) == NUM_AUDIO_FRAMES) { 165 if ((frame + 1) == NUM_AUDIO_FRAMES) {
165 risc_phys_jump_addr = 166 risc_phys_jump_addr =
166 dev->_risc_phys_start_addr + 167 dev->_risc_phys_start_addr +
@@ -179,17 +180,17 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
179 fifo_enable); 180 fifo_enable);
180 181
181 if (USE_RISC_NOOP_AUDIO) { 182 if (USE_RISC_NOOP_AUDIO) {
182 for (i = 0; i < NUM_NO_OPS; i++) { 183 for (i = 0; i < NUM_NO_OPS; i++)
183 *(rp++) = cpu_to_le32(RISC_NOOP); 184 *(rp++) = cpu_to_le32(RISC_NOOP);
184 }
185 } 185 }
186 186
187 // Loop to (Nth)FrameRISC or to Start of Risc program & generate IRQ 187 /* Loop to (Nth)FrameRISC or to Start of Risc program &
188 * generate IRQ */
188 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); 189 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
189 *(rp++) = cpu_to_le32(risc_phys_jump_addr); 190 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
190 *(rp++) = cpu_to_le32(0); 191 *(rp++) = cpu_to_le32(0);
191 192
192 //Recalculate virtual address based on frame index 193 /* Recalculate virtual address based on frame index */
193 rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 + 194 rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
194 (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4); 195 (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
195 } 196 }
@@ -220,19 +221,19 @@ void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
220 u32 tmp = 0; 221 u32 tmp = 0;
221 222
222 if (!dev->_audio_is_running) { 223 if (!dev->_audio_is_running) {
223 printk 224 printk(KERN_DEBUG
224 ("cx25821: No audio file is currently running so return!\n"); 225 "cx25821: No audio file is currently running so return!\n");
225 return; 226 return;
226 } 227 }
227 //Disable RISC interrupts 228 /* Disable RISC interrupts */
228 cx_write(sram_ch->int_msk, 0); 229 cx_write(sram_ch->int_msk, 0);
229 230
230 //Turn OFF risc and fifo enable in AUD_DMA_CNTRL 231 /* Turn OFF risc and fifo enable in AUD_DMA_CNTRL */
231 tmp = cx_read(sram_ch->dma_ctl); 232 tmp = cx_read(sram_ch->dma_ctl);
232 cx_write(sram_ch->dma_ctl, 233 cx_write(sram_ch->dma_ctl,
233 tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en)); 234 tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en));
234 235
235 //Clear data buffer memory 236 /* Clear data buffer memory */
236 if (dev->_audiodata_buf_virt_addr) 237 if (dev->_audiodata_buf_virt_addr)
237 memset(dev->_audiodata_buf_virt_addr, 0, 238 memset(dev->_audiodata_buf_virt_addr, 0,
238 dev->_audiodata_buf_size); 239 dev->_audiodata_buf_size);
@@ -253,9 +254,8 @@ void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
253 254
254void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev) 255void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
255{ 256{
256 if (dev->_audio_is_running) { 257 if (dev->_audio_is_running)
257 cx25821_stop_upstream_audio(dev); 258 cx25821_stop_upstream_audio(dev);
258 }
259 259
260 cx25821_free_memory_audio(dev); 260 cx25821_free_memory_audio(dev);
261} 261}
@@ -282,7 +282,7 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
282 282
283 if (IS_ERR(myfile)) { 283 if (IS_ERR(myfile)) {
284 const int open_errno = -PTR_ERR(myfile); 284 const int open_errno = -PTR_ERR(myfile);
285 printk("%s(): ERROR opening file(%s) with errno = %d! \n", 285 printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
286 __func__, dev->_audiofilename, open_errno); 286 __func__, dev->_audiofilename, open_errno);
287 return PTR_ERR(myfile); 287 return PTR_ERR(myfile);
288 } else { 288 } else {
@@ -294,7 +294,7 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
294 } 294 }
295 295
296 if (!myfile->f_op->read) { 296 if (!myfile->f_op->read) {
297 printk("%s: File has no READ operations registered! \n", 297 printk("%s: File has no READ operations registered!\n",
298 __func__); 298 __func__);
299 filp_close(myfile, NULL); 299 filp_close(myfile, NULL);
300 return -EIO; 300 return -EIO;
@@ -347,7 +347,7 @@ static void cx25821_audioups_handler(struct work_struct *work)
347 container_of(work, struct cx25821_dev, _audio_work_entry); 347 container_of(work, struct cx25821_dev, _audio_work_entry);
348 348
349 if (!dev) { 349 if (!dev) {
350 printk("ERROR %s(): since container_of(work_struct) FAILED! \n", 350 printk(KERN_ERR "ERROR %s(): since container_of(work_struct) FAILED!\n",
351 __func__); 351 __func__);
352 return; 352 return;
353 } 353 }
@@ -373,19 +373,19 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
373 373
374 if (IS_ERR(myfile)) { 374 if (IS_ERR(myfile)) {
375 const int open_errno = -PTR_ERR(myfile); 375 const int open_errno = -PTR_ERR(myfile);
376 printk("%s(): ERROR opening file(%s) with errno = %d! \n", 376 printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
377 __func__, dev->_audiofilename, open_errno); 377 __func__, dev->_audiofilename, open_errno);
378 return PTR_ERR(myfile); 378 return PTR_ERR(myfile);
379 } else { 379 } else {
380 if (!(myfile->f_op)) { 380 if (!(myfile->f_op)) {
381 printk("%s: File has no file operations registered! \n", 381 printk("%s: File has no file operations registered!\n",
382 __func__); 382 __func__);
383 filp_close(myfile, NULL); 383 filp_close(myfile, NULL);
384 return -EIO; 384 return -EIO;
385 } 385 }
386 386
387 if (!myfile->f_op->read) { 387 if (!myfile->f_op->read) {
388 printk("%s: File has no READ operations registered! \n", 388 printk("%s: File has no READ operations registered!\n",
389 __func__); 389 __func__);
390 filp_close(myfile, NULL); 390 filp_close(myfile, NULL);
391 return -EIO; 391 return -EIO;
@@ -421,13 +421,11 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
421 } 421 }
422 } 422 }
423 423
424 if (i > 0) { 424 if (i > 0)
425 dev->_audioframe_count++; 425 dev->_audioframe_count++;
426 }
427 426
428 if (vfs_read_retval < line_size) { 427 if (vfs_read_retval < line_size)
429 break; 428 break;
430 }
431 } 429 }
432 430
433 dev->_audiofile_status = 431 dev->_audiofile_status =
@@ -460,14 +458,14 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
460 dev->_audiorisc_size = dev->audio_upstream_riscbuf_size; 458 dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
461 459
462 if (!dev->_risc_virt_addr) { 460 if (!dev->_risc_virt_addr) {
463 printk 461 printk(KERN_DEBUG
464 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n"); 462 "cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
465 return -ENOMEM; 463 return -ENOMEM;
466 } 464 }
467 //Clear out memory at address 465 /* Clear out memory at address */
468 memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size); 466 memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
469 467
470 //For Audio Data buffer allocation 468 /* For Audio Data buffer allocation */
471 dev->_audiodata_buf_virt_addr = 469 dev->_audiodata_buf_virt_addr =
472 pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size, 470 pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size,
473 &data_dma_addr); 471 &data_dma_addr);
@@ -475,30 +473,30 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
475 dev->_audiodata_buf_size = dev->audio_upstream_databuf_size; 473 dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
476 474
477 if (!dev->_audiodata_buf_virt_addr) { 475 if (!dev->_audiodata_buf_virt_addr) {
478 printk 476 printk(KERN_DEBUG
479 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning. \n"); 477 "cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning.\n");
480 return -ENOMEM; 478 return -ENOMEM;
481 } 479 }
482 //Clear out memory at address 480 /* Clear out memory at address */
483 memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size); 481 memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size);
484 482
485 ret = cx25821_openfile_audio(dev, sram_ch); 483 ret = cx25821_openfile_audio(dev, sram_ch);
486 if (ret < 0) 484 if (ret < 0)
487 return ret; 485 return ret;
488 486
489 //Creating RISC programs 487 /* Creating RISC programs */
490 ret = 488 ret =
491 cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl, 489 cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
492 dev->_audio_lines_count); 490 dev->_audio_lines_count);
493 if (ret < 0) { 491 if (ret < 0) {
494 printk(KERN_DEBUG 492 printk(KERN_DEBUG
495 "cx25821 ERROR creating audio upstream RISC programs! \n"); 493 "cx25821 ERROR creating audio upstream RISC programs!\n");
496 goto error; 494 goto error;
497 } 495 }
498 496
499 return 0; 497 return 0;
500 498
501 error: 499error:
502 return ret; 500 return ret;
503} 501}
504 502
@@ -512,22 +510,22 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
512 __le32 *rp; 510 __le32 *rp;
513 511
514 if (status & FLD_AUD_SRC_RISCI1) { 512 if (status & FLD_AUD_SRC_RISCI1) {
515 //Get interrupt_index of the program that interrupted 513 /* Get interrupt_index of the program that interrupted */
516 u32 prog_cnt = cx_read(channel->gpcnt); 514 u32 prog_cnt = cx_read(channel->gpcnt);
517 515
518 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers 516 /* Since we've identified our IRQ, clear our bits from the
517 * interrupt mask and interrupt status registers */
519 cx_write(channel->int_msk, 0); 518 cx_write(channel->int_msk, 0);
520 cx_write(channel->int_stat, cx_read(channel->int_stat)); 519 cx_write(channel->int_stat, cx_read(channel->int_stat));
521 520
522 spin_lock(&dev->slock); 521 spin_lock(&dev->slock);
523 522
524 while (prog_cnt != dev->_last_index_irq) { 523 while (prog_cnt != dev->_last_index_irq) {
525 //Update _last_index_irq 524 /* Update _last_index_irq */
526 if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) { 525 if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1))
527 dev->_last_index_irq++; 526 dev->_last_index_irq++;
528 } else { 527 else
529 dev->_last_index_irq = 0; 528 dev->_last_index_irq = 0;
530 }
531 529
532 dev->_audioframe_index = dev->_last_index_irq; 530 dev->_audioframe_index = dev->_last_index_irq;
533 531
@@ -559,7 +557,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
559 cpu_to_le32(RISC_NOOP); 557 cpu_to_le32(RISC_NOOP);
560 } 558 }
561 } 559 }
562 // Jump to 2nd Audio Frame 560 /* Jump to 2nd Audio Frame */
563 *(rp++) = 561 *(rp++) =
564 cpu_to_le32(RISC_JUMP | RISC_IRQ1 | 562 cpu_to_le32(RISC_JUMP | RISC_IRQ1 |
565 RISC_CNT_RESET); 563 RISC_CNT_RESET);
@@ -582,7 +580,8 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
582 printk("%s: Audio Received OpCode Error Interrupt!\n", 580 printk("%s: Audio Received OpCode Error Interrupt!\n",
583 __func__); 581 __func__);
584 582
585 // Read and write back the interrupt status register to clear our bits 583 /* Read and write back the interrupt status register to clear
584 * our bits */
586 cx_write(channel->int_stat, cx_read(channel->int_stat)); 585 cx_write(channel->int_stat, cx_read(channel->int_stat));
587 } 586 }
588 587
@@ -591,7 +590,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
591 dev->_audioframe_count); 590 dev->_audioframe_count);
592 return -1; 591 return -1;
593 } 592 }
594 //ElSE, set the interrupt mask register, re-enable irq. 593 /* ElSE, set the interrupt mask register, re-enable irq. */
595 int_msk_tmp = cx_read(channel->int_msk); 594 int_msk_tmp = cx_read(channel->int_msk);
596 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); 595 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
597 596
@@ -613,7 +612,7 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
613 msk_stat = cx_read(sram_ch->int_mstat); 612 msk_stat = cx_read(sram_ch->int_mstat);
614 audio_status = cx_read(sram_ch->int_stat); 613 audio_status = cx_read(sram_ch->int_stat);
615 614
616 // Only deal with our interrupt 615 /* Only deal with our interrupt */
617 if (audio_status) { 616 if (audio_status) {
618 handled = 617 handled =
619 cx25821_audio_upstream_irq(dev, 618 cx25821_audio_upstream_irq(dev,
@@ -622,11 +621,10 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
622 audio_status); 621 audio_status);
623 } 622 }
624 623
625 if (handled < 0) { 624 if (handled < 0)
626 cx25821_stop_upstream_audio(dev); 625 cx25821_stop_upstream_audio(dev);
627 } else { 626 else
628 handled += handled; 627 handled += handled;
629 }
630 628
631 return IRQ_RETVAL(handled); 629 return IRQ_RETVAL(handled);
632} 630}
@@ -638,13 +636,14 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
638 u32 tmp; 636 u32 tmp;
639 637
640 do { 638 do {
641 //Wait 10 microsecond before checking to see if the FIFO is turned ON. 639 /* Wait 10 microsecond before checking to see if the FIFO is
640 * turned ON. */
642 udelay(10); 641 udelay(10);
643 642
644 tmp = cx_read(sram_ch->dma_ctl); 643 tmp = cx_read(sram_ch->dma_ctl);
645 644
646 if (count++ > 1000) //10 millisecond timeout 645 /* 10 millisecond timeout */
647 { 646 if (count++ > 1000) {
648 printk 647 printk
649 ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n", 648 ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
650 __func__); 649 __func__);
@@ -661,31 +660,34 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
661 u32 tmp = 0; 660 u32 tmp = 0;
662 int err = 0; 661 int err = 0;
663 662
664 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS. 663 /* Set the physical start address of the RISC program in the initial
664 * program counter(IPC) member of the CMDS. */
665 cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr); 665 cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
666 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ 666 /* Risc IPC High 64 bits 63-32 */
667 cx_write(sram_ch->cmds_start + 4, 0);
667 668
668 /* reset counter */ 669 /* reset counter */
669 cx_write(sram_ch->gpcnt_ctl, 3); 670 cx_write(sram_ch->gpcnt_ctl, 3);
670 671
671 //Set the line length (It looks like we do not need to set the line length) 672 /* Set the line length (It looks like we do not need to set the
673 * line length) */
672 cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH); 674 cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
673 675
674 //Set the input mode to 16-bit 676 /* Set the input mode to 16-bit */
675 tmp = cx_read(sram_ch->aud_cfg); 677 tmp = cx_read(sram_ch->aud_cfg);
676 tmp |= 678 tmp |=
677 FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | 679 FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
678 FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE; 680 FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
679 cx_write(sram_ch->aud_cfg, tmp); 681 cx_write(sram_ch->aud_cfg, tmp);
680 682
681 // Read and write back the interrupt status register to clear it 683 /* Read and write back the interrupt status register to clear it */
682 tmp = cx_read(sram_ch->int_stat); 684 tmp = cx_read(sram_ch->int_stat);
683 cx_write(sram_ch->int_stat, tmp); 685 cx_write(sram_ch->int_stat, tmp);
684 686
685 // Clear our bits from the interrupt status register. 687 /* Clear our bits from the interrupt status register. */
686 cx_write(sram_ch->int_stat, _intr_msk); 688 cx_write(sram_ch->int_stat, _intr_msk);
687 689
688 //Set the interrupt mask register, enable irq. 690 /* Set the interrupt mask register, enable irq. */
689 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); 691 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
690 tmp = cx_read(sram_ch->int_msk); 692 tmp = cx_read(sram_ch->int_msk);
691 cx_write(sram_ch->int_msk, tmp |= _intr_msk); 693 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
@@ -699,19 +701,19 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
699 goto fail_irq; 701 goto fail_irq;
700 } 702 }
701 703
702 // Start the DMA engine 704 /* Start the DMA engine */
703 tmp = cx_read(sram_ch->dma_ctl); 705 tmp = cx_read(sram_ch->dma_ctl);
704 cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en); 706 cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en);
705 707
706 dev->_audio_is_running = 1; 708 dev->_audio_is_running = 1;
707 dev->_is_first_audio_frame = 1; 709 dev->_is_first_audio_frame = 1;
708 710
709 // The fifo_en bit turns on by the first Risc program 711 /* The fifo_en bit turns on by the first Risc program */
710 cx25821_wait_fifo_enable(dev, sram_ch); 712 cx25821_wait_fifo_enable(dev, sram_ch);
711 713
712 return 0; 714 return 0;
713 715
714 fail_irq: 716fail_irq:
715 cx25821_dev_unregister(dev); 717 cx25821_dev_unregister(dev);
716 return err; 718 return err;
717} 719}
@@ -731,14 +733,14 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
731 dev->_audio_upstream_channel_select = channel_select; 733 dev->_audio_upstream_channel_select = channel_select;
732 sram_ch = &dev->sram_channels[channel_select]; 734 sram_ch = &dev->sram_channels[channel_select];
733 735
734 //Work queue 736 /* Work queue */
735 INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler); 737 INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
736 dev->_irq_audio_queues = 738 dev->_irq_audio_queues =
737 create_singlethread_workqueue("cx25821_audioworkqueue"); 739 create_singlethread_workqueue("cx25821_audioworkqueue");
738 740
739 if (!dev->_irq_audio_queues) { 741 if (!dev->_irq_audio_queues) {
740 printk 742 printk(KERN_DEBUG
741 ("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n"); 743 "cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
742 return -ENOMEM; 744 return -ENOMEM;
743 } 745 }
744 746
@@ -760,7 +762,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
760 memcpy(dev->_audiofilename, dev->input_audiofilename, 762 memcpy(dev->_audiofilename, dev->input_audiofilename,
761 str_length + 1); 763 str_length + 1);
762 764
763 //Default if filename is empty string 765 /* Default if filename is empty string */
764 if (strcmp(dev->input_audiofilename, "") == 0) { 766 if (strcmp(dev->input_audiofilename, "") == 0) {
765 dev->_audiofilename = "/root/audioGOOD.wav"; 767 dev->_audiofilename = "/root/audioGOOD.wav";
766 } 768 }
@@ -784,7 +786,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
784 RISC_SYNC_INSTRUCTION_SIZE; 786 RISC_SYNC_INSTRUCTION_SIZE;
785 dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS; 787 dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
786 788
787 //Allocating buffers and prepare RISC program 789 /* Allocating buffers and prepare RISC program */
788 retval = 790 retval =
789 cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size); 791 cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
790 if (retval < 0) { 792 if (retval < 0) {
@@ -793,12 +795,12 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
793 dev->name); 795 dev->name);
794 goto error; 796 goto error;
795 } 797 }
796 //Start RISC engine 798 /* Start RISC engine */
797 cx25821_start_audio_dma_upstream(dev, sram_ch); 799 cx25821_start_audio_dma_upstream(dev, sram_ch);
798 800
799 return 0; 801 return 0;
800 802
801 error: 803error:
802 cx25821_dev_unregister(dev); 804 cx25821_dev_unregister(dev);
803 805
804 return err; 806 return err;
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
index e76451c309f1..e49ead982f39 100644
--- a/drivers/staging/cx25821/cx25821-audups11.c
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -88,10 +88,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
88} 88}
89 89
90static struct videobuf_queue_ops cx25821_video_qops = { 90static struct videobuf_queue_ops cx25821_video_qops = {
91 .buf_setup = buffer_setup, 91 .buf_setup = cx25821_buffer_setup,
92 .buf_prepare = buffer_prepare, 92 .buf_prepare = cx25821_buffer_prepare,
93 .buf_queue = buffer_queue, 93 .buf_queue = buffer_queue,
94 .buf_release = buffer_release, 94 .buf_release = cx25821_buffer_release,
95}; 95};
96 96
97static int video_open(struct file *file) 97static int video_open(struct file *file)
@@ -145,7 +145,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
145 145
146 switch (fh->type) { 146 switch (fh->type) {
147 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 147 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
148 if (res_locked(fh->dev, RESOURCE_VIDEO11)) 148 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO11))
149 return -EBUSY; 149 return -EBUSY;
150 150
151 return videobuf_read_one(&fh->vidq, data, count, ppos, 151 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -163,7 +163,7 @@ static unsigned int video_poll(struct file *file,
163 struct cx25821_fh *fh = file->private_data; 163 struct cx25821_fh *fh = file->private_data;
164 struct cx25821_buffer *buf; 164 struct cx25821_buffer *buf;
165 165
166 if (res_check(fh, RESOURCE_VIDEO11)) { 166 if (cx25821_res_check(fh, RESOURCE_VIDEO11)) {
167 /* streaming capture */ 167 /* streaming capture */
168 if (list_empty(&fh->vidq.stream)) 168 if (list_empty(&fh->vidq.stream))
169 return POLLERR; 169 return POLLERR;
@@ -191,19 +191,19 @@ static int video_release(struct file *file)
191 //cx_write(channel11->dma_ctl, 0); 191 //cx_write(channel11->dma_ctl, 0);
192 192
193 /* stop video capture */ 193 /* stop video capture */
194 if (res_check(fh, RESOURCE_VIDEO11)) { 194 if (cx25821_res_check(fh, RESOURCE_VIDEO11)) {
195 videobuf_queue_cancel(&fh->vidq); 195 videobuf_queue_cancel(&fh->vidq);
196 res_free(dev, fh, RESOURCE_VIDEO11); 196 cx25821_res_free(dev, fh, RESOURCE_VIDEO11);
197 } 197 }
198 198
199 if (fh->vidq.read_buf) { 199 if (fh->vidq.read_buf) {
200 buffer_release(&fh->vidq, fh->vidq.read_buf); 200 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
201 kfree(fh->vidq.read_buf); 201 kfree(fh->vidq.read_buf);
202 } 202 }
203 203
204 videobuf_mmap_free(&fh->vidq); 204 videobuf_mmap_free(&fh->vidq);
205 205
206 v4l2_prio_close(&dev->prio, &fh->prio); 206 v4l2_prio_close(&dev->prio, fh->prio);
207 207
208 file->private_data = NULL; 208 file->private_data = NULL;
209 kfree(fh); 209 kfree(fh);
@@ -224,7 +224,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
224 return -EINVAL; 224 return -EINVAL;
225 } 225 }
226 226
227 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO11)))) { 227 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO11)))) {
228 return -EBUSY; 228 return -EBUSY;
229 } 229 }
230 230
@@ -242,11 +242,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
242 if (i != fh->type) 242 if (i != fh->type)
243 return -EINVAL; 243 return -EINVAL;
244 244
245 res = get_resource(fh, RESOURCE_VIDEO11); 245 res = cx25821_get_resource(fh, RESOURCE_VIDEO11);
246 err = videobuf_streamoff(get_queue(fh)); 246 err = videobuf_streamoff(get_queue(fh));
247 if (err < 0) 247 if (err < 0)
248 return err; 248 return err;
249 res_free(dev, fh, res); 249 cx25821_res_free(dev, fh, res);
250 return 0; 250 return 0;
251} 251}
252 252
@@ -258,13 +258,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
258 int err; 258 int err;
259 259
260 if (fh) { 260 if (fh) {
261 err = v4l2_prio_check(&dev->prio, &fh->prio); 261 err = v4l2_prio_check(&dev->prio, fh->prio);
262 if (0 != err) 262 if (0 != err)
263 return err; 263 return err;
264 } 264 }
265 265
266 dprintk(2, "%s()\n", __func__); 266 dprintk(2, "%s()\n", __func__);
267 err = vidioc_try_fmt_vid_cap(file, priv, f); 267 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
268 268
269 if (0 != err) 269 if (0 != err)
270 return err; 270 return err;
@@ -350,7 +350,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
350 350
351 if (fh) { 351 if (fh) {
352 dev = fh->dev; 352 dev = fh->dev;
353 err = v4l2_prio_check(&dev->prio, &fh->prio); 353 err = v4l2_prio_check(&dev->prio, fh->prio);
354 if (0 != err) 354 if (0 != err)
355 return err; 355 return err;
356 } 356 }
@@ -364,50 +364,50 @@ static const struct v4l2_file_operations video_fops = {
364 .release = video_release, 364 .release = video_release,
365 .read = video_read, 365 .read = video_read,
366 .poll = video_poll, 366 .poll = video_poll,
367 .mmap = video_mmap, 367 .mmap = cx25821_video_mmap,
368 .ioctl = video_ioctl_upstream11, 368 .ioctl = video_ioctl_upstream11,
369}; 369};
370 370
371static const struct v4l2_ioctl_ops video_ioctl_ops = { 371static const struct v4l2_ioctl_ops video_ioctl_ops = {
372 .vidioc_querycap = vidioc_querycap, 372 .vidioc_querycap = cx25821_vidioc_querycap,
373 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 373 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
374 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 374 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
375 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 375 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
376 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 376 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
377 .vidioc_reqbufs = vidioc_reqbufs, 377 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
378 .vidioc_querybuf = vidioc_querybuf, 378 .vidioc_querybuf = cx25821_vidioc_querybuf,
379 .vidioc_qbuf = vidioc_qbuf, 379 .vidioc_qbuf = cx25821_vidioc_qbuf,
380 .vidioc_dqbuf = vidioc_dqbuf, 380 .vidioc_dqbuf = vidioc_dqbuf,
381#ifdef TUNER_FLAG 381#ifdef TUNER_FLAG
382 .vidioc_s_std = vidioc_s_std, 382 .vidioc_s_std = cx25821_vidioc_s_std,
383 .vidioc_querystd = vidioc_querystd, 383 .vidioc_querystd = cx25821_vidioc_querystd,
384#endif 384#endif
385 .vidioc_cropcap = vidioc_cropcap, 385 .vidioc_cropcap = cx25821_vidioc_cropcap,
386 .vidioc_s_crop = vidioc_s_crop, 386 .vidioc_s_crop = cx25821_vidioc_s_crop,
387 .vidioc_g_crop = vidioc_g_crop, 387 .vidioc_g_crop = cx25821_vidioc_g_crop,
388 .vidioc_enum_input = vidioc_enum_input, 388 .vidioc_enum_input = cx25821_vidioc_enum_input,
389 .vidioc_g_input = vidioc_g_input, 389 .vidioc_g_input = cx25821_vidioc_g_input,
390 .vidioc_s_input = vidioc_s_input, 390 .vidioc_s_input = cx25821_vidioc_s_input,
391 .vidioc_g_ctrl = vidioc_g_ctrl, 391 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
392 .vidioc_s_ctrl = vidioc_s_ctrl, 392 .vidioc_s_ctrl = vidioc_s_ctrl,
393 .vidioc_queryctrl = vidioc_queryctrl, 393 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
394 .vidioc_streamon = vidioc_streamon, 394 .vidioc_streamon = vidioc_streamon,
395 .vidioc_streamoff = vidioc_streamoff, 395 .vidioc_streamoff = vidioc_streamoff,
396 .vidioc_log_status = vidioc_log_status, 396 .vidioc_log_status = vidioc_log_status,
397 .vidioc_g_priority = vidioc_g_priority, 397 .vidioc_g_priority = cx25821_vidioc_g_priority,
398 .vidioc_s_priority = vidioc_s_priority, 398 .vidioc_s_priority = cx25821_vidioc_s_priority,
399#ifdef CONFIG_VIDEO_V4L1_COMPAT 399#ifdef CONFIG_VIDEO_V4L1_COMPAT
400 .vidiocgmbuf = vidiocgmbuf, 400 .vidiocgmbuf = cx25821_vidiocgmbuf,
401#endif 401#endif
402#ifdef TUNER_FLAG 402#ifdef TUNER_FLAG
403 .vidioc_g_tuner = vidioc_g_tuner, 403 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
404 .vidioc_s_tuner = vidioc_s_tuner, 404 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
405 .vidioc_g_frequency = vidioc_g_frequency, 405 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
406 .vidioc_s_frequency = vidioc_s_frequency, 406 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
407#endif 407#endif
408#ifdef CONFIG_VIDEO_ADV_DEBUG 408#ifdef CONFIG_VIDEO_ADV_DEBUG
409 .vidioc_g_register = vidioc_g_register, 409 .vidioc_g_register = cx25821_vidioc_g_register,
410 .vidioc_s_register = vidioc_s_register, 410 .vidioc_s_register = cx25821_vidioc_s_register,
411#endif 411#endif
412}; 412};
413 413
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
index 4d0b9eac3e49..da0f56d50e27 100644
--- a/drivers/staging/cx25821/cx25821-cards.c
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -30,12 +30,12 @@
30#include "cx25821.h" 30#include "cx25821.h"
31#include "tuner-xc2028.h" 31#include "tuner-xc2028.h"
32 32
33// board config info 33/* board config info */
34 34
35struct cx25821_board cx25821_boards[] = { 35struct cx25821_board cx25821_boards[] = {
36 [UNKNOWN_BOARD] = { 36 [UNKNOWN_BOARD] = {
37 .name = "UNKNOWN/GENERIC", 37 .name = "UNKNOWN/GENERIC",
38 // Ensure safe default for unknown boards 38 /* Ensure safe default for unknown boards */
39 .clk_freq = 0, 39 .clk_freq = 0,
40 }, 40 },
41 41
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index 9e9b8c3c9311..d90abb383fc8 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -32,6 +32,7 @@ MODULE_AUTHOR("Shu Lin - Hiep Huynh");
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33 33
34struct list_head cx25821_devlist; 34struct list_head cx25821_devlist;
35EXPORT_SYMBOL(cx25821_devlist);
35 36
36static unsigned int debug; 37static unsigned int debug;
37module_param(debug, int, 0644); 38module_param(debug, int, 0644);
@@ -313,6 +314,7 @@ struct sram_channel cx25821_sram_channels[] = {
313 .irq_bit = 11, 314 .irq_bit = 11,
314 }, 315 },
315}; 316};
317EXPORT_SYMBOL(cx25821_sram_channels);
316 318
317struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00]; 319struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
318struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01]; 320struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
@@ -388,70 +390,74 @@ static void cx25821_registers_init(struct cx25821_dev *dev)
388{ 390{
389 u32 tmp; 391 u32 tmp;
390 392
391 // enable RUN_RISC in Pecos 393 /* enable RUN_RISC in Pecos */
392 cx_write(DEV_CNTRL2, 0x20); 394 cx_write(DEV_CNTRL2, 0x20);
393 395
394 // Set the master PCI interrupt masks to enable video, audio, MBIF, and GPIO interrupts 396 /* Set the master PCI interrupt masks to enable video, audio, MBIF,
395 // I2C interrupt masking is handled by the I2C objects themselves. 397 * and GPIO interrupts
398 * I2C interrupt masking is handled by the I2C objects themselves. */
396 cx_write(PCI_INT_MSK, 0x2001FFFF); 399 cx_write(PCI_INT_MSK, 0x2001FFFF);
397 400
398 tmp = cx_read(RDR_TLCTL0); 401 tmp = cx_read(RDR_TLCTL0);
399 tmp &= ~FLD_CFG_RCB_CK_EN; // Clear the RCB_CK_EN bit 402 tmp &= ~FLD_CFG_RCB_CK_EN; /* Clear the RCB_CK_EN bit */
400 cx_write(RDR_TLCTL0, tmp); 403 cx_write(RDR_TLCTL0, tmp);
401 404
402 // PLL-A setting for the Audio Master Clock 405 /* PLL-A setting for the Audio Master Clock */
403 cx_write(PLL_A_INT_FRAC, 0x9807A58B); 406 cx_write(PLL_A_INT_FRAC, 0x9807A58B);
404 407
405 // PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1 408 /* PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1 */
406 cx_write(PLL_A_POST_STAT_BIST, 0x8000019C); 409 cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
407 410
408 // clear reset bit [31] 411 /* clear reset bit [31] */
409 tmp = cx_read(PLL_A_INT_FRAC); 412 tmp = cx_read(PLL_A_INT_FRAC);
410 cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF); 413 cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
411 414
412 // PLL-B setting for Mobilygen Host Bus Interface 415 /* PLL-B setting for Mobilygen Host Bus Interface */
413 cx_write(PLL_B_INT_FRAC, 0x9883A86F); 416 cx_write(PLL_B_INT_FRAC, 0x9883A86F);
414 417
415 // PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0 418 /* PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0 */
416 cx_write(PLL_B_POST_STAT_BIST, 0x8000018D); 419 cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
417 420
418 // clear reset bit [31] 421 /* clear reset bit [31] */
419 tmp = cx_read(PLL_B_INT_FRAC); 422 tmp = cx_read(PLL_B_INT_FRAC);
420 cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF); 423 cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
421 424
422 // PLL-C setting for video upstream channel 425 /* PLL-C setting for video upstream channel */
423 cx_write(PLL_C_INT_FRAC, 0x96A0EA3F); 426 cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
424 427
425 // PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0 428 /* PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0 */
426 cx_write(PLL_C_POST_STAT_BIST, 0x80000103); 429 cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
427 430
428 // clear reset bit [31] 431 /* clear reset bit [31] */
429 tmp = cx_read(PLL_C_INT_FRAC); 432 tmp = cx_read(PLL_C_INT_FRAC);
430 cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF); 433 cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
431 434
432 // PLL-D setting for audio upstream channel 435 /* PLL-D setting for audio upstream channel */
433 cx_write(PLL_D_INT_FRAC, 0x98757F5B); 436 cx_write(PLL_D_INT_FRAC, 0x98757F5B);
434 437
435 // PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0 438 /* PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0 */
436 cx_write(PLL_D_POST_STAT_BIST, 0x80000113); 439 cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
437 440
438 // clear reset bit [31] 441 /* clear reset bit [31] */
439 tmp = cx_read(PLL_D_INT_FRAC); 442 tmp = cx_read(PLL_D_INT_FRAC);
440 cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF); 443 cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
441 444
442 // This selects the PLL C clock source for the video upstream channel I and J 445 /* This selects the PLL C clock source for the video upstream channel
446 * I and J */
443 tmp = cx_read(VID_CH_CLK_SEL); 447 tmp = cx_read(VID_CH_CLK_SEL);
444 cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000); 448 cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
445 449
446 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C 450 /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
447 //select 656/VIP DST for downstream Channel A - C 451 * channel A-C
452 * select 656/VIP DST for downstream Channel A - C */
448 tmp = cx_read(VID_CH_MODE_SEL); 453 tmp = cx_read(VID_CH_MODE_SEL);
449 //cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF); 454 /* cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF); */
450 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); 455 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
451 456
452 // enables 656 port I and J as output 457 /* enables 656 port I and J as output */
453 tmp = cx_read(CLK_RST); 458 tmp = cx_read(CLK_RST);
454 tmp |= FLD_USE_ALT_PLL_REF; // use external ALT_PLL_REF pin as its reference clock instead 459 /* use external ALT_PLL_REF pin as its reference clock instead */
460 tmp |= FLD_USE_ALT_PLL_REF;
455 cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE)); 461 cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
456 462
457 mdelay(100); 463 mdelay(100);
@@ -476,9 +482,8 @@ int cx25821_sram_channel_setup(struct cx25821_dev *dev,
476 cdt = ch->cdt; 482 cdt = ch->cdt;
477 lines = ch->fifo_size / bpl; 483 lines = ch->fifo_size / bpl;
478 484
479 if (lines > 4) { 485 if (lines > 4)
480 lines = 4; 486 lines = 4;
481 }
482 487
483 BUG_ON(lines < 2); 488 BUG_ON(lines < 2);
484 489
@@ -494,16 +499,15 @@ int cx25821_sram_channel_setup(struct cx25821_dev *dev,
494 cx_write(cdt + 16 * i + 12, 0); 499 cx_write(cdt + 16 * i + 12, 0);
495 } 500 }
496 501
497 //init the first cdt buffer 502 /* init the first cdt buffer */
498 for (i = 0; i < 128; i++) 503 for (i = 0; i < 128; i++)
499 cx_write(ch->fifo_start + 4 * i, i); 504 cx_write(ch->fifo_start + 4 * i, i);
500 505
501 /* write CMDS */ 506 /* write CMDS */
502 if (ch->jumponly) { 507 if (ch->jumponly)
503 cx_write(ch->cmds_start + 0, 8); 508 cx_write(ch->cmds_start + 0, 8);
504 } else { 509 else
505 cx_write(ch->cmds_start + 0, risc); 510 cx_write(ch->cmds_start + 0, risc);
506 }
507 511
508 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ 512 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
509 cx_write(ch->cmds_start + 8, cdt); 513 cx_write(ch->cmds_start + 8, cdt);
@@ -526,6 +530,7 @@ int cx25821_sram_channel_setup(struct cx25821_dev *dev,
526 530
527 return 0; 531 return 0;
528} 532}
533EXPORT_SYMBOL(cx25821_sram_channel_setup);
529 534
530int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, 535int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
531 struct sram_channel *ch, 536 struct sram_channel *ch,
@@ -546,9 +551,8 @@ int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
546 cdt = ch->cdt; 551 cdt = ch->cdt;
547 lines = ch->fifo_size / bpl; 552 lines = ch->fifo_size / bpl;
548 553
549 if (lines > 3) { 554 if (lines > 3)
550 lines = 3; //for AUDIO 555 lines = 3; /* for AUDIO */
551 }
552 556
553 BUG_ON(lines < 2); 557 BUG_ON(lines < 2);
554 558
@@ -565,25 +569,23 @@ int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
565 } 569 }
566 570
567 /* write CMDS */ 571 /* write CMDS */
568 if (ch->jumponly) { 572 if (ch->jumponly)
569 cx_write(ch->cmds_start + 0, 8); 573 cx_write(ch->cmds_start + 0, 8);
570 } else { 574 else
571 cx_write(ch->cmds_start + 0, risc); 575 cx_write(ch->cmds_start + 0, risc);
572 }
573 576
574 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ 577 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
575 cx_write(ch->cmds_start + 8, cdt); 578 cx_write(ch->cmds_start + 8, cdt);
576 cx_write(ch->cmds_start + 12, (lines * 16) >> 3); 579 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
577 cx_write(ch->cmds_start + 16, ch->ctrl_start); 580 cx_write(ch->cmds_start + 16, ch->ctrl_start);
578 581
579 //IQ size 582 /* IQ size */
580 if (ch->jumponly) { 583 if (ch->jumponly)
581 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); 584 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
582 } else { 585 else
583 cx_write(ch->cmds_start + 20, 64 >> 2); 586 cx_write(ch->cmds_start + 20, 64 >> 2);
584 }
585 587
586 //zero out 588 /* zero out */
587 for (i = 24; i < 80; i += 4) 589 for (i = 24; i < 80; i += 4)
588 cx_write(ch->cmds_start + i, 0); 590 cx_write(ch->cmds_start + i, 0);
589 591
@@ -595,6 +597,7 @@ int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
595 597
596 return 0; 598 return 0;
597} 599}
600EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
598 601
599void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch) 602void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
600{ 603{
@@ -658,6 +661,7 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
658 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n", 661 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
659 cx_read(ch->cnt2_reg)); 662 cx_read(ch->cnt2_reg));
660} 663}
664EXPORT_SYMBOL(cx25821_sram_channel_dump);
661 665
662void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, 666void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
663 struct sram_channel *ch) 667 struct sram_channel *ch)
@@ -731,7 +735,7 @@ void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
731 printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc); 735 printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
732 } 736 }
733 737
734 //read data from the first cdt buffer 738 /* read data from the first cdt buffer */
735 risc = cx_read(AUD_A_CDT); 739 risc = cx_read(AUD_A_CDT);
736 printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc); 740 printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
737 for (i = 0; i < 8; i++) { 741 for (i = 0; i < 8; i++) {
@@ -741,31 +745,32 @@ void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
741 printk(KERN_WARNING "\n\n"); 745 printk(KERN_WARNING "\n\n");
742 746
743 value = cx_read(CLK_RST); 747 value = cx_read(CLK_RST);
744 CX25821_INFO(" CLK_RST = 0x%x \n\n", value); 748 CX25821_INFO(" CLK_RST = 0x%x\n\n", value);
745 749
746 value = cx_read(PLL_A_POST_STAT_BIST); 750 value = cx_read(PLL_A_POST_STAT_BIST);
747 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x \n\n", value); 751 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x\n\n", value);
748 value = cx_read(PLL_A_INT_FRAC); 752 value = cx_read(PLL_A_INT_FRAC);
749 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x \n\n", value); 753 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x\n\n", value);
750 754
751 value = cx_read(PLL_B_POST_STAT_BIST); 755 value = cx_read(PLL_B_POST_STAT_BIST);
752 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x \n\n", value); 756 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x\n\n", value);
753 value = cx_read(PLL_B_INT_FRAC); 757 value = cx_read(PLL_B_INT_FRAC);
754 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x \n\n", value); 758 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x\n\n", value);
755 759
756 value = cx_read(PLL_C_POST_STAT_BIST); 760 value = cx_read(PLL_C_POST_STAT_BIST);
757 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x \n\n", value); 761 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x\n\n", value);
758 value = cx_read(PLL_C_INT_FRAC); 762 value = cx_read(PLL_C_INT_FRAC);
759 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x \n\n", value); 763 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x\n\n", value);
760 764
761 value = cx_read(PLL_D_POST_STAT_BIST); 765 value = cx_read(PLL_D_POST_STAT_BIST);
762 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x \n\n", value); 766 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x\n\n", value);
763 value = cx_read(PLL_D_INT_FRAC); 767 value = cx_read(PLL_D_INT_FRAC);
764 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x \n\n", value); 768 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x\n\n", value);
765 769
766 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); 770 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
767 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x \n\n", value); 771 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x\n\n", value);
768} 772}
773EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
769 774
770static void cx25821_shutdown(struct cx25821_dev *dev) 775static void cx25821_shutdown(struct cx25821_dev *dev)
771{ 776{
@@ -835,8 +840,8 @@ static void cx25821_initialize(struct cx25821_dev *dev)
835 cx_write(AUD_E_INT_STAT, 0xffffffff); 840 cx_write(AUD_E_INT_STAT, 0xffffffff);
836 841
837 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); 842 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
838 cx_write(PAD_CTRL, 0x12); //for I2C 843 cx_write(PAD_CTRL, 0x12); /* for I2C */
839 cx25821_registers_init(dev); //init Pecos registers 844 cx25821_registers_init(dev); /* init Pecos registers */
840 mdelay(100); 845 mdelay(100);
841 846
842 for (i = 0; i < VID_CHANNEL_NUM; i++) { 847 for (i = 0; i < VID_CHANNEL_NUM; i++) {
@@ -847,7 +852,7 @@ static void cx25821_initialize(struct cx25821_dev *dev)
847 dev->use_cif_resolution[i] = FALSE; 852 dev->use_cif_resolution[i] = FALSE;
848 } 853 }
849 854
850 //Probably only affect Downstream 855 /* Probably only affect Downstream */
851 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J; 856 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
852 i++) { 857 i++) {
853 cx25821_set_vip_mode(dev, &dev->sram_channels[i]); 858 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
@@ -859,7 +864,7 @@ static void cx25821_initialize(struct cx25821_dev *dev)
859 cx25821_gpio_init(dev); 864 cx25821_gpio_init(dev);
860} 865}
861 866
862static int get_resources(struct cx25821_dev *dev) 867static int cx25821_get_resources(struct cx25821_dev *dev)
863{ 868{
864 if (request_mem_region 869 if (request_mem_region
865 (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0), 870 (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0),
@@ -944,12 +949,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
944 dev->clk_freq = 28000000; 949 dev->clk_freq = 28000000;
945 dev->sram_channels = cx25821_sram_channels; 950 dev->sram_channels = cx25821_sram_channels;
946 951
947 if (dev->nr > 1) { 952 if (dev->nr > 1)
948 CX25821_INFO("dev->nr > 1!"); 953 CX25821_INFO("dev->nr > 1!");
949 }
950 954
951 /* board config */ 955 /* board config */
952 dev->board = 1; //card[dev->nr]; 956 dev->board = 1; /* card[dev->nr]; */
953 dev->_max_num_decoders = MAX_DECODERS; 957 dev->_max_num_decoders = MAX_DECODERS;
954 958
955 dev->pci_bus = dev->pci->bus->number; 959 dev->pci_bus = dev->pci->bus->number;
@@ -967,7 +971,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
967 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */ 971 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
968 972
969 973
970 if (get_resources(dev) < 0) { 974 if (cx25821_get_resources(dev) < 0) {
971 printk(KERN_ERR "%s No more PCIe resources for " 975 printk(KERN_ERR "%s No more PCIe resources for "
972 "subsystem: %04x:%04x\n", 976 "subsystem: %04x:%04x\n",
973 dev->name, dev->pci->subsystem_vendor, 977 dev->name, dev->pci->subsystem_vendor,
@@ -1007,8 +1011,8 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
1007 cx25821_initialize(dev); 1011 cx25821_initialize(dev);
1008 1012
1009 cx25821_i2c_register(&dev->i2c_bus[0]); 1013 cx25821_i2c_register(&dev->i2c_bus[0]);
1010// cx25821_i2c_register(&dev->i2c_bus[1]); 1014/* cx25821_i2c_register(&dev->i2c_bus[1]);
1011// cx25821_i2c_register(&dev->i2c_bus[2]); 1015 * cx25821_i2c_register(&dev->i2c_bus[2]); */
1012 1016
1013 CX25821_INFO("i2c register! bus->i2c_rc = %d\n", 1017 CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
1014 dev->i2c_bus[0].i2c_rc); 1018 dev->i2c_bus[0].i2c_rc);
@@ -1026,7 +1030,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
1026 1030
1027 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; 1031 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1028 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) { 1032 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1029 //Since we don't have template8 for Audio Downstream 1033 /* Since we don't have template8 for Audio Downstream */
1030 if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) { 1034 if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) {
1031 printk(KERN_ERR 1035 printk(KERN_ERR
1032 "%s() Failed to register analog video adapters for Upstream channel %d.\n", 1036 "%s() Failed to register analog video adapters for Upstream channel %d.\n",
@@ -1034,7 +1038,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
1034 } 1038 }
1035 } 1039 }
1036 1040
1037 // register IOCTL device 1041 /* register IOCTL device */
1038 dev->ioctl_dev = 1042 dev->ioctl_dev =
1039 cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH], 1043 cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH],
1040 "video"); 1044 "video");
@@ -1112,6 +1116,7 @@ void cx25821_dev_unregister(struct cx25821_dev *dev)
1112 cx25821_i2c_unregister(&dev->i2c_bus[0]); 1116 cx25821_i2c_unregister(&dev->i2c_bus[0]);
1113 cx25821_iounmap(dev); 1117 cx25821_iounmap(dev);
1114} 1118}
1119EXPORT_SYMBOL(cx25821_dev_unregister);
1115 1120
1116static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist, 1121static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
1117 unsigned int offset, u32 sync_line, 1122 unsigned int offset, u32 sync_line,
@@ -1122,9 +1127,8 @@ static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
1122 unsigned int line, todo; 1127 unsigned int line, todo;
1123 1128
1124 /* sync instruction */ 1129 /* sync instruction */
1125 if (sync_line != NO_SYNC_LINE) { 1130 if (sync_line != NO_SYNC_LINE)
1126 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); 1131 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1127 }
1128 1132
1129 /* scan lines */ 1133 /* scan lines */
1130 sg = sglist; 1134 sg = sglist;
@@ -1299,7 +1303,8 @@ int cx25821_risc_databuffer_audio(struct pci_dev *pci,
1299 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; 1303 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
1300 instructions += 1; 1304 instructions += 1;
1301 1305
1302 if ((rc = btcx_riscmem_alloc(pci, risc, instructions * 12)) < 0) 1306 rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
1307 if (rc < 0)
1303 return rc; 1308 return rc;
1304 1309
1305 /* write risc instructions */ 1310 /* write risc instructions */
@@ -1312,6 +1317,7 @@ int cx25821_risc_databuffer_audio(struct pci_dev *pci,
1312 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); 1317 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1313 return 0; 1318 return 0;
1314} 1319}
1320EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
1315 1321
1316int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, 1322int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
1317 u32 reg, u32 mask, u32 value) 1323 u32 reg, u32 mask, u32 value)
@@ -1375,7 +1381,7 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id)
1375 } 1381 }
1376 } 1382 }
1377 1383
1378 out: 1384out:
1379 return IRQ_RETVAL(handled); 1385 return IRQ_RETVAL(handled);
1380} 1386}
1381 1387
@@ -1399,12 +1405,14 @@ void cx25821_print_irqbits(char *name, char *tag, char **strings,
1399 } 1405 }
1400 printk("\n"); 1406 printk("\n");
1401} 1407}
1408EXPORT_SYMBOL(cx25821_print_irqbits);
1402 1409
1403struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci) 1410struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
1404{ 1411{
1405 struct cx25821_dev *dev = pci_get_drvdata(pci); 1412 struct cx25821_dev *dev = pci_get_drvdata(pci);
1406 return dev; 1413 return dev;
1407} 1414}
1415EXPORT_SYMBOL(cx25821_dev_get);
1408 1416
1409static int __devinit cx25821_initdev(struct pci_dev *pci_dev, 1417static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
1410 const struct pci_device_id *pci_id) 1418 const struct pci_device_id *pci_id)
@@ -1430,7 +1438,7 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
1430 goto fail_unregister_device; 1438 goto fail_unregister_device;
1431 } 1439 }
1432 1440
1433 printk(KERN_INFO "cx25821 Athena pci enable ! \n"); 1441 printk(KERN_INFO "cx25821 Athena pci enable !\n");
1434 1442
1435 if (cx25821_dev_setup(dev) < 0) { 1443 if (cx25821_dev_setup(dev) < 0) {
1436 err = -EINVAL; 1444 err = -EINVAL;
@@ -1464,14 +1472,14 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
1464 1472
1465 return 0; 1473 return 0;
1466 1474
1467 fail_irq: 1475fail_irq:
1468 printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ ! \n"); 1476 printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ !\n");
1469 cx25821_dev_unregister(dev); 1477 cx25821_dev_unregister(dev);
1470 1478
1471 fail_unregister_device: 1479fail_unregister_device:
1472 v4l2_device_unregister(&dev->v4l2_dev); 1480 v4l2_device_unregister(&dev->v4l2_dev);
1473 1481
1474 fail_free: 1482fail_free:
1475 kfree(dev); 1483 kfree(dev);
1476 return err; 1484 return err;
1477} 1485}
@@ -1536,16 +1544,6 @@ static void __exit cx25821_fini(void)
1536 pci_unregister_driver(&cx25821_pci_driver); 1544 pci_unregister_driver(&cx25821_pci_driver);
1537} 1545}
1538 1546
1539EXPORT_SYMBOL(cx25821_devlist);
1540EXPORT_SYMBOL(cx25821_sram_channels);
1541EXPORT_SYMBOL(cx25821_print_irqbits);
1542EXPORT_SYMBOL(cx25821_dev_get);
1543EXPORT_SYMBOL(cx25821_dev_unregister);
1544EXPORT_SYMBOL(cx25821_sram_channel_setup);
1545EXPORT_SYMBOL(cx25821_sram_channel_dump);
1546EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
1547EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
1548EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
1549EXPORT_SYMBOL(cx25821_set_gpiopin_direction); 1547EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
1550 1548
1551module_init(cx25821_init); 1549module_init(cx25821_init);
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/staging/cx25821/cx25821-gpio.c
index e8a37b47e437..2f154b3658a1 100644
--- a/drivers/staging/cx25821/cx25821-gpio.c
+++ b/drivers/staging/cx25821/cx25821-gpio.c
@@ -31,7 +31,7 @@ void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
31 u32 gpio_register = 0; 31 u32 gpio_register = 0;
32 u32 value = 0; 32 u32 value = 0;
33 33
34 // Check for valid pinNumber 34 /* Check for valid pinNumber */
35 if (pin_number >= 47) 35 if (pin_number >= 47)
36 return; 36 return;
37 37
@@ -39,14 +39,14 @@ void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
39 bit = pin_number - 31; 39 bit = pin_number - 31;
40 gpio_oe_reg = GPIO_HI_OE; 40 gpio_oe_reg = GPIO_HI_OE;
41 } 41 }
42 // Here we will make sure that the GPIOs 0 and 1 are output. keep the rest as is 42 /* Here we will make sure that the GPIOs 0 and 1 are output. keep the
43 * rest as is */
43 gpio_register = cx_read(gpio_oe_reg); 44 gpio_register = cx_read(gpio_oe_reg);
44 45
45 if (pin_logic_value == 1) { 46 if (pin_logic_value == 1)
46 value = gpio_register | Set_GPIO_Bit(bit); 47 value = gpio_register | Set_GPIO_Bit(bit);
47 } else { 48 else
48 value = gpio_register & Clear_GPIO_Bit(bit); 49 value = gpio_register & Clear_GPIO_Bit(bit);
49 }
50 50
51 cx_write(gpio_oe_reg, value); 51 cx_write(gpio_oe_reg, value);
52} 52}
@@ -58,11 +58,12 @@ static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
58 u32 gpio_reg = GPIO_LO; 58 u32 gpio_reg = GPIO_LO;
59 u32 value = 0; 59 u32 value = 0;
60 60
61 // Check for valid pinNumber 61 /* Check for valid pinNumber */
62 if (pin_number >= 47) 62 if (pin_number >= 47)
63 return; 63 return;
64 64
65 cx25821_set_gpiopin_direction(dev, pin_number, 0); // change to output direction 65 /* change to output direction */
66 cx25821_set_gpiopin_direction(dev, pin_number, 0);
66 67
67 if (pin_number > 31) { 68 if (pin_number > 31) {
68 bit = pin_number - 31; 69 bit = pin_number - 31;
@@ -71,25 +72,23 @@ static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
71 72
72 value = cx_read(gpio_reg); 73 value = cx_read(gpio_reg);
73 74
74 if (pin_logic_value == 0) { 75 if (pin_logic_value == 0)
75 value &= Clear_GPIO_Bit(bit); 76 value &= Clear_GPIO_Bit(bit);
76 } else { 77 else
77 value |= Set_GPIO_Bit(bit); 78 value |= Set_GPIO_Bit(bit);
78 }
79 79
80 cx_write(gpio_reg, value); 80 cx_write(gpio_reg, value);
81} 81}
82 82
83void cx25821_gpio_init(struct cx25821_dev *dev) 83void cx25821_gpio_init(struct cx25821_dev *dev)
84{ 84{
85 if (dev == NULL) { 85 if (dev == NULL)
86 return; 86 return;
87 }
88 87
89 switch (dev->board) { 88 switch (dev->board) {
90 case CX25821_BOARD_CONEXANT_ATHENA10: 89 case CX25821_BOARD_CONEXANT_ATHENA10:
91 default: 90 default:
92 //set GPIO 5 to select the path for Medusa/Athena 91 /* set GPIO 5 to select the path for Medusa/Athena */
93 cx25821_set_gpiopin_logicvalue(dev, 5, 1); 92 cx25821_set_gpiopin_logicvalue(dev, 5, 1);
94 mdelay(20); 93 mdelay(20);
95 break; 94 break;
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
index f4f2681d8f1c..08f45b52df6a 100644
--- a/drivers/staging/cx25821/cx25821-i2c.c
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -28,7 +28,7 @@ static unsigned int i2c_debug;
28module_param(i2c_debug, int, 0644); 28module_param(i2c_debug, int, 0644);
29MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 29MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
30 30
31static unsigned int i2c_scan = 0; 31static unsigned int i2c_scan;
32module_param(i2c_scan, int, 0444); 32module_param(i2c_scan, int, 0444);
33MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); 33MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
34 34
@@ -159,9 +159,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
159 159
160 return msg->len; 160 return msg->len;
161 161
162 eio: 162eio:
163 retval = -EIO; 163 retval = -EIO;
164 err: 164err:
165 if (i2c_debug) 165 if (i2c_debug)
166 printk(KERN_ERR " ERR: %d\n", retval); 166 printk(KERN_ERR " ERR: %d\n", retval);
167 return retval; 167 return retval;
@@ -223,9 +223,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
223 } 223 }
224 224
225 return msg->len; 225 return msg->len;
226 eio: 226eio:
227 retval = -EIO; 227 retval = -EIO;
228 err: 228err:
229 if (i2c_debug) 229 if (i2c_debug)
230 printk(KERN_ERR " ERR: %d\n", retval); 230 printk(KERN_ERR " ERR: %d\n", retval);
231 return retval; 231 return retval;
@@ -266,7 +266,7 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
266 } 266 }
267 return num; 267 return num;
268 268
269 err: 269err:
270 return retval; 270 return retval;
271} 271}
272 272
@@ -319,7 +319,7 @@ int cx25821_i2c_register(struct cx25821_i2c *bus)
319 319
320 bus->i2c_client.adapter = &bus->i2c_adap; 320 bus->i2c_client.adapter = &bus->i2c_adap;
321 321
322 //set up the I2c 322 /* set up the I2c */
323 bus->i2c_client.addr = (0x88 >> 1); 323 bus->i2c_client.addr = (0x88 >> 1);
324 324
325 return bus->i2c_rc; 325 return bus->i2c_rc;
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index d6016200d699..34616dc507f9 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -24,11 +24,12 @@
24#include "cx25821-medusa-video.h" 24#include "cx25821-medusa-video.h"
25#include "cx25821-biffuncs.h" 25#include "cx25821-biffuncs.h"
26 26
27///////////////////////////////////////////////////////////////////////////////////////// 27/*
28//medusa_enable_bluefield_output() 28 * medusa_enable_bluefield_output()
29// 29 *
30// Enable the generation of blue filed output if no video 30 * Enable the generation of blue filed output if no video
31// 31 *
32 */
32static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel, 33static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
33 int enable) 34 int enable)
34{ 35{
@@ -73,15 +74,15 @@ static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
73 } 74 }
74 75
75 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp); 76 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
76 value &= 0xFFFFFF7F; // clear BLUE_FIELD_EN 77 value &= 0xFFFFFF7F; /* clear BLUE_FIELD_EN */
77 if (enable) 78 if (enable)
78 value |= 0x00000080; // set BLUE_FIELD_EN 79 value |= 0x00000080; /* set BLUE_FIELD_EN */
79 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value); 80 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
80 81
81 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp); 82 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
82 value &= 0xFFFFFF7F; 83 value &= 0xFFFFFF7F;
83 if (enable) 84 if (enable)
84 value |= 0x00000080; // set BLUE_FIELD_EN 85 value |= 0x00000080; /* set BLUE_FIELD_EN */
85 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value); 86 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
86} 87}
87 88
@@ -95,17 +96,18 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
95 mutex_lock(&dev->lock); 96 mutex_lock(&dev->lock);
96 97
97 for (i = 0; i < MAX_DECODERS; i++) { 98 for (i = 0; i < MAX_DECODERS; i++) {
98 // set video format NTSC-M 99 /* set video format NTSC-M */
99 value = 100 value =
100 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), 101 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
101 &tmp); 102 &tmp);
102 value &= 0xFFFFFFF0; 103 value &= 0xFFFFFFF0;
103 value |= 0x10001; // enable the fast locking mode bit[16] 104 /* enable the fast locking mode bit[16] */
105 value |= 0x10001;
104 ret_val = 106 ret_val =
105 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), 107 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
106 value); 108 value);
107 109
108 // resolution NTSC 720x480 110 /* resolution NTSC 720x480 */
109 value = 111 value =
110 cx25821_i2c_read(&dev->i2c_bus[0], 112 cx25821_i2c_read(&dev->i2c_bus[0],
111 HORIZ_TIM_CTRL + (0x200 * i), &tmp); 113 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
@@ -119,17 +121,17 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
119 cx25821_i2c_read(&dev->i2c_bus[0], 121 cx25821_i2c_read(&dev->i2c_bus[0],
120 VERT_TIM_CTRL + (0x200 * i), &tmp); 122 VERT_TIM_CTRL + (0x200 * i), &tmp);
121 value &= 0x00C00C00; 123 value &= 0x00C00C00;
122 value |= 0x1C1E001A; // vblank_cnt + 2 to get camera ID 124 value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */
123 ret_val = 125 ret_val =
124 cx25821_i2c_write(&dev->i2c_bus[0], 126 cx25821_i2c_write(&dev->i2c_bus[0],
125 VERT_TIM_CTRL + (0x200 * i), value); 127 VERT_TIM_CTRL + (0x200 * i), value);
126 128
127 // chroma subcarrier step size 129 /* chroma subcarrier step size */
128 ret_val = 130 ret_val =
129 cx25821_i2c_write(&dev->i2c_bus[0], 131 cx25821_i2c_write(&dev->i2c_bus[0],
130 SC_STEP_SIZE + (0x200 * i), 0x43E00000); 132 SC_STEP_SIZE + (0x200 * i), 0x43E00000);
131 133
132 // enable VIP optional active 134 /* enable VIP optional active */
133 value = 135 value =
134 cx25821_i2c_read(&dev->i2c_bus[0], 136 cx25821_i2c_read(&dev->i2c_bus[0],
135 OUT_CTRL_NS + (0x200 * i), &tmp); 137 OUT_CTRL_NS + (0x200 * i), &tmp);
@@ -139,7 +141,7 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
139 cx25821_i2c_write(&dev->i2c_bus[0], 141 cx25821_i2c_write(&dev->i2c_bus[0],
140 OUT_CTRL_NS + (0x200 * i), value); 142 OUT_CTRL_NS + (0x200 * i), value);
141 143
142 // enable VIP optional active (VIP_OPT_AL) for direct output. 144 /* enable VIP optional active (VIP_OPT_AL) for direct output. */
143 value = 145 value =
144 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), 146 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
145 &tmp); 147 &tmp);
@@ -149,19 +151,21 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
149 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), 151 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
150 value); 152 value);
151 153
152 // clear VPRES_VERT_EN bit, fixes the chroma run away problem 154 /*
153 // when the input switching rate < 16 fields 155 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
154 // 156 * when the input switching rate < 16 fields
157 */
155 value = 158 value =
156 cx25821_i2c_read(&dev->i2c_bus[0], 159 cx25821_i2c_read(&dev->i2c_bus[0],
157 MISC_TIM_CTRL + (0x200 * i), &tmp); 160 MISC_TIM_CTRL + (0x200 * i), &tmp);
158 value = setBitAtPos(value, 14); // disable special play detection 161 /* disable special play detection */
162 value = setBitAtPos(value, 14);
159 value = clearBitAtPos(value, 15); 163 value = clearBitAtPos(value, 15);
160 ret_val = 164 ret_val =
161 cx25821_i2c_write(&dev->i2c_bus[0], 165 cx25821_i2c_write(&dev->i2c_bus[0],
162 MISC_TIM_CTRL + (0x200 * i), value); 166 MISC_TIM_CTRL + (0x200 * i), value);
163 167
164 // set vbi_gate_en to 0 168 /* set vbi_gate_en to 0 */
165 value = 169 value =
166 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), 170 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
167 &tmp); 171 &tmp);
@@ -170,12 +174,12 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
170 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), 174 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
171 value); 175 value);
172 176
173 // Enable the generation of blue field output if no video 177 /* Enable the generation of blue field output if no video */
174 medusa_enable_bluefield_output(dev, i, 1); 178 medusa_enable_bluefield_output(dev, i, 1);
175 } 179 }
176 180
177 for (i = 0; i < MAX_ENCODERS; i++) { 181 for (i = 0; i < MAX_ENCODERS; i++) {
178 // NTSC hclock 182 /* NTSC hclock */
179 value = 183 value =
180 cx25821_i2c_read(&dev->i2c_bus[0], 184 cx25821_i2c_read(&dev->i2c_bus[0],
181 DENC_A_REG_1 + (0x100 * i), &tmp); 185 DENC_A_REG_1 + (0x100 * i), &tmp);
@@ -185,7 +189,7 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
185 cx25821_i2c_write(&dev->i2c_bus[0], 189 cx25821_i2c_write(&dev->i2c_bus[0],
186 DENC_A_REG_1 + (0x100 * i), value); 190 DENC_A_REG_1 + (0x100 * i), value);
187 191
188 // burst begin and burst end 192 /* burst begin and burst end */
189 value = 193 value =
190 cx25821_i2c_read(&dev->i2c_bus[0], 194 cx25821_i2c_read(&dev->i2c_bus[0],
191 DENC_A_REG_2 + (0x100 * i), &tmp); 195 DENC_A_REG_2 + (0x100 * i), &tmp);
@@ -204,7 +208,7 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
204 cx25821_i2c_write(&dev->i2c_bus[0], 208 cx25821_i2c_write(&dev->i2c_bus[0],
205 DENC_A_REG_3 + (0x100 * i), value); 209 DENC_A_REG_3 + (0x100 * i), value);
206 210
207 // set NTSC vblank, no phase alternation, 7.5 IRE pedestal 211 /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
208 value = 212 value =
209 cx25821_i2c_read(&dev->i2c_bus[0], 213 cx25821_i2c_read(&dev->i2c_bus[0],
210 DENC_A_REG_4 + (0x100 * i), &tmp); 214 DENC_A_REG_4 + (0x100 * i), &tmp);
@@ -227,17 +231,19 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev)
227 cx25821_i2c_write(&dev->i2c_bus[0], 231 cx25821_i2c_write(&dev->i2c_bus[0],
228 DENC_A_REG_6 + (0x100 * i), 0x009A89C1); 232 DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
229 233
230 // Subcarrier Increment 234 /* Subcarrier Increment */
231 ret_val = 235 ret_val =
232 cx25821_i2c_write(&dev->i2c_bus[0], 236 cx25821_i2c_write(&dev->i2c_bus[0],
233 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); 237 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
234 } 238 }
235 239
236 //set picture resolutions 240 /* set picture resolutions */
237 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720 241 /* 0 - 720 */
238 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 480 242 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
243 /* 0 - 480 */
244 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
239 245
240 // set Bypass input format to NTSC 525 lines 246 /* set Bypass input format to NTSC 525 lines */
241 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); 247 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
242 value |= 0x00080200; 248 value |= 0x00080200;
243 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); 249 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
@@ -252,7 +258,7 @@ static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
252 int ret_val = -1; 258 int ret_val = -1;
253 u32 value = 0, tmp = 0; 259 u32 value = 0, tmp = 0;
254 260
255 // Setup for 2D threshold 261 /* Setup for 2D threshold */
256 ret_val = 262 ret_val =
257 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec), 263 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
258 0x20002861); 264 0x20002861);
@@ -263,7 +269,7 @@ static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
263 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec), 269 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
264 0x200A1023); 270 0x200A1023);
265 271
266 // Setup flat chroma and luma thresholds 272 /* Setup flat chroma and luma thresholds */
267 value = 273 value =
268 cx25821_i2c_read(&dev->i2c_bus[0], 274 cx25821_i2c_read(&dev->i2c_bus[0],
269 COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); 275 COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
@@ -272,12 +278,12 @@ static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
272 cx25821_i2c_write(&dev->i2c_bus[0], 278 cx25821_i2c_write(&dev->i2c_bus[0],
273 COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); 279 COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
274 280
275 // set comb 2D blend 281 /* set comb 2D blend */
276 ret_val = 282 ret_val =
277 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec), 283 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
278 0x210F0F0F); 284 0x210F0F0F);
279 285
280 // COMB MISC CONTROL 286 /* COMB MISC CONTROL */
281 ret_val = 287 ret_val =
282 cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec), 288 cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
283 0x41120A7F); 289 0x41120A7F);
@@ -295,17 +301,18 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
295 mutex_lock(&dev->lock); 301 mutex_lock(&dev->lock);
296 302
297 for (i = 0; i < MAX_DECODERS; i++) { 303 for (i = 0; i < MAX_DECODERS; i++) {
298 // set video format PAL-BDGHI 304 /* set video format PAL-BDGHI */
299 value = 305 value =
300 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), 306 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
301 &tmp); 307 &tmp);
302 value &= 0xFFFFFFF0; 308 value &= 0xFFFFFFF0;
303 value |= 0x10004; // enable the fast locking mode bit[16] 309 /* enable the fast locking mode bit[16] */
310 value |= 0x10004;
304 ret_val = 311 ret_val =
305 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i), 312 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
306 value); 313 value);
307 314
308 // resolution PAL 720x576 315 /* resolution PAL 720x576 */
309 value = 316 value =
310 cx25821_i2c_read(&dev->i2c_bus[0], 317 cx25821_i2c_read(&dev->i2c_bus[0],
311 HORIZ_TIM_CTRL + (0x200 * i), &tmp); 318 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
@@ -315,22 +322,22 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
315 cx25821_i2c_write(&dev->i2c_bus[0], 322 cx25821_i2c_write(&dev->i2c_bus[0],
316 HORIZ_TIM_CTRL + (0x200 * i), value); 323 HORIZ_TIM_CTRL + (0x200 * i), value);
317 324
318 // vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 325 /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
319 value = 326 value =
320 cx25821_i2c_read(&dev->i2c_bus[0], 327 cx25821_i2c_read(&dev->i2c_bus[0],
321 VERT_TIM_CTRL + (0x200 * i), &tmp); 328 VERT_TIM_CTRL + (0x200 * i), &tmp);
322 value &= 0x00C00C00; 329 value &= 0x00C00C00;
323 value |= 0x28240026; // vblank_cnt + 2 to get camera ID 330 value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */
324 ret_val = 331 ret_val =
325 cx25821_i2c_write(&dev->i2c_bus[0], 332 cx25821_i2c_write(&dev->i2c_bus[0],
326 VERT_TIM_CTRL + (0x200 * i), value); 333 VERT_TIM_CTRL + (0x200 * i), value);
327 334
328 // chroma subcarrier step size 335 /* chroma subcarrier step size */
329 ret_val = 336 ret_val =
330 cx25821_i2c_write(&dev->i2c_bus[0], 337 cx25821_i2c_write(&dev->i2c_bus[0],
331 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); 338 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
332 339
333 // enable VIP optional active 340 /* enable VIP optional active */
334 value = 341 value =
335 cx25821_i2c_read(&dev->i2c_bus[0], 342 cx25821_i2c_read(&dev->i2c_bus[0],
336 OUT_CTRL_NS + (0x200 * i), &tmp); 343 OUT_CTRL_NS + (0x200 * i), &tmp);
@@ -340,7 +347,7 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
340 cx25821_i2c_write(&dev->i2c_bus[0], 347 cx25821_i2c_write(&dev->i2c_bus[0],
341 OUT_CTRL_NS + (0x200 * i), value); 348 OUT_CTRL_NS + (0x200 * i), value);
342 349
343 // enable VIP optional active (VIP_OPT_AL) for direct output. 350 /* enable VIP optional active (VIP_OPT_AL) for direct output. */
344 value = 351 value =
345 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), 352 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
346 &tmp); 353 &tmp);
@@ -350,18 +357,21 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
350 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i), 357 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
351 value); 358 value);
352 359
353 // clear VPRES_VERT_EN bit, fixes the chroma run away problem 360 /*
354 // when the input switching rate < 16 fields 361 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
362 * when the input switching rate < 16 fields
363 */
355 value = 364 value =
356 cx25821_i2c_read(&dev->i2c_bus[0], 365 cx25821_i2c_read(&dev->i2c_bus[0],
357 MISC_TIM_CTRL + (0x200 * i), &tmp); 366 MISC_TIM_CTRL + (0x200 * i), &tmp);
358 value = setBitAtPos(value, 14); // disable special play detection 367 /* disable special play detection */
368 value = setBitAtPos(value, 14);
359 value = clearBitAtPos(value, 15); 369 value = clearBitAtPos(value, 15);
360 ret_val = 370 ret_val =
361 cx25821_i2c_write(&dev->i2c_bus[0], 371 cx25821_i2c_write(&dev->i2c_bus[0],
362 MISC_TIM_CTRL + (0x200 * i), value); 372 MISC_TIM_CTRL + (0x200 * i), value);
363 373
364 // set vbi_gate_en to 0 374 /* set vbi_gate_en to 0 */
365 value = 375 value =
366 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i), 376 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
367 &tmp); 377 &tmp);
@@ -372,12 +382,12 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
372 382
373 medusa_PALCombInit(dev, i); 383 medusa_PALCombInit(dev, i);
374 384
375 // Enable the generation of blue field output if no video 385 /* Enable the generation of blue field output if no video */
376 medusa_enable_bluefield_output(dev, i, 1); 386 medusa_enable_bluefield_output(dev, i, 1);
377 } 387 }
378 388
379 for (i = 0; i < MAX_ENCODERS; i++) { 389 for (i = 0; i < MAX_ENCODERS; i++) {
380 // PAL hclock 390 /* PAL hclock */
381 value = 391 value =
382 cx25821_i2c_read(&dev->i2c_bus[0], 392 cx25821_i2c_read(&dev->i2c_bus[0],
383 DENC_A_REG_1 + (0x100 * i), &tmp); 393 DENC_A_REG_1 + (0x100 * i), &tmp);
@@ -387,7 +397,7 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
387 cx25821_i2c_write(&dev->i2c_bus[0], 397 cx25821_i2c_write(&dev->i2c_bus[0],
388 DENC_A_REG_1 + (0x100 * i), value); 398 DENC_A_REG_1 + (0x100 * i), value);
389 399
390 // burst begin and burst end 400 /* burst begin and burst end */
391 value = 401 value =
392 cx25821_i2c_read(&dev->i2c_bus[0], 402 cx25821_i2c_read(&dev->i2c_bus[0],
393 DENC_A_REG_2 + (0x100 * i), &tmp); 403 DENC_A_REG_2 + (0x100 * i), &tmp);
@@ -397,7 +407,7 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
397 cx25821_i2c_write(&dev->i2c_bus[0], 407 cx25821_i2c_write(&dev->i2c_bus[0],
398 DENC_A_REG_2 + (0x100 * i), value); 408 DENC_A_REG_2 + (0x100 * i), value);
399 409
400 // hblank and vactive 410 /* hblank and vactive */
401 value = 411 value =
402 cx25821_i2c_read(&dev->i2c_bus[0], 412 cx25821_i2c_read(&dev->i2c_bus[0],
403 DENC_A_REG_3 + (0x100 * i), &tmp); 413 DENC_A_REG_3 + (0x100 * i), &tmp);
@@ -407,7 +417,7 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
407 cx25821_i2c_write(&dev->i2c_bus[0], 417 cx25821_i2c_write(&dev->i2c_bus[0],
408 DENC_A_REG_3 + (0x100 * i), value); 418 DENC_A_REG_3 + (0x100 * i), value);
409 419
410 // set PAL vblank, phase alternation, 0 IRE pedestal 420 /* set PAL vblank, phase alternation, 0 IRE pedestal */
411 value = 421 value =
412 cx25821_i2c_read(&dev->i2c_bus[0], 422 cx25821_i2c_read(&dev->i2c_bus[0],
413 DENC_A_REG_4 + (0x100 * i), &tmp); 423 DENC_A_REG_4 + (0x100 * i), &tmp);
@@ -430,17 +440,19 @@ static int medusa_initialize_pal(struct cx25821_dev *dev)
430 cx25821_i2c_write(&dev->i2c_bus[0], 440 cx25821_i2c_write(&dev->i2c_bus[0],
431 DENC_A_REG_6 + (0x100 * i), 0x00A493CF); 441 DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
432 442
433 // Subcarrier Increment 443 /* Subcarrier Increment */
434 ret_val = 444 ret_val =
435 cx25821_i2c_write(&dev->i2c_bus[0], 445 cx25821_i2c_write(&dev->i2c_bus[0],
436 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); 446 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
437 } 447 }
438 448
439 //set picture resolutions 449 /* set picture resolutions */
440 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720 450 /* 0 - 720 */
441 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 576 451 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
452 /* 0 - 576 */
453 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
442 454
443 // set Bypass input format to PAL 625 lines 455 /* set Bypass input format to PAL 625 lines */
444 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); 456 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
445 value &= 0xFFF7FDFF; 457 value &= 0xFFF7FDFF;
446 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); 458 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
@@ -455,18 +467,17 @@ int medusa_set_videostandard(struct cx25821_dev *dev)
455 int status = STATUS_SUCCESS; 467 int status = STATUS_SUCCESS;
456 u32 value = 0, tmp = 0; 468 u32 value = 0, tmp = 0;
457 469
458 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) { 470 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
459 status = medusa_initialize_pal(dev); 471 status = medusa_initialize_pal(dev);
460 } else { 472 else
461 status = medusa_initialize_ntsc(dev); 473 status = medusa_initialize_ntsc(dev);
462 }
463 474
464 // Enable DENC_A output 475 /* Enable DENC_A output */
465 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp); 476 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
466 value = setBitAtPos(value, 4); 477 value = setBitAtPos(value, 4);
467 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value); 478 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
468 479
469 // Enable DENC_B output 480 /* Enable DENC_B output */
470 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp); 481 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
471 value = setBitAtPos(value, 4); 482 value = setBitAtPos(value, 4);
472 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value); 483 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
@@ -486,10 +497,10 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
486 497
487 mutex_lock(&dev->lock); 498 mutex_lock(&dev->lock);
488 499
489 // validate the width - cannot be negative 500 /* validate the width - cannot be negative */
490 if (width > MAX_WIDTH) { 501 if (width > MAX_WIDTH) {
491 printk 502 printk
492 ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n", 503 ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
493 __func__, width, MAX_WIDTH); 504 __func__, width, MAX_WIDTH);
494 width = MAX_WIDTH; 505 width = MAX_WIDTH;
495 } 506 }
@@ -523,14 +534,14 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
523 vscale = 0x1E00; 534 vscale = 0x1E00;
524 break; 535 break;
525 536
526 default: //720 537 default: /* 720 */
527 hscale = 0x0; 538 hscale = 0x0;
528 vscale = 0x0; 539 vscale = 0x0;
529 break; 540 break;
530 } 541 }
531 542
532 for (; decoder < decoder_count; decoder++) { 543 for (; decoder < decoder_count; decoder++) {
533 // write scaling values for each decoder 544 /* write scaling values for each decoder */
534 ret_val = 545 ret_val =
535 cx25821_i2c_write(&dev->i2c_bus[0], 546 cx25821_i2c_write(&dev->i2c_bus[0],
536 HSCALE_CTRL + (0x200 * decoder), hscale); 547 HSCALE_CTRL + (0x200 * decoder), hscale);
@@ -552,7 +563,7 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
552 563
553 mutex_lock(&dev->lock); 564 mutex_lock(&dev->lock);
554 565
555 // no support 566 /* no support */
556 if (decoder < VDEC_A && decoder > VDEC_H) { 567 if (decoder < VDEC_A && decoder > VDEC_H) {
557 mutex_unlock(&dev->lock); 568 mutex_unlock(&dev->lock);
558 return; 569 return;
@@ -577,11 +588,10 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
577 588
578 _display_field_cnt[decoder] = duration; 589 _display_field_cnt[decoder] = duration;
579 590
580 // update hardware 591 /* update hardware */
581 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); 592 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
582 593
583 if (!(decoder % 2)) // EVEN decoder 594 if (!(decoder % 2)) { /* EVEN decoder */
584 {
585 fld_cnt &= 0xFFFF0000; 595 fld_cnt &= 0xFFFF0000;
586 fld_cnt |= duration; 596 fld_cnt |= duration;
587 } else { 597 } else {
@@ -594,8 +604,7 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
594 mutex_unlock(&dev->lock); 604 mutex_unlock(&dev->lock);
595} 605}
596 606
597///////////////////////////////////////////////////////////////////////////////////////// 607/* Map to Medusa register setting */
598// Map to Medusa register setting
599static int mapM(int srcMin, 608static int mapM(int srcMin,
600 int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal) 609 int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
601{ 610{
@@ -603,20 +612,21 @@ static int mapM(int srcMin,
603 int denominator; 612 int denominator;
604 int quotient; 613 int quotient;
605 614
606 if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) { 615 if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
607 return -1; 616 return -1;
608 } 617 /*
609 // This is the overall expression used: 618 * This is the overall expression used:
610 // *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin; 619 * *dstVal =
611 // but we need to account for rounding so below we use the modulus 620 * (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
612 // operator to find the remainder and increment if necessary. 621 * but we need to account for rounding so below we use the modulus
622 * operator to find the remainder and increment if necessary.
623 */
613 numerator = (srcVal - srcMin) * (dstMax - dstMin); 624 numerator = (srcVal - srcMin) * (dstMax - dstMin);
614 denominator = srcMax - srcMin; 625 denominator = srcMax - srcMin;
615 quotient = numerator / denominator; 626 quotient = numerator / denominator;
616 627
617 if (2 * (numerator % denominator) >= denominator) { 628 if (2 * (numerator % denominator) >= denominator)
618 quotient++; 629 quotient++;
619 }
620 630
621 *dstVal = quotient + dstMin; 631 *dstVal = quotient + dstMin;
622 632
@@ -636,7 +646,6 @@ static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
636 } 646 }
637} 647}
638 648
639/////////////////////////////////////////////////////////////////////////////////////////
640int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) 649int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
641{ 650{
642 int ret_val = 0; 651 int ret_val = 0;
@@ -665,7 +674,6 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
665 return ret_val; 674 return ret_val;
666} 675}
667 676
668/////////////////////////////////////////////////////////////////////////////////////////
669int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) 677int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
670{ 678{
671 int ret_val = 0; 679 int ret_val = 0;
@@ -695,7 +703,6 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
695 return ret_val; 703 return ret_val;
696} 704}
697 705
698/////////////////////////////////////////////////////////////////////////////////////////
699int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) 706int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
700{ 707{
701 int ret_val = 0; 708 int ret_val = 0;
@@ -727,7 +734,6 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
727 return ret_val; 734 return ret_val;
728} 735}
729 736
730/////////////////////////////////////////////////////////////////////////////////////////
731int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) 737int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
732{ 738{
733 int ret_val = 0; 739 int ret_val = 0;
@@ -768,98 +774,90 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
768 return ret_val; 774 return ret_val;
769} 775}
770 776
771///////////////////////////////////////////////////////////////////////////////////////// 777/* Program the display sequence and monitor output. */
772// Program the display sequence and monitor output. 778
773//
774int medusa_video_init(struct cx25821_dev *dev) 779int medusa_video_init(struct cx25821_dev *dev)
775{ 780{
776 u32 value = 0, tmp = 0; 781 u32 value, tmp = 0;
777 int ret_val = 0; 782 int ret_val;
778 int i = 0; 783 int i;
779 784
780 mutex_lock(&dev->lock); 785 mutex_lock(&dev->lock);
781 786
782 _num_decoders = dev->_max_num_decoders; 787 _num_decoders = dev->_max_num_decoders;
783 788
784 // disable Auto source selection on all video decoders 789 /* disable Auto source selection on all video decoders */
785 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); 790 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
786 value &= 0xFFFFF0FF; 791 value &= 0xFFFFF0FF;
787 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); 792 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
793 if (ret_val < 0)
794 goto error;
788 795
789 if (ret_val < 0) { 796 /* Turn off Master source switch enable */
790 mutex_unlock(&dev->lock);
791 return -EINVAL;
792 }
793 // Turn off Master source switch enable
794 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); 797 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
795 value &= 0xFFFFFFDF; 798 value &= 0xFFFFFFDF;
796 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); 799 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
797
798 if (ret_val < 0) 800 if (ret_val < 0)
799 return -EINVAL; 801 goto error;
800 802
801 mutex_unlock(&dev->lock); 803 mutex_unlock(&dev->lock);
802 804
803 for (i = 0; i < _num_decoders; i++) { 805 for (i = 0; i < _num_decoders; i++)
804 medusa_set_decoderduration(dev, i, _display_field_cnt[i]); 806 medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
805 }
806 807
807 mutex_lock(&dev->lock); 808 mutex_lock(&dev->lock);
808 809
809 // Select monitor as DENC A input, power up the DAC 810 /* Select monitor as DENC A input, power up the DAC */
810 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); 811 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
811 value &= 0xFF70FF70; 812 value &= 0xFF70FF70;
812 value |= 0x00090008; // set en_active 813 value |= 0x00090008; /* set en_active */
813 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value); 814 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
815 if (ret_val < 0)
816 goto error;
814 817
815 if (ret_val < 0) { 818 /* enable input is VIP/656 */
816 mutex_unlock(&dev->lock);
817 return -EINVAL;
818 }
819 // enable input is VIP/656
820 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); 819 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
821 value |= 0x00040100; // enable VIP 820 value |= 0x00040100; /* enable VIP */
822 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); 821 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
823 822
824 if (ret_val < 0) { 823 if (ret_val < 0)
825 mutex_unlock(&dev->lock); 824 goto error;
826 return -EINVAL; 825
827 } 826 /* select AFE clock to output mode */
828 // select AFE clock to output mode
829 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); 827 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
830 value &= 0x83FFFFFF; 828 value &= 0x83FFFFFF;
831 ret_val = 829 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
832 cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, 830 value | 0x10000000);
833 value | 0x10000000); 831 if (ret_val < 0)
832 goto error;
834 833
835 if (ret_val < 0) { 834 /* Turn on all of the data out and control output pins. */
836 mutex_unlock(&dev->lock);
837 return -EINVAL;
838 }
839 // Turn on all of the data out and control output pins.
840 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp); 835 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
841 value &= 0xFEF0FE00; 836 value &= 0xFEF0FE00;
842 if (_num_decoders == MAX_DECODERS) { 837 if (_num_decoders == MAX_DECODERS) {
843 // Note: The octal board does not support control pins(bit16-19). 838 /*
844 // These bits are ignored in the octal board. 839 * Note: The octal board does not support control pins(bit16-19)
845 value |= 0x010001F8; // disable VDEC A-C port, default to Mobilygen Interface 840 * These bits are ignored in the octal board.
841 *
842 * disable VDEC A-C port, default to Mobilygen Interface
843 */
844 value |= 0x010001F8;
846 } else { 845 } else {
847 value |= 0x010F0108; // disable VDEC A-C port, default to Mobilygen Interface 846 /* disable VDEC A-C port, default to Mobilygen Interface */
847 value |= 0x010F0108;
848 } 848 }
849 849
850 value |= 7; 850 value |= 7;
851 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value); 851 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
852 if (ret_val < 0) { 852 if (ret_val < 0)
853 mutex_unlock(&dev->lock); 853 goto error;
854 return -EINVAL;
855 }
856 854
857 mutex_unlock(&dev->lock); 855 mutex_unlock(&dev->lock);
858 856
859 ret_val = medusa_set_videostandard(dev); 857 ret_val = medusa_set_videostandard(dev);
858 return ret_val;
860 859
861 if (ret_val < 0) 860error:
862 return -EINVAL; 861 mutex_unlock(&dev->lock);
863 862 return ret_val;
864 return 1;
865} 863}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
index 6d48a1e26d1b..c842d8f3d692 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -32,7 +32,7 @@
32#include <linux/file.h> 32#include <linux/file.h>
33#include <linux/fcntl.h> 33#include <linux/fcntl.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <asm/uaccess.h> 35#include <linux/uaccess.h>
36 36
37MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); 37MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
38MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); 38MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
@@ -60,9 +60,8 @@ int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
60 cdt = ch->cdt; 60 cdt = ch->cdt;
61 lines = ch->fifo_size / bpl; 61 lines = ch->fifo_size / bpl;
62 62
63 if (lines > 4) { 63 if (lines > 4)
64 lines = 4; 64 lines = 4;
65 }
66 65
67 BUG_ON(lines < 2); 66 BUG_ON(lines < 2);
68 67
@@ -97,7 +96,7 @@ int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
97} 96}
98 97
99static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, 98static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
100 __le32 * rp, unsigned int offset, 99 __le32 *rp, unsigned int offset,
101 unsigned int bpl, u32 sync_line, 100 unsigned int bpl, u32 sync_line,
102 unsigned int lines, int fifo_enable, 101 unsigned int lines, int fifo_enable,
103 int field_type) 102 int field_type)
@@ -108,9 +107,8 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
108 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); 107 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
109 108
110 if (USE_RISC_NOOP_VIDEO) { 109 if (USE_RISC_NOOP_VIDEO) {
111 for (i = 0; i < NUM_NO_OPS; i++) { 110 for (i = 0; i < NUM_NO_OPS; i++)
112 *(rp++) = cpu_to_le32(RISC_NOOP); 111 *(rp++) = cpu_to_le32(RISC_NOOP);
113 }
114 } 112 }
115 113
116 /* scan lines */ 114 /* scan lines */
@@ -140,14 +138,12 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
140 int dist_betwn_starts = bpl * 2; 138 int dist_betwn_starts = bpl * 2;
141 139
142 /* sync instruction */ 140 /* sync instruction */
143 if (sync_line != NO_SYNC_LINE) { 141 if (sync_line != NO_SYNC_LINE)
144 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); 142 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
145 }
146 143
147 if (USE_RISC_NOOP_VIDEO) { 144 if (USE_RISC_NOOP_VIDEO) {
148 for (i = 0; i < NUM_NO_OPS; i++) { 145 for (i = 0; i < NUM_NO_OPS; i++)
149 *(rp++) = cpu_to_le32(RISC_NOOP); 146 *(rp++) = cpu_to_le32(RISC_NOOP);
150 }
151 } 147 }
152 148
153 /* scan lines */ 149 /* scan lines */
@@ -157,12 +153,13 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
157 *(rp++) = cpu_to_le32(0); /* bits 63-32 */ 153 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
158 154
159 if ((lines <= NTSC_FIELD_HEIGHT) 155 if ((lines <= NTSC_FIELD_HEIGHT)
160 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) { 156 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC))
161 offset += dist_betwn_starts; //to skip the other field line 157 /* to skip the other field line */
162 } 158 offset += dist_betwn_starts;
163 159
164 // check if we need to enable the FIFO after the first 4 lines 160 /* check if we need to enable the FIFO after the first 4 lines
165 // For the upstream video channel, the risc engine will enable the FIFO. 161 * For the upstream video channel, the risc engine will enable
162 * the FIFO. */
166 if (fifo_enable && line == 3) { 163 if (fifo_enable && line == 3) {
167 *(rp++) = RISC_WRITECR; 164 *(rp++) = RISC_WRITECR;
168 *(rp++) = sram_ch->dma_ctl; 165 *(rp++) = sram_ch->dma_ctl;
@@ -181,7 +178,8 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
181{ 178{
182 __le32 *rp; 179 __le32 *rp;
183 int fifo_enable = 0; 180 int fifo_enable = 0;
184 int singlefield_lines = lines >> 1; //get line count for single field 181 /* get line count for single field */
182 int singlefield_lines = lines >> 1;
185 int odd_num_lines = singlefield_lines; 183 int odd_num_lines = singlefield_lines;
186 int frame = 0; 184 int frame = 0;
187 int frame_size = 0; 185 int frame_size = 0;
@@ -225,7 +223,7 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
225 223
226 fifo_enable = FIFO_DISABLE; 224 fifo_enable = FIFO_DISABLE;
227 225
228 //Even Field 226 /* Even Field */
229 rp = cx25821_risc_field_upstream(dev, rp, 227 rp = cx25821_risc_field_upstream(dev, rp,
230 dev->_data_buf_phys_addr + 228 dev->_data_buf_phys_addr +
231 databuf_offset, bottom_offset, 229 databuf_offset, bottom_offset,
@@ -241,7 +239,9 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
241 risc_flag = RISC_CNT_INC; 239 risc_flag = RISC_CNT_INC;
242 } 240 }
243 241
244 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ 242 /* Loop to 2ndFrameRISC or to Start of Risc
243 * program & generate IRQ
244 */
245 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); 245 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
246 *(rp++) = cpu_to_le32(risc_phys_jump_addr); 246 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
247 *(rp++) = cpu_to_le32(0); 247 *(rp++) = cpu_to_le32(0);
@@ -258,18 +258,18 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
258 258
259 if (!dev->_is_running) { 259 if (!dev->_is_running) {
260 printk 260 printk
261 ("cx25821: No video file is currently running so return!\n"); 261 (KERN_INFO "cx25821: No video file is currently running so return!\n");
262 return; 262 return;
263 } 263 }
264 //Disable RISC interrupts 264 /* Disable RISC interrupts */
265 tmp = cx_read(sram_ch->int_msk); 265 tmp = cx_read(sram_ch->int_msk);
266 cx_write(sram_ch->int_msk, tmp & ~_intr_msk); 266 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
267 267
268 //Turn OFF risc and fifo enable 268 /* Turn OFF risc and fifo enable */
269 tmp = cx_read(sram_ch->dma_ctl); 269 tmp = cx_read(sram_ch->dma_ctl);
270 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); 270 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
271 271
272 //Clear data buffer memory 272 /* Clear data buffer memory */
273 if (dev->_data_buf_virt_addr) 273 if (dev->_data_buf_virt_addr)
274 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); 274 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
275 275
@@ -292,9 +292,8 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
292 292
293void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev) 293void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
294{ 294{
295 if (dev->_is_running) { 295 if (dev->_is_running)
296 cx25821_stop_upstream_video_ch1(dev); 296 cx25821_stop_upstream_video_ch1(dev);
297 }
298 297
299 if (dev->_dma_virt_addr) { 298 if (dev->_dma_virt_addr) {
300 pci_free_consistent(dev->pci, dev->_risc_size, 299 pci_free_consistent(dev->pci, dev->_risc_size,
@@ -347,19 +346,19 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
347 346
348 if (IS_ERR(myfile)) { 347 if (IS_ERR(myfile)) {
349 const int open_errno = -PTR_ERR(myfile); 348 const int open_errno = -PTR_ERR(myfile);
350 printk("%s(): ERROR opening file(%s) with errno = %d! \n", 349 printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
351 __func__, dev->_filename, open_errno); 350 __func__, dev->_filename, open_errno);
352 return PTR_ERR(myfile); 351 return PTR_ERR(myfile);
353 } else { 352 } else {
354 if (!(myfile->f_op)) { 353 if (!(myfile->f_op)) {
355 printk("%s: File has no file operations registered!", 354 printk(KERN_ERR "%s: File has no file operations registered!",
356 __func__); 355 __func__);
357 filp_close(myfile, NULL); 356 filp_close(myfile, NULL);
358 return -EIO; 357 return -EIO;
359 } 358 }
360 359
361 if (!myfile->f_op->read) { 360 if (!myfile->f_op->read) {
362 printk("%s: File has no READ operations registered!", 361 printk(KERN_ERR "%s: File has no READ operations registered!",
363 __func__); 362 __func__);
364 filp_close(myfile, NULL); 363 filp_close(myfile, NULL);
365 return -EIO; 364 return -EIO;
@@ -412,7 +411,7 @@ static void cx25821_vidups_handler(struct work_struct *work)
412 container_of(work, struct cx25821_dev, _irq_work_entry); 411 container_of(work, struct cx25821_dev, _irq_work_entry);
413 412
414 if (!dev) { 413 if (!dev) {
415 printk("ERROR %s(): since container_of(work_struct) FAILED! \n", 414 printk(KERN_ERR "ERROR %s(): since container_of(work_struct) FAILED!\n",
416 __func__); 415 __func__);
417 return; 416 return;
418 } 417 }
@@ -438,12 +437,12 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
438 437
439 if (IS_ERR(myfile)) { 438 if (IS_ERR(myfile)) {
440 const int open_errno = -PTR_ERR(myfile); 439 const int open_errno = -PTR_ERR(myfile);
441 printk("%s(): ERROR opening file(%s) with errno = %d! \n", 440 printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
442 __func__, dev->_filename, open_errno); 441 __func__, dev->_filename, open_errno);
443 return PTR_ERR(myfile); 442 return PTR_ERR(myfile);
444 } else { 443 } else {
445 if (!(myfile->f_op)) { 444 if (!(myfile->f_op)) {
446 printk("%s: File has no file operations registered!", 445 printk(KERN_ERR "%s: File has no file operations registered!",
447 __func__); 446 __func__);
448 filp_close(myfile, NULL); 447 filp_close(myfile, NULL);
449 return -EIO; 448 return -EIO;
@@ -451,7 +450,7 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
451 450
452 if (!myfile->f_op->read) { 451 if (!myfile->f_op->read) {
453 printk 452 printk
454 ("%s: File has no READ operations registered! Returning.", 453 (KERN_ERR "%s: File has no READ operations registered! Returning.",
455 __func__); 454 __func__);
456 filp_close(myfile, NULL); 455 filp_close(myfile, NULL);
457 return -EIO; 456 return -EIO;
@@ -490,9 +489,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
490 if (i > 0) 489 if (i > 0)
491 dev->_frame_count++; 490 dev->_frame_count++;
492 491
493 if (vfs_read_retval < line_size) { 492 if (vfs_read_retval < line_size)
494 break; 493 break;
495 }
496 } 494 }
497 495
498 dev->_file_status = 496 dev->_file_status =
@@ -528,11 +526,11 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
528 526
529 if (!dev->_dma_virt_addr) { 527 if (!dev->_dma_virt_addr) {
530 printk 528 printk
531 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n"); 529 (KERN_ERR "cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
532 return -ENOMEM; 530 return -ENOMEM;
533 } 531 }
534 532
535 //Clear memory at address 533 /* Clear memory at address */
536 memset(dev->_dma_virt_addr, 0, dev->_risc_size); 534 memset(dev->_dma_virt_addr, 0, dev->_risc_size);
537 535
538 if (dev->_data_buf_virt_addr != NULL) { 536 if (dev->_data_buf_virt_addr != NULL) {
@@ -540,7 +538,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
540 dev->_data_buf_virt_addr, 538 dev->_data_buf_virt_addr,
541 dev->_data_buf_phys_addr); 539 dev->_data_buf_phys_addr);
542 } 540 }
543 //For Video Data buffer allocation 541 /* For Video Data buffer allocation */
544 dev->_data_buf_virt_addr = 542 dev->_data_buf_virt_addr =
545 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size, 543 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
546 &data_dma_addr); 544 &data_dma_addr);
@@ -549,30 +547,30 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
549 547
550 if (!dev->_data_buf_virt_addr) { 548 if (!dev->_data_buf_virt_addr) {
551 printk 549 printk
552 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n"); 550 (KERN_ERR "cx25821: FAILED to allocate memory for data buffer! Returning.\n");
553 return -ENOMEM; 551 return -ENOMEM;
554 } 552 }
555 553
556 //Clear memory at address 554 /* Clear memory at address */
557 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); 555 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
558 556
559 ret = cx25821_openfile(dev, sram_ch); 557 ret = cx25821_openfile(dev, sram_ch);
560 if (ret < 0) 558 if (ret < 0)
561 return ret; 559 return ret;
562 560
563 //Create RISC programs 561 /* Create RISC programs */
564 ret = 562 ret =
565 cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, 563 cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
566 dev->_lines_count); 564 dev->_lines_count);
567 if (ret < 0) { 565 if (ret < 0) {
568 printk(KERN_INFO 566 printk(KERN_INFO
569 "cx25821: Failed creating Video Upstream Risc programs! \n"); 567 "cx25821: Failed creating Video Upstream Risc programs!\n");
570 goto error; 568 goto error;
571 } 569 }
572 570
573 return 0; 571 return 0;
574 572
575 error: 573error:
576 return ret; 574 return ret;
577} 575}
578 576
@@ -588,10 +586,11 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
588 __le32 *rp; 586 __le32 *rp;
589 587
590 if (status & FLD_VID_SRC_RISC1) { 588 if (status & FLD_VID_SRC_RISC1) {
591 // We should only process one program per call 589 /* We should only process one program per call */
592 u32 prog_cnt = cx_read(channel->gpcnt); 590 u32 prog_cnt = cx_read(channel->gpcnt);
593 591
594 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers 592 /* Since we've identified our IRQ, clear our bits from the
593 * interrupt mask and interrupt status registers */
595 int_msk_tmp = cx_read(channel->int_msk); 594 int_msk_tmp = cx_read(channel->int_msk);
596 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); 595 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
597 cx_write(channel->int_stat, _intr_msk); 596 cx_write(channel->int_stat, _intr_msk);
@@ -632,7 +631,7 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
632 FIFO_DISABLE, 631 FIFO_DISABLE,
633 ODD_FIELD); 632 ODD_FIELD);
634 633
635 // Jump to Even Risc program of 1st Frame 634 /* Jump to Even Risc program of 1st Frame */
636 *(rp++) = cpu_to_le32(RISC_JUMP); 635 *(rp++) = cpu_to_le32(RISC_JUMP);
637 *(rp++) = cpu_to_le32(risc_phys_jump_addr); 636 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
638 *(rp++) = cpu_to_le32(0); 637 *(rp++) = cpu_to_le32(0);
@@ -643,24 +642,24 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
643 } else { 642 } else {
644 if (status & FLD_VID_SRC_UF) 643 if (status & FLD_VID_SRC_UF)
645 printk 644 printk
646 ("%s: Video Received Underflow Error Interrupt!\n", 645 (KERN_ERR "%s: Video Received Underflow Error Interrupt!\n",
647 __func__); 646 __func__);
648 647
649 if (status & FLD_VID_SRC_SYNC) 648 if (status & FLD_VID_SRC_SYNC)
650 printk("%s: Video Received Sync Error Interrupt!\n", 649 printk(KERN_ERR "%s: Video Received Sync Error Interrupt!\n",
651 __func__); 650 __func__);
652 651
653 if (status & FLD_VID_SRC_OPC_ERR) 652 if (status & FLD_VID_SRC_OPC_ERR)
654 printk("%s: Video Received OpCode Error Interrupt!\n", 653 printk(KERN_ERR "%s: Video Received OpCode Error Interrupt!\n",
655 __func__); 654 __func__);
656 } 655 }
657 656
658 if (dev->_file_status == END_OF_FILE) { 657 if (dev->_file_status == END_OF_FILE) {
659 printk("cx25821: EOF Channel 1 Framecount = %d\n", 658 printk(KERN_ERR "cx25821: EOF Channel 1 Framecount = %d\n",
660 dev->_frame_count); 659 dev->_frame_count);
661 return -1; 660 return -1;
662 } 661 }
663 //ElSE, set the interrupt mask register, re-enable irq. 662 /* ElSE, set the interrupt mask register, re-enable irq. */
664 int_msk_tmp = cx_read(channel->int_msk); 663 int_msk_tmp = cx_read(channel->int_msk);
665 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); 664 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
666 665
@@ -685,17 +684,16 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
685 msk_stat = cx_read(sram_ch->int_mstat); 684 msk_stat = cx_read(sram_ch->int_mstat);
686 vid_status = cx_read(sram_ch->int_stat); 685 vid_status = cx_read(sram_ch->int_stat);
687 686
688 // Only deal with our interrupt 687 /* Only deal with our interrupt */
689 if (vid_status) { 688 if (vid_status) {
690 handled = 689 handled =
691 cx25821_video_upstream_irq(dev, channel_num, vid_status); 690 cx25821_video_upstream_irq(dev, channel_num, vid_status);
692 } 691 }
693 692
694 if (handled < 0) { 693 if (handled < 0)
695 cx25821_stop_upstream_video_ch1(dev); 694 cx25821_stop_upstream_video_ch1(dev);
696 } else { 695 else
697 handled += handled; 696 handled += handled;
698 }
699 697
700 return IRQ_RETVAL(handled); 698 return IRQ_RETVAL(handled);
701} 699}
@@ -714,19 +712,19 @@ void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
714 value |= dev->_isNTSC ? 0 : 0x10; 712 value |= dev->_isNTSC ? 0 : 0x10;
715 cx_write(ch->vid_fmt_ctl, value); 713 cx_write(ch->vid_fmt_ctl, value);
716 714
717 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format 715 /* set number of active pixels in each line.
716 * Default is 720 pixels in both NTSC and PAL format */
718 cx_write(ch->vid_active_ctl1, width); 717 cx_write(ch->vid_active_ctl1, width);
719 718
720 num_lines = (height / 2) & 0x3FF; 719 num_lines = (height / 2) & 0x3FF;
721 odd_num_lines = num_lines; 720 odd_num_lines = num_lines;
722 721
723 if (dev->_isNTSC) { 722 if (dev->_isNTSC)
724 odd_num_lines += 1; 723 odd_num_lines += 1;
725 }
726 724
727 value = (num_lines << 16) | odd_num_lines; 725 value = (num_lines << 16) | odd_num_lines;
728 726
729 // set number of active lines in field 0 (top) and field 1 (bottom) 727 /* set number of active lines in field 0 (top) and field 1 (bottom) */
730 cx_write(ch->vid_active_ctl2, value); 728 cx_write(ch->vid_active_ctl2, value);
731 729
732 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); 730 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
@@ -738,21 +736,26 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
738 u32 tmp = 0; 736 u32 tmp = 0;
739 int err = 0; 737 int err = 0;
740 738
741 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C 739 /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
740 * channel A-C
741 */
742 tmp = cx_read(VID_CH_MODE_SEL); 742 tmp = cx_read(VID_CH_MODE_SEL);
743 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); 743 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
744 744
745 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds. 745 /* Set the physical start address of the RISC program in the initial
746 * program counter(IPC) member of the cmds.
747 */
746 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr); 748 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
747 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ 749 /* Risc IPC High 64 bits 63-32 */
750 cx_write(sram_ch->cmds_start + 4, 0);
748 751
749 /* reset counter */ 752 /* reset counter */
750 cx_write(sram_ch->gpcnt_ctl, 3); 753 cx_write(sram_ch->gpcnt_ctl, 3);
751 754
752 // Clear our bits from the interrupt status register. 755 /* Clear our bits from the interrupt status register. */
753 cx_write(sram_ch->int_stat, _intr_msk); 756 cx_write(sram_ch->int_stat, _intr_msk);
754 757
755 //Set the interrupt mask register, enable irq. 758 /* Set the interrupt mask register, enable irq. */
756 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); 759 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
757 tmp = cx_read(sram_ch->int_msk); 760 tmp = cx_read(sram_ch->int_msk);
758 cx_write(sram_ch->int_msk, tmp |= _intr_msk); 761 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
@@ -766,7 +769,7 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
766 goto fail_irq; 769 goto fail_irq;
767 } 770 }
768 771
769 // Start the DMA engine 772 /* Start the DMA engine */
770 tmp = cx_read(sram_ch->dma_ctl); 773 tmp = cx_read(sram_ch->dma_ctl);
771 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); 774 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
772 775
@@ -775,7 +778,7 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
775 778
776 return 0; 779 return 0;
777 780
778 fail_irq: 781fail_irq:
779 cx25821_dev_unregister(dev); 782 cx25821_dev_unregister(dev);
780 return err; 783 return err;
781} 784}
@@ -792,7 +795,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
792 int str_length = 0; 795 int str_length = 0;
793 796
794 if (dev->_is_running) { 797 if (dev->_is_running) {
795 printk("Video Channel is still running so return!\n"); 798 printk(KERN_INFO "Video Channel is still running so return!\n");
796 return 0; 799 return 0;
797 } 800 }
798 801
@@ -804,10 +807,12 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
804 807
805 if (!dev->_irq_queues) { 808 if (!dev->_irq_queues) {
806 printk 809 printk
807 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n"); 810 (KERN_ERR "cx25821: create_singlethread_workqueue() for Video FAILED!\n");
808 return -ENOMEM; 811 return -ENOMEM;
809 } 812 }
810 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C 813 /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
814 * channel A-C
815 */
811 tmp = cx_read(VID_CH_MODE_SEL); 816 tmp = cx_read(VID_CH_MODE_SEL);
812 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); 817 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
813 818
@@ -841,7 +846,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
841 memcpy(dev->_filename, dev->_defaultname, str_length + 1); 846 memcpy(dev->_filename, dev->_defaultname, str_length + 1);
842 } 847 }
843 848
844 //Default if filename is empty string 849 /* Default if filename is empty string */
845 if (strcmp(dev->input_filename, "") == 0) { 850 if (strcmp(dev->input_filename, "") == 0) {
846 if (dev->_isNTSC) { 851 if (dev->_isNTSC) {
847 dev->_filename = 852 dev->_filename =
@@ -875,7 +880,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
875 dev->upstream_riscbuf_size = risc_buffer_size * 2; 880 dev->upstream_riscbuf_size = risc_buffer_size * 2;
876 dev->upstream_databuf_size = data_frame_size * 2; 881 dev->upstream_databuf_size = data_frame_size * 2;
877 882
878 //Allocating buffers and prepare RISC program 883 /* Allocating buffers and prepare RISC program */
879 retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size); 884 retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
880 if (retval < 0) { 885 if (retval < 0) {
881 printk(KERN_ERR 886 printk(KERN_ERR
@@ -888,7 +893,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
888 893
889 return 0; 894 return 0;
890 895
891 error: 896error:
892 cx25821_dev_unregister(dev); 897 cx25821_dev_unregister(dev);
893 898
894 return err; 899 return err;
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index 8cd3986d2e5c..791212c1a661 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -54,34 +54,34 @@ static void init_controls(struct cx25821_dev *dev, int chan_num);
54 54
55struct cx25821_fmt formats[] = { 55struct cx25821_fmt formats[] = {
56 { 56 {
57 .name = "8 bpp, gray", 57 .name = "8 bpp, gray",
58 .fourcc = V4L2_PIX_FMT_GREY, 58 .fourcc = V4L2_PIX_FMT_GREY,
59 .depth = 8, 59 .depth = 8,
60 .flags = FORMAT_FLAGS_PACKED, 60 .flags = FORMAT_FLAGS_PACKED,
61 }, { 61 }, {
62 .name = "4:1:1, packed, Y41P", 62 .name = "4:1:1, packed, Y41P",
63 .fourcc = V4L2_PIX_FMT_Y41P, 63 .fourcc = V4L2_PIX_FMT_Y41P,
64 .depth = 12, 64 .depth = 12,
65 .flags = FORMAT_FLAGS_PACKED, 65 .flags = FORMAT_FLAGS_PACKED,
66 }, { 66 }, {
67 .name = "4:2:2, packed, YUYV", 67 .name = "4:2:2, packed, YUYV",
68 .fourcc = V4L2_PIX_FMT_YUYV, 68 .fourcc = V4L2_PIX_FMT_YUYV,
69 .depth = 16, 69 .depth = 16,
70 .flags = FORMAT_FLAGS_PACKED, 70 .flags = FORMAT_FLAGS_PACKED,
71 }, { 71 }, {
72 .name = "4:2:2, packed, UYVY", 72 .name = "4:2:2, packed, UYVY",
73 .fourcc = V4L2_PIX_FMT_UYVY, 73 .fourcc = V4L2_PIX_FMT_UYVY,
74 .depth = 16, 74 .depth = 16,
75 .flags = FORMAT_FLAGS_PACKED, 75 .flags = FORMAT_FLAGS_PACKED,
76 }, { 76 }, {
77 .name = "4:2:0, YUV", 77 .name = "4:2:0, YUV",
78 .fourcc = V4L2_PIX_FMT_YUV420, 78 .fourcc = V4L2_PIX_FMT_YUV420,
79 .depth = 12, 79 .depth = 12,
80 .flags = FORMAT_FLAGS_PACKED, 80 .flags = FORMAT_FLAGS_PACKED,
81 }, 81 },
82}; 82};
83 83
84int get_format_size(void) 84int cx25821_get_format_size(void)
85{ 85{
86 return ARRAY_SIZE(formats); 86 return ARRAY_SIZE(formats);
87} 87}
@@ -102,7 +102,7 @@ struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
102 return NULL; 102 return NULL;
103} 103}
104 104
105void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q) 105void cx25821_dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
106{ 106{
107 struct cx25821_buffer *buf; 107 struct cx25821_buffer *buf;
108 struct list_head *item; 108 struct list_head *item;
@@ -212,7 +212,7 @@ static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
212*/ 212*/
213 213
214// resource management 214// resource management
215int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit) 215int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
216{ 216{
217 dprintk(1, "%s()\n", __func__); 217 dprintk(1, "%s()\n", __func__);
218 if (fh->resources & bit) 218 if (fh->resources & bit)
@@ -234,17 +234,17 @@ int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
234 return 1; 234 return 1;
235} 235}
236 236
237int res_check(struct cx25821_fh *fh, unsigned int bit) 237int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
238{ 238{
239 return fh->resources & bit; 239 return fh->resources & bit;
240} 240}
241 241
242int res_locked(struct cx25821_dev *dev, unsigned int bit) 242int cx25821_res_locked(struct cx25821_dev *dev, unsigned int bit)
243{ 243{
244 return dev->resources & bit; 244 return dev->resources & bit;
245} 245}
246 246
247void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits) 247void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
248{ 248{
249 BUG_ON((fh->resources & bits) != bits); 249 BUG_ON((fh->resources & bits) != bits);
250 dprintk(1, "%s()\n", __func__); 250 dprintk(1, "%s()\n", __func__);
@@ -506,7 +506,7 @@ int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
506 return err; 506 return err;
507} 507}
508 508
509int buffer_setup(struct videobuf_queue *q, unsigned int *count, 509int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
510 unsigned int *size) 510 unsigned int *size)
511{ 511{
512 struct cx25821_fh *fh = q->priv_data; 512 struct cx25821_fh *fh = q->priv_data;
@@ -516,13 +516,13 @@ int buffer_setup(struct videobuf_queue *q, unsigned int *count,
516 if (0 == *count) 516 if (0 == *count)
517 *count = 32; 517 *count = 32;
518 518
519 while (*size * *count > vid_limit * 1024 * 1024) 519 if (*size * *count > vid_limit * 1024 * 1024)
520 (*count)--; 520 *count = (vid_limit * 1024 * 1024) / *size;
521 521
522 return 0; 522 return 0;
523} 523}
524 524
525int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, 525int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
526 enum v4l2_field field) 526 enum v4l2_field field)
527{ 527{
528 struct cx25821_fh *fh = q->priv_data; 528 struct cx25821_fh *fh = q->priv_data;
@@ -648,7 +648,7 @@ int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
648 return rc; 648 return rc;
649} 649}
650 650
651void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 651void cx25821_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
652{ 652{
653 struct cx25821_buffer *buf = 653 struct cx25821_buffer *buf =
654 container_of(vb, struct cx25821_buffer, vb); 654 container_of(vb, struct cx25821_buffer, vb);
@@ -667,7 +667,7 @@ struct videobuf_queue *get_queue(struct cx25821_fh *fh)
667 } 667 }
668} 668}
669 669
670int get_resource(struct cx25821_fh *fh, int resource) 670int cx25821_get_resource(struct cx25821_fh *fh, int resource)
671{ 671{
672 switch (fh->type) { 672 switch (fh->type) {
673 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 673 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -678,7 +678,7 @@ int get_resource(struct cx25821_fh *fh, int resource)
678 } 678 }
679} 679}
680 680
681int video_mmap(struct file *file, struct vm_area_struct *vma) 681int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
682{ 682{
683 struct cx25821_fh *fh = file->private_data; 683 struct cx25821_fh *fh = file->private_data;
684 684
@@ -686,7 +686,7 @@ int video_mmap(struct file *file, struct vm_area_struct *vma)
686} 686}
687 687
688/* VIDEO IOCTLS */ 688/* VIDEO IOCTLS */
689int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) 689int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
690{ 690{
691 struct cx25821_fh *fh = priv; 691 struct cx25821_fh *fh = priv;
692 692
@@ -700,7 +700,7 @@ int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
700 return 0; 700 return 0;
701} 701}
702 702
703int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) 703int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
704{ 704{
705 struct cx25821_fmt *fmt; 705 struct cx25821_fmt *fmt;
706 enum v4l2_field field; 706 enum v4l2_field field;
@@ -746,7 +746,7 @@ int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
746 return 0; 746 return 0;
747} 747}
748 748
749int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) 749int cx25821_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
750{ 750{
751 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 751 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
752 752
@@ -761,7 +761,7 @@ int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
761 return 0; 761 return 0;
762} 762}
763 763
764int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 764int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
765 struct v4l2_fmtdesc *f) 765 struct v4l2_fmtdesc *f)
766{ 766{
767 if (unlikely(f->index >= ARRAY_SIZE(formats))) 767 if (unlikely(f->index >= ARRAY_SIZE(formats)))
@@ -774,7 +774,7 @@ int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
774} 774}
775 775
776#ifdef CONFIG_VIDEO_V4L1_COMPAT 776#ifdef CONFIG_VIDEO_V4L1_COMPAT
777int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) 777int cx25821_vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
778{ 778{
779 struct cx25821_fh *fh = priv; 779 struct cx25821_fh *fh = priv;
780 struct videobuf_queue *q; 780 struct videobuf_queue *q;
@@ -801,25 +801,25 @@ int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
801} 801}
802#endif 802#endif
803 803
804int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) 804int cx25821_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
805{ 805{
806 struct cx25821_fh *fh = priv; 806 struct cx25821_fh *fh = priv;
807 return videobuf_reqbufs(get_queue(fh), p); 807 return videobuf_reqbufs(get_queue(fh), p);
808} 808}
809 809
810int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) 810int cx25821_vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
811{ 811{
812 struct cx25821_fh *fh = priv; 812 struct cx25821_fh *fh = priv;
813 return videobuf_querybuf(get_queue(fh), p); 813 return videobuf_querybuf(get_queue(fh), p);
814} 814}
815 815
816int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) 816int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
817{ 817{
818 struct cx25821_fh *fh = priv; 818 struct cx25821_fh *fh = priv;
819 return videobuf_qbuf(get_queue(fh), p); 819 return videobuf_qbuf(get_queue(fh), p);
820} 820}
821 821
822int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) 822int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
823{ 823{
824 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; 824 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
825 825
@@ -828,7 +828,7 @@ int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
828 return 0; 828 return 0;
829} 829}
830 830
831int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio) 831int cx25821_vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
832{ 832{
833 struct cx25821_fh *fh = f; 833 struct cx25821_fh *fh = f;
834 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; 834 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
@@ -837,7 +837,7 @@ int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
837} 837}
838 838
839#ifdef TUNER_FLAG 839#ifdef TUNER_FLAG
840int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms) 840int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
841{ 841{
842 struct cx25821_fh *fh = priv; 842 struct cx25821_fh *fh = priv;
843 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 843 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
@@ -846,7 +846,7 @@ int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
846 dprintk(1, "%s()\n", __func__); 846 dprintk(1, "%s()\n", __func__);
847 847
848 if (fh) { 848 if (fh) {
849 err = v4l2_prio_check(&dev->prio, &fh->prio); 849 err = v4l2_prio_check(&dev->prio, fh->prio);
850 if (0 != err) 850 if (0 != err)
851 return err; 851 return err;
852 } 852 }
@@ -891,14 +891,14 @@ int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
891 return 0; 891 return 0;
892} 892}
893 893
894int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) 894int cx25821_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
895{ 895{
896 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 896 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
897 dprintk(1, "%s()\n", __func__); 897 dprintk(1, "%s()\n", __func__);
898 return cx25821_enum_input(dev, i); 898 return cx25821_enum_input(dev, i);
899} 899}
900 900
901int vidioc_g_input(struct file *file, void *priv, unsigned int *i) 901int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
902{ 902{
903 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 903 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
904 904
@@ -907,7 +907,7 @@ int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
907 return 0; 907 return 0;
908} 908}
909 909
910int vidioc_s_input(struct file *file, void *priv, unsigned int i) 910int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
911{ 911{
912 struct cx25821_fh *fh = priv; 912 struct cx25821_fh *fh = priv;
913 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 913 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
@@ -916,7 +916,7 @@ int vidioc_s_input(struct file *file, void *priv, unsigned int i)
916 dprintk(1, "%s(%d)\n", __func__, i); 916 dprintk(1, "%s(%d)\n", __func__, i);
917 917
918 if (fh) { 918 if (fh) {
919 err = v4l2_prio_check(&dev->prio, &fh->prio); 919 err = v4l2_prio_check(&dev->prio, fh->prio);
920 if (0 != err) 920 if (0 != err)
921 return err; 921 return err;
922 } 922 }
@@ -933,7 +933,7 @@ int vidioc_s_input(struct file *file, void *priv, unsigned int i)
933} 933}
934 934
935#ifdef TUNER_FLAG 935#ifdef TUNER_FLAG
936int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) 936int cx25821_vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
937{ 937{
938 struct cx25821_fh *fh = priv; 938 struct cx25821_fh *fh = priv;
939 struct cx25821_dev *dev = fh->dev; 939 struct cx25821_dev *dev = fh->dev;
@@ -960,15 +960,14 @@ int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
960 return 0; 960 return 0;
961} 961}
962 962
963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) 963int cx25821_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
964{ 964{
965 struct cx25821_fh *fh = priv; 965 struct cx25821_fh *fh = priv;
966 struct cx25821_dev *dev; 966 struct cx25821_dev *dev;
967 int err; 967 int err;
968 968
969 if (fh) { 969 if (fh) {
970 dev = fh->dev; 970 err = v4l2_prio_check(&dev->prio, fh->prio);
971 err = v4l2_prio_check(&dev->prio, &fh->prio);
972 if (0 != err) 971 if (0 != err)
973 return err; 972 return err;
974 } 973 }
@@ -978,7 +977,7 @@ int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
978#endif 977#endif
979 978
980#ifdef CONFIG_VIDEO_ADV_DEBUG 979#ifdef CONFIG_VIDEO_ADV_DEBUG
981int vidioc_g_register(struct file *file, void *fh, 980int cx25821_vidioc_g_register(struct file *file, void *fh,
982 struct v4l2_dbg_register *reg) 981 struct v4l2_dbg_register *reg)
983{ 982{
984 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; 983 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
@@ -991,7 +990,7 @@ int vidioc_g_register(struct file *file, void *fh,
991 return 0; 990 return 0;
992} 991}
993 992
994int vidioc_s_register(struct file *file, void *fh, 993int cx25821_vidioc_s_register(struct file *file, void *fh,
995 struct v4l2_dbg_register *reg) 994 struct v4l2_dbg_register *reg)
996{ 995{
997 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; 996 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
@@ -1007,7 +1006,7 @@ int vidioc_s_register(struct file *file, void *fh,
1007#endif 1006#endif
1008 1007
1009#ifdef TUNER_FLAG 1008#ifdef TUNER_FLAG
1010int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) 1009int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1011{ 1010{
1012 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 1011 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1013 1012
@@ -1025,14 +1024,14 @@ int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1025 return 0; 1024 return 0;
1026} 1025}
1027 1026
1028int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t) 1027int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1029{ 1028{
1030 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 1029 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1031 struct cx25821_fh *fh = priv; 1030 struct cx25821_fh *fh = priv;
1032 int err; 1031 int err;
1033 1032
1034 if (fh) { 1033 if (fh) {
1035 err = v4l2_prio_check(&dev->prio, &fh->prio); 1034 err = v4l2_prio_check(&dev->prio, fh->prio);
1036 if (0 != err) 1035 if (0 != err)
1037 return err; 1036 return err;
1038 } 1037 }
@@ -1108,7 +1107,7 @@ static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1108 return 0; 1107 return 0;
1109} 1108}
1110 1109
1111int vidioc_queryctrl(struct file *file, void *priv, 1110int cx25821_vidioc_queryctrl(struct file *file, void *priv,
1112 struct v4l2_queryctrl *qctrl) 1111 struct v4l2_queryctrl *qctrl)
1113{ 1112{
1114 return cx25821_ctrl_query(qctrl); 1113 return cx25821_ctrl_query(qctrl);
@@ -1127,7 +1126,7 @@ static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1127 return NULL; 1126 return NULL;
1128} 1127}
1129 1128
1130int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl) 1129int cx25821_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
1131{ 1130{
1132 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 1131 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1133 1132
@@ -1216,7 +1215,7 @@ static void init_controls(struct cx25821_dev *dev, int chan_num)
1216 } 1215 }
1217} 1216}
1218 1217
1219int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap) 1218int cx25821_vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1220{ 1219{
1221 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 1220 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1222 1221
@@ -1233,28 +1232,28 @@ int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1233 return 0; 1232 return 0;
1234} 1233}
1235 1234
1236int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1235int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1237{ 1236{
1238 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; 1237 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1239 struct cx25821_fh *fh = priv; 1238 struct cx25821_fh *fh = priv;
1240 int err; 1239 int err;
1241 1240
1242 if (fh) { 1241 if (fh) {
1243 err = v4l2_prio_check(&dev->prio, &fh->prio); 1242 err = v4l2_prio_check(&dev->prio, fh->prio);
1244 if (0 != err) 1243 if (0 != err)
1245 return err; 1244 return err;
1246 } 1245 }
1247 // vidioc_s_crop not supported 1246 // cx25821_vidioc_s_crop not supported
1248 return -EINVAL; 1247 return -EINVAL;
1249} 1248}
1250 1249
1251int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1250int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1252{ 1251{
1253 // vidioc_g_crop not supported 1252 // cx25821_vidioc_g_crop not supported
1254 return -EINVAL; 1253 return -EINVAL;
1255} 1254}
1256 1255
1257int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm) 1256int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1258{ 1257{
1259 // medusa does not support video standard sensing of current input 1258 // medusa does not support video standard sensing of current input
1260 *norm = CX25821_NORMS; 1259 *norm = CX25821_NORMS;
@@ -1262,7 +1261,7 @@ int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1262 return 0; 1261 return 0;
1263} 1262}
1264 1263
1265int is_valid_width(u32 width, v4l2_std_id tvnorm) 1264int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
1266{ 1265{
1267 if (tvnorm == V4L2_STD_PAL_BG) { 1266 if (tvnorm == V4L2_STD_PAL_BG) {
1268 if (width == 352 || width == 720) 1267 if (width == 352 || width == 720)
@@ -1280,7 +1279,7 @@ int is_valid_width(u32 width, v4l2_std_id tvnorm)
1280 return 0; 1279 return 0;
1281} 1280}
1282 1281
1283int is_valid_height(u32 height, v4l2_std_id tvnorm) 1282int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
1284{ 1283{
1285 if (tvnorm == V4L2_STD_PAL_BG) { 1284 if (tvnorm == V4L2_STD_PAL_BG) {
1286 if (height == 576 || height == 288) 1285 if (height == 576 || height == 288)
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
index 4417ff5d90d4..0bddc02be57d 100644
--- a/drivers/staging/cx25821/cx25821-video.h
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -101,7 +101,7 @@ extern struct cx25821_fmt formats[];
101extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc); 101extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
102extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; 102extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
103 103
104extern void dump_video_queue(struct cx25821_dev *dev, 104extern void cx25821_dump_video_queue(struct cx25821_dev *dev,
105 struct cx25821_dmaqueue *q); 105 struct cx25821_dmaqueue *q);
106extern void cx25821_video_wakeup(struct cx25821_dev *dev, 106extern void cx25821_video_wakeup(struct cx25821_dev *dev,
107 struct cx25821_dmaqueue *q, u32 count); 107 struct cx25821_dmaqueue *q, u32 count);
@@ -110,11 +110,11 @@ extern void cx25821_video_wakeup(struct cx25821_dev *dev,
110extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm); 110extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
111#endif 111#endif
112 112
113extern int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, 113extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
114 unsigned int bit); 114 unsigned int bit);
115extern int res_check(struct cx25821_fh *fh, unsigned int bit); 115extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit);
116extern int res_locked(struct cx25821_dev *dev, unsigned int bit); 116extern int cx25821_res_locked(struct cx25821_dev *dev, unsigned int bit);
117extern void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, 117extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
118 unsigned int bits); 118 unsigned int bits);
119extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input); 119extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
120extern int cx25821_start_video_dma(struct cx25821_dev *dev, 120extern int cx25821_start_video_dma(struct cx25821_dev *dev,
@@ -128,67 +128,67 @@ extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
128extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num); 128extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
129extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num, 129extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
130 struct video_device *video_template); 130 struct video_device *video_template);
131extern int get_format_size(void); 131extern int cx25821_get_format_size(void);
132 132
133extern int buffer_setup(struct videobuf_queue *q, unsigned int *count, 133extern int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
134 unsigned int *size); 134 unsigned int *size);
135extern int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, 135extern int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
136 enum v4l2_field field); 136 enum v4l2_field field);
137extern void buffer_release(struct videobuf_queue *q, 137extern void cx25821_buffer_release(struct videobuf_queue *q,
138 struct videobuf_buffer *vb); 138 struct videobuf_buffer *vb);
139extern struct videobuf_queue *get_queue(struct cx25821_fh *fh); 139extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
140extern int get_resource(struct cx25821_fh *fh, int resource); 140extern int cx25821_get_resource(struct cx25821_fh *fh, int resource);
141extern int video_mmap(struct file *file, struct vm_area_struct *vma); 141extern int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma);
142extern int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 142extern int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
143 struct v4l2_format *f); 143 struct v4l2_format *f);
144extern int vidioc_querycap(struct file *file, void *priv, 144extern int cx25821_vidioc_querycap(struct file *file, void *priv,
145 struct v4l2_capability *cap); 145 struct v4l2_capability *cap);
146extern int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 146extern int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
147 struct v4l2_fmtdesc *f); 147 struct v4l2_fmtdesc *f);
148extern int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf); 148extern int cx25821_vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
149extern int vidioc_reqbufs(struct file *file, void *priv, 149extern int cx25821_vidioc_reqbufs(struct file *file, void *priv,
150 struct v4l2_requestbuffers *p); 150 struct v4l2_requestbuffers *p);
151extern int vidioc_querybuf(struct file *file, void *priv, 151extern int cx25821_vidioc_querybuf(struct file *file, void *priv,
152 struct v4l2_buffer *p); 152 struct v4l2_buffer *p);
153extern int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p); 153extern int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
154extern int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms); 154extern int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms);
155extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i); 155extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
156extern int vidioc_enum_input(struct file *file, void *priv, 156extern int cx25821_vidioc_enum_input(struct file *file, void *priv,
157 struct v4l2_input *i); 157 struct v4l2_input *i);
158extern int vidioc_g_input(struct file *file, void *priv, unsigned int *i); 158extern int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
159extern int vidioc_s_input(struct file *file, void *priv, unsigned int i); 159extern int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i);
160extern int vidioc_g_ctrl(struct file *file, void *priv, 160extern int cx25821_vidioc_g_ctrl(struct file *file, void *priv,
161 struct v4l2_control *ctl); 161 struct v4l2_control *ctl);
162extern int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 162extern int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
163 struct v4l2_format *f); 163 struct v4l2_format *f);
164extern int vidioc_g_frequency(struct file *file, void *priv, 164extern int cx25821_vidioc_g_frequency(struct file *file, void *priv,
165 struct v4l2_frequency *f); 165 struct v4l2_frequency *f);
166extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f); 166extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
167extern int vidioc_s_frequency(struct file *file, void *priv, 167extern int cx25821_vidioc_s_frequency(struct file *file, void *priv,
168 struct v4l2_frequency *f); 168 struct v4l2_frequency *f);
169extern int vidioc_g_register(struct file *file, void *fh, 169extern int cx25821_vidioc_g_register(struct file *file, void *fh,
170 struct v4l2_dbg_register *reg); 170 struct v4l2_dbg_register *reg);
171extern int vidioc_s_register(struct file *file, void *fh, 171extern int cx25821_vidioc_s_register(struct file *file, void *fh,
172 struct v4l2_dbg_register *reg); 172 struct v4l2_dbg_register *reg);
173extern int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t); 173extern int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
174extern int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t); 174extern int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
175 175
176extern int is_valid_width(u32 width, v4l2_std_id tvnorm); 176extern int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm);
177extern int is_valid_height(u32 height, v4l2_std_id tvnorm); 177extern int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm);
178 178
179extern int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p); 179extern int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p);
180extern int vidioc_s_priority(struct file *file, void *f, 180extern int cx25821_vidioc_s_priority(struct file *file, void *f,
181 enum v4l2_priority prio); 181 enum v4l2_priority prio);
182 182
183extern int vidioc_queryctrl(struct file *file, void *priv, 183extern int cx25821_vidioc_queryctrl(struct file *file, void *priv,
184 struct v4l2_queryctrl *qctrl); 184 struct v4l2_queryctrl *qctrl);
185extern int cx25821_set_control(struct cx25821_dev *dev, 185extern int cx25821_set_control(struct cx25821_dev *dev,
186 struct v4l2_control *ctrl, int chan_num); 186 struct v4l2_control *ctrl, int chan_num);
187 187
188extern int vidioc_cropcap(struct file *file, void *fh, 188extern int cx25821_vidioc_cropcap(struct file *file, void *fh,
189 struct v4l2_cropcap *cropcap); 189 struct v4l2_cropcap *cropcap);
190extern int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop); 190extern int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop);
191extern int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop); 191extern int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop);
192 192
193extern int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm); 193extern int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm);
194#endif 194#endif
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
index ad7a69129118..0be2cc15d856 100644
--- a/drivers/staging/cx25821/cx25821-video0.c
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -147,7 +147,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
147 147
148 switch (fh->type) { 148 switch (fh->type) {
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 149 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
150 if (res_locked(fh->dev, RESOURCE_VIDEO0)) 150 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO0))
151 return -EBUSY; 151 return -EBUSY;
152 152
153 return videobuf_read_one(&fh->vidq, data, count, ppos, 153 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -165,7 +165,7 @@ static unsigned int video_poll(struct file *file,
165 struct cx25821_fh *fh = file->private_data; 165 struct cx25821_fh *fh = file->private_data;
166 struct cx25821_buffer *buf; 166 struct cx25821_buffer *buf;
167 167
168 if (res_check(fh, RESOURCE_VIDEO0)) { 168 if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
169 /* streaming capture */ 169 /* streaming capture */
170 if (list_empty(&fh->vidq.stream)) 170 if (list_empty(&fh->vidq.stream))
171 return POLLERR; 171 return POLLERR;
@@ -207,19 +207,19 @@ static int video_release(struct file *file)
207 cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */ 207 cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
208 208
209 /* stop video capture */ 209 /* stop video capture */
210 if (res_check(fh, RESOURCE_VIDEO0)) { 210 if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
211 videobuf_queue_cancel(&fh->vidq); 211 videobuf_queue_cancel(&fh->vidq);
212 res_free(dev, fh, RESOURCE_VIDEO0); 212 cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
213 } 213 }
214 214
215 if (fh->vidq.read_buf) { 215 if (fh->vidq.read_buf) {
216 buffer_release(&fh->vidq, fh->vidq.read_buf); 216 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
217 kfree(fh->vidq.read_buf); 217 kfree(fh->vidq.read_buf);
218 } 218 }
219 219
220 videobuf_mmap_free(&fh->vidq); 220 videobuf_mmap_free(&fh->vidq);
221 221
222 v4l2_prio_close(&dev->prio, &fh->prio); 222 v4l2_prio_close(&dev->prio, fh->prio);
223 file->private_data = NULL; 223 file->private_data = NULL;
224 kfree(fh); 224 kfree(fh);
225 225
@@ -239,7 +239,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
239 return -EINVAL; 239 return -EINVAL;
240 } 240 }
241 241
242 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO0)))) { 242 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO0)))) {
243 return -EBUSY; 243 return -EBUSY;
244 } 244 }
245 245
@@ -257,11 +257,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
257 if (i != fh->type) 257 if (i != fh->type)
258 return -EINVAL; 258 return -EINVAL;
259 259
260 res = get_resource(fh, RESOURCE_VIDEO0); 260 res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
261 err = videobuf_streamoff(get_queue(fh)); 261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0) 262 if (err < 0)
263 return err; 263 return err;
264 res_free(dev, fh, res); 264 cx25821_res_free(dev, fh, res);
265 return 0; 265 return 0;
266} 266}
267 267
@@ -274,13 +274,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
274 int pix_format = PIXEL_FRMT_422; 274 int pix_format = PIXEL_FRMT_422;
275 275
276 if (fh) { 276 if (fh) {
277 err = v4l2_prio_check(&dev->prio, &fh->prio); 277 err = v4l2_prio_check(&dev->prio, fh->prio);
278 if (0 != err) 278 if (0 != err)
279 return err; 279 return err;
280 } 280 }
281 281
282 dprintk(2, "%s()\n", __func__); 282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f); 283 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
284 284
285 if (0 != err) 285 if (0 != err)
286 return err; 286 return err;
@@ -289,11 +289,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
289 fh->vidq.field = f->fmt.pix.field; 289 fh->vidq.field = f->fmt.pix.field;
290 290
291 // check if width and height is valid based on set standard 291 // check if width and height is valid based on set standard
292 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 292 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
293 fh->width = f->fmt.pix.width; 293 fh->width = f->fmt.pix.width;
294 } 294 }
295 295
296 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 296 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
297 fh->height = f->fmt.pix.height; 297 fh->height = f->fmt.pix.height;
298 } 298 }
299 299
@@ -363,7 +363,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
363 int err; 363 int err;
364 364
365 if (fh) { 365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio); 366 err = v4l2_prio_check(&dev->prio, fh->prio);
367 if (0 != err) 367 if (0 != err)
368 return err; 368 return err;
369 } 369 }
@@ -378,50 +378,50 @@ static const struct v4l2_file_operations video_fops = {
378 .release = video_release, 378 .release = video_release,
379 .read = video_read, 379 .read = video_read,
380 .poll = video_poll, 380 .poll = video_poll,
381 .mmap = video_mmap, 381 .mmap = cx25821_video_mmap,
382 .ioctl = video_ioctl2, 382 .ioctl = video_ioctl2,
383}; 383};
384 384
385static const struct v4l2_ioctl_ops video_ioctl_ops = { 385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap, 386 .vidioc_querycap = cx25821_vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 387 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 388 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 389 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs, 391 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf, 392 .vidioc_querybuf = cx25821_vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf, 393 .vidioc_qbuf = cx25821_vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf, 394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG 395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std, 396 .vidioc_s_std = cx25821_vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd, 397 .vidioc_querystd = cx25821_vidioc_querystd,
398#endif 398#endif
399 .vidioc_cropcap = vidioc_cropcap, 399 .vidioc_cropcap = cx25821_vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop, 400 .vidioc_s_crop = cx25821_vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop, 401 .vidioc_g_crop = cx25821_vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input, 402 .vidioc_enum_input = cx25821_vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input, 403 .vidioc_g_input = cx25821_vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input, 404 .vidioc_s_input = cx25821_vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl, 405 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl, 406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl, 407 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon, 408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff, 409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status, 410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority, 411 .vidioc_g_priority = cx25821_vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority, 412 .vidioc_s_priority = cx25821_vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT 413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf, 414 .vidiocgmbuf = cx25821_vidiocgmbuf,
415#endif 415#endif
416#ifdef TUNER_FLAG 416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner, 417 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner, 418 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency, 419 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency, 420 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
421#endif 421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG 422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register, 423 .vidioc_g_register = cx25821_vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register, 424 .vidioc_s_register = cx25821_vidioc_s_register,
425#endif 425#endif
426}; 426};
427 427
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
index e3f3c4ac7908..b0bae627bfb1 100644
--- a/drivers/staging/cx25821/cx25821-video1.c
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -147,7 +147,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
147 147
148 switch (fh->type) { 148 switch (fh->type) {
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 149 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
150 if (res_locked(fh->dev, RESOURCE_VIDEO1)) 150 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO1))
151 return -EBUSY; 151 return -EBUSY;
152 152
153 return videobuf_read_one(&fh->vidq, data, count, ppos, 153 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -165,7 +165,7 @@ static unsigned int video_poll(struct file *file,
165 struct cx25821_fh *fh = file->private_data; 165 struct cx25821_fh *fh = file->private_data;
166 struct cx25821_buffer *buf; 166 struct cx25821_buffer *buf;
167 167
168 if (res_check(fh, RESOURCE_VIDEO1)) { 168 if (cx25821_res_check(fh, RESOURCE_VIDEO1)) {
169 /* streaming capture */ 169 /* streaming capture */
170 if (list_empty(&fh->vidq.stream)) 170 if (list_empty(&fh->vidq.stream))
171 return POLLERR; 171 return POLLERR;
@@ -207,19 +207,19 @@ static int video_release(struct file *file)
207 cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */ 207 cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */
208 208
209 /* stop video capture */ 209 /* stop video capture */
210 if (res_check(fh, RESOURCE_VIDEO1)) { 210 if (cx25821_res_check(fh, RESOURCE_VIDEO1)) {
211 videobuf_queue_cancel(&fh->vidq); 211 videobuf_queue_cancel(&fh->vidq);
212 res_free(dev, fh, RESOURCE_VIDEO1); 212 cx25821_res_free(dev, fh, RESOURCE_VIDEO1);
213 } 213 }
214 214
215 if (fh->vidq.read_buf) { 215 if (fh->vidq.read_buf) {
216 buffer_release(&fh->vidq, fh->vidq.read_buf); 216 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
217 kfree(fh->vidq.read_buf); 217 kfree(fh->vidq.read_buf);
218 } 218 }
219 219
220 videobuf_mmap_free(&fh->vidq); 220 videobuf_mmap_free(&fh->vidq);
221 221
222 v4l2_prio_close(&dev->prio, &fh->prio); 222 v4l2_prio_close(&dev->prio, fh->prio);
223 file->private_data = NULL; 223 file->private_data = NULL;
224 kfree(fh); 224 kfree(fh);
225 225
@@ -239,7 +239,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
239 return -EINVAL; 239 return -EINVAL;
240 } 240 }
241 241
242 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO1)))) { 242 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO1)))) {
243 return -EBUSY; 243 return -EBUSY;
244 } 244 }
245 245
@@ -257,11 +257,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
257 if (i != fh->type) 257 if (i != fh->type)
258 return -EINVAL; 258 return -EINVAL;
259 259
260 res = get_resource(fh, RESOURCE_VIDEO1); 260 res = cx25821_get_resource(fh, RESOURCE_VIDEO1);
261 err = videobuf_streamoff(get_queue(fh)); 261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0) 262 if (err < 0)
263 return err; 263 return err;
264 res_free(dev, fh, res); 264 cx25821_res_free(dev, fh, res);
265 return 0; 265 return 0;
266} 266}
267 267
@@ -274,13 +274,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
274 int pix_format = 0; 274 int pix_format = 0;
275 275
276 if (fh) { 276 if (fh) {
277 err = v4l2_prio_check(&dev->prio, &fh->prio); 277 err = v4l2_prio_check(&dev->prio, fh->prio);
278 if (0 != err) 278 if (0 != err)
279 return err; 279 return err;
280 } 280 }
281 281
282 dprintk(2, "%s()\n", __func__); 282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f); 283 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
284 284
285 if (0 != err) 285 if (0 != err)
286 return err; 286 return err;
@@ -289,11 +289,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
289 fh->vidq.field = f->fmt.pix.field; 289 fh->vidq.field = f->fmt.pix.field;
290 290
291 // check if width and height is valid based on set standard 291 // check if width and height is valid based on set standard
292 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 292 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
293 fh->width = f->fmt.pix.width; 293 fh->width = f->fmt.pix.width;
294 } 294 }
295 295
296 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 296 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
297 fh->height = f->fmt.pix.height; 297 fh->height = f->fmt.pix.height;
298 } 298 }
299 299
@@ -363,7 +363,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
363 int err; 363 int err;
364 364
365 if (fh) { 365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio); 366 err = v4l2_prio_check(&dev->prio, fh->prio);
367 if (0 != err) 367 if (0 != err)
368 return err; 368 return err;
369 } 369 }
@@ -378,50 +378,50 @@ static const struct v4l2_file_operations video_fops = {
378 .release = video_release, 378 .release = video_release,
379 .read = video_read, 379 .read = video_read,
380 .poll = video_poll, 380 .poll = video_poll,
381 .mmap = video_mmap, 381 .mmap = cx25821_video_mmap,
382 .ioctl = video_ioctl2, 382 .ioctl = video_ioctl2,
383}; 383};
384 384
385static const struct v4l2_ioctl_ops video_ioctl_ops = { 385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap, 386 .vidioc_querycap = cx25821_vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 387 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 388 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 389 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs, 391 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf, 392 .vidioc_querybuf = cx25821_vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf, 393 .vidioc_qbuf = cx25821_vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf, 394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG 395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std, 396 .vidioc_s_std = cx25821_vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd, 397 .vidioc_querystd = cx25821_vidioc_querystd,
398#endif 398#endif
399 .vidioc_cropcap = vidioc_cropcap, 399 .vidioc_cropcap = cx25821_vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop, 400 .vidioc_s_crop = cx25821_vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop, 401 .vidioc_g_crop = cx25821_vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input, 402 .vidioc_enum_input = cx25821_vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input, 403 .vidioc_g_input = cx25821_vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input, 404 .vidioc_s_input = cx25821_vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl, 405 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl, 406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl, 407 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon, 408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff, 409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status, 410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority, 411 .vidioc_g_priority = cx25821_vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority, 412 .vidioc_s_priority = cx25821_vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT 413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf, 414 .vidiocgmbuf = cx25821_vidiocgmbuf,
415#endif 415#endif
416#ifdef TUNER_FLAG 416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner, 417 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner, 418 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency, 419 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency, 420 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
421#endif 421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG 422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register, 423 .vidioc_g_register = cx25821_vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register, 424 .vidioc_s_register = cx25821_vidioc_s_register,
425#endif 425#endif
426}; 426};
427 427
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
index 36fb855a497e..400cdb80674e 100644
--- a/drivers/staging/cx25821/cx25821-video2.c
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -147,7 +147,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
147 147
148 switch (fh->type) { 148 switch (fh->type) {
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 149 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
150 if (res_locked(fh->dev, RESOURCE_VIDEO2)) 150 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO2))
151 return -EBUSY; 151 return -EBUSY;
152 152
153 return videobuf_read_one(&fh->vidq, data, count, ppos, 153 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -165,7 +165,7 @@ static unsigned int video_poll(struct file *file,
165 struct cx25821_fh *fh = file->private_data; 165 struct cx25821_fh *fh = file->private_data;
166 struct cx25821_buffer *buf; 166 struct cx25821_buffer *buf;
167 167
168 if (res_check(fh, RESOURCE_VIDEO2)) { 168 if (cx25821_res_check(fh, RESOURCE_VIDEO2)) {
169 /* streaming capture */ 169 /* streaming capture */
170 if (list_empty(&fh->vidq.stream)) 170 if (list_empty(&fh->vidq.stream))
171 return POLLERR; 171 return POLLERR;
@@ -207,19 +207,19 @@ static int video_release(struct file *file)
207 cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */ 207 cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */
208 208
209 /* stop video capture */ 209 /* stop video capture */
210 if (res_check(fh, RESOURCE_VIDEO2)) { 210 if (cx25821_res_check(fh, RESOURCE_VIDEO2)) {
211 videobuf_queue_cancel(&fh->vidq); 211 videobuf_queue_cancel(&fh->vidq);
212 res_free(dev, fh, RESOURCE_VIDEO2); 212 cx25821_res_free(dev, fh, RESOURCE_VIDEO2);
213 } 213 }
214 214
215 if (fh->vidq.read_buf) { 215 if (fh->vidq.read_buf) {
216 buffer_release(&fh->vidq, fh->vidq.read_buf); 216 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
217 kfree(fh->vidq.read_buf); 217 kfree(fh->vidq.read_buf);
218 } 218 }
219 219
220 videobuf_mmap_free(&fh->vidq); 220 videobuf_mmap_free(&fh->vidq);
221 221
222 v4l2_prio_close(&dev->prio, &fh->prio); 222 v4l2_prio_close(&dev->prio, fh->prio);
223 file->private_data = NULL; 223 file->private_data = NULL;
224 kfree(fh); 224 kfree(fh);
225 225
@@ -239,7 +239,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
239 return -EINVAL; 239 return -EINVAL;
240 } 240 }
241 241
242 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO2)))) { 242 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO2)))) {
243 return -EBUSY; 243 return -EBUSY;
244 } 244 }
245 245
@@ -257,11 +257,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
257 if (i != fh->type) 257 if (i != fh->type)
258 return -EINVAL; 258 return -EINVAL;
259 259
260 res = get_resource(fh, RESOURCE_VIDEO2); 260 res = cx25821_get_resource(fh, RESOURCE_VIDEO2);
261 err = videobuf_streamoff(get_queue(fh)); 261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0) 262 if (err < 0)
263 return err; 263 return err;
264 res_free(dev, fh, res); 264 cx25821_res_free(dev, fh, res);
265 return 0; 265 return 0;
266} 266}
267 267
@@ -274,13 +274,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
274 int pix_format = 0; 274 int pix_format = 0;
275 275
276 if (fh) { 276 if (fh) {
277 err = v4l2_prio_check(&dev->prio, &fh->prio); 277 err = v4l2_prio_check(&dev->prio, fh->prio);
278 if (0 != err) 278 if (0 != err)
279 return err; 279 return err;
280 } 280 }
281 281
282 dprintk(2, "%s()\n", __func__); 282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f); 283 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
284 284
285 if (0 != err) 285 if (0 != err)
286 return err; 286 return err;
@@ -289,11 +289,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
289 fh->vidq.field = f->fmt.pix.field; 289 fh->vidq.field = f->fmt.pix.field;
290 290
291 // check if width and height is valid based on set standard 291 // check if width and height is valid based on set standard
292 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 292 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
293 fh->width = f->fmt.pix.width; 293 fh->width = f->fmt.pix.width;
294 } 294 }
295 295
296 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 296 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
297 fh->height = f->fmt.pix.height; 297 fh->height = f->fmt.pix.height;
298 } 298 }
299 299
@@ -365,7 +365,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
365 int err; 365 int err;
366 366
367 if (fh) { 367 if (fh) {
368 err = v4l2_prio_check(&dev->prio, &fh->prio); 368 err = v4l2_prio_check(&dev->prio, fh->prio);
369 if (0 != err) 369 if (0 != err)
370 return err; 370 return err;
371 } 371 }
@@ -380,50 +380,50 @@ static const struct v4l2_file_operations video_fops = {
380 .release = video_release, 380 .release = video_release,
381 .read = video_read, 381 .read = video_read,
382 .poll = video_poll, 382 .poll = video_poll,
383 .mmap = video_mmap, 383 .mmap = cx25821_video_mmap,
384 .ioctl = video_ioctl2, 384 .ioctl = video_ioctl2,
385}; 385};
386 386
387static const struct v4l2_ioctl_ops video_ioctl_ops = { 387static const struct v4l2_ioctl_ops video_ioctl_ops = {
388 .vidioc_querycap = vidioc_querycap, 388 .vidioc_querycap = cx25821_vidioc_querycap,
389 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 389 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
390 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 390 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
391 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 391 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
392 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 392 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
393 .vidioc_reqbufs = vidioc_reqbufs, 393 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
394 .vidioc_querybuf = vidioc_querybuf, 394 .vidioc_querybuf = cx25821_vidioc_querybuf,
395 .vidioc_qbuf = vidioc_qbuf, 395 .vidioc_qbuf = cx25821_vidioc_qbuf,
396 .vidioc_dqbuf = vidioc_dqbuf, 396 .vidioc_dqbuf = vidioc_dqbuf,
397#ifdef TUNER_FLAG 397#ifdef TUNER_FLAG
398 .vidioc_s_std = vidioc_s_std, 398 .vidioc_s_std = cx25821_vidioc_s_std,
399 .vidioc_querystd = vidioc_querystd, 399 .vidioc_querystd = cx25821_vidioc_querystd,
400#endif 400#endif
401 .vidioc_cropcap = vidioc_cropcap, 401 .vidioc_cropcap = cx25821_vidioc_cropcap,
402 .vidioc_s_crop = vidioc_s_crop, 402 .vidioc_s_crop = cx25821_vidioc_s_crop,
403 .vidioc_g_crop = vidioc_g_crop, 403 .vidioc_g_crop = cx25821_vidioc_g_crop,
404 .vidioc_enum_input = vidioc_enum_input, 404 .vidioc_enum_input = cx25821_vidioc_enum_input,
405 .vidioc_g_input = vidioc_g_input, 405 .vidioc_g_input = cx25821_vidioc_g_input,
406 .vidioc_s_input = vidioc_s_input, 406 .vidioc_s_input = cx25821_vidioc_s_input,
407 .vidioc_g_ctrl = vidioc_g_ctrl, 407 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
408 .vidioc_s_ctrl = vidioc_s_ctrl, 408 .vidioc_s_ctrl = vidioc_s_ctrl,
409 .vidioc_queryctrl = vidioc_queryctrl, 409 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
410 .vidioc_streamon = vidioc_streamon, 410 .vidioc_streamon = vidioc_streamon,
411 .vidioc_streamoff = vidioc_streamoff, 411 .vidioc_streamoff = vidioc_streamoff,
412 .vidioc_log_status = vidioc_log_status, 412 .vidioc_log_status = vidioc_log_status,
413 .vidioc_g_priority = vidioc_g_priority, 413 .vidioc_g_priority = cx25821_vidioc_g_priority,
414 .vidioc_s_priority = vidioc_s_priority, 414 .vidioc_s_priority = cx25821_vidioc_s_priority,
415#ifdef CONFIG_VIDEO_V4L1_COMPAT 415#ifdef CONFIG_VIDEO_V4L1_COMPAT
416 .vidiocgmbuf = vidiocgmbuf, 416 .vidiocgmbuf = cx25821_vidiocgmbuf,
417#endif 417#endif
418#ifdef TUNER_FLAG 418#ifdef TUNER_FLAG
419 .vidioc_g_tuner = vidioc_g_tuner, 419 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
420 .vidioc_s_tuner = vidioc_s_tuner, 420 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
421 .vidioc_g_frequency = vidioc_g_frequency, 421 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
422 .vidioc_s_frequency = vidioc_s_frequency, 422 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
423#endif 423#endif
424#ifdef CONFIG_VIDEO_ADV_DEBUG 424#ifdef CONFIG_VIDEO_ADV_DEBUG
425 .vidioc_g_register = vidioc_g_register, 425 .vidioc_g_register = cx25821_vidioc_g_register,
426 .vidioc_s_register = vidioc_s_register, 426 .vidioc_s_register = cx25821_vidioc_s_register,
427#endif 427#endif
428}; 428};
429 429
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
index 1e0f10abdbcd..3b216ed0906e 100644
--- a/drivers/staging/cx25821/cx25821-video3.c
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -147,7 +147,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
147 147
148 switch (fh->type) { 148 switch (fh->type) {
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 149 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
150 if (res_locked(fh->dev, RESOURCE_VIDEO3)) 150 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO3))
151 return -EBUSY; 151 return -EBUSY;
152 152
153 return videobuf_read_one(&fh->vidq, data, count, ppos, 153 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -165,7 +165,7 @@ static unsigned int video_poll(struct file *file,
165 struct cx25821_fh *fh = file->private_data; 165 struct cx25821_fh *fh = file->private_data;
166 struct cx25821_buffer *buf; 166 struct cx25821_buffer *buf;
167 167
168 if (res_check(fh, RESOURCE_VIDEO3)) { 168 if (cx25821_res_check(fh, RESOURCE_VIDEO3)) {
169 /* streaming capture */ 169 /* streaming capture */
170 if (list_empty(&fh->vidq.stream)) 170 if (list_empty(&fh->vidq.stream))
171 return POLLERR; 171 return POLLERR;
@@ -207,19 +207,19 @@ static int video_release(struct file *file)
207 cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */ 207 cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */
208 208
209 /* stop video capture */ 209 /* stop video capture */
210 if (res_check(fh, RESOURCE_VIDEO3)) { 210 if (cx25821_res_check(fh, RESOURCE_VIDEO3)) {
211 videobuf_queue_cancel(&fh->vidq); 211 videobuf_queue_cancel(&fh->vidq);
212 res_free(dev, fh, RESOURCE_VIDEO3); 212 cx25821_res_free(dev, fh, RESOURCE_VIDEO3);
213 } 213 }
214 214
215 if (fh->vidq.read_buf) { 215 if (fh->vidq.read_buf) {
216 buffer_release(&fh->vidq, fh->vidq.read_buf); 216 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
217 kfree(fh->vidq.read_buf); 217 kfree(fh->vidq.read_buf);
218 } 218 }
219 219
220 videobuf_mmap_free(&fh->vidq); 220 videobuf_mmap_free(&fh->vidq);
221 221
222 v4l2_prio_close(&dev->prio, &fh->prio); 222 v4l2_prio_close(&dev->prio, fh->prio);
223 file->private_data = NULL; 223 file->private_data = NULL;
224 kfree(fh); 224 kfree(fh);
225 225
@@ -239,7 +239,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
239 return -EINVAL; 239 return -EINVAL;
240 } 240 }
241 241
242 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO3)))) { 242 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO3)))) {
243 return -EBUSY; 243 return -EBUSY;
244 } 244 }
245 245
@@ -257,11 +257,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
257 if (i != fh->type) 257 if (i != fh->type)
258 return -EINVAL; 258 return -EINVAL;
259 259
260 res = get_resource(fh, RESOURCE_VIDEO3); 260 res = cx25821_get_resource(fh, RESOURCE_VIDEO3);
261 err = videobuf_streamoff(get_queue(fh)); 261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0) 262 if (err < 0)
263 return err; 263 return err;
264 res_free(dev, fh, res); 264 cx25821_res_free(dev, fh, res);
265 return 0; 265 return 0;
266} 266}
267 267
@@ -274,13 +274,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
274 int pix_format = 0; 274 int pix_format = 0;
275 275
276 if (fh) { 276 if (fh) {
277 err = v4l2_prio_check(&dev->prio, &fh->prio); 277 err = v4l2_prio_check(&dev->prio, fh->prio);
278 if (0 != err) 278 if (0 != err)
279 return err; 279 return err;
280 } 280 }
281 281
282 dprintk(2, "%s()\n", __func__); 282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f); 283 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
284 284
285 if (0 != err) 285 if (0 != err)
286 return err; 286 return err;
@@ -289,11 +289,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
289 fh->vidq.field = f->fmt.pix.field; 289 fh->vidq.field = f->fmt.pix.field;
290 290
291 // check if width and height is valid based on set standard 291 // check if width and height is valid based on set standard
292 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 292 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
293 fh->width = f->fmt.pix.width; 293 fh->width = f->fmt.pix.width;
294 } 294 }
295 295
296 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 296 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
297 fh->height = f->fmt.pix.height; 297 fh->height = f->fmt.pix.height;
298 } 298 }
299 299
@@ -364,7 +364,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
364 int err; 364 int err;
365 365
366 if (fh) { 366 if (fh) {
367 err = v4l2_prio_check(&dev->prio, &fh->prio); 367 err = v4l2_prio_check(&dev->prio, fh->prio);
368 if (0 != err) 368 if (0 != err)
369 return err; 369 return err;
370 } 370 }
@@ -379,50 +379,50 @@ static const struct v4l2_file_operations video_fops = {
379 .release = video_release, 379 .release = video_release,
380 .read = video_read, 380 .read = video_read,
381 .poll = video_poll, 381 .poll = video_poll,
382 .mmap = video_mmap, 382 .mmap = cx25821_video_mmap,
383 .ioctl = video_ioctl2, 383 .ioctl = video_ioctl2,
384}; 384};
385 385
386static const struct v4l2_ioctl_ops video_ioctl_ops = { 386static const struct v4l2_ioctl_ops video_ioctl_ops = {
387 .vidioc_querycap = vidioc_querycap, 387 .vidioc_querycap = cx25821_vidioc_querycap,
388 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 388 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
389 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 389 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
390 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 390 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
391 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 391 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
392 .vidioc_reqbufs = vidioc_reqbufs, 392 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
393 .vidioc_querybuf = vidioc_querybuf, 393 .vidioc_querybuf = cx25821_vidioc_querybuf,
394 .vidioc_qbuf = vidioc_qbuf, 394 .vidioc_qbuf = cx25821_vidioc_qbuf,
395 .vidioc_dqbuf = vidioc_dqbuf, 395 .vidioc_dqbuf = vidioc_dqbuf,
396#ifdef TUNER_FLAG 396#ifdef TUNER_FLAG
397 .vidioc_s_std = vidioc_s_std, 397 .vidioc_s_std = cx25821_vidioc_s_std,
398 .vidioc_querystd = vidioc_querystd, 398 .vidioc_querystd = cx25821_vidioc_querystd,
399#endif 399#endif
400 .vidioc_cropcap = vidioc_cropcap, 400 .vidioc_cropcap = cx25821_vidioc_cropcap,
401 .vidioc_s_crop = vidioc_s_crop, 401 .vidioc_s_crop = cx25821_vidioc_s_crop,
402 .vidioc_g_crop = vidioc_g_crop, 402 .vidioc_g_crop = cx25821_vidioc_g_crop,
403 .vidioc_enum_input = vidioc_enum_input, 403 .vidioc_enum_input = cx25821_vidioc_enum_input,
404 .vidioc_g_input = vidioc_g_input, 404 .vidioc_g_input = cx25821_vidioc_g_input,
405 .vidioc_s_input = vidioc_s_input, 405 .vidioc_s_input = cx25821_vidioc_s_input,
406 .vidioc_g_ctrl = vidioc_g_ctrl, 406 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
407 .vidioc_s_ctrl = vidioc_s_ctrl, 407 .vidioc_s_ctrl = vidioc_s_ctrl,
408 .vidioc_queryctrl = vidioc_queryctrl, 408 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
409 .vidioc_streamon = vidioc_streamon, 409 .vidioc_streamon = vidioc_streamon,
410 .vidioc_streamoff = vidioc_streamoff, 410 .vidioc_streamoff = vidioc_streamoff,
411 .vidioc_log_status = vidioc_log_status, 411 .vidioc_log_status = vidioc_log_status,
412 .vidioc_g_priority = vidioc_g_priority, 412 .vidioc_g_priority = cx25821_vidioc_g_priority,
413 .vidioc_s_priority = vidioc_s_priority, 413 .vidioc_s_priority = cx25821_vidioc_s_priority,
414#ifdef CONFIG_VIDEO_V4L1_COMPAT 414#ifdef CONFIG_VIDEO_V4L1_COMPAT
415 .vidiocgmbuf = vidiocgmbuf, 415 .vidiocgmbuf = cx25821_vidiocgmbuf,
416#endif 416#endif
417#ifdef TUNER_FLAG 417#ifdef TUNER_FLAG
418 .vidioc_g_tuner = vidioc_g_tuner, 418 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
419 .vidioc_s_tuner = vidioc_s_tuner, 419 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
420 .vidioc_g_frequency = vidioc_g_frequency, 420 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
421 .vidioc_s_frequency = vidioc_s_frequency, 421 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
422#endif 422#endif
423#ifdef CONFIG_VIDEO_ADV_DEBUG 423#ifdef CONFIG_VIDEO_ADV_DEBUG
424 .vidioc_g_register = vidioc_g_register, 424 .vidioc_g_register = cx25821_vidioc_g_register,
425 .vidioc_s_register = vidioc_s_register, 425 .vidioc_s_register = cx25821_vidioc_s_register,
426#endif 426#endif
427}; 427};
428 428
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
index 0cbe7a79d8c0..f7b08c51868a 100644
--- a/drivers/staging/cx25821/cx25821-video4.c
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -146,7 +146,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
146 146
147 switch (fh->type) { 147 switch (fh->type) {
148 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 148 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
149 if (res_locked(fh->dev, RESOURCE_VIDEO4)) 149 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO4))
150 return -EBUSY; 150 return -EBUSY;
151 151
152 return videobuf_read_one(&fh->vidq, data, count, ppos, 152 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -164,7 +164,7 @@ static unsigned int video_poll(struct file *file,
164 struct cx25821_fh *fh = file->private_data; 164 struct cx25821_fh *fh = file->private_data;
165 struct cx25821_buffer *buf; 165 struct cx25821_buffer *buf;
166 166
167 if (res_check(fh, RESOURCE_VIDEO4)) { 167 if (cx25821_res_check(fh, RESOURCE_VIDEO4)) {
168 /* streaming capture */ 168 /* streaming capture */
169 if (list_empty(&fh->vidq.stream)) 169 if (list_empty(&fh->vidq.stream))
170 return POLLERR; 170 return POLLERR;
@@ -206,19 +206,19 @@ static int video_release(struct file *file)
206 cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */ 206 cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */
207 207
208 /* stop video capture */ 208 /* stop video capture */
209 if (res_check(fh, RESOURCE_VIDEO4)) { 209 if (cx25821_res_check(fh, RESOURCE_VIDEO4)) {
210 videobuf_queue_cancel(&fh->vidq); 210 videobuf_queue_cancel(&fh->vidq);
211 res_free(dev, fh, RESOURCE_VIDEO4); 211 cx25821_res_free(dev, fh, RESOURCE_VIDEO4);
212 } 212 }
213 213
214 if (fh->vidq.read_buf) { 214 if (fh->vidq.read_buf) {
215 buffer_release(&fh->vidq, fh->vidq.read_buf); 215 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
216 kfree(fh->vidq.read_buf); 216 kfree(fh->vidq.read_buf);
217 } 217 }
218 218
219 videobuf_mmap_free(&fh->vidq); 219 videobuf_mmap_free(&fh->vidq);
220 220
221 v4l2_prio_close(&dev->prio, &fh->prio); 221 v4l2_prio_close(&dev->prio, fh->prio);
222 file->private_data = NULL; 222 file->private_data = NULL;
223 kfree(fh); 223 kfree(fh);
224 224
@@ -238,7 +238,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
238 return -EINVAL; 238 return -EINVAL;
239 } 239 }
240 240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO4)))) { 241 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO4)))) {
242 return -EBUSY; 242 return -EBUSY;
243 } 243 }
244 244
@@ -256,11 +256,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
256 if (i != fh->type) 256 if (i != fh->type)
257 return -EINVAL; 257 return -EINVAL;
258 258
259 res = get_resource(fh, RESOURCE_VIDEO4); 259 res = cx25821_get_resource(fh, RESOURCE_VIDEO4);
260 err = videobuf_streamoff(get_queue(fh)); 260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0) 261 if (err < 0)
262 return err; 262 return err;
263 res_free(dev, fh, res); 263 cx25821_res_free(dev, fh, res);
264 return 0; 264 return 0;
265} 265}
266 266
@@ -274,12 +274,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
274 274
275 // check priority 275 // check priority
276 if (fh) { 276 if (fh) {
277 err = v4l2_prio_check(&dev->prio, &fh->prio); 277 err = v4l2_prio_check(&dev->prio, fh->prio);
278 if (0 != err) 278 if (0 != err)
279 return err; 279 return err;
280 } 280 }
281 dprintk(2, "%s()\n", __func__); 281 dprintk(2, "%s()\n", __func__);
282 err = vidioc_try_fmt_vid_cap(file, priv, f); 282 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
283 283
284 if (0 != err) 284 if (0 != err)
285 return err; 285 return err;
@@ -288,11 +288,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
288 fh->vidq.field = f->fmt.pix.field; 288 fh->vidq.field = f->fmt.pix.field;
289 289
290 // check if width and height is valid based on set standard 290 // check if width and height is valid based on set standard
291 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 291 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
292 fh->width = f->fmt.pix.width; 292 fh->width = f->fmt.pix.width;
293 } 293 }
294 294
295 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 295 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
296 fh->height = f->fmt.pix.height; 296 fh->height = f->fmt.pix.height;
297 } 297 }
298 298
@@ -363,7 +363,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
363 int err; 363 int err;
364 364
365 if (fh) { 365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio); 366 err = v4l2_prio_check(&dev->prio, fh->prio);
367 if (0 != err) 367 if (0 != err)
368 return err; 368 return err;
369 } 369 }
@@ -378,50 +378,50 @@ static const struct v4l2_file_operations video_fops = {
378 .release = video_release, 378 .release = video_release,
379 .read = video_read, 379 .read = video_read,
380 .poll = video_poll, 380 .poll = video_poll,
381 .mmap = video_mmap, 381 .mmap = cx25821_video_mmap,
382 .ioctl = video_ioctl2, 382 .ioctl = video_ioctl2,
383}; 383};
384 384
385static const struct v4l2_ioctl_ops video_ioctl_ops = { 385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap, 386 .vidioc_querycap = cx25821_vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 387 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 388 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 389 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs, 391 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf, 392 .vidioc_querybuf = cx25821_vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf, 393 .vidioc_qbuf = cx25821_vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf, 394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG 395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std, 396 .vidioc_s_std = cx25821_vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd, 397 .vidioc_querystd = cx25821_vidioc_querystd,
398#endif 398#endif
399 .vidioc_cropcap = vidioc_cropcap, 399 .vidioc_cropcap = cx25821_vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop, 400 .vidioc_s_crop = cx25821_vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop, 401 .vidioc_g_crop = cx25821_vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input, 402 .vidioc_enum_input = cx25821_vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input, 403 .vidioc_g_input = cx25821_vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input, 404 .vidioc_s_input = cx25821_vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl, 405 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl, 406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl, 407 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon, 408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff, 409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status, 410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority, 411 .vidioc_g_priority = cx25821_vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority, 412 .vidioc_s_priority = cx25821_vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT 413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf, 414 .vidiocgmbuf = cx25821_vidiocgmbuf,
415#endif 415#endif
416#ifdef TUNER_FLAG 416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner, 417 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner, 418 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency, 419 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency, 420 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
421#endif 421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG 422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register, 423 .vidioc_g_register = cx25821_vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register, 424 .vidioc_s_register = cx25821_vidioc_s_register,
425#endif 425#endif
426}; 426};
427 427
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
index 5dc08adc12e8..59370337b076 100644
--- a/drivers/staging/cx25821/cx25821-video5.c
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -147,7 +147,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
147 147
148 switch (fh->type) { 148 switch (fh->type) {
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 149 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
150 if (res_locked(fh->dev, RESOURCE_VIDEO5)) 150 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO5))
151 return -EBUSY; 151 return -EBUSY;
152 152
153 return videobuf_read_one(&fh->vidq, data, count, ppos, 153 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -165,7 +165,7 @@ static unsigned int video_poll(struct file *file,
165 struct cx25821_fh *fh = file->private_data; 165 struct cx25821_fh *fh = file->private_data;
166 struct cx25821_buffer *buf; 166 struct cx25821_buffer *buf;
167 167
168 if (res_check(fh, RESOURCE_VIDEO5)) { 168 if (cx25821_res_check(fh, RESOURCE_VIDEO5)) {
169 /* streaming capture */ 169 /* streaming capture */
170 if (list_empty(&fh->vidq.stream)) 170 if (list_empty(&fh->vidq.stream))
171 return POLLERR; 171 return POLLERR;
@@ -207,19 +207,19 @@ static int video_release(struct file *file)
207 cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */ 207 cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */
208 208
209 /* stop video capture */ 209 /* stop video capture */
210 if (res_check(fh, RESOURCE_VIDEO5)) { 210 if (cx25821_res_check(fh, RESOURCE_VIDEO5)) {
211 videobuf_queue_cancel(&fh->vidq); 211 videobuf_queue_cancel(&fh->vidq);
212 res_free(dev, fh, RESOURCE_VIDEO5); 212 cx25821_res_free(dev, fh, RESOURCE_VIDEO5);
213 } 213 }
214 214
215 if (fh->vidq.read_buf) { 215 if (fh->vidq.read_buf) {
216 buffer_release(&fh->vidq, fh->vidq.read_buf); 216 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
217 kfree(fh->vidq.read_buf); 217 kfree(fh->vidq.read_buf);
218 } 218 }
219 219
220 videobuf_mmap_free(&fh->vidq); 220 videobuf_mmap_free(&fh->vidq);
221 221
222 v4l2_prio_close(&dev->prio, &fh->prio); 222 v4l2_prio_close(&dev->prio, fh->prio);
223 file->private_data = NULL; 223 file->private_data = NULL;
224 kfree(fh); 224 kfree(fh);
225 225
@@ -239,7 +239,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
239 return -EINVAL; 239 return -EINVAL;
240 } 240 }
241 241
242 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO5)))) { 242 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO5)))) {
243 return -EBUSY; 243 return -EBUSY;
244 } 244 }
245 245
@@ -257,11 +257,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
257 if (i != fh->type) 257 if (i != fh->type)
258 return -EINVAL; 258 return -EINVAL;
259 259
260 res = get_resource(fh, RESOURCE_VIDEO5); 260 res = cx25821_get_resource(fh, RESOURCE_VIDEO5);
261 err = videobuf_streamoff(get_queue(fh)); 261 err = videobuf_streamoff(get_queue(fh));
262 if (err < 0) 262 if (err < 0)
263 return err; 263 return err;
264 res_free(dev, fh, res); 264 cx25821_res_free(dev, fh, res);
265 return 0; 265 return 0;
266} 266}
267 267
@@ -274,13 +274,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
274 int pix_format = 0; 274 int pix_format = 0;
275 275
276 if (fh) { 276 if (fh) {
277 err = v4l2_prio_check(&dev->prio, &fh->prio); 277 err = v4l2_prio_check(&dev->prio, fh->prio);
278 if (0 != err) 278 if (0 != err)
279 return err; 279 return err;
280 } 280 }
281 281
282 dprintk(2, "%s()\n", __func__); 282 dprintk(2, "%s()\n", __func__);
283 err = vidioc_try_fmt_vid_cap(file, priv, f); 283 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
284 284
285 if (0 != err) 285 if (0 != err)
286 return err; 286 return err;
@@ -289,11 +289,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
289 fh->vidq.field = f->fmt.pix.field; 289 fh->vidq.field = f->fmt.pix.field;
290 290
291 // check if width and height is valid based on set standard 291 // check if width and height is valid based on set standard
292 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 292 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
293 fh->width = f->fmt.pix.width; 293 fh->width = f->fmt.pix.width;
294 } 294 }
295 295
296 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 296 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
297 fh->height = f->fmt.pix.height; 297 fh->height = f->fmt.pix.height;
298 } 298 }
299 299
@@ -363,7 +363,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
363 int err; 363 int err;
364 364
365 if (fh) { 365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio); 366 err = v4l2_prio_check(&dev->prio, fh->prio);
367 if (0 != err) 367 if (0 != err)
368 return err; 368 return err;
369 } 369 }
@@ -378,50 +378,50 @@ static const struct v4l2_file_operations video_fops = {
378 .release = video_release, 378 .release = video_release,
379 .read = video_read, 379 .read = video_read,
380 .poll = video_poll, 380 .poll = video_poll,
381 .mmap = video_mmap, 381 .mmap = cx25821_video_mmap,
382 .ioctl = video_ioctl2, 382 .ioctl = video_ioctl2,
383}; 383};
384 384
385static const struct v4l2_ioctl_ops video_ioctl_ops = { 385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap, 386 .vidioc_querycap = cx25821_vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 387 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 388 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 389 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs, 391 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf, 392 .vidioc_querybuf = cx25821_vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf, 393 .vidioc_qbuf = cx25821_vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf, 394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG 395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std, 396 .vidioc_s_std = cx25821_vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd, 397 .vidioc_querystd = cx25821_vidioc_querystd,
398#endif 398#endif
399 .vidioc_cropcap = vidioc_cropcap, 399 .vidioc_cropcap = cx25821_vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop, 400 .vidioc_s_crop = cx25821_vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop, 401 .vidioc_g_crop = cx25821_vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input, 402 .vidioc_enum_input = cx25821_vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input, 403 .vidioc_g_input = cx25821_vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input, 404 .vidioc_s_input = cx25821_vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl, 405 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl, 406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl, 407 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon, 408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff, 409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status, 410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority, 411 .vidioc_g_priority = cx25821_vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority, 412 .vidioc_s_priority = cx25821_vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT 413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf, 414 .vidiocgmbuf = cx25821_vidiocgmbuf,
415#endif 415#endif
416#ifdef TUNER_FLAG 416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner, 417 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner, 418 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency, 419 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency, 420 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
421#endif 421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG 422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register, 423 .vidioc_g_register = cx25821_vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register, 424 .vidioc_s_register = cx25821_vidioc_s_register,
425#endif 425#endif
426}; 426};
427 427
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
index 2938ad3ad3c5..4db2eb83d35a 100644
--- a/drivers/staging/cx25821/cx25821-video6.c
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -147,7 +147,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
147 147
148 switch (fh->type) { 148 switch (fh->type) {
149 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 149 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
150 if (res_locked(fh->dev, RESOURCE_VIDEO6)) 150 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO6))
151 return -EBUSY; 151 return -EBUSY;
152 152
153 return videobuf_read_one(&fh->vidq, data, count, ppos, 153 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -165,7 +165,7 @@ static unsigned int video_poll(struct file *file,
165 struct cx25821_fh *fh = file->private_data; 165 struct cx25821_fh *fh = file->private_data;
166 struct cx25821_buffer *buf; 166 struct cx25821_buffer *buf;
167 167
168 if (res_check(fh, RESOURCE_VIDEO6)) { 168 if (cx25821_res_check(fh, RESOURCE_VIDEO6)) {
169 /* streaming capture */ 169 /* streaming capture */
170 if (list_empty(&fh->vidq.stream)) 170 if (list_empty(&fh->vidq.stream))
171 return POLLERR; 171 return POLLERR;
@@ -207,18 +207,18 @@ static int video_release(struct file *file)
207 cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */ 207 cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */
208 208
209 /* stop video capture */ 209 /* stop video capture */
210 if (res_check(fh, RESOURCE_VIDEO6)) { 210 if (cx25821_res_check(fh, RESOURCE_VIDEO6)) {
211 videobuf_queue_cancel(&fh->vidq); 211 videobuf_queue_cancel(&fh->vidq);
212 res_free(dev, fh, RESOURCE_VIDEO6); 212 cx25821_res_free(dev, fh, RESOURCE_VIDEO6);
213 } 213 }
214 if (fh->vidq.read_buf) { 214 if (fh->vidq.read_buf) {
215 buffer_release(&fh->vidq, fh->vidq.read_buf); 215 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
216 kfree(fh->vidq.read_buf); 216 kfree(fh->vidq.read_buf);
217 } 217 }
218 218
219 videobuf_mmap_free(&fh->vidq); 219 videobuf_mmap_free(&fh->vidq);
220 220
221 v4l2_prio_close(&dev->prio, &fh->prio); 221 v4l2_prio_close(&dev->prio, fh->prio);
222 file->private_data = NULL; 222 file->private_data = NULL;
223 kfree(fh); 223 kfree(fh);
224 224
@@ -238,7 +238,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
238 return -EINVAL; 238 return -EINVAL;
239 } 239 }
240 240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO6)))) { 241 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO6)))) {
242 return -EBUSY; 242 return -EBUSY;
243 } 243 }
244 244
@@ -256,11 +256,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
256 if (i != fh->type) 256 if (i != fh->type)
257 return -EINVAL; 257 return -EINVAL;
258 258
259 res = get_resource(fh, RESOURCE_VIDEO6); 259 res = cx25821_get_resource(fh, RESOURCE_VIDEO6);
260 err = videobuf_streamoff(get_queue(fh)); 260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0) 261 if (err < 0)
262 return err; 262 return err;
263 res_free(dev, fh, res); 263 cx25821_res_free(dev, fh, res);
264 return 0; 264 return 0;
265} 265}
266 266
@@ -273,13 +273,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
273 int pix_format = 0; 273 int pix_format = 0;
274 274
275 if (fh) { 275 if (fh) {
276 err = v4l2_prio_check(&dev->prio, &fh->prio); 276 err = v4l2_prio_check(&dev->prio, fh->prio);
277 if (0 != err) 277 if (0 != err)
278 return err; 278 return err;
279 } 279 }
280 280
281 dprintk(2, "%s()\n", __func__); 281 dprintk(2, "%s()\n", __func__);
282 err = vidioc_try_fmt_vid_cap(file, priv, f); 282 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
283 283
284 if (0 != err) 284 if (0 != err)
285 return err; 285 return err;
@@ -288,11 +288,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
288 fh->vidq.field = f->fmt.pix.field; 288 fh->vidq.field = f->fmt.pix.field;
289 289
290 // check if width and height is valid based on set standard 290 // check if width and height is valid based on set standard
291 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 291 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
292 fh->width = f->fmt.pix.width; 292 fh->width = f->fmt.pix.width;
293 } 293 }
294 294
295 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 295 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
296 fh->height = f->fmt.pix.height; 296 fh->height = f->fmt.pix.height;
297 } 297 }
298 298
@@ -363,7 +363,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
363 int err; 363 int err;
364 364
365 if (fh) { 365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio); 366 err = v4l2_prio_check(&dev->prio, fh->prio);
367 if (0 != err) 367 if (0 != err)
368 return err; 368 return err;
369 } 369 }
@@ -378,50 +378,50 @@ static const struct v4l2_file_operations video_fops = {
378 .release = video_release, 378 .release = video_release,
379 .read = video_read, 379 .read = video_read,
380 .poll = video_poll, 380 .poll = video_poll,
381 .mmap = video_mmap, 381 .mmap = cx25821_video_mmap,
382 .ioctl = video_ioctl2, 382 .ioctl = video_ioctl2,
383}; 383};
384 384
385static const struct v4l2_ioctl_ops video_ioctl_ops = { 385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap, 386 .vidioc_querycap = cx25821_vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 387 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 388 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 389 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs, 391 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf, 392 .vidioc_querybuf = cx25821_vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf, 393 .vidioc_qbuf = cx25821_vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf, 394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG 395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std, 396 .vidioc_s_std = cx25821_vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd, 397 .vidioc_querystd = cx25821_vidioc_querystd,
398#endif 398#endif
399 .vidioc_cropcap = vidioc_cropcap, 399 .vidioc_cropcap = cx25821_vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop, 400 .vidioc_s_crop = cx25821_vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop, 401 .vidioc_g_crop = cx25821_vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input, 402 .vidioc_enum_input = cx25821_vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input, 403 .vidioc_g_input = cx25821_vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input, 404 .vidioc_s_input = cx25821_vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl, 405 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl, 406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl, 407 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon, 408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff, 409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status, 410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority, 411 .vidioc_g_priority = cx25821_vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority, 412 .vidioc_s_priority = cx25821_vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT 413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf, 414 .vidiocgmbuf = cx25821_vidiocgmbuf,
415#endif 415#endif
416#ifdef TUNER_FLAG 416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner, 417 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner, 418 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency, 419 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency, 420 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
421#endif 421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG 422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register, 423 .vidioc_g_register = cx25821_vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register, 424 .vidioc_s_register = cx25821_vidioc_s_register,
425#endif 425#endif
426}; 426};
427 427
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
index 458e525d72af..5e4a769badad 100644
--- a/drivers/staging/cx25821/cx25821-video7.c
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -85,10 +85,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
85} 85}
86 86
87static struct videobuf_queue_ops cx25821_video_qops = { 87static struct videobuf_queue_ops cx25821_video_qops = {
88 .buf_setup = buffer_setup, 88 .buf_setup = cx25821_buffer_setup,
89 .buf_prepare = buffer_prepare, 89 .buf_prepare = cx25821_buffer_prepare,
90 .buf_queue = buffer_queue, 90 .buf_queue = buffer_queue,
91 .buf_release = buffer_release, 91 .buf_release = cx25821_buffer_release,
92}; 92};
93 93
94static int video_open(struct file *file) 94static int video_open(struct file *file)
@@ -146,7 +146,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
146 146
147 switch (fh->type) { 147 switch (fh->type) {
148 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 148 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
149 if (res_locked(fh->dev, RESOURCE_VIDEO7)) 149 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO7))
150 return -EBUSY; 150 return -EBUSY;
151 151
152 return videobuf_read_one(&fh->vidq, data, count, ppos, 152 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -164,7 +164,7 @@ static unsigned int video_poll(struct file *file,
164 struct cx25821_fh *fh = file->private_data; 164 struct cx25821_fh *fh = file->private_data;
165 struct cx25821_buffer *buf; 165 struct cx25821_buffer *buf;
166 166
167 if (res_check(fh, RESOURCE_VIDEO7)) { 167 if (cx25821_res_check(fh, RESOURCE_VIDEO7)) {
168 /* streaming capture */ 168 /* streaming capture */
169 if (list_empty(&fh->vidq.stream)) 169 if (list_empty(&fh->vidq.stream))
170 return POLLERR; 170 return POLLERR;
@@ -206,19 +206,19 @@ static int video_release(struct file *file)
206 cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */ 206 cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */
207 207
208 /* stop video capture */ 208 /* stop video capture */
209 if (res_check(fh, RESOURCE_VIDEO7)) { 209 if (cx25821_res_check(fh, RESOURCE_VIDEO7)) {
210 videobuf_queue_cancel(&fh->vidq); 210 videobuf_queue_cancel(&fh->vidq);
211 res_free(dev, fh, RESOURCE_VIDEO7); 211 cx25821_res_free(dev, fh, RESOURCE_VIDEO7);
212 } 212 }
213 213
214 if (fh->vidq.read_buf) { 214 if (fh->vidq.read_buf) {
215 buffer_release(&fh->vidq, fh->vidq.read_buf); 215 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
216 kfree(fh->vidq.read_buf); 216 kfree(fh->vidq.read_buf);
217 } 217 }
218 218
219 videobuf_mmap_free(&fh->vidq); 219 videobuf_mmap_free(&fh->vidq);
220 220
221 v4l2_prio_close(&dev->prio, &fh->prio); 221 v4l2_prio_close(&dev->prio, fh->prio);
222 file->private_data = NULL; 222 file->private_data = NULL;
223 kfree(fh); 223 kfree(fh);
224 224
@@ -238,7 +238,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
238 return -EINVAL; 238 return -EINVAL;
239 } 239 }
240 240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO7)))) { 241 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO7)))) {
242 return -EBUSY; 242 return -EBUSY;
243 } 243 }
244 244
@@ -256,11 +256,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
256 if (i != fh->type) 256 if (i != fh->type)
257 return -EINVAL; 257 return -EINVAL;
258 258
259 res = get_resource(fh, RESOURCE_VIDEO7); 259 res = cx25821_get_resource(fh, RESOURCE_VIDEO7);
260 err = videobuf_streamoff(get_queue(fh)); 260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0) 261 if (err < 0)
262 return err; 262 return err;
263 res_free(dev, fh, res); 263 cx25821_res_free(dev, fh, res);
264 return 0; 264 return 0;
265} 265}
266 266
@@ -273,13 +273,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
273 int pix_format = 0; 273 int pix_format = 0;
274 274
275 if (fh) { 275 if (fh) {
276 err = v4l2_prio_check(&dev->prio, &fh->prio); 276 err = v4l2_prio_check(&dev->prio, fh->prio);
277 if (0 != err) 277 if (0 != err)
278 return err; 278 return err;
279 } 279 }
280 280
281 dprintk(2, "%s()\n", __func__); 281 dprintk(2, "%s()\n", __func__);
282 err = vidioc_try_fmt_vid_cap(file, priv, f); 282 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
283 283
284 if (0 != err) 284 if (0 != err)
285 return err; 285 return err;
@@ -288,11 +288,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
288 fh->vidq.field = f->fmt.pix.field; 288 fh->vidq.field = f->fmt.pix.field;
289 289
290 // check if width and height is valid based on set standard 290 // check if width and height is valid based on set standard
291 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) { 291 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
292 fh->width = f->fmt.pix.width; 292 fh->width = f->fmt.pix.width;
293 } 293 }
294 294
295 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) { 295 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
296 fh->height = f->fmt.pix.height; 296 fh->height = f->fmt.pix.height;
297 } 297 }
298 298
@@ -362,7 +362,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
362 int err; 362 int err;
363 363
364 if (fh) { 364 if (fh) {
365 err = v4l2_prio_check(&dev->prio, &fh->prio); 365 err = v4l2_prio_check(&dev->prio, fh->prio);
366 if (0 != err) 366 if (0 != err)
367 return err; 367 return err;
368 } 368 }
@@ -377,50 +377,50 @@ static const struct v4l2_file_operations video_fops = {
377 .release = video_release, 377 .release = video_release,
378 .read = video_read, 378 .read = video_read,
379 .poll = video_poll, 379 .poll = video_poll,
380 .mmap = video_mmap, 380 .mmap = cx25821_video_mmap,
381 .ioctl = video_ioctl2, 381 .ioctl = video_ioctl2,
382}; 382};
383 383
384static const struct v4l2_ioctl_ops video_ioctl_ops = { 384static const struct v4l2_ioctl_ops video_ioctl_ops = {
385 .vidioc_querycap = vidioc_querycap, 385 .vidioc_querycap = cx25821_vidioc_querycap,
386 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 386 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
387 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 387 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
388 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 388 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
389 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 389 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
390 .vidioc_reqbufs = vidioc_reqbufs, 390 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
391 .vidioc_querybuf = vidioc_querybuf, 391 .vidioc_querybuf = cx25821_vidioc_querybuf,
392 .vidioc_qbuf = vidioc_qbuf, 392 .vidioc_qbuf = cx25821_vidioc_qbuf,
393 .vidioc_dqbuf = vidioc_dqbuf, 393 .vidioc_dqbuf = vidioc_dqbuf,
394#ifdef TUNER_FLAG 394#ifdef TUNER_FLAG
395 .vidioc_s_std = vidioc_s_std, 395 .vidioc_s_std = cx25821_vidioc_s_std,
396 .vidioc_querystd = vidioc_querystd, 396 .vidioc_querystd = cx25821_vidioc_querystd,
397#endif 397#endif
398 .vidioc_cropcap = vidioc_cropcap, 398 .vidioc_cropcap = cx25821_vidioc_cropcap,
399 .vidioc_s_crop = vidioc_s_crop, 399 .vidioc_s_crop = cx25821_vidioc_s_crop,
400 .vidioc_g_crop = vidioc_g_crop, 400 .vidioc_g_crop = cx25821_vidioc_g_crop,
401 .vidioc_enum_input = vidioc_enum_input, 401 .vidioc_enum_input = cx25821_vidioc_enum_input,
402 .vidioc_g_input = vidioc_g_input, 402 .vidioc_g_input = cx25821_vidioc_g_input,
403 .vidioc_s_input = vidioc_s_input, 403 .vidioc_s_input = cx25821_vidioc_s_input,
404 .vidioc_g_ctrl = vidioc_g_ctrl, 404 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
405 .vidioc_s_ctrl = vidioc_s_ctrl, 405 .vidioc_s_ctrl = vidioc_s_ctrl,
406 .vidioc_queryctrl = vidioc_queryctrl, 406 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
407 .vidioc_streamon = vidioc_streamon, 407 .vidioc_streamon = vidioc_streamon,
408 .vidioc_streamoff = vidioc_streamoff, 408 .vidioc_streamoff = vidioc_streamoff,
409 .vidioc_log_status = vidioc_log_status, 409 .vidioc_log_status = vidioc_log_status,
410 .vidioc_g_priority = vidioc_g_priority, 410 .vidioc_g_priority = cx25821_vidioc_g_priority,
411 .vidioc_s_priority = vidioc_s_priority, 411 .vidioc_s_priority = cx25821_vidioc_s_priority,
412#ifdef CONFIG_VIDEO_V4L1_COMPAT 412#ifdef CONFIG_VIDEO_V4L1_COMPAT
413 .vidiocgmbuf = vidiocgmbuf, 413 .vidiocgmbuf = cx25821_vidiocgmbuf,
414#endif 414#endif
415#ifdef TUNER_FLAG 415#ifdef TUNER_FLAG
416 .vidioc_g_tuner = vidioc_g_tuner, 416 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
417 .vidioc_s_tuner = vidioc_s_tuner, 417 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
418 .vidioc_g_frequency = vidioc_g_frequency, 418 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
419 .vidioc_s_frequency = vidioc_s_frequency, 419 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
420#endif 420#endif
421#ifdef CONFIG_VIDEO_ADV_DEBUG 421#ifdef CONFIG_VIDEO_ADV_DEBUG
422 .vidioc_g_register = vidioc_g_register, 422 .vidioc_g_register = cx25821_vidioc_g_register,
423 .vidioc_s_register = vidioc_s_register, 423 .vidioc_s_register = cx25821_vidioc_s_register,
424#endif 424#endif
425}; 425};
426 426
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
index 1da52b54a454..d16807d88be0 100644
--- a/drivers/staging/cx25821/cx25821-videoioctl.c
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -145,7 +145,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
145 145
146 switch (fh->type) { 146 switch (fh->type) {
147 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 147 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
148 if (res_locked(fh->dev, RESOURCE_VIDEO_IOCTL)) 148 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
149 return -EBUSY; 149 return -EBUSY;
150 150
151 return videobuf_read_one(&fh->vidq, data, count, ppos, 151 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -163,7 +163,7 @@ static unsigned int video_poll(struct file *file,
163 struct cx25821_fh *fh = file->private_data; 163 struct cx25821_fh *fh = file->private_data;
164 struct cx25821_buffer *buf; 164 struct cx25821_buffer *buf;
165 165
166 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) { 166 if (cx25821_res_check(fh, RESOURCE_VIDEO_IOCTL)) {
167 /* streaming capture */ 167 /* streaming capture */
168 if (list_empty(&fh->vidq.stream)) 168 if (list_empty(&fh->vidq.stream))
169 return POLLERR; 169 return POLLERR;
@@ -189,19 +189,19 @@ static int video_release(struct file *file)
189 struct cx25821_dev *dev = fh->dev; 189 struct cx25821_dev *dev = fh->dev;
190 190
191 /* stop video capture */ 191 /* stop video capture */
192 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) { 192 if (cx25821_res_check(fh, RESOURCE_VIDEO_IOCTL)) {
193 videobuf_queue_cancel(&fh->vidq); 193 videobuf_queue_cancel(&fh->vidq);
194 res_free(dev, fh, RESOURCE_VIDEO_IOCTL); 194 cx25821_res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
195 } 195 }
196 196
197 if (fh->vidq.read_buf) { 197 if (fh->vidq.read_buf) {
198 buffer_release(&fh->vidq, fh->vidq.read_buf); 198 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
199 kfree(fh->vidq.read_buf); 199 kfree(fh->vidq.read_buf);
200 } 200 }
201 201
202 videobuf_mmap_free(&fh->vidq); 202 videobuf_mmap_free(&fh->vidq);
203 203
204 v4l2_prio_close(&dev->prio, &fh->prio); 204 v4l2_prio_close(&dev->prio, fh->prio);
205 205
206 file->private_data = NULL; 206 file->private_data = NULL;
207 kfree(fh); 207 kfree(fh);
@@ -222,7 +222,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 224
225 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO_IOCTL)))) { 225 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO_IOCTL)))) {
226 return -EBUSY; 226 return -EBUSY;
227 } 227 }
228 228
@@ -240,11 +240,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
240 if (i != fh->type) 240 if (i != fh->type)
241 return -EINVAL; 241 return -EINVAL;
242 242
243 res = get_resource(fh, RESOURCE_VIDEO_IOCTL); 243 res = cx25821_get_resource(fh, RESOURCE_VIDEO_IOCTL);
244 err = videobuf_streamoff(get_queue(fh)); 244 err = videobuf_streamoff(get_queue(fh));
245 if (err < 0) 245 if (err < 0)
246 return err; 246 return err;
247 res_free(dev, fh, res); 247 cx25821_res_free(dev, fh, res);
248 return 0; 248 return 0;
249} 249}
250 250
@@ -256,13 +256,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
256 int err; 256 int err;
257 257
258 if (fh) { 258 if (fh) {
259 err = v4l2_prio_check(&dev->prio, &fh->prio); 259 err = v4l2_prio_check(&dev->prio, fh->prio);
260 if (0 != err) 260 if (0 != err)
261 return err; 261 return err;
262 } 262 }
263 263
264 dprintk(2, "%s()\n", __func__); 264 dprintk(2, "%s()\n", __func__);
265 err = vidioc_try_fmt_vid_cap(file, priv, f); 265 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
266 266
267 if (0 != err) 267 if (0 != err)
268 return err; 268 return err;
@@ -409,7 +409,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
409 int err; 409 int err;
410 410
411 if (fh) { 411 if (fh) {
412 err = v4l2_prio_check(&dev->prio, &fh->prio); 412 err = v4l2_prio_check(&dev->prio, fh->prio);
413 if (0 != err) 413 if (0 != err)
414 return err; 414 return err;
415 } 415 }
@@ -424,50 +424,50 @@ static const struct v4l2_file_operations video_fops = {
424 .release = video_release, 424 .release = video_release,
425 .read = video_read, 425 .read = video_read,
426 .poll = video_poll, 426 .poll = video_poll,
427 .mmap = video_mmap, 427 .mmap = cx25821_video_mmap,
428 .ioctl = video_ioctl_set, 428 .ioctl = video_ioctl_set,
429}; 429};
430 430
431static const struct v4l2_ioctl_ops video_ioctl_ops = { 431static const struct v4l2_ioctl_ops video_ioctl_ops = {
432 .vidioc_querycap = vidioc_querycap, 432 .vidioc_querycap = cx25821_vidioc_querycap,
433 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 433 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
434 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 434 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
435 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 435 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
436 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 436 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
437 .vidioc_reqbufs = vidioc_reqbufs, 437 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
438 .vidioc_querybuf = vidioc_querybuf, 438 .vidioc_querybuf = cx25821_vidioc_querybuf,
439 .vidioc_qbuf = vidioc_qbuf, 439 .vidioc_qbuf = cx25821_vidioc_qbuf,
440 .vidioc_dqbuf = vidioc_dqbuf, 440 .vidioc_dqbuf = vidioc_dqbuf,
441#ifdef TUNER_FLAG 441#ifdef TUNER_FLAG
442 .vidioc_s_std = vidioc_s_std, 442 .vidioc_s_std = cx25821_vidioc_s_std,
443 .vidioc_querystd = vidioc_querystd, 443 .vidioc_querystd = cx25821_vidioc_querystd,
444#endif 444#endif
445 .vidioc_cropcap = vidioc_cropcap, 445 .vidioc_cropcap = cx25821_vidioc_cropcap,
446 .vidioc_s_crop = vidioc_s_crop, 446 .vidioc_s_crop = cx25821_vidioc_s_crop,
447 .vidioc_g_crop = vidioc_g_crop, 447 .vidioc_g_crop = cx25821_vidioc_g_crop,
448 .vidioc_enum_input = vidioc_enum_input, 448 .vidioc_enum_input = cx25821_vidioc_enum_input,
449 .vidioc_g_input = vidioc_g_input, 449 .vidioc_g_input = cx25821_vidioc_g_input,
450 .vidioc_s_input = vidioc_s_input, 450 .vidioc_s_input = cx25821_vidioc_s_input,
451 .vidioc_g_ctrl = vidioc_g_ctrl, 451 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
452 .vidioc_s_ctrl = vidioc_s_ctrl, 452 .vidioc_s_ctrl = vidioc_s_ctrl,
453 .vidioc_queryctrl = vidioc_queryctrl, 453 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
454 .vidioc_streamon = vidioc_streamon, 454 .vidioc_streamon = vidioc_streamon,
455 .vidioc_streamoff = vidioc_streamoff, 455 .vidioc_streamoff = vidioc_streamoff,
456 .vidioc_log_status = vidioc_log_status, 456 .vidioc_log_status = vidioc_log_status,
457 .vidioc_g_priority = vidioc_g_priority, 457 .vidioc_g_priority = cx25821_vidioc_g_priority,
458 .vidioc_s_priority = vidioc_s_priority, 458 .vidioc_s_priority = cx25821_vidioc_s_priority,
459#ifdef CONFIG_VIDEO_V4L1_COMPAT 459#ifdef CONFIG_VIDEO_V4L1_COMPAT
460 .vidiocgmbuf = vidiocgmbuf, 460 .vidiocgmbuf = cx25821_vidiocgmbuf,
461#endif 461#endif
462#ifdef TUNER_FLAG 462#ifdef TUNER_FLAG
463 .vidioc_g_tuner = vidioc_g_tuner, 463 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
464 .vidioc_s_tuner = vidioc_s_tuner, 464 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
465 .vidioc_g_frequency = vidioc_g_frequency, 465 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
466 .vidioc_s_frequency = vidioc_s_frequency, 466 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
467#endif 467#endif
468#ifdef CONFIG_VIDEO_ADV_DEBUG 468#ifdef CONFIG_VIDEO_ADV_DEBUG
469 .vidioc_g_register = vidioc_g_register, 469 .vidioc_g_register = cx25821_vidioc_g_register,
470 .vidioc_s_register = vidioc_s_register, 470 .vidioc_s_register = cx25821_vidioc_s_register,
471#endif 471#endif
472}; 472};
473 473
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
index b76d9f62c3d1..c746a17ccbd2 100644
--- a/drivers/staging/cx25821/cx25821-vidups10.c
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -143,7 +143,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
143 143
144 switch (fh->type) { 144 switch (fh->type) {
145 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 145 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
146 if (res_locked(fh->dev, RESOURCE_VIDEO10)) 146 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO10))
147 return -EBUSY; 147 return -EBUSY;
148 148
149 return videobuf_read_one(&fh->vidq, data, count, ppos, 149 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -161,7 +161,7 @@ static unsigned int video_poll(struct file *file,
161 struct cx25821_fh *fh = file->private_data; 161 struct cx25821_fh *fh = file->private_data;
162 struct cx25821_buffer *buf; 162 struct cx25821_buffer *buf;
163 163
164 if (res_check(fh, RESOURCE_VIDEO10)) { 164 if (cx25821_res_check(fh, RESOURCE_VIDEO10)) {
165 /* streaming capture */ 165 /* streaming capture */
166 if (list_empty(&fh->vidq.stream)) 166 if (list_empty(&fh->vidq.stream))
167 return POLLERR; 167 return POLLERR;
@@ -189,19 +189,19 @@ static int video_release(struct file *file)
189 //cx_write(channel10->dma_ctl, 0); 189 //cx_write(channel10->dma_ctl, 0);
190 190
191 /* stop video capture */ 191 /* stop video capture */
192 if (res_check(fh, RESOURCE_VIDEO10)) { 192 if (cx25821_res_check(fh, RESOURCE_VIDEO10)) {
193 videobuf_queue_cancel(&fh->vidq); 193 videobuf_queue_cancel(&fh->vidq);
194 res_free(dev, fh, RESOURCE_VIDEO10); 194 cx25821_res_free(dev, fh, RESOURCE_VIDEO10);
195 } 195 }
196 196
197 if (fh->vidq.read_buf) { 197 if (fh->vidq.read_buf) {
198 buffer_release(&fh->vidq, fh->vidq.read_buf); 198 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
199 kfree(fh->vidq.read_buf); 199 kfree(fh->vidq.read_buf);
200 } 200 }
201 201
202 videobuf_mmap_free(&fh->vidq); 202 videobuf_mmap_free(&fh->vidq);
203 203
204 v4l2_prio_close(&dev->prio, &fh->prio); 204 v4l2_prio_close(&dev->prio, fh->prio);
205 205
206 file->private_data = NULL; 206 file->private_data = NULL;
207 kfree(fh); 207 kfree(fh);
@@ -222,7 +222,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 224
225 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO10)))) { 225 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO10)))) {
226 return -EBUSY; 226 return -EBUSY;
227 } 227 }
228 228
@@ -240,11 +240,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
240 if (i != fh->type) 240 if (i != fh->type)
241 return -EINVAL; 241 return -EINVAL;
242 242
243 res = get_resource(fh, RESOURCE_VIDEO10); 243 res = cx25821_get_resource(fh, RESOURCE_VIDEO10);
244 err = videobuf_streamoff(get_queue(fh)); 244 err = videobuf_streamoff(get_queue(fh));
245 if (err < 0) 245 if (err < 0)
246 return err; 246 return err;
247 res_free(dev, fh, res); 247 cx25821_res_free(dev, fh, res);
248 return 0; 248 return 0;
249} 249}
250 250
@@ -299,13 +299,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
299 int err; 299 int err;
300 300
301 if (fh) { 301 if (fh) {
302 err = v4l2_prio_check(&dev->prio, &fh->prio); 302 err = v4l2_prio_check(&dev->prio, fh->prio);
303 if (0 != err) 303 if (0 != err)
304 return err; 304 return err;
305 } 305 }
306 306
307 dprintk(2, "%s()\n", __func__); 307 dprintk(2, "%s()\n", __func__);
308 err = vidioc_try_fmt_vid_cap(file, priv, f); 308 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
309 309
310 if (0 != err) 310 if (0 != err)
311 return err; 311 return err;
@@ -347,7 +347,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
347 int err; 347 int err;
348 348
349 if (fh) { 349 if (fh) {
350 err = v4l2_prio_check(&dev->prio, &fh->prio); 350 err = v4l2_prio_check(&dev->prio, fh->prio);
351 if (0 != err) 351 if (0 != err)
352 return err; 352 return err;
353 } 353 }
@@ -362,50 +362,50 @@ static const struct v4l2_file_operations video_fops = {
362 .release = video_release, 362 .release = video_release,
363 .read = video_read, 363 .read = video_read,
364 .poll = video_poll, 364 .poll = video_poll,
365 .mmap = video_mmap, 365 .mmap = cx25821_video_mmap,
366 .ioctl = video_ioctl_upstream10, 366 .ioctl = video_ioctl_upstream10,
367}; 367};
368 368
369static const struct v4l2_ioctl_ops video_ioctl_ops = { 369static const struct v4l2_ioctl_ops video_ioctl_ops = {
370 .vidioc_querycap = vidioc_querycap, 370 .vidioc_querycap = cx25821_vidioc_querycap,
371 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 371 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
372 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 372 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
373 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 373 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
374 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 374 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
375 .vidioc_reqbufs = vidioc_reqbufs, 375 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
376 .vidioc_querybuf = vidioc_querybuf, 376 .vidioc_querybuf = cx25821_vidioc_querybuf,
377 .vidioc_qbuf = vidioc_qbuf, 377 .vidioc_qbuf = cx25821_vidioc_qbuf,
378 .vidioc_dqbuf = vidioc_dqbuf, 378 .vidioc_dqbuf = vidioc_dqbuf,
379#ifdef TUNER_FLAG 379#ifdef TUNER_FLAG
380 .vidioc_s_std = vidioc_s_std, 380 .vidioc_s_std = cx25821_vidioc_s_std,
381 .vidioc_querystd = vidioc_querystd, 381 .vidioc_querystd = cx25821_vidioc_querystd,
382#endif 382#endif
383 .vidioc_cropcap = vidioc_cropcap, 383 .vidioc_cropcap = cx25821_vidioc_cropcap,
384 .vidioc_s_crop = vidioc_s_crop, 384 .vidioc_s_crop = cx25821_vidioc_s_crop,
385 .vidioc_g_crop = vidioc_g_crop, 385 .vidioc_g_crop = cx25821_vidioc_g_crop,
386 .vidioc_enum_input = vidioc_enum_input, 386 .vidioc_enum_input = cx25821_vidioc_enum_input,
387 .vidioc_g_input = vidioc_g_input, 387 .vidioc_g_input = cx25821_vidioc_g_input,
388 .vidioc_s_input = vidioc_s_input, 388 .vidioc_s_input = cx25821_vidioc_s_input,
389 .vidioc_g_ctrl = vidioc_g_ctrl, 389 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
390 .vidioc_s_ctrl = vidioc_s_ctrl, 390 .vidioc_s_ctrl = vidioc_s_ctrl,
391 .vidioc_queryctrl = vidioc_queryctrl, 391 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
392 .vidioc_streamon = vidioc_streamon, 392 .vidioc_streamon = vidioc_streamon,
393 .vidioc_streamoff = vidioc_streamoff, 393 .vidioc_streamoff = vidioc_streamoff,
394 .vidioc_log_status = vidioc_log_status, 394 .vidioc_log_status = vidioc_log_status,
395 .vidioc_g_priority = vidioc_g_priority, 395 .vidioc_g_priority = cx25821_vidioc_g_priority,
396 .vidioc_s_priority = vidioc_s_priority, 396 .vidioc_s_priority = cx25821_vidioc_s_priority,
397#ifdef CONFIG_VIDEO_V4L1_COMPAT 397#ifdef CONFIG_VIDEO_V4L1_COMPAT
398 .vidiocgmbuf = vidiocgmbuf, 398 .vidiocgmbuf = cx25821_vidiocgmbuf,
399#endif 399#endif
400#ifdef TUNER_FLAG 400#ifdef TUNER_FLAG
401 .vidioc_g_tuner = vidioc_g_tuner, 401 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
402 .vidioc_s_tuner = vidioc_s_tuner, 402 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
403 .vidioc_g_frequency = vidioc_g_frequency, 403 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
404 .vidioc_s_frequency = vidioc_s_frequency, 404 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
405#endif 405#endif
406#ifdef CONFIG_VIDEO_ADV_DEBUG 406#ifdef CONFIG_VIDEO_ADV_DEBUG
407 .vidioc_g_register = vidioc_g_register, 407 .vidioc_g_register = cx25821_vidioc_g_register,
408 .vidioc_s_register = vidioc_s_register, 408 .vidioc_s_register = cx25821_vidioc_s_register,
409#endif 409#endif
410}; 410};
411 411
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
index 1580da3b29aa..466e0f34ae34 100644
--- a/drivers/staging/cx25821/cx25821-vidups9.c
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -86,10 +86,10 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
86} 86}
87 87
88static struct videobuf_queue_ops cx25821_video_qops = { 88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup, 89 .buf_setup = cx25821_buffer_setup,
90 .buf_prepare = buffer_prepare, 90 .buf_prepare = cx25821_buffer_prepare,
91 .buf_queue = buffer_queue, 91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release, 92 .buf_release = cx25821_buffer_release,
93}; 93};
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
@@ -143,7 +143,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
143 143
144 switch (fh->type) { 144 switch (fh->type) {
145 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 145 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
146 if (res_locked(fh->dev, RESOURCE_VIDEO9)) 146 if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO9))
147 return -EBUSY; 147 return -EBUSY;
148 148
149 return videobuf_read_one(&fh->vidq, data, count, ppos, 149 return videobuf_read_one(&fh->vidq, data, count, ppos,
@@ -161,7 +161,7 @@ static unsigned int video_poll(struct file *file,
161 struct cx25821_fh *fh = file->private_data; 161 struct cx25821_fh *fh = file->private_data;
162 struct cx25821_buffer *buf; 162 struct cx25821_buffer *buf;
163 163
164 if (res_check(fh, RESOURCE_VIDEO9)) { 164 if (cx25821_res_check(fh, RESOURCE_VIDEO9)) {
165 /* streaming capture */ 165 /* streaming capture */
166 if (list_empty(&fh->vidq.stream)) 166 if (list_empty(&fh->vidq.stream))
167 return POLLERR; 167 return POLLERR;
@@ -189,19 +189,19 @@ static int video_release(struct file *file)
189 //cx_write(channel9->dma_ctl, 0); 189 //cx_write(channel9->dma_ctl, 0);
190 190
191 /* stop video capture */ 191 /* stop video capture */
192 if (res_check(fh, RESOURCE_VIDEO9)) { 192 if (cx25821_res_check(fh, RESOURCE_VIDEO9)) {
193 videobuf_queue_cancel(&fh->vidq); 193 videobuf_queue_cancel(&fh->vidq);
194 res_free(dev, fh, RESOURCE_VIDEO9); 194 cx25821_res_free(dev, fh, RESOURCE_VIDEO9);
195 } 195 }
196 196
197 if (fh->vidq.read_buf) { 197 if (fh->vidq.read_buf) {
198 buffer_release(&fh->vidq, fh->vidq.read_buf); 198 cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
199 kfree(fh->vidq.read_buf); 199 kfree(fh->vidq.read_buf);
200 } 200 }
201 201
202 videobuf_mmap_free(&fh->vidq); 202 videobuf_mmap_free(&fh->vidq);
203 203
204 v4l2_prio_close(&dev->prio, &fh->prio); 204 v4l2_prio_close(&dev->prio, fh->prio);
205 205
206 file->private_data = NULL; 206 file->private_data = NULL;
207 kfree(fh); 207 kfree(fh);
@@ -222,7 +222,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 224
225 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO9)))) { 225 if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO9)))) {
226 return -EBUSY; 226 return -EBUSY;
227 } 227 }
228 228
@@ -240,11 +240,11 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
240 if (i != fh->type) 240 if (i != fh->type)
241 return -EINVAL; 241 return -EINVAL;
242 242
243 res = get_resource(fh, RESOURCE_VIDEO9); 243 res = cx25821_get_resource(fh, RESOURCE_VIDEO9);
244 err = videobuf_streamoff(get_queue(fh)); 244 err = videobuf_streamoff(get_queue(fh));
245 if (err < 0) 245 if (err < 0)
246 return err; 246 return err;
247 res_free(dev, fh, res); 247 cx25821_res_free(dev, fh, res);
248 return 0; 248 return 0;
249} 249}
250 250
@@ -299,13 +299,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
299 int err; 299 int err;
300 300
301 if (fh) { 301 if (fh) {
302 err = v4l2_prio_check(&dev->prio, &fh->prio); 302 err = v4l2_prio_check(&dev->prio, fh->prio);
303 if (0 != err) 303 if (0 != err)
304 return err; 304 return err;
305 } 305 }
306 306
307 dprintk(2, "%s()\n", __func__); 307 dprintk(2, "%s()\n", __func__);
308 err = vidioc_try_fmt_vid_cap(file, priv, f); 308 err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
309 309
310 if (0 != err) 310 if (0 != err)
311 return err; 311 return err;
@@ -345,7 +345,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
345 struct cx25821_fh *fh = priv; 345 struct cx25821_fh *fh = priv;
346 int err; 346 int err;
347 if (fh) { 347 if (fh) {
348 err = v4l2_prio_check(&dev->prio, &fh->prio); 348 err = v4l2_prio_check(&dev->prio, fh->prio);
349 if (0 != err) 349 if (0 != err)
350 return err; 350 return err;
351 } 351 }
@@ -360,50 +360,50 @@ static const struct v4l2_file_operations video_fops = {
360 .release = video_release, 360 .release = video_release,
361 .read = video_read, 361 .read = video_read,
362 .poll = video_poll, 362 .poll = video_poll,
363 .mmap = video_mmap, 363 .mmap = cx25821_video_mmap,
364 .ioctl = video_ioctl_upstream9, 364 .ioctl = video_ioctl_upstream9,
365}; 365};
366 366
367static const struct v4l2_ioctl_ops video_ioctl_ops = { 367static const struct v4l2_ioctl_ops video_ioctl_ops = {
368 .vidioc_querycap = vidioc_querycap, 368 .vidioc_querycap = cx25821_vidioc_querycap,
369 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 369 .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
370 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 370 .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
371 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 371 .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
372 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 372 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
373 .vidioc_reqbufs = vidioc_reqbufs, 373 .vidioc_reqbufs = cx25821_vidioc_reqbufs,
374 .vidioc_querybuf = vidioc_querybuf, 374 .vidioc_querybuf = cx25821_vidioc_querybuf,
375 .vidioc_qbuf = vidioc_qbuf, 375 .vidioc_qbuf = cx25821_vidioc_qbuf,
376 .vidioc_dqbuf = vidioc_dqbuf, 376 .vidioc_dqbuf = vidioc_dqbuf,
377#ifdef TUNER_FLAG 377#ifdef TUNER_FLAG
378 .vidioc_s_std = vidioc_s_std, 378 .vidioc_s_std = cx25821_vidioc_s_std,
379 .vidioc_querystd = vidioc_querystd, 379 .vidioc_querystd = cx25821_vidioc_querystd,
380#endif 380#endif
381 .vidioc_cropcap = vidioc_cropcap, 381 .vidioc_cropcap = cx25821_vidioc_cropcap,
382 .vidioc_s_crop = vidioc_s_crop, 382 .vidioc_s_crop = cx25821_vidioc_s_crop,
383 .vidioc_g_crop = vidioc_g_crop, 383 .vidioc_g_crop = cx25821_vidioc_g_crop,
384 .vidioc_enum_input = vidioc_enum_input, 384 .vidioc_enum_input = cx25821_vidioc_enum_input,
385 .vidioc_g_input = vidioc_g_input, 385 .vidioc_g_input = cx25821_vidioc_g_input,
386 .vidioc_s_input = vidioc_s_input, 386 .vidioc_s_input = cx25821_vidioc_s_input,
387 .vidioc_g_ctrl = vidioc_g_ctrl, 387 .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
388 .vidioc_s_ctrl = vidioc_s_ctrl, 388 .vidioc_s_ctrl = vidioc_s_ctrl,
389 .vidioc_queryctrl = vidioc_queryctrl, 389 .vidioc_queryctrl = cx25821_vidioc_queryctrl,
390 .vidioc_streamon = vidioc_streamon, 390 .vidioc_streamon = vidioc_streamon,
391 .vidioc_streamoff = vidioc_streamoff, 391 .vidioc_streamoff = vidioc_streamoff,
392 .vidioc_log_status = vidioc_log_status, 392 .vidioc_log_status = vidioc_log_status,
393 .vidioc_g_priority = vidioc_g_priority, 393 .vidioc_g_priority = cx25821_vidioc_g_priority,
394 .vidioc_s_priority = vidioc_s_priority, 394 .vidioc_s_priority = cx25821_vidioc_s_priority,
395#ifdef CONFIG_VIDEO_V4L1_COMPAT 395#ifdef CONFIG_VIDEO_V4L1_COMPAT
396 .vidiocgmbuf = vidiocgmbuf, 396 .vidiocgmbuf = cx25821_vidiocgmbuf,
397#endif 397#endif
398#ifdef TUNER_FLAG 398#ifdef TUNER_FLAG
399 .vidioc_g_tuner = vidioc_g_tuner, 399 .vidioc_g_tuner = cx25821_vidioc_g_tuner,
400 .vidioc_s_tuner = vidioc_s_tuner, 400 .vidioc_s_tuner = cx25821_vidioc_s_tuner,
401 .vidioc_g_frequency = vidioc_g_frequency, 401 .vidioc_g_frequency = cx25821_vidioc_g_frequency,
402 .vidioc_s_frequency = vidioc_s_frequency, 402 .vidioc_s_frequency = cx25821_vidioc_s_frequency,
403#endif 403#endif
404#ifdef CONFIG_VIDEO_ADV_DEBUG 404#ifdef CONFIG_VIDEO_ADV_DEBUG
405 .vidioc_g_register = vidioc_g_register, 405 .vidioc_g_register = cx25821_vidioc_g_register,
406 .vidioc_s_register = vidioc_s_register, 406 .vidioc_s_register = cx25821_vidioc_s_register,
407#endif 407#endif
408}; 408};
409 409
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
new file mode 100644
index 000000000000..5fe759cc2ee9
--- /dev/null
+++ b/drivers/staging/tm6000/Kconfig
@@ -0,0 +1,32 @@
1config VIDEO_TM6000
2 tristate "TV Master TM5600/6000/6010 driver"
3 depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL
4 select VIDEO_TUNER
5 select TUNER_XC2028
6 select VIDEOBUF_VMALLOC
7 help
8 Support for TM5600/TM6000/TM6010 USB Device
9
10 Since these cards have no MPEG decoder onboard, they transmit
11 only compressed MPEG data over the usb bus, so you need
12 an external software decoder to watch TV on your computer.
13
14 Say Y if you own such a device and want to use it.
15
16config VIDEO_TM6000_ALSA
17 tristate "TV Master TM5600/6000/6010 audio support"
18 depends on VIDEO_TM6000 && SND && EXPERIMENTAL
19 select SND_PCM
20 ---help---
21 This is a video4linux driver for direct (DMA) audio for
22 TM5600/TM6000/TM6010 USB Devices.
23
24 To compile this driver as a module, choose M here: the
25 module will be called tm6000-alsa.
26
27config VIDEO_TM6000_DVB
28 bool "DVB Support for tm6000 based TV cards"
29 depends on VIDEO_TM6000 && DVB_CORE && EXPERIMENTAL
30 select DVB_ZL10353
31 ---help---
32 This adds support for DVB cards based on the tm5600/tm6000 chip.
diff --git a/drivers/staging/tm6000/Makefile b/drivers/staging/tm6000/Makefile
new file mode 100644
index 000000000000..93370fccc073
--- /dev/null
+++ b/drivers/staging/tm6000/Makefile
@@ -0,0 +1,17 @@
1tm6000-objs := tm6000-cards.o \
2 tm6000-core.o \
3 tm6000-i2c.o \
4 tm6000-video.o \
5 tm6000-stds.o
6
7ifeq ($(CONFIG_VIDEO_TM6000_DVB),y)
8tm6000-objs += tm6000-dvb.o
9endif
10
11obj-$(CONFIG_VIDEO_TM6000) += tm6000.o
12obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
13
14EXTRA_CFLAGS = -Idrivers/media/video
15EXTRA_CFLAGS += -Idrivers/media/common/tuners
16EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
17EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/staging/tm6000/README b/drivers/staging/tm6000/README
new file mode 100644
index 000000000000..c340ebc2ee9f
--- /dev/null
+++ b/drivers/staging/tm6000/README
@@ -0,0 +1,22 @@
1Todo:
2 - Fix the loss of some blocks when receiving the video URB's
3 - Add a lock at tm6000_read_write_usb() to prevent two simultaneous access to the
4 URB control transfers
5 - Properly add the locks at tm6000-video
6 - Add audio support
7 - Add vbi support
8 - Add IR support
9 - Do several cleanups
10 - I think that frame1/frame0 are inverted. This causes a funny effect at the image.
11 the fix is trivial, but require some tests
12 - My tm6010 devices sometimes insist on stop working. I need to turn them off, removing
13 from my machine and wait for a while for it to work again. I'm starting to think that
14 it is an overheat issue - is there a workaround that we could do?
15 - Sometimes, tm6010 doesn't read eeprom at the proper time (hardware bug). So, the device
16 got miss-detected as a "generic" tm6000. This can be really bad if the tuner is the
17 Low Power one, as it may result on loading the high power firmware, that could damage
18 the device. Maybe we may read eeprom to double check, when the device is marked as "generic"
19 - Coding Style fixes
20 - sparse cleanups
21
22Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
new file mode 100644
index 000000000000..bc89f9d28002
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -0,0 +1,414 @@
1/*
2 *
3 * Support for audio capture for tm5600/6000/6010
4 * (c) 2007-2008 Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * Based on cx88-alsa.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/interrupt.h>
17#include <linux/usb.h>
18
19#include <asm/delay.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/control.h>
24#include <sound/initval.h>
25
26
27#include "tm6000.h"
28#include "tm6000-regs.h"
29
30#undef dprintk
31
32#define dprintk(level, fmt, arg...) do { \
33 if (debug >= level) \
34 printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg); \
35 } while (0)
36
37/****************************************************************************
38 Data type declarations - Can be moded to a header file later
39 ****************************************************************************/
40
41struct snd_tm6000_card {
42 struct snd_card *card;
43
44 spinlock_t reg_lock;
45
46 atomic_t count;
47
48 unsigned int period_size;
49 unsigned int num_periods;
50
51 struct tm6000_core *core;
52 struct tm6000_buffer *buf;
53
54 int bufsize;
55
56 struct snd_pcm_substream *substream;
57};
58
59
60/****************************************************************************
61 Module global static vars
62 ****************************************************************************/
63
64static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
65static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
66static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
67
68module_param_array(enable, bool, NULL, 0444);
69MODULE_PARM_DESC(enable, "Enable tm6000x soundcard. default enabled.");
70
71module_param_array(index, int, NULL, 0444);
72MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s).");
73
74
75/****************************************************************************
76 Module macros
77 ****************************************************************************/
78
79MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards");
80MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
81MODULE_LICENSE("GPL");
82MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},"
83 "{{Trident,tm6000},"
84 "{{Trident,tm6010}");
85static unsigned int debug;
86module_param(debug, int, 0644);
87MODULE_PARM_DESC(debug, "enable debug messages");
88
89/****************************************************************************
90 Module specific funtions
91 ****************************************************************************/
92
93/*
94 * BOARD Specific: Sets audio DMA
95 */
96
97static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
98{
99 struct tm6000_core *core = chip->core;
100 int val;
101
102 /* Enables audio */
103 val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0);
104 val |= 0x20;
105 tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
106
107 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0x80);
108
109 return 0;
110}
111
112/*
113 * BOARD Specific: Resets audio DMA
114 */
115static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
116{
117 struct tm6000_core *core = chip->core;
118 int val;
119 dprintk(1, "Stopping audio DMA\n");
120
121 /* Enables audio */
122 val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0);
123 val &= ~0x20;
124 tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
125
126 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0);
127
128 return 0;
129}
130
131static int dsp_buffer_free(struct snd_tm6000_card *chip)
132{
133 BUG_ON(!chip->bufsize);
134
135 dprintk(2, "Freeing buffer\n");
136
137 /* FIXME: Frees buffer */
138
139 chip->bufsize = 0;
140
141 return 0;
142}
143
144/****************************************************************************
145 ALSA PCM Interface
146 ****************************************************************************/
147
148/*
149 * Digital hardware definition
150 */
151#define DEFAULT_FIFO_SIZE 4096
152
153static struct snd_pcm_hardware snd_tm6000_digital_hw = {
154 .info = SNDRV_PCM_INFO_MMAP |
155 SNDRV_PCM_INFO_INTERLEAVED |
156 SNDRV_PCM_INFO_BLOCK_TRANSFER |
157 SNDRV_PCM_INFO_MMAP_VALID,
158 .formats = SNDRV_PCM_FMTBIT_S16_LE,
159
160 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
161 .rate_min = 44100,
162 .rate_max = 48000,
163 .channels_min = 2,
164 .channels_max = 2,
165 .period_bytes_min = DEFAULT_FIFO_SIZE/4,
166 .period_bytes_max = DEFAULT_FIFO_SIZE/4,
167 .periods_min = 1,
168 .periods_max = 1024,
169 .buffer_bytes_max = (1024*1024),
170};
171
172/*
173 * audio pcm capture open callback
174 */
175static int snd_tm6000_pcm_open(struct snd_pcm_substream *substream)
176{
177 struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
178 struct snd_pcm_runtime *runtime = substream->runtime;
179 int err;
180
181 err = snd_pcm_hw_constraint_pow2(runtime, 0,
182 SNDRV_PCM_HW_PARAM_PERIODS);
183 if (err < 0)
184 goto _error;
185
186 chip->substream = substream;
187
188 runtime->hw = snd_tm6000_digital_hw;
189
190 return 0;
191_error:
192 dprintk(1, "Error opening PCM!\n");
193 return err;
194}
195
196/*
197 * audio close callback
198 */
199static int snd_tm6000_close(struct snd_pcm_substream *substream)
200{
201 return 0;
202}
203
204/*
205 * hw_params callback
206 */
207static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
208 struct snd_pcm_hw_params *hw_params)
209{
210 struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
211
212 if (substream->runtime->dma_area) {
213 dsp_buffer_free(chip);
214 substream->runtime->dma_area = NULL;
215 }
216
217 chip->period_size = params_period_bytes(hw_params);
218 chip->num_periods = params_periods(hw_params);
219 chip->bufsize = chip->period_size * params_periods(hw_params);
220
221 BUG_ON(!chip->bufsize);
222
223 dprintk(1, "Setting buffer\n");
224
225 /* FIXME: Allocate buffer for audio */
226
227
228 return 0;
229}
230
231/*
232 * hw free callback
233 */
234static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
235{
236
237 struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
238
239 if (substream->runtime->dma_area) {
240 dsp_buffer_free(chip);
241 substream->runtime->dma_area = NULL;
242 }
243
244 return 0;
245}
246
247/*
248 * prepare callback
249 */
250static int snd_tm6000_prepare(struct snd_pcm_substream *substream)
251{
252 return 0;
253}
254
255
256/*
257 * trigger callback
258 */
259static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd)
260{
261 struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
262 int err;
263
264 spin_lock(&chip->reg_lock);
265
266 switch (cmd) {
267 case SNDRV_PCM_TRIGGER_START:
268 err = _tm6000_start_audio_dma(chip);
269 break;
270 case SNDRV_PCM_TRIGGER_STOP:
271 err = _tm6000_stop_audio_dma(chip);
272 break;
273 default:
274 err = -EINVAL;
275 break;
276 }
277
278 spin_unlock(&chip->reg_lock);
279
280 return err;
281}
282
283/*
284 * pointer callback
285 */
286static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream)
287{
288 struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
289 struct snd_pcm_runtime *runtime = substream->runtime;
290 u16 count;
291
292 count = atomic_read(&chip->count);
293
294 return runtime->period_size * (count & (runtime->periods-1));
295}
296
297/*
298 * operators
299 */
300static struct snd_pcm_ops snd_tm6000_pcm_ops = {
301 .open = snd_tm6000_pcm_open,
302 .close = snd_tm6000_close,
303 .ioctl = snd_pcm_lib_ioctl,
304 .hw_params = snd_tm6000_hw_params,
305 .hw_free = snd_tm6000_hw_free,
306 .prepare = snd_tm6000_prepare,
307 .trigger = snd_tm6000_card_trigger,
308 .pointer = snd_tm6000_pointer,
309};
310
311/*
312 * create a PCM device
313 */
314static int __devinit snd_tm6000_pcm(struct snd_tm6000_card *chip,
315 int device, char *name)
316{
317 int err;
318 struct snd_pcm *pcm;
319
320 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
321 if (err < 0)
322 return err;
323 pcm->private_data = chip;
324 strcpy(pcm->name, name);
325 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
326
327 return 0;
328}
329
330/* FIXME: Control interface - How to control volume/mute? */
331
332/****************************************************************************
333 Basic Flow for Sound Devices
334 ****************************************************************************/
335
336/*
337 * Alsa Constructor - Component probe
338 */
339
340int tm6000_audio_init(struct tm6000_core *dev, int idx)
341{
342 struct snd_card *card;
343 struct snd_tm6000_card *chip;
344 int rc, len;
345 char component[14];
346
347 if (idx >= SNDRV_CARDS)
348 return -ENODEV;
349
350 if (!enable[idx])
351 return -ENOENT;
352
353 rc = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
354 if (rc < 0) {
355 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
356 return rc;
357 }
358
359 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
360 if (!chip) {
361 rc = -ENOMEM;
362 goto error;
363 }
364
365 chip->core = dev;
366 chip->card = card;
367
368 strcpy(card->driver, "tm6000-alsa");
369 sprintf(component, "USB%04x:%04x",
370 le16_to_cpu(dev->udev->descriptor.idVendor),
371 le16_to_cpu(dev->udev->descriptor.idProduct));
372 snd_component_add(card, component);
373
374 if (dev->udev->descriptor.iManufacturer)
375 len = usb_string(dev->udev,
376 dev->udev->descriptor.iManufacturer,
377 card->longname, sizeof(card->longname));
378 else
379 len = 0;
380
381 if (len > 0)
382 strlcat(card->longname, " ", sizeof(card->longname));
383
384 strlcat(card->longname, card->shortname, sizeof(card->longname));
385
386 len = strlcat(card->longname, " at ", sizeof(card->longname));
387
388 if (len < sizeof(card->longname))
389 usb_make_path(dev->udev, card->longname + len,
390 sizeof(card->longname) - len);
391
392 strlcat(card->longname,
393 dev->udev->speed == USB_SPEED_LOW ? ", low speed" :
394 dev->udev->speed == USB_SPEED_FULL ? ", full speed" :
395 ", high speed",
396 sizeof(card->longname));
397
398 rc = snd_tm6000_pcm(chip, 0, "tm6000 Digital");
399 if (rc < 0)
400 goto error;
401
402 rc = snd_card_register(card);
403 if (rc < 0)
404 goto error;
405
406
407 return 0;
408
409error:
410 snd_card_free(card);
411 return rc;
412}
413EXPORT_SYMBOL_GPL(tm6000_audio_init);
414
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
new file mode 100644
index 000000000000..6143e20d139d
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -0,0 +1,973 @@
1/*
2 tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/pci.h>
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/usb.h>
26#include <linux/version.h>
27#include <media/v4l2-common.h>
28#include <media/tuner.h>
29#include <media/tvaudio.h>
30#include <media/i2c-addr.h>
31
32#include "tm6000.h"
33#include "tm6000-regs.h"
34#include "tuner-xc2028.h"
35#include "xc5000.h"
36
37#define TM6000_BOARD_UNKNOWN 0
38#define TM5600_BOARD_GENERIC 1
39#define TM6000_BOARD_GENERIC 2
40#define TM6010_BOARD_GENERIC 3
41#define TM5600_BOARD_10MOONS_UT821 4
42#define TM5600_BOARD_10MOONS_UT330 5
43#define TM6000_BOARD_ADSTECH_DUAL_TV 6
44#define TM6000_BOARD_FREECOM_AND_SIMILAR 7
45#define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
46#define TM6010_BOARD_HAUPPAUGE_900H 9
47#define TM6010_BOARD_BEHOLD_WANDER 10
48#define TM6010_BOARD_BEHOLD_VOYAGER 11
49#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
50#define TM6010_BOARD_TWINHAN_TU501 13
51
52#define TM6000_MAXBOARDS 16
53static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
54
55module_param_array(card, int, NULL, 0444);
56
57static unsigned long tm6000_devused;
58
59
60struct tm6000_board {
61 char *name;
62
63 struct tm6000_capabilities caps;
64
65 enum tm6000_devtype type; /* variant of the chipset */
66 int tuner_type; /* type of the tuner */
67 int tuner_addr; /* tuner address */
68 int demod_addr; /* demodulator address */
69
70 struct tm6000_gpio gpio;
71};
72
73struct tm6000_board tm6000_boards[] = {
74 [TM6000_BOARD_UNKNOWN] = {
75 .name = "Unknown tm6000 video grabber",
76 .caps = {
77 .has_tuner = 1,
78 },
79 .gpio = {
80 .tuner_reset = TM6000_GPIO_1,
81 },
82 },
83 [TM5600_BOARD_GENERIC] = {
84 .name = "Generic tm5600 board",
85 .type = TM5600,
86 .tuner_type = TUNER_XC2028,
87 .tuner_addr = 0xc2 >> 1,
88 .caps = {
89 .has_tuner = 1,
90 },
91 .gpio = {
92 .tuner_reset = TM6000_GPIO_1,
93 },
94 },
95 [TM6000_BOARD_GENERIC] = {
96 .name = "Generic tm6000 board",
97 .tuner_type = TUNER_XC2028,
98 .tuner_addr = 0xc2 >> 1,
99 .caps = {
100 .has_tuner = 1,
101 .has_dvb = 1,
102 },
103 .gpio = {
104 .tuner_reset = TM6000_GPIO_1,
105 },
106 },
107 [TM6010_BOARD_GENERIC] = {
108 .name = "Generic tm6010 board",
109 .type = TM6010,
110 .tuner_type = TUNER_XC2028,
111 .tuner_addr = 0xc2 >> 1,
112 .demod_addr = 0x1e >> 1,
113 .caps = {
114 .has_tuner = 1,
115 .has_dvb = 1,
116 .has_zl10353 = 1,
117 .has_eeprom = 1,
118 .has_remote = 1,
119 },
120 .gpio = {
121 .tuner_reset = TM6010_GPIO_2,
122 .tuner_on = TM6010_GPIO_3,
123 .demod_reset = TM6010_GPIO_1,
124 .demod_on = TM6010_GPIO_4,
125 .power_led = TM6010_GPIO_7,
126 .dvb_led = TM6010_GPIO_5,
127 .ir = TM6010_GPIO_0,
128 },
129 },
130 [TM5600_BOARD_10MOONS_UT821] = {
131 .name = "10Moons UT 821",
132 .tuner_type = TUNER_XC2028,
133 .type = TM5600,
134 .tuner_addr = 0xc2 >> 1,
135 .caps = {
136 .has_tuner = 1,
137 .has_eeprom = 1,
138 },
139 .gpio = {
140 .tuner_reset = TM6000_GPIO_1,
141 },
142 },
143 [TM5600_BOARD_10MOONS_UT330] = {
144 .name = "10Moons UT 330",
145 .tuner_type = TUNER_PHILIPS_FQ1216AME_MK4,
146 .tuner_addr = 0xc8 >> 1,
147 .caps = {
148 .has_tuner = 1,
149 .has_dvb = 0,
150 .has_zl10353 = 0,
151 .has_eeprom = 1,
152 },
153 },
154 [TM6000_BOARD_ADSTECH_DUAL_TV] = {
155 .name = "ADSTECH Dual TV USB",
156 .tuner_type = TUNER_XC2028,
157 .tuner_addr = 0xc8 >> 1,
158 .caps = {
159 .has_tuner = 1,
160 .has_tda9874 = 1,
161 .has_dvb = 1,
162 .has_zl10353 = 1,
163 .has_eeprom = 1,
164 },
165 },
166 [TM6000_BOARD_FREECOM_AND_SIMILAR] = {
167 .name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
168 .tuner_type = TUNER_XC2028, /* has a XC3028 */
169 .tuner_addr = 0xc2 >> 1,
170 .demod_addr = 0x1e >> 1,
171 .caps = {
172 .has_tuner = 1,
173 .has_dvb = 1,
174 .has_zl10353 = 1,
175 .has_eeprom = 0,
176 .has_remote = 1,
177 },
178 .gpio = {
179 .tuner_reset = TM6000_GPIO_4,
180 },
181 },
182 [TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = {
183 .name = "ADSTECH Mini Dual TV USB",
184 .tuner_type = TUNER_XC2028, /* has a XC3028 */
185 .tuner_addr = 0xc8 >> 1,
186 .demod_addr = 0x1e >> 1,
187 .caps = {
188 .has_tuner = 1,
189 .has_dvb = 1,
190 .has_zl10353 = 1,
191 .has_eeprom = 0,
192 },
193 .gpio = {
194 .tuner_reset = TM6000_GPIO_4,
195 },
196 },
197 [TM6010_BOARD_HAUPPAUGE_900H] = {
198 .name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
199 .tuner_type = TUNER_XC2028, /* has a XC3028 */
200 .tuner_addr = 0xc2 >> 1,
201 .demod_addr = 0x1e >> 1,
202 .type = TM6010,
203 .caps = {
204 .has_tuner = 1,
205 .has_dvb = 1,
206 .has_zl10353 = 1,
207 .has_eeprom = 1,
208 .has_remote = 1,
209 },
210 .gpio = {
211 .tuner_reset = TM6010_GPIO_2,
212 .tuner_on = TM6010_GPIO_3,
213 .demod_reset = TM6010_GPIO_1,
214 .demod_on = TM6010_GPIO_4,
215 .power_led = TM6010_GPIO_7,
216 .dvb_led = TM6010_GPIO_5,
217 .ir = TM6010_GPIO_0,
218 },
219 },
220 [TM6010_BOARD_BEHOLD_WANDER] = {
221 .name = "Beholder Wander DVB-T/TV/FM USB2.0",
222 .tuner_type = TUNER_XC5000,
223 .tuner_addr = 0xc2 >> 1,
224 .demod_addr = 0x1e >> 1,
225 .type = TM6010,
226 .caps = {
227 .has_tuner = 1,
228 .has_dvb = 1,
229 .has_zl10353 = 1,
230 .has_eeprom = 1,
231 .has_remote = 1,
232 },
233 .gpio = {
234 .tuner_reset = TM6010_GPIO_0,
235 .demod_reset = TM6010_GPIO_1,
236 .power_led = TM6010_GPIO_6,
237 },
238 },
239 [TM6010_BOARD_BEHOLD_VOYAGER] = {
240 .name = "Beholder Voyager TV/FM USB2.0",
241 .tuner_type = TUNER_XC5000,
242 .tuner_addr = 0xc2 >> 1,
243 .type = TM6010,
244 .caps = {
245 .has_tuner = 1,
246 .has_dvb = 0,
247 .has_zl10353 = 0,
248 .has_eeprom = 1,
249 .has_remote = 1,
250 },
251 .gpio = {
252 .tuner_reset = TM6010_GPIO_0,
253 .power_led = TM6010_GPIO_6,
254 },
255 },
256 [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
257 .name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
258 .tuner_type = TUNER_XC2028, /* has a XC3028 */
259 .tuner_addr = 0xc2 >> 1,
260 .demod_addr = 0x1e >> 1,
261 .type = TM6010,
262 .caps = {
263 .has_tuner = 1,
264 .has_dvb = 1,
265 .has_zl10353 = 1,
266 .has_eeprom = 1,
267 .has_remote = 1,
268 },
269 .gpio = {
270 .tuner_reset = TM6010_GPIO_2,
271 .tuner_on = TM6010_GPIO_3,
272 .demod_reset = TM6010_GPIO_1,
273 .demod_on = TM6010_GPIO_4,
274 .power_led = TM6010_GPIO_7,
275 .dvb_led = TM6010_GPIO_5,
276 .ir = TM6010_GPIO_0,
277 },
278 },
279 [TM6010_BOARD_TWINHAN_TU501] = {
280 .name = "Twinhan TU501(704D1)",
281 .tuner_type = TUNER_XC2028, /* has a XC3028 */
282 .tuner_addr = 0xc2 >> 1,
283 .demod_addr = 0x1e >> 1,
284 .type = TM6010,
285 .caps = {
286 .has_tuner = 1,
287 .has_dvb = 1,
288 .has_zl10353 = 1,
289 .has_eeprom = 1,
290 .has_remote = 1,
291 },
292 .gpio = {
293 .tuner_reset = TM6010_GPIO_2,
294 .tuner_on = TM6010_GPIO_3,
295 .demod_reset = TM6010_GPIO_1,
296 .demod_on = TM6010_GPIO_4,
297 .power_led = TM6010_GPIO_7,
298 .dvb_led = TM6010_GPIO_5,
299 .ir = TM6010_GPIO_0,
300 },
301 }
302};
303
304/* table of devices that work with this driver */
305struct usb_device_id tm6000_id_table[] = {
306 { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_10MOONS_UT821 },
307 { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
308 { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
309 { USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR },
310 { USB_DEVICE(0x06e1, 0xb339), .driver_info = TM6000_BOARD_ADSTECH_MINI_DUAL_TV },
311 { USB_DEVICE(0x2040, 0x6600), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
312 { USB_DEVICE(0x2040, 0x6601), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
313 { USB_DEVICE(0x2040, 0x6610), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
314 { USB_DEVICE(0x2040, 0x6611), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
315 { USB_DEVICE(0x6000, 0xdec0), .driver_info = TM6010_BOARD_BEHOLD_WANDER },
316 { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER },
317 { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
318 { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
319 { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
320 { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
321 { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
322 { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
323 { },
324};
325
326/* Tuner callback to provide the proper gpio changes needed for xc5000 */
327int tm6000_xc5000_callback(void *ptr, int component, int command, int arg)
328{
329 int rc = 0;
330 struct tm6000_core *dev = ptr;
331
332 if (dev->tuner_type != TUNER_XC5000)
333 return 0;
334
335 switch (command) {
336 case XC5000_TUNER_RESET:
337 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
338 dev->gpio.tuner_reset, 0x01);
339 msleep(15);
340 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
341 dev->gpio.tuner_reset, 0x00);
342 msleep(15);
343 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
344 dev->gpio.tuner_reset, 0x01);
345 break;
346 }
347 return (rc);
348}
349
350
351/* Tuner callback to provide the proper gpio changes needed for xc2028 */
352
353int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
354{
355 int rc = 0;
356 struct tm6000_core *dev = ptr;
357
358 if (dev->tuner_type != TUNER_XC2028)
359 return 0;
360
361 switch (command) {
362 case XC2028_RESET_CLK:
363 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
364 0x02, arg);
365 msleep(10);
366 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
367 TM6000_GPIO_CLK, 0);
368 if (rc < 0)
369 return rc;
370 msleep(10);
371 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
372 TM6000_GPIO_CLK, 1);
373 break;
374 case XC2028_TUNER_RESET:
375 /* Reset codes during load firmware */
376 switch (arg) {
377 case 0:
378 /* newer tuner can faster reset */
379 switch (dev->model) {
380 case TM5600_BOARD_10MOONS_UT821:
381 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
382 dev->gpio.tuner_reset, 0x01);
383 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
384 0x300, 0x01);
385 msleep(10);
386 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
387 dev->gpio.tuner_reset, 0x00);
388 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
389 0x300, 0x00);
390 msleep(10);
391 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
392 dev->gpio.tuner_reset, 0x01);
393 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
394 0x300, 0x01);
395 break;
396 case TM6010_BOARD_HAUPPAUGE_900H:
397 case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
398 case TM6010_BOARD_TWINHAN_TU501:
399 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
400 dev->gpio.tuner_reset, 0x01);
401 msleep(60);
402 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
403 dev->gpio.tuner_reset, 0x00);
404 msleep(75);
405 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
406 dev->gpio.tuner_reset, 0x01);
407 msleep(60);
408 break;
409 default:
410 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
411 dev->gpio.tuner_reset, 0x00);
412 msleep(130);
413 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
414 dev->gpio.tuner_reset, 0x01);
415 msleep(130);
416 break;
417 }
418 break;
419 case 1:
420 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
421 0x02, 0x01);
422 msleep(10);
423 break;
424
425 case 2:
426 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
427 TM6000_GPIO_CLK, 0);
428 if (rc < 0)
429 return rc;
430 msleep(100);
431 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
432 TM6000_GPIO_CLK, 1);
433 msleep(100);
434 break;
435 }
436 }
437 return rc;
438}
439
440int tm6000_cards_setup(struct tm6000_core *dev)
441{
442 int i, rc;
443
444 /*
445 * Board-specific initialization sequence. Handles all GPIO
446 * initialization sequences that are board-specific.
447 * Up to now, all found devices use GPIO1 and GPIO4 at the same way.
448 * Probably, they're all based on some reference device. Due to that,
449 * there's a common routine at the end to handle those GPIO's. Devices
450 * that use different pinups or init sequences can just return at
451 * the board-specific session.
452 */
453 switch (dev->model) {
454 case TM6010_BOARD_HAUPPAUGE_900H:
455 case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
456 case TM6010_BOARD_TWINHAN_TU501:
457 case TM6010_BOARD_GENERIC:
458 /* Turn xceive 3028 on */
459 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.tuner_on, 0x01);
460 msleep(15);
461 /* Turn zarlink zl10353 on */
462 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00);
463 msleep(15);
464 /* Reset zarlink zl10353 */
465 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00);
466 msleep(50);
467 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01);
468 msleep(15);
469 /* Turn zarlink zl10353 off */
470 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x01);
471 msleep(15);
472 /* ir ? */
473 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.ir, 0x01);
474 msleep(15);
475 /* Power led on (blue) */
476 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x00);
477 msleep(15);
478 /* DVB led off (orange) */
479 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.dvb_led, 0x01);
480 msleep(15);
481 /* Turn zarlink zl10353 on */
482 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00);
483 msleep(15);
484 break;
485 case TM6010_BOARD_BEHOLD_WANDER:
486 /* Power led on (blue) */
487 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
488 msleep(15);
489 /* Reset zarlink zl10353 */
490 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00);
491 msleep(50);
492 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01);
493 msleep(15);
494 break;
495 case TM6010_BOARD_BEHOLD_VOYAGER:
496 /* Power led on (blue) */
497 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
498 msleep(15);
499 break;
500 default:
501 break;
502 }
503
504 /*
505 * Default initialization. Most of the devices seem to use GPIO1
506 * and GPIO4.on the same way, so, this handles the common sequence
507 * used by most devices.
508 * If a device uses a different sequence or different GPIO pins for
509 * reset, just add the code at the board-specific part
510 */
511
512 if (dev->gpio.tuner_reset) {
513 for (i = 0; i < 2; i++) {
514 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
515 dev->gpio.tuner_reset, 0x00);
516 if (rc < 0) {
517 printk(KERN_ERR "Error %i doing tuner reset\n", rc);
518 return rc;
519 }
520
521 msleep(10); /* Just to be conservative */
522 rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
523 dev->gpio.tuner_reset, 0x01);
524 if (rc < 0) {
525 printk(KERN_ERR "Error %i doing tuner reset\n", rc);
526 return rc;
527 }
528 msleep(10);
529
530 if (!i) {
531 rc = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
532 if (rc >= 0)
533 printk(KERN_DEBUG "board=0x%08x\n", rc);
534 }
535 }
536 } else {
537 printk(KERN_ERR "Tuner reset is not configured\n");
538 return -1;
539 }
540
541 msleep(50);
542
543 return 0;
544};
545
546static void tm6000_config_tuner(struct tm6000_core *dev)
547{
548 struct tuner_setup tun_setup;
549
550 /* Load tuner module */
551 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
552 "tuner", "tuner", dev->tuner_addr, NULL);
553
554 memset(&tun_setup, 0, sizeof(tun_setup));
555 tun_setup.type = dev->tuner_type;
556 tun_setup.addr = dev->tuner_addr;
557
558 tun_setup.mode_mask = 0;
559 if (dev->caps.has_tuner)
560 tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO);
561 if (dev->caps.has_dvb)
562 tun_setup.mode_mask |= T_DIGITAL_TV;
563
564 switch (dev->tuner_type) {
565 case TUNER_XC2028:
566 tun_setup.tuner_callback = tm6000_tuner_callback;;
567 break;
568 case TUNER_XC5000:
569 tun_setup.tuner_callback = tm6000_xc5000_callback;
570 break;
571 }
572
573 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
574
575 switch (dev->tuner_type) {
576 case TUNER_XC2028: {
577 struct v4l2_priv_tun_config xc2028_cfg;
578 struct xc2028_ctrl ctl;
579
580 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
581 memset(&ctl, 0, sizeof(ctl));
582
583 ctl.input1 = 1;
584 ctl.read_not_reliable = 0;
585 ctl.msleep = 10;
586 ctl.demod = XC3028_FE_ZARLINK456;
587 ctl.vhfbw7 = 1;
588 ctl.uhfbw8 = 1;
589 xc2028_cfg.tuner = TUNER_XC2028;
590 xc2028_cfg.priv = &ctl;
591
592 switch (dev->model) {
593 case TM6010_BOARD_HAUPPAUGE_900H:
594 case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
595 case TM6010_BOARD_TWINHAN_TU501:
596 ctl.fname = "xc3028L-v36.fw";
597 break;
598 default:
599 if (dev->dev_type == TM6010)
600 ctl.fname = "xc3028-v27.fw";
601 else
602 ctl.fname = "xc3028-v24.fw";
603 }
604
605 printk(KERN_INFO "Setting firmware parameters for xc2028\n");
606 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
607 &xc2028_cfg);
608
609 }
610 break;
611 case TUNER_XC5000:
612 {
613 struct v4l2_priv_tun_config xc5000_cfg;
614 struct xc5000_config ctl = {
615 .i2c_address = dev->tuner_addr,
616 .if_khz = 4570,
617 .radio_input = XC5000_RADIO_FM1,
618 };
619
620 xc5000_cfg.tuner = TUNER_XC5000;
621 xc5000_cfg.priv = &ctl;
622
623
624 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
625 &xc5000_cfg);
626 }
627 break;
628 default:
629 printk(KERN_INFO "Unknown tuner type. Tuner is not configured.\n");
630 break;
631 }
632}
633
634static int tm6000_init_dev(struct tm6000_core *dev)
635{
636 struct v4l2_frequency f;
637 int rc = 0;
638
639 mutex_init(&dev->lock);
640
641 mutex_lock(&dev->lock);
642
643 /* Initializa board-specific data */
644 dev->dev_type = tm6000_boards[dev->model].type;
645 dev->tuner_type = tm6000_boards[dev->model].tuner_type;
646 dev->tuner_addr = tm6000_boards[dev->model].tuner_addr;
647
648 dev->gpio = tm6000_boards[dev->model].gpio;
649
650 dev->demod_addr = tm6000_boards[dev->model].demod_addr;
651
652 dev->caps = tm6000_boards[dev->model].caps;
653
654 /* initialize hardware */
655 rc = tm6000_init(dev);
656 if (rc < 0)
657 goto err;
658
659 rc = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
660 if (rc < 0)
661 goto err;
662
663 /* register i2c bus */
664 rc = tm6000_i2c_register(dev);
665 if (rc < 0)
666 goto err;
667
668 /* Default values for STD and resolutions */
669 dev->width = 720;
670 dev->height = 480;
671 dev->norm = V4L2_STD_PAL_M;
672
673 /* Configure tuner */
674 tm6000_config_tuner(dev);
675
676 /* Set video standard */
677 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
678
679 /* Set tuner frequency - also loads firmware on xc2028/xc3028 */
680 f.tuner = 0;
681 f.type = V4L2_TUNER_ANALOG_TV;
682 f.frequency = 3092; /* 193.25 MHz */
683 dev->freq = f.frequency;
684 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
685
686 if (dev->caps.has_tda9874)
687 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
688 "tvaudio", "tvaudio", I2C_ADDR_TDA9874, NULL);
689
690 /* register and initialize V4L2 */
691 rc = tm6000_v4l2_register(dev);
692 if (rc < 0)
693 goto err;
694
695 if (dev->caps.has_dvb) {
696 dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
697 if (!dev->dvb) {
698 rc = -ENOMEM;
699 goto err2;
700 }
701
702#ifdef CONFIG_VIDEO_TM6000_DVB
703 rc = tm6000_dvb_register(dev);
704 if (rc < 0) {
705 kfree(dev->dvb);
706 dev->dvb = NULL;
707 goto err2;
708 }
709#endif
710 }
711 mutex_unlock(&dev->lock);
712 return 0;
713
714err2:
715 v4l2_device_unregister(&dev->v4l2_dev);
716
717err:
718 mutex_unlock(&dev->lock);
719 return rc;
720}
721
722/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
723#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
724
725static void get_max_endpoint(struct usb_device *udev,
726 struct usb_host_interface *alt,
727 char *msgtype,
728 struct usb_host_endpoint *curr_e,
729 struct tm6000_endpoint *tm_ep)
730{
731 u16 tmp = le16_to_cpu(curr_e->desc.wMaxPacketSize);
732 unsigned int size = tmp & 0x7ff;
733
734 if (udev->speed == USB_SPEED_HIGH)
735 size = size * hb_mult (tmp);
736
737 if (size > tm_ep->maxsize) {
738 tm_ep->endp = curr_e;
739 tm_ep->maxsize = size;
740 tm_ep->bInterfaceNumber = alt->desc.bInterfaceNumber;
741 tm_ep->bAlternateSetting = alt->desc.bAlternateSetting;
742
743 printk(KERN_INFO "tm6000: %s endpoint: 0x%02x (max size=%u bytes)\n",
744 msgtype, curr_e->desc.bEndpointAddress,
745 size);
746 }
747}
748
749/*
750 * tm6000_usb_probe()
751 * checks for supported devices
752 */
753static int tm6000_usb_probe(struct usb_interface *interface,
754 const struct usb_device_id *id)
755{
756 struct usb_device *usbdev;
757 struct tm6000_core *dev = NULL;
758 int i, rc = 0;
759 int nr = 0;
760 char *speed;
761
762 usbdev = usb_get_dev(interface_to_usbdev(interface));
763
764 /* Selects the proper interface */
765 rc = usb_set_interface(usbdev, 0, 1);
766 if (rc < 0)
767 goto err;
768
769 /* Check to see next free device and mark as used */
770 nr = find_first_zero_bit(&tm6000_devused, TM6000_MAXBOARDS);
771 if (nr >= TM6000_MAXBOARDS) {
772 printk(KERN_ERR "tm6000: Supports only %i tm60xx boards.\n", TM6000_MAXBOARDS);
773 usb_put_dev(usbdev);
774 return -ENOMEM;
775 }
776
777 /* Create and initialize dev struct */
778 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
779 if (dev == NULL) {
780 printk(KERN_ERR "tm6000" ": out of memory!\n");
781 usb_put_dev(usbdev);
782 return -ENOMEM;
783 }
784 spin_lock_init(&dev->slock);
785
786 /* Increment usage count */
787 tm6000_devused |= 1<<nr;
788 snprintf(dev->name, 29, "tm6000 #%d", nr);
789
790 dev->model = id->driver_info;
791 if ((card[nr] >= 0) && (card[nr] < ARRAY_SIZE(tm6000_boards)))
792 dev->model = card[nr];
793
794 dev->udev = usbdev;
795 dev->devno = nr;
796
797 switch (usbdev->speed) {
798 case USB_SPEED_LOW:
799 speed = "1.5";
800 break;
801 case USB_SPEED_UNKNOWN:
802 case USB_SPEED_FULL:
803 speed = "12";
804 break;
805 case USB_SPEED_HIGH:
806 speed = "480";
807 break;
808 default:
809 speed = "unknown";
810 }
811
812
813
814 /* Get endpoints */
815 for (i = 0; i < interface->num_altsetting; i++) {
816 int ep;
817
818 for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) {
819 struct usb_host_endpoint *e;
820 int dir_out;
821
822 e = &interface->altsetting[i].endpoint[ep];
823
824 dir_out = ((e->desc.bEndpointAddress &
825 USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
826
827 printk(KERN_INFO "tm6000: alt %d, interface %i, class %i\n",
828 i,
829 interface->altsetting[i].desc.bInterfaceNumber,
830 interface->altsetting[i].desc.bInterfaceClass);
831
832 switch (e->desc.bmAttributes) {
833 case USB_ENDPOINT_XFER_BULK:
834 if (!dir_out) {
835 get_max_endpoint(usbdev,
836 &interface->altsetting[i],
837 "Bulk IN", e,
838 &dev->bulk_in);
839 } else {
840 get_max_endpoint(usbdev,
841 &interface->altsetting[i],
842 "Bulk OUT", e,
843 &dev->bulk_out);
844 }
845 break;
846 case USB_ENDPOINT_XFER_ISOC:
847 if (!dir_out) {
848 get_max_endpoint(usbdev,
849 &interface->altsetting[i],
850 "ISOC IN", e,
851 &dev->isoc_in);
852 } else {
853 get_max_endpoint(usbdev,
854 &interface->altsetting[i],
855 "ISOC OUT", e,
856 &dev->isoc_out);
857 }
858 break;
859 }
860 }
861 }
862
863
864 printk(KERN_INFO "tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n",
865 speed,
866 le16_to_cpu(dev->udev->descriptor.idVendor),
867 le16_to_cpu(dev->udev->descriptor.idProduct),
868 interface->altsetting->desc.bInterfaceNumber);
869
870/* check if the the device has the iso in endpoint at the correct place */
871 if (!dev->isoc_in.endp) {
872 printk(KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n");
873 rc = -ENODEV;
874
875 goto err;
876 }
877
878 /* save our data pointer in this interface device */
879 usb_set_intfdata(interface, dev);
880
881 printk(KERN_INFO "tm6000: Found %s\n", tm6000_boards[dev->model].name);
882
883 rc = tm6000_init_dev(dev);
884
885 if (rc < 0)
886 goto err;
887
888 return 0;
889
890err:
891 printk(KERN_ERR "tm6000: Error %d while registering\n", rc);
892
893 tm6000_devused &= ~(1<<nr);
894 usb_put_dev(usbdev);
895
896 kfree(dev);
897 return rc;
898}
899
900/*
901 * tm6000_usb_disconnect()
902 * called when the device gets diconencted
903 * video device will be unregistered on v4l2_close in case it is still open
904 */
905static void tm6000_usb_disconnect(struct usb_interface *interface)
906{
907 struct tm6000_core *dev = usb_get_intfdata(interface);
908 usb_set_intfdata(interface, NULL);
909
910 if (!dev)
911 return;
912
913 printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name);
914
915 mutex_lock(&dev->lock);
916
917#ifdef CONFIG_VIDEO_TM6000_DVB
918 if (dev->dvb) {
919 tm6000_dvb_unregister(dev);
920 kfree(dev->dvb);
921 }
922#endif
923
924 tm6000_v4l2_unregister(dev);
925
926 tm6000_i2c_unregister(dev);
927
928 v4l2_device_unregister(&dev->v4l2_dev);
929
930 dev->state |= DEV_DISCONNECTED;
931
932 usb_put_dev(dev->udev);
933
934 mutex_unlock(&dev->lock);
935 kfree(dev);
936}
937
938static struct usb_driver tm6000_usb_driver = {
939 .name = "tm6000",
940 .probe = tm6000_usb_probe,
941 .disconnect = tm6000_usb_disconnect,
942 .id_table = tm6000_id_table,
943};
944
945static int __init tm6000_module_init(void)
946{
947 int result;
948
949 printk(KERN_INFO "tm6000" " v4l2 driver version %d.%d.%d loaded\n",
950 (TM6000_VERSION >> 16) & 0xff,
951 (TM6000_VERSION >> 8) & 0xff, TM6000_VERSION & 0xff);
952
953 /* register this driver with the USB subsystem */
954 result = usb_register(&tm6000_usb_driver);
955 if (result)
956 printk(KERN_ERR "tm6000"
957 " usb_register failed. Error number %d.\n", result);
958
959 return result;
960}
961
962static void __exit tm6000_module_exit(void)
963{
964 /* deregister at USB subsystem */
965 usb_deregister(&tm6000_usb_driver);
966}
967
968module_init(tm6000_module_init);
969module_exit(tm6000_module_exit);
970
971MODULE_DESCRIPTION("Trident TVMaster TM5600/TM6000/TM6010 USB2 adapter");
972MODULE_AUTHOR("Mauro Carvalho Chehab");
973MODULE_LICENSE("GPL");
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
new file mode 100644
index 000000000000..bfbc53bd2912
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -0,0 +1,602 @@
1/*
2 tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
7 - DVB-T support
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation version 2
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/usb.h>
26#include <linux/i2c.h>
27#include "tm6000.h"
28#include "tm6000-regs.h"
29#include <media/v4l2-common.h>
30#include <media/tuner.h>
31
32#define USB_TIMEOUT 5*HZ /* ms */
33
34int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
35 u16 value, u16 index, u8 *buf, u16 len)
36{
37 int ret, i;
38 unsigned int pipe;
39 static int ini=0, last=0, n=0;
40 u8 *data=NULL;
41
42 if (len)
43 data = kzalloc(len, GFP_KERNEL);
44
45
46 if (req_type & USB_DIR_IN)
47 pipe=usb_rcvctrlpipe(dev->udev, 0);
48 else {
49 pipe=usb_sndctrlpipe(dev->udev, 0);
50 memcpy(data, buf, len);
51 }
52
53 if (tm6000_debug & V4L2_DEBUG_I2C) {
54 if (!ini)
55 last=ini=jiffies;
56
57 printk("%06i (dev %p, pipe %08x): ", n, dev->udev, pipe);
58
59 printk( "%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ",
60 (req_type & USB_DIR_IN)?" IN":"OUT",
61 jiffies_to_msecs(jiffies-last),
62 jiffies_to_msecs(jiffies-ini),
63 req_type, req,value&0xff,value>>8, index&0xff, index>>8,
64 len&0xff, len>>8);
65 last=jiffies;
66 n++;
67
68 if ( !(req_type & USB_DIR_IN) ) {
69 printk(">>> ");
70 for (i=0;i<len;i++) {
71 printk(" %02x",buf[i]);
72 }
73 printk("\n");
74 }
75 }
76
77 ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index, data,
78 len, USB_TIMEOUT);
79
80 if (req_type & USB_DIR_IN)
81 memcpy(buf, data, len);
82
83 if (tm6000_debug & V4L2_DEBUG_I2C) {
84 if (ret<0) {
85 if (req_type & USB_DIR_IN)
86 printk("<<< (len=%d)\n",len);
87
88 printk("%s: Error #%d\n", __FUNCTION__, ret);
89 } else if (req_type & USB_DIR_IN) {
90 printk("<<< ");
91 for (i=0;i<len;i++) {
92 printk(" %02x",buf[i]);
93 }
94 printk("\n");
95 }
96 }
97
98 kfree(data);
99
100 msleep(5);
101
102 return ret;
103}
104
105int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
106{
107 return
108 tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
109 req, value, index, NULL, 0);
110}
111EXPORT_SYMBOL_GPL(tm6000_set_reg);
112
113int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
114{
115 int rc;
116 u8 buf[1];
117
118 rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
119 value, index, buf, 1);
120
121 if (rc<0)
122 return rc;
123
124 return *buf;
125}
126EXPORT_SYMBOL_GPL(tm6000_get_reg);
127
128int tm6000_get_reg16 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
129{
130 int rc;
131 u8 buf[2];
132
133 rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
134 value, index, buf, 2);
135
136 if (rc<0)
137 return rc;
138
139 return buf[1]|buf[0]<<8;
140}
141
142int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
143{
144 int rc;
145 u8 buf[4];
146
147 rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
148 value, index, buf, 4);
149
150 if (rc<0)
151 return rc;
152
153 return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24;
154}
155
156void tm6000_set_fourcc_format(struct tm6000_core *dev)
157{
158 if (dev->dev_type == TM6010) {
159 int val;
160
161 val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0) & 0xfc;
162 if (dev->fourcc == V4L2_PIX_FMT_UYVY)
163 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
164 else
165 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val | 1);
166 } else {
167 if (dev->fourcc == V4L2_PIX_FMT_UYVY)
168 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
169 else
170 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0x90);
171 }
172}
173
174int tm6000_init_analog_mode (struct tm6000_core *dev)
175{
176 if (dev->dev_type == TM6010) {
177 int val;
178
179 /* Enable video */
180 val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0);
181 val |= 0x60;
182 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
183 val = tm6000_get_reg(dev,
184 TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0);
185 val &= ~0x40;
186 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val);
187
188 /* Init teletext */
189 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
190 tm6000_set_reg(dev, TM6010_REQ07_R41_TELETEXT_VBI_CODE1, 0x27);
191 tm6000_set_reg(dev, TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55);
192 tm6000_set_reg(dev, TM6010_REQ07_R43_VBI_DATA_TYPE_LINE7, 0x66);
193 tm6000_set_reg(dev, TM6010_REQ07_R44_VBI_DATA_TYPE_LINE8, 0x66);
194 tm6000_set_reg(dev, TM6010_REQ07_R45_VBI_DATA_TYPE_LINE9, 0x66);
195 tm6000_set_reg(dev,
196 TM6010_REQ07_R46_VBI_DATA_TYPE_LINE10, 0x66);
197 tm6000_set_reg(dev,
198 TM6010_REQ07_R47_VBI_DATA_TYPE_LINE11, 0x66);
199 tm6000_set_reg(dev,
200 TM6010_REQ07_R48_VBI_DATA_TYPE_LINE12, 0x66);
201 tm6000_set_reg(dev,
202 TM6010_REQ07_R49_VBI_DATA_TYPE_LINE13, 0x66);
203 tm6000_set_reg(dev,
204 TM6010_REQ07_R4A_VBI_DATA_TYPE_LINE14, 0x66);
205 tm6000_set_reg(dev,
206 TM6010_REQ07_R4B_VBI_DATA_TYPE_LINE15, 0x66);
207 tm6000_set_reg(dev,
208 TM6010_REQ07_R4C_VBI_DATA_TYPE_LINE16, 0x66);
209 tm6000_set_reg(dev,
210 TM6010_REQ07_R4D_VBI_DATA_TYPE_LINE17, 0x66);
211 tm6000_set_reg(dev,
212 TM6010_REQ07_R4E_VBI_DATA_TYPE_LINE18, 0x66);
213 tm6000_set_reg(dev,
214 TM6010_REQ07_R4F_VBI_DATA_TYPE_LINE19, 0x66);
215 tm6000_set_reg(dev,
216 TM6010_REQ07_R50_VBI_DATA_TYPE_LINE20, 0x66);
217 tm6000_set_reg(dev,
218 TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x66);
219 tm6000_set_reg(dev,
220 TM6010_REQ07_R52_VBI_DATA_TYPE_LINE22, 0x66);
221 tm6000_set_reg(dev,
222 TM6010_REQ07_R53_VBI_DATA_TYPE_LINE23, 0x00);
223 tm6000_set_reg(dev,
224 TM6010_REQ07_R54_VBI_DATA_TYPE_RLINES, 0x00);
225 tm6000_set_reg(dev,
226 TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01);
227 tm6000_set_reg(dev,
228 TM6010_REQ07_R56_VBI_LOOP_FILTER_I_GAIN, 0x00);
229 tm6000_set_reg(dev,
230 TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02);
231 tm6000_set_reg(dev, TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35);
232 tm6000_set_reg(dev, TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0);
233 tm6000_set_reg(dev, TM6010_REQ07_R5A_VBI_TELETEXT_DTO1, 0x11);
234 tm6000_set_reg(dev, TM6010_REQ07_R5B_VBI_TELETEXT_DTO0, 0x4c);
235 tm6000_set_reg(dev, TM6010_REQ07_R40_TELETEXT_VBI_CODE0, 0x01);
236 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
237
238
239 /* Init audio */
240 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
241 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
242 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
243 tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0);
244 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x05);
245 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x06);
246 tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00);
247 tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00);
248 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08);
249 tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91);
250 tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20);
251 tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12);
252 tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20);
253 tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0);
254 tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80);
255 tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0);
256 tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80);
257 tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12);
258 tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe);
259 tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20);
260 tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14);
261 tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe);
262 tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01);
263 tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0);
264 tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32);
265 tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64);
266 tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20);
267 tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00);
268 tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00);
269 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
270 tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00);
271 tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00);
272 tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
273 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
274 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
275
276 } else {
277 /* Enables soft reset */
278 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
279
280 if (dev->scaler) {
281 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
282 } else {
283 /* Enable Hfilter and disable TS Drop err */
284 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
285 }
286
287 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
288 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23);
289 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0);
290 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8);
291 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06);
292 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x1f);
293
294 /* AP Software reset */
295 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
296 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
297
298 tm6000_set_fourcc_format(dev);
299
300 /* Disables soft reset */
301 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
302
303 /* E3: Select input 0 - TV tuner */
304 tm6000_set_reg(dev, TM6010_REQ07_RE3_OUT_SEL1, 0x00);
305 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x60);
306
307 /* This controls input */
308 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0);
309 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_3, 0x01);
310 }
311 msleep(20);
312
313 /* Tuner firmware can now be loaded */
314
315 /*FIXME: Hack!!! */
316 struct v4l2_frequency f;
317 mutex_lock(&dev->lock);
318 f.frequency=dev->freq;
319 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
320 mutex_unlock(&dev->lock);
321
322 msleep(100);
323 tm6000_set_standard (dev, &dev->norm);
324 tm6000_set_audio_bitrate (dev,48000);
325
326 return 0;
327}
328
329int tm6000_init_digital_mode (struct tm6000_core *dev)
330{
331 if (dev->dev_type == TM6010) {
332 int val;
333 u8 buf[2];
334
335 /* digital init */
336 val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0);
337 val &= ~0x60;
338 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
339 val = tm6000_get_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0);
340 val |= 0x40;
341 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val);
342 tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28);
343 tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc);
344 tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff);
345 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
346 tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
347 printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
348
349
350 } else {
351 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
352 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
353 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
354 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x08);
355 tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c);
356 tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff);
357 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
358 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40);
359 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
360 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09);
361 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x37);
362 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8);
363 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0);
364 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60);
365
366 tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c);
367 tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff);
368 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
369 msleep(50);
370
371 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
372 msleep(50);
373 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
374 msleep(50);
375 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
376 msleep(100);
377 }
378 return 0;
379}
380
381struct reg_init {
382 u8 req;
383 u8 reg;
384 u8 val;
385};
386
387/* The meaning of those initializations are unknown */
388struct reg_init tm6000_init_tab[] = {
389 /* REG VALUE */
390 { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x1f },
391 { TM6010_REQ07_RFF_SOFT_RESET, 0x08 },
392 { TM6010_REQ07_RFF_SOFT_RESET, 0x00 },
393 { TM6010_REQ07_RD5_POWERSAVE, 0x4f },
394 { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23 },
395 { TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0x08 },
396 { TM6010_REQ07_RE2_OUT_SEL2, 0x00 },
397 { TM6010_REQ07_RE3_OUT_SEL1, 0x10 },
398 { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0x00 },
399 { TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0x00 },
400 { REQ_07_SET_GET_AVREG, 0xeb, 0x64 }, /* 48000 bits/sample, external input */
401 { REQ_07_SET_GET_AVREG, 0xee, 0xc2 },
402 { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */
403 { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
404 { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 },
405 { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
406 { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
407 { TM6010_REQ07_R05_NOISE_THRESHOLD, 0x64 },
408 { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01 },
409 { TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0x82 },
410 { TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0x36 },
411 { TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0x50 },
412 { TM6010_REQ07_R0C_CHROMA_AGC_CONTROL, 0x6a },
413 { TM6010_REQ07_R11_AGC_PEAK_CONTROL, 0xc9 },
414 { TM6010_REQ07_R12_AGC_GATE_STARTH, 0x07 },
415 { TM6010_REQ07_R13_AGC_GATE_STARTL, 0x3b },
416 { TM6010_REQ07_R14_AGC_GATE_WIDTH, 0x47 },
417 { TM6010_REQ07_R15_AGC_BP_DELAY, 0x6f },
418 { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0xcd },
419 { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
420 { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
421 { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
422 { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
423 { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
424 { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
425 { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
426 { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
427 { TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME, 0x3c },
428 { TM6010_REQ07_R21_HSYNC_PHASE_OFFSET, 0x3c },
429 { TM6010_REQ07_R2D_CHROMA_BURST_END, 0x48 },
430 { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
431 { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
432 { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
433 { TM6010_REQ07_R32_VSYNC_HLOCK_MIN, 0x74 },
434 { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
435 { TM6010_REQ07_R34_VSYNC_AGC_MIN, 0x74 },
436 { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
437 { TM6010_REQ07_R36_VSYNC_VBI_MIN, 0x7a },
438 { TM6010_REQ07_R37_VSYNC_VBI_MAX, 0x26 },
439 { TM6010_REQ07_R38_VSYNC_THRESHOLD, 0x40 },
440 { TM6010_REQ07_R39_VSYNC_TIME_CONSTANT, 0x0a },
441 { TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55 },
442 { TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x11 },
443 { TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01 },
444 { TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02 },
445 { TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35 },
446 { TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0 },
447 { TM6010_REQ07_R80_COMB_FILTER_TRESHOLD, 0x15 },
448 { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
449 { TM6010_REQ07_RC1_TRESHOLD, 0xd0 },
450 { TM6010_REQ07_RC3_HSTART1, 0x88 },
451 { TM6010_REQ07_R3F_RESET, 0x00 }, /* End of the soft reset */
452 { TM6010_REQ05_R18_IMASK7, 0x00 },
453};
454
455struct reg_init tm6010_init_tab[] = {
456 { TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x00 },
457 { TM6010_REQ07_RC4_HSTART0, 0xa0 },
458 { TM6010_REQ07_RC6_HEND0, 0x40 },
459 { TM6010_REQ07_RCA_VEND0, 0x31 },
460 { TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0xe1 },
461 { TM6010_REQ07_RE0_DVIDEO_SOURCE, 0x03 },
462 { TM6010_REQ07_RFE_POWER_DOWN, 0x7f },
463
464 { TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0 },
465 { TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4 },
466 { TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8 },
467 { TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00 },
468 { TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2 },
469 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 },
470 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 },
471 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 },
472 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc },
473
474 { TM6010_REQ07_R3F_RESET, 0x01 },
475 { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
476 { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 },
477 { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f },
478 { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 },
479 { TM6010_REQ07_R05_NOISE_THRESHOLD, 0x64 },
480 { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01 },
481 { TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0x82 },
482 { TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0x36 },
483 { TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0x50 },
484 { TM6010_REQ07_R0C_CHROMA_AGC_CONTROL, 0x6a },
485 { TM6010_REQ07_R11_AGC_PEAK_CONTROL, 0xc9 },
486 { TM6010_REQ07_R12_AGC_GATE_STARTH, 0x07 },
487 { TM6010_REQ07_R13_AGC_GATE_STARTL, 0x3b },
488 { TM6010_REQ07_R14_AGC_GATE_WIDTH, 0x47 },
489 { TM6010_REQ07_R15_AGC_BP_DELAY, 0x6f },
490 { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0xcd },
491 { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e },
492 { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b },
493 { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 },
494 { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 },
495 { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c },
496 { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc },
497 { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc },
498 { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd },
499 { TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME, 0x3c },
500 { TM6010_REQ07_R21_HSYNC_PHASE_OFFSET, 0x3c },
501 { TM6010_REQ07_R2D_CHROMA_BURST_END, 0x48 },
502 { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 },
503 { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 },
504 { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 },
505 { TM6010_REQ07_R32_VSYNC_HLOCK_MIN, 0x74 },
506 { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c },
507 { TM6010_REQ07_R34_VSYNC_AGC_MIN, 0x74 },
508 { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c },
509 { TM6010_REQ07_R36_VSYNC_VBI_MIN, 0x7a },
510 { TM6010_REQ07_R37_VSYNC_VBI_MAX, 0x26 },
511 { TM6010_REQ07_R38_VSYNC_THRESHOLD, 0x40 },
512 { TM6010_REQ07_R39_VSYNC_TIME_CONSTANT, 0x0a },
513 { TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55 },
514 { TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x11 },
515 { TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01 },
516 { TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02 },
517 { TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35 },
518 { TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0 },
519 { TM6010_REQ07_R80_COMB_FILTER_TRESHOLD, 0x15 },
520 { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 },
521 { TM6010_REQ07_RC1_TRESHOLD, 0xd0 },
522 { TM6010_REQ07_RC3_HSTART1, 0x88 },
523 { TM6010_REQ07_R3F_RESET, 0x00 },
524
525 { TM6010_REQ05_R18_IMASK7, 0x00 },
526
527 { TM6010_REQ07_RD8_IR_LEADER1, 0xaa },
528 { TM6010_REQ07_RD8_IR_LEADER0, 0x30 },
529 { TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20 },
530 { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0 },
531 { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
532 { TM6010_REQ07_RD8_IR, 0x2f },
533
534 /* set remote wakeup key:any key wakeup */
535 { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe },
536 { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff },
537};
538
539int tm6000_init (struct tm6000_core *dev)
540{
541 int board, rc=0, i, size;
542 struct reg_init *tab;
543
544 if (dev->dev_type == TM6010) {
545 tab = tm6010_init_tab;
546 size = ARRAY_SIZE(tm6010_init_tab);
547 } else {
548 tab = tm6000_init_tab;
549 size = ARRAY_SIZE(tm6000_init_tab);
550 }
551
552 /* Load board's initialization table */
553 for (i=0; i< size; i++) {
554 rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
555 if (rc<0) {
556 printk (KERN_ERR "Error %i while setting req %d, "
557 "reg %d to value %d\n", rc,
558 tab[i].req,tab[i].reg, tab[i].val);
559 return rc;
560 }
561 }
562
563 msleep(5); /* Just to be conservative */
564
565 /* Check board version - maybe 10Moons specific */
566 board=tm6000_get_reg32 (dev, REQ_40_GET_VERSION, 0, 0);
567 if (board >=0) {
568 printk (KERN_INFO "Board version = 0x%08x\n",board);
569 } else {
570 printk (KERN_ERR "Error %i while retrieving board version\n",board);
571 }
572
573 rc = tm6000_cards_setup(dev);
574
575 return rc;
576}
577
578int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
579{
580 int val;
581
582 val=tm6000_get_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
583printk("Original value=%d\n",val);
584 if (val<0)
585 return val;
586
587 val &= 0x0f; /* Preserve the audio input control bits */
588 switch (bitrate) {
589 case 44100:
590 val|=0xd0;
591 dev->audio_bitrate=bitrate;
592 break;
593 case 48000:
594 val|=0x60;
595 dev->audio_bitrate=bitrate;
596 break;
597 }
598 val=tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, val);
599
600 return val;
601}
602EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
new file mode 100644
index 000000000000..eafc89c22b6b
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -0,0 +1,346 @@
1/*
2 tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/usb.h>
22
23#include "tm6000.h"
24#include "tm6000-regs.h"
25
26#include "zl10353.h"
27
28#include <media/tuner.h>
29
30#include "tuner-xc2028.h"
31
32static void inline print_err_status (struct tm6000_core *dev,
33 int packet, int status)
34{
35 char *errmsg = "Unknown";
36
37 switch(status) {
38 case -ENOENT:
39 errmsg = "unlinked synchronuously";
40 break;
41 case -ECONNRESET:
42 errmsg = "unlinked asynchronuously";
43 break;
44 case -ENOSR:
45 errmsg = "Buffer error (overrun)";
46 break;
47 case -EPIPE:
48 errmsg = "Stalled (device not responding)";
49 break;
50 case -EOVERFLOW:
51 errmsg = "Babble (bad cable?)";
52 break;
53 case -EPROTO:
54 errmsg = "Bit-stuff error (bad cable?)";
55 break;
56 case -EILSEQ:
57 errmsg = "CRC/Timeout (could be anything)";
58 break;
59 case -ETIME:
60 errmsg = "Device does not respond";
61 break;
62 }
63 if (packet<0) {
64 dprintk(dev, 1, "URB status %d [%s].\n",
65 status, errmsg);
66 } else {
67 dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
68 packet, status, errmsg);
69 }
70}
71
72static void tm6000_urb_received(struct urb *urb)
73{
74 int ret;
75 struct tm6000_core* dev = urb->context;
76
77 if(urb->status != 0) {
78 print_err_status (dev,0,urb->status);
79 }
80 else if(urb->actual_length>0){
81 dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
82 urb->actual_length);
83 }
84
85 if(dev->dvb->streams > 0) {
86 ret = usb_submit_urb(urb, GFP_ATOMIC);
87 if(ret < 0) {
88 printk(KERN_ERR "tm6000: error %s\n", __FUNCTION__);
89 kfree(urb->transfer_buffer);
90 usb_free_urb(urb);
91 }
92 }
93}
94
95int tm6000_start_stream(struct tm6000_core *dev)
96{
97 int ret;
98 unsigned int pipe, size;
99 struct tm6000_dvb *dvb = dev->dvb;
100
101 printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
102
103 tm6000_init_digital_mode(dev);
104
105 dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
106 if(dvb->bulk_urb == NULL) {
107 printk(KERN_ERR "tm6000: couldn't allocate urb\n");
108 return -ENOMEM;
109 }
110
111 pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress
112 & USB_ENDPOINT_NUMBER_MASK);
113
114 size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
115 size = size * 15; /* 512 x 8 or 12 or 15 */
116
117 dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
118 if(dvb->bulk_urb->transfer_buffer == NULL) {
119 usb_free_urb(dvb->bulk_urb);
120 printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
121 return -ENOMEM;
122 }
123
124 usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
125 dvb->bulk_urb->transfer_buffer,
126 size,
127 tm6000_urb_received, dev);
128
129 ret = usb_clear_halt(dev->udev, pipe);
130 if(ret < 0) {
131 printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",ret,__FUNCTION__);
132 return ret;
133 }
134 else {
135 printk(KERN_ERR "tm6000: pipe resetted\n");
136 }
137
138/* mutex_lock(&tm6000_driver.open_close_mutex); */
139 ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
140
141/* mutex_unlock(&tm6000_driver.open_close_mutex); */
142 if (ret) {
143 printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
144
145 kfree(dvb->bulk_urb->transfer_buffer);
146 usb_free_urb(dvb->bulk_urb);
147 return ret;
148 }
149
150 return 0;
151}
152
153void tm6000_stop_stream(struct tm6000_core *dev)
154{
155 struct tm6000_dvb *dvb = dev->dvb;
156
157 if(dvb->bulk_urb) {
158 printk (KERN_INFO "urb killing\n");
159 usb_kill_urb(dvb->bulk_urb);
160 printk (KERN_INFO "urb buffer free\n");
161 kfree(dvb->bulk_urb->transfer_buffer);
162 usb_free_urb(dvb->bulk_urb);
163 dvb->bulk_urb = NULL;
164 }
165}
166
167int tm6000_start_feed(struct dvb_demux_feed *feed)
168{
169 struct dvb_demux *demux = feed->demux;
170 struct tm6000_core *dev = demux->priv;
171 struct tm6000_dvb *dvb = dev->dvb;
172 printk(KERN_INFO "tm6000: got start feed request %s\n",__FUNCTION__);
173
174 mutex_lock(&dvb->mutex);
175 if(dvb->streams == 0) {
176 dvb->streams = 1;
177/* mutex_init(&tm6000_dev->streming_mutex); */
178 tm6000_start_stream(dev);
179 }
180 else {
181 ++(dvb->streams);
182 }
183 mutex_unlock(&dvb->mutex);
184
185 return 0;
186}
187
188int tm6000_stop_feed(struct dvb_demux_feed *feed) {
189 struct dvb_demux *demux = feed->demux;
190 struct tm6000_core *dev = demux->priv;
191 struct tm6000_dvb *dvb = dev->dvb;
192
193 printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
194
195 mutex_lock(&dvb->mutex);
196
197 printk (KERN_INFO "stream %#x\n", dvb->streams);
198 --(dvb->streams);
199 if(dvb->streams == 0) {
200 printk (KERN_INFO "stop stream\n");
201 tm6000_stop_stream(dev);
202/* mutex_destroy(&tm6000_dev->streaming_mutex); */
203 }
204 mutex_unlock(&dvb->mutex);
205/* mutex_destroy(&tm6000_dev->streaming_mutex); */
206
207 return 0;
208}
209
210int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
211{
212 struct tm6000_dvb *dvb = dev->dvb;
213
214 if(dev->caps.has_zl10353) {
215 struct zl10353_config config =
216 {.demod_address = dev->demod_addr,
217 .no_tuner = 1,
218 .parallel_ts = 1,
219 .if2 = 45700,
220 .disable_i2c_gate_ctrl = 1,
221 };
222
223 dvb->frontend = dvb_attach(zl10353_attach, &config,
224 &dev->i2c_adap);
225 }
226 else {
227 printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
228 return -1;
229 }
230
231 return (!dvb->frontend) ? -1 : 0;
232}
233
234DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
235
236int tm6000_dvb_register(struct tm6000_core *dev)
237{
238 int ret = -1;
239 struct tm6000_dvb *dvb = dev->dvb;
240
241 mutex_init(&dvb->mutex);
242
243 dvb->streams = 0;
244
245 /* attach the frontend */
246 ret = tm6000_dvb_attach_frontend(dev);
247 if(ret < 0) {
248 printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
249 goto err;
250 }
251
252 ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
253 THIS_MODULE, &dev->udev->dev, adapter_nr);
254 dvb->adapter.priv = dev;
255
256 if (dvb->frontend) {
257 struct xc2028_config cfg = {
258 .i2c_adap = &dev->i2c_adap,
259 .i2c_addr = dev->tuner_addr,
260 };
261
262 dvb->frontend->callback = tm6000_tuner_callback;
263 ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
264 if (ret < 0) {
265 printk(KERN_ERR
266 "tm6000: couldn't register frontend\n");
267 goto adapter_err;
268 }
269
270 if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) {
271 printk(KERN_ERR "tm6000: couldn't register "
272 "frontend (xc3028)\n");
273 ret = -EINVAL;
274 goto frontend_err;
275 }
276 printk(KERN_INFO "tm6000: XC2028/3028 asked to be "
277 "attached to frontend!\n");
278 } else {
279 printk(KERN_ERR "tm6000: no frontend found\n");
280 }
281
282 dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
283 | DMX_MEMORY_BASED_FILTERING;
284 dvb->demux.priv = dev;
285 dvb->demux.filternum = 8;
286 dvb->demux.feednum = 8;
287 dvb->demux.start_feed = tm6000_start_feed;
288 dvb->demux.stop_feed = tm6000_stop_feed;
289 dvb->demux.write_to_decoder = NULL;
290 ret = dvb_dmx_init(&dvb->demux);
291 if(ret < 0) {
292 printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
293 goto frontend_err;
294 }
295
296 dvb->dmxdev.filternum = dev->dvb->demux.filternum;
297 dvb->dmxdev.demux = &dev->dvb->demux.dmx;
298 dvb->dmxdev.capabilities = 0;
299
300 ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
301 if(ret < 0) {
302 printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
303 goto dvb_dmx_err;
304 }
305
306 return 0;
307
308dvb_dmx_err:
309 dvb_dmx_release(&dvb->demux);
310frontend_err:
311 if(dvb->frontend) {
312 dvb_frontend_detach(dvb->frontend);
313 dvb_unregister_frontend(dvb->frontend);
314 }
315adapter_err:
316 dvb_unregister_adapter(&dvb->adapter);
317err:
318 return ret;
319}
320
321void tm6000_dvb_unregister(struct tm6000_core *dev)
322{
323 struct tm6000_dvb *dvb = dev->dvb;
324
325 if(dvb->bulk_urb != NULL) {
326 struct urb *bulk_urb = dvb->bulk_urb;
327
328 kfree(bulk_urb->transfer_buffer);
329 bulk_urb->transfer_buffer = NULL;
330 usb_unlink_urb(bulk_urb);
331 usb_free_urb(bulk_urb);
332 }
333
334/* mutex_lock(&tm6000_driver.open_close_mutex); */
335 if(dvb->frontend) {
336 dvb_frontend_detach(dvb->frontend);
337 dvb_unregister_frontend(dvb->frontend);
338 }
339
340 dvb_dmxdev_release(&dvb->dmxdev);
341 dvb_dmx_release(&dvb->demux);
342 dvb_unregister_adapter(&dvb->adapter);
343 mutex_destroy(&dvb->mutex);
344/* mutex_unlock(&tm6000_driver.open_close_mutex); */
345
346}
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
new file mode 100644
index 000000000000..94ff489a1bbb
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -0,0 +1,370 @@
1/*
2 tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
7 - Fix SMBus Read Byte command
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation version 2
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/usb.h>
26#include <linux/i2c.h>
27
28#include "tm6000.h"
29#include "tm6000-regs.h"
30#include <media/v4l2-common.h>
31#include <media/tuner.h>
32#include "tuner-xc2028.h"
33
34
35/*FIXME: Hack to avoid needing to patch i2c-id.h */
36#define I2C_HW_B_TM6000 I2C_HW_B_EM28XX
37/* ----------------------------------------------------------- */
38
39static unsigned int i2c_debug = 0;
40module_param(i2c_debug, int, 0644);
41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
42
43#define i2c_dprintk(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
44 printk(KERN_DEBUG "%s at %s: " fmt, \
45 dev->name, __FUNCTION__ , ##args); } while (0)
46
47static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
48 __u8 reg, char *buf, int len)
49{
50 int rc;
51 unsigned int tsleep;
52 unsigned int i2c_packet_limit = 16;
53
54 if (dev->dev_type == TM6010)
55 i2c_packet_limit = 64;
56
57 if (!buf)
58 return -1;
59
60 if (len < 1 || len > i2c_packet_limit) {
61 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
62 len, i2c_packet_limit);
63 return -1;
64 }
65
66 /* capture mutex */
67 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
68 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
69 addr | reg << 8, 0, buf, len);
70
71 if (rc < 0) {
72 /* release mutex */
73 return rc;
74 }
75
76 /* Calculate delay time, 14000us for 64 bytes */
77 tsleep = ((len * 200) + 200 + 1000) / 1000;
78 msleep(tsleep);
79
80 /* release mutex */
81 return rc;
82}
83
84/* Generic read - doesn't work fine with 16bit registers */
85static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
86 __u8 reg, char *buf, int len)
87{
88 int rc;
89 u8 b[2];
90 unsigned int i2c_packet_limit = 16;
91
92 if (dev->dev_type == TM6010)
93 i2c_packet_limit = 64;
94
95 if (!buf)
96 return -1;
97
98 if (len < 1 || len > i2c_packet_limit) {
99 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
100 len, i2c_packet_limit);
101 return -1;
102 }
103
104 /* capture mutex */
105 if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) {
106 /*
107 * Workaround an I2C bug when reading from zl10353
108 */
109 reg -= 1;
110 len += 1;
111
112 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
113 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len);
114
115 *buf = b[1];
116 } else {
117 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
118 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
119 }
120
121 /* release mutex */
122 return rc;
123}
124
125/*
126 * read from a 16bit register
127 * for example xc2028, xc3028 or xc3028L
128 */
129static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr,
130 __u16 reg, char *buf, int len)
131{
132 int rc;
133 unsigned char ureg;
134
135 if (!buf || len != 2)
136 return -1;
137
138 /* capture mutex */
139 if (dev->dev_type == TM6010) {
140 ureg = reg & 0xFF;
141 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
142 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
143 addr | (reg & 0xFF00), 0, &ureg, 1);
144
145 if (rc < 0) {
146 /* release mutex */
147 return rc;
148 }
149
150 msleep(1400 / 1000);
151 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
152 USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ,
153 reg, 0, buf, len);
154 } else {
155 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
156 USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN,
157 addr, reg, buf, len);
158 }
159
160 /* release mutex */
161 return rc;
162}
163
164static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
165 struct i2c_msg msgs[], int num)
166{
167 struct tm6000_core *dev = i2c_adap->algo_data;
168 int addr, rc, i, byte;
169
170 if (num <= 0)
171 return 0;
172 for (i = 0; i < num; i++) {
173 addr = (msgs[i].addr << 1) & 0xff;
174 i2c_dprintk(2,"%s %s addr=0x%x len=%d:",
175 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
176 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
177 if (msgs[i].flags & I2C_M_RD) {
178 /* read request without preceding register selection */
179 /*
180 * The TM6000 only supports a read transaction
181 * immediately after a 1 or 2 byte write to select
182 * a register. We cannot fulfil this request.
183 */
184 i2c_dprintk(2, " read without preceding write not"
185 " supported");
186 rc = -EOPNOTSUPP;
187 goto err;
188 } else if (i + 1 < num && msgs[i].len <= 2 &&
189 (msgs[i + 1].flags & I2C_M_RD) &&
190 msgs[i].addr == msgs[i + 1].addr) {
191 /* 1 or 2 byte write followed by a read */
192 if (i2c_debug >= 2)
193 for (byte = 0; byte < msgs[i].len; byte++)
194 printk(" %02x", msgs[i].buf[byte]);
195 i2c_dprintk(2, "; joined to read %s len=%d:",
196 i == num - 2 ? "stop" : "nonstop",
197 msgs[i + 1].len);
198
199 if (msgs[i].len == 2) {
200 rc = tm6000_i2c_recv_regs16(dev, addr,
201 msgs[i].buf[0] << 8 | msgs[i].buf[1],
202 msgs[i + 1].buf, msgs[i + 1].len);
203 } else {
204 rc = tm6000_i2c_recv_regs(dev, addr, msgs[i].buf[0],
205 msgs[i + 1].buf, msgs[i + 1].len);
206 }
207
208 i++;
209
210 if (addr == dev->tuner_addr << 1) {
211 tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
212 tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
213 }
214 if (i2c_debug >= 2)
215 for (byte = 0; byte < msgs[i].len; byte++)
216 printk(" %02x", msgs[i].buf[byte]);
217 } else {
218 /* write bytes */
219 if (i2c_debug >= 2)
220 for (byte = 0; byte < msgs[i].len; byte++)
221 printk(" %02x", msgs[i].buf[byte]);
222 rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0],
223 msgs[i].buf + 1, msgs[i].len - 1);
224
225 if (addr == dev->tuner_addr << 1) {
226 tm6000_set_reg(dev, REQ_50_SET_START, 0, 0);
227 tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0);
228 }
229 }
230 if (i2c_debug >= 2)
231 printk("\n");
232 if (rc < 0)
233 goto err;
234 }
235
236 return num;
237err:
238 i2c_dprintk(2," ERROR: %i\n", rc);
239 return rc;
240}
241
242static int tm6000_i2c_eeprom(struct tm6000_core *dev,
243 unsigned char *eedata, int len)
244{
245 int i, rc;
246 unsigned char *p = eedata;
247 unsigned char bytes[17];
248
249 dev->i2c_client.addr = 0xa0 >> 1;
250
251 bytes[16] = '\0';
252 for (i = 0; i < len; ) {
253 *p = i;
254 rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1);
255 if (rc < 1) {
256 if (p == eedata)
257 goto noeeprom;
258 else {
259 printk(KERN_WARNING
260 "%s: i2c eeprom read error (err=%d)\n",
261 dev->name, rc);
262 }
263 return -1;
264 }
265 p++;
266 if (0 == (i % 16))
267 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
268 printk(" %02x", eedata[i]);
269 if ((eedata[i] >= ' ') && (eedata[i] <= 'z')) {
270 bytes[i%16] = eedata[i];
271 } else {
272 bytes[i%16]='.';
273 }
274
275 i++;
276
277 if (0 == (i % 16)) {
278 bytes[16] = '\0';
279 printk(" %s\n", bytes);
280 }
281 }
282 if (0 != (i%16)) {
283 bytes[i%16] = '\0';
284 for (i %= 16; i < 16; i++)
285 printk(" ");
286 }
287 printk(" %s\n", bytes);
288
289 return 0;
290
291noeeprom:
292 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
293 dev->name, rc);
294 return rc;
295}
296
297/* ----------------------------------------------------------- */
298
299/*
300 * functionality()
301 */
302static u32 functionality(struct i2c_adapter *adap)
303{
304 return I2C_FUNC_SMBUS_EMUL;
305}
306
307#define mass_write(addr, reg, data...) \
308 { const static u8 _val[] = data; \
309 rc=tm6000_read_write_usb(dev,USB_DIR_OUT | USB_TYPE_VENDOR, \
310 REQ_16_SET_GET_I2C_WR1_RDN,(reg<<8)+addr, 0x00, (u8 *) _val, \
311 ARRAY_SIZE(_val)); \
312 if (rc<0) { \
313 printk(KERN_ERR "Error on line %d: %d\n",__LINE__,rc); \
314 return rc; \
315 } \
316 msleep (10); \
317 }
318
319static struct i2c_algorithm tm6000_algo = {
320 .master_xfer = tm6000_i2c_xfer,
321 .functionality = functionality,
322};
323
324static struct i2c_adapter tm6000_adap_template = {
325 .owner = THIS_MODULE,
326 .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
327 .name = "tm6000",
328 .id = I2C_HW_B_TM6000,
329 .algo = &tm6000_algo,
330};
331
332static struct i2c_client tm6000_client_template = {
333 .name = "tm6000 internal",
334};
335
336/* ----------------------------------------------------------- */
337
338/*
339 * tm6000_i2c_register()
340 * register i2c bus
341 */
342int tm6000_i2c_register(struct tm6000_core *dev)
343{
344 unsigned char eedata[256];
345
346 dev->i2c_adap = tm6000_adap_template;
347 dev->i2c_adap.dev.parent = &dev->udev->dev;
348 strcpy(dev->i2c_adap.name, dev->name);
349 dev->i2c_adap.algo_data = dev;
350 i2c_add_adapter(&dev->i2c_adap);
351
352 dev->i2c_client = tm6000_client_template;
353 dev->i2c_client.adapter = &dev->i2c_adap;
354
355 i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
356
357 tm6000_i2c_eeprom(dev, eedata, sizeof(eedata));
358
359 return 0;
360}
361
362/*
363 * tm6000_i2c_unregister()
364 * unregister i2c_bus
365 */
366int tm6000_i2c_unregister(struct tm6000_core *dev)
367{
368 i2c_del_adapter(&dev->i2c_adap);
369 return 0;
370}
diff --git a/drivers/staging/tm6000/tm6000-regs.h b/drivers/staging/tm6000/tm6000-regs.h
new file mode 100644
index 000000000000..1c5289c971fa
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-regs.h
@@ -0,0 +1,541 @@
1/*
2 tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20/*
21 * Define TV Master TM5600/TM6000/TM6010 Request codes
22 */
23#define REQ_00_SET_IR_VALUE 0
24#define REQ_01_SET_WAKEUP_IRCODE 1
25#define REQ_02_GET_IR_CODE 2
26#define REQ_03_SET_GET_MCU_PIN 3
27#define REQ_04_EN_DISABLE_MCU_INT 4
28#define REQ_05_SET_GET_USBREG 5
29 /* Write: RegNum, Value, 0 */
30 /* Read : RegNum, Value, 1, RegStatus */
31#define REQ_06_SET_GET_USBREG_BIT 6
32#define REQ_07_SET_GET_AVREG 7
33 /* Write: RegNum, Value, 0 */
34 /* Read : RegNum, Value, 1, RegStatus */
35#define REQ_08_SET_GET_AVREG_BIT 8
36#define REQ_09_SET_GET_TUNER_FQ 9
37#define REQ_10_SET_TUNER_SYSTEM 10
38#define REQ_11_SET_EEPROM_ADDR 11
39#define REQ_12_SET_GET_EEPROMBYTE 12
40#define REQ_13_GET_EEPROM_SEQREAD 13
41#define REQ_14_SET_GET_I2C_WR2_RDN 14
42#define REQ_15_SET_GET_I2CBYTE 15
43 /* Write: Subaddr, Slave Addr, value, 0 */
44 /* Read : Subaddr, Slave Addr, value, 1 */
45#define REQ_16_SET_GET_I2C_WR1_RDN 16
46 /* Subaddr, Slave Addr, 0, length */
47#define REQ_17_SET_GET_I2CFP 17
48 /* Write: Slave Addr, register, value */
49 /* Read : Slave Addr, register, 2, data */
50#define REQ_20_DATA_TRANSFER 20
51#define REQ_30_I2C_WRITE 30
52#define REQ_31_I2C_READ 31
53#define REQ_35_AFTEK_TUNER_READ 35
54#define REQ_40_GET_VERSION 40
55#define REQ_50_SET_START 50
56#define REQ_51_SET_STOP 51
57#define REQ_52_TRANSMIT_DATA 52
58#define REQ_53_SPI_INITIAL 53
59#define REQ_54_SPI_SETSTART 54
60#define REQ_55_SPI_INOUTDATA 55
61#define REQ_56_SPI_SETSTOP 56
62
63/*
64 * Define TV Master TM5600/TM6000/TM6010 GPIO lines
65 */
66
67#define TM6000_GPIO_CLK 0x101
68#define TM6000_GPIO_DATA 0x100
69
70#define TM6000_GPIO_1 0x102
71#define TM6000_GPIO_2 0x103
72#define TM6000_GPIO_3 0x104
73#define TM6000_GPIO_4 0x300
74#define TM6000_GPIO_5 0x301
75#define TM6000_GPIO_6 0x304
76#define TM6000_GPIO_7 0x305
77
78/* tm6010 defines GPIO with different values */
79#define TM6010_GPIO_0 0x0102
80#define TM6010_GPIO_1 0x0103
81#define TM6010_GPIO_2 0x0104
82#define TM6010_GPIO_3 0x0105
83#define TM6010_GPIO_4 0x0106
84#define TM6010_GPIO_5 0x0107
85#define TM6010_GPIO_6 0x0300
86#define TM6010_GPIO_7 0x0301
87#define TM6010_GPIO_9 0x0305
88/*
89 * Define TV Master TM5600/TM6000/TM6010 URB message codes and length
90 */
91
92enum {
93 TM6000_URB_MSG_VIDEO=1,
94 TM6000_URB_MSG_AUDIO,
95 TM6000_URB_MSG_VBI,
96 TM6000_URB_MSG_PTS,
97 TM6000_URB_MSG_ERR,
98};
99
100/* Define TM6000/TM6010 Video decoder registers */
101#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00
102#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01
103#define TM6010_REQ07_R02_VIDEO_CONTROL2 0x07, 0x02
104#define TM6010_REQ07_R03_YC_SEP_CONTROL 0x07, 0x03
105#define TM6010_REQ07_R04_LUMA_HAGC_CONTROL 0x07, 0x04
106#define TM6010_REQ07_R05_NOISE_THRESHOLD 0x07, 0x05
107#define TM6010_REQ07_R06_AGC_GATE_THRESHOLD 0x07, 0x06
108#define TM6010_REQ07_R07_OUTPUT_CONTROL 0x07, 0x07
109#define TM6010_REQ07_R08_LUMA_CONTRAST_ADJ 0x07, 0x08
110#define TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ 0x07, 0x09
111#define TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ 0x07, 0x0a
112#define TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ 0x07, 0x0b
113#define TM6010_REQ07_R0C_CHROMA_AGC_CONTROL 0x07, 0x0c
114#define TM6010_REQ07_R0D_CHROMA_KILL_LEVEL 0x07, 0x0d
115#define TM6010_REQ07_R0F_CHROMA_AUTO_POSITION 0x07, 0x0f
116#define TM6010_REQ07_R10_AGC_PEAK_NOMINAL 0x07, 0x10
117#define TM6010_REQ07_R11_AGC_PEAK_CONTROL 0x07, 0x11
118#define TM6010_REQ07_R12_AGC_GATE_STARTH 0x07, 0x12
119#define TM6010_REQ07_R13_AGC_GATE_STARTL 0x07, 0x13
120#define TM6010_REQ07_R14_AGC_GATE_WIDTH 0x07, 0x14
121#define TM6010_REQ07_R15_AGC_BP_DELAY 0x07, 0x15
122#define TM6010_REQ07_R16_LOCK_COUNT 0x07, 0x16
123#define TM6010_REQ07_R17_HLOOP_MAXSTATE 0x07, 0x17
124#define TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3 0x07, 0x18
125#define TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2 0x07, 0x19
126#define TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1 0x07, 0x1a
127#define TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0 0x07, 0x1b
128#define TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3 0x07, 0x1c
129#define TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2 0x07, 0x1d
130#define TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1 0x07, 0x1e
131#define TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0 0x07, 0x1f
132#define TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME 0x07, 0x20
133#define TM6010_REQ07_R21_HSYNC_PHASE_OFFSET 0x07, 0x21
134#define TM6010_REQ07_R22_HSYNC_PLL_START_TIME 0x07, 0x22
135#define TM6010_REQ07_R23_HSYNC_PLL_END_TIME 0x07, 0x23
136#define TM6010_REQ07_R24_HSYNC_TIP_START_TIME 0x07, 0x24
137#define TM6010_REQ07_R25_HSYNC_TIP_END_TIME 0x07, 0x25
138#define TM6010_REQ07_R26_HSYNC_RISING_EDGE_START 0x07, 0x26
139#define TM6010_REQ07_R27_HSYNC_RISING_EDGE_END 0x07, 0x27
140#define TM6010_REQ07_R28_BACKPORCH_START 0x07, 0x28
141#define TM6010_REQ07_R29_BACKPORCH_END 0x07, 0x29
142#define TM6010_REQ07_R2A_HSYNC_FILTER_START 0x07, 0x2a
143#define TM6010_REQ07_R2B_HSYNC_FILTER_END 0x07, 0x2b
144#define TM6010_REQ07_R2C_CHROMA_BURST_START 0x07, 0x2c
145#define TM6010_REQ07_R2D_CHROMA_BURST_END 0x07, 0x2d
146#define TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART 0x07, 0x2e
147#define TM6010_REQ07_R2F_ACTIVE_VIDEO_HWIDTH 0x07, 0x2f
148#define TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART 0x07, 0x30
149#define TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT 0x07, 0x31
150#define TM6010_REQ07_R32_VSYNC_HLOCK_MIN 0x07, 0x32
151#define TM6010_REQ07_R33_VSYNC_HLOCK_MAX 0x07, 0x33
152#define TM6010_REQ07_R34_VSYNC_AGC_MIN 0x07, 0x34
153#define TM6010_REQ07_R35_VSYNC_AGC_MAX 0x07, 0x35
154#define TM6010_REQ07_R36_VSYNC_VBI_MIN 0x07, 0x36
155#define TM6010_REQ07_R37_VSYNC_VBI_MAX 0x07, 0x37
156#define TM6010_REQ07_R38_VSYNC_THRESHOLD 0x07, 0x38
157#define TM6010_REQ07_R39_VSYNC_TIME_CONSTANT 0x07, 0x39
158#define TM6010_REQ07_R3A_STATUS1 0x07, 0x3a
159#define TM6010_REQ07_R3B_STATUS2 0x07, 0x3b
160#define TM6010_REQ07_R3C_STATUS3 0x07, 0x3c
161#define TM6010_REQ07_R3F_RESET 0x07, 0x3f
162#define TM6010_REQ07_R40_TELETEXT_VBI_CODE0 0x07, 0x40
163#define TM6010_REQ07_R41_TELETEXT_VBI_CODE1 0x07, 0x41
164#define TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL 0x07, 0x42
165#define TM6010_REQ07_R43_VBI_DATA_TYPE_LINE7 0x07, 0x43
166#define TM6010_REQ07_R44_VBI_DATA_TYPE_LINE8 0x07, 0x44
167#define TM6010_REQ07_R45_VBI_DATA_TYPE_LINE9 0x07, 0x45
168#define TM6010_REQ07_R46_VBI_DATA_TYPE_LINE10 0x07, 0x46
169#define TM6010_REQ07_R47_VBI_DATA_TYPE_LINE11 0x07, 0x47
170#define TM6010_REQ07_R48_VBI_DATA_TYPE_LINE12 0x07, 0x48
171#define TM6010_REQ07_R49_VBI_DATA_TYPE_LINE13 0x07, 0x49
172#define TM6010_REQ07_R4A_VBI_DATA_TYPE_LINE14 0x07, 0x4a
173#define TM6010_REQ07_R4B_VBI_DATA_TYPE_LINE15 0x07, 0x4b
174#define TM6010_REQ07_R4C_VBI_DATA_TYPE_LINE16 0x07, 0x4c
175#define TM6010_REQ07_R4D_VBI_DATA_TYPE_LINE17 0x07, 0x4d
176#define TM6010_REQ07_R4E_VBI_DATA_TYPE_LINE18 0x07, 0x4e
177#define TM6010_REQ07_R4F_VBI_DATA_TYPE_LINE19 0x07, 0x4f
178#define TM6010_REQ07_R50_VBI_DATA_TYPE_LINE20 0x07, 0x50
179#define TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21 0x07, 0x51
180#define TM6010_REQ07_R52_VBI_DATA_TYPE_LINE22 0x07, 0x52
181#define TM6010_REQ07_R53_VBI_DATA_TYPE_LINE23 0x07, 0x53
182#define TM6010_REQ07_R54_VBI_DATA_TYPE_RLINES 0x07, 0x54
183#define TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN 0x07, 0x55
184#define TM6010_REQ07_R56_VBI_LOOP_FILTER_I_GAIN 0x07, 0x56
185#define TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN 0x07, 0x57
186#define TM6010_REQ07_R58_VBI_CAPTION_DTO1 0x07, 0x58
187#define TM6010_REQ07_R59_VBI_CAPTION_DTO0 0x07, 0x59
188#define TM6010_REQ07_R5A_VBI_TELETEXT_DTO1 0x07, 0x5a
189#define TM6010_REQ07_R5B_VBI_TELETEXT_DTO0 0x07, 0x5b
190#define TM6010_REQ07_R5C_VBI_WSS625_DTO1 0x07, 0x5c
191#define TM6010_REQ07_R5D_VBI_WSS625_DTO0 0x07, 0x5d
192#define TM6010_REQ07_R5E_VBI_CAPTION_FRAME_START 0x07, 0x5e
193#define TM6010_REQ07_R5F_VBI_WSS625_FRAME_START 0x07, 0x5f
194#define TM6010_REQ07_R60_TELETEXT_FRAME_START 0x07, 0x60
195#define TM6010_REQ07_R61_VBI_CCDATA1 0x07, 0x61
196#define TM6010_REQ07_R62_VBI_CCDATA2 0x07, 0x62
197#define TM6010_REQ07_R63_VBI_WSS625_DATA1 0x07, 0x63
198#define TM6010_REQ07_R64_VBI_WSS625_DATA2 0x07, 0x64
199#define TM6010_REQ07_R65_VBI_DATA_STATUS 0x07, 0x65
200#define TM6010_REQ07_R66_VBI_CAPTION_START 0x07, 0x66
201#define TM6010_REQ07_R67_VBI_WSS625_START 0x07, 0x67
202#define TM6010_REQ07_R68_VBI_TELETEXT_START 0x07, 0x68
203#define TM6010_REQ07_R70_HSYNC_DTO_INC_STATUS3 0x07, 0x70
204#define TM6010_REQ07_R71_HSYNC_DTO_INC_STATUS2 0x07, 0x71
205#define TM6010_REQ07_R72_HSYNC_DTO_INC_STATUS1 0x07, 0x72
206#define TM6010_REQ07_R73_HSYNC_DTO_INC_STATUS0 0x07, 0x73
207#define TM6010_REQ07_R74_CHROMA_DTO_INC_STATUS3 0x07, 0x74
208#define TM6010_REQ07_R75_CHROMA_DTO_INC_STATUS2 0x07, 0x75
209#define TM6010_REQ07_R76_CHROMA_DTO_INC_STATUS1 0x07, 0x76
210#define TM6010_REQ07_R77_CHROMA_DTO_INC_STATUS0 0x07, 0x77
211#define TM6010_REQ07_R78_AGC_AGAIN_STATUS 0x07, 0x78
212#define TM6010_REQ07_R79_AGC_DGAIN_STATUS 0x07, 0x79
213#define TM6010_REQ07_R7A_CHROMA_MAG_STATUS 0x07, 0x7a
214#define TM6010_REQ07_R7B_CHROMA_GAIN_STATUS1 0x07, 0x7b
215#define TM6010_REQ07_R7C_CHROMA_GAIN_STATUS0 0x07, 0x7c
216#define TM6010_REQ07_R7D_CORDIC_FREQ_STATUS 0x07, 0x7d
217#define TM6010_REQ07_R7F_STATUS_NOISE 0x07, 0x7f
218#define TM6010_REQ07_R80_COMB_FILTER_TRESHOLD 0x07, 0x80
219#define TM6010_REQ07_R82_COMB_FILTER_CONFIG 0x07, 0x82
220#define TM6010_REQ07_R83_CHROMA_LOCK_CONFIG 0x07, 0x83
221#define TM6010_REQ07_R84_NOISE_NTSC_C 0x07, 0x84
222#define TM6010_REQ07_R85_NOISE_PAL_C 0x07, 0x85
223#define TM6010_REQ07_R86_NOISE_PHASE_C 0x07, 0x86
224#define TM6010_REQ07_R87_NOISE_PHASE_Y 0x07, 0x87
225#define TM6010_REQ07_R8A_CHROMA_LOOPFILTER_STATE 0x07, 0x8a
226#define TM6010_REQ07_R8B_CHROMA_HRESAMPLER 0x07, 0x8b
227#define TM6010_REQ07_R8D_CPUMP_DELAY_ADJ 0x07, 0x8d
228#define TM6010_REQ07_R8E_CPUMP_ADJ 0x07, 0x8e
229#define TM6010_REQ07_R8F_CPUMP_DELAY 0x07, 0x8f
230
231/* Define TM6000/TM6010 Miscellaneous registers */
232#define TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE 0x07, 0xc0
233#define TM6010_REQ07_RC1_TRESHOLD 0x07, 0xc1
234#define TM6010_REQ07_RC2_HSYNC_WIDTH 0x07, 0xc2
235#define TM6010_REQ07_RC3_HSTART1 0x07, 0xc3
236#define TM6010_REQ07_RC4_HSTART0 0x07, 0xc4
237#define TM6010_REQ07_RC5_HEND1 0x07, 0xc5
238#define TM6010_REQ07_RC6_HEND0 0x07, 0xc6
239#define TM6010_REQ07_RC7_VSTART1 0x07, 0xc7
240#define TM6010_REQ07_RC8_VSTART0 0x07, 0xc8
241#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9
242#define TM6010_REQ07_RCA_VEND0 0x07, 0xca
243#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb
244#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF 0x07, 0xcc
245#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0
246#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1
247#define TM6010_REQ07_RD2_ADDR_FOR_REQ2 0x07, 0xd2
248#define TM6010_REQ07_RD3_ADDR_FOR_REQ3 0x07, 0xd3
249#define TM6010_REQ07_RD4_ADDR_FOR_REQ4 0x07, 0xd4
250#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5
251#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6
252#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7
253#define TM6010_REQ07_RD8_IR 0x07, 0xd8
254#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9
255#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda
256#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb
257#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc
258#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd
259#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde
260#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf
261#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0
262#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1
263#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2
264#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3
265#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4
266#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5
267#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7
268#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8
269#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9
270#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea
271#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0
272#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1
273#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2
274#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3
275#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4
276#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5
277#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6
278#define TM6010_REQ07_RF7_BIST 0x07, 0xf7
279#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe
280#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff
281
282/* Define TM6000/TM6010 USB registers */
283#define TM6010_REQ05_R00_MAIN_CTRL 0x05, 0x00
284#define TM6010_REQ05_R01_DEVADDR 0x05, 0x01
285#define TM6010_REQ05_R02_TEST 0x05, 0x02
286#define TM6010_REQ05_R04_SOFN0 0x05, 0x04
287#define TM6010_REQ05_R05_SOFN1 0x05, 0x05
288#define TM6010_REQ05_R06_SOFTM0 0x05, 0x06
289#define TM6010_REQ05_R07_SOFTM1 0x05, 0x07
290#define TM6010_REQ05_R08_PHY_TEST 0x05, 0x08
291#define TM6010_REQ05_R09_VCTL 0x05, 0x09
292#define TM6010_REQ05_R0A_VSTA 0x05, 0x0a
293#define TM6010_REQ05_R0B_CX_CFG 0x05, 0x0b
294#define TM6010_REQ05_R0C_ENDP0_REG0 0x05, 0x0c
295#define TM6010_REQ05_R10_GMASK 0x05, 0x10
296#define TM6010_REQ05_R11_IMASK0 0x05, 0x11
297#define TM6010_REQ05_R12_IMASK1 0x05, 0x12
298#define TM6010_REQ05_R13_IMASK2 0x05, 0x13
299#define TM6010_REQ05_R14_IMASK3 0x05, 0x14
300#define TM6010_REQ05_R15_IMASK4 0x05, 0x15
301#define TM6010_REQ05_R16_IMASK5 0x05, 0x16
302#define TM6010_REQ05_R17_IMASK6 0x05, 0x17
303#define TM6010_REQ05_R18_IMASK7 0x05, 0x18
304#define TM6010_REQ05_R19_ZEROP0 0x05, 0x19
305#define TM6010_REQ05_R1A_ZEROP1 0x05, 0x1a
306#define TM6010_REQ05_R1C_FIFO_EMP0 0x05, 0x1c
307#define TM6010_REQ05_R1D_FIFO_EMP1 0x05, 0x1d
308#define TM6010_REQ05_R20_IRQ_GROUP 0x05, 0x20
309#define TM6010_REQ05_R21_IRQ_SOURCE0 0x05, 0x21
310#define TM6010_REQ05_R22_IRQ_SOURCE1 0x05, 0x22
311#define TM6010_REQ05_R23_IRQ_SOURCE2 0x05, 0x23
312#define TM6010_REQ05_R24_IRQ_SOURCE3 0x05, 0x24
313#define TM6010_REQ05_R25_IRQ_SOURCE4 0x05, 0x25
314#define TM6010_REQ05_R26_IRQ_SOURCE5 0x05, 0x26
315#define TM6010_REQ05_R27_IRQ_SOURCE6 0x05, 0x27
316#define TM6010_REQ05_R28_IRQ_SOURCE7 0x05, 0x28
317#define TM6010_REQ05_R29_SEQ_ERR0 0x05, 0x29
318#define TM6010_REQ05_R2A_SEQ_ERR1 0x05, 0x2a
319#define TM6010_REQ05_R2B_SEQ_ABORT0 0x05, 0x2b
320#define TM6010_REQ05_R2C_SEQ_ABORT1 0x05, 0x2c
321#define TM6010_REQ05_R2D_TX_ZERO0 0x05, 0x2d
322#define TM6010_REQ05_R2E_TX_ZERO1 0x05, 0x2e
323#define TM6010_REQ05_R2F_IDLE_CNT 0x05, 0x2f
324#define TM6010_REQ05_R30_FNO_P1 0x05, 0x30
325#define TM6010_REQ05_R31_FNO_P2 0x05, 0x31
326#define TM6010_REQ05_R32_FNO_P3 0x05, 0x32
327#define TM6010_REQ05_R33_FNO_P4 0x05, 0x33
328#define TM6010_REQ05_R34_FNO_P5 0x05, 0x34
329#define TM6010_REQ05_R35_FNO_P6 0x05, 0x35
330#define TM6010_REQ05_R36_FNO_P7 0x05, 0x36
331#define TM6010_REQ05_R37_FNO_P8 0x05, 0x37
332#define TM6010_REQ05_R38_FNO_P9 0x05, 0x38
333#define TM6010_REQ05_R30_FNO_P10 0x05, 0x39
334#define TM6010_REQ05_R30_FNO_P11 0x05, 0x3a
335#define TM6010_REQ05_R30_FNO_P12 0x05, 0x3b
336#define TM6010_REQ05_R30_FNO_P13 0x05, 0x3c
337#define TM6010_REQ05_R30_FNO_P14 0x05, 0x3d
338#define TM6010_REQ05_R30_FNO_P15 0x05, 0x3e
339#define TM6010_REQ05_R40_IN_MAXPS_LOW1 0x05, 0x40
340#define TM6010_REQ05_R41_IN_MAXPS_HIGH1 0x05, 0x41
341#define TM6010_REQ05_R42_IN_MAXPS_LOW2 0x05, 0x42
342#define TM6010_REQ05_R43_IN_MAXPS_HIGH2 0x05, 0x43
343#define TM6010_REQ05_R44_IN_MAXPS_LOW3 0x05, 0x44
344#define TM6010_REQ05_R45_IN_MAXPS_HIGH3 0x05, 0x45
345#define TM6010_REQ05_R46_IN_MAXPS_LOW4 0x05, 0x46
346#define TM6010_REQ05_R47_IN_MAXPS_HIGH4 0x05, 0x47
347#define TM6010_REQ05_R48_IN_MAXPS_LOW5 0x05, 0x48
348#define TM6010_REQ05_R49_IN_MAXPS_HIGH5 0x05, 0x49
349#define TM6010_REQ05_R4A_IN_MAXPS_LOW6 0x05, 0x4a
350#define TM6010_REQ05_R4B_IN_MAXPS_HIGH6 0x05, 0x4b
351#define TM6010_REQ05_R4C_IN_MAXPS_LOW7 0x05, 0x4c
352#define TM6010_REQ05_R4D_IN_MAXPS_HIGH7 0x05, 0x4d
353#define TM6010_REQ05_R4E_IN_MAXPS_LOW8 0x05, 0x4e
354#define TM6010_REQ05_R4F_IN_MAXPS_HIGH8 0x05, 0x4f
355#define TM6010_REQ05_R50_IN_MAXPS_LOW9 0x05, 0x50
356#define TM6010_REQ05_R51_IN_MAXPS_HIGH9 0x05, 0x51
357#define TM6010_REQ05_R40_IN_MAXPS_LOW10 0x05, 0x52
358#define TM6010_REQ05_R41_IN_MAXPS_HIGH10 0x05, 0x53
359#define TM6010_REQ05_R40_IN_MAXPS_LOW11 0x05, 0x54
360#define TM6010_REQ05_R41_IN_MAXPS_HIGH11 0x05, 0x55
361#define TM6010_REQ05_R40_IN_MAXPS_LOW12 0x05, 0x56
362#define TM6010_REQ05_R41_IN_MAXPS_HIGH12 0x05, 0x57
363#define TM6010_REQ05_R40_IN_MAXPS_LOW13 0x05, 0x58
364#define TM6010_REQ05_R41_IN_MAXPS_HIGH13 0x05, 0x59
365#define TM6010_REQ05_R40_IN_MAXPS_LOW14 0x05, 0x5a
366#define TM6010_REQ05_R41_IN_MAXPS_HIGH14 0x05, 0x5b
367#define TM6010_REQ05_R40_IN_MAXPS_LOW15 0x05, 0x5c
368#define TM6010_REQ05_R41_IN_MAXPS_HIGH15 0x05, 0x5d
369#define TM6010_REQ05_R60_OUT_MAXPS_LOW1 0x05, 0x60
370#define TM6010_REQ05_R61_OUT_MAXPS_HIGH1 0x05, 0x61
371#define TM6010_REQ05_R62_OUT_MAXPS_LOW2 0x05, 0x62
372#define TM6010_REQ05_R63_OUT_MAXPS_HIGH2 0x05, 0x63
373#define TM6010_REQ05_R64_OUT_MAXPS_LOW3 0x05, 0x64
374#define TM6010_REQ05_R65_OUT_MAXPS_HIGH3 0x05, 0x65
375#define TM6010_REQ05_R66_OUT_MAXPS_LOW4 0x05, 0x66
376#define TM6010_REQ05_R67_OUT_MAXPS_HIGH4 0x05, 0x67
377#define TM6010_REQ05_R68_OUT_MAXPS_LOW5 0x05, 0x68
378#define TM6010_REQ05_R69_OUT_MAXPS_HIGH5 0x05, 0x69
379#define TM6010_REQ05_R6A_OUT_MAXPS_LOW6 0x05, 0x6a
380#define TM6010_REQ05_R6B_OUT_MAXPS_HIGH6 0x05, 0x6b
381#define TM6010_REQ05_R6C_OUT_MAXPS_LOW7 0x05, 0x6c
382#define TM6010_REQ05_R6D_OUT_MAXPS_HIGH7 0x05, 0x6d
383#define TM6010_REQ05_R6E_OUT_MAXPS_LOW8 0x05, 0x6e
384#define TM6010_REQ05_R6F_OUT_MAXPS_HIGH8 0x05, 0x6f
385#define TM6010_REQ05_R70_OUT_MAXPS_LOW9 0x05, 0x70
386#define TM6010_REQ05_R71_OUT_MAXPS_HIGH9 0x05, 0x71
387#define TM6010_REQ05_R60_OUT_MAXPS_LOW10 0x05, 0x72
388#define TM6010_REQ05_R61_OUT_MAXPS_HIGH10 0x05, 0x73
389#define TM6010_REQ05_R60_OUT_MAXPS_LOW11 0x05, 0x74
390#define TM6010_REQ05_R61_OUT_MAXPS_HIGH11 0x05, 0x75
391#define TM6010_REQ05_R60_OUT_MAXPS_LOW12 0x05, 0x76
392#define TM6010_REQ05_R61_OUT_MAXPS_HIGH12 0x05, 0x77
393#define TM6010_REQ05_R60_OUT_MAXPS_LOW13 0x05, 0x78
394#define TM6010_REQ05_R61_OUT_MAXPS_HIGH13 0x05, 0x79
395#define TM6010_REQ05_R60_OUT_MAXPS_LOW14 0x05, 0x7a
396#define TM6010_REQ05_R61_OUT_MAXPS_HIGH14 0x05, 0x7b
397#define TM6010_REQ05_R60_OUT_MAXPS_LOW15 0x05, 0x7c
398#define TM6010_REQ05_R61_OUT_MAXPS_HIGH15 0x05, 0x7d
399#define TM6010_REQ05_R80_FIFO0 0x05, 0x80
400#define TM6010_REQ05_R81_FIFO1 0x05, 0x81
401#define TM6010_REQ05_R82_FIFO2 0x05, 0x82
402#define TM6010_REQ05_R83_FIFO3 0x05, 0x83
403#define TM6010_REQ05_R84_FIFO4 0x05, 0x84
404#define TM6010_REQ05_R85_FIFO5 0x05, 0x85
405#define TM6010_REQ05_R86_FIFO6 0x05, 0x86
406#define TM6010_REQ05_R87_FIFO7 0x05, 0x87
407#define TM6010_REQ05_R88_FIFO8 0x05, 0x88
408#define TM6010_REQ05_R89_FIFO9 0x05, 0x89
409#define TM6010_REQ05_R81_FIFO10 0x05, 0x8a
410#define TM6010_REQ05_R81_FIFO11 0x05, 0x8b
411#define TM6010_REQ05_R81_FIFO12 0x05, 0x8c
412#define TM6010_REQ05_R81_FIFO13 0x05, 0x8d
413#define TM6010_REQ05_R81_FIFO14 0x05, 0x8e
414#define TM6010_REQ05_R81_FIFO15 0x05, 0x8f
415#define TM6010_REQ05_R90_CFG_FIFO0 0x05, 0x90
416#define TM6010_REQ05_R91_CFG_FIFO1 0x05, 0x91
417#define TM6010_REQ05_R92_CFG_FIFO2 0x05, 0x92
418#define TM6010_REQ05_R93_CFG_FIFO3 0x05, 0x93
419#define TM6010_REQ05_R94_CFG_FIFO4 0x05, 0x94
420#define TM6010_REQ05_R95_CFG_FIFO5 0x05, 0x95
421#define TM6010_REQ05_R96_CFG_FIFO6 0x05, 0x96
422#define TM6010_REQ05_R97_CFG_FIFO7 0x05, 0x97
423#define TM6010_REQ05_R98_CFG_FIFO8 0x05, 0x98
424#define TM6010_REQ05_R99_CFG_FIFO9 0x05, 0x99
425#define TM6010_REQ05_R91_CFG_FIFO10 0x05, 0x9a
426#define TM6010_REQ05_R91_CFG_FIFO11 0x05, 0x9b
427#define TM6010_REQ05_R91_CFG_FIFO12 0x05, 0x9c
428#define TM6010_REQ05_R91_CFG_FIFO13 0x05, 0x9d
429#define TM6010_REQ05_R91_CFG_FIFO14 0x05, 0x9e
430#define TM6010_REQ05_R91_CFG_FIFO15 0x05, 0x9f
431#define TM6010_REQ05_RA0_CTL_FIFO0 0x05, 0xa0
432#define TM6010_REQ05_RA1_CTL_FIFO1 0x05, 0xa1
433#define TM6010_REQ05_RA2_CTL_FIFO2 0x05, 0xa2
434#define TM6010_REQ05_RA3_CTL_FIFO3 0x05, 0xa3
435#define TM6010_REQ05_RA4_CTL_FIFO4 0x05, 0xa4
436#define TM6010_REQ05_RA5_CTL_FIFO5 0x05, 0xa5
437#define TM6010_REQ05_RA6_CTL_FIFO6 0x05, 0xa6
438#define TM6010_REQ05_RA7_CTL_FIFO7 0x05, 0xa7
439#define TM6010_REQ05_RA8_CTL_FIFO8 0x05, 0xa8
440#define TM6010_REQ05_RA9_CTL_FIFO9 0x05, 0xa9
441#define TM6010_REQ05_RA1_CTL_FIFO10 0x05, 0xaa
442#define TM6010_REQ05_RA1_CTL_FIFO11 0x05, 0xab
443#define TM6010_REQ05_RA1_CTL_FIFO12 0x05, 0xac
444#define TM6010_REQ05_RA1_CTL_FIFO13 0x05, 0xad
445#define TM6010_REQ05_RA1_CTL_FIFO14 0x05, 0xae
446#define TM6010_REQ05_RA1_CTL_FIFO15 0x05, 0xaf
447#define TM6010_REQ05_RB0_BC_LOW_FIFO0 0x05, 0xb0
448#define TM6010_REQ05_RB1_BC_LOW_FIFO1 0x05, 0xb1
449#define TM6010_REQ05_RB2_BC_LOW_FIFO2 0x05, 0xb2
450#define TM6010_REQ05_RB3_BC_LOW_FIFO3 0x05, 0xb3
451#define TM6010_REQ05_RB4_BC_LOW_FIFO4 0x05, 0xb4
452#define TM6010_REQ05_RB5_BC_LOW_FIFO5 0x05, 0xb5
453#define TM6010_REQ05_RB6_BC_LOW_FIFO6 0x05, 0xb6
454#define TM6010_REQ05_RB7_BC_LOW_FIFO7 0x05, 0xb7
455#define TM6010_REQ05_RB8_BC_LOW_FIFO8 0x05, 0xb8
456#define TM6010_REQ05_RB9_BC_LOW_FIFO9 0x05, 0xb9
457#define TM6010_REQ05_RB1_BC_LOW_FIFO10 0x05, 0xba
458#define TM6010_REQ05_RB1_BC_LOW_FIFO11 0x05, 0xbb
459#define TM6010_REQ05_RB1_BC_LOW_FIFO12 0x05, 0xbc
460#define TM6010_REQ05_RB1_BC_LOW_FIFO13 0x05, 0xbd
461#define TM6010_REQ05_RB1_BC_LOW_FIFO14 0x05, 0xbe
462#define TM6010_REQ05_RB1_BC_LOW_FIFO15 0x05, 0xbf
463#define TM6010_REQ05_RC0_DATA_FIFO0 0x05, 0xc0
464#define TM6010_REQ05_RC4_DATA_FIFO1 0x05, 0xc4
465#define TM6010_REQ05_RC8_DATA_FIFO2 0x05, 0xc8
466#define TM6010_REQ05_RCC_DATA_FIFO3 0x05, 0xcc
467#define TM6010_REQ05_RD0_DATA_FIFO4 0x05, 0xd0
468#define TM6010_REQ05_RD4_DATA_FIFO5 0x05, 0xd4
469#define TM6010_REQ05_RD8_DATA_FIFO6 0x05, 0xd8
470#define TM6010_REQ05_RDC_DATA_FIFO7 0x05, 0xdc
471#define TM6010_REQ05_RE0_DATA_FIFO8 0x05, 0xe0
472#define TM6010_REQ05_RE4_DATA_FIFO9 0x05, 0xe4
473#define TM6010_REQ05_RC4_DATA_FIFO10 0x05, 0xe8
474#define TM6010_REQ05_RC4_DATA_FIFO11 0x05, 0xec
475#define TM6010_REQ05_RC4_DATA_FIFO12 0x05, 0xf0
476#define TM6010_REQ05_RC4_DATA_FIFO13 0x05, 0xf4
477#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8
478#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc
479
480/* Define TM6000/TM6010 Audio decoder registers */
481#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00
482#define TM6010_REQ08_R01_A_INIT 0x08, 0x01
483#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02
484#define TM6010_REQ08_R03_A_AUTO_GAIN_CTRL 0x08, 0x03
485#define TM6010_REQ08_R04_A_SIF_AMP_CTRL 0x08, 0x04
486#define TM6010_REQ08_R05_A_STANDARD_MOD 0x08, 0x05
487#define TM6010_REQ08_R06_A_SOUND_MOD 0x08, 0x06
488#define TM6010_REQ08_R07_A_LEFT_VOL 0x08, 0x07
489#define TM6010_REQ08_R08_A_RIGHT_VOL 0x08, 0x08
490#define TM6010_REQ08_R09_A_MAIN_VOL 0x08, 0x09
491#define TM6010_REQ08_R0A_A_I2S_MOD 0x08, 0x0a
492#define TM6010_REQ08_R0B_A_ASD_THRES1 0x08, 0x0b
493#define TM6010_REQ08_R0C_A_ASD_THRES2 0x08, 0x0c
494#define TM6010_REQ08_R0D_A_AMD_THRES 0x08, 0x0d
495#define TM6010_REQ08_R0E_A_MONO_THRES1 0x08, 0x0e
496#define TM6010_REQ08_R0F_A_MONO_THRES2 0x08, 0x0f
497#define TM6010_REQ08_R10_A_MUTE_THRES1 0x08, 0x10
498#define TM6010_REQ08_R11_A_MUTE_THRES2 0x08, 0x11
499#define TM6010_REQ08_R12_A_AGC_U 0x08, 0x12
500#define TM6010_REQ08_R13_A_AGC_ERR_T 0x08, 0x13
501#define TM6010_REQ08_R14_A_AGC_GAIN_INIT 0x08, 0x14
502#define TM6010_REQ08_R15_A_AGC_STEP_THR 0x08, 0x15
503#define TM6010_REQ08_R16_A_AGC_GAIN_MAX 0x08, 0x16
504#define TM6010_REQ08_R17_A_AGC_GAIN_MIN 0x08, 0x17
505#define TM6010_REQ08_R18_A_TR_CTRL 0x08, 0x18
506#define TM6010_REQ08_R19_A_FH_2FH_GAIN 0x08, 0x19
507#define TM6010_REQ08_R1A_A_NICAM_SER_MAX 0x08, 0x1a
508#define TM6010_REQ08_R1B_A_NICAM_SER_MIN 0x08, 0x1b
509#define TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT 0x08, 0x1e
510#define TM6010_REQ08_R1F_A_TEST_INTF_SEL 0x08, 0x1f
511#define TM6010_REQ08_R20_A_TEST_PIN_SEL 0x08, 0x20
512#define TM6010_REQ08_R21_A_AGC_ERR 0x08, 0x21
513#define TM6010_REQ08_R22_A_AGC_GAIN 0x08, 0x22
514#define TM6010_REQ08_R23_A_NICAM_INFO 0x08, 0x23
515#define TM6010_REQ08_R24_A_SER 0x08, 0x24
516#define TM6010_REQ08_R25_A_C1_AMP 0x08, 0x25
517#define TM6010_REQ08_R26_A_C2_AMP 0x08, 0x26
518#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27
519#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28
520
521/* Define TM6000/TM6010 Video ADC registers */
522#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0
523#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1
524#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2
525#define TM6010_REQ08_RE3_ADC_IN1_SEL 0x08, 0xe3
526#define TM6010_REQ08_RE4_ADC_IN2_SEL 0x08, 0xe4
527#define TM6010_REQ08_RE5_GAIN_PARAM 0x08, 0xe5
528#define TM6010_REQ08_RE6_POWER_DOWN_CTRL2 0x08, 0xe6
529#define TM6010_REQ08_RE7_REG_GAIN_Y 0x08, 0xe7
530#define TM6010_REQ08_RE8_REG_GAIN_C 0x08, 0xe8
531#define TM6010_REQ08_RE9_BIAS_CTRL 0x08, 0xe9
532#define TM6010_REQ08_REA_BUFF_DRV_CTRL 0x08, 0xea
533#define TM6010_REQ08_REB_SIF_GAIN_CTRL 0x08, 0xeb
534#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec
535#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed
536
537/* Define TM6000/TM6010 Audio ADC registers */
538#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0
539#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1
540#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2
541#define TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL 0x08, 0xf3
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
new file mode 100644
index 000000000000..b3564f611e5e
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -0,0 +1,873 @@
1/*
2 tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@redhat.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include "tm6000.h"
23#include "tm6000-regs.h"
24
25struct tm6000_reg_settings {
26 unsigned char req;
27 unsigned char reg;
28 unsigned char value;
29};
30
31struct tm6000_std_tv_settings {
32 v4l2_std_id id;
33 struct tm6000_reg_settings sif[12];
34 struct tm6000_reg_settings nosif[12];
35 struct tm6000_reg_settings common[25];
36};
37
38struct tm6000_std_settings {
39 v4l2_std_id id;
40 struct tm6000_reg_settings common[37];
41};
42
43static struct tm6000_std_tv_settings tv_stds[] = {
44 {
45 .id = V4L2_STD_PAL_M,
46 .sif = {
47 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
48 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
49 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
50 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
51 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
52 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
53 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
54 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
55 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
56 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
57 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
58 {0, 0, 0},
59 },
60 .nosif = {
61 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
62 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
63 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
64 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
65 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
66 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
67 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
68 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
69 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
70 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
71 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
72 {0, 0, 0},
73 },
74 .common = {
75 {TM6010_REQ07_R3F_RESET, 0x01},
76 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
77 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
78 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
79 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
80 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
81 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
82 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
83 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
84 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
85 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
86 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
87 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
88 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
89 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
90 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20},
91 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
92 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
93 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
94 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
95 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
96
97 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
98 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
99 {TM6010_REQ07_R3F_RESET, 0x00},
100 {0, 0, 0},
101 },
102 }, {
103 .id = V4L2_STD_PAL_Nc,
104 .sif = {
105 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
106 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
107 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
108 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
109 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
110 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
111 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
112 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
113 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
114 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
115 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
116 {0, 0, 0},
117 },
118 .nosif = {
119 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
120 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
121 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
122 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
123 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
124 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
125 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
126 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
127 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
128 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
129 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
130 {0, 0, 0},
131 },
132 .common = {
133 {TM6010_REQ07_R3F_RESET, 0x01},
134 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
135 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
136 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
137 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
138 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
139 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
140 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
141 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
142 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
143 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
144 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
145 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
146 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
147 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
148 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
149 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
150 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
151 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
152 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
153 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
154
155 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
156 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
157 {TM6010_REQ07_R3F_RESET, 0x00},
158 {0, 0, 0},
159 },
160 }, {
161 .id = V4L2_STD_PAL,
162 .sif = {
163 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
164 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
165 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
166 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
167 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
168 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
169 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
170 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
171 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
172 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
173 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
174 {0, 0, 0}
175 },
176 .nosif = {
177 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
178 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
179 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
180 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
181 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
182 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
183 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
184 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
185 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
186 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
187 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
188 {0, 0, 0},
189 },
190 .common = {
191 {TM6010_REQ07_R3F_RESET, 0x01},
192 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
193 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
194 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
195 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
196 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
197 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
198 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
199 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
200 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
201 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
202 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
203 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
204 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
205 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
206 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
207 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
208 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
209 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
210 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
211 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
212
213 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
214 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
215 {TM6010_REQ07_R3F_RESET, 0x00},
216 {0, 0, 0},
217 },
218 }, {
219 .id = V4L2_STD_SECAM,
220 .sif = {
221 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
222 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
223 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
224 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
225 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
226 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
227 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
228 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
229 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
230 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
231 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
232 {0, 0, 0},
233 },
234 .nosif = {
235 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
236 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
237 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
238 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
239 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
240 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
241 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
242 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
243 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
244 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
245 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
246 {0, 0, 0},
247 },
248 .common = {
249 {TM6010_REQ07_R3F_RESET, 0x01},
250 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
251 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
252 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
253 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
254 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
255 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
256 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
257 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
258 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
259 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
260 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
261 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
262 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
263 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
264 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
265 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
266 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
267 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
268 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
269 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
270
271 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
272 {TM6010_REQ07_R3F_RESET, 0x00},
273 {0, 0, 0},
274 },
275 }, {
276 .id = V4L2_STD_NTSC,
277 .sif = {
278 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
279 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
280 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
281 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
282 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
283 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
284 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
285 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
286 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
287 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
288 {TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
289 {0, 0, 0},
290 },
291 .nosif = {
292 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
293 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
294 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
295 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
296 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
297 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
298 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
299 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
300 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
301 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
302 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
303 {0, 0, 0},
304 },
305 .common = {
306 {TM6010_REQ07_R3F_RESET, 0x01},
307 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
308 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
309 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
310 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
311 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
312 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
313 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
314 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
315 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
316 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
317 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
318 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
319 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
320 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
321 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
322 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
323 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
324 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
325 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
326 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
327
328 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
329 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
330 {TM6010_REQ07_R3F_RESET, 0x00},
331 {0, 0, 0},
332 },
333 },
334};
335
336static struct tm6000_std_settings composite_stds[] = {
337 {
338 .id = V4L2_STD_PAL_M,
339 .common = {
340 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
341 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
342 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
343 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
344 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
345 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
346 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
347 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
348 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
349 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
350 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
351
352 {TM6010_REQ07_R3F_RESET, 0x01},
353 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
354 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
355 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
356 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
357 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
358 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
359 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
360 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
361 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
362 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
363 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
364 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
365 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
366 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
367 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20},
368 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
369 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
370 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
371 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
372 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
373
374 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
375 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
376 {TM6010_REQ07_R3F_RESET, 0x00},
377 {0, 0, 0},
378 },
379 }, {
380 .id = V4L2_STD_PAL_Nc,
381 .common = {
382 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
383 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
384 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
385 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
386 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
387 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
388 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
389 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
390 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
391 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
392 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
393
394 {TM6010_REQ07_R3F_RESET, 0x01},
395 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
396 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
397 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
398 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
399 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
400 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
401 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
402 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
403 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
404 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
405 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
406 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
407 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
408 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
409 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
410 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
411 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
412 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
413 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
414 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
415
416 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
417 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
418 {TM6010_REQ07_R3F_RESET, 0x00},
419 {0, 0, 0},
420 },
421 }, {
422 .id = V4L2_STD_PAL,
423 .common = {
424 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
425 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
426 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
427 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
428 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
429 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
430 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
431 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
432 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
433 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
434 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
435
436 {TM6010_REQ07_R3F_RESET, 0x01},
437 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
438 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
439 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
440 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
441 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
442 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
443 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
444 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
445 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
446 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
447 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
448 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
449 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
450 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
451 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
452 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
453 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
454 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
455 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
456 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
457
458 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
459 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
460 {TM6010_REQ07_R3F_RESET, 0x00},
461 {0, 0, 0},
462 },
463 }, {
464 .id = V4L2_STD_SECAM,
465 .common = {
466 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
467 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
468 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
469 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
470 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
471 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
472 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
473 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
474 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
475 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
476 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
477
478 {TM6010_REQ07_R3F_RESET, 0x01},
479 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
480 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
481 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
482 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
483 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
484 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
485 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
486 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
487 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
488 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
489 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
490 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
491 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
492 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
493 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
494 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
495 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
496 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
497 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
498 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
499
500 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
501 {TM6010_REQ07_R3F_RESET, 0x00},
502 {0, 0, 0},
503 },
504 }, {
505 .id = V4L2_STD_NTSC,
506 .common = {
507 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
508 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
509 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
510 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
511 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
512 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
513 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
514 {TM6010_REQ08_RED_GAIN_SEL, 0xe8},
515 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
516 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
517 {TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
518
519 {TM6010_REQ07_R3F_RESET, 0x01},
520 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
521 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
522 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
523 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
524 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
525 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
526 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
527 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
528 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
529 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
530 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
531 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
532 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
533 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
534 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
535 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
536 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
537 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
538 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
539 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
540
541 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
542 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
543 {TM6010_REQ07_R3F_RESET, 0x00},
544 {0, 0, 0},
545 },
546 },
547};
548
549static struct tm6000_std_settings svideo_stds[] = {
550 {
551 .id = V4L2_STD_PAL_M,
552 .common = {
553 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
554 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
555 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
556 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
557 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
558 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
559 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
560 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
561 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
562 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
563 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
564
565 {TM6010_REQ07_R3F_RESET, 0x01},
566 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05},
567 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
568 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
569 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
570 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
571 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
572 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
573 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
574 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
575 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
576 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
577 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
578 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
579 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
580 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
581 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
582 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
583 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
584 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
585 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
586
587 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
588 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
589 {TM6010_REQ07_R3F_RESET, 0x00},
590 {0, 0, 0},
591 },
592 }, {
593 .id = V4L2_STD_PAL_Nc,
594 .common = {
595 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
596 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
597 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
598 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
599 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
600 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
601 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
602 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
603 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
604 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
605 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
606
607 {TM6010_REQ07_R3F_RESET, 0x01},
608 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37},
609 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
610 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
611 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
612 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
613 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
614 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
615 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
616 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
617 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
618 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
619 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
620 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
621 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
622 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
623 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
624 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
625 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
626 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
627 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
628
629 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
630 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
631 {TM6010_REQ07_R3F_RESET, 0x00},
632 {0, 0, 0},
633 },
634 }, {
635 .id = V4L2_STD_PAL,
636 .common = {
637 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
638 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
639 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
640 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
641 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
642 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
643 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
644 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
645 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
646 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
647 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
648
649 {TM6010_REQ07_R3F_RESET, 0x01},
650 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33},
651 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
652 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
653 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
654 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x00},
655 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
656 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
657 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
658 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
659 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
660 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
661 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
662 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
663 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
664 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a},
665 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
666 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
667 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
668 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
669 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
670
671 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
672 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
673 {TM6010_REQ07_R3F_RESET, 0x00},
674 {0, 0, 0},
675 },
676 }, {
677 .id = V4L2_STD_SECAM,
678 .common = {
679 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
680 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
681 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
682 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
683 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
684 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
685 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
686 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
687 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
688 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
689 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
690
691 {TM6010_REQ07_R3F_RESET, 0x01},
692 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39},
693 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
694 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
695 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
696 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
697 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
698 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
699 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
700 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
701 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
702 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
703 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
704 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
705 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
706 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a},
707 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
708 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
709 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
710 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
711 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
712
713 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
714 {TM6010_REQ07_R3F_RESET, 0x00},
715 {0, 0, 0},
716 },
717 }, {
718 .id = V4L2_STD_NTSC,
719 .common = {
720 {TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
721 {TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
722 {TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
723 {TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
724 {TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
725 {TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
726 {TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
727 {TM6010_REQ08_RED_GAIN_SEL, 0xe0},
728 {TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
729 {TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
730 {TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
731
732 {TM6010_REQ07_R3F_RESET, 0x01},
733 {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01},
734 {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
735 {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
736 {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
737 {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x00},
738 {TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b},
739 {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
740 {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
741 {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
742 {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
743 {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
744 {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
745 {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
746 {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
747 {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
748 {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
749 {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
750 {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
751 {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
752 {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
753 {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
754
755 {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
756 {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
757 {TM6010_REQ07_R3F_RESET, 0x00},
758 {0, 0, 0},
759 },
760 },
761};
762
763void tm6000_get_std_res(struct tm6000_core *dev)
764{
765 /* Currently, those are the only supported resoltions */
766 if (dev->norm & V4L2_STD_525_60) {
767 dev->height = 480;
768 } else {
769 dev->height = 576;
770 }
771 dev->width = 720;
772}
773
774static int tm6000_load_std(struct tm6000_core *dev,
775 struct tm6000_reg_settings *set, int max_size)
776{
777 int i, rc;
778
779 /* Load board's initialization table */
780 for (i = 0; max_size; i++) {
781 if (!set[i].req)
782 return 0;
783
784 if ((dev->dev_type != TM6010) &&
785 (set[i].req == REQ_08_SET_GET_AVREG_BIT))
786 continue;
787
788 rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
789 if (rc < 0) {
790 printk(KERN_ERR "Error %i while setting "
791 "req %d, reg %d to value %d\n",
792 rc, set[i].req, set[i].reg, set[i].value);
793 return rc;
794 }
795 }
796
797 return 0;
798}
799
800static int tm6000_set_tv(struct tm6000_core *dev, int pos)
801{
802 int rc;
803
804 /* FIXME: This code is for tm6010 - not tested yet - doesn't work with
805 tm5600
806 */
807
808 /* FIXME: This is tuner-dependent */
809 int nosif = 0;
810
811 if (nosif) {
812 rc = tm6000_load_std(dev, tv_stds[pos].nosif,
813 sizeof(tv_stds[pos].nosif));
814 } else {
815 rc = tm6000_load_std(dev, tv_stds[pos].sif,
816 sizeof(tv_stds[pos].sif));
817 }
818 if (rc < 0)
819 return rc;
820 rc = tm6000_load_std(dev, tv_stds[pos].common,
821 sizeof(tv_stds[pos].common));
822
823 return rc;
824}
825
826int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm)
827{
828 int i, rc = 0;
829
830 dev->norm = *norm;
831 tm6000_get_std_res(dev);
832
833 switch (dev->input) {
834 case TM6000_INPUT_TV:
835 for (i = 0; i < ARRAY_SIZE(tv_stds); i++) {
836 if (*norm & tv_stds[i].id) {
837 rc = tm6000_set_tv(dev, i);
838 goto ret;
839 }
840 }
841 return -EINVAL;
842 case TM6000_INPUT_SVIDEO:
843 for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
844 if (*norm & svideo_stds[i].id) {
845 rc = tm6000_load_std(dev, svideo_stds[i].common,
846 sizeof(svideo_stds[i].
847 common));
848 goto ret;
849 }
850 }
851 return -EINVAL;
852 case TM6000_INPUT_COMPOSITE:
853 for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
854 if (*norm & composite_stds[i].id) {
855 rc = tm6000_load_std(dev,
856 composite_stds[i].common,
857 sizeof(composite_stds[i].
858 common));
859 goto ret;
860 }
861 }
862 return -EINVAL;
863 }
864
865ret:
866 if (rc < 0)
867 return rc;
868
869 msleep(40);
870
871
872 return 0;
873}
diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
new file mode 100644
index 000000000000..5a5049acd4ec
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
@@ -0,0 +1,53 @@
1/*
2 tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/videodev2.h>
21
22#define TM6000_URB_MSG_LEN 180
23
24struct usb_isoc_ctl {
25 /* max packet size of isoc transaction */
26 int max_pkt_size;
27
28 /* number of allocated urbs */
29 int num_bufs;
30
31 /* urb for isoc transfers */
32 struct urb **urb;
33
34 /* transfer buffers for isoc transfer */
35 char **transfer_buffer;
36
37 /* Last buffer command and region */
38 u8 cmd;
39 int pos, size, pktsize;
40
41 /* Last field: ODD or EVEN? */
42 int field;
43
44 /* Stores incomplete commands */
45 u32 tmp_buf;
46 int tmp_buf_len;
47
48 /* Stores already requested buffers */
49 struct tm6000_buffer *buf;
50
51 /* Stores the number of received fields */
52 int nfields;
53};
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
new file mode 100644
index 000000000000..f2b7fe4a3581
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -0,0 +1,1557 @@
1/*
2 tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
7 - Fixed module load/unload
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation version 2
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/ioport.h>
30#include <linux/init.h>
31#include <linux/sched.h>
32#include <linux/random.h>
33#include <linux/version.h>
34#include <linux/usb.h>
35#include <linux/videodev2.h>
36#include <media/v4l2-ioctl.h>
37#include <linux/interrupt.h>
38#include <linux/kthread.h>
39#include <linux/highmem.h>
40#include <linux/freezer.h>
41
42#include "tm6000-regs.h"
43#include "tm6000.h"
44
45#define BUFFER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
46
47/* Limits minimum and default number of buffers */
48#define TM6000_MIN_BUF 4
49#define TM6000_DEF_BUF 8
50
51#define TM6000_MAX_ISO_PACKETS 40 /* Max number of ISO packets */
52
53/* Declare static vars that will be used as parameters */
54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
55static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
56
57/* Debug level */
58int tm6000_debug;
59
60/* supported controls */
61static struct v4l2_queryctrl tm6000_qctrl[] = {
62 {
63 .id = V4L2_CID_BRIGHTNESS,
64 .type = V4L2_CTRL_TYPE_INTEGER,
65 .name = "Brightness",
66 .minimum = 0,
67 .maximum = 255,
68 .step = 1,
69 .default_value = 54,
70 .flags = 0,
71 }, {
72 .id = V4L2_CID_CONTRAST,
73 .type = V4L2_CTRL_TYPE_INTEGER,
74 .name = "Contrast",
75 .minimum = 0,
76 .maximum = 255,
77 .step = 0x1,
78 .default_value = 119,
79 .flags = 0,
80 }, {
81 .id = V4L2_CID_SATURATION,
82 .type = V4L2_CTRL_TYPE_INTEGER,
83 .name = "Saturation",
84 .minimum = 0,
85 .maximum = 255,
86 .step = 0x1,
87 .default_value = 112,
88 .flags = 0,
89 }, {
90 .id = V4L2_CID_HUE,
91 .type = V4L2_CTRL_TYPE_INTEGER,
92 .name = "Hue",
93 .minimum = -128,
94 .maximum = 127,
95 .step = 0x1,
96 .default_value = 0,
97 .flags = 0,
98 }
99};
100
101static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)];
102
103static struct tm6000_fmt format[] = {
104 {
105 .name = "4:2:2, packed, YVY2",
106 .fourcc = V4L2_PIX_FMT_YUYV,
107 .depth = 16,
108 }, {
109 .name = "4:2:2, packed, UYVY",
110 .fourcc = V4L2_PIX_FMT_UYVY,
111 .depth = 16,
112 }, {
113 .name = "A/V + VBI mux packet",
114 .fourcc = V4L2_PIX_FMT_TM6000,
115 .depth = 16,
116 }
117};
118
119/* ------------------------------------------------------------------
120 DMA and thread functions
121 ------------------------------------------------------------------*/
122
123#define norm_maxw(a) 720
124#define norm_maxh(a) 576
125
126#define norm_minw(a) norm_maxw(a)
127#define norm_minh(a) norm_maxh(a)
128
129/*
130 * video-buf generic routine to get the next available buffer
131 */
132static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
133 struct tm6000_buffer **buf)
134{
135 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
136 char *outp;
137
138 if (list_empty(&dma_q->active)) {
139 dprintk(dev, V4L2_DEBUG_QUEUE, "No active queue to serve\n");
140 *buf = NULL;
141 return;
142 }
143
144 *buf = list_entry(dma_q->active.next,
145 struct tm6000_buffer, vb.queue);
146
147 if (!buf)
148 return;
149
150 /* Cleans up buffer - Usefull for testing for frame/URB loss */
151 outp = videobuf_to_vmalloc(&(*buf)->vb);
152// if (outp)
153// memset(outp, 0, (*buf)->vb.size);
154
155 return;
156}
157
158/*
159 * Announces that a buffer were filled and request the next
160 */
161static inline void buffer_filled(struct tm6000_core *dev,
162 struct tm6000_dmaqueue *dma_q,
163 struct tm6000_buffer *buf)
164{
165 /* Advice that buffer was filled */
166 dprintk(dev, V4L2_DEBUG_ISOC, "[%p/%d] wakeup\n", buf, buf->vb.i);
167 buf->vb.state = VIDEOBUF_DONE;
168 buf->vb.field_count++;
169 do_gettimeofday(&buf->vb.ts);
170
171 list_del(&buf->vb.queue);
172 wake_up(&buf->vb.done);
173}
174
175const char *tm6000_msg_type[] = {
176 "unknown(0)", /* 0 */
177 "video", /* 1 */
178 "audio", /* 2 */
179 "vbi", /* 3 */
180 "pts", /* 4 */
181 "err", /* 5 */
182 "unknown(6)", /* 6 */
183 "unknown(7)", /* 7 */
184};
185
186/*
187 * Identify the tm5600/6000 buffer header type and properly handles
188 */
189static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
190 u8 *out_p, struct tm6000_buffer **buf)
191{
192 struct tm6000_dmaqueue *dma_q = urb->context;
193 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
194 u8 c;
195 unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
196 int rc = 0;
197 /* FIXME: move to tm6000-isoc */
198 static int last_line = -2, start_line = -2, last_field = -2;
199
200 /* FIXME: this is the hardcoded window size
201 */
202 unsigned int linewidth = (*buf)->vb.width << 1;
203
204 if (!dev->isoc_ctl.cmd) {
205 c = (header >> 24) & 0xff;
206
207 /* split the header fields */
208 size = (((header & 0x7e) << 1) -1) *4;
209 block = (header >> 7) & 0xf;
210 field = (header >> 11) & 0x1;
211 line = (header >> 12) & 0x1ff;
212 cmd = (header >> 21) & 0x7;
213
214 /* Validates header fields */
215 if(size > TM6000_URB_MSG_LEN)
216 size = TM6000_URB_MSG_LEN;
217
218 if (cmd == TM6000_URB_MSG_VIDEO) {
219 if ((block+1)*TM6000_URB_MSG_LEN>linewidth)
220 cmd = TM6000_URB_MSG_ERR;
221
222 /* FIXME: Mounts the image as field0+field1
223 * It should, instead, check if the user selected
224 * entrelaced or non-entrelaced mode
225 */
226 pos = ((line << 1) - field - 1) * linewidth +
227 block * TM6000_URB_MSG_LEN;
228
229 /* Don't allow to write out of the buffer */
230 if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) {
231 dprintk(dev, V4L2_DEBUG_ISOC,
232 "ERR: size=%d, num=%d, line=%d, "
233 "field=%d\n",
234 size, block, line, field);
235
236 cmd = TM6000_URB_MSG_ERR;
237 }
238 } else {
239 pos=0;
240 }
241
242 /* Prints debug info */
243 dprintk(dev, V4L2_DEBUG_ISOC, "size=%d, num=%d, "
244 " line=%d, field=%d\n",
245 size, block, line, field);
246
247 if ((last_line!=line)&&(last_line+1!=line) &&
248 (cmd != TM6000_URB_MSG_ERR) ) {
249 if (cmd != TM6000_URB_MSG_VIDEO) {
250 dprintk(dev, V4L2_DEBUG_ISOC, "cmd=%d, "
251 "size=%d, num=%d, line=%d, field=%d\n",
252 cmd, size, block, line, field);
253 }
254 if (start_line<0)
255 start_line=last_line;
256 /* Prints debug info */
257 dprintk(dev, V4L2_DEBUG_ISOC, "lines= %d-%d, "
258 "field=%d\n",
259 start_line, last_line, field);
260
261 if ((start_line<6 && last_line>200) &&
262 (last_field != field) ) {
263
264 dev->isoc_ctl.nfields++;
265 if (dev->isoc_ctl.nfields>=2) {
266 dev->isoc_ctl.nfields=0;
267
268 /* Announces that a new buffer were filled */
269 buffer_filled (dev, dma_q, *buf);
270 dprintk(dev, V4L2_DEBUG_ISOC,
271 "new buffer filled\n");
272 get_next_buf (dma_q, buf);
273 if (!*buf)
274 return rc;
275 out_p = videobuf_to_vmalloc(&((*buf)->vb));
276 if (!out_p)
277 return rc;
278
279 pos = dev->isoc_ctl.pos = 0;
280 }
281 }
282
283 start_line=line;
284 last_field=field;
285 }
286 if (cmd == TM6000_URB_MSG_VIDEO)
287 last_line = line;
288
289 pktsize = TM6000_URB_MSG_LEN;
290 } else {
291 /* Continue the last copy */
292 cmd = dev->isoc_ctl.cmd;
293 size= dev->isoc_ctl.size;
294 pos = dev->isoc_ctl.pos;
295 pktsize = dev->isoc_ctl.pktsize;
296 }
297
298 cpysize = (endp-(*ptr) > size) ? size : endp - *ptr;
299
300 if (cpysize) {
301 /* handles each different URB message */
302 switch(cmd) {
303 case TM6000_URB_MSG_VIDEO:
304 /* Fills video buffer */
305 memcpy(&out_p[pos], *ptr, cpysize);
306 break;
307 case TM6000_URB_MSG_PTS:
308 break;
309 case TM6000_URB_MSG_AUDIO:
310/* Need some code to process audio */
311printk ("%ld: cmd=%s, size=%d\n", jiffies,
312 tm6000_msg_type[cmd],size);
313 break;
314 default:
315 dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
316 tm6000_msg_type[cmd],size);
317 }
318 }
319 if (cpysize<size) {
320 /* End of URB packet, but cmd processing is not
321 * complete. Preserve the state for a next packet
322 */
323 dev->isoc_ctl.pos = pos+cpysize;
324 dev->isoc_ctl.size= size-cpysize;
325 dev->isoc_ctl.cmd = cmd;
326 dev->isoc_ctl.pktsize = pktsize-cpysize;
327 (*ptr)+=cpysize;
328 } else {
329 dev->isoc_ctl.cmd = 0;
330 (*ptr)+=pktsize;
331 }
332
333 return rc;
334}
335
336static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
337 struct urb *urb, struct tm6000_buffer **buf)
338{
339 struct tm6000_dmaqueue *dma_q = urb->context;
340 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
341 u8 *ptr=data, *endp=data+len;
342 unsigned long header=0;
343 int rc=0;
344
345 for (ptr=data; ptr<endp;) {
346 if (!dev->isoc_ctl.cmd) {
347 u8 *p=(u8 *)&dev->isoc_ctl.tmp_buf;
348 /* FIXME: This seems very complex
349 * It just recovers up to 3 bytes of the header that
350 * might be at the previous packet
351 */
352 if (dev->isoc_ctl.tmp_buf_len) {
353 while (dev->isoc_ctl.tmp_buf_len) {
354 if ( *(ptr+3-dev->isoc_ctl.tmp_buf_len) == 0x47) {
355 break;
356 }
357 p++;
358 dev->isoc_ctl.tmp_buf_len--;
359 }
360 if (dev->isoc_ctl.tmp_buf_len) {
361 memcpy(&header, p,
362 dev->isoc_ctl.tmp_buf_len);
363 memcpy((u8 *)&header +
364 dev->isoc_ctl.tmp_buf_len,
365 ptr,
366 4 - dev->isoc_ctl.tmp_buf_len);
367 ptr += 4 - dev->isoc_ctl.tmp_buf_len;
368 goto HEADER;
369 }
370 }
371 /* Seek for sync */
372 for (;ptr<endp-3;ptr++) {
373 if (*(ptr+3)==0x47)
374 break;
375 }
376
377 if (ptr+3>=endp) {
378 dev->isoc_ctl.tmp_buf_len=endp-ptr;
379 memcpy (&dev->isoc_ctl.tmp_buf,ptr,
380 dev->isoc_ctl.tmp_buf_len);
381 dev->isoc_ctl.cmd=0;
382 return rc;
383 }
384
385 /* Get message header */
386 header=*(unsigned long *)ptr;
387 ptr+=4;
388 }
389HEADER:
390 /* Copy or continue last copy */
391 rc=copy_packet(urb,header,&ptr,endp,out_p,buf);
392 if (rc<0) {
393 buf=NULL;
394 printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
395 jiffies);
396 return rc;
397 }
398 if (!*buf)
399 return 0;
400 }
401
402 return 0;
403}
404/*
405 * Identify the tm5600/6000 buffer header type and properly handles
406 */
407static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len,
408 struct urb *urb, struct tm6000_buffer **buf)
409{
410 struct tm6000_dmaqueue *dma_q = urb->context;
411 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
412 unsigned int pos=dev->isoc_ctl.pos,cpysize;
413 int rc=1;
414
415 while (len>0) {
416 cpysize=min(len,(*buf)->vb.size-pos);
417//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
418 memcpy(&out_p[pos], ptr, cpysize);
419 pos+=cpysize;
420 ptr+=cpysize;
421 len-=cpysize;
422 if (pos >= (*buf)->vb.size) {
423 pos=0;
424 /* Announces that a new buffer were filled */
425 buffer_filled (dev, dma_q, *buf);
426 dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
427 get_next_buf (dma_q, buf);
428 if (!*buf)
429 break;
430 out_p = videobuf_to_vmalloc(&((*buf)->vb));
431 if (!out_p)
432 return rc;
433 pos = 0;
434 }
435 }
436
437 dev->isoc_ctl.pos=pos;
438 return rc;
439}
440
441static void inline print_err_status (struct tm6000_core *dev,
442 int packet, int status)
443{
444 char *errmsg = "Unknown";
445
446 switch(status) {
447 case -ENOENT:
448 errmsg = "unlinked synchronuously";
449 break;
450 case -ECONNRESET:
451 errmsg = "unlinked asynchronuously";
452 break;
453 case -ENOSR:
454 errmsg = "Buffer error (overrun)";
455 break;
456 case -EPIPE:
457 errmsg = "Stalled (device not responding)";
458 break;
459 case -EOVERFLOW:
460 errmsg = "Babble (bad cable?)";
461 break;
462 case -EPROTO:
463 errmsg = "Bit-stuff error (bad cable?)";
464 break;
465 case -EILSEQ:
466 errmsg = "CRC/Timeout (could be anything)";
467 break;
468 case -ETIME:
469 errmsg = "Device does not respond";
470 break;
471 }
472 if (packet<0) {
473 dprintk(dev, V4L2_DEBUG_QUEUE, "URB status %d [%s].\n",
474 status, errmsg);
475 } else {
476 dprintk(dev, V4L2_DEBUG_QUEUE, "URB packet %d, status %d [%s].\n",
477 packet, status, errmsg);
478 }
479}
480
481
482/*
483 * Controls the isoc copy of each urb packet
484 */
485static inline int tm6000_isoc_copy(struct urb *urb)
486{
487 struct tm6000_dmaqueue *dma_q = urb->context;
488 struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
489 struct tm6000_buffer *buf;
490 int i, len=0, rc=1;
491 int size;
492 char *outp = NULL, *p;
493 unsigned long copied;
494
495 get_next_buf(dma_q, &buf);
496 if (buf)
497 outp = videobuf_to_vmalloc(&buf->vb);
498
499 if (!outp)
500 return 0;
501
502 size = buf->vb.size;
503
504 copied=0;
505
506 if (urb->status<0) {
507 print_err_status (dev,-1,urb->status);
508 return 0;
509 }
510
511 for (i = 0; i < urb->number_of_packets; i++) {
512 int status = urb->iso_frame_desc[i].status;
513
514 if (status<0) {
515 print_err_status (dev,i,status);
516 continue;
517 }
518
519 len=urb->iso_frame_desc[i].actual_length;
520
521// if (len>=TM6000_URB_MSG_LEN) {
522 p=urb->transfer_buffer + urb->iso_frame_desc[i].offset;
523 if (!urb->iso_frame_desc[i].status) {
524 if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) {
525 rc=copy_multiplexed(p, outp, len, urb, &buf);
526 if (rc<=0)
527 return rc;
528 } else {
529 copy_streams(p, outp, len, urb, &buf);
530 }
531 }
532 copied += len;
533 if (copied >= size || !buf)
534 break;
535// }
536 }
537 return rc;
538}
539
540/* ------------------------------------------------------------------
541 URB control
542 ------------------------------------------------------------------*/
543
544/*
545 * IRQ callback, called by URB callback
546 */
547static void tm6000_irq_callback(struct urb *urb)
548{
549 struct tm6000_dmaqueue *dma_q = urb->context;
550 struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
551 int i;
552
553 if (!dev)
554 return;
555
556 spin_lock(&dev->slock);
557 tm6000_isoc_copy(urb);
558 spin_unlock(&dev->slock);
559
560 /* Reset urb buffers */
561 for (i = 0; i < urb->number_of_packets; i++) {
562 urb->iso_frame_desc[i].status = 0;
563 urb->iso_frame_desc[i].actual_length = 0;
564 }
565
566 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
567 if (urb->status)
568 tm6000_err("urb resubmit failed (error=%i)\n",
569 urb->status);
570}
571
572/*
573 * Stop and Deallocate URBs
574 */
575static void tm6000_uninit_isoc(struct tm6000_core *dev)
576{
577 struct urb *urb;
578 int i;
579
580 dev->isoc_ctl.nfields = -1;
581 dev->isoc_ctl.buf = NULL;
582 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
583 urb=dev->isoc_ctl.urb[i];
584 if (urb) {
585 usb_kill_urb(urb);
586 usb_unlink_urb(urb);
587 if (dev->isoc_ctl.transfer_buffer[i]) {
588 usb_free_coherent(dev->udev,
589 urb->transfer_buffer_length,
590 dev->isoc_ctl.transfer_buffer[i],
591 urb->transfer_dma);
592 }
593 usb_free_urb(urb);
594 dev->isoc_ctl.urb[i] = NULL;
595 }
596 dev->isoc_ctl.transfer_buffer[i] = NULL;
597 }
598
599 kfree (dev->isoc_ctl.urb);
600 kfree (dev->isoc_ctl.transfer_buffer);
601
602 dev->isoc_ctl.urb=NULL;
603 dev->isoc_ctl.transfer_buffer=NULL;
604 dev->isoc_ctl.num_bufs = 0;
605
606 dev->isoc_ctl.num_bufs=0;
607}
608
609/*
610 * Allocate URBs and start IRQ
611 */
612static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
613{
614 struct tm6000_dmaqueue *dma_q = &dev->vidq;
615 int i, j, sb_size, pipe, size, max_packets, num_bufs = 5;
616 struct urb *urb;
617
618 /* De-allocates all pending stuff */
619 tm6000_uninit_isoc(dev);
620
621 usb_set_interface(dev->udev,
622 dev->isoc_in.bInterfaceNumber,
623 dev->isoc_in.bAlternateSetting);
624
625 pipe = usb_rcvisocpipe(dev->udev,
626 dev->isoc_in.endp->desc.bEndpointAddress &
627 USB_ENDPOINT_NUMBER_MASK);
628
629 size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
630
631 if (size > dev->isoc_in.maxsize)
632 size = dev->isoc_in.maxsize;
633
634 dev->isoc_ctl.max_pkt_size = size;
635
636 max_packets = ( framesize + size - 1) / size;
637
638 if (max_packets > TM6000_MAX_ISO_PACKETS)
639 max_packets = TM6000_MAX_ISO_PACKETS;
640
641 sb_size = max_packets * size;
642
643 dev->isoc_ctl.num_bufs = num_bufs;
644
645 dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
646 if (!dev->isoc_ctl.urb) {
647 tm6000_err("cannot alloc memory for usb buffers\n");
648 return -ENOMEM;
649 }
650
651 dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs,
652 GFP_KERNEL);
653 if (!dev->isoc_ctl.transfer_buffer) {
654 tm6000_err("cannot allocate memory for usbtransfer\n");
655 kfree(dev->isoc_ctl.urb);
656 return -ENOMEM;
657 }
658
659 dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets"
660 " (%d bytes) of %d bytes each to handle %u size\n",
661 max_packets, num_bufs, sb_size,
662 dev->isoc_in.maxsize, size);
663
664 /* allocate urbs and transfer buffers */
665 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
666 urb = usb_alloc_urb(max_packets, GFP_KERNEL);
667 if (!urb) {
668 tm6000_err("cannot alloc isoc_ctl.urb %i\n", i);
669 tm6000_uninit_isoc(dev);
670 usb_free_urb(urb);
671 return -ENOMEM;
672 }
673 dev->isoc_ctl.urb[i] = urb;
674
675 dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
676 sb_size, GFP_KERNEL, &urb->transfer_dma);
677 if (!dev->isoc_ctl.transfer_buffer[i]) {
678 tm6000_err ("unable to allocate %i bytes for transfer"
679 " buffer %i%s\n",
680 sb_size, i,
681 in_interrupt()?" while in int":"");
682 tm6000_uninit_isoc(dev);
683 return -ENOMEM;
684 }
685 memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
686
687 usb_fill_bulk_urb(urb, dev->udev, pipe,
688 dev->isoc_ctl.transfer_buffer[i], sb_size,
689 tm6000_irq_callback, dma_q);
690 urb->interval = dev->isoc_in.endp->desc.bInterval;
691 urb->number_of_packets = max_packets;
692 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
693
694 for (j = 0; j < max_packets; j++) {
695 urb->iso_frame_desc[j].offset = size * j;
696 urb->iso_frame_desc[j].length = size;
697 }
698 }
699
700 return 0;
701}
702
703static int tm6000_start_thread( struct tm6000_core *dev)
704{
705 struct tm6000_dmaqueue *dma_q = &dev->vidq;
706 int i;
707
708 dma_q->frame=0;
709 dma_q->ini_jiffies=jiffies;
710
711 init_waitqueue_head(&dma_q->wq);
712
713 /* submit urbs and enables IRQ */
714 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
715 int rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
716 if (rc) {
717 tm6000_err("submit of urb %i failed (error=%i)\n", i,
718 rc);
719 tm6000_uninit_isoc(dev);
720 return rc;
721 }
722 }
723
724 return 0;
725}
726
727/* ------------------------------------------------------------------
728 Videobuf operations
729 ------------------------------------------------------------------*/
730
731static int
732buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
733{
734 struct tm6000_fh *fh = vq->priv_data;
735
736 *size = fh->fmt->depth * fh->width * fh->height >> 3;
737 if (0 == *count)
738 *count = TM6000_DEF_BUF;
739
740 if (*count < TM6000_MIN_BUF) {
741 *count=TM6000_MIN_BUF;
742 }
743
744 while (*size * *count > vid_limit * 1024 * 1024)
745 (*count)--;
746
747 return 0;
748}
749
750static void free_buffer(struct videobuf_queue *vq, struct tm6000_buffer *buf)
751{
752 struct tm6000_fh *fh = vq->priv_data;
753 struct tm6000_core *dev = fh->dev;
754 unsigned long flags;
755
756 if (in_interrupt())
757 BUG();
758
759 /* We used to wait for the buffer to finish here, but this didn't work
760 because, as we were keeping the state as VIDEOBUF_QUEUED,
761 videobuf_queue_cancel marked it as finished for us.
762 (Also, it could wedge forever if the hardware was misconfigured.)
763
764 This should be safe; by the time we get here, the buffer isn't
765 queued anymore. If we ever start marking the buffers as
766 VIDEOBUF_ACTIVE, it won't be, though.
767 */
768 spin_lock_irqsave(&dev->slock, flags);
769 if (dev->isoc_ctl.buf == buf)
770 dev->isoc_ctl.buf = NULL;
771 spin_unlock_irqrestore(&dev->slock, flags);
772
773 videobuf_vmalloc_free(&buf->vb);
774 buf->vb.state = VIDEOBUF_NEEDS_INIT;
775}
776
777static int
778buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
779 enum v4l2_field field)
780{
781 struct tm6000_fh *fh = vq->priv_data;
782 struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb);
783 struct tm6000_core *dev = fh->dev;
784 int rc = 0, urb_init = 0;
785
786 BUG_ON(NULL == fh->fmt);
787
788
789 /* FIXME: It assumes depth=2 */
790 /* The only currently supported format is 16 bits/pixel */
791 buf->vb.size = fh->fmt->depth*fh->width*fh->height >> 3;
792 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
793 return -EINVAL;
794
795 if (buf->fmt != fh->fmt ||
796 buf->vb.width != fh->width ||
797 buf->vb.height != fh->height ||
798 buf->vb.field != field) {
799 buf->fmt = fh->fmt;
800 buf->vb.width = fh->width;
801 buf->vb.height = fh->height;
802 buf->vb.field = field;
803 buf->vb.state = VIDEOBUF_NEEDS_INIT;
804 }
805
806 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
807 if (0 != (rc = videobuf_iolock(vq, &buf->vb, NULL)))
808 goto fail;
809 urb_init = 1;
810 }
811
812 if (!dev->isoc_ctl.num_bufs)
813 urb_init = 1;
814
815 if (urb_init) {
816 rc = tm6000_prepare_isoc(dev, buf->vb.size);
817 if (rc < 0)
818 goto fail;
819
820 rc = tm6000_start_thread(dev);
821 if (rc < 0)
822 goto fail;
823
824 }
825
826 buf->vb.state = VIDEOBUF_PREPARED;
827 return 0;
828
829fail:
830 free_buffer(vq, buf);
831 return rc;
832}
833
834static void
835buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
836{
837 struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb);
838 struct tm6000_fh *fh = vq->priv_data;
839 struct tm6000_core *dev = fh->dev;
840 struct tm6000_dmaqueue *vidq = &dev->vidq;
841
842 buf->vb.state = VIDEOBUF_QUEUED;
843 list_add_tail(&buf->vb.queue, &vidq->active);
844}
845
846static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb)
847{
848 struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb);
849
850 free_buffer(vq,buf);
851}
852
853static struct videobuf_queue_ops tm6000_video_qops = {
854 .buf_setup = buffer_setup,
855 .buf_prepare = buffer_prepare,
856 .buf_queue = buffer_queue,
857 .buf_release = buffer_release,
858};
859
860/* ------------------------------------------------------------------
861 IOCTL handling
862 ------------------------------------------------------------------*/
863
864static int res_get(struct tm6000_core *dev, struct tm6000_fh *fh)
865{
866 /* is it free? */
867 mutex_lock(&dev->lock);
868 if (dev->resources) {
869 /* no, someone else uses it */
870 mutex_unlock(&dev->lock);
871 return 0;
872 }
873 /* it's free, grab it */
874 dev->resources =1;
875 dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n");
876 mutex_unlock(&dev->lock);
877 return 1;
878}
879
880static int res_locked(struct tm6000_core *dev)
881{
882 return (dev->resources);
883}
884
885static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh)
886{
887 mutex_lock(&dev->lock);
888 dev->resources = 0;
889 dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n");
890 mutex_unlock(&dev->lock);
891}
892
893/* ------------------------------------------------------------------
894 IOCTL vidioc handling
895 ------------------------------------------------------------------*/
896static int vidioc_querycap (struct file *file, void *priv,
897 struct v4l2_capability *cap)
898{
899 // struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
900
901 strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
902 strlcpy(cap->card,"Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
903 // strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info));
904 cap->version = TM6000_VERSION;
905 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
906 V4L2_CAP_STREAMING |
907 V4L2_CAP_TUNER |
908 V4L2_CAP_READWRITE;
909 return 0;
910}
911
912static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
913 struct v4l2_fmtdesc *f)
914{
915 if (unlikely(f->index >= ARRAY_SIZE(format)))
916 return -EINVAL;
917
918 strlcpy(f->description,format[f->index].name,sizeof(f->description));
919 f->pixelformat = format[f->index].fourcc;
920 return 0;
921}
922
923static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
924 struct v4l2_format *f)
925{
926 struct tm6000_fh *fh=priv;
927
928 f->fmt.pix.width = fh->width;
929 f->fmt.pix.height = fh->height;
930 f->fmt.pix.field = fh->vb_vidq.field;
931 f->fmt.pix.pixelformat = fh->fmt->fourcc;
932 f->fmt.pix.bytesperline =
933 (f->fmt.pix.width * fh->fmt->depth) >> 3;
934 f->fmt.pix.sizeimage =
935 f->fmt.pix.height * f->fmt.pix.bytesperline;
936
937 return (0);
938}
939
940static struct tm6000_fmt* format_by_fourcc(unsigned int fourcc)
941{
942 unsigned int i;
943
944 for (i = 0; i < ARRAY_SIZE(format); i++)
945 if (format[i].fourcc == fourcc)
946 return format+i;
947 return NULL;
948}
949
950static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
951 struct v4l2_format *f)
952{
953 struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
954 struct tm6000_fmt *fmt;
955 enum v4l2_field field;
956
957 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
958 if (NULL == fmt) {
959 dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Fourcc format (0x%08x)"
960 " invalid.\n", f->fmt.pix.pixelformat);
961 return -EINVAL;
962 }
963
964 field = f->fmt.pix.field;
965
966 if (field == V4L2_FIELD_ANY) {
967// field=V4L2_FIELD_INTERLACED;
968 field=V4L2_FIELD_SEQ_TB;
969 } else if (V4L2_FIELD_INTERLACED != field) {
970 dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Field type invalid.\n");
971 return -EINVAL;
972 }
973
974 tm6000_get_std_res (dev);
975
976 f->fmt.pix.width = dev->width;
977 f->fmt.pix.height = dev->height;
978
979 f->fmt.pix.width &= ~0x01;
980
981 f->fmt.pix.field = field;
982
983 f->fmt.pix.bytesperline =
984 (f->fmt.pix.width * fmt->depth) >> 3;
985 f->fmt.pix.sizeimage =
986 f->fmt.pix.height * f->fmt.pix.bytesperline;
987
988 return 0;
989}
990
991/*FIXME: This seems to be generic enough to be at videodev2 */
992static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
993 struct v4l2_format *f)
994{
995 struct tm6000_fh *fh=priv;
996 struct tm6000_core *dev = fh->dev;
997 int ret = vidioc_try_fmt_vid_cap(file,fh,f);
998 if (ret < 0)
999 return (ret);
1000
1001 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1002 fh->width = f->fmt.pix.width;
1003 fh->height = f->fmt.pix.height;
1004 fh->vb_vidq.field = f->fmt.pix.field;
1005 fh->type = f->type;
1006
1007 dev->fourcc = f->fmt.pix.pixelformat;
1008
1009 tm6000_set_fourcc_format(dev);
1010
1011 return (0);
1012}
1013
1014static int vidioc_reqbufs (struct file *file, void *priv,
1015 struct v4l2_requestbuffers *p)
1016{
1017 struct tm6000_fh *fh=priv;
1018
1019 return (videobuf_reqbufs(&fh->vb_vidq, p));
1020}
1021
1022static int vidioc_querybuf (struct file *file, void *priv,
1023 struct v4l2_buffer *p)
1024{
1025 struct tm6000_fh *fh=priv;
1026
1027 return (videobuf_querybuf(&fh->vb_vidq, p));
1028}
1029
1030static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
1031{
1032 struct tm6000_fh *fh=priv;
1033
1034 return (videobuf_qbuf(&fh->vb_vidq, p));
1035}
1036
1037static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
1038{
1039 struct tm6000_fh *fh=priv;
1040
1041 return (videobuf_dqbuf(&fh->vb_vidq, p,
1042 file->f_flags & O_NONBLOCK));
1043}
1044
1045#ifdef CONFIG_VIDEO_V4L1_COMPAT
1046static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
1047{
1048 struct tm6000_fh *fh=priv;
1049
1050 return videobuf_cgmbuf (&fh->vb_vidq, mbuf, 8);
1051}
1052#endif
1053
1054static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1055{
1056 struct tm6000_fh *fh=priv;
1057 struct tm6000_core *dev = fh->dev;
1058
1059 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1060 return -EINVAL;
1061 if (i != fh->type)
1062 return -EINVAL;
1063
1064 if (!res_get(dev,fh))
1065 return -EBUSY;
1066 return (videobuf_streamon(&fh->vb_vidq));
1067}
1068
1069static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1070{
1071 struct tm6000_fh *fh=priv;
1072 struct tm6000_core *dev = fh->dev;
1073
1074 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1075 return -EINVAL;
1076 if (i != fh->type)
1077 return -EINVAL;
1078
1079 videobuf_streamoff(&fh->vb_vidq);
1080 res_free(dev,fh);
1081
1082 return (0);
1083}
1084
1085static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
1086{
1087 int rc=0;
1088 struct tm6000_fh *fh=priv;
1089 struct tm6000_core *dev = fh->dev;
1090
1091 rc=tm6000_set_standard (dev, norm);
1092
1093 fh->width = dev->width;
1094 fh->height = dev->height;
1095
1096 if (rc<0)
1097 return rc;
1098
1099 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
1100
1101 return 0;
1102}
1103
1104static int vidioc_enum_input (struct file *file, void *priv,
1105 struct v4l2_input *inp)
1106{
1107 switch (inp->index) {
1108 case TM6000_INPUT_TV:
1109 inp->type = V4L2_INPUT_TYPE_TUNER;
1110 strcpy(inp->name,"Television");
1111 break;
1112 case TM6000_INPUT_COMPOSITE:
1113 inp->type = V4L2_INPUT_TYPE_CAMERA;
1114 strcpy(inp->name,"Composite");
1115 break;
1116 case TM6000_INPUT_SVIDEO:
1117 inp->type = V4L2_INPUT_TYPE_CAMERA;
1118 strcpy(inp->name,"S-Video");
1119 break;
1120 default:
1121 return -EINVAL;
1122 }
1123 inp->std = TM6000_STD;
1124
1125 return 0;
1126}
1127
1128static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
1129{
1130 struct tm6000_fh *fh=priv;
1131 struct tm6000_core *dev = fh->dev;
1132
1133 *i=dev->input;
1134
1135 return 0;
1136}
1137static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
1138{
1139 struct tm6000_fh *fh=priv;
1140 struct tm6000_core *dev = fh->dev;
1141 int rc=0;
1142 char buf[1];
1143
1144 switch (i) {
1145 case TM6000_INPUT_TV:
1146 dev->input=i;
1147 *buf=0;
1148 break;
1149 case TM6000_INPUT_COMPOSITE:
1150 case TM6000_INPUT_SVIDEO:
1151 dev->input=i;
1152 *buf=1;
1153 break;
1154 default:
1155 return -EINVAL;
1156 }
1157 rc=tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
1158 REQ_03_SET_GET_MCU_PIN, 0x03, 1, buf, 1);
1159
1160 if (!rc) {
1161 dev->input=i;
1162 rc=vidioc_s_std (file, priv, &dev->vfd->current_norm);
1163 }
1164
1165 return (rc);
1166}
1167
1168 /* --- controls ---------------------------------------------- */
1169static int vidioc_queryctrl (struct file *file, void *priv,
1170 struct v4l2_queryctrl *qc)
1171{
1172 int i;
1173
1174 for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++)
1175 if (qc->id && qc->id == tm6000_qctrl[i].id) {
1176 memcpy(qc, &(tm6000_qctrl[i]),
1177 sizeof(*qc));
1178 return (0);
1179 }
1180
1181 return -EINVAL;
1182}
1183
1184static int vidioc_g_ctrl (struct file *file, void *priv,
1185 struct v4l2_control *ctrl)
1186{
1187 struct tm6000_fh *fh=priv;
1188 struct tm6000_core *dev = fh->dev;
1189 int val;
1190
1191 /* FIXME: Probably, those won't work! Maybe we need shadow regs */
1192 switch (ctrl->id) {
1193 case V4L2_CID_CONTRAST:
1194 val = tm6000_get_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0);
1195 break;
1196 case V4L2_CID_BRIGHTNESS:
1197 val = tm6000_get_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0);
1198 return 0;
1199 case V4L2_CID_SATURATION:
1200 val = tm6000_get_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0);
1201 return 0;
1202 case V4L2_CID_HUE:
1203 val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0);
1204 return 0;
1205 default:
1206 return -EINVAL;
1207 }
1208
1209 if (val<0)
1210 return val;
1211
1212 ctrl->value=val;
1213
1214 return 0;
1215}
1216static int vidioc_s_ctrl (struct file *file, void *priv,
1217 struct v4l2_control *ctrl)
1218{
1219 struct tm6000_fh *fh =priv;
1220 struct tm6000_core *dev = fh->dev;
1221 u8 val=ctrl->value;
1222
1223 switch (ctrl->id) {
1224 case V4L2_CID_CONTRAST:
1225 tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val);
1226 return 0;
1227 case V4L2_CID_BRIGHTNESS:
1228 tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val);
1229 return 0;
1230 case V4L2_CID_SATURATION:
1231 tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val);
1232 return 0;
1233 case V4L2_CID_HUE:
1234 tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val);
1235 return 0;
1236 }
1237 return -EINVAL;
1238}
1239
1240static int vidioc_g_tuner (struct file *file, void *priv,
1241 struct v4l2_tuner *t)
1242{
1243 struct tm6000_fh *fh =priv;
1244 struct tm6000_core *dev = fh->dev;
1245
1246 if (unlikely(UNSET == dev->tuner_type))
1247 return -EINVAL;
1248 if (0 != t->index)
1249 return -EINVAL;
1250
1251 strcpy(t->name, "Television");
1252 t->type = V4L2_TUNER_ANALOG_TV;
1253 t->capability = V4L2_TUNER_CAP_NORM;
1254 t->rangehigh = 0xffffffffUL;
1255 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1256
1257 return 0;
1258}
1259
1260static int vidioc_s_tuner (struct file *file, void *priv,
1261 struct v4l2_tuner *t)
1262{
1263 struct tm6000_fh *fh =priv;
1264 struct tm6000_core *dev = fh->dev;
1265
1266 if (UNSET == dev->tuner_type)
1267 return -EINVAL;
1268 if (0 != t->index)
1269 return -EINVAL;
1270
1271 return 0;
1272}
1273
1274static int vidioc_g_frequency (struct file *file, void *priv,
1275 struct v4l2_frequency *f)
1276{
1277 struct tm6000_fh *fh =priv;
1278 struct tm6000_core *dev = fh->dev;
1279
1280 if (unlikely(UNSET == dev->tuner_type))
1281 return -EINVAL;
1282
1283 f->type = V4L2_TUNER_ANALOG_TV;
1284 f->frequency = dev->freq;
1285
1286 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f);
1287
1288 return 0;
1289}
1290
1291static int vidioc_s_frequency (struct file *file, void *priv,
1292 struct v4l2_frequency *f)
1293{
1294 struct tm6000_fh *fh =priv;
1295 struct tm6000_core *dev = fh->dev;
1296
1297 if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
1298 return -EINVAL;
1299
1300 if (unlikely(UNSET == dev->tuner_type))
1301 return -EINVAL;
1302 if (unlikely(f->tuner != 0))
1303 return -EINVAL;
1304
1305// mutex_lock(&dev->lock);
1306 dev->freq = f->frequency;
1307 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
1308// mutex_unlock(&dev->lock);
1309
1310 return 0;
1311}
1312
1313/* ------------------------------------------------------------------
1314 File operations for the device
1315 ------------------------------------------------------------------*/
1316
1317static int tm6000_open(struct file *file)
1318{
1319 struct video_device *vdev = video_devdata(file);
1320 struct tm6000_core *dev = video_drvdata(file);
1321 struct tm6000_fh *fh;
1322 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1323 int i,rc;
1324
1325 printk(KERN_INFO "tm6000: open called (dev=%s)\n",
1326 video_device_node_name(vdev));
1327
1328 dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n",
1329 video_device_node_name(vdev));
1330
1331
1332 /* If more than one user, mutex should be added */
1333 dev->users++;
1334
1335 dprintk(dev, V4L2_DEBUG_OPEN, "open dev=%s type=%s users=%d\n",
1336 video_device_node_name(vdev), v4l2_type_names[type],
1337 dev->users);
1338
1339 /* allocate + initialize per filehandle data */
1340 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1341 if (NULL == fh) {
1342 dev->users--;
1343 return -ENOMEM;
1344 }
1345
1346 file->private_data = fh;
1347 fh->dev = dev;
1348
1349 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1350 dev->fourcc = format[0].fourcc;
1351
1352 fh->fmt = format_by_fourcc(dev->fourcc);
1353
1354 tm6000_get_std_res (dev);
1355
1356 fh->width = dev->width;
1357 fh->height = dev->height;
1358
1359 dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, "
1360 "dev->vidq=0x%08lx\n",
1361 (unsigned long)fh,(unsigned long)dev,(unsigned long)&dev->vidq);
1362 dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
1363 "queued=%d\n",list_empty(&dev->vidq.queued));
1364 dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty "
1365 "active=%d\n",list_empty(&dev->vidq.active));
1366
1367 /* initialize hardware on analog mode */
1368 if (dev->mode!=TM6000_MODE_ANALOG) {
1369 rc=tm6000_init_analog_mode (dev);
1370 if (rc<0)
1371 return rc;
1372
1373 /* Put all controls at a sane state */
1374 for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++)
1375 qctl_regs[i] =tm6000_qctrl[i].default_value;
1376
1377 dev->mode=TM6000_MODE_ANALOG;
1378 }
1379
1380 videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops,
1381 NULL, &dev->slock,
1382 fh->type,
1383 V4L2_FIELD_INTERLACED,
1384 sizeof(struct tm6000_buffer),fh);
1385
1386 return 0;
1387}
1388
1389static ssize_t
1390tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
1391{
1392 struct tm6000_fh *fh = file->private_data;
1393
1394 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1395 if (res_locked(fh->dev))
1396 return -EBUSY;
1397
1398 return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
1399 file->f_flags & O_NONBLOCK);
1400 }
1401 return 0;
1402}
1403
1404static unsigned int
1405tm6000_poll(struct file *file, struct poll_table_struct *wait)
1406{
1407 struct tm6000_fh *fh = file->private_data;
1408 struct tm6000_buffer *buf;
1409
1410 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1411 return POLLERR;
1412
1413 if (res_get(fh->dev,fh)) {
1414 /* streaming capture */
1415 if (list_empty(&fh->vb_vidq.stream))
1416 return POLLERR;
1417 buf = list_entry(fh->vb_vidq.stream.next,struct tm6000_buffer,vb.stream);
1418 } else {
1419 /* read() capture */
1420 return videobuf_poll_stream(file, &fh->vb_vidq,
1421 wait);
1422 }
1423 poll_wait(file, &buf->vb.done, wait);
1424 if (buf->vb.state == VIDEOBUF_DONE ||
1425 buf->vb.state == VIDEOBUF_ERROR)
1426 return POLLIN|POLLRDNORM;
1427 return 0;
1428}
1429
1430static int tm6000_release(struct file *file)
1431{
1432 struct tm6000_fh *fh = file->private_data;
1433 struct tm6000_core *dev = fh->dev;
1434 struct video_device *vdev = video_devdata(file);
1435
1436 dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: close called (dev=%s, users=%d)\n",
1437 video_device_node_name(vdev), dev->users);
1438
1439 dev->users--;
1440
1441 if (!dev->users) {
1442 tm6000_uninit_isoc(dev);
1443 videobuf_mmap_free(&fh->vb_vidq);
1444 }
1445
1446 kfree (fh);
1447
1448 return 0;
1449}
1450
1451static int tm6000_mmap(struct file *file, struct vm_area_struct * vma)
1452{
1453 struct tm6000_fh *fh = file->private_data;
1454 int ret;
1455
1456 ret=videobuf_mmap_mapper(&fh->vb_vidq, vma);
1457
1458 return ret;
1459}
1460
1461static struct v4l2_file_operations tm6000_fops = {
1462 .owner = THIS_MODULE,
1463 .open = tm6000_open,
1464 .release = tm6000_release,
1465 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
1466 .read = tm6000_read,
1467 .poll = tm6000_poll,
1468 .mmap = tm6000_mmap,
1469};
1470
1471static const struct v4l2_ioctl_ops video_ioctl_ops = {
1472 .vidioc_querycap = vidioc_querycap,
1473 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1474 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1475 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1476 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1477 .vidioc_s_std = vidioc_s_std,
1478 .vidioc_enum_input = vidioc_enum_input,
1479 .vidioc_g_input = vidioc_g_input,
1480 .vidioc_s_input = vidioc_s_input,
1481 .vidioc_queryctrl = vidioc_queryctrl,
1482 .vidioc_g_ctrl = vidioc_g_ctrl,
1483 .vidioc_s_ctrl = vidioc_s_ctrl,
1484 .vidioc_g_tuner = vidioc_g_tuner,
1485 .vidioc_s_tuner = vidioc_s_tuner,
1486 .vidioc_g_frequency = vidioc_g_frequency,
1487 .vidioc_s_frequency = vidioc_s_frequency,
1488 .vidioc_streamon = vidioc_streamon,
1489 .vidioc_streamoff = vidioc_streamoff,
1490 .vidioc_reqbufs = vidioc_reqbufs,
1491 .vidioc_querybuf = vidioc_querybuf,
1492 .vidioc_qbuf = vidioc_qbuf,
1493 .vidioc_dqbuf = vidioc_dqbuf,
1494#ifdef CONFIG_VIDEO_V4L1_COMPAT
1495 .vidiocgmbuf = vidiocgmbuf,
1496#endif
1497};
1498
1499static struct video_device tm6000_template = {
1500 .name = "tm6000",
1501 .fops = &tm6000_fops,
1502 .ioctl_ops = &video_ioctl_ops,
1503 .release = video_device_release,
1504 .tvnorms = TM6000_STD,
1505 .current_norm = V4L2_STD_NTSC_M,
1506};
1507
1508/* -----------------------------------------------------------------
1509 Initialization and module stuff
1510 ------------------------------------------------------------------*/
1511
1512int tm6000_v4l2_register(struct tm6000_core *dev)
1513{
1514 int ret = -1;
1515 struct video_device *vfd;
1516
1517 vfd = video_device_alloc();
1518 if(!vfd) {
1519 return -ENOMEM;
1520 }
1521 dev->vfd = vfd;
1522
1523 /* init video dma queues */
1524 INIT_LIST_HEAD(&dev->vidq.active);
1525 INIT_LIST_HEAD(&dev->vidq.queued);
1526
1527 memcpy (dev->vfd, &tm6000_template, sizeof(*(dev->vfd)));
1528 dev->vfd->debug=tm6000_debug;
1529 vfd->v4l2_dev = &dev->v4l2_dev;
1530 video_set_drvdata(vfd, dev);
1531
1532 ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr);
1533 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
1534 return ret;
1535}
1536
1537int tm6000_v4l2_unregister(struct tm6000_core *dev)
1538{
1539 video_unregister_device(dev->vfd);
1540
1541 return 0;
1542}
1543
1544int tm6000_v4l2_exit(void)
1545{
1546 return 0;
1547}
1548
1549module_param(video_nr, int, 0);
1550MODULE_PARM_DESC(video_nr,"Allow changing video device number");
1551
1552module_param_named (debug, tm6000_debug, int, 0444);
1553MODULE_PARM_DESC(debug,"activates debug info");
1554
1555module_param(vid_limit,int,0644);
1556MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
1557
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
new file mode 100644
index 000000000000..6812d6867d57
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000.h
@@ -0,0 +1,301 @@
1/*
2 tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices
3
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
7 - DVB-T support
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation version 2
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23// Use the tm6000-hack, instead of the proper initialization code
24//#define HACK 1
25
26#include <linux/videodev2.h>
27#include <media/v4l2-common.h>
28#include <media/videobuf-vmalloc.h>
29#include "tm6000-usb-isoc.h"
30#include <linux/i2c.h>
31#include <linux/mutex.h>
32#include <media/v4l2-device.h>
33
34
35#include <linux/dvb/frontend.h>
36#include "dvb_demux.h"
37#include "dvb_frontend.h"
38#include "dmxdev.h"
39
40#define TM6000_VERSION KERNEL_VERSION(0, 0, 2)
41
42/* Inputs */
43
44enum tm6000_itype {
45 TM6000_INPUT_TV = 0,
46 TM6000_INPUT_COMPOSITE,
47 TM6000_INPUT_SVIDEO,
48};
49
50enum tm6000_devtype {
51 TM6000 = 0,
52 TM5600,
53 TM6010,
54};
55
56/* ------------------------------------------------------------------
57 Basic structures
58 ------------------------------------------------------------------*/
59
60struct tm6000_fmt {
61 char *name;
62 u32 fourcc; /* v4l2 format id */
63 int depth;
64};
65
66/* buffer for one video frame */
67struct tm6000_buffer {
68 /* common v4l buffer stuff -- must be first */
69 struct videobuf_buffer vb;
70
71 struct tm6000_fmt *fmt;
72};
73
74struct tm6000_dmaqueue {
75 struct list_head active;
76 struct list_head queued;
77
78 /* thread for generating video stream*/
79 struct task_struct *kthread;
80 wait_queue_head_t wq;
81 /* Counters to control fps rate */
82 int frame;
83 int ini_jiffies;
84};
85
86/* device states */
87enum tm6000_core_state {
88 DEV_INITIALIZED = 0x01,
89 DEV_DISCONNECTED = 0x02,
90 DEV_MISCONFIGURED = 0x04,
91};
92
93/* io methods */
94enum tm6000_io_method {
95 IO_NONE,
96 IO_READ,
97 IO_MMAP,
98};
99
100enum tm6000_mode {
101 TM6000_MODE_UNKNOWN=0,
102 TM6000_MODE_ANALOG,
103 TM6000_MODE_DIGITAL,
104};
105
106struct tm6000_gpio {
107 int tuner_reset;
108 int tuner_on;
109 int demod_reset;
110 int demod_on;
111 int power_led;
112 int dvb_led;
113 int ir;
114};
115
116struct tm6000_capabilities {
117 unsigned int has_tuner:1;
118 unsigned int has_tda9874:1;
119 unsigned int has_dvb:1;
120 unsigned int has_zl10353:1;
121 unsigned int has_eeprom:1;
122 unsigned int has_remote:1;
123};
124
125struct tm6000_dvb {
126 struct dvb_adapter adapter;
127 struct dvb_demux demux;
128 struct dvb_frontend *frontend;
129 struct dmxdev dmxdev;
130 unsigned int streams;
131 struct urb *bulk_urb;
132 struct mutex mutex;
133};
134
135struct tm6000_endpoint {
136 struct usb_host_endpoint *endp;
137 __u8 bInterfaceNumber;
138 __u8 bAlternateSetting;
139 unsigned maxsize;
140};
141
142struct tm6000_core {
143 /* generic device properties */
144 char name[30]; /* name (including minor) of the device */
145 int model; /* index in the device_data struct */
146 int devno; /* marks the number of this device */
147 enum tm6000_devtype dev_type; /* type of device */
148
149 v4l2_std_id norm; /* Current norm */
150 int width,height; /* Selected resolution */
151
152 enum tm6000_core_state state;
153
154 /* Device Capabilities*/
155 struct tm6000_capabilities caps;
156
157 /* Tuner configuration */
158 int tuner_type; /* type of the tuner */
159 int tuner_addr; /* tuner address */
160
161 struct tm6000_gpio gpio;
162
163 /* Demodulator configuration */
164 int demod_addr; /* demodulator address */
165
166 int audio_bitrate;
167 /* i2c i/o */
168 struct i2c_adapter i2c_adap;
169 struct i2c_client i2c_client;
170
171 /* video for linux */
172 int users;
173
174 /* various device info */
175 unsigned int resources;
176 struct video_device *vfd;
177 struct tm6000_dmaqueue vidq;
178 struct v4l2_device v4l2_dev;
179
180 int input;
181 int freq;
182 unsigned int fourcc;
183
184 enum tm6000_mode mode;
185
186 /* DVB-T support */
187 struct tm6000_dvb *dvb;
188
189 /* locks */
190 struct mutex lock;
191
192 /* usb transfer */
193 struct usb_device *udev; /* the usb device */
194
195 struct tm6000_endpoint bulk_in, bulk_out, isoc_in, isoc_out;
196
197 /* scaler!=0 if scaler is active*/
198 int scaler;
199
200 /* Isoc control struct */
201 struct usb_isoc_ctl isoc_ctl;
202
203 spinlock_t slock;
204};
205
206struct tm6000_fh {
207 struct tm6000_core *dev;
208
209 /* video capture */
210 struct tm6000_fmt *fmt;
211 unsigned int width,height;
212 struct videobuf_queue vb_vidq;
213
214 enum v4l2_buf_type type;
215};
216
217#define TM6000_STD V4L2_STD_PAL|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc| \
218 V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
219 V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
220
221/* In tm6000-cards.c */
222
223int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
224int tm6000_xc5000_callback (void *ptr, int component, int command, int arg);
225int tm6000_cards_setup(struct tm6000_core *dev);
226
227/* In tm6000-core.c */
228
229int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
230 u16 value, u16 index, u8 *buf, u16 len);
231int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
232int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
233int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
234int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
235int tm6000_init (struct tm6000_core *dev);
236
237int tm6000_init_analog_mode (struct tm6000_core *dev);
238int tm6000_init_digital_mode (struct tm6000_core *dev);
239int tm6000_set_audio_bitrate (struct tm6000_core *dev, int bitrate);
240
241int tm6000_dvb_register(struct tm6000_core *dev);
242void tm6000_dvb_unregister(struct tm6000_core *dev);
243
244int tm6000_v4l2_register(struct tm6000_core *dev);
245int tm6000_v4l2_unregister(struct tm6000_core *dev);
246int tm6000_v4l2_exit(void);
247void tm6000_set_fourcc_format(struct tm6000_core *dev);
248
249/* In tm6000-stds.c */
250void tm6000_get_std_res(struct tm6000_core *dev);
251int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
252
253/* In tm6000-i2c.c */
254int tm6000_i2c_register(struct tm6000_core *dev);
255int tm6000_i2c_unregister(struct tm6000_core *dev);
256
257/* In tm6000-queue.c */
258
259int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
260
261int tm6000_vidioc_streamon(struct file *file, void *priv,
262 enum v4l2_buf_type i);
263int tm6000_vidioc_streamoff(struct file *file, void *priv,
264 enum v4l2_buf_type i);
265int tm6000_vidioc_reqbufs (struct file *file, void *priv,
266 struct v4l2_requestbuffers *rb);
267int tm6000_vidioc_querybuf (struct file *file, void *priv,
268 struct v4l2_buffer *b);
269int tm6000_vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *b);
270int tm6000_vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *b);
271ssize_t tm6000_v4l2_read(struct file *filp, char __user * buf, size_t count,
272 loff_t * f_pos);
273unsigned int tm6000_v4l2_poll(struct file *file,
274 struct poll_table_struct *wait);
275int tm6000_queue_init(struct tm6000_core *dev);
276
277/* In tm6000-alsa.c */
278int tm6000_audio_init(struct tm6000_core *dev, int idx);
279
280
281/* Debug stuff */
282
283extern int tm6000_debug;
284
285#define dprintk(dev, level, fmt, arg...) do {\
286 if (tm6000_debug & level) \
287 printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \
288 dev->name, __FUNCTION__ , ##arg); } while (0)
289
290#define V4L2_DEBUG_REG 0x0004
291#define V4L2_DEBUG_I2C 0x0008
292#define V4L2_DEBUG_QUEUE 0x0010
293#define V4L2_DEBUG_ISOC 0x0020
294#define V4L2_DEBUG_RES_LOCK 0x0040 /* Resource locking */
295#define V4L2_DEBUG_OPEN 0x0080 /* video open/close debug */
296
297#define tm6000_err(fmt, arg...) do {\
298 printk(KERN_ERR "tm6000 %s :"fmt, \
299 __FUNCTION__ , ##arg); } while (0)
300
301
diff --git a/include/linux/meye.h b/include/linux/meye.h
index 12010ace1f04..0dd49954f746 100644
--- a/include/linux/meye.h
+++ b/include/linux/meye.h
@@ -44,17 +44,17 @@ struct meye_params {
44}; 44};
45 45
46/* query the extended parameters */ 46/* query the extended parameters */
47#define MEYEIOC_G_PARAMS _IOR ('v', BASE_VIDIOCPRIVATE+0, struct meye_params) 47#define MEYEIOC_G_PARAMS _IOR ('v', BASE_VIDIOC_PRIVATE+0, struct meye_params)
48/* set the extended parameters */ 48/* set the extended parameters */
49#define MEYEIOC_S_PARAMS _IOW ('v', BASE_VIDIOCPRIVATE+1, struct meye_params) 49#define MEYEIOC_S_PARAMS _IOW ('v', BASE_VIDIOC_PRIVATE+1, struct meye_params)
50/* queue a buffer for mjpeg capture */ 50/* queue a buffer for mjpeg capture */
51#define MEYEIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOCPRIVATE+2, int) 51#define MEYEIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOC_PRIVATE+2, int)
52/* sync a previously queued mjpeg buffer */ 52/* sync a previously queued mjpeg buffer */
53#define MEYEIOC_SYNC _IOWR('v', BASE_VIDIOCPRIVATE+3, int) 53#define MEYEIOC_SYNC _IOWR('v', BASE_VIDIOC_PRIVATE+3, int)
54/* get a still uncompressed snapshot */ 54/* get a still uncompressed snapshot */
55#define MEYEIOC_STILLCAPT _IO ('v', BASE_VIDIOCPRIVATE+4) 55#define MEYEIOC_STILLCAPT _IO ('v', BASE_VIDIOC_PRIVATE+4)
56/* get a jpeg compressed snapshot */ 56/* get a jpeg compressed snapshot */
57#define MEYEIOC_STILLJCAPT _IOR ('v', BASE_VIDIOCPRIVATE+5, int) 57#define MEYEIOC_STILLJCAPT _IOR ('v', BASE_VIDIOC_PRIVATE+5, int)
58 58
59/* V4L2 private controls */ 59/* V4L2 private controls */
60#define V4L2_CID_AGC V4L2_CID_PRIVATE_BASE 60#define V4L2_CID_AGC V4L2_CID_PRIVATE_BASE
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 3793d168b44d..047f7e6edb86 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -160,16 +160,6 @@ enum v4l2_buf_type {
160 V4L2_BUF_TYPE_PRIVATE = 0x80, 160 V4L2_BUF_TYPE_PRIVATE = 0x80,
161}; 161};
162 162
163enum v4l2_ctrl_type {
164 V4L2_CTRL_TYPE_INTEGER = 1,
165 V4L2_CTRL_TYPE_BOOLEAN = 2,
166 V4L2_CTRL_TYPE_MENU = 3,
167 V4L2_CTRL_TYPE_BUTTON = 4,
168 V4L2_CTRL_TYPE_INTEGER64 = 5,
169 V4L2_CTRL_TYPE_CTRL_CLASS = 6,
170 V4L2_CTRL_TYPE_STRING = 7,
171};
172
173enum v4l2_tuner_type { 163enum v4l2_tuner_type {
174 V4L2_TUNER_RADIO = 1, 164 V4L2_TUNER_RADIO = 1,
175 V4L2_TUNER_ANALOG_TV = 2, 165 V4L2_TUNER_ANALOG_TV = 2,
@@ -294,6 +284,8 @@ struct v4l2_pix_format {
294 284
295/* Grey formats */ 285/* Grey formats */
296#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ 286#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */
287#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */
288#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */
297#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ 289#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
298#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ 290#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
299 291
@@ -369,6 +361,7 @@ struct v4l2_pix_format {
369#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ 361#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
370#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ 362#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
371#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ 363#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
364#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
372 365
373/* 366/*
374 * F O R M A T E N U M E R A T I O N 367 * F O R M A T E N U M E R A T I O N
@@ -549,6 +542,8 @@ struct v4l2_buffer {
549#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ 542#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
550#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ 543#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
551#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ 544#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
545/* Buffer is ready, but the data contained within is corrupted. */
546#define V4L2_BUF_FLAG_ERROR 0x0040
552#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ 547#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
553#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ 548#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */
554 549
@@ -939,6 +934,16 @@ struct v4l2_ext_controls {
939#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) 934#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
940#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) 935#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
941 936
937enum v4l2_ctrl_type {
938 V4L2_CTRL_TYPE_INTEGER = 1,
939 V4L2_CTRL_TYPE_BOOLEAN = 2,
940 V4L2_CTRL_TYPE_MENU = 3,
941 V4L2_CTRL_TYPE_BUTTON = 4,
942 V4L2_CTRL_TYPE_INTEGER64 = 5,
943 V4L2_CTRL_TYPE_CTRL_CLASS = 6,
944 V4L2_CTRL_TYPE_STRING = 7,
945};
946
942/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ 947/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
943struct v4l2_queryctrl { 948struct v4l2_queryctrl {
944 __u32 id; 949 __u32 id;
@@ -1023,14 +1028,24 @@ enum v4l2_colorfx {
1023 V4L2_COLORFX_NONE = 0, 1028 V4L2_COLORFX_NONE = 0,
1024 V4L2_COLORFX_BW = 1, 1029 V4L2_COLORFX_BW = 1,
1025 V4L2_COLORFX_SEPIA = 2, 1030 V4L2_COLORFX_SEPIA = 2,
1031 V4L2_COLORFX_NEGATIVE = 3,
1032 V4L2_COLORFX_EMBOSS = 4,
1033 V4L2_COLORFX_SKETCH = 5,
1034 V4L2_COLORFX_SKY_BLUE = 6,
1035 V4L2_COLORFX_GRASS_GREEN = 7,
1036 V4L2_COLORFX_SKIN_WHITEN = 8,
1037 V4L2_COLORFX_VIVID = 9,
1026}; 1038};
1027#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) 1039#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
1028#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) 1040#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
1029 1041
1030#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) 1042#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
1031#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) 1043#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
1044
1045#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36)
1046
1032/* last CID + 1 */ 1047/* last CID + 1 */
1033#define V4L2_CID_LASTP1 (V4L2_CID_BASE+36) 1048#define V4L2_CID_LASTP1 (V4L2_CID_BASE+37)
1034 1049
1035/* MPEG-class control IDs defined by V4L2 */ 1050/* MPEG-class control IDs defined by V4L2 */
1036#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) 1051#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
@@ -1276,6 +1291,9 @@ enum v4l2_exposure_auto_type {
1276 1291
1277#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) 1292#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
1278 1293
1294#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17)
1295#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18)
1296
1279/* FM Modulator class control IDs */ 1297/* FM Modulator class control IDs */
1280#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) 1298#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
1281#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) 1299#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
@@ -1621,6 +1639,38 @@ struct v4l2_streamparm {
1621}; 1639};
1622 1640
1623/* 1641/*
1642 * E V E N T S
1643 */
1644
1645#define V4L2_EVENT_ALL 0
1646#define V4L2_EVENT_VSYNC 1
1647#define V4L2_EVENT_EOS 2
1648#define V4L2_EVENT_PRIVATE_START 0x08000000
1649
1650/* Payload for V4L2_EVENT_VSYNC */
1651struct v4l2_event_vsync {
1652 /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */
1653 __u8 field;
1654} __attribute__ ((packed));
1655
1656struct v4l2_event {
1657 __u32 type;
1658 union {
1659 struct v4l2_event_vsync vsync;
1660 __u8 data[64];
1661 } u;
1662 __u32 pending;
1663 __u32 sequence;
1664 struct timespec timestamp;
1665 __u32 reserved[9];
1666};
1667
1668struct v4l2_event_subscription {
1669 __u32 type;
1670 __u32 reserved[7];
1671};
1672
1673/*
1624 * A D V A N C E D D E B U G G I N G 1674 * A D V A N C E D D E B U G G I N G
1625 * 1675 *
1626 * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! 1676 * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
@@ -1742,6 +1792,9 @@ struct v4l2_dbg_chip_ident {
1742#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) 1792#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset)
1743#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) 1793#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
1744#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) 1794#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
1795#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event)
1796#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription)
1797#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
1745 1798
1746/* Reminder: when adding new ioctls please add support for them to 1799/* Reminder: when adding new ioctls please add support for them to
1747 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 1800 drivers/media/video/v4l2-compat-ioctl32.c as well! */
diff --git a/include/media/ak881x.h b/include/media/ak881x.h
new file mode 100644
index 000000000000..b7f2add5ce7b
--- /dev/null
+++ b/include/media/ak881x.h
@@ -0,0 +1,25 @@
1/*
2 * Header for AK8813 / AK8814 TV-ecoders from Asahi Kasei Microsystems Co., Ltd. (AKM)
3 *
4 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef AK881X_H
12#define AK881X_H
13
14#define AK881X_IF_MODE_MASK (3 << 0)
15#define AK881X_IF_MODE_BT656 (0 << 0)
16#define AK881X_IF_MODE_MASTER (1 << 0)
17#define AK881X_IF_MODE_SLAVE (2 << 0)
18#define AK881X_FIELD (1 << 2)
19#define AK881X_COMPONENT (1 << 3)
20
21struct ak881x_pdata {
22 unsigned long flags;
23};
24
25#endif
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
index 4314a5f6a087..cc973ed845a7 100644
--- a/include/media/davinci/vpfe_capture.h
+++ b/include/media/davinci/vpfe_capture.h
@@ -94,6 +94,8 @@ struct vpfe_config {
94 /* vpfe clock */ 94 /* vpfe clock */
95 struct clk *vpssclk; 95 struct clk *vpssclk;
96 struct clk *slaveclk; 96 struct clk *slaveclk;
97 /* Function for Clearing the interrupt */
98 void (*clr_intr)(int vdint);
97}; 99};
98 100
99struct vpfe_device { 101struct vpfe_device {
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index c66298062d39..528050e39ad9 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -50,6 +50,10 @@ struct card_ir {
50 struct ir_input_state ir; 50 struct ir_input_state ir;
51 char name[32]; 51 char name[32];
52 char phys[32]; 52 char phys[32];
53 int users;
54
55 u32 running:1;
56 struct ir_dev_props props;
53 57
54 /* Usual gpio signalling */ 58 /* Usual gpio signalling */
55 59
@@ -79,6 +83,9 @@ struct card_ir {
79 /* NEC decoding */ 83 /* NEC decoding */
80 u32 nec_gpio; 84 u32 nec_gpio;
81 struct tasklet_struct tlet; 85 struct tasklet_struct tlet;
86
87 /* IR core raw decoding */
88 u32 raw_decode;
82}; 89};
83 90
84/* Routines from ir-functions.c */ 91/* Routines from ir-functions.c */
@@ -97,71 +104,4 @@ u32 ir_rc5_decode(unsigned int code);
97void ir_rc5_timer_end(unsigned long data); 104void ir_rc5_timer_end(unsigned long data);
98void ir_rc5_timer_keyup(unsigned long data); 105void ir_rc5_timer_keyup(unsigned long data);
99 106
100/* scancode->keycode map tables from ir-keymaps.c */
101
102extern struct ir_scancode_table ir_codes_empty_table;
103extern struct ir_scancode_table ir_codes_avermedia_table;
104extern struct ir_scancode_table ir_codes_avermedia_dvbt_table;
105extern struct ir_scancode_table ir_codes_avermedia_m135a_table;
106extern struct ir_scancode_table ir_codes_avermedia_cardbus_table;
107extern struct ir_scancode_table ir_codes_apac_viewcomp_table;
108extern struct ir_scancode_table ir_codes_pixelview_table;
109extern struct ir_scancode_table ir_codes_pixelview_new_table;
110extern struct ir_scancode_table ir_codes_nebula_table;
111extern struct ir_scancode_table ir_codes_dntv_live_dvb_t_table;
112extern struct ir_scancode_table ir_codes_iodata_bctv7e_table;
113extern struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table;
114extern struct ir_scancode_table ir_codes_msi_tvanywhere_table;
115extern struct ir_scancode_table ir_codes_cinergy_1400_table;
116extern struct ir_scancode_table ir_codes_avertv_303_table;
117extern struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table;
118extern struct ir_scancode_table ir_codes_em_terratec_table;
119extern struct ir_scancode_table ir_codes_pinnacle_grey_table;
120extern struct ir_scancode_table ir_codes_flyvideo_table;
121extern struct ir_scancode_table ir_codes_flydvb_table;
122extern struct ir_scancode_table ir_codes_cinergy_table;
123extern struct ir_scancode_table ir_codes_eztv_table;
124extern struct ir_scancode_table ir_codes_avermedia_table;
125extern struct ir_scancode_table ir_codes_videomate_tv_pvr_table;
126extern struct ir_scancode_table ir_codes_manli_table;
127extern struct ir_scancode_table ir_codes_gotview7135_table;
128extern struct ir_scancode_table ir_codes_purpletv_table;
129extern struct ir_scancode_table ir_codes_pctv_sedna_table;
130extern struct ir_scancode_table ir_codes_pv951_table;
131extern struct ir_scancode_table ir_codes_rc5_tv_table;
132extern struct ir_scancode_table ir_codes_winfast_table;
133extern struct ir_scancode_table ir_codes_pinnacle_color_table;
134extern struct ir_scancode_table ir_codes_hauppauge_new_table;
135extern struct ir_scancode_table ir_codes_rc5_hauppauge_new_table;
136extern struct ir_scancode_table ir_codes_npgtech_table;
137extern struct ir_scancode_table ir_codes_norwood_table;
138extern struct ir_scancode_table ir_codes_proteus_2309_table;
139extern struct ir_scancode_table ir_codes_budget_ci_old_table;
140extern struct ir_scancode_table ir_codes_asus_pc39_table;
141extern struct ir_scancode_table ir_codes_encore_enltv_table;
142extern struct ir_scancode_table ir_codes_encore_enltv2_table;
143extern struct ir_scancode_table ir_codes_tt_1500_table;
144extern struct ir_scancode_table ir_codes_fusionhdtv_mce_table;
145extern struct ir_scancode_table ir_codes_behold_table;
146extern struct ir_scancode_table ir_codes_behold_columbus_table;
147extern struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table;
148extern struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table;
149extern struct ir_scancode_table ir_codes_powercolor_real_angel_table;
150extern struct ir_scancode_table ir_codes_avermedia_a16d_table;
151extern struct ir_scancode_table ir_codes_encore_enltv_fm53_table;
152extern struct ir_scancode_table ir_codes_real_audio_220_32_keys_table;
153extern struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table;
154extern struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table;
155extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table;
156extern struct ir_scancode_table ir_codes_kaiomy_table;
157extern struct ir_scancode_table ir_codes_dm1105_nec_table;
158extern struct ir_scancode_table ir_codes_tevii_nec_table;
159extern struct ir_scancode_table ir_codes_tbs_nec_table;
160extern struct ir_scancode_table ir_codes_evga_indtube_table;
161extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
162extern struct ir_scancode_table ir_codes_videomate_s350_table;
163extern struct ir_scancode_table ir_codes_gadmei_rm008z_table;
164extern struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table;
165extern struct ir_scancode_table ir_codes_winfast_usbii_deluxe_table;
166extern struct ir_scancode_table ir_codes_kworld_315u_table;
167#endif 107#endif
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index 61c223bc3953..ad1303f20e00 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -1,6 +1,8 @@
1/* 1/*
2 * Remote Controller core header 2 * Remote Controller core header
3 * 3 *
4 * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
4 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation version 2 of the License. 8 * the Free Software Foundation version 2 of the License.
@@ -14,61 +16,133 @@
14#ifndef _IR_CORE 16#ifndef _IR_CORE
15#define _IR_CORE 17#define _IR_CORE
16 18
17#include <linux/input.h>
18#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/kfifo.h>
21#include <linux/time.h>
22#include <linux/timer.h>
23#include <media/rc-map.h>
19 24
20extern int ir_core_debug; 25extern int ir_core_debug;
21#define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ 26#define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \
22 printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) 27 printk(KERN_DEBUG "%s: " fmt , __func__, ## arg)
23 28
24#define IR_TYPE_UNKNOWN 0 29enum rc_driver_type {
25#define IR_TYPE_RC5 (1 << 0) /* Philips RC5 protocol */ 30 RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */
26#define IR_TYPE_PD (1 << 1) /* Pulse distance encoded IR */ 31 RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */
27#define IR_TYPE_NEC (1 << 2)
28#define IR_TYPE_OTHER (((u64)1) << 63l)
29
30struct ir_scancode {
31 u16 scancode;
32 u32 keycode;
33};
34
35struct ir_scancode_table {
36 struct ir_scancode *scan;
37 int size;
38 u64 ir_type;
39 spinlock_t lock;
40}; 32};
41 33
34/**
35 * struct ir_dev_props - Allow caller drivers to set special properties
36 * @driver_type: specifies if the driver or hardware have already a decoder,
37 * or if it needs to use the IR raw event decoders to produce a scancode
38 * @allowed_protos: bitmask with the supported IR_TYPE_* protocols
39 * @scanmask: some hardware decoders are not capable of providing the full
40 * scancode to the application. As this is a hardware limit, we can't do
41 * anything with it. Yet, as the same keycode table can be used with other
42 * devices, a mask is provided to allow its usage. Drivers should generally
43 * leave this field in blank
44 * @priv: driver-specific data, to be used on the callbacks
45 * @change_protocol: allow changing the protocol used on hardware decoders
46 * @open: callback to allow drivers to enable polling/irq when IR input device
47 * is opened.
48 * @close: callback to allow drivers to disable polling/irq when IR input device
49 * is opened.
50 */
42struct ir_dev_props { 51struct ir_dev_props {
43 unsigned long allowed_protos; 52 enum rc_driver_type driver_type;
44 void *priv; 53 unsigned long allowed_protos;
45 int (*change_protocol)(void *priv, u64 ir_type); 54 u32 scanmask;
55 void *priv;
56 int (*change_protocol)(void *priv, u64 ir_type);
57 int (*open)(void *priv);
58 void (*close)(void *priv);
46}; 59};
47 60
48
49struct ir_input_dev { 61struct ir_input_dev {
50 struct input_dev *dev; /* Input device*/ 62 struct device dev; /* device */
63 char *driver_name; /* Name of the driver module */
51 struct ir_scancode_table rc_tab; /* scan/key table */ 64 struct ir_scancode_table rc_tab; /* scan/key table */
52 unsigned long devno; /* device number */ 65 unsigned long devno; /* device number */
53 struct attribute_group attr; /* IR attributes */
54 struct device *class_dev; /* virtual class dev */
55 const struct ir_dev_props *props; /* Device properties */ 66 const struct ir_dev_props *props; /* Device properties */
67 struct ir_raw_event_ctrl *raw; /* for raw pulse/space events */
68 struct input_dev *input_dev; /* the input device associated with this device */
69
70 /* key info - needed by IR keycode handlers */
71 spinlock_t keylock; /* protects the below members */
72 bool keypressed; /* current state */
73 unsigned long keyup_jiffies; /* when should the current keypress be released? */
74 struct timer_list timer_keyup; /* timer for releasing a keypress */
75 u32 last_keycode; /* keycode of last command */
76 u32 last_scancode; /* scancode of last command */
77 u8 last_toggle; /* toggle of last command */
56}; 78};
57#define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr)
58 79
59/* Routines from ir-keytable.c */ 80enum raw_event_type {
81 IR_SPACE = (1 << 0),
82 IR_PULSE = (1 << 1),
83 IR_START_EVENT = (1 << 2),
84 IR_STOP_EVENT = (1 << 3),
85};
60 86
61u32 ir_g_keycode_from_table(struct input_dev *input_dev, 87#define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr)
62 u32 scancode);
63 88
64int ir_input_register(struct input_dev *dev, 89/* From ir-keytable.c */
90int __ir_input_register(struct input_dev *dev,
65 const struct ir_scancode_table *ir_codes, 91 const struct ir_scancode_table *ir_codes,
66 const struct ir_dev_props *props); 92 const struct ir_dev_props *props,
93 const char *driver_name);
94
95static inline int ir_input_register(struct input_dev *dev,
96 const char *map_name,
97 const struct ir_dev_props *props,
98 const char *driver_name) {
99 struct ir_scancode_table *ir_codes;
100 struct ir_input_dev *ir_dev;
101 int rc;
102
103 if (!map_name)
104 return -EINVAL;
105
106 ir_codes = get_rc_map(map_name);
107 if (!ir_codes)
108 return -EINVAL;
109
110 rc = __ir_input_register(dev, ir_codes, props, driver_name);
111 if (rc < 0)
112 return -EINVAL;
113
114 ir_dev = input_get_drvdata(dev);
115
116 if (!rc && ir_dev->props && ir_dev->props->change_protocol)
117 rc = ir_dev->props->change_protocol(ir_dev->props->priv,
118 ir_codes->ir_type);
119
120 return rc;
121}
122
67void ir_input_unregister(struct input_dev *input_dev); 123void ir_input_unregister(struct input_dev *input_dev);
68 124
69/* Routines from ir-sysfs.c */ 125void ir_repeat(struct input_dev *dev);
126void ir_keydown(struct input_dev *dev, int scancode, u8 toggle);
127u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode);
128
129/* From ir-raw-event.c */
130
131struct ir_raw_event {
132 unsigned pulse:1;
133 unsigned duration:31;
134};
135
136#define IR_MAX_DURATION 0x7FFFFFFF /* a bit more than 2 seconds */
70 137
71int ir_register_class(struct input_dev *input_dev); 138void ir_raw_event_handle(struct input_dev *input_dev);
72void ir_unregister_class(struct input_dev *input_dev); 139int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
140int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
141static inline void ir_raw_event_reset(struct input_dev *input_dev)
142{
143 struct ir_raw_event ev = { .pulse = false, .duration = 0 };
144 ir_raw_event_store(input_dev, &ev);
145 ir_raw_event_handle(input_dev);
146}
73 147
74#endif 148#endif /* _IR_CORE */
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 9142936603cc..0506e45c9a4f 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -6,7 +6,7 @@
6struct IR_i2c; 6struct IR_i2c;
7 7
8struct IR_i2c { 8struct IR_i2c {
9 struct ir_scancode_table *ir_codes; 9 char *ir_codes;
10 10
11 struct i2c_client *c; 11 struct i2c_client *c;
12 struct input_dev *input; 12 struct input_dev *input;
@@ -34,9 +34,9 @@ enum ir_kbd_get_key_fn {
34 34
35/* Can be passed when instantiating an ir_video i2c device */ 35/* Can be passed when instantiating an ir_video i2c device */
36struct IR_i2c_init_data { 36struct IR_i2c_init_data {
37 struct ir_scancode_table *ir_codes; 37 char *ir_codes;
38 const char *name; 38 const char *name;
39 u64 type; /* IR_TYPE_RC5, IR_TYPE_PD, etc */ 39 u64 type; /* IR_TYPE_RC5, etc */
40 /* 40 /*
41 * Specify either a function pointer or a value indicating one of 41 * Specify either a function pointer or a value indicating one of
42 * ir_kbd_i2c's internal get_key functions 42 * ir_kbd_i2c's internal get_key functions
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
new file mode 100644
index 000000000000..5833966a7100
--- /dev/null
+++ b/include/media/rc-map.h
@@ -0,0 +1,121 @@
1/*
2 * rc-map.h - define RC map names used by RC drivers
3 *
4 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/input.h>
13
14#define IR_TYPE_UNKNOWN 0
15#define IR_TYPE_RC5 (1 << 0) /* Philips RC5 protocol */
16#define IR_TYPE_NEC (1 << 1)
17#define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */
18#define IR_TYPE_JVC (1 << 3) /* JVC protocol */
19#define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */
20#define IR_TYPE_OTHER (1u << 31)
21
22struct ir_scancode {
23 u32 scancode;
24 u32 keycode;
25};
26
27struct ir_scancode_table {
28 struct ir_scancode *scan;
29 unsigned int size; /* Max number of entries */
30 unsigned int len; /* Used number of entries */
31 unsigned int alloc; /* Size of *scan in bytes */
32 u64 ir_type;
33 char *name;
34 spinlock_t lock;
35};
36
37struct rc_keymap {
38 struct list_head list;
39 struct ir_scancode_table map;
40};
41
42/* Routines from rc-map.c */
43
44int ir_register_map(struct rc_keymap *map);
45void ir_unregister_map(struct rc_keymap *map);
46struct ir_scancode_table *get_rc_map(const char *name);
47void rc_map_init(void);
48
49/* Names of the several keytables defined in-kernel */
50
51#define RC_MAP_ADSTECH_DVB_T_PCI "rc-adstech-dvb-t-pci"
52#define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp"
53#define RC_MAP_ASUS_PC39 "rc-asus-pc39"
54#define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600"
55#define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d"
56#define RC_MAP_AVERMEDIA_CARDBUS "rc-avermedia-cardbus"
57#define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt"
58#define RC_MAP_AVERMEDIA_M135A_RM_JX "rc-avermedia-m135a-rm-jx"
59#define RC_MAP_AVERMEDIA "rc-avermedia"
60#define RC_MAP_AVERTV_303 "rc-avertv-303"
61#define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus"
62#define RC_MAP_BEHOLD "rc-behold"
63#define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old"
64#define RC_MAP_CINERGY_1400 "rc-cinergy-1400"
65#define RC_MAP_CINERGY "rc-cinergy"
66#define RC_MAP_DM1105_NEC "rc-dm1105-nec"
67#define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro"
68#define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t"
69#define RC_MAP_EMPTY "rc-empty"
70#define RC_MAP_EM_TERRATEC "rc-em-terratec"
71#define RC_MAP_ENCORE_ENLTV2 "rc-encore-enltv2"
72#define RC_MAP_ENCORE_ENLTV_FM53 "rc-encore-enltv-fm53"
73#define RC_MAP_ENCORE_ENLTV "rc-encore-enltv"
74#define RC_MAP_EVGA_INDTUBE "rc-evga-indtube"
75#define RC_MAP_EZTV "rc-eztv"
76#define RC_MAP_FLYDVB "rc-flydvb"
77#define RC_MAP_FLYVIDEO "rc-flyvideo"
78#define RC_MAP_FUSIONHDTV_MCE "rc-fusionhdtv-mce"
79#define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z"
80#define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce"
81#define RC_MAP_GOTVIEW7135 "rc-gotview7135"
82#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge-new"
83#define RC_MAP_IMON_MCE "rc-imon-mce"
84#define RC_MAP_IMON_PAD "rc-imon-pad"
85#define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e"
86#define RC_MAP_KAIOMY "rc-kaiomy"
87#define RC_MAP_KWORLD_315U "rc-kworld-315u"
88#define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog"
89#define RC_MAP_MANLI "rc-manli"
90#define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus"
91#define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere"
92#define RC_MAP_NEBULA "rc-nebula"
93#define RC_MAP_NEC_TERRATEC_CINERGY_XS "rc-nec-terratec-cinergy-xs"
94#define RC_MAP_NORWOOD "rc-norwood"
95#define RC_MAP_NPGTECH "rc-npgtech"
96#define RC_MAP_PCTV_SEDNA "rc-pctv-sedna"
97#define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color"
98#define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey"
99#define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd"
100#define RC_MAP_PIXELVIEW_NEW "rc-pixelview-new"
101#define RC_MAP_PIXELVIEW "rc-pixelview"
102#define RC_MAP_PIXELVIEW_MK12 "rc-pixelview-mk12"
103#define RC_MAP_POWERCOLOR_REAL_ANGEL "rc-powercolor-real-angel"
104#define RC_MAP_PROTEUS_2309 "rc-proteus-2309"
105#define RC_MAP_PURPLETV "rc-purpletv"
106#define RC_MAP_PV951 "rc-pv951"
107#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new"
108#define RC_MAP_RC5_TV "rc-rc5-tv"
109#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
110#define RC_MAP_TBS_NEC "rc-tbs-nec"
111#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
112#define RC_MAP_TEVII_NEC "rc-tevii-nec"
113#define RC_MAP_TT_1500 "rc-tt-1500"
114#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
115#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
116#define RC_MAP_WINFAST "rc-winfast"
117#define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe"
118/*
119 * Please, do not just append newer Remote Controller names at the end.
120 * The names should be ordered in alphabetical order
121 */
diff --git a/include/media/sh_vou.h b/include/media/sh_vou.h
new file mode 100644
index 000000000000..a3ef30242b00
--- /dev/null
+++ b/include/media/sh_vou.h
@@ -0,0 +1,34 @@
1/*
2 * SuperH Video Output Unit (VOU) driver header
3 *
4 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef SH_VOU_H
11#define SH_VOU_H
12
13#include <linux/i2c.h>
14
15/* Bus flags */
16#define SH_VOU_PCLK_FALLING (1 << 0)
17#define SH_VOU_HSYNC_LOW (1 << 1)
18#define SH_VOU_VSYNC_LOW (1 << 2)
19
20enum sh_vou_bus_fmt {
21 SH_VOU_BUS_8BIT,
22 SH_VOU_BUS_16BIT,
23 SH_VOU_BUS_BT656,
24};
25
26struct sh_vou_pdata {
27 enum sh_vou_bus_fmt bus_fmt;
28 int i2c_adap;
29 struct i2c_board_info *board_info;
30 unsigned long flags;
31 char *module_name;
32};
33
34#endif
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 9d69f01b6fa2..c9a5bbfa6ab5 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -266,8 +266,8 @@ static inline unsigned long soc_camera_bus_param_compatible(
266 common_flags; 266 common_flags;
267} 267}
268 268
269static inline void soc_camera_limit_side(unsigned int *start, 269static inline void soc_camera_limit_side(int *start, int *length,
270 unsigned int *length, unsigned int start_min, 270 unsigned int start_min,
271 unsigned int length_min, unsigned int length_max) 271 unsigned int length_min, unsigned int length_max)
272{ 272{
273 if (*length < length_min) 273 if (*length < length_min)
@@ -284,4 +284,12 @@ static inline void soc_camera_limit_side(unsigned int *start,
284extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, 284extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
285 unsigned long flags); 285 unsigned long flags);
286 286
287/* This is only temporary here - until v4l2-subdev begins to link to video_device */
288#include <linux/i2c.h>
289static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *client)
290{
291 struct soc_camera_device *icd = client->dev.platform_data;
292 return icd->vdev;
293}
294
287#endif 295#endif
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 56abf21dd786..21b4428c12ab 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -25,6 +25,10 @@
25#define V4L2_CHIP_IDENT_H_ 25#define V4L2_CHIP_IDENT_H_
26 26
27/* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */ 27/* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */
28
29/* KEEP THIS LIST ORDERED BY ID!
30 Otherwise it will be hard to see which ranges are already in use when
31 adding support to a new chip family. */
28enum { 32enum {
29 /* general idents: reserved range 0-49 */ 33 /* general idents: reserved range 0-49 */
30 V4L2_IDENT_NONE = 0, /* No chip matched */ 34 V4L2_IDENT_NONE = 0, /* No chip matched */
@@ -77,17 +81,14 @@ enum {
77 V4L2_IDENT_CX23417 = 417, 81 V4L2_IDENT_CX23417 = 417,
78 V4L2_IDENT_CX23418 = 418, 82 V4L2_IDENT_CX23418 = 418,
79 83
80 /* module au0828 */
81 V4L2_IDENT_AU0828 = 828,
82
83 /* module indycam: just ident 2000 */
84 V4L2_IDENT_INDYCAM = 2000,
85
86 /* module bt819: reserved range 810-819 */ 84 /* module bt819: reserved range 810-819 */
87 V4L2_IDENT_BT815A = 815, 85 V4L2_IDENT_BT815A = 815,
88 V4L2_IDENT_BT817A = 817, 86 V4L2_IDENT_BT817A = 817,
89 V4L2_IDENT_BT819A = 819, 87 V4L2_IDENT_BT819A = 819,
90 88
89 /* module au0828 */
90 V4L2_IDENT_AU0828 = 828,
91
91 /* module bt856: just ident 856 */ 92 /* module bt856: just ident 856 */
92 V4L2_IDENT_BT856 = 856, 93 V4L2_IDENT_BT856 = 856,
93 94
@@ -99,6 +100,9 @@ enum {
99 V4L2_IDENT_KS0127 = 1127, 100 V4L2_IDENT_KS0127 = 1127,
100 V4L2_IDENT_KS0127B = 1128, 101 V4L2_IDENT_KS0127B = 1128,
101 102
103 /* module indycam: just ident 2000 */
104 V4L2_IDENT_INDYCAM = 2000,
105
102 /* module vp27smpx: just ident 2700 */ 106 /* module vp27smpx: just ident 2700 */
103 V4L2_IDENT_VP27SMPX = 2700, 107 V4L2_IDENT_VP27SMPX = 2700,
104 108
@@ -162,20 +166,21 @@ enum {
162 /* module saa7706h: just ident 7706 */ 166 /* module saa7706h: just ident 7706 */
163 V4L2_IDENT_SAA7706H = 7706, 167 V4L2_IDENT_SAA7706H = 7706,
164 168
169 /* module mt9v011, just ident 8243 */
170 V4L2_IDENT_MT9V011 = 8243,
171
165 /* module wm8739: just ident 8739 */ 172 /* module wm8739: just ident 8739 */
166 V4L2_IDENT_WM8739 = 8739, 173 V4L2_IDENT_WM8739 = 8739,
167 174
168 /* module wm8775: just ident 8775 */ 175 /* module wm8775: just ident 8775 */
169 V4L2_IDENT_WM8775 = 8775, 176 V4L2_IDENT_WM8775 = 8775,
170 177
171 /* module tda9840: just ident 9840 */
172 V4L2_IDENT_TDA9840 = 9840,
173
174 /* module cafe_ccic, just ident 8801 */ 178 /* module cafe_ccic, just ident 8801 */
175 V4L2_IDENT_CAFE = 8801, 179 V4L2_IDENT_CAFE = 8801,
176 180
177 /* module mt9v011, just ident 8243 */ 181 /* AKM AK8813/AK8814 */
178 V4L2_IDENT_MT9V011 = 8243, 182 V4L2_IDENT_AK8813 = 8813,
183 V4L2_IDENT_AK8814 = 8814,
179 184
180 /* module cx23885 and cx25840 */ 185 /* module cx23885 and cx25840 */
181 V4L2_IDENT_CX23885 = 8850, 186 V4L2_IDENT_CX23885 = 8850,
@@ -186,6 +191,9 @@ enum {
186 V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */ 191 V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
187 V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */ 192 V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
188 193
194 /* module tda9840: just ident 9840 */
195 V4L2_IDENT_TDA9840 = 9840,
196
189 /* module tw9910: just ident 9910 */ 197 /* module tw9910: just ident 9910 */
190 V4L2_IDENT_TW9910 = 9910, 198 V4L2_IDENT_TW9910 = 9910,
191 199
@@ -198,72 +206,70 @@ enum {
198 V4L2_IDENT_CX23101 = 23101, 206 V4L2_IDENT_CX23101 = 23101,
199 V4L2_IDENT_CX23102 = 23102, 207 V4L2_IDENT_CX23102 = 23102,
200 208
201 /* module msp3400: reserved range 34000-34999 and 44000-44999 */ 209 /* module msp3400: reserved range 34000-34999 for msp34xx */
202 V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only 210 V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only
203 use internally (tveeprom.c). */ 211 use internally (tveeprom.c). */
204 212
205 V4L2_IDENT_MSP3400B = 34002, 213 V4L2_IDENT_MSP3400B = 34002,
206 V4L2_IDENT_MSP3410B = 34102,
207
208 V4L2_IDENT_MSP3400C = 34003, 214 V4L2_IDENT_MSP3400C = 34003,
209 V4L2_IDENT_MSP3410C = 34103,
210
211 V4L2_IDENT_MSP3400D = 34004, 215 V4L2_IDENT_MSP3400D = 34004,
212 V4L2_IDENT_MSP3410D = 34104, 216 V4L2_IDENT_MSP3400G = 34007,
217 V4L2_IDENT_MSP3401G = 34017,
218 V4L2_IDENT_MSP3402G = 34027,
213 V4L2_IDENT_MSP3405D = 34054, 219 V4L2_IDENT_MSP3405D = 34054,
214 V4L2_IDENT_MSP3415D = 34154, 220 V4L2_IDENT_MSP3405G = 34057,
215 V4L2_IDENT_MSP3407D = 34074, 221 V4L2_IDENT_MSP3407D = 34074,
216 V4L2_IDENT_MSP3417D = 34174, 222 V4L2_IDENT_MSP3407G = 34077,
217 223
218 V4L2_IDENT_MSP3400G = 34007, 224 V4L2_IDENT_MSP3410B = 34102,
225 V4L2_IDENT_MSP3410C = 34103,
226 V4L2_IDENT_MSP3410D = 34104,
219 V4L2_IDENT_MSP3410G = 34107, 227 V4L2_IDENT_MSP3410G = 34107,
220 V4L2_IDENT_MSP3420G = 34207,
221 V4L2_IDENT_MSP3430G = 34307,
222 V4L2_IDENT_MSP3440G = 34407,
223 V4L2_IDENT_MSP3450G = 34507,
224 V4L2_IDENT_MSP3460G = 34607,
225
226 V4L2_IDENT_MSP3401G = 34017,
227 V4L2_IDENT_MSP3411G = 34117, 228 V4L2_IDENT_MSP3411G = 34117,
228 V4L2_IDENT_MSP3421G = 34217,
229 V4L2_IDENT_MSP3431G = 34317,
230 V4L2_IDENT_MSP3441G = 34417,
231 V4L2_IDENT_MSP3451G = 34517,
232 V4L2_IDENT_MSP3461G = 34617,
233
234 V4L2_IDENT_MSP3402G = 34027,
235 V4L2_IDENT_MSP3412G = 34127, 229 V4L2_IDENT_MSP3412G = 34127,
236 V4L2_IDENT_MSP3422G = 34227, 230 V4L2_IDENT_MSP3415D = 34154,
237 V4L2_IDENT_MSP3442G = 34427,
238 V4L2_IDENT_MSP3452G = 34527,
239
240 V4L2_IDENT_MSP3405G = 34057,
241 V4L2_IDENT_MSP3415G = 34157, 231 V4L2_IDENT_MSP3415G = 34157,
242 V4L2_IDENT_MSP3425G = 34257, 232 V4L2_IDENT_MSP3417D = 34174,
243 V4L2_IDENT_MSP3435G = 34357,
244 V4L2_IDENT_MSP3445G = 34457,
245 V4L2_IDENT_MSP3455G = 34557,
246 V4L2_IDENT_MSP3465G = 34657,
247
248 V4L2_IDENT_MSP3407G = 34077,
249 V4L2_IDENT_MSP3417G = 34177, 233 V4L2_IDENT_MSP3417G = 34177,
234
235 V4L2_IDENT_MSP3420G = 34207,
236 V4L2_IDENT_MSP3421G = 34217,
237 V4L2_IDENT_MSP3422G = 34227,
238 V4L2_IDENT_MSP3425G = 34257,
250 V4L2_IDENT_MSP3427G = 34277, 239 V4L2_IDENT_MSP3427G = 34277,
240
241 V4L2_IDENT_MSP3430G = 34307,
242 V4L2_IDENT_MSP3431G = 34317,
243 V4L2_IDENT_MSP3435G = 34357,
251 V4L2_IDENT_MSP3437G = 34377, 244 V4L2_IDENT_MSP3437G = 34377,
245
246 V4L2_IDENT_MSP3440G = 34407,
247 V4L2_IDENT_MSP3441G = 34417,
248 V4L2_IDENT_MSP3442G = 34427,
249 V4L2_IDENT_MSP3445G = 34457,
252 V4L2_IDENT_MSP3447G = 34477, 250 V4L2_IDENT_MSP3447G = 34477,
251
252 V4L2_IDENT_MSP3450G = 34507,
253 V4L2_IDENT_MSP3451G = 34517,
254 V4L2_IDENT_MSP3452G = 34527,
255 V4L2_IDENT_MSP3455G = 34557,
253 V4L2_IDENT_MSP3457G = 34577, 256 V4L2_IDENT_MSP3457G = 34577,
257
258 V4L2_IDENT_MSP3460G = 34607,
259 V4L2_IDENT_MSP3461G = 34617,
260 V4L2_IDENT_MSP3465G = 34657,
254 V4L2_IDENT_MSP3467G = 34677, 261 V4L2_IDENT_MSP3467G = 34677,
255 262
256 /* module msp3400: reserved range 34000-34999 and 44000-44999 */ 263 /* module msp3400: reserved range 44000-44999 for msp44xx */
257 V4L2_IDENT_MSP4400G = 44007, 264 V4L2_IDENT_MSP4400G = 44007,
258 V4L2_IDENT_MSP4410G = 44107,
259 V4L2_IDENT_MSP4420G = 44207,
260 V4L2_IDENT_MSP4440G = 44407,
261 V4L2_IDENT_MSP4450G = 44507,
262
263 V4L2_IDENT_MSP4408G = 44087, 265 V4L2_IDENT_MSP4408G = 44087,
266 V4L2_IDENT_MSP4410G = 44107,
264 V4L2_IDENT_MSP4418G = 44187, 267 V4L2_IDENT_MSP4418G = 44187,
268 V4L2_IDENT_MSP4420G = 44207,
265 V4L2_IDENT_MSP4428G = 44287, 269 V4L2_IDENT_MSP4428G = 44287,
270 V4L2_IDENT_MSP4440G = 44407,
266 V4L2_IDENT_MSP4448G = 44487, 271 V4L2_IDENT_MSP4448G = 44487,
272 V4L2_IDENT_MSP4450G = 44507,
267 V4L2_IDENT_MSP4458G = 44587, 273 V4L2_IDENT_MSP4458G = 44587,
268 274
269 /* Micron CMOS sensor chips: 45000-45099 */ 275 /* Micron CMOS sensor chips: 45000-45099 */
@@ -282,20 +288,27 @@ enum {
282 /* HV7131R CMOS sensor: just ident 46000 */ 288 /* HV7131R CMOS sensor: just ident 46000 */
283 V4L2_IDENT_HV7131R = 46000, 289 V4L2_IDENT_HV7131R = 46000,
284 290
291 /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
292 V4L2_IDENT_RJ54N1CB0C = 51980,
293
294 /* module m52790: just ident 52790 */
295 V4L2_IDENT_M52790 = 52790,
296
285 /* module cs53132a: just ident 53132 */ 297 /* module cs53132a: just ident 53132 */
286 V4L2_IDENT_CS53l32A = 53132, 298 V4L2_IDENT_CS53l32A = 53132,
287 299
300 /* modules upd61151 MPEG2 encoder: just ident 54000 */
301 V4L2_IDENT_UPD61161 = 54000,
302 /* modules upd61152 MPEG2 encoder with AC3: just ident 54001 */
303 V4L2_IDENT_UPD61162 = 54001,
304
288 /* module upd64031a: just ident 64031 */ 305 /* module upd64031a: just ident 64031 */
289 V4L2_IDENT_UPD64031A = 64031, 306 V4L2_IDENT_UPD64031A = 64031,
290 307
291 /* module upd64083: just ident 64083 */ 308 /* module upd64083: just ident 64083 */
292 V4L2_IDENT_UPD64083 = 64083, 309 V4L2_IDENT_UPD64083 = 64083,
293 310
294 /* module m52790: just ident 52790 */ 311 /* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */
295 V4L2_IDENT_M52790 = 52790,
296
297 /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
298 V4L2_IDENT_RJ54N1CB0C = 51980,
299}; 312};
300 313
301#endif 314#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1c7b259f341c..98b32645e5a7 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -85,13 +85,13 @@
85struct v4l2_prio_state { 85struct v4l2_prio_state {
86 atomic_t prios[4]; 86 atomic_t prios[4];
87}; 87};
88int v4l2_prio_init(struct v4l2_prio_state *global); 88void v4l2_prio_init(struct v4l2_prio_state *global);
89int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, 89int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
90 enum v4l2_priority new); 90 enum v4l2_priority new);
91int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); 91void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
92int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local); 92void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
93enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); 93enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
94int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local); 94int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
95 95
96/* ------------------------------------------------------------------------- */ 96/* ------------------------------------------------------------------------- */
97 97
@@ -184,6 +184,25 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
184 184
185/* ------------------------------------------------------------------------- */ 185/* ------------------------------------------------------------------------- */
186 186
187/* SPI Helper functions */
188#if defined(CONFIG_SPI)
189
190#include <linux/spi/spi.h>
191
192struct spi_device;
193
194/* Load an spi module and return an initialized v4l2_subdev struct.
195 The client_type argument is the name of the chip that's on the adapter. */
196struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
197 struct spi_master *master, struct spi_board_info *info);
198
199/* Initialize an v4l2_subdev with data from an spi_device struct */
200void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
201 const struct v4l2_subdev_ops *ops);
202#endif
203
204/* ------------------------------------------------------------------------- */
205
187/* Note: these remaining ioctls/structs should be removed as well, but they are 206/* Note: these remaining ioctls/structs should be removed as well, but they are
188 still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and 207 still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and
189 v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup 208 v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 2dee93892ea2..bebe44b03e0f 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -32,6 +32,7 @@ struct v4l2_device;
32 Drivers can clear this flag if they want to block all future 32 Drivers can clear this flag if they want to block all future
33 device access. It is cleared by video_unregister_device. */ 33 device access. It is cleared by video_unregister_device. */
34#define V4L2_FL_REGISTERED (0) 34#define V4L2_FL_REGISTERED (0)
35#define V4L2_FL_USES_V4L2_FH (1)
35 36
36struct v4l2_file_operations { 37struct v4l2_file_operations {
37 struct module *owner; 38 struct module *owner;
@@ -77,6 +78,10 @@ struct video_device
77 /* attribute to differentiate multiple indices on one physical device */ 78 /* attribute to differentiate multiple indices on one physical device */
78 int index; 79 int index;
79 80
81 /* V4L2 file handles */
82 spinlock_t fh_lock; /* Lock for all v4l2_fhs */
83 struct list_head fh_list; /* List of struct v4l2_fh */
84
80 int debug; /* Activates debug level*/ 85 int debug; /* Activates debug level*/
81 86
82 /* Video standard vars */ 87 /* Video standard vars */
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
new file mode 100644
index 000000000000..3b86177c8cd2
--- /dev/null
+++ b/include/media/v4l2-event.h
@@ -0,0 +1,67 @@
1/*
2 * v4l2-event.h
3 *
4 * V4L2 events.
5 *
6 * Copyright (C) 2009--2010 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#ifndef V4L2_EVENT_H
26#define V4L2_EVENT_H
27
28#include <linux/types.h>
29#include <linux/videodev2.h>
30#include <linux/wait.h>
31
32struct v4l2_fh;
33struct video_device;
34
35struct v4l2_kevent {
36 struct list_head list;
37 struct v4l2_event event;
38};
39
40struct v4l2_subscribed_event {
41 struct list_head list;
42 u32 type;
43};
44
45struct v4l2_events {
46 wait_queue_head_t wait;
47 struct list_head subscribed; /* Subscribed events */
48 struct list_head free; /* Events ready for use */
49 struct list_head available; /* Dequeueable event */
50 unsigned int navailable;
51 unsigned int nallocated; /* Number of allocated events */
52 u32 sequence;
53};
54
55int v4l2_event_init(struct v4l2_fh *fh);
56int v4l2_event_alloc(struct v4l2_fh *fh, unsigned int n);
57void v4l2_event_free(struct v4l2_fh *fh);
58int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
59 int nonblocking);
60void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
61int v4l2_event_pending(struct v4l2_fh *fh);
62int v4l2_event_subscribe(struct v4l2_fh *fh,
63 struct v4l2_event_subscription *sub);
64int v4l2_event_unsubscribe(struct v4l2_fh *fh,
65 struct v4l2_event_subscription *sub);
66
67#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
new file mode 100644
index 000000000000..1d72dde320bf
--- /dev/null
+++ b/include/media/v4l2-fh.h
@@ -0,0 +1,65 @@
1/*
2 * v4l2-fh.h
3 *
4 * V4L2 file handle. Store per file handle data for the V4L2
5 * framework. Using file handles is optional for the drivers.
6 *
7 * Copyright (C) 2009--2010 Nokia Corporation.
8 *
9 * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef V4L2_FH_H
27#define V4L2_FH_H
28
29#include <linux/list.h>
30
31struct video_device;
32struct v4l2_events;
33
34struct v4l2_fh {
35 struct list_head list;
36 struct video_device *vdev;
37 struct v4l2_events *events; /* events, pending and subscribed */
38};
39
40/*
41 * Initialise the file handle. Parts of the V4L2 framework using the
42 * file handles should be initialised in this function. Must be called
43 * from driver's v4l2_file_operations->open() handler if the driver
44 * uses v4l2_fh.
45 */
46int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev);
47/*
48 * Add the fh to the list of file handles on a video_device. The file
49 * handle must be initialised first.
50 */
51void v4l2_fh_add(struct v4l2_fh *fh);
52/*
53 * Remove file handle from the list of file handles. Must be called in
54 * v4l2_file_operations->release() handler if the driver uses v4l2_fh.
55 */
56void v4l2_fh_del(struct v4l2_fh *fh);
57/*
58 * Release resources related to a file handle. Parts of the V4L2
59 * framework using the v4l2_fh must release their resources here, too.
60 * Must be called in v4l2_file_operations->release() handler if the
61 * driver uses v4l2_fh.
62 */
63void v4l2_fh_exit(struct v4l2_fh *fh);
64
65#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index e8ba0f2efbae..06daa6e8e051 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -21,6 +21,8 @@
21#include <linux/videodev2.h> 21#include <linux/videodev2.h>
22#endif 22#endif
23 23
24struct v4l2_fh;
25
24struct v4l2_ioctl_ops { 26struct v4l2_ioctl_ops {
25 /* ioctl callbacks */ 27 /* ioctl callbacks */
26 28
@@ -254,6 +256,11 @@ struct v4l2_ioctl_ops {
254 int (*vidioc_g_dv_timings) (struct file *file, void *fh, 256 int (*vidioc_g_dv_timings) (struct file *file, void *fh,
255 struct v4l2_dv_timings *timings); 257 struct v4l2_dv_timings *timings);
256 258
259 int (*vidioc_subscribe_event) (struct v4l2_fh *fh,
260 struct v4l2_event_subscription *sub);
261 int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh,
262 struct v4l2_event_subscription *sub);
263
257 /* For other private ioctls */ 264 /* For other private ioctls */
258 long (*vidioc_default) (struct file *file, void *fh, 265 long (*vidioc_default) (struct file *file, void *fh,
259 int cmd, void *arg); 266 int cmd, void *arg);
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
new file mode 100644
index 000000000000..8d149f1c58d0
--- /dev/null
+++ b/include/media/v4l2-mem2mem.h
@@ -0,0 +1,201 @@
1/*
2 * Memory-to-memory device framework for Video for Linux 2.
3 *
4 * Helper functions for devices that use memory buffers for both source
5 * and destination.
6 *
7 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
8 * Pawel Osciak, <p.osciak@samsung.com>
9 * Marek Szyprowski, <m.szyprowski@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version
15 */
16
17#ifndef _MEDIA_V4L2_MEM2MEM_H
18#define _MEDIA_V4L2_MEM2MEM_H
19
20#include <media/videobuf-core.h>
21
22/**
23 * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
24 * @device_run: required. Begin the actual job (transaction) inside this
25 * callback.
26 * The job does NOT have to end before this callback returns
27 * (and it will be the usual case). When the job finishes,
28 * v4l2_m2m_job_finish() has to be called.
29 * @job_ready: optional. Should return 0 if the driver does not have a job
30 * fully prepared to run yet (i.e. it will not be able to finish a
31 * transaction without sleeping). If not provided, it will be
32 * assumed that one source and one destination buffer are all
33 * that is required for the driver to perform one full transaction.
34 * This method may not sleep.
35 * @job_abort: required. Informs the driver that it has to abort the currently
36 * running transaction as soon as possible (i.e. as soon as it can
37 * stop the device safely; e.g. in the next interrupt handler),
38 * even if the transaction would not have been finished by then.
39 * After the driver performs the necessary steps, it has to call
40 * v4l2_m2m_job_finish() (as if the transaction ended normally).
41 * This function does not have to (and will usually not) wait
42 * until the device enters a state when it can be stopped.
43 */
44struct v4l2_m2m_ops {
45 void (*device_run)(void *priv);
46 int (*job_ready)(void *priv);
47 void (*job_abort)(void *priv);
48};
49
50struct v4l2_m2m_dev;
51
52struct v4l2_m2m_queue_ctx {
53/* private: internal use only */
54 struct videobuf_queue q;
55
56 /* Queue for buffers ready to be processed as soon as this
57 * instance receives access to the device */
58 struct list_head rdy_queue;
59 u8 num_rdy;
60};
61
62struct v4l2_m2m_ctx {
63/* private: internal use only */
64 struct v4l2_m2m_dev *m2m_dev;
65
66 /* Capture (output to memory) queue context */
67 struct v4l2_m2m_queue_ctx cap_q_ctx;
68
69 /* Output (input from memory) queue context */
70 struct v4l2_m2m_queue_ctx out_q_ctx;
71
72 /* For device job queue */
73 struct list_head queue;
74 unsigned long job_flags;
75
76 /* Instance private data */
77 void *priv;
78};
79
80void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev);
81
82struct videobuf_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
83 enum v4l2_buf_type type);
84
85void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
86 struct v4l2_m2m_ctx *m2m_ctx);
87
88int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
89 struct v4l2_requestbuffers *reqbufs);
90
91int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
92 struct v4l2_buffer *buf);
93
94int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
95 struct v4l2_buffer *buf);
96int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
97 struct v4l2_buffer *buf);
98
99int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
100 enum v4l2_buf_type type);
101int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
102 enum v4l2_buf_type type);
103
104unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
105 struct poll_table_struct *wait);
106
107int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
108 struct vm_area_struct *vma);
109
110struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops);
111void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
112
113struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(void *priv, struct v4l2_m2m_dev *m2m_dev,
114 void (*vq_init)(void *priv, struct videobuf_queue *,
115 enum v4l2_buf_type));
116void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
117
118void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct videobuf_queue *vq,
119 struct videobuf_buffer *vb);
120
121/**
122 * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for
123 * use
124 */
125static inline
126unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
127{
128 return m2m_ctx->cap_q_ctx.num_rdy;
129}
130
131/**
132 * v4l2_m2m_num_src_bufs_ready() - return the number of destination buffers
133 * ready for use
134 */
135static inline
136unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
137{
138 return m2m_ctx->out_q_ctx.num_rdy;
139}
140
141void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type);
142
143/**
144 * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready
145 * buffers
146 */
147static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
148{
149 return v4l2_m2m_next_buf(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
150}
151
152/**
153 * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of
154 * ready buffers
155 */
156static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
157{
158 return v4l2_m2m_next_buf(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
159}
160
161/**
162 * v4l2_m2m_get_src_vq() - return videobuf_queue for source buffers
163 */
164static inline
165struct videobuf_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
166{
167 return v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
168}
169
170/**
171 * v4l2_m2m_get_dst_vq() - return videobuf_queue for destination buffers
172 */
173static inline
174struct videobuf_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
175{
176 return v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
177}
178
179void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx,
180 enum v4l2_buf_type type);
181
182/**
183 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
184 * buffers and return it
185 */
186static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
187{
188 return v4l2_m2m_buf_remove(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
189}
190
191/**
192 * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of
193 * ready buffers and return it
194 */
195static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
196{
197 return v4l2_m2m_buf_remove(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
198}
199
200#endif /* _MEDIA_V4L2_MEM2MEM_H */
201
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 2bcdca0a57fc..a88889355ae0 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -184,28 +184,6 @@ struct v4l2_subdev_audio_ops {
184}; 184};
185 185
186/* 186/*
187 decode_vbi_line: video decoders that support sliced VBI need to implement
188 this ioctl. Field p of the v4l2_sliced_vbi_line struct is set to the
189 start of the VBI data that was generated by the decoder. The driver
190 then parses the sliced VBI data and sets the other fields in the
191 struct accordingly. The pointer p is updated to point to the start of
192 the payload which can be copied verbatim into the data field of the
193 v4l2_sliced_vbi_data struct. If no valid VBI data was found, then the
194 type field is set to 0 on return.
195
196 s_vbi_data: used to generate VBI signals on a video signal.
197 v4l2_sliced_vbi_data is filled with the data packets that should be
198 output. Note that if you set the line field to 0, then that VBI signal
199 is disabled. If no valid VBI data was found, then the type field is
200 set to 0 on return.
201
202 g_vbi_data: used to obtain the sliced VBI packet from a readback register.
203 Not all video decoders support this. If no data is available because
204 the readback register contains invalid or erroneous data -EIO is
205 returned. Note that you must fill in the 'id' member and the 'field'
206 member (to determine whether CC data from the first or second field
207 should be obtained).
208
209 s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by 187 s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
210 video input devices. 188 video input devices.
211 189
@@ -243,10 +221,6 @@ struct v4l2_subdev_audio_ops {
243struct v4l2_subdev_video_ops { 221struct v4l2_subdev_video_ops {
244 int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); 222 int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
245 int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags); 223 int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags);
246 int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line);
247 int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data);
248 int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data);
249 int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap);
250 int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); 224 int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std);
251 int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); 225 int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std);
252 int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); 226 int (*g_input_status)(struct v4l2_subdev *sd, u32 *status);
@@ -262,6 +236,8 @@ struct v4l2_subdev_video_ops {
262 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 236 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
263 int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); 237 int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);
264 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); 238 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);
239 int (*enum_dv_presets) (struct v4l2_subdev *sd,
240 struct v4l2_dv_enum_preset *preset);
265 int (*s_dv_preset)(struct v4l2_subdev *sd, 241 int (*s_dv_preset)(struct v4l2_subdev *sd,
266 struct v4l2_dv_preset *preset); 242 struct v4l2_dv_preset *preset);
267 int (*query_dv_preset)(struct v4l2_subdev *sd, 243 int (*query_dv_preset)(struct v4l2_subdev *sd,
@@ -280,6 +256,45 @@ struct v4l2_subdev_video_ops {
280 struct v4l2_mbus_framefmt *fmt); 256 struct v4l2_mbus_framefmt *fmt);
281}; 257};
282 258
259/*
260 decode_vbi_line: video decoders that support sliced VBI need to implement
261 this ioctl. Field p of the v4l2_sliced_vbi_line struct is set to the
262 start of the VBI data that was generated by the decoder. The driver
263 then parses the sliced VBI data and sets the other fields in the
264 struct accordingly. The pointer p is updated to point to the start of
265 the payload which can be copied verbatim into the data field of the
266 v4l2_sliced_vbi_data struct. If no valid VBI data was found, then the
267 type field is set to 0 on return.
268
269 s_vbi_data: used to generate VBI signals on a video signal.
270 v4l2_sliced_vbi_data is filled with the data packets that should be
271 output. Note that if you set the line field to 0, then that VBI signal
272 is disabled. If no valid VBI data was found, then the type field is
273 set to 0 on return.
274
275 g_vbi_data: used to obtain the sliced VBI packet from a readback register.
276 Not all video decoders support this. If no data is available because
277 the readback register contains invalid or erroneous data -EIO is
278 returned. Note that you must fill in the 'id' member and the 'field'
279 member (to determine whether CC data from the first or second field
280 should be obtained).
281
282 s_raw_fmt: setup the video encoder/decoder for raw VBI.
283
284 g_sliced_fmt: retrieve the current sliced VBI settings.
285
286 s_sliced_fmt: setup the sliced VBI settings.
287 */
288struct v4l2_subdev_vbi_ops {
289 int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line);
290 int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data);
291 int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data);
292 int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap);
293 int (*s_raw_fmt)(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
294 int (*g_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
295 int (*s_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
296};
297
283/** 298/**
284 * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations 299 * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations
285 * @g_skip_top_lines: number of lines at the top of the image to be skipped. 300 * @g_skip_top_lines: number of lines at the top of the image to be skipped.
@@ -379,6 +394,7 @@ struct v4l2_subdev_ops {
379 const struct v4l2_subdev_tuner_ops *tuner; 394 const struct v4l2_subdev_tuner_ops *tuner;
380 const struct v4l2_subdev_audio_ops *audio; 395 const struct v4l2_subdev_audio_ops *audio;
381 const struct v4l2_subdev_video_ops *video; 396 const struct v4l2_subdev_video_ops *video;
397 const struct v4l2_subdev_vbi_ops *vbi;
382 const struct v4l2_subdev_ir_ops *ir; 398 const struct v4l2_subdev_ir_ops *ir;
383 const struct v4l2_subdev_sensor_ops *sensor; 399 const struct v4l2_subdev_sensor_ops *sensor;
384}; 400};
@@ -387,6 +403,8 @@ struct v4l2_subdev_ops {
387 403
388/* Set this flag if this subdev is a i2c device. */ 404/* Set this flag if this subdev is a i2c device. */
389#define V4L2_SUBDEV_FL_IS_I2C (1U << 0) 405#define V4L2_SUBDEV_FL_IS_I2C (1U << 0)
406/* Set this flag if this subdev is a spi device. */
407#define V4L2_SUBDEV_FL_IS_SPI (1U << 1)
390 408
391/* Each instance of a subdev driver should create this struct, either 409/* Each instance of a subdev driver should create this struct, either
392 stand-alone or embedded in a larger struct. 410 stand-alone or embedded in a larger struct.
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index 316fdccdcaa0..f91a736c133d 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -127,30 +127,16 @@ struct videobuf_queue_ops {
127struct videobuf_qtype_ops { 127struct videobuf_qtype_ops {
128 u32 magic; 128 u32 magic;
129 129
130 void *(*alloc) (size_t size); 130 struct videobuf_buffer *(*alloc)(size_t size);
131 void *(*vmalloc) (struct videobuf_buffer *buf); 131 void *(*vaddr) (struct videobuf_buffer *buf);
132 int (*iolock) (struct videobuf_queue* q, 132 int (*iolock) (struct videobuf_queue *q,
133 struct videobuf_buffer *vb, 133 struct videobuf_buffer *vb,
134 struct v4l2_framebuffer *fbuf); 134 struct v4l2_framebuffer *fbuf);
135 int (*mmap) (struct videobuf_queue *q, 135 int (*sync) (struct videobuf_queue *q,
136 unsigned int *count,
137 unsigned int *size,
138 enum v4l2_memory memory);
139 int (*sync) (struct videobuf_queue* q,
140 struct videobuf_buffer *buf); 136 struct videobuf_buffer *buf);
141 int (*video_copy_to_user)(struct videobuf_queue *q,
142 char __user *data,
143 size_t count,
144 int nonblocking);
145 int (*copy_stream) (struct videobuf_queue *q,
146 char __user *data,
147 size_t count,
148 size_t pos,
149 int vbihack,
150 int nonblocking);
151 int (*mmap_free) (struct videobuf_queue *q);
152 int (*mmap_mapper) (struct videobuf_queue *q, 137 int (*mmap_mapper) (struct videobuf_queue *q,
153 struct vm_area_struct *vma); 138 struct videobuf_buffer *buf,
139 struct vm_area_struct *vma);
154}; 140};
155 141
156struct videobuf_queue { 142struct videobuf_queue {
@@ -171,7 +157,6 @@ struct videobuf_queue {
171 157
172 unsigned int streaming:1; 158 unsigned int streaming:1;
173 unsigned int reading:1; 159 unsigned int reading:1;
174 unsigned int is_mmapped:1;
175 160
176 /* capture via mmap() + ioctl(QBUF/DQBUF) */ 161 /* capture via mmap() + ioctl(QBUF/DQBUF) */
177 struct list_head stream; 162 struct list_head stream;
@@ -185,14 +170,14 @@ struct videobuf_queue {
185}; 170};
186 171
187int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); 172int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
188int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, 173int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
189 struct v4l2_framebuffer *fbuf); 174 struct v4l2_framebuffer *fbuf);
190 175
191void *videobuf_alloc(struct videobuf_queue* q); 176struct videobuf_buffer *videobuf_alloc(struct videobuf_queue *q);
192 177
193/* Used on videobuf-dvb */ 178/* Used on videobuf-dvb */
194void *videobuf_queue_to_vmalloc (struct videobuf_queue* q, 179void *videobuf_queue_to_vaddr(struct videobuf_queue *q,
195 struct videobuf_buffer *buf); 180 struct videobuf_buffer *buf);
196 181
197void videobuf_queue_core_init(struct videobuf_queue *q, 182void videobuf_queue_core_init(struct videobuf_queue *q,
198 const struct videobuf_queue_ops *ops, 183 const struct videobuf_queue_ops *ops,
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
index 53e72f787175..a195f3b9c00a 100644
--- a/include/media/videobuf-dma-sg.h
+++ b/include/media/videobuf-dma-sg.h
@@ -17,6 +17,8 @@
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 18 * the Free Software Foundation; either version 2
19 */ 19 */
20#ifndef _VIDEOBUF_DMA_SG_H
21#define _VIDEOBUF_DMA_SG_H
20 22
21#include <media/videobuf-core.h> 23#include <media/videobuf-core.h>
22 24
@@ -27,14 +29,14 @@
27 * block (NULL on errors). Memory for the scatterlist is allocated 29 * block (NULL on errors). Memory for the scatterlist is allocated
28 * using kmalloc. The caller must free the memory. 30 * using kmalloc. The caller must free the memory.
29 */ 31 */
30struct scatterlist* videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages); 32struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages);
31 33
32/* 34/*
33 * Return a scatterlist for a an array of userpages (NULL on errors). 35 * Return a scatterlist for a an array of userpages (NULL on errors).
34 * Memory for the scatterlist is allocated using kmalloc. The caller 36 * Memory for the scatterlist is allocated using kmalloc. The caller
35 * must free the memory. 37 * must free the memory.
36 */ 38 */
37struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages, 39struct scatterlist *videobuf_pages_to_sg(struct page **pages, int nr_pages,
38 int offset); 40 int offset);
39 41
40/* --------------------------------------------------------------------- */ 42/* --------------------------------------------------------------------- */
@@ -78,8 +80,7 @@ struct videobuf_dmabuf {
78 int direction; 80 int direction;
79}; 81};
80 82
81struct videobuf_dma_sg_memory 83struct videobuf_dma_sg_memory {
82{
83 u32 magic; 84 u32 magic;
84 85
85 /* for mmap'ed buffers */ 86 /* for mmap'ed buffers */
@@ -95,14 +96,13 @@ int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
95 dma_addr_t addr, int nr_pages); 96 dma_addr_t addr, int nr_pages);
96int videobuf_dma_free(struct videobuf_dmabuf *dma); 97int videobuf_dma_free(struct videobuf_dmabuf *dma);
97 98
98int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma); 99int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma);
99int videobuf_dma_sync(struct videobuf_queue* q,struct videobuf_dmabuf *dma); 100int videobuf_dma_unmap(struct videobuf_queue *q, struct videobuf_dmabuf *dma);
100int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma); 101struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
101struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf);
102 102
103void *videobuf_sg_alloc(size_t size); 103void *videobuf_sg_alloc(size_t size);
104 104
105void videobuf_queue_sg_init(struct videobuf_queue* q, 105void videobuf_queue_sg_init(struct videobuf_queue *q,
106 const struct videobuf_queue_ops *ops, 106 const struct videobuf_queue_ops *ops,
107 struct device *dev, 107 struct device *dev,
108 spinlock_t *irqlock, 108 spinlock_t *irqlock,
@@ -111,9 +111,11 @@ void videobuf_queue_sg_init(struct videobuf_queue* q,
111 unsigned int msize, 111 unsigned int msize,
112 void *priv); 112 void *priv);
113 113
114 /*FIXME: these variants are used only on *-alsa code, where videobuf is 114/*FIXME: these variants are used only on *-alsa code, where videobuf is
115 * used without queue 115 * used without queue
116 */ 116 */
117int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma); 117int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma);
118int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma); 118int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma);
119 119
120#endif /* _VIDEOBUF_DMA_SG_H */
121
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
index 4b419a257a7d..851eb1a2ff2a 100644
--- a/include/media/videobuf-vmalloc.h
+++ b/include/media/videobuf-vmalloc.h
@@ -19,17 +19,17 @@
19 19
20/* --------------------------------------------------------------------- */ 20/* --------------------------------------------------------------------- */
21 21
22struct videobuf_vmalloc_memory 22struct videobuf_vmalloc_memory {
23{
24 u32 magic; 23 u32 magic;
25 24
26 void *vmalloc; 25 void *vmalloc;
27 26
28 /* remap_vmalloc_range seems to need to run after mmap() on some cases */ 27 /* remap_vmalloc_range seems to need to run
28 * after mmap() on some cases */
29 struct vm_area_struct *vma; 29 struct vm_area_struct *vma;
30}; 30};
31 31
32void videobuf_queue_vmalloc_init(struct videobuf_queue* q, 32void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
33 const struct videobuf_queue_ops *ops, 33 const struct videobuf_queue_ops *ops,
34 struct device *dev, 34 struct device *dev,
35 spinlock_t *irqlock, 35 spinlock_t *irqlock,
@@ -38,8 +38,8 @@ void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
38 unsigned int msize, 38 unsigned int msize,
39 void *priv); 39 void *priv);
40 40
41void *videobuf_to_vmalloc (struct videobuf_buffer *buf); 41void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
42 42
43void videobuf_vmalloc_free (struct videobuf_buffer *buf); 43void videobuf_vmalloc_free(struct videobuf_buffer *buf);
44 44
45#endif 45#endif