summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2010-12-13 12:02:38 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2010-12-13 12:02:38 +1100
commit44e6b417519ac94e33bb6b0e37d54112ee8eb976 (patch)
tree1512781c207be21e696093842c3cf291f03f4d57 /drivers
parent04dccdec470a9370c01c9fabfed14ab1447ae95c (diff)
parent3c91560bf96a1f7ad39131e7730fd319647ff734 (diff)
Merge remote branch 'v4l-dvb/master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/Kconfig18
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/media/IR/ir-functions.c356
-rw-r--r--drivers/media/IR/ir-keytable.c710
-rw-r--r--drivers/media/IR/ir-sysfs.c362
-rw-r--r--drivers/media/IR/keymaps/rc-tbs-nec.c73
-rw-r--r--drivers/media/IR/rc-map.c107
-rw-r--r--drivers/media/Kconfig2
-rw-r--r--drivers/media/Makefile2
-rw-r--r--drivers/media/common/saa7146_hlp.c8
-rw-r--r--drivers/media/common/saa7146_video.c16
-rw-r--r--drivers/media/common/tuners/max2165.c10
-rw-r--r--drivers/media/dvb/dm1105/Kconfig3
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c44
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig10
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-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.c16
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.h4
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c22
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c4
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.c6
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c6
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c62
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c146
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c16
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c14
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c103
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h29
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c54
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c28
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.h8
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c202
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c24
-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/technisat-usb2.c807
-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/frontends/Kconfig10
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/atbm8830.c8
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c51
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h2
-rw-r--r--drivers/media/dvb/frontends/ix2505v.c2
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c11
-rw-r--r--drivers/media/dvb/frontends/mb86a20s.c615
-rw-r--r--drivers/media/dvb/frontends/mb86a20s.h52
-rw-r--r--drivers/media/dvb/frontends/s921.c548
-rw-r--r--drivers/media/dvb/frontends/s921.h47
-rw-r--r--drivers/media/dvb/frontends/s921_core.c216
-rw-r--r--drivers/media/dvb/frontends/s921_core.h114
-rw-r--r--drivers/media/dvb/frontends/s921_module.c192
-rw-r--r--drivers/media/dvb/frontends/s921_module.h49
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c2
-rw-r--r--drivers/media/dvb/frontends/stb6100.c198
-rw-r--r--drivers/media/dvb/frontends/stv090x.c22
-rw-r--r--drivers/media/dvb/frontends/stv090x.h15
-rw-r--r--drivers/media/dvb/mantis/Kconfig2
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c2
-rw-r--r--drivers/media/dvb/mantis/hopper_vp3028.c6
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_common.h4
-rw-r--r--drivers/media/dvb/mantis/mantis_dvb.c17
-rw-r--r--drivers/media/dvb/mantis/mantis_input.c76
-rw-r--r--drivers/media/dvb/mantis/mantis_ioc.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_ioc.h2
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1033.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1034.c10
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1041.c6
-rw-r--r--drivers/media/dvb/mantis/mantis_vp2033.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_vp2040.c4
-rw-r--r--drivers/media/dvb/mantis/mantis_vp3030.c8
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c5
-rw-r--r--drivers/media/dvb/siano/Kconfig2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c2
-rw-r--r--drivers/media/dvb/siano/smsir.c52
-rw-r--r--drivers/media/dvb/siano/smsir.h5
-rw-r--r--drivers/media/dvb/siano/smsusb.c9
-rw-r--r--drivers/media/dvb/ttpci/Kconfig3
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c53
-rw-r--r--drivers/media/radio/radio-aimslab.c16
-rw-r--r--drivers/media/radio/radio-aztech.c6
-rw-r--r--drivers/media/radio/radio-cadet.c12
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c6
-rw-r--r--drivers/media/radio/radio-gemtek.c14
-rw-r--r--drivers/media/radio/radio-maestro.c14
-rw-r--r--drivers/media/radio/radio-maxiradio.c2
-rw-r--r--drivers/media/radio/radio-miropcm20.c6
-rw-r--r--drivers/media/radio/radio-rtrack2.c10
-rw-r--r--drivers/media/radio/radio-sf16fmi.c7
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c11
-rw-r--r--drivers/media/radio/radio-si4713.c3
-rw-r--r--drivers/media/radio/radio-tea5764.c49
-rw-r--r--drivers/media/radio/radio-terratec.c8
-rw-r--r--drivers/media/radio/radio-timb.c5
-rw-r--r--drivers/media/radio/radio-trust.c18
-rw-r--r--drivers/media/radio/radio-typhoon.c16
-rw-r--r--drivers/media/radio/radio-zoltrix.c30
-rw-r--r--drivers/media/radio/si4713-i2c.c74
-rw-r--r--drivers/media/radio/si4713-i2c.h5
-rw-r--r--drivers/media/rc/Kconfig (renamed from drivers/media/IR/Kconfig)70
-rw-r--r--drivers/media/rc/Makefile (renamed from drivers/media/IR/Makefile)8
-rw-r--r--drivers/media/rc/ene_ir.c (renamed from drivers/media/IR/ene_ir.c)131
-rw-r--r--drivers/media/rc/ene_ir.h (renamed from drivers/media/IR/ene_ir.h)3
-rw-r--r--drivers/media/rc/imon.c (renamed from drivers/media/IR/imon.c)107
-rw-r--r--drivers/media/rc/ir-jvc-decoder.c (renamed from drivers/media/IR/ir-jvc-decoder.c)17
-rw-r--r--drivers/media/rc/ir-lirc-codec.c (renamed from drivers/media/IR/ir-lirc-codec.c)127
-rw-r--r--drivers/media/rc/ir-nec-decoder.c (renamed from drivers/media/IR/ir-nec-decoder.c)19
-rw-r--r--drivers/media/rc/ir-raw.c (renamed from drivers/media/IR/ir-raw-event.c)197
-rw-r--r--drivers/media/rc/ir-rc5-decoder.c (renamed from drivers/media/IR/ir-rc5-decoder.c)17
-rw-r--r--drivers/media/rc/ir-rc5-sz-decoder.c (renamed from drivers/media/IR/ir-rc5-sz-decoder.c)17
-rw-r--r--drivers/media/rc/ir-rc6-decoder.c (renamed from drivers/media/IR/ir-rc6-decoder.c)21
-rw-r--r--drivers/media/rc/ir-sony-decoder.c (renamed from drivers/media/IR/ir-sony-decoder.c)15
-rw-r--r--drivers/media/rc/keymaps/Kconfig (renamed from drivers/media/IR/keymaps/Kconfig)2
-rw-r--r--drivers/media/rc/keymaps/Makefile (renamed from drivers/media/IR/keymaps/Makefile)1
-rw-r--r--drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c (renamed from drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-alink-dtu-m.c (renamed from drivers/media/IR/keymaps/rc-alink-dtu-m.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-anysee.c (renamed from drivers/media/IR/keymaps/rc-anysee.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-apac-viewcomp.c (renamed from drivers/media/IR/keymaps/rc-apac-viewcomp.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-asus-pc39.c (renamed from drivers/media/IR/keymaps/rc-asus-pc39.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c (renamed from drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-a16d.c (renamed from drivers/media/IR/keymaps/rc-avermedia-a16d.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-cardbus.c (renamed from drivers/media/IR/keymaps/rc-avermedia-cardbus.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-dvbt.c (renamed from drivers/media/IR/keymaps/rc-avermedia-dvbt.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m135a.c (renamed from drivers/media/IR/keymaps/rc-avermedia-m135a.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c (renamed from drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-rm-ks.c (renamed from drivers/media/IR/keymaps/rc-avermedia-rm-ks.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia.c (renamed from drivers/media/IR/keymaps/rc-avermedia.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-avertv-303.c (renamed from drivers/media/IR/keymaps/rc-avertv-303.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c (renamed from drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-behold-columbus.c (renamed from drivers/media/IR/keymaps/rc-behold-columbus.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-behold.c (renamed from drivers/media/IR/keymaps/rc-behold.c)78
-rw-r--r--drivers/media/rc/keymaps/rc-budget-ci-old.c (renamed from drivers/media/IR/keymaps/rc-budget-ci-old.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy-1400.c (renamed from drivers/media/IR/keymaps/rc-cinergy-1400.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy.c (renamed from drivers/media/IR/keymaps/rc-cinergy.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dib0700-nec.c (renamed from drivers/media/IR/keymaps/rc-dib0700-nec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dib0700-rc5.c (renamed from drivers/media/IR/keymaps/rc-dib0700-rc5.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c (renamed from drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-digittrade.c (renamed from drivers/media/IR/keymaps/rc-digittrade.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dm1105-nec.c (renamed from drivers/media/IR/keymaps/rc-dm1105-nec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c (renamed from drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c (renamed from drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-em-terratec.c (renamed from drivers/media/IR/keymaps/rc-em-terratec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv-fm53.c (renamed from drivers/media/IR/keymaps/rc-encore-enltv-fm53.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv.c (renamed from drivers/media/IR/keymaps/rc-encore-enltv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv2.c (renamed from drivers/media/IR/keymaps/rc-encore-enltv2.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-evga-indtube.c (renamed from drivers/media/IR/keymaps/rc-evga-indtube.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-eztv.c (renamed from drivers/media/IR/keymaps/rc-eztv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-flydvb.c (renamed from drivers/media/IR/keymaps/rc-flydvb.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-flyvideo.c (renamed from drivers/media/IR/keymaps/rc-flyvideo.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-fusionhdtv-mce.c (renamed from drivers/media/IR/keymaps/rc-fusionhdtv-mce.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-gadmei-rm008z.c (renamed from drivers/media/IR/keymaps/rc-gadmei-rm008z.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c (renamed from drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-gotview7135.c (renamed from drivers/media/IR/keymaps/rc-gotview7135.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge-new.c (renamed from drivers/media/IR/keymaps/rc-hauppauge-new.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-imon-mce.c (renamed from drivers/media/IR/keymaps/rc-imon-mce.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-imon-pad.c (renamed from drivers/media/IR/keymaps/rc-imon-pad.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-iodata-bctv7e.c (renamed from drivers/media/IR/keymaps/rc-iodata-bctv7e.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-kaiomy.c (renamed from drivers/media/IR/keymaps/rc-kaiomy.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-315u.c (renamed from drivers/media/IR/keymaps/rc-kworld-315u.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c (renamed from drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-leadtek-y04g0051.c (renamed from drivers/media/IR/keymaps/rc-leadtek-y04g0051.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-lirc.c (renamed from drivers/media/IR/keymaps/rc-lirc.c)12
-rw-r--r--drivers/media/rc/keymaps/rc-lme2510.c (renamed from drivers/media/IR/keymaps/rc-lme2510.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-manli.c (renamed from drivers/media/IR/keymaps/rc-manli.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-digivox-ii.c (renamed from drivers/media/IR/keymaps/rc-msi-digivox-ii.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-digivox-iii.c (renamed from drivers/media/IR/keymaps/rc-msi-digivox-iii.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c (renamed from drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere.c (renamed from drivers/media/IR/keymaps/rc-msi-tvanywhere.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-nebula.c (renamed from drivers/media/IR/keymaps/rc-nebula.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c (renamed from drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-norwood.c (renamed from drivers/media/IR/keymaps/rc-norwood.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-npgtech.c (renamed from drivers/media/IR/keymaps/rc-npgtech.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pctv-sedna.c (renamed from drivers/media/IR/keymaps/rc-pctv-sedna.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-color.c (renamed from drivers/media/IR/keymaps/rc-pinnacle-color.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-grey.c (renamed from drivers/media/IR/keymaps/rc-pinnacle-grey.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c (renamed from drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-mk12.c (renamed from drivers/media/IR/keymaps/rc-pixelview-mk12.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-new.c (renamed from drivers/media/IR/keymaps/rc-pixelview-new.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview.c (renamed from drivers/media/IR/keymaps/rc-pixelview.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-powercolor-real-angel.c (renamed from drivers/media/IR/keymaps/rc-powercolor-real-angel.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-proteus-2309.c (renamed from drivers/media/IR/keymaps/rc-proteus-2309.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-purpletv.c (renamed from drivers/media/IR/keymaps/rc-purpletv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-pv951.c (renamed from drivers/media/IR/keymaps/rc-pv951.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c (renamed from drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c)48
-rw-r--r--drivers/media/rc/keymaps/rc-rc5-tv.c (renamed from drivers/media/IR/keymaps/rc-rc5-tv.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-rc6-mce.c (renamed from drivers/media/IR/keymaps/rc-rc6-mce.c)31
-rw-r--r--drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c (renamed from drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-streamzap.c (renamed from drivers/media/IR/keymaps/rc-streamzap.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-tbs-nec.c75
-rw-r--r--drivers/media/rc/keymaps/rc-technisat-usb2.c93
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c (renamed from drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-slim.c (renamed from drivers/media/IR/keymaps/rc-terratec-slim.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-tevii-nec.c (renamed from drivers/media/IR/keymaps/rc-tevii-nec.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-total-media-in-hand.c (renamed from drivers/media/IR/keymaps/rc-total-media-in-hand.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-trekstor.c (renamed from drivers/media/IR/keymaps/rc-trekstor.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-tt-1500.c (renamed from drivers/media/IR/keymaps/rc-tt-1500.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-twinhan1027.c (renamed from drivers/media/IR/keymaps/rc-twinhan1027.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-s350.c (renamed from drivers/media/IR/keymaps/rc-videomate-s350.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-tv-pvr.c (renamed from drivers/media/IR/keymaps/rc-videomate-tv-pvr.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c (renamed from drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c)10
-rw-r--r--drivers/media/rc/keymaps/rc-winfast.c (renamed from drivers/media/IR/keymaps/rc-winfast.c)10
-rw-r--r--drivers/media/rc/lirc_dev.c (renamed from drivers/media/IR/lirc_dev.c)37
-rw-r--r--drivers/media/rc/mceusb.c (renamed from drivers/media/IR/mceusb.c)241
-rw-r--r--drivers/media/rc/nuvoton-cir.c (renamed from drivers/media/IR/nuvoton-cir.c)104
-rw-r--r--drivers/media/rc/nuvoton-cir.h (renamed from drivers/media/IR/nuvoton-cir.h)3
-rw-r--r--drivers/media/rc/rc-core-priv.h (renamed from drivers/media/IR/ir-core-priv.h)34
-rw-r--r--drivers/media/rc/rc-loopback.c260
-rw-r--r--drivers/media/rc/rc-main.c1135
-rw-r--r--drivers/media/rc/streamzap.c (renamed from drivers/media/IR/streamzap.c)86
-rw-r--r--drivers/media/rc/winbond-cir.c (renamed from drivers/input/misc/winbond-cir.c)886
-rw-r--r--drivers/media/video/Kconfig12
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/arv.c2
-rw-r--r--drivers/media/video/au0828/au0828-video.c106
-rw-r--r--drivers/media/video/au0828/au0828.h6
-rw-r--r--drivers/media/video/bt8xx/Kconfig4
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c6
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c226
-rw-r--r--drivers/media/video/bt8xx/bttv.h1
-rw-r--r--drivers/media/video/bt8xx/bttvp.h34
-rw-r--r--drivers/media/video/bw-qcam.c2
-rw-r--r--drivers/media/video/c-qcam.c2
-rw-r--r--drivers/media/video/cafe_ccic.c7
-rw-r--r--drivers/media/video/cx18/Kconfig3
-rw-r--r--drivers/media/video/cx18/cx18-alsa-pcm.c8
-rw-r--r--drivers/media/video/cx18/cx18-cards.c63
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.h4
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c32
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-streams.c2
-rw-r--r--drivers/media/video/cx231xx/Kconfig19
-rw-r--r--drivers/media/video/cx231xx/Makefile5
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c65
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c40
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c101
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h26
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c70
-rw-r--r--drivers/media/video/cx23885/cx23885.h5
-rw-r--r--drivers/media/video/cx23885/cx23888-ir.c2
-rw-r--r--drivers/media/video/cx25840/cx25840-ir.c2
-rw-r--r--drivers/media/video/cx88/Kconfig3
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c2
-rw-r--r--drivers/media/video/cx88/cx88-input.c241
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2
-rw-r--r--drivers/media/video/em28xx/Kconfig5
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c72
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c16
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c78
-rw-r--r--drivers/media/video/em28xx/em28xx.h4
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c2
-rw-r--r--drivers/media/video/gspca/cpia1.c12
-rw-r--r--drivers/media/video/gspca/gspca.c20
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c2
-rw-r--r--drivers/media/video/gspca/ov519.c1679
-rw-r--r--drivers/media/video/gspca/pac207.c4
-rw-r--r--drivers/media/video/gspca/sn9c20x.c141
-rw-r--r--drivers/media/video/gspca/sonixb.c4
-rw-r--r--drivers/media/video/gspca/sonixj.c18
-rw-r--r--drivers/media/video/gspca/spca561.c2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c57
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h11
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c18
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h3
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h4
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c21
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.h3
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h9
-rw-r--r--drivers/media/video/gspca/t613.c2
-rw-r--r--drivers/media/video/gspca/tv8532.c2
-rw-r--r--drivers/media/video/gspca/w996Xcf.c325
-rw-r--r--drivers/media/video/gspca/xirlink_cit.c194
-rw-r--r--drivers/media/video/gspca/zc3xx.c2
-rw-r--r--drivers/media/video/imx074.c1
-rw-r--r--drivers/media/video/ir-kbd-i2c.c75
-rw-r--r--drivers/media/video/ivtv/Kconfig3
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c6
-rw-r--r--drivers/media/video/meye.c14
-rw-r--r--drivers/media/video/mt9m001.c1
-rw-r--r--drivers/media/video/mt9m111.c1
-rw-r--r--drivers/media/video/mt9t031.c1
-rw-r--r--drivers/media/video/mt9v022.c1
-rw-r--r--drivers/media/video/mx2_camera.c2
-rw-r--r--drivers/media/video/mx3_camera.c3
-rw-r--r--drivers/media/video/pms.c2
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c7
-rw-r--r--drivers/media/video/pwc/pwc-if.c68
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c13
-rw-r--r--drivers/media/video/pwc/pwc.h1
-rw-r--r--drivers/media/video/rj54n1cb0c.c1
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c2
-rw-r--r--drivers/media/video/saa7134/Kconfig2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c110
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c69
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c430
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c12
-rw-r--r--drivers/media/video/saa7134/saa7134.h25
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c123
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c92
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c16
-rw-r--r--drivers/media/video/saa7164/saa7164-cards.c2
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c10
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c40
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c33
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-i2c.c4
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c37
-rw-r--r--drivers/media/video/saa7164/saa7164.h17
-rw-r--r--drivers/media/video/sh_vou.c13
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c2
-rw-r--r--drivers/media/video/sr030pc30.c2
-rw-r--r--drivers/media/video/tea6415c.c2
-rw-r--r--drivers/media/video/timblogiw.c894
-rw-r--r--drivers/media/video/tlg2300/Kconfig4
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c48
-rw-r--r--drivers/media/video/uvc/uvc_queue.c133
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c185
-rw-r--r--drivers/media/video/uvc/uvc_video.c3
-rw-r--r--drivers/media/video/uvc/uvcvideo.h10
-rw-r--r--drivers/media/video/v4l2-dev.c69
-rw-r--r--drivers/media/video/v4l2-device.c1
-rw-r--r--drivers/media/video/videobuf-dma-sg.c3
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/mfd/timberdale.c61
-rw-r--r--drivers/mfd/timberdale.h2
-rw-r--r--drivers/staging/cx25821/Kconfig4
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c71
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c66
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c2
-rw-r--r--drivers/staging/cx25821/cx25821-core.c191
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c19
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c7
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c63
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c90
-rw-r--r--drivers/staging/cx25821/cx25821-video.c90
-rw-r--r--drivers/staging/cx25821/cx25821-video.h11
-rw-r--r--drivers/staging/cx25821/cx25821.h9
-rw-r--r--drivers/staging/go7007/Kconfig4
-rw-r--r--drivers/staging/tm6000/Kconfig2
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c7
-rw-r--r--drivers/staging/tm6000/tm6000-core.c27
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c39
-rw-r--r--drivers/staging/tm6000/tm6000-input.c100
358 files changed, 10513 insertions, 7624 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index b99b8cbde02f..c1a81bcdb319 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -294,24 +294,6 @@ config INPUT_SGI_BTNS
To compile this driver as a module, choose M here: the
module will be called sgi_btns.
-config INPUT_WINBOND_CIR
- tristate "Winbond IR remote control"
- depends on X86 && PNP
- select NEW_LEDS
- select LEDS_CLASS
- select LEDS_TRIGGERS
- select BITREVERSE
- help
- Say Y here if you want to use the IR remote functionality found
- in some Winbond SuperI/O chips. Currently only the WPCD376I
- chip is supported (included in some Intel Media series motherboards).
-
- IR Receive and wake-on-IR from suspend and power-off is currently
- supported.
-
- To compile this driver as a module, choose M here: the module will be
- called winbond_cir.
-
config HP_SDC_RTC
tristate "HP SDC Real Time Clock"
depends on (GSC || HP300) && SERIO
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 1fe1f6c8b737..06b2b5154038 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
deleted file mode 100644
index db591e421887..000000000000
--- a/drivers/media/IR/ir-functions.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- *
- * some common structs and functions to handle infrared remotes via
- * input layer ...
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/jiffies.h>
-#include <media/ir-common.h>
-#include "ir-core-priv.h"
-
-/* -------------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static int repeat = 1;
-module_param(repeat, int, 0444);
-MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
-
-/* -------------------------------------------------------------------------- */
-
-static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
-{
- if (KEY_RESERVED == ir->keycode) {
- printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
- dev->name, ir->ir_key, ir->keypressed);
- return;
- }
- IR_dprintk(1,"%s: key event code=%d down=%d\n",
- dev->name,ir->keycode,ir->keypressed);
- input_report_key(dev,ir->keycode,ir->keypressed);
- input_sync(dev);
-}
-
-/* -------------------------------------------------------------------------- */
-
-int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
- const u64 ir_type)
-{
- ir->ir_type = ir_type;
-
- if (repeat)
- set_bit(EV_REP, dev->evbit);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ir_input_init);
-
-
-void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
-{
- if (ir->keypressed) {
- ir->keypressed = 0;
- ir_input_key_event(dev,ir);
- }
-}
-EXPORT_SYMBOL_GPL(ir_input_nokey);
-
-void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
- u32 ir_key)
-{
- u32 keycode = ir_g_keycode_from_table(dev, ir_key);
-
- if (ir->keypressed && ir->keycode != keycode) {
- ir->keypressed = 0;
- ir_input_key_event(dev,ir);
- }
- if (!ir->keypressed) {
- ir->ir_key = ir_key;
- ir->keycode = keycode;
- ir->keypressed = 1;
- ir_input_key_event(dev,ir);
- }
-}
-EXPORT_SYMBOL_GPL(ir_input_keydown);
-
-/* -------------------------------------------------------------------------- */
-/* extract mask bits out of data and pack them into the result */
-u32 ir_extract_bits(u32 data, u32 mask)
-{
- u32 vbit = 1, value = 0;
-
- do {
- if (mask&1) {
- if (data&1)
- value |= vbit;
- vbit<<=1;
- }
- data>>=1;
- } while (mask>>=1);
-
- return value;
-}
-EXPORT_SYMBOL_GPL(ir_extract_bits);
-
-static int inline getbit(u32 *samples, int bit)
-{
- return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
-}
-
-/* sump raw samples for visual debugging ;) */
-int ir_dump_samples(u32 *samples, int count)
-{
- int i, bit, start;
-
- printk(KERN_DEBUG "ir samples: ");
- start = 0;
- for (i = 0; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (bit)
- start = 1;
- if (0 == start)
- continue;
- printk("%s", bit ? "#" : "_");
- }
- printk("\n");
- return 0;
-}
-EXPORT_SYMBOL_GPL(ir_dump_samples);
-
-/* decode raw samples, pulse distance coding used by NEC remotes */
-int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
-{
- int i,last,bit,len;
- u32 curBit;
- u32 value;
-
- /* find start burst */
- for (i = len = 0; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (bit) {
- len++;
- } else {
- if (len >= 29)
- break;
- len = 0;
- }
- }
-
- /* start burst to short */
- if (len < 29)
- return 0xffffffff;
-
- /* find start silence */
- for (len = 0; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (bit) {
- break;
- } else {
- len++;
- }
- }
-
- /* silence to short */
- if (len < 7)
- return 0xffffffff;
-
- /* go decoding */
- len = 0;
- last = 1;
- value = 0; curBit = 1;
- for (; i < count * 32; i++) {
- bit = getbit(samples,i);
- if (last) {
- if(bit) {
- continue;
- } else {
- len = 1;
- }
- } else {
- if (bit) {
- if (len > (low + high) /2)
- value |= curBit;
- curBit <<= 1;
- if (curBit == 1)
- break;
- } else {
- len++;
- }
- }
- last = bit;
- }
-
- return value;
-}
-EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
-
-/* decode raw samples, biphase coding, used by rc5 for example */
-int ir_decode_biphase(u32 *samples, int count, int low, int high)
-{
- int i,last,bit,len,flips;
- u32 value;
-
- /* find start bit (1) */
- for (i = 0; i < 32; i++) {
- bit = getbit(samples,i);
- if (bit)
- break;
- }
-
- /* go decoding */
- len = 0;
- flips = 0;
- value = 1;
- for (; i < count * 32; i++) {
- if (len > high)
- break;
- if (flips > 1)
- break;
- last = bit;
- bit = getbit(samples,i);
- if (last == bit) {
- len++;
- continue;
- }
- if (len < low) {
- len++;
- flips++;
- continue;
- }
- value <<= 1;
- value |= bit;
- flips = 0;
- len = 1;
- }
- return value;
-}
-EXPORT_SYMBOL_GPL(ir_decode_biphase);
-
-/* RC5 decoding stuff, moved from bttv-input.c to share it with
- * saa7134 */
-
-/* decode raw bit pattern to RC5 code */
-u32 ir_rc5_decode(unsigned int code)
-{
- unsigned int org_code = code;
- unsigned int pair;
- unsigned int rc5 = 0;
- int i;
-
- for (i = 0; i < 14; ++i) {
- pair = code & 0x3;
- code >>= 2;
-
- rc5 <<= 1;
- switch (pair) {
- case 0:
- case 2:
- break;
- case 1:
- rc5 |= 1;
- break;
- case 3:
- IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
- return 0;
- }
- }
- IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
- "instr=%x\n", rc5, org_code, RC5_START(rc5),
- RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
- return rc5;
-}
-EXPORT_SYMBOL_GPL(ir_rc5_decode);
-
-void ir_rc5_timer_end(unsigned long data)
-{
- struct card_ir *ir = (struct card_ir *)data;
- struct timeval tv;
- unsigned long current_jiffies, timeout;
- u32 gap;
- u32 rc5 = 0;
-
- /* get time */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* signal we're ready to start a new code */
- ir->active = 0;
-
- /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
- if (gap < 28000) {
- IR_dprintk(1, "ir-common: spurious timer_end\n");
- return;
- }
-
- if (ir->last_bit < 20) {
- /* ignore spurious codes (caused by light/other remotes) */
- IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
- } else {
- ir->code = (ir->code << ir->shift_by) | 1;
- rc5 = ir_rc5_decode(ir->code);
-
- /* two start bits? */
- if (RC5_START(rc5) != ir->start) {
- IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
-
- /* right address? */
- } else if (RC5_ADDR(rc5) == ir->addr) {
- u32 toggle = RC5_TOGGLE(rc5);
- u32 instr = RC5_INSTR(rc5);
-
- /* Good code, decide if repeat/repress */
- if (toggle != RC5_TOGGLE(ir->last_rc5) ||
- instr != RC5_INSTR(ir->last_rc5)) {
- IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
- toggle);
- ir_input_nokey(ir->dev, &ir->ir);
- ir_input_keydown(ir->dev, &ir->ir, instr);
- }
-
- /* Set/reset key-up timer */
- timeout = current_jiffies +
- msecs_to_jiffies(ir->rc5_key_timeout);
- mod_timer(&ir->timer_keyup, timeout);
-
- /* Save code for repeat test */
- ir->last_rc5 = rc5;
- }
- }
-}
-EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
-
-void ir_rc5_timer_keyup(unsigned long data)
-{
- struct card_ir *ir = (struct card_ir *)data;
-
- IR_dprintk(1, "ir-common: key released\n");
- ir_input_nokey(ir->dev, &ir->ir);
-}
-EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
deleted file mode 100644
index f60107c3b091..000000000000
--- a/drivers/media/IR/ir-keytable.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/* ir-keytable.c - handle IR scancode->keycode tables
- *
- * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-
-#include <linux/input.h>
-#include <linux/slab.h>
-#include "ir-core-priv.h"
-
-/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
-#define IR_TAB_MIN_SIZE 256
-#define IR_TAB_MAX_SIZE 8192
-
-/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
-#define IR_KEYPRESS_TIMEOUT 250
-
-/**
- * ir_create_table() - initializes a scancode table
- * @rc_tab: the ir_scancode_table to initialize
- * @name: name to assign to the table
- * @ir_type: ir type to assign to the new table
- * @size: initial size of the table
- * @return: zero on success or a negative error code
- *
- * This routine will initialize the ir_scancode_table and will allocate
- * memory to hold at least the specified number elements.
- */
-static int ir_create_table(struct ir_scancode_table *rc_tab,
- const char *name, u64 ir_type, size_t size)
-{
- rc_tab->name = name;
- rc_tab->ir_type = ir_type;
- rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode));
- rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
- rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL);
- if (!rc_tab->scan)
- return -ENOMEM;
-
- IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
- rc_tab->size, rc_tab->alloc);
- return 0;
-}
-
-/**
- * ir_free_table() - frees memory allocated by a scancode table
- * @rc_tab: the table whose mappings need to be freed
- *
- * This routine will free memory alloctaed for key mappings used by given
- * scancode table.
- */
-static void ir_free_table(struct ir_scancode_table *rc_tab)
-{
- rc_tab->size = 0;
- kfree(rc_tab->scan);
- rc_tab->scan = NULL;
-}
-
-/**
- * ir_resize_table() - resizes a scancode table if necessary
- * @rc_tab: the ir_scancode_table to resize
- * @gfp_flags: gfp flags to use when allocating memory
- * @return: zero on success or a negative error code
- *
- * This routine will shrink the ir_scancode_table if it has lots of
- * unused entries and grow it if it is full.
- */
-static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags)
-{
- unsigned int oldalloc = rc_tab->alloc;
- unsigned int newalloc = oldalloc;
- struct ir_scancode *oldscan = rc_tab->scan;
- struct ir_scancode *newscan;
-
- if (rc_tab->size == rc_tab->len) {
- /* All entries in use -> grow keytable */
- if (rc_tab->alloc >= IR_TAB_MAX_SIZE)
- return -ENOMEM;
-
- newalloc *= 2;
- IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
- }
-
- if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
- /* Less than 1/3 of entries in use -> shrink keytable */
- newalloc /= 2;
- IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
- }
-
- if (newalloc == oldalloc)
- return 0;
-
- newscan = kmalloc(newalloc, gfp_flags);
- if (!newscan) {
- IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
- return -ENOMEM;
- }
-
- memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode));
- rc_tab->scan = newscan;
- rc_tab->alloc = newalloc;
- rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode);
- kfree(oldscan);
- return 0;
-}
-
-/**
- * ir_update_mapping() - set a keycode in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @rc_tab: scancode table to be adjusted
- * @index: index of the mapping that needs to be updated
- * @keycode: the desired keycode
- * @return: previous keycode assigned to the mapping
- *
- * This routine is used to update scancode->keycopde mapping at given
- * position.
- */
-static unsigned int ir_update_mapping(struct input_dev *dev,
- struct ir_scancode_table *rc_tab,
- unsigned int index,
- unsigned int new_keycode)
-{
- int old_keycode = rc_tab->scan[index].keycode;
- int i;
-
- /* Did the user wish to remove the mapping? */
- if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
- IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
- index, rc_tab->scan[index].scancode);
- rc_tab->len--;
- memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1],
- (rc_tab->len - index) * sizeof(struct ir_scancode));
- } else {
- IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n",
- index,
- old_keycode == KEY_RESERVED ? "New" : "Replacing",
- rc_tab->scan[index].scancode, new_keycode);
- rc_tab->scan[index].keycode = new_keycode;
- __set_bit(new_keycode, dev->keybit);
- }
-
- if (old_keycode != KEY_RESERVED) {
- /* A previous mapping was updated... */
- __clear_bit(old_keycode, dev->keybit);
- /* ... but another scancode might use the same keycode */
- for (i = 0; i < rc_tab->len; i++) {
- if (rc_tab->scan[i].keycode == old_keycode) {
- __set_bit(old_keycode, dev->keybit);
- break;
- }
- }
-
- /* Possibly shrink the keytable, failure is not a problem */
- ir_resize_table(rc_tab, GFP_ATOMIC);
- }
-
- return old_keycode;
-}
-
-/**
- * ir_locate_scancode() - set a keycode in the scancode->keycode table
- * @ir_dev: the struct ir_input_dev device descriptor
- * @rc_tab: scancode table to be searched
- * @scancode: the desired scancode
- * @resize: controls whether we allowed to resize the table to
- * accomodate not yet present scancodes
- * @return: index of the mapping containing scancode in question
- * or -1U in case of failure.
- *
- * This routine is used to locate given scancode in ir_scancode_table.
- * If scancode is not yet present the routine will allocate a new slot
- * for it.
- */
-static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev,
- struct ir_scancode_table *rc_tab,
- unsigned int scancode,
- bool resize)
-{
- unsigned int i;
-
- /*
- * Unfortunately, some hardware-based IR decoders don't provide
- * all bits for the complete IR code. In general, they provide only
- * the command part of the IR code. Yet, as it is possible to replace
- * the provided IR with another one, it is needed to allow loading
- * IR tables from other remotes. So,
- */
- if (ir_dev->props && ir_dev->props->scanmask)
- scancode &= ir_dev->props->scanmask;
-
- /* First check if we already have a mapping for this ir command */
- for (i = 0; i < rc_tab->len; i++) {
- if (rc_tab->scan[i].scancode == scancode)
- return i;
-
- /* Keytable is sorted from lowest to highest scancode */
- if (rc_tab->scan[i].scancode >= scancode)
- break;
- }
-
- /* No previous mapping found, we might need to grow the table */
- if (rc_tab->size == rc_tab->len) {
- if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC))
- return -1U;
- }
-
- /* i is the proper index to insert our new keycode */
- if (i < rc_tab->len)
- memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
- (rc_tab->len - i) * sizeof(struct ir_scancode));
- rc_tab->scan[i].scancode = scancode;
- rc_tab->scan[i].keycode = KEY_RESERVED;
- rc_tab->len++;
-
- return i;
-}
-
-/**
- * ir_setkeycode() - set a keycode in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @scancode: the desired scancode
- * @keycode: result
- * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
- *
- * This routine is used to handle evdev EVIOCSKEY ioctl.
- */
-static int ir_setkeycode(struct input_dev *dev,
- const struct input_keymap_entry *ke,
- unsigned int *old_keycode)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned int index;
- unsigned int scancode;
- int retval;
- unsigned long flags;
-
- spin_lock_irqsave(&rc_tab->lock, flags);
-
- if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
- index = ke->index;
- if (index >= rc_tab->len) {
- retval = -EINVAL;
- goto out;
- }
- } else {
- retval = input_scancode_to_scalar(ke, &scancode);
- if (retval)
- goto out;
-
- index = ir_establish_scancode(ir_dev, rc_tab, scancode, true);
- if (index >= rc_tab->len) {
- retval = -ENOMEM;
- goto out;
- }
- }
-
- *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode);
-
-out:
- spin_unlock_irqrestore(&rc_tab->lock, flags);
- return retval;
-}
-
-/**
- * ir_setkeytable() - sets several entries in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @to: the struct ir_scancode_table to copy entries to
- * @from: the struct ir_scancode_table to copy entries from
- * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
- *
- * This routine is used to handle table initialization.
- */
-static int ir_setkeytable(struct ir_input_dev *ir_dev,
- const struct ir_scancode_table *from)
-{
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned int i, index;
- int rc;
-
- rc = ir_create_table(&ir_dev->rc_tab,
- from->name, from->ir_type, from->size);
- if (rc)
- return rc;
-
- IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
- rc_tab->size, rc_tab->alloc);
-
- for (i = 0; i < from->size; i++) {
- index = ir_establish_scancode(ir_dev, rc_tab,
- from->scan[i].scancode, false);
- if (index >= rc_tab->len) {
- rc = -ENOMEM;
- break;
- }
-
- ir_update_mapping(ir_dev->input_dev, rc_tab, index,
- from->scan[i].keycode);
- }
-
- if (rc)
- ir_free_table(rc_tab);
-
- return rc;
-}
-
-/**
- * ir_lookup_by_scancode() - locate mapping by scancode
- * @rc_tab: the &struct ir_scancode_table to search
- * @scancode: scancode to look for in the table
- * @return: index in the table, -1U if not found
- *
- * This routine performs binary search in RC keykeymap table for
- * given scancode.
- */
-static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab,
- unsigned int scancode)
-{
- int start = 0;
- int end = rc_tab->len - 1;
- int mid;
-
- while (start <= end) {
- mid = (start + end) / 2;
- if (rc_tab->scan[mid].scancode < scancode)
- start = mid + 1;
- else if (rc_tab->scan[mid].scancode > scancode)
- end = mid - 1;
- else
- return mid;
- }
-
- return -1U;
-}
-
-/**
- * ir_getkeycode() - get a keycode from the scancode->keycode table
- * @dev: the struct input_dev device descriptor
- * @scancode: the desired scancode
- * @keycode: used to return the keycode, if found, or KEY_RESERVED
- * @return: always returns zero.
- *
- * This routine is used to handle evdev EVIOCGKEY ioctl.
- */
-static int ir_getkeycode(struct input_dev *dev,
- struct input_keymap_entry *ke)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- struct ir_scancode *entry;
- unsigned long flags;
- unsigned int index;
- unsigned int scancode;
- int retval;
-
- spin_lock_irqsave(&rc_tab->lock, flags);
-
- if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
- index = ke->index;
- } else {
- retval = input_scancode_to_scalar(ke, &scancode);
- if (retval)
- goto out;
-
- index = ir_lookup_by_scancode(rc_tab, scancode);
- }
-
- if (index >= rc_tab->len) {
- if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
- IR_dprintk(1, "unknown key for scancode 0x%04x\n",
- scancode);
- retval = -EINVAL;
- goto out;
- }
-
- entry = &rc_tab->scan[index];
-
- ke->index = index;
- ke->keycode = entry->keycode;
- ke->len = sizeof(entry->scancode);
- memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
-
- retval = 0;
-
-out:
- spin_unlock_irqrestore(&rc_tab->lock, flags);
- return retval;
-}
-
-/**
- * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
- * @input_dev: the struct input_dev descriptor of the device
- * @scancode: the scancode that we're seeking
- *
- * This routine is used by the input routines when a key is pressed at the
- * IR. The scancode is received and needs to be converted into a keycode.
- * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the
- * corresponding keycode from the table.
- */
-u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
- unsigned int keycode;
- unsigned int index;
- unsigned long flags;
-
- spin_lock_irqsave(&rc_tab->lock, flags);
-
- index = ir_lookup_by_scancode(rc_tab, scancode);
- keycode = index < rc_tab->len ?
- rc_tab->scan[index].keycode : KEY_RESERVED;
-
- spin_unlock_irqrestore(&rc_tab->lock, flags);
-
- if (keycode != KEY_RESERVED)
- IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
- dev->name, scancode, keycode);
-
- return keycode;
-}
-EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
-
-/**
- * ir_keyup() - generates input event to cleanup a key press
- * @ir: the struct ir_input_dev descriptor of the device
- *
- * This routine is used to signal that a key has been released on the
- * remote control. It reports a keyup input event via input_report_key().
- */
-void ir_keyup(struct ir_input_dev *ir)
-{
- if (!ir->keypressed)
- return;
-
- IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode);
- input_report_key(ir->input_dev, ir->last_keycode, 0);
- input_sync(ir->input_dev);
- ir->keypressed = false;
-}
-EXPORT_SYMBOL_GPL(ir_keyup);
-
-/**
- * ir_timer_keyup() - generates a keyup event after a timeout
- * @cookie: a pointer to struct ir_input_dev passed to setup_timer()
- *
- * This routine will generate a keyup event some time after a keydown event
- * is generated when no further activity has been detected.
- */
-static void ir_timer_keyup(unsigned long cookie)
-{
- struct ir_input_dev *ir = (struct ir_input_dev *)cookie;
- unsigned long flags;
-
- /*
- * ir->keyup_jiffies is used to prevent a race condition if a
- * hardware interrupt occurs at this point and the keyup timer
- * event is moved further into the future as a result.
- *
- * The timer will then be reactivated and this function called
- * again in the future. We need to exit gracefully in that case
- * to allow the input subsystem to do its auto-repeat magic or
- * a keyup event might follow immediately after the keydown.
- */
- spin_lock_irqsave(&ir->keylock, flags);
- if (time_is_before_eq_jiffies(ir->keyup_jiffies))
- ir_keyup(ir);
- spin_unlock_irqrestore(&ir->keylock, flags);
-}
-
-/**
- * ir_repeat() - notifies the IR core that a key is still pressed
- * @dev: the struct input_dev descriptor of the device
- *
- * This routine is used by IR decoders when a repeat message which does
- * not include the necessary bits to reproduce the scancode has been
- * received.
- */
-void ir_repeat(struct input_dev *dev)
-{
- unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
-
- spin_lock_irqsave(&ir->keylock, flags);
-
- input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode);
-
- if (!ir->keypressed)
- goto out;
-
- ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
-
-out:
- spin_unlock_irqrestore(&ir->keylock, flags);
-}
-EXPORT_SYMBOL_GPL(ir_repeat);
-
-/**
- * ir_keydown() - generates input event for a key press
- * @dev: the struct input_dev descriptor of the device
- * @scancode: the scancode that we're seeking
- * @toggle: the toggle value (protocol dependent, if the protocol doesn't
- * support toggle values, this should be set to zero)
- *
- * This routine is used by the input routines when a key is pressed at the
- * IR. It gets the keycode for a scancode and reports an input event via
- * input_report_key().
- */
-void ir_keydown(struct input_dev *dev, int scancode, u8 toggle)
-{
- unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
-
- u32 keycode = ir_g_keycode_from_table(dev, scancode);
-
- spin_lock_irqsave(&ir->keylock, flags);
-
- input_event(dev, EV_MSC, MSC_SCAN, scancode);
-
- /* Repeat event? */
- if (ir->keypressed &&
- ir->last_scancode == scancode &&
- ir->last_toggle == toggle)
- goto set_timer;
-
- /* Release old keypress */
- ir_keyup(ir);
-
- ir->last_scancode = scancode;
- ir->last_toggle = toggle;
- ir->last_keycode = keycode;
-
-
- if (keycode == KEY_RESERVED)
- goto out;
-
-
- /* Register a keypress */
- ir->keypressed = true;
- IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
- dev->name, keycode, scancode);
- input_report_key(dev, ir->last_keycode, 1);
- input_sync(dev);
-
-set_timer:
- ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
-out:
- spin_unlock_irqrestore(&ir->keylock, flags);
-}
-EXPORT_SYMBOL_GPL(ir_keydown);
-
-static int ir_open(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- return ir_dev->props->open(ir_dev->props->priv);
-}
-
-static void ir_close(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- ir_dev->props->close(ir_dev->props->priv);
-}
-
-/**
- * __ir_input_register() - sets the IR keycode table and add the handlers
- * for keymap table get/set
- * @input_dev: the struct input_dev descriptor of the device
- * @rc_tab: the struct ir_scancode_table table of scancode/keymap
- *
- * This routine is used to initialize the input infrastructure
- * to work with an IR.
- * It will register the input/evdev interface for the device and
- * register the syfs code for IR class
- */
-int __ir_input_register(struct input_dev *input_dev,
- const struct ir_scancode_table *rc_tab,
- struct ir_dev_props *props,
- const char *driver_name)
-{
- struct ir_input_dev *ir_dev;
- int rc;
-
- if (rc_tab->scan == NULL || !rc_tab->size)
- return -EINVAL;
-
- ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
- if (!ir_dev)
- return -ENOMEM;
-
- ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name);
- if (!ir_dev->driver_name) {
- rc = -ENOMEM;
- goto out_dev;
- }
-
- input_dev->getkeycode_new = ir_getkeycode;
- input_dev->setkeycode_new = ir_setkeycode;
- input_set_drvdata(input_dev, ir_dev);
- ir_dev->input_dev = input_dev;
-
- spin_lock_init(&ir_dev->rc_tab.lock);
- spin_lock_init(&ir_dev->keylock);
- setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev);
-
- if (props) {
- ir_dev->props = props;
- if (props->open)
- input_dev->open = ir_open;
- if (props->close)
- input_dev->close = ir_close;
- }
-
- set_bit(EV_KEY, input_dev->evbit);
- set_bit(EV_REP, input_dev->evbit);
- set_bit(EV_MSC, input_dev->evbit);
- set_bit(MSC_SCAN, input_dev->mscbit);
-
- rc = ir_setkeytable(ir_dev, rc_tab);
- if (rc)
- goto out_name;
-
- rc = ir_register_class(input_dev);
- if (rc < 0)
- goto out_table;
-
- if (ir_dev->props)
- if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
- rc = ir_raw_event_register(input_dev);
- if (rc < 0)
- goto out_event;
- }
-
- rc = ir_register_input(input_dev);
- if (rc < 0)
- goto out_event;
-
- IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
- driver_name, rc_tab->name,
- (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
- " in raw mode" : "");
-
- /*
- * Default delay of 250ms is too short for some protocols, expecially
- * since the timeout is currently set to 250ms. Increase it to 500ms,
- * to avoid wrong repetition of the keycodes.
- */
- input_dev->rep[REP_DELAY] = 500;
-
- return 0;
-
-out_event:
- ir_unregister_class(input_dev);
-out_table:
- ir_free_table(&ir_dev->rc_tab);
-out_name:
- kfree(ir_dev->driver_name);
-out_dev:
- kfree(ir_dev);
- return rc;
-}
-EXPORT_SYMBOL_GPL(__ir_input_register);
-
-/**
- * ir_input_unregister() - unregisters IR and frees resources
- * @input_dev: the struct input_dev descriptor of the device
-
- * This routine is used to free memory and de-register interfaces.
- */
-void ir_input_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- if (!ir_dev)
- return;
-
- IR_dprintk(1, "Freed keycode table\n");
-
- del_timer_sync(&ir_dev->timer_keyup);
- if (ir_dev->props)
- if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
- ir_raw_event_unregister(input_dev);
-
- ir_free_table(&ir_dev->rc_tab);
-
- ir_unregister_class(input_dev);
-
- kfree(ir_dev->driver_name);
- kfree(ir_dev);
-}
-EXPORT_SYMBOL_GPL(ir_input_unregister);
-
-int ir_core_debug; /* ir_debug level (0,1,2) */
-EXPORT_SYMBOL_GPL(ir_core_debug);
-module_param_named(debug, ir_core_debug, int, 0644);
-
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
deleted file mode 100644
index 38423a8da871..000000000000
--- a/drivers/media/IR/ir-sysfs.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/* ir-sysfs.c - sysfs interface for RC devices (/sys/class/rc)
- *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/device.h>
-#include "ir-core-priv.h"
-
-#define IRRCV_NUM_DEVICES 256
-
-/* bit array to represent IR sysfs device number */
-static unsigned long ir_core_dev_number;
-
-/* class for /sys/class/rc */
-static char *ir_devnode(struct device *dev, mode_t *mode)
-{
- return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
-}
-
-static struct class ir_input_class = {
- .name = "rc",
- .devnode = ir_devnode,
-};
-
-static struct {
- u64 type;
- char *name;
-} proto_names[] = {
- { IR_TYPE_UNKNOWN, "unknown" },
- { IR_TYPE_RC5, "rc-5" },
- { IR_TYPE_NEC, "nec" },
- { IR_TYPE_RC6, "rc-6" },
- { IR_TYPE_JVC, "jvc" },
- { IR_TYPE_SONY, "sony" },
- { IR_TYPE_RC5_SZ, "rc-5-sz" },
- { IR_TYPE_LIRC, "lirc" },
-};
-
-#define PROTO_NONE "none"
-
-/**
- * show_protocols() - shows the current IR protocol(s)
- * @d: the device descriptor
- * @mattr: the device attribute struct (unused)
- * @buf: a pointer to the output buffer
- *
- * This routine is a callback routine for input read the IR protocol type(s).
- * it is trigged by reading /sys/class/rc/rc?/protocols.
- * It returns the protocol names of supported protocols.
- * Enabled protocols are printed in brackets.
- */
-static ssize_t show_protocols(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- u64 allowed, enabled;
- char *tmp = buf;
- int i;
-
- /* Device is being removed */
- if (!ir_dev)
- return -EINVAL;
-
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
- enabled = ir_dev->rc_tab.ir_type;
- allowed = ir_dev->props->allowed_protos;
- } else if (ir_dev->raw) {
- enabled = ir_dev->raw->enabled_protocols;
- allowed = ir_raw_get_allowed_protocols();
- } else
- return sprintf(tmp, "[builtin]\n");
-
- IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
- (long long)allowed,
- (long long)enabled);
-
- for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
- if (allowed & enabled & proto_names[i].type)
- tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
- else if (allowed & proto_names[i].type)
- tmp += sprintf(tmp, "%s ", proto_names[i].name);
- }
-
- if (tmp != buf)
- tmp--;
- *tmp = '\n';
- return tmp + 1 - buf;
-}
-
-/**
- * store_protocols() - changes the current IR protocol(s)
- * @d: the device descriptor
- * @mattr: the device attribute struct (unused)
- * @buf: a pointer to the input buffer
- * @len: length of the input buffer
- *
- * This routine is a callback routine for changing the IR protocol type.
- * It is trigged by writing to /sys/class/rc/rc?/protocols.
- * Writing "+proto" will add a protocol to the list of enabled protocols.
- * Writing "-proto" will remove a protocol from the list of enabled protocols.
- * Writing "proto" will enable only "proto".
- * Writing "none" will disable all protocols.
- * Returns -EINVAL if an invalid protocol combination or unknown protocol name
- * is used, otherwise @len.
- */
-static ssize_t store_protocols(struct device *d,
- struct device_attribute *mattr,
- const char *data,
- size_t len)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- bool enable, disable;
- const char *tmp;
- u64 type;
- u64 mask;
- int rc, i, count = 0;
- unsigned long flags;
-
- /* Device is being removed */
- if (!ir_dev)
- return -EINVAL;
-
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
- type = ir_dev->rc_tab.ir_type;
- else if (ir_dev->raw)
- type = ir_dev->raw->enabled_protocols;
- else {
- IR_dprintk(1, "Protocol switching not supported\n");
- return -EINVAL;
- }
-
- while ((tmp = strsep((char **) &data, " \n")) != NULL) {
- if (!*tmp)
- break;
-
- if (*tmp == '+') {
- enable = true;
- disable = false;
- tmp++;
- } else if (*tmp == '-') {
- enable = false;
- disable = true;
- tmp++;
- } else {
- enable = false;
- disable = false;
- }
-
- if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
- tmp += sizeof(PROTO_NONE);
- mask = 0;
- count++;
- } else {
- for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
- if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
- tmp += strlen(proto_names[i].name);
- mask = proto_names[i].type;
- break;
- }
- }
- if (i == ARRAY_SIZE(proto_names)) {
- IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
- return -EINVAL;
- }
- count++;
- }
-
- if (enable)
- type |= mask;
- else if (disable)
- type &= ~mask;
- else
- type = mask;
- }
-
- if (!count) {
- IR_dprintk(1, "Protocol not specified\n");
- return -EINVAL;
- }
-
- if (ir_dev->props && ir_dev->props->change_protocol) {
- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
- type);
- if (rc < 0) {
- IR_dprintk(1, "Error setting protocols to 0x%llx\n",
- (long long)type);
- return -EINVAL;
- }
- }
-
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
- spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
- ir_dev->rc_tab.ir_type = type;
- spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
- } else {
- ir_dev->raw->enabled_protocols = type;
- }
-
- IR_dprintk(1, "Current protocol(s): 0x%llx\n",
- (long long)type);
-
- return len;
-}
-
-#define ADD_HOTPLUG_VAR(fmt, val...) \
- do { \
- int err = add_uevent_var(env, fmt, val); \
- if (err) \
- return err; \
- } while (0)
-
-static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(device);
-
- if (ir_dev->rc_tab.name)
- ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
- if (ir_dev->driver_name)
- ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
-
- return 0;
-}
-
-/*
- * Static device attribute struct with the sysfs attributes for IR's
- */
-static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
- show_protocols, store_protocols);
-
-static struct attribute *rc_dev_attrs[] = {
- &dev_attr_protocols.attr,
- NULL,
-};
-
-static struct attribute_group rc_dev_attr_grp = {
- .attrs = rc_dev_attrs,
-};
-
-static const struct attribute_group *rc_dev_attr_groups[] = {
- &rc_dev_attr_grp,
- NULL
-};
-
-static struct device_type rc_dev_type = {
- .groups = rc_dev_attr_groups,
- .uevent = rc_dev_uevent,
-};
-
-/**
- * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
- * @input_dev: the struct input_dev descriptor of the device
- *
- * This routine is used to register the syfs code for IR class
- */
-int ir_register_class(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- int devno = find_first_zero_bit(&ir_core_dev_number,
- IRRCV_NUM_DEVICES);
-
- if (unlikely(devno < 0))
- return devno;
-
- ir_dev->dev.type = &rc_dev_type;
- ir_dev->devno = devno;
-
- ir_dev->dev.class = &ir_input_class;
- ir_dev->dev.parent = input_dev->dev.parent;
- input_dev->dev.parent = &ir_dev->dev;
- dev_set_name(&ir_dev->dev, "rc%d", devno);
- dev_set_drvdata(&ir_dev->dev, ir_dev);
- return device_register(&ir_dev->dev);
-};
-
-/**
- * ir_register_input - registers ir input device with input subsystem
- * @input_dev: the struct input_dev descriptor of the device
- */
-
-int ir_register_input(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- int rc;
- const char *path;
-
-
- rc = input_register_device(input_dev);
- if (rc < 0) {
- device_del(&ir_dev->dev);
- return rc;
- }
-
- __module_get(THIS_MODULE);
-
- path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
- printk(KERN_INFO "%s: %s as %s\n",
- dev_name(&ir_dev->dev),
- input_dev->name ? input_dev->name : "Unspecified device",
- path ? path : "N/A");
- kfree(path);
-
- set_bit(ir_dev->devno, &ir_core_dev_number);
- return 0;
-}
-
-/**
- * ir_unregister_class() - removes the sysfs for sysfs for
- * /sys/class/rc/rc?
- * @input_dev: the struct input_dev descriptor of the device
- *
- * This routine is used to unregister the syfs code for IR class
- */
-void ir_unregister_class(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- input_set_drvdata(input_dev, NULL);
- clear_bit(ir_dev->devno, &ir_core_dev_number);
- input_unregister_device(input_dev);
- device_del(&ir_dev->dev);
-
- module_put(THIS_MODULE);
-}
-
-/*
- * Init/exit code for the module. Basically, creates/removes /sys/class/rc
- */
-
-static int __init ir_core_init(void)
-{
- int rc = class_register(&ir_input_class);
- if (rc) {
- printk(KERN_ERR "ir_core: unable to register rc class\n");
- return rc;
- }
-
- /* Initialize/load the decoders/keymap code that will be used */
- ir_raw_init();
- ir_rcmap_init();
-
- return 0;
-}
-
-static void __exit ir_core_exit(void)
-{
- class_unregister(&ir_input_class);
- ir_rcmap_cleanup();
-}
-
-module_init(ir_core_init);
-module_exit(ir_core_exit);
diff --git a/drivers/media/IR/keymaps/rc-tbs-nec.c b/drivers/media/IR/keymaps/rc-tbs-nec.c
deleted file mode 100644
index 3309631e6f80..000000000000
--- a/drivers/media/IR/keymaps/rc-tbs-nec.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* tbs-nec.h - Keytable for tbs_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <media/rc-map.h>
-
-static struct ir_scancode tbs_nec[] = {
- { 0x04, KEY_POWER2}, /*power*/
- { 0x14, KEY_MUTE}, /*mute*/
- { 0x07, KEY_1},
- { 0x06, KEY_2},
- { 0x05, KEY_3},
- { 0x0b, KEY_4},
- { 0x0a, KEY_5},
- { 0x09, KEY_6},
- { 0x0f, KEY_7},
- { 0x0e, KEY_8},
- { 0x0d, KEY_9},
- { 0x12, KEY_0},
- { 0x16, KEY_CHANNELUP}, /*ch+*/
- { 0x11, KEY_CHANNELDOWN},/*ch-*/
- { 0x13, KEY_VOLUMEUP}, /*vol+*/
- { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
- { 0x03, KEY_RECORD}, /*rec*/
- { 0x18, KEY_PAUSE}, /*pause*/
- { 0x19, KEY_OK}, /*ok*/
- { 0x1a, KEY_CAMERA}, /* snapshot */
- { 0x01, KEY_UP},
- { 0x10, KEY_LEFT},
- { 0x02, KEY_RIGHT},
- { 0x08, KEY_DOWN},
- { 0x15, KEY_FAVORITES},
- { 0x17, KEY_SUBTITLE},
- { 0x1d, KEY_ZOOM},
- { 0x1f, KEY_EXIT},
- { 0x1e, KEY_MENU},
- { 0x1c, KEY_EPG},
- { 0x00, KEY_PREVIOUS},
- { 0x1b, KEY_MODE},
-};
-
-static struct rc_keymap tbs_nec_map = {
- .map = {
- .scan = tbs_nec,
- .size = ARRAY_SIZE(tbs_nec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
- .name = RC_MAP_TBS_NEC,
- }
-};
-
-static int __init init_rc_map_tbs_nec(void)
-{
- return ir_register_map(&tbs_nec_map);
-}
-
-static void __exit exit_rc_map_tbs_nec(void)
-{
- ir_unregister_map(&tbs_nec_map);
-}
-
-module_init(init_rc_map_tbs_nec)
-module_exit(exit_rc_map_tbs_nec)
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/IR/rc-map.c b/drivers/media/IR/rc-map.c
deleted file mode 100644
index 689143f2fff0..000000000000
--- a/drivers/media/IR/rc-map.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ir-raw-event.c - handle IR Pulse/Space event
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <media/ir-core.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-
-/* Used to handle IR raw handler extensions */
-static LIST_HEAD(rc_map_list);
-static DEFINE_SPINLOCK(rc_map_lock);
-
-static struct rc_keymap *seek_rc_map(const char *name)
-{
- struct rc_keymap *map = NULL;
-
- spin_lock(&rc_map_lock);
- list_for_each_entry(map, &rc_map_list, list) {
- if (!strcmp(name, map->map.name)) {
- spin_unlock(&rc_map_lock);
- return map;
- }
- }
- spin_unlock(&rc_map_lock);
-
- return NULL;
-}
-
-struct ir_scancode_table *get_rc_map(const char *name)
-{
-
- struct rc_keymap *map;
-
- map = seek_rc_map(name);
-#ifdef MODULE
- if (!map) {
- int rc = request_module(name);
- if (rc < 0) {
- printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
- return NULL;
- }
- msleep(20); /* Give some time for IR to register */
-
- map = seek_rc_map(name);
- }
-#endif
- if (!map) {
- printk(KERN_ERR "IR keymap %s not found\n", name);
- return NULL;
- }
-
- printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
-
- return &map->map;
-}
-EXPORT_SYMBOL_GPL(get_rc_map);
-
-int ir_register_map(struct rc_keymap *map)
-{
- spin_lock(&rc_map_lock);
- list_add_tail(&map->list, &rc_map_list);
- spin_unlock(&rc_map_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(ir_register_map);
-
-void ir_unregister_map(struct rc_keymap *map)
-{
- spin_lock(&rc_map_lock);
- list_del(&map->list);
- spin_unlock(&rc_map_lock);
-}
-EXPORT_SYMBOL_GPL(ir_unregister_map);
-
-
-static struct ir_scancode empty[] = {
- { 0x2a, KEY_COFFEE },
-};
-
-static struct rc_keymap empty_map = {
- .map = {
- .scan = empty,
- .size = ARRAY_SIZE(empty),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
- .name = RC_MAP_EMPTY,
- }
-};
-
-int ir_rcmap_init(void)
-{
- return ir_register_map(&empty_map);
-}
-
-void ir_rcmap_cleanup(void)
-{
- ir_unregister_map(&empty_map);
-}
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index a28541b2b1a2..c21dfc28482e 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -99,7 +99,7 @@ config VIDEO_MEDIA
comment "Multimedia drivers"
source "drivers/media/common/Kconfig"
-source "drivers/media/IR/Kconfig"
+source "drivers/media/rc/Kconfig"
#
# Tuner drivers for DVB and V4L
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 499b0810d019..b603ea645ede 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,7 +2,7 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y += common/ IR/ video/
+obj-y += common/ rc/ video/
obj-$(CONFIG_VIDEO_DEV) += radio/
obj-$(CONFIG_DVB_CORE) += dvb/
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index 05bde9ccb770..1d1d8d200755 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e
static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
{
struct saa7146_vv *vv = dev->vv_data;
- struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
int b_depth = vv->ov_fmt->depth;
int b_bpl = vv->ov_fb.fmt.bytesperline;
@@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
struct saa7146_vv *vv = dev->vv_data;
struct saa7146_video_dma vdma1;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
int width = buf->fmt->width;
int height = buf->fmt->height;
@@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
struct saa7146_video_dma vdma2;
struct saa7146_video_dma vdma3;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
int width = buf->fmt->width;
int height = buf->fmt->height;
@@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
{
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
struct saa7146_vv *vv = dev->vv_data;
u32 vdma1_prot_addr;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 741c5732b430..d246910129e8 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -84,7 +84,7 @@ static struct saa7146_format formats[] = {
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
-struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
+struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
{
int i, j = NUM_FORMATS;
@@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
struct scatterlist *list = dma->sglist;
int length = dma->sglen;
- struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
@@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh)
}
}
- fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
@@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
return -EBUSY;
}
- fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
@@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
return -EPERM;
/* check args */
- fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
- fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+ fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q,
buf->fmt = &fh->video_fmt;
buf->vb.field = fh->video_fmt.field;
- sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
+ sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
release_all_pagetables(dev, buf);
if( 0 != IS_PLANAR(sfmt->trans)) {
@@ -1378,7 +1378,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
fh->video_fmt.bytesperline = 0;
fh->video_fmt.field = V4L2_FIELD_ANY;
- sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
+ sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
videobuf_queue_sg_init(&fh->video_q, &video_qops,
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
index 937e4b00d7ee..9883617b7862 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/common/tuners/max2165.c
@@ -52,13 +52,12 @@ static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
msg.addr = priv->config->i2c_address;
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
- __func__, reg, data);
+ dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret != 1)
- dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+ dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
__func__, reg, data, ret);
return (ret != 1) ? -EIO : 0;
@@ -78,14 +77,13 @@ static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret != 2) {
- dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
- __func__, reg, ret);
+ dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
return -EIO;
}
*p_data = b1[0];
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+ dprintk("%s: reg=0x%02X, data=0x%02X\n",
__func__, reg, b1[0]);
return 0;
}
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
index a6ceb08f1183..f3de0a4d63f2 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -1,7 +1,6 @@
config DVB_DM1105
tristate "SDMC DM1105 based PCI cards"
depends on DVB_CORE && PCI && I2C
- depends on INPUT
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_STV0288 if !DVB_FE_CUSTOMISE
@@ -9,7 +8,7 @@ config DVB_DM1105
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
select DVB_DS3000 if !DVB_FE_CUSTOMISE
- depends on VIDEO_IR
+ depends on RC_CORE
help
Support for cards based on the SDMC DM1105 PCI chip like
DvbWorld 2002
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 5d404f1bf036..2d8b4044be36 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -26,9 +26,8 @@
#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
-#include <linux/input.h>
#include <linux/slab.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "demux.h"
#include "dmxdev.h"
@@ -266,7 +265,7 @@ static void dm1105_card_list(struct pci_dev *pci)
/* infrared remote control */
struct infrared {
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char input_phys[32];
struct work_struct work;
u32 ir_command;
@@ -532,7 +531,7 @@ static void dm1105_emit_key(struct work_struct *work)
data = (ircom >> 8) & 0x7f;
- ir_keydown(ir->input_dev, data, 0);
+ rc_keydown(ir->dev, data, 0);
}
/* work handler */
@@ -593,46 +592,47 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
{
- struct input_dev *input_dev;
- char *ir_codes = RC_MAP_DM1105_NEC;
+ struct rc_dev *dev;
int err = -ENOMEM;
- input_dev = input_allocate_device();
- if (!input_dev)
+ dev = rc_allocate_device();
+ if (!dev)
return -ENOMEM;
- dm1105->ir.input_dev = input_dev;
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- input_dev->name = "DVB on-card IR receiver";
- input_dev->phys = dm1105->ir.input_phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->map_name = RC_MAP_DM1105_NEC;
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ dev->input_name = "DVB on-card IR receiver";
+ dev->input_phys = dm1105->ir.input_phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
- input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
- input_dev->id.product = dm1105->pdev->subsystem_device;
+ dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
+ dev->input_id.product = dm1105->pdev->subsystem_device;
} else {
- input_dev->id.vendor = dm1105->pdev->vendor;
- input_dev->id.product = dm1105->pdev->device;
+ dev->input_id.vendor = dm1105->pdev->vendor;
+ dev->input_id.product = dm1105->pdev->device;
}
-
- input_dev->dev.parent = &dm1105->pdev->dev;
+ dev->dev.parent = &dm1105->pdev->dev;
INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
- err = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(dev);
if (err < 0) {
- input_free_device(input_dev);
+ rc_free_device(dev);
return err;
}
+ dm1105->ir.dev = dev;
return 0;
}
void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
{
- ir_input_unregister(dm1105->ir.input_dev);
+ rc_unregister_device(dm1105->ir.dev);
}
static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 2525d3b3c88d..fe4f894183ff 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,6 +1,6 @@
config DVB_USB
tristate "Support for various USB DVB devices"
- depends on DVB_CORE && USB && I2C && IR_CORE
+ depends on DVB_CORE && USB && I2C && RC_CORE
help
By enabling this you will be able to choose the various supported
USB1.1 and USB2.0 DVB devices.
@@ -358,3 +358,11 @@ config DVB_USB_LME2510
select DVB_IX2505V if !DVB_FE_CUSTOMISE
help
Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
+
+config DVB_USB_TECHNISAT_USB2
+ tristate "Technisat DVB-S/S2 USB2.0 support"
+ depends on DVB_USB
+ select DVB_STB0899 if !DVB_FE_CUSTOMISE
+ select DVB_STB6100 if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 5b1d12f2d591..4bac13da0c39 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
dvb-usb-lmedm04-objs = lmedm04.o
obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
+dvb-usb-technisat-usb2-objs = technisat-usb2.o
+obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
+
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index a5c363727133..53b93a4b6f8a 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
return 0;
}
-static struct ir_scancode ir_codes_a800_table[] = {
+static struct rc_map_table rc_map_a800_table[] = {
{ 0x0201, KEY_PROG1 }, /* SOURCE */
{ 0x0200, KEY_POWER }, /* POWER */
{ 0x0205, KEY_1 }, /* 1 */
@@ -148,8 +148,8 @@ static struct dvb_usb_device_properties a800_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_a800_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_a800_table),
+ .rc_map_table = rc_map_a800_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
.rc_query = a800_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index 696207fe37ec..c3bc64ed405c 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,
#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args)
-struct ir_scancode ir_codes_af9005_table[] = {
+struct rc_map_table rc_map_af9005_table[] = {
{0x01b7, KEY_POWER},
{0x01a7, KEY_VOLUMEUP},
@@ -74,7 +74,7 @@ struct ir_scancode ir_codes_af9005_table[] = {
{0x00d5, KEY_GOTO}, /* marked jump on the remote */
};
-int ir_codes_af9005_table_size = ARRAY_SIZE(ir_codes_af9005_table);
+int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
static int repeatable_keys[] = {
KEY_VOLUMEUP,
@@ -130,10 +130,10 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
deb_decode("code != inverted code\n");
return 0;
}
- for (i = 0; i < ir_codes_af9005_table_size; i++) {
- if (rc5_custom(&ir_codes_af9005_table[i]) == cust
- && rc5_data(&ir_codes_af9005_table[i]) == dat) {
- *event = ir_codes_af9005_table[i].keycode;
+ for (i = 0; i < rc_map_af9005_table_size; i++) {
+ if (rc5_custom(&rc_map_af9005_table[i]) == cust
+ && rc5_data(&rc_map_af9005_table[i]) == dat) {
+ *event = rc_map_af9005_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
deb_decode
("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,
return 0;
}
-EXPORT_SYMBOL(ir_codes_af9005_table);
-EXPORT_SYMBOL(ir_codes_af9005_table_size);
+EXPORT_SYMBOL(rc_map_af9005_table);
+EXPORT_SYMBOL(rc_map_af9005_table_size);
EXPORT_SYMBOL(af9005_rc_decode);
MODULE_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 8ecba8848bcf..51f6439dcfd5 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -1027,8 +1027,8 @@ static struct dvb_usb_device_properties af9005_properties = {
.rc.legacy = {
.rc_interval = 200,
- .rc_key_map = NULL,
- .rc_key_map_size = 0,
+ .rc_map_table = NULL,
+ .rc_map_size = 0,
.rc_query = af9005_rc_query,
},
@@ -1070,14 +1070,14 @@ static int __init af9005_usb_module_init(void)
return result;
}
rc_decode = symbol_request(af9005_rc_decode);
- rc_keys = symbol_request(ir_codes_af9005_table);
- rc_keys_size = symbol_request(ir_codes_af9005_table_size);
+ rc_keys = symbol_request(rc_map_af9005_table);
+ rc_keys_size = symbol_request(rc_map_af9005_table_size);
if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
err("af9005_rc_decode function not found, disabling remote");
af9005_properties.rc.legacy.rc_query = NULL;
} else {
- af9005_properties.rc.legacy.rc_key_map = rc_keys;
- af9005_properties.rc.legacy.rc_key_map_size = *rc_keys_size;
+ af9005_properties.rc.legacy.rc_map_table = rc_keys;
+ af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
}
return 0;
@@ -1089,9 +1089,9 @@ static void __exit af9005_usb_module_exit(void)
if (rc_decode != NULL)
symbol_put(af9005_rc_decode);
if (rc_keys != NULL)
- symbol_put(ir_codes_af9005_table);
+ symbol_put(rc_map_af9005_table);
if (rc_keys_size != NULL)
- symbol_put(ir_codes_af9005_table_size);
+ symbol_put(rc_map_af9005_table_size);
/* deregister this driver from the USB subsystem */
usb_deregister(&af9005_usb_driver);
}
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h
index 3c1fbd1c5d60..c71c77bd7f4b 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];
/* remote control decoder */
extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
u32 * event, int *state);
-extern struct ir_scancode ir_codes_af9005_table[];
-extern int ir_codes_af9005_table_size;
+extern struct rc_map_table rc_map_af9005_table[];
+extern int rc_map_af9005_table_size;
#endif
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 31c0a0ed39f5..8671ca362c81 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -1041,13 +1041,13 @@ static int af9015_rc_query(struct dvb_usb_device *d)
priv->rc_keycode = buf[12] << 16 |
buf[13] << 8 | buf[14];
}
- ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ rc_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
priv->rc_keycode = 0; /* clear just for sure */
}
} else if (priv->rc_repeat != buf[6] || buf[0]) {
deb_rc("%s: key repeated\n", __func__);
- ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ rc_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
deb_rc("%s: no key press\n", __func__);
}
@@ -1344,13 +1344,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
- .protocol = IR_TYPE_NEC,
+ .protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
@@ -1474,13 +1472,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
- .protocol = IR_TYPE_NEC,
+ .protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
@@ -1588,13 +1584,11 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.identify_state = af9015_identify_state,
.rc.core = {
- .protocol = IR_TYPE_NEC,
+ .protocol = RC_TYPE_NEC,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = RC_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 1759d26bca42..6b402e943539 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -394,7 +394,7 @@ static int anysee_rc_query(struct dvb_usb_device *d)
if (ircode[0]) {
deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
- ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0);
+ rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
}
return 0;
@@ -476,7 +476,7 @@ static struct dvb_usb_device_properties anysee_properties = {
.rc.core = {
.rc_codes = RC_MAP_ANYSEE,
- .protocol = IR_TYPE_OTHER,
+ .protocol = RC_TYPE_OTHER,
.module_name = "anysee",
.rc_query = anysee_rc_query,
.rc_interval = 250, /* windows driver uses 500ms */
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c
index 62c58288469f..9a7837fcfd7f 100644
--- a/drivers/media/dvb/dvb-usb/az6027.c
+++ b/drivers/media/dvb/dvb-usb/az6027.c
@@ -386,7 +386,7 @@ static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
}
/* keys for the enclosed remote control */
-static struct ir_scancode ir_codes_az6027_table[] = {
+static struct rc_map_table rc_map_az6027_table[] = {
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
};
@@ -1126,8 +1126,8 @@ static struct dvb_usb_device_properties az6027_properties = {
.read_mac_address = az6027_read_mac_addr,
*/
.rc.legacy = {
- .rc_key_map = ir_codes_az6027_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_az6027_table),
+ .rc_map_table = rc_map_az6027_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_az6027_table),
.rc_interval = 400,
.rc_query = az6027_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
index 4f5aa83fc1fc..16f2ce2bc15a 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)
return 0;
}
-static struct ir_scancode ir_codes_cinergyt2_table[] = {
+static struct rc_map_table rc_map_cinergyt2_table[] = {
{ 0x0401, KEY_POWER },
{ 0x0402, KEY_1 },
{ 0x0403, KEY_2 },
@@ -219,8 +219,8 @@ static struct dvb_usb_device_properties cinergyt2_properties = {
.rc.legacy = {
.rc_interval = 50,
- .rc_key_map = ir_codes_cinergyt2_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_cinergyt2_table),
+ .rc_map_table = rc_map_cinergyt2_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_cinergyt2_table),
.rc_query = cinergyt2_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index cd9f362c37b2..acb5fb2d2e73 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -385,7 +385,7 @@ static int cxusb_d680_dmb_streaming_ctrl(
static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[4];
int i;
@@ -394,7 +394,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[2] &&
rc5_data(&keymap[i]) == ircode[3]) {
*event = keymap[i].keycode;
@@ -410,7 +410,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[4];
int i;
struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
@@ -422,7 +422,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
return 0;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[1] &&
rc5_data(&keymap[i]) == ircode[2]) {
*event = keymap[i].keycode;
@@ -438,7 +438,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
u8 ircode[2];
int i;
@@ -448,7 +448,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
return 0;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
if (rc5_custom(&keymap[i]) == ircode[0] &&
rc5_data(&keymap[i]) == ircode[1]) {
*event = keymap[i].keycode;
@@ -461,7 +461,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
return 0;
}
-static struct ir_scancode ir_codes_dvico_mce_table[] = {
+static struct rc_map_table rc_map_dvico_mce_table[] = {
{ 0xfe02, KEY_TV },
{ 0xfe0e, KEY_MP3 },
{ 0xfe1a, KEY_DVD },
@@ -509,7 +509,7 @@ static struct ir_scancode ir_codes_dvico_mce_table[] = {
{ 0xfe4e, KEY_POWER },
};
-static struct ir_scancode ir_codes_dvico_portable_table[] = {
+static struct rc_map_table rc_map_dvico_portable_table[] = {
{ 0xfc02, KEY_SETUP }, /* Profile */
{ 0xfc43, KEY_POWER2 },
{ 0xfc06, KEY_EPG },
@@ -548,7 +548,7 @@ static struct ir_scancode ir_codes_dvico_portable_table[] = {
{ 0xfc00, KEY_UNKNOWN }, /* HD */
};
-static struct ir_scancode ir_codes_d680_dmb_table[] = {
+static struct rc_map_table rc_map_d680_dmb_table[] = {
{ 0x0038, KEY_UNKNOWN }, /* TV/AV */
{ 0x080c, KEY_ZOOM },
{ 0x0800, KEY_0 },
@@ -923,7 +923,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
return -EIO;
/* try to determine if there is no IR decoder on the I2C bus */
- for (i = 0; adap->dev->props.rc.legacy.rc_key_map != NULL && i < 5; i++) {
+ for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
msleep(20);
if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
goto no_IR;
@@ -931,7 +931,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
continue;
if (ircode[2] + ircode[3] != 0xff) {
no_IR:
- adap->dev->props.rc.legacy.rc_key_map = NULL;
+ adap->dev->props.rc.legacy.rc_map_table = NULL;
info("No IR receiver detected on this device.");
break;
}
@@ -1453,8 +1453,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1506,8 +1506,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
.rc.legacy = {
.rc_interval = 150,
- .rc_key_map = ir_codes_dvico_mce_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
+ .rc_map_table = rc_map_dvico_mce_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_rc_query,
},
@@ -1567,8 +1567,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1619,8 +1619,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1670,8 +1670,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_mce_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
+ .rc_map_table = rc_map_dvico_mce_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_bluebird2_rc_query,
},
@@ -1720,8 +1720,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_bluebird2_rc_query,
},
@@ -1772,8 +1772,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_portable_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_portable_table),
+ .rc_map_table = rc_map_dvico_portable_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
.rc_query = cxusb_rc_query,
},
@@ -1865,8 +1865,8 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_dvico_mce_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dvico_mce_table),
+ .rc_map_table = rc_map_dvico_mce_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
.rc_query = cxusb_rc_query,
},
@@ -1915,8 +1915,8 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_d680_dmb_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
+ .rc_map_table = rc_map_d680_dmb_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
.rc_query = cxusb_d680_dmb_rc_query,
},
@@ -1966,8 +1966,8 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_d680_dmb_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_d680_dmb_table),
+ .rc_map_table = rc_map_d680_dmb_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
.rc_query = cxusb_d680_dmb_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index c2c9d236ec7e..3537d65c04bc 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -60,7 +60,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
extern struct i2c_algorithm dib0700_i2c_algo;
extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc, int *cold);
-extern int dib0700_change_protocol(void *priv, u64 ir_type);
+extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
extern int dib0700_device_count;
extern int dvb_usb_dib0700_ir_proto;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 48397f103d32..8ca48f76dfa9 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -471,19 +471,19 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return dib0700_ctrl_wr(adap->dev, b, 4);
}
-int dib0700_change_protocol(void *priv, u64 ir_type)
+int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
{
- struct dvb_usb_device *d = priv;
+ struct dvb_usb_device *d = rc->priv;
struct dib0700_state *st = d->priv;
u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
int new_proto, ret;
/* Set the IR mode */
- if (ir_type == IR_TYPE_RC5)
+ if (rc_type == RC_TYPE_RC5)
new_proto = 1;
- else if (ir_type == IR_TYPE_NEC)
+ else if (rc_type == RC_TYPE_NEC)
new_proto = 0;
- else if (ir_type == IR_TYPE_RC6) {
+ else if (rc_type == RC_TYPE_RC6) {
if (st->fw_version < 0x10200)
return -EINVAL;
@@ -499,7 +499,7 @@ int dib0700_change_protocol(void *priv, u64 ir_type)
return ret;
}
- d->props.rc.core.protocol = ir_type;
+ d->props.rc.core.protocol = rc_type;
return ret;
}
@@ -535,7 +535,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
if (d == NULL)
return;
- if (d->rc_input_dev == NULL) {
+ if (d->rc_dev == NULL) {
/* This will occur if disable_rc_polling=1 */
usb_free_urb(purb);
return;
@@ -562,7 +562,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
purb->actual_length);
switch (d->props.rc.core.protocol) {
- case IR_TYPE_NEC:
+ case RC_TYPE_NEC:
toggle = 0;
/* NEC protocol sends repeat code as 0 0 0 FF */
@@ -600,7 +600,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
goto resubmit;
}
- ir_keydown(d->rc_input_dev, keycode, toggle);
+ rc_keydown(d->rc_dev, keycode, toggle);
resubmit:
/* Clean the buffer before we requeue */
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index e06acd1fecb6..defd83964ce2 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -510,7 +510,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = 0;
switch (d->props.rc.core.protocol) {
- case IR_TYPE_NEC:
+ case RC_TYPE_NEC:
/* NEC protocol sends repeat code as 0 0 0 FF */
if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
(key[3] == 0xff))
@@ -520,13 +520,13 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = keycode;
}
- ir_keydown(d->rc_input_dev, keycode, 0);
+ rc_keydown(d->rc_dev, keycode, 0);
break;
default:
/* RC-5 protocol changes toggle bit on new keypress */
keycode = key[3-2] << 8 | key[3-3];
toggle = key[3-1];
- ir_keydown(d->rc_input_dev, keycode, toggle);
+ rc_keydown(d->rc_dev, keycode, toggle);
break;
}
@@ -1924,12 +1924,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -1960,12 +1958,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2021,12 +2017,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2065,12 +2059,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2143,12 +2135,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2189,12 +2179,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2259,12 +2247,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2308,12 +2294,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -2379,12 +2363,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2417,12 +2399,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2487,12 +2467,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2533,12 +2511,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 2,
@@ -2584,12 +2560,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -2623,12 +2597,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = RC_TYPE_RC5 |
+ RC_TYPE_RC6 |
+ RC_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
},
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index ba991aa21aff..956f7ae2e510 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);
/*
* common remote control stuff
*/
-struct ir_scancode ir_codes_dibusb_table[] = {
+struct rc_map_table rc_map_dibusb_table[] = {
/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
@@ -456,7 +456,7 @@ struct ir_scancode ir_codes_dibusb_table[] = {
{ 0x804e, KEY_ENTER },
{ 0x804f, KEY_VOLUMEDOWN },
};
-EXPORT_SYMBOL(ir_codes_dibusb_table);
+EXPORT_SYMBOL(rc_map_dibusb_table);
int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 8e3c0d2cce16..04d91bdd3562 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -213,8 +213,8 @@ static struct dvb_usb_device_properties dibusb1_1_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@@ -299,8 +299,8 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@@ -365,8 +365,8 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
@@ -424,8 +424,8 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 1cbc41cb4e8f..c1d9094b61e5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -83,8 +83,8 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
.rc.legacy = {
.rc_interval = DEFAULT_RC_INTERVAL,
- .rc_key_map = ir_codes_dibusb_table,
- .rc_key_map_size = 111, /* FIXME */
+ .rc_map_table = rc_map_dibusb_table,
+ .rc_map_size = 111, /* FIXME */
.rc_query = dibusb_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 61a6bf389472..e47c321b3ffc 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);
#define DEFAULT_RC_INTERVAL 150
//#define DEFAULT_RC_INTERVAL 100000
-extern struct ir_scancode ir_codes_dibusb_table[];
+extern struct rc_map_table rc_map_dibusb_table[];
extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 13d006bb19db..f2dbce7edb3b 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)
return 0;
}
-static struct ir_scancode ir_codes_digitv_table[] = {
+static struct rc_map_table rc_map_digitv_table[] = {
{ 0x5f55, KEY_0 },
{ 0x6f55, KEY_1 },
{ 0x9f55, KEY_2 },
@@ -237,10 +237,10 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
/* if something is inside the buffer, simulate key press */
if (key[1] != 0)
{
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
- if (rc5_custom(&d->props.rc.legacy.rc_key_map[i]) == key[1] &&
- rc5_data(&d->props.rc.legacy.rc_key_map[i]) == key[2]) {
- *event = d->props.rc.legacy.rc_key_map[i].keycode;
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
+ if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
+ rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
+ *event = d->props.rc.legacy.rc_map_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
return 0;
}
@@ -312,8 +312,8 @@ static struct dvb_usb_device_properties digitv_properties = {
.rc.legacy = {
.rc_interval = 1000,
- .rc_key_map = ir_codes_digitv_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_digitv_table),
+ .rc_map_table = rc_map_digitv_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_digitv_table),
.rc_query = digitv_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index ca495e07f35c..ecd86eca2548 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,
/* remote control */
/* key list for the tiny remote control (Yakumo, don't know about the others) */
-static struct ir_scancode ir_codes_dtt200u_table[] = {
+static struct rc_map_table rc_map_dtt200u_table[] = {
{ 0x8001, KEY_MUTE },
{ 0x8002, KEY_CHANNELDOWN },
{ 0x8003, KEY_VOLUMEDOWN },
@@ -163,8 +163,8 @@ static struct dvb_usb_device_properties dtt200u_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@@ -210,8 +210,8 @@ static struct dvb_usb_device_properties wt220u_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@@ -257,8 +257,8 @@ static struct dvb_usb_device_properties wt220u_fc_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
@@ -304,8 +304,8 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
.rc.legacy = {
.rc_interval = 300,
- .rc_key_map = ir_codes_dtt200u_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dtt200u_table),
+ .rc_map_table = rc_map_dtt200u_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
.rc_query = dtt200u_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 192a40ce583d..824b1cf2a174 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -311,4 +311,5 @@
#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac
#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001
#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
+#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index b579fed3ab3f..532d2aa491e8 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -13,11 +13,11 @@ static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
{
struct dvb_usb_device *d = input_get_drvdata(dev);
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int i;
/* See if we can match the raw key code. */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].scancode == scancode) {
*keycode = keymap[i].keycode;
return 0;
@@ -28,7 +28,7 @@ static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
* otherwise, input core won't let legacy_dvb_usb_setkeycode
* to work
*/
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].keycode == KEY_RESERVED ||
keymap[i].keycode == KEY_UNKNOWN) {
*keycode = KEY_RESERVED;
@@ -43,18 +43,18 @@ static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
{
struct dvb_usb_device *d = input_get_drvdata(dev);
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
int i;
/* Search if it is replacing an existing keycode */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].scancode == scancode) {
keymap[i].keycode = keycode;
return 0;
}
/* Search if is there a clean entry. If so, use it */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (keymap[i].keycode == KEY_RESERVED ||
keymap[i].keycode == KEY_UNKNOWN) {
keymap[i].scancode = scancode;
@@ -106,10 +106,10 @@ static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
- input_event(d->rc_input_dev, EV_KEY, event, 1);
- input_sync(d->rc_input_dev);
- input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(d->rc_input_dev);
+ input_event(d->input_dev, EV_KEY, event, 1);
+ input_sync(d->input_dev);
+ input_event(d->input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->input_dev);
break;
default:
break;
@@ -154,20 +154,32 @@ schedule:
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
}
-static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d,
- struct input_dev *input_dev)
+static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i, err, rc_interval;
+ struct input_dev *input_dev;
+
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ input_dev->name = "IR-receiver inside an USB DVB receiver";
+ input_dev->phys = d->rc_phys;
+ usb_to_input_id(d->udev, &input_dev->id);
+ input_dev->dev.parent = &d->udev->dev;
+ d->input_dev = input_dev;
+ d->rc_dev = NULL;
input_dev->getkeycode = legacy_dvb_usb_getkeycode;
input_dev->setkeycode = legacy_dvb_usb_setkeycode;
/* set the bits for the keys */
- deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size);
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
+ deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
deb_rc("setting bit for event %d item %d\n",
- d->props.rc.legacy.rc_key_map[i].keycode, i);
- set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit);
+ d->props.rc.legacy.rc_map_table[i].keycode, i);
+ set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
}
/* setting these two values to non-zero, we have to manage key repeats */
@@ -221,18 +233,34 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
msecs_to_jiffies(d->props.rc.core.rc_interval));
}
-static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
- struct input_dev *input_dev)
+static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int err, rc_interval;
+ struct rc_dev *dev;
+
+ dev = rc_allocate_device();
+ if (!dev)
+ return -ENOMEM;
- d->props.rc.core.rc_props.priv = d;
- err = ir_input_register(input_dev,
- d->props.rc.core.rc_codes,
- &d->props.rc.core.rc_props,
- d->props.rc.core.module_name);
- if (err < 0)
+ dev->driver_name = d->props.rc.core.module_name;
+ dev->map_name = d->props.rc.core.rc_codes;
+ dev->change_protocol = d->props.rc.core.change_protocol;
+ dev->allowed_protos = d->props.rc.core.allowed_protos;
+ dev->driver_type = d->props.rc.core.driver_type;
+ usb_to_input_id(d->udev, &dev->input_id);
+ dev->input_name = "IR-receiver inside an USB DVB receiver";
+ dev->input_phys = d->rc_phys;
+ dev->dev.parent = &d->udev->dev;
+ dev->priv = d;
+
+ err = rc_register_device(dev);
+ if (err < 0) {
+ rc_free_device(dev);
return err;
+ }
+
+ d->input_dev = NULL;
+ d->rc_dev = dev;
if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
return 0;
@@ -251,13 +279,12 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
- struct input_dev *input_dev;
int err;
if (dvb_usb_disable_rc_polling)
return 0;
- if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query)
+ if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
d->props.rc.mode = DVB_RC_LEGACY;
else if (d->props.rc.core.rc_codes)
d->props.rc.mode = DVB_RC_CORE;
@@ -267,26 +294,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY);
- input_dev->name = "IR-receiver inside an USB DVB receiver";
- input_dev->phys = d->rc_phys;
- usb_to_input_id(d->udev, &input_dev->id);
- input_dev->dev.parent = &d->udev->dev;
-
/* Start the remote-control polling. */
if (d->props.rc.legacy.rc_interval < 40)
d->props.rc.legacy.rc_interval = 100; /* default */
- d->rc_input_dev = input_dev;
-
if (d->props.rc.mode == DVB_RC_LEGACY)
- err = legacy_dvb_usb_remote_init(d, input_dev);
+ err = legacy_dvb_usb_remote_init(d);
else
- err = rc_core_dvb_usb_remote_init(d, input_dev);
+ err = rc_core_dvb_usb_remote_init(d);
if (err)
return err;
@@ -301,9 +316,9 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
cancel_rearming_delayed_work(&d->rc_query_work);
flush_scheduled_work();
if (d->props.rc.mode == DVB_RC_LEGACY)
- input_unregister_device(d->rc_input_dev);
+ input_unregister_device(d->input_dev);
else
- ir_input_unregister(d->rc_input_dev);
+ rc_unregister_device(d->rc_dev);
}
d->state &= ~DVB_USB_STATE_REMOTE;
return 0;
@@ -316,7 +331,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
u8 keybuf[5], u32 *event, int *state)
{
int i;
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
switch (keybuf[0]) {
@@ -329,7 +344,7 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
break;
}
/* See if we can match the raw key code. */
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
if (rc5_custom(&keymap[i]) == keybuf[1] &&
rc5_data(&keymap[i]) == keybuf[3]) {
*event = keymap[i].keycode;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 34f7b3ba8cc7..60f7044b0f46 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -14,7 +14,7 @@
#include <linux/usb.h>
#include <linux/firmware.h>
#include <linux/mutex.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "dvb_frontend.h"
#include "dvb_demux.h"
@@ -75,17 +75,17 @@ struct dvb_usb_device_description {
struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
};
-static inline u8 rc5_custom(struct ir_scancode *key)
+static inline u8 rc5_custom(struct rc_map_table *key)
{
return (key->scancode >> 8) & 0xff;
}
-static inline u8 rc5_data(struct ir_scancode *key)
+static inline u8 rc5_data(struct rc_map_table *key)
{
return key->scancode & 0xff;
}
-static inline u8 rc5_scan(struct ir_scancode *key)
+static inline u8 rc5_scan(struct rc_map_table *key)
{
return key->scancode & 0xffff;
}
@@ -159,9 +159,9 @@ struct dvb_usb_adapter_properties {
/**
* struct dvb_rc_legacy - old properties of remote controller
- * @rc_key_map: a hard-wired array of struct ir_scancode (NULL to disable
+ * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
* remote control handling).
- * @rc_key_map_size: number of items in @rc_key_map.
+ * @rc_map_size: number of items in @rc_map_table.
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
*/
@@ -170,8 +170,8 @@ struct dvb_rc_legacy {
#define REMOTE_NO_KEY_PRESSED 0x00
#define REMOTE_KEY_PRESSED 0x01
#define REMOTE_KEY_REPEAT 0x02
- struct ir_scancode *rc_key_map;
- int rc_key_map_size;
+ struct rc_map_table *rc_map_table;
+ int rc_map_size;
int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
int rc_interval;
};
@@ -180,19 +180,22 @@ struct dvb_rc_legacy {
* struct dvb_rc properties of remote controller, using rc-core
* @rc_codes: name of rc codes table
* @protocol: type of protocol(s) currently used by the driver
+ * @allowed_protos: protocol(s) supported by the driver
+ * @change_protocol: callback to change protocol
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
- * @rc_props: remote controller properties
* @bulk_mode: device supports bulk mode for RC (disable polling mode)
*/
struct dvb_rc {
char *rc_codes;
u64 protocol;
+ u64 allowed_protos;
+ int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
char *module_name;
int (*rc_query) (struct dvb_usb_device *d);
int rc_interval;
- struct ir_dev_props rc_props;
bool bulk_mode; /* uses bulk mode */
+ enum rc_driver_type driver_type;
};
/**
@@ -385,7 +388,8 @@ struct dvb_usb_adapter {
*
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
*
- * @rc_input_dev: input device for the remote control.
+ * @rc_dev: rc device for the remote control (rc-core mode)
+ * @input_dev: input device for the remote control (legacy mode)
* @rc_query_work: struct work_struct frequent rc queries
* @last_event: last triggered event
* @last_state: last state (no, pressed, repeat)
@@ -418,7 +422,8 @@ struct dvb_usb_device {
struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
/* remote control */
- struct input_dev *rc_input_dev;
+ struct rc_dev *rc_dev;
+ struct input_dev *input_dev;
char rc_phys[64];
struct delayed_work rc_query_work;
u32 last_event;
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 774df88dc6e3..2c307ba0d28b 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -73,8 +73,8 @@
"Please see linux/Documentation/dvb/ for more details " \
"on firmware-problems."
-struct ir_codes_dvb_usb_table_table {
- struct ir_scancode *rc_keys;
+struct rc_map_dvb_usb_table_table {
+ struct rc_map_table *rc_keys;
int rc_keys_size;
};
@@ -948,7 +948,7 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
-static struct ir_scancode ir_codes_dw210x_table[] = {
+static struct rc_map_table rc_map_dw210x_table[] = {
{ 0xf80a, KEY_Q }, /*power*/
{ 0xf80c, KEY_M }, /*mute*/
{ 0xf811, KEY_1 },
@@ -982,7 +982,7 @@ static struct ir_scancode ir_codes_dw210x_table[] = {
{ 0xf81b, KEY_B }, /*recall*/
};
-static struct ir_scancode ir_codes_tevii_table[] = {
+static struct rc_map_table rc_map_tevii_table[] = {
{ 0xf80a, KEY_POWER },
{ 0xf80c, KEY_MUTE },
{ 0xf811, KEY_1 },
@@ -1032,7 +1032,7 @@ static struct ir_scancode ir_codes_tevii_table[] = {
{ 0xf858, KEY_SWITCHVIDEOMODE },
};
-static struct ir_scancode ir_codes_tbs_table[] = {
+static struct rc_map_table rc_map_tbs_table[] = {
{ 0xf884, KEY_POWER },
{ 0xf894, KEY_MUTE },
{ 0xf887, KEY_1 },
@@ -1067,16 +1067,16 @@ static struct ir_scancode ir_codes_tbs_table[] = {
{ 0xf89b, KEY_MODE }
};
-static struct ir_codes_dvb_usb_table_table keys_tables[] = {
- { ir_codes_dw210x_table, ARRAY_SIZE(ir_codes_dw210x_table) },
- { ir_codes_tevii_table, ARRAY_SIZE(ir_codes_tevii_table) },
- { ir_codes_tbs_table, ARRAY_SIZE(ir_codes_tbs_table) },
+static struct rc_map_dvb_usb_table_table keys_tables[] = {
+ { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
+ { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
+ { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
};
static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
- int keymap_size = d->props.rc.legacy.rc_key_map_size;
+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
+ int keymap_size = d->props.rc.legacy.rc_map_size;
u8 key[2];
struct i2c_msg msg = {
.addr = DW2102_RC_QUERY,
@@ -1185,14 +1185,14 @@ static int dw2102_load_firmware(struct usb_device *dev,
/* init registers */
switch (dev->descriptor.idProduct) {
case USB_PID_PROF_1100:
- s6x0_properties.rc.legacy.rc_key_map = ir_codes_tbs_table;
- s6x0_properties.rc.legacy.rc_key_map_size =
- ARRAY_SIZE(ir_codes_tbs_table);
+ s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
+ s6x0_properties.rc.legacy.rc_map_size =
+ ARRAY_SIZE(rc_map_tbs_table);
break;
case USB_PID_TEVII_S650:
- dw2104_properties.rc.legacy.rc_key_map = ir_codes_tevii_table;
- dw2104_properties.rc.legacy.rc_key_map_size =
- ARRAY_SIZE(ir_codes_tevii_table);
+ dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
+ dw2104_properties.rc.legacy.rc_map_size =
+ ARRAY_SIZE(rc_map_tevii_table);
case USB_PID_DW2104:
reset = 1;
dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
@@ -1257,8 +1257,8 @@ static struct dvb_usb_device_properties dw2102_properties = {
.i2c_algo = &dw2102_serit_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_dw210x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
+ .rc_map_table = rc_map_dw210x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1310,8 +1310,8 @@ static struct dvb_usb_device_properties dw2104_properties = {
.i2c_algo = &dw2104_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_dw210x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
+ .rc_map_table = rc_map_dw210x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1359,8 +1359,8 @@ static struct dvb_usb_device_properties dw3101_properties = {
.i2c_algo = &dw3101_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_dw210x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
+ .rc_map_table = rc_map_dw210x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1404,8 +1404,8 @@ static struct dvb_usb_device_properties s6x0_properties = {
.i2c_algo = &s6x0_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_tevii_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table),
+ .rc_map_table = rc_map_tevii_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
},
@@ -1468,8 +1468,8 @@ static int dw2102_probe(struct usb_interface *intf,
/* fill only different fields */
p7500->firmware = "dvb-usb-p7500.fw";
p7500->devices[0] = d7500;
- p7500->rc.legacy.rc_key_map = ir_codes_tbs_table;
- p7500->rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table);
+ p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
+ p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
p7500->adapter->frontend_attach = prof_7500_frontend_attach;
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 c821293dbc22..1cb3d9a66e02 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -24,6 +24,33 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DV
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
+{
+ return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
+}
+
+static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
+{
+ return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
+}
+
+static void gp8psk_info(struct dvb_usb_device *d)
+{
+ u8 fpga_vers, fw_vers[6];
+
+ if (!gp8psk_get_fw_version(d, fw_vers))
+ info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i",
+ fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
+ 2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
+ else
+ info("failed to get FW version");
+
+ if (!gp8psk_get_fpga_version(d, &fpga_vers))
+ info("FPGA Version = %i", fpga_vers);
+ else
+ info("failed to get FPGA version");
+}
+
int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
{
int ret = 0,try = 0;
@@ -146,6 +173,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
return -EINVAL;
+ gp8psk_info(d);
}
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
index e83a57506cfa..831749a518cb 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.h
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -25,7 +25,6 @@ extern int dvb_usb_gp8psk_debug;
#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
-/* gp8psk commands */
/* Twinhan Vendor requests */
#define TH_COMMAND_IN 0xC0
@@ -49,8 +48,10 @@ extern int dvb_usb_gp8psk_debug;
#define SET_DVB_MODE 0x8E
#define SET_DN_SWITCH 0x8F
#define GET_SIGNAL_LOCK 0x90 /* in */
+#define GET_FW_VERS 0x92
#define GET_SERIAL_NUMBER 0x93 /* in */
#define USE_EXTRA_VOLT 0x94
+#define GET_FPGA_VERS 0x95
#define CW3K_INIT 0x9d
/* PSK_configuration bits */
@@ -88,6 +89,11 @@ extern int dvb_usb_gp8psk_debug;
#define PRODUCT_STRING_READ 0x0D
#define FW_BCD_VERSION_READ 0x14
+/* firmware revision id's */
+#define GP8PSK_FW_REV1 0x020604
+#define GP8PSK_FW_REV2 0x020704
+#define GP8PSK_FW_VERS(_fw_vers) ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
+
extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index d939fbbf9fe6..1455c238b01b 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -61,7 +61,7 @@
#define DVB_USB_LOG_PREFIX "LME2510(C)"
#include <linux/usb.h>
#include <linux/usb/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "dvb-usb.h"
#include "lmedm04.h"
@@ -112,7 +112,6 @@ struct lme2510_state {
u8 i2c_tuner_gate_r;
u8 i2c_tuner_addr;
u8 stream_on;
- u8 one_tune;
void *buffer;
struct urb *lme_urb;
void *usb_buffer;
@@ -125,7 +124,7 @@ static int lme2510_bulk_write(struct usb_device *dev,
int ret, actual_l;
ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
- snd, len , &actual_l, 500);
+ snd, len , &actual_l, 100);
return ret;
}
@@ -135,7 +134,7 @@ static int lme2510_bulk_read(struct usb_device *dev,
int ret, actual_l;
ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
- rev, len , &actual_l, 500);
+ rev, len , &actual_l, 200);
return ret;
}
@@ -167,7 +166,7 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
- msleep(12);
+ msleep(10);
ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
@@ -182,15 +181,13 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
return (ret < 0) ? -ENODEV : 0;
}
-static int lme2510_usb_talk_restart(struct dvb_usb_device *d,
- u8 *wbuf, int wlen, u8 *rbuf, int rlen) {
+static int lme2510_stream_restart(struct dvb_usb_device *d)
+{
static u8 stream_on[] = LME_ST_ON_W;
int ret;
u8 rbuff[10];
- /*Send Normal Command*/
- ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
/*Restart Stream Command*/
- ret |= lme2510_usb_talk(d, stream_on, sizeof(stream_on),
+ ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
rbuff, sizeof(rbuff));
return ret;
}
@@ -201,7 +198,7 @@ static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
deb_info(1, "INT Key Keypress =%04x", keypress);
if (keypress > 0)
- ir_keydown(d->rc_input_dev, keypress, 0);
+ rc_keydown(d->rc_dev, keypress, 0);
return 0;
}
@@ -254,11 +251,16 @@ static void lme2510_int_response(struct urb *lme_urb)
case TUNER_S7395:
/* Tweak for earlier firmware*/
if (ibuf[1] == 0x03) {
+ if (ibuf[2] > 1)
+ st->signal_lock = ibuf[2];
st->signal_level = ibuf[3];
st->signal_sn = ibuf[4];
} else {
st->signal_level = ibuf[4];
st->signal_sn = ibuf[5];
+ st->signal_lock =
+ (st->signal_lock & 0xf7) +
+ ((ibuf[2] & 0x01) << 0x03);
}
break;
default:
@@ -341,11 +343,10 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->signal_lock = rbuf[1];
if ((st->stream_on & 1) &&
(st->signal_lock & 0x10)) {
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ lme2510_stream_restart(d);
st->i2c_talk_onoff = 0;
}
- msleep(80);
+ msleep(80);
}
}
break;
@@ -355,15 +356,12 @@ static int lme2510_msg(struct dvb_usb_device *d,
st->signal_lock = rbuf[1];
if ((st->stream_on & 1) &&
(st->signal_lock & 0x8)) {
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ lme2510_stream_restart(d);
st->i2c_talk_onoff = 0;
}
}
if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
msleep(5);
-
-
}
break;
default:
@@ -385,18 +383,16 @@ static int lme2510_msg(struct dvb_usb_device *d,
rbuf[0] = 0x55;
rbuf[1] = st->signal_sn;
break;
- /*DiSEqC functions as per TDA10086*/
- case 0x36:
- case 0x48:
- case 0x49:
- case 0x4a:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- if (wbuf[2] == 0x1c)
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ rbuf[0] = 0x55;
+ rbuf[1] = 0x00;
+ break;
default:
+ lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+ st->i2c_talk_onoff = 1;
break;
}
break;
@@ -413,39 +409,22 @@ static int lme2510_msg(struct dvb_usb_device *d,
break;
case 0x24:
rbuf[0] = 0x55;
- rbuf[1] = (st->signal_level & 0x80)
- ? 0 : st->signal_lock;
- break;
- case 0x6:
- if (wbuf[2] == 0xd0)
- lme2510_usb_talk(d,
- wbuf, wlen, rbuf, rlen);
- break;
- case 0x1:
- if (st->one_tune > 0)
- break;
- st->one_tune++;
- st->i2c_talk_onoff = 1;
- /*DiSEqC functions as per STV0288*/
- case 0x5:
- case 0x7:
- case 0x8:
- case 0x9:
- case 0xa:
- case 0xb:
- if (wbuf[2] == 0xd0)
- lme2510_usb_talk_restart(d,
- wbuf, wlen, rbuf, rlen);
+ rbuf[1] = st->signal_lock;
break;
- default:
+ case 0x2e:
+ case 0x26:
+ case 0x27:
rbuf[0] = 0x55;
rbuf[1] = 0x00;
break;
+ default:
+ lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
+ st->i2c_talk_onoff = 1;
+ break;
}
break;
default:
break;
-
}
deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)",
@@ -548,35 +527,26 @@ static int lme2510_identify_state(struct usb_device *udev,
static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct lme2510_state *st = adap->dev->priv;
- static u8 stream_on[] = LME_ST_ON_W;
static u8 clear_reg_3[] = LME_CLEAR_PID;
static u8 rbuf[1];
- static u8 timeout;
- int ret = 0, len = 2, rlen = sizeof(rbuf);
+ int ret = 0, rlen = sizeof(rbuf);
deb_info(1, "STM (%02x)", onoff);
- if (onoff == 1) {
- st->i2c_talk_onoff = 0;
- timeout = 0;
- /* wait for i2C to be free */
- while (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) {
- timeout++;
- if (timeout > 5)
- return -ENODEV;
- }
- msleep(100);
- ret |= lme2510_usb_talk(adap->dev,
- stream_on, len, rbuf, rlen);
+ /* Streaming is started by FE_HAS_LOCK */
+ if (onoff == 1)
st->stream_on = 1;
- st->one_tune = 0;
- mutex_unlock(&adap->dev->i2c_mutex);
- } else {
+ else {
deb_info(1, "STM Steam Off");
+ /* mutex is here only to avoid collision with I2C */
+ ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
+
ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
st->stream_on = 0;
st->i2c_talk_onoff = 1;
+
+ mutex_unlock(&adap->dev->i2c_mutex);
}
return (ret < 0) ? -ENODEV : 0;
@@ -585,41 +555,39 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int lme2510_int_service(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap->dev;
- struct input_dev *input_dev;
- char *ir_codes = RC_MAP_LME2510;
- int ret = 0;
+ struct rc_dev *rc;
+ int ret;
info("STA Configuring Remote");
- usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-
- strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-
- input_dev = input_allocate_device();
- if (!input_dev)
+ rc = rc_allocate_device();
+ if (!rc)
return -ENOMEM;
- input_dev->name = "LME2510 Remote Control";
- input_dev->phys = d->rc_phys;
-
- usb_to_input_id(d->udev, &input_dev->id);
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+ strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510");
+ rc->input_name = "LME2510 Remote Control";
+ rc->input_phys = d->rc_phys;
+ rc->map_name = RC_MAP_LME2510;
+ rc->driver_name = "LME 2510";
+ usb_to_input_id(d->udev, &rc->input_id);
+ ret = rc_register_device(rc);
if (ret) {
- input_free_device(input_dev);
+ rc_free_device(rc);
return ret;
}
+ d->rc_dev = rc;
- d->rc_input_dev = input_dev;
/* Start the Interupt */
ret = lme2510_int_read(adap);
-
if (ret < 0) {
- ir_input_unregister(input_dev);
- input_free_device(input_dev);
+ rc_unregister_device(rc);
+ return -ENODEV;
}
- return (ret < 0) ? -ENODEV : 0;
+
+ return 0;
}
static u8 check_sum(u8 *p, u8 len)
@@ -668,6 +636,7 @@ static int lme2510_download_firmware(struct usb_device *dev,
ret |= (data[0] == 0x88) ? 0 : -1;
}
}
+
usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
@@ -701,6 +670,7 @@ static void lme_coldreset(struct usb_device *dev)
info("FRM Firmware Cold Reset");
ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/
ret |= lme2510_bulk_read(dev, data, len_in, 1);
+
return;
}
@@ -712,6 +682,8 @@ static void lme_firmware_switch(struct usb_device *udev, int cold)
char *firm_msg[] = {"Loading", "Switching to"};
int ret;
+ cold = (cold > 0) ? (cold & 1) : 0;
+
if (udev->descriptor.idProduct == 0x1122)
return;
@@ -740,22 +712,26 @@ static void lme_firmware_switch(struct usb_device *udev, int cold)
cold = 0;
break;
}
+
release_firmware(fw);
+
if (cold)
lme_coldreset(udev);
+
return;
}
static int lme2510_kill_urb(struct usb_data_stream *stream)
{
int i;
+
for (i = 0; i < stream->urbs_submitted; i++) {
deb_info(3, "killing URB no. %d.", i);
-
/* stop the URB */
usb_kill_urb(stream->urb_list[i]);
}
stream->urbs_submitted = 0;
+
return 0;
}
@@ -783,18 +759,13 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct lme2510_state *st = adap->dev->priv;
static u8 voltage_low[] = LME_VOLTAGE_L;
static u8 voltage_high[] = LME_VOLTAGE_H;
- static u8 lnb_on[] = LNB_ON;
- static u8 lnb_off[] = LNB_OFF;
static u8 rbuf[1];
int ret = 0, len = 3, rlen = 1;
- if (st->stream_on == 1)
- return 0;
-
- ret |= lme2510_usb_talk(adap->dev, lnb_on, len, rbuf, rlen);
+ if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
+ return -EAGAIN;
switch (voltage) {
case SEC_VOLTAGE_18:
@@ -803,17 +774,15 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
break;
case SEC_VOLTAGE_OFF:
- ret |= lme2510_usb_talk(adap->dev,
- lnb_off, len, rbuf, rlen);
case SEC_VOLTAGE_13:
default:
ret |= lme2510_usb_talk(adap->dev,
voltage_low, len, rbuf, rlen);
break;
+ }
+ mutex_unlock(&adap->dev->i2c_mutex);
- };
- st->i2c_talk_onoff = 1;
return (ret < 0) ? -ENODEV : 0;
}
@@ -850,12 +819,14 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
if (dvb_usb_lme2510_firmware != 1) {
dvb_usb_lme2510_firmware = 1;
lme_firmware_switch(adap->dev->udev, 1);
- }
+ } else /*stops LG/Sharp multi tuner problems*/
+ dvb_usb_lme2510_firmware = 0;
return 0;
}
kfree(adap->fe);
adap->fe = NULL;
}
+
st->i2c_gate = 5;
adap->fe = dvb_attach(stv0288_attach, &lme_config,
&adap->dev->i2c_adap);
@@ -889,8 +860,23 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
{
struct lme2510_state *st = d->priv;
+ static u8 lnb_on[] = LNB_ON;
+ static u8 lnb_off[] = LNB_OFF;
+ static u8 rbuf[1];
+ int ret, len = 3, rlen = 1;
+
+ ret = mutex_lock_interruptible(&d->i2c_mutex);
+
+ if (onoff)
+ ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
+ else
+ ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+
st->i2c_talk_onoff = 1;
- return 0;
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
}
/* DVB USB Driver stuff */
@@ -1036,7 +1022,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d)
usb_free_coherent(d->udev, 5000, st->buffer,
st->lme_urb->transfer_dma);
info("Interupt Service Stopped");
- ir_input_unregister(d->rc_input_dev);
+ rc_unregister_device(d->rc_dev);
info("Remote Stopped");
}
return buffer;
@@ -1084,5 +1070,5 @@ module_exit(lme2510_module_exit);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0");
-MODULE_VERSION("1.60");
+MODULE_VERSION("1.71");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index bdef1a18b664..da9dc91ce910 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -142,9 +142,9 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
goto unlock;
- for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
- if (rc5_data(&d->props.rc.legacy.rc_key_map[i]) == rc_state[1]) {
- *event = d->props.rc.legacy.rc_key_map[i].keycode;
+ for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
+ if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
+ *event = d->props.rc.legacy.rc_map_table[i].keycode;
switch(rc_state[0]) {
case 0x80:
@@ -589,7 +589,7 @@ static struct m920x_inits pinnacle310e_init[] = {
};
/* ir keymaps */
-static struct ir_scancode ir_codes_megasky_table[] = {
+static struct rc_map_table rc_map_megasky_table[] = {
{ 0x0012, KEY_POWER },
{ 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
{ 0x0002, KEY_CHANNELUP },
@@ -608,7 +608,7 @@ static struct ir_scancode ir_codes_megasky_table[] = {
{ 0x000e, KEY_COFFEE }, /* "MTS" */
};
-static struct ir_scancode ir_codes_tvwalkertwin_table[] = {
+static struct rc_map_table rc_map_tvwalkertwin_table[] = {
{ 0x0001, KEY_ZOOM }, /* Full Screen */
{ 0x0002, KEY_CAMERA }, /* snapshot */
{ 0x0003, KEY_MUTE },
@@ -628,7 +628,7 @@ static struct ir_scancode ir_codes_tvwalkertwin_table[] = {
{ 0x001e, KEY_VOLUMEUP },
};
-static struct ir_scancode ir_codes_pinnacle310e_table[] = {
+static struct rc_map_table rc_map_pinnacle310e_table[] = {
{ 0x16, KEY_POWER },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
@@ -786,8 +786,8 @@ static struct dvb_usb_device_properties megasky_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_megasky_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_megasky_table),
+ .rc_map_table = rc_map_megasky_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_megasky_table),
.rc_query = m920x_rc_query,
},
@@ -889,8 +889,8 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_tvwalkertwin_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_tvwalkertwin_table),
+ .rc_map_table = rc_map_tvwalkertwin_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_tvwalkertwin_table),
.rc_query = m920x_rc_query,
},
@@ -998,8 +998,8 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_pinnacle310e_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_pinnacle310e_table),
+ .rc_map_table = rc_map_pinnacle310e_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_pinnacle310e_table),
.rc_query = m920x_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 181f36a12e2a..9d3cd2de46fc 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);
#define deb_ee(args...) dprintk(debug,0x02,args)
/* Hauppauge NOVA-T USB2 keys */
-static struct ir_scancode ir_codes_haupp_table[] = {
+static struct rc_map_table rc_map_haupp_table[] = {
{ 0x1e00, KEY_0 },
{ 0x1e01, KEY_1 },
{ 0x1e02, KEY_2 },
@@ -91,14 +91,14 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
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);
- for (i = 0; i < ARRAY_SIZE(ir_codes_haupp_table); i++) {
- if (rc5_data(&ir_codes_haupp_table[i]) == data &&
- rc5_custom(&ir_codes_haupp_table[i]) == custom) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
+ if (rc5_data(&rc_map_haupp_table[i]) == data &&
+ rc5_custom(&rc_map_haupp_table[i]) == custom) {
- deb_rc("c: %x, d: %x\n", rc5_data(&ir_codes_haupp_table[i]),
- rc5_custom(&ir_codes_haupp_table[i]));
+ deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
+ rc5_custom(&rc_map_haupp_table[i]));
- *event = ir_codes_haupp_table[i].keycode;
+ *event = rc_map_haupp_table[i].keycode;
*state = REMOTE_KEY_PRESSED;
if (st->old_toggle == toggle) {
if (st->last_repeat_count++ < 2)
@@ -197,8 +197,8 @@ static struct dvb_usb_device_properties nova_t_properties = {
.rc.legacy = {
.rc_interval = 100,
- .rc_key_map = ir_codes_haupp_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_haupp_table),
+ .rc_map_table = rc_map_haupp_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_haupp_table),
.rc_query = nova_t_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index f896337b4535..1f1b7d6980a5 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -35,7 +35,7 @@
struct opera1_state {
u32 last_key_pressed;
};
-struct ir_codes_opera_table {
+struct rc_map_opera_table {
u32 keycode;
u32 event;
};
@@ -331,7 +331,7 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
return 0;
}
-static struct ir_scancode ir_codes_opera1_table[] = {
+static struct rc_map_table rc_map_opera1_table[] = {
{0x5fa0, KEY_1},
{0x51af, KEY_2},
{0x5da2, KEY_3},
@@ -404,12 +404,12 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
send_key = (send_key & 0xffff) | 0x0100;
- for (i = 0; i < ARRAY_SIZE(ir_codes_opera1_table); i++) {
- if (rc5_scan(&ir_codes_opera1_table[i]) == (send_key & 0xffff)) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
+ if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
*state = REMOTE_KEY_PRESSED;
- *event = ir_codes_opera1_table[i].keycode;
+ *event = rc_map_opera1_table[i].keycode;
opst->last_key_pressed =
- ir_codes_opera1_table[i].keycode;
+ rc_map_opera1_table[i].keycode;
break;
}
opst->last_key_pressed = 0;
@@ -497,8 +497,8 @@ static struct dvb_usb_device_properties opera1_properties = {
.i2c_algo = &opera1_i2c_algo,
.rc.legacy = {
- .rc_key_map = ir_codes_opera1_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_opera1_table),
+ .rc_map_table = rc_map_opera1_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
.rc_interval = 200,
.rc_query = opera1_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c
new file mode 100644
index 000000000000..cce1559f7bfe
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c
@@ -0,0 +1,807 @@
+/*
+ * Linux driver for Technisat DVB-S/S2 USB 2.0 device
+ *
+ * Copyright (C) 2010 Patrick Boettcher,
+ * Kernel Labs Inc. PO Box 745, St James, NY 11780
+ *
+ * Development was sponsored by Technisat Digital UK Limited, whose
+ * registered office is Witan Gate House 500 - 600 Witan Gate West,
+ * Milton Keynes, MK9 1SH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
+ * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
+ * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
+ * GNU General Public License for more details.
+ */
+
+#define DVB_USB_LOG_PREFIX "technisat-usb2"
+#include "dvb-usb.h"
+
+#include "stv6110x.h"
+#include "stv090x.h"
+
+/* module parameters */
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,
+ "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
+ DVB_USB_DEBUG_STATUS);
+
+/* disables all LED control command and
+ * also does not start the signal polling thread */
+static int disable_led_control;
+module_param(disable_led_control, int, 0444);
+MODULE_PARM_DESC(disable_led_control,
+ "disable LED control of the device "
+ "(default: 0 - LED control is active).");
+
+/* device private data */
+struct technisat_usb2_state {
+ struct dvb_usb_device *dev;
+ struct delayed_work green_led_work;
+ u8 power_state;
+
+ u16 last_scan_code;
+};
+
+/* debug print helpers */
+#define deb_info(args...) dprintk(debug, 0x01, args)
+#define deb_eeprom(args...) dprintk(debug, 0x02, args)
+#define deb_i2c(args...) dprintk(debug, 0x04, args)
+#define deb_rc(args...) dprintk(debug, 0x08, args)
+
+/* vendor requests */
+#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
+#define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4
+#define GET_VERSION_INFO_VENDOR_REQUEST 0xB5
+#define SET_GREEN_LED_VENDOR_REQUEST 0xB6
+#define SET_RED_LED_VENDOR_REQUEST 0xB7
+#define GET_IR_DATA_VENDOR_REQUEST 0xB8
+#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9
+#define SET_USB_REENUMERATION 0xBA
+
+/* i2c-access methods */
+#define I2C_SPEED_100KHZ_BIT 0x40
+
+#define I2C_STATUS_NAK 7
+#define I2C_STATUS_OK 8
+
+static int technisat_usb2_i2c_access(struct usb_device *udev,
+ u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+{
+ u8 b[64];
+ int ret, actual_length;
+
+ deb_i2c("i2c-access: %02x, tx: ", device_addr);
+ debug_dump(tx, txlen, deb_i2c);
+ deb_i2c(" ");
+
+ if (txlen > 62) {
+ err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
+ device_addr);
+ txlen = 62;
+ }
+ if (rxlen > 62) {
+ err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
+ device_addr);
+ txlen = 62;
+ }
+
+ b[0] = I2C_SPEED_100KHZ_BIT;
+ b[1] = device_addr << 1;
+
+ if (rx != NULL) {
+ b[0] |= rxlen;
+ b[1] |= 1;
+ }
+
+ memcpy(&b[2], tx, txlen);
+ ret = usb_bulk_msg(udev,
+ usb_sndbulkpipe(udev, 0x01),
+ b, 2 + txlen,
+ NULL, 1000);
+
+ if (ret < 0) {
+ err("i2c-error: out failed %02x = %d", device_addr, ret);
+ return -ENODEV;
+ }
+
+ ret = usb_bulk_msg(udev,
+ usb_rcvbulkpipe(udev, 0x01),
+ b, 64, &actual_length, 1000);
+ if (ret < 0) {
+ err("i2c-error: in failed %02x = %d", device_addr, ret);
+ return -ENODEV;
+ }
+
+ if (b[0] != I2C_STATUS_OK) {
+ err("i2c-error: %02x = %d", device_addr, b[0]);
+ /* handle tuner-i2c-nak */
+ if (!(b[0] == I2C_STATUS_NAK &&
+ device_addr == 0x60
+ /* && device_is_technisat_usb2 */))
+ return -ENODEV;
+ }
+
+ deb_i2c("status: %d, ", b[0]);
+
+ if (rx != NULL) {
+ memcpy(rx, &b[2], rxlen);
+
+ deb_i2c("rx (%d): ", rxlen);
+ debug_dump(rx, rxlen, deb_i2c);
+ }
+
+ deb_i2c("\n");
+
+ return 0;
+}
+
+static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+ int num)
+{
+ int ret = 0, i;
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+ /* Ensure nobody else hits the i2c bus while we're sending our
+ sequence of messages, (such as the remote control thread) */
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ for (i = 0; i < num; i++) {
+ if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
+ ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
+ msg[i].buf, msg[i].len,
+ msg[i+1].buf, msg[i+1].len);
+ if (ret != 0)
+ break;
+ i++;
+ } else {
+ ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
+ msg[i].buf, msg[i].len,
+ NULL, 0);
+ if (ret != 0)
+ break;
+ }
+ }
+
+ if (ret == 0)
+ ret = i;
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
+}
+
+static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm technisat_usb2_i2c_algo = {
+ .master_xfer = technisat_usb2_i2c_xfer,
+ .functionality = technisat_usb2_i2c_func,
+};
+
+#if 0
+static void technisat_usb2_frontend_reset(struct usb_device *udev)
+{
+ usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ SET_FRONT_END_RESET_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ 10, 0,
+ NULL, 0, 500);
+}
+#endif
+
+/* LED control */
+enum technisat_usb2_led_state {
+ LED_OFF,
+ LED_BLINK,
+ LED_ON,
+ LED_UNDEFINED
+};
+
+static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
+{
+ int ret;
+
+ u8 led[8] = {
+ red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+ 0
+ };
+
+ if (disable_led_control && state != LED_OFF)
+ return 0;
+
+ switch (state) {
+ case LED_ON:
+ led[1] = 0x82;
+ break;
+ case LED_BLINK:
+ led[1] = 0x82;
+ if (red) {
+ led[2] = 0x02;
+ led[3] = 10;
+ led[4] = 10;
+ } else {
+ led[2] = 0xff;
+ led[3] = 50;
+ led[4] = 50;
+ }
+ led[5] = 1;
+ break;
+
+ default:
+ case LED_OFF:
+ led[1] = 0x80;
+ break;
+ }
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+ red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ 0, 0,
+ led, sizeof(led), 500);
+
+ mutex_unlock(&d->i2c_mutex);
+ return ret;
+}
+
+static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
+{
+ int ret;
+ u8 b = 0;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+ SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ (red << 8) | green, 0,
+ &b, 1, 500);
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
+}
+
+static void technisat_usb2_green_led_control(struct work_struct *work)
+{
+ struct technisat_usb2_state *state =
+ container_of(work, struct technisat_usb2_state, green_led_work.work);
+ struct dvb_frontend *fe = state->dev->adapter[0].fe;
+
+ if (state->power_state == 0)
+ goto schedule;
+
+ if (fe != NULL) {
+ enum fe_status status;
+
+ if (fe->ops.read_status(fe, &status) != 0)
+ goto schedule;
+
+ if (status & FE_HAS_LOCK) {
+ u32 ber;
+
+ if (fe->ops.read_ber(fe, &ber) != 0)
+ goto schedule;
+
+ if (ber > 1000)
+ technisat_usb2_set_led(state->dev, 0, LED_BLINK);
+ else
+ technisat_usb2_set_led(state->dev, 0, LED_ON);
+ } else
+ technisat_usb2_set_led(state->dev, 0, LED_OFF);
+ }
+
+schedule:
+ schedule_delayed_work(&state->green_led_work,
+ msecs_to_jiffies(500));
+}
+
+/* method to find out whether the firmware has to be downloaded or not */
+static int technisat_usb2_identify_state(struct usb_device *udev,
+ struct dvb_usb_device_properties *props,
+ struct dvb_usb_device_description **desc, int *cold)
+{
+ int ret;
+ u8 version[3];
+
+ /* first select the interface */
+ if (usb_set_interface(udev, 0, 1) != 0)
+ err("could not set alternate setting to 0");
+ else
+ info("set alternate setting");
+
+ *cold = 0; /* by default do not download a firmware - just in case something is wrong */
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ GET_VERSION_INFO_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_IN,
+ 0, 0,
+ version, sizeof(version), 500);
+
+ if (ret < 0)
+ *cold = 1;
+ else {
+ info("firmware version: %d.%d", version[1], version[2]);
+ *cold = 0;
+ }
+
+ return 0;
+}
+
+/* power control */
+static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
+{
+ struct technisat_usb2_state *state = d->priv;
+
+ state->power_state = level;
+
+ if (disable_led_control)
+ return 0;
+
+ /* green led is turned off in any case - will be turned on when tuning */
+ technisat_usb2_set_led(d, 0, LED_OFF);
+ /* red led is turned on all the time */
+ technisat_usb2_set_led(d, 1, LED_ON);
+ return 0;
+}
+
+/* mac address reading - from the eeprom */
+#if 0
+static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
+{
+ u8 reg;
+ u8 b[16];
+ int i, j;
+
+ /* full EEPROM dump */
+ for (j = 0; j < 256 * 4; j += 16) {
+ reg = j;
+ if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
+ break;
+
+ deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
+ for (i = 0; i < 16; i++)
+ deb_eeprom("%02x ", b[i]);
+ deb_eeprom("\n");
+ }
+}
+#endif
+
+static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
+{
+ u8 lrc = 0;
+ while (--length)
+ lrc ^= *b++;
+ return lrc;
+}
+
+static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
+ u16 offset, u8 *b, u16 length, u8 tries)
+{
+ u8 bo = offset & 0xff;
+ struct i2c_msg msg[] = {
+ {
+ .addr = 0x50 | ((offset >> 8) & 0x3),
+ .buf = &bo,
+ .len = 1
+ }, {
+ .addr = 0x50 | ((offset >> 8) & 0x3),
+ .flags = I2C_M_RD,
+ .buf = b,
+ .len = length
+ }
+ };
+
+ while (tries--) {
+ int status;
+
+ if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
+ break;
+
+ status =
+ technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
+
+ if (status)
+ return 0;
+ }
+
+ return -EREMOTEIO;
+}
+
+#define EEPROM_MAC_START 0x3f8
+#define EEPROM_MAC_TOTAL 8
+static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
+ u8 mac[])
+{
+ u8 buf[EEPROM_MAC_TOTAL];
+
+ if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
+ buf, EEPROM_MAC_TOTAL, 4) != 0)
+ return -ENODEV;
+
+ memcpy(mac, buf, 6);
+ return 0;
+}
+
+/* frontend attach */
+static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ int i;
+ u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
+
+ gpio[2] = 1; /* high - voltage ? */
+
+ switch (voltage) {
+ case SEC_VOLTAGE_13:
+ gpio[0] = 1;
+ break;
+ case SEC_VOLTAGE_18:
+ gpio[0] = 1;
+ gpio[1] = 1;
+ break;
+ default:
+ case SEC_VOLTAGE_OFF:
+ break;
+ }
+
+ for (i = 0; i < 3; i++)
+ if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
+ return -EREMOTEIO;
+ return 0;
+}
+
+static struct stv090x_config technisat_usb2_stv090x_config = {
+ .device = STV0903,
+ .demod_mode = STV090x_SINGLE,
+ .clk_mode = STV090x_CLK_EXT,
+
+ .xtal = 8000000,
+ .address = 0x68,
+
+ .ts1_mode = STV090x_TSMODE_DVBCI,
+ .ts1_clk = 13400000,
+ .ts1_tei = 1,
+
+ .repeater_level = STV090x_RPTLEVEL_64,
+
+ .tuner_bbgain = 6,
+};
+
+static struct stv6110x_config technisat_usb2_stv6110x_config = {
+ .addr = 0x60,
+ .refclk = 16000000,
+ .clk_div = 2,
+};
+
+static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
+{
+ struct usb_device *udev = a->dev->udev;
+ int ret;
+
+ a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
+ &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
+
+ if (a->fe) {
+ struct stv6110x_devctl *ctl;
+
+ ctl = dvb_attach(stv6110x_attach,
+ a->fe,
+ &technisat_usb2_stv6110x_config,
+ &a->dev->i2c_adap);
+
+ if (ctl) {
+ technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init;
+ technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep;
+ technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
+ technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+ technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+ technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+ technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+ technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
+ technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
+ technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
+ technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status;
+
+ /* call the init function once to initialize
+ tuner's clock output divider and demod's
+ master clock */
+ if (a->fe->ops.init)
+ a->fe->ops.init(a->fe);
+
+ if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ 0, 0,
+ NULL, 0, 500);
+ mutex_unlock(&a->dev->i2c_mutex);
+
+ if (ret != 0)
+ err("could not set IF_CLK to external");
+
+ a->fe->ops.set_voltage = technisat_usb2_set_voltage;
+
+ /* if everything was successful assign a nice name to the frontend */
+ strlcpy(a->fe->ops.info.name, a->dev->desc->name,
+ sizeof(a->fe->ops.info.name));
+ } else {
+ dvb_frontend_detach(a->fe);
+ a->fe = NULL;
+ }
+ }
+
+ technisat_usb2_set_led_timer(a->dev, 1, 1);
+
+ return a->fe == NULL ? -ENODEV : 0;
+}
+
+/* Remote control */
+
+/* the device is giving providing raw IR-signals to the host mapping
+ * it only to one remote control is just the default implementation
+ */
+#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
+#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
+
+#define FIRMWARE_CLOCK_TICK 83333
+#define FIRMWARE_CLOCK_DIVISOR 256
+
+#define IR_PERCENT_TOLERANCE 15
+
+#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
+#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
+
+#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
+#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
+
+#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+
+#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
+
+static int technisat_usb2_get_ir(struct dvb_usb_device *d)
+{
+ u8 buf[62], *b;
+ int ret;
+ struct ir_raw_event ev;
+
+ buf[0] = GET_IR_DATA_VENDOR_REQUEST;
+ buf[1] = 0x08;
+ buf[2] = 0x8f;
+ buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
+ buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+ ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+ GET_IR_DATA_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ 0, 0,
+ buf, 5, 500);
+ if (ret < 0)
+ goto unlock;
+
+ buf[1] = 0;
+ buf[2] = 0;
+ ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+ GET_IR_DATA_VENDOR_REQUEST,
+ USB_TYPE_VENDOR | USB_DIR_IN,
+ 0x8080, 0,
+ buf, sizeof(buf), 500);
+
+unlock:
+ mutex_unlock(&d->i2c_mutex);
+
+ if (ret < 0)
+ return ret;
+
+ if (ret == 1)
+ return 0; /* no key pressed */
+
+ /* decoding */
+ b = buf+1;
+
+#if 0
+ deb_rc("RC: %d ", ret);
+ debug_dump(b, ret, deb_rc);
+#endif
+
+ ev.pulse = 0;
+ while (1) {
+ ev.pulse = !ev.pulse;
+ ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
+ ir_raw_event_store(d->rc_dev, &ev);
+
+ b++;
+ if (*b == 0xff) {
+ ev.pulse = 0;
+ ev.duration = 888888*2;
+ ir_raw_event_store(d->rc_dev, &ev);
+ break;
+ }
+ }
+
+ ir_raw_event_handle(d->rc_dev);
+
+ return 1;
+}
+
+static int technisat_usb2_rc_query(struct dvb_usb_device *d)
+{
+ int ret = technisat_usb2_get_ir(d);
+
+ if (ret < 0)
+ return ret;
+
+ if (ret == 0)
+ return 0;
+
+ if (!disable_led_control)
+ technisat_usb2_set_led(d, 1, LED_BLINK);
+
+ return 0;
+}
+
+/* DVB-USB and USB stuff follows */
+static struct usb_device_id technisat_usb2_id_table[] = {
+ { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
+ { 0 } /* Terminating entry */
+};
+
+/* device description */
+static struct dvb_usb_device_properties technisat_usb2_devices = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+
+ .identify_state = technisat_usb2_identify_state,
+ .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
+
+ .size_of_priv = sizeof(struct technisat_usb2_state),
+
+ .i2c_algo = &technisat_usb2_i2c_algo,
+
+ .power_ctrl = technisat_usb2_power_ctrl,
+ .read_mac_address = technisat_usb2_read_mac_address,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = technisat_usb2_frontend_attach,
+
+ .stream = {
+ .type = USB_ISOC,
+ .count = 8,
+ .endpoint = 0x2,
+ .u = {
+ .isoc = {
+ .framesperurb = 32,
+ .framesize = 2048,
+ .interval = 3,
+ }
+ }
+ },
+
+ .size_of_priv = 0,
+ },
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Technisat SkyStar USB HD (DVB-S/S2)",
+ { &technisat_usb2_id_table[0], NULL },
+ { NULL },
+ },
+ },
+
+ .rc.core = {
+ .rc_interval = 100,
+ .rc_codes = RC_MAP_TECHNISAT_USB2,
+ .module_name = "technisat-usb2",
+ .rc_query = technisat_usb2_rc_query,
+ .allowed_protos = RC_TYPE_ALL,
+ .driver_type = RC_DRIVER_IR_RAW,
+ }
+};
+
+static int technisat_usb2_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct dvb_usb_device *dev;
+
+ if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
+ &dev, adapter_nr) != 0)
+ return -ENODEV;
+
+ if (dev) {
+ struct technisat_usb2_state *state = dev->priv;
+ state->dev = dev;
+
+ if (!disable_led_control) {
+ INIT_DELAYED_WORK(&state->green_led_work,
+ technisat_usb2_green_led_control);
+ schedule_delayed_work(&state->green_led_work,
+ msecs_to_jiffies(500));
+ }
+ }
+
+ return 0;
+}
+
+static void technisat_usb2_disconnect(struct usb_interface *intf)
+{
+ struct dvb_usb_device *dev = usb_get_intfdata(intf);
+
+ /* work and stuff was only created when the device is is hot-state */
+ if (dev != NULL) {
+ struct technisat_usb2_state *state = dev->priv;
+ if (state != NULL) {
+ cancel_rearming_delayed_work(&state->green_led_work);
+ flush_scheduled_work();
+ }
+ }
+
+ dvb_usb_device_exit(intf);
+}
+
+static struct usb_driver technisat_usb2_driver = {
+ .name = "dvb_usb_technisat_usb2",
+ .probe = technisat_usb2_probe,
+ .disconnect = technisat_usb2_disconnect,
+ .id_table = technisat_usb2_id_table,
+};
+
+/* module stuff */
+static int __init technisat_usb2_module_init(void)
+{
+ int result = usb_register(&technisat_usb2_driver);
+ if (result) {
+ err("usb_register failed. Code %d", result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit technisat_usb2_module_exit(void)
+{
+ usb_deregister(&technisat_usb2_driver);
+}
+
+module_init(technisat_usb2_module_init);
+module_exit(technisat_usb2_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
+MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index 5c9f3275aaa0..7890e75600df 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)
}
/* keys for the enclosed remote control */
-static struct ir_scancode ir_codes_vp702x_table[] = {
+static struct rc_map_table rc_map_vp702x_table[] = {
{ 0x0001, KEY_1 },
{ 0x0002, KEY_2 },
};
@@ -197,10 +197,10 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
- for (i = 0; i < ARRAY_SIZE(ir_codes_vp702x_table); i++)
- if (rc5_custom(&ir_codes_vp702x_table[i]) == key[1]) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
+ if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
*state = REMOTE_KEY_PRESSED;
- *event = ir_codes_vp702x_table[i].keycode;
+ *event = rc_map_vp702x_table[i].keycode;
break;
}
return 0;
@@ -284,8 +284,8 @@ static struct dvb_usb_device_properties vp702x_properties = {
.read_mac_address = vp702x_read_mac_addr,
.rc.legacy = {
- .rc_key_map = ir_codes_vp702x_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table),
+ .rc_map_table = rc_map_vp702x_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
.rc_interval = 400,
.rc_query = vp702x_rc_query,
},
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index f13791ca5994..ab0ab3c35e80 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)
/* The keymapping struct. Somehow this should be loaded to the driver, but
* currently it is hardcoded. */
-static struct ir_scancode ir_codes_vp7045_table[] = {
+static struct rc_map_table rc_map_vp7045_table[] = {
{ 0x0016, KEY_POWER },
{ 0x0010, KEY_MUTE },
{ 0x0003, KEY_1 },
@@ -165,10 +165,10 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
- for (i = 0; i < ARRAY_SIZE(ir_codes_vp7045_table); i++)
- if (rc5_data(&ir_codes_vp7045_table[i]) == key) {
+ for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
+ if (rc5_data(&rc_map_vp7045_table[i]) == key) {
*state = REMOTE_KEY_PRESSED;
- *event = ir_codes_vp7045_table[i].keycode;
+ *event = rc_map_vp7045_table[i].keycode;
break;
}
return 0;
@@ -261,8 +261,8 @@ static struct dvb_usb_device_properties vp7045_properties = {
.rc.legacy = {
.rc_interval = 400,
- .rc_key_map = ir_codes_vp7045_table,
- .rc_key_map_size = ARRAY_SIZE(ir_codes_vp7045_table),
+ .rc_map_table = rc_map_vp7045_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
.rc_query = vp7045_rc_query,
},
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 96b27016670e..ef3e43a03199 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -497,7 +497,7 @@ comment "ISDB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_S921
- tristate "Sharp S921 tuner"
+ tristate "Sharp S921 frontend"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
@@ -512,6 +512,14 @@ config DVB_DIB8000
A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
+config DVB_MB86A20S
+ tristate "Fujitsu mb86a20s"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
+ Say Y when you want to support this frontend.
+
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 9a31985c0dfb..b1d9525aa7e3 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -5,7 +5,6 @@
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
EXTRA_CFLAGS += -Idrivers/media/common/tuners/
-s921-objs := s921_module.o s921_core.o
stb0899-objs = stb0899_drv.o stb0899_algo.o
stv0900-objs = stv0900_core.o stv0900_sw.o
au8522-objs = au8522_dig.o au8522_decoder.o
@@ -82,4 +81,5 @@ obj-$(CONFIG_DVB_ISL6423) += isl6423.o
obj-$(CONFIG_DVB_EC100) += ec100.o
obj-$(CONFIG_DVB_DS3000) += ds3000.o
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
+obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
index 43aac2f85c2e..1539ea1f81ac 100644
--- a/drivers/media/dvb/frontends/atbm8830.c
+++ b/drivers/media/dvb/frontends/atbm8830.c
@@ -50,8 +50,7 @@ static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
msg2.addr = dev_addr;
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
- __func__, reg, data);
+ dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg1, 1);
if (ret != 1)
@@ -77,8 +76,7 @@ static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, &msg1, 1);
if (ret != 1) {
- dprintk(KERN_DEBUG "%s: error reg=0x%04x, ret=%i\n",
- __func__, reg, ret);
+ dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
return -EIO;
}
@@ -88,7 +86,7 @@ static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
*p_data = buf2[0];
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%04X, data=0x%02X\n",
+ dprintk("%s: reg=0x%04X, data=0x%02X\n",
__func__, reg, buf2[0]);
return 0;
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 6d9c5943eb3d..b537891a4cc9 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -278,10 +278,18 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
- au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
- AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
- au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
- AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+ input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
+ } else {
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ }
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
@@ -347,9 +355,11 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+ /* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
- au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
- au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ /* Enable clamping control */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
@@ -366,14 +376,14 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
- /* It's not clear why they turn off the PGA before enabling the clamp
- control, but the Windows trace does it so we will too... */
+ /* It's not clear why we have to have the PGA in automatic mode while
+ enabling clamp control, but it's what Windows does */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
- /* Turn on the PGA */
+ /* Disable automatic PGA (since the CVBS is coming from the tuner) */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
@@ -396,7 +406,10 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
- /* Disable clamping control (required for S-video) */
+ /* PGA in automatic mode */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+ /* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
setup_decoder_defaults(state,
@@ -410,29 +423,15 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
static void disable_audio_input(struct au8522_state *state)
{
- /* This can probably be optimized */
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
- au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
- au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
-
- au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
- au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
- au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
- au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
- au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
-
- au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
- msleep(5);
- au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
- au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
- AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
}
/* 0=disable, 1=SIF */
@@ -622,7 +621,7 @@ static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return v4l2_ctrl_query_fill(qc, 0, 255, 1,
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
case V4L2_CID_SATURATION:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_HUE:
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index 609cf04bc312..751e17d692a9 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -397,7 +397,9 @@ void au8522_release_state(struct au8522_state *state);
#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO 0x2a
#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO 0x15
#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c
index 55f2eba7bc96..6360c681ded9 100644
--- a/drivers/media/dvb/frontends/ix2505v.c
+++ b/drivers/media/dvb/frontends/ix2505v.c
@@ -72,7 +72,7 @@ static int ix2505v_read_status_reg(struct ix2505v_state *state)
ret = i2c_transfer(state->i2c, msg, 1);
deb_i2c("Read %s ", __func__);
- return (ret = 1) ? (int) b2[0] : -1;
+ return (ret == 1) ? (int) b2[0] : -1;
}
static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index 0fcddc4569d2..1172b54689f8 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -60,13 +60,12 @@ static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
msg.addr += 0x02;
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
- __func__, reg, data);
+ dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret != 1)
- dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+ dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
__func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
@@ -91,15 +90,13 @@ static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
ret = i2c_transfer(priv->i2c, msg, 2);
if (ret != 2) {
- dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
- __func__, reg, ret);
+ dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
return -1;
}
*p_data = b1[0];
if (debug >= 2)
- printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
- __func__, reg, b1[0]);
+ dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
return 0;
}
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c
new file mode 100644
index 000000000000..d3ad3e75a35a
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a20s.c
@@ -0,0 +1,615 @@
+/*
+ * Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
+ *
+ * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
+ *
+ * FIXME: Need to port to DVB v5.2 API
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "mb86a20s.h"
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define rc(args...) do { \
+ printk(KERN_ERR "mb86a20s: " args); \
+} while (0)
+
+#define dprintk(args...) \
+ do { \
+ if (debug) { \
+ printk(KERN_DEBUG "mb86a20s: %s: ", __func__); \
+ printk(args); \
+ } \
+ } while (0)
+
+struct mb86a20s_state {
+ struct i2c_adapter *i2c;
+ const struct mb86a20s_config *config;
+
+ struct dvb_frontend frontend;
+};
+
+struct regdata {
+ u8 reg;
+ u8 data;
+};
+
+/*
+ * Initialization sequence: Use whatevere default values that PV SBTVD
+ * does on its initialisation, obtained via USB snoop
+ */
+static struct regdata mb86a20s_init[] = {
+ { 0x70, 0x0f },
+ { 0x70, 0xff },
+ { 0x08, 0x01 },
+ { 0x09, 0x3e },
+ { 0x50, 0xd1 },
+ { 0x51, 0x22 },
+ { 0x39, 0x01 },
+ { 0x71, 0x00 },
+ { 0x28, 0x2a },
+ { 0x29, 0x00 },
+ { 0x2a, 0xff },
+ { 0x2b, 0x80 },
+ { 0x28, 0x20 },
+ { 0x29, 0x33 },
+ { 0x2a, 0xdf },
+ { 0x2b, 0xa9 },
+ { 0x3b, 0x21 },
+ { 0x3c, 0x3a },
+ { 0x01, 0x0d },
+ { 0x04, 0x08 },
+ { 0x05, 0x05 },
+ { 0x04, 0x0e },
+ { 0x05, 0x00 },
+ { 0x04, 0x0f },
+ { 0x05, 0x14 },
+ { 0x04, 0x0b },
+ { 0x05, 0x8c },
+ { 0x04, 0x00 },
+ { 0x05, 0x00 },
+ { 0x04, 0x01 },
+ { 0x05, 0x07 },
+ { 0x04, 0x02 },
+ { 0x05, 0x0f },
+ { 0x04, 0x03 },
+ { 0x05, 0xa0 },
+ { 0x04, 0x09 },
+ { 0x05, 0x00 },
+ { 0x04, 0x0a },
+ { 0x05, 0xff },
+ { 0x04, 0x27 },
+ { 0x05, 0x64 },
+ { 0x04, 0x28 },
+ { 0x05, 0x00 },
+ { 0x04, 0x1e },
+ { 0x05, 0xff },
+ { 0x04, 0x29 },
+ { 0x05, 0x0a },
+ { 0x04, 0x32 },
+ { 0x05, 0x0a },
+ { 0x04, 0x14 },
+ { 0x05, 0x02 },
+ { 0x04, 0x04 },
+ { 0x05, 0x00 },
+ { 0x04, 0x05 },
+ { 0x05, 0x22 },
+ { 0x04, 0x06 },
+ { 0x05, 0x0e },
+ { 0x04, 0x07 },
+ { 0x05, 0xd8 },
+ { 0x04, 0x12 },
+ { 0x05, 0x00 },
+ { 0x04, 0x13 },
+ { 0x05, 0xff },
+ { 0x52, 0x01 },
+ { 0x50, 0xa7 },
+ { 0x51, 0x00 },
+ { 0x50, 0xa8 },
+ { 0x51, 0xff },
+ { 0x50, 0xa9 },
+ { 0x51, 0xff },
+ { 0x50, 0xaa },
+ { 0x51, 0x00 },
+ { 0x50, 0xab },
+ { 0x51, 0xff },
+ { 0x50, 0xac },
+ { 0x51, 0xff },
+ { 0x50, 0xad },
+ { 0x51, 0x00 },
+ { 0x50, 0xae },
+ { 0x51, 0xff },
+ { 0x50, 0xaf },
+ { 0x51, 0xff },
+ { 0x5e, 0x07 },
+ { 0x50, 0xdc },
+ { 0x51, 0x01 },
+ { 0x50, 0xdd },
+ { 0x51, 0xf4 },
+ { 0x50, 0xde },
+ { 0x51, 0x01 },
+ { 0x50, 0xdf },
+ { 0x51, 0xf4 },
+ { 0x50, 0xe0 },
+ { 0x51, 0x01 },
+ { 0x50, 0xe1 },
+ { 0x51, 0xf4 },
+ { 0x50, 0xb0 },
+ { 0x51, 0x07 },
+ { 0x50, 0xb2 },
+ { 0x51, 0xff },
+ { 0x50, 0xb3 },
+ { 0x51, 0xff },
+ { 0x50, 0xb4 },
+ { 0x51, 0xff },
+ { 0x50, 0xb5 },
+ { 0x51, 0xff },
+ { 0x50, 0xb6 },
+ { 0x51, 0xff },
+ { 0x50, 0xb7 },
+ { 0x51, 0xff },
+ { 0x50, 0x50 },
+ { 0x51, 0x02 },
+ { 0x50, 0x51 },
+ { 0x51, 0x04 },
+ { 0x45, 0x04 },
+ { 0x48, 0x04 },
+ { 0x50, 0xd5 },
+ { 0x51, 0x01 }, /* Serial */
+ { 0x50, 0xd6 },
+ { 0x51, 0x1f },
+ { 0x50, 0xd2 },
+ { 0x51, 0x03 },
+ { 0x50, 0xd7 },
+ { 0x51, 0x3f },
+ { 0x1c, 0x01 },
+ { 0x28, 0x06 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x03 },
+ { 0x28, 0x07 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x0d },
+ { 0x28, 0x08 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x02 },
+ { 0x28, 0x09 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x01 },
+ { 0x28, 0x0a },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x21 },
+ { 0x28, 0x0b },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x29 },
+ { 0x28, 0x0c },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x16 },
+ { 0x28, 0x0d },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x31 },
+ { 0x28, 0x0e },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x0e },
+ { 0x28, 0x0f },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x4e },
+ { 0x28, 0x10 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x46 },
+ { 0x28, 0x11 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x0f },
+ { 0x28, 0x12 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x56 },
+ { 0x28, 0x13 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x35 },
+ { 0x28, 0x14 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x01 },
+ { 0x2b, 0xbe },
+ { 0x28, 0x15 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x01 },
+ { 0x2b, 0x84 },
+ { 0x28, 0x16 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x03 },
+ { 0x2b, 0xee },
+ { 0x28, 0x17 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x98 },
+ { 0x28, 0x18 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x00 },
+ { 0x2b, 0x9f },
+ { 0x28, 0x19 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x07 },
+ { 0x2b, 0xb2 },
+ { 0x28, 0x1a },
+ { 0x29, 0x00 },
+ { 0x2a, 0x06 },
+ { 0x2b, 0xc2 },
+ { 0x28, 0x1b },
+ { 0x29, 0x00 },
+ { 0x2a, 0x07 },
+ { 0x2b, 0x4a },
+ { 0x28, 0x1c },
+ { 0x29, 0x00 },
+ { 0x2a, 0x01 },
+ { 0x2b, 0xbc },
+ { 0x28, 0x1d },
+ { 0x29, 0x00 },
+ { 0x2a, 0x04 },
+ { 0x2b, 0xba },
+ { 0x28, 0x1e },
+ { 0x29, 0x00 },
+ { 0x2a, 0x06 },
+ { 0x2b, 0x14 },
+ { 0x50, 0x1e },
+ { 0x51, 0x5d },
+ { 0x50, 0x22 },
+ { 0x51, 0x00 },
+ { 0x50, 0x23 },
+ { 0x51, 0xc8 },
+ { 0x50, 0x24 },
+ { 0x51, 0x00 },
+ { 0x50, 0x25 },
+ { 0x51, 0xf0 },
+ { 0x50, 0x26 },
+ { 0x51, 0x00 },
+ { 0x50, 0x27 },
+ { 0x51, 0xc3 },
+ { 0x50, 0x39 },
+ { 0x51, 0x02 },
+ { 0x50, 0xd5 },
+ { 0x51, 0x01 },
+ { 0xd0, 0x00 },
+};
+
+static struct regdata mb86a20s_reset_reception[] = {
+ { 0x70, 0xf0 },
+ { 0x70, 0xff },
+ { 0x08, 0x01 },
+ { 0x08, 0x00 },
+};
+
+static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
+ u8 i2c_addr, int reg, int data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+ };
+ int rc;
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+ if (rc != 1) {
+ printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
+ " data == 0x%02x)\n", __func__, rc, reg, data);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
+ u8 i2c_addr, struct regdata *rd, int size)
+{
+ int i, rc;
+
+ for (i = 0; i < size; i++) {
+ rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
+ rd[i].data);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
+ u8 i2c_addr, u8 reg)
+{
+ u8 val;
+ int rc;
+ struct i2c_msg msg[] = {
+ { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+ };
+
+ rc = i2c_transfer(state->i2c, msg, 2);
+
+ if (rc != 2) {
+ rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
+ return rc;
+ }
+
+ return val;
+}
+
+#define mb86a20s_readreg(state, reg) \
+ mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
+#define mb86a20s_writereg(state, reg, val) \
+ mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
+#define mb86a20s_writeregdata(state, regdata) \
+ mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
+ regdata, ARRAY_SIZE(regdata))
+
+static int mb86a20s_initfe(struct dvb_frontend *fe)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ int rc;
+ u8 regD5 = 1;
+
+ dprintk("\n");
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ /* Initialize the frontend */
+ rc = mb86a20s_writeregdata(state, mb86a20s_init);
+ if (rc < 0)
+ return rc;
+
+ if (!state->config->is_serial) {
+ regD5 &= ~1;
+
+ rc = mb86a20s_writereg(state, 0x50, 0xd5);
+ if (rc < 0)
+ return rc;
+ rc = mb86a20s_writereg(state, 0x51, regD5);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ return 0;
+}
+
+static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ unsigned rf_max, rf_min, rf;
+ u8 val;
+
+ dprintk("\n");
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ /* Does a binary search to get RF strength */
+ rf_max = 0xfff;
+ rf_min = 0;
+ do {
+ rf = (rf_max + rf_min) / 2;
+ mb86a20s_writereg(state, 0x04, 0x1f);
+ mb86a20s_writereg(state, 0x05, rf >> 8);
+ mb86a20s_writereg(state, 0x04, 0x20);
+ mb86a20s_writereg(state, 0x04, rf);
+
+ val = mb86a20s_readreg(state, 0x02);
+ if (val & 0x08)
+ rf_min = (rf_max + rf_min) / 2;
+ else
+ rf_max = (rf_max + rf_min) / 2;
+ if (rf_max - rf_min < 4) {
+ *strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
+ break;
+ }
+ } while (1);
+
+ dprintk("signal strength = %d\n", *strength);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ return 0;
+}
+
+static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ u8 val;
+
+ dprintk("\n");
+ *status = 0;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ val = mb86a20s_readreg(state, 0x0a) & 0xf;
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ if (val >= 2)
+ *status |= FE_HAS_SIGNAL;
+
+ if (val >= 4)
+ *status |= FE_HAS_CARRIER;
+
+ if (val >= 5)
+ *status |= FE_HAS_VITERBI;
+
+ if (val >= 7)
+ *status |= FE_HAS_SYNC;
+
+ if (val >= 8) /* Maybe 9? */
+ *status |= FE_HAS_LOCK;
+
+ dprintk("val = %d, status = 0x%02x\n", val, *status);
+
+ return 0;
+}
+
+static int mb86a20s_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ fe->ops.tuner_ops.set_params(fe, p);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ return rc;
+}
+
+static int mb86a20s_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+
+ /* FIXME: For now, it does nothing */
+
+ fe->dtv_property_cache.bandwidth_hz = 6000000;
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
+ fe->dtv_property_cache.isdbt_partial_reception = 0;
+
+ return 0;
+}
+
+static int mb86a20s_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params,
+ unsigned int mode_flags,
+ unsigned int *delay,
+ fe_status_t *status)
+{
+ int rc = 0;
+
+ dprintk("\n");
+
+ if (params != NULL)
+ rc = mb86a20s_set_frontend(fe, params);
+
+ if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+ mb86a20s_read_status(fe, status);
+
+ return rc;
+}
+
+static void mb86a20s_release(struct dvb_frontend *fe)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+
+ dprintk("\n");
+
+ kfree(state);
+}
+
+static struct dvb_frontend_ops mb86a20s_ops;
+
+struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+ struct i2c_adapter *i2c)
+{
+ u8 rev;
+
+ /* allocate memory for the internal state */
+ struct mb86a20s_state *state =
+ kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
+
+ dprintk("\n");
+ if (state == NULL) {
+ rc("Unable to kzalloc\n");
+ goto error;
+ }
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &mb86a20s_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* Check if it is a mb86a20s frontend */
+ rev = mb86a20s_readreg(state, 0);
+
+ if (rev == 0x13) {
+ printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
+ } else {
+ printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
+ rev);
+ goto error;
+ }
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(mb86a20s_attach);
+
+static struct dvb_frontend_ops mb86a20s_ops = {
+ /* Use dib8000 values per default */
+ .info = {
+ .name = "Fujitsu mb86A20s",
+ .type = FE_OFDM,
+ .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+ /* Actually, those values depend on the used tuner */
+ .frequency_min = 45000000,
+ .frequency_max = 864000000,
+ .frequency_stepsize = 62500,
+ },
+
+ .release = mb86a20s_release,
+
+ .init = mb86a20s_initfe,
+ .set_frontend = mb86a20s_set_frontend,
+ .get_frontend = mb86a20s_get_frontend,
+ .read_status = mb86a20s_read_status,
+ .read_signal_strength = mb86a20s_read_signal_strength,
+ .tune = mb86a20s_tune,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mb86a20s.h b/drivers/media/dvb/frontends/mb86a20s.h
new file mode 100644
index 000000000000..bf22e77888b9
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a20s.h
@@ -0,0 +1,52 @@
+/*
+ * Fujitsu mb86a20s driver
+ *
+ * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef MB86A20S_H
+#define MB86A20S_H
+
+#include <linux/dvb/frontend.h>
+
+/**
+ * struct mb86a20s_config - Define the per-device attributes of the frontend
+ *
+ * @demod_address: the demodulator's i2c address
+ */
+
+struct mb86a20s_config {
+ u8 demod_address;
+ bool is_serial;
+};
+
+#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+ struct i2c_adapter *i2c);
+extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *mb86a20s_attach(
+ const struct mb86a20s_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static struct i2c_adapter *
+ mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* MB86A20S */
diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb/frontends/s921.c
new file mode 100644
index 000000000000..ca0103d5f148
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.c
@@ -0,0 +1,548 @@
+/*
+ * Sharp VA3A5JZ921 One Seg Broadcast Module driver
+ * This device is labeled as just S. 921 at the top of the frontend can
+ *
+ * Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
+ *
+ * Developed for Leadership SBTVD 1seg device sold in Brazil
+ *
+ * Frontend module based on cx24123 driver, getting some info from
+ * the old s921 driver.
+ *
+ * FIXME: Need to port to DVB v5.2 API
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "s921.h"
+
+static int debug = 1;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+#define rc(args...) do { \
+ printk(KERN_ERR "s921: " args); \
+} while (0)
+
+#define dprintk(args...) \
+ do { \
+ if (debug) { \
+ printk(KERN_DEBUG "s921: %s: ", __func__); \
+ printk(args); \
+ } \
+ } while (0)
+
+struct s921_state {
+ struct i2c_adapter *i2c;
+ const struct s921_config *config;
+
+ struct dvb_frontend frontend;
+
+ /* The Demod can't easily provide these, we cache them */
+ u32 currentfreq;
+};
+
+/*
+ * Various tuner defaults need to be established for a given frequency kHz.
+ * fixme: The bounds on the bands do not match the doc in real life.
+ * fixme: Some of them have been moved, other might need adjustment.
+ */
+static struct s921_bandselect_val {
+ u32 freq_low;
+ u8 band_reg;
+} s921_bandselect[] = {
+ { 0, 0x7b },
+ { 485140000, 0x5b },
+ { 515140000, 0x3b },
+ { 545140000, 0x1b },
+ { 599140000, 0xfb },
+ { 623140000, 0xdb },
+ { 659140000, 0xbb },
+ { 713140000, 0x9b },
+};
+
+struct regdata {
+ u8 reg;
+ u8 data;
+};
+
+static struct regdata s921_init[] = {
+ { 0x01, 0x80 }, /* Probably, a reset sequence */
+ { 0x01, 0x40 },
+ { 0x01, 0x80 },
+ { 0x01, 0x40 },
+
+ { 0x02, 0x00 },
+ { 0x03, 0x40 },
+ { 0x04, 0x01 },
+ { 0x05, 0x00 },
+ { 0x06, 0x00 },
+ { 0x07, 0x00 },
+ { 0x08, 0x00 },
+ { 0x09, 0x00 },
+ { 0x0a, 0x00 },
+ { 0x0b, 0x5a },
+ { 0x0c, 0x00 },
+ { 0x0d, 0x00 },
+ { 0x0f, 0x00 },
+ { 0x13, 0x1b },
+ { 0x14, 0x80 },
+ { 0x15, 0x40 },
+ { 0x17, 0x70 },
+ { 0x18, 0x01 },
+ { 0x19, 0x12 },
+ { 0x1a, 0x01 },
+ { 0x1b, 0x12 },
+ { 0x1c, 0xa0 },
+ { 0x1d, 0x00 },
+ { 0x1e, 0x0a },
+ { 0x1f, 0x08 },
+ { 0x20, 0x40 },
+ { 0x21, 0xff },
+ { 0x22, 0x4c },
+ { 0x23, 0x4e },
+ { 0x24, 0x4c },
+ { 0x25, 0x00 },
+ { 0x26, 0x00 },
+ { 0x27, 0xf4 },
+ { 0x28, 0x60 },
+ { 0x29, 0x88 },
+ { 0x2a, 0x40 },
+ { 0x2b, 0x40 },
+ { 0x2c, 0xff },
+ { 0x2d, 0x00 },
+ { 0x2e, 0xff },
+ { 0x2f, 0x00 },
+ { 0x30, 0x20 },
+ { 0x31, 0x06 },
+ { 0x32, 0x0c },
+ { 0x34, 0x0f },
+ { 0x37, 0xfe },
+ { 0x38, 0x00 },
+ { 0x39, 0x63 },
+ { 0x3a, 0x10 },
+ { 0x3b, 0x10 },
+ { 0x47, 0x00 },
+ { 0x49, 0xe5 },
+ { 0x4b, 0x00 },
+ { 0x50, 0xc0 },
+ { 0x52, 0x20 },
+ { 0x54, 0x5a },
+ { 0x55, 0x5b },
+ { 0x56, 0x40 },
+ { 0x57, 0x70 },
+ { 0x5c, 0x50 },
+ { 0x5d, 0x00 },
+ { 0x62, 0x17 },
+ { 0x63, 0x2f },
+ { 0x64, 0x6f },
+ { 0x68, 0x00 },
+ { 0x69, 0x89 },
+ { 0x6a, 0x00 },
+ { 0x6b, 0x00 },
+ { 0x6c, 0x00 },
+ { 0x6d, 0x00 },
+ { 0x6e, 0x00 },
+ { 0x70, 0x10 },
+ { 0x71, 0x00 },
+ { 0x75, 0x00 },
+ { 0x76, 0x30 },
+ { 0x77, 0x01 },
+ { 0xaf, 0x00 },
+ { 0xb0, 0xa0 },
+ { 0xb2, 0x3d },
+ { 0xb3, 0x25 },
+ { 0xb4, 0x8b },
+ { 0xb5, 0x4b },
+ { 0xb6, 0x3f },
+ { 0xb7, 0xff },
+ { 0xb8, 0xff },
+ { 0xb9, 0xfc },
+ { 0xba, 0x00 },
+ { 0xbb, 0x00 },
+ { 0xbc, 0x00 },
+ { 0xd0, 0x30 },
+ { 0xe4, 0x84 },
+ { 0xf0, 0x48 },
+ { 0xf1, 0x19 },
+ { 0xf2, 0x5a },
+ { 0xf3, 0x8e },
+ { 0xf4, 0x2d },
+ { 0xf5, 0x07 },
+ { 0xf6, 0x5a },
+ { 0xf7, 0xba },
+ { 0xf8, 0xd7 },
+};
+
+static struct regdata s921_prefreq[] = {
+ { 0x47, 0x60 },
+ { 0x68, 0x00 },
+ { 0x69, 0x89 },
+ { 0xf0, 0x48 },
+ { 0xf1, 0x19 },
+};
+
+static struct regdata s921_postfreq[] = {
+ { 0xf5, 0xae },
+ { 0xf6, 0xb7 },
+ { 0xf7, 0xba },
+ { 0xf8, 0xd7 },
+ { 0x68, 0x0a },
+ { 0x69, 0x09 },
+};
+
+static int s921_i2c_writereg(struct s921_state *state,
+ u8 i2c_addr, int reg, int data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+ };
+ int rc;
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+ if (rc != 1) {
+ printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
+ " data == 0x%02x)\n", __func__, rc, reg, data);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
+ struct regdata *rd, int size)
+{
+ int i, rc;
+
+ for (i = 0; i < size; i++) {
+ rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
+{
+ u8 val;
+ int rc;
+ struct i2c_msg msg[] = {
+ { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
+ };
+
+ rc = i2c_transfer(state->i2c, msg, 2);
+
+ if (rc != 2) {
+ rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
+ return rc;
+ }
+
+ return val;
+}
+
+#define s921_readreg(state, reg) \
+ s921_i2c_readreg(state, state->config->demod_address, reg)
+#define s921_writereg(state, reg, val) \
+ s921_i2c_writereg(state, state->config->demod_address, reg, val)
+#define s921_writeregdata(state, regdata) \
+ s921_i2c_writeregdata(state, state->config->demod_address, \
+ regdata, ARRAY_SIZE(regdata))
+
+static int s921_pll_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int band, rc, i;
+ unsigned long f_offset;
+ u8 f_switch;
+ u64 offset;
+
+ dprintk("frequency=%i\n", p->frequency);
+
+ for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
+ if (p->frequency < s921_bandselect[band].freq_low)
+ break;
+ band--;
+
+ if (band < 0) {
+ rc("%s: frequency out of range\n", __func__);
+ return -EINVAL;
+ }
+
+ f_switch = s921_bandselect[band].band_reg;
+
+ offset = ((u64)p->frequency) * 258;
+ do_div(offset, 6000000);
+ f_offset = ((unsigned long)offset) + 2321;
+
+ rc = s921_writeregdata(state, s921_prefreq);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writereg(state, 0xf3, f_offset & 0xff);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writereg(state, 0xf4, f_switch);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_writeregdata(state, s921_postfreq);
+ if (rc < 0)
+ return rc;
+
+ for (i = 0 ; i < 6; i++) {
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+ }
+ rc = s921_writereg(state, 0x01, 0x40);
+ if (rc < 0)
+ return rc;
+
+ rc = s921_readreg(state, 0x01);
+ dprintk("status 0x01: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x32);
+ dprintk("status 0x32: %02x\n", rc);
+
+ dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
+
+ return 0;
+}
+
+static int s921_initfe(struct dvb_frontend *fe)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
+
+ rc = s921_writeregdata(state, s921_init);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int regstatus, rc;
+
+ *status = 0;
+
+ rc = s921_readreg(state, 0x81);
+ if (rc < 0)
+ return rc;
+
+ regstatus = rc << 8;
+
+ rc = s921_readreg(state, 0x82);
+ if (rc < 0)
+ return rc;
+
+ regstatus |= rc;
+
+ dprintk("status = %04x\n", regstatus);
+
+ /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
+ if ((regstatus & 0xff) == 0x40) {
+ *status = FE_HAS_SIGNAL |
+ FE_HAS_CARRIER |
+ FE_HAS_VITERBI |
+ FE_HAS_SYNC |
+ FE_HAS_LOCK;
+ } else if (regstatus & 0x40) {
+ /* This is close to Full Sync, but not enough to get useful info */
+ *status = FE_HAS_SIGNAL |
+ FE_HAS_CARRIER |
+ FE_HAS_VITERBI |
+ FE_HAS_SYNC;
+ }
+
+ return 0;
+}
+
+static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ fe_status_t status;
+ struct s921_state *state = fe->demodulator_priv;
+ int rc;
+
+ /* FIXME: Use the proper register for it... 0x80? */
+ rc = s921_read_status(fe, &status);
+ if (rc < 0)
+ return rc;
+
+ *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
+
+ dprintk("strength = 0x%04x\n", *strength);
+
+ rc = s921_readreg(state, 0x01);
+ dprintk("status 0x01: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x80);
+ dprintk("status 0x80: %02x\n", rc);
+
+ rc = s921_readreg(state, 0x32);
+ dprintk("status 0x32: %02x\n", rc);
+
+ return 0;
+}
+
+static int s921_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s921_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
+
+ /* FIXME: We don't know how to use non-auto mode */
+
+ rc = s921_pll_tune(fe, p);
+ if (rc < 0)
+ return rc;
+
+ state->currentfreq = p->frequency;
+
+ return 0;
+}
+
+static int s921_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s921_state *state = fe->demodulator_priv;
+
+ /* FIXME: Probably it is possible to get it from regs f1 and f2 */
+ p->frequency = state->currentfreq;
+
+ return 0;
+}
+
+static int s921_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params,
+ unsigned int mode_flags,
+ unsigned int *delay,
+ fe_status_t *status)
+{
+ int rc = 0;
+
+ dprintk("\n");
+
+ if (params != NULL)
+ rc = s921_set_frontend(fe, params);
+
+ if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+ s921_read_status(fe, status);
+
+ return rc;
+}
+
+static int s921_get_algo(struct dvb_frontend *fe)
+{
+ return 1; /* FE_ALGO_HW */
+}
+
+static void s921_release(struct dvb_frontend *fe)
+{
+ struct s921_state *state = fe->demodulator_priv;
+
+ dprintk("\n");
+ kfree(state);
+}
+
+static struct dvb_frontend_ops s921_ops;
+
+struct dvb_frontend *s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c)
+{
+ /* allocate memory for the internal state */
+ struct s921_state *state =
+ kzalloc(sizeof(struct s921_state), GFP_KERNEL);
+
+ dprintk("\n");
+ if (state == NULL) {
+ rc("Unable to kzalloc\n");
+ goto rcor;
+ }
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &s921_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ return &state->frontend;
+
+rcor:
+ kfree(state);
+
+ return NULL;
+}
+EXPORT_SYMBOL(s921_attach);
+
+static struct dvb_frontend_ops s921_ops = {
+ /* Use dib8000 values per default */
+ .info = {
+ .name = "Sharp S921",
+ .type = FE_OFDM,
+ .frequency_min = 470000000,
+ /*
+ * Max should be 770MHz instead, according with Sharp docs,
+ * but Leadership doc says it works up to 806 MHz. This is
+ * required to get channel 69, used in Brazil
+ */
+ .frequency_max = 806000000,
+ .frequency_tolerance = 0,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
+ FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .release = s921_release,
+
+ .init = s921_initfe,
+ .set_frontend = s921_set_frontend,
+ .get_frontend = s921_get_frontend,
+ .read_status = s921_read_status,
+ .read_signal_strength = s921_read_signal_strength,
+ .tune = s921_tune,
+ .get_frontend_algo = s921_get_algo,
+};
+
+MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921.h b/drivers/media/dvb/frontends/s921.h
new file mode 100644
index 000000000000..f220d8299c81
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.h
@@ -0,0 +1,47 @@
+/*
+ * Sharp s921 driver
+ *
+ * Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef S921_H
+#define S921_H
+
+#include <linux/dvb/frontend.h>
+
+struct s921_config {
+ /* the demodulator's i2c address */
+ u8 demod_address;
+};
+
+#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *s921_attach(const struct s921_config *config,
+ struct i2c_adapter *i2c);
+extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
+#else
+static inline struct dvb_frontend *s921_attach(
+ const struct s921_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static struct i2c_adapter *
+ s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c
deleted file mode 100644
index 974b52be9aea..000000000000
--- a/drivers/media/dvb/frontends/s921_core.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Driver for Sharp s921 driver
- *
- * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
- *
- */
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include "s921_core.h"
-
-static int s921_isdb_init(struct s921_isdb_t *dev);
-static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
-static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
-static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
-
-static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
- 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
- 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
- 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
- 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
- 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
- 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
- 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
- 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
- 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
- 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
- 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
- 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
- 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
- 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
- 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
- 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
- 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
- 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
- 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
- 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
- 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
- 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
- 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
- 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
- 0xf8, 0xd7 };
-
-static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
- 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
- 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
- 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
- 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
- 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
- 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
- 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
- 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
- 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
- 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
- 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
- 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
- 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
- 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
- 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
- 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
-
-int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
- switch(cmd) {
- case ISDB_T_CMD_INIT:
- s921_isdb_init(dev);
- break;
- case ISDB_T_CMD_SET_PARAM:
- s921_isdb_set_parameters(dev, data);
- break;
- case ISDB_T_CMD_TUNE:
- s921_isdb_tune(dev, data);
- break;
- case ISDB_T_CMD_GET_STATUS:
- s921_isdb_get_status(dev, data);
- break;
- default:
- printk("unhandled command\n");
- return -EINVAL;
- }
- return 0;
-}
-
-static int s921_isdb_init(struct s921_isdb_t *dev) {
- unsigned int i;
- unsigned int ret;
- printk("isdb_init\n");
- for (i = 0; i < sizeof(init_table); i+=2) {
- ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
- if (ret != 0) {
- printk("i2c write failed\n");
- return ret;
- }
- }
- return 0;
-}
-
-static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
-
- int ret;
- /* auto is sufficient for now, lateron this should be reflected in an extra interface */
-
-
-
- ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
- ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
-
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
- if (ret < 0)
- return -EINVAL;
-
- return E_OK;
-}
-
-static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
-
- int ret;
- int index;
-
- index = (params->frequency - 473143000)/6000000;
-
- if (index > 48) {
- return -EINVAL;
- }
-
- dev->i2c_write(dev->priv_dev, 0x47, 0x60);
-
- ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
- if (ret < 0)
- return -EINVAL;
-
- ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
- if (ret < 0)
- return -EINVAL;
-
- dev->i2c_write(dev->priv_dev, 0x01, 0x40);
- return 0;
-}
-
-static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
- unsigned int *ret = (unsigned int*)data;
- u8 ifagc_dt;
- u8 rfagc_dt;
-
- mdelay(10);
- ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
- rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
- if (rfagc_dt == 0x40) {
- *ret = 1;
- }
- return 0;
-}
diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h
deleted file mode 100644
index de2f10a44e72..000000000000
--- a/drivers/media/dvb/frontends/s921_core.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef _S921_CORE_H
-#define _S921_CORE_H
-//#define u8 unsigned int
-//#define u32 unsigned int
-
-
-
-//#define EINVAL -1
-#define E_OK 0
-
-struct s921_isdb_t {
- void *priv_dev;
- int (*i2c_write)(void *dev, u8 reg, u8 val);
- int (*i2c_read)(void *dev, u8 reg);
-};
-
-#define ISDB_T_CMD_INIT 0
-#define ISDB_T_CMD_SET_PARAM 1
-#define ISDB_T_CMD_TUNE 2
-#define ISDB_T_CMD_GET_STATUS 3
-
-struct s921_isdb_t_tune_params {
- u32 frequency;
-};
-
-struct s921_isdb_t_status {
-};
-
-struct s921_isdb_t_transmission_mode_params {
- u8 mode;
- u8 layer_a_mode;
-#define ISDB_T_LA_MODE_1 0
-#define ISDB_T_LA_MODE_2 1
-#define ISDB_T_LA_MODE_3 2
- u8 layer_a_carrier_modulation;
-#define ISDB_T_LA_CM_DQPSK 0
-#define ISDB_T_LA_CM_QPSK 1
-#define ISDB_T_LA_CM_16QAM 2
-#define ISDB_T_LA_CM_64QAM 3
-#define ISDB_T_LA_CM_NOLAYER 4
- u8 layer_a_code_rate;
-#define ISDB_T_LA_CR_1_2 0
-#define ISDB_T_LA_CR_2_3 1
-#define ISDB_T_LA_CR_3_4 2
-#define ISDB_T_LA_CR_5_6 4
-#define ISDB_T_LA_CR_7_8 8
-#define ISDB_T_LA_CR_NOLAYER 16
- u8 layer_a_time_interleave;
-#define ISDB_T_LA_TI_0 0
-#define ISDB_T_LA_TI_1 1
-#define ISDB_T_LA_TI_2 2
-#define ISDB_T_LA_TI_4 4
-#define ISDB_T_LA_TI_8 8
-#define ISDB_T_LA_TI_16 16
-#define ISDB_T_LA_TI_32 32
- u8 layer_a_nseg;
-
- u8 layer_b_mode;
-#define ISDB_T_LB_MODE_1 0
-#define ISDB_T_LB_MODE_2 1
-#define ISDB_T_LB_MODE_3 2
- u8 layer_b_carrier_modulation;
-#define ISDB_T_LB_CM_DQPSK 0
-#define ISDB_T_LB_CM_QPSK 1
-#define ISDB_T_LB_CM_16QAM 2
-#define ISDB_T_LB_CM_64QAM 3
-#define ISDB_T_LB_CM_NOLAYER 4
- u8 layer_b_code_rate;
-#define ISDB_T_LB_CR_1_2 0
-#define ISDB_T_LB_CR_2_3 1
-#define ISDB_T_LB_CR_3_4 2
-#define ISDB_T_LB_CR_5_6 4
-#define ISDB_T_LB_CR_7_8 8
-#define ISDB_T_LB_CR_NOLAYER 16
- u8 layer_b_time_interleave;
-#define ISDB_T_LB_TI_0 0
-#define ISDB_T_LB_TI_1 1
-#define ISDB_T_LB_TI_2 2
-#define ISDB_T_LB_TI_4 4
-#define ISDB_T_LB_TI_8 8
-#define ISDB_T_LB_TI_16 16
-#define ISDB_T_LB_TI_32 32
- u8 layer_b_nseg;
-
- u8 layer_c_mode;
-#define ISDB_T_LC_MODE_1 0
-#define ISDB_T_LC_MODE_2 1
-#define ISDB_T_LC_MODE_3 2
- u8 layer_c_carrier_modulation;
-#define ISDB_T_LC_CM_DQPSK 0
-#define ISDB_T_LC_CM_QPSK 1
-#define ISDB_T_LC_CM_16QAM 2
-#define ISDB_T_LC_CM_64QAM 3
-#define ISDB_T_LC_CM_NOLAYER 4
- u8 layer_c_code_rate;
-#define ISDB_T_LC_CR_1_2 0
-#define ISDB_T_LC_CR_2_3 1
-#define ISDB_T_LC_CR_3_4 2
-#define ISDB_T_LC_CR_5_6 4
-#define ISDB_T_LC_CR_7_8 8
-#define ISDB_T_LC_CR_NOLAYER 16
- u8 layer_c_time_interleave;
-#define ISDB_T_LC_TI_0 0
-#define ISDB_T_LC_TI_1 1
-#define ISDB_T_LC_TI_2 2
-#define ISDB_T_LC_TI_4 4
-#define ISDB_T_LC_TI_8 8
-#define ISDB_T_LC_TI_16 16
-#define ISDB_T_LC_TI_32 32
- u8 layer_c_nseg;
-};
-
-int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
-#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
deleted file mode 100644
index 0eefff61cc50..000000000000
--- a/drivers/media/dvb/frontends/s921_module.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Driver for Sharp s921 driver
- *
- * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
- *
- * All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "s921_module.h"
-#include "s921_core.h"
-
-static unsigned int debug = 0;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"s921 debugging (default off)");
-
-#define dprintk(fmt, args...) if (debug) do {\
- printk("s921 debug: " fmt, ##args); } while (0)
-
-struct s921_state
-{
- struct dvb_frontend frontend;
- fe_modulation_t current_modulation;
- __u32 snr;
- __u32 current_frequency;
- __u8 addr;
- struct s921_isdb_t dev;
- struct i2c_adapter *i2c;
-};
-
-static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
- struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
- struct s921_isdb_t_transmission_mode_params params;
- struct s921_isdb_t_tune_params tune_params;
-
- tune_params.frequency = param->frequency;
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, &params);
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
- mdelay(100);
- return 0;
-}
-
-static int s921_init(struct dvb_frontend *fe) {
- printk("s921 init\n");
- return 0;
-}
-
-static int s921_sleep(struct dvb_frontend *fe) {
- printk("s921 sleep\n");
- return 0;
-}
-
-static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
- struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
- unsigned int ret;
- mdelay(5);
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
- *status = 0;
-
- printk("status: %02x\n", ret);
- if (ret == 1) {
- *status |= FE_HAS_CARRIER;
- *status |= FE_HAS_VITERBI;
- *status |= FE_HAS_LOCK;
- *status |= FE_HAS_SYNC;
- *status |= FE_HAS_SIGNAL;
- }
-
- return 0;
-}
-
-static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
-{
- dprintk("read ber\n");
- return 0;
-}
-
-static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
-{
- dprintk("read snr\n");
- return 0;
-}
-
-static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
-{
- dprintk("read ucblocks\n");
- return 0;
-}
-
-static void s921_release(struct dvb_frontend *fe)
-{
- struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
- kfree(state);
-}
-
-static struct dvb_frontend_ops demod_s921={
- .info = {
- .name = "SHARP S921",
- .type = FE_OFDM,
- .frequency_min = 473143000,
- .frequency_max = 767143000,
- .frequency_stepsize = 6000000,
- .frequency_tolerance = 0,
- .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
- FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
- FE_CAN_FEC_AUTO |
- FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
- FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
- FE_CAN_MUTE_TS
- },
- .init = s921_init,
- .sleep = s921_sleep,
- .set_frontend = s921_set_parameters,
- .read_snr = s921_read_snr,
- .read_ber = s921_read_ber,
- .read_status = s921_read_status,
- .read_ucblocks = s921_read_ucblocks,
- .release = s921_release,
-};
-
-static int s921_write(void *dev, u8 reg, u8 val) {
- struct s921_state *state = dev;
- char buf[2]={reg,val};
- int err;
- struct i2c_msg i2cmsgs = {
- .addr = state->addr,
- .flags = 0,
- .len = 2,
- .buf = buf
- };
-
- if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
- printk("%s i2c_transfer error %d\n", __func__, err);
- if (err < 0)
- return err;
- else
- return -EREMOTEIO;
- }
-
- return 0;
-}
-
-static int s921_read(void *dev, u8 reg) {
- struct s921_state *state = dev;
- u8 b1;
- int ret;
- struct i2c_msg msg[2] = { { .addr = state->addr,
- .flags = 0,
- .buf = &reg, .len = 1 },
- { .addr = state->addr,
- .flags = I2C_M_RD,
- .buf = &b1, .len = 1 } };
-
- ret = i2c_transfer(state->i2c, msg, 2);
- if (ret != 2)
- return ret;
- return b1;
-}
-
-struct dvb_frontend* s921_attach(const struct s921_config *config,
- struct i2c_adapter *i2c)
-{
-
- struct s921_state *state;
- state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
- if (state == NULL)
- return NULL;
-
- state->addr = config->i2c_address;
- state->i2c = i2c;
- state->dev.i2c_write = &s921_write;
- state->dev.i2c_read = &s921_read;
- state->dev.priv_dev = state;
-
- s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
-
- memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
- state->frontend.demodulator_priv = state;
- return &state->frontend;
-}
-
-EXPORT_SYMBOL_GPL(s921_attach);
-MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
-MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h
deleted file mode 100644
index 78660424ba95..000000000000
--- a/drivers/media/dvb/frontends/s921_module.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Driver for DVB-T s921 demodulator
- *
- * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef S921_MODULE_H
-#define S921_MODULE_H
-
-#include <linux/dvb/frontend.h>
-#include "s921_core.h"
-
-int s921_isdb_init(struct s921_isdb_t *dev);
-int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
-
-struct s921_config
-{
- /* demodulator's I2C address */
- u8 i2c_address;
-};
-
-#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
-extern struct dvb_frontend* s921_attach(const struct s921_config *config,
- struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
- struct i2c_adapter *i2c)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-#endif /* CONFIG_DVB_S921 */
-
-#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 8e38fcee564e..37a222d9ddb3 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -714,7 +714,7 @@ static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma
reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
-
+ msleep(100);
return 0;
}
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index 80a9e4cba631..64673b8b64a2 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -51,7 +51,7 @@ module_param(verbose, int, 0644);
if (x > y) \
printk(format, ##arg); \
} \
-} while(0)
+} while (0)
struct stb6100_lkup {
u32 val_low;
@@ -117,7 +117,10 @@ static const struct stb6100_regmask stb6100_template[] = {
[STB6100_TEST3] = { 0x00, 0xde },
};
-static void stb6100_normalise_regs(u8 regs[])
+/*
+ * Currently unused. Some boards might need it in the future
+ */
+static inline void stb6100_normalise_regs(u8 regs[])
{
int i;
@@ -157,13 +160,25 @@ static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
u8 regs[STB6100_NUMREGS];
int rc;
+ struct i2c_msg msg = {
+ .addr = state->config->tuner_address + reg,
+ .flags = I2C_M_RD,
+ .buf = regs,
+ .len = 1
+ };
+
+ rc = i2c_transfer(state->i2c, &msg, 1);
+
if (unlikely(reg >= STB6100_NUMREGS)) {
dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
return -EINVAL;
}
- if ((rc = stb6100_read_regs(state, regs)) < 0)
- return rc;
- return (unsigned int)regs[reg];
+ if (unlikely(verbose > FE_DEBUG)) {
+ dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
+ dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[reg], regs[0]);
+ }
+
+ return (unsigned int)regs[0];
}
static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
@@ -211,20 +226,17 @@ static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
return stb6100_write_reg_range(state, &data, reg, 1);
}
-static int stb6100_write_regs(struct stb6100_state *state, u8 regs[])
-{
- stb6100_normalise_regs(regs);
- return stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 1);
-}
static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
{
int rc;
struct stb6100_state *state = fe->tuner_priv;
- if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0)
+ rc = stb6100_read_reg(state, STB6100_LD);
+ if (rc < 0) {
+ dprintk(verbose, FE_ERROR, 1, "%s failed", __func__);
return rc;
-
+ }
return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
}
@@ -234,7 +246,8 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
u8 f;
struct stb6100_state *state = fe->tuner_priv;
- if ((rc = stb6100_read_reg(state, STB6100_F)) < 0)
+ rc = stb6100_read_reg(state, STB6100_F);
+ if (rc < 0)
return rc;
f = rc & STB6100_F_F;
@@ -265,14 +278,21 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
/* Turn on LPF bandwidth setting clock control,
* set bandwidth, wait 10ms, turn off.
*/
- if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0)
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK);
+ if (rc < 0)
return rc;
- if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0)
+ rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp);
+ if (rc < 0)
return rc;
- msleep(1);
- if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0)
+
+ msleep(5); /* This is dangerous as another (related) thread may start */
+
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
+ if (rc < 0)
return rc;
+ msleep(10); /* This is dangerous as another (related) thread may start */
+
return 0;
}
@@ -284,7 +304,8 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
struct stb6100_state *state = fe->tuner_priv;
u8 regs[STB6100_NUMREGS];
- if ((rc = stb6100_read_regs(state, regs)) < 0)
+ rc = stb6100_read_regs(state, regs);
+ if (rc < 0)
return rc;
odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
@@ -312,8 +333,7 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
u8 regs[STB6100_NUMREGS];
u8 g, psd2, odiv;
- if ((rc = stb6100_read_regs(state, regs)) < 0)
- return rc;
+ dprintk(verbose, FE_DEBUG, 1, "Version 2010-8-14 13:51");
if (fe->ops.get_frontend) {
dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
@@ -321,96 +341,140 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
}
srate = p.u.qpsk.symbol_rate;
- regs[STB6100_DLB] = 0xdc;
- /* Disable LPEN */
- regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */
+ /* Set up tuner cleanly, LPF calibration on */
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK);
+ if (rc < 0)
+ return rc; /* allow LPF calibration */
- if ((rc = stb6100_write_regs(state, regs)) < 0)
+ /* PLL Loop disabled, bias on, VCO on, synth on */
+ regs[STB6100_LPEN] = 0xeb;
+ rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
+ if (rc < 0)
return rc;
- /* Baseband gain. */
- if (srate >= 15000000)
- g = 9; // +4 dB
- else if (srate >= 5000000)
- g = 11; // +8 dB
- else
- g = 14; // +14 dB
-
- regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g;
- regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
- regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
+ /* Program the registers with their data values */
/* VCO divide ratio (LO divide ratio, VCO prescaler enable). */
if (frequency <= 1075000)
odiv = 1;
else
odiv = 0;
- regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT);
- if ((frequency > 1075000) && (frequency <= 1325000))
- psd2 = 0;
- else
- psd2 = 1;
- regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
+ /* VCO enabled, seach clock off as per LL3.7, 3.4.1 */
+ regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT);
/* OSM */
for (ptr = lkup;
(ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
ptr++);
+
if (ptr->val_high == 0) {
printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
return -EINVAL;
}
regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
+ rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+ if (rc < 0)
+ return rc;
+ if ((frequency > 1075000) && (frequency <= 1325000))
+ psd2 = 0;
+ else
+ psd2 = 1;
/* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */
fvco = frequency << (1 + odiv);
/* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
nint = fvco / (state->reference << psd2);
/* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
- << (9 - psd2),
- state->reference);
+ << (9 - psd2), state->reference);
+
+ /* NI */
+ regs[STB6100_NI] = nint;
+ rc = stb6100_write_reg(state, STB6100_NI, regs[STB6100_NI]);
+ if (rc < 0)
+ return rc;
+
+ /* NF */
+ regs[STB6100_NF_LSB] = nfrac;
+ rc = stb6100_write_reg(state, STB6100_NF_LSB, regs[STB6100_NF_LSB]);
+ if (rc < 0)
+ return rc;
+
+ /* K */
+ regs[STB6100_K] = (0x38 & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
+ regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
+ rc = stb6100_write_reg(state, STB6100_K, regs[STB6100_K]);
+ if (rc < 0)
+ return rc;
+
+ /* G Baseband gain. */
+ if (srate >= 15000000)
+ g = 9; /* +4 dB */
+ else if (srate >= 5000000)
+ g = 11; /* +8 dB */
+ else
+ g = 14; /* +14 dB */
+
+ regs[STB6100_G] = (0x10 & ~STB6100_G_G) | g;
+ regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
+ regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
+ rc = stb6100_write_reg(state, STB6100_G, regs[STB6100_G]);
+ if (rc < 0)
+ return rc;
+
+ /* F we don't write as it is set up in BW set */
+
+ /* DLB set DC servo loop BW to 160Hz (LLA 3.8 / 2.1) */
+ regs[STB6100_DLB] = 0xcc;
+ rc = stb6100_write_reg(state, STB6100_DLB, regs[STB6100_DLB]);
+ if (rc < 0)
+ return rc;
+
dprintk(verbose, FE_DEBUG, 1,
"frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
frequency, srate, (unsigned int)g, (unsigned int)odiv,
(unsigned int)psd2, state->reference,
ptr->reg, fvco, nint, nfrac);
- regs[STB6100_NI] = nint;
- regs[STB6100_NF_LSB] = nfrac;
- regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
- regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */
- regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */
- regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */
- regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */
- /* Power up. */
- regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN;
- msleep(2);
- if ((rc = stb6100_write_regs(state, regs)) < 0)
+ /* Set up the test registers */
+ regs[STB6100_TEST1] = 0x8f;
+ rc = stb6100_write_reg(state, STB6100_TEST1, regs[STB6100_TEST1]);
+ if (rc < 0)
+ return rc;
+ regs[STB6100_TEST3] = 0xde;
+ rc = stb6100_write_reg(state, STB6100_TEST3, regs[STB6100_TEST3]);
+ if (rc < 0)
return rc;
- msleep(2);
- regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */
- if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0)
+ /* Bring up tuner according to LLA 3.7 3.4.1, step 2 */
+ regs[STB6100_LPEN] = 0xfb; /* PLL Loop enabled, bias on, VCO on, synth on */
+ rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
+ if (rc < 0)
return rc;
+ msleep(2);
+
+ /* Bring up tuner according to LLA 3.7 3.4.1, step 3 */
regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */
- if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
+ rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+ if (rc < 0)
return rc;
- msleep(10); /* wait for LO to lock */
+ msleep(10); /* This is dangerous as another (related) thread may start */ /* wait for LO to lock */
+
regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */
regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */
- if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0)
- return rc;
- regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */
- stb6100_normalise_regs(regs);
- if ((rc = stb6100_write_reg_range(state, &regs[1], 1, STB6100_NUMREGS - 3)) < 0)
+ rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
+ if (rc < 0)
return rc;
- msleep(100);
+ rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
+ if (rc < 0)
+ return rc; /* Stop LPF calibration */
+ msleep(10); /* This is dangerous as another (related) thread may start */
+ /* wait for stabilisation, (should not be necessary) */
return 0;
}
@@ -433,8 +497,8 @@ static int stb6100_init(struct dvb_frontend *fe)
state->bandwidth = status->bandwidth * 1000; /* Hz */
state->reference = status->refclock / 1000; /* kHz */
- /* Set default bandwidth. */
- return stb6100_set_bandwidth(fe, state->bandwidth);
+ /* Set default bandwidth. Modified, PN 13-May-10 */
+ return 0;
}
static int stb6100_get_state(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 425e7a43ae19..dff4486ecc00 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -4169,6 +4169,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
switch (state->config->ts1_mode) {
case STV090x_TSMODE_PARALLEL_PUNCTURED:
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4177,6 +4178,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
case STV090x_TSMODE_DVBCI:
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4185,6 +4187,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
case STV090x_TSMODE_SERIAL_PUNCTURED:
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4193,6 +4196,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
case STV090x_TSMODE_SERIAL_CONTINUOUS:
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4206,6 +4210,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
switch (state->config->ts2_mode) {
case STV090x_TSMODE_PARALLEL_PUNCTURED:
reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4214,6 +4219,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
case STV090x_TSMODE_DVBCI:
reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4222,6 +4228,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
case STV090x_TSMODE_SERIAL_PUNCTURED:
reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4230,6 +4237,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
case STV090x_TSMODE_SERIAL_CONTINUOUS:
reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
+ STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4516,6 +4524,20 @@ err:
return -1;
}
+int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
+ u8 xor_value)
+{
+ struct stv090x_state *state = fe->demodulator_priv;
+ u8 reg = 0;
+
+ STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);
+ STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);
+ STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);
+
+ return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
+}
+EXPORT_SYMBOL(stv090x_set_gpio);
+
static struct dvb_frontend_ops stv090x_ops = {
.info = {
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
index dd1b93ae4e9d..52e969094385 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -78,6 +78,9 @@ struct stv090x_config {
u32 ts1_clk;
u32 ts2_clk;
+ u8 ts1_tei:1;
+ u8 ts2_tei:1;
+
enum stv090x_i2crpt repeater_level;
u8 tuner_bbgain; /* default: 10db */
@@ -104,6 +107,11 @@ struct stv090x_config {
extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
struct i2c_adapter *i2c,
enum stv090x_demodulator demod);
+
+/* dir = 0 -> output, dir = 1 -> input/open-drain */
+extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
+ u8 dir, u8 value, u8 xor_value);
+
#else
static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
@@ -113,6 +121,13 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
+
+static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
+ u8 opd, u8 value, u8 xor_value)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
#endif /* CONFIG_DVB_STV090x */
#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
index fd0830ed10d8..a13a50503134 100644
--- a/drivers/media/dvb/mantis/Kconfig
+++ b/drivers/media/dvb/mantis/Kconfig
@@ -1,6 +1,6 @@
config MANTIS_CORE
tristate "Mantis/Hopper PCI bridge based devices"
- depends on PCI && I2C && INPUT && IR_CORE
+ depends on PCI && I2C && INPUT && RC_CORE
help
Support for PCI cards based on the Mantis and Hopper PCi bridge.
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 09e9fc785189..70e73afefb3d 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -251,6 +251,8 @@ static struct pci_device_id hopper_pci_table[] = {
{ }
};
+MODULE_DEVICE_TABLE(pci, hopper_pci_table);
+
static struct pci_driver hopper_pci_driver = {
.name = DRIVER_NAME,
.id_table = hopper_pci_table,
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/dvb/mantis/hopper_vp3028.c
index 96674c78e86b..68a29f8bdf73 100644
--- a/drivers/media/dvb/mantis/hopper_vp3028.c
+++ b/drivers/media/dvb/mantis/hopper_vp3028.c
@@ -47,17 +47,17 @@ static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
struct mantis_hwconfig *config = mantis->hwconfig;
int err = 0;
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
err = mantis_frontend_power(mantis, POWER_ON);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
err = mantis_frontend_power(mantis, POWER_ON);
if (err == 0) {
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
- fe = zl10353_attach(&hopper_vp3028_config, adapter);
+ fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter);
if (!fe)
return -1;
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index cf4b39ffdaad..40da225098cc 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -281,6 +281,8 @@ static struct pci_device_id mantis_pci_table[] = {
{ }
};
+MODULE_DEVICE_TABLE(pci, mantis_pci_table);
+
static struct pci_driver mantis_pci_driver = {
.name = DRIVER_NAME,
.id_table = mantis_pci_table,
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
index d0b645a483c9..bd400d21b81f 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -171,7 +171,9 @@ struct mantis_pci {
struct work_struct uart_work;
spinlock_t uart_lock;
- struct input_dev *rc;
+ struct rc_dev *rc;
+ char input_name[80];
+ char input_phys[80];
};
#define MANTIS_HIF_STATUS (mantis->gpio_status)
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c
index 99d82eec3b03..e5180e45d310 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -47,15 +47,15 @@ int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
switch (power) {
case POWER_ON:
dprintk(MANTIS_DEBUG, 1, "Power ON");
- gpio_set_bits(mantis, config->power, POWER_ON);
+ mantis_gpio_set_bits(mantis, config->power, POWER_ON);
msleep(100);
- gpio_set_bits(mantis, config->power, POWER_ON);
+ mantis_gpio_set_bits(mantis, config->power, POWER_ON);
msleep(100);
break;
case POWER_OFF:
dprintk(MANTIS_DEBUG, 1, "Power OFF");
- gpio_set_bits(mantis, config->power, POWER_OFF);
+ mantis_gpio_set_bits(mantis, config->power, POWER_OFF);
msleep(100);
break;
@@ -73,13 +73,13 @@ void mantis_frontend_soft_reset(struct mantis_pci *mantis)
struct mantis_hwconfig *config = mantis->hwconfig;
dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
msleep(100);
return;
@@ -117,6 +117,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
if (mantis->feeds == 1) {
dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
mantis_dma_start(mantis);
+ tasklet_enable(&mantis->tasklet);
}
return mantis->feeds;
@@ -136,6 +137,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
mantis->feeds--;
if (mantis->feeds == 0) {
dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
+ tasklet_disable(&mantis->tasklet);
mantis_dma_stop(mantis);
}
@@ -216,6 +218,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)
dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
+ tasklet_disable(&mantis->tasklet);
if (mantis->hwconfig) {
result = config->frontend_init(mantis, mantis->fe);
if (result < 0) {
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index a99489b8418b..db6d54d3fec0 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -18,8 +18,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <linux/pci.h>
#include "dmxdev.h"
@@ -33,8 +32,9 @@
#include "mantis_uart.h"
#define MODULE_NAME "mantis_core"
+#define RC_MAP_MANTIS "rc-mantis"
-static struct ir_scancode mantis_ir_table[] = {
+static struct rc_map_table mantis_ir_table[] = {
{ 0x29, KEY_POWER },
{ 0x28, KEY_FAVORITES },
{ 0x30, KEY_TEXT },
@@ -95,53 +95,65 @@ static struct ir_scancode mantis_ir_table[] = {
{ 0x00, KEY_BLUE },
};
-struct ir_scancode_table ir_mantis = {
- .scan = mantis_ir_table,
- .size = ARRAY_SIZE(mantis_ir_table),
+static struct rc_map_list ir_mantis_map = {
+ .map = {
+ .scan = mantis_ir_table,
+ .size = ARRAY_SIZE(mantis_ir_table),
+ .rc_type = RC_TYPE_UNKNOWN,
+ .name = RC_MAP_MANTIS,
+ }
};
-EXPORT_SYMBOL_GPL(ir_mantis);
int mantis_input_init(struct mantis_pci *mantis)
{
- struct input_dev *rc;
- char name[80], dev[80];
+ struct rc_dev *dev;
int err;
- rc = input_allocate_device();
- if (!rc) {
- dprintk(MANTIS_ERROR, 1, "Input device allocate failed");
- return -ENOMEM;
- }
+ err = rc_map_register(&ir_mantis_map);
+ if (err)
+ goto out;
- sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
- sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev));
+ dev = rc_allocate_device();
+ if (!dev) {
+ dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
+ err = -ENOMEM;
+ goto out_map;
+ }
- rc->name = name;
- rc->phys = dev;
+ sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
+ sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
- rc->id.bustype = BUS_PCI;
- rc->id.vendor = mantis->vendor_id;
- rc->id.product = mantis->device_id;
- rc->id.version = 1;
- rc->dev = mantis->pdev->dev;
+ dev->input_name = mantis->input_name;
+ dev->input_phys = mantis->input_phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.vendor = mantis->vendor_id;
+ dev->input_id.product = mantis->device_id;
+ dev->input_id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->map_name = RC_MAP_MANTIS;
+ dev->dev.parent = &mantis->pdev->dev;
- err = __ir_input_register(rc, &ir_mantis, NULL, MODULE_NAME);
+ err = rc_register_device(dev);
if (err) {
dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
- input_free_device(rc);
- return -ENODEV;
+ goto out_dev;
}
- mantis->rc = rc;
-
+ mantis->rc = dev;
return 0;
+
+out_dev:
+ rc_free_device(dev);
+out_map:
+ rc_map_unregister(&ir_mantis_map);
+out:
+ return err;
}
int mantis_exit(struct mantis_pci *mantis)
{
- struct input_dev *rc = mantis->rc;
-
- ir_input_unregister(rc);
-
+ rc_unregister_device(mantis->rc);
+ rc_map_unregister(&ir_mantis_map);
return 0;
}
+
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c
index fe31cfb0b158..479086dbb9a8 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/dvb/mantis/mantis_ioc.c
@@ -75,7 +75,7 @@ int mantis_get_mac(struct mantis_pci *mantis)
EXPORT_SYMBOL_GPL(mantis_get_mac);
/* Turn the given bit on or off. */
-void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
{
u32 cur;
@@ -90,7 +90,7 @@ void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
mmwrite(0x00, MANTIS_GPIF_DOUT);
}
-EXPORT_SYMBOL_GPL(gpio_set_bits);
+EXPORT_SYMBOL_GPL(mantis_gpio_set_bits);
int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
{
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/dvb/mantis/mantis_ioc.h
index 188fe5a81614..d56e002b2955 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.h
+++ b/drivers/media/dvb/mantis/mantis_ioc.h
@@ -44,7 +44,7 @@ enum mantis_stream_control {
};
extern int mantis_get_mac(struct mantis_pci *mantis);
-extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
+extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c
index 4a723bda0031..deec927c7f7a 100644
--- a/drivers/media/dvb/mantis/mantis_vp1033.c
+++ b/drivers/media/dvb/mantis/mantis_vp1033.c
@@ -173,7 +173,7 @@ static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
- fe = stv0299_attach(&lgtdqcs001f_config, adapter);
+ fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
if (fe) {
fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c
index 8e6ae558ee57..26bc0cbe84d4 100644
--- a/drivers/media/dvb/mantis/mantis_vp1034.c
+++ b/drivers/media/dvb/mantis/mantis_vp1034.c
@@ -50,13 +50,13 @@ int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
switch (voltage) {
case SEC_VOLTAGE_13:
dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
- gpio_set_bits(mantis, 13, 1);
- gpio_set_bits(mantis, 14, 0);
+ mantis_gpio_set_bits(mantis, 13, 1);
+ mantis_gpio_set_bits(mantis, 14, 0);
break;
case SEC_VOLTAGE_18:
dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
- gpio_set_bits(mantis, 13, 1);
- gpio_set_bits(mantis, 14, 1);
+ mantis_gpio_set_bits(mantis, 13, 1);
+ mantis_gpio_set_bits(mantis, 14, 1);
break;
case SEC_VOLTAGE_OFF:
dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
@@ -82,7 +82,7 @@ static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
- fe = mb86a16_attach(&vp1034_mb86a16_config, adapter);
+ fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter);
if (fe) {
dprintk(MANTIS_ERROR, 1,
"found MB86A16 DVB-S/DSS frontend @0x%02x",
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c
index d1aa2bc0c155..38a436ca2fdf 100644
--- a/drivers/media/dvb/mantis/mantis_vp1041.c
+++ b/drivers/media/dvb/mantis/mantis_vp1041.c
@@ -316,14 +316,14 @@ static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
if (err == 0) {
mantis_frontend_soft_reset(mantis);
msleep(250);
- mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter);
+ mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter);
if (mantis->fe) {
dprintk(MANTIS_ERROR, 1,
"found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
vp1041_stb0899_config.demod_address);
- if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) {
- if (!lnbp21_attach(mantis->fe, adapter, 0, 0))
+ if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) {
+ if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0))
dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
}
} else {
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c
index 10ce81790a8c..06da0ddf05a7 100644
--- a/drivers/media/dvb/mantis/mantis_vp2033.c
+++ b/drivers/media/dvb/mantis/mantis_vp2033.c
@@ -132,7 +132,7 @@ static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
- fe = tda10021_attach(&vp2033_tda1002x_cu1216_config,
+ fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config,
adapter,
read_pwm(mantis));
@@ -141,7 +141,7 @@ static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
vp2033_tda1002x_cu1216_config.demod_address);
} else {
- fe = tda10023_attach(&vp2033_tda10023_cu1216_config,
+ fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config,
adapter,
read_pwm(mantis));
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c
index a7ca233e800b..f72b137b7652 100644
--- a/drivers/media/dvb/mantis/mantis_vp2040.c
+++ b/drivers/media/dvb/mantis/mantis_vp2040.c
@@ -132,7 +132,7 @@ static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
- fe = tda10021_attach(&vp2040_tda1002x_cu1216_config,
+ fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config,
adapter,
read_pwm(mantis));
@@ -141,7 +141,7 @@ static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
vp2040_tda1002x_cu1216_config.demod_address);
} else {
- fe = tda10023_attach(&vp2040_tda10023_cu1216_config,
+ fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config,
adapter,
read_pwm(mantis));
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c
index 1f4334214953..c09308cd3ac6 100644
--- a/drivers/media/dvb/mantis/mantis_vp3030.c
+++ b/drivers/media/dvb/mantis/mantis_vp3030.c
@@ -59,21 +59,21 @@ static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
struct mantis_hwconfig *config = mantis->hwconfig;
int err = 0;
- gpio_set_bits(mantis, config->reset, 0);
+ mantis_gpio_set_bits(mantis, config->reset, 0);
msleep(100);
err = mantis_frontend_power(mantis, POWER_ON);
msleep(100);
- gpio_set_bits(mantis, config->reset, 1);
+ mantis_gpio_set_bits(mantis, config->reset, 1);
if (err == 0) {
msleep(250);
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
- fe = zl10353_attach(&mantis_vp3030_config, adapter);
+ fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter);
if (!fe)
return -1;
- tda665x_attach(fe, &env57h12d5_config, adapter);
+ dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter);
} else {
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
adapter->name,
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index 3a7ef71087be..be71f915e2a3 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -1515,7 +1515,7 @@ static int init_channels(struct ngene *dev)
void __devexit ngene_remove(struct pci_dev *pdev)
{
- struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
+ struct ngene *dev = pci_get_drvdata(pdev);
int i;
tasklet_kill(&dev->event_tasklet);
@@ -1536,12 +1536,11 @@ int __devinit ngene_probe(struct pci_dev *pci_dev,
if (pci_enable_device(pci_dev) < 0)
return -ENODEV;
- dev = vmalloc(sizeof(struct ngene));
+ dev = vzalloc(sizeof(struct ngene));
if (dev == NULL) {
stat = -ENOMEM;
goto fail0;
}
- memset(dev, 0, sizeof(struct ngene));
dev->pci_dev = pci_dev;
dev->card_info = (struct ngene_info *)id->driver_data;
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
index e520bceee0af..bc6456eb2c4f 100644
--- a/drivers/media/dvb/siano/Kconfig
+++ b/drivers/media/dvb/siano/Kconfig
@@ -4,7 +4,7 @@
config SMS_SIANO_MDTV
tristate "Siano SMS1xxx based MDTV receiver"
- depends on DVB_CORE && IR_CORE && HAS_DMA
+ depends on DVB_CORE && RC_CORE && HAS_DMA
---help---
Choose Y or M here if you have MDTV receiver with a Siano chipset.
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 135e45bd00c7..78765ed28063 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -438,7 +438,7 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
int rc;
void *buffer;
- coredev->ir.input_dev = NULL;
+ coredev->ir.dev = NULL;
ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
if (ir_io) {/* only if IR port exist we use IR sub-module */
sms_info("IR loading");
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
index a27c44a8af5a..37bc5c4b8ad8 100644
--- a/drivers/media/dvb/siano/smsir.c
+++ b/drivers/media/dvb/siano/smsir.c
@@ -45,25 +45,24 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
ev.pulse = (samples[i] > 0) ? false : true;
- ir_raw_event_store(coredev->ir.input_dev, &ev);
+ ir_raw_event_store(coredev->ir.dev, &ev);
}
- ir_raw_event_handle(coredev->ir.input_dev);
+ ir_raw_event_handle(coredev->ir.dev);
}
int sms_ir_init(struct smscore_device_t *coredev)
{
- struct input_dev *input_dev;
+ int err;
int board_id = smscore_get_board_id(coredev);
+ struct rc_dev *dev;
- sms_log("Allocating input device");
- input_dev = input_allocate_device();
- if (!input_dev) {
+ sms_log("Allocating rc device");
+ dev = rc_allocate_device();
+ if (!dev) {
sms_err("Not enough memory");
return -ENOMEM;
}
- coredev->ir.input_dev = input_dev;
-
coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
sms_log("IR port %d, timeout %d ms",
@@ -75,38 +74,41 @@ int sms_ir_init(struct smscore_device_t *coredev)
strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
- input_dev->name = coredev->ir.name;
- input_dev->phys = coredev->ir.phys;
- input_dev->dev.parent = coredev->device;
+ dev->input_name = coredev->ir.name;
+ dev->input_phys = coredev->ir.phys;
+ dev->dev.parent = coredev->device;
#if 0
/* TODO: properly initialize the parameters bellow */
- input_dev->id.bustype = BUS_USB;
- input_dev->id.version = 1;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ dev->input_id.bustype = BUS_USB;
+ dev->input_id.version = 1;
+ dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif
- coredev->ir.props.priv = coredev;
- coredev->ir.props.driver_type = RC_DRIVER_IR_RAW;
- coredev->ir.props.allowed_protos = IR_TYPE_ALL;
+ dev->priv = coredev;
+ dev->driver_type = RC_DRIVER_IR_RAW;
+ dev->allowed_protos = RC_TYPE_ALL;
+ dev->map_name = sms_get_board(board_id)->rc_codes;
+ dev->driver_name = MODULE_NAME;
- sms_log("Input device (IR) %s is set for key events", input_dev->name);
+ sms_log("Input device (IR) %s is set for key events", dev->input_name);
- if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes,
- &coredev->ir.props, MODULE_NAME)) {
+ err = rc_register_device(dev);
+ if (err < 0) {
sms_err("Failed to register device");
- input_free_device(input_dev);
- return -EACCES;
+ rc_free_device(dev);
+ return err;
}
+ coredev->ir.dev = dev;
return 0;
}
void sms_ir_exit(struct smscore_device_t *coredev)
{
- if (coredev->ir.input_dev)
- ir_input_unregister(coredev->ir.input_dev);
+ if (coredev->ir.dev)
+ rc_unregister_device(coredev->ir.dev);
sms_log("");
}
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h
index 926e247523bd..ae92b3a8587e 100644
--- a/drivers/media/dvb/siano/smsir.h
+++ b/drivers/media/dvb/siano/smsir.h
@@ -28,20 +28,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define __SMS_IR_H__
#include <linux/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#define IR_DEFAULT_TIMEOUT 100
struct smscore_device_t;
struct ir_t {
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char name[40];
char phys[32];
char *rc_codes;
u64 protocol;
- struct ir_dev_props props;
u32 timeout;
u32 controller;
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 50d4338610e0..0b8da57cf4c3 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -288,8 +288,7 @@ static int smsusb1_setmode(void *context, int mode)
static void smsusb_term_device(struct usb_interface *intf)
{
- struct smsusb_device_t *dev =
- (struct smsusb_device_t *) usb_get_intfdata(intf);
+ struct smsusb_device_t *dev = usb_get_intfdata(intf);
if (dev) {
smsusb_stop_streaming(dev);
@@ -445,8 +444,7 @@ static void smsusb_disconnect(struct usb_interface *intf)
static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
{
- struct smsusb_device_t *dev =
- (struct smsusb_device_t *)usb_get_intfdata(intf);
+ struct smsusb_device_t *dev = usb_get_intfdata(intf);
printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
smsusb_stop_streaming(dev);
return 0;
@@ -455,8 +453,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
static int smsusb_resume(struct usb_interface *intf)
{
int rc, i;
- struct smsusb_device_t *dev =
- (struct smsusb_device_t *)usb_get_intfdata(intf);
+ struct smsusb_device_t *dev = usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
printk(KERN_INFO "%s: Entering.\n", __func__);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index debea8d1d31c..44afab2fdc2d 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -89,7 +89,6 @@ config DVB_BUDGET
config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_BUDGET_CORE && I2C
- depends on INPUT # due to IR
select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
@@ -98,7 +97,7 @@ config DVB_BUDGET_CI
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
- depends on VIDEO_IR
+ depends on RC_CORE
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index a9c2c326df4b..8ae67c1751a9 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -33,9 +33,8 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/spinlock.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "budget.h"
@@ -96,7 +95,7 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct budget_ci_ir {
- struct input_dev *dev;
+ struct rc_dev *dev;
struct tasklet_struct msp430_irq_tasklet;
char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
char phys[32];
@@ -118,7 +117,7 @@ struct budget_ci {
static void msp430_ir_interrupt(unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci *) data;
- struct input_dev *dev = budget_ci->ir.dev;
+ struct rc_dev *dev = budget_ci->ir.dev;
u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
/*
@@ -160,19 +159,17 @@ static void msp430_ir_interrupt(unsigned long data)
budget_ci->ir.rc5_device != (command & 0x1f))
return;
- ir_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
+ rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
}
static int msp430_ir_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *input_dev = budget_ci->ir.dev;
+ struct rc_dev *dev;
int error;
- char *ir_codes = NULL;
-
- budget_ci->ir.dev = input_dev = input_allocate_device();
- if (!input_dev) {
+ dev = rc_allocate_device();
+ if (!dev) {
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
return -ENOMEM;
}
@@ -182,19 +179,19 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
"pci-%s/ir0", pci_name(saa->pci));
- input_dev->name = budget_ci->ir.name;
-
- input_dev->phys = budget_ci->ir.phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->input_name = budget_ci->ir.name;
+ dev->input_phys = budget_ci->ir.phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (saa->pci->subsystem_vendor) {
- input_dev->id.vendor = saa->pci->subsystem_vendor;
- input_dev->id.product = saa->pci->subsystem_device;
+ dev->input_id.vendor = saa->pci->subsystem_vendor;
+ dev->input_id.product = saa->pci->subsystem_device;
} else {
- input_dev->id.vendor = saa->pci->vendor;
- input_dev->id.product = saa->pci->device;
+ dev->input_id.vendor = saa->pci->vendor;
+ dev->input_id.product = saa->pci->device;
}
- input_dev->dev.parent = &saa->pci->dev;
+ dev->dev.parent = &saa->pci->dev;
if (rc5_device < 0)
budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -208,7 +205,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1011:
case 0x1012:
/* The hauppauge keymap is a superset of these remotes */
- ir_codes = RC_MAP_HAUPPAUGE_NEW;
+ dev->map_name = RC_MAP_HAUPPAUGE_NEW;
if (rc5_device < 0)
budget_ci->ir.rc5_device = 0x1f;
@@ -218,23 +215,22 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1019:
case 0x101a:
/* for the Technotrend 1500 bundled remote */
- ir_codes = RC_MAP_TT_1500;
+ dev->map_name = RC_MAP_TT_1500;
break;
default:
/* unknown remote */
- ir_codes = RC_MAP_BUDGET_CI_OLD;
+ dev->map_name = RC_MAP_BUDGET_CI_OLD;
break;
}
- error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+ error = rc_register_device(dev);
if (error) {
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
+ rc_free_device(dev);
return error;
}
- /* note: these must be after input_register_device */
- input_dev->rep[REP_DELAY] = 400;
- input_dev->rep[REP_PERIOD] = 250;
+ budget_ci->ir.dev = dev;
tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
(unsigned long) budget_ci);
@@ -248,13 +244,12 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
static void msp430_ir_deinit(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *dev = budget_ci->ir.dev;
SAA7146_IER_DISABLE(saa, MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
- ir_input_unregister(dev);
+ rc_unregister_device(budget_ci->ir.dev);
}
static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 5bf4985daede..05e832f61c3e 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations rtrack_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
@@ -412,13 +412,6 @@ static int __init rtrack_init(void)
rt->vdev.release = video_device_release_empty;
video_set_drvdata(&rt->vdev, rt);
- if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(&rt->v4l2_dev);
- release_region(rt->io, 2);
- return -EINVAL;
- }
- v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
-
/* Set up the I/O locking */
mutex_init(&rt->lock);
@@ -430,6 +423,13 @@ static int __init rtrack_init(void)
sleep_delay(2000000); /* make sure it's totally down */
outb(0xc0, rt->io); /* steady volume, mute card */
+ if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&rt->v4l2_dev);
+ release_region(rt->io, 2);
+ return -EINVAL;
+ }
+ v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
+
return 0;
}
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index c22311393624..dd8a6ab0d437 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
static const struct v4l2_file_operations aztech_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
@@ -375,6 +375,8 @@ static int __init aztech_init(void)
az->vdev.ioctl_ops = &aztech_ioctl_ops;
az->vdev.release = video_device_release_empty;
video_set_drvdata(&az->vdev, az);
+ /* mute card - prevents noisy bootups */
+ outb(0, az->io);
if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
@@ -383,8 +385,6 @@ static int __init aztech_init(void)
}
v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
- /* mute card - prevents noisy bootups */
- outb(0, az->io);
return 0;
}
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index b701ea6e7c73..bc9ad0897c55 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
unsigned char readbuf[RDS_BUFFER];
int i = 0;
+ mutex_lock(&dev->lock);
if (dev->rdsstat == 0) {
- mutex_lock(&dev->lock);
dev->rdsstat = 1;
outb(0x80, dev->io); /* Select RDS fifo */
- mutex_unlock(&dev->lock);
init_timer(&dev->readtimer);
dev->readtimer.function = cadet_handler;
dev->readtimer.data = (unsigned long)dev;
@@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
add_timer(&dev->readtimer);
}
if (dev->rdsin == dev->rdsout) {
+ mutex_unlock(&dev->lock);
if (file->f_flags & O_NONBLOCK)
return -EWOULDBLOCK;
interruptible_sleep_on(&dev->read_queue);
+ mutex_lock(&dev->lock);
}
while (i < count && dev->rdsin != dev->rdsout)
readbuf[i++] = dev->rdsbuf[dev->rdsout++];
+ mutex_unlock(&dev->lock);
if (copy_to_user(data, readbuf, i))
return -EFAULT;
@@ -525,9 +527,11 @@ static int cadet_open(struct file *file)
{
struct cadet *dev = video_drvdata(file);
+ mutex_lock(&dev->lock);
dev->users++;
if (1 == dev->users)
init_waitqueue_head(&dev->read_queue);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -535,11 +539,13 @@ static int cadet_release(struct file *file)
{
struct cadet *dev = video_drvdata(file);
+ mutex_lock(&dev->lock);
dev->users--;
if (0 == dev->users) {
del_timer_sync(&dev->readtimer);
dev->rdsstat = 0;
}
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = {
.open = cadet_open,
.release = cadet_release,
.read = cadet_read,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.poll = cadet_poll,
};
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 79039674a0e0..28fa85ba2087 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
static const struct v4l2_file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
@@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev
card->vdev.release = video_device_release_empty;
video_set_drvdata(&card->vdev, card);
+ gemtek_pci_mute(card);
+
if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
goto err_video;
- gemtek_pci_mute(card);
-
v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
pdev->revision, card->iobase, card->iobase + card->length - 1);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 73985f641f07..259936422e49 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt)
static const struct v4l2_file_operations gemtek_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static int vidioc_querycap(struct file *file, void *priv,
@@ -577,12 +577,6 @@ static int __init gemtek_init(void)
gt->vdev.release = video_device_release_empty;
video_set_drvdata(&gt->vdev, gt);
- if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(v4l2_dev);
- release_region(gt->io, 1);
- return -EBUSY;
- }
-
/* Set defaults */
gt->lastfreq = GEMTEK_LOWFREQ;
gt->bu2614data = 0;
@@ -590,6 +584,12 @@ static int __init gemtek_init(void)
if (initmute)
gemtek_mute(gt);
+ if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(gt->io, 1);
+ return -EBUSY;
+ }
+
return 0;
}
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 08f1051979ca..6af61bfeb178 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations maestro_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
@@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
dev->vdev.release = video_device_release_empty;
video_set_drvdata(&dev->vdev, dev);
+ if (!radio_power_on(dev)) {
+ retval = -EIO;
+ goto errfr1;
+ }
+
retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
if (retval) {
v4l2_err(v4l2_dev, "can't register video device!\n");
goto errfr1;
}
- if (!radio_power_on(dev)) {
- retval = -EIO;
- goto errunr;
- }
-
v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
return 0;
-errunr:
- video_unregister_device(&dev->vdev);
errfr1:
v4l2_device_unregister(v4l2_dev);
errfr:
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 255d40df4b46..6459a220b0dd 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
static const struct v4l2_file_operations maxiradio_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
index 4ff885445fd4..3fb76e3834c9 100644
--- a/drivers/media/radio/radio-miropcm20.c
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -33,6 +33,7 @@ struct pcm20 {
unsigned long freq;
int muted;
struct snd_miro_aci *aci;
+ struct mutex lock;
};
static struct pcm20 pcm20_card = {
@@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
static const struct v4l2_file_operations pcm20_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static int vidioc_querycap(struct file *file, void *priv,
@@ -229,7 +230,7 @@ static int __init pcm20_init(void)
return -ENODEV;
}
strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
-
+ mutex_init(&dev->lock);
res = v4l2_device_register(NULL, v4l2_dev);
if (res < 0) {
@@ -242,6 +243,7 @@ static int __init pcm20_init(void)
dev->vdev.fops = &pcm20_fops;
dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
dev->vdev.release = video_device_release_empty;
+ dev->vdev.lock = &dev->lock;
video_set_drvdata(&dev->vdev, dev);
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index a79296aac9a9..8d6ea591bd18 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations rtrack2_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
@@ -315,6 +315,10 @@ static int __init rtrack2_init(void)
dev->vdev.release = video_device_release_empty;
video_set_drvdata(&dev->vdev, dev);
+ /* mute card - prevents noisy bootups */
+ outb(1, dev->io);
+ dev->muted = 1;
+
mutex_init(&dev->lock);
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
@@ -324,10 +328,6 @@ static int __init rtrack2_init(void)
v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
- /* mute card - prevents noisy bootups */
- outb(1, dev->io);
- dev->muted = 1;
-
return 0;
}
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 985359d18aa5..b5a5f89e238a 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations fmi_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
@@ -382,6 +382,9 @@ static int __init fmi_init(void)
mutex_init(&fmi->lock);
+ /* mute card - prevents noisy bootups */
+ fmi_mute(fmi);
+
if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
release_region(fmi->io, 2);
@@ -391,8 +394,6 @@ static int __init fmi_init(void)
}
v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
- /* mute card - prevents noisy bootups */
- fmi_mute(fmi);
return 0;
}
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 52c7bbb32b8b..dc3f04c52d5e 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations fmr2_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
@@ -424,6 +424,10 @@ static int __init fmr2_init(void)
fmr2->vdev.release = video_device_release_empty;
video_set_drvdata(&fmr2->vdev, fmr2);
+ /* mute card - prevents noisy bootups */
+ fmr2_mute(fmr2->io);
+ fmr2_product_info(fmr2);
+
if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(v4l2_dev);
release_region(fmr2->io, 2);
@@ -431,11 +435,6 @@ static int __init fmr2_init(void)
}
v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
- /* mute card - prevents noisy bootups */
- mutex_lock(&fmr2->lock);
- fmr2_mute(fmr2->io);
- fmr2_product_info(fmr2);
- mutex_unlock(&fmr2->lock);
debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
return 0;
}
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 03829e6818bd..726d367ad8d0 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -53,7 +53,8 @@ struct radio_si4713_device {
/* radio_si4713_fops - file operations interface */
static const struct v4l2_file_operations radio_si4713_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ /* Note: locking is done at the subdev level in the i2c driver. */
+ .unlocked_ioctl = video_ioctl2,
};
/* Video4Linux Interface */
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 789d2ec66e19..0e71d816c725 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -142,7 +142,6 @@ struct tea5764_device {
struct video_device *videodev;
struct tea5764_regs regs;
struct mutex mutex;
- int users;
};
/* I2C code related */
@@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv,
return 0;
}
-static int tea5764_open(struct file *file)
-{
- /* Currently we support only one device */
- struct tea5764_device *radio = video_drvdata(file);
-
- mutex_lock(&radio->mutex);
- /* Only exclusive access */
- if (radio->users) {
- mutex_unlock(&radio->mutex);
- return -EBUSY;
- }
- radio->users++;
- mutex_unlock(&radio->mutex);
- file->private_data = radio;
- return 0;
-}
-
-static int tea5764_close(struct file *file)
-{
- struct tea5764_device *radio = video_drvdata(file);
-
- if (!radio)
- return -ENODEV;
- mutex_lock(&radio->mutex);
- radio->users--;
- mutex_unlock(&radio->mutex);
- return 0;
-}
-
/* File system interface */
static const struct v4l2_file_operations tea5764_fops = {
.owner = THIS_MODULE,
- .open = tea5764_open,
- .release = tea5764_close,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops tea5764_ioctl_ops = {
@@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
int ret;
PDEBUG("probe");
- radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL);
+ radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL);
if (!radio)
return -ENOMEM;
@@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, radio);
video_set_drvdata(radio->videodev, radio);
-
- ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
- if (ret < 0) {
- PWARN("Could not register video device!");
- goto errrel;
- }
+ radio->videodev->lock = &radio->mutex;
/* initialize and power off the chip */
tea5764_i2c_read(radio);
@@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
tea5764_mute(radio, 1);
tea5764_power_down(radio);
+ ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ if (ret < 0) {
+ PWARN("Could not register video device!");
+ goto errrel;
+ }
+
PINFO("registered.");
return 0;
errrel:
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index fc1c860fd438..a32663917059 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations terratec_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
@@ -389,6 +389,9 @@ static int __init terratec_init(void)
mutex_init(&tt->lock);
+ /* mute card - prevents noisy bootups */
+ tt_write_vol(tt, 0);
+
if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(&tt->v4l2_dev);
release_region(tt->io, 2);
@@ -396,9 +399,6 @@ static int __init terratec_init(void)
}
v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
-
- /* mute card - prevents noisy bootups */
- tt_write_vol(tt, 0);
return 0;
}
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index b8bb3ef47df5..a185610b376b 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -34,6 +34,7 @@ struct timbradio {
struct v4l2_subdev *sd_dsp;
struct video_device video_dev;
struct v4l2_device v4l2_dev;
+ struct mutex lock;
};
@@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
static const struct v4l2_file_operations timbradio_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static int __devinit timbradio_probe(struct platform_device *pdev)
@@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
}
tr->pdata = *pdata;
+ mutex_init(&tr->lock);
strlcpy(tr->video_dev.name, "Timberdale Radio",
sizeof(tr->video_dev.name));
@@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
tr->video_dev.release = video_device_release_empty;
tr->video_dev.minor = -1;
+ tr->video_dev.lock = &tr->lock;
strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
err = v4l2_device_register(NULL, &tr->v4l2_dev);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 9d6dcf8af5b0..22fa9cc28abe 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations trust_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops trust_ioctl_ops = {
@@ -396,14 +396,6 @@ static int __init trust_init(void)
tr->vdev.release = video_device_release_empty;
video_set_drvdata(&tr->vdev, tr);
- if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(v4l2_dev);
- release_region(tr->io, 2);
- return -EINVAL;
- }
-
- v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
-
write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
@@ -418,6 +410,14 @@ static int __init trust_init(void)
/* mute card - prevents noisy bootups */
tr_setmute(tr, 1);
+ if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(tr->io, 2);
+ return -EINVAL;
+ }
+
+ v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
+
return 0;
}
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index b1f630527dc1..8dbbf08f2207 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv)
static const struct v4l2_file_operations typhoon_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
@@ -344,18 +344,18 @@ static int __init typhoon_init(void)
strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
dev->io = io;
- dev->curfreq = dev->mutefreq = mutefreq;
if (dev->io == -1) {
v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
return -EINVAL;
}
- if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+ if (mutefreq < 87000 || mutefreq > 108500) {
v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
return -EINVAL;
}
+ dev->curfreq = dev->mutefreq = mutefreq << 4;
mutex_init(&dev->lock);
if (!request_region(dev->io, 8, "typhoon")) {
@@ -378,17 +378,17 @@ static int __init typhoon_init(void)
dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
dev->vdev.release = video_device_release_empty;
video_set_drvdata(&dev->vdev, dev);
+
+ /* mute card - prevents noisy bootups */
+ typhoon_mute(dev);
+
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
v4l2_device_unregister(&dev->v4l2_dev);
release_region(dev->io, 8);
return -EINVAL;
}
v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
- v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
- dev->mutefreq <<= 4;
-
- /* mute card - prevents noisy bootups */
- typhoon_mute(dev);
+ v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq);
return 0;
}
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index f31eab99c943..af99c5bd88c1 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
static const struct v4l2_file_operations zoltrix_fops =
{
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
@@ -424,20 +424,6 @@ static int __init zoltrix_init(void)
return res;
}
- strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
- zol->vdev.v4l2_dev = v4l2_dev;
- zol->vdev.fops = &zoltrix_fops;
- zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
- zol->vdev.release = video_device_release_empty;
- video_set_drvdata(&zol->vdev, zol);
-
- if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
- v4l2_device_unregister(v4l2_dev);
- release_region(zol->io, 2);
- return -EINVAL;
- }
- v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
-
mutex_init(&zol->lock);
/* mute card - prevents noisy bootups */
@@ -452,6 +438,20 @@ static int __init zoltrix_init(void)
zol->curvol = 0;
zol->stereo = 1;
+ strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+ zol->vdev.v4l2_dev = v4l2_dev;
+ zol->vdev.fops = &zoltrix_fops;
+ zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+ zol->vdev.release = video_device_release_empty;
+ video_set_drvdata(&zol->vdev, zol);
+
+ if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(zol->io, 2);
+ return -EINVAL;
+ }
+ v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
+
return 0;
}
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index a6e6f1987a3a..0fab6f8f7e24 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -27,6 +27,8 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
@@ -43,6 +45,11 @@ MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
MODULE_VERSION("0.0.1");
+static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = {
+ "vio",
+ "vdd",
+};
+
#define DEFAULT_RDS_PI 0x00
#define DEFAULT_RDS_PTY 0x00
#define DEFAULT_RDS_PS_NAME ""
@@ -369,7 +376,17 @@ static int si4713_powerup(struct si4713_device *sdev)
if (sdev->power_state)
return 0;
- sdev->platform_data->set_power(1);
+ err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (err) {
+ v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err);
+ return err;
+ }
+ if (gpio_is_valid(sdev->gpio_reset)) {
+ udelay(50);
+ gpio_set_value(sdev->gpio_reset, 1);
+ }
+
err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
args, ARRAY_SIZE(args),
resp, ARRAY_SIZE(resp),
@@ -384,7 +401,13 @@ static int si4713_powerup(struct si4713_device *sdev)
err = si4713_write_property(sdev, SI4713_GPO_IEN,
SI4713_STC_INT | SI4713_CTS);
} else {
- sdev->platform_data->set_power(0);
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_set_value(sdev->gpio_reset, 0);
+ err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (err)
+ v4l2_err(&sdev->sd,
+ "Failed to disable supplies: %d\n", err);
}
return err;
@@ -411,7 +434,13 @@ static int si4713_powerdown(struct si4713_device *sdev)
v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
resp[0]);
v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
- sdev->platform_data->set_power(0);
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_set_value(sdev->gpio_reset, 0);
+ err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (err)
+ v4l2_err(&sdev->sd,
+ "Failed to disable supplies: %d\n", err);
sdev->power_state = POWER_OFF;
}
@@ -1967,7 +1996,8 @@ static int si4713_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct si4713_device *sdev;
- int rval;
+ struct si4713_platform_data *pdata = client->dev.platform_data;
+ int rval, i;
sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
if (!sdev) {
@@ -1976,11 +2006,26 @@ static int si4713_probe(struct i2c_client *client,
goto exit;
}
- sdev->platform_data = client->dev.platform_data;
- if (!sdev->platform_data) {
- v4l2_err(&sdev->sd, "No platform data registered.\n");
- rval = -ENODEV;
- goto free_sdev;
+ sdev->gpio_reset = -1;
+ if (pdata && gpio_is_valid(pdata->gpio_reset)) {
+ rval = gpio_request(pdata->gpio_reset, "si4713 reset");
+ if (rval) {
+ dev_err(&client->dev,
+ "Failed to request gpio: %d\n", rval);
+ goto free_sdev;
+ }
+ sdev->gpio_reset = pdata->gpio_reset;
+ gpio_direction_output(sdev->gpio_reset, 0);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sdev->supplies); i++)
+ sdev->supplies[i].supply = si4713_supply_names[i];
+
+ rval = regulator_bulk_get(&client->dev, ARRAY_SIZE(sdev->supplies),
+ sdev->supplies);
+ if (rval) {
+ dev_err(&client->dev, "Cannot get regulators: %d\n", rval);
+ goto free_gpio;
}
v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
@@ -1994,7 +2039,7 @@ static int si4713_probe(struct i2c_client *client,
client->name, sdev);
if (rval < 0) {
v4l2_err(&sdev->sd, "Could not request IRQ\n");
- goto free_sdev;
+ goto put_reg;
}
v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
} else {
@@ -2012,6 +2057,11 @@ static int si4713_probe(struct i2c_client *client,
free_irq:
if (client->irq)
free_irq(client->irq, sdev);
+put_reg:
+ regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
+free_gpio:
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_free(sdev->gpio_reset);
free_sdev:
kfree(sdev);
exit:
@@ -2031,7 +2081,9 @@ static int si4713_remove(struct i2c_client *client)
free_irq(client->irq, sdev);
v4l2_device_unregister_subdev(sd);
-
+ regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
+ if (gpio_is_valid(sdev->gpio_reset))
+ gpio_free(sdev->gpio_reset);
kfree(sdev);
return 0;
diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713-i2c.h
index faf8cff124f1..c6dfa7fb101c 100644
--- a/drivers/media/radio/si4713-i2c.h
+++ b/drivers/media/radio/si4713-i2c.h
@@ -211,6 +211,8 @@ struct acomp_info {
u32 enabled;
};
+#define SI4713_NUM_SUPPLIES 2
+
/*
* si4713_device - private data
*/
@@ -220,11 +222,12 @@ struct si4713_device {
/* private data structures */
struct mutex mutex;
struct completion work;
- struct si4713_platform_data *platform_data;
struct rds_info rds_info;
struct limiter_info limiter_info;
struct pilot_info pilot_info;
struct acomp_info acomp_info;
+ struct regulator_bulk_data supplies[SI4713_NUM_SUPPLIES];
+ int gpio_reset;
u32 frequency;
u32 preemphasis;
u32 mute;
diff --git a/drivers/media/IR/Kconfig b/drivers/media/rc/Kconfig
index aa4163eb7a83..3785162f928e 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -1,21 +1,17 @@
-menuconfig IR_CORE
- tristate "Infrared remote controller adapters"
+menuconfig RC_CORE
+ tristate "Remote Controller adapters"
depends on INPUT
default INPUT
---help---
Enable support for Remote Controllers on Linux. This is
needed in order to support several video capture adapters.
+ Currently, all supported devices use InfraRed.
Enable this option if you have a video capture board even
if you don't need IR, as otherwise, you may not be able to
compile the driver for your adapter.
-config VIDEO_IR
- tristate
- depends on IR_CORE
- default IR_CORE
-
-if IR_CORE
+if RC_CORE
config LIRC
tristate
@@ -28,11 +24,11 @@ config LIRC
LIRC daemon handles protocol decoding for IR reception and
encoding for IR transmitting (aka "blasting").
-source "drivers/media/IR/keymaps/Kconfig"
+source "drivers/media/rc/keymaps/Kconfig"
config IR_NEC_DECODER
tristate "Enable IR raw decoder for the NEC protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -42,7 +38,7 @@ config IR_NEC_DECODER
config IR_RC5_DECODER
tristate "Enable IR raw decoder for the RC-5 protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -52,7 +48,7 @@ config IR_RC5_DECODER
config IR_RC6_DECODER
tristate "Enable IR raw decoder for the RC6 protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -62,7 +58,7 @@ config IR_RC6_DECODER
config IR_JVC_DECODER
tristate "Enable IR raw decoder for the JVC protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -72,7 +68,7 @@ config IR_JVC_DECODER
config IR_SONY_DECODER
tristate "Enable IR raw decoder for the Sony protocol"
- depends on IR_CORE
+ depends on RC_CORE
default y
---help---
@@ -81,7 +77,7 @@ config IR_SONY_DECODER
config IR_RC5_SZ_DECODER
tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
- depends on IR_CORE
+ depends on RC_CORE
select BITREVERSE
default y
@@ -93,7 +89,7 @@ config IR_RC5_SZ_DECODER
config IR_LIRC_CODEC
tristate "Enable IR to LIRC bridge"
- depends on IR_CORE
+ depends on RC_CORE
depends on LIRC
default y
@@ -104,7 +100,7 @@ config IR_LIRC_CODEC
config IR_ENE
tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)"
depends on PNP
- depends on IR_CORE
+ depends on RC_CORE
---help---
Say Y here to enable support for integrated infrared receiver
/transceiver made by ENE.
@@ -118,7 +114,7 @@ config IR_ENE
config IR_IMON
tristate "SoundGraph iMON Receiver and Display"
depends on USB_ARCH_HAS_HCD
- depends on IR_CORE
+ depends on RC_CORE
select USB
---help---
Say Y here if you want to use a SoundGraph iMON (aka Antec Veris)
@@ -130,7 +126,7 @@ config IR_IMON
config IR_MCEUSB
tristate "Windows Media Center Ed. eHome Infrared Transceiver"
depends on USB_ARCH_HAS_HCD
- depends on IR_CORE
+ depends on RC_CORE
select USB
---help---
Say Y here if you want to use a Windows Media Center Edition
@@ -142,7 +138,7 @@ config IR_MCEUSB
config IR_NUVOTON
tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
depends on PNP
- depends on IR_CORE
+ depends on RC_CORE
---help---
Say Y here to enable support for integrated infrared receiver
/transciever made by Nuvoton (formerly Winbond). This chip is
@@ -155,7 +151,7 @@ config IR_NUVOTON
config IR_STREAMZAP
tristate "Streamzap PC Remote IR Receiver"
depends on USB_ARCH_HAS_HCD
- depends on IR_CORE
+ depends on RC_CORE
select USB
---help---
Say Y here if you want to use a Streamzap PC Remote
@@ -164,4 +160,34 @@ config IR_STREAMZAP
To compile this driver as a module, choose M here: the
module will be called streamzap.
-endif #IR_CORE
+config IR_WINBOND_CIR
+ tristate "Winbond IR remote control"
+ depends on X86 && PNP
+ depends on RC_CORE
+ select NEW_LEDS
+ select LEDS_CLASS
+ select LEDS_TRIGGERS
+ select BITREVERSE
+ ---help---
+ Say Y here if you want to use the IR remote functionality found
+ in some Winbond SuperI/O chips. Currently only the WPCD376I
+ chip is supported (included in some Intel Media series
+ motherboards).
+
+ To compile this driver as a module, choose M here: the module will
+ be called winbond_cir.
+
+config RC_LOOPBACK
+ tristate "Remote Control Loopback Driver"
+ depends on RC_CORE
+ ---help---
+ Say Y here if you want support for the remote control loopback
+ driver which allows TX data to be sent back as RX data.
+ This is mostly useful for debugging purposes.
+
+ If you're not sure, select N here.
+
+ To compile this driver as a module, choose M here: the module will
+ be called rc_loopback.
+
+endif #RC_CORE
diff --git a/drivers/media/IR/Makefile b/drivers/media/rc/Makefile
index f9574adab82a..67b4f7fe2577 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,10 +1,8 @@
-ir-common-objs := ir-functions.o
-ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o rc-map.o
+rc-core-objs := rc-main.o ir-raw.o
obj-y += keymaps/
-obj-$(CONFIG_IR_CORE) += ir-core.o
-obj-$(CONFIG_VIDEO_IR) += ir-common.o
+obj-$(CONFIG_RC_CORE) += rc-core.o
obj-$(CONFIG_LIRC) += lirc_dev.o
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
@@ -20,3 +18,5 @@ obj-$(CONFIG_IR_MCEUSB) += mceusb.o
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
obj-$(CONFIG_IR_ENE) += ene_ir.o
obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
+obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
+obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/rc/ene_ir.c
index 7637babcd262..80b3c319f698 100644
--- a/drivers/media/IR/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -37,9 +37,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include "ene_ir.h"
static int sample_period;
@@ -357,7 +355,7 @@ void ene_rx_sense_carrier(struct ene_device *dev)
ev.carrier_report = true;
ev.carrier = carrier;
ev.duty_cycle = duty_cycle;
- ir_raw_event_store(dev->idev, &ev);
+ ir_raw_event_store(dev->rdev, &ev);
}
}
@@ -448,32 +446,32 @@ static void ene_rx_setup(struct ene_device *dev)
select_timeout:
if (dev->rx_fan_input_inuse) {
- dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
+ dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
/* Fan input doesn't support timeouts, it just ends the
input with a maximum sample */
- dev->props->min_timeout = dev->props->max_timeout =
+ dev->rdev->min_timeout = dev->rdev->max_timeout =
MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
ENE_FW_SAMPLE_PERIOD_FAN);
} else {
- dev->props->rx_resolution = MS_TO_NS(sample_period);
+ dev->rdev->rx_resolution = MS_TO_NS(sample_period);
/* Theoreticly timeout is unlimited, but we cap it
* because it was seen that on one device, it
* would stop sending spaces after around 250 msec.
* Besides, this is close to 2^32 anyway and timeout is u32.
*/
- dev->props->min_timeout = MS_TO_NS(127 * sample_period);
- dev->props->max_timeout = MS_TO_NS(200000);
+ dev->rdev->min_timeout = MS_TO_NS(127 * sample_period);
+ dev->rdev->max_timeout = MS_TO_NS(200000);
}
if (dev->hw_learning_and_tx_capable)
- dev->props->tx_resolution = MS_TO_NS(sample_period);
+ dev->rdev->tx_resolution = MS_TO_NS(sample_period);
- if (dev->props->timeout > dev->props->max_timeout)
- dev->props->timeout = dev->props->max_timeout;
- if (dev->props->timeout < dev->props->min_timeout)
- dev->props->timeout = dev->props->min_timeout;
+ if (dev->rdev->timeout > dev->rdev->max_timeout)
+ dev->rdev->timeout = dev->rdev->max_timeout;
+ if (dev->rdev->timeout < dev->rdev->min_timeout)
+ dev->rdev->timeout = dev->rdev->min_timeout;
}
/* Enable the device for receive */
@@ -504,7 +502,7 @@ static void ene_rx_enable(struct ene_device *dev)
ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
/* enter idle mode */
- ir_raw_event_set_idle(dev->idev, true);
+ ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = true;
}
@@ -518,7 +516,7 @@ static void ene_rx_disable(struct ene_device *dev)
/* disable hardware IRQ and firmware flag */
ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
- ir_raw_event_set_idle(dev->idev, true);
+ ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = false;
}
@@ -805,10 +803,10 @@ static irqreturn_t ene_isr(int irq, void *data)
ev.duration = MS_TO_NS(hw_sample);
ev.pulse = pulse;
- ir_raw_event_store_with_filter(dev->idev, &ev);
+ ir_raw_event_store_with_filter(dev->rdev, &ev);
}
- ir_raw_event_handle(dev->idev);
+ ir_raw_event_handle(dev->rdev);
unlock:
spin_unlock_irqrestore(&dev->hw_lock, flags);
return retval;
@@ -823,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev)
dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */
- dev->props->timeout = MS_TO_NS(150000);
+ dev->rdev->timeout = MS_TO_NS(150000);
}
/* Upload all hardware settings at once. Used at load and resume time */
@@ -838,9 +836,9 @@ static void ene_setup_hw_settings(struct ene_device *dev)
}
/* outside interface: called on first open*/
-static int ene_open(void *data)
+static int ene_open(struct rc_dev *rdev)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
@@ -850,9 +848,9 @@ static int ene_open(void *data)
}
/* outside interface: called on device close*/
-static void ene_close(void *data)
+static void ene_close(struct rc_dev *rdev)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
@@ -861,9 +859,9 @@ static void ene_close(void *data)
}
/* outside interface: set transmitter mask */
-static int ene_set_tx_mask(void *data, u32 tx_mask)
+static int ene_set_tx_mask(struct rc_dev *rdev, u32 tx_mask)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
dbg("TX: attempt to set transmitter mask %02x", tx_mask);
/* invalid txmask */
@@ -879,9 +877,9 @@ static int ene_set_tx_mask(void *data, u32 tx_mask)
}
/* outside interface : set tx carrier */
-static int ene_set_tx_carrier(void *data, u32 carrier)
+static int ene_set_tx_carrier(struct rc_dev *rdev, u32 carrier)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
u32 period = 2000000 / carrier;
dbg("TX: attempt to set tx carrier to %d kHz", carrier);
@@ -900,9 +898,9 @@ static int ene_set_tx_carrier(void *data, u32 carrier)
}
/*outside interface : set tx duty cycle */
-static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
+static int ene_set_tx_duty_cycle(struct rc_dev *rdev, u32 duty_cycle)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
dbg("TX: setting duty cycle to %d%%", duty_cycle);
dev->tx_duty_cycle = duty_cycle;
ene_tx_set_carrier(dev);
@@ -910,9 +908,9 @@ static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
}
/* outside interface: enable learning mode */
-static int ene_set_learning_mode(void *data, int enable)
+static int ene_set_learning_mode(struct rc_dev *rdev, int enable)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
if (enable == dev->learning_mode_enabled)
return 0;
@@ -926,9 +924,9 @@ static int ene_set_learning_mode(void *data, int enable)
return 0;
}
-static int ene_set_carrier_report(void *data, int enable)
+static int ene_set_carrier_report(struct rc_dev *rdev, int enable)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
if (enable == dev->carrier_detect_enabled)
@@ -944,18 +942,20 @@ static int ene_set_carrier_report(void *data, int enable)
}
/* outside interface: enable or disable idle mode */
-static void ene_set_idle(void *data, bool idle)
+static void ene_set_idle(struct rc_dev *rdev, bool idle)
{
+ struct ene_device *dev = rdev->priv;
+
if (idle) {
- ene_rx_reset((struct ene_device *)data);
+ ene_rx_reset(dev);
dbg("RX: end of data");
}
}
/* outside interface: transmit */
-static int ene_transmit(void *data, int *buf, u32 n)
+static int ene_transmit(struct rc_dev *rdev, int *buf, u32 n)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
dev->tx_buffer = buf;
@@ -992,16 +992,13 @@ static int ene_transmit(void *data, int *buf, u32 n)
static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
{
int error = -ENOMEM;
- struct ir_dev_props *ir_props;
- struct input_dev *input_dev;
+ struct rc_dev *rdev;
struct ene_device *dev;
/* allocate memory */
- input_dev = input_allocate_device();
- ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
-
- if (!input_dev || !ir_props || !dev)
+ rdev = rc_allocate_device();
+ if (!dev || !rdev)
goto error1;
/* validate resources */
@@ -1054,24 +1051,25 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
if (!dev->hw_learning_and_tx_capable)
learning_mode_force = false;
- ir_props->driver_type = RC_DRIVER_IR_RAW;
- ir_props->allowed_protos = IR_TYPE_ALL;
- ir_props->priv = dev;
- ir_props->open = ene_open;
- ir_props->close = ene_close;
- ir_props->s_idle = ene_set_idle;
-
- dev->props = ir_props;
- dev->idev = input_dev;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = RC_TYPE_ALL;
+ rdev->priv = dev;
+ rdev->open = ene_open;
+ rdev->close = ene_close;
+ rdev->s_idle = ene_set_idle;
+ rdev->driver_name = ENE_DRIVER_NAME;
+ rdev->map_name = RC_MAP_RC6_MCE;
+ rdev->input_name = "ENE eHome Infrared Remote Receiver";
if (dev->hw_learning_and_tx_capable) {
- ir_props->s_learning_mode = ene_set_learning_mode;
+ rdev->s_learning_mode = ene_set_learning_mode;
init_completion(&dev->tx_complete);
- ir_props->tx_ir = ene_transmit;
- ir_props->s_tx_mask = ene_set_tx_mask;
- ir_props->s_tx_carrier = ene_set_tx_carrier;
- ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
- ir_props->s_carrier_report = ene_set_carrier_report;
+ rdev->tx_ir = ene_transmit;
+ rdev->s_tx_mask = ene_set_tx_mask;
+ rdev->s_tx_carrier = ene_set_tx_carrier;
+ rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle;
+ rdev->s_carrier_report = ene_set_carrier_report;
+ rdev->input_name = "ENE eHome Infrared Remote Transceiver";
}
ene_rx_setup_hw_buffer(dev);
@@ -1081,16 +1079,11 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
device_set_wakeup_capable(&pnp_dev->dev, true);
device_set_wakeup_enable(&pnp_dev->dev, true);
- if (dev->hw_learning_and_tx_capable)
- input_dev->name = "ENE eHome Infrared Remote Transceiver";
- else
- input_dev->name = "ENE eHome Infrared Remote Receiver";
-
- error = -ENODEV;
- if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
- ENE_DRIVER_NAME))
+ error = rc_register_device(rdev);
+ if (error < 0)
goto error;
+ dev->rdev = rdev;
ene_notice("driver has been succesfully loaded");
return 0;
error:
@@ -1099,8 +1092,7 @@ error:
if (dev && dev->hw_io >= 0)
release_region(dev->hw_io, ENE_IO_SIZE);
error1:
- input_free_device(input_dev);
- kfree(ir_props);
+ rc_free_device(rdev);
kfree(dev);
return error;
}
@@ -1118,8 +1110,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
free_irq(dev->irq, dev);
release_region(dev->hw_io, ENE_IO_SIZE);
- ir_input_unregister(dev->idev);
- kfree(dev->props);
+ rc_unregister_device(dev->rdev);
kfree(dev);
}
diff --git a/drivers/media/IR/ene_ir.h b/drivers/media/rc/ene_ir.h
index f5870667a433..c179baf34cb4 100644
--- a/drivers/media/IR/ene_ir.h
+++ b/drivers/media/rc/ene_ir.h
@@ -205,8 +205,7 @@
struct ene_device {
struct pnp_dev *pnp_dev;
- struct input_dev *idev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
/* hw IO settings */
long hw_io;
diff --git a/drivers/media/IR/imon.c b/drivers/media/rc/imon.c
index bc118066bc38..6811512b4e83 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/rc/imon.c
@@ -38,7 +38,7 @@
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <linux/time.h>
#include <linux/timer.h>
@@ -88,7 +88,6 @@ static ssize_t lcd_write(struct file *file, const char *buf,
struct imon_context {
struct device *dev;
- struct ir_dev_props *props;
/* Newer devices have two interfaces */
struct usb_device *usbdev_intf0;
struct usb_device *usbdev_intf1;
@@ -123,7 +122,7 @@ struct imon_context {
u16 vendor; /* usb vendor ID */
u16 product; /* usb product ID */
- struct input_dev *rdev; /* input device for remote */
+ struct rc_dev *rdev; /* rc-core device for remote */
struct input_dev *idev; /* input device for panel & IR mouse */
struct input_dev *touch; /* input device for touchscreen */
@@ -132,7 +131,7 @@ struct imon_context {
u32 last_keycode; /* last reported input keycode */
u32 rc_scancode; /* the computed remote scancode */
u8 rc_toggle; /* the computed remote toggle bit */
- u64 ir_type; /* iMON or MCE (RC6) IR protocol? */
+ u64 rc_type; /* iMON or MCE (RC6) IR protocol? */
bool release_code; /* some keys send a release code */
u8 display_type; /* store the display type */
@@ -984,27 +983,27 @@ static void imon_touch_display_timeout(unsigned long data)
* really just RC-6), but only one or the other at a time, as the signals
* are decoded onboard the receiver.
*/
-int imon_ir_change_protocol(void *priv, u64 ir_type)
+static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
{
int retval;
- struct imon_context *ictx = priv;
+ struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev;
bool pad_mouse;
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
- if (ir_type && !(ir_type & ictx->props->allowed_protos))
+ if (rc_type && !(rc_type & rc->allowed_protos))
dev_warn(dev, "Looks like you're trying to use an IR protocol "
"this device does not support\n");
- switch (ir_type) {
- case IR_TYPE_RC6:
+ switch (rc_type) {
+ case RC_TYPE_RC6:
dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
ir_proto_packet[0] = 0x01;
pad_mouse = false;
break;
- case IR_TYPE_UNKNOWN:
- case IR_TYPE_OTHER:
+ case RC_TYPE_UNKNOWN:
+ case RC_TYPE_OTHER:
dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
if (pad_stabilize && !nomouse)
pad_mouse = true;
@@ -1013,7 +1012,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
pad_mouse = false;
}
/* ir_proto_packet[0] = 0x00; // already the default */
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
break;
default:
dev_warn(dev, "Unsupported IR protocol specified, overriding "
@@ -1025,7 +1024,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
pad_mouse = false;
}
/* ir_proto_packet[0] = 0x00; // already the default */
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
break;
}
@@ -1035,7 +1034,7 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
if (retval)
goto out;
- ictx->ir_type = ir_type;
+ ictx->rc_type = rc_type;
ictx->pad_mouse = pad_mouse;
out:
@@ -1147,14 +1146,14 @@ static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode)
bool is_release_code = false;
/* Look for the initial press of a button */
- keycode = ir_g_keycode_from_table(ictx->rdev, scancode);
+ keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
ictx->rc_toggle = 0x0;
ictx->rc_scancode = scancode;
/* Look for the release of a button */
if (keycode == KEY_RESERVED) {
release = scancode & ~0x4000;
- keycode = ir_g_keycode_from_table(ictx->rdev, release);
+ keycode = rc_g_keycode_from_table(ictx->rdev, release);
if (keycode != KEY_RESERVED)
is_release_code = true;
}
@@ -1183,7 +1182,7 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode)
scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
ictx->rc_scancode = scancode;
- keycode = ir_g_keycode_from_table(ictx->rdev, scancode);
+ keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
/* not used in mce mode, but make sure we know its false */
ictx->release_code = false;
@@ -1307,7 +1306,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
rel_x = buf[2];
rel_y = buf[3];
- if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
+ if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
dir = stabilize((int)rel_x, (int)rel_y,
timeout, threshold);
@@ -1374,7 +1373,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
buf[0] = 0x01;
buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
- if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) {
+ if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
dir = stabilize((int)rel_x, (int)rel_y,
timeout, threshold);
if (!dir) {
@@ -1479,17 +1478,12 @@ static void imon_incoming_packet(struct imon_context *ictx,
bool norelease = false;
int i;
u64 scancode;
- struct input_dev *rdev = NULL;
- struct ir_input_dev *irdev = NULL;
int press_type = 0;
int msec;
struct timeval t;
static struct timeval prev_time = { 0, 0 };
u8 ktype;
- rdev = ictx->rdev;
- irdev = input_get_drvdata(rdev);
-
/* filter out junk data on the older 0xffdc imon devices */
if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
return;
@@ -1501,7 +1495,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
kc = imon_panel_key_lookup(scancode);
} else {
scancode = be32_to_cpu(*((u32 *)buf));
- if (ictx->ir_type == IR_TYPE_RC6) {
+ if (ictx->rc_type == RC_TYPE_RC6) {
ktype = IMON_KEY_IMON;
if (buf[0] == 0x80)
ktype = IMON_KEY_MCE;
@@ -1570,9 +1564,9 @@ static void imon_incoming_packet(struct imon_context *ictx,
if (ktype != IMON_KEY_PANEL) {
if (press_type == 0)
- ir_keyup(irdev);
+ rc_keyup(ictx->rdev);
else {
- ir_keydown(rdev, ictx->rc_scancode, ictx->rc_toggle);
+ rc_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle);
spin_lock_irqsave(&ictx->kc_lock, flags);
ictx->last_keycode = ictx->kc;
spin_unlock_irqrestore(&ictx->kc_lock, flags);
@@ -1715,7 +1709,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
{
u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
- u64 allowed_protos = IR_TYPE_OTHER;
+ u64 allowed_protos = RC_TYPE_OTHER;
switch (ffdc_cfg_byte) {
/* iMON Knob, no display, iMON IR + vol knob */
@@ -1744,13 +1738,13 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
case 0x9e:
dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
detected_display_type = IMON_DISPLAY_TYPE_VFD;
- allowed_protos = IR_TYPE_RC6;
+ allowed_protos = RC_TYPE_RC6;
break;
/* iMON LCD, MCE IR */
case 0x9f:
dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
detected_display_type = IMON_DISPLAY_TYPE_LCD;
- allowed_protos = IR_TYPE_RC6;
+ allowed_protos = RC_TYPE_RC6;
break;
default:
dev_info(ictx->dev, "Unknown 0xffdc device, "
@@ -1762,8 +1756,8 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
ictx->display_type = detected_display_type;
- ictx->props->allowed_protos = allowed_protos;
- ictx->ir_type = allowed_protos;
+ ictx->rdev->allowed_protos = allowed_protos;
+ ictx->rc_type = allowed_protos;
}
static void imon_set_display_type(struct imon_context *ictx)
@@ -1816,18 +1810,15 @@ static void imon_set_display_type(struct imon_context *ictx)
ictx->display_type = configured_display_type;
}
-static struct input_dev *imon_init_rdev(struct imon_context *ictx)
+static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
{
- struct input_dev *rdev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
int ret;
- char *ir_codes = NULL;
const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88 };
- rdev = input_allocate_device();
- props = kzalloc(sizeof(*props), GFP_KERNEL);
- if (!rdev || !props) {
+ rdev = rc_allocate_device();
+ if (!rdev) {
dev_err(ictx->dev, "remote control dev allocation failed\n");
goto out;
}
@@ -1838,18 +1829,20 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
sizeof(ictx->phys_rdev));
strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev));
- rdev->name = ictx->name_rdev;
- rdev->phys = ictx->phys_rdev;
- usb_to_input_id(ictx->usbdev_intf0, &rdev->id);
+ rdev->input_name = ictx->name_rdev;
+ rdev->input_phys = ictx->phys_rdev;
+ usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id);
rdev->dev.parent = ictx->dev;
- rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
- input_set_drvdata(rdev, ictx);
- props->priv = ictx;
- props->driver_type = RC_DRIVER_SCANCODE;
- props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */
- props->change_protocol = imon_ir_change_protocol;
- ictx->props = props;
+ rdev->priv = ictx;
+ rdev->driver_type = RC_DRIVER_SCANCODE;
+ rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
+ rdev->change_protocol = imon_ir_change_protocol;
+ rdev->driver_name = MOD_NAME;
+ if (ictx->rc_type == RC_TYPE_RC6)
+ rdev->map_name = RC_MAP_IMON_MCE;
+ else
+ rdev->map_name = RC_MAP_IMON_PAD;
/* Enable front-panel buttons and/or knobs */
memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
@@ -1863,12 +1856,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
imon_set_display_type(ictx);
- if (ictx->ir_type == IR_TYPE_RC6)
- ir_codes = RC_MAP_IMON_MCE;
- else
- ir_codes = RC_MAP_IMON_PAD;
-
- ret = ir_input_register(rdev, ir_codes, props, MOD_NAME);
+ ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(ictx->dev, "remote input dev register failed\n");
goto out;
@@ -1877,8 +1865,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
return rdev;
out:
- kfree(props);
- input_free_device(rdev);
+ rc_free_device(rdev);
return NULL;
}
@@ -2149,7 +2136,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
return ictx;
urb_submit_failed:
- ir_input_unregister(ictx->rdev);
+ rc_unregister_device(ictx->rdev);
rdev_setup_failed:
input_unregister_device(ictx->idev);
idev_setup_failed:
@@ -2287,7 +2274,7 @@ static int __devinit imon_probe(struct usb_interface *interface,
mutex_lock(&driver_lock);
first_if = usb_ifnum_to_if(usbdev, 0);
- first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if);
+ first_if_ctx = usb_get_intfdata(first_if);
if (ifnum == 0) {
ictx = imon_init_intf0(interface);
@@ -2376,7 +2363,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0);
input_unregister_device(ictx->idev);
- ir_input_unregister(ictx->rdev);
+ rc_unregister_device(ictx->rdev);
if (ictx->display_supported) {
if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
usb_deregister_dev(interface, &imon_lcd_class);
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index 63dca6e5458b..624449afaa61 100644
--- a/drivers/media/IR/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -13,7 +13,7 @@
*/
#include <linux/bitrev.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define JVC_NBITS 16 /* dev(8) + func(8) */
#define JVC_UNIT 525000 /* ns */
@@ -37,17 +37,16 @@ enum jvc_state {
/**
* ir_jvc_decode() - Decode one JVC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct jvc_dec *data = &ir_dev->raw->jvc;
+ struct jvc_dec *data = &dev->raw->jvc;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_JVC))
return 0;
if (!is_timing_event(ev)) {
@@ -140,12 +139,12 @@ again:
scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
(bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
- ir_keydown(input_dev, scancode, data->toggle);
+ rc_keydown(dev, scancode, data->toggle);
data->first = false;
data->old_bits = data->bits;
} else if (data->bits == data->old_bits) {
IR_dprintk(1, "JVC repeat\n");
- ir_repeat(input_dev);
+ rc_repeat(dev);
} else {
IR_dprintk(1, "JVC invalid repeat msg\n");
break;
@@ -174,7 +173,7 @@ out:
}
static struct ir_raw_handler jvc_handler = {
- .protocols = IR_TYPE_JVC,
+ .protocols = RC_TYPE_JVC,
.decode = ir_jvc_decode,
};
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 9fc0db9d344d..1e87ee8e5c99 100644
--- a/drivers/media/IR/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -16,29 +16,28 @@
#include <linux/wait.h>
#include <media/lirc.h>
#include <media/lirc_dev.h>
-#include <media/ir-core.h>
-#include "ir-core-priv.h"
+#include <media/rc-core.h>
+#include "rc-core-priv.h"
#define LIRCBUF_SIZE 256
/**
* ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
* lircd userspace daemon for decoding.
- * @input_dev: the struct input_dev descriptor of the device
+ * @input_dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the lirc interfaces aren't wired up.
*/
-static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct lirc_codec *lirc = &ir_dev->raw->lirc;
+ struct lirc_codec *lirc = &dev->raw->lirc;
int sample;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_LIRC))
return 0;
- if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
+ if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
return -EINVAL;
/* Packet start */
@@ -79,7 +78,7 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
(u64)LIRC_VALUE_MASK);
gap_sample = LIRC_SPACE(lirc->gap_duration);
- lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.drv->rbuf,
(unsigned char *) &gap_sample);
lirc->gap = false;
}
@@ -88,9 +87,9 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
LIRC_SPACE(ev.duration / 1000);
}
- lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.drv->rbuf,
(unsigned char *) &sample);
- wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
+ wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
return 0;
}
@@ -99,7 +98,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
size_t n, loff_t *ppos)
{
struct lirc_codec *lirc;
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
int *txbuf; /* buffer with values to transmit */
int ret = 0, count;
@@ -118,14 +117,14 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
if (IS_ERR(txbuf))
return PTR_ERR(txbuf);
- ir_dev = lirc->ir_dev;
- if (!ir_dev) {
+ dev = lirc->dev;
+ if (!dev) {
ret = -EFAULT;
goto out;
}
- if (ir_dev->props && ir_dev->props->tx_ir)
- ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n);
+ if (dev->tx_ir)
+ ret = dev->tx_ir(dev, txbuf, (u32)n);
out:
kfree(txbuf);
@@ -136,21 +135,18 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
unsigned long __user arg)
{
struct lirc_codec *lirc;
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
int ret = 0;
- void *drv_data;
__u32 val = 0, tmp;
lirc = lirc_get_pdata(filep);
if (!lirc)
return -EFAULT;
- ir_dev = lirc->ir_dev;
- if (!ir_dev || !ir_dev->props || !ir_dev->props->priv)
+ dev = lirc->dev;
+ if (!dev)
return -EFAULT;
- drv_data = ir_dev->props->priv;
-
if (_IOC_DIR(cmd) & _IOC_WRITE) {
ret = get_user(val, (__u32 *)arg);
if (ret)
@@ -171,84 +167,85 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
- if (!ir_dev->props->s_tx_mask)
+ if (!dev->s_tx_mask)
return -EINVAL;
- return ir_dev->props->s_tx_mask(drv_data, val);
+ return dev->s_tx_mask(dev, val);
case LIRC_SET_SEND_CARRIER:
- if (!ir_dev->props->s_tx_carrier)
+ if (!dev->s_tx_carrier)
return -EINVAL;
- return ir_dev->props->s_tx_carrier(drv_data, val);
+ return dev->s_tx_carrier(dev, val);
case LIRC_SET_SEND_DUTY_CYCLE:
- if (!ir_dev->props->s_tx_duty_cycle)
+ if (!dev->s_tx_duty_cycle)
return -ENOSYS;
if (val <= 0 || val >= 100)
return -EINVAL;
- return ir_dev->props->s_tx_duty_cycle(drv_data, val);
+ return dev->s_tx_duty_cycle(dev, val);
/* RX settings */
case LIRC_SET_REC_CARRIER:
- if (!ir_dev->props->s_rx_carrier_range)
+ if (!dev->s_rx_carrier_range)
return -ENOSYS;
if (val <= 0)
return -EINVAL;
- return ir_dev->props->s_rx_carrier_range(drv_data,
- ir_dev->raw->lirc.carrier_low, val);
+ return dev->s_rx_carrier_range(dev,
+ dev->raw->lirc.carrier_low,
+ val);
case LIRC_SET_REC_CARRIER_RANGE:
if (val <= 0)
return -EINVAL;
- ir_dev->raw->lirc.carrier_low = val;
+ dev->raw->lirc.carrier_low = val;
return 0;
case LIRC_GET_REC_RESOLUTION:
- val = ir_dev->props->rx_resolution;
+ val = dev->rx_resolution;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
- if (!ir_dev->props->s_learning_mode)
+ if (!dev->s_learning_mode)
return -ENOSYS;
- return ir_dev->props->s_learning_mode(drv_data, !!val);
+ return dev->s_learning_mode(dev, !!val);
case LIRC_SET_MEASURE_CARRIER_MODE:
- if (!ir_dev->props->s_carrier_report)
+ if (!dev->s_carrier_report)
return -ENOSYS;
- return ir_dev->props->s_carrier_report(drv_data, !!val);
+ return dev->s_carrier_report(dev, !!val);
/* Generic timeout support */
case LIRC_GET_MIN_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
- val = ir_dev->props->min_timeout / 1000;
+ val = dev->min_timeout / 1000;
break;
case LIRC_GET_MAX_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
- val = ir_dev->props->max_timeout / 1000;
+ val = dev->max_timeout / 1000;
break;
case LIRC_SET_REC_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
tmp = val * 1000;
- if (tmp < ir_dev->props->min_timeout ||
- tmp > ir_dev->props->max_timeout)
+ if (tmp < dev->min_timeout ||
+ tmp > dev->max_timeout)
return -EINVAL;
- ir_dev->props->timeout = tmp;
+ dev->timeout = tmp;
break;
case LIRC_SET_REC_TIMEOUT_REPORTS:
@@ -289,9 +286,8 @@ static struct file_operations lirc_fops = {
.llseek = no_llseek,
};
-static int ir_lirc_register(struct input_dev *input_dev)
+static int ir_lirc_register(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct lirc_driver *drv;
struct lirc_buffer *rbuf;
int rc = -ENOMEM;
@@ -310,44 +306,40 @@ static int ir_lirc_register(struct input_dev *input_dev)
goto rbuf_init_failed;
features = LIRC_CAN_REC_MODE2;
- if (ir_dev->props->tx_ir) {
-
+ if (dev->tx_ir) {
features |= LIRC_CAN_SEND_PULSE;
- if (ir_dev->props->s_tx_mask)
+ if (dev->s_tx_mask)
features |= LIRC_CAN_SET_TRANSMITTER_MASK;
- if (ir_dev->props->s_tx_carrier)
+ if (dev->s_tx_carrier)
features |= LIRC_CAN_SET_SEND_CARRIER;
-
- if (ir_dev->props->s_tx_duty_cycle)
+ if (dev->s_tx_duty_cycle)
features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
}
- if (ir_dev->props->s_rx_carrier_range)
+ if (dev->s_rx_carrier_range)
features |= LIRC_CAN_SET_REC_CARRIER |
LIRC_CAN_SET_REC_CARRIER_RANGE;
- if (ir_dev->props->s_learning_mode)
+ if (dev->s_learning_mode)
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
- if (ir_dev->props->s_carrier_report)
+ if (dev->s_carrier_report)
features |= LIRC_CAN_MEASURE_CARRIER;
-
- if (ir_dev->props->max_timeout)
+ if (dev->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT;
-
snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
- ir_dev->driver_name);
+ dev->driver_name);
drv->minor = -1;
drv->features = features;
- drv->data = &ir_dev->raw->lirc;
+ drv->data = &dev->raw->lirc;
drv->rbuf = rbuf;
drv->set_use_inc = &ir_lirc_open;
drv->set_use_dec = &ir_lirc_close;
drv->code_length = sizeof(struct ir_raw_event) * 8;
drv->fops = &lirc_fops;
- drv->dev = &ir_dev->dev;
+ drv->dev = &dev->dev;
drv->owner = THIS_MODULE;
drv->minor = lirc_register_driver(drv);
@@ -356,8 +348,8 @@ static int ir_lirc_register(struct input_dev *input_dev)
goto lirc_register_failed;
}
- ir_dev->raw->lirc.drv = drv;
- ir_dev->raw->lirc.ir_dev = ir_dev;
+ dev->raw->lirc.drv = drv;
+ dev->raw->lirc.dev = dev;
return 0;
lirc_register_failed:
@@ -369,10 +361,9 @@ rbuf_alloc_failed:
return rc;
}
-static int ir_lirc_unregister(struct input_dev *input_dev)
+static int ir_lirc_unregister(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct lirc_codec *lirc = &ir_dev->raw->lirc;
+ struct lirc_codec *lirc = &dev->raw->lirc;
lirc_unregister_driver(lirc->drv->minor);
lirc_buffer_free(lirc->drv->rbuf);
@@ -382,7 +373,7 @@ static int ir_lirc_unregister(struct input_dev *input_dev)
}
static struct ir_raw_handler lirc_handler = {
- .protocols = IR_TYPE_LIRC,
+ .protocols = RC_TYPE_LIRC,
.decode = ir_lirc_decode,
.raw_register = ir_lirc_register,
.raw_unregister = ir_lirc_unregister,
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 70993f79c8a2..5d15c31288b9 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -13,7 +13,7 @@
*/
#include <linux/bitrev.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define NEC_NBITS 32
#define NEC_UNIT 562500 /* ns */
@@ -39,19 +39,18 @@ enum nec_state {
/**
* ir_nec_decode() - Decode one NEC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct nec_dec *data = &ir_dev->raw->nec;
+ struct nec_dec *data = &dev->raw->nec;
u32 scancode;
u8 address, not_address, command, not_command;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
return 0;
if (!is_timing_event(ev)) {
@@ -89,7 +88,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
data->state = STATE_BIT_PULSE;
return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
- ir_repeat(input_dev);
+ rc_repeat(dev);
IR_dprintk(1, "Repeat last key\n");
data->state = STATE_TRAILER_PULSE;
return 0;
@@ -115,7 +114,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
geq_margin(ev.duration,
NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
IR_dprintk(1, "Repeat last key\n");
- ir_repeat(input_dev);
+ rc_repeat(dev);
data->state = STATE_INACTIVE;
return 0;
@@ -179,7 +178,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (data->is_nec_x)
data->necx_repeat = true;
- ir_keydown(input_dev, scancode, 0);
+ rc_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
@@ -191,7 +190,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
}
static struct ir_raw_handler nec_handler = {
- .protocols = IR_TYPE_NEC,
+ .protocols = RC_TYPE_NEC,
.decode = ir_nec_decode,
};
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/rc/ir-raw.c
index a06a07e4e0b1..185baddcbf14 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/rc/ir-raw.c
@@ -1,4 +1,4 @@
-/* ir-raw-event.c - handle IR Pulse/Space event
+/* ir-raw.c - handle IR pulse/space events
*
* Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
@@ -16,7 +16,7 @@
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/freezer.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
/* Define the max number of pulse/space transitions to buffer */
#define MAX_IR_EVENT_SIZE 512
@@ -64,7 +64,7 @@ static int ir_raw_event_thread(void *data)
mutex_lock(&ir_raw_handler_lock);
list_for_each_entry(handler, &ir_raw_handler_list, list)
- handler->decode(raw->input_dev, ev);
+ handler->decode(raw->dev, ev);
raw->prev_ev = ev;
mutex_unlock(&ir_raw_handler_lock);
}
@@ -74,7 +74,7 @@ static int ir_raw_event_thread(void *data)
/**
* ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This routine (which may be called from an interrupt context) stores a
@@ -82,17 +82,15 @@ static int ir_raw_event_thread(void *data)
* signalled as positive values and spaces as negative values. A zero value
* will reset the decoding state machines.
*/
-int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
-
- if (!ir->raw)
+ if (!dev->raw)
return -EINVAL;
IR_dprintk(2, "sample: (%05dus %s)\n",
- TO_US(ev->duration), TO_STR(ev->pulse));
+ TO_US(ev->duration), TO_STR(ev->pulse));
- if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
+ if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
return -ENOMEM;
return 0;
@@ -101,7 +99,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
/**
* ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @type: the type of the event that has occurred
*
* This routine (which may be called from an interrupt context) is used to
@@ -110,50 +108,49 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
* hardware which does not provide durations directly but only interrupts
* (or similar events) on state change.
*/
-int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
+int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
ktime_t now;
s64 delta; /* ns */
struct ir_raw_event ev;
int rc = 0;
- if (!ir->raw)
+ if (!dev->raw)
return -EINVAL;
now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
+ delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
/* Check for a long duration since last event or if we're
* being called for the first time, note that delta can't
* possibly be negative.
*/
ev.duration = 0;
- if (delta > IR_MAX_DURATION || !ir->raw->last_type)
+ if (delta > IR_MAX_DURATION || !dev->raw->last_type)
type |= IR_START_EVENT;
else
ev.duration = delta;
if (type & IR_START_EVENT)
- ir_raw_event_reset(input_dev);
- else if (ir->raw->last_type & IR_SPACE) {
+ ir_raw_event_reset(dev);
+ else if (dev->raw->last_type & IR_SPACE) {
ev.pulse = false;
- rc = ir_raw_event_store(input_dev, &ev);
- } else if (ir->raw->last_type & IR_PULSE) {
+ rc = ir_raw_event_store(dev, &ev);
+ } else if (dev->raw->last_type & IR_PULSE) {
ev.pulse = true;
- rc = ir_raw_event_store(input_dev, &ev);
+ rc = ir_raw_event_store(dev, &ev);
} else
return 0;
- ir->raw->last_event = now;
- ir->raw->last_type = type;
+ dev->raw->last_event = now;
+ dev->raw->last_type = type;
return rc;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
/**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @type: the type of the event that has occurred
*
* This routine (which may be called from an interrupt context) works
@@ -161,84 +158,76 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
* This routine is intended for devices with limited internal buffer
* It automerges samples of same type, and handles timeouts
*/
-int ir_raw_event_store_with_filter(struct input_dev *input_dev,
- struct ir_raw_event *ev)
+int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- struct ir_raw_event_ctrl *raw = ir->raw;
-
- if (!raw || !ir->props)
+ if (!dev->raw)
return -EINVAL;
/* Ignore spaces in idle mode */
- if (ir->idle && !ev->pulse)
+ if (dev->idle && !ev->pulse)
return 0;
- else if (ir->idle)
- ir_raw_event_set_idle(input_dev, false);
-
- if (!raw->this_ev.duration) {
- raw->this_ev = *ev;
- } else if (ev->pulse == raw->this_ev.pulse) {
- raw->this_ev.duration += ev->duration;
- } else {
- ir_raw_event_store(input_dev, &raw->this_ev);
- raw->this_ev = *ev;
+ else if (dev->idle)
+ ir_raw_event_set_idle(dev, false);
+
+ if (!dev->raw->this_ev.duration)
+ dev->raw->this_ev = *ev;
+ else if (ev->pulse == dev->raw->this_ev.pulse)
+ dev->raw->this_ev.duration += ev->duration;
+ else {
+ ir_raw_event_store(dev, &dev->raw->this_ev);
+ dev->raw->this_ev = *ev;
}
/* Enter idle mode if nessesary */
- if (!ev->pulse && ir->props->timeout &&
- raw->this_ev.duration >= ir->props->timeout) {
- ir_raw_event_set_idle(input_dev, true);
- }
+ if (!ev->pulse && dev->timeout &&
+ dev->raw->this_ev.duration >= dev->timeout)
+ ir_raw_event_set_idle(dev, true);
+
return 0;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
/**
- * ir_raw_event_set_idle() - hint the ir core if device is receiving
- * IR data or not
- * @input_dev: the struct input_dev device descriptor
- * @idle: the hint value
+ * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not
+ * @dev: the struct rc_dev device descriptor
+ * @idle: whether the device is idle or not
*/
-void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle)
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- struct ir_raw_event_ctrl *raw = ir->raw;
-
- if (!ir->props || !ir->raw)
+ if (!dev->raw)
return;
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
if (idle) {
- raw->this_ev.timeout = true;
- ir_raw_event_store(input_dev, &raw->this_ev);
- init_ir_raw_event(&raw->this_ev);
+ dev->raw->this_ev.timeout = true;
+ ir_raw_event_store(dev, &dev->raw->this_ev);
+ init_ir_raw_event(&dev->raw->this_ev);
}
- if (ir->props->s_idle)
- ir->props->s_idle(ir->props->priv, idle);
- ir->idle = idle;
+ if (dev->s_idle)
+ dev->s_idle(dev, idle);
+
+ dev->idle = idle;
}
EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
/**
* ir_raw_event_handle() - schedules the decoding of stored ir data
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
*
- * This routine will signal the workqueue to start decoding stored ir data.
+ * This routine will tell rc-core to start decoding stored ir data.
*/
-void ir_raw_event_handle(struct input_dev *input_dev)
+void ir_raw_event_handle(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
unsigned long flags;
- if (!ir->raw)
+ if (!dev->raw)
return;
- spin_lock_irqsave(&ir->raw->lock, flags);
- wake_up_process(ir->raw->thread);
- spin_unlock_irqrestore(&ir->raw->lock, flags);
+ spin_lock_irqsave(&dev->raw->lock, flags);
+ wake_up_process(dev->raw->thread);
+ spin_unlock_irqrestore(&dev->raw->lock, flags);
}
EXPORT_SYMBOL_GPL(ir_raw_event_handle);
@@ -256,69 +245,69 @@ ir_raw_get_allowed_protocols()
/*
* Used to (un)register raw event clients
*/
-int ir_raw_event_register(struct input_dev *input_dev)
+int ir_raw_event_register(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
int rc;
struct ir_raw_handler *handler;
- ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
- if (!ir->raw)
- return -ENOMEM;
+ if (!dev)
+ return -EINVAL;
- ir->raw->input_dev = input_dev;
+ dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
+ if (!dev->raw)
+ return -ENOMEM;
- ir->raw->enabled_protocols = ~0;
- rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
+ dev->raw->dev = dev;
+ dev->raw->enabled_protocols = ~0;
+ rc = kfifo_alloc(&dev->raw->kfifo,
+ sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
GFP_KERNEL);
- if (rc < 0) {
- kfree(ir->raw);
- ir->raw = NULL;
- return rc;
- }
+ if (rc < 0)
+ goto out;
- spin_lock_init(&ir->raw->lock);
- ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
- "rc%u", (unsigned int)ir->devno);
+ spin_lock_init(&dev->raw->lock);
+ dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
+ "rc%ld", dev->devno);
- if (IS_ERR(ir->raw->thread)) {
- int ret = PTR_ERR(ir->raw->thread);
-
- kfree(ir->raw);
- ir->raw = NULL;
- return ret;
+ if (IS_ERR(dev->raw->thread)) {
+ rc = PTR_ERR(dev->raw->thread);
+ goto out;
}
mutex_lock(&ir_raw_handler_lock);
- list_add_tail(&ir->raw->list, &ir_raw_client_list);
+ list_add_tail(&dev->raw->list, &ir_raw_client_list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_register)
- handler->raw_register(ir->raw->input_dev);
+ handler->raw_register(dev);
mutex_unlock(&ir_raw_handler_lock);
return 0;
+
+out:
+ kfree(dev->raw);
+ dev->raw = NULL;
+ return rc;
}
-void ir_raw_event_unregister(struct input_dev *input_dev)
+void ir_raw_event_unregister(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
struct ir_raw_handler *handler;
- if (!ir->raw)
+ if (!dev || !dev->raw)
return;
- kthread_stop(ir->raw->thread);
+ kthread_stop(dev->raw->thread);
mutex_lock(&ir_raw_handler_lock);
- list_del(&ir->raw->list);
+ list_del(&dev->raw->list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_unregister)
- handler->raw_unregister(ir->raw->input_dev);
+ handler->raw_unregister(dev);
mutex_unlock(&ir_raw_handler_lock);
- kfifo_free(&ir->raw->kfifo);
- kfree(ir->raw);
- ir->raw = NULL;
+ kfifo_free(&dev->raw->kfifo);
+ kfree(dev->raw);
+ dev->raw = NULL;
}
/*
@@ -333,7 +322,7 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
if (ir_raw_handler->raw_register)
list_for_each_entry(raw, &ir_raw_client_list, list)
- ir_raw_handler->raw_register(raw->input_dev);
+ ir_raw_handler->raw_register(raw->dev);
available_protocols |= ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock);
@@ -349,7 +338,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
list_del(&ir_raw_handler->list);
if (ir_raw_handler->raw_unregister)
list_for_each_entry(raw, &ir_raw_client_list, list)
- ir_raw_handler->raw_unregister(raw->input_dev);
+ ir_raw_handler->raw_unregister(raw->dev);
available_protocols &= ~ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock);
}
@@ -368,7 +357,7 @@ static void init_decoders(struct work_struct *work)
load_lirc_codec();
/* If needed, we may later add some init code. In this case,
- it is needed to change the CONFIG_MODULE test at ir-core.h
+ it is needed to change the CONFIG_MODULE test at rc-core.h
*/
}
#endif
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c
index 572ed4ca8c68..ebdba5539916 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -20,7 +20,7 @@
* the first two bits are start bits, and a third one is a filing bit
*/
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define RC5_NBITS 14
#define RC5X_NBITS 20
@@ -40,19 +40,18 @@ enum rc5_state {
/**
* ir_rc5_decode() - Decode one RC-5 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc5_dec *data = &ir_dev->raw->rc5;
+ struct rc5_dec *data = &dev->raw->rc5;
u8 toggle;
u32 scancode;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_RC5))
return 0;
if (!is_timing_event(ev)) {
@@ -96,7 +95,7 @@ again:
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -151,7 +150,7 @@ again:
scancode, toggle);
}
- ir_keydown(input_dev, scancode, toggle);
+ rc_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
@@ -164,7 +163,7 @@ out:
}
static struct ir_raw_handler rc5_handler = {
- .protocols = IR_TYPE_RC5,
+ .protocols = RC_TYPE_RC5,
.decode = ir_rc5_decode,
};
diff --git a/drivers/media/IR/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c
index 7c413501a3f7..90aa8868629a 100644
--- a/drivers/media/IR/ir-rc5-sz-decoder.c
+++ b/drivers/media/rc/ir-rc5-sz-decoder.c
@@ -20,7 +20,7 @@
* the first two bits are start bits, and a third one is a filing bit
*/
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define RC5_SZ_NBITS 15
#define RC5_UNIT 888888 /* ns */
@@ -36,19 +36,18 @@ enum rc5_sz_state {
/**
* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
+ struct rc5_sz_dec *data = &dev->raw->rc5_sz;
u8 toggle, command, system;
u32 scancode;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ))
return 0;
if (!is_timing_event(ev)) {
@@ -91,7 +90,7 @@ again:
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -115,7 +114,7 @@ again:
IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
scancode, toggle);
- ir_keydown(input_dev, scancode, toggle);
+ rc_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
@@ -128,7 +127,7 @@ out:
}
static struct ir_raw_handler rc5_sz_handler = {
- .protocols = IR_TYPE_RC5_SZ,
+ .protocols = RC_TYPE_RC5_SZ,
.decode = ir_rc5_sz_decode,
};
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index d25da91f44ff..755dafa3871b 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -12,7 +12,7 @@
* GNU General Public License for more details.
*/
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
/*
* This decoder currently supports:
@@ -70,19 +70,18 @@ static enum rc6_mode rc6_mode(struct rc6_dec *data)
/**
* ir_rc6_decode() - Decode one RC6 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc6_dec *data = &ir_dev->raw->rc6;
+ struct rc6_dec *data = &dev->raw->rc6;
u32 scancode;
u8 toggle;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_RC6))
return 0;
if (!is_timing_event(ev)) {
@@ -139,7 +138,7 @@ again:
return 0;
case STATE_HEADER_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == RC6_HEADER_NBITS)
@@ -159,7 +158,7 @@ again:
return 0;
case STATE_TOGGLE_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
+ if (!is_transition(&ev, &dev->raw->prev_ev) ||
!geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break;
@@ -204,7 +203,7 @@ again:
return 0;
case STATE_BODY_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -243,7 +242,7 @@ again:
goto out;
}
- ir_keydown(input_dev, scancode, toggle);
+ rc_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
@@ -256,7 +255,7 @@ out:
}
static struct ir_raw_handler rc6_handler = {
- .protocols = IR_TYPE_RC6,
+ .protocols = RC_TYPE_RC6,
.decode = ir_rc6_decode,
};
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index 2d15730822bc..a92de80c48db 100644
--- a/drivers/media/IR/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -13,7 +13,7 @@
*/
#include <linux/bitrev.h>
-#include "ir-core-priv.h"
+#include "rc-core-priv.h"
#define SONY_UNIT 600000 /* ns */
#define SONY_HEADER_PULSE (4 * SONY_UNIT)
@@ -33,19 +33,18 @@ enum sony_state {
/**
* ir_sony_decode() - Decode one Sony pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct sony_dec *data = &ir_dev->raw->sony;
+ struct sony_dec *data = &dev->raw->sony;
u32 scancode;
u8 device, subdevice, function;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
+ if (!(dev->raw->enabled_protocols & RC_TYPE_SONY))
return 0;
if (!is_timing_event(ev)) {
@@ -144,7 +143,7 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
scancode = device << 16 | subdevice << 8 | function;
IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
- ir_keydown(input_dev, scancode, 0);
+ rc_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
@@ -157,7 +156,7 @@ out:
}
static struct ir_raw_handler sony_handler = {
- .protocols = IR_TYPE_SONY,
+ .protocols = RC_TYPE_SONY,
.decode = ir_sony_decode,
};
diff --git a/drivers/media/IR/keymaps/Kconfig b/drivers/media/rc/keymaps/Kconfig
index 14b22f58f823..8e615fd55852 100644
--- a/drivers/media/IR/keymaps/Kconfig
+++ b/drivers/media/rc/keymaps/Kconfig
@@ -1,6 +1,6 @@
config RC_MAP
tristate "Compile Remote Controller keymap modules"
- depends on IR_CORE
+ depends on RC_CORE
default y
---help---
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 3194d391bbd4..e894b43e9407 100644
--- a/drivers/media/IR/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-real-audio-220-32-keys.o \
rc-streamzap.o \
rc-tbs-nec.o \
+ rc-technisat-usb2.o \
rc-terratec-cinergy-xs.o \
rc-terratec-slim.o \
rc-tevii-nec.o \
diff --git a/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
index b17283176ecd..136d3952dedc 100644
--- a/drivers/media/IR/keymaps/rc-adstech-dvb-t-pci.c
+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
@@ -14,7 +14,7 @@
/* ADS Tech Instant TV DVB-T PCI Remote */
-static struct ir_scancode adstech_dvb_t_pci[] = {
+static struct rc_map_table adstech_dvb_t_pci[] = {
/* Keys 0 to 9 */
{ 0x4d, KEY_0 },
{ 0x57, KEY_1 },
@@ -63,23 +63,23 @@ static struct ir_scancode adstech_dvb_t_pci[] = {
{ 0x1c, KEY_VOLUMEDOWN },
};
-static struct rc_keymap adstech_dvb_t_pci_map = {
+static struct rc_map_list adstech_dvb_t_pci_map = {
.map = {
.scan = adstech_dvb_t_pci,
.size = ARRAY_SIZE(adstech_dvb_t_pci),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ADSTECH_DVB_T_PCI,
}
};
static int __init init_rc_map_adstech_dvb_t_pci(void)
{
- return ir_register_map(&adstech_dvb_t_pci_map);
+ return rc_map_register(&adstech_dvb_t_pci_map);
}
static void __exit exit_rc_map_adstech_dvb_t_pci(void)
{
- ir_unregister_map(&adstech_dvb_t_pci_map);
+ rc_map_unregister(&adstech_dvb_t_pci_map);
}
module_init(init_rc_map_adstech_dvb_t_pci)
diff --git a/drivers/media/IR/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c
index ddfee7f8093d..fe652e928dc0 100644
--- a/drivers/media/IR/keymaps/rc-alink-dtu-m.c
+++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c
@@ -21,7 +21,7 @@
#include <media/rc-map.h>
/* A-Link DTU(m) slim remote, 6 rows, 3 columns. */
-static struct ir_scancode alink_dtu_m[] = {
+static struct rc_map_table alink_dtu_m[] = {
{ 0x0800, KEY_VOLUMEUP },
{ 0x0801, KEY_1 },
{ 0x0802, KEY_3 },
@@ -42,23 +42,23 @@ static struct ir_scancode alink_dtu_m[] = {
{ 0x081d, KEY_CHANNELDOWN },
};
-static struct rc_keymap alink_dtu_m_map = {
+static struct rc_map_list alink_dtu_m_map = {
.map = {
.scan = alink_dtu_m,
.size = ARRAY_SIZE(alink_dtu_m),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_ALINK_DTU_M,
}
};
static int __init init_rc_map_alink_dtu_m(void)
{
- return ir_register_map(&alink_dtu_m_map);
+ return rc_map_register(&alink_dtu_m_map);
}
static void __exit exit_rc_map_alink_dtu_m(void)
{
- ir_unregister_map(&alink_dtu_m_map);
+ rc_map_unregister(&alink_dtu_m_map);
}
module_init(init_rc_map_alink_dtu_m)
diff --git a/drivers/media/IR/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c
index 30d70498cfed..884f1b51a8ee 100644
--- a/drivers/media/IR/keymaps/rc-anysee.c
+++ b/drivers/media/rc/keymaps/rc-anysee.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode anysee[] = {
+static struct rc_map_table anysee[] = {
{ 0x0800, KEY_0 },
{ 0x0801, KEY_1 },
{ 0x0802, KEY_2 },
@@ -67,23 +67,23 @@ static struct ir_scancode anysee[] = {
{ 0x0851, KEY_PAUSE },
};
-static struct rc_keymap anysee_map = {
+static struct rc_map_list anysee_map = {
.map = {
.scan = anysee,
.size = ARRAY_SIZE(anysee),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_ANYSEE,
}
};
static int __init init_rc_map_anysee(void)
{
- return ir_register_map(&anysee_map);
+ return rc_map_register(&anysee_map);
}
static void __exit exit_rc_map_anysee(void)
{
- ir_unregister_map(&anysee_map);
+ rc_map_unregister(&anysee_map);
}
module_init(init_rc_map_anysee)
diff --git a/drivers/media/IR/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
index 0ef2b562baf0..7af188209ff9 100644
--- a/drivers/media/IR/keymaps/rc-apac-viewcomp.c
+++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
@@ -14,7 +14,7 @@
/* Attila Kondoros <attila.kondoros@chello.hu> */
-static struct ir_scancode apac_viewcomp[] = {
+static struct rc_map_table apac_viewcomp[] = {
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -54,23 +54,23 @@ static struct ir_scancode apac_viewcomp[] = {
{ 0x18, KEY_KPMINUS }, /* fine tune <<<< */
};
-static struct rc_keymap apac_viewcomp_map = {
+static struct rc_map_list apac_viewcomp_map = {
.map = {
.scan = apac_viewcomp,
.size = ARRAY_SIZE(apac_viewcomp),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_APAC_VIEWCOMP,
}
};
static int __init init_rc_map_apac_viewcomp(void)
{
- return ir_register_map(&apac_viewcomp_map);
+ return rc_map_register(&apac_viewcomp_map);
}
static void __exit exit_rc_map_apac_viewcomp(void)
{
- ir_unregister_map(&apac_viewcomp_map);
+ rc_map_unregister(&apac_viewcomp_map);
}
module_init(init_rc_map_apac_viewcomp)
diff --git a/drivers/media/IR/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c
index 2996e0a3b8d5..b2481154491b 100644
--- a/drivers/media/IR/keymaps/rc-asus-pc39.c
+++ b/drivers/media/rc/keymaps/rc-asus-pc39.c
@@ -18,7 +18,7 @@
* which has a label saying is "Model PC-39"
*/
-static struct ir_scancode asus_pc39[] = {
+static struct rc_map_table asus_pc39[] = {
/* Keys 0 to 9 */
{ 0x082a, KEY_0 },
{ 0x0816, KEY_1 },
@@ -65,23 +65,23 @@ static struct ir_scancode asus_pc39[] = {
{ 0x083e, KEY_DVD }, /* dvd */
};
-static struct rc_keymap asus_pc39_map = {
+static struct rc_map_list asus_pc39_map = {
.map = {
.scan = asus_pc39,
.size = ARRAY_SIZE(asus_pc39),
- .ir_type = IR_TYPE_RC5,
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_ASUS_PC39,
}
};
static int __init init_rc_map_asus_pc39(void)
{
- return ir_register_map(&asus_pc39_map);
+ return rc_map_register(&asus_pc39_map);
}
static void __exit exit_rc_map_asus_pc39(void)
{
- ir_unregister_map(&asus_pc39_map);
+ rc_map_unregister(&asus_pc39_map);
}
module_init(init_rc_map_asus_pc39)
diff --git a/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
index 8edfd293d010..f766b24b0158 100644
--- a/drivers/media/IR/keymaps/rc-ati-tv-wonder-hd-600.c
+++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
@@ -16,7 +16,7 @@
Devin Heitmueller <devin.heitmueller@gmail.com>
*/
-static struct ir_scancode ati_tv_wonder_hd_600[] = {
+static struct rc_map_table ati_tv_wonder_hd_600[] = {
{ 0x00, KEY_RECORD}, /* Row 1 */
{ 0x01, KEY_PLAYPAUSE},
{ 0x02, KEY_STOP},
@@ -43,23 +43,23 @@ static struct ir_scancode ati_tv_wonder_hd_600[] = {
{ 0x17, KEY_VOLUMEDOWN},
};
-static struct rc_keymap ati_tv_wonder_hd_600_map = {
+static struct rc_map_list ati_tv_wonder_hd_600_map = {
.map = {
.scan = ati_tv_wonder_hd_600,
.size = ARRAY_SIZE(ati_tv_wonder_hd_600),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ATI_TV_WONDER_HD_600,
}
};
static int __init init_rc_map_ati_tv_wonder_hd_600(void)
{
- return ir_register_map(&ati_tv_wonder_hd_600_map);
+ return rc_map_register(&ati_tv_wonder_hd_600_map);
}
static void __exit exit_rc_map_ati_tv_wonder_hd_600(void)
{
- ir_unregister_map(&ati_tv_wonder_hd_600_map);
+ rc_map_unregister(&ati_tv_wonder_hd_600_map);
}
module_init(init_rc_map_ati_tv_wonder_hd_600)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
index 12f043587f2e..ec9beeebd410 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-a16d.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode avermedia_a16d[] = {
+static struct rc_map_table avermedia_a16d[] = {
{ 0x20, KEY_LIST},
{ 0x00, KEY_POWER},
{ 0x28, KEY_1},
@@ -49,23 +49,23 @@ static struct ir_scancode avermedia_a16d[] = {
{ 0x2a, KEY_MENU},
};
-static struct rc_keymap avermedia_a16d_map = {
+static struct rc_map_list avermedia_a16d_map = {
.map = {
.scan = avermedia_a16d,
.size = ARRAY_SIZE(avermedia_a16d),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA_A16D,
}
};
static int __init init_rc_map_avermedia_a16d(void)
{
- return ir_register_map(&avermedia_a16d_map);
+ return rc_map_register(&avermedia_a16d_map);
}
static void __exit exit_rc_map_avermedia_a16d(void)
{
- ir_unregister_map(&avermedia_a16d_map);
+ rc_map_unregister(&avermedia_a16d_map);
}
module_init(init_rc_map_avermedia_a16d)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
index 2a945b02e8ca..bdf97b74cf90 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-cardbus.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
@@ -14,7 +14,7 @@
/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
-static struct ir_scancode avermedia_cardbus[] = {
+static struct rc_map_table avermedia_cardbus[] = {
{ 0x00, KEY_POWER },
{ 0x01, KEY_TUNER }, /* TV/FM */
{ 0x03, KEY_TEXT }, /* Teletext */
@@ -71,23 +71,23 @@ static struct ir_scancode avermedia_cardbus[] = {
{ 0x43, KEY_CHANNELUP }, /* Channel up */
};
-static struct rc_keymap avermedia_cardbus_map = {
+static struct rc_map_list avermedia_cardbus_map = {
.map = {
.scan = avermedia_cardbus,
.size = ARRAY_SIZE(avermedia_cardbus),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA_CARDBUS,
}
};
static int __init init_rc_map_avermedia_cardbus(void)
{
- return ir_register_map(&avermedia_cardbus_map);
+ return rc_map_register(&avermedia_cardbus_map);
}
static void __exit exit_rc_map_avermedia_cardbus(void)
{
- ir_unregister_map(&avermedia_cardbus_map);
+ rc_map_unregister(&avermedia_cardbus_map);
}
module_init(init_rc_map_avermedia_cardbus)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
index 39dde6222875..3ddb41bc075e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-dvbt.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
@@ -14,7 +14,7 @@
/* Matt Jesson <dvb@jesson.eclipse.co.uk */
-static struct ir_scancode avermedia_dvbt[] = {
+static struct rc_map_table avermedia_dvbt[] = {
{ 0x28, KEY_0 }, /* '0' / 'enter' */
{ 0x22, KEY_1 }, /* '1' */
{ 0x12, KEY_2 }, /* '2' / 'up arrow' */
@@ -52,23 +52,23 @@ static struct ir_scancode avermedia_dvbt[] = {
{ 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
};
-static struct rc_keymap avermedia_dvbt_map = {
+static struct rc_map_list avermedia_dvbt_map = {
.map = {
.scan = avermedia_dvbt,
.size = ARRAY_SIZE(avermedia_dvbt),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA_DVBT,
}
};
static int __init init_rc_map_avermedia_dvbt(void)
{
- return ir_register_map(&avermedia_dvbt_map);
+ return rc_map_register(&avermedia_dvbt_map);
}
static void __exit exit_rc_map_avermedia_dvbt(void)
{
- ir_unregister_map(&avermedia_dvbt_map);
+ rc_map_unregister(&avermedia_dvbt_map);
}
module_init(init_rc_map_avermedia_dvbt)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index e4471fb2ad1e..357fea58a46e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -22,7 +22,7 @@
* codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*/
-static struct ir_scancode avermedia_m135a[] = {
+static struct rc_map_table avermedia_m135a[] = {
/* RM-JX */
{ 0x0200, KEY_POWER2 },
{ 0x022e, KEY_DOT }, /* '.' */
@@ -121,23 +121,23 @@ static struct ir_scancode avermedia_m135a[] = {
{ 0x041e, KEY_NEXT },
};
-static struct rc_keymap avermedia_m135a_map = {
+static struct rc_map_list avermedia_m135a_map = {
.map = {
.scan = avermedia_m135a,
.size = ARRAY_SIZE(avermedia_m135a),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M135A,
}
};
static int __init init_rc_map_avermedia_m135a(void)
{
- return ir_register_map(&avermedia_m135a_map);
+ return rc_map_register(&avermedia_m135a_map);
}
static void __exit exit_rc_map_avermedia_m135a(void)
{
- ir_unregister_map(&avermedia_m135a_map);
+ rc_map_unregister(&avermedia_m135a_map);
}
module_init(init_rc_map_avermedia_m135a)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
index cf8d45717cb3..e694e6eac37e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
@@ -16,7 +16,7 @@
* Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*/
-static struct ir_scancode avermedia_m733a_rm_k6[] = {
+static struct rc_map_table avermedia_m733a_rm_k6[] = {
{ 0x0401, KEY_POWER2 },
{ 0x0406, KEY_MUTE },
{ 0x0408, KEY_MODE }, /* TV/FM */
@@ -69,23 +69,23 @@ static struct ir_scancode avermedia_m733a_rm_k6[] = {
{ 0x041e, KEY_NEXT },
};
-static struct rc_keymap avermedia_m733a_rm_k6_map = {
+static struct rc_map_list avermedia_m733a_rm_k6_map = {
.map = {
.scan = avermedia_m733a_rm_k6,
.size = ARRAY_SIZE(avermedia_m733a_rm_k6),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M733A_RM_K6,
}
};
static int __init init_rc_map_avermedia_m733a_rm_k6(void)
{
- return ir_register_map(&avermedia_m733a_rm_k6_map);
+ return rc_map_register(&avermedia_m733a_rm_k6_map);
}
static void __exit exit_rc_map_avermedia_m733a_rm_k6(void)
{
- ir_unregister_map(&avermedia_m733a_rm_k6_map);
+ rc_map_unregister(&avermedia_m733a_rm_k6_map);
}
module_init(init_rc_map_avermedia_m733a_rm_k6)
diff --git a/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
index 9ee60906c861..f4ca1fff455d 100644
--- a/drivers/media/IR/keymaps/rc-avermedia-rm-ks.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
@@ -23,7 +23,7 @@
/* Initial keytable is from Jose Alberto Reguero <jareguero@telefonica.net>
and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */
/* FIXME: mappings are not 100% correct? */
-static struct ir_scancode avermedia_rm_ks[] = {
+static struct rc_map_table avermedia_rm_ks[] = {
{ 0x0501, KEY_POWER2 },
{ 0x0502, KEY_CHANNELUP },
{ 0x0503, KEY_CHANNELDOWN },
@@ -53,23 +53,23 @@ static struct ir_scancode avermedia_rm_ks[] = {
{ 0x0556, KEY_ZOOM },
};
-static struct rc_keymap avermedia_rm_ks_map = {
+static struct rc_map_list avermedia_rm_ks_map = {
.map = {
.scan = avermedia_rm_ks,
.size = ARRAY_SIZE(avermedia_rm_ks),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_RM_KS,
}
};
static int __init init_rc_map_avermedia_rm_ks(void)
{
- return ir_register_map(&avermedia_rm_ks_map);
+ return rc_map_register(&avermedia_rm_ks_map);
}
static void __exit exit_rc_map_avermedia_rm_ks(void)
{
- ir_unregister_map(&avermedia_rm_ks_map);
+ rc_map_unregister(&avermedia_rm_ks_map);
}
module_init(init_rc_map_avermedia_rm_ks)
diff --git a/drivers/media/IR/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c
index 21effd5bfb0d..edfa71506d3e 100644
--- a/drivers/media/IR/keymaps/rc-avermedia.c
+++ b/drivers/media/rc/keymaps/rc-avermedia.c
@@ -14,7 +14,7 @@
/* Alex Hermann <gaaf@gmx.net> */
-static struct ir_scancode avermedia[] = {
+static struct rc_map_table avermedia[] = {
{ 0x28, KEY_1 },
{ 0x18, KEY_2 },
{ 0x38, KEY_3 },
@@ -60,23 +60,23 @@ static struct ir_scancode avermedia[] = {
{ 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
};
-static struct rc_keymap avermedia_map = {
+static struct rc_map_list avermedia_map = {
.map = {
.scan = avermedia,
.size = ARRAY_SIZE(avermedia),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERMEDIA,
}
};
static int __init init_rc_map_avermedia(void)
{
- return ir_register_map(&avermedia_map);
+ return rc_map_register(&avermedia_map);
}
static void __exit exit_rc_map_avermedia(void)
{
- ir_unregister_map(&avermedia_map);
+ rc_map_unregister(&avermedia_map);
}
module_init(init_rc_map_avermedia)
diff --git a/drivers/media/IR/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c
index 971c59d6f9d6..32e94988dc94 100644
--- a/drivers/media/IR/keymaps/rc-avertv-303.c
+++ b/drivers/media/rc/keymaps/rc-avertv-303.c
@@ -14,7 +14,7 @@
/* AVERTV STUDIO 303 Remote */
-static struct ir_scancode avertv_303[] = {
+static struct rc_map_table avertv_303[] = {
{ 0x2a, KEY_1 },
{ 0x32, KEY_2 },
{ 0x3a, KEY_3 },
@@ -59,23 +59,23 @@ static struct ir_scancode avertv_303[] = {
{ 0x1b, KEY_UP },
};
-static struct rc_keymap avertv_303_map = {
+static struct rc_map_list avertv_303_map = {
.map = {
.scan = avertv_303,
.size = ARRAY_SIZE(avertv_303),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_AVERTV_303,
}
};
static int __init init_rc_map_avertv_303(void)
{
- return ir_register_map(&avertv_303_map);
+ return rc_map_register(&avertv_303_map);
}
static void __exit exit_rc_map_avertv_303(void)
{
- ir_unregister_map(&avertv_303_map);
+ rc_map_unregister(&avertv_303_map);
}
module_init(init_rc_map_avertv_303)
diff --git a/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
index e0876147d471..c3f6d62ac892 100644
--- a/drivers/media/IR/keymaps/rc-azurewave-ad-tu700.c
+++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode azurewave_ad_tu700[] = {
+static struct rc_map_table azurewave_ad_tu700[] = {
{ 0x0000, KEY_TAB }, /* Tab */
{ 0x0001, KEY_2 },
{ 0x0002, KEY_CHANNELDOWN },
@@ -76,23 +76,23 @@ static struct ir_scancode azurewave_ad_tu700[] = {
{ 0x005f, KEY_BLUE },
};
-static struct rc_keymap azurewave_ad_tu700_map = {
+static struct rc_map_list azurewave_ad_tu700_map = {
.map = {
.scan = azurewave_ad_tu700,
.size = ARRAY_SIZE(azurewave_ad_tu700),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_AZUREWAVE_AD_TU700,
}
};
static int __init init_rc_map_azurewave_ad_tu700(void)
{
- return ir_register_map(&azurewave_ad_tu700_map);
+ return rc_map_register(&azurewave_ad_tu700_map);
}
static void __exit exit_rc_map_azurewave_ad_tu700(void)
{
- ir_unregister_map(&azurewave_ad_tu700_map);
+ rc_map_unregister(&azurewave_ad_tu700_map);
}
module_init(init_rc_map_azurewave_ad_tu700)
diff --git a/drivers/media/IR/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c
index 9f56c98fef5b..4b787fa94f08 100644
--- a/drivers/media/IR/keymaps/rc-behold-columbus.c
+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
@@ -21,7 +21,7 @@
* helps to descide which keycodes to assign to the buttons.
*/
-static struct ir_scancode behold_columbus[] = {
+static struct rc_map_table behold_columbus[] = {
/* 0x13 0x11 0x1C 0x12 *
* Mute Source TV/FM Power *
@@ -82,23 +82,23 @@ static struct ir_scancode behold_columbus[] = {
};
-static struct rc_keymap behold_columbus_map = {
+static struct rc_map_list behold_columbus_map = {
.map = {
.scan = behold_columbus,
.size = ARRAY_SIZE(behold_columbus),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_BEHOLD_COLUMBUS,
}
};
static int __init init_rc_map_behold_columbus(void)
{
- return ir_register_map(&behold_columbus_map);
+ return rc_map_register(&behold_columbus_map);
}
static void __exit exit_rc_map_behold_columbus(void)
{
- ir_unregister_map(&behold_columbus_map);
+ rc_map_unregister(&behold_columbus_map);
}
module_init(init_rc_map_behold_columbus)
diff --git a/drivers/media/IR/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index abc140b2098b..0ee1f149364c 100644
--- a/drivers/media/IR/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -24,13 +24,13 @@
* helps to descide which keycodes to assign to the buttons.
*/
-static struct ir_scancode behold[] = {
+static struct rc_map_table behold[] = {
/* 0x1c 0x12 *
* TV/FM POWER *
* */
- { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
- { 0x12, KEY_POWER },
+ { 0x6b861c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
+ { 0x6b8612, KEY_POWER },
/* 0x01 0x02 0x03 *
* 1 2 3 *
@@ -41,28 +41,28 @@ static struct ir_scancode behold[] = {
* 0x07 0x08 0x09 *
* 7 8 9 *
* */
- { 0x01, KEY_1 },
- { 0x02, KEY_2 },
- { 0x03, KEY_3 },
- { 0x04, KEY_4 },
- { 0x05, KEY_5 },
- { 0x06, KEY_6 },
- { 0x07, KEY_7 },
- { 0x08, KEY_8 },
- { 0x09, KEY_9 },
+ { 0x6b8601, KEY_1 },
+ { 0x6b8602, KEY_2 },
+ { 0x6b8603, KEY_3 },
+ { 0x6b8604, KEY_4 },
+ { 0x6b8605, KEY_5 },
+ { 0x6b8606, KEY_6 },
+ { 0x6b8607, KEY_7 },
+ { 0x6b8608, KEY_8 },
+ { 0x6b8609, KEY_9 },
/* 0x0a 0x00 0x17 *
* RECALL 0 MODE *
* */
- { 0x0a, KEY_AGAIN },
- { 0x00, KEY_0 },
- { 0x17, KEY_MODE },
+ { 0x6b860a, KEY_AGAIN },
+ { 0x6b8600, KEY_0 },
+ { 0x6b8617, KEY_MODE },
/* 0x14 0x10 *
* ASPECT FULLSCREEN *
* */
- { 0x14, KEY_SCREEN },
- { 0x10, KEY_ZOOM },
+ { 0x6b8614, KEY_SCREEN },
+ { 0x6b8610, KEY_ZOOM },
/* 0x0b *
* Up *
@@ -73,17 +73,17 @@ static struct ir_scancode behold[] = {
* 0x015 *
* Down *
* */
- { 0x0b, KEY_CHANNELUP },
- { 0x18, KEY_VOLUMEDOWN },
- { 0x16, KEY_OK }, /* XXX KEY_ENTER */
- { 0x0c, KEY_VOLUMEUP },
- { 0x15, KEY_CHANNELDOWN },
+ { 0x6b860b, KEY_CHANNELUP },
+ { 0x6b8618, KEY_VOLUMEDOWN },
+ { 0x6b8616, KEY_OK }, /* XXX KEY_ENTER */
+ { 0x6b860c, KEY_VOLUMEUP },
+ { 0x6b8615, KEY_CHANNELDOWN },
/* 0x11 0x0d *
* MUTE INFO *
* */
- { 0x11, KEY_MUTE },
- { 0x0d, KEY_INFO },
+ { 0x6b8611, KEY_MUTE },
+ { 0x6b860d, KEY_INFO },
/* 0x0f 0x1b 0x1a *
* RECORD PLAY/PAUSE STOP *
@@ -92,46 +92,46 @@ static struct ir_scancode behold[] = {
*TELETEXT AUDIO SOURCE *
* RED YELLOW *
* */
- { 0x0f, KEY_RECORD },
- { 0x1b, KEY_PLAYPAUSE },
- { 0x1a, KEY_STOP },
- { 0x0e, KEY_TEXT },
- { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
- { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
+ { 0x6b860f, KEY_RECORD },
+ { 0x6b861b, KEY_PLAYPAUSE },
+ { 0x6b861a, KEY_STOP },
+ { 0x6b860e, KEY_TEXT },
+ { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */
+ { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */
/* 0x1d 0x13 0x19 *
* SLEEP PREVIEW DVB *
* GREEN BLUE *
* */
- { 0x1d, KEY_SLEEP },
- { 0x13, KEY_GREEN },
- { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
+ { 0x6b861d, KEY_SLEEP },
+ { 0x6b8613, KEY_GREEN },
+ { 0x6b8619, KEY_BLUE }, /* XXX KEY_SAT */
/* 0x58 0x5c *
* FREEZE SNAPSHOT *
* */
- { 0x58, KEY_SLOW },
- { 0x5c, KEY_CAMERA },
+ { 0x6b8658, KEY_SLOW },
+ { 0x6b865c, KEY_CAMERA },
};
-static struct rc_keymap behold_map = {
+static struct rc_map_list behold_map = {
.map = {
.scan = behold,
.size = ARRAY_SIZE(behold),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_BEHOLD,
}
};
static int __init init_rc_map_behold(void)
{
- return ir_register_map(&behold_map);
+ return rc_map_register(&behold_map);
}
static void __exit exit_rc_map_behold(void)
{
- ir_unregister_map(&behold_map);
+ rc_map_unregister(&behold_map);
}
module_init(init_rc_map_behold)
diff --git a/drivers/media/IR/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c
index 64c2ac913338..97fc3862f608 100644
--- a/drivers/media/IR/keymaps/rc-budget-ci-old.c
+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
@@ -18,7 +18,7 @@
* This is a "middle of the road" approach, differences are noted
*/
-static struct ir_scancode budget_ci_old[] = {
+static struct rc_map_table budget_ci_old[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -66,23 +66,23 @@ static struct ir_scancode budget_ci_old[] = {
{ 0x3e, KEY_TUNER },
};
-static struct rc_keymap budget_ci_old_map = {
+static struct rc_map_list budget_ci_old_map = {
.map = {
.scan = budget_ci_old,
.size = ARRAY_SIZE(budget_ci_old),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_BUDGET_CI_OLD,
}
};
static int __init init_rc_map_budget_ci_old(void)
{
- return ir_register_map(&budget_ci_old_map);
+ return rc_map_register(&budget_ci_old_map);
}
static void __exit exit_rc_map_budget_ci_old(void)
{
- ir_unregister_map(&budget_ci_old_map);
+ rc_map_unregister(&budget_ci_old_map);
}
module_init(init_rc_map_budget_ci_old)
diff --git a/drivers/media/IR/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c
index 074f2c2c2c61..284534b67e7d 100644
--- a/drivers/media/IR/keymaps/rc-cinergy-1400.c
+++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c
@@ -14,7 +14,7 @@
/* Cinergy 1400 DVB-T */
-static struct ir_scancode cinergy_1400[] = {
+static struct rc_map_table cinergy_1400[] = {
{ 0x01, KEY_POWER },
{ 0x02, KEY_1 },
{ 0x03, KEY_2 },
@@ -58,23 +58,23 @@ static struct ir_scancode cinergy_1400[] = {
{ 0x5c, KEY_NEXT },
};
-static struct rc_keymap cinergy_1400_map = {
+static struct rc_map_list cinergy_1400_map = {
.map = {
.scan = cinergy_1400,
.size = ARRAY_SIZE(cinergy_1400),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_CINERGY_1400,
}
};
static int __init init_rc_map_cinergy_1400(void)
{
- return ir_register_map(&cinergy_1400_map);
+ return rc_map_register(&cinergy_1400_map);
}
static void __exit exit_rc_map_cinergy_1400(void)
{
- ir_unregister_map(&cinergy_1400_map);
+ rc_map_unregister(&cinergy_1400_map);
}
module_init(init_rc_map_cinergy_1400)
diff --git a/drivers/media/IR/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c
index cf84c3dba742..99520ff65b61 100644
--- a/drivers/media/IR/keymaps/rc-cinergy.c
+++ b/drivers/media/rc/keymaps/rc-cinergy.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode cinergy[] = {
+static struct rc_map_table cinergy[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -52,23 +52,23 @@ static struct ir_scancode cinergy[] = {
{ 0x23, KEY_STOP },
};
-static struct rc_keymap cinergy_map = {
+static struct rc_map_list cinergy_map = {
.map = {
.scan = cinergy,
.size = ARRAY_SIZE(cinergy),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_CINERGY,
}
};
static int __init init_rc_map_cinergy(void)
{
- return ir_register_map(&cinergy_map);
+ return rc_map_register(&cinergy_map);
}
static void __exit exit_rc_map_cinergy(void)
{
- ir_unregister_map(&cinergy_map);
+ rc_map_unregister(&cinergy_map);
}
module_init(init_rc_map_cinergy)
diff --git a/drivers/media/IR/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c
index ae1832038fbe..c59851b203da 100644
--- a/drivers/media/IR/keymaps/rc-dib0700-nec.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c
@@ -17,7 +17,7 @@
#include <media/rc-map.h>
-static struct ir_scancode dib0700_nec_table[] = {
+static struct rc_map_table dib0700_nec_table[] = {
/* Key codes for the Pixelview SBTVD remote */
{ 0x8613, KEY_MUTE },
{ 0x8612, KEY_POWER },
@@ -98,23 +98,23 @@ static struct ir_scancode dib0700_nec_table[] = {
{ 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */
};
-static struct rc_keymap dib0700_nec_map = {
+static struct rc_map_list dib0700_nec_map = {
.map = {
.scan = dib0700_nec_table,
.size = ARRAY_SIZE(dib0700_nec_table),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_DIB0700_NEC_TABLE,
}
};
static int __init init_rc_map(void)
{
- return ir_register_map(&dib0700_nec_map);
+ return rc_map_register(&dib0700_nec_map);
}
static void __exit exit_rc_map(void)
{
- ir_unregister_map(&dib0700_nec_map);
+ rc_map_unregister(&dib0700_nec_map);
}
module_init(init_rc_map)
diff --git a/drivers/media/IR/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
index 4a4797cfd77d..4af12e45dfba 100644
--- a/drivers/media/IR/keymaps/rc-dib0700-rc5.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
@@ -17,7 +17,7 @@
#include <media/rc-map.h>
-static struct ir_scancode dib0700_rc5_table[] = {
+static struct rc_map_table dib0700_rc5_table[] = {
/* Key codes for the tiny Pinnacle remote*/
{ 0x0700, KEY_MUTE },
{ 0x0701, KEY_MENU }, /* Pinnacle logo */
@@ -209,23 +209,23 @@ static struct ir_scancode dib0700_rc5_table[] = {
{ 0x1d3d, KEY_POWER },
};
-static struct rc_keymap dib0700_rc5_map = {
+static struct rc_map_list dib0700_rc5_map = {
.map = {
.scan = dib0700_rc5_table,
.size = ARRAY_SIZE(dib0700_rc5_table),
- .ir_type = IR_TYPE_RC5,
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_DIB0700_RC5_TABLE,
}
};
static int __init init_rc_map(void)
{
- return ir_register_map(&dib0700_rc5_map);
+ return rc_map_register(&dib0700_rc5_map);
}
static void __exit exit_rc_map(void)
{
- ir_unregister_map(&dib0700_rc5_map);
+ rc_map_unregister(&dib0700_rc5_map);
}
module_init(init_rc_map)
diff --git a/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
index 63e469e2dd21..f68b450f5593 100644
--- a/drivers/media/IR/keymaps/rc-digitalnow-tinytwin.c
+++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode digitalnow_tinytwin[] = {
+static struct rc_map_table digitalnow_tinytwin[] = {
{ 0x0000, KEY_MUTE }, /* [symbol speaker] */
{ 0x0001, KEY_VOLUMEUP },
{ 0x0002, KEY_POWER2 }, /* TV [power button] */
@@ -72,23 +72,23 @@ static struct ir_scancode digitalnow_tinytwin[] = {
{ 0x005a, KEY_PREVIOUS }, /* REPLAY */
};
-static struct rc_keymap digitalnow_tinytwin_map = {
+static struct rc_map_list digitalnow_tinytwin_map = {
.map = {
.scan = digitalnow_tinytwin,
.size = ARRAY_SIZE(digitalnow_tinytwin),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_DIGITALNOW_TINYTWIN,
}
};
static int __init init_rc_map_digitalnow_tinytwin(void)
{
- return ir_register_map(&digitalnow_tinytwin_map);
+ return rc_map_register(&digitalnow_tinytwin_map);
}
static void __exit exit_rc_map_digitalnow_tinytwin(void)
{
- ir_unregister_map(&digitalnow_tinytwin_map);
+ rc_map_unregister(&digitalnow_tinytwin_map);
}
module_init(init_rc_map_digitalnow_tinytwin)
diff --git a/drivers/media/IR/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c
index 5dece78e19c5..21d49871f2a3 100644
--- a/drivers/media/IR/keymaps/rc-digittrade.c
+++ b/drivers/media/rc/keymaps/rc-digittrade.c
@@ -25,7 +25,7 @@
Initial keytable was from Alain Kalker <miki@dds.nl> */
/* Digittrade DVB-T USB Stick */
-static struct ir_scancode digittrade[] = {
+static struct rc_map_table digittrade[] = {
{ 0x0000, KEY_9 },
{ 0x0001, KEY_EPG }, /* EPG */
{ 0x0002, KEY_VOLUMEDOWN }, /* Vol Dn */
@@ -56,23 +56,23 @@ static struct ir_scancode digittrade[] = {
{ 0x0054, KEY_0 },
};
-static struct rc_keymap digittrade_map = {
+static struct rc_map_list digittrade_map = {
.map = {
.scan = digittrade,
.size = ARRAY_SIZE(digittrade),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_DIGITTRADE,
}
};
static int __init init_rc_map_digittrade(void)
{
- return ir_register_map(&digittrade_map);
+ return rc_map_register(&digittrade_map);
}
static void __exit exit_rc_map_digittrade(void)
{
- ir_unregister_map(&digittrade_map);
+ rc_map_unregister(&digittrade_map);
}
module_init(init_rc_map_digittrade)
diff --git a/drivers/media/IR/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c
index 90684d0efea3..d024fbf88bc4 100644
--- a/drivers/media/IR/keymaps/rc-dm1105-nec.c
+++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c
@@ -16,7 +16,7 @@
Igor M. Liplianin <liplianin@me.by>
*/
-static struct ir_scancode dm1105_nec[] = {
+static struct rc_map_table dm1105_nec[] = {
{ 0x0a, KEY_POWER2}, /* power */
{ 0x0c, KEY_MUTE}, /* mute */
{ 0x11, KEY_1},
@@ -50,23 +50,23 @@ static struct ir_scancode dm1105_nec[] = {
{ 0x1b, KEY_B}, /* recall */
};
-static struct rc_keymap dm1105_nec_map = {
+static struct rc_map_list dm1105_nec_map = {
.map = {
.scan = dm1105_nec,
.size = ARRAY_SIZE(dm1105_nec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_DM1105_NEC,
}
};
static int __init init_rc_map_dm1105_nec(void)
{
- return ir_register_map(&dm1105_nec_map);
+ return rc_map_register(&dm1105_nec_map);
}
static void __exit exit_rc_map_dm1105_nec(void)
{
- ir_unregister_map(&dm1105_nec_map);
+ rc_map_unregister(&dm1105_nec_map);
}
module_init(init_rc_map_dm1105_nec)
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
index 8a4027af964a..43912bd02a9e 100644
--- a/drivers/media/IR/keymaps/rc-dntv-live-dvb-t.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
@@ -14,7 +14,7 @@
/* DigitalNow DNTV Live DVB-T Remote */
-static struct ir_scancode dntv_live_dvb_t[] = {
+static struct rc_map_table dntv_live_dvb_t[] = {
{ 0x00, KEY_ESC }, /* 'go up a level?' */
/* Keys 0 to 9 */
{ 0x0a, KEY_0 },
@@ -52,23 +52,23 @@ static struct ir_scancode dntv_live_dvb_t[] = {
{ 0x1f, KEY_VOLUMEDOWN },
};
-static struct rc_keymap dntv_live_dvb_t_map = {
+static struct rc_map_list dntv_live_dvb_t_map = {
.map = {
.scan = dntv_live_dvb_t,
.size = ARRAY_SIZE(dntv_live_dvb_t),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_DNTV_LIVE_DVB_T,
}
};
static int __init init_rc_map_dntv_live_dvb_t(void)
{
- return ir_register_map(&dntv_live_dvb_t_map);
+ return rc_map_register(&dntv_live_dvb_t_map);
}
static void __exit exit_rc_map_dntv_live_dvb_t(void)
{
- ir_unregister_map(&dntv_live_dvb_t_map);
+ rc_map_unregister(&dntv_live_dvb_t_map);
}
module_init(init_rc_map_dntv_live_dvb_t)
diff --git a/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
index 6f4d60764d59..015e99de06de 100644
--- a/drivers/media/IR/keymaps/rc-dntv-live-dvbt-pro.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
@@ -14,7 +14,7 @@
/* DigitalNow DNTV Live! DVB-T Pro Remote */
-static struct ir_scancode dntv_live_dvbt_pro[] = {
+static struct rc_map_table dntv_live_dvbt_pro[] = {
{ 0x16, KEY_POWER },
{ 0x5b, KEY_HOME },
@@ -71,23 +71,23 @@ static struct ir_scancode dntv_live_dvbt_pro[] = {
{ 0x5d, KEY_BLUE },
};
-static struct rc_keymap dntv_live_dvbt_pro_map = {
+static struct rc_map_list dntv_live_dvbt_pro_map = {
.map = {
.scan = dntv_live_dvbt_pro,
.size = ARRAY_SIZE(dntv_live_dvbt_pro),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_DNTV_LIVE_DVBT_PRO,
}
};
static int __init init_rc_map_dntv_live_dvbt_pro(void)
{
- return ir_register_map(&dntv_live_dvbt_pro_map);
+ return rc_map_register(&dntv_live_dvbt_pro_map);
}
static void __exit exit_rc_map_dntv_live_dvbt_pro(void)
{
- ir_unregister_map(&dntv_live_dvbt_pro_map);
+ rc_map_unregister(&dntv_live_dvbt_pro_map);
}
module_init(init_rc_map_dntv_live_dvbt_pro)
diff --git a/drivers/media/IR/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c
index 3130c9c29e6b..269d4299da34 100644
--- a/drivers/media/IR/keymaps/rc-em-terratec.c
+++ b/drivers/media/rc/keymaps/rc-em-terratec.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode em_terratec[] = {
+static struct rc_map_table em_terratec[] = {
{ 0x01, KEY_CHANNEL },
{ 0x02, KEY_SELECT },
{ 0x03, KEY_MUTE },
@@ -43,23 +43,23 @@ static struct ir_scancode em_terratec[] = {
{ 0x40, KEY_ZOOM },
};
-static struct rc_keymap em_terratec_map = {
+static struct rc_map_list em_terratec_map = {
.map = {
.scan = em_terratec,
.size = ARRAY_SIZE(em_terratec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EM_TERRATEC,
}
};
static int __init init_rc_map_em_terratec(void)
{
- return ir_register_map(&em_terratec_map);
+ return rc_map_register(&em_terratec_map);
}
static void __exit exit_rc_map_em_terratec(void)
{
- ir_unregister_map(&em_terratec_map);
+ rc_map_unregister(&em_terratec_map);
}
module_init(init_rc_map_em_terratec)
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
index 4b816967877e..e388698a0697 100644
--- a/drivers/media/IR/keymaps/rc-encore-enltv-fm53.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-static struct ir_scancode encore_enltv_fm53[] = {
+static struct rc_map_table encore_enltv_fm53[] = {
{ 0x10, KEY_POWER2},
{ 0x06, KEY_MUTE},
@@ -55,23 +55,23 @@ static struct ir_scancode encore_enltv_fm53[] = {
{ 0x47, KEY_SLEEP}, /* shutdown */
};
-static struct rc_keymap encore_enltv_fm53_map = {
+static struct rc_map_list encore_enltv_fm53_map = {
.map = {
.scan = encore_enltv_fm53,
.size = ARRAY_SIZE(encore_enltv_fm53),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ENCORE_ENLTV_FM53,
}
};
static int __init init_rc_map_encore_enltv_fm53(void)
{
- return ir_register_map(&encore_enltv_fm53_map);
+ return rc_map_register(&encore_enltv_fm53_map);
}
static void __exit exit_rc_map_encore_enltv_fm53(void)
{
- ir_unregister_map(&encore_enltv_fm53_map);
+ rc_map_unregister(&encore_enltv_fm53_map);
}
module_init(init_rc_map_encore_enltv_fm53)
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c
index 9fabffd28cc9..afa4e92284ef 100644
--- a/drivers/media/IR/keymaps/rc-encore-enltv.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
@@ -15,7 +15,7 @@
/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
Juan Pablo Sormani <sorman@gmail.com> */
-static struct ir_scancode encore_enltv[] = {
+static struct rc_map_table encore_enltv[] = {
/* Power button does nothing, neither in Windows app,
although it sends data (used for BIOS wakeup?) */
@@ -86,23 +86,23 @@ static struct ir_scancode encore_enltv[] = {
{ 0x57, KEY_BLUE }, /* AP4 */
};
-static struct rc_keymap encore_enltv_map = {
+static struct rc_map_list encore_enltv_map = {
.map = {
.scan = encore_enltv,
.size = ARRAY_SIZE(encore_enltv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ENCORE_ENLTV,
}
};
static int __init init_rc_map_encore_enltv(void)
{
- return ir_register_map(&encore_enltv_map);
+ return rc_map_register(&encore_enltv_map);
}
static void __exit exit_rc_map_encore_enltv(void)
{
- ir_unregister_map(&encore_enltv_map);
+ rc_map_unregister(&encore_enltv_map);
}
module_init(init_rc_map_encore_enltv)
diff --git a/drivers/media/IR/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c
index efefd5166618..7d5b00ed4ff2 100644
--- a/drivers/media/IR/keymaps/rc-encore-enltv2.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
@@ -15,7 +15,7 @@
/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
Mauro Carvalho Chehab <mchehab@infradead.org> */
-static struct ir_scancode encore_enltv2[] = {
+static struct rc_map_table encore_enltv2[] = {
{ 0x4c, KEY_POWER2 },
{ 0x4a, KEY_TUNER },
{ 0x40, KEY_1 },
@@ -64,23 +64,23 @@ static struct ir_scancode encore_enltv2[] = {
{ 0x79, KEY_STOP },
};
-static struct rc_keymap encore_enltv2_map = {
+static struct rc_map_list encore_enltv2_map = {
.map = {
.scan = encore_enltv2,
.size = ARRAY_SIZE(encore_enltv2),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_ENCORE_ENLTV2,
}
};
static int __init init_rc_map_encore_enltv2(void)
{
- return ir_register_map(&encore_enltv2_map);
+ return rc_map_register(&encore_enltv2_map);
}
static void __exit exit_rc_map_encore_enltv2(void)
{
- ir_unregister_map(&encore_enltv2_map);
+ rc_map_unregister(&encore_enltv2_map);
}
module_init(init_rc_map_encore_enltv2)
diff --git a/drivers/media/IR/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c
index 3f3fb13813b3..a2bf24f6dfbb 100644
--- a/drivers/media/IR/keymaps/rc-evga-indtube.c
+++ b/drivers/media/rc/keymaps/rc-evga-indtube.c
@@ -16,7 +16,7 @@
Devin Heitmueller <devin.heitmueller@gmail.com>
*/
-static struct ir_scancode evga_indtube[] = {
+static struct rc_map_table evga_indtube[] = {
{ 0x12, KEY_POWER},
{ 0x02, KEY_MODE}, /* TV */
{ 0x14, KEY_MUTE},
@@ -35,23 +35,23 @@ static struct ir_scancode evga_indtube[] = {
{ 0x13, KEY_CAMERA},
};
-static struct rc_keymap evga_indtube_map = {
+static struct rc_map_list evga_indtube_map = {
.map = {
.scan = evga_indtube,
.size = ARRAY_SIZE(evga_indtube),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EVGA_INDTUBE,
}
};
static int __init init_rc_map_evga_indtube(void)
{
- return ir_register_map(&evga_indtube_map);
+ return rc_map_register(&evga_indtube_map);
}
static void __exit exit_rc_map_evga_indtube(void)
{
- ir_unregister_map(&evga_indtube_map);
+ rc_map_unregister(&evga_indtube_map);
}
module_init(init_rc_map_evga_indtube)
diff --git a/drivers/media/IR/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c
index 660907a78db9..1e8e5b2d6e36 100644
--- a/drivers/media/IR/keymaps/rc-eztv.c
+++ b/drivers/media/rc/keymaps/rc-eztv.c
@@ -15,7 +15,7 @@
/* Alfons Geser <a.geser@cox.net>
* updates from Job D. R. Borges <jobdrb@ig.com.br> */
-static struct ir_scancode eztv[] = {
+static struct rc_map_table eztv[] = {
{ 0x12, KEY_POWER },
{ 0x01, KEY_TV }, /* DVR */
{ 0x15, KEY_DVD }, /* DVD */
@@ -70,23 +70,23 @@ static struct ir_scancode eztv[] = {
{ 0x21, KEY_DOT }, /* . (decimal dot) */
};
-static struct rc_keymap eztv_map = {
+static struct rc_map_list eztv_map = {
.map = {
.scan = eztv,
.size = ARRAY_SIZE(eztv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_EZTV,
}
};
static int __init init_rc_map_eztv(void)
{
- return ir_register_map(&eztv_map);
+ return rc_map_register(&eztv_map);
}
static void __exit exit_rc_map_eztv(void)
{
- ir_unregister_map(&eztv_map);
+ rc_map_unregister(&eztv_map);
}
module_init(init_rc_map_eztv)
diff --git a/drivers/media/IR/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
index a173c81035f4..aea2f4acf7d8 100644
--- a/drivers/media/IR/keymaps/rc-flydvb.c
+++ b/drivers/media/rc/keymaps/rc-flydvb.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode flydvb[] = {
+static struct rc_map_table flydvb[] = {
{ 0x01, KEY_ZOOM }, /* Full Screen */
{ 0x00, KEY_POWER }, /* Power */
@@ -51,23 +51,23 @@ static struct ir_scancode flydvb[] = {
{ 0x0e, KEY_NEXT }, /* End >>| */
};
-static struct rc_keymap flydvb_map = {
+static struct rc_map_list flydvb_map = {
.map = {
.scan = flydvb,
.size = ARRAY_SIZE(flydvb),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_FLYDVB,
}
};
static int __init init_rc_map_flydvb(void)
{
- return ir_register_map(&flydvb_map);
+ return rc_map_register(&flydvb_map);
}
static void __exit exit_rc_map_flydvb(void)
{
- ir_unregister_map(&flydvb_map);
+ rc_map_unregister(&flydvb_map);
}
module_init(init_rc_map_flydvb)
diff --git a/drivers/media/IR/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c
index 9c73043cbdba..5bbe68371756 100644
--- a/drivers/media/IR/keymaps/rc-flyvideo.c
+++ b/drivers/media/rc/keymaps/rc-flyvideo.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode flyvideo[] = {
+static struct rc_map_table flyvideo[] = {
{ 0x0f, KEY_0 },
{ 0x03, KEY_1 },
{ 0x04, KEY_2 },
@@ -44,23 +44,23 @@ static struct ir_scancode flyvideo[] = {
{ 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
};
-static struct rc_keymap flyvideo_map = {
+static struct rc_map_list flyvideo_map = {
.map = {
.scan = flyvideo,
.size = ARRAY_SIZE(flyvideo),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_FLYVIDEO,
}
};
static int __init init_rc_map_flyvideo(void)
{
- return ir_register_map(&flyvideo_map);
+ return rc_map_register(&flyvideo_map);
}
static void __exit exit_rc_map_flyvideo(void)
{
- ir_unregister_map(&flyvideo_map);
+ rc_map_unregister(&flyvideo_map);
}
module_init(init_rc_map_flyvideo)
diff --git a/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
index cdb10389b10e..c80b25c65b57 100644
--- a/drivers/media/IR/keymaps/rc-fusionhdtv-mce.c
+++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
@@ -14,7 +14,7 @@
/* DViCO FUSION HDTV MCE remote */
-static struct ir_scancode fusionhdtv_mce[] = {
+static struct rc_map_table fusionhdtv_mce[] = {
{ 0x0b, KEY_1 },
{ 0x17, KEY_2 },
@@ -72,23 +72,23 @@ static struct ir_scancode fusionhdtv_mce[] = {
{ 0x4e, KEY_POWER },
};
-static struct rc_keymap fusionhdtv_mce_map = {
+static struct rc_map_list fusionhdtv_mce_map = {
.map = {
.scan = fusionhdtv_mce,
.size = ARRAY_SIZE(fusionhdtv_mce),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_FUSIONHDTV_MCE,
}
};
static int __init init_rc_map_fusionhdtv_mce(void)
{
- return ir_register_map(&fusionhdtv_mce_map);
+ return rc_map_register(&fusionhdtv_mce_map);
}
static void __exit exit_rc_map_fusionhdtv_mce(void)
{
- ir_unregister_map(&fusionhdtv_mce_map);
+ rc_map_unregister(&fusionhdtv_mce_map);
}
module_init(init_rc_map_fusionhdtv_mce)
diff --git a/drivers/media/IR/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
index c16c0d1263ac..068c9ead98dd 100644
--- a/drivers/media/IR/keymaps/rc-gadmei-rm008z.c
+++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
@@ -16,7 +16,7 @@
Shine Liu <shinel@foxmail.com>
*/
-static struct ir_scancode gadmei_rm008z[] = {
+static struct rc_map_table gadmei_rm008z[] = {
{ 0x14, KEY_POWER2}, /* POWER OFF */
{ 0x0c, KEY_MUTE}, /* MUTE */
@@ -55,23 +55,23 @@ static struct ir_scancode gadmei_rm008z[] = {
{ 0x15, KEY_ENTER}, /* OK */
};
-static struct rc_keymap gadmei_rm008z_map = {
+static struct rc_map_list gadmei_rm008z_map = {
.map = {
.scan = gadmei_rm008z,
.size = ARRAY_SIZE(gadmei_rm008z),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_GADMEI_RM008Z,
}
};
static int __init init_rc_map_gadmei_rm008z(void)
{
- return ir_register_map(&gadmei_rm008z_map);
+ return rc_map_register(&gadmei_rm008z_map);
}
static void __exit exit_rc_map_gadmei_rm008z(void)
{
- ir_unregister_map(&gadmei_rm008z_map);
+ rc_map_unregister(&gadmei_rm008z_map);
}
module_init(init_rc_map_gadmei_rm008z)
diff --git a/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
index 89f8e384e52a..cdbbed467926 100644
--- a/drivers/media/IR/keymaps/rc-genius-tvgo-a11mce.c
+++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
@@ -17,7 +17,7 @@
* Adrian Pardini <pardo.bsso@gmail.com>
*/
-static struct ir_scancode genius_tvgo_a11mce[] = {
+static struct rc_map_table genius_tvgo_a11mce[] = {
/* Keys 0 to 9 */
{ 0x48, KEY_0 },
{ 0x09, KEY_1 },
@@ -58,23 +58,23 @@ static struct ir_scancode genius_tvgo_a11mce[] = {
{ 0x50, KEY_BLUE },
};
-static struct rc_keymap genius_tvgo_a11mce_map = {
+static struct rc_map_list genius_tvgo_a11mce_map = {
.map = {
.scan = genius_tvgo_a11mce,
.size = ARRAY_SIZE(genius_tvgo_a11mce),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_GENIUS_TVGO_A11MCE,
}
};
static int __init init_rc_map_genius_tvgo_a11mce(void)
{
- return ir_register_map(&genius_tvgo_a11mce_map);
+ return rc_map_register(&genius_tvgo_a11mce_map);
}
static void __exit exit_rc_map_genius_tvgo_a11mce(void)
{
- ir_unregister_map(&genius_tvgo_a11mce_map);
+ rc_map_unregister(&genius_tvgo_a11mce_map);
}
module_init(init_rc_map_genius_tvgo_a11mce)
diff --git a/drivers/media/IR/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c
index 52f025bb35f6..a38bdde8c140 100644
--- a/drivers/media/IR/keymaps/rc-gotview7135.c
+++ b/drivers/media/rc/keymaps/rc-gotview7135.c
@@ -14,7 +14,7 @@
/* Mike Baikov <mike@baikov.com> */
-static struct ir_scancode gotview7135[] = {
+static struct rc_map_table gotview7135[] = {
{ 0x11, KEY_POWER },
{ 0x35, KEY_TV },
@@ -53,23 +53,23 @@ static struct ir_scancode gotview7135[] = {
{ 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
};
-static struct rc_keymap gotview7135_map = {
+static struct rc_map_list gotview7135_map = {
.map = {
.scan = gotview7135,
.size = ARRAY_SIZE(gotview7135),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_GOTVIEW7135,
}
};
static int __init init_rc_map_gotview7135(void)
{
- return ir_register_map(&gotview7135_map);
+ return rc_map_register(&gotview7135_map);
}
static void __exit exit_rc_map_gotview7135(void)
{
- ir_unregister_map(&gotview7135_map);
+ rc_map_unregister(&gotview7135_map);
}
module_init(init_rc_map_gotview7135)
diff --git a/drivers/media/IR/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c
index c6f8cd7c5186..bd11da46e56a 100644
--- a/drivers/media/IR/keymaps/rc-hauppauge-new.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge-new.c
@@ -16,7 +16,7 @@
* slightly different versions), shipped with cx88+ivtv cards.
* almost rc5 coding, but some non-standard keys */
-static struct ir_scancode hauppauge_new[] = {
+static struct rc_map_table hauppauge_new[] = {
/* Keys 0 to 9 */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -74,23 +74,23 @@ static struct ir_scancode hauppauge_new[] = {
{ 0x3d, KEY_POWER }, /* system power (green button) */
};
-static struct rc_keymap hauppauge_new_map = {
+static struct rc_map_list hauppauge_new_map = {
.map = {
.scan = hauppauge_new,
.size = ARRAY_SIZE(hauppauge_new),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_HAUPPAUGE_NEW,
}
};
static int __init init_rc_map_hauppauge_new(void)
{
- return ir_register_map(&hauppauge_new_map);
+ return rc_map_register(&hauppauge_new_map);
}
static void __exit exit_rc_map_hauppauge_new(void)
{
- ir_unregister_map(&hauppauge_new_map);
+ rc_map_unregister(&hauppauge_new_map);
}
module_init(init_rc_map_hauppauge_new)
diff --git a/drivers/media/IR/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c
index e49f350e3a0d..cb67184e015c 100644
--- a/drivers/media/IR/keymaps/rc-imon-mce.c
+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
/* mce-mode imon mce remote key table */
-static struct ir_scancode imon_mce[] = {
+static struct rc_map_table imon_mce[] = {
/* keys sorted mostly by frequency of use to optimize lookups */
{ 0x800ff415, KEY_REWIND },
{ 0x800ff414, KEY_FASTFORWARD },
@@ -115,24 +115,24 @@ static struct ir_scancode imon_mce[] = {
};
-static struct rc_keymap imon_mce_map = {
+static struct rc_map_list imon_mce_map = {
.map = {
.scan = imon_mce,
.size = ARRAY_SIZE(imon_mce),
/* its RC6, but w/a hardware decoder */
- .ir_type = IR_TYPE_RC6,
+ .rc_type = RC_TYPE_RC6,
.name = RC_MAP_IMON_MCE,
}
};
static int __init init_rc_map_imon_mce(void)
{
- return ir_register_map(&imon_mce_map);
+ return rc_map_register(&imon_mce_map);
}
static void __exit exit_rc_map_imon_mce(void)
{
- ir_unregister_map(&imon_mce_map);
+ rc_map_unregister(&imon_mce_map);
}
module_init(init_rc_map_imon_mce)
diff --git a/drivers/media/IR/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c
index bc4db72f02e6..eef46b73ca7b 100644
--- a/drivers/media/IR/keymaps/rc-imon-pad.c
+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
@@ -17,7 +17,7 @@
* same remote to different hex codes, and the silkscreened names
* vary a bit between the SoundGraph and Antec remotes... ugh.
*/
-static struct ir_scancode imon_pad[] = {
+static struct rc_map_table imon_pad[] = {
/* keys sorted mostly by frequency of use to optimize lookups */
{ 0x2a8195b7, KEY_REWIND },
{ 0x298315b7, KEY_REWIND },
@@ -129,24 +129,24 @@ static struct ir_scancode imon_pad[] = {
{ 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
};
-static struct rc_keymap imon_pad_map = {
+static struct rc_map_list imon_pad_map = {
.map = {
.scan = imon_pad,
.size = ARRAY_SIZE(imon_pad),
/* actual protocol details unknown, hardware decoder */
- .ir_type = IR_TYPE_OTHER,
+ .rc_type = RC_TYPE_OTHER,
.name = RC_MAP_IMON_PAD,
}
};
static int __init init_rc_map_imon_pad(void)
{
- return ir_register_map(&imon_pad_map);
+ return rc_map_register(&imon_pad_map);
}
static void __exit exit_rc_map_imon_pad(void)
{
- ir_unregister_map(&imon_pad_map);
+ rc_map_unregister(&imon_pad_map);
}
module_init(init_rc_map_imon_pad)
diff --git a/drivers/media/IR/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
index ef6600259fc0..1f59e163f75d 100644
--- a/drivers/media/IR/keymaps/rc-iodata-bctv7e.c
+++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
@@ -14,7 +14,7 @@
/* IO-DATA BCTV7E Remote */
-static struct ir_scancode iodata_bctv7e[] = {
+static struct rc_map_table iodata_bctv7e[] = {
{ 0x40, KEY_TV },
{ 0x20, KEY_RADIO }, /* FM */
{ 0x60, KEY_EPG },
@@ -62,23 +62,23 @@ static struct ir_scancode iodata_bctv7e[] = {
{ 0x01, KEY_NEXT }, /* skip >| */
};
-static struct rc_keymap iodata_bctv7e_map = {
+static struct rc_map_list iodata_bctv7e_map = {
.map = {
.scan = iodata_bctv7e,
.size = ARRAY_SIZE(iodata_bctv7e),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_IODATA_BCTV7E,
}
};
static int __init init_rc_map_iodata_bctv7e(void)
{
- return ir_register_map(&iodata_bctv7e_map);
+ return rc_map_register(&iodata_bctv7e_map);
}
static void __exit exit_rc_map_iodata_bctv7e(void)
{
- ir_unregister_map(&iodata_bctv7e_map);
+ rc_map_unregister(&iodata_bctv7e_map);
}
module_init(init_rc_map_iodata_bctv7e)
diff --git a/drivers/media/IR/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c
index 4c7883ba0f15..f31dc5c1ad9c 100644
--- a/drivers/media/IR/keymaps/rc-kaiomy.c
+++ b/drivers/media/rc/keymaps/rc-kaiomy.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-static struct ir_scancode kaiomy[] = {
+static struct rc_map_table kaiomy[] = {
{ 0x43, KEY_POWER2},
{ 0x01, KEY_LIST},
{ 0x0b, KEY_ZOOM},
@@ -61,23 +61,23 @@ static struct ir_scancode kaiomy[] = {
{ 0x1f, KEY_BLUE},
};
-static struct rc_keymap kaiomy_map = {
+static struct rc_map_list kaiomy_map = {
.map = {
.scan = kaiomy,
.size = ARRAY_SIZE(kaiomy),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_KAIOMY,
}
};
static int __init init_rc_map_kaiomy(void)
{
- return ir_register_map(&kaiomy_map);
+ return rc_map_register(&kaiomy_map);
}
static void __exit exit_rc_map_kaiomy(void)
{
- ir_unregister_map(&kaiomy_map);
+ rc_map_unregister(&kaiomy_map);
}
module_init(init_rc_map_kaiomy)
diff --git a/drivers/media/IR/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c
index 618c817374e6..3ce6ef79fc34 100644
--- a/drivers/media/IR/keymaps/rc-kworld-315u.c
+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
@@ -15,7 +15,7 @@
/* Kworld 315U
*/
-static struct ir_scancode kworld_315u[] = {
+static struct rc_map_table kworld_315u[] = {
{ 0x6143, KEY_POWER },
{ 0x6101, KEY_TUNER }, /* source */
{ 0x610b, KEY_ZOOM },
@@ -57,23 +57,23 @@ static struct ir_scancode kworld_315u[] = {
{ 0x611f, KEY_BLUE },
};
-static struct rc_keymap kworld_315u_map = {
+static struct rc_map_list kworld_315u_map = {
.map = {
.scan = kworld_315u,
.size = ARRAY_SIZE(kworld_315u),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_KWORLD_315U,
}
};
static int __init init_rc_map_kworld_315u(void)
{
- return ir_register_map(&kworld_315u_map);
+ return rc_map_register(&kworld_315u_map);
}
static void __exit exit_rc_map_kworld_315u(void)
{
- ir_unregister_map(&kworld_315u_map);
+ rc_map_unregister(&kworld_315u_map);
}
module_init(init_rc_map_kworld_315u)
diff --git a/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index 366732f1f7b7..e45f0b8759d0 100644
--- a/drivers/media/IR/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-static struct ir_scancode kworld_plus_tv_analog[] = {
+static struct rc_map_table kworld_plus_tv_analog[] = {
{ 0x0c, KEY_PROG1 }, /* Kworld key */
{ 0x16, KEY_CLOSECD }, /* -> ) */
{ 0x1d, KEY_POWER2 },
@@ -73,23 +73,23 @@ static struct ir_scancode kworld_plus_tv_analog[] = {
{ 0x23, KEY_GREEN}, /* C */
};
-static struct rc_keymap kworld_plus_tv_analog_map = {
+static struct rc_map_list kworld_plus_tv_analog_map = {
.map = {
.scan = kworld_plus_tv_analog,
.size = ARRAY_SIZE(kworld_plus_tv_analog),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_KWORLD_PLUS_TV_ANALOG,
}
};
static int __init init_rc_map_kworld_plus_tv_analog(void)
{
- return ir_register_map(&kworld_plus_tv_analog_map);
+ return rc_map_register(&kworld_plus_tv_analog_map);
}
static void __exit exit_rc_map_kworld_plus_tv_analog(void)
{
- ir_unregister_map(&kworld_plus_tv_analog_map);
+ rc_map_unregister(&kworld_plus_tv_analog_map);
}
module_init(init_rc_map_kworld_plus_tv_analog)
diff --git a/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
index 7521315fd876..8faa54ff16e6 100644
--- a/drivers/media/IR/keymaps/rc-leadtek-y04g0051.c
+++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode leadtek_y04g0051[] = {
+static struct rc_map_table leadtek_y04g0051[] = {
{ 0x0300, KEY_POWER2 },
{ 0x0303, KEY_SCREEN },
{ 0x0304, KEY_RIGHT },
@@ -73,23 +73,23 @@ static struct ir_scancode leadtek_y04g0051[] = {
{ 0x035f, KEY_CHANNELDOWN },
};
-static struct rc_keymap leadtek_y04g0051_map = {
+static struct rc_map_list leadtek_y04g0051_map = {
.map = {
.scan = leadtek_y04g0051,
.size = ARRAY_SIZE(leadtek_y04g0051),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_LEADTEK_Y04G0051,
}
};
static int __init init_rc_map_leadtek_y04g0051(void)
{
- return ir_register_map(&leadtek_y04g0051_map);
+ return rc_map_register(&leadtek_y04g0051_map);
}
static void __exit exit_rc_map_leadtek_y04g0051(void)
{
- ir_unregister_map(&leadtek_y04g0051_map);
+ rc_map_unregister(&leadtek_y04g0051_map);
}
module_init(init_rc_map_leadtek_y04g0051)
diff --git a/drivers/media/IR/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c
index 43fcf9035082..e8e23e233c39 100644
--- a/drivers/media/IR/keymaps/rc-lirc.c
+++ b/drivers/media/rc/keymaps/rc-lirc.c
@@ -9,29 +9,29 @@
* (at your option) any later version.
*/
-#include <media/ir-core.h>
+#include <media/rc-core.h>
-static struct ir_scancode lirc[] = {
+static struct rc_map_table lirc[] = {
{ },
};
-static struct rc_keymap lirc_map = {
+static struct rc_map_list lirc_map = {
.map = {
.scan = lirc,
.size = ARRAY_SIZE(lirc),
- .ir_type = IR_TYPE_LIRC,
+ .rc_type = RC_TYPE_LIRC,
.name = RC_MAP_LIRC,
}
};
static int __init init_rc_map_lirc(void)
{
- return ir_register_map(&lirc_map);
+ return rc_map_register(&lirc_map);
}
static void __exit exit_rc_map_lirc(void)
{
- ir_unregister_map(&lirc_map);
+ rc_map_unregister(&lirc_map);
}
module_init(init_rc_map_lirc)
diff --git a/drivers/media/IR/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c
index 40dcf0b4e21a..875cd81477c7 100644
--- a/drivers/media/IR/keymaps/rc-lme2510.c
+++ b/drivers/media/rc/keymaps/rc-lme2510.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode lme2510_rc[] = {
+static struct rc_map_table lme2510_rc[] = {
{ 0xba45, KEY_0 },
{ 0xa05f, KEY_1 },
{ 0xaf50, KEY_2 },
@@ -42,23 +42,23 @@ static struct ir_scancode lme2510_rc[] = {
};
-static struct rc_keymap lme2510_map = {
+static struct rc_map_list lme2510_map = {
.map = {
.scan = lme2510_rc,
.size = ARRAY_SIZE(lme2510_rc),
- .ir_type = IR_TYPE_UNKNOWN,
+ .rc_type = RC_TYPE_UNKNOWN,
.name = RC_MAP_LME2510,
}
};
static int __init init_rc_lme2510_map(void)
{
- return ir_register_map(&lme2510_map);
+ return rc_map_register(&lme2510_map);
}
static void __exit exit_rc_lme2510_map(void)
{
- ir_unregister_map(&lme2510_map);
+ rc_map_unregister(&lme2510_map);
}
module_init(init_rc_lme2510_map)
diff --git a/drivers/media/IR/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c
index 0f590b3d01c0..23b2d04e7a9f 100644
--- a/drivers/media/IR/keymaps/rc-manli.c
+++ b/drivers/media/rc/keymaps/rc-manli.c
@@ -21,7 +21,7 @@
helps to descide which keycodes to assign to the buttons.
*/
-static struct ir_scancode manli[] = {
+static struct rc_map_table manli[] = {
/* 0x1c 0x12 *
* FUNCTION POWER *
@@ -108,23 +108,23 @@ static struct ir_scancode manli[] = {
/* 0x1d unused ? */
};
-static struct rc_keymap manli_map = {
+static struct rc_map_list manli_map = {
.map = {
.scan = manli,
.size = ARRAY_SIZE(manli),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_MANLI,
}
};
static int __init init_rc_map_manli(void)
{
- return ir_register_map(&manli_map);
+ return rc_map_register(&manli_map);
}
static void __exit exit_rc_map_manli(void)
{
- ir_unregister_map(&manli_map);
+ rc_map_unregister(&manli_map);
}
module_init(init_rc_map_manli)
diff --git a/drivers/media/IR/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
index 67237fbf9e4b..7b9a01b6e4cf 100644
--- a/drivers/media/IR/keymaps/rc-msi-digivox-ii.c
+++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
@@ -20,7 +20,7 @@
#include <media/rc-map.h>
-static struct ir_scancode msi_digivox_ii[] = {
+static struct rc_map_table msi_digivox_ii[] = {
{ 0x0002, KEY_2 },
{ 0x0003, KEY_UP }, /* up */
{ 0x0004, KEY_3 },
@@ -41,23 +41,23 @@ static struct ir_scancode msi_digivox_ii[] = {
{ 0x001f, KEY_VOLUMEDOWN },
};
-static struct rc_keymap msi_digivox_ii_map = {
+static struct rc_map_list msi_digivox_ii_map = {
.map = {
.scan = msi_digivox_ii,
.size = ARRAY_SIZE(msi_digivox_ii),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_MSI_DIGIVOX_II,
}
};
static int __init init_rc_map_msi_digivox_ii(void)
{
- return ir_register_map(&msi_digivox_ii_map);
+ return rc_map_register(&msi_digivox_ii_map);
}
static void __exit exit_rc_map_msi_digivox_ii(void)
{
- ir_unregister_map(&msi_digivox_ii_map);
+ rc_map_unregister(&msi_digivox_ii_map);
}
module_init(init_rc_map_msi_digivox_ii)
diff --git a/drivers/media/IR/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c
index 882056e52ef9..ae9d06b39157 100644
--- a/drivers/media/IR/keymaps/rc-msi-digivox-iii.c
+++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c
@@ -24,7 +24,7 @@
/* Uses NEC extended 0x61d6. */
/* This remote seems to be same as rc-kworld-315u.c. Anyhow, add new remote
since rc-kworld-315u.c lacks NEC extended address byte. */
-static struct ir_scancode msi_digivox_iii[] = {
+static struct rc_map_table msi_digivox_iii[] = {
{ 0x61d601, KEY_VIDEO }, /* Source */
{ 0x61d602, KEY_3 },
{ 0x61d603, KEY_POWER }, /* ShutDown */
@@ -59,23 +59,23 @@ static struct ir_scancode msi_digivox_iii[] = {
{ 0x61d643, KEY_POWER2 }, /* [red power button] */
};
-static struct rc_keymap msi_digivox_iii_map = {
+static struct rc_map_list msi_digivox_iii_map = {
.map = {
.scan = msi_digivox_iii,
.size = ARRAY_SIZE(msi_digivox_iii),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_MSI_DIGIVOX_III,
}
};
static int __init init_rc_map_msi_digivox_iii(void)
{
- return ir_register_map(&msi_digivox_iii_map);
+ return rc_map_register(&msi_digivox_iii_map);
}
static void __exit exit_rc_map_msi_digivox_iii(void)
{
- ir_unregister_map(&msi_digivox_iii_map);
+ rc_map_unregister(&msi_digivox_iii_map);
}
module_init(init_rc_map_msi_digivox_iii)
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
index eb8e42c18ff9..fa8fd0ab94c7 100644
--- a/drivers/media/IR/keymaps/rc-msi-tvanywhere-plus.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
@@ -26,7 +26,7 @@
Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
*/
-static struct ir_scancode msi_tvanywhere_plus[] = {
+static struct rc_map_table msi_tvanywhere_plus[] = {
/* ---- Remote Button Layout ----
@@ -97,23 +97,23 @@ static struct ir_scancode msi_tvanywhere_plus[] = {
{ 0x1d, KEY_RESTART }, /* Reset */
};
-static struct rc_keymap msi_tvanywhere_plus_map = {
+static struct rc_map_list msi_tvanywhere_plus_map = {
.map = {
.scan = msi_tvanywhere_plus,
.size = ARRAY_SIZE(msi_tvanywhere_plus),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_MSI_TVANYWHERE_PLUS,
}
};
static int __init init_rc_map_msi_tvanywhere_plus(void)
{
- return ir_register_map(&msi_tvanywhere_plus_map);
+ return rc_map_register(&msi_tvanywhere_plus_map);
}
static void __exit exit_rc_map_msi_tvanywhere_plus(void)
{
- ir_unregister_map(&msi_tvanywhere_plus_map);
+ rc_map_unregister(&msi_tvanywhere_plus_map);
}
module_init(init_rc_map_msi_tvanywhere_plus)
diff --git a/drivers/media/IR/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
index ef411854f067..18b37facb0dd 100644
--- a/drivers/media/IR/keymaps/rc-msi-tvanywhere.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
@@ -14,7 +14,7 @@
/* MSI TV@nywhere MASTER remote */
-static struct ir_scancode msi_tvanywhere[] = {
+static struct rc_map_table msi_tvanywhere[] = {
/* Keys 0 to 9 */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -43,23 +43,23 @@ static struct ir_scancode msi_tvanywhere[] = {
{ 0x1f, KEY_VOLUMEDOWN },
};
-static struct rc_keymap msi_tvanywhere_map = {
+static struct rc_map_list msi_tvanywhere_map = {
.map = {
.scan = msi_tvanywhere,
.size = ARRAY_SIZE(msi_tvanywhere),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_MSI_TVANYWHERE,
}
};
static int __init init_rc_map_msi_tvanywhere(void)
{
- return ir_register_map(&msi_tvanywhere_map);
+ return rc_map_register(&msi_tvanywhere_map);
}
static void __exit exit_rc_map_msi_tvanywhere(void)
{
- ir_unregister_map(&msi_tvanywhere_map);
+ rc_map_unregister(&msi_tvanywhere_map);
}
module_init(init_rc_map_msi_tvanywhere)
diff --git a/drivers/media/IR/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index ccc50eb402ec..3e6f077eb700 100644
--- a/drivers/media/IR/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode nebula[] = {
+static struct rc_map_table nebula[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -70,23 +70,23 @@ static struct ir_scancode nebula[] = {
{ 0x36, KEY_PC },
};
-static struct rc_keymap nebula_map = {
+static struct rc_map_list nebula_map = {
.map = {
.scan = nebula,
.size = ARRAY_SIZE(nebula),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_NEBULA,
}
};
static int __init init_rc_map_nebula(void)
{
- return ir_register_map(&nebula_map);
+ return rc_map_register(&nebula_map);
}
static void __exit exit_rc_map_nebula(void)
{
- ir_unregister_map(&nebula_map);
+ rc_map_unregister(&nebula_map);
}
module_init(init_rc_map_nebula)
diff --git a/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
index e1b54d20db60..26f114c5c0de 100644
--- a/drivers/media/IR/keymaps/rc-nec-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -16,7 +16,7 @@
Mauro Carvalho Chehab <mchehab@redhat.com>
*/
-static struct ir_scancode nec_terratec_cinergy_xs[] = {
+static struct rc_map_table nec_terratec_cinergy_xs[] = {
{ 0x1441, KEY_HOME},
{ 0x1401, KEY_POWER2},
@@ -79,23 +79,23 @@ static struct ir_scancode nec_terratec_cinergy_xs[] = {
{ 0x145c, KEY_NEXT},
};
-static struct rc_keymap nec_terratec_cinergy_xs_map = {
+static struct rc_map_list nec_terratec_cinergy_xs_map = {
.map = {
.scan = nec_terratec_cinergy_xs,
.size = ARRAY_SIZE(nec_terratec_cinergy_xs),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_NEC_TERRATEC_CINERGY_XS,
}
};
static int __init init_rc_map_nec_terratec_cinergy_xs(void)
{
- return ir_register_map(&nec_terratec_cinergy_xs_map);
+ return rc_map_register(&nec_terratec_cinergy_xs_map);
}
static void __exit exit_rc_map_nec_terratec_cinergy_xs(void)
{
- ir_unregister_map(&nec_terratec_cinergy_xs_map);
+ rc_map_unregister(&nec_terratec_cinergy_xs_map);
}
module_init(init_rc_map_nec_terratec_cinergy_xs)
diff --git a/drivers/media/IR/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c
index e5849a6b3f05..629ee9d84537 100644
--- a/drivers/media/IR/keymaps/rc-norwood.c
+++ b/drivers/media/rc/keymaps/rc-norwood.c
@@ -16,7 +16,7 @@
By Peter Naulls <peter@chocky.org>
Key comments are the functions given in the manual */
-static struct ir_scancode norwood[] = {
+static struct rc_map_table norwood[] = {
/* Keys 0 to 9 */
{ 0x20, KEY_0 },
{ 0x21, KEY_1 },
@@ -59,23 +59,23 @@ static struct ir_scancode norwood[] = {
{ 0x65, KEY_POWER }, /* Computer power */
};
-static struct rc_keymap norwood_map = {
+static struct rc_map_list norwood_map = {
.map = {
.scan = norwood,
.size = ARRAY_SIZE(norwood),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_NORWOOD,
}
};
static int __init init_rc_map_norwood(void)
{
- return ir_register_map(&norwood_map);
+ return rc_map_register(&norwood_map);
}
static void __exit exit_rc_map_norwood(void)
{
- ir_unregister_map(&norwood_map);
+ rc_map_unregister(&norwood_map);
}
module_init(init_rc_map_norwood)
diff --git a/drivers/media/IR/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c
index b9ece1e90296..4aa588bf6d69 100644
--- a/drivers/media/IR/keymaps/rc-npgtech.c
+++ b/drivers/media/rc/keymaps/rc-npgtech.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode npgtech[] = {
+static struct rc_map_table npgtech[] = {
{ 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
{ 0x2a, KEY_FRONT },
@@ -54,23 +54,23 @@ static struct ir_scancode npgtech[] = {
};
-static struct rc_keymap npgtech_map = {
+static struct rc_map_list npgtech_map = {
.map = {
.scan = npgtech,
.size = ARRAY_SIZE(npgtech),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_NPGTECH,
}
};
static int __init init_rc_map_npgtech(void)
{
- return ir_register_map(&npgtech_map);
+ return rc_map_register(&npgtech_map);
}
static void __exit exit_rc_map_npgtech(void)
{
- ir_unregister_map(&npgtech_map);
+ rc_map_unregister(&npgtech_map);
}
module_init(init_rc_map_npgtech)
diff --git a/drivers/media/IR/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c
index 4129bb44a25b..fa5ae5981eb8 100644
--- a/drivers/media/IR/keymaps/rc-pctv-sedna.c
+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
@@ -17,7 +17,7 @@
Pavel Mihaylov <bin@bash.info>
Also for the remote bundled with Kozumi KTV-01C card */
-static struct ir_scancode pctv_sedna[] = {
+static struct rc_map_table pctv_sedna[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -54,23 +54,23 @@ static struct ir_scancode pctv_sedna[] = {
{ 0x1f, KEY_PLAY }, /* Play */
};
-static struct rc_keymap pctv_sedna_map = {
+static struct rc_map_list pctv_sedna_map = {
.map = {
.scan = pctv_sedna,
.size = ARRAY_SIZE(pctv_sedna),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PCTV_SEDNA,
}
};
static int __init init_rc_map_pctv_sedna(void)
{
- return ir_register_map(&pctv_sedna_map);
+ return rc_map_register(&pctv_sedna_map);
}
static void __exit exit_rc_map_pctv_sedna(void)
{
- ir_unregister_map(&pctv_sedna_map);
+ rc_map_unregister(&pctv_sedna_map);
}
module_init(init_rc_map_pctv_sedna)
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c
index 326e023ce126..23b8c505c6aa 100644
--- a/drivers/media/IR/keymaps/rc-pinnacle-color.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode pinnacle_color[] = {
+static struct rc_map_table pinnacle_color[] = {
{ 0x59, KEY_MUTE },
{ 0x4a, KEY_POWER },
@@ -68,23 +68,23 @@ static struct ir_scancode pinnacle_color[] = {
{ 0x0a, KEY_BACKSPACE },
};
-static struct rc_keymap pinnacle_color_map = {
+static struct rc_map_list pinnacle_color_map = {
.map = {
.scan = pinnacle_color,
.size = ARRAY_SIZE(pinnacle_color),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PINNACLE_COLOR,
}
};
static int __init init_rc_map_pinnacle_color(void)
{
- return ir_register_map(&pinnacle_color_map);
+ return rc_map_register(&pinnacle_color_map);
}
static void __exit exit_rc_map_pinnacle_color(void)
{
- ir_unregister_map(&pinnacle_color_map);
+ rc_map_unregister(&pinnacle_color_map);
}
module_init(init_rc_map_pinnacle_color)
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
index 14cb772515c6..6ba8c368d10a 100644
--- a/drivers/media/IR/keymaps/rc-pinnacle-grey.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode pinnacle_grey[] = {
+static struct rc_map_table pinnacle_grey[] = {
{ 0x3a, KEY_0 },
{ 0x31, KEY_1 },
{ 0x32, KEY_2 },
@@ -63,23 +63,23 @@ static struct ir_scancode pinnacle_grey[] = {
{ 0x18, KEY_EPG },
};
-static struct rc_keymap pinnacle_grey_map = {
+static struct rc_map_list pinnacle_grey_map = {
.map = {
.scan = pinnacle_grey,
.size = ARRAY_SIZE(pinnacle_grey),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PINNACLE_GREY,
}
};
static int __init init_rc_map_pinnacle_grey(void)
{
- return ir_register_map(&pinnacle_grey_map);
+ return rc_map_register(&pinnacle_grey_map);
}
static void __exit exit_rc_map_pinnacle_grey(void)
{
- ir_unregister_map(&pinnacle_grey_map);
+ rc_map_unregister(&pinnacle_grey_map);
}
module_init(init_rc_map_pinnacle_grey)
diff --git a/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
index 835bf4ef8de7..bb10ffe086b4 100644
--- a/drivers/media/IR/keymaps/rc-pinnacle-pctv-hd.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
@@ -14,7 +14,7 @@
/* Pinnacle PCTV HD 800i mini remote */
-static struct ir_scancode pinnacle_pctv_hd[] = {
+static struct rc_map_table pinnacle_pctv_hd[] = {
{ 0x0f, KEY_1 },
{ 0x15, KEY_2 },
@@ -47,23 +47,23 @@ static struct ir_scancode pinnacle_pctv_hd[] = {
{ 0x3f, KEY_EPG }, /* Labeled "?" */
};
-static struct rc_keymap pinnacle_pctv_hd_map = {
+static struct rc_map_list pinnacle_pctv_hd_map = {
.map = {
.scan = pinnacle_pctv_hd,
.size = ARRAY_SIZE(pinnacle_pctv_hd),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PINNACLE_PCTV_HD,
}
};
static int __init init_rc_map_pinnacle_pctv_hd(void)
{
- return ir_register_map(&pinnacle_pctv_hd_map);
+ return rc_map_register(&pinnacle_pctv_hd_map);
}
static void __exit exit_rc_map_pinnacle_pctv_hd(void)
{
- ir_unregister_map(&pinnacle_pctv_hd_map);
+ rc_map_unregister(&pinnacle_pctv_hd_map);
}
module_init(init_rc_map_pinnacle_pctv_hd)
diff --git a/drivers/media/IR/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
index 5a735d569a8b..8d9f664e0a2d 100644
--- a/drivers/media/IR/keymaps/rc-pixelview-mk12.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
@@ -16,7 +16,7 @@
* Keytable for MK-F12 IR remote provided together with Pixelview
* Ultra Pro Remote Controller. Uses NEC extended format.
*/
-static struct ir_scancode pixelview_mk12[] = {
+static struct rc_map_table pixelview_mk12[] = {
{ 0x866b03, KEY_TUNER }, /* Timeshift */
{ 0x866b1e, KEY_POWER2 }, /* power */
@@ -57,23 +57,23 @@ static struct ir_scancode pixelview_mk12[] = {
{ 0x866b07, KEY_RADIO }, /* FM */
};
-static struct rc_keymap pixelview_map = {
+static struct rc_map_list pixelview_map = {
.map = {
.scan = pixelview_mk12,
.size = ARRAY_SIZE(pixelview_mk12),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_PIXELVIEW_MK12,
}
};
static int __init init_rc_map_pixelview(void)
{
- return ir_register_map(&pixelview_map);
+ return rc_map_register(&pixelview_map);
}
static void __exit exit_rc_map_pixelview(void)
{
- ir_unregister_map(&pixelview_map);
+ rc_map_unregister(&pixelview_map);
}
module_init(init_rc_map_pixelview)
diff --git a/drivers/media/IR/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c
index 7bbbbf5735e6..777a70076be2 100644
--- a/drivers/media/IR/keymaps/rc-pixelview-new.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
@@ -17,7 +17,7 @@
present on PV MPEG 8000GT
*/
-static struct ir_scancode pixelview_new[] = {
+static struct rc_map_table pixelview_new[] = {
{ 0x3c, KEY_TIME }, /* Timeshift */
{ 0x12, KEY_POWER },
@@ -57,23 +57,23 @@ static struct ir_scancode pixelview_new[] = {
{ 0x34, KEY_RADIO },
};
-static struct rc_keymap pixelview_new_map = {
+static struct rc_map_list pixelview_new_map = {
.map = {
.scan = pixelview_new,
.size = ARRAY_SIZE(pixelview_new),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PIXELVIEW_NEW,
}
};
static int __init init_rc_map_pixelview_new(void)
{
- return ir_register_map(&pixelview_new_map);
+ return rc_map_register(&pixelview_new_map);
}
static void __exit exit_rc_map_pixelview_new(void)
{
- ir_unregister_map(&pixelview_new_map);
+ rc_map_unregister(&pixelview_new_map);
}
module_init(init_rc_map_pixelview_new)
diff --git a/drivers/media/IR/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c
index 82ff12e182a0..0ec5988916b9 100644
--- a/drivers/media/IR/keymaps/rc-pixelview.c
+++ b/drivers/media/rc/keymaps/rc-pixelview.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode pixelview[] = {
+static struct rc_map_table pixelview[] = {
{ 0x1e, KEY_POWER }, /* power */
{ 0x07, KEY_MEDIA }, /* source */
@@ -56,23 +56,23 @@ static struct ir_scancode pixelview[] = {
{ 0x18, KEY_MUTE }, /* mute/unmute */
};
-static struct rc_keymap pixelview_map = {
+static struct rc_map_list pixelview_map = {
.map = {
.scan = pixelview,
.size = ARRAY_SIZE(pixelview),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PIXELVIEW,
}
};
static int __init init_rc_map_pixelview(void)
{
- return ir_register_map(&pixelview_map);
+ return rc_map_register(&pixelview_map);
}
static void __exit exit_rc_map_pixelview(void)
{
- ir_unregister_map(&pixelview_map);
+ rc_map_unregister(&pixelview_map);
}
module_init(init_rc_map_pixelview)
diff --git a/drivers/media/IR/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
index 7cef8190a224..5f9d546a86c4 100644
--- a/drivers/media/IR/keymaps/rc-powercolor-real-angel.c
+++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
@@ -17,7 +17,7 @@
* Daniel Fraga <fragabr@gmail.com>
*/
-static struct ir_scancode powercolor_real_angel[] = {
+static struct rc_map_table powercolor_real_angel[] = {
{ 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
{ 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
{ 0x00, KEY_0 },
@@ -55,23 +55,23 @@ static struct ir_scancode powercolor_real_angel[] = {
{ 0x25, KEY_POWER }, /* power */
};
-static struct rc_keymap powercolor_real_angel_map = {
+static struct rc_map_list powercolor_real_angel_map = {
.map = {
.scan = powercolor_real_angel,
.size = ARRAY_SIZE(powercolor_real_angel),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_POWERCOLOR_REAL_ANGEL,
}
};
static int __init init_rc_map_powercolor_real_angel(void)
{
- return ir_register_map(&powercolor_real_angel_map);
+ return rc_map_register(&powercolor_real_angel_map);
}
static void __exit exit_rc_map_powercolor_real_angel(void)
{
- ir_unregister_map(&powercolor_real_angel_map);
+ rc_map_unregister(&powercolor_real_angel_map);
}
module_init(init_rc_map_powercolor_real_angel)
diff --git a/drivers/media/IR/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c
index 22e92d39dee5..8a3a643879d4 100644
--- a/drivers/media/IR/keymaps/rc-proteus-2309.c
+++ b/drivers/media/rc/keymaps/rc-proteus-2309.c
@@ -14,7 +14,7 @@
/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
-static struct ir_scancode proteus_2309[] = {
+static struct rc_map_table proteus_2309[] = {
/* numeric */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -43,23 +43,23 @@ static struct ir_scancode proteus_2309[] = {
{ 0x14, KEY_F1 },
};
-static struct rc_keymap proteus_2309_map = {
+static struct rc_map_list proteus_2309_map = {
.map = {
.scan = proteus_2309,
.size = ARRAY_SIZE(proteus_2309),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PROTEUS_2309,
}
};
static int __init init_rc_map_proteus_2309(void)
{
- return ir_register_map(&proteus_2309_map);
+ return rc_map_register(&proteus_2309_map);
}
static void __exit exit_rc_map_proteus_2309(void)
{
- ir_unregister_map(&proteus_2309_map);
+ rc_map_unregister(&proteus_2309_map);
}
module_init(init_rc_map_proteus_2309)
diff --git a/drivers/media/IR/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c
index 4e20fc2269f7..ef90296bfd68 100644
--- a/drivers/media/IR/keymaps/rc-purpletv.c
+++ b/drivers/media/rc/keymaps/rc-purpletv.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode purpletv[] = {
+static struct rc_map_table purpletv[] = {
{ 0x03, KEY_POWER },
{ 0x6f, KEY_MUTE },
{ 0x10, KEY_BACKSPACE }, /* Recall */
@@ -55,23 +55,23 @@ static struct ir_scancode purpletv[] = {
};
-static struct rc_keymap purpletv_map = {
+static struct rc_map_list purpletv_map = {
.map = {
.scan = purpletv,
.size = ARRAY_SIZE(purpletv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PURPLETV,
}
};
static int __init init_rc_map_purpletv(void)
{
- return ir_register_map(&purpletv_map);
+ return rc_map_register(&purpletv_map);
}
static void __exit exit_rc_map_purpletv(void)
{
- ir_unregister_map(&purpletv_map);
+ rc_map_unregister(&purpletv_map);
}
module_init(init_rc_map_purpletv)
diff --git a/drivers/media/IR/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
index 36679e706cf3..83a418de12c6 100644
--- a/drivers/media/IR/keymaps/rc-pv951.c
+++ b/drivers/media/rc/keymaps/rc-pv951.c
@@ -14,7 +14,7 @@
/* Mark Phalan <phalanm@o2.ie> */
-static struct ir_scancode pv951[] = {
+static struct rc_map_table pv951[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
@@ -52,23 +52,23 @@ static struct ir_scancode pv951[] = {
{ 0x1c, KEY_MEDIA }, /* PC/TV */
};
-static struct rc_keymap pv951_map = {
+static struct rc_map_list pv951_map = {
.map = {
.scan = pv951,
.size = ARRAY_SIZE(pv951),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_PV951,
}
};
static int __init init_rc_map_pv951(void)
{
- return ir_register_map(&pv951_map);
+ return rc_map_register(&pv951_map);
}
static void __exit exit_rc_map_pv951(void)
{
- ir_unregister_map(&pv951_map);
+ rc_map_unregister(&pv951_map);
}
module_init(init_rc_map_pv951)
diff --git a/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
index cc6b8f548747..dfc9b15f43a9 100644
--- a/drivers/media/IR/keymaps/rc-rc5-hauppauge-new.c
+++ b/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
@@ -19,7 +19,7 @@
* This table contains the complete RC5 code, instead of just the data part
*/
-static struct ir_scancode rc5_hauppauge_new[] = {
+static struct rc_map_table rc5_hauppauge_new[] = {
/* Keys 0 to 9 */
{ 0x1e00, KEY_0 },
{ 0x1e01, KEY_1 },
@@ -75,25 +75,63 @@ static struct ir_scancode rc5_hauppauge_new[] = {
{ 0x1e3b, KEY_SELECT }, /* top right button */
{ 0x1e3c, KEY_ZOOM }, /* full */
{ 0x1e3d, KEY_POWER }, /* system power (green button) */
+
+ /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */
+ { 0x1d00, KEY_0 },
+ { 0x1d01, KEY_1 },
+ { 0x1d02, KEY_2 },
+ { 0x1d03, KEY_3 },
+ { 0x1d04, KEY_4 },
+ { 0x1d05, KEY_5 },
+ { 0x1d06, KEY_6 },
+ { 0x1d07, KEY_7 },
+ { 0x1d08, KEY_8 },
+ { 0x1d09, KEY_9 },
+ { 0x1d0a, KEY_TEXT },
+ { 0x1d0d, KEY_MENU },
+ { 0x1d0f, KEY_MUTE },
+ { 0x1d10, KEY_VOLUMEUP },
+ { 0x1d11, KEY_VOLUMEDOWN },
+ { 0x1d12, KEY_PREVIOUS }, /* Prev.Ch .. ??? */
+ { 0x1d14, KEY_UP },
+ { 0x1d15, KEY_DOWN },
+ { 0x1d16, KEY_LEFT },
+ { 0x1d17, KEY_RIGHT },
+ { 0x1d1c, KEY_TV },
+ { 0x1d1e, KEY_NEXT }, /* >| */
+ { 0x1d1f, KEY_EXIT },
+ { 0x1d20, KEY_CHANNELUP },
+ { 0x1d21, KEY_CHANNELDOWN },
+ { 0x1d24, KEY_LAST }, /* <| */
+ { 0x1d25, KEY_OK },
+ { 0x1d30, KEY_PAUSE },
+ { 0x1d32, KEY_REWIND },
+ { 0x1d34, KEY_FASTFORWARD },
+ { 0x1d35, KEY_PLAY },
+ { 0x1d36, KEY_STOP },
+ { 0x1d37, KEY_RECORD },
+ { 0x1d3b, KEY_GOTO },
+ { 0x1d3d, KEY_POWER },
+ { 0x1d3f, KEY_HOME },
};
-static struct rc_keymap rc5_hauppauge_new_map = {
+static struct rc_map_list rc5_hauppauge_new_map = {
.map = {
.scan = rc5_hauppauge_new,
.size = ARRAY_SIZE(rc5_hauppauge_new),
- .ir_type = IR_TYPE_RC5,
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_RC5_HAUPPAUGE_NEW,
}
};
static int __init init_rc_map_rc5_hauppauge_new(void)
{
- return ir_register_map(&rc5_hauppauge_new_map);
+ return rc_map_register(&rc5_hauppauge_new_map);
}
static void __exit exit_rc_map_rc5_hauppauge_new(void)
{
- ir_unregister_map(&rc5_hauppauge_new_map);
+ rc_map_unregister(&rc5_hauppauge_new_map);
}
module_init(init_rc_map_rc5_hauppauge_new)
diff --git a/drivers/media/IR/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c
index 73cce2f8ddfb..4fcef9f1f721 100644
--- a/drivers/media/IR/keymaps/rc-rc5-tv.c
+++ b/drivers/media/rc/keymaps/rc-rc5-tv.c
@@ -16,7 +16,7 @@
/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
/* used by old (black) Hauppauge remotes */
-static struct ir_scancode rc5_tv[] = {
+static struct rc_map_table rc5_tv[] = {
/* Keys 0 to 9 */
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -55,23 +55,23 @@ static struct ir_scancode rc5_tv[] = {
};
-static struct rc_keymap rc5_tv_map = {
+static struct rc_map_list rc5_tv_map = {
.map = {
.scan = rc5_tv,
.size = ARRAY_SIZE(rc5_tv),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_RC5_TV,
}
};
static int __init init_rc_map_rc5_tv(void)
{
- return ir_register_map(&rc5_tv_map);
+ return rc_map_register(&rc5_tv_map);
}
static void __exit exit_rc_map_rc5_tv(void)
{
- ir_unregister_map(&rc5_tv_map);
+ rc_map_unregister(&rc5_tv_map);
}
module_init(init_rc_map_rc5_tv)
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c
index 1b7adabbcee9..3bf3337875d1 100644
--- a/drivers/media/IR/keymaps/rc-rc6-mce.c
+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
@@ -11,7 +11,7 @@
#include <media/rc-map.h>
-static struct ir_scancode rc6_mce[] = {
+static struct rc_map_table rc6_mce[] = {
{ 0x800f0400, KEY_NUMERIC_0 },
{ 0x800f0401, KEY_NUMERIC_1 },
@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f040a, KEY_DELETE },
{ 0x800f040b, KEY_ENTER },
- { 0x800f040c, KEY_POWER },
- { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
+ { 0x800f040c, KEY_POWER }, /* PC Power */
+ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
{ 0x800f040e, KEY_MUTE },
{ 0x800f040f, KEY_INFO },
@@ -56,53 +56,54 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0422, KEY_OK },
{ 0x800f0423, KEY_EXIT },
{ 0x800f0424, KEY_DVD },
- { 0x800f0425, KEY_TUNER }, /* LiveTV */
- { 0x800f0426, KEY_EPG }, /* Guide */
- { 0x800f0427, KEY_ZOOM }, /* Aspect */
+ { 0x800f0425, KEY_TUNER }, /* LiveTV */
+ { 0x800f0426, KEY_EPG }, /* Guide */
+ { 0x800f0427, KEY_ZOOM }, /* Aspect */
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0446, KEY_TV },
- { 0x800f0447, KEY_AUDIO }, /* My Music */
- { 0x800f0448, KEY_PVR }, /* RecordedTV */
+ { 0x800f0447, KEY_AUDIO }, /* My Music */
+ { 0x800f0448, KEY_PVR }, /* RecordedTV */
{ 0x800f0449, KEY_CAMERA },
{ 0x800f044a, KEY_VIDEO },
{ 0x800f044c, KEY_LANGUAGE },
{ 0x800f044d, KEY_TITLE },
- { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
+ { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
{ 0x800f0450, KEY_RADIO },
- { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
+ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
{ 0x800f045b, KEY_RED },
{ 0x800f045c, KEY_GREEN },
{ 0x800f045d, KEY_YELLOW },
{ 0x800f045e, KEY_BLUE },
+ { 0x800f0465, KEY_POWER2 }, /* TV Power */
{ 0x800f046e, KEY_PLAYPAUSE },
- { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
+ { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0481, KEY_PLAYPAUSE },
};
-static struct rc_keymap rc6_mce_map = {
+static struct rc_map_list rc6_mce_map = {
.map = {
.scan = rc6_mce,
.size = ARRAY_SIZE(rc6_mce),
- .ir_type = IR_TYPE_RC6,
+ .rc_type = RC_TYPE_RC6,
.name = RC_MAP_RC6_MCE,
}
};
static int __init init_rc_map_rc6_mce(void)
{
- return ir_register_map(&rc6_mce_map);
+ return rc_map_register(&rc6_mce_map);
}
static void __exit exit_rc_map_rc6_mce(void)
{
- ir_unregister_map(&rc6_mce_map);
+ rc_map_unregister(&rc6_mce_map);
}
module_init(init_rc_map_rc6_mce)
diff --git a/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
index ab1a6d2baf72..2d14598592d8 100644
--- a/drivers/media/IR/keymaps/rc-real-audio-220-32-keys.c
+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
@@ -14,7 +14,7 @@
/* Zogis Real Audio 220 - 32 keys IR */
-static struct ir_scancode real_audio_220_32_keys[] = {
+static struct rc_map_table real_audio_220_32_keys[] = {
{ 0x1c, KEY_RADIO},
{ 0x12, KEY_POWER2},
@@ -52,23 +52,23 @@ static struct ir_scancode real_audio_220_32_keys[] = {
};
-static struct rc_keymap real_audio_220_32_keys_map = {
+static struct rc_map_list real_audio_220_32_keys_map = {
.map = {
.scan = real_audio_220_32_keys,
.size = ARRAY_SIZE(real_audio_220_32_keys),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_REAL_AUDIO_220_32_KEYS,
}
};
static int __init init_rc_map_real_audio_220_32_keys(void)
{
- return ir_register_map(&real_audio_220_32_keys_map);
+ return rc_map_register(&real_audio_220_32_keys_map);
}
static void __exit exit_rc_map_real_audio_220_32_keys(void)
{
- ir_unregister_map(&real_audio_220_32_keys_map);
+ rc_map_unregister(&real_audio_220_32_keys_map);
}
module_init(init_rc_map_real_audio_220_32_keys)
diff --git a/drivers/media/IR/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c
index df32013a321c..92cc10d2f9cd 100644
--- a/drivers/media/IR/keymaps/rc-streamzap.c
+++ b/drivers/media/rc/keymaps/rc-streamzap.c
@@ -11,7 +11,7 @@
#include <media/rc-map.h>
-static struct ir_scancode streamzap[] = {
+static struct rc_map_table streamzap[] = {
/*
* The Streamzap remote is almost, but not quite, RC-5, as it has an extra
* bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
@@ -56,23 +56,23 @@ static struct ir_scancode streamzap[] = {
};
-static struct rc_keymap streamzap_map = {
+static struct rc_map_list streamzap_map = {
.map = {
.scan = streamzap,
.size = ARRAY_SIZE(streamzap),
- .ir_type = IR_TYPE_RC5_SZ,
+ .rc_type = RC_TYPE_RC5_SZ,
.name = RC_MAP_STREAMZAP,
}
};
static int __init init_rc_map_streamzap(void)
{
- return ir_register_map(&streamzap_map);
+ return rc_map_register(&streamzap_map);
}
static void __exit exit_rc_map_streamzap(void)
{
- ir_unregister_map(&streamzap_map);
+ rc_map_unregister(&streamzap_map);
}
module_init(init_rc_map_streamzap)
diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c
new file mode 100644
index 000000000000..7242ee66f6e0
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tbs-nec.c
@@ -0,0 +1,75 @@
+/* tbs-nec.h - Keytable for tbs_nec Remote Controller
+ *
+ * keymap imported from ir-keymaps.c
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+
+static struct rc_map_table tbs_nec[] = {
+ { 0x84, KEY_POWER2}, /* power */
+ { 0x94, KEY_MUTE}, /* mute */
+ { 0x87, KEY_1},
+ { 0x86, KEY_2},
+ { 0x85, KEY_3},
+ { 0x8b, KEY_4},
+ { 0x8a, KEY_5},
+ { 0x89, KEY_6},
+ { 0x8f, KEY_7},
+ { 0x8e, KEY_8},
+ { 0x8d, KEY_9},
+ { 0x92, KEY_0},
+ { 0xc0, KEY_10CHANNELSUP}, /* 10+ */
+ { 0xd0, KEY_10CHANNELSDOWN}, /* 10- */
+ { 0x96, KEY_CHANNELUP}, /* ch+ */
+ { 0x91, KEY_CHANNELDOWN}, /* ch- */
+ { 0x93, KEY_VOLUMEUP}, /* vol+ */
+ { 0x8c, KEY_VOLUMEDOWN}, /* vol- */
+ { 0x83, KEY_RECORD}, /* rec */
+ { 0x98, KEY_PAUSE}, /* pause, yellow */
+ { 0x99, KEY_OK}, /* ok */
+ { 0x9a, KEY_CAMERA}, /* snapshot */
+ { 0x81, KEY_UP},
+ { 0x90, KEY_LEFT},
+ { 0x82, KEY_RIGHT},
+ { 0x88, KEY_DOWN},
+ { 0x95, KEY_FAVORITES}, /* blue */
+ { 0x97, KEY_SUBTITLE}, /* green */
+ { 0x9d, KEY_ZOOM},
+ { 0x9f, KEY_EXIT},
+ { 0x9e, KEY_MENU},
+ { 0x9c, KEY_EPG},
+ { 0x80, KEY_PREVIOUS}, /* red */
+ { 0x9b, KEY_MODE},
+};
+
+static struct rc_map_list tbs_nec_map = {
+ .map = {
+ .scan = tbs_nec,
+ .size = ARRAY_SIZE(tbs_nec),
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .name = RC_MAP_TBS_NEC,
+ }
+};
+
+static int __init init_rc_map_tbs_nec(void)
+{
+ return rc_map_register(&tbs_nec_map);
+}
+
+static void __exit exit_rc_map_tbs_nec(void)
+{
+ rc_map_unregister(&tbs_nec_map);
+}
+
+module_init(init_rc_map_tbs_nec)
+module_exit(exit_rc_map_tbs_nec)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-technisat-usb2.c b/drivers/media/rc/keymaps/rc-technisat-usb2.c
new file mode 100644
index 000000000000..4afe5774f192
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-technisat-usb2.c
@@ -0,0 +1,93 @@
+/* rc-technisat-usb2.c - Keytable for SkyStar HD USB
+ *
+ * Copyright (C) 2010 Patrick Boettcher,
+ * Kernel Labs Inc. PO Box 745, St James, NY 11780
+ *
+ * Development was sponsored by Technisat Digital UK Limited, whose
+ * registered office is Witan Gate House 500 - 600 Witan Gate West,
+ * Milton Keynes, MK9 1SH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
+ * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
+ * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
+ * GNU General Public License for more details.
+ */
+
+#include <media/rc-map.h>
+
+static struct rc_map_table technisat_usb2[] = {
+ {0x0a0c, KEY_POWER},
+ {0x0a01, KEY_1},
+ {0x0a02, KEY_2},
+ {0x0a03, KEY_3},
+ {0x0a0d, KEY_MUTE},
+ {0x0a04, KEY_4},
+ {0x0a05, KEY_5},
+ {0x0a06, KEY_6},
+ {0x0a38, KEY_VIDEO}, /* EXT */
+ {0x0a07, KEY_7},
+ {0x0a08, KEY_8},
+ {0x0a09, KEY_9},
+ {0x0a00, KEY_0},
+ {0x0a4f, KEY_INFO},
+ {0x0a20, KEY_CHANNELUP},
+ {0x0a52, KEY_MENU},
+ {0x0a11, KEY_VOLUMEUP},
+ {0x0a57, KEY_OK},
+ {0x0a10, KEY_VOLUMEDOWN},
+ {0x0a2f, KEY_EPG},
+ {0x0a21, KEY_CHANNELDOWN},
+ {0x0a22, KEY_REFRESH},
+ {0x0a3c, KEY_TEXT},
+ {0x0a76, KEY_ENTER}, /* HOOK */
+ {0x0a0f, KEY_HELP},
+ {0x0a6b, KEY_RED},
+ {0x0a6c, KEY_GREEN},
+ {0x0a6d, KEY_YELLOW},
+ {0x0a6e, KEY_BLUE},
+ {0x0a29, KEY_STOP},
+ {0x0a23, KEY_LANGUAGE},
+ {0x0a53, KEY_TV},
+ {0x0a0a, KEY_PROGRAM},
+};
+
+static struct rc_map_list technisat_usb2_map = {
+ .map = {
+ .scan = technisat_usb2,
+ .size = ARRAY_SIZE(technisat_usb2),
+ .rc_type = RC_TYPE_RC5,
+ .name = RC_MAP_TECHNISAT_USB2,
+ }
+};
+
+static int __init init_rc_map(void)
+{
+ return rc_map_register(&technisat_usb2_map);
+}
+
+static void __exit exit_rc_map(void)
+{
+ rc_map_unregister(&technisat_usb2_map);
+}
+
+module_init(init_rc_map)
+module_exit(exit_rc_map)
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
index 5326a0b444c1..bc38e34b9fda 100644
--- a/drivers/media/IR/keymaps/rc-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
@@ -16,7 +16,7 @@
Devin Heitmueller <dheitmueller@linuxtv.org>
*/
-static struct ir_scancode terratec_cinergy_xs[] = {
+static struct rc_map_table terratec_cinergy_xs[] = {
{ 0x41, KEY_HOME},
{ 0x01, KEY_POWER},
{ 0x42, KEY_MENU},
@@ -66,23 +66,23 @@ static struct ir_scancode terratec_cinergy_xs[] = {
{ 0x5c, KEY_NEXT},
};
-static struct rc_keymap terratec_cinergy_xs_map = {
+static struct rc_map_list terratec_cinergy_xs_map = {
.map = {
.scan = terratec_cinergy_xs,
.size = ARRAY_SIZE(terratec_cinergy_xs),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TERRATEC_CINERGY_XS,
}
};
static int __init init_rc_map_terratec_cinergy_xs(void)
{
- return ir_register_map(&terratec_cinergy_xs_map);
+ return rc_map_register(&terratec_cinergy_xs_map);
}
static void __exit exit_rc_map_terratec_cinergy_xs(void)
{
- ir_unregister_map(&terratec_cinergy_xs_map);
+ rc_map_unregister(&terratec_cinergy_xs_map);
}
module_init(init_rc_map_terratec_cinergy_xs)
diff --git a/drivers/media/IR/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c
index 10dee4c1deff..1abafa5fd303 100644
--- a/drivers/media/IR/keymaps/rc-terratec-slim.c
+++ b/drivers/media/rc/keymaps/rc-terratec-slim.c
@@ -22,7 +22,7 @@
/* TerraTec slim remote, 7 rows, 4 columns. */
/* Uses NEC extended 0x02bd. */
-static struct ir_scancode terratec_slim[] = {
+static struct rc_map_table terratec_slim[] = {
{ 0x02bd00, KEY_1 },
{ 0x02bd01, KEY_2 },
{ 0x02bd02, KEY_3 },
@@ -53,23 +53,23 @@ static struct ir_scancode terratec_slim[] = {
{ 0x02bd45, KEY_POWER2 }, /* [red power button] */
};
-static struct rc_keymap terratec_slim_map = {
+static struct rc_map_list terratec_slim_map = {
.map = {
.scan = terratec_slim,
.size = ARRAY_SIZE(terratec_slim),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_TERRATEC_SLIM,
}
};
static int __init init_rc_map_terratec_slim(void)
{
- return ir_register_map(&terratec_slim_map);
+ return rc_map_register(&terratec_slim_map);
}
static void __exit exit_rc_map_terratec_slim(void)
{
- ir_unregister_map(&terratec_slim_map);
+ rc_map_unregister(&terratec_slim_map);
}
module_init(init_rc_map_terratec_slim)
diff --git a/drivers/media/IR/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c
index e30d411c07bb..ef5ba3f32735 100644
--- a/drivers/media/IR/keymaps/rc-tevii-nec.c
+++ b/drivers/media/rc/keymaps/rc-tevii-nec.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode tevii_nec[] = {
+static struct rc_map_table tevii_nec[] = {
{ 0x0a, KEY_POWER2},
{ 0x0c, KEY_MUTE},
{ 0x11, KEY_1},
@@ -62,23 +62,23 @@ static struct ir_scancode tevii_nec[] = {
{ 0x58, KEY_SWITCHVIDEOMODE},
};
-static struct rc_keymap tevii_nec_map = {
+static struct rc_map_list tevii_nec_map = {
.map = {
.scan = tevii_nec,
.size = ARRAY_SIZE(tevii_nec),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TEVII_NEC,
}
};
static int __init init_rc_map_tevii_nec(void)
{
- return ir_register_map(&tevii_nec_map);
+ return rc_map_register(&tevii_nec_map);
}
static void __exit exit_rc_map_tevii_nec(void)
{
- ir_unregister_map(&tevii_nec_map);
+ rc_map_unregister(&tevii_nec_map);
}
module_init(init_rc_map_tevii_nec)
diff --git a/drivers/media/IR/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c
index fd1985763781..20ac4e19fb3f 100644
--- a/drivers/media/IR/keymaps/rc-total-media-in-hand.c
+++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c
@@ -21,7 +21,7 @@
#include <media/rc-map.h>
/* Uses NEC extended 0x02bd */
-static struct ir_scancode total_media_in_hand[] = {
+static struct rc_map_table total_media_in_hand[] = {
{ 0x02bd00, KEY_1 },
{ 0x02bd01, KEY_2 },
{ 0x02bd02, KEY_3 },
@@ -59,23 +59,23 @@ static struct ir_scancode total_media_in_hand[] = {
{ 0x02bd45, KEY_INFO }, /* [red (I)] */
};
-static struct rc_keymap total_media_in_hand_map = {
+static struct rc_map_list total_media_in_hand_map = {
.map = {
.scan = total_media_in_hand,
.size = ARRAY_SIZE(total_media_in_hand),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_TOTAL_MEDIA_IN_HAND,
}
};
static int __init init_rc_map_total_media_in_hand(void)
{
- return ir_register_map(&total_media_in_hand_map);
+ return rc_map_register(&total_media_in_hand_map);
}
static void __exit exit_rc_map_total_media_in_hand(void)
{
- ir_unregister_map(&total_media_in_hand_map);
+ rc_map_unregister(&total_media_in_hand_map);
}
module_init(init_rc_map_total_media_in_hand)
diff --git a/drivers/media/IR/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c
index 91092caca452..f8190ead2e32 100644
--- a/drivers/media/IR/keymaps/rc-trekstor.c
+++ b/drivers/media/rc/keymaps/rc-trekstor.c
@@ -23,7 +23,7 @@
/* TrekStor DVB-T USB Stick remote controller. */
/* Imported from af9015.h.
Initial keytable was from Marc Schneider <macke@macke.org> */
-static struct ir_scancode trekstor[] = {
+static struct rc_map_table trekstor[] = {
{ 0x0084, KEY_0 },
{ 0x0085, KEY_MUTE }, /* Mute */
{ 0x0086, KEY_HOMEPAGE }, /* Home */
@@ -54,23 +54,23 @@ static struct ir_scancode trekstor[] = {
{ 0x009f, KEY_LEFT }, /* Left */
};
-static struct rc_keymap trekstor_map = {
+static struct rc_map_list trekstor_map = {
.map = {
.scan = trekstor,
.size = ARRAY_SIZE(trekstor),
- .ir_type = IR_TYPE_NEC,
+ .rc_type = RC_TYPE_NEC,
.name = RC_MAP_TREKSTOR,
}
};
static int __init init_rc_map_trekstor(void)
{
- return ir_register_map(&trekstor_map);
+ return rc_map_register(&trekstor_map);
}
static void __exit exit_rc_map_trekstor(void)
{
- ir_unregister_map(&trekstor_map);
+ rc_map_unregister(&trekstor_map);
}
module_init(init_rc_map_trekstor)
diff --git a/drivers/media/IR/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c
index bc88de011d5d..bb194879a794 100644
--- a/drivers/media/IR/keymaps/rc-tt-1500.c
+++ b/drivers/media/rc/keymaps/rc-tt-1500.c
@@ -14,7 +14,7 @@
/* for the Technotrend 1500 bundled remotes (grey and black): */
-static struct ir_scancode tt_1500[] = {
+static struct rc_map_table tt_1500[] = {
{ 0x01, KEY_POWER },
{ 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
{ 0x03, KEY_1 },
@@ -56,23 +56,23 @@ static struct ir_scancode tt_1500[] = {
{ 0x3f, KEY_FORWARD },
};
-static struct rc_keymap tt_1500_map = {
+static struct rc_map_list tt_1500_map = {
.map = {
.scan = tt_1500,
.size = ARRAY_SIZE(tt_1500),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TT_1500,
}
};
static int __init init_rc_map_tt_1500(void)
{
- return ir_register_map(&tt_1500_map);
+ return rc_map_register(&tt_1500_map);
}
static void __exit exit_rc_map_tt_1500(void)
{
- ir_unregister_map(&tt_1500_map);
+ rc_map_unregister(&tt_1500_map);
}
module_init(init_rc_map_tt_1500)
diff --git a/drivers/media/IR/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c
index 0b5d356c2d84..8bf8df64b081 100644
--- a/drivers/media/IR/keymaps/rc-twinhan1027.c
+++ b/drivers/media/rc/keymaps/rc-twinhan1027.c
@@ -1,6 +1,6 @@
#include <media/rc-map.h>
-static struct ir_scancode twinhan_vp1027[] = {
+static struct rc_map_table twinhan_vp1027[] = {
{ 0x16, KEY_POWER2 },
{ 0x17, KEY_FAVORITES },
{ 0x0f, KEY_TEXT },
@@ -61,23 +61,23 @@ static struct ir_scancode twinhan_vp1027[] = {
{ 0x5f, KEY_BLUE },
};
-static struct rc_keymap twinhan_vp1027_map = {
+static struct rc_map_list twinhan_vp1027_map = {
.map = {
.scan = twinhan_vp1027,
.size = ARRAY_SIZE(twinhan_vp1027),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_TWINHAN_VP1027_DVBS,
}
};
static int __init init_rc_map_twinhan_vp1027(void)
{
- return ir_register_map(&twinhan_vp1027_map);
+ return rc_map_register(&twinhan_vp1027_map);
}
static void __exit exit_rc_map_twinhan_vp1027(void)
{
- ir_unregister_map(&twinhan_vp1027_map);
+ rc_map_unregister(&twinhan_vp1027_map);
}
module_init(init_rc_map_twinhan_vp1027)
diff --git a/drivers/media/IR/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c
index 4df7fcd1d2fc..9e474a6024e5 100644
--- a/drivers/media/IR/keymaps/rc-videomate-s350.c
+++ b/drivers/media/rc/keymaps/rc-videomate-s350.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode videomate_s350[] = {
+static struct rc_map_table videomate_s350[] = {
{ 0x00, KEY_TV},
{ 0x01, KEY_DVD},
{ 0x04, KEY_RECORD},
@@ -59,23 +59,23 @@ static struct ir_scancode videomate_s350[] = {
{ 0x20, KEY_TEXT},
};
-static struct rc_keymap videomate_s350_map = {
+static struct rc_map_list videomate_s350_map = {
.map = {
.scan = videomate_s350,
.size = ARRAY_SIZE(videomate_s350),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_VIDEOMATE_S350,
}
};
static int __init init_rc_map_videomate_s350(void)
{
- return ir_register_map(&videomate_s350_map);
+ return rc_map_register(&videomate_s350_map);
}
static void __exit exit_rc_map_videomate_s350(void)
{
- ir_unregister_map(&videomate_s350_map);
+ rc_map_unregister(&videomate_s350_map);
}
module_init(init_rc_map_videomate_s350)
diff --git a/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
index 776b0a638d87..5f2a46e1f8f6 100644
--- a/drivers/media/IR/keymaps/rc-videomate-tv-pvr.c
+++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
@@ -12,7 +12,7 @@
#include <media/rc-map.h>
-static struct ir_scancode videomate_tv_pvr[] = {
+static struct rc_map_table videomate_tv_pvr[] = {
{ 0x14, KEY_MUTE },
{ 0x24, KEY_ZOOM },
@@ -61,23 +61,23 @@ static struct ir_scancode videomate_tv_pvr[] = {
{ 0x21, KEY_SLEEP },
};
-static struct rc_keymap videomate_tv_pvr_map = {
+static struct rc_map_list videomate_tv_pvr_map = {
.map = {
.scan = videomate_tv_pvr,
.size = ARRAY_SIZE(videomate_tv_pvr),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_VIDEOMATE_TV_PVR,
}
};
static int __init init_rc_map_videomate_tv_pvr(void)
{
- return ir_register_map(&videomate_tv_pvr_map);
+ return rc_map_register(&videomate_tv_pvr_map);
}
static void __exit exit_rc_map_videomate_tv_pvr(void)
{
- ir_unregister_map(&videomate_tv_pvr_map);
+ rc_map_unregister(&videomate_tv_pvr_map);
}
module_init(init_rc_map_videomate_tv_pvr)
diff --git a/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
index 9d2d550aaa90..bd8d021f40aa 100644
--- a/drivers/media/IR/keymaps/rc-winfast-usbii-deluxe.c
+++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
@@ -16,7 +16,7 @@
Magnus Alm <magnus.alm@gmail.com>
*/
-static struct ir_scancode winfast_usbii_deluxe[] = {
+static struct rc_map_table winfast_usbii_deluxe[] = {
{ 0x62, KEY_0},
{ 0x75, KEY_1},
{ 0x76, KEY_2},
@@ -56,23 +56,23 @@ static struct ir_scancode winfast_usbii_deluxe[] = {
};
-static struct rc_keymap winfast_usbii_deluxe_map = {
+static struct rc_map_list winfast_usbii_deluxe_map = {
.map = {
.scan = winfast_usbii_deluxe,
.size = ARRAY_SIZE(winfast_usbii_deluxe),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_WINFAST_USBII_DELUXE,
}
};
static int __init init_rc_map_winfast_usbii_deluxe(void)
{
- return ir_register_map(&winfast_usbii_deluxe_map);
+ return rc_map_register(&winfast_usbii_deluxe_map);
}
static void __exit exit_rc_map_winfast_usbii_deluxe(void)
{
- ir_unregister_map(&winfast_usbii_deluxe_map);
+ rc_map_unregister(&winfast_usbii_deluxe_map);
}
module_init(init_rc_map_winfast_usbii_deluxe)
diff --git a/drivers/media/IR/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 0e90a3bd9499..2747db43b70c 100644
--- a/drivers/media/IR/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -14,7 +14,7 @@
/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
-static struct ir_scancode winfast[] = {
+static struct rc_map_table winfast[] = {
/* Keys 0 to 9 */
{ 0x12, KEY_0 },
{ 0x05, KEY_1 },
@@ -76,23 +76,23 @@ static struct ir_scancode winfast[] = {
{ 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
};
-static struct rc_keymap winfast_map = {
+static struct rc_map_list winfast_map = {
.map = {
.scan = winfast,
.size = ARRAY_SIZE(winfast),
- .ir_type = IR_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
.name = RC_MAP_WINFAST,
}
};
static int __init init_rc_map_winfast(void)
{
- return ir_register_map(&winfast_map);
+ return rc_map_register(&winfast_map);
}
static void __exit exit_rc_map_winfast(void)
{
- ir_unregister_map(&winfast_map);
+ rc_map_unregister(&winfast_map);
}
module_init(init_rc_map_winfast)
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 8418b14ee4d2..fd237ab120bb 100644
--- a/drivers/media/IR/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -178,7 +178,9 @@ static int lirc_cdev_add(struct irctl *ir)
cdev_init(cdev, &lirc_dev_fops);
cdev->owner = THIS_MODULE;
}
- kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
+ retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
+ if (retval)
+ return retval;
retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
if (retval)
@@ -522,10 +524,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
- if (!ir->attached) {
- mutex_unlock(&ir->irctl_lock);
+ if (!ir->attached)
return POLLERR;
- }
poll_wait(file, &ir->buf->wait_poll, wait);
@@ -629,7 +629,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
EXPORT_SYMBOL(lirc_dev_fop_ioctl);
ssize_t lirc_dev_fop_read(struct file *file,
- char *buffer,
+ char __user *buffer,
size_t length,
loff_t *ppos)
{
@@ -649,18 +649,18 @@ ssize_t lirc_dev_fop_read(struct file *file,
if (!buf)
return -ENOMEM;
- if (mutex_lock_interruptible(&ir->irctl_lock))
- return -ERESTARTSYS;
+ if (mutex_lock_interruptible(&ir->irctl_lock)) {
+ ret = -ERESTARTSYS;
+ goto out_unlocked;
+ }
if (!ir->attached) {
- mutex_unlock(&ir->irctl_lock);
- return -ENODEV;
+ ret = -ENODEV;
+ goto out_locked;
}
if (length % ir->chunk_size) {
- dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
- ir->d.name, ir->d.minor);
- mutex_unlock(&ir->irctl_lock);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_locked;
}
/*
@@ -711,18 +711,23 @@ ssize_t lirc_dev_fop_read(struct file *file,
lirc_buffer_read(ir->buf, buf);
ret = copy_to_user((void *)buffer+written, buf,
ir->buf->chunk_size);
- written += ir->buf->chunk_size;
+ if (!ret)
+ written += ir->buf->chunk_size;
+ else
+ ret = -EFAULT;
}
}
remove_wait_queue(&ir->buf->wait_poll, &wait);
set_current_state(TASK_RUNNING);
+
+out_locked:
mutex_unlock(&ir->irctl_lock);
out_unlocked:
kfree(buf);
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
- ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
+ ir->d.name, ir->d.minor, ret ? "<fail>" : "<ok>", ret);
return ret ? ret : written;
}
@@ -744,7 +749,7 @@ void *lirc_get_pdata(struct file *file)
EXPORT_SYMBOL(lirc_get_pdata);
-ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
+ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer,
size_t length, loff_t *ppos)
{
struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/rc/mceusb.c
index 9dce684fd231..33c01474dcf6 100644
--- a/drivers/media/IR/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -36,9 +36,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
#define DRIVER_VERSION "1.91"
#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
@@ -49,6 +48,7 @@
#define USB_BUFLEN 32 /* USB reception buffer length */
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
+#define MS_TO_NS(msec) ((msec) * 1000)
/* MCE constants */
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
@@ -74,6 +74,7 @@
#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
+#define MCE_CMD_SIG_END 0x01 /* End of signal */
#define MCE_CMD_PING 0x03 /* Ping device */
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
@@ -91,6 +92,7 @@
#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
+#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */
#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
@@ -146,6 +148,7 @@ enum mceusb_model_type {
MCE_GEN3,
MCE_GEN2_TX_INV,
POLARIS_EVK,
+ CX_HYBRID_TV,
};
struct mceusb_model {
@@ -154,6 +157,7 @@ struct mceusb_model {
u32 mce_gen3:1;
u32 tx_mask_inverted:1;
u32 is_polaris:1;
+ u32 no_tx:1;
const char *rc_map; /* Allow specify a per-board map */
const char *name; /* per-board name */
@@ -183,7 +187,12 @@ static const struct mceusb_model mceusb_model[] = {
* to allow testing it
*/
.rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
- .name = "cx231xx MCE IR",
+ .name = "Conexant Hybrid TV (cx231xx) MCE IR",
+ },
+ [CX_HYBRID_TV] = {
+ .is_polaris = 1,
+ .no_tx = 1, /* tx isn't wired up at all */
+ .name = "Conexant Hybrid TV (cx231xx) MCE IR",
},
};
@@ -292,9 +301,12 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
/* TiVo PC IR Receiver */
{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
- /* Conexant SDK */
+ /* Conexant Hybrid TV "Shelby" Polaris SDK */
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
.driver_info = POLARIS_EVK },
+ /* Conexant Hybrid TV RDU253S Polaris */
+ { USB_DEVICE(VENDOR_CONEXANT, 0x58a5),
+ .driver_info = CX_HYBRID_TV },
/* Terminating entry */
{ }
};
@@ -302,12 +314,14 @@ static struct usb_device_id mceusb_dev_table[] = {
/* data structure for each usb transceiver */
struct mceusb_dev {
/* ir-core bits */
- struct ir_dev_props *props;
- struct ir_raw_event rawir;
+ struct rc_dev *rc;
+
+ /* optional features we can enable */
+ bool carrier_report_enabled;
+ bool learning_enabled;
/* core device bits */
struct device *dev;
- struct input_dev *idev;
/* usb */
struct usb_device *usbdev;
@@ -318,6 +332,8 @@ struct mceusb_dev {
/* buffers and dma */
unsigned char *buf_in;
unsigned int len_in;
+ dma_addr_t dma_in;
+ dma_addr_t dma_out;
enum {
CMD_HEADER = 0,
@@ -325,15 +341,14 @@ struct mceusb_dev {
CMD_DATA,
PARSE_IRDATA,
} parser_state;
- u8 cmd, rem; /* Remaining IR data bytes in packet */
- dma_addr_t dma_in;
- dma_addr_t dma_out;
+ u8 cmd, rem; /* Remaining IR data bytes in packet */
struct {
u32 connected:1;
u32 tx_mask_inverted:1;
u32 microsoft_gen1:1;
+ u32 no_tx:1;
} flags;
/* transmit support */
@@ -408,9 +423,10 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
case MCE_CMD_UNKNOWN:
case MCE_CMD_S_CARRIER:
case MCE_CMD_S_TIMEOUT:
- case MCE_CMD_G_RXSENSOR:
+ case MCE_RSP_PULSE_COUNT:
datasize = 2;
break;
+ case MCE_CMD_SIG_END:
case MCE_CMD_S_TXMASK:
case MCE_CMD_S_RXSENSOR:
datasize = 1;
@@ -433,7 +449,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
return;
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
- if (ir->flags.microsoft_gen1 && !out)
+ if (ir->flags.microsoft_gen1 && !out && !offset)
skip = 2;
if (len <= skip)
@@ -491,6 +507,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
break;
case MCE_COMMAND_HEADER:
switch (subcmd) {
+ case MCE_CMD_SIG_END:
+ dev_info(dev, "End of signal\n");
+ break;
case MCE_CMD_PING:
dev_info(dev, "Ping\n");
break;
@@ -525,10 +544,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
inout, data1 == 0x02 ? "short" : "long");
break;
case MCE_CMD_G_RXSENSOR:
- if (len == 2)
+ /* aka MCE_RSP_PULSE_COUNT */
+ if (out)
dev_info(dev, "Get receive sensor\n");
- else
- dev_info(dev, "Received pulse count is %d\n",
+ else if (ir->learning_enabled)
+ dev_info(dev, "RX pulse count: %d\n",
((data1 << 8) | data2));
break;
case MCE_RSP_CMD_INVALID:
@@ -639,9 +659,9 @@ static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
}
/* Send data out the IR blaster port(s) */
-static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
+static int mceusb_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
int i, ret = 0;
int count, cmdcount = 0;
unsigned char *cmdbuf; /* MCE command buffer */
@@ -724,10 +744,10 @@ out:
return ret ? ret : n;
}
-/* Sets active IR outputs -- mce devices typically (all?) have two */
-static int mceusb_set_tx_mask(void *priv, u32 mask)
+/* Sets active IR outputs -- mce devices typically have two */
+static int mceusb_set_tx_mask(struct rc_dev *dev, u32 mask)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
if (ir->flags.tx_mask_inverted)
ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
@@ -739,9 +759,9 @@ static int mceusb_set_tx_mask(void *priv, u32 mask)
}
/* Sets the send carrier frequency and mode */
-static int mceusb_set_tx_carrier(void *priv, u32 carrier)
+static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
int clk = 10000000;
int prescaler = 0, divisor = 0;
unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
@@ -752,7 +772,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
if (carrier == 0) {
ir->carrier = carrier;
- cmdbuf[2] = 0x01;
+ cmdbuf[2] = MCE_CMD_SIG_END;
cmdbuf[3] = MCE_IRDATA_TRAILER;
dev_dbg(ir->dev, "%s: disabling carrier "
"modulation\n", __func__);
@@ -782,6 +802,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
return carrier;
}
+/*
+ * We don't do anything but print debug spew for many of the command bits
+ * we receive from the hardware, but some of them are useful information
+ * we want to store so that we can use them.
+ */
+static void mceusb_handle_command(struct mceusb_dev *ir, int index)
+{
+ u8 hi = ir->buf_in[index + 1] & 0xff;
+ u8 lo = ir->buf_in[index + 2] & 0xff;
+
+ switch (ir->buf_in[index]) {
+ /* 2-byte return value commands */
+ case MCE_CMD_S_TIMEOUT:
+ ir->rc->timeout = MS_TO_NS((hi << 8 | lo) / 2);
+ break;
+
+ /* 1-byte return value commands */
+ case MCE_CMD_S_TXMASK:
+ ir->tx_mask = hi;
+ break;
+ case MCE_CMD_S_RXSENSOR:
+ ir->learning_enabled = (hi == 0x02);
+ break;
+ default:
+ break;
+ }
+}
+
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
{
DEFINE_IR_RAW_EVENT(rawir);
@@ -791,39 +839,30 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
if (ir->flags.microsoft_gen1)
i = 2;
+ /* if there's no data, just return now */
+ if (buf_len <= i)
+ return;
+
for (; i < buf_len; i++) {
switch (ir->parser_state) {
case SUBCMD:
ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
mceusb_dev_printdata(ir, ir->buf_in, i - 1,
ir->rem + 2, false);
+ mceusb_handle_command(ir, i);
ir->parser_state = CMD_DATA;
break;
case PARSE_IRDATA:
ir->rem--;
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
- * MCE_TIME_UNIT * 1000;
-
- if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
- if (ir->rawir.pulse == rawir.pulse) {
- ir->rawir.duration += rawir.duration;
- } else {
- ir->rawir.duration = rawir.duration;
- ir->rawir.pulse = rawir.pulse;
- }
- if (ir->rem)
- break;
- }
- rawir.duration += ir->rawir.duration;
- ir->rawir.duration = 0;
- ir->rawir.pulse = rawir.pulse;
+ * MS_TO_NS(MCE_TIME_UNIT);
dev_dbg(ir->dev, "Storing %s with duration %d\n",
rawir.pulse ? "pulse" : "space",
rawir.duration);
- ir_raw_event_store(ir->idev, &rawir);
+ ir_raw_event_store_with_filter(ir->rc, &rawir);
break;
case CMD_DATA:
ir->rem--;
@@ -839,17 +878,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
continue;
}
ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
- mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
- if (ir->rem) {
+ mceusb_dev_printdata(ir, ir->buf_in,
+ i, ir->rem + 1, false);
+ if (ir->rem)
ir->parser_state = PARSE_IRDATA;
- break;
- }
- /*
- * a package with len=0 (e. g. 0x80) means end of
- * data. We could use it to do the call to
- * ir_raw_event_handle(). For now, we don't need to
- * use it.
- */
break;
}
@@ -857,7 +889,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
ir->parser_state = CMD_HEADER;
}
dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
- ir_raw_event_handle(ir->idev);
+ ir_raw_event_handle(ir->rc);
}
static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
@@ -984,9 +1016,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
mce_sync_in(ir, NULL, maxp);
- /* get the transmitter bitmask */
- mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
- mce_sync_in(ir, NULL, maxp);
+ if (!ir->flags.no_tx) {
+ /* get the transmitter bitmask */
+ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+ mce_sync_in(ir, NULL, maxp);
+ }
/* get receiver timeout value */
mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
@@ -997,66 +1031,53 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
mce_sync_in(ir, NULL, maxp);
}
-static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
+static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
{
- struct input_dev *idev;
- struct ir_dev_props *props;
struct device *dev = ir->dev;
- const char *rc_map = RC_MAP_RC6_MCE;
- const char *name = "Media Center Ed. eHome Infrared Remote Transceiver";
- int ret = -ENODEV;
-
- idev = input_allocate_device();
- if (!idev) {
- dev_err(dev, "remote input dev allocation failed\n");
- goto idev_alloc_failed;
- }
+ struct rc_dev *rc;
+ int ret;
- ret = -ENOMEM;
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props) {
- dev_err(dev, "remote ir dev props allocation failed\n");
- goto props_alloc_failed;
+ rc = rc_allocate_device();
+ if (!rc) {
+ dev_err(dev, "remote dev allocation failed\n");
+ goto out;
}
- if (mceusb_model[ir->model].name)
- name = mceusb_model[ir->model].name;
-
snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)",
- name,
+ mceusb_model[ir->model].name ?
+ mceusb_model[ir->model].name :
+ "Media Center Ed. eHome Infrared Remote Transceiver",
le16_to_cpu(ir->usbdev->descriptor.idVendor),
le16_to_cpu(ir->usbdev->descriptor.idProduct));
- idev->name = ir->name;
usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
- strlcat(ir->phys, "/input0", sizeof(ir->phys));
- idev->phys = ir->phys;
-
- props->priv = ir;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- props->s_tx_mask = mceusb_set_tx_mask;
- props->s_tx_carrier = mceusb_set_tx_carrier;
- props->tx_ir = mceusb_tx_ir;
- ir->props = props;
-
- if (mceusb_model[ir->model].rc_map)
- rc_map = mceusb_model[ir->model].rc_map;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ usb_to_input_id(ir->usbdev, &rc->input_id);
+ rc->dev.parent = dev;
+ rc->priv = ir;
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protos = RC_TYPE_ALL;
+ if (!ir->flags.no_tx) {
+ rc->s_tx_mask = mceusb_set_tx_mask;
+ rc->s_tx_carrier = mceusb_set_tx_carrier;
+ rc->tx_ir = mceusb_tx_ir;
+ }
+ rc->driver_name = DRIVER_NAME;
+ rc->map_name = mceusb_model[ir->model].rc_map ?
+ mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE;
- ret = ir_input_register(idev, rc_map, props, DRIVER_NAME);
+ ret = rc_register_device(rc);
if (ret < 0) {
- dev_err(dev, "remote input device register failed\n");
- goto irdev_failed;
+ dev_err(dev, "remote dev registration failed\n");
+ goto out;
}
- return idev;
+ return rc;
-irdev_failed:
- kfree(props);
-props_alloc_failed:
- input_free_device(idev);
-idev_alloc_failed:
+out:
+ rc_free_device(rc);
return NULL;
}
@@ -1077,7 +1098,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
bool tx_mask_inverted;
bool is_polaris;
- dev_dbg(&intf->dev, ": %s called\n", __func__);
+ dev_dbg(&intf->dev, "%s called\n", __func__);
idesc = intf->cur_altsetting;
@@ -1107,7 +1128,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ep_in = ep;
ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
ep_in->bInterval = 1;
- dev_dbg(&intf->dev, ": acceptable inbound endpoint "
+ dev_dbg(&intf->dev, "acceptable inbound endpoint "
"found\n");
}
@@ -1122,12 +1143,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ep_out = ep;
ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
ep_out->bInterval = 1;
- dev_dbg(&intf->dev, ": acceptable outbound endpoint "
+ dev_dbg(&intf->dev, "acceptable outbound endpoint "
"found\n");
}
}
if (ep_in == NULL) {
- dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n");
+ dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
return -ENODEV;
}
@@ -1151,10 +1172,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
ir->len_in = maxp;
ir->flags.microsoft_gen1 = is_microsoft_gen1;
ir->flags.tx_mask_inverted = tx_mask_inverted;
+ ir->flags.no_tx = mceusb_model[model].no_tx;
ir->model = model;
- init_ir_raw_event(&ir->rawir);
-
/* Saving usb interface data for use by the transmitter routine */
ir->usb_ep_in = ep_in;
ir->usb_ep_out = ep_out;
@@ -1169,9 +1189,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- ir->idev = mceusb_init_input_dev(ir);
- if (!ir->idev)
- goto input_dev_fail;
+ ir->rc = mceusb_init_rc_dev(ir);
+ if (!ir->rc)
+ goto rc_dev_fail;
/* flush buffers on the device */
mce_sync_in(ir, NULL, maxp);
@@ -1191,7 +1211,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir);
- mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
+ if (!ir->flags.no_tx)
+ mceusb_set_tx_mask(ir->rc, MCE_DEFAULT_TX_MASK);
usb_set_intfdata(intf, ir);
@@ -1201,7 +1222,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
return 0;
/* Error-handling path */
-input_dev_fail:
+rc_dev_fail:
usb_free_urb(ir->urb_in);
urb_in_alloc_fail:
usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
@@ -1225,7 +1246,7 @@ static void __devexit mceusb_dev_disconnect(struct usb_interface *intf)
return;
ir->usbdev = NULL;
- ir_input_unregister(ir->idev);
+ rc_unregister_device(ir->rc);
usb_kill_urb(ir->urb_in);
usb_free_urb(ir->urb_in);
usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 301be53aee85..dd4caf8ef80b 100644
--- a/drivers/media/IR/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -32,8 +32,7 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <linux/pci_ids.h>
#include "nuvoton-cir.h"
@@ -249,9 +248,12 @@ static int nvt_hw_detect(struct nvt_dev *nvt)
chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor);
- if (chip_major != CHIP_ID_HIGH &&
- (chip_minor != CHIP_ID_LOW || chip_minor != CHIP_ID_LOW2))
+ if (chip_major != CHIP_ID_HIGH ||
+ (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) {
+ nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x",
+ chip_id, chip_major, chip_minor);
ret = -ENODEV;
+ }
nvt_efm_disable(nvt);
@@ -476,9 +478,9 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
* always set CP as 0x81
* set CC by SPEC, CC = 3MHz/carrier - 1
*/
-static int nvt_set_tx_carrier(void *data, u32 carrier)
+static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
- struct nvt_dev *nvt = data;
+ struct nvt_dev *nvt = dev->priv;
u16 val;
nvt_cir_reg_write(nvt, 1, CIR_CP);
@@ -509,9 +511,9 @@ static int nvt_set_tx_carrier(void *data, u32 carrier)
* number may larger than TXFCONT (0xff). So in interrupt_handler, it has to
* set TXFCONT as 0xff, until buf_count less than 0xff.
*/
-static int nvt_tx_ir(void *priv, int *txbuf, u32 n)
+static int nvt_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
{
- struct nvt_dev *nvt = priv;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
size_t cur_count;
unsigned int i;
@@ -603,6 +605,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
count = nvt->pkts;
nvt_dbg_verbose("Processing buffer of len %d", count);
+ init_ir_raw_event(&rawir);
+
for (i = 0; i < count; i++) {
nvt->pkts--;
sample = nvt->buf[i];
@@ -643,11 +647,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
* indicates end of IR signal, but new data incoming. In both
* cases, it means we're ready to call ir_raw_event_handle
*/
- if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) &&
- (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE))
+ if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
+ nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
ir_raw_event_handle(nvt->rdev);
+ }
}
+ nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
+ ir_raw_event_handle(nvt->rdev);
+
if (nvt->pkts) {
nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
nvt->pkts = 0;
@@ -942,9 +950,9 @@ static void nvt_disable_cir(struct nvt_dev *nvt)
nvt_efm_disable(nvt);
}
-static int nvt_open(void *data)
+static int nvt_open(struct rc_dev *dev)
{
- struct nvt_dev *nvt = (struct nvt_dev *)data;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
@@ -955,9 +963,9 @@ static int nvt_open(void *data)
return 0;
}
-static void nvt_close(void *data)
+static void nvt_close(struct rc_dev *dev)
{
- struct nvt_dev *nvt = (struct nvt_dev *)data;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
@@ -969,21 +977,16 @@ static void nvt_close(void *data)
/* Allocate memory, probe hardware, and initialize everything */
static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
{
- struct nvt_dev *nvt = NULL;
- struct input_dev *rdev = NULL;
- struct ir_dev_props *props = NULL;
+ struct nvt_dev *nvt;
+ struct rc_dev *rdev;
int ret = -ENOMEM;
nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL);
if (!nvt)
return ret;
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props)
- goto failure;
-
/* input device for IR remote (and tx) */
- rdev = input_allocate_device();
+ rdev = rc_allocate_device();
if (!rdev)
goto failure;
@@ -1057,41 +1060,38 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
nvt_cir_regs_init(nvt);
nvt_cir_wake_regs_init(nvt);
- /* Set up ir-core props */
- props->priv = nvt;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- props->open = nvt_open;
- props->close = nvt_close;
+ /* Set up the rc device */
+ rdev->priv = nvt;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = RC_TYPE_ALL;
+ rdev->open = nvt_open;
+ rdev->close = nvt_close;
+ rdev->tx_ir = nvt_tx_ir;
+ rdev->s_tx_carrier = nvt_set_tx_carrier;
+ rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
+ rdev->input_id.bustype = BUS_HOST;
+ rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2;
+ rdev->input_id.product = nvt->chip_major;
+ rdev->input_id.version = nvt->chip_minor;
+ rdev->driver_name = NVT_DRIVER_NAME;
+ rdev->map_name = RC_MAP_RC6_MCE;
#if 0
- props->min_timeout = XYZ;
- props->max_timeout = XYZ;
- props->timeout = XYZ;
+ rdev->min_timeout = XYZ;
+ rdev->max_timeout = XYZ;
+ rdev->timeout = XYZ;
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
- props->rx_resolution = XYZ;
-
+ rdev->rx_resolution = XYZ;
/* tx bits */
- props->tx_resolution = XYZ;
+ rdev->tx_resolution = XYZ;
#endif
- props->tx_ir = nvt_tx_ir;
- props->s_tx_carrier = nvt_set_tx_carrier;
-
- rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver";
- rdev->id.bustype = BUS_HOST;
- rdev->id.vendor = PCI_VENDOR_ID_WINBOND2;
- rdev->id.product = nvt->chip_major;
- rdev->id.version = nvt->chip_minor;
- nvt->props = props;
- nvt->rdev = rdev;
-
- device_set_wakeup_capable(&pdev->dev, 1);
- device_set_wakeup_enable(&pdev->dev, 1);
-
- ret = ir_input_register(rdev, RC_MAP_RC6_MCE, props, NVT_DRIVER_NAME);
+ ret = rc_register_device(rdev);
if (ret)
goto failure;
+ device_set_wakeup_capable(&pdev->dev, 1);
+ device_set_wakeup_enable(&pdev->dev, 1);
+ nvt->rdev = rdev;
nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
if (debug) {
cir_dump_regs(nvt);
@@ -1111,8 +1111,7 @@ failure:
if (nvt->cir_wake_addr)
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
- input_free_device(rdev);
- kfree(props);
+ rc_free_device(rdev);
kfree(nvt);
return ret;
@@ -1137,9 +1136,8 @@ static void __devexit nvt_remove(struct pnp_dev *pdev)
release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
- ir_input_unregister(nvt->rdev);
+ rc_unregister_device(nvt->rdev);
- kfree(nvt->props);
kfree(nvt);
}
diff --git a/drivers/media/IR/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h
index 62dc53017c8e..1df82351cb03 100644
--- a/drivers/media/IR/nuvoton-cir.h
+++ b/drivers/media/rc/nuvoton-cir.h
@@ -66,8 +66,7 @@ static int debug;
struct nvt_dev {
struct pnp_dev *pdev;
- struct input_dev *rdev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
struct ir_raw_event rawir;
spinlock_t nvt_lock;
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 81c936bd793f..873b38789751 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -13,22 +13,22 @@
* GNU General Public License for more details.
*/
-#ifndef _IR_RAW_EVENT
-#define _IR_RAW_EVENT
+#ifndef _RC_CORE_PRIV
+#define _RC_CORE_PRIV
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
struct ir_raw_handler {
struct list_head list;
u64 protocols; /* which are handled by this handler */
- int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
+ int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
/* These two should only be used by the lirc decoder */
- int (*raw_register)(struct input_dev *input_dev);
- int (*raw_unregister)(struct input_dev *input_dev);
+ int (*raw_register)(struct rc_dev *dev);
+ int (*raw_unregister)(struct rc_dev *dev);
};
struct ir_raw_event_ctrl {
@@ -38,7 +38,7 @@ struct ir_raw_event_ctrl {
struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */
- struct input_dev *input_dev; /* pointer to the parent input_dev */
+ struct rc_dev *dev; /* pointer to the parent rc_dev */
u64 enabled_protocols; /* enabled raw protocol decoders */
/* raw decoder state follows */
@@ -85,7 +85,7 @@ struct ir_raw_event_ctrl {
unsigned wanted_bits;
} rc5_sz;
struct lirc_codec {
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
struct lirc_driver *drv;
int carrier_low;
@@ -129,27 +129,17 @@ static inline bool is_timing_event(struct ir_raw_event ev)
#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
-/*
- * Routines from ir-sysfs.c - Meant to be called only internally inside
- * ir-core
- */
-int ir_register_input(struct input_dev *input_dev);
-
-int ir_register_class(struct input_dev *input_dev);
-void ir_unregister_class(struct input_dev *input_dev);
/*
- * Routines from ir-raw-event.c to be used internally and by decoders
+ * Routines from rc-raw.c to be used internally and by decoders
*/
u64 ir_raw_get_allowed_protocols(void);
-int ir_raw_event_register(struct input_dev *input_dev);
-void ir_raw_event_unregister(struct input_dev *input_dev);
+int ir_raw_event_register(struct rc_dev *dev);
+void ir_raw_event_unregister(struct rc_dev *dev);
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
void ir_raw_init(void);
-int ir_rcmap_init(void);
-void ir_rcmap_cleanup(void);
/*
* Decoder initialization code
*
@@ -200,4 +190,4 @@ void ir_rcmap_cleanup(void);
#endif
-#endif /* _IR_RAW_EVENT */
+#endif /* _RC_CORE_PRIV */
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
new file mode 100644
index 000000000000..49cee61d79c6
--- /dev/null
+++ b/drivers/media/rc/rc-loopback.c
@@ -0,0 +1,260 @@
+/*
+ * Loopback driver for rc-core,
+ *
+ * Copyright (c) 2010 David Härdeman <david@hardeman.nu>
+ *
+ * This driver receives TX data and passes it back as RX data,
+ * which is useful for (scripted) debugging of rc-core without
+ * having to use actual hardware.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <media/rc-core.h>
+
+#define DRIVER_NAME "rc-loopback"
+#define dprintk(x...) if (debug) printk(KERN_INFO DRIVER_NAME ": " x)
+#define RXMASK_REGULAR 0x1
+#define RXMASK_LEARNING 0x2
+
+static bool debug;
+
+struct loopback_dev {
+ struct rc_dev *dev;
+ u32 txmask;
+ u32 txcarrier;
+ u32 txduty;
+ bool idle;
+ bool learning;
+ bool carrierreport;
+ u32 rxcarriermin;
+ u32 rxcarriermax;
+};
+
+static struct loopback_dev loopdev;
+
+static int loop_set_tx_mask(struct rc_dev *dev, u32 mask)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) {
+ dprintk("invalid tx mask: %u\n", mask);
+ return -EINVAL;
+ }
+
+ dprintk("setting tx mask: %u\n", mask);
+ lodev->txmask = mask;
+ return 0;
+}
+
+static int loop_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ dprintk("setting tx carrier: %u\n", carrier);
+ lodev->txcarrier = carrier;
+ return 0;
+}
+
+static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (duty_cycle < 1 || duty_cycle > 99) {
+ dprintk("invalid duty cycle: %u\n", duty_cycle);
+ return -EINVAL;
+ }
+
+ dprintk("setting duty cycle: %u\n", duty_cycle);
+ lodev->txduty = duty_cycle;
+ return 0;
+}
+
+static int loop_set_rx_carrier_range(struct rc_dev *dev, u32 min, u32 max)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (min < 1 || min > max) {
+ dprintk("invalid rx carrier range %u to %u\n", min, max);
+ return -EINVAL;
+ }
+
+ dprintk("setting rx carrier range %u to %u\n", min, max);
+ lodev->rxcarriermin = min;
+ lodev->rxcarriermax = max;
+ return 0;
+}
+
+static int loop_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
+{
+ struct loopback_dev *lodev = dev->priv;
+ u32 rxmask;
+ unsigned count;
+ unsigned total_duration = 0;
+ unsigned i;
+ DEFINE_IR_RAW_EVENT(rawir);
+
+ if (n == 0 || n % sizeof(int)) {
+ dprintk("invalid tx buffer size\n");
+ return -EINVAL;
+ }
+
+ count = n / sizeof(int);
+ for (i = 0; i < count; i++)
+ total_duration += abs(txbuf[i]);
+
+ if (total_duration == 0) {
+ dprintk("invalid tx data, total duration zero\n");
+ return -EINVAL;
+ }
+
+ if (lodev->txcarrier < lodev->rxcarriermin ||
+ lodev->txcarrier > lodev->rxcarriermax) {
+ dprintk("ignoring tx, carrier out of range\n");
+ goto out;
+ }
+
+ if (lodev->learning)
+ rxmask = RXMASK_LEARNING;
+ else
+ rxmask = RXMASK_REGULAR;
+
+ if (!(rxmask & lodev->txmask)) {
+ dprintk("ignoring tx, rx mask mismatch\n");
+ goto out;
+ }
+
+ for (i = 0; i < count; i++) {
+ rawir.pulse = i % 2 ? false : true;
+ rawir.duration = abs(txbuf[i]) * 1000;
+ if (rawir.duration)
+ ir_raw_event_store_with_filter(dev, &rawir);
+ }
+ ir_raw_event_handle(dev);
+
+out:
+ /* Lirc expects this function to take as long as the total duration */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(usecs_to_jiffies(total_duration));
+ return n;
+}
+
+static void loop_set_idle(struct rc_dev *dev, bool enable)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (lodev->idle != enable) {
+ dprintk("%sing idle mode\n", enable ? "enter" : "exit");
+ lodev->idle = enable;
+ }
+}
+
+static int loop_set_learning_mode(struct rc_dev *dev, int enable)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (lodev->learning != enable) {
+ dprintk("%sing learning mode\n", enable ? "enter" : "exit");
+ lodev->learning = !!enable;
+ }
+
+ return 0;
+}
+
+static int loop_set_carrier_report(struct rc_dev *dev, int enable)
+{
+ struct loopback_dev *lodev = dev->priv;
+
+ if (lodev->carrierreport != enable) {
+ dprintk("%sabling carrier reports\n", enable ? "en" : "dis");
+ lodev->carrierreport = !!enable;
+ }
+
+ return 0;
+}
+
+static int __init loop_init(void)
+{
+ struct rc_dev *rc;
+ int ret;
+
+ rc = rc_allocate_device();
+ if (!rc) {
+ printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
+ return -ENOMEM;
+ }
+
+ rc->input_name = "rc-core loopback device";
+ rc->input_phys = "rc-core/virtual";
+ rc->input_id.bustype = BUS_VIRTUAL;
+ rc->input_id.version = 1;
+ rc->driver_name = DRIVER_NAME;
+ rc->map_name = RC_MAP_EMPTY;
+ rc->priv = &loopdev;
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protos = RC_TYPE_ALL;
+ rc->timeout = 100 * 1000 * 1000; /* 100 ms */
+ rc->min_timeout = 1;
+ rc->max_timeout = UINT_MAX;
+ rc->rx_resolution = 1000;
+ rc->tx_resolution = 1000;
+ rc->s_tx_mask = loop_set_tx_mask;
+ rc->s_tx_carrier = loop_set_tx_carrier;
+ rc->s_tx_duty_cycle = loop_set_tx_duty_cycle;
+ rc->s_rx_carrier_range = loop_set_rx_carrier_range;
+ rc->tx_ir = loop_tx_ir;
+ rc->s_idle = loop_set_idle;
+ rc->s_learning_mode = loop_set_learning_mode;
+ rc->s_carrier_report = loop_set_carrier_report;
+ rc->priv = &loopdev;
+
+ loopdev.txmask = RXMASK_REGULAR;
+ loopdev.txcarrier = 36000;
+ loopdev.txduty = 50;
+ loopdev.rxcarriermin = 1;
+ loopdev.rxcarriermax = ~0;
+ loopdev.idle = true;
+ loopdev.learning = false;
+ loopdev.carrierreport = false;
+
+ ret = rc_register_device(rc);
+ if (ret < 0) {
+ printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n");
+ rc_free_device(rc);
+ return ret;
+ }
+
+ loopdev.dev = rc;
+ return 0;
+}
+
+static void __exit loop_exit(void)
+{
+ rc_unregister_device(loopdev.dev);
+}
+
+module_init(loop_init);
+module_exit(loop_exit);
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debug messages");
+
+MODULE_DESCRIPTION("Loopback device for rc-core debugging");
+MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
new file mode 100644
index 000000000000..72be8a02118c
--- /dev/null
+++ b/drivers/media/rc/rc-main.c
@@ -0,0 +1,1135 @@
+/* rc-main.c - Remote Controller core module
+ *
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <media/rc-core.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include "rc-core-priv.h"
+
+/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
+#define IR_TAB_MIN_SIZE 256
+#define IR_TAB_MAX_SIZE 8192
+
+/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
+#define IR_KEYPRESS_TIMEOUT 250
+
+/* Used to keep track of known keymaps */
+static LIST_HEAD(rc_map_list);
+static DEFINE_SPINLOCK(rc_map_lock);
+
+static struct rc_map_list *seek_rc_map(const char *name)
+{
+ struct rc_map_list *map = NULL;
+
+ spin_lock(&rc_map_lock);
+ list_for_each_entry(map, &rc_map_list, list) {
+ if (!strcmp(name, map->map.name)) {
+ spin_unlock(&rc_map_lock);
+ return map;
+ }
+ }
+ spin_unlock(&rc_map_lock);
+
+ return NULL;
+}
+
+struct rc_map *rc_map_get(const char *name)
+{
+
+ struct rc_map_list *map;
+
+ map = seek_rc_map(name);
+#ifdef MODULE
+ if (!map) {
+ int rc = request_module(name);
+ if (rc < 0) {
+ printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
+ return NULL;
+ }
+ msleep(20); /* Give some time for IR to register */
+
+ map = seek_rc_map(name);
+ }
+#endif
+ if (!map) {
+ printk(KERN_ERR "IR keymap %s not found\n", name);
+ return NULL;
+ }
+
+ printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
+
+ return &map->map;
+}
+EXPORT_SYMBOL_GPL(rc_map_get);
+
+int rc_map_register(struct rc_map_list *map)
+{
+ spin_lock(&rc_map_lock);
+ list_add_tail(&map->list, &rc_map_list);
+ spin_unlock(&rc_map_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rc_map_register);
+
+void rc_map_unregister(struct rc_map_list *map)
+{
+ spin_lock(&rc_map_lock);
+ list_del(&map->list);
+ spin_unlock(&rc_map_lock);
+}
+EXPORT_SYMBOL_GPL(rc_map_unregister);
+
+
+static struct rc_map_table empty[] = {
+ { 0x2a, KEY_COFFEE },
+};
+
+static struct rc_map_list empty_map = {
+ .map = {
+ .scan = empty,
+ .size = ARRAY_SIZE(empty),
+ .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .name = RC_MAP_EMPTY,
+ }
+};
+
+/**
+ * ir_create_table() - initializes a scancode table
+ * @rc_map: the rc_map to initialize
+ * @name: name to assign to the table
+ * @rc_type: ir type to assign to the new table
+ * @size: initial size of the table
+ * @return: zero on success or a negative error code
+ *
+ * This routine will initialize the rc_map and will allocate
+ * memory to hold at least the specified number of elements.
+ */
+static int ir_create_table(struct rc_map *rc_map,
+ const char *name, u64 rc_type, size_t size)
+{
+ rc_map->name = name;
+ rc_map->rc_type = rc_type;
+ rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table));
+ rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
+ rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL);
+ if (!rc_map->scan)
+ return -ENOMEM;
+
+ IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
+ rc_map->size, rc_map->alloc);
+ return 0;
+}
+
+/**
+ * ir_free_table() - frees memory allocated by a scancode table
+ * @rc_map: the table whose mappings need to be freed
+ *
+ * This routine will free memory alloctaed for key mappings used by given
+ * scancode table.
+ */
+static void ir_free_table(struct rc_map *rc_map)
+{
+ rc_map->size = 0;
+ kfree(rc_map->scan);
+ rc_map->scan = NULL;
+}
+
+/**
+ * ir_resize_table() - resizes a scancode table if necessary
+ * @rc_map: the rc_map to resize
+ * @gfp_flags: gfp flags to use when allocating memory
+ * @return: zero on success or a negative error code
+ *
+ * This routine will shrink the rc_map if it has lots of
+ * unused entries and grow it if it is full.
+ */
+static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags)
+{
+ unsigned int oldalloc = rc_map->alloc;
+ unsigned int newalloc = oldalloc;
+ struct rc_map_table *oldscan = rc_map->scan;
+ struct rc_map_table *newscan;
+
+ if (rc_map->size == rc_map->len) {
+ /* All entries in use -> grow keytable */
+ if (rc_map->alloc >= IR_TAB_MAX_SIZE)
+ return -ENOMEM;
+
+ newalloc *= 2;
+ IR_dprintk(1, "Growing table to %u bytes\n", newalloc);
+ }
+
+ if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
+ /* Less than 1/3 of entries in use -> shrink keytable */
+ newalloc /= 2;
+ IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc);
+ }
+
+ if (newalloc == oldalloc)
+ return 0;
+
+ newscan = kmalloc(newalloc, gfp_flags);
+ if (!newscan) {
+ IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc);
+ return -ENOMEM;
+ }
+
+ memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table));
+ rc_map->scan = newscan;
+ rc_map->alloc = newalloc;
+ rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
+ kfree(oldscan);
+ return 0;
+}
+
+/**
+ * ir_update_mapping() - set a keycode in the scancode->keycode table
+ * @dev: the struct rc_dev device descriptor
+ * @rc_map: scancode table to be adjusted
+ * @index: index of the mapping that needs to be updated
+ * @keycode: the desired keycode
+ * @return: previous keycode assigned to the mapping
+ *
+ * This routine is used to update scancode->keycode mapping at given
+ * position.
+ */
+static unsigned int ir_update_mapping(struct rc_dev *dev,
+ struct rc_map *rc_map,
+ unsigned int index,
+ unsigned int new_keycode)
+{
+ int old_keycode = rc_map->scan[index].keycode;
+ int i;
+
+ /* Did the user wish to remove the mapping? */
+ if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
+ IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
+ index, rc_map->scan[index].scancode);
+ rc_map->len--;
+ memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
+ (rc_map->len - index) * sizeof(struct rc_map_table));
+ } else {
+ IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n",
+ index,
+ old_keycode == KEY_RESERVED ? "New" : "Replacing",
+ rc_map->scan[index].scancode, new_keycode);
+ rc_map->scan[index].keycode = new_keycode;
+ __set_bit(new_keycode, dev->input_dev->keybit);
+ }
+
+ if (old_keycode != KEY_RESERVED) {
+ /* A previous mapping was updated... */
+ __clear_bit(old_keycode, dev->input_dev->keybit);
+ /* ... but another scancode might use the same keycode */
+ for (i = 0; i < rc_map->len; i++) {
+ if (rc_map->scan[i].keycode == old_keycode) {
+ __set_bit(old_keycode, dev->input_dev->keybit);
+ break;
+ }
+ }
+
+ /* Possibly shrink the keytable, failure is not a problem */
+ ir_resize_table(rc_map, GFP_ATOMIC);
+ }
+
+ return old_keycode;
+}
+
+/**
+ * ir_establish_scancode() - set a keycode in the scancode->keycode table
+ * @dev: the struct rc_dev device descriptor
+ * @rc_map: scancode table to be searched
+ * @scancode: the desired scancode
+ * @resize: controls whether we allowed to resize the table to
+ * accomodate not yet present scancodes
+ * @return: index of the mapping containing scancode in question
+ * or -1U in case of failure.
+ *
+ * This routine is used to locate given scancode in rc_map.
+ * If scancode is not yet present the routine will allocate a new slot
+ * for it.
+ */
+static unsigned int ir_establish_scancode(struct rc_dev *dev,
+ struct rc_map *rc_map,
+ unsigned int scancode,
+ bool resize)
+{
+ unsigned int i;
+
+ /*
+ * Unfortunately, some hardware-based IR decoders don't provide
+ * all bits for the complete IR code. In general, they provide only
+ * the command part of the IR code. Yet, as it is possible to replace
+ * the provided IR with another one, it is needed to allow loading
+ * IR tables from other remotes. So, we support specifying a mask to
+ * indicate the valid bits of the scancodes.
+ */
+ if (dev->scanmask)
+ scancode &= dev->scanmask;
+
+ /* First check if we already have a mapping for this ir command */
+ for (i = 0; i < rc_map->len; i++) {
+ if (rc_map->scan[i].scancode == scancode)
+ return i;
+
+ /* Keytable is sorted from lowest to highest scancode */
+ if (rc_map->scan[i].scancode >= scancode)
+ break;
+ }
+
+ /* No previous mapping found, we might need to grow the table */
+ if (rc_map->size == rc_map->len) {
+ if (!resize || ir_resize_table(rc_map, GFP_ATOMIC))
+ return -1U;
+ }
+
+ /* i is the proper index to insert our new keycode */
+ if (i < rc_map->len)
+ memmove(&rc_map->scan[i + 1], &rc_map->scan[i],
+ (rc_map->len - i) * sizeof(struct rc_map_table));
+ rc_map->scan[i].scancode = scancode;
+ rc_map->scan[i].keycode = KEY_RESERVED;
+ rc_map->len++;
+
+ return i;
+}
+
+/**
+ * ir_setkeycode() - set a keycode in the scancode->keycode table
+ * @idev: the struct input_dev device descriptor
+ * @scancode: the desired scancode
+ * @keycode: result
+ * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
+ *
+ * This routine is used to handle evdev EVIOCSKEY ioctl.
+ */
+static int ir_setkeycode(struct input_dev *idev,
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+ struct rc_map *rc_map = &rdev->rc_map;
+ unsigned int index;
+ unsigned int scancode;
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rc_map->lock, flags);
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ if (index >= rc_map->len) {
+ retval = -EINVAL;
+ goto out;
+ }
+ } else {
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ index = ir_establish_scancode(rdev, rc_map, scancode, true);
+ if (index >= rc_map->len) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ }
+
+ *old_keycode = ir_update_mapping(rdev, rc_map, index, ke->keycode);
+
+out:
+ spin_unlock_irqrestore(&rc_map->lock, flags);
+ return retval;
+}
+
+/**
+ * ir_setkeytable() - sets several entries in the scancode->keycode table
+ * @dev: the struct rc_dev device descriptor
+ * @to: the struct rc_map to copy entries to
+ * @from: the struct rc_map to copy entries from
+ * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
+ *
+ * This routine is used to handle table initialization.
+ */
+static int ir_setkeytable(struct rc_dev *dev,
+ const struct rc_map *from)
+{
+ struct rc_map *rc_map = &dev->rc_map;
+ unsigned int i, index;
+ int rc;
+
+ rc = ir_create_table(rc_map, from->name,
+ from->rc_type, from->size);
+ if (rc)
+ return rc;
+
+ IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
+ rc_map->size, rc_map->alloc);
+
+ for (i = 0; i < from->size; i++) {
+ index = ir_establish_scancode(dev, rc_map,
+ from->scan[i].scancode, false);
+ if (index >= rc_map->len) {
+ rc = -ENOMEM;
+ break;
+ }
+
+ ir_update_mapping(dev, rc_map, index,
+ from->scan[i].keycode);
+ }
+
+ if (rc)
+ ir_free_table(rc_map);
+
+ return rc;
+}
+
+/**
+ * ir_lookup_by_scancode() - locate mapping by scancode
+ * @rc_map: the struct rc_map to search
+ * @scancode: scancode to look for in the table
+ * @return: index in the table, -1U if not found
+ *
+ * This routine performs binary search in RC keykeymap table for
+ * given scancode.
+ */
+static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
+ unsigned int scancode)
+{
+ int start = 0;
+ int end = rc_map->len - 1;
+ int mid;
+
+ while (start <= end) {
+ mid = (start + end) / 2;
+ if (rc_map->scan[mid].scancode < scancode)
+ start = mid + 1;
+ else if (rc_map->scan[mid].scancode > scancode)
+ end = mid - 1;
+ else
+ return mid;
+ }
+
+ return -1U;
+}
+
+/**
+ * ir_getkeycode() - get a keycode from the scancode->keycode table
+ * @idev: the struct input_dev device descriptor
+ * @scancode: the desired scancode
+ * @keycode: used to return the keycode, if found, or KEY_RESERVED
+ * @return: always returns zero.
+ *
+ * This routine is used to handle evdev EVIOCGKEY ioctl.
+ */
+static int ir_getkeycode(struct input_dev *idev,
+ struct input_keymap_entry *ke)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+ struct rc_map *rc_map = &rdev->rc_map;
+ struct rc_map_table *entry;
+ unsigned long flags;
+ unsigned int index;
+ unsigned int scancode;
+ int retval;
+
+ spin_lock_irqsave(&rc_map->lock, flags);
+
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
+ index = ke->index;
+ } else {
+ retval = input_scancode_to_scalar(ke, &scancode);
+ if (retval)
+ goto out;
+
+ index = ir_lookup_by_scancode(rc_map, scancode);
+ }
+
+ if (index >= rc_map->len) {
+ if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
+ IR_dprintk(1, "unknown key for scancode 0x%04x\n",
+ scancode);
+ retval = -EINVAL;
+ goto out;
+ }
+
+ entry = &rc_map->scan[index];
+
+ ke->index = index;
+ ke->keycode = entry->keycode;
+ ke->len = sizeof(entry->scancode);
+ memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
+
+ retval = 0;
+
+out:
+ spin_unlock_irqrestore(&rc_map->lock, flags);
+ return retval;
+}
+
+/**
+ * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode to look for
+ * @return: the corresponding keycode, or KEY_RESERVED
+ *
+ * This routine is used by drivers which need to convert a scancode to a
+ * keycode. Normally it should not be used since drivers should have no
+ * interest in keycodes.
+ */
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
+{
+ struct rc_map *rc_map = &dev->rc_map;
+ unsigned int keycode;
+ unsigned int index;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rc_map->lock, flags);
+
+ index = ir_lookup_by_scancode(rc_map, scancode);
+ keycode = index < rc_map->len ?
+ rc_map->scan[index].keycode : KEY_RESERVED;
+
+ spin_unlock_irqrestore(&rc_map->lock, flags);
+
+ if (keycode != KEY_RESERVED)
+ IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
+ dev->input_name, scancode, keycode);
+
+ return keycode;
+}
+EXPORT_SYMBOL_GPL(rc_g_keycode_from_table);
+
+/**
+ * ir_do_keyup() - internal function to signal the release of a keypress
+ * @dev: the struct rc_dev descriptor of the device
+ *
+ * This function is used internally to release a keypress, it must be
+ * called with keylock held.
+ */
+static void ir_do_keyup(struct rc_dev *dev)
+{
+ if (!dev->keypressed)
+ return;
+
+ IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
+ input_report_key(dev->input_dev, dev->last_keycode, 0);
+ input_sync(dev->input_dev);
+ dev->keypressed = false;
+}
+
+/**
+ * rc_keyup() - signals the release of a keypress
+ * @dev: the struct rc_dev descriptor of the device
+ *
+ * This routine is used to signal that a key has been released on the
+ * remote control.
+ */
+void rc_keyup(struct rc_dev *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keyup(dev);
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_keyup);
+
+/**
+ * ir_timer_keyup() - generates a keyup event after a timeout
+ * @cookie: a pointer to the struct rc_dev for the device
+ *
+ * This routine will generate a keyup event some time after a keydown event
+ * is generated when no further activity has been detected.
+ */
+static void ir_timer_keyup(unsigned long cookie)
+{
+ struct rc_dev *dev = (struct rc_dev *)cookie;
+ unsigned long flags;
+
+ /*
+ * ir->keyup_jiffies is used to prevent a race condition if a
+ * hardware interrupt occurs at this point and the keyup timer
+ * event is moved further into the future as a result.
+ *
+ * The timer will then be reactivated and this function called
+ * again in the future. We need to exit gracefully in that case
+ * to allow the input subsystem to do its auto-repeat magic or
+ * a keyup event might follow immediately after the keydown.
+ */
+ spin_lock_irqsave(&dev->keylock, flags);
+ if (time_is_before_eq_jiffies(dev->keyup_jiffies))
+ ir_do_keyup(dev);
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+
+/**
+ * rc_repeat() - signals that a key is still pressed
+ * @dev: the struct rc_dev descriptor of the device
+ *
+ * This routine is used by IR decoders when a repeat message which does
+ * not include the necessary bits to reproduce the scancode has been
+ * received.
+ */
+void rc_repeat(struct rc_dev *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->keylock, flags);
+
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
+
+ if (!dev->keypressed)
+ goto out;
+
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+
+out:
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_repeat);
+
+/**
+ * ir_do_keydown() - internal function to process a keypress
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode of the keypress
+ * @keycode: the keycode of the keypress
+ * @toggle: the toggle value of the keypress
+ *
+ * This function is used internally to register a keypress, it must be
+ * called with keylock held.
+ */
+static void ir_do_keydown(struct rc_dev *dev, int scancode,
+ u32 keycode, u8 toggle)
+{
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
+
+ /* Repeat event? */
+ if (dev->keypressed &&
+ dev->last_scancode == scancode &&
+ dev->last_toggle == toggle)
+ return;
+
+ /* Release old keypress */
+ ir_do_keyup(dev);
+
+ dev->last_scancode = scancode;
+ dev->last_toggle = toggle;
+ dev->last_keycode = keycode;
+
+ if (keycode == KEY_RESERVED)
+ return;
+
+ /* Register a keypress */
+ dev->keypressed = true;
+ IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
+ dev->input_name, keycode, scancode);
+ input_report_key(dev->input_dev, dev->last_keycode, 1);
+ input_sync(dev->input_dev);
+}
+
+/**
+ * rc_keydown() - generates input event for a key press
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode that we're seeking
+ * @toggle: the toggle value (protocol dependent, if the protocol doesn't
+ * support toggle values, this should be set to zero)
+ *
+ * This routine is used to signal that a key has been pressed on the
+ * remote control.
+ */
+void rc_keydown(struct rc_dev *dev, int scancode, u8 toggle)
+{
+ unsigned long flags;
+ u32 keycode = rc_g_keycode_from_table(dev, scancode);
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keydown(dev, scancode, keycode, toggle);
+
+ if (dev->keypressed) {
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+ }
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_keydown);
+
+/**
+ * rc_keydown_notimeout() - generates input event for a key press without
+ * an automatic keyup event at a later time
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode that we're seeking
+ * @toggle: the toggle value (protocol dependent, if the protocol doesn't
+ * support toggle values, this should be set to zero)
+ *
+ * This routine is used to signal that a key has been pressed on the
+ * remote control. The driver must manually call rc_keyup() at a later stage.
+ */
+void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle)
+{
+ unsigned long flags;
+ u32 keycode = rc_g_keycode_from_table(dev, scancode);
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keydown(dev, scancode, keycode, toggle);
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
+
+static int ir_open(struct input_dev *idev)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+
+ return rdev->open(rdev);
+}
+
+static void ir_close(struct input_dev *idev)
+{
+ struct rc_dev *rdev = input_get_drvdata(idev);
+
+ rdev->close(rdev);
+}
+
+/* class for /sys/class/rc */
+static char *ir_devnode(struct device *dev, mode_t *mode)
+{
+ return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
+}
+
+static struct class ir_input_class = {
+ .name = "rc",
+ .devnode = ir_devnode,
+};
+
+static struct {
+ u64 type;
+ char *name;
+} proto_names[] = {
+ { RC_TYPE_UNKNOWN, "unknown" },
+ { RC_TYPE_RC5, "rc-5" },
+ { RC_TYPE_NEC, "nec" },
+ { RC_TYPE_RC6, "rc-6" },
+ { RC_TYPE_JVC, "jvc" },
+ { RC_TYPE_SONY, "sony" },
+ { RC_TYPE_RC5_SZ, "rc-5-sz" },
+ { RC_TYPE_LIRC, "lirc" },
+};
+
+#define PROTO_NONE "none"
+
+/**
+ * show_protocols() - shows the current IR protocol(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct (unused)
+ * @buf: a pointer to the output buffer
+ *
+ * This routine is a callback routine for input read the IR protocol type(s).
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
+ * It returns the protocol names of supported protocols.
+ * Enabled protocols are printed in brackets.
+ */
+static ssize_t show_protocols(struct device *device,
+ struct device_attribute *mattr, char *buf)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+ u64 allowed, enabled;
+ char *tmp = buf;
+ int i;
+
+ /* Device is being removed */
+ if (!dev)
+ return -EINVAL;
+
+ if (dev->driver_type == RC_DRIVER_SCANCODE) {
+ enabled = dev->rc_map.rc_type;
+ allowed = dev->allowed_protos;
+ } else {
+ enabled = dev->raw->enabled_protocols;
+ allowed = ir_raw_get_allowed_protocols();
+ }
+
+ IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
+ (long long)allowed,
+ (long long)enabled);
+
+ for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+ if (allowed & enabled & proto_names[i].type)
+ tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
+ else if (allowed & proto_names[i].type)
+ tmp += sprintf(tmp, "%s ", proto_names[i].name);
+ }
+
+ if (tmp != buf)
+ tmp--;
+ *tmp = '\n';
+ return tmp + 1 - buf;
+}
+
+/**
+ * store_protocols() - changes the current IR protocol(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct (unused)
+ * @buf: a pointer to the input buffer
+ * @len: length of the input buffer
+ *
+ * This routine is for changing the IR protocol type.
+ * It is trigged by writing to /sys/class/rc/rc?/protocols.
+ * Writing "+proto" will add a protocol to the list of enabled protocols.
+ * Writing "-proto" will remove a protocol from the list of enabled protocols.
+ * Writing "proto" will enable only "proto".
+ * Writing "none" will disable all protocols.
+ * Returns -EINVAL if an invalid protocol combination or unknown protocol name
+ * is used, otherwise @len.
+ */
+static ssize_t store_protocols(struct device *device,
+ struct device_attribute *mattr,
+ const char *data,
+ size_t len)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+ bool enable, disable;
+ const char *tmp;
+ u64 type;
+ u64 mask;
+ int rc, i, count = 0;
+ unsigned long flags;
+
+ /* Device is being removed */
+ if (!dev)
+ return -EINVAL;
+
+ if (dev->driver_type == RC_DRIVER_SCANCODE)
+ type = dev->rc_map.rc_type;
+ else if (dev->raw)
+ type = dev->raw->enabled_protocols;
+ else {
+ IR_dprintk(1, "Protocol switching not supported\n");
+ return -EINVAL;
+ }
+
+ while ((tmp = strsep((char **) &data, " \n")) != NULL) {
+ if (!*tmp)
+ break;
+
+ if (*tmp == '+') {
+ enable = true;
+ disable = false;
+ tmp++;
+ } else if (*tmp == '-') {
+ enable = false;
+ disable = true;
+ tmp++;
+ } else {
+ enable = false;
+ disable = false;
+ }
+
+ if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
+ tmp += sizeof(PROTO_NONE);
+ mask = 0;
+ count++;
+ } else {
+ for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+ if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
+ tmp += strlen(proto_names[i].name);
+ mask = proto_names[i].type;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(proto_names)) {
+ IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
+ return -EINVAL;
+ }
+ count++;
+ }
+
+ if (enable)
+ type |= mask;
+ else if (disable)
+ type &= ~mask;
+ else
+ type = mask;
+ }
+
+ if (!count) {
+ IR_dprintk(1, "Protocol not specified\n");
+ return -EINVAL;
+ }
+
+ if (dev->change_protocol) {
+ rc = dev->change_protocol(dev, type);
+ if (rc < 0) {
+ IR_dprintk(1, "Error setting protocols to 0x%llx\n",
+ (long long)type);
+ return -EINVAL;
+ }
+ }
+
+ if (dev->driver_type == RC_DRIVER_SCANCODE) {
+ spin_lock_irqsave(&dev->rc_map.lock, flags);
+ dev->rc_map.rc_type = type;
+ spin_unlock_irqrestore(&dev->rc_map.lock, flags);
+ } else {
+ dev->raw->enabled_protocols = type;
+ }
+
+ IR_dprintk(1, "Current protocol(s): 0x%llx\n",
+ (long long)type);
+
+ return len;
+}
+
+static void rc_dev_release(struct device *device)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
+#define ADD_HOTPLUG_VAR(fmt, val...) \
+ do { \
+ int err = add_uevent_var(env, fmt, val); \
+ if (err) \
+ return err; \
+ } while (0)
+
+static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+
+ if (dev->rc_map.name)
+ ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
+ if (dev->driver_name)
+ ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
+
+ return 0;
+}
+
+/*
+ * Static device attribute struct with the sysfs attributes for IR's
+ */
+static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
+ show_protocols, store_protocols);
+
+static struct attribute *rc_dev_attrs[] = {
+ &dev_attr_protocols.attr,
+ NULL,
+};
+
+static struct attribute_group rc_dev_attr_grp = {
+ .attrs = rc_dev_attrs,
+};
+
+static const struct attribute_group *rc_dev_attr_groups[] = {
+ &rc_dev_attr_grp,
+ NULL
+};
+
+static struct device_type rc_dev_type = {
+ .groups = rc_dev_attr_groups,
+ .release = rc_dev_release,
+ .uevent = rc_dev_uevent,
+};
+
+struct rc_dev *rc_allocate_device(void)
+{
+ struct rc_dev *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->input_dev = input_allocate_device();
+ if (!dev->input_dev) {
+ kfree(dev);
+ return NULL;
+ }
+
+ dev->input_dev->getkeycode_new = ir_getkeycode;
+ dev->input_dev->setkeycode_new = ir_setkeycode;
+ input_set_drvdata(dev->input_dev, dev);
+
+ spin_lock_init(&dev->rc_map.lock);
+ spin_lock_init(&dev->keylock);
+ setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
+
+ dev->dev.type = &rc_dev_type;
+ dev->dev.class = &ir_input_class;
+ device_initialize(&dev->dev);
+
+ __module_get(THIS_MODULE);
+ return dev;
+}
+EXPORT_SYMBOL_GPL(rc_allocate_device);
+
+void rc_free_device(struct rc_dev *dev)
+{
+ if (dev) {
+ input_free_device(dev->input_dev);
+ put_device(&dev->dev);
+ }
+}
+EXPORT_SYMBOL_GPL(rc_free_device);
+
+int rc_register_device(struct rc_dev *dev)
+{
+ static atomic_t devno = ATOMIC_INIT(0);
+ struct rc_map *rc_map;
+ const char *path;
+ int rc;
+
+ if (!dev || !dev->map_name)
+ return -EINVAL;
+
+ rc_map = rc_map_get(dev->map_name);
+ if (!rc_map)
+ rc_map = rc_map_get(RC_MAP_EMPTY);
+ if (!rc_map || !rc_map->scan || rc_map->size == 0)
+ return -EINVAL;
+
+ set_bit(EV_KEY, dev->input_dev->evbit);
+ set_bit(EV_REP, dev->input_dev->evbit);
+ set_bit(EV_MSC, dev->input_dev->evbit);
+ set_bit(MSC_SCAN, dev->input_dev->mscbit);
+ if (dev->open)
+ dev->input_dev->open = ir_open;
+ if (dev->close)
+ dev->input_dev->close = ir_close;
+
+ dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1);
+ dev_set_name(&dev->dev, "rc%ld", dev->devno);
+ dev_set_drvdata(&dev->dev, dev);
+ rc = device_add(&dev->dev);
+ if (rc)
+ return rc;
+
+ rc = ir_setkeytable(dev, rc_map);
+ if (rc)
+ goto out_dev;
+
+ dev->input_dev->dev.parent = &dev->dev;
+ memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
+ dev->input_dev->phys = dev->input_phys;
+ dev->input_dev->name = dev->input_name;
+ rc = input_register_device(dev->input_dev);
+ if (rc)
+ goto out_table;
+
+ /*
+ * Default delay of 250ms is too short for some protocols, expecially
+ * since the timeout is currently set to 250ms. Increase it to 500ms,
+ * to avoid wrong repetition of the keycodes. Note that this must be
+ * set after the call to input_register_device().
+ */
+ dev->input_dev->rep[REP_DELAY] = 500;
+
+ path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
+ printk(KERN_INFO "%s: %s as %s\n",
+ dev_name(&dev->dev),
+ dev->input_name ? dev->input_name : "Unspecified device",
+ path ? path : "N/A");
+ kfree(path);
+
+ if (dev->driver_type == RC_DRIVER_IR_RAW) {
+ rc = ir_raw_event_register(dev);
+ if (rc < 0)
+ goto out_input;
+ }
+
+ if (dev->change_protocol) {
+ rc = dev->change_protocol(dev, rc_map->rc_type);
+ if (rc < 0)
+ goto out_raw;
+ }
+
+ IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n",
+ dev->devno,
+ dev->driver_name ? dev->driver_name : "unknown",
+ rc_map->name ? rc_map->name : "unknown",
+ dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked");
+
+ return 0;
+
+out_raw:
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ ir_raw_event_unregister(dev);
+out_input:
+ input_unregister_device(dev->input_dev);
+ dev->input_dev = NULL;
+out_table:
+ ir_free_table(&dev->rc_map);
+out_dev:
+ device_del(&dev->dev);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(rc_register_device);
+
+void rc_unregister_device(struct rc_dev *dev)
+{
+ if (!dev)
+ return;
+
+ del_timer_sync(&dev->timer_keyup);
+
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ ir_raw_event_unregister(dev);
+
+ input_unregister_device(dev->input_dev);
+ dev->input_dev = NULL;
+
+ ir_free_table(&dev->rc_map);
+ IR_dprintk(1, "Freed keycode table\n");
+
+ device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(rc_unregister_device);
+
+/*
+ * Init/exit code for the module. Basically, creates/removes /sys/class/rc
+ */
+
+static int __init rc_core_init(void)
+{
+ int rc = class_register(&ir_input_class);
+ if (rc) {
+ printk(KERN_ERR "rc_core: unable to register rc class\n");
+ return rc;
+ }
+
+ /* Initialize/load the decoders/keymap code that will be used */
+ ir_raw_init();
+ rc_map_register(&empty_map);
+
+ return 0;
+}
+
+static void __exit rc_core_exit(void)
+{
+ class_unregister(&ir_input_class);
+ rc_map_unregister(&empty_map);
+}
+
+module_init(rc_core_init);
+module_exit(rc_core_exit);
+
+int rc_core_debug; /* ir_debug level (0,1,2) */
+EXPORT_SYMBOL_GPL(rc_core_debug);
+module_param_named(debug, rc_core_debug, int, 0644);
+
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/rc/streamzap.c
index 548381c35bfd..7f82f55159da 100644
--- a/drivers/media/IR/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -35,8 +35,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
-#include <linux/input.h>
-#include <media/ir-core.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
#define DRIVER_VERSION "1.61"
#define DRIVER_NAME "streamzap"
@@ -85,13 +85,11 @@ enum StreamzapDecoderState {
/* structure to hold our device specific stuff */
struct streamzap_ir {
-
/* ir-core */
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
/* core device info */
struct device *dev;
- struct input_dev *idev;
/* usb */
struct usb_device *usbdev;
@@ -140,7 +138,9 @@ static struct usb_driver streamzap_driver = {
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
- ir_raw_event_store(sz->idev, &rawir);
+ dev_dbg(sz->dev, "Storing %s with duration %u us\n",
+ (rawir.pulse ? "pulse" : "space"), rawir.duration);
+ ir_raw_event_store_with_filter(sz->rdev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
@@ -167,7 +167,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
}
- dev_dbg(sz->dev, "ls %u\n", rawir.duration);
sz_push(sz, rawir);
sz->idle = false;
@@ -180,7 +179,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
sz->sum += rawir.duration;
rawir.duration *= 1000;
rawir.duration &= IR_MAX_DURATION;
- dev_dbg(sz->dev, "p %u\n", rawir.duration);
sz_push(sz, rawir);
}
@@ -200,7 +198,6 @@ static void sz_push_full_space(struct streamzap_ir *sz,
rawir.duration += SZ_RESOLUTION / 2;
sz->sum += rawir.duration;
rawir.duration *= 1000;
- dev_dbg(sz->dev, "s %u\n", rawir.duration);
sz_push(sz, rawir);
}
@@ -221,8 +218,6 @@ static void streamzap_callback(struct urb *urb)
struct streamzap_ir *sz;
unsigned int i;
int len;
- static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
- IR_MAX_DURATION) | 0x03000000);
if (!urb)
return;
@@ -246,7 +241,7 @@ static void streamzap_callback(struct urb *urb)
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
for (i = 0; i < len; i++) {
- dev_dbg(sz->dev, "sz idx %d: %x\n",
+ dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
i, (unsigned char)sz->buf_in[i]);
switch (sz->decoder_state) {
case PulseSpace:
@@ -273,11 +268,11 @@ static void streamzap_callback(struct urb *urb)
DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false;
- rawir.duration = timeout;
+ rawir.duration = sz->rdev->timeout;
sz->idle = true;
if (sz->timeout_enabled)
sz_push(sz, rawir);
- ir_raw_event_handle(sz->idev);
+ ir_raw_event_handle(sz->rdev);
} else {
sz_push_full_space(sz, sz->buf_in[i]);
}
@@ -300,54 +295,45 @@ static void streamzap_callback(struct urb *urb)
return;
}
-static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
+static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
{
- struct input_dev *idev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
struct device *dev = sz->dev;
int ret;
- idev = input_allocate_device();
- if (!idev) {
- dev_err(dev, "remote input dev allocation failed\n");
- goto idev_alloc_failed;
- }
-
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props) {
- dev_err(dev, "remote ir dev props allocation failed\n");
- goto props_alloc_failed;
+ rdev = rc_allocate_device();
+ if (!rdev) {
+ dev_err(dev, "remote dev allocation failed\n");
+ goto out;
}
snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
"Receiver (%04x:%04x)",
le16_to_cpu(sz->usbdev->descriptor.idVendor),
le16_to_cpu(sz->usbdev->descriptor.idProduct));
-
- idev->name = sz->name;
usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
strlcat(sz->phys, "/input0", sizeof(sz->phys));
- idev->phys = sz->phys;
-
- props->priv = sz;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- sz->props = props;
-
- ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
+ rdev->input_name = sz->name;
+ rdev->input_phys = sz->phys;
+ usb_to_input_id(sz->usbdev, &rdev->input_id);
+ rdev->dev.parent = dev;
+ rdev->priv = sz;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = RC_TYPE_ALL;
+ rdev->driver_name = DRIVER_NAME;
+ rdev->map_name = RC_MAP_STREAMZAP;
+
+ ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
- goto irdev_failed;
+ goto out;
}
- return idev;
+ return rdev;
-irdev_failed:
- kfree(props);
-props_alloc_failed:
- input_free_device(idev);
-idev_alloc_failed:
+out:
+ rc_free_device(rdev);
return NULL;
}
@@ -436,14 +422,16 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- sz->idev = streamzap_init_input_dev(sz);
- if (!sz->idev)
- goto input_dev_fail;
+ sz->rdev = streamzap_init_rc_dev(sz);
+ if (!sz->rdev)
+ goto rc_dev_fail;
sz->idle = true;
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true;
+ sz->rdev->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
+ IR_MAX_DURATION) | 0x03000000);
#if 0
/* not yet supported, depends on patches from maxim */
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
@@ -473,7 +461,7 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
return 0;
-input_dev_fail:
+rc_dev_fail:
usb_free_urb(sz->urb_in);
free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
@@ -504,7 +492,7 @@ static void streamzap_disconnect(struct usb_interface *interface)
return;
sz->usbdev = NULL;
- ir_input_unregister(sz->idev);
+ rc_unregister_device(sz->rdev);
usb_kill_urb(sz->urb_in);
usb_free_urb(sz->urb_in);
usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 64f1de7960c6..186de5522001 100644
--- a/drivers/input/misc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -7,10 +7,10 @@
* with minor modifications.
*
* Original Author: David Härdeman <david@hardeman.nu>
- * Copyright (C) 2009 David Härdeman <david@hardeman.nu>
+ * Copyright (C) 2009 - 2010 David Härdeman <david@hardeman.nu>
*
- * Dedicated to Matilda, my newborn daughter, without whose loving attention
- * this driver would have been finished in half the time and with a fraction
+ * Dedicated to my daughter Matilda, without whose loving attention this
+ * driver would have been finished in half the time and with a fraction
* of the bugs.
*
* Written using:
@@ -19,15 +19,11 @@
* o DSDT dumps
*
* Supported features:
- * o RC6
* o Wake-On-CIR functionality
*
* To do:
- * o Test NEC and RC5
- *
- * Left as an exercise for the reader:
- * o Learning (I have neither the hardware, nor the need)
- * o IR Transmit (ibid)
+ * o Learning
+ * o IR Transmit
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,15 +44,13 @@
#include <linux/pnp.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/input.h>
#include <linux/leds.h>
-#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/pci_ids.h>
#include <linux/io.h>
#include <linux/bitrev.h>
-#include <linux/bitops.h>
#include <linux/slab.h>
+#include <media/rc-core.h>
#define DRVNAME "winbond-cir"
@@ -108,7 +102,7 @@
#define WBCIR_REG_SP3_IRCR2 0x04 /* Infrared Control 2 */
/* Bank 6 */
#define WBCIR_REG_SP3_IRCR3 0x00 /* Infrared Control 3 */
-#define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */
+#define WBCIR_REG_SP3_SIR_PW 0x02 /* SIR Pulse Width */
/* Bank 7 */
#define WBCIR_REG_SP3_IRRXDC 0x00 /* IR RX Demod Control */
#define WBCIR_REG_SP3_IRTXMC 0x01 /* IR TX Mod Control */
@@ -153,7 +147,7 @@ enum wbcir_bank {
WBCIR_BANK_7 = 0xF4,
};
-/* Supported IR Protocols */
+/* Supported power-on IR Protocols */
enum wbcir_protocol {
IR_PROTOCOL_RC5 = 0x0,
IR_PROTOCOL_NEC = 0x1,
@@ -164,113 +158,35 @@ enum wbcir_protocol {
#define WBCIR_NAME "Winbond CIR"
#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */
#define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */
-#define IR_KEYPRESS_TIMEOUT 250 /* FIXME: should be per-protocol? */
#define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */
#define WAKEUP_IOMEM_LEN 0x10 /* Wake-Up I/O Reg Len */
#define EHFUNC_IOMEM_LEN 0x10 /* Enhanced Func I/O Reg Len */
#define SP_IOMEM_LEN 0x08 /* Serial Port 3 (IR) Reg Len */
-#define WBCIR_MAX_IDLE_BYTES 10
-
-static DEFINE_SPINLOCK(wbcir_lock);
-static DEFINE_RWLOCK(keytable_lock);
-struct wbcir_key {
- u32 scancode;
- unsigned int keycode;
-};
-
-struct wbcir_keyentry {
- struct wbcir_key key;
- struct list_head list;
-};
-
-static struct wbcir_key rc6_def_keymap[] = {
- { 0x800F0400, KEY_NUMERIC_0 },
- { 0x800F0401, KEY_NUMERIC_1 },
- { 0x800F0402, KEY_NUMERIC_2 },
- { 0x800F0403, KEY_NUMERIC_3 },
- { 0x800F0404, KEY_NUMERIC_4 },
- { 0x800F0405, KEY_NUMERIC_5 },
- { 0x800F0406, KEY_NUMERIC_6 },
- { 0x800F0407, KEY_NUMERIC_7 },
- { 0x800F0408, KEY_NUMERIC_8 },
- { 0x800F0409, KEY_NUMERIC_9 },
- { 0x800F041D, KEY_NUMERIC_STAR },
- { 0x800F041C, KEY_NUMERIC_POUND },
- { 0x800F0410, KEY_VOLUMEUP },
- { 0x800F0411, KEY_VOLUMEDOWN },
- { 0x800F0412, KEY_CHANNELUP },
- { 0x800F0413, KEY_CHANNELDOWN },
- { 0x800F040E, KEY_MUTE },
- { 0x800F040D, KEY_VENDOR }, /* Vista Logo Key */
- { 0x800F041E, KEY_UP },
- { 0x800F041F, KEY_DOWN },
- { 0x800F0420, KEY_LEFT },
- { 0x800F0421, KEY_RIGHT },
- { 0x800F0422, KEY_OK },
- { 0x800F0423, KEY_ESC },
- { 0x800F040F, KEY_INFO },
- { 0x800F040A, KEY_CLEAR },
- { 0x800F040B, KEY_ENTER },
- { 0x800F045B, KEY_RED },
- { 0x800F045C, KEY_GREEN },
- { 0x800F045D, KEY_YELLOW },
- { 0x800F045E, KEY_BLUE },
- { 0x800F045A, KEY_TEXT },
- { 0x800F0427, KEY_SWITCHVIDEOMODE },
- { 0x800F040C, KEY_POWER },
- { 0x800F0450, KEY_RADIO },
- { 0x800F0448, KEY_PVR },
- { 0x800F0447, KEY_AUDIO },
- { 0x800F0426, KEY_EPG },
- { 0x800F0449, KEY_CAMERA },
- { 0x800F0425, KEY_TV },
- { 0x800F044A, KEY_VIDEO },
- { 0x800F0424, KEY_DVD },
- { 0x800F0416, KEY_PLAY },
- { 0x800F0418, KEY_PAUSE },
- { 0x800F0419, KEY_STOP },
- { 0x800F0414, KEY_FASTFORWARD },
- { 0x800F041A, KEY_NEXT },
- { 0x800F041B, KEY_PREVIOUS },
- { 0x800F0415, KEY_REWIND },
- { 0x800F0417, KEY_RECORD },
-};
-
-/* Registers and other state is protected by wbcir_lock */
+/* Per-device data */
struct wbcir_data {
+ spinlock_t spinlock;
+
unsigned long wbase; /* Wake-Up Baseaddr */
unsigned long ebase; /* Enhanced Func. Baseaddr */
unsigned long sbase; /* Serial Port Baseaddr */
unsigned int irq; /* Serial Port IRQ */
- struct input_dev *input_dev;
- struct timer_list timer_keyup;
+ struct rc_dev *dev;
+
struct led_trigger *rxtrigger;
struct led_trigger *txtrigger;
struct led_classdev led;
- u32 last_scancode;
- unsigned int last_keycode;
- u8 last_toggle;
- u8 keypressed;
- unsigned long keyup_jiffies;
- unsigned int idle_count;
-
- /* RX irdata and parsing state */
- unsigned long irdata[30];
- unsigned int irdata_count;
- unsigned int irdata_idle;
- unsigned int irdata_off;
- unsigned int irdata_error;
-
- /* Protected by keytable_lock */
- struct list_head keytable;
+ /* RX irdata state */
+ bool irdata_active;
+ bool irdata_error;
+ struct ir_raw_event ev;
};
static enum wbcir_protocol protocol = IR_PROTOCOL_RC6;
module_param(protocol, uint, 0444);
-MODULE_PARM_DESC(protocol, "IR protocol to use "
+MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command "
"(0 = RC5, 1 = NEC, 2 = RC6A, default)");
static int invert; /* default = 0 */
@@ -327,7 +243,7 @@ wbcir_led_brightness_get(struct led_classdev *led_cdev)
static void
wbcir_led_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness brightness)
+ enum led_brightness brightness)
{
struct wbcir_data *data = container_of(led_cdev,
struct wbcir_data,
@@ -338,7 +254,7 @@ wbcir_led_brightness_set(struct led_classdev *led_cdev,
WBCIR_LED_ENABLE);
}
-/* Manchester encodes bits to RC6 message cells (see wbcir_parse_rc6) */
+/* Manchester encodes bits to RC6 message cells (see wbcir_shutdown) */
static u8
wbcir_to_rc6cells(u8 val)
{
@@ -357,579 +273,6 @@ wbcir_to_rc6cells(u8 val)
return coded;
}
-
-
-/*****************************************************************************
- *
- * INPUT FUNCTIONS
- *
- *****************************************************************************/
-
-static unsigned int
-wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode)
-{
- struct wbcir_keyentry *keyentry;
- unsigned int keycode = KEY_RESERVED;
- unsigned long flags;
-
- read_lock_irqsave(&keytable_lock, flags);
-
- list_for_each_entry(keyentry, &data->keytable, list) {
- if (keyentry->key.scancode == scancode) {
- keycode = keyentry->key.keycode;
- break;
- }
- }
-
- read_unlock_irqrestore(&keytable_lock, flags);
- return keycode;
-}
-
-static int
-wbcir_getkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int *keycode)
-{
- struct wbcir_data *data = input_get_drvdata(dev);
-
- *keycode = wbcir_do_getkeycode(data, scancode);
- return 0;
-}
-
-static int
-wbcir_setkeycode(struct input_dev *dev,
- unsigned int scancode, unsigned int keycode)
-{
- struct wbcir_data *data = input_get_drvdata(dev);
- struct wbcir_keyentry *keyentry;
- struct wbcir_keyentry *new_keyentry;
- unsigned long flags;
- unsigned int old_keycode = KEY_RESERVED;
-
- new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
- if (!new_keyentry)
- return -ENOMEM;
-
- write_lock_irqsave(&keytable_lock, flags);
-
- list_for_each_entry(keyentry, &data->keytable, list) {
- if (keyentry->key.scancode != scancode)
- continue;
-
- old_keycode = keyentry->key.keycode;
- keyentry->key.keycode = keycode;
-
- if (keyentry->key.keycode == KEY_RESERVED) {
- list_del(&keyentry->list);
- kfree(keyentry);
- }
-
- break;
- }
-
- set_bit(keycode, dev->keybit);
-
- if (old_keycode == KEY_RESERVED) {
- new_keyentry->key.scancode = scancode;
- new_keyentry->key.keycode = keycode;
- list_add(&new_keyentry->list, &data->keytable);
- } else {
- kfree(new_keyentry);
- clear_bit(old_keycode, dev->keybit);
- list_for_each_entry(keyentry, &data->keytable, list) {
- if (keyentry->key.keycode == old_keycode) {
- set_bit(old_keycode, dev->keybit);
- break;
- }
- }
- }
-
- write_unlock_irqrestore(&keytable_lock, flags);
- return 0;
-}
-
-/*
- * Timer function to report keyup event some time after keydown is
- * reported by the ISR.
- */
-static void
-wbcir_keyup(unsigned long cookie)
-{
- struct wbcir_data *data = (struct wbcir_data *)cookie;
- unsigned long flags;
-
- /*
- * data->keyup_jiffies is used to prevent a race condition if a
- * hardware interrupt occurs at this point and the keyup timer
- * event is moved further into the future as a result.
- *
- * The timer will then be reactivated and this function called
- * again in the future. We need to exit gracefully in that case
- * to allow the input subsystem to do its auto-repeat magic or
- * a keyup event might follow immediately after the keydown.
- */
-
- spin_lock_irqsave(&wbcir_lock, flags);
-
- if (time_is_after_eq_jiffies(data->keyup_jiffies) && data->keypressed) {
- data->keypressed = 0;
- led_trigger_event(data->rxtrigger, LED_OFF);
- input_report_key(data->input_dev, data->last_keycode, 0);
- input_sync(data->input_dev);
- }
-
- spin_unlock_irqrestore(&wbcir_lock, flags);
-}
-
-static void
-wbcir_keydown(struct wbcir_data *data, u32 scancode, u8 toggle)
-{
- unsigned int keycode;
-
- /* Repeat? */
- if (data->last_scancode == scancode &&
- data->last_toggle == toggle &&
- data->keypressed)
- goto set_timer;
- data->last_scancode = scancode;
-
- /* Do we need to release an old keypress? */
- if (data->keypressed) {
- input_report_key(data->input_dev, data->last_keycode, 0);
- input_sync(data->input_dev);
- data->keypressed = 0;
- }
-
- /* Report scancode */
- input_event(data->input_dev, EV_MSC, MSC_SCAN, (int)scancode);
-
- /* Do we know this scancode? */
- keycode = wbcir_do_getkeycode(data, scancode);
- if (keycode == KEY_RESERVED)
- goto set_timer;
-
- /* Register a keypress */
- input_report_key(data->input_dev, keycode, 1);
- data->keypressed = 1;
- data->last_keycode = keycode;
- data->last_toggle = toggle;
-
-set_timer:
- input_sync(data->input_dev);
- led_trigger_event(data->rxtrigger,
- data->keypressed ? LED_FULL : LED_OFF);
- data->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&data->timer_keyup, data->keyup_jiffies);
-}
-
-
-
-/*****************************************************************************
- *
- * IR PARSING FUNCTIONS
- *
- *****************************************************************************/
-
-/* Resets all irdata */
-static void
-wbcir_reset_irdata(struct wbcir_data *data)
-{
- memset(data->irdata, 0, sizeof(data->irdata));
- data->irdata_count = 0;
- data->irdata_off = 0;
- data->irdata_error = 0;
- data->idle_count = 0;
-}
-
-/* Adds one bit of irdata */
-static void
-add_irdata_bit(struct wbcir_data *data, int set)
-{
- if (data->irdata_count >= sizeof(data->irdata) * 8) {
- data->irdata_error = 1;
- return;
- }
-
- if (set)
- __set_bit(data->irdata_count, data->irdata);
- data->irdata_count++;
-}
-
-/* Gets count bits of irdata */
-static u16
-get_bits(struct wbcir_data *data, int count)
-{
- u16 val = 0x0;
-
- if (data->irdata_count - data->irdata_off < count) {
- data->irdata_error = 1;
- return 0x0;
- }
-
- while (count > 0) {
- val <<= 1;
- if (test_bit(data->irdata_off, data->irdata))
- val |= 0x1;
- count--;
- data->irdata_off++;
- }
-
- return val;
-}
-
-/* Reads 16 cells and converts them to a byte */
-static u8
-wbcir_rc6cells_to_byte(struct wbcir_data *data)
-{
- u16 raw = get_bits(data, 16);
- u8 val = 0x00;
- int bit;
-
- for (bit = 0; bit < 8; bit++) {
- switch (raw & 0x03) {
- case 0x01:
- break;
- case 0x02:
- val |= (0x01 << bit);
- break;
- default:
- data->irdata_error = 1;
- break;
- }
- raw >>= 2;
- }
-
- return val;
-}
-
-/* Decodes a number of bits from raw RC5 data */
-static u8
-wbcir_get_rc5bits(struct wbcir_data *data, unsigned int count)
-{
- u16 raw = get_bits(data, count * 2);
- u8 val = 0x00;
- int bit;
-
- for (bit = 0; bit < count; bit++) {
- switch (raw & 0x03) {
- case 0x01:
- val |= (0x01 << bit);
- break;
- case 0x02:
- break;
- default:
- data->irdata_error = 1;
- break;
- }
- raw >>= 2;
- }
-
- return val;
-}
-
-static void
-wbcir_parse_rc6(struct device *dev, struct wbcir_data *data)
-{
- /*
- * Normal bits are manchester coded as follows:
- * cell0 + cell1 = logic "0"
- * cell1 + cell0 = logic "1"
- *
- * The IR pulse has the following components:
- *
- * Leader - 6 * cell1 - discarded
- * Gap - 2 * cell0 - discarded
- * Start bit - Normal Coding - always "1"
- * Mode Bit 2 - 0 - Normal Coding
- * Toggle bit - Normal Coding with double bit time,
- * e.g. cell0 + cell0 + cell1 + cell1
- * means logic "0".
- *
- * The rest depends on the mode, the following modes are known:
- *
- * MODE 0:
- * Address Bit 7 - 0 - Normal Coding
- * Command Bit 7 - 0 - Normal Coding
- *
- * MODE 6:
- * The above Toggle Bit is used as a submode bit, 0 = A, 1 = B.
- * Submode B is for pointing devices, only remotes using submode A
- * are supported.
- *
- * Customer range bit - 0 => Customer = 7 bits, 0...127
- * 1 => Customer = 15 bits, 32768...65535
- * Customer Bits - Normal Coding
- *
- * Customer codes are allocated by Philips. The rest of the bits
- * are customer dependent. The following is commonly used (and the
- * only supported config):
- *
- * Toggle Bit - Normal Coding
- * Address Bit 6 - 0 - Normal Coding
- * Command Bit 7 - 0 - Normal Coding
- *
- * All modes are followed by at least 6 * cell0.
- *
- * MODE 0 msglen:
- * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (toggle) +
- * 8 * 2 (address) + 8 * 2 (command) =
- * 44 cells
- *
- * MODE 6A msglen:
- * 1 * 2 (start bit) + 3 * 2 (mode) + 2 * 2 (submode) +
- * 1 * 2 (customer range bit) + 7/15 * 2 (customer bits) +
- * 1 * 2 (toggle bit) + 7 * 2 (address) + 8 * 2 (command) =
- * 60 - 76 cells
- */
- u8 mode;
- u8 toggle;
- u16 customer = 0x0;
- u8 address;
- u8 command;
- u32 scancode;
-
- /* Leader mark */
- while (get_bits(data, 1) && !data->irdata_error)
- /* Do nothing */;
-
- /* Leader space */
- if (get_bits(data, 1)) {
- dev_dbg(dev, "RC6 - Invalid leader space\n");
- return;
- }
-
- /* Start bit */
- if (get_bits(data, 2) != 0x02) {
- dev_dbg(dev, "RC6 - Invalid start bit\n");
- return;
- }
-
- /* Mode */
- mode = get_bits(data, 6);
- switch (mode) {
- case 0x15: /* 010101 = b000 */
- mode = 0;
- break;
- case 0x29: /* 101001 = b110 */
- mode = 6;
- break;
- default:
- dev_dbg(dev, "RC6 - Invalid mode\n");
- return;
- }
-
- /* Toggle bit / Submode bit */
- toggle = get_bits(data, 4);
- switch (toggle) {
- case 0x03:
- toggle = 0;
- break;
- case 0x0C:
- toggle = 1;
- break;
- default:
- dev_dbg(dev, "RC6 - Toggle bit error\n");
- break;
- }
-
- /* Customer */
- if (mode == 6) {
- if (toggle != 0) {
- dev_dbg(dev, "RC6B - Not Supported\n");
- return;
- }
-
- customer = wbcir_rc6cells_to_byte(data);
-
- if (customer & 0x80) {
- /* 15 bit customer value */
- customer <<= 8;
- customer |= wbcir_rc6cells_to_byte(data);
- }
- }
-
- /* Address */
- address = wbcir_rc6cells_to_byte(data);
- if (mode == 6) {
- toggle = address >> 7;
- address &= 0x7F;
- }
-
- /* Command */
- command = wbcir_rc6cells_to_byte(data);
-
- /* Create scancode */
- scancode = command;
- scancode |= address << 8;
- scancode |= customer << 16;
-
- /* Last sanity check */
- if (data->irdata_error) {
- dev_dbg(dev, "RC6 - Cell error(s)\n");
- return;
- }
-
- dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
- "toggle %u mode %u scan 0x%08X\n",
- address,
- command,
- customer,
- (unsigned int)toggle,
- (unsigned int)mode,
- scancode);
-
- wbcir_keydown(data, scancode, toggle);
-}
-
-static void
-wbcir_parse_rc5(struct device *dev, struct wbcir_data *data)
-{
- /*
- * Bits are manchester coded as follows:
- * cell1 + cell0 = logic "0"
- * cell0 + cell1 = logic "1"
- * (i.e. the reverse of RC6)
- *
- * Start bit 1 - "1" - discarded
- * Start bit 2 - Must be inverted to get command bit 6
- * Toggle bit
- * Address Bit 4 - 0
- * Command Bit 5 - 0
- */
- u8 toggle;
- u8 address;
- u8 command;
- u32 scancode;
-
- /* Start bit 1 */
- if (!get_bits(data, 1)) {
- dev_dbg(dev, "RC5 - Invalid start bit\n");
- return;
- }
-
- /* Start bit 2 */
- if (!wbcir_get_rc5bits(data, 1))
- command = 0x40;
- else
- command = 0x00;
-
- toggle = wbcir_get_rc5bits(data, 1);
- address = wbcir_get_rc5bits(data, 5);
- command |= wbcir_get_rc5bits(data, 6);
- scancode = address << 7 | command;
-
- /* Last sanity check */
- if (data->irdata_error) {
- dev_dbg(dev, "RC5 - Invalid message\n");
- return;
- }
-
- dev_dbg(dev, "IR-RC5 ad %u cm %u t %u s %u\n",
- (unsigned int)address,
- (unsigned int)command,
- (unsigned int)toggle,
- (unsigned int)scancode);
-
- wbcir_keydown(data, scancode, toggle);
-}
-
-static void
-wbcir_parse_nec(struct device *dev, struct wbcir_data *data)
-{
- /*
- * Each bit represents 560 us.
- *
- * Leader - 9 ms burst
- * Gap - 4.5 ms silence
- * Address1 bit 0 - 7 - Address 1
- * Address2 bit 0 - 7 - Address 2
- * Command1 bit 0 - 7 - Command 1
- * Command2 bit 0 - 7 - Command 2
- *
- * Note the bit order!
- *
- * With the old NEC protocol, Address2 was the inverse of Address1
- * and Command2 was the inverse of Command1 and were used as
- * an error check.
- *
- * With NEC extended, Address1 is the LSB of the Address and
- * Address2 is the MSB, Command parsing remains unchanged.
- *
- * A repeat message is coded as:
- * Leader - 9 ms burst
- * Gap - 2.25 ms silence
- * Repeat - 560 us active
- */
- u8 address1;
- u8 address2;
- u8 command1;
- u8 command2;
- u16 address;
- u32 scancode;
-
- /* Leader mark */
- while (get_bits(data, 1) && !data->irdata_error)
- /* Do nothing */;
-
- /* Leader space */
- if (get_bits(data, 4)) {
- dev_dbg(dev, "NEC - Invalid leader space\n");
- return;
- }
-
- /* Repeat? */
- if (get_bits(data, 1)) {
- if (!data->keypressed) {
- dev_dbg(dev, "NEC - Stray repeat message\n");
- return;
- }
-
- dev_dbg(dev, "IR-NEC repeat s %u\n",
- (unsigned int)data->last_scancode);
-
- wbcir_keydown(data, data->last_scancode, data->last_toggle);
- return;
- }
-
- /* Remaining leader space */
- if (get_bits(data, 3)) {
- dev_dbg(dev, "NEC - Invalid leader space\n");
- return;
- }
-
- address1 = bitrev8(get_bits(data, 8));
- address2 = bitrev8(get_bits(data, 8));
- command1 = bitrev8(get_bits(data, 8));
- command2 = bitrev8(get_bits(data, 8));
-
- /* Sanity check */
- if (data->irdata_error) {
- dev_dbg(dev, "NEC - Invalid message\n");
- return;
- }
-
- /* Check command validity */
- if (command1 != ~command2) {
- dev_dbg(dev, "NEC - Command bytes mismatch\n");
- return;
- }
-
- /* Check for extended NEC protocol */
- address = address1;
- if (address1 != ~address2)
- address |= address2 << 8;
-
- scancode = address << 8 | command1;
-
- dev_dbg(dev, "IR-NEC ad %u cm %u s %u\n",
- (unsigned int)address,
- (unsigned int)command1,
- (unsigned int)scancode);
-
- wbcir_keydown(data, scancode, !data->last_toggle);
-}
-
-
-
/*****************************************************************************
*
* INTERRUPT FUNCTIONS
@@ -941,75 +284,88 @@ wbcir_irq_handler(int irqno, void *cookie)
{
struct pnp_dev *device = cookie;
struct wbcir_data *data = pnp_get_drvdata(device);
- struct device *dev = &device->dev;
- u8 status;
unsigned long flags;
u8 irdata[8];
+ u8 disable = true;
+ u8 status;
int i;
- unsigned int hw;
- spin_lock_irqsave(&wbcir_lock, flags);
+ spin_lock_irqsave(&data->spinlock, flags);
wbcir_select_bank(data, WBCIR_BANK_0);
status = inb(data->sbase + WBCIR_REG_SP3_EIR);
if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) {
- spin_unlock_irqrestore(&wbcir_lock, flags);
+ spin_unlock_irqrestore(&data->spinlock, flags);
return IRQ_NONE;
}
- if (status & WBCIR_IRQ_ERR)
- data->irdata_error = 1;
+ /* Check for e.g. buffer overflow */
+ if (status & WBCIR_IRQ_ERR) {
+ data->irdata_error = true;
+ ir_raw_event_reset(data->dev);
+ }
if (!(status & WBCIR_IRQ_RX))
goto out;
+ if (!data->irdata_active) {
+ data->irdata_active = true;
+ led_trigger_event(data->rxtrigger, LED_FULL);
+ }
+
/* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8);
- for (i = 0; i < sizeof(irdata); i++) {
- hw = hweight8(irdata[i]);
- if (hw > 4)
- add_irdata_bit(data, 0);
- else
- add_irdata_bit(data, 1);
+ for (i = 0; i < 8; i++) {
+ u8 pulse;
+ u32 duration;
- if (hw == 8)
- data->idle_count++;
- else
- data->idle_count = 0;
+ if (irdata[i] != 0xFF && irdata[i] != 0x00)
+ disable = false;
+
+ if (data->irdata_error)
+ continue;
+
+ pulse = irdata[i] & 0x80 ? false : true;
+ duration = (irdata[i] & 0x7F) * 10000; /* ns */
+
+ if (data->ev.pulse != pulse) {
+ if (data->ev.duration != 0) {
+ ir_raw_event_store(data->dev, &data->ev);
+ data->ev.duration = 0;
+ }
+
+ data->ev.pulse = pulse;
+ }
+
+ data->ev.duration += duration;
}
- if (data->idle_count > WBCIR_MAX_IDLE_BYTES) {
- /* Set RXINACTIVE... */
+ if (disable) {
+ if (data->ev.duration != 0 && !data->irdata_error) {
+ ir_raw_event_store(data->dev, &data->ev);
+ data->ev.duration = 0;
+ }
+
+ /* Set RXINACTIVE */
outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
- /* ...and drain the FIFO */
+ /* Drain the FIFO */
while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL)
inb(data->sbase + WBCIR_REG_SP3_RXDATA);
- dev_dbg(dev, "IRDATA:\n");
- for (i = 0; i < data->irdata_count; i += BITS_PER_LONG)
- dev_dbg(dev, "0x%08lX\n", data->irdata[i/BITS_PER_LONG]);
-
- switch (protocol) {
- case IR_PROTOCOL_RC5:
- wbcir_parse_rc5(dev, data);
- break;
- case IR_PROTOCOL_RC6:
- wbcir_parse_rc6(dev, data);
- break;
- case IR_PROTOCOL_NEC:
- wbcir_parse_nec(dev, data);
- break;
- }
-
- wbcir_reset_irdata(data);
+ ir_raw_event_reset(data->dev);
+ data->irdata_error = false;
+ data->irdata_active = false;
+ led_trigger_event(data->rxtrigger, LED_OFF);
}
+ ir_raw_event_handle(data->dev);
+
out:
- spin_unlock_irqrestore(&wbcir_lock, flags);
+ spin_unlock_irqrestore(&data->spinlock, flags);
return IRQ_HANDLED;
}
@@ -1199,6 +555,10 @@ finish:
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+ /* Disable LED */
+ data->irdata_active = false;
+ led_trigger_event(data->rxtrigger, LED_OFF);
+
/*
* ACPI will set the HW disable bit for SP3 which means that the
* output signals are left in an undefined state which may cause
@@ -1323,8 +683,15 @@ wbcir_init_hw(struct wbcir_data *data)
/* Clear AUX status bits */
outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
+ /* Clear IR decoding state */
+ data->irdata_active = false;
+ led_trigger_event(data->rxtrigger, LED_OFF);
+ data->irdata_error = false;
+ data->ev.duration = 0;
+ ir_raw_event_reset(data->dev);
+ ir_raw_event_handle(data->dev);
+
/* Enable interrupts */
- wbcir_reset_irdata(data);
outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
}
@@ -1361,6 +728,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
pnp_set_drvdata(device, data);
+ spin_lock_init(&data->spinlock);
data->ebase = pnp_port_start(device, 0);
data->wbase = pnp_port_start(device, 1);
data->sbase = pnp_port_start(device, 2);
@@ -1426,43 +794,25 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
if (err)
goto exit_unregister_rxtrigger;
- data->input_dev = input_allocate_device();
- if (!data->input_dev) {
+ data->dev = rc_allocate_device();
+ if (!data->dev) {
err = -ENOMEM;
goto exit_unregister_led;
}
- data->input_dev->evbit[0] = BIT(EV_KEY);
- data->input_dev->name = WBCIR_NAME;
- data->input_dev->phys = "wbcir/cir0";
- data->input_dev->id.bustype = BUS_HOST;
- data->input_dev->id.vendor = PCI_VENDOR_ID_WINBOND;
- data->input_dev->id.product = WBCIR_ID_FAMILY;
- data->input_dev->id.version = WBCIR_ID_CHIP;
- data->input_dev->getkeycode = wbcir_getkeycode;
- data->input_dev->setkeycode = wbcir_setkeycode;
- input_set_capability(data->input_dev, EV_MSC, MSC_SCAN);
- input_set_drvdata(data->input_dev, data);
-
- err = input_register_device(data->input_dev);
+ data->dev->driver_name = WBCIR_NAME;
+ data->dev->input_name = WBCIR_NAME;
+ data->dev->input_phys = "wbcir/cir0";
+ data->dev->input_id.bustype = BUS_HOST;
+ data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND;
+ data->dev->input_id.product = WBCIR_ID_FAMILY;
+ data->dev->input_id.version = WBCIR_ID_CHIP;
+ data->dev->priv = data;
+ data->dev->dev.parent = &device->dev;
+
+ err = rc_register_device(data->dev);
if (err)
- goto exit_free_input;
-
- data->last_scancode = INVALID_SCANCODE;
- INIT_LIST_HEAD(&data->keytable);
- setup_timer(&data->timer_keyup, wbcir_keyup, (unsigned long)data);
-
- /* Load default keymaps */
- if (protocol == IR_PROTOCOL_RC6) {
- int i;
- for (i = 0; i < ARRAY_SIZE(rc6_def_keymap); i++) {
- err = wbcir_setkeycode(data->input_dev,
- (int)rc6_def_keymap[i].scancode,
- (int)rc6_def_keymap[i].keycode);
- if (err)
- goto exit_unregister_keys;
- }
- }
+ goto exit_free_rc;
device_init_wakeup(&device->dev, 1);
@@ -1470,21 +820,8 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
return 0;
-exit_unregister_keys:
- if (!list_empty(&data->keytable)) {
- struct wbcir_keyentry *key;
- struct wbcir_keyentry *keytmp;
-
- list_for_each_entry_safe(key, keytmp, &data->keytable, list) {
- list_del(&key->list);
- kfree(key);
- }
- }
- input_unregister_device(data->input_dev);
- /* Can't call input_free_device on an unregistered device */
- data->input_dev = NULL;
-exit_free_input:
- input_free_device(data->input_dev);
+exit_free_rc:
+ rc_free_device(data->dev);
exit_unregister_led:
led_classdev_unregister(&data->led);
exit_unregister_rxtrigger:
@@ -1510,15 +847,11 @@ static void __devexit
wbcir_remove(struct pnp_dev *device)
{
struct wbcir_data *data = pnp_get_drvdata(device);
- struct wbcir_keyentry *key;
- struct wbcir_keyentry *keytmp;
/* Disable interrupts */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
- del_timer_sync(&data->timer_keyup);
-
free_irq(data->irq, device);
/* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */
@@ -1530,8 +863,7 @@ wbcir_remove(struct pnp_dev *device)
/* Clear BUFF_EN, END_EN, MATCH_EN */
wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
- /* This will generate a keyup event if necessary */
- input_unregister_device(data->input_dev);
+ rc_unregister_device(data->dev);
led_trigger_unregister_simple(data->rxtrigger);
led_trigger_unregister_simple(data->txtrigger);
@@ -1544,11 +876,6 @@ wbcir_remove(struct pnp_dev *device)
release_region(data->ebase, EHFUNC_IOMEM_LEN);
release_region(data->sbase, SP_IOMEM_LEN);
- list_for_each_entry_safe(key, keytmp, &data->keytable, list) {
- list_del(&key->list);
- kfree(key);
- }
-
kfree(data);
pnp_set_drvdata(device, NULL);
@@ -1581,8 +908,7 @@ wbcir_init(void)
case IR_PROTOCOL_RC6:
break;
default:
- printk(KERN_ERR DRVNAME ": Invalid protocol argument\n");
- return -EINVAL;
+ printk(KERN_ERR DRVNAME ": Invalid power-on protocol\n");
}
ret = pnp_register_driver(&wbcir_driver);
@@ -1598,11 +924,9 @@ wbcir_exit(void)
pnp_unregister_driver(&wbcir_driver);
}
-MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
-MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver");
-MODULE_LICENSE("GPL");
-
module_init(wbcir_init);
module_exit(wbcir_exit);
-
+MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
+MODULE_DESCRIPTION("Winbond SuperI/O Consumer IR Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6830d2848bd7..4b751ef47a83 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -96,7 +96,7 @@ config VIDEO_HELPER_CHIPS_AUTO
config VIDEO_IR_I2C
tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO
- depends on I2C && VIDEO_IR
+ depends on I2C && RC_CORE
default y
---help---
Most boards have an IR chip directly connected via GPIO. However,
@@ -666,6 +666,16 @@ config VIDEO_HEXIUM_GEMINI
To compile this driver as a module, choose M here: the
module will be called hexium_gemini.
+config VIDEO_TIMBERDALE
+ tristate "Support for timberdale Video In/LogiWIN"
+ depends on VIDEO_V4L2 && I2C
+ select DMA_ENGINE
+ select TIMB_DMA
+ select VIDEO_ADV7180
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ Add support for the Video In peripherial of the timberdale FPGA.
+
source "drivers/media/video/cx88/Kconfig"
source "drivers/media/video/cx23885/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index af79d476a4c8..482f14b3ff84 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_MXB) += mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
+obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 31e7a123d19a..f989f2820d88 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar)
static const struct v4l2_file_operations ar_fops = {
.owner = THIS_MODULE,
.read = ar_read,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops ar_ioctl_ops = {
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 162fd5f9d448..48682af911fa 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -122,6 +122,7 @@ static void au0828_irq_callback(struct urb *urb)
{
struct au0828_dmaqueue *dma_q = urb->context;
struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+ unsigned long flags = 0;
int rc, i;
switch (urb->status) {
@@ -139,9 +140,9 @@ static void au0828_irq_callback(struct urb *urb)
}
/* Copy data from URB */
- spin_lock(&dev->slock);
+ spin_lock_irqsave(&dev->slock, flags);
rc = dev->isoc_ctl.isoc_copy(dev, urb);
- spin_unlock(&dev->slock);
+ spin_unlock_irqrestore(&dev->slock, flags);
/* Reset urb buffers */
for (i = 0; i < urb->number_of_packets; i++) {
@@ -576,7 +577,7 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
p += 4;
au0828_isocdbg("Video frame %s\n",
(fbyte & 0x40) ? "odd" : "even");
- if (!(fbyte & 0x40)) {
+ if (fbyte & 0x40) {
/* VBI */
if (vbi_buf != NULL)
vbi_buffer_filled(dev,
@@ -597,6 +598,15 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
outp = NULL;
else
outp = videobuf_to_vmalloc(&buf->vb);
+
+ /* As long as isoc traffic is arriving, keep
+ resetting the timer */
+ if (dev->vid_timeout_running)
+ mod_timer(&dev->vid_timeout,
+ jiffies + (HZ / 10));
+ if (dev->vbi_timeout_running)
+ mod_timer(&dev->vbi_timeout,
+ jiffies + (HZ / 10));
}
if (buf != NULL) {
@@ -907,6 +917,57 @@ static int get_ressource(struct au0828_fh *fh)
}
}
+/* This function ensures that video frames continue to be delivered even if
+ the ITU-656 input isn't receiving any data (thereby preventing applications
+ such as tvtime from hanging) */
+void au0828_vid_buffer_timeout(unsigned long data)
+{
+ struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dmaqueue *dma_q = &dev->vidq;
+ struct au0828_buffer *buf;
+ unsigned char *vid_data;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&dev->slock, flags);
+
+ buf = dev->isoc_ctl.buf;
+ if (buf != NULL) {
+ vid_data = videobuf_to_vmalloc(&buf->vb);
+ memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
+ buffer_filled(dev, dma_q, buf);
+ }
+ get_next_buf(dma_q, &buf);
+
+ if (dev->vid_timeout_running == 1)
+ mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
+
+ spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+void au0828_vbi_buffer_timeout(unsigned long data)
+{
+ struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dmaqueue *dma_q = &dev->vbiq;
+ struct au0828_buffer *buf;
+ unsigned char *vbi_data;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&dev->slock, flags);
+
+ buf = dev->isoc_ctl.vbi_buf;
+ if (buf != NULL) {
+ vbi_data = videobuf_to_vmalloc(&buf->vb);
+ memset(vbi_data, 0x00, buf->vb.size);
+ vbi_buffer_filled(dev, dma_q, buf);
+ }
+ vbi_get_next_buf(dma_q, &buf);
+
+ if (dev->vbi_timeout_running == 1)
+ mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+ spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+
static int au0828_v4l2_open(struct file *filp)
{
int ret = 0;
@@ -976,7 +1037,6 @@ static int au0828_v4l2_open(struct file *filp)
V4L2_FIELD_SEQ_TB,
sizeof(struct au0828_buffer), fh, NULL);
-
return ret;
}
@@ -987,11 +1047,19 @@ static int au0828_v4l2_close(struct file *filp)
struct au0828_dev *dev = fh->dev;
if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
+ /* Cancel timeout thread in case they didn't call streamoff */
+ dev->vid_timeout_running = 0;
+ del_timer_sync(&dev->vid_timeout);
+
videobuf_stop(&fh->vb_vidq);
res_free(fh, AU0828_RESOURCE_VIDEO);
}
if (res_check(fh, AU0828_RESOURCE_VBI)) {
+ /* Cancel timeout thread in case they didn't call streamoff */
+ dev->vbi_timeout_running = 0;
+ del_timer_sync(&dev->vbi_timeout);
+
videobuf_stop(&fh->vb_vbiq);
res_free(fh, AU0828_RESOURCE_VBI);
}
@@ -1048,6 +1116,13 @@ static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
if (!res_get(fh, AU0828_RESOURCE_VBI))
return -EBUSY;
+ if (dev->vbi_timeout_running == 0) {
+ /* Handle case where caller tries to read without
+ calling streamon first */
+ dev->vbi_timeout_running = 1;
+ mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+ }
+
return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK);
}
@@ -1577,10 +1652,15 @@ static int vidioc_streamon(struct file *file, void *priv,
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
}
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
rc = videobuf_streamon(&fh->vb_vidq);
- else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ dev->vid_timeout_running = 1;
+ mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
+ } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
rc = videobuf_streamon(&fh->vb_vbiq);
+ dev->vbi_timeout_running = 1;
+ mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+ }
return rc;
}
@@ -1607,6 +1687,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
fh, type, fh->resources, dev->resources);
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dev->vid_timeout_running = 0;
+ del_timer_sync(&dev->vid_timeout);
+
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
rc = au0828_stream_interrupt(dev);
if (rc != 0)
@@ -1621,6 +1704,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
videobuf_streamoff(&fh->vb_vidq);
res_free(fh, AU0828_RESOURCE_VIDEO);
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ dev->vbi_timeout_running = 0;
+ del_timer_sync(&dev->vbi_timeout);
+
videobuf_streamoff(&fh->vb_vbiq);
res_free(fh, AU0828_RESOURCE_VBI);
}
@@ -1840,6 +1926,14 @@ int au0828_analog_register(struct au0828_dev *dev,
INIT_LIST_HEAD(&dev->vbiq.active);
INIT_LIST_HEAD(&dev->vbiq.queued);
+ dev->vid_timeout.function = au0828_vid_buffer_timeout;
+ dev->vid_timeout.data = (unsigned long) dev;
+ init_timer(&dev->vid_timeout);
+
+ dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
+ dev->vbi_timeout.data = (unsigned long) dev;
+ init_timer(&dev->vbi_timeout);
+
dev->width = NTSC_STD_W;
dev->height = NTSC_STD_H;
dev->field_size = dev->width * dev->height;
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 9905bc4f5f59..9cde35321824 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -53,7 +53,7 @@
/* Defination for AU0828 USB transfer */
#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
-#define AU0828_ISO_PACKETS_PER_URB 10
+#define AU0828_ISO_PACKETS_PER_URB 128
#define AU0828_MIN_BUF 4
#define AU0828_DEF_BUF 8
@@ -204,6 +204,10 @@ struct au0828_dev {
unsigned int resources; /* resources in use */
struct video_device *vdev;
struct video_device *vbi_dev;
+ struct timer_list vid_timeout;
+ int vid_timeout_running;
+ struct timer_list vbi_timeout;
+ int vbi_timeout_running;
int width;
int height;
int vbi_width;
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index 1a4a89fdf767..7da5c2e1fc12 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -1,10 +1,10 @@
config VIDEO_BT848
tristate "BT848 Video For Linux"
- depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
+ depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index a529619e51f6..944fd16ab5e1 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4152,9 +4152,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
btv=(struct bttv *)dev_id;
- if (btv->custom_irq)
- handled = btv->custom_irq(btv);
-
count=0;
while (1) {
/* get/clear interrupt status bits */
@@ -4190,7 +4187,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
btv->field_count++;
if ((astat & BT848_INT_GPINT) && btv->remote) {
- wake_up(&btv->gpioq);
bttv_input_irq(btv);
}
@@ -4395,7 +4391,6 @@ static int __devinit bttv_probe(struct pci_dev *dev,
mutex_init(&btv->lock);
spin_lock_init(&btv->s_lock);
spin_lock_init(&btv->gpio_lock);
- init_waitqueue_head(&btv->gpioq);
init_waitqueue_head(&btv->i2c_queue);
INIT_LIST_HEAD(&btv->c.subs);
INIT_LIST_HEAD(&btv->capture);
@@ -4583,7 +4578,6 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
/* tell gpio modules we are leaving ... */
btv->shutdown=1;
- wake_up(&btv->gpioq);
bttv_input_fini(btv);
bttv_sub_del_devices(&btv->c);
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 6bf05a7dc5f9..7f48306133be 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -31,15 +31,9 @@
static int ir_debug;
module_param(ir_debug, int, 0644);
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
static int ir_rc5_remote_gap = 885;
module_param(ir_rc5_remote_gap, int, 0644);
-static int ir_rc5_key_timeout = 200;
-module_param(ir_rc5_key_timeout, int, 0644);
#undef dprintk
#define dprintk(arg...) do { \
@@ -55,7 +49,7 @@ module_param(ir_rc5_key_timeout, int, 0644);
static void ir_handle_key(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
u32 gpio,data;
/* read gpio value */
@@ -74,23 +68,22 @@ static void ir_handle_key(struct bttv *btv)
(gpio & ir->mask_keydown) ? " down" : "",
(gpio & ir->mask_keyup) ? " up" : "");
- if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
- (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(ir->dev, &ir->ir, data);
+ if ((ir->mask_keydown && (gpio & ir->mask_keydown)) ||
+ (ir->mask_keyup && !(gpio & ir->mask_keyup))) {
+ rc_keydown_notimeout(ir->dev, data, 0);
} else {
/* HACK: Probably, ir->mask_keydown is missing
for this board */
if (btv->c.type == BTTV_BOARD_WINFAST2000)
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
- ir_input_nokey(ir->dev,&ir->ir);
+ rc_keyup(ir->dev);
}
-
}
static void ir_enltv_handle_key(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
u32 gpio, data, keyup;
/* read gpio value */
@@ -107,9 +100,9 @@ static void ir_enltv_handle_key(struct bttv *btv)
gpio, data,
(gpio & ir->mask_keyup) ? " up" : "up/down");
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
if (keyup)
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
} else {
if ((ir->last_gpio & 1 << 31) == keyup)
return;
@@ -119,26 +112,30 @@ static void ir_enltv_handle_key(struct bttv *btv)
(gpio & ir->mask_keyup) ? " up" : "down");
if (keyup)
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
else
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
}
ir->last_gpio = data | keyup;
}
+static int bttv_rc5_irq(struct bttv *btv);
+
void bttv_input_irq(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
- if (!ir->polling)
+ if (ir->rc5_gpio)
+ bttv_rc5_irq(btv);
+ else if (!ir->polling)
ir_handle_key(btv);
}
static void bttv_input_timer(unsigned long data)
{
struct bttv *btv = (struct bttv*)data;
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
if (btv->c.type == BTTV_BOARD_ENLTV_FM_2)
ir_enltv_handle_key(btv);
@@ -147,11 +144,109 @@ static void bttv_input_timer(unsigned long data)
mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
}
-/* ---------------------------------------------------------------*/
+/*
+ * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying
+ * on the rc-core way. As we need to be sure that both IRQ transitions are
+ * properly triggered, Better to touch it only with this hardware for
+ * testing.
+ */
+
+#define RC5_START(x) (((x) >> 12) & 3)
+#define RC5_TOGGLE(x) (((x) >> 11) & 1)
+#define RC5_ADDR(x) (((x) >> 6) & 31)
+#define RC5_INSTR(x) ((x) & 63)
+
+/* decode raw bit pattern to RC5 code */
+static u32 bttv_rc5_decode(unsigned int code)
+{
+ unsigned int org_code = code;
+ unsigned int pair;
+ unsigned int rc5 = 0;
+ int i;
+
+ for (i = 0; i < 14; ++i) {
+ pair = code & 0x3;
+ code >>= 2;
+
+ rc5 <<= 1;
+ switch (pair) {
+ case 0:
+ case 2:
+ break;
+ case 1:
+ rc5 |= 1;
+ break;
+ case 3:
+ dprintk(KERN_INFO DEVNAME ":rc5_decode(%x) bad code\n",
+ org_code);
+ return 0;
+ }
+ }
+ dprintk(KERN_INFO DEVNAME ":"
+ "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+ "instr=%x\n", rc5, org_code, RC5_START(rc5),
+ RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+ return rc5;
+}
+
+static void bttv_rc5_timer_end(unsigned long data)
+{
+ struct bttv_ir *ir = (struct bttv_ir *)data;
+ struct timeval tv;
+ unsigned long current_jiffies;
+ u32 gap;
+ u32 rc5 = 0;
+
+ /* get time */
+ current_jiffies = jiffies;
+ do_gettimeofday(&tv);
+
+ /* avoid overflow with gap >1s */
+ if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+ gap = 200000;
+ } else {
+ gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+ tv.tv_usec - ir->base_time.tv_usec;
+ }
+
+ /* signal we're ready to start a new code */
+ ir->active = false;
+
+ /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
+ if (gap < 28000) {
+ dprintk(KERN_INFO DEVNAME ": spurious timer_end\n");
+ return;
+ }
+
+ if (ir->last_bit < 20) {
+ /* ignore spurious codes (caused by light/other remotes) */
+ dprintk(KERN_INFO DEVNAME ": short code: %x\n", ir->code);
+ } else {
+ ir->code = (ir->code << ir->shift_by) | 1;
+ rc5 = bttv_rc5_decode(ir->code);
+
+ /* two start bits? */
+ if (RC5_START(rc5) != ir->start) {
+ printk(KERN_INFO DEVNAME ":"
+ " rc5 start bits invalid: %u\n", RC5_START(rc5));
+
+ /* right address? */
+ } else if (RC5_ADDR(rc5) == ir->addr) {
+ u32 toggle = RC5_TOGGLE(rc5);
+ u32 instr = RC5_INSTR(rc5);
+
+ /* Good code */
+ rc_keydown(ir->dev, instr, toggle);
+ dprintk(KERN_INFO DEVNAME ":"
+ " instruction %x, toggle %x\n",
+ instr, toggle);
+ }
+ }
+}
static int bttv_rc5_irq(struct bttv *btv)
{
- struct card_ir *ir = btv->remote;
+ struct bttv_ir *ir = btv->remote;
struct timeval tv;
u32 gpio;
u32 gap;
@@ -160,10 +255,6 @@ static int bttv_rc5_irq(struct bttv *btv)
/* read gpio port */
gpio = bttv_gpio_read(&btv->c);
- /* remote IRQ? */
- if (!(gpio & 0x20))
- return 0;
-
/* get time of bit */
current_jiffies = jiffies;
do_gettimeofday(&tv);
@@ -176,6 +267,13 @@ static int bttv_rc5_irq(struct bttv *btv)
tv.tv_usec - ir->base_time.tv_usec;
}
+ dprintk(KERN_INFO DEVNAME ": RC5 IRQ: gap %d us for %s\n",
+ gap, (gpio & 0x20) ? "mark" : "space");
+
+ /* remote IRQ? */
+ if (!(gpio & 0x20))
+ return 0;
+
/* active code => add bit */
if (ir->active) {
/* only if in the code (otherwise spurious IRQ or timer
@@ -187,13 +285,12 @@ static int bttv_rc5_irq(struct bttv *btv)
}
/* starting new code */
} else {
- ir->active = 1;
+ ir->active = true;
ir->code = 0;
ir->base_time = tv;
ir->last_bit = 0;
- mod_timer(&ir->timer_end,
- current_jiffies + msecs_to_jiffies(30));
+ mod_timer(&ir->timer, current_jiffies + msecs_to_jiffies(30));
}
/* toggle GPIO pin 4 to reset the irq */
@@ -204,7 +301,7 @@ static int bttv_rc5_irq(struct bttv *btv)
/* ---------------------------------------------------------------------- */
-static void bttv_ir_start(struct bttv *btv, struct card_ir *ir)
+static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
{
if (ir->polling) {
setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv);
@@ -212,17 +309,10 @@ static void bttv_ir_start(struct bttv *btv, struct card_ir *ir)
add_timer(&ir->timer);
} else if (ir->rc5_gpio) {
/* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_rc5_timer_end;
- ir->timer_end.data = (unsigned long)ir;
-
- init_timer(&ir->timer_keyup);
- ir->timer_keyup.function = ir_rc5_timer_keyup;
- ir->timer_keyup.data = (unsigned long)ir;
+ setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir);
ir->shift_by = 1;
ir->start = 3;
ir->addr = 0x0;
- ir->rc5_key_timeout = ir_rc5_key_timeout;
ir->rc5_remote_gap = ir_rc5_remote_gap;
}
}
@@ -237,7 +327,7 @@ static void bttv_ir_stop(struct bttv *btv)
if (btv->remote->rc5_gpio) {
u32 gpio;
- del_timer_sync(&btv->remote->timer_end);
+ del_timer_sync(&btv->remote->timer);
flush_scheduled_work();
gpio = bttv_gpio_read(&btv->c);
@@ -290,16 +380,15 @@ void __devinit init_bttv_i2c_ir(struct bttv *btv)
btv->init_data.name = "PV951";
btv->init_data.get_key = get_key_pv951;
btv->init_data.ir_codes = RC_MAP_PV951;
- btv->init_data.type = IR_TYPE_OTHER;
info.addr = 0x4b;
break;
default:
/*
* The external IR receiver is at i2c address 0x34 (0x35 for
- * reads). Future Hauppauge cards will have an internal
- * receiver at 0x30 (0x31 for reads). In theory, both can be
- * fitted, and Hauppauge suggest an external overrides an
- * internal.
+ * reads). Future Hauppauge cards will have an internal
+ * receiver at 0x30 (0x31 for reads). In theory, both can be
+ * fitted, and Hauppauge suggest an external overrides an
+ * internal.
* That's why we probe 0x1a (~0x34) first. CB
*/
@@ -324,18 +413,17 @@ int __devexit fini_bttv_i2c(struct bttv *btv)
int bttv_input_init(struct bttv *btv)
{
- struct card_ir *ir;
+ struct bttv_ir *ir;
char *ir_codes = NULL;
- struct input_dev *input_dev;
- u64 ir_type = IR_TYPE_OTHER;
+ struct rc_dev *rc;
int err = -ENOMEM;
if (!btv->has_remote)
return -ENODEV;
ir = kzalloc(sizeof(*ir),GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ rc = rc_allocate_device();
+ if (!ir || !rc)
goto err_out_free;
/* detect & configure */
@@ -398,8 +486,7 @@ int bttv_input_init(struct bttv *btv)
break;
case BTTV_BOARD_NEBULA_DIGITV:
ir_codes = RC_MAP_NEBULA;
- btv->custom_irq = bttv_rc5_irq;
- ir->rc5_gpio = 1;
+ ir->rc5_gpio = true;
break;
case BTTV_BOARD_MACHTV_MAGICTV:
ir_codes = RC_MAP_APAC_VIEWCOMP;
@@ -441,48 +528,43 @@ int bttv_input_init(struct bttv *btv)
}
/* init input device */
- ir->dev = input_dev;
+ ir->dev = rc;
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
btv->c.type);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(btv->c.pci));
- err = ir_input_init(input_dev, &ir->ir, ir_type);
- if (err < 0)
- goto err_out_free;
-
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (btv->c.pci->subsystem_vendor) {
- input_dev->id.vendor = btv->c.pci->subsystem_vendor;
- input_dev->id.product = btv->c.pci->subsystem_device;
+ rc->input_id.vendor = btv->c.pci->subsystem_vendor;
+ rc->input_id.product = btv->c.pci->subsystem_device;
} else {
- input_dev->id.vendor = btv->c.pci->vendor;
- input_dev->id.product = btv->c.pci->device;
+ rc->input_id.vendor = btv->c.pci->vendor;
+ rc->input_id.product = btv->c.pci->device;
}
- input_dev->dev.parent = &btv->c.pci->dev;
+ rc->dev.parent = &btv->c.pci->dev;
+ rc->map_name = ir_codes;
+ rc->driver_name = MODULE_NAME;
btv->remote = ir;
bttv_ir_start(btv, ir);
/* all done */
- err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_stop;
- /* the remote isn't as bouncy as a keyboard */
- ir->dev->rep[REP_DELAY] = repeat_delay;
- ir->dev->rep[REP_PERIOD] = repeat_period;
-
return 0;
err_out_stop:
bttv_ir_stop(btv);
btv->remote = NULL;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -493,7 +575,7 @@ void bttv_input_fini(struct bttv *btv)
return;
bttv_ir_stop(btv);
- ir_input_unregister(btv->remote->dev);
+ rc_unregister_device(btv->remote->dev);
kfree(btv->remote);
btv->remote = NULL;
}
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 6fd2a8ebda1e..fd62bf15d779 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -17,7 +17,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/ir-common.h>
#include <media/i2c-addr.h>
#include <media/tuner.h>
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index d1e26a448ed2..9b776faf0741 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -41,7 +41,7 @@
#include <linux/device.h>
#include <media/videobuf-dma-sg.h>
#include <media/tveeprom.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
#include "bt848.h"
@@ -120,6 +120,33 @@ struct bttv_format {
int hshift,vshift; /* for planar modes */
};
+struct bttv_ir {
+ struct rc_dev *dev;
+ struct timer_list timer;
+
+ char name[32];
+ char phys[32];
+
+ /* Usual gpio signalling */
+ u32 mask_keycode;
+ u32 mask_keydown;
+ u32 mask_keyup;
+ u32 polling;
+ u32 last_gpio;
+ int shift_by;
+ int start; // What should RC5_START() be
+ int addr; // What RC5_ADDR() should be.
+ int rc5_remote_gap;
+
+ /* RC5 gpio */
+ bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */
+ u32 last_bit; /* last raw bit seen */
+ u32 code; /* raw code under construction */
+ struct timeval base_time; /* time of last seen code */
+ bool active; /* building raw code */
+};
+
+
/* ---------------------------------------------------------- */
struct bttv_geometry {
@@ -305,7 +332,6 @@ struct bttv_pll_info {
/* for gpio-connected remote control */
struct bttv_input {
struct input_dev *dev;
- struct ir_input_state ir;
char name[32];
char phys[32];
u32 mask_keycode;
@@ -338,12 +364,10 @@ struct bttv {
struct bttv_pll_info pll;
int triton1;
int gpioirq;
- int (*custom_irq)(struct bttv *btv);
int use_i2c_hw;
/* old gpio interface */
- wait_queue_head_t gpioq;
int shutdown;
void (*volume_gpio)(struct bttv *btv, __u16 volume);
@@ -368,7 +392,7 @@ struct bttv {
/* infrared remote */
int has_remote;
- struct card_ir *remote;
+ struct bttv_ir *remote;
/* I2C remote data */
struct IR_i2c_init_data init_data;
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 935e0c9a9674..c1193506131c 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
static const struct v4l2_file_operations qcam_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = qcam_read,
};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 6e4b19698c13..24fc00965a12 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
static const struct v4l2_file_operations qcam_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = qcam_read,
};
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 0a9a3341e92d..49f1b8f1418e 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -859,8 +859,6 @@ static int cafe_cam_configure(struct cafe_camera *cam)
struct v4l2_mbus_framefmt mbus_fmt;
int ret;
- if (cam->state != S_IDLE)
- return -EINVAL;
v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
ret = sensor_call(cam, core, init, 0);
if (ret == 0)
@@ -1775,7 +1773,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = {
.read = cafe_v4l_read,
.poll = cafe_v4l_poll,
.mmap = cafe_v4l_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
@@ -2194,12 +2192,13 @@ static int cafe_pci_resume(struct pci_dev *pdev)
return ret;
}
cafe_ctlr_init(cam);
- cafe_ctlr_power_down(cam);
mutex_lock(&cam->s_mutex);
if (cam->users > 0) {
cafe_ctlr_power_up(cam);
__cafe_cam_reset(cam);
+ } else {
+ cafe_ctlr_power_down(cam);
}
mutex_unlock(&cam->s_mutex);
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 76c054d1eef9..d9d2f6ad6ffb 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -1,9 +1,8 @@
config VIDEO_CX18
tristate "Conexant cx23418 MPEG encoder support"
depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
- depends on INPUT # due to VIDEO_IR
select I2C_ALGOBIT
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c
index 8f55692db36d..82d195be9197 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/video/cx18/cx18-alsa-pcm.c
@@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
- return snd_pcm_lib_ioctl(substream, cmd, arg);
+ struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+ int ret;
+
+ snd_cx18_lock(cxsc);
+ ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+ snd_cx18_unlock(cxsc);
+ return ret;
}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index fe1090940b01..52ba913b5af8 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -39,7 +39,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
.tv = { 0x61, 0x60, I2C_CLIENT_END },
};
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
+/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
This keeps the PCI ID database up to date. Note that the entries
must be added under vendor 0x4444 (Conexant) as subsystem IDs.
New vendor IDs should still be added to the vendor ID list. */
@@ -251,6 +251,66 @@ static const struct cx18_card cx18_card_mpc718 = {
/* ------------------------------------------------------------------------- */
+/* GoTView PCI */
+
+static const struct cx18_card_pci_info cx18_pci_gotview_dvd3[] = {
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_GOTVIEW, 0x3343 },
+ { 0, 0, 0 }
+};
+
+static const struct cx18_card cx18_card_gotview_dvd3 = {
+ .type = CX18_CARD_GOTVIEW_PCI_DVD3,
+ .name = "GoTView PCI DVD3 Hybrid",
+ .comment = "Experimenters needed for device to work well.\n"
+ "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
+ .v4l2_capabilities = CX18_CAP_ENCODER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
+ .video_inputs = {
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
+ { CX18_CARD_INPUT_SVIDEO1, 1,
+ CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
+ { CX18_CARD_INPUT_SVIDEO2, 2,
+ CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
+ { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
+ },
+ .audio_inputs = {
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
+ { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
+ },
+ .tuners = {
+ /* XC3028 tuner */
+ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
+ },
+ /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
+ .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
+ .ddr = {
+ /* Hynix HY5DU283222B DDR RAM */
+ .chip_config = 0x303,
+ .refresh = 0x3bd,
+ .timing1 = 0x36320966,
+ .timing2 = 0x1f,
+ .tune_lane = 0,
+ .initial_emrs = 2,
+ },
+ .gpio_init.initial_value = 0x1,
+ .gpio_init.direction = 0x3,
+
+ .gpio_audio_input = { .mask = 0x3,
+ .tuner = 0x1,
+ .linein = 0x2,
+ .radio = 0x1 },
+ .xceive_pin = 0,
+ .pci_list = cx18_pci_gotview_dvd3,
+ .i2c = &cx18_i2c_std,
+};
+
+/* ------------------------------------------------------------------------- */
+
/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
@@ -463,6 +523,7 @@ static const struct cx18_card *cx18_card_list[] = {
&cx18_card_toshiba_qosmio_dvbt,
&cx18_card_leadtek_pvr2100,
&cx18_card_leadtek_dvr3100h,
+ &cx18_card_gotview_dvd3
};
const struct cx18_card *cx18_get_card(u16 index)
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index df60f27337cf..98ac2e935743 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -156,6 +156,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
"\t\t\t 7 = Leadtek WinFast PVR2100\n"
"\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
+ "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -333,6 +334,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
tveeprom_hauppauge_analog(&c, tv, eedata);
break;
case CX18_CARD_YUAN_MPC718:
+ case CX18_CARD_GOTVIEW_PCI_DVD3:
tv->model = 0x718;
cx18_eeprom_dump(cx, eedata, sizeof(eedata));
CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 77be58c1096b..cf4f20e91858 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -84,7 +84,8 @@
#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
#define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */
-#define CX18_CARD_LAST 7
+#define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */
+#define CX18_CARD_LAST 8
#define CX18_ENC_STREAM_TYPE_MPG 0
#define CX18_ENC_STREAM_TYPE_TS 1
@@ -106,6 +107,7 @@
#define CX18_PCI_ID_CONEXANT 0x14f1
#define CX18_PCI_ID_TOSHIBA 0x1179
#define CX18_PCI_ID_LEADTEK 0x107D
+#define CX18_PCI_ID_GOTVIEW 0x5854
/* ======================================================================== */
/* ========================== START USER SETTABLE DMA VARIABLES =========== */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 6d19f040d70f..c7f0bad39ad0 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -203,6 +203,14 @@ static struct zl10353_config yuan_mpc718_zl10353_demod = {
.disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
};
+static struct zl10353_config gotview_dvd3_zl10353_demod = {
+ .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
+ .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
+ .parallel_ts = 1, /* Not a serial TS */
+ .no_tuner = 1, /* XC3028 is not behind the gate */
+ .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
+};
+
static int dvb_register(struct cx18_stream *stream);
/* Kernel DVB framework calls this when the feed needs to start.
@@ -247,6 +255,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
case CX18_CARD_LEADTEK_DVR3100H:
case CX18_CARD_YUAN_MPC718:
+ case CX18_CARD_GOTVIEW_PCI_DVD3:
default:
/* Assumption - Parallel transport - Signalling
* undefined or default.
@@ -495,6 +504,29 @@ static int dvb_register(struct cx18_stream *stream)
fe->ops.tuner_ops.set_config(fe, &ctrl);
}
break;
+ case CX18_CARD_GOTVIEW_PCI_DVD3:
+ dvb->fe = dvb_attach(zl10353_attach,
+ &gotview_dvd3_zl10353_demod,
+ &cx->i2c_adap[1]);
+ if (dvb->fe != NULL) {
+ struct dvb_frontend *fe;
+ struct xc2028_config cfg = {
+ .i2c_adap = &cx->i2c_adap[1],
+ .i2c_addr = 0xc2 >> 1,
+ .ctrl = NULL,
+ };
+ static struct xc2028_ctrl ctrl = {
+ .fname = XC2028_DEFAULT_FIRMWARE,
+ .max_len = 64,
+ .demod = XC3028_FE_ZARLINK456,
+ .type = XC2028_AUTO,
+ };
+
+ fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
+ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
+ fe->ops.tuner_ops.set_config(fe, &ctrl);
+ }
+ break;
default:
/* No Digital Tv Support */
break;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index e71a026f3419..c330fb917b50 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -98,7 +98,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
case CX18_HW_Z8F0811_IR_RX_HAUP:
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = IR_TYPE_RC5;
+ init_data->type = RC_TYPE_RC5;
init_data->name = cx->card_name;
info.platform_data = init_data;
break;
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 9045f1ece0eb..ab461e27d9dd 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
.read = cx18_v4l2_read,
.open = cx18_v4l2_open,
/* FIXME change to video_ioctl2 if serialization lock can be removed */
- .ioctl = cx18_v4l2_ioctl,
+ .unlocked_ioctl = cx18_v4l2_ioctl,
.release = cx18_v4l2_close,
.poll = cx18_v4l2_enc_poll,
};
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig
index bb04914983fd..ae85a7a7bd73 100644
--- a/drivers/media/video/cx231xx/Kconfig
+++ b/drivers/media/video/cx231xx/Kconfig
@@ -1,9 +1,9 @@
config VIDEO_CX231XX
tristate "Conexant cx231xx USB video capture support"
- depends on VIDEO_DEV && I2C && INPUT
+ depends on VIDEO_DEV && I2C
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_VMALLOC
select VIDEO_CX25840
select VIDEO_CX2341X
@@ -14,6 +14,19 @@ config VIDEO_CX231XX
To compile this driver as a module, choose M here: the
module will be called cx231xx
+config VIDEO_CX231XX_RC
+ bool "Conexant cx231xx Remote Controller additional support"
+ depends on RC_CORE
+ depends on VIDEO_CX231XX
+ default y
+ ---help---
+ cx231xx hardware has a builtin RX/TX support. However, a few
+ designs opted to not use it, but, instead, some other hardware.
+ This module enables the usage of those other hardware, like the
+ ones used with ISDB-T boards.
+
+ On most cases, all you need for IR is mceusb module.
+
config VIDEO_CX231XX_ALSA
tristate "Conexant Cx231xx ALSA audio module"
depends on VIDEO_CX231XX && SND
@@ -30,6 +43,8 @@ config VIDEO_CX231XX_DVB
depends on VIDEO_CX231XX && DVB_CORE
select VIDEOBUF_DVB
select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_NXP18271 if !DVB_FE_CUSTOMISE
+ select DVB_MB86A20S if !DVB_FE_CUSTOMISE
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile
index a6bc4cc54677..2c2484355449 100644
--- a/drivers/media/video/cx231xx/Makefile
+++ b/drivers/media/video/cx231xx/Makefile
@@ -1,5 +1,6 @@
-cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \
- cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
+cx231xx-y += cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o
+cx231xx-y += cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
+cx231xx-$(CONFIG_VIDEO_CX231XX_RC) += cx231xx-input.o
cx231xx-alsa-objs := cx231xx-audio.o
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index 4c7cac3b6254..fc9526a5b746 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -940,14 +940,14 @@ static int cx231xx_load_firmware(struct cx231xx *dev)
u16 _buffer_size = 4096;
u8 *p_buffer;
- p_current_fw = (u32 *)vmalloc(1884180*4);
+ p_current_fw = vmalloc(1884180 * 4);
p_fw = p_current_fw;
if (p_current_fw == 0) {
dprintk(2, "FAIL!!!\n");
return -1;
}
- p_buffer = (u8 *)vmalloc(4096);
+ p_buffer = vmalloc(4096);
if (p_buffer == 0) {
dprintk(2, "FAIL!!!\n");
return -1;
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index cf50fafa8abb..d52955c21007 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -354,6 +354,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev,
case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
FLD_PWRDN_ENABLE_PLL)) {
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 2c78d188bb06..61756502c085 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -34,6 +34,7 @@
#include <media/cx25840.h>
#include "dvb-usb-ids.h"
#include "xc5000.h"
+#include "tda18271.h"
#include "cx231xx.h"
@@ -395,6 +396,45 @@ struct cx231xx_board cx231xx_boards[] = {
.gpio = 0,
} },
},
+ [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
+ .name = "Pixelview PlayTV USB Hybrid",
+ .tuner_type = TUNER_NXP_TDA18271,
+ .tuner_addr = 0x60,
+ .decoder = CX231XX_AVDECODER,
+ .output_mode = OUT_MODE_VIP11,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
+ .tuner_sif_gpio = -1,
+ .tuner_scl_gpio = -1,
+ .tuner_sda_gpio = -1,
+ .gpio_pin_status_mask = 0x4001000,
+ .tuner_i2c_master = 2,
+ .demod_i2c_master = 1,
+ .ir_i2c_master = 2,
+ .rc_map_name = RC_MAP_PIXELVIEW_NEW,
+ .has_dvb = 1,
+ .demod_addr = 0x10,
+ .norm = V4L2_STD_PAL_M,
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ } },
+ },
};
const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
@@ -402,8 +442,6 @@ const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
struct usb_device_id cx231xx_id_table[] = {
{USB_DEVICE(0x0572, 0x5A3C),
.driver_info = CX231XX_BOARD_UNKNOWN},
- {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
- .driver_info = CX231XX_BOARD_UNKNOWN},
{USB_DEVICE(0x0572, 0x58A2),
.driver_info = CX231XX_BOARD_CNXT_CARRAERA},
{USB_DEVICE(0x0572, 0x58A1),
@@ -424,6 +462,8 @@ struct usb_device_id cx231xx_id_table[] = {
.driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
{USB_DEVICE(0x2040, 0xc200),
.driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
+ {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
+ .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
{},
};
@@ -453,6 +493,16 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
1);
msleep(10);
}
+ } else if (dev->tuner_type == TUNER_NXP_TDA18271) {
+ switch (command) {
+ case TDA18271_CALLBACK_CMD_AGC_ENABLE:
+ if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
+ rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
}
return rc;
}
@@ -615,8 +665,11 @@ void cx231xx_release_resources(struct cx231xx *dev)
cx231xx_remove_from_devlist(dev);
+ /* Release I2C buses */
cx231xx_dev_uninit(dev);
+ cx231xx_ir_exit(dev);
+
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -731,16 +784,14 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
retval = cx231xx_register_analog_devices(dev);
if (retval < 0) {
cx231xx_release_resources(dev);
- goto fail_reg_devices;
+ return retval;
}
+ cx231xx_ir_init(dev);
+
cx231xx_init_extension(dev);
return 0;
-
-fail_reg_devices:
- mutex_unlock(&dev->lock);
- return retval;
}
#if defined(CONFIG_MODULES) && defined(MODULE)
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index 4af46fca9b0a..44d124c2fc35 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -740,6 +740,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
break;
default:
@@ -1288,7 +1289,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
/* Internal Master 3 Bus */
dev->i2c_bus[2].nr = 2;
dev->i2c_bus[2].dev = dev;
- dev->i2c_bus[2].i2c_period = I2C_SPEED_400K; /* 400kHz */
+ dev->i2c_bus[2].i2c_period = I2C_SPEED_100K; /* 100kHz */
dev->i2c_bus[2].i2c_nostop = 0;
dev->i2c_bus[2].i2c_reserve = 0;
@@ -1381,6 +1382,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
break;
default:
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index 5feb3ee640d9..fe59a1c3f064 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -33,6 +33,7 @@
#include "tda18271.h"
#include "s5h1411.h"
#include "lgdt3305.h"
+#include "mb86a20s.h"
MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
@@ -88,6 +89,11 @@ static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
.if_lvl = 1, .rfagc_top = 0x37, },
};
+static struct tda18271_std_map mb86a20s_tda18271_config = {
+ .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+ .if_lvl = 7, .rfagc_top = 0x37, },
+};
+
static struct tda18271_config cnxt_rde253s_tunerconfig = {
.std_map = &cnxt_rde253s_tda18271_std_map,
.gate = TDA18271_GATE_ANALOG,
@@ -135,6 +141,17 @@ static struct tda18271_config hcw_tda18271_config = {
.gate = TDA18271_GATE_DIGITAL,
};
+static const struct mb86a20s_config pv_mb86a20s_config = {
+ .demod_address = 0x10,
+ .is_serial = true,
+};
+
+static struct tda18271_config pv_tda18271_config = {
+ .std_map = &mb86a20s_tda18271_config,
+ .gate = TDA18271_GATE_DIGITAL,
+ .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
+};
+
static inline void print_err_status(struct cx231xx *dev, int packet, int status)
{
char *errmsg = "Unknown";
@@ -687,6 +704,29 @@ static int dvb_init(struct cx231xx *dev)
&hcw_tda18271_config);
break;
+ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+
+ printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
+ __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
+
+ dev->dvb->frontend = dvb_attach(mb86a20s_attach,
+ &pv_mb86a20s_config,
+ &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap);
+
+ if (dev->dvb->frontend == NULL) {
+ printk(DRIVER_NAME
+ ": Failed to attach mb86a20s demod\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ /* define general-purpose callback pointer */
+ dvb->frontend->callback = cx231xx_tuner_callback;
+
+ dvb_attach(tda18271_attach, dev->dvb->frontend,
+ 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
+ &pv_tda18271_config);
+ break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
new file mode 100644
index 000000000000..c236a4e7e97b
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -0,0 +1,101 @@
+/*
+ * cx231xx IR glue driver
+ *
+ * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * Polaris (cx231xx) has its support for IR's with a design close to MCE.
+ * however, a few designs are using an external I2C chip for IR, instead
+ * of using the one provided by the chip.
+ * This driver provides support for those extra devices
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include "cx231xx.h"
+#include <linux/usb.h>
+#include <linux/slab.h>
+
+#define MODULE_NAME "cx231xx-input"
+
+static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key,
+ u32 *ir_raw)
+{
+ u8 cmd;
+
+ dev_dbg(&ir->rc->input_dev->dev, "%s\n", __func__);
+
+ /* poll IR chip */
+ if (1 != i2c_master_recv(ir->c, &cmd, 1))
+ return -EIO;
+
+ /* it seems that 0xFE indicates that a button is still hold
+ down, while 0xff indicates that no button is hold
+ down. 0xfe sequences are sometimes interrupted by 0xFF */
+
+ if (cmd == 0xff)
+ return 0;
+
+ dev_dbg(&ir->rc->input_dev->dev, "scancode = %02x\n", cmd);
+
+ *ir_key = cmd;
+ *ir_raw = cmd;
+ return 1;
+}
+
+int cx231xx_ir_init(struct cx231xx *dev)
+{
+ struct i2c_board_info info;
+ u8 ir_i2c_bus;
+
+ dev_dbg(&dev->udev->dev, "%s\n", __func__);
+
+ /* Only initialize if a rc keycode map is defined */
+ if (!cx231xx_boards[dev->model].rc_map_name)
+ return -ENODEV;
+
+ request_module("ir-kbd-i2c");
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ memset(&dev->init_data, 0, sizeof(dev->init_data));
+ dev->init_data.rc_dev = rc_allocate_device();
+ if (!dev->init_data.rc_dev)
+ return -ENOMEM;
+
+ dev->init_data.name = cx231xx_boards[dev->model].name;
+
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ info.platform_data = &dev->init_data;
+
+ /*
+ * Board-dependent values
+ *
+ * For now, there's just one type of hardware design using
+ * an i2c device.
+ */
+ dev->init_data.get_key = get_key_isdbt;
+ dev->init_data.ir_codes = cx231xx_boards[dev->model].rc_map_name;
+ /* The i2c micro-controller only outputs the cmd part of NEC protocol */
+ dev->init_data.rc_dev->scanmask = 0xff;
+ dev->init_data.rc_dev->driver_name = "cx231xx";
+ dev->init_data.type = RC_TYPE_NEC;
+ info.addr = 0x30;
+
+ /* Load and bind ir-kbd-i2c */
+ ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master;
+ dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n",
+ ir_i2c_bus, info.addr);
+ i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info);
+
+ return 0;
+}
+
+void cx231xx_ir_exit(struct cx231xx *dev)
+{
+}
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index d067df9b81e7..72bbea2bcd56 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -34,7 +34,8 @@
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-device.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
+#include <media/ir-kbd-i2c.h>
#include <media/videobuf-dvb.h>
#include "cx231xx-reg.h"
@@ -62,6 +63,7 @@
#define CX231XX_BOARD_CNXT_RDU_250 7
#define CX231XX_BOARD_HAUPPAUGE_EXETER 8
#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
+#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
/* Limits minimum and default number of buffers */
#define CX231XX_MIN_BUF 4
@@ -344,6 +346,10 @@ struct cx231xx_board {
/* i2c masters */
u8 tuner_i2c_master;
u8 demod_i2c_master;
+ u8 ir_i2c_master;
+
+ /* for devices with I2C chips for IR */
+ char *rc_map_name;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
@@ -356,7 +362,7 @@ struct cx231xx_board {
struct cx231xx_input input[MAX_CX231XX_INPUT];
struct cx231xx_input radio;
- struct ir_scancode_table *ir_codes;
+ struct rc_map *ir_codes;
};
/* device states */
@@ -605,6 +611,9 @@ struct cx231xx {
struct cx231xx_board board;
+ /* For I2C IR support */
+ struct IR_i2c_init_data init_data;
+
unsigned int stream_on:1; /* Locks streams */
unsigned int vbi_stream_on:1; /* Locks streams for VBI */
unsigned int has_audio_class:1;
@@ -616,8 +625,6 @@ struct cx231xx {
struct v4l2_subdev *sd_cx25840;
struct v4l2_subdev *sd_tuner;
- struct cx231xx_IR *ir;
-
struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
atomic_t stream_started; /* stream should be running if true */
@@ -954,6 +961,17 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
extern int cx231xx_417_register(struct cx231xx *dev);
extern void cx231xx_417_unregister(struct cx231xx *dev);
+/* cx23885-input.c */
+
+#if defined(CONFIG_VIDEO_CX231XX_RC)
+int cx231xx_ir_init(struct cx231xx *dev);
+void cx231xx_ir_exit(struct cx231xx *dev);
+#else
+#define cx231xx_ir_init(dev) (0)
+#define cx231xx_ir_exit(dev) (0)
+#endif
+
+
/* printk macros */
#define cx231xx_err(fmt, arg...) do {\
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index e1367b35647a..6b4a516addfe 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_CX23885
select VIDEO_BTCX
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on IR_CORE
+ depends on RC_CORE
select VIDEOBUF_DVB
select VIDEOBUF_DMA_SG
select VIDEO_CX25840
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index bb61870b8d6e..0b0d0664382a 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -35,9 +35,8 @@
* 02110-1301, USA.
*/
-#include <linux/input.h>
#include <linux/slab.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <media/v4l2-subdev.h>
#include "cx23885.h"
@@ -62,16 +61,16 @@ static void cx23885_input_process_measurements(struct cx23885_dev *dev,
count = num / sizeof(struct ir_raw_event);
for (i = 0; i < count; i++) {
- ir_raw_event_store(kernel_ir->inp_dev,
+ ir_raw_event_store(kernel_ir->rc,
&ir_core_event[i]);
handle = true;
}
} while (num != 0);
if (overrun)
- ir_raw_event_reset(kernel_ir->inp_dev);
+ ir_raw_event_reset(kernel_ir->rc);
else if (handle)
- ir_raw_event_handle(kernel_ir->inp_dev);
+ ir_raw_event_handle(kernel_ir->rc);
}
void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
@@ -197,9 +196,9 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev)
return 0;
}
-static int cx23885_input_ir_open(void *priv)
+static int cx23885_input_ir_open(struct rc_dev *rc)
{
- struct cx23885_kernel_ir *kernel_ir = priv;
+ struct cx23885_kernel_ir *kernel_ir = rc->priv;
if (kernel_ir->cx == NULL)
return -ENODEV;
@@ -234,9 +233,9 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev)
flush_scheduled_work();
}
-static void cx23885_input_ir_close(void *priv)
+static void cx23885_input_ir_close(struct rc_dev *rc)
{
- struct cx23885_kernel_ir *kernel_ir = priv;
+ struct cx23885_kernel_ir *kernel_ir = rc->priv;
if (kernel_ir->cx != NULL)
cx23885_input_ir_stop(kernel_ir->cx);
@@ -245,9 +244,7 @@ static void cx23885_input_ir_close(void *priv)
int cx23885_input_init(struct cx23885_dev *dev)
{
struct cx23885_kernel_ir *kernel_ir;
- struct input_dev *inp_dev;
- struct ir_dev_props *props;
-
+ struct rc_dev *rc;
char *rc_map;
enum rc_driver_type driver_type;
unsigned long allowed_protos;
@@ -267,14 +264,14 @@ int cx23885_input_init(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1250:
/* Integrated CX2388[58] IR controller */
driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = IR_TYPE_ALL;
+ allowed_protos = RC_TYPE_ALL;
/* The grey Hauppauge RC-5 remote */
rc_map = RC_MAP_RC5_HAUPPAUGE_NEW;
break;
case CX23885_BOARD_TEVII_S470:
/* Integrated CX23885 IR controller */
driver_type = RC_DRIVER_IR_RAW;
- allowed_protos = IR_TYPE_ALL;
+ allowed_protos = RC_TYPE_ALL;
/* A guess at the remote */
rc_map = RC_MAP_TEVII_NEC;
break;
@@ -294,37 +291,36 @@ int cx23885_input_init(struct cx23885_dev *dev)
pci_name(dev->pci));
/* input device */
- inp_dev = input_allocate_device();
- if (inp_dev == NULL) {
+ rc = rc_allocate_device();
+ if (!rc) {
ret = -ENOMEM;
goto err_out_free;
}
- kernel_ir->inp_dev = inp_dev;
- inp_dev->name = kernel_ir->name;
- inp_dev->phys = kernel_ir->phys;
- inp_dev->id.bustype = BUS_PCI;
- inp_dev->id.version = 1;
+ kernel_ir->rc = rc;
+ rc->input_name = kernel_ir->name;
+ rc->input_phys = kernel_ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) {
- inp_dev->id.vendor = dev->pci->subsystem_vendor;
- inp_dev->id.product = dev->pci->subsystem_device;
+ rc->input_id.vendor = dev->pci->subsystem_vendor;
+ rc->input_id.product = dev->pci->subsystem_device;
} else {
- inp_dev->id.vendor = dev->pci->vendor;
- inp_dev->id.product = dev->pci->device;
+ rc->input_id.vendor = dev->pci->vendor;
+ rc->input_id.product = dev->pci->device;
}
- inp_dev->dev.parent = &dev->pci->dev;
-
- /* kernel ir device properties */
- props = &kernel_ir->props;
- props->driver_type = driver_type;
- props->allowed_protos = allowed_protos;
- props->priv = kernel_ir;
- props->open = cx23885_input_ir_open;
- props->close = cx23885_input_ir_close;
+ rc->dev.parent = &dev->pci->dev;
+ rc->driver_type = driver_type;
+ rc->allowed_protos = allowed_protos;
+ rc->priv = kernel_ir;
+ rc->open = cx23885_input_ir_open;
+ rc->close = cx23885_input_ir_close;
+ rc->map_name = rc_map;
+ rc->driver_name = MODULE_NAME;
/* Go */
dev->kernel_ir = kernel_ir;
- ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME);
+ ret = rc_register_device(rc);
if (ret)
goto err_out_stop;
@@ -333,7 +329,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
err_out_stop:
cx23885_input_ir_stop(dev);
dev->kernel_ir = NULL;
- /* TODO: double check clean-up of kernel_ir->inp_dev */
+ rc_free_device(rc);
err_out_free:
kfree(kernel_ir->phys);
kfree(kernel_ir->name);
@@ -348,7 +344,7 @@ void cx23885_input_fini(struct cx23885_dev *dev)
if (dev->kernel_ir == NULL)
return;
- ir_input_unregister(dev->kernel_ir->inp_dev);
+ rc_unregister_device(dev->kernel_ir->rc);
kfree(dev->kernel_ir->phys);
kfree(dev->kernel_ir->name);
kfree(dev->kernel_ir);
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index ed94b17dd8a5..fd387229daff 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -30,7 +30,7 @@
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
#include <media/videobuf-dvb.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "btcx-risc.h"
#include "cx23885-reg.h"
@@ -310,8 +310,7 @@ struct cx23885_kernel_ir {
char *name;
char *phys;
- struct input_dev *inp_dev;
- struct ir_dev_props props;
+ struct rc_dev *rc;
};
struct cx23885_dev {
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c
index e78e3e4c8112..e37be6fcf67d 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/video/cx23885/cx23888-ir.c
@@ -26,7 +26,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "cx23885.h"
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c
index 97a4e9b25fe4..627926f6bde8 100644
--- a/drivers/media/video/cx25840/cx25840-ir.c
+++ b/drivers/media/video/cx25840/cx25840-ir.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/kfifo.h>
#include <media/cx25840.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include "cx25840-core.h"
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 0fa85cbefbb1..5c42abdf422f 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -1,12 +1,11 @@
config VIDEO_CX88
tristate "Conexant 2388x (bt878 successor) support"
- depends on VIDEO_DEV && PCI && I2C && INPUT
+ depends on VIDEO_DEV && PCI && I2C && RC_CORE
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for Conexant 2388x based
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index d7c94848249e..bca307eb1e24 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1064,7 +1064,7 @@ static int mpeg_open(struct file *file)
err = drv->request_acquire(drv);
if(err != 0) {
dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
- mutex_unlock(&dev->core->lock);;
+ mutex_unlock(&dev->core->lock);
return err;
}
}
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 9b9e169cce90..7e0ee106e1d3 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -47,7 +47,7 @@ MODULE_PARM_DESC(latency,"pci latency timer");
static int disable_ir;
module_param(disable_ir, int, 0444);
-MODULE_PARM_DESC(latency, "Disable IR support");
+MODULE_PARM_DESC(disable_ir, "Disable IR support");
#define info_printk(core, fmt, arg...) \
printk(KERN_INFO "%s: " fmt, core->name , ## arg)
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index fc777bc6e716..4a3bf5476c71 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -24,14 +24,12 @@
#include <linux/init.h>
#include <linux/hrtimer.h>
-#include <linux/input.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include "cx88.h"
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#define MODULE_NAME "cx88xx"
@@ -39,9 +37,7 @@
struct cx88_IR {
struct cx88_core *core;
- struct input_dev *input;
- struct ir_dev_props props;
- u64 ir_type;
+ struct rc_dev *dev;
int users;
@@ -50,8 +46,6 @@ struct cx88_IR {
/* sample from gpio pin 16 */
u32 sampling;
- u32 samples[16];
- int scount;
/* poll external decoder */
int polling;
@@ -63,6 +57,10 @@ struct cx88_IR {
u32 mask_keyup;
};
+static unsigned ir_samplerate = 4;
+module_param(ir_samplerate, uint, 0444);
+MODULE_PARM_DESC(ir_samplerate, "IR samplerate in kHz, 1 - 20, default 4");
+
static int ir_debug;
module_param(ir_debug, int, 0644); /* debug level [IR] */
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
@@ -125,21 +123,26 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
data = (data << 4) | ((gpio_key & 0xf0) >> 4);
- ir_keydown(ir->input, data, 0);
+ rc_keydown(ir->dev, data, 0);
} else if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown)
- ir_keydown(ir->input, data, 0);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ else
+ rc_keyup(ir->dev);
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup))
- ir_keydown(ir->input, data, 0);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ else
+ rc_keyup(ir->dev);
} else {
/* can't distinguish keydown/up :-/ */
- ir_keydown(ir->input, data, 0);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keyup(ir->dev);
}
}
@@ -176,8 +179,8 @@ static int __cx88_ir_start(void *priv)
}
if (ir->sampling) {
core->pci_irqmask |= PCI_INT_IR_SMPINT;
- cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */
- cx_write(MO_DDSCFG_IO, 0x5); /* enable */
+ cx_write(MO_DDS_IO, 0x33F286 * ir_samplerate); /* samplerate */
+ cx_write(MO_DDSCFG_IO, 0x5); /* enable */
}
return 0;
}
@@ -214,17 +217,17 @@ void cx88_ir_stop(struct cx88_core *core)
__cx88_ir_stop(core);
}
-static int cx88_ir_open(void *priv)
+static int cx88_ir_open(struct rc_dev *rc)
{
- struct cx88_core *core = priv;
+ struct cx88_core *core = rc->priv;
core->ir->users++;
return __cx88_ir_start(core);
}
-static void cx88_ir_close(void *priv)
+static void cx88_ir_close(struct rc_dev *rc)
{
- struct cx88_core *core = priv;
+ struct cx88_core *core = rc->priv;
core->ir->users--;
if (!core->ir->users)
@@ -236,20 +239,20 @@ static void cx88_ir_close(void *priv)
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
{
struct cx88_IR *ir;
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char *ir_codes = NULL;
- u64 ir_type = IR_TYPE_OTHER;
+ u64 rc_type = RC_TYPE_OTHER;
int err = -ENOMEM;
u32 hardware_mask = 0; /* For devices with a hardware mask, when
* used with a full-code IR table
*/
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ dev = rc_allocate_device();
+ if (!ir || !dev)
goto err_out_free;
- ir->input = input_dev;
+ ir->dev = dev;
/* detect & configure */
switch (core->boardnr) {
@@ -264,7 +267,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
ir_codes = RC_MAP_CINERGY_1400;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xeb04; /* address */
break;
case CX88_BOARD_HAUPPAUGE:
@@ -279,7 +281,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_PCHDTV_HD5500:
case CX88_BOARD_HAUPPAUGE_IRONLY:
ir_codes = RC_MAP_HAUPPAUGE_NEW;
- ir_type = IR_TYPE_RC5;
ir->sampling = 1;
break;
case CX88_BOARD_WINFAST_DTV2000H:
@@ -367,18 +368,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_PROF_7301:
case CX88_BOARD_PROF_6200:
ir_codes = RC_MAP_TBS_NEC;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
case CX88_BOARD_TEVII_S460:
case CX88_BOARD_TEVII_S420:
ir_codes = RC_MAP_TEVII_NEC;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
ir_codes = RC_MAP_DNTV_LIVE_DVBT_PRO;
- ir_type = IR_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
case CX88_BOARD_NORWOOD_MICRO:
@@ -396,7 +394,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
ir_codes = RC_MAP_PINNACLE_PCTV_HD;
- ir_type = IR_TYPE_RC5;
ir->sampling = 1;
break;
case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
@@ -407,12 +404,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_TWINHAN_VP1027_DVBS:
ir_codes = RC_MAP_TWINHAN_VP1027_DVBS;
- ir_type = IR_TYPE_NEC;
+ rc_type = RC_TYPE_NEC;
ir->sampling = 0xff00; /* address */
break;
}
- if (NULL == ir_codes) {
+ if (!ir_codes) {
err = -ENODEV;
goto err_out_free;
}
@@ -436,37 +433,45 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
- ir->ir_type = ir_type;
-
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->input_name = ir->name;
+ dev->input_phys = ir->phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (pci->subsystem_vendor) {
- input_dev->id.vendor = pci->subsystem_vendor;
- input_dev->id.product = pci->subsystem_device;
+ dev->input_id.vendor = pci->subsystem_vendor;
+ dev->input_id.product = pci->subsystem_device;
} else {
- input_dev->id.vendor = pci->vendor;
- input_dev->id.product = pci->device;
+ dev->input_id.vendor = pci->vendor;
+ dev->input_id.product = pci->device;
}
- input_dev->dev.parent = &pci->dev;
- /* record handles to ourself */
+ dev->dev.parent = &pci->dev;
+ dev->map_name = ir_codes;
+ dev->driver_name = MODULE_NAME;
+ dev->priv = core;
+ dev->open = cx88_ir_open;
+ dev->close = cx88_ir_close;
+ dev->scanmask = hardware_mask;
+
+ if (ir->sampling) {
+ dev->driver_type = RC_DRIVER_IR_RAW;
+ dev->timeout = 10 * 1000 * 1000; /* 10 ms */
+ } else {
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ dev->allowed_protos = rc_type;
+ }
+
ir->core = core;
core->ir = ir;
- ir->props.priv = core;
- ir->props.open = cx88_ir_open;
- ir->props.close = cx88_ir_close;
- ir->props.scanmask = hardware_mask;
-
/* all done */
- err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
+ err = rc_register_device(dev);
if (err)
goto err_out_free;
return 0;
- err_out_free:
+err_out_free:
+ rc_free_device(dev);
core->ir = NULL;
kfree(ir);
return err;
@@ -481,7 +486,7 @@ int cx88_ir_fini(struct cx88_core *core)
return 0;
cx88_ir_stop(core);
- ir_input_unregister(ir->input);
+ rc_unregister_device(ir->dev);
kfree(ir);
/* done */
@@ -494,128 +499,34 @@ int cx88_ir_fini(struct cx88_core *core)
void cx88_ir_irq(struct cx88_core *core)
{
struct cx88_IR *ir = core->ir;
- u32 samples, ircode;
- int i, start, range, toggle, dev, code;
+ u32 samples;
+ unsigned todo, bits;
+ struct ir_raw_event ev;
- if (NULL == ir)
- return;
- if (!ir->sampling)
+ if (!ir || !ir->sampling)
return;
+ /*
+ * Samples are stored in a 32 bit register, oldest sample in
+ * the msb. A set bit represents space and an unset bit
+ * represents a pulse.
+ */
samples = cx_read(MO_SAMPLE_IO);
- if (0 != samples && 0xffffffff != samples) {
- /* record sample data */
- if (ir->scount < ARRAY_SIZE(ir->samples))
- ir->samples[ir->scount++] = samples;
- return;
- }
- if (!ir->scount) {
- /* nothing to sample */
- return;
- }
-
- /* have a complete sample */
- if (ir->scount < ARRAY_SIZE(ir->samples))
- ir->samples[ir->scount++] = samples;
- for (i = 0; i < ir->scount; i++)
- ir->samples[i] = ~ir->samples[i];
- if (ir_debug)
- ir_dump_samples(ir->samples, ir->scount);
-
- /* decode it */
- switch (core->boardnr) {
- case CX88_BOARD_TEVII_S460:
- case CX88_BOARD_TEVII_S420:
- case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
- case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
- case CX88_BOARD_OMICOM_SS4_PCI:
- case CX88_BOARD_SATTRADE_ST4200:
- case CX88_BOARD_TBS_8920:
- case CX88_BOARD_TBS_8910:
- case CX88_BOARD_PROF_7300:
- case CX88_BOARD_PROF_7301:
- case CX88_BOARD_PROF_6200:
- case CX88_BOARD_TWINHAN_VP1027_DVBS:
- ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
-
- if (ircode == 0xffffffff) { /* decoding error */
- ir_dprintk("pulse distance decoding error\n");
- break;
- }
-
- ir_dprintk("pulse distance decoded: %x\n", ircode);
-
- if (ircode == 0) { /* key still pressed */
- ir_dprintk("pulse distance decoded repeat code\n");
- ir_repeat(ir->input);
- break;
- }
-
- if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
- ir_dprintk("pulse distance decoded wrong address\n");
- break;
- }
- if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
- ir_dprintk("pulse distance decoded wrong check sum\n");
- break;
- }
+ if (samples == 0xff && ir->dev->idle)
+ return;
- ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0xff);
- ir_keydown(ir->input, (ircode >> 16) & 0xff, 0);
- break;
- case CX88_BOARD_HAUPPAUGE:
- case CX88_BOARD_HAUPPAUGE_DVB_T1:
- case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
- case CX88_BOARD_HAUPPAUGE_HVR1100:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- case CX88_BOARD_HAUPPAUGE_HVR4000:
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- case CX88_BOARD_PCHDTV_HD3000:
- case CX88_BOARD_PCHDTV_HD5500:
- case CX88_BOARD_HAUPPAUGE_IRONLY:
- ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
- ir_dprintk("biphase decoded: %x\n", ircode);
- /*
- * RC5 has an extension bit which adds a new range
- * of available codes, this is detected here. Also
- * hauppauge remotes (black/silver) always use
- * specific device ids. If we do not filter the
- * device ids then messages destined for devices
- * such as TVs (id=0) will get through to the
- * device causing mis-fired events.
- */
- /* split rc5 data block ... */
- start = (ircode & 0x2000) >> 13;
- range = (ircode & 0x1000) >> 12;
- toggle= (ircode & 0x0800) >> 11;
- dev = (ircode & 0x07c0) >> 6;
- code = (ircode & 0x003f) | ((range << 6) ^ 0x0040);
- if( start != 1)
- /* no key pressed */
- break;
- if ( dev != 0x1e && dev != 0x1f )
- /* not a hauppauge remote */
- break;
- ir_keydown(ir->input, code, toggle);
- break;
- case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
- ir_dprintk("biphase decoded: %x\n", ircode);
- if ((ircode & 0xfffff000) != 0x3000)
- break;
- /* Note: bit 0x800 being the toggle is assumed, not checked
- with real hardware */
- ir_keydown(ir->input, ircode & 0x3f, ircode & 0x0800 ? 1 : 0);
- break;
+ init_ir_raw_event(&ev);
+ for (todo = 32; todo > 0; todo -= bits) {
+ ev.pulse = samples & 0x80000000 ? false : true;
+ bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
+ ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate);
+ ir_raw_event_store_with_filter(ir->dev, &ev);
+ samples <<= bits;
}
-
- ir->scount = 0;
- return;
+ ir_raw_event_handle(ir->dev);
}
-
void cx88_i2c_init_ir(struct cx88_core *core)
{
struct i2c_board_info info;
@@ -646,7 +557,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
/* Hauppauge XVR */
core->init_data.name = "cx88 Hauppauge XVR remote";
core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW;
- core->init_data.type = IR_TYPE_RC5;
+ core->init_data.type = RC_TYPE_RC5;
core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
info.platform_data = &core->init_data;
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 7333a9bb2549..353eadaa823e 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -1276,7 +1276,7 @@ static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
vb->field = field;
- ret = videobuf_iolock(vq, vb, NULL);;
+ ret = videobuf_iolock(vq, vb, NULL);
if (ret < 0)
return ret;
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 66aefd6eef55..985100ea17a4 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,9 +1,9 @@
config VIDEO_EM28XX
tristate "Empia EM28xx USB video capture support"
- depends on VIDEO_DEV && I2C && INPUT
+ depends on VIDEO_DEV && I2C
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_VMALLOC
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
@@ -37,6 +37,7 @@ config VIDEO_EM28XX_DVB
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ select DVB_S921 if !DVB_FE_CUSTOMISE
select VIDEOBUF_DVB
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index f7e9168157a5..5d79d0eb64ab 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -268,6 +268,20 @@ static struct em28xx_reg_seq dikom_dk300_digital[] = {
};
+/* Reset for the most [digital] boards */
+static struct em28xx_reg_seq leadership_digital[] = {
+ {EM2874_R80_GPIO, 0x70, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq leadership_reset[] = {
+ {EM2874_R80_GPIO, 0xf0, 0xff, 10},
+ {EM2874_R80_GPIO, 0xb0, 0xff, 10},
+ {EM2874_R80_GPIO, 0xf0, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+
/*
* Board definitions
*/
@@ -1224,6 +1238,19 @@ struct em28xx_board em28xx_boards[] = {
.vmux = SAA7115_COMPOSITE0,
} },
},
+
+ [EM2874_LEADERSHIP_ISDBT] = {
+ .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
+ EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_FREQ_100_KHZ,
+ .xclk = EM28XX_XCLK_FREQUENCY_10MHZ,
+ .name = "EM2874 Leadership ISDBT",
+ .tuner_type = TUNER_ABSENT,
+ .tuner_gpio = leadership_reset,
+ .dvb_gpio = leadership_digital,
+ .has_dvb = 1,
+ },
+
[EM2880_BOARD_MSI_DIGIVOX_AD] = {
.name = "MSI DigiVox A/D",
.valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -1469,7 +1496,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
- .name = "Terratec Hybrid XS (em2882)",
+ .name = "Terratec Cinnergy Hybrid T USB XS (em2882)",
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.mts_firmware = 1,
@@ -1754,6 +1781,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2868),
.driver_info = EM2820_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0x2875),
+ .driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0xe300),
.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
{ USB_DEVICE(0xeb1a, 0xe303),
@@ -1791,7 +1820,7 @@ struct usb_device_id em28xx_id_table[] = {
{ USB_DEVICE(0x0ccd, 0x005e),
.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
{ USB_DEVICE(0x0ccd, 0x0042),
- .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
+ .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
{ USB_DEVICE(0x0ccd, 0x0043),
.driver_info = EM2870_BOARD_TERRATEC_XS },
{ USB_DEVICE(0x0ccd, 0x0047),
@@ -1873,6 +1902,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
{0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
+ {0x6b800080, EM2874_LEADERSHIP_ISDBT, TUNER_ABSENT},
};
/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
@@ -2408,7 +2438,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
dev->init_data.get_key = em28xx_get_key_em_haup;
dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
- dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;;
+ dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
break;
@@ -2430,8 +2460,36 @@ void em28xx_card_setup(struct em28xx *dev)
dev->board.is_webcam = 0;
else
dev->progressive = 1;
- } else
- em28xx_set_model(dev);
+ }
+
+ if (!dev->board.is_webcam) {
+ switch (dev->model) {
+ case EM2820_BOARD_UNKNOWN:
+ case EM2800_BOARD_UNKNOWN:
+ /*
+ * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
+ *
+ * This occurs because they share identical USB vendor and
+ * product IDs.
+ *
+ * What we do here is look up the EEPROM hash of the K-WORLD
+ * and if it is found then we decide that we do not have
+ * a DIGIVOX and reset the device to the K-WORLD instead.
+ *
+ * This solution is only valid if they do not share eeprom
+ * hash identities which has not been determined as yet.
+ */
+ if (em28xx_hint_board(dev) < 0)
+ em28xx_errdev("Board not discovered\n");
+ else {
+ em28xx_set_model(dev);
+ em28xx_pre_card_setup(dev);
+ }
+ break;
+ default:
+ em28xx_set_model(dev);
+ }
+ }
em28xx_info("Identified as %s (card=%d)\n",
dev->board.name, dev->model);
@@ -2749,8 +2807,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
em28xx_pre_card_setup(dev);
if (!dev->board.is_em2800) {
- /* Sets I2C speed to 100 KHz */
- retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
+ /* Resets I2C speed */
+ em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_regs_req failed!"
" retval [%d]\n",
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 3ac8d3025fea..c7c04bf712aa 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -37,6 +37,7 @@
#include "mt352_priv.h" /* FIXME */
#include "tda1002x.h"
#include "tda18271.h"
+#include "s921.h"
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -245,6 +246,10 @@ static struct lgdt3305_config em2870_lgdt3304_dev = {
.qam_if_khz = 4000,
};
+static struct s921_config sharp_isdbt = {
+ .demod_address = 0x30 >> 1
+};
+
static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
@@ -481,6 +486,7 @@ static int dvb_init(struct em28xx *dev)
if (!dev->board.has_dvb) {
/* This device does not support the extension */
+ printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n");
return 0;
}
@@ -496,6 +502,16 @@ static int dvb_init(struct em28xx *dev)
em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
/* init frontend */
switch (dev->model) {
+ case EM2874_LEADERSHIP_ISDBT:
+ dvb->frontend = dvb_attach(s921_attach,
+ &sharp_isdbt, &dev->i2c_adap);
+
+ if (!dvb->frontend) {
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ break;
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 6759cd5570dd..29cc74441a7d 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/usb.h>
#include <linux/slab.h>
@@ -64,7 +63,7 @@ struct em28xx_ir_poll_result {
struct em28xx_IR {
struct em28xx *dev;
- struct input_dev *input;
+ struct rc_dev *rc;
char name[32];
char phys[32];
@@ -75,10 +74,6 @@ struct em28xx_IR {
unsigned int last_readcount;
int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
-
- /* IR device properties */
-
- struct ir_dev_props props;
};
/**********************************************************
@@ -302,12 +297,12 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
poll_result.toggle_bit, poll_result.read_count,
poll_result.rc_address, poll_result.rc_data[0]);
if (ir->full_code)
- ir_keydown(ir->input,
+ rc_keydown(ir->rc,
poll_result.rc_address << 8 |
poll_result.rc_data[0],
poll_result.toggle_bit);
else
- ir_keydown(ir->input,
+ rc_keydown(ir->rc,
poll_result.rc_data[0],
poll_result.toggle_bit);
@@ -331,9 +326,9 @@ static void em28xx_ir_work(struct work_struct *work)
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
-static int em28xx_ir_start(void *priv)
+static int em28xx_ir_start(struct rc_dev *rc)
{
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc->priv;
INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
schedule_delayed_work(&ir->work, 0);
@@ -341,30 +336,30 @@ static int em28xx_ir_start(void *priv)
return 0;
}
-static void em28xx_ir_stop(void *priv)
+static void em28xx_ir_stop(struct rc_dev *rc)
{
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc->priv;
cancel_delayed_work_sync(&ir->work);
}
-int em28xx_ir_change_protocol(void *priv, u64 ir_type)
+int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
{
int rc = 0;
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc_dev->priv;
struct em28xx *dev = ir->dev;
u8 ir_config = EM2874_IR_RC5;
/* Adjust xclk based o IR table for RC5/NEC tables */
- if (ir_type == IR_TYPE_RC5) {
+ if (rc_type == RC_TYPE_RC5) {
dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
ir->full_code = 1;
- } else if (ir_type == IR_TYPE_NEC) {
+ } else if (rc_type == RC_TYPE_NEC) {
dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
ir_config = EM2874_IR_NEC;
ir->full_code = 1;
- } else if (ir_type != IR_TYPE_UNKNOWN)
+ } else if (rc_type != RC_TYPE_UNKNOWN)
rc = -EINVAL;
em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
@@ -391,7 +386,7 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type)
int em28xx_ir_init(struct em28xx *dev)
{
struct em28xx_IR *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
if (dev->board.ir_codes == NULL) {
@@ -400,28 +395,27 @@ int em28xx_ir_init(struct em28xx *dev)
}
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ rc = rc_allocate_device();
+ if (!ir || !rc)
goto err_out_free;
/* record handles to ourself */
ir->dev = dev;
dev->ir = ir;
-
- ir->input = input_dev;
+ ir->rc = rc;
/*
* em2874 supports more protocols. For now, let's just announce
* the two protocols that were already tested
*/
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.priv = ir;
- ir->props.change_protocol = em28xx_ir_change_protocol;
- ir->props.open = em28xx_ir_start;
- ir->props.close = em28xx_ir_stop;
+ rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+ rc->priv = ir;
+ rc->change_protocol = em28xx_ir_change_protocol;
+ rc->open = em28xx_ir_start;
+ rc->close = em28xx_ir_stop;
/* By default, keep protocol field untouched */
- err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
+ err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
if (err)
goto err_out_free;
@@ -435,27 +429,27 @@ int em28xx_ir_init(struct em28xx *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_USB;
- input_dev->id.version = 1;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
-
- input_dev->dev.parent = &dev->udev->dev;
-
-
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ rc->dev.parent = &dev->udev->dev;
+ rc->map_name = dev->board.ir_codes;
+ rc->driver_name = MODULE_NAME;
/* all done */
- err = ir_input_register(ir->input, dev->board.ir_codes,
- &ir->props, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_stop;
return 0;
+
err_out_stop:
dev->ir = NULL;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -468,8 +462,8 @@ int em28xx_ir_fini(struct em28xx *dev)
if (!ir)
return 0;
- em28xx_ir_stop(ir);
- ir_input_unregister(ir->input);
+ em28xx_ir_stop(ir->rc);
+ rc_unregister_device(ir->rc);
kfree(ir);
/* done */
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6a75e6a4fc21..6f2795a3d4b7 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -33,7 +33,7 @@
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/ir-kbd-i2c.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
#include <media/videobuf-dvb.h>
#endif
@@ -117,6 +117,8 @@
#define EM2800_BOARD_VC211A 74
#define EM2882_BOARD_DIKOM_DK300 75
#define EM2870_BOARD_KWORLD_A340 76
+#define EM2874_LEADERSHIP_ISDBT 77
+
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index a5cfc76b40b7..bb164099ea2c 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = {
.owner = THIS_MODULE,
.open = et61x251_open,
.release = et61x251_release,
- .ioctl = et61x251_ioctl,
+ .unlocked_ioctl = et61x251_ioctl,
.read = et61x251_read,
.poll = et61x251_poll,
.mmap = et61x251_mmap,
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 9b121681d135..c1ae05f4661f 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -37,7 +37,7 @@ MODULE_LICENSE("GPL");
/* constant value's */
#define MAGIC_0 0x19
#define MAGIC_1 0x68
-#define DATA_IN 0xC0
+#define DATA_IN 0xc0
#define DATA_OUT 0x40
#define VIDEOSIZE_QCIF 0 /* 176x144 */
#define VIDEOSIZE_CIF 1 /* 352x288 */
@@ -660,9 +660,9 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command,
if (sd->params.qx3.button) {
/* button pressed - unlock the latch */
do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
- 3, 0xDF, 0xDF, 0);
+ 3, 0xdf, 0xdf, 0);
do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
- 3, 0xFF, 0xFF, 0);
+ 3, 0xff, 0xff, 0);
}
/* test whether microscope is cradled */
@@ -829,7 +829,7 @@ static int goto_low_power(struct gspca_dev *gspca_dev)
if (ret)
return ret;
- do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+ ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
if (ret)
return ret;
@@ -1110,12 +1110,12 @@ static int command_setlights(struct gspca_dev *gspca_dev)
p2 = (sd->params.qx3.toplight == 0) << 3;
ret = do_command(gspca_dev, CPIA_COMMAND_WriteVCReg,
- 0x90, 0x8F, 0x50, 0);
+ 0x90, 0x8f, 0x50, 0);
if (ret)
return ret;
return do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 2, 0,
- p1 | p2 | 0xE0, 0);
+ p1 | p2 | 0xe0, 0);
}
static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply)
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 8fe8fb486d62..5a2274b2b0e8 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 10, 0)
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 11, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -224,12 +224,12 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
buffer, buffer_len,
int_irq, (void *)gspca_dev, interval);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- gspca_dev->int_urb = urb;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret < 0) {
PDEBUG(D_ERR, "submit int URB failed with error %i", ret);
goto error_submit;
}
+ gspca_dev->int_urb = urb;
return ret;
error_submit:
@@ -652,16 +652,12 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
: USB_ENDPOINT_XFER_ISOC;
i = gspca_dev->alt; /* previous alt setting */
if (gspca_dev->cam.reverse_alts) {
- if (gspca_dev->audio && i < gspca_dev->nbalt - 2)
- i++;
while (++i < gspca_dev->nbalt) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
break;
}
} else {
- if (gspca_dev->audio && i > 1)
- i--;
while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
@@ -676,13 +672,11 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
i, ep->desc.bEndpointAddress);
gspca_dev->alt = i; /* memorize the current alt setting */
if (gspca_dev->nbalt > 1) {
- gspca_input_destroy_urb(gspca_dev);
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
if (ret < 0) {
err("set alt %d err %d", i, ret);
ep = NULL;
}
- gspca_input_create_urb(gspca_dev);
}
return ep;
}
@@ -759,7 +753,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
}
} else { /* bulk */
urb->pipe = usb_rcvbulkpipe(gspca_dev->dev,
- ep->desc.bEndpointAddress),
+ ep->desc.bEndpointAddress);
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
urb->complete = bulk_irq;
}
@@ -781,7 +775,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (!gspca_dev->present) {
ret = -ENODEV;
- goto out;
+ goto unlock;
}
/* reset the streaming variables */
@@ -802,8 +796,10 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (gspca_dev->sd_desc->isoc_init) {
ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
if (ret < 0)
- goto out;
+ goto unlock;
}
+
+ gspca_input_destroy_urb(gspca_dev);
ep = get_ep(gspca_dev);
if (ep == NULL) {
ret = -EIO;
@@ -873,6 +869,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
}
}
out:
+ gspca_input_create_urb(gspca_dev);
+unlock:
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 8ded8b100576..703d48670a24 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -624,7 +624,7 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
/* Mask away all uninteresting bits */
i2c_data = ((val & 0x0300) >> 2) |
- (i2c_data & 0x3F);
+ (i2c_data & 0x3f);
err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
if (err < 0)
return err;
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 6cf6855aa506..0ed21dbb46cd 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -75,14 +75,14 @@ struct sd {
struct gspca_ctrl ctrls[NCTRL];
- __u8 packet_nr;
+ u8 packet_nr;
char bridge;
#define BRIDGE_OV511 0
#define BRIDGE_OV511PLUS 1
#define BRIDGE_OV518 2
#define BRIDGE_OV518PLUS 3
-#define BRIDGE_OV519 4
+#define BRIDGE_OV519 4 /* = ov530 */
#define BRIDGE_OVFX2 5
#define BRIDGE_W9968CF 6
#define BRIDGE_MASK 7
@@ -94,42 +94,44 @@ struct sd {
char snapshot_needs_reset;
/* Determined by sensor type */
- __u8 sif;
+ u8 sif;
- __u8 quality;
+ u8 quality;
#define QUALITY_MIN 50
#define QUALITY_MAX 70
#define QUALITY_DEF 50
- __u8 stopped; /* Streaming is temporarily paused */
- __u8 first_frame;
-
- __u8 frame_rate; /* current Framerate */
- __u8 clockdiv; /* clockdiv override */
-
- char sensor; /* Type of image sensor chip (SEN_*) */
-#define SEN_UNKNOWN 0
-#define SEN_OV2610 1
-#define SEN_OV3610 2
-#define SEN_OV6620 3
-#define SEN_OV6630 4
-#define SEN_OV66308AF 5
-#define SEN_OV7610 6
-#define SEN_OV7620 7
-#define SEN_OV7620AE 8
-#define SEN_OV7640 9
-#define SEN_OV7648 10
-#define SEN_OV7670 11
-#define SEN_OV76BE 12
-#define SEN_OV8610 13
+ u8 stopped; /* Streaming is temporarily paused */
+ u8 first_frame;
+
+ u8 frame_rate; /* current Framerate */
+ u8 clockdiv; /* clockdiv override */
+
+ s8 sensor; /* Type of image sensor chip (SEN_*) */
u8 sensor_addr;
- int sensor_width;
- int sensor_height;
- int sensor_reg_cache[256];
+ u16 sensor_width;
+ u16 sensor_height;
+ s16 sensor_reg_cache[256];
u8 jpeg_hdr[JPEG_HDR_SZ];
};
+enum sensors {
+ SEN_OV2610,
+ SEN_OV3610,
+ SEN_OV6620,
+ SEN_OV6630,
+ SEN_OV66308AF,
+ SEN_OV7610,
+ SEN_OV7620,
+ SEN_OV7620AE,
+ SEN_OV7640,
+ SEN_OV7648,
+ SEN_OV7660,
+ SEN_OV7670,
+ SEN_OV76BE,
+ SEN_OV8610,
+};
/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
the ov sensors which is already present here. When we have the time we
@@ -182,7 +184,7 @@ static const struct ctrl sd_ctrls[] = {
},
.set_control = setcolors,
},
-/* The flip controls work with ov7670 only */
+/* The flip controls work for sensors ov7660 and ov7670 only */
[HFLIP] = {
{
.id = V4L2_CID_HFLIP,
@@ -225,7 +227,7 @@ static const struct ctrl sd_ctrls[] = {
.type = V4L2_CTRL_TYPE_MENU,
.name = "Light frequency filter",
.minimum = 0,
- .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
+ .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
.step = 1,
.default_value = 0,
},
@@ -233,6 +235,53 @@ static const struct ctrl sd_ctrls[] = {
},
};
+/* table of the disabled controls */
+static const unsigned ctrl_dis[] = {
+[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */
+
+[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
+
+[SEN_OV6620] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV6630] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV66308AF] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7610] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7620] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7620AE] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV7640] = (1 << HFLIP) |
+ (1 << VFLIP) |
+ (1 << AUTOBRIGHT) |
+ (1 << CONTRAST),
+
+[SEN_OV7648] = (1 << HFLIP) |
+ (1 << VFLIP) |
+ (1 << AUTOBRIGHT) |
+ (1 << CONTRAST),
+
+[SEN_OV7660] = (1 << AUTOBRIGHT),
+
+[SEN_OV7670] = (1 << COLORS) |
+ (1 << AUTOBRIGHT),
+
+[SEN_OV76BE] = (1 << HFLIP) |
+ (1 << VFLIP),
+
+[SEN_OV8610] = (1 << HFLIP) |
+ (1 << VFLIP) |
+ (1 << FREQ),
+};
+
static const struct v4l2_pix_format ov519_vga_mode[] = {
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
@@ -412,7 +461,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
.priv = 0},
};
-
/* Registers common to OV511 / OV518 */
#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
#define R51x_SYS_RESET 0x50
@@ -420,7 +468,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define OV511_RESET_OMNICE 0x08
#define R51x_SYS_INIT 0x53
#define R51x_SYS_SNAP 0x52
-#define R51x_SYS_CUST_ID 0x5F
+#define R51x_SYS_CUST_ID 0x5f
#define R51x_COMP_LUT_BEGIN 0x80
/* OV511 Camera interface register numbers */
@@ -435,13 +483,13 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define R511_CAM_OPTS 0x18
#define R511_SNAP_FRAME 0x19
-#define R511_SNAP_PXCNT 0x1A
-#define R511_SNAP_LNCNT 0x1B
-#define R511_SNAP_PXDIV 0x1C
-#define R511_SNAP_LNDIV 0x1D
-#define R511_SNAP_UV_EN 0x1E
-#define R511_SNAP_UV_EN 0x1E
-#define R511_SNAP_OPTS 0x1F
+#define R511_SNAP_PXCNT 0x1a
+#define R511_SNAP_LNCNT 0x1b
+#define R511_SNAP_PXDIV 0x1c
+#define R511_SNAP_LNDIV 0x1d
+#define R511_SNAP_UV_EN 0x1e
+#define R511_SNAP_UV_EN 0x1e
+#define R511_SNAP_OPTS 0x1f
#define R511_DRAM_FLOW_CTL 0x20
#define R511_FIFO_OPTS 0x31
@@ -466,13 +514,14 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define OV519_R25_FORMAT 0x25
/* OV519 System Controller register numbers */
-#define OV519_SYS_RESET1 0x51
-#define OV519_SYS_EN_CLK1 0x54
+#define OV519_R51_RESET1 0x51
+#define OV519_R54_EN_CLK1 0x54
+#define OV519_R57_SNAPSHOT 0x57
#define OV519_GPIO_DATA_OUT0 0x71
#define OV519_GPIO_IO_CTRL0 0x72
-#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
+/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
/*
* The FX2 chip does not give us a zero length read at end of frame.
@@ -526,80 +575,81 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
#define OV7610_REG_COM_I 0x29 /* misc settings */
-/* OV7670 registers */
-#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
-#define OV7670_REG_BLUE 0x01 /* blue gain */
-#define OV7670_REG_RED 0x02 /* red gain */
-#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
-#define OV7670_REG_COM1 0x04 /* Control 1 */
-#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */
-#define OV7670_REG_COM3 0x0c /* Control 3 */
-#define OV7670_REG_COM4 0x0d /* Control 4 */
-#define OV7670_REG_COM5 0x0e /* All "reserved" */
-#define OV7670_REG_COM6 0x0f /* Control 6 */
-#define OV7670_REG_AECH 0x10 /* More bits of AEC value */
-#define OV7670_REG_CLKRC 0x11 /* Clock control */
-#define OV7670_REG_COM7 0x12 /* Control 7 */
-#define OV7670_COM7_FMT_VGA 0x00
-#define OV7670_COM7_YUV 0x00 /* YUV */
-#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
-#define OV7670_COM7_FMT_MASK 0x38
-#define OV7670_COM7_RESET 0x80 /* Register reset */
-#define OV7670_REG_COM8 0x13 /* Control 8 */
-#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
-#define OV7670_COM8_AWB 0x02 /* White balance enable */
-#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
-#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
-#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
-#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
-#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */
-#define OV7670_REG_COM10 0x15 /* Control 10 */
-#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */
-#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */
-#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
-#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
-#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
-#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
-#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
-#define OV7670_REG_AEW 0x24 /* AGC upper limit */
-#define OV7670_REG_AEB 0x25 /* AGC lower limit */
-#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */
-#define OV7670_REG_HREF 0x32 /* HREF pieces */
-#define OV7670_REG_TSLB 0x3a /* lots of stuff */
-#define OV7670_REG_COM11 0x3b /* Control 11 */
-#define OV7670_COM11_EXP 0x02
-#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
-#define OV7670_REG_COM12 0x3c /* Control 12 */
-#define OV7670_REG_COM13 0x3d /* Control 13 */
-#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
-#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
-#define OV7670_REG_COM14 0x3e /* Control 14 */
-#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */
-#define OV7670_REG_COM15 0x40 /* Control 15 */
-#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */
-#define OV7670_REG_COM16 0x41 /* Control 16 */
-#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
-#define OV7670_REG_BRIGHT 0x55 /* Brightness */
-#define OV7670_REG_CONTRAS 0x56 /* Contrast control */
-#define OV7670_REG_GFIX 0x69 /* Fix gain control */
-#define OV7670_REG_RGB444 0x8c /* RGB 444 control */
-#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
-#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
-#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */
-#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
-#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
-#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
-#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
-#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
-#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
+/* OV7660 and OV7670 registers */
+#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
+#define OV7670_R01_BLUE 0x01 /* blue gain */
+#define OV7670_R02_RED 0x02 /* red gain */
+#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
+#define OV7670_R04_COM1 0x04 /* Control 1 */
+/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
+#define OV7670_R0C_COM3 0x0c /* Control 3 */
+#define OV7670_R0D_COM4 0x0d /* Control 4 */
+#define OV7670_R0E_COM5 0x0e /* All "reserved" */
+#define OV7670_R0F_COM6 0x0f /* Control 6 */
+#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
+#define OV7670_R11_CLKRC 0x11 /* Clock control */
+#define OV7670_R12_COM7 0x12 /* Control 7 */
+#define OV7670_COM7_FMT_VGA 0x00
+/*#define OV7670_COM7_YUV 0x00 * YUV */
+#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
+#define OV7670_COM7_FMT_MASK 0x38
+#define OV7670_COM7_RESET 0x80 /* Register reset */
+#define OV7670_R13_COM8 0x13 /* Control 8 */
+#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
+#define OV7670_COM8_AWB 0x02 /* White balance enable */
+#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
+#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
+#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
+#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
+#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
+#define OV7670_R15_COM10 0x15 /* Control 10 */
+#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
+#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
+#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
+#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
+#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
+#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
+#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
+#define OV7670_R24_AEW 0x24 /* AGC upper limit */
+#define OV7670_R25_AEB 0x25 /* AGC lower limit */
+#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
+#define OV7670_R32_HREF 0x32 /* HREF pieces */
+#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
+#define OV7670_R3B_COM11 0x3b /* Control 11 */
+#define OV7670_COM11_EXP 0x02
+#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
+#define OV7670_R3C_COM12 0x3c /* Control 12 */
+#define OV7670_R3D_COM13 0x3d /* Control 13 */
+#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
+#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
+#define OV7670_R3E_COM14 0x3e /* Control 14 */
+#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
+#define OV7670_R40_COM15 0x40 /* Control 15 */
+/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
+#define OV7670_R41_COM16 0x41 /* Control 16 */
+#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
+/* end of ov7660 common registers */
+#define OV7670_R55_BRIGHT 0x55 /* Brightness */
+#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
+#define OV7670_R69_GFIX 0x69 /* Fix gain control */
+/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
+#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
+#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
+#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
+#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
+#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
+#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
+#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
+#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
+#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
struct ov_regvals {
- __u8 reg;
- __u8 val;
+ u8 reg;
+ u8 val;
};
struct ov_i2c_regvals {
- __u8 reg;
- __u8 val;
+ u8 reg;
+ u8 val;
};
/* Settings for OV2610 camera chip */
@@ -617,7 +667,6 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* "wait 4096 external clock ... to make sure the sensor is
* stable and ready to access registers" i.e. 160us at 24MHz
*/
-
{ 0x12, 0x80 }, /* COMH reset */
{ 0x12, 0x00 }, /* QXGA, master */
@@ -650,7 +699,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMI[0] "Exposure control"
* = 0 (0x00) .......0 "Manual"
*/
- { 0x13, 0xC0 },
+ { 0x13, 0xc0 },
/*
* 09 COMC "Common Control C"
@@ -706,7 +755,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COME[0] "Auto zero circuit select"
* = 1 (0x01) .......1 "On"
*/
- { 0x0d, 0xA1 },
+ { 0x0d, 0xa1 },
/*
* 0E COMF "Common Control F"
@@ -770,7 +819,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMJ[0] "Reserved"
* = 0 (0x00) .......0
*/
- { 0x14, 0xC6 },
+ { 0x14, 0xc6 },
/*
* 15 COMK "Common Control K"
@@ -876,7 +925,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* FVOPT[7:0] "Range"
* = 31 (0x1F) 00011111
*/
- { 0x3c, 0x1F },
+ { 0x3c, 0x1f },
/*
* 44 Undocumented = 0 (0x00) 00000000
@@ -925,7 +974,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* 48[7:0] "It's a secret"
* = 192 (0xC0) 11000000
*/
- { 0x48, 0xC0 },
+ { 0x48, 0xc0 },
/*
* 49 Undocumented = 25 (0x19) 00011001
@@ -939,18 +988,18 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* 4B[7:0] "It's a secret"
* = 128 (0x80) 10000000
*/
- { 0x4B, 0x80 },
+ { 0x4b, 0x80 },
/*
* 4D Undocumented = 196 (0xC4) 11000100
* 4D[7:0] "It's a secret"
* = 196 (0xC4) 11000100
*/
- { 0x4D, 0xC4 },
+ { 0x4d, 0xc4 },
/*
* 35 VREF "Reference Voltage Control"
- * = 76 (0x4C) 01001100
+ * = 76 (0x4c) 01001100
* VREF[7:5] "Column high reference control"
* = 2 (0x02) 010..... "higher voltage"
* VREF[4:2] "Column low reference control"
@@ -958,21 +1007,21 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* VREF[1:0] "Reserved"
* = 0 (0x00) ......00
*/
- { 0x35, 0x4C },
+ { 0x35, 0x4c },
/*
* 3D Undocumented = 0 (0x00) 00000000
* 3D[7:0] "It's a secret"
* = 0 (0x00) 00000000
*/
- { 0x3D, 0x00 },
+ { 0x3d, 0x00 },
/*
* 3E Undocumented = 0 (0x00) 00000000
* 3E[7:0] "It's a secret"
* = 0 (0x00) 00000000
*/
- { 0x3E, 0x00 },
+ { 0x3e, 0x00 },
/*
* 3B FREFB "Internal Reference Adjustment"
@@ -1012,7 +1061,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* VBLM[3:0] "Sensor current control"
* = 10 (0x0A) ....1010
*/
- { 0x34, 0x5A },
+ { 0x34, 0x5a },
/*
* 3B FREFB "Internal Reference Adjustment"
@@ -1078,7 +1127,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFST[7:0] "Horizontal window start, 8 MSBs"
* = 31 (0x1F) 00011111
*/
- { 0x17, 0x1F },
+ { 0x17, 0x1f },
/*
* 18 HREFEND "Horizontal window end"
@@ -1086,7 +1135,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFEND[7:0] "Horizontal Window End, 8 MSBs"
* = 95 (0x5F) 01011111
*/
- { 0x18, 0x5F },
+ { 0x18, 0x5f },
/*
* 19 VSTRT "Vertical window start"
@@ -1126,7 +1175,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMA[1:0] "Vertical window start line control 2 LSBs"
* = 2 (0x02) ......10
*/
- { 0x03, 0x4A },
+ { 0x03, 0x4a },
/*
* 11 CLKRC "Clock Rate Control"
@@ -1183,7 +1232,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFST[7:0] "Horizontal window start, 8 MSBs"
* = 31 (0x1F) 00011111
*/
- { 0x17, 0x1F },
+ { 0x17, 0x1f },
/*
* 18 HREFEND "Horizontal window end"
@@ -1191,7 +1240,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* HREFEND[7:0] "Horizontal Window End, 8 MSBs"
* = 95 (0x5F) 01011111
*/
- { 0x18, 0x5F },
+ { 0x18, 0x5f },
/*
* 19 VSTRT "Vertical window start"
@@ -1231,7 +1280,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* COMA[1:0] "Vertical window start line control 2 LSBs"
* = 2 (0x02) ......10
*/
- { 0x03, 0x4A },
+ { 0x03, 0x4a },
/*
* 02 RED "Red Gain Control"
@@ -1241,7 +1290,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* RED[6:0] "Value"
* = 47 (0x2F) .0101111
*/
- { 0x02, 0xAF },
+ { 0x02, 0xaf },
/*
* 2D ADDVSL "VSYNC Pulse Width"
@@ -1249,7 +1298,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* ADDVSL[7:0] "VSYNC pulse width, LSB"
* = 210 (0xD2) 11010010
*/
- { 0x2d, 0xD2 },
+ { 0x2d, 0xd2 },
/*
* 00 GAIN = 24 (0x18) 00011000
@@ -1272,7 +1321,7 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* BLUE[6:0] "Value"
* = 112 (0x70) .1110000
*/
- { 0x01, 0xF0 },
+ { 0x01, 0xf0 },
/*
* 10 AEC "Automatic Exposure Control"
@@ -1280,14 +1329,14 @@ static const struct ov_i2c_regvals norm_3620b[] = {
* AEC[7:0] "Automatic Exposure Control, 8 MSBs"
* = 10 (0x0A) 00001010
*/
- { 0x10, 0x0A },
-
- { 0xE1, 0x67 },
- { 0xE3, 0x03 },
- { 0xE4, 0x26 },
- { 0xE5, 0x3E },
- { 0xF8, 0x01 },
- { 0xFF, 0x01 },
+ { 0x10, 0x0a },
+
+ { 0xe1, 0x67 },
+ { 0xe3, 0x03 },
+ { 0xe4, 0x26 },
+ { 0xe5, 0x3e },
+ { 0xf8, 0x01 },
+ { 0xff, 0x01 },
};
static const struct ov_i2c_regvals norm_6x20[] = {
@@ -1296,7 +1345,7 @@ static const struct ov_i2c_regvals norm_6x20[] = {
{ 0x03, 0x60 },
{ 0x05, 0x7f }, /* For when autoadjust is off */
{ 0x07, 0xa8 },
- /* The ratio of 0x0c and 0x0d controls the white point */
+ /* The ratio of 0x0c and 0x0d controls the white point */
{ 0x0c, 0x24 },
{ 0x0d, 0x24 },
{ 0x0f, 0x15 }, /* COMS */
@@ -1464,7 +1513,7 @@ static const struct ov_i2c_regvals norm_7620[] = {
{ 0x00, 0x00 }, /* gain */
{ 0x01, 0x80 }, /* blue gain */
{ 0x02, 0x80 }, /* red gain */
- { 0x03, 0xc0 }, /* OV7670_REG_VREF */
+ { 0x03, 0xc0 }, /* OV7670_R03_VREF */
{ 0x06, 0x60 },
{ 0x07, 0x00 },
{ 0x0c, 0x24 },
@@ -1532,33 +1581,177 @@ static const struct ov_i2c_regvals norm_7640[] = {
{ 0x12, 0x14 },
};
+static const struct ov_regvals init_519_ov7660[] = {
+ { 0x5d, 0x03 }, /* Turn off suspend mode */
+ { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
+ { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { 0xa2, 0x20 }, /* a2-a5 are undocumented */
+ { 0xa3, 0x18 },
+ { 0xa4, 0x04 },
+ { 0xa5, 0x28 },
+ { 0x37, 0x00 }, /* SetUsbInit */
+ { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
+ /* Enable both fields, YUV Input, disable defect comp (why?) */
+ { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
+ { 0x21, 0x38 },
+ { 0x22, 0x1d },
+ { 0x17, 0x50 }, /* undocumented */
+ { 0x37, 0x00 }, /* undocumented */
+ { 0x40, 0xff }, /* I2C timeout counter */
+ { 0x46, 0x00 }, /* I2C clock prescaler */
+};
+static const struct ov_i2c_regvals norm_7660[] = {
+ {OV7670_R12_COM7, OV7670_COM7_RESET},
+ {OV7670_R11_CLKRC, 0x81},
+ {0x92, 0x00}, /* DM_LNL */
+ {0x93, 0x00}, /* DM_LNH */
+ {0x9d, 0x4c}, /* BD50ST */
+ {0x9e, 0x3f}, /* BD60ST */
+ {OV7670_R3B_COM11, 0x02},
+ {OV7670_R13_COM8, 0xf5},
+ {OV7670_R10_AECH, 0x00},
+ {OV7670_R00_GAIN, 0x00},
+ {OV7670_R01_BLUE, 0x7c},
+ {OV7670_R02_RED, 0x9d},
+ {OV7670_R12_COM7, 0x00},
+ {OV7670_R04_COM1, 00},
+ {OV7670_R18_HSTOP, 0x01},
+ {OV7670_R17_HSTART, 0x13},
+ {OV7670_R32_HREF, 0x92},
+ {OV7670_R19_VSTART, 0x02},
+ {OV7670_R1A_VSTOP, 0x7a},
+ {OV7670_R03_VREF, 0x00},
+ {OV7670_R0E_COM5, 0x04},
+ {OV7670_R0F_COM6, 0x62},
+ {OV7670_R15_COM10, 0x00},
+ {0x16, 0x02}, /* RSVD */
+ {0x1b, 0x00}, /* PSHFT */
+ {OV7670_R1E_MVFP, 0x01},
+ {0x29, 0x3c}, /* RSVD */
+ {0x33, 0x00}, /* CHLF */
+ {0x34, 0x07}, /* ARBLM */
+ {0x35, 0x84}, /* RSVD */
+ {0x36, 0x00}, /* RSVD */
+ {0x37, 0x04}, /* ADC */
+ {0x39, 0x43}, /* OFON */
+ {OV7670_R3A_TSLB, 0x00},
+ {OV7670_R3C_COM12, 0x6c},
+ {OV7670_R3D_COM13, 0x98},
+ {OV7670_R3F_EDGE, 0x23},
+ {OV7670_R40_COM15, 0xc1},
+ {OV7670_R41_COM16, 0x22},
+ {0x6b, 0x0a}, /* DBLV */
+ {0xa1, 0x08}, /* RSVD */
+ {0x69, 0x80}, /* HV */
+ {0x43, 0xf0}, /* RSVD.. */
+ {0x44, 0x10},
+ {0x45, 0x78},
+ {0x46, 0xa8},
+ {0x47, 0x60},
+ {0x48, 0x80},
+ {0x59, 0xba},
+ {0x5a, 0x9a},
+ {0x5b, 0x22},
+ {0x5c, 0xb9},
+ {0x5d, 0x9b},
+ {0x5e, 0x10},
+ {0x5f, 0xe0},
+ {0x60, 0x85},
+ {0x61, 0x60},
+ {0x9f, 0x9d}, /* RSVD */
+ {0xa0, 0xa0}, /* DSPC2 */
+ {0x4f, 0x60}, /* matrix */
+ {0x50, 0x64},
+ {0x51, 0x04},
+ {0x52, 0x18},
+ {0x53, 0x3c},
+ {0x54, 0x54},
+ {0x55, 0x40},
+ {0x56, 0x40},
+ {0x57, 0x40},
+ {0x58, 0x0d}, /* matrix sign */
+ {0x8b, 0xcc}, /* RSVD */
+ {0x8c, 0xcc},
+ {0x8d, 0xcf},
+ {0x6c, 0x40}, /* gamma curve */
+ {0x6d, 0xe0},
+ {0x6e, 0xa0},
+ {0x6f, 0x80},
+ {0x70, 0x70},
+ {0x71, 0x80},
+ {0x72, 0x60},
+ {0x73, 0x60},
+ {0x74, 0x50},
+ {0x75, 0x40},
+ {0x76, 0x38},
+ {0x77, 0x3c},
+ {0x78, 0x32},
+ {0x79, 0x1a},
+ {0x7a, 0x28},
+ {0x7b, 0x24},
+ {0x7c, 0x04}, /* gamma curve */
+ {0x7d, 0x12},
+ {0x7e, 0x26},
+ {0x7f, 0x46},
+ {0x80, 0x54},
+ {0x81, 0x64},
+ {0x82, 0x70},
+ {0x83, 0x7c},
+ {0x84, 0x86},
+ {0x85, 0x8e},
+ {0x86, 0x9c},
+ {0x87, 0xab},
+ {0x88, 0xc4},
+ {0x89, 0xd1},
+ {0x8a, 0xe5},
+ {OV7670_R14_COM9, 0x1e},
+ {OV7670_R24_AEW, 0x80},
+ {OV7670_R25_AEB, 0x72},
+ {OV7670_R26_VPT, 0xb3},
+ {0x62, 0x80}, /* LCC1 */
+ {0x63, 0x80}, /* LCC2 */
+ {0x64, 0x06}, /* LCC3 */
+ {0x65, 0x00}, /* LCC4 */
+ {0x66, 0x01}, /* LCC5 */
+ {0x94, 0x0e}, /* RSVD.. */
+ {0x95, 0x14},
+ {OV7670_R13_COM8, OV7670_COM8_FASTAEC
+ | OV7670_COM8_AECSTEP
+ | OV7670_COM8_BFILT
+ | 0x10
+ | OV7670_COM8_AGC
+ | OV7670_COM8_AWB
+ | OV7670_COM8_AEC},
+ {0xa1, 0xc8}
+};
+
/* 7670. Defaults taken from OmniVision provided data,
* as provided by Jonathan Corbet of OLPC */
static const struct ov_i2c_regvals norm_7670[] = {
- { OV7670_REG_COM7, OV7670_COM7_RESET },
- { OV7670_REG_TSLB, 0x04 }, /* OV */
- { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
- { OV7670_REG_CLKRC, 0x01 },
+ { OV7670_R12_COM7, OV7670_COM7_RESET },
+ { OV7670_R3A_TSLB, 0x04 }, /* OV */
+ { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
+ { OV7670_R11_CLKRC, 0x01 },
/*
* Set the hardware window. These values from OV don't entirely
* make sense - hstop is less than hstart. But they work...
*/
- { OV7670_REG_HSTART, 0x13 },
- { OV7670_REG_HSTOP, 0x01 },
- { OV7670_REG_HREF, 0xb6 },
- { OV7670_REG_VSTART, 0x02 },
- { OV7670_REG_VSTOP, 0x7a },
- { OV7670_REG_VREF, 0x0a },
-
- { OV7670_REG_COM3, 0x00 },
- { OV7670_REG_COM14, 0x00 },
+ { OV7670_R17_HSTART, 0x13 },
+ { OV7670_R18_HSTOP, 0x01 },
+ { OV7670_R32_HREF, 0xb6 },
+ { OV7670_R19_VSTART, 0x02 },
+ { OV7670_R1A_VSTOP, 0x7a },
+ { OV7670_R03_VREF, 0x0a },
+
+ { OV7670_R0C_COM3, 0x00 },
+ { OV7670_R3E_COM14, 0x00 },
/* Mystery scaling numbers */
{ 0x70, 0x3a },
{ 0x71, 0x35 },
{ 0x72, 0x11 },
{ 0x73, 0xf0 },
{ 0xa2, 0x02 },
-/* { OV7670_REG_COM10, 0x0 }, */
+/* { OV7670_R15_COM10, 0x0 }, */
/* Gamma curve values */
{ 0x7a, 0x20 },
@@ -1580,37 +1773,37 @@ static const struct ov_i2c_regvals norm_7670[] = {
/* AGC and AEC parameters. Note we start by disabling those features,
then turn them only after tweaking the values. */
- { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ { OV7670_R13_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT },
- { OV7670_REG_GAIN, 0x00 },
- { OV7670_REG_AECH, 0x00 },
- { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
- { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
- { OV7670_REG_BD50MAX, 0x05 },
- { OV7670_REG_BD60MAX, 0x07 },
- { OV7670_REG_AEW, 0x95 },
- { OV7670_REG_AEB, 0x33 },
- { OV7670_REG_VPT, 0xe3 },
- { OV7670_REG_HAECC1, 0x78 },
- { OV7670_REG_HAECC2, 0x68 },
+ { OV7670_R00_GAIN, 0x00 },
+ { OV7670_R10_AECH, 0x00 },
+ { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
+ { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
+ { OV7670_RA5_BD50MAX, 0x05 },
+ { OV7670_RAB_BD60MAX, 0x07 },
+ { OV7670_R24_AEW, 0x95 },
+ { OV7670_R25_AEB, 0x33 },
+ { OV7670_R26_VPT, 0xe3 },
+ { OV7670_R9F_HAECC1, 0x78 },
+ { OV7670_RA0_HAECC2, 0x68 },
{ 0xa1, 0x03 }, /* magic */
- { OV7670_REG_HAECC3, 0xd8 },
- { OV7670_REG_HAECC4, 0xd8 },
- { OV7670_REG_HAECC5, 0xf0 },
- { OV7670_REG_HAECC6, 0x90 },
- { OV7670_REG_HAECC7, 0x94 },
- { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ { OV7670_RA6_HAECC3, 0xd8 },
+ { OV7670_RA7_HAECC4, 0xd8 },
+ { OV7670_RA8_HAECC5, 0xf0 },
+ { OV7670_RA9_HAECC6, 0x90 },
+ { OV7670_RAA_HAECC7, 0x94 },
+ { OV7670_R13_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT
| OV7670_COM8_AGC
| OV7670_COM8_AEC },
/* Almost all of these are magic "reserved" values. */
- { OV7670_REG_COM5, 0x61 },
- { OV7670_REG_COM6, 0x4b },
+ { OV7670_R0E_COM5, 0x61 },
+ { OV7670_R0F_COM6, 0x4b },
{ 0x16, 0x02 },
- { OV7670_REG_MVFP, 0x07 },
+ { OV7670_R1E_MVFP, 0x07 },
{ 0x21, 0x02 },
{ 0x22, 0x91 },
{ 0x29, 0x07 },
@@ -1619,10 +1812,10 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x37, 0x1d },
{ 0x38, 0x71 },
{ 0x39, 0x2a },
- { OV7670_REG_COM12, 0x78 },
+ { OV7670_R3C_COM12, 0x78 },
{ 0x4d, 0x40 },
{ 0x4e, 0x20 },
- { OV7670_REG_GFIX, 0x00 },
+ { OV7670_R69_GFIX, 0x00 },
{ 0x6b, 0x4a },
{ 0x74, 0x10 },
{ 0x8d, 0x4f },
@@ -1657,9 +1850,9 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x6f, 0x9f },
/* "9e for advance AWB" */
{ 0x6a, 0x40 },
- { OV7670_REG_BLUE, 0x40 },
- { OV7670_REG_RED, 0x60 },
- { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ { OV7670_R01_BLUE, 0x40 },
+ { OV7670_R02_RED, 0x60 },
+ { OV7670_R13_COM8, OV7670_COM8_FASTAEC
| OV7670_COM8_AECSTEP
| OV7670_COM8_BFILT
| OV7670_COM8_AGC
@@ -1675,22 +1868,22 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x54, 0x80 },
{ 0x58, 0x9e },
- { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
- { OV7670_REG_EDGE, 0x00 },
+ { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
+ { OV7670_R3F_EDGE, 0x00 },
{ 0x75, 0x05 },
{ 0x76, 0xe1 },
{ 0x4c, 0x00 },
{ 0x77, 0x01 },
- { OV7670_REG_COM13, OV7670_COM13_GAMMA
+ { OV7670_R3D_COM13, OV7670_COM13_GAMMA
| OV7670_COM13_UVSAT
| 2}, /* was 3 */
{ 0x4b, 0x09 },
{ 0xc9, 0x60 },
- { OV7670_REG_COM16, 0x38 },
+ { OV7670_R41_COM16, 0x38 },
{ 0x56, 0x40 },
{ 0x34, 0x11 },
- { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
+ { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
{ 0xa4, 0x88 },
{ 0x96, 0x00 },
{ 0x97, 0x30 },
@@ -1825,10 +2018,13 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
}
/* Write a OV519 register */
-static int reg_w(struct sd *sd, __u16 index, __u16 value)
+static void reg_w(struct sd *sd, u16 index, u16 value)
{
int ret, req = 0;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
@@ -1838,6 +2034,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
req = 0x0a;
/* fall through */
case BRIDGE_W9968CF:
+ PDEBUG(D_USBO, "SET %02x %04x %04x",
+ req, value, index);
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
req,
@@ -1848,6 +2046,8 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
req = 1;
}
+ PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
+ req, index, value);
sd->gspca_dev.usb_buf[0] = value;
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -1857,22 +2057,22 @@ static int reg_w(struct sd *sd, __u16 index, __u16 value)
sd->gspca_dev.usb_buf, 1, 500);
leave:
if (ret < 0) {
- err("Write reg 0x%04x -> [0x%02x] failed",
- value, index);
- return ret;
+ err("reg_w %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
+ return;
}
-
- PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
- return 0;
}
/* Read from a OV519 register, note not valid for the w9968cf!! */
/* returns: negative is error, pos or zero is data */
-static int reg_r(struct sd *sd, __u16 index)
+static int reg_r(struct sd *sd, u16 index)
{
int ret;
int req;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
@@ -1893,29 +2093,37 @@ static int reg_r(struct sd *sd, __u16 index)
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
- } else
- err("Read reg [0x%02x] failed", index);
+ PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
+ req, index, ret);
+ } else {
+ err("reg_r %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
+ }
return ret;
}
/* Read 8 values from a OV519 register */
static int reg_r8(struct sd *sd,
- __u16 index)
+ u16 index)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1, /* REQ_IO */
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, sd->gspca_dev.usb_buf, 8, 500);
- if (ret >= 0)
+ if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- else
- err("Read reg 8 [0x%02x] failed", index);
+ } else {
+ err("reg_r8 %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
+ }
return ret;
}
@@ -1926,34 +2134,37 @@ static int reg_r8(struct sd *sd,
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
-static int reg_w_mask(struct sd *sd,
- __u16 index,
- __u8 value,
- __u8 mask)
+static void reg_w_mask(struct sd *sd,
+ u16 index,
+ u8 value,
+ u8 mask)
{
int ret;
- __u8 oldval;
+ u8 oldval;
if (mask != 0xff) {
value &= mask; /* Enforce mask on value */
ret = reg_r(sd, index);
if (ret < 0)
- return ret;
+ return;
oldval = ret & ~mask; /* Clear the masked bits */
value |= oldval; /* Set the desired bits */
}
- return reg_w(sd, index, value);
+ reg_w(sd, index, value);
}
/*
* Writes multiple (n) byte value to a single register. Only valid with certain
* registers (0x30 and 0xc4 - 0xce).
*/
-static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
+static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
*((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
ret = usb_control_msg(sd->gspca_dev.dev,
@@ -1963,69 +2174,55 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
0, index,
sd->gspca_dev.usb_buf, n, 500);
if (ret < 0) {
- err("Write reg32 [%02x] %08x failed", index, value);
- return ret;
+ err("reg_w32 %02x failed %d", index, ret);
+ sd->gspca_dev.usb_err = ret;
}
-
- return 0;
}
-static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
{
int rc, retries;
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+ PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
/* Three byte write cycle */
for (retries = 6; ; ) {
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_3, reg);
/* Write "value" to I2C data port of OV511 */
- rc = reg_w(sd, R51x_I2C_DATA, value);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_DATA, value);
/* Initiate 3-byte write cycle */
- rc = reg_w(sd, R511_I2C_CTL, 0x01);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x01);
do {
rc = reg_r(sd, R511_I2C_CTL);
} while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
if (rc < 0)
- return rc;
+ return;
if ((rc & 2) == 0) /* Ack? */
break;
if (--retries < 0) {
PDEBUG(D_USBO, "i2c write retries exhausted");
- return -1;
+ return;
}
}
-
- return 0;
}
-static int ov511_i2c_r(struct sd *sd, __u8 reg)
+static int ov511_i2c_r(struct sd *sd, u8 reg)
{
int rc, value, retries;
/* Two byte write cycle */
for (retries = 6; ; ) {
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_2, reg);
/* Initiate 2-byte write cycle */
- rc = reg_w(sd, R511_I2C_CTL, 0x03);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x03);
do {
rc = reg_r(sd, R511_I2C_CTL);
@@ -2049,9 +2246,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
/* Two byte read cycle */
for (retries = 6; ; ) {
/* Initiate 2-byte read cycle */
- rc = reg_w(sd, R511_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x05);
do {
rc = reg_r(sd, R511_I2C_CTL);
@@ -2064,9 +2259,7 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
break;
/* I2C abort */
- rc = reg_w(sd, R511_I2C_CTL, 0x10);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x10);
if (--retries < 0) {
PDEBUG(D_USBI, "i2c read retries exhausted");
@@ -2076,12 +2269,10 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+ PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
/* This is needed to make i2c_w() work */
- rc = reg_w(sd, R511_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
+ reg_w(sd, R511_I2C_CTL, 0x05);
return value;
}
@@ -2091,32 +2282,24 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg)
* This is normally only called from i2c_w(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
-static int ov518_i2c_w(struct sd *sd,
- __u8 reg,
- __u8 value)
+static void ov518_i2c_w(struct sd *sd,
+ u8 reg,
+ u8 value)
{
- int rc;
-
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+ PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_3, reg);
/* Write "value" to I2C data port of OV511 */
- rc = reg_w(sd, R51x_I2C_DATA, value);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_DATA, value);
/* Initiate 3-byte write cycle */
- rc = reg_w(sd, R518_I2C_CTL, 0x01);
- if (rc < 0)
- return rc;
+ reg_w(sd, R518_I2C_CTL, 0x01);
/* wait for write complete */
msleep(4);
- return reg_r8(sd, R518_I2C_CTL);
+ reg_r8(sd, R518_I2C_CTL);
}
/*
@@ -2126,105 +2309,102 @@ static int ov518_i2c_w(struct sd *sd,
* This is normally only called from i2c_r(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
-static int ov518_i2c_r(struct sd *sd, __u8 reg)
+static int ov518_i2c_r(struct sd *sd, u8 reg)
{
- int rc, value;
+ int value;
/* Select camera register */
- rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
- if (rc < 0)
- return rc;
+ reg_w(sd, R51x_I2C_SADDR_2, reg);
/* Initiate 2-byte write cycle */
- rc = reg_w(sd, R518_I2C_CTL, 0x03);
- if (rc < 0)
- return rc;
+ reg_w(sd, R518_I2C_CTL, 0x03);
/* Initiate 2-byte read cycle */
- rc = reg_w(sd, R518_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
+ reg_w(sd, R518_I2C_CTL, 0x05);
value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+ PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
return value;
}
-static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (__u16)value, (__u16)reg, NULL, 0, 500);
+ (u16) value, (u16) reg, NULL, 0, 500);
if (ret < 0) {
- err("i2c 0x%02x -> [0x%02x] failed", value, reg);
- return ret;
+ err("ovfx2_i2c_w %02x failed %d", reg, ret);
+ sd->gspca_dev.usb_err = ret;
}
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
- return 0;
+ PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
}
-static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
+static int ovfx2_i2c_r(struct sd *sd, u8 reg)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
0x03,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
+ 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
- } else
- err("i2c read [0x%02x] failed", reg);
+ PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
+ } else {
+ err("ovfx2_i2c_r %02x failed %d", reg, ret);
+ sd->gspca_dev.usb_err = ret;
+ }
return ret;
}
-static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
+static void i2c_w(struct sd *sd, u8 reg, u8 value)
{
- int ret = -1;
-
if (sd->sensor_reg_cache[reg] == value)
- return 0;
+ return;
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- ret = ov511_i2c_w(sd, reg, value);
+ ov511_i2c_w(sd, reg, value);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
case BRIDGE_OV519:
- ret = ov518_i2c_w(sd, reg, value);
+ ov518_i2c_w(sd, reg, value);
break;
case BRIDGE_OVFX2:
- ret = ovfx2_i2c_w(sd, reg, value);
+ ovfx2_i2c_w(sd, reg, value);
break;
case BRIDGE_W9968CF:
- ret = w9968cf_i2c_w(sd, reg, value);
+ w9968cf_i2c_w(sd, reg, value);
break;
}
- if (ret >= 0) {
+ if (sd->gspca_dev.usb_err >= 0) {
/* Up on sensor reset empty the register cache */
if (reg == 0x12 && (value & 0x80))
memset(sd->sensor_reg_cache, -1,
- sizeof(sd->sensor_reg_cache));
+ sizeof(sd->sensor_reg_cache));
else
sd->sensor_reg_cache[reg] = value;
}
-
- return ret;
}
-static int i2c_r(struct sd *sd, __u8 reg)
+static int i2c_r(struct sd *sd, u8 reg)
{
int ret = -1;
@@ -2260,95 +2440,99 @@ static int i2c_r(struct sd *sd, __u8 reg)
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
-static int i2c_w_mask(struct sd *sd,
- __u8 reg,
- __u8 value,
- __u8 mask)
+static void i2c_w_mask(struct sd *sd,
+ u8 reg,
+ u8 value,
+ u8 mask)
{
int rc;
- __u8 oldval;
+ u8 oldval;
value &= mask; /* Enforce mask on value */
rc = i2c_r(sd, reg);
if (rc < 0)
- return rc;
+ return;
oldval = rc & ~mask; /* Clear the masked bits */
value |= oldval; /* Set the desired bits */
- return i2c_w(sd, reg, value);
+ i2c_w(sd, reg, value);
}
/* Temporarily stops OV511 from functioning. Must do this before changing
* registers while the camera is streaming */
-static inline int ov51x_stop(struct sd *sd)
+static inline void ov51x_stop(struct sd *sd)
{
PDEBUG(D_STREAM, "stopping");
sd->stopped = 1;
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- return reg_w(sd, R51x_SYS_RESET, 0x3d);
+ reg_w(sd, R51x_SYS_RESET, 0x3d);
+ break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+ reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
+ break;
case BRIDGE_OV519:
- return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+ reg_w(sd, OV519_R51_RESET1, 0x0f);
+ reg_w(sd, OV519_R51_RESET1, 0x00);
+ reg_w(sd, 0x22, 0x00); /* FRAR */
+ break;
case BRIDGE_OVFX2:
- return reg_w_mask(sd, 0x0f, 0x00, 0x02);
+ reg_w_mask(sd, 0x0f, 0x00, 0x02);
+ break;
case BRIDGE_W9968CF:
- return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
+ reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
+ break;
}
-
- return 0;
}
/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
* actually stopped (for performance). */
-static inline int ov51x_restart(struct sd *sd)
+static inline void ov51x_restart(struct sd *sd)
{
- int rc;
-
PDEBUG(D_STREAM, "restarting");
if (!sd->stopped)
- return 0;
+ return;
sd->stopped = 0;
/* Reinitialize the stream */
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- return reg_w(sd, R51x_SYS_RESET, 0x00);
+ reg_w(sd, R51x_SYS_RESET, 0x00);
+ break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- rc = reg_w(sd, 0x2f, 0x80);
- if (rc < 0)
- return rc;
- return reg_w(sd, R51x_SYS_RESET, 0x00);
+ reg_w(sd, 0x2f, 0x80);
+ reg_w(sd, R51x_SYS_RESET, 0x00);
+ break;
case BRIDGE_OV519:
- return reg_w(sd, OV519_SYS_RESET1, 0x00);
+ reg_w(sd, OV519_R51_RESET1, 0x0f);
+ reg_w(sd, OV519_R51_RESET1, 0x00);
+ reg_w(sd, 0x22, 0x1d); /* FRAR */
+ break;
case BRIDGE_OVFX2:
- return reg_w_mask(sd, 0x0f, 0x02, 0x02);
+ reg_w_mask(sd, 0x0f, 0x02, 0x02);
+ break;
case BRIDGE_W9968CF:
- return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
+ reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
+ break;
}
-
- return 0;
}
-static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
+static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
/* This does an initial reset of an OmniVision sensor and ensures that I2C
* is synchronized. Returns <0 on failure.
*/
-static int init_ov_sensor(struct sd *sd, __u8 slave)
+static int init_ov_sensor(struct sd *sd, u8 slave)
{
int i;
- if (ov51x_set_slave_ids(sd, slave) < 0)
- return -EIO;
+ ov51x_set_slave_ids(sd, slave);
/* Reset the sensor */
- if (i2c_w(sd, 0x12, 0x80) < 0)
- return -EIO;
+ i2c_w(sd, 0x12, 0x80);
/* Wait for it to initialize */
msleep(150);
@@ -2361,15 +2545,16 @@ static int init_ov_sensor(struct sd *sd, __u8 slave)
}
/* Reset the sensor */
- if (i2c_w(sd, 0x12, 0x80) < 0)
- return -EIO;
+ i2c_w(sd, 0x12, 0x80);
+
/* Wait for it to initialize */
msleep(150);
+
/* Dummy read to sync I2C */
if (i2c_r(sd, 0x00) < 0)
- return -EIO;
+ return -1;
}
- return -EIO;
+ return -1;
}
/* Set the read and write slave IDs. The "slave" argument is the write slave,
@@ -2377,53 +2562,40 @@ static int init_ov_sensor(struct sd *sd, __u8 slave)
* This should not be called from outside the i2c I/O functions.
* Sets I2C read and write slave IDs. Returns <0 for error
*/
-static int ov51x_set_slave_ids(struct sd *sd,
- __u8 slave)
+static void ov51x_set_slave_ids(struct sd *sd,
+ u8 slave)
{
- int rc;
-
switch (sd->bridge) {
case BRIDGE_OVFX2:
- return reg_w(sd, OVFX2_I2C_ADDR, slave);
+ reg_w(sd, OVFX2_I2C_ADDR, slave);
+ return;
case BRIDGE_W9968CF:
sd->sensor_addr = slave;
- return 0;
+ return;
}
- rc = reg_w(sd, R51x_I2C_W_SID, slave);
- if (rc < 0)
- return rc;
- return reg_w(sd, R51x_I2C_R_SID, slave + 1);
+ reg_w(sd, R51x_I2C_W_SID, slave);
+ reg_w(sd, R51x_I2C_R_SID, slave + 1);
}
-static int write_regvals(struct sd *sd,
+static void write_regvals(struct sd *sd,
const struct ov_regvals *regvals,
int n)
{
- int rc;
-
while (--n >= 0) {
- rc = reg_w(sd, regvals->reg, regvals->val);
- if (rc < 0)
- return rc;
+ reg_w(sd, regvals->reg, regvals->val);
regvals++;
}
- return 0;
}
-static int write_i2c_regvals(struct sd *sd,
- const struct ov_i2c_regvals *regvals,
- int n)
+static void write_i2c_regvals(struct sd *sd,
+ const struct ov_i2c_regvals *regvals,
+ int n)
{
- int rc;
-
while (--n >= 0) {
- rc = i2c_w(sd, regvals->reg, regvals->val);
- if (rc < 0)
- return rc;
+ i2c_w(sd, regvals->reg, regvals->val);
regvals++;
}
- return 0;
}
/****************************************************************************
@@ -2433,13 +2605,13 @@ static int write_i2c_regvals(struct sd *sd,
***************************************************************************/
/* This initializes the OV2x10 / OV3610 / OV3620 */
-static int ov_hires_configure(struct sd *sd)
+static void ov_hires_configure(struct sd *sd)
{
int high, low;
if (sd->bridge != BRIDGE_OVFX2) {
err("error hires sensors only supported with ovfx2");
- return -1;
+ return;
}
PDEBUG(D_PROBE, "starting ov hires configuration");
@@ -2455,20 +2627,15 @@ static int ov_hires_configure(struct sd *sd)
PDEBUG(D_PROBE, "Sensor is an OV3610");
sd->sensor = SEN_OV3610;
} else {
- err("Error unknown sensor type: 0x%02x%02x",
- high, low);
- return -1;
+ err("Error unknown sensor type: %02x%02x",
+ high, low);
}
-
- /* Set sensor-specific vars */
- return 0;
}
-
/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
* the same register settings as the OV8610, since they are very similar.
*/
-static int ov8xx0_configure(struct sd *sd)
+static void ov8xx0_configure(struct sd *sd)
{
int rc;
@@ -2478,27 +2645,21 @@ static int ov8xx0_configure(struct sd *sd)
rc = i2c_r(sd, OV7610_REG_COM_I);
if (rc < 0) {
PDEBUG(D_ERR, "Error detecting sensor type");
- return -1;
+ return;
}
- if ((rc & 3) == 1) {
+ if ((rc & 3) == 1)
sd->sensor = SEN_OV8610;
- } else {
+ else
err("Unknown image sensor version: %d", rc & 3);
- return -1;
- }
-
- /* Set sensor-specific vars */
- return 0;
}
/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
* the same register settings as the OV7610, since they are very similar.
*/
-static int ov7xx0_configure(struct sd *sd)
+static void ov7xx0_configure(struct sd *sd)
{
int rc, high, low;
-
PDEBUG(D_PROBE, "starting OV7xx0 configuration");
/* Detect sensor (sub)type */
@@ -2508,7 +2669,7 @@ static int ov7xx0_configure(struct sd *sd)
* it appears to be wrongly detected as a 7610 by default */
if (rc < 0) {
PDEBUG(D_ERR, "Error detecting sensor type");
- return -1;
+ return;
}
if ((rc & 3) == 3) {
/* quick hack to make OV7670s work */
@@ -2536,19 +2697,19 @@ static int ov7xx0_configure(struct sd *sd)
high = i2c_r(sd, 0x0a);
if (high < 0) {
PDEBUG(D_ERR, "Error detecting camera chip PID");
- return high;
+ return;
}
low = i2c_r(sd, 0x0b);
if (low < 0) {
PDEBUG(D_ERR, "Error detecting camera chip VER");
- return low;
+ return;
}
if (high == 0x76) {
switch (low) {
case 0x30:
err("Sensor is an OV7630/OV7635");
err("7630 is not supported by this driver");
- return -1;
+ return;
case 0x40:
PDEBUG(D_PROBE, "Sensor is an OV7645");
sd->sensor = SEN_OV7640; /* FIXME */
@@ -2561,9 +2722,14 @@ static int ov7xx0_configure(struct sd *sd)
PDEBUG(D_PROBE, "Sensor is an OV7648");
sd->sensor = SEN_OV7648;
break;
+ case 0x60:
+ PDEBUG(D_PROBE, "Sensor is a OV7660");
+ sd->sensor = SEN_OV7660;
+ sd->invert_led = 0;
+ break;
default:
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
- return -1;
+ return;
}
} else {
PDEBUG(D_PROBE, "Sensor is an OV7620");
@@ -2571,15 +2737,11 @@ static int ov7xx0_configure(struct sd *sd)
}
} else {
err("Unknown image sensor version: %d", rc & 3);
- return -1;
}
-
- /* Set sensor-specific vars */
- return 0;
}
/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
-static int ov6xx0_configure(struct sd *sd)
+static void ov6xx0_configure(struct sd *sd)
{
int rc;
PDEBUG(D_PROBE, "starting OV6xx0 configuration");
@@ -2588,7 +2750,7 @@ static int ov6xx0_configure(struct sd *sd)
rc = i2c_r(sd, OV7610_REG_COM_I);
if (rc < 0) {
PDEBUG(D_ERR, "Error detecting sensor type");
- return -1;
+ return;
}
/* Ugh. The first two bits are the version bits, but
@@ -2619,13 +2781,11 @@ static int ov6xx0_configure(struct sd *sd)
break;
default:
err("FATAL: Unknown sensor version: 0x%02x", rc);
- return -1;
+ return;
}
/* Set sensor-specific vars */
sd->sif = 1;
-
- return 0;
}
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
@@ -2637,14 +2797,14 @@ static void ov51x_led_control(struct sd *sd, int on)
switch (sd->bridge) {
/* OV511 has no LED control */
case BRIDGE_OV511PLUS:
- reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
+ reg_w(sd, R511_SYS_LED_CTL, on);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
+ reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
break;
case BRIDGE_OV519:
- reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
+ reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
break;
}
}
@@ -2679,7 +2839,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
}
}
-static int ov51x_upload_quan_tables(struct sd *sd)
+static void ov51x_upload_quan_tables(struct sd *sd)
{
const unsigned char yQuanTable511[] = {
0, 1, 1, 2, 2, 3, 3, 4,
@@ -2710,7 +2870,6 @@ static int ov51x_upload_quan_tables(struct sd *sd)
6, 6, 6, 6, 7, 7, 7, 8,
7, 7, 6, 7, 7, 7, 8, 8
};
-
const unsigned char uvQuanTable518[] = {
6, 6, 6, 7, 7, 7, 7, 7,
6, 6, 6, 7, 7, 7, 7, 7,
@@ -2720,18 +2879,18 @@ static int ov51x_upload_quan_tables(struct sd *sd)
const unsigned char *pYTable, *pUVTable;
unsigned char val0, val1;
- int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
+ int i, size, reg = R51x_COMP_LUT_BEGIN;
PDEBUG(D_PROBE, "Uploading quantization tables");
if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
pYTable = yQuanTable511;
pUVTable = uvQuanTable511;
- size = 32;
+ size = 32;
} else {
pYTable = yQuanTable518;
pUVTable = uvQuanTable518;
- size = 16;
+ size = 16;
}
for (i = 0; i < size; i++) {
@@ -2740,30 +2899,23 @@ static int ov51x_upload_quan_tables(struct sd *sd)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = reg_w(sd, reg, val0);
- if (rc < 0)
- return rc;
+ reg_w(sd, reg, val0);
val0 = *pUVTable++;
val1 = *pUVTable++;
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = reg_w(sd, reg + size, val0);
- if (rc < 0)
- return rc;
+ reg_w(sd, reg + size, val0);
reg++;
}
-
- return 0;
}
/* This initializes the OV511/OV511+ and the sensor */
-static int ov511_configure(struct gspca_dev *gspca_dev)
+static void ov511_configure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int rc;
/* For 511 and 511+ */
const struct ov_regvals init_511[] = {
@@ -2809,42 +2961,27 @@ static int ov511_configure(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
- rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
- if (rc < 0)
- return rc;
+ write_regvals(sd, init_511, ARRAY_SIZE(init_511));
switch (sd->bridge) {
case BRIDGE_OV511:
- rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
break;
case BRIDGE_OV511PLUS:
- rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
break;
}
/* Init compression */
- rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
- if (rc < 0)
- return rc;
-
- rc = ov51x_upload_quan_tables(sd);
- if (rc < 0) {
- PDEBUG(D_ERR, "Error uploading quantization tables");
- return rc;
- }
+ write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
- return 0;
+ ov51x_upload_quan_tables(sd);
}
/* This initializes the OV518/OV518+ and the sensor */
-static int ov518_configure(struct gspca_dev *gspca_dev)
+static void ov518_configure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int rc;
/* For 518 and 518+ */
const struct ov_regvals init_518[] = {
@@ -2892,65 +3029,49 @@ static int ov518_configure(struct gspca_dev *gspca_dev)
/* First 5 bits of custom ID reg are a revision ID on OV518 */
PDEBUG(D_PROBE, "Device revision %d",
- 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
+ 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
- rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
- if (rc < 0)
- return rc;
+ write_regvals(sd, init_518, ARRAY_SIZE(init_518));
/* Set LED GPIO pin to output mode */
- rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
- if (rc < 0)
- return rc;
+ reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
switch (sd->bridge) {
case BRIDGE_OV518:
- rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
break;
case BRIDGE_OV518PLUS:
- rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
- if (rc < 0)
- return rc;
+ write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
break;
}
- rc = ov51x_upload_quan_tables(sd);
- if (rc < 0) {
- PDEBUG(D_ERR, "Error uploading quantization tables");
- return rc;
- }
+ ov51x_upload_quan_tables(sd);
- rc = reg_w(sd, 0x2f, 0x80);
- if (rc < 0)
- return rc;
-
- return 0;
+ reg_w(sd, 0x2f, 0x80);
}
-static int ov519_configure(struct sd *sd)
+static void ov519_configure(struct sd *sd)
{
static const struct ov_regvals init_519[] = {
- { 0x5a, 0x6d }, /* EnableSystem */
- { 0x53, 0x9b },
- { 0x54, 0xff }, /* set bit2 to enable jpeg */
- { 0x5d, 0x03 },
- { 0x49, 0x01 },
- { 0x48, 0x00 },
+ { 0x5a, 0x6d }, /* EnableSystem */
+ { 0x53, 0x9b },
+ { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
+ { 0x5d, 0x03 },
+ { 0x49, 0x01 },
+ { 0x48, 0x00 },
/* Set LED pin to output mode. Bit 4 must be cleared or sensor
* detection will fail. This deserves further investigation. */
{ OV519_GPIO_IO_CTRL0, 0xee },
- { 0x51, 0x0f }, /* SetUsbInit */
- { 0x51, 0x00 },
- { 0x22, 0x00 },
+ { OV519_R51_RESET1, 0x0f },
+ { OV519_R51_RESET1, 0x00 },
+ { 0x22, 0x00 },
/* windows reads 0x55 at this point*/
};
- return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
+ write_regvals(sd, init_519, ARRAY_SIZE(init_519));
}
-static int ovfx2_configure(struct sd *sd)
+static void ovfx2_configure(struct sd *sd)
{
static const struct ov_regvals init_fx2[] = {
{ 0x00, 0x60 },
@@ -2964,7 +3085,92 @@ static int ovfx2_configure(struct sd *sd)
sd->stopped = 1;
- return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+ write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
+}
+
+/* set the mode */
+/* This function works for ov7660 only */
+static void ov519_set_mode(struct sd *sd)
+{
+ static const struct ov_regvals bridge_ov7660[2][10] = {
+ {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
+ {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
+ {0x25, 0x01}, {0x26, 0x00}},
+ {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
+ {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
+ {0x25, 0x03}, {0x26, 0x00}}
+ };
+ static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
+ {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
+ {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
+ };
+ static const struct ov_i2c_regvals sensor_ov7660_2[] = {
+ {OV7670_R17_HSTART, 0x13},
+ {OV7670_R18_HSTOP, 0x01},
+ {OV7670_R32_HREF, 0x92},
+ {OV7670_R19_VSTART, 0x02},
+ {OV7670_R1A_VSTOP, 0x7a},
+ {OV7670_R03_VREF, 0x00},
+/* {0x33, 0x00}, */
+/* {0x34, 0x07}, */
+/* {0x36, 0x00}, */
+/* {0x6b, 0x0a}, */
+ };
+
+ write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
+ ARRAY_SIZE(bridge_ov7660[0]));
+ write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
+ ARRAY_SIZE(sensor_ov7660[0]));
+ write_i2c_regvals(sd, sensor_ov7660_2,
+ ARRAY_SIZE(sensor_ov7660_2));
+}
+
+/* set the frame rate */
+/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
+static void ov519_set_fr(struct sd *sd)
+{
+ int fr;
+ u8 clock;
+ /* frame rate table with indices:
+ * - mode = 0: 320x240, 1: 640x480
+ * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
+ * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
+ */
+ static const u8 fr_tb[2][6][3] = {
+ {{0x04, 0xff, 0x00},
+ {0x04, 0x1f, 0x00},
+ {0x04, 0x1b, 0x00},
+ {0x04, 0x15, 0x00},
+ {0x04, 0x09, 0x00},
+ {0x04, 0x01, 0x00}},
+ {{0x0c, 0xff, 0x00},
+ {0x0c, 0x1f, 0x00},
+ {0x0c, 0x1b, 0x00},
+ {0x04, 0xff, 0x01},
+ {0x04, 0x1f, 0x01},
+ {0x04, 0x1b, 0x01}},
+ };
+
+ if (frame_rate > 0)
+ sd->frame_rate = frame_rate;
+ if (sd->frame_rate >= 30)
+ fr = 0;
+ else if (sd->frame_rate >= 25)
+ fr = 1;
+ else if (sd->frame_rate >= 20)
+ fr = 2;
+ else if (sd->frame_rate >= 15)
+ fr = 3;
+ else if (sd->frame_rate >= 10)
+ fr = 4;
+ else
+ fr = 5;
+ reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
+ reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
+ clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
+ if (sd->sensor == SEN_OV7660)
+ clock |= 0x80; /* enable double clock */
+ ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
}
/* this function is called at probe time */
@@ -2973,99 +3179,119 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
- int ret = 0;
sd->bridge = id->driver_info & BRIDGE_MASK;
- sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
+ sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- ret = ov511_configure(gspca_dev);
+ cam->cam_mode = ov511_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- ret = ov518_configure(gspca_dev);
+ cam->cam_mode = ov518_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
break;
case BRIDGE_OV519:
- ret = ov519_configure(sd);
+ cam->cam_mode = ov519_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
+ sd->invert_led = !sd->invert_led;
break;
case BRIDGE_OVFX2:
- ret = ovfx2_configure(sd);
+ cam->cam_mode = ov519_vga_mode;
+ cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
cam->bulk_size = OVFX2_BULK_SIZE;
cam->bulk_nurbs = MAX_NURBS;
cam->bulk = 1;
break;
case BRIDGE_W9968CF:
- ret = w9968cf_configure(sd);
+ cam->cam_mode = w9968cf_vga_mode;
+ cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
cam->reverse_alts = 1;
break;
}
- if (ret)
- goto error;
+ gspca_dev->cam.ctrls = sd->ctrls;
+ sd->quality = QUALITY_DEF;
- ov51x_led_control(sd, 0); /* turn LED off */
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam = &gspca_dev->cam;
+
+ switch (sd->bridge) {
+ case BRIDGE_OV511:
+ case BRIDGE_OV511PLUS:
+ ov511_configure(gspca_dev);
+ break;
+ case BRIDGE_OV518:
+ case BRIDGE_OV518PLUS:
+ ov518_configure(gspca_dev);
+ break;
+ case BRIDGE_OV519:
+ ov519_configure(sd);
+ break;
+ case BRIDGE_OVFX2:
+ ovfx2_configure(sd);
+ break;
+ case BRIDGE_W9968CF:
+ w9968cf_configure(sd);
+ break;
+ }
/* The OV519 must be more aggressive about sensor detection since
* I2C write will never fail if the sensor is not present. We have
* to try to initialize the sensor to detect its presence */
+ sd->sensor = -1;
/* Test for 76xx */
if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
- if (ov7xx0_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure OV7xx0");
- goto error;
- }
+ ov7xx0_configure(sd);
+
/* Test for 6xx0 */
} else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
- if (ov6xx0_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure OV6xx0");
- goto error;
- }
+ ov6xx0_configure(sd);
+
/* Test for 8xx0 */
} else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
- if (ov8xx0_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure OV8xx0");
- goto error;
- }
+ ov8xx0_configure(sd);
+
/* Test for 3xxx / 2xxx */
} else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
- if (ov_hires_configure(sd) < 0) {
- PDEBUG(D_ERR, "Failed to configure high res OV");
- goto error;
- }
+ ov_hires_configure(sd);
} else {
err("Can't determine sensor slave IDs");
goto error;
}
+ if (sd->sensor < 0)
+ goto error;
+
+ ov51x_led_control(sd, 0); /* turn LED off */
+
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- if (!sd->sif) {
- cam->cam_mode = ov511_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
- } else {
+ if (sd->sif) {
cam->cam_mode = ov511_sif_mode;
cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
}
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- if (!sd->sif) {
- cam->cam_mode = ov518_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
- } else {
+ if (sd->sif) {
cam->cam_mode = ov518_sif_mode;
cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
}
break;
case BRIDGE_OV519:
- if (!sd->sif) {
- cam->cam_mode = ov519_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- } else {
+ if (sd->sif) {
cam->cam_mode = ov519_sif_mode;
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
}
@@ -3077,118 +3303,107 @@ static int sd_config(struct gspca_dev *gspca_dev,
} else if (sd->sensor == SEN_OV3610) {
cam->cam_mode = ovfx2_ov3610_mode;
cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
- } else if (!sd->sif) {
- cam->cam_mode = ov519_vga_mode;
- cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
- } else {
+ } else if (sd->sif) {
cam->cam_mode = ov519_sif_mode;
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
}
break;
case BRIDGE_W9968CF:
- cam->cam_mode = w9968cf_vga_mode;
- cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
if (sd->sif)
- cam->nmodes--;
+ cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
/* w9968cf needs initialisation once the sensor is known */
- if (w9968cf_init(sd) < 0)
- goto error;
+ w9968cf_init(sd);
break;
}
- gspca_dev->cam.ctrls = sd->ctrls;
- if (sd->sensor == SEN_OV7670)
- gspca_dev->ctrl_dis = 1 << COLORS;
- else
- gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
- sd->quality = QUALITY_DEF;
- if (sd->sensor == SEN_OV7640 ||
- sd->sensor == SEN_OV7648)
- gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST);
- if (sd->sensor == SEN_OV7670)
- gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT;
- /* OV8610 Frequency filter control should work but needs testing */
- if (sd->sensor == SEN_OV8610)
- gspca_dev->ctrl_dis |= 1 << FREQ;
- /* No controls for the OV2610/OV3610 */
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- gspca_dev->ctrl_dis |= (1 << NCTRL) - 1;
- return 0;
-error:
- PDEBUG(D_ERR, "OV519 Config failed");
- return -EBUSY;
-}
-
-/* this function is called at probe and resume time */
-static int sd_init(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
+ gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
/* initialize the sensor */
switch (sd->sensor) {
case SEN_OV2610:
- if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
- return -EIO;
+ write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
+
/* Enable autogain, autoexpo, awb, bandfilter */
- if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
- return -EIO;
+ i2c_w_mask(sd, 0x13, 0x27, 0x27);
break;
case SEN_OV3610:
- if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
- return -EIO;
+ write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
+
/* Enable autogain, autoexpo, awb, bandfilter */
- if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
- return -EIO;
+ i2c_w_mask(sd, 0x13, 0x27, 0x27);
break;
case SEN_OV6620:
- if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
- return -EIO;
+ write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
break;
case SEN_OV6630:
case SEN_OV66308AF:
sd->ctrls[CONTRAST].def = 200;
/* The default is too low for the ov6630 */
- if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
- return -EIO;
+ write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
break;
default:
/* case SEN_OV7610: */
/* case SEN_OV76BE: */
- if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
- return -EIO;
- if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
- return -EIO;
+ write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
+ i2c_w_mask(sd, 0x0e, 0x00, 0x40);
break;
case SEN_OV7620:
case SEN_OV7620AE:
- if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
- return -EIO;
+ write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
break;
case SEN_OV7640:
case SEN_OV7648:
- if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
- return -EIO;
+ write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
+ break;
+ case SEN_OV7660:
+ i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
+ msleep(14);
+ reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
+ write_regvals(sd, init_519_ov7660,
+ ARRAY_SIZE(init_519_ov7660));
+ write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
+ sd->gspca_dev.curr_mode = 1; /* 640x480 */
+ sd->frame_rate = 15;
+ ov519_set_mode(sd);
+ ov519_set_fr(sd);
+ sd->ctrls[COLORS].max = 4; /* 0..4 */
+ sd->ctrls[COLORS].val =
+ sd->ctrls[COLORS].def = 2;
+ setcolors(gspca_dev);
+ sd->ctrls[CONTRAST].max = 6; /* 0..6 */
+ sd->ctrls[CONTRAST].val =
+ sd->ctrls[CONTRAST].def = 3;
+ setcontrast(gspca_dev);
+ sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
+ sd->ctrls[BRIGHTNESS].val =
+ sd->ctrls[BRIGHTNESS].def = 3;
+ setbrightness(gspca_dev);
+ sd_reset_snapshot(gspca_dev);
+ ov51x_restart(sd);
+ ov51x_stop(sd); /* not in win traces */
+ ov51x_led_control(sd, 0);
break;
case SEN_OV7670:
sd->ctrls[FREQ].max = 3; /* auto */
sd->ctrls[FREQ].def = 3;
- if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
- return -EIO;
+ write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
break;
case SEN_OV8610:
- if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
- return -EIO;
+ write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
break;
}
- return 0;
+ return gspca_dev->usb_err;
+error:
+ PDEBUG(D_ERR, "OV519 Config failed");
+ return -EINVAL;
}
/* Set up the OV511/OV511+ with the given image parameters.
*
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
-static int ov511_mode_init_regs(struct sd *sd)
+static void ov511_mode_init_regs(struct sd *sd)
{
int hsegs, vsegs, packet_size, fps, needed;
int interlaced = 0;
@@ -3199,7 +3414,8 @@ static int ov511_mode_init_regs(struct sd *sd)
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
err("Couldn't get altsetting");
- return -EIO;
+ sd->gspca_dev.usb_err = -EIO;
+ return;
}
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
@@ -3302,8 +3518,6 @@ static int ov511_mode_init_regs(struct sd *sd)
reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
reg_w(sd, R51x_SYS_RESET, 0);
-
- return 0;
}
/* Sets up the OV518/OV518+ with the given image parameters
@@ -3313,7 +3527,7 @@ static int ov511_mode_init_regs(struct sd *sd)
*
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
-static int ov518_mode_init_regs(struct sd *sd)
+static void ov518_mode_init_regs(struct sd *sd)
{
int hsegs, vsegs, packet_size;
struct usb_host_interface *alt;
@@ -3323,14 +3537,14 @@ static int ov518_mode_init_regs(struct sd *sd)
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
err("Couldn't get altsetting");
- return -EIO;
+ sd->gspca_dev.usb_err = -EIO;
+ return;
}
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
/******** Set the mode ********/
-
reg_w(sd, 0x2b, 0);
reg_w(sd, 0x2c, 0);
reg_w(sd, 0x2d, 0);
@@ -3364,7 +3578,7 @@ static int ov518_mode_init_regs(struct sd *sd)
/* Windows driver does this here; who knows why */
reg_w(sd, 0x2f, 0x80);
- /******** Set the framerate ********/
+ /******** Set the framerate ********/
sd->clockdiv = 1;
/* Mode independent, but framerate dependent, regs */
@@ -3427,11 +3641,8 @@ static int ov518_mode_init_regs(struct sd *sd)
}
reg_w(sd, 0x2f, 0x80);
-
- return 0;
}
-
/* Sets up the OV519 with the given image parameters
*
* OV519 needs a completely different approach, until we can figure out what
@@ -3439,12 +3650,12 @@ static int ov518_mode_init_regs(struct sd *sd)
*
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
-static int ov519_mode_init_regs(struct sd *sd)
+static void ov519_mode_init_regs(struct sd *sd)
{
static const struct ov_regvals mode_init_519_ov7670[] = {
{ 0x5d, 0x03 }, /* Turn off suspend mode */
{ 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
- { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
{ 0xa2, 0x20 }, /* a2-a5 are undocumented */
{ 0xa3, 0x18 },
{ 0xa4, 0x04 },
@@ -3467,7 +3678,7 @@ static int ov519_mode_init_regs(struct sd *sd)
static const struct ov_regvals mode_init_519[] = {
{ 0x5d, 0x03 }, /* Turn off suspend mode */
{ 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
- { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
{ 0xa2, 0x20 }, /* a2-a5 are undocumented */
{ 0xa3, 0x18 },
{ 0xa4, 0x04 },
@@ -3486,19 +3697,21 @@ static int ov519_mode_init_regs(struct sd *sd)
};
/******** Set the mode ********/
- if (sd->sensor != SEN_OV7670) {
- if (write_regvals(sd, mode_init_519,
- ARRAY_SIZE(mode_init_519)))
- return -EIO;
+ switch (sd->sensor) {
+ default:
+ write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
if (sd->sensor == SEN_OV7640 ||
sd->sensor == SEN_OV7648) {
/* Select 8-bit input mode */
reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
}
- } else {
- if (write_regvals(sd, mode_init_519_ov7670,
- ARRAY_SIZE(mode_init_519_ov7670)))
- return -EIO;
+ break;
+ case SEN_OV7660:
+ return; /* done by ov519_set_mode/fr() */
+ case SEN_OV7670:
+ write_regvals(sd, mode_init_519_ov7670,
+ ARRAY_SIZE(mode_init_519_ov7670));
+ break;
}
reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
@@ -3594,17 +3807,16 @@ static int ov519_mode_init_regs(struct sd *sd)
}
break;
}
- return 0;
}
-static int mode_init_ov_sensor_regs(struct sd *sd)
+static void mode_init_ov_sensor_regs(struct sd *sd)
{
struct gspca_dev *gspca_dev;
int qvga, xstart, xend, ystart, yend;
- __u8 v;
+ u8 v;
gspca_dev = &sd->gspca_dev;
- qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
+ qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
/******** Mode (VGA/QVGA) and sensor specific regs ********/
switch (sd->sensor) {
@@ -3616,7 +3828,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
- return 0;
+ return;
case SEN_OV3610:
if (qvga) {
xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
@@ -3640,7 +3852,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
i2c_w(sd, 0x18, xend >> 4);
i2c_w(sd, 0x19, ystart >> 3);
i2c_w(sd, 0x1a, yend >> 3);
- return 0;
+ return;
case SEN_OV8610:
/* For OV8610 qvga means qsvga */
i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
@@ -3687,11 +3899,11 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
/* set COM7_FMT_VGA or COM7_FMT_QVGA
* do we need to set anything else?
* HSTART etc are set in set_ov_sensor_window itself */
- i2c_w_mask(sd, OV7670_REG_COM7,
+ i2c_w_mask(sd, OV7670_R12_COM7,
qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
OV7670_COM7_FMT_MASK);
i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
OV7670_COM8_AWB);
if (qvga) { /* QVGA from ov7670.c by
* Jonathan Corbet */
@@ -3707,21 +3919,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
}
/* OV7670 hardware window registers are split across
* multiple locations */
- i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
- i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
- v = i2c_r(sd, OV7670_REG_HREF);
+ i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
+ i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
+ v = i2c_r(sd, OV7670_R32_HREF);
v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
msleep(10); /* need to sleep between read and write to
* same reg! */
- i2c_w(sd, OV7670_REG_HREF, v);
+ i2c_w(sd, OV7670_R32_HREF, v);
- i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
- i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
- v = i2c_r(sd, OV7670_REG_VREF);
+ i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
+ i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
+ v = i2c_r(sd, OV7670_R03_VREF);
v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
msleep(10); /* need to sleep between read and write to
* same reg! */
- i2c_w(sd, OV7670_REG_VREF, v);
+ i2c_w(sd, OV7670_R03_VREF, v);
break;
case SEN_OV6620:
i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
@@ -3734,46 +3946,50 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
break;
default:
- return -EINVAL;
+ return;
}
/******** Clock programming ********/
i2c_w(sd, 0x11, sd->clockdiv);
-
- return 0;
}
+/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
static void sethvflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- if (sd->sensor != SEN_OV7670)
- return;
if (sd->gspca_dev.streaming)
- ov51x_stop(sd);
- i2c_w_mask(sd, OV7670_REG_MVFP,
+ reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */
+ i2c_w_mask(sd, OV7670_R1E_MVFP,
OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
| OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
if (sd->gspca_dev.streaming)
- ov51x_restart(sd);
+ reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */
}
-static int set_ov_sensor_window(struct sd *sd)
+static void set_ov_sensor_window(struct sd *sd)
{
struct gspca_dev *gspca_dev;
int qvga, crop;
int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
- int ret;
/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
- sd->sensor == SEN_OV7670)
- return mode_init_ov_sensor_regs(sd);
+ switch (sd->sensor) {
+ case SEN_OV2610:
+ case SEN_OV3610:
+ case SEN_OV7670:
+ mode_init_ov_sensor_regs(sd);
+ return;
+ case SEN_OV7660:
+ ov519_set_mode(sd);
+ ov519_set_fr(sd);
+ return;
+ }
gspca_dev = &sd->gspca_dev;
- qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
- crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
+ qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
+ crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
/* The different sensor ICs handle setting up of window differently.
* IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
@@ -3820,7 +4036,7 @@ static int set_ov_sensor_window(struct sd *sd)
vwsbase = vwebase = 0x03;
break;
default:
- return -EINVAL;
+ return;
}
switch (sd->sensor) {
@@ -3855,23 +4071,18 @@ static int set_ov_sensor_window(struct sd *sd)
}
}
- ret = mode_init_ov_sensor_regs(sd);
- if (ret < 0)
- return ret;
+ mode_init_ov_sensor_regs(sd);
i2c_w(sd, 0x17, hwsbase);
i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
i2c_w(sd, 0x19, vwsbase);
i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
-
- return 0;
}
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int ret = 0;
/* Default for most bridges, allow bridge_mode_init_regs to override */
sd->sensor_width = sd->gspca_dev.width;
@@ -3880,50 +4091,46 @@ static int sd_start(struct gspca_dev *gspca_dev)
switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
- ret = ov511_mode_init_regs(sd);
+ ov511_mode_init_regs(sd);
break;
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
- ret = ov518_mode_init_regs(sd);
+ ov518_mode_init_regs(sd);
break;
case BRIDGE_OV519:
- ret = ov519_mode_init_regs(sd);
+ ov519_mode_init_regs(sd);
break;
/* case BRIDGE_OVFX2: nothing to do */
case BRIDGE_W9968CF:
- ret = w9968cf_mode_init_regs(sd);
+ w9968cf_mode_init_regs(sd);
break;
}
- if (ret < 0)
- goto out;
-
- ret = set_ov_sensor_window(sd);
- if (ret < 0)
- goto out;
-
- setcontrast(gspca_dev);
- setbrightness(gspca_dev);
- setcolors(gspca_dev);
- sethvflip(gspca_dev);
- setautobright(gspca_dev);
- setfreq_i(sd);
+
+ set_ov_sensor_window(sd);
+
+ if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST)))
+ setcontrast(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
+ setbrightness(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
+ setcolors(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
+ sethvflip(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
+ setautobright(gspca_dev);
+ if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
+ setfreq_i(sd);
/* Force clear snapshot state in case the snapshot button was
pressed while we weren't streaming */
sd->snapshot_needs_reset = 1;
sd_reset_snapshot(gspca_dev);
- sd->snapshot_pressed = 0;
sd->first_frame = 3;
- ret = ov51x_restart(sd);
- if (ret < 0)
- goto out;
+ ov51x_restart(sd);
ov51x_led_control(sd, 1);
- return 0;
-out:
- PDEBUG(D_ERR, "camera start error:%d", ret);
- return ret;
+ return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -3938,8 +4145,21 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ if (!sd->gspca_dev.present)
+ return;
if (sd->bridge == BRIDGE_W9968CF)
w9968cf_stop0(sd);
+
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ /* If the last button state is pressed, release it now! */
+ if (sd->snapshot_pressed) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+ input_sync(gspca_dev->input_dev);
+ sd->snapshot_pressed = 0;
+ }
+#endif
+ if (sd->bridge == BRIDGE_OV519)
+ reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
}
static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
@@ -4160,6 +4380,22 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int val;
+ static const struct ov_i2c_regvals brit_7660[][7] = {
+ {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
+ {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
+ {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
+ {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
+ {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
+ {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
+ {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
+ {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
+ {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
+ {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
+ {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
+ {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
+ {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
+ {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
+ };
val = sd->ctrls[BRIGHTNESS].val;
switch (sd->sensor) {
@@ -4179,10 +4415,14 @@ static void setbrightness(struct gspca_dev *gspca_dev)
if (!sd->ctrls[AUTOBRIGHT].val)
i2c_w(sd, OV7610_REG_BRT, val);
break;
+ case SEN_OV7660:
+ write_i2c_regvals(sd, brit_7660[val],
+ ARRAY_SIZE(brit_7660[0]));
+ break;
case SEN_OV7670:
/*win trace
- * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
- i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
+ * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
+ i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
break;
}
}
@@ -4191,6 +4431,64 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int val;
+ static const struct ov_i2c_regvals contrast_7660[][31] = {
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
+ {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
+ {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
+ {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
+ {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
+ {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
+ {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
+ {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
+ {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
+ {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
+ {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
+ {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
+ {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
+ {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
+ {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
+ {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
+ {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
+ {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
+ {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
+ {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
+ {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
+ {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
+ {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
+ {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
+ {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
+ {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
+ {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
+ {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
+ {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
+ {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
+ {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
+ {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
+ {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
+ {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
+ {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
+ {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
+ {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
+ {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
+ {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
+ {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
+ {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
+ {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
+ {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
+ {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
+ {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
+ {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
+ {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
+ {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
+ {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
+ };
val = sd->ctrls[CONTRAST].val;
switch (sd->sensor) {
@@ -4203,7 +4501,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
break;
case SEN_OV8610: {
- static const __u8 ctab[] = {
+ static const u8 ctab[] = {
0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
};
@@ -4213,7 +4511,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
}
case SEN_OV7620:
case SEN_OV7620AE: {
- static const __u8 ctab[] = {
+ static const u8 ctab[] = {
0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
};
@@ -4222,9 +4520,13 @@ static void setcontrast(struct gspca_dev *gspca_dev)
i2c_w(sd, 0x64, ctab[val >> 4]);
break;
}
+ case SEN_OV7660:
+ write_i2c_regvals(sd, contrast_7660[val],
+ ARRAY_SIZE(contrast_7660[0]));
+ break;
case SEN_OV7670:
/* check that this isn't just the same as ov7610 */
- i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
+ i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
break;
}
}
@@ -4233,6 +4535,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int val;
+ static const struct ov_i2c_regvals colors_7660[][6] = {
+ {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
+ {0x53, 0x19}, {0x54, 0x23}},
+ {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
+ {0x53, 0x2c}, {0x54, 0x3e}},
+ {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
+ {0x53, 0x40}, {0x54, 0x59}},
+ {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
+ {0x53, 0x53}, {0x54, 0x73}},
+ {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
+ {0x53, 0x66}, {0x54, 0x8e}},
+ };
val = sd->ctrls[COLORS].val;
switch (sd->sensor) {
@@ -4256,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
case SEN_OV7648:
i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
break;
+ case SEN_OV7660:
+ write_i2c_regvals(sd, colors_7660[val],
+ ARRAY_SIZE(colors_7660[0]));
+ break;
case SEN_OV7670:
/* supported later once I work out how to do it
* transparently fail now! */
@@ -4268,38 +4586,31 @@ static void setautobright(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
- sd->sensor == SEN_OV7670 ||
- sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- return;
-
i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
}
static void setfreq_i(struct sd *sd)
{
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- return;
-
- if (sd->sensor == SEN_OV7670) {
+ if (sd->sensor == SEN_OV7660
+ || sd->sensor == SEN_OV7670) {
switch (sd->ctrls[FREQ].val) {
case 0: /* Banding filter disabled */
- i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
+ i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
break;
case 1: /* 50 hz */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
+ i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
break;
case 2: /* 60 hz */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
+ i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
break;
- case 3: /* Auto hz */
- i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
+ case 3: /* Auto hz - ov7670 only */
+ i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
OV7670_COM8_BFILT);
- i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
+ i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
0x18);
break;
}
@@ -4443,14 +4754,14 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4064),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4068),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x054c, 0x0155),
- .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
+ .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
@@ -4464,7 +4775,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
- {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
+ {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
{}
};
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 15e97fa4c337..96f9986305b4 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -162,7 +162,7 @@ static const __u8 pac207_sensor_init[][8] = {
{0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84},
{0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
{0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
- {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
+ {0x32, 0x00, 0x96, 0x00, 0xa2, 0x02, 0xaf, 0x00},
};
static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
@@ -228,7 +228,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
- idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
+ idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4);
idreg[1] = idreg[1] & 0x0f;
PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
idreg[0], idreg[1]);
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 6b155ae3a746..cb08d00d0a31 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -33,6 +33,14 @@ MODULE_LICENSE("GPL");
#define MODULE_NAME "sn9c20x"
+/*
+ * Pixel format private data
+ */
+#define SCALE_MASK 0x0f
+#define SCALE_160x120 0
+#define SCALE_320x240 1
+#define SCALE_640x480 2
+#define SCALE_1280x1024 3
#define MODE_RAW 0x10
#define MODE_JPEG 0x20
#define MODE_SXGA 0x80
@@ -348,47 +356,47 @@ static const struct v4l2_pix_format vga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 4 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0 | MODE_JPEG},
+ .priv = SCALE_160x120 | MODE_JPEG},
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0 | MODE_RAW},
+ .priv = SCALE_160x120 | MODE_RAW},
{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 240 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
+ .priv = SCALE_160x120},
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1 | MODE_JPEG},
+ .priv = SCALE_320x240 | MODE_JPEG},
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_RAW},
+ .priv = SCALE_320x240 | MODE_RAW},
{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 480 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
+ .priv = SCALE_320x240},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2 | MODE_JPEG},
+ .priv = SCALE_640x480 | MODE_JPEG},
{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2 | MODE_RAW},
+ .priv = SCALE_640x480 | MODE_RAW},
{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 960 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
+ .priv = SCALE_640x480},
};
static const struct v4l2_pix_format sxga_mode[] = {
@@ -396,52 +404,75 @@ static const struct v4l2_pix_format sxga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 4 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 0 | MODE_JPEG},
+ .priv = SCALE_160x120 | MODE_JPEG},
{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 160 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0 | MODE_RAW},
+ .priv = SCALE_160x120 | MODE_RAW},
{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 160,
.sizeimage = 240 * 120,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0},
+ .priv = SCALE_160x120},
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 1 | MODE_JPEG},
+ .priv = SCALE_320x240 | MODE_JPEG},
{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1 | MODE_RAW},
+ .priv = SCALE_320x240 | MODE_RAW},
{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 480 * 240 ,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1},
+ .priv = SCALE_320x240},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 2 | MODE_JPEG},
+ .priv = SCALE_640x480 | MODE_JPEG},
{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2 | MODE_RAW},
+ .priv = SCALE_640x480 | MODE_RAW},
{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 960 * 480,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
+ .priv = SCALE_640x480},
{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
.bytesperline = 1280,
.sizeimage = 1280 * 1024,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 3 | MODE_RAW | MODE_SXGA},
+ .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
+};
+
+static const struct v4l2_pix_format mono_mode[] = {
+ {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_160x120 | MODE_RAW},
+ {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 ,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_320x240 | MODE_RAW},
+ {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_640x480 | MODE_RAW},
+ {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
};
static const s16 hsv_red_x[] = {
@@ -1029,16 +1060,19 @@ static struct i2c_reg_u16 mt9v011_init[] = {
};
static struct i2c_reg_u16 mt9m001_init[] = {
- {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
- {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
- {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
- {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
- {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
- {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
- {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
- {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
- {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
- {0x2e, 0x0029}, {0x07, 0x0002},
+ {0x0d, 0x0001},
+ {0x0d, 0x0000},
+ {0x04, 0x0500}, /* hres = 1280 */
+ {0x03, 0x0400}, /* vres = 1024 */
+ {0x20, 0x1100},
+ {0x06, 0x0010},
+ {0x2b, 0x0024},
+ {0x2e, 0x0024},
+ {0x35, 0x0024},
+ {0x2d, 0x0020},
+ {0x2c, 0x0020},
+ {0x09, 0x0ad4},
+ {0x35, 0x0057},
};
static struct i2c_reg_u16 mt9m111_init[] = {
@@ -1224,8 +1258,17 @@ static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
{
int i;
+ u16 id;
struct sd *sd = (struct sd *) gspca_dev;
+ if (i2c_r2(gspca_dev, 0x1c, &id) < 0)
+ return -EINVAL;
+
+ if (id != 0x7fa2) {
+ err("sensor id for ov9650 doesn't match (0x%04x)", id);
+ return -ENODEV;
+ }
+
for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
if (i2c_w1(gspca_dev, ov9650_init[i].reg,
ov9650_init[i].val) < 0) {
@@ -1425,6 +1468,25 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
+ u16 id;
+
+ if (i2c_r2(gspca_dev, 0x00, &id) < 0)
+ return -EINVAL;
+
+ /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
+ switch (id) {
+ case 0x8411:
+ case 0x8421:
+ info("MT9M001 color sensor detected");
+ break;
+ case 0x8431:
+ info("MT9M001 mono sensor detected");
+ break;
+ default:
+ err("No MT9M001 chip detected, ID = %x\n", id);
+ return -ENODEV;
+ }
+
for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
mt9m001_init[i].val) < 0) {
@@ -1434,8 +1496,8 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
}
/* disable hflip and vflip */
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
- sd->hstart = 2;
- sd->vstart = 2;
+ sd->hstart = 1;
+ sd->vstart = 1;
return 0;
}
@@ -1977,6 +2039,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sxga_mode;
cam->nmodes = ARRAY_SIZE(sxga_mode);
break;
+ case SENSOR_MT9M001:
+ cam->cam_mode = mono_mode;
+ cam->nmodes = ARRAY_SIZE(mono_mode);
+ break;
default:
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2075,7 +2141,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
case SENSOR_MT9M001:
if (mt9m001_init_sensor(gspca_dev) < 0)
return -ENODEV;
- info("MT9M001 sensor detected");
break;
case SENSOR_HV7131R:
if (hv7131r_init_sensor(gspca_dev) < 0)
@@ -2173,22 +2238,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
else if (mode & MODE_JPEG)
fmt = 0x2c;
else
- fmt = 0x2f;
+ fmt = 0x2f; /* YUV 420 */
- switch (mode & 0x0f) {
- case 3:
+ switch (mode & SCALE_MASK) {
+ case SCALE_1280x1024:
scale = 0xc0;
info("Set 1280x1024");
break;
- case 2:
+ case SCALE_640x480:
scale = 0x80;
info("Set 640x480");
break;
- case 1:
+ case SCALE_320x240:
scale = 0x90;
info("Set 320x240");
break;
- case 0:
+ case SCALE_160x120:
scale = 0xa0;
info("Set 160x120");
break;
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 706f96f92654..11b19728a41d 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -340,7 +340,7 @@ static const __u8 ov6650_sensor_init[][8] = {
* but blue wont be there. Avoid this data ... */
{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
- {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
+ {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
/* Enable rgb brightness control */
{0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
/* HDG: Note windows uses the line below, which sets both register 0x60
@@ -505,7 +505,7 @@ static const __u8 pas202_sensor_init[][8] = {
{0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
{0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
{0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
- {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
+ {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
{0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
{0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
{0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 330dadc00106..2229847fe034 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1579,22 +1579,22 @@ static void i2c_w_seq(struct gspca_dev *gspca_dev,
}
}
+/* check the ID of the hv7131 sensor */
+/* this sequence is needed because it activates the sensor */
static void hv7131r_probe(struct gspca_dev *gspca_dev)
{
- i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
+ i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
- reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
+ reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
msleep(10);
- i2c_r(gspca_dev, 0, 5); /* read sensor id */
- if (gspca_dev->usb_buf[0] == 0x02
+ i2c_r(gspca_dev, 0, 5); /* read sensor id */
+ if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
&& gspca_dev->usb_buf[1] == 0x09
- && gspca_dev->usb_buf[2] == 0x01
- && gspca_dev->usb_buf[3] == 0x00
- && gspca_dev->usb_buf[4] == 0x00) {
- PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
+ && gspca_dev->usb_buf[2] == 0x01) {
+ PDEBUG(D_PROBE, "Sensor HV7131R found");
return;
}
- PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
+ warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x",
gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
gspca_dev->usb_buf[2]);
}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index ad73f4812c05..3a162c6d5466 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -597,7 +597,7 @@ static void setgain(struct gspca_dev *gspca_dev)
else if (sd->gain < 128)
gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
else
- gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
+ gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0;
gspca_dev->usb_buf[1] = 0;
reg_w_buf(gspca_dev, 0x8335, 2);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 086de44a6e57..28ea4175b80e 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -263,7 +263,21 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
static int stv06xx_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int err;
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
+ int err, packet_size;
+
+ intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+ alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+ if (!alt) {
+ PDEBUG(D_ERR, "Couldn't get altsetting");
+ return -EIO;
+ }
+
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+ err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
+ if (err < 0)
+ return err;
/* Prepare the sensor for start */
err = sd->sensor->start(sd);
@@ -282,6 +296,43 @@ out:
return (err < 0) ? err : 0;
}
+static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
+{
+ struct usb_host_interface *alt;
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ alt->endpoint[0].desc.wMaxPacketSize =
+ cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
+
+ return 0;
+}
+
+static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev)
+{
+ int ret, packet_size, min_packet_size;
+ struct usb_host_interface *alt;
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+ min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
+ if (packet_size <= min_packet_size)
+ return -EIO;
+
+ packet_size -= 100;
+ if (packet_size < min_packet_size)
+ packet_size = min_packet_size;
+ alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
+
+ ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
+ if (ret < 0)
+ PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret);
+
+ return ret;
+}
+
static void stv06xx_stopN(struct gspca_dev *gspca_dev)
{
int err;
@@ -349,7 +400,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
}
/* First byte seem to be 02=data 2nd byte is unknown??? */
- if (sd->bridge == BRIDGE_ST6422 && (id & 0xFF00) == 0x0200)
+ if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200)
goto frame_data;
switch (id) {
@@ -462,6 +513,8 @@ static const struct sd_desc sd_desc = {
.start = stv06xx_start,
.stopN = stv06xx_stopN,
.pkt_scan = stv06xx_pkt_scan,
+ .isoc_init = stv06xx_isoc_init,
+ .isoc_nego = stv06xx_isoc_nego,
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
.int_pkt_scan = sd_int_pkt_scan,
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index cf3d0ccc1121..b538dce96f78 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -146,6 +146,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
+ /* FIXME (see if we can lower min_packet_size, needs testing, and also
+ adjusting framerate when the bandwidth gets lower) */
+ .min_packet_size = { 847 },
+ .max_packet_size = { 847 },
+
.init = hdcs_init,
.probe = hdcs_probe_1x00,
.start = hdcs_start,
@@ -160,6 +165,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
+ /* FIXME (see if we can lower min_packet_size, needs testing, and also
+ adjusting framerate when the bandwidthm gets lower) */
+ .min_packet_size = { 847 },
+ .max_packet_size = { 847 },
+
.init = hdcs_init,
.probe = hdcs_probe_1020,
.start = hdcs_start,
@@ -177,7 +187,6 @@ static const u16 stv_bridge_init[][2] = {
{STV_REG04, 0x07},
{STV_SCAN_RATE, 0x20},
- {STV_ISO_SIZE_L, 847},
{STV_Y_CTRL, 0x01},
{STV_X_CTRL, 0x0a}
};
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index 285221e6b390..ac47b4c94388 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -208,11 +208,24 @@ static int pb0100_probe(struct sd *sd)
static int pb0100_start(struct sd *sd)
{
- int err;
+ int err, packet_size, max_packet_size;
+ struct usb_host_interface *alt;
+ struct usb_interface *intf;
struct cam *cam = &sd->gspca_dev.cam;
s32 *sensor_settings = sd->sensor_priv;
u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
+ intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
+ alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+ packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
+
+ /* If we don't have enough bandwidth use a lower framerate */
+ max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
+ if (packet_size < max_packet_size)
+ stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
+ else
+ stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
+
/* Setup sensor window */
if (mode & PB0100_CROP_TO_VGA) {
stv06xx_write_sensor(sd, PB_RSTART, 30);
@@ -328,9 +341,6 @@ static int pb0100_init(struct sd *sd)
stv06xx_write_bridge(sd, STV_REG03, 0x45);
stv06xx_write_bridge(sd, STV_REG04, 0x07);
- /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
- stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
-
/* Scan/timing for the sensor */
stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
stv06xx_write_sensor(sd, PB_CFILLIN, 14);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 4de4fa5ebc57..757de246dc75 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -138,6 +138,9 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
.i2c_addr = 0xba,
.i2c_len = 2,
+ .min_packet_size = { 635, 847 },
+ .max_packet_size = { 847, 923 },
+
.init = pb0100_init,
.probe = pb0100_probe,
.start = pb0100_start,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index 934b9cebc1ab..fb229d8ded58 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -53,6 +53,10 @@ struct stv06xx_sensor {
/* length of an i2c word */
u8 i2c_len;
+ /* Isoc packet size (per mode) */
+ int min_packet_size[4];
+ int max_packet_size[4];
+
/* Probes if the sensor is connected */
int (*probe)(struct sd *sd);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 3af53264a364..42f3a1e41188 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -151,11 +151,11 @@ static int st6422_init(struct sd *sd)
{ STV_ISO_ENABLE, 0x00 }, /* disable capture */
{ 0x1436, 0x00 },
{ 0x1432, 0x03 }, /* 0x00-0x1F brightness */
- { 0x143a, 0xF9 }, /* 0x00-0x0F contrast */
+ { 0x143a, 0xf9 }, /* 0x00-0x0F contrast */
{ 0x0509, 0x38 }, /* R */
{ 0x050a, 0x38 }, /* G */
{ 0x050b, 0x38 }, /* B */
- { 0x050c, 0x2A },
+ { 0x050c, 0x2a },
{ 0x050d, 0x01 },
@@ -213,7 +213,6 @@ static int st6422_init(struct sd *sd)
{ 0x150e, 0x8e },
{ 0x150f, 0x37 },
{ 0x15c0, 0x00 },
- { 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */
{ 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */
@@ -237,23 +236,9 @@ static void st6422_disconnect(struct sd *sd)
static int st6422_start(struct sd *sd)
{
- int err, packet_size;
+ int err;
struct cam *cam = &sd->gspca_dev.cam;
s32 *sensor_settings = sd->sensor_priv;
- struct usb_host_interface *alt;
- struct usb_interface *intf;
-
- intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
- alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
- if (!alt) {
- err("Couldn't get altsetting");
- return -EIO;
- }
-
- packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- err = stv06xx_write_bridge(sd, 0x15c1, packet_size);
- if (err < 0)
- return err;
if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
index b2d45fe50522..12608aebe50b 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
@@ -49,6 +49,9 @@ static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
const struct stv06xx_sensor stv06xx_sensor_st6422 = {
.name = "ST6422",
+ /* No known way to lower framerate in case of less bandwidth */
+ .min_packet_size = { 300, 847 },
+ .max_packet_size = { 300, 847 },
.init = st6422_init,
.probe = st6422_probe,
.start = st6422_start,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index b3b5508473bc..7fe3587f5f71 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -197,6 +197,10 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.i2c_flush = 5,
.i2c_addr = 0x20,
.i2c_len = 1,
+ /* FIXME (see if we can lower packet_size-s, needs testing, and also
+ adjusting framerate when the bandwidth gets lower) */
+ .min_packet_size = { 1023 },
+ .max_packet_size = { 1023 },
.init = vv6410_init,
.probe = vv6410_probe,
.start = vv6410_start,
@@ -220,10 +224,6 @@ static const u8 x1536[] = { /* 0x1536 - 0x153b */
0x02, 0x00, 0x60, 0x01, 0x20, 0x01
};
-static const u8 x15c1[] = { /* 0x15c1 - 0x15c2 */
- 0xff, 0x03 /* Output word 0x03ff = 1023 (ISO size) */
-};
-
static const struct stv_init stv_bridge_init[] = {
/* This reg is written twice. Some kind of reset? */
{NULL, 0x1620, 0x80},
@@ -232,7 +232,6 @@ static const struct stv_init stv_bridge_init[] = {
{NULL, 0x1423, 0x04},
{x1500, 0x1500, ARRAY_SIZE(x1500)},
{x1536, 0x1536, ARRAY_SIZE(x1536)},
- {x15c1, 0x15c1, ARRAY_SIZE(x15c1)}
};
static const u8 vv6410_sensor_init[][2] = {
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index b45f4d0f3997..8f0c33116e0d 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -487,7 +487,7 @@ static const u8 gamma_table[GAMMA_MAX][17] = {
{0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
0xff},
- {0x00, 0x04, 0x0B, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
+ {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
0xff},
{0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index d9e3c6050781..38c22f0a4263 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -132,7 +132,7 @@ static const struct v4l2_pix_format sif_mode[] = {
#define R36_PID 0x36
#define R37_PIDH 0x37
#define R39_Test1 0x39 /* GPIO */
-#define R3B_Test3 0x3B /* GPIO */
+#define R3B_Test3 0x3b /* GPIO */
#define R83_AD_IDH 0x83
#define R91_AD_SLOPEREG 0x91
#define R94_AD_BITCONTROL 0x94
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
index 4066ac8c45a0..4a9e622e5e1b 100644
--- a/drivers/media/video/gspca/w996Xcf.c
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -59,18 +59,21 @@ static const struct v4l2_pix_format w9968cf_vga_mode[] = {
.colorspace = V4L2_COLORSPACE_JPEG},
};
-static int reg_w(struct sd *sd, __u16 index, __u16 value);
+static void reg_w(struct sd *sd, u16 index, u16 value);
/*--------------------------------------------------------------------------
Write 64-bit data to the fast serial bus registers.
Return 0 on success, -1 otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_write_fsb(struct sd *sd, u16* data)
+static void w9968cf_write_fsb(struct sd *sd, u16* data)
{
struct usb_device *udev = sd->gspca_dev.dev;
u16 value;
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
value = *data++;
memcpy(sd->gspca_dev.usb_buf, data, 6);
@@ -79,20 +82,21 @@ static int w9968cf_write_fsb(struct sd *sd, u16* data)
value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
if (ret < 0) {
err("Write FSB registers failed (%d)", ret);
- return ret;
+ sd->gspca_dev.usb_err = ret;
}
-
- return 0;
}
/*--------------------------------------------------------------------------
Write data to the serial bus control register.
Return 0 on success, a negative number otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_write_sb(struct sd *sd, u16 value)
+static void w9968cf_write_sb(struct sd *sd, u16 value)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return;
+
/* We don't use reg_w here, as that would cause all writes when
bitbanging i2c to be logged, making the logs impossible to read */
ret = usb_control_msg(sd->gspca_dev.dev,
@@ -105,10 +109,8 @@ static int w9968cf_write_sb(struct sd *sd, u16 value)
if (ret < 0) {
err("Write SB reg [01] %04x failed", value);
- return ret;
+ sd->gspca_dev.usb_err = ret;
}
-
- return 0;
}
/*--------------------------------------------------------------------------
@@ -119,6 +121,9 @@ static int w9968cf_read_sb(struct sd *sd)
{
int ret;
+ if (sd->gspca_dev.usb_err < 0)
+ return -1;
+
/* We don't use reg_r here, as the w9968cf is special and has 16
bit registers instead of 8 bit */
ret = usb_control_msg(sd->gspca_dev.dev,
@@ -126,11 +131,13 @@ static int w9968cf_read_sb(struct sd *sd)
1,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
- if (ret >= 0)
+ if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0] |
(sd->gspca_dev.usb_buf[1] << 8);
- else
+ } else {
err("Read SB reg [01] failed");
+ sd->gspca_dev.usb_err = ret;
+ }
udelay(W9968CF_I2C_BUS_DELAY);
@@ -142,22 +149,20 @@ static int w9968cf_read_sb(struct sd *sd)
This function is called by w9968cf_start_transfer().
Return 0 on success, a negative number otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_upload_quantizationtables(struct sd *sd)
+static void w9968cf_upload_quantizationtables(struct sd *sd)
{
u16 a, b;
- int ret = 0, i, j;
+ int i, j;
- ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
+ reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
for (i = 0, j = 0; i < 32; i++, j += 2) {
- a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
- b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
- ret += reg_w(sd, 0x40+i, a);
- ret += reg_w(sd, 0x60+i, b);
+ a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
+ b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
+ reg_w(sd, 0x40 + i, a);
+ reg_w(sd, 0x60 + i, b);
}
- ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
-
- return ret;
+ reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
}
/****************************************************************************
@@ -168,50 +173,39 @@ static int w9968cf_upload_quantizationtables(struct sd *sd)
* i2c_adap_read_byte() *
****************************************************************************/
-static int w9968cf_smbus_start(struct sd *sd)
+static void w9968cf_smbus_start(struct sd *sd)
{
- int ret = 0;
-
- ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
-
- return ret;
+ w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+ w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
}
-static int w9968cf_smbus_stop(struct sd *sd)
+static void w9968cf_smbus_stop(struct sd *sd)
{
- int ret = 0;
-
- ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
-
- return ret;
+ w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
+ w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
+ w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
}
-static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
+static void w9968cf_smbus_write_byte(struct sd *sd, u8 v)
{
u8 bit;
- int ret = 0, sda;
+ int sda;
for (bit = 0 ; bit < 8 ; bit++) {
sda = (v & 0x80) ? 2 : 0;
v <<= 1;
/* SDE=1, SDA=sda, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x10 | sda);
+ w9968cf_write_sb(sd, 0x10 | sda);
/* SDE=1, SDA=sda, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x11 | sda);
+ w9968cf_write_sb(sd, 0x11 | sda);
/* SDE=1, SDA=sda, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x10 | sda);
+ w9968cf_write_sb(sd, 0x10 | sda);
}
-
- return ret;
}
-static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
+static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v)
{
u8 bit;
- int ret = 0;
/* No need to ensure SDA is high as we are always called after
read_ack which ends with SDA high */
@@ -219,51 +213,40 @@ static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
for (bit = 0 ; bit < 8 ; bit++) {
*v <<= 1;
/* SDE=1, SDA=1, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0013);
+ w9968cf_write_sb(sd, 0x0013);
*v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
/* SDE=1, SDA=1, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x0012);
+ w9968cf_write_sb(sd, 0x0012);
}
-
- return ret;
}
-static int w9968cf_smbus_write_nack(struct sd *sd)
+static void w9968cf_smbus_write_nack(struct sd *sd)
{
- int ret = 0;
-
/* No need to ensure SDA is high as we are always called after
read_byte which ends with SDA high */
- ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
- ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
-
- return ret;
+ w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+ w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
}
-static int w9968cf_smbus_read_ack(struct sd *sd)
+static void w9968cf_smbus_read_ack(struct sd *sd)
{
- int ret = 0, sda;
+ int sda;
/* Ensure SDA is high before raising clock to avoid a spurious stop */
- ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
+ w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+ w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
sda = w9968cf_read_sb(sd);
- ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- if (sda < 0)
- ret += sda;
- else if (sda & 0x08) {
+ w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
+ if (sda >= 0 && (sda & 0x08)) {
PDEBUG(D_USBI, "Did not receive i2c ACK");
- ret += -1;
+ sd->gspca_dev.usb_err = -EIO;
}
-
- return ret;
}
/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
-static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
+static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
{
u16* data = (u16 *)sd->gspca_dev.usb_buf;
- int ret = 0;
data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
@@ -276,7 +259,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
- ret += w9968cf_write_fsb(sd, data);
+ w9968cf_write_fsb(sd, data);
data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
@@ -290,7 +273,7 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
data[3] = 0x001d;
- ret += w9968cf_write_fsb(sd, data);
+ w9968cf_write_fsb(sd, data);
data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
data[0] |= (value & 0x40) ? 0x0540 : 0x0;
@@ -304,14 +287,9 @@ static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
data[2] |= (value & 0x01) ? 0x5400 : 0x0;
data[3] = 0xfe1d;
- ret += w9968cf_write_fsb(sd, data);
+ w9968cf_write_fsb(sd, data);
- if (!ret)
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
- else
- PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
-
- return ret;
+ PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
}
/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
@@ -321,28 +299,28 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
u8 value;
/* Fast serial bus data control disable */
- ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
-
- ret += w9968cf_smbus_start(sd);
- ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
- ret += w9968cf_smbus_read_ack(sd);
- ret += w9968cf_smbus_write_byte(sd, reg);
- ret += w9968cf_smbus_read_ack(sd);
- ret += w9968cf_smbus_stop(sd);
- ret += w9968cf_smbus_start(sd);
- ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
- ret += w9968cf_smbus_read_ack(sd);
- ret += w9968cf_smbus_read_byte(sd, &value);
+ w9968cf_write_sb(sd, 0x0013); /* don't change ! */
+
+ w9968cf_smbus_start(sd);
+ w9968cf_smbus_write_byte(sd, sd->sensor_addr);
+ w9968cf_smbus_read_ack(sd);
+ w9968cf_smbus_write_byte(sd, reg);
+ w9968cf_smbus_read_ack(sd);
+ w9968cf_smbus_stop(sd);
+ w9968cf_smbus_start(sd);
+ w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
+ w9968cf_smbus_read_ack(sd);
+ w9968cf_smbus_read_byte(sd, &value);
/* signal we don't want to read anymore, the v4l1 driver used to
send an ack here which is very wrong! (and then fixed
the issues this gave by retrying reads) */
- ret += w9968cf_smbus_write_nack(sd);
- ret += w9968cf_smbus_stop(sd);
+ w9968cf_smbus_write_nack(sd);
+ w9968cf_smbus_stop(sd);
/* Fast serial bus data control re-enable */
- ret += w9968cf_write_sb(sd, 0x0030);
+ w9968cf_write_sb(sd, 0x0030);
- if (!ret) {
+ if (sd->gspca_dev.usb_err >= 0) {
ret = value;
PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
} else
@@ -351,79 +329,68 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
return ret;
}
-
/*--------------------------------------------------------------------------
Turn on the LED on some webcams. A beep should be heard too.
Return 0 on success, a negative number otherwise.
--------------------------------------------------------------------------*/
-static int w9968cf_configure(struct sd *sd)
+static void w9968cf_configure(struct sd *sd)
{
- int ret = 0;
-
- ret += reg_w(sd, 0x00, 0xff00); /* power-down */
- ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
- ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
- ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
- ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
- ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
- ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
-
- if (ret)
- PDEBUG(D_ERR, "Couldn't turn on the LED");
+ reg_w(sd, 0x00, 0xff00); /* power-down */
+ reg_w(sd, 0x00, 0xbf17); /* reset everything */
+ reg_w(sd, 0x00, 0xbf10); /* normal operation */
+ reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
+ reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
+ reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
+ reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
sd->stopped = 1;
-
- return ret;
}
-static int w9968cf_init(struct sd *sd)
+static void w9968cf_init(struct sd *sd)
{
- int ret = 0;
unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
y0 = 0x0000,
- u0 = y0 + hw_bufsize/2,
- v0 = u0 + hw_bufsize/4,
- y1 = v0 + hw_bufsize/4,
- u1 = y1 + hw_bufsize/2,
- v1 = u1 + hw_bufsize/4;
-
- ret += reg_w(sd, 0x00, 0xff00); /* power off */
- ret += reg_w(sd, 0x00, 0xbf10); /* power on */
-
- ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
- ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
-
- ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
- ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
- ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
- ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
- ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
- ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
-
- ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
- ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
- ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
- ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
- ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
- ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
-
- ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
- ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
-
- ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
- ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
-
- ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
- ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
- ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
- ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
-
- return ret;
+ u0 = y0 + hw_bufsize / 2,
+ v0 = u0 + hw_bufsize / 4,
+ y1 = v0 + hw_bufsize / 4,
+ u1 = y1 + hw_bufsize / 2,
+ v1 = u1 + hw_bufsize / 4;
+
+ reg_w(sd, 0x00, 0xff00); /* power off */
+ reg_w(sd, 0x00, 0xbf10); /* power on */
+
+ reg_w(sd, 0x03, 0x405d); /* DRAM timings */
+ reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
+
+ reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
+ reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
+ reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
+ reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
+ reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
+ reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
+
+ reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
+ reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
+ reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
+ reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
+ reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
+ reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
+
+ reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
+ reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
+
+ reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
+ reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
+
+ reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
+ reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
+ reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
+ reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
}
-static int w9968cf_set_crop_window(struct sd *sd)
+static void w9968cf_set_crop_window(struct sd *sd)
{
- int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch,
+ int start_cropx, start_cropy, x, y, fw, fh, cw, ch,
max_width, max_height;
if (sd->sif) {
@@ -456,8 +423,8 @@ static int w9968cf_set_crop_window(struct sd *sd)
fw = SC(sd->gspca_dev.width) / max_width;
fh = SC(sd->gspca_dev.height) / max_height;
- cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
- ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
+ cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width) / fh;
+ ch = (fw >= fh) ? SC(sd->gspca_dev.height) / fw : max_height;
sd->sensor_width = max_width;
sd->sensor_height = max_height;
@@ -465,42 +432,40 @@ static int w9968cf_set_crop_window(struct sd *sd)
x = (max_width - cw) / 2;
y = (max_height - ch) / 2;
- ret += reg_w(sd, 0x10, start_cropx + x);
- ret += reg_w(sd, 0x11, start_cropy + y);
- ret += reg_w(sd, 0x12, start_cropx + x + cw);
- ret += reg_w(sd, 0x13, start_cropy + y + ch);
-
- return ret;
+ reg_w(sd, 0x10, start_cropx + x);
+ reg_w(sd, 0x11, start_cropy + y);
+ reg_w(sd, 0x12, start_cropx + x + cw);
+ reg_w(sd, 0x13, start_cropy + y + ch);
}
-static int w9968cf_mode_init_regs(struct sd *sd)
+static void w9968cf_mode_init_regs(struct sd *sd)
{
- int ret = 0, val, vs_polarity, hs_polarity;
+ int val, vs_polarity, hs_polarity;
- ret += w9968cf_set_crop_window(sd);
+ w9968cf_set_crop_window(sd);
- ret += reg_w(sd, 0x14, sd->gspca_dev.width);
- ret += reg_w(sd, 0x15, sd->gspca_dev.height);
+ reg_w(sd, 0x14, sd->gspca_dev.width);
+ reg_w(sd, 0x15, sd->gspca_dev.height);
/* JPEG width & height */
- ret += reg_w(sd, 0x30, sd->gspca_dev.width);
- ret += reg_w(sd, 0x31, sd->gspca_dev.height);
+ reg_w(sd, 0x30, sd->gspca_dev.width);
+ reg_w(sd, 0x31, sd->gspca_dev.height);
/* Y & UV frame buffer strides (in WORD) */
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) {
- ret += reg_w(sd, 0x2c, sd->gspca_dev.width/2);
- ret += reg_w(sd, 0x2d, sd->gspca_dev.width/4);
+ reg_w(sd, 0x2c, sd->gspca_dev.width / 2);
+ reg_w(sd, 0x2d, sd->gspca_dev.width / 4);
} else
- ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
+ reg_w(sd, 0x2c, sd->gspca_dev.width);
- ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
- ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
+ reg_w(sd, 0x00, 0xbf17); /* reset everything */
+ reg_w(sd, 0x00, 0xbf10); /* normal operation */
/* Transfer size in WORDS (for UYVY format only) */
val = sd->gspca_dev.width * sd->gspca_dev.height;
- ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
- ret += reg_w(sd, 0x3e, val >> 16); /* high bits */
+ reg_w(sd, 0x3d, val & 0xffff); /* low bits */
+ reg_w(sd, 0x3e, val >> 16); /* high bits */
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) {
@@ -508,7 +473,7 @@ static int w9968cf_mode_init_regs(struct sd *sd)
jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
sd->gspca_dev.width, 0x22); /* JPEG 420 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
- ret += w9968cf_upload_quantizationtables(sd);
+ w9968cf_upload_quantizationtables(sd);
}
/* Video Capture Control Register */
@@ -540,19 +505,15 @@ static int w9968cf_mode_init_regs(struct sd *sd)
val |= 0x8000; /* capt. enable */
- ret += reg_w(sd, 0x16, val);
+ reg_w(sd, 0x16, val);
sd->gspca_dev.empty_packet = 0;
-
- return ret;
}
static void w9968cf_stop0(struct sd *sd)
{
- if (sd->gspca_dev.present) {
- reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
- reg_w(sd, 0x16, 0x0000); /* stop video capture */
- }
+ reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
+ reg_w(sd, 0x16, 0x0000); /* stop video capture */
}
/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c
index 8715577bc2d8..5b5039a02031 100644
--- a/drivers/media/video/gspca/xirlink_cit.c
+++ b/drivers/media/video/gspca/xirlink_cit.c
@@ -29,6 +29,7 @@
#define MODULE_NAME "xirlink-cit"
+#include <linux/input.h>
#include "gspca.h"
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
@@ -58,6 +59,7 @@ struct sd {
#define CIT_MODEL4 4
#define CIT_IBM_NETCAM_PRO 5
u8 input_index;
+ u8 button_state;
u8 stop_on_control_change;
u8 sof_read;
u8 sof_len;
@@ -185,60 +187,60 @@ static const struct ctrl sd_ctrls[] = {
static const struct v4l2_pix_format cif_yuv_mode[] = {
{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
+ .sizeimage = 176 * 144 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 352,
- .sizeimage = 352 * 288 * 3 / 2,
+ .sizeimage = 352 * 288 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
static const struct v4l2_pix_format vga_yuv_mode[] = {
{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
+ .sizeimage = 160 * 120 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
+ .sizeimage = 320 * 240 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 2,
+ .sizeimage = 640 * 480 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
static const struct v4l2_pix_format model0_mode[] = {
{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
+ .sizeimage = 160 * 120 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
+ .sizeimage = 176 * 144 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 2,
+ .sizeimage = 320 * 240 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
static const struct v4l2_pix_format model2_mode[] = {
{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 160,
- .sizeimage = 160 * 120 * 3 / 2,
+ .sizeimage = 160 * 120 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
.bytesperline = 176,
- .sizeimage = 176 * 144 * 3 / 2,
+ .sizeimage = 176 * 144 * 3 / 2 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240,
+ .sizeimage = 320 * 240 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
.bytesperline = 352,
- .sizeimage = 352 * 288,
+ .sizeimage = 352 * 288 + 4,
.colorspace = V4L2_COLORSPACE_SRGB},
};
@@ -804,7 +806,7 @@ static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
return 0;
}
-static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index)
+static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
{
struct usb_device *udev = gspca_dev->dev;
__u8 *buf = gspca_dev->usb_buf;
@@ -819,10 +821,8 @@ static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index)
return res;
}
- PDEBUG(D_PROBE,
- "Register %04x value: %02x %02x %02x %02x %02x %02x %02x %02x",
- index,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+ if (verbose)
+ PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]);
return 0;
}
@@ -907,7 +907,7 @@ static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
cit_send_x_00_05(gspca_dev, 0x0089);
cit_send_x_00(gspca_dev, fkey);
cit_send_00_04_06(gspca_dev);
- cit_read_reg(gspca_dev, 0x0126);
+ cit_read_reg(gspca_dev, 0x0126, 0);
cit_send_FF_04_02(gspca_dev);
}
@@ -1074,12 +1074,12 @@ static int cit_init_model0(struct gspca_dev *gspca_dev)
static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
{
- cit_read_reg(gspca_dev, 0x128);
+ cit_read_reg(gspca_dev, 0x128, 1);
cit_write_reg(gspca_dev, 0x0003, 0x0133);
cit_write_reg(gspca_dev, 0x0000, 0x0117);
cit_write_reg(gspca_dev, 0x0008, 0x0123);
cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0112);
cit_write_reg(gspca_dev, 0x0000, 0x0133);
@@ -1098,7 +1098,7 @@ static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x00ff, 0x0130);
cit_write_reg(gspca_dev, 0xcd41, 0x0124);
cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_read_reg(gspca_dev, 0x0126);
+ cit_read_reg(gspca_dev, 0x0126, 1);
cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
@@ -1557,18 +1557,20 @@ static int cit_restart_stream(struct gspca_dev *gspca_dev)
switch (sd->model) {
case CIT_MODEL0:
case CIT_MODEL1:
- case CIT_MODEL3:
- case CIT_IBM_NETCAM_PRO:
cit_write_reg(gspca_dev, 0x0001, 0x0114);
/* Fall through */
case CIT_MODEL2:
case CIT_MODEL4:
cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- /* This happens repeatedly while streaming with the ibm netcam
- pro and the ibmcam driver did it for model3 after changing
- settings, but it does not seem to have any effect. */
- /* cit_write_reg(gspca_dev, 0x0001, 0x0113); */
+ break;
+ case CIT_MODEL3:
+ case CIT_IBM_NETCAM_PRO:
+ cit_write_reg(gspca_dev, 0x0001, 0x0114);
+ cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
+ /* Clear button events from while we were not streaming */
+ cit_write_reg(gspca_dev, 0x0001, 0x0113);
break;
}
@@ -1680,23 +1682,23 @@ static int cit_start_model1(struct gspca_dev *gspca_dev)
if (clock_div < 0)
return clock_div;
- cit_read_reg(gspca_dev, 0x0128);
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0128, 1);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
cit_write_reg(gspca_dev, 0x01, 0x0108);
cit_write_reg(gspca_dev, 0x03, 0x0112);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x06, 0x0115);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x44, 0x0116);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x40, 0x0116);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x0e, 0x0115);
cit_write_reg(gspca_dev, 0x19, 0x012c);
@@ -1878,7 +1880,7 @@ static int cit_start_model2(struct gspca_dev *gspca_dev)
int clock_div = 0;
cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0112);
cit_write_reg(gspca_dev, 0x00bc, 0x012c);
@@ -2070,10 +2072,10 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
/* HDG not in ibmcam driver, added to see if it helps with
auto-detecting between model3 and ibm netcamera pro */
- cit_read_reg(gspca_dev, 0x128);
+ cit_read_reg(gspca_dev, 0x128, 1);
cit_write_reg(gspca_dev, 0x0000, 0x0100);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0112);
cit_write_reg(gspca_dev, 0x0000, 0x0123);
@@ -2083,7 +2085,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x0060, 0x0116);
cit_write_reg(gspca_dev, 0x0002, 0x0115);
cit_write_reg(gspca_dev, 0x0003, 0x0115);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x000b, 0x0115);
/* TESTME HDG not in ibmcam driver, added to see if it helps with
@@ -2096,7 +2098,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
cit_write_reg(gspca_dev, 0x00ff, 0x0130);
cit_write_reg(gspca_dev, 0xcd41, 0x0124);
cit_write_reg(gspca_dev, 0xfffa, 0x0124);
- cit_read_reg(gspca_dev, 0x0126);
+ cit_read_reg(gspca_dev, 0x0126, 1);
}
cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
@@ -2293,7 +2295,7 @@ static int cit_start_model3(struct gspca_dev *gspca_dev)
if (rca_input) {
for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
if (rca_initdata[i][0])
- cit_read_reg(gspca_dev, rca_initdata[i][2]);
+ cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
else
cit_write_reg(gspca_dev, rca_initdata[i][1],
rca_initdata[i][2]);
@@ -2712,7 +2714,7 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
if (rca_input) {
for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
if (rca_initdata[i][0])
- cit_read_reg(gspca_dev, rca_initdata[i][2]);
+ cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
else
cit_write_reg(gspca_dev, rca_initdata[i][1],
rca_initdata[i][2]);
@@ -2769,16 +2771,55 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
+static int sd_isoc_init(struct gspca_dev *gspca_dev)
+{
+ struct usb_host_interface *alt;
+ int max_packet_size;
+
+ switch (gspca_dev->width) {
+ case 160:
+ max_packet_size = 450;
+ break;
+ case 176:
+ max_packet_size = 600;
+ break;
+ default:
+ max_packet_size = 1022;
+ break;
+ }
+
+ /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
+ alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
+ alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
+
+ return 0;
+}
+
static int sd_isoc_nego(struct gspca_dev *gspca_dev)
{
- int ret, packet_size;
+ int ret, packet_size, min_packet_size;
struct usb_host_interface *alt;
+ switch (gspca_dev->width) {
+ case 160:
+ min_packet_size = 200;
+ break;
+ case 176:
+ min_packet_size = 266;
+ break;
+ default:
+ min_packet_size = 400;
+ break;
+ }
+
alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- packet_size -= 100;
- if (packet_size < 300)
+ if (packet_size <= min_packet_size)
return -EIO;
+
+ packet_size -= 100;
+ if (packet_size < min_packet_size)
+ packet_size = min_packet_size;
alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
@@ -2796,15 +2837,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct usb_host_interface *alt;
/* We cannot use gspca_dev->present here as that is not set when
sd_init gets called and we get called from sd_init */
if (!gspca_dev->dev)
return;
- alt = &gspca_dev->dev->config->intf_cache[0]->altsetting[1];
-
switch (sd->model) {
case CIT_MODEL0:
/* HDG windows does this, but it causes the cams autogain to
@@ -2815,7 +2853,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
break;
case CIT_MODEL1:
cit_send_FF_04_02(gspca_dev);
- cit_read_reg(gspca_dev, 0x0100);
+ cit_read_reg(gspca_dev, 0x0100, 0);
cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
break;
case CIT_MODEL2:
@@ -2834,9 +2872,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
case CIT_MODEL3:
cit_write_reg(gspca_dev, 0x0006, 0x012c);
cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
- cit_read_reg(gspca_dev, 0x0116);
+ cit_read_reg(gspca_dev, 0x0116, 0);
cit_write_reg(gspca_dev, 0x0064, 0x0116);
- cit_read_reg(gspca_dev, 0x0115);
+ cit_read_reg(gspca_dev, 0x0115, 0);
cit_write_reg(gspca_dev, 0x0003, 0x0115);
cit_write_reg(gspca_dev, 0x0008, 0x0123);
cit_write_reg(gspca_dev, 0x0000, 0x0117);
@@ -2859,12 +2897,17 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
restarting the stream after this */
/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
cit_write_reg(gspca_dev, 0x00c0, 0x0100);
-
- /* Start isoc bandwidth "negotiation" at max isoc bandwith
- next stream start */
- alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(1022);
break;
}
+
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ /* If the last button state is pressed, release it now! */
+ if (sd->button_state) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
+ input_sync(gspca_dev->input_dev);
+ sd->button_state = 0;
+ }
+#endif
}
static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
@@ -3158,6 +3201,38 @@ static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+static void cit_check_button(struct gspca_dev *gspca_dev)
+{
+ int new_button_state;
+ struct sd *sd = (struct sd *)gspca_dev;
+
+ switch (sd->model) {
+ case CIT_MODEL3:
+ case CIT_IBM_NETCAM_PRO:
+ break;
+ default: /* TEST ME unknown if this works on other models too */
+ return;
+ }
+
+ /* Read the button state */
+ cit_read_reg(gspca_dev, 0x0113, 0);
+ new_button_state = !gspca_dev->usb_buf[0];
+
+ /* Tell the cam we've seen the button press, notice that this
+ is a nop (iow the cam keeps reporting pressed) until the
+ button is actually released. */
+ if (new_button_state)
+ cit_write_reg(gspca_dev, 0x01, 0x0113);
+
+ if (sd->button_state != new_button_state) {
+ input_report_key(gspca_dev->input_dev, KEY_CAMERA,
+ new_button_state);
+ input_sync(gspca_dev->input_dev);
+ sd->button_state = new_button_state;
+ }
+}
+#endif
/* sub-driver description */
static const struct sd_desc sd_desc = {
@@ -3170,6 +3245,10 @@ static const struct sd_desc sd_desc = {
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ .dq_callback = cit_check_button,
+ .other_input = 1,
+#endif
};
static const struct sd_desc sd_desc_isoc_nego = {
@@ -3179,10 +3258,15 @@ static const struct sd_desc sd_desc_isoc_nego = {
.config = sd_config,
.init = sd_init,
.start = sd_start,
+ .isoc_init = sd_isoc_init,
.isoc_nego = sd_isoc_nego,
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ .dq_callback = cit_check_button,
+ .other_input = 1,
+#endif
};
/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index c7e1970ca284..042dc808593f 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -4499,7 +4499,7 @@ static const struct usb_action mt9v111_3_Initial[] = {
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index 27b5dfdfbb93..1a1169115716 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -467,7 +467,6 @@ static int imx074_remove(struct i2c_client *client)
icd->ops = NULL;
if (icl->free_bus)
icl->free_bus(icl);
- client->driver = NULL;
kfree(priv);
return 0;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index ce4a75375909..dd54c3dae054 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -46,7 +46,7 @@
#include <linux/i2c.h>
#include <linux/workqueue.h>
-#include <media/ir-core.h>
+#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
/* ----------------------------------------------------------------------- */
@@ -252,7 +252,7 @@ static void ir_key_poll(struct IR_i2c *ir)
}
if (rc)
- ir_keydown(ir->input, ir_key, 0);
+ rc_keydown(ir->rc, ir_key, 0);
}
static void ir_work(struct work_struct *work)
@@ -269,22 +269,18 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
char *ir_codes = NULL;
const char *name = NULL;
- u64 ir_type = 0;
+ u64 rc_type = RC_TYPE_UNKNOWN;
struct IR_i2c *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc = NULL;
struct i2c_adapter *adap = client->adapter;
unsigned short addr = client->addr;
int err;
- ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
- err = -ENOMEM;
- goto err_out_free;
- }
+ ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+ if (!ir)
+ return -ENOMEM;
ir->c = client;
- ir->input = input_dev;
ir->polling_interval = DEFAULT_POLLING_INTERVAL;
i2c_set_clientdata(client, ir);
@@ -292,7 +288,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x64:
name = "Pixelview";
ir->get_key = get_key_pixelview;
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_EMPTY;
break;
case 0x18:
@@ -300,7 +296,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x1a:
name = "Hauppauge";
ir->get_key = get_key_haup;
- ir_type = IR_TYPE_RC5;
+ rc_type = RC_TYPE_RC5;
if (hauppauge == 1) {
ir_codes = RC_MAP_HAUPPAUGE_NEW;
} else {
@@ -310,19 +306,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x30:
name = "KNC One";
ir->get_key = get_key_knc1;
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_EMPTY;
break;
case 0x6b:
name = "FusionHDTV";
ir->get_key = get_key_fusionhdtv;
- ir_type = IR_TYPE_RC5;
+ rc_type = RC_TYPE_RC5;
ir_codes = RC_MAP_FUSIONHDTV_MCE;
break;
case 0x40:
name = "AVerMedia Cardbus remote";
ir->get_key = get_key_avermedia_cardbus;
- ir_type = IR_TYPE_OTHER;
+ rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
break;
}
@@ -333,9 +329,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
client->dev.platform_data;
ir_codes = init_data->ir_codes;
+ rc = init_data->rc_dev;
+
name = init_data->name;
if (init_data->type)
- ir_type = init_data->type;
+ rc_type = init_data->type;
if (init_data->polling_interval)
ir->polling_interval = init_data->polling_interval;
@@ -366,8 +364,21 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
+ if (!rc) {
+ /*
+ * If platform_data doesn't specify rc_dev, initilize it
+ * internally
+ */
+ rc = rc_allocate_device();
+ if (!rc) {
+ err = -ENOMEM;
+ goto err_out_free;
+ }
+ }
+ ir->rc = rc;
+
/* Make sure we are all setup before going on */
- if (!name || !ir->get_key || !ir_type || !ir_codes) {
+ if (!name || !ir->get_key || !rc_type || !ir_codes) {
dprintk(1, ": Unsupported device at address 0x%02x\n",
addr);
err = -ENODEV;
@@ -382,18 +393,28 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_name(&adap->dev),
dev_name(&client->dev));
- /* init + register input device */
- ir->ir_type = ir_type;
- input_dev->id.bustype = BUS_I2C;
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
+ /*
+ * Initialize input_dev fields
+ * It doesn't make sense to allow overriding them via platform_data
+ */
+ rc->input_id.bustype = BUS_I2C;
+ rc->input_phys = ir->phys;
+ rc->input_name = ir->name;
+
+ /*
+ * Initialize the other fields of rc_dev
+ */
+ rc->map_name = ir->ir_codes;
+ rc->allowed_protos = rc_type;
+ if (!rc->driver_name)
+ rc->driver_name = MODULE_NAME;
- err = ir_input_register(ir->input, ir->ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_free;
printk(MODULE_NAME ": %s detected at %s [%s]\n",
- ir->input->name, ir->input->phys, adap->name);
+ ir->name, ir->phys, adap->name);
/* start polling via eventd */
INIT_DELAYED_WORK(&ir->work, ir_work);
@@ -402,6 +423,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
return 0;
err_out_free:
+ /* Only frees rc if it were allocated internally */
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -414,7 +437,7 @@ static int ir_remove(struct i2c_client *client)
cancel_delayed_work_sync(&ir->work);
/* unregister device */
- ir_input_unregister(ir->input);
+ rc_unregister_device(ir->rc);
/* free memory */
kfree(ir);
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index be4af1fa557e..89f65914cc8e 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -1,9 +1,8 @@
config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
depends on VIDEO_V4L2 && PCI && I2C
- depends on INPUT # due to VIDEO_IR
select I2C_ALGOBIT
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 665191c9b407..68170924448c 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -172,7 +172,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
init_data->internal_get_key_func =
IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
- init_data->type = IR_TYPE_OTHER;
+ init_data->type = RC_TYPE_OTHER;
init_data->name = "AVerMedia AVerTV card";
break;
case IVTV_HW_I2C_IR_RX_HAUP_EXT:
@@ -180,14 +180,14 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
/* Default to old black remote */
init_data->ir_codes = RC_MAP_RC5_TV;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = IR_TYPE_RC5;
+ init_data->type = RC_TYPE_RC5;
init_data->name = itv->card_name;
break;
case IVTV_HW_Z8F0811_IR_RX_HAUP:
/* Default to grey remote */
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = IR_TYPE_RC5;
+ init_data->type = RC_TYPE_RC5;
init_data->name = itv->card_name;
break;
}
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 2be23bccd3c8..48d2c2419c13 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = {
.open = meye_open,
.release = meye_release,
.mmap = meye_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.poll = meye_poll,
};
@@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
msleep(1);
mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
- if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
- video_nr) < 0) {
- v4l2_err(v4l2_dev, "video_register_device failed\n");
- goto outvideoreg;
- }
-
mutex_init(&meye.lock);
init_waitqueue_head(&meye.proc_list);
meye.brightness = 32 << 10;
@@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
+ if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
+ video_nr) < 0) {
+ v4l2_err(v4l2_dev, "video_register_device failed\n");
+ goto outvideoreg;
+ }
+
v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n",
MEYE_DRIVER_VERSION);
v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n",
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index fcb4cd941853..f7fc88d240e6 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -798,7 +798,6 @@ static int mt9m001_remove(struct i2c_client *client)
icd->ops = NULL;
mt9m001_video_remove(icd);
- client->driver = NULL;
kfree(mt9m001);
return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 525a16e73285..53fa2a7bf156 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -1092,7 +1092,6 @@ static int mt9m111_remove(struct i2c_client *client)
struct soc_camera_device *icd = client->dev.platform_data;
icd->ops = NULL;
- client->driver = NULL;
kfree(mt9m111);
return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 9bd44a816ea1..7ce279c3751d 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -896,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client)
if (icd)
icd->ops = NULL;
- client->driver = NULL;
kfree(mt9t031);
return 0;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index b96171cc79f9..6a784c87e5ff 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -930,7 +930,6 @@ static int mt9v022_remove(struct i2c_client *client)
icd->ops = NULL;
mt9v022_video_remove(icd);
- client->driver = NULL;
kfree(mt9v022);
return 0;
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 072bd2d1cfad..13565cba237d 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
csicr1 |= CSICR1_REDGE;
- if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
- csicr1 |= CSICR1_INV_PCLK;
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_SOF_POL;
if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index aa871c2936b3..330d42e15498 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -1186,13 +1186,12 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
goto egetres;
}
- mx3_cam = vmalloc(sizeof(*mx3_cam));
+ mx3_cam = vzalloc(sizeof(*mx3_cam));
if (!mx3_cam) {
dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
err = -ENOMEM;
goto ealloc;
}
- memset(mx3_cam, 0, sizeof(*mx3_cam));
mx3_cam->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(mx3_cam->clk)) {
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 7129b50757db..7551907f8c28 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf,
static const struct v4l2_file_operations pms_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = pms_read,
};
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 6b8fbddc0747..1593f8deb810 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -1386,11 +1386,16 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
{
ARG_DEF(int, qual)
+ if (pdev->iso_init) {
+ ret = -EBUSY;
+ break;
+ }
+
ARG_IN(qual)
if (ARGR(qual) < 0 || ARGR(qual) > 3)
ret = -EINVAL;
else
- ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
+ ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
if (ret >= 0)
pdev->vcompression = ARGR(qual);
break;
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f3dc89da4c4e..bd1519a4ecb4 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -287,14 +287,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
/* create frame buffers, and make circular ring */
for (i = 0; i < default_fbufs; i++) {
if (pdev->fbuf[i].data == NULL) {
- kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
+ kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
if (kbuf == NULL) {
PWC_ERROR("Failed to allocate frame buffer %d.\n", i);
return -ENOMEM;
}
PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf);
pdev->fbuf[i].data = kbuf;
- memset(kbuf, 0, PWC_FRAME_SIZE);
}
}
@@ -899,10 +898,13 @@ int pwc_isoc_init(struct pwc_device *pdev)
/* link */
for (i = 0; i < MAX_ISO_BUFS; i++) {
ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
- if (ret)
+ if (ret) {
PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
- else
- PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
+ pdev->iso_init = 1;
+ pwc_isoc_cleanup(pdev);
+ return ret;
+ }
+ PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
}
/* All is done... */
@@ -958,7 +960,7 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
/* Stop camera, but only if we are sure the camera is still there (unplug
is signalled by EPIPE)
*/
- if (pdev->error_status && pdev->error_status != EPIPE) {
+ if (pdev->error_status != EPIPE) {
PWC_DEBUG_OPEN("Setting alternate interface 0.\n");
usb_set_interface(pdev->udev, 0, 0);
}
@@ -967,36 +969,6 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
}
-int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
-{
- int ret, start;
-
- /* Stop isoc stuff */
- pwc_isoc_cleanup(pdev);
- /* Reset parameters */
- pwc_reset_buffers(pdev);
- /* Try to set video mode... */
- start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
- if (ret) {
- PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n");
- /* That failed... restore old mode (we know that worked) */
- start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
- if (start) {
- PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n");
- }
- }
- if (start == 0)
- {
- if (pwc_isoc_init(pdev) < 0)
- {
- PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
- ret = -EAGAIN; /* let's try again, who knows if it works a second time */
- }
- }
- pdev->drop_frames++; /* try to avoid garbage during switch */
- return ret; /* Return original error code */
-}
-
/*********
* sysfs
*********/
@@ -1176,7 +1148,7 @@ static int pwc_video_open(struct file *file)
/* Set some defaults */
pdev->vsnapshot = 0;
- /* Start iso pipe for video; first try the last used video size
+ /* Set video size, first try the last used video size
(or the default one); if that fails try QCIF/10 or QSIF/10;
it that fails too, give up.
*/
@@ -1203,15 +1175,6 @@ static int pwc_video_open(struct file *file)
return i;
}
- i = pwc_isoc_init(pdev);
- if (i) {
- PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i);
- pwc_isoc_cleanup(pdev);
- pwc_free_buffers(pdev);
- mutex_unlock(&pdev->modlock);
- return i;
- }
-
/* Initialize the webcam to sane value */
pwc_set_brightness(pdev, 0x7fff);
pwc_set_agc(pdev, 1, 0);
@@ -1326,6 +1289,11 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
goto err_out;
}
+ /* Start the stream (if not already started) */
+ rv = pwc_isoc_init(pdev);
+ if (rv)
+ goto err_out;
+
/* In case we're doing partial reads, we don't have to wait for a frame */
if (pdev->image_read_pos == 0) {
/* Do wait queueing according to the (doc)book */
@@ -1395,6 +1363,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
{
struct video_device *vdev = file->private_data;
struct pwc_device *pdev;
+ int ret;
if (vdev == NULL)
return -EFAULT;
@@ -1402,6 +1371,13 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
if (pdev == NULL)
return -EFAULT;
+ /* Start the stream (if not already started) */
+ mutex_lock(&pdev->modlock);
+ ret = pwc_isoc_init(pdev);
+ mutex_unlock(&pdev->modlock);
+ if (ret)
+ return ret;
+
poll_wait(file, &pdev->frameq, wait);
if (pdev->error_status)
return POLLERR;
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 7061a03f5cf1..2ef1668638f9 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -309,7 +309,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
pixelformat != V4L2_PIX_FMT_PWC2)
return -EINVAL;
- PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d "
+ if (pdev->iso_init)
+ return -EBUSY;
+
+ PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
"compression=%d snapshot=%d format=%c%c%c%c\n",
f->fmt.pix.width, f->fmt.pix.height, fps,
compression, snapshot,
@@ -318,14 +321,14 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
(pixelformat>>16)&255,
(pixelformat>>24)&255);
- ret = pwc_try_video_mode(pdev,
+ ret = pwc_set_video_mode(pdev,
f->fmt.pix.width,
f->fmt.pix.height,
fps,
compression,
snapshot);
- PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret);
+ PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
if (ret)
return ret;
@@ -882,9 +885,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_STREAMON:
{
- /* WARNING: pwc_try_video_mode() called pwc_isoc_init */
- pwc_isoc_init(pdev);
- return 0;
+ return pwc_isoc_init(pdev);
}
case VIDIOC_STREAMOFF:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 36a9c83b5f5d..16bbc6df9b07 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -275,7 +275,6 @@ extern int pwc_trace;
extern int pwc_mbufs;
/** functions in pwc-if.c */
-int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
int pwc_handle_frame(struct pwc_device *pdev);
void pwc_next_image(struct pwc_device *pdev);
int pwc_isoc_init(struct pwc_device *pdev);
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index d2fa2d43ff19..57e11b6f19fb 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -1460,7 +1460,6 @@ static int rj54n1_remove(struct i2c_client *client)
icd->ops = NULL;
if (icl->free_bus)
icl->free_bus(icl);
- client->driver = NULL;
kfree(rj54n1);
return 0;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 2e7c547894b6..91fc213f97b6 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -543,7 +543,7 @@ static void fimc_dma_run(void *priv)
unsigned long flags;
u32 ret;
- if (WARN(!ctx, "null hardware context"))
+ if (WARN(!ctx, "null hardware context\n"))
return;
fimc = ctx->fimc_dev;
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 3fe71be41a1f..380f1b28cfcc 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -26,7 +26,7 @@ config VIDEO_SAA7134_ALSA
config VIDEO_SAA7134_RC
bool "Philips SAA7134 Remote Controller support"
- depends on VIDEO_IR
+ depends on RC_CORE
depends on VIDEO_SAA7134
default y
---help---
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 1d4d0a49ea52..ff23e6ebdde4 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5176,6 +5176,58 @@ struct saa7134_board saa7134_boards[] = {
.amux = 2,
},
},
+ [SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = {
+ .name = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid",
+ .audio_clock = 0x00187de7,
+#if 0
+ /*
+ * FIXME: Analog mode doesn't work, if digital is enabled. The proper
+ * fix is to use tda8290 driver, but Kworld seems to use an
+ * unsupported version of tda8295.
+ */
+ .tuner_type = TUNER_NXP_TDA18271, /* TUNER_PHILIPS_TDA8290 */
+ .tuner_addr = 0x60,
+#else
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+#endif
+ .radio_type = UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 0x8e054000,
+ .mpeg = SAA7134_MPEG_DVB,
+ .ts_type = SAA7134_MPEG_TS_PARALLEL,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+#if 0 /* FIXME */
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x200,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ .gpio = 0x200,
+#endif
+ } },
+#if 0
+ .radio = {
+ .name = name_radio,
+ .vmux = 1,
+ .amux = LINE1,
+ .gpio = 0x100,
+ },
+#endif
+ .mute = {
+ .name = name_mute,
+ .vmux = 0,
+ .amux = TV,
+ },
+ },
[SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS] = {
.name = "Avermedia AVerTV GO 007 FM Plus",
.audio_clock = 0x00187de7,
@@ -6615,6 +6667,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
}, {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x17de,
+ .subdevice = 0xb136,
+ .driver_data = SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1461, /* Avermedia Technologies Inc */
.subdevice = 0xf31d,
.driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
@@ -6831,6 +6889,23 @@ static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev,
return 0;
}
+static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev,
+ enum tda18271_mode mode)
+{
+ /* toggle AGC switch through GPIO 27 */
+ switch (mode) {
+ case TDA18271_ANALOG:
+ saa7134_set_gpio(dev, 27, 0);
+ break;
+ case TDA18271_DIGITAL:
+ saa7134_set_gpio(dev, 27, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
int command, int arg)
{
@@ -6843,6 +6918,9 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
case SAA7134_BOARD_HAUPPAUGE_HVR1120:
ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
break;
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+ ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg);
+ break;
default:
break;
}
@@ -6863,6 +6941,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
case SAA7134_BOARD_HAUPPAUGE_HVR1150:
case SAA7134_BOARD_HAUPPAUGE_HVR1120:
case SAA7134_BOARD_AVERMEDIA_M733A:
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
/* tda8290 + tda18271 */
ret = saa7134_tda8290_18271_callback(dev, command, arg);
break;
@@ -7541,6 +7620,37 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name);
break;
}
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+ {
+ struct i2c_msg msg = { .addr = 0x4b, .flags = 0 };
+ int i;
+ static u8 buffer[][2] = {
+ {0x30, 0x31},
+ {0xff, 0x00},
+ {0x41, 0x03},
+ {0x41, 0x1a},
+ {0xff, 0x02},
+ {0x34, 0x00},
+ {0x45, 0x97},
+ {0x45, 0xc1},
+ };
+ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
+ saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
+
+ /*
+ * FIXME: identify what device is at addr 0x4b and what means
+ * this initialization
+ */
+ for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+ msg.buf = &buffer[i][0];
+ msg.len = ARRAY_SIZE(buffer[0]);
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ printk(KERN_WARNING
+ "%s: Unable to enable tuner(%i).\n",
+ dev->name, i);
+ }
+ break;
+ }
} /* switch() */
/* initialize tuner */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index beb95e21d109..3315a48a848b 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -52,6 +52,7 @@
#include "tda18271.h"
#include "lgdt3305.h"
#include "tda8290.h"
+#include "mb86a20s.h"
#include "zl10353.h"
@@ -228,6 +229,20 @@ static struct mt352_config avermedia_xc3028_mt352_dev = {
.demod_init = mt352_avermedia_xc3028_init,
};
+static struct tda18271_std_map mb86a20s_tda18271_std_map = {
+ .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+ .if_lvl = 7, .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config kworld_tda18271_config = {
+ .std_map = &mb86a20s_tda18271_std_map,
+ .gate = TDA18271_GATE_DIGITAL,
+};
+
+static const struct mb86a20s_config kworld_mb86a20s_config = {
+ .demod_address = 0x10,
+};
+
/* ==================================================================
* tda1004x based DVB-T cards, helper functions
*/
@@ -608,6 +623,37 @@ static struct tda827x_config tda827x_cfg_2_sw42 = {
/* ------------------------------------------------------------------ */
+static int __kworld_sbtvd_i2c_gate_ctrl(struct saa7134_dev *dev, int enable)
+{
+ unsigned char initmsg[] = {0x45, 0x97};
+ unsigned char msg_enable[] = {0x45, 0xc1};
+ unsigned char msg_disable[] = {0x45, 0x81};
+ struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2};
+
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
+ wprintk("could not access the I2C gate\n");
+ return -EIO;
+ }
+ if (enable)
+ msg.buf = msg_enable;
+ else
+ msg.buf = msg_disable;
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
+ wprintk("could not access the I2C gate\n");
+ return -EIO;
+ }
+ msleep(20);
+ return 0;
+}
+static int kworld_sbtvd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+
+ return __kworld_sbtvd_i2c_gate_ctrl(dev, enable);
+}
+
+/* ------------------------------------------------------------------ */
+
static struct tda1004x_config tda827x_lifeview_config = {
.demod_address = 0x08,
.invert = 1,
@@ -1613,6 +1659,29 @@ static int dvb_init(struct saa7134_dev *dev)
&dtv1000s_tda18271_config);
}
break;
+ case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+ __kworld_sbtvd_i2c_gate_ctrl(dev, 0);
+ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000);
+ saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000);
+ msleep(20);
+ saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000);
+ saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000);
+ msleep(20);
+ fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
+ &kworld_mb86a20s_config,
+ &dev->i2c_adap);
+ __kworld_sbtvd_i2c_gate_ctrl(dev, 1);
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_adap,
+ &kworld_tda18271_config);
+ /*
+ * Only after success, it can initialize the gate, otherwise
+ * an OOPS will hit, due to kfree(fe0->dvb.frontend)
+ */
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_i2c_gate_ctrl;
+ }
+ break;
default:
wprintk("Huh? unknown DVB card?\n");
break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 46d31dfca7a3..98678d941847 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/slab.h>
#include "saa7134-reg.h"
@@ -42,41 +41,19 @@ static int pinnacle_remote;
module_param(pinnacle_remote, int, 0644); /* Choose Pinnacle PCTV remote */
MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=grey (defaults to 0)");
-static int ir_rc5_remote_gap = 885;
-module_param(ir_rc5_remote_gap, int, 0644);
-static int ir_rc5_key_timeout = 115;
-module_param(ir_rc5_key_timeout, int, 0644);
-
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-MODULE_PARM_DESC(repeat_delay, "delay before key repeat started");
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
-MODULE_PARM_DESC(repeat_period, "repeat period between "
- "keypresses when key is down");
-
-static unsigned int disable_other_ir;
-module_param(disable_other_ir, int, 0644);
-MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
- "alternative remotes from other manufacturers");
-
#define dprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
#define i2cdprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
-/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
-static int saa7134_rc5_irq(struct saa7134_dev *dev);
-static int saa7134_nec_irq(struct saa7134_dev *dev);
+/* Helper function for raw decoding at GPIO16 or GPIO18 */
static int saa7134_raw_decode_irq(struct saa7134_dev *dev);
-static void nec_task(unsigned long data);
-static void saa7134_nec_timer(unsigned long data);
/* -------------------- GPIO generic keycode builder -------------------- */
static int build_key(struct saa7134_dev *dev)
{
- struct card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = dev->remote;
u32 gpio, data;
/* here comes the additional handshake steps for some cards */
@@ -104,25 +81,25 @@ static int build_key(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
if (data == ir->mask_keycode)
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
else
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
return 0;
}
if (ir->polling) {
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(ir->dev, &ir->ir, data);
+ rc_keydown_notimeout(ir->dev, data, 0);
} else {
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keyup(ir->dev);
}
}
else { /* IRQ driven mode - handle key press and release in one go */
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- ir_input_keydown(ir->dev, &ir->ir, data);
- ir_input_nokey(ir->dev, &ir->ir);
+ rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keyup(ir->dev);
}
}
@@ -300,22 +277,12 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
i2cdprintk("read error\n");
return -EIO;
}
- /* IR of this card normally decode signals NEC-standard from
- * - Sven IHOO MT 5.1R remote. xxyye718
- * - Sven DVD HD-10xx remote. xxyyf708
- * - BBK ...
- * - mayby others
- * So, skip not our, if disable full codes mode.
- */
- if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir)
- return 0;
- /* Wrong data decode fix */
if (data[9] != (unsigned char)(~data[8]))
return 0;
- *ir_key = data[9];
- *ir_raw = data[9];
+ *ir_raw = ((data[10] << 16) | (data[11] << 8) | (data[9] << 0));
+ *ir_key = *ir_raw;
return 1;
}
@@ -400,7 +367,7 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
void saa7134_input_irq(struct saa7134_dev *dev)
{
- struct card_ir *ir;
+ struct saa7134_card_ir *ir;
if (!dev || !dev->remote)
return;
@@ -409,12 +376,8 @@ void saa7134_input_irq(struct saa7134_dev *dev)
if (!ir->running)
return;
- if (ir->nec_gpio) {
- saa7134_nec_irq(dev);
- } else if (!ir->polling && !ir->rc5_gpio && !ir->raw_decode) {
+ if (!ir->polling && !ir->raw_decode) {
build_key(dev);
- } else if (ir->rc5_gpio) {
- saa7134_rc5_irq(dev);
} else if (ir->raw_decode) {
saa7134_raw_decode_irq(dev);
}
@@ -423,7 +386,7 @@ void saa7134_input_irq(struct saa7134_dev *dev)
static void saa7134_input_timer(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = dev->remote;
build_key(dev);
mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
@@ -432,57 +395,37 @@ static void saa7134_input_timer(unsigned long data)
static void ir_raw_decode_timer_end(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = dev->remote;
ir_raw_event_handle(dev->remote->dev);
- ir->active = 0;
+ ir->active = false;
}
static int __saa7134_ir_start(void *priv)
{
struct saa7134_dev *dev = priv;
- struct card_ir *ir;
+ struct saa7134_card_ir *ir;
- if (!dev)
+ if (!dev || !dev->remote)
return -EINVAL;
ir = dev->remote;
- if (!ir)
- return -EINVAL;
-
if (ir->running)
return 0;
- ir->running = 1;
+ ir->running = true;
+ ir->active = false;
+
if (ir->polling) {
setup_timer(&ir->timer, saa7134_input_timer,
(unsigned long)dev);
- ir->timer.expires = jiffies + HZ;
+ ir->timer.expires = jiffies + HZ;
add_timer(&ir->timer);
- } else if (ir->rc5_gpio) {
- /* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_rc5_timer_end;
- ir->timer_end.data = (unsigned long)ir;
- init_timer(&ir->timer_keyup);
- ir->timer_keyup.function = ir_rc5_timer_keyup;
- ir->timer_keyup.data = (unsigned long)ir;
- ir->shift_by = 2;
- ir->start = 0x2;
- ir->addr = 0x17;
- ir->rc5_key_timeout = ir_rc5_key_timeout;
- ir->rc5_remote_gap = ir_rc5_remote_gap;
- } else if (ir->nec_gpio) {
- setup_timer(&ir->timer_keyup, saa7134_nec_timer,
- (unsigned long)dev);
- tasklet_init(&ir->tlet, nec_task, (unsigned long)dev);
} else if (ir->raw_decode) {
/* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_raw_decode_timer_end;
- ir->timer_end.data = (unsigned long)dev;
- ir->active = 0;
+ setup_timer(&ir->timer, ir_raw_decode_timer_end,
+ (unsigned long)dev);
}
return 0;
@@ -491,29 +434,20 @@ static int __saa7134_ir_start(void *priv)
static void __saa7134_ir_stop(void *priv)
{
struct saa7134_dev *dev = priv;
- struct card_ir *ir;
+ struct saa7134_card_ir *ir;
- if (!dev)
+ if (!dev || !dev->remote)
return;
ir = dev->remote;
- if (!ir)
- return;
-
if (!ir->running)
return;
- if (dev->remote->polling)
- del_timer_sync(&dev->remote->timer);
- else if (ir->rc5_gpio)
- del_timer_sync(&ir->timer_end);
- else if (ir->nec_gpio)
- tasklet_kill(&ir->tlet);
- else if (ir->raw_decode) {
- del_timer_sync(&ir->timer_end);
- ir->active = 0;
- }
- ir->running = 0;
+ if (ir->polling || ir->raw_decode)
+ del_timer_sync(&ir->timer);
+
+ ir->active = false;
+ ir->running = false;
return;
}
@@ -532,71 +466,33 @@ void saa7134_ir_stop(struct saa7134_dev *dev)
__saa7134_ir_stop(dev);
}
-static int saa7134_ir_open(void *priv)
+static int saa7134_ir_open(struct rc_dev *rc)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
dev->remote->users++;
return __saa7134_ir_start(dev);
}
-static void saa7134_ir_close(void *priv)
+static void saa7134_ir_close(struct rc_dev *rc)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
dev->remote->users--;
if (!dev->remote->users)
__saa7134_ir_stop(dev);
}
-
-static int saa7134_ir_change_protocol(void *priv, u64 ir_type)
-{
- struct saa7134_dev *dev = priv;
- struct card_ir *ir = dev->remote;
- u32 nec_gpio, rc5_gpio;
-
- if (ir_type == IR_TYPE_RC5) {
- dprintk("Changing protocol to RC5\n");
- nec_gpio = 0;
- rc5_gpio = 1;
- } else if (ir_type == IR_TYPE_NEC) {
- dprintk("Changing protocol to NEC\n");
- nec_gpio = 1;
- rc5_gpio = 0;
- } else {
- dprintk("IR protocol type %ud is not supported\n",
- (unsigned)ir_type);
- return -EINVAL;
- }
-
- if (ir->running) {
- saa7134_ir_stop(dev);
- ir->nec_gpio = nec_gpio;
- ir->rc5_gpio = rc5_gpio;
- saa7134_ir_start(dev);
- } else {
- ir->nec_gpio = nec_gpio;
- ir->rc5_gpio = rc5_gpio;
- }
-
- return 0;
-}
-
int saa7134_input_init1(struct saa7134_dev *dev)
{
- struct card_ir *ir;
- struct input_dev *input_dev;
+ struct saa7134_card_ir *ir;
+ struct rc_dev *rc;
char *ir_codes = NULL;
u32 mask_keycode = 0;
u32 mask_keydown = 0;
u32 mask_keyup = 0;
- int polling = 0;
- int rc5_gpio = 0;
- int nec_gpio = 0;
- int raw_decode = 0;
- int allow_protocol_change = 0;
- u64 ir_type = IR_TYPE_OTHER;
+ unsigned polling = 0;
+ bool raw_decode = false;
int err;
if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -661,14 +557,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
mask_keyup = 0x0040000;
mask_keycode = 0xffff;
- raw_decode = 1;
+ raw_decode = true;
break;
case SAA7134_BOARD_AVERMEDIA_M733A:
ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6;
mask_keydown = 0x0040000;
mask_keyup = 0x0040000;
mask_keycode = 0xffff;
- raw_decode = 1;
+ raw_decode = true;
break;
case SAA7134_BOARD_AVERMEDIA_777:
case SAA7134_BOARD_AVERMEDIA_A16AR:
@@ -775,7 +671,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
mask_keyup = 0x0040000;
mask_keycode = 0xffff;
- raw_decode = 1;
+ raw_decode = true;
break;
case SAA7134_BOARD_ENCORE_ENLTV:
case SAA7134_BOARD_ENCORE_ENLTV_FM:
@@ -786,9 +682,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_ENCORE_ENLTV_FM53:
ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
- mask_keydown = 0x0040000;
- mask_keycode = 0x00007f;
- nec_gpio = 1;
+ mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
+ mask_keyup = 0x0040000;
+ mask_keycode = 0xffff;
+ raw_decode = true;
break;
case SAA7134_BOARD_10MOONSTVMASTER3:
ir_codes = RC_MAP_ENCORE_ENLTV;
@@ -832,24 +729,20 @@ int saa7134_input_init1(struct saa7134_dev *dev)
}
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
+ rc = rc_allocate_device();
+ if (!ir || !rc) {
err = -ENOMEM;
goto err_out_free;
}
- ir->dev = input_dev;
+ ir->dev = rc;
dev->remote = ir;
- ir->running = 0;
-
/* init hardware-specific stuff */
ir->mask_keycode = mask_keycode;
ir->mask_keydown = mask_keydown;
ir->mask_keyup = mask_keyup;
ir->polling = polling;
- ir->rc5_gpio = rc5_gpio;
- ir->nec_gpio = nec_gpio;
ir->raw_decode = raw_decode;
/* init input device */
@@ -858,47 +751,35 @@ int saa7134_input_init1(struct saa7134_dev *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci));
-
- ir->props.priv = dev;
- ir->props.open = saa7134_ir_open;
- ir->props.close = saa7134_ir_close;
-
+ rc->priv = dev;
+ rc->open = saa7134_ir_open;
+ rc->close = saa7134_ir_close;
if (raw_decode)
- ir->props.driver_type = RC_DRIVER_IR_RAW;
-
- if (!raw_decode && allow_protocol_change) {
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.change_protocol = saa7134_ir_change_protocol;
- }
+ rc->driver_type = RC_DRIVER_IR_RAW;
- err = ir_input_init(input_dev, &ir->ir, ir_type);
- if (err < 0)
- goto err_out_free;
-
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) {
- input_dev->id.vendor = dev->pci->subsystem_vendor;
- input_dev->id.product = dev->pci->subsystem_device;
+ rc->input_id.vendor = dev->pci->subsystem_vendor;
+ rc->input_id.product = dev->pci->subsystem_device;
} else {
- input_dev->id.vendor = dev->pci->vendor;
- input_dev->id.product = dev->pci->device;
+ rc->input_id.vendor = dev->pci->vendor;
+ rc->input_id.product = dev->pci->device;
}
- input_dev->dev.parent = &dev->pci->dev;
+ rc->dev.parent = &dev->pci->dev;
+ rc->map_name = ir_codes;
+ rc->driver_name = MODULE_NAME;
- err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_free;
- /* the remote isn't as bouncy as a keyboard */
- ir->dev->rep[REP_DELAY] = repeat_delay;
- ir->dev->rep[REP_PERIOD] = repeat_period;
-
return 0;
err_out_free:
+ rc_free_device(rc);
dev->remote = NULL;
kfree(ir);
return err;
@@ -910,7 +791,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
return;
saa7134_ir_stop(dev);
- ir_input_unregister(dev->remote->dev);
+ rc_unregister_device(dev->remote->dev);
kfree(dev->remote);
dev->remote = NULL;
}
@@ -918,14 +799,12 @@ void saa7134_input_fini(struct saa7134_dev *dev)
void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
{
struct i2c_board_info info;
-
struct i2c_msg msg_msi = {
.addr = 0x50,
.flags = I2C_M_RD,
.len = 0,
.buf = NULL,
};
-
int rc;
if (disable_ir) {
@@ -972,7 +851,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
an existing device. Weird...
REVISIT: might no longer be needed */
rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
- dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+ dprintk("probe 0x%02x @ %s: %s\n",
msg_msi.addr, dev->i2c_adap.name,
(1 == rc) ? "yes" : "no");
break;
@@ -1000,7 +879,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
dev->init_data.name = "BeholdTV";
dev->init_data.get_key = get_key_beholdm6xx;
dev->init_data.ir_codes = RC_MAP_BEHOLD;
- dev->init_data.type = IR_TYPE_NEC;
+ dev->init_data.type = RC_TYPE_NEC;
info.addr = 0x2d;
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
@@ -1025,8 +904,8 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
{
- struct card_ir *ir = dev->remote;
- unsigned long timeout;
+ struct saa7134_card_ir *ir = dev->remote;
+ unsigned long timeout;
int space;
/* Generate initial event */
@@ -1035,7 +914,6 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);
-
/*
* Wait 15 ms from the start of the first IR event before processing
* the event. This time is enough for NEC protocol. May need adjustments
@@ -1043,173 +921,9 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
*/
if (!ir->active) {
timeout = jiffies + jiffies_to_msecs(15);
- mod_timer(&ir->timer_end, timeout);
- ir->active = 1;
+ mod_timer(&ir->timer, timeout);
+ ir->active = true;
}
return 1;
}
-
-static int saa7134_rc5_irq(struct saa7134_dev *dev)
-{
- struct card_ir *ir = dev->remote;
- struct timeval tv;
- u32 gap;
- unsigned long current_jiffies, timeout;
-
- /* get time of bit */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* active code => add bit */
- if (ir->active) {
- /* only if in the code (otherwise spurious IRQ or timer
- late) */
- if (ir->last_bit < 28) {
- ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
- ir_rc5_remote_gap;
- ir->code |= 1 << ir->last_bit;
- }
- /* starting new code */
- } else {
- ir->active = 1;
- ir->code = 0;
- ir->base_time = tv;
- ir->last_bit = 0;
-
- timeout = current_jiffies + (500 + 30 * HZ) / 1000;
- mod_timer(&ir->timer_end, timeout);
- }
-
- return 1;
-}
-
-/* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms
- The first pulse (start) has 9 + 4.5 ms
- */
-
-static void saa7134_nec_timer(unsigned long data)
-{
- struct saa7134_dev *dev = (struct saa7134_dev *) data;
- struct card_ir *ir = dev->remote;
-
- dprintk("Cancel key repeat\n");
-
- ir_input_nokey(ir->dev, &ir->ir);
-}
-
-static void nec_task(unsigned long data)
-{
- struct saa7134_dev *dev = (struct saa7134_dev *) data;
- struct card_ir *ir;
- struct timeval tv;
- int count, pulse, oldpulse, gap;
- u32 ircode = 0, not_code = 0;
- int ngap = 0;
-
- if (!data) {
- printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n");
- /* GPIO will be kept disabled */
- return;
- }
-
- ir = dev->remote;
-
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
- pulse = oldpulse;
-
- do_gettimeofday(&tv);
- ir->base_time = tv;
-
- /* Decode NEC pulsecode. This code can take up to 76.5 ms to run.
- Unfortunately, using IRQ to decode pulse didn't work, since it uses
- a pulse train of 38KHz. This means one pulse on each 52 us
- */
- do {
- /* Wait until the end of pulse/space or 5 ms */
- for (count = 0; count < 500; count++) {
- udelay(10);
- /* rising SAA7134_GPIO_GPRESCAN reads the status */
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)
- & ir->mask_keydown;
- if (pulse != oldpulse)
- break;
- }
-
- do_gettimeofday(&tv);
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
-
- if (!pulse) {
- /* Bit 0 has 560 us, while bit 1 has 1120 us.
- Do something only if bit == 1
- */
- if (ngap && (gap > 560 + 280)) {
- unsigned int shift = ngap - 1;
-
- /* Address first, then command */
- if (shift < 8) {
- shift += 8;
- ircode |= 1 << shift;
- } else if (shift < 16) {
- not_code |= 1 << shift;
- } else if (shift < 24) {
- shift -= 16;
- ircode |= 1 << shift;
- } else {
- shift -= 24;
- not_code |= 1 << shift;
- }
- }
- ngap++;
- }
-
-
- ir->base_time = tv;
-
- /* TIMEOUT - Long pulse */
- if (gap >= 5000)
- break;
- oldpulse = pulse;
- } while (ngap < 32);
-
- if (ngap == 32) {
- /* FIXME: should check if not_code == ~ircode */
- ir->code = ir_extract_bits(ircode, ir->mask_keycode);
-
- dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
- ir->code, ircode, not_code);
-
- ir_input_keydown(ir->dev, &ir->ir, ir->code);
- } else
- dprintk("Repeat last key\n");
-
- /* Keep repeating the last key */
- mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150));
-
- saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
-}
-
-static int saa7134_nec_irq(struct saa7134_dev *dev)
-{
- struct card_ir *ir = dev->remote;
-
- saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
- tasklet_schedule(&ir->tlet);
-
- return 1;
-}
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 3e7d2fd1688f..57e646bb48b3 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -550,16 +550,16 @@ static int tvaudio_thread(void *data)
} else if (0 != dev->last_carrier) {
/* no carrier -- try last detected one as fallback */
carrier = dev->last_carrier;
- dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
- "using %d.%03d MHz [last detected]\n",
- dev->name, carrier/1000, carrier%1000);
+ dprintk("audio carrier scan failed, "
+ "using %d.%03d MHz [last detected]\n",
+ carrier/1000, carrier%1000);
} else {
/* no carrier + no fallback -- use default */
carrier = default_carrier;
- dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
- "using %d.%03d MHz [default]\n",
- dev->name, carrier/1000, carrier%1000);
+ dprintk("audio carrier scan failed, "
+ "using %d.%03d MHz [default]\n",
+ carrier/1000, carrier%1000);
}
tvaudio_setcarrier(dev,carrier,carrier);
dev->automute = 0;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index d3b6a196e5dc..babfbe7543eb 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -37,7 +37,7 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/tuner.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
#include <media/videobuf-dma-sg.h>
#include <sound/core.h>
@@ -119,6 +119,26 @@ struct saa7134_format {
unsigned int uvswap:1;
};
+struct saa7134_card_ir {
+ struct rc_dev *dev;
+
+ char name[32];
+ char phys[32];
+ unsigned users;
+
+ u32 polling;
+ u32 last_gpio;
+ u32 mask_keycode, mask_keydown, mask_keyup;
+
+ bool running;
+ bool active;
+
+ struct timer_list timer;
+
+ /* IR core raw decoding */
+ u32 raw_decode;
+};
+
/* ----------------------------------------------------------- */
/* card configuration */
@@ -305,6 +325,7 @@ struct saa7134_format {
#define SAA7134_BOARD_BEHOLD_A7 179
#define SAA7134_BOARD_AVERMEDIA_M733A 180
#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181
+#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
@@ -529,7 +550,7 @@ struct saa7134_dev {
/* infrared remote */
int has_remote;
- struct card_ir *remote;
+ struct saa7134_card_ir *remote;
/* pci i/o */
char name[32];
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index ad3bc4154176..bd86d970f4c2 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -40,9 +40,8 @@ int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i)
ret = saa7164_cmd_send(dev, 0, GET_CUR,
GET_FW_STATUS_CONTROL, sizeof(struct tmFwInfoStruct), i);
- if (ret != SAA_OK) {
+ if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
printk(KERN_INFO "saa7164[%d]-CPU: %d percent", dev->nr, i->CPULoad);
@@ -63,14 +62,15 @@ int saa7164_api_collect_debug(struct saa7164_dev *dev)
ret = saa7164_cmd_send(dev, 0, GET_CUR,
GET_DEBUG_DATA_CONTROL, sizeof(d), &d);
- if (ret != SAA_OK) {
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
+ if (ret != SAA_OK)
+ printk(KERN_ERR "%s() error, ret = 0x%x\n",
+ __func__, ret);
if (d.dwResult != SAA_OK)
break;
- printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr, d.ucDebugData);
+ printk(KERN_INFO "saa7164[%d]-FWMSG: %s", dev->nr,
+ d.ucDebugData);
}
return 0;
@@ -86,9 +86,9 @@ int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
/* Retrieve current state */
ret = saa7164_cmd_send(dev, 0, GET_CUR,
SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
- if (ret != SAA_OK) {
+ if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
+
dprintk(DBGLVL_API, "%s() Was %d\n", __func__, lvl.dwDebugLevel);
lvl.dwDebugLevel = level;
@@ -96,9 +96,8 @@ int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level)
/* set new state */
ret = saa7164_cmd_send(dev, 0, SET_CUR,
SET_DEBUG_LEVEL_CONTROL, sizeof(lvl), &lvl);
- if (ret != SAA_OK) {
+ if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- }
return ret;
}
@@ -152,8 +151,10 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
dprintk(DBGLVL_API, "SET/COMMIT Verified\n");
dprintk(DBGLVL_API, "rsp.bmHint = 0x%x\n", rsp.bmHint);
- dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n", rsp.bFormatIndex);
- dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n", rsp.bFrameIndex);
+ dprintk(DBGLVL_API, "rsp.bFormatIndex = 0x%x\n",
+ rsp.bFormatIndex);
+ dprintk(DBGLVL_API, "rsp.bFrameIndex = 0x%x\n",
+ rsp.bFrameIndex);
} else
printk(KERN_ERR "%s() compare failed\n", __func__);
}
@@ -210,14 +211,17 @@ int saa7164_api_set_encoder(struct saa7164_port *port)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
/* Establish video bitrates */
- if (port->encoder_params.bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ if (port->encoder_params.bitrate_mode ==
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_CONSTANT;
else
vb.ucVideoBitRateMode = EU_VIDEO_BIT_RATE_MODE_VARIABLE_PEAK;
vb.dwVideoBitRate = port->encoder_params.bitrate;
vb.dwVideoBitRatePeak = port->encoder_params.bitrate_peak;
ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_VIDEO_BIT_RATE_CONTROL, sizeof(struct tmComResEncVideoBitRate), &vb);
+ EU_VIDEO_BIT_RATE_CONTROL,
+ sizeof(struct tmComResEncVideoBitRate),
+ &vb);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -226,9 +230,12 @@ int saa7164_api_set_encoder(struct saa7164_port *port)
ab.dwAudioBitRate = 384000;
ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
- EU_AUDIO_BIT_RATE_CONTROL, sizeof(struct tmComResEncAudioBitRate), &ab);
+ EU_AUDIO_BIT_RATE_CONTROL,
+ sizeof(struct tmComResEncAudioBitRate),
+ &ab);
if (ret != SAA_OK)
- printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+ printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
+ ret);
saa7164_api_set_aspect_ratio(port);
saa7164_api_set_gop_size(port);
@@ -244,7 +251,8 @@ int saa7164_api_get_encoder(struct saa7164_port *port)
struct tmComResEncVideoInputAspectRatio ar;
int ret;
- dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid);
+ dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
+ port->hwcfg.sourceid);
port->encoder_profile = 0;
port->video_format = 0;
@@ -257,7 +265,8 @@ int saa7164_api_get_encoder(struct saa7164_port *port)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
- EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8), &port->video_resolution);
+ EU_VIDEO_RESOLUTION_CONTROL, sizeof(u8),
+ &port->video_resolution);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -294,13 +303,20 @@ int saa7164_api_get_encoder(struct saa7164_port *port)
dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
- dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode);
- dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", v.dwVideoBitRate);
- dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak);
- dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode);
- dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", a.dwAudioBitRate);
- dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak);
- dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height);
+ dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n",
+ v.ucVideoBitRateMode);
+ dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n",
+ v.dwVideoBitRate);
+ dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n",
+ v.dwVideoBitRatePeak);
+ dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n",
+ a.ucAudioBitRateMode);
+ dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n",
+ a.dwAudioBitRate);
+ dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n",
+ a.dwAudioBitRatePeak);
+ dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n",
+ ar.width, ar.height);
return ret;
}
@@ -439,7 +455,8 @@ int saa7164_api_set_videomux(struct saa7164_port *port)
/* Audio Mux */
ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
- SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[port->mux_input - 1]);
+ SU_INPUT_SELECT_CONTROL, sizeof(u8),
+ &inputs[port->mux_input - 1]);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -492,7 +509,8 @@ int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
+ dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
+ level, min, max, v);
v = level;
if (v < min)
@@ -517,7 +535,8 @@ int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
- dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
+ dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__,
+ level, min, max, v);
return ret;
}
@@ -539,7 +558,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port)
lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
- AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults), &lvl);
+ AUDIO_DEFAULT_CONTROL, sizeof(struct tmComResAudioDefaults),
+ &lvl);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
@@ -555,7 +575,8 @@ int saa7164_api_set_audio_std(struct saa7164_port *port)
ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
if (ret != SAA_OK)
- printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret);
+ printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n",
+ __func__, ret);
return ret;
}
@@ -575,7 +596,9 @@ int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
if (ret != SAA_OK)
- printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret);
+ printk(KERN_ERR
+ "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n",
+ __func__, ret);
return ret;
}
@@ -646,9 +669,9 @@ int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
EXU_REGISTER_ACCESS_CONTROL, len, &buf);
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
-
- //saa7164_dumphex16(dev, buf, 16);
-
+#if 0
+ saa7164_dumphex16(dev, buf, 16);
+#endif
return ret == SAA_OK ? 0 : -EIO;
}
@@ -696,7 +719,8 @@ int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
} else {
/* Unknown standard, assume DTV */
dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
- saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */
+ /* Undefinded Video Standard */
+ saa7164_api_set_dif(port, 0x00, 0x80);
agc_disable = 1;
}
@@ -933,7 +957,7 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
if (hdr->type != CS_INTERFACE)
return SAA_ERR_NOT_SUPPORTED;
- dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
+ dprintk(DBGLVL_API, "@ 0x%x =\n", idx);
switch (hdr->subtype) {
case GENERAL_REQUEST:
dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
@@ -1085,7 +1109,8 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
vbiport = &dev->ports[SAA7164_PORT_VBI2];
memcpy(&vbiport->hwcfg, vcoutputtermhdr,
sizeof(*vcoutputtermhdr));
- memcpy(&vbiport->vbi_fmt_ntsc, vbifmt, sizeof(*vbifmt));
+ memcpy(&vbiport->vbi_fmt_ntsc, vbifmt,
+ sizeof(*vbifmt));
saa7164_api_configure_port_vbi(dev,
vbiport);
break;
@@ -1134,7 +1159,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->tunerunit, tunerunithdr,
sizeof(struct tmComResTunerDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d] tuner)\n", encport->nr);
+ dprintk(DBGLVL_API,
+ " (becomes dev->enc[%d] tuner)\n",
+ encport->nr);
}
break;
case VC_SELECTOR_UNIT:
@@ -1163,7 +1190,8 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->vidproc, pdh,
sizeof(struct tmComResProcDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
+ encport->nr);
}
break;
case FEATURE_UNIT:
@@ -1181,15 +1209,18 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->audfeat, afd,
sizeof(struct tmComResAFeatureDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n",
+ encport->nr);
break;
case ENCODER_UNIT:
edh = (struct tmComResEncoderDescrHeader *)(buf + idx);
dprintk(DBGLVL_API, " ENCODER_UNIT\n");
dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
- dprintk(DBGLVL_API, " vsourceid = 0x%x\n", edh->vsourceid);
- dprintk(DBGLVL_API, " asourceid = 0x%x\n", edh->asourceid);
+ dprintk(DBGLVL_API, " vsourceid = 0x%x\n",
+ edh->vsourceid);
+ dprintk(DBGLVL_API, " asourceid = 0x%x\n",
+ edh->asourceid);
dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
if (edh->iunit == edh->unitid) {
if (currpath == 1)
@@ -1198,7 +1229,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->encunit, edh,
sizeof(struct tmComResEncoderDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API,
+ " (becomes dev->enc[%d])\n",
+ encport->nr);
}
break;
case EXTENSION_UNIT:
@@ -1262,7 +1295,9 @@ int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
encport = &dev->ports[SAA7164_PORT_ENC2];
memcpy(&encport->ifunit, exthdr,
sizeof(struct tmComResExtDevDescrHeader));
- dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
+ dprintk(DBGLVL_API,
+ " (becomes dev->enc[%d])\n",
+ encport->nr);
}
break;
case PVC_INFRARED_UNIT:
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
index 7230912acc7d..ddd25211c9e8 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -24,46 +24,46 @@
#include "saa7164.h"
/* The PCI address space for buffer handling looks like this:
-
- +-u32 wide-------------+
- | +
- +-u64 wide------------------------------------+
- + +
- +----------------------+
- | CurrentBufferPtr + Pointer to current PCI buffer >-+
- +----------------------+ |
- | Unused + |
- +----------------------+ |
- | Pitch + = 188 (bytes) |
- +----------------------+ |
- | PCI buffer size + = pitch * number of lines (312) |
- +----------------------+ |
- |0| Buf0 Write Offset + |
- +----------------------+ v
- |1| Buf1 Write Offset + |
- +----------------------+ |
- |2| Buf2 Write Offset + |
- +----------------------+ |
- |3| Buf3 Write Offset + |
- +----------------------+ |
- ... More write offsets |
- +---------------------------------------------+ |
- +0| set of ptrs to PCI pagetables + |
- +---------------------------------------------+ |
- +1| set of ptrs to PCI pagetables + <--------+
- +---------------------------------------------+
- +2| set of ptrs to PCI pagetables +
- +---------------------------------------------+
- +3| set of ptrs to PCI pagetables + >--+
- +---------------------------------------------+ |
- ... More buffer pointers | +----------------+
- +->| pt[0] TS data |
- | +----------------+
- |
- | +----------------+
- +->| pt[1] TS data |
- | +----------------+
- | etc
+ *
+ * +-u32 wide-------------+
+ * | +
+ * +-u64 wide------------------------------------+
+ * + +
+ * +----------------------+
+ * | CurrentBufferPtr + Pointer to current PCI buffer >-+
+ * +----------------------+ |
+ * | Unused + |
+ * +----------------------+ |
+ * | Pitch + = 188 (bytes) |
+ * +----------------------+ |
+ * | PCI buffer size + = pitch * number of lines (312) |
+ * +----------------------+ |
+ * |0| Buf0 Write Offset + |
+ * +----------------------+ v
+ * |1| Buf1 Write Offset + |
+ * +----------------------+ |
+ * |2| Buf2 Write Offset + |
+ * +----------------------+ |
+ * |3| Buf3 Write Offset + |
+ * +----------------------+ |
+ * ... More write offsets |
+ * +---------------------------------------------+ |
+ * +0| set of ptrs to PCI pagetables + |
+ * +---------------------------------------------+ |
+ * +1| set of ptrs to PCI pagetables + <--------+
+ * +---------------------------------------------+
+ * +2| set of ptrs to PCI pagetables +
+ * +---------------------------------------------+
+ * +3| set of ptrs to PCI pagetables + >--+
+ * +---------------------------------------------+ |
+ * ... More buffer pointers | +----------------+
+ * +->| pt[0] TS data |
+ * | +----------------+
+ * |
+ * | +----------------+
+ * +->| pt[1] TS data |
+ * | +----------------+
+ * | etc
*/
void saa7164_buffer_display(struct saa7164_buffer *buf)
@@ -283,7 +283,8 @@ int saa7164_buffer_cfg_port(struct saa7164_port *port)
return 0;
}
-struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, u32 len)
+struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
+ u32 len)
{
struct saa7164_user_buffer *buf;
@@ -313,12 +314,9 @@ void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
if (!buf)
return;
- if (buf->data) {
- kfree(buf->data);
- buf->data = 0;
- }
+ kfree(buf->data);
+ buf->data = 0;
- if (buf)
- kfree(buf);
+ kfree(buf);
}
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
index 30d5283da41e..b2b0d97101d0 100644
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -43,7 +43,8 @@ int saa7164_bus_setup(struct saa7164_dev *dev)
b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
- b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64));
+ b->m_dwSetWritePos = ((u32)dev->intfdesc.BARLocation) +
+ (2 * sizeof(u64));
b->m_dwSetReadPos = b->m_dwSetWritePos + (1 * sizeof(u32));
b->m_dwGetWritePos = b->m_dwSetWritePos + (2 * sizeof(u32));
@@ -105,7 +106,8 @@ void saa7164_bus_verify(struct saa7164_dev *dev)
}
}
-void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void *buf)
+void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m,
+ void *buf)
{
dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
@@ -129,7 +131,8 @@ void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m, void *
* SAA_OK The function executed successfully.
* < 0 One or more members are not initialized.
*/
-int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf)
+int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
+ void *buf)
{
struct tmComResBusInfo *bus = &dev->bus;
u32 bytes_to_write, free_write_space, timeout, curr_srp, curr_swp;
@@ -294,14 +297,15 @@ out:
/*
* Receive a command or a response from the bus. The implementation does not
* know if it is a command or a response it simply dequeues the data,
- * depending on the bus information given in the struct tmComResBusInfo structure.
+ * depending on the bus information given in the struct tmComResBusInfo
+ * structure.
*
* Return Value:
* 0 The function executed successfully.
* < 0 One or more members are not initialized.
*/
-int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf,
- int peekonly)
+int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
+ void *buf, int peekonly)
{
struct tmComResBusInfo *bus = &dev->bus;
u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
index 4cb634e952a6..69822a4e7275 100644
--- a/drivers/media/video/saa7164/saa7164-cards.c
+++ b/drivers/media/video/saa7164/saa7164-cards.c
@@ -482,7 +482,7 @@ void saa7164_gpio_setup(struct saa7164_dev *dev)
saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
- msleep(10);
+ msleep(20);
saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
index 301a9e302f45..a97ae17b36c2 100644
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -122,8 +122,8 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
return ret;
}
- /* It's unlikely to have more than 4 or 5 pending messages, ensure we exit
- * at some point regardles.
+ /* It's unlikely to have more than 4 or 5 pending messages,
+ * ensure we exit at some point regardless.
*/
} while (i++ < 32);
@@ -186,7 +186,8 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev)
return SAA_OK;
}
-int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf)
+int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
+ void *buf)
{
struct tmComResBusInfo *bus = &dev->bus;
u8 cmd_sent;
@@ -292,7 +293,8 @@ int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
* We typically are signalled in < 50ms but it can
* take MUCH longer.
*/
- wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
+ wait_event_timeout(*q, dev->cmds[seqno].signalled,
+ (HZ * waitsecs));
r = time_before(jiffies, stamp + (HZ * waitsecs));
if (r)
ret = SAA_OK;
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index e1bac5051460..d6bf3f82cc34 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -40,12 +40,12 @@ MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
MODULE_LICENSE("GPL");
/*
- 1 Basic
- 2
- 4 i2c
- 8 api
- 16 cmd
- 32 bus
+ * 1 Basic
+ * 2
+ * 4 i2c
+ * 8 api
+ * 16 cmd
+ * 32 bus
*/
unsigned int saa_debug;
@@ -82,7 +82,8 @@ MODULE_PARM_DESC(crc_checking, "enable crc sanity checking on buffers");
unsigned int guard_checking = 1;
module_param(guard_checking, int, 0644);
-MODULE_PARM_DESC(guard_checking, "enable dma sanity checking for buffer overruns");
+MODULE_PARM_DESC(guard_checking,
+ "enable dma sanity checking for buffer overruns");
static unsigned int saa7164_devcount;
@@ -123,7 +124,9 @@ static void saa7164_pack_verifier(struct saa7164_buffer *buf)
if ((*(p + i + 0) != 0x00) || (*(p + i + 1) != 0x00) ||
(*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) {
printk(KERN_ERR "No pack at 0x%x\n", i);
-// saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
+#if 0
+ saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
+#endif
}
}
}
@@ -199,19 +202,16 @@ static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
strcpy(hg->name, name);
/* First 30ms x 1ms */
- for (i = 0; i < 30; i++) {
+ for (i = 0; i < 30; i++)
hg->counter1[0 + i].val = i;
- }
/* 30 - 200ms x 10ms */
- for (i = 0; i < 18; i++) {
+ for (i = 0; i < 18; i++)
hg->counter1[30 + i].val = 30 + (i * 10);
- }
/* 200 - 2000ms x 100ms */
- for (i = 0; i < 15; i++) {
+ for (i = 0; i < 15; i++)
hg->counter1[48 + i].val = 200 + (i * 200);
- }
/* Catch all massive value (2secs) */
hg->counter1[55].val = 2000;
@@ -315,7 +315,9 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
(*(p + buf->actual_size + 0x13) != 0xff)) {
printk(KERN_ERR "%s() buf %p guard buffer breach\n",
__func__, buf);
-// saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
+#if 0
+ saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
+#endif
}
}
@@ -961,9 +963,7 @@ static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
/* We need a deferred interrupt handler for cmd handling */
INIT_WORK(&port->workenc, saa7164_work_enchandler);
- }
- else
- if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
+ } else if ((portnr == SAA7164_PORT_VBI1) || (portnr == SAA7164_PORT_VBI2)) {
port->type = SAA7164_MPEG_VBI;
/* We need a deferred interrupt handler for cmd handling */
@@ -1001,7 +1001,7 @@ static int saa7164_dev_setup(struct saa7164_dev *dev)
atomic_inc(&dev->refcount);
dev->nr = saa7164_devcount++;
- sprintf(dev->name, "saa7164[%d]", dev->nr);
+ snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr);
mutex_lock(&devlist);
list_add_tail(&dev->devlist, &saa7164_devlist);
@@ -1169,7 +1169,7 @@ static int saa7164_proc_open(struct inode *inode, struct file *filp)
return single_open(filp, saa7164_proc_show, NULL);
}
-static struct file_operations saa7164_proc_fops = {
+static const struct file_operations saa7164_proc_fops = {
.open = saa7164_proc_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index cbb53d0ee979..1838408cd5cb 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -125,16 +125,22 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
dprintk(DBGLVL_ENC, "%s()\n", __func__);
- if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
- dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n", __func__);
+ if (port->encoder_params.stream_type ==
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
+ dprintk(DBGLVL_ENC,
+ "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_PS\n",
+ __func__);
params->samplesperline = 128;
params->numberoflines = 256;
params->pitch = 128;
params->numpagetables = 2 +
((SAA7164_PS_NUMBER_OF_LINES * 128) / PAGE_SIZE);
} else
- if (port->encoder_params.stream_type == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
- dprintk(DBGLVL_ENC, "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n", __func__);
+ if (port->encoder_params.stream_type ==
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
+ dprintk(DBGLVL_ENC,
+ "%s() type=V4L2_MPEG_STREAM_TYPE_MPEG2_TS\n",
+ __func__);
params->samplesperline = 188;
params->numberoflines = 312;
params->pitch = 188;
@@ -826,7 +832,8 @@ static int fill_queryctrl(struct saa7164_encoder_params *params,
return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
return v4l2_ctrl_query_fill(c,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
1, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
return v4l2_ctrl_query_fill(c,
@@ -1113,7 +1120,9 @@ struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
if (crc_checking) {
crc = crc32(0, ubuf->data, ubuf->actual_size);
if (crc != ubuf->crc) {
- printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
+ printk(KERN_ERR
+ "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
+ __func__,
ubuf, ubuf->crc, crc);
}
}
@@ -1201,9 +1210,8 @@ static ssize_t fops_read(struct file *file, char __user *buffer,
buffer += cnt;
ret += cnt;
- if (ubuf->pos > ubuf->actual_size) {
+ if (ubuf->pos > ubuf->actual_size)
printk(KERN_ERR "read() pos > actual, huh?\n");
- }
if (ubuf->pos == ubuf->actual_size) {
@@ -1227,16 +1235,16 @@ static ssize_t fops_read(struct file *file, char __user *buffer,
}
}
err:
- if (!ret && !ubuf) {
+ if (!ret && !ubuf)
ret = -EAGAIN;
- }
return ret;
}
static unsigned int fops_poll(struct file *file, poll_table *wait)
{
- struct saa7164_encoder_fh *fh = (struct saa7164_encoder_fh *)file->private_data;
+ struct saa7164_encoder_fh *fh =
+ (struct saa7164_encoder_fh *)file->private_data;
struct saa7164_port *port = fh->port;
struct saa7164_user_buffer *ubuf;
unsigned int mask = 0;
@@ -1249,9 +1257,8 @@ static unsigned int fops_poll(struct file *file, poll_table *wait)
saa7164_histogram_update(&port->poll_interval,
port->last_poll_msecs_diff);
- if (!video_is_registered(port->v4l_device)) {
+ if (!video_is_registered(port->v4l_device))
return -EIO;
- }
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
if (atomic_inc_return(&port->v4l_reader_count) == 1) {
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
index 484533c32bb1..22b02323dca9 100644
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -178,7 +178,7 @@ int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
goto out;
}
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
if (timeout++ > 60)
break;
}
@@ -235,7 +235,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
__func__, err_flags);
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
printk(KERN_ERR "%s() firmware corrupt\n",
@@ -294,7 +294,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
__func__, err_flags);
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
printk(KERN_ERR
@@ -365,7 +365,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
first_timeout = SAA_DEVICE_TIMEOUT;
while (first_timeout) {
- msleep(10);
+ msleep(10); /* Checkpatch throws a < 20ms warning */
version =
saa7164_getcurrentfirmwareversion(dev);
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
index b5167d33650a..26148f76cba2 100644
--- a/drivers/media/video/saa7164/saa7164-i2c.c
+++ b/drivers/media/video/saa7164/saa7164-i2c.c
@@ -23,7 +23,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include "saa7164.h"
@@ -65,7 +65,7 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
}
return num;
- err:
+err:
return retval;
}
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index 323c7cdca37b..8abbe6d661e4 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -51,11 +51,15 @@ static void saa7164_vbi_configure(struct saa7164_port *port)
/* Set up the DIF (enable it) for analog mode by default */
saa7164_api_initialize_dif(port);
-// /* Configure the correct video standard */
-// saa7164_api_configure_dif(port, port->encodernorm.id);
+ /* Configure the correct video standard */
+#if 0
+ saa7164_api_configure_dif(port, port->encodernorm.id);
+#endif
-// /* Ensure the audio decoder is correct configured */
-// saa7164_api_set_audio_std(port);
+#if 0
+ /* Ensure the audio decoder is correct configured */
+ saa7164_api_set_audio_std(port);
+#endif
dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
}
@@ -919,8 +923,10 @@ static int saa7164_vbi_start_streaming(struct saa7164_port *port)
saa7164_vbi_buffers_alloc(port);
/* Configure the encoder with any cache values */
-// saa7164_api_set_encoder(port);
-// saa7164_api_get_encoder(port);
+#if 0
+ saa7164_api_set_encoder(port);
+ saa7164_api_get_encoder(port);
+#endif
/* Place the empty buffers on the hardware */
saa7164_buffer_cfg_port(port);
@@ -1060,7 +1066,8 @@ struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
if (crc_checking) {
crc = crc32(0, ubuf->data, ubuf->actual_size);
if (crc != ubuf->crc) {
- printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
+ printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
+ __func__,
ubuf, ubuf->crc, crc);
}
}
@@ -1148,9 +1155,8 @@ static ssize_t fops_read(struct file *file, char __user *buffer,
buffer += cnt;
ret += cnt;
- if (ubuf->pos > ubuf->actual_size) {
+ if (ubuf->pos > ubuf->actual_size)
printk(KERN_ERR "read() pos > actual, huh?\n");
- }
if (ubuf->pos == ubuf->actual_size) {
@@ -1197,9 +1203,8 @@ static unsigned int fops_poll(struct file *file, poll_table *wait)
saa7164_histogram_update(&port->poll_interval,
port->last_poll_msecs_diff);
- if (!video_is_registered(port->v4l_device)) {
+ if (!video_is_registered(port->v4l_device))
return -EIO;
- }
if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
if (atomic_inc_return(&port->v4l_reader_count) == 1) {
@@ -1257,10 +1262,14 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
.vidioc_log_status = vidioc_log_status,
.vidioc_queryctrl = vidioc_queryctrl,
-// .vidioc_g_chip_ident = saa7164_g_chip_ident,
+#if 0
+ .vidioc_g_chip_ident = saa7164_g_chip_ident,
+#endif
#ifdef CONFIG_VIDEO_ADV_DEBUG
-// .vidioc_g_register = saa7164_g_register,
-// .vidioc_s_register = saa7164_s_register,
+#if 0
+ .vidioc_g_register = saa7164_g_register,
+ .vidioc_s_register = saa7164_s_register,
+#endif
#endif
.vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
index 041ae8e20f68..16745d2fb349 100644
--- a/drivers/media/video/saa7164/saa7164.h
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -113,7 +113,8 @@
#define DBGLVL_THR 4096
#define DBGLVL_CPU 8192
-#define SAA7164_NORMS (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
+#define SAA7164_NORMS \
+ (V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443)
enum port_t {
SAA7164_MPEG_UNDEFINED = 0,
@@ -182,15 +183,11 @@ struct saa7164_subid {
struct saa7164_encoder_fh {
struct saa7164_port *port;
-// u32 freq;
-// u32 tuner_type;
atomic_t v4l_reading;
};
struct saa7164_vbi_fh {
struct saa7164_port *port;
-// u32 freq;
-// u32 tuner_type;
atomic_t v4l_reading;
};
@@ -265,8 +262,6 @@ struct saa7164_ctrl {
struct saa7164_tvnorm {
char *name;
v4l2_std_id id;
-// u32 cxiformat;
-// u32 cxoformat;
};
struct saa7164_encoder_params {
@@ -447,7 +442,7 @@ struct saa7164_dev {
int nr;
int hwrevision;
u32 board;
- char name[32];
+ char name[16];
/* firmware status */
struct saa7164_fw_status fw_status;
@@ -510,7 +505,8 @@ extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
/* saa7164-bus.c */
int saa7164_bus_setup(struct saa7164_dev *dev);
void saa7164_bus_dump(struct saa7164_dev *dev);
-int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg, void *buf);
+int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
+ void *buf);
int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
void *buf, int peekonly);
@@ -552,7 +548,8 @@ int saa7164_api_get_videomux(struct saa7164_port *port);
int saa7164_api_set_vbi_format(struct saa7164_port *port);
int saa7164_api_set_debug(struct saa7164_dev *dev, u8 level);
int saa7164_api_collect_debug(struct saa7164_dev *dev);
-int saa7164_api_get_load_info(struct saa7164_dev *dev, struct tmFwInfoStruct *i);
+int saa7164_api_get_load_info(struct saa7164_dev *dev,
+ struct tmFwInfoStruct *i);
/* ----------------------------------------------------------- */
/* saa7164-cards.c */
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
index 4e5a8cf76ded..07cf0c6c7c1f 100644
--- a/drivers/media/video/sh_vou.c
+++ b/drivers/media/video/sh_vou.c
@@ -75,6 +75,7 @@ struct sh_vou_device {
int pix_idx;
struct videobuf_buffer *active;
enum sh_vou_status status;
+ struct mutex fop_lock;
};
struct sh_vou_file {
@@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
vb->state = VIDEOBUF_NEEDS_INIT;
}
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
@@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
return 0;
}
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
static int sh_vou_buf_prepare(struct videobuf_queue *vq,
struct videobuf_buffer *vb,
enum v4l2_field field)
@@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq,
return 0;
}
-/* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */
+/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
static void sh_vou_buf_queue(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
@@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file)
V4L2_BUF_TYPE_VIDEO_OUTPUT,
V4L2_FIELD_NONE,
sizeof(struct videobuf_buffer), vdev,
- NULL);
+ &vou_dev->fop_lock);
return 0;
}
@@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = {
.owner = THIS_MODULE,
.open = sh_vou_open,
.release = sh_vou_release,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.mmap = sh_vou_mmap,
.poll = sh_vou_poll,
};
@@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&vou_dev->queue);
spin_lock_init(&vou_dev->lock);
+ mutex_init(&vou_dev->fop_lock);
atomic_set(&vou_dev->use_count, 0);
vou_dev->pdata = vou_pdata;
vou_dev->status = SH_VOU_IDLE;
@@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
vdev->tvnorms |= V4L2_STD_PAL;
vdev->v4l2_dev = &vou_dev->v4l2_dev;
vdev->release = video_device_release;
+ vdev->lock = &vou_dev->fop_lock;
vou_dev->vdev = vdev;
video_set_drvdata(vdev, vou_dev);
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 28e19daadec9..f49fbfb7dc13 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = {
.owner = THIS_MODULE,
.open = sn9c102_open,
.release = sn9c102_release,
- .ioctl = sn9c102_ioctl,
+ .unlocked_ioctl = sn9c102_ioctl,
.read = sn9c102_read,
.poll = sn9c102_poll,
.mmap = sn9c102_mmap,
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c
index c9dc67aba980..864696b7a006 100644
--- a/drivers/media/video/sr030pc30.c
+++ b/drivers/media/video/sr030pc30.c
@@ -735,7 +735,7 @@ static int sr030pc30_s_power(struct v4l2_subdev *sd, int on)
const struct sr030pc30_platform_data *pdata = info->pdata;
int ret;
- if (WARN(pdata == NULL, "No platform data!"))
+ if (WARN(pdata == NULL, "No platform data!\n"))
return -ENOMEM;
/*
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 3e99cea8e4dc..19621ed523ec 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -148,7 +148,7 @@ static int tea6415c_probe(struct i2c_client *client,
/* let's see whether this adapter can support what we need */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE))
- return 0;
+ return -EIO;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c
new file mode 100644
index 000000000000..cf48aa934b8c
--- /dev/null
+++ b/drivers/media/video/timblogiw.c
@@ -0,0 +1,894 @@
+/*
+ * timblogiw.c timberdale FPGA LogiWin Video In driver
+ * Copyright (c) 2009-2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Timberdale FPGA LogiWin Video In
+ */
+
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/scatterlist.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/timb_video.h>
+
+#define DRIVER_NAME "timb-video"
+
+#define TIMBLOGIWIN_NAME "Timberdale Video-In"
+#define TIMBLOGIW_VERSION_CODE 0x04
+
+#define TIMBLOGIW_LINES_PER_DESC 44
+#define TIMBLOGIW_MAX_VIDEO_MEM 16
+
+#define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name)
+
+
+struct timblogiw {
+ struct video_device video_dev;
+ struct v4l2_device v4l2_dev; /* mutual exclusion */
+ struct mutex lock;
+ struct device *dev;
+ struct timb_video_platform_data pdata;
+ struct v4l2_subdev *sd_enc; /* encoder */
+ bool opened;
+};
+
+struct timblogiw_tvnorm {
+ v4l2_std_id std;
+ u16 width;
+ u16 height;
+ u8 fps;
+};
+
+struct timblogiw_fh {
+ struct videobuf_queue vb_vidq;
+ struct timblogiw_tvnorm const *cur_norm;
+ struct list_head capture;
+ struct dma_chan *chan;
+ spinlock_t queue_lock; /* mutual exclusion */
+ unsigned int frame_count;
+};
+
+struct timblogiw_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ struct scatterlist sg[16];
+ dma_cookie_t cookie;
+ struct timblogiw_fh *fh;
+};
+
+const struct timblogiw_tvnorm timblogiw_tvnorms[] = {
+ {
+ .std = V4L2_STD_PAL,
+ .width = 720,
+ .height = 576,
+ .fps = 25
+ },
+ {
+ .std = V4L2_STD_NTSC,
+ .width = 720,
+ .height = 480,
+ .fps = 30
+ }
+};
+
+static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm)
+{
+ return norm->width * 2;
+}
+
+
+static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm)
+{
+ return norm->height * timblogiw_bytes_per_line(norm);
+}
+
+static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
+ if (timblogiw_tvnorms[i].std & std)
+ return timblogiw_tvnorms + i;
+
+ /* default to first element */
+ return timblogiw_tvnorms;
+}
+
+static void timblogiw_dma_cb(void *data)
+{
+ struct timblogiw_buffer *buf = data;
+ struct timblogiw_fh *fh = buf->fh;
+ struct videobuf_buffer *vb = &buf->vb;
+
+ spin_lock(&fh->queue_lock);
+
+ /* mark the transfer done */
+ buf->cookie = -1;
+
+ fh->frame_count++;
+
+ if (vb->state != VIDEOBUF_ERROR) {
+ list_del(&vb->queue);
+ do_gettimeofday(&vb->ts);
+ vb->field_count = fh->frame_count * 2;
+ vb->state = VIDEOBUF_DONE;
+
+ wake_up(&vb->done);
+ }
+
+ if (!list_empty(&fh->capture)) {
+ vb = list_entry(fh->capture.next, struct videobuf_buffer,
+ queue);
+ vb->state = VIDEOBUF_ACTIVE;
+ }
+
+ spin_unlock(&fh->queue_lock);
+}
+
+static bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param)
+{
+ return chan->chan_id == (int)filter_param;
+}
+
+/* IOCTL functions */
+
+static int timblogiw_g_fmt(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s entry\n", __func__);
+
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ mutex_lock(&lw->lock);
+
+ format->fmt.pix.width = fh->cur_norm->width;
+ format->fmt.pix.height = fh->cur_norm->height;
+ format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm);
+ format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm);
+ format->fmt.pix.field = V4L2_FIELD_NONE;
+
+ mutex_unlock(&lw->lock);
+
+ return 0;
+}
+
+static int timblogiw_try_fmt(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct v4l2_pix_format *pix = &format->fmt.pix;
+
+ dev_dbg(&vdev->dev,
+ "%s - width=%d, height=%d, pixelformat=%d, field=%d\n"
+ "bytes per line %d, size image: %d, colorspace: %d\n",
+ __func__,
+ pix->width, pix->height, pix->pixelformat, pix->field,
+ pix->bytesperline, pix->sizeimage, pix->colorspace);
+
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (pix->field != V4L2_FIELD_NONE)
+ return -EINVAL;
+
+ if (pix->pixelformat != V4L2_PIX_FMT_UYVY)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int timblogiw_s_fmt(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+ struct v4l2_pix_format *pix = &format->fmt.pix;
+ int err;
+
+ mutex_lock(&lw->lock);
+
+ err = timblogiw_try_fmt(file, priv, format);
+ if (err)
+ goto out;
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ dev_err(&vdev->dev, "%s queue busy\n", __func__);
+ err = -EBUSY;
+ goto out;
+ }
+
+ pix->width = fh->cur_norm->width;
+ pix->height = fh->cur_norm->height;
+
+out:
+ mutex_unlock(&lw->lock);
+ return err;
+}
+
+static int timblogiw_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+ memset(cap, 0, sizeof(*cap));
+ strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
+ strncpy(cap->driver, DRIVER_NAME, sizeof(cap->card)-1);
+ strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
+ cap->version = TIMBLOGIW_VERSION_CODE;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+ V4L2_CAP_READWRITE;
+
+ return 0;
+}
+
+static int timblogiw_enum_fmt(struct file *file, void *priv,
+ struct v4l2_fmtdesc *fmt)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index);
+
+ if (fmt->index != 0)
+ return -EINVAL;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->index = 0;
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ strncpy(fmt->description, "4:2:2, packed, YUYV",
+ sizeof(fmt->description)-1);
+ fmt->pixelformat = V4L2_PIX_FMT_UYVY;
+
+ return 0;
+}
+
+static int timblogiw_g_parm(struct file *file, void *priv,
+ struct v4l2_streamparm *sp)
+{
+ struct timblogiw_fh *fh = priv;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
+
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+ cp->timeperframe.numerator = 1;
+ cp->timeperframe.denominator = fh->cur_norm->fps;
+
+ return 0;
+}
+
+static int timblogiw_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int timblogiw_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int timblogiw_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ *std = fh->cur_norm->std;
+ return 0;
+}
+
+static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+ int err = 0;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ mutex_lock(&lw->lock);
+
+ if (TIMBLOGIW_HAS_DECODER(lw))
+ err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std);
+
+ if (!err)
+ fh->cur_norm = timblogiw_get_norm(*std);
+
+ mutex_unlock(&lw->lock);
+
+ return err;
+}
+
+static int timblogiw_enuminput(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ struct video_device *vdev = video_devdata(file);
+ int i;
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ if (inp->index != 0)
+ return -EINVAL;
+
+ memset(inp, 0, sizeof(*inp));
+ inp->index = 0;
+
+ strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1);
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+
+ inp->std = 0;
+ for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
+ inp->std |= timblogiw_tvnorms[i].std;
+
+ return 0;
+}
+
+static int timblogiw_g_input(struct file *file, void *priv,
+ unsigned int *input)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ *input = 0;
+
+ return 0;
+}
+
+static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ if (input != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int timblogiw_streamon(struct file *file, void *priv, unsigned int type)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dev_dbg(&vdev->dev, "%s - No capture device\n", __func__);
+ return -EINVAL;
+ }
+
+ fh->frame_count = 0;
+ return videobuf_streamon(&fh->vb_vidq);
+}
+
+static int timblogiw_streamoff(struct file *file, void *priv,
+ unsigned int type)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s entry\n", __func__);
+
+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ return videobuf_streamoff(&fh->vb_vidq);
+}
+
+static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s entry\n", __func__);
+
+ if (TIMBLOGIW_HAS_DECODER(lw))
+ return v4l2_subdev_call(lw->sd_enc, video, querystd, std);
+ else {
+ *std = fh->cur_norm->std;
+ return 0;
+ }
+}
+
+static int timblogiw_enum_framesizes(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = priv;
+
+ dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__,
+ fsize->index, fsize->pixel_format);
+
+ if ((fsize->index != 0) ||
+ (fsize->pixel_format != V4L2_PIX_FMT_UYVY))
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = fh->cur_norm->width;
+ fsize->discrete.height = fh->cur_norm->height;
+
+ return 0;
+}
+
+/* Video buffer functions */
+
+static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+
+ *size = timblogiw_frame_size(fh->cur_norm);
+
+ if (!*count)
+ *count = 32;
+
+ while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024)
+ (*count)--;
+
+ return 0;
+}
+
+static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+ struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
+ vb);
+ unsigned int data_size = timblogiw_frame_size(fh->cur_norm);
+ int err = 0;
+
+ if (vb->baddr && vb->bsize < data_size)
+ /* User provided buffer, but it is too small */
+ return -ENOMEM;
+
+ vb->size = data_size;
+ vb->width = fh->cur_norm->width;
+ vb->height = fh->cur_norm->height;
+ vb->field = field;
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ int i;
+ unsigned int size;
+ unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
+ timblogiw_bytes_per_line(fh->cur_norm);
+ dma_addr_t addr;
+
+ sg_init_table(buf->sg, ARRAY_SIZE(buf->sg));
+
+ err = videobuf_iolock(vq, vb, NULL);
+ if (err)
+ goto err;
+
+ addr = videobuf_to_dma_contig(vb);
+ for (i = 0, size = 0; size < data_size; i++) {
+ sg_dma_address(buf->sg + i) = addr + size;
+ size += bytes_per_desc;
+ sg_dma_len(buf->sg + i) = (size > data_size) ?
+ (bytes_per_desc - (size - data_size)) :
+ bytes_per_desc;
+ }
+
+ vb->state = VIDEOBUF_PREPARED;
+ buf->cookie = -1;
+ buf->fh = fh;
+ }
+
+ return 0;
+
+err:
+ videobuf_dma_contig_free(vq, vb);
+ vb->state = VIDEOBUF_NEEDS_INIT;
+ return err;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+ struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
+ vb);
+ struct dma_async_tx_descriptor *desc;
+ int sg_elems;
+ int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
+ timblogiw_bytes_per_line(fh->cur_norm);
+
+ sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc;
+ sg_elems +=
+ (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0;
+
+ if (list_empty(&fh->capture))
+ vb->state = VIDEOBUF_ACTIVE;
+ else
+ vb->state = VIDEOBUF_QUEUED;
+
+ list_add_tail(&vb->queue, &fh->capture);
+
+ spin_unlock_irq(&fh->queue_lock);
+
+ desc = fh->chan->device->device_prep_slave_sg(fh->chan,
+ buf->sg, sg_elems, DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
+ if (!desc) {
+ spin_lock_irq(&fh->queue_lock);
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_PREPARED;
+ return;
+ }
+
+ desc->callback_param = buf;
+ desc->callback = timblogiw_dma_cb;
+
+ buf->cookie = desc->tx_submit(desc);
+
+ spin_lock_irq(&fh->queue_lock);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct timblogiw_fh *fh = vq->priv_data;
+ struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
+ vb);
+
+ videobuf_waiton(vq, vb, 0, 0);
+ if (buf->cookie >= 0)
+ dma_sync_wait(fh->chan, buf->cookie);
+
+ videobuf_dma_contig_free(vq, vb);
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static struct videobuf_queue_ops timblogiw_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+/* Device Operations functions */
+
+static int timblogiw_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh;
+ v4l2_std_id std;
+ dma_cap_mask_t mask;
+ int err = 0;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ mutex_lock(&lw->lock);
+ if (lw->opened) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) {
+ struct i2c_adapter *adapt;
+
+ /* find the video decoder */
+ adapt = i2c_get_adapter(lw->pdata.i2c_adapter);
+ if (!adapt) {
+ dev_err(&vdev->dev, "No I2C bus #%d\n",
+ lw->pdata.i2c_adapter);
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* now find the encoder */
+ lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt,
+ lw->pdata.encoder.info, NULL);
+
+ i2c_put_adapter(adapt);
+
+ if (!lw->sd_enc) {
+ dev_err(&vdev->dev, "Failed to get encoder: %s\n",
+ lw->pdata.encoder.module_name);
+ err = -ENODEV;
+ goto out;
+ }
+ }
+
+ fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+ if (!fh) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ fh->cur_norm = timblogiw_tvnorms;
+ timblogiw_querystd(file, fh, &std);
+ fh->cur_norm = timblogiw_get_norm(std);
+
+ INIT_LIST_HEAD(&fh->capture);
+ spin_lock_init(&fh->queue_lock);
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+
+ /* find the DMA channel */
+ fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn,
+ (void *)lw->pdata.dma_channel);
+ if (!fh->chan) {
+ dev_err(&vdev->dev, "Failed to get DMA channel\n");
+ kfree(fh);
+ err = -ENODEV;
+ goto out;
+ }
+
+ file->private_data = fh;
+ videobuf_queue_dma_contig_init(&fh->vb_vidq,
+ &timblogiw_video_qops, lw->dev, &fh->queue_lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
+ sizeof(struct timblogiw_buffer), fh, NULL);
+
+ lw->opened = true;
+out:
+ mutex_unlock(&lw->lock);
+
+ return err;
+}
+
+static int timblogiw_close(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw *lw = video_get_drvdata(vdev);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
+
+ videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
+
+ dma_release_channel(fh->chan);
+
+ kfree(fh);
+
+ mutex_lock(&lw->lock);
+ lw->opened = false;
+ mutex_unlock(&lw->lock);
+ return 0;
+}
+
+static ssize_t timblogiw_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
+ file->f_flags & O_NONBLOCK);
+}
+
+static unsigned int timblogiw_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_poll_stream(file, &fh->vb_vidq, wait);
+}
+
+static int timblogiw_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct timblogiw_fh *fh = file->private_data;
+
+ dev_dbg(&vdev->dev, "%s: entry\n", __func__);
+
+ return videobuf_mmap_mapper(&fh->vb_vidq, vma);
+}
+
+/* Platform device functions */
+
+static __devinitconst struct v4l2_ioctl_ops timblogiw_ioctl_ops = {
+ .vidioc_querycap = timblogiw_querycap,
+ .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt,
+ .vidioc_g_fmt_vid_cap = timblogiw_g_fmt,
+ .vidioc_try_fmt_vid_cap = timblogiw_try_fmt,
+ .vidioc_s_fmt_vid_cap = timblogiw_s_fmt,
+ .vidioc_g_parm = timblogiw_g_parm,
+ .vidioc_reqbufs = timblogiw_reqbufs,
+ .vidioc_querybuf = timblogiw_querybuf,
+ .vidioc_qbuf = timblogiw_qbuf,
+ .vidioc_dqbuf = timblogiw_dqbuf,
+ .vidioc_g_std = timblogiw_g_std,
+ .vidioc_s_std = timblogiw_s_std,
+ .vidioc_enum_input = timblogiw_enuminput,
+ .vidioc_g_input = timblogiw_g_input,
+ .vidioc_s_input = timblogiw_s_input,
+ .vidioc_streamon = timblogiw_streamon,
+ .vidioc_streamoff = timblogiw_streamoff,
+ .vidioc_querystd = timblogiw_querystd,
+ .vidioc_enum_framesizes = timblogiw_enum_framesizes,
+};
+
+static __devinitconst struct v4l2_file_operations timblogiw_fops = {
+ .owner = THIS_MODULE,
+ .open = timblogiw_open,
+ .release = timblogiw_close,
+ .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .mmap = timblogiw_mmap,
+ .read = timblogiw_read,
+ .poll = timblogiw_poll,
+};
+
+static __devinitconst struct video_device timblogiw_template = {
+ .name = TIMBLOGIWIN_NAME,
+ .fops = &timblogiw_fops,
+ .ioctl_ops = &timblogiw_ioctl_ops,
+ .release = video_device_release_empty,
+ .minor = -1,
+ .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC
+};
+
+static int __devinit timblogiw_probe(struct platform_device *pdev)
+{
+ int err;
+ struct timblogiw *lw = NULL;
+ struct timb_video_platform_data *pdata = pdev->dev.platform_data;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data\n");
+ err = -EINVAL;
+ goto err;
+ }
+
+ if (!pdata->encoder.module_name)
+ dev_info(&pdev->dev, "Running without decoder\n");
+
+ lw = kzalloc(sizeof(*lw), GFP_KERNEL);
+ if (!lw) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ if (pdev->dev.parent)
+ lw->dev = pdev->dev.parent;
+ else
+ lw->dev = &pdev->dev;
+
+ memcpy(&lw->pdata, pdata, sizeof(lw->pdata));
+
+ mutex_init(&lw->lock);
+
+ lw->video_dev = timblogiw_template;
+
+ strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name));
+ err = v4l2_device_register(NULL, &lw->v4l2_dev);
+ if (err)
+ goto err_register;
+
+ lw->video_dev.v4l2_dev = &lw->v4l2_dev;
+
+ platform_set_drvdata(pdev, lw);
+ video_set_drvdata(&lw->video_dev, lw);
+
+ err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0);
+ if (err) {
+ dev_err(&pdev->dev, "Error reg video: %d\n", err);
+ goto err_request;
+ }
+
+
+ return 0;
+
+err_request:
+ platform_set_drvdata(pdev, NULL);
+ v4l2_device_unregister(&lw->v4l2_dev);
+err_register:
+ kfree(lw);
+err:
+ dev_err(&pdev->dev, "Failed to register: %d\n", err);
+
+ return err;
+}
+
+static int __devexit timblogiw_remove(struct platform_device *pdev)
+{
+ struct timblogiw *lw = platform_get_drvdata(pdev);
+
+ video_unregister_device(&lw->video_dev);
+
+ v4l2_device_unregister(&lw->v4l2_dev);
+
+ kfree(lw);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver timblogiw_platform_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = timblogiw_probe,
+ .remove = __devexit_p(timblogiw_remove),
+};
+
+/* Module functions */
+
+static int __init timblogiw_init(void)
+{
+ return platform_driver_register(&timblogiw_platform_driver);
+}
+
+static void __exit timblogiw_exit(void)
+{
+ platform_driver_unregister(&timblogiw_platform_driver);
+}
+
+module_init(timblogiw_init);
+module_exit(timblogiw_exit);
+
+MODULE_DESCRIPTION(TIMBLOGIWIN_NAME);
+MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/video/tlg2300/Kconfig
index 1686ebfa6951..645d915267e6 100644
--- a/drivers/media/video/tlg2300/Kconfig
+++ b/drivers/media/video/tlg2300/Kconfig
@@ -1,9 +1,9 @@
config VIDEO_TLG2300
tristate "Telegent TLG2300 USB video capture support"
- depends on VIDEO_DEV && I2C && INPUT && SND && DVB_CORE
+ depends on VIDEO_DEV && I2C && SND && DVB_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_VMALLOC
select SND_PCM
select VIDEOBUF_DVB
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index f169f7736677..59f8a9ad3796 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
}
}
-struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
+static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
__u32 v4l2_id, struct uvc_control_mapping **mapping)
{
struct uvc_control *ctrl = NULL;
@@ -944,6 +944,52 @@ done:
return ret;
}
+/*
+ * Mapping V4L2 controls to UVC controls can be straighforward if done well.
+ * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
+ * must be grouped (for instance the Red Balance, Blue Balance and Do White
+ * Balance V4L2 controls use the White Balance Component UVC control) or
+ * otherwise translated. The approach we take here is to use a translation
+ * table for the controls that can be mapped directly, and handle the others
+ * manually.
+ */
+int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+ struct v4l2_querymenu *query_menu)
+{
+ struct uvc_menu_info *menu_info;
+ struct uvc_control_mapping *mapping;
+ struct uvc_control *ctrl;
+ u32 index = query_menu->index;
+ u32 id = query_menu->id;
+ int ret;
+
+ memset(query_menu, 0, sizeof(*query_menu));
+ query_menu->id = id;
+ query_menu->index = index;
+
+ ret = mutex_lock_interruptible(&chain->ctrl_mutex);
+ if (ret < 0)
+ return -ERESTARTSYS;
+
+ ctrl = uvc_find_control(chain, query_menu->id, &mapping);
+ if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (query_menu->index >= mapping->menu_count) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ menu_info = &mapping->menu_info[query_menu->index];
+ strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
+
+done:
+ mutex_unlock(&chain->ctrl_mutex);
+ return ret;
+}
+
/* --------------------------------------------------------------------------
* Control transactions
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index ed6d5449741c..f14581bd707f 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -90,6 +90,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
}
/*
+ * Free the video buffers.
+ *
+ * This function must be called with the queue lock held.
+ */
+static int __uvc_free_buffers(struct uvc_video_queue *queue)
+{
+ unsigned int i;
+
+ for (i = 0; i < queue->count; ++i) {
+ if (queue->buffer[i].vma_use_count != 0)
+ return -EBUSY;
+ }
+
+ if (queue->count) {
+ vfree(queue->mem);
+ queue->count = 0;
+ }
+
+ return 0;
+}
+
+int uvc_free_buffers(struct uvc_video_queue *queue)
+{
+ int ret;
+
+ mutex_lock(&queue->mutex);
+ ret = __uvc_free_buffers(queue);
+ mutex_unlock(&queue->mutex);
+
+ return ret;
+}
+
+/*
* Allocate the video buffers.
*
* Pages are reserved to make sure they will not be swapped, as they will be
@@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
mutex_lock(&queue->mutex);
- if ((ret = uvc_free_buffers(queue)) < 0)
+ if ((ret = __uvc_free_buffers(queue)) < 0)
goto done;
/* Bail out if no buffers should be allocated. */
@@ -152,28 +185,6 @@ done:
}
/*
- * Free the video buffers.
- *
- * This function must be called with the queue lock held.
- */
-int uvc_free_buffers(struct uvc_video_queue *queue)
-{
- unsigned int i;
-
- for (i = 0; i < queue->count; ++i) {
- if (queue->buffer[i].vma_use_count != 0)
- return -EBUSY;
- }
-
- if (queue->count) {
- vfree(queue->mem);
- queue->count = 0;
- }
-
- return 0;
-}
-
-/*
* Check if buffers have been allocated.
*/
int uvc_queue_allocated(struct uvc_video_queue *queue)
@@ -369,6 +380,82 @@ done:
}
/*
+ * VMA operations.
+ */
+static void uvc_vm_open(struct vm_area_struct *vma)
+{
+ struct uvc_buffer *buffer = vma->vm_private_data;
+ buffer->vma_use_count++;
+}
+
+static void uvc_vm_close(struct vm_area_struct *vma)
+{
+ struct uvc_buffer *buffer = vma->vm_private_data;
+ buffer->vma_use_count--;
+}
+
+static const struct vm_operations_struct uvc_vm_ops = {
+ .open = uvc_vm_open,
+ .close = uvc_vm_close,
+};
+
+/*
+ * Memory-map a video buffer.
+ *
+ * This function implements video buffers memory mapping and is intended to be
+ * used by the device mmap handler.
+ */
+int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
+{
+ struct uvc_buffer *uninitialized_var(buffer);
+ struct page *page;
+ unsigned long addr, start, size;
+ unsigned int i;
+ int ret = 0;
+
+ start = vma->vm_start;
+ size = vma->vm_end - vma->vm_start;
+
+ mutex_lock(&queue->mutex);
+
+ for (i = 0; i < queue->count; ++i) {
+ buffer = &queue->buffer[i];
+ if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
+ break;
+ }
+
+ if (i == queue->count || size != queue->buf_size) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /*
+ * VM_IO marks the area as being an mmaped region for I/O to a
+ * device. It also prevents the region from being core dumped.
+ */
+ vma->vm_flags |= VM_IO;
+
+ addr = (unsigned long)queue->mem + buffer->buf.m.offset;
+ while (size > 0) {
+ page = vmalloc_to_page((void *)addr);
+ if ((ret = vm_insert_page(vma, start, page)) < 0)
+ goto done;
+
+ start += PAGE_SIZE;
+ addr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vma->vm_ops = &uvc_vm_ops;
+ vma->vm_private_data = buffer;
+ uvc_vm_open(vma);
+
+done:
+ mutex_unlock(&queue->mutex);
+ return ret;
+}
+
+/*
* Poll the video queue.
*
* This function implements video queue polling and is intended to be used by
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 6d15de9b5204..8cf61e8a634f 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -101,40 +101,6 @@ done:
*/
/*
- * Mapping V4L2 controls to UVC controls can be straighforward if done well.
- * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
- * must be grouped (for instance the Red Balance, Blue Balance and Do White
- * Balance V4L2 controls use the White Balance Component UVC control) or
- * otherwise translated. The approach we take here is to use a translation
- * table for the controls that can be mapped directly, and handle the others
- * manually.
- */
-static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
- struct v4l2_querymenu *query_menu)
-{
- struct uvc_menu_info *menu_info;
- struct uvc_control_mapping *mapping;
- struct uvc_control *ctrl;
- u32 index = query_menu->index;
- u32 id = query_menu->id;
-
- ctrl = uvc_find_control(chain, query_menu->id, &mapping);
- if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
- return -EINVAL;
-
- if (query_menu->index >= mapping->menu_count)
- return -EINVAL;
-
- memset(query_menu, 0, sizeof(*query_menu));
- query_menu->id = id;
- query_menu->index = index;
-
- menu_info = &mapping->menu_info[query_menu->index];
- strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
- return 0;
-}
-
-/*
* Find the frame interval closest to the requested frame interval for the
* given frame format and size. This should be done by the device as part of
* the Video Probe and Commit negotiation, but some hardware don't implement
@@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
* developers test their webcams with the Linux driver as well as with
* the Windows driver).
*/
+ mutex_lock(&stream->mutex);
if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
probe->dwMaxVideoFrameSize =
stream->ctrl.dwMaxVideoFrameSize;
/* Probe the device. */
ret = uvc_probe_video(stream, probe);
+ mutex_unlock(&stream->mutex);
if (ret < 0)
goto done;
@@ -289,14 +257,21 @@ done:
static int uvc_v4l2_get_format(struct uvc_streaming *stream,
struct v4l2_format *fmt)
{
- struct uvc_format *format = stream->cur_format;
- struct uvc_frame *frame = stream->cur_frame;
+ struct uvc_format *format;
+ struct uvc_frame *frame;
+ int ret = 0;
if (fmt->type != stream->type)
return -EINVAL;
- if (format == NULL || frame == NULL)
- return -EINVAL;
+ mutex_lock(&stream->mutex);
+ format = stream->cur_format;
+ frame = stream->cur_frame;
+
+ if (format == NULL || frame == NULL) {
+ ret = -EINVAL;
+ goto done;
+ }
fmt->fmt.pix.pixelformat = format->fcc;
fmt->fmt.pix.width = frame->wWidth;
@@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream,
fmt->fmt.pix.colorspace = format->colorspace;
fmt->fmt.pix.priv = 0;
- return 0;
+done:
+ mutex_unlock(&stream->mutex);
+ return ret;
}
static int uvc_v4l2_set_format(struct uvc_streaming *stream,
@@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream,
if (fmt->type != stream->type)
return -EINVAL;
- if (uvc_queue_allocated(&stream->queue))
- return -EBUSY;
-
ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
if (ret < 0)
return ret;
+ mutex_lock(&stream->mutex);
+
+ if (uvc_queue_allocated(&stream->queue)) {
+ ret = -EBUSY;
+ goto done;
+ }
+
memcpy(&stream->ctrl, &probe, sizeof probe);
stream->cur_format = format;
stream->cur_frame = frame;
- return 0;
+done:
+ mutex_unlock(&stream->mutex);
+ return ret;
}
static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
@@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
if (parm->type != stream->type)
return -EINVAL;
+ mutex_lock(&stream->mutex);
numerator = stream->ctrl.dwFrameInterval;
+ mutex_unlock(&stream->mutex);
+
denominator = 10000000;
uvc_simplify_fraction(&numerator, &denominator, 8, 333);
@@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
struct v4l2_streamparm *parm)
{
- struct uvc_frame *frame = stream->cur_frame;
struct uvc_streaming_control probe;
struct v4l2_fract timeperframe;
uint32_t interval;
@@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
if (parm->type != stream->type)
return -EINVAL;
- if (uvc_queue_streaming(&stream->queue))
- return -EBUSY;
-
if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
timeperframe = parm->parm.capture.timeperframe;
else
timeperframe = parm->parm.output.timeperframe;
- memcpy(&probe, &stream->ctrl, sizeof probe);
interval = uvc_fraction_to_interval(timeperframe.numerator,
timeperframe.denominator);
-
uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
timeperframe.numerator, timeperframe.denominator, interval);
- probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
+
+ mutex_lock(&stream->mutex);
+
+ if (uvc_queue_streaming(&stream->queue)) {
+ mutex_unlock(&stream->mutex);
+ return -EBUSY;
+ }
+
+ memcpy(&probe, &stream->ctrl, sizeof probe);
+ probe.dwFrameInterval =
+ uvc_try_frame_interval(stream->cur_frame, interval);
/* Probe the device with the new settings. */
ret = uvc_probe_video(stream, &probe);
- if (ret < 0)
+ if (ret < 0) {
+ mutex_unlock(&stream->mutex);
return ret;
+ }
memcpy(&stream->ctrl, &probe, sizeof probe);
+ mutex_unlock(&stream->mutex);
/* Return the actual frame period. */
timeperframe.numerator = probe.dwFrameInterval;
@@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file)
if (uvc_has_privileges(handle)) {
uvc_video_enable(stream, 0);
- mutex_lock(&stream->queue.mutex);
if (uvc_free_buffers(&stream->queue) < 0)
uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
"free buffers.\n");
- mutex_unlock(&stream->queue.mutex);
}
/* Release the file handle. */
@@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
}
case VIDIOC_QUERYMENU:
- return uvc_v4l2_query_menu(chain, arg);
+ return uvc_query_v4l2_menu(chain, arg);
case VIDIOC_G_EXT_CTRLS:
{
@@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_CROPCAP:
{
struct v4l2_cropcap *ccap = arg;
- struct uvc_frame *frame = stream->cur_frame;
if (ccap->type != stream->type)
return -EINVAL;
ccap->bounds.left = 0;
ccap->bounds.top = 0;
- ccap->bounds.width = frame->wWidth;
- ccap->bounds.height = frame->wHeight;
+
+ mutex_lock(&stream->mutex);
+ ccap->bounds.width = stream->cur_frame->wWidth;
+ ccap->bounds.height = stream->cur_frame->wHeight;
+ mutex_unlock(&stream->mutex);
ccap->defrect = ccap->bounds;
@@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_REQBUFS:
{
struct v4l2_requestbuffers *rb = arg;
- unsigned int bufsize =
- stream->ctrl.dwMaxVideoFrameSize;
if (rb->type != stream->type ||
rb->memory != V4L2_MEMORY_MMAP)
@@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if ((ret = uvc_acquire_privileges(handle)) < 0)
return ret;
- ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
+ mutex_lock(&stream->mutex);
+ ret = uvc_alloc_buffers(&stream->queue, rb->count,
+ stream->ctrl.dwMaxVideoFrameSize);
+ mutex_unlock(&stream->mutex);
if (ret < 0)
return ret;
@@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if (!uvc_has_privileges(handle))
return -EBUSY;
+ mutex_lock(&stream->mutex);
ret = uvc_video_enable(stream, 1);
+ mutex_unlock(&stream->mutex);
if (ret < 0)
return ret;
break;
@@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
return -EINVAL;
}
-/*
- * VMA operations.
- */
-static void uvc_vm_open(struct vm_area_struct *vma)
-{
- struct uvc_buffer *buffer = vma->vm_private_data;
- buffer->vma_use_count++;
-}
-
-static void uvc_vm_close(struct vm_area_struct *vma)
-{
- struct uvc_buffer *buffer = vma->vm_private_data;
- buffer->vma_use_count--;
-}
-
-static const struct vm_operations_struct uvc_vm_ops = {
- .open = uvc_vm_open,
- .close = uvc_vm_close,
-};
-
static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
{
struct uvc_fh *handle = file->private_data;
struct uvc_streaming *stream = handle->stream;
- struct uvc_video_queue *queue = &stream->queue;
- struct uvc_buffer *uninitialized_var(buffer);
- struct page *page;
- unsigned long addr, start, size;
- unsigned int i;
- int ret = 0;
uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
- start = vma->vm_start;
- size = vma->vm_end - vma->vm_start;
-
- mutex_lock(&queue->mutex);
-
- for (i = 0; i < queue->count; ++i) {
- buffer = &queue->buffer[i];
- if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
-
- if (i == queue->count || size != queue->buf_size) {
- ret = -EINVAL;
- goto done;
- }
-
- /*
- * VM_IO marks the area as being an mmaped region for I/O to a
- * device. It also prevents the region from being core dumped.
- */
- vma->vm_flags |= VM_IO;
-
- addr = (unsigned long)queue->mem + buffer->buf.m.offset;
- while (size > 0) {
- page = vmalloc_to_page((void *)addr);
- if ((ret = vm_insert_page(vma, start, page)) < 0)
- goto done;
-
- start += PAGE_SIZE;
- addr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &uvc_vm_ops;
- vma->vm_private_data = buffer;
- uvc_vm_open(vma);
-
-done:
- mutex_unlock(&queue->mutex);
- return ret;
+ return uvc_queue_mmap(&stream->queue, vma);
}
static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
@@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = {
.owner = THIS_MODULE,
.open = uvc_v4l2_open,
.release = uvc_v4l2_release,
- .ioctl = uvc_v4l2_ioctl,
+ .unlocked_ioctl = uvc_v4l2_ioctl,
.read = uvc_v4l2_read,
.mmap = uvc_v4l2_mmap,
.poll = uvc_v4l2_poll,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 5555f0102838..5673d673504b 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
unsigned int i;
int ret;
- mutex_lock(&stream->mutex);
-
/* Perform probing. The device should adjust the requested values
* according to its capabilities. However, some devices, namely the
* first generation UVC Logitech webcams, don't implement the Video
@@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
}
done:
- mutex_unlock(&stream->mutex);
return ret;
}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index d97cf6d6a4f9..45f01e7e13d2 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -436,7 +436,9 @@ struct uvc_streaming {
struct uvc_streaming_control ctrl;
struct uvc_format *cur_format;
struct uvc_frame *cur_frame;
-
+ /* Protect access to ctrl, cur_format, cur_frame and hardware video
+ * probe control.
+ */
struct mutex mutex;
unsigned int frozen : 1;
@@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf);
+extern int uvc_queue_mmap(struct uvc_video_queue *queue,
+ struct vm_area_struct *vma);
extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
struct file *file, poll_table *wait);
extern int uvc_queue_allocated(struct uvc_video_queue *queue);
@@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev);
extern int uvc_status_resume(struct uvc_device *dev);
/* Controls */
-extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
- __u32 v4l2_id, struct uvc_control_mapping **mapping);
extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
struct v4l2_queryctrl *v4l2_ctrl);
+extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+ struct v4l2_querymenu *query_menu);
extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
const struct uvc_control_mapping *mapping);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 03f7f4670e9b..359e23290a7e 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
size_t sz, loff_t *off)
{
struct video_device *vdev = video_devdata(filp);
- int ret = -EIO;
+ int ret = -ENODEV;
if (!vdev->fops->read)
return -EINVAL;
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->read(filp, buf, sz, off);
if (vdev->lock)
@@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
size_t sz, loff_t *off)
{
struct video_device *vdev = video_devdata(filp);
- int ret = -EIO;
+ int ret = -ENODEV;
if (!vdev->fops->write)
return -EINVAL;
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->write(filp, buf, sz, off);
if (vdev->lock)
@@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
{
struct video_device *vdev = video_devdata(filp);
- int ret = DEFAULT_POLLMASK;
+ int ret = POLLERR | POLLHUP;
if (!vdev->fops->poll)
- return ret;
+ return DEFAULT_POLLMASK;
if (vdev->lock)
mutex_lock(vdev->lock);
if (video_is_registered(vdev))
@@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
int ret = -ENODEV;
if (vdev->fops->unlocked_ioctl) {
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
if (vdev->lock)
mutex_unlock(vdev->lock);
} else if (vdev->fops->ioctl) {
- /* TODO: convert all drivers to unlocked_ioctl */
+ /* This code path is a replacement for the BKL. It is a major
+ * hack but it will have to do for those drivers that are not
+ * yet converted to use unlocked_ioctl.
+ *
+ * There are two options: if the driver implements struct
+ * v4l2_device, then the lock defined there is used to
+ * serialize the ioctls. Otherwise the v4l2 core lock defined
+ * below is used. This lock is really bad since it serializes
+ * completely independent devices.
+ *
+ * Both variants suffer from the same problem: if the driver
+ * sleeps, then it blocks all ioctls since the lock is still
+ * held. This is very common for VIDIOC_DQBUF since that
+ * normally waits for a frame to arrive. As a result any other
+ * ioctl calls will proceed very, very slowly since each call
+ * will have to wait for the VIDIOC_QBUF to finish. Things that
+ * should take 0.01s may now take 10-20 seconds.
+ *
+ * The workaround is to *not* take the lock for VIDIOC_DQBUF.
+ * This actually works OK for videobuf-based drivers, since
+ * videobuf will take its own internal lock.
+ */
static DEFINE_MUTEX(v4l2_ioctl_mutex);
+ struct mutex *m = vdev->v4l2_dev ?
+ &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
- mutex_lock(&v4l2_ioctl_mutex);
+ if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->ioctl(filp, cmd, arg);
- mutex_unlock(&v4l2_ioctl_mutex);
+ if (cmd != VIDIOC_DQBUF)
+ mutex_unlock(m);
} else
ret = -ENOTTY;
@@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
if (!vdev->fops->mmap)
return ret;
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->mmap(filp, vm);
if (vdev->lock)
@@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
mutex_lock(&videodev_lock);
vdev = video_devdata(filp);
/* return ENODEV if the video device has already been removed. */
- if (vdev == NULL) {
+ if (vdev == NULL || !video_is_registered(vdev)) {
mutex_unlock(&videodev_lock);
return -ENODEV;
}
@@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp)
video_get(vdev);
mutex_unlock(&videodev_lock);
if (vdev->fops->open) {
- if (vdev->lock)
- mutex_lock(vdev->lock);
+ if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
+ ret = -ERESTARTSYS;
+ goto err;
+ }
if (video_is_registered(vdev))
ret = vdev->fops->open(filp);
else
@@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
mutex_unlock(vdev->lock);
}
+err:
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
@@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev)
if (!vdev || !video_is_registered(vdev))
return;
+ mutex_lock(&videodev_lock);
+ /* This must be in a critical section to prevent a race with v4l2_open.
+ * Once this bit has been cleared video_get may never be called again.
+ */
clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
+ mutex_unlock(&videodev_lock);
device_unregister(&vdev->dev);
}
EXPORT_SYMBOL(video_unregister_device);
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 0b08f96b74a5..7fe6f92af480 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
+ mutex_init(&v4l2_dev->ioctl_lock);
v4l2_dev->dev = dev;
if (dev == NULL) {
/* If dev == NULL, then name must be filled in by the caller */
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 20f227ee2b3e..ab684e807034 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -69,10 +69,9 @@ static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt,
struct page *pg;
int i;
- sglist = vmalloc(nr_pages * sizeof(*sglist));
+ sglist = vzalloc(nr_pages * sizeof(*sglist));
if (NULL == sglist)
return NULL;
- memset(sglist, 0, nr_pages * sizeof(*sglist));
sg_init_table(sglist, nr_pages);
for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
pg = vmalloc_to_page(virt);
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 635420d8d84a..019ee206cbee 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -815,7 +815,7 @@ out:
static const struct v4l2_file_operations w9966_fops = {
.owner = THIS_MODULE,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
.read = w9966_v4l_read,
};
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 727f62c15a60..6ad8a7f8d390 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -40,6 +40,7 @@
#include <linux/spi/mc33880.h>
#include <media/timb_radio.h>
+#include <media/timb_video.h>
#include <linux/timb_dma.h>
@@ -246,7 +247,23 @@ static const __devinitconst struct resource timberdale_uartlite_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_radio_resources[] = {
+static __devinitdata struct i2c_board_info timberdale_adv7180_i2c_board_info = {
+ /* Requires jumper JP9 to be off */
+ I2C_BOARD_INFO("adv7180", 0x42 >> 1),
+ .irq = IRQ_TIMBERDALE_ADV7180
+};
+
+static __devinitdata struct timb_video_platform_data
+ timberdale_video_platform_data = {
+ .dma_channel = DMA_VIDEO_RX,
+ .i2c_adapter = 0,
+ .encoder = {
+ .info = &timberdale_adv7180_i2c_board_info
+ }
+};
+
+static const __devinitconst struct resource
+timberdale_radio_resources[] = {
{
.start = RDSOFFSET,
.end = RDSEND,
@@ -271,15 +288,25 @@ static __devinitdata struct timb_radio_platform_data
timberdale_radio_platform_data = {
.i2c_adapter = 0,
.tuner = {
- .module_name = "tef6862",
.info = &timberdale_tef6868_i2c_board_info
},
.dsp = {
- .module_name = "saa7706h",
.info = &timberdale_saa7706_i2c_board_info
}
};
+static const __devinitconst struct resource timberdale_video_resources[] = {
+ {
+ .start = LOGIWOFFSET,
+ .end = LOGIWEND,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ note that the "frame buffer" is located in DMA area
+ starting at 0x1200000
+ */
+};
+
static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = {
.nr_channels = 10,
.channels = {
@@ -380,6 +407,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
.data_size = sizeof(timberdale_gpio_platform_data),
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
@@ -440,6 +474,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
.resources = timberdale_mlogicore_resources,
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
@@ -490,6 +531,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
.data_size = sizeof(timberdale_gpio_platform_data),
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
@@ -533,6 +581,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
.data_size = sizeof(timberdale_gpio_platform_data),
},
{
+ .name = "timb-video",
+ .num_resources = ARRAY_SIZE(timberdale_video_resources),
+ .resources = timberdale_video_resources,
+ .platform_data = &timberdale_video_platform_data,
+ .data_size = sizeof(timberdale_video_platform_data),
+ },
+ {
.name = "timb-radio",
.num_resources = ARRAY_SIZE(timberdale_radio_resources),
.resources = timberdale_radio_resources,
diff --git a/drivers/mfd/timberdale.h b/drivers/mfd/timberdale.h
index c11bf6ebfe00..4412acd826fa 100644
--- a/drivers/mfd/timberdale.h
+++ b/drivers/mfd/timberdale.h
@@ -23,7 +23,7 @@
#ifndef MFD_TIMBERDALE_H
#define MFD_TIMBERDALE_H
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
/* This driver only support versions >= 3.8 and < 4.0 */
#define TIMB_SUPPORTED_MAJOR 3
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
index 1d73334d2a44..b2656957aa8f 100644
--- a/drivers/staging/cx25821/Kconfig
+++ b/drivers/staging/cx25821/Kconfig
@@ -1,11 +1,11 @@
config VIDEO_CX25821
tristate "Conexant cx25821 support"
- depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
+ depends on DVB_CORE && VIDEO_DEV && PCI && I2C
depends on BKL # please fix
select I2C_ALGOBIT
select VIDEO_BTCX
select VIDEO_TVEEPROM
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEOBUF_DVB
select VIDEOBUF_DMA_SG
select VIDEO_CX25840
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index 2a01dc057b2c..9a205a342c55 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -20,6 +20,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
@@ -42,11 +44,16 @@
#define AUDIO_SRAM_CHANNEL SRAM_CH08
-#define dprintk(level, fmt, arg...) if (debug >= level) \
- printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
-
-#define dprintk_core(level, fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
+#define dprintk(level, fmt, arg...) \
+do { \
+ if (debug >= level) \
+ pr_info("%s/1: " fmt, chip->dev->name, ##arg); \
+} while (0)
+#define dprintk_core(level, fmt, arg...) \
+do { \
+ if (debug >= level) \
+ printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name, ##arg); \
+} while (0)
/****************************************************************************
Data type declarations - Can be moded to a header file later
@@ -173,12 +180,11 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip)
tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
FLD_AUD_CLK_ENABLE);
- /* printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line,"
- "cmds_start(0x%x)= %d lines/FIFO, %d periods, "
- "%d byte buffer\n", buf->bpl,
- audio_ch->cmds_start,
- cx_read(audio_ch->cmds_start + 12)>>1,
- chip->num_periods, buf->bpl *chip->num_periods);
+ /*
+ pr_info("DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d byte buffer\n",
+ buf->bpl, audio_ch->cmds_start,
+ cx_read(audio_ch->cmds_start + 12)>>1,
+ chip->num_periods, buf->bpl * chip->num_periods);
*/
/* Enables corresponding bits at AUD_INT_STAT */
@@ -259,8 +265,7 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status,
/* risc op code error */
if (status & AUD_INT_OPC_ERR) {
- printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",
- dev->name);
+ pr_warn("WARNING %s/1: Audio risc op code error\n", dev->name);
cx_clear(AUD_INT_DMA_CTL,
FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
@@ -269,8 +274,7 @@ static void cx25821_aud_irq(struct cx25821_audio_dev *chip, u32 status,
[AUDIO_SRAM_CHANNEL]);
}
if (status & AUD_INT_DN_SYNC) {
- printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",
- dev->name);
+ pr_warn("WARNING %s: Downstream sync error!\n", dev->name);
cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
return;
}
@@ -388,8 +392,7 @@ static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
unsigned int bpl = 0;
if (!chip) {
- printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
- " Can't proceed with open\n");
+ pr_err("DEBUG: cx25821 can't find device struct. Can't proceed with open\n");
return -ENODEV;
}
@@ -479,8 +482,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
chip->period_size, chip->num_periods,
1);
if (ret < 0) {
- printk(KERN_INFO
- "DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
+ pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
goto error;
}
@@ -608,8 +610,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
if (err < 0) {
- printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n",
- __func__);
+ pr_info("ERROR: FAILED snd_pcm_new() in %s\n", __func__);
return err;
}
pcm->private_data = chip;
@@ -674,23 +675,21 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
int err;
if (devno >= SNDRV_CARDS) {
- printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
- __func__);
+ pr_info("DEBUG ERROR: devno >= SNDRV_CARDS %s\n", __func__);
return -ENODEV;
}
if (!enable[devno]) {
++devno;
- printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
+ pr_info("DEBUG ERROR: !enable[devno] %s\n", __func__);
return -ENOENT;
}
err = snd_card_create(index[devno], id[devno], THIS_MODULE,
sizeof(struct cx25821_audio_dev), &card);
if (err < 0) {
- printk(KERN_INFO
- "DEBUG ERROR: cannot create snd_card_new in %s\n",
- __func__);
+ pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n",
+ __func__);
return err;
}
@@ -712,16 +711,15 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
if (err < 0) {
- printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n",
+ pr_err("ERROR %s: can't get IRQ %d for ALSA\n",
chip->dev->name, dev->pci->irq);
goto error;
}
err = snd_cx25821_pcm(chip, 0, "cx25821 Digital");
if (err < 0) {
- printk(KERN_INFO
- "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
- __func__);
+ pr_info("DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
+ __func__);
goto error;
}
@@ -732,13 +730,13 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
chip->iobase, chip->irq);
strcpy(card->mixername, "CX25821");
- printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n",
- card->driver, devno);
+ pr_info("%s/%i: ALSA support for cx25821 boards\n",
+ card->driver, devno);
err = snd_card_register(card);
if (err < 0) {
- printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n",
- __func__);
+ pr_info("DEBUG ERROR: cannot register sound card %s\n",
+ __func__);
goto error;
}
@@ -778,8 +776,7 @@ static int cx25821_alsa_init(void)
}
if (dev == NULL)
- printk(KERN_INFO
- "cx25821 ERROR ALSA: no cx25821 cards found\n");
+ pr_info("ERROR ALSA: no cx25821 cards found\n");
return 0;
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
index 1607b0d86e6f..7992a3ba526f 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
#include "cx25821-audio-upstream.h"
@@ -221,7 +223,7 @@ void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
if (!dev->_audio_is_running) {
printk(KERN_DEBUG
- "cx25821: No audio file is currently running so return!\n");
+ pr_fmt("No audio file is currently running so return!\n"));
return;
}
/* Disable RISC interrupts */
@@ -281,19 +283,19 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_audiofilename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR "%s: File has no file operations registered!\n",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR "%s: File has no READ operations registered!\n",
+ pr_err("%s(): File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -320,9 +322,8 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
frame_offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Audio file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+ __func__);
break;
}
}
@@ -346,7 +347,7 @@ static void cx25821_audioups_handler(struct work_struct *work)
container_of(work, struct cx25821_dev, _audio_work_entry);
if (!dev) {
- printk(KERN_ERR "ERROR %s(): since container_of(work_struct) FAILED!\n",
+ pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
__func__);
return;
}
@@ -373,19 +374,19 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_audiofilename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR "%s: File has no file operations registered!\n",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR "%s: File has no READ operations registered!\n",
+ pr_err("%s(): File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -414,9 +415,8 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Audio file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+ __func__);
break;
}
}
@@ -459,7 +459,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
if (!dev->_risc_virt_addr) {
printk(KERN_DEBUG
- "cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
+ pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n"));
return -ENOMEM;
}
/* Clear out memory at address */
@@ -474,7 +474,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
if (!dev->_audiodata_buf_virt_addr) {
printk(KERN_DEBUG
- "cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning.\n");
+ pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n"));
return -ENOMEM;
}
/* Clear out memory at address */
@@ -490,7 +490,7 @@ static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
dev->_audio_lines_count);
if (ret < 0) {
printk(KERN_DEBUG
- "cx25821 ERROR creating audio upstream RISC programs!\n");
+ pr_fmt("ERROR creating audio upstream RISC programs!\n"));
goto error;
}
@@ -569,16 +569,16 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
spin_unlock(&dev->slock);
} else {
if (status & FLD_AUD_SRC_OF)
- printk(KERN_WARNING "%s: Audio Received Overflow Error Interrupt!\n",
- __func__);
+ pr_warn("%s(): Audio Received Overflow Error Interrupt!\n",
+ __func__);
if (status & FLD_AUD_SRC_SYNC)
- printk(KERN_WARNING "%s: Audio Received Sync Error Interrupt!\n",
- __func__);
+ pr_warn("%s(): Audio Received Sync Error Interrupt!\n",
+ __func__);
if (status & FLD_AUD_SRC_OPC_ERR)
- printk(KERN_WARNING "%s: Audio Received OpCode Error Interrupt!\n",
- __func__);
+ pr_warn("%s(): Audio Received OpCode Error Interrupt!\n",
+ __func__);
/* Read and write back the interrupt status register to clear
* our bits */
@@ -586,8 +586,8 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
}
if (dev->_audiofile_status == END_OF_FILE) {
- printk(KERN_WARNING "cx25821: EOF Channel Audio Framecount = %d\n",
- dev->_audioframe_count);
+ pr_warn("EOF Channel Audio Framecount = %d\n",
+ dev->_audioframe_count);
return -1;
}
/* ElSE, set the interrupt mask register, re-enable irq. */
@@ -644,9 +644,8 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
/* 10 millisecond timeout */
if (count++ > 1000) {
- printk(KERN_ERR
- "cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
- __func__);
+ pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n",
+ __func__);
return;
}
@@ -696,8 +695,8 @@ int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
+ pr_err("%s: can't get upstream IRQ %d\n",
+ dev->name, dev->pci->irq);
goto fail_irq;
}
@@ -726,7 +725,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
int str_length = 0;
if (dev->_audio_is_running) {
- printk(KERN_WARNING "Audio Channel is still running so return!\n");
+ pr_warn("Audio Channel is still running so return!\n");
return 0;
}
@@ -740,7 +739,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
if (!dev->_irq_audio_queues) {
printk(KERN_DEBUG
- "cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
+ pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n"));
return -ENOMEM;
}
@@ -787,8 +786,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
retval =
cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
if (retval < 0) {
- printk(KERN_ERR
- "%s: Failed to set up Audio upstream buffers!\n",
+ pr_err("%s: Failed to set up Audio upstream buffers!\n",
dev->name);
goto error;
}
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
index da0f56d50e27..94e8d685c889 100644
--- a/drivers/staging/cx25821/cx25821-cards.c
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index 300da319b065..a216b620b718 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/i2c.h>
#include <linux/slab.h>
#include "cx25821.h"
@@ -332,7 +334,7 @@ struct cx25821_dmaqueue mpegq;
static int cx25821_risc_decode(u32 risc)
{
- static char *instr[16] = {
+ static const char * const instr[16] = {
[RISC_SYNC >> 28] = "sync",
[RISC_WRITE >> 28] = "write",
[RISC_WRITEC >> 28] = "writec",
@@ -344,7 +346,7 @@ static int cx25821_risc_decode(u32 risc)
[RISC_WRITECM >> 28] = "writecm",
[RISC_WRITECR >> 28] = "writecr",
};
- static int incr[16] = {
+ static const int incr[16] = {
[RISC_WRITE >> 28] = 3,
[RISC_JUMP >> 28] = 3,
[RISC_SKIP >> 28] = 1,
@@ -353,7 +355,7 @@ static int cx25821_risc_decode(u32 risc)
[RISC_WRITECM >> 28] = 3,
[RISC_WRITECR >> 28] = 4,
};
- static char *bits[] = {
+ static const char * const bits[] = {
"12", "13", "14", "resync",
"cnt0", "cnt1", "18", "19",
"20", "21", "22", "23",
@@ -361,13 +363,13 @@ static int cx25821_risc_decode(u32 risc)
};
int i;
- printk("0x%08x [ %s", risc,
- instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
+ pr_cont("0x%08x [ %s",
+ risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
if (risc & (1 << (i + 12)))
- printk(" %s", bits[i]);
+ pr_cont(" %s", bits[i]);
}
- printk(" count=%d ]\n", risc & 0xfff);
+ pr_cont(" count=%d ]\n", risc & 0xfff);
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
@@ -620,16 +622,15 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
u32 risc;
unsigned int i, j, n;
- printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name,
- ch->name);
+ pr_warn("%s: %s - dma channel status dump\n", dev->name, ch->name);
for (i = 0; i < ARRAY_SIZE(name); i++)
- printk(KERN_WARNING "cmds + 0x%2x: %-15s: 0x%08x\n", i * 4,
- name[i], cx_read(ch->cmds_start + 4 * i));
+ pr_warn("cmds + 0x%2x: %-15s: 0x%08x\n",
+ i * 4, name[i], cx_read(ch->cmds_start + 4 * i));
j = i * 4;
for (i = 0; i < 4;) {
risc = cx_read(ch->cmds_start + 4 * (i + 14));
- printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
+ pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
i += cx25821_risc_decode(risc);
}
@@ -637,36 +638,35 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
risc = cx_read(ch->ctrl_start + 4 * i);
/* No consideration for bits 63-32 */
- printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
- ch->ctrl_start + 4 * i, i);
+ pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
+ i * 4, ch->ctrl_start + 4 * i, i);
n = cx25821_risc_decode(risc);
for (j = 1; j < n; j++) {
risc = cx_read(ch->ctrl_start + 4 * (i + j));
- printk(KERN_WARNING
- "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
- 4 * (i + j), i + j, risc, j);
+ pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
+ 4 * (i + j), i + j, risc, j);
}
}
- printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
- ch->fifo_start, ch->fifo_start + ch->fifo_size);
- printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
- ch->ctrl_start, ch->ctrl_start + 6 * 16);
- printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
- cx_read(ch->ptr1_reg));
- printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
- cx_read(ch->ptr2_reg));
- printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
- cx_read(ch->cnt1_reg));
- printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
- cx_read(ch->cnt2_reg));
+ pr_warn(" : fifo: 0x%08x -> 0x%x\n",
+ ch->fifo_start, ch->fifo_start + ch->fifo_size);
+ pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
+ ch->ctrl_start, ch->ctrl_start + 6 * 16);
+ pr_warn(" : ptr1_reg: 0x%08x\n",
+ cx_read(ch->ptr1_reg));
+ pr_warn(" : ptr2_reg: 0x%08x\n",
+ cx_read(ch->ptr2_reg));
+ pr_warn(" : cnt1_reg: 0x%08x\n",
+ cx_read(ch->cnt1_reg));
+ pr_warn(" : cnt2_reg: 0x%08x\n",
+ cx_read(ch->cnt2_reg));
}
EXPORT_SYMBOL(cx25821_sram_channel_dump);
void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
struct sram_channel *ch)
{
- static char *name[] = {
+ static const char * const name[] = {
"init risc lo",
"init risc hi",
"cdt base",
@@ -686,18 +686,18 @@ void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
u32 risc, value, tmp;
unsigned int i, j, n;
- printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n",
- dev->name, ch->name);
+ pr_info("\n%s: %s - dma Audio channel status dump\n",
+ dev->name, ch->name);
for (i = 0; i < ARRAY_SIZE(name); i++)
- printk(KERN_INFO "%s: cmds + 0x%2x: %-15s: 0x%08x\n",
- dev->name, i * 4, name[i],
- cx_read(ch->cmds_start + 4 * i));
+ pr_info("%s: cmds + 0x%2x: %-15s: 0x%08x\n",
+ dev->name, i * 4, name[i],
+ cx_read(ch->cmds_start + 4 * i));
j = i * 4;
for (i = 0; i < 4;) {
risc = cx_read(ch->cmds_start + 4 * (i + 14));
- printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
+ pr_warn("cmds + 0x%2x: risc%d: ", j + i * 4, i);
i += cx25821_risc_decode(risc);
}
@@ -705,44 +705,43 @@ void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
risc = cx_read(ch->ctrl_start + 4 * i);
/* No consideration for bits 63-32 */
- printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
- ch->ctrl_start + 4 * i, i);
+ pr_warn("ctrl + 0x%2x (0x%08x): iq %x: ",
+ i * 4, ch->ctrl_start + 4 * i, i);
n = cx25821_risc_decode(risc);
for (j = 1; j < n; j++) {
risc = cx_read(ch->ctrl_start + 4 * (i + j));
- printk(KERN_WARNING
- "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
- 4 * (i + j), i + j, risc, j);
+ pr_warn("ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
+ 4 * (i + j), i + j, risc, j);
}
}
- printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
- ch->fifo_start, ch->fifo_start + ch->fifo_size);
- printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
- ch->ctrl_start, ch->ctrl_start + 6 * 16);
- printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
- cx_read(ch->ptr1_reg));
- printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
- cx_read(ch->ptr2_reg));
- printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
- cx_read(ch->cnt1_reg));
- printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
- cx_read(ch->cnt2_reg));
+ pr_warn(" : fifo: 0x%08x -> 0x%x\n",
+ ch->fifo_start, ch->fifo_start + ch->fifo_size);
+ pr_warn(" : ctrl: 0x%08x -> 0x%x\n",
+ ch->ctrl_start, ch->ctrl_start + 6 * 16);
+ pr_warn(" : ptr1_reg: 0x%08x\n",
+ cx_read(ch->ptr1_reg));
+ pr_warn(" : ptr2_reg: 0x%08x\n",
+ cx_read(ch->ptr2_reg));
+ pr_warn(" : cnt1_reg: 0x%08x\n",
+ cx_read(ch->cnt1_reg));
+ pr_warn(" : cnt2_reg: 0x%08x\n",
+ cx_read(ch->cnt2_reg));
for (i = 0; i < 4; i++) {
risc = cx_read(ch->cmds_start + 56 + (i * 4));
- printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
+ pr_warn("instruction %d = 0x%x\n", i, risc);
}
/* read data from the first cdt buffer */
risc = cx_read(AUD_A_CDT);
- printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
+ pr_warn("\nread cdt loc=0x%x\n", risc);
for (i = 0; i < 8; i++) {
n = cx_read(risc + i * 4);
- printk(KERN_WARNING "0x%x ", n);
+ pr_cont("0x%x ", n);
}
- printk(KERN_WARNING "\n\n");
+ pr_cont("\n\n");
value = cx_read(CLK_RST);
CX25821_INFO(" CLK_RST = 0x%x\n\n", value);
@@ -870,7 +869,7 @@ static int cx25821_get_resources(struct cx25821_dev *dev)
dev->name))
return 0;
- printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
+ pr_err("%s: can't get MMIO memory @ 0x%llx\n",
dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
return -EBUSY;
@@ -880,8 +879,8 @@ static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
{
dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
- printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__,
- dev->hwrevision);
+ pr_info("%s(): Hardware revision = 0x%02x\n",
+ __func__, dev->hwrevision);
}
static void cx25821_iounmap(struct cx25821_dev *dev)
@@ -901,9 +900,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
{
int io_size = 0, i;
- printk(KERN_INFO "\n***********************************\n");
- printk(KERN_INFO "cx25821 set up\n");
- printk(KERN_INFO "***********************************\n\n");
+ pr_info("\n***********************************\n");
+ pr_info("cx25821 set up\n");
+ pr_info("***********************************\n\n");
mutex_init(&dev->lock);
@@ -920,13 +919,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
if (dev->pci->device != 0x8210) {
- printk(KERN_INFO
- "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
- __func__, dev->pci->device);
+ pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n",
+ __func__, dev->pci->device);
return -1;
} else {
- printk(KERN_INFO "Athena Hardware device = 0x%02x\n",
- dev->pci->device);
+ pr_info("Athena Hardware device = 0x%02x\n", dev->pci->device);
}
/* Apply a sensible clock frequency for the PCIe bridge */
@@ -956,8 +953,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
if (cx25821_get_resources(dev) < 0) {
- printk(KERN_ERR "%s No more PCIe resources for "
- "subsystem: %04x:%04x\n",
+ pr_err("%s: No more PCIe resources for subsystem: %04x:%04x\n",
dev->name, dev->pci->subsystem_vendor,
dev->pci->subsystem_device);
@@ -985,11 +981,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->bmmio = (u8 __iomem *) dev->lmmio;
- printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- dev->name, dev->pci->subsystem_vendor,
- dev->pci->subsystem_device, cx25821_boards[dev->board].name,
- dev->board, card[dev->nr] == dev->board ?
- "insmod option" : "autodetected");
+ pr_info("%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ dev->name, dev->pci->subsystem_vendor,
+ dev->pci->subsystem_device, cx25821_boards[dev->board].name,
+ dev->board, card[dev->nr] == dev->board ?
+ "insmod option" : "autodetected");
/* init hardware */
cx25821_initialize(dev);
@@ -1004,8 +1000,7 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
cx25821_card_setup(dev);
if (medusa_video_init(dev) < 0)
- CX25821_ERR("%s() Failed to initialize medusa!\n"
- , __func__);
+ CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__);
cx25821_video_register(dev);
@@ -1017,13 +1012,12 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
if (video_register_device
(dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
cx25821_videoioctl_unregister(dev);
- printk(KERN_ERR
- "%s() Failed to register video adapter for IOCTL, so \
- unregistering videoioctl device.\n", __func__);
+ pr_err("%s(): Failed to register video adapter for IOCTL, so unregistering videoioctl device\n",
+ __func__);
}
cx25821_dev_checkrevision(dev);
- CX25821_INFO("cx25821 setup done!\n");
+ CX25821_INFO("setup done!\n");
return 0;
}
@@ -1362,20 +1356,20 @@ void cx25821_print_irqbits(char *name, char *tag, char **strings,
{
unsigned int i;
- printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
+ printk(KERN_DEBUG pr_fmt("%s: %s [0x%x]"), name, tag, bits);
for (i = 0; i < len; i++) {
if (!(bits & (1 << i)))
continue;
if (strings[i])
- printk(" %s", strings[i]);
+ pr_cont(" %s", strings[i]);
else
- printk(" %d", i);
+ pr_cont(" %d", i);
if (!(mask & (1 << i)))
continue;
- printk("*");
+ pr_cont("*");
}
- printk("\n");
+ pr_cont("\n");
}
EXPORT_SYMBOL(cx25821_print_irqbits);
@@ -1405,12 +1399,12 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
if (pci_enable_device(pci_dev)) {
err = -EIO;
- printk(KERN_INFO "pci enable failed! ");
+ pr_info("pci enable failed!\n");
goto fail_unregister_device;
}
- printk(KERN_INFO "cx25821 Athena pci enable !\n");
+ pr_info("Athena pci enable !\n");
err = cx25821_dev_setup(dev);
if (err) {
@@ -1423,14 +1417,13 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
/* print pci info */
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
- printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", dev->name,
- pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat, (unsigned long long)dev->base_io_addr);
+ pr_info("%s/0: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
+ dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
+ dev->pci_lat, (unsigned long long)dev->base_io_addr);
pci_set_master(pci_dev);
if (!pci_dma_supported(pci_dev, 0xffffffff)) {
- printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
+ pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
err = -EIO;
goto fail_irq;
}
@@ -1440,15 +1433,14 @@ static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
- pci_dev->irq);
+ pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq);
goto fail_irq;
}
return 0;
fail_irq:
- printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ !\n");
+ pr_info("cx25821_initdev() can't get IRQ !\n");
cx25821_dev_unregister(dev);
fail_unregister_pci:
@@ -1510,9 +1502,10 @@ static struct pci_driver cx25821_pci_driver = {
static int __init cx25821_init(void)
{
INIT_LIST_HEAD(&cx25821_devlist);
- printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
- (CX25821_VERSION_CODE >> 16) & 0xff,
- (CX25821_VERSION_CODE >> 8) & 0xff, CX25821_VERSION_CODE & 0xff);
+ pr_info("driver version %d.%d.%d loaded\n",
+ (CX25821_VERSION_CODE >> 16) & 0xff,
+ (CX25821_VERSION_CODE >> 8) & 0xff,
+ CX25821_VERSION_CODE & 0xff);
return pci_register_driver(&cx25821_pci_driver);
}
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
index 2b14bcca6897..130dfebebe20 100644
--- a/drivers/staging/cx25821/cx25821-i2c.c
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821.h"
#include <linux/i2c.h>
@@ -32,10 +34,11 @@ static unsigned int i2c_scan;
module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-#define dprintk(level, fmt, arg...)\
- do { if (i2c_debug >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
+#define dprintk(level, fmt, arg...) \
+do { \
+ if (i2c_debug >= level) \
+ printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \
+} while (0)
#define I2C_WAIT_DELAY 32
#define I2C_WAIT_RETRY 64
@@ -98,7 +101,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
if (!i2c_slave_did_ack(i2c_adap))
return -EIO;
- dprintk(1, "%s() returns 0\n", __func__);
+ dprintk(1, "%s(): returns 0\n", __func__);
return 0;
}
@@ -163,7 +166,7 @@ eio:
retval = -EIO;
err:
if (i2c_debug)
- printk(KERN_ERR " ERR: %d\n", retval);
+ pr_err(" ERR: %d\n", retval);
return retval;
}
@@ -187,7 +190,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
if (!i2c_slave_did_ack(i2c_adap))
return -EIO;
- dprintk(1, "%s() returns 0\n", __func__);
+ dprintk(1, "%s(): returns 0\n", __func__);
return 0;
}
@@ -227,7 +230,7 @@ eio:
retval = -EIO;
err:
if (i2c_debug)
- printk(KERN_ERR " ERR: %d\n", retval);
+ pr_err(" ERR: %d\n", retval);
return retval;
}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index 1e11e0ce2d0a..fc780d0908dc 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821.h"
#include "cx25821-medusa-video.h"
#include "cx25821-biffuncs.h"
@@ -499,9 +501,8 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width,
/* validate the width - cannot be negative */
if (width > MAX_WIDTH) {
- printk
- ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
- __func__, width, MAX_WIDTH);
+ pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
+ __func__, width, MAX_WIDTH);
width = MAX_WIDTH;
}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
index 405e2db72b0f..e2efacdfb874 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
#include "cx25821-video-upstream-ch2.h"
@@ -211,8 +213,7 @@ void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
u32 tmp = 0;
if (!dev->_is_running_ch2) {
- printk
- ("cx25821: No video file is currently running so return!\n");
+ pr_info("No video file is currently running so return!\n");
return;
}
/* Disable RISC interrupts */
@@ -301,19 +302,19 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename_ch2, open_errno);
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename_ch2, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk("%s: File has no file operations registered!",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk("%s: File has no READ operations registered!",
+ pr_err("%s(): File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -340,9 +341,8 @@ int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
frame_offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -366,8 +366,8 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work)
container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
if (!dev) {
- printk("ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
+ pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
+ __func__);
return;
}
@@ -393,21 +393,20 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk("%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename_ch2, open_errno);
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename_ch2, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk("%s: File has no file operations registered!",
+ pr_err("%s(): File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk
- ("%s: File has no READ operations registered! Returning.",
- __func__);
+ pr_err("%s(): File has no READ operations registered! Returning\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -435,9 +434,8 @@ int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -483,8 +481,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
if (!dev->_dma_virt_addr_ch2) {
- printk
- ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
return -ENOMEM;
}
@@ -504,8 +501,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
if (!dev->_data_buf_virt_addr_ch2) {
- printk
- ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for data buffer! Returning\n");
return -ENOMEM;
}
@@ -521,8 +517,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
dev->_lines_count_ch2);
if (ret < 0) {
- printk(KERN_INFO
- "cx25821: Failed creating Video Upstream Risc programs!\n");
+ pr_info("Failed creating Video Upstream Risc programs!\n");
goto error;
}
@@ -602,8 +597,8 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
}
if (dev->_file_status_ch2 == END_OF_FILE) {
- printk("cx25821: EOF Channel 2 Framecount = %d\n",
- dev->_frame_count_ch2);
+ pr_info("EOF Channel 2 Framecount = %d\n",
+ dev->_frame_count_ch2);
return -1;
}
/* ElSE, set the interrupt mask register, re-enable irq. */
@@ -714,8 +709,8 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
+ pr_err("%s: can't get upstream IRQ %d\n",
+ dev->name, dev->pci->irq);
goto fail_irq;
}
/* Start the DMA engine */
@@ -744,7 +739,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
int str_length = 0;
if (dev->_is_running_ch2) {
- printk("Video Channel is still running so return!\n");
+ pr_info("Video Channel is still running so return!\n");
return 0;
}
@@ -756,8 +751,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
create_singlethread_workqueue("cx25821_workqueue2");
if (!dev->_irq_queues_ch2) {
- printk
- ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
+ pr_err("create_singlethread_workqueue() for Video FAILED!\n");
return -ENOMEM;
}
/*
@@ -829,8 +823,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
dev->_line_size_ch2);
if (retval < 0) {
- printk(KERN_ERR
- "%s: Failed to set up Video upstream buffers!\n",
+ pr_err("%s: Failed to set up Video upstream buffers!\n",
dev->name);
goto error;
}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
index 16bf74d65912..31b4e3c74c8d 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
#include "cx25821-video-upstream.h"
@@ -257,8 +259,7 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
u32 tmp = 0;
if (!dev->_is_running) {
- printk
- (KERN_INFO "cx25821: No video file is currently running so return!\n");
+ pr_info("No video file is currently running so return!\n");
return;
}
/* Disable RISC interrupts */
@@ -346,23 +347,20 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR
- "%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename, open_errno);
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR
- "%s: File has no file operations registered!",
- __func__);
+ pr_err("%s(): File has no file operations registered!\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR
- "%s: File has no READ operations registered!",
- __func__);
+ pr_err("%s(): File has no READ operations registered!\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -388,10 +386,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
frame_offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more bytes to \
- read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -415,9 +411,8 @@ static void cx25821_vidups_handler(struct work_struct *work)
container_of(work, struct cx25821_dev, _irq_work_entry);
if (!dev) {
- printk(KERN_ERR
- "ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
+ pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
+ __func__);
return;
}
@@ -443,23 +438,20 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_filename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR
- "%s: File has no file operations registered!",
- __func__);
+ pr_err("%s(): File has no file operations registered!\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR
- "%s: File has no READ operations registered! \
- Returning.",
- __func__);
+ pr_err("%s(): File has no READ operations registered! Returning\n",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -487,10 +479,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
offset += vfs_read_retval;
if (vfs_read_retval < line_size) {
- printk(KERN_INFO
- "Done: exit %s() since no more \
- bytes to read from Video file.\n",
- __func__);
+ pr_info("Done: exit %s() since no more bytes to read from Video file\n",
+ __func__);
break;
}
}
@@ -534,9 +524,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
dev->_risc_size = dev->upstream_riscbuf_size;
if (!dev->_dma_virt_addr) {
- printk
- (KERN_ERR "cx25821: FAILED to allocate memory for Risc \
- buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
return -ENOMEM;
}
@@ -556,9 +544,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
dev->_data_buf_size = dev->upstream_databuf_size;
if (!dev->_data_buf_virt_addr) {
- printk
- (KERN_ERR "cx25821: FAILED to allocate memory for data \
- buffer! Returning.\n");
+ pr_err("FAILED to allocate memory for data buffer! Returning\n");
return -ENOMEM;
}
@@ -574,8 +560,7 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
dev->_lines_count);
if (ret < 0) {
- printk(KERN_INFO
- "cx25821: Failed creating Video Upstream Risc programs!\n");
+ pr_info("Failed creating Video Upstream Risc programs!\n");
goto error;
}
@@ -652,22 +637,20 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
spin_unlock(&dev->slock);
} else {
if (status & FLD_VID_SRC_UF)
- printk
- (KERN_ERR "%s: Video Received Underflow Error \
- Interrupt!\n", __func__);
+ pr_err("%s(): Video Received Underflow Error Interrupt!\n",
+ __func__);
if (status & FLD_VID_SRC_SYNC)
- printk(KERN_ERR "%s: Video Received Sync Error \
- Interrupt!\n", __func__);
+ pr_err("%s(): Video Received Sync Error Interrupt!\n",
+ __func__);
if (status & FLD_VID_SRC_OPC_ERR)
- printk(KERN_ERR "%s: Video Received OpCode Error \
- Interrupt!\n", __func__);
+ pr_err("%s(): Video Received OpCode Error Interrupt!\n",
+ __func__);
}
if (dev->_file_status == END_OF_FILE) {
- printk(KERN_ERR "cx25821: EOF Channel 1 Framecount = %d\n",
- dev->_frame_count);
+ pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count);
return -1;
}
/* ElSE, set the interrupt mask register, re-enable irq. */
@@ -775,8 +758,8 @@ int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
request_irq(dev->pci->irq, cx25821_upstream_irq,
IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
- printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
- dev->pci->irq);
+ pr_err("%s: can't get upstream IRQ %d\n",
+ dev->name, dev->pci->irq);
goto fail_irq;
}
@@ -806,7 +789,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
int str_length = 0;
if (dev->_is_running) {
- printk(KERN_INFO "Video Channel is still running so return!\n");
+ pr_info("Video Channel is still running so return!\n");
return 0;
}
@@ -817,9 +800,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
if (!dev->_irq_queues) {
- printk
- (KERN_ERR "cx25821: create_singlethread_workqueue() for \
- Video FAILED!\n");
+ pr_err("create_singlethread_workqueue() for Video FAILED!\n");
return -ENOMEM;
}
/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
@@ -895,8 +876,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
/* Allocating buffers and prepare RISC program */
retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
if (retval < 0) {
- printk(KERN_ERR
- "%s: Failed to set up Video upstream buffers!\n",
+ pr_err("%s: Failed to set up Video upstream buffers!\n",
dev->name);
goto error;
}
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index e7f1d5778cec..3c121fcb8731 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -24,6 +24,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "cx25821-video.h"
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
@@ -92,7 +94,7 @@ int cx25821_get_format_size(void)
return ARRAY_SIZE(formats);
}
-struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
+struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
{
unsigned int i;
@@ -104,7 +106,7 @@ struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
if (formats[i].fourcc == fourcc)
return formats + i;
- printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
+ pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
return NULL;
}
@@ -159,15 +161,15 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
else
mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
if (bc != 1)
- printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
+ pr_err("%s: %d buffers handled (should be 1)\n",
__func__, bc);
}
#ifdef TUNER_FLAG
int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
{
- dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
- (unsigned int)norm, v4l2_norm_to_name(norm));
+ dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
+ __func__, (unsigned int)norm, v4l2_norm_to_name(norm));
dev->tvnorm = norm;
@@ -267,7 +269,7 @@ int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
struct v4l2_routing route;
memset(&route, 0, sizeof(route));
- dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
+ dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
dev->input = input;
@@ -400,8 +402,8 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
/* risc op code error */
if (status & (1 << 16)) {
- printk(KERN_WARNING "%s, %s: video risc op code error\n",
- dev->name, channel->name);
+ pr_warn("%s, %s: video risc op code error\n",
+ dev->name, channel->name);
cx_clear(channel->dma_ctl, 0x11);
cx25821_sram_channel_dump(dev, channel);
}
@@ -458,7 +460,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
btcx_riscmem_free(dev->pci,
&dev->channels[chan_num].vidq.stopper);
- printk(KERN_WARNING "device %d released!\n", chan_num);
+ pr_warn("device %d released!\n", chan_num);
}
}
@@ -590,7 +592,7 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
init_buffer = 1;
rc = videobuf_iolock(q, &buf->vb, NULL);
if (0 != rc) {
- printk(KERN_DEBUG "videobuf_iolock failed!\n");
+ printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n"));
goto fail;
}
}
@@ -848,7 +850,7 @@ static int video_open(struct file *file)
pix_format =
(dev->channels[ch_id].pixel_formats ==
PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
+ fh->fmt = cx25821_format_by_fourcc(pix_format);
v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);
@@ -1010,7 +1012,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
if (0 != err)
return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
fh->vidq.field = f->fmt.pix.field;
/* check if width and height is valid based on set standard */
@@ -1038,8 +1040,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
dev->channels[fh->channel_id].cif_width = fh->width;
medusa_set_resolution(dev, fh->width, SRAM_CH00);
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
+ dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width,
+ fh->height, fh->vidq.field);
v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
@@ -1070,14 +1072,14 @@ static int vidioc_log_status(struct file *file, void *priv)
u32 tmp = 0;
snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
+ pr_info("%s/2: ============ START LOG STATUS ============\n",
+ dev->name);
cx25821_call_all(dev, core, log_status);
tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 0 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
+ pr_info("Video input 0 is %s\n",
+ (tmp & 0x11) ? "streaming" : "stopped");
+ pr_info("%s/2: ============= END LOG STATUS =============\n",
+ dev->name);
return 0;
}
@@ -1119,7 +1121,7 @@ int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fo
enum v4l2_field field;
unsigned int maxw, maxh;
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
if (NULL == fmt)
return -EINVAL;
@@ -1319,7 +1321,7 @@ int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
*i = dev->input;
- dprintk(1, "%s() returns %d\n", __func__, *i);
+ dprintk(1, "%s(): returns %d\n", __func__, *i);
return 0;
}
@@ -1339,7 +1341,7 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
}
if (i > 2) {
- dprintk(1, "%s() -EINVAL\n", __func__);
+ dprintk(1, "%s(): -EINVAL\n", __func__);
return -EINVAL;
}
@@ -1390,7 +1392,7 @@ int cx25821_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_freque
if (0 != err)
return err;
} else {
- printk(KERN_ERR "Invalid fh pointer!\n");
+ pr_err("Invalid fh pointer!\n");
return -EINVAL;
}
@@ -1733,12 +1735,10 @@ static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
data_from_user = (struct upstream_user_struct *)arg;
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -1776,12 +1776,10 @@ static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
data_from_user = (struct upstream_user_struct *)arg;
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -1819,12 +1817,10 @@ static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
data_from_user = (struct upstream_user_struct *)arg;
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
@@ -1866,12 +1862,10 @@ static long video_ioctl_set(struct file *file, unsigned int cmd,
data_from_user = (struct downstream_user_struct *)arg;
- if (!data_from_user) {
- printk(
- "cx25821 in %s(): User data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
+ if (!data_from_user) {
+ pr_err("%s(): User data is INVALID. Returning\n", __func__);
+ return 0;
+ }
command = data_from_user->command;
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
index cc6034b1a95d..213f37cea348 100644
--- a/drivers/staging/cx25821/cx25821-video.h
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -49,10 +49,11 @@
#define VIDEO_DEBUG 0
-#define dprintk(level, fmt, arg...)\
- do { if (VIDEO_DEBUG >= level)\
- printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
- } while (0)
+#define dprintk(level, fmt, arg...) \
+do { \
+ if (VIDEO_DEBUG >= level) \
+ printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \
+} while (0)
/* For IOCTL to identify running upstream */
#define UPSTREAM_START_VIDEO 700
@@ -87,7 +88,7 @@ extern unsigned int vid_limit;
#define FORMAT_FLAGS_PACKED 0x01
extern struct cx25821_fmt formats[];
-extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
+extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc);
extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
extern void cx25821_dump_video_queue(struct cx25821_dev *dev,
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
index c94000125782..55115235f7f6 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/staging/cx25821/cx25821.h
@@ -519,9 +519,12 @@ extern struct sram_channel cx25821_sram_channels[];
#define Set_GPIO_Bit(Bit) (1 << Bit)
#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
-#define CX25821_ERR(fmt, args...) printk(KERN_ERR "cx25821(%d): " fmt, dev->board, ## args)
-#define CX25821_WARN(fmt, args...) printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
-#define CX25821_INFO(fmt, args...) printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
+#define CX25821_ERR(fmt, args...) \
+ pr_err("(%d): " fmt, dev->board, ##args)
+#define CX25821_WARN(fmt, args...) \
+ pr_warn("(%d): " fmt, dev->board, ##args)
+#define CX25821_INFO(fmt, args...) \
+ pr_info("(%d): " fmt, dev->board, ##args)
extern int cx25821_i2c_register(struct cx25821_i2c *bus);
extern void cx25821_card_setup(struct cx25821_dev *dev);
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index 3aecd30f0d1e..1da57df5cbcb 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -1,10 +1,10 @@
config VIDEO_GO7007
tristate "WIS GO7007 MPEG encoder support"
- depends on VIDEO_DEV && PCI && I2C && INPUT
+ depends on VIDEO_DEV && PCI && I2C
depends on BKL # please fix
depends on SND
select VIDEOBUF_DMA_SG
- depends on VIDEO_IR
+ depends on RC_CORE
select VIDEO_TUNER
select VIDEO_TVEEPROM
select SND_PCM
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index de7ebb99d8f6..114eec8a630a 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_TM6000
tristate "TV Master TM5600/6000/6010 driver"
- depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL
+ depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB && EXPERIMENTAL
select VIDEO_TUNER
select MEDIA_TUNER_XC2028
select MEDIA_TUNER_XC5000
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index b143258f094a..5a7946c6de50 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -521,13 +521,6 @@ int tm6000_cards_setup(struct tm6000_core *dev)
printk(KERN_ERR "Error %i doing tuner reset\n", rc);
return rc;
}
- msleep(10);
-
- if (!i) {
- rc = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
- if (rc >= 0)
- printk(KERN_DEBUG "board=0x%08x\n", rc);
- }
}
} else {
printk(KERN_ERR "Tuner reset is not configured\n");
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 40a0206e2432..8c897d79ce7a 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -542,6 +542,26 @@ int tm6000_init(struct tm6000_core *dev)
int board, rc = 0, i, size;
struct reg_init *tab;
+ /* Check board revision */
+ board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
+ if (board >= 0) {
+ switch (board & 0xff) {
+ case 0xf3:
+ printk(KERN_INFO "Found tm6000\n");
+ if (dev->dev_type != TM6000)
+ dev->dev_type = TM6000;
+ break;
+ case 0xf4:
+ printk(KERN_INFO "Found tm6010\n");
+ if (dev->dev_type != TM6010)
+ dev->dev_type = TM6010;
+ break;
+ default:
+ printk(KERN_INFO "Unknown board version = 0x%08x\n", board);
+ }
+ } else
+ printk(KERN_ERR "Error %i while retrieving board version\n", board);
+
if (dev->dev_type == TM6010) {
tab = tm6010_init_tab;
size = ARRAY_SIZE(tm6010_init_tab);
@@ -563,13 +583,6 @@ int tm6000_init(struct tm6000_core *dev)
msleep(5); /* Just to be conservative */
- /* Check board version - maybe 10Moons specific */
- board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
- if (board >= 0)
- printk(KERN_INFO "Board version = 0x%08x\n", board);
- else
- printk(KERN_ERR "Error %i while retrieving board version\n", board);
-
rc = tm6000_cards_setup(dev);
return rc;
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 93f625fc852b..18de4748f27e 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -301,33 +301,11 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-#define mass_write(addr, reg, data...) \
- { static const u8 _val[] = data; \
- rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, \
- REQ_16_SET_GET_I2C_WR1_RDN, (reg<<8)+addr, 0x00, (u8 *) _val, \
- ARRAY_SIZE(_val)); \
- if (rc < 0) { \
- printk(KERN_ERR "Error on line %d: %d\n", __LINE__, rc); \
- return rc; \
- } \
- msleep(10); \
- }
-
-static struct i2c_algorithm tm6000_algo = {
+static const struct i2c_algorithm tm6000_algo = {
.master_xfer = tm6000_i2c_xfer,
.functionality = functionality,
};
-static struct i2c_adapter tm6000_adap_template = {
- .owner = THIS_MODULE,
- .name = "tm6000",
- .algo = &tm6000_algo,
-};
-
-static struct i2c_client tm6000_client_template = {
- .name = "tm6000 internal",
-};
-
/* ----------------------------------------------------------- */
/*
@@ -337,17 +315,20 @@ static struct i2c_client tm6000_client_template = {
int tm6000_i2c_register(struct tm6000_core *dev)
{
unsigned char eedata[256];
+ int rc;
- dev->i2c_adap = tm6000_adap_template;
+ dev->i2c_adap.owner = THIS_MODULE;
+ dev->i2c_adap.algo = &tm6000_algo;
dev->i2c_adap.dev.parent = &dev->udev->dev;
- strcpy(dev->i2c_adap.name, dev->name);
+ strlcpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
dev->i2c_adap.algo_data = dev;
- i2c_add_adapter(&dev->i2c_adap);
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
+ rc = i2c_add_adapter(&dev->i2c_adap);
+ if (rc)
+ return rc;
- dev->i2c_client = tm6000_client_template;
dev->i2c_client.adapter = &dev->i2c_adap;
-
- i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
+ strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
tm6000_i2c_eeprom(dev, eedata, sizeof(eedata));
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c
index 6022caaa739b..e02ea6720380 100644
--- a/drivers/staging/tm6000/tm6000-input.c
+++ b/drivers/staging/tm6000/tm6000-input.c
@@ -24,8 +24,7 @@
#include <linux/input.h>
#include <linux/usb.h>
-#include <media/ir-core.h>
-#include <media/ir-common.h>
+#include <media/rc-core.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -51,8 +50,7 @@ struct tm6000_ir_poll_result {
struct tm6000_IR {
struct tm6000_core *dev;
- struct ir_input_dev *input;
- struct ir_input_state ir;
+ struct rc_dev *rc;
char name[32];
char phys[32];
@@ -67,7 +65,7 @@ struct tm6000_IR {
int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
/* IR device properties */
- struct ir_dev_props props;
+ u64 rc_type;
};
@@ -145,7 +143,7 @@ static int default_polling_getkey(struct tm6000_IR *ir,
return 0;
if (&dev->int_in) {
- if (ir->ir.ir_type == IR_TYPE_RC5)
+ if (ir->rc_type == RC_TYPE_RC5)
poll_result->rc_data = ir->urb_data[0];
else
poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8;
@@ -155,7 +153,7 @@ static int default_polling_getkey(struct tm6000_IR *ir,
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
msleep(10);
- if (ir->ir.ir_type == IR_TYPE_RC5) {
+ if (ir->rc_type == RC_TYPE_RC5) {
rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
REQ_02_GET_IR_CODE, 0, 0, buf, 1);
@@ -201,10 +199,7 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir)
dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
if (ir->key) {
- ir_input_keydown(ir->input->input_dev, &ir->ir,
- (u32)poll_result.rc_data);
-
- ir_input_nokey(ir->input->input_dev, &ir->ir);
+ rc_keydown(ir->rc, poll_result.rc_data, 0);
ir->key = 0;
}
return;
@@ -218,9 +213,9 @@ static void tm6000_ir_work(struct work_struct *work)
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
-static int tm6000_ir_start(void *priv)
+static int tm6000_ir_start(struct rc_dev *rc)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
schedule_delayed_work(&ir->work, 0);
@@ -228,16 +223,16 @@ static int tm6000_ir_start(void *priv)
return 0;
}
-static void tm6000_ir_stop(void *priv)
+static void tm6000_ir_stop(struct rc_dev *rc)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
cancel_delayed_work_sync(&ir->work);
}
-int tm6000_ir_change_protocol(void *priv, u64 ir_type)
+int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
ir->get_key = default_polling_getkey;
@@ -249,9 +244,9 @@ int tm6000_ir_change_protocol(void *priv, u64 ir_type)
int tm6000_ir_init(struct tm6000_core *dev)
{
struct tm6000_IR *ir;
- struct ir_input_dev *ir_input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
- int pipe, size, rc;
+ int pipe, size;
if (!enable_ir)
return -ENODEV;
@@ -263,24 +258,22 @@ int tm6000_ir_init(struct tm6000_core *dev)
return 0;
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL);
- ir_input_dev->input_dev = input_allocate_device();
- if (!ir || !ir_input_dev || !ir_input_dev->input_dev)
- goto err_out_free;
+ rc = rc_allocate_device();
+ if (!ir | !rc)
+ goto out;
/* record handles to ourself */
ir->dev = dev;
dev->ir = ir;
-
- ir->input = ir_input_dev;
+ ir->rc = rc;
/* input einrichten */
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.priv = ir;
- ir->props.change_protocol = tm6000_ir_change_protocol;
- ir->props.open = tm6000_ir_start;
- ir->props.close = tm6000_ir_stop;
- ir->props.driver_type = RC_DRIVER_SCANCODE;
+ rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+ rc->priv = ir;
+ rc->change_protocol = tm6000_ir_change_protocol;
+ rc->open = tm6000_ir_start;
+ rc->close = tm6000_ir_stop;
+ rc->driver_type = RC_DRIVER_SCANCODE;
ir->polling = 50;
@@ -290,19 +283,17 @@ int tm6000_ir_init(struct tm6000_core *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
- err = ir_input_init(ir_input_dev->input_dev, &ir->ir, IR_TYPE_OTHER);
- if (err < 0)
- goto err_out_free;
-
- ir_input_dev->input_dev->name = ir->name;
- ir_input_dev->input_dev->phys = ir->phys;
- ir_input_dev->input_dev->id.bustype = BUS_USB;
- ir_input_dev->input_dev->id.version = 1;
- ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
- ir_input_dev->input_dev->dev.parent = &dev->udev->dev;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ rc->map_name = dev->ir_codes;
+ rc->driver_name = "tm6000";
+ rc->dev.parent = &dev->udev->dev;
if (&dev->int_in) {
dprintk("IR over int\n");
@@ -319,35 +310,32 @@ int tm6000_ir_init(struct tm6000_core *dev)
ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if (ir->int_urb->transfer_buffer == NULL) {
usb_free_urb(ir->int_urb);
- goto err_out_stop;
+ goto out;
}
dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
ir->int_urb->transfer_buffer, size,
tm6000_ir_urb_received, dev,
dev->int_in.endp->desc.bInterval);
- rc = usb_submit_urb(ir->int_urb, GFP_KERNEL);
- if (rc) {
+ err = usb_submit_urb(ir->int_urb, GFP_KERNEL);
+ if (err) {
kfree(ir->int_urb->transfer_buffer);
usb_free_urb(ir->int_urb);
- err = rc;
- goto err_out_stop;
+ goto out;
}
ir->urb_data = kzalloc(size, GFP_KERNEL);
}
/* ir register */
- err = ir_input_register(ir->input->input_dev, dev->ir_codes,
- &ir->props, "tm6000");
+ err = rc_register_device(rc);
if (err)
- goto err_out_stop;
+ goto out;
return 0;
-err_out_stop:
+out:
dev->ir = NULL;
-err_out_free:
- kfree(ir_input_dev);
+ rc_free_device(rc);
kfree(ir);
return err;
}
@@ -361,7 +349,7 @@ int tm6000_ir_fini(struct tm6000_core *dev)
if (!ir)
return 0;
- ir_input_unregister(ir->input->input_dev);
+ rc_unregister_device(ir->rc);
if (ir->int_urb) {
usb_kill_urb(ir->int_urb);
@@ -372,8 +360,6 @@ int tm6000_ir_fini(struct tm6000_core *dev)
ir->urb_data = NULL;
}
- kfree(ir->input);
- ir->input = NULL;
kfree(ir);
dev->ir = NULL;